diff --git a/.github/workflows/Tasmota_build_master.yml b/.github/workflows/Tasmota_build_master.yml index b8ee7ff4a..974191d7a 100644 --- a/.github/workflows/Tasmota_build_master.yml +++ b/.github/workflows/Tasmota_build_master.yml @@ -1,269 +1,269 @@ -name: Build_firmware_master - -on: - workflow_dispatch: # Start a workflow - push: - branches: master - paths-ignore: - - '.github/**' # Ignore changes towards the .github directory - - '**.md' # Do no build if *.md files changes - - 'tasmota/berry/**' # Ignore Berry examples - -# Ensures that only one deploy task per branch/environment will run at a time. -concurrency: - group: environment-${{ github.ref }} - cancel-in-progress: true - -jobs: - safeboot-images: - runs-on: ubuntu-latest - if: github.repository == 'arendst/Tasmota' - continue-on-error: true - strategy: - matrix: - variant: - - tasmota32-safeboot - - tasmota32solo1-safeboot - - tasmota32s2-safeboot - - tasmota32s2cdc-safeboot - - tasmota32s3-safeboot - - tasmota32s3ser-safeboot - - tasmota32c2-safeboot - - tasmota32c3-safeboot - - tasmota32c3ser-safeboot - - tasmota32c5-safeboot - - tasmota32c5ser-safeboot - - tasmota32c6-safeboot - - tasmota32c6ser-safeboot - - tasmota32p4-safeboot - - tasmota32p4ser-safeboot - steps: - - uses: actions/checkout@v4 - with: - ref: master - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: '3.13' - - name: Install uv - uses: astral-sh/setup-uv@v7 - with: - version: "latest" - enable-cache: false - - name: Install dependencies - run: | - uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.19.zip - cp ./platformio_override_sample.ini ./platformio_override.ini - - name: Add "release" to footer - run: | - sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h - - name: Run PlatformIO - env: - PYTHONIOENCODING: utf-8 - PYTHONUTF8: '1' - run: platformio run -e ${{ matrix.variant }} - - name: Upload safeboot firmware artifacts - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.variant }} - path: ./build_output - - base-images: - runs-on: ubuntu-latest - if: github.repository == 'arendst/Tasmota' - continue-on-error: true - strategy: - matrix: - variant: - - tasmota - - tasmota-4M - - tasmota-minimal - - tasmota-display - - tasmota-ir - - tasmota-knx - - tasmota-lite - - tasmota-sensors - - tasmota-zbbridge - - tasmota-zigbee - steps: - - uses: actions/checkout@v4 - with: - ref: master - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: '3.13' - - name: Install uv - uses: astral-sh/setup-uv@v7 - with: - version: "latest" - enable-cache: false - - name: Install dependencies - run: | - uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.19.zip - cp ./platformio_override_sample.ini ./platformio_override.ini - - name: Add "release" to footer - run: | - sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h - - name: Run PlatformIO - env: - PYTHONIOENCODING: utf-8 - PYTHONUTF8: '1' - run: platformio run -e ${{ matrix.variant }} - - name: Upload firmware artifacts - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.variant }} - path: ./build_output - - base32-images: - needs: safeboot-images - runs-on: ubuntu-latest - if: github.repository == 'arendst/Tasmota' - continue-on-error: true - strategy: - matrix: - variant: - - tasmota32 - - tasmota32-zbbrdgpro - - tasmota32-webcam - - tasmota32-bluetooth - - tasmota32-nspanel - - tasmota32-display - - tasmota32-ir - - tasmota32-lvgl - - tasmota32c2 - - tasmota32c3 - - tasmota32c5 - - tasmota32c6 - - tasmota32p4 - - tasmota32s2 - - tasmota32s2cdc - - tasmota32s3 - - tasmota32solo1 - steps: - - uses: actions/checkout@v4 - with: - ref: master - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: '3.13' - - name: Install uv - uses: astral-sh/setup-uv@v7 - with: - version: "latest" - enable-cache: false - - name: Install dependencies - run: | - uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.19.zip - cp ./platformio_override_sample.ini ./platformio_override.ini - - name: Download safeboot firmwares - uses: actions/download-artifact@v4 - with: - pattern: tasmota32* - path: ./temp - - name: Move safeboot files - run: | - mkdir -p ./firmware/firmware - find ./temp -type f -exec cp -t ./firmware/firmware {} + - - name: Add "release" to footer - run: | - sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h - - name: Run PlatformIO - env: - PYTHONIOENCODING: utf-8 - PYTHONUTF8: '1' - run: platformio run -e ${{ matrix.variant }} - - name: Upload firmware artifacts - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.variant }} - path: ./build_output - - language-images: - needs: safeboot-images - runs-on: ubuntu-latest - if: github.repository == 'arendst/Tasmota' - continue-on-error: true - strategy: - matrix: - variant: [ tasmota, tasmota32 ] - language: [ AD, AF, BG, BR, CN, CZ, DE, ES, FR, FY, GR, HE, HU, IT, KO, LT, NL, PL, PT, RO, RU, SE, SK, TR, TW, UK, VN ] - steps: - - uses: actions/checkout@v4 - with: - ref: master - - name: Set up Python - uses: actions/setup-python@v6 - with: - python-version: '3.13' - - name: Install uv - uses: astral-sh/setup-uv@v7 - with: - version: "latest" - enable-cache: false - - name: Install dependencies - run: | - uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.19.zip - cp ./platformio_override_sample.ini ./platformio_override.ini - - name: Download safeboot firmwares - uses: actions/download-artifact@v4 - with: - pattern: tasmota32* - path: ./temp - - name: Move safeboot files - run: | - mkdir -p ./firmware/firmware - find ./temp -type f -exec cp -t ./firmware/firmware {} + - - name: Add "release" to footer - run: | - sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h - - name: Run PlatformIO - env: - PYTHONIOENCODING: utf-8 - PYTHONUTF8: '1' - run: platformio run -e ${{ matrix.variant }}-${{ matrix.language }} - - name: Upload language firmware artifacts - uses: actions/upload-artifact@v4 - with: - name: ${{ matrix.variant }}-${{ matrix.language }} - path: ./build_output - - Release: - needs: [base-images, base32-images, language-images] - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v4 - - name: Download all Tasmota artifacts - uses: actions/download-artifact@v4 - with: - pattern: tasmota* - path: ./temp - - name: Move files - run: | - mkdir -p ./release - find ./temp -type f -exec cp -t ./release {} + - - name: Display structure of downloaded files - run: ls -R ./release/ - - name: Release - uses: jason2866/action-gh-release@v1.2 - with: - tag_name: ${{ github.run_number }} - files: | - ./release/tasmota* - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - Start_final_copy: - needs: Release - runs-on: ubuntu-latest - env: - GH_TOKEN: ${{ secrets.API_TOKEN_GITHUB }} - steps: - - name: Dispatch workflow in arendst/Tasmota-firmware - run: | - gh api repos/arendst/Tasmota-firmware/actions/workflows/fetch_deploy.yml/dispatches \ - --method POST \ - -f ref='gh_actions' +name: Build_firmware_master + +on: + workflow_dispatch: # Start a workflow + push: + branches: master + paths-ignore: + - '.github/**' # Ignore changes towards the .github directory + - '**.md' # Do no build if *.md files changes + - 'tasmota/berry/**' # Ignore Berry examples + +# Ensures that only one deploy task per branch/environment will run at a time. +concurrency: + group: environment-${{ github.ref }} + cancel-in-progress: true + +jobs: + safeboot-images: + runs-on: ubuntu-latest + if: github.repository == 'arendst/Tasmota' + continue-on-error: true + strategy: + matrix: + variant: + - tasmota32-safeboot + - tasmota32solo1-safeboot + - tasmota32s2-safeboot + - tasmota32s2cdc-safeboot + - tasmota32s3-safeboot + - tasmota32s3ser-safeboot + - tasmota32c2-safeboot + - tasmota32c3-safeboot + - tasmota32c3ser-safeboot + - tasmota32c5-safeboot + - tasmota32c5ser-safeboot + - tasmota32c6-safeboot + - tasmota32c6ser-safeboot + - tasmota32p4-safeboot + - tasmota32p4ser-safeboot + steps: + - uses: actions/checkout@v4 + with: + ref: master + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: '3.13' + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + version: "latest" + enable-cache: false + - name: Install dependencies + run: | + uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.19.zip + cp ./platformio_override_sample.ini ./platformio_override.ini + - name: Add "release" to footer + run: | + sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h + - name: Run PlatformIO + env: + PYTHONIOENCODING: utf-8 + PYTHONUTF8: '1' + run: platformio run -e ${{ matrix.variant }} + - name: Upload safeboot firmware artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.variant }} + path: ./build_output + + base-images: + runs-on: ubuntu-latest + if: github.repository == 'arendst/Tasmota' + continue-on-error: true + strategy: + matrix: + variant: + - tasmota + - tasmota-4M + - tasmota-minimal + - tasmota-display + - tasmota-ir + - tasmota-knx + - tasmota-lite + - tasmota-sensors + - tasmota-zbbridge + - tasmota-zigbee + steps: + - uses: actions/checkout@v4 + with: + ref: master + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: '3.13' + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + version: "latest" + enable-cache: false + - name: Install dependencies + run: | + uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.19.zip + cp ./platformio_override_sample.ini ./platformio_override.ini + - name: Add "release" to footer + run: | + sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h + - name: Run PlatformIO + env: + PYTHONIOENCODING: utf-8 + PYTHONUTF8: '1' + run: platformio run -e ${{ matrix.variant }} + - name: Upload firmware artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.variant }} + path: ./build_output + + base32-images: + needs: safeboot-images + runs-on: ubuntu-latest + if: github.repository == 'arendst/Tasmota' + continue-on-error: true + strategy: + matrix: + variant: + - tasmota32 + - tasmota32-zbbrdgpro + - tasmota32-webcam + - tasmota32-bluetooth + - tasmota32-nspanel + - tasmota32-display + - tasmota32-ir + - tasmota32-lvgl + - tasmota32c2 + - tasmota32c3 + - tasmota32c5 + - tasmota32c6 + - tasmota32p4 + - tasmota32s2 + - tasmota32s2cdc + - tasmota32s3 + - tasmota32solo1 + steps: + - uses: actions/checkout@v4 + with: + ref: master + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: '3.13' + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + version: "latest" + enable-cache: false + - name: Install dependencies + run: | + uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.19.zip + cp ./platformio_override_sample.ini ./platformio_override.ini + - name: Download safeboot firmwares + uses: actions/download-artifact@v4 + with: + pattern: tasmota32* + path: ./temp + - name: Move safeboot files + run: | + mkdir -p ./firmware/firmware + find ./temp -type f -exec cp -t ./firmware/firmware {} + + - name: Add "release" to footer + run: | + sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h + - name: Run PlatformIO + env: + PYTHONIOENCODING: utf-8 + PYTHONUTF8: '1' + run: platformio run -e ${{ matrix.variant }} + - name: Upload firmware artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.variant }} + path: ./build_output + + language-images: + needs: safeboot-images + runs-on: ubuntu-latest + if: github.repository == 'arendst/Tasmota' + continue-on-error: true + strategy: + matrix: + variant: [ tasmota, tasmota32 ] + language: [ AD, AF, BG, BR, CN, CZ, DE, ES, FR, FY, GR, HE, HU, IT, KO, LT, NL, PL, PT, RO, RU, SE, SK, TR, TW, UK, VN ] + steps: + - uses: actions/checkout@v4 + with: + ref: master + - name: Set up Python + uses: actions/setup-python@v6 + with: + python-version: '3.13' + - name: Install uv + uses: astral-sh/setup-uv@v7 + with: + version: "latest" + enable-cache: false + - name: Install dependencies + run: | + uv pip install --system -U https://github.com/pioarduino/platformio-core/archive/refs/tags/v6.1.19.zip + cp ./platformio_override_sample.ini ./platformio_override.ini + - name: Download safeboot firmwares + uses: actions/download-artifact@v4 + with: + pattern: tasmota32* + path: ./temp + - name: Move safeboot files + run: | + mkdir -p ./firmware/firmware + find ./temp -type f -exec cp -t ./firmware/firmware {} + + - name: Add "release" to footer + run: | + sed -i -e "s/TASMOTA_SHA_SHORT/TASMOTA_SHA_SHORT release-/g" ./tasmota/include/tasmota_version.h + - name: Run PlatformIO + env: + PYTHONIOENCODING: utf-8 + PYTHONUTF8: '1' + run: platformio run -e ${{ matrix.variant }}-${{ matrix.language }} + - name: Upload language firmware artifacts + uses: actions/upload-artifact@v4 + with: + name: ${{ matrix.variant }}-${{ matrix.language }} + path: ./build_output + + Release: + needs: [base-images, base32-images, language-images] + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v4 + - name: Download all Tasmota artifacts + uses: actions/download-artifact@v4 + with: + pattern: tasmota* + path: ./temp + - name: Move files + run: | + mkdir -p ./release + find ./temp -type f -exec cp -t ./release {} + + - name: Display structure of downloaded files + run: ls -R ./release/ + - name: Release + uses: jason2866/action-gh-release@v1.2 + with: + tag_name: ${{ github.run_number }} + files: | + ./release/tasmota* + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + Start_final_copy: + needs: Release + runs-on: ubuntu-latest + env: + GH_TOKEN: ${{ secrets.API_TOKEN_GITHUB }} + steps: + - name: Dispatch workflow in arendst/Tasmota-firmware + run: | + gh api repos/arendst/Tasmota-firmware/actions/workflows/fetch_deploy.yml/dispatches \ + --method POST \ + -f ref='gh_actions' diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 594f6f14e..364cbf523 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -1,152 +1,152 @@ - - - Logo - - -# RELEASE NOTES - -## Migration Information - -**This version removes support for direct migration from versions before v8.1.0 (Doris)** - -See [migration path](https://tasmota.github.io/docs/Upgrading#migration-path) for instructions how to migrate to a major version. - -**Do not upgrade from minimal to minimal version. It will most likely fail at some point and will require flashing via serial.** If you do have to use minimal versions, always OTA to a full version of the same release before applying next minimal version. - -Pay attention to the following version breaks due to dynamic settings updates: - -1. Migrate to **Sonoff-Tasmota 3.9.x** -2. Migrate to **Sonoff-Tasmota 4.x** -3. Migrate to **Sonoff-Tasmota 5.14** (http://ota.tasmota.com/tasmota/release_5.14.0/sonoff.bin) - NOTICE underscore as a dash is not supported in older versions -4. Migrate to **Sonoff-Tasmota 6.7.1** (http://ota.tasmota.com/tasmota/release_6.7.1/sonoff.bin) - NOTICE underscore as a dash is not supported in older versions -5. Migrate to **Tasmota 7.2.0** (http://ota.tasmota.com/tasmota/release-7.2.0/tasmota.bin) - ---- Major change in parameter storage layout --- - -6. Migrate to **Tasmota 8.5.1** (http://ota.tasmota.com/tasmota/release-8.5.1/tasmota.bin) - ---- Major change in internal GPIO function representation --- - -7. Migrate to **Tasmota 9.1** (http://ota.tasmota.com/tasmota/release-9.1.0/tasmota.bin.gz) -8. Upgrade to **latest release** (http://ota.tasmota.com/tasmota/release/tasmota.bin.gz) - -While fallback or downgrading is common practice it was never supported due to Settings additions or changes in newer releases. Starting with release **v9.1.0 Imogen** the internal GPIO function representation has changed in such a way that fallback is only possible to the latest GPIO configuration before installing **v9.1.0**. - -## Supported Core versions - -This release will be supported from ESP8266/Arduino library Core version **2.7.8** due to reported security and stability issues on previous Core version. This will also support gzipped binaries. - -This release will be supported from ESP32/Arduino library Core version **v3.1.10**. - -Support of ESP8266 Core versions before 2.7.8 and ESP32 Core versions before v3.1.10 have been removed. - -## Initial configuration tools - -For initial configuration this release supports Webserver based **WifiManager** or **Serial** based command interface. - -## Initial installation - -Easy initial installation of Tasmota can be performed using the [Tasmota WebInstaller](https://tasmota.github.io/install/). - -## Provided Binary Downloads - -### ESP8266 or ESP8285 based -The following binary downloads have been compiled with ESP8266/Arduino library core version **2.7.8**. - -- **tasmota.bin** = The Tasmota version with most drivers for 1M+ flash. **RECOMMENDED RELEASE BINARY** -- **tasmota-4M.bin** = The Tasmota version with most drivers and filesystem for 4M+ flash. -- **tasmota-AD.bin** to **tasmota-VN.bin** = The Tasmota version in different languages for 1M+ flash. -- **tasmota-lite.bin** = The Lite version without most drivers and sensors for 1M+ flash. -- **tasmota-knx.bin** = The Knx version without some features but adds KNX support for 1M+ flash. -- **tasmota-sensors.bin** = The Sensors version adds more useful sensors for 1M+ flash. -- **tasmota-ir.bin** = The InfraRed Receiver and transmitter version allowing all available protocols provided by library IRremoteESP8266 but without most other features for 1M+ flash. -- **tasmota-display.bin** = The Display version without Energy Monitoring but adds display support for 1M+ flash. -- **tasmota-zbbridge.bin** = The dedicated Sonoff Zigbee Bridge version for 2M+ flash. -- **tasmota-zigbee.bin** = The dedicated cc25xx Zigbee Bridge version for 4M+ flash. - -Above binaries are also available as gzipped version allowing faster uploads. - -Latest released binaries can be downloaded from -- https://github.com/arendst/Tasmota-firmware/tree/firmware/release-firmware -- http://ota.tasmota.com/tasmota/release - -Historical binaries can be downloaded from -- http://ota.tasmota.com/tasmota/release-15.2.0 - -The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz`` - -### ESP32, ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-P4, ESP32-S2 and ESP32-S3 based -The following binary downloads have been compiled with ESP32/Arduino library core version **v3.1.10**. - -- **tasmota32.bin** = The Tasmota version with most drivers including additional sensors and KNX for 4M+ flash. **RECOMMENDED RELEASE BINARY** -- **tasmota32solo1.bin** = The Tasmota version with most drivers including additional sensors and KNX for single core ESP32 and 4M+ flash. -- **tasmota32c2.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C2 with serial and 4M+ flash. -- **tasmota32c3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C3 with USB HWCDC and fallback to serial and 4M+ flash. -- **tasmota32c5.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C5 with USB HWCDC and fallback to serial and 4M+ flash. -- **tasmota32c6.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C6 with USB HWCDC and fallback to serial and 4M+ flash. -- **tasmota32p4.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-P4 with USB HWCDC and fallback to serial and 4M+ flash. -- **tasmota32s2.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-S2 with serial and 4M+ flash. -- **tasmota32s2cdc.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-S2 with serial over embedded USB CDC only and 4M+ flash. -- **tasmota32s3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-S3 with USB HWCDC and fallback to serial and 4M+ flash. -- **tasmota32-AD.bin** to **tasmota32-VN.bin** = The Tasmota version in different languages for 4M+ flash. -- **tasmota32-bluetooth.bin** = The Bluetooth version adds BLE support for 4M+ flash. -- **tasmota32-display.bin** = The Display version without Energy Monitoring but adds display support for 4M+ flash. -- **tasmota32-ir.bin** = The InfraRed Receiver and transmitter version allowing all available protocols provided by library IRremoteESP8266 but without most other features for 4M+ flash. -- **tasmota32-lvgl.bin** = The LVGL version adds Light and Versatile Graphics Library (LVGL) display support for 4M+ flash. -- **tasmota32-nspanel.bin** = The Sonoff NSPanel Smart Scene Wall Switch version with HASPmota display support. -- **tasmota32-webcam.bin** = The Webcam version adds webcam support for 4M+ flash. -- **tasmota32-zbbridgepro.bin** - The Sonoff Zigbee Bridge Pro version with CC2652P firmware load support. - -Latest released binaries can be downloaded from -- https://github.com/arendst/Tasmota-firmware/tree/firmware/release-firmware -- https://ota.tasmota.com/tasmota32/release - -Historical binaries can be downloaded from -- https://ota.tasmota.com/tasmota32/release-15.2.0 - -The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasmota.com/tasmota32/release/tasmota32.bin`` - -## Additional information - -[List](MODULES.md) of embedded modules. - -[Complete list](BUILDS.md) of available feature and sensors. - -## Changelog v15.2.0.5 -### Added -- Support for TCA9554 8-bit I/O expander mutually exclusive with PCA9557 -- Support for Adafruit I2C QT Rotary Encoder [#24270](https://github.com/arendst/Tasmota/issues/24270) -- Improv USB CDC connected devices -- Dingtian `SetOption81 1` to invert input and `SetOption133 1` to invert output [#24364](https://github.com/arendst/Tasmota/issues/24364) -- Zigbee support for `int24` type [#24334](https://github.com/arendst/Tasmota/issues/24334) -- Berry `path.listdir("file.tapp#")` to list directory inside '.tapp' archives [#24367](https://github.com/arendst/Tasmota/issues/24367) - -### Changed -- ESP8266 platform update from 2025.10.00 to 2026.01.00 [#24354](https://github.com/arendst/Tasmota/issues/24354) -- ESP32 Platform from 2025.12.30 to 2026.02.30, Framework (Arduino Core) from v3.1.7 to v3.1.10 and IDF from v5.3.4.251205 to v5.3.4.260127 [#24444](https://github.com/arendst/Tasmota/issues/24444) -- Vid6608 library from v1.0.2 to v1.0.3 [#24218](https://github.com/arendst/Tasmota/issues/24218) -- IRremoteESP8266 library from v2.8.6 to v2.8.6-ca474a6 [#24226](https://github.com/arendst/Tasmota/issues/24226) -- Refactor Adafruit Seesaw soil driver [#24270](https://github.com/arendst/Tasmota/issues/24270) -- LM75AD output when no valid reading received from 0 to null [#24263](https://github.com/arendst/Tasmota/issues/24263) -- Dingtian define `DINGTIAN_INPUTS_INVERTED` replaced by `SetOption81` [#24364](https://github.com/arendst/Tasmota/issues/24364) -- Update Zigbee WebUI [#24224](https://github.com/arendst/Tasmota/issues/24224) -- JPEG decoder [#24368](https://github.com/arendst/Tasmota/issues/24368) - -### Fixed -- ESP8266 TasmotaSerial flush receive buffer on executing `TasmotaSerial.flush();` -- ESP8266 KNX unwanted reply [#24267](https://github.com/arendst/Tasmota/issues/24267) -- ESP32-P4 unique MQTT Client based on hosted MCU MAC address -- ScrubDNS() function [#23886](https://github.com/arendst/Tasmota/issues/23886) -- GDK101 power on detection [#24242](https://github.com/arendst/Tasmota/issues/24242) -- Udisplay backlight with SPI displays [#24277](https://github.com/arendst/Tasmota/issues/24277) -- Udisplay SPI driver display dimension parameters regression from v15.1.0.1 [#24376](https://github.com/arendst/Tasmota/issues/24376) -- Display ST77xx and Parallel issues introduced after refactor UDisplay [#24368](https://github.com/arendst/Tasmota/issues/24368) -- DALI watchdog exception -- TuyaMCU v1 exception 28 regression from v15.1.0.1 reverted PR24063 [#24220](https://github.com/arendst/Tasmota/issues/24220) -- ESP32 BearSSL hw accelerated SHA1 [#24397](https://github.com/arendst/Tasmota/issues/24397) -- ESP32 BLE not starting [#24240](https://github.com/arendst/Tasmota/issues/24240) -- Zigbee compilation warning in Berry mapping [#24333](https://github.com/arendst/Tasmota/issues/24333) - -### Removed -- Berry `animate` to be replaced with `animation` framework [#24241](https://github.com/arendst/Tasmota/issues/24241) -- AlpineJS 2.8.2 - not needed anymore [#24427](https://github.com/arendst/Tasmota/issues/24427) + + + Logo + + +# RELEASE NOTES + +## Migration Information + +**This version removes support for direct migration from versions before v8.1.0 (Doris)** + +See [migration path](https://tasmota.github.io/docs/Upgrading#migration-path) for instructions how to migrate to a major version. + +**Do not upgrade from minimal to minimal version. It will most likely fail at some point and will require flashing via serial.** If you do have to use minimal versions, always OTA to a full version of the same release before applying next minimal version. + +Pay attention to the following version breaks due to dynamic settings updates: + +1. Migrate to **Sonoff-Tasmota 3.9.x** +2. Migrate to **Sonoff-Tasmota 4.x** +3. Migrate to **Sonoff-Tasmota 5.14** (http://ota.tasmota.com/tasmota/release_5.14.0/sonoff.bin) - NOTICE underscore as a dash is not supported in older versions +4. Migrate to **Sonoff-Tasmota 6.7.1** (http://ota.tasmota.com/tasmota/release_6.7.1/sonoff.bin) - NOTICE underscore as a dash is not supported in older versions +5. Migrate to **Tasmota 7.2.0** (http://ota.tasmota.com/tasmota/release-7.2.0/tasmota.bin) + +--- Major change in parameter storage layout --- + +6. Migrate to **Tasmota 8.5.1** (http://ota.tasmota.com/tasmota/release-8.5.1/tasmota.bin) + +--- Major change in internal GPIO function representation --- + +7. Migrate to **Tasmota 9.1** (http://ota.tasmota.com/tasmota/release-9.1.0/tasmota.bin.gz) +8. Upgrade to **latest release** (http://ota.tasmota.com/tasmota/release/tasmota.bin.gz) + +While fallback or downgrading is common practice it was never supported due to Settings additions or changes in newer releases. Starting with release **v9.1.0 Imogen** the internal GPIO function representation has changed in such a way that fallback is only possible to the latest GPIO configuration before installing **v9.1.0**. + +## Supported Core versions + +This release will be supported from ESP8266/Arduino library Core version **2.7.8** due to reported security and stability issues on previous Core version. This will also support gzipped binaries. + +This release will be supported from ESP32/Arduino library Core version **v3.1.10**. + +Support of ESP8266 Core versions before 2.7.8 and ESP32 Core versions before v3.1.10 have been removed. + +## Initial configuration tools + +For initial configuration this release supports Webserver based **WifiManager** or **Serial** based command interface. + +## Initial installation + +Easy initial installation of Tasmota can be performed using the [Tasmota WebInstaller](https://tasmota.github.io/install/). + +## Provided Binary Downloads + +### ESP8266 or ESP8285 based +The following binary downloads have been compiled with ESP8266/Arduino library core version **2.7.8**. + +- **tasmota.bin** = The Tasmota version with most drivers for 1M+ flash. **RECOMMENDED RELEASE BINARY** +- **tasmota-4M.bin** = The Tasmota version with most drivers and filesystem for 4M+ flash. +- **tasmota-AD.bin** to **tasmota-VN.bin** = The Tasmota version in different languages for 1M+ flash. +- **tasmota-lite.bin** = The Lite version without most drivers and sensors for 1M+ flash. +- **tasmota-knx.bin** = The Knx version without some features but adds KNX support for 1M+ flash. +- **tasmota-sensors.bin** = The Sensors version adds more useful sensors for 1M+ flash. +- **tasmota-ir.bin** = The InfraRed Receiver and transmitter version allowing all available protocols provided by library IRremoteESP8266 but without most other features for 1M+ flash. +- **tasmota-display.bin** = The Display version without Energy Monitoring but adds display support for 1M+ flash. +- **tasmota-zbbridge.bin** = The dedicated Sonoff Zigbee Bridge version for 2M+ flash. +- **tasmota-zigbee.bin** = The dedicated cc25xx Zigbee Bridge version for 4M+ flash. + +Above binaries are also available as gzipped version allowing faster uploads. + +Latest released binaries can be downloaded from +- https://github.com/arendst/Tasmota-firmware/tree/firmware/release-firmware +- http://ota.tasmota.com/tasmota/release + +Historical binaries can be downloaded from +- http://ota.tasmota.com/tasmota/release-15.2.0 + +The latter links can be used for OTA upgrades too like ``OtaUrl http://ota.tasmota.com/tasmota/release/tasmota.bin.gz`` + +### ESP32, ESP32-C2, ESP32-C3, ESP32-C5, ESP32-C6, ESP32-P4, ESP32-S2 and ESP32-S3 based +The following binary downloads have been compiled with ESP32/Arduino library core version **v3.1.10**. + +- **tasmota32.bin** = The Tasmota version with most drivers including additional sensors and KNX for 4M+ flash. **RECOMMENDED RELEASE BINARY** +- **tasmota32solo1.bin** = The Tasmota version with most drivers including additional sensors and KNX for single core ESP32 and 4M+ flash. +- **tasmota32c2.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C2 with serial and 4M+ flash. +- **tasmota32c3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C3 with USB HWCDC and fallback to serial and 4M+ flash. +- **tasmota32c5.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C5 with USB HWCDC and fallback to serial and 4M+ flash. +- **tasmota32c6.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-C6 with USB HWCDC and fallback to serial and 4M+ flash. +- **tasmota32p4.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-P4 with USB HWCDC and fallback to serial and 4M+ flash. +- **tasmota32s2.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-S2 with serial and 4M+ flash. +- **tasmota32s2cdc.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-S2 with serial over embedded USB CDC only and 4M+ flash. +- **tasmota32s3.bin** = The Tasmota version with most drivers including additional sensors and KNX for ESP32-S3 with USB HWCDC and fallback to serial and 4M+ flash. +- **tasmota32-AD.bin** to **tasmota32-VN.bin** = The Tasmota version in different languages for 4M+ flash. +- **tasmota32-bluetooth.bin** = The Bluetooth version adds BLE support for 4M+ flash. +- **tasmota32-display.bin** = The Display version without Energy Monitoring but adds display support for 4M+ flash. +- **tasmota32-ir.bin** = The InfraRed Receiver and transmitter version allowing all available protocols provided by library IRremoteESP8266 but without most other features for 4M+ flash. +- **tasmota32-lvgl.bin** = The LVGL version adds Light and Versatile Graphics Library (LVGL) display support for 4M+ flash. +- **tasmota32-nspanel.bin** = The Sonoff NSPanel Smart Scene Wall Switch version with HASPmota display support. +- **tasmota32-webcam.bin** = The Webcam version adds webcam support for 4M+ flash. +- **tasmota32-zbbridgepro.bin** - The Sonoff Zigbee Bridge Pro version with CC2652P firmware load support. + +Latest released binaries can be downloaded from +- https://github.com/arendst/Tasmota-firmware/tree/firmware/release-firmware +- https://ota.tasmota.com/tasmota32/release + +Historical binaries can be downloaded from +- https://ota.tasmota.com/tasmota32/release-15.2.0 + +The latter links can be used for OTA upgrades too like ``OtaUrl https://ota.tasmota.com/tasmota32/release/tasmota32.bin`` + +## Additional information + +[List](MODULES.md) of embedded modules. + +[Complete list](BUILDS.md) of available feature and sensors. + +## Changelog v15.2.0.5 +### Added +- Support for TCA9554 8-bit I/O expander mutually exclusive with PCA9557 +- Support for Adafruit I2C QT Rotary Encoder [#24270](https://github.com/arendst/Tasmota/issues/24270) +- Improv USB CDC connected devices +- Dingtian `SetOption81 1` to invert input and `SetOption133 1` to invert output [#24364](https://github.com/arendst/Tasmota/issues/24364) +- Zigbee support for `int24` type [#24334](https://github.com/arendst/Tasmota/issues/24334) +- Berry `path.listdir("file.tapp#")` to list directory inside '.tapp' archives [#24367](https://github.com/arendst/Tasmota/issues/24367) + +### Changed +- ESP8266 platform update from 2025.10.00 to 2026.01.00 [#24354](https://github.com/arendst/Tasmota/issues/24354) +- ESP32 Platform from 2025.12.30 to 2026.02.30, Framework (Arduino Core) from v3.1.7 to v3.1.10 and IDF from v5.3.4.251205 to v5.3.4.260127 [#24444](https://github.com/arendst/Tasmota/issues/24444) +- Vid6608 library from v1.0.2 to v1.0.3 [#24218](https://github.com/arendst/Tasmota/issues/24218) +- IRremoteESP8266 library from v2.8.6 to v2.8.6-ca474a6 [#24226](https://github.com/arendst/Tasmota/issues/24226) +- Refactor Adafruit Seesaw soil driver [#24270](https://github.com/arendst/Tasmota/issues/24270) +- LM75AD output when no valid reading received from 0 to null [#24263](https://github.com/arendst/Tasmota/issues/24263) +- Dingtian define `DINGTIAN_INPUTS_INVERTED` replaced by `SetOption81` [#24364](https://github.com/arendst/Tasmota/issues/24364) +- Update Zigbee WebUI [#24224](https://github.com/arendst/Tasmota/issues/24224) +- JPEG decoder [#24368](https://github.com/arendst/Tasmota/issues/24368) + +### Fixed +- ESP8266 TasmotaSerial flush receive buffer on executing `TasmotaSerial.flush();` +- ESP8266 KNX unwanted reply [#24267](https://github.com/arendst/Tasmota/issues/24267) +- ESP32-P4 unique MQTT Client based on hosted MCU MAC address +- ScrubDNS() function [#23886](https://github.com/arendst/Tasmota/issues/23886) +- GDK101 power on detection [#24242](https://github.com/arendst/Tasmota/issues/24242) +- Udisplay backlight with SPI displays [#24277](https://github.com/arendst/Tasmota/issues/24277) +- Udisplay SPI driver display dimension parameters regression from v15.1.0.1 [#24376](https://github.com/arendst/Tasmota/issues/24376) +- Display ST77xx and Parallel issues introduced after refactor UDisplay [#24368](https://github.com/arendst/Tasmota/issues/24368) +- DALI watchdog exception +- TuyaMCU v1 exception 28 regression from v15.1.0.1 reverted PR24063 [#24220](https://github.com/arendst/Tasmota/issues/24220) +- ESP32 BearSSL hw accelerated SHA1 [#24397](https://github.com/arendst/Tasmota/issues/24397) +- ESP32 BLE not starting [#24240](https://github.com/arendst/Tasmota/issues/24240) +- Zigbee compilation warning in Berry mapping [#24333](https://github.com/arendst/Tasmota/issues/24333) + +### Removed +- Berry `animate` to be replaced with `animation` framework [#24241](https://github.com/arendst/Tasmota/issues/24241) +- AlpineJS 2.8.2 - not needed anymore [#24427](https://github.com/arendst/Tasmota/issues/24427) diff --git a/boards/esp32s2.json b/boards/esp32s2.json index 8ee95aa39..020be7b61 100644 --- a/boards/esp32s2.json +++ b/boards/esp32s2.json @@ -1,43 +1,43 @@ -{ - "build": { - "core": "esp32", - "extra_flags": "-DARDUINO_TASMOTA -DBOARD_HAS_PSRAM -DESP32_4M -DESP32S2", - "f_cpu": "240000000L", - "f_flash": "80000000L", - "flash_mode": "dio", - "mcu": "esp32s2", - "variant": "esp32s2", - "partitions": "partitions/esp32_partition_app2880k_fs320k.csv" - }, - "connectivity": [ - "wifi" - ], - "debug": { - "openocd_target": "esp32s2.cfg" - }, - "frameworks": [ - "arduino", - "espidf" - ], - "name": "Espressif Generic ESP32-S2 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS", - "upload": { - "arduino": { - "flash_extra_images": [ - [ - "0x10000", - "tasmota32s2-safeboot.bin" - ] - ] - }, - "flash_size": "4MB", - "maximum_ram_size": 327680, - "maximum_size": 4194304, - "require_upload_port": true, - "speed": 460800 - }, - "download": { - "speed": 230400 - }, - "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html", - "vendor": "Espressif" -} +{ + "build": { + "core": "esp32", + "extra_flags": "-DARDUINO_TASMOTA -DBOARD_HAS_PSRAM -DESP32_4M -DESP32S2", + "f_cpu": "240000000L", + "f_flash": "80000000L", + "flash_mode": "dio", + "mcu": "esp32s2", + "variant": "esp32s2", + "partitions": "partitions/esp32_partition_app2880k_fs320k.csv" + }, + "connectivity": [ + "wifi" + ], + "debug": { + "openocd_target": "esp32s2.cfg" + }, + "frameworks": [ + "arduino", + "espidf" + ], + "name": "Espressif Generic ESP32-S2 >= 4M Flash PSRAM, Tasmota 2880k Code/OTA, 320k FS", + "upload": { + "arduino": { + "flash_extra_images": [ + [ + "0x10000", + "tasmota32s2-safeboot.bin" + ] + ] + }, + "flash_size": "4MB", + "maximum_ram_size": 327680, + "maximum_size": 4194304, + "require_upload_port": true, + "speed": 460800 + }, + "download": { + "speed": 230400 + }, + "url": "https://docs.espressif.com/projects/esp-idf/en/latest/esp32s2/hw-reference/esp32s2/user-guide-saola-1-v1.2.html", + "vendor": "Espressif" +} diff --git a/boards/esp8266_1M.json b/boards/esp8266_1M.json index f07889d94..107e97837 100644 --- a/boards/esp8266_1M.json +++ b/boards/esp8266_1M.json @@ -1,30 +1,30 @@ -{ - "build": { - "arduino": { - "ldscript": "eagle.flash.1m.ld" - }, - "core": "esp8266", - "extra_flags": "-DARDUINO_TASMOTA -DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01 -DESP8266_1M", - "f_cpu": "80000000L", - "f_flash": "40000000L", - "flash_mode": "dout", - "mcu": "esp8266", - "variant": "generic" - }, - "connectivity": [ - "wifi" - ], - "frameworks": [ - "arduino" - ], - "name": "Espressif Generic ESP8266 Tasmota 1M sketch NO FS", - "upload": { - "maximum_ram_size": 81920, - "maximum_size": 995326, - "require_upload_port": true, - "resetmethod": "ck", - "speed": 115200 - }, - "url": "http://www.esp8266.com/wiki/doku.php?id=esp8266-module-family", - "vendor": "Espressif" -} +{ + "build": { + "arduino": { + "ldscript": "eagle.flash.1m.ld" + }, + "core": "esp8266", + "extra_flags": "-DARDUINO_TASMOTA -DESP8266 -DARDUINO_ARCH_ESP8266 -DARDUINO_ESP8266_ESP01 -DESP8266_1M", + "f_cpu": "80000000L", + "f_flash": "40000000L", + "flash_mode": "dout", + "mcu": "esp8266", + "variant": "generic" + }, + "connectivity": [ + "wifi" + ], + "frameworks": [ + "arduino" + ], + "name": "Espressif Generic ESP8266 Tasmota 1M sketch NO FS", + "upload": { + "maximum_ram_size": 81920, + "maximum_size": 995326, + "require_upload_port": true, + "resetmethod": "ck", + "speed": 115200 + }, + "url": "http://www.esp8266.com/wiki/doku.php?id=esp8266-module-family", + "vendor": "Espressif" +} diff --git a/include/tasmota_options.h b/include/tasmota_options.h index ebfc69019..6c37bf729 100644 --- a/include/tasmota_options.h +++ b/include/tasmota_options.h @@ -1,26 +1,26 @@ -/* - tasmota_include.h - header to be included in libs for external configuration via Tasmota ifdefs - - Copyright (C) 2021 Theo Arends - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef __TASMOTA_INCLUDE__ -#define __TASMOTA_INCLUDE__ - -#include "../tasmota/my_user_config.h" -#include "../tasmota/include/tasmota_configurations.h" - +/* + tasmota_include.h - header to be included in libs for external configuration via Tasmota ifdefs + + Copyright (C) 2021 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef __TASMOTA_INCLUDE__ +#define __TASMOTA_INCLUDE__ + +#include "../tasmota/my_user_config.h" +#include "../tasmota/include/tasmota_configurations.h" + #endif // __TASMOTA_INCLUDE__ \ No newline at end of file diff --git a/lib/lib_audio/mp3_shine_esp32/COPYING b/lib/lib_audio/mp3_shine_esp32/COPYING index 7ccf9c7ff..bf50f20de 100755 --- a/lib/lib_audio/mp3_shine_esp32/COPYING +++ b/lib/lib_audio/mp3_shine_esp32/COPYING @@ -1,482 +1,482 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the - Free Software Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307 USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if +you distribute copies of the library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, so that any problems introduced by others will not reflect on +the original authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, complete source code means +all the source code for all modules it contains, plus any associated +interface definition files, plus the scripts used to control compilation +and installation of the library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete source code as you receive it, in any medium, provided that +you conspicuously and appropriately publish on each copy an +appropriate copyright notice and disclaimer of warranty; keep intact +all the notices that refer to this License and to the absence of any +warranty; and distribute a copy of this License along with the +Library. + + You may charge a fee for the physical act of transferring a copy, +and you may at your option offer warranty protection in exchange for a +fee. + + 2. You may modify your copy or copies of the Library or any portion +of it, thus forming a work based on the Library, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Library, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote +it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you accompany +it with the complete corresponding machine-readable source code, which +must be distributed under the terms of Sections 1 and 2 above on a +medium customarily used for software interchange. + + If distribution of object code is made by offering access to copy +from a designated place, then offering equivalent access to copy the +source code from the same place satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. However, as a special exception, +the source code distributed need not include anything that is normally +distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies +the executable. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library is void, and will automatically terminate your +rights under this License. However, parties who have received copies, +or rights, from you under this License will not have their licenses +terminated so long as such parties remain in full compliance. + + 9. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +subject to these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 11. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Library. + +If any portion of this section is held invalid or unenforceable under any +particular circumstance, the balance of the section is intended to apply, +and the section as a whole is intended to apply in other circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library under this License may add +an explicit geographical distribution limitation excluding those countries, +so that distribution is permitted only in or among countries not thus +excluded. In such case, this License incorporates the limitation as if +written in the body of this License. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library General Public License from time to time. +Such new versions will be similar in spirit to the present version, +but may differ in detail to address new problems or concerns. + +Each version is given a distinguishing version number. If the Library +specifies a version number of this License which applies to it and +"any later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +write to the author to ask for permission. For software which is +copyrighted by the Free Software Foundation, write to the Free +Software Foundation; we sometimes make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. It is +safest to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least the +"copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 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 + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307 USA. + +Also add information on how to contact you by electronic and paper mail. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/lib/lib_audio/mp3_shine_esp32/changelog.txt b/lib/lib_audio/mp3_shine_esp32/changelog.txt index c7ca1b320..0257a82e2 100755 --- a/lib/lib_audio/mp3_shine_esp32/changelog.txt +++ b/lib/lib_audio/mp3_shine_esp32/changelog.txt @@ -1,2 +1,2 @@ -0.1.4: better input wav file handling (from Yichin Lin) -code cleanup +0.1.4: better input wav file handling (from Yichin Lin) +code cleanup diff --git a/lib/lib_audio/mp3_shine_esp32/src/bitstream.h b/lib/lib_audio/mp3_shine_esp32/src/bitstream.h index 10c1beadf..add97c72d 100755 --- a/lib/lib_audio/mp3_shine_esp32/src/bitstream.h +++ b/lib/lib_audio/mp3_shine_esp32/src/bitstream.h @@ -1,28 +1,28 @@ -#ifndef BITSTREAM_H -#define BITSTREAM_H - -typedef struct bit_stream_struc { - unsigned char *data; /* Processed data */ - int data_size; /* Total data size */ - int data_position; /* Data position */ - unsigned int cache; /* bit stream cache */ - int cache_bits; /* free bits in cache */ -} bitstream_t; - -/* "bit_stream.h" Definitions */ - -#define MINIMUM 4 /* Minimum size of the buffer in bytes */ -#define MAX_LENGTH 32 /* Maximum length of word written or - read from bit stream */ - -#define BUFFER_SIZE 4096 - -//#define MIN(A, B) ((A) < (B) ? (A) : (B)) -//#define MAX(A, B) ((A) > (B) ? (A) : (B)) - -void shine_open_bit_stream(bitstream_t *bs,const int size); -void shine_close_bit_stream(bitstream_t *bs); -void shine_putbits(bitstream_t *bs,unsigned int val, unsigned int N); -int shine_get_bits_count(bitstream_t *bs); - -#endif +#ifndef BITSTREAM_H +#define BITSTREAM_H + +typedef struct bit_stream_struc { + unsigned char *data; /* Processed data */ + int data_size; /* Total data size */ + int data_position; /* Data position */ + unsigned int cache; /* bit stream cache */ + int cache_bits; /* free bits in cache */ +} bitstream_t; + +/* "bit_stream.h" Definitions */ + +#define MINIMUM 4 /* Minimum size of the buffer in bytes */ +#define MAX_LENGTH 32 /* Maximum length of word written or + read from bit stream */ + +#define BUFFER_SIZE 4096 + +//#define MIN(A, B) ((A) < (B) ? (A) : (B)) +//#define MAX(A, B) ((A) > (B) ? (A) : (B)) + +void shine_open_bit_stream(bitstream_t *bs,const int size); +void shine_close_bit_stream(bitstream_t *bs); +void shine_putbits(bitstream_t *bs,unsigned int val, unsigned int N); +int shine_get_bits_count(bitstream_t *bs); + +#endif diff --git a/lib/lib_audio/mp3_shine_esp32/src/huffman.cpp b/lib/lib_audio/mp3_shine_esp32/src/huffman.cpp index d4bd6aaf8..f043c63ce 100755 --- a/lib/lib_audio/mp3_shine_esp32/src/huffman.cpp +++ b/lib/lib_audio/mp3_shine_esp32/src/huffman.cpp @@ -1,120 +1,120 @@ -/* huffman.c */ - -#include "types.h" -#include "huffman.h" -#include "bitstream.h" -#include "l3bitstream.h" - -const HUFFBITS dmask = 1 << (((sizeof(HUFFBITS))<<3)-1); -const unsigned int hs = sizeof(HUFFBITS)<<3; - -static const HUFFBITS t1HB[] = {1, 1, 1, 0}; -static const HUFFBITS t2HB[] = {1, 2, 1, 3, 1, 1, 3, 2, 0}; -static const HUFFBITS t3HB[] = {3, 2, 1, 1, 1, 1, 3, 2, 0}; -static const HUFFBITS t5HB[] = {1, 2, 6, 5, 3, 1, 4, 4, 7, 5, 7, 1, 6, 1, 1, 0}; -static const HUFFBITS t6HB[] = {7, 3, 5, 1, 6, 2, 3, 2, 5, 4, 4, 1, 3, 3, 2, 0}; -static const HUFFBITS t7HB[] = {1, 2, 10, 19, 16, 10, 3, 3, 7, 10, 5, 3, 11, 4, 13, 17, 8, 4, 12, 11, 18, 15, 11, 2, 7, 6, 9, 14, 3, 1, 6, 4, 5, 3, 2, 0}; -static const HUFFBITS t8HB[] = {3, 4, 6, 18, 12, 5, 5, 1, 2, 16, 9, 3, 7, 3, 5, 14, 7, 3, 19, 17, 15, 13, 10, 4, 13, 5, 8, 11, 5, 1, 12, 4, 4, 1, 1, 0}; -static const HUFFBITS t9HB[] = {7, 5, 9, 14, 15, 7, 6, 4, 5, 5, 6, 7, 7, 6, 8, 8, 8, 5, 15, 6, 9, 10, 5, 1, 11, 7, 9, 6, 4, 1, 14, 4, 6, 2, 6, 0}; -static const HUFFBITS t10HB[] = {1, 2, 10, 23, 35, 30, 12, 17, 3, 3, 8, 12, 18, 21, 12, 7, 11, 9, 15, 21, 32, 40, 19, 6, 14, 13, 22, 34, 46, 23, 18, 7, 20, 19, 33, 47, 27, 22, 9, 3, 31, 22, 41, 26, 21, 20, 5, 3, 14, 13, 10, 11, 16, 6, 5, 1, 9, 8, 7, 8, 4 , 4, 2, 0}; -static const HUFFBITS t11HB[] = {3, 4, 10, 24, 34, 33, 21, 15, 5, 3, 4, 10, 32, 17, 11, 10, 11, 7, 13, 18, 30, 31, 20, 5, 25, 11, 19, 59, 27, 18, 12, 5, 35, 33, 31, 58, 30, 16, 7, 5, 28, 26, 32, 19, 17, 15, 8, 14, 14, 12, 9, 13, 14, 9, 4, 1, 11, 4, 6, 6, 6, 3, 2, 0}; -static const HUFFBITS t12HB[] = {9, 6, 16, 33, 41, 39, 38, 26, 7, 5, 6, 9, 23, 16, 26, 11, 17, 7, 11, 14, 21, 30, 10, 7, 17, 10, 15, 12, 18, 28, 14, 5, 32, 13, 22, 19, 18, 16, 9, 5, 40, 17, 31, 29, 17, 13, 4, 2, 27, 12, 11, 15, 10, 7, 4, 1, 27, 12, 8, 12 , 6, 3, 1, 0}; -static const HUFFBITS t13HB[] = {1, 5, 14, 21, 34, 51, 46, 71, 42, 52, 68, 52, 67, 44, 43, 19, 3, 4, 12, 19, 31, 26, 44, 33, 31, 24, 32, 24, 31, 35, 22, 14, 15, 13, 23, 36, 59, 49, 77, 65, 29, 40, 30, 40, 27, 33, 42, 16, 22, - 20, 37, 61, 56, 79, 73, 64, 43, 76, 56, 37, 26, 31, 25, 14, 35, 16, 60, 57, 97, 75, 114, 91, 54, 73, 55, 41, 48, 53, 23, 24, 58, 27, 50, 96, 76, 70, 93, 84, 77, 58, 79, 29, 74, 49, 41, 17, 47, - 45, 78, 74, 115, 94, 90, 79, 69, 83, 71, 50, 59, 38, 36, 15, 72, 34, 56, 95, 92, 85, 91, 90, 86, 73, 77, 65, 51, 44, 43, 42, 43, 20, 30, 44, 55, 78, 72, 87, 78, 61, 46, 54, 37, 30, 20, 16, 53, - 25, 41, 37, 44, 59, 54, 81, 66, 76, 57, 54, 37, 18, 39, 11, 35, 33, 31, 57, 42, 82, 72, 80, 47, 58, 55, 21, 22, 26, 38, 22, 53, 25, 23, 38, 70, 60, 51, 36, 55, 26, 34, 23, 27, 14, 9, 7, 34, 32, - 28, 39, 49, 75, 30, 52, 48, 40, 52, 28, 18, 17, 9, 5, 45, 21, 34, 64, 56, 50, 49, 45, 31, 19, 12, 15, 10, 7, 6, 3, 48, 23, 20, 39, 36, 35, 53, 21, 16, 23, 13, 10, 6, 1, 4, 2, 16, 15, 17, 27, 25, - 20, 29, 11, 17, 12, 16, 8, 1, 1, 0, 1}; -static const HUFFBITS t15HB[] = {7, 12, 18, 53, 47, 76, 124, 108, 89, 123, 108, 119, 107, 81, 122, 63, 13, 5, 16, 27, 46, 36, 61, 51, 42, 70, 52, 83, 65, 41, 59, 36, 19, 17, 15, 24, 41, 34, 59, 48, 40, 64, 50, 78, 62, 80, 56, - 33, 29, 28, 25, 43, 39, 63, 55, 93, 76, 59, 93, 72, 54, 75, 50, 29, 52, 22, 42, 40, 67, 57, 95, 79, 72, 57, 89, 69, 49, 66, 46, 27, 77, 37, 35, 66, 58, 52, 91, 74, 62, 48, 79, 63, 90, 62, 40, 38, - 125, 32, 60, 56, 50, 92, 78, 65, 55, 87, 71, 51, 73, 51, 70, 30, 109, 53, 49, 94, 88, 75, 66, 122, 91, 73, 56, 42, 64, 44, 21, 25, 90, 43, 41, 77, 73, 63, 56, 92, 77, 66, 47, 67, 48, 53, 36, 20, - 71, 34, 67, 60, 58, 49, 88, 76, 67, 106, 71, 54, 38, 39, 23, 15, 109, 53, 51, 47, 90, 82, 58, 57, 48, 72, 57, 41, 23, 27, 62, 9, 86, 42, 40, 37, 70, 64, 52, 43, 70, 55, 42, 25, 29, 18, 11, 11, - 118, 68, 30, 55, 50, 46, 74, 65, 49, 39, 24, 16, 22, 13, 14, 7, 91, 44, 39, 38, 34, 63, 52, 45, 31, 52, 28, 19, 14, 8, 9, 3, 123, 60, 58, 53, 47, 43, 32, 22, 37, 24, 17, 12, 15, 10, 2, 1, 71, - 37, 34, 30, 28, 20, 17, 26, 21, 16, 10, 6, 8, 6, 2, 0}; -static const HUFFBITS t16HB[] = {1, 5, 14, 44, 74, 63, 110, 93, 172, 149, 138, 242, 225, 195, 376, 17, 3, 4, 12, 20, 35, 62, 53, 47, 83, 75, 68, 119, 201, 107, 207, 9, 15, 13, 23, 38, 67, 58, 103, 90, 161, 72, 127, 117, - 110, 209, 206, 16, 45, 21, 39, 69, 64, 114, 99, 87, 158, 140, 252, 212, 199, 387, 365, 26, 75, 36, 68, 65, 115, 101, 179, 164, 155, 264, 246, 226, 395, 382, 362, 9, 66, 30, 59, 56, 102, - 185, 173, 265, 142, 253, 232, 400, 388, 378, 445, 16, 111, 54, 52, 100, 184, 178, 160, 133, 257, 244, 228, 217, 385, 366, 715, 10, 98, 48, 91, 88, 165, 157, 148, 261, 248, 407, 397, 372, - 380, 889, 884, 8, 85, 84, 81, 159, 156, 143, 260, 249, 427, 401, 392, 383, 727, 713, 708, 7, 154, 76, 73, 141, 131, 256, 245, 426, 406, 394, 384, 735, 359, 710, 352, 11, 139, 129, 67, 125, - 247, 233, 229, 219, 393, 743, 737, 720, 885, 882, 439, 4, 243, 120, 118, 115, 227, 223, 396, 746, 742, 736, 721, 712, 706, 223, 436, 6, 202, 224, 222, 218, 216, 389, 386, 381, 364, 888, - 443, 707, 440, 437, 1728, 4, 747, 211, 210, 208, 370, 379, 734, 723, 714, 1735, 883, 877, 876, 3459, 865, 2, 377, 369, 102, 187, 726, 722, 358, 711, 709, 866, 1734, 871, 3458, 870, 434, - 0, 12, 10, 7, 11, 10, 17, 11, 9, 13, 12, 10, 7, 5, 3, 1, 3}; -static const HUFFBITS t24HB[] = {15, 13, 46, 80, 146, 262, 248, 434, 426, 669, 653, 649, 621, 517, 1032, 88, 14, 12, 21, 38, 71, 130, 122, 216, 209, 198, 327, 345, 319, 297, 279, 42, 47, 22, 41, 74, 68, 128, 120, 221, - 207, 194, 182, 340, 315, 295, 541, 18, 81, 39, 75, 70, 134, 125, 116, 220, 204, 190, 178, 325, 311, 293, 271, 16, 147, 72, 69, 135, 127, 118, 112, 210, 200, 188, 352, 323, 306, 285, - 540, 14, 263, 66, 129, 126, 119, 114, 214, 202, 192, 180, 341, 317, 301, 281, 262, 12, 249, 123, 121, 117, 113, 215, 206, 195, 185, 347, 330, 308, 291, 272, 520, 10, 435, 115, 111, - 109, 211, 203, 196, 187, 353, 332, 313, 298, 283, 531, 381, 17, 427, 212, 208, 205, 201, 193, 186, 177, 169, 320, 303, 286, 268, 514, 377, 16, 335, 199, 197, 191, 189, 181, 174, 333, - 321, 305, 289, 275, 521, 379, 371, 11, 668, 184, 183, 179, 175, 344, 331, 314, 304, 290, 277, 530, 383, 373, 366, 10, 652, 346, 171, 168, 164, 318, 309, 299, 287, 276, 263, 513, 375, - 368, 362, 6, 648, 322, 316, 312, 307, 302, 292, 284, 269, 261, 512, 376, 370, 364, 359, 4, 620, 300, 296, 294, 288, 282, 273, 266, 515, 380, 374, 369, 365, 361, 357, 2, 1033, 280, 278, - 274, 267, 264, 259, 382, 378, 372, 367, 363, 360, 358, 356, 0, 43, 20, 19, 17, 15, 13, 11, 9, 7, 6, 4, 7, 5, 3, 1, 3}; -static const HUFFBITS t32HB[] = {1, 5, 4, 5, 6, 5, 4, 4, 7, 3, 6, 0, 7, 2, 3, 1}; -static const HUFFBITS t33HB[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; - -static const unsigned char t1l[] = {1, 3, 2, 3}; -static const unsigned char t2l[] = {1, 3, 6, 3, 3, 5, 5, 5, 6}; -static const unsigned char t3l[] = {2, 2, 6, 3, 2, 5, 5, 5, 6}; -static const unsigned char t5l[] = {1, 3, 6, 7, 3, 3, 6, 7, 6, 6, 7, 8, 7, 6, 7, 8}; -static const unsigned char t6l[] = {3, 3, 5, 7, 3, 2, 4, 5, 4, 4, 5, 6, 6, 5, 6, 7}; -static const unsigned char t7l[] = {1, 3, 6, 8, 8, 9, 3, 4, 6, 7, 7, 8, 6, 5, 7, 8, 8, 9, 7, 7, 8, 9, 9, 9, 7, 7, 8, 9, 9, 10, 8, 8, 9, 10, 10, 10}; -static const unsigned char t8l[] = {2, 3, 6, 8, 8, 9, 3, 2, 4, 8, 8, 8, 6, 4, 6, 8, 8, 9, 8, 8, 8, 9, 9, 10, 8, 7, 8, 9, 10, 10, 9, 8, 9, 9, 11, 11}; -static const unsigned char t9l[] = {3, 3, 5, 6, 8, 9, 3, 3, 4, 5, 6, 8, 4, 4, 5, 6, 7, 8, 6, 5, 6, 7, 7, 8, 7, 6, 7, 7, 8, 9, 8, 7, 8, 8, 9, 9}; -static const unsigned char t10l[] = {1, 3, 6, 8, 9, 9, 9, 10, 3, 4, 6, 7, 8, 9, 8, 8, 6, 6, 7, 8, 9, 10, 9, 9, 7, 7, 8, 9, 10, 10, 9, 10, 8, 8, 9, 10, 10, 10, 10, 10, 9, 9, 10, 10, 11, 11, 10, 11, 8, 8, 9, 10, 10, 10, 11, 11, 9, 8, 9, 10, 10, 11, 11, 11}; -static const unsigned char t11l[] = {2, 3, 5, 7, 8, 9, 8, 9, 3, 3, 4, 6, 8, 8, 7, 8, 5, 5, 6, 7, 8, 9, 8, 8, 7, 6, 7, 9, 8, 10, 8, 9, 8, 8, 8, 9, 9, 10, 9, 10, 8, 8, 9, 10, 10, 11, 10, 11, 8, 7, 7, 8, 9, 10, 10, 10, 8, 7, 8, 9, 10, 10, 10, 10}; -static const unsigned char t12l[] = {4, 3, 5, 7, 8, 9, 9, 9, 3, 3, 4, 5, 7, 7, 8, 8, 5, 4, 5, 6, 7, 8, 7, 8, 6, 5, 6, 6, 7, 8, 8, 8, 7, 6, 7, 7, 8, 8, 8, 9, 8, 7, 8, 8, 8, 9, 8, 9, 8, 7, 7, 8, 8, 9, 9, 10, 9, 8, 8, 9, 9, 9, 9, 10}; -static const unsigned char t13l[] = {1, 4, 6, 7, 8, 9, 9, 10, 9, 10, 11, 11, 12, 12, 13, 13, 3, 4, 6, 7, 8, 8, 9, 9, 9, 9, 10, 10, 11, 12, 12, 12, 6, 6, 7, 8, 9, 9, 10, 10, 9, 10, 10, 11, 11, 12, 13, 13, 7, 7, 8, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 13, 13, -8, 7, 9, 9, 10, 10, 11, 11, 10, 11, 11, 12, 12, 13, 13, 14, 9, 8, 9, 10, 10, 10, 11, 11, 11, 11, 12, 11, 13, 13, 14, 14, 9, 9, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14, 10, 9, 10, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 16, 16, 9, 8, 9, 10, -10, 11, 11, 12, 12, 12, 12, 13, 13, 14, 15, 15, 10, 9, 10, 10, 11, 11, 11, 13, 12, 13, 13, 14, 14, 14, 16, 15, 10, 10, 10, 11, 11, 12, 12, 13, 12, 13, 14, 13, 14, 15, 16, 17, 11, 10, 10, 11, 12, 12, 12, 12, 13, 13, 13, 14, 15, 15, 15, 16, 11, 11, 11, 12, 12, -13, 12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 12, 11, 12, 13, 13, 13, 14, 14, 14, 14, 14, 15, 16, 15, 16, 16, 13, 12, 12, 13, 13, 13, 15, 14, 14, 17, 15, 15, 15, 17, 16, 16, 12, 12, 13, 14, 14, 14, 15, 14, 15, 15, 16, 16, 19, 18, 19, 16}; -static const unsigned char t15l[] = {3, 4, 5, 7, 7, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12, 13, 4, 3, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 5, 5, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 11, 6, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 7, 6, 7, - 7, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 11, 8, 7, 7, 8, 8, 8, 9, 9, 9, 9, 10, 10, 11, 11, 11, 12, 9, 7, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 9, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 12, 9, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, - 12, 12, 12, 9, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 10, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 13, 12, 10, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 11, 10, 9, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 13, 13, -11, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 12, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 12, 13, 12, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13}; -static const unsigned char t16l[] = {1, 4, 6, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 9, 3, 4, 6, 7, 8, 9, 9, 9, 10, 10, 10, 11, 12, 11, 12, 8, 6, 6, 7, 8, 9, 9, 10, 10, 11, 10, 11, 11, 11, 12, 12, 9, 8, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, - 10, 9, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 9, 9, 8, 9, 9, 10, 11, 11, 12, 11, 12, 12, 13, 13, 13, 14, 10, 10, 9, 9, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 10, 10, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 13, 15, 15, 10, 10, 10, - 10, 11, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 14, 10, 11, 10, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 13, 14, 13, 11, 11, 11, 10, 11, 12, 12, 12, 12, 13, 14, 14, 14, 15, 15, 14, 10, 12, 11, 11, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14, 13, 14, 11, 12, 12, - 12, 12, 12, 13, 13, 13, 13, 15, 14, 14, 14, 14, 16, 11, 14, 12, 12, 12, 13, 13, 14, 14, 14, 16, 15, 15, 15, 17, 15, 11, 13, 13, 11, 12, 14, 14, 13, 14, 14, 15, 16, 15, 17, 15, 14, 11, 9, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 8}; -static const unsigned char t24l[] = {4, 4, 6, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 12, 9, 4, 4, 5, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10, 8, 6, 5, 6, 7, 7, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 7, 7, 6, 7, 7, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 7, 8, 7, 7, 8, - 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 7, 9, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 7, 9, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 7, 10, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 8, 10, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, -8, 10, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 8, 11, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 8, 11, 10, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 8, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 8, 11, 10, 10, - 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 8, 12, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 4}; -static const unsigned char t32l[] = {1, 4, 4, 5, 4, 6, 5, 6, 4, 5, 5, 6, 5, 6, 6, 6}; -static const unsigned char t33l[] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; - -#define NOREF -1 -const struct huffcodetab shine_huffman_table[HTN] = -{ -{ 0, 0, 0, 0,NULL,NULL}, -{ 2, 2, 0, 0,t1HB, t1l}, -{ 3, 3, 0, 0,t2HB, t2l}, -{ 3, 3, 0, 0,t3HB, t3l}, -{ 0, 0, 0, 0,NULL,NULL},/* Apparently not used*/ -{ 4, 4, 0, 0,t5HB, t5l}, -{ 4, 4, 0, 0,t6HB, t6l}, -{ 6, 6, 0, 0,t7HB, t7l}, -{ 6, 6, 0, 0,t8HB, t8l}, -{ 6, 6, 0, 0,t9HB, t9l}, -{ 8, 8, 0, 0,t10HB, t10l}, -{ 8, 8, 0, 0,t11HB, t11l}, -{ 8, 8, 0, 0,t12HB, t12l}, -{16,16, 0, 0,t13HB, t13l}, -{ 0, 0, 0, 0,NULL,NULL},/* Apparently not used*/ -{16,16, 0, 0,t15HB, t15l}, -{16,16, 1, 1,t16HB, t16l}, -{16,16, 2, 3,t16HB, t16l}, -{16,16, 3, 7,t16HB, t16l}, -{16,16, 4, 15,t16HB, t16l}, -{16,16, 6, 63,t16HB, t16l}, -{16,16, 8, 255,t16HB, t16l}, -{16,16,10,1023,t16HB, t16l}, -{16,16,13,8191,t16HB, t16l}, -{16,16, 4, 15,t24HB, t24l}, -{16,16, 5, 31,t24HB, t24l}, -{16,16, 6, 63,t24HB, t24l}, -{16,16, 7, 127,t24HB, t24l}, -{16,16, 8, 255,t24HB, t24l}, -{16,16, 9, 511,t24HB, t24l}, -{16,16,11,2047,t24HB, t24l}, -{16,16,13,8191,t24HB, t24l}, -{ 1,16, 0, 0,t32HB, t32l}, -{ 1,16, 0, 0,t33HB, t33l}, -}; - - +/* huffman.c */ + +#include "types.h" +#include "huffman.h" +#include "bitstream.h" +#include "l3bitstream.h" + +const HUFFBITS dmask = 1 << (((sizeof(HUFFBITS))<<3)-1); +const unsigned int hs = sizeof(HUFFBITS)<<3; + +static const HUFFBITS t1HB[] = {1, 1, 1, 0}; +static const HUFFBITS t2HB[] = {1, 2, 1, 3, 1, 1, 3, 2, 0}; +static const HUFFBITS t3HB[] = {3, 2, 1, 1, 1, 1, 3, 2, 0}; +static const HUFFBITS t5HB[] = {1, 2, 6, 5, 3, 1, 4, 4, 7, 5, 7, 1, 6, 1, 1, 0}; +static const HUFFBITS t6HB[] = {7, 3, 5, 1, 6, 2, 3, 2, 5, 4, 4, 1, 3, 3, 2, 0}; +static const HUFFBITS t7HB[] = {1, 2, 10, 19, 16, 10, 3, 3, 7, 10, 5, 3, 11, 4, 13, 17, 8, 4, 12, 11, 18, 15, 11, 2, 7, 6, 9, 14, 3, 1, 6, 4, 5, 3, 2, 0}; +static const HUFFBITS t8HB[] = {3, 4, 6, 18, 12, 5, 5, 1, 2, 16, 9, 3, 7, 3, 5, 14, 7, 3, 19, 17, 15, 13, 10, 4, 13, 5, 8, 11, 5, 1, 12, 4, 4, 1, 1, 0}; +static const HUFFBITS t9HB[] = {7, 5, 9, 14, 15, 7, 6, 4, 5, 5, 6, 7, 7, 6, 8, 8, 8, 5, 15, 6, 9, 10, 5, 1, 11, 7, 9, 6, 4, 1, 14, 4, 6, 2, 6, 0}; +static const HUFFBITS t10HB[] = {1, 2, 10, 23, 35, 30, 12, 17, 3, 3, 8, 12, 18, 21, 12, 7, 11, 9, 15, 21, 32, 40, 19, 6, 14, 13, 22, 34, 46, 23, 18, 7, 20, 19, 33, 47, 27, 22, 9, 3, 31, 22, 41, 26, 21, 20, 5, 3, 14, 13, 10, 11, 16, 6, 5, 1, 9, 8, 7, 8, 4 , 4, 2, 0}; +static const HUFFBITS t11HB[] = {3, 4, 10, 24, 34, 33, 21, 15, 5, 3, 4, 10, 32, 17, 11, 10, 11, 7, 13, 18, 30, 31, 20, 5, 25, 11, 19, 59, 27, 18, 12, 5, 35, 33, 31, 58, 30, 16, 7, 5, 28, 26, 32, 19, 17, 15, 8, 14, 14, 12, 9, 13, 14, 9, 4, 1, 11, 4, 6, 6, 6, 3, 2, 0}; +static const HUFFBITS t12HB[] = {9, 6, 16, 33, 41, 39, 38, 26, 7, 5, 6, 9, 23, 16, 26, 11, 17, 7, 11, 14, 21, 30, 10, 7, 17, 10, 15, 12, 18, 28, 14, 5, 32, 13, 22, 19, 18, 16, 9, 5, 40, 17, 31, 29, 17, 13, 4, 2, 27, 12, 11, 15, 10, 7, 4, 1, 27, 12, 8, 12 , 6, 3, 1, 0}; +static const HUFFBITS t13HB[] = {1, 5, 14, 21, 34, 51, 46, 71, 42, 52, 68, 52, 67, 44, 43, 19, 3, 4, 12, 19, 31, 26, 44, 33, 31, 24, 32, 24, 31, 35, 22, 14, 15, 13, 23, 36, 59, 49, 77, 65, 29, 40, 30, 40, 27, 33, 42, 16, 22, + 20, 37, 61, 56, 79, 73, 64, 43, 76, 56, 37, 26, 31, 25, 14, 35, 16, 60, 57, 97, 75, 114, 91, 54, 73, 55, 41, 48, 53, 23, 24, 58, 27, 50, 96, 76, 70, 93, 84, 77, 58, 79, 29, 74, 49, 41, 17, 47, + 45, 78, 74, 115, 94, 90, 79, 69, 83, 71, 50, 59, 38, 36, 15, 72, 34, 56, 95, 92, 85, 91, 90, 86, 73, 77, 65, 51, 44, 43, 42, 43, 20, 30, 44, 55, 78, 72, 87, 78, 61, 46, 54, 37, 30, 20, 16, 53, + 25, 41, 37, 44, 59, 54, 81, 66, 76, 57, 54, 37, 18, 39, 11, 35, 33, 31, 57, 42, 82, 72, 80, 47, 58, 55, 21, 22, 26, 38, 22, 53, 25, 23, 38, 70, 60, 51, 36, 55, 26, 34, 23, 27, 14, 9, 7, 34, 32, + 28, 39, 49, 75, 30, 52, 48, 40, 52, 28, 18, 17, 9, 5, 45, 21, 34, 64, 56, 50, 49, 45, 31, 19, 12, 15, 10, 7, 6, 3, 48, 23, 20, 39, 36, 35, 53, 21, 16, 23, 13, 10, 6, 1, 4, 2, 16, 15, 17, 27, 25, + 20, 29, 11, 17, 12, 16, 8, 1, 1, 0, 1}; +static const HUFFBITS t15HB[] = {7, 12, 18, 53, 47, 76, 124, 108, 89, 123, 108, 119, 107, 81, 122, 63, 13, 5, 16, 27, 46, 36, 61, 51, 42, 70, 52, 83, 65, 41, 59, 36, 19, 17, 15, 24, 41, 34, 59, 48, 40, 64, 50, 78, 62, 80, 56, + 33, 29, 28, 25, 43, 39, 63, 55, 93, 76, 59, 93, 72, 54, 75, 50, 29, 52, 22, 42, 40, 67, 57, 95, 79, 72, 57, 89, 69, 49, 66, 46, 27, 77, 37, 35, 66, 58, 52, 91, 74, 62, 48, 79, 63, 90, 62, 40, 38, + 125, 32, 60, 56, 50, 92, 78, 65, 55, 87, 71, 51, 73, 51, 70, 30, 109, 53, 49, 94, 88, 75, 66, 122, 91, 73, 56, 42, 64, 44, 21, 25, 90, 43, 41, 77, 73, 63, 56, 92, 77, 66, 47, 67, 48, 53, 36, 20, + 71, 34, 67, 60, 58, 49, 88, 76, 67, 106, 71, 54, 38, 39, 23, 15, 109, 53, 51, 47, 90, 82, 58, 57, 48, 72, 57, 41, 23, 27, 62, 9, 86, 42, 40, 37, 70, 64, 52, 43, 70, 55, 42, 25, 29, 18, 11, 11, + 118, 68, 30, 55, 50, 46, 74, 65, 49, 39, 24, 16, 22, 13, 14, 7, 91, 44, 39, 38, 34, 63, 52, 45, 31, 52, 28, 19, 14, 8, 9, 3, 123, 60, 58, 53, 47, 43, 32, 22, 37, 24, 17, 12, 15, 10, 2, 1, 71, + 37, 34, 30, 28, 20, 17, 26, 21, 16, 10, 6, 8, 6, 2, 0}; +static const HUFFBITS t16HB[] = {1, 5, 14, 44, 74, 63, 110, 93, 172, 149, 138, 242, 225, 195, 376, 17, 3, 4, 12, 20, 35, 62, 53, 47, 83, 75, 68, 119, 201, 107, 207, 9, 15, 13, 23, 38, 67, 58, 103, 90, 161, 72, 127, 117, + 110, 209, 206, 16, 45, 21, 39, 69, 64, 114, 99, 87, 158, 140, 252, 212, 199, 387, 365, 26, 75, 36, 68, 65, 115, 101, 179, 164, 155, 264, 246, 226, 395, 382, 362, 9, 66, 30, 59, 56, 102, + 185, 173, 265, 142, 253, 232, 400, 388, 378, 445, 16, 111, 54, 52, 100, 184, 178, 160, 133, 257, 244, 228, 217, 385, 366, 715, 10, 98, 48, 91, 88, 165, 157, 148, 261, 248, 407, 397, 372, + 380, 889, 884, 8, 85, 84, 81, 159, 156, 143, 260, 249, 427, 401, 392, 383, 727, 713, 708, 7, 154, 76, 73, 141, 131, 256, 245, 426, 406, 394, 384, 735, 359, 710, 352, 11, 139, 129, 67, 125, + 247, 233, 229, 219, 393, 743, 737, 720, 885, 882, 439, 4, 243, 120, 118, 115, 227, 223, 396, 746, 742, 736, 721, 712, 706, 223, 436, 6, 202, 224, 222, 218, 216, 389, 386, 381, 364, 888, + 443, 707, 440, 437, 1728, 4, 747, 211, 210, 208, 370, 379, 734, 723, 714, 1735, 883, 877, 876, 3459, 865, 2, 377, 369, 102, 187, 726, 722, 358, 711, 709, 866, 1734, 871, 3458, 870, 434, + 0, 12, 10, 7, 11, 10, 17, 11, 9, 13, 12, 10, 7, 5, 3, 1, 3}; +static const HUFFBITS t24HB[] = {15, 13, 46, 80, 146, 262, 248, 434, 426, 669, 653, 649, 621, 517, 1032, 88, 14, 12, 21, 38, 71, 130, 122, 216, 209, 198, 327, 345, 319, 297, 279, 42, 47, 22, 41, 74, 68, 128, 120, 221, + 207, 194, 182, 340, 315, 295, 541, 18, 81, 39, 75, 70, 134, 125, 116, 220, 204, 190, 178, 325, 311, 293, 271, 16, 147, 72, 69, 135, 127, 118, 112, 210, 200, 188, 352, 323, 306, 285, + 540, 14, 263, 66, 129, 126, 119, 114, 214, 202, 192, 180, 341, 317, 301, 281, 262, 12, 249, 123, 121, 117, 113, 215, 206, 195, 185, 347, 330, 308, 291, 272, 520, 10, 435, 115, 111, + 109, 211, 203, 196, 187, 353, 332, 313, 298, 283, 531, 381, 17, 427, 212, 208, 205, 201, 193, 186, 177, 169, 320, 303, 286, 268, 514, 377, 16, 335, 199, 197, 191, 189, 181, 174, 333, + 321, 305, 289, 275, 521, 379, 371, 11, 668, 184, 183, 179, 175, 344, 331, 314, 304, 290, 277, 530, 383, 373, 366, 10, 652, 346, 171, 168, 164, 318, 309, 299, 287, 276, 263, 513, 375, + 368, 362, 6, 648, 322, 316, 312, 307, 302, 292, 284, 269, 261, 512, 376, 370, 364, 359, 4, 620, 300, 296, 294, 288, 282, 273, 266, 515, 380, 374, 369, 365, 361, 357, 2, 1033, 280, 278, + 274, 267, 264, 259, 382, 378, 372, 367, 363, 360, 358, 356, 0, 43, 20, 19, 17, 15, 13, 11, 9, 7, 6, 4, 7, 5, 3, 1, 3}; +static const HUFFBITS t32HB[] = {1, 5, 4, 5, 6, 5, 4, 4, 7, 3, 6, 0, 7, 2, 3, 1}; +static const HUFFBITS t33HB[] = {15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; + +static const unsigned char t1l[] = {1, 3, 2, 3}; +static const unsigned char t2l[] = {1, 3, 6, 3, 3, 5, 5, 5, 6}; +static const unsigned char t3l[] = {2, 2, 6, 3, 2, 5, 5, 5, 6}; +static const unsigned char t5l[] = {1, 3, 6, 7, 3, 3, 6, 7, 6, 6, 7, 8, 7, 6, 7, 8}; +static const unsigned char t6l[] = {3, 3, 5, 7, 3, 2, 4, 5, 4, 4, 5, 6, 6, 5, 6, 7}; +static const unsigned char t7l[] = {1, 3, 6, 8, 8, 9, 3, 4, 6, 7, 7, 8, 6, 5, 7, 8, 8, 9, 7, 7, 8, 9, 9, 9, 7, 7, 8, 9, 9, 10, 8, 8, 9, 10, 10, 10}; +static const unsigned char t8l[] = {2, 3, 6, 8, 8, 9, 3, 2, 4, 8, 8, 8, 6, 4, 6, 8, 8, 9, 8, 8, 8, 9, 9, 10, 8, 7, 8, 9, 10, 10, 9, 8, 9, 9, 11, 11}; +static const unsigned char t9l[] = {3, 3, 5, 6, 8, 9, 3, 3, 4, 5, 6, 8, 4, 4, 5, 6, 7, 8, 6, 5, 6, 7, 7, 8, 7, 6, 7, 7, 8, 9, 8, 7, 8, 8, 9, 9}; +static const unsigned char t10l[] = {1, 3, 6, 8, 9, 9, 9, 10, 3, 4, 6, 7, 8, 9, 8, 8, 6, 6, 7, 8, 9, 10, 9, 9, 7, 7, 8, 9, 10, 10, 9, 10, 8, 8, 9, 10, 10, 10, 10, 10, 9, 9, 10, 10, 11, 11, 10, 11, 8, 8, 9, 10, 10, 10, 11, 11, 9, 8, 9, 10, 10, 11, 11, 11}; +static const unsigned char t11l[] = {2, 3, 5, 7, 8, 9, 8, 9, 3, 3, 4, 6, 8, 8, 7, 8, 5, 5, 6, 7, 8, 9, 8, 8, 7, 6, 7, 9, 8, 10, 8, 9, 8, 8, 8, 9, 9, 10, 9, 10, 8, 8, 9, 10, 10, 11, 10, 11, 8, 7, 7, 8, 9, 10, 10, 10, 8, 7, 8, 9, 10, 10, 10, 10}; +static const unsigned char t12l[] = {4, 3, 5, 7, 8, 9, 9, 9, 3, 3, 4, 5, 7, 7, 8, 8, 5, 4, 5, 6, 7, 8, 7, 8, 6, 5, 6, 6, 7, 8, 8, 8, 7, 6, 7, 7, 8, 8, 8, 9, 8, 7, 8, 8, 8, 9, 8, 9, 8, 7, 7, 8, 8, 9, 9, 10, 9, 8, 8, 9, 9, 9, 9, 10}; +static const unsigned char t13l[] = {1, 4, 6, 7, 8, 9, 9, 10, 9, 10, 11, 11, 12, 12, 13, 13, 3, 4, 6, 7, 8, 8, 9, 9, 9, 9, 10, 10, 11, 12, 12, 12, 6, 6, 7, 8, 9, 9, 10, 10, 9, 10, 10, 11, 11, 12, 13, 13, 7, 7, 8, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 13, 13, +8, 7, 9, 9, 10, 10, 11, 11, 10, 11, 11, 12, 12, 13, 13, 14, 9, 8, 9, 10, 10, 10, 11, 11, 11, 11, 12, 11, 13, 13, 14, 14, 9, 9, 10, 10, 11, 11, 11, 11, 11, 12, 12, 12, 13, 13, 14, 14, 10, 9, 10, 11, 11, 11, 12, 12, 12, 12, 13, 13, 13, 14, 16, 16, 9, 8, 9, 10, +10, 11, 11, 12, 12, 12, 12, 13, 13, 14, 15, 15, 10, 9, 10, 10, 11, 11, 11, 13, 12, 13, 13, 14, 14, 14, 16, 15, 10, 10, 10, 11, 11, 12, 12, 13, 12, 13, 14, 13, 14, 15, 16, 17, 11, 10, 10, 11, 12, 12, 12, 12, 13, 13, 13, 14, 15, 15, 15, 16, 11, 11, 11, 12, 12, +13, 12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 12, 11, 12, 13, 13, 13, 14, 14, 14, 14, 14, 15, 16, 15, 16, 16, 13, 12, 12, 13, 13, 13, 15, 14, 14, 17, 15, 15, 15, 17, 16, 16, 12, 12, 13, 14, 14, 14, 15, 14, 15, 15, 16, 16, 19, 18, 19, 16}; +static const unsigned char t15l[] = {3, 4, 5, 7, 7, 8, 9, 9, 9, 10, 10, 11, 11, 11, 12, 13, 4, 3, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 10, 11, 11, 5, 5, 5, 6, 7, 7, 8, 8, 8, 9, 9, 10, 10, 11, 11, 11, 6, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 7, 6, 7, + 7, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 11, 8, 7, 7, 8, 8, 8, 9, 9, 9, 9, 10, 10, 11, 11, 11, 12, 9, 7, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 12, 12, 9, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 12, 9, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, + 12, 12, 12, 9, 8, 9, 9, 9, 9, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 10, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 11, 12, 13, 12, 10, 9, 9, 9, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 13, 11, 10, 9, 10, 10, 10, 11, 11, 11, 11, 11, 11, 12, 12, 13, 13, +11, 10, 10, 10, 10, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 12, 11, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 12, 13, 12, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13, 13, 13}; +static const unsigned char t16l[] = {1, 4, 6, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 9, 3, 4, 6, 7, 8, 9, 9, 9, 10, 10, 10, 11, 12, 11, 12, 8, 6, 6, 7, 8, 9, 9, 10, 10, 11, 10, 11, 11, 11, 12, 12, 9, 8, 7, 8, 9, 9, 10, 10, 10, 11, 11, 12, 12, 12, 13, 13, + 10, 9, 8, 9, 9, 10, 10, 11, 11, 11, 12, 12, 12, 13, 13, 13, 9, 9, 8, 9, 9, 10, 11, 11, 12, 11, 12, 12, 13, 13, 13, 14, 10, 10, 9, 9, 10, 11, 11, 11, 11, 12, 12, 12, 12, 13, 13, 14, 10, 10, 9, 10, 10, 11, 11, 11, 12, 12, 13, 13, 13, 13, 15, 15, 10, 10, 10, + 10, 11, 11, 11, 12, 12, 13, 13, 13, 13, 14, 14, 14, 10, 11, 10, 10, 11, 11, 12, 12, 13, 13, 13, 13, 14, 13, 14, 13, 11, 11, 11, 10, 11, 12, 12, 12, 12, 13, 14, 14, 14, 15, 15, 14, 10, 12, 11, 11, 11, 12, 12, 13, 14, 14, 14, 14, 14, 14, 13, 14, 11, 12, 12, + 12, 12, 12, 13, 13, 13, 13, 15, 14, 14, 14, 14, 16, 11, 14, 12, 12, 12, 13, 13, 14, 14, 14, 16, 15, 15, 15, 17, 15, 11, 13, 13, 11, 12, 14, 14, 13, 14, 14, 15, 16, 15, 17, 15, 14, 11, 9, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 8}; +static const unsigned char t24l[] = {4, 4, 6, 7, 8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 12, 9, 4, 4, 5, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 10, 8, 6, 5, 6, 7, 7, 8, 8, 9, 9, 9, 9, 10, 10, 10, 11, 7, 7, 6, 7, 7, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 7, 8, 7, 7, 8, + 8, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 7, 9, 7, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 7, 9, 8, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 7, 10, 8, 8, 8, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 8, 10, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11, +8, 10, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 11, 11, 11, 8, 11, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 8, 11, 10, 9, 9, 9, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 8, 11, 10, 10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 8, 11, 10, 10, + 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 8, 12, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 8, 8, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 8, 8, 8, 8, 4}; +static const unsigned char t32l[] = {1, 4, 4, 5, 4, 6, 5, 6, 4, 5, 5, 6, 5, 6, 6, 6}; +static const unsigned char t33l[] = {4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4}; + +#define NOREF -1 +const struct huffcodetab shine_huffman_table[HTN] = +{ +{ 0, 0, 0, 0,NULL,NULL}, +{ 2, 2, 0, 0,t1HB, t1l}, +{ 3, 3, 0, 0,t2HB, t2l}, +{ 3, 3, 0, 0,t3HB, t3l}, +{ 0, 0, 0, 0,NULL,NULL},/* Apparently not used*/ +{ 4, 4, 0, 0,t5HB, t5l}, +{ 4, 4, 0, 0,t6HB, t6l}, +{ 6, 6, 0, 0,t7HB, t7l}, +{ 6, 6, 0, 0,t8HB, t8l}, +{ 6, 6, 0, 0,t9HB, t9l}, +{ 8, 8, 0, 0,t10HB, t10l}, +{ 8, 8, 0, 0,t11HB, t11l}, +{ 8, 8, 0, 0,t12HB, t12l}, +{16,16, 0, 0,t13HB, t13l}, +{ 0, 0, 0, 0,NULL,NULL},/* Apparently not used*/ +{16,16, 0, 0,t15HB, t15l}, +{16,16, 1, 1,t16HB, t16l}, +{16,16, 2, 3,t16HB, t16l}, +{16,16, 3, 7,t16HB, t16l}, +{16,16, 4, 15,t16HB, t16l}, +{16,16, 6, 63,t16HB, t16l}, +{16,16, 8, 255,t16HB, t16l}, +{16,16,10,1023,t16HB, t16l}, +{16,16,13,8191,t16HB, t16l}, +{16,16, 4, 15,t24HB, t24l}, +{16,16, 5, 31,t24HB, t24l}, +{16,16, 6, 63,t24HB, t24l}, +{16,16, 7, 127,t24HB, t24l}, +{16,16, 8, 255,t24HB, t24l}, +{16,16, 9, 511,t24HB, t24l}, +{16,16,11,2047,t24HB, t24l}, +{16,16,13,8191,t24HB, t24l}, +{ 1,16, 0, 0,t32HB, t32l}, +{ 1,16, 0, 0,t33HB, t33l}, +}; + + diff --git a/lib/lib_audio/mp3_shine_esp32/src/huffman.h b/lib/lib_audio/mp3_shine_esp32/src/huffman.h index d2d5b517a..a728d913a 100755 --- a/lib/lib_audio/mp3_shine_esp32/src/huffman.h +++ b/lib/lib_audio/mp3_shine_esp32/src/huffman.h @@ -1,19 +1,19 @@ -#define HUFFBITS uint16_t -#define HTN 34 -#define MXOFF 250 - -struct huffcodetab { - unsigned int xlen; /*max. x-index+ */ - unsigned int ylen; /*max. y-index+ */ - unsigned int linbits; /*number of linbits */ - unsigned int linmax; /*max number to be stored in linbits */ - const HUFFBITS *table; /*pointer to array[xlen][ylen] */ - const unsigned char *hlen; /*pointer to array[xlen][ylen] */ -}; - -extern const struct huffcodetab shine_huffman_table[HTN];/* global memory block */ - /* array of all huffcodtable headers */ - /* 0..31 Huffman code table 0..31 */ - /* 32,33 count1-tables */ - - +#define HUFFBITS uint16_t +#define HTN 34 +#define MXOFF 250 + +struct huffcodetab { + unsigned int xlen; /*max. x-index+ */ + unsigned int ylen; /*max. y-index+ */ + unsigned int linbits; /*number of linbits */ + unsigned int linmax; /*max number to be stored in linbits */ + const HUFFBITS *table; /*pointer to array[xlen][ylen] */ + const unsigned char *hlen; /*pointer to array[xlen][ylen] */ +}; + +extern const struct huffcodetab shine_huffman_table[HTN];/* global memory block */ + /* array of all huffcodtable headers */ + /* 0..31 Huffman code table 0..31 */ + /* 32,33 count1-tables */ + + diff --git a/lib/lib_audio/mp3_shine_esp32/src/l3bitstream.h b/lib/lib_audio/mp3_shine_esp32/src/l3bitstream.h index 6e165f54a..661fad7dc 100755 --- a/lib/lib_audio/mp3_shine_esp32/src/l3bitstream.h +++ b/lib/lib_audio/mp3_shine_esp32/src/l3bitstream.h @@ -1,6 +1,6 @@ -#ifndef shine_BITSTREAM_H -#define shine_BITSTREAM_H - -void shine_format_bitstream(shine_global_config *config); - -#endif +#ifndef shine_BITSTREAM_H +#define shine_BITSTREAM_H + +void shine_format_bitstream(shine_global_config *config); + +#endif diff --git a/lib/lib_audio/mp3_shine_esp32/src/l3loop.h b/lib/lib_audio/mp3_shine_esp32/src/l3loop.h index 0e71a9100..44f7cd279 100755 --- a/lib/lib_audio/mp3_shine_esp32/src/l3loop.h +++ b/lib/lib_audio/mp3_shine_esp32/src/l3loop.h @@ -1,9 +1,9 @@ -#ifndef L3LOOP_H -#define L3LOOP_H - -void shine_loop_initialise(shine_global_config *config); - -void shine_iteration_loop(shine_global_config *config); - -#endif - +#ifndef L3LOOP_H +#define L3LOOP_H + +void shine_loop_initialise(shine_global_config *config); + +void shine_iteration_loop(shine_global_config *config); + +#endif + diff --git a/lib/lib_audio/mp3_shine_esp32/src/l3mdct.h b/lib/lib_audio/mp3_shine_esp32/src/l3mdct.h index b374fd421..87925ff46 100755 --- a/lib/lib_audio/mp3_shine_esp32/src/l3mdct.h +++ b/lib/lib_audio/mp3_shine_esp32/src/l3mdct.h @@ -1,7 +1,7 @@ -#ifndef shine_MDCT_H -#define shine_MDCT_H - -void shine_mdct_initialise(shine_global_config *config); -void shine_mdct_sub(shine_global_config *config, int stride); - -#endif +#ifndef shine_MDCT_H +#define shine_MDCT_H + +void shine_mdct_initialise(shine_global_config *config); +void shine_mdct_sub(shine_global_config *config, int stride); + +#endif diff --git a/lib/lib_audio/mp3_shine_esp32/src/l3subband.h b/lib/lib_audio/mp3_shine_esp32/src/l3subband.h index 631ac42a2..3050b897a 100755 --- a/lib/lib_audio/mp3_shine_esp32/src/l3subband.h +++ b/lib/lib_audio/mp3_shine_esp32/src/l3subband.h @@ -1,9 +1,9 @@ -#ifndef L3SUBBAND_H -#define L3SUBBAND_H - -#include - -void shine_subband_initialise( shine_global_config *config ); -void shine_window_filter_subband(int16_t **buffer, int s[SBLIMIT], int k, shine_global_config *config, int stride); - -#endif +#ifndef L3SUBBAND_H +#define L3SUBBAND_H + +#include + +void shine_subband_initialise( shine_global_config *config ); +void shine_window_filter_subband(int16_t **buffer, int s[SBLIMIT], int k, shine_global_config *config, int stride); + +#endif diff --git a/lib/lib_audio/mp3_shine_esp32/src/reservoir.cpp b/lib/lib_audio/mp3_shine_esp32/src/reservoir.cpp index fa2a45c09..12814de0c 100755 --- a/lib/lib_audio/mp3_shine_esp32/src/reservoir.cpp +++ b/lib/lib_audio/mp3_shine_esp32/src/reservoir.cpp @@ -1,132 +1,132 @@ -/* reservoir.c - * Layer3 bit reservoir: Described in C.1.5.4.2.2 of the IS - */ - -#include "types.h" -#include "layer3.h" -#include "l3loop.h" -#include "huffman.h" -#include "bitstream.h" -#include "l3bitstream.h" -#include "reservoir.h" - -/* - * shine_max_reservoir_bits: - * ------------ - * Called at the beginning of each granule to get the max bit - * allowance for the current granule based on reservoir size - * and perceptual entropy. - */ -int shine_max_reservoir_bits (double *pe, shine_global_config *config ) { - int more_bits, max_bits, add_bits, over_bits; - int mean_bits = config->mean_bits; - - mean_bits /= config->wave.channels; - max_bits = mean_bits; - - if(max_bits>4095) - max_bits = 4095; - if(!config->ResvMax) - return max_bits; - - more_bits = *pe * 3.1 - mean_bits; - add_bits = 0; - if(more_bits>100) - { - int frac = (config->ResvSize * 6) / 10; - - if(fracResvSize - ((config->ResvMax <<3) / 10) - add_bits; - if (over_bits>0) - add_bits += over_bits; - - max_bits += add_bits; - if(max_bits>4095) - max_bits = 4095; - return max_bits; -} - -/* - * shine_ResvAdjust: - * ----------- - * Called after a granule's bit allocation. Readjusts the size of - * the reservoir to reflect the granule's usage. - */ -void shine_ResvAdjust(gr_info *gi, shine_global_config *config ) { - config->ResvSize += (config->mean_bits / config->wave.channels) - gi->part2_3_length; -} - -/* - * shine_ResvFrameEnd: - * ------------- - * Called after all granules in a frame have been allocated. Makes sure - * that the reservoir size is within limits, possibly by adding stuffing - * bits. Note that stuffing bits are added by increasing a granule's - * part2_3_length. The bitstream formatter will detect this and write the - * appropriate stuffing bits to the bitstream. - */ -void shine_ResvFrameEnd(shine_global_config *config ) { - gr_info *gi; - int gr, ch, ancillary_pad, stuffingBits; - int over_bits; - shine_side_info_t *l3_side = &config->side_info; - - ancillary_pad = 0; - - /* just in case mean_bits is odd, this is necessary... */ - if((config->wave.channels==2) && (config->mean_bits & 1)) - config->ResvSize += 1; - - over_bits = config->ResvSize - config->ResvMax; - if(over_bits<0) - over_bits = 0; - - config->ResvSize -= over_bits; - stuffingBits = over_bits + ancillary_pad; - - /* we must be byte aligned */ - if((over_bits = config->ResvSize % 8)) - { - stuffingBits += over_bits; - config->ResvSize -= over_bits; - } - - if(stuffingBits) - { - /* - * plan a: put all into the first granule - * This was preferred by someone designing a - * real-time decoder... - */ - gi = (gr_info *) &(l3_side->gr[0].ch[0]); - - if ( gi->part2_3_length + stuffingBits < 4095 ) - gi->part2_3_length += stuffingBits; - else - { - /* plan b: distribute throughout the granules */ - for (gr = 0; gr < config->mpeg.granules_per_frame; gr++ ) - for (ch = 0; ch < config->wave.channels; ch++ ) - { - int extraBits, bitsThisGr; - gr_info *gi = (gr_info *) &(l3_side->gr[gr].ch[ch]); - if (!stuffingBits) - break; - extraBits = 4095 - gi->part2_3_length; - bitsThisGr = extraBits < stuffingBits ? extraBits : stuffingBits; - gi->part2_3_length += bitsThisGr; - stuffingBits -= bitsThisGr; - } - /* - * If any stuffing bits remain, we elect to spill them - * into ancillary data. The bitstream formatter will do this if - * l3side->resvDrain is set - */ - l3_side->resvDrain = stuffingBits; - } - } -} +/* reservoir.c + * Layer3 bit reservoir: Described in C.1.5.4.2.2 of the IS + */ + +#include "types.h" +#include "layer3.h" +#include "l3loop.h" +#include "huffman.h" +#include "bitstream.h" +#include "l3bitstream.h" +#include "reservoir.h" + +/* + * shine_max_reservoir_bits: + * ------------ + * Called at the beginning of each granule to get the max bit + * allowance for the current granule based on reservoir size + * and perceptual entropy. + */ +int shine_max_reservoir_bits (double *pe, shine_global_config *config ) { + int more_bits, max_bits, add_bits, over_bits; + int mean_bits = config->mean_bits; + + mean_bits /= config->wave.channels; + max_bits = mean_bits; + + if(max_bits>4095) + max_bits = 4095; + if(!config->ResvMax) + return max_bits; + + more_bits = *pe * 3.1 - mean_bits; + add_bits = 0; + if(more_bits>100) + { + int frac = (config->ResvSize * 6) / 10; + + if(fracResvSize - ((config->ResvMax <<3) / 10) - add_bits; + if (over_bits>0) + add_bits += over_bits; + + max_bits += add_bits; + if(max_bits>4095) + max_bits = 4095; + return max_bits; +} + +/* + * shine_ResvAdjust: + * ----------- + * Called after a granule's bit allocation. Readjusts the size of + * the reservoir to reflect the granule's usage. + */ +void shine_ResvAdjust(gr_info *gi, shine_global_config *config ) { + config->ResvSize += (config->mean_bits / config->wave.channels) - gi->part2_3_length; +} + +/* + * shine_ResvFrameEnd: + * ------------- + * Called after all granules in a frame have been allocated. Makes sure + * that the reservoir size is within limits, possibly by adding stuffing + * bits. Note that stuffing bits are added by increasing a granule's + * part2_3_length. The bitstream formatter will detect this and write the + * appropriate stuffing bits to the bitstream. + */ +void shine_ResvFrameEnd(shine_global_config *config ) { + gr_info *gi; + int gr, ch, ancillary_pad, stuffingBits; + int over_bits; + shine_side_info_t *l3_side = &config->side_info; + + ancillary_pad = 0; + + /* just in case mean_bits is odd, this is necessary... */ + if((config->wave.channels==2) && (config->mean_bits & 1)) + config->ResvSize += 1; + + over_bits = config->ResvSize - config->ResvMax; + if(over_bits<0) + over_bits = 0; + + config->ResvSize -= over_bits; + stuffingBits = over_bits + ancillary_pad; + + /* we must be byte aligned */ + if((over_bits = config->ResvSize % 8)) + { + stuffingBits += over_bits; + config->ResvSize -= over_bits; + } + + if(stuffingBits) + { + /* + * plan a: put all into the first granule + * This was preferred by someone designing a + * real-time decoder... + */ + gi = (gr_info *) &(l3_side->gr[0].ch[0]); + + if ( gi->part2_3_length + stuffingBits < 4095 ) + gi->part2_3_length += stuffingBits; + else + { + /* plan b: distribute throughout the granules */ + for (gr = 0; gr < config->mpeg.granules_per_frame; gr++ ) + for (ch = 0; ch < config->wave.channels; ch++ ) + { + int extraBits, bitsThisGr; + gr_info *gi = (gr_info *) &(l3_side->gr[gr].ch[ch]); + if (!stuffingBits) + break; + extraBits = 4095 - gi->part2_3_length; + bitsThisGr = extraBits < stuffingBits ? extraBits : stuffingBits; + gi->part2_3_length += bitsThisGr; + stuffingBits -= bitsThisGr; + } + /* + * If any stuffing bits remain, we elect to spill them + * into ancillary data. The bitstream formatter will do this if + * l3side->resvDrain is set + */ + l3_side->resvDrain = stuffingBits; + } + } +} diff --git a/lib/lib_audio/mp3_shine_esp32/src/reservoir.h b/lib/lib_audio/mp3_shine_esp32/src/reservoir.h index 2f1ffa5e2..6be5005b1 100755 --- a/lib/lib_audio/mp3_shine_esp32/src/reservoir.h +++ b/lib/lib_audio/mp3_shine_esp32/src/reservoir.h @@ -1,9 +1,9 @@ -#ifndef RESERVOIR_H -#define RESERVOIR_H - -void shine_ResvFrameBegin(int frameLength, shine_global_config *config); -int shine_max_reservoir_bits (double *pe, shine_global_config *config); -void shine_ResvAdjust (gr_info *gi, shine_global_config *config ); -void shine_ResvFrameEnd (shine_global_config *config ); - -#endif +#ifndef RESERVOIR_H +#define RESERVOIR_H + +void shine_ResvFrameBegin(int frameLength, shine_global_config *config); +int shine_max_reservoir_bits (double *pe, shine_global_config *config); +void shine_ResvAdjust (gr_info *gi, shine_global_config *config ); +void shine_ResvFrameEnd (shine_global_config *config ); + +#endif diff --git a/lib/lib_audio/mp3_shine_esp32/src/tables.cpp b/lib/lib_audio/mp3_shine_esp32/src/tables.cpp index 40cdd9d99..ffd5c01a7 100755 --- a/lib/lib_audio/mp3_shine_esp32/src/tables.cpp +++ b/lib/lib_audio/mp3_shine_esp32/src/tables.cpp @@ -1,126 +1,126 @@ -/* tables.c - * - * Here are MPEG1 Table B.8 and MPEG2 Table B.1 -- Layer III scalefactor bands. - * Index into this using a method such as: - * idx = fr_ps->header->sampling_frequency + (fr_ps->header->version * 3) - */ - -#include "tables.h" - -const int shine_slen1_tab[16] = { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }; -const int shine_slen2_tab[16] = { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 }; - -/* Valid samplerates and bitrates. */ -const int samplerates[9] = { - 44100, 48000, 32000, /* MPEG-I */ - 22050, 24000, 16000, /* MPEG-II */ - 11025, 12000, 8000 /* MPEG-2.5 */ -}; - -const int bitrates[16][4] = { - /* MPEG version: - * 2.5, reserved, II, I */ - { -1, -1, -1, -1}, - { 8, -1, 8, 32}, - { 16, -1, 16, 40}, - { 24, -1, 24, 48}, - { 32, -1, 32, 56}, - { 40, -1, 40, 64}, - { 48, -1, 48, 80}, - { 56, -1, 56, 96}, - { 64, -1, 64, 112}, - { -1, -1, 80, 128}, - { -1, -1, 96, 160}, - { -1, -1, 112, 192}, - { -1, -1, 128, 224}, - { -1, -1, 144, 256}, - { -1, -1, 160, 320}, - { -1, -1, -1, -1} -}; - -const int shine_scale_fact_band_index[9][23] = -{ - /* MPEG-I */ - /* Table B.8.b: 44.1 kHz */ - {0,4,8,12,16,20,24,30,36,44,52,62,74,90,110,134,162,196,238,288,342,418,576}, - /* Table B.8.c: 48 kHz */ - {0,4,8,12,16,20,24,30,36,42,50,60,72,88,106,128,156,190,230,276,330,384,576}, - /* Table B.8.a: 32 kHz */ - {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576}, - /* MPEG-II */ - /* Table B.2.b: 22.05 kHz */ - {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, - /* Table B.2.c: 24 kHz */ - {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576}, - /* Table B.2.a: 16 kHz */ - {0,6,12,18,24,30,36,44,45,66,80,96,116,140,168,200,238,248,336,396,464,522,576}, - - /* MPEG-2.5 */ - /* 11.025 kHz */ - {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, - /* 12 kHz */ - {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, - /* MPEG-2.5 8 kHz */ - {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576}, -}; - -/* note. 0.035781 is shine_enwindow maximum value */ -/* scale and convert to fixed point before storing */ -#define SHINE_EW(x) (int)((double)(x) * 0x7fffffff) -#define SHINE_EW2(a,b) SHINE_EW(a), SHINE_EW(b) -#define SHINE_EW10(a,b,c,d,e,f,g,h,i,j) SHINE_EW2(a,b), SHINE_EW2(c,d), SHINE_EW2(e,f), SHINE_EW2(g,h), SHINE_EW2(i,j) - -const int shine_enwindow[] = { -SHINE_EW10( 0.000000, -0.000000, -0.000000, -0.000000, -0.000000, -0.000000, -0.000000, -0.000001, -0.000001, -0.000001), -SHINE_EW10( -0.000001, -0.000001, -0.000001, -0.000002, -0.000002, -0.000002, -0.000002, -0.000003, -0.000003, -0.000003), -SHINE_EW10( -0.000004, -0.000004, -0.000005, -0.000005, -0.000006, -0.000007, -0.000008, -0.000008, -0.000009, -0.000010), -SHINE_EW10( -0.000011, -0.000012, -0.000014, -0.000015, -0.000017, -0.000018, -0.000020, -0.000021, -0.000023, -0.000025), -SHINE_EW10( -0.000028, -0.000030, -0.000032, -0.000035, -0.000038, -0.000041, -0.000043, -0.000046, -0.000050, -0.000053), -SHINE_EW10( -0.000056, -0.000060, -0.000063, -0.000066, -0.000070, -0.000073, -0.000077, -0.000081, -0.000084, -0.000087), -SHINE_EW10( -0.000091, -0.000093, -0.000096, -0.000099, 0.000102, 0.000104, 0.000106, 0.000107, 0.000108, 0.000109), -SHINE_EW10( 0.000109, 0.000108, 0.000107, 0.000105, 0.000103, 0.000099, 0.000095, 0.000090, 0.000084, 0.000078), -SHINE_EW10( 0.000070, 0.000061, 0.000051, 0.000040, 0.000027, 0.000014, -0.000001, -0.000017, -0.000034, -0.000053), -SHINE_EW10( -0.000073, -0.000094, -0.000116, -0.000140, -0.000165, -0.000191, -0.000219, -0.000247, -0.000277, -0.000308), -SHINE_EW10( -0.000339, -0.000371, -0.000404, -0.000438, -0.000473, -0.000507, -0.000542, -0.000577, -0.000612, -0.000647), -SHINE_EW10( -0.000681, -0.000714, -0.000747, -0.000779, -0.000810, -0.000839, -0.000866, -0.000892, -0.000915, -0.000936), -SHINE_EW10( -0.000954, -0.000969, -0.000981, -0.000989, -0.000994, -0.000995, -0.000992, -0.000984, 0.000971, 0.000954), -SHINE_EW10( 0.000931, 0.000903, 0.000869, 0.000829, 0.000784, 0.000732, 0.000674, 0.000610, 0.000539, 0.000463), -SHINE_EW10( 0.000379, 0.000288, 0.000192, 0.000088, -0.000021, -0.000137, -0.000260, -0.000388, -0.000522, -0.000662), -SHINE_EW10( -0.000807, -0.000957, -0.001111, -0.001270, -0.001432, -0.001598, -0.001767, -0.001937, -0.002110, -0.002283), -SHINE_EW10( -0.002457, -0.002631, -0.002803, -0.002974, -0.003142, -0.003307, -0.003467, -0.003623, -0.003772, -0.003914), -SHINE_EW10( -0.004049, -0.004175, -0.004291, -0.004396, -0.004490, -0.004570, -0.004638, -0.004691, -0.004728, -0.004749), -SHINE_EW10( -0.004752, -0.004737, -0.004703, -0.004649, -0.004574, -0.004477, -0.004358, -0.004215, -0.004049, -0.003859), -SHINE_EW10( -0.003643, -0.003402, 0.003135, 0.002841, 0.002522, 0.002175, 0.001801, 0.001400, 0.000971, 0.000516), -SHINE_EW10( 0.000033, -0.000476, -0.001012, -0.001574, -0.002162, -0.002774, -0.003411, -0.004072, -0.004756, -0.005462), -SHINE_EW10( -0.006189, -0.006937, -0.007703, -0.008487, -0.009288, -0.010104, -0.010933, -0.011775, -0.012628, -0.013489), -SHINE_EW10( -0.014359, -0.015234, -0.016113, -0.016994, -0.017876, -0.018757, -0.019634, -0.020507, -0.021372, -0.022229), -SHINE_EW10( -0.023074, -0.023907, -0.024725, -0.025527, -0.026311, -0.027074, -0.027815, -0.028533, -0.029225, -0.029890), -SHINE_EW10( -0.030527, -0.031133, -0.031707, -0.032248, -0.032755, -0.033226, -0.033660, -0.034056, -0.034413, -0.034730), -SHINE_EW10( -0.035007, -0.035242, -0.035435, -0.035586, -0.035694, -0.035759, 0.035781, 0.035759, 0.035694, 0.035586), -SHINE_EW10( 0.035435, 0.035242, 0.035007, 0.034730, 0.034413, 0.034056, 0.033660, 0.033226, 0.032755, 0.032248), -SHINE_EW10( 0.031707, 0.031133, 0.030527, 0.029890, 0.029225, 0.028533, 0.027815, 0.027074, 0.026311, 0.025527), -SHINE_EW10( 0.024725, 0.023907, 0.023074, 0.022229, 0.021372, 0.020507, 0.019634, 0.018757, 0.017876, 0.016994), -SHINE_EW10( 0.016113, 0.015234, 0.014359, 0.013489, 0.012628, 0.011775, 0.010933, 0.010104, 0.009288, 0.008487), -SHINE_EW10( 0.007703, 0.006937, 0.006189, 0.005462, 0.004756, 0.004072, 0.003411, 0.002774, 0.002162, 0.001574), -SHINE_EW10( 0.001012, 0.000476, -0.000033, -0.000516, -0.000971, -0.001400, -0.001801, -0.002175, -0.002522, -0.002841), -SHINE_EW10( 0.003135, 0.003402, 0.003643, 0.003859, 0.004049, 0.004215, 0.004358, 0.004477, 0.004574, 0.004649), -SHINE_EW10( 0.004703, 0.004737, 0.004752, 0.004749, 0.004728, 0.004691, 0.004638, 0.004570, 0.004490, 0.004396), -SHINE_EW10( 0.004291, 0.004175, 0.004049, 0.003914, 0.003772, 0.003623, 0.003467, 0.003307, 0.003142, 0.002974), -SHINE_EW10( 0.002803, 0.002631, 0.002457, 0.002283, 0.002110, 0.001937, 0.001767, 0.001598, 0.001432, 0.001270), -SHINE_EW10( 0.001111, 0.000957, 0.000807, 0.000662, 0.000522, 0.000388, 0.000260, 0.000137, 0.000021, -0.000088), -SHINE_EW10( -0.000192, -0.000288, -0.000379, -0.000463, -0.000539, -0.000610, -0.000674, -0.000732, -0.000784, -0.000829), -SHINE_EW10( -0.000869, -0.000903, -0.000931, -0.000954, 0.000971, 0.000984, 0.000992, 0.000995, 0.000994, 0.000989), -SHINE_EW10( 0.000981, 0.000969, 0.000954, 0.000936, 0.000915, 0.000892, 0.000866, 0.000839, 0.000810, 0.000779), -SHINE_EW10( 0.000747, 0.000714, 0.000681, 0.000647, 0.000612, 0.000577, 0.000542, 0.000507, 0.000473, 0.000438), -SHINE_EW10( 0.000404, 0.000371, 0.000339, 0.000308, 0.000277, 0.000247, 0.000219, 0.000191, 0.000165, 0.000140), -SHINE_EW10( 0.000116, 0.000094, 0.000073, 0.000053, 0.000034, 0.000017, 0.000001, -0.000014, -0.000027, -0.000040), -SHINE_EW10( -0.000051, -0.000061, -0.000070, -0.000078, -0.000084, -0.000090, -0.000095, -0.000099, -0.000103, -0.000105), -SHINE_EW10( -0.000107, -0.000108, -0.000109, -0.000109, -0.000108, -0.000107, -0.000106, -0.000104, 0.000102, 0.000099), -SHINE_EW10( 0.000096, 0.000093, 0.000091, 0.000087, 0.000084, 0.000081, 0.000077, 0.000073, 0.000070, 0.000066), -SHINE_EW10( 0.000063, 0.000060, 0.000056, 0.000053, 0.000050, 0.000046, 0.000043, 0.000041, 0.000038, 0.000035), -SHINE_EW10( 0.000032, 0.000030, 0.000028, 0.000025, 0.000023, 0.000021, 0.000020, 0.000018, 0.000017, 0.000015), -SHINE_EW10( 0.000014, 0.000012, 0.000011, 0.000010, 0.000009, 0.000008, 0.000008, 0.000007, 0.000006, 0.000005), -SHINE_EW10( 0.000005, 0.000004, 0.000004, 0.000003, 0.000003, 0.000003, 0.000002, 0.000002, 0.000002, 0.000002), -SHINE_EW10( 0.000001, 0.000001, 0.000001, 0.000001, 0.000001, 0.000001, 0.000000, 0.000000, 0.000000, 0.000000), -SHINE_EW2 ( 0.000000, 0.000000) -}; +/* tables.c + * + * Here are MPEG1 Table B.8 and MPEG2 Table B.1 -- Layer III scalefactor bands. + * Index into this using a method such as: + * idx = fr_ps->header->sampling_frequency + (fr_ps->header->version * 3) + */ + +#include "tables.h" + +const int shine_slen1_tab[16] = { 0, 0, 0, 0, 3, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4 }; +const int shine_slen2_tab[16] = { 0, 1, 2, 3, 0, 1, 2, 3, 1, 2, 3, 1, 2, 3, 2, 3 }; + +/* Valid samplerates and bitrates. */ +const int samplerates[9] = { + 44100, 48000, 32000, /* MPEG-I */ + 22050, 24000, 16000, /* MPEG-II */ + 11025, 12000, 8000 /* MPEG-2.5 */ +}; + +const int bitrates[16][4] = { + /* MPEG version: + * 2.5, reserved, II, I */ + { -1, -1, -1, -1}, + { 8, -1, 8, 32}, + { 16, -1, 16, 40}, + { 24, -1, 24, 48}, + { 32, -1, 32, 56}, + { 40, -1, 40, 64}, + { 48, -1, 48, 80}, + { 56, -1, 56, 96}, + { 64, -1, 64, 112}, + { -1, -1, 80, 128}, + { -1, -1, 96, 160}, + { -1, -1, 112, 192}, + { -1, -1, 128, 224}, + { -1, -1, 144, 256}, + { -1, -1, 160, 320}, + { -1, -1, -1, -1} +}; + +const int shine_scale_fact_band_index[9][23] = +{ + /* MPEG-I */ + /* Table B.8.b: 44.1 kHz */ + {0,4,8,12,16,20,24,30,36,44,52,62,74,90,110,134,162,196,238,288,342,418,576}, + /* Table B.8.c: 48 kHz */ + {0,4,8,12,16,20,24,30,36,42,50,60,72,88,106,128,156,190,230,276,330,384,576}, + /* Table B.8.a: 32 kHz */ + {0,4,8,12,16,20,24,30,36,44,54,66,82,102,126,156,194,240,296,364,448,550,576}, + /* MPEG-II */ + /* Table B.2.b: 22.05 kHz */ + {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, + /* Table B.2.c: 24 kHz */ + {0,6,12,18,24,30,36,44,54,66,80,96,114,136,162,194,232,278,330,394,464,540,576}, + /* Table B.2.a: 16 kHz */ + {0,6,12,18,24,30,36,44,45,66,80,96,116,140,168,200,238,248,336,396,464,522,576}, + + /* MPEG-2.5 */ + /* 11.025 kHz */ + {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, + /* 12 kHz */ + {0,6,12,18,24,30,36,44,54,66,80,96,116,140,168,200,238,284,336,396,464,522,576}, + /* MPEG-2.5 8 kHz */ + {0,12,24,36,48,60,72,88,108,132,160,192,232,280,336,400,476,566,568,570,572,574,576}, +}; + +/* note. 0.035781 is shine_enwindow maximum value */ +/* scale and convert to fixed point before storing */ +#define SHINE_EW(x) (int)((double)(x) * 0x7fffffff) +#define SHINE_EW2(a,b) SHINE_EW(a), SHINE_EW(b) +#define SHINE_EW10(a,b,c,d,e,f,g,h,i,j) SHINE_EW2(a,b), SHINE_EW2(c,d), SHINE_EW2(e,f), SHINE_EW2(g,h), SHINE_EW2(i,j) + +const int shine_enwindow[] = { +SHINE_EW10( 0.000000, -0.000000, -0.000000, -0.000000, -0.000000, -0.000000, -0.000000, -0.000001, -0.000001, -0.000001), +SHINE_EW10( -0.000001, -0.000001, -0.000001, -0.000002, -0.000002, -0.000002, -0.000002, -0.000003, -0.000003, -0.000003), +SHINE_EW10( -0.000004, -0.000004, -0.000005, -0.000005, -0.000006, -0.000007, -0.000008, -0.000008, -0.000009, -0.000010), +SHINE_EW10( -0.000011, -0.000012, -0.000014, -0.000015, -0.000017, -0.000018, -0.000020, -0.000021, -0.000023, -0.000025), +SHINE_EW10( -0.000028, -0.000030, -0.000032, -0.000035, -0.000038, -0.000041, -0.000043, -0.000046, -0.000050, -0.000053), +SHINE_EW10( -0.000056, -0.000060, -0.000063, -0.000066, -0.000070, -0.000073, -0.000077, -0.000081, -0.000084, -0.000087), +SHINE_EW10( -0.000091, -0.000093, -0.000096, -0.000099, 0.000102, 0.000104, 0.000106, 0.000107, 0.000108, 0.000109), +SHINE_EW10( 0.000109, 0.000108, 0.000107, 0.000105, 0.000103, 0.000099, 0.000095, 0.000090, 0.000084, 0.000078), +SHINE_EW10( 0.000070, 0.000061, 0.000051, 0.000040, 0.000027, 0.000014, -0.000001, -0.000017, -0.000034, -0.000053), +SHINE_EW10( -0.000073, -0.000094, -0.000116, -0.000140, -0.000165, -0.000191, -0.000219, -0.000247, -0.000277, -0.000308), +SHINE_EW10( -0.000339, -0.000371, -0.000404, -0.000438, -0.000473, -0.000507, -0.000542, -0.000577, -0.000612, -0.000647), +SHINE_EW10( -0.000681, -0.000714, -0.000747, -0.000779, -0.000810, -0.000839, -0.000866, -0.000892, -0.000915, -0.000936), +SHINE_EW10( -0.000954, -0.000969, -0.000981, -0.000989, -0.000994, -0.000995, -0.000992, -0.000984, 0.000971, 0.000954), +SHINE_EW10( 0.000931, 0.000903, 0.000869, 0.000829, 0.000784, 0.000732, 0.000674, 0.000610, 0.000539, 0.000463), +SHINE_EW10( 0.000379, 0.000288, 0.000192, 0.000088, -0.000021, -0.000137, -0.000260, -0.000388, -0.000522, -0.000662), +SHINE_EW10( -0.000807, -0.000957, -0.001111, -0.001270, -0.001432, -0.001598, -0.001767, -0.001937, -0.002110, -0.002283), +SHINE_EW10( -0.002457, -0.002631, -0.002803, -0.002974, -0.003142, -0.003307, -0.003467, -0.003623, -0.003772, -0.003914), +SHINE_EW10( -0.004049, -0.004175, -0.004291, -0.004396, -0.004490, -0.004570, -0.004638, -0.004691, -0.004728, -0.004749), +SHINE_EW10( -0.004752, -0.004737, -0.004703, -0.004649, -0.004574, -0.004477, -0.004358, -0.004215, -0.004049, -0.003859), +SHINE_EW10( -0.003643, -0.003402, 0.003135, 0.002841, 0.002522, 0.002175, 0.001801, 0.001400, 0.000971, 0.000516), +SHINE_EW10( 0.000033, -0.000476, -0.001012, -0.001574, -0.002162, -0.002774, -0.003411, -0.004072, -0.004756, -0.005462), +SHINE_EW10( -0.006189, -0.006937, -0.007703, -0.008487, -0.009288, -0.010104, -0.010933, -0.011775, -0.012628, -0.013489), +SHINE_EW10( -0.014359, -0.015234, -0.016113, -0.016994, -0.017876, -0.018757, -0.019634, -0.020507, -0.021372, -0.022229), +SHINE_EW10( -0.023074, -0.023907, -0.024725, -0.025527, -0.026311, -0.027074, -0.027815, -0.028533, -0.029225, -0.029890), +SHINE_EW10( -0.030527, -0.031133, -0.031707, -0.032248, -0.032755, -0.033226, -0.033660, -0.034056, -0.034413, -0.034730), +SHINE_EW10( -0.035007, -0.035242, -0.035435, -0.035586, -0.035694, -0.035759, 0.035781, 0.035759, 0.035694, 0.035586), +SHINE_EW10( 0.035435, 0.035242, 0.035007, 0.034730, 0.034413, 0.034056, 0.033660, 0.033226, 0.032755, 0.032248), +SHINE_EW10( 0.031707, 0.031133, 0.030527, 0.029890, 0.029225, 0.028533, 0.027815, 0.027074, 0.026311, 0.025527), +SHINE_EW10( 0.024725, 0.023907, 0.023074, 0.022229, 0.021372, 0.020507, 0.019634, 0.018757, 0.017876, 0.016994), +SHINE_EW10( 0.016113, 0.015234, 0.014359, 0.013489, 0.012628, 0.011775, 0.010933, 0.010104, 0.009288, 0.008487), +SHINE_EW10( 0.007703, 0.006937, 0.006189, 0.005462, 0.004756, 0.004072, 0.003411, 0.002774, 0.002162, 0.001574), +SHINE_EW10( 0.001012, 0.000476, -0.000033, -0.000516, -0.000971, -0.001400, -0.001801, -0.002175, -0.002522, -0.002841), +SHINE_EW10( 0.003135, 0.003402, 0.003643, 0.003859, 0.004049, 0.004215, 0.004358, 0.004477, 0.004574, 0.004649), +SHINE_EW10( 0.004703, 0.004737, 0.004752, 0.004749, 0.004728, 0.004691, 0.004638, 0.004570, 0.004490, 0.004396), +SHINE_EW10( 0.004291, 0.004175, 0.004049, 0.003914, 0.003772, 0.003623, 0.003467, 0.003307, 0.003142, 0.002974), +SHINE_EW10( 0.002803, 0.002631, 0.002457, 0.002283, 0.002110, 0.001937, 0.001767, 0.001598, 0.001432, 0.001270), +SHINE_EW10( 0.001111, 0.000957, 0.000807, 0.000662, 0.000522, 0.000388, 0.000260, 0.000137, 0.000021, -0.000088), +SHINE_EW10( -0.000192, -0.000288, -0.000379, -0.000463, -0.000539, -0.000610, -0.000674, -0.000732, -0.000784, -0.000829), +SHINE_EW10( -0.000869, -0.000903, -0.000931, -0.000954, 0.000971, 0.000984, 0.000992, 0.000995, 0.000994, 0.000989), +SHINE_EW10( 0.000981, 0.000969, 0.000954, 0.000936, 0.000915, 0.000892, 0.000866, 0.000839, 0.000810, 0.000779), +SHINE_EW10( 0.000747, 0.000714, 0.000681, 0.000647, 0.000612, 0.000577, 0.000542, 0.000507, 0.000473, 0.000438), +SHINE_EW10( 0.000404, 0.000371, 0.000339, 0.000308, 0.000277, 0.000247, 0.000219, 0.000191, 0.000165, 0.000140), +SHINE_EW10( 0.000116, 0.000094, 0.000073, 0.000053, 0.000034, 0.000017, 0.000001, -0.000014, -0.000027, -0.000040), +SHINE_EW10( -0.000051, -0.000061, -0.000070, -0.000078, -0.000084, -0.000090, -0.000095, -0.000099, -0.000103, -0.000105), +SHINE_EW10( -0.000107, -0.000108, -0.000109, -0.000109, -0.000108, -0.000107, -0.000106, -0.000104, 0.000102, 0.000099), +SHINE_EW10( 0.000096, 0.000093, 0.000091, 0.000087, 0.000084, 0.000081, 0.000077, 0.000073, 0.000070, 0.000066), +SHINE_EW10( 0.000063, 0.000060, 0.000056, 0.000053, 0.000050, 0.000046, 0.000043, 0.000041, 0.000038, 0.000035), +SHINE_EW10( 0.000032, 0.000030, 0.000028, 0.000025, 0.000023, 0.000021, 0.000020, 0.000018, 0.000017, 0.000015), +SHINE_EW10( 0.000014, 0.000012, 0.000011, 0.000010, 0.000009, 0.000008, 0.000008, 0.000007, 0.000006, 0.000005), +SHINE_EW10( 0.000005, 0.000004, 0.000004, 0.000003, 0.000003, 0.000003, 0.000002, 0.000002, 0.000002, 0.000002), +SHINE_EW10( 0.000001, 0.000001, 0.000001, 0.000001, 0.000001, 0.000001, 0.000000, 0.000000, 0.000000, 0.000000), +SHINE_EW2 ( 0.000000, 0.000000) +}; diff --git a/lib/lib_audio/mp3_shine_esp32/src/tables.h b/lib/lib_audio/mp3_shine_esp32/src/tables.h index 1fbde4bd4..c33791c3f 100755 --- a/lib/lib_audio/mp3_shine_esp32/src/tables.h +++ b/lib/lib_audio/mp3_shine_esp32/src/tables.h @@ -1,16 +1,16 @@ -#ifndef TABLES_H -#define TABLES_H - -#include "types.h" - -extern const int shine_slen1_tab[16]; -extern const int shine_slen2_tab[16]; - -extern const int samplerates[9]; -extern const int bitrates[16][4]; - -extern const int shine_scale_fact_band_index[9][23]; -extern const int shine_enwindow[]; - -#endif - +#ifndef TABLES_H +#define TABLES_H + +#include "types.h" + +extern const int shine_slen1_tab[16]; +extern const int shine_slen2_tab[16]; + +extern const int samplerates[9]; +extern const int bitrates[16][4]; + +extern const int shine_scale_fact_band_index[9][23]; +extern const int shine_enwindow[]; + +#endif + diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/BlynkIrRemote/BlynkIrRemote.ino b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/BlynkIrRemote/BlynkIrRemote.ino index 1948f3c4c..686cba1fb 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/BlynkIrRemote/BlynkIrRemote.ino +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/BlynkIrRemote/BlynkIrRemote.ino @@ -1,198 +1,198 @@ -/************************************************************* - Emulate a physical remote via an iOS and Android App. - Copyright Gaurav Barwalia 2020 - - Download latest Blynk library here: - https://github.com/blynkkk/blynk-library/releases/latest - - Blynk is a platform with iOS and Android apps to control - Arduino, Raspberry Pi and the likes over the Internet. - You can easily build graphic interfaces for all your - projects by simply dragging and dropping widgets. - - Downloads, docs, tutorials: http://www.blynk.cc - Sketch generator: http://examples.blynk.cc - Blynk community: http://community.blynk.cc - Follow us: http://www.fb.com/blynkapp - http://twitter.com/blynk_app - - Blynk library is licensed under MIT license - This example code is in public domain. - - ************************************************************* - This example runs directly on ESP8266 chip. - - Note: This requires ESP8266 support package: - https://github.com/esp8266/Arduino - - Please be sure to select the right ESP8266 module - in the Tools -> Board menu! - - Change WiFi ssid, pass, and Blynk auth token to run :) - Feel free to apply it to any other example. It's simple! - *************************************************************/ - - /* - // After decoding received below codes - - // Power button - -18:12:33.993 -> Protocol : NEC -18:12:33.993 -> Code : 0x1FE50AF (32 Bits) -18:12:33.993 -> uint16_t rawData[71] = {9040, 4452, 606, 532, 606, 534, 630, 508, 604, 534, 604, 534, 604, 534, 630, 506, 606, 1646, 632, 1620, 606, 1646, 632, 1620, 630, 1620, 632, 1620, 630, 1620, 606, 1646, 632, 506, 632, 506, 632, 1620, 632, 506, 632, 1620, 632, 506, 632, 508, 632, 506, 632, 506, 632, 1620, 632, 506, 632, 1624, 628, 506, 632, 1620, 632, 1618, 632, 1620, 632, 1620, 632, 39016, 9040, 2216, 630}; // NEC 1FE50AF -18:12:34.027 -> uint32_t address = 0x80; -18:12:34.027 -> uint32_t command = 0xA; -18:12:34.027 -> uint64_t data = 0x1FE50AF; - -//mute button - -18:13:27.215 -> Protocol : NEC -18:13:27.215 -> Code : 0x1FE30CF (32 Bits) -18:13:27.215 -> uint16_t rawData[71] = {9094, 4398, 660, 478, 658, 480, 658, 480, 658, 480, 658, 480, 658, 480, 660, 480, 658, 1594, 658, 1594, 658, 1594, 658, 1594, 658, 1592, 658, 1594, 658, 1592, 658, 1594, 660, 480, 658, 480, 658, 480, 658, 1592, 658, 1592, 658, 480, 658, 480, 660, 478, 660, 478, 658, 1594, 658, 1592, 658, 480, 658, 480, 658, 1594, 658, 1592, 658, 1594, 658, 1594, 658, 38986, 9094, 2162, 658}; // NEC 1FE30CF -18:13:27.285 -> uint32_t address = 0x80; -18:13:27.285 -> uint32_t command = 0xC; -18:13:27.285 -> uint64_t data = 0x1FE30CF; - -//Vol. low - -18:14:44.427 -> Protocol : NEC -18:14:44.427 -> Code : 0x1FEC03F (32 Bits) -18:14:44.427 -> uint16_t rawData[71] = {9120, 4374, 658, 478, 658, 480, 658, 480, 658, 480, 658, 482, 658, 478, 658, 480, 658, 1594, 658, 1594, 658, 1592, 660, 1594, 658, 1592, 658, 1594, 658, 1594, 658, 1592, 660, 480, 658, 1594, 658, 1594, 658, 480, 658, 480, 660, 480, 658, 480, 658, 480, 658, 480, 658, 480, 658, 480, 658, 1594, 660, 1592, 658, 1594, 658, 1594, 658, 1592, 658, 1594, 658, 39002, 9094, 2162, 658}; // NEC 1FEC03F -18:14:44.497 -> uint32_t address = 0x80; -18:14:44.497 -> uint32_t command = 0x3; -18:14:44.497 -> uint64_t data = 0x1FEC03F; - -//VOl. High - -18:15:11.677 -> Protocol : NEC -18:15:11.677 -> Code : 0x1FE40BF (32 Bits) -18:15:11.677 -> uint16_t rawData[67] = {9068, 4426, 630, 506, 632, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 656, 1594, 630, 1622, 632, 1620, 630, 1622, 630, 508, 630, 508, 630, 1622, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 1622, 656, 482, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 632, 1620, 630}; // NEC 1FE40BF -18:15:11.747 -> uint32_t address = 0x80; -18:15:11.747 -> uint32_t command = 0x2; -18:15:11.747 -> uint64_t data = 0x1FE40BF; - -//Play/Pause - -18:15:38.529 -> Protocol : NEC -18:15:38.529 -> Code : 0x1FE32CD (32 Bits) -18:15:38.529 -> uint16_t rawData[71] = {9092, 4400, 632, 504, 658, 480, 658, 480, 632, 506, 658, 480, 658, 480, 658, 482, 632, 1620, 658, 1594, 658, 1594, 632, 1618, 658, 1594, 658, 1594, 632, 1620, 632, 1618, 634, 506, 658, 480, 658, 480, 632, 1620, 658, 1598, 656, 478, 658, 478, 658, 1594, 658, 482, 632, 1618, 632, 1618, 634, 506, 632, 506, 658, 1594, 632, 1620, 658, 480, 632, 1620, 658, 38998, 9094, 2162, 660}; // NEC 1FE32CD -18:15:38.564 -> uint32_t address = 0x80; -18:15:38.564 -> uint32_t command = 0x4C; -18:15:38.564 -> uint64_t data = 0x1FE32CD; - -//Song Back - -18:16:07.527 -> Protocol : NEC -18:16:07.527 -> Code : 0x1FEA05F (32 Bits) -18:16:07.562 -> uint16_t rawData[71] = {9590, 3902, 684, 452, 686, 456, 652, 480, 660, 480, 684, 456, 656, 480, 658, 480, 684, 1568, 658, 1594, 658, 1594, 686, 1566, 658, 1594, 684, 1568, 658, 1594, 658, 1594, 686, 454, 684, 1568, 686, 454, 658, 1594, 684, 454, 686, 454, 658, 480, 660, 480, 684, 454, 658, 482, 658, 1594, 682, 456, 658, 1596, 658, 1594, 686, 1568, 660, 1592, 684, 1568, 686, 38982, 9098, 2162, 684}; // NEC 1FEA05F -18:16:07.597 -> uint32_t address = 0x80; -18:16:07.597 -> uint32_t command = 0x5; -18:16:07.597 -> uint64_t data = 0x1FEA05F; - -//Song Forward - -18:17:20.541 -> Protocol : NEC -18:17:20.541 -> Code : 0x1FEE01F (32 Bits) -18:17:20.575 -> uint16_t rawData[71] = {9068, 4424, 632, 506, 630, 506, 632, 508, 606, 532, 632, 506, 630, 508, 630, 508, 632, 1620, 632, 1620, 632, 1620, 604, 1646, 606, 1646, 630, 1622, 604, 1646, 632, 1620, 606, 534, 630, 1622, 604, 1646, 630, 1622, 604, 534, 630, 508, 604, 534, 606, 534, 630, 508, 630, 508, 606, 534, 606, 532, 630, 1622, 604, 1646, 632, 1620, 604, 1648, 604, 1646, 604, 39040, 9040, 2216, 604}; // NEC 1FEE01F -18:17:20.610 -> uint32_t address = 0x80; -18:17:20.610 -> uint32_t command = 0x7; -18:17:20.610 -> uint64_t data = 0x1FEE01F; - - */ - -// check complete video tutorial here for program explanation https://www.youtube.com/watch?v=LqmkDKu54XY&t=17s - -/* Comment this out to disable prints and save space */ -#define BLYNK_PRINT Serial -#define BLYNK_TEMPLATE_ID "TMPL••••••••" // Made up values. Please Change. -#define BLYNK_TEMPLATE_NAME "My First Device" // Please Change. - -#if defined(ESP8266) -#include -#include -#else -#include -#endif // ESP8266 -#if defined(ESP32) -#include -#endif // ESP32 - -// IR library -#include -#include - -const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2). -IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message. - -// You should get Auth Token in the Blynk App. -// Go to the Project Settings (nut icon). -char auth[] = "YourAuthToken"; - -// Your WiFi credentials. -// Set password to "" for open networks. -char ssid[] = "YourNetworkName"; -char pass[] = "YourPassword"; - - BLYNK_WRITE(V51) { // Power button - if (param.asInt() == 0) { - // Serial.println("NEC"); - irsend.sendNEC(0x1FE50AF); - } - } - - BLYNK_WRITE(V52) { // Mute button - if (param.asInt() == 0) { - // Serial.println("NEC"); - irsend.sendNEC(0x1FE30CF); - } - } - - BLYNK_WRITE(V53) { // Song Forward - if (param.asInt() == 0) { - // Serial.println("NEC"); - irsend.sendNEC(0x1FEE01F); - } - } - - BLYNK_WRITE(V54) { // Song Backward - if (param.asInt() == 0) { - // Serial.println("NEC"); - irsend.sendNEC(0x1FEA05F); - delay(10); // double tap back button to back one song - irsend.sendNEC(0x1FEA05F); - } - } - - BLYNK_WRITE(V55) { // Volume -- - if (param.asInt() == 0) { - // Serial.println("NEC"); - irsend.sendNEC(0x1FEC03F); - } - } - - BLYNK_WRITE(V56) { // Volume ++ - if (param.asInt() == 0) { - // Serial.println("NEC"); - irsend.sendNEC(0x1FE40BF); - } - } - - BLYNK_WRITE(V57) { // Play/Pause - if (param.asInt() == 0) { - // Serial.println("NEC"); - irsend.sendNEC(0x1FE32CD); - } - } - -void setup() { -#if defined(BLYNK_PRINT) - // Debug console - Serial.begin(115200); -#endif // BLYNK_PRINT - - Blynk.begin(auth, ssid, pass); -} - -void loop() { - Blynk.run(); -} +/************************************************************* + Emulate a physical remote via an iOS and Android App. + Copyright Gaurav Barwalia 2020 + + Download latest Blynk library here: + https://github.com/blynkkk/blynk-library/releases/latest + + Blynk is a platform with iOS and Android apps to control + Arduino, Raspberry Pi and the likes over the Internet. + You can easily build graphic interfaces for all your + projects by simply dragging and dropping widgets. + + Downloads, docs, tutorials: http://www.blynk.cc + Sketch generator: http://examples.blynk.cc + Blynk community: http://community.blynk.cc + Follow us: http://www.fb.com/blynkapp + http://twitter.com/blynk_app + + Blynk library is licensed under MIT license + This example code is in public domain. + + ************************************************************* + This example runs directly on ESP8266 chip. + + Note: This requires ESP8266 support package: + https://github.com/esp8266/Arduino + + Please be sure to select the right ESP8266 module + in the Tools -> Board menu! + + Change WiFi ssid, pass, and Blynk auth token to run :) + Feel free to apply it to any other example. It's simple! + *************************************************************/ + + /* + // After decoding received below codes + + // Power button + +18:12:33.993 -> Protocol : NEC +18:12:33.993 -> Code : 0x1FE50AF (32 Bits) +18:12:33.993 -> uint16_t rawData[71] = {9040, 4452, 606, 532, 606, 534, 630, 508, 604, 534, 604, 534, 604, 534, 630, 506, 606, 1646, 632, 1620, 606, 1646, 632, 1620, 630, 1620, 632, 1620, 630, 1620, 606, 1646, 632, 506, 632, 506, 632, 1620, 632, 506, 632, 1620, 632, 506, 632, 508, 632, 506, 632, 506, 632, 1620, 632, 506, 632, 1624, 628, 506, 632, 1620, 632, 1618, 632, 1620, 632, 1620, 632, 39016, 9040, 2216, 630}; // NEC 1FE50AF +18:12:34.027 -> uint32_t address = 0x80; +18:12:34.027 -> uint32_t command = 0xA; +18:12:34.027 -> uint64_t data = 0x1FE50AF; + +//mute button + +18:13:27.215 -> Protocol : NEC +18:13:27.215 -> Code : 0x1FE30CF (32 Bits) +18:13:27.215 -> uint16_t rawData[71] = {9094, 4398, 660, 478, 658, 480, 658, 480, 658, 480, 658, 480, 658, 480, 660, 480, 658, 1594, 658, 1594, 658, 1594, 658, 1594, 658, 1592, 658, 1594, 658, 1592, 658, 1594, 660, 480, 658, 480, 658, 480, 658, 1592, 658, 1592, 658, 480, 658, 480, 660, 478, 660, 478, 658, 1594, 658, 1592, 658, 480, 658, 480, 658, 1594, 658, 1592, 658, 1594, 658, 1594, 658, 38986, 9094, 2162, 658}; // NEC 1FE30CF +18:13:27.285 -> uint32_t address = 0x80; +18:13:27.285 -> uint32_t command = 0xC; +18:13:27.285 -> uint64_t data = 0x1FE30CF; + +//Vol. low + +18:14:44.427 -> Protocol : NEC +18:14:44.427 -> Code : 0x1FEC03F (32 Bits) +18:14:44.427 -> uint16_t rawData[71] = {9120, 4374, 658, 478, 658, 480, 658, 480, 658, 480, 658, 482, 658, 478, 658, 480, 658, 1594, 658, 1594, 658, 1592, 660, 1594, 658, 1592, 658, 1594, 658, 1594, 658, 1592, 660, 480, 658, 1594, 658, 1594, 658, 480, 658, 480, 660, 480, 658, 480, 658, 480, 658, 480, 658, 480, 658, 480, 658, 1594, 660, 1592, 658, 1594, 658, 1594, 658, 1592, 658, 1594, 658, 39002, 9094, 2162, 658}; // NEC 1FEC03F +18:14:44.497 -> uint32_t address = 0x80; +18:14:44.497 -> uint32_t command = 0x3; +18:14:44.497 -> uint64_t data = 0x1FEC03F; + +//VOl. High + +18:15:11.677 -> Protocol : NEC +18:15:11.677 -> Code : 0x1FE40BF (32 Bits) +18:15:11.677 -> uint16_t rawData[67] = {9068, 4426, 630, 506, 632, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 656, 1594, 630, 1622, 632, 1620, 630, 1622, 630, 508, 630, 508, 630, 1622, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 508, 630, 1622, 656, 482, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 630, 1622, 632, 1620, 630}; // NEC 1FE40BF +18:15:11.747 -> uint32_t address = 0x80; +18:15:11.747 -> uint32_t command = 0x2; +18:15:11.747 -> uint64_t data = 0x1FE40BF; + +//Play/Pause + +18:15:38.529 -> Protocol : NEC +18:15:38.529 -> Code : 0x1FE32CD (32 Bits) +18:15:38.529 -> uint16_t rawData[71] = {9092, 4400, 632, 504, 658, 480, 658, 480, 632, 506, 658, 480, 658, 480, 658, 482, 632, 1620, 658, 1594, 658, 1594, 632, 1618, 658, 1594, 658, 1594, 632, 1620, 632, 1618, 634, 506, 658, 480, 658, 480, 632, 1620, 658, 1598, 656, 478, 658, 478, 658, 1594, 658, 482, 632, 1618, 632, 1618, 634, 506, 632, 506, 658, 1594, 632, 1620, 658, 480, 632, 1620, 658, 38998, 9094, 2162, 660}; // NEC 1FE32CD +18:15:38.564 -> uint32_t address = 0x80; +18:15:38.564 -> uint32_t command = 0x4C; +18:15:38.564 -> uint64_t data = 0x1FE32CD; + +//Song Back + +18:16:07.527 -> Protocol : NEC +18:16:07.527 -> Code : 0x1FEA05F (32 Bits) +18:16:07.562 -> uint16_t rawData[71] = {9590, 3902, 684, 452, 686, 456, 652, 480, 660, 480, 684, 456, 656, 480, 658, 480, 684, 1568, 658, 1594, 658, 1594, 686, 1566, 658, 1594, 684, 1568, 658, 1594, 658, 1594, 686, 454, 684, 1568, 686, 454, 658, 1594, 684, 454, 686, 454, 658, 480, 660, 480, 684, 454, 658, 482, 658, 1594, 682, 456, 658, 1596, 658, 1594, 686, 1568, 660, 1592, 684, 1568, 686, 38982, 9098, 2162, 684}; // NEC 1FEA05F +18:16:07.597 -> uint32_t address = 0x80; +18:16:07.597 -> uint32_t command = 0x5; +18:16:07.597 -> uint64_t data = 0x1FEA05F; + +//Song Forward + +18:17:20.541 -> Protocol : NEC +18:17:20.541 -> Code : 0x1FEE01F (32 Bits) +18:17:20.575 -> uint16_t rawData[71] = {9068, 4424, 632, 506, 630, 506, 632, 508, 606, 532, 632, 506, 630, 508, 630, 508, 632, 1620, 632, 1620, 632, 1620, 604, 1646, 606, 1646, 630, 1622, 604, 1646, 632, 1620, 606, 534, 630, 1622, 604, 1646, 630, 1622, 604, 534, 630, 508, 604, 534, 606, 534, 630, 508, 630, 508, 606, 534, 606, 532, 630, 1622, 604, 1646, 632, 1620, 604, 1648, 604, 1646, 604, 39040, 9040, 2216, 604}; // NEC 1FEE01F +18:17:20.610 -> uint32_t address = 0x80; +18:17:20.610 -> uint32_t command = 0x7; +18:17:20.610 -> uint64_t data = 0x1FEE01F; + + */ + +// check complete video tutorial here for program explanation https://www.youtube.com/watch?v=LqmkDKu54XY&t=17s + +/* Comment this out to disable prints and save space */ +#define BLYNK_PRINT Serial +#define BLYNK_TEMPLATE_ID "TMPL••••••••" // Made up values. Please Change. +#define BLYNK_TEMPLATE_NAME "My First Device" // Please Change. + +#if defined(ESP8266) +#include +#include +#else +#include +#endif // ESP8266 +#if defined(ESP32) +#include +#endif // ESP32 + +// IR library +#include +#include + +const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2). +IRsend irsend(kIrLed); // Set the GPIO to be used to sending the message. + +// You should get Auth Token in the Blynk App. +// Go to the Project Settings (nut icon). +char auth[] = "YourAuthToken"; + +// Your WiFi credentials. +// Set password to "" for open networks. +char ssid[] = "YourNetworkName"; +char pass[] = "YourPassword"; + + BLYNK_WRITE(V51) { // Power button + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE50AF); + } + } + + BLYNK_WRITE(V52) { // Mute button + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE30CF); + } + } + + BLYNK_WRITE(V53) { // Song Forward + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FEE01F); + } + } + + BLYNK_WRITE(V54) { // Song Backward + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FEA05F); + delay(10); // double tap back button to back one song + irsend.sendNEC(0x1FEA05F); + } + } + + BLYNK_WRITE(V55) { // Volume -- + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FEC03F); + } + } + + BLYNK_WRITE(V56) { // Volume ++ + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE40BF); + } + } + + BLYNK_WRITE(V57) { // Play/Pause + if (param.asInt() == 0) { + // Serial.println("NEC"); + irsend.sendNEC(0x1FE32CD); + } + } + +void setup() { +#if defined(BLYNK_PRINT) + // Debug console + Serial.begin(115200); +#endif // BLYNK_PRINT + + Blynk.begin(auth, ssid, pass); +} + +void loop() { + Blynk.run(); +} diff --git a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/TurnOnGreeAC/TurnOnGreeAC.ino b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/TurnOnGreeAC/TurnOnGreeAC.ino index 64c857f3d..ecb3b8869 100644 --- a/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/TurnOnGreeAC/TurnOnGreeAC.ino +++ b/lib/lib_basic/IRremoteESP8266/IRremoteESP8266/examples/TurnOnGreeAC/TurnOnGreeAC.ino @@ -1,77 +1,77 @@ -/* Copyright 2016, 2018 David Conran -* Copyright 2020 Sadid Rafsun Tulon -* -* An IR LED circuit *MUST* be connected to the ESP8266 on a pin -* as specified by kIrLed below. -* -* TL;DR: The IR LED needs to be driven by a transistor for a good result. -* -* Suggested circuit: -* https://github.com/crankyoldgit/IRremoteESP8266/wiki#ir-sending -* -* Common mistakes & tips: -* * Don't just connect the IR LED directly to the pin, it won't -* have enough current to drive the IR LED effectively. -* * Make sure you have the IR LED polarity correct. -* See: https://learn.sparkfun.com/tutorials/polarity/diode-and-led-polarity -* * Typical digital camera/phones can be used to see if the IR LED is flashed. -* Replace the IR LED with a normal LED if you don't have a digital camera -* when debugging. -* * Avoid using the following pins unless you really know what you are doing: -* * Pin 0/D3: Can interfere with the boot/program mode & support circuits. -* * Pin 1/TX/TXD0: Any serial transmissions from the ESP8266 will interfere. -* * Pin 3/RX/RXD0: Any serial transmissions to the ESP8266 will interfere. -* * ESP-01 modules are tricky. We suggest you use a module with more GPIOs -* for your first time. e.g. ESP-12 etc. -*/ -#include -#include -#include -#include - -const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2). -IRGreeAC ac(kIrLed); // Set the GPIO to be used for sending messages. - -void printState() { - // Display the settings. - Serial.println("GREE A/C remote is in the following state:"); - Serial.printf(" %s\n", ac.toString().c_str()); - // Display the encoded IR sequence. - unsigned char* ir_code = ac.getRaw(); - Serial.print("IR Code: 0x"); - for (uint8_t i = 0; i < kGreeStateLength; i++) - Serial.printf("%02X", ir_code[i]); - Serial.println(); -} - -void setup() { - ac.begin(); - Serial.begin(115200); - delay(200); - - // Set up what we want to send. See ir_Gree.cpp for all the options. - // Most things default to off. - Serial.println("Default state of the remote."); - printState(); - Serial.println("Setting desired state for A/C."); - ac.on(); - ac.setFan(1); - // kGreeAuto, kGreeDry, kGreeCool, kGreeFan, kGreeHeat - ac.setMode(kGreeCool); - ac.setTemp(20); // 16-30C - ac.setSwingVertical(true, kGreeSwingAuto); - ac.setXFan(false); - ac.setLight(false); - ac.setSleep(false); - ac.setTurbo(false); -} - -void loop() { - // Now send the IR signal. -#if SEND_GREE - Serial.println("Sending IR command to A/C ..."); - ac.send(); -#endif // SEND_GREE - printState(); - delay(5000); -} +/* Copyright 2016, 2018 David Conran +* Copyright 2020 Sadid Rafsun Tulon +* +* An IR LED circuit *MUST* be connected to the ESP8266 on a pin +* as specified by kIrLed below. +* +* TL;DR: The IR LED needs to be driven by a transistor for a good result. +* +* Suggested circuit: +* https://github.com/crankyoldgit/IRremoteESP8266/wiki#ir-sending +* +* Common mistakes & tips: +* * Don't just connect the IR LED directly to the pin, it won't +* have enough current to drive the IR LED effectively. +* * Make sure you have the IR LED polarity correct. +* See: https://learn.sparkfun.com/tutorials/polarity/diode-and-led-polarity +* * Typical digital camera/phones can be used to see if the IR LED is flashed. +* Replace the IR LED with a normal LED if you don't have a digital camera +* when debugging. +* * Avoid using the following pins unless you really know what you are doing: +* * Pin 0/D3: Can interfere with the boot/program mode & support circuits. +* * Pin 1/TX/TXD0: Any serial transmissions from the ESP8266 will interfere. +* * Pin 3/RX/RXD0: Any serial transmissions to the ESP8266 will interfere. +* * ESP-01 modules are tricky. We suggest you use a module with more GPIOs +* for your first time. e.g. ESP-12 etc. +*/ +#include +#include +#include +#include + +const uint16_t kIrLed = 4; // ESP8266 GPIO pin to use. Recommended: 4 (D2). +IRGreeAC ac(kIrLed); // Set the GPIO to be used for sending messages. + +void printState() { + // Display the settings. + Serial.println("GREE A/C remote is in the following state:"); + Serial.printf(" %s\n", ac.toString().c_str()); + // Display the encoded IR sequence. + unsigned char* ir_code = ac.getRaw(); + Serial.print("IR Code: 0x"); + for (uint8_t i = 0; i < kGreeStateLength; i++) + Serial.printf("%02X", ir_code[i]); + Serial.println(); +} + +void setup() { + ac.begin(); + Serial.begin(115200); + delay(200); + + // Set up what we want to send. See ir_Gree.cpp for all the options. + // Most things default to off. + Serial.println("Default state of the remote."); + printState(); + Serial.println("Setting desired state for A/C."); + ac.on(); + ac.setFan(1); + // kGreeAuto, kGreeDry, kGreeCool, kGreeFan, kGreeHeat + ac.setMode(kGreeCool); + ac.setTemp(20); // 16-30C + ac.setSwingVertical(true, kGreeSwingAuto); + ac.setXFan(false); + ac.setLight(false); + ac.setSleep(false); + ac.setTurbo(false); +} + +void loop() { + // Now send the IR signal. +#if SEND_GREE + Serial.println("Sending IR command to A/C ..."); + ac.send(); +#endif // SEND_GREE + printState(); + delay(5000); +} diff --git a/lib/lib_basic/NeoPixelBus/.gitignore b/lib/lib_basic/NeoPixelBus/.gitignore index 6dae74742..08e23decd 100644 --- a/lib/lib_basic/NeoPixelBus/.gitignore +++ b/lib/lib_basic/NeoPixelBus/.gitignore @@ -1,32 +1,32 @@ -# Windows image file caches -Thumbs.db -ehthumbs.db - -# Folder config file -Desktop.ini - -# Recycle Bin used on file shares -$RECYCLE.BIN/ - -# Windows Installer files -*.cab -*.msi -*.msm -*.msp - -# ========================= -# Operating System Files -# ========================= - -# OSX -# ========================= - +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# ========================= +# Operating System Files +# ========================= + +# OSX +# ========================= + .DS_Store .AppleDouble .LSOverride # Icon must ends with two \r. -Icon +Icon # Thumbnails ._* diff --git a/lib/lib_div/ESPFtpServer/ESPFtpServer.cpp b/lib/lib_div/ESPFtpServer/ESPFtpServer.cpp index afe14f5e5..84e9b3656 100755 --- a/lib/lib_div/ESPFtpServer/ESPFtpServer.cpp +++ b/lib/lib_div/ESPFtpServer/ESPFtpServer.cpp @@ -1,1133 +1,1133 @@ -/* - * FTP SERVER FOR ESP32/ESP8266 - * based on FTP Server for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200) - * based on Jean-Michel Gallego's work - * modified to work with esp8266 SPIFFS by David Paiva david@nailbuster.com - * 2017: modified by @robo8080 (ported to ESP32 and SD) - * 2019: modified by @fa1ke5 (use SD card in SD_MMC mode (No SD lib, SD_MMC lib), and added fully fuctional passive mode ftp server) - * 2020: modified by @jmwislez (support generic FS, and re-introduced ESP8266) - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -#include "ESPFtpServer.h" -#include - -#ifdef ESP32 -#undef F -#define F(A) A -#endif - -void FtpServer::begin (String uname, String pword, FS *ufp) { - - if (is_up) return; - - cfsp = ufp; - - // Tells the ftp server to begin listening for incoming connection - _FTP_USER = uname; - _FTP_PASS = pword; - - ftpServer = new WiFiServer(FTP_CTRL_PORT); - if (!ftpServer) return; - dataServer = new WiFiServer(FTP_DATA_PORT_PASV); - if (!dataServer) return; - - ftpServer->begin (); - delay (10); - dataServer->begin (); - delay (10); - millisTimeOut = (uint32_t)FTP_TIME_OUT * 60 * 1000; - millisDelay = 0; - cmdStatus = 0; - iniVariables (); - is_up = true; -} - -FtpServer::~FtpServer(void) { - ftpServer->close(); - ftpServer->stop(); - delete ftpServer; - dataServer->close(); - dataServer->stop(); - delete dataServer; -} - - -void FtpServer::iniVariables () { - // Default for data port - dataPort = FTP_DATA_PORT_PASV; - - // Default Data connection is Active - dataPassiveConn = false; - - // Set the root directory - strcpy (cwdName, "/"); - - rnfrCmd = false; - transferStatus = 0; -} - -void FtpServer::handleFTP () { - - if (!is_up) return; - - if ((int32_t) (millisDelay - millis ()) > 0) { - return; - } - - if (ftpServer->hasClient ()) { - #ifdef FTP_DEBUG - Serial.println (F("-> disconnecting client")); - #endif - client.stop (); - client = ftpServer->available (); - } - - if (cmdStatus == 0) { - if (client.connected ()) { - disconnectClient (); - } - cmdStatus = 1; - } - else if (cmdStatus == 1) { // Ftp server waiting for connection - abortTransfer (); - iniVariables (); - #ifdef FTP_DEBUG - Serial.println (F("-> ftp server waiting for connection on port ") + String (FTP_CTRL_PORT)); - #endif - cmdStatus = 2; - } - else if (cmdStatus == 2) { // Ftp server idle - if (client.connected ()) { // A client connected - clientConnected (); - millisEndConnection = millis () + 10 * 1000; // wait client id during 10 s. - cmdStatus = 3; - } - } - else if (readChar () > 0) { // got response - if (cmdStatus == 3) { // Ftp server waiting for user identity - if (userIdentity ()) { - cmdStatus = 4; - } - else { - cmdStatus = 0; - } - } - else if (cmdStatus == 4) { // Ftp server waiting for user registration - if (userPassword ()) { - cmdStatus = 5; - millisEndConnection = millis () + millisTimeOut; - } - else { - cmdStatus = 0; - } - } - else if (cmdStatus == 5) { // Ftp server waiting for user command - if (!processCommand ()) { - cmdStatus = 0; - } - else { - millisEndConnection = millis () + millisTimeOut; - } - } - } - else if (!client.connected () || !client) { - cmdStatus = 1; - #ifdef FTP_DEBUG - Serial.println (F("-> client disconnected")); - #endif - } - - if (transferStatus == 1) { // Retrieve data - if (!doRetrieve ()) { - transferStatus = 0; - } - } - else if (transferStatus == 2) { // Store data - if (!doStore ()) { - transferStatus = 0; - } - } - else if (cmdStatus > 2 && ! ((int32_t) (millisEndConnection - millis ()) > 0 )) { - client.println (F("530 Timeout")); - millisDelay = millis () + 200; // delay of 200 ms - cmdStatus = 0; - } -} - -void FtpServer::clientConnected () { - #ifdef FTP_DEBUG - Serial.println (F("-> client connected")); - #endif - client.println (F("220-Welcome to FTP for ESP8266/ESP32")); - client.println (F("220-By David Paiva")); - client.println (F("220-Version ") + String (FTP_SERVER_VERSION)); - client.println (F("220 Put your ftp client in passive mode, and do not attempt more than one connection")); - iCL = 0; -} - -void FtpServer::disconnectClient () { - #ifdef FTP_DEBUG - Serial.println (F("-> disconnecting client")); - #endif - abortTransfer (); - client.println (F("221 Goodbye")); - client.stop (); -} - -boolean FtpServer::userIdentity () { - if (strcmp (command, "USER")) { - client.println (F("500 Syntax error")); - } - if (strcmp (parameters, _FTP_USER.c_str ())) { - client.println (F("530 user not found")); - } - else { - client.println (F("331 OK. Password required")); - strcpy (cwdName, "/"); - return true; - } - millisDelay = millis () + 100; // delay of 100 ms - return false; -} - -boolean FtpServer::userPassword () { - if (strcmp (command, "PASS")) { - client.println (F("500 Syntax error")); - } - else if (strcmp (parameters, _FTP_PASS.c_str ())) { - client.println (F("530 ")); - } - else { - #ifdef FTP_DEBUG - Serial.println (F("-> user authenticated")); - #endif - client.println (F("230 OK.")); - return true; - } - millisDelay = millis () + 100; // delay of 100 ms - return false; -} - -boolean FtpServer::processCommand () { - struct tm * ptm; - time_t ftime; - char buffer[80]; - - /////////////////////////////////////// - // // - // ACCESS CONTROL COMMANDS // - // // - /////////////////////////////////////// - - // - // CDUP - Change to Parent Directory - // - if (!strcmp (command, "CDUP") || (!strcmp (command, "CWD") && !strcmp (parameters, ".."))) { - bool ok = false; - if (strlen (cwdName) > 1) { // do nothing if cwdName is root - // if cwdName ends with '/', remove it (must not append) - if (cwdName[strlen (cwdName) - 1] == '/') { - cwdName[ strlen (cwdName ) - 1 ] = 0; - } - // search last '/' - char * pSep = strrchr (cwdName, '/'); - ok = pSep > cwdName; - // if found, ends the string on its position - if (ok) { - * pSep = 0; - ok = cfsp->exists (cwdName); - } - } - // if an error appends, move to root - if (!ok) { - strcpy (cwdName, "/"); - } - client.println (F("250 Ok. Current directory is ") + String (cwdName)); - } - - // - // CWD - Change Working Directory - // - else if (!strcmp (command, "CWD")) { - char path[FTP_CWD_SIZE]; - if (haveParameter () && makeExistsPath (path)) { - strcpy (cwdName, path); - client.println (F("250 Ok. Current directory is ") + String (cwdName)); - } - } - - // - // PWD - Print Directory - // - else if (!strcmp (command, "PWD")) { - client.println (F("257 \"") + String (cwdName) + F("\" is your current directory")); - } - - // - // QUIT - // - else if (!strcmp (command, "QUIT")) { - disconnectClient (); - return false; - } - - /////////////////////////////////////// - // // - // TRANSFER PARAMETER COMMANDS // - // // - /////////////////////////////////////// - - // - // MODE - Transfer Mode - // - else if (!strcmp (command, "MODE")) { - if (!strcmp (parameters, "S")) { - client.println (F("200 S Ok")); - } - else { - client.println (F("504 Only S (tream) is supported")); - } - } - - // - // PASV - Passive Connection management - // - else if (!strcmp (command, "PASV")) { - if (data.connected ()) { - data.stop (); - #ifdef FTP_DEBUG - Serial.println (F("-> client disconnected from dataserver")); - #endif - } - dataIp = WiFi.localIP (); - dataPort = FTP_DATA_PORT_PASV; - #ifdef FTP_DEBUG - Serial.println (F("-> connection management set to passive")); - Serial.println (F("-> data port set to ") + String (dataPort)); - #endif - client.println (F("227 Entering Passive Mode (") + String (dataIp[0]) + "," + String (dataIp[1]) + "," + String (dataIp[2]) + "," + String (dataIp[3]) + "," + String (dataPort >> 8) + "," + String (dataPort & 255) + ")."); - dataPassiveConn = true; - } - - // - // PORT - Data Port - // - else if (!strcmp (command, "PORT")) { - if (data) { - data.stop (); - #ifdef FTP_DEBUG - Serial.println (F("-> client disconnected from dataserver")); - #endif - } - // get IP of data client - dataIp[0] = atoi (parameters); - char * p = strchr (parameters, ','); - for (uint8_t i = 1; i < 4; i ++) { - dataIp[i] = atoi (++ p); - p = strchr (p, ','); - } - // get port of data client - dataPort = 256 * atoi (++ p); - p = strchr (p, ','); - dataPort += atoi (++ p); - if (p == NULL) { - client.println (F("501 Can't interpret parameters")); - } - else { - client.println (F("200 PORT command successful")); - dataPassiveConn = false; - } - } - - // - // STRU - File Structure - // - else if (!strcmp (command, "STRU")) { - if (!strcmp (parameters, "F")) { - client.println (F("200 F Ok")); - } - else { - client.println (F("504 Only F (ile) is supported")); - } - } - - // - // TYPE - Data Type - // - else if (!strcmp (command, "TYPE")) { - if (!strcmp (parameters, "A")) { - client.println (F("200 TYPE is now ASCII")); - } - else if (!strcmp (parameters, "I" )) { - client.println (F("200 TYPE is now 8-bit binary")); - } - else { - client.println (F("504 Unknown TYPE")); - } - } - - /////////////////////////////////////// - // // - // FTP SERVICE COMMANDS // - // // - /////////////////////////////////////// - - // - // ABOR - Abort - // - else if (!strcmp (command, "ABOR")) { - abortTransfer (); - client.println (F("226 Data connection closed")); - } - - // - // DELE - Delete a File - // - else if (!strcmp (command, "DELE")) { - char path[FTP_CWD_SIZE]; - if (strlen (parameters) == 0) { - client.println (F("501 No file name")); - } - else if (makePath (path)) { - if (!cfsp->exists (path)) { - client.println (F("550 File ") + String (parameters) + F(" not found")); - } - else { - if (cfsp->remove (path)) { - client.println (F("250 Deleted ") + String (parameters)); - // silently recreate the directory if it vanished with the last file it contained - String directory = String (path).substring (0, String(path).lastIndexOf ("/")); - if (!cfsp->exists (directory.c_str())) { - cfsp->mkdir (directory.c_str()); - } - } - else { - client.println (F("450 Can't delete ") + String (parameters)); - } - } - } - } - - // - // LIST - List - // - else if (!strcmp (command, "LIST")) { - if (dataConnect ()) { - client.println (F("150 Accepted data connection")); - uint16_t nm = 0; - - #ifdef ESP8266 - Dir dir = cfsp->openDir (cwdName); - while (dir.next ()) { - String fname, fsize; - fname = dir.fileName (); - time_t ftime = dir.fileTime (); - ptm = gmtime (&ftime); - int pos = fname.lastIndexOf ("/"); //looking for the beginning of the file by the last "/" - fname.remove (0, pos + 1); //Delete everything up to and including the filename - fsize = String (dir.fileSize ()); - if (dir.isDirectory ()){ - sprintf (buffer, "%04d-%02d-%02d %02d:%02d %s", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, fname.c_str()); - } - else { - sprintf (buffer, "%04d-%02d-%02d %02d:%02d %s %s", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, fillSpaces (14, String (fsize)).c_str(), fname.c_str()); - } - data.println (buffer); - nm ++; - } - client.println( "226 " + String (nm) + " matches total"); - #endif - #ifdef ESP32 - File dir = cfsp->open (cwdName); - if ((!dir) || (!dir.isDirectory ())) { - client.println (F("550 Can't open directory ") + String (cwdName)); - } - else { - File file = dir.openNextFile (); - while (file) { - String fname, fsize; - fname = file.name (); - ftime = file.getLastWrite (); - ptm = gmtime (&ftime); - int pos = fname.lastIndexOf ("/"); //looking for the beginning of the file by the last "/" - fname.remove (0, pos + 1); //Delete everything up to and including the filename - #ifdef FTP_DEBUG - Serial.println ("-> " + fname); - #endif - fsize = String (file.size ()); - if (file.isDirectory ()){ - sprintf (buffer, "%04u-%02u-%02u %02u:%02u %s", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, fname.c_str()); - } - else { - sprintf (buffer, "%04u-%02u-%02u %02d:%02u %s %s", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, fillSpaces (14, String (fsize)).c_str(), fname.c_str()); - } - data.println (buffer); - nm ++; - file = dir.openNextFile (); - } - client.println ("226 " + String (nm) + F(" matches total")); - } - #endif - data.stop (); - #ifdef FTP_DEBUG - Serial.println (F("-> client disconnected from dataserver")); - #endif - } - else { - client.println (F("425 No data connection")); - data.stop (); - } - } - - // - // MLSD - Listing for Machine Processing (see RFC 3659) - // - else if (!strcmp (command, "MLSD")) { - if (!dataConnect ()) { - client.println (F("425 No data connection MLSD")); - } - else { - client.println (F("150 Accepted data connection")); - uint16_t nm = 0; - #ifdef ESP8266 - Dir dir = cfsp->openDir (cwdName); - char dtStr[15]; - while (dir.next ()) { - String fn, fs; - fn = dir.fileName (); - int pos = fn.lastIndexOf ("/"); //looking for the beginning of the file by the last "/" - fn.remove (0, pos + 1); //Delete everything up to and including the filename - fs = String (dir.fileSize ()); - ftime = dir.fileTime (); - ptm = gmtime (&ftime); - if (dir.isDirectory ()) { - sprintf (buffer, "Type=dir;Modify=%04u%02u%02u%02u%02u%02u; %s", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, fn.c_str()); - } - else { - sprintf (buffer, "Type=file;Size=%s;Modify=%04u%02u%02u%02u%02u%02u; %s", fs.c_str(), ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, fn.c_str()); - } - data.println (buffer); - nm ++; - } - client.println (F("226-options: -a -l")); - client.println("226 " + String(nm) + F(" matches total")); - #endif - #ifdef ESP32 - File dir = cfsp->open (cwdName); - char dtStr[15]; - if (!cfsp->exists (cwdName)) { - client.println (F("550 Can't open directory ") + String (parameters)); - } - else { - File file = dir.openNextFile (); - while (file) { - String fn, fs; - fn = file.name (); - int pos = fn.lastIndexOf ("/"); // looking for the beginning of the file by the last "/" - fn.remove (0, pos + 1); // delete everything up to and including the filename - fs = String (file.size ()); - ftime = file.getLastWrite (); - ptm = gmtime (&ftime); - if (file.isDirectory ()) { - sprintf (buffer, "Type=dir;Modify=%04u%02u%02u%02u%02u%02u; %s", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, fn.c_str()); - } - else { - sprintf (buffer, "Type=file;Size=%s;Modify=%04u%02u%02u%02u%02u%02u; %s", fs.c_str(), ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, fn.c_str()); - } - data.println (buffer); - nm ++; - file = dir.openNextFile (); - } - client.println (F("226-options: -a -l")); - client.println ("226 " + String (nm) + F(" matches total")); - } - #endif - data.stop (); - #ifdef FTP_DEBUG - Serial.println (F("-> client disconnected from dataserver")); - #endif - } - } - - // - // NLST - Name List - // - else if (!strcmp (command, "NLST" )) { - if (!dataConnect ()) { - client.println (F("425 No data connection")); - } - else { - client.println (F("150 Accepted data connection")); - uint16_t nm = 0; - #ifdef ESP8266 - Dir dir = cfsp->openDir (cwdName); - if (!cfsp->exists (cwdName)) { - client.println (F("550 Can't open directory ") + String (parameters)); - } - else { - while (dir.next ()) { - data.println (dir.fileName ()); - nm ++; - } - client.println ("226 " + String(nm) + F(" matches total")); - } - #endif - #ifdef ESP32 - File dir = cfsp->open (cwdName); - if (!cfsp->exists (cwdName)) { - client.println (F("550 Can't open directory ") + String (parameters)); - } - else { - File file = dir.openNextFile (); - while (file) { - data.println (file.name ()); - nm ++; - file = dir.openNextFile (); - } - client.println ("226 " + String (nm) + F(" matches total")); - } - #endif - data.stop (); - #ifdef FTP_DEBUG - Serial.println (F("-> client disconnected from dataserver")); - #endif - } - } - - // - // NOOP - // - else if (!strcmp (command, "NOOP")) { - client.println (F("200 Zzz...")); - } - - // - // RETR - Retrieve - // - else if (!strcmp (command, "RETR")) { - char path[FTP_CWD_SIZE]; - if (strlen (parameters) == 0) { - client.println (F("501 No file name")); - } - else if (makePath (path)) { - file = cfsp->open (path, "r"); - if (!file) { - client.println (F("550 File ") + String (parameters) + F(" not found")); - } - else if (!file) { - client.println (F("450 Can't open ") + String (parameters)); - } - else if (!dataConnect ()) { - client.println (F("425 No data connection")); - } - else { - #ifdef FTP_DEBUG - Serial.println (F("-> sending ") + String (parameters)); - #endif - client.println (F("150-Connected to port ") + String (dataPort)); - client.println (F("150 ") + String (file.size ()) + F(" bytes to download")); - millisBeginTrans = millis (); - bytesTransferred = 0; - transferStatus = 1; - } - } - } - - // - // STOR - Store - // - else if (!strcmp (command, "STOR")) { - char path[FTP_CWD_SIZE]; - if (strlen (parameters) == 0) { - client.println (F("501 No file name")); - } - else if (makePath (path)) { - file = cfsp->open (path, "w"); - if (!file) { - client.println (F("451 Can't open/create ") + String (parameters)); - } - else if (!dataConnect ()) { - client.println (F("425 No data connection")); - file.close (); - } - else { - #ifdef FTP_DEBUG - Serial.println (F("-> receiving ") + String (parameters)); - #endif - client.println (F("150 Connected to port ") + String (dataPort)); - millisBeginTrans = millis (); - bytesTransferred = 0; - transferStatus = 2; - } - } - } - - // - // MKD - Make Directory - // - - else if (!strcmp (command, "MKD")) { - char path[FTP_CWD_SIZE]; - if (haveParameter () && makePath (path)) { - if (cfsp->exists (path)) { - client.println (F("521 Can't create \"") + String (parameters) + F("\", Directory exists")); - } - else { - if (cfsp->mkdir (path)) { - client.println (F("257 \"") + String (parameters) + F("\" created")); - } - else { - client.println (F("550 Can't create \"") + String (parameters) + "\""); - } - } - } - } - - // - // RMD - Remove a Directory - // - else if (!strcmp (command, "RMD")) { - char path[FTP_CWD_SIZE]; - if (haveParameter () && makePath (path)) { - if (cfsp->rmdir (path)) { - #ifdef FTP_DEBUG - Serial.println (F("-> deleting ") + String (parameters)); - #endif - client.println ("250 \"" + String (parameters) + F("\" deleted")); - } - else { - if (cfsp->exists (path)) { // hack - client.println (F("550 Can't remove \"") + String (parameters) + F("\". Directory not empty?")); - } - else { - #ifdef FTP_DEBUG - Serial.println (F("-> deleting ") + String (parameters)); - #endif - client.println ("250 \"" + String (parameters) + F("\" deleted")); - } - } - } - } - - // - // RNFR - Rename From - // - else if (!strcmp (command, "RNFR")) { - buf[0] = 0; - if (strlen (parameters) == 0) { - client.println (F("501 No file name")); - } - else if (makePath (buf)) { - if (!cfsp->exists (buf)) { - client.println (F("550 File ") + String (parameters) + F(" not found")); - } - else { - #ifdef FTP_DEBUG - Serial.println (F("-> renaming ") + String (buf)); - #endif - client.println (F("350 RNFR accepted - file exists, ready for destination")); - rnfrCmd = true; - } - } - } - - // - // RNTO - Rename To - // - else if (!strcmp (command, "RNTO")) { - char path[FTP_CWD_SIZE]; - char dir[FTP_FIL_SIZE]; - if (strlen (buf ) == 0 || ! rnfrCmd) { - client.println (F("503 Need RNFR before RNTO")); - } - else if (strlen (parameters ) == 0) { - client.println (F("501 No file name")); - } - else if (makePath (path)) { - if (cfsp->exists (path)) { - client.println (F("553 ") + String (parameters) + F(" already exists")); - } - else { - #ifdef FTP_DEBUG - Serial.println (F("-> renaming ") + String (buf) + " to " + String (path)); - #endif - if (cfsp->rename (buf, path)) { - client.println (F("250 File successfully renamed or moved")); - } - else { - client.println (F("451 Rename/move failure")); - } - } - } - rnfrCmd = false; - } - - /////////////////////////////////////// - // // - // EXTENSIONS COMMANDS (RFC 3659) // - // // - /////////////////////////////////////// - - // - // FEAT - New Features - // - else if (!strcmp (command, "FEAT")) { - client.println (F("211-Extensions supported:")); - client.println (F(" MLSD")); - client.println (F("211 End.")); - } - - // - // MDTM - File Modification Time (see RFC 3659) - // - else if (!strcmp (command, "MDTM")) { - client.println (F("550 Unable to retrieve time")); - } - - // - // SIZE - Size of the file - // - else if (!strcmp (command, "SIZE")) { - char path[FTP_CWD_SIZE]; - if (strlen (parameters) == 0) { - client.println (F("501 No file name")); - } - else if (makePath (path)) { - file = cfsp->open (path, "r"); - if (!file) { - client.println (F("450 Can't open ") + String (parameters)); - } - else { - client.println (F("213 ") + String (file.size ())); - file.close (); - } - } - } - - // - // SITE - System command - // - else if (!strcmp (command, "SITE")) { - client.println (F("500 Unknown SITE command ") + String (parameters)); - } - - // - // Unrecognized commands ... - // - else { - client.println (F("500 Unknown command")); - } - return true; -} - -boolean FtpServer::dataConnect () { - unsigned long startTime = millis (); - //wait 5 seconds for a data connection - if (!data.connected ()) { - while (!dataServer->hasClient () && millis () - startTime < 10000) { - yield (); - } - if (dataServer->hasClient ()) { - data.stop (); - #ifdef FTP_DEBUG - Serial.println (F("-> client disconnected from dataserver")); - #endif - data = dataServer->available (); - #ifdef FTP_DEBUG - Serial.println (F("-> client connected to dataserver")); - #endif - } - } - return data.connected (); -} - -boolean FtpServer::doRetrieve () { - if (data.connected ()) { - int16_t nb = file.readBytes (buf, FTP_BUF_SIZE); - if (nb > 0) { - data.write ((uint8_t*)buf, nb); - bytesTransferred += nb; - return true; - } - } - closeTransfer (); - return false; -} - -boolean FtpServer::doStore () { - // Avoid blocking by never reading more bytes than are available - int navail = data.available(); - if (navail > 0) { - // And be sure not to overflow the buffer - if (navail > FTP_BUF_SIZE) { - navail = FTP_BUF_SIZE; - } - int16_t nb = data.read((uint8_t *)buf, navail); - if (nb > 0) { - file.write((uint8_t *)buf, nb); - bytesTransferred += nb; - } - } - if (!data.connected() && (navail <= 0)) { - closeTransfer(); - return false; - } - else { - return true; - } -} - -void FtpServer::closeTransfer () { - uint32_t deltaT = (int32_t) (millis () - millisBeginTrans); - if (deltaT > 0 && bytesTransferred > 0) { - client.println (F("226-File successfully transferred")); - client.println ("226 " + String (deltaT) + " ms, " + String (bytesTransferred / deltaT) + " kbytes/s"); - } - else { - client.println (F("226 File successfully transferred")); - } - file.close (); - data.stop (); - #ifdef FTP_DEBUG - Serial.println (F("-> file successfully transferred")); - Serial.println (F("-> client disconnected from dataserver")); - #endif -} - -void FtpServer::abortTransfer () { - if (transferStatus > 0) { - file.close (); - data.stop (); - #ifdef FTP_DEBUG - Serial.println (F("-> client disconnected from dataserver")); - #endif - client.println (F("426 Transfer aborted")); - #ifdef FTP_DEBUG - Serial.println (F("-> transfer aborted")); - #endif - } - transferStatus = 0; -} - -// Read a char from client connected to ftp server -// -// update cmdLine and command buffers, iCL and parameters pointers -// -// return: -// -2 if buffer cmdLine is full -// -1 if line not completed -// 0 if empty line received -// length of cmdLine (positive) if no empty line received - -int8_t FtpServer::readChar () { - int8_t rc = -1; - - if (client.available ()) { - char c = client.read (); - #ifdef FTP_DEBUG - Serial.print (c); - #endif - if (c == '\\') { - c = '/'; - } - if (c != '\r' ) { - if (c != '\n' ) { - if (iCL < FTP_CMD_SIZE) { - cmdLine[iCL ++] = c; - } - else { - rc = -2; // Line too long - } - } - else { - cmdLine[iCL] = 0; - command[0] = 0; - parameters = NULL; - // empty line? - if (iCL == 0) { - rc = 0; - } - else { - rc = iCL; - // search for space between command and parameters - parameters = strchr (cmdLine, ' '); - if (parameters != NULL) { - if (parameters - cmdLine > 4) { - rc = -2; // Syntax error - } - else { - strncpy (command, cmdLine, parameters - cmdLine); - command[parameters - cmdLine] = 0; - - while (* (++ parameters) == ' ') { - ; - } - } - } - else if (strlen (cmdLine) > 4) { - rc = -2; // Syntax error. - } - else { - strcpy (command, cmdLine); - } - iCL = 0; - } - } - } - if (rc > 0) { - for (uint8_t i = 0; i < strlen (command); i ++) { - command[i] = toupper (command[i]); - } - } - if (rc == -2) { - iCL = 0; - client.println (F("500 Syntax error")); - } - } - return rc; -} - -// Make complete path/name from cwdName and parameters -// -// 3 possible cases: parameters can be absolute path, relative path or only the name -// -// parameters: -// fullName : where to store the path/name -// -// return: -// true, if done - -boolean FtpServer::makePath (char * fullName) { - return makePath (fullName, parameters); -} - -boolean FtpServer::makePath (char * fullName, char * param) { - if (param == NULL) { - param = parameters; - } - // Root or empty? - if (strcmp (param, "/") == 0 || strlen (param) == 0) { - strcpy (fullName, "/"); - return true; - } - // If relative path, concatenate with current dir - if (param[0] != '/' ) { - strcpy (fullName, cwdName); - if (fullName[strlen (fullName) - 1] != '/') { - strncat (fullName, "/", FTP_CWD_SIZE); - } - strncat (fullName, param, FTP_CWD_SIZE); - } - else { - strcpy (fullName, param); - } - // If ends with '/', remove it - uint16_t strl = strlen (fullName) - 1; - if (fullName[strl] == '/' && strl > 1) { - fullName[strl] = 0; - } - if (strlen (fullName) < FTP_CWD_SIZE) { - return true; - } - client.println (F("500 Command line too long")); - return false; -} - -// Calculate year, month, day, hour, minute and second -// from first parameter sent by MDTM command (YYYYMMDDHHMMSS) -// -// parameters: -// pyear, pmonth, pday, phour, pminute and psecond: pointer of -// variables where to store data -// -// return: -// 0 if parameter is not YYYYMMDDHHMMSS -// length of parameter + space - -uint8_t FtpServer::getDateTime (uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, - uint8_t * phour, uint8_t * pminute, uint8_t * psecond) { - char dt[15]; - - // Date/time are expressed as a 14 digits long string - // terminated by a space and followed by name of file - if (strlen (parameters ) < 15 || parameters[14] != ' ') { - return 0; - } - for (uint8_t i = 0; i < 14; i ++) { - if (!isdigit (parameters[i])) { - return 0; - } - } - strncpy (dt, parameters, 14); - dt[14] = 0; - * psecond = atoi (dt + 12); - dt[12] = 0; - * pminute = atoi (dt + 10); - dt[10] = 0; - * phour = atoi (dt + 8); - dt[8] = 0; - * pday = atoi (dt + 6); - dt[6] = 0; - * pmonth = atoi (dt + 4); - dt[4] = 0; - * pyear = atoi (dt); - return 15; -} - -// Create string YYYYMMDDHHMMSS from date and time -// -// parameters: -// date, time -// tstr: where to store the string. Must be at least 15 characters long -// -// return: -// pointer to tstr - -char * FtpServer::makeDateTimeStr (char * tstr, uint16_t date, uint16_t time) { - sprintf (tstr, "%04u%02u%02u%02u%02u%02u", - ((date & 0xFE00) >> 9) + 1980, (date & 0x01E0) >> 5, date & 0x001F, - (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) << 1); - return tstr; -} - -bool FtpServer::haveParameter () { - if (parameters != NULL && strlen (parameters) > 0) { - return true; - } - client.println (F("501 No file name")); - return false; -} - -bool FtpServer::makeExistsPath (char * path, char * param) { - if (!makePath (path, param)) { - return false; - } - if (cfsp->exists (path)) { - return true; - } - client.println (F("550 ") + String (path) + F(" not found.")); - return false; -} - -String FtpServer::fillSpaces (uint8_t length, String input) { - String output; - output = ""; - while (output.length() < length - input.length()) { - output += " "; - } - output += input; - return (output); -} +/* + * FTP SERVER FOR ESP32/ESP8266 + * based on FTP Server for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200) + * based on Jean-Michel Gallego's work + * modified to work with esp8266 SPIFFS by David Paiva david@nailbuster.com + * 2017: modified by @robo8080 (ported to ESP32 and SD) + * 2019: modified by @fa1ke5 (use SD card in SD_MMC mode (No SD lib, SD_MMC lib), and added fully fuctional passive mode ftp server) + * 2020: modified by @jmwislez (support generic FS, and re-introduced ESP8266) + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +#include "ESPFtpServer.h" +#include + +#ifdef ESP32 +#undef F +#define F(A) A +#endif + +void FtpServer::begin (String uname, String pword, FS *ufp) { + + if (is_up) return; + + cfsp = ufp; + + // Tells the ftp server to begin listening for incoming connection + _FTP_USER = uname; + _FTP_PASS = pword; + + ftpServer = new WiFiServer(FTP_CTRL_PORT); + if (!ftpServer) return; + dataServer = new WiFiServer(FTP_DATA_PORT_PASV); + if (!dataServer) return; + + ftpServer->begin (); + delay (10); + dataServer->begin (); + delay (10); + millisTimeOut = (uint32_t)FTP_TIME_OUT * 60 * 1000; + millisDelay = 0; + cmdStatus = 0; + iniVariables (); + is_up = true; +} + +FtpServer::~FtpServer(void) { + ftpServer->close(); + ftpServer->stop(); + delete ftpServer; + dataServer->close(); + dataServer->stop(); + delete dataServer; +} + + +void FtpServer::iniVariables () { + // Default for data port + dataPort = FTP_DATA_PORT_PASV; + + // Default Data connection is Active + dataPassiveConn = false; + + // Set the root directory + strcpy (cwdName, "/"); + + rnfrCmd = false; + transferStatus = 0; +} + +void FtpServer::handleFTP () { + + if (!is_up) return; + + if ((int32_t) (millisDelay - millis ()) > 0) { + return; + } + + if (ftpServer->hasClient ()) { + #ifdef FTP_DEBUG + Serial.println (F("-> disconnecting client")); + #endif + client.stop (); + client = ftpServer->available (); + } + + if (cmdStatus == 0) { + if (client.connected ()) { + disconnectClient (); + } + cmdStatus = 1; + } + else if (cmdStatus == 1) { // Ftp server waiting for connection + abortTransfer (); + iniVariables (); + #ifdef FTP_DEBUG + Serial.println (F("-> ftp server waiting for connection on port ") + String (FTP_CTRL_PORT)); + #endif + cmdStatus = 2; + } + else if (cmdStatus == 2) { // Ftp server idle + if (client.connected ()) { // A client connected + clientConnected (); + millisEndConnection = millis () + 10 * 1000; // wait client id during 10 s. + cmdStatus = 3; + } + } + else if (readChar () > 0) { // got response + if (cmdStatus == 3) { // Ftp server waiting for user identity + if (userIdentity ()) { + cmdStatus = 4; + } + else { + cmdStatus = 0; + } + } + else if (cmdStatus == 4) { // Ftp server waiting for user registration + if (userPassword ()) { + cmdStatus = 5; + millisEndConnection = millis () + millisTimeOut; + } + else { + cmdStatus = 0; + } + } + else if (cmdStatus == 5) { // Ftp server waiting for user command + if (!processCommand ()) { + cmdStatus = 0; + } + else { + millisEndConnection = millis () + millisTimeOut; + } + } + } + else if (!client.connected () || !client) { + cmdStatus = 1; + #ifdef FTP_DEBUG + Serial.println (F("-> client disconnected")); + #endif + } + + if (transferStatus == 1) { // Retrieve data + if (!doRetrieve ()) { + transferStatus = 0; + } + } + else if (transferStatus == 2) { // Store data + if (!doStore ()) { + transferStatus = 0; + } + } + else if (cmdStatus > 2 && ! ((int32_t) (millisEndConnection - millis ()) > 0 )) { + client.println (F("530 Timeout")); + millisDelay = millis () + 200; // delay of 200 ms + cmdStatus = 0; + } +} + +void FtpServer::clientConnected () { + #ifdef FTP_DEBUG + Serial.println (F("-> client connected")); + #endif + client.println (F("220-Welcome to FTP for ESP8266/ESP32")); + client.println (F("220-By David Paiva")); + client.println (F("220-Version ") + String (FTP_SERVER_VERSION)); + client.println (F("220 Put your ftp client in passive mode, and do not attempt more than one connection")); + iCL = 0; +} + +void FtpServer::disconnectClient () { + #ifdef FTP_DEBUG + Serial.println (F("-> disconnecting client")); + #endif + abortTransfer (); + client.println (F("221 Goodbye")); + client.stop (); +} + +boolean FtpServer::userIdentity () { + if (strcmp (command, "USER")) { + client.println (F("500 Syntax error")); + } + if (strcmp (parameters, _FTP_USER.c_str ())) { + client.println (F("530 user not found")); + } + else { + client.println (F("331 OK. Password required")); + strcpy (cwdName, "/"); + return true; + } + millisDelay = millis () + 100; // delay of 100 ms + return false; +} + +boolean FtpServer::userPassword () { + if (strcmp (command, "PASS")) { + client.println (F("500 Syntax error")); + } + else if (strcmp (parameters, _FTP_PASS.c_str ())) { + client.println (F("530 ")); + } + else { + #ifdef FTP_DEBUG + Serial.println (F("-> user authenticated")); + #endif + client.println (F("230 OK.")); + return true; + } + millisDelay = millis () + 100; // delay of 100 ms + return false; +} + +boolean FtpServer::processCommand () { + struct tm * ptm; + time_t ftime; + char buffer[80]; + + /////////////////////////////////////// + // // + // ACCESS CONTROL COMMANDS // + // // + /////////////////////////////////////// + + // + // CDUP - Change to Parent Directory + // + if (!strcmp (command, "CDUP") || (!strcmp (command, "CWD") && !strcmp (parameters, ".."))) { + bool ok = false; + if (strlen (cwdName) > 1) { // do nothing if cwdName is root + // if cwdName ends with '/', remove it (must not append) + if (cwdName[strlen (cwdName) - 1] == '/') { + cwdName[ strlen (cwdName ) - 1 ] = 0; + } + // search last '/' + char * pSep = strrchr (cwdName, '/'); + ok = pSep > cwdName; + // if found, ends the string on its position + if (ok) { + * pSep = 0; + ok = cfsp->exists (cwdName); + } + } + // if an error appends, move to root + if (!ok) { + strcpy (cwdName, "/"); + } + client.println (F("250 Ok. Current directory is ") + String (cwdName)); + } + + // + // CWD - Change Working Directory + // + else if (!strcmp (command, "CWD")) { + char path[FTP_CWD_SIZE]; + if (haveParameter () && makeExistsPath (path)) { + strcpy (cwdName, path); + client.println (F("250 Ok. Current directory is ") + String (cwdName)); + } + } + + // + // PWD - Print Directory + // + else if (!strcmp (command, "PWD")) { + client.println (F("257 \"") + String (cwdName) + F("\" is your current directory")); + } + + // + // QUIT + // + else if (!strcmp (command, "QUIT")) { + disconnectClient (); + return false; + } + + /////////////////////////////////////// + // // + // TRANSFER PARAMETER COMMANDS // + // // + /////////////////////////////////////// + + // + // MODE - Transfer Mode + // + else if (!strcmp (command, "MODE")) { + if (!strcmp (parameters, "S")) { + client.println (F("200 S Ok")); + } + else { + client.println (F("504 Only S (tream) is supported")); + } + } + + // + // PASV - Passive Connection management + // + else if (!strcmp (command, "PASV")) { + if (data.connected ()) { + data.stop (); + #ifdef FTP_DEBUG + Serial.println (F("-> client disconnected from dataserver")); + #endif + } + dataIp = WiFi.localIP (); + dataPort = FTP_DATA_PORT_PASV; + #ifdef FTP_DEBUG + Serial.println (F("-> connection management set to passive")); + Serial.println (F("-> data port set to ") + String (dataPort)); + #endif + client.println (F("227 Entering Passive Mode (") + String (dataIp[0]) + "," + String (dataIp[1]) + "," + String (dataIp[2]) + "," + String (dataIp[3]) + "," + String (dataPort >> 8) + "," + String (dataPort & 255) + ")."); + dataPassiveConn = true; + } + + // + // PORT - Data Port + // + else if (!strcmp (command, "PORT")) { + if (data) { + data.stop (); + #ifdef FTP_DEBUG + Serial.println (F("-> client disconnected from dataserver")); + #endif + } + // get IP of data client + dataIp[0] = atoi (parameters); + char * p = strchr (parameters, ','); + for (uint8_t i = 1; i < 4; i ++) { + dataIp[i] = atoi (++ p); + p = strchr (p, ','); + } + // get port of data client + dataPort = 256 * atoi (++ p); + p = strchr (p, ','); + dataPort += atoi (++ p); + if (p == NULL) { + client.println (F("501 Can't interpret parameters")); + } + else { + client.println (F("200 PORT command successful")); + dataPassiveConn = false; + } + } + + // + // STRU - File Structure + // + else if (!strcmp (command, "STRU")) { + if (!strcmp (parameters, "F")) { + client.println (F("200 F Ok")); + } + else { + client.println (F("504 Only F (ile) is supported")); + } + } + + // + // TYPE - Data Type + // + else if (!strcmp (command, "TYPE")) { + if (!strcmp (parameters, "A")) { + client.println (F("200 TYPE is now ASCII")); + } + else if (!strcmp (parameters, "I" )) { + client.println (F("200 TYPE is now 8-bit binary")); + } + else { + client.println (F("504 Unknown TYPE")); + } + } + + /////////////////////////////////////// + // // + // FTP SERVICE COMMANDS // + // // + /////////////////////////////////////// + + // + // ABOR - Abort + // + else if (!strcmp (command, "ABOR")) { + abortTransfer (); + client.println (F("226 Data connection closed")); + } + + // + // DELE - Delete a File + // + else if (!strcmp (command, "DELE")) { + char path[FTP_CWD_SIZE]; + if (strlen (parameters) == 0) { + client.println (F("501 No file name")); + } + else if (makePath (path)) { + if (!cfsp->exists (path)) { + client.println (F("550 File ") + String (parameters) + F(" not found")); + } + else { + if (cfsp->remove (path)) { + client.println (F("250 Deleted ") + String (parameters)); + // silently recreate the directory if it vanished with the last file it contained + String directory = String (path).substring (0, String(path).lastIndexOf ("/")); + if (!cfsp->exists (directory.c_str())) { + cfsp->mkdir (directory.c_str()); + } + } + else { + client.println (F("450 Can't delete ") + String (parameters)); + } + } + } + } + + // + // LIST - List + // + else if (!strcmp (command, "LIST")) { + if (dataConnect ()) { + client.println (F("150 Accepted data connection")); + uint16_t nm = 0; + + #ifdef ESP8266 + Dir dir = cfsp->openDir (cwdName); + while (dir.next ()) { + String fname, fsize; + fname = dir.fileName (); + time_t ftime = dir.fileTime (); + ptm = gmtime (&ftime); + int pos = fname.lastIndexOf ("/"); //looking for the beginning of the file by the last "/" + fname.remove (0, pos + 1); //Delete everything up to and including the filename + fsize = String (dir.fileSize ()); + if (dir.isDirectory ()){ + sprintf (buffer, "%04d-%02d-%02d %02d:%02d %s", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, fname.c_str()); + } + else { + sprintf (buffer, "%04d-%02d-%02d %02d:%02d %s %s", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, fillSpaces (14, String (fsize)).c_str(), fname.c_str()); + } + data.println (buffer); + nm ++; + } + client.println( "226 " + String (nm) + " matches total"); + #endif + #ifdef ESP32 + File dir = cfsp->open (cwdName); + if ((!dir) || (!dir.isDirectory ())) { + client.println (F("550 Can't open directory ") + String (cwdName)); + } + else { + File file = dir.openNextFile (); + while (file) { + String fname, fsize; + fname = file.name (); + ftime = file.getLastWrite (); + ptm = gmtime (&ftime); + int pos = fname.lastIndexOf ("/"); //looking for the beginning of the file by the last "/" + fname.remove (0, pos + 1); //Delete everything up to and including the filename + #ifdef FTP_DEBUG + Serial.println ("-> " + fname); + #endif + fsize = String (file.size ()); + if (file.isDirectory ()){ + sprintf (buffer, "%04u-%02u-%02u %02u:%02u %s", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, fname.c_str()); + } + else { + sprintf (buffer, "%04u-%02u-%02u %02d:%02u %s %s", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, fillSpaces (14, String (fsize)).c_str(), fname.c_str()); + } + data.println (buffer); + nm ++; + file = dir.openNextFile (); + } + client.println ("226 " + String (nm) + F(" matches total")); + } + #endif + data.stop (); + #ifdef FTP_DEBUG + Serial.println (F("-> client disconnected from dataserver")); + #endif + } + else { + client.println (F("425 No data connection")); + data.stop (); + } + } + + // + // MLSD - Listing for Machine Processing (see RFC 3659) + // + else if (!strcmp (command, "MLSD")) { + if (!dataConnect ()) { + client.println (F("425 No data connection MLSD")); + } + else { + client.println (F("150 Accepted data connection")); + uint16_t nm = 0; + #ifdef ESP8266 + Dir dir = cfsp->openDir (cwdName); + char dtStr[15]; + while (dir.next ()) { + String fn, fs; + fn = dir.fileName (); + int pos = fn.lastIndexOf ("/"); //looking for the beginning of the file by the last "/" + fn.remove (0, pos + 1); //Delete everything up to and including the filename + fs = String (dir.fileSize ()); + ftime = dir.fileTime (); + ptm = gmtime (&ftime); + if (dir.isDirectory ()) { + sprintf (buffer, "Type=dir;Modify=%04u%02u%02u%02u%02u%02u; %s", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, fn.c_str()); + } + else { + sprintf (buffer, "Type=file;Size=%s;Modify=%04u%02u%02u%02u%02u%02u; %s", fs.c_str(), ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, fn.c_str()); + } + data.println (buffer); + nm ++; + } + client.println (F("226-options: -a -l")); + client.println("226 " + String(nm) + F(" matches total")); + #endif + #ifdef ESP32 + File dir = cfsp->open (cwdName); + char dtStr[15]; + if (!cfsp->exists (cwdName)) { + client.println (F("550 Can't open directory ") + String (parameters)); + } + else { + File file = dir.openNextFile (); + while (file) { + String fn, fs; + fn = file.name (); + int pos = fn.lastIndexOf ("/"); // looking for the beginning of the file by the last "/" + fn.remove (0, pos + 1); // delete everything up to and including the filename + fs = String (file.size ()); + ftime = file.getLastWrite (); + ptm = gmtime (&ftime); + if (file.isDirectory ()) { + sprintf (buffer, "Type=dir;Modify=%04u%02u%02u%02u%02u%02u; %s", ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, fn.c_str()); + } + else { + sprintf (buffer, "Type=file;Size=%s;Modify=%04u%02u%02u%02u%02u%02u; %s", fs.c_str(), ptm->tm_year + 1900, ptm->tm_mon + 1, ptm->tm_mday, ptm->tm_hour, ptm->tm_min, ptm->tm_sec, fn.c_str()); + } + data.println (buffer); + nm ++; + file = dir.openNextFile (); + } + client.println (F("226-options: -a -l")); + client.println ("226 " + String (nm) + F(" matches total")); + } + #endif + data.stop (); + #ifdef FTP_DEBUG + Serial.println (F("-> client disconnected from dataserver")); + #endif + } + } + + // + // NLST - Name List + // + else if (!strcmp (command, "NLST" )) { + if (!dataConnect ()) { + client.println (F("425 No data connection")); + } + else { + client.println (F("150 Accepted data connection")); + uint16_t nm = 0; + #ifdef ESP8266 + Dir dir = cfsp->openDir (cwdName); + if (!cfsp->exists (cwdName)) { + client.println (F("550 Can't open directory ") + String (parameters)); + } + else { + while (dir.next ()) { + data.println (dir.fileName ()); + nm ++; + } + client.println ("226 " + String(nm) + F(" matches total")); + } + #endif + #ifdef ESP32 + File dir = cfsp->open (cwdName); + if (!cfsp->exists (cwdName)) { + client.println (F("550 Can't open directory ") + String (parameters)); + } + else { + File file = dir.openNextFile (); + while (file) { + data.println (file.name ()); + nm ++; + file = dir.openNextFile (); + } + client.println ("226 " + String (nm) + F(" matches total")); + } + #endif + data.stop (); + #ifdef FTP_DEBUG + Serial.println (F("-> client disconnected from dataserver")); + #endif + } + } + + // + // NOOP + // + else if (!strcmp (command, "NOOP")) { + client.println (F("200 Zzz...")); + } + + // + // RETR - Retrieve + // + else if (!strcmp (command, "RETR")) { + char path[FTP_CWD_SIZE]; + if (strlen (parameters) == 0) { + client.println (F("501 No file name")); + } + else if (makePath (path)) { + file = cfsp->open (path, "r"); + if (!file) { + client.println (F("550 File ") + String (parameters) + F(" not found")); + } + else if (!file) { + client.println (F("450 Can't open ") + String (parameters)); + } + else if (!dataConnect ()) { + client.println (F("425 No data connection")); + } + else { + #ifdef FTP_DEBUG + Serial.println (F("-> sending ") + String (parameters)); + #endif + client.println (F("150-Connected to port ") + String (dataPort)); + client.println (F("150 ") + String (file.size ()) + F(" bytes to download")); + millisBeginTrans = millis (); + bytesTransferred = 0; + transferStatus = 1; + } + } + } + + // + // STOR - Store + // + else if (!strcmp (command, "STOR")) { + char path[FTP_CWD_SIZE]; + if (strlen (parameters) == 0) { + client.println (F("501 No file name")); + } + else if (makePath (path)) { + file = cfsp->open (path, "w"); + if (!file) { + client.println (F("451 Can't open/create ") + String (parameters)); + } + else if (!dataConnect ()) { + client.println (F("425 No data connection")); + file.close (); + } + else { + #ifdef FTP_DEBUG + Serial.println (F("-> receiving ") + String (parameters)); + #endif + client.println (F("150 Connected to port ") + String (dataPort)); + millisBeginTrans = millis (); + bytesTransferred = 0; + transferStatus = 2; + } + } + } + + // + // MKD - Make Directory + // + + else if (!strcmp (command, "MKD")) { + char path[FTP_CWD_SIZE]; + if (haveParameter () && makePath (path)) { + if (cfsp->exists (path)) { + client.println (F("521 Can't create \"") + String (parameters) + F("\", Directory exists")); + } + else { + if (cfsp->mkdir (path)) { + client.println (F("257 \"") + String (parameters) + F("\" created")); + } + else { + client.println (F("550 Can't create \"") + String (parameters) + "\""); + } + } + } + } + + // + // RMD - Remove a Directory + // + else if (!strcmp (command, "RMD")) { + char path[FTP_CWD_SIZE]; + if (haveParameter () && makePath (path)) { + if (cfsp->rmdir (path)) { + #ifdef FTP_DEBUG + Serial.println (F("-> deleting ") + String (parameters)); + #endif + client.println ("250 \"" + String (parameters) + F("\" deleted")); + } + else { + if (cfsp->exists (path)) { // hack + client.println (F("550 Can't remove \"") + String (parameters) + F("\". Directory not empty?")); + } + else { + #ifdef FTP_DEBUG + Serial.println (F("-> deleting ") + String (parameters)); + #endif + client.println ("250 \"" + String (parameters) + F("\" deleted")); + } + } + } + } + + // + // RNFR - Rename From + // + else if (!strcmp (command, "RNFR")) { + buf[0] = 0; + if (strlen (parameters) == 0) { + client.println (F("501 No file name")); + } + else if (makePath (buf)) { + if (!cfsp->exists (buf)) { + client.println (F("550 File ") + String (parameters) + F(" not found")); + } + else { + #ifdef FTP_DEBUG + Serial.println (F("-> renaming ") + String (buf)); + #endif + client.println (F("350 RNFR accepted - file exists, ready for destination")); + rnfrCmd = true; + } + } + } + + // + // RNTO - Rename To + // + else if (!strcmp (command, "RNTO")) { + char path[FTP_CWD_SIZE]; + char dir[FTP_FIL_SIZE]; + if (strlen (buf ) == 0 || ! rnfrCmd) { + client.println (F("503 Need RNFR before RNTO")); + } + else if (strlen (parameters ) == 0) { + client.println (F("501 No file name")); + } + else if (makePath (path)) { + if (cfsp->exists (path)) { + client.println (F("553 ") + String (parameters) + F(" already exists")); + } + else { + #ifdef FTP_DEBUG + Serial.println (F("-> renaming ") + String (buf) + " to " + String (path)); + #endif + if (cfsp->rename (buf, path)) { + client.println (F("250 File successfully renamed or moved")); + } + else { + client.println (F("451 Rename/move failure")); + } + } + } + rnfrCmd = false; + } + + /////////////////////////////////////// + // // + // EXTENSIONS COMMANDS (RFC 3659) // + // // + /////////////////////////////////////// + + // + // FEAT - New Features + // + else if (!strcmp (command, "FEAT")) { + client.println (F("211-Extensions supported:")); + client.println (F(" MLSD")); + client.println (F("211 End.")); + } + + // + // MDTM - File Modification Time (see RFC 3659) + // + else if (!strcmp (command, "MDTM")) { + client.println (F("550 Unable to retrieve time")); + } + + // + // SIZE - Size of the file + // + else if (!strcmp (command, "SIZE")) { + char path[FTP_CWD_SIZE]; + if (strlen (parameters) == 0) { + client.println (F("501 No file name")); + } + else if (makePath (path)) { + file = cfsp->open (path, "r"); + if (!file) { + client.println (F("450 Can't open ") + String (parameters)); + } + else { + client.println (F("213 ") + String (file.size ())); + file.close (); + } + } + } + + // + // SITE - System command + // + else if (!strcmp (command, "SITE")) { + client.println (F("500 Unknown SITE command ") + String (parameters)); + } + + // + // Unrecognized commands ... + // + else { + client.println (F("500 Unknown command")); + } + return true; +} + +boolean FtpServer::dataConnect () { + unsigned long startTime = millis (); + //wait 5 seconds for a data connection + if (!data.connected ()) { + while (!dataServer->hasClient () && millis () - startTime < 10000) { + yield (); + } + if (dataServer->hasClient ()) { + data.stop (); + #ifdef FTP_DEBUG + Serial.println (F("-> client disconnected from dataserver")); + #endif + data = dataServer->available (); + #ifdef FTP_DEBUG + Serial.println (F("-> client connected to dataserver")); + #endif + } + } + return data.connected (); +} + +boolean FtpServer::doRetrieve () { + if (data.connected ()) { + int16_t nb = file.readBytes (buf, FTP_BUF_SIZE); + if (nb > 0) { + data.write ((uint8_t*)buf, nb); + bytesTransferred += nb; + return true; + } + } + closeTransfer (); + return false; +} + +boolean FtpServer::doStore () { + // Avoid blocking by never reading more bytes than are available + int navail = data.available(); + if (navail > 0) { + // And be sure not to overflow the buffer + if (navail > FTP_BUF_SIZE) { + navail = FTP_BUF_SIZE; + } + int16_t nb = data.read((uint8_t *)buf, navail); + if (nb > 0) { + file.write((uint8_t *)buf, nb); + bytesTransferred += nb; + } + } + if (!data.connected() && (navail <= 0)) { + closeTransfer(); + return false; + } + else { + return true; + } +} + +void FtpServer::closeTransfer () { + uint32_t deltaT = (int32_t) (millis () - millisBeginTrans); + if (deltaT > 0 && bytesTransferred > 0) { + client.println (F("226-File successfully transferred")); + client.println ("226 " + String (deltaT) + " ms, " + String (bytesTransferred / deltaT) + " kbytes/s"); + } + else { + client.println (F("226 File successfully transferred")); + } + file.close (); + data.stop (); + #ifdef FTP_DEBUG + Serial.println (F("-> file successfully transferred")); + Serial.println (F("-> client disconnected from dataserver")); + #endif +} + +void FtpServer::abortTransfer () { + if (transferStatus > 0) { + file.close (); + data.stop (); + #ifdef FTP_DEBUG + Serial.println (F("-> client disconnected from dataserver")); + #endif + client.println (F("426 Transfer aborted")); + #ifdef FTP_DEBUG + Serial.println (F("-> transfer aborted")); + #endif + } + transferStatus = 0; +} + +// Read a char from client connected to ftp server +// +// update cmdLine and command buffers, iCL and parameters pointers +// +// return: +// -2 if buffer cmdLine is full +// -1 if line not completed +// 0 if empty line received +// length of cmdLine (positive) if no empty line received + +int8_t FtpServer::readChar () { + int8_t rc = -1; + + if (client.available ()) { + char c = client.read (); + #ifdef FTP_DEBUG + Serial.print (c); + #endif + if (c == '\\') { + c = '/'; + } + if (c != '\r' ) { + if (c != '\n' ) { + if (iCL < FTP_CMD_SIZE) { + cmdLine[iCL ++] = c; + } + else { + rc = -2; // Line too long + } + } + else { + cmdLine[iCL] = 0; + command[0] = 0; + parameters = NULL; + // empty line? + if (iCL == 0) { + rc = 0; + } + else { + rc = iCL; + // search for space between command and parameters + parameters = strchr (cmdLine, ' '); + if (parameters != NULL) { + if (parameters - cmdLine > 4) { + rc = -2; // Syntax error + } + else { + strncpy (command, cmdLine, parameters - cmdLine); + command[parameters - cmdLine] = 0; + + while (* (++ parameters) == ' ') { + ; + } + } + } + else if (strlen (cmdLine) > 4) { + rc = -2; // Syntax error. + } + else { + strcpy (command, cmdLine); + } + iCL = 0; + } + } + } + if (rc > 0) { + for (uint8_t i = 0; i < strlen (command); i ++) { + command[i] = toupper (command[i]); + } + } + if (rc == -2) { + iCL = 0; + client.println (F("500 Syntax error")); + } + } + return rc; +} + +// Make complete path/name from cwdName and parameters +// +// 3 possible cases: parameters can be absolute path, relative path or only the name +// +// parameters: +// fullName : where to store the path/name +// +// return: +// true, if done + +boolean FtpServer::makePath (char * fullName) { + return makePath (fullName, parameters); +} + +boolean FtpServer::makePath (char * fullName, char * param) { + if (param == NULL) { + param = parameters; + } + // Root or empty? + if (strcmp (param, "/") == 0 || strlen (param) == 0) { + strcpy (fullName, "/"); + return true; + } + // If relative path, concatenate with current dir + if (param[0] != '/' ) { + strcpy (fullName, cwdName); + if (fullName[strlen (fullName) - 1] != '/') { + strncat (fullName, "/", FTP_CWD_SIZE); + } + strncat (fullName, param, FTP_CWD_SIZE); + } + else { + strcpy (fullName, param); + } + // If ends with '/', remove it + uint16_t strl = strlen (fullName) - 1; + if (fullName[strl] == '/' && strl > 1) { + fullName[strl] = 0; + } + if (strlen (fullName) < FTP_CWD_SIZE) { + return true; + } + client.println (F("500 Command line too long")); + return false; +} + +// Calculate year, month, day, hour, minute and second +// from first parameter sent by MDTM command (YYYYMMDDHHMMSS) +// +// parameters: +// pyear, pmonth, pday, phour, pminute and psecond: pointer of +// variables where to store data +// +// return: +// 0 if parameter is not YYYYMMDDHHMMSS +// length of parameter + space + +uint8_t FtpServer::getDateTime (uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, + uint8_t * phour, uint8_t * pminute, uint8_t * psecond) { + char dt[15]; + + // Date/time are expressed as a 14 digits long string + // terminated by a space and followed by name of file + if (strlen (parameters ) < 15 || parameters[14] != ' ') { + return 0; + } + for (uint8_t i = 0; i < 14; i ++) { + if (!isdigit (parameters[i])) { + return 0; + } + } + strncpy (dt, parameters, 14); + dt[14] = 0; + * psecond = atoi (dt + 12); + dt[12] = 0; + * pminute = atoi (dt + 10); + dt[10] = 0; + * phour = atoi (dt + 8); + dt[8] = 0; + * pday = atoi (dt + 6); + dt[6] = 0; + * pmonth = atoi (dt + 4); + dt[4] = 0; + * pyear = atoi (dt); + return 15; +} + +// Create string YYYYMMDDHHMMSS from date and time +// +// parameters: +// date, time +// tstr: where to store the string. Must be at least 15 characters long +// +// return: +// pointer to tstr + +char * FtpServer::makeDateTimeStr (char * tstr, uint16_t date, uint16_t time) { + sprintf (tstr, "%04u%02u%02u%02u%02u%02u", + ((date & 0xFE00) >> 9) + 1980, (date & 0x01E0) >> 5, date & 0x001F, + (time & 0xF800) >> 11, (time & 0x07E0) >> 5, (time & 0x001F) << 1); + return tstr; +} + +bool FtpServer::haveParameter () { + if (parameters != NULL && strlen (parameters) > 0) { + return true; + } + client.println (F("501 No file name")); + return false; +} + +bool FtpServer::makeExistsPath (char * path, char * param) { + if (!makePath (path, param)) { + return false; + } + if (cfsp->exists (path)) { + return true; + } + client.println (F("550 ") + String (path) + F(" not found.")); + return false; +} + +String FtpServer::fillSpaces (uint8_t length, String input) { + String output; + output = ""; + while (output.length() < length - input.length()) { + output += " "; + } + output += input; + return (output); +} diff --git a/lib/lib_div/ESPFtpServer/ESPFtpServer.h b/lib/lib_div/ESPFtpServer/ESPFtpServer.h index 84f380658..954cc5709 100755 --- a/lib/lib_div/ESPFtpServer/ESPFtpServer.h +++ b/lib/lib_div/ESPFtpServer/ESPFtpServer.h @@ -1,125 +1,125 @@ -/* -* FTP SERVER FOR ESP8266/ESP32 - * based on FTP Server for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200) - * based on Jean-Michel Gallego's work - * modified to work with esp8266 SPIFFS by David Paiva (david@nailbuster.com) - * 2017: modified by @robo8080 (ported to ESP32 and SD) - * 2019: modified by @fa1ke5 (use SD card in SD_MMC mode (No SD lib, SD_MMC lib), and added fully fuctional passive mode ftp server) - * 2020: modified by @jmwislez (support generic FS, and re-introduced ESP8266) - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program 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 General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - - -/******************************************************************************* - ** ** - ** DEFINITIONS FOR FTP SERVER ** - ** ** - *******************************************************************************/ - -// Uncomment to print debugging info to console -//#define FTP_DEBUG - -#ifndef FTP_SERVERESP_H -#define FTP_SERVERESP_H - -#include -#include -#ifdef ESP32 - #include -#else - #include -#endif - -#define FTP_SERVER_VERSION "jmwislez/ESP32FtpServer 0.1.0" - -#define FTP_CTRL_PORT 21 // Command port on wich server is listening -#define FTP_DATA_PORT_PASV 50009 // Data port in passive mode - -#define FTP_TIME_OUT 5 // Disconnect client after 5 minutes of inactivity - -#ifdef ESP32 -#define FTP_CMD_SIZE 255 + 8 // max size of a command -#define FTP_CWD_SIZE 255 + 8 // max size of a directory name -#define FTP_FIL_SIZE 255 // max size of a file name -#define FTP_BUF_SIZE 4096 //512 // 700 KByte/s download in AP mode, direct connection. -#endif - -#ifdef ESP8266 -#define FTP_CMD_SIZE 128 // max size of a command -#define FTP_CWD_SIZE 128 // max size of a directory name -#define FTP_FIL_SIZE 64 // max size of a file name -#define FTP_BUF_SIZE 256 // 700 KByte/s download in AP mode, direct connection. -#endif - -class FtpServer { - public: - void begin(String uname, String pword, FS *ufp); - void handleFTP (void); - ~FtpServer(void); - bool is_up = false; - - private: - bool haveParameter (); - bool makeExistsPath (char * path, char * param = NULL); - void iniVariables (); - void clientConnected (); - void disconnectClient (); - boolean userIdentity (); - boolean userPassword (); - boolean processCommand (); - boolean dataConnect (); - boolean doRetrieve (); - boolean doStore (); - void closeTransfer (); - void abortTransfer (); - boolean makePath (char * fullname); - boolean makePath (char * fullName, char * param); - uint8_t getDateTime (uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, - uint8_t * phour, uint8_t * pminute, uint8_t * second); - char * makeDateTimeStr (char * tstr, uint16_t date, uint16_t time); - int8_t readChar (); - String fillSpaces (uint8_t len, String input_str); - - IPAddress dataIp; // IP address of client for data - WiFiClient client; - WiFiClient data; - - WiFiServer *ftpServer; - WiFiServer *dataServer; - - FS *cfsp; - - File file; - - boolean dataPassiveConn; - uint16_t dataPort; - char buf[FTP_BUF_SIZE]; // data buffer for transfers - char cmdLine[FTP_CMD_SIZE]; // where to store incoming char from client - char cwdName[FTP_CWD_SIZE]; // name of current directory - char command[5]; // command sent by client - boolean rnfrCmd; // previous command was RNFR - char * parameters; // point to begin of parameters sent by client - uint16_t iCL; // pointer to cmdLine next incoming char - int8_t cmdStatus, // status of ftp command connexion - transferStatus; // status of ftp data transfer - uint32_t millisTimeOut, // disconnect after 5 min of inactivity - millisDelay, - millisEndConnection, // - millisBeginTrans, // store time of beginning of a transaction - bytesTransferred; // - String _FTP_USER; - String _FTP_PASS; -}; - -#endif // FTP_SERVERESP_H +/* +* FTP SERVER FOR ESP8266/ESP32 + * based on FTP Server for Arduino Due and Ethernet shield (W5100) or WIZ820io (W5200) + * based on Jean-Michel Gallego's work + * modified to work with esp8266 SPIFFS by David Paiva (david@nailbuster.com) + * 2017: modified by @robo8080 (ported to ESP32 and SD) + * 2019: modified by @fa1ke5 (use SD card in SD_MMC mode (No SD lib, SD_MMC lib), and added fully fuctional passive mode ftp server) + * 2020: modified by @jmwislez (support generic FS, and re-introduced ESP8266) + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + + +/******************************************************************************* + ** ** + ** DEFINITIONS FOR FTP SERVER ** + ** ** + *******************************************************************************/ + +// Uncomment to print debugging info to console +//#define FTP_DEBUG + +#ifndef FTP_SERVERESP_H +#define FTP_SERVERESP_H + +#include +#include +#ifdef ESP32 + #include +#else + #include +#endif + +#define FTP_SERVER_VERSION "jmwislez/ESP32FtpServer 0.1.0" + +#define FTP_CTRL_PORT 21 // Command port on wich server is listening +#define FTP_DATA_PORT_PASV 50009 // Data port in passive mode + +#define FTP_TIME_OUT 5 // Disconnect client after 5 minutes of inactivity + +#ifdef ESP32 +#define FTP_CMD_SIZE 255 + 8 // max size of a command +#define FTP_CWD_SIZE 255 + 8 // max size of a directory name +#define FTP_FIL_SIZE 255 // max size of a file name +#define FTP_BUF_SIZE 4096 //512 // 700 KByte/s download in AP mode, direct connection. +#endif + +#ifdef ESP8266 +#define FTP_CMD_SIZE 128 // max size of a command +#define FTP_CWD_SIZE 128 // max size of a directory name +#define FTP_FIL_SIZE 64 // max size of a file name +#define FTP_BUF_SIZE 256 // 700 KByte/s download in AP mode, direct connection. +#endif + +class FtpServer { + public: + void begin(String uname, String pword, FS *ufp); + void handleFTP (void); + ~FtpServer(void); + bool is_up = false; + + private: + bool haveParameter (); + bool makeExistsPath (char * path, char * param = NULL); + void iniVariables (); + void clientConnected (); + void disconnectClient (); + boolean userIdentity (); + boolean userPassword (); + boolean processCommand (); + boolean dataConnect (); + boolean doRetrieve (); + boolean doStore (); + void closeTransfer (); + void abortTransfer (); + boolean makePath (char * fullname); + boolean makePath (char * fullName, char * param); + uint8_t getDateTime (uint16_t * pyear, uint8_t * pmonth, uint8_t * pday, + uint8_t * phour, uint8_t * pminute, uint8_t * second); + char * makeDateTimeStr (char * tstr, uint16_t date, uint16_t time); + int8_t readChar (); + String fillSpaces (uint8_t len, String input_str); + + IPAddress dataIp; // IP address of client for data + WiFiClient client; + WiFiClient data; + + WiFiServer *ftpServer; + WiFiServer *dataServer; + + FS *cfsp; + + File file; + + boolean dataPassiveConn; + uint16_t dataPort; + char buf[FTP_BUF_SIZE]; // data buffer for transfers + char cmdLine[FTP_CMD_SIZE]; // where to store incoming char from client + char cwdName[FTP_CWD_SIZE]; // name of current directory + char command[5]; // command sent by client + boolean rnfrCmd; // previous command was RNFR + char * parameters; // point to begin of parameters sent by client + uint16_t iCL; // pointer to cmdLine next incoming char + int8_t cmdStatus, // status of ftp command connexion + transferStatus; // status of ftp data transfer + uint32_t millisTimeOut, // disconnect after 5 min of inactivity + millisDelay, + millisEndConnection, // + millisBeginTrans, // store time of beginning of a transaction + bytesTransferred; // + String _FTP_USER; + String _FTP_PASS; +}; + +#endif // FTP_SERVERESP_H diff --git a/lib/lib_div/ESPFtpServer/examples/ESPFtpServer.ino b/lib/lib_div/ESPFtpServer/examples/ESPFtpServer.ino index 7fcd1a08c..7122fdea2 100644 --- a/lib/lib_div/ESPFtpServer/examples/ESPFtpServer.ino +++ b/lib/lib_div/ESPFtpServer/examples/ESPFtpServer.ino @@ -1,104 +1,104 @@ -// Uncomment the file system to use for FTP server - -#define FS_LITTLEFS -//#define FS_SPIFFS -//#define FS_SD_MMC - -#ifdef ESP32 -#include -#endif -#ifdef ESP8266 -#include -#endif -#include -#include -#include "ESPFtpServer.h" - -#if defined(FS_LITTLEFS) -#ifdef ESP32 -#include "LITTLEFS.h" -#define FS_ID LITTLEFS -#endif -#ifdef ESP8266 -#include "LittleFS.h" -#define FS_ID LittleFS -#endif -#define FS_NAME "LittleFS" -#elif defined(FS_SPIFFS) -#ifdef ESP32 -#include "SPIFFS.h" -#endif -#define FS_ID SPIFFS -#define FS_NAME "SPIFFS" -#elif defined(FS_SD_MMC) -#include "SD_MMC.h" -#define FS_ID SD_MMC -#define FS_NAME "SD_MMC" -#else -#define FS_ID SD -#define FS_NAME "UNDEF" -#endif - -const char* ssid = "*********************"; -const char* password = "*********************"; - -const char* ntpServer = "pool.ntp.org"; -const long gmtOffset_sec = 3600; -const int daylightOffset_sec = 3600; -struct tm timeinfo; - -FtpServer ftpSrv; //set #define FTP_DEBUG in ESP32FtpServer.h to see ftp verbose on serial - -#ifdef ESP8266 -bool getLocalTime (struct tm * info) { - time_t now; - - time(&now); - localtime_r (&now, info); - - if (info->tm_year > (2016 - 1900)) { - return true; - } - else { - return false; - } -} -#endif - -void setup (void) { - Serial.begin (115200); - - WiFi.begin (ssid, password); - Serial.println (""); - - // Wait for connection - while (WiFi.status () != WL_CONNECTED) { - delay (500); - Serial.print ("."); - } - Serial.println (""); - Serial.print ("Connected to "); - Serial.println (ssid); - Serial.print ("IP address: "); - Serial.println (WiFi.localIP ()); - - configTime (gmtOffset_sec, daylightOffset_sec, ntpServer); - while (!getLocalTime (&timeinfo)) { - delay (500); - Serial.print ("."); - } - Serial.printf ("\nNow is : %d-%02d-%02d %02d:%02d:%02d\n", (timeinfo.tm_year) + 1900, (timeinfo.tm_mon) + 1, timeinfo.tm_mday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec); - - //FS_ID.format (); - if (FS_ID.begin ()) { - Serial.println ("File system opened (" + String (FS_NAME) + ")"); - ftpSrv.begin ("esp32", "esp32"); //username, password for ftp. set ports in ESPFtpServer.h (default 21, 50009 for PASV) - } - else { - Serial.println ("File system could not be opened; ftp server will not work"); - } -} - -void loop (void){ - ftpSrv.handleFTP (FS_ID); //make sure in loop you call handleFTP()! -} +// Uncomment the file system to use for FTP server + +#define FS_LITTLEFS +//#define FS_SPIFFS +//#define FS_SD_MMC + +#ifdef ESP32 +#include +#endif +#ifdef ESP8266 +#include +#endif +#include +#include +#include "ESPFtpServer.h" + +#if defined(FS_LITTLEFS) +#ifdef ESP32 +#include "LITTLEFS.h" +#define FS_ID LITTLEFS +#endif +#ifdef ESP8266 +#include "LittleFS.h" +#define FS_ID LittleFS +#endif +#define FS_NAME "LittleFS" +#elif defined(FS_SPIFFS) +#ifdef ESP32 +#include "SPIFFS.h" +#endif +#define FS_ID SPIFFS +#define FS_NAME "SPIFFS" +#elif defined(FS_SD_MMC) +#include "SD_MMC.h" +#define FS_ID SD_MMC +#define FS_NAME "SD_MMC" +#else +#define FS_ID SD +#define FS_NAME "UNDEF" +#endif + +const char* ssid = "*********************"; +const char* password = "*********************"; + +const char* ntpServer = "pool.ntp.org"; +const long gmtOffset_sec = 3600; +const int daylightOffset_sec = 3600; +struct tm timeinfo; + +FtpServer ftpSrv; //set #define FTP_DEBUG in ESP32FtpServer.h to see ftp verbose on serial + +#ifdef ESP8266 +bool getLocalTime (struct tm * info) { + time_t now; + + time(&now); + localtime_r (&now, info); + + if (info->tm_year > (2016 - 1900)) { + return true; + } + else { + return false; + } +} +#endif + +void setup (void) { + Serial.begin (115200); + + WiFi.begin (ssid, password); + Serial.println (""); + + // Wait for connection + while (WiFi.status () != WL_CONNECTED) { + delay (500); + Serial.print ("."); + } + Serial.println (""); + Serial.print ("Connected to "); + Serial.println (ssid); + Serial.print ("IP address: "); + Serial.println (WiFi.localIP ()); + + configTime (gmtOffset_sec, daylightOffset_sec, ntpServer); + while (!getLocalTime (&timeinfo)) { + delay (500); + Serial.print ("."); + } + Serial.printf ("\nNow is : %d-%02d-%02d %02d:%02d:%02d\n", (timeinfo.tm_year) + 1900, (timeinfo.tm_mon) + 1, timeinfo.tm_mday, timeinfo.tm_hour, timeinfo.tm_min, timeinfo.tm_sec); + + //FS_ID.format (); + if (FS_ID.begin ()) { + Serial.println ("File system opened (" + String (FS_NAME) + ")"); + ftpSrv.begin ("esp32", "esp32"); //username, password for ftp. set ports in ESPFtpServer.h (default 21, 50009 for PASV) + } + else { + Serial.println ("File system could not be opened; ftp server will not work"); + } +} + +void loop (void){ + ftpSrv.handleFTP (FS_ID); //make sure in loop you call handleFTP()! +} diff --git a/lib/lib_div/ams/library.properties b/lib/lib_div/ams/library.properties index 472c784f0..c3e7de8cd 100755 --- a/lib/lib_div/ams/library.properties +++ b/lib/lib_div/ams/library.properties @@ -1,17 +1,17 @@ -name=AMS Parser - -version=1.2.0 - -author=Gunnar Skjold - -maintainer=https://github.com/gskjold - -sentence=Meter parsing Library for Espressif ESP32 and ESP8266 devices. - -paragraph=This library allows the ESP32 and ESP8266 devices to parse several meter protocolls - -category=Communication - -url=https://github.com/UtilitechAS/amsreader-firmware - -architectures=esp32,esp8266 +name=AMS Parser + +version=1.2.0 + +author=Gunnar Skjold + +maintainer=https://github.com/gskjold + +sentence=Meter parsing Library for Espressif ESP32 and ESP8266 devices. + +paragraph=This library allows the ESP32 and ESP8266 devices to parse several meter protocolls + +category=Communication + +url=https://github.com/UtilitechAS/amsreader-firmware + +architectures=esp32,esp8266 diff --git a/lib/lib_i2c/MPU_accel/library.properties b/lib/lib_i2c/MPU_accel/library.properties index 583ca0e8f..702ff29f8 100644 --- a/lib/lib_i2c/MPU_accel/library.properties +++ b/lib/lib_i2c/MPU_accel/library.properties @@ -1,9 +1,9 @@ -name=MPU_accel -version= -author=M5StickC -maintainer=Stephan Hadinger -sentence=Support for MPU6886, MPU9250 -paragraph=Support for MPU6886, MPU9250 -category= -url=https://github.com/m5stack/M5StickC/blob/master/src/utility/ -architectures=* +name=MPU_accel +version= +author=M5StickC +maintainer=Stephan Hadinger +sentence=Support for MPU6886, MPU9250 +paragraph=Support for MPU6886, MPU9250 +category= +url=https://github.com/m5stack/M5StickC/blob/master/src/utility/ +architectures=* diff --git a/lib/lib_i2c/ScioSense_ENS16x/library.properties b/lib/lib_i2c/ScioSense_ENS16x/library.properties index f85dc659e..1e9058b94 100644 --- a/lib/lib_i2c/ScioSense_ENS16x/library.properties +++ b/lib/lib_i2c/ScioSense_ENS16x/library.properties @@ -1,9 +1,9 @@ -name=ScioSense ENS16x -version=8.0.0 -author=Christoph Friese -maintainer=ScioSense -sentence=Arduino library for the ENS160 and ENS161 digital four channel MOX gas sensor with I2C interface from ScioSense -paragraph=This library controls the ENS160 and ENS161. The main feature of this library is performing a single shot measurement, retrieving the measurement data. -category=Device Control -url=https://github.com/sciosense/ens16x -architectures=* +name=ScioSense ENS16x +version=8.0.0 +author=Christoph Friese +maintainer=ScioSense +sentence=Arduino library for the ENS160 and ENS161 digital four channel MOX gas sensor with I2C interface from ScioSense +paragraph=This library controls the ENS160 and ENS161. The main feature of this library is performing a single shot measurement, retrieving the measurement data. +category=Device Control +url=https://github.com/sciosense/ens16x +architectures=* diff --git a/lib/lib_i2c/ScioSense_ENS16x/src/ScioSense_ENS16x.cpp b/lib/lib_i2c/ScioSense_ENS16x/src/ScioSense_ENS16x.cpp index 6f21190e2..414c83084 100644 --- a/lib/lib_i2c/ScioSense_ENS16x/src/ScioSense_ENS16x.cpp +++ b/lib/lib_i2c/ScioSense_ENS16x/src/ScioSense_ENS16x.cpp @@ -1,490 +1,490 @@ -/* - ScioSense_ENS16x.h - Library for the ENS160 & ENS161 sensor with I2C interface from ScioSense - 2023 Jul 03 v8 Christoph Friese Update to cover ENS160 and ENS161 - 2023 Mar 23 v7 Christoph Friese Bugfix measurement routine, prepare next release - 2021 Nov 25 v6 Martin Herold Custom mode timing fixed - 2021 July 29 v5 Christoph Friese Changed nomenclature to ScioSense as product shifted from ams - 2021 Feb 04 v4 Giuseppe de Pinto Custom mode fixed - 2020 Apr 06 v3 Christoph Friese Changed nomenclature to ScioSense as product shifted from ams - 2020 Feb 15 v2 Giuseppe Pasetti Corrected firmware flash option - 2019 May 05 v1 Christoph Friese Created - - based on application note "ENS160 Software Integration.pdf" rev 0.01 -*/ - -#include "ScioSense_ENS16x.h" -#include "math.h" - -ScioSense_ENS16x::ScioSense_ENS16x(uint8_t slaveaddr) { - this->_slaveaddr = slaveaddr; - - this->_ADDR = 0; - this->_nINT = 0; - this->_nCS = 0; -} - -#ifndef ENS16x_DISABLE_ENHANCED_FEATURES -ScioSense_ENS16x::ScioSense_ENS16x(uint8_t ADDR, uint8_t nCS, uint8_t nINT) { - this->_slaveaddr = ENS16x_I2CADDR_0; - - this->_ADDR = ADDR; - this->_nINT = nINT; - this->_nCS = nCS; -} - -ScioSense_ENS16x::ScioSense_ENS16x(uint8_t slaveaddr, uint8_t ADDR, uint8_t nCS, uint8_t nINT) { - this->_slaveaddr = slaveaddr; - - this->_ADDR = ADDR; - this->_nINT = nINT; - this->_nCS = nCS; -} - -// Function to redefine I2C pins -void ScioSense_ENS16x::setI2C(uint8_t sda, uint8_t scl) { - this->_sdaPin = sda; - this->_sclPin = scl; -} -#endif - -// Init I2C communication, resets ENS16x and checks its PART_ID. Returns false on I2C problems or wrong PART_ID. -bool ScioSense_ENS16x::begin(bool debug) -{ -#ifndef ENS16x_DISABLE_DEBUG - debugENS16x = debug; - - //Set pin levels - if (this->_ADDR > 0) { - pinMode(this->_ADDR, OUTPUT); - digitalWrite(this->_ADDR, LOW); - } - if (this->_nINT > 0) pinMode(this->_nINT, INPUT_PULLUP); - if (this->_nCS > 0) { - pinMode(this->_nCS, OUTPUT); - digitalWrite(this->_nCS, HIGH); - } -#endif - - //init I2C - _i2c_init(); -#ifndef ENS16x_DISABLE_DEBUG - if (debugENS16x) { - Serial.println("begin() - I2C init done"); - } -#endif - delay(ENS16x_BOOTING); // Wait to boot after reset - - this->_available = false; - this->_available = this->reset(); - - this->_available = this->checkPartID(); - - if (this->_available) { - this->_available = this->setMode(ENS16x_OPMODE_IDLE); - this->_available = this->clearCommand(); - this->_available = this->getFirmware(); - } -#ifndef ENS16x_DISABLE_DEBUG - if (debugENS16x) { - Serial.println("ENS16x in idle mode"); - } -#endif - return this->_available; -} - -// Sends a reset to the ENS16x. Returns false on I2C problems. -bool ScioSense_ENS16x::reset(void) -{ - uint8_t result = this->write8(_slaveaddr, ENS16x_REG_OPMODE, ENS16x_OPMODE_RESET); - -#ifndef ENS16x_DISABLE_DEBUG - if (debugENS16x) { - Serial.print("reset() result: "); - Serial.println(result == 0 ? "ok" : "nok"); - } -#endif - delay(ENS16x_BOOTING); // Wait to boot after reset - - return result == 0; -} - -// Reads the part ID and confirms valid sensor -bool ScioSense_ENS16x::checkPartID(void) { - uint8_t i2cbuf[2]; - uint16_t part_id; - bool result = false; - - this->read(_slaveaddr, ENS16x_REG_PART_ID, i2cbuf, 2); - part_id = i2cbuf[0] | ((uint16_t)i2cbuf[1] << 8); - -#ifndef ENS16x_DISABLE_DEBUG - if (debugENS16x) { - Serial.print("checkPartID() result: "); - if (part_id == ENS160_PARTID) Serial.println("ENS160 ok"); - else if (part_id == ENS161_PARTID) Serial.println("ENS161 ok"); - else Serial.println("nok"); - } -#endif - delay(ENS16x_BOOTING); // Wait to boot after reset - - if (part_id == ENS160_PARTID) { this->_revENS16x = 0; result = true; } - else if (part_id == ENS161_PARTID) { this->_revENS16x = 1; result = true; } - - return result; -} - -// Initialize idle mode and confirms -bool ScioSense_ENS16x::clearCommand(void) { - uint8_t status; - uint8_t result; - - result = this->write8(_slaveaddr, ENS16x_REG_COMMAND, ENS16x_COMMAND_NOP); - result = this->write8(_slaveaddr, ENS16x_REG_COMMAND, ENS16x_COMMAND_CLRGPR); -#ifndef ENS16x_DISABLE_DEBUG - if (debugENS16x) { - Serial.print("clearCommand() result: "); - Serial.println(result == 0 ? "ok" : "nok"); - } -#endif - delay(ENS16x_BOOTING); // Wait to boot after reset - - status = this->read8(_slaveaddr, ENS16x_REG_DATA_STATUS); -#ifndef ENS16x_DISABLE_DEBUG - if (debugENS16x) { - Serial.print("clearCommand() status: 0x"); - Serial.println(status, HEX); - } -#endif - delay(ENS16x_BOOTING); // Wait to boot after reset - - return result == 0; -} - -// Read firmware revisions -bool ScioSense_ENS16x::getFirmware() { - uint8_t i2cbuf[3]; - uint8_t result; - - this->clearCommand(); - - delay(ENS16x_BOOTING); // Wait to boot after reset - - result = this->write8(_slaveaddr, ENS16x_REG_COMMAND, ENS16x_COMMAND_GET_APPVER); - result = this->read(_slaveaddr, ENS16x_REG_GPR_READ_4, i2cbuf, 3); - - this->_fw_ver_major = i2cbuf[0]; - this->_fw_ver_minor = i2cbuf[1]; - this->_fw_ver_build = i2cbuf[2]; - - if (this->_fw_ver_major > 6) this->_revENS16x = 1; - else this->_revENS16x = 0; - -#ifndef ENS16x_DISABLE_DEBUG - if (debugENS16x) { - Serial.println(this->_fw_ver_major); - Serial.println(this->_fw_ver_minor); - Serial.println(this->_fw_ver_build); - Serial.print("getFirmware() result: "); - Serial.println(result == 0 ? "ok" : "nok"); - } -#endif - delay(ENS16x_BOOTING); // Wait to boot after reset - - return result == 0; -} - -// Set operation mode of sensor -bool ScioSense_ENS16x::setMode(uint8_t mode) { - uint8_t result; - - //LP only valid for rev>0 - if ((mode == ENS161_OPMODE_LP) and (_revENS16x == 0)) result = 1; - else result = this->write8(_slaveaddr, ENS16x_REG_OPMODE, mode); - -#ifndef ENS16x_DISABLE_DEBUG - //if (debugENS16x) { - Serial.print("setMode() activate result: "); - Serial.println(result == 0 ? "ok" : "nok"); - //} -#endif - delay(ENS16x_BOOTING); // Wait to boot after reset - - return result == 0; -} - -#ifndef ENS16x_DISABLE_ENHANCED_FEATURES -// Initialize definition of custom mode with steps -bool ScioSense_ENS16x::initCustomMode(uint16_t stepNum) { - uint8_t result; - - if (stepNum > 0) { - this->_stepCount = stepNum; - - result = this->setMode(ENS16x_OPMODE_IDLE); - result = this->clearCommand(); - - result = this->write8(_slaveaddr, ENS16x_REG_COMMAND, ENS16x_COMMAND_SETSEQ); - } else { - result = 1; - } - delay(ENS16x_BOOTING); // Wait to boot after reset - - return result == 0; -} -#endif - -#ifndef ENS16x_DISABLE_ENHANCED_FEATURES -// Add a step to custom measurement profile with definition of duration, enabled data acquisition and temperature for each hotplate -bool ScioSense_ENS16x::addCustomStep(uint16_t time, bool measureHP0, bool measureHP1, bool measureHP2, bool measureHP3, uint16_t tempHP0, uint16_t tempHP1, uint16_t tempHP2, uint16_t tempHP3) { - uint8_t seq_ack; - uint8_t temp; - -#ifndef ENS16x_DISABLE_DEBUG - if (debugENS16x) { - Serial.print("setCustomMode() write step "); - Serial.println(this->_stepCount); - } -#endif - delay(ENS16x_BOOTING); // Wait to boot after reset - - temp = (uint8_t)(((time / 24)-1) << 6); - if (measureHP0) temp = temp | 0x20; - if (measureHP1) temp = temp | 0x10; - if (measureHP2) temp = temp | 0x8; - if (measureHP3) temp = temp | 0x4; - this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_0, temp); - - temp = (uint8_t)(((time / 24)-1) >> 2); - this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_1, temp); - - this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_2, (uint8_t)(tempHP0/2)); - this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_3, (uint8_t)(tempHP1/2)); - this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_4, (uint8_t)(tempHP2/2)); - this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_5, (uint8_t)(tempHP3/2)); - - this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_6, (uint8_t)(this->_stepCount - 1)); - - if (this->_stepCount == 1) { - this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_7, 128); - } else { - this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_7, 0); - } - delay(ENS16x_BOOTING); - - seq_ack = this->read8(_slaveaddr, ENS16x_REG_GPR_READ_7); - delay(ENS16x_BOOTING); // Wait to boot after reset - - if ((ENS16x_SEQ_ACK_COMPLETE | this->_stepCount) != seq_ack) { - this->_stepCount = this->_stepCount - 1; - return 0; - } else { - return 1; - } - -} -#endif - -// Perform prediction measurement and stores result in internal variables -bool ScioSense_ENS16x::measure(bool waitForNew) { - uint8_t i2cbuf[8]; - uint8_t status; - bool newData = false; - - // Set default status for early bail out -#ifndef ENS16x_DISABLE_DEBUG - if (debugENS16x) Serial.println("Start measurement"); -#endif - - if (waitForNew) { - do { - delay(10); - status = this->read8(_slaveaddr, ENS16x_REG_DATA_STATUS); - -#ifndef ENS16x_DISABLE_DEBUG - if (debugENS16x) { - Serial.print("Status: "); - Serial.println(status); - } -#endif - } while (!IS_NEWDAT(status)); - } else { - status = this->read8(_slaveaddr, ENS16x_REG_DATA_STATUS); - } - - // Read predictions - if (IS_NEWDAT(status)) { - newData = true; - this->read(_slaveaddr, ENS16x_REG_DATA_AQI, i2cbuf, 7); - _data_aqi = i2cbuf[0]; - _data_tvoc = i2cbuf[1] | ((uint16_t)i2cbuf[2] << 8); - _data_eco2 = i2cbuf[3] | ((uint16_t)i2cbuf[4] << 8); - if (_revENS16x > 0) _data_aqis = ((uint16_t)i2cbuf[5]) | ((uint16_t)i2cbuf[6] << 8); - else _data_aqis = 0; - } - - return newData; -} - -#ifndef ENS16x_DISABLE_ENHANCED_FEATURES -// Perfrom raw measurement and stores result in internal variables -bool ScioSense_ENS16x::measureRaw(bool waitForNew) { - uint8_t i2cbuf[8]; - uint8_t status; - bool newData = false; - - // Set default status for early bail out -#ifndef ENS16x_DISABLE_DEBUG - if (debugENS16x) Serial.println("Start measurement"); -#endif - - if (waitForNew) { - do { - delay(10); - status = this->read8(_slaveaddr, ENS16x_REG_DATA_STATUS); - -#ifndef ENS16x_DISABLE_DEBUG - if (debugENS16x) { - Serial.print("Status: "); - Serial.println(status); - } -#endif - } while (!IS_NEWGPR(status)); - } else { - status = this->read8(_slaveaddr, ENS16x_REG_DATA_STATUS); - } - - if (IS_NEWGPR(status)) { - newData = true; - - // Read raw resistance values - this->read(_slaveaddr, ENS16x_REG_GPR_READ_0, i2cbuf, 8); - _hp0_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[0] | ((uint16_t)i2cbuf[1] << 8))); - _hp1_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[2] | ((uint16_t)i2cbuf[3] << 8))); - _hp2_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[4] | ((uint16_t)i2cbuf[5] << 8))); - _hp3_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[6] | ((uint16_t)i2cbuf[7] << 8))); - - // Read baselines - this->read(_slaveaddr, ENS16x_REG_DATA_BL, i2cbuf, 8); - _hp0_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[0] | ((uint16_t)i2cbuf[1] << 8))); - _hp1_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[2] | ((uint16_t)i2cbuf[3] << 8))); - _hp2_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[4] | ((uint16_t)i2cbuf[5] << 8))); - _hp3_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[6] | ((uint16_t)i2cbuf[7] << 8))); - - this->read(_slaveaddr, ENS16x_REG_DATA_MISR, i2cbuf, 1); - _misr = i2cbuf[0]; - } - - return newData; -} - -// Writes t (degC) and h (%rh) to ENV_DATA. Returns false on I2C problems. -bool ScioSense_ENS16x::set_envdata(float t, float h) { - - uint16_t t_data = (uint16_t)((t + 273.15f) * 64.0f); - - uint16_t rh_data = (uint16_t)(h * 512.0f); - - return this->set_envdata210(t_data, rh_data); -} - -// Writes t and h (in ENS210 format) to ENV_DATA. Returns false on I2C problems. -bool ScioSense_ENS16x::set_envdata210(uint16_t t, uint16_t h) { - //uint16_t temp; - uint8_t trh_in[4]; - - //temp = (uint16_t)((t + 273.15f) * 64.0f); - trh_in[0] = t & 0xff; - trh_in[1] = (t >> 8) & 0xff; - - //temp = (uint16_t)(h * 512.0f); - trh_in[2] = h & 0xff; - trh_in[3] = (h >> 8) & 0xff; - - uint8_t result = this->write(_slaveaddr, ENS16x_REG_TEMP_IN, trh_in, 4); - - return result; -} -#endif - -/**************************************************************************/ - -void ScioSense_ENS16x::_i2c_init() { -#ifndef ENS16x_DISABLE_ENHANCED_FEATURES - if (this->_sdaPin != this->_sclPin) - Wire.begin(this->_sdaPin, this->_sclPin); - else -#endif - Wire.begin(); -} - -/**************************************************************************/ - -uint8_t ScioSense_ENS16x::read8(uint8_t addr, byte reg) { - uint8_t ret; - this->read(addr, reg, &ret, 1); - - return ret; -} - -uint8_t ScioSense_ENS16x::read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num) { - uint8_t pos = 0; - uint8_t result = 0; - -#ifndef ENS16x_DISABLE_DEBUG - if (debugENS16x) { - Serial.print("I2C read address: 0x"); - Serial.print(addr, HEX); - Serial.print(" - register: 0x"); - Serial.println(reg, HEX); - } -#endif - - //on arduino we need to read in 32 byte chunks - while(pos < num){ - - uint8_t read_now = min((uint8_t)32, (uint8_t)(num - pos)); - Wire.beginTransmission((uint8_t)addr); - - Wire.write((uint8_t)reg + pos); - result = Wire.endTransmission(); - Wire.requestFrom((uint8_t)addr, read_now); - - for(int i=0; iwrite(addr, reg, &value, 1); - return result; -} - -uint8_t ScioSense_ENS16x::write(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num) { -#ifndef ENS16x_DISABLE_DEBUG - if (debugENS16x) { - Serial.print("I2C write address: 0x"); - Serial.print(addr, HEX); - Serial.print(" - register: 0x"); - Serial.print(reg, HEX); - Serial.print(" - value:"); - for (int i = 0; i_slaveaddr = slaveaddr; + + this->_ADDR = 0; + this->_nINT = 0; + this->_nCS = 0; +} + +#ifndef ENS16x_DISABLE_ENHANCED_FEATURES +ScioSense_ENS16x::ScioSense_ENS16x(uint8_t ADDR, uint8_t nCS, uint8_t nINT) { + this->_slaveaddr = ENS16x_I2CADDR_0; + + this->_ADDR = ADDR; + this->_nINT = nINT; + this->_nCS = nCS; +} + +ScioSense_ENS16x::ScioSense_ENS16x(uint8_t slaveaddr, uint8_t ADDR, uint8_t nCS, uint8_t nINT) { + this->_slaveaddr = slaveaddr; + + this->_ADDR = ADDR; + this->_nINT = nINT; + this->_nCS = nCS; +} + +// Function to redefine I2C pins +void ScioSense_ENS16x::setI2C(uint8_t sda, uint8_t scl) { + this->_sdaPin = sda; + this->_sclPin = scl; +} +#endif + +// Init I2C communication, resets ENS16x and checks its PART_ID. Returns false on I2C problems or wrong PART_ID. +bool ScioSense_ENS16x::begin(bool debug) +{ +#ifndef ENS16x_DISABLE_DEBUG + debugENS16x = debug; + + //Set pin levels + if (this->_ADDR > 0) { + pinMode(this->_ADDR, OUTPUT); + digitalWrite(this->_ADDR, LOW); + } + if (this->_nINT > 0) pinMode(this->_nINT, INPUT_PULLUP); + if (this->_nCS > 0) { + pinMode(this->_nCS, OUTPUT); + digitalWrite(this->_nCS, HIGH); + } +#endif + + //init I2C + _i2c_init(); +#ifndef ENS16x_DISABLE_DEBUG + if (debugENS16x) { + Serial.println("begin() - I2C init done"); + } +#endif + delay(ENS16x_BOOTING); // Wait to boot after reset + + this->_available = false; + this->_available = this->reset(); + + this->_available = this->checkPartID(); + + if (this->_available) { + this->_available = this->setMode(ENS16x_OPMODE_IDLE); + this->_available = this->clearCommand(); + this->_available = this->getFirmware(); + } +#ifndef ENS16x_DISABLE_DEBUG + if (debugENS16x) { + Serial.println("ENS16x in idle mode"); + } +#endif + return this->_available; +} + +// Sends a reset to the ENS16x. Returns false on I2C problems. +bool ScioSense_ENS16x::reset(void) +{ + uint8_t result = this->write8(_slaveaddr, ENS16x_REG_OPMODE, ENS16x_OPMODE_RESET); + +#ifndef ENS16x_DISABLE_DEBUG + if (debugENS16x) { + Serial.print("reset() result: "); + Serial.println(result == 0 ? "ok" : "nok"); + } +#endif + delay(ENS16x_BOOTING); // Wait to boot after reset + + return result == 0; +} + +// Reads the part ID and confirms valid sensor +bool ScioSense_ENS16x::checkPartID(void) { + uint8_t i2cbuf[2]; + uint16_t part_id; + bool result = false; + + this->read(_slaveaddr, ENS16x_REG_PART_ID, i2cbuf, 2); + part_id = i2cbuf[0] | ((uint16_t)i2cbuf[1] << 8); + +#ifndef ENS16x_DISABLE_DEBUG + if (debugENS16x) { + Serial.print("checkPartID() result: "); + if (part_id == ENS160_PARTID) Serial.println("ENS160 ok"); + else if (part_id == ENS161_PARTID) Serial.println("ENS161 ok"); + else Serial.println("nok"); + } +#endif + delay(ENS16x_BOOTING); // Wait to boot after reset + + if (part_id == ENS160_PARTID) { this->_revENS16x = 0; result = true; } + else if (part_id == ENS161_PARTID) { this->_revENS16x = 1; result = true; } + + return result; +} + +// Initialize idle mode and confirms +bool ScioSense_ENS16x::clearCommand(void) { + uint8_t status; + uint8_t result; + + result = this->write8(_slaveaddr, ENS16x_REG_COMMAND, ENS16x_COMMAND_NOP); + result = this->write8(_slaveaddr, ENS16x_REG_COMMAND, ENS16x_COMMAND_CLRGPR); +#ifndef ENS16x_DISABLE_DEBUG + if (debugENS16x) { + Serial.print("clearCommand() result: "); + Serial.println(result == 0 ? "ok" : "nok"); + } +#endif + delay(ENS16x_BOOTING); // Wait to boot after reset + + status = this->read8(_slaveaddr, ENS16x_REG_DATA_STATUS); +#ifndef ENS16x_DISABLE_DEBUG + if (debugENS16x) { + Serial.print("clearCommand() status: 0x"); + Serial.println(status, HEX); + } +#endif + delay(ENS16x_BOOTING); // Wait to boot after reset + + return result == 0; +} + +// Read firmware revisions +bool ScioSense_ENS16x::getFirmware() { + uint8_t i2cbuf[3]; + uint8_t result; + + this->clearCommand(); + + delay(ENS16x_BOOTING); // Wait to boot after reset + + result = this->write8(_slaveaddr, ENS16x_REG_COMMAND, ENS16x_COMMAND_GET_APPVER); + result = this->read(_slaveaddr, ENS16x_REG_GPR_READ_4, i2cbuf, 3); + + this->_fw_ver_major = i2cbuf[0]; + this->_fw_ver_minor = i2cbuf[1]; + this->_fw_ver_build = i2cbuf[2]; + + if (this->_fw_ver_major > 6) this->_revENS16x = 1; + else this->_revENS16x = 0; + +#ifndef ENS16x_DISABLE_DEBUG + if (debugENS16x) { + Serial.println(this->_fw_ver_major); + Serial.println(this->_fw_ver_minor); + Serial.println(this->_fw_ver_build); + Serial.print("getFirmware() result: "); + Serial.println(result == 0 ? "ok" : "nok"); + } +#endif + delay(ENS16x_BOOTING); // Wait to boot after reset + + return result == 0; +} + +// Set operation mode of sensor +bool ScioSense_ENS16x::setMode(uint8_t mode) { + uint8_t result; + + //LP only valid for rev>0 + if ((mode == ENS161_OPMODE_LP) and (_revENS16x == 0)) result = 1; + else result = this->write8(_slaveaddr, ENS16x_REG_OPMODE, mode); + +#ifndef ENS16x_DISABLE_DEBUG + //if (debugENS16x) { + Serial.print("setMode() activate result: "); + Serial.println(result == 0 ? "ok" : "nok"); + //} +#endif + delay(ENS16x_BOOTING); // Wait to boot after reset + + return result == 0; +} + +#ifndef ENS16x_DISABLE_ENHANCED_FEATURES +// Initialize definition of custom mode with steps +bool ScioSense_ENS16x::initCustomMode(uint16_t stepNum) { + uint8_t result; + + if (stepNum > 0) { + this->_stepCount = stepNum; + + result = this->setMode(ENS16x_OPMODE_IDLE); + result = this->clearCommand(); + + result = this->write8(_slaveaddr, ENS16x_REG_COMMAND, ENS16x_COMMAND_SETSEQ); + } else { + result = 1; + } + delay(ENS16x_BOOTING); // Wait to boot after reset + + return result == 0; +} +#endif + +#ifndef ENS16x_DISABLE_ENHANCED_FEATURES +// Add a step to custom measurement profile with definition of duration, enabled data acquisition and temperature for each hotplate +bool ScioSense_ENS16x::addCustomStep(uint16_t time, bool measureHP0, bool measureHP1, bool measureHP2, bool measureHP3, uint16_t tempHP0, uint16_t tempHP1, uint16_t tempHP2, uint16_t tempHP3) { + uint8_t seq_ack; + uint8_t temp; + +#ifndef ENS16x_DISABLE_DEBUG + if (debugENS16x) { + Serial.print("setCustomMode() write step "); + Serial.println(this->_stepCount); + } +#endif + delay(ENS16x_BOOTING); // Wait to boot after reset + + temp = (uint8_t)(((time / 24)-1) << 6); + if (measureHP0) temp = temp | 0x20; + if (measureHP1) temp = temp | 0x10; + if (measureHP2) temp = temp | 0x8; + if (measureHP3) temp = temp | 0x4; + this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_0, temp); + + temp = (uint8_t)(((time / 24)-1) >> 2); + this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_1, temp); + + this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_2, (uint8_t)(tempHP0/2)); + this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_3, (uint8_t)(tempHP1/2)); + this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_4, (uint8_t)(tempHP2/2)); + this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_5, (uint8_t)(tempHP3/2)); + + this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_6, (uint8_t)(this->_stepCount - 1)); + + if (this->_stepCount == 1) { + this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_7, 128); + } else { + this->write8(_slaveaddr, ENS16x_REG_GPR_WRITE_7, 0); + } + delay(ENS16x_BOOTING); + + seq_ack = this->read8(_slaveaddr, ENS16x_REG_GPR_READ_7); + delay(ENS16x_BOOTING); // Wait to boot after reset + + if ((ENS16x_SEQ_ACK_COMPLETE | this->_stepCount) != seq_ack) { + this->_stepCount = this->_stepCount - 1; + return 0; + } else { + return 1; + } + +} +#endif + +// Perform prediction measurement and stores result in internal variables +bool ScioSense_ENS16x::measure(bool waitForNew) { + uint8_t i2cbuf[8]; + uint8_t status; + bool newData = false; + + // Set default status for early bail out +#ifndef ENS16x_DISABLE_DEBUG + if (debugENS16x) Serial.println("Start measurement"); +#endif + + if (waitForNew) { + do { + delay(10); + status = this->read8(_slaveaddr, ENS16x_REG_DATA_STATUS); + +#ifndef ENS16x_DISABLE_DEBUG + if (debugENS16x) { + Serial.print("Status: "); + Serial.println(status); + } +#endif + } while (!IS_NEWDAT(status)); + } else { + status = this->read8(_slaveaddr, ENS16x_REG_DATA_STATUS); + } + + // Read predictions + if (IS_NEWDAT(status)) { + newData = true; + this->read(_slaveaddr, ENS16x_REG_DATA_AQI, i2cbuf, 7); + _data_aqi = i2cbuf[0]; + _data_tvoc = i2cbuf[1] | ((uint16_t)i2cbuf[2] << 8); + _data_eco2 = i2cbuf[3] | ((uint16_t)i2cbuf[4] << 8); + if (_revENS16x > 0) _data_aqis = ((uint16_t)i2cbuf[5]) | ((uint16_t)i2cbuf[6] << 8); + else _data_aqis = 0; + } + + return newData; +} + +#ifndef ENS16x_DISABLE_ENHANCED_FEATURES +// Perfrom raw measurement and stores result in internal variables +bool ScioSense_ENS16x::measureRaw(bool waitForNew) { + uint8_t i2cbuf[8]; + uint8_t status; + bool newData = false; + + // Set default status for early bail out +#ifndef ENS16x_DISABLE_DEBUG + if (debugENS16x) Serial.println("Start measurement"); +#endif + + if (waitForNew) { + do { + delay(10); + status = this->read8(_slaveaddr, ENS16x_REG_DATA_STATUS); + +#ifndef ENS16x_DISABLE_DEBUG + if (debugENS16x) { + Serial.print("Status: "); + Serial.println(status); + } +#endif + } while (!IS_NEWGPR(status)); + } else { + status = this->read8(_slaveaddr, ENS16x_REG_DATA_STATUS); + } + + if (IS_NEWGPR(status)) { + newData = true; + + // Read raw resistance values + this->read(_slaveaddr, ENS16x_REG_GPR_READ_0, i2cbuf, 8); + _hp0_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[0] | ((uint16_t)i2cbuf[1] << 8))); + _hp1_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[2] | ((uint16_t)i2cbuf[3] << 8))); + _hp2_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[4] | ((uint16_t)i2cbuf[5] << 8))); + _hp3_rs = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[6] | ((uint16_t)i2cbuf[7] << 8))); + + // Read baselines + this->read(_slaveaddr, ENS16x_REG_DATA_BL, i2cbuf, 8); + _hp0_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[0] | ((uint16_t)i2cbuf[1] << 8))); + _hp1_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[2] | ((uint16_t)i2cbuf[3] << 8))); + _hp2_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[4] | ((uint16_t)i2cbuf[5] << 8))); + _hp3_bl = CONVERT_RS_RAW2OHMS_F((uint32_t)(i2cbuf[6] | ((uint16_t)i2cbuf[7] << 8))); + + this->read(_slaveaddr, ENS16x_REG_DATA_MISR, i2cbuf, 1); + _misr = i2cbuf[0]; + } + + return newData; +} + +// Writes t (degC) and h (%rh) to ENV_DATA. Returns false on I2C problems. +bool ScioSense_ENS16x::set_envdata(float t, float h) { + + uint16_t t_data = (uint16_t)((t + 273.15f) * 64.0f); + + uint16_t rh_data = (uint16_t)(h * 512.0f); + + return this->set_envdata210(t_data, rh_data); +} + +// Writes t and h (in ENS210 format) to ENV_DATA. Returns false on I2C problems. +bool ScioSense_ENS16x::set_envdata210(uint16_t t, uint16_t h) { + //uint16_t temp; + uint8_t trh_in[4]; + + //temp = (uint16_t)((t + 273.15f) * 64.0f); + trh_in[0] = t & 0xff; + trh_in[1] = (t >> 8) & 0xff; + + //temp = (uint16_t)(h * 512.0f); + trh_in[2] = h & 0xff; + trh_in[3] = (h >> 8) & 0xff; + + uint8_t result = this->write(_slaveaddr, ENS16x_REG_TEMP_IN, trh_in, 4); + + return result; +} +#endif + +/**************************************************************************/ + +void ScioSense_ENS16x::_i2c_init() { +#ifndef ENS16x_DISABLE_ENHANCED_FEATURES + if (this->_sdaPin != this->_sclPin) + Wire.begin(this->_sdaPin, this->_sclPin); + else +#endif + Wire.begin(); +} + +/**************************************************************************/ + +uint8_t ScioSense_ENS16x::read8(uint8_t addr, byte reg) { + uint8_t ret; + this->read(addr, reg, &ret, 1); + + return ret; +} + +uint8_t ScioSense_ENS16x::read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num) { + uint8_t pos = 0; + uint8_t result = 0; + +#ifndef ENS16x_DISABLE_DEBUG + if (debugENS16x) { + Serial.print("I2C read address: 0x"); + Serial.print(addr, HEX); + Serial.print(" - register: 0x"); + Serial.println(reg, HEX); + } +#endif + + //on arduino we need to read in 32 byte chunks + while(pos < num){ + + uint8_t read_now = min((uint8_t)32, (uint8_t)(num - pos)); + Wire.beginTransmission((uint8_t)addr); + + Wire.write((uint8_t)reg + pos); + result = Wire.endTransmission(); + Wire.requestFrom((uint8_t)addr, read_now); + + for(int i=0; iwrite(addr, reg, &value, 1); + return result; +} + +uint8_t ScioSense_ENS16x::write(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num) { +#ifndef ENS16x_DISABLE_DEBUG + if (debugENS16x) { + Serial.print("I2C write address: 0x"); + Serial.print(addr, HEX); + Serial.print(" - register: 0x"); + Serial.print(reg, HEX); + Serial.print(" - value:"); + for (int i = 0; i= 100) - #include "Arduino.h" -#else - #include "WProgram.h" -#endif - -#include - -// Chip constants -#define ENS160_PARTID 0x0160 -#define ENS161_PARTID 0x0161 -#define ENS16x_BOOTING 10 - -// 7-bit I2C slave address of the ENS16x -#define ENS16x_I2CADDR_0 0x52 //ADDR low -#define ENS16x_I2CADDR_1 0x53 //ADDR high - -// ENS16x registers for version V0 -#define ENS16x_REG_PART_ID 0x00 // 2 byte register -#define ENS16x_REG_OPMODE 0x10 -#define ENS16x_REG_CONFIG 0x11 -#define ENS16x_REG_COMMAND 0x12 -#define ENS16x_REG_TEMP_IN 0x13 -#define ENS16x_REG_RH_IN 0x15 -#define ENS16x_REG_DATA_STATUS 0x20 -#define ENS16x_REG_DATA_AQI 0x21 -#define ENS16x_REG_DATA_TVOC 0x22 -#define ENS16x_REG_DATA_ECO2 0x24 -#define ENS16x_REG_DATA_BL 0x28 -#define ENS16x_REG_DATA_T 0x30 -#define ENS16x_REG_DATA_RH 0x32 -#define ENS16x_REG_DATA_MISR 0x38 -#define ENS16x_REG_GPR_WRITE_0 0x40 -#define ENS16x_REG_GPR_WRITE_1 ENS16x_REG_GPR_WRITE_0 + 1 -#define ENS16x_REG_GPR_WRITE_2 ENS16x_REG_GPR_WRITE_0 + 2 -#define ENS16x_REG_GPR_WRITE_3 ENS16x_REG_GPR_WRITE_0 + 3 -#define ENS16x_REG_GPR_WRITE_4 ENS16x_REG_GPR_WRITE_0 + 4 -#define ENS16x_REG_GPR_WRITE_5 ENS16x_REG_GPR_WRITE_0 + 5 -#define ENS16x_REG_GPR_WRITE_6 ENS16x_REG_GPR_WRITE_0 + 6 -#define ENS16x_REG_GPR_WRITE_7 ENS16x_REG_GPR_WRITE_0 + 7 -#define ENS16x_REG_GPR_READ_0 0x48 -#define ENS16x_REG_GPR_READ_4 ENS16x_REG_GPR_READ_0 + 4 -#define ENS16x_REG_GPR_READ_6 ENS16x_REG_GPR_READ_0 + 6 -#define ENS16x_REG_GPR_READ_7 ENS16x_REG_GPR_READ_0 + 7 - -//ENS16x data register fields -#define ENS16x_COMMAND_NOP 0x00 -#define ENS16x_COMMAND_CLRGPR 0xCC -#define ENS16x_COMMAND_GET_APPVER 0x0E -#define ENS16x_COMMAND_SETTH 0x02 -#define ENS16x_COMMAND_SETSEQ 0xC2 - -#define ENS16x_OPMODE_RESET 0xF0 -#define ENS16x_OPMODE_DEP_SLEEP 0x00 -#define ENS16x_OPMODE_IDLE 0x01 -#define ENS16x_OPMODE_STD 0x02 -#define ENS161_OPMODE_LP 0x03 -#define ENS16x_OPMODE_CUSTOM 0xC0 - -#define ENS16x_BL_CMD_START 0x02 -#define ENS16x_BL_CMD_ERASE_APP 0x04 -#define ENS16x_BL_CMD_ERASE_BLINE 0x06 -#define ENS16x_BL_CMD_WRITE 0x08 -#define ENS16x_BL_CMD_VERIFY 0x0A -#define ENS16x_BL_CMD_GET_BLVER 0x0C -#define ENS16x_BL_CMD_GET_APPVER 0x0E -#define ENS16x_BL_CMD_EXITBL 0x12 - -#define ENS16x_SEQ_ACK_NOTCOMPLETE 0x80 -#define ENS16x_SEQ_ACK_COMPLETE 0xC0 - -#define IS_ENS16x_SEQ_ACK_NOT_COMPLETE(x) (ENS16x_SEQ_ACK_NOTCOMPLETE == (ENS16x_SEQ_ACK_NOTCOMPLETE & (x))) -#define IS_ENS16x_SEQ_ACK_COMPLETE(x) (ENS16x_SEQ_ACK_COMPLETE == (ENS16x_SEQ_ACK_COMPLETE & (x))) - -#define ENS16x_DATA_STATUS_NEWDAT 0x02 -#define ENS16x_DATA_STATUS_NEWGPR 0x01 - -#define IS_NEWDAT(x) (ENS16x_DATA_STATUS_NEWDAT == (ENS16x_DATA_STATUS_NEWDAT & (x))) -#define IS_NEWGPR(x) (ENS16x_DATA_STATUS_NEWGPR == (ENS16x_DATA_STATUS_NEWGPR & (x))) -#define IS_NEW_DATA_AVAILABLE(x) (0 != ((ENS16x_DATA_STATUS_NEWDAT | ENS16x_DATA_STATUS_NEWGPR ) & (x))) - -#define CONVERT_RS_RAW2OHMS_I(x) (1 << ((x) >> 11)) -#define CONVERT_RS_RAW2OHMS_F(x) (pow (2, (float)(x) / 2048)) - -class ScioSense_ENS16x { - - public: - ScioSense_ENS16x(uint8_t slaveaddr = ENS16x_I2CADDR_0); // Constructor using slave address (5A or 5B) -#ifndef ENS16x_DISABLE_ENHANCED_FEATURES - ScioSense_ENS16x(uint8_t ADDR, uint8_t nCS, uint8_t nINT); // Constructor with pin definition - ScioSense_ENS16x(uint8_t slaveaddr, uint8_t ADDR, uint8_t nCS, uint8_t nINT); // Constructor with slave address and pin definition -#endif - - void setI2C(uint8_t sda, uint8_t scl); // Function to redefine I2C pins - - bool begin(bool debug=false); // Init I2C communication, resets ENS16x and checks its PART_ID. Returns false on I2C problems or wrong PART_ID. - bool available() { return this->_available; } // Report availability of sensor - uint8_t revENS16x() { return this->_revENS16x; } // Report version of sensor (0: ENS16x, 1: ENS161) - bool setMode(uint8_t mode); // Set operation mode of sensor - -#ifndef ENS16x_DISABLE_ENHANCED_FEATURES - bool initCustomMode(uint16_t stepNum); // Initialize definition of custom mode with steps - bool addCustomStep(uint16_t time, bool measureHP0, bool measureHP1, bool measureHP2, bool measureHP3, uint16_t tempHP0, uint16_t tempHP1, uint16_t tempHP2, uint16_t tempHP3); - // Add a step to custom measurement profile with definition of duration, enabled data acquisition and temperature for each hotplate -#endif - - bool measure(bool waitForNew = true); // Perform measurement and stores result in internal variables -#ifndef ENS16x_DISABLE_ENHANCED_FEATURES - bool measureRaw(bool waitForNew = true); // Perform raw measurement and stores result in internal variables - bool set_envdata(float t, float h); // Writes t (degC) and h (%rh) to ENV_DATA. Returns "0" if I2C transmission is successful - bool set_envdata210(uint16_t t, uint16_t h); // Writes t and h (in ENS210 format) to ENV_DATA. Returns "0" if I2C transmission is successful -#endif - uint8_t getMajorRev() { return this->_fw_ver_major; } // Get major revision number of used firmware - uint8_t getMinorRev() { return this->_fw_ver_minor; } // Get minor revision number of used firmware - uint8_t getBuild() { return this->_fw_ver_build; } // Get build revision number of used firmware - - uint8_t getAQI() { return this->_data_aqi; } // Get AQI value of last measurement - uint16_t getTVOC() { return this->_data_tvoc; } // Get TVOC value of last measurement - uint16_t geteCO2() { return this->_data_eco2; } // Get eCO2 value of last measurement - uint16_t getAQIS() { return this->_data_aqis; } // Get AQI500 value of last measurement - uint32_t getHP0() { return this->_hp0_rs; } // Get resistance of HP0 of last measurement - uint32_t getHP1() { return this->_hp1_rs; } // Get resistance of HP1 of last measurement - uint32_t getHP2() { return this->_hp2_rs; } // Get resistance of HP2 of last measurement - uint32_t getHP3() { return this->_hp3_rs; } // Get resistance of HP3 of last measurement - uint32_t getHP0BL() { return this->_hp0_bl; } // Get baseline resistance of HP0 of last measurement - uint32_t getHP1BL() { return this->_hp1_bl; } // Get baseline resistance of HP1 of last measurement - uint32_t getHP2BL() { return this->_hp2_bl; } // Get baseline resistance of HP2 of last measurement - uint32_t getHP3BL() { return this->_hp3_bl; } // Get baseline resistance of HP3 of last measurement - uint8_t getMISR() { return this->_misr; } // Return status code of sensor - - private: - uint8_t _ADDR; - uint8_t _nINT; - uint8_t _nCS; - uint8_t _sdaPin = 0; - uint8_t _sclPin = 0; - -#ifndef ENS16x_DISABLE_DEBUG - bool debugENS16x = false; -#endif - - bool reset(); // Sends a reset to the ENS16x. Returns false on I2C problems. - bool checkPartID(); // Reads the part ID and confirms valid sensor - bool clearCommand(); // Initialize idle mode and confirms - bool getFirmware(); // Read firmware revisions - - bool _available = false; // ENS16x available - uint8_t _revENS16x = 0; // ENS160 or ENS161 connected? (FW >7) - - uint8_t _fw_ver_major; - uint8_t _fw_ver_minor; - uint8_t _fw_ver_build; - - uint16_t _stepCount; // Counter for custom sequence - - uint8_t _data_aqi; - uint16_t _data_tvoc; - uint16_t _data_eco2; - uint16_t _data_aqis; - uint32_t _hp0_rs; - uint32_t _hp0_bl; - uint32_t _hp1_rs; - uint32_t _hp1_bl; - uint32_t _hp2_rs; - uint32_t _hp2_bl; - uint32_t _hp3_rs; - uint32_t _hp3_bl; - uint16_t _temp; - int _slaveaddr; - uint8_t _misr; - - //Isotherm, HP0 252°C / HP1 350°C / HP2 250°C / HP3 324°C / measure every 1008ms - uint8_t _seq_steps[1][8] = { - { 0x7C, 0x0A, 0x7E, 0xAF, 0xAF, 0xA2, 0x00, 0x80 }, - }; - - -/****************************************************************************/ -/* General functions */ -/****************************************************************************/ - void _i2c_init(); - - uint8_t read8(uint8_t addr, byte reg); - uint8_t read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num); - - uint8_t write8(uint8_t addr, byte reg, byte value); - uint8_t write(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num); - -}; - - +/* + ScioSense_ENS16x.h - Library for the ENS160 & ENS161 sensor with I2C interface from ScioSense + 2023 Jul 03 v8 Christoph Friese Update to cover ENS160 and ENS161 + 2023 Mar 23 v7 Christoph Friese Bugfix measurement routine, prepare next release + 2021 Nov 25 v6 Martin Herold Custom mode timing fixed + 2021 July 29 v5 Christoph Friese Changed nomenclature to ScioSense as product shifted from ams + 2021 Feb 04 v4 Giuseppe de Pinto Custom mode fixed + 2020 Apr 06 v3 Christoph Friese Changed nomenclature to ScioSense as product shifted from ams + 2020 Feb 15 v2 Giuseppe Pasetti Corrected firmware flash option + 2019 May 05 v1 Christoph Friese Created + + based on application note "ENS160 Software Integration.pdf" rev 0.01 +*/ + +#ifndef __SCIOSENSE_ENS16x_H_ +#define __SCIOSENSE_ENS16x_H_ + +#define ENS16x_DISABLE_DEBUG +#define ENS16x_DISABLE_ENHANCED_FEATURES + +#if (ARDUINO >= 100) + #include "Arduino.h" +#else + #include "WProgram.h" +#endif + +#include + +// Chip constants +#define ENS160_PARTID 0x0160 +#define ENS161_PARTID 0x0161 +#define ENS16x_BOOTING 10 + +// 7-bit I2C slave address of the ENS16x +#define ENS16x_I2CADDR_0 0x52 //ADDR low +#define ENS16x_I2CADDR_1 0x53 //ADDR high + +// ENS16x registers for version V0 +#define ENS16x_REG_PART_ID 0x00 // 2 byte register +#define ENS16x_REG_OPMODE 0x10 +#define ENS16x_REG_CONFIG 0x11 +#define ENS16x_REG_COMMAND 0x12 +#define ENS16x_REG_TEMP_IN 0x13 +#define ENS16x_REG_RH_IN 0x15 +#define ENS16x_REG_DATA_STATUS 0x20 +#define ENS16x_REG_DATA_AQI 0x21 +#define ENS16x_REG_DATA_TVOC 0x22 +#define ENS16x_REG_DATA_ECO2 0x24 +#define ENS16x_REG_DATA_BL 0x28 +#define ENS16x_REG_DATA_T 0x30 +#define ENS16x_REG_DATA_RH 0x32 +#define ENS16x_REG_DATA_MISR 0x38 +#define ENS16x_REG_GPR_WRITE_0 0x40 +#define ENS16x_REG_GPR_WRITE_1 ENS16x_REG_GPR_WRITE_0 + 1 +#define ENS16x_REG_GPR_WRITE_2 ENS16x_REG_GPR_WRITE_0 + 2 +#define ENS16x_REG_GPR_WRITE_3 ENS16x_REG_GPR_WRITE_0 + 3 +#define ENS16x_REG_GPR_WRITE_4 ENS16x_REG_GPR_WRITE_0 + 4 +#define ENS16x_REG_GPR_WRITE_5 ENS16x_REG_GPR_WRITE_0 + 5 +#define ENS16x_REG_GPR_WRITE_6 ENS16x_REG_GPR_WRITE_0 + 6 +#define ENS16x_REG_GPR_WRITE_7 ENS16x_REG_GPR_WRITE_0 + 7 +#define ENS16x_REG_GPR_READ_0 0x48 +#define ENS16x_REG_GPR_READ_4 ENS16x_REG_GPR_READ_0 + 4 +#define ENS16x_REG_GPR_READ_6 ENS16x_REG_GPR_READ_0 + 6 +#define ENS16x_REG_GPR_READ_7 ENS16x_REG_GPR_READ_0 + 7 + +//ENS16x data register fields +#define ENS16x_COMMAND_NOP 0x00 +#define ENS16x_COMMAND_CLRGPR 0xCC +#define ENS16x_COMMAND_GET_APPVER 0x0E +#define ENS16x_COMMAND_SETTH 0x02 +#define ENS16x_COMMAND_SETSEQ 0xC2 + +#define ENS16x_OPMODE_RESET 0xF0 +#define ENS16x_OPMODE_DEP_SLEEP 0x00 +#define ENS16x_OPMODE_IDLE 0x01 +#define ENS16x_OPMODE_STD 0x02 +#define ENS161_OPMODE_LP 0x03 +#define ENS16x_OPMODE_CUSTOM 0xC0 + +#define ENS16x_BL_CMD_START 0x02 +#define ENS16x_BL_CMD_ERASE_APP 0x04 +#define ENS16x_BL_CMD_ERASE_BLINE 0x06 +#define ENS16x_BL_CMD_WRITE 0x08 +#define ENS16x_BL_CMD_VERIFY 0x0A +#define ENS16x_BL_CMD_GET_BLVER 0x0C +#define ENS16x_BL_CMD_GET_APPVER 0x0E +#define ENS16x_BL_CMD_EXITBL 0x12 + +#define ENS16x_SEQ_ACK_NOTCOMPLETE 0x80 +#define ENS16x_SEQ_ACK_COMPLETE 0xC0 + +#define IS_ENS16x_SEQ_ACK_NOT_COMPLETE(x) (ENS16x_SEQ_ACK_NOTCOMPLETE == (ENS16x_SEQ_ACK_NOTCOMPLETE & (x))) +#define IS_ENS16x_SEQ_ACK_COMPLETE(x) (ENS16x_SEQ_ACK_COMPLETE == (ENS16x_SEQ_ACK_COMPLETE & (x))) + +#define ENS16x_DATA_STATUS_NEWDAT 0x02 +#define ENS16x_DATA_STATUS_NEWGPR 0x01 + +#define IS_NEWDAT(x) (ENS16x_DATA_STATUS_NEWDAT == (ENS16x_DATA_STATUS_NEWDAT & (x))) +#define IS_NEWGPR(x) (ENS16x_DATA_STATUS_NEWGPR == (ENS16x_DATA_STATUS_NEWGPR & (x))) +#define IS_NEW_DATA_AVAILABLE(x) (0 != ((ENS16x_DATA_STATUS_NEWDAT | ENS16x_DATA_STATUS_NEWGPR ) & (x))) + +#define CONVERT_RS_RAW2OHMS_I(x) (1 << ((x) >> 11)) +#define CONVERT_RS_RAW2OHMS_F(x) (pow (2, (float)(x) / 2048)) + +class ScioSense_ENS16x { + + public: + ScioSense_ENS16x(uint8_t slaveaddr = ENS16x_I2CADDR_0); // Constructor using slave address (5A or 5B) +#ifndef ENS16x_DISABLE_ENHANCED_FEATURES + ScioSense_ENS16x(uint8_t ADDR, uint8_t nCS, uint8_t nINT); // Constructor with pin definition + ScioSense_ENS16x(uint8_t slaveaddr, uint8_t ADDR, uint8_t nCS, uint8_t nINT); // Constructor with slave address and pin definition +#endif + + void setI2C(uint8_t sda, uint8_t scl); // Function to redefine I2C pins + + bool begin(bool debug=false); // Init I2C communication, resets ENS16x and checks its PART_ID. Returns false on I2C problems or wrong PART_ID. + bool available() { return this->_available; } // Report availability of sensor + uint8_t revENS16x() { return this->_revENS16x; } // Report version of sensor (0: ENS16x, 1: ENS161) + bool setMode(uint8_t mode); // Set operation mode of sensor + +#ifndef ENS16x_DISABLE_ENHANCED_FEATURES + bool initCustomMode(uint16_t stepNum); // Initialize definition of custom mode with steps + bool addCustomStep(uint16_t time, bool measureHP0, bool measureHP1, bool measureHP2, bool measureHP3, uint16_t tempHP0, uint16_t tempHP1, uint16_t tempHP2, uint16_t tempHP3); + // Add a step to custom measurement profile with definition of duration, enabled data acquisition and temperature for each hotplate +#endif + + bool measure(bool waitForNew = true); // Perform measurement and stores result in internal variables +#ifndef ENS16x_DISABLE_ENHANCED_FEATURES + bool measureRaw(bool waitForNew = true); // Perform raw measurement and stores result in internal variables + bool set_envdata(float t, float h); // Writes t (degC) and h (%rh) to ENV_DATA. Returns "0" if I2C transmission is successful + bool set_envdata210(uint16_t t, uint16_t h); // Writes t and h (in ENS210 format) to ENV_DATA. Returns "0" if I2C transmission is successful +#endif + uint8_t getMajorRev() { return this->_fw_ver_major; } // Get major revision number of used firmware + uint8_t getMinorRev() { return this->_fw_ver_minor; } // Get minor revision number of used firmware + uint8_t getBuild() { return this->_fw_ver_build; } // Get build revision number of used firmware + + uint8_t getAQI() { return this->_data_aqi; } // Get AQI value of last measurement + uint16_t getTVOC() { return this->_data_tvoc; } // Get TVOC value of last measurement + uint16_t geteCO2() { return this->_data_eco2; } // Get eCO2 value of last measurement + uint16_t getAQIS() { return this->_data_aqis; } // Get AQI500 value of last measurement + uint32_t getHP0() { return this->_hp0_rs; } // Get resistance of HP0 of last measurement + uint32_t getHP1() { return this->_hp1_rs; } // Get resistance of HP1 of last measurement + uint32_t getHP2() { return this->_hp2_rs; } // Get resistance of HP2 of last measurement + uint32_t getHP3() { return this->_hp3_rs; } // Get resistance of HP3 of last measurement + uint32_t getHP0BL() { return this->_hp0_bl; } // Get baseline resistance of HP0 of last measurement + uint32_t getHP1BL() { return this->_hp1_bl; } // Get baseline resistance of HP1 of last measurement + uint32_t getHP2BL() { return this->_hp2_bl; } // Get baseline resistance of HP2 of last measurement + uint32_t getHP3BL() { return this->_hp3_bl; } // Get baseline resistance of HP3 of last measurement + uint8_t getMISR() { return this->_misr; } // Return status code of sensor + + private: + uint8_t _ADDR; + uint8_t _nINT; + uint8_t _nCS; + uint8_t _sdaPin = 0; + uint8_t _sclPin = 0; + +#ifndef ENS16x_DISABLE_DEBUG + bool debugENS16x = false; +#endif + + bool reset(); // Sends a reset to the ENS16x. Returns false on I2C problems. + bool checkPartID(); // Reads the part ID and confirms valid sensor + bool clearCommand(); // Initialize idle mode and confirms + bool getFirmware(); // Read firmware revisions + + bool _available = false; // ENS16x available + uint8_t _revENS16x = 0; // ENS160 or ENS161 connected? (FW >7) + + uint8_t _fw_ver_major; + uint8_t _fw_ver_minor; + uint8_t _fw_ver_build; + + uint16_t _stepCount; // Counter for custom sequence + + uint8_t _data_aqi; + uint16_t _data_tvoc; + uint16_t _data_eco2; + uint16_t _data_aqis; + uint32_t _hp0_rs; + uint32_t _hp0_bl; + uint32_t _hp1_rs; + uint32_t _hp1_bl; + uint32_t _hp2_rs; + uint32_t _hp2_bl; + uint32_t _hp3_rs; + uint32_t _hp3_bl; + uint16_t _temp; + int _slaveaddr; + uint8_t _misr; + + //Isotherm, HP0 252°C / HP1 350°C / HP2 250°C / HP3 324°C / measure every 1008ms + uint8_t _seq_steps[1][8] = { + { 0x7C, 0x0A, 0x7E, 0xAF, 0xAF, 0xA2, 0x00, 0x80 }, + }; + + +/****************************************************************************/ +/* General functions */ +/****************************************************************************/ + void _i2c_init(); + + uint8_t read8(uint8_t addr, byte reg); + uint8_t read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num); + + uint8_t write8(uint8_t addr, byte reg, byte value); + uint8_t write(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num); + +}; + + #endif \ No newline at end of file diff --git a/lib/lib_i2c/ScioSense_ENS210/library.properties b/lib/lib_i2c/ScioSense_ENS210/library.properties index 0a9f30ed6..164d50055 100644 --- a/lib/lib_i2c/ScioSense_ENS210/library.properties +++ b/lib/lib_i2c/ScioSense_ENS210/library.properties @@ -1,9 +1,9 @@ -name=ScioSense ENS210 -version=3.0.0 -author=Christoph Friese -maintainer=Christoph Friese -sentence=Arduino library for the ENS210 digital temperature & humidity sensor with I2C interface from ScioSense -paragraph=This library controls the ENS210. The main feature of this library is performing a single shot measurement, retrieving the measurement data. -category=Device Control -url=https://github.com/sciosense/ens210 -architectures=* +name=ScioSense ENS210 +version=3.0.0 +author=Christoph Friese +maintainer=Christoph Friese +sentence=Arduino library for the ENS210 digital temperature & humidity sensor with I2C interface from ScioSense +paragraph=This library controls the ENS210. The main feature of this library is performing a single shot measurement, retrieving the measurement data. +category=Device Control +url=https://github.com/sciosense/ens210 +architectures=* diff --git a/lib/lib_i2c/ScioSense_ENS210/src/ScioSense_ENS210.cpp b/lib/lib_i2c/ScioSense_ENS210/src/ScioSense_ENS210.cpp index 48c291cdc..fa2112c23 100644 --- a/lib/lib_i2c/ScioSense_ENS210/src/ScioSense_ENS210.cpp +++ b/lib/lib_i2c/ScioSense_ENS210/src/ScioSense_ENS210.cpp @@ -1,648 +1,648 @@ -/* - ScioSense_ENS210.h - Library for the ENS210 relative humidity and temperature sensor with I2C interface from ScioSense - 2020 Apr 06 v3 Christoph Friese Changed nomenclature to ScioSense as product shifted from ams - 2018 Aug 28 v2 Christoph Friese Adjusted I2C communication - 2017 Aug 01 v1 Maarten Pennings Created -*/ - -#include "ScioSense_ENS210.h" -#include - -// Compute the CRC-7 of 'val' (should only have 17 bits) -// https://en.wikipedia.org/wiki/Cyclic_redundancy_check#Computation -static uint32_t crc7( uint32_t val ) -{ - // Setup polynomial - uint32_t pol= CRC7POLY; - // Align polynomial with data - pol = pol << (DATA7WIDTH-CRC7WIDTH-1); - // Loop variable (indicates which bit to test, start with highest) - uint32_t bit = DATA7MSB; - // Make room for CRC value - val = val << CRC7WIDTH; - bit = bit << CRC7WIDTH; - pol = pol << CRC7WIDTH; - // Insert initial vector - val |= CRC7IVEC; - // Apply division until all bits done - while( bit & (DATA7MASK<>= 1; - pol >>= 1; - } - return val; -} - -ScioSense_ENS210::ScioSense_ENS210(uint8_t slaveaddr) { - this->_slaveaddress = slaveaddr; -} - -#ifndef ENS210_DISABLE_ENHANCED_FEATURES -void ScioSense_ENS210::setI2C(uint8_t sda, uint8_t scl) { - this->_sdaPin = sda; - this->_sclPin = scl; -} -#endif - -// Init I2C communication, resets ENS210 and checks its PART_ID. Returns false on I2C problems or wrong PART_ID. -// Stores solder correction. -bool ScioSense_ENS210::begin(bool debug) { - bool result; - -#ifndef ENS210_DISABLE_DEBUG - debugENS210 = debug; -#endif - - //init I2C - _i2c_init(); -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.println("ens210 debug - I2C init done"); - } -#endif - - // Record solder correction - this->_soldercorrection= 0; - this->_available = false; - this->_singleMode = true; - this->_t_data = -1; - this->_h_data = -1; - this->_partID = 0; - - this->lowpower(false); - - result = this->getversion(); - - if(this->_partID == ENS210_PARTID ) { - this->_available = true; - } - return result; -} - -#ifndef ENS210_DISABLE_ENHANCED_FEATURES -void ScioSense_ENS210::changeAddr(uint8_t oldAddr, uint8_t newAddr) { - uint8_t i2cbuf[2]; - - _i2c_init(); - - //Disable low power mode --> always on - uint8_t result = this->write8(oldAddr, 0x10, 0x00); -#ifndef ENS210_DISABLE_DEBUG - Serial.print("Low Power off result: 0x"); - Serial.println(result,HEX); -#endif - delay(100); - - // read status register - result = this->read(oldAddr, 0x11, i2cbuf, 1); -#ifndef ENS210_DISABLE_DEBUG - Serial.print("Read status result: 0x"); - Serial.println(result,HEX); - for (uint8_t i=0; i<1; i++) { - Serial.print("\t0x"); - Serial.print(i2cbuf[i],HEX); - } - Serial.println(); -#endif - delay(100); - - // enable low level access. PASSWORD_WRITE_ENABLE - result = this->write8(oldAddr, 0x10, 0x30); -#ifndef ENS210_DISABLE_DEBUG - Serial.print("PASSWORD_WRITE_ENABLE result: 0x"); - Serial.println(result,HEX); -#endif - delay(100); - - // read status register - result = this->read(oldAddr, 0x11, i2cbuf, 1); -#ifndef ENS210_DISABLE_DEBUG - Serial.print("Read status result: 0x"); - Serial.println(result,HEX); - for (uint8_t i=0; i<1; i++) { - Serial.print("\t0x"); - Serial.print(i2cbuf[i],HEX); - } - Serial.println(); -#endif - delay(100); - - // low level access password. Password is 00 00 00 00 - uint8_t passwdCmd[4] = {0x00, 0x00, 0x00, 0x00}; - result = this->write(oldAddr, 0x48, passwdCmd, 5); -#ifndef ENS210_DISABLE_DEBUG - Serial.print("Write password result: 0x"); - Serial.println(result,HEX); -#endif - delay(100); - - // read low-level mode sensor output data - result = this->read(oldAddr, 0x46, i2cbuf, 2); -#ifndef ENS210_DISABLE_DEBUG - Serial.print("Read low level result: 0x"); - Serial.println(result,HEX); - for (uint8_t i=0; i<2; i++) { - Serial.print("\t0x"); - Serial.print(i2cbuf[i],HEX); - } - Serial.println(); -#endif - delay(100); - - // write values to parameter field and data1&2 field - uint8_t newAddrCmd[5] = {0x00,0x00,0x22,0x00,0x41}; - newAddrCmd[4] = newAddr; - result = this->write(oldAddr, 0x41, newAddrCmd, 5); -#ifndef ENS210_DISABLE_DEBUG - Serial.print("Write parameters result: 0x"); - Serial.println(result,HEX); -#endif - delay(100); - - // write SEN_CMD to execute low-level command specified, 0xCE means “APB_WRITE” - result = this->write8(oldAddr, 0x40, 0xCE); -#ifndef ENS210_DISABLE_DEBUG - Serial.print("Execute result: 0x"); - Serial.println(result,HEX); -#endif - delay(100); - - // Read low-level mode sensor output data to check if programming succeeded. Expected response: 0x00 0xAC - result = this->read(oldAddr, 0x46, i2cbuf, 2); -#ifndef ENS210_DISABLE_DEBUG - Serial.print("Read back result: 0x"); - Serial.println(result,HEX); - for (uint8_t i=0; i<2; i++) { - Serial.print("\t0x"); - Serial.print(i2cbuf[i],HEX); - } - Serial.println(); -#endif - delay(100); - - // reset ENS210 - result = this->write8(oldAddr, 0x10, 0xFF); -#ifndef ENS210_DISABLE_DEBUG - Serial.print("Reset result: 0x"); - Serial.println(result,HEX); -#endif - delay(100); - - // reset ENS210 - result = this->write8(oldAddr, 0x10, 0xFF); -#ifndef ENS210_DISABLE_DEBUG - Serial.print("Reset result: 0x"); - Serial.println(result,HEX); -#endif - delay(100); - - // reset ENS210 - result = this->write8(newAddr, 0x10, 0xFF); -#ifndef ENS210_DISABLE_DEBUG - Serial.print("Reset result: 0x"); - Serial.println(result,HEX); -#endif - delay(100); -} -#endif //#ifndef ENS210_DISABLE_ENHANCED_FEATURES - -// Sends a reset to the ENS210. Returns false on I2C problems. -bool ScioSense_ENS210::reset(void) { - uint8_t result = this->write8(_slaveaddress, ENS210_REG_SYS_CTRL, 0x80); -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("ens210 debug - reset: 0x"); - Serial.println(result,HEX); - } -#endif - delay(ENS210_BOOTING); // Wait to boot after reset - return result==0; -} - - -// Sets ENS210 to low (true) or high (false) power. Returns false on I2C problems. -bool ScioSense_ENS210::lowpower(bool enable) { - uint8_t power = enable ? 0x01: 0x00; - uint8_t result = this->write8(this->_slaveaddress, ENS210_REG_SYS_CTRL, power); -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("ens210 debug - lowpower: 0x"); - Serial.println(result,HEX); - } -#endif - delay(ENS210_BOOTING); // Wait boot-time after power switch - return result==0; -} - - -// Reads PART_ID and UID of ENS210. Returns false on I2C problems. -bool ScioSense_ENS210::getversion() { - bool ok; - uint8_t i2cbuf[8]; - uint8_t result; - - // Must disable low power to read PART_ID or UID - ok= lowpower(false); if(!ok) goto errorexit; - - // Read the PART_ID - result = this->read(this->_slaveaddress, ENS210_REG_PART_ID, i2cbuf, 2); -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("ens210 debug - PART_ID I2C result: 0x"); - Serial.println(result, HEX); - } -#endif - //this->_partID = (uint16_t)(i2cbuf[1]*256U + i2cbuf[0]*1U); - this->_partID = (uint16_t)(((uint16_t)i2cbuf[1] << 8) | ((uint16_t)i2cbuf[0])); -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("PART_ID: 0x"); - Serial.println(this->_partID,HEX); - } -#endif - - // Read the REV - result = this->read(this->_slaveaddress, ENS210_REG_REV, i2cbuf, 2); -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("ens210 debug - REV I2C result: 0x"); - Serial.println(result, HEX); - } -#endif - this->_rev = (uint16_t)(((uint16_t)i2cbuf[1] << 8) | ((uint16_t)i2cbuf[0])); -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("REV: 0x"); - Serial.println(this->_rev,HEX); - } -#endif - - // Read the UID - result = this->read(_slaveaddress, ENS210_REG_UID,i2cbuf,8); -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("ens210 debug - UID 0x"); - Serial.println(result,HEX); - } -#endif - this->_uID = (uint64_t)((uint64_t)i2cbuf[7]<<56 | (uint64_t)i2cbuf[6]<<48 | (uint64_t)i2cbuf[5]<<40 | (uint64_t)i2cbuf[4]<<32 | (uint64_t)i2cbuf[3]<<24 | (uint64_t)i2cbuf[2]<<16 | (uint64_t)i2cbuf[1]<<8 | (uint64_t)i2cbuf[0]); - - //for( int i=0; i<8; i++) ((uint8_t*)this->_uID)[i]=i2cbuf[i]; //((uint8_t*)this->_uID)[i]=i2cbuf[i]; - this->_uIDhi = (uint32_t)(this->_uID >> 32); - this->_uIDlo = (uint32_t)(this->_uID & 0xFFFFFFFF); - -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("UID hi 0x"); - Serial.print(this->_uIDhi,HEX); - Serial.print(" - 0x"); - Serial.println(this->_uIDlo,HEX); - } -#endif - - // Go back to default power mode (low power enabled) - ok= lowpower(true); if(!ok) goto errorexit; - - // Success - return true; - - errorexit: - // Try to go back to default mode (low power enabled) - ok= lowpower(true); - - // Hopefully enabling low power was successful; but there was an error before that anyhow - return false; -} - -// Configures ENS210 measurement mode -// false for continuous mode / true for single shot measurement. Returns false on I2C problems. -bool ScioSense_ENS210::setSingleMode(bool enable) -{ - this->_singleMode = enable; - uint8_t mode = enable ? 0x00: 0x03; - uint8_t result = this->write8(_slaveaddress, ENS210_REG_SENS_RUN, mode); -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("ens210 debug - start mode 0x"); - Serial.print(mode,HEX); - Serial.print(" - result 0x"); - Serial.println(result,HEX); - } -#endif - return result==0; -} - -// Performs one single shot temperature and relative humidity measurement. -void ScioSense_ENS210::measure() //int * t_data, int * t_status, int * h_data, int * h_status ) -{ - bool ok; - // Set default status for early bail out -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) Serial.println("Start measurement"); -#endif - this->_t_status = ENS210_STATUS_I2CERROR; - this->_h_status = ENS210_STATUS_I2CERROR; - - // Start a single shot measurement - if (this->_singleMode) - { - uint8_t result = this->write8(_slaveaddress, ENS210_REG_SENS_RUN, 0x00); -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("ens210 debug - start single 0x"); - Serial.println(result,HEX); - } -#endif - } - - //Trigger measurement - uint8_t result = this->write8(_slaveaddress, ENS210_REG_SENS_START, 0x03); -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("ens210 debug - trigger measurement 0x"); - Serial.println(result,HEX); - } -#endif - - // Wait for measurement to complete - if (this->_singleMode) delay(ENS210_THCONV_SINGLE_MS); - else delay(ENS210_THCONV_CONT_MS); - - // Get the measurement data -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) Serial.println("Start measurement"); -#endif - ok = readValue(); if(!ok) return; -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) Serial.println("Measurement ok"); -#endif -} - -// Reads measurement data from the ENS210. Returns false on I2C problems. -bool ScioSense_ENS210::readValue() //uint32_t *t_val, uint32_t *h_val) -{ - uint8_t i2cbuf[6]; - uint8_t valid; - uint32_t crc; - uint32_t payload; - uint8_t crc_ok; - - // Read T_VAL and H_VAL - uint8_t result = this->read(_slaveaddress, ENS210_REG_T_VAL, i2cbuf, 6); -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("ens210 debug - readValue:"); - Serial.println(result); - Serial.print(i2cbuf[0],HEX); Serial.print("\t"); - Serial.print(i2cbuf[1],HEX); Serial.print("\t"); - Serial.print(i2cbuf[2],HEX); Serial.print("\t"); - Serial.print(i2cbuf[3],HEX); Serial.print("\t"); - Serial.print(i2cbuf[4],HEX); Serial.print("\t"); - Serial.print(i2cbuf[5],HEX); Serial.println("\t"); - } -#endif - // Retrieve and pack bytes into t_val and h_val - uint32_t t_val= (uint32_t)((uint32_t)i2cbuf[2]<<16 | (uint32_t)i2cbuf[1]<<8 | (uint32_t)i2cbuf[0]); - this->_t_data = (t_val>>0) & 0xffff; - valid = (t_val>>16) & 0x1; - crc = (t_val>>17) & 0x7f; - payload = (t_val>>0 ) & 0x1ffff; - crc_ok = crc7(payload)==crc; - if( !crc_ok ) this->_t_status = ENS210_STATUS_CRCERROR; - else if( !valid ) this->_t_status = ENS210_STATUS_INVALID; - else this->_t_status = ENS210_STATUS_OK; -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("_t_data 0x"); - Serial.print(t_val,HEX); - Serial.print(" - 0x"); - Serial.println(this->_t_data,HEX); - Serial.print("Valid: "); - Serial.print(valid); - Serial.print(" Status: "); - Serial.println(this->_t_status); - } -#endif - - uint32_t h_val= (uint32_t)((uint32_t)i2cbuf[5]<<16 | (uint32_t)i2cbuf[4]<<8 | (uint32_t)i2cbuf[3]); - this->_h_data = (h_val>>0) & 0xffff; - - valid = (h_val>>16) & 0x1; - crc = (h_val>>17) & 0x7f; - payload = (h_val>>0 ) & 0x1ffff; - crc_ok= crc7(payload)==crc; - if( !crc_ok ) this->_h_status= ENS210_STATUS_CRCERROR; - else if( !valid ) this->_h_status= ENS210_STATUS_INVALID; - else this->_h_status= ENS210_STATUS_OK; -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("_h_data 0x"); - Serial.print(h_val,HEX); - Serial.print(" - 0x"); - Serial.println(this->_h_data,HEX); - Serial.print("Valid: "); - Serial.print(valid); - Serial.print(" Status: "); - Serial.println(this->_h_status); - } -#endif - - // Success - return true; -} - - -#ifndef ENS210_DISABLE_ENHANCED_FEATURES -// Converts a status (ENS210_STATUS_XXX) to a human readable string. -const char * ScioSense_ENS210::status_str( int status ) -{ - switch( status ) { - case ENS210_STATUS_I2CERROR : return "i2c-error"; - case ENS210_STATUS_CRCERROR : return "crc-error"; - case ENS210_STATUS_INVALID : return "data-invalid"; - case ENS210_STATUS_OK : return "ok"; - default : return "unknown-status"; - } -} -#endif - -#ifndef ENS210_DISABLE_ENHANCED_FEATURES -// Convert raw `t_data` temperature to Kelvin (also applies the solder correction). -// The output value is in Kelvin multiplied by parameter `multiplier`. -float ScioSense_ENS210::getTempKelvin() -{ - // Force 32 bits - float t = this->_t_data & 0xFFFF; - // Compensate for soldering effect - t-= _soldercorrection; - // Return m*K. This equals m*(t/64) = (m*t)/64 - // Note m is the multiplier, K is temperature in Kelvin, t is raw t_data value. - // Uses K=t/64. - return t/64; //IDIV(t,64); -} -#endif - -// Convert raw `t_data` temperature to Celsius (also applies the solder correction). -// The output value is in Celsius multiplied by parameter `multiplier`. -float ScioSense_ENS210::getTempCelsius() -{ - //assert( (1<=multiplier) && (multiplier<=1024) ); - // Force 32 bits - float t= this->_t_data & 0xFFFF; - // Compensate for soldering effect - t-= _soldercorrection; - // Return m*C. This equals m*(K-273.15) = m*K - 27315*m/100 = m*t/64 - 27315*m/100 - // Note m is the multiplier, C is temperature in Celsius, K is temperature in Kelvin, t is raw t_data value. - // Uses C=K-273.15 and K=t/64. - return t/64 - 27315L/100; //IDIV(t,64) - IDIV(27315L,100); -} - -#ifndef ENS210_DISABLE_ENHANCED_FEATURES -// Convert raw `t_data` temperature to Fahrenheit (also applies the solder correction). -float ScioSense_ENS210::getTempFahrenheit() -{ - float t= this->_t_data & 0xFFFF; - // Compensate for soldering effect - t-= _soldercorrection; - // Return m*F. This equals m*(1.8*(K-273.15)+32) = m*(1.8*K-273.15*1.8+32) = 1.8*m*K-459.67*m = 9*m*K/5 - 45967*m/100 = 9*m*t/320 - 45967*m/100 - // Note m is the multiplier, F is temperature in Fahrenheit, K is temperature in Kelvin, t is raw t_data value. - // Uses F=1.8*(K-273.15)+32 and K=t/64. - return 9*t/320 - 45967/100; //IDIV(9*t,320) - IDIV(45967L,100); - // The first multiplication stays below 32 bits (t:16, multiplier:11, 9:4) - // The second multiplication stays below 32 bits (multiplier:10, 45967:16) -} -#endif - -// Convert raw `h_data` relative humidity to %RH. -float ScioSense_ENS210::getHumidityPercent() -{ - float h= this->_h_data & 0xFFFF; - // Return m*H. This equals m*(h/512) = (m*h)/512 - // Note m is the multiplier, H is the relative humidity in %RH, h is raw h_data value. - // Uses H=h/512. - return h/512; //IDIV(h, 512); -} - - -// Convert raw `h_data` absolute humidity to %RH. -#define MOLAR_MASS_OF_WATER 18.01534 -#define UNIVERSAL_GAS_CONSTANT 8.21447215 - -#ifndef ENS210_DISABLE_ENHANCED_FEATURES -float ScioSense_ENS210::getAbsoluteHumidityPercent() -{ - //taken from https://carnotcycle.wordpress.com/2012/08/04/how-to-convert-relative-humidity-to-absolute-humidity/ - //precision is about 0.1°C in range -30 to 35°C - //August-Roche-Magnus 6.1094 exp(17.625 x T)/(T + 243.04) - //Buck (1981) 6.1121 exp(17.502 x T)/(T + 240.97) - //reference https://www.eas.ualberta.ca/jdwilson/EAS372_13/Vomel_CIRES_satvpformulae.html // Use Buck (1981) - - return (6.1121 * pow(2.718281828,(17.67* this->getTempCelsius())/(this->getTempCelsius() + 243.5))* this->getHumidityPercent() *MOLAR_MASS_OF_WATER)/((273.15+ this->getTempCelsius() )*UNIVERSAL_GAS_CONSTANT); -} -#endif - -#ifndef ENS210_DISABLE_ENHANCED_FEATURES -// Sets the solder correction (default is 50mK) - only used by the `toXxx` functions. -void ScioSense_ENS210::correction_set(int correction) -{ - assert( -1*64_soldercorrection = correction; -} -#endif - - -/****************************************************************************/ -/* General functions */ -/****************************************************************************/ - -void ScioSense_ENS210::_i2c_init() { -#ifndef ENS210_DISABLE_ENHANCED_FEATURES - if (this->_sdaPin != this->_sclPin) - Wire.begin(this->_sdaPin, this->_sclPin); - else -#endif - Wire.begin(); -} -/**************************************************************************/ - -uint8_t ScioSense_ENS210::read8(uint8_t addr, byte reg) -{ - uint8_t ret; - this->read(addr, reg, &ret, 1); - - return ret; -} - -uint8_t ScioSense_ENS210::read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num) -{ - uint8_t pos = 0; - uint8_t result = 0; - -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("I2C read address: 0x"); - Serial.print(addr, HEX); - Serial.print(" - register: 0x"); - Serial.println(reg, HEX); - } -#endif - - //on arduino we need to read in 32 byte chunks - while(pos < num){ - - uint8_t read_now = 32; //min((uint8_t)32, (uint8_t)(num - pos)); - Wire.beginTransmission((uint8_t)addr); - - Wire.write((uint8_t)reg + pos); - result = Wire.endTransmission(); - Wire.requestFrom((uint8_t)addr, read_now); - - //for(int i=0; iwrite(addr, reg, &value, 1); - return result; -} - -uint8_t ScioSense_ENS210::write(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num) -{ -#ifndef ENS210_DISABLE_DEBUG - if (debugENS210) { - Serial.print("I2C write address: 0x"); - Serial.print(addr, HEX); - Serial.print(" - register: 0x"); - Serial.print(reg, HEX); - Serial.print(" - value: 0x"); - for (int i = 0; i + +// Compute the CRC-7 of 'val' (should only have 17 bits) +// https://en.wikipedia.org/wiki/Cyclic_redundancy_check#Computation +static uint32_t crc7( uint32_t val ) +{ + // Setup polynomial + uint32_t pol= CRC7POLY; + // Align polynomial with data + pol = pol << (DATA7WIDTH-CRC7WIDTH-1); + // Loop variable (indicates which bit to test, start with highest) + uint32_t bit = DATA7MSB; + // Make room for CRC value + val = val << CRC7WIDTH; + bit = bit << CRC7WIDTH; + pol = pol << CRC7WIDTH; + // Insert initial vector + val |= CRC7IVEC; + // Apply division until all bits done + while( bit & (DATA7MASK<>= 1; + pol >>= 1; + } + return val; +} + +ScioSense_ENS210::ScioSense_ENS210(uint8_t slaveaddr) { + this->_slaveaddress = slaveaddr; +} + +#ifndef ENS210_DISABLE_ENHANCED_FEATURES +void ScioSense_ENS210::setI2C(uint8_t sda, uint8_t scl) { + this->_sdaPin = sda; + this->_sclPin = scl; +} +#endif + +// Init I2C communication, resets ENS210 and checks its PART_ID. Returns false on I2C problems or wrong PART_ID. +// Stores solder correction. +bool ScioSense_ENS210::begin(bool debug) { + bool result; + +#ifndef ENS210_DISABLE_DEBUG + debugENS210 = debug; +#endif + + //init I2C + _i2c_init(); +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.println("ens210 debug - I2C init done"); + } +#endif + + // Record solder correction + this->_soldercorrection= 0; + this->_available = false; + this->_singleMode = true; + this->_t_data = -1; + this->_h_data = -1; + this->_partID = 0; + + this->lowpower(false); + + result = this->getversion(); + + if(this->_partID == ENS210_PARTID ) { + this->_available = true; + } + return result; +} + +#ifndef ENS210_DISABLE_ENHANCED_FEATURES +void ScioSense_ENS210::changeAddr(uint8_t oldAddr, uint8_t newAddr) { + uint8_t i2cbuf[2]; + + _i2c_init(); + + //Disable low power mode --> always on + uint8_t result = this->write8(oldAddr, 0x10, 0x00); +#ifndef ENS210_DISABLE_DEBUG + Serial.print("Low Power off result: 0x"); + Serial.println(result,HEX); +#endif + delay(100); + + // read status register + result = this->read(oldAddr, 0x11, i2cbuf, 1); +#ifndef ENS210_DISABLE_DEBUG + Serial.print("Read status result: 0x"); + Serial.println(result,HEX); + for (uint8_t i=0; i<1; i++) { + Serial.print("\t0x"); + Serial.print(i2cbuf[i],HEX); + } + Serial.println(); +#endif + delay(100); + + // enable low level access. PASSWORD_WRITE_ENABLE + result = this->write8(oldAddr, 0x10, 0x30); +#ifndef ENS210_DISABLE_DEBUG + Serial.print("PASSWORD_WRITE_ENABLE result: 0x"); + Serial.println(result,HEX); +#endif + delay(100); + + // read status register + result = this->read(oldAddr, 0x11, i2cbuf, 1); +#ifndef ENS210_DISABLE_DEBUG + Serial.print("Read status result: 0x"); + Serial.println(result,HEX); + for (uint8_t i=0; i<1; i++) { + Serial.print("\t0x"); + Serial.print(i2cbuf[i],HEX); + } + Serial.println(); +#endif + delay(100); + + // low level access password. Password is 00 00 00 00 + uint8_t passwdCmd[4] = {0x00, 0x00, 0x00, 0x00}; + result = this->write(oldAddr, 0x48, passwdCmd, 5); +#ifndef ENS210_DISABLE_DEBUG + Serial.print("Write password result: 0x"); + Serial.println(result,HEX); +#endif + delay(100); + + // read low-level mode sensor output data + result = this->read(oldAddr, 0x46, i2cbuf, 2); +#ifndef ENS210_DISABLE_DEBUG + Serial.print("Read low level result: 0x"); + Serial.println(result,HEX); + for (uint8_t i=0; i<2; i++) { + Serial.print("\t0x"); + Serial.print(i2cbuf[i],HEX); + } + Serial.println(); +#endif + delay(100); + + // write values to parameter field and data1&2 field + uint8_t newAddrCmd[5] = {0x00,0x00,0x22,0x00,0x41}; + newAddrCmd[4] = newAddr; + result = this->write(oldAddr, 0x41, newAddrCmd, 5); +#ifndef ENS210_DISABLE_DEBUG + Serial.print("Write parameters result: 0x"); + Serial.println(result,HEX); +#endif + delay(100); + + // write SEN_CMD to execute low-level command specified, 0xCE means “APB_WRITE” + result = this->write8(oldAddr, 0x40, 0xCE); +#ifndef ENS210_DISABLE_DEBUG + Serial.print("Execute result: 0x"); + Serial.println(result,HEX); +#endif + delay(100); + + // Read low-level mode sensor output data to check if programming succeeded. Expected response: 0x00 0xAC + result = this->read(oldAddr, 0x46, i2cbuf, 2); +#ifndef ENS210_DISABLE_DEBUG + Serial.print("Read back result: 0x"); + Serial.println(result,HEX); + for (uint8_t i=0; i<2; i++) { + Serial.print("\t0x"); + Serial.print(i2cbuf[i],HEX); + } + Serial.println(); +#endif + delay(100); + + // reset ENS210 + result = this->write8(oldAddr, 0x10, 0xFF); +#ifndef ENS210_DISABLE_DEBUG + Serial.print("Reset result: 0x"); + Serial.println(result,HEX); +#endif + delay(100); + + // reset ENS210 + result = this->write8(oldAddr, 0x10, 0xFF); +#ifndef ENS210_DISABLE_DEBUG + Serial.print("Reset result: 0x"); + Serial.println(result,HEX); +#endif + delay(100); + + // reset ENS210 + result = this->write8(newAddr, 0x10, 0xFF); +#ifndef ENS210_DISABLE_DEBUG + Serial.print("Reset result: 0x"); + Serial.println(result,HEX); +#endif + delay(100); +} +#endif //#ifndef ENS210_DISABLE_ENHANCED_FEATURES + +// Sends a reset to the ENS210. Returns false on I2C problems. +bool ScioSense_ENS210::reset(void) { + uint8_t result = this->write8(_slaveaddress, ENS210_REG_SYS_CTRL, 0x80); +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("ens210 debug - reset: 0x"); + Serial.println(result,HEX); + } +#endif + delay(ENS210_BOOTING); // Wait to boot after reset + return result==0; +} + + +// Sets ENS210 to low (true) or high (false) power. Returns false on I2C problems. +bool ScioSense_ENS210::lowpower(bool enable) { + uint8_t power = enable ? 0x01: 0x00; + uint8_t result = this->write8(this->_slaveaddress, ENS210_REG_SYS_CTRL, power); +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("ens210 debug - lowpower: 0x"); + Serial.println(result,HEX); + } +#endif + delay(ENS210_BOOTING); // Wait boot-time after power switch + return result==0; +} + + +// Reads PART_ID and UID of ENS210. Returns false on I2C problems. +bool ScioSense_ENS210::getversion() { + bool ok; + uint8_t i2cbuf[8]; + uint8_t result; + + // Must disable low power to read PART_ID or UID + ok= lowpower(false); if(!ok) goto errorexit; + + // Read the PART_ID + result = this->read(this->_slaveaddress, ENS210_REG_PART_ID, i2cbuf, 2); +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("ens210 debug - PART_ID I2C result: 0x"); + Serial.println(result, HEX); + } +#endif + //this->_partID = (uint16_t)(i2cbuf[1]*256U + i2cbuf[0]*1U); + this->_partID = (uint16_t)(((uint16_t)i2cbuf[1] << 8) | ((uint16_t)i2cbuf[0])); +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("PART_ID: 0x"); + Serial.println(this->_partID,HEX); + } +#endif + + // Read the REV + result = this->read(this->_slaveaddress, ENS210_REG_REV, i2cbuf, 2); +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("ens210 debug - REV I2C result: 0x"); + Serial.println(result, HEX); + } +#endif + this->_rev = (uint16_t)(((uint16_t)i2cbuf[1] << 8) | ((uint16_t)i2cbuf[0])); +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("REV: 0x"); + Serial.println(this->_rev,HEX); + } +#endif + + // Read the UID + result = this->read(_slaveaddress, ENS210_REG_UID,i2cbuf,8); +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("ens210 debug - UID 0x"); + Serial.println(result,HEX); + } +#endif + this->_uID = (uint64_t)((uint64_t)i2cbuf[7]<<56 | (uint64_t)i2cbuf[6]<<48 | (uint64_t)i2cbuf[5]<<40 | (uint64_t)i2cbuf[4]<<32 | (uint64_t)i2cbuf[3]<<24 | (uint64_t)i2cbuf[2]<<16 | (uint64_t)i2cbuf[1]<<8 | (uint64_t)i2cbuf[0]); + + //for( int i=0; i<8; i++) ((uint8_t*)this->_uID)[i]=i2cbuf[i]; //((uint8_t*)this->_uID)[i]=i2cbuf[i]; + this->_uIDhi = (uint32_t)(this->_uID >> 32); + this->_uIDlo = (uint32_t)(this->_uID & 0xFFFFFFFF); + +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("UID hi 0x"); + Serial.print(this->_uIDhi,HEX); + Serial.print(" - 0x"); + Serial.println(this->_uIDlo,HEX); + } +#endif + + // Go back to default power mode (low power enabled) + ok= lowpower(true); if(!ok) goto errorexit; + + // Success + return true; + + errorexit: + // Try to go back to default mode (low power enabled) + ok= lowpower(true); + + // Hopefully enabling low power was successful; but there was an error before that anyhow + return false; +} + +// Configures ENS210 measurement mode +// false for continuous mode / true for single shot measurement. Returns false on I2C problems. +bool ScioSense_ENS210::setSingleMode(bool enable) +{ + this->_singleMode = enable; + uint8_t mode = enable ? 0x00: 0x03; + uint8_t result = this->write8(_slaveaddress, ENS210_REG_SENS_RUN, mode); +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("ens210 debug - start mode 0x"); + Serial.print(mode,HEX); + Serial.print(" - result 0x"); + Serial.println(result,HEX); + } +#endif + return result==0; +} + +// Performs one single shot temperature and relative humidity measurement. +void ScioSense_ENS210::measure() //int * t_data, int * t_status, int * h_data, int * h_status ) +{ + bool ok; + // Set default status for early bail out +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) Serial.println("Start measurement"); +#endif + this->_t_status = ENS210_STATUS_I2CERROR; + this->_h_status = ENS210_STATUS_I2CERROR; + + // Start a single shot measurement + if (this->_singleMode) + { + uint8_t result = this->write8(_slaveaddress, ENS210_REG_SENS_RUN, 0x00); +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("ens210 debug - start single 0x"); + Serial.println(result,HEX); + } +#endif + } + + //Trigger measurement + uint8_t result = this->write8(_slaveaddress, ENS210_REG_SENS_START, 0x03); +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("ens210 debug - trigger measurement 0x"); + Serial.println(result,HEX); + } +#endif + + // Wait for measurement to complete + if (this->_singleMode) delay(ENS210_THCONV_SINGLE_MS); + else delay(ENS210_THCONV_CONT_MS); + + // Get the measurement data +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) Serial.println("Start measurement"); +#endif + ok = readValue(); if(!ok) return; +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) Serial.println("Measurement ok"); +#endif +} + +// Reads measurement data from the ENS210. Returns false on I2C problems. +bool ScioSense_ENS210::readValue() //uint32_t *t_val, uint32_t *h_val) +{ + uint8_t i2cbuf[6]; + uint8_t valid; + uint32_t crc; + uint32_t payload; + uint8_t crc_ok; + + // Read T_VAL and H_VAL + uint8_t result = this->read(_slaveaddress, ENS210_REG_T_VAL, i2cbuf, 6); +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("ens210 debug - readValue:"); + Serial.println(result); + Serial.print(i2cbuf[0],HEX); Serial.print("\t"); + Serial.print(i2cbuf[1],HEX); Serial.print("\t"); + Serial.print(i2cbuf[2],HEX); Serial.print("\t"); + Serial.print(i2cbuf[3],HEX); Serial.print("\t"); + Serial.print(i2cbuf[4],HEX); Serial.print("\t"); + Serial.print(i2cbuf[5],HEX); Serial.println("\t"); + } +#endif + // Retrieve and pack bytes into t_val and h_val + uint32_t t_val= (uint32_t)((uint32_t)i2cbuf[2]<<16 | (uint32_t)i2cbuf[1]<<8 | (uint32_t)i2cbuf[0]); + this->_t_data = (t_val>>0) & 0xffff; + valid = (t_val>>16) & 0x1; + crc = (t_val>>17) & 0x7f; + payload = (t_val>>0 ) & 0x1ffff; + crc_ok = crc7(payload)==crc; + if( !crc_ok ) this->_t_status = ENS210_STATUS_CRCERROR; + else if( !valid ) this->_t_status = ENS210_STATUS_INVALID; + else this->_t_status = ENS210_STATUS_OK; +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("_t_data 0x"); + Serial.print(t_val,HEX); + Serial.print(" - 0x"); + Serial.println(this->_t_data,HEX); + Serial.print("Valid: "); + Serial.print(valid); + Serial.print(" Status: "); + Serial.println(this->_t_status); + } +#endif + + uint32_t h_val= (uint32_t)((uint32_t)i2cbuf[5]<<16 | (uint32_t)i2cbuf[4]<<8 | (uint32_t)i2cbuf[3]); + this->_h_data = (h_val>>0) & 0xffff; + + valid = (h_val>>16) & 0x1; + crc = (h_val>>17) & 0x7f; + payload = (h_val>>0 ) & 0x1ffff; + crc_ok= crc7(payload)==crc; + if( !crc_ok ) this->_h_status= ENS210_STATUS_CRCERROR; + else if( !valid ) this->_h_status= ENS210_STATUS_INVALID; + else this->_h_status= ENS210_STATUS_OK; +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("_h_data 0x"); + Serial.print(h_val,HEX); + Serial.print(" - 0x"); + Serial.println(this->_h_data,HEX); + Serial.print("Valid: "); + Serial.print(valid); + Serial.print(" Status: "); + Serial.println(this->_h_status); + } +#endif + + // Success + return true; +} + + +#ifndef ENS210_DISABLE_ENHANCED_FEATURES +// Converts a status (ENS210_STATUS_XXX) to a human readable string. +const char * ScioSense_ENS210::status_str( int status ) +{ + switch( status ) { + case ENS210_STATUS_I2CERROR : return "i2c-error"; + case ENS210_STATUS_CRCERROR : return "crc-error"; + case ENS210_STATUS_INVALID : return "data-invalid"; + case ENS210_STATUS_OK : return "ok"; + default : return "unknown-status"; + } +} +#endif + +#ifndef ENS210_DISABLE_ENHANCED_FEATURES +// Convert raw `t_data` temperature to Kelvin (also applies the solder correction). +// The output value is in Kelvin multiplied by parameter `multiplier`. +float ScioSense_ENS210::getTempKelvin() +{ + // Force 32 bits + float t = this->_t_data & 0xFFFF; + // Compensate for soldering effect + t-= _soldercorrection; + // Return m*K. This equals m*(t/64) = (m*t)/64 + // Note m is the multiplier, K is temperature in Kelvin, t is raw t_data value. + // Uses K=t/64. + return t/64; //IDIV(t,64); +} +#endif + +// Convert raw `t_data` temperature to Celsius (also applies the solder correction). +// The output value is in Celsius multiplied by parameter `multiplier`. +float ScioSense_ENS210::getTempCelsius() +{ + //assert( (1<=multiplier) && (multiplier<=1024) ); + // Force 32 bits + float t= this->_t_data & 0xFFFF; + // Compensate for soldering effect + t-= _soldercorrection; + // Return m*C. This equals m*(K-273.15) = m*K - 27315*m/100 = m*t/64 - 27315*m/100 + // Note m is the multiplier, C is temperature in Celsius, K is temperature in Kelvin, t is raw t_data value. + // Uses C=K-273.15 and K=t/64. + return t/64 - 27315L/100; //IDIV(t,64) - IDIV(27315L,100); +} + +#ifndef ENS210_DISABLE_ENHANCED_FEATURES +// Convert raw `t_data` temperature to Fahrenheit (also applies the solder correction). +float ScioSense_ENS210::getTempFahrenheit() +{ + float t= this->_t_data & 0xFFFF; + // Compensate for soldering effect + t-= _soldercorrection; + // Return m*F. This equals m*(1.8*(K-273.15)+32) = m*(1.8*K-273.15*1.8+32) = 1.8*m*K-459.67*m = 9*m*K/5 - 45967*m/100 = 9*m*t/320 - 45967*m/100 + // Note m is the multiplier, F is temperature in Fahrenheit, K is temperature in Kelvin, t is raw t_data value. + // Uses F=1.8*(K-273.15)+32 and K=t/64. + return 9*t/320 - 45967/100; //IDIV(9*t,320) - IDIV(45967L,100); + // The first multiplication stays below 32 bits (t:16, multiplier:11, 9:4) + // The second multiplication stays below 32 bits (multiplier:10, 45967:16) +} +#endif + +// Convert raw `h_data` relative humidity to %RH. +float ScioSense_ENS210::getHumidityPercent() +{ + float h= this->_h_data & 0xFFFF; + // Return m*H. This equals m*(h/512) = (m*h)/512 + // Note m is the multiplier, H is the relative humidity in %RH, h is raw h_data value. + // Uses H=h/512. + return h/512; //IDIV(h, 512); +} + + +// Convert raw `h_data` absolute humidity to %RH. +#define MOLAR_MASS_OF_WATER 18.01534 +#define UNIVERSAL_GAS_CONSTANT 8.21447215 + +#ifndef ENS210_DISABLE_ENHANCED_FEATURES +float ScioSense_ENS210::getAbsoluteHumidityPercent() +{ + //taken from https://carnotcycle.wordpress.com/2012/08/04/how-to-convert-relative-humidity-to-absolute-humidity/ + //precision is about 0.1°C in range -30 to 35°C + //August-Roche-Magnus 6.1094 exp(17.625 x T)/(T + 243.04) + //Buck (1981) 6.1121 exp(17.502 x T)/(T + 240.97) + //reference https://www.eas.ualberta.ca/jdwilson/EAS372_13/Vomel_CIRES_satvpformulae.html // Use Buck (1981) + + return (6.1121 * pow(2.718281828,(17.67* this->getTempCelsius())/(this->getTempCelsius() + 243.5))* this->getHumidityPercent() *MOLAR_MASS_OF_WATER)/((273.15+ this->getTempCelsius() )*UNIVERSAL_GAS_CONSTANT); +} +#endif + +#ifndef ENS210_DISABLE_ENHANCED_FEATURES +// Sets the solder correction (default is 50mK) - only used by the `toXxx` functions. +void ScioSense_ENS210::correction_set(int correction) +{ + assert( -1*64_soldercorrection = correction; +} +#endif + + +/****************************************************************************/ +/* General functions */ +/****************************************************************************/ + +void ScioSense_ENS210::_i2c_init() { +#ifndef ENS210_DISABLE_ENHANCED_FEATURES + if (this->_sdaPin != this->_sclPin) + Wire.begin(this->_sdaPin, this->_sclPin); + else +#endif + Wire.begin(); +} +/**************************************************************************/ + +uint8_t ScioSense_ENS210::read8(uint8_t addr, byte reg) +{ + uint8_t ret; + this->read(addr, reg, &ret, 1); + + return ret; +} + +uint8_t ScioSense_ENS210::read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num) +{ + uint8_t pos = 0; + uint8_t result = 0; + +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("I2C read address: 0x"); + Serial.print(addr, HEX); + Serial.print(" - register: 0x"); + Serial.println(reg, HEX); + } +#endif + + //on arduino we need to read in 32 byte chunks + while(pos < num){ + + uint8_t read_now = 32; //min((uint8_t)32, (uint8_t)(num - pos)); + Wire.beginTransmission((uint8_t)addr); + + Wire.write((uint8_t)reg + pos); + result = Wire.endTransmission(); + Wire.requestFrom((uint8_t)addr, read_now); + + //for(int i=0; iwrite(addr, reg, &value, 1); + return result; +} + +uint8_t ScioSense_ENS210::write(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num) +{ +#ifndef ENS210_DISABLE_DEBUG + if (debugENS210) { + Serial.print("I2C write address: 0x"); + Serial.print(addr, HEX); + Serial.print(" - register: 0x"); + Serial.print(reg, HEX); + Serial.print(" - value: 0x"); + for (int i = 0; i= 100) - #include "Arduino.h" -#else - #include "WProgram.h" -#endif - -#include - -#define ENS210_I2CADDR 0x43 //ADDR low - -// Chip constants -#define ENS210_PARTID 0x0210 // The expected part id of the ENS210 -#define ENS210_BOOTING 2 // Booting time in ms (also after reset, or going to high power) -#define ENS210_THCONV_SINGLE_MS 130 // Conversion time in ms for single shot T/H measurement -#define ENS210_THCONV_CONT_MS 238 // Conversion time in ms for continuous T/H measurement - -// Addresses of the ENS210 registers -#define ENS210_REG_PART_ID 0x00 -#define ENS210_REG_REV 0x02 -#define ENS210_REG_UID 0x04 -#define ENS210_REG_SYS_CTRL 0x10 -#define ENS210_REG_SYS_STAT 0x11 -#define ENS210_REG_SENS_RUN 0x21 -#define ENS210_REG_SENS_START 0x22 -#define ENS210_REG_SENS_STOP 0x23 -#define ENS210_REG_SENS_STAT 0x24 -#define ENS210_REG_T_VAL 0x30 -#define ENS210_REG_H_VAL 0x33 - -// Division macro (used in conversion functions), implementing integer division with rounding. -// It supports both positive and negative dividends (n), but ONLY positive divisors (d). -//#define IDIV(n,d) ((n)>0 ? ((n)+(d)/2)/(d) : ((n)-(d)/2)/(d)) - -// 7654 3210 -// Polynomial 0b 1000 1001 ~ x^7+x^3+x^0 -// 0x 8 9 -#define CRC7WIDTH 7 // A 7 bits CRC has polynomial of 7th order, which has 8 terms -#define CRC7POLY 0x89 // The 8 coefficients of the polynomial -#define CRC7IVEC 0x7F // Initial vector has all 7 bits high -// Payload data -#define DATA7WIDTH 17 -#define DATA7MASK ((1UL<_available; } - uint16_t getPartID() { return this->_partID; } - uint16_t getRev() { return this->_rev; } - uint32_t getHighUID(bool high) { uint32_t result = high ? this->_uIDhi : this->_uIDlo; return result; } - void measure(); // perfrom measurement and stores result in internal variables -#ifndef ENS210_DISABLE_ENHANCED_FEATURES - float getTempKelvin (); // Converts and returns data (from `measure`) in Kelvin - float getTempFahrenheit (); // Converts and returns data (from `measure`) in Fahrenheit -#endif - float getTempCelsius (); // Converts and returns data (from `measure`) in Celsius - float getHumidityPercent(); // Converts and returns data (from `measure`) in %RH -#ifndef ENS210_DISABLE_ENHANCED_FEATURES - float getAbsoluteHumidityPercent(); // Converts and returns data (from `measure`) in %aH -#endif - char getStatusT() { return this->_t_status; } // Converts a status (ENS210_STATUS_XXX) to a human readable string. - uint32_t getDataT() { return this->_t_data; } - char getStatusH() { return this->_h_status; } // Converts a status (ENS210_STATUS_XXX) to a human readable string. - uint32_t getDataH() { return this->_h_data; } -#ifndef ENS210_DISABLE_ENHANCED_FEATURES - static const char * status_str( int status ); // Converts a status (ENS210_STATUS_XXX) to a human readable string. -#endif - - // Optionally set a solder `correction` (units: 1/64K, default from `begin` is 0). - // See "Effect of Soldering on Temperature Readout" in "Design-Guidelines" from - // https://download.ams.com/ENVIRONMENTAL-SENSORS/ENS210/Documentation -#ifndef ENS210_DISABLE_ENHANCED_FEATURES - void correction_set(int correction=50*64/1000); // Sets the solder correction (default is 50mK) - only used by the `toXxx()` functions. - int correction_get() {return this->_soldercorrection;} // Gets the solder correction. -#endif - - private: -#ifndef ENS210_DISABLE_DEBUG - bool debugENS210 = false; -#endif - bool reset(void); // Sends a reset to the ENS210. Returns false on I2C problems. - bool lowpower(bool enable); // Sets ENS210 to low (true) or high (false) power. Returns false on I2C problems. - bool getversion(); // Reads PART_ID and UID of ENS210. Returns false on I2C problems. - bool readValue(); // Reads measurement data from the ENS210. Returns false on I2C problems. - - bool _available = false; // ENS210 available - uint16_t _partID; // Part ID of ENS210, should be 0x210 - uint16_t _rev; // Revision 0 MRA2.6 / 1 MRA2.12 - uint64_t _uID; // Unique ID of this specific ENS210 - uint32_t _uIDhi; // First 32bit of unique ID of this specific ENS210 - uint32_t _uIDlo; // Second 32bit of unique ID of this specific ENS210 - bool _singleMode = true; // Measurement mode: true single shot / false continuous - uint32_t _t_data; - uint8_t _t_status; - uint32_t _h_data; - uint8_t _h_status; - uint8_t _slaveaddress = 0x43; // Slave address of ENS210 - uint8_t _soldercorrection; // Correction due to soldering (in 1/64K); subtracted from `t_data` by conversion functions. - - uint8_t _sdaPin = 0; - uint8_t _sclPin = 0; - - /****************************************************************************/ - /* General functions */ - /****************************************************************************/ - - uint8_t write8(uint8_t addr, byte reg, byte value); - uint8_t read8(uint8_t addr, byte reg); - - uint8_t read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num); - uint8_t write(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num); - void _i2c_init(); -}; - - -#endif +/* + ScioSense_ENS210.h - Library for the ENS210 relative humidity and temperature sensor with I2C interface from ScioSense + 2020 Apr 06 v3 Chrsitoph Friese Changed nomenclature to ScioSense as product shifted from ams + 2018 Aug 28 v2 Christoph Friese Adjusted I2C communication + 2017 Aug 01 v1 Maarten Pennings Created +*/ + +#ifndef __SCIOSENSE_ENS210_H_ +#define __SCIOSENSE_ENS210_H_ + +#define ENS210_DISABLE_DEBUG +#define ENS210_DISABLE_ENHANCED_FEATURES + +#if (ARDUINO >= 100) + #include "Arduino.h" +#else + #include "WProgram.h" +#endif + +#include + +#define ENS210_I2CADDR 0x43 //ADDR low + +// Chip constants +#define ENS210_PARTID 0x0210 // The expected part id of the ENS210 +#define ENS210_BOOTING 2 // Booting time in ms (also after reset, or going to high power) +#define ENS210_THCONV_SINGLE_MS 130 // Conversion time in ms for single shot T/H measurement +#define ENS210_THCONV_CONT_MS 238 // Conversion time in ms for continuous T/H measurement + +// Addresses of the ENS210 registers +#define ENS210_REG_PART_ID 0x00 +#define ENS210_REG_REV 0x02 +#define ENS210_REG_UID 0x04 +#define ENS210_REG_SYS_CTRL 0x10 +#define ENS210_REG_SYS_STAT 0x11 +#define ENS210_REG_SENS_RUN 0x21 +#define ENS210_REG_SENS_START 0x22 +#define ENS210_REG_SENS_STOP 0x23 +#define ENS210_REG_SENS_STAT 0x24 +#define ENS210_REG_T_VAL 0x30 +#define ENS210_REG_H_VAL 0x33 + +// Division macro (used in conversion functions), implementing integer division with rounding. +// It supports both positive and negative dividends (n), but ONLY positive divisors (d). +//#define IDIV(n,d) ((n)>0 ? ((n)+(d)/2)/(d) : ((n)-(d)/2)/(d)) + +// 7654 3210 +// Polynomial 0b 1000 1001 ~ x^7+x^3+x^0 +// 0x 8 9 +#define CRC7WIDTH 7 // A 7 bits CRC has polynomial of 7th order, which has 8 terms +#define CRC7POLY 0x89 // The 8 coefficients of the polynomial +#define CRC7IVEC 0x7F // Initial vector has all 7 bits high +// Payload data +#define DATA7WIDTH 17 +#define DATA7MASK ((1UL<_available; } + uint16_t getPartID() { return this->_partID; } + uint16_t getRev() { return this->_rev; } + uint32_t getHighUID(bool high) { uint32_t result = high ? this->_uIDhi : this->_uIDlo; return result; } + void measure(); // perfrom measurement and stores result in internal variables +#ifndef ENS210_DISABLE_ENHANCED_FEATURES + float getTempKelvin (); // Converts and returns data (from `measure`) in Kelvin + float getTempFahrenheit (); // Converts and returns data (from `measure`) in Fahrenheit +#endif + float getTempCelsius (); // Converts and returns data (from `measure`) in Celsius + float getHumidityPercent(); // Converts and returns data (from `measure`) in %RH +#ifndef ENS210_DISABLE_ENHANCED_FEATURES + float getAbsoluteHumidityPercent(); // Converts and returns data (from `measure`) in %aH +#endif + char getStatusT() { return this->_t_status; } // Converts a status (ENS210_STATUS_XXX) to a human readable string. + uint32_t getDataT() { return this->_t_data; } + char getStatusH() { return this->_h_status; } // Converts a status (ENS210_STATUS_XXX) to a human readable string. + uint32_t getDataH() { return this->_h_data; } +#ifndef ENS210_DISABLE_ENHANCED_FEATURES + static const char * status_str( int status ); // Converts a status (ENS210_STATUS_XXX) to a human readable string. +#endif + + // Optionally set a solder `correction` (units: 1/64K, default from `begin` is 0). + // See "Effect of Soldering on Temperature Readout" in "Design-Guidelines" from + // https://download.ams.com/ENVIRONMENTAL-SENSORS/ENS210/Documentation +#ifndef ENS210_DISABLE_ENHANCED_FEATURES + void correction_set(int correction=50*64/1000); // Sets the solder correction (default is 50mK) - only used by the `toXxx()` functions. + int correction_get() {return this->_soldercorrection;} // Gets the solder correction. +#endif + + private: +#ifndef ENS210_DISABLE_DEBUG + bool debugENS210 = false; +#endif + bool reset(void); // Sends a reset to the ENS210. Returns false on I2C problems. + bool lowpower(bool enable); // Sets ENS210 to low (true) or high (false) power. Returns false on I2C problems. + bool getversion(); // Reads PART_ID and UID of ENS210. Returns false on I2C problems. + bool readValue(); // Reads measurement data from the ENS210. Returns false on I2C problems. + + bool _available = false; // ENS210 available + uint16_t _partID; // Part ID of ENS210, should be 0x210 + uint16_t _rev; // Revision 0 MRA2.6 / 1 MRA2.12 + uint64_t _uID; // Unique ID of this specific ENS210 + uint32_t _uIDhi; // First 32bit of unique ID of this specific ENS210 + uint32_t _uIDlo; // Second 32bit of unique ID of this specific ENS210 + bool _singleMode = true; // Measurement mode: true single shot / false continuous + uint32_t _t_data; + uint8_t _t_status; + uint32_t _h_data; + uint8_t _h_status; + uint8_t _slaveaddress = 0x43; // Slave address of ENS210 + uint8_t _soldercorrection; // Correction due to soldering (in 1/64K); subtracted from `t_data` by conversion functions. + + uint8_t _sdaPin = 0; + uint8_t _sclPin = 0; + + /****************************************************************************/ + /* General functions */ + /****************************************************************************/ + + uint8_t write8(uint8_t addr, byte reg, byte value); + uint8_t read8(uint8_t addr, byte reg); + + uint8_t read(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num); + uint8_t write(uint8_t addr, uint8_t reg, uint8_t *buf, uint8_t num); + void _i2c_init(); +}; + + +#endif diff --git a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp index 57568061b..4cba7044b 100755 --- a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp +++ b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.cpp @@ -1,1053 +1,1053 @@ -/* - WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries - - Mostly compatible with Arduino WiFi shield library and standard - WiFiClient/ServerSecure (except for certificate handling). - - Copyright (C) 2021 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 "tasmota_options.h" -#ifdef USE_TLS - -// #define DEBUG_TLS -// #define DEBUG_ESP_SSL - -#define LWIP_INTERNAL - -#include -#include -#include - -#include "WiFiClientSecureLightBearSSL.h" // needs to be before "ESP8266WiFi.h" to avoid conflict with Arduino headers -#include "ESP8266WiFi.h" -#include "WiFiHelper.h" -#include "WiFiClient.h" -#include "StackThunk_light.h" -#include "lwip/opt.h" -#include "lwip/ip.h" -#include "lwip/tcp.h" -#include "lwip/inet.h" -#include "lwip/netif.h" -#ifdef ESP8266 - #include - #include "c_types.h" -#endif - -#if __has_include("core_version.h") // ESP32 Stage has no core_version.h file. Disable include via PlatformIO Option -#include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_7_1) -#endif // ESP32_STAGE -#undef DEBUG_TLS - -#ifdef DEBUG_TLS -#include "coredecls.h" -#define LOG_HEAP_SIZE(a) _Log_heap_size(a) -void _Log_heap_size(const char *msg) { -#ifdef ESP8266 - register uint32_t *sp asm("a1"); - int freestack = 4 * (sp - g_pcont->stack); - Serial.printf("%s %d, Fragmentation=%d, Thunkstack=%d, Free stack=%d, FreeContStack=%d\n", - msg, ESP.getFreeHeap(), ESP.getHeapFragmentation(), stack_thunk_light_get_max_usage(), - freestack, ESP.getFreeContStack()); -#elif defined(ESP32) - Serial.printf("> Heap %s = %d\n", msg, uxTaskGetStackHighWaterMark(nullptr)); -#endif -} -#else -#define LOG_HEAP_SIZE(a) -#endif - -// get UTC time from Tasmota -extern uint32_t UtcTime(void); -extern uint32_t CfgTime(void); - -#ifdef ESP8266 // Stack thunk is not needed with ESP32 -// Stack thunked versions of calls -// Initially in BearSSLHelpers.h -extern "C" { -extern unsigned char *thunk_light_br_ssl_engine_recvapp_buf( const br_ssl_engine_context *cc, size_t *len); -extern void thunk_light_br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len); -extern unsigned char *thunk_light_br_ssl_engine_recvrec_buf( const br_ssl_engine_context *cc, size_t *len); -extern void thunk_light_br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len); -extern unsigned char *thunk_light_br_ssl_engine_sendapp_buf( const br_ssl_engine_context *cc, size_t *len); -extern void thunk_light_br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len); -extern unsigned char *thunk_light_br_ssl_engine_sendrec_buf( const br_ssl_engine_context *cc, size_t *len); -extern void thunk_light_br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len); -}; - -// Second stack thunked helpers -make_stack_thunk_light(br_ssl_engine_recvapp_ack); -make_stack_thunk_light(br_ssl_engine_recvapp_buf); -make_stack_thunk_light(br_ssl_engine_recvrec_ack); -make_stack_thunk_light(br_ssl_engine_recvrec_buf); -make_stack_thunk_light(br_ssl_engine_sendapp_ack); -make_stack_thunk_light(br_ssl_engine_sendapp_buf); -make_stack_thunk_light(br_ssl_engine_sendrec_ack); -make_stack_thunk_light(br_ssl_engine_sendrec_buf); - -// create new version of Thunk function to store on SYS stack -// unless the Thunk was initialized. Thanks to AES128 GCM, we can keep -// symetric processing on the stack -void min_br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_recvapp_ack(cc, len); - } else { - return br_ssl_engine_recvapp_ack(cc, len); - } -} -unsigned char *min_br_ssl_engine_recvapp_buf(const br_ssl_engine_context *cc, size_t *len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_recvapp_buf(cc, len); - } else { - return br_ssl_engine_recvapp_buf(cc, len); - } -} -void min_br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_recvrec_ack(cc, len); - } else { - return br_ssl_engine_recvrec_ack(cc, len); - } -} -unsigned char *min_br_ssl_engine_recvrec_buf(const br_ssl_engine_context *cc, size_t *len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_recvrec_buf(cc, len); - } else { - return br_ssl_engine_recvrec_buf(cc, len); - } -} -void min_br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_sendapp_ack(cc, len); - } else { - return br_ssl_engine_sendapp_ack(cc, len); - } -} -unsigned char *min_br_ssl_engine_sendapp_buf(const br_ssl_engine_context *cc, size_t *len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_sendapp_buf(cc, len); - } else { - return br_ssl_engine_sendapp_buf(cc, len); - } -} -void min_br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_sendrec_ack(cc, len); - } else { - return br_ssl_engine_sendrec_ack(cc, len); - } -} -unsigned char *min_br_ssl_engine_sendrec_buf(const br_ssl_engine_context *cc, size_t *len) { - if (stack_thunk_light_get_refcnt()) { - return thunk_light_br_ssl_engine_sendrec_buf(cc, len); - } else { - return br_ssl_engine_sendrec_buf(cc, len); - } -} - -// Use min_ instead of original thunk_ -#define br_ssl_engine_recvapp_ack min_br_ssl_engine_recvapp_ack -#define br_ssl_engine_recvapp_buf min_br_ssl_engine_recvapp_buf -#define br_ssl_engine_recvrec_ack min_br_ssl_engine_recvrec_ack -#define br_ssl_engine_recvrec_buf min_br_ssl_engine_recvrec_buf -#define br_ssl_engine_sendapp_ack min_br_ssl_engine_sendapp_ack -#define br_ssl_engine_sendapp_buf min_br_ssl_engine_sendapp_buf -#define br_ssl_engine_sendrec_ack min_br_ssl_engine_sendrec_ack -#define br_ssl_engine_sendrec_buf min_br_ssl_engine_sendrec_buf - -#endif // ESP8266 - -//#define DEBUG_ESP_SSL -#ifdef DEBUG_ESP_SSL -//#define DEBUG_BSSL(fmt, ...) DEBUG_ESP_PORT.printf_P((PGM_P)PSTR( "BSSL:" fmt), ## __VA_ARGS__) -#define DEBUG_BSSL(fmt, ...) Serial.printf(fmt, ## __VA_ARGS__) -#else -#define DEBUG_BSSL(...) -#endif - -namespace BearSSL { - -void WiFiClientSecure_light::_clear() { - // TLS handshake may take more than the 5 second default timeout - _timeout = 10000; // 10 seconds max, it should never go over 6 seconds - - _sc = nullptr; - _ctx_present = false; - _eng = nullptr; - _iobuf_in = nullptr; - _iobuf_out = nullptr; - setBufferSizes(1024, 1024); // reasonable minimum - _handshake_done = false; - _last_error = 0; - _recvapp_buf = nullptr; - _recvapp_len = 0; - _insecure = false; // set to true when calling setPubKeyFingerprint() - _rsa_only = true; // for now we disable ECDSA by default - _fingerprint_any = true; // by default accept all fingerprints - _fingerprint1 = nullptr; - _fingerprint2 = nullptr; - _chain_P = nullptr; - _sk_ec_P = nullptr; - _ta_P = nullptr; - _ta_size = 0; - _max_thunkstack_use = 0; - _alpn_names = nullptr; - _alpn_num = 0; -} - -// Constructor -WiFiClientSecure_light::WiFiClientSecure_light(int recv, int xmit) : WiFiClient() { - _clear(); - // LOG_HEAP_SIZE("StackThunk before"); - //stack_thunk_light_add_ref(); - // LOG_HEAP_SIZE("StackThunk after"); - // now finish the setup - setBufferSizes(recv, xmit); // reasonable minimum - allocateBuffers(); -} - -WiFiClientSecure_light::~WiFiClientSecure_light() { -#ifdef ESP8266 - if (_client) { - _client->unref(); - _client = nullptr; - } -#elif defined(ESP32) - stop(); -#endif - //_cipher_list = nullptr; // std::shared will free if last reference - _freeSSL(); -} - -void WiFiClientSecure_light::allocateBuffers(void) { - // We prefer to allocate all buffers at start, rather than lazy allocation and deallocation - // in the long run it avoids heap fragmentation and improves stability - LOG_HEAP_SIZE("allocateBuffers before"); - _sc = std::make_shared(); - LOG_HEAP_SIZE("allocateBuffers ClientContext"); - _iobuf_in = std::shared_ptr(new unsigned char[_iobuf_in_size], std::default_delete()); - _iobuf_out = std::shared_ptr(new unsigned char[_iobuf_out_size], std::default_delete()); - LOG_HEAP_SIZE("allocateBuffers after"); -} - -void WiFiClientSecure_light::setClientECCert(const br_x509_certificate *cert, const br_ec_private_key *sk, - unsigned allowed_usages, unsigned cert_issuer_key_type) { - _chain_P = cert; - _sk_ec_P = sk; - _allowed_usages = allowed_usages; - _cert_issuer_key_type = cert_issuer_key_type; -} - -void WiFiClientSecure_light::setTrustAnchor(const br_x509_trust_anchor *ta, size_t ta_size) { - _ta_P = ta; - _ta_size = ta_size; -} - -void WiFiClientSecure_light::setBufferSizes(int recv, int xmit) { - // Following constants taken from bearssl/src/ssl/ssl_engine.c (not exported unfortunately) - const int MAX_OUT_OVERHEAD = 85; - const int MAX_IN_OVERHEAD = 325; - - // The data buffers must be between 512B and 16KB - recv = std::max(512, std::min(16384, recv)); - xmit = std::max(512, std::min(16384, xmit)); - - // Add in overhead for SSL protocol - recv += MAX_IN_OVERHEAD; - xmit += MAX_OUT_OVERHEAD; - _iobuf_in_size = recv; - _iobuf_out_size = xmit; -} - -#ifdef ESP8266 -bool WiFiClientSecure_light::stop(unsigned int maxWaitMs) { - bool ret = WiFiClient::stop(maxWaitMs); // calls our virtual flush() - _freeSSL(); - return ret; -} - -bool WiFiClientSecure_light::flush(unsigned int maxWaitMs) { - (void) _run_until(BR_SSL_SENDAPP); - return WiFiClient::flush(maxWaitMs); -} -#elif defined(ESP32) -void WiFiClientSecure_light::stop(void) { - WiFiClient::stop(); // calls our virtual flush() - _freeSSL(); -} - -void WiFiClientSecure_light::flush(void) { - (void) _run_until(BR_SSL_SENDAPP); - // don't call flush on ESP32 - its behavior is different and empties the receive buffer - which we don't want -} -#endif - -#ifdef ESP32 -int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port, int32_t timeout) { - DEBUG_BSSL("connect(%s,%d)", ip.toString().c_str(), port); - clearLastError(); - if (!WiFiClient::connect(ip, port, timeout)) { - setLastError(ERR_TCP_CONNECT); - return 0; - } - bool success = _connectSSL(_domain.isEmpty() ? nullptr : _domain.c_str()); - if (!success) { stop(); } - return success; -} -#else // ESP32 -int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port) { - DEBUG_BSSL("connect(%s,%d)", ip.toString().c_str(), port); - clearLastError(); - if (!WiFiClient::connect(ip, port)) { - setLastError(ERR_TCP_CONNECT); - return 0; - } - bool success = _connectSSL(_domain.isEmpty() ? nullptr : _domain.c_str()); - if (!success) { stop(); } - return success; -} -#endif - -#ifdef ESP32 -int WiFiClientSecure_light::connect(const char* name, uint16_t port, int32_t timeout) { - DEBUG_BSSL("connect(%s,%d)\n", name, port); - IPAddress remote_addr; - clearLastError(); - if (!WiFiHelper::hostByName(name, remote_addr)) { - DEBUG_BSSL("connect: Name loopup failure\n"); - setLastError(ERR_CANT_RESOLVE_IP); - return 0; - } - DEBUG_BSSL("connect(%s,%d)\n", remote_addr.toString().c_str(), port); - if (!WiFiClient::connect(remote_addr, port, timeout)) { - DEBUG_BSSL("connect: Unable to connect TCP socket\n"); - _last_error = ERR_TCP_CONNECT; - return 0; - } - LOG_HEAP_SIZE("Before calling _connectSSL"); - return _connectSSL(name); -} -#else // ESP32 -int WiFiClientSecure_light::connect(const char* name, uint16_t port) { - DEBUG_BSSL("connect(%s,%d)\n", name, port); - IPAddress remote_addr; - clearLastError(); - if (!WiFiHelper::hostByName(name, remote_addr)) { - DEBUG_BSSL("connect: Name loopup failure\n"); - setLastError(ERR_CANT_RESOLVE_IP); - return 0; - } - DEBUG_BSSL("connect(%s,%d)\n", remote_addr.toString().c_str(), port); - if (!WiFiClient::connect(remote_addr, port)) { - DEBUG_BSSL("connect: Unable to connect TCP socket\n"); - _last_error = ERR_TCP_CONNECT; - return 0; - } - LOG_HEAP_SIZE("Before calling _connectSSL"); - return _connectSSL(name); -} -#endif - -void WiFiClientSecure_light::_freeSSL() { - _ctx_present = false; - _recvapp_buf = nullptr; - _recvapp_len = 0; - // This connection is toast - _handshake_done = false; -} - -bool WiFiClientSecure_light::_clientConnected() { -#ifdef ESP8266 - return (_client && _client->state() == ESTABLISHED); -#elif defined(ESP32) - return WiFiClient::connected(); -#endif -} - -uint8_t WiFiClientSecure_light::connected() { - if (available() || (_clientConnected() && _handshake_done)) { - return true; - } - return false; -} - -size_t WiFiClientSecure_light::_write(const uint8_t *buf, size_t size, bool pmem) { - size_t sent_bytes = 0; - - if (!connected() || !size || !_handshake_done) { - return 0; - } - - do { - // Ensure we yield if we need multiple fragments to avoid WDT - if (sent_bytes) { - optimistic_yield(1000); - } - - // Get BearSSL to a state where we can send - if (_run_until(BR_SSL_SENDAPP) < 0) { - break; - } - - if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) { - size_t sendapp_len; - unsigned char *sendapp_buf = br_ssl_engine_sendapp_buf(_eng, &sendapp_len); - int to_send = size > sendapp_len ? sendapp_len : size; - if (pmem) { - memcpy_P(sendapp_buf, buf, to_send); - } else { - memcpy(sendapp_buf, buf, to_send); - } - br_ssl_engine_sendapp_ack(_eng, to_send); - br_ssl_engine_flush(_eng, 0); - flush(); - buf += to_send; - sent_bytes += to_send; - size -= to_send; - } else { - break; - } - } while (size); - - LOG_HEAP_SIZE("_write"); - return sent_bytes; -} - -void WiFiClientSecure_light::setInsecure() { - _insecure = true; -} - -size_t WiFiClientSecure_light::write(const uint8_t *buf, size_t size) { - return _write(buf, size, false); -} - -size_t WiFiClientSecure_light::write_P(PGM_P buf, size_t size) { - return _write((const uint8_t *)buf, size, true); -} - -// We have to manually read and send individual chunks. -size_t WiFiClientSecure_light::write(Stream& stream) { - size_t totalSent = 0; - size_t countRead; - size_t countSent; - - if (!connected() || !_handshake_done) { - DEBUG_BSSL("write: Connect/handshake not completed yet\n"); - return 0; - } - - do { - uint8_t temp[256]; // Temporary chunk size same as ClientContext - countSent = 0; - countRead = stream.readBytes(temp, sizeof(temp)); - if (countRead) { - countSent = _write((const uint8_t*)temp, countRead, true); - totalSent += countSent; - } - yield(); // Feed the WDT - } while ((countSent == countRead) && (countSent > 0)); - return totalSent; -} - -int WiFiClientSecure_light::read(uint8_t *buf, size_t size) { - if (!ctx_present() || !_handshake_done) { - return -1; - } - - int avail = available(); - bool conn = connected(); - if (!avail && conn) { - return 0; // We're still connected, but nothing to read - } - if (!avail && !conn) { - DEBUG_BSSL("read: Not connected, none left available\n"); - return -1; - } - - if (avail) { - // Take data from the recvapp buffer - int to_copy = _recvapp_len < size ? _recvapp_len : size; - memcpy(buf, _recvapp_buf, to_copy); - br_ssl_engine_recvapp_ack(_eng, to_copy); - _recvapp_buf = nullptr; - _recvapp_len = 0; - return to_copy; - } - - if (!conn) { - DEBUG_BSSL("read: Not connected\n"); - return -1; - } - return 0; // If we're connected, no error but no read. -} - -int WiFiClientSecure_light::read() { - uint8_t c; - if (1 == read(&c, 1)) { - return c; - } - DEBUG_BSSL("read: failed\n"); - return -1; -} - -int WiFiClientSecure_light::available() { - if (_recvapp_buf) { - return _recvapp_len; // Anything from last call? - } - _recvapp_buf = nullptr; - _recvapp_len = 0; - if (!ctx_present() || _run_until(BR_SSL_RECVAPP, false) < 0) { - return 0; - } - int st = br_ssl_engine_current_state(_eng); - if (st == BR_SSL_CLOSED) { - return 0; // Nothing leftover, SSL is closed - } - if (st & BR_SSL_RECVAPP) { - _recvapp_buf = br_ssl_engine_recvapp_buf(_eng, &_recvapp_len); - return _recvapp_len; - } - - return 0; -} - -int WiFiClientSecure_light::peek() { - if (!ctx_present() || !available()) { - DEBUG_BSSL("peek: Not connected, none left available\n"); - return -1; - } - if (_recvapp_buf && _recvapp_len) { - return _recvapp_buf[0]; - } - DEBUG_BSSL("peek: No data left\n"); - return -1; -} - -size_t WiFiClientSecure_light::peekBytes(uint8_t *buffer, size_t length) { - size_t to_copy = 0; - if (!ctx_present()) { - DEBUG_BSSL("peekBytes: Not connected\n"); - return 0; - } - - _startMillis = millis(); - while ((available() < (int) length) && ((millis() - _startMillis) < 5000)) { - yield(); - } - - to_copy = _recvapp_len < length ? _recvapp_len : length; - memcpy(buffer, _recvapp_buf, to_copy); - return to_copy; -} - -/* --- Copied almost verbatim from BEARSSL SSL_IO.C --- - Run the engine, until the specified target state is achieved, or - an error occurs. The target state is SENDAPP, RECVAPP, or the - combination of both (the combination matches either). When a match is - achieved, this function returns 0. On error, it returns -1. -*/ -int WiFiClientSecure_light::_run_until(unsigned target, bool blocking) { - //LOG_HEAP_SIZE("_run_until 1"); - if (!ctx_present()) { - DEBUG_BSSL("_run_until: Not connected\n"); - return -1; - } - uint32_t t = millis(); - for (int no_work = 0; blocking || no_work < 2;) { - if (blocking) { - // Only for blocking operations can we afford to yield() - optimistic_yield(100); - } - - if (((int32_t)(millis() - (t + this->_loopTimeout)) >= 0)){ - DEBUG_BSSL("_run_until: Timeout\n"); - setLastError(ERR_TLS_TIMEOUT); - return -1; - } - - int state; - state = br_ssl_engine_current_state(_eng); - if (state & BR_SSL_CLOSED) { - return -1; - } - -#ifdef ESP8266 - if (!(_client->state() == ESTABLISHED) && !WiFiClient::available()) { - return (state & target) ? 0 : -1; - } -#elif defined(ESP32) - if (!_clientConnected() && !WiFiClient::available()) { - return (state & target) ? 0 : -1; - } -#endif - - /* - If there is some record data to send, do it. This takes - precedence over everything else. - */ - if (state & BR_SSL_SENDREC) { - unsigned char *buf; - size_t len; - int wlen; - - buf = br_ssl_engine_sendrec_buf(_eng, &len); - wlen = WiFiClient::write(buf, len); - if (wlen <= 0) { - /* - If we received a close_notify and we - still send something, then we have our - own response close_notify to send, and - the peer is allowed by RFC 5246 not to - wait for it. - */ - return -1; - } - if (wlen > 0) { - br_ssl_engine_sendrec_ack(_eng, wlen); - } - no_work = 0; - continue; - } - - /* - If we reached our target, then we are finished. - */ - if (state & target) { - return 0; - } - /* - If some application data must be read, and we did not - exit, then this means that we are trying to write data, - and that's not possible until the application data is - read. This may happen if using a shared in/out buffer, - and the underlying protocol is not strictly half-duplex. - This is unrecoverable here, so we report an error. - */ - if (state & BR_SSL_RECVAPP) { - DEBUG_BSSL("_run_until: Fatal protocol state\n"); - return -1; - } - /* - If we reached that point, then either we are trying - to read data and there is some, or the engine is stuck - until a new record is obtained. - */ - if (state & BR_SSL_RECVREC) { - if (WiFiClient::available()) { - unsigned char *buf; - size_t len; - int rlen; - - buf = br_ssl_engine_recvrec_buf(_eng, &len); - rlen = WiFiClient::read(buf, len); - if (rlen < 0) { - return -1; - } - if (rlen > 0) { - br_ssl_engine_recvrec_ack(_eng, rlen); - } - no_work = 0; - continue; - } - } - /* - We can reach that point if the target RECVAPP, and - the state contains SENDAPP only. This may happen with - a shared in/out buffer. In that case, we must flush - the buffered data to "make room" for a new incoming - record. - */ - br_ssl_engine_flush(_eng, 0); - - no_work++; // We didn't actually advance here - } - // We only get here if we ran through the loop without getting anything done - return -1; -} - -bool WiFiClientSecure_light::_wait_for_handshake() { - _handshake_done = false; - while (!_handshake_done && _clientConnected()) { - int ret = _run_until(BR_SSL_SENDAPP); - if (ret < 0) { - DEBUG_BSSL("_wait_for_handshake: failed\n"); - break; - } - if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) { - _handshake_done = true; - } - optimistic_yield(1000); - } - return _handshake_done; -} - -static uint8_t htoi (unsigned char c) -{ - if (c>='0' && c <='9') return c - '0'; - else if (c>='A' && c<='F') return 10 + c - 'A'; - else if (c>='a' && c<='f') return 10 + c - 'a'; - else return 255; -} - -extern "C" { - - // see https://stackoverflow.com/questions/6357031/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-in-c - void tohex(unsigned char * in, size_t insz, char * out, size_t outsz) { - unsigned char * pin = in; - static const char * hex = "0123456789ABCDEF"; - char * pout = out; - for(; pin < in+insz; pout +=3, pin++){ - pout[0] = hex[(*pin>>4) & 0xF]; - pout[1] = hex[ *pin & 0xF]; - pout[2] = ':'; - if (pout + 3 - out > outsz){ - /* Better to truncate output string than overflow buffer */ - /* it would be still better to either return a status */ - /* or ensure the target buffer is large enough and it never happen */ - break; - } - } - pout[-1] = 0; - } - - - // BearSSL doesn't define a true insecure decoder, so we make one ourselves - // from the simple parser. It generates the issuer and subject hashes and - // the SHA1 fingerprint, only one (or none!) of which will be used to - // "verify" the certificate. - - // Private x509 decoder state - struct br_x509_pubkeyfingerprint_context { - const br_x509_class *vtable; - bool done_cert; // did we parse the first cert already? - bool fingerprint_all; - uint8_t *pubkey_recv_fingerprint; - const uint8_t *fingerprint1; - const uint8_t *fingerprint2; - unsigned usages; // pubkey usage - br_x509_decoder_context ctx; // defined in BearSSL - }; - - // Callback on the first byte of any certificate - static void pubkeyfingerprint_start_chain(const br_x509_class **ctx, const char *server_name) { - br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; - // Don't process anything but the first certificate in the chain - if (!xc->done_cert) { - br_x509_decoder_init(&xc->ctx, nullptr, nullptr, nullptr, nullptr); - } - (void)server_name; // ignore server name - } - - // Callback for each certificate present in the chain (but only operates - // on the first one by design). - static void pubkeyfingerprint_start_cert(const br_x509_class **ctx, uint32_t length) { - (void) ctx; // do nothing - (void) length; - } - - // Callback for each byte stream in the chain. Only process first cert. - static void pubkeyfingerprint_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) { - br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; - // Don't process anything but the first certificate in the chain - if (!xc->done_cert) { - br_x509_decoder_push(&xc->ctx, (const void*)buf, len); - } - } - - // Callback on individual cert end. - static void pubkeyfingerprint_end_cert(const br_x509_class **ctx) { - br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; - xc->done_cert = true; // first cert already processed - } - - // Add a data element with a u32be length prefix to the sha1 state. - static void sha1_update_len(br_sha1_context *shactx, const void *msg, uint32_t len) { - uint8_t buf[] = {0, 0, 0, 0}; - - buf[0] = (len >> 24) & 0xff; - buf[1] = (len >> 16) & 0xff; - buf[2] = (len >> 8) & 0xff; - buf[3] = (len >> 0) & 0xff; - br_sha1_update(shactx, buf, 4); // length - - br_sha1_update(shactx, msg, len); // message - } - - // Calculate the received fingerprint based on the certificate's public key. - // The public exponent and modulus are length prefixed to avoid security - // vulnerabilities related to ambiguous serialization. Without this, an - // attacker can generate alternative public keys which result in the same - // fingerprint, but are trivial to crack. This works because RSA keys can be - // created with more than two primes, and most numbers, even large ones, can - // be easily factored. - static void pubkeyfingerprint_pubkey_fingerprint(br_x509_pubkeyfingerprint_context *xc) { - if (xc->ctx.pkey.key_type == BR_KEYTYPE_RSA) { - br_rsa_public_key rsakey = xc->ctx.pkey.key.rsa; - - br_sha1_context shactx; - - br_sha1_init(&shactx); - - // The tag string doesn't really matter, but it should differ depending on - // key type. For RSA it's a fixed string. - sha1_update_len(&shactx, "ssh-rsa", 7); // tag - sha1_update_len(&shactx, rsakey.e, rsakey.elen); // exponent - sha1_update_len(&shactx, rsakey.n, rsakey.nlen); // modulus - - br_sha1_out(&shactx, xc->pubkey_recv_fingerprint); // copy to fingerprint - } - #ifndef ESP8266 - else if (xc->ctx.pkey.key_type == BR_KEYTYPE_EC) { - br_ec_public_key eckey = xc->ctx.pkey.key.ec; - - br_sha1_context shactx; - - br_sha1_init(&shactx); - - // The tag string doesn't really matter, but it should differ depending on - // key type. For ECDSA it's a fixed string. - sha1_update_len(&shactx, "ecdsa", 5); // tag - int32_t curve = htonl(eckey.curve); - sha1_update_len(&shactx, &curve, 4); // curve id as int32be - sha1_update_len(&shactx, eckey.q, eckey.qlen); // public point - } - #endif - else { - // We don't support anything else, so just set the fingerprint to all zeros. - memset(xc->pubkey_recv_fingerprint, 0, 20); - } - } - - // Callback when complete chain has been parsed. - // Return 0 on validation success, !0 on validation error - static unsigned pubkeyfingerprint_end_chain(const br_x509_class **ctx) { - br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; - pubkeyfingerprint_pubkey_fingerprint(xc); - if (!xc->fingerprint_all) { - if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint1, 20)) { - return 0; - } - if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint2, 20)) { - return 0; - } - return 1; // no match, error - } else { - // Default (no validation at all) or no errors in prior checks = success. - return 0; - } - } - - // Return the public key from the validator (set by x509_minimal) - static const br_x509_pkey *pubkeyfingerprint_get_pkey(const br_x509_class *const *ctx, unsigned *usages) { - const br_x509_pubkeyfingerprint_context *xc = (const br_x509_pubkeyfingerprint_context *)ctx; - - if (usages != NULL) { - *usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN; // I said we were insecure! - } - return &xc->ctx.pkey; - } - - // Set up the x509 insecure data structures for BearSSL core to use. - void br_x509_pubkeyfingerprint_init(br_x509_pubkeyfingerprint_context *ctx, - const uint8_t *fingerprint1, const uint8_t *fingerprint2, - uint8_t *recv_fingerprint, - bool fingerprint_all) { - static const br_x509_class br_x509_pubkeyfingerprint_vtable PROGMEM = { - sizeof(br_x509_pubkeyfingerprint_context), - pubkeyfingerprint_start_chain, - pubkeyfingerprint_start_cert, - pubkeyfingerprint_append, - pubkeyfingerprint_end_cert, - pubkeyfingerprint_end_chain, - pubkeyfingerprint_get_pkey - }; - - memset(ctx, 0, sizeof * ctx); - ctx->vtable = &br_x509_pubkeyfingerprint_vtable; - ctx->done_cert = false; - ctx->fingerprint1 = fingerprint1; - ctx->fingerprint2 = fingerprint2; - ctx->pubkey_recv_fingerprint = recv_fingerprint; - ctx->fingerprint_all = fingerprint_all; - } - - static const uint16_t suites[] = { - BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - }; - static const uint16_t suites_RSA_ONLY[] = { - BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - }; - - // Default initializion for our SSL clients - static void br_ssl_client_base_init(br_ssl_client_context *cc, bool _rsa_only) { - br_ssl_client_zero(cc); - // forbid SSL renegotiation, as we free the Private Key after handshake - br_ssl_engine_add_flags(&cc->eng, BR_OPT_NO_RENEGOTIATION); - - br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); -#if defined(ESP32) || (defined(ESP8266) && defined(USE_MQTT_TLS_ECDSA)) - if (_rsa_only) { - br_ssl_engine_set_suites(&cc->eng, suites_RSA_ONLY, (sizeof suites_RSA_ONLY) / (sizeof suites_RSA_ONLY[0])); - } else { - br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); - } -#else - br_ssl_engine_set_suites(&cc->eng, suites_RSA_ONLY, (sizeof suites_RSA_ONLY) / (sizeof suites_RSA_ONLY[0])); -#endif - br_ssl_client_set_default_rsapub(cc); - br_ssl_engine_set_default_rsavrfy(&cc->eng); - - // install hashes - br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); - br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - - // AES CTR/GCM small version, not contstant time (we don't really care here as there is no TPM anyways) - br_ssl_engine_set_gcm(&cc->eng, &br_sslrec_in_gcm_vtable, &br_sslrec_out_gcm_vtable); - br_ssl_engine_set_aes_ctr(&cc->eng, &br_aes_small_ctr_vtable); - br_ssl_engine_set_ghash(&cc->eng, &br_ghash_ctmul32); - - // we support only P256 EC curve for AWS IoT, no EC curve for Letsencrypt unless forced - br_ssl_engine_set_ec(&cc->eng, &br_ec_p256_m15); -#if defined(ESP32) || (defined(ESP8266) && defined(USE_MQTT_TLS_ECDSA)) - br_ssl_engine_set_ecdsa(&cc->eng, &br_ecdsa_i15_vrfy_asn1); -#endif - } -} - -// Called by connect() to do the actual SSL setup and handshake. -// Returns if the SSL handshake succeeded. -bool WiFiClientSecure_light::_connectSSL(const char* hostName) { - // Validation context, either full CA validation or checking only fingerprints - - br_x509_minimal_context *x509_minimal = nullptr; - br_x509_pubkeyfingerprint_context *x509_insecure = nullptr; - - LOG_HEAP_SIZE("_connectSSL.start"); - - do { // used to exit on Out of Memory error and keep all cleanup code at the same place - // ============================================================ - // allocate Thunk stack, move to alternate stack and initialize -#ifdef ESP8266 - stack_thunk_light_set_size(_rsa_only); - stack_thunk_light_add_ref(); -#endif // ESP8266 - LOG_HEAP_SIZE("Thunk allocated"); - DEBUG_BSSL("_connectSSL: start connection\n"); - _freeSSL(); - clearLastError(); -#ifdef ESP8266 - if (!stack_thunk_light_get_stack_bot()) break; -#endif // ESP8266 - - _ctx_present = true; - _eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr - - br_ssl_client_base_init(_sc.get(), _rsa_only); - if (_alpn_names && _alpn_num > 0) { - br_ssl_engine_set_protocol_names(_eng, _alpn_names, _alpn_num); - } - - // ============================================================ - // Allocatte and initialize Decoder Context - LOG_HEAP_SIZE("_connectSSL before DecoderContext allocation"); - // Only failure possible in the installation is OOM - - x509_insecure = (br_x509_pubkeyfingerprint_context*) malloc(sizeof(br_x509_pubkeyfingerprint_context)); - //x509_insecure = std::unique_ptr(new br_x509_pubkeyfingerprint_context); - if (!x509_insecure) break; - br_x509_pubkeyfingerprint_init(x509_insecure, _fingerprint1, _fingerprint2, _recv_fingerprint, _fingerprint_any); - br_ssl_engine_set_x509(_eng, &x509_insecure->vtable); - - if (!_insecure) { - x509_minimal = (br_x509_minimal_context*) malloc(sizeof(br_x509_minimal_context)); - if (!x509_minimal) break; - br_x509_minimal_init(x509_minimal, &br_sha256_vtable, _ta_P, _ta_size); - br_x509_minimal_set_rsa(x509_minimal, br_ssl_engine_get_rsavrfy(_eng)); - br_x509_minimal_set_hash(x509_minimal, br_sha256_ID, &br_sha256_vtable); -#if defined(ESP32) || (defined(ESP8266) && defined(USE_MQTT_TLS_ECDSA)) - if (!_rsa_only) { - br_x509_minimal_set_ecdsa(x509_minimal, &br_ec_all_m15, &br_ecdsa_i15_vrfy_asn1); - } -#endif - br_ssl_engine_set_x509(_eng, &x509_minimal->vtable); - uint32_t now = UtcTime(); - uint32_t cfg_time = CfgTime(); - if (cfg_time > now) { now = cfg_time; } - br_x509_minimal_set_time(x509_minimal, now / 86400 + 719528, now % 86400); - } - LOG_HEAP_SIZE("_connectSSL after DecoderContext allocation"); - - // ============================================================ - // Set send/receive buffers - br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size); - - // ============================================================ - // allocate Private key if needed, only if USE_MQTT_CLIENT_CERT - LOG_HEAP_SIZE("_connectSSL before PrivKey allocation"); - #if defined(USE_MQTT_CLIENT_CERT) - // ============================================================ - // Set the EC Private Key, only USE_MQTT_CLIENT_CERT - // limited to P256 curve - br_ssl_client_set_single_ec(_sc.get(), _chain_P, 1, - _sk_ec_P, _allowed_usages, - _cert_issuer_key_type, &br_ec_p256_m15, br_ecdsa_sign_asn1_get_default()); - #endif // USE_MQTT_CLIENT_CERT - - // ============================================================ - // Start TLS connection, ALL - if (!br_ssl_client_reset(_sc.get(), hostName, 0)) break; - - auto ret = _wait_for_handshake(); - #ifdef DEBUG_ESP_SSL - if (!ret) { - DEBUG_BSSL("Couldn't connect. Error = %d\n", getLastError()); - } else { - DEBUG_BSSL("Connected! MFLNStatus = %d\n", getMFLNStatus()); - } - #endif - LOG_HEAP_SIZE("_connectSSL.end"); -#ifdef ESP8266 - _max_thunkstack_use = stack_thunk_light_get_max_usage(); - stack_thunk_light_del_ref(); - //stack_thunk_light_repaint(); - LOG_HEAP_SIZE("_connectSSL.end, freeing StackThunk"); -#endif // ESP8266 - - free(x509_minimal); // safe to call if nullptr - free(x509_insecure); - LOG_HEAP_SIZE("_connectSSL after release of Priv Key"); - return ret; - } while (0); - - // ============================================================ - // if we arrived here, this means we had an OOM error, cleaning up - setLastError(ERR_OOM); - DEBUG_BSSL("_connectSSL: Out of memory\n"); -#ifdef ESP8266 - stack_thunk_light_del_ref(); -#endif - free(x509_minimal); // safe to call if nullptr - free(x509_insecure); - LOG_HEAP_SIZE("_connectSSL clean_on_error"); - return false; -} - -}; - -#include "t_bearssl_tasmota_config.h" - -#endif // USE_TLS +/* + WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries + - Mostly compatible with Arduino WiFi shield library and standard + WiFiClient/ServerSecure (except for certificate handling). + + Copyright (C) 2021 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 "tasmota_options.h" +#ifdef USE_TLS + +// #define DEBUG_TLS +// #define DEBUG_ESP_SSL + +#define LWIP_INTERNAL + +#include +#include +#include + +#include "WiFiClientSecureLightBearSSL.h" // needs to be before "ESP8266WiFi.h" to avoid conflict with Arduino headers +#include "ESP8266WiFi.h" +#include "WiFiHelper.h" +#include "WiFiClient.h" +#include "StackThunk_light.h" +#include "lwip/opt.h" +#include "lwip/ip.h" +#include "lwip/tcp.h" +#include "lwip/inet.h" +#include "lwip/netif.h" +#ifdef ESP8266 + #include + #include "c_types.h" +#endif + +#if __has_include("core_version.h") // ESP32 Stage has no core_version.h file. Disable include via PlatformIO Option +#include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_7_1) +#endif // ESP32_STAGE +#undef DEBUG_TLS + +#ifdef DEBUG_TLS +#include "coredecls.h" +#define LOG_HEAP_SIZE(a) _Log_heap_size(a) +void _Log_heap_size(const char *msg) { +#ifdef ESP8266 + register uint32_t *sp asm("a1"); + int freestack = 4 * (sp - g_pcont->stack); + Serial.printf("%s %d, Fragmentation=%d, Thunkstack=%d, Free stack=%d, FreeContStack=%d\n", + msg, ESP.getFreeHeap(), ESP.getHeapFragmentation(), stack_thunk_light_get_max_usage(), + freestack, ESP.getFreeContStack()); +#elif defined(ESP32) + Serial.printf("> Heap %s = %d\n", msg, uxTaskGetStackHighWaterMark(nullptr)); +#endif +} +#else +#define LOG_HEAP_SIZE(a) +#endif + +// get UTC time from Tasmota +extern uint32_t UtcTime(void); +extern uint32_t CfgTime(void); + +#ifdef ESP8266 // Stack thunk is not needed with ESP32 +// Stack thunked versions of calls +// Initially in BearSSLHelpers.h +extern "C" { +extern unsigned char *thunk_light_br_ssl_engine_recvapp_buf( const br_ssl_engine_context *cc, size_t *len); +extern void thunk_light_br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len); +extern unsigned char *thunk_light_br_ssl_engine_recvrec_buf( const br_ssl_engine_context *cc, size_t *len); +extern void thunk_light_br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len); +extern unsigned char *thunk_light_br_ssl_engine_sendapp_buf( const br_ssl_engine_context *cc, size_t *len); +extern void thunk_light_br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len); +extern unsigned char *thunk_light_br_ssl_engine_sendrec_buf( const br_ssl_engine_context *cc, size_t *len); +extern void thunk_light_br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len); +}; + +// Second stack thunked helpers +make_stack_thunk_light(br_ssl_engine_recvapp_ack); +make_stack_thunk_light(br_ssl_engine_recvapp_buf); +make_stack_thunk_light(br_ssl_engine_recvrec_ack); +make_stack_thunk_light(br_ssl_engine_recvrec_buf); +make_stack_thunk_light(br_ssl_engine_sendapp_ack); +make_stack_thunk_light(br_ssl_engine_sendapp_buf); +make_stack_thunk_light(br_ssl_engine_sendrec_ack); +make_stack_thunk_light(br_ssl_engine_sendrec_buf); + +// create new version of Thunk function to store on SYS stack +// unless the Thunk was initialized. Thanks to AES128 GCM, we can keep +// symetric processing on the stack +void min_br_ssl_engine_recvapp_ack(br_ssl_engine_context *cc, size_t len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_recvapp_ack(cc, len); + } else { + return br_ssl_engine_recvapp_ack(cc, len); + } +} +unsigned char *min_br_ssl_engine_recvapp_buf(const br_ssl_engine_context *cc, size_t *len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_recvapp_buf(cc, len); + } else { + return br_ssl_engine_recvapp_buf(cc, len); + } +} +void min_br_ssl_engine_recvrec_ack(br_ssl_engine_context *cc, size_t len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_recvrec_ack(cc, len); + } else { + return br_ssl_engine_recvrec_ack(cc, len); + } +} +unsigned char *min_br_ssl_engine_recvrec_buf(const br_ssl_engine_context *cc, size_t *len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_recvrec_buf(cc, len); + } else { + return br_ssl_engine_recvrec_buf(cc, len); + } +} +void min_br_ssl_engine_sendapp_ack(br_ssl_engine_context *cc, size_t len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_sendapp_ack(cc, len); + } else { + return br_ssl_engine_sendapp_ack(cc, len); + } +} +unsigned char *min_br_ssl_engine_sendapp_buf(const br_ssl_engine_context *cc, size_t *len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_sendapp_buf(cc, len); + } else { + return br_ssl_engine_sendapp_buf(cc, len); + } +} +void min_br_ssl_engine_sendrec_ack(br_ssl_engine_context *cc, size_t len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_sendrec_ack(cc, len); + } else { + return br_ssl_engine_sendrec_ack(cc, len); + } +} +unsigned char *min_br_ssl_engine_sendrec_buf(const br_ssl_engine_context *cc, size_t *len) { + if (stack_thunk_light_get_refcnt()) { + return thunk_light_br_ssl_engine_sendrec_buf(cc, len); + } else { + return br_ssl_engine_sendrec_buf(cc, len); + } +} + +// Use min_ instead of original thunk_ +#define br_ssl_engine_recvapp_ack min_br_ssl_engine_recvapp_ack +#define br_ssl_engine_recvapp_buf min_br_ssl_engine_recvapp_buf +#define br_ssl_engine_recvrec_ack min_br_ssl_engine_recvrec_ack +#define br_ssl_engine_recvrec_buf min_br_ssl_engine_recvrec_buf +#define br_ssl_engine_sendapp_ack min_br_ssl_engine_sendapp_ack +#define br_ssl_engine_sendapp_buf min_br_ssl_engine_sendapp_buf +#define br_ssl_engine_sendrec_ack min_br_ssl_engine_sendrec_ack +#define br_ssl_engine_sendrec_buf min_br_ssl_engine_sendrec_buf + +#endif // ESP8266 + +//#define DEBUG_ESP_SSL +#ifdef DEBUG_ESP_SSL +//#define DEBUG_BSSL(fmt, ...) DEBUG_ESP_PORT.printf_P((PGM_P)PSTR( "BSSL:" fmt), ## __VA_ARGS__) +#define DEBUG_BSSL(fmt, ...) Serial.printf(fmt, ## __VA_ARGS__) +#else +#define DEBUG_BSSL(...) +#endif + +namespace BearSSL { + +void WiFiClientSecure_light::_clear() { + // TLS handshake may take more than the 5 second default timeout + _timeout = 10000; // 10 seconds max, it should never go over 6 seconds + + _sc = nullptr; + _ctx_present = false; + _eng = nullptr; + _iobuf_in = nullptr; + _iobuf_out = nullptr; + setBufferSizes(1024, 1024); // reasonable minimum + _handshake_done = false; + _last_error = 0; + _recvapp_buf = nullptr; + _recvapp_len = 0; + _insecure = false; // set to true when calling setPubKeyFingerprint() + _rsa_only = true; // for now we disable ECDSA by default + _fingerprint_any = true; // by default accept all fingerprints + _fingerprint1 = nullptr; + _fingerprint2 = nullptr; + _chain_P = nullptr; + _sk_ec_P = nullptr; + _ta_P = nullptr; + _ta_size = 0; + _max_thunkstack_use = 0; + _alpn_names = nullptr; + _alpn_num = 0; +} + +// Constructor +WiFiClientSecure_light::WiFiClientSecure_light(int recv, int xmit) : WiFiClient() { + _clear(); + // LOG_HEAP_SIZE("StackThunk before"); + //stack_thunk_light_add_ref(); + // LOG_HEAP_SIZE("StackThunk after"); + // now finish the setup + setBufferSizes(recv, xmit); // reasonable minimum + allocateBuffers(); +} + +WiFiClientSecure_light::~WiFiClientSecure_light() { +#ifdef ESP8266 + if (_client) { + _client->unref(); + _client = nullptr; + } +#elif defined(ESP32) + stop(); +#endif + //_cipher_list = nullptr; // std::shared will free if last reference + _freeSSL(); +} + +void WiFiClientSecure_light::allocateBuffers(void) { + // We prefer to allocate all buffers at start, rather than lazy allocation and deallocation + // in the long run it avoids heap fragmentation and improves stability + LOG_HEAP_SIZE("allocateBuffers before"); + _sc = std::make_shared(); + LOG_HEAP_SIZE("allocateBuffers ClientContext"); + _iobuf_in = std::shared_ptr(new unsigned char[_iobuf_in_size], std::default_delete()); + _iobuf_out = std::shared_ptr(new unsigned char[_iobuf_out_size], std::default_delete()); + LOG_HEAP_SIZE("allocateBuffers after"); +} + +void WiFiClientSecure_light::setClientECCert(const br_x509_certificate *cert, const br_ec_private_key *sk, + unsigned allowed_usages, unsigned cert_issuer_key_type) { + _chain_P = cert; + _sk_ec_P = sk; + _allowed_usages = allowed_usages; + _cert_issuer_key_type = cert_issuer_key_type; +} + +void WiFiClientSecure_light::setTrustAnchor(const br_x509_trust_anchor *ta, size_t ta_size) { + _ta_P = ta; + _ta_size = ta_size; +} + +void WiFiClientSecure_light::setBufferSizes(int recv, int xmit) { + // Following constants taken from bearssl/src/ssl/ssl_engine.c (not exported unfortunately) + const int MAX_OUT_OVERHEAD = 85; + const int MAX_IN_OVERHEAD = 325; + + // The data buffers must be between 512B and 16KB + recv = std::max(512, std::min(16384, recv)); + xmit = std::max(512, std::min(16384, xmit)); + + // Add in overhead for SSL protocol + recv += MAX_IN_OVERHEAD; + xmit += MAX_OUT_OVERHEAD; + _iobuf_in_size = recv; + _iobuf_out_size = xmit; +} + +#ifdef ESP8266 +bool WiFiClientSecure_light::stop(unsigned int maxWaitMs) { + bool ret = WiFiClient::stop(maxWaitMs); // calls our virtual flush() + _freeSSL(); + return ret; +} + +bool WiFiClientSecure_light::flush(unsigned int maxWaitMs) { + (void) _run_until(BR_SSL_SENDAPP); + return WiFiClient::flush(maxWaitMs); +} +#elif defined(ESP32) +void WiFiClientSecure_light::stop(void) { + WiFiClient::stop(); // calls our virtual flush() + _freeSSL(); +} + +void WiFiClientSecure_light::flush(void) { + (void) _run_until(BR_SSL_SENDAPP); + // don't call flush on ESP32 - its behavior is different and empties the receive buffer - which we don't want +} +#endif + +#ifdef ESP32 +int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port, int32_t timeout) { + DEBUG_BSSL("connect(%s,%d)", ip.toString().c_str(), port); + clearLastError(); + if (!WiFiClient::connect(ip, port, timeout)) { + setLastError(ERR_TCP_CONNECT); + return 0; + } + bool success = _connectSSL(_domain.isEmpty() ? nullptr : _domain.c_str()); + if (!success) { stop(); } + return success; +} +#else // ESP32 +int WiFiClientSecure_light::connect(IPAddress ip, uint16_t port) { + DEBUG_BSSL("connect(%s,%d)", ip.toString().c_str(), port); + clearLastError(); + if (!WiFiClient::connect(ip, port)) { + setLastError(ERR_TCP_CONNECT); + return 0; + } + bool success = _connectSSL(_domain.isEmpty() ? nullptr : _domain.c_str()); + if (!success) { stop(); } + return success; +} +#endif + +#ifdef ESP32 +int WiFiClientSecure_light::connect(const char* name, uint16_t port, int32_t timeout) { + DEBUG_BSSL("connect(%s,%d)\n", name, port); + IPAddress remote_addr; + clearLastError(); + if (!WiFiHelper::hostByName(name, remote_addr)) { + DEBUG_BSSL("connect: Name loopup failure\n"); + setLastError(ERR_CANT_RESOLVE_IP); + return 0; + } + DEBUG_BSSL("connect(%s,%d)\n", remote_addr.toString().c_str(), port); + if (!WiFiClient::connect(remote_addr, port, timeout)) { + DEBUG_BSSL("connect: Unable to connect TCP socket\n"); + _last_error = ERR_TCP_CONNECT; + return 0; + } + LOG_HEAP_SIZE("Before calling _connectSSL"); + return _connectSSL(name); +} +#else // ESP32 +int WiFiClientSecure_light::connect(const char* name, uint16_t port) { + DEBUG_BSSL("connect(%s,%d)\n", name, port); + IPAddress remote_addr; + clearLastError(); + if (!WiFiHelper::hostByName(name, remote_addr)) { + DEBUG_BSSL("connect: Name loopup failure\n"); + setLastError(ERR_CANT_RESOLVE_IP); + return 0; + } + DEBUG_BSSL("connect(%s,%d)\n", remote_addr.toString().c_str(), port); + if (!WiFiClient::connect(remote_addr, port)) { + DEBUG_BSSL("connect: Unable to connect TCP socket\n"); + _last_error = ERR_TCP_CONNECT; + return 0; + } + LOG_HEAP_SIZE("Before calling _connectSSL"); + return _connectSSL(name); +} +#endif + +void WiFiClientSecure_light::_freeSSL() { + _ctx_present = false; + _recvapp_buf = nullptr; + _recvapp_len = 0; + // This connection is toast + _handshake_done = false; +} + +bool WiFiClientSecure_light::_clientConnected() { +#ifdef ESP8266 + return (_client && _client->state() == ESTABLISHED); +#elif defined(ESP32) + return WiFiClient::connected(); +#endif +} + +uint8_t WiFiClientSecure_light::connected() { + if (available() || (_clientConnected() && _handshake_done)) { + return true; + } + return false; +} + +size_t WiFiClientSecure_light::_write(const uint8_t *buf, size_t size, bool pmem) { + size_t sent_bytes = 0; + + if (!connected() || !size || !_handshake_done) { + return 0; + } + + do { + // Ensure we yield if we need multiple fragments to avoid WDT + if (sent_bytes) { + optimistic_yield(1000); + } + + // Get BearSSL to a state where we can send + if (_run_until(BR_SSL_SENDAPP) < 0) { + break; + } + + if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) { + size_t sendapp_len; + unsigned char *sendapp_buf = br_ssl_engine_sendapp_buf(_eng, &sendapp_len); + int to_send = size > sendapp_len ? sendapp_len : size; + if (pmem) { + memcpy_P(sendapp_buf, buf, to_send); + } else { + memcpy(sendapp_buf, buf, to_send); + } + br_ssl_engine_sendapp_ack(_eng, to_send); + br_ssl_engine_flush(_eng, 0); + flush(); + buf += to_send; + sent_bytes += to_send; + size -= to_send; + } else { + break; + } + } while (size); + + LOG_HEAP_SIZE("_write"); + return sent_bytes; +} + +void WiFiClientSecure_light::setInsecure() { + _insecure = true; +} + +size_t WiFiClientSecure_light::write(const uint8_t *buf, size_t size) { + return _write(buf, size, false); +} + +size_t WiFiClientSecure_light::write_P(PGM_P buf, size_t size) { + return _write((const uint8_t *)buf, size, true); +} + +// We have to manually read and send individual chunks. +size_t WiFiClientSecure_light::write(Stream& stream) { + size_t totalSent = 0; + size_t countRead; + size_t countSent; + + if (!connected() || !_handshake_done) { + DEBUG_BSSL("write: Connect/handshake not completed yet\n"); + return 0; + } + + do { + uint8_t temp[256]; // Temporary chunk size same as ClientContext + countSent = 0; + countRead = stream.readBytes(temp, sizeof(temp)); + if (countRead) { + countSent = _write((const uint8_t*)temp, countRead, true); + totalSent += countSent; + } + yield(); // Feed the WDT + } while ((countSent == countRead) && (countSent > 0)); + return totalSent; +} + +int WiFiClientSecure_light::read(uint8_t *buf, size_t size) { + if (!ctx_present() || !_handshake_done) { + return -1; + } + + int avail = available(); + bool conn = connected(); + if (!avail && conn) { + return 0; // We're still connected, but nothing to read + } + if (!avail && !conn) { + DEBUG_BSSL("read: Not connected, none left available\n"); + return -1; + } + + if (avail) { + // Take data from the recvapp buffer + int to_copy = _recvapp_len < size ? _recvapp_len : size; + memcpy(buf, _recvapp_buf, to_copy); + br_ssl_engine_recvapp_ack(_eng, to_copy); + _recvapp_buf = nullptr; + _recvapp_len = 0; + return to_copy; + } + + if (!conn) { + DEBUG_BSSL("read: Not connected\n"); + return -1; + } + return 0; // If we're connected, no error but no read. +} + +int WiFiClientSecure_light::read() { + uint8_t c; + if (1 == read(&c, 1)) { + return c; + } + DEBUG_BSSL("read: failed\n"); + return -1; +} + +int WiFiClientSecure_light::available() { + if (_recvapp_buf) { + return _recvapp_len; // Anything from last call? + } + _recvapp_buf = nullptr; + _recvapp_len = 0; + if (!ctx_present() || _run_until(BR_SSL_RECVAPP, false) < 0) { + return 0; + } + int st = br_ssl_engine_current_state(_eng); + if (st == BR_SSL_CLOSED) { + return 0; // Nothing leftover, SSL is closed + } + if (st & BR_SSL_RECVAPP) { + _recvapp_buf = br_ssl_engine_recvapp_buf(_eng, &_recvapp_len); + return _recvapp_len; + } + + return 0; +} + +int WiFiClientSecure_light::peek() { + if (!ctx_present() || !available()) { + DEBUG_BSSL("peek: Not connected, none left available\n"); + return -1; + } + if (_recvapp_buf && _recvapp_len) { + return _recvapp_buf[0]; + } + DEBUG_BSSL("peek: No data left\n"); + return -1; +} + +size_t WiFiClientSecure_light::peekBytes(uint8_t *buffer, size_t length) { + size_t to_copy = 0; + if (!ctx_present()) { + DEBUG_BSSL("peekBytes: Not connected\n"); + return 0; + } + + _startMillis = millis(); + while ((available() < (int) length) && ((millis() - _startMillis) < 5000)) { + yield(); + } + + to_copy = _recvapp_len < length ? _recvapp_len : length; + memcpy(buffer, _recvapp_buf, to_copy); + return to_copy; +} + +/* --- Copied almost verbatim from BEARSSL SSL_IO.C --- + Run the engine, until the specified target state is achieved, or + an error occurs. The target state is SENDAPP, RECVAPP, or the + combination of both (the combination matches either). When a match is + achieved, this function returns 0. On error, it returns -1. +*/ +int WiFiClientSecure_light::_run_until(unsigned target, bool blocking) { + //LOG_HEAP_SIZE("_run_until 1"); + if (!ctx_present()) { + DEBUG_BSSL("_run_until: Not connected\n"); + return -1; + } + uint32_t t = millis(); + for (int no_work = 0; blocking || no_work < 2;) { + if (blocking) { + // Only for blocking operations can we afford to yield() + optimistic_yield(100); + } + + if (((int32_t)(millis() - (t + this->_loopTimeout)) >= 0)){ + DEBUG_BSSL("_run_until: Timeout\n"); + setLastError(ERR_TLS_TIMEOUT); + return -1; + } + + int state; + state = br_ssl_engine_current_state(_eng); + if (state & BR_SSL_CLOSED) { + return -1; + } + +#ifdef ESP8266 + if (!(_client->state() == ESTABLISHED) && !WiFiClient::available()) { + return (state & target) ? 0 : -1; + } +#elif defined(ESP32) + if (!_clientConnected() && !WiFiClient::available()) { + return (state & target) ? 0 : -1; + } +#endif + + /* + If there is some record data to send, do it. This takes + precedence over everything else. + */ + if (state & BR_SSL_SENDREC) { + unsigned char *buf; + size_t len; + int wlen; + + buf = br_ssl_engine_sendrec_buf(_eng, &len); + wlen = WiFiClient::write(buf, len); + if (wlen <= 0) { + /* + If we received a close_notify and we + still send something, then we have our + own response close_notify to send, and + the peer is allowed by RFC 5246 not to + wait for it. + */ + return -1; + } + if (wlen > 0) { + br_ssl_engine_sendrec_ack(_eng, wlen); + } + no_work = 0; + continue; + } + + /* + If we reached our target, then we are finished. + */ + if (state & target) { + return 0; + } + /* + If some application data must be read, and we did not + exit, then this means that we are trying to write data, + and that's not possible until the application data is + read. This may happen if using a shared in/out buffer, + and the underlying protocol is not strictly half-duplex. + This is unrecoverable here, so we report an error. + */ + if (state & BR_SSL_RECVAPP) { + DEBUG_BSSL("_run_until: Fatal protocol state\n"); + return -1; + } + /* + If we reached that point, then either we are trying + to read data and there is some, or the engine is stuck + until a new record is obtained. + */ + if (state & BR_SSL_RECVREC) { + if (WiFiClient::available()) { + unsigned char *buf; + size_t len; + int rlen; + + buf = br_ssl_engine_recvrec_buf(_eng, &len); + rlen = WiFiClient::read(buf, len); + if (rlen < 0) { + return -1; + } + if (rlen > 0) { + br_ssl_engine_recvrec_ack(_eng, rlen); + } + no_work = 0; + continue; + } + } + /* + We can reach that point if the target RECVAPP, and + the state contains SENDAPP only. This may happen with + a shared in/out buffer. In that case, we must flush + the buffered data to "make room" for a new incoming + record. + */ + br_ssl_engine_flush(_eng, 0); + + no_work++; // We didn't actually advance here + } + // We only get here if we ran through the loop without getting anything done + return -1; +} + +bool WiFiClientSecure_light::_wait_for_handshake() { + _handshake_done = false; + while (!_handshake_done && _clientConnected()) { + int ret = _run_until(BR_SSL_SENDAPP); + if (ret < 0) { + DEBUG_BSSL("_wait_for_handshake: failed\n"); + break; + } + if (br_ssl_engine_current_state(_eng) & BR_SSL_SENDAPP) { + _handshake_done = true; + } + optimistic_yield(1000); + } + return _handshake_done; +} + +static uint8_t htoi (unsigned char c) +{ + if (c>='0' && c <='9') return c - '0'; + else if (c>='A' && c<='F') return 10 + c - 'A'; + else if (c>='a' && c<='f') return 10 + c - 'a'; + else return 255; +} + +extern "C" { + + // see https://stackoverflow.com/questions/6357031/how-do-you-convert-a-byte-array-to-a-hexadecimal-string-in-c + void tohex(unsigned char * in, size_t insz, char * out, size_t outsz) { + unsigned char * pin = in; + static const char * hex = "0123456789ABCDEF"; + char * pout = out; + for(; pin < in+insz; pout +=3, pin++){ + pout[0] = hex[(*pin>>4) & 0xF]; + pout[1] = hex[ *pin & 0xF]; + pout[2] = ':'; + if (pout + 3 - out > outsz){ + /* Better to truncate output string than overflow buffer */ + /* it would be still better to either return a status */ + /* or ensure the target buffer is large enough and it never happen */ + break; + } + } + pout[-1] = 0; + } + + + // BearSSL doesn't define a true insecure decoder, so we make one ourselves + // from the simple parser. It generates the issuer and subject hashes and + // the SHA1 fingerprint, only one (or none!) of which will be used to + // "verify" the certificate. + + // Private x509 decoder state + struct br_x509_pubkeyfingerprint_context { + const br_x509_class *vtable; + bool done_cert; // did we parse the first cert already? + bool fingerprint_all; + uint8_t *pubkey_recv_fingerprint; + const uint8_t *fingerprint1; + const uint8_t *fingerprint2; + unsigned usages; // pubkey usage + br_x509_decoder_context ctx; // defined in BearSSL + }; + + // Callback on the first byte of any certificate + static void pubkeyfingerprint_start_chain(const br_x509_class **ctx, const char *server_name) { + br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; + // Don't process anything but the first certificate in the chain + if (!xc->done_cert) { + br_x509_decoder_init(&xc->ctx, nullptr, nullptr, nullptr, nullptr); + } + (void)server_name; // ignore server name + } + + // Callback for each certificate present in the chain (but only operates + // on the first one by design). + static void pubkeyfingerprint_start_cert(const br_x509_class **ctx, uint32_t length) { + (void) ctx; // do nothing + (void) length; + } + + // Callback for each byte stream in the chain. Only process first cert. + static void pubkeyfingerprint_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) { + br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; + // Don't process anything but the first certificate in the chain + if (!xc->done_cert) { + br_x509_decoder_push(&xc->ctx, (const void*)buf, len); + } + } + + // Callback on individual cert end. + static void pubkeyfingerprint_end_cert(const br_x509_class **ctx) { + br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; + xc->done_cert = true; // first cert already processed + } + + // Add a data element with a u32be length prefix to the sha1 state. + static void sha1_update_len(br_sha1_context *shactx, const void *msg, uint32_t len) { + uint8_t buf[] = {0, 0, 0, 0}; + + buf[0] = (len >> 24) & 0xff; + buf[1] = (len >> 16) & 0xff; + buf[2] = (len >> 8) & 0xff; + buf[3] = (len >> 0) & 0xff; + br_sha1_update(shactx, buf, 4); // length + + br_sha1_update(shactx, msg, len); // message + } + + // Calculate the received fingerprint based on the certificate's public key. + // The public exponent and modulus are length prefixed to avoid security + // vulnerabilities related to ambiguous serialization. Without this, an + // attacker can generate alternative public keys which result in the same + // fingerprint, but are trivial to crack. This works because RSA keys can be + // created with more than two primes, and most numbers, even large ones, can + // be easily factored. + static void pubkeyfingerprint_pubkey_fingerprint(br_x509_pubkeyfingerprint_context *xc) { + if (xc->ctx.pkey.key_type == BR_KEYTYPE_RSA) { + br_rsa_public_key rsakey = xc->ctx.pkey.key.rsa; + + br_sha1_context shactx; + + br_sha1_init(&shactx); + + // The tag string doesn't really matter, but it should differ depending on + // key type. For RSA it's a fixed string. + sha1_update_len(&shactx, "ssh-rsa", 7); // tag + sha1_update_len(&shactx, rsakey.e, rsakey.elen); // exponent + sha1_update_len(&shactx, rsakey.n, rsakey.nlen); // modulus + + br_sha1_out(&shactx, xc->pubkey_recv_fingerprint); // copy to fingerprint + } + #ifndef ESP8266 + else if (xc->ctx.pkey.key_type == BR_KEYTYPE_EC) { + br_ec_public_key eckey = xc->ctx.pkey.key.ec; + + br_sha1_context shactx; + + br_sha1_init(&shactx); + + // The tag string doesn't really matter, but it should differ depending on + // key type. For ECDSA it's a fixed string. + sha1_update_len(&shactx, "ecdsa", 5); // tag + int32_t curve = htonl(eckey.curve); + sha1_update_len(&shactx, &curve, 4); // curve id as int32be + sha1_update_len(&shactx, eckey.q, eckey.qlen); // public point + } + #endif + else { + // We don't support anything else, so just set the fingerprint to all zeros. + memset(xc->pubkey_recv_fingerprint, 0, 20); + } + } + + // Callback when complete chain has been parsed. + // Return 0 on validation success, !0 on validation error + static unsigned pubkeyfingerprint_end_chain(const br_x509_class **ctx) { + br_x509_pubkeyfingerprint_context *xc = (br_x509_pubkeyfingerprint_context *)ctx; + pubkeyfingerprint_pubkey_fingerprint(xc); + if (!xc->fingerprint_all) { + if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint1, 20)) { + return 0; + } + if (0 == memcmp_P(xc->pubkey_recv_fingerprint, xc->fingerprint2, 20)) { + return 0; + } + return 1; // no match, error + } else { + // Default (no validation at all) or no errors in prior checks = success. + return 0; + } + } + + // Return the public key from the validator (set by x509_minimal) + static const br_x509_pkey *pubkeyfingerprint_get_pkey(const br_x509_class *const *ctx, unsigned *usages) { + const br_x509_pubkeyfingerprint_context *xc = (const br_x509_pubkeyfingerprint_context *)ctx; + + if (usages != NULL) { + *usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN; // I said we were insecure! + } + return &xc->ctx.pkey; + } + + // Set up the x509 insecure data structures for BearSSL core to use. + void br_x509_pubkeyfingerprint_init(br_x509_pubkeyfingerprint_context *ctx, + const uint8_t *fingerprint1, const uint8_t *fingerprint2, + uint8_t *recv_fingerprint, + bool fingerprint_all) { + static const br_x509_class br_x509_pubkeyfingerprint_vtable PROGMEM = { + sizeof(br_x509_pubkeyfingerprint_context), + pubkeyfingerprint_start_chain, + pubkeyfingerprint_start_cert, + pubkeyfingerprint_append, + pubkeyfingerprint_end_cert, + pubkeyfingerprint_end_chain, + pubkeyfingerprint_get_pkey + }; + + memset(ctx, 0, sizeof * ctx); + ctx->vtable = &br_x509_pubkeyfingerprint_vtable; + ctx->done_cert = false; + ctx->fingerprint1 = fingerprint1; + ctx->fingerprint2 = fingerprint2; + ctx->pubkey_recv_fingerprint = recv_fingerprint; + ctx->fingerprint_all = fingerprint_all; + } + + static const uint16_t suites[] = { + BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + }; + static const uint16_t suites_RSA_ONLY[] = { + BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + }; + + // Default initializion for our SSL clients + static void br_ssl_client_base_init(br_ssl_client_context *cc, bool _rsa_only) { + br_ssl_client_zero(cc); + // forbid SSL renegotiation, as we free the Private Key after handshake + br_ssl_engine_add_flags(&cc->eng, BR_OPT_NO_RENEGOTIATION); + + br_ssl_engine_set_versions(&cc->eng, BR_TLS12, BR_TLS12); +#if defined(ESP32) || (defined(ESP8266) && defined(USE_MQTT_TLS_ECDSA)) + if (_rsa_only) { + br_ssl_engine_set_suites(&cc->eng, suites_RSA_ONLY, (sizeof suites_RSA_ONLY) / (sizeof suites_RSA_ONLY[0])); + } else { + br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); + } +#else + br_ssl_engine_set_suites(&cc->eng, suites_RSA_ONLY, (sizeof suites_RSA_ONLY) / (sizeof suites_RSA_ONLY[0])); +#endif + br_ssl_client_set_default_rsapub(cc); + br_ssl_engine_set_default_rsavrfy(&cc->eng); + + // install hashes + br_ssl_engine_set_hash(&cc->eng, br_sha256_ID, &br_sha256_vtable); + br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); + + // AES CTR/GCM small version, not contstant time (we don't really care here as there is no TPM anyways) + br_ssl_engine_set_gcm(&cc->eng, &br_sslrec_in_gcm_vtable, &br_sslrec_out_gcm_vtable); + br_ssl_engine_set_aes_ctr(&cc->eng, &br_aes_small_ctr_vtable); + br_ssl_engine_set_ghash(&cc->eng, &br_ghash_ctmul32); + + // we support only P256 EC curve for AWS IoT, no EC curve for Letsencrypt unless forced + br_ssl_engine_set_ec(&cc->eng, &br_ec_p256_m15); +#if defined(ESP32) || (defined(ESP8266) && defined(USE_MQTT_TLS_ECDSA)) + br_ssl_engine_set_ecdsa(&cc->eng, &br_ecdsa_i15_vrfy_asn1); +#endif + } +} + +// Called by connect() to do the actual SSL setup and handshake. +// Returns if the SSL handshake succeeded. +bool WiFiClientSecure_light::_connectSSL(const char* hostName) { + // Validation context, either full CA validation or checking only fingerprints + + br_x509_minimal_context *x509_minimal = nullptr; + br_x509_pubkeyfingerprint_context *x509_insecure = nullptr; + + LOG_HEAP_SIZE("_connectSSL.start"); + + do { // used to exit on Out of Memory error and keep all cleanup code at the same place + // ============================================================ + // allocate Thunk stack, move to alternate stack and initialize +#ifdef ESP8266 + stack_thunk_light_set_size(_rsa_only); + stack_thunk_light_add_ref(); +#endif // ESP8266 + LOG_HEAP_SIZE("Thunk allocated"); + DEBUG_BSSL("_connectSSL: start connection\n"); + _freeSSL(); + clearLastError(); +#ifdef ESP8266 + if (!stack_thunk_light_get_stack_bot()) break; +#endif // ESP8266 + + _ctx_present = true; + _eng = &_sc->eng; // Allocation/deallocation taken care of by the _sc shared_ptr + + br_ssl_client_base_init(_sc.get(), _rsa_only); + if (_alpn_names && _alpn_num > 0) { + br_ssl_engine_set_protocol_names(_eng, _alpn_names, _alpn_num); + } + + // ============================================================ + // Allocatte and initialize Decoder Context + LOG_HEAP_SIZE("_connectSSL before DecoderContext allocation"); + // Only failure possible in the installation is OOM + + x509_insecure = (br_x509_pubkeyfingerprint_context*) malloc(sizeof(br_x509_pubkeyfingerprint_context)); + //x509_insecure = std::unique_ptr(new br_x509_pubkeyfingerprint_context); + if (!x509_insecure) break; + br_x509_pubkeyfingerprint_init(x509_insecure, _fingerprint1, _fingerprint2, _recv_fingerprint, _fingerprint_any); + br_ssl_engine_set_x509(_eng, &x509_insecure->vtable); + + if (!_insecure) { + x509_minimal = (br_x509_minimal_context*) malloc(sizeof(br_x509_minimal_context)); + if (!x509_minimal) break; + br_x509_minimal_init(x509_minimal, &br_sha256_vtable, _ta_P, _ta_size); + br_x509_minimal_set_rsa(x509_minimal, br_ssl_engine_get_rsavrfy(_eng)); + br_x509_minimal_set_hash(x509_minimal, br_sha256_ID, &br_sha256_vtable); +#if defined(ESP32) || (defined(ESP8266) && defined(USE_MQTT_TLS_ECDSA)) + if (!_rsa_only) { + br_x509_minimal_set_ecdsa(x509_minimal, &br_ec_all_m15, &br_ecdsa_i15_vrfy_asn1); + } +#endif + br_ssl_engine_set_x509(_eng, &x509_minimal->vtable); + uint32_t now = UtcTime(); + uint32_t cfg_time = CfgTime(); + if (cfg_time > now) { now = cfg_time; } + br_x509_minimal_set_time(x509_minimal, now / 86400 + 719528, now % 86400); + } + LOG_HEAP_SIZE("_connectSSL after DecoderContext allocation"); + + // ============================================================ + // Set send/receive buffers + br_ssl_engine_set_buffers_bidi(_eng, _iobuf_in.get(), _iobuf_in_size, _iobuf_out.get(), _iobuf_out_size); + + // ============================================================ + // allocate Private key if needed, only if USE_MQTT_CLIENT_CERT + LOG_HEAP_SIZE("_connectSSL before PrivKey allocation"); + #if defined(USE_MQTT_CLIENT_CERT) + // ============================================================ + // Set the EC Private Key, only USE_MQTT_CLIENT_CERT + // limited to P256 curve + br_ssl_client_set_single_ec(_sc.get(), _chain_P, 1, + _sk_ec_P, _allowed_usages, + _cert_issuer_key_type, &br_ec_p256_m15, br_ecdsa_sign_asn1_get_default()); + #endif // USE_MQTT_CLIENT_CERT + + // ============================================================ + // Start TLS connection, ALL + if (!br_ssl_client_reset(_sc.get(), hostName, 0)) break; + + auto ret = _wait_for_handshake(); + #ifdef DEBUG_ESP_SSL + if (!ret) { + DEBUG_BSSL("Couldn't connect. Error = %d\n", getLastError()); + } else { + DEBUG_BSSL("Connected! MFLNStatus = %d\n", getMFLNStatus()); + } + #endif + LOG_HEAP_SIZE("_connectSSL.end"); +#ifdef ESP8266 + _max_thunkstack_use = stack_thunk_light_get_max_usage(); + stack_thunk_light_del_ref(); + //stack_thunk_light_repaint(); + LOG_HEAP_SIZE("_connectSSL.end, freeing StackThunk"); +#endif // ESP8266 + + free(x509_minimal); // safe to call if nullptr + free(x509_insecure); + LOG_HEAP_SIZE("_connectSSL after release of Priv Key"); + return ret; + } while (0); + + // ============================================================ + // if we arrived here, this means we had an OOM error, cleaning up + setLastError(ERR_OOM); + DEBUG_BSSL("_connectSSL: Out of memory\n"); +#ifdef ESP8266 + stack_thunk_light_del_ref(); +#endif + free(x509_minimal); // safe to call if nullptr + free(x509_insecure); + LOG_HEAP_SIZE("_connectSSL clean_on_error"); + return false; +} + +}; + +#include "t_bearssl_tasmota_config.h" + +#endif // USE_TLS diff --git a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h index dab8ca4f7..53ff1cc5e 100755 --- a/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h +++ b/lib/lib_ssl/tls_mini/src/WiFiClientSecureLightBearSSL.h @@ -1,309 +1,309 @@ -/* - WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries - - Mostly compatible with Arduino WiFi shield library and standard - WiFiClient/ServerSecure (except for certificate handling). - - Copyright (C) 2021 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 -*/ - -#if __has_include("core_version.h") // ESP32 Stage has no core_version.h file. Disable include via PlatformIO Option -#include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_7_1) -#endif // ESP32_STAGE - -#ifndef wificlientlightbearssl_h -#define wificlientlightbearssl_h -#ifdef USE_TLS -#include -#include "WiFiClient.h" -#include - -namespace BearSSL { - -class WiFiClientSecure_light : public WiFiClient { - public: - WiFiClientSecure_light(int recv, int xmit); - ~WiFiClientSecure_light() override; - - void allocateBuffers(void); - - #ifdef ESP32 // the method to override in ESP32 has timeout argument default #define WIFI_CLIENT_DEF_CONN_TIMEOUT_MS (3000) - int connect(IPAddress ip, uint16_t port, int32_t timeout = 3000) override; - int connect(const char* name, uint16_t port, int32_t timeout = 3000) override; - #else - int connect(IPAddress ip, uint16_t port) override; - int connect(const char* name, uint16_t port) override; - #endif - - uint8_t connected() override; - size_t write(const uint8_t *buf, size_t size) override; - #ifdef ESP8266 - size_t write_P(PGM_P buf, size_t size) override; - #else - size_t write_P(PGM_P buf, size_t size); - #endif - size_t write(const char *buf) { - return write((const uint8_t*)buf, strlen(buf)); - } - size_t write_P(const char *buf) { - return write_P((PGM_P)buf, strlen_P(buf)); - } - size_t write(Stream& stream); // Note this is not virtual - int read(uint8_t *buf, size_t size) override; - int available() override; - int read() override; - int peek() override; - #ifdef ESP8266 - size_t peekBytes(uint8_t *buffer, size_t length) override; - bool flush(unsigned int maxWaitMs); - bool stop(unsigned int maxWaitMs); - void flush() override { (void)flush(0); } - void stop() override { (void)stop(0); } - #else - size_t peekBytes(uint8_t *buffer, size_t length); - void flush() override; - void stop() override; - #endif - - // Only check SHA1 fingerprint of public key - void setPubKeyFingerprint(const uint8_t *f1, const uint8_t *f2, - bool f_any = false) { - _fingerprint1 = f1; - _fingerprint2 = f2; - _fingerprint_any = f_any; - _insecure = true; - _rsa_only = true; // if fingerprint, we limit to RSA only - } - void setRSAOnly(bool rsa_only) { - _rsa_only = rsa_only; - } - const uint8_t * getRecvPubKeyFingerprint(void) { - return _recv_fingerprint; - } - - void setClientECCert(const br_x509_certificate *cert, const br_ec_private_key *sk, - unsigned allowed_usages, unsigned cert_issuer_key_type); - - void setTrustAnchor(const br_x509_trust_anchor *ta, size_t ta_size); - - void setALPN(const char **names, size_t num) { - // set ALPN extensions, used mostly by AWS IoT on port 443. Need to be static pointers - _alpn_names = names; - _alpn_num = num; - } - - // Sets the requested buffer size for transmit and receive - void setBufferSizes(int recv, int xmit); - - // Returns whether MFLN negotiation for the above buffer sizes succeeded (after connection) - int getMFLNStatus() { - return connected() && br_ssl_engine_get_mfln_negotiated(_eng); - } - - int32_t getLastError(void) { - if (_last_error) { - return _last_error; - } else { - return br_ssl_engine_last_error(_eng); - } - } - int32_t getLastCipherSuite(void) { - return _eng->session.cipher_suite; - } - inline void setLastError(int32_t err) { - _last_error = err; - } - inline void clearLastError(void) { - _last_error = 0; - } - inline size_t getMaxThunkStackUse(void) { - return _max_thunkstack_use; - } - - void setInsecure(); - void setECDSA(bool ecdsa) { - _rsa_only = !ecdsa; - }; - - void setDomainName(const char * domain) { - _domain = domain; - } - - private: - uint32_t _loopTimeout=10000; - void _clear(); - bool _ctx_present; - std::shared_ptr _sc; - inline bool ctx_present() { - return _ctx_present; - } - br_ssl_engine_context *_eng; // &_sc->eng, to allow for client or server contexts - std::shared_ptr _iobuf_in; - std::shared_ptr _iobuf_out; - int _iobuf_in_size; - int _iobuf_out_size; - bool _handshake_done; - uint64_t _last_error; - - bool _fingerprint_any; // accept all fingerprints - bool _insecure; // force fingerprint - bool _rsa_only; // restrict to RSA only key exchange (no ECDSA - enabled to force RSA fingerprints) - const uint8_t *_fingerprint1; // fingerprint1 to be checked against - const uint8_t *_fingerprint2; // fingerprint2 to be checked against - uint8_t _recv_fingerprint[20]; // fingerprint received - - unsigned char *_recvapp_buf; - size_t _recvapp_len; - bool _clientConnected(); // Is the underlying socket alive? - bool _connectSSL(const char *hostName); // Do initial SSL handshake - void _freeSSL(); - int _run_until(unsigned target, bool blocking = true); - size_t _write(const uint8_t *buf, size_t size, bool pmem); - bool _wait_for_handshake(); // Sets and return the _handshake_done after connecting - - // Optional client certificate - const br_x509_certificate *_chain_P; // PROGMEM certificate - const br_ec_private_key *_sk_ec_P; // PROGMEM private key - const br_x509_trust_anchor *_ta_P; // PROGMEM server CA - size_t _ta_size; - unsigned _allowed_usages; - unsigned _cert_issuer_key_type; - - // record the maximum use of ThunkStack for monitoring - size_t _max_thunkstack_use; - - // domain name (string) that will be used with SNI when the address provided is already resolved - String _domain; - - // ALPN - const char ** _alpn_names; - size_t _alpn_num; - -}; - -#define ERR_OOM -1000 -#define ERR_CANT_RESOLVE_IP -1001 -#define ERR_TCP_CONNECT -1002 -// #define ERR_MISSING_EC_KEY -1003 // deprecated, AWS IoT is not called if the private key is not present -// #define ERR_MISSING_CA -1004 // deprecated -#define ERR_TLS_TIMEOUT -1005 - -// For reference, BearSSL error codes: -// #define BR_ERR_OK 0 -// #define BR_ERR_BAD_PARAM 1 -// #define BR_ERR_BAD_STATE 2 -// #define BR_ERR_UNSUPPORTED_VERSION 3 -// #define BR_ERR_BAD_VERSION 4 -// #define BR_ERR_BAD_LENGTH 5 -// #define BR_ERR_TOO_LARGE 6 -// #define BR_ERR_BAD_MAC 7 -// #define BR_ERR_NO_RANDOM 8 -// #define BR_ERR_UNKNOWN_TYPE 9 -// #define BR_ERR_UNEXPECTED 10 -// #define BR_ERR_BAD_CCS 12 -// #define BR_ERR_BAD_ALERT 13 -// #define BR_ERR_BAD_HANDSHAKE 14 -// #define BR_ERR_OVERSIZED_ID 15 -// #define BR_ERR_BAD_CIPHER_SUITE 16 -// #define BR_ERR_BAD_COMPRESSION 17 -// #define BR_ERR_BAD_FRAGLEN 18 -// #define BR_ERR_BAD_SECRENEG 19 -// #define BR_ERR_EXTRA_EXTENSION 20 -// #define BR_ERR_BAD_SNI 21 -// #define BR_ERR_BAD_HELLO_DONE 22 -// #define BR_ERR_LIMIT_EXCEEDED 23 -// #define BR_ERR_BAD_FINISHED 24 -// #define BR_ERR_RESUME_MISMATCH 25 -// #define BR_ERR_INVALID_ALGORITHM 26 -// #define BR_ERR_BAD_SIGNATURE 27 -// #define BR_ERR_WRONG_KEY_USAGE 28 -// #define BR_ERR_NO_CLIENT_AUTH 29 -// #define BR_ERR_IO 31 -// #define BR_ERR_RECV_FATAL_ALERT 256 -// #define BR_ERR_SEND_FATAL_ALERT 512 -// #define BR_ERR_X509_OK 32 -// #define BR_ERR_X509_INVALID_VALUE 33 -// #define BR_ERR_X509_TRUNCATED 34 -// #define BR_ERR_X509_EMPTY_CHAIN 35 -// #define BR_ERR_X509_INNER_TRUNC 36 -// #define BR_ERR_X509_BAD_TAG_CLASS 37 -// #define BR_ERR_X509_BAD_TAG_VALUE 38 -// #define BR_ERR_X509_INDEFINITE_LENGTH 39 -// #define BR_ERR_X509_EXTRA_ELEMENT 40 -// #define BR_ERR_X509_UNEXPECTED 41 -// #define BR_ERR_X509_NOT_CONSTRUCTED 42 -// #define BR_ERR_X509_NOT_PRIMITIVE 43 -// #define BR_ERR_X509_PARTIAL_BYTE 44 -// #define BR_ERR_X509_BAD_BOOLEAN 45 -// #define BR_ERR_X509_OVERFLOW 46 -// #define BR_ERR_X509_BAD_DN 47 -// #define BR_ERR_X509_BAD_TIME 48 -// #define BR_ERR_X509_UNSUPPORTED 49 -// #define BR_ERR_X509_LIMIT_EXCEEDED 50 -// #define BR_ERR_X509_WRONG_KEY_TYPE 51 -// #define BR_ERR_X509_BAD_SIGNATURE 52 -// #define BR_ERR_X509_TIME_UNKNOWN 53 -// #define BR_ERR_X509_EXPIRED 54 -// #define BR_ERR_X509_DN_MISMATCH 55 -// #define BR_ERR_X509_BAD_SERVER_NAME 56 -// #define BR_ERR_X509_CRITICAL_EXTENSION 57 -// #define BR_ERR_X509_NOT_CA 58 -// #define BR_ERR_X509_FORBIDDEN_KEY_USAGE 59 -// #define BR_ERR_X509_WEAK_PUBLIC_KEY 60 -// #define BR_ERR_X509_NOT_TRUSTED 62 - -// Alert types for TLSContentType.ALERT messages -// See RFC 8466, section B.2 - -// CLOSE_NOTIFY = 0 -// UNEXPECTED_MESSAGE = 10 -// BAD_RECORD_MAC = 20 -// DECRYPTION_FAILED = 21 -// RECORD_OVERFLOW = 22 -// DECOMPRESSION_FAILURE = 30 -// HANDSHAKE_FAILURE = 40 -// NO_CERTIFICATE = 41 -// BAD_CERTIFICATE = 42 -// UNSUPPORTED_CERTIFICATE = 43 -// CERTIFICATE_REVOKED = 44 -// CERTIFICATE_EXPIRED = 45 -// CERTIFICATE_UNKNOWN = 46 -// ILLEGAL_PARAMETER = 47 -// UNKNOWN_CA = 48 -// ACCESS_DENIED = 49 -// DECODE_ERROR = 50 -// DECRYPT_ERROR = 51 -// EXPORT_RESTRICTION = 60 -// PROTOCOL_VERSION = 70 -// INSUFFICIENT_SECURITY = 71 -// INTERNAL_ERROR = 80 -// INAPPROPRIATE_FALLBACK = 86 -// USER_CANCELED = 90 -// NO_RENEGOTIATION = 100 -// MISSING_EXTENSION = 109 -// UNSUPPORTED_EXTENSION = 110 -// CERTIFICATE_UNOBTAINABLE = 111 -// UNRECOGNIZED_NAME = 112 -// BAD_CERTIFICATE_STATUS_RESPONSE = 113 -// BAD_CERTIFICATE_HASH_VALUE = 114 -// UNKNOWN_PSK_IDENTITY = 115 -// CERTIFICATE_REQUIRED = 116 -// NO_APPLICATION_PROTOCOL = 120 - -}; - -#endif // USE_TLS -#endif // wificlientlightbearssl_h +/* + WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries + - Mostly compatible with Arduino WiFi shield library and standard + WiFiClient/ServerSecure (except for certificate handling). + + Copyright (C) 2021 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 +*/ + +#if __has_include("core_version.h") // ESP32 Stage has no core_version.h file. Disable include via PlatformIO Option +#include // Arduino_Esp8266 version information (ARDUINO_ESP8266_RELEASE and ARDUINO_ESP8266_RELEASE_2_7_1) +#endif // ESP32_STAGE + +#ifndef wificlientlightbearssl_h +#define wificlientlightbearssl_h +#ifdef USE_TLS +#include +#include "WiFiClient.h" +#include + +namespace BearSSL { + +class WiFiClientSecure_light : public WiFiClient { + public: + WiFiClientSecure_light(int recv, int xmit); + ~WiFiClientSecure_light() override; + + void allocateBuffers(void); + + #ifdef ESP32 // the method to override in ESP32 has timeout argument default #define WIFI_CLIENT_DEF_CONN_TIMEOUT_MS (3000) + int connect(IPAddress ip, uint16_t port, int32_t timeout = 3000) override; + int connect(const char* name, uint16_t port, int32_t timeout = 3000) override; + #else + int connect(IPAddress ip, uint16_t port) override; + int connect(const char* name, uint16_t port) override; + #endif + + uint8_t connected() override; + size_t write(const uint8_t *buf, size_t size) override; + #ifdef ESP8266 + size_t write_P(PGM_P buf, size_t size) override; + #else + size_t write_P(PGM_P buf, size_t size); + #endif + size_t write(const char *buf) { + return write((const uint8_t*)buf, strlen(buf)); + } + size_t write_P(const char *buf) { + return write_P((PGM_P)buf, strlen_P(buf)); + } + size_t write(Stream& stream); // Note this is not virtual + int read(uint8_t *buf, size_t size) override; + int available() override; + int read() override; + int peek() override; + #ifdef ESP8266 + size_t peekBytes(uint8_t *buffer, size_t length) override; + bool flush(unsigned int maxWaitMs); + bool stop(unsigned int maxWaitMs); + void flush() override { (void)flush(0); } + void stop() override { (void)stop(0); } + #else + size_t peekBytes(uint8_t *buffer, size_t length); + void flush() override; + void stop() override; + #endif + + // Only check SHA1 fingerprint of public key + void setPubKeyFingerprint(const uint8_t *f1, const uint8_t *f2, + bool f_any = false) { + _fingerprint1 = f1; + _fingerprint2 = f2; + _fingerprint_any = f_any; + _insecure = true; + _rsa_only = true; // if fingerprint, we limit to RSA only + } + void setRSAOnly(bool rsa_only) { + _rsa_only = rsa_only; + } + const uint8_t * getRecvPubKeyFingerprint(void) { + return _recv_fingerprint; + } + + void setClientECCert(const br_x509_certificate *cert, const br_ec_private_key *sk, + unsigned allowed_usages, unsigned cert_issuer_key_type); + + void setTrustAnchor(const br_x509_trust_anchor *ta, size_t ta_size); + + void setALPN(const char **names, size_t num) { + // set ALPN extensions, used mostly by AWS IoT on port 443. Need to be static pointers + _alpn_names = names; + _alpn_num = num; + } + + // Sets the requested buffer size for transmit and receive + void setBufferSizes(int recv, int xmit); + + // Returns whether MFLN negotiation for the above buffer sizes succeeded (after connection) + int getMFLNStatus() { + return connected() && br_ssl_engine_get_mfln_negotiated(_eng); + } + + int32_t getLastError(void) { + if (_last_error) { + return _last_error; + } else { + return br_ssl_engine_last_error(_eng); + } + } + int32_t getLastCipherSuite(void) { + return _eng->session.cipher_suite; + } + inline void setLastError(int32_t err) { + _last_error = err; + } + inline void clearLastError(void) { + _last_error = 0; + } + inline size_t getMaxThunkStackUse(void) { + return _max_thunkstack_use; + } + + void setInsecure(); + void setECDSA(bool ecdsa) { + _rsa_only = !ecdsa; + }; + + void setDomainName(const char * domain) { + _domain = domain; + } + + private: + uint32_t _loopTimeout=10000; + void _clear(); + bool _ctx_present; + std::shared_ptr _sc; + inline bool ctx_present() { + return _ctx_present; + } + br_ssl_engine_context *_eng; // &_sc->eng, to allow for client or server contexts + std::shared_ptr _iobuf_in; + std::shared_ptr _iobuf_out; + int _iobuf_in_size; + int _iobuf_out_size; + bool _handshake_done; + uint64_t _last_error; + + bool _fingerprint_any; // accept all fingerprints + bool _insecure; // force fingerprint + bool _rsa_only; // restrict to RSA only key exchange (no ECDSA - enabled to force RSA fingerprints) + const uint8_t *_fingerprint1; // fingerprint1 to be checked against + const uint8_t *_fingerprint2; // fingerprint2 to be checked against + uint8_t _recv_fingerprint[20]; // fingerprint received + + unsigned char *_recvapp_buf; + size_t _recvapp_len; + bool _clientConnected(); // Is the underlying socket alive? + bool _connectSSL(const char *hostName); // Do initial SSL handshake + void _freeSSL(); + int _run_until(unsigned target, bool blocking = true); + size_t _write(const uint8_t *buf, size_t size, bool pmem); + bool _wait_for_handshake(); // Sets and return the _handshake_done after connecting + + // Optional client certificate + const br_x509_certificate *_chain_P; // PROGMEM certificate + const br_ec_private_key *_sk_ec_P; // PROGMEM private key + const br_x509_trust_anchor *_ta_P; // PROGMEM server CA + size_t _ta_size; + unsigned _allowed_usages; + unsigned _cert_issuer_key_type; + + // record the maximum use of ThunkStack for monitoring + size_t _max_thunkstack_use; + + // domain name (string) that will be used with SNI when the address provided is already resolved + String _domain; + + // ALPN + const char ** _alpn_names; + size_t _alpn_num; + +}; + +#define ERR_OOM -1000 +#define ERR_CANT_RESOLVE_IP -1001 +#define ERR_TCP_CONNECT -1002 +// #define ERR_MISSING_EC_KEY -1003 // deprecated, AWS IoT is not called if the private key is not present +// #define ERR_MISSING_CA -1004 // deprecated +#define ERR_TLS_TIMEOUT -1005 + +// For reference, BearSSL error codes: +// #define BR_ERR_OK 0 +// #define BR_ERR_BAD_PARAM 1 +// #define BR_ERR_BAD_STATE 2 +// #define BR_ERR_UNSUPPORTED_VERSION 3 +// #define BR_ERR_BAD_VERSION 4 +// #define BR_ERR_BAD_LENGTH 5 +// #define BR_ERR_TOO_LARGE 6 +// #define BR_ERR_BAD_MAC 7 +// #define BR_ERR_NO_RANDOM 8 +// #define BR_ERR_UNKNOWN_TYPE 9 +// #define BR_ERR_UNEXPECTED 10 +// #define BR_ERR_BAD_CCS 12 +// #define BR_ERR_BAD_ALERT 13 +// #define BR_ERR_BAD_HANDSHAKE 14 +// #define BR_ERR_OVERSIZED_ID 15 +// #define BR_ERR_BAD_CIPHER_SUITE 16 +// #define BR_ERR_BAD_COMPRESSION 17 +// #define BR_ERR_BAD_FRAGLEN 18 +// #define BR_ERR_BAD_SECRENEG 19 +// #define BR_ERR_EXTRA_EXTENSION 20 +// #define BR_ERR_BAD_SNI 21 +// #define BR_ERR_BAD_HELLO_DONE 22 +// #define BR_ERR_LIMIT_EXCEEDED 23 +// #define BR_ERR_BAD_FINISHED 24 +// #define BR_ERR_RESUME_MISMATCH 25 +// #define BR_ERR_INVALID_ALGORITHM 26 +// #define BR_ERR_BAD_SIGNATURE 27 +// #define BR_ERR_WRONG_KEY_USAGE 28 +// #define BR_ERR_NO_CLIENT_AUTH 29 +// #define BR_ERR_IO 31 +// #define BR_ERR_RECV_FATAL_ALERT 256 +// #define BR_ERR_SEND_FATAL_ALERT 512 +// #define BR_ERR_X509_OK 32 +// #define BR_ERR_X509_INVALID_VALUE 33 +// #define BR_ERR_X509_TRUNCATED 34 +// #define BR_ERR_X509_EMPTY_CHAIN 35 +// #define BR_ERR_X509_INNER_TRUNC 36 +// #define BR_ERR_X509_BAD_TAG_CLASS 37 +// #define BR_ERR_X509_BAD_TAG_VALUE 38 +// #define BR_ERR_X509_INDEFINITE_LENGTH 39 +// #define BR_ERR_X509_EXTRA_ELEMENT 40 +// #define BR_ERR_X509_UNEXPECTED 41 +// #define BR_ERR_X509_NOT_CONSTRUCTED 42 +// #define BR_ERR_X509_NOT_PRIMITIVE 43 +// #define BR_ERR_X509_PARTIAL_BYTE 44 +// #define BR_ERR_X509_BAD_BOOLEAN 45 +// #define BR_ERR_X509_OVERFLOW 46 +// #define BR_ERR_X509_BAD_DN 47 +// #define BR_ERR_X509_BAD_TIME 48 +// #define BR_ERR_X509_UNSUPPORTED 49 +// #define BR_ERR_X509_LIMIT_EXCEEDED 50 +// #define BR_ERR_X509_WRONG_KEY_TYPE 51 +// #define BR_ERR_X509_BAD_SIGNATURE 52 +// #define BR_ERR_X509_TIME_UNKNOWN 53 +// #define BR_ERR_X509_EXPIRED 54 +// #define BR_ERR_X509_DN_MISMATCH 55 +// #define BR_ERR_X509_BAD_SERVER_NAME 56 +// #define BR_ERR_X509_CRITICAL_EXTENSION 57 +// #define BR_ERR_X509_NOT_CA 58 +// #define BR_ERR_X509_FORBIDDEN_KEY_USAGE 59 +// #define BR_ERR_X509_WEAK_PUBLIC_KEY 60 +// #define BR_ERR_X509_NOT_TRUSTED 62 + +// Alert types for TLSContentType.ALERT messages +// See RFC 8466, section B.2 + +// CLOSE_NOTIFY = 0 +// UNEXPECTED_MESSAGE = 10 +// BAD_RECORD_MAC = 20 +// DECRYPTION_FAILED = 21 +// RECORD_OVERFLOW = 22 +// DECOMPRESSION_FAILURE = 30 +// HANDSHAKE_FAILURE = 40 +// NO_CERTIFICATE = 41 +// BAD_CERTIFICATE = 42 +// UNSUPPORTED_CERTIFICATE = 43 +// CERTIFICATE_REVOKED = 44 +// CERTIFICATE_EXPIRED = 45 +// CERTIFICATE_UNKNOWN = 46 +// ILLEGAL_PARAMETER = 47 +// UNKNOWN_CA = 48 +// ACCESS_DENIED = 49 +// DECODE_ERROR = 50 +// DECRYPT_ERROR = 51 +// EXPORT_RESTRICTION = 60 +// PROTOCOL_VERSION = 70 +// INSUFFICIENT_SECURITY = 71 +// INTERNAL_ERROR = 80 +// INAPPROPRIATE_FALLBACK = 86 +// USER_CANCELED = 90 +// NO_RENEGOTIATION = 100 +// MISSING_EXTENSION = 109 +// UNSUPPORTED_EXTENSION = 110 +// CERTIFICATE_UNOBTAINABLE = 111 +// UNRECOGNIZED_NAME = 112 +// BAD_CERTIFICATE_STATUS_RESPONSE = 113 +// BAD_CERTIFICATE_HASH_VALUE = 114 +// UNKNOWN_PSK_IDENTITY = 115 +// CERTIFICATE_REQUIRED = 116 +// NO_APPLICATION_PROTOCOL = 120 + +}; + +#endif // USE_TLS +#endif // wificlientlightbearssl_h diff --git a/lib/libesp32/ESP-Mail-Client/LICENSE b/lib/libesp32/ESP-Mail-Client/LICENSE index c22fc2301..b0a6d88c4 100644 --- a/lib/libesp32/ESP-Mail-Client/LICENSE +++ b/lib/libesp32/ESP-Mail-Client/LICENSE @@ -1,21 +1,21 @@ -MIT License - -Copyright (c) 2023 mobizt - -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. +MIT License + +Copyright (c) 2023 mobizt + +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/lib/libesp32/ESP-Mail-Client/examples/IMAP/ACL/ACL.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/ACL/ACL.ino index 145e9815c..a23bcf510 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/ACL/ACL.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/ACL/ACL.ino @@ -1,258 +1,258 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt - */ - -// This example shows how to get, set the access control list. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - IMAP_Rights_List acl_list; - - Serial.println("\nGet ACLs..."); - - if (!imap.getACL("INBOX", &acl_list)) - { - Serial.println("Get ACLs failed"); - } - else - { - Serial.println("ACL..."); - - for (size_t i = 0; i < acl_list.size(); i++) - { - MailClient.printf("Identifier: %s, Rights: ", acl_list[i].identifier.c_str()); - String r; - for (int j = esp_mail_imap_rights_administer; j < esp_mail_imap_rights_maxType; j++) - { - if (acl_list[i].rights[j]) - r += (char)('a' + j); - } - - Serial.println(r); - } - } - - IMAP_Rights_Info acl; - acl.identifier = "Steve"; - acl.rights[esp_mail_imap_rights_administer] = true; - acl.rights[esp_mail_imap_rights_create] = true; - acl.rights[esp_mail_imap_rights_create_c] = true; - acl.rights[esp_mail_imap_rights_delete_message] = true; - acl.rights[esp_mail_imap_rights_delete_d] = true; - acl.rights[esp_mail_imap_rights_delete_mailbox] = true; - acl.rights[esp_mail_imap_rights_expunge] = true; - acl.rights[esp_mail_imap_rights_lookup] = true; - acl.rights[esp_mail_imap_rights_insert] = true; - acl.rights[esp_mail_imap_rights_post] = true; - acl.rights[esp_mail_imap_rights_read] = true; - acl.rights[esp_mail_imap_rights_write] = true; - acl.rights[esp_mail_imap_rights_seen] = true; - - Serial.println("\nSet ACLs..."); - - if (!imap.setACL("INBOX", &acl)) - { - Serial.println("Set ACLs failed"); - } - else - { - Serial.println("Set ACLs success"); - } - - Serial.println("\nGet my rights..."); - - if (!imap.myRights("INBOX", &acl)) - { - Serial.println("Set my rights failed"); - } - else - { - Serial.print("Rights: "); - - String r; - for (int i = esp_mail_imap_rights_administer; i < esp_mail_imap_rights_maxType; i++) - { - if (acl.rights[i]) - r += (char)('a' + i); - } - - Serial.println(r); - } - - Serial.println("\nDelete ACLs..."); - - if (!imap.deleteACL("INBOX", "Steve")) - { - Serial.println("Set ACLs failed"); - } - else - { - Serial.println("Delete ACLs success"); - } - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +// This example shows how to get, set the access control list. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + IMAP_Rights_List acl_list; + + Serial.println("\nGet ACLs..."); + + if (!imap.getACL("INBOX", &acl_list)) + { + Serial.println("Get ACLs failed"); + } + else + { + Serial.println("ACL..."); + + for (size_t i = 0; i < acl_list.size(); i++) + { + MailClient.printf("Identifier: %s, Rights: ", acl_list[i].identifier.c_str()); + String r; + for (int j = esp_mail_imap_rights_administer; j < esp_mail_imap_rights_maxType; j++) + { + if (acl_list[i].rights[j]) + r += (char)('a' + j); + } + + Serial.println(r); + } + } + + IMAP_Rights_Info acl; + acl.identifier = "Steve"; + acl.rights[esp_mail_imap_rights_administer] = true; + acl.rights[esp_mail_imap_rights_create] = true; + acl.rights[esp_mail_imap_rights_create_c] = true; + acl.rights[esp_mail_imap_rights_delete_message] = true; + acl.rights[esp_mail_imap_rights_delete_d] = true; + acl.rights[esp_mail_imap_rights_delete_mailbox] = true; + acl.rights[esp_mail_imap_rights_expunge] = true; + acl.rights[esp_mail_imap_rights_lookup] = true; + acl.rights[esp_mail_imap_rights_insert] = true; + acl.rights[esp_mail_imap_rights_post] = true; + acl.rights[esp_mail_imap_rights_read] = true; + acl.rights[esp_mail_imap_rights_write] = true; + acl.rights[esp_mail_imap_rights_seen] = true; + + Serial.println("\nSet ACLs..."); + + if (!imap.setACL("INBOX", &acl)) + { + Serial.println("Set ACLs failed"); + } + else + { + Serial.println("Set ACLs success"); + } + + Serial.println("\nGet my rights..."); + + if (!imap.myRights("INBOX", &acl)) + { + Serial.println("Set my rights failed"); + } + else + { + Serial.print("Rights: "); + + String r; + for (int i = esp_mail_imap_rights_administer; i < esp_mail_imap_rights_maxType; i++) + { + if (acl.rights[i]) + r += (char)('a' + i); + } + + Serial.println(r); + } + + Serial.println("\nDelete ACLs..."); + + if (!imap.deleteACL("INBOX", "Steve")) + { + Serial.println("Set ACLs failed"); + } + else + { + Serial.println("Delete ACLs success"); + } + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Append_Message/Append_Message.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Append_Message/Append_Message.ino index d7bbea2c2..15d051c57 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Append_Message/Append_Message.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Append_Message/Append_Message.ino @@ -1,239 +1,239 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to append message to mailbox. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** Assign SD card type and FS used in src/ESP_Mail_FS.h and - * change the config for that card interfaces in src/extras/SDHelper.h - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#include - -// required IMAP and SMTP -#if defined(ENABLE_IMAP) && defined(ENABLE_SMTP) - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); -} - -#endif - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -// required IMAP and SMTP -#if defined(ENABLE_IMAP) && defined(ENABLE_SMTP) - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - ESP_Mail_Message message[2]; // The same usage as SMTP_Message - - message[0].sender.name = "Fred Foobar"; - message[0].sender.email = "foobar@Blurdybloop.example.COM"; - message[0].subject = "afternoon meeting"; - message[0].addRecipient("Joe Mooch", "mooch@owatagu.example.net"); - message[0].text.content = "Hello Joe, do you think we can meet at 3:30 tomorrow?"; - message[0].text.charSet = "us-ascii"; - message[0].text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - ESP_Mail_Attachment att[2]; // The same usage as SMTP_Attachment - - att[0].descr.filename = "shaun.png"; - att[0].descr.mime = "image/png"; - att[0].blob.data = shaun_png; - att[0].blob.size = sizeof(shaun_png); - att[0].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - message[0].addAttachment(att[0]); - - message[1].sender.name = "Joe Mooch"; - message[1].sender.email = "mooch@OWaTaGu.example.net"; - message[1].subject = "Re: afternoon meeting"; - message[1].addRecipient("Fred Foobar", "foobar@blurdybloop.example.com"); - message[1].text.content = "3:30 is fine with me."; - message[1].text.charSet = "us-ascii"; - message[1].text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - att[1].descr.filename = "mu_law.wav"; - att[1].descr.mime = "audio/basic"; - att[1].blob.data = mu_law_wave; - att[1].blob.size = sizeof(mu_law_wave); - att[1].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - message[1].addAttachment(att[1]); - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - if (!imap.selectFolder(F("INBOX"))) - return; - - // If MULTIAPPEND extension is supported, the multiple messages will send by a single APPEND command. - // If not, one message can append for a APPEND command. - // Outlook.com does not accept flag and date/time arguments in APPEND command - if (!MailClient.appendMessage(&imap, &message[0], false /* if not last message to append */, "\\Flagged" /* flags or empty string for Outlook.com */, "Thu, 16 Jun 2022 12:30:25 -0800 (PST)" /* date/time or empty string for Outlook.com */)) - MailClient.printf("Message appending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); - - if (!MailClient.appendMessage(&imap, &message[1], true /* last message to append */)) - MailClient.printf("Message appending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); - -#endif -} - -void loop() -{ -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to append message to mailbox. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#include + +// required IMAP and SMTP +#if defined(ENABLE_IMAP) && defined(ENABLE_SMTP) + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); +} + +#endif + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +// required IMAP and SMTP +#if defined(ENABLE_IMAP) && defined(ENABLE_SMTP) + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + ESP_Mail_Message message[2]; // The same usage as SMTP_Message + + message[0].sender.name = "Fred Foobar"; + message[0].sender.email = "foobar@Blurdybloop.example.COM"; + message[0].subject = "afternoon meeting"; + message[0].addRecipient("Joe Mooch", "mooch@owatagu.example.net"); + message[0].text.content = "Hello Joe, do you think we can meet at 3:30 tomorrow?"; + message[0].text.charSet = "us-ascii"; + message[0].text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + ESP_Mail_Attachment att[2]; // The same usage as SMTP_Attachment + + att[0].descr.filename = "shaun.png"; + att[0].descr.mime = "image/png"; + att[0].blob.data = shaun_png; + att[0].blob.size = sizeof(shaun_png); + att[0].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + message[0].addAttachment(att[0]); + + message[1].sender.name = "Joe Mooch"; + message[1].sender.email = "mooch@OWaTaGu.example.net"; + message[1].subject = "Re: afternoon meeting"; + message[1].addRecipient("Fred Foobar", "foobar@blurdybloop.example.com"); + message[1].text.content = "3:30 is fine with me."; + message[1].text.charSet = "us-ascii"; + message[1].text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + att[1].descr.filename = "mu_law.wav"; + att[1].descr.mime = "audio/basic"; + att[1].blob.data = mu_law_wave; + att[1].blob.size = sizeof(mu_law_wave); + att[1].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + message[1].addAttachment(att[1]); + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + if (!imap.selectFolder(F("INBOX"))) + return; + + // If MULTIAPPEND extension is supported, the multiple messages will send by a single APPEND command. + // If not, one message can append for a APPEND command. + // Outlook.com does not accept flag and date/time arguments in APPEND command + if (!MailClient.appendMessage(&imap, &message[0], false /* if not last message to append */, "\\Flagged" /* flags or empty string for Outlook.com */, "Thu, 16 Jun 2022 12:30:25 -0800 (PST)" /* date/time or empty string for Outlook.com */)) + MailClient.printf("Message appending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + + if (!MailClient.appendMessage(&imap, &message[1], true /* last message to append */)) + MailClient.printf("Message appending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); + +#endif +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Append_Message/data.h b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Append_Message/data.h index c7a88aeab..0b73e9752 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Append_Message/data.h +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Append_Message/data.h @@ -1,1957 +1,1957 @@ -#include - -static const uint8_t mu_law_wave[] PROGMEM = { -0x52, 0x49, 0x46, 0x46, 0x84, 0x5D, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20, -0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, -0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x66, 0x61, 0x63, 0x74, 0x04, 0x00, 0x00, 0x00, 0x00, 0x5D, -0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x5D, 0x00, 0x00, 0xFB, 0xFD, 0xFF, 0xFE, 0xFF, 0x7F, -0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7C, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7C, 0x7D, -0x7C, 0x7C, 0x7D, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7E, 0xFF, 0x7F, -0x7D, 0x7C, 0x7B, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7C, 0x7C, 0x7B, -0x7B, 0x7B, 0x7A, 0x7A, 0x7B, 0x7A, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x7C, 0x7E, -0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x79, 0x79, 0x7B, 0x7B, 0x7B, 0x7C, 0x7C, 0x7E, 0xFF, 0xFE, 0xFE, -0xFF, 0x7E, 0x7C, 0x7D, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x79, 0x78, 0x79, -0x7A, 0x79, 0x78, 0x78, 0x78, 0x77, 0x78, 0x78, 0x79, 0x79, 0x78, 0x77, 0x77, 0x78, 0x78, 0x79, -0x7A, 0x79, 0x79, 0x78, 0x78, 0x7A, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, -0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFC, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF8, 0xF8, -0xF7, 0xF7, 0xF8, 0xF9, 0xF9, 0xFB, 0xFC, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFE, -0xFF, 0xFF, 0xFE, 0x7E, 0x7D, 0x7D, 0x7C, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x7C, -0x7B, 0x7A, 0x79, 0x79, 0x79, 0x77, 0x77, 0x78, 0x79, 0x7B, 0x7C, 0x7B, 0x7B, 0x7C, 0x7B, 0x7B, -0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x79, 0x79, -0x78, 0x77, 0x77, 0x79, 0x79, 0x79, 0x7B, 0x7B, 0x7A, 0x7C, 0x7E, 0x7D, 0x7E, 0x7E, 0x7C, 0x7C, -0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x79, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x78, 0x78, 0x7A, 0x7A, 0x79, -0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFC, 0xFB, 0xFB, 0xFC, -0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFE, 0xFF, 0x7E, 0x7E, 0xFF, 0xFF, 0x7E, 0x7E, 0x7D, 0x7B, -0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, -0x7C, 0x7B, 0x79, 0x7A, 0x7A, 0x7A, 0x7A, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7C, 0x79, 0x79, 0x7A, -0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7C, 0x7C, 0x7C, 0x7E, 0x7D, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0xFE, -0xFD, 0xFD, 0xFB, 0xFB, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, -0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7D, 0x7E, 0x7D, 0x7B, 0x7B, 0x7B, 0x79, 0x78, 0x77, -0x78, 0x78, 0x77, 0x77, 0x77, 0x78, 0x78, 0x76, 0x76, 0x75, 0x73, 0x73, 0x73, 0x72, 0x73, 0x73, -0x74, 0x74, 0x74, 0x75, 0x77, 0x78, 0x78, 0x77, 0x76, 0x77, 0x76, 0x76, 0x78, 0x79, 0x79, 0x79, -0x78, 0x79, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7E, -0x7E, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFE, 0xFF, 0xFD, 0xFE, 0x7F, 0xFF, -0x7F, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7E, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7D, 0x7F, -0xFF, 0xFF, 0xFE, 0xFE, 0x7F, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7C, 0x7D, -0x7D, 0x7D, 0x7D, 0x7E, 0x7F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFF, 0xFE, 0xFC, 0xFD, 0xFC, 0xFC, 0xFD, -0xFC, 0xFB, 0xFB, 0xFC, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFD, 0xFE, -0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7D, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7D, 0x7B, 0x7B, 0x79, -0x78, 0x78, 0x78, 0x76, 0x74, 0x74, 0x73, 0x72, 0x75, 0x77, 0x77, 0x76, 0x75, 0x75, 0x76, 0x77, -0x77, 0x76, 0x74, 0x74, 0x74, 0x74, 0x76, 0x76, 0x76, 0x77, 0x75, 0x76, 0x78, 0x79, 0x77, 0x77, -0x79, 0x7B, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7D, 0x7F, 0x7E, 0xFF, 0xFF, 0x7F, 0xFE, 0xFC, 0xFE, -0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFD, 0xFC, 0xFE, 0xFF, 0x7E, 0x7F, 0x7F, 0x7D, 0x7E, 0xFF, 0x7F, -0x7F, 0xFF, 0x7F, 0x7E, 0x7D, 0x7E, 0xFF, 0x7E, 0x7F, 0x7F, 0x7C, 0x7D, 0x7F, 0x7D, 0x7E, 0x7E, -0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7B, 0x7D, 0x7B, 0x7A, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7C, -0x7D, 0x7E, 0x7F, 0xFF, 0x7F, 0x7F, 0x7F, 0xFF, 0xFD, 0xFD, 0xFD, 0xFC, 0xFB, 0xFB, 0xFB, 0xFB, -0xFA, 0xFB, 0xFB, 0xFB, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x7E, 0x7E, 0x7D, 0x7B, 0x7B, 0x7B, -0x78, 0x79, 0x78, 0x75, 0x76, 0x76, 0x76, 0x76, 0x74, 0x74, 0x73, 0x73, 0x74, 0x73, 0x72, 0x73, -0x75, 0x75, 0x74, 0x76, 0x74, 0x72, 0x73, 0x74, 0x75, 0x75, 0x76, 0x77, 0x77, 0x78, 0x77, 0x77, -0x77, 0x78, 0x78, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x7A, 0x79, 0x7B, 0x7C, 0x7B, 0x7B, -0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7C, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, -0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, -0xFE, 0x7E, 0x7E, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7E, 0xFF, 0x7E, 0x7E, 0x7E, 0x7D, -0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFD, 0xFC, 0xFE, 0x7F, 0x7E, 0x7E, 0x7F, 0xFF, 0xFF, -0x7F, 0x7E, 0x7D, 0x7D, 0x7D, 0x7B, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, 0x7D, 0x7C, 0x7C, -0x7D, 0x7C, 0x7C, 0x7E, 0x7E, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFF, -0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, -0xFB, 0xFB, 0xFA, 0xFB, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, -0x7E, 0x7E, 0x7E, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7F, -0x7D, 0x7B, 0x7C, 0x7C, 0x7D, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7E, -0x7F, 0x7E, 0x7D, 0x7C, 0x7B, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x78, 0x77, 0x77, 0x76, 0x74, 0x73, -0x72, 0x73, 0x74, 0x75, 0x77, 0x78, 0x78, 0x79, 0x79, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, -0x7C, 0x7D, 0x7E, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, 0x7D, 0x7C, 0x7B, -0x7A, 0x7B, 0x7B, 0x7A, 0x7A, 0x79, 0x79, 0x7A, 0x79, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x79, 0x79, -0x79, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7A, 0x7B, 0x7C, 0x7B, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7F, -0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7D, 0x7D, -0x7D, 0x7D, 0x7E, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7F, 0x7F, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7F, 0x7F, 0x7E, -0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, -0x7A, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, -0x7D, 0x7E, 0xFF, 0x7E, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7A, 0x7A, -0x7A, 0x79, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, 0x7D, 0x7C, 0x7C, 0x7A, 0x79, 0x79, 0x78, 0x78, -0x78, 0x77, 0x77, 0x76, 0x75, 0x74, 0x74, 0x74, 0x73, 0x73, 0x73, 0x73, 0x74, 0x74, 0x76, 0x75, -0x74, 0x75, 0x77, 0x78, 0x78, 0x7A, 0x7B, 0x7D, 0xFF, 0xFE, 0xFE, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, -0xFC, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, -0xF8, 0xFA, 0xF8, 0xF6, 0xF7, 0xF7, 0xF8, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFB, -0xFB, 0xFB, 0xFD, 0xFE, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, 0xFE, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, -0x7F, 0x7E, 0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0xFD, 0xFE, 0xFF, -0xFE, 0xFE, 0xFD, 0xFE, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7E, 0x7F, -0x7D, 0x7D, 0x7E, 0x7E, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x79, 0x77, 0x78, 0x79, 0x78, 0x77, 0x76, -0x76, 0x75, 0x73, 0x74, 0x73, 0x71, 0x70, 0x70, 0x71, 0x72, 0x71, 0x71, 0x70, 0x6F, 0x6F, 0x6F, -0x70, 0x71, 0x71, 0x72, 0x73, 0x74, 0x74, 0x74, 0x76, 0x77, 0x76, 0x78, 0x79, 0x79, 0x79, 0x78, -0x7A, 0x7B, 0x7B, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, -0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7D, -0x7D, 0x7D, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7C, 0x7A, 0x78, 0x79, 0x78, 0x77, -0x76, 0x78, 0x79, 0x78, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7A, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, -0x7E, 0xFF, 0xFD, 0xFC, 0xFC, 0xFA, 0xF9, 0xFA, 0xFB, 0xFA, 0xF9, 0xF8, 0xF8, 0xF9, 0xFA, 0xF9, -0xF9, 0xF9, 0xF9, 0xF9, 0xF8, 0xF7, 0xF9, 0xF9, 0xF8, 0xF8, 0xFA, 0xFB, 0xFA, 0xFB, 0xFD, 0xFD, -0xFC, 0xFD, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFF, 0x7F, 0x7F, 0x7E, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, -0x7A, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x75, 0x76, 0x77, 0x76, 0x75, 0x76, 0x76, 0x75, 0x76, 0x77, -0x78, 0x79, 0x7B, 0x7B, 0x7B, 0x7A, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7A, 0x7B, 0x7B, 0x7A, -0x7B, 0x7D, 0x7E, 0x7B, 0x7C, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFC, 0xFD, 0xFE, 0xFF, -0xFE, 0xFF, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7D, 0x7F, 0x7F, 0x7C, 0x7B, -0x7A, 0x78, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7C, 0x7C, 0x7A, 0x7B, 0x7C, 0x7C, 0x7B, 0x7C, 0x7C, -0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x79, 0x7A, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, -0x7D, 0xFE, 0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFA, 0xF8, 0xF8, 0xF9, 0xF8, 0xF5, 0xF4, 0xF7, 0xF8, -0xF8, 0xF8, 0xF9, 0xFB, 0xFC, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7B, -0x7A, 0x7B, 0x7B, 0x7A, 0x78, 0x78, 0x77, 0x76, 0x76, 0x75, 0x76, 0x76, 0x76, 0x77, 0x75, 0x75, -0x76, 0x75, 0x76, 0x76, 0x78, 0x78, 0x77, 0x78, 0x76, 0x74, 0x75, 0x77, 0x79, 0x7A, 0x7A, 0x7B, -0x7C, 0x7D, 0x7D, 0x7D, 0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0x7F, 0xFF, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, -0xFE, 0x7F, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0xFF, 0xFD, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, -0xFC, 0xFD, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7C, -0x7B, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x7A, 0x7C, 0x7A, 0x7B, 0x7C, 0x7C, 0x7E, 0x7E, 0xFF, -0xFF, 0x7F, 0x7F, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, -0x7C, 0x7D, 0xFF, 0x7E, 0x7C, 0x7D, 0xFF, 0xFF, 0xFF, 0xFD, 0xFD, 0xFF, 0x7E, 0x7F, 0x7E, 0x7E, -0x7F, 0x7E, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x79, -0x77, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7C, 0x7D, 0x7D, 0x7E, 0xFD, 0xFD, 0xFE, 0xFC, 0xFC, 0xFB, -0xFB, 0xFC, 0xFB, 0xFB, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, -0xFF, 0xFF, 0xFD, 0xFC, 0xFD, 0xFD, 0xFC, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7D, 0x7C, 0x7D, 0x7E, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, -0x7B, 0x7C, 0x7D, 0x7B, 0x7B, 0x7C, 0x7A, 0x78, 0x78, 0x78, 0x77, 0x75, 0x75, 0x75, 0x73, 0x72, -0x72, 0x72, 0x71, 0x71, 0x72, 0x72, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x74, 0x74, -0x75, 0x76, 0x76, 0x76, 0x77, 0x78, 0x77, 0x78, 0x79, 0x77, 0x78, 0x78, 0x79, 0x7A, 0x7A, 0x7A, -0x7A, 0x79, 0x77, 0x76, 0x76, 0x78, 0x78, 0x77, 0x77, 0x77, 0x75, 0x74, 0x74, 0x75, 0x75, 0x76, -0x79, 0x79, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7D, 0xFF, 0xFD, 0xFD, 0xFE, 0xFF, 0xFE, 0xFC, -0xF9, 0xF9, 0xFB, 0xFA, 0xF9, 0xF8, 0xF8, 0xF8, 0xF6, 0xF4, 0xF6, 0xF8, 0xF7, 0xF7, 0xF9, 0xF9, -0xF9, 0xF8, 0xF8, 0xFB, 0xFA, 0xF9, 0xFA, 0xFB, 0xFC, 0xFE, 0xFC, 0xFD, 0xFF, 0x7E, 0x7F, 0x7E, -0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, 0x7A, 0x7A, 0x79, 0x79, 0x78, 0x77, 0x78, -0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, 0x7F, 0xFE, 0xFE, 0xFD, 0xFD, -0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0xFC, 0xFB, 0xFC, -0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, -0x7C, 0x7B, 0x7B, 0x7C, 0x79, 0x79, 0x79, 0x78, 0x76, 0x75, 0x76, 0x78, 0x77, 0x76, 0x76, 0x77, -0x76, 0x74, 0x74, 0x75, 0x75, 0x75, 0x74, 0x74, 0x76, 0x77, 0x78, 0x7A, 0x7C, 0x7B, 0x7A, 0x7D, -0x7E, 0x7E, 0x7C, 0x7D, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFE, 0xFF, -0xFF, 0x7F, 0x7E, 0x7F, 0xFF, 0xFE, 0xFD, 0xFF, 0xFE, 0xFC, 0xFB, 0xFC, 0xFE, 0xFD, 0xFC, 0xFE, -0xFF, 0xFE, 0xFD, 0xFF, 0x7E, 0x7F, 0xFE, 0xFC, 0xFD, 0xFE, 0xFD, 0xFD, 0xFE, 0x7F, 0x7E, 0xFF, -0xFF, 0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7E, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, -0x7E, 0x7D, 0x7E, 0xFF, 0xFF, 0xFE, 0xFD, 0xFF, 0x7D, 0x7A, 0x79, 0x79, 0x7A, 0x7C, 0x7B, 0x7B, -0x7D, 0x7E, 0x7E, 0x7D, 0xFF, 0xFF, 0x7F, 0x7F, 0x7E, 0x7B, 0x7A, 0x7A, 0x7A, 0x78, 0x77, 0x77, -0x77, 0x78, 0x78, 0x76, 0x76, 0x76, 0x76, 0x74, 0x74, 0x73, 0x74, 0x74, 0x75, 0x74, 0x72, 0x74, -0x76, 0x74, 0x74, 0x76, 0x76, 0x74, 0x73, 0x73, 0x72, 0x73, 0x74, 0x76, 0x77, 0x75, 0x73, 0x75, -0x77, 0x78, 0x75, 0x75, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7B, -0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7D, 0x7C, 0x7D, 0x7B, 0x7C, 0x7F, -0xFF, 0xFF, 0x7E, 0x7D, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x79, 0x77, 0x77, -0x78, 0x76, 0x76, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x7B, 0x7C, 0x7B, 0x7C, 0x7D, 0xFF, -0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFB, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, -0xFA, 0xF9, 0xF9, 0xF7, 0xF7, 0xF7, 0xF4, 0xF4, 0xF4, 0xF2, 0xEF, 0xEE, 0xEF, 0xF2, 0xF2, 0xF1, -0xF2, 0xF5, 0xF5, 0xF3, 0xF1, 0xF2, 0xF5, 0xF7, 0xF8, 0xFA, 0xFB, 0xFC, 0xFC, 0xFB, 0xFC, 0xFC, -0xFD, 0xFF, 0x7F, 0x7E, 0x7C, 0x7A, 0x7A, 0x78, 0x77, 0x76, 0x75, 0x75, 0x74, 0x71, 0x70, 0x71, -0x71, 0x71, 0x70, 0x6F, 0x71, 0x71, 0x71, 0x73, 0x75, 0x77, 0x77, 0x76, 0x79, 0x7A, 0x79, 0x79, -0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7F, 0xFF, 0xFE, 0xFF, 0x7E, 0x7D, 0x7E, 0x7E, 0x7D, 0x7D, -0x7E, 0x7C, 0x7C, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x77, 0x75, 0x75, 0x76, 0x78, 0x79, 0x78, -0x7A, 0x7C, 0x7C, 0x7A, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7B, 0x7D, 0x7D, 0x7C, -0x7C, 0x7E, 0xFF, 0x7F, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0xFF, 0x7F, 0x7E, -0x7D, 0x7D, 0xFF, 0xFF, 0x7F, 0xFF, 0xFC, 0xFC, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xFB, 0xFB, -0xF9, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0x7F, 0x7F, 0x7E, 0x7D, 0x7E, 0x7D, 0x7B, 0x7C, 0x7B, -0x7B, 0x7C, 0x7C, 0x7A, 0x78, 0x78, 0x7B, 0x7A, 0x77, 0x75, 0x76, 0x75, 0x76, 0x76, 0x76, 0x76, -0x78, 0x79, 0x78, 0x75, 0x75, 0x76, 0x77, 0x7A, 0x7D, 0xFF, 0xFC, 0xFB, 0xFA, 0xFA, 0xFB, 0xFA, -0xFB, 0xFB, 0xFC, 0xFD, 0xFD, 0x7E, 0x78, 0x76, 0x72, 0x70, 0x71, 0x75, 0x77, 0x77, 0x79, 0x7A, -0x7A, 0x7A, 0x7B, 0xFF, 0xFB, 0xFA, 0xF9, 0xFB, 0xFD, 0xFE, 0x7E, 0x7F, 0xFF, 0xFC, 0xF6, 0xF3, -0xF7, 0xFC, 0xFF, 0x7A, 0x73, 0x6E, 0x6C, 0x6D, 0x6E, 0x6E, 0x6E, 0x6E, 0x6F, 0x74, 0x73, 0x72, -0x75, 0x7A, 0x7D, 0x7D, 0xFF, 0xFF, 0x7C, 0x7C, 0x7D, 0x7B, 0x7A, 0x79, 0x7B, 0xFF, 0xFF, 0x7D, -0x7C, 0xFF, 0xFE, 0x7D, 0xFC, 0xF3, 0xF6, 0xFC, 0xFE, 0xFE, 0xFF, 0x78, 0x75, 0x79, 0x7A, 0x7E, -0xF8, 0xF6, 0xF6, 0xF2, 0xEF, 0xEE, 0xF0, 0xF7, 0xFD, 0xFE, 0xFD, 0x7B, 0x77, 0x7C, 0xFF, 0xFB, -0xFD, 0x7D, 0xFF, 0x7C, 0x78, 0x7A, 0x7A, 0xFF, 0xF9, 0xF5, 0xF1, 0xF4, 0xFA, 0xFC, 0xFC, 0xFA, -0xF8, 0xFA, 0xFB, 0xFA, 0xFB, 0xFC, 0xFD, 0xFF, 0x7D, 0x7B, 0x7D, 0x7E, 0x7A, 0x76, 0x76, 0x75, -0x72, 0x75, 0x7B, 0x7D, 0x7A, 0x7A, 0x7D, 0xFF, 0x7C, 0x7C, 0xFF, 0x7D, 0x7A, 0x7B, 0x7C, 0x7E, -0xFC, 0xFC, 0x7F, 0xFE, 0xFD, 0xFE, 0xFC, 0xF8, 0xF9, 0xFA, 0xFB, 0xFE, 0x7E, 0x79, 0x72, 0x72, -0x74, 0x76, 0x78, 0x76, 0x78, 0x7A, 0x75, 0x76, 0x77, 0x75, 0x73, 0x73, 0x73, 0x73, 0x74, 0x73, -0x73, 0x77, 0x78, 0x79, 0x79, 0x7A, 0x79, 0x73, 0x73, 0x7B, 0x7C, 0x7C, 0xFC, 0xFC, 0xFE, 0x7F, -0x76, 0x73, 0x76, 0x73, 0x73, 0x78, 0x7C, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0x7D, 0x7B, 0x7B, -0x7C, 0x7A, 0x78, 0x7B, 0x7B, 0x7D, 0x7F, 0x7A, 0x77, 0x73, 0x6F, 0x70, 0x72, 0x73, 0x72, 0x72, -0x73, 0x74, 0x74, 0x76, 0x7D, 0xFE, 0x7D, 0x7C, 0x7C, 0x78, 0x76, 0x77, 0x79, 0x7B, 0xFF, 0xFD, -0xFE, 0x7E, 0x7B, 0x7A, 0x78, 0x78, 0x7B, 0x7C, 0x7C, 0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x79, 0x7B, -0xFF, 0xFA, 0xF9, 0xFD, 0x7E, 0x7D, 0x7C, 0x7B, 0x7E, 0xFE, 0xFC, 0xFF, 0x7E, 0xFE, 0xFD, 0xFE, -0xFD, 0xFC, 0xFB, 0xFC, 0xFC, 0xFD, 0xF9, 0xF3, 0xF2, 0xF3, 0xF4, 0xF6, 0xF6, 0xF8, 0xFA, 0xFC, -0xFB, 0xF7, 0xF9, 0xFC, 0xFC, 0xFD, 0xFD, 0x7E, 0x7C, 0x7F, 0xFF, 0x7D, 0x7A, 0x7A, 0x7B, 0x78, -0x78, 0x78, 0x75, 0x75, 0x76, 0x79, 0x7A, 0x79, 0x7C, 0x7F, 0xFD, 0xFF, 0x7E, 0xFF, 0x7D, 0x79, -0x77, 0x78, 0x79, 0x78, 0x79, 0x7C, 0x7D, 0x7F, 0x7E, 0x7E, 0xFE, 0xFC, 0xF8, 0xF7, 0xFA, 0xFB, -0xFC, 0xFD, 0xFF, 0x7D, 0x7E, 0x7F, 0xFF, 0x7D, 0x7B, 0x7D, 0xFE, 0xF9, 0xF5, 0xF6, 0xF6, 0xF4, -0xF6, 0xFA, 0xFE, 0x7D, 0x79, 0x78, 0x77, 0x77, 0x7A, 0x7E, 0xFE, 0xFF, 0xFF, 0xFA, 0xFA, 0xFE, -0x7C, 0x75, 0x71, 0x72, 0x74, 0x75, 0x74, 0x75, 0x75, 0x77, 0x79, 0x79, 0x77, 0x74, 0x74, 0x74, -0x72, 0x71, 0x70, 0x71, 0x70, 0x6F, 0x72, 0x73, 0x72, 0x73, 0x71, 0x70, 0x73, 0x78, 0x7A, 0x78, -0x77, 0x77, 0x76, 0x74, 0x73, 0x72, 0x70, 0x71, 0x75, 0x78, 0x7B, 0x7F, 0xFF, 0xFE, 0xFB, 0xFD, -0x7E, 0xFF, 0xFD, 0x7F, 0x7C, 0x7B, 0x7F, 0xFD, 0xFF, 0xFE, 0xFC, 0xFE, 0xFD, 0xFC, 0xFA, 0xF7, -0xF7, 0xFB, 0xFD, 0xFE, 0x7E, 0x7C, 0x7B, 0x7A, 0x7B, 0x79, 0x75, 0x75, 0x76, 0x78, 0x7D, 0xFF, -0x7E, 0x7D, 0x7E, 0x7C, 0x77, 0x75, 0x76, 0x76, 0x78, 0x7E, 0xFD, 0xFB, 0xFC, 0xFD, 0xFE, 0x7C, -0x78, 0x78, 0x7A, 0x7B, 0x7E, 0x7E, 0x7D, 0x7D, 0x7C, 0x7A, 0x78, 0x79, 0x7B, 0x7A, 0x7D, 0xFC, -0xFD, 0x7E, 0xFF, 0xFB, 0xF7, 0xF6, 0xF7, 0xF7, 0xF6, 0xFA, 0xFF, 0xFE, 0xFD, 0xFF, 0x7D, 0xFF, -0xFC, 0xFB, 0xF9, 0xFD, 0xFE, 0xFD, 0x7E, 0x79, 0x76, 0x71, 0x6F, 0x6E, 0x6E, 0x6F, 0x72, 0x76, -0x7A, 0x7E, 0xFF, 0xFF, 0x7C, 0x7B, 0x7C, 0x7B, 0x7A, 0x79, 0x7A, 0x7E, 0xFF, 0xFF, 0x7E, 0x7D, -0x7D, 0x7E, 0x7C, 0x78, 0x79, 0x7A, 0x7B, 0xFF, 0xFF, 0x7F, 0x7E, 0x7B, 0x79, 0x79, 0x76, 0x72, -0x73, 0x7B, 0xFF, 0xFE, 0xFB, 0xFA, 0xFA, 0xFC, 0x7D, 0x78, 0x77, 0x78, 0x79, 0x79, 0x78, 0x79, -0x77, 0x73, 0x74, 0x76, 0x77, 0x79, 0x7A, 0x7B, 0x7F, 0xFD, 0xFE, 0xFF, 0x7F, 0x7E, 0x7E, 0x7C, -0x78, 0x78, 0x7B, 0x7B, 0x7A, 0x7C, 0x7F, 0xFE, 0xFD, 0xFE, 0x7E, 0xFF, 0xFD, 0xFC, 0xF9, 0xF5, -0xF2, 0xF0, 0xF2, 0xF3, 0xF0, 0xF1, 0xF2, 0xF1, 0xF4, 0xF7, 0xF8, 0xFC, 0xFC, 0xF6, 0xF3, 0xF4, -0xF5, 0xF5, 0xF6, 0xFB, 0xFF, 0xFF, 0xFF, 0x7D, 0x7D, 0x7E, 0x7D, 0x79, 0x75, 0x74, 0x75, 0x72, -0x72, 0x75, 0x75, 0x74, 0x77, 0x7A, 0x7A, 0x7A, 0x7A, 0x77, 0x74, 0x73, 0x72, 0x74, 0x75, 0x76, -0x77, 0x74, 0x74, 0x77, 0x79, 0x79, 0x79, 0x78, 0x77, 0x74, 0x70, 0x6F, 0x70, 0x6F, 0x6E, 0x6E, -0x6E, 0x6F, 0x6F, 0x72, 0x75, 0x72, 0x74, 0x79, 0x7B, 0x7B, 0x7B, 0x7D, 0xFF, 0x7E, 0x7F, 0xFE, -0xFE, 0x7F, 0x7D, 0x7D, 0xFF, 0xFD, 0xFE, 0x7E, 0x7D, 0x7D, 0x7E, 0x7C, 0x79, 0x77, 0x75, 0x76, -0x77, 0x78, 0x78, 0x74, 0x75, 0x7A, 0x7F, 0xFB, 0xF9, 0xF9, 0xF8, 0xFD, 0x7E, 0x7B, 0x76, 0x78, -0x7B, 0x7C, 0x7E, 0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x7C, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x7D, 0x7B, -0x7B, 0x79, 0x79, 0x7A, 0x7D, 0xFF, 0x7F, 0x7F, 0xFF, 0xFD, 0xFB, 0xFD, 0xFE, 0xFE, 0xFF, 0x7D, -0x7C, 0x7F, 0xFB, 0xF7, 0xF6, 0xFC, 0x7F, 0xFF, 0xFE, 0xFB, 0xFD, 0xFE, 0xFC, 0xFD, 0xFE, 0x7C, -0x76, 0x74, 0x74, 0x79, 0x79, 0x76, 0x77, 0x79, 0x7C, 0x7D, 0x7B, 0x7B, 0x7B, 0x7E, 0xFD, 0xFB, -0xF9, 0xF9, 0xFE, 0x7C, 0x79, 0x79, 0x77, 0x76, 0x79, 0x7B, 0x7D, 0x7C, 0x7C, 0x7D, 0x7C, 0x78, -0x75, 0x74, 0x72, 0x72, 0x73, 0x71, 0x70, 0x73, 0x78, 0x7C, 0x7D, 0x7E, 0xFF, 0x7F, 0x7F, 0x7D, -0x7A, 0x78, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x7B, 0xFF, 0xFF, 0xFD, 0xFC, 0xFC, 0xFA, 0xF9, -0xF8, 0xF9, 0xFE, 0x7E, 0xFF, 0xFE, 0xFE, 0x7D, 0x7A, 0x78, 0x75, 0x75, 0x77, 0x7A, 0x7A, 0x79, -0x7B, 0x7D, 0xFF, 0xFD, 0xFC, 0xFC, 0xFB, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xFB, 0xFA, 0xF9, 0xF7, -0xF8, 0xFA, 0xF8, 0xF9, 0xFC, 0xFD, 0xFD, 0xFC, 0xF9, 0xF7, 0xF8, 0xFC, 0x7E, 0x7B, 0x7A, 0x7A, -0x79, 0x79, 0x7A, 0x7A, 0x7A, 0x77, 0x72, 0x72, 0x74, 0x76, 0x7B, 0x7C, 0x7B, 0x7D, 0x7E, 0x7D, -0x7D, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x78, 0x78, 0x79, 0x79, 0x79, 0x78, 0x79, 0x7B, 0x7C, 0x7C, -0x7A, 0x7A, 0x77, 0x75, 0x75, 0x74, 0x73, 0x70, 0x6E, 0x6E, 0x6E, 0x6F, 0x72, 0x75, 0x77, 0x7A, -0x7D, 0x7D, 0x7D, 0x7E, 0xFF, 0x7D, 0x7A, 0x7A, 0x7A, 0x7B, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7F, -0x7D, 0x7B, 0x78, 0x75, 0x73, 0x74, 0x75, 0x75, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7D, 0xFE, 0xFC, -0xF9, 0xF8, 0xF8, 0xF8, 0xF6, 0xF5, 0xF6, 0xF8, 0xFB, 0xFC, 0xFB, 0xFD, 0xFF, 0x7E, 0x7D, 0x7C, -0x7C, 0x7B, 0x7C, 0x7B, 0x79, 0x79, 0x7A, 0x79, 0x76, 0x74, 0x72, 0x72, 0x73, 0x74, 0x75, 0x77, -0x78, 0x78, 0x78, 0x77, 0x76, 0x75, 0x75, 0x78, 0x7A, 0x79, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0x7F, -0xFE, 0xFC, 0xFC, 0xFC, 0xFA, 0xF8, 0xF7, 0xF7, 0xF8, 0xF7, 0xF5, 0xF5, 0xF5, 0xF4, 0xF5, 0xF6, -0xF7, 0xF8, 0xF9, 0xFB, 0xFE, 0x7F, 0x7D, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7D, 0x7A, 0x7A, 0x7A, -0x7A, 0x79, 0x79, 0x79, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x7A, 0x7A, 0x79, 0x77, 0x76, -0x77, 0x77, 0x77, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7B, -0x78, 0x78, 0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0x7F, 0x7F, 0xFE, -0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFE, 0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, -0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x76, 0x77, 0x78, 0x77, 0x79, -0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7D, 0x7B, 0x7B, 0x7D, 0x7C, 0x7D, 0xFF, 0x7E, -0xFF, 0xFD, 0xFB, 0xF9, 0xF8, 0xF9, 0xF9, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF3, 0xF5, 0xF6, 0xF6, -0xF7, 0xF9, 0xFB, 0xFB, 0xFA, 0xFA, 0xFB, 0xFC, 0xFB, 0xFD, 0xFD, 0xFB, 0xFB, 0xFB, 0xFA, 0xF8, -0xF8, 0xF9, 0xFB, 0xFD, 0x7E, 0x7B, 0x78, 0x78, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x75, 0x75, -0x73, 0x71, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6E, 0x6E, 0x6F, 0x6F, 0x6E, 0x6E, 0x6E, 0x6D, -0x6D, 0x6E, 0x6D, 0x6D, 0x6E, 0x6F, 0x70, 0x72, 0x73, 0x74, 0x75, 0x79, 0x7C, 0x7D, 0x7E, 0xFF, -0xFF, 0xFF, 0xFD, 0xFC, 0xFA, 0xF9, 0xFB, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0x7E, 0x7B, 0x7A, -0x79, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7C, 0x7C, 0x7B, 0x79, 0x79, 0x78, 0x78, 0x79, 0x7A, 0x7C, -0x7E, 0x7E, 0x7E, 0x7C, 0x7B, 0x7A, 0x7A, 0x7A, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x7D, 0xFF, 0xFD, -0xFC, 0xFB, 0xFA, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFB, 0xFB, -0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFD, 0xFC, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, 0xF7, -0xF6, 0xF7, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0x7E, 0x7D, 0x7C, 0x7C, -0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, -0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7B, 0x78, 0x77, 0x76, 0x75, 0x75, 0x75, 0x76, 0x76, 0x75, 0x76, -0x77, 0x78, 0x78, 0x78, 0x79, 0x79, 0x7B, 0x7D, 0x7D, 0x7E, 0x7F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFE, -0xFD, 0xFB, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFF, 0x7F, 0x7E, 0x7C, 0x7C, 0x7B, -0x7A, 0x7A, 0x7A, 0x78, 0x78, 0x77, 0x77, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 0x7D, 0x7B, -0x7A, 0x7B, 0x7C, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7A, 0x7B, 0x7F, 0xFD, 0x7D, 0x79, 0xFE, -0xFA, 0xFE, 0xFC, 0xF8, 0xFC, 0xFF, 0xFF, 0xFE, 0xFB, 0xFC, 0x7F, 0xFF, 0x7F, 0x7C, 0x7D, 0x7D, -0x7E, 0x7E, 0x7B, 0x7A, 0x7A, 0x7B, 0x7C, 0x7E, 0x7E, 0x7C, 0x7B, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, -0x7D, 0x7E, 0x7F, 0x7E, 0x7F, 0xFF, 0xFE, 0xFD, 0xFE, 0xFF, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7E, -0x7D, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x7A, 0x7A, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x75, 0x74, 0x73, -0x74, 0x75, 0x74, 0x74, 0x75, 0x75, 0x75, 0x76, 0x77, 0x76, 0x77, 0x77, 0x79, 0x7B, 0x7C, 0x7D, -0x7D, 0x7D, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFE, 0xFD, 0xFE, 0xFF, 0xFE, 0xFD, 0xFB, 0xFC, 0xFD, -0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7E, -0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, -0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, -0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7F, 0x7F, 0x7E, -0x7D, 0x7C, 0x7B, 0x7B, 0x79, 0x77, 0x77, 0x78, 0x76, 0x76, 0x78, 0x7A, 0x78, 0x78, 0x78, 0x77, -0x77, 0x76, 0x75, 0x76, 0x75, 0x75, 0x77, 0x77, 0x76, 0x74, 0x74, 0x75, 0x76, 0x75, 0x76, 0x76, -0x75, 0x76, 0x76, 0x75, 0x74, 0x73, 0x74, 0x74, 0x75, 0x76, 0x76, 0x77, 0x78, 0x7A, 0x7A, 0x7B, -0x7C, 0x7B, 0x7D, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFE, 0xFD, 0xFD, 0xFD, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0xFE, -0xFE, 0xFE, 0x7F, 0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFD, 0xFD, 0xFD, -0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0xFE, 0xFC, 0xFA, 0xF9, 0xF8, 0xF8, 0xF8, 0xF9, 0xFA, -0xFD, 0xFE, 0xFC, 0xFD, 0xFE, 0xFE, 0xFF, 0x7F, 0xFF, 0x7E, 0x7D, 0x7B, 0x79, 0x79, 0x7B, 0x7C, -0x7C, 0x7D, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7B, 0x7B, 0x7A, 0x77, 0x78, 0x75, 0x75, 0x76, 0x76, -0x78, 0x75, 0x76, 0x77, 0x73, 0x75, 0x73, 0x77, 0x76, 0x73, 0x78, 0x73, 0x78, 0x77, 0x75, 0x7B, -0x70, 0x7E, 0x68, 0x5B, 0xE4, 0xD9, 0x77, 0x66, 0x5F, 0x6B, 0xEB, 0x78, 0x6B, 0xEC, 0xE9, 0x67, -0x5A, 0x62, 0xF8, 0xE2, 0xF1, 0x6B, 0x6F, 0x72, 0x6E, 0x6D, 0x72, 0xEF, 0xE7, 0xF7, 0x6D, 0x6A, -0x70, 0x7B, 0xFC, 0xF5, 0xED, 0xEF, 0x7D, 0x71, 0x70, 0xFF, 0xEE, 0xEF, 0xF8, 0xFC, 0x7B, 0x73, -0x6F, 0x71, 0x7E, 0xF2, 0xF2, 0x76, 0x67, 0x68, 0x78, 0xF7, 0xF5, 0xFC, 0x7E, 0x7B, 0x73, 0x70, -0x79, 0xF4, 0xEB, 0xEC, 0xF8, 0x7C, 0x7B, 0xFF, 0xF6, 0xEF, 0xEF, 0xF4, 0xF8, 0xFE, 0x7D, 0xFE, -0xF8, 0xF4, 0xF4, 0xF9, 0xFE, 0x7E, 0x7C, 0x7C, 0xFD, 0xF8, 0xF8, 0xFD, 0x7D, 0x7A, 0x79, 0x7C, -0xFF, 0xFD, 0xFB, 0xFC, 0x7D, 0x7B, 0x7D, 0x7F, 0xFD, 0xFD, 0xFF, 0x7E, 0x7C, 0x7A, 0x79, 0x7C, -0x7E, 0x7D, 0x7D, 0x7B, 0x78, 0x79, 0x7B, 0x7A, 0x78, 0x79, 0x77, 0x76, 0x78, 0x71, 0x70, 0x78, -0x7E, 0xF6, 0xFE, 0x67, 0x68, 0xF4, 0xEF, 0x74, 0x69, 0x6A, 0xFF, 0x7E, 0x6E, 0xF2, 0xFB, 0x69, -0x66, 0x69, 0xDD, 0xD9, 0x71, 0x7B, 0x74, 0x5F, 0x69, 0x61, 0x6A, 0xE6, 0xEC, 0x66, 0x55, 0x50, -0x5C, 0xFB, 0xED, 0xF5, 0xFA, 0x6F, 0x6E, 0x7B, 0xE8, 0xCF, 0xC7, 0xC6, 0xCA, 0xCB, 0xDB, 0x3A, -0x2E, 0x49, 0xBD, 0xB7, 0xC6, 0x4D, 0x41, 0x4B, 0x49, 0x4D, 0xD9, 0xBF, 0xC2, 0xFD, 0x3F, 0x3D, -0x51, 0xDF, 0xCD, 0xCC, 0xD5, 0xF4, 0x50, 0x46, 0x4D, 0xF0, 0xCB, 0xCA, 0xDA, 0x61, 0x51, 0x52, -0x5B, 0xE6, 0xD0, 0xCE, 0xDC, 0x5D, 0x53, 0x51, 0x6A, 0xF9, 0x48, 0x67, 0xC2, 0xE0, 0x5F, 0x5B, -0x4C, 0x71, 0xFA, 0x6E, 0xCE, 0xCF, 0x7A, 0x64, 0x79, 0xD8, 0xCE, 0xD1, 0xCD, 0xC3, 0xC5, 0xCD, -0xC7, 0xDC, 0x42, 0x3E, 0x53, 0xD2, 0xC0, 0xDE, 0x44, 0x48, 0x58, 0x53, 0x59, 0xFA, 0xD9, 0xD6, -0x5E, 0x43, 0x47, 0x61, 0xE1, 0xD8, 0xEA, 0x64, 0x46, 0x3C, 0x51, 0x7F, 0x77, 0xD0, 0xF6, 0x4B, -0x4B, 0x4A, 0x6F, 0xCA, 0xC6, 0xC9, 0xC7, 0xC2, 0xC8, 0xBD, 0xB0, 0xAB, 0xBB, 0x1F, 0x19, 0x5F, -0xA3, 0xA5, 0xBA, 0x30, 0x30, 0x47, 0x31, 0x37, 0xBC, 0xAB, 0xB8, 0x3D, 0x2B, 0x30, 0x4E, 0xBD, -0xB4, 0xC4, 0x5D, 0x3F, 0x38, 0x41, 0x6E, 0xC8, 0xC1, 0xDC, 0x4B, 0x3B, 0x3F, 0xE5, 0xBF, 0xBC, -0xC8, 0xE5, 0xDE, 0xC0, 0xAE, 0xAD, 0xAF, 0xC1, 0x20, 0x1A, 0x63, 0xA8, 0xA7, 0xB5, 0x36, 0x2E, -0x3D, 0x32, 0x3F, 0xBD, 0xB1, 0xC1, 0x39, 0x2E, 0x42, 0xE8, 0xCA, 0xC3, 0xDB, 0x5F, 0x47, 0x39, -0x47, 0xD5, 0xCB, 0xD1, 0x70, 0x4B, 0x4D, 0xF0, 0xC1, 0xB3, 0xAE, 0xB4, 0xBE, 0xB8, 0xB8, 0x34, -0x1C, 0x27, 0xB6, 0xA3, 0xAC, 0x4F, 0x2C, 0x32, 0x3B, 0x3E, 0xEB, 0xB9, 0xBB, 0x45, 0x2E, 0x39, -0x60, 0xC3, 0xBB, 0xD8, 0x4D, 0x45, 0x41, 0x57, 0xD6, 0xDE, 0x79, 0x5D, 0x50, 0x5B, 0xDB, 0xBE, -0xB4, 0xB3, 0xBC, 0xC4, 0xB6, 0xAC, 0xC2, 0x26, 0x1A, 0x30, 0xAB, 0xA9, 0xBB, 0x61, 0x33, 0x30, -0x36, 0x39, 0xCF, 0xB9, 0x64, 0x41, 0x42, 0x3E, 0x5E, 0xD3, 0xCF, 0xC4, 0xEC, 0x47, 0x56, 0x5C, -0x50, 0x57, 0x62, 0xDF, 0xD2, 0xD3, 0xC4, 0xB6, 0xB3, 0xBA, 0xB8, 0xAD, 0xAF, 0x3C, 0x1C, 0x1E, -0xCB, 0xA1, 0xA9, 0xFE, 0x2D, 0x2C, 0x39, 0x3D, 0x64, 0xBE, 0xD5, 0x4B, 0x42, 0x3A, 0x40, 0xEC, -0xC4, 0xBE, 0xD1, 0x4A, 0x3E, 0x47, 0x62, 0xE4, 0xD7, 0xD6, 0xDC, 0xDE, 0xCD, 0xB6, 0xAD, 0xAE, -0xAC, 0xAD, 0xE6, 0x22, 0x19, 0x2E, 0xA6, 0x9E, 0xB2, 0x39, 0x28, 0x2D, 0x39, 0x4E, 0xC2, 0xBE, -0x5B, 0x3E, 0x3B, 0x3C, 0x58, 0xC6, 0xBD, 0xC7, 0x60, 0x3F, 0x3F, 0x51, 0xED, 0xCF, 0xC8, 0xD1, -0xE0, 0xD9, 0xBC, 0xAC, 0xAB, 0xAB, 0xA9, 0xC2, 0x25, 0x17, 0x22, 0xAE, 0x9D, 0xA9, 0x47, 0x26, -0x29, 0x34, 0x47, 0xC5, 0xBB, 0x77, 0x3F, 0x3A, 0x38, 0x4E, 0xC6, 0xBC, 0xBE, 0xE6, 0x3D, 0x39, -0x43, 0x67, 0xCE, 0xC7, 0xD6, 0xED, 0xD9, 0xBD, 0xAB, 0xAB, 0xAE, 0xA9, 0xB4, 0x30, 0x1A, 0x1B, -0xD5, 0x9D, 0xA3, 0xDA, 0x2A, 0x26, 0x31, 0x3C, 0x6C, 0xBF, 0xCE, 0x5E, 0x42, 0x32, 0x3C, 0xD6, -0xBC, 0xB8, 0xCC, 0x3F, 0x37, 0x3B, 0x51, 0xCC, 0xC1, 0xCC, 0xE2, 0xDE, 0xBD, 0xAC, 0xAA, 0xA9, -0xA7, 0xC5, 0x26, 0x18, 0x1F, 0xB7, 0x9D, 0xA6, 0xDF, 0x2B, 0x26, 0x2D, 0x37, 0xEB, 0xBA, 0xCB, -0x5E, 0x3C, 0x30, 0x44, 0xC9, 0xBB, 0xB8, 0xCF, 0x3D, 0x34, 0x3B, 0x5F, 0xC1, 0xBE, 0xCE, 0xD6, -0xCE, 0xB8, 0xAB, 0xAA, 0xA4, 0xA8, 0x42, 0x1C, 0x18, 0x31, 0xA4, 0x9F, 0xAF, 0x48, 0x29, 0x28, -0x2C, 0x37, 0xCC, 0xBA, 0xC7, 0x57, 0x30, 0x31, 0x5A, 0xC6, 0xB6, 0xB7, 0x5F, 0x38, 0x34, 0x3D, -0xE2, 0xBD, 0xBD, 0xC7, 0xD2, 0xCA, 0xB2, 0xAB, 0xA7, 0xA2, 0xB3, 0x29, 0x18, 0x1C, 0xD2, 0x9F, -0xA5, 0xBC, 0x3A, 0x2A, 0x29, 0x2A, 0x3E, 0xC3, 0xBB, 0xC1, 0x43, 0x2D, 0x3A, 0xF5, 0xC1, 0xB5, -0xBE, 0x4F, 0x36, 0x32, 0x3F, 0xD2, 0xBB, 0xBA, 0xBE, 0xC5, 0xBF, 0xB1, 0xAB, 0xA4, 0xA7, 0x75, -0x1F, 0x18, 0x27, 0xAE, 0xA2, 0xAD, 0xD6, 0x36, 0x2B, 0x28, 0x2C, 0x4E, 0xC2, 0xB8, 0xC9, 0x35, -0x2F, 0x42, 0x71, 0xBA, 0xB4, 0xD2, 0x44, 0x34, 0x34, 0x4C, 0xCD, 0xBE, 0xBB, 0xB9, 0xBC, 0xB3, -0xAE, 0xAB, 0xA3, 0xB0, 0x2C, 0x1A, 0x1C, 0x5F, 0xA4, 0xA9, 0xBA, 0x6F, 0x34, 0x28, 0x26, 0x32, -0x77, 0xB9, 0xB3, 0x5E, 0x32, 0x38, 0x40, 0xD8, 0xB6, 0xBE, 0xF4, 0x40, 0x34, 0x3A, 0x5B, 0xC7, -0xB7, 0xB4, 0xB7, 0xB4, 0xB2, 0xAE, 0xA5, 0xAB, 0x3B, 0x1D, 0x1B, 0x34, 0xAE, 0xAA, 0xB4, 0xC7, -0x42, 0x2C, 0x25, 0x2B, 0x43, 0xCF, 0xB5, 0xBE, 0x3F, 0x38, 0x3D, 0x4D, 0xC4, 0xBD, 0xCF, 0x5D, -0x3E, 0x38, 0x43, 0xE4, 0xBF, 0xB4, 0xAF, 0xB0, 0xAF, 0xAE, 0xA8, 0xA7, 0xF6, 0x21, 0x1A, 0x27, -0xBA, 0xAC, 0xB5, 0xB9, 0xE2, 0x36, 0x26, 0x25, 0x33, 0x4E, 0xBA, 0xB2, 0x64, 0x41, 0x3F, 0x3D, -0xE6, 0xC6, 0xCD, 0xD4, 0x50, 0x3D, 0x3C, 0x48, 0xD4, 0xB9, 0xAF, 0xAD, 0xAE, 0xAE, 0xAA, 0xA7, -0xC0, 0x2A, 0x1B, 0x1F, 0x65, 0xAF, 0xB5, 0xB5, 0xBF, 0x4C, 0x2C, 0x23, 0x2A, 0x37, 0xE6, 0xAF, -0xBC, 0x5B, 0x4B, 0x3B, 0x49, 0xCF, 0xCE, 0xD0, 0xDE, 0x4F, 0x40, 0x3F, 0x57, 0xC7, 0xB3, 0xAA, -0xA9, 0xAC, 0xAE, 0xA9, 0xAE, 0x3B, 0x1E, 0x1E, 0x37, 0xBA, 0xB7, 0xB7, 0xB5, 0xC9, 0x3A, 0x26, -0x27, 0x2E, 0x37, 0xC1, 0xB1, 0xCA, 0xE8, 0x49, 0x3E, 0x62, 0x78, 0xEF, 0xD7, 0x69, 0x4F, 0x44, -0x48, 0xFB, 0xC5, 0xAF, 0xA9, 0xA8, 0xAA, 0xAB, 0xAA, 0xCF, 0x26, 0x1C, 0x22, 0x4A, 0xBD, 0xBB, -0xAF, 0xB1, 0xD7, 0x31, 0x25, 0x27, 0x28, 0x38, 0xB9, 0xB6, 0xC3, 0xCB, 0x4B, 0x45, 0x4E, 0x47, -0x62, 0xE0, 0xF9, 0x5C, 0x4C, 0x5C, 0xE4, 0xBF, 0xAD, 0xA8, 0xA5, 0xA7, 0xA9, 0xB2, 0x36, 0x20, -0x1E, 0x29, 0x56, 0xCC, 0xB8, 0xAC, 0xB5, 0xFA, 0x2F, 0x28, 0x25, 0x25, 0x45, 0xBE, 0xBF, 0xB8, -0xC5, 0x5F, 0x54, 0x41, 0x43, 0x4F, 0x56, 0x75, 0x70, 0xFE, 0xE2, 0xD3, 0xB9, 0xAD, 0xA8, 0xA6, -0xA6, 0xA8, 0xCA, 0x2D, 0x22, 0x21, 0x2E, 0x47, 0x77, 0xB4, 0xAD, 0xB7, 0xDC, 0x39, 0x2D, 0x24, -0x28, 0x40, 0x5A, 0xC7, 0xB5, 0xBD, 0xC0, 0xDB, 0x4E, 0x4C, 0x40, 0x44, 0x4E, 0x56, 0xDA, 0xCC, -0xC0, 0xB1, 0xAC, 0xA7, 0xA5, 0xA6, 0xAD, 0x4F, 0x2A, 0x23, 0x25, 0x2F, 0x39, 0x6C, 0xB6, 0xB1, -0xB7, 0xD6, 0x43, 0x2F, 0x26, 0x2C, 0x35, 0x3A, 0xDF, 0xC7, 0xBE, 0xBA, 0xCB, 0xD4, 0x6E, 0x48, -0x44, 0x3E, 0x4A, 0x6C, 0xD6, 0xB9, 0xB0, 0xA8, 0xA4, 0xA5, 0xA4, 0xB5, 0x42, 0x2C, 0x23, 0x27, -0x2B, 0x2E, 0x55, 0xC2, 0xB9, 0xB6, 0xC5, 0xF4, 0x3C, 0x32, 0x34, 0x2F, 0x37, 0x4A, 0x5B, 0xCF, -0xC9, 0xC6, 0xC0, 0xCA, 0xCF, 0xF4, 0x52, 0x51, 0x4E, 0xF8, 0xC4, 0xB7, 0xAD, 0xA9, 0xA6, 0xA7, -0xB8, 0x5D, 0x38, 0x2F, 0x2E, 0x2B, 0x2C, 0x35, 0x42, 0x5D, 0x7D, 0xE3, 0xDF, 0x6F, 0x73, 0x5A, -0x4D, 0x55, 0x4F, 0x4F, 0x58, 0x5C, 0x6E, 0xFA, 0xE2, 0xD4, 0xD4, 0xD6, 0xD9, 0xD6, 0xCC, 0xC6, -0xBF, 0xBB, 0xB8, 0xB6, 0xBC, 0xC9, 0xDC, 0x60, 0x59, 0x53, 0x4A, 0x49, 0x46, 0x45, 0x46, 0x43, -0x45, 0x45, 0x49, 0x56, 0x5A, 0x5D, 0x6E, 0x72, 0x7C, 0x74, 0x6D, 0x7A, 0x7A, 0xFC, 0xED, 0xE8, -0xEB, 0xFF, 0xFD, 0xEC, 0xDE, 0xD2, 0xCC, 0xC7, 0xC5, 0xCA, 0xD2, 0xD9, 0xDB, 0xD4, 0xCF, 0xD1, -0xD9, 0xE7, 0xFC, 0x6E, 0x60, 0x57, 0x50, 0x4C, 0x49, 0x47, 0x46, 0x45, 0x47, 0x4A, 0x4D, 0x4F, -0x4F, 0x53, 0x5A, 0x5F, 0x62, 0x60, 0x62, 0x6B, 0x77, 0xEC, 0xD8, 0xCC, 0xC7, 0xC7, 0xCB, 0xCF, -0xD3, 0xD3, 0xCE, 0xCB, 0xCA, 0xCC, 0xCF, 0xD4, 0xD9, 0xDF, 0xEB, 0xFE, 0x6A, 0x58, 0x4D, 0x46, -0x43, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x52, 0x54, 0x55, 0x54, 0x57, 0x5C, 0x61, 0x72, 0xE5, -0xD4, 0xCC, 0xCB, 0xCD, 0xD0, 0xD4, 0xD3, 0xD1, 0xD0, 0xCF, 0xD1, 0xD2, 0xD4, 0xD6, 0xD9, 0xDB, -0xDB, 0xDD, 0xEC, 0x6B, 0x59, 0x53, 0x54, 0x57, 0x59, 0x58, 0x57, 0x5A, 0x5C, 0x5A, 0x55, 0x52, -0x52, 0x51, 0x51, 0x57, 0x61, 0xFC, 0xE3, 0xDF, 0xE0, 0xE4, 0xE3, 0xE0, 0xDF, 0xDE, 0xDD, 0xDE, -0xDD, 0xDF, 0xE0, 0xDF, 0xDC, 0xD9, 0xDC, 0xE7, 0x7E, 0x6B, 0x6D, 0x7C, 0xEE, 0xE6, 0xE7, 0xEA, -0xEC, 0xF5, 0x7A, 0x6A, 0x61, 0x5A, 0x51, 0x4F, 0x50, 0x55, 0x5D, 0x62, 0x63, 0x60, 0x5F, 0x61, -0x65, 0x68, 0x6D, 0x75, 0xFA, 0xF1, 0xF1, 0xEE, 0xE6, 0xDD, 0xDB, 0xDE, 0xEB, 0x79, 0x6B, 0x6F, -0xF7, 0xE2, 0xDC, 0xDB, 0xDA, 0xDA, 0xDC, 0xDD, 0xDE, 0xE0, 0xF1, 0x6B, 0x5F, 0x5F, 0x66, 0x6B, -0x6A, 0x65, 0x5E, 0x5B, 0x5A, 0x59, 0x5A, 0x5C, 0x5E, 0x5E, 0x5E, 0x5E, 0x68, 0xFC, 0xE8, 0xE5, -0xEB, 0xFB, 0x71, 0x6D, 0x78, 0xEE, 0xE2, 0xDE, 0xDD, 0xDC, 0xDE, 0xDF, 0xDC, 0xD9, 0xD9, 0xE0, -0xED, 0xF0, 0xEC, 0xE4, 0xE2, 0xE6, 0xEE, 0x7C, 0x6D, 0x65, 0x5E, 0x5E, 0x62, 0x64, 0x61, 0x5C, -0x5B, 0x5F, 0x70, 0xF7, 0xF8, 0x78, 0x6B, 0x65, 0x61, 0x69, 0xFA, 0xE9, 0xE5, 0xE2, 0xE5, 0xEA, -0xED, 0xEB, 0xE5, 0xE5, 0xED, 0xF9, 0xFC, 0xEF, 0xE3, 0xDE, 0xDE, 0xE1, 0xE9, 0xF4, 0x74, 0x6A, -0x6B, 0x6F, 0x6F, 0x67, 0x5E, 0x5C, 0x5F, 0x6A, 0x6F, 0x6C, 0x66, 0x5F, 0x5D, 0x5E, 0x64, 0x6F, -0xFE, 0xEF, 0xEC, 0xF2, 0xFD, 0x7E, 0xFB, 0xF6, 0xFF, 0x6F, 0x6A, 0x6A, 0x74, 0xF4, 0xE9, 0xE4, -0xE7, 0xEE, 0x7D, 0x6A, 0x69, 0x6F, 0xFE, 0xF7, 0x7B, 0x6B, 0x68, 0x6E, 0x79, 0x78, 0x6F, 0x69, -0x62, 0x5F, 0x60, 0x66, 0x72, 0xF6, 0xEB, 0xEC, 0xF3, 0xFC, 0xFA, 0xF2, 0xF2, 0xFE, 0x70, 0x69, -0x69, 0x71, 0xF7, 0xE8, 0xE3, 0xE4, 0xED, 0x76, 0x69, 0x6A, 0x6F, 0x7E, 0xFB, 0x7D, 0x75, 0x73, -0x7C, 0xFB, 0xFC, 0x7D, 0x73, 0x6D, 0x6A, 0x69, 0x6F, 0xFD, 0xEC, 0xE8, 0xED, 0xF6, 0xF7, 0xF1, -0xED, 0xEF, 0xF6, 0x7E, 0x76, 0x78, 0xFB, 0xEC, 0xE2, 0xDE, 0xE0, 0xEB, 0xFE, 0x73, 0x73, 0x7E, -0xFA, 0xFC, 0xFF, 0x7B, 0x7D, 0xFC, 0xFE, 0x7B, 0x74, 0x6F, 0x6D, 0x6C, 0x6E, 0x77, 0xFA, 0xEE, -0xED, 0xF6, 0x7A, 0x73, 0x77, 0x7B, 0x7C, 0x78, 0x6E, 0x6B, 0x6F, 0x7C, 0xEF, 0xE7, 0xE2, 0xE6, -0xF2, 0x7A, 0x71, 0x75, 0x7D, 0xFE, 0xFD, 0xFD, 0xFB, 0xF5, 0xF7, 0xFE, 0x77, 0x6E, 0x6A, 0x67, -0x67, 0x6C, 0x76, 0xF7, 0xEE, 0xEF, 0xFA, 0x7B, 0x78, 0x7B, 0xFF, 0x7F, 0x78, 0x6F, 0x6C, 0x6C, -0x72, 0xFE, 0xEF, 0xEC, 0xEF, 0xFD, 0x76, 0x70, 0x71, 0x75, 0x7A, 0x7E, 0x7E, 0xFF, 0xFC, 0xFD, -0x7C, 0x73, 0x6D, 0x69, 0x65, 0x63, 0x65, 0x6B, 0x79, 0xFB, 0xFD, 0x78, 0x70, 0x70, 0x74, 0x79, -0x7C, 0x7B, 0x79, 0x77, 0x78, 0x7F, 0xF4, 0xED, 0xED, 0xF2, 0xFB, 0x7A, 0x74, 0x74, 0x76, 0x7A, -0x7F, 0xFB, 0xF5, 0xF4, 0xF6, 0xFA, 0x7D, 0x75, 0x6E, 0x6B, 0x6B, 0x6F, 0x7D, 0xF3, 0xEF, 0xF4, -0x7E, 0x78, 0x7A, 0xFF, 0xFA, 0xF7, 0xF5, 0xF4, 0xF4, 0xF1, 0xED, 0xE9, 0xE6, 0xE8, 0xEE, 0xF8, -0x7F, 0x7C, 0x7A, 0x7A, 0x7B, 0x7D, 0xFD, 0xF8, 0xF8, 0xF9, 0xFC, 0x7D, 0x74, 0x6C, 0x69, 0x69, -0x6C, 0x76, 0xFA, 0xF6, 0xFD, 0x78, 0x71, 0x6F, 0x6F, 0x6F, 0x71, 0x74, 0x77, 0x7C, 0xFD, 0xF5, -0xEC, 0xE9, 0xEA, 0xEF, 0xFB, 0x7A, 0x74, 0x73, 0x73, 0x73, 0x73, 0x78, 0x7E, 0xFE, 0xFD, 0xFE, -0x7B, 0x74, 0x6D, 0x68, 0x66, 0x69, 0x6F, 0x7B, 0x7F, 0x7C, 0x77, 0x73, 0x72, 0x6F, 0x6D, 0x6D, -0x6D, 0x6D, 0x6E, 0x72, 0x7A, 0xFA, 0xF1, 0xEE, 0xEF, 0xF6, 0xFD, 0x7D, 0x7B, 0x7A, 0x78, 0x78, -0x79, 0x79, 0x7A, 0x7C, 0x7D, 0x7E, 0x7D, 0x77, 0x70, 0x6E, 0x71, 0x79, 0x7E, 0x7E, 0x7E, 0x7D, -0x7E, 0x7D, 0x7C, 0x7A, 0x78, 0x76, 0x74, 0x73, 0x75, 0x7A, 0xFC, 0xF6, 0xF4, 0xF4, 0xF6, 0xF6, -0xF6, 0xF9, 0xF9, 0xF7, 0xF5, 0xF3, 0xF1, 0xF1, 0xF3, 0xF5, 0xF7, 0xFA, 0x7B, 0x6F, 0x6D, 0x6D, -0x6F, 0x6F, 0x6E, 0x6E, 0x70, 0x70, 0x71, 0x74, 0x78, 0x7C, 0x7D, 0x7E, 0x7D, 0xFF, 0xFB, 0xF7, -0xF4, 0xF4, 0xF6, 0xF8, 0xFB, 0xFD, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x7F, 0xFF, 0xFC, 0xF8, -0xF9, 0xFD, 0x7D, 0x7C, 0x7F, 0xFE, 0x7E, 0x7C, 0x7A, 0x79, 0x77, 0x75, 0x75, 0x76, 0x79, 0x76, -0x71, 0x6F, 0x6F, 0x71, 0x76, 0x78, 0x78, 0x78, 0x7B, 0x7D, 0x7A, 0x77, 0x76, 0x76, 0x78, 0x79, -0x78, 0x79, 0x7C, 0xFD, 0xF4, 0xF1, 0xF2, 0xF5, 0xF9, 0xFB, 0x7F, 0x79, 0x76, 0x76, 0x78, 0x77, -0x77, 0x7B, 0xFF, 0xFA, 0xF6, 0xF6, 0xF7, 0xF6, 0xF6, 0xF7, 0xF9, 0xFA, 0xF9, 0xF6, 0xF6, 0xF9, -0xFB, 0xFE, 0x7F, 0x7E, 0x7C, 0x79, 0x7A, 0xFE, 0xF5, 0xEF, 0xEE, 0xEF, 0xF1, 0xF3, 0xF4, 0xFB, -0x79, 0x73, 0x72, 0x6E, 0x6B, 0x68, 0x68, 0x6C, 0x73, 0x7A, 0x7C, 0x7B, 0x7B, 0x7D, 0x7D, 0xFD, -0xF6, 0xF0, 0xEE, 0xEF, 0xF6, 0xFB, 0xFF, 0x7D, 0x7F, 0x7D, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, 0x7B, -0x7A, 0xFF, 0xFD, 0xFF, 0x7E, 0x7A, 0x75, 0x74, 0x71, 0x6F, 0x6F, 0x70, 0x77, 0x7A, 0x78, 0x75, -0x72, 0x75, 0x73, 0x6F, 0x6F, 0x70, 0x75, 0x77, 0x76, 0x78, 0x75, 0x78, 0x7B, 0x7B, 0x7F, 0x7B, -0x7E, 0x7F, 0x7E, 0x7E, 0x77, 0x79, 0x73, 0x71, 0x71, 0x6B, 0x6F, 0x60, 0x5B, 0x6F, 0x72, 0x69, -0x71, 0x72, 0x7E, 0xFC, 0xF7, 0xEE, 0xF4, 0xFB, 0x7E, 0x7E, 0xFC, 0xF9, 0xFD, 0x7F, 0xFC, 0x72, -0x78, 0x64, 0x53, 0x71, 0xDF, 0xF0, 0xEB, 0xE9, 0xF0, 0x7C, 0x7B, 0xEA, 0xF6, 0x7E, 0x79, 0x6C, -0x79, 0x5F, 0x5B, 0xEC, 0xE2, 0xEF, 0xED, 0xF1, 0xF7, 0xFE, 0x7C, 0xFE, 0x75, 0x6E, 0x75, 0x79, -0x7A, 0x72, 0x6E, 0x75, 0x7A, 0x7B, 0x77, 0x77, 0xFE, 0xF8, 0xF6, 0xF5, 0xEB, 0xE9, 0xEC, 0xE8, -0xEE, 0xEC, 0xED, 0x77, 0xFD, 0x61, 0x51, 0x66, 0xE7, 0xDC, 0xD8, 0xD3, 0xD3, 0x6C, 0x52, 0x63, -0x6F, 0x73, 0x7F, 0xFB, 0xF4, 0x79, 0x7B, 0xF1, 0xED, 0xEC, 0xFA, 0x76, 0x7A, 0x74, 0x6B, 0x6B, -0x75, 0x7C, 0x7C, 0x79, 0xFE, 0xF6, 0xFE, 0x7A, 0x71, 0x75, 0xFF, 0x70, 0x6D, 0x6E, 0x69, 0x66, -0x5E, 0x62, 0xFA, 0xEA, 0xE5, 0xE0, 0xE1, 0xE5, 0xEE, 0xF1, 0xE5, 0xE4, 0xEA, 0xE8, 0xE7, 0xE7, -0xE3, 0xE7, 0xE8, 0xE8, 0xEF, 0xF7, 0x78, 0x6E, 0x6D, 0x60, 0x5A, 0x57, 0x54, 0x53, 0x51, 0x50, -0x52, 0x54, 0x57, 0x59, 0x5D, 0x67, 0x70, 0x7B, 0xF5, 0xE5, 0xDA, 0xD5, 0xD2, 0xCD, 0xC4, 0xBE, -0xBB, 0xB7, 0xB5, 0xBB, 0xCB, 0xDE, 0xE9, 0x56, 0x3F, 0x3A, 0x39, 0x3B, 0x3B, 0x3A, 0x3F, 0x4E, -0x5D, 0x69, 0xF2, 0xDD, 0xD9, 0xE2, 0xF3, 0xF4, 0x72, 0x5C, 0x53, 0x4E, 0x4D, 0x4E, 0x4E, 0x4F, -0x58, 0x7E, 0xDA, 0xCB, 0xBF, 0xBA, 0xB7, 0xB4, 0xB0, 0xAE, 0xB2, 0xBE, 0xD7, 0x70, 0x4E, 0x3B, -0x32, 0x30, 0x33, 0x35, 0x35, 0x3A, 0x49, 0x5F, 0x7E, 0xEF, 0xE1, 0xD2, 0xD1, 0xE6, 0xEF, 0xF7, -0x5F, 0x4F, 0x48, 0x48, 0x4B, 0x48, 0x4B, 0x55, 0x72, 0xE1, 0xD2, 0xC2, 0xBA, 0xB6, 0xB3, 0xB0, -0xAD, 0xAE, 0xBA, 0xD0, 0x64, 0x4C, 0x3C, 0x30, 0x2E, 0x2F, 0x33, 0x35, 0x3A, 0x47, 0x6C, 0xE6, -0xEB, 0xD0, 0xC6, 0xCC, 0xD6, 0xE3, 0xEF, 0x69, 0x4E, 0x4B, 0x4B, 0x47, 0x46, 0x48, 0x4F, 0x61, -0xFE, 0xD1, 0xBE, 0xB8, 0xB5, 0xB2, 0xAF, 0xAD, 0xAE, 0xBA, 0xCD, 0x5F, 0x47, 0x3B, 0x2F, 0x2D, -0x2E, 0x30, 0x35, 0x3B, 0x47, 0x6C, 0xF4, 0xE2, 0xCB, 0xC7, 0xCD, 0xD7, 0xDD, 0xE3, 0x6E, 0x4E, -0x4A, 0x4B, 0x48, 0x47, 0x4A, 0x5B, 0xE4, 0xD3, 0xC0, 0xB7, 0xB3, 0xB0, 0xAF, 0xAC, 0xAC, 0xB3, -0xC4, 0x7D, 0x4C, 0x3E, 0x30, 0x2C, 0x2E, 0x31, 0x35, 0x3A, 0x45, 0x62, 0xFA, 0xEB, 0xCE, 0xCA, -0xD2, 0xDA, 0xE7, 0xE9, 0x6D, 0x4C, 0x49, 0x49, 0x47, 0x48, 0x4C, 0x68, 0xD7, 0xCA, 0xBC, 0xB5, -0xB2, 0xB0, 0xAE, 0xAC, 0xAE, 0xB9, 0xCE, 0x5D, 0x45, 0x39, 0x2F, 0x2D, 0x2E, 0x31, 0x36, 0x3B, -0x47, 0x5C, 0x6E, 0xE4, 0xD3, 0xD3, 0xD4, 0xDA, 0xDE, 0xEB, 0x5B, 0x4D, 0x4A, 0x47, 0x48, 0x49, -0x54, 0xEB, 0xCE, 0xBE, 0xB8, 0xB7, 0xB3, 0xB3, 0xB5, 0xB3, 0xBB, 0xC9, 0xC8, 0xED, 0x47, 0x42, -0x3A, 0x36, 0x37, 0x34, 0x39, 0x3E, 0x3F, 0x47, 0x4E, 0x65, 0xDE, 0xEC, 0xDC, 0xCE, 0xD9, 0xEB, -0x5F, 0x54, 0x51, 0x47, 0x46, 0x4C, 0x58, 0xFC, 0xD8, 0xC4, 0xBB, 0xBA, 0xB8, 0xB5, 0xB2, 0xAF, -0xB0, 0xB6, 0xBD, 0xCC, 0x66, 0x47, 0x3B, 0x34, 0x32, 0x32, 0x34, 0x38, 0x3B, 0x3F, 0x4B, 0x58, -0x69, 0xE9, 0xD9, 0xD4, 0xDB, 0x77, 0x5C, 0x59, 0x4F, 0x4A, 0x4B, 0x51, 0x69, 0xE0, 0xCE, 0xC2, -0xBD, 0xBC, 0xBA, 0xB8, 0xB7, 0xB4, 0xB2, 0xB7, 0xC3, 0xCE, 0xD4, 0x67, 0x44, 0x3D, 0x3C, 0x3B, -0x38, 0x38, 0x3B, 0x3F, 0x42, 0x46, 0x4E, 0x5F, 0x6A, 0x6B, 0xFD, 0xF7, 0x70, 0x5C, 0x54, 0x58, -0x58, 0x53, 0x5B, 0x73, 0xE5, 0xD2, 0xCA, 0xC6, 0xC2, 0xBF, 0xBE, 0xBE, 0xBD, 0xBB, 0xBC, 0xC3, -0xCA, 0xD0, 0xE2, 0x5F, 0x4E, 0x4A, 0x44, 0x3E, 0x3D, 0x3D, 0x3F, 0x42, 0x44, 0x4B, 0x55, 0x57, -0x5F, 0x69, 0x68, 0x63, 0x58, 0x56, 0x5B, 0x56, 0x57, 0x66, 0x79, 0xE8, 0xD9, 0xCF, 0xCB, 0xCB, -0xC8, 0xC4, 0xC5, 0xC6, 0xC9, 0xC9, 0xC6, 0xCD, 0xD4, 0xD8, 0xE2, 0xF1, 0x66, 0x5C, 0x57, 0x4C, -0x49, 0x49, 0x48, 0x49, 0x49, 0x4B, 0x51, 0x51, 0x4F, 0x53, 0x56, 0x58, 0x58, 0x54, 0x58, 0x5F, -0x5E, 0x5B, 0x63, 0xF2, 0xE5, 0xE5, 0xD7, 0xCF, 0xD2, 0xD6, 0xD1, 0xCF, 0xD6, 0xD6, 0xD2, 0xCF, -0xCE, 0xD0, 0xD8, 0xDB, 0xDB, 0xE5, 0x6D, 0x67, 0x65, 0x5C, 0x58, 0x54, 0x59, 0x5D, 0x57, 0x57, -0x5B, 0x5B, 0x59, 0x56, 0x57, 0x5A, 0x56, 0x52, 0x5A, 0x5C, 0x5D, 0x7D, 0xF1, 0xF3, 0xE7, 0xE3, -0xDF, 0xDB, 0xDA, 0xE7, 0xEC, 0xDE, 0xE5, 0xE9, 0xE6, 0xE4, 0xD6, 0xDF, 0xF8, 0xDE, 0xE9, 0x7C, -0xEE, 0xFB, 0x7A, 0x6B, 0x65, 0xFF, 0x79, 0x69, 0x6B, 0x63, 0x65, 0x62, 0x56, 0x5A, 0x60, 0x55, -0x58, 0x62, 0x5E, 0x64, 0x79, 0x7C, 0x78, 0xED, 0xE1, 0xEC, 0xF0, 0xE4, 0xF0, 0x6E, 0x7C, 0xED, -0xDD, 0xDB, 0xFE, 0x73, 0xED, 0xF0, 0xFF, 0xF9, 0xDE, 0xDC, 0x76, 0x6E, 0xFB, 0x7B, 0xFB, 0x6F, -0x6F, 0xEF, 0x7B, 0x6E, 0xF8, 0xE9, 0x7E, 0x5B, 0x5F, 0xF3, 0xFD, 0x67, 0x74, 0xEA, 0xEF, 0x77, -0x6D, 0x7C, 0xE8, 0xE2, 0xEE, 0xFB, 0xE6, 0xED, 0x66, 0x6C, 0x7B, 0x7C, 0xF4, 0xEF, 0xE2, 0xE6, -0x72, 0x70, 0xF0, 0xEE, 0x6E, 0x6B, 0xFB, 0xF5, 0xF6, 0x71, 0x6A, 0x6C, 0x65, 0x67, 0x5F, 0x5D, -0x6B, 0x62, 0x65, 0xFD, 0xED, 0xE9, 0xF2, 0xED, 0xE3, 0xE7, 0xE4, 0xE8, 0xED, 0xEF, 0x66, 0x5E, -0x79, 0x7E, 0x78, 0xF5, 0xFA, 0x79, 0x7A, 0xF5, 0xE7, 0xE2, 0xE4, 0xF2, 0xFF, 0x73, 0x66, 0x6B, -0x70, 0xFD, 0xEF, 0x6F, 0x67, 0x5F, 0x5C, 0x6B, 0x6E, 0x78, 0x77, 0x6D, 0xF1, 0xF4, 0xF8, 0xE5, -0xE9, 0xEB, 0xEC, 0xEF, 0xEF, 0xF0, 0xE7, 0xED, 0x6B, 0x6F, 0xF0, 0xFF, 0x6A, 0x6F, 0x7E, 0x6F, -0x69, 0xED, 0xDF, 0xFF, 0x7C, 0xEB, 0xF3, 0xF8, 0x7E, 0x7A, 0xFB, 0x6E, 0x5E, 0x60, 0x70, 0x7A, -0xFC, 0xF4, 0xFF, 0xEF, 0xF5, 0x72, 0xF1, 0xEC, 0xEA, 0xE1, 0xE9, 0xED, 0xF2, 0xFC, 0xE7, 0xF0, -0x68, 0x76, 0xEF, 0xF4, 0xF9, 0x77, 0x79, 0xFB, 0xFC, 0xF6, 0xEE, 0xE9, 0xF2, 0x6D, 0x70, 0x6F, -0x6F, 0xFE, 0x6A, 0x69, 0x7F, 0x6F, 0x6F, 0x79, 0x78, 0x77, 0x6E, 0xFE, 0xEE, 0xF0, 0xEF, 0x7E, -0xF4, 0xE9, 0xF8, 0xFD, 0x7C, 0x77, 0x7D, 0x78, 0x7D, 0xFE, 0x79, 0x72, 0x6E, 0x72, 0x7B, 0x73, -0x6B, 0x74, 0x76, 0x6C, 0x72, 0x70, 0x75, 0x6D, 0x5A, 0x5C, 0x6A, 0x77, 0xFE, 0x71, 0x7A, 0xF2, -0xE9, 0xE7, 0xEA, 0xDE, 0xE6, 0xF5, 0xEB, 0xF5, 0xEE, 0xEA, 0xF3, 0xEE, 0xF4, 0xEE, 0xF5, 0x73, -0xF4, 0xF6, 0x73, 0x7C, 0xEC, 0xE9, 0x72, 0x67, 0x6C, 0x70, 0x6E, 0x69, 0x6F, 0x68, 0x5D, 0x64, -0x71, 0x75, 0x6B, 0x6D, 0xF9, 0x79, 0x6F, 0xF4, 0xEA, 0xF5, 0x79, 0x7B, 0x7D, 0xFA, 0xF3, 0xF7, -0xF4, 0xF4, 0xF9, 0x7F, 0x77, 0x7F, 0xF5, 0xFD, 0x71, 0x71, 0x7B, 0x78, 0x7A, 0x73, 0x68, 0x71, -0x7A, 0x6B, 0x6C, 0x6E, 0x69, 0x6E, 0x71, 0x6C, 0x69, 0x6C, 0x7A, 0x7D, 0xF6, 0xEB, 0xF4, 0xF2, -0xF4, 0x78, 0xF8, 0xF1, 0xF6, 0xFE, 0x71, 0x75, 0x7C, 0x7B, 0x7D, 0x7E, 0xFB, 0x7E, 0x77, 0x76, -0xFF, 0xF7, 0x79, 0x70, 0x6E, 0x6C, 0x71, 0x6F, 0x6C, 0x6A, 0x70, 0x6E, 0x5F, 0x65, 0x6C, 0x66, -0x6D, 0x7A, 0xF1, 0x78, 0x6B, 0xED, 0xFB, 0x6C, 0x7C, 0x74, 0xF1, 0xEC, 0x76, 0xF9, 0xF8, 0x75, -0x71, 0x7A, 0xEC, 0xFA, 0x6C, 0x76, 0x7C, 0x7F, 0x6E, 0x6A, 0x76, 0x6C, 0x76, 0xF2, 0x7C, 0x76, -0x66, 0x62, 0x7D, 0xF9, 0x78, 0x69, 0x6A, 0xF8, 0x78, 0x6D, 0xFC, 0xF8, 0xF3, 0xF7, 0x7D, 0xEF, -0xF1, 0x7C, 0xF1, 0xE9, 0xEB, 0xEE, 0xF3, 0xFD, 0x73, 0x7D, 0xFA, 0x74, 0x78, 0x7A, 0x6E, 0x70, -0x76, 0x73, 0x6F, 0x6D, 0x6C, 0x68, 0x6D, 0x7D, 0x6E, 0x64, 0x6D, 0xFC, 0xFA, 0x71, 0x6F, 0xFF, -0x70, 0x70, 0xF0, 0xEE, 0xEF, 0xEB, 0xEC, 0xEC, 0xED, 0xF0, 0xEE, 0xE9, 0xEB, 0xF8, 0xFB, 0xED, -0xE9, 0xF7, 0xFF, 0xED, 0xEE, 0xEF, 0xF3, 0x6E, 0x70, 0xF3, 0xFF, 0x6F, 0x6F, 0x6F, 0x79, 0x7C, -0x79, 0x7E, 0x77, 0x6E, 0x6E, 0x7B, 0x7C, 0x6B, 0x72, 0xF6, 0xFF, 0x7D, 0x7D, 0x72, 0x78, 0xFB, -0xFD, 0xFB, 0xFA, 0x7D, 0x7A, 0x6D, 0x68, 0x74, 0x75, 0xF1, 0xE7, 0x7B, 0x76, 0x6B, 0x66, 0xFD, -0x73, 0x68, 0x6B, 0x73, 0x7C, 0x62, 0x64, 0x70, 0x64, 0x6D, 0x79, 0x70, 0x70, 0x74, 0xF8, 0x7C, -0x7C, 0xF8, 0x6B, 0x70, 0xF9, 0x7D, 0xF1, 0xF0, 0xFF, 0x7F, 0xF8, 0xED, 0xF2, 0xFC, 0xFF, 0x76, -0x7B, 0x7C, 0xFE, 0xFE, 0x6C, 0x7C, 0xED, 0x79, 0x77, 0x71, 0x69, 0x76, 0x7A, 0x76, 0x7A, 0x6F, -0x6E, 0x6E, 0x73, 0xFF, 0x78, 0x76, 0x7F, 0x7A, 0x6F, 0x78, 0xFE, 0x77, 0xFB, 0xEE, 0xEE, 0xF1, -0x7A, 0xFB, 0xEE, 0x75, 0x70, 0xFE, 0x7D, 0x72, 0x6D, 0x6F, 0x7B, 0xFB, 0xF9, 0x7C, 0x7E, 0x7A, -0x70, 0x76, 0x7B, 0xF7, 0xF5, 0x70, 0x74, 0xFF, 0x78, 0xFA, 0xFC, 0x79, 0x78, 0x6D, 0x7A, 0xFA, -0x77, 0xFC, 0xF4, 0xF1, 0xF1, 0xF7, 0xEB, 0xED, 0xFB, 0xF7, 0xEF, 0xF2, 0x78, 0x79, 0xF0, 0xF3, -0xFC, 0xFC, 0x7E, 0x77, 0xFF, 0xFC, 0x78, 0xF6, 0xF9, 0x6F, 0x7A, 0x78, 0x6F, 0xFF, 0xF9, 0x7E, -0x76, 0x72, 0x76, 0x78, 0x79, 0xFD, 0xFA, 0x7A, 0x7E, 0xF1, 0xFB, 0x7A, 0xF2, 0xEF, 0xFF, 0x74, -0x75, 0x7E, 0xFF, 0xF6, 0xE9, 0xF4, 0x71, 0x74, 0x74, 0x7C, 0xF8, 0x79, 0x75, 0x74, 0x73, 0xF9, -0xFE, 0xFF, 0xFA, 0x6A, 0x6C, 0xFE, 0x70, 0x72, 0x7C, 0x7D, 0x70, 0x67, 0x6F, 0x76, 0x7B, 0xF0, -0x7E, 0x6E, 0x6E, 0x76, 0xF1, 0xF2, 0x7A, 0x72, 0x7B, 0xFD, 0x79, 0x77, 0x6E, 0x6A, 0x6D, 0x6E, -0x74, 0x72, 0x77, 0xF5, 0x7C, 0x6D, 0x6C, 0x6D, 0x70, 0x76, 0xFD, 0xFC, 0xFF, 0xFE, 0xFE, 0xFA, -0x7D, 0x77, 0x74, 0x6F, 0xFB, 0xFA, 0x71, 0xFC, 0xF8, 0xFE, 0xEB, 0xE5, 0xEE, 0x7F, 0xF6, 0xED, -0xFA, 0x78, 0xF6, 0xF1, 0xF8, 0xF6, 0x79, 0x70, 0x7C, 0x75, 0x78, 0xF6, 0xFA, 0xFC, 0xFB, 0x7B, -0x7D, 0xF9, 0xF7, 0xF7, 0x7E, 0x6B, 0x68, 0xFA, 0xE6, 0xEE, 0x7B, 0x7B, 0x79, 0x7E, 0xFB, 0xF2, -0xEA, 0xEE, 0xF1, 0xF6, 0x79, 0xFB, 0xF0, 0xFB, 0xFF, 0xF0, 0xEE, 0xF4, 0xEF, 0xFB, 0x6F, 0x6C, -0x72, 0xFF, 0x71, 0x6C, 0x6A, 0x6D, 0xF4, 0xFB, 0x7C, 0xF3, 0xFA, 0xFC, 0x6F, 0x73, 0xFB, 0x72, -0x7D, 0x78, 0x76, 0xEF, 0xF3, 0x7C, 0x71, 0xFA, 0xF2, 0xFB, 0xEF, 0xF0, 0xEA, 0xFD, 0x6B, 0xED, -0xF2, 0x77, 0x6E, 0x6D, 0xFD, 0x64, 0xF3, 0xDF, 0x5C, 0x61, 0xED, 0xF2, 0x7E, 0x66, 0x73, 0x6E, -0x66, 0xFF, 0x6F, 0x72, 0x70, 0x66, 0xF3, 0xF7, 0x6F, 0x72, 0x75, 0xED, 0xEF, 0xF4, 0xED, 0xEF, -0xEF, 0x6E, 0x6F, 0xF7, 0x72, 0x7E, 0x78, 0x6F, 0xF9, 0x77, 0xFC, 0xF4, 0x6C, 0x66, 0x6A, 0x76, -0x65, 0x5C, 0x6D, 0xFF, 0xF8, 0xEA, 0xE2, 0xEF, 0x65, 0x70, 0xEB, 0xE8, 0xE2, 0xDF, 0xDA, 0xD9, -0xE3, 0xF0, 0xFA, 0xE6, 0xDD, 0xDF, 0xDF, 0xE0, 0xE4, 0xFC, 0x63, 0x60, 0x64, 0x63, 0x66, 0x78, -0x65, 0x57, 0x60, 0x67, 0x64, 0x67, 0x5F, 0x6E, 0xF3, 0x7F, 0x75, 0xFE, 0xEA, 0xF4, 0xF8, 0xE0, -0xE0, 0xE4, 0xE3, 0xE7, 0xEA, 0xFB, 0x6F, 0x6E, 0x75, 0x72, 0x68, 0x6E, 0x77, 0x74, 0x6D, 0x73, -0xF9, 0x74, 0xF2, 0xE2, 0xEF, 0xDE, 0xDD, 0x79, 0xFD, 0xF4, 0x6F, 0x6A, 0x6E, 0xFE, 0x7A, 0x68, -0x60, 0x63, 0x6B, 0x66, 0x67, 0x76, 0xFE, 0x78, 0x65, 0x63, 0x7A, 0xFF, 0x72, 0x72, 0x74, 0x7D, -0x7C, 0x6B, 0x72, 0xEF, 0xF6, 0x73, 0x74, 0x7C, 0x74, 0x68, 0x68, 0x73, 0xFA, 0xF6, 0x6F, 0x67, -0x6F, 0x6D, 0x6A, 0x69, 0x68, 0x74, 0x6D, 0x64, 0x6F, 0x75, 0x77, 0xFA, 0x7F, 0xF5, 0xEF, 0x78, -0x77, 0x7D, 0x7A, 0xFE, 0x77, 0x73, 0xF8, 0xF4, 0xFE, 0x6F, 0x71, 0xF7, 0x74, 0x79, 0xEF, 0x7B, -0xF9, 0xFA, 0x68, 0x71, 0x7F, 0x76, 0x73, 0x71, 0x7D, 0x7D, 0x65, 0x5D, 0x69, 0x6E, 0x5F, 0x67, -0x6F, 0x6D, 0xFF, 0x7F, 0x6E, 0x6F, 0x73, 0x77, 0xF2, 0xDE, 0xD4, 0xD0, 0xD0, 0xCF, 0xCE, 0xD0, -0xD2, 0xD6, 0xDA, 0xDB, 0xE7, 0x6D, 0x5B, 0x52, 0x4C, 0x47, 0x44, 0x43, 0x44, 0x47, 0x49, 0x4B, -0x4E, 0x52, 0x56, 0x5A, 0x5D, 0x64, 0x75, 0xE6, 0xCF, 0xC5, 0xBF, 0xBD, 0xBB, 0xB7, 0xB5, 0xB1, -0xAF, 0xB5, 0xC1, 0xDF, 0x51, 0x44, 0x3A, 0x33, 0x33, 0x37, 0x3D, 0x44, 0x48, 0x4D, 0x51, 0x54, -0x53, 0x4D, 0x49, 0x44, 0x43, 0x45, 0x46, 0x4C, 0x54, 0x65, 0xE4, 0xCF, 0xC4, 0xBB, 0xB4, 0xAF, -0xAD, 0xAC, 0xAA, 0xAB, 0xB5, 0xD1, 0x49, 0x3B, 0x35, 0x2F, 0x2D, 0x32, 0x3D, 0x4E, 0x57, 0x51, -0x4F, 0x50, 0x4C, 0x42, 0x3D, 0x3F, 0x46, 0x4A, 0x4F, 0x5E, 0xEC, 0xD9, 0xDA, 0xD2, 0xC8, 0xBE, -0xB7, 0xB0, 0xAD, 0xAB, 0xA9, 0xA8, 0xAD, 0xC4, 0x48, 0x36, 0x31, 0x2E, 0x2D, 0x30, 0x3E, 0x67, -0xE2, 0x63, 0x47, 0x43, 0x42, 0x39, 0x36, 0x3B, 0x46, 0x6B, 0xE1, 0xDB, 0xCC, 0xC8, 0xCC, 0xD7, -0xDD, 0xC6, 0xBA, 0xB2, 0xAC, 0xAA, 0xA7, 0xA7, 0xB0, 0x69, 0x32, 0x2D, 0x2D, 0x2C, 0x2D, 0x39, -0xF1, 0xC2, 0xCA, 0x5E, 0x3D, 0x38, 0x34, 0x2E, 0x2F, 0x3E, 0x69, 0xCC, 0xC3, 0xBD, 0xBD, 0xC2, -0xCD, 0xEC, 0xF4, 0xCD, 0xC0, 0xB7, 0xAC, 0xA7, 0xA4, 0xA4, 0xB7, 0x3A, 0x2A, 0x29, 0x2A, 0x2B, -0x30, 0x56, 0xBA, 0xB6, 0xCD, 0x4A, 0x33, 0x2C, 0x2C, 0x2B, 0x34, 0x65, 0xC3, 0xBB, 0xBB, 0xBC, -0xC1, 0xDA, 0x7F, 0x6A, 0x75, 0xD1, 0xC2, 0xB8, 0xAC, 0xA6, 0xA5, 0xA4, 0xB0, 0x35, 0x23, 0x25, -0x29, 0x2F, 0x38, 0x73, 0xB3, 0xAF, 0xC8, 0x3E, 0x2E, 0x29, 0x26, 0x2C, 0x3D, 0xDF, 0xB8, 0xB5, -0xBB, 0xC5, 0xE7, 0x5A, 0x53, 0x68, 0xD9, 0xC8, 0xBA, 0xB3, 0xAD, 0xA8, 0xA7, 0xA6, 0xAF, 0x34, -0x1F, 0x24, 0x2E, 0x3B, 0x48, 0xDA, 0xB3, 0xB0, 0xD6, 0x33, 0x29, 0x29, 0x29, 0x2F, 0x5B, 0xC3, -0xB9, 0xB8, 0xC1, 0xDB, 0x53, 0x46, 0x4E, 0xEE, 0xCB, 0xC5, 0xBF, 0xBA, 0xB6, 0xAE, 0xAA, 0xA8, -0xAA, 0xDB, 0x26, 0x20, 0x2B, 0x3E, 0x5E, 0xEE, 0xC1, 0xB6, 0xC1, 0x3F, 0x2A, 0x29, 0x2A, 0x2F, -0x4F, 0xCA, 0xC0, 0xBE, 0xC5, 0xDC, 0x51, 0x44, 0x4B, 0x7D, 0xCB, 0xC5, 0xC5, 0xC2, 0xBF, 0xBD, -0xB1, 0xA9, 0xA8, 0xAA, 0xCB, 0x28, 0x20, 0x2C, 0x44, 0x7E, 0xDE, 0xC8, 0xBB, 0xC6, 0x3F, 0x2B, -0x29, 0x2E, 0x35, 0x4C, 0xCB, 0xBF, 0xC3, 0xCA, 0xE6, 0x4E, 0x43, 0x44, 0x6A, 0xC8, 0xC3, 0xC3, -0xC8, 0xC8, 0xBE, 0xB5, 0xAB, 0xA7, 0xA8, 0xBC, 0x2D, 0x1F, 0x29, 0x42, 0xD7, 0xD0, 0xCD, 0xBF, -0xC5, 0x4C, 0x2E, 0x2B, 0x2F, 0x36, 0x4A, 0xD7, 0xBE, 0xBD, 0xD5, 0x74, 0x50, 0x42, 0x45, 0x53, -0xD1, 0xBE, 0xBE, 0xC5, 0xD2, 0xCD, 0xBC, 0xAE, 0xA7, 0xA7, 0xB5, 0x36, 0x21, 0x28, 0x41, 0xD1, -0xC9, 0xD4, 0xCB, 0xCB, 0x51, 0x31, 0x2B, 0x2F, 0x39, 0x47, 0xE9, 0xC5, 0xC0, 0xCD, 0xED, 0x50, -0x3F, 0x3F, 0x52, 0xCD, 0xBB, 0xBC, 0xC6, 0xDE, 0xE7, 0xCB, 0xB5, 0xA8, 0xA4, 0xA9, 0xCC, 0x28, -0x20, 0x2E, 0x6F, 0xC2, 0xCF, 0xF7, 0xDA, 0xEB, 0x3F, 0x2E, 0x2D, 0x34, 0x3E, 0x5D, 0xCD, 0xBF, -0xC7, 0x73, 0x53, 0x43, 0x3C, 0x49, 0xDD, 0xBC, 0xB7, 0xC2, 0xE4, 0x62, 0xEC, 0xBD, 0xAA, 0xA3, -0xA4, 0xB3, 0x32, 0x1F, 0x26, 0x42, 0xC3, 0xC0, 0xF2, 0x68, 0x73, 0x4D, 0x37, 0x2D, 0x2F, 0x39, -0x47, 0xDD, 0xC2, 0xBE, 0xD2, 0x4A, 0x3E, 0x3B, 0x42, 0xEB, 0xBE, 0xB5, 0xB9, 0xD5, 0x54, 0x54, -0xCB, 0xAD, 0xA3, 0xA2, 0xAC, 0x4D, 0x23, 0x21, 0x34, 0xCF, 0xBA, 0xD0, 0x5E, 0x73, 0x5D, 0x43, -0x34, 0x30, 0x38, 0x3C, 0x46, 0xCE, 0xB9, 0xBE, 0x5F, 0x3E, 0x3B, 0x3E, 0x62, 0xC0, 0xB5, 0xB6, -0xC9, 0x54, 0x48, 0xE3, 0xB1, 0xA4, 0xA0, 0xA6, 0xC3, 0x2B, 0x1E, 0x29, 0x5D, 0xB9, 0xBD, 0x72, -0x50, 0x5B, 0x50, 0x3C, 0x30, 0x30, 0x36, 0x3F, 0x7C, 0xC0, 0xBA, 0xD0, 0x45, 0x3A, 0x38, 0x46, -0xCB, 0xB7, 0xB5, 0xC4, 0x5A, 0x48, 0x62, 0xBA, 0xA8, 0xA1, 0xA3, 0xB0, 0x3C, 0x20, 0x20, 0x39, -0xBD, 0xB1, 0xC7, 0x4F, 0x4A, 0x4E, 0x48, 0x35, 0x2E, 0x31, 0x39, 0x56, 0xC0, 0xB8, 0xC2, 0x4D, -0x39, 0x37, 0x3E, 0xE2, 0xBC, 0xB6, 0xBB, 0xDC, 0x4B, 0x4A, 0xD3, 0xAE, 0xA3, 0xA0, 0xA8, 0xD5, -0x29, 0x1F, 0x2B, 0xE3, 0xB3, 0xBA, 0x65, 0x47, 0x4C, 0x4F, 0x3D, 0x2F, 0x2D, 0x30, 0x41, 0xCB, -0xB7, 0xBA, 0x76, 0x3D, 0x38, 0x39, 0x51, 0xC5, 0xB6, 0xB6, 0xCC, 0x50, 0x46, 0x7E, 0xB4, 0xA6, -0xA1, 0xA4, 0xB8, 0x35, 0x20, 0x25, 0x48, 0xB8, 0xB5, 0xDB, 0x47, 0x47, 0x52, 0x4A, 0x34, 0x2D, -0x2E, 0x39, 0xEC, 0xBA, 0xB6, 0xCF, 0x3F, 0x38, 0x37, 0x41, 0xD0, 0xB8, 0xB4, 0xBF, 0x6A, 0x4A, -0x5B, 0xBC, 0xA8, 0xA1, 0xA2, 0xAF, 0x3E, 0x22, 0x24, 0x3E, 0xBA, 0xB3, 0xD4, 0x45, 0x41, 0x4F, -0x52, 0x37, 0x2D, 0x2D, 0x36, 0x65, 0xBB, 0xB6, 0xC9, 0x46, 0x38, 0x35, 0x3D, 0xDC, 0xB7, 0xB0, -0xBA, 0xF0, 0x48, 0x4E, 0xC1, 0xAA, 0xA2, 0xA1, 0xAB, 0x5E, 0x27, 0x21, 0x32, 0xC7, 0xB4, 0xC8, -0x48, 0x3E, 0x4B, 0x58, 0x3D, 0x2E, 0x2C, 0x2F, 0x48, 0xBF, 0xB5, 0xBF, 0x4C, 0x36, 0x34, 0x3A, -0x67, 0xBC, 0xB2, 0xB7, 0xD6, 0x4C, 0x4A, 0xCE, 0xAD, 0xA3, 0xA0, 0xA7, 0xD8, 0x29, 0x20, 0x2F, -0xD2, 0xB5, 0xC4, 0x4C, 0x40, 0x4B, 0x64, 0x44, 0x2F, 0x2C, 0x2D, 0x3F, 0xC4, 0xB4, 0xB9, 0x5F, -0x39, 0x36, 0x39, 0x5D, 0xBE, 0xB3, 0xB4, 0xC8, 0x59, 0x4B, 0xDC, 0xAF, 0xA3, 0x9F, 0xA5, 0xC5, -0x2C, 0x21, 0x2C, 0xFB, 0xB9, 0xC1, 0x53, 0x42, 0x4A, 0x5F, 0x49, 0x31, 0x2C, 0x2C, 0x3A, 0xCF, -0xB6, 0xBA, 0xF7, 0x3E, 0x39, 0x3A, 0x4C, 0xCA, 0xB7, 0xB4, 0xBF, 0x79, 0x4D, 0xE5, 0xB1, 0xA4, -0x9F, 0xA4, 0xC6, 0x2B, 0x20, 0x2C, 0xEC, 0xB7, 0xC1, 0x57, 0x43, 0x49, 0x5C, 0x47, 0x31, 0x2C, -0x2C, 0x39, 0xD3, 0xB7, 0xBA, 0xDC, 0x46, 0x3C, 0x39, 0x47, 0xCE, 0xB9, 0xB5, 0xBD, 0xDE, 0x5E, -0xD3, 0xB0, 0xA4, 0xA0, 0xA6, 0xCF, 0x2A, 0x21, 0x2D, 0xF6, 0xBB, 0xC8, 0x55, 0x44, 0x48, 0x51, -0x3F, 0x2F, 0x2C, 0x2D, 0x3B, 0xD8, 0xBC, 0xBF, 0xE7, 0x4E, 0x45, 0x3C, 0x44, 0xEB, 0xBE, 0xB5, -0xBA, 0xCA, 0xE3, 0xC9, 0xAF, 0xA5, 0xA0, 0xA7, 0xE6, 0x28, 0x22, 0x2E, 0xEA, 0xBD, 0xC8, 0x5D, -0x46, 0x4A, 0x4D, 0x3B, 0x2F, 0x2D, 0x2F, 0x3F, 0xD0, 0xBE, 0xC3, 0xE6, 0x56, 0x4B, 0x43, 0x4C, -0xFA, 0xC8, 0xBB, 0xBB, 0xC3, 0xC8, 0xBD, 0xAE, 0xA7, 0xA3, 0xAA, 0x6C, 0x2A, 0x25, 0x30, 0x5A, -0xCD, 0xD3, 0x5F, 0x4D, 0x50, 0x4C, 0x3B, 0x2F, 0x2D, 0x2F, 0x3D, 0xE6, 0xCC, 0xD3, 0xDA, 0xDB, -0x79, 0x55, 0x56, 0x68, 0xE0, 0xCA, 0xC2, 0xC0, 0xBC, 0xB1, 0xAB, 0xA6, 0xA5, 0xAE, 0x53, 0x2C, -0x29, 0x30, 0x41, 0x59, 0x62, 0x53, 0x57, 0x7F, 0x5D, 0x40, 0x35, 0x2E, 0x2F, 0x3D, 0x58, 0x78, -0xE5, 0xCD, 0xC8, 0xCF, 0xDA, 0xEC, 0x7B, 0xE4, 0xD1, 0xCA, 0xC4, 0xBA, 0xB0, 0xAC, 0xAA, 0xAB, -0xBA, 0x4F, 0x39, 0x39, 0x3D, 0x3F, 0x42, 0x3D, 0x3C, 0x45, 0x51, 0x52, 0x4C, 0x42, 0x3B, 0x3E, -0x4A, 0x4C, 0x4D, 0x57, 0x69, 0xEE, 0xDE, 0xE4, 0xFD, 0xED, 0xDC, 0xD3, 0xCD, 0xCA, 0xC3, 0xBD, -0xB9, 0xB6, 0xB8, 0xC3, 0xCE, 0xC8, 0xC1, 0xC5, 0xCE, 0xF9, 0x4A, 0x3F, 0x3F, 0x41, 0x3F, 0x3D, -0x39, 0x38, 0x3B, 0x3C, 0x3A, 0x3C, 0x43, 0x4C, 0x52, 0x58, 0x5B, 0x59, 0x65, 0xDC, 0xCB, 0xC3, -0xBD, 0xB8, 0xB6, 0xB2, 0xAF, 0xB2, 0xB6, 0xB2, 0xB0, 0xB6, 0xBF, 0xD7, 0x4F, 0x40, 0x3F, 0x3D, -0x3A, 0x35, 0x2F, 0x2D, 0x2F, 0x32, 0x33, 0x34, 0x39, 0x3E, 0x46, 0x51, 0x59, 0x5C, 0x6F, 0xD8, -0xC6, 0xBD, 0xB8, 0xB4, 0xB2, 0xAF, 0xAC, 0xAD, 0xAF, 0xAE, 0xAE, 0xB2, 0xBC, 0xCF, 0x55, 0x42, -0x3E, 0x3B, 0x36, 0x31, 0x2D, 0x2A, 0x2B, 0x2F, 0x32, 0x33, 0x36, 0x3B, 0x40, 0x4A, 0x57, 0x69, -0xEE, 0xD6, 0xC8, 0xBF, 0xB9, 0xB3, 0xB1, 0xAF, 0xAC, 0xAB, 0xAE, 0xAF, 0xAF, 0xB1, 0xB9, 0xC6, -0x75, 0x46, 0x3D, 0x3A, 0x36, 0x30, 0x2D, 0x2B, 0x2A, 0x2D, 0x31, 0x34, 0x36, 0x39, 0x3E, 0x46, -0x56, 0x77, 0xE3, 0xD4, 0xCA, 0xC3, 0xBD, 0xB6, 0xB1, 0xAF, 0xAC, 0xAB, 0xAC, 0xAF, 0xAF, 0xB0, -0xB5, 0xBE, 0xDA, 0x4E, 0x3E, 0x3A, 0x36, 0x31, 0x2D, 0x2C, 0x2B, 0x2C, 0x2F, 0x32, 0x34, 0x38, -0x3D, 0x43, 0x4D, 0x66, 0xE7, 0xD6, 0xCB, 0xC5, 0xC0, 0xBA, 0xB3, 0xAF, 0xAD, 0xAB, 0xAC, 0xAE, -0xAF, 0xAF, 0xB3, 0xBB, 0xCD, 0x5A, 0x40, 0x3A, 0x36, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, 0x2F, 0x31, -0x32, 0x38, 0x3D, 0x41, 0x4B, 0x5C, 0xF8, 0xD8, 0xCA, 0xC3, 0xBF, 0xBA, 0xB4, 0xB0, 0xAD, 0xAB, -0xAB, 0xAE, 0xAF, 0xB0, 0xB3, 0xBA, 0xC9, 0x68, 0x46, 0x3C, 0x37, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, -0x2F, 0x30, 0x31, 0x36, 0x3C, 0x3F, 0x49, 0x58, 0x70, 0xDD, 0xCA, 0xC2, 0xBE, 0xB9, 0xB3, 0xB0, -0xAD, 0xAA, 0xAB, 0xAE, 0xAF, 0xAF, 0xB4, 0xBC, 0xCB, 0x61, 0x46, 0x3D, 0x36, 0x30, 0x2E, 0x2C, -0x2B, 0x2D, 0x2F, 0x2F, 0x31, 0x37, 0x3B, 0x3F, 0x4B, 0x5C, 0xFF, 0xD8, 0xC8, 0xC1, 0xBC, 0xB6, -0xB2, 0xAF, 0xAC, 0xAA, 0xAB, 0xAD, 0xAE, 0xAF, 0xB5, 0xBD, 0xCF, 0x5C, 0x45, 0x3C, 0x35, 0x2F, -0x2D, 0x2C, 0x2C, 0x2D, 0x2F, 0x2F, 0x32, 0x37, 0x3B, 0x3F, 0x4B, 0x5F, 0xEE, 0xD4, 0xC8, 0xC1, -0xBC, 0xB5, 0xB0, 0xAE, 0xAB, 0xAA, 0xAB, 0xAD, 0xAF, 0xB1, 0xB7, 0xC0, 0xD9, 0x53, 0x42, 0x3B, -0x34, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x30, 0x33, 0x37, 0x3C, 0x43, 0x4D, 0x5E, 0xEC, 0xD0, -0xC7, 0xC0, 0xBB, 0xB6, 0xB0, 0xAE, 0xAB, 0xAA, 0xAC, 0xAE, 0xAF, 0xB3, 0xB9, 0xC5, 0xE2, 0x4E, -0x3F, 0x39, 0x32, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x2F, 0x33, 0x39, 0x3D, 0x44, 0x4F, 0x65, -0xE3, 0xCE, 0xC5, 0xBF, 0xBA, 0xB4, 0xAF, 0xAD, 0xAA, 0xAA, 0xAC, 0xAE, 0xB0, 0xB5, 0xBB, 0xC8, -0xF8, 0x4C, 0x3E, 0x38, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, 0x2E, 0x2F, 0x31, 0x35, 0x39, 0x3E, 0x4A, -0x5C, 0xF9, 0xD8, 0xCB, 0xC2, 0xBC, 0xB7, 0xB2, 0xAE, 0xAB, 0xA9, 0xAA, 0xAC, 0xAE, 0xB2, 0xB8, -0xBE, 0xCE, 0x72, 0x48, 0x3B, 0x34, 0x2F, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x31, 0x36, 0x3A, -0x3E, 0x4A, 0x5F, 0xEA, 0xD0, 0xC9, 0xC1, 0xBB, 0xB5, 0xB0, 0xAE, 0xAB, 0xA9, 0xAB, 0xAC, 0xAE, -0xB4, 0xBB, 0xC4, 0xD6, 0x60, 0x45, 0x39, 0x30, 0x2D, 0x2C, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x32, -0x35, 0x3A, 0x43, 0x51, 0x6A, 0xDF, 0xCB, 0xC3, 0xBD, 0xB8, 0xB2, 0xAE, 0xAC, 0xAA, 0xAA, 0xAB, -0xAC, 0xAF, 0xB7, 0xBD, 0xCC, 0xF1, 0x51, 0x3F, 0x36, 0x2F, 0x2D, 0x2B, 0x2A, 0x2C, 0x2D, 0x2E, -0x2F, 0x33, 0x37, 0x3B, 0x45, 0x58, 0x77, 0xD5, 0xC8, 0xC0, 0xBB, 0xB6, 0xB1, 0xAE, 0xAB, 0xA9, -0xAA, 0xAB, 0xAC, 0xB1, 0xB9, 0xC0, 0xD3, 0x6A, 0x4A, 0x3C, 0x33, 0x2E, 0x2D, 0x2B, 0x2B, 0x2C, -0x2D, 0x2E, 0x31, 0x34, 0x38, 0x3F, 0x4C, 0x5D, 0xEA, 0xCE, 0xC6, 0xBE, 0xB8, 0xB4, 0xAF, 0xAD, -0xAB, 0xAA, 0xAA, 0xAB, 0xAD, 0xB2, 0xB9, 0xC3, 0xD8, 0x61, 0x47, 0x3A, 0x32, 0x2E, 0x2C, 0x2B, -0x2C, 0x2C, 0x2D, 0x2F, 0x31, 0x34, 0x38, 0x3F, 0x4D, 0x62, 0xDD, 0xCC, 0xC3, 0xBC, 0xB7, 0xB2, -0xAE, 0xAC, 0xAA, 0xAA, 0xAA, 0xAB, 0xAE, 0xB3, 0xBA, 0xC6, 0xE1, 0x55, 0x41, 0x37, 0x30, 0x2D, -0x2B, 0x2A, 0x2B, 0x2C, 0x2D, 0x2F, 0x31, 0x34, 0x39, 0x40, 0x4D, 0x6A, 0xD8, 0xC9, 0xC1, 0xBC, -0xB7, 0xB2, 0xAE, 0xAC, 0xAA, 0xAA, 0xAB, 0xAC, 0xAF, 0xB7, 0xBB, 0xC6, 0x79, 0x55, 0x44, 0x37, -0x30, 0x2D, 0x2C, 0x2B, 0x2C, 0x2D, 0x2D, 0x2F, 0x33, 0x35, 0x39, 0x42, 0x51, 0x6C, 0xDA, 0xCA, -0xC4, 0xBE, 0xBA, 0xB6, 0xB0, 0xAD, 0xAC, 0xAC, 0xAC, 0xAD, 0xAF, 0xB4, 0xB9, 0xC0, 0xD0, 0x65, -0x47, 0x3A, 0x32, 0x2F, 0x2C, 0x2B, 0x2B, 0x2C, 0x2D, 0x2E, 0x31, 0x36, 0x3A, 0x3F, 0x4A, 0x5E, -0xDC, 0xCC, 0xC4, 0xBE, 0xBA, 0xB6, 0xB2, 0xAF, 0xAE, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB8, 0xBE, -0xCA, 0xE6, 0x4F, 0x3F, 0x38, 0x31, 0x2E, 0x2C, 0x2C, 0x2C, 0x2D, 0x2F, 0x31, 0x35, 0x3A, 0x3F, -0x4B, 0x64, 0xDD, 0xCB, 0xC3, 0xBD, 0xBA, 0xB7, 0xB4, 0xB1, 0xAF, 0xAE, 0xAE, 0xB0, 0xB3, 0xB5, -0xB9, 0xBE, 0xC6, 0xD3, 0x74, 0x4E, 0x40, 0x3A, 0x35, 0x32, 0x30, 0x2F, 0x2F, 0x30, 0x33, 0x36, -0x3A, 0x3F, 0x48, 0x52, 0x6C, 0xDF, 0xCE, 0xC7, 0xC1, 0xBE, 0xBB, 0xB9, 0xB8, 0xB7, 0xB6, 0xB6, -0xB7, 0xB9, 0xBB, 0xBE, 0xC4, 0xCA, 0xD9, 0x6C, 0x50, 0x45, 0x3D, 0x3A, 0x37, 0x35, 0x35, 0x35, -0x36, 0x37, 0x39, 0x3C, 0x3F, 0x46, 0x4F, 0x5E, 0xF1, 0xD9, 0xCF, 0xCC, 0xC9, 0xC5, 0xC1, 0xBE, -0xBC, 0xBC, 0xBC, 0xBD, 0xBF, 0xC2, 0xC4, 0xC7, 0xCC, 0xD5, 0xE8, 0x64, 0x52, 0x4A, 0x45, 0x41, -0x3F, 0x3E, 0x3D, 0x3D, 0x3E, 0x41, 0x45, 0x49, 0x4D, 0x53, 0x5C, 0x71, 0xE9, 0xDD, 0xD6, 0xD1, -0xCE, 0xCB, 0xC9, 0xC8, 0xC8, 0xC7, 0xC7, 0xC8, 0xC9, 0xCC, 0xCF, 0xD4, 0xDA, 0xE4, 0xF7, 0x69, -0x5B, 0x53, 0x4F, 0x4E, 0x4D, 0x4D, 0x4D, 0x4E, 0x51, 0x58, 0x5F, 0x68, 0x6F, 0x77, 0xFC, 0xEE, -0xE8, 0xE5, 0xE1, 0xDD, 0xDE, 0xDE, 0xDE, 0xE2, 0xE6, 0xE6, 0xEB, 0xF0, 0xED, 0xEA, 0xEC, 0xEE, -0xF8, 0x6A, 0x5C, 0x57, 0x55, 0x56, 0x58, 0x59, 0x58, 0x58, 0x5B, 0x5E, 0x63, 0x71, 0xF7, 0xEE, -0xE9, 0xE3, 0xE4, 0xE8, 0xE7, 0xEA, 0xEE, 0xEE, 0xF2, 0xFB, 0xFF, 0x7B, 0x74, 0x6E, 0x6B, 0x65, -0x60, 0x65, 0x67, 0x61, 0x60, 0x61, 0x5E, 0x5E, 0x62, 0x69, 0x70, 0x7F, 0xF6, 0xF2, 0xEC, 0xE7, -0xE6, 0xE3, 0xDF, 0xDE, 0xDE, 0xDD, 0xDE, 0xE0, 0xE5, 0xEC, 0xF6, 0x7F, 0x78, 0x75, 0x70, 0x6B, -0x64, 0x5E, 0x5A, 0x58, 0x58, 0x59, 0x5A, 0x5C, 0x5D, 0x5E, 0x61, 0x67, 0x6C, 0x75, 0xF8, 0xEC, -0xE6, 0xE0, 0xDD, 0xDD, 0xDE, 0xDF, 0xE0, 0xE2, 0xE2, 0xE4, 0xE6, 0xE9, 0xEE, 0xF9, 0x7D, 0x75, -0x6E, 0x6A, 0x65, 0x61, 0x5E, 0x5C, 0x5B, 0x5C, 0x5D, 0x5E, 0x60, 0x63, 0x66, 0x6C, 0x76, 0xFA, -0xEE, 0xE9, 0xE4, 0xE1, 0xDF, 0xDD, 0xDE, 0xDF, 0xE2, 0xE6, 0xEA, 0xEE, 0xF4, 0xFA, 0x7E, 0x7A, -0x75, 0x72, 0x74, 0x74, 0x71, 0x70, 0x6D, 0x6A, 0x6A, 0x6B, 0x6D, 0x70, 0x74, 0x78, 0x7A, 0x7D, -0xFA, 0xF0, 0xEA, 0xE5, 0xE3, 0xE2, 0xE0, 0xDF, 0xE1, 0xE3, 0xE4, 0xE8, 0xEB, 0xEE, 0xF4, 0xFB, -0x7E, 0x75, 0x6D, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x65, 0x64, 0x63, 0x64, 0x66, 0x69, 0x6D, 0x72, -0x77, 0x7B, 0xFE, 0xF7, 0xF0, 0xEB, 0xE8, 0xE7, 0xE6, 0xE6, 0xE6, 0xE7, 0xE7, 0xE8, 0xEA, 0xED, -0xF3, 0xFC, 0x79, 0x72, 0x6F, 0x6C, 0x6B, 0x6B, 0x69, 0x66, 0x64, 0x63, 0x62, 0x63, 0x67, 0x6C, -0x73, 0x7C, 0xFE, 0xFD, 0xFA, 0xF4, 0xEE, 0xEA, 0xE5, 0xE1, 0xE1, 0xE2, 0xE5, 0xE9, 0xED, 0xEF, -0xF1, 0xF2, 0xF4, 0xF8, 0xFF, 0x76, 0x6E, 0x6A, 0x68, 0x67, 0x66, 0x65, 0x64, 0x62, 0x61, 0x61, -0x63, 0x67, 0x6B, 0x72, 0x7E, 0xFA, 0xF5, 0xF1, 0xEE, 0xED, 0xEC, 0xE9, 0xE8, 0xE7, 0xE7, 0xE9, -0xEC, 0xF0, 0xF9, 0x7D, 0x77, 0x73, 0x70, 0x6F, 0x6E, 0x6C, 0x69, 0x67, 0x65, 0x66, 0x66, 0x68, -0x69, 0x69, 0x6A, 0x6C, 0x6E, 0x75, 0x7F, 0xF8, 0xF1, 0xED, 0xEB, 0xEA, 0xEA, 0xEB, 0xEB, 0xEB, -0xEA, 0xE9, 0xEA, 0xEC, 0xEF, 0xF4, 0xFB, 0x7D, 0x77, 0x73, 0x71, 0x6F, 0x6D, 0x6B, 0x69, 0x67, -0x66, 0x67, 0x68, 0x69, 0x6B, 0x6D, 0x6F, 0x74, 0x79, 0x7F, 0xF9, 0xF3, 0xEF, 0xEE, 0xEE, 0xEE, -0xEE, 0xED, 0xED, 0xED, 0xEE, 0xEC, 0xEC, 0xF1, 0xF3, 0xF6, 0xFD, 0xFF, 0x7D, 0x78, 0x78, 0x76, -0x70, 0x6F, 0x6E, 0x6D, 0x6D, 0x6E, 0x6F, 0x71, 0x73, 0x77, 0x7B, 0x7D, 0xFF, 0xFB, 0xF8, 0xF8, -0xFA, 0xFB, 0xFE, 0x7E, 0x7D, 0x7A, 0x79, 0x7A, 0x76, 0x76, 0x76, 0x72, 0x70, 0x6F, 0x6D, 0x6E, -0x6D, 0x6B, 0x6E, 0x65, 0x66, 0x57, 0x41, 0x59, 0xC7, 0x62, 0x57, 0xCD, 0x64, 0x6B, 0xCC, 0x6D, -0xF6, 0xD1, 0x69, 0x6E, 0xDA, 0x7D, 0x61, 0xEE, 0xF1, 0xFD, 0xFF, 0x6E, 0xE7, 0x74, 0x66, 0xE9, -0x6A, 0xFC, 0xF2, 0x64, 0xEE, 0x6F, 0x6B, 0x7B, 0x69, 0xF2, 0x68, 0x74, 0xEC, 0x5F, 0xED, 0xFC, -0x5F, 0xDE, 0x72, 0x65, 0xDC, 0x51, 0x4C, 0xE8, 0x5F, 0xEF, 0xD7, 0x4E, 0xF3, 0xF9, 0x52, 0xC3, -0xE2, 0x56, 0xC9, 0x5B, 0x59, 0xE4, 0x50, 0x53, 0x47, 0x66, 0xF9, 0x47, 0xC9, 0xCB, 0x59, 0xD4, -0x55, 0x58, 0xD3, 0x5C, 0xF9, 0xCE, 0xD7, 0x6D, 0x61, 0xDB, 0xE4, 0xE8, 0x70, 0x79, 0xCD, 0x6B, -0x5D, 0xEC, 0x66, 0xDC, 0x6C, 0x5F, 0xD3, 0xF9, 0xFB, 0x66, 0x55, 0xDE, 0xFB, 0x64, 0xD7, 0xDA, -0xF1, 0xF1, 0xF1, 0xE5, 0xDB, 0xF4, 0x75, 0xDF, 0xE7, 0xFD, 0x79, 0xEC, 0xD9, 0xF0, 0x6E, 0xF5, -0xE4, 0xE5, 0x64, 0x74, 0xDF, 0x7D, 0x68, 0x75, 0xF0, 0xFD, 0x7B, 0xFC, 0x7B, 0xDE, 0xEF, 0x64, -0xDF, 0xE8, 0xFF, 0xE9, 0xFF, 0xE2, 0xE1, 0x76, 0xF6, 0xEF, 0xEC, 0xF9, 0x6D, 0x7C, 0x73, 0x6D, -0x69, 0x67, 0x76, 0x75, 0x73, 0x64, 0x66, 0xFD, 0x60, 0x5F, 0x77, 0x67, 0x70, 0x74, 0x60, 0x78, -0x7A, 0x5C, 0x67, 0x79, 0x6C, 0x77, 0x63, 0x63, 0xEF, 0x6C, 0x66, 0x73, 0x6D, 0xF8, 0x72, 0x74, -0xE6, 0xFB, 0x7B, 0xF3, 0xF6, 0xF1, 0xFE, 0x7B, 0xF5, 0xF1, 0x6D, 0x63, 0x75, 0x6E, 0x60, 0x64, -0x67, 0x67, 0x68, 0x67, 0x67, 0x6C, 0x64, 0x5B, 0x65, 0x6E, 0x69, 0x72, 0x76, 0x74, 0xFE, 0xFD, -0xFF, 0xF6, 0xF3, 0x7C, 0x7A, 0xFC, 0xFE, 0xFB, 0x7E, 0x75, 0xF5, 0xEE, 0xFC, 0xF7, 0xF3, 0xFF, -0xFE, 0x74, 0x6B, 0x6F, 0x6D, 0x6A, 0x6C, 0x6A, 0x7A, 0xF9, 0x71, 0x7C, 0xF5, 0x7C, 0x7B, 0x7F, -0xFE, 0x72, 0x6E, 0xFF, 0x6F, 0x66, 0x6B, 0x6A, 0x6E, 0x76, 0x71, 0x7C, 0x7A, 0x6E, 0x6C, 0x69, -0x6C, 0x6D, 0x63, 0x65, 0x6A, 0x66, 0x63, 0x65, 0x6C, 0x68, 0x64, 0x69, 0x6A, 0x6E, 0x79, 0x7B, -0x78, 0x6D, 0x6E, 0x79, 0x77, 0xFA, 0xED, 0xEF, 0xEF, 0xEC, 0xE8, 0xEF, 0xFB, 0xF6, 0xEF, 0xEE, -0xF7, 0xF9, 0xF3, 0xF7, 0xF1, 0xF3, 0xFD, 0xFD, 0x7A, 0x7B, 0xFE, 0x79, 0x7C, 0x7B, 0x6E, 0x72, -0x7A, 0x72, 0x71, 0x79, 0x79, 0x6F, 0x6F, 0x78, 0x74, 0x72, 0x7B, 0x72, 0x78, 0xF6, 0xF7, 0xF9, -0x78, 0x79, 0xEE, 0xF5, 0x74, 0x76, 0x7A, 0xFE, 0x7E, 0x75, 0x7A, 0x7E, 0x74, 0x70, 0x7D, 0xF8, -0xF8, 0x7D, 0x77, 0xF8, 0xF0, 0x7F, 0x7E, 0xF2, 0xED, 0xF0, 0xF4, 0xEB, 0xE9, 0xFE, 0x74, 0xEF, -0xE1, 0xE0, 0xDC, 0xD9, 0xD7, 0xD3, 0xD7, 0xDD, 0xD9, 0xD9, 0xDF, 0xE6, 0xEB, 0xF2, 0x78, 0x65, -0x61, 0x65, 0x5F, 0x5A, 0x5B, 0x5B, 0x5A, 0x5C, 0x5B, 0x5D, 0x5E, 0x5C, 0x5B, 0x5B, 0x5B, 0x5C, -0x5E, 0x6B, 0xEA, 0xD9, 0xD2, 0xD1, 0xCD, 0xC8, 0xC6, 0xC5, 0xC5, 0xC3, 0xC3, 0xC6, 0xCA, 0xD2, -0xE8, 0x67, 0x51, 0x49, 0x42, 0x3D, 0x3D, 0x3E, 0x3F, 0x41, 0x44, 0x49, 0x4E, 0x50, 0x55, 0x5A, -0x5F, 0x6F, 0xEF, 0xDA, 0xCD, 0xCA, 0xC8, 0xC4, 0xBF, 0xBD, 0xBB, 0xB9, 0xB7, 0xB6, 0xBA, 0xC2, -0xCC, 0xE2, 0x56, 0x43, 0x3B, 0x39, 0x37, 0x36, 0x37, 0x3B, 0x3E, 0x42, 0x47, 0x4B, 0x51, 0x5A, -0x5B, 0x5E, 0x67, 0x7A, 0xED, 0xE8, 0xDB, 0xCF, 0xCB, 0xC5, 0xBD, 0xB9, 0xB6, 0xB2, 0xB0, 0xB4, -0xB9, 0xBF, 0xCD, 0xFC, 0x49, 0x3B, 0x37, 0x33, 0x31, 0x32, 0x33, 0x38, 0x3E, 0x45, 0x4F, 0x5F, -0x74, 0xF0, 0xEF, 0xF1, 0xF4, 0xFF, 0x77, 0x72, 0xFB, 0xE4, 0xD9, 0xCE, 0xC3, 0xBA, 0xB6, 0xB2, -0xB0, 0xB2, 0xB6, 0xBB, 0xC8, 0xE4, 0x51, 0x3E, 0x38, 0x33, 0x2F, 0x2F, 0x31, 0x35, 0x3A, 0x3E, -0x49, 0x5D, 0xFE, 0xE4, 0xDD, 0xD9, 0xD9, 0xE1, 0xEB, 0xEE, 0xEE, 0xE7, 0xDD, 0xD2, 0xC7, 0xBD, -0xB9, 0xB5, 0xB2, 0xB5, 0xB8, 0xBB, 0xC6, 0xDA, 0x5F, 0x45, 0x3D, 0x37, 0x33, 0x31, 0x31, 0x35, -0x39, 0x3D, 0x45, 0x53, 0x6F, 0xE3, 0xD9, 0xD0, 0xCF, 0xD2, 0xD5, 0xD9, 0xD9, 0xD8, 0xD4, 0xCE, -0xC8, 0xC0, 0xBD, 0xB9, 0xB8, 0xBB, 0xBD, 0xC1, 0xCD, 0xDF, 0x5F, 0x4A, 0x41, 0x3B, 0x37, 0x36, -0x35, 0x36, 0x3A, 0x3D, 0x44, 0x4E, 0x5F, 0xEC, 0xDB, 0xD6, 0xD2, 0xD4, 0xD6, 0xDA, 0xDD, 0xDB, -0xD8, 0xD2, 0xCD, 0xC9, 0xC3, 0xBF, 0xBE, 0xBF, 0xC3, 0xC4, 0xCA, 0xD6, 0xED, 0x5E, 0x50, 0x48, -0x3F, 0x3C, 0x3B, 0x3A, 0x3A, 0x3D, 0x40, 0x4A, 0x55, 0x6A, 0xE6, 0xDC, 0xD8, 0xD6, 0xD8, 0xD8, -0xDB, 0xDE, 0xDF, 0xE2, 0xDE, 0xDC, 0xD9, 0xD0, 0xCB, 0xC8, 0xC8, 0xCC, 0xCD, 0xCD, 0xD1, 0xDB, -0xF2, 0x67, 0x5B, 0x51, 0x49, 0x44, 0x42, 0x41, 0x42, 0x44, 0x49, 0x4E, 0x55, 0x5C, 0x6A, 0x7E, -0xF3, 0xED, 0xED, 0xEF, 0xEC, 0xED, 0xF4, 0xF7, 0xF0, 0xEB, 0xE4, 0xDF, 0xDA, 0xD2, 0xCD, 0xCC, -0xCC, 0xCF, 0xCF, 0xCE, 0xD3, 0xDB, 0xE7, 0x7C, 0x69, 0x5E, 0x54, 0x4F, 0x4E, 0x4D, 0x4E, 0x4F, -0x52, 0x58, 0x5B, 0x5E, 0x63, 0x67, 0x6B, 0x6B, 0x6A, 0x6B, 0x6C, 0x6E, 0x6F, 0x73, 0x7D, 0xF3, -0xEA, 0xE1, 0xDC, 0xD8, 0xD3, 0xD1, 0xCF, 0xCE, 0xD1, 0xD2, 0xD2, 0xD6, 0xDB, 0xE2, 0xEF, 0xFD, -0x73, 0x66, 0x5F, 0x5C, 0x5A, 0x59, 0x58, 0x56, 0x56, 0x57, 0x57, 0x58, 0x58, 0x5A, 0x5C, 0x5D, -0x61, 0x65, 0x6A, 0x74, 0x7E, 0xF4, 0xEA, 0xE2, 0xDD, 0xDA, 0xD7, 0xD5, 0xD2, 0xD1, 0xD0, 0xD1, -0xD3, 0xD3, 0xD4, 0xD7, 0xDB, 0xE0, 0xE8, 0xEF, 0x7B, 0x69, 0x5F, 0x5B, 0x57, 0x53, 0x50, 0x4F, -0x4F, 0x4F, 0x4F, 0x50, 0x52, 0x56, 0x59, 0x5C, 0x60, 0x68, 0x6E, 0x7A, 0xFB, 0xF1, 0xEB, 0xE7, -0xE2, 0xDE, 0xDC, 0xDA, 0xD7, 0xD5, 0xD3, 0xD3, 0xD3, 0xD5, 0xD5, 0xD8, 0xDC, 0xE4, 0xF2, 0x78, -0x6A, 0x5E, 0x59, 0x55, 0x52, 0x50, 0x4F, 0x4F, 0x50, 0x52, 0x55, 0x58, 0x5A, 0x5D, 0x61, 0x64, -0x69, 0x6E, 0x74, 0xFF, 0xF6, 0xEE, 0xE9, 0xE4, 0xDF, 0xDC, 0xD8, 0xD5, 0xD2, 0xD0, 0xD1, 0xD1, -0xD2, 0xD6, 0xD7, 0xDA, 0xDF, 0xE8, 0xF8, 0x71, 0x69, 0x60, 0x5C, 0x58, 0x56, 0x54, 0x53, 0x53, -0x53, 0x55, 0x56, 0x58, 0x5A, 0x5C, 0x5F, 0x63, 0x69, 0x71, 0xFF, 0xEF, 0xEA, 0xE6, 0xE1, 0xDF, -0xDE, 0xDB, 0xDA, 0xDA, 0xD7, 0xD4, 0xD1, 0xD1, 0xD2, 0xD4, 0xD7, 0xD8, 0xDB, 0xE1, 0xED, 0x78, -0x69, 0x61, 0x5A, 0x53, 0x50, 0x4F, 0x4E, 0x4F, 0x4F, 0x51, 0x55, 0x59, 0x5D, 0x60, 0x65, 0x6C, -0x6F, 0x76, 0x7E, 0xFC, 0xF5, 0xF2, 0xF2, 0xED, 0xE7, 0xE1, 0xDD, 0xD9, 0xD4, 0xCE, 0xCB, 0xCA, -0xC8, 0xCA, 0xCF, 0xD0, 0xD7, 0xE6, 0x7C, 0x5E, 0x53, 0x4F, 0x4C, 0x4A, 0x4A, 0x4A, 0x4C, 0x4E, -0x4F, 0x51, 0x57, 0x5D, 0x62, 0x66, 0x69, 0x6D, 0x6D, 0x67, 0x63, 0x65, 0x6B, 0x70, 0x75, 0xFE, -0xEA, 0xDC, 0xD3, 0xCE, 0xC9, 0xC2, 0xBE, 0xBC, 0xBC, 0xC1, 0xC8, 0xCB, 0xDC, 0x69, 0x50, 0x46, -0x42, 0x3F, 0x3D, 0x3D, 0x3F, 0x43, 0x4B, 0x4F, 0x55, 0x61, 0x6F, 0xFC, 0xF0, 0xFA, 0xFD, 0x7B, -0x63, 0x5A, 0x54, 0x52, 0x54, 0x58, 0x62, 0x7D, 0xDE, 0xCC, 0xC4, 0xBC, 0xB6, 0xB1, 0xAE, 0xB2, -0xBA, 0xC1, 0xDA, 0x5A, 0x45, 0x38, 0x33, 0x32, 0x33, 0x36, 0x3A, 0x3E, 0x4B, 0x66, 0xEA, 0xD6, -0xCE, 0xCF, 0xD3, 0xE0, 0x6E, 0x5C, 0x51, 0x4D, 0x4B, 0x4A, 0x4F, 0x5B, 0x7A, 0xD6, 0xC6, 0xBA, -0xB1, 0xAE, 0xAA, 0xAA, 0xAF, 0xBA, 0xD1, 0x4E, 0x3D, 0x31, 0x2B, 0x2B, 0x2C, 0x30, 0x38, 0x3E, -0x4E, 0xEA, 0xCD, 0xC7, 0xC8, 0xCB, 0xCE, 0xDD, 0x64, 0x4F, 0x48, 0x48, 0x47, 0x46, 0x4D, 0x62, -0xDD, 0xCA, 0xBD, 0xB1, 0xAC, 0xA9, 0xA7, 0xAA, 0xB2, 0xC4, 0x51, 0x3A, 0x2F, 0x29, 0x28, 0x2A, -0x2E, 0x39, 0x45, 0x5A, 0xDB, 0xC8, 0xC2, 0xC5, 0xCD, 0xD5, 0xE8, 0x5B, 0x4C, 0x46, 0x47, 0x4C, -0x4E, 0x59, 0xF3, 0xD3, 0xC6, 0xBE, 0xB5, 0xAD, 0xAA, 0xA6, 0xA8, 0xB2, 0xC5, 0x54, 0x38, 0x2F, -0x28, 0x26, 0x2A, 0x2F, 0x3A, 0x4B, 0x73, 0xCF, 0xC5, 0xC4, 0xC9, 0xD9, 0xF8, 0x5F, 0x4C, 0x47, -0x47, 0x48, 0x4F, 0x5A, 0x74, 0xD9, 0xCE, 0xC7, 0xBF, 0xBA, 0xB0, 0xAC, 0xAA, 0xA9, 0xB0, 0xC5, -0x5C, 0x3B, 0x30, 0x2B, 0x27, 0x29, 0x2E, 0x39, 0x49, 0x6C, 0xD2, 0xC7, 0xC5, 0xCA, 0xDA, 0x7A, -0x5E, 0x4D, 0x48, 0x49, 0x4B, 0x52, 0x5E, 0x70, 0xDC, 0xCE, 0xC9, 0xC4, 0xBE, 0xB5, 0xAE, 0xAC, -0xAA, 0xAD, 0xBB, 0xE1, 0x43, 0x35, 0x2E, 0x29, 0x28, 0x2B, 0x32, 0x3D, 0x4E, 0x7E, 0xD2, 0xC9, -0xC7, 0xCC, 0xDF, 0xFE, 0x61, 0x4F, 0x4C, 0x4B, 0x4C, 0x54, 0x5D, 0x72, 0xDA, 0xCE, 0xC7, 0xC0, -0xB9, 0xB0, 0xAD, 0xAA, 0xAA, 0xB1, 0xC5, 0x5D, 0x3D, 0x33, 0x2C, 0x29, 0x29, 0x2D, 0x35, 0x3F, -0x4F, 0x78, 0xD7, 0xCA, 0xC7, 0xCD, 0xD9, 0xE3, 0x71, 0x5C, 0x54, 0x4D, 0x4E, 0x55, 0x5A, 0x6E, -0xE3, 0xD3, 0xC8, 0xBE, 0xB6, 0xAF, 0xAC, 0xAA, 0xAC, 0xB7, 0xCE, 0x53, 0x3D, 0x34, 0x2D, 0x2A, -0x2A, 0x2E, 0x35, 0x3E, 0x4A, 0x5C, 0xE5, 0xCD, 0xC8, 0xCB, 0xCE, 0xD5, 0xE2, 0xF7, 0x66, 0x57, -0x54, 0x56, 0x5B, 0x6E, 0xE7, 0xD5, 0xC9, 0xBE, 0xB6, 0xB1, 0xAE, 0xAE, 0xB4, 0xBE, 0xD3, 0x5C, -0x46, 0x3C, 0x34, 0x30, 0x2F, 0x32, 0x38, 0x3E, 0x45, 0x4E, 0x69, 0xDC, 0xCF, 0xCD, 0xCF, 0xD3, -0xD9, 0xDF, 0xEF, 0x6F, 0x68, 0x67, 0x6F, 0xF7, 0xE7, 0xDC, 0xD2, 0xC8, 0xC1, 0xBE, 0xBC, 0xBD, -0xC3, 0xCB, 0xD5, 0xEA, 0x6A, 0x58, 0x4D, 0x47, 0x43, 0x43, 0x44, 0x47, 0x4A, 0x4D, 0x52, 0x5D, -0x6D, 0x78, 0x77, 0x78, 0x76, 0x73, 0x75, 0x72, 0x72, 0x78, 0x7E, 0xF6, 0xEB, 0xE3, 0xDC, 0xD6, -0xD2, 0xCF, 0xCE, 0xCE, 0xCD, 0xCF, 0xD2, 0xD4, 0xD7, 0xDA, 0xDD, 0xE3, 0xEF, 0x7A, 0x6C, 0x65, -0x5F, 0x5B, 0x57, 0x53, 0x4F, 0x4E, 0x4D, 0x4C, 0x4A, 0x4A, 0x4A, 0x4B, 0x4D, 0x4F, 0x53, 0x59, -0x5F, 0x6C, 0xFE, 0xEC, 0xE3, 0xDE, 0xDC, 0xDA, 0xD9, 0xD8, 0xD7, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, -0xD8, 0xDA, 0xDC, 0xDE, 0xE3, 0xEC, 0xFB, 0x6F, 0x63, 0x5B, 0x55, 0x4F, 0x4D, 0x4C, 0x4B, 0x4C, -0x4C, 0x4D, 0x4F, 0x53, 0x58, 0x5E, 0x67, 0x73, 0xFB, 0xEE, 0xE8, 0xE3, 0xDF, 0xDC, 0xDA, 0xD9, -0xD8, 0xD8, 0xD8, 0xD9, 0xDB, 0xDD, 0xDF, 0xE1, 0xE5, 0xE9, 0xEE, 0xF6, 0x7C, 0x6E, 0x66, 0x5F, -0x5C, 0x5A, 0x58, 0x56, 0x56, 0x57, 0x58, 0x5A, 0x5D, 0x60, 0x66, 0x6D, 0x74, 0x7C, 0xFB, 0xF4, -0xEE, 0xEA, 0xE7, 0xE5, 0xE4, 0xE4, 0xE4, 0xE7, 0xEA, 0xEC, 0xED, 0xED, 0xEC, 0xED, 0xEC, 0xED, -0xEE, 0xF1, 0xF9, 0x7F, 0x79, 0x75, 0x70, 0x6D, 0x6C, 0x6C, 0x6E, 0x73, 0x79, 0xFE, 0xF9, 0xF3, -0xEE, 0xEB, 0xE9, 0xE8, 0xE6, 0xE5, 0xE6, 0xE8, 0xEA, 0xED, 0xF1, 0xF8, 0xFD, 0x7E, 0x7E, 0xFE, -0xFC, 0xF9, 0xF5, 0xF5, 0xF6, 0xFB, 0x7C, 0x77, 0x71, 0x6E, 0x6C, 0x6A, 0x69, 0x69, 0x6B, 0x6E, -0x70, 0x75, 0x7A, 0xFE, 0xF6, 0xF1, 0xEE, 0xEC, 0xEB, 0xEB, 0xEC, 0xEE, 0xF1, 0xF5, 0xFB, 0x7D, -0x7B, 0x7A, 0x7C, 0xFE, 0xFA, 0xF4, 0xF1, 0xF0, 0xF0, 0xF3, 0xF7, 0xFB, 0xFD, 0xFF, 0xFF, 0x7F, -0x7F, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0xFD, 0xFC, 0xFA, 0xF5, 0xF4, 0xF1, 0xEF, 0xEF, 0xEF, 0xF0, -0xF4, 0xF8, 0xFD, 0x7D, 0x78, 0x77, 0x78, 0x7A, 0x7C, 0x7C, 0x7E, 0x7C, 0x7A, 0x79, 0x76, 0x77, -0x78, 0x77, 0x7B, 0x7E, 0xFF, 0xFD, 0xFD, 0xFE, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0x7E, 0xFE, 0xFB, -0xFA, 0xF9, 0xFA, 0xFB, 0xFE, 0x7F, 0x7C, 0x79, 0x78, 0x77, 0x77, 0x7A, 0x7C, 0x7D, 0x7E, 0x7B, -0x77, 0x74, 0x71, 0x6F, 0x6E, 0x6E, 0x6F, 0x6F, 0x70, 0x71, 0x73, 0x74, 0x76, 0x76, 0x75, 0x76, -0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x77, 0x74, 0x72, 0x70, 0x6F, 0x6E, 0x6E, 0x6E, 0x70, 0x74, -0x78, 0x7B, 0x7D, 0x7D, 0x7C, 0x7C, 0x7A, 0x76, 0x72, 0x71, 0x70, 0x70, 0x70, 0x71, 0x72, 0x72, -0x74, 0x76, 0x78, 0x7B, 0x7F, 0xFE, 0xFC, 0xF9, 0xF6, 0xF5, 0xF7, 0xFC, 0xFF, 0x7C, 0x79, 0x78, -0x77, 0x77, 0x77, 0x7A, 0x7E, 0xFE, 0xFC, 0xFA, 0xF8, 0xF8, 0xFA, 0xFC, 0xFE, 0x7D, 0x7A, 0x76, -0x74, 0x74, 0x73, 0x75, 0x76, 0x76, 0x78, 0x7A, 0x7C, 0x7E, 0xFF, 0xFB, 0xF9, 0xF8, 0xF9, 0xFD, -0x7E, 0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x78, 0x7C, 0x7F, 0xFB, 0xF6, 0xF5, 0xF2, 0xF2, 0xF3, -0xF4, 0xF7, 0xF8, 0xFA, 0xFC, 0xFE, 0xFF, 0xFF, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFA, -0xF7, 0xF6, 0xF8, 0xFC, 0x7F, 0x7C, 0x79, 0x72, 0x6F, 0x6E, 0x6E, 0x6E, 0x6F, 0x73, 0x77, 0x77, -0x7B, 0x7D, 0x7E, 0x7F, 0x7E, 0x7C, 0x7A, 0x77, 0x75, 0x71, 0x6F, 0x6E, 0x6D, 0x6E, 0x6F, 0x70, -0x73, 0x74, 0x77, 0x79, 0x7C, 0x7D, 0x7D, 0x7D, 0x7B, 0x7A, 0x79, 0x76, 0x73, 0x70, 0x6F, 0x71, -0x73, 0x78, 0x7B, 0x7F, 0xFB, 0xF8, 0xF5, 0xF3, 0xF5, 0xF6, 0xF6, 0xF8, 0xF9, 0xFC, 0xFE, 0xFF, -0x7F, 0xFF, 0xFD, 0xFC, 0xFC, 0xFB, 0xF7, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF6, 0xF7, 0xF9, -0xFA, 0xFC, 0xFF, 0xFF, 0x7F, 0x7F, 0xFE, 0xFD, 0xFE, 0xFD, 0xFB, 0xFB, 0xFC, 0xFE, 0x7E, 0x7C, -0x7A, 0x79, 0x77, 0x76, 0x77, 0x77, 0x78, 0x78, 0x79, 0x7C, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, -0x7D, 0x7E, 0x7C, 0x7E, 0x7F, 0x7E, 0x7E, 0xFF, 0xFD, 0xFC, 0xFB, 0xF8, 0xF8, 0xFA, 0xFA, 0xFC, -0xFE, 0x7D, 0x78, 0x75, 0x72, 0x70, 0x70, 0x73, 0x75, 0x76, 0x78, 0x79, 0x79, 0x7A, 0x79, 0x78, -0x77, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x79, 0x7A, 0x7B, 0x7D, 0x7F, 0xFC, 0xF8, 0xF6, -0xF4, 0xF2, 0xF3, 0xF7, 0xF9, 0xFB, 0x7E, 0x78, 0x75, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x74, -0x75, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x78, 0x78, 0x78, 0x77, 0x75, 0x75, 0x76, 0x79, 0x7B, -0x7C, 0x7E, 0xFE, 0xFC, 0xF9, 0xF6, 0xF5, 0xF6, 0xF7, 0xF9, 0xFC, 0xFE, 0x7C, 0x79, 0x77, 0x76, -0x75, 0x74, 0x74, 0x75, 0x74, 0x76, 0x77, 0x78, 0x79, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x78, 0x78, -0x77, 0x76, 0x77, 0x77, 0x77, 0x78, 0x7A, 0x7C, 0xFF, 0xFD, 0xFA, 0xF8, 0xF6, 0xF7, 0xF8, 0xF7, -0xF8, 0xF8, 0xF8, 0xF9, 0xFA, 0xF9, 0xF9, 0xFA, 0xFB, 0xFB, 0xFB, 0xFD, 0xFD, 0xFC, 0xFD, 0xFE, -0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7B, 0x7A, 0x79, 0x79, 0x79, 0x78, 0x79, 0x7B, 0x7C, 0x7C, 0x7C, -0x7C, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x71, 0x70, 0x6F, 0x6F, 0x6E, -0x6D, 0x6C, 0x6C, 0x6D, 0x6E, 0x6E, 0x6E, 0x6F, 0x6E, 0x6F, 0x70, 0x70, 0x72, 0x75, 0x78, 0x7B, -0x7B, 0x7C, 0x7D, 0xFF, 0xFD, 0xFC, 0xFA, 0xFA, 0xF9, 0xF7, 0xF7, 0xF7, 0xF7, 0xF8, 0xF8, 0xF9, -0xFA, 0xFA, 0xFA, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFB, -0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFF, 0x7F, 0xFC, 0xFA, 0xFB, 0xFA, 0xFA, 0xF9, -0xFA, 0xFC, 0xFC, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, 0xFE, 0xFD, 0xFC, 0xFD, 0xFA, 0xFA, 0xF9, 0xF8, -0xFA, 0xF8, 0xFA, 0xFA, 0xFB, 0xFE, 0xFB, 0xFF, 0xFD, 0xFD, 0xFF, 0xFB, 0xFF, 0xFA, 0xFC, 0x7F, -0xFC, 0x70, 0x6A, 0x64, 0x61, 0x67, 0x6C, 0x73, 0x61, 0x60, 0x5A, 0x47, 0x53, 0xDF, 0x7D, 0x6F, -0x71, 0x69, 0x7F, 0x72, 0x70, 0x68, 0x5A, 0x5B, 0x59, 0x55, 0x5A, 0x5D, 0x4E, 0x46, 0x51, 0x77, -0xF6, 0xEC, 0xE8, 0xE6, 0xE5, 0xE4, 0xE1, 0xE5, 0xFD, 0x60, 0x65, 0xE6, 0xDB, 0xDD, 0xE1, 0xE4, -0xE2, 0xDC, 0xD4, 0xCF, 0xCF, 0xCF, 0xD1, 0xD2, 0xCF, 0xCD, 0xCC, 0xCD, 0xD0, 0xD4, 0xD7, 0xD5, -0xCE, 0xCD, 0xD3, 0xD9, 0xDB, 0xDA, 0xD9, 0xDC, 0xE2, 0xE5, 0xF1, 0xEE, 0xD7, 0xD2, 0xD9, 0xDC, -0xDD, 0xD9, 0xDC, 0xE7, 0xDF, 0xD9, 0xDD, 0x74, 0x62, 0xFC, 0xE9, 0xF2, 0x6C, 0x5D, 0x5D, 0x61, -0x6B, 0x6C, 0x5C, 0x5D, 0x70, 0x64, 0x5B, 0x6D, 0x78, 0x61, 0x57, 0x58, 0x65, 0x62, 0x53, 0x51, -0x69, 0xF5, 0x59, 0x53, 0x69, 0x68, 0x54, 0x4F, 0x67, 0xFA, 0x5B, 0x58, 0x5D, 0x60, 0x5D, 0x4E, -0x53, 0x61, 0x5A, 0x5F, 0x63, 0x61, 0x5E, 0x4C, 0x4C, 0x5A, 0x6B, 0xF7, 0x58, 0x47, 0x51, 0x6D, -0x68, 0x5A, 0x55, 0x53, 0x4A, 0x4E, 0xEE, 0xE1, 0x56, 0x46, 0x4D, 0x74, 0x70, 0x59, 0x53, 0x4C, -0x4E, 0x62, 0xF2, 0xF3, 0x5A, 0x4A, 0x4F, 0x6D, 0x6B, 0x57, 0x63, 0xED, 0x79, 0x69, 0x62, 0x5D, -0x6C, 0x67, 0x5E, 0xF5, 0xEA, 0x69, 0x63, 0x76, 0xFA, 0x6A, 0x59, 0x5D, 0xFB, 0xF6, 0x72, 0xFB, -0x71, 0x5D, 0x65, 0x7D, 0xFC, 0x79, 0xFB, 0xE9, 0xE2, 0xDD, 0xE3, 0xF9, 0xFA, 0xF3, 0xEA, 0xEC, -0x7D, 0xF1, 0xE5, 0xF2, 0x78, 0x6D, 0x6D, 0xED, 0xE4, 0xE5, 0xE4, 0xF6, 0x7A, 0xF8, 0xE5, 0xDC, -0xEA, 0xDF, 0xCF, 0xD3, 0xE7, 0x6C, 0x78, 0xCF, 0xC9, 0xD5, 0x7E, 0x64, 0x7E, 0xD7, 0xCF, 0xD7, -0xE0, 0xE8, 0xDC, 0xCB, 0xC5, 0xCC, 0xE6, 0x73, 0xE9, 0xD2, 0xC9, 0xCA, 0xD3, 0xED, 0x68, 0xF3, -0xD9, 0xDA, 0xDC, 0xDA, 0xD7, 0xDB, 0xE1, 0xE1, 0xEA, 0x69, 0x59, 0x60, 0xEE, 0xE0, 0xDC, 0xDF, -0xE5, 0xDD, 0xE1, 0xED, 0xED, 0xF4, 0xF6, 0xF2, 0xEE, 0xED, 0xFC, 0x6F, 0x64, 0x5C, 0x5C, 0x61, -0x76, 0xEA, 0xE1, 0xEB, 0x73, 0x66, 0x60, 0x69, 0xFB, 0x7E, 0x70, 0x76, 0xFF, 0x78, 0x73, 0xEB, -0xE2, 0x6F, 0x5C, 0x69, 0xE9, 0xDB, 0xDE, 0x73, 0x5E, 0x6D, 0xED, 0xEB, 0xF4, 0xFF, 0x77, 0xFD, -0xE7, 0xE2, 0xFB, 0x66, 0x69, 0xFE, 0xFA, 0x6B, 0x63, 0x69, 0x74, 0x74, 0x66, 0x63, 0x6F, 0xFB, -0xFD, 0x73, 0x71, 0x7B, 0xF4, 0xE8, 0xE2, 0xE8, 0xF2, 0xEB, 0xDE, 0xDC, 0xDE, 0xE2, 0xE7, 0xE5, -0xDF, 0xDF, 0xE8, 0xFC, 0x6D, 0x6A, 0x66, 0x5C, 0x53, 0x51, 0x56, 0x5B, 0x59, 0x56, 0x56, 0x5A, -0x5E, 0x5A, 0x53, 0x53, 0x59, 0x5D, 0x5F, 0x64, 0x74, 0xE9, 0xD6, 0xCB, 0xCB, 0xD3, 0xDC, 0xD4, -0xC8, 0xC1, 0xBF, 0xBE, 0xBE, 0xC5, 0xCE, 0xDC, 0xEA, 0x68, 0x4B, 0x3E, 0x3B, 0x3B, 0x3D, 0x3E, -0x41, 0x45, 0x47, 0x48, 0x4A, 0x4C, 0x4A, 0x47, 0x49, 0x4F, 0x5E, 0x6D, 0xF5, 0xDB, 0xCC, 0xC5, -0xC1, 0xBF, 0xBE, 0xBC, 0xBA, 0xB7, 0xB2, 0xAF, 0xAE, 0xB7, 0xDA, 0x43, 0x38, 0x35, 0x32, 0x31, -0x33, 0x3A, 0x46, 0x54, 0x5D, 0x56, 0x4A, 0x44, 0x43, 0x46, 0x44, 0x3F, 0x40, 0x4B, 0x61, 0x7B, -0xFD, 0xE7, 0xD4, 0xCA, 0xC5, 0xBF, 0xBB, 0xB6, 0xB1, 0xAF, 0xAD, 0xAC, 0xAC, 0xB4, 0xD8, 0x3C, -0x2D, 0x2B, 0x2D, 0x2F, 0x37, 0x41, 0x54, 0x76, 0xFF, 0x68, 0x54, 0x46, 0x40, 0x44, 0x49, 0x4A, -0x49, 0x4C, 0x5C, 0xFB, 0xE9, 0xE5, 0xDB, 0xCE, 0xC8, 0xC3, 0xBE, 0xBA, 0xB6, 0xB1, 0xAE, 0xAB, -0xA9, 0xAB, 0xBD, 0x3F, 0x2A, 0x26, 0x2A, 0x31, 0x3A, 0x43, 0x58, 0xE9, 0xDB, 0xE8, 0x5E, 0x46, -0x3C, 0x3D, 0x48, 0x55, 0x56, 0x55, 0x61, 0xF3, 0xE8, 0xE6, 0xDC, 0xCF, 0xC9, 0xC0, 0xB9, 0xB4, -0xB3, 0xB3, 0xAF, 0xAA, 0xA8, 0xAF, 0x75, 0x2C, 0x22, 0x24, 0x2D, 0x3F, 0x56, 0x72, 0xE0, 0xCF, -0xD4, 0x59, 0x3F, 0x38, 0x38, 0x3E, 0x4C, 0x68, 0xE8, 0xE3, 0xEA, 0x7E, 0x67, 0x64, 0x79, 0xDC, -0xCB, 0xBF, 0xB7, 0xB1, 0xAF, 0xAE, 0xAC, 0xAA, 0xB1, 0x56, 0x29, 0x1F, 0x20, 0x2B, 0x45, 0xD1, -0xC4, 0xC7, 0xCB, 0xD8, 0x4B, 0x33, 0x2E, 0x34, 0x42, 0x6D, 0xCD, 0xC5, 0xC8, 0xD1, 0xE0, 0x69, -0x52, 0x52, 0x6D, 0xD4, 0xC6, 0xBB, 0xB1, 0xAC, 0xAB, 0xAA, 0xA8, 0xAE, 0x68, 0x28, 0x1D, 0x1E, -0x2B, 0x53, 0xBC, 0xB6, 0xBD, 0xCA, 0xE1, 0x4E, 0x33, 0x2A, 0x2C, 0x3B, 0x7D, 0xBF, 0xBB, 0xC1, -0xD5, 0xED, 0x6A, 0x4F, 0x4C, 0x58, 0x7E, 0xD6, 0xC7, 0xBB, 0xB2, 0xAD, 0xA9, 0xA6, 0xA9, 0xC3, -0x2D, 0x1D, 0x1B, 0x23, 0x41, 0xBC, 0xAF, 0xB5, 0xC2, 0xDE, 0x4F, 0x3B, 0x2D, 0x27, 0x2D, 0x49, -0xC3, 0xB5, 0xB9, 0xCB, 0x64, 0x54, 0x56, 0x51, 0x58, 0x75, 0xE3, 0xD1, 0xCA, 0xC1, 0xB6, 0xAB, -0xA6, 0xA3, 0xA6, 0xC0, 0x2B, 0x1C, 0x1A, 0x24, 0x4D, 0xB0, 0xAA, 0xB0, 0xC3, 0xF0, 0x46, 0x38, -0x2D, 0x28, 0x2B, 0x4C, 0xBC, 0xB2, 0xB6, 0xD1, 0x4B, 0x46, 0x4F, 0x58, 0x61, 0xEE, 0xE1, 0xDB, -0xCF, 0xCB, 0xBD, 0xAE, 0xA7, 0xA3, 0xA2, 0xB6, 0x2C, 0x1B, 0x19, 0x21, 0x52, 0xAB, 0xA5, 0xAE, -0xC9, 0x4F, 0x3B, 0x37, 0x32, 0x2A, 0x2A, 0x3D, 0xC9, 0xB2, 0xB1, 0xCA, 0x44, 0x3D, 0x49, 0x5F, -0xDD, 0xD8, 0x77, 0x6E, 0xED, 0xDB, 0xC7, 0xB7, 0xAB, 0xA5, 0xA3, 0xA6, 0xC8, 0x26, 0x1A, 0x1A, -0x27, 0xC5, 0xA4, 0xA3, 0xAF, 0xE9, 0x3B, 0x33, 0x34, 0x31, 0x2D, 0x31, 0x57, 0xBF, 0xB3, 0xBA, -0x78, 0x41, 0x3E, 0x4E, 0xDC, 0xCE, 0xD4, 0x78, 0x5B, 0x67, 0xDC, 0xC4, 0xB7, 0xAC, 0xA6, 0xA5, -0xA5, 0xBA, 0x2C, 0x1B, 0x19, 0x23, 0xD8, 0xA3, 0x9F, 0xAB, 0xDA, 0x34, 0x2D, 0x30, 0x33, 0x33, -0x37, 0x54, 0xC1, 0xB7, 0xBD, 0x6E, 0x41, 0x3D, 0x4A, 0xD8, 0xCA, 0xD0, 0xEB, 0x56, 0x54, 0x74, -0xCE, 0xBD, 0xAF, 0xA8, 0xA6, 0xA5, 0xAE, 0x3B, 0x1E, 0x19, 0x1E, 0x43, 0xA8, 0x9E, 0xA6, 0xC8, -0x33, 0x29, 0x2C, 0x32, 0x39, 0x3D, 0x4E, 0xCD, 0xBE, 0xC2, 0xFF, 0x40, 0x3D, 0x48, 0xE0, 0xC4, -0xCB, 0xEA, 0x4F, 0x48, 0x59, 0xD7, 0xBE, 0xB5, 0xAD, 0xA9, 0xA9, 0xA7, 0xB3, 0x34, 0x1D, 0x19, -0x20, 0xEE, 0xA2, 0x9D, 0xA8, 0x60, 0x2A, 0x26, 0x2D, 0x3B, 0x4A, 0x4E, 0x64, 0xCE, 0xC6, 0xCF, -0x57, 0x42, 0x47, 0x67, 0xCB, 0xC3, 0xD4, 0x5C, 0x48, 0x47, 0x63, 0xCA, 0xBA, 0xB2, 0xAE, 0xAC, -0xAC, 0xAB, 0xB3, 0x3D, 0x1F, 0x1B, 0x20, 0x51, 0xA5, 0x9E, 0xA8, 0x6C, 0x2A, 0x24, 0x2B, 0x3E, -0x5E, 0x6C, 0x66, 0xFA, 0xE0, 0xE4, 0x60, 0x4B, 0x4E, 0x71, 0xD2, 0xC8, 0xD8, 0x5A, 0x4A, 0x49, -0x6E, 0xC6, 0xB9, 0xB3, 0xB1, 0xAF, 0xAE, 0xAC, 0xAF, 0x48, 0x21, 0x1B, 0x1F, 0x4C, 0xA5, 0x9D, -0xA7, 0x64, 0x28, 0x23, 0x2C, 0x4A, 0xD6, 0xD9, 0x61, 0x59, 0x6C, 0xEF, 0xF8, 0x5B, 0x5B, 0xEE, -0xD5, 0xCD, 0xDB, 0x5C, 0x4D, 0x4C, 0x6E, 0xC8, 0xBB, 0xB8, 0xB8, 0xB6, 0xB3, 0xAD, 0xA8, 0xBC, -0x2D, 0x1D, 0x1B, 0x2B, 0xB7, 0x9F, 0xA1, 0xB9, 0x33, 0x23, 0x28, 0x3A, 0xEB, 0xCF, 0x77, 0x50, -0x56, 0x6E, 0xE2, 0x73, 0x55, 0x5D, 0xE6, 0xCF, 0xD9, 0x5B, 0x4B, 0x47, 0x59, 0xD2, 0xC3, 0xBD, -0xBD, 0xBC, 0xB6, 0xAE, 0xA9, 0xAB, 0x68, 0x24, 0x1B, 0x1E, 0x3C, 0xAA, 0x9E, 0xA6, 0xDE, 0x2A, -0x23, 0x2C, 0x47, 0xD1, 0xCE, 0x72, 0x55, 0x58, 0x6A, 0x78, 0x5D, 0x5B, 0xF9, 0xDA, 0xD3, 0xDE, -0x5A, 0x49, 0x4A, 0x5F, 0xD1, 0xC0, 0xBD, 0xBC, 0xB9, 0xB3, 0xAD, 0xA9, 0xB1, 0x3C, 0x1F, 0x1C, -0x24, 0xE1, 0xA4, 0x9F, 0xAD, 0x44, 0x26, 0x25, 0x32, 0x6E, 0xC3, 0xCD, 0x64, 0x4F, 0x4F, 0x62, -0x70, 0x5C, 0x68, 0xE1, 0xD4, 0xD3, 0xF6, 0x4E, 0x45, 0x4B, 0x78, 0xCA, 0xBE, 0xBC, 0xBC, 0xB8, -0xB3, 0xAC, 0xA9, 0xBC, 0x2F, 0x1E, 0x1C, 0x2A, 0xBC, 0xA0, 0xA1, 0xB7, 0x35, 0x24, 0x28, 0x3B, -0xD8, 0xC4, 0xDC, 0x53, 0x4B, 0x4F, 0x67, 0x6D, 0x65, 0xEA, 0xDB, 0xD5, 0xDA, 0x5E, 0x4B, 0x48, -0x53, 0xDB, 0xC4, 0xBD, 0xBD, 0xBB, 0xB5, 0xAE, 0xA8, 0xAB, 0x75, 0x25, 0x1B, 0x1E, 0x3D, 0xAA, -0x9E, 0xA6, 0xDC, 0x2B, 0x25, 0x2E, 0x4E, 0xCC, 0xCC, 0x66, 0x4B, 0x4C, 0x5A, 0x74, 0x6C, 0x6D, -0xDF, 0xD6, 0xD6, 0xED, 0x4D, 0x43, 0x46, 0x59, 0xD0, 0xBF, 0xBC, 0xBB, 0xB8, 0xB3, 0xAD, 0xA9, -0xB3, 0x38, 0x1E, 0x1B, 0x24, 0xCF, 0xA2, 0x9F, 0xAF, 0x3E, 0x26, 0x27, 0x36, 0x6A, 0xCD, 0xE6, -0x4F, 0x4D, 0x55, 0x6E, 0xEF, 0x63, 0x7B, 0xDA, 0xDB, 0xDF, 0x5F, 0x49, 0x47, 0x4F, 0xE8, 0xC5, -0xBD, 0xBC, 0xBB, 0xB6, 0xAF, 0xAA, 0xAA, 0xCD, 0x29, 0x1C, 0x1D, 0x34, 0xAE, 0x9F, 0xA4, 0xC7, -0x2E, 0x25, 0x2C, 0x41, 0xDB, 0xD2, 0x75, 0x5B, 0x59, 0x60, 0x6E, 0x5B, 0x5C, 0xDF, 0xD0, 0xD8, -0x74, 0x4B, 0x43, 0x4B, 0x6E, 0xCC, 0xBF, 0xBD, 0xBE, 0xBC, 0xB5, 0xAD, 0xA8, 0xAD, 0x4B, 0x22, -0x1C, 0x22, 0x65, 0xA6, 0x9F, 0xAC, 0x4C, 0x2A, 0x28, 0x33, 0x50, 0xDE, 0xF2, 0x65, 0x7C, 0xF8, -0x79, 0x5A, 0x4B, 0x5E, 0xD7, 0xCF, 0xD6, 0x5F, 0x45, 0x43, 0x4C, 0xFB, 0xC9, 0xBF, 0xBD, 0xBC, -0xB8, 0xB2, 0xAD, 0xAA, 0xB7, 0x38, 0x20, 0x1D, 0x29, 0xC6, 0xA5, 0xA4, 0xB8, 0x3C, 0x2A, 0x2C, -0x39, 0x53, 0x7F, 0x6F, 0x79, 0xE8, 0xF9, 0x61, 0x4D, 0x4B, 0xFF, 0xD0, 0xD3, 0xEC, 0x4F, 0x45, -0x49, 0x58, 0xDF, 0xC7, 0xBF, 0xBD, 0xBB, 0xB5, 0xAF, 0xA9, 0xAA, 0xCA, 0x2C, 0x1D, 0x1E, 0x36, -0xB1, 0xA2, 0xA8, 0xCE, 0x33, 0x2B, 0x30, 0x3E, 0x4F, 0x5A, 0x6D, 0xD8, 0xD2, 0xF5, 0x4F, 0x46, -0x54, 0xD4, 0xCA, 0xD7, 0x65, 0x48, 0x43, 0x4C, 0x61, 0xD7, 0xC4, 0xBF, 0xBD, 0xB7, 0xB1, 0xAD, -0xAA, 0xB0, 0x48, 0x23, 0x1D, 0x24, 0x5D, 0xAA, 0xA4, 0xB0, 0x56, 0x30, 0x2E, 0x34, 0x3E, 0x47, -0x52, 0xE3, 0xC9, 0xCE, 0x65, 0x45, 0x43, 0x6A, 0xCE, 0xCD, 0xDE, 0x58, 0x49, 0x49, 0x4F, 0x6D, -0xD1, 0xC0, 0xBB, 0xB6, 0xAF, 0xAE, 0xAA, 0xAB, 0xCF, 0x2B, 0x1D, 0x1E, 0x36, 0xB2, 0xA4, 0xA9, -0xC7, 0x3B, 0x2F, 0x31, 0x37, 0x3D, 0x46, 0x6E, 0xC7, 0xC5, 0xE5, 0x4C, 0x41, 0x50, 0xD5, 0xCB, -0xDF, 0x58, 0x4C, 0x49, 0x4E, 0x62, 0xE4, 0xC8, 0xBD, 0xB9, 0xB4, 0xAF, 0xAD, 0xA9, 0xB2, 0x41, -0x22, 0x1D, 0x26, 0xEB, 0xAA, 0xA6, 0xB3, 0x5D, 0x38, 0x32, 0x32, 0x34, 0x39, 0x4D, 0xCC, 0xBD, -0xC7, 0x60, 0x44, 0x47, 0x6D, 0xDC, 0xE2, 0xEF, 0x63, 0x58, 0x50, 0x4D, 0x5A, 0xDB, 0xC3, 0xBA, -0xB3, 0xAF, 0xAD, 0xAC, 0xAE, 0xD3, 0x2D, 0x1F, 0x20, 0x38, 0xB9, 0xA9, 0xAD, 0xC4, 0x4C, 0x39, -0x33, 0x30, 0x32, 0x3C, 0xFA, 0xBE, 0xBE, 0xD5, 0x51, 0x46, 0x4F, 0x6F, 0x7B, 0x65, 0x68, 0x76, -0x60, 0x54, 0x52, 0x61, 0xCF, 0xBF, 0xB7, 0xAE, 0xAC, 0xAB, 0xAB, 0xBC, 0x39, 0x22, 0x1E, 0x2B, -0xE7, 0xAF, 0xAC, 0xB6, 0xD1, 0x4E, 0x3A, 0x2F, 0x2D, 0x31, 0x45, 0xCC, 0xBC, 0xC2, 0xDA, 0x58, -0x4D, 0x55, 0x52, 0x52, 0x68, 0xED, 0xF4, 0x66, 0x55, 0x59, 0xEF, 0xCE, 0xBF, 0xB5, 0xAD, 0xAB, -0xAB, 0xAE, 0xCC, 0x31, 0x22, 0x22, 0x2F, 0xE8, 0xB6, 0xB1, 0xB8, 0xC4, 0x73, 0x3D, 0x2F, 0x2B, -0x2F, 0x3F, 0xDD, 0xC0, 0xBF, 0xC7, 0xD8, 0x73, 0x55, 0x46, 0x44, 0x53, 0x7B, 0xEE, 0xED, 0xF2, -0xED, 0xDC, 0xCF, 0xC1, 0xB3, 0xAC, 0xA9, 0xA9, 0xB2, 0x58, 0x2C, 0x24, 0x28, 0x36, 0x5C, 0xC7, -0xBA, 0xB6, 0xB7, 0xCA, 0x49, 0x34, 0x2D, 0x2E, 0x37, 0x49, 0xE0, 0xC4, 0xBD, 0xBE, 0xC7, 0xEA, -0x4C, 0x42, 0x44, 0x49, 0x50, 0x69, 0xDD, 0xD0, 0xCB, 0xC6, 0xBD, 0xB3, 0xAD, 0xAB, 0xAB, 0xBA, -0x49, 0x2F, 0x2B, 0x2D, 0x32, 0x3A, 0x4B, 0xD6, 0xBC, 0xB6, 0xBD, 0xD7, 0x51, 0x3D, 0x36, 0x34, -0x37, 0x3E, 0x52, 0xDE, 0xC8, 0xC3, 0xC7, 0xCE, 0xDE, 0x72, 0x56, 0x4F, 0x53, 0x5D, 0xFF, 0xDA, -0xC9, 0xBD, 0xB7, 0xB4, 0xB2, 0xB6, 0xC6, 0x62, 0x47, 0x3F, 0x3D, 0x3B, 0x3B, 0x40, 0x4E, 0x6F, -0xEC, 0x7B, 0x67, 0x5E, 0x5B, 0x59, 0x55, 0x5A, 0x65, 0x5E, 0x5A, 0x5F, 0x61, 0x5E, 0x63, 0x65, -0x61, 0x6D, 0xF5, 0xFA, 0x7A, 0x77, 0x77, 0xFF, 0xEB, 0xDC, 0xD5, 0xCE, 0xCA, 0xC8, 0xC8, 0xCD, -0xD9, 0xEC, 0x76, 0x70, 0xFD, 0xED, 0xEA, 0xEE, 0x7D, 0x66, 0x59, 0x53, 0x50, 0x4F, 0x50, 0x54, -0x56, 0x58, 0x59, 0x5A, 0x5A, 0x5C, 0x5F, 0x6B, 0xF6, 0xE5, 0xE1, 0xE7, 0xEF, 0xF5, 0xF2, 0xEA, -0xDF, 0xD8, 0xCE, 0xC8, 0xC4, 0xC5, 0xCB, 0xD4, 0xDF, 0xE9, 0xE7, 0xE1, 0xDD, 0xDB, 0xDE, 0xEE, -0x68, 0x57, 0x4F, 0x4D, 0x4D, 0x4E, 0x4F, 0x4F, 0x52, 0x54, 0x53, 0x51, 0x53, 0x57, 0x5E, 0x6F, -0xFA, 0xEF, 0xEF, 0xF3, 0xF1, 0xF1, 0xEE, 0xE6, 0xDE, 0xD6, 0xCF, 0xCD, 0xCE, 0xD3, 0xDA, 0xDC, -0xDF, 0xDF, 0xD9, 0xD5, 0xD4, 0xD7, 0xE0, 0xFE, 0x6B, 0x5F, 0x5A, 0x58, 0x56, 0x54, 0x54, 0x53, -0x53, 0x50, 0x4E, 0x4F, 0x52, 0x56, 0x5C, 0x64, 0x67, 0x66, 0x69, 0x6C, 0x6D, 0x74, 0xFA, 0xEC, -0xDF, 0xD7, 0xD6, 0xDD, 0xE6, 0xF3, 0x7B, 0xF7, 0xE8, 0xDC, 0xD3, 0xD0, 0xD2, 0xD9, 0xE1, 0xE7, -0xEB, 0xF6, 0x7B, 0x74, 0x6F, 0x6B, 0x66, 0x5E, 0x59, 0x55, 0x53, 0x52, 0x56, 0x59, 0x5C, 0x61, -0x5F, 0x64, 0x65, 0x62, 0x6F, 0x7B, 0xFC, 0xE4, 0xDC, 0xD9, 0xE2, 0x7E, 0xFF, 0xFE, 0xFF, 0xEE, -0xDF, 0xD8, 0xD6, 0xD7, 0xDB, 0xDD, 0xDD, 0xE8, 0xE7, 0xE3, 0xEA, 0xE7, 0xF9, 0x72, 0x7C, 0x5F, -0x56, 0x58, 0x58, 0x56, 0x57, 0x57, 0x53, 0x54, 0x4A, 0x42, 0x4F, 0x67, 0x6A, 0xE0, 0xD4, 0xD8, -0xD7, 0xDD, 0xFD, 0xFE, 0xE4, 0x7B, 0xFF, 0xD9, 0xDF, 0xDE, 0xD7, 0xDA, 0xCF, 0xCF, 0xD3, 0xCD, -0xD3, 0xDF, 0xDD, 0xDE, 0xF3, 0x6D, 0x5F, 0x55, 0x54, 0x55, 0x51, 0x51, 0x50, 0x4F, 0x51, 0x53, -0x57, 0x59, 0x60, 0x73, 0xFB, 0xE7, 0xE1, 0xEA, 0xF4, 0x7D, 0x6D, 0x6F, 0x7F, 0x78, 0xF5, 0xE7, -0xEA, 0xE0, 0xDE, 0xD9, 0xCD, 0xCB, 0xC5, 0xC2, 0xC5, 0xCB, 0xDB, 0xDD, 0xEC, 0x53, 0x4C, 0x45, -0x42, 0x49, 0x48, 0x49, 0x4D, 0x51, 0x5A, 0x55, 0x55, 0x5D, 0x64, 0xF4, 0xED, 0xF5, 0xEB, 0xF2, -0x7A, 0x6D, 0x60, 0x5E, 0x6E, 0xF3, 0xF7, 0xE9, 0xDF, 0xDD, 0xD4, 0xCD, 0xC8, 0xC1, 0xBC, 0xB8, -0xB5, 0xB8, 0xC7, 0xF5, 0x52, 0x3E, 0x38, 0x37, 0x36, 0x3D, 0x4B, 0x59, 0xFD, 0xDF, 0xE3, 0xFE, -0x5C, 0x54, 0x52, 0x4E, 0x50, 0x55, 0x5D, 0xFF, 0xF2, 0xF1, 0xE9, 0xFB, 0xFD, 0x74, 0x5E, 0x62, -0x7A, 0xE3, 0xD2, 0xCA, 0xC0, 0xB9, 0xB1, 0xAD, 0xAE, 0xBC, 0x68, 0x3E, 0x31, 0x2D, 0x2E, 0x30, -0x3B, 0x5B, 0xD4, 0xC7, 0xC9, 0xD6, 0x65, 0x4A, 0x46, 0x3E, 0x3D, 0x47, 0x51, 0x7F, 0xD5, 0xD0, -0xCE, 0xD2, 0xE2, 0x6E, 0x57, 0x55, 0x61, 0xEA, 0xCD, 0xBE, 0xB7, 0xB2, 0xAD, 0xAB, 0xB0, 0xCE, -0x40, 0x2F, 0x2B, 0x2D, 0x2F, 0x38, 0x59, 0xCA, 0xBD, 0xBE, 0xCF, 0x70, 0x45, 0x39, 0x3A, 0x3B, -0x3F, 0x5D, 0xD9, 0xCB, 0xC4, 0xC5, 0xCF, 0xEA, 0x62, 0x52, 0x50, 0x5C, 0x7E, 0xD1, 0xBE, 0xB5, -0xAF, 0xAE, 0xAB, 0xAC, 0xC2, 0x44, 0x2F, 0x2A, 0x2D, 0x32, 0x38, 0x55, 0xC6, 0xBA, 0xBC, 0xCF, -0x5B, 0x40, 0x36, 0x34, 0x38, 0x40, 0x66, 0xCD, 0xC4, 0xC2, 0xC6, 0xD1, 0xFE, 0x52, 0x4C, 0x4F, -0x5C, 0xEF, 0xCF, 0xC1, 0xB7, 0xAF, 0xAD, 0xAB, 0xAD, 0xC9, 0x3C, 0x2D, 0x29, 0x2D, 0x35, 0x3D, -0xF1, 0xBD, 0xB8, 0xBF, 0xE1, 0x4C, 0x3C, 0x32, 0x31, 0x39, 0x47, 0xF7, 0xCB, 0xC4, 0xC2, 0xC7, -0xD9, 0x6F, 0x54, 0x4D, 0x4F, 0x5D, 0xEF, 0xCF, 0xC1, 0xB8, 0xAF, 0xAD, 0xAB, 0xAC, 0xC9, 0x3A, -0x2C, 0x29, 0x2D, 0x37, 0x44, 0xD8, 0xB9, 0xB7, 0xC4, 0x6C, 0x44, 0x38, 0x31, 0x30, 0x39, 0x4E, -0xDF, 0xCA, 0xC5, 0xC6, 0xCD, 0xEF, 0x5E, 0x5A, 0x53, 0x55, 0x64, 0xE8, 0xCD, 0xC4, 0xBB, 0xB0, -0xAC, 0xAA, 0xAC, 0xD0, 0x36, 0x2C, 0x2B, 0x2E, 0x39, 0x4A, 0xCB, 0xB6, 0xB7, 0xC8, 0x5D, 0x43, -0x39, 0x31, 0x32, 0x3D, 0x58, 0xD9, 0xCD, 0xCA, 0xC9, 0xD6, 0x73, 0x62, 0x63, 0x62, 0x68, 0x72, -0xE9, 0xCE, 0xC6, 0xBB, 0xAF, 0xAD, 0xAB, 0xAE, 0xD7, 0x38, 0x2D, 0x2C, 0x2F, 0x3B, 0x4F, 0xCA, -0xB6, 0xB8, 0xCB, 0x5D, 0x41, 0x39, 0x32, 0x33, 0x3E, 0x59, 0xDC, 0xCF, 0xCD, 0xCB, 0xD8, 0x63, -0x53, 0x5A, 0x5E, 0x61, 0x6F, 0xEA, 0xCF, 0xC6, 0xBC, 0xB0, 0xAD, 0xAB, 0xAE, 0xEE, 0x32, 0x2C, -0x2C, 0x30, 0x3B, 0x50, 0xC9, 0xB6, 0xB9, 0xCF, 0x5D, 0x47, 0x3A, 0x32, 0x33, 0x3F, 0x63, 0xDB, -0xD5, 0xCC, 0xC8, 0xD7, 0x66, 0x56, 0x58, 0x5C, 0x5A, 0x5B, 0x7E, 0xCE, 0xC4, 0xBB, 0xB0, 0xAD, -0xAB, 0xAF, 0x7B, 0x2F, 0x2C, 0x2E, 0x31, 0x39, 0x52, 0xC6, 0xB6, 0xBA, 0xD1, 0x5C, 0x4E, 0x3E, -0x32, 0x33, 0x3F, 0x64, 0xEA, 0xFD, 0xCE, 0xC2, 0xD0, 0x6C, 0x57, 0x5D, 0x64, 0x56, 0x53, 0x6C, -0xCE, 0xC4, 0xBD, 0xB1, 0xAD, 0xAA, 0xAE, 0x6F, 0x31, 0x2F, 0x31, 0x31, 0x37, 0x4F, 0xC5, 0xB6, -0xBA, 0xD2, 0xFC, 0x60, 0x45, 0x36, 0x35, 0x41, 0x56, 0xF8, 0xF2, 0xE4, 0xC6, 0xC8, 0x7C, 0x5A, -0x6A, 0x6A, 0x57, 0x52, 0x5B, 0xDA, 0xC6, 0xC0, 0xB6, 0xAE, 0xAA, 0xAC, 0xDD, 0x33, 0x30, 0x35, -0x31, 0x30, 0x42, 0xCE, 0xBA, 0xBA, 0xCC, 0xD9, 0xD9, 0x53, 0x3A, 0x35, 0x3E, 0x4D, 0x52, 0x60, -0xD6, 0xC5, 0xD2, 0x71, 0xE7, 0x7C, 0x55, 0x53, 0x51, 0x5B, 0xEE, 0xDC, 0xD3, 0xBE, 0xB2, 0xB0, -0xAD, 0xAE, 0x67, 0x31, 0x38, 0x39, 0x2F, 0x32, 0x49, 0xD5, 0xBE, 0xBF, 0xCF, 0xCD, 0xCA, 0x5C, -0x3D, 0x3C, 0x41, 0x41, 0x47, 0x5D, 0xE1, 0xC9, 0xC7, 0xD4, 0xDD, 0xFC, 0x51, 0x4C, 0x4C, 0x4C, -0x5F, 0xE2, 0xDC, 0xCA, 0xBF, 0xBD, 0xB9, 0xB5, 0xAF, 0xBA, 0x43, 0x35, 0x44, 0x3E, 0x2F, 0x36, -0x53, 0xD4, 0xC8, 0xCC, 0xD1, 0xC3, 0xC5, 0x5E, 0x41, 0x45, 0x49, 0x42, 0x44, 0x55, 0xE9, 0xD0, -0xD1, 0xDA, 0xD6, 0xD7, 0xFD, 0x5A, 0x58, 0x5B, 0x5A, 0x5B, 0x5F, 0x6C, 0x7A, 0xE1, 0xD3, 0xD2, -0xCC, 0xC8, 0xC4, 0xBF, 0xBD, 0xBA, 0xC2, 0x49, 0x3C, 0x4C, 0x41, 0x35, 0x3B, 0x52, 0xF3, 0xD6, -0xD1, 0xCE, 0xC3, 0xC6, 0x7A, 0x53, 0x57, 0x4E, 0x44, 0x46, 0x4F, 0x64, 0xE8, 0xDF, 0xDD, 0xD4, -0xD6, 0xEC, 0x56, 0x49, 0x54, 0x5E, 0x4F, 0x57, 0xFA, 0xE1, 0xDC, 0xE0, 0xE3, 0xD6, 0xD0, 0xDC, -0xD9, 0xC9, 0xC2, 0xBD, 0xC5, 0x58, 0x50, 0xE6, 0x4B, 0x37, 0x3F, 0x4F, 0x4D, 0x52, 0x6D, 0xDD, -0xC8, 0xC8, 0xDC, 0xDC, 0xD1, 0x72, 0x4A, 0x4A, 0x4E, 0x4B, 0x4E, 0x57, 0x6A, 0xDF, 0xD7, 0xDB, -0xD5, 0xCF, 0xDA, 0xF4, 0x74, 0x67, 0x5E, 0x5E, 0x5E, 0x66, 0xF9, 0xED, 0xEC, 0xE8, 0xE4, 0xE8, -0xF4, 0xF7, 0x60, 0x52, 0x6D, 0xF3, 0x5B, 0x66, 0xE7, 0xE1, 0xE0, 0xDF, 0xDF, 0xD8, 0xD1, 0xEA, -0x6B, 0xD9, 0xD1, 0xE5, 0xE6, 0xCC, 0xC4, 0xE7, 0x52, 0xEA, 0xE4, 0x4C, 0x48, 0x59, 0x5D, 0x59, -0x5D, 0x60, 0xF7, 0xDF, 0x79, 0x6A, 0xDF, 0xDC, 0xFE, 0xF8, 0xE2, 0xF0, 0x6F, 0x6B, 0x61, 0x5F, -0x62, 0x5D, 0x5E, 0x6C, 0x76, 0x70, 0xF7, 0xE5, 0xE6, 0xE7, 0xE5, 0xEA, 0xF4, 0x7D, 0x6C, 0x66, -0x68, 0x66, 0x66, 0x73, 0xF8, 0xF3, 0xF4, 0xF6, 0xFB, 0x7E, 0x7A, 0x7E, 0xF6, 0xEF, 0xED, 0xE9, -0xE9, 0xEF, 0xFB, 0x78, 0x6E, 0x69, 0x64, 0x63, 0x68, 0x6E, 0x74, 0x7B, 0xFA, 0xF6, 0xF3, 0xFF, -0x6B, 0x69, 0x69, 0x60, 0x5F, 0x65, 0x6C, 0x73, 0x7C, 0xF3, 0xEB, 0xE9, 0xEA, 0xE8, 0xE6, 0xE6, -0xE7, 0xE4, 0xDE, 0xDD, 0xE2, 0xE2, 0xE1, 0xE9, 0xF8, 0x77, 0x6B, 0x62, 0x5D, 0x5B, 0x5A, 0x59, -0x5A, 0x5B, 0x5D, 0x5E, 0x5E, 0x5E, 0x5F, 0x62, 0x67, 0x6D, 0x78, 0xFA, 0xF2, 0xEE, 0xEF, 0xF3, -0xF7, 0xF8, 0xFA, 0xFE, 0xFA, 0xF3, 0xF1, 0xEF, 0xEA, 0xE7, 0xE5, 0xE6, 0xE9, 0xEF, 0xFB, 0x79, -0x70, 0x6C, 0x6A, 0x6C, 0x6F, 0x77, 0x7C, 0xFD, 0xFB, 0x7F, 0x73, 0x6C, 0x69, 0x69, 0x6C, 0x73, -0xFA, 0xED, 0xE9, 0xE5, 0xE1, 0xE4, 0xE8, 0xE8, 0xE7, 0xE7, 0xE5, 0xE2, 0xE0, 0xDD, 0xDC, 0xE1, -0xE3, 0xE2, 0xEC, 0x7C, 0x6C, 0x63, 0x5D, 0x5B, 0x59, 0x58, 0x5A, 0x5B, 0x5B, 0x5C, 0x5F, 0x60, -0x5F, 0x60, 0x65, 0x6A, 0x75, 0xF8, 0xEC, 0xE7, 0xE6, 0xE7, 0xEA, 0xF0, 0xF8, 0xF9, 0xF4, 0xED, -0xE9, 0xE5, 0xE3, 0xE3, 0xE6, 0xEB, 0xF6, 0x76, 0x6C, 0x67, 0x62, 0x5F, 0x61, 0x64, 0x69, 0x6F, -0x73, 0x73, 0x75, 0x75, 0x70, 0x6E, 0x6F, 0x6E, 0x6E, 0x75, 0xFE, 0xF3, 0xEC, 0xE9, 0xE9, 0xE9, -0xED, 0xFA, 0x7A, 0x74, 0x71, 0x72, 0x73, 0x74, 0x7A, 0xFF, 0xFF, 0x7B, 0x72, 0x6E, 0x6D, 0x6C, -0x6C, 0x6E, 0x73, 0x7C, 0xFC, 0xF7, 0xF0, 0xEB, 0xE6, 0xE0, 0xDD, 0xDB, 0xDB, 0xDB, 0xDC, 0xDF, -0xE2, 0xE3, 0xE8, 0xF2, 0x7D, 0x6C, 0x61, 0x5D, 0x5A, 0x58, 0x59, 0x5C, 0x5E, 0x61, 0x66, 0x69, -0x6A, 0x6B, 0x6C, 0x6B, 0x6C, 0x75, 0xFE, 0xF7, 0xEE, 0xEA, 0xE8, 0xE6, 0xE9, 0xEC, 0xEB, 0xEB, -0xEE, 0xF0, 0xF2, 0xF6, 0xF9, 0xFD, 0x7F, 0xFF, 0x7C, 0x74, 0x6D, 0x69, 0x66, 0x64, 0x64, 0x68, -0x6B, 0x6D, 0x75, 0x7D, 0xFC, 0xF8, 0xFA, 0xFC, 0xFA, 0xF7, 0xF5, 0xF0, 0xEB, 0xE6, 0xE4, 0xE5, -0xE9, 0xED, 0xF2, 0xFC, 0x7A, 0x74, 0x6E, 0x6C, 0x6A, 0x69, 0x69, 0x6A, 0x6B, 0x6D, 0x6E, 0x6E, -0x6D, 0x6E, 0x70, 0x71, 0x74, 0x79, 0x7B, 0x7E, 0xFB, 0xF6, 0xF8, 0xF9, 0xF6, 0xF5, 0xF8, 0xFA, -0xF7, 0xF0, 0xEE, 0xF0, 0xF7, 0xFC, 0x7D, 0x73, 0x6C, 0x6B, 0x6B, 0x6A, 0x6B, 0x6B, 0x6B, 0x6B, -0x6C, 0x6D, 0x6D, 0x6E, 0x71, 0x71, 0x71, 0x72, 0x77, 0x7D, 0xFC, 0xF7, 0xF3, 0xED, 0xEB, 0xEB, -0xEE, 0xF4, 0xF9, 0xFE, 0x79, 0x77, 0x7B, 0x7F, 0x7F, 0xFF, 0xFF, 0x7B, 0x77, 0x76, 0x77, 0x79, -0x79, 0x7A, 0x7C, 0xFF, 0xFC, 0xFC, 0xFA, 0xF8, 0xF9, 0xF9, 0xFA, 0xFD, 0xFE, 0xFD, 0xFA, 0xF8, -0xF5, 0xF2, 0xF1, 0xF2, 0xF4, 0xF8, 0xFE, 0x7C, 0x79, 0x77, 0x77, 0x7A, 0x7E, 0x7F, 0x7C, 0x79, -0x78, 0x75, 0x73, 0x72, 0x71, 0x73, 0x75, 0x76, 0x78, 0x7D, 0xFD, 0xFB, 0xFC, 0xFF, 0x7D, 0x79, -0x76, 0x76, 0x77, 0x7C, 0xFB, 0xF5, 0xF3, 0xF3, 0xF3, 0xF7, 0x7D, 0x74, 0x6F, 0x6D, 0x6B, 0x6C, -0x6E, 0x73, 0x77, 0x77, 0x77, 0x7A, 0x7A, 0x76, 0x73, 0x72, 0x6F, 0x6D, 0x6B, 0x6C, 0x6F, 0x76, -0x7A, 0x7D, 0xFE, 0xFC, 0x7E, 0x7A, 0x75, 0x71, 0x6E, 0x6D, 0x6E, 0x71, 0x77, 0x7D, 0xFE, 0xFC, -0xFC, 0xFE, 0xFF, 0x7D, 0x7B, 0x7C, 0x7E, 0xFF, 0xFF, 0xFC, 0xF9, 0xF7, 0xF6, 0xF8, 0xFA, 0xFC, -0xFF, 0x7E, 0x7F, 0xFF, 0xFD, 0xFB, 0xF7, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFD, 0x7D, 0x7A, 0x7A, -0x7D, 0x7E, 0x7F, 0xFF, 0xFE, 0xFE, 0x7E, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0xFF, 0xFD, 0xFD, 0xFD, -0xFB, 0xF8, 0xF7, 0xF9, 0xFD, 0x7C, 0x79, 0x78, 0x78, 0x77, 0x77, 0x76, 0x75, 0x75, 0x75, 0x75, -0x75, 0x74, 0x76, 0x78, 0x79, 0x7B, 0x7D, 0x7F, 0xFD, 0xFB, 0xFF, 0x7A, 0x79, 0x7D, 0xFE, 0xFD, -0xFD, 0xFC, 0xFD, 0xFA, 0xF5, 0xF2, 0xF3, 0xF6, 0xF8, 0xF9, 0xFC, 0xFF, 0xFD, 0xF8, 0xF5, 0xF5, -0xF6, 0xFA, 0xFC, 0xFD, 0x7F, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x77, 0x7B, 0x7E, 0x7E, 0x7E, 0x7F, -0x7E, 0x7C, 0x79, 0x76, 0x76, 0x78, 0x79, 0x78, 0x7B, 0x7E, 0xFF, 0x7F, 0x7C, 0x7A, 0x78, 0x75, -0x73, 0x73, 0x74, 0x76, 0x77, 0x78, 0x7B, 0x7B, 0x79, 0x79, 0x78, 0x77, 0x78, 0x74, 0x71, 0x72, -0x73, 0x76, 0x77, 0x77, 0x79, 0x79, 0x77, 0x76, 0x75, 0x76, 0x78, 0x7B, 0x7F, 0xFC, 0xFB, 0xFB, -0xFA, 0xFB, 0xFE, 0x7C, 0x79, 0x79, 0x78, 0x78, 0x7B, 0xFF, 0xFD, 0xFD, 0xFC, 0xFC, 0xFE, 0x7E, -0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x78, 0x79, 0x7A, 0x7C, 0x7C, 0x7C, 0x7B, 0x77, 0x78, 0x7A, -0x7A, 0x7A, 0x7C, 0x7E, 0xFF, 0x7F, 0x7F, 0xFF, 0xFF, 0x7F, 0x7E, 0x7F, 0x7E, 0x7C, 0x7A, 0x7A, -0x79, 0x79, 0x7B, 0x7E, 0x7E, 0x7F, 0xFD, 0xFC, 0xFD, 0xFD, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, -0xFF, 0x7E, 0x7D, 0x7F, 0xFF, 0xFF, 0xFE, 0xFC, 0xFB, 0xFC, 0xFC, 0xFE, 0x7E, 0x7F, 0x7E, 0x7B, -0x7C, 0x7D, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x77, 0x7A, -0x7C, 0x7D, 0x7E, 0x7E, 0x7C, 0x79, 0x76, 0x77, 0x79, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0x7D, -0x7D, 0x7C, 0x7A, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x7C, 0x7E, 0x7D, 0x7E, 0x7E, 0x7C, 0x7B, 0x7C, -0x7C, 0x7C, 0x7D, 0xFF, 0xFC, 0xFB, 0xFB, 0xFC, 0xFF, 0x7C, 0x79, 0x77, 0x74, 0x75, 0x77, 0x7A, -0x7D, 0x7E, 0xFF, 0xFD, 0xFD, 0xFE, 0x7E, 0x7D, 0x7D, 0x7B, 0x7A, 0x7B, 0x7D, 0x7E, 0xFE, 0xFD, -0xFF, 0x7F, 0x7D, 0x7B, 0x7A, 0x78, 0x76, 0x76, 0x79, 0x7C, 0x7E, 0xFF, 0xFF, 0x7F, 0x7E, 0x7C, -0x7A, 0x79, 0x78, 0x78, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0x7F, 0x7E, 0x7D, 0x7B, 0x7A, -0x7B, 0x7C, 0x7D, 0xFE, 0xFC, 0xFA, 0xF9, 0xFA, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFA, 0xF8, 0xF7, -0xF6, 0xF7, 0xF9, 0xFB, 0xFE, 0x7E, 0x7C, 0x7A, 0x79, 0x79, 0x7B, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, -0x7E, 0x7C, 0x7B, 0x79, 0x7A, 0x7C, 0x7C, 0x7E, 0x7E, 0x7F, 0xFF, 0x7F, 0x7E, 0x7C, 0x7B, 0x79, -0x77, 0x76, 0x76, 0x78, 0x7B, 0x7B, 0x7B, 0x7A, 0x7A, 0x7A, 0x77, 0x77, 0x78, 0x78, 0x79, 0x7B, -0x7D, 0x79, 0x79, 0x7E, 0x79, 0x78, 0x79, 0x78, 0x7A, 0x78, 0x7D, 0x7D, 0x7C, 0xFF, 0x7D, 0x7F, -0x7E, 0x7B, 0x7A, 0x76, 0x79, 0x76, 0x78, 0x7B, 0x79, 0xFF, 0x7D, 0xFB, 0xFD, 0x7D, 0xF9, 0x7B, -0xFF, 0x79, 0x75, 0xFF, 0x6E, 0x7F, 0x71, 0x73, 0x79, 0x51, 0x60, 0xE2, 0x6F, 0x7D, 0xF7, 0xF5, -0x77, 0x72, 0xE4, 0x50, 0x4C, 0xDE, 0xFB, 0x66, 0xE5, 0xF6, 0x6F, 0x6C, 0xE7, 0xDC, 0x6E, 0xFD, -0xE6, 0x7E, 0xE9, 0x77, 0x62, 0xE3, 0xE9, 0x6C, 0x71, 0xEA, 0xDE, 0x75, 0x7E, 0xE8, 0x75, 0xF8, -0x7A, 0xFC, 0xF2, 0x65, 0xF8, 0xEE, 0xF9, 0xF4, 0x73, 0xE4, 0xF9, 0x6E, 0xE5, 0x75, 0x67, 0x5A, -0x50, 0x57, 0x5A, 0x7D, 0x6C, 0x64, 0xDA, 0xED, 0x64, 0xEA, 0xE9, 0xF5, 0x7E, 0x6F, 0xFC, 0xF2, -0x66, 0x63, 0xF7, 0x7D, 0x78, 0xF6, 0xF8, 0xE1, 0xE2, 0xF9, 0xEB, 0xE4, 0xED, 0xFE, 0xFA, 0xF6, -0xF1, 0xF2, 0x6F, 0xFE, 0xE8, 0xFF, 0x7F, 0xEA, 0xE8, 0xED, 0xEE, 0xEA, 0xEB, 0xED, 0xF8, 0xEF, -0xE8, 0x7F, 0xF5, 0xE6, 0xF7, 0xF2, 0xF3, 0xF2, 0xDF, 0xEB, 0xF5, 0xE3, 0xEC, 0xF2, 0xEF, 0xFC, -0xED, 0xEF, 0xFD, 0xED, 0xF0, 0x7C, 0x77, 0xFE, 0xF1, 0x77, 0x79, 0xEF, 0xF6, 0xF8, 0xFB, 0x72, -0x75, 0x79, 0x78, 0x70, 0x6E, 0x7C, 0x7D, 0x74, 0x79, 0x77, 0x6E, 0x71, 0x7D, 0x6F, 0x6B, 0x7D, -0xFE, 0x76, 0x7A, 0x7D, 0x7F, 0x75, 0x6C, 0x7B, 0xF7, 0x7A, 0x7B, 0x7E, 0x74, 0x79, 0x75, 0x70, -0x7C, 0x79, 0xFD, 0xF6, 0x6E, 0x6E, 0x7B, 0x6B, 0x67, 0x6D, 0x6E, 0x6A, 0x67, 0x6A, 0x6D, 0x6F, -0x6B, 0x67, 0x6D, 0x6C, 0x65, 0x63, 0x5E, 0x65, 0x6A, 0x5F, 0x68, 0x6C, 0x60, 0x6C, 0x7D, 0x6D, -0x6E, 0x7D, 0x7C, 0xFF, 0xEE, 0xEB, 0xEC, 0xE3, 0xDE, 0xE1, 0xE4, 0xE0, 0xE8, 0xF8, 0xEE, 0xFA, -0x6D, 0x69, 0x5C, 0x58, 0x59, 0x53, 0x50, 0x4E, 0x4D, 0x4E, 0x4F, 0x4F, 0x53, 0x51, 0x51, 0x54, -0x55, 0x56, 0x5A, 0x5E, 0x69, 0xF7, 0xE2, 0xD8, 0xCF, 0xCE, 0xCD, 0xCC, 0xCE, 0xCE, 0xCA, 0xC7, -0xC2, 0xBF, 0xBE, 0xBD, 0xC2, 0xD5, 0xF1, 0x62, 0x4B, 0x3F, 0x3D, 0x3D, 0x3E, 0x40, 0x42, 0x4A, -0x51, 0x51, 0x51, 0x55, 0x56, 0x4F, 0x4D, 0x4E, 0x50, 0x52, 0x55, 0x5C, 0x69, 0xFA, 0xE4, 0xD9, -0xCD, 0xC9, 0xC5, 0xC1, 0xBF, 0xBB, 0xBB, 0xBD, 0xB9, 0xB7, 0xB5, 0xB7, 0xC8, 0xDD, 0x61, 0x43, -0x3C, 0x38, 0x38, 0x3D, 0x40, 0x46, 0x4E, 0x5A, 0x60, 0x5D, 0x5B, 0x5B, 0x5A, 0x58, 0x56, 0x58, -0x5C, 0x5E, 0x5E, 0x64, 0x6B, 0x6D, 0xF9, 0xED, 0xE5, 0xDC, 0xD9, 0xD2, 0xCC, 0xC5, 0xBF, 0xBF, -0xBA, 0xB7, 0xB6, 0xB1, 0xB7, 0xCB, 0xFA, 0x49, 0x3A, 0x35, 0x31, 0x33, 0x3A, 0x42, 0x4C, 0x5C, -0xFD, 0xE1, 0xEE, 0x68, 0x66, 0x5C, 0x51, 0x4F, 0x4D, 0x55, 0x5F, 0x5D, 0x64, 0x71, 0xFA, 0xED, -0xEF, 0xEB, 0xDE, 0xD3, 0xCC, 0xC3, 0xBE, 0xBD, 0xB9, 0xB8, 0xB5, 0xAF, 0xB7, 0xCC, 0x60, 0x3F, -0x39, 0x34, 0x2F, 0x31, 0x3A, 0x47, 0x56, 0x6F, 0xE3, 0xDA, 0xD5, 0xEC, 0x56, 0x50, 0x4E, 0x4B, -0x4B, 0x4C, 0x57, 0x7B, 0xE7, 0xE0, 0xDC, 0xD5, 0xD6, 0xDE, 0xEC, 0xEF, 0xDE, 0xD7, 0xCC, 0xC1, -0xBD, 0xB8, 0xB5, 0xB4, 0xB0, 0xB6, 0xCB, 0x58, 0x3E, 0x38, 0x34, 0x2F, 0x2F, 0x38, 0x45, 0x59, -0x7D, 0xDD, 0xD1, 0xCE, 0xDD, 0x63, 0x53, 0x4E, 0x4C, 0x4A, 0x4B, 0x53, 0x69, 0xE7, 0xDB, 0xD5, -0xD0, 0xCE, 0xD3, 0xDC, 0xE4, 0xEA, 0xE8, 0xE2, 0xD5, 0xC8, 0xC0, 0xBB, 0xB8, 0xB5, 0xB2, 0xB9, -0xD1, 0x54, 0x40, 0x3A, 0x34, 0x2F, 0x2F, 0x36, 0x3F, 0x4C, 0x5B, 0x7E, 0xDE, 0xD4, 0xDB, 0xFF, -0x62, 0x58, 0x55, 0x53, 0x4F, 0x52, 0x5D, 0x6F, 0xF0, 0xE4, 0xDE, 0xDA, 0xD8, 0xDC, 0xE1, 0xE5, -0xDF, 0xDC, 0xD6, 0xCC, 0xC6, 0xC1, 0xBE, 0xBB, 0xB8, 0xBC, 0xCE, 0x67, 0x4B, 0x44, 0x3E, 0x38, -0x35, 0x37, 0x3D, 0x45, 0x4B, 0x53, 0x61, 0xFA, 0xE4, 0xEC, 0x7F, 0x79, 0x78, 0x79, 0x70, 0x68, -0x68, 0x70, 0x7B, 0x7D, 0x7D, 0xF9, 0xEE, 0xEA, 0xE8, 0xE6, 0xE1, 0xDB, 0xD6, 0xCF, 0xCB, 0xC8, -0xC5, 0xC1, 0xBE, 0xBF, 0xC7, 0xD5, 0xF9, 0x5F, 0x55, 0x4A, 0x42, 0x3E, 0x3E, 0x41, 0x45, 0x48, -0x4C, 0x56, 0x5F, 0x6F, 0xF8, 0xEF, 0xE7, 0xE4, 0xE6, 0xE2, 0xEA, 0xF5, 0xFD, 0x75, 0x75, 0x79, -0x75, 0x76, 0x7E, 0xFA, 0xF1, 0xE9, 0xE0, 0xDA, 0xD3, 0xCF, 0xCC, 0xCA, 0xC7, 0xC4, 0xC5, 0xCC, -0xD3, 0xDF, 0xFF, 0x69, 0x58, 0x4C, 0x47, 0x43, 0x42, 0x42, 0x43, 0x46, 0x4C, 0x55, 0x59, 0x62, -0x77, 0xFD, 0xEE, 0xEC, 0xF3, 0xEC, 0xF2, 0x76, 0x76, 0x6F, 0x6E, 0x79, 0x79, 0x7F, 0xF3, 0xED, -0xE4, 0xDD, 0xDB, 0xD7, 0xD3, 0xD0, 0xCE, 0xCC, 0xCB, 0xCA, 0xCC, 0xD1, 0xD6, 0xDD, 0xEA, 0x7E, -0x62, 0x56, 0x4F, 0x4C, 0x49, 0x48, 0x49, 0x4C, 0x50, 0x56, 0x58, 0x5C, 0x67, 0x6F, 0x6C, 0x6E, -0x6D, 0x6A, 0x6F, 0x6D, 0x6B, 0x6E, 0x6D, 0x76, 0xFA, 0xF9, 0xF1, 0xEB, 0xE7, 0xE1, 0xDE, 0xDD, -0xDB, 0xD8, 0xD7, 0xD4, 0xD2, 0xD0, 0xCF, 0xD4, 0xD8, 0xDA, 0xDF, 0xEA, 0xF8, 0x6D, 0x60, 0x5C, -0x58, 0x56, 0x56, 0x56, 0x57, 0x59, 0x5B, 0x5B, 0x5A, 0x5C, 0x5F, 0x5F, 0x5F, 0x63, 0x66, 0x6B, -0x72, 0x77, 0x7E, 0xF7, 0xF0, 0xEC, 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xEA, 0xE7, 0xE6, 0xE5, -0xE3, 0xE1, 0xDD, 0xDA, 0xD9, 0xD8, 0xDD, 0xDF, 0xDD, 0xE0, 0xE7, 0xEE, 0xFE, 0x74, 0x6C, 0x62, -0x5C, 0x59, 0x56, 0x54, 0x52, 0x51, 0x51, 0x52, 0x55, 0x58, 0x59, 0x5D, 0x62, 0x68, 0x70, 0x75, -0x7D, 0xF9, 0xF8, 0xF4, 0xF5, 0xF9, 0xF5, 0xF3, 0xF3, 0xF2, 0xF2, 0xEF, 0xED, 0xEB, 0xEA, 0xE6, -0xE3, 0xE0, 0xDC, 0xDA, 0xD7, 0xD8, 0xDB, 0xDB, 0xDA, 0xDC, 0xDF, 0xE8, 0xF6, 0x7F, 0x6E, 0x60, -0x5B, 0x58, 0x56, 0x54, 0x53, 0x52, 0x53, 0x59, 0x5C, 0x5E, 0x63, 0x68, 0x6F, 0x7B, 0x7C, 0xFF, -0xFC, 0xFC, 0xFB, 0xFC, 0xFD, 0xF8, 0xF7, 0xF6, 0xF4, 0xF5, 0xF3, 0xF0, 0xEF, 0xED, 0xEB, 0xE8, -0xE4, 0xE0, 0xDD, 0xDA, 0xD9, 0xDA, 0xDC, 0xDC, 0xDC, 0xE0, 0xE9, 0xF8, 0x76, 0x6B, 0x61, 0x5C, -0x5A, 0x5A, 0x5A, 0x5B, 0x5C, 0x5E, 0x62, 0x67, 0x6B, 0x6D, 0x6F, 0x72, 0x75, 0x76, 0x76, 0x75, -0x74, 0x79, 0x7E, 0x7B, 0x78, 0x7D, 0xFB, 0xFB, 0xFD, 0xFA, 0xF6, 0xF5, 0xF2, 0xEF, 0xEC, 0xE9, -0xE4, 0xDF, 0xDE, 0xDE, 0xE0, 0xE7, 0xEA, 0xEC, 0xF2, 0xFE, 0x76, 0x6F, 0x6F, 0x6D, 0x6A, 0x6A, -0x6B, 0x6C, 0x6C, 0x69, 0x67, 0x67, 0x66, 0x65, 0x64, 0x64, 0x65, 0x66, 0x67, 0x69, 0x6B, 0x6E, -0x71, 0x76, 0x7A, 0x7D, 0xFE, 0xFC, 0xFA, 0xF8, 0xF4, 0xF0, 0xEE, 0xEC, 0xEA, 0xE9, 0xE8, 0xE9, -0xEB, 0xEB, 0xEC, 0xED, 0xEE, 0xED, 0xEB, 0xE9, 0xEA, 0xE9, 0xE9, 0xEA, 0xEC, 0xF0, 0xF6, 0xFD, -0x78, 0x71, 0x6D, 0x69, 0x67, 0x66, 0x65, 0x65, 0x66, 0x67, 0x66, 0x66, 0x67, 0x67, 0x66, 0x66, -0x69, 0x6B, 0x6D, 0x73, 0x7A, 0xFE, 0xF7, 0xF3, 0xEF, 0xEE, 0xEE, 0xEC, 0xEB, 0xEA, 0xE8, 0xE7, -0xE5, 0xE3, 0xE1, 0xE1, 0xE1, 0xE3, 0xE6, 0xE8, 0xEB, 0xEF, 0xF8, 0x7E, 0x75, 0x6F, 0x6B, 0x69, -0x67, 0x66, 0x65, 0x65, 0x66, 0x67, 0x67, 0x68, 0x68, 0x69, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, -0x70, 0x6F, 0x6F, 0x6F, 0x72, 0x75, 0x79, 0xFF, 0xFB, 0xF6, 0xF2, 0xEF, 0xEE, 0xED, 0xEE, 0xF0, -0xF3, 0xF6, 0xF8, 0xFC, 0xFF, 0x7D, 0x79, 0x76, 0x72, 0x6E, 0x6D, 0x6B, 0x6B, 0x6C, 0x6C, 0x6D, -0x6E, 0x71, 0x76, 0x7B, 0xFF, 0xFE, 0xFD, 0xFC, 0xFD, 0x7F, 0x7B, 0x78, 0x75, 0x74, 0x75, 0x77, -0x7A, 0x7E, 0xFC, 0xF9, 0xF6, 0xF5, 0xF4, 0xF4, 0xF5, 0xF7, 0xF8, 0xF8, 0xF7, 0xF6, 0xF5, 0xF5, -0xF6, 0xF8, 0xFA, 0xFC, 0x7F, 0x7B, 0x79, 0x78, 0x77, 0x77, 0x79, 0x7D, 0xFD, 0xF9, 0xF4, 0xF2, -0xF1, 0xF1, 0xF3, 0xF5, 0xFA, 0xFE, 0x7F, 0xFF, 0xFD, 0xFC, 0xFB, 0xF7, 0xF5, 0xF4, 0xF4, 0xF6, -0xF8, 0xFB, 0xFD, 0xFF, 0x7E, 0x7E, 0x7E, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7E, 0x7B, 0x79, 0x77, -0x76, 0x75, 0x74, 0x74, 0x75, 0x78, 0x7C, 0x7F, 0xFE, 0xFD, 0xFE, 0xFF, 0x7E, 0x7C, 0x7B, 0x79, -0x79, 0x7A, 0x7D, 0xFE, 0xFC, 0xFA, 0xF8, 0xF8, 0xF9, 0xFB, 0xFD, 0x7F, 0x7B, 0x78, 0x76, 0x75, -0x74, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x75, 0x76, 0x76, 0x77, 0x7A, 0x7C, -0x7E, 0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7C, 0x7A, 0x78, 0x77, 0x77, 0x76, 0x79, 0x7B, 0x7E, 0xFF, -0xFE, 0xFD, 0xFD, 0xFF, 0x7E, 0x7C, 0x7C, 0x7B, 0x79, 0x78, 0x78, 0x78, 0x77, 0x75, 0x74, 0x74, -0x74, 0x74, 0x75, 0x76, 0x79, 0x7C, 0x7E, 0xFF, 0xFC, 0xF8, 0xF7, 0xF6, 0xF7, 0xF7, 0xF7, 0xF9, -0xFC, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7F, 0xFF, 0xFC, 0xFB, 0xFA, 0xF8, 0xF8, 0xF8, 0xF6, 0xF5, -0xF5, 0xF4, 0xF4, 0xF5, 0xF7, 0xF8, 0xFA, 0xFD, 0x7F, 0x7E, 0x7D, 0x7C, 0x7C, 0x7D, 0x7E, 0xFE, -0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF9, 0xF9, 0xFA, 0xFB, 0xFD, 0xFF, 0x7E, 0x7D, 0x79, 0x77, 0x75, -0x72, 0x71, 0x70, 0x70, 0x70, 0x71, 0x71, 0x70, 0x71, 0x72, 0x71, 0x72, 0x71, 0x72, 0x73, 0x72, -0x72, 0x71, 0x71, 0x71, 0x72, 0x74, 0x74, 0x76, 0x77, 0x77, 0x77, 0x78, 0x77, 0x78, 0x78, 0x78, -0x7A, 0x7C, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFD, 0xFF, 0x7E, 0x7D, 0x7B, 0x7C, 0x7B, -0x7B, 0x7B, 0x7B, 0x7B, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7B, 0x7C, 0x7E, 0xFF, 0xFD, -0xFB, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0xFF, 0x7F, 0x7D, 0x7C, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7D, -0x7F, 0x7F, 0xFF, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, -0xFF, 0xFF, 0xFF, 0xFD, 0xFA, 0xF9, 0xF7, 0xF5, 0xF4, 0xF3, 0xF1, 0xF1, 0xF1, 0xF1, 0xF2, 0xF2, -0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xFA, 0xFC, 0xFE, 0xFE, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, -0x7F, 0x7D, 0x7C, 0x7D, 0x7B, 0x7A, 0x7D, 0x7B, 0x7B, 0x7C, 0x7B, 0x7B, 0x7B, 0x79, 0x78, 0x77, -0x77, 0x76, 0x75, 0x76, 0x75, 0x74, 0x74, 0x75, 0x74, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73, 0x74, -0x72, 0x70, 0x70, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x70, 0x70, 0x70, 0x71, 0x72, 0x73, 0x73, 0x76, -0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7B, 0x7D, 0x7E, 0x7D, 0x7F, 0x7D, 0x7C, 0x7B, 0x7B, 0x7C, -0x7B, 0x7B, 0x7A, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0xFF, 0x7D, 0x7E, 0x7C, 0x7C, 0x7B, 0x78, -0x7C, 0x7A, 0x7C, 0x7D, 0x7B, 0x7E, 0x7C, 0x7F, 0x7D, 0x7A, 0x7E, 0x78, 0x7B, 0x6F, 0x68, 0x5C, -0x4C, 0x58, 0xDD, 0xE1, 0xEB, 0xE1, 0xE9, 0xEF, 0xF8, 0xE9, 0xE1, 0xED, 0xF9, 0xFC, 0xF2, 0xED, -0x7D, 0x76, 0xFB, 0xF9, 0x7C, 0x70, 0x6F, 0x78, 0x79, 0x6D, 0x6D, 0x76, 0x7D, 0xFE, 0x7A, 0x79, -0xFC, 0xFD, 0xFD, 0xFA, 0xFB, 0xFA, 0xFC, 0xFF, 0xFC, 0xFC, 0xFE, 0xFD, 0xFE, 0xFB, 0xFB, 0xFE, -0xFE, 0x7E, 0x7D, 0x7C, 0x7C, 0x7B, 0x78, 0x7D, 0x7D, 0xFF, 0xFA, 0xFF, 0xF9, 0xF9, 0xFA, 0xF7, -0x7F, 0xF9, 0x7A, 0x7A, 0x6F, 0x51, 0x52, 0x6E, 0x71, 0xF1, 0xD8, 0xD3, 0xDB, 0xEF, 0xE2, 0xDB, -0xED, 0xF6, 0xF3, 0xEF, 0xF4, 0x6A, 0x74, 0x73, 0x57, 0x5E, 0x77, 0x6E, 0xFD, 0xF4, 0xFC, 0x7D, -0x73, 0xE9, 0xDE, 0xE2, 0xDE, 0xE3, 0xE5, 0xE8, 0xFA, 0xF7, 0xFA, 0x6F, 0x6C, 0x6A, 0x6B, 0x6A, -0x66, 0x6B, 0x75, 0x70, 0x74, 0xFA, 0xFB, 0xFD, 0xF8, 0xF3, 0xF2, 0xFB, 0xF5, 0xED, 0xEF, 0xEB, -0xE5, 0xDF, 0xDA, 0xD7, 0xD5, 0xD3, 0xD3, 0xD4, 0xD8, 0xE0, 0xEE, 0x76, 0x5D, 0x53, 0x4D, 0x49, -0x46, 0x43, 0x42, 0x43, 0x43, 0x45, 0x48, 0x4B, 0x4F, 0x57, 0x60, 0x6D, 0xF7, 0xE3, 0xDB, 0xD4, -0xCF, 0xCB, 0xC8, 0xC4, 0xBE, 0xBC, 0xB9, 0xB4, 0xB6, 0xBC, 0xC1, 0xC3, 0xD5, 0x4F, 0x4B, 0x43, -0x36, 0x33, 0x34, 0x32, 0x31, 0x36, 0x3B, 0x3F, 0x48, 0x60, 0xDF, 0xD2, 0xC9, 0xC1, 0xC3, 0xC6, -0xC7, 0xCF, 0xE3, 0x67, 0x56, 0x47, 0x3E, 0x3F, 0x3C, 0x3B, 0x43, 0x48, 0x4F, 0xFA, 0xD5, 0xC5, -0xBD, 0xB7, 0xB1, 0xAE, 0xAC, 0xAE, 0xB1, 0xB5, 0xC0, 0xD7, 0x5D, 0x40, 0x38, 0x31, 0x2E, 0x2D, -0x2C, 0x2E, 0x32, 0x37, 0x3F, 0x4F, 0xF8, 0xD0, 0xC4, 0xBC, 0xBB, 0xBB, 0xBB, 0xBE, 0xC7, 0xD0, -0xF1, 0x56, 0x48, 0x40, 0x3D, 0x3B, 0x3D, 0x42, 0x49, 0x63, 0xDA, 0xCB, 0xBC, 0xB6, 0xB0, 0xAE, -0xAF, 0xAF, 0xB4, 0xBC, 0xC6, 0xFE, 0x4C, 0x3E, 0x34, 0x30, 0x2E, 0x2D, 0x2E, 0x30, 0x35, 0x3C, -0x46, 0x62, 0xDE, 0xCA, 0xBE, 0xBD, 0xBB, 0xBA, 0xBD, 0xC3, 0xCB, 0xDC, 0x6B, 0x59, 0x51, 0x52, -0x60, 0xFF, 0xD5, 0xC4, 0xBE, 0xBC, 0xBA, 0xB9, 0xBB, 0xC3, 0xC8, 0xD6, 0x5A, 0x4C, 0x42, 0x39, -0x36, 0x35, 0x32, 0x34, 0x36, 0x39, 0x41, 0x47, 0x58, 0xE0, 0xDA, 0xC9, 0xC1, 0xC4, 0xC0, 0xC0, -0xC6, 0xCA, 0xD1, 0xDC, 0xF3, 0x6E, 0xFC, 0xE8, 0xDB, 0xCB, 0xC2, 0xBE, 0xBD, 0xBE, 0xBD, 0xC0, -0xCD, 0xCE, 0xEC, 0x4E, 0x4C, 0x40, 0x38, 0x39, 0x37, 0x35, 0x38, 0x38, 0x3B, 0x43, 0x49, 0x54, -0xEA, 0xDB, 0xCE, 0xC5, 0xC5, 0xC3, 0xC1, 0xC7, 0xCA, 0xCF, 0xDB, 0xE9, 0xFD, 0xF7, 0xE9, 0xDD, -0xCE, 0xC6, 0xC1, 0xBF, 0xC0, 0xBF, 0xC3, 0xCF, 0xD0, 0xE6, 0x51, 0x4E, 0x43, 0x3A, 0x3B, 0x38, -0x35, 0x38, 0x38, 0x3A, 0x3F, 0x44, 0x4E, 0x5F, 0xEF, 0xD7, 0xCD, 0xC8, 0xC6, 0xC4, 0xC6, 0xC9, -0xCC, 0xD4, 0xDD, 0xE6, 0xE1, 0xDA, 0xD7, 0xCA, 0xC3, 0xC4, 0xC4, 0xC1, 0xC3, 0xCC, 0xCF, 0xD8, -0x60, 0x54, 0x4E, 0x3F, 0x3D, 0x3D, 0x39, 0x3A, 0x3C, 0x3B, 0x3D, 0x47, 0x48, 0x51, 0x79, 0xFA, -0xDD, 0xCD, 0xCF, 0xCC, 0xC8, 0xCD, 0xCE, 0xCE, 0xD7, 0xDC, 0xDC, 0xD7, 0xD4, 0xCC, 0xC3, 0xC1, -0xBF, 0xBF, 0xC2, 0xC1, 0xCE, 0xDB, 0xDD, 0x54, 0x4C, 0x49, 0x3C, 0x3B, 0x3B, 0x38, 0x3A, 0x3B, -0x3C, 0x3E, 0x48, 0x4C, 0x55, 0xF3, 0xEC, 0xDB, 0xCD, 0xD1, 0xCD, 0xCB, 0xD2, 0xD1, 0xD6, 0xDD, -0xE1, 0xE2, 0xD7, 0xD3, 0xCA, 0xC0, 0xBE, 0xBE, 0xBF, 0xBE, 0xC1, 0xCF, 0xD0, 0xED, 0x4E, 0x4D, -0x41, 0x3A, 0x3A, 0x37, 0x35, 0x38, 0x3A, 0x3A, 0x3F, 0x49, 0x4A, 0x62, 0xE7, 0xEA, 0xCE, 0xCB, -0xCF, 0xC8, 0xCB, 0xD1, 0xCF, 0xD7, 0xE2, 0xE5, 0xE5, 0xDF, 0xD5, 0xCC, 0xC5, 0xBE, 0xBE, 0xC0, -0xBC, 0xC0, 0xCD, 0xC8, 0xDC, 0x58, 0x5B, 0x47, 0x3C, 0x3D, 0x39, 0x36, 0x39, 0x3A, 0x39, 0x3E, -0x47, 0x49, 0x59, 0xEA, 0xEC, 0xD0, 0xC9, 0xCD, 0xC7, 0xC8, 0xCE, 0xCD, 0xD2, 0xDC, 0xDF, 0xDF, -0xDD, 0xD6, 0xCB, 0xC6, 0xBF, 0xBF, 0xC4, 0xBD, 0xC4, 0xD1, 0xC9, 0xEF, 0x55, 0x5D, 0x43, 0x3D, -0x3E, 0x38, 0x37, 0x3A, 0x3A, 0x3A, 0x3E, 0x45, 0x48, 0x56, 0x74, 0xF8, 0xD8, 0xCF, 0xD0, 0xCB, -0xCB, 0xCE, 0xCE, 0xD2, 0xD9, 0xDC, 0xDC, 0xD7, 0xD3, 0xCA, 0xC4, 0xC0, 0xBF, 0xC2, 0xBE, 0xC3, -0xCF, 0xCB, 0xE5, 0x58, 0x5C, 0x45, 0x3D, 0x3E, 0x39, 0x37, 0x39, 0x3A, 0x3A, 0x3D, 0x45, 0x46, -0x52, 0x79, 0x73, 0xD7, 0xCD, 0xD1, 0xC8, 0xC8, 0xCD, 0xCA, 0xCF, 0xD5, 0xD7, 0xDC, 0xDA, 0xD4, -0xCD, 0xC7, 0xC1, 0xC0, 0xC5, 0xBF, 0xC2, 0xD1, 0xCA, 0xDA, 0x5A, 0x68, 0x4C, 0x3E, 0x42, 0x3B, -0x38, 0x3B, 0x3A, 0x3A, 0x3D, 0x42, 0x44, 0x4B, 0x62, 0x66, 0xF1, 0xD0, 0xD6, 0xCD, 0xC8, 0xCE, -0xCA, 0xCB, 0xD1, 0xCF, 0xD2, 0xD2, 0xCE, 0xC9, 0xC5, 0xC1, 0xBF, 0xC5, 0xC1, 0xC0, 0xD3, 0xCE, -0xD6, 0x57, 0x5F, 0x4E, 0x3E, 0x41, 0x3D, 0x39, 0x3B, 0x3B, 0x3A, 0x3D, 0x42, 0x44, 0x4C, 0x5A, -0x5E, 0xEC, 0xDD, 0xDC, 0xCE, 0xD0, 0xD1, 0xCD, 0xD4, 0xD4, 0xD4, 0xDA, 0xD3, 0xCE, 0xCB, 0xC4, -0xBF, 0xBE, 0xC2, 0xBE, 0xBF, 0xCD, 0xCB, 0xD5, 0x5B, 0x5F, 0x4D, 0x3E, 0x3F, 0x3B, 0x37, 0x39, -0x3A, 0x39, 0x3C, 0x3F, 0x42, 0x4B, 0x59, 0x61, 0xEA, 0xDA, 0xD6, 0xCD, 0xCD, 0xCE, 0xCD, 0xCF, -0xD3, 0xD6, 0xDA, 0xD7, 0xD2, 0xCE, 0xC7, 0xC2, 0xBF, 0xC0, 0xC1, 0xBE, 0xC8, 0xCE, 0xCB, 0x79, -0x5A, 0x5C, 0x41, 0x3F, 0x3E, 0x38, 0x39, 0x3A, 0x39, 0x3A, 0x3E, 0x42, 0x45, 0x51, 0x62, 0x65, -0xDD, 0xD5, 0xD7, 0xCA, 0xCC, 0xCE, 0xCA, 0xCE, 0xD0, 0xCF, 0xCF, 0xCD, 0xC9, 0xC4, 0xBF, 0xBD, -0xBE, 0xBF, 0xBD, 0xC5, 0xCE, 0xCB, 0xF8, 0x58, 0x5B, 0x43, 0x3E, 0x3E, 0x39, 0x38, 0x3A, 0x39, -0x3A, 0x3E, 0x44, 0x45, 0x51, 0x6E, 0x69, 0xDC, 0xCF, 0xD7, 0xCA, 0xCB, 0xD0, 0xCC, 0xD1, 0xD5, -0xD5, 0xD5, 0xCF, 0xCB, 0xC5, 0xBF, 0xBC, 0xBD, 0xBF, 0xBB, 0xC3, 0xCC, 0xC8, 0xEF, 0x5B, 0x5D, -0x41, 0x3D, 0x3D, 0x37, 0x37, 0x38, 0x37, 0x38, 0x3B, 0x41, 0x43, 0x4E, 0x6B, 0x67, 0xDC, 0xCE, -0xD4, 0xC9, 0xC8, 0xCE, 0xCA, 0xCE, 0xD5, 0xD4, 0xD5, 0xD3, 0xCE, 0xC7, 0xC3, 0xBE, 0xBE, 0xC3, -0xBD, 0xC2, 0xD0, 0xC9, 0xDE, 0x57, 0x61, 0x47, 0x3D, 0x3F, 0x39, 0x36, 0x38, 0x38, 0x38, 0x3A, -0x41, 0x40, 0x48, 0x6A, 0x5C, 0xF7, 0xCD, 0xDB, 0xCD, 0xC6, 0xD1, 0xCC, 0xCC, 0xD6, 0xD5, 0xD3, -0xCF, 0xCE, 0xC6, 0xC0, 0xBF, 0xBE, 0xBF, 0xBE, 0xC0, 0xCC, 0xCB, 0xDB, 0x5D, 0x5B, 0x49, 0x3E, -0x3E, 0x39, 0x37, 0x38, 0x38, 0x38, 0x3B, 0x40, 0x42, 0x4A, 0x63, 0x66, 0xE5, 0xCE, 0xD0, 0xCA, -0xC7, 0xCA, 0xCA, 0xCC, 0xCE, 0xD1, 0xCF, 0xCC, 0xCC, 0xC4, 0xBF, 0xBF, 0xBE, 0xC0, 0xBE, 0xC2, -0xCE, 0xCC, 0xE2, 0x58, 0x59, 0x47, 0x3D, 0x3D, 0x39, 0x37, 0x39, 0x39, 0x39, 0x3C, 0x40, 0x44, -0x4D, 0x5D, 0x6F, 0xE0, 0xD4, 0xCF, 0xCC, 0xCB, 0xCB, 0xCD, 0xCF, 0xCF, 0xD4, 0xD1, 0xCC, 0xCA, -0xC4, 0xBF, 0xBD, 0xBF, 0xBF, 0xBE, 0xC7, 0xCF, 0xCE, 0x79, 0x52, 0x51, 0x41, 0x3C, 0x3B, 0x38, -0x36, 0x38, 0x39, 0x38, 0x3D, 0x44, 0x44, 0x55, 0x70, 0x76, 0xD5, 0xCF, 0xCF, 0xC9, 0xCB, 0xCB, -0xCD, 0xD1, 0xD1, 0xD9, 0xD2, 0xCD, 0xCD, 0xC4, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xC9, 0xCF, 0xD0, -0x6A, 0x53, 0x4F, 0x3F, 0x3C, 0x3B, 0x38, 0x37, 0x38, 0x39, 0x3A, 0x3E, 0x44, 0x4A, 0x56, 0x75, -0xE7, 0xD7, 0xCD, 0xCB, 0xCA, 0xC9, 0xCA, 0xCD, 0xCE, 0xCF, 0xD3, 0xCE, 0xCA, 0xC7, 0xC0, 0xBE, -0xBE, 0xBF, 0xBF, 0xC1, 0xCD, 0xD2, 0xDB, 0x5C, 0x4F, 0x4A, 0x3E, 0x3C, 0x3B, 0x39, 0x38, 0x3A, -0x3A, 0x3C, 0x43, 0x46, 0x4E, 0x71, 0x7A, 0xDD, 0xCE, 0xD0, 0xCB, 0xCA, 0xCD, 0xCC, 0xD1, 0xD2, -0xD5, 0xD7, 0xCC, 0xCC, 0xC7, 0xBE, 0xBF, 0xBF, 0xBE, 0xC0, 0xC6, 0xCD, 0xD5, 0xEE, 0x54, 0x4D, -0x45, 0x3C, 0x3B, 0x39, 0x37, 0x38, 0x39, 0x3A, 0x3E, 0x44, 0x4A, 0x59, 0x71, 0xE8, 0xD4, 0xCE, -0xCC, 0xC9, 0xCB, 0xCB, 0xCE, 0xD2, 0xD4, 0xD7, 0xD2, 0xCD, 0xCB, 0xC4, 0xBF, 0xBF, 0xC0, 0xC0, -0xC0, 0xC9, 0xD1, 0xD8, 0x73, 0x52, 0x4B, 0x42, 0x3C, 0x3A, 0x39, 0x38, 0x38, 0x39, 0x3C, 0x3F, -0x41, 0x4E, 0x5D, 0x63, 0xDF, 0xD3, 0xD1, 0xCD, 0xCB, 0xCC, 0xD1, 0xD1, 0xD3, 0xDE, 0xDA, 0xD1, -0xCF, 0xCC, 0xC4, 0xBF, 0xC2, 0xC2, 0xBF, 0xC6, 0xCD, 0xD2, 0xE3, 0x63, 0x4F, 0x4A, 0x42, 0x3C, -0x3B, 0x3A, 0x39, 0x3A, 0x3B, 0x3F, 0x42, 0x47, 0x5A, 0x62, 0x7C, 0xD5, 0xD2, 0xCF, 0xCC, 0xCD, -0xCE, 0xD5, 0xD6, 0xD9, 0xE0, 0xD9, 0xD2, 0xCE, 0xCB, 0xC4, 0xBF, 0xC2, 0xC2, 0xBF, 0xC6, 0xCD, -0xD4, 0xE2, 0x67, 0x4F, 0x4B, 0x43, 0x3D, 0x3C, 0x3B, 0x3B, 0x3B, 0x3C, 0x42, 0x43, 0x49, 0x60, -0x6B, 0xF5, 0xD4, 0xD2, 0xD0, 0xD2, 0xD2, 0xD4, 0xDF, 0xDD, 0xDF, 0xEA, 0xDC, 0xD5, 0xD0, 0xCB, -0xC4, 0xC0, 0xC2, 0xBF, 0xC0, 0xC7, 0xC9, 0xD0, 0xDD, 0x7A, 0x57, 0x52, 0x48, 0x3F, 0x3F, 0x3D, -0x3C, 0x3C, 0x3D, 0x42, 0x44, 0x49, 0x5B, 0x64, 0x7C, 0xDE, 0xDB, 0xDB, 0xDC, 0xDA, 0xDF, 0xEE, -0xE9, 0xE6, 0xE8, 0xE3, 0xDB, 0xD0, 0xCD, 0xCC, 0xC5, 0xC3, 0xC5, 0xC2, 0xC3, 0xC8, 0xCD, 0xD1, -0xDE, 0x6F, 0x5B, 0x50, 0x4A, 0x44, 0x40, 0x3F, 0x3E, 0x3E, 0x42, 0x43, 0x47, 0x4F, 0x58, 0x5F, -0x69, 0xF6, 0xED, 0xF7, 0xEB, 0xE8, 0xEA, 0xEC, 0xE8, 0xE0, 0xE0, 0xDD, 0xD7, 0xD0, 0xCE, 0xCC, -0xC8, 0xC7, 0xC6, 0xC4, 0xC8, 0xC9, 0xCB, 0xD2, 0xDA, 0xEF, 0x71, 0x5B, 0x4F, 0x4E, 0x49, 0x45, -0x46, 0x45, 0x47, 0x47, 0x4A, 0x4E, 0x4E, 0x54, 0x5A, 0x5D, 0x62, 0x65, 0x70, 0x6C, 0x69, 0xFA, -0x7A, 0x7A, 0xE6, 0xE2, 0xDF, 0xDA, 0xD5, 0xCF, 0xD1, 0xD1, 0xCB, 0xCE, 0xD4, 0xCE, 0xD1, 0xD9, -0xDB, 0xE0, 0xE1, 0xEE, 0x6A, 0x74, 0x6C, 0x5A, 0x5B, 0x5A, 0x56, 0x56, 0x53, 0x56, 0x57, 0x53, -0x57, 0x5B, 0x59, 0x59, 0x5D, 0x65, 0x60, 0x61, 0x6F, 0x73, 0xF7, 0xEF, 0xEA, 0xDD, 0xDF, 0xDC, -0xD5, 0xD8, 0xDC, 0xDC, 0xDA, 0xDF, 0xE5, 0xE1, 0xEB, 0xED, 0xED, 0xFC, 0xFF, 0x70, 0x6C, 0x6C, -0x66, 0x5F, 0x5F, 0x62, 0x5F, 0x60, 0x60, 0x5A, 0x5F, 0x64, 0x5C, 0x64, 0x6E, 0x5F, 0x5E, 0x69, -0x6B, 0x7B, 0xF0, 0xFA, 0xE9, 0xE4, 0xE8, 0xDF, 0xE6, 0xEB, 0xE1, 0xE2, 0xE6, 0xE3, 0xE8, 0xED, -0xE5, 0xFC, 0x71, 0xE9, 0xFE, 0x7A, 0xEC, 0x73, 0x7E, 0x77, 0x64, 0xFD, 0x74, 0x66, 0x7B, 0x6C, -0x6B, 0x72, 0x6A, 0x79, 0x73, 0x71, 0xF4, 0x79, 0xFC, 0xEF, 0xF9, 0xEB, 0xF1, 0xF0, 0xE2, 0xE3, -0xE0, 0xE2, 0xE3, 0xEB, 0xFC, 0xEA, 0xF8, 0x6F, 0x70, 0x69, 0x77, 0x6C, 0x6D, 0xEF, 0x6B, 0x67, -0x6D, 0x65, 0x76, 0x75, 0x6F, 0x7E, 0x69, 0x67, 0x6F, 0x68, 0x6F, 0x73, 0x68, 0x69, 0x68, 0x69, -0x75, 0xFA, 0xEE, 0xF2, 0xEA, 0xDE, 0xE2, 0xE7, 0xE5, 0xEB, 0xF3, 0xED, 0xE8, 0xF7, 0x7F, 0xFA, -0x74, 0x6A, 0x68, 0x65, 0x66, 0x68, 0x64, 0x65, 0x68, 0x64, 0x6D, 0x77, 0x72, 0x70, 0x69, 0x77, -0x78, 0x64, 0x6B, 0x68, 0x60, 0x66, 0x67, 0x67, 0x61, 0x6D, 0xEB, 0xE8, 0xEC, 0xEB, 0xEA, 0xF7, -0xF5, 0xE2, 0xE5, 0xF6, 0xF8, 0xF0, 0x7E, 0x77, 0xFA, 0x76, 0x77, 0x7D, 0x6E, 0x74, 0x74, 0x72, -0x72, 0x6D, 0x75, 0x74, 0x74, 0x75, 0x76, 0xEF, 0xEE, 0xEF, 0xEA, 0xFA, 0x7F, 0xF2, 0xF6, 0xF7, -0xEF, 0xEA, 0xE4, 0xE5, 0xE7, 0xE3, 0xE9, 0xEC, 0xE8, 0xEB, 0xF0, 0xF8, 0xFC, 0x7F, 0x73, 0x73, -0x70, 0x72, 0x75, 0x69, 0x67, 0x6A, 0x6C, 0x6D, 0x6C, 0x70, 0x6D, 0x6D, 0x78, 0x72, 0x6F, 0x6E, -0x6C, 0x6F, 0x77, 0xF7, 0xEF, 0xF1, 0xF6, 0xF4, 0xF1, 0xFC, 0xF8, 0xEE, 0xF0, 0xEE, 0xEF, 0xEF, -0xEC, 0xEE, 0xF3, 0xF4, 0x76, 0x69, 0x77, 0xFA, 0x70, 0x75, 0x7E, 0x6E, 0x6D, 0x6E, 0x6E, 0x6E, -0x6D, 0x70, 0x74, 0x79, 0xFE, 0x7D, 0x78, 0x7C, 0x7A, 0x75, 0x78, 0x75, 0x70, 0x7C, 0xFC, 0xFB, -0xF4, 0xF3, 0xED, 0xEC, 0xF6, 0xF1, 0xEF, 0xF6, 0xF0, 0xFB, 0x7A, 0x7C, 0x74, 0x79, 0x74, 0x6C, -0x6C, 0x63, 0x67, 0x6C, 0x62, 0x66, 0x67, 0x68, 0x6C, 0x6A, 0x7D, 0x78, 0x6B, 0x7B, 0x71, 0x75, -0xFB, 0x75, 0x76, 0x7E, 0xEE, 0xED, 0xFA, 0xE8, 0xEE, 0x7F, 0xE4, 0xE9, 0xED, 0xE1, 0xEC, 0xEE, -0xE6, 0xF6, 0xFE, 0xF7, 0xFF, 0x7B, 0x72, 0x7C, 0x7F, 0x6B, 0x6C, 0x66, 0x67, 0x71, 0x66, 0x72, -0xFF, 0x69, 0x7B, 0xF7, 0xFF, 0xF3, 0xF6, 0xF3, 0xF2, 0xEE, 0xED, 0xFF, 0xF6, 0xED, 0xFB, 0xF2, -0xE9, 0xF0, 0xEC, 0xE6, 0xF4, 0xF2, 0xF5, 0x7C, 0xED, 0x7E, 0x6B, 0x7B, 0x77, 0xFE, 0x7A, 0x69, -0x68, 0x60, 0x65, 0x66, 0x61, 0x71, 0x74, 0x74, 0xFC, 0x7E, 0xFA, 0xFF, 0x7E, 0xF9, 0xFB, 0xEE, -0xED, 0xEF, 0xEF, 0xF4, 0xEC, 0xEC, 0xF2, 0xF0, 0xEF, 0xED, 0xF4, 0xF6, 0xEF, 0xFD, 0xF8, 0xF1, -0x77, 0x74, 0x7A, 0x70, 0x6F, 0x79, 0x76, 0x6A, 0x68, 0x6C, 0x6C, 0x69, 0x65, 0x66, 0x6E, 0x73, -0x6C, 0x6D, 0x7A, 0x79, 0x7A, 0xFE, 0x73, 0x72, 0x7A, 0x7E, 0xF3, 0xEF, 0xEE, 0xF1, 0xF6, 0xEC, -0xEF, 0xFA, 0xEE, 0xF5, 0xFE, 0xF2, 0xF0, 0xF7, 0xFA, 0xF9, 0xFB, 0xFB, 0x7A, 0x6B, 0x6B, 0x72, -0x6C, 0x6A, 0x76, 0x74, 0x6E, 0x72, 0x6C, 0x6B, 0x6F, 0x6B, 0x6E, 0x71, 0x6D, 0x75, 0x76, 0x70, -0x78, 0x7C, 0xFA, 0xF2, 0xF7, 0xF1, 0xED, 0xF3, 0xF4, 0xF6, 0xFA, 0xF0, 0xEF, 0xFD, 0x7B, 0xFF, -0x78, 0x6C, 0x70, 0x72, 0x6E, 0x73, 0x6D, 0x6D, 0x6D, 0x65, 0x65, 0x69, 0x6F, 0x70, 0x6B, 0x6E, -0x71, 0x6E, 0x6E, 0x6F, 0x7A, 0x7D, 0x7E, 0xEF, 0xF4, 0x7D, 0xFB, 0xF3, 0xEC, 0xEB, 0xF0, 0xEF, -0xEE, 0xEE, 0xF3, 0xF0, 0xED, 0xFF, 0xFF, 0xF3, 0x7E, 0xFB, 0xFF, 0x73, 0x7E, 0x7A, 0x76, 0x6F, -0x6C, 0x7A, 0x74, 0x6F, 0xFF, 0x7B, 0x79, 0xF7, 0xF5, 0xFB, 0xF6, 0xF3, 0x7E, 0x7D, 0xFA, 0xFD, -0xF6, 0xF5, 0x7D, 0x7B, 0x7A, 0xFF, 0xFB, 0x7D, 0x75, 0x76, 0xF3, 0xF3, 0x78, 0xFE, 0x76, 0x6B, -0x7B, 0xFB, 0x75, 0x69, 0x6C, 0xF6, 0xF6, 0x7B, 0x6F, 0x69, 0x6E, 0x72, 0x70, 0x74, 0x78, 0xFF, -0x7F, 0xFD, 0xF5, 0xF8, 0xF5, 0xF9, 0x75, 0x74, 0x7D, 0xF7, 0xFB, 0x70, 0x7E, 0xE9, 0xEF, 0xF7, -0xE6, 0xED, 0x74, 0x7A, 0xF7, 0x7D, 0x71, 0x77, 0xFE, 0xF6, 0xFC, 0x6B, 0x6B, 0x72, 0x69, 0x6D, -0x7B, 0x7C, 0xFD, 0x6F, 0x6B, 0xFC, 0x7F, 0x73, 0xF9, 0xF5, 0x70, 0x6E, 0xFD, 0xFF, 0x7C, 0xFB, -0x70, 0x76, 0xEF, 0x7D, 0x75, 0xFB, 0xF6, 0xEF, 0xF6, 0x7C, 0x79, 0x76, 0xFE, 0x7D, 0x73, 0xFD, -0xFE, 0x76, 0x6E, 0x66, 0x6B, 0x75, 0x6D, 0x7D, 0xF2, 0x6D, 0x75, 0xED, 0x7A, 0x6D, 0x7E, 0xF9, -0xFE, 0x6E, 0x78, 0xF4, 0x6E, 0x73, 0xF8, 0x74, 0xFF, 0xFE, 0x77, 0xF6, 0x7C, 0x71, 0x7F, 0x7E, -0x7E, 0x79, 0x78, 0x7C, 0x6E, 0x6F, 0x70, 0x6D, 0xFD, 0xFA, 0x6C, 0x6B, 0x71, 0x70, 0x7B, 0x7A, -0x7C, 0xFD, 0x6D, 0x75, 0xED, 0xF8, 0xFC, 0xF7, 0xFB, 0xEE, 0xEF, 0x79, 0xFF, 0xED, 0xF8, 0x7A, -0xF1, 0xED, 0xF7, 0xFC, 0xF8, 0xF1, 0xF8, 0x79, 0x7D, 0xF6, 0x78, 0x6E, 0xFD, 0xFB, 0x72, 0x6E, -0x6C, 0x74, 0xFE, 0xFF, 0xF7, 0xFE, 0x6D, 0x75, 0x79, 0x6F, 0x7C, 0x7D, 0x76, 0x78, 0x7A, 0x7F, -0x75, 0x7D, 0xF7, 0xF8, 0xEF, 0x7B, 0x7A, 0xF3, 0xFF, 0xEF, 0xF8, 0xFE, 0xF6, 0x6E, 0xF4, 0xED, -0x6F, 0x7C, 0x74, 0x75, 0xF2, 0x7C, 0x75, 0xF9, 0xEE, 0xFF, 0x70, 0x7C, 0x7F, 0xFD, 0xFD, 0xFA, -0x79, 0x6C, 0x7C, 0x7F, 0xFD, 0xF3, 0x78, 0xFE, 0xF7, 0xFC, 0xED, 0xF1, 0xFD, 0xFE, 0x7D, 0xF4, -0xED, 0xF4, 0xFA, 0xFD, 0x70, 0x73, 0xF6, 0xFF, 0x7D, 0xF7, 0x79, 0x72, 0x78, 0x7D, 0x77, 0x6E, -0x71, 0x6C, 0x6A, 0x7D, 0x74, 0x71, 0x7D, 0x6E, 0x79, 0xF8, 0x70, 0x7C, 0xFE, 0x6D, 0x6F, 0x6E, -0x6D, 0x7D, 0xFD, 0xFB, 0xFA, 0x7C, 0xFD, 0xFA, 0xF7, 0xF4, 0xFD, 0x7B, 0x76, 0x7D, 0xF3, 0xF5, -0xFD, 0xF5, 0xED, 0x7A, 0x6D, 0xF5, 0x7C, 0x76, 0xEF, 0x77, 0x6E, 0xFF, 0x74, 0x79, 0xFD, 0x76, -0x7A, 0x7E, 0x7B, 0x7D, 0x78, 0x73, 0x7A, 0xFB, 0xFB, 0x7E, 0xFB, 0xF2, 0xF8, 0xF9, 0xFB, 0xFE, -0xF5, 0xF6, 0xF9, 0x7E, 0x73, 0xF7, 0xFA, 0x74, 0xFC, 0x7B, 0x70, 0xFF, 0xFC, 0x7E, 0x7C, 0xFE, -0xFF, 0x7C, 0xFC, 0x7E, 0x79, 0xFF, 0x7C, 0x79, 0x79, 0x79, 0x7A, 0x79, 0x7A, 0x7C, 0x7A, 0x75, -0x72, 0x7C, 0xFC, 0xFE, 0xFE, 0xFC, 0xF9, 0xFE, 0xFE, 0xFA, 0x7C, 0xFD, 0xFC, 0x77, 0x7B, 0x7A, -0x73, 0x78, 0x7A, 0x78, 0x7B, 0x77, 0x6E, 0x70, 0x7B, 0x7A, 0x72, 0x74, 0x76, 0x75, 0x77, 0x75, -0x70, 0x6F, 0x6F, 0x6F, 0x74, 0x77, 0x72, 0x6F, 0x70, 0x79, 0x79, 0x6F, 0x7E, 0xFA, 0x72, 0x79, -0x79, 0x78, 0xFE, 0x78, 0xFF, 0xFE, 0x76, 0xFF, 0xFF, 0x7D, 0xFF, 0x7E, 0x7B, 0x78, 0x7C, 0x75, -0x75, 0xFF, 0xFF, 0xF8, 0xF6, 0xFD, 0xF5, 0xF4, 0xF6, 0xFC, 0x7C, 0x7C, 0x7B, 0xFC, 0xFD, 0xFD, -0xFD, 0x77, 0x7A, 0x7F, 0x7E, 0xFC, 0xFA, 0xF7, 0xFF, 0xFE, 0xF1, 0xFD, 0xFD, 0xF0, 0xF9, 0xF8, -0xEE, 0xEF, 0xF8, 0x7E, 0x79, 0x77, 0x6C, 0x66, 0x6A, 0x68, 0x67, 0x71, 0x74, 0x77, 0x7E, 0x7B, -0xFD, 0xFD, 0x7F, 0xFF, 0x79, 0xFE, 0xFE, 0x75, 0x78, 0x7A, 0x74, 0x70, 0x76, 0x77, 0x75, 0x7C, -0x7C, 0x79, 0x78, 0x77, 0x78, 0x7C, 0x7E, 0x77, 0x74, 0x79, 0x77, 0x78, 0x78, 0x77, 0x7B, 0x78, -0x77, 0x77, 0x7A, 0xFE, 0x7D, 0xFE, 0xF6, 0xFB, 0xFC, 0xF8, 0xF6, 0xFA, 0xFD, 0xFB, 0xFC, 0x7D, -0x7B, 0xFB, 0xF5, 0xFC, 0xFF, 0xFD, 0xFE, 0xFF, 0x7F, 0xFC, 0xF8, 0xFF, 0x7F, 0xF7, 0xF9, 0xFA, -0xF9, 0xFB, 0xFA, 0xFA, 0xFA, 0xF8, 0xF8, 0xFD, 0x7E, 0xF8, 0xF7, 0xEF, 0xE0, 0xE1, 0xF7, 0x6E, -0x69, 0x65, 0x5C, 0x5B, 0x61, 0x69, 0x6E, 0x76, 0xF8, 0xEF, 0xF2, 0xEB, 0xE3, 0xDE, 0xE2, 0xFA, -0x66, 0x5B, 0x5F, 0x6E, 0x6E, 0xFB, 0xED, 0xED, 0xEC, 0xF8, 0x7E, 0x7B, 0x6E, 0x67, 0x60, 0x65, -0x6E, 0x6F, 0x78, 0xFB, 0x7E, 0x7D, 0xFA, 0xF9, 0xF7, 0xF5, 0xF7, 0xEE, 0xEB, 0xF3, 0xFA, 0x7A, -0x6D, 0x69, 0x6A, 0x69, 0x64, 0x69, 0x6E, 0x6F, 0x78, 0xFB, 0xFB, 0x7C, 0xF8, 0xF1, 0xFB, 0xF4, -0xF9, 0x7D, 0xF8, 0x7D, 0xFD, 0xF3, 0x7C, 0xFD, 0xF4, 0x7A, 0x6F, 0x79, 0xFF, 0x75, 0x78, 0xFA, -0xFB, 0xFE, 0xFB, 0xF9, 0xFE, 0xFF, 0xFF, 0xFC, 0xF5, 0xFD, 0x79, 0xFF, 0xF9, 0xFA, 0xFF, 0xFF, -0x7B, 0x74, 0x75, 0x6F, 0x71, 0x7D, 0x74, 0x75, 0x79, 0x71, 0x77, 0x7E, 0x7E, 0x7C, 0x74, 0x71, -0x77, 0x7A, 0x7F, 0xFB, 0x72, 0x69, 0x74, 0x74, 0x6A, 0x74, 0x7E, 0x79, 0x76, 0x74, 0x7F, 0x7C, -0x76, 0xF8, 0xF8, 0x7E, 0x7D, 0x7E, 0xFE, 0x77, 0x7B, 0xF8, 0x7B, 0xFF, 0xF3, 0xFC, 0xFF, 0xFE, -0xFD, 0xF5, 0xF6, 0xF3, 0xF2, 0xFA, 0xF8, 0xF3, 0xFB, 0x7E, 0xFA, 0xFA, 0x7E, 0xFE, 0xFC, 0x7C, -0x78, 0x7D, 0xFB, 0xF3, 0xFD, 0x74, 0xF7, 0xF5, 0x76, 0xF9, 0xF8, 0xFF, 0xF5, 0x76, 0x7B, 0xFA, -0x77, 0xFD, 0x7C, 0x77, 0x7D, 0x6F, 0x7D, 0xF7, 0xFC, 0xFD, 0x7B, 0xF5, 0xF8, 0x7A, 0xF4, 0xFB, -0x77, 0x7B, 0x76, 0x74, 0x7D, 0x7E, 0x72, 0x71, 0x70, 0x70, 0x77, 0x70, 0x7B, 0xFD, 0x6F, 0x72, -0x7D, 0x7A, 0x71, 0x79, 0xF8, 0x77, 0x6F, 0x74, 0x7A, 0x78, 0x7C, 0xF6, 0x7C, 0xFB, 0x7D, 0x6C, -0xEF, 0xFC, 0x6D, 0xF1, 0xF5, 0x7D, 0x79, 0xFA, 0xF5, 0x75, 0xF4, 0x7C, 0xFC, 0xE6, 0x68, 0x78, -0xE4, 0x6E, 0x77, 0xF2, 0x7E, 0x70, 0x69, 0xF9, 0xF7, 0x6C, 0x74, 0xF3, 0xEE, 0x79, 0x7E, 0xFB, -0x7A, 0xF6, 0x6C, 0x6B, 0xED, 0x77, 0x6A, 0x70, 0x6F, 0xFC, 0x7E, 0x79, 0xF2, 0xEE, 0xF8, 0x7D, -0xEF, 0xEB, 0x7E, 0x72, 0x7D, 0x74, 0x6B, 0xFA, 0xE5, 0xE7, 0xE4, 0xEB, 0xF8, 0xEC, 0xEA, 0xF3, -0xFB, 0xFA, 0xEF, 0xF6, 0x7C, 0xFF, 0x7B, 0x72, 0x78, 0x7C, 0x6F, 0x6E, 0xFF, 0xFF, 0x75, 0x74, -0x74, 0x76, 0x6C, 0x6A, 0x7F, 0x78, 0x6D, 0x74, 0x6E, 0x76, 0x7B, 0x69, 0x6B, 0x79, 0x72, 0x6A, -0x6D, 0x77, 0xFD, 0xFC, 0x6F, 0x7C, 0xEE, 0x76, 0x69, 0x74, 0xFB, 0x74, 0x6A, 0x7D, 0xF0, 0xFF, -0x6B, 0x71, 0xEF, 0x7D, 0x74, 0xF8, 0x75, 0x74, 0x77, 0x6C, 0x6E, 0x71, 0x73, 0x72, 0x70, 0xF4, -0xF0, 0x79, 0x7B, 0xFB, 0xF3, 0xF4, 0x78, 0x79, 0xF7, 0xFC, 0x6E, 0x70, 0xF8, 0xF8, 0x79, 0x6D, -0x70, 0xFB, 0x6E, 0x64, 0x6B, 0x72, 0x6F, 0x65, 0x71, 0xFC, 0x71, 0x76, 0x6E, 0x71, 0xF9, 0xFF, -0xFD, 0x73, 0x7A, 0xFF, 0x66, 0x70, 0xFE, 0x79, 0xFD, 0x7D, 0xF1, 0xF6, 0x76, 0x79, 0x6D, 0x79, -0xFF, 0x72, 0x7F, 0xF8, 0xF0, 0xFF, 0x71, 0xEC, 0xE9, 0x7C, 0x7C, 0xF1, 0xF7, 0xF7, 0xF5, 0xFA, -0xF1, 0x7C, 0x70, 0x7D, 0xFB, 0xF4, 0x7C, 0x7D, 0xF6, 0xFD, 0xEF, 0xF6, 0xEE, 0xE1, 0xEE, 0xF4, -0xF3, 0xEE, 0xF4, 0x78, 0xEC, 0xF7, 0x72, 0x74, 0x6E, 0xF5, 0x6A, 0x7B, 0xDF, 0x69, 0x7F, 0xE7, -0x6F, 0x7C, 0x68, 0xF4, 0xEE, 0x5C, 0x72, 0x6B, 0x6D, 0xEC, 0x60, 0x7E, 0xEB, 0x66, 0x6D, 0x6A, -0x7A, 0xFF, 0x6A, 0x6E, 0x74, 0xED, 0x79, 0x6B, 0xED, 0xFA, 0xFC, 0x70, 0x65, 0xF6, 0x75, 0x67, -0x78, 0x78, 0xF4, 0xFF, 0x5F, 0xF9, 0xE3, 0x6D, 0xF1, 0x7A, 0x70, 0xDB, 0x6A, 0xF9, 0xDC, 0x66, -0xDB, 0xF8, 0x65, 0xD6, 0x6A, 0xF2, 0xE6, 0x5E, 0xE1, 0x76, 0x6F, 0xF5, 0x65, 0xEF, 0x5F, 0x66, -0x6F, 0x5A, 0xFB, 0x5E, 0x65, 0x7E, 0x60, 0xF2, 0x5D, 0x72, 0xE8, 0x5A, 0xEA, 0x6E, 0x62, 0xE4, -0x5E, 0x6F, 0x74, 0x67, 0xEA, 0x64, 0x77, 0xF3, 0x69, 0xF1, 0x6B, 0x6E, 0xEB, 0x74, 0x74, 0x74, -0xF6, 0xF5, 0x66, 0xF5, 0xF7, 0x6C, 0xE9, 0x70, 0x6F, 0xE4, 0x6E, 0xF0, 0xF4, 0x63, 0xE1, 0xFE, -0x6D, 0xE4, 0x6D, 0xF2, 0xEF, 0x6C, 0xE8, 0x7B, 0xFC, 0xED, 0x74, 0xEB, 0xFE, 0xFC, 0xEF, 0x6D, -0xEC, 0xFB, 0x71, 0xEB, 0x77, 0xF3, 0xF8, 0x6F, 0xE9, 0xFE, 0xFC, 0xEE, 0x6F, 0xEB, 0xED, 0x7A, -0xEE, 0xF4, 0xF3, 0xF8, 0xF1, 0xEE, 0x79, 0xF4, 0xF3, 0xFC, 0xF1, 0x7C, 0xF4, 0xF9, 0x76, 0xE8, -0xF8, 0x75, 0xE3, 0x7B, 0x6E, 0xE0, 0x75, 0x72, 0xE3, 0x6C, 0xF8, 0xE7, 0x6D, 0xEA, 0xF4, 0x75, -0xEA, 0x71, 0xFA, 0xED, 0x6A, 0xF2, 0xFB, 0x70, 0xEB, 0x6F, 0x71, 0xEE, 0x6C, 0xF6, 0xF2, 0x68, -0xF3, 0xF8, 0x6D, 0x7A, 0xFC, 0x75, 0x6D, 0xF3, 0x6E, 0x6E, 0xEE, 0x61, 0x7C, 0xFE, 0x60, 0xF2, -0x6D, 0x78, 0x7C, 0x63, 0xEB, 0x64, 0x71, 0xED, 0x5C, 0xEB, 0x6F, 0x69, 0xEA, 0x5D, 0xE7, 0xF8, -0x5E, 0xE6, 0x6F, 0xFA, 0x79, 0x72, 0xE8, 0x5E, 0xE9, 0xFB, 0x5F, 0xDE, 0x61, 0xFA, 0xE3, 0x5A, -0xE3, 0x79, 0x62, 0xDF, 0x64, 0x76, 0xE4, 0x63, 0xFE, 0xE9, 0x64, 0xF8, 0xE6, 0x5F, 0xF2, 0xE8, -0x62, 0xE7, 0xFB, 0x6A, 0xF0, 0x77, 0xF9, 0x77, 0xE9, 0x78, 0x59, 0xE3, 0x71, 0x6C, 0xDF, 0x5F, -0xEF, 0xE9, 0x5F, 0xFA, 0x76, 0xF9, 0x7D, 0x67, 0xEE, 0x7B, 0x6F, 0x7E, 0x6B, 0x6D, 0xF7, 0x6E, -0x6B, 0xF0, 0x63, 0xF0, 0x75, 0x57, 0xD4, 0x59, 0x57, 0xCD, 0x4F, 0xEE, 0xDE, 0x4B, 0xCF, 0x68, -0x5B, 0xD4, 0x50, 0xE0, 0xEF, 0x54, 0xD5, 0x57, 0x6A, 0xD3, 0x54, 0x79, 0xDF, 0x5E, 0xFC, 0xE6, -0x5F, 0x71, 0xE0, 0x64, 0x76, 0xFC, 0x5D, 0xEA, 0xF8, 0x58, 0x79, 0xDB, 0x68, 0x59, 0xDF, 0x76, -0x64, 0xDA, 0x63, 0x5A, 0xD9, 0xE0, 0x51, 0xF3, 0xD3, 0x4D, 0xDE, 0xCF, 0x3F, 0xDA, 0xC2, 0x41, -0x6A, 0xC3, 0x50, 0x55, 0xC6, 0x5A, 0x4B, 0xC2, 0x7A, 0x46, 0xCA, 0xDF, 0x4C, 0xD8, 0xDE, 0x4F, -0xE2, 0xD2, 0x4D, 0x6B, 0xCD, 0x5C, 0x56, 0xD8, 0xEB, 0x54, 0xEF, 0xDE, 0x4F, 0x78, 0xD7, 0x54, -0x5B, 0xDA, 0xFA, 0x56, 0xF6, 0xE9, 0x58, 0xF1, 0xE5, 0x59, 0x6D, 0xE8, 0x7B, 0x64, 0x7E, 0xE2, -0x60, 0x6D, 0xDC, 0x63, 0x67, 0xDC, 0x6F, 0x62, 0xE2, 0x7B, 0x60, 0xEC, 0xF3, 0x67, 0x77, 0xF1, -0x7C, 0x75, 0xF0, 0x79, 0x6F, 0xED, 0x76, 0x6B, 0xF3, 0xFF, 0x74, 0xF4, 0xF8, 0x6B, 0x6C, 0xE6, -0xE7, 0x61, 0x79, 0xDD, 0x6F, 0x77, 0xDE, 0x6D, 0x6E, 0xE4, 0x7E, 0xF9, 0xE8, 0x6D, 0x6F, 0xDE, -0xEF, 0x5C, 0xEF, 0xDB, 0x64, 0x6B, 0xDF, 0xF9, 0x6C, 0xF4, 0xF5, 0x72, 0xF5, 0xF7, 0x66, 0x7D, -0xE9, 0x7D, 0x70, 0x79, 0xF6, 0x7B, 0x6C, 0xF3, 0xF2, 0x6A, 0x76, 0xED, 0x79, 0x6B, 0xF2, 0xF1, -0x6B, 0x78, 0xEF, 0x73, 0x74, 0xED, 0x73, 0x6A, 0xEB, 0xF2, 0x64, 0x6F, 0xE2, 0xF8, 0x5E, 0xF3, -0xE8, 0x64, 0x74, 0xEF, 0x7B, 0x77, 0x74, 0x78, 0x6D, 0xF8, 0xEA, 0x63, 0x68, 0xEC, 0xEF, 0x6E, -0x63, 0xEE, 0xFA, 0x5F, 0xE5, 0xEB, 0x58, 0x73, 0xD1, 0xF3, 0x4D, 0xF2, 0xCD, 0x5D, 0x54, 0xDF, -0xDD, 0x61, 0x5B, 0xD9, 0xDF, 0x50, 0xF0, 0xD3, 0x5F, 0x5D, 0xE4, 0xDF, 0x6E, 0x5B, 0xED, 0xD8, -0x68, 0x56, 0xEA, 0xD3, 0x70, 0x52, 0xF0, 0xD3, 0x74, 0x57, 0xF5, 0xD8, 0x6A, 0x58, 0xE4, 0xE2, -0x5C, 0x7A, 0xD8, 0x77, 0x5A, 0xE8, 0xD9, 0x73, 0x5F, 0x7D, 0xE3, 0xEC, 0x73, 0x72, 0x6E, 0xF6, -0xDF, 0xF7, 0x62, 0x6B, 0xE5, 0xDD, 0x6B, 0x58, 0xF7, 0xDB, 0x73, 0x5E, 0x75, 0x7E, 0xF6, 0xFE, -0x66, 0x71, 0x7B, 0x7E, 0xEE, 0x6C, 0x6B, 0xEB, 0x76, 0x6C, 0xEA, 0x7A, 0x67, 0xE5, 0xE8, 0x5F, -0x75, 0xDE, 0xEE, 0x6F, 0x7A, 0xED, 0xE8, 0xF8, 0xFB, 0xF4, 0x78, 0xF1, 0xE4, 0x6E, 0x62, 0xEB, -0xEC, 0x65, 0x6D, 0x7E, 0x6B, 0x69, 0x6E, 0x72, 0x78, 0x68, 0x5E, 0x74, 0xE9, 0x6F, 0x5E, 0x72, -0xEB, 0x7A, 0x6F, 0xF1, 0x78, 0x75, 0xE5, 0xE6, 0xE2, 0xDD, 0xE0, 0xD6, 0xD1, 0xD5, 0xD1, 0xD3, -0xDE, 0xE0, 0xDD, 0xE9, 0x68, 0x57, 0x52, 0x50, 0x4B, 0x48, 0x48, 0x48, 0x48, 0x4B, 0x51, 0x56, -0x56, 0x5D, 0x68, 0x6A, 0x69, 0x7C, 0xE8, 0xED, 0xED, 0xDC, 0xD5, 0xCD, 0xCB, 0xCD, 0xC5, 0xBE, -0xBE, 0xBC, 0xBC, 0xBF, 0xC5, 0xD2, 0x72, 0x52, 0x48, 0x40, 0x3C, 0x39, 0x39, 0x3B, 0x3D, 0x40, -0x4A, 0x5A, 0x6C, 0x7E, 0xDF, 0xCF, 0xCE, 0xDB, 0x6F, 0x63, 0x6E, 0x60, 0x4D, 0x47, 0x4D, 0x5E, -0x7C, 0xFA, 0xE4, 0xCD, 0xC1, 0xBD, 0xBC, 0xBA, 0xB7, 0xB4, 0xB5, 0xBE, 0xD7, 0xEB, 0xF2, 0x4E, -0x3B, 0x36, 0x37, 0x39, 0x38, 0x39, 0x3D, 0x48, 0x58, 0xFE, 0xDA, 0xD6, 0xD8, 0xCF, 0xC8, 0xCD, -0xF3, 0x5A, 0x59, 0x58, 0x4E, 0x47, 0x48, 0x4F, 0x5F, 0xF2, 0xD9, 0xCE, 0xC6, 0xBF, 0xBB, 0xBA, -0xB9, 0xB7, 0xB5, 0xB7, 0xC0, 0xD9, 0x68, 0x57, 0x49, 0x3B, 0x35, 0x35, 0x38, 0x3A, 0x3B, 0x3F, -0x4B, 0x60, 0xE7, 0xD8, 0xD5, 0xD4, 0xCE, 0xCA, 0xCF, 0xF9, 0x59, 0x51, 0x4E, 0x4C, 0x48, 0x46, -0x49, 0x56, 0xFB, 0xD9, 0xD1, 0xC9, 0xBE, 0xB8, 0xB6, 0xB5, 0xB3, 0xB2, 0xB6, 0xC3, 0xE5, 0x60, -0x4E, 0x3F, 0x37, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x41, 0x4E, 0x6F, 0xDA, 0xD2, 0xD4, 0xD1, 0xCA, -0xC9, 0xD7, 0x6F, 0x59, 0x4D, 0x47, 0x47, 0x48, 0x45, 0x46, 0x52, 0xEE, 0xD7, 0xD0, 0xC7, 0xBC, -0xB5, 0xB3, 0xB3, 0xB1, 0xB0, 0xB7, 0xCA, 0x68, 0x4F, 0x45, 0x3B, 0x32, 0x2E, 0x30, 0x35, 0x39, -0x3D, 0x44, 0x52, 0xEC, 0xD0, 0xCF, 0xD3, 0xD0, 0xCD, 0xCF, 0xE3, 0x63, 0x5B, 0x59, 0x52, 0x4D, -0x4C, 0x4F, 0x5A, 0x6D, 0xE5, 0xD2, 0xC8, 0xBE, 0xB9, 0xB5, 0xB3, 0xB1, 0xAF, 0xB1, 0xBD, 0xE3, -0x53, 0x4B, 0x40, 0x35, 0x2E, 0x2F, 0x34, 0x39, 0x3B, 0x3F, 0x4C, 0x75, 0xDA, 0xD6, 0xD2, 0xCE, -0xCE, 0xD0, 0xD9, 0xEF, 0x62, 0x56, 0x55, 0x55, 0x4F, 0x4E, 0x52, 0x61, 0xEF, 0xDB, 0xCC, 0xBF, -0xB9, 0xB5, 0xB3, 0xB0, 0xAE, 0xB4, 0xC8, 0x63, 0x4D, 0x45, 0x39, 0x2E, 0x2C, 0x2F, 0x35, 0x38, -0x3B, 0x43, 0x5A, 0xDD, 0xCE, 0xCD, 0xCC, 0xCB, 0xCD, 0xD2, 0xDE, 0x76, 0x5A, 0x52, 0x53, 0x51, -0x4E, 0x4F, 0x5C, 0x7C, 0xE2, 0xD2, 0xC5, 0xBB, 0xB5, 0xB2, 0xB0, 0xAE, 0xAE, 0xB6, 0xCF, 0x55, -0x48, 0x3F, 0x34, 0x2C, 0x2C, 0x2F, 0x36, 0x39, 0x3D, 0x4A, 0x7D, 0xCE, 0xCA, 0xCB, 0xCB, 0xCB, -0xCD, 0xD9, 0x76, 0x59, 0x4F, 0x4C, 0x4C, 0x4A, 0x4C, 0x54, 0x68, 0xEC, 0xD8, 0xCB, 0xBF, 0xB8, -0xB3, 0xB0, 0xAE, 0xAD, 0xAE, 0xBC, 0xF5, 0x4C, 0x43, 0x39, 0x2E, 0x2A, 0x2D, 0x32, 0x37, 0x3B, -0x44, 0x5F, 0xD5, 0xC8, 0xC7, 0xC9, 0xCB, 0xCE, 0xD3, 0xE9, 0x5A, 0x4D, 0x4D, 0x4D, 0x4B, 0x4B, -0x50, 0x63, 0xF6, 0xDE, 0xCE, 0xC5, 0xBD, 0xB7, 0xB2, 0xB0, 0xAF, 0xAD, 0xAF, 0xBF, 0x5E, 0x45, -0x40, 0x37, 0x2C, 0x29, 0x2D, 0x34, 0x38, 0x3C, 0x48, 0x77, 0xCD, 0xC6, 0xC7, 0xCB, 0xCB, 0xCF, -0xE9, 0x59, 0x4E, 0x4B, 0x47, 0x44, 0x47, 0x4D, 0x57, 0x69, 0xEB, 0xD7, 0xCA, 0xBF, 0xB9, 0xB3, -0xAF, 0xAE, 0xAD, 0xAC, 0xB5, 0xDE, 0x49, 0x43, 0x3B, 0x2D, 0x28, 0x2A, 0x30, 0x36, 0x3A, 0x44, -0x6A, 0xCD, 0xC2, 0xC2, 0xC6, 0xCA, 0xCC, 0xD8, 0x60, 0x4C, 0x48, 0x46, 0x44, 0x43, 0x49, 0x54, -0x68, 0xEC, 0xD8, 0xCB, 0xC2, 0xBC, 0xB8, 0xB2, 0xAF, 0xAE, 0xAE, 0xAE, 0xBA, 0x74, 0x45, 0x3F, -0x36, 0x2C, 0x29, 0x2C, 0x32, 0x37, 0x3E, 0x4E, 0xE3, 0xC7, 0xC2, 0xC5, 0xC6, 0xC8, 0xD2, 0x71, -0x52, 0x4D, 0x49, 0x42, 0x41, 0x47, 0x51, 0x60, 0x7B, 0xDE, 0xCE, 0xC6, 0xC0, 0xBE, 0xB9, 0xB2, -0xAF, 0xAF, 0xAE, 0xAE, 0xBC, 0x6B, 0x47, 0x3F, 0x34, 0x2C, 0x2A, 0x2D, 0x32, 0x39, 0x3F, 0x4F, -0xDF, 0xC5, 0xC4, 0xCD, 0xCA, 0xC7, 0xDB, 0x5A, 0x4E, 0x4D, 0x48, 0x42, 0x40, 0x45, 0x54, 0x6F, -0x74, 0xEC, 0xCD, 0xC4, 0xC4, 0xC1, 0xBB, 0xB3, 0xAF, 0xB0, 0xAE, 0xAE, 0xBC, 0x6F, 0x4A, 0x3F, -0x34, 0x2C, 0x2B, 0x2E, 0x34, 0x3B, 0x42, 0x56, 0xCF, 0xBF, 0xC2, 0xCB, 0xC6, 0xC6, 0xE6, 0x52, -0x4B, 0x47, 0x45, 0x3F, 0x3D, 0x45, 0x5E, 0x7A, 0x72, 0xDB, 0xC7, 0xC3, 0xC5, 0xC2, 0xBC, 0xB5, -0xB1, 0xB3, 0xB0, 0xAE, 0xB9, 0xF0, 0x4C, 0x43, 0x38, 0x2E, 0x2B, 0x2D, 0x34, 0x3A, 0x3E, 0x4F, -0xD3, 0xC1, 0xC4, 0xCD, 0xCC, 0xC8, 0xDE, 0x4D, 0x45, 0x47, 0x47, 0x41, 0x3D, 0x47, 0x6D, 0xF7, -0x79, 0xDA, 0xC9, 0xC6, 0xC8, 0xC9, 0xC0, 0xB8, 0xB4, 0xB5, 0xB0, 0xAC, 0xB1, 0xCF, 0x5A, 0x4E, -0x3E, 0x30, 0x2B, 0x2D, 0x33, 0x38, 0x3B, 0x48, 0xDC, 0xC4, 0xC5, 0xCA, 0xCB, 0xCB, 0xD9, 0x50, -0x46, 0x4B, 0x46, 0x3E, 0x3F, 0x48, 0x55, 0x76, 0x7E, 0xE3, 0xCA, 0xC9, 0xCE, 0xCB, 0xC6, 0xBE, -0xBA, 0xB8, 0xB4, 0xAE, 0xAE, 0xBD, 0xEA, 0x62, 0x48, 0x35, 0x2D, 0x2C, 0x30, 0x35, 0x37, 0x3F, -0x6F, 0xCB, 0xCA, 0xC9, 0xC7, 0xCE, 0xD9, 0x60, 0x46, 0x46, 0x48, 0x40, 0x40, 0x49, 0x52, 0x69, -0xED, 0xE1, 0xD1, 0xCC, 0xD0, 0xD2, 0xD0, 0xCD, 0xC2, 0xBD, 0xB9, 0xB2, 0xAE, 0xAF, 0xBA, 0xE0, -0x67, 0x4C, 0x34, 0x2D, 0x2E, 0x30, 0x34, 0x37, 0x41, 0xF4, 0xCD, 0xCC, 0xC7, 0xC5, 0xD0, 0xED, -0x64, 0x4D, 0x45, 0x47, 0x43, 0x44, 0x4F, 0x51, 0x69, 0xD9, 0xDD, 0xD1, 0xCB, 0xD1, 0xCF, 0xD2, -0xCD, 0xBF, 0xBC, 0xB8, 0xB0, 0xAD, 0xAE, 0xBC, 0xD9, 0x76, 0x48, 0x32, 0x2D, 0x2F, 0x30, 0x32, -0x38, 0x49, 0xE6, 0xD1, 0xCB, 0xC1, 0xC1, 0xD2, 0x7A, 0x6F, 0x51, 0x42, 0x43, 0x45, 0x4A, 0x4D, -0x4E, 0x72, 0xD7, 0xDB, 0xD8, 0xCE, 0xCF, 0xD7, 0xDD, 0xD3, 0xC6, 0xBF, 0xBB, 0xB3, 0xAD, 0xAE, -0xB8, 0xCD, 0xE2, 0x52, 0x35, 0x2E, 0x2F, 0x2F, 0x2F, 0x35, 0x43, 0x62, 0xE5, 0xCF, 0xC1, 0xC0, -0xD1, 0xE1, 0xDB, 0x5E, 0x46, 0x49, 0x4D, 0x4A, 0x49, 0x51, 0x6A, 0xEE, 0xEB, 0xDE, 0xD0, 0xD4, -0xDF, 0xDC, 0xD7, 0xCF, 0xC5, 0xBE, 0xB7, 0xB1, 0xAE, 0xAF, 0xBC, 0xD3, 0xE7, 0x48, 0x31, 0x2E, -0x2F, 0x2E, 0x2F, 0x36, 0x44, 0x5B, 0xF4, 0xCC, 0xBF, 0xC2, 0xD4, 0xD1, 0xCF, 0x59, 0x4B, 0x51, -0x4B, 0x46, 0x44, 0x4C, 0x56, 0x51, 0x66, 0xE5, 0xE6, 0xE0, 0xDF, 0xD6, 0xD1, 0xCD, 0xC0, 0xBB, -0xB7, 0xB0, 0xAD, 0xB0, 0xBD, 0xCE, 0xEF, 0x44, 0x31, 0x2F, 0x30, 0x2E, 0x2E, 0x39, 0x46, 0x56, -0xF0, 0xC7, 0xBD, 0xC2, 0xC9, 0xC8, 0xCC, 0x7A, 0x50, 0x57, 0x4F, 0x42, 0x42, 0x4A, 0x4C, 0x4C, -0x5D, 0xEF, 0xEE, 0xE3, 0xD6, 0xD1, 0xD2, 0xCC, 0xC0, 0xBC, 0xBA, 0xB3, 0xAE, 0xAF, 0xBA, 0xC9, -0xD6, 0x4F, 0x36, 0x30, 0x30, 0x2E, 0x2D, 0x34, 0x3E, 0x45, 0x5C, 0xCF, 0xC1, 0xC0, 0xC1, 0xC0, -0xC9, 0xD9, 0xF5, 0x54, 0x4A, 0x47, 0x40, 0x41, 0x42, 0x45, 0x4E, 0x53, 0x68, 0xE8, 0xE1, 0xD1, -0xCD, 0xCC, 0xC5, 0xBF, 0xBB, 0xB8, 0xB4, 0xAF, 0xB0, 0xBD, 0xCB, 0xD8, 0x4B, 0x36, 0x34, 0x33, -0x2E, 0x2E, 0x37, 0x3D, 0x44, 0x62, 0xCD, 0xC4, 0xC0, 0xBE, 0xBF, 0xC5, 0xCF, 0xEE, 0x66, 0x4F, -0x45, 0x43, 0x40, 0x41, 0x44, 0x47, 0x51, 0x5B, 0x71, 0xDD, 0xD8, 0xCE, 0xC8, 0xC6, 0xC1, 0xBD, -0xB9, 0xB7, 0xB2, 0xAF, 0xB9, 0xC3, 0xCC, 0x71, 0x40, 0x37, 0x36, 0x31, 0x2E, 0x33, 0x3A, 0x3D, -0x4A, 0xE6, 0xCF, 0xC7, 0xBE, 0xBF, 0xC2, 0xCA, 0xD3, 0xE6, 0x50, 0x4C, 0x4B, 0x3E, 0x3E, 0x43, -0x41, 0x47, 0x4D, 0x59, 0x75, 0xE4, 0xD0, 0xCC, 0xC9, 0xC3, 0xBF, 0xBD, 0xBB, 0xB8, 0xB3, 0xB3, -0xBB, 0xC3, 0xCD, 0x6A, 0x42, 0x3A, 0x38, 0x31, 0x30, 0x36, 0x39, 0x3C, 0x4B, 0x7A, 0xDB, 0xCB, -0xC1, 0xC3, 0xC5, 0xC5, 0xD5, 0xE5, 0x6B, 0x4E, 0x4C, 0x43, 0x40, 0x45, 0x42, 0x48, 0x50, 0x55, -0x6C, 0xE8, 0xD7, 0xCD, 0xCC, 0xC7, 0xC3, 0xC0, 0xBD, 0xBC, 0xB8, 0xB2, 0xB5, 0xBD, 0xC2, 0xD0, -0x5D, 0x45, 0x3C, 0x38, 0x32, 0x32, 0x37, 0x37, 0x3C, 0x4C, 0x5E, 0xEE, 0xCD, 0xC5, 0xC8, 0xC6, -0xC5, 0xD0, 0xE2, 0xF9, 0x5D, 0x4D, 0x47, 0x46, 0x42, 0x41, 0x47, 0x4B, 0x4E, 0x63, 0xEA, 0xE3, -0xD3, 0xC9, 0xCB, 0xC8, 0xC0, 0xBF, 0xBD, 0xBA, 0xB5, 0xB6, 0xBC, 0xC1, 0xCC, 0x7E, 0x4B, 0x3F, -0x3B, 0x35, 0x32, 0x37, 0x37, 0x3A, 0x45, 0x50, 0x6D, 0xD7, 0xC8, 0xC6, 0xC7, 0xC2, 0xCA, 0xD7, -0xDB, 0x6D, 0x59, 0x4F, 0x48, 0x48, 0x45, 0x46, 0x4D, 0x4F, 0x5E, 0xFF, 0xE6, 0xD7, 0xD4, 0xCF, -0xD1, 0xD5, 0xD0, 0xD3, 0xCD, 0xC6, 0xC1, 0xBA, 0xB8, 0xBB, 0xC2, 0xC4, 0xCD, 0x58, 0x4C, 0x48, -0x39, 0x36, 0x39, 0x36, 0x37, 0x3E, 0x44, 0x4B, 0x66, 0xDC, 0xD4, 0xCA, 0xC3, 0xC5, 0xC7, 0xCA, -0xCE, 0xDD, 0x6D, 0x5F, 0x4F, 0x46, 0x47, 0x46, 0x43, 0x49, 0x4E, 0x53, 0x65, 0xF1, 0xE4, 0xD9, -0xCF, 0xCE, 0xCD, 0xC6, 0xC3, 0xC0, 0xBA, 0xB7, 0xB7, 0xBD, 0xC4, 0xC5, 0xFD, 0x4A, 0x4C, 0x3B, -0x33, 0x37, 0x34, 0x32, 0x3A, 0x3F, 0x47, 0x5B, 0xDC, 0xCB, 0xC8, 0xBE, 0xBC, 0xC3, 0xC0, 0xC7, -0xDE, 0xEC, 0x5B, 0x49, 0x45, 0x3F, 0x3E, 0x3F, 0x40, 0x49, 0x4E, 0x5B, 0xEF, 0xDF, 0xD4, 0xCC, -0xCA, 0xC7, 0xC5, 0xC3, 0xBF, 0xBD, 0xBB, 0xB8, 0xB8, 0xC0, 0xCB, 0xCA, 0x68, 0x45, 0x4D, 0x3D, -0x35, 0x3C, 0x3A, 0x38, 0x41, 0x49, 0x4D, 0x69, 0xDB, 0xD3, 0xCD, 0xC5, 0xC6, 0xCC, 0xCB, 0xD0, -0xEB, 0x76, 0x5C, 0x4C, 0x48, 0x44, 0x41, 0x41, 0x44, 0x49, 0x4E, 0x5D, 0x7E, 0xE6, 0xD4, 0xCE, -0xCE, 0xCB, 0xCB, 0xCE, 0xCE, 0xCA, 0xC9, 0xC6, 0xBE, 0xBC, 0xC6, 0xCA, 0xC4, 0xE0, 0x58, 0x77, -0x4A, 0x3D, 0x45, 0x3D, 0x39, 0x3F, 0x41, 0x40, 0x4C, 0x61, 0x6D, 0xE7, 0xCE, 0xCC, 0xCC, 0xC9, -0xCA, 0xD1, 0xDB, 0xE2, 0x66, 0x54, 0x50, 0x48, 0x45, 0x47, 0x47, 0x4B, 0x51, 0x5A, 0x71, 0xEB, -0xDD, 0xD5, 0xD2, 0xCF, 0xCC, 0xCC, 0xCA, 0xC4, 0xC3, 0xBF, 0xB9, 0xBD, 0xCB, 0xC0, 0xC9, 0x56, -0x71, 0x5A, 0x3A, 0x3F, 0x3E, 0x34, 0x3A, 0x3E, 0x3C, 0x42, 0x54, 0x62, 0x73, 0xCF, 0xC8, 0xCC, -0xC3, 0xC3, 0xCD, 0xCF, 0xDD, 0x6D, 0x56, 0x4D, 0x48, 0x42, 0x42, 0x44, 0x45, 0x4D, 0x57, 0x61, -0xED, 0xDB, 0xD5, 0xCD, 0xCD, 0xCD, 0xCD, 0xD0, 0xCD, 0xD1, 0xCA, 0xC4, 0xC7, 0xBA, 0xC2, 0xD8, -0xBB, 0xD7, 0x53, 0xCC, 0x4E, 0x3E, 0x57, 0x3E, 0x3B, 0x43, 0x3F, 0x3E, 0x46, 0x52, 0x50, 0x60, -0xD6, 0xD9, 0xD4, 0xC6, 0xCA, 0xCF, 0xCB, 0xD5, 0xF4, 0xFB, 0x5D, 0x4E, 0x4C, 0x4B, 0x46, 0x45, -0x4F, 0x4E, 0x4D, 0x7E, 0x6F, 0x71, 0xD4, 0xE1, 0xDF, 0xCE, 0xD9, 0xD5, 0xCD, 0xCD, 0xC5, 0xBF, -0xB9, 0xBA, 0xC6, 0xBA, 0xBF, 0x6C, 0xCE, 0xFB, 0x3D, 0x4D, 0x40, 0x35, 0x3C, 0x3B, 0x38, 0x3E, -0x47, 0x4B, 0x52, 0xDF, 0xD8, 0xD6, 0xC3, 0xC6, 0xCB, 0xC5, 0xCD, 0xDD, 0xE4, 0x6B, 0x50, 0x4D, -0x49, 0x44, 0x45, 0x47, 0x48, 0x49, 0x50, 0x5D, 0x5C, 0xEE, 0xDD, 0xE7, 0xD1, 0xD5, 0xDC, 0xD0, -0xDA, 0xD8, 0xD1, 0xCD, 0xC6, 0xBF, 0xBA, 0xC1, 0xC4, 0xBA, 0xD3, 0xE1, 0xCC, 0x4D, 0x49, 0x4F, -0x3B, 0x3B, 0x3E, 0x3A, 0x3C, 0x42, 0x4A, 0x4C, 0x6D, 0xD9, 0xDC, 0xC9, 0xC4, 0xCA, 0xC6, 0xC8, -0xD0, 0xD8, 0xE5, 0x68, 0x58, 0x53, 0x4C, 0x4A, 0x4B, 0x4C, 0x4E, 0x56, 0x5F, 0x69, 0xEA, 0xE0, -0xE8, 0xD5, 0xDD, 0xE7, 0xD9, 0xFB, 0xF9, 0xF5, 0x64, 0x75, 0x6D, 0xF5, 0xE5, 0xD8, 0xC8, 0xC4, -0xBB, 0xBF, 0xC4, 0xB7, 0xCC, 0xD6, 0xC3, 0x56, 0x52, 0x5F, 0x3D, 0x3E, 0x3E, 0x39, 0x3A, 0x3D, -0x41, 0x41, 0x4F, 0x6B, 0x63, 0xD6, 0xCD, 0xD1, 0xC7, 0xC8, 0xCE, 0xCE, 0xD6, 0xE8, 0x71, 0x67, -0x55, 0x4F, 0x52, 0x4D, 0x4F, 0x56, 0x56, 0x5E, 0x6D, 0x7E, 0xF5, 0xDF, 0xE3, 0xEE, 0xDC, 0x7B, -0x73, 0xED, 0x5C, 0x6A, 0x69, 0x5B, 0x70, 0x6D, 0xEF, 0xE1, 0xCF, 0xC8, 0xC4, 0xB9, 0xC5, 0xC2, -0xB6, 0xDC, 0xCD, 0xC3, 0x49, 0x60, 0x57, 0x3A, 0x40, 0x3D, 0x38, 0x3A, 0x3E, 0x3F, 0x3E, 0x53, -0x58, 0x59, 0xD3, 0xD7, 0xD2, 0xC4, 0xC9, 0xCA, 0xC8, 0xCD, 0xD8, 0xDE, 0xEE, 0x5F, 0x5D, 0x59, -0x4F, 0x54, 0x56, 0x54, 0x5D, 0x69, 0x6D, 0xF2, 0xE1, 0xDF, 0xDB, 0xD8, 0xDD, 0xE8, 0xEB, 0x71, -0x5D, 0x66, 0x56, 0x52, 0x62, 0x52, 0x5C, 0x74, 0x63, 0xE2, 0xDD, 0xD4, 0xCA, 0xC9, 0xBF, 0xC0, -0xBB, 0xBB, 0xCC, 0xBB, 0xC8, 0x68, 0xC8, 0x58, 0x44, 0x5D, 0x3C, 0x3B, 0x40, 0x3A, 0x3B, 0x3F, -0x44, 0x43, 0x52, 0x7A, 0x62, 0xD4, 0xCB, 0xD1, 0xC3, 0xC4, 0xC8, 0xC5, 0xCA, 0xD0, 0xD9, 0xE1, -0x6C, 0x5C, 0x5B, 0x4E, 0x4D, 0x50, 0x4C, 0x50, 0x58, 0x58, 0x63, 0x79, 0xFE, 0xED, 0xE1, 0xE7, -0xEE, 0xE6, 0xFB, 0x6D, 0x7A, 0x61, 0x5D, 0x62, 0x59, 0x5B, 0x5E, 0x5C, 0x64, 0x69, 0x72, 0xFE, -0xF1, 0xE6, 0xE2, 0xDB, 0xD9, 0xD6, 0xD3, 0xD3, 0xD0, 0xD0, 0xCF, 0xCE, 0xCD, 0xCD, 0xDA, 0xDB, -0xDA, 0x64, 0x69, 0x63, 0x4C, 0x4F, 0x4D, 0x46, 0x4A, 0x4A, 0x48, 0x4D, 0x52, 0x52, 0x5C, 0x70, -0x71, 0xEB, 0xDC, 0xDE, 0xD7, 0xD4, 0xD8, 0xD5, 0xD7, 0xDD, 0xDF, 0xE7, 0xFD, 0x71, 0x69, 0x5D, -0x5A, 0x5A, 0x57, 0x56, 0x5B, 0x59, 0x5A, 0x69, 0x62, 0x6A, 0xF5, 0x73, 0xF1, 0xE7, 0xF4, 0xE6, -0xE6, 0xEE, 0xEA, 0xED, 0xF5, 0xF1, 0xED, 0xF0, 0xEA, 0xE4, 0xE7, 0xDF, 0xDE, 0xDF, 0xDC, 0xDE, -0xDF, 0xE1, 0xE8, 0xEE, 0xFD, 0x77, 0x6B, 0x64, 0x61, 0x5C, 0x5C, 0x5C, 0x5B, 0x5F, 0x61, 0x67, -0x6E, 0x78, 0xF8, 0xF1, 0xEA, 0xE5, 0xE4, 0xE2, 0xE1, 0xE5, 0xEA, 0xED, 0xFA, 0x77, 0x6E, 0x66, -0x62, 0x5D, 0x5C, 0x5A, 0x59, 0x59, 0x59, 0x5B, 0x5C, 0x5D, 0x64, 0x64, 0x6C, 0x77, 0x7C, 0xEE, -0xEB, 0xE0, 0xDB, 0xD7, 0xCF, 0xCF, 0xCA, 0xC8, 0xC5, 0xC4, 0xCD, 0xC7, 0xCB, 0xE8, 0xD3, 0xFD, -0x55, 0x67, 0x4B, 0x45, 0x48, 0x40, 0x3F, 0x42, 0x43, 0x43, 0x4A, 0x50, 0x50, 0x6C, 0xF5, 0xF2, -0xD4, 0xD2, 0xD1, 0xCB, 0xCC, 0xCE, 0xCE, 0xD0, 0xDA, 0xDC, 0xDF, 0xFD, 0x7D, 0x6F, 0x5E, 0x5F, -0x5D, 0x59, 0x5A, 0x5C, 0x5C, 0x5F, 0x68, 0x68, 0x6F, 0xFC, 0xFC, 0xEF, 0xE9, 0xEB, 0xE9, 0xE9, -0xED, 0xEF, 0xF2, 0xF8, 0xFE, 0xFE, 0x7C, 0x7C, 0x7E, 0x79, 0xFE, 0xFB, 0xFE, 0xF7, 0xF6, 0xF9, -0xF6, 0xF8, 0xFD, 0xFF, 0x7C, 0x73, 0x70, 0x6E, 0x6A, 0x6A, 0x69, 0x68, 0x6A, 0x6B, 0x6C, 0x6F, -0x74, 0x79, 0xFF, 0xFA, 0xF8, 0xF2, 0xF4, 0xF6, 0xF3, 0xFE, 0xFB, 0x74, 0x62, 0x69, 0x5F, 0x5A, -0x66, 0x5B, 0x5D, 0x70, 0x61, 0x78, 0xED, 0xF4, 0xDB, 0xD7, 0xD0, 0xCB, 0xC9, 0xC3, 0xCC, 0xC9, -0xC4, 0xDD, 0xD2, 0xD7, 0x59, 0x6E, 0x57, 0x45, 0x4B, 0x45, 0x3F, 0x43, 0x44, 0x43, 0x49, 0x51, -0x4F, 0x5E, 0xFB, 0x70, 0xDE, 0xD8, 0xDC, 0xD1, 0xD2, 0xD7, 0xD4, 0xD6, 0xDD, 0xDF, 0xDF, 0xF1, -0xF2, 0xF2, 0x6F, 0x73, 0x72, 0x69, 0x6D, 0x6F, 0x6D, 0x72, 0x7B, 0x79, 0x7E, 0xF8, 0xFD, 0xF9, -0xF6, 0xFD, 0xFA, 0xFA, 0xFD, 0xFB, 0xFB, 0xFD, 0xFA, 0xF6, 0xF8, 0xF3, 0xF2, 0xF4, 0xEF, 0xF1, -0xF4, 0xF2, 0xF6, 0xF9, 0xF8, 0xF9, 0xFD, 0xFD, 0xFC, 0x7F, 0x7E, 0x7D, 0x79, 0x76, 0x74, 0x71, -0x6F, 0x6E, 0x6C, 0x6C, 0x6D, 0x6B, 0x6C, 0x6D, 0x6C, 0x71, 0x71, 0x70, 0x7E, 0x79, 0x7C, 0xFA, -0x7B, 0xFD, 0xFC, 0x7A, 0xFE, 0x7C, 0x78, 0x7B, 0x76, 0x76, 0x78, 0x77, 0x77, 0x7C, 0x7E, 0xFF, -0xF2, 0xF3, 0xED, 0xE7, 0xE8, 0xE0, 0xDE, 0xDC, 0xD7, 0xD8, 0xD3, 0xD4, 0xDA, 0xD7, 0xDF, 0xEB, -0xED, 0x6A, 0x60, 0x5C, 0x52, 0x4F, 0x4D, 0x4B, 0x4A, 0x4B, 0x4B, 0x4D, 0x50, 0x54, 0x5B, 0x66, -0x6F, 0xF1, 0xE6, 0xDF, 0xDA, 0xD8, 0xD8, 0xD7, 0xD9, 0xDB, 0xDE, 0xE2, 0xEA, 0xF1, 0xFA, 0x78, -0x70, 0x6D, 0x69, 0x68, 0x66, 0x65, 0x65, 0x66, 0x66, 0x67, 0x6A, 0x6B, 0x6C, 0x70, 0x74, 0x79, -0xFB, 0xF5, 0xEF, 0xEB, 0xE9, 0xE6, 0xE3, 0xE2, 0xE1, 0xE0, 0xE0, 0xE0, 0xE1, 0xE3, 0xE3, 0xE6, -0xE9, 0xEB, 0xEF, 0xF7, 0x7F, 0x75, 0x6E, 0x6A, 0x66, 0x62, 0x61, 0x5F, 0x5F, 0x60, 0x5F, 0x62, -0x65, 0x66, 0x6C, 0x6E, 0x72, 0x7D, 0xFE, 0xF6, 0xEF, 0xED, 0xE9, 0xE7, 0xE4, 0xE3, 0xE0, 0xDF, -0xE1, 0xDF, 0xE1, 0xE3, 0xE3, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xED, 0xF5, 0xF6, 0xF9, 0x75, -0x76, 0x6E, 0x66, 0x65, 0x5E, 0x5B, 0x5A, 0x56, 0x55, 0x54, 0x53, 0x54, 0x55, 0x57, 0x59, 0x5D, -0x60, 0x66, 0x70, 0x79, 0xFA, 0xF0, 0xEE, 0xEC, 0xED, 0xED, 0xF0, 0xF5, 0xF8, 0xFF, 0xFD, 0x7E, -0x7D, 0xFE, 0x7E, 0xFD, 0xF8, 0xF6, 0xEF, 0xED, 0xEB, 0xE8, 0xE4, 0xE3, 0xE0, 0xDF, 0xDE, 0xDC, -0xDD, 0xDC, 0xDD, 0xE1, 0xE2, 0xE9, 0xF3, 0x7A, 0x65, 0x61, 0x5B, 0x56, 0x56, 0x51, 0x50, 0x52, -0x50, 0x55, 0x58, 0x59, 0x5F, 0x68, 0x70, 0xFC, 0xEE, 0xE9, 0xE4, 0xE1, 0xE4, 0xE4, 0xE7, 0xED, -0xEE, 0xF8, 0xFF, 0x7D, 0x76, 0x76, 0x7A, 0x7B, 0xFF, 0xF9, 0xF7, 0xF1, 0xED, 0xED, 0xEB, 0xE9, -0xEA, 0xEA, 0xEC, 0xED, 0xEE, 0xF0, 0xF1, 0xF2, 0xF2, 0xF3, 0xF0, 0xF1, 0xF3, 0xEF, 0xF3, 0xF5, -0xF4, 0xFB, 0xFC, 0xFC, 0x7C, 0x7A, 0x76, 0x70, 0x6F, 0x6F, 0x6C, 0x6C, 0x6C, 0x68, 0x6B, 0x6B, -0x68, 0x6D, 0x6B, 0x6B, 0x6F, 0x6E, 0x70, 0x77, 0x76, 0x7A, 0x7F, 0xFF, 0xFD, 0xF6, 0xF7, 0xF5, -0xEF, 0xF4, 0xF1, 0xEF, 0xF2, 0xEE, 0xF0, 0xF1, 0xEE, 0xF0, 0xF1, 0xF1, 0xF2, 0xF6, 0xF9, 0xFA, -0x7F, 0x7E, 0x7A, 0x76, 0x7A, 0x73, 0x72, 0x74, 0x6F, 0x73, 0x75, 0x73, 0x75, 0x74, 0x76, 0x73, -0x77, 0x7A, 0x76, 0x7E, 0x78, 0x76, 0x7E, 0x76, 0x7A, 0x79, 0x74, 0x7D, 0x77, 0x77, 0x79, 0x74, -0x76, 0x77, 0x7A, 0x79, 0x7C, 0xFF, 0x79, 0xFC, 0xFA, 0x7E, 0xF4, 0xF9, 0xFC, 0xF6, 0x7E, 0xFF, -0xFF, 0x7B, 0x7C, 0x77, 0x75, 0x76, 0x78, 0x76, 0x74, 0x7B, 0x74, 0x75, 0x7E, 0x74, 0x7B, 0x7C, -0x72, 0x7A, 0x77, 0x74, 0x7A, 0x75, 0x72, 0x73, 0x72, 0x6E, 0x6E, 0x70, 0x6D, 0x70, 0x71, 0x6E, -0x75, 0x73, 0x72, 0x79, 0x78, 0x7B, 0xFF, 0xFF, 0xFD, 0xFA, 0xFC, 0xFB, 0xF7, 0xFD, 0xFE, 0xFA, -0x7D, 0x7D, 0xFE, 0x79, 0x7B, 0x7C, 0x7B, 0x7E, 0x7E, 0xFD, 0xFA, 0xFA, 0xF7, 0xF8, 0xF9, 0xF9, -0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x7D, 0x7B, 0x77, 0x78, 0x74, 0x71, 0x74, 0x6F, 0x6F, 0x71, 0x6D, -0x6F, 0x71, 0x6F, 0x73, 0x74, 0x77, 0x7B, 0x7D, 0x7F, 0xFF, 0xFC, 0xFE, 0xFB, 0xF8, 0xFB, 0xF7, -0xF9, 0xFE, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0x7E, 0x7C, 0x7E, 0x7B, 0x7B, 0x7E, 0x7C, 0xFF, 0xFE, -0xFE, 0xFB, 0xFE, 0xFF, 0xFD, 0xFE, 0x7E, 0x7F, 0x7A, 0x78, 0x79, 0x75, 0x74, 0x75, 0x73, 0x75, -0x77, 0x77, 0x79, 0x7B, 0x7D, 0xFF, 0xFA, 0xF8, 0xF4, 0xF2, 0xF5, 0xF1, 0xF2, 0xF6, 0xF3, 0xF6, -0xFA, 0xFB, 0xFC, 0x7D, 0x7A, 0x7A, 0x74, 0x77, 0x78, 0x74, 0x7A, 0x77, 0x7A, 0xFF, 0x7F, 0xF9, -0xFB, 0xFB, 0xF9, 0xFF, 0x7F, 0x7C, 0x7A, 0x77, 0x72, 0x73, 0x6E, 0x6E, 0x6E, 0x6D, 0x70, 0x70, -0x75, 0x7D, 0x7B, 0xFE, 0xFD, 0xFF, 0xFC, 0xFF, 0x7E, 0xFF, 0x7E, 0x7A, 0x79, 0x76, 0x6F, 0x72, -0x72, 0x6F, 0x73, 0x6F, 0x6E, 0x74, 0x72, 0x74, 0x7C, 0x7C, 0xFF, 0xF9, 0xFA, 0xF9, 0xF5, 0xF7, -0xF7, 0xF5, 0xFA, 0xFA, 0xF7, 0xFA, 0xF9, 0xF8, 0xFC, 0xF9, 0xF8, 0xFA, 0xF6, 0xF9, 0xFC, 0xFA, -0xFD, 0xFE, 0xFD, 0xFF, 0x7E, 0x7E, 0x7D, 0x7A, 0x7C, 0x7B, 0x79, 0x7C, 0x7B, 0x7B, 0xFF, 0x7E, -0xFF, 0xFC, 0xFE, 0xFE, 0xFB, 0xFD, 0x7C, 0x7F, 0x7F, 0x76, 0x78, 0x78, 0x74, 0x78, 0x78, 0x78, -0x7B, 0x7A, 0x7A, 0x79, 0x77, 0x78, 0x79, 0x78, 0x7A, 0x7B, 0x7A, 0x7C, 0x7F, 0x7D, 0xFF, 0xFC, -0xFD, 0xFA, 0xFB, 0xFD, 0xFE, 0xFF, 0x7F, 0x7D, 0x7C, 0x7A, 0x7B, 0x7D, 0x7D, 0x7E, 0x7E, 0x7D, -0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7F, 0xFF, 0xFE, 0xFC, 0xFC, 0xFB, -0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xFB, 0xFB, 0xFD, 0xFF, 0x7D, 0x7B, 0x7B, 0x7A, 0x77, 0x77, 0x78, -0x77, 0x77, 0x79, 0x7A, 0x7B, 0x7B, 0x7D, 0x7E, 0xFF, 0xFE, 0xFE, 0xFD, 0xFC, 0xFC, 0xFC, 0xFC, -0xFE, 0xFF, 0xFF, 0x7E, 0x7B, 0x78, 0x77, 0x76, 0x74, 0x73, 0x73, 0x71, 0x72, 0x73, 0x73, 0x74, -0x75, 0x76, 0x77, 0x77, 0x78, 0x78, 0x7A, 0x7D, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0x7F, 0x7E, 0x7D, 0x7D, 0x7C, 0x7A, 0x79, 0x79, 0x78, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7A, -0x79, 0x7B, 0x7B, 0x7B, 0x7C, 0x7A, 0x7A, 0x79, 0x78, 0x78, 0x76, 0x76, 0x75, 0x73, 0x73, 0x73, -0x74, 0x77, 0x79, 0x7A, 0x7D, 0x7F, 0xFE, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFF, -0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4C, 0x49, 0x53, 0x54, 0x4A, 0x00, -0x00, 0x00, 0x49, 0x4E, 0x46, 0x4F, 0x49, 0x53, 0x46, 0x54, 0x3E, 0x00, 0x00, 0x00, 0x46, 0x69, -0x6C, 0x65, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x6F, -0x6C, 0x64, 0x57, 0x61, 0x76, 0x65, 0x2E, 0x20, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x57, 0x61, 0x76, -0x65, 0x20, 0x63, 0x6F, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, -0x43, 0x68, 0x72, 0x69, 0x73, 0x20, 0x43, 0x72, 0x61, 0x69, 0x67, 0x00 - -}; - -static const uint8_t shaun_png[] PROGMEM = { - 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x57, 0x08, 0x06, 0x00, 0x00, 0x00, 0xF2, 0x0C, 0xE0, - 0x57, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4B, 0x47, 0x44, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xA0, - 0xBD, 0xA7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x42, 0x8A, 0x00, - 0x00, 0x42, 0x8A, 0x01, 0x34, 0xA8, 0x6C, 0x25, 0x00, 0x00, 0x00, 0x09, 0x76, 0x70, 0x41, 0x67, - 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x57, 0x00, 0x73, 0x4D, 0x3B, 0xD6, 0x00, 0x00, 0x1B, - 0x47, 0x49, 0x44, 0x41, 0x54, 0x78, 0xDA, 0xED, 0x9D, 0x79, 0x74, 0x14, 0x55, 0xBE, 0xC7, 0x3F, - 0x55, 0xDD, 0x49, 0x67, 0x5F, 0x3A, 0x7B, 0x42, 0x82, 0x61, 0x49, 0x02, 0x81, 0xB0, 0x29, 0x32, - 0x22, 0x3C, 0x16, 0x41, 0x45, 0x10, 0x15, 0x7D, 0x13, 0x65, 0xD0, 0x81, 0xE3, 0x7B, 0xCC, 0xD3, - 0x51, 0x04, 0xF5, 0xE1, 0xB8, 0xCE, 0xE6, 0x28, 0x22, 0x23, 0x33, 0x2C, 0x2A, 0x22, 0xEE, 0x02, - 0x22, 0x0C, 0x2A, 0x83, 0x28, 0x7B, 0x20, 0xC8, 0x92, 0x10, 0xD9, 0x97, 0x40, 0x08, 0x81, 0x90, - 0x3D, 0x64, 0x21, 0xE9, 0x4E, 0x3A, 0x5D, 0xF7, 0xFD, 0x71, 0xBB, 0x93, 0x0E, 0x10, 0xD2, 0x59, - 0x3A, 0x01, 0xCF, 0xFB, 0x9E, 0xD3, 0xE7, 0xA4, 0x6E, 0xA5, 0x6E, 0xDD, 0xFA, 0xFD, 0xEA, 0xFE, - 0xEE, 0xEF, 0xFE, 0xB6, 0x52, 0xB8, 0xFE, 0xA1, 0x03, 0x7A, 0x01, 0x43, 0x81, 0x9B, 0x80, 0x6A, - 0x60, 0x3F, 0xA0, 0x02, 0x8F, 0x00, 0xB7, 0x03, 0xA1, 0x80, 0x00, 0x72, 0x81, 0xAD, 0xC0, 0xC7, - 0xC0, 0x6E, 0xA0, 0xAE, 0xB3, 0x07, 0xFF, 0x4B, 0x43, 0x30, 0xF0, 0x67, 0x20, 0x1B, 0xB0, 0x20, - 0x89, 0xAE, 0x01, 0x95, 0x40, 0xB9, 0xED, 0xF8, 0x6A, 0xBF, 0x3C, 0xDB, 0x75, 0x81, 0xCD, 0xF4, - 0xAF, 0x03, 0x8C, 0x40, 0x2C, 0xD0, 0x13, 0x88, 0x00, 0x0C, 0x9D, 0xF9, 0xC0, 0x4A, 0x27, 0xDD, - 0xD7, 0x13, 0x88, 0x07, 0xFA, 0x03, 0x51, 0x36, 0x22, 0xE4, 0x03, 0x87, 0x80, 0x83, 0x48, 0x62, - 0x1B, 0x81, 0x85, 0x40, 0x72, 0x2B, 0xC7, 0xA9, 0x01, 0x5F, 0x00, 0x2F, 0x03, 0x35, 0xB6, 0xE3, - 0x0A, 0xDB, 0xDF, 0xDE, 0xC0, 0x48, 0x60, 0x22, 0x30, 0x08, 0xC9, 0x78, 0x3D, 0x92, 0xD1, 0x99, - 0xC0, 0x0F, 0xC0, 0x5A, 0xE0, 0x5C, 0x47, 0x13, 0xA6, 0xA3, 0x19, 0xA2, 0x07, 0x46, 0x00, 0x4F, - 0x22, 0x45, 0x4D, 0xD0, 0x65, 0x63, 0xB8, 0x84, 0x14, 0x47, 0xEF, 0x03, 0x09, 0xC0, 0x4B, 0x48, - 0xD1, 0x44, 0x40, 0x40, 0x00, 0x31, 0x31, 0x31, 0x54, 0x56, 0x56, 0x92, 0x93, 0x93, 0x83, 0xD5, - 0x6A, 0x25, 0x3A, 0x3A, 0x9A, 0x89, 0x13, 0x27, 0x32, 0x60, 0xC0, 0x00, 0xAC, 0x56, 0x2B, 0xBB, - 0x77, 0xEF, 0x66, 0xDD, 0xBA, 0x75, 0x14, 0x16, 0x16, 0xDA, 0xFB, 0xAB, 0x03, 0x4E, 0x23, 0x67, - 0x4D, 0x9D, 0x8D, 0xC0, 0xFB, 0x90, 0x22, 0xF0, 0x1E, 0xC0, 0xAB, 0x89, 0x71, 0x6A, 0xC0, 0x11, - 0xE0, 0x0D, 0xE0, 0x6B, 0xE4, 0xEC, 0xFC, 0xC5, 0xC1, 0x07, 0x78, 0x0D, 0x28, 0xA5, 0x69, 0x51, - 0x63, 0xFF, 0x99, 0x80, 0x2A, 0xFB, 0xF1, 0xC0, 0x81, 0x03, 0xC5, 0xA6, 0x4D, 0x9B, 0x44, 0x49, - 0x49, 0x89, 0xC8, 0xCA, 0xCA, 0x12, 0xAF, 0xBF, 0xFE, 0xBA, 0x78, 0xFC, 0xF1, 0xC7, 0x45, 0x5A, - 0x5A, 0x9A, 0xD0, 0x34, 0x4D, 0xD8, 0x51, 0x57, 0x57, 0x27, 0xB6, 0x6E, 0xDD, 0x2A, 0xFA, 0xF7, - 0xEF, 0xDF, 0x5C, 0xFF, 0x8D, 0x7E, 0x8A, 0xA2, 0x08, 0x55, 0x55, 0xAF, 0x76, 0xAE, 0x02, 0x78, - 0x0E, 0xF9, 0x22, 0x75, 0x08, 0x3A, 0x6A, 0x86, 0x78, 0x02, 0x7F, 0x05, 0x9E, 0x02, 0xDC, 0x00, - 0x14, 0x45, 0x21, 0x24, 0x24, 0x84, 0xE8, 0xE8, 0x68, 0xDC, 0xDD, 0xDD, 0xB9, 0x70, 0xE1, 0x02, - 0xB9, 0xB9, 0xB9, 0xD4, 0xD5, 0x35, 0x5E, 0x87, 0xBD, 0xBC, 0xBC, 0x58, 0xB1, 0x62, 0x05, 0x13, - 0x26, 0x4C, 0xA8, 0x6F, 0x13, 0x42, 0x20, 0x84, 0x40, 0x55, 0xD5, 0xAB, 0xDE, 0x6C, 0xD7, 0xAE, - 0x5D, 0x3C, 0xFC, 0xF0, 0xC3, 0xE4, 0xE4, 0xE4, 0x34, 0xFD, 0xE0, 0x8A, 0x42, 0x7C, 0x7C, 0x3C, - 0xF7, 0xDC, 0x73, 0x0F, 0xFD, 0xFA, 0xF5, 0xC3, 0xC3, 0xC3, 0x83, 0xEC, 0xEC, 0x6C, 0x36, 0x6C, - 0xD8, 0x40, 0x6A, 0x6A, 0x2A, 0x35, 0x35, 0x35, 0xF6, 0x7F, 0xAD, 0xB4, 0x8D, 0xFB, 0x73, 0xC0, - 0xDA, 0x41, 0xF4, 0x72, 0x39, 0x7E, 0x8F, 0x7C, 0xEB, 0x05, 0x20, 0xC2, 0xC2, 0xC2, 0xC4, 0x2B, - 0xAF, 0xBC, 0x22, 0x0E, 0x1E, 0x3C, 0x28, 0x2E, 0x5E, 0xBC, 0x28, 0x2A, 0x2A, 0x2A, 0x44, 0x56, - 0x56, 0x96, 0x58, 0xBC, 0x78, 0xB1, 0x48, 0x48, 0x48, 0x68, 0xF4, 0x96, 0xC6, 0xC4, 0xC4, 0x88, - 0x33, 0x67, 0xCE, 0x88, 0x96, 0xE2, 0xE3, 0x8F, 0x3F, 0x16, 0x77, 0xDE, 0x79, 0xA7, 0x78, 0xFE, - 0xF9, 0xE7, 0xC5, 0xBB, 0xEF, 0xBE, 0x2B, 0xDE, 0x7E, 0xFB, 0x6D, 0xF1, 0xE0, 0x83, 0x0F, 0x0A, - 0xA3, 0xD1, 0x28, 0xDC, 0xDC, 0xDC, 0xC4, 0xD4, 0xA9, 0x53, 0xC5, 0xE9, 0xD3, 0xA7, 0xAF, 0xB8, - 0xAE, 0xA2, 0xA2, 0x42, 0x2C, 0x58, 0xB0, 0x40, 0x04, 0x07, 0x07, 0x3B, 0x8E, 0xA3, 0x00, 0x58, - 0x0D, 0xFC, 0x0E, 0x08, 0xEF, 0x6C, 0x62, 0xB6, 0x15, 0x7D, 0x80, 0x33, 0xF6, 0x87, 0x8B, 0x8D, - 0x8D, 0x15, 0xEB, 0xD7, 0xAF, 0x6F, 0x24, 0x6A, 0x1C, 0x91, 0x91, 0x91, 0x21, 0x06, 0x0F, 0x1E, - 0x2C, 0x00, 0x61, 0x30, 0x18, 0xC4, 0xAF, 0x7F, 0xFD, 0x6B, 0x51, 0x51, 0x51, 0xD1, 0x62, 0x86, - 0x58, 0xAD, 0x56, 0x61, 0x36, 0x9B, 0x1B, 0xDD, 0xA7, 0xA6, 0xA6, 0x46, 0xEC, 0xD8, 0xB1, 0x43, - 0xAC, 0x5A, 0xB5, 0x4A, 0x94, 0x97, 0x97, 0x37, 0x79, 0xAD, 0xA6, 0x69, 0x62, 0xF1, 0xE2, 0xC5, - 0xC2, 0xC3, 0xC3, 0xE3, 0x72, 0x11, 0x66, 0x05, 0x76, 0x02, 0x43, 0x3A, 0x9B, 0xA8, 0x6D, 0xC1, - 0xDB, 0xF6, 0x07, 0xF2, 0xF5, 0xF5, 0x15, 0x2B, 0x56, 0xAC, 0x68, 0x96, 0x98, 0xC7, 0x8E, 0x1D, - 0x13, 0xF3, 0xE7, 0xCF, 0x17, 0x1B, 0x36, 0x6C, 0x10, 0xA5, 0xA5, 0xA5, 0x2D, 0x66, 0x46, 0x7B, - 0xA0, 0xB2, 0xB2, 0x52, 0x4C, 0x98, 0x30, 0xA1, 0xA9, 0x75, 0xE7, 0x00, 0x52, 0x31, 0x68, 0x77, - 0xB8, 0x7A, 0x0D, 0x89, 0x02, 0x36, 0xDA, 0x07, 0x3F, 0x79, 0xF2, 0x64, 0x3E, 0xFC, 0xF0, 0x43, - 0x0C, 0x86, 0x4E, 0x55, 0xF5, 0x9D, 0xC6, 0xC1, 0x83, 0x07, 0x59, 0xBB, 0x76, 0x2D, 0x16, 0x8B, - 0x85, 0x94, 0x94, 0x14, 0x52, 0x53, 0x53, 0xB1, 0x5A, 0xEB, 0x97, 0x91, 0xF7, 0x91, 0xDA, 0xE2, - 0x0D, 0xB5, 0xAE, 0x8C, 0x07, 0xCC, 0x80, 0xF0, 0xF4, 0xF4, 0x14, 0xEB, 0xD6, 0xAD, 0xEB, 0x94, - 0xB7, 0xBD, 0x3D, 0x50, 0x54, 0x54, 0x24, 0x92, 0x93, 0x93, 0x1D, 0x67, 0x49, 0x36, 0xD0, 0xBD, - 0xB3, 0x09, 0xDC, 0x12, 0x84, 0x00, 0xAB, 0xEC, 0x0F, 0x10, 0x1F, 0x1F, 0x2F, 0x72, 0x73, 0x73, - 0x3B, 0x9B, 0xAE, 0x6D, 0xC2, 0x96, 0x2D, 0x5B, 0x84, 0x8F, 0x8F, 0x8F, 0xA3, 0x6A, 0x7E, 0x47, - 0x7B, 0x13, 0x4D, 0x6D, 0x7B, 0x17, 0x57, 0x85, 0x37, 0x72, 0x53, 0x35, 0xC9, 0xDE, 0xD0, 0xAD, - 0x5B, 0x37, 0x8C, 0x46, 0xA3, 0x8B, 0x6E, 0xD7, 0x31, 0xF0, 0xF5, 0xF5, 0x45, 0xAF, 0xAF, 0xDF, - 0x92, 0xA8, 0x80, 0x47, 0x7B, 0xDF, 0xC3, 0x55, 0x0C, 0xF9, 0x4F, 0xE0, 0x37, 0xD8, 0xD6, 0xA8, - 0x84, 0x84, 0x04, 0x9E, 0x7E, 0xFA, 0x69, 0x3C, 0x3C, 0xDA, 0x7D, 0xFC, 0x1D, 0x8A, 0x5D, 0xBB, - 0x76, 0x51, 0x56, 0x56, 0x66, 0x3F, 0xAC, 0x42, 0xDA, 0xCC, 0xDA, 0x15, 0xAE, 0xD8, 0x81, 0x1A, - 0x81, 0xC7, 0xB1, 0x19, 0xE9, 0x12, 0x12, 0x12, 0xF8, 0xEC, 0xB3, 0xCF, 0xB8, 0xF9, 0xE6, 0x9B, - 0x5D, 0x44, 0xA6, 0x8E, 0x43, 0x5E, 0x5E, 0x23, 0xFA, 0x0B, 0x5C, 0xF7, 0x42, 0xB7, 0x2B, 0x46, - 0x21, 0x6D, 0x52, 0x42, 0xAF, 0xD7, 0x8B, 0x25, 0x4B, 0x96, 0x74, 0xB6, 0xE8, 0x6F, 0x37, 0xEC, - 0xDD, 0xBB, 0x57, 0x84, 0x86, 0x86, 0x3A, 0x2E, 0xEC, 0xB3, 0xDB, 0x9B, 0x78, 0xAE, 0xE0, 0x70, - 0x12, 0x72, 0x0D, 0xA1, 0x6B, 0xD7, 0xAE, 0x8C, 0x1D, 0x3B, 0xD6, 0x85, 0xBC, 0xEF, 0x58, 0x24, - 0x25, 0x25, 0x31, 0x64, 0x48, 0xA3, 0x3D, 0xE1, 0x2D, 0xB4, 0xB3, 0x94, 0x71, 0x05, 0x43, 0x22, - 0xED, 0x7F, 0x44, 0x47, 0x47, 0x13, 0x12, 0x12, 0xE2, 0x1A, 0xEA, 0x74, 0x02, 0x0C, 0x06, 0x03, - 0x89, 0x89, 0x89, 0x8E, 0x4D, 0x51, 0x48, 0x3B, 0x5D, 0xBB, 0xC1, 0x15, 0x0C, 0xA9, 0xEF, 0x53, - 0xA7, 0xD3, 0x35, 0x69, 0x00, 0xBC, 0x51, 0xE1, 0xEB, 0xEB, 0xEB, 0x78, 0x68, 0xE0, 0x06, 0x98, - 0x21, 0xF5, 0xCE, 0x88, 0xBC, 0xBC, 0x3C, 0x47, 0xAD, 0xE4, 0x17, 0x81, 0xD2, 0xD2, 0x52, 0xC7, - 0xC3, 0x6A, 0xDA, 0xD9, 0x57, 0xE2, 0x0A, 0x86, 0x1C, 0x46, 0xEE, 0xCE, 0xC9, 0xCA, 0xCA, 0x22, - 0x35, 0x35, 0xD5, 0x65, 0xC4, 0xE9, 0x68, 0x54, 0x55, 0x55, 0x91, 0x91, 0x91, 0xE1, 0xD8, 0x94, - 0x8D, 0x64, 0xCA, 0x75, 0x8D, 0x70, 0xE0, 0x67, 0x6C, 0x9A, 0xC8, 0xD0, 0xA1, 0x43, 0x45, 0x76, - 0x76, 0x76, 0x67, 0x2B, 0x48, 0xED, 0x82, 0x1F, 0x7E, 0xF8, 0x41, 0xF8, 0xF9, 0xF9, 0x39, 0x6A, - 0x59, 0x4F, 0x74, 0x36, 0xB1, 0x9D, 0xC5, 0x73, 0x48, 0xA3, 0x9B, 0x00, 0xC4, 0xC8, 0x91, 0x23, - 0xC5, 0x8F, 0x3F, 0xFE, 0x28, 0xCC, 0x66, 0xB3, 0xCB, 0x88, 0x65, 0xB5, 0x5A, 0x5D, 0xCA, 0x8C, - 0xAC, 0xAC, 0x2C, 0x31, 0x6C, 0xD8, 0x30, 0x47, 0x66, 0x64, 0x01, 0x71, 0x9D, 0x4D, 0x68, 0x67, - 0x61, 0x04, 0xD6, 0x39, 0x0C, 0x5E, 0xF8, 0xF8, 0xF8, 0x88, 0x05, 0x0B, 0x16, 0xB8, 0x84, 0x58, - 0x99, 0x99, 0x99, 0x62, 0xFA, 0xF4, 0xE9, 0x62, 0xD9, 0xB2, 0x65, 0xC2, 0x64, 0x32, 0x5D, 0x71, - 0x5E, 0xD3, 0x34, 0x71, 0xEE, 0xDC, 0x39, 0x91, 0x97, 0x97, 0xD7, 0xAA, 0xFE, 0x4F, 0x9E, 0x3C, - 0x29, 0x46, 0x8C, 0x18, 0x71, 0xB9, 0x09, 0xFE, 0xF5, 0xCE, 0x26, 0xB2, 0xB3, 0x08, 0x46, 0x5A, - 0x79, 0x1B, 0x31, 0x04, 0x10, 0x49, 0x49, 0x49, 0x22, 0x27, 0x27, 0xA7, 0x5D, 0x99, 0x61, 0xB5, - 0x5A, 0xC5, 0x8C, 0x19, 0x33, 0x04, 0x20, 0xBC, 0xBC, 0xBC, 0xC4, 0xA3, 0x8F, 0x3E, 0x2A, 0x36, - 0x6F, 0xDE, 0x2C, 0xCE, 0x9F, 0x3F, 0x2F, 0x0A, 0x0B, 0x0B, 0xC5, 0xE1, 0xC3, 0x87, 0xC5, 0xDC, - 0xB9, 0x73, 0x45, 0x42, 0x42, 0x82, 0x18, 0x33, 0x66, 0x8C, 0x28, 0x28, 0x28, 0x68, 0xF1, 0x3D, - 0x96, 0x2E, 0x5D, 0x7A, 0x39, 0x33, 0x34, 0x60, 0x3B, 0xF0, 0xDF, 0x40, 0x37, 0x64, 0x38, 0xD1, - 0x75, 0x87, 0x28, 0xA4, 0xEF, 0x79, 0x2F, 0x36, 0x93, 0x3B, 0x57, 0x09, 0x26, 0x98, 0x35, 0x6B, - 0x56, 0xBB, 0x8A, 0xAE, 0x6D, 0xDB, 0xB6, 0x89, 0xD0, 0xD0, 0x50, 0xE1, 0xED, 0x69, 0x10, 0xE1, - 0xC1, 0x01, 0x02, 0x10, 0x9E, 0x5E, 0x5E, 0xA2, 0x5B, 0xB7, 0xEE, 0xA2, 0x57, 0xAF, 0x5E, 0x22, - 0x38, 0x24, 0x44, 0x28, 0x8A, 0x22, 0x00, 0xE1, 0xE6, 0xE6, 0x26, 0x3E, 0xFA, 0xE8, 0xA3, 0x16, - 0xDF, 0x63, 0xCD, 0x9A, 0x35, 0x42, 0xAF, 0xD7, 0x5F, 0xCD, 0x51, 0x55, 0x87, 0x14, 0x5D, 0x0B, - 0x80, 0x5B, 0x01, 0xF7, 0xB6, 0x12, 0xB1, 0x3D, 0x38, 0x1B, 0x0A, 0x4C, 0x07, 0xE6, 0x21, 0x0D, - 0x8A, 0x5D, 0x70, 0xD0, 0xCD, 0x75, 0x3A, 0x1D, 0xE1, 0xE1, 0xE1, 0x24, 0x25, 0x25, 0x61, 0x36, - 0x9B, 0x49, 0x4D, 0x4D, 0xC5, 0x64, 0x32, 0xD1, 0xB7, 0x6F, 0x5F, 0x7C, 0x7C, 0x7C, 0x00, 0x19, - 0xB4, 0x50, 0x50, 0x50, 0x40, 0x59, 0x59, 0x19, 0xBE, 0xBE, 0xBE, 0x28, 0x8A, 0x73, 0x7E, 0xB3, - 0xEC, 0xEC, 0x6C, 0x9E, 0x7E, 0xFA, 0x69, 0x8E, 0x1D, 0x3B, 0xC6, 0x8C, 0x87, 0xC7, 0x31, 0x77, - 0xC6, 0x14, 0x02, 0xFD, 0x7C, 0xA8, 0xAA, 0x36, 0x51, 0x5A, 0x5A, 0x42, 0x65, 0x45, 0x39, 0x81, - 0x3E, 0x06, 0xEE, 0xFC, 0x55, 0x7F, 0x86, 0x0D, 0x48, 0x20, 0xFD, 0xE8, 0x69, 0xB2, 0xB3, 0xCF, - 0x72, 0xC7, 0x1D, 0x77, 0xB4, 0xC8, 0xF2, 0xBC, 0x7E, 0xFD, 0x7A, 0x36, 0x6C, 0xD8, 0x80, 0x9F, - 0x9F, 0x1F, 0x3A, 0x9D, 0x0E, 0x8B, 0xA5, 0x5E, 0xD3, 0x55, 0x91, 0xC1, 0x78, 0x83, 0x81, 0xFB, - 0x81, 0xDE, 0x40, 0x11, 0xD2, 0xE8, 0xA8, 0xB5, 0x03, 0x6D, 0x5B, 0x04, 0x37, 0xA4, 0x68, 0x4A, - 0x45, 0xBE, 0x29, 0x8D, 0x66, 0x42, 0x97, 0x2E, 0x5D, 0xC4, 0x23, 0x8F, 0x3C, 0x22, 0x3E, 0xF9, - 0xE4, 0x13, 0x71, 0xEC, 0xD8, 0x31, 0x51, 0x55, 0x55, 0x25, 0x5E, 0x7A, 0xE9, 0x25, 0x01, 0x08, - 0x9D, 0x4E, 0x27, 0x06, 0x0E, 0x1A, 0x24, 0x66, 0xCF, 0x9E, 0x2D, 0xE6, 0xCF, 0x9F, 0x2F, 0x66, - 0xCE, 0x9C, 0x29, 0xFA, 0xF4, 0xE9, 0x23, 0x7A, 0xF7, 0xEE, 0x2D, 0xD6, 0xAC, 0x59, 0xE3, 0xD4, - 0x02, 0x9D, 0x99, 0x99, 0x29, 0xC6, 0x8D, 0x1B, 0x27, 0x95, 0x86, 0x9B, 0x13, 0x45, 0xEE, 0x86, - 0x25, 0x42, 0x64, 0xAC, 0x16, 0x5A, 0xFA, 0x2A, 0x51, 0xB6, 0xED, 0x63, 0x71, 0xFA, 0x9B, 0x05, - 0xE2, 0xF8, 0xD7, 0xF3, 0xC5, 0x85, 0x0D, 0xEF, 0x0B, 0xCB, 0xDE, 0x15, 0xA2, 0x74, 0xFB, 0x27, - 0x62, 0xFC, 0xB0, 0x41, 0x02, 0x10, 0x77, 0xDF, 0x7D, 0xB7, 0x38, 0x7A, 0xF4, 0x68, 0xA3, 0xFE, - 0x34, 0x4D, 0x13, 0xFB, 0xF7, 0xEF, 0x17, 0x6F, 0xBD, 0xF5, 0x96, 0xD8, 0xBD, 0x7B, 0xB7, 0xB0, - 0x58, 0x2C, 0xC2, 0x62, 0xB1, 0x88, 0x6D, 0xDB, 0xB6, 0x89, 0xB8, 0xB8, 0x38, 0xE1, 0xEE, 0xEE, - 0x2E, 0xDE, 0x7B, 0xEF, 0x3D, 0xB1, 0x69, 0xD3, 0x26, 0xF1, 0xDC, 0x73, 0xCF, 0x89, 0x7E, 0xFD, - 0xFA, 0x09, 0x77, 0x77, 0xF7, 0xAB, 0xCD, 0x9A, 0x12, 0xE0, 0x03, 0x64, 0x10, 0x60, 0x87, 0xC5, - 0xBD, 0x45, 0x20, 0x67, 0x44, 0x99, 0xE3, 0x60, 0x74, 0x3A, 0x9D, 0x48, 0x4A, 0x4A, 0x12, 0x6F, - 0xBE, 0xF9, 0xA6, 0x38, 0x76, 0xEC, 0x98, 0xB0, 0x58, 0x2C, 0xF5, 0x0F, 0x6C, 0x32, 0x99, 0xC4, - 0xA4, 0x49, 0x93, 0x04, 0x20, 0xBA, 0x84, 0x1A, 0x85, 0xA7, 0xC1, 0xAD, 0xD1, 0x83, 0x78, 0xB8, - 0xBB, 0x09, 0x9D, 0xAA, 0x8A, 0xA0, 0xA0, 0x20, 0xF1, 0xDA, 0x6B, 0xAF, 0x89, 0xB3, 0x67, 0xCF, - 0x5E, 0x35, 0x10, 0xA2, 0xA2, 0xA2, 0x42, 0xAC, 0x5C, 0xB9, 0x52, 0x0C, 0x18, 0x30, 0x40, 0x00, - 0xE2, 0x96, 0xDE, 0xDD, 0xC5, 0xC1, 0x95, 0x6F, 0x0B, 0xB1, 0xFF, 0x6B, 0x21, 0xD2, 0xBE, 0x92, - 0xBF, 0xF4, 0x55, 0x42, 0xEC, 0x5F, 0x25, 0xDB, 0xD2, 0x57, 0xC9, 0xB6, 0xFD, 0x5F, 0x8B, 0xC3, - 0x5F, 0xFD, 0x5D, 0x0C, 0x4E, 0xEC, 0x21, 0x00, 0xD1, 0xA3, 0x47, 0x0F, 0xF1, 0x87, 0x3F, 0xFC, - 0x41, 0xAC, 0x5A, 0xB5, 0x4A, 0xAC, 0x5C, 0xB9, 0x52, 0xCC, 0x9A, 0x35, 0x4B, 0xC4, 0xC4, 0xC4, - 0x08, 0x40, 0x84, 0x87, 0x87, 0x8B, 0xFB, 0xEE, 0xBB, 0x4F, 0x4C, 0x9C, 0x38, 0xB1, 0xDE, 0x98, - 0x38, 0x79, 0xF2, 0xE4, 0xFA, 0x60, 0x0B, 0x4D, 0xD3, 0x44, 0x7E, 0x7E, 0xBE, 0x58, 0xBE, 0x7C, - 0xB9, 0x18, 0x3F, 0x7E, 0xBC, 0xF0, 0xF5, 0xF5, 0xBD, 0x1A, 0x63, 0xCE, 0x21, 0x8D, 0x8F, 0xC1, - 0x2D, 0x21, 0x6C, 0x4B, 0x39, 0xA8, 0x20, 0x83, 0x9E, 0x5F, 0x07, 0x86, 0x39, 0x5E, 0x1F, 0x17, - 0x17, 0xC7, 0xF4, 0xE9, 0xD3, 0x49, 0x4E, 0x4E, 0x26, 0x32, 0x32, 0xF2, 0x8A, 0x0B, 0x77, 0xEC, - 0xD8, 0xC1, 0x84, 0x09, 0x13, 0xF0, 0xD4, 0x2B, 0x2C, 0xFF, 0xDB, 0x33, 0x58, 0xEA, 0xEA, 0x48, - 0x3B, 0x7A, 0x9A, 0xD2, 0x8A, 0x4B, 0x04, 0x07, 0xF8, 0x31, 0xA8, 0x57, 0x37, 0x52, 0x7F, 0x3E, - 0xCE, 0x3F, 0x96, 0xAF, 0xA7, 0xEC, 0x52, 0x35, 0x71, 0xF1, 0xF1, 0xDC, 0x39, 0x76, 0x2C, 0x03, - 0x07, 0x0E, 0x24, 0x28, 0x28, 0x88, 0xAA, 0xAA, 0x2A, 0x4E, 0x9C, 0x38, 0xC1, 0x96, 0x2D, 0x5B, - 0xD8, 0xB3, 0x67, 0x0F, 0x96, 0xDA, 0x5A, 0xEE, 0xBA, 0xAD, 0x3F, 0x73, 0x9F, 0x99, 0x42, 0xAF, - 0x6E, 0xD1, 0xA0, 0x39, 0x21, 0x21, 0x54, 0x95, 0x13, 0x67, 0xCE, 0xF3, 0xA7, 0x25, 0xAB, 0xF8, - 0x76, 0x7B, 0x1A, 0x55, 0xE6, 0x1A, 0xDB, 0x23, 0x08, 0x00, 0x02, 0x7C, 0xBD, 0x49, 0xEA, 0x19, - 0xC3, 0xD1, 0xAC, 0xF3, 0x14, 0x97, 0x55, 0xA2, 0x28, 0x0A, 0xE1, 0xE1, 0xE1, 0x24, 0x27, 0x27, - 0x33, 0x7B, 0xF6, 0x6C, 0xC2, 0xC2, 0xC2, 0xAE, 0xE8, 0xB2, 0xBA, 0xBA, 0x9A, 0xD4, 0xD4, 0x54, - 0x96, 0x2E, 0x5D, 0xCA, 0xF7, 0xDF, 0x7F, 0x4F, 0x65, 0x65, 0xA5, 0xE3, 0x69, 0x2B, 0xB0, 0x03, - 0xF8, 0x13, 0x90, 0x82, 0x13, 0x62, 0xAC, 0x25, 0x0C, 0x71, 0x03, 0x26, 0x03, 0x7F, 0x41, 0xAE, - 0x13, 0x80, 0xB4, 0xED, 0x4C, 0x99, 0x32, 0x85, 0x99, 0x33, 0x67, 0xD2, 0xA3, 0x47, 0x8F, 0xAB, - 0x5E, 0x28, 0x84, 0x60, 0xC6, 0x8C, 0x19, 0x2C, 0x58, 0xB0, 0x80, 0xA9, 0xF7, 0x8E, 0x64, 0xC9, - 0x2B, 0xBF, 0xB3, 0x79, 0xDE, 0x84, 0xA4, 0x85, 0x22, 0x87, 0x52, 0x67, 0xA9, 0x63, 0xEB, 0xDE, - 0x43, 0xFC, 0x73, 0xE5, 0xF7, 0x6C, 0x4F, 0x3F, 0x42, 0x65, 0xB5, 0x59, 0x0E, 0x52, 0x51, 0x11, - 0x42, 0x3E, 0x8B, 0x5E, 0xA7, 0x92, 0xD8, 0x2D, 0x9A, 0x69, 0x13, 0x47, 0x32, 0xE5, 0x9E, 0xFF, - 0x20, 0xD0, 0xDF, 0xD7, 0x39, 0x66, 0x38, 0x30, 0xA5, 0xDA, 0x64, 0x66, 0xD7, 0x81, 0x13, 0x6C, - 0xD9, 0x77, 0x98, 0xAC, 0xDC, 0x02, 0x54, 0x45, 0xA1, 0x67, 0x4C, 0x04, 0x63, 0x6E, 0x4D, 0x62, - 0x50, 0xAF, 0x6E, 0x7C, 0xBA, 0x6E, 0x3B, 0x4F, 0xCE, 0x59, 0x4A, 0x78, 0x44, 0x24, 0x5F, 0x7E, - 0xF9, 0x25, 0x43, 0x87, 0x0E, 0x45, 0xA7, 0xBB, 0xF6, 0x72, 0x6B, 0x36, 0x9B, 0xD9, 0xB6, 0x6D, - 0x1B, 0x0B, 0x17, 0x2E, 0x64, 0xD3, 0xA6, 0x4D, 0x8E, 0x81, 0x76, 0x20, 0xE3, 0xBA, 0xDE, 0x04, - 0x96, 0xD0, 0xCC, 0xCE, 0xDE, 0x59, 0x86, 0xF8, 0x02, 0xFF, 0x0B, 0x3C, 0x83, 0x0C, 0x09, 0x05, - 0x20, 0x31, 0x31, 0x91, 0x3F, 0xFE, 0xF1, 0x8F, 0xDC, 0x7B, 0xEF, 0xBD, 0xB8, 0xBB, 0x37, 0xAD, - 0x60, 0x9C, 0x39, 0x73, 0x86, 0x31, 0x63, 0xC7, 0x92, 0x9B, 0x73, 0x96, 0x7F, 0xCD, 0x7B, 0x9E, - 0xBB, 0x6E, 0x1F, 0x08, 0xD6, 0x26, 0x88, 0xA8, 0x53, 0xA9, 0xAA, 0x32, 0xF1, 0xF3, 0xF1, 0x33, - 0xEC, 0x3C, 0x70, 0x82, 0xE3, 0xD9, 0xB9, 0x54, 0x5C, 0xAA, 0xC6, 0xD3, 0xC3, 0x40, 0x4C, 0x78, - 0x30, 0x83, 0x13, 0xBB, 0x33, 0xA4, 0x6F, 0x1C, 0xE1, 0x21, 0x81, 0x36, 0xE1, 0x20, 0x9C, 0x67, - 0x86, 0xE3, 0x53, 0xAB, 0x2A, 0x08, 0xD0, 0xEA, 0xAC, 0xA0, 0x80, 0xAA, 0xD3, 0xD5, 0x4F, 0x96, - 0xBC, 0xA2, 0x52, 0xEE, 0x7A, 0xF2, 0xAF, 0x1C, 0x3D, 0x9B, 0xC7, 0x8A, 0xE5, 0xCB, 0x99, 0x34, - 0x69, 0x92, 0xD3, 0x5D, 0x57, 0x56, 0x56, 0xB2, 0x62, 0xC5, 0x0A, 0xE6, 0xCD, 0x9B, 0xC7, 0x89, - 0x13, 0x27, 0x1C, 0x4F, 0xD5, 0x00, 0xCB, 0x80, 0x57, 0x81, 0xE2, 0xB6, 0x30, 0x24, 0x10, 0x29, - 0xA2, 0xFE, 0x0B, 0x9B, 0xF6, 0xA4, 0xD7, 0xEB, 0x79, 0xE0, 0x81, 0x07, 0xF8, 0xF3, 0x9F, 0xFF, - 0x4C, 0x7C, 0x7C, 0x7C, 0xB3, 0x1D, 0x2C, 0x59, 0xB2, 0x84, 0xE9, 0xD3, 0xA7, 0x33, 0x6C, 0x40, - 0x02, 0xDF, 0xBE, 0xF3, 0x02, 0x01, 0xBE, 0xDE, 0xD7, 0x26, 0xA4, 0x9D, 0x60, 0x80, 0xB0, 0x6A, - 0x68, 0x9A, 0x86, 0xAA, 0x28, 0x28, 0x3A, 0x1D, 0x28, 0x8A, 0x9C, 0x11, 0xAD, 0x61, 0x84, 0xB3, - 0x50, 0x14, 0x5E, 0x5A, 0xB4, 0x9C, 0xBF, 0x2D, 0x5B, 0x43, 0x72, 0x72, 0x32, 0x9F, 0x7E, 0xFA, - 0x29, 0x6E, 0x6E, 0x6E, 0x2D, 0xEA, 0x22, 0x33, 0x33, 0x93, 0xD7, 0x5F, 0x7F, 0x9D, 0x15, 0x2B, - 0x56, 0x38, 0xCE, 0x16, 0x0D, 0x19, 0x01, 0x39, 0x13, 0x99, 0xCB, 0x72, 0x05, 0x9A, 0x33, 0x2E, - 0x86, 0x00, 0xFF, 0x40, 0xAA, 0xB5, 0x7A, 0x90, 0x22, 0xEA, 0x85, 0x17, 0x5E, 0x60, 0xC9, 0x92, - 0x25, 0x4E, 0x31, 0xC3, 0x6C, 0x36, 0xB3, 0x6E, 0xDD, 0x3A, 0x00, 0x26, 0x0C, 0xBF, 0x99, 0x00, - 0x7F, 0x9F, 0xE6, 0x89, 0x29, 0x90, 0x33, 0xC8, 0xAA, 0xA1, 0x00, 0x3A, 0x55, 0x95, 0xAA, 0xB0, - 0xA6, 0x81, 0xD5, 0xEA, 0x5A, 0x66, 0x00, 0xA8, 0x0A, 0x13, 0x86, 0x0F, 0x22, 0xC0, 0xD7, 0x8B, - 0x94, 0x94, 0x14, 0x32, 0x33, 0x33, 0x5B, 0xDC, 0x45, 0xCF, 0x9E, 0x3D, 0x59, 0xBC, 0x78, 0x31, - 0x73, 0xE6, 0xCC, 0x71, 0xF4, 0x09, 0xA9, 0xC0, 0x43, 0xC8, 0x7D, 0x4B, 0xC4, 0x55, 0x6F, 0x7D, - 0x8D, 0x3E, 0x8D, 0x34, 0xEC, 0x2D, 0x54, 0x80, 0x90, 0x90, 0x10, 0xDE, 0x79, 0xE7, 0x1D, 0x5E, - 0x7D, 0xF5, 0x55, 0xFC, 0xFD, 0xFD, 0x9D, 0x1A, 0xD8, 0xF1, 0xE3, 0xC7, 0xF9, 0x69, 0xF7, 0x6E, - 0x42, 0x02, 0xFD, 0x18, 0x3B, 0xA4, 0x9F, 0x7D, 0xFD, 0xBC, 0xBE, 0xA1, 0x69, 0xF4, 0xED, 0x11, - 0xC3, 0x2D, 0x89, 0x3D, 0xB8, 0x70, 0xE1, 0x02, 0x5B, 0xB7, 0x6E, 0x6D, 0x55, 0x37, 0x5E, 0x5E, - 0x5E, 0x3C, 0xF5, 0xD4, 0x53, 0x7C, 0xF0, 0xC1, 0x07, 0xC4, 0xC6, 0xC6, 0x3A, 0x9E, 0xBA, 0x1F, - 0x98, 0x03, 0x5C, 0x41, 0xC4, 0xA6, 0x18, 0xE2, 0x89, 0x4C, 0x1D, 0x98, 0x8C, 0x4D, 0xAC, 0x45, - 0x45, 0x45, 0xB1, 0x68, 0xD1, 0x22, 0xA6, 0x4D, 0x9B, 0xD6, 0xA2, 0xE9, 0xBB, 0x7D, 0xFB, 0x76, - 0x8A, 0x8B, 0x8A, 0xB8, 0xB5, 0x4F, 0x4F, 0xE2, 0xBB, 0x46, 0xB6, 0x6C, 0x01, 0xEE, 0x2C, 0x08, - 0xF0, 0xF6, 0xF6, 0x64, 0xDC, 0xD0, 0x01, 0x00, 0x6C, 0xD8, 0xB0, 0x01, 0xB3, 0xD9, 0xDC, 0xAA, - 0xAE, 0x54, 0x55, 0x65, 0xE2, 0xC4, 0x89, 0x2C, 0x5D, 0xBA, 0xF4, 0x72, 0xA5, 0xE7, 0x11, 0xE4, - 0xBA, 0xDC, 0xC8, 0xC1, 0x75, 0x35, 0x86, 0x28, 0xC0, 0xFF, 0x20, 0xC5, 0x94, 0x0A, 0x92, 0x19, - 0xEF, 0xBE, 0xFB, 0x2E, 0x0F, 0x3D, 0xF4, 0x90, 0xD3, 0xBB, 0x68, 0x90, 0xE2, 0x6A, 0xD3, 0xA6, - 0x4D, 0x00, 0x8C, 0x19, 0x92, 0x84, 0x87, 0xE7, 0x8D, 0x11, 0x42, 0x0A, 0x80, 0x80, 0x11, 0x83, - 0x12, 0x09, 0xF2, 0xF7, 0x21, 0x2D, 0x2D, 0x9D, 0xAC, 0xAC, 0xAC, 0x36, 0x75, 0x37, 0x6A, 0xD4, - 0x28, 0x16, 0x2D, 0x5A, 0x44, 0x54, 0x54, 0x94, 0xBD, 0x49, 0x87, 0xCC, 0x0A, 0xB8, 0xDF, 0xF1, - 0xFF, 0xAE, 0xC6, 0x90, 0x31, 0xC8, 0x0D, 0x8D, 0x01, 0xC0, 0x68, 0x34, 0x32, 0x6F, 0xDE, 0xBC, - 0x46, 0xF9, 0x19, 0xCE, 0x22, 0x3B, 0x3B, 0x9B, 0xF4, 0xFD, 0xFB, 0x09, 0xF2, 0xF7, 0x61, 0xF8, - 0x80, 0x5E, 0x37, 0x86, 0xB8, 0xB2, 0x43, 0x68, 0xC4, 0xC5, 0x44, 0x30, 0x20, 0x3E, 0x96, 0xFC, - 0xFC, 0x3C, 0x76, 0xED, 0xDA, 0xD5, 0xE6, 0x2E, 0xC7, 0x8E, 0x1D, 0xCB, 0x1B, 0x6F, 0xBC, 0xE1, - 0xE8, 0x06, 0xF6, 0x43, 0x66, 0x89, 0xDD, 0x64, 0x6F, 0xB8, 0x9C, 0x21, 0x91, 0x48, 0x51, 0x15, - 0x0A, 0xD2, 0xA9, 0xFF, 0xF2, 0xCB, 0x2F, 0xF3, 0xD0, 0x43, 0x0F, 0xB5, 0x6A, 0x00, 0xE9, 0xE9, - 0xE9, 0xE4, 0x5D, 0xC8, 0xA3, 0x4F, 0xF7, 0x18, 0x7A, 0x44, 0x87, 0x3B, 0xBF, 0x18, 0xAB, 0x2A, - 0xA8, 0xAA, 0x4C, 0xCC, 0x01, 0xD0, 0xA9, 0x52, 0xBB, 0x6A, 0x2D, 0x54, 0x05, 0x54, 0x15, 0xAB, - 0xA6, 0x61, 0xD5, 0xB4, 0xFA, 0xFE, 0xAF, 0x09, 0x01, 0x5E, 0x5E, 0x9E, 0x0C, 0x1F, 0xD8, 0x1B, - 0x80, 0x9D, 0x3B, 0x77, 0xA2, 0xB5, 0x83, 0xB8, 0x4D, 0x4E, 0x4E, 0x66, 0xFA, 0xF4, 0xE9, 0x8E, - 0x4D, 0xFD, 0x90, 0x41, 0xDB, 0x2A, 0x34, 0x96, 0x5F, 0x0A, 0x32, 0x21, 0xE5, 0x36, 0x7B, 0xC3, - 0x23, 0x8F, 0x3C, 0xC2, 0xF4, 0xE9, 0xD3, 0x5B, 0x1D, 0xA8, 0x20, 0xDD, 0xB7, 0x82, 0xDB, 0xFA, - 0xC5, 0xE3, 0xE3, 0xED, 0x09, 0x5A, 0x33, 0x0C, 0x51, 0x14, 0xAC, 0x9A, 0x46, 0xFA, 0xA1, 0x93, - 0xFC, 0x7B, 0xE7, 0x7E, 0x4E, 0x9D, 0xCB, 0xC7, 0xDB, 0xD3, 0xC0, 0x6D, 0x49, 0xF1, 0x8C, 0xBB, - 0x7D, 0x20, 0xA1, 0x41, 0x01, 0x2D, 0x5F, 0x83, 0x14, 0x85, 0x53, 0x39, 0x79, 0xFC, 0x6B, 0xCB, - 0x5E, 0xD2, 0x8F, 0x67, 0x61, 0xB5, 0x6A, 0x24, 0x76, 0x8F, 0xE6, 0xFE, 0x11, 0xB7, 0xD0, 0x37, - 0xEE, 0xA6, 0x6B, 0xAB, 0x99, 0x8A, 0xC2, 0xAD, 0x7D, 0x7B, 0xE2, 0xAE, 0xD7, 0x91, 0x91, 0x91, - 0x41, 0x49, 0x49, 0x49, 0x9B, 0xA3, 0x68, 0xDC, 0xDC, 0xDC, 0x78, 0xE6, 0x99, 0x67, 0x48, 0x49, - 0x49, 0x61, 0xEF, 0xDE, 0xBD, 0xF6, 0xE6, 0xC9, 0xC0, 0x72, 0x60, 0xBF, 0x23, 0x43, 0xFA, 0x03, - 0x53, 0xED, 0x07, 0x7D, 0xFA, 0xF4, 0xE1, 0xC5, 0x17, 0x5F, 0xC4, 0xCB, 0xCB, 0xCB, 0xE9, 0x9B, - 0x39, 0xA2, 0xAC, 0xAC, 0x8C, 0xFD, 0xFB, 0xF7, 0xA3, 0x53, 0x15, 0x86, 0xF4, 0xED, 0x09, 0x8A, - 0x4A, 0x73, 0x91, 0xFB, 0xB5, 0x96, 0x3A, 0x16, 0xAE, 0xFC, 0x9E, 0x39, 0x1F, 0x7F, 0x43, 0xE1, - 0xC5, 0xF2, 0xFA, 0xF6, 0x65, 0xDF, 0x6C, 0x65, 0xD8, 0x80, 0x04, 0xDE, 0x79, 0x76, 0x2A, 0xFD, - 0x13, 0x62, 0x9D, 0x67, 0x8A, 0xA2, 0xF0, 0x7D, 0xEA, 0x7E, 0x9E, 0x7D, 0xE7, 0x53, 0x8E, 0x9D, - 0x69, 0x50, 0xFB, 0xBF, 0xDE, 0xBC, 0x9B, 0x0F, 0xD7, 0x6E, 0xE6, 0x2F, 0xFF, 0x93, 0xCC, 0xA3, - 0xE3, 0xFF, 0x03, 0xB5, 0xA9, 0xD9, 0xA7, 0x69, 0xF4, 0x8E, 0xED, 0x42, 0xD7, 0x88, 0x10, 0x4E, - 0x67, 0x65, 0x71, 0xF2, 0xE4, 0xC9, 0x76, 0x09, 0x6B, 0x8A, 0x8A, 0x8A, 0x62, 0xE6, 0xCC, 0x99, - 0x4C, 0x9D, 0x3A, 0xD5, 0xAE, 0x2C, 0x44, 0x00, 0x8F, 0x02, 0x19, 0xF6, 0x17, 0x44, 0x05, 0xA6, - 0x61, 0x33, 0x89, 0xB8, 0xBB, 0xBB, 0x33, 0x6B, 0xD6, 0xAC, 0x26, 0x4D, 0x21, 0xCE, 0xE0, 0xEC, - 0xD9, 0xB3, 0x64, 0x9E, 0x3A, 0x45, 0x44, 0x70, 0x20, 0xBD, 0xBB, 0x75, 0x01, 0xD1, 0x0C, 0x11, - 0x55, 0x95, 0x55, 0x9B, 0x7E, 0xE2, 0xD5, 0xF7, 0xBE, 0x6A, 0xC4, 0x0C, 0x2F, 0x2F, 0x2F, 0xFC, - 0xFC, 0xFD, 0xD9, 0x96, 0x7E, 0x94, 0x67, 0xDE, 0xFE, 0x88, 0x82, 0xE2, 0x8B, 0xCE, 0x89, 0x2F, - 0x55, 0xE5, 0xF0, 0xE9, 0x1C, 0x66, 0xBC, 0xFD, 0x71, 0x23, 0x66, 0x18, 0x0C, 0x06, 0xC2, 0xC2, - 0xC2, 0x28, 0x2C, 0xAB, 0xE2, 0xF9, 0x7F, 0x7C, 0xCE, 0x96, 0x7D, 0x87, 0x9B, 0x16, 0x5F, 0x42, - 0x10, 0x1E, 0xE4, 0x4F, 0xBF, 0xB8, 0x9B, 0xA8, 0xBA, 0x74, 0x89, 0xB4, 0xB4, 0xB4, 0x36, 0x33, - 0xC3, 0x8E, 0x71, 0xE3, 0xC6, 0x31, 0x7C, 0xF8, 0x70, 0xC7, 0xA6, 0x7B, 0x80, 0x04, 0xFB, 0x48, - 0x12, 0x80, 0xFB, 0xEC, 0x67, 0x46, 0x8C, 0x18, 0xC1, 0x03, 0x0F, 0x3C, 0xD0, 0xA6, 0x1B, 0x1E, - 0x3D, 0x7A, 0x94, 0xD2, 0x92, 0x12, 0xE2, 0xBB, 0x46, 0x12, 0x19, 0x62, 0xBC, 0xB6, 0xB8, 0x52, - 0x14, 0xCA, 0x2B, 0x2E, 0xF1, 0xFE, 0xEA, 0x8D, 0x54, 0x99, 0x1A, 0xD4, 0xCB, 0xBE, 0x7D, 0xFB, - 0xB2, 0x72, 0xE5, 0x4A, 0x36, 0x6F, 0xDE, 0xCC, 0x13, 0x4F, 0x3C, 0xC1, 0x4F, 0x87, 0x32, 0xF9, - 0x2E, 0x25, 0x4D, 0xAE, 0x09, 0xCD, 0x41, 0x08, 0xBE, 0x58, 0xBF, 0x83, 0xCC, 0x9C, 0x86, 0x78, - 0x5C, 0xA3, 0xD1, 0xC8, 0xFC, 0xF9, 0xF3, 0x49, 0x49, 0x49, 0xE1, 0xBD, 0xF7, 0xDE, 0x45, 0xE8, - 0xDD, 0xF9, 0x60, 0xCD, 0x26, 0x2C, 0xB5, 0x4D, 0x47, 0xF2, 0xE8, 0xDD, 0xDD, 0xE4, 0x0C, 0x07, - 0xF6, 0xEC, 0xD9, 0xE3, 0x98, 0xB0, 0xD3, 0x26, 0xF8, 0xF9, 0xF9, 0x31, 0x79, 0xF2, 0x64, 0xC7, - 0x68, 0xFA, 0x58, 0x60, 0xBC, 0x9D, 0x21, 0xE3, 0xB1, 0xCD, 0x0E, 0x83, 0xC1, 0xC0, 0xB4, 0x69, - 0xD3, 0x9C, 0xDE, 0xF8, 0x35, 0x85, 0x43, 0x87, 0x0E, 0x01, 0x90, 0xD8, 0x3D, 0x06, 0x2F, 0x8F, - 0x66, 0xD4, 0x5D, 0x45, 0xE1, 0x6C, 0x5E, 0x11, 0xC7, 0xCE, 0x9C, 0x6F, 0xD4, 0xFC, 0xE4, 0x93, - 0x4F, 0x32, 0x7E, 0xFC, 0x78, 0x06, 0x0C, 0x18, 0xC0, 0x8B, 0x2F, 0xBE, 0x48, 0x74, 0xD7, 0x9B, - 0x48, 0xFD, 0xF9, 0x78, 0xD3, 0x76, 0x30, 0x07, 0x98, 0xCC, 0x35, 0xEC, 0x3D, 0x72, 0xAA, 0x51, - 0xDB, 0x98, 0x31, 0x63, 0x78, 0xFC, 0xF1, 0xC7, 0x89, 0x8B, 0x8B, 0xE3, 0xB1, 0xC7, 0x1E, 0x63, - 0xC2, 0x84, 0x09, 0xA4, 0x1F, 0x3B, 0x4D, 0x71, 0x59, 0xE5, 0x35, 0x66, 0x9D, 0x42, 0xBF, 0xB8, - 0x9B, 0x70, 0xD7, 0xEB, 0x38, 0x7E, 0xFC, 0x38, 0xE5, 0xE5, 0xE5, 0xCD, 0xDE, 0xDB, 0x59, 0x8C, - 0x1A, 0x35, 0x8A, 0xEE, 0xDD, 0xEB, 0x73, 0x7E, 0x74, 0xC0, 0x44, 0x15, 0xB9, 0x5B, 0xBC, 0xDB, - 0xDE, 0xDA, 0xB7, 0x6F, 0x5F, 0x46, 0x8F, 0x1E, 0xDD, 0xA6, 0x1B, 0x59, 0x2C, 0x16, 0x8E, 0x1E, - 0x3D, 0x2A, 0xFB, 0xEB, 0x11, 0xD3, 0xBC, 0x46, 0xA3, 0x80, 0xB9, 0xD6, 0x42, 0xAD, 0xA5, 0xF1, - 0xDB, 0x27, 0x1C, 0xB4, 0x32, 0x21, 0x04, 0x08, 0x41, 0xB5, 0xB9, 0x06, 0xAD, 0x39, 0x6D, 0x4D, - 0x01, 0xAB, 0x55, 0xC3, 0x5C, 0xD3, 0xF8, 0xCD, 0xB7, 0x58, 0x2C, 0xF5, 0x9A, 0x92, 0xA6, 0x69, - 0xD4, 0xD6, 0xD6, 0x52, 0x6B, 0xA9, 0xA3, 0xCE, 0x6A, 0x6D, 0xDA, 0xAA, 0x27, 0x34, 0x62, 0x23, - 0x43, 0x09, 0x35, 0xFA, 0x93, 0x9D, 0x9D, 0x4D, 0x4A, 0x4A, 0x0A, 0x15, 0x15, 0x15, 0x8D, 0xC6, - 0xD6, 0x52, 0x54, 0x57, 0x57, 0x93, 0x9E, 0x9E, 0xCE, 0xFB, 0xEF, 0xBF, 0x7F, 0x79, 0xE0, 0x5D, - 0x92, 0x1E, 0x48, 0x44, 0x66, 0xCA, 0x02, 0x70, 0xF7, 0xDD, 0x77, 0x13, 0x1C, 0xDC, 0x22, 0x9F, - 0xCA, 0x15, 0xA8, 0xA8, 0xA8, 0xE0, 0xCC, 0x99, 0x33, 0x78, 0xB8, 0xEB, 0xE9, 0x19, 0x13, 0x4E, - 0xB3, 0x1B, 0x10, 0x21, 0x08, 0x0F, 0x0A, 0x20, 0xD4, 0xE8, 0x47, 0x45, 0x55, 0x83, 0x75, 0x7A, - 0xD1, 0xA2, 0x45, 0x44, 0x44, 0x44, 0x10, 0x15, 0x15, 0xC5, 0x87, 0x1F, 0x7E, 0xC8, 0xE9, 0xAC, - 0xD3, 0x3C, 0x3C, 0xA2, 0x9F, 0xB4, 0xCC, 0x5E, 0x6B, 0x61, 0x17, 0xE0, 0xE5, 0x61, 0xA0, 0x47, - 0x74, 0x38, 0xBB, 0x0E, 0x36, 0x58, 0x5C, 0x37, 0x6E, 0xDC, 0xC8, 0xDC, 0xB9, 0x73, 0x19, 0x33, - 0x66, 0x0C, 0x3B, 0x76, 0xEC, 0xE0, 0xBB, 0xEF, 0xD6, 0x31, 0xA0, 0x47, 0x24, 0x81, 0xBE, 0xDE, - 0x4D, 0x0F, 0x51, 0x40, 0xA8, 0xD1, 0x9F, 0xAE, 0x11, 0x21, 0xA4, 0x1E, 0x38, 0xC1, 0x6F, 0x7F, - 0xFB, 0x5B, 0x12, 0x12, 0x12, 0x18, 0x32, 0x64, 0x08, 0x83, 0x07, 0x0F, 0xA6, 0x7B, 0xF7, 0xEE, - 0x44, 0x45, 0x45, 0x11, 0x18, 0x18, 0x88, 0xC1, 0x60, 0x40, 0xA7, 0xD3, 0xD5, 0x6F, 0x9E, 0x35, - 0x4D, 0xC3, 0x62, 0xB1, 0x50, 0x5D, 0x5D, 0x4D, 0x71, 0x71, 0x31, 0xA7, 0x4F, 0x9F, 0x26, 0x2D, - 0x2D, 0x8D, 0x94, 0x94, 0x14, 0x32, 0x32, 0x32, 0x28, 0x2E, 0xBE, 0xC2, 0xE8, 0x9B, 0xAB, 0x47, - 0xAA, 0xB9, 0x46, 0x00, 0x6F, 0x6F, 0x6F, 0x46, 0x8C, 0x18, 0xD1, 0x26, 0x66, 0x00, 0x14, 0x14, - 0x14, 0x90, 0x97, 0x9F, 0x4F, 0x90, 0xBF, 0x2F, 0x51, 0xA1, 0xC6, 0xE6, 0x37, 0x84, 0x9A, 0xA0, - 0x4B, 0x58, 0x10, 0xE3, 0x6E, 0x1F, 0xC8, 0x3F, 0x97, 0xAF, 0xAF, 0x6F, 0x3E, 0x7C, 0xF8, 0x30, - 0x0F, 0x3F, 0xFC, 0x30, 0xEE, 0xEE, 0xEE, 0x94, 0x57, 0x54, 0x10, 0x66, 0xF4, 0x63, 0xC2, 0xF0, - 0x41, 0x4E, 0x8D, 0x41, 0x75, 0xD3, 0x31, 0x69, 0xF4, 0xAD, 0xAC, 0xD9, 0xBA, 0x87, 0x4B, 0x36, - 0xBF, 0x4A, 0x65, 0x65, 0x25, 0xAF, 0xBD, 0xF6, 0x1A, 0x73, 0xE6, 0xCC, 0xA1, 0xBA, 0xBA, 0x1A, - 0x10, 0x3C, 0x74, 0xC7, 0x6D, 0xF8, 0xF8, 0x78, 0x35, 0xCD, 0x60, 0x21, 0xF0, 0xF1, 0xF2, 0x20, - 0xBE, 0x6B, 0x24, 0xA9, 0x07, 0x4E, 0x50, 0x5E, 0x5E, 0xCE, 0x9E, 0x3D, 0x7B, 0xD8, 0xB3, 0x67, - 0x0F, 0x3A, 0x9D, 0x0E, 0x1F, 0x1F, 0x1F, 0x42, 0x42, 0x42, 0x88, 0x88, 0x88, 0x20, 0x28, 0x28, - 0x08, 0x5F, 0x5F, 0x5F, 0x0C, 0x06, 0x03, 0x9A, 0xA6, 0x51, 0x5D, 0x5D, 0x4D, 0x59, 0x59, 0x19, - 0x85, 0x85, 0x85, 0x14, 0x14, 0x14, 0x50, 0x52, 0x52, 0xD2, 0x94, 0x09, 0x46, 0x43, 0x66, 0xF6, - 0xBE, 0xAA, 0x47, 0x3A, 0xE8, 0x55, 0x80, 0x2E, 0x5D, 0xBA, 0x90, 0x90, 0x90, 0xD0, 0x6A, 0x46, - 0x98, 0xCD, 0x66, 0x32, 0x32, 0x32, 0x58, 0xB8, 0x70, 0x21, 0x45, 0x85, 0x45, 0x0C, 0x4C, 0x88, - 0x25, 0xC8, 0xDF, 0xD7, 0xA9, 0x0D, 0xA1, 0xAA, 0x53, 0x99, 0xF9, 0xC8, 0x3D, 0x1C, 0x3C, 0x79, - 0x96, 0x6D, 0xE9, 0x47, 0xEA, 0xDB, 0x4D, 0x26, 0x13, 0x26, 0x93, 0x09, 0x1F, 0x4F, 0x0F, 0x66, - 0x3F, 0x76, 0x1F, 0x37, 0xF7, 0xEE, 0xEE, 0x9C, 0xDA, 0x6B, 0xD5, 0xB8, 0xEB, 0xB6, 0xFE, 0x3C, - 0x9D, 0x7C, 0x37, 0xF3, 0x3E, 0x5F, 0x47, 0x8D, 0x6D, 0xE1, 0xB6, 0x5A, 0xAD, 0x54, 0x56, 0x56, - 0xA2, 0x53, 0x55, 0x7E, 0x33, 0x6E, 0x38, 0x53, 0xC6, 0x0D, 0x6B, 0x76, 0x7C, 0x8A, 0x4E, 0x27, - 0x35, 0xC5, 0xCB, 0x6F, 0x61, 0xB5, 0x52, 0x5E, 0x5E, 0x4E, 0x79, 0x79, 0x39, 0xA7, 0x4E, 0x9D, - 0xA2, 0x15, 0xA8, 0x46, 0x46, 0x79, 0xAE, 0x04, 0xD6, 0x00, 0xE7, 0xF5, 0xC8, 0x48, 0x09, 0x40, - 0x9A, 0x8C, 0x5B, 0x2A, 0xAE, 0xEA, 0xEA, 0xEA, 0x38, 0x7F, 0xFE, 0x3C, 0x5B, 0xB7, 0x6E, 0x65, - 0xCD, 0x9A, 0x35, 0xEC, 0xDA, 0xB5, 0xAB, 0x5E, 0x2E, 0x46, 0x04, 0x07, 0xE0, 0xED, 0x61, 0x70, - 0x6E, 0x87, 0xAE, 0x09, 0x6E, 0x8A, 0x0A, 0xE5, 0xE3, 0x3F, 0x3D, 0xC9, 0x3F, 0x97, 0xAF, 0x67, - 0xDD, 0xCE, 0x74, 0x8A, 0x4A, 0x2B, 0x70, 0x73, 0xD3, 0xD3, 0x3B, 0xB6, 0x0B, 0xBF, 0x7B, 0x70, - 0x0C, 0xF7, 0x8F, 0xBA, 0x15, 0x55, 0x55, 0x9C, 0x36, 0xC1, 0xB8, 0xBB, 0xB9, 0xF1, 0xF2, 0xE3, - 0x0F, 0xD2, 0xA3, 0x4B, 0x38, 0x1F, 0x7D, 0xB7, 0x8D, 0x53, 0xE7, 0xF2, 0xD1, 0x34, 0x8D, 0xE8, - 0xB0, 0x20, 0x92, 0xEF, 0x1C, 0xCA, 0xB4, 0x89, 0xA3, 0xF1, 0x6F, 0xCE, 0x37, 0x63, 0x43, 0xD7, - 0x88, 0x10, 0x74, 0x3A, 0x15, 0xAB, 0x54, 0x28, 0x34, 0xA4, 0x93, 0xC9, 0x1B, 0x59, 0xC0, 0xC6, - 0x59, 0x33, 0x42, 0x1D, 0x32, 0x0E, 0xE1, 0x14, 0x32, 0x38, 0xE4, 0x47, 0x64, 0xD8, 0x54, 0x99, - 0xFD, 0x1F, 0xF4, 0x38, 0xD8, 0xE5, 0x2D, 0x16, 0x0B, 0x07, 0x0F, 0x1E, 0x24, 0x2A, 0x2A, 0x0A, - 0x3F, 0x3F, 0x3F, 0x0C, 0x06, 0x03, 0xAA, 0xCD, 0x17, 0xA1, 0x69, 0x1A, 0x75, 0x75, 0x75, 0x98, - 0x4C, 0x26, 0x4A, 0x4B, 0x4B, 0xC9, 0xCE, 0xCE, 0xE6, 0xC0, 0x81, 0x03, 0xEC, 0xDE, 0xBD, 0x9B, - 0x7D, 0xFB, 0xF6, 0x71, 0xEE, 0xDC, 0xB9, 0x2B, 0xEA, 0x94, 0x44, 0x86, 0x04, 0xE2, 0xEE, 0xD6, - 0x82, 0x68, 0x7D, 0x4D, 0xD0, 0x35, 0x32, 0x84, 0xB7, 0x9E, 0x99, 0xC2, 0xAC, 0xC9, 0xE3, 0x29, - 0xBC, 0x58, 0x8E, 0xC1, 0xDD, 0x8D, 0xE8, 0xB0, 0x20, 0x7C, 0x7D, 0xBC, 0x6D, 0x8E, 0x29, 0xE7, - 0xBB, 0x43, 0x08, 0x3C, 0x0D, 0x6E, 0x4C, 0xBD, 0x6F, 0x34, 0x93, 0x46, 0x0F, 0x21, 0xBF, 0xF8, - 0x22, 0x56, 0x4D, 0x10, 0x16, 0xE4, 0x4F, 0xA0, 0xBF, 0xAF, 0xA4, 0xA2, 0x53, 0x8B, 0xB3, 0x5C, - 0xE3, 0x3C, 0xDD, 0xDD, 0xB9, 0x24, 0xD5, 0xF2, 0x3A, 0xE0, 0x0F, 0xC8, 0x52, 0x4E, 0x7D, 0x80, - 0x18, 0x64, 0x5C, 0x5A, 0x28, 0x32, 0x11, 0x54, 0x8F, 0xD4, 0x9A, 0xAA, 0x6D, 0xC4, 0x2E, 0x45, - 0xC6, 0x6F, 0x1D, 0x47, 0x56, 0x27, 0x3A, 0x8B, 0x2C, 0x6C, 0x73, 0xC5, 0xCD, 0xF5, 0x38, 0x64, - 0x92, 0x6E, 0xDC, 0xB8, 0x91, 0x3D, 0x7B, 0xF6, 0x10, 0x1A, 0x1A, 0x4A, 0x68, 0x68, 0x28, 0x46, - 0xA3, 0x11, 0x2F, 0x2F, 0x2F, 0x54, 0x55, 0xA5, 0xB6, 0xB6, 0x96, 0xCA, 0xCA, 0x4A, 0x8A, 0x8B, - 0x8B, 0x29, 0x2C, 0x2C, 0xA4, 0xA4, 0xA4, 0x04, 0x93, 0xC9, 0x74, 0x4D, 0x6D, 0x23, 0x24, 0xD0, - 0x5F, 0x6A, 0x58, 0x2D, 0x31, 0x77, 0x68, 0x02, 0x9D, 0xA2, 0x10, 0x15, 0x16, 0x44, 0x54, 0x78, - 0x70, 0x3D, 0x61, 0x5B, 0x6D, 0xB6, 0x17, 0x80, 0xD0, 0xF0, 0xF3, 0xF1, 0xC2, 0xCF, 0xD7, 0xBB, - 0xA1, 0xBF, 0x96, 0x68, 0x49, 0x02, 0x42, 0x02, 0xFD, 0xF0, 0xF5, 0xF6, 0xB0, 0x33, 0xC4, 0x1D, - 0x39, 0x4B, 0x76, 0xD8, 0x7E, 0x20, 0x67, 0x89, 0x3B, 0x52, 0xFC, 0xEB, 0x6C, 0xC7, 0x16, 0x1B, - 0xF3, 0x9C, 0xAE, 0x6C, 0xA7, 0x07, 0x7E, 0x02, 0x46, 0x83, 0xD4, 0x0A, 0xCA, 0xCA, 0xCA, 0x28, - 0x2B, 0x2B, 0xE3, 0xE4, 0xC9, 0x93, 0x2D, 0x7D, 0xF4, 0x3A, 0xE0, 0x02, 0xD2, 0xCB, 0xE8, 0x09, - 0x10, 0xE4, 0xEF, 0xD3, 0x7A, 0xA3, 0x60, 0x4B, 0x89, 0xE6, 0xCA, 0xFE, 0x84, 0x20, 0xD0, 0xD7, - 0x9B, 0x40, 0x3F, 0x1F, 0xF2, 0x8A, 0xCB, 0xEC, 0xAD, 0x51, 0x97, 0xFF, 0x17, 0xD2, 0x6F, 0xDE, - 0x26, 0xE8, 0x91, 0x36, 0xF9, 0x67, 0x80, 0xE1, 0xC8, 0xCD, 0xA1, 0x0F, 0xCE, 0xC9, 0xC4, 0x3A, - 0xE4, 0xB4, 0xCB, 0x46, 0xCA, 0xC1, 0x6D, 0xC0, 0x79, 0x64, 0x15, 0xB7, 0xAE, 0x00, 0x7E, 0xDE, - 0xED, 0x9A, 0xED, 0xD5, 0x89, 0x10, 0x78, 0x7B, 0x7A, 0x60, 0xF4, 0xF3, 0x71, 0x6C, 0x0C, 0x72, - 0xC5, 0x9D, 0xF4, 0x48, 0xB9, 0xF6, 0x7B, 0x64, 0x40, 0x57, 0x37, 0xE4, 0xBE, 0xA4, 0x2B, 0xD2, - 0x14, 0x1F, 0x8C, 0x9C, 0x86, 0x3A, 0xA4, 0x65, 0xB0, 0x0C, 0x29, 0x0F, 0xCF, 0x03, 0x27, 0x69, - 0x90, 0x87, 0x17, 0x91, 0x6F, 0x48, 0x4F, 0x1C, 0xEA, 0x61, 0x79, 0x7A, 0x18, 0x3A, 0xAF, 0x88, - 0x60, 0x7B, 0x42, 0x80, 0x9B, 0x5E, 0x87, 0xBF, 0x4F, 0x23, 0x43, 0x6B, 0xDB, 0x4C, 0x19, 0x4D, - 0xC0, 0xBE, 0xE2, 0xD6, 0x21, 0x6B, 0x1E, 0xE6, 0x03, 0x76, 0x4F, 0x8C, 0x62, 0x3B, 0xEF, 0xB8, - 0xCD, 0xAE, 0xE3, 0xDA, 0x26, 0x5B, 0x9D, 0xFD, 0xFF, 0x55, 0x45, 0xC1, 0x5D, 0xAF, 0xBB, 0xB1, - 0x9C, 0x52, 0xD7, 0x22, 0x94, 0x5E, 0x87, 0x6F, 0xE3, 0x19, 0xEF, 0x47, 0xC3, 0x8B, 0xDA, 0x7E, - 0xF7, 0xB9, 0xC6, 0x39, 0xC1, 0x2F, 0xB4, 0xD6, 0x60, 0x6B, 0xA0, 0x2A, 0x0A, 0x9E, 0x86, 0x46, - 0xB1, 0x67, 0x9E, 0xB8, 0x80, 0x21, 0xED, 0x9D, 0x63, 0x58, 0x3F, 0x1F, 0x84, 0x10, 0xD2, 0x3B, - 0xF7, 0x4B, 0x10, 0x59, 0x00, 0x8A, 0x82, 0xA1, 0xB1, 0x0A, 0x6F, 0xD7, 0xA4, 0xDA, 0x15, 0xED, - 0xCD, 0x90, 0x1A, 0xA0, 0x16, 0x40, 0x13, 0x82, 0x6A, 0x73, 0xED, 0x2F, 0x46, 0x64, 0x01, 0x97, - 0x07, 0x78, 0xDC, 0x30, 0x0C, 0x31, 0xD9, 0x0F, 0x2A, 0xAA, 0x4C, 0x6D, 0xE8, 0xEA, 0x3A, 0x83, - 0x10, 0xD2, 0x2A, 0xDC, 0x00, 0x0D, 0x17, 0xBC, 0x6E, 0xED, 0xCD, 0x10, 0x13, 0xB2, 0xCE, 0x09, - 0x00, 0x45, 0xA5, 0xE5, 0xAE, 0x8F, 0x32, 0xEC, 0x20, 0x08, 0x21, 0x30, 0x35, 0x36, 0xE7, 0x9B, - 0x70, 0x41, 0x35, 0x39, 0x57, 0x30, 0xA4, 0xBE, 0x70, 0xC0, 0x85, 0xE2, 0x8B, 0x88, 0x1B, 0x21, - 0x30, 0xCE, 0x09, 0x58, 0x35, 0x8D, 0x4B, 0xD5, 0x8D, 0x66, 0xFC, 0x0D, 0xC1, 0x90, 0x1A, 0x1C, - 0x82, 0x88, 0xCF, 0xE6, 0x15, 0x61, 0x32, 0xB7, 0x79, 0xF3, 0xDA, 0xF9, 0x50, 0xA0, 0xA6, 0xB6, - 0x8E, 0x92, 0xF2, 0x4B, 0x8E, 0xAD, 0xC5, 0xDC, 0x00, 0x22, 0x0B, 0xE4, 0x66, 0x11, 0x80, 0x9C, - 0xFC, 0x62, 0xF9, 0x10, 0x6D, 0x89, 0xA9, 0xBA, 0x2E, 0xA0, 0x70, 0xC9, 0x64, 0x96, 0xAE, 0xDE, - 0x06, 0xB4, 0x7B, 0xF1, 0x32, 0x70, 0x5D, 0x69, 0x8D, 0x5A, 0x80, 0xFC, 0x92, 0x32, 0x4E, 0x9D, - 0xCB, 0x77, 0x2E, 0x28, 0xE1, 0x7A, 0x86, 0xA2, 0x50, 0x50, 0x5A, 0x4E, 0x51, 0x43, 0x34, 0x8C, - 0x40, 0x5A, 0x2B, 0xDA, 0x1D, 0xAE, 0x60, 0xC8, 0x49, 0x64, 0x26, 0x2A, 0x55, 0xA6, 0x2B, 0x03, - 0x0D, 0x6E, 0x48, 0x28, 0x0A, 0xA7, 0xCE, 0xE5, 0x53, 0x7E, 0xA9, 0xDE, 0xBD, 0x5C, 0x89, 0xF4, - 0x69, 0xB4, 0x3B, 0x5C, 0xC1, 0x90, 0x73, 0xC8, 0xCF, 0x4E, 0x00, 0xB0, 0x65, 0xDF, 0x61, 0xAA, - 0xAB, 0xCD, 0x9D, 0xBF, 0x41, 0x54, 0x14, 0x19, 0x92, 0xDA, 0x9A, 0x28, 0x4C, 0x21, 0xD8, 0x77, - 0xE4, 0x14, 0x96, 0xBA, 0xFA, 0x35, 0x3C, 0x1F, 0x69, 0xC3, 0x6B, 0x77, 0xB8, 0x82, 0x21, 0x26, - 0xE4, 0x57, 0x6E, 0x00, 0x48, 0x3F, 0x96, 0xC5, 0xE1, 0x53, 0x39, 0xAD, 0x23, 0x84, 0x1D, 0x8A, - 0xD2, 0x40, 0xD0, 0x96, 0xAE, 0x47, 0x0A, 0xA0, 0xD3, 0x51, 0x71, 0xA9, 0x9A, 0x9D, 0xE9, 0x47, - 0x39, 0x9E, 0xD5, 0xC2, 0x4F, 0x82, 0x28, 0x0A, 0xE5, 0x95, 0x97, 0xD8, 0x91, 0x71, 0xDC, 0xB1, - 0xF5, 0x20, 0x36, 0x29, 0xD0, 0xDE, 0x70, 0xD5, 0x67, 0x18, 0x36, 0xDB, 0x06, 0x1C, 0x52, 0x52, - 0x5E, 0xC9, 0xAA, 0x4D, 0xBB, 0x19, 0xDC, 0xA7, 0xF5, 0x51, 0x90, 0xCB, 0x37, 0xEC, 0x64, 0xF7, - 0xA1, 0x4C, 0x46, 0xDF, 0xD2, 0x87, 0x61, 0x03, 0x7B, 0x39, 0x9F, 0xE8, 0xA9, 0x28, 0x54, 0x9B, - 0x6B, 0xF8, 0xF1, 0xA7, 0x03, 0x2C, 0x59, 0xB3, 0x91, 0xED, 0xFB, 0x8F, 0xD2, 0x3B, 0x36, 0x9A, - 0xB5, 0xF3, 0x9E, 0x27, 0x2A, 0x2C, 0xC8, 0xB9, 0x3D, 0x92, 0xAA, 0xB0, 0xF7, 0xC8, 0x69, 0x0E, - 0x64, 0x66, 0xDB, 0x5B, 0x84, 0xED, 0xF9, 0x5C, 0x62, 0xE7, 0x73, 0x55, 0x8D, 0x8E, 0x12, 0x64, - 0xAC, 0x70, 0x1F, 0x80, 0x0B, 0xC5, 0xA5, 0x8C, 0x1D, 0xD2, 0x8F, 0x90, 0xA0, 0x80, 0x96, 0x6D, - 0x14, 0x6D, 0x8B, 0xE9, 0xF4, 0xD7, 0xDF, 0xE7, 0xDB, 0x94, 0x34, 0xD6, 0x6E, 0xDF, 0xC7, 0xB6, - 0xB4, 0x23, 0x18, 0xFD, 0x7C, 0xE8, 0xD9, 0x35, 0xB2, 0xE9, 0x98, 0x5C, 0xDB, 0xB5, 0x85, 0x17, - 0xCB, 0xF9, 0xDF, 0x7F, 0x7C, 0xC6, 0x6B, 0xEF, 0x7F, 0xC5, 0xB1, 0xEC, 0x5C, 0x2C, 0x75, 0x56, - 0xAA, 0xCC, 0x35, 0xDC, 0x3F, 0x62, 0x30, 0x51, 0xE1, 0xCE, 0x31, 0xA4, 0xCE, 0x6A, 0xE5, 0x8D, - 0x65, 0xFF, 0x62, 0xEF, 0xE1, 0xFA, 0x25, 0xE3, 0x3C, 0x32, 0x13, 0xB9, 0xB8, 0xD9, 0x8B, 0x5B, - 0x01, 0x57, 0xD5, 0xDF, 0xAB, 0x45, 0x3A, 0xAA, 0xAA, 0x01, 0xB2, 0x2F, 0x14, 0xB1, 0x74, 0xED, - 0x16, 0xB4, 0x56, 0x84, 0x61, 0x6A, 0x9A, 0x46, 0x8D, 0x45, 0x7A, 0x40, 0xCD, 0x35, 0xB5, 0xA4, - 0x1E, 0x38, 0xC1, 0xB4, 0x3F, 0x2D, 0xE6, 0x93, 0xEF, 0xB6, 0x35, 0xBD, 0x2E, 0xD9, 0x66, 0xC6, - 0x4B, 0x0B, 0x97, 0xB3, 0x74, 0xED, 0x16, 0xCC, 0x0E, 0xA1, 0xA2, 0x31, 0xE1, 0xC1, 0x44, 0x85, - 0x19, 0x9B, 0x8F, 0xC4, 0x07, 0xD0, 0xA9, 0xEC, 0x3B, 0x72, 0x8A, 0x75, 0x3B, 0xD2, 0x1D, 0x5B, - 0xBF, 0x47, 0xFA, 0xD2, 0x5D, 0x02, 0x57, 0x16, 0x44, 0xDC, 0x82, 0x8C, 0xAA, 0x00, 0xE0, 0xCB, - 0xEF, 0x77, 0xB0, 0xEB, 0xE0, 0x49, 0xB9, 0x0E, 0x38, 0x0B, 0x21, 0x08, 0x33, 0x06, 0x70, 0xD7, - 0x6D, 0xFD, 0xEB, 0x9B, 0xBC, 0x3D, 0x0D, 0x18, 0xDC, 0xDD, 0x78, 0xE5, 0xDD, 0x15, 0xEC, 0xFC, - 0xF9, 0xC4, 0xD5, 0xD7, 0x26, 0x45, 0x61, 0xD5, 0xC6, 0x9F, 0xF8, 0xF4, 0xDF, 0xDB, 0x19, 0x79, - 0x73, 0x62, 0xFD, 0xF5, 0xC1, 0x01, 0xBE, 0x3C, 0x3F, 0xE5, 0x5E, 0x19, 0x6B, 0xEC, 0x44, 0xF4, - 0xA3, 0xD9, 0x5C, 0xC3, 0xA2, 0xAF, 0x7E, 0xA0, 0xE8, 0x62, 0x85, 0xBD, 0xB5, 0x14, 0x17, 0x7F, - 0xD8, 0xC5, 0x95, 0x65, 0x85, 0x2C, 0x48, 0xD1, 0x75, 0x2F, 0xE0, 0x51, 0x65, 0xAA, 0xA1, 0xE8, - 0x62, 0x05, 0xF7, 0x0C, 0x1D, 0x88, 0x87, 0xC1, 0xF9, 0xA2, 0x39, 0x8A, 0xAA, 0x92, 0xD4, 0xB3, - 0x2B, 0x25, 0x65, 0x95, 0x14, 0x94, 0x94, 0x73, 0xEF, 0xF0, 0x9B, 0x99, 0xFD, 0xD8, 0x44, 0xBE, - 0x4D, 0x49, 0x27, 0x33, 0x27, 0x8F, 0x7B, 0x87, 0x0D, 0xC2, 0xE0, 0xD8, 0x9F, 0xA2, 0x90, 0x5B, - 0x58, 0xC2, 0xEF, 0xDF, 0x5A, 0x86, 0x5E, 0xA7, 0x63, 0xD9, 0x1F, 0x9F, 0xE0, 0x81, 0x91, 0xB7, - 0x12, 0xDF, 0x35, 0x82, 0x19, 0x0F, 0x8F, 0x63, 0xDC, 0xED, 0x03, 0x9D, 0xDB, 0x16, 0xE9, 0x54, - 0x56, 0x6F, 0xDA, 0xCD, 0x9C, 0x8F, 0xBF, 0x71, 0xD4, 0xAE, 0xBE, 0x44, 0x7E, 0x15, 0xC1, 0x65, - 0xF6, 0x20, 0x57, 0xD7, 0x79, 0x3A, 0x87, 0x0C, 0x33, 0x1A, 0x0C, 0x70, 0xE6, 0x42, 0x21, 0x46, - 0x3F, 0x6F, 0x7E, 0x95, 0x14, 0xD7, 0x22, 0x2D, 0xD8, 0xD7, 0xDB, 0x8B, 0x3B, 0x6F, 0xEB, 0xCF, - 0x83, 0xA3, 0x87, 0x30, 0x69, 0xF4, 0x10, 0x92, 0xE2, 0x63, 0x11, 0x42, 0xE3, 0x93, 0x75, 0xDB, - 0xE9, 0xD3, 0x3D, 0x9A, 0xC4, 0x9E, 0x31, 0x0D, 0x6F, 0xBC, 0x4E, 0xE5, 0x8B, 0x7F, 0xA7, 0xF0, - 0xD9, 0xFA, 0x14, 0x5E, 0xFD, 0xAF, 0x87, 0xB8, 0x7F, 0xD4, 0xAD, 0x04, 0xFA, 0x7B, 0x73, 0x4B, - 0xDF, 0x38, 0x62, 0x22, 0x42, 0x9C, 0x13, 0x09, 0xAA, 0xCA, 0x89, 0xEC, 0x5C, 0x9E, 0x7A, 0x6B, - 0x19, 0xB9, 0x85, 0xF5, 0xB1, 0xB7, 0x39, 0xC0, 0xB3, 0x34, 0x91, 0x5F, 0xDE, 0x5E, 0x70, 0x35, - 0x43, 0x34, 0xE4, 0x46, 0x71, 0x14, 0x10, 0xAA, 0x69, 0x82, 0x03, 0x27, 0xCF, 0xD2, 0x3F, 0x3E, - 0x96, 0xEE, 0x31, 0x11, 0x2D, 0x5A, 0xE0, 0xDD, 0x74, 0x3A, 0x8C, 0x81, 0x7E, 0x78, 0xB8, 0xCB, - 0x0C, 0xE0, 0xB8, 0xAE, 0x91, 0x6C, 0xDE, 0x7B, 0x88, 0xFC, 0x92, 0x8B, 0xDC, 0x3F, 0xE2, 0x96, - 0xFA, 0x05, 0xBE, 0xB6, 0xD6, 0xC2, 0x5F, 0x96, 0x7E, 0x8D, 0x97, 0x87, 0x81, 0x37, 0x9F, 0xFE, - 0x0D, 0x3E, 0x9E, 0x86, 0x86, 0x88, 0x13, 0x67, 0xEE, 0xA7, 0x28, 0x94, 0x55, 0x56, 0xF1, 0xEC, - 0xDF, 0x3F, 0x61, 0x6B, 0x5A, 0x7D, 0x04, 0xA5, 0x15, 0xF9, 0x71, 0x81, 0xD5, 0x2E, 0xA6, 0x57, - 0x87, 0xD4, 0x2E, 0x3F, 0x8D, 0xAC, 0x04, 0x51, 0x09, 0x50, 0x50, 0x2A, 0x35, 0x9F, 0xA3, 0xA7, - 0x72, 0x5A, 0xB6, 0x9E, 0x40, 0x43, 0x05, 0x07, 0x21, 0x08, 0x31, 0xFA, 0xF3, 0xDB, 0x09, 0x23, - 0x38, 0x73, 0xA1, 0x88, 0xCA, 0x2A, 0x53, 0xFD, 0x5E, 0xA5, 0xFC, 0x52, 0x35, 0x39, 0xF9, 0xC5, - 0xFC, 0xE7, 0xD8, 0xDB, 0x08, 0x0B, 0x0E, 0x68, 0xB1, 0x56, 0x67, 0xAE, 0xAD, 0xE5, 0xAF, 0x4B, - 0x57, 0xB3, 0x7A, 0xF3, 0x1E, 0xC7, 0x33, 0xDF, 0x21, 0x4B, 0x2E, 0xB9, 0x1C, 0x1D, 0x55, 0xE5, - 0x78, 0x35, 0xF0, 0x1E, 0x36, 0xEB, 0xE8, 0xCF, 0x27, 0xB2, 0x99, 0x31, 0xF7, 0x23, 0x72, 0x72, - 0x0B, 0x5B, 0xBF, 0x61, 0x14, 0x82, 0x31, 0x43, 0xFA, 0xD1, 0x2D, 0x2A, 0x94, 0x3A, 0x87, 0x7C, - 0x91, 0x3A, 0xAB, 0x95, 0x40, 0x3F, 0x1F, 0xC6, 0xDE, 0x9A, 0xD4, 0x32, 0x5B, 0xAC, 0xA2, 0x60, - 0xAE, 0xB5, 0x30, 0xE7, 0xA3, 0xB5, 0x2C, 0xFC, 0x6A, 0x83, 0x74, 0x3F, 0x4B, 0x1C, 0x01, 0x5E, - 0xC1, 0x21, 0xDC, 0xD3, 0x95, 0xE8, 0xA8, 0x5A, 0x81, 0x1A, 0x90, 0x81, 0x0C, 0x13, 0xEA, 0x05, - 0x90, 0x95, 0x5B, 0xC8, 0xC9, 0xB3, 0x17, 0xB8, 0xBD, 0x7F, 0x82, 0x73, 0xE5, 0x36, 0x2E, 0x87, - 0x00, 0x7F, 0x1F, 0x4F, 0x06, 0x27, 0xF6, 0x20, 0xD4, 0xE8, 0x57, 0x2F, 0xB2, 0xF4, 0x3A, 0x1D, - 0x91, 0x21, 0x46, 0x6E, 0xE9, 0xDD, 0x1D, 0x37, 0x9D, 0x93, 0x8F, 0xA7, 0xAA, 0x54, 0x56, 0x9B, - 0xF9, 0xDB, 0xD2, 0xD5, 0xCC, 0xFD, 0xFC, 0xBB, 0xFA, 0xC0, 0x6C, 0x64, 0xE0, 0xDF, 0x13, 0xC8, - 0x60, 0xC2, 0x0E, 0x41, 0x47, 0x16, 0x6F, 0xAC, 0x46, 0x7E, 0x65, 0x73, 0x10, 0x32, 0x16, 0x96, - 0xCC, 0x73, 0xF9, 0x1C, 0x3A, 0x95, 0xC3, 0xA0, 0x84, 0x6E, 0x84, 0xB6, 0x54, 0xBC, 0x20, 0x23, - 0x41, 0x02, 0xFC, 0x7D, 0x1A, 0x6D, 0x10, 0xDD, 0xF4, 0x3A, 0xE2, 0x6E, 0x8A, 0x72, 0x9E, 0x19, - 0x3A, 0x95, 0xF3, 0xF9, 0xC5, 0xBC, 0xF0, 0xCF, 0xCF, 0x79, 0x77, 0xF5, 0x8F, 0xD4, 0x5A, 0xEA, - 0xA3, 0x3E, 0x8B, 0x90, 0x45, 0x62, 0xBE, 0xE9, 0x40, 0x1A, 0x75, 0x78, 0x35, 0xCD, 0x8B, 0x48, - 0xA6, 0x0C, 0xC4, 0x96, 0x42, 0x77, 0x26, 0xB7, 0x90, 0x9D, 0x3F, 0x1F, 0x27, 0x36, 0x3C, 0x84, - 0xD8, 0xE8, 0xF0, 0x6B, 0xEF, 0xBE, 0xAF, 0x86, 0xAB, 0xF1, 0xD0, 0x49, 0x93, 0x88, 0x26, 0x20, - 0x25, 0xED, 0x08, 0x4F, 0xCE, 0x59, 0xCA, 0xB7, 0xDB, 0xD3, 0xB0, 0x36, 0x6C, 0x16, 0x0B, 0x90, - 0xCC, 0x58, 0xD1, 0xC1, 0xF4, 0xE9, 0x94, 0xF2, 0xA6, 0x85, 0xC8, 0x4F, 0x6B, 0xF7, 0xC5, 0x16, - 0x72, 0x5A, 0x50, 0x5A, 0xCE, 0x86, 0x9F, 0x7E, 0xA6, 0xA6, 0xA6, 0x96, 0x5E, 0x37, 0x45, 0xC9, - 0x04, 0x1A, 0x57, 0xC1, 0x66, 0xA4, 0xCC, 0x2D, 0x28, 0xE1, 0xEF, 0x9F, 0x7F, 0xC7, 0xEC, 0x05, - 0x5F, 0x34, 0xCA, 0xD2, 0x45, 0x2A, 0x21, 0x4F, 0x22, 0xF3, 0x35, 0x3A, 0x3C, 0x20, 0xA0, 0xB3, - 0xEA, 0xCD, 0x16, 0x21, 0x2D, 0xC2, 0x5D, 0x90, 0x5F, 0x8D, 0x56, 0x4D, 0xE6, 0x5A, 0x76, 0x64, - 0x1C, 0x27, 0xF5, 0xE7, 0xE3, 0xF8, 0x79, 0x79, 0x10, 0x13, 0x1E, 0x8C, 0xA1, 0xB9, 0x64, 0xD1, - 0x96, 0x40, 0x95, 0x96, 0xE2, 0xC2, 0xD2, 0x32, 0xBE, 0xF8, 0xF7, 0x0E, 0x9E, 0x7D, 0xE7, 0x13, - 0x56, 0x6D, 0xFC, 0xC9, 0x1E, 0xCD, 0x0E, 0x92, 0xF8, 0xDB, 0x91, 0xC5, 0x13, 0x5A, 0x57, 0xFE, - 0xA7, 0x1D, 0xD0, 0xD9, 0x5E, 0x8A, 0x40, 0xA4, 0x68, 0xF8, 0x3D, 0x0E, 0xDF, 0x3E, 0xF7, 0x34, - 0xB8, 0x33, 0x6C, 0x40, 0x2F, 0xA6, 0x8C, 0x1B, 0xCE, 0xE8, 0xC1, 0x7D, 0x09, 0x0F, 0x09, 0x40, - 0x51, 0x75, 0x36, 0x95, 0xD7, 0xC9, 0x1C, 0x11, 0x45, 0xB1, 0x79, 0x2A, 0x15, 0x6A, 0x6B, 0x6A, - 0x38, 0x95, 0x93, 0xCF, 0xBA, 0x9D, 0xE9, 0x7C, 0xB5, 0xF1, 0x27, 0x0E, 0x9C, 0x3C, 0x7B, 0x79, - 0x48, 0x4F, 0x39, 0xF0, 0x21, 0xF2, 0x23, 0x98, 0x2E, 0x71, 0xCD, 0x3A, 0x8B, 0xCE, 0x66, 0x08, - 0x48, 0x17, 0xC0, 0x9D, 0xC0, 0x8B, 0xC8, 0x62, 0xC4, 0xF5, 0xB3, 0xD6, 0x4D, 0xAF, 0x23, 0xBE, - 0x6B, 0x24, 0x23, 0x6F, 0xEE, 0xC3, 0xA8, 0x5B, 0x12, 0xE9, 0xD3, 0x3D, 0x86, 0x88, 0xE0, 0x40, - 0xBC, 0x3C, 0xDC, 0x1B, 0xAA, 0xCB, 0x35, 0x82, 0x00, 0x4D, 0x50, 0x6B, 0xB1, 0x50, 0x56, 0x51, - 0xC5, 0x99, 0x0B, 0x85, 0xEC, 0x3B, 0x7A, 0x9A, 0x2D, 0xFB, 0x0E, 0xB3, 0xFB, 0x50, 0x26, 0xF9, - 0x25, 0x65, 0x97, 0xE7, 0xB3, 0xD4, 0x21, 0x3F, 0xA5, 0x3A, 0x17, 0xF9, 0x01, 0xCC, 0x4E, 0x0F, - 0x9D, 0xBD, 0x1E, 0x18, 0x62, 0x47, 0x28, 0xB2, 0xB4, 0xC7, 0x34, 0xA4, 0x7A, 0xDC, 0x68, 0x6C, - 0xEE, 0x6E, 0x7A, 0x42, 0x8D, 0xFE, 0x74, 0x8B, 0x0C, 0x25, 0x36, 0x2A, 0x8C, 0x2E, 0xA1, 0x46, - 0x82, 0xFC, 0x7D, 0xF0, 0xF2, 0x34, 0xA0, 0x2A, 0x2A, 0xE6, 0x5A, 0x0B, 0x15, 0x97, 0xAA, 0xB9, - 0x50, 0x7C, 0x91, 0x9C, 0xFC, 0x62, 0xCE, 0xE4, 0x16, 0x72, 0xBE, 0xB0, 0x84, 0x8A, 0xAA, 0xAB, - 0x26, 0x15, 0xD5, 0x21, 0x93, 0x2C, 0x97, 0x02, 0x5F, 0x21, 0x8D, 0x86, 0xFF, 0x8F, 0xAB, 0x40, - 0x41, 0xA6, 0x44, 0xBC, 0x88, 0xDC, 0xB7, 0xD4, 0xD0, 0x82, 0xEF, 0xA2, 0x3B, 0xF1, 0x2B, 0x03, - 0x7E, 0x40, 0x32, 0x3D, 0xB4, 0xB3, 0x1F, 0xB6, 0x29, 0x02, 0x5C, 0xAF, 0x08, 0x45, 0xD6, 0x06, - 0xBE, 0x0B, 0xF8, 0x15, 0x72, 0xEF, 0xE2, 0x6C, 0x32, 0x91, 0x1D, 0x16, 0xA4, 0x23, 0xE9, 0x38, - 0x32, 0xA1, 0x68, 0x13, 0x72, 0x66, 0x54, 0x75, 0xF6, 0xC3, 0x35, 0x85, 0xEB, 0x99, 0x21, 0x76, - 0xE8, 0x90, 0x16, 0xE3, 0x3E, 0x48, 0xAB, 0x71, 0x5F, 0xA0, 0x07, 0x92, 0x61, 0x01, 0x34, 0xE4, - 0xF5, 0xD5, 0x22, 0x09, 0x5D, 0x8C, 0xF4, 0xEA, 0x1D, 0x45, 0xA6, 0x1C, 0x67, 0x20, 0x23, 0x44, - 0x2A, 0x5B, 0x76, 0xDB, 0xCE, 0xC1, 0xFF, 0x01, 0xCE, 0x34, 0xF5, 0xEC, 0x2D, 0xA9, 0x9C, 0xA8, - 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3A, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x32, 0x2D, 0x30, 0x31, 0x2D, 0x33, 0x31, 0x54, 0x31, - 0x33, 0x3A, 0x34, 0x31, 0x3A, 0x31, 0x38, 0x2D, 0x30, 0x38, 0x3A, 0x30, 0x30, 0xED, 0x4F, 0xCC, - 0x0D, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3A, 0x6D, 0x6F, - 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x32, 0x2D, 0x30, 0x31, 0x2D, 0x33, 0x31, 0x54, - 0x31, 0x33, 0x3A, 0x34, 0x31, 0x3A, 0x31, 0x38, 0x2D, 0x30, 0x38, 0x3A, 0x30, 0x30, 0x9C, 0x12, - 0x74, 0xB1, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, - 0x72, 0x65, 0x00, 0x77, 0x77, 0x77, 0x2E, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2E, - 0x6F, 0x72, 0x67, 0x9B, 0xEE, 0x3C, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, +#include + +static const uint8_t mu_law_wave[] PROGMEM = { +0x52, 0x49, 0x46, 0x46, 0x84, 0x5D, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20, +0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, +0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x66, 0x61, 0x63, 0x74, 0x04, 0x00, 0x00, 0x00, 0x00, 0x5D, +0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x5D, 0x00, 0x00, 0xFB, 0xFD, 0xFF, 0xFE, 0xFF, 0x7F, +0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7C, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7C, 0x7D, +0x7C, 0x7C, 0x7D, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7E, 0xFF, 0x7F, +0x7D, 0x7C, 0x7B, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7C, 0x7C, 0x7B, +0x7B, 0x7B, 0x7A, 0x7A, 0x7B, 0x7A, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x7C, 0x7E, +0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x79, 0x79, 0x7B, 0x7B, 0x7B, 0x7C, 0x7C, 0x7E, 0xFF, 0xFE, 0xFE, +0xFF, 0x7E, 0x7C, 0x7D, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x79, 0x78, 0x79, +0x7A, 0x79, 0x78, 0x78, 0x78, 0x77, 0x78, 0x78, 0x79, 0x79, 0x78, 0x77, 0x77, 0x78, 0x78, 0x79, +0x7A, 0x79, 0x79, 0x78, 0x78, 0x7A, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, +0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFC, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF8, 0xF8, +0xF7, 0xF7, 0xF8, 0xF9, 0xF9, 0xFB, 0xFC, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFE, +0xFF, 0xFF, 0xFE, 0x7E, 0x7D, 0x7D, 0x7C, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x7C, +0x7B, 0x7A, 0x79, 0x79, 0x79, 0x77, 0x77, 0x78, 0x79, 0x7B, 0x7C, 0x7B, 0x7B, 0x7C, 0x7B, 0x7B, +0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x79, 0x79, +0x78, 0x77, 0x77, 0x79, 0x79, 0x79, 0x7B, 0x7B, 0x7A, 0x7C, 0x7E, 0x7D, 0x7E, 0x7E, 0x7C, 0x7C, +0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x79, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x78, 0x78, 0x7A, 0x7A, 0x79, +0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFC, 0xFB, 0xFB, 0xFC, +0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFE, 0xFF, 0x7E, 0x7E, 0xFF, 0xFF, 0x7E, 0x7E, 0x7D, 0x7B, +0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, +0x7C, 0x7B, 0x79, 0x7A, 0x7A, 0x7A, 0x7A, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7C, 0x79, 0x79, 0x7A, +0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7C, 0x7C, 0x7C, 0x7E, 0x7D, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0xFE, +0xFD, 0xFD, 0xFB, 0xFB, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, +0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7D, 0x7E, 0x7D, 0x7B, 0x7B, 0x7B, 0x79, 0x78, 0x77, +0x78, 0x78, 0x77, 0x77, 0x77, 0x78, 0x78, 0x76, 0x76, 0x75, 0x73, 0x73, 0x73, 0x72, 0x73, 0x73, +0x74, 0x74, 0x74, 0x75, 0x77, 0x78, 0x78, 0x77, 0x76, 0x77, 0x76, 0x76, 0x78, 0x79, 0x79, 0x79, +0x78, 0x79, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7E, +0x7E, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFE, 0xFF, 0xFD, 0xFE, 0x7F, 0xFF, +0x7F, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7E, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7D, 0x7F, +0xFF, 0xFF, 0xFE, 0xFE, 0x7F, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7C, 0x7D, +0x7D, 0x7D, 0x7D, 0x7E, 0x7F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFF, 0xFE, 0xFC, 0xFD, 0xFC, 0xFC, 0xFD, +0xFC, 0xFB, 0xFB, 0xFC, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFD, 0xFE, +0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7D, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7D, 0x7B, 0x7B, 0x79, +0x78, 0x78, 0x78, 0x76, 0x74, 0x74, 0x73, 0x72, 0x75, 0x77, 0x77, 0x76, 0x75, 0x75, 0x76, 0x77, +0x77, 0x76, 0x74, 0x74, 0x74, 0x74, 0x76, 0x76, 0x76, 0x77, 0x75, 0x76, 0x78, 0x79, 0x77, 0x77, +0x79, 0x7B, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7D, 0x7F, 0x7E, 0xFF, 0xFF, 0x7F, 0xFE, 0xFC, 0xFE, +0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFD, 0xFC, 0xFE, 0xFF, 0x7E, 0x7F, 0x7F, 0x7D, 0x7E, 0xFF, 0x7F, +0x7F, 0xFF, 0x7F, 0x7E, 0x7D, 0x7E, 0xFF, 0x7E, 0x7F, 0x7F, 0x7C, 0x7D, 0x7F, 0x7D, 0x7E, 0x7E, +0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7B, 0x7D, 0x7B, 0x7A, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7C, +0x7D, 0x7E, 0x7F, 0xFF, 0x7F, 0x7F, 0x7F, 0xFF, 0xFD, 0xFD, 0xFD, 0xFC, 0xFB, 0xFB, 0xFB, 0xFB, +0xFA, 0xFB, 0xFB, 0xFB, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x7E, 0x7E, 0x7D, 0x7B, 0x7B, 0x7B, +0x78, 0x79, 0x78, 0x75, 0x76, 0x76, 0x76, 0x76, 0x74, 0x74, 0x73, 0x73, 0x74, 0x73, 0x72, 0x73, +0x75, 0x75, 0x74, 0x76, 0x74, 0x72, 0x73, 0x74, 0x75, 0x75, 0x76, 0x77, 0x77, 0x78, 0x77, 0x77, +0x77, 0x78, 0x78, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x7A, 0x79, 0x7B, 0x7C, 0x7B, 0x7B, +0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7C, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, +0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, +0xFE, 0x7E, 0x7E, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7E, 0xFF, 0x7E, 0x7E, 0x7E, 0x7D, +0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFD, 0xFC, 0xFE, 0x7F, 0x7E, 0x7E, 0x7F, 0xFF, 0xFF, +0x7F, 0x7E, 0x7D, 0x7D, 0x7D, 0x7B, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, 0x7D, 0x7C, 0x7C, +0x7D, 0x7C, 0x7C, 0x7E, 0x7E, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFF, +0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, +0xFB, 0xFB, 0xFA, 0xFB, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, +0x7E, 0x7E, 0x7E, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7F, +0x7D, 0x7B, 0x7C, 0x7C, 0x7D, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7E, +0x7F, 0x7E, 0x7D, 0x7C, 0x7B, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x78, 0x77, 0x77, 0x76, 0x74, 0x73, +0x72, 0x73, 0x74, 0x75, 0x77, 0x78, 0x78, 0x79, 0x79, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, +0x7C, 0x7D, 0x7E, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, 0x7D, 0x7C, 0x7B, +0x7A, 0x7B, 0x7B, 0x7A, 0x7A, 0x79, 0x79, 0x7A, 0x79, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x79, 0x79, +0x79, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7A, 0x7B, 0x7C, 0x7B, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7F, +0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7D, 0x7D, +0x7D, 0x7D, 0x7E, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7F, 0x7F, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7F, 0x7F, 0x7E, +0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, +0x7A, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, +0x7D, 0x7E, 0xFF, 0x7E, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7A, 0x7A, +0x7A, 0x79, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, 0x7D, 0x7C, 0x7C, 0x7A, 0x79, 0x79, 0x78, 0x78, +0x78, 0x77, 0x77, 0x76, 0x75, 0x74, 0x74, 0x74, 0x73, 0x73, 0x73, 0x73, 0x74, 0x74, 0x76, 0x75, +0x74, 0x75, 0x77, 0x78, 0x78, 0x7A, 0x7B, 0x7D, 0xFF, 0xFE, 0xFE, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, +0xFC, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, +0xF8, 0xFA, 0xF8, 0xF6, 0xF7, 0xF7, 0xF8, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFB, +0xFB, 0xFB, 0xFD, 0xFE, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, 0xFE, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, +0x7F, 0x7E, 0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0xFD, 0xFE, 0xFF, +0xFE, 0xFE, 0xFD, 0xFE, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7E, 0x7F, +0x7D, 0x7D, 0x7E, 0x7E, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x79, 0x77, 0x78, 0x79, 0x78, 0x77, 0x76, +0x76, 0x75, 0x73, 0x74, 0x73, 0x71, 0x70, 0x70, 0x71, 0x72, 0x71, 0x71, 0x70, 0x6F, 0x6F, 0x6F, +0x70, 0x71, 0x71, 0x72, 0x73, 0x74, 0x74, 0x74, 0x76, 0x77, 0x76, 0x78, 0x79, 0x79, 0x79, 0x78, +0x7A, 0x7B, 0x7B, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, +0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7D, +0x7D, 0x7D, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7C, 0x7A, 0x78, 0x79, 0x78, 0x77, +0x76, 0x78, 0x79, 0x78, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7A, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, +0x7E, 0xFF, 0xFD, 0xFC, 0xFC, 0xFA, 0xF9, 0xFA, 0xFB, 0xFA, 0xF9, 0xF8, 0xF8, 0xF9, 0xFA, 0xF9, +0xF9, 0xF9, 0xF9, 0xF9, 0xF8, 0xF7, 0xF9, 0xF9, 0xF8, 0xF8, 0xFA, 0xFB, 0xFA, 0xFB, 0xFD, 0xFD, +0xFC, 0xFD, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFF, 0x7F, 0x7F, 0x7E, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, +0x7A, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x75, 0x76, 0x77, 0x76, 0x75, 0x76, 0x76, 0x75, 0x76, 0x77, +0x78, 0x79, 0x7B, 0x7B, 0x7B, 0x7A, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7A, 0x7B, 0x7B, 0x7A, +0x7B, 0x7D, 0x7E, 0x7B, 0x7C, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFC, 0xFD, 0xFE, 0xFF, +0xFE, 0xFF, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7D, 0x7F, 0x7F, 0x7C, 0x7B, +0x7A, 0x78, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7C, 0x7C, 0x7A, 0x7B, 0x7C, 0x7C, 0x7B, 0x7C, 0x7C, +0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x79, 0x7A, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, +0x7D, 0xFE, 0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFA, 0xF8, 0xF8, 0xF9, 0xF8, 0xF5, 0xF4, 0xF7, 0xF8, +0xF8, 0xF8, 0xF9, 0xFB, 0xFC, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7B, +0x7A, 0x7B, 0x7B, 0x7A, 0x78, 0x78, 0x77, 0x76, 0x76, 0x75, 0x76, 0x76, 0x76, 0x77, 0x75, 0x75, +0x76, 0x75, 0x76, 0x76, 0x78, 0x78, 0x77, 0x78, 0x76, 0x74, 0x75, 0x77, 0x79, 0x7A, 0x7A, 0x7B, +0x7C, 0x7D, 0x7D, 0x7D, 0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0x7F, 0xFF, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, +0xFE, 0x7F, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0xFF, 0xFD, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, +0xFC, 0xFD, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7C, +0x7B, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x7A, 0x7C, 0x7A, 0x7B, 0x7C, 0x7C, 0x7E, 0x7E, 0xFF, +0xFF, 0x7F, 0x7F, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, +0x7C, 0x7D, 0xFF, 0x7E, 0x7C, 0x7D, 0xFF, 0xFF, 0xFF, 0xFD, 0xFD, 0xFF, 0x7E, 0x7F, 0x7E, 0x7E, +0x7F, 0x7E, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x79, +0x77, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7C, 0x7D, 0x7D, 0x7E, 0xFD, 0xFD, 0xFE, 0xFC, 0xFC, 0xFB, +0xFB, 0xFC, 0xFB, 0xFB, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, +0xFF, 0xFF, 0xFD, 0xFC, 0xFD, 0xFD, 0xFC, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7D, 0x7C, 0x7D, 0x7E, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, +0x7B, 0x7C, 0x7D, 0x7B, 0x7B, 0x7C, 0x7A, 0x78, 0x78, 0x78, 0x77, 0x75, 0x75, 0x75, 0x73, 0x72, +0x72, 0x72, 0x71, 0x71, 0x72, 0x72, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x74, 0x74, +0x75, 0x76, 0x76, 0x76, 0x77, 0x78, 0x77, 0x78, 0x79, 0x77, 0x78, 0x78, 0x79, 0x7A, 0x7A, 0x7A, +0x7A, 0x79, 0x77, 0x76, 0x76, 0x78, 0x78, 0x77, 0x77, 0x77, 0x75, 0x74, 0x74, 0x75, 0x75, 0x76, +0x79, 0x79, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7D, 0xFF, 0xFD, 0xFD, 0xFE, 0xFF, 0xFE, 0xFC, +0xF9, 0xF9, 0xFB, 0xFA, 0xF9, 0xF8, 0xF8, 0xF8, 0xF6, 0xF4, 0xF6, 0xF8, 0xF7, 0xF7, 0xF9, 0xF9, +0xF9, 0xF8, 0xF8, 0xFB, 0xFA, 0xF9, 0xFA, 0xFB, 0xFC, 0xFE, 0xFC, 0xFD, 0xFF, 0x7E, 0x7F, 0x7E, +0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, 0x7A, 0x7A, 0x79, 0x79, 0x78, 0x77, 0x78, +0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, 0x7F, 0xFE, 0xFE, 0xFD, 0xFD, +0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0xFC, 0xFB, 0xFC, +0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, +0x7C, 0x7B, 0x7B, 0x7C, 0x79, 0x79, 0x79, 0x78, 0x76, 0x75, 0x76, 0x78, 0x77, 0x76, 0x76, 0x77, +0x76, 0x74, 0x74, 0x75, 0x75, 0x75, 0x74, 0x74, 0x76, 0x77, 0x78, 0x7A, 0x7C, 0x7B, 0x7A, 0x7D, +0x7E, 0x7E, 0x7C, 0x7D, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFE, 0xFF, +0xFF, 0x7F, 0x7E, 0x7F, 0xFF, 0xFE, 0xFD, 0xFF, 0xFE, 0xFC, 0xFB, 0xFC, 0xFE, 0xFD, 0xFC, 0xFE, +0xFF, 0xFE, 0xFD, 0xFF, 0x7E, 0x7F, 0xFE, 0xFC, 0xFD, 0xFE, 0xFD, 0xFD, 0xFE, 0x7F, 0x7E, 0xFF, +0xFF, 0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7E, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, +0x7E, 0x7D, 0x7E, 0xFF, 0xFF, 0xFE, 0xFD, 0xFF, 0x7D, 0x7A, 0x79, 0x79, 0x7A, 0x7C, 0x7B, 0x7B, +0x7D, 0x7E, 0x7E, 0x7D, 0xFF, 0xFF, 0x7F, 0x7F, 0x7E, 0x7B, 0x7A, 0x7A, 0x7A, 0x78, 0x77, 0x77, +0x77, 0x78, 0x78, 0x76, 0x76, 0x76, 0x76, 0x74, 0x74, 0x73, 0x74, 0x74, 0x75, 0x74, 0x72, 0x74, +0x76, 0x74, 0x74, 0x76, 0x76, 0x74, 0x73, 0x73, 0x72, 0x73, 0x74, 0x76, 0x77, 0x75, 0x73, 0x75, +0x77, 0x78, 0x75, 0x75, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7B, +0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7D, 0x7C, 0x7D, 0x7B, 0x7C, 0x7F, +0xFF, 0xFF, 0x7E, 0x7D, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x79, 0x77, 0x77, +0x78, 0x76, 0x76, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x7B, 0x7C, 0x7B, 0x7C, 0x7D, 0xFF, +0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFB, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, +0xFA, 0xF9, 0xF9, 0xF7, 0xF7, 0xF7, 0xF4, 0xF4, 0xF4, 0xF2, 0xEF, 0xEE, 0xEF, 0xF2, 0xF2, 0xF1, +0xF2, 0xF5, 0xF5, 0xF3, 0xF1, 0xF2, 0xF5, 0xF7, 0xF8, 0xFA, 0xFB, 0xFC, 0xFC, 0xFB, 0xFC, 0xFC, +0xFD, 0xFF, 0x7F, 0x7E, 0x7C, 0x7A, 0x7A, 0x78, 0x77, 0x76, 0x75, 0x75, 0x74, 0x71, 0x70, 0x71, +0x71, 0x71, 0x70, 0x6F, 0x71, 0x71, 0x71, 0x73, 0x75, 0x77, 0x77, 0x76, 0x79, 0x7A, 0x79, 0x79, +0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7F, 0xFF, 0xFE, 0xFF, 0x7E, 0x7D, 0x7E, 0x7E, 0x7D, 0x7D, +0x7E, 0x7C, 0x7C, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x77, 0x75, 0x75, 0x76, 0x78, 0x79, 0x78, +0x7A, 0x7C, 0x7C, 0x7A, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7B, 0x7D, 0x7D, 0x7C, +0x7C, 0x7E, 0xFF, 0x7F, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0xFF, 0x7F, 0x7E, +0x7D, 0x7D, 0xFF, 0xFF, 0x7F, 0xFF, 0xFC, 0xFC, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xFB, 0xFB, +0xF9, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0x7F, 0x7F, 0x7E, 0x7D, 0x7E, 0x7D, 0x7B, 0x7C, 0x7B, +0x7B, 0x7C, 0x7C, 0x7A, 0x78, 0x78, 0x7B, 0x7A, 0x77, 0x75, 0x76, 0x75, 0x76, 0x76, 0x76, 0x76, +0x78, 0x79, 0x78, 0x75, 0x75, 0x76, 0x77, 0x7A, 0x7D, 0xFF, 0xFC, 0xFB, 0xFA, 0xFA, 0xFB, 0xFA, +0xFB, 0xFB, 0xFC, 0xFD, 0xFD, 0x7E, 0x78, 0x76, 0x72, 0x70, 0x71, 0x75, 0x77, 0x77, 0x79, 0x7A, +0x7A, 0x7A, 0x7B, 0xFF, 0xFB, 0xFA, 0xF9, 0xFB, 0xFD, 0xFE, 0x7E, 0x7F, 0xFF, 0xFC, 0xF6, 0xF3, +0xF7, 0xFC, 0xFF, 0x7A, 0x73, 0x6E, 0x6C, 0x6D, 0x6E, 0x6E, 0x6E, 0x6E, 0x6F, 0x74, 0x73, 0x72, +0x75, 0x7A, 0x7D, 0x7D, 0xFF, 0xFF, 0x7C, 0x7C, 0x7D, 0x7B, 0x7A, 0x79, 0x7B, 0xFF, 0xFF, 0x7D, +0x7C, 0xFF, 0xFE, 0x7D, 0xFC, 0xF3, 0xF6, 0xFC, 0xFE, 0xFE, 0xFF, 0x78, 0x75, 0x79, 0x7A, 0x7E, +0xF8, 0xF6, 0xF6, 0xF2, 0xEF, 0xEE, 0xF0, 0xF7, 0xFD, 0xFE, 0xFD, 0x7B, 0x77, 0x7C, 0xFF, 0xFB, +0xFD, 0x7D, 0xFF, 0x7C, 0x78, 0x7A, 0x7A, 0xFF, 0xF9, 0xF5, 0xF1, 0xF4, 0xFA, 0xFC, 0xFC, 0xFA, +0xF8, 0xFA, 0xFB, 0xFA, 0xFB, 0xFC, 0xFD, 0xFF, 0x7D, 0x7B, 0x7D, 0x7E, 0x7A, 0x76, 0x76, 0x75, +0x72, 0x75, 0x7B, 0x7D, 0x7A, 0x7A, 0x7D, 0xFF, 0x7C, 0x7C, 0xFF, 0x7D, 0x7A, 0x7B, 0x7C, 0x7E, +0xFC, 0xFC, 0x7F, 0xFE, 0xFD, 0xFE, 0xFC, 0xF8, 0xF9, 0xFA, 0xFB, 0xFE, 0x7E, 0x79, 0x72, 0x72, +0x74, 0x76, 0x78, 0x76, 0x78, 0x7A, 0x75, 0x76, 0x77, 0x75, 0x73, 0x73, 0x73, 0x73, 0x74, 0x73, +0x73, 0x77, 0x78, 0x79, 0x79, 0x7A, 0x79, 0x73, 0x73, 0x7B, 0x7C, 0x7C, 0xFC, 0xFC, 0xFE, 0x7F, +0x76, 0x73, 0x76, 0x73, 0x73, 0x78, 0x7C, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0x7D, 0x7B, 0x7B, +0x7C, 0x7A, 0x78, 0x7B, 0x7B, 0x7D, 0x7F, 0x7A, 0x77, 0x73, 0x6F, 0x70, 0x72, 0x73, 0x72, 0x72, +0x73, 0x74, 0x74, 0x76, 0x7D, 0xFE, 0x7D, 0x7C, 0x7C, 0x78, 0x76, 0x77, 0x79, 0x7B, 0xFF, 0xFD, +0xFE, 0x7E, 0x7B, 0x7A, 0x78, 0x78, 0x7B, 0x7C, 0x7C, 0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x79, 0x7B, +0xFF, 0xFA, 0xF9, 0xFD, 0x7E, 0x7D, 0x7C, 0x7B, 0x7E, 0xFE, 0xFC, 0xFF, 0x7E, 0xFE, 0xFD, 0xFE, +0xFD, 0xFC, 0xFB, 0xFC, 0xFC, 0xFD, 0xF9, 0xF3, 0xF2, 0xF3, 0xF4, 0xF6, 0xF6, 0xF8, 0xFA, 0xFC, +0xFB, 0xF7, 0xF9, 0xFC, 0xFC, 0xFD, 0xFD, 0x7E, 0x7C, 0x7F, 0xFF, 0x7D, 0x7A, 0x7A, 0x7B, 0x78, +0x78, 0x78, 0x75, 0x75, 0x76, 0x79, 0x7A, 0x79, 0x7C, 0x7F, 0xFD, 0xFF, 0x7E, 0xFF, 0x7D, 0x79, +0x77, 0x78, 0x79, 0x78, 0x79, 0x7C, 0x7D, 0x7F, 0x7E, 0x7E, 0xFE, 0xFC, 0xF8, 0xF7, 0xFA, 0xFB, +0xFC, 0xFD, 0xFF, 0x7D, 0x7E, 0x7F, 0xFF, 0x7D, 0x7B, 0x7D, 0xFE, 0xF9, 0xF5, 0xF6, 0xF6, 0xF4, +0xF6, 0xFA, 0xFE, 0x7D, 0x79, 0x78, 0x77, 0x77, 0x7A, 0x7E, 0xFE, 0xFF, 0xFF, 0xFA, 0xFA, 0xFE, +0x7C, 0x75, 0x71, 0x72, 0x74, 0x75, 0x74, 0x75, 0x75, 0x77, 0x79, 0x79, 0x77, 0x74, 0x74, 0x74, +0x72, 0x71, 0x70, 0x71, 0x70, 0x6F, 0x72, 0x73, 0x72, 0x73, 0x71, 0x70, 0x73, 0x78, 0x7A, 0x78, +0x77, 0x77, 0x76, 0x74, 0x73, 0x72, 0x70, 0x71, 0x75, 0x78, 0x7B, 0x7F, 0xFF, 0xFE, 0xFB, 0xFD, +0x7E, 0xFF, 0xFD, 0x7F, 0x7C, 0x7B, 0x7F, 0xFD, 0xFF, 0xFE, 0xFC, 0xFE, 0xFD, 0xFC, 0xFA, 0xF7, +0xF7, 0xFB, 0xFD, 0xFE, 0x7E, 0x7C, 0x7B, 0x7A, 0x7B, 0x79, 0x75, 0x75, 0x76, 0x78, 0x7D, 0xFF, +0x7E, 0x7D, 0x7E, 0x7C, 0x77, 0x75, 0x76, 0x76, 0x78, 0x7E, 0xFD, 0xFB, 0xFC, 0xFD, 0xFE, 0x7C, +0x78, 0x78, 0x7A, 0x7B, 0x7E, 0x7E, 0x7D, 0x7D, 0x7C, 0x7A, 0x78, 0x79, 0x7B, 0x7A, 0x7D, 0xFC, +0xFD, 0x7E, 0xFF, 0xFB, 0xF7, 0xF6, 0xF7, 0xF7, 0xF6, 0xFA, 0xFF, 0xFE, 0xFD, 0xFF, 0x7D, 0xFF, +0xFC, 0xFB, 0xF9, 0xFD, 0xFE, 0xFD, 0x7E, 0x79, 0x76, 0x71, 0x6F, 0x6E, 0x6E, 0x6F, 0x72, 0x76, +0x7A, 0x7E, 0xFF, 0xFF, 0x7C, 0x7B, 0x7C, 0x7B, 0x7A, 0x79, 0x7A, 0x7E, 0xFF, 0xFF, 0x7E, 0x7D, +0x7D, 0x7E, 0x7C, 0x78, 0x79, 0x7A, 0x7B, 0xFF, 0xFF, 0x7F, 0x7E, 0x7B, 0x79, 0x79, 0x76, 0x72, +0x73, 0x7B, 0xFF, 0xFE, 0xFB, 0xFA, 0xFA, 0xFC, 0x7D, 0x78, 0x77, 0x78, 0x79, 0x79, 0x78, 0x79, +0x77, 0x73, 0x74, 0x76, 0x77, 0x79, 0x7A, 0x7B, 0x7F, 0xFD, 0xFE, 0xFF, 0x7F, 0x7E, 0x7E, 0x7C, +0x78, 0x78, 0x7B, 0x7B, 0x7A, 0x7C, 0x7F, 0xFE, 0xFD, 0xFE, 0x7E, 0xFF, 0xFD, 0xFC, 0xF9, 0xF5, +0xF2, 0xF0, 0xF2, 0xF3, 0xF0, 0xF1, 0xF2, 0xF1, 0xF4, 0xF7, 0xF8, 0xFC, 0xFC, 0xF6, 0xF3, 0xF4, +0xF5, 0xF5, 0xF6, 0xFB, 0xFF, 0xFF, 0xFF, 0x7D, 0x7D, 0x7E, 0x7D, 0x79, 0x75, 0x74, 0x75, 0x72, +0x72, 0x75, 0x75, 0x74, 0x77, 0x7A, 0x7A, 0x7A, 0x7A, 0x77, 0x74, 0x73, 0x72, 0x74, 0x75, 0x76, +0x77, 0x74, 0x74, 0x77, 0x79, 0x79, 0x79, 0x78, 0x77, 0x74, 0x70, 0x6F, 0x70, 0x6F, 0x6E, 0x6E, +0x6E, 0x6F, 0x6F, 0x72, 0x75, 0x72, 0x74, 0x79, 0x7B, 0x7B, 0x7B, 0x7D, 0xFF, 0x7E, 0x7F, 0xFE, +0xFE, 0x7F, 0x7D, 0x7D, 0xFF, 0xFD, 0xFE, 0x7E, 0x7D, 0x7D, 0x7E, 0x7C, 0x79, 0x77, 0x75, 0x76, +0x77, 0x78, 0x78, 0x74, 0x75, 0x7A, 0x7F, 0xFB, 0xF9, 0xF9, 0xF8, 0xFD, 0x7E, 0x7B, 0x76, 0x78, +0x7B, 0x7C, 0x7E, 0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x7C, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x7D, 0x7B, +0x7B, 0x79, 0x79, 0x7A, 0x7D, 0xFF, 0x7F, 0x7F, 0xFF, 0xFD, 0xFB, 0xFD, 0xFE, 0xFE, 0xFF, 0x7D, +0x7C, 0x7F, 0xFB, 0xF7, 0xF6, 0xFC, 0x7F, 0xFF, 0xFE, 0xFB, 0xFD, 0xFE, 0xFC, 0xFD, 0xFE, 0x7C, +0x76, 0x74, 0x74, 0x79, 0x79, 0x76, 0x77, 0x79, 0x7C, 0x7D, 0x7B, 0x7B, 0x7B, 0x7E, 0xFD, 0xFB, +0xF9, 0xF9, 0xFE, 0x7C, 0x79, 0x79, 0x77, 0x76, 0x79, 0x7B, 0x7D, 0x7C, 0x7C, 0x7D, 0x7C, 0x78, +0x75, 0x74, 0x72, 0x72, 0x73, 0x71, 0x70, 0x73, 0x78, 0x7C, 0x7D, 0x7E, 0xFF, 0x7F, 0x7F, 0x7D, +0x7A, 0x78, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x7B, 0xFF, 0xFF, 0xFD, 0xFC, 0xFC, 0xFA, 0xF9, +0xF8, 0xF9, 0xFE, 0x7E, 0xFF, 0xFE, 0xFE, 0x7D, 0x7A, 0x78, 0x75, 0x75, 0x77, 0x7A, 0x7A, 0x79, +0x7B, 0x7D, 0xFF, 0xFD, 0xFC, 0xFC, 0xFB, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xFB, 0xFA, 0xF9, 0xF7, +0xF8, 0xFA, 0xF8, 0xF9, 0xFC, 0xFD, 0xFD, 0xFC, 0xF9, 0xF7, 0xF8, 0xFC, 0x7E, 0x7B, 0x7A, 0x7A, +0x79, 0x79, 0x7A, 0x7A, 0x7A, 0x77, 0x72, 0x72, 0x74, 0x76, 0x7B, 0x7C, 0x7B, 0x7D, 0x7E, 0x7D, +0x7D, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x78, 0x78, 0x79, 0x79, 0x79, 0x78, 0x79, 0x7B, 0x7C, 0x7C, +0x7A, 0x7A, 0x77, 0x75, 0x75, 0x74, 0x73, 0x70, 0x6E, 0x6E, 0x6E, 0x6F, 0x72, 0x75, 0x77, 0x7A, +0x7D, 0x7D, 0x7D, 0x7E, 0xFF, 0x7D, 0x7A, 0x7A, 0x7A, 0x7B, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7F, +0x7D, 0x7B, 0x78, 0x75, 0x73, 0x74, 0x75, 0x75, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7D, 0xFE, 0xFC, +0xF9, 0xF8, 0xF8, 0xF8, 0xF6, 0xF5, 0xF6, 0xF8, 0xFB, 0xFC, 0xFB, 0xFD, 0xFF, 0x7E, 0x7D, 0x7C, +0x7C, 0x7B, 0x7C, 0x7B, 0x79, 0x79, 0x7A, 0x79, 0x76, 0x74, 0x72, 0x72, 0x73, 0x74, 0x75, 0x77, +0x78, 0x78, 0x78, 0x77, 0x76, 0x75, 0x75, 0x78, 0x7A, 0x79, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0x7F, +0xFE, 0xFC, 0xFC, 0xFC, 0xFA, 0xF8, 0xF7, 0xF7, 0xF8, 0xF7, 0xF5, 0xF5, 0xF5, 0xF4, 0xF5, 0xF6, +0xF7, 0xF8, 0xF9, 0xFB, 0xFE, 0x7F, 0x7D, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7D, 0x7A, 0x7A, 0x7A, +0x7A, 0x79, 0x79, 0x79, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x7A, 0x7A, 0x79, 0x77, 0x76, +0x77, 0x77, 0x77, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7B, +0x78, 0x78, 0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0x7F, 0x7F, 0xFE, +0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFE, 0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, +0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x76, 0x77, 0x78, 0x77, 0x79, +0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7D, 0x7B, 0x7B, 0x7D, 0x7C, 0x7D, 0xFF, 0x7E, +0xFF, 0xFD, 0xFB, 0xF9, 0xF8, 0xF9, 0xF9, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF3, 0xF5, 0xF6, 0xF6, +0xF7, 0xF9, 0xFB, 0xFB, 0xFA, 0xFA, 0xFB, 0xFC, 0xFB, 0xFD, 0xFD, 0xFB, 0xFB, 0xFB, 0xFA, 0xF8, +0xF8, 0xF9, 0xFB, 0xFD, 0x7E, 0x7B, 0x78, 0x78, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x75, 0x75, +0x73, 0x71, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6E, 0x6E, 0x6F, 0x6F, 0x6E, 0x6E, 0x6E, 0x6D, +0x6D, 0x6E, 0x6D, 0x6D, 0x6E, 0x6F, 0x70, 0x72, 0x73, 0x74, 0x75, 0x79, 0x7C, 0x7D, 0x7E, 0xFF, +0xFF, 0xFF, 0xFD, 0xFC, 0xFA, 0xF9, 0xFB, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0x7E, 0x7B, 0x7A, +0x79, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7C, 0x7C, 0x7B, 0x79, 0x79, 0x78, 0x78, 0x79, 0x7A, 0x7C, +0x7E, 0x7E, 0x7E, 0x7C, 0x7B, 0x7A, 0x7A, 0x7A, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x7D, 0xFF, 0xFD, +0xFC, 0xFB, 0xFA, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFB, 0xFB, +0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFD, 0xFC, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, 0xF7, +0xF6, 0xF7, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0x7E, 0x7D, 0x7C, 0x7C, +0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, +0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7B, 0x78, 0x77, 0x76, 0x75, 0x75, 0x75, 0x76, 0x76, 0x75, 0x76, +0x77, 0x78, 0x78, 0x78, 0x79, 0x79, 0x7B, 0x7D, 0x7D, 0x7E, 0x7F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFE, +0xFD, 0xFB, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFF, 0x7F, 0x7E, 0x7C, 0x7C, 0x7B, +0x7A, 0x7A, 0x7A, 0x78, 0x78, 0x77, 0x77, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 0x7D, 0x7B, +0x7A, 0x7B, 0x7C, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7A, 0x7B, 0x7F, 0xFD, 0x7D, 0x79, 0xFE, +0xFA, 0xFE, 0xFC, 0xF8, 0xFC, 0xFF, 0xFF, 0xFE, 0xFB, 0xFC, 0x7F, 0xFF, 0x7F, 0x7C, 0x7D, 0x7D, +0x7E, 0x7E, 0x7B, 0x7A, 0x7A, 0x7B, 0x7C, 0x7E, 0x7E, 0x7C, 0x7B, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, +0x7D, 0x7E, 0x7F, 0x7E, 0x7F, 0xFF, 0xFE, 0xFD, 0xFE, 0xFF, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7E, +0x7D, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x7A, 0x7A, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x75, 0x74, 0x73, +0x74, 0x75, 0x74, 0x74, 0x75, 0x75, 0x75, 0x76, 0x77, 0x76, 0x77, 0x77, 0x79, 0x7B, 0x7C, 0x7D, +0x7D, 0x7D, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFE, 0xFD, 0xFE, 0xFF, 0xFE, 0xFD, 0xFB, 0xFC, 0xFD, +0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7E, +0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, +0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, +0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7F, 0x7F, 0x7E, +0x7D, 0x7C, 0x7B, 0x7B, 0x79, 0x77, 0x77, 0x78, 0x76, 0x76, 0x78, 0x7A, 0x78, 0x78, 0x78, 0x77, +0x77, 0x76, 0x75, 0x76, 0x75, 0x75, 0x77, 0x77, 0x76, 0x74, 0x74, 0x75, 0x76, 0x75, 0x76, 0x76, +0x75, 0x76, 0x76, 0x75, 0x74, 0x73, 0x74, 0x74, 0x75, 0x76, 0x76, 0x77, 0x78, 0x7A, 0x7A, 0x7B, +0x7C, 0x7B, 0x7D, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFE, 0xFD, 0xFD, 0xFD, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0xFE, +0xFE, 0xFE, 0x7F, 0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFD, 0xFD, 0xFD, +0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0xFE, 0xFC, 0xFA, 0xF9, 0xF8, 0xF8, 0xF8, 0xF9, 0xFA, +0xFD, 0xFE, 0xFC, 0xFD, 0xFE, 0xFE, 0xFF, 0x7F, 0xFF, 0x7E, 0x7D, 0x7B, 0x79, 0x79, 0x7B, 0x7C, +0x7C, 0x7D, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7B, 0x7B, 0x7A, 0x77, 0x78, 0x75, 0x75, 0x76, 0x76, +0x78, 0x75, 0x76, 0x77, 0x73, 0x75, 0x73, 0x77, 0x76, 0x73, 0x78, 0x73, 0x78, 0x77, 0x75, 0x7B, +0x70, 0x7E, 0x68, 0x5B, 0xE4, 0xD9, 0x77, 0x66, 0x5F, 0x6B, 0xEB, 0x78, 0x6B, 0xEC, 0xE9, 0x67, +0x5A, 0x62, 0xF8, 0xE2, 0xF1, 0x6B, 0x6F, 0x72, 0x6E, 0x6D, 0x72, 0xEF, 0xE7, 0xF7, 0x6D, 0x6A, +0x70, 0x7B, 0xFC, 0xF5, 0xED, 0xEF, 0x7D, 0x71, 0x70, 0xFF, 0xEE, 0xEF, 0xF8, 0xFC, 0x7B, 0x73, +0x6F, 0x71, 0x7E, 0xF2, 0xF2, 0x76, 0x67, 0x68, 0x78, 0xF7, 0xF5, 0xFC, 0x7E, 0x7B, 0x73, 0x70, +0x79, 0xF4, 0xEB, 0xEC, 0xF8, 0x7C, 0x7B, 0xFF, 0xF6, 0xEF, 0xEF, 0xF4, 0xF8, 0xFE, 0x7D, 0xFE, +0xF8, 0xF4, 0xF4, 0xF9, 0xFE, 0x7E, 0x7C, 0x7C, 0xFD, 0xF8, 0xF8, 0xFD, 0x7D, 0x7A, 0x79, 0x7C, +0xFF, 0xFD, 0xFB, 0xFC, 0x7D, 0x7B, 0x7D, 0x7F, 0xFD, 0xFD, 0xFF, 0x7E, 0x7C, 0x7A, 0x79, 0x7C, +0x7E, 0x7D, 0x7D, 0x7B, 0x78, 0x79, 0x7B, 0x7A, 0x78, 0x79, 0x77, 0x76, 0x78, 0x71, 0x70, 0x78, +0x7E, 0xF6, 0xFE, 0x67, 0x68, 0xF4, 0xEF, 0x74, 0x69, 0x6A, 0xFF, 0x7E, 0x6E, 0xF2, 0xFB, 0x69, +0x66, 0x69, 0xDD, 0xD9, 0x71, 0x7B, 0x74, 0x5F, 0x69, 0x61, 0x6A, 0xE6, 0xEC, 0x66, 0x55, 0x50, +0x5C, 0xFB, 0xED, 0xF5, 0xFA, 0x6F, 0x6E, 0x7B, 0xE8, 0xCF, 0xC7, 0xC6, 0xCA, 0xCB, 0xDB, 0x3A, +0x2E, 0x49, 0xBD, 0xB7, 0xC6, 0x4D, 0x41, 0x4B, 0x49, 0x4D, 0xD9, 0xBF, 0xC2, 0xFD, 0x3F, 0x3D, +0x51, 0xDF, 0xCD, 0xCC, 0xD5, 0xF4, 0x50, 0x46, 0x4D, 0xF0, 0xCB, 0xCA, 0xDA, 0x61, 0x51, 0x52, +0x5B, 0xE6, 0xD0, 0xCE, 0xDC, 0x5D, 0x53, 0x51, 0x6A, 0xF9, 0x48, 0x67, 0xC2, 0xE0, 0x5F, 0x5B, +0x4C, 0x71, 0xFA, 0x6E, 0xCE, 0xCF, 0x7A, 0x64, 0x79, 0xD8, 0xCE, 0xD1, 0xCD, 0xC3, 0xC5, 0xCD, +0xC7, 0xDC, 0x42, 0x3E, 0x53, 0xD2, 0xC0, 0xDE, 0x44, 0x48, 0x58, 0x53, 0x59, 0xFA, 0xD9, 0xD6, +0x5E, 0x43, 0x47, 0x61, 0xE1, 0xD8, 0xEA, 0x64, 0x46, 0x3C, 0x51, 0x7F, 0x77, 0xD0, 0xF6, 0x4B, +0x4B, 0x4A, 0x6F, 0xCA, 0xC6, 0xC9, 0xC7, 0xC2, 0xC8, 0xBD, 0xB0, 0xAB, 0xBB, 0x1F, 0x19, 0x5F, +0xA3, 0xA5, 0xBA, 0x30, 0x30, 0x47, 0x31, 0x37, 0xBC, 0xAB, 0xB8, 0x3D, 0x2B, 0x30, 0x4E, 0xBD, +0xB4, 0xC4, 0x5D, 0x3F, 0x38, 0x41, 0x6E, 0xC8, 0xC1, 0xDC, 0x4B, 0x3B, 0x3F, 0xE5, 0xBF, 0xBC, +0xC8, 0xE5, 0xDE, 0xC0, 0xAE, 0xAD, 0xAF, 0xC1, 0x20, 0x1A, 0x63, 0xA8, 0xA7, 0xB5, 0x36, 0x2E, +0x3D, 0x32, 0x3F, 0xBD, 0xB1, 0xC1, 0x39, 0x2E, 0x42, 0xE8, 0xCA, 0xC3, 0xDB, 0x5F, 0x47, 0x39, +0x47, 0xD5, 0xCB, 0xD1, 0x70, 0x4B, 0x4D, 0xF0, 0xC1, 0xB3, 0xAE, 0xB4, 0xBE, 0xB8, 0xB8, 0x34, +0x1C, 0x27, 0xB6, 0xA3, 0xAC, 0x4F, 0x2C, 0x32, 0x3B, 0x3E, 0xEB, 0xB9, 0xBB, 0x45, 0x2E, 0x39, +0x60, 0xC3, 0xBB, 0xD8, 0x4D, 0x45, 0x41, 0x57, 0xD6, 0xDE, 0x79, 0x5D, 0x50, 0x5B, 0xDB, 0xBE, +0xB4, 0xB3, 0xBC, 0xC4, 0xB6, 0xAC, 0xC2, 0x26, 0x1A, 0x30, 0xAB, 0xA9, 0xBB, 0x61, 0x33, 0x30, +0x36, 0x39, 0xCF, 0xB9, 0x64, 0x41, 0x42, 0x3E, 0x5E, 0xD3, 0xCF, 0xC4, 0xEC, 0x47, 0x56, 0x5C, +0x50, 0x57, 0x62, 0xDF, 0xD2, 0xD3, 0xC4, 0xB6, 0xB3, 0xBA, 0xB8, 0xAD, 0xAF, 0x3C, 0x1C, 0x1E, +0xCB, 0xA1, 0xA9, 0xFE, 0x2D, 0x2C, 0x39, 0x3D, 0x64, 0xBE, 0xD5, 0x4B, 0x42, 0x3A, 0x40, 0xEC, +0xC4, 0xBE, 0xD1, 0x4A, 0x3E, 0x47, 0x62, 0xE4, 0xD7, 0xD6, 0xDC, 0xDE, 0xCD, 0xB6, 0xAD, 0xAE, +0xAC, 0xAD, 0xE6, 0x22, 0x19, 0x2E, 0xA6, 0x9E, 0xB2, 0x39, 0x28, 0x2D, 0x39, 0x4E, 0xC2, 0xBE, +0x5B, 0x3E, 0x3B, 0x3C, 0x58, 0xC6, 0xBD, 0xC7, 0x60, 0x3F, 0x3F, 0x51, 0xED, 0xCF, 0xC8, 0xD1, +0xE0, 0xD9, 0xBC, 0xAC, 0xAB, 0xAB, 0xA9, 0xC2, 0x25, 0x17, 0x22, 0xAE, 0x9D, 0xA9, 0x47, 0x26, +0x29, 0x34, 0x47, 0xC5, 0xBB, 0x77, 0x3F, 0x3A, 0x38, 0x4E, 0xC6, 0xBC, 0xBE, 0xE6, 0x3D, 0x39, +0x43, 0x67, 0xCE, 0xC7, 0xD6, 0xED, 0xD9, 0xBD, 0xAB, 0xAB, 0xAE, 0xA9, 0xB4, 0x30, 0x1A, 0x1B, +0xD5, 0x9D, 0xA3, 0xDA, 0x2A, 0x26, 0x31, 0x3C, 0x6C, 0xBF, 0xCE, 0x5E, 0x42, 0x32, 0x3C, 0xD6, +0xBC, 0xB8, 0xCC, 0x3F, 0x37, 0x3B, 0x51, 0xCC, 0xC1, 0xCC, 0xE2, 0xDE, 0xBD, 0xAC, 0xAA, 0xA9, +0xA7, 0xC5, 0x26, 0x18, 0x1F, 0xB7, 0x9D, 0xA6, 0xDF, 0x2B, 0x26, 0x2D, 0x37, 0xEB, 0xBA, 0xCB, +0x5E, 0x3C, 0x30, 0x44, 0xC9, 0xBB, 0xB8, 0xCF, 0x3D, 0x34, 0x3B, 0x5F, 0xC1, 0xBE, 0xCE, 0xD6, +0xCE, 0xB8, 0xAB, 0xAA, 0xA4, 0xA8, 0x42, 0x1C, 0x18, 0x31, 0xA4, 0x9F, 0xAF, 0x48, 0x29, 0x28, +0x2C, 0x37, 0xCC, 0xBA, 0xC7, 0x57, 0x30, 0x31, 0x5A, 0xC6, 0xB6, 0xB7, 0x5F, 0x38, 0x34, 0x3D, +0xE2, 0xBD, 0xBD, 0xC7, 0xD2, 0xCA, 0xB2, 0xAB, 0xA7, 0xA2, 0xB3, 0x29, 0x18, 0x1C, 0xD2, 0x9F, +0xA5, 0xBC, 0x3A, 0x2A, 0x29, 0x2A, 0x3E, 0xC3, 0xBB, 0xC1, 0x43, 0x2D, 0x3A, 0xF5, 0xC1, 0xB5, +0xBE, 0x4F, 0x36, 0x32, 0x3F, 0xD2, 0xBB, 0xBA, 0xBE, 0xC5, 0xBF, 0xB1, 0xAB, 0xA4, 0xA7, 0x75, +0x1F, 0x18, 0x27, 0xAE, 0xA2, 0xAD, 0xD6, 0x36, 0x2B, 0x28, 0x2C, 0x4E, 0xC2, 0xB8, 0xC9, 0x35, +0x2F, 0x42, 0x71, 0xBA, 0xB4, 0xD2, 0x44, 0x34, 0x34, 0x4C, 0xCD, 0xBE, 0xBB, 0xB9, 0xBC, 0xB3, +0xAE, 0xAB, 0xA3, 0xB0, 0x2C, 0x1A, 0x1C, 0x5F, 0xA4, 0xA9, 0xBA, 0x6F, 0x34, 0x28, 0x26, 0x32, +0x77, 0xB9, 0xB3, 0x5E, 0x32, 0x38, 0x40, 0xD8, 0xB6, 0xBE, 0xF4, 0x40, 0x34, 0x3A, 0x5B, 0xC7, +0xB7, 0xB4, 0xB7, 0xB4, 0xB2, 0xAE, 0xA5, 0xAB, 0x3B, 0x1D, 0x1B, 0x34, 0xAE, 0xAA, 0xB4, 0xC7, +0x42, 0x2C, 0x25, 0x2B, 0x43, 0xCF, 0xB5, 0xBE, 0x3F, 0x38, 0x3D, 0x4D, 0xC4, 0xBD, 0xCF, 0x5D, +0x3E, 0x38, 0x43, 0xE4, 0xBF, 0xB4, 0xAF, 0xB0, 0xAF, 0xAE, 0xA8, 0xA7, 0xF6, 0x21, 0x1A, 0x27, +0xBA, 0xAC, 0xB5, 0xB9, 0xE2, 0x36, 0x26, 0x25, 0x33, 0x4E, 0xBA, 0xB2, 0x64, 0x41, 0x3F, 0x3D, +0xE6, 0xC6, 0xCD, 0xD4, 0x50, 0x3D, 0x3C, 0x48, 0xD4, 0xB9, 0xAF, 0xAD, 0xAE, 0xAE, 0xAA, 0xA7, +0xC0, 0x2A, 0x1B, 0x1F, 0x65, 0xAF, 0xB5, 0xB5, 0xBF, 0x4C, 0x2C, 0x23, 0x2A, 0x37, 0xE6, 0xAF, +0xBC, 0x5B, 0x4B, 0x3B, 0x49, 0xCF, 0xCE, 0xD0, 0xDE, 0x4F, 0x40, 0x3F, 0x57, 0xC7, 0xB3, 0xAA, +0xA9, 0xAC, 0xAE, 0xA9, 0xAE, 0x3B, 0x1E, 0x1E, 0x37, 0xBA, 0xB7, 0xB7, 0xB5, 0xC9, 0x3A, 0x26, +0x27, 0x2E, 0x37, 0xC1, 0xB1, 0xCA, 0xE8, 0x49, 0x3E, 0x62, 0x78, 0xEF, 0xD7, 0x69, 0x4F, 0x44, +0x48, 0xFB, 0xC5, 0xAF, 0xA9, 0xA8, 0xAA, 0xAB, 0xAA, 0xCF, 0x26, 0x1C, 0x22, 0x4A, 0xBD, 0xBB, +0xAF, 0xB1, 0xD7, 0x31, 0x25, 0x27, 0x28, 0x38, 0xB9, 0xB6, 0xC3, 0xCB, 0x4B, 0x45, 0x4E, 0x47, +0x62, 0xE0, 0xF9, 0x5C, 0x4C, 0x5C, 0xE4, 0xBF, 0xAD, 0xA8, 0xA5, 0xA7, 0xA9, 0xB2, 0x36, 0x20, +0x1E, 0x29, 0x56, 0xCC, 0xB8, 0xAC, 0xB5, 0xFA, 0x2F, 0x28, 0x25, 0x25, 0x45, 0xBE, 0xBF, 0xB8, +0xC5, 0x5F, 0x54, 0x41, 0x43, 0x4F, 0x56, 0x75, 0x70, 0xFE, 0xE2, 0xD3, 0xB9, 0xAD, 0xA8, 0xA6, +0xA6, 0xA8, 0xCA, 0x2D, 0x22, 0x21, 0x2E, 0x47, 0x77, 0xB4, 0xAD, 0xB7, 0xDC, 0x39, 0x2D, 0x24, +0x28, 0x40, 0x5A, 0xC7, 0xB5, 0xBD, 0xC0, 0xDB, 0x4E, 0x4C, 0x40, 0x44, 0x4E, 0x56, 0xDA, 0xCC, +0xC0, 0xB1, 0xAC, 0xA7, 0xA5, 0xA6, 0xAD, 0x4F, 0x2A, 0x23, 0x25, 0x2F, 0x39, 0x6C, 0xB6, 0xB1, +0xB7, 0xD6, 0x43, 0x2F, 0x26, 0x2C, 0x35, 0x3A, 0xDF, 0xC7, 0xBE, 0xBA, 0xCB, 0xD4, 0x6E, 0x48, +0x44, 0x3E, 0x4A, 0x6C, 0xD6, 0xB9, 0xB0, 0xA8, 0xA4, 0xA5, 0xA4, 0xB5, 0x42, 0x2C, 0x23, 0x27, +0x2B, 0x2E, 0x55, 0xC2, 0xB9, 0xB6, 0xC5, 0xF4, 0x3C, 0x32, 0x34, 0x2F, 0x37, 0x4A, 0x5B, 0xCF, +0xC9, 0xC6, 0xC0, 0xCA, 0xCF, 0xF4, 0x52, 0x51, 0x4E, 0xF8, 0xC4, 0xB7, 0xAD, 0xA9, 0xA6, 0xA7, +0xB8, 0x5D, 0x38, 0x2F, 0x2E, 0x2B, 0x2C, 0x35, 0x42, 0x5D, 0x7D, 0xE3, 0xDF, 0x6F, 0x73, 0x5A, +0x4D, 0x55, 0x4F, 0x4F, 0x58, 0x5C, 0x6E, 0xFA, 0xE2, 0xD4, 0xD4, 0xD6, 0xD9, 0xD6, 0xCC, 0xC6, +0xBF, 0xBB, 0xB8, 0xB6, 0xBC, 0xC9, 0xDC, 0x60, 0x59, 0x53, 0x4A, 0x49, 0x46, 0x45, 0x46, 0x43, +0x45, 0x45, 0x49, 0x56, 0x5A, 0x5D, 0x6E, 0x72, 0x7C, 0x74, 0x6D, 0x7A, 0x7A, 0xFC, 0xED, 0xE8, +0xEB, 0xFF, 0xFD, 0xEC, 0xDE, 0xD2, 0xCC, 0xC7, 0xC5, 0xCA, 0xD2, 0xD9, 0xDB, 0xD4, 0xCF, 0xD1, +0xD9, 0xE7, 0xFC, 0x6E, 0x60, 0x57, 0x50, 0x4C, 0x49, 0x47, 0x46, 0x45, 0x47, 0x4A, 0x4D, 0x4F, +0x4F, 0x53, 0x5A, 0x5F, 0x62, 0x60, 0x62, 0x6B, 0x77, 0xEC, 0xD8, 0xCC, 0xC7, 0xC7, 0xCB, 0xCF, +0xD3, 0xD3, 0xCE, 0xCB, 0xCA, 0xCC, 0xCF, 0xD4, 0xD9, 0xDF, 0xEB, 0xFE, 0x6A, 0x58, 0x4D, 0x46, +0x43, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x52, 0x54, 0x55, 0x54, 0x57, 0x5C, 0x61, 0x72, 0xE5, +0xD4, 0xCC, 0xCB, 0xCD, 0xD0, 0xD4, 0xD3, 0xD1, 0xD0, 0xCF, 0xD1, 0xD2, 0xD4, 0xD6, 0xD9, 0xDB, +0xDB, 0xDD, 0xEC, 0x6B, 0x59, 0x53, 0x54, 0x57, 0x59, 0x58, 0x57, 0x5A, 0x5C, 0x5A, 0x55, 0x52, +0x52, 0x51, 0x51, 0x57, 0x61, 0xFC, 0xE3, 0xDF, 0xE0, 0xE4, 0xE3, 0xE0, 0xDF, 0xDE, 0xDD, 0xDE, +0xDD, 0xDF, 0xE0, 0xDF, 0xDC, 0xD9, 0xDC, 0xE7, 0x7E, 0x6B, 0x6D, 0x7C, 0xEE, 0xE6, 0xE7, 0xEA, +0xEC, 0xF5, 0x7A, 0x6A, 0x61, 0x5A, 0x51, 0x4F, 0x50, 0x55, 0x5D, 0x62, 0x63, 0x60, 0x5F, 0x61, +0x65, 0x68, 0x6D, 0x75, 0xFA, 0xF1, 0xF1, 0xEE, 0xE6, 0xDD, 0xDB, 0xDE, 0xEB, 0x79, 0x6B, 0x6F, +0xF7, 0xE2, 0xDC, 0xDB, 0xDA, 0xDA, 0xDC, 0xDD, 0xDE, 0xE0, 0xF1, 0x6B, 0x5F, 0x5F, 0x66, 0x6B, +0x6A, 0x65, 0x5E, 0x5B, 0x5A, 0x59, 0x5A, 0x5C, 0x5E, 0x5E, 0x5E, 0x5E, 0x68, 0xFC, 0xE8, 0xE5, +0xEB, 0xFB, 0x71, 0x6D, 0x78, 0xEE, 0xE2, 0xDE, 0xDD, 0xDC, 0xDE, 0xDF, 0xDC, 0xD9, 0xD9, 0xE0, +0xED, 0xF0, 0xEC, 0xE4, 0xE2, 0xE6, 0xEE, 0x7C, 0x6D, 0x65, 0x5E, 0x5E, 0x62, 0x64, 0x61, 0x5C, +0x5B, 0x5F, 0x70, 0xF7, 0xF8, 0x78, 0x6B, 0x65, 0x61, 0x69, 0xFA, 0xE9, 0xE5, 0xE2, 0xE5, 0xEA, +0xED, 0xEB, 0xE5, 0xE5, 0xED, 0xF9, 0xFC, 0xEF, 0xE3, 0xDE, 0xDE, 0xE1, 0xE9, 0xF4, 0x74, 0x6A, +0x6B, 0x6F, 0x6F, 0x67, 0x5E, 0x5C, 0x5F, 0x6A, 0x6F, 0x6C, 0x66, 0x5F, 0x5D, 0x5E, 0x64, 0x6F, +0xFE, 0xEF, 0xEC, 0xF2, 0xFD, 0x7E, 0xFB, 0xF6, 0xFF, 0x6F, 0x6A, 0x6A, 0x74, 0xF4, 0xE9, 0xE4, +0xE7, 0xEE, 0x7D, 0x6A, 0x69, 0x6F, 0xFE, 0xF7, 0x7B, 0x6B, 0x68, 0x6E, 0x79, 0x78, 0x6F, 0x69, +0x62, 0x5F, 0x60, 0x66, 0x72, 0xF6, 0xEB, 0xEC, 0xF3, 0xFC, 0xFA, 0xF2, 0xF2, 0xFE, 0x70, 0x69, +0x69, 0x71, 0xF7, 0xE8, 0xE3, 0xE4, 0xED, 0x76, 0x69, 0x6A, 0x6F, 0x7E, 0xFB, 0x7D, 0x75, 0x73, +0x7C, 0xFB, 0xFC, 0x7D, 0x73, 0x6D, 0x6A, 0x69, 0x6F, 0xFD, 0xEC, 0xE8, 0xED, 0xF6, 0xF7, 0xF1, +0xED, 0xEF, 0xF6, 0x7E, 0x76, 0x78, 0xFB, 0xEC, 0xE2, 0xDE, 0xE0, 0xEB, 0xFE, 0x73, 0x73, 0x7E, +0xFA, 0xFC, 0xFF, 0x7B, 0x7D, 0xFC, 0xFE, 0x7B, 0x74, 0x6F, 0x6D, 0x6C, 0x6E, 0x77, 0xFA, 0xEE, +0xED, 0xF6, 0x7A, 0x73, 0x77, 0x7B, 0x7C, 0x78, 0x6E, 0x6B, 0x6F, 0x7C, 0xEF, 0xE7, 0xE2, 0xE6, +0xF2, 0x7A, 0x71, 0x75, 0x7D, 0xFE, 0xFD, 0xFD, 0xFB, 0xF5, 0xF7, 0xFE, 0x77, 0x6E, 0x6A, 0x67, +0x67, 0x6C, 0x76, 0xF7, 0xEE, 0xEF, 0xFA, 0x7B, 0x78, 0x7B, 0xFF, 0x7F, 0x78, 0x6F, 0x6C, 0x6C, +0x72, 0xFE, 0xEF, 0xEC, 0xEF, 0xFD, 0x76, 0x70, 0x71, 0x75, 0x7A, 0x7E, 0x7E, 0xFF, 0xFC, 0xFD, +0x7C, 0x73, 0x6D, 0x69, 0x65, 0x63, 0x65, 0x6B, 0x79, 0xFB, 0xFD, 0x78, 0x70, 0x70, 0x74, 0x79, +0x7C, 0x7B, 0x79, 0x77, 0x78, 0x7F, 0xF4, 0xED, 0xED, 0xF2, 0xFB, 0x7A, 0x74, 0x74, 0x76, 0x7A, +0x7F, 0xFB, 0xF5, 0xF4, 0xF6, 0xFA, 0x7D, 0x75, 0x6E, 0x6B, 0x6B, 0x6F, 0x7D, 0xF3, 0xEF, 0xF4, +0x7E, 0x78, 0x7A, 0xFF, 0xFA, 0xF7, 0xF5, 0xF4, 0xF4, 0xF1, 0xED, 0xE9, 0xE6, 0xE8, 0xEE, 0xF8, +0x7F, 0x7C, 0x7A, 0x7A, 0x7B, 0x7D, 0xFD, 0xF8, 0xF8, 0xF9, 0xFC, 0x7D, 0x74, 0x6C, 0x69, 0x69, +0x6C, 0x76, 0xFA, 0xF6, 0xFD, 0x78, 0x71, 0x6F, 0x6F, 0x6F, 0x71, 0x74, 0x77, 0x7C, 0xFD, 0xF5, +0xEC, 0xE9, 0xEA, 0xEF, 0xFB, 0x7A, 0x74, 0x73, 0x73, 0x73, 0x73, 0x78, 0x7E, 0xFE, 0xFD, 0xFE, +0x7B, 0x74, 0x6D, 0x68, 0x66, 0x69, 0x6F, 0x7B, 0x7F, 0x7C, 0x77, 0x73, 0x72, 0x6F, 0x6D, 0x6D, +0x6D, 0x6D, 0x6E, 0x72, 0x7A, 0xFA, 0xF1, 0xEE, 0xEF, 0xF6, 0xFD, 0x7D, 0x7B, 0x7A, 0x78, 0x78, +0x79, 0x79, 0x7A, 0x7C, 0x7D, 0x7E, 0x7D, 0x77, 0x70, 0x6E, 0x71, 0x79, 0x7E, 0x7E, 0x7E, 0x7D, +0x7E, 0x7D, 0x7C, 0x7A, 0x78, 0x76, 0x74, 0x73, 0x75, 0x7A, 0xFC, 0xF6, 0xF4, 0xF4, 0xF6, 0xF6, +0xF6, 0xF9, 0xF9, 0xF7, 0xF5, 0xF3, 0xF1, 0xF1, 0xF3, 0xF5, 0xF7, 0xFA, 0x7B, 0x6F, 0x6D, 0x6D, +0x6F, 0x6F, 0x6E, 0x6E, 0x70, 0x70, 0x71, 0x74, 0x78, 0x7C, 0x7D, 0x7E, 0x7D, 0xFF, 0xFB, 0xF7, +0xF4, 0xF4, 0xF6, 0xF8, 0xFB, 0xFD, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x7F, 0xFF, 0xFC, 0xF8, +0xF9, 0xFD, 0x7D, 0x7C, 0x7F, 0xFE, 0x7E, 0x7C, 0x7A, 0x79, 0x77, 0x75, 0x75, 0x76, 0x79, 0x76, +0x71, 0x6F, 0x6F, 0x71, 0x76, 0x78, 0x78, 0x78, 0x7B, 0x7D, 0x7A, 0x77, 0x76, 0x76, 0x78, 0x79, +0x78, 0x79, 0x7C, 0xFD, 0xF4, 0xF1, 0xF2, 0xF5, 0xF9, 0xFB, 0x7F, 0x79, 0x76, 0x76, 0x78, 0x77, +0x77, 0x7B, 0xFF, 0xFA, 0xF6, 0xF6, 0xF7, 0xF6, 0xF6, 0xF7, 0xF9, 0xFA, 0xF9, 0xF6, 0xF6, 0xF9, +0xFB, 0xFE, 0x7F, 0x7E, 0x7C, 0x79, 0x7A, 0xFE, 0xF5, 0xEF, 0xEE, 0xEF, 0xF1, 0xF3, 0xF4, 0xFB, +0x79, 0x73, 0x72, 0x6E, 0x6B, 0x68, 0x68, 0x6C, 0x73, 0x7A, 0x7C, 0x7B, 0x7B, 0x7D, 0x7D, 0xFD, +0xF6, 0xF0, 0xEE, 0xEF, 0xF6, 0xFB, 0xFF, 0x7D, 0x7F, 0x7D, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, 0x7B, +0x7A, 0xFF, 0xFD, 0xFF, 0x7E, 0x7A, 0x75, 0x74, 0x71, 0x6F, 0x6F, 0x70, 0x77, 0x7A, 0x78, 0x75, +0x72, 0x75, 0x73, 0x6F, 0x6F, 0x70, 0x75, 0x77, 0x76, 0x78, 0x75, 0x78, 0x7B, 0x7B, 0x7F, 0x7B, +0x7E, 0x7F, 0x7E, 0x7E, 0x77, 0x79, 0x73, 0x71, 0x71, 0x6B, 0x6F, 0x60, 0x5B, 0x6F, 0x72, 0x69, +0x71, 0x72, 0x7E, 0xFC, 0xF7, 0xEE, 0xF4, 0xFB, 0x7E, 0x7E, 0xFC, 0xF9, 0xFD, 0x7F, 0xFC, 0x72, +0x78, 0x64, 0x53, 0x71, 0xDF, 0xF0, 0xEB, 0xE9, 0xF0, 0x7C, 0x7B, 0xEA, 0xF6, 0x7E, 0x79, 0x6C, +0x79, 0x5F, 0x5B, 0xEC, 0xE2, 0xEF, 0xED, 0xF1, 0xF7, 0xFE, 0x7C, 0xFE, 0x75, 0x6E, 0x75, 0x79, +0x7A, 0x72, 0x6E, 0x75, 0x7A, 0x7B, 0x77, 0x77, 0xFE, 0xF8, 0xF6, 0xF5, 0xEB, 0xE9, 0xEC, 0xE8, +0xEE, 0xEC, 0xED, 0x77, 0xFD, 0x61, 0x51, 0x66, 0xE7, 0xDC, 0xD8, 0xD3, 0xD3, 0x6C, 0x52, 0x63, +0x6F, 0x73, 0x7F, 0xFB, 0xF4, 0x79, 0x7B, 0xF1, 0xED, 0xEC, 0xFA, 0x76, 0x7A, 0x74, 0x6B, 0x6B, +0x75, 0x7C, 0x7C, 0x79, 0xFE, 0xF6, 0xFE, 0x7A, 0x71, 0x75, 0xFF, 0x70, 0x6D, 0x6E, 0x69, 0x66, +0x5E, 0x62, 0xFA, 0xEA, 0xE5, 0xE0, 0xE1, 0xE5, 0xEE, 0xF1, 0xE5, 0xE4, 0xEA, 0xE8, 0xE7, 0xE7, +0xE3, 0xE7, 0xE8, 0xE8, 0xEF, 0xF7, 0x78, 0x6E, 0x6D, 0x60, 0x5A, 0x57, 0x54, 0x53, 0x51, 0x50, +0x52, 0x54, 0x57, 0x59, 0x5D, 0x67, 0x70, 0x7B, 0xF5, 0xE5, 0xDA, 0xD5, 0xD2, 0xCD, 0xC4, 0xBE, +0xBB, 0xB7, 0xB5, 0xBB, 0xCB, 0xDE, 0xE9, 0x56, 0x3F, 0x3A, 0x39, 0x3B, 0x3B, 0x3A, 0x3F, 0x4E, +0x5D, 0x69, 0xF2, 0xDD, 0xD9, 0xE2, 0xF3, 0xF4, 0x72, 0x5C, 0x53, 0x4E, 0x4D, 0x4E, 0x4E, 0x4F, +0x58, 0x7E, 0xDA, 0xCB, 0xBF, 0xBA, 0xB7, 0xB4, 0xB0, 0xAE, 0xB2, 0xBE, 0xD7, 0x70, 0x4E, 0x3B, +0x32, 0x30, 0x33, 0x35, 0x35, 0x3A, 0x49, 0x5F, 0x7E, 0xEF, 0xE1, 0xD2, 0xD1, 0xE6, 0xEF, 0xF7, +0x5F, 0x4F, 0x48, 0x48, 0x4B, 0x48, 0x4B, 0x55, 0x72, 0xE1, 0xD2, 0xC2, 0xBA, 0xB6, 0xB3, 0xB0, +0xAD, 0xAE, 0xBA, 0xD0, 0x64, 0x4C, 0x3C, 0x30, 0x2E, 0x2F, 0x33, 0x35, 0x3A, 0x47, 0x6C, 0xE6, +0xEB, 0xD0, 0xC6, 0xCC, 0xD6, 0xE3, 0xEF, 0x69, 0x4E, 0x4B, 0x4B, 0x47, 0x46, 0x48, 0x4F, 0x61, +0xFE, 0xD1, 0xBE, 0xB8, 0xB5, 0xB2, 0xAF, 0xAD, 0xAE, 0xBA, 0xCD, 0x5F, 0x47, 0x3B, 0x2F, 0x2D, +0x2E, 0x30, 0x35, 0x3B, 0x47, 0x6C, 0xF4, 0xE2, 0xCB, 0xC7, 0xCD, 0xD7, 0xDD, 0xE3, 0x6E, 0x4E, +0x4A, 0x4B, 0x48, 0x47, 0x4A, 0x5B, 0xE4, 0xD3, 0xC0, 0xB7, 0xB3, 0xB0, 0xAF, 0xAC, 0xAC, 0xB3, +0xC4, 0x7D, 0x4C, 0x3E, 0x30, 0x2C, 0x2E, 0x31, 0x35, 0x3A, 0x45, 0x62, 0xFA, 0xEB, 0xCE, 0xCA, +0xD2, 0xDA, 0xE7, 0xE9, 0x6D, 0x4C, 0x49, 0x49, 0x47, 0x48, 0x4C, 0x68, 0xD7, 0xCA, 0xBC, 0xB5, +0xB2, 0xB0, 0xAE, 0xAC, 0xAE, 0xB9, 0xCE, 0x5D, 0x45, 0x39, 0x2F, 0x2D, 0x2E, 0x31, 0x36, 0x3B, +0x47, 0x5C, 0x6E, 0xE4, 0xD3, 0xD3, 0xD4, 0xDA, 0xDE, 0xEB, 0x5B, 0x4D, 0x4A, 0x47, 0x48, 0x49, +0x54, 0xEB, 0xCE, 0xBE, 0xB8, 0xB7, 0xB3, 0xB3, 0xB5, 0xB3, 0xBB, 0xC9, 0xC8, 0xED, 0x47, 0x42, +0x3A, 0x36, 0x37, 0x34, 0x39, 0x3E, 0x3F, 0x47, 0x4E, 0x65, 0xDE, 0xEC, 0xDC, 0xCE, 0xD9, 0xEB, +0x5F, 0x54, 0x51, 0x47, 0x46, 0x4C, 0x58, 0xFC, 0xD8, 0xC4, 0xBB, 0xBA, 0xB8, 0xB5, 0xB2, 0xAF, +0xB0, 0xB6, 0xBD, 0xCC, 0x66, 0x47, 0x3B, 0x34, 0x32, 0x32, 0x34, 0x38, 0x3B, 0x3F, 0x4B, 0x58, +0x69, 0xE9, 0xD9, 0xD4, 0xDB, 0x77, 0x5C, 0x59, 0x4F, 0x4A, 0x4B, 0x51, 0x69, 0xE0, 0xCE, 0xC2, +0xBD, 0xBC, 0xBA, 0xB8, 0xB7, 0xB4, 0xB2, 0xB7, 0xC3, 0xCE, 0xD4, 0x67, 0x44, 0x3D, 0x3C, 0x3B, +0x38, 0x38, 0x3B, 0x3F, 0x42, 0x46, 0x4E, 0x5F, 0x6A, 0x6B, 0xFD, 0xF7, 0x70, 0x5C, 0x54, 0x58, +0x58, 0x53, 0x5B, 0x73, 0xE5, 0xD2, 0xCA, 0xC6, 0xC2, 0xBF, 0xBE, 0xBE, 0xBD, 0xBB, 0xBC, 0xC3, +0xCA, 0xD0, 0xE2, 0x5F, 0x4E, 0x4A, 0x44, 0x3E, 0x3D, 0x3D, 0x3F, 0x42, 0x44, 0x4B, 0x55, 0x57, +0x5F, 0x69, 0x68, 0x63, 0x58, 0x56, 0x5B, 0x56, 0x57, 0x66, 0x79, 0xE8, 0xD9, 0xCF, 0xCB, 0xCB, +0xC8, 0xC4, 0xC5, 0xC6, 0xC9, 0xC9, 0xC6, 0xCD, 0xD4, 0xD8, 0xE2, 0xF1, 0x66, 0x5C, 0x57, 0x4C, +0x49, 0x49, 0x48, 0x49, 0x49, 0x4B, 0x51, 0x51, 0x4F, 0x53, 0x56, 0x58, 0x58, 0x54, 0x58, 0x5F, +0x5E, 0x5B, 0x63, 0xF2, 0xE5, 0xE5, 0xD7, 0xCF, 0xD2, 0xD6, 0xD1, 0xCF, 0xD6, 0xD6, 0xD2, 0xCF, +0xCE, 0xD0, 0xD8, 0xDB, 0xDB, 0xE5, 0x6D, 0x67, 0x65, 0x5C, 0x58, 0x54, 0x59, 0x5D, 0x57, 0x57, +0x5B, 0x5B, 0x59, 0x56, 0x57, 0x5A, 0x56, 0x52, 0x5A, 0x5C, 0x5D, 0x7D, 0xF1, 0xF3, 0xE7, 0xE3, +0xDF, 0xDB, 0xDA, 0xE7, 0xEC, 0xDE, 0xE5, 0xE9, 0xE6, 0xE4, 0xD6, 0xDF, 0xF8, 0xDE, 0xE9, 0x7C, +0xEE, 0xFB, 0x7A, 0x6B, 0x65, 0xFF, 0x79, 0x69, 0x6B, 0x63, 0x65, 0x62, 0x56, 0x5A, 0x60, 0x55, +0x58, 0x62, 0x5E, 0x64, 0x79, 0x7C, 0x78, 0xED, 0xE1, 0xEC, 0xF0, 0xE4, 0xF0, 0x6E, 0x7C, 0xED, +0xDD, 0xDB, 0xFE, 0x73, 0xED, 0xF0, 0xFF, 0xF9, 0xDE, 0xDC, 0x76, 0x6E, 0xFB, 0x7B, 0xFB, 0x6F, +0x6F, 0xEF, 0x7B, 0x6E, 0xF8, 0xE9, 0x7E, 0x5B, 0x5F, 0xF3, 0xFD, 0x67, 0x74, 0xEA, 0xEF, 0x77, +0x6D, 0x7C, 0xE8, 0xE2, 0xEE, 0xFB, 0xE6, 0xED, 0x66, 0x6C, 0x7B, 0x7C, 0xF4, 0xEF, 0xE2, 0xE6, +0x72, 0x70, 0xF0, 0xEE, 0x6E, 0x6B, 0xFB, 0xF5, 0xF6, 0x71, 0x6A, 0x6C, 0x65, 0x67, 0x5F, 0x5D, +0x6B, 0x62, 0x65, 0xFD, 0xED, 0xE9, 0xF2, 0xED, 0xE3, 0xE7, 0xE4, 0xE8, 0xED, 0xEF, 0x66, 0x5E, +0x79, 0x7E, 0x78, 0xF5, 0xFA, 0x79, 0x7A, 0xF5, 0xE7, 0xE2, 0xE4, 0xF2, 0xFF, 0x73, 0x66, 0x6B, +0x70, 0xFD, 0xEF, 0x6F, 0x67, 0x5F, 0x5C, 0x6B, 0x6E, 0x78, 0x77, 0x6D, 0xF1, 0xF4, 0xF8, 0xE5, +0xE9, 0xEB, 0xEC, 0xEF, 0xEF, 0xF0, 0xE7, 0xED, 0x6B, 0x6F, 0xF0, 0xFF, 0x6A, 0x6F, 0x7E, 0x6F, +0x69, 0xED, 0xDF, 0xFF, 0x7C, 0xEB, 0xF3, 0xF8, 0x7E, 0x7A, 0xFB, 0x6E, 0x5E, 0x60, 0x70, 0x7A, +0xFC, 0xF4, 0xFF, 0xEF, 0xF5, 0x72, 0xF1, 0xEC, 0xEA, 0xE1, 0xE9, 0xED, 0xF2, 0xFC, 0xE7, 0xF0, +0x68, 0x76, 0xEF, 0xF4, 0xF9, 0x77, 0x79, 0xFB, 0xFC, 0xF6, 0xEE, 0xE9, 0xF2, 0x6D, 0x70, 0x6F, +0x6F, 0xFE, 0x6A, 0x69, 0x7F, 0x6F, 0x6F, 0x79, 0x78, 0x77, 0x6E, 0xFE, 0xEE, 0xF0, 0xEF, 0x7E, +0xF4, 0xE9, 0xF8, 0xFD, 0x7C, 0x77, 0x7D, 0x78, 0x7D, 0xFE, 0x79, 0x72, 0x6E, 0x72, 0x7B, 0x73, +0x6B, 0x74, 0x76, 0x6C, 0x72, 0x70, 0x75, 0x6D, 0x5A, 0x5C, 0x6A, 0x77, 0xFE, 0x71, 0x7A, 0xF2, +0xE9, 0xE7, 0xEA, 0xDE, 0xE6, 0xF5, 0xEB, 0xF5, 0xEE, 0xEA, 0xF3, 0xEE, 0xF4, 0xEE, 0xF5, 0x73, +0xF4, 0xF6, 0x73, 0x7C, 0xEC, 0xE9, 0x72, 0x67, 0x6C, 0x70, 0x6E, 0x69, 0x6F, 0x68, 0x5D, 0x64, +0x71, 0x75, 0x6B, 0x6D, 0xF9, 0x79, 0x6F, 0xF4, 0xEA, 0xF5, 0x79, 0x7B, 0x7D, 0xFA, 0xF3, 0xF7, +0xF4, 0xF4, 0xF9, 0x7F, 0x77, 0x7F, 0xF5, 0xFD, 0x71, 0x71, 0x7B, 0x78, 0x7A, 0x73, 0x68, 0x71, +0x7A, 0x6B, 0x6C, 0x6E, 0x69, 0x6E, 0x71, 0x6C, 0x69, 0x6C, 0x7A, 0x7D, 0xF6, 0xEB, 0xF4, 0xF2, +0xF4, 0x78, 0xF8, 0xF1, 0xF6, 0xFE, 0x71, 0x75, 0x7C, 0x7B, 0x7D, 0x7E, 0xFB, 0x7E, 0x77, 0x76, +0xFF, 0xF7, 0x79, 0x70, 0x6E, 0x6C, 0x71, 0x6F, 0x6C, 0x6A, 0x70, 0x6E, 0x5F, 0x65, 0x6C, 0x66, +0x6D, 0x7A, 0xF1, 0x78, 0x6B, 0xED, 0xFB, 0x6C, 0x7C, 0x74, 0xF1, 0xEC, 0x76, 0xF9, 0xF8, 0x75, +0x71, 0x7A, 0xEC, 0xFA, 0x6C, 0x76, 0x7C, 0x7F, 0x6E, 0x6A, 0x76, 0x6C, 0x76, 0xF2, 0x7C, 0x76, +0x66, 0x62, 0x7D, 0xF9, 0x78, 0x69, 0x6A, 0xF8, 0x78, 0x6D, 0xFC, 0xF8, 0xF3, 0xF7, 0x7D, 0xEF, +0xF1, 0x7C, 0xF1, 0xE9, 0xEB, 0xEE, 0xF3, 0xFD, 0x73, 0x7D, 0xFA, 0x74, 0x78, 0x7A, 0x6E, 0x70, +0x76, 0x73, 0x6F, 0x6D, 0x6C, 0x68, 0x6D, 0x7D, 0x6E, 0x64, 0x6D, 0xFC, 0xFA, 0x71, 0x6F, 0xFF, +0x70, 0x70, 0xF0, 0xEE, 0xEF, 0xEB, 0xEC, 0xEC, 0xED, 0xF0, 0xEE, 0xE9, 0xEB, 0xF8, 0xFB, 0xED, +0xE9, 0xF7, 0xFF, 0xED, 0xEE, 0xEF, 0xF3, 0x6E, 0x70, 0xF3, 0xFF, 0x6F, 0x6F, 0x6F, 0x79, 0x7C, +0x79, 0x7E, 0x77, 0x6E, 0x6E, 0x7B, 0x7C, 0x6B, 0x72, 0xF6, 0xFF, 0x7D, 0x7D, 0x72, 0x78, 0xFB, +0xFD, 0xFB, 0xFA, 0x7D, 0x7A, 0x6D, 0x68, 0x74, 0x75, 0xF1, 0xE7, 0x7B, 0x76, 0x6B, 0x66, 0xFD, +0x73, 0x68, 0x6B, 0x73, 0x7C, 0x62, 0x64, 0x70, 0x64, 0x6D, 0x79, 0x70, 0x70, 0x74, 0xF8, 0x7C, +0x7C, 0xF8, 0x6B, 0x70, 0xF9, 0x7D, 0xF1, 0xF0, 0xFF, 0x7F, 0xF8, 0xED, 0xF2, 0xFC, 0xFF, 0x76, +0x7B, 0x7C, 0xFE, 0xFE, 0x6C, 0x7C, 0xED, 0x79, 0x77, 0x71, 0x69, 0x76, 0x7A, 0x76, 0x7A, 0x6F, +0x6E, 0x6E, 0x73, 0xFF, 0x78, 0x76, 0x7F, 0x7A, 0x6F, 0x78, 0xFE, 0x77, 0xFB, 0xEE, 0xEE, 0xF1, +0x7A, 0xFB, 0xEE, 0x75, 0x70, 0xFE, 0x7D, 0x72, 0x6D, 0x6F, 0x7B, 0xFB, 0xF9, 0x7C, 0x7E, 0x7A, +0x70, 0x76, 0x7B, 0xF7, 0xF5, 0x70, 0x74, 0xFF, 0x78, 0xFA, 0xFC, 0x79, 0x78, 0x6D, 0x7A, 0xFA, +0x77, 0xFC, 0xF4, 0xF1, 0xF1, 0xF7, 0xEB, 0xED, 0xFB, 0xF7, 0xEF, 0xF2, 0x78, 0x79, 0xF0, 0xF3, +0xFC, 0xFC, 0x7E, 0x77, 0xFF, 0xFC, 0x78, 0xF6, 0xF9, 0x6F, 0x7A, 0x78, 0x6F, 0xFF, 0xF9, 0x7E, +0x76, 0x72, 0x76, 0x78, 0x79, 0xFD, 0xFA, 0x7A, 0x7E, 0xF1, 0xFB, 0x7A, 0xF2, 0xEF, 0xFF, 0x74, +0x75, 0x7E, 0xFF, 0xF6, 0xE9, 0xF4, 0x71, 0x74, 0x74, 0x7C, 0xF8, 0x79, 0x75, 0x74, 0x73, 0xF9, +0xFE, 0xFF, 0xFA, 0x6A, 0x6C, 0xFE, 0x70, 0x72, 0x7C, 0x7D, 0x70, 0x67, 0x6F, 0x76, 0x7B, 0xF0, +0x7E, 0x6E, 0x6E, 0x76, 0xF1, 0xF2, 0x7A, 0x72, 0x7B, 0xFD, 0x79, 0x77, 0x6E, 0x6A, 0x6D, 0x6E, +0x74, 0x72, 0x77, 0xF5, 0x7C, 0x6D, 0x6C, 0x6D, 0x70, 0x76, 0xFD, 0xFC, 0xFF, 0xFE, 0xFE, 0xFA, +0x7D, 0x77, 0x74, 0x6F, 0xFB, 0xFA, 0x71, 0xFC, 0xF8, 0xFE, 0xEB, 0xE5, 0xEE, 0x7F, 0xF6, 0xED, +0xFA, 0x78, 0xF6, 0xF1, 0xF8, 0xF6, 0x79, 0x70, 0x7C, 0x75, 0x78, 0xF6, 0xFA, 0xFC, 0xFB, 0x7B, +0x7D, 0xF9, 0xF7, 0xF7, 0x7E, 0x6B, 0x68, 0xFA, 0xE6, 0xEE, 0x7B, 0x7B, 0x79, 0x7E, 0xFB, 0xF2, +0xEA, 0xEE, 0xF1, 0xF6, 0x79, 0xFB, 0xF0, 0xFB, 0xFF, 0xF0, 0xEE, 0xF4, 0xEF, 0xFB, 0x6F, 0x6C, +0x72, 0xFF, 0x71, 0x6C, 0x6A, 0x6D, 0xF4, 0xFB, 0x7C, 0xF3, 0xFA, 0xFC, 0x6F, 0x73, 0xFB, 0x72, +0x7D, 0x78, 0x76, 0xEF, 0xF3, 0x7C, 0x71, 0xFA, 0xF2, 0xFB, 0xEF, 0xF0, 0xEA, 0xFD, 0x6B, 0xED, +0xF2, 0x77, 0x6E, 0x6D, 0xFD, 0x64, 0xF3, 0xDF, 0x5C, 0x61, 0xED, 0xF2, 0x7E, 0x66, 0x73, 0x6E, +0x66, 0xFF, 0x6F, 0x72, 0x70, 0x66, 0xF3, 0xF7, 0x6F, 0x72, 0x75, 0xED, 0xEF, 0xF4, 0xED, 0xEF, +0xEF, 0x6E, 0x6F, 0xF7, 0x72, 0x7E, 0x78, 0x6F, 0xF9, 0x77, 0xFC, 0xF4, 0x6C, 0x66, 0x6A, 0x76, +0x65, 0x5C, 0x6D, 0xFF, 0xF8, 0xEA, 0xE2, 0xEF, 0x65, 0x70, 0xEB, 0xE8, 0xE2, 0xDF, 0xDA, 0xD9, +0xE3, 0xF0, 0xFA, 0xE6, 0xDD, 0xDF, 0xDF, 0xE0, 0xE4, 0xFC, 0x63, 0x60, 0x64, 0x63, 0x66, 0x78, +0x65, 0x57, 0x60, 0x67, 0x64, 0x67, 0x5F, 0x6E, 0xF3, 0x7F, 0x75, 0xFE, 0xEA, 0xF4, 0xF8, 0xE0, +0xE0, 0xE4, 0xE3, 0xE7, 0xEA, 0xFB, 0x6F, 0x6E, 0x75, 0x72, 0x68, 0x6E, 0x77, 0x74, 0x6D, 0x73, +0xF9, 0x74, 0xF2, 0xE2, 0xEF, 0xDE, 0xDD, 0x79, 0xFD, 0xF4, 0x6F, 0x6A, 0x6E, 0xFE, 0x7A, 0x68, +0x60, 0x63, 0x6B, 0x66, 0x67, 0x76, 0xFE, 0x78, 0x65, 0x63, 0x7A, 0xFF, 0x72, 0x72, 0x74, 0x7D, +0x7C, 0x6B, 0x72, 0xEF, 0xF6, 0x73, 0x74, 0x7C, 0x74, 0x68, 0x68, 0x73, 0xFA, 0xF6, 0x6F, 0x67, +0x6F, 0x6D, 0x6A, 0x69, 0x68, 0x74, 0x6D, 0x64, 0x6F, 0x75, 0x77, 0xFA, 0x7F, 0xF5, 0xEF, 0x78, +0x77, 0x7D, 0x7A, 0xFE, 0x77, 0x73, 0xF8, 0xF4, 0xFE, 0x6F, 0x71, 0xF7, 0x74, 0x79, 0xEF, 0x7B, +0xF9, 0xFA, 0x68, 0x71, 0x7F, 0x76, 0x73, 0x71, 0x7D, 0x7D, 0x65, 0x5D, 0x69, 0x6E, 0x5F, 0x67, +0x6F, 0x6D, 0xFF, 0x7F, 0x6E, 0x6F, 0x73, 0x77, 0xF2, 0xDE, 0xD4, 0xD0, 0xD0, 0xCF, 0xCE, 0xD0, +0xD2, 0xD6, 0xDA, 0xDB, 0xE7, 0x6D, 0x5B, 0x52, 0x4C, 0x47, 0x44, 0x43, 0x44, 0x47, 0x49, 0x4B, +0x4E, 0x52, 0x56, 0x5A, 0x5D, 0x64, 0x75, 0xE6, 0xCF, 0xC5, 0xBF, 0xBD, 0xBB, 0xB7, 0xB5, 0xB1, +0xAF, 0xB5, 0xC1, 0xDF, 0x51, 0x44, 0x3A, 0x33, 0x33, 0x37, 0x3D, 0x44, 0x48, 0x4D, 0x51, 0x54, +0x53, 0x4D, 0x49, 0x44, 0x43, 0x45, 0x46, 0x4C, 0x54, 0x65, 0xE4, 0xCF, 0xC4, 0xBB, 0xB4, 0xAF, +0xAD, 0xAC, 0xAA, 0xAB, 0xB5, 0xD1, 0x49, 0x3B, 0x35, 0x2F, 0x2D, 0x32, 0x3D, 0x4E, 0x57, 0x51, +0x4F, 0x50, 0x4C, 0x42, 0x3D, 0x3F, 0x46, 0x4A, 0x4F, 0x5E, 0xEC, 0xD9, 0xDA, 0xD2, 0xC8, 0xBE, +0xB7, 0xB0, 0xAD, 0xAB, 0xA9, 0xA8, 0xAD, 0xC4, 0x48, 0x36, 0x31, 0x2E, 0x2D, 0x30, 0x3E, 0x67, +0xE2, 0x63, 0x47, 0x43, 0x42, 0x39, 0x36, 0x3B, 0x46, 0x6B, 0xE1, 0xDB, 0xCC, 0xC8, 0xCC, 0xD7, +0xDD, 0xC6, 0xBA, 0xB2, 0xAC, 0xAA, 0xA7, 0xA7, 0xB0, 0x69, 0x32, 0x2D, 0x2D, 0x2C, 0x2D, 0x39, +0xF1, 0xC2, 0xCA, 0x5E, 0x3D, 0x38, 0x34, 0x2E, 0x2F, 0x3E, 0x69, 0xCC, 0xC3, 0xBD, 0xBD, 0xC2, +0xCD, 0xEC, 0xF4, 0xCD, 0xC0, 0xB7, 0xAC, 0xA7, 0xA4, 0xA4, 0xB7, 0x3A, 0x2A, 0x29, 0x2A, 0x2B, +0x30, 0x56, 0xBA, 0xB6, 0xCD, 0x4A, 0x33, 0x2C, 0x2C, 0x2B, 0x34, 0x65, 0xC3, 0xBB, 0xBB, 0xBC, +0xC1, 0xDA, 0x7F, 0x6A, 0x75, 0xD1, 0xC2, 0xB8, 0xAC, 0xA6, 0xA5, 0xA4, 0xB0, 0x35, 0x23, 0x25, +0x29, 0x2F, 0x38, 0x73, 0xB3, 0xAF, 0xC8, 0x3E, 0x2E, 0x29, 0x26, 0x2C, 0x3D, 0xDF, 0xB8, 0xB5, +0xBB, 0xC5, 0xE7, 0x5A, 0x53, 0x68, 0xD9, 0xC8, 0xBA, 0xB3, 0xAD, 0xA8, 0xA7, 0xA6, 0xAF, 0x34, +0x1F, 0x24, 0x2E, 0x3B, 0x48, 0xDA, 0xB3, 0xB0, 0xD6, 0x33, 0x29, 0x29, 0x29, 0x2F, 0x5B, 0xC3, +0xB9, 0xB8, 0xC1, 0xDB, 0x53, 0x46, 0x4E, 0xEE, 0xCB, 0xC5, 0xBF, 0xBA, 0xB6, 0xAE, 0xAA, 0xA8, +0xAA, 0xDB, 0x26, 0x20, 0x2B, 0x3E, 0x5E, 0xEE, 0xC1, 0xB6, 0xC1, 0x3F, 0x2A, 0x29, 0x2A, 0x2F, +0x4F, 0xCA, 0xC0, 0xBE, 0xC5, 0xDC, 0x51, 0x44, 0x4B, 0x7D, 0xCB, 0xC5, 0xC5, 0xC2, 0xBF, 0xBD, +0xB1, 0xA9, 0xA8, 0xAA, 0xCB, 0x28, 0x20, 0x2C, 0x44, 0x7E, 0xDE, 0xC8, 0xBB, 0xC6, 0x3F, 0x2B, +0x29, 0x2E, 0x35, 0x4C, 0xCB, 0xBF, 0xC3, 0xCA, 0xE6, 0x4E, 0x43, 0x44, 0x6A, 0xC8, 0xC3, 0xC3, +0xC8, 0xC8, 0xBE, 0xB5, 0xAB, 0xA7, 0xA8, 0xBC, 0x2D, 0x1F, 0x29, 0x42, 0xD7, 0xD0, 0xCD, 0xBF, +0xC5, 0x4C, 0x2E, 0x2B, 0x2F, 0x36, 0x4A, 0xD7, 0xBE, 0xBD, 0xD5, 0x74, 0x50, 0x42, 0x45, 0x53, +0xD1, 0xBE, 0xBE, 0xC5, 0xD2, 0xCD, 0xBC, 0xAE, 0xA7, 0xA7, 0xB5, 0x36, 0x21, 0x28, 0x41, 0xD1, +0xC9, 0xD4, 0xCB, 0xCB, 0x51, 0x31, 0x2B, 0x2F, 0x39, 0x47, 0xE9, 0xC5, 0xC0, 0xCD, 0xED, 0x50, +0x3F, 0x3F, 0x52, 0xCD, 0xBB, 0xBC, 0xC6, 0xDE, 0xE7, 0xCB, 0xB5, 0xA8, 0xA4, 0xA9, 0xCC, 0x28, +0x20, 0x2E, 0x6F, 0xC2, 0xCF, 0xF7, 0xDA, 0xEB, 0x3F, 0x2E, 0x2D, 0x34, 0x3E, 0x5D, 0xCD, 0xBF, +0xC7, 0x73, 0x53, 0x43, 0x3C, 0x49, 0xDD, 0xBC, 0xB7, 0xC2, 0xE4, 0x62, 0xEC, 0xBD, 0xAA, 0xA3, +0xA4, 0xB3, 0x32, 0x1F, 0x26, 0x42, 0xC3, 0xC0, 0xF2, 0x68, 0x73, 0x4D, 0x37, 0x2D, 0x2F, 0x39, +0x47, 0xDD, 0xC2, 0xBE, 0xD2, 0x4A, 0x3E, 0x3B, 0x42, 0xEB, 0xBE, 0xB5, 0xB9, 0xD5, 0x54, 0x54, +0xCB, 0xAD, 0xA3, 0xA2, 0xAC, 0x4D, 0x23, 0x21, 0x34, 0xCF, 0xBA, 0xD0, 0x5E, 0x73, 0x5D, 0x43, +0x34, 0x30, 0x38, 0x3C, 0x46, 0xCE, 0xB9, 0xBE, 0x5F, 0x3E, 0x3B, 0x3E, 0x62, 0xC0, 0xB5, 0xB6, +0xC9, 0x54, 0x48, 0xE3, 0xB1, 0xA4, 0xA0, 0xA6, 0xC3, 0x2B, 0x1E, 0x29, 0x5D, 0xB9, 0xBD, 0x72, +0x50, 0x5B, 0x50, 0x3C, 0x30, 0x30, 0x36, 0x3F, 0x7C, 0xC0, 0xBA, 0xD0, 0x45, 0x3A, 0x38, 0x46, +0xCB, 0xB7, 0xB5, 0xC4, 0x5A, 0x48, 0x62, 0xBA, 0xA8, 0xA1, 0xA3, 0xB0, 0x3C, 0x20, 0x20, 0x39, +0xBD, 0xB1, 0xC7, 0x4F, 0x4A, 0x4E, 0x48, 0x35, 0x2E, 0x31, 0x39, 0x56, 0xC0, 0xB8, 0xC2, 0x4D, +0x39, 0x37, 0x3E, 0xE2, 0xBC, 0xB6, 0xBB, 0xDC, 0x4B, 0x4A, 0xD3, 0xAE, 0xA3, 0xA0, 0xA8, 0xD5, +0x29, 0x1F, 0x2B, 0xE3, 0xB3, 0xBA, 0x65, 0x47, 0x4C, 0x4F, 0x3D, 0x2F, 0x2D, 0x30, 0x41, 0xCB, +0xB7, 0xBA, 0x76, 0x3D, 0x38, 0x39, 0x51, 0xC5, 0xB6, 0xB6, 0xCC, 0x50, 0x46, 0x7E, 0xB4, 0xA6, +0xA1, 0xA4, 0xB8, 0x35, 0x20, 0x25, 0x48, 0xB8, 0xB5, 0xDB, 0x47, 0x47, 0x52, 0x4A, 0x34, 0x2D, +0x2E, 0x39, 0xEC, 0xBA, 0xB6, 0xCF, 0x3F, 0x38, 0x37, 0x41, 0xD0, 0xB8, 0xB4, 0xBF, 0x6A, 0x4A, +0x5B, 0xBC, 0xA8, 0xA1, 0xA2, 0xAF, 0x3E, 0x22, 0x24, 0x3E, 0xBA, 0xB3, 0xD4, 0x45, 0x41, 0x4F, +0x52, 0x37, 0x2D, 0x2D, 0x36, 0x65, 0xBB, 0xB6, 0xC9, 0x46, 0x38, 0x35, 0x3D, 0xDC, 0xB7, 0xB0, +0xBA, 0xF0, 0x48, 0x4E, 0xC1, 0xAA, 0xA2, 0xA1, 0xAB, 0x5E, 0x27, 0x21, 0x32, 0xC7, 0xB4, 0xC8, +0x48, 0x3E, 0x4B, 0x58, 0x3D, 0x2E, 0x2C, 0x2F, 0x48, 0xBF, 0xB5, 0xBF, 0x4C, 0x36, 0x34, 0x3A, +0x67, 0xBC, 0xB2, 0xB7, 0xD6, 0x4C, 0x4A, 0xCE, 0xAD, 0xA3, 0xA0, 0xA7, 0xD8, 0x29, 0x20, 0x2F, +0xD2, 0xB5, 0xC4, 0x4C, 0x40, 0x4B, 0x64, 0x44, 0x2F, 0x2C, 0x2D, 0x3F, 0xC4, 0xB4, 0xB9, 0x5F, +0x39, 0x36, 0x39, 0x5D, 0xBE, 0xB3, 0xB4, 0xC8, 0x59, 0x4B, 0xDC, 0xAF, 0xA3, 0x9F, 0xA5, 0xC5, +0x2C, 0x21, 0x2C, 0xFB, 0xB9, 0xC1, 0x53, 0x42, 0x4A, 0x5F, 0x49, 0x31, 0x2C, 0x2C, 0x3A, 0xCF, +0xB6, 0xBA, 0xF7, 0x3E, 0x39, 0x3A, 0x4C, 0xCA, 0xB7, 0xB4, 0xBF, 0x79, 0x4D, 0xE5, 0xB1, 0xA4, +0x9F, 0xA4, 0xC6, 0x2B, 0x20, 0x2C, 0xEC, 0xB7, 0xC1, 0x57, 0x43, 0x49, 0x5C, 0x47, 0x31, 0x2C, +0x2C, 0x39, 0xD3, 0xB7, 0xBA, 0xDC, 0x46, 0x3C, 0x39, 0x47, 0xCE, 0xB9, 0xB5, 0xBD, 0xDE, 0x5E, +0xD3, 0xB0, 0xA4, 0xA0, 0xA6, 0xCF, 0x2A, 0x21, 0x2D, 0xF6, 0xBB, 0xC8, 0x55, 0x44, 0x48, 0x51, +0x3F, 0x2F, 0x2C, 0x2D, 0x3B, 0xD8, 0xBC, 0xBF, 0xE7, 0x4E, 0x45, 0x3C, 0x44, 0xEB, 0xBE, 0xB5, +0xBA, 0xCA, 0xE3, 0xC9, 0xAF, 0xA5, 0xA0, 0xA7, 0xE6, 0x28, 0x22, 0x2E, 0xEA, 0xBD, 0xC8, 0x5D, +0x46, 0x4A, 0x4D, 0x3B, 0x2F, 0x2D, 0x2F, 0x3F, 0xD0, 0xBE, 0xC3, 0xE6, 0x56, 0x4B, 0x43, 0x4C, +0xFA, 0xC8, 0xBB, 0xBB, 0xC3, 0xC8, 0xBD, 0xAE, 0xA7, 0xA3, 0xAA, 0x6C, 0x2A, 0x25, 0x30, 0x5A, +0xCD, 0xD3, 0x5F, 0x4D, 0x50, 0x4C, 0x3B, 0x2F, 0x2D, 0x2F, 0x3D, 0xE6, 0xCC, 0xD3, 0xDA, 0xDB, +0x79, 0x55, 0x56, 0x68, 0xE0, 0xCA, 0xC2, 0xC0, 0xBC, 0xB1, 0xAB, 0xA6, 0xA5, 0xAE, 0x53, 0x2C, +0x29, 0x30, 0x41, 0x59, 0x62, 0x53, 0x57, 0x7F, 0x5D, 0x40, 0x35, 0x2E, 0x2F, 0x3D, 0x58, 0x78, +0xE5, 0xCD, 0xC8, 0xCF, 0xDA, 0xEC, 0x7B, 0xE4, 0xD1, 0xCA, 0xC4, 0xBA, 0xB0, 0xAC, 0xAA, 0xAB, +0xBA, 0x4F, 0x39, 0x39, 0x3D, 0x3F, 0x42, 0x3D, 0x3C, 0x45, 0x51, 0x52, 0x4C, 0x42, 0x3B, 0x3E, +0x4A, 0x4C, 0x4D, 0x57, 0x69, 0xEE, 0xDE, 0xE4, 0xFD, 0xED, 0xDC, 0xD3, 0xCD, 0xCA, 0xC3, 0xBD, +0xB9, 0xB6, 0xB8, 0xC3, 0xCE, 0xC8, 0xC1, 0xC5, 0xCE, 0xF9, 0x4A, 0x3F, 0x3F, 0x41, 0x3F, 0x3D, +0x39, 0x38, 0x3B, 0x3C, 0x3A, 0x3C, 0x43, 0x4C, 0x52, 0x58, 0x5B, 0x59, 0x65, 0xDC, 0xCB, 0xC3, +0xBD, 0xB8, 0xB6, 0xB2, 0xAF, 0xB2, 0xB6, 0xB2, 0xB0, 0xB6, 0xBF, 0xD7, 0x4F, 0x40, 0x3F, 0x3D, +0x3A, 0x35, 0x2F, 0x2D, 0x2F, 0x32, 0x33, 0x34, 0x39, 0x3E, 0x46, 0x51, 0x59, 0x5C, 0x6F, 0xD8, +0xC6, 0xBD, 0xB8, 0xB4, 0xB2, 0xAF, 0xAC, 0xAD, 0xAF, 0xAE, 0xAE, 0xB2, 0xBC, 0xCF, 0x55, 0x42, +0x3E, 0x3B, 0x36, 0x31, 0x2D, 0x2A, 0x2B, 0x2F, 0x32, 0x33, 0x36, 0x3B, 0x40, 0x4A, 0x57, 0x69, +0xEE, 0xD6, 0xC8, 0xBF, 0xB9, 0xB3, 0xB1, 0xAF, 0xAC, 0xAB, 0xAE, 0xAF, 0xAF, 0xB1, 0xB9, 0xC6, +0x75, 0x46, 0x3D, 0x3A, 0x36, 0x30, 0x2D, 0x2B, 0x2A, 0x2D, 0x31, 0x34, 0x36, 0x39, 0x3E, 0x46, +0x56, 0x77, 0xE3, 0xD4, 0xCA, 0xC3, 0xBD, 0xB6, 0xB1, 0xAF, 0xAC, 0xAB, 0xAC, 0xAF, 0xAF, 0xB0, +0xB5, 0xBE, 0xDA, 0x4E, 0x3E, 0x3A, 0x36, 0x31, 0x2D, 0x2C, 0x2B, 0x2C, 0x2F, 0x32, 0x34, 0x38, +0x3D, 0x43, 0x4D, 0x66, 0xE7, 0xD6, 0xCB, 0xC5, 0xC0, 0xBA, 0xB3, 0xAF, 0xAD, 0xAB, 0xAC, 0xAE, +0xAF, 0xAF, 0xB3, 0xBB, 0xCD, 0x5A, 0x40, 0x3A, 0x36, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, 0x2F, 0x31, +0x32, 0x38, 0x3D, 0x41, 0x4B, 0x5C, 0xF8, 0xD8, 0xCA, 0xC3, 0xBF, 0xBA, 0xB4, 0xB0, 0xAD, 0xAB, +0xAB, 0xAE, 0xAF, 0xB0, 0xB3, 0xBA, 0xC9, 0x68, 0x46, 0x3C, 0x37, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, +0x2F, 0x30, 0x31, 0x36, 0x3C, 0x3F, 0x49, 0x58, 0x70, 0xDD, 0xCA, 0xC2, 0xBE, 0xB9, 0xB3, 0xB0, +0xAD, 0xAA, 0xAB, 0xAE, 0xAF, 0xAF, 0xB4, 0xBC, 0xCB, 0x61, 0x46, 0x3D, 0x36, 0x30, 0x2E, 0x2C, +0x2B, 0x2D, 0x2F, 0x2F, 0x31, 0x37, 0x3B, 0x3F, 0x4B, 0x5C, 0xFF, 0xD8, 0xC8, 0xC1, 0xBC, 0xB6, +0xB2, 0xAF, 0xAC, 0xAA, 0xAB, 0xAD, 0xAE, 0xAF, 0xB5, 0xBD, 0xCF, 0x5C, 0x45, 0x3C, 0x35, 0x2F, +0x2D, 0x2C, 0x2C, 0x2D, 0x2F, 0x2F, 0x32, 0x37, 0x3B, 0x3F, 0x4B, 0x5F, 0xEE, 0xD4, 0xC8, 0xC1, +0xBC, 0xB5, 0xB0, 0xAE, 0xAB, 0xAA, 0xAB, 0xAD, 0xAF, 0xB1, 0xB7, 0xC0, 0xD9, 0x53, 0x42, 0x3B, +0x34, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x30, 0x33, 0x37, 0x3C, 0x43, 0x4D, 0x5E, 0xEC, 0xD0, +0xC7, 0xC0, 0xBB, 0xB6, 0xB0, 0xAE, 0xAB, 0xAA, 0xAC, 0xAE, 0xAF, 0xB3, 0xB9, 0xC5, 0xE2, 0x4E, +0x3F, 0x39, 0x32, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x2F, 0x33, 0x39, 0x3D, 0x44, 0x4F, 0x65, +0xE3, 0xCE, 0xC5, 0xBF, 0xBA, 0xB4, 0xAF, 0xAD, 0xAA, 0xAA, 0xAC, 0xAE, 0xB0, 0xB5, 0xBB, 0xC8, +0xF8, 0x4C, 0x3E, 0x38, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, 0x2E, 0x2F, 0x31, 0x35, 0x39, 0x3E, 0x4A, +0x5C, 0xF9, 0xD8, 0xCB, 0xC2, 0xBC, 0xB7, 0xB2, 0xAE, 0xAB, 0xA9, 0xAA, 0xAC, 0xAE, 0xB2, 0xB8, +0xBE, 0xCE, 0x72, 0x48, 0x3B, 0x34, 0x2F, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x31, 0x36, 0x3A, +0x3E, 0x4A, 0x5F, 0xEA, 0xD0, 0xC9, 0xC1, 0xBB, 0xB5, 0xB0, 0xAE, 0xAB, 0xA9, 0xAB, 0xAC, 0xAE, +0xB4, 0xBB, 0xC4, 0xD6, 0x60, 0x45, 0x39, 0x30, 0x2D, 0x2C, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x32, +0x35, 0x3A, 0x43, 0x51, 0x6A, 0xDF, 0xCB, 0xC3, 0xBD, 0xB8, 0xB2, 0xAE, 0xAC, 0xAA, 0xAA, 0xAB, +0xAC, 0xAF, 0xB7, 0xBD, 0xCC, 0xF1, 0x51, 0x3F, 0x36, 0x2F, 0x2D, 0x2B, 0x2A, 0x2C, 0x2D, 0x2E, +0x2F, 0x33, 0x37, 0x3B, 0x45, 0x58, 0x77, 0xD5, 0xC8, 0xC0, 0xBB, 0xB6, 0xB1, 0xAE, 0xAB, 0xA9, +0xAA, 0xAB, 0xAC, 0xB1, 0xB9, 0xC0, 0xD3, 0x6A, 0x4A, 0x3C, 0x33, 0x2E, 0x2D, 0x2B, 0x2B, 0x2C, +0x2D, 0x2E, 0x31, 0x34, 0x38, 0x3F, 0x4C, 0x5D, 0xEA, 0xCE, 0xC6, 0xBE, 0xB8, 0xB4, 0xAF, 0xAD, +0xAB, 0xAA, 0xAA, 0xAB, 0xAD, 0xB2, 0xB9, 0xC3, 0xD8, 0x61, 0x47, 0x3A, 0x32, 0x2E, 0x2C, 0x2B, +0x2C, 0x2C, 0x2D, 0x2F, 0x31, 0x34, 0x38, 0x3F, 0x4D, 0x62, 0xDD, 0xCC, 0xC3, 0xBC, 0xB7, 0xB2, +0xAE, 0xAC, 0xAA, 0xAA, 0xAA, 0xAB, 0xAE, 0xB3, 0xBA, 0xC6, 0xE1, 0x55, 0x41, 0x37, 0x30, 0x2D, +0x2B, 0x2A, 0x2B, 0x2C, 0x2D, 0x2F, 0x31, 0x34, 0x39, 0x40, 0x4D, 0x6A, 0xD8, 0xC9, 0xC1, 0xBC, +0xB7, 0xB2, 0xAE, 0xAC, 0xAA, 0xAA, 0xAB, 0xAC, 0xAF, 0xB7, 0xBB, 0xC6, 0x79, 0x55, 0x44, 0x37, +0x30, 0x2D, 0x2C, 0x2B, 0x2C, 0x2D, 0x2D, 0x2F, 0x33, 0x35, 0x39, 0x42, 0x51, 0x6C, 0xDA, 0xCA, +0xC4, 0xBE, 0xBA, 0xB6, 0xB0, 0xAD, 0xAC, 0xAC, 0xAC, 0xAD, 0xAF, 0xB4, 0xB9, 0xC0, 0xD0, 0x65, +0x47, 0x3A, 0x32, 0x2F, 0x2C, 0x2B, 0x2B, 0x2C, 0x2D, 0x2E, 0x31, 0x36, 0x3A, 0x3F, 0x4A, 0x5E, +0xDC, 0xCC, 0xC4, 0xBE, 0xBA, 0xB6, 0xB2, 0xAF, 0xAE, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB8, 0xBE, +0xCA, 0xE6, 0x4F, 0x3F, 0x38, 0x31, 0x2E, 0x2C, 0x2C, 0x2C, 0x2D, 0x2F, 0x31, 0x35, 0x3A, 0x3F, +0x4B, 0x64, 0xDD, 0xCB, 0xC3, 0xBD, 0xBA, 0xB7, 0xB4, 0xB1, 0xAF, 0xAE, 0xAE, 0xB0, 0xB3, 0xB5, +0xB9, 0xBE, 0xC6, 0xD3, 0x74, 0x4E, 0x40, 0x3A, 0x35, 0x32, 0x30, 0x2F, 0x2F, 0x30, 0x33, 0x36, +0x3A, 0x3F, 0x48, 0x52, 0x6C, 0xDF, 0xCE, 0xC7, 0xC1, 0xBE, 0xBB, 0xB9, 0xB8, 0xB7, 0xB6, 0xB6, +0xB7, 0xB9, 0xBB, 0xBE, 0xC4, 0xCA, 0xD9, 0x6C, 0x50, 0x45, 0x3D, 0x3A, 0x37, 0x35, 0x35, 0x35, +0x36, 0x37, 0x39, 0x3C, 0x3F, 0x46, 0x4F, 0x5E, 0xF1, 0xD9, 0xCF, 0xCC, 0xC9, 0xC5, 0xC1, 0xBE, +0xBC, 0xBC, 0xBC, 0xBD, 0xBF, 0xC2, 0xC4, 0xC7, 0xCC, 0xD5, 0xE8, 0x64, 0x52, 0x4A, 0x45, 0x41, +0x3F, 0x3E, 0x3D, 0x3D, 0x3E, 0x41, 0x45, 0x49, 0x4D, 0x53, 0x5C, 0x71, 0xE9, 0xDD, 0xD6, 0xD1, +0xCE, 0xCB, 0xC9, 0xC8, 0xC8, 0xC7, 0xC7, 0xC8, 0xC9, 0xCC, 0xCF, 0xD4, 0xDA, 0xE4, 0xF7, 0x69, +0x5B, 0x53, 0x4F, 0x4E, 0x4D, 0x4D, 0x4D, 0x4E, 0x51, 0x58, 0x5F, 0x68, 0x6F, 0x77, 0xFC, 0xEE, +0xE8, 0xE5, 0xE1, 0xDD, 0xDE, 0xDE, 0xDE, 0xE2, 0xE6, 0xE6, 0xEB, 0xF0, 0xED, 0xEA, 0xEC, 0xEE, +0xF8, 0x6A, 0x5C, 0x57, 0x55, 0x56, 0x58, 0x59, 0x58, 0x58, 0x5B, 0x5E, 0x63, 0x71, 0xF7, 0xEE, +0xE9, 0xE3, 0xE4, 0xE8, 0xE7, 0xEA, 0xEE, 0xEE, 0xF2, 0xFB, 0xFF, 0x7B, 0x74, 0x6E, 0x6B, 0x65, +0x60, 0x65, 0x67, 0x61, 0x60, 0x61, 0x5E, 0x5E, 0x62, 0x69, 0x70, 0x7F, 0xF6, 0xF2, 0xEC, 0xE7, +0xE6, 0xE3, 0xDF, 0xDE, 0xDE, 0xDD, 0xDE, 0xE0, 0xE5, 0xEC, 0xF6, 0x7F, 0x78, 0x75, 0x70, 0x6B, +0x64, 0x5E, 0x5A, 0x58, 0x58, 0x59, 0x5A, 0x5C, 0x5D, 0x5E, 0x61, 0x67, 0x6C, 0x75, 0xF8, 0xEC, +0xE6, 0xE0, 0xDD, 0xDD, 0xDE, 0xDF, 0xE0, 0xE2, 0xE2, 0xE4, 0xE6, 0xE9, 0xEE, 0xF9, 0x7D, 0x75, +0x6E, 0x6A, 0x65, 0x61, 0x5E, 0x5C, 0x5B, 0x5C, 0x5D, 0x5E, 0x60, 0x63, 0x66, 0x6C, 0x76, 0xFA, +0xEE, 0xE9, 0xE4, 0xE1, 0xDF, 0xDD, 0xDE, 0xDF, 0xE2, 0xE6, 0xEA, 0xEE, 0xF4, 0xFA, 0x7E, 0x7A, +0x75, 0x72, 0x74, 0x74, 0x71, 0x70, 0x6D, 0x6A, 0x6A, 0x6B, 0x6D, 0x70, 0x74, 0x78, 0x7A, 0x7D, +0xFA, 0xF0, 0xEA, 0xE5, 0xE3, 0xE2, 0xE0, 0xDF, 0xE1, 0xE3, 0xE4, 0xE8, 0xEB, 0xEE, 0xF4, 0xFB, +0x7E, 0x75, 0x6D, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x65, 0x64, 0x63, 0x64, 0x66, 0x69, 0x6D, 0x72, +0x77, 0x7B, 0xFE, 0xF7, 0xF0, 0xEB, 0xE8, 0xE7, 0xE6, 0xE6, 0xE6, 0xE7, 0xE7, 0xE8, 0xEA, 0xED, +0xF3, 0xFC, 0x79, 0x72, 0x6F, 0x6C, 0x6B, 0x6B, 0x69, 0x66, 0x64, 0x63, 0x62, 0x63, 0x67, 0x6C, +0x73, 0x7C, 0xFE, 0xFD, 0xFA, 0xF4, 0xEE, 0xEA, 0xE5, 0xE1, 0xE1, 0xE2, 0xE5, 0xE9, 0xED, 0xEF, +0xF1, 0xF2, 0xF4, 0xF8, 0xFF, 0x76, 0x6E, 0x6A, 0x68, 0x67, 0x66, 0x65, 0x64, 0x62, 0x61, 0x61, +0x63, 0x67, 0x6B, 0x72, 0x7E, 0xFA, 0xF5, 0xF1, 0xEE, 0xED, 0xEC, 0xE9, 0xE8, 0xE7, 0xE7, 0xE9, +0xEC, 0xF0, 0xF9, 0x7D, 0x77, 0x73, 0x70, 0x6F, 0x6E, 0x6C, 0x69, 0x67, 0x65, 0x66, 0x66, 0x68, +0x69, 0x69, 0x6A, 0x6C, 0x6E, 0x75, 0x7F, 0xF8, 0xF1, 0xED, 0xEB, 0xEA, 0xEA, 0xEB, 0xEB, 0xEB, +0xEA, 0xE9, 0xEA, 0xEC, 0xEF, 0xF4, 0xFB, 0x7D, 0x77, 0x73, 0x71, 0x6F, 0x6D, 0x6B, 0x69, 0x67, +0x66, 0x67, 0x68, 0x69, 0x6B, 0x6D, 0x6F, 0x74, 0x79, 0x7F, 0xF9, 0xF3, 0xEF, 0xEE, 0xEE, 0xEE, +0xEE, 0xED, 0xED, 0xED, 0xEE, 0xEC, 0xEC, 0xF1, 0xF3, 0xF6, 0xFD, 0xFF, 0x7D, 0x78, 0x78, 0x76, +0x70, 0x6F, 0x6E, 0x6D, 0x6D, 0x6E, 0x6F, 0x71, 0x73, 0x77, 0x7B, 0x7D, 0xFF, 0xFB, 0xF8, 0xF8, +0xFA, 0xFB, 0xFE, 0x7E, 0x7D, 0x7A, 0x79, 0x7A, 0x76, 0x76, 0x76, 0x72, 0x70, 0x6F, 0x6D, 0x6E, +0x6D, 0x6B, 0x6E, 0x65, 0x66, 0x57, 0x41, 0x59, 0xC7, 0x62, 0x57, 0xCD, 0x64, 0x6B, 0xCC, 0x6D, +0xF6, 0xD1, 0x69, 0x6E, 0xDA, 0x7D, 0x61, 0xEE, 0xF1, 0xFD, 0xFF, 0x6E, 0xE7, 0x74, 0x66, 0xE9, +0x6A, 0xFC, 0xF2, 0x64, 0xEE, 0x6F, 0x6B, 0x7B, 0x69, 0xF2, 0x68, 0x74, 0xEC, 0x5F, 0xED, 0xFC, +0x5F, 0xDE, 0x72, 0x65, 0xDC, 0x51, 0x4C, 0xE8, 0x5F, 0xEF, 0xD7, 0x4E, 0xF3, 0xF9, 0x52, 0xC3, +0xE2, 0x56, 0xC9, 0x5B, 0x59, 0xE4, 0x50, 0x53, 0x47, 0x66, 0xF9, 0x47, 0xC9, 0xCB, 0x59, 0xD4, +0x55, 0x58, 0xD3, 0x5C, 0xF9, 0xCE, 0xD7, 0x6D, 0x61, 0xDB, 0xE4, 0xE8, 0x70, 0x79, 0xCD, 0x6B, +0x5D, 0xEC, 0x66, 0xDC, 0x6C, 0x5F, 0xD3, 0xF9, 0xFB, 0x66, 0x55, 0xDE, 0xFB, 0x64, 0xD7, 0xDA, +0xF1, 0xF1, 0xF1, 0xE5, 0xDB, 0xF4, 0x75, 0xDF, 0xE7, 0xFD, 0x79, 0xEC, 0xD9, 0xF0, 0x6E, 0xF5, +0xE4, 0xE5, 0x64, 0x74, 0xDF, 0x7D, 0x68, 0x75, 0xF0, 0xFD, 0x7B, 0xFC, 0x7B, 0xDE, 0xEF, 0x64, +0xDF, 0xE8, 0xFF, 0xE9, 0xFF, 0xE2, 0xE1, 0x76, 0xF6, 0xEF, 0xEC, 0xF9, 0x6D, 0x7C, 0x73, 0x6D, +0x69, 0x67, 0x76, 0x75, 0x73, 0x64, 0x66, 0xFD, 0x60, 0x5F, 0x77, 0x67, 0x70, 0x74, 0x60, 0x78, +0x7A, 0x5C, 0x67, 0x79, 0x6C, 0x77, 0x63, 0x63, 0xEF, 0x6C, 0x66, 0x73, 0x6D, 0xF8, 0x72, 0x74, +0xE6, 0xFB, 0x7B, 0xF3, 0xF6, 0xF1, 0xFE, 0x7B, 0xF5, 0xF1, 0x6D, 0x63, 0x75, 0x6E, 0x60, 0x64, +0x67, 0x67, 0x68, 0x67, 0x67, 0x6C, 0x64, 0x5B, 0x65, 0x6E, 0x69, 0x72, 0x76, 0x74, 0xFE, 0xFD, +0xFF, 0xF6, 0xF3, 0x7C, 0x7A, 0xFC, 0xFE, 0xFB, 0x7E, 0x75, 0xF5, 0xEE, 0xFC, 0xF7, 0xF3, 0xFF, +0xFE, 0x74, 0x6B, 0x6F, 0x6D, 0x6A, 0x6C, 0x6A, 0x7A, 0xF9, 0x71, 0x7C, 0xF5, 0x7C, 0x7B, 0x7F, +0xFE, 0x72, 0x6E, 0xFF, 0x6F, 0x66, 0x6B, 0x6A, 0x6E, 0x76, 0x71, 0x7C, 0x7A, 0x6E, 0x6C, 0x69, +0x6C, 0x6D, 0x63, 0x65, 0x6A, 0x66, 0x63, 0x65, 0x6C, 0x68, 0x64, 0x69, 0x6A, 0x6E, 0x79, 0x7B, +0x78, 0x6D, 0x6E, 0x79, 0x77, 0xFA, 0xED, 0xEF, 0xEF, 0xEC, 0xE8, 0xEF, 0xFB, 0xF6, 0xEF, 0xEE, +0xF7, 0xF9, 0xF3, 0xF7, 0xF1, 0xF3, 0xFD, 0xFD, 0x7A, 0x7B, 0xFE, 0x79, 0x7C, 0x7B, 0x6E, 0x72, +0x7A, 0x72, 0x71, 0x79, 0x79, 0x6F, 0x6F, 0x78, 0x74, 0x72, 0x7B, 0x72, 0x78, 0xF6, 0xF7, 0xF9, +0x78, 0x79, 0xEE, 0xF5, 0x74, 0x76, 0x7A, 0xFE, 0x7E, 0x75, 0x7A, 0x7E, 0x74, 0x70, 0x7D, 0xF8, +0xF8, 0x7D, 0x77, 0xF8, 0xF0, 0x7F, 0x7E, 0xF2, 0xED, 0xF0, 0xF4, 0xEB, 0xE9, 0xFE, 0x74, 0xEF, +0xE1, 0xE0, 0xDC, 0xD9, 0xD7, 0xD3, 0xD7, 0xDD, 0xD9, 0xD9, 0xDF, 0xE6, 0xEB, 0xF2, 0x78, 0x65, +0x61, 0x65, 0x5F, 0x5A, 0x5B, 0x5B, 0x5A, 0x5C, 0x5B, 0x5D, 0x5E, 0x5C, 0x5B, 0x5B, 0x5B, 0x5C, +0x5E, 0x6B, 0xEA, 0xD9, 0xD2, 0xD1, 0xCD, 0xC8, 0xC6, 0xC5, 0xC5, 0xC3, 0xC3, 0xC6, 0xCA, 0xD2, +0xE8, 0x67, 0x51, 0x49, 0x42, 0x3D, 0x3D, 0x3E, 0x3F, 0x41, 0x44, 0x49, 0x4E, 0x50, 0x55, 0x5A, +0x5F, 0x6F, 0xEF, 0xDA, 0xCD, 0xCA, 0xC8, 0xC4, 0xBF, 0xBD, 0xBB, 0xB9, 0xB7, 0xB6, 0xBA, 0xC2, +0xCC, 0xE2, 0x56, 0x43, 0x3B, 0x39, 0x37, 0x36, 0x37, 0x3B, 0x3E, 0x42, 0x47, 0x4B, 0x51, 0x5A, +0x5B, 0x5E, 0x67, 0x7A, 0xED, 0xE8, 0xDB, 0xCF, 0xCB, 0xC5, 0xBD, 0xB9, 0xB6, 0xB2, 0xB0, 0xB4, +0xB9, 0xBF, 0xCD, 0xFC, 0x49, 0x3B, 0x37, 0x33, 0x31, 0x32, 0x33, 0x38, 0x3E, 0x45, 0x4F, 0x5F, +0x74, 0xF0, 0xEF, 0xF1, 0xF4, 0xFF, 0x77, 0x72, 0xFB, 0xE4, 0xD9, 0xCE, 0xC3, 0xBA, 0xB6, 0xB2, +0xB0, 0xB2, 0xB6, 0xBB, 0xC8, 0xE4, 0x51, 0x3E, 0x38, 0x33, 0x2F, 0x2F, 0x31, 0x35, 0x3A, 0x3E, +0x49, 0x5D, 0xFE, 0xE4, 0xDD, 0xD9, 0xD9, 0xE1, 0xEB, 0xEE, 0xEE, 0xE7, 0xDD, 0xD2, 0xC7, 0xBD, +0xB9, 0xB5, 0xB2, 0xB5, 0xB8, 0xBB, 0xC6, 0xDA, 0x5F, 0x45, 0x3D, 0x37, 0x33, 0x31, 0x31, 0x35, +0x39, 0x3D, 0x45, 0x53, 0x6F, 0xE3, 0xD9, 0xD0, 0xCF, 0xD2, 0xD5, 0xD9, 0xD9, 0xD8, 0xD4, 0xCE, +0xC8, 0xC0, 0xBD, 0xB9, 0xB8, 0xBB, 0xBD, 0xC1, 0xCD, 0xDF, 0x5F, 0x4A, 0x41, 0x3B, 0x37, 0x36, +0x35, 0x36, 0x3A, 0x3D, 0x44, 0x4E, 0x5F, 0xEC, 0xDB, 0xD6, 0xD2, 0xD4, 0xD6, 0xDA, 0xDD, 0xDB, +0xD8, 0xD2, 0xCD, 0xC9, 0xC3, 0xBF, 0xBE, 0xBF, 0xC3, 0xC4, 0xCA, 0xD6, 0xED, 0x5E, 0x50, 0x48, +0x3F, 0x3C, 0x3B, 0x3A, 0x3A, 0x3D, 0x40, 0x4A, 0x55, 0x6A, 0xE6, 0xDC, 0xD8, 0xD6, 0xD8, 0xD8, +0xDB, 0xDE, 0xDF, 0xE2, 0xDE, 0xDC, 0xD9, 0xD0, 0xCB, 0xC8, 0xC8, 0xCC, 0xCD, 0xCD, 0xD1, 0xDB, +0xF2, 0x67, 0x5B, 0x51, 0x49, 0x44, 0x42, 0x41, 0x42, 0x44, 0x49, 0x4E, 0x55, 0x5C, 0x6A, 0x7E, +0xF3, 0xED, 0xED, 0xEF, 0xEC, 0xED, 0xF4, 0xF7, 0xF0, 0xEB, 0xE4, 0xDF, 0xDA, 0xD2, 0xCD, 0xCC, +0xCC, 0xCF, 0xCF, 0xCE, 0xD3, 0xDB, 0xE7, 0x7C, 0x69, 0x5E, 0x54, 0x4F, 0x4E, 0x4D, 0x4E, 0x4F, +0x52, 0x58, 0x5B, 0x5E, 0x63, 0x67, 0x6B, 0x6B, 0x6A, 0x6B, 0x6C, 0x6E, 0x6F, 0x73, 0x7D, 0xF3, +0xEA, 0xE1, 0xDC, 0xD8, 0xD3, 0xD1, 0xCF, 0xCE, 0xD1, 0xD2, 0xD2, 0xD6, 0xDB, 0xE2, 0xEF, 0xFD, +0x73, 0x66, 0x5F, 0x5C, 0x5A, 0x59, 0x58, 0x56, 0x56, 0x57, 0x57, 0x58, 0x58, 0x5A, 0x5C, 0x5D, +0x61, 0x65, 0x6A, 0x74, 0x7E, 0xF4, 0xEA, 0xE2, 0xDD, 0xDA, 0xD7, 0xD5, 0xD2, 0xD1, 0xD0, 0xD1, +0xD3, 0xD3, 0xD4, 0xD7, 0xDB, 0xE0, 0xE8, 0xEF, 0x7B, 0x69, 0x5F, 0x5B, 0x57, 0x53, 0x50, 0x4F, +0x4F, 0x4F, 0x4F, 0x50, 0x52, 0x56, 0x59, 0x5C, 0x60, 0x68, 0x6E, 0x7A, 0xFB, 0xF1, 0xEB, 0xE7, +0xE2, 0xDE, 0xDC, 0xDA, 0xD7, 0xD5, 0xD3, 0xD3, 0xD3, 0xD5, 0xD5, 0xD8, 0xDC, 0xE4, 0xF2, 0x78, +0x6A, 0x5E, 0x59, 0x55, 0x52, 0x50, 0x4F, 0x4F, 0x50, 0x52, 0x55, 0x58, 0x5A, 0x5D, 0x61, 0x64, +0x69, 0x6E, 0x74, 0xFF, 0xF6, 0xEE, 0xE9, 0xE4, 0xDF, 0xDC, 0xD8, 0xD5, 0xD2, 0xD0, 0xD1, 0xD1, +0xD2, 0xD6, 0xD7, 0xDA, 0xDF, 0xE8, 0xF8, 0x71, 0x69, 0x60, 0x5C, 0x58, 0x56, 0x54, 0x53, 0x53, +0x53, 0x55, 0x56, 0x58, 0x5A, 0x5C, 0x5F, 0x63, 0x69, 0x71, 0xFF, 0xEF, 0xEA, 0xE6, 0xE1, 0xDF, +0xDE, 0xDB, 0xDA, 0xDA, 0xD7, 0xD4, 0xD1, 0xD1, 0xD2, 0xD4, 0xD7, 0xD8, 0xDB, 0xE1, 0xED, 0x78, +0x69, 0x61, 0x5A, 0x53, 0x50, 0x4F, 0x4E, 0x4F, 0x4F, 0x51, 0x55, 0x59, 0x5D, 0x60, 0x65, 0x6C, +0x6F, 0x76, 0x7E, 0xFC, 0xF5, 0xF2, 0xF2, 0xED, 0xE7, 0xE1, 0xDD, 0xD9, 0xD4, 0xCE, 0xCB, 0xCA, +0xC8, 0xCA, 0xCF, 0xD0, 0xD7, 0xE6, 0x7C, 0x5E, 0x53, 0x4F, 0x4C, 0x4A, 0x4A, 0x4A, 0x4C, 0x4E, +0x4F, 0x51, 0x57, 0x5D, 0x62, 0x66, 0x69, 0x6D, 0x6D, 0x67, 0x63, 0x65, 0x6B, 0x70, 0x75, 0xFE, +0xEA, 0xDC, 0xD3, 0xCE, 0xC9, 0xC2, 0xBE, 0xBC, 0xBC, 0xC1, 0xC8, 0xCB, 0xDC, 0x69, 0x50, 0x46, +0x42, 0x3F, 0x3D, 0x3D, 0x3F, 0x43, 0x4B, 0x4F, 0x55, 0x61, 0x6F, 0xFC, 0xF0, 0xFA, 0xFD, 0x7B, +0x63, 0x5A, 0x54, 0x52, 0x54, 0x58, 0x62, 0x7D, 0xDE, 0xCC, 0xC4, 0xBC, 0xB6, 0xB1, 0xAE, 0xB2, +0xBA, 0xC1, 0xDA, 0x5A, 0x45, 0x38, 0x33, 0x32, 0x33, 0x36, 0x3A, 0x3E, 0x4B, 0x66, 0xEA, 0xD6, +0xCE, 0xCF, 0xD3, 0xE0, 0x6E, 0x5C, 0x51, 0x4D, 0x4B, 0x4A, 0x4F, 0x5B, 0x7A, 0xD6, 0xC6, 0xBA, +0xB1, 0xAE, 0xAA, 0xAA, 0xAF, 0xBA, 0xD1, 0x4E, 0x3D, 0x31, 0x2B, 0x2B, 0x2C, 0x30, 0x38, 0x3E, +0x4E, 0xEA, 0xCD, 0xC7, 0xC8, 0xCB, 0xCE, 0xDD, 0x64, 0x4F, 0x48, 0x48, 0x47, 0x46, 0x4D, 0x62, +0xDD, 0xCA, 0xBD, 0xB1, 0xAC, 0xA9, 0xA7, 0xAA, 0xB2, 0xC4, 0x51, 0x3A, 0x2F, 0x29, 0x28, 0x2A, +0x2E, 0x39, 0x45, 0x5A, 0xDB, 0xC8, 0xC2, 0xC5, 0xCD, 0xD5, 0xE8, 0x5B, 0x4C, 0x46, 0x47, 0x4C, +0x4E, 0x59, 0xF3, 0xD3, 0xC6, 0xBE, 0xB5, 0xAD, 0xAA, 0xA6, 0xA8, 0xB2, 0xC5, 0x54, 0x38, 0x2F, +0x28, 0x26, 0x2A, 0x2F, 0x3A, 0x4B, 0x73, 0xCF, 0xC5, 0xC4, 0xC9, 0xD9, 0xF8, 0x5F, 0x4C, 0x47, +0x47, 0x48, 0x4F, 0x5A, 0x74, 0xD9, 0xCE, 0xC7, 0xBF, 0xBA, 0xB0, 0xAC, 0xAA, 0xA9, 0xB0, 0xC5, +0x5C, 0x3B, 0x30, 0x2B, 0x27, 0x29, 0x2E, 0x39, 0x49, 0x6C, 0xD2, 0xC7, 0xC5, 0xCA, 0xDA, 0x7A, +0x5E, 0x4D, 0x48, 0x49, 0x4B, 0x52, 0x5E, 0x70, 0xDC, 0xCE, 0xC9, 0xC4, 0xBE, 0xB5, 0xAE, 0xAC, +0xAA, 0xAD, 0xBB, 0xE1, 0x43, 0x35, 0x2E, 0x29, 0x28, 0x2B, 0x32, 0x3D, 0x4E, 0x7E, 0xD2, 0xC9, +0xC7, 0xCC, 0xDF, 0xFE, 0x61, 0x4F, 0x4C, 0x4B, 0x4C, 0x54, 0x5D, 0x72, 0xDA, 0xCE, 0xC7, 0xC0, +0xB9, 0xB0, 0xAD, 0xAA, 0xAA, 0xB1, 0xC5, 0x5D, 0x3D, 0x33, 0x2C, 0x29, 0x29, 0x2D, 0x35, 0x3F, +0x4F, 0x78, 0xD7, 0xCA, 0xC7, 0xCD, 0xD9, 0xE3, 0x71, 0x5C, 0x54, 0x4D, 0x4E, 0x55, 0x5A, 0x6E, +0xE3, 0xD3, 0xC8, 0xBE, 0xB6, 0xAF, 0xAC, 0xAA, 0xAC, 0xB7, 0xCE, 0x53, 0x3D, 0x34, 0x2D, 0x2A, +0x2A, 0x2E, 0x35, 0x3E, 0x4A, 0x5C, 0xE5, 0xCD, 0xC8, 0xCB, 0xCE, 0xD5, 0xE2, 0xF7, 0x66, 0x57, +0x54, 0x56, 0x5B, 0x6E, 0xE7, 0xD5, 0xC9, 0xBE, 0xB6, 0xB1, 0xAE, 0xAE, 0xB4, 0xBE, 0xD3, 0x5C, +0x46, 0x3C, 0x34, 0x30, 0x2F, 0x32, 0x38, 0x3E, 0x45, 0x4E, 0x69, 0xDC, 0xCF, 0xCD, 0xCF, 0xD3, +0xD9, 0xDF, 0xEF, 0x6F, 0x68, 0x67, 0x6F, 0xF7, 0xE7, 0xDC, 0xD2, 0xC8, 0xC1, 0xBE, 0xBC, 0xBD, +0xC3, 0xCB, 0xD5, 0xEA, 0x6A, 0x58, 0x4D, 0x47, 0x43, 0x43, 0x44, 0x47, 0x4A, 0x4D, 0x52, 0x5D, +0x6D, 0x78, 0x77, 0x78, 0x76, 0x73, 0x75, 0x72, 0x72, 0x78, 0x7E, 0xF6, 0xEB, 0xE3, 0xDC, 0xD6, +0xD2, 0xCF, 0xCE, 0xCE, 0xCD, 0xCF, 0xD2, 0xD4, 0xD7, 0xDA, 0xDD, 0xE3, 0xEF, 0x7A, 0x6C, 0x65, +0x5F, 0x5B, 0x57, 0x53, 0x4F, 0x4E, 0x4D, 0x4C, 0x4A, 0x4A, 0x4A, 0x4B, 0x4D, 0x4F, 0x53, 0x59, +0x5F, 0x6C, 0xFE, 0xEC, 0xE3, 0xDE, 0xDC, 0xDA, 0xD9, 0xD8, 0xD7, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, +0xD8, 0xDA, 0xDC, 0xDE, 0xE3, 0xEC, 0xFB, 0x6F, 0x63, 0x5B, 0x55, 0x4F, 0x4D, 0x4C, 0x4B, 0x4C, +0x4C, 0x4D, 0x4F, 0x53, 0x58, 0x5E, 0x67, 0x73, 0xFB, 0xEE, 0xE8, 0xE3, 0xDF, 0xDC, 0xDA, 0xD9, +0xD8, 0xD8, 0xD8, 0xD9, 0xDB, 0xDD, 0xDF, 0xE1, 0xE5, 0xE9, 0xEE, 0xF6, 0x7C, 0x6E, 0x66, 0x5F, +0x5C, 0x5A, 0x58, 0x56, 0x56, 0x57, 0x58, 0x5A, 0x5D, 0x60, 0x66, 0x6D, 0x74, 0x7C, 0xFB, 0xF4, +0xEE, 0xEA, 0xE7, 0xE5, 0xE4, 0xE4, 0xE4, 0xE7, 0xEA, 0xEC, 0xED, 0xED, 0xEC, 0xED, 0xEC, 0xED, +0xEE, 0xF1, 0xF9, 0x7F, 0x79, 0x75, 0x70, 0x6D, 0x6C, 0x6C, 0x6E, 0x73, 0x79, 0xFE, 0xF9, 0xF3, +0xEE, 0xEB, 0xE9, 0xE8, 0xE6, 0xE5, 0xE6, 0xE8, 0xEA, 0xED, 0xF1, 0xF8, 0xFD, 0x7E, 0x7E, 0xFE, +0xFC, 0xF9, 0xF5, 0xF5, 0xF6, 0xFB, 0x7C, 0x77, 0x71, 0x6E, 0x6C, 0x6A, 0x69, 0x69, 0x6B, 0x6E, +0x70, 0x75, 0x7A, 0xFE, 0xF6, 0xF1, 0xEE, 0xEC, 0xEB, 0xEB, 0xEC, 0xEE, 0xF1, 0xF5, 0xFB, 0x7D, +0x7B, 0x7A, 0x7C, 0xFE, 0xFA, 0xF4, 0xF1, 0xF0, 0xF0, 0xF3, 0xF7, 0xFB, 0xFD, 0xFF, 0xFF, 0x7F, +0x7F, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0xFD, 0xFC, 0xFA, 0xF5, 0xF4, 0xF1, 0xEF, 0xEF, 0xEF, 0xF0, +0xF4, 0xF8, 0xFD, 0x7D, 0x78, 0x77, 0x78, 0x7A, 0x7C, 0x7C, 0x7E, 0x7C, 0x7A, 0x79, 0x76, 0x77, +0x78, 0x77, 0x7B, 0x7E, 0xFF, 0xFD, 0xFD, 0xFE, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0x7E, 0xFE, 0xFB, +0xFA, 0xF9, 0xFA, 0xFB, 0xFE, 0x7F, 0x7C, 0x79, 0x78, 0x77, 0x77, 0x7A, 0x7C, 0x7D, 0x7E, 0x7B, +0x77, 0x74, 0x71, 0x6F, 0x6E, 0x6E, 0x6F, 0x6F, 0x70, 0x71, 0x73, 0x74, 0x76, 0x76, 0x75, 0x76, +0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x77, 0x74, 0x72, 0x70, 0x6F, 0x6E, 0x6E, 0x6E, 0x70, 0x74, +0x78, 0x7B, 0x7D, 0x7D, 0x7C, 0x7C, 0x7A, 0x76, 0x72, 0x71, 0x70, 0x70, 0x70, 0x71, 0x72, 0x72, +0x74, 0x76, 0x78, 0x7B, 0x7F, 0xFE, 0xFC, 0xF9, 0xF6, 0xF5, 0xF7, 0xFC, 0xFF, 0x7C, 0x79, 0x78, +0x77, 0x77, 0x77, 0x7A, 0x7E, 0xFE, 0xFC, 0xFA, 0xF8, 0xF8, 0xFA, 0xFC, 0xFE, 0x7D, 0x7A, 0x76, +0x74, 0x74, 0x73, 0x75, 0x76, 0x76, 0x78, 0x7A, 0x7C, 0x7E, 0xFF, 0xFB, 0xF9, 0xF8, 0xF9, 0xFD, +0x7E, 0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x78, 0x7C, 0x7F, 0xFB, 0xF6, 0xF5, 0xF2, 0xF2, 0xF3, +0xF4, 0xF7, 0xF8, 0xFA, 0xFC, 0xFE, 0xFF, 0xFF, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFA, +0xF7, 0xF6, 0xF8, 0xFC, 0x7F, 0x7C, 0x79, 0x72, 0x6F, 0x6E, 0x6E, 0x6E, 0x6F, 0x73, 0x77, 0x77, +0x7B, 0x7D, 0x7E, 0x7F, 0x7E, 0x7C, 0x7A, 0x77, 0x75, 0x71, 0x6F, 0x6E, 0x6D, 0x6E, 0x6F, 0x70, +0x73, 0x74, 0x77, 0x79, 0x7C, 0x7D, 0x7D, 0x7D, 0x7B, 0x7A, 0x79, 0x76, 0x73, 0x70, 0x6F, 0x71, +0x73, 0x78, 0x7B, 0x7F, 0xFB, 0xF8, 0xF5, 0xF3, 0xF5, 0xF6, 0xF6, 0xF8, 0xF9, 0xFC, 0xFE, 0xFF, +0x7F, 0xFF, 0xFD, 0xFC, 0xFC, 0xFB, 0xF7, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF6, 0xF7, 0xF9, +0xFA, 0xFC, 0xFF, 0xFF, 0x7F, 0x7F, 0xFE, 0xFD, 0xFE, 0xFD, 0xFB, 0xFB, 0xFC, 0xFE, 0x7E, 0x7C, +0x7A, 0x79, 0x77, 0x76, 0x77, 0x77, 0x78, 0x78, 0x79, 0x7C, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, +0x7D, 0x7E, 0x7C, 0x7E, 0x7F, 0x7E, 0x7E, 0xFF, 0xFD, 0xFC, 0xFB, 0xF8, 0xF8, 0xFA, 0xFA, 0xFC, +0xFE, 0x7D, 0x78, 0x75, 0x72, 0x70, 0x70, 0x73, 0x75, 0x76, 0x78, 0x79, 0x79, 0x7A, 0x79, 0x78, +0x77, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x79, 0x7A, 0x7B, 0x7D, 0x7F, 0xFC, 0xF8, 0xF6, +0xF4, 0xF2, 0xF3, 0xF7, 0xF9, 0xFB, 0x7E, 0x78, 0x75, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x74, +0x75, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x78, 0x78, 0x78, 0x77, 0x75, 0x75, 0x76, 0x79, 0x7B, +0x7C, 0x7E, 0xFE, 0xFC, 0xF9, 0xF6, 0xF5, 0xF6, 0xF7, 0xF9, 0xFC, 0xFE, 0x7C, 0x79, 0x77, 0x76, +0x75, 0x74, 0x74, 0x75, 0x74, 0x76, 0x77, 0x78, 0x79, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x78, 0x78, +0x77, 0x76, 0x77, 0x77, 0x77, 0x78, 0x7A, 0x7C, 0xFF, 0xFD, 0xFA, 0xF8, 0xF6, 0xF7, 0xF8, 0xF7, +0xF8, 0xF8, 0xF8, 0xF9, 0xFA, 0xF9, 0xF9, 0xFA, 0xFB, 0xFB, 0xFB, 0xFD, 0xFD, 0xFC, 0xFD, 0xFE, +0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7B, 0x7A, 0x79, 0x79, 0x79, 0x78, 0x79, 0x7B, 0x7C, 0x7C, 0x7C, +0x7C, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x71, 0x70, 0x6F, 0x6F, 0x6E, +0x6D, 0x6C, 0x6C, 0x6D, 0x6E, 0x6E, 0x6E, 0x6F, 0x6E, 0x6F, 0x70, 0x70, 0x72, 0x75, 0x78, 0x7B, +0x7B, 0x7C, 0x7D, 0xFF, 0xFD, 0xFC, 0xFA, 0xFA, 0xF9, 0xF7, 0xF7, 0xF7, 0xF7, 0xF8, 0xF8, 0xF9, +0xFA, 0xFA, 0xFA, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFB, +0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFF, 0x7F, 0xFC, 0xFA, 0xFB, 0xFA, 0xFA, 0xF9, +0xFA, 0xFC, 0xFC, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, 0xFE, 0xFD, 0xFC, 0xFD, 0xFA, 0xFA, 0xF9, 0xF8, +0xFA, 0xF8, 0xFA, 0xFA, 0xFB, 0xFE, 0xFB, 0xFF, 0xFD, 0xFD, 0xFF, 0xFB, 0xFF, 0xFA, 0xFC, 0x7F, +0xFC, 0x70, 0x6A, 0x64, 0x61, 0x67, 0x6C, 0x73, 0x61, 0x60, 0x5A, 0x47, 0x53, 0xDF, 0x7D, 0x6F, +0x71, 0x69, 0x7F, 0x72, 0x70, 0x68, 0x5A, 0x5B, 0x59, 0x55, 0x5A, 0x5D, 0x4E, 0x46, 0x51, 0x77, +0xF6, 0xEC, 0xE8, 0xE6, 0xE5, 0xE4, 0xE1, 0xE5, 0xFD, 0x60, 0x65, 0xE6, 0xDB, 0xDD, 0xE1, 0xE4, +0xE2, 0xDC, 0xD4, 0xCF, 0xCF, 0xCF, 0xD1, 0xD2, 0xCF, 0xCD, 0xCC, 0xCD, 0xD0, 0xD4, 0xD7, 0xD5, +0xCE, 0xCD, 0xD3, 0xD9, 0xDB, 0xDA, 0xD9, 0xDC, 0xE2, 0xE5, 0xF1, 0xEE, 0xD7, 0xD2, 0xD9, 0xDC, +0xDD, 0xD9, 0xDC, 0xE7, 0xDF, 0xD9, 0xDD, 0x74, 0x62, 0xFC, 0xE9, 0xF2, 0x6C, 0x5D, 0x5D, 0x61, +0x6B, 0x6C, 0x5C, 0x5D, 0x70, 0x64, 0x5B, 0x6D, 0x78, 0x61, 0x57, 0x58, 0x65, 0x62, 0x53, 0x51, +0x69, 0xF5, 0x59, 0x53, 0x69, 0x68, 0x54, 0x4F, 0x67, 0xFA, 0x5B, 0x58, 0x5D, 0x60, 0x5D, 0x4E, +0x53, 0x61, 0x5A, 0x5F, 0x63, 0x61, 0x5E, 0x4C, 0x4C, 0x5A, 0x6B, 0xF7, 0x58, 0x47, 0x51, 0x6D, +0x68, 0x5A, 0x55, 0x53, 0x4A, 0x4E, 0xEE, 0xE1, 0x56, 0x46, 0x4D, 0x74, 0x70, 0x59, 0x53, 0x4C, +0x4E, 0x62, 0xF2, 0xF3, 0x5A, 0x4A, 0x4F, 0x6D, 0x6B, 0x57, 0x63, 0xED, 0x79, 0x69, 0x62, 0x5D, +0x6C, 0x67, 0x5E, 0xF5, 0xEA, 0x69, 0x63, 0x76, 0xFA, 0x6A, 0x59, 0x5D, 0xFB, 0xF6, 0x72, 0xFB, +0x71, 0x5D, 0x65, 0x7D, 0xFC, 0x79, 0xFB, 0xE9, 0xE2, 0xDD, 0xE3, 0xF9, 0xFA, 0xF3, 0xEA, 0xEC, +0x7D, 0xF1, 0xE5, 0xF2, 0x78, 0x6D, 0x6D, 0xED, 0xE4, 0xE5, 0xE4, 0xF6, 0x7A, 0xF8, 0xE5, 0xDC, +0xEA, 0xDF, 0xCF, 0xD3, 0xE7, 0x6C, 0x78, 0xCF, 0xC9, 0xD5, 0x7E, 0x64, 0x7E, 0xD7, 0xCF, 0xD7, +0xE0, 0xE8, 0xDC, 0xCB, 0xC5, 0xCC, 0xE6, 0x73, 0xE9, 0xD2, 0xC9, 0xCA, 0xD3, 0xED, 0x68, 0xF3, +0xD9, 0xDA, 0xDC, 0xDA, 0xD7, 0xDB, 0xE1, 0xE1, 0xEA, 0x69, 0x59, 0x60, 0xEE, 0xE0, 0xDC, 0xDF, +0xE5, 0xDD, 0xE1, 0xED, 0xED, 0xF4, 0xF6, 0xF2, 0xEE, 0xED, 0xFC, 0x6F, 0x64, 0x5C, 0x5C, 0x61, +0x76, 0xEA, 0xE1, 0xEB, 0x73, 0x66, 0x60, 0x69, 0xFB, 0x7E, 0x70, 0x76, 0xFF, 0x78, 0x73, 0xEB, +0xE2, 0x6F, 0x5C, 0x69, 0xE9, 0xDB, 0xDE, 0x73, 0x5E, 0x6D, 0xED, 0xEB, 0xF4, 0xFF, 0x77, 0xFD, +0xE7, 0xE2, 0xFB, 0x66, 0x69, 0xFE, 0xFA, 0x6B, 0x63, 0x69, 0x74, 0x74, 0x66, 0x63, 0x6F, 0xFB, +0xFD, 0x73, 0x71, 0x7B, 0xF4, 0xE8, 0xE2, 0xE8, 0xF2, 0xEB, 0xDE, 0xDC, 0xDE, 0xE2, 0xE7, 0xE5, +0xDF, 0xDF, 0xE8, 0xFC, 0x6D, 0x6A, 0x66, 0x5C, 0x53, 0x51, 0x56, 0x5B, 0x59, 0x56, 0x56, 0x5A, +0x5E, 0x5A, 0x53, 0x53, 0x59, 0x5D, 0x5F, 0x64, 0x74, 0xE9, 0xD6, 0xCB, 0xCB, 0xD3, 0xDC, 0xD4, +0xC8, 0xC1, 0xBF, 0xBE, 0xBE, 0xC5, 0xCE, 0xDC, 0xEA, 0x68, 0x4B, 0x3E, 0x3B, 0x3B, 0x3D, 0x3E, +0x41, 0x45, 0x47, 0x48, 0x4A, 0x4C, 0x4A, 0x47, 0x49, 0x4F, 0x5E, 0x6D, 0xF5, 0xDB, 0xCC, 0xC5, +0xC1, 0xBF, 0xBE, 0xBC, 0xBA, 0xB7, 0xB2, 0xAF, 0xAE, 0xB7, 0xDA, 0x43, 0x38, 0x35, 0x32, 0x31, +0x33, 0x3A, 0x46, 0x54, 0x5D, 0x56, 0x4A, 0x44, 0x43, 0x46, 0x44, 0x3F, 0x40, 0x4B, 0x61, 0x7B, +0xFD, 0xE7, 0xD4, 0xCA, 0xC5, 0xBF, 0xBB, 0xB6, 0xB1, 0xAF, 0xAD, 0xAC, 0xAC, 0xB4, 0xD8, 0x3C, +0x2D, 0x2B, 0x2D, 0x2F, 0x37, 0x41, 0x54, 0x76, 0xFF, 0x68, 0x54, 0x46, 0x40, 0x44, 0x49, 0x4A, +0x49, 0x4C, 0x5C, 0xFB, 0xE9, 0xE5, 0xDB, 0xCE, 0xC8, 0xC3, 0xBE, 0xBA, 0xB6, 0xB1, 0xAE, 0xAB, +0xA9, 0xAB, 0xBD, 0x3F, 0x2A, 0x26, 0x2A, 0x31, 0x3A, 0x43, 0x58, 0xE9, 0xDB, 0xE8, 0x5E, 0x46, +0x3C, 0x3D, 0x48, 0x55, 0x56, 0x55, 0x61, 0xF3, 0xE8, 0xE6, 0xDC, 0xCF, 0xC9, 0xC0, 0xB9, 0xB4, +0xB3, 0xB3, 0xAF, 0xAA, 0xA8, 0xAF, 0x75, 0x2C, 0x22, 0x24, 0x2D, 0x3F, 0x56, 0x72, 0xE0, 0xCF, +0xD4, 0x59, 0x3F, 0x38, 0x38, 0x3E, 0x4C, 0x68, 0xE8, 0xE3, 0xEA, 0x7E, 0x67, 0x64, 0x79, 0xDC, +0xCB, 0xBF, 0xB7, 0xB1, 0xAF, 0xAE, 0xAC, 0xAA, 0xB1, 0x56, 0x29, 0x1F, 0x20, 0x2B, 0x45, 0xD1, +0xC4, 0xC7, 0xCB, 0xD8, 0x4B, 0x33, 0x2E, 0x34, 0x42, 0x6D, 0xCD, 0xC5, 0xC8, 0xD1, 0xE0, 0x69, +0x52, 0x52, 0x6D, 0xD4, 0xC6, 0xBB, 0xB1, 0xAC, 0xAB, 0xAA, 0xA8, 0xAE, 0x68, 0x28, 0x1D, 0x1E, +0x2B, 0x53, 0xBC, 0xB6, 0xBD, 0xCA, 0xE1, 0x4E, 0x33, 0x2A, 0x2C, 0x3B, 0x7D, 0xBF, 0xBB, 0xC1, +0xD5, 0xED, 0x6A, 0x4F, 0x4C, 0x58, 0x7E, 0xD6, 0xC7, 0xBB, 0xB2, 0xAD, 0xA9, 0xA6, 0xA9, 0xC3, +0x2D, 0x1D, 0x1B, 0x23, 0x41, 0xBC, 0xAF, 0xB5, 0xC2, 0xDE, 0x4F, 0x3B, 0x2D, 0x27, 0x2D, 0x49, +0xC3, 0xB5, 0xB9, 0xCB, 0x64, 0x54, 0x56, 0x51, 0x58, 0x75, 0xE3, 0xD1, 0xCA, 0xC1, 0xB6, 0xAB, +0xA6, 0xA3, 0xA6, 0xC0, 0x2B, 0x1C, 0x1A, 0x24, 0x4D, 0xB0, 0xAA, 0xB0, 0xC3, 0xF0, 0x46, 0x38, +0x2D, 0x28, 0x2B, 0x4C, 0xBC, 0xB2, 0xB6, 0xD1, 0x4B, 0x46, 0x4F, 0x58, 0x61, 0xEE, 0xE1, 0xDB, +0xCF, 0xCB, 0xBD, 0xAE, 0xA7, 0xA3, 0xA2, 0xB6, 0x2C, 0x1B, 0x19, 0x21, 0x52, 0xAB, 0xA5, 0xAE, +0xC9, 0x4F, 0x3B, 0x37, 0x32, 0x2A, 0x2A, 0x3D, 0xC9, 0xB2, 0xB1, 0xCA, 0x44, 0x3D, 0x49, 0x5F, +0xDD, 0xD8, 0x77, 0x6E, 0xED, 0xDB, 0xC7, 0xB7, 0xAB, 0xA5, 0xA3, 0xA6, 0xC8, 0x26, 0x1A, 0x1A, +0x27, 0xC5, 0xA4, 0xA3, 0xAF, 0xE9, 0x3B, 0x33, 0x34, 0x31, 0x2D, 0x31, 0x57, 0xBF, 0xB3, 0xBA, +0x78, 0x41, 0x3E, 0x4E, 0xDC, 0xCE, 0xD4, 0x78, 0x5B, 0x67, 0xDC, 0xC4, 0xB7, 0xAC, 0xA6, 0xA5, +0xA5, 0xBA, 0x2C, 0x1B, 0x19, 0x23, 0xD8, 0xA3, 0x9F, 0xAB, 0xDA, 0x34, 0x2D, 0x30, 0x33, 0x33, +0x37, 0x54, 0xC1, 0xB7, 0xBD, 0x6E, 0x41, 0x3D, 0x4A, 0xD8, 0xCA, 0xD0, 0xEB, 0x56, 0x54, 0x74, +0xCE, 0xBD, 0xAF, 0xA8, 0xA6, 0xA5, 0xAE, 0x3B, 0x1E, 0x19, 0x1E, 0x43, 0xA8, 0x9E, 0xA6, 0xC8, +0x33, 0x29, 0x2C, 0x32, 0x39, 0x3D, 0x4E, 0xCD, 0xBE, 0xC2, 0xFF, 0x40, 0x3D, 0x48, 0xE0, 0xC4, +0xCB, 0xEA, 0x4F, 0x48, 0x59, 0xD7, 0xBE, 0xB5, 0xAD, 0xA9, 0xA9, 0xA7, 0xB3, 0x34, 0x1D, 0x19, +0x20, 0xEE, 0xA2, 0x9D, 0xA8, 0x60, 0x2A, 0x26, 0x2D, 0x3B, 0x4A, 0x4E, 0x64, 0xCE, 0xC6, 0xCF, +0x57, 0x42, 0x47, 0x67, 0xCB, 0xC3, 0xD4, 0x5C, 0x48, 0x47, 0x63, 0xCA, 0xBA, 0xB2, 0xAE, 0xAC, +0xAC, 0xAB, 0xB3, 0x3D, 0x1F, 0x1B, 0x20, 0x51, 0xA5, 0x9E, 0xA8, 0x6C, 0x2A, 0x24, 0x2B, 0x3E, +0x5E, 0x6C, 0x66, 0xFA, 0xE0, 0xE4, 0x60, 0x4B, 0x4E, 0x71, 0xD2, 0xC8, 0xD8, 0x5A, 0x4A, 0x49, +0x6E, 0xC6, 0xB9, 0xB3, 0xB1, 0xAF, 0xAE, 0xAC, 0xAF, 0x48, 0x21, 0x1B, 0x1F, 0x4C, 0xA5, 0x9D, +0xA7, 0x64, 0x28, 0x23, 0x2C, 0x4A, 0xD6, 0xD9, 0x61, 0x59, 0x6C, 0xEF, 0xF8, 0x5B, 0x5B, 0xEE, +0xD5, 0xCD, 0xDB, 0x5C, 0x4D, 0x4C, 0x6E, 0xC8, 0xBB, 0xB8, 0xB8, 0xB6, 0xB3, 0xAD, 0xA8, 0xBC, +0x2D, 0x1D, 0x1B, 0x2B, 0xB7, 0x9F, 0xA1, 0xB9, 0x33, 0x23, 0x28, 0x3A, 0xEB, 0xCF, 0x77, 0x50, +0x56, 0x6E, 0xE2, 0x73, 0x55, 0x5D, 0xE6, 0xCF, 0xD9, 0x5B, 0x4B, 0x47, 0x59, 0xD2, 0xC3, 0xBD, +0xBD, 0xBC, 0xB6, 0xAE, 0xA9, 0xAB, 0x68, 0x24, 0x1B, 0x1E, 0x3C, 0xAA, 0x9E, 0xA6, 0xDE, 0x2A, +0x23, 0x2C, 0x47, 0xD1, 0xCE, 0x72, 0x55, 0x58, 0x6A, 0x78, 0x5D, 0x5B, 0xF9, 0xDA, 0xD3, 0xDE, +0x5A, 0x49, 0x4A, 0x5F, 0xD1, 0xC0, 0xBD, 0xBC, 0xB9, 0xB3, 0xAD, 0xA9, 0xB1, 0x3C, 0x1F, 0x1C, +0x24, 0xE1, 0xA4, 0x9F, 0xAD, 0x44, 0x26, 0x25, 0x32, 0x6E, 0xC3, 0xCD, 0x64, 0x4F, 0x4F, 0x62, +0x70, 0x5C, 0x68, 0xE1, 0xD4, 0xD3, 0xF6, 0x4E, 0x45, 0x4B, 0x78, 0xCA, 0xBE, 0xBC, 0xBC, 0xB8, +0xB3, 0xAC, 0xA9, 0xBC, 0x2F, 0x1E, 0x1C, 0x2A, 0xBC, 0xA0, 0xA1, 0xB7, 0x35, 0x24, 0x28, 0x3B, +0xD8, 0xC4, 0xDC, 0x53, 0x4B, 0x4F, 0x67, 0x6D, 0x65, 0xEA, 0xDB, 0xD5, 0xDA, 0x5E, 0x4B, 0x48, +0x53, 0xDB, 0xC4, 0xBD, 0xBD, 0xBB, 0xB5, 0xAE, 0xA8, 0xAB, 0x75, 0x25, 0x1B, 0x1E, 0x3D, 0xAA, +0x9E, 0xA6, 0xDC, 0x2B, 0x25, 0x2E, 0x4E, 0xCC, 0xCC, 0x66, 0x4B, 0x4C, 0x5A, 0x74, 0x6C, 0x6D, +0xDF, 0xD6, 0xD6, 0xED, 0x4D, 0x43, 0x46, 0x59, 0xD0, 0xBF, 0xBC, 0xBB, 0xB8, 0xB3, 0xAD, 0xA9, +0xB3, 0x38, 0x1E, 0x1B, 0x24, 0xCF, 0xA2, 0x9F, 0xAF, 0x3E, 0x26, 0x27, 0x36, 0x6A, 0xCD, 0xE6, +0x4F, 0x4D, 0x55, 0x6E, 0xEF, 0x63, 0x7B, 0xDA, 0xDB, 0xDF, 0x5F, 0x49, 0x47, 0x4F, 0xE8, 0xC5, +0xBD, 0xBC, 0xBB, 0xB6, 0xAF, 0xAA, 0xAA, 0xCD, 0x29, 0x1C, 0x1D, 0x34, 0xAE, 0x9F, 0xA4, 0xC7, +0x2E, 0x25, 0x2C, 0x41, 0xDB, 0xD2, 0x75, 0x5B, 0x59, 0x60, 0x6E, 0x5B, 0x5C, 0xDF, 0xD0, 0xD8, +0x74, 0x4B, 0x43, 0x4B, 0x6E, 0xCC, 0xBF, 0xBD, 0xBE, 0xBC, 0xB5, 0xAD, 0xA8, 0xAD, 0x4B, 0x22, +0x1C, 0x22, 0x65, 0xA6, 0x9F, 0xAC, 0x4C, 0x2A, 0x28, 0x33, 0x50, 0xDE, 0xF2, 0x65, 0x7C, 0xF8, +0x79, 0x5A, 0x4B, 0x5E, 0xD7, 0xCF, 0xD6, 0x5F, 0x45, 0x43, 0x4C, 0xFB, 0xC9, 0xBF, 0xBD, 0xBC, +0xB8, 0xB2, 0xAD, 0xAA, 0xB7, 0x38, 0x20, 0x1D, 0x29, 0xC6, 0xA5, 0xA4, 0xB8, 0x3C, 0x2A, 0x2C, +0x39, 0x53, 0x7F, 0x6F, 0x79, 0xE8, 0xF9, 0x61, 0x4D, 0x4B, 0xFF, 0xD0, 0xD3, 0xEC, 0x4F, 0x45, +0x49, 0x58, 0xDF, 0xC7, 0xBF, 0xBD, 0xBB, 0xB5, 0xAF, 0xA9, 0xAA, 0xCA, 0x2C, 0x1D, 0x1E, 0x36, +0xB1, 0xA2, 0xA8, 0xCE, 0x33, 0x2B, 0x30, 0x3E, 0x4F, 0x5A, 0x6D, 0xD8, 0xD2, 0xF5, 0x4F, 0x46, +0x54, 0xD4, 0xCA, 0xD7, 0x65, 0x48, 0x43, 0x4C, 0x61, 0xD7, 0xC4, 0xBF, 0xBD, 0xB7, 0xB1, 0xAD, +0xAA, 0xB0, 0x48, 0x23, 0x1D, 0x24, 0x5D, 0xAA, 0xA4, 0xB0, 0x56, 0x30, 0x2E, 0x34, 0x3E, 0x47, +0x52, 0xE3, 0xC9, 0xCE, 0x65, 0x45, 0x43, 0x6A, 0xCE, 0xCD, 0xDE, 0x58, 0x49, 0x49, 0x4F, 0x6D, +0xD1, 0xC0, 0xBB, 0xB6, 0xAF, 0xAE, 0xAA, 0xAB, 0xCF, 0x2B, 0x1D, 0x1E, 0x36, 0xB2, 0xA4, 0xA9, +0xC7, 0x3B, 0x2F, 0x31, 0x37, 0x3D, 0x46, 0x6E, 0xC7, 0xC5, 0xE5, 0x4C, 0x41, 0x50, 0xD5, 0xCB, +0xDF, 0x58, 0x4C, 0x49, 0x4E, 0x62, 0xE4, 0xC8, 0xBD, 0xB9, 0xB4, 0xAF, 0xAD, 0xA9, 0xB2, 0x41, +0x22, 0x1D, 0x26, 0xEB, 0xAA, 0xA6, 0xB3, 0x5D, 0x38, 0x32, 0x32, 0x34, 0x39, 0x4D, 0xCC, 0xBD, +0xC7, 0x60, 0x44, 0x47, 0x6D, 0xDC, 0xE2, 0xEF, 0x63, 0x58, 0x50, 0x4D, 0x5A, 0xDB, 0xC3, 0xBA, +0xB3, 0xAF, 0xAD, 0xAC, 0xAE, 0xD3, 0x2D, 0x1F, 0x20, 0x38, 0xB9, 0xA9, 0xAD, 0xC4, 0x4C, 0x39, +0x33, 0x30, 0x32, 0x3C, 0xFA, 0xBE, 0xBE, 0xD5, 0x51, 0x46, 0x4F, 0x6F, 0x7B, 0x65, 0x68, 0x76, +0x60, 0x54, 0x52, 0x61, 0xCF, 0xBF, 0xB7, 0xAE, 0xAC, 0xAB, 0xAB, 0xBC, 0x39, 0x22, 0x1E, 0x2B, +0xE7, 0xAF, 0xAC, 0xB6, 0xD1, 0x4E, 0x3A, 0x2F, 0x2D, 0x31, 0x45, 0xCC, 0xBC, 0xC2, 0xDA, 0x58, +0x4D, 0x55, 0x52, 0x52, 0x68, 0xED, 0xF4, 0x66, 0x55, 0x59, 0xEF, 0xCE, 0xBF, 0xB5, 0xAD, 0xAB, +0xAB, 0xAE, 0xCC, 0x31, 0x22, 0x22, 0x2F, 0xE8, 0xB6, 0xB1, 0xB8, 0xC4, 0x73, 0x3D, 0x2F, 0x2B, +0x2F, 0x3F, 0xDD, 0xC0, 0xBF, 0xC7, 0xD8, 0x73, 0x55, 0x46, 0x44, 0x53, 0x7B, 0xEE, 0xED, 0xF2, +0xED, 0xDC, 0xCF, 0xC1, 0xB3, 0xAC, 0xA9, 0xA9, 0xB2, 0x58, 0x2C, 0x24, 0x28, 0x36, 0x5C, 0xC7, +0xBA, 0xB6, 0xB7, 0xCA, 0x49, 0x34, 0x2D, 0x2E, 0x37, 0x49, 0xE0, 0xC4, 0xBD, 0xBE, 0xC7, 0xEA, +0x4C, 0x42, 0x44, 0x49, 0x50, 0x69, 0xDD, 0xD0, 0xCB, 0xC6, 0xBD, 0xB3, 0xAD, 0xAB, 0xAB, 0xBA, +0x49, 0x2F, 0x2B, 0x2D, 0x32, 0x3A, 0x4B, 0xD6, 0xBC, 0xB6, 0xBD, 0xD7, 0x51, 0x3D, 0x36, 0x34, +0x37, 0x3E, 0x52, 0xDE, 0xC8, 0xC3, 0xC7, 0xCE, 0xDE, 0x72, 0x56, 0x4F, 0x53, 0x5D, 0xFF, 0xDA, +0xC9, 0xBD, 0xB7, 0xB4, 0xB2, 0xB6, 0xC6, 0x62, 0x47, 0x3F, 0x3D, 0x3B, 0x3B, 0x40, 0x4E, 0x6F, +0xEC, 0x7B, 0x67, 0x5E, 0x5B, 0x59, 0x55, 0x5A, 0x65, 0x5E, 0x5A, 0x5F, 0x61, 0x5E, 0x63, 0x65, +0x61, 0x6D, 0xF5, 0xFA, 0x7A, 0x77, 0x77, 0xFF, 0xEB, 0xDC, 0xD5, 0xCE, 0xCA, 0xC8, 0xC8, 0xCD, +0xD9, 0xEC, 0x76, 0x70, 0xFD, 0xED, 0xEA, 0xEE, 0x7D, 0x66, 0x59, 0x53, 0x50, 0x4F, 0x50, 0x54, +0x56, 0x58, 0x59, 0x5A, 0x5A, 0x5C, 0x5F, 0x6B, 0xF6, 0xE5, 0xE1, 0xE7, 0xEF, 0xF5, 0xF2, 0xEA, +0xDF, 0xD8, 0xCE, 0xC8, 0xC4, 0xC5, 0xCB, 0xD4, 0xDF, 0xE9, 0xE7, 0xE1, 0xDD, 0xDB, 0xDE, 0xEE, +0x68, 0x57, 0x4F, 0x4D, 0x4D, 0x4E, 0x4F, 0x4F, 0x52, 0x54, 0x53, 0x51, 0x53, 0x57, 0x5E, 0x6F, +0xFA, 0xEF, 0xEF, 0xF3, 0xF1, 0xF1, 0xEE, 0xE6, 0xDE, 0xD6, 0xCF, 0xCD, 0xCE, 0xD3, 0xDA, 0xDC, +0xDF, 0xDF, 0xD9, 0xD5, 0xD4, 0xD7, 0xE0, 0xFE, 0x6B, 0x5F, 0x5A, 0x58, 0x56, 0x54, 0x54, 0x53, +0x53, 0x50, 0x4E, 0x4F, 0x52, 0x56, 0x5C, 0x64, 0x67, 0x66, 0x69, 0x6C, 0x6D, 0x74, 0xFA, 0xEC, +0xDF, 0xD7, 0xD6, 0xDD, 0xE6, 0xF3, 0x7B, 0xF7, 0xE8, 0xDC, 0xD3, 0xD0, 0xD2, 0xD9, 0xE1, 0xE7, +0xEB, 0xF6, 0x7B, 0x74, 0x6F, 0x6B, 0x66, 0x5E, 0x59, 0x55, 0x53, 0x52, 0x56, 0x59, 0x5C, 0x61, +0x5F, 0x64, 0x65, 0x62, 0x6F, 0x7B, 0xFC, 0xE4, 0xDC, 0xD9, 0xE2, 0x7E, 0xFF, 0xFE, 0xFF, 0xEE, +0xDF, 0xD8, 0xD6, 0xD7, 0xDB, 0xDD, 0xDD, 0xE8, 0xE7, 0xE3, 0xEA, 0xE7, 0xF9, 0x72, 0x7C, 0x5F, +0x56, 0x58, 0x58, 0x56, 0x57, 0x57, 0x53, 0x54, 0x4A, 0x42, 0x4F, 0x67, 0x6A, 0xE0, 0xD4, 0xD8, +0xD7, 0xDD, 0xFD, 0xFE, 0xE4, 0x7B, 0xFF, 0xD9, 0xDF, 0xDE, 0xD7, 0xDA, 0xCF, 0xCF, 0xD3, 0xCD, +0xD3, 0xDF, 0xDD, 0xDE, 0xF3, 0x6D, 0x5F, 0x55, 0x54, 0x55, 0x51, 0x51, 0x50, 0x4F, 0x51, 0x53, +0x57, 0x59, 0x60, 0x73, 0xFB, 0xE7, 0xE1, 0xEA, 0xF4, 0x7D, 0x6D, 0x6F, 0x7F, 0x78, 0xF5, 0xE7, +0xEA, 0xE0, 0xDE, 0xD9, 0xCD, 0xCB, 0xC5, 0xC2, 0xC5, 0xCB, 0xDB, 0xDD, 0xEC, 0x53, 0x4C, 0x45, +0x42, 0x49, 0x48, 0x49, 0x4D, 0x51, 0x5A, 0x55, 0x55, 0x5D, 0x64, 0xF4, 0xED, 0xF5, 0xEB, 0xF2, +0x7A, 0x6D, 0x60, 0x5E, 0x6E, 0xF3, 0xF7, 0xE9, 0xDF, 0xDD, 0xD4, 0xCD, 0xC8, 0xC1, 0xBC, 0xB8, +0xB5, 0xB8, 0xC7, 0xF5, 0x52, 0x3E, 0x38, 0x37, 0x36, 0x3D, 0x4B, 0x59, 0xFD, 0xDF, 0xE3, 0xFE, +0x5C, 0x54, 0x52, 0x4E, 0x50, 0x55, 0x5D, 0xFF, 0xF2, 0xF1, 0xE9, 0xFB, 0xFD, 0x74, 0x5E, 0x62, +0x7A, 0xE3, 0xD2, 0xCA, 0xC0, 0xB9, 0xB1, 0xAD, 0xAE, 0xBC, 0x68, 0x3E, 0x31, 0x2D, 0x2E, 0x30, +0x3B, 0x5B, 0xD4, 0xC7, 0xC9, 0xD6, 0x65, 0x4A, 0x46, 0x3E, 0x3D, 0x47, 0x51, 0x7F, 0xD5, 0xD0, +0xCE, 0xD2, 0xE2, 0x6E, 0x57, 0x55, 0x61, 0xEA, 0xCD, 0xBE, 0xB7, 0xB2, 0xAD, 0xAB, 0xB0, 0xCE, +0x40, 0x2F, 0x2B, 0x2D, 0x2F, 0x38, 0x59, 0xCA, 0xBD, 0xBE, 0xCF, 0x70, 0x45, 0x39, 0x3A, 0x3B, +0x3F, 0x5D, 0xD9, 0xCB, 0xC4, 0xC5, 0xCF, 0xEA, 0x62, 0x52, 0x50, 0x5C, 0x7E, 0xD1, 0xBE, 0xB5, +0xAF, 0xAE, 0xAB, 0xAC, 0xC2, 0x44, 0x2F, 0x2A, 0x2D, 0x32, 0x38, 0x55, 0xC6, 0xBA, 0xBC, 0xCF, +0x5B, 0x40, 0x36, 0x34, 0x38, 0x40, 0x66, 0xCD, 0xC4, 0xC2, 0xC6, 0xD1, 0xFE, 0x52, 0x4C, 0x4F, +0x5C, 0xEF, 0xCF, 0xC1, 0xB7, 0xAF, 0xAD, 0xAB, 0xAD, 0xC9, 0x3C, 0x2D, 0x29, 0x2D, 0x35, 0x3D, +0xF1, 0xBD, 0xB8, 0xBF, 0xE1, 0x4C, 0x3C, 0x32, 0x31, 0x39, 0x47, 0xF7, 0xCB, 0xC4, 0xC2, 0xC7, +0xD9, 0x6F, 0x54, 0x4D, 0x4F, 0x5D, 0xEF, 0xCF, 0xC1, 0xB8, 0xAF, 0xAD, 0xAB, 0xAC, 0xC9, 0x3A, +0x2C, 0x29, 0x2D, 0x37, 0x44, 0xD8, 0xB9, 0xB7, 0xC4, 0x6C, 0x44, 0x38, 0x31, 0x30, 0x39, 0x4E, +0xDF, 0xCA, 0xC5, 0xC6, 0xCD, 0xEF, 0x5E, 0x5A, 0x53, 0x55, 0x64, 0xE8, 0xCD, 0xC4, 0xBB, 0xB0, +0xAC, 0xAA, 0xAC, 0xD0, 0x36, 0x2C, 0x2B, 0x2E, 0x39, 0x4A, 0xCB, 0xB6, 0xB7, 0xC8, 0x5D, 0x43, +0x39, 0x31, 0x32, 0x3D, 0x58, 0xD9, 0xCD, 0xCA, 0xC9, 0xD6, 0x73, 0x62, 0x63, 0x62, 0x68, 0x72, +0xE9, 0xCE, 0xC6, 0xBB, 0xAF, 0xAD, 0xAB, 0xAE, 0xD7, 0x38, 0x2D, 0x2C, 0x2F, 0x3B, 0x4F, 0xCA, +0xB6, 0xB8, 0xCB, 0x5D, 0x41, 0x39, 0x32, 0x33, 0x3E, 0x59, 0xDC, 0xCF, 0xCD, 0xCB, 0xD8, 0x63, +0x53, 0x5A, 0x5E, 0x61, 0x6F, 0xEA, 0xCF, 0xC6, 0xBC, 0xB0, 0xAD, 0xAB, 0xAE, 0xEE, 0x32, 0x2C, +0x2C, 0x30, 0x3B, 0x50, 0xC9, 0xB6, 0xB9, 0xCF, 0x5D, 0x47, 0x3A, 0x32, 0x33, 0x3F, 0x63, 0xDB, +0xD5, 0xCC, 0xC8, 0xD7, 0x66, 0x56, 0x58, 0x5C, 0x5A, 0x5B, 0x7E, 0xCE, 0xC4, 0xBB, 0xB0, 0xAD, +0xAB, 0xAF, 0x7B, 0x2F, 0x2C, 0x2E, 0x31, 0x39, 0x52, 0xC6, 0xB6, 0xBA, 0xD1, 0x5C, 0x4E, 0x3E, +0x32, 0x33, 0x3F, 0x64, 0xEA, 0xFD, 0xCE, 0xC2, 0xD0, 0x6C, 0x57, 0x5D, 0x64, 0x56, 0x53, 0x6C, +0xCE, 0xC4, 0xBD, 0xB1, 0xAD, 0xAA, 0xAE, 0x6F, 0x31, 0x2F, 0x31, 0x31, 0x37, 0x4F, 0xC5, 0xB6, +0xBA, 0xD2, 0xFC, 0x60, 0x45, 0x36, 0x35, 0x41, 0x56, 0xF8, 0xF2, 0xE4, 0xC6, 0xC8, 0x7C, 0x5A, +0x6A, 0x6A, 0x57, 0x52, 0x5B, 0xDA, 0xC6, 0xC0, 0xB6, 0xAE, 0xAA, 0xAC, 0xDD, 0x33, 0x30, 0x35, +0x31, 0x30, 0x42, 0xCE, 0xBA, 0xBA, 0xCC, 0xD9, 0xD9, 0x53, 0x3A, 0x35, 0x3E, 0x4D, 0x52, 0x60, +0xD6, 0xC5, 0xD2, 0x71, 0xE7, 0x7C, 0x55, 0x53, 0x51, 0x5B, 0xEE, 0xDC, 0xD3, 0xBE, 0xB2, 0xB0, +0xAD, 0xAE, 0x67, 0x31, 0x38, 0x39, 0x2F, 0x32, 0x49, 0xD5, 0xBE, 0xBF, 0xCF, 0xCD, 0xCA, 0x5C, +0x3D, 0x3C, 0x41, 0x41, 0x47, 0x5D, 0xE1, 0xC9, 0xC7, 0xD4, 0xDD, 0xFC, 0x51, 0x4C, 0x4C, 0x4C, +0x5F, 0xE2, 0xDC, 0xCA, 0xBF, 0xBD, 0xB9, 0xB5, 0xAF, 0xBA, 0x43, 0x35, 0x44, 0x3E, 0x2F, 0x36, +0x53, 0xD4, 0xC8, 0xCC, 0xD1, 0xC3, 0xC5, 0x5E, 0x41, 0x45, 0x49, 0x42, 0x44, 0x55, 0xE9, 0xD0, +0xD1, 0xDA, 0xD6, 0xD7, 0xFD, 0x5A, 0x58, 0x5B, 0x5A, 0x5B, 0x5F, 0x6C, 0x7A, 0xE1, 0xD3, 0xD2, +0xCC, 0xC8, 0xC4, 0xBF, 0xBD, 0xBA, 0xC2, 0x49, 0x3C, 0x4C, 0x41, 0x35, 0x3B, 0x52, 0xF3, 0xD6, +0xD1, 0xCE, 0xC3, 0xC6, 0x7A, 0x53, 0x57, 0x4E, 0x44, 0x46, 0x4F, 0x64, 0xE8, 0xDF, 0xDD, 0xD4, +0xD6, 0xEC, 0x56, 0x49, 0x54, 0x5E, 0x4F, 0x57, 0xFA, 0xE1, 0xDC, 0xE0, 0xE3, 0xD6, 0xD0, 0xDC, +0xD9, 0xC9, 0xC2, 0xBD, 0xC5, 0x58, 0x50, 0xE6, 0x4B, 0x37, 0x3F, 0x4F, 0x4D, 0x52, 0x6D, 0xDD, +0xC8, 0xC8, 0xDC, 0xDC, 0xD1, 0x72, 0x4A, 0x4A, 0x4E, 0x4B, 0x4E, 0x57, 0x6A, 0xDF, 0xD7, 0xDB, +0xD5, 0xCF, 0xDA, 0xF4, 0x74, 0x67, 0x5E, 0x5E, 0x5E, 0x66, 0xF9, 0xED, 0xEC, 0xE8, 0xE4, 0xE8, +0xF4, 0xF7, 0x60, 0x52, 0x6D, 0xF3, 0x5B, 0x66, 0xE7, 0xE1, 0xE0, 0xDF, 0xDF, 0xD8, 0xD1, 0xEA, +0x6B, 0xD9, 0xD1, 0xE5, 0xE6, 0xCC, 0xC4, 0xE7, 0x52, 0xEA, 0xE4, 0x4C, 0x48, 0x59, 0x5D, 0x59, +0x5D, 0x60, 0xF7, 0xDF, 0x79, 0x6A, 0xDF, 0xDC, 0xFE, 0xF8, 0xE2, 0xF0, 0x6F, 0x6B, 0x61, 0x5F, +0x62, 0x5D, 0x5E, 0x6C, 0x76, 0x70, 0xF7, 0xE5, 0xE6, 0xE7, 0xE5, 0xEA, 0xF4, 0x7D, 0x6C, 0x66, +0x68, 0x66, 0x66, 0x73, 0xF8, 0xF3, 0xF4, 0xF6, 0xFB, 0x7E, 0x7A, 0x7E, 0xF6, 0xEF, 0xED, 0xE9, +0xE9, 0xEF, 0xFB, 0x78, 0x6E, 0x69, 0x64, 0x63, 0x68, 0x6E, 0x74, 0x7B, 0xFA, 0xF6, 0xF3, 0xFF, +0x6B, 0x69, 0x69, 0x60, 0x5F, 0x65, 0x6C, 0x73, 0x7C, 0xF3, 0xEB, 0xE9, 0xEA, 0xE8, 0xE6, 0xE6, +0xE7, 0xE4, 0xDE, 0xDD, 0xE2, 0xE2, 0xE1, 0xE9, 0xF8, 0x77, 0x6B, 0x62, 0x5D, 0x5B, 0x5A, 0x59, +0x5A, 0x5B, 0x5D, 0x5E, 0x5E, 0x5E, 0x5F, 0x62, 0x67, 0x6D, 0x78, 0xFA, 0xF2, 0xEE, 0xEF, 0xF3, +0xF7, 0xF8, 0xFA, 0xFE, 0xFA, 0xF3, 0xF1, 0xEF, 0xEA, 0xE7, 0xE5, 0xE6, 0xE9, 0xEF, 0xFB, 0x79, +0x70, 0x6C, 0x6A, 0x6C, 0x6F, 0x77, 0x7C, 0xFD, 0xFB, 0x7F, 0x73, 0x6C, 0x69, 0x69, 0x6C, 0x73, +0xFA, 0xED, 0xE9, 0xE5, 0xE1, 0xE4, 0xE8, 0xE8, 0xE7, 0xE7, 0xE5, 0xE2, 0xE0, 0xDD, 0xDC, 0xE1, +0xE3, 0xE2, 0xEC, 0x7C, 0x6C, 0x63, 0x5D, 0x5B, 0x59, 0x58, 0x5A, 0x5B, 0x5B, 0x5C, 0x5F, 0x60, +0x5F, 0x60, 0x65, 0x6A, 0x75, 0xF8, 0xEC, 0xE7, 0xE6, 0xE7, 0xEA, 0xF0, 0xF8, 0xF9, 0xF4, 0xED, +0xE9, 0xE5, 0xE3, 0xE3, 0xE6, 0xEB, 0xF6, 0x76, 0x6C, 0x67, 0x62, 0x5F, 0x61, 0x64, 0x69, 0x6F, +0x73, 0x73, 0x75, 0x75, 0x70, 0x6E, 0x6F, 0x6E, 0x6E, 0x75, 0xFE, 0xF3, 0xEC, 0xE9, 0xE9, 0xE9, +0xED, 0xFA, 0x7A, 0x74, 0x71, 0x72, 0x73, 0x74, 0x7A, 0xFF, 0xFF, 0x7B, 0x72, 0x6E, 0x6D, 0x6C, +0x6C, 0x6E, 0x73, 0x7C, 0xFC, 0xF7, 0xF0, 0xEB, 0xE6, 0xE0, 0xDD, 0xDB, 0xDB, 0xDB, 0xDC, 0xDF, +0xE2, 0xE3, 0xE8, 0xF2, 0x7D, 0x6C, 0x61, 0x5D, 0x5A, 0x58, 0x59, 0x5C, 0x5E, 0x61, 0x66, 0x69, +0x6A, 0x6B, 0x6C, 0x6B, 0x6C, 0x75, 0xFE, 0xF7, 0xEE, 0xEA, 0xE8, 0xE6, 0xE9, 0xEC, 0xEB, 0xEB, +0xEE, 0xF0, 0xF2, 0xF6, 0xF9, 0xFD, 0x7F, 0xFF, 0x7C, 0x74, 0x6D, 0x69, 0x66, 0x64, 0x64, 0x68, +0x6B, 0x6D, 0x75, 0x7D, 0xFC, 0xF8, 0xFA, 0xFC, 0xFA, 0xF7, 0xF5, 0xF0, 0xEB, 0xE6, 0xE4, 0xE5, +0xE9, 0xED, 0xF2, 0xFC, 0x7A, 0x74, 0x6E, 0x6C, 0x6A, 0x69, 0x69, 0x6A, 0x6B, 0x6D, 0x6E, 0x6E, +0x6D, 0x6E, 0x70, 0x71, 0x74, 0x79, 0x7B, 0x7E, 0xFB, 0xF6, 0xF8, 0xF9, 0xF6, 0xF5, 0xF8, 0xFA, +0xF7, 0xF0, 0xEE, 0xF0, 0xF7, 0xFC, 0x7D, 0x73, 0x6C, 0x6B, 0x6B, 0x6A, 0x6B, 0x6B, 0x6B, 0x6B, +0x6C, 0x6D, 0x6D, 0x6E, 0x71, 0x71, 0x71, 0x72, 0x77, 0x7D, 0xFC, 0xF7, 0xF3, 0xED, 0xEB, 0xEB, +0xEE, 0xF4, 0xF9, 0xFE, 0x79, 0x77, 0x7B, 0x7F, 0x7F, 0xFF, 0xFF, 0x7B, 0x77, 0x76, 0x77, 0x79, +0x79, 0x7A, 0x7C, 0xFF, 0xFC, 0xFC, 0xFA, 0xF8, 0xF9, 0xF9, 0xFA, 0xFD, 0xFE, 0xFD, 0xFA, 0xF8, +0xF5, 0xF2, 0xF1, 0xF2, 0xF4, 0xF8, 0xFE, 0x7C, 0x79, 0x77, 0x77, 0x7A, 0x7E, 0x7F, 0x7C, 0x79, +0x78, 0x75, 0x73, 0x72, 0x71, 0x73, 0x75, 0x76, 0x78, 0x7D, 0xFD, 0xFB, 0xFC, 0xFF, 0x7D, 0x79, +0x76, 0x76, 0x77, 0x7C, 0xFB, 0xF5, 0xF3, 0xF3, 0xF3, 0xF7, 0x7D, 0x74, 0x6F, 0x6D, 0x6B, 0x6C, +0x6E, 0x73, 0x77, 0x77, 0x77, 0x7A, 0x7A, 0x76, 0x73, 0x72, 0x6F, 0x6D, 0x6B, 0x6C, 0x6F, 0x76, +0x7A, 0x7D, 0xFE, 0xFC, 0x7E, 0x7A, 0x75, 0x71, 0x6E, 0x6D, 0x6E, 0x71, 0x77, 0x7D, 0xFE, 0xFC, +0xFC, 0xFE, 0xFF, 0x7D, 0x7B, 0x7C, 0x7E, 0xFF, 0xFF, 0xFC, 0xF9, 0xF7, 0xF6, 0xF8, 0xFA, 0xFC, +0xFF, 0x7E, 0x7F, 0xFF, 0xFD, 0xFB, 0xF7, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFD, 0x7D, 0x7A, 0x7A, +0x7D, 0x7E, 0x7F, 0xFF, 0xFE, 0xFE, 0x7E, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0xFF, 0xFD, 0xFD, 0xFD, +0xFB, 0xF8, 0xF7, 0xF9, 0xFD, 0x7C, 0x79, 0x78, 0x78, 0x77, 0x77, 0x76, 0x75, 0x75, 0x75, 0x75, +0x75, 0x74, 0x76, 0x78, 0x79, 0x7B, 0x7D, 0x7F, 0xFD, 0xFB, 0xFF, 0x7A, 0x79, 0x7D, 0xFE, 0xFD, +0xFD, 0xFC, 0xFD, 0xFA, 0xF5, 0xF2, 0xF3, 0xF6, 0xF8, 0xF9, 0xFC, 0xFF, 0xFD, 0xF8, 0xF5, 0xF5, +0xF6, 0xFA, 0xFC, 0xFD, 0x7F, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x77, 0x7B, 0x7E, 0x7E, 0x7E, 0x7F, +0x7E, 0x7C, 0x79, 0x76, 0x76, 0x78, 0x79, 0x78, 0x7B, 0x7E, 0xFF, 0x7F, 0x7C, 0x7A, 0x78, 0x75, +0x73, 0x73, 0x74, 0x76, 0x77, 0x78, 0x7B, 0x7B, 0x79, 0x79, 0x78, 0x77, 0x78, 0x74, 0x71, 0x72, +0x73, 0x76, 0x77, 0x77, 0x79, 0x79, 0x77, 0x76, 0x75, 0x76, 0x78, 0x7B, 0x7F, 0xFC, 0xFB, 0xFB, +0xFA, 0xFB, 0xFE, 0x7C, 0x79, 0x79, 0x78, 0x78, 0x7B, 0xFF, 0xFD, 0xFD, 0xFC, 0xFC, 0xFE, 0x7E, +0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x78, 0x79, 0x7A, 0x7C, 0x7C, 0x7C, 0x7B, 0x77, 0x78, 0x7A, +0x7A, 0x7A, 0x7C, 0x7E, 0xFF, 0x7F, 0x7F, 0xFF, 0xFF, 0x7F, 0x7E, 0x7F, 0x7E, 0x7C, 0x7A, 0x7A, +0x79, 0x79, 0x7B, 0x7E, 0x7E, 0x7F, 0xFD, 0xFC, 0xFD, 0xFD, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, +0xFF, 0x7E, 0x7D, 0x7F, 0xFF, 0xFF, 0xFE, 0xFC, 0xFB, 0xFC, 0xFC, 0xFE, 0x7E, 0x7F, 0x7E, 0x7B, +0x7C, 0x7D, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x77, 0x7A, +0x7C, 0x7D, 0x7E, 0x7E, 0x7C, 0x79, 0x76, 0x77, 0x79, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0x7D, +0x7D, 0x7C, 0x7A, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x7C, 0x7E, 0x7D, 0x7E, 0x7E, 0x7C, 0x7B, 0x7C, +0x7C, 0x7C, 0x7D, 0xFF, 0xFC, 0xFB, 0xFB, 0xFC, 0xFF, 0x7C, 0x79, 0x77, 0x74, 0x75, 0x77, 0x7A, +0x7D, 0x7E, 0xFF, 0xFD, 0xFD, 0xFE, 0x7E, 0x7D, 0x7D, 0x7B, 0x7A, 0x7B, 0x7D, 0x7E, 0xFE, 0xFD, +0xFF, 0x7F, 0x7D, 0x7B, 0x7A, 0x78, 0x76, 0x76, 0x79, 0x7C, 0x7E, 0xFF, 0xFF, 0x7F, 0x7E, 0x7C, +0x7A, 0x79, 0x78, 0x78, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0x7F, 0x7E, 0x7D, 0x7B, 0x7A, +0x7B, 0x7C, 0x7D, 0xFE, 0xFC, 0xFA, 0xF9, 0xFA, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFA, 0xF8, 0xF7, +0xF6, 0xF7, 0xF9, 0xFB, 0xFE, 0x7E, 0x7C, 0x7A, 0x79, 0x79, 0x7B, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, +0x7E, 0x7C, 0x7B, 0x79, 0x7A, 0x7C, 0x7C, 0x7E, 0x7E, 0x7F, 0xFF, 0x7F, 0x7E, 0x7C, 0x7B, 0x79, +0x77, 0x76, 0x76, 0x78, 0x7B, 0x7B, 0x7B, 0x7A, 0x7A, 0x7A, 0x77, 0x77, 0x78, 0x78, 0x79, 0x7B, +0x7D, 0x79, 0x79, 0x7E, 0x79, 0x78, 0x79, 0x78, 0x7A, 0x78, 0x7D, 0x7D, 0x7C, 0xFF, 0x7D, 0x7F, +0x7E, 0x7B, 0x7A, 0x76, 0x79, 0x76, 0x78, 0x7B, 0x79, 0xFF, 0x7D, 0xFB, 0xFD, 0x7D, 0xF9, 0x7B, +0xFF, 0x79, 0x75, 0xFF, 0x6E, 0x7F, 0x71, 0x73, 0x79, 0x51, 0x60, 0xE2, 0x6F, 0x7D, 0xF7, 0xF5, +0x77, 0x72, 0xE4, 0x50, 0x4C, 0xDE, 0xFB, 0x66, 0xE5, 0xF6, 0x6F, 0x6C, 0xE7, 0xDC, 0x6E, 0xFD, +0xE6, 0x7E, 0xE9, 0x77, 0x62, 0xE3, 0xE9, 0x6C, 0x71, 0xEA, 0xDE, 0x75, 0x7E, 0xE8, 0x75, 0xF8, +0x7A, 0xFC, 0xF2, 0x65, 0xF8, 0xEE, 0xF9, 0xF4, 0x73, 0xE4, 0xF9, 0x6E, 0xE5, 0x75, 0x67, 0x5A, +0x50, 0x57, 0x5A, 0x7D, 0x6C, 0x64, 0xDA, 0xED, 0x64, 0xEA, 0xE9, 0xF5, 0x7E, 0x6F, 0xFC, 0xF2, +0x66, 0x63, 0xF7, 0x7D, 0x78, 0xF6, 0xF8, 0xE1, 0xE2, 0xF9, 0xEB, 0xE4, 0xED, 0xFE, 0xFA, 0xF6, +0xF1, 0xF2, 0x6F, 0xFE, 0xE8, 0xFF, 0x7F, 0xEA, 0xE8, 0xED, 0xEE, 0xEA, 0xEB, 0xED, 0xF8, 0xEF, +0xE8, 0x7F, 0xF5, 0xE6, 0xF7, 0xF2, 0xF3, 0xF2, 0xDF, 0xEB, 0xF5, 0xE3, 0xEC, 0xF2, 0xEF, 0xFC, +0xED, 0xEF, 0xFD, 0xED, 0xF0, 0x7C, 0x77, 0xFE, 0xF1, 0x77, 0x79, 0xEF, 0xF6, 0xF8, 0xFB, 0x72, +0x75, 0x79, 0x78, 0x70, 0x6E, 0x7C, 0x7D, 0x74, 0x79, 0x77, 0x6E, 0x71, 0x7D, 0x6F, 0x6B, 0x7D, +0xFE, 0x76, 0x7A, 0x7D, 0x7F, 0x75, 0x6C, 0x7B, 0xF7, 0x7A, 0x7B, 0x7E, 0x74, 0x79, 0x75, 0x70, +0x7C, 0x79, 0xFD, 0xF6, 0x6E, 0x6E, 0x7B, 0x6B, 0x67, 0x6D, 0x6E, 0x6A, 0x67, 0x6A, 0x6D, 0x6F, +0x6B, 0x67, 0x6D, 0x6C, 0x65, 0x63, 0x5E, 0x65, 0x6A, 0x5F, 0x68, 0x6C, 0x60, 0x6C, 0x7D, 0x6D, +0x6E, 0x7D, 0x7C, 0xFF, 0xEE, 0xEB, 0xEC, 0xE3, 0xDE, 0xE1, 0xE4, 0xE0, 0xE8, 0xF8, 0xEE, 0xFA, +0x6D, 0x69, 0x5C, 0x58, 0x59, 0x53, 0x50, 0x4E, 0x4D, 0x4E, 0x4F, 0x4F, 0x53, 0x51, 0x51, 0x54, +0x55, 0x56, 0x5A, 0x5E, 0x69, 0xF7, 0xE2, 0xD8, 0xCF, 0xCE, 0xCD, 0xCC, 0xCE, 0xCE, 0xCA, 0xC7, +0xC2, 0xBF, 0xBE, 0xBD, 0xC2, 0xD5, 0xF1, 0x62, 0x4B, 0x3F, 0x3D, 0x3D, 0x3E, 0x40, 0x42, 0x4A, +0x51, 0x51, 0x51, 0x55, 0x56, 0x4F, 0x4D, 0x4E, 0x50, 0x52, 0x55, 0x5C, 0x69, 0xFA, 0xE4, 0xD9, +0xCD, 0xC9, 0xC5, 0xC1, 0xBF, 0xBB, 0xBB, 0xBD, 0xB9, 0xB7, 0xB5, 0xB7, 0xC8, 0xDD, 0x61, 0x43, +0x3C, 0x38, 0x38, 0x3D, 0x40, 0x46, 0x4E, 0x5A, 0x60, 0x5D, 0x5B, 0x5B, 0x5A, 0x58, 0x56, 0x58, +0x5C, 0x5E, 0x5E, 0x64, 0x6B, 0x6D, 0xF9, 0xED, 0xE5, 0xDC, 0xD9, 0xD2, 0xCC, 0xC5, 0xBF, 0xBF, +0xBA, 0xB7, 0xB6, 0xB1, 0xB7, 0xCB, 0xFA, 0x49, 0x3A, 0x35, 0x31, 0x33, 0x3A, 0x42, 0x4C, 0x5C, +0xFD, 0xE1, 0xEE, 0x68, 0x66, 0x5C, 0x51, 0x4F, 0x4D, 0x55, 0x5F, 0x5D, 0x64, 0x71, 0xFA, 0xED, +0xEF, 0xEB, 0xDE, 0xD3, 0xCC, 0xC3, 0xBE, 0xBD, 0xB9, 0xB8, 0xB5, 0xAF, 0xB7, 0xCC, 0x60, 0x3F, +0x39, 0x34, 0x2F, 0x31, 0x3A, 0x47, 0x56, 0x6F, 0xE3, 0xDA, 0xD5, 0xEC, 0x56, 0x50, 0x4E, 0x4B, +0x4B, 0x4C, 0x57, 0x7B, 0xE7, 0xE0, 0xDC, 0xD5, 0xD6, 0xDE, 0xEC, 0xEF, 0xDE, 0xD7, 0xCC, 0xC1, +0xBD, 0xB8, 0xB5, 0xB4, 0xB0, 0xB6, 0xCB, 0x58, 0x3E, 0x38, 0x34, 0x2F, 0x2F, 0x38, 0x45, 0x59, +0x7D, 0xDD, 0xD1, 0xCE, 0xDD, 0x63, 0x53, 0x4E, 0x4C, 0x4A, 0x4B, 0x53, 0x69, 0xE7, 0xDB, 0xD5, +0xD0, 0xCE, 0xD3, 0xDC, 0xE4, 0xEA, 0xE8, 0xE2, 0xD5, 0xC8, 0xC0, 0xBB, 0xB8, 0xB5, 0xB2, 0xB9, +0xD1, 0x54, 0x40, 0x3A, 0x34, 0x2F, 0x2F, 0x36, 0x3F, 0x4C, 0x5B, 0x7E, 0xDE, 0xD4, 0xDB, 0xFF, +0x62, 0x58, 0x55, 0x53, 0x4F, 0x52, 0x5D, 0x6F, 0xF0, 0xE4, 0xDE, 0xDA, 0xD8, 0xDC, 0xE1, 0xE5, +0xDF, 0xDC, 0xD6, 0xCC, 0xC6, 0xC1, 0xBE, 0xBB, 0xB8, 0xBC, 0xCE, 0x67, 0x4B, 0x44, 0x3E, 0x38, +0x35, 0x37, 0x3D, 0x45, 0x4B, 0x53, 0x61, 0xFA, 0xE4, 0xEC, 0x7F, 0x79, 0x78, 0x79, 0x70, 0x68, +0x68, 0x70, 0x7B, 0x7D, 0x7D, 0xF9, 0xEE, 0xEA, 0xE8, 0xE6, 0xE1, 0xDB, 0xD6, 0xCF, 0xCB, 0xC8, +0xC5, 0xC1, 0xBE, 0xBF, 0xC7, 0xD5, 0xF9, 0x5F, 0x55, 0x4A, 0x42, 0x3E, 0x3E, 0x41, 0x45, 0x48, +0x4C, 0x56, 0x5F, 0x6F, 0xF8, 0xEF, 0xE7, 0xE4, 0xE6, 0xE2, 0xEA, 0xF5, 0xFD, 0x75, 0x75, 0x79, +0x75, 0x76, 0x7E, 0xFA, 0xF1, 0xE9, 0xE0, 0xDA, 0xD3, 0xCF, 0xCC, 0xCA, 0xC7, 0xC4, 0xC5, 0xCC, +0xD3, 0xDF, 0xFF, 0x69, 0x58, 0x4C, 0x47, 0x43, 0x42, 0x42, 0x43, 0x46, 0x4C, 0x55, 0x59, 0x62, +0x77, 0xFD, 0xEE, 0xEC, 0xF3, 0xEC, 0xF2, 0x76, 0x76, 0x6F, 0x6E, 0x79, 0x79, 0x7F, 0xF3, 0xED, +0xE4, 0xDD, 0xDB, 0xD7, 0xD3, 0xD0, 0xCE, 0xCC, 0xCB, 0xCA, 0xCC, 0xD1, 0xD6, 0xDD, 0xEA, 0x7E, +0x62, 0x56, 0x4F, 0x4C, 0x49, 0x48, 0x49, 0x4C, 0x50, 0x56, 0x58, 0x5C, 0x67, 0x6F, 0x6C, 0x6E, +0x6D, 0x6A, 0x6F, 0x6D, 0x6B, 0x6E, 0x6D, 0x76, 0xFA, 0xF9, 0xF1, 0xEB, 0xE7, 0xE1, 0xDE, 0xDD, +0xDB, 0xD8, 0xD7, 0xD4, 0xD2, 0xD0, 0xCF, 0xD4, 0xD8, 0xDA, 0xDF, 0xEA, 0xF8, 0x6D, 0x60, 0x5C, +0x58, 0x56, 0x56, 0x56, 0x57, 0x59, 0x5B, 0x5B, 0x5A, 0x5C, 0x5F, 0x5F, 0x5F, 0x63, 0x66, 0x6B, +0x72, 0x77, 0x7E, 0xF7, 0xF0, 0xEC, 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xEA, 0xE7, 0xE6, 0xE5, +0xE3, 0xE1, 0xDD, 0xDA, 0xD9, 0xD8, 0xDD, 0xDF, 0xDD, 0xE0, 0xE7, 0xEE, 0xFE, 0x74, 0x6C, 0x62, +0x5C, 0x59, 0x56, 0x54, 0x52, 0x51, 0x51, 0x52, 0x55, 0x58, 0x59, 0x5D, 0x62, 0x68, 0x70, 0x75, +0x7D, 0xF9, 0xF8, 0xF4, 0xF5, 0xF9, 0xF5, 0xF3, 0xF3, 0xF2, 0xF2, 0xEF, 0xED, 0xEB, 0xEA, 0xE6, +0xE3, 0xE0, 0xDC, 0xDA, 0xD7, 0xD8, 0xDB, 0xDB, 0xDA, 0xDC, 0xDF, 0xE8, 0xF6, 0x7F, 0x6E, 0x60, +0x5B, 0x58, 0x56, 0x54, 0x53, 0x52, 0x53, 0x59, 0x5C, 0x5E, 0x63, 0x68, 0x6F, 0x7B, 0x7C, 0xFF, +0xFC, 0xFC, 0xFB, 0xFC, 0xFD, 0xF8, 0xF7, 0xF6, 0xF4, 0xF5, 0xF3, 0xF0, 0xEF, 0xED, 0xEB, 0xE8, +0xE4, 0xE0, 0xDD, 0xDA, 0xD9, 0xDA, 0xDC, 0xDC, 0xDC, 0xE0, 0xE9, 0xF8, 0x76, 0x6B, 0x61, 0x5C, +0x5A, 0x5A, 0x5A, 0x5B, 0x5C, 0x5E, 0x62, 0x67, 0x6B, 0x6D, 0x6F, 0x72, 0x75, 0x76, 0x76, 0x75, +0x74, 0x79, 0x7E, 0x7B, 0x78, 0x7D, 0xFB, 0xFB, 0xFD, 0xFA, 0xF6, 0xF5, 0xF2, 0xEF, 0xEC, 0xE9, +0xE4, 0xDF, 0xDE, 0xDE, 0xE0, 0xE7, 0xEA, 0xEC, 0xF2, 0xFE, 0x76, 0x6F, 0x6F, 0x6D, 0x6A, 0x6A, +0x6B, 0x6C, 0x6C, 0x69, 0x67, 0x67, 0x66, 0x65, 0x64, 0x64, 0x65, 0x66, 0x67, 0x69, 0x6B, 0x6E, +0x71, 0x76, 0x7A, 0x7D, 0xFE, 0xFC, 0xFA, 0xF8, 0xF4, 0xF0, 0xEE, 0xEC, 0xEA, 0xE9, 0xE8, 0xE9, +0xEB, 0xEB, 0xEC, 0xED, 0xEE, 0xED, 0xEB, 0xE9, 0xEA, 0xE9, 0xE9, 0xEA, 0xEC, 0xF0, 0xF6, 0xFD, +0x78, 0x71, 0x6D, 0x69, 0x67, 0x66, 0x65, 0x65, 0x66, 0x67, 0x66, 0x66, 0x67, 0x67, 0x66, 0x66, +0x69, 0x6B, 0x6D, 0x73, 0x7A, 0xFE, 0xF7, 0xF3, 0xEF, 0xEE, 0xEE, 0xEC, 0xEB, 0xEA, 0xE8, 0xE7, +0xE5, 0xE3, 0xE1, 0xE1, 0xE1, 0xE3, 0xE6, 0xE8, 0xEB, 0xEF, 0xF8, 0x7E, 0x75, 0x6F, 0x6B, 0x69, +0x67, 0x66, 0x65, 0x65, 0x66, 0x67, 0x67, 0x68, 0x68, 0x69, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, +0x70, 0x6F, 0x6F, 0x6F, 0x72, 0x75, 0x79, 0xFF, 0xFB, 0xF6, 0xF2, 0xEF, 0xEE, 0xED, 0xEE, 0xF0, +0xF3, 0xF6, 0xF8, 0xFC, 0xFF, 0x7D, 0x79, 0x76, 0x72, 0x6E, 0x6D, 0x6B, 0x6B, 0x6C, 0x6C, 0x6D, +0x6E, 0x71, 0x76, 0x7B, 0xFF, 0xFE, 0xFD, 0xFC, 0xFD, 0x7F, 0x7B, 0x78, 0x75, 0x74, 0x75, 0x77, +0x7A, 0x7E, 0xFC, 0xF9, 0xF6, 0xF5, 0xF4, 0xF4, 0xF5, 0xF7, 0xF8, 0xF8, 0xF7, 0xF6, 0xF5, 0xF5, +0xF6, 0xF8, 0xFA, 0xFC, 0x7F, 0x7B, 0x79, 0x78, 0x77, 0x77, 0x79, 0x7D, 0xFD, 0xF9, 0xF4, 0xF2, +0xF1, 0xF1, 0xF3, 0xF5, 0xFA, 0xFE, 0x7F, 0xFF, 0xFD, 0xFC, 0xFB, 0xF7, 0xF5, 0xF4, 0xF4, 0xF6, +0xF8, 0xFB, 0xFD, 0xFF, 0x7E, 0x7E, 0x7E, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7E, 0x7B, 0x79, 0x77, +0x76, 0x75, 0x74, 0x74, 0x75, 0x78, 0x7C, 0x7F, 0xFE, 0xFD, 0xFE, 0xFF, 0x7E, 0x7C, 0x7B, 0x79, +0x79, 0x7A, 0x7D, 0xFE, 0xFC, 0xFA, 0xF8, 0xF8, 0xF9, 0xFB, 0xFD, 0x7F, 0x7B, 0x78, 0x76, 0x75, +0x74, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x75, 0x76, 0x76, 0x77, 0x7A, 0x7C, +0x7E, 0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7C, 0x7A, 0x78, 0x77, 0x77, 0x76, 0x79, 0x7B, 0x7E, 0xFF, +0xFE, 0xFD, 0xFD, 0xFF, 0x7E, 0x7C, 0x7C, 0x7B, 0x79, 0x78, 0x78, 0x78, 0x77, 0x75, 0x74, 0x74, +0x74, 0x74, 0x75, 0x76, 0x79, 0x7C, 0x7E, 0xFF, 0xFC, 0xF8, 0xF7, 0xF6, 0xF7, 0xF7, 0xF7, 0xF9, +0xFC, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7F, 0xFF, 0xFC, 0xFB, 0xFA, 0xF8, 0xF8, 0xF8, 0xF6, 0xF5, +0xF5, 0xF4, 0xF4, 0xF5, 0xF7, 0xF8, 0xFA, 0xFD, 0x7F, 0x7E, 0x7D, 0x7C, 0x7C, 0x7D, 0x7E, 0xFE, +0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF9, 0xF9, 0xFA, 0xFB, 0xFD, 0xFF, 0x7E, 0x7D, 0x79, 0x77, 0x75, +0x72, 0x71, 0x70, 0x70, 0x70, 0x71, 0x71, 0x70, 0x71, 0x72, 0x71, 0x72, 0x71, 0x72, 0x73, 0x72, +0x72, 0x71, 0x71, 0x71, 0x72, 0x74, 0x74, 0x76, 0x77, 0x77, 0x77, 0x78, 0x77, 0x78, 0x78, 0x78, +0x7A, 0x7C, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFD, 0xFF, 0x7E, 0x7D, 0x7B, 0x7C, 0x7B, +0x7B, 0x7B, 0x7B, 0x7B, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7B, 0x7C, 0x7E, 0xFF, 0xFD, +0xFB, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0xFF, 0x7F, 0x7D, 0x7C, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7D, +0x7F, 0x7F, 0xFF, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, +0xFF, 0xFF, 0xFF, 0xFD, 0xFA, 0xF9, 0xF7, 0xF5, 0xF4, 0xF3, 0xF1, 0xF1, 0xF1, 0xF1, 0xF2, 0xF2, +0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xFA, 0xFC, 0xFE, 0xFE, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, +0x7F, 0x7D, 0x7C, 0x7D, 0x7B, 0x7A, 0x7D, 0x7B, 0x7B, 0x7C, 0x7B, 0x7B, 0x7B, 0x79, 0x78, 0x77, +0x77, 0x76, 0x75, 0x76, 0x75, 0x74, 0x74, 0x75, 0x74, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73, 0x74, +0x72, 0x70, 0x70, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x70, 0x70, 0x70, 0x71, 0x72, 0x73, 0x73, 0x76, +0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7B, 0x7D, 0x7E, 0x7D, 0x7F, 0x7D, 0x7C, 0x7B, 0x7B, 0x7C, +0x7B, 0x7B, 0x7A, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0xFF, 0x7D, 0x7E, 0x7C, 0x7C, 0x7B, 0x78, +0x7C, 0x7A, 0x7C, 0x7D, 0x7B, 0x7E, 0x7C, 0x7F, 0x7D, 0x7A, 0x7E, 0x78, 0x7B, 0x6F, 0x68, 0x5C, +0x4C, 0x58, 0xDD, 0xE1, 0xEB, 0xE1, 0xE9, 0xEF, 0xF8, 0xE9, 0xE1, 0xED, 0xF9, 0xFC, 0xF2, 0xED, +0x7D, 0x76, 0xFB, 0xF9, 0x7C, 0x70, 0x6F, 0x78, 0x79, 0x6D, 0x6D, 0x76, 0x7D, 0xFE, 0x7A, 0x79, +0xFC, 0xFD, 0xFD, 0xFA, 0xFB, 0xFA, 0xFC, 0xFF, 0xFC, 0xFC, 0xFE, 0xFD, 0xFE, 0xFB, 0xFB, 0xFE, +0xFE, 0x7E, 0x7D, 0x7C, 0x7C, 0x7B, 0x78, 0x7D, 0x7D, 0xFF, 0xFA, 0xFF, 0xF9, 0xF9, 0xFA, 0xF7, +0x7F, 0xF9, 0x7A, 0x7A, 0x6F, 0x51, 0x52, 0x6E, 0x71, 0xF1, 0xD8, 0xD3, 0xDB, 0xEF, 0xE2, 0xDB, +0xED, 0xF6, 0xF3, 0xEF, 0xF4, 0x6A, 0x74, 0x73, 0x57, 0x5E, 0x77, 0x6E, 0xFD, 0xF4, 0xFC, 0x7D, +0x73, 0xE9, 0xDE, 0xE2, 0xDE, 0xE3, 0xE5, 0xE8, 0xFA, 0xF7, 0xFA, 0x6F, 0x6C, 0x6A, 0x6B, 0x6A, +0x66, 0x6B, 0x75, 0x70, 0x74, 0xFA, 0xFB, 0xFD, 0xF8, 0xF3, 0xF2, 0xFB, 0xF5, 0xED, 0xEF, 0xEB, +0xE5, 0xDF, 0xDA, 0xD7, 0xD5, 0xD3, 0xD3, 0xD4, 0xD8, 0xE0, 0xEE, 0x76, 0x5D, 0x53, 0x4D, 0x49, +0x46, 0x43, 0x42, 0x43, 0x43, 0x45, 0x48, 0x4B, 0x4F, 0x57, 0x60, 0x6D, 0xF7, 0xE3, 0xDB, 0xD4, +0xCF, 0xCB, 0xC8, 0xC4, 0xBE, 0xBC, 0xB9, 0xB4, 0xB6, 0xBC, 0xC1, 0xC3, 0xD5, 0x4F, 0x4B, 0x43, +0x36, 0x33, 0x34, 0x32, 0x31, 0x36, 0x3B, 0x3F, 0x48, 0x60, 0xDF, 0xD2, 0xC9, 0xC1, 0xC3, 0xC6, +0xC7, 0xCF, 0xE3, 0x67, 0x56, 0x47, 0x3E, 0x3F, 0x3C, 0x3B, 0x43, 0x48, 0x4F, 0xFA, 0xD5, 0xC5, +0xBD, 0xB7, 0xB1, 0xAE, 0xAC, 0xAE, 0xB1, 0xB5, 0xC0, 0xD7, 0x5D, 0x40, 0x38, 0x31, 0x2E, 0x2D, +0x2C, 0x2E, 0x32, 0x37, 0x3F, 0x4F, 0xF8, 0xD0, 0xC4, 0xBC, 0xBB, 0xBB, 0xBB, 0xBE, 0xC7, 0xD0, +0xF1, 0x56, 0x48, 0x40, 0x3D, 0x3B, 0x3D, 0x42, 0x49, 0x63, 0xDA, 0xCB, 0xBC, 0xB6, 0xB0, 0xAE, +0xAF, 0xAF, 0xB4, 0xBC, 0xC6, 0xFE, 0x4C, 0x3E, 0x34, 0x30, 0x2E, 0x2D, 0x2E, 0x30, 0x35, 0x3C, +0x46, 0x62, 0xDE, 0xCA, 0xBE, 0xBD, 0xBB, 0xBA, 0xBD, 0xC3, 0xCB, 0xDC, 0x6B, 0x59, 0x51, 0x52, +0x60, 0xFF, 0xD5, 0xC4, 0xBE, 0xBC, 0xBA, 0xB9, 0xBB, 0xC3, 0xC8, 0xD6, 0x5A, 0x4C, 0x42, 0x39, +0x36, 0x35, 0x32, 0x34, 0x36, 0x39, 0x41, 0x47, 0x58, 0xE0, 0xDA, 0xC9, 0xC1, 0xC4, 0xC0, 0xC0, +0xC6, 0xCA, 0xD1, 0xDC, 0xF3, 0x6E, 0xFC, 0xE8, 0xDB, 0xCB, 0xC2, 0xBE, 0xBD, 0xBE, 0xBD, 0xC0, +0xCD, 0xCE, 0xEC, 0x4E, 0x4C, 0x40, 0x38, 0x39, 0x37, 0x35, 0x38, 0x38, 0x3B, 0x43, 0x49, 0x54, +0xEA, 0xDB, 0xCE, 0xC5, 0xC5, 0xC3, 0xC1, 0xC7, 0xCA, 0xCF, 0xDB, 0xE9, 0xFD, 0xF7, 0xE9, 0xDD, +0xCE, 0xC6, 0xC1, 0xBF, 0xC0, 0xBF, 0xC3, 0xCF, 0xD0, 0xE6, 0x51, 0x4E, 0x43, 0x3A, 0x3B, 0x38, +0x35, 0x38, 0x38, 0x3A, 0x3F, 0x44, 0x4E, 0x5F, 0xEF, 0xD7, 0xCD, 0xC8, 0xC6, 0xC4, 0xC6, 0xC9, +0xCC, 0xD4, 0xDD, 0xE6, 0xE1, 0xDA, 0xD7, 0xCA, 0xC3, 0xC4, 0xC4, 0xC1, 0xC3, 0xCC, 0xCF, 0xD8, +0x60, 0x54, 0x4E, 0x3F, 0x3D, 0x3D, 0x39, 0x3A, 0x3C, 0x3B, 0x3D, 0x47, 0x48, 0x51, 0x79, 0xFA, +0xDD, 0xCD, 0xCF, 0xCC, 0xC8, 0xCD, 0xCE, 0xCE, 0xD7, 0xDC, 0xDC, 0xD7, 0xD4, 0xCC, 0xC3, 0xC1, +0xBF, 0xBF, 0xC2, 0xC1, 0xCE, 0xDB, 0xDD, 0x54, 0x4C, 0x49, 0x3C, 0x3B, 0x3B, 0x38, 0x3A, 0x3B, +0x3C, 0x3E, 0x48, 0x4C, 0x55, 0xF3, 0xEC, 0xDB, 0xCD, 0xD1, 0xCD, 0xCB, 0xD2, 0xD1, 0xD6, 0xDD, +0xE1, 0xE2, 0xD7, 0xD3, 0xCA, 0xC0, 0xBE, 0xBE, 0xBF, 0xBE, 0xC1, 0xCF, 0xD0, 0xED, 0x4E, 0x4D, +0x41, 0x3A, 0x3A, 0x37, 0x35, 0x38, 0x3A, 0x3A, 0x3F, 0x49, 0x4A, 0x62, 0xE7, 0xEA, 0xCE, 0xCB, +0xCF, 0xC8, 0xCB, 0xD1, 0xCF, 0xD7, 0xE2, 0xE5, 0xE5, 0xDF, 0xD5, 0xCC, 0xC5, 0xBE, 0xBE, 0xC0, +0xBC, 0xC0, 0xCD, 0xC8, 0xDC, 0x58, 0x5B, 0x47, 0x3C, 0x3D, 0x39, 0x36, 0x39, 0x3A, 0x39, 0x3E, +0x47, 0x49, 0x59, 0xEA, 0xEC, 0xD0, 0xC9, 0xCD, 0xC7, 0xC8, 0xCE, 0xCD, 0xD2, 0xDC, 0xDF, 0xDF, +0xDD, 0xD6, 0xCB, 0xC6, 0xBF, 0xBF, 0xC4, 0xBD, 0xC4, 0xD1, 0xC9, 0xEF, 0x55, 0x5D, 0x43, 0x3D, +0x3E, 0x38, 0x37, 0x3A, 0x3A, 0x3A, 0x3E, 0x45, 0x48, 0x56, 0x74, 0xF8, 0xD8, 0xCF, 0xD0, 0xCB, +0xCB, 0xCE, 0xCE, 0xD2, 0xD9, 0xDC, 0xDC, 0xD7, 0xD3, 0xCA, 0xC4, 0xC0, 0xBF, 0xC2, 0xBE, 0xC3, +0xCF, 0xCB, 0xE5, 0x58, 0x5C, 0x45, 0x3D, 0x3E, 0x39, 0x37, 0x39, 0x3A, 0x3A, 0x3D, 0x45, 0x46, +0x52, 0x79, 0x73, 0xD7, 0xCD, 0xD1, 0xC8, 0xC8, 0xCD, 0xCA, 0xCF, 0xD5, 0xD7, 0xDC, 0xDA, 0xD4, +0xCD, 0xC7, 0xC1, 0xC0, 0xC5, 0xBF, 0xC2, 0xD1, 0xCA, 0xDA, 0x5A, 0x68, 0x4C, 0x3E, 0x42, 0x3B, +0x38, 0x3B, 0x3A, 0x3A, 0x3D, 0x42, 0x44, 0x4B, 0x62, 0x66, 0xF1, 0xD0, 0xD6, 0xCD, 0xC8, 0xCE, +0xCA, 0xCB, 0xD1, 0xCF, 0xD2, 0xD2, 0xCE, 0xC9, 0xC5, 0xC1, 0xBF, 0xC5, 0xC1, 0xC0, 0xD3, 0xCE, +0xD6, 0x57, 0x5F, 0x4E, 0x3E, 0x41, 0x3D, 0x39, 0x3B, 0x3B, 0x3A, 0x3D, 0x42, 0x44, 0x4C, 0x5A, +0x5E, 0xEC, 0xDD, 0xDC, 0xCE, 0xD0, 0xD1, 0xCD, 0xD4, 0xD4, 0xD4, 0xDA, 0xD3, 0xCE, 0xCB, 0xC4, +0xBF, 0xBE, 0xC2, 0xBE, 0xBF, 0xCD, 0xCB, 0xD5, 0x5B, 0x5F, 0x4D, 0x3E, 0x3F, 0x3B, 0x37, 0x39, +0x3A, 0x39, 0x3C, 0x3F, 0x42, 0x4B, 0x59, 0x61, 0xEA, 0xDA, 0xD6, 0xCD, 0xCD, 0xCE, 0xCD, 0xCF, +0xD3, 0xD6, 0xDA, 0xD7, 0xD2, 0xCE, 0xC7, 0xC2, 0xBF, 0xC0, 0xC1, 0xBE, 0xC8, 0xCE, 0xCB, 0x79, +0x5A, 0x5C, 0x41, 0x3F, 0x3E, 0x38, 0x39, 0x3A, 0x39, 0x3A, 0x3E, 0x42, 0x45, 0x51, 0x62, 0x65, +0xDD, 0xD5, 0xD7, 0xCA, 0xCC, 0xCE, 0xCA, 0xCE, 0xD0, 0xCF, 0xCF, 0xCD, 0xC9, 0xC4, 0xBF, 0xBD, +0xBE, 0xBF, 0xBD, 0xC5, 0xCE, 0xCB, 0xF8, 0x58, 0x5B, 0x43, 0x3E, 0x3E, 0x39, 0x38, 0x3A, 0x39, +0x3A, 0x3E, 0x44, 0x45, 0x51, 0x6E, 0x69, 0xDC, 0xCF, 0xD7, 0xCA, 0xCB, 0xD0, 0xCC, 0xD1, 0xD5, +0xD5, 0xD5, 0xCF, 0xCB, 0xC5, 0xBF, 0xBC, 0xBD, 0xBF, 0xBB, 0xC3, 0xCC, 0xC8, 0xEF, 0x5B, 0x5D, +0x41, 0x3D, 0x3D, 0x37, 0x37, 0x38, 0x37, 0x38, 0x3B, 0x41, 0x43, 0x4E, 0x6B, 0x67, 0xDC, 0xCE, +0xD4, 0xC9, 0xC8, 0xCE, 0xCA, 0xCE, 0xD5, 0xD4, 0xD5, 0xD3, 0xCE, 0xC7, 0xC3, 0xBE, 0xBE, 0xC3, +0xBD, 0xC2, 0xD0, 0xC9, 0xDE, 0x57, 0x61, 0x47, 0x3D, 0x3F, 0x39, 0x36, 0x38, 0x38, 0x38, 0x3A, +0x41, 0x40, 0x48, 0x6A, 0x5C, 0xF7, 0xCD, 0xDB, 0xCD, 0xC6, 0xD1, 0xCC, 0xCC, 0xD6, 0xD5, 0xD3, +0xCF, 0xCE, 0xC6, 0xC0, 0xBF, 0xBE, 0xBF, 0xBE, 0xC0, 0xCC, 0xCB, 0xDB, 0x5D, 0x5B, 0x49, 0x3E, +0x3E, 0x39, 0x37, 0x38, 0x38, 0x38, 0x3B, 0x40, 0x42, 0x4A, 0x63, 0x66, 0xE5, 0xCE, 0xD0, 0xCA, +0xC7, 0xCA, 0xCA, 0xCC, 0xCE, 0xD1, 0xCF, 0xCC, 0xCC, 0xC4, 0xBF, 0xBF, 0xBE, 0xC0, 0xBE, 0xC2, +0xCE, 0xCC, 0xE2, 0x58, 0x59, 0x47, 0x3D, 0x3D, 0x39, 0x37, 0x39, 0x39, 0x39, 0x3C, 0x40, 0x44, +0x4D, 0x5D, 0x6F, 0xE0, 0xD4, 0xCF, 0xCC, 0xCB, 0xCB, 0xCD, 0xCF, 0xCF, 0xD4, 0xD1, 0xCC, 0xCA, +0xC4, 0xBF, 0xBD, 0xBF, 0xBF, 0xBE, 0xC7, 0xCF, 0xCE, 0x79, 0x52, 0x51, 0x41, 0x3C, 0x3B, 0x38, +0x36, 0x38, 0x39, 0x38, 0x3D, 0x44, 0x44, 0x55, 0x70, 0x76, 0xD5, 0xCF, 0xCF, 0xC9, 0xCB, 0xCB, +0xCD, 0xD1, 0xD1, 0xD9, 0xD2, 0xCD, 0xCD, 0xC4, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xC9, 0xCF, 0xD0, +0x6A, 0x53, 0x4F, 0x3F, 0x3C, 0x3B, 0x38, 0x37, 0x38, 0x39, 0x3A, 0x3E, 0x44, 0x4A, 0x56, 0x75, +0xE7, 0xD7, 0xCD, 0xCB, 0xCA, 0xC9, 0xCA, 0xCD, 0xCE, 0xCF, 0xD3, 0xCE, 0xCA, 0xC7, 0xC0, 0xBE, +0xBE, 0xBF, 0xBF, 0xC1, 0xCD, 0xD2, 0xDB, 0x5C, 0x4F, 0x4A, 0x3E, 0x3C, 0x3B, 0x39, 0x38, 0x3A, +0x3A, 0x3C, 0x43, 0x46, 0x4E, 0x71, 0x7A, 0xDD, 0xCE, 0xD0, 0xCB, 0xCA, 0xCD, 0xCC, 0xD1, 0xD2, +0xD5, 0xD7, 0xCC, 0xCC, 0xC7, 0xBE, 0xBF, 0xBF, 0xBE, 0xC0, 0xC6, 0xCD, 0xD5, 0xEE, 0x54, 0x4D, +0x45, 0x3C, 0x3B, 0x39, 0x37, 0x38, 0x39, 0x3A, 0x3E, 0x44, 0x4A, 0x59, 0x71, 0xE8, 0xD4, 0xCE, +0xCC, 0xC9, 0xCB, 0xCB, 0xCE, 0xD2, 0xD4, 0xD7, 0xD2, 0xCD, 0xCB, 0xC4, 0xBF, 0xBF, 0xC0, 0xC0, +0xC0, 0xC9, 0xD1, 0xD8, 0x73, 0x52, 0x4B, 0x42, 0x3C, 0x3A, 0x39, 0x38, 0x38, 0x39, 0x3C, 0x3F, +0x41, 0x4E, 0x5D, 0x63, 0xDF, 0xD3, 0xD1, 0xCD, 0xCB, 0xCC, 0xD1, 0xD1, 0xD3, 0xDE, 0xDA, 0xD1, +0xCF, 0xCC, 0xC4, 0xBF, 0xC2, 0xC2, 0xBF, 0xC6, 0xCD, 0xD2, 0xE3, 0x63, 0x4F, 0x4A, 0x42, 0x3C, +0x3B, 0x3A, 0x39, 0x3A, 0x3B, 0x3F, 0x42, 0x47, 0x5A, 0x62, 0x7C, 0xD5, 0xD2, 0xCF, 0xCC, 0xCD, +0xCE, 0xD5, 0xD6, 0xD9, 0xE0, 0xD9, 0xD2, 0xCE, 0xCB, 0xC4, 0xBF, 0xC2, 0xC2, 0xBF, 0xC6, 0xCD, +0xD4, 0xE2, 0x67, 0x4F, 0x4B, 0x43, 0x3D, 0x3C, 0x3B, 0x3B, 0x3B, 0x3C, 0x42, 0x43, 0x49, 0x60, +0x6B, 0xF5, 0xD4, 0xD2, 0xD0, 0xD2, 0xD2, 0xD4, 0xDF, 0xDD, 0xDF, 0xEA, 0xDC, 0xD5, 0xD0, 0xCB, +0xC4, 0xC0, 0xC2, 0xBF, 0xC0, 0xC7, 0xC9, 0xD0, 0xDD, 0x7A, 0x57, 0x52, 0x48, 0x3F, 0x3F, 0x3D, +0x3C, 0x3C, 0x3D, 0x42, 0x44, 0x49, 0x5B, 0x64, 0x7C, 0xDE, 0xDB, 0xDB, 0xDC, 0xDA, 0xDF, 0xEE, +0xE9, 0xE6, 0xE8, 0xE3, 0xDB, 0xD0, 0xCD, 0xCC, 0xC5, 0xC3, 0xC5, 0xC2, 0xC3, 0xC8, 0xCD, 0xD1, +0xDE, 0x6F, 0x5B, 0x50, 0x4A, 0x44, 0x40, 0x3F, 0x3E, 0x3E, 0x42, 0x43, 0x47, 0x4F, 0x58, 0x5F, +0x69, 0xF6, 0xED, 0xF7, 0xEB, 0xE8, 0xEA, 0xEC, 0xE8, 0xE0, 0xE0, 0xDD, 0xD7, 0xD0, 0xCE, 0xCC, +0xC8, 0xC7, 0xC6, 0xC4, 0xC8, 0xC9, 0xCB, 0xD2, 0xDA, 0xEF, 0x71, 0x5B, 0x4F, 0x4E, 0x49, 0x45, +0x46, 0x45, 0x47, 0x47, 0x4A, 0x4E, 0x4E, 0x54, 0x5A, 0x5D, 0x62, 0x65, 0x70, 0x6C, 0x69, 0xFA, +0x7A, 0x7A, 0xE6, 0xE2, 0xDF, 0xDA, 0xD5, 0xCF, 0xD1, 0xD1, 0xCB, 0xCE, 0xD4, 0xCE, 0xD1, 0xD9, +0xDB, 0xE0, 0xE1, 0xEE, 0x6A, 0x74, 0x6C, 0x5A, 0x5B, 0x5A, 0x56, 0x56, 0x53, 0x56, 0x57, 0x53, +0x57, 0x5B, 0x59, 0x59, 0x5D, 0x65, 0x60, 0x61, 0x6F, 0x73, 0xF7, 0xEF, 0xEA, 0xDD, 0xDF, 0xDC, +0xD5, 0xD8, 0xDC, 0xDC, 0xDA, 0xDF, 0xE5, 0xE1, 0xEB, 0xED, 0xED, 0xFC, 0xFF, 0x70, 0x6C, 0x6C, +0x66, 0x5F, 0x5F, 0x62, 0x5F, 0x60, 0x60, 0x5A, 0x5F, 0x64, 0x5C, 0x64, 0x6E, 0x5F, 0x5E, 0x69, +0x6B, 0x7B, 0xF0, 0xFA, 0xE9, 0xE4, 0xE8, 0xDF, 0xE6, 0xEB, 0xE1, 0xE2, 0xE6, 0xE3, 0xE8, 0xED, +0xE5, 0xFC, 0x71, 0xE9, 0xFE, 0x7A, 0xEC, 0x73, 0x7E, 0x77, 0x64, 0xFD, 0x74, 0x66, 0x7B, 0x6C, +0x6B, 0x72, 0x6A, 0x79, 0x73, 0x71, 0xF4, 0x79, 0xFC, 0xEF, 0xF9, 0xEB, 0xF1, 0xF0, 0xE2, 0xE3, +0xE0, 0xE2, 0xE3, 0xEB, 0xFC, 0xEA, 0xF8, 0x6F, 0x70, 0x69, 0x77, 0x6C, 0x6D, 0xEF, 0x6B, 0x67, +0x6D, 0x65, 0x76, 0x75, 0x6F, 0x7E, 0x69, 0x67, 0x6F, 0x68, 0x6F, 0x73, 0x68, 0x69, 0x68, 0x69, +0x75, 0xFA, 0xEE, 0xF2, 0xEA, 0xDE, 0xE2, 0xE7, 0xE5, 0xEB, 0xF3, 0xED, 0xE8, 0xF7, 0x7F, 0xFA, +0x74, 0x6A, 0x68, 0x65, 0x66, 0x68, 0x64, 0x65, 0x68, 0x64, 0x6D, 0x77, 0x72, 0x70, 0x69, 0x77, +0x78, 0x64, 0x6B, 0x68, 0x60, 0x66, 0x67, 0x67, 0x61, 0x6D, 0xEB, 0xE8, 0xEC, 0xEB, 0xEA, 0xF7, +0xF5, 0xE2, 0xE5, 0xF6, 0xF8, 0xF0, 0x7E, 0x77, 0xFA, 0x76, 0x77, 0x7D, 0x6E, 0x74, 0x74, 0x72, +0x72, 0x6D, 0x75, 0x74, 0x74, 0x75, 0x76, 0xEF, 0xEE, 0xEF, 0xEA, 0xFA, 0x7F, 0xF2, 0xF6, 0xF7, +0xEF, 0xEA, 0xE4, 0xE5, 0xE7, 0xE3, 0xE9, 0xEC, 0xE8, 0xEB, 0xF0, 0xF8, 0xFC, 0x7F, 0x73, 0x73, +0x70, 0x72, 0x75, 0x69, 0x67, 0x6A, 0x6C, 0x6D, 0x6C, 0x70, 0x6D, 0x6D, 0x78, 0x72, 0x6F, 0x6E, +0x6C, 0x6F, 0x77, 0xF7, 0xEF, 0xF1, 0xF6, 0xF4, 0xF1, 0xFC, 0xF8, 0xEE, 0xF0, 0xEE, 0xEF, 0xEF, +0xEC, 0xEE, 0xF3, 0xF4, 0x76, 0x69, 0x77, 0xFA, 0x70, 0x75, 0x7E, 0x6E, 0x6D, 0x6E, 0x6E, 0x6E, +0x6D, 0x70, 0x74, 0x79, 0xFE, 0x7D, 0x78, 0x7C, 0x7A, 0x75, 0x78, 0x75, 0x70, 0x7C, 0xFC, 0xFB, +0xF4, 0xF3, 0xED, 0xEC, 0xF6, 0xF1, 0xEF, 0xF6, 0xF0, 0xFB, 0x7A, 0x7C, 0x74, 0x79, 0x74, 0x6C, +0x6C, 0x63, 0x67, 0x6C, 0x62, 0x66, 0x67, 0x68, 0x6C, 0x6A, 0x7D, 0x78, 0x6B, 0x7B, 0x71, 0x75, +0xFB, 0x75, 0x76, 0x7E, 0xEE, 0xED, 0xFA, 0xE8, 0xEE, 0x7F, 0xE4, 0xE9, 0xED, 0xE1, 0xEC, 0xEE, +0xE6, 0xF6, 0xFE, 0xF7, 0xFF, 0x7B, 0x72, 0x7C, 0x7F, 0x6B, 0x6C, 0x66, 0x67, 0x71, 0x66, 0x72, +0xFF, 0x69, 0x7B, 0xF7, 0xFF, 0xF3, 0xF6, 0xF3, 0xF2, 0xEE, 0xED, 0xFF, 0xF6, 0xED, 0xFB, 0xF2, +0xE9, 0xF0, 0xEC, 0xE6, 0xF4, 0xF2, 0xF5, 0x7C, 0xED, 0x7E, 0x6B, 0x7B, 0x77, 0xFE, 0x7A, 0x69, +0x68, 0x60, 0x65, 0x66, 0x61, 0x71, 0x74, 0x74, 0xFC, 0x7E, 0xFA, 0xFF, 0x7E, 0xF9, 0xFB, 0xEE, +0xED, 0xEF, 0xEF, 0xF4, 0xEC, 0xEC, 0xF2, 0xF0, 0xEF, 0xED, 0xF4, 0xF6, 0xEF, 0xFD, 0xF8, 0xF1, +0x77, 0x74, 0x7A, 0x70, 0x6F, 0x79, 0x76, 0x6A, 0x68, 0x6C, 0x6C, 0x69, 0x65, 0x66, 0x6E, 0x73, +0x6C, 0x6D, 0x7A, 0x79, 0x7A, 0xFE, 0x73, 0x72, 0x7A, 0x7E, 0xF3, 0xEF, 0xEE, 0xF1, 0xF6, 0xEC, +0xEF, 0xFA, 0xEE, 0xF5, 0xFE, 0xF2, 0xF0, 0xF7, 0xFA, 0xF9, 0xFB, 0xFB, 0x7A, 0x6B, 0x6B, 0x72, +0x6C, 0x6A, 0x76, 0x74, 0x6E, 0x72, 0x6C, 0x6B, 0x6F, 0x6B, 0x6E, 0x71, 0x6D, 0x75, 0x76, 0x70, +0x78, 0x7C, 0xFA, 0xF2, 0xF7, 0xF1, 0xED, 0xF3, 0xF4, 0xF6, 0xFA, 0xF0, 0xEF, 0xFD, 0x7B, 0xFF, +0x78, 0x6C, 0x70, 0x72, 0x6E, 0x73, 0x6D, 0x6D, 0x6D, 0x65, 0x65, 0x69, 0x6F, 0x70, 0x6B, 0x6E, +0x71, 0x6E, 0x6E, 0x6F, 0x7A, 0x7D, 0x7E, 0xEF, 0xF4, 0x7D, 0xFB, 0xF3, 0xEC, 0xEB, 0xF0, 0xEF, +0xEE, 0xEE, 0xF3, 0xF0, 0xED, 0xFF, 0xFF, 0xF3, 0x7E, 0xFB, 0xFF, 0x73, 0x7E, 0x7A, 0x76, 0x6F, +0x6C, 0x7A, 0x74, 0x6F, 0xFF, 0x7B, 0x79, 0xF7, 0xF5, 0xFB, 0xF6, 0xF3, 0x7E, 0x7D, 0xFA, 0xFD, +0xF6, 0xF5, 0x7D, 0x7B, 0x7A, 0xFF, 0xFB, 0x7D, 0x75, 0x76, 0xF3, 0xF3, 0x78, 0xFE, 0x76, 0x6B, +0x7B, 0xFB, 0x75, 0x69, 0x6C, 0xF6, 0xF6, 0x7B, 0x6F, 0x69, 0x6E, 0x72, 0x70, 0x74, 0x78, 0xFF, +0x7F, 0xFD, 0xF5, 0xF8, 0xF5, 0xF9, 0x75, 0x74, 0x7D, 0xF7, 0xFB, 0x70, 0x7E, 0xE9, 0xEF, 0xF7, +0xE6, 0xED, 0x74, 0x7A, 0xF7, 0x7D, 0x71, 0x77, 0xFE, 0xF6, 0xFC, 0x6B, 0x6B, 0x72, 0x69, 0x6D, +0x7B, 0x7C, 0xFD, 0x6F, 0x6B, 0xFC, 0x7F, 0x73, 0xF9, 0xF5, 0x70, 0x6E, 0xFD, 0xFF, 0x7C, 0xFB, +0x70, 0x76, 0xEF, 0x7D, 0x75, 0xFB, 0xF6, 0xEF, 0xF6, 0x7C, 0x79, 0x76, 0xFE, 0x7D, 0x73, 0xFD, +0xFE, 0x76, 0x6E, 0x66, 0x6B, 0x75, 0x6D, 0x7D, 0xF2, 0x6D, 0x75, 0xED, 0x7A, 0x6D, 0x7E, 0xF9, +0xFE, 0x6E, 0x78, 0xF4, 0x6E, 0x73, 0xF8, 0x74, 0xFF, 0xFE, 0x77, 0xF6, 0x7C, 0x71, 0x7F, 0x7E, +0x7E, 0x79, 0x78, 0x7C, 0x6E, 0x6F, 0x70, 0x6D, 0xFD, 0xFA, 0x6C, 0x6B, 0x71, 0x70, 0x7B, 0x7A, +0x7C, 0xFD, 0x6D, 0x75, 0xED, 0xF8, 0xFC, 0xF7, 0xFB, 0xEE, 0xEF, 0x79, 0xFF, 0xED, 0xF8, 0x7A, +0xF1, 0xED, 0xF7, 0xFC, 0xF8, 0xF1, 0xF8, 0x79, 0x7D, 0xF6, 0x78, 0x6E, 0xFD, 0xFB, 0x72, 0x6E, +0x6C, 0x74, 0xFE, 0xFF, 0xF7, 0xFE, 0x6D, 0x75, 0x79, 0x6F, 0x7C, 0x7D, 0x76, 0x78, 0x7A, 0x7F, +0x75, 0x7D, 0xF7, 0xF8, 0xEF, 0x7B, 0x7A, 0xF3, 0xFF, 0xEF, 0xF8, 0xFE, 0xF6, 0x6E, 0xF4, 0xED, +0x6F, 0x7C, 0x74, 0x75, 0xF2, 0x7C, 0x75, 0xF9, 0xEE, 0xFF, 0x70, 0x7C, 0x7F, 0xFD, 0xFD, 0xFA, +0x79, 0x6C, 0x7C, 0x7F, 0xFD, 0xF3, 0x78, 0xFE, 0xF7, 0xFC, 0xED, 0xF1, 0xFD, 0xFE, 0x7D, 0xF4, +0xED, 0xF4, 0xFA, 0xFD, 0x70, 0x73, 0xF6, 0xFF, 0x7D, 0xF7, 0x79, 0x72, 0x78, 0x7D, 0x77, 0x6E, +0x71, 0x6C, 0x6A, 0x7D, 0x74, 0x71, 0x7D, 0x6E, 0x79, 0xF8, 0x70, 0x7C, 0xFE, 0x6D, 0x6F, 0x6E, +0x6D, 0x7D, 0xFD, 0xFB, 0xFA, 0x7C, 0xFD, 0xFA, 0xF7, 0xF4, 0xFD, 0x7B, 0x76, 0x7D, 0xF3, 0xF5, +0xFD, 0xF5, 0xED, 0x7A, 0x6D, 0xF5, 0x7C, 0x76, 0xEF, 0x77, 0x6E, 0xFF, 0x74, 0x79, 0xFD, 0x76, +0x7A, 0x7E, 0x7B, 0x7D, 0x78, 0x73, 0x7A, 0xFB, 0xFB, 0x7E, 0xFB, 0xF2, 0xF8, 0xF9, 0xFB, 0xFE, +0xF5, 0xF6, 0xF9, 0x7E, 0x73, 0xF7, 0xFA, 0x74, 0xFC, 0x7B, 0x70, 0xFF, 0xFC, 0x7E, 0x7C, 0xFE, +0xFF, 0x7C, 0xFC, 0x7E, 0x79, 0xFF, 0x7C, 0x79, 0x79, 0x79, 0x7A, 0x79, 0x7A, 0x7C, 0x7A, 0x75, +0x72, 0x7C, 0xFC, 0xFE, 0xFE, 0xFC, 0xF9, 0xFE, 0xFE, 0xFA, 0x7C, 0xFD, 0xFC, 0x77, 0x7B, 0x7A, +0x73, 0x78, 0x7A, 0x78, 0x7B, 0x77, 0x6E, 0x70, 0x7B, 0x7A, 0x72, 0x74, 0x76, 0x75, 0x77, 0x75, +0x70, 0x6F, 0x6F, 0x6F, 0x74, 0x77, 0x72, 0x6F, 0x70, 0x79, 0x79, 0x6F, 0x7E, 0xFA, 0x72, 0x79, +0x79, 0x78, 0xFE, 0x78, 0xFF, 0xFE, 0x76, 0xFF, 0xFF, 0x7D, 0xFF, 0x7E, 0x7B, 0x78, 0x7C, 0x75, +0x75, 0xFF, 0xFF, 0xF8, 0xF6, 0xFD, 0xF5, 0xF4, 0xF6, 0xFC, 0x7C, 0x7C, 0x7B, 0xFC, 0xFD, 0xFD, +0xFD, 0x77, 0x7A, 0x7F, 0x7E, 0xFC, 0xFA, 0xF7, 0xFF, 0xFE, 0xF1, 0xFD, 0xFD, 0xF0, 0xF9, 0xF8, +0xEE, 0xEF, 0xF8, 0x7E, 0x79, 0x77, 0x6C, 0x66, 0x6A, 0x68, 0x67, 0x71, 0x74, 0x77, 0x7E, 0x7B, +0xFD, 0xFD, 0x7F, 0xFF, 0x79, 0xFE, 0xFE, 0x75, 0x78, 0x7A, 0x74, 0x70, 0x76, 0x77, 0x75, 0x7C, +0x7C, 0x79, 0x78, 0x77, 0x78, 0x7C, 0x7E, 0x77, 0x74, 0x79, 0x77, 0x78, 0x78, 0x77, 0x7B, 0x78, +0x77, 0x77, 0x7A, 0xFE, 0x7D, 0xFE, 0xF6, 0xFB, 0xFC, 0xF8, 0xF6, 0xFA, 0xFD, 0xFB, 0xFC, 0x7D, +0x7B, 0xFB, 0xF5, 0xFC, 0xFF, 0xFD, 0xFE, 0xFF, 0x7F, 0xFC, 0xF8, 0xFF, 0x7F, 0xF7, 0xF9, 0xFA, +0xF9, 0xFB, 0xFA, 0xFA, 0xFA, 0xF8, 0xF8, 0xFD, 0x7E, 0xF8, 0xF7, 0xEF, 0xE0, 0xE1, 0xF7, 0x6E, +0x69, 0x65, 0x5C, 0x5B, 0x61, 0x69, 0x6E, 0x76, 0xF8, 0xEF, 0xF2, 0xEB, 0xE3, 0xDE, 0xE2, 0xFA, +0x66, 0x5B, 0x5F, 0x6E, 0x6E, 0xFB, 0xED, 0xED, 0xEC, 0xF8, 0x7E, 0x7B, 0x6E, 0x67, 0x60, 0x65, +0x6E, 0x6F, 0x78, 0xFB, 0x7E, 0x7D, 0xFA, 0xF9, 0xF7, 0xF5, 0xF7, 0xEE, 0xEB, 0xF3, 0xFA, 0x7A, +0x6D, 0x69, 0x6A, 0x69, 0x64, 0x69, 0x6E, 0x6F, 0x78, 0xFB, 0xFB, 0x7C, 0xF8, 0xF1, 0xFB, 0xF4, +0xF9, 0x7D, 0xF8, 0x7D, 0xFD, 0xF3, 0x7C, 0xFD, 0xF4, 0x7A, 0x6F, 0x79, 0xFF, 0x75, 0x78, 0xFA, +0xFB, 0xFE, 0xFB, 0xF9, 0xFE, 0xFF, 0xFF, 0xFC, 0xF5, 0xFD, 0x79, 0xFF, 0xF9, 0xFA, 0xFF, 0xFF, +0x7B, 0x74, 0x75, 0x6F, 0x71, 0x7D, 0x74, 0x75, 0x79, 0x71, 0x77, 0x7E, 0x7E, 0x7C, 0x74, 0x71, +0x77, 0x7A, 0x7F, 0xFB, 0x72, 0x69, 0x74, 0x74, 0x6A, 0x74, 0x7E, 0x79, 0x76, 0x74, 0x7F, 0x7C, +0x76, 0xF8, 0xF8, 0x7E, 0x7D, 0x7E, 0xFE, 0x77, 0x7B, 0xF8, 0x7B, 0xFF, 0xF3, 0xFC, 0xFF, 0xFE, +0xFD, 0xF5, 0xF6, 0xF3, 0xF2, 0xFA, 0xF8, 0xF3, 0xFB, 0x7E, 0xFA, 0xFA, 0x7E, 0xFE, 0xFC, 0x7C, +0x78, 0x7D, 0xFB, 0xF3, 0xFD, 0x74, 0xF7, 0xF5, 0x76, 0xF9, 0xF8, 0xFF, 0xF5, 0x76, 0x7B, 0xFA, +0x77, 0xFD, 0x7C, 0x77, 0x7D, 0x6F, 0x7D, 0xF7, 0xFC, 0xFD, 0x7B, 0xF5, 0xF8, 0x7A, 0xF4, 0xFB, +0x77, 0x7B, 0x76, 0x74, 0x7D, 0x7E, 0x72, 0x71, 0x70, 0x70, 0x77, 0x70, 0x7B, 0xFD, 0x6F, 0x72, +0x7D, 0x7A, 0x71, 0x79, 0xF8, 0x77, 0x6F, 0x74, 0x7A, 0x78, 0x7C, 0xF6, 0x7C, 0xFB, 0x7D, 0x6C, +0xEF, 0xFC, 0x6D, 0xF1, 0xF5, 0x7D, 0x79, 0xFA, 0xF5, 0x75, 0xF4, 0x7C, 0xFC, 0xE6, 0x68, 0x78, +0xE4, 0x6E, 0x77, 0xF2, 0x7E, 0x70, 0x69, 0xF9, 0xF7, 0x6C, 0x74, 0xF3, 0xEE, 0x79, 0x7E, 0xFB, +0x7A, 0xF6, 0x6C, 0x6B, 0xED, 0x77, 0x6A, 0x70, 0x6F, 0xFC, 0x7E, 0x79, 0xF2, 0xEE, 0xF8, 0x7D, +0xEF, 0xEB, 0x7E, 0x72, 0x7D, 0x74, 0x6B, 0xFA, 0xE5, 0xE7, 0xE4, 0xEB, 0xF8, 0xEC, 0xEA, 0xF3, +0xFB, 0xFA, 0xEF, 0xF6, 0x7C, 0xFF, 0x7B, 0x72, 0x78, 0x7C, 0x6F, 0x6E, 0xFF, 0xFF, 0x75, 0x74, +0x74, 0x76, 0x6C, 0x6A, 0x7F, 0x78, 0x6D, 0x74, 0x6E, 0x76, 0x7B, 0x69, 0x6B, 0x79, 0x72, 0x6A, +0x6D, 0x77, 0xFD, 0xFC, 0x6F, 0x7C, 0xEE, 0x76, 0x69, 0x74, 0xFB, 0x74, 0x6A, 0x7D, 0xF0, 0xFF, +0x6B, 0x71, 0xEF, 0x7D, 0x74, 0xF8, 0x75, 0x74, 0x77, 0x6C, 0x6E, 0x71, 0x73, 0x72, 0x70, 0xF4, +0xF0, 0x79, 0x7B, 0xFB, 0xF3, 0xF4, 0x78, 0x79, 0xF7, 0xFC, 0x6E, 0x70, 0xF8, 0xF8, 0x79, 0x6D, +0x70, 0xFB, 0x6E, 0x64, 0x6B, 0x72, 0x6F, 0x65, 0x71, 0xFC, 0x71, 0x76, 0x6E, 0x71, 0xF9, 0xFF, +0xFD, 0x73, 0x7A, 0xFF, 0x66, 0x70, 0xFE, 0x79, 0xFD, 0x7D, 0xF1, 0xF6, 0x76, 0x79, 0x6D, 0x79, +0xFF, 0x72, 0x7F, 0xF8, 0xF0, 0xFF, 0x71, 0xEC, 0xE9, 0x7C, 0x7C, 0xF1, 0xF7, 0xF7, 0xF5, 0xFA, +0xF1, 0x7C, 0x70, 0x7D, 0xFB, 0xF4, 0x7C, 0x7D, 0xF6, 0xFD, 0xEF, 0xF6, 0xEE, 0xE1, 0xEE, 0xF4, +0xF3, 0xEE, 0xF4, 0x78, 0xEC, 0xF7, 0x72, 0x74, 0x6E, 0xF5, 0x6A, 0x7B, 0xDF, 0x69, 0x7F, 0xE7, +0x6F, 0x7C, 0x68, 0xF4, 0xEE, 0x5C, 0x72, 0x6B, 0x6D, 0xEC, 0x60, 0x7E, 0xEB, 0x66, 0x6D, 0x6A, +0x7A, 0xFF, 0x6A, 0x6E, 0x74, 0xED, 0x79, 0x6B, 0xED, 0xFA, 0xFC, 0x70, 0x65, 0xF6, 0x75, 0x67, +0x78, 0x78, 0xF4, 0xFF, 0x5F, 0xF9, 0xE3, 0x6D, 0xF1, 0x7A, 0x70, 0xDB, 0x6A, 0xF9, 0xDC, 0x66, +0xDB, 0xF8, 0x65, 0xD6, 0x6A, 0xF2, 0xE6, 0x5E, 0xE1, 0x76, 0x6F, 0xF5, 0x65, 0xEF, 0x5F, 0x66, +0x6F, 0x5A, 0xFB, 0x5E, 0x65, 0x7E, 0x60, 0xF2, 0x5D, 0x72, 0xE8, 0x5A, 0xEA, 0x6E, 0x62, 0xE4, +0x5E, 0x6F, 0x74, 0x67, 0xEA, 0x64, 0x77, 0xF3, 0x69, 0xF1, 0x6B, 0x6E, 0xEB, 0x74, 0x74, 0x74, +0xF6, 0xF5, 0x66, 0xF5, 0xF7, 0x6C, 0xE9, 0x70, 0x6F, 0xE4, 0x6E, 0xF0, 0xF4, 0x63, 0xE1, 0xFE, +0x6D, 0xE4, 0x6D, 0xF2, 0xEF, 0x6C, 0xE8, 0x7B, 0xFC, 0xED, 0x74, 0xEB, 0xFE, 0xFC, 0xEF, 0x6D, +0xEC, 0xFB, 0x71, 0xEB, 0x77, 0xF3, 0xF8, 0x6F, 0xE9, 0xFE, 0xFC, 0xEE, 0x6F, 0xEB, 0xED, 0x7A, +0xEE, 0xF4, 0xF3, 0xF8, 0xF1, 0xEE, 0x79, 0xF4, 0xF3, 0xFC, 0xF1, 0x7C, 0xF4, 0xF9, 0x76, 0xE8, +0xF8, 0x75, 0xE3, 0x7B, 0x6E, 0xE0, 0x75, 0x72, 0xE3, 0x6C, 0xF8, 0xE7, 0x6D, 0xEA, 0xF4, 0x75, +0xEA, 0x71, 0xFA, 0xED, 0x6A, 0xF2, 0xFB, 0x70, 0xEB, 0x6F, 0x71, 0xEE, 0x6C, 0xF6, 0xF2, 0x68, +0xF3, 0xF8, 0x6D, 0x7A, 0xFC, 0x75, 0x6D, 0xF3, 0x6E, 0x6E, 0xEE, 0x61, 0x7C, 0xFE, 0x60, 0xF2, +0x6D, 0x78, 0x7C, 0x63, 0xEB, 0x64, 0x71, 0xED, 0x5C, 0xEB, 0x6F, 0x69, 0xEA, 0x5D, 0xE7, 0xF8, +0x5E, 0xE6, 0x6F, 0xFA, 0x79, 0x72, 0xE8, 0x5E, 0xE9, 0xFB, 0x5F, 0xDE, 0x61, 0xFA, 0xE3, 0x5A, +0xE3, 0x79, 0x62, 0xDF, 0x64, 0x76, 0xE4, 0x63, 0xFE, 0xE9, 0x64, 0xF8, 0xE6, 0x5F, 0xF2, 0xE8, +0x62, 0xE7, 0xFB, 0x6A, 0xF0, 0x77, 0xF9, 0x77, 0xE9, 0x78, 0x59, 0xE3, 0x71, 0x6C, 0xDF, 0x5F, +0xEF, 0xE9, 0x5F, 0xFA, 0x76, 0xF9, 0x7D, 0x67, 0xEE, 0x7B, 0x6F, 0x7E, 0x6B, 0x6D, 0xF7, 0x6E, +0x6B, 0xF0, 0x63, 0xF0, 0x75, 0x57, 0xD4, 0x59, 0x57, 0xCD, 0x4F, 0xEE, 0xDE, 0x4B, 0xCF, 0x68, +0x5B, 0xD4, 0x50, 0xE0, 0xEF, 0x54, 0xD5, 0x57, 0x6A, 0xD3, 0x54, 0x79, 0xDF, 0x5E, 0xFC, 0xE6, +0x5F, 0x71, 0xE0, 0x64, 0x76, 0xFC, 0x5D, 0xEA, 0xF8, 0x58, 0x79, 0xDB, 0x68, 0x59, 0xDF, 0x76, +0x64, 0xDA, 0x63, 0x5A, 0xD9, 0xE0, 0x51, 0xF3, 0xD3, 0x4D, 0xDE, 0xCF, 0x3F, 0xDA, 0xC2, 0x41, +0x6A, 0xC3, 0x50, 0x55, 0xC6, 0x5A, 0x4B, 0xC2, 0x7A, 0x46, 0xCA, 0xDF, 0x4C, 0xD8, 0xDE, 0x4F, +0xE2, 0xD2, 0x4D, 0x6B, 0xCD, 0x5C, 0x56, 0xD8, 0xEB, 0x54, 0xEF, 0xDE, 0x4F, 0x78, 0xD7, 0x54, +0x5B, 0xDA, 0xFA, 0x56, 0xF6, 0xE9, 0x58, 0xF1, 0xE5, 0x59, 0x6D, 0xE8, 0x7B, 0x64, 0x7E, 0xE2, +0x60, 0x6D, 0xDC, 0x63, 0x67, 0xDC, 0x6F, 0x62, 0xE2, 0x7B, 0x60, 0xEC, 0xF3, 0x67, 0x77, 0xF1, +0x7C, 0x75, 0xF0, 0x79, 0x6F, 0xED, 0x76, 0x6B, 0xF3, 0xFF, 0x74, 0xF4, 0xF8, 0x6B, 0x6C, 0xE6, +0xE7, 0x61, 0x79, 0xDD, 0x6F, 0x77, 0xDE, 0x6D, 0x6E, 0xE4, 0x7E, 0xF9, 0xE8, 0x6D, 0x6F, 0xDE, +0xEF, 0x5C, 0xEF, 0xDB, 0x64, 0x6B, 0xDF, 0xF9, 0x6C, 0xF4, 0xF5, 0x72, 0xF5, 0xF7, 0x66, 0x7D, +0xE9, 0x7D, 0x70, 0x79, 0xF6, 0x7B, 0x6C, 0xF3, 0xF2, 0x6A, 0x76, 0xED, 0x79, 0x6B, 0xF2, 0xF1, +0x6B, 0x78, 0xEF, 0x73, 0x74, 0xED, 0x73, 0x6A, 0xEB, 0xF2, 0x64, 0x6F, 0xE2, 0xF8, 0x5E, 0xF3, +0xE8, 0x64, 0x74, 0xEF, 0x7B, 0x77, 0x74, 0x78, 0x6D, 0xF8, 0xEA, 0x63, 0x68, 0xEC, 0xEF, 0x6E, +0x63, 0xEE, 0xFA, 0x5F, 0xE5, 0xEB, 0x58, 0x73, 0xD1, 0xF3, 0x4D, 0xF2, 0xCD, 0x5D, 0x54, 0xDF, +0xDD, 0x61, 0x5B, 0xD9, 0xDF, 0x50, 0xF0, 0xD3, 0x5F, 0x5D, 0xE4, 0xDF, 0x6E, 0x5B, 0xED, 0xD8, +0x68, 0x56, 0xEA, 0xD3, 0x70, 0x52, 0xF0, 0xD3, 0x74, 0x57, 0xF5, 0xD8, 0x6A, 0x58, 0xE4, 0xE2, +0x5C, 0x7A, 0xD8, 0x77, 0x5A, 0xE8, 0xD9, 0x73, 0x5F, 0x7D, 0xE3, 0xEC, 0x73, 0x72, 0x6E, 0xF6, +0xDF, 0xF7, 0x62, 0x6B, 0xE5, 0xDD, 0x6B, 0x58, 0xF7, 0xDB, 0x73, 0x5E, 0x75, 0x7E, 0xF6, 0xFE, +0x66, 0x71, 0x7B, 0x7E, 0xEE, 0x6C, 0x6B, 0xEB, 0x76, 0x6C, 0xEA, 0x7A, 0x67, 0xE5, 0xE8, 0x5F, +0x75, 0xDE, 0xEE, 0x6F, 0x7A, 0xED, 0xE8, 0xF8, 0xFB, 0xF4, 0x78, 0xF1, 0xE4, 0x6E, 0x62, 0xEB, +0xEC, 0x65, 0x6D, 0x7E, 0x6B, 0x69, 0x6E, 0x72, 0x78, 0x68, 0x5E, 0x74, 0xE9, 0x6F, 0x5E, 0x72, +0xEB, 0x7A, 0x6F, 0xF1, 0x78, 0x75, 0xE5, 0xE6, 0xE2, 0xDD, 0xE0, 0xD6, 0xD1, 0xD5, 0xD1, 0xD3, +0xDE, 0xE0, 0xDD, 0xE9, 0x68, 0x57, 0x52, 0x50, 0x4B, 0x48, 0x48, 0x48, 0x48, 0x4B, 0x51, 0x56, +0x56, 0x5D, 0x68, 0x6A, 0x69, 0x7C, 0xE8, 0xED, 0xED, 0xDC, 0xD5, 0xCD, 0xCB, 0xCD, 0xC5, 0xBE, +0xBE, 0xBC, 0xBC, 0xBF, 0xC5, 0xD2, 0x72, 0x52, 0x48, 0x40, 0x3C, 0x39, 0x39, 0x3B, 0x3D, 0x40, +0x4A, 0x5A, 0x6C, 0x7E, 0xDF, 0xCF, 0xCE, 0xDB, 0x6F, 0x63, 0x6E, 0x60, 0x4D, 0x47, 0x4D, 0x5E, +0x7C, 0xFA, 0xE4, 0xCD, 0xC1, 0xBD, 0xBC, 0xBA, 0xB7, 0xB4, 0xB5, 0xBE, 0xD7, 0xEB, 0xF2, 0x4E, +0x3B, 0x36, 0x37, 0x39, 0x38, 0x39, 0x3D, 0x48, 0x58, 0xFE, 0xDA, 0xD6, 0xD8, 0xCF, 0xC8, 0xCD, +0xF3, 0x5A, 0x59, 0x58, 0x4E, 0x47, 0x48, 0x4F, 0x5F, 0xF2, 0xD9, 0xCE, 0xC6, 0xBF, 0xBB, 0xBA, +0xB9, 0xB7, 0xB5, 0xB7, 0xC0, 0xD9, 0x68, 0x57, 0x49, 0x3B, 0x35, 0x35, 0x38, 0x3A, 0x3B, 0x3F, +0x4B, 0x60, 0xE7, 0xD8, 0xD5, 0xD4, 0xCE, 0xCA, 0xCF, 0xF9, 0x59, 0x51, 0x4E, 0x4C, 0x48, 0x46, +0x49, 0x56, 0xFB, 0xD9, 0xD1, 0xC9, 0xBE, 0xB8, 0xB6, 0xB5, 0xB3, 0xB2, 0xB6, 0xC3, 0xE5, 0x60, +0x4E, 0x3F, 0x37, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x41, 0x4E, 0x6F, 0xDA, 0xD2, 0xD4, 0xD1, 0xCA, +0xC9, 0xD7, 0x6F, 0x59, 0x4D, 0x47, 0x47, 0x48, 0x45, 0x46, 0x52, 0xEE, 0xD7, 0xD0, 0xC7, 0xBC, +0xB5, 0xB3, 0xB3, 0xB1, 0xB0, 0xB7, 0xCA, 0x68, 0x4F, 0x45, 0x3B, 0x32, 0x2E, 0x30, 0x35, 0x39, +0x3D, 0x44, 0x52, 0xEC, 0xD0, 0xCF, 0xD3, 0xD0, 0xCD, 0xCF, 0xE3, 0x63, 0x5B, 0x59, 0x52, 0x4D, +0x4C, 0x4F, 0x5A, 0x6D, 0xE5, 0xD2, 0xC8, 0xBE, 0xB9, 0xB5, 0xB3, 0xB1, 0xAF, 0xB1, 0xBD, 0xE3, +0x53, 0x4B, 0x40, 0x35, 0x2E, 0x2F, 0x34, 0x39, 0x3B, 0x3F, 0x4C, 0x75, 0xDA, 0xD6, 0xD2, 0xCE, +0xCE, 0xD0, 0xD9, 0xEF, 0x62, 0x56, 0x55, 0x55, 0x4F, 0x4E, 0x52, 0x61, 0xEF, 0xDB, 0xCC, 0xBF, +0xB9, 0xB5, 0xB3, 0xB0, 0xAE, 0xB4, 0xC8, 0x63, 0x4D, 0x45, 0x39, 0x2E, 0x2C, 0x2F, 0x35, 0x38, +0x3B, 0x43, 0x5A, 0xDD, 0xCE, 0xCD, 0xCC, 0xCB, 0xCD, 0xD2, 0xDE, 0x76, 0x5A, 0x52, 0x53, 0x51, +0x4E, 0x4F, 0x5C, 0x7C, 0xE2, 0xD2, 0xC5, 0xBB, 0xB5, 0xB2, 0xB0, 0xAE, 0xAE, 0xB6, 0xCF, 0x55, +0x48, 0x3F, 0x34, 0x2C, 0x2C, 0x2F, 0x36, 0x39, 0x3D, 0x4A, 0x7D, 0xCE, 0xCA, 0xCB, 0xCB, 0xCB, +0xCD, 0xD9, 0x76, 0x59, 0x4F, 0x4C, 0x4C, 0x4A, 0x4C, 0x54, 0x68, 0xEC, 0xD8, 0xCB, 0xBF, 0xB8, +0xB3, 0xB0, 0xAE, 0xAD, 0xAE, 0xBC, 0xF5, 0x4C, 0x43, 0x39, 0x2E, 0x2A, 0x2D, 0x32, 0x37, 0x3B, +0x44, 0x5F, 0xD5, 0xC8, 0xC7, 0xC9, 0xCB, 0xCE, 0xD3, 0xE9, 0x5A, 0x4D, 0x4D, 0x4D, 0x4B, 0x4B, +0x50, 0x63, 0xF6, 0xDE, 0xCE, 0xC5, 0xBD, 0xB7, 0xB2, 0xB0, 0xAF, 0xAD, 0xAF, 0xBF, 0x5E, 0x45, +0x40, 0x37, 0x2C, 0x29, 0x2D, 0x34, 0x38, 0x3C, 0x48, 0x77, 0xCD, 0xC6, 0xC7, 0xCB, 0xCB, 0xCF, +0xE9, 0x59, 0x4E, 0x4B, 0x47, 0x44, 0x47, 0x4D, 0x57, 0x69, 0xEB, 0xD7, 0xCA, 0xBF, 0xB9, 0xB3, +0xAF, 0xAE, 0xAD, 0xAC, 0xB5, 0xDE, 0x49, 0x43, 0x3B, 0x2D, 0x28, 0x2A, 0x30, 0x36, 0x3A, 0x44, +0x6A, 0xCD, 0xC2, 0xC2, 0xC6, 0xCA, 0xCC, 0xD8, 0x60, 0x4C, 0x48, 0x46, 0x44, 0x43, 0x49, 0x54, +0x68, 0xEC, 0xD8, 0xCB, 0xC2, 0xBC, 0xB8, 0xB2, 0xAF, 0xAE, 0xAE, 0xAE, 0xBA, 0x74, 0x45, 0x3F, +0x36, 0x2C, 0x29, 0x2C, 0x32, 0x37, 0x3E, 0x4E, 0xE3, 0xC7, 0xC2, 0xC5, 0xC6, 0xC8, 0xD2, 0x71, +0x52, 0x4D, 0x49, 0x42, 0x41, 0x47, 0x51, 0x60, 0x7B, 0xDE, 0xCE, 0xC6, 0xC0, 0xBE, 0xB9, 0xB2, +0xAF, 0xAF, 0xAE, 0xAE, 0xBC, 0x6B, 0x47, 0x3F, 0x34, 0x2C, 0x2A, 0x2D, 0x32, 0x39, 0x3F, 0x4F, +0xDF, 0xC5, 0xC4, 0xCD, 0xCA, 0xC7, 0xDB, 0x5A, 0x4E, 0x4D, 0x48, 0x42, 0x40, 0x45, 0x54, 0x6F, +0x74, 0xEC, 0xCD, 0xC4, 0xC4, 0xC1, 0xBB, 0xB3, 0xAF, 0xB0, 0xAE, 0xAE, 0xBC, 0x6F, 0x4A, 0x3F, +0x34, 0x2C, 0x2B, 0x2E, 0x34, 0x3B, 0x42, 0x56, 0xCF, 0xBF, 0xC2, 0xCB, 0xC6, 0xC6, 0xE6, 0x52, +0x4B, 0x47, 0x45, 0x3F, 0x3D, 0x45, 0x5E, 0x7A, 0x72, 0xDB, 0xC7, 0xC3, 0xC5, 0xC2, 0xBC, 0xB5, +0xB1, 0xB3, 0xB0, 0xAE, 0xB9, 0xF0, 0x4C, 0x43, 0x38, 0x2E, 0x2B, 0x2D, 0x34, 0x3A, 0x3E, 0x4F, +0xD3, 0xC1, 0xC4, 0xCD, 0xCC, 0xC8, 0xDE, 0x4D, 0x45, 0x47, 0x47, 0x41, 0x3D, 0x47, 0x6D, 0xF7, +0x79, 0xDA, 0xC9, 0xC6, 0xC8, 0xC9, 0xC0, 0xB8, 0xB4, 0xB5, 0xB0, 0xAC, 0xB1, 0xCF, 0x5A, 0x4E, +0x3E, 0x30, 0x2B, 0x2D, 0x33, 0x38, 0x3B, 0x48, 0xDC, 0xC4, 0xC5, 0xCA, 0xCB, 0xCB, 0xD9, 0x50, +0x46, 0x4B, 0x46, 0x3E, 0x3F, 0x48, 0x55, 0x76, 0x7E, 0xE3, 0xCA, 0xC9, 0xCE, 0xCB, 0xC6, 0xBE, +0xBA, 0xB8, 0xB4, 0xAE, 0xAE, 0xBD, 0xEA, 0x62, 0x48, 0x35, 0x2D, 0x2C, 0x30, 0x35, 0x37, 0x3F, +0x6F, 0xCB, 0xCA, 0xC9, 0xC7, 0xCE, 0xD9, 0x60, 0x46, 0x46, 0x48, 0x40, 0x40, 0x49, 0x52, 0x69, +0xED, 0xE1, 0xD1, 0xCC, 0xD0, 0xD2, 0xD0, 0xCD, 0xC2, 0xBD, 0xB9, 0xB2, 0xAE, 0xAF, 0xBA, 0xE0, +0x67, 0x4C, 0x34, 0x2D, 0x2E, 0x30, 0x34, 0x37, 0x41, 0xF4, 0xCD, 0xCC, 0xC7, 0xC5, 0xD0, 0xED, +0x64, 0x4D, 0x45, 0x47, 0x43, 0x44, 0x4F, 0x51, 0x69, 0xD9, 0xDD, 0xD1, 0xCB, 0xD1, 0xCF, 0xD2, +0xCD, 0xBF, 0xBC, 0xB8, 0xB0, 0xAD, 0xAE, 0xBC, 0xD9, 0x76, 0x48, 0x32, 0x2D, 0x2F, 0x30, 0x32, +0x38, 0x49, 0xE6, 0xD1, 0xCB, 0xC1, 0xC1, 0xD2, 0x7A, 0x6F, 0x51, 0x42, 0x43, 0x45, 0x4A, 0x4D, +0x4E, 0x72, 0xD7, 0xDB, 0xD8, 0xCE, 0xCF, 0xD7, 0xDD, 0xD3, 0xC6, 0xBF, 0xBB, 0xB3, 0xAD, 0xAE, +0xB8, 0xCD, 0xE2, 0x52, 0x35, 0x2E, 0x2F, 0x2F, 0x2F, 0x35, 0x43, 0x62, 0xE5, 0xCF, 0xC1, 0xC0, +0xD1, 0xE1, 0xDB, 0x5E, 0x46, 0x49, 0x4D, 0x4A, 0x49, 0x51, 0x6A, 0xEE, 0xEB, 0xDE, 0xD0, 0xD4, +0xDF, 0xDC, 0xD7, 0xCF, 0xC5, 0xBE, 0xB7, 0xB1, 0xAE, 0xAF, 0xBC, 0xD3, 0xE7, 0x48, 0x31, 0x2E, +0x2F, 0x2E, 0x2F, 0x36, 0x44, 0x5B, 0xF4, 0xCC, 0xBF, 0xC2, 0xD4, 0xD1, 0xCF, 0x59, 0x4B, 0x51, +0x4B, 0x46, 0x44, 0x4C, 0x56, 0x51, 0x66, 0xE5, 0xE6, 0xE0, 0xDF, 0xD6, 0xD1, 0xCD, 0xC0, 0xBB, +0xB7, 0xB0, 0xAD, 0xB0, 0xBD, 0xCE, 0xEF, 0x44, 0x31, 0x2F, 0x30, 0x2E, 0x2E, 0x39, 0x46, 0x56, +0xF0, 0xC7, 0xBD, 0xC2, 0xC9, 0xC8, 0xCC, 0x7A, 0x50, 0x57, 0x4F, 0x42, 0x42, 0x4A, 0x4C, 0x4C, +0x5D, 0xEF, 0xEE, 0xE3, 0xD6, 0xD1, 0xD2, 0xCC, 0xC0, 0xBC, 0xBA, 0xB3, 0xAE, 0xAF, 0xBA, 0xC9, +0xD6, 0x4F, 0x36, 0x30, 0x30, 0x2E, 0x2D, 0x34, 0x3E, 0x45, 0x5C, 0xCF, 0xC1, 0xC0, 0xC1, 0xC0, +0xC9, 0xD9, 0xF5, 0x54, 0x4A, 0x47, 0x40, 0x41, 0x42, 0x45, 0x4E, 0x53, 0x68, 0xE8, 0xE1, 0xD1, +0xCD, 0xCC, 0xC5, 0xBF, 0xBB, 0xB8, 0xB4, 0xAF, 0xB0, 0xBD, 0xCB, 0xD8, 0x4B, 0x36, 0x34, 0x33, +0x2E, 0x2E, 0x37, 0x3D, 0x44, 0x62, 0xCD, 0xC4, 0xC0, 0xBE, 0xBF, 0xC5, 0xCF, 0xEE, 0x66, 0x4F, +0x45, 0x43, 0x40, 0x41, 0x44, 0x47, 0x51, 0x5B, 0x71, 0xDD, 0xD8, 0xCE, 0xC8, 0xC6, 0xC1, 0xBD, +0xB9, 0xB7, 0xB2, 0xAF, 0xB9, 0xC3, 0xCC, 0x71, 0x40, 0x37, 0x36, 0x31, 0x2E, 0x33, 0x3A, 0x3D, +0x4A, 0xE6, 0xCF, 0xC7, 0xBE, 0xBF, 0xC2, 0xCA, 0xD3, 0xE6, 0x50, 0x4C, 0x4B, 0x3E, 0x3E, 0x43, +0x41, 0x47, 0x4D, 0x59, 0x75, 0xE4, 0xD0, 0xCC, 0xC9, 0xC3, 0xBF, 0xBD, 0xBB, 0xB8, 0xB3, 0xB3, +0xBB, 0xC3, 0xCD, 0x6A, 0x42, 0x3A, 0x38, 0x31, 0x30, 0x36, 0x39, 0x3C, 0x4B, 0x7A, 0xDB, 0xCB, +0xC1, 0xC3, 0xC5, 0xC5, 0xD5, 0xE5, 0x6B, 0x4E, 0x4C, 0x43, 0x40, 0x45, 0x42, 0x48, 0x50, 0x55, +0x6C, 0xE8, 0xD7, 0xCD, 0xCC, 0xC7, 0xC3, 0xC0, 0xBD, 0xBC, 0xB8, 0xB2, 0xB5, 0xBD, 0xC2, 0xD0, +0x5D, 0x45, 0x3C, 0x38, 0x32, 0x32, 0x37, 0x37, 0x3C, 0x4C, 0x5E, 0xEE, 0xCD, 0xC5, 0xC8, 0xC6, +0xC5, 0xD0, 0xE2, 0xF9, 0x5D, 0x4D, 0x47, 0x46, 0x42, 0x41, 0x47, 0x4B, 0x4E, 0x63, 0xEA, 0xE3, +0xD3, 0xC9, 0xCB, 0xC8, 0xC0, 0xBF, 0xBD, 0xBA, 0xB5, 0xB6, 0xBC, 0xC1, 0xCC, 0x7E, 0x4B, 0x3F, +0x3B, 0x35, 0x32, 0x37, 0x37, 0x3A, 0x45, 0x50, 0x6D, 0xD7, 0xC8, 0xC6, 0xC7, 0xC2, 0xCA, 0xD7, +0xDB, 0x6D, 0x59, 0x4F, 0x48, 0x48, 0x45, 0x46, 0x4D, 0x4F, 0x5E, 0xFF, 0xE6, 0xD7, 0xD4, 0xCF, +0xD1, 0xD5, 0xD0, 0xD3, 0xCD, 0xC6, 0xC1, 0xBA, 0xB8, 0xBB, 0xC2, 0xC4, 0xCD, 0x58, 0x4C, 0x48, +0x39, 0x36, 0x39, 0x36, 0x37, 0x3E, 0x44, 0x4B, 0x66, 0xDC, 0xD4, 0xCA, 0xC3, 0xC5, 0xC7, 0xCA, +0xCE, 0xDD, 0x6D, 0x5F, 0x4F, 0x46, 0x47, 0x46, 0x43, 0x49, 0x4E, 0x53, 0x65, 0xF1, 0xE4, 0xD9, +0xCF, 0xCE, 0xCD, 0xC6, 0xC3, 0xC0, 0xBA, 0xB7, 0xB7, 0xBD, 0xC4, 0xC5, 0xFD, 0x4A, 0x4C, 0x3B, +0x33, 0x37, 0x34, 0x32, 0x3A, 0x3F, 0x47, 0x5B, 0xDC, 0xCB, 0xC8, 0xBE, 0xBC, 0xC3, 0xC0, 0xC7, +0xDE, 0xEC, 0x5B, 0x49, 0x45, 0x3F, 0x3E, 0x3F, 0x40, 0x49, 0x4E, 0x5B, 0xEF, 0xDF, 0xD4, 0xCC, +0xCA, 0xC7, 0xC5, 0xC3, 0xBF, 0xBD, 0xBB, 0xB8, 0xB8, 0xC0, 0xCB, 0xCA, 0x68, 0x45, 0x4D, 0x3D, +0x35, 0x3C, 0x3A, 0x38, 0x41, 0x49, 0x4D, 0x69, 0xDB, 0xD3, 0xCD, 0xC5, 0xC6, 0xCC, 0xCB, 0xD0, +0xEB, 0x76, 0x5C, 0x4C, 0x48, 0x44, 0x41, 0x41, 0x44, 0x49, 0x4E, 0x5D, 0x7E, 0xE6, 0xD4, 0xCE, +0xCE, 0xCB, 0xCB, 0xCE, 0xCE, 0xCA, 0xC9, 0xC6, 0xBE, 0xBC, 0xC6, 0xCA, 0xC4, 0xE0, 0x58, 0x77, +0x4A, 0x3D, 0x45, 0x3D, 0x39, 0x3F, 0x41, 0x40, 0x4C, 0x61, 0x6D, 0xE7, 0xCE, 0xCC, 0xCC, 0xC9, +0xCA, 0xD1, 0xDB, 0xE2, 0x66, 0x54, 0x50, 0x48, 0x45, 0x47, 0x47, 0x4B, 0x51, 0x5A, 0x71, 0xEB, +0xDD, 0xD5, 0xD2, 0xCF, 0xCC, 0xCC, 0xCA, 0xC4, 0xC3, 0xBF, 0xB9, 0xBD, 0xCB, 0xC0, 0xC9, 0x56, +0x71, 0x5A, 0x3A, 0x3F, 0x3E, 0x34, 0x3A, 0x3E, 0x3C, 0x42, 0x54, 0x62, 0x73, 0xCF, 0xC8, 0xCC, +0xC3, 0xC3, 0xCD, 0xCF, 0xDD, 0x6D, 0x56, 0x4D, 0x48, 0x42, 0x42, 0x44, 0x45, 0x4D, 0x57, 0x61, +0xED, 0xDB, 0xD5, 0xCD, 0xCD, 0xCD, 0xCD, 0xD0, 0xCD, 0xD1, 0xCA, 0xC4, 0xC7, 0xBA, 0xC2, 0xD8, +0xBB, 0xD7, 0x53, 0xCC, 0x4E, 0x3E, 0x57, 0x3E, 0x3B, 0x43, 0x3F, 0x3E, 0x46, 0x52, 0x50, 0x60, +0xD6, 0xD9, 0xD4, 0xC6, 0xCA, 0xCF, 0xCB, 0xD5, 0xF4, 0xFB, 0x5D, 0x4E, 0x4C, 0x4B, 0x46, 0x45, +0x4F, 0x4E, 0x4D, 0x7E, 0x6F, 0x71, 0xD4, 0xE1, 0xDF, 0xCE, 0xD9, 0xD5, 0xCD, 0xCD, 0xC5, 0xBF, +0xB9, 0xBA, 0xC6, 0xBA, 0xBF, 0x6C, 0xCE, 0xFB, 0x3D, 0x4D, 0x40, 0x35, 0x3C, 0x3B, 0x38, 0x3E, +0x47, 0x4B, 0x52, 0xDF, 0xD8, 0xD6, 0xC3, 0xC6, 0xCB, 0xC5, 0xCD, 0xDD, 0xE4, 0x6B, 0x50, 0x4D, +0x49, 0x44, 0x45, 0x47, 0x48, 0x49, 0x50, 0x5D, 0x5C, 0xEE, 0xDD, 0xE7, 0xD1, 0xD5, 0xDC, 0xD0, +0xDA, 0xD8, 0xD1, 0xCD, 0xC6, 0xBF, 0xBA, 0xC1, 0xC4, 0xBA, 0xD3, 0xE1, 0xCC, 0x4D, 0x49, 0x4F, +0x3B, 0x3B, 0x3E, 0x3A, 0x3C, 0x42, 0x4A, 0x4C, 0x6D, 0xD9, 0xDC, 0xC9, 0xC4, 0xCA, 0xC6, 0xC8, +0xD0, 0xD8, 0xE5, 0x68, 0x58, 0x53, 0x4C, 0x4A, 0x4B, 0x4C, 0x4E, 0x56, 0x5F, 0x69, 0xEA, 0xE0, +0xE8, 0xD5, 0xDD, 0xE7, 0xD9, 0xFB, 0xF9, 0xF5, 0x64, 0x75, 0x6D, 0xF5, 0xE5, 0xD8, 0xC8, 0xC4, +0xBB, 0xBF, 0xC4, 0xB7, 0xCC, 0xD6, 0xC3, 0x56, 0x52, 0x5F, 0x3D, 0x3E, 0x3E, 0x39, 0x3A, 0x3D, +0x41, 0x41, 0x4F, 0x6B, 0x63, 0xD6, 0xCD, 0xD1, 0xC7, 0xC8, 0xCE, 0xCE, 0xD6, 0xE8, 0x71, 0x67, +0x55, 0x4F, 0x52, 0x4D, 0x4F, 0x56, 0x56, 0x5E, 0x6D, 0x7E, 0xF5, 0xDF, 0xE3, 0xEE, 0xDC, 0x7B, +0x73, 0xED, 0x5C, 0x6A, 0x69, 0x5B, 0x70, 0x6D, 0xEF, 0xE1, 0xCF, 0xC8, 0xC4, 0xB9, 0xC5, 0xC2, +0xB6, 0xDC, 0xCD, 0xC3, 0x49, 0x60, 0x57, 0x3A, 0x40, 0x3D, 0x38, 0x3A, 0x3E, 0x3F, 0x3E, 0x53, +0x58, 0x59, 0xD3, 0xD7, 0xD2, 0xC4, 0xC9, 0xCA, 0xC8, 0xCD, 0xD8, 0xDE, 0xEE, 0x5F, 0x5D, 0x59, +0x4F, 0x54, 0x56, 0x54, 0x5D, 0x69, 0x6D, 0xF2, 0xE1, 0xDF, 0xDB, 0xD8, 0xDD, 0xE8, 0xEB, 0x71, +0x5D, 0x66, 0x56, 0x52, 0x62, 0x52, 0x5C, 0x74, 0x63, 0xE2, 0xDD, 0xD4, 0xCA, 0xC9, 0xBF, 0xC0, +0xBB, 0xBB, 0xCC, 0xBB, 0xC8, 0x68, 0xC8, 0x58, 0x44, 0x5D, 0x3C, 0x3B, 0x40, 0x3A, 0x3B, 0x3F, +0x44, 0x43, 0x52, 0x7A, 0x62, 0xD4, 0xCB, 0xD1, 0xC3, 0xC4, 0xC8, 0xC5, 0xCA, 0xD0, 0xD9, 0xE1, +0x6C, 0x5C, 0x5B, 0x4E, 0x4D, 0x50, 0x4C, 0x50, 0x58, 0x58, 0x63, 0x79, 0xFE, 0xED, 0xE1, 0xE7, +0xEE, 0xE6, 0xFB, 0x6D, 0x7A, 0x61, 0x5D, 0x62, 0x59, 0x5B, 0x5E, 0x5C, 0x64, 0x69, 0x72, 0xFE, +0xF1, 0xE6, 0xE2, 0xDB, 0xD9, 0xD6, 0xD3, 0xD3, 0xD0, 0xD0, 0xCF, 0xCE, 0xCD, 0xCD, 0xDA, 0xDB, +0xDA, 0x64, 0x69, 0x63, 0x4C, 0x4F, 0x4D, 0x46, 0x4A, 0x4A, 0x48, 0x4D, 0x52, 0x52, 0x5C, 0x70, +0x71, 0xEB, 0xDC, 0xDE, 0xD7, 0xD4, 0xD8, 0xD5, 0xD7, 0xDD, 0xDF, 0xE7, 0xFD, 0x71, 0x69, 0x5D, +0x5A, 0x5A, 0x57, 0x56, 0x5B, 0x59, 0x5A, 0x69, 0x62, 0x6A, 0xF5, 0x73, 0xF1, 0xE7, 0xF4, 0xE6, +0xE6, 0xEE, 0xEA, 0xED, 0xF5, 0xF1, 0xED, 0xF0, 0xEA, 0xE4, 0xE7, 0xDF, 0xDE, 0xDF, 0xDC, 0xDE, +0xDF, 0xE1, 0xE8, 0xEE, 0xFD, 0x77, 0x6B, 0x64, 0x61, 0x5C, 0x5C, 0x5C, 0x5B, 0x5F, 0x61, 0x67, +0x6E, 0x78, 0xF8, 0xF1, 0xEA, 0xE5, 0xE4, 0xE2, 0xE1, 0xE5, 0xEA, 0xED, 0xFA, 0x77, 0x6E, 0x66, +0x62, 0x5D, 0x5C, 0x5A, 0x59, 0x59, 0x59, 0x5B, 0x5C, 0x5D, 0x64, 0x64, 0x6C, 0x77, 0x7C, 0xEE, +0xEB, 0xE0, 0xDB, 0xD7, 0xCF, 0xCF, 0xCA, 0xC8, 0xC5, 0xC4, 0xCD, 0xC7, 0xCB, 0xE8, 0xD3, 0xFD, +0x55, 0x67, 0x4B, 0x45, 0x48, 0x40, 0x3F, 0x42, 0x43, 0x43, 0x4A, 0x50, 0x50, 0x6C, 0xF5, 0xF2, +0xD4, 0xD2, 0xD1, 0xCB, 0xCC, 0xCE, 0xCE, 0xD0, 0xDA, 0xDC, 0xDF, 0xFD, 0x7D, 0x6F, 0x5E, 0x5F, +0x5D, 0x59, 0x5A, 0x5C, 0x5C, 0x5F, 0x68, 0x68, 0x6F, 0xFC, 0xFC, 0xEF, 0xE9, 0xEB, 0xE9, 0xE9, +0xED, 0xEF, 0xF2, 0xF8, 0xFE, 0xFE, 0x7C, 0x7C, 0x7E, 0x79, 0xFE, 0xFB, 0xFE, 0xF7, 0xF6, 0xF9, +0xF6, 0xF8, 0xFD, 0xFF, 0x7C, 0x73, 0x70, 0x6E, 0x6A, 0x6A, 0x69, 0x68, 0x6A, 0x6B, 0x6C, 0x6F, +0x74, 0x79, 0xFF, 0xFA, 0xF8, 0xF2, 0xF4, 0xF6, 0xF3, 0xFE, 0xFB, 0x74, 0x62, 0x69, 0x5F, 0x5A, +0x66, 0x5B, 0x5D, 0x70, 0x61, 0x78, 0xED, 0xF4, 0xDB, 0xD7, 0xD0, 0xCB, 0xC9, 0xC3, 0xCC, 0xC9, +0xC4, 0xDD, 0xD2, 0xD7, 0x59, 0x6E, 0x57, 0x45, 0x4B, 0x45, 0x3F, 0x43, 0x44, 0x43, 0x49, 0x51, +0x4F, 0x5E, 0xFB, 0x70, 0xDE, 0xD8, 0xDC, 0xD1, 0xD2, 0xD7, 0xD4, 0xD6, 0xDD, 0xDF, 0xDF, 0xF1, +0xF2, 0xF2, 0x6F, 0x73, 0x72, 0x69, 0x6D, 0x6F, 0x6D, 0x72, 0x7B, 0x79, 0x7E, 0xF8, 0xFD, 0xF9, +0xF6, 0xFD, 0xFA, 0xFA, 0xFD, 0xFB, 0xFB, 0xFD, 0xFA, 0xF6, 0xF8, 0xF3, 0xF2, 0xF4, 0xEF, 0xF1, +0xF4, 0xF2, 0xF6, 0xF9, 0xF8, 0xF9, 0xFD, 0xFD, 0xFC, 0x7F, 0x7E, 0x7D, 0x79, 0x76, 0x74, 0x71, +0x6F, 0x6E, 0x6C, 0x6C, 0x6D, 0x6B, 0x6C, 0x6D, 0x6C, 0x71, 0x71, 0x70, 0x7E, 0x79, 0x7C, 0xFA, +0x7B, 0xFD, 0xFC, 0x7A, 0xFE, 0x7C, 0x78, 0x7B, 0x76, 0x76, 0x78, 0x77, 0x77, 0x7C, 0x7E, 0xFF, +0xF2, 0xF3, 0xED, 0xE7, 0xE8, 0xE0, 0xDE, 0xDC, 0xD7, 0xD8, 0xD3, 0xD4, 0xDA, 0xD7, 0xDF, 0xEB, +0xED, 0x6A, 0x60, 0x5C, 0x52, 0x4F, 0x4D, 0x4B, 0x4A, 0x4B, 0x4B, 0x4D, 0x50, 0x54, 0x5B, 0x66, +0x6F, 0xF1, 0xE6, 0xDF, 0xDA, 0xD8, 0xD8, 0xD7, 0xD9, 0xDB, 0xDE, 0xE2, 0xEA, 0xF1, 0xFA, 0x78, +0x70, 0x6D, 0x69, 0x68, 0x66, 0x65, 0x65, 0x66, 0x66, 0x67, 0x6A, 0x6B, 0x6C, 0x70, 0x74, 0x79, +0xFB, 0xF5, 0xEF, 0xEB, 0xE9, 0xE6, 0xE3, 0xE2, 0xE1, 0xE0, 0xE0, 0xE0, 0xE1, 0xE3, 0xE3, 0xE6, +0xE9, 0xEB, 0xEF, 0xF7, 0x7F, 0x75, 0x6E, 0x6A, 0x66, 0x62, 0x61, 0x5F, 0x5F, 0x60, 0x5F, 0x62, +0x65, 0x66, 0x6C, 0x6E, 0x72, 0x7D, 0xFE, 0xF6, 0xEF, 0xED, 0xE9, 0xE7, 0xE4, 0xE3, 0xE0, 0xDF, +0xE1, 0xDF, 0xE1, 0xE3, 0xE3, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xED, 0xF5, 0xF6, 0xF9, 0x75, +0x76, 0x6E, 0x66, 0x65, 0x5E, 0x5B, 0x5A, 0x56, 0x55, 0x54, 0x53, 0x54, 0x55, 0x57, 0x59, 0x5D, +0x60, 0x66, 0x70, 0x79, 0xFA, 0xF0, 0xEE, 0xEC, 0xED, 0xED, 0xF0, 0xF5, 0xF8, 0xFF, 0xFD, 0x7E, +0x7D, 0xFE, 0x7E, 0xFD, 0xF8, 0xF6, 0xEF, 0xED, 0xEB, 0xE8, 0xE4, 0xE3, 0xE0, 0xDF, 0xDE, 0xDC, +0xDD, 0xDC, 0xDD, 0xE1, 0xE2, 0xE9, 0xF3, 0x7A, 0x65, 0x61, 0x5B, 0x56, 0x56, 0x51, 0x50, 0x52, +0x50, 0x55, 0x58, 0x59, 0x5F, 0x68, 0x70, 0xFC, 0xEE, 0xE9, 0xE4, 0xE1, 0xE4, 0xE4, 0xE7, 0xED, +0xEE, 0xF8, 0xFF, 0x7D, 0x76, 0x76, 0x7A, 0x7B, 0xFF, 0xF9, 0xF7, 0xF1, 0xED, 0xED, 0xEB, 0xE9, +0xEA, 0xEA, 0xEC, 0xED, 0xEE, 0xF0, 0xF1, 0xF2, 0xF2, 0xF3, 0xF0, 0xF1, 0xF3, 0xEF, 0xF3, 0xF5, +0xF4, 0xFB, 0xFC, 0xFC, 0x7C, 0x7A, 0x76, 0x70, 0x6F, 0x6F, 0x6C, 0x6C, 0x6C, 0x68, 0x6B, 0x6B, +0x68, 0x6D, 0x6B, 0x6B, 0x6F, 0x6E, 0x70, 0x77, 0x76, 0x7A, 0x7F, 0xFF, 0xFD, 0xF6, 0xF7, 0xF5, +0xEF, 0xF4, 0xF1, 0xEF, 0xF2, 0xEE, 0xF0, 0xF1, 0xEE, 0xF0, 0xF1, 0xF1, 0xF2, 0xF6, 0xF9, 0xFA, +0x7F, 0x7E, 0x7A, 0x76, 0x7A, 0x73, 0x72, 0x74, 0x6F, 0x73, 0x75, 0x73, 0x75, 0x74, 0x76, 0x73, +0x77, 0x7A, 0x76, 0x7E, 0x78, 0x76, 0x7E, 0x76, 0x7A, 0x79, 0x74, 0x7D, 0x77, 0x77, 0x79, 0x74, +0x76, 0x77, 0x7A, 0x79, 0x7C, 0xFF, 0x79, 0xFC, 0xFA, 0x7E, 0xF4, 0xF9, 0xFC, 0xF6, 0x7E, 0xFF, +0xFF, 0x7B, 0x7C, 0x77, 0x75, 0x76, 0x78, 0x76, 0x74, 0x7B, 0x74, 0x75, 0x7E, 0x74, 0x7B, 0x7C, +0x72, 0x7A, 0x77, 0x74, 0x7A, 0x75, 0x72, 0x73, 0x72, 0x6E, 0x6E, 0x70, 0x6D, 0x70, 0x71, 0x6E, +0x75, 0x73, 0x72, 0x79, 0x78, 0x7B, 0xFF, 0xFF, 0xFD, 0xFA, 0xFC, 0xFB, 0xF7, 0xFD, 0xFE, 0xFA, +0x7D, 0x7D, 0xFE, 0x79, 0x7B, 0x7C, 0x7B, 0x7E, 0x7E, 0xFD, 0xFA, 0xFA, 0xF7, 0xF8, 0xF9, 0xF9, +0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x7D, 0x7B, 0x77, 0x78, 0x74, 0x71, 0x74, 0x6F, 0x6F, 0x71, 0x6D, +0x6F, 0x71, 0x6F, 0x73, 0x74, 0x77, 0x7B, 0x7D, 0x7F, 0xFF, 0xFC, 0xFE, 0xFB, 0xF8, 0xFB, 0xF7, +0xF9, 0xFE, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0x7E, 0x7C, 0x7E, 0x7B, 0x7B, 0x7E, 0x7C, 0xFF, 0xFE, +0xFE, 0xFB, 0xFE, 0xFF, 0xFD, 0xFE, 0x7E, 0x7F, 0x7A, 0x78, 0x79, 0x75, 0x74, 0x75, 0x73, 0x75, +0x77, 0x77, 0x79, 0x7B, 0x7D, 0xFF, 0xFA, 0xF8, 0xF4, 0xF2, 0xF5, 0xF1, 0xF2, 0xF6, 0xF3, 0xF6, +0xFA, 0xFB, 0xFC, 0x7D, 0x7A, 0x7A, 0x74, 0x77, 0x78, 0x74, 0x7A, 0x77, 0x7A, 0xFF, 0x7F, 0xF9, +0xFB, 0xFB, 0xF9, 0xFF, 0x7F, 0x7C, 0x7A, 0x77, 0x72, 0x73, 0x6E, 0x6E, 0x6E, 0x6D, 0x70, 0x70, +0x75, 0x7D, 0x7B, 0xFE, 0xFD, 0xFF, 0xFC, 0xFF, 0x7E, 0xFF, 0x7E, 0x7A, 0x79, 0x76, 0x6F, 0x72, +0x72, 0x6F, 0x73, 0x6F, 0x6E, 0x74, 0x72, 0x74, 0x7C, 0x7C, 0xFF, 0xF9, 0xFA, 0xF9, 0xF5, 0xF7, +0xF7, 0xF5, 0xFA, 0xFA, 0xF7, 0xFA, 0xF9, 0xF8, 0xFC, 0xF9, 0xF8, 0xFA, 0xF6, 0xF9, 0xFC, 0xFA, +0xFD, 0xFE, 0xFD, 0xFF, 0x7E, 0x7E, 0x7D, 0x7A, 0x7C, 0x7B, 0x79, 0x7C, 0x7B, 0x7B, 0xFF, 0x7E, +0xFF, 0xFC, 0xFE, 0xFE, 0xFB, 0xFD, 0x7C, 0x7F, 0x7F, 0x76, 0x78, 0x78, 0x74, 0x78, 0x78, 0x78, +0x7B, 0x7A, 0x7A, 0x79, 0x77, 0x78, 0x79, 0x78, 0x7A, 0x7B, 0x7A, 0x7C, 0x7F, 0x7D, 0xFF, 0xFC, +0xFD, 0xFA, 0xFB, 0xFD, 0xFE, 0xFF, 0x7F, 0x7D, 0x7C, 0x7A, 0x7B, 0x7D, 0x7D, 0x7E, 0x7E, 0x7D, +0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7F, 0xFF, 0xFE, 0xFC, 0xFC, 0xFB, +0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xFB, 0xFB, 0xFD, 0xFF, 0x7D, 0x7B, 0x7B, 0x7A, 0x77, 0x77, 0x78, +0x77, 0x77, 0x79, 0x7A, 0x7B, 0x7B, 0x7D, 0x7E, 0xFF, 0xFE, 0xFE, 0xFD, 0xFC, 0xFC, 0xFC, 0xFC, +0xFE, 0xFF, 0xFF, 0x7E, 0x7B, 0x78, 0x77, 0x76, 0x74, 0x73, 0x73, 0x71, 0x72, 0x73, 0x73, 0x74, +0x75, 0x76, 0x77, 0x77, 0x78, 0x78, 0x7A, 0x7D, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0x7F, 0x7E, 0x7D, 0x7D, 0x7C, 0x7A, 0x79, 0x79, 0x78, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7A, +0x79, 0x7B, 0x7B, 0x7B, 0x7C, 0x7A, 0x7A, 0x79, 0x78, 0x78, 0x76, 0x76, 0x75, 0x73, 0x73, 0x73, +0x74, 0x77, 0x79, 0x7A, 0x7D, 0x7F, 0xFE, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFF, +0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4C, 0x49, 0x53, 0x54, 0x4A, 0x00, +0x00, 0x00, 0x49, 0x4E, 0x46, 0x4F, 0x49, 0x53, 0x46, 0x54, 0x3E, 0x00, 0x00, 0x00, 0x46, 0x69, +0x6C, 0x65, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x6F, +0x6C, 0x64, 0x57, 0x61, 0x76, 0x65, 0x2E, 0x20, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x57, 0x61, 0x76, +0x65, 0x20, 0x63, 0x6F, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, +0x43, 0x68, 0x72, 0x69, 0x73, 0x20, 0x43, 0x72, 0x61, 0x69, 0x67, 0x00 + +}; + +static const uint8_t shaun_png[] PROGMEM = { + 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x57, 0x08, 0x06, 0x00, 0x00, 0x00, 0xF2, 0x0C, 0xE0, + 0x57, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4B, 0x47, 0x44, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xA0, + 0xBD, 0xA7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x42, 0x8A, 0x00, + 0x00, 0x42, 0x8A, 0x01, 0x34, 0xA8, 0x6C, 0x25, 0x00, 0x00, 0x00, 0x09, 0x76, 0x70, 0x41, 0x67, + 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x57, 0x00, 0x73, 0x4D, 0x3B, 0xD6, 0x00, 0x00, 0x1B, + 0x47, 0x49, 0x44, 0x41, 0x54, 0x78, 0xDA, 0xED, 0x9D, 0x79, 0x74, 0x14, 0x55, 0xBE, 0xC7, 0x3F, + 0x55, 0xDD, 0x49, 0x67, 0x5F, 0x3A, 0x7B, 0x42, 0x82, 0x61, 0x49, 0x02, 0x81, 0xB0, 0x29, 0x32, + 0x22, 0x3C, 0x16, 0x41, 0x45, 0x10, 0x15, 0x7D, 0x13, 0x65, 0xD0, 0x81, 0xE3, 0x7B, 0xCC, 0xD3, + 0x51, 0x04, 0xF5, 0xE1, 0xB8, 0xCE, 0xE6, 0x28, 0x22, 0x23, 0x33, 0x2C, 0x2A, 0x22, 0xEE, 0x02, + 0x22, 0x0C, 0x2A, 0x83, 0x28, 0x7B, 0x20, 0xC8, 0x92, 0x10, 0xD9, 0x97, 0x40, 0x08, 0x81, 0x90, + 0x3D, 0x64, 0x21, 0xE9, 0x4E, 0x3A, 0x5D, 0xF7, 0xFD, 0x71, 0xBB, 0x93, 0x0E, 0x10, 0xD2, 0x59, + 0x3A, 0x01, 0xCF, 0xFB, 0x9E, 0xD3, 0xE7, 0xA4, 0x6E, 0xA5, 0x6E, 0xDD, 0xFA, 0xFD, 0xEA, 0xFE, + 0xEE, 0xEF, 0xFE, 0xB6, 0x52, 0xB8, 0xFE, 0xA1, 0x03, 0x7A, 0x01, 0x43, 0x81, 0x9B, 0x80, 0x6A, + 0x60, 0x3F, 0xA0, 0x02, 0x8F, 0x00, 0xB7, 0x03, 0xA1, 0x80, 0x00, 0x72, 0x81, 0xAD, 0xC0, 0xC7, + 0xC0, 0x6E, 0xA0, 0xAE, 0xB3, 0x07, 0xFF, 0x4B, 0x43, 0x30, 0xF0, 0x67, 0x20, 0x1B, 0xB0, 0x20, + 0x89, 0xAE, 0x01, 0x95, 0x40, 0xB9, 0xED, 0xF8, 0x6A, 0xBF, 0x3C, 0xDB, 0x75, 0x81, 0xCD, 0xF4, + 0xAF, 0x03, 0x8C, 0x40, 0x2C, 0xD0, 0x13, 0x88, 0x00, 0x0C, 0x9D, 0xF9, 0xC0, 0x4A, 0x27, 0xDD, + 0xD7, 0x13, 0x88, 0x07, 0xFA, 0x03, 0x51, 0x36, 0x22, 0xE4, 0x03, 0x87, 0x80, 0x83, 0x48, 0x62, + 0x1B, 0x81, 0x85, 0x40, 0x72, 0x2B, 0xC7, 0xA9, 0x01, 0x5F, 0x00, 0x2F, 0x03, 0x35, 0xB6, 0xE3, + 0x0A, 0xDB, 0xDF, 0xDE, 0xC0, 0x48, 0x60, 0x22, 0x30, 0x08, 0xC9, 0x78, 0x3D, 0x92, 0xD1, 0x99, + 0xC0, 0x0F, 0xC0, 0x5A, 0xE0, 0x5C, 0x47, 0x13, 0xA6, 0xA3, 0x19, 0xA2, 0x07, 0x46, 0x00, 0x4F, + 0x22, 0x45, 0x4D, 0xD0, 0x65, 0x63, 0xB8, 0x84, 0x14, 0x47, 0xEF, 0x03, 0x09, 0xC0, 0x4B, 0x48, + 0xD1, 0x44, 0x40, 0x40, 0x00, 0x31, 0x31, 0x31, 0x54, 0x56, 0x56, 0x92, 0x93, 0x93, 0x83, 0xD5, + 0x6A, 0x25, 0x3A, 0x3A, 0x9A, 0x89, 0x13, 0x27, 0x32, 0x60, 0xC0, 0x00, 0xAC, 0x56, 0x2B, 0xBB, + 0x77, 0xEF, 0x66, 0xDD, 0xBA, 0x75, 0x14, 0x16, 0x16, 0xDA, 0xFB, 0xAB, 0x03, 0x4E, 0x23, 0x67, + 0x4D, 0x9D, 0x8D, 0xC0, 0xFB, 0x90, 0x22, 0xF0, 0x1E, 0xC0, 0xAB, 0x89, 0x71, 0x6A, 0xC0, 0x11, + 0xE0, 0x0D, 0xE0, 0x6B, 0xE4, 0xEC, 0xFC, 0xC5, 0xC1, 0x07, 0x78, 0x0D, 0x28, 0xA5, 0x69, 0x51, + 0x63, 0xFF, 0x99, 0x80, 0x2A, 0xFB, 0xF1, 0xC0, 0x81, 0x03, 0xC5, 0xA6, 0x4D, 0x9B, 0x44, 0x49, + 0x49, 0x89, 0xC8, 0xCA, 0xCA, 0x12, 0xAF, 0xBF, 0xFE, 0xBA, 0x78, 0xFC, 0xF1, 0xC7, 0x45, 0x5A, + 0x5A, 0x9A, 0xD0, 0x34, 0x4D, 0xD8, 0x51, 0x57, 0x57, 0x27, 0xB6, 0x6E, 0xDD, 0x2A, 0xFA, 0xF7, + 0xEF, 0xDF, 0x5C, 0xFF, 0x8D, 0x7E, 0x8A, 0xA2, 0x08, 0x55, 0x55, 0xAF, 0x76, 0xAE, 0x02, 0x78, + 0x0E, 0xF9, 0x22, 0x75, 0x08, 0x3A, 0x6A, 0x86, 0x78, 0x02, 0x7F, 0x05, 0x9E, 0x02, 0xDC, 0x00, + 0x14, 0x45, 0x21, 0x24, 0x24, 0x84, 0xE8, 0xE8, 0x68, 0xDC, 0xDD, 0xDD, 0xB9, 0x70, 0xE1, 0x02, + 0xB9, 0xB9, 0xB9, 0xD4, 0xD5, 0x35, 0x5E, 0x87, 0xBD, 0xBC, 0xBC, 0x58, 0xB1, 0x62, 0x05, 0x13, + 0x26, 0x4C, 0xA8, 0x6F, 0x13, 0x42, 0x20, 0x84, 0x40, 0x55, 0xD5, 0xAB, 0xDE, 0x6C, 0xD7, 0xAE, + 0x5D, 0x3C, 0xFC, 0xF0, 0xC3, 0xE4, 0xE4, 0xE4, 0x34, 0xFD, 0xE0, 0x8A, 0x42, 0x7C, 0x7C, 0x3C, + 0xF7, 0xDC, 0x73, 0x0F, 0xFD, 0xFA, 0xF5, 0xC3, 0xC3, 0xC3, 0x83, 0xEC, 0xEC, 0x6C, 0x36, 0x6C, + 0xD8, 0x40, 0x6A, 0x6A, 0x2A, 0x35, 0x35, 0x35, 0xF6, 0x7F, 0xAD, 0xB4, 0x8D, 0xFB, 0x73, 0xC0, + 0xDA, 0x41, 0xF4, 0x72, 0x39, 0x7E, 0x8F, 0x7C, 0xEB, 0x05, 0x20, 0xC2, 0xC2, 0xC2, 0xC4, 0x2B, + 0xAF, 0xBC, 0x22, 0x0E, 0x1E, 0x3C, 0x28, 0x2E, 0x5E, 0xBC, 0x28, 0x2A, 0x2A, 0x2A, 0x44, 0x56, + 0x56, 0x96, 0x58, 0xBC, 0x78, 0xB1, 0x48, 0x48, 0x48, 0x68, 0xF4, 0x96, 0xC6, 0xC4, 0xC4, 0x88, + 0x33, 0x67, 0xCE, 0x88, 0x96, 0xE2, 0xE3, 0x8F, 0x3F, 0x16, 0x77, 0xDE, 0x79, 0xA7, 0x78, 0xFE, + 0xF9, 0xE7, 0xC5, 0xBB, 0xEF, 0xBE, 0x2B, 0xDE, 0x7E, 0xFB, 0x6D, 0xF1, 0xE0, 0x83, 0x0F, 0x0A, + 0xA3, 0xD1, 0x28, 0xDC, 0xDC, 0xDC, 0xC4, 0xD4, 0xA9, 0x53, 0xC5, 0xE9, 0xD3, 0xA7, 0xAF, 0xB8, + 0xAE, 0xA2, 0xA2, 0x42, 0x2C, 0x58, 0xB0, 0x40, 0x04, 0x07, 0x07, 0x3B, 0x8E, 0xA3, 0x00, 0x58, + 0x0D, 0xFC, 0x0E, 0x08, 0xEF, 0x6C, 0x62, 0xB6, 0x15, 0x7D, 0x80, 0x33, 0xF6, 0x87, 0x8B, 0x8D, + 0x8D, 0x15, 0xEB, 0xD7, 0xAF, 0x6F, 0x24, 0x6A, 0x1C, 0x91, 0x91, 0x91, 0x21, 0x06, 0x0F, 0x1E, + 0x2C, 0x00, 0x61, 0x30, 0x18, 0xC4, 0xAF, 0x7F, 0xFD, 0x6B, 0x51, 0x51, 0x51, 0xD1, 0x62, 0x86, + 0x58, 0xAD, 0x56, 0x61, 0x36, 0x9B, 0x1B, 0xDD, 0xA7, 0xA6, 0xA6, 0x46, 0xEC, 0xD8, 0xB1, 0x43, + 0xAC, 0x5A, 0xB5, 0x4A, 0x94, 0x97, 0x97, 0x37, 0x79, 0xAD, 0xA6, 0x69, 0x62, 0xF1, 0xE2, 0xC5, + 0xC2, 0xC3, 0xC3, 0xE3, 0x72, 0x11, 0x66, 0x05, 0x76, 0x02, 0x43, 0x3A, 0x9B, 0xA8, 0x6D, 0xC1, + 0xDB, 0xF6, 0x07, 0xF2, 0xF5, 0xF5, 0x15, 0x2B, 0x56, 0xAC, 0x68, 0x96, 0x98, 0xC7, 0x8E, 0x1D, + 0x13, 0xF3, 0xE7, 0xCF, 0x17, 0x1B, 0x36, 0x6C, 0x10, 0xA5, 0xA5, 0xA5, 0x2D, 0x66, 0x46, 0x7B, + 0xA0, 0xB2, 0xB2, 0x52, 0x4C, 0x98, 0x30, 0xA1, 0xA9, 0x75, 0xE7, 0x00, 0x52, 0x31, 0x68, 0x77, + 0xB8, 0x7A, 0x0D, 0x89, 0x02, 0x36, 0xDA, 0x07, 0x3F, 0x79, 0xF2, 0x64, 0x3E, 0xFC, 0xF0, 0x43, + 0x0C, 0x86, 0x4E, 0x55, 0xF5, 0x9D, 0xC6, 0xC1, 0x83, 0x07, 0x59, 0xBB, 0x76, 0x2D, 0x16, 0x8B, + 0x85, 0x94, 0x94, 0x14, 0x52, 0x53, 0x53, 0xB1, 0x5A, 0xEB, 0x97, 0x91, 0xF7, 0x91, 0xDA, 0xE2, + 0x0D, 0xB5, 0xAE, 0x8C, 0x07, 0xCC, 0x80, 0xF0, 0xF4, 0xF4, 0x14, 0xEB, 0xD6, 0xAD, 0xEB, 0x94, + 0xB7, 0xBD, 0x3D, 0x50, 0x54, 0x54, 0x24, 0x92, 0x93, 0x93, 0x1D, 0x67, 0x49, 0x36, 0xD0, 0xBD, + 0xB3, 0x09, 0xDC, 0x12, 0x84, 0x00, 0xAB, 0xEC, 0x0F, 0x10, 0x1F, 0x1F, 0x2F, 0x72, 0x73, 0x73, + 0x3B, 0x9B, 0xAE, 0x6D, 0xC2, 0x96, 0x2D, 0x5B, 0x84, 0x8F, 0x8F, 0x8F, 0xA3, 0x6A, 0x7E, 0x47, + 0x7B, 0x13, 0x4D, 0x6D, 0x7B, 0x17, 0x57, 0x85, 0x37, 0x72, 0x53, 0x35, 0xC9, 0xDE, 0xD0, 0xAD, + 0x5B, 0x37, 0x8C, 0x46, 0xA3, 0x8B, 0x6E, 0xD7, 0x31, 0xF0, 0xF5, 0xF5, 0x45, 0xAF, 0xAF, 0xDF, + 0x92, 0xA8, 0x80, 0x47, 0x7B, 0xDF, 0xC3, 0x55, 0x0C, 0xF9, 0x4F, 0xE0, 0x37, 0xD8, 0xD6, 0xA8, + 0x84, 0x84, 0x04, 0x9E, 0x7E, 0xFA, 0x69, 0x3C, 0x3C, 0xDA, 0x7D, 0xFC, 0x1D, 0x8A, 0x5D, 0xBB, + 0x76, 0x51, 0x56, 0x56, 0x66, 0x3F, 0xAC, 0x42, 0xDA, 0xCC, 0xDA, 0x15, 0xAE, 0xD8, 0x81, 0x1A, + 0x81, 0xC7, 0xB1, 0x19, 0xE9, 0x12, 0x12, 0x12, 0xF8, 0xEC, 0xB3, 0xCF, 0xB8, 0xF9, 0xE6, 0x9B, + 0x5D, 0x44, 0xA6, 0x8E, 0x43, 0x5E, 0x5E, 0x23, 0xFA, 0x0B, 0x5C, 0xF7, 0x42, 0xB7, 0x2B, 0x46, + 0x21, 0x6D, 0x52, 0x42, 0xAF, 0xD7, 0x8B, 0x25, 0x4B, 0x96, 0x74, 0xB6, 0xE8, 0x6F, 0x37, 0xEC, + 0xDD, 0xBB, 0x57, 0x84, 0x86, 0x86, 0x3A, 0x2E, 0xEC, 0xB3, 0xDB, 0x9B, 0x78, 0xAE, 0xE0, 0x70, + 0x12, 0x72, 0x0D, 0xA1, 0x6B, 0xD7, 0xAE, 0x8C, 0x1D, 0x3B, 0xD6, 0x85, 0xBC, 0xEF, 0x58, 0x24, + 0x25, 0x25, 0x31, 0x64, 0x48, 0xA3, 0x3D, 0xE1, 0x2D, 0xB4, 0xB3, 0x94, 0x71, 0x05, 0x43, 0x22, + 0xED, 0x7F, 0x44, 0x47, 0x47, 0x13, 0x12, 0x12, 0xE2, 0x1A, 0xEA, 0x74, 0x02, 0x0C, 0x06, 0x03, + 0x89, 0x89, 0x89, 0x8E, 0x4D, 0x51, 0x48, 0x3B, 0x5D, 0xBB, 0xC1, 0x15, 0x0C, 0xA9, 0xEF, 0x53, + 0xA7, 0xD3, 0x35, 0x69, 0x00, 0xBC, 0x51, 0xE1, 0xEB, 0xEB, 0xEB, 0x78, 0x68, 0xE0, 0x06, 0x98, + 0x21, 0xF5, 0xCE, 0x88, 0xBC, 0xBC, 0x3C, 0x47, 0xAD, 0xE4, 0x17, 0x81, 0xD2, 0xD2, 0x52, 0xC7, + 0xC3, 0x6A, 0xDA, 0xD9, 0x57, 0xE2, 0x0A, 0x86, 0x1C, 0x46, 0xEE, 0xCE, 0xC9, 0xCA, 0xCA, 0x22, + 0x35, 0x35, 0xD5, 0x65, 0xC4, 0xE9, 0x68, 0x54, 0x55, 0x55, 0x91, 0x91, 0x91, 0xE1, 0xD8, 0x94, + 0x8D, 0x64, 0xCA, 0x75, 0x8D, 0x70, 0xE0, 0x67, 0x6C, 0x9A, 0xC8, 0xD0, 0xA1, 0x43, 0x45, 0x76, + 0x76, 0x76, 0x67, 0x2B, 0x48, 0xED, 0x82, 0x1F, 0x7E, 0xF8, 0x41, 0xF8, 0xF9, 0xF9, 0x39, 0x6A, + 0x59, 0x4F, 0x74, 0x36, 0xB1, 0x9D, 0xC5, 0x73, 0x48, 0xA3, 0x9B, 0x00, 0xC4, 0xC8, 0x91, 0x23, + 0xC5, 0x8F, 0x3F, 0xFE, 0x28, 0xCC, 0x66, 0xB3, 0xCB, 0x88, 0x65, 0xB5, 0x5A, 0x5D, 0xCA, 0x8C, + 0xAC, 0xAC, 0x2C, 0x31, 0x6C, 0xD8, 0x30, 0x47, 0x66, 0x64, 0x01, 0x71, 0x9D, 0x4D, 0x68, 0x67, + 0x61, 0x04, 0xD6, 0x39, 0x0C, 0x5E, 0xF8, 0xF8, 0xF8, 0x88, 0x05, 0x0B, 0x16, 0xB8, 0x84, 0x58, + 0x99, 0x99, 0x99, 0x62, 0xFA, 0xF4, 0xE9, 0x62, 0xD9, 0xB2, 0x65, 0xC2, 0x64, 0x32, 0x5D, 0x71, + 0x5E, 0xD3, 0x34, 0x71, 0xEE, 0xDC, 0x39, 0x91, 0x97, 0x97, 0xD7, 0xAA, 0xFE, 0x4F, 0x9E, 0x3C, + 0x29, 0x46, 0x8C, 0x18, 0x71, 0xB9, 0x09, 0xFE, 0xF5, 0xCE, 0x26, 0xB2, 0xB3, 0x08, 0x46, 0x5A, + 0x79, 0x1B, 0x31, 0x04, 0x10, 0x49, 0x49, 0x49, 0x22, 0x27, 0x27, 0xA7, 0x5D, 0x99, 0x61, 0xB5, + 0x5A, 0xC5, 0x8C, 0x19, 0x33, 0x04, 0x20, 0xBC, 0xBC, 0xBC, 0xC4, 0xA3, 0x8F, 0x3E, 0x2A, 0x36, + 0x6F, 0xDE, 0x2C, 0xCE, 0x9F, 0x3F, 0x2F, 0x0A, 0x0B, 0x0B, 0xC5, 0xE1, 0xC3, 0x87, 0xC5, 0xDC, + 0xB9, 0x73, 0x45, 0x42, 0x42, 0x82, 0x18, 0x33, 0x66, 0x8C, 0x28, 0x28, 0x28, 0x68, 0xF1, 0x3D, + 0x96, 0x2E, 0x5D, 0x7A, 0x39, 0x33, 0x34, 0x60, 0x3B, 0xF0, 0xDF, 0x40, 0x37, 0x64, 0x38, 0xD1, + 0x75, 0x87, 0x28, 0xA4, 0xEF, 0x79, 0x2F, 0x36, 0x93, 0x3B, 0x57, 0x09, 0x26, 0x98, 0x35, 0x6B, + 0x56, 0xBB, 0x8A, 0xAE, 0x6D, 0xDB, 0xB6, 0x89, 0xD0, 0xD0, 0x50, 0xE1, 0xED, 0x69, 0x10, 0xE1, + 0xC1, 0x01, 0x02, 0x10, 0x9E, 0x5E, 0x5E, 0xA2, 0x5B, 0xB7, 0xEE, 0xA2, 0x57, 0xAF, 0x5E, 0x22, + 0x38, 0x24, 0x44, 0x28, 0x8A, 0x22, 0x00, 0xE1, 0xE6, 0xE6, 0x26, 0x3E, 0xFA, 0xE8, 0xA3, 0x16, + 0xDF, 0x63, 0xCD, 0x9A, 0x35, 0x42, 0xAF, 0xD7, 0x5F, 0xCD, 0x51, 0x55, 0x87, 0x14, 0x5D, 0x0B, + 0x80, 0x5B, 0x01, 0xF7, 0xB6, 0x12, 0xB1, 0x3D, 0x38, 0x1B, 0x0A, 0x4C, 0x07, 0xE6, 0x21, 0x0D, + 0x8A, 0x5D, 0x70, 0xD0, 0xCD, 0x75, 0x3A, 0x1D, 0xE1, 0xE1, 0xE1, 0x24, 0x25, 0x25, 0x61, 0x36, + 0x9B, 0x49, 0x4D, 0x4D, 0xC5, 0x64, 0x32, 0xD1, 0xB7, 0x6F, 0x5F, 0x7C, 0x7C, 0x7C, 0x00, 0x19, + 0xB4, 0x50, 0x50, 0x50, 0x40, 0x59, 0x59, 0x19, 0xBE, 0xBE, 0xBE, 0x28, 0x8A, 0x73, 0x7E, 0xB3, + 0xEC, 0xEC, 0x6C, 0x9E, 0x7E, 0xFA, 0x69, 0x8E, 0x1D, 0x3B, 0xC6, 0x8C, 0x87, 0xC7, 0x31, 0x77, + 0xC6, 0x14, 0x02, 0xFD, 0x7C, 0xA8, 0xAA, 0x36, 0x51, 0x5A, 0x5A, 0x42, 0x65, 0x45, 0x39, 0x81, + 0x3E, 0x06, 0xEE, 0xFC, 0x55, 0x7F, 0x86, 0x0D, 0x48, 0x20, 0xFD, 0xE8, 0x69, 0xB2, 0xB3, 0xCF, + 0x72, 0xC7, 0x1D, 0x77, 0xB4, 0xC8, 0xF2, 0xBC, 0x7E, 0xFD, 0x7A, 0x36, 0x6C, 0xD8, 0x80, 0x9F, + 0x9F, 0x1F, 0x3A, 0x9D, 0x0E, 0x8B, 0xA5, 0x5E, 0xD3, 0x55, 0x91, 0xC1, 0x78, 0x83, 0x81, 0xFB, + 0x81, 0xDE, 0x40, 0x11, 0xD2, 0xE8, 0xA8, 0xB5, 0x03, 0x6D, 0x5B, 0x04, 0x37, 0xA4, 0x68, 0x4A, + 0x45, 0xBE, 0x29, 0x8D, 0x66, 0x42, 0x97, 0x2E, 0x5D, 0xC4, 0x23, 0x8F, 0x3C, 0x22, 0x3E, 0xF9, + 0xE4, 0x13, 0x71, 0xEC, 0xD8, 0x31, 0x51, 0x55, 0x55, 0x25, 0x5E, 0x7A, 0xE9, 0x25, 0x01, 0x08, + 0x9D, 0x4E, 0x27, 0x06, 0x0E, 0x1A, 0x24, 0x66, 0xCF, 0x9E, 0x2D, 0xE6, 0xCF, 0x9F, 0x2F, 0x66, + 0xCE, 0x9C, 0x29, 0xFA, 0xF4, 0xE9, 0x23, 0x7A, 0xF7, 0xEE, 0x2D, 0xD6, 0xAC, 0x59, 0xE3, 0xD4, + 0x02, 0x9D, 0x99, 0x99, 0x29, 0xC6, 0x8D, 0x1B, 0x27, 0x95, 0x86, 0x9B, 0x13, 0x45, 0xEE, 0x86, + 0x25, 0x42, 0x64, 0xAC, 0x16, 0x5A, 0xFA, 0x2A, 0x51, 0xB6, 0xED, 0x63, 0x71, 0xFA, 0x9B, 0x05, + 0xE2, 0xF8, 0xD7, 0xF3, 0xC5, 0x85, 0x0D, 0xEF, 0x0B, 0xCB, 0xDE, 0x15, 0xA2, 0x74, 0xFB, 0x27, + 0x62, 0xFC, 0xB0, 0x41, 0x02, 0x10, 0x77, 0xDF, 0x7D, 0xB7, 0x38, 0x7A, 0xF4, 0x68, 0xA3, 0xFE, + 0x34, 0x4D, 0x13, 0xFB, 0xF7, 0xEF, 0x17, 0x6F, 0xBD, 0xF5, 0x96, 0xD8, 0xBD, 0x7B, 0xB7, 0xB0, + 0x58, 0x2C, 0xC2, 0x62, 0xB1, 0x88, 0x6D, 0xDB, 0xB6, 0x89, 0xB8, 0xB8, 0x38, 0xE1, 0xEE, 0xEE, + 0x2E, 0xDE, 0x7B, 0xEF, 0x3D, 0xB1, 0x69, 0xD3, 0x26, 0xF1, 0xDC, 0x73, 0xCF, 0x89, 0x7E, 0xFD, + 0xFA, 0x09, 0x77, 0x77, 0xF7, 0xAB, 0xCD, 0x9A, 0x12, 0xE0, 0x03, 0x64, 0x10, 0x60, 0x87, 0xC5, + 0xBD, 0x45, 0x20, 0x67, 0x44, 0x99, 0xE3, 0x60, 0x74, 0x3A, 0x9D, 0x48, 0x4A, 0x4A, 0x12, 0x6F, + 0xBE, 0xF9, 0xA6, 0x38, 0x76, 0xEC, 0x98, 0xB0, 0x58, 0x2C, 0xF5, 0x0F, 0x6C, 0x32, 0x99, 0xC4, + 0xA4, 0x49, 0x93, 0x04, 0x20, 0xBA, 0x84, 0x1A, 0x85, 0xA7, 0xC1, 0xAD, 0xD1, 0x83, 0x78, 0xB8, + 0xBB, 0x09, 0x9D, 0xAA, 0x8A, 0xA0, 0xA0, 0x20, 0xF1, 0xDA, 0x6B, 0xAF, 0x89, 0xB3, 0x67, 0xCF, + 0x5E, 0x35, 0x10, 0xA2, 0xA2, 0xA2, 0x42, 0xAC, 0x5C, 0xB9, 0x52, 0x0C, 0x18, 0x30, 0x40, 0x00, + 0xE2, 0x96, 0xDE, 0xDD, 0xC5, 0xC1, 0x95, 0x6F, 0x0B, 0xB1, 0xFF, 0x6B, 0x21, 0xD2, 0xBE, 0x92, + 0xBF, 0xF4, 0x55, 0x42, 0xEC, 0x5F, 0x25, 0xDB, 0xD2, 0x57, 0xC9, 0xB6, 0xFD, 0x5F, 0x8B, 0xC3, + 0x5F, 0xFD, 0x5D, 0x0C, 0x4E, 0xEC, 0x21, 0x00, 0xD1, 0xA3, 0x47, 0x0F, 0xF1, 0x87, 0x3F, 0xFC, + 0x41, 0xAC, 0x5A, 0xB5, 0x4A, 0xAC, 0x5C, 0xB9, 0x52, 0xCC, 0x9A, 0x35, 0x4B, 0xC4, 0xC4, 0xC4, + 0x08, 0x40, 0x84, 0x87, 0x87, 0x8B, 0xFB, 0xEE, 0xBB, 0x4F, 0x4C, 0x9C, 0x38, 0xB1, 0xDE, 0x98, + 0x38, 0x79, 0xF2, 0xE4, 0xFA, 0x60, 0x0B, 0x4D, 0xD3, 0x44, 0x7E, 0x7E, 0xBE, 0x58, 0xBE, 0x7C, + 0xB9, 0x18, 0x3F, 0x7E, 0xBC, 0xF0, 0xF5, 0xF5, 0xBD, 0x1A, 0x63, 0xCE, 0x21, 0x8D, 0x8F, 0xC1, + 0x2D, 0x21, 0x6C, 0x4B, 0x39, 0xA8, 0x20, 0x83, 0x9E, 0x5F, 0x07, 0x86, 0x39, 0x5E, 0x1F, 0x17, + 0x17, 0xC7, 0xF4, 0xE9, 0xD3, 0x49, 0x4E, 0x4E, 0x26, 0x32, 0x32, 0xF2, 0x8A, 0x0B, 0x77, 0xEC, + 0xD8, 0xC1, 0x84, 0x09, 0x13, 0xF0, 0xD4, 0x2B, 0x2C, 0xFF, 0xDB, 0x33, 0x58, 0xEA, 0xEA, 0x48, + 0x3B, 0x7A, 0x9A, 0xD2, 0x8A, 0x4B, 0x04, 0x07, 0xF8, 0x31, 0xA8, 0x57, 0x37, 0x52, 0x7F, 0x3E, + 0xCE, 0x3F, 0x96, 0xAF, 0xA7, 0xEC, 0x52, 0x35, 0x71, 0xF1, 0xF1, 0xDC, 0x39, 0x76, 0x2C, 0x03, + 0x07, 0x0E, 0x24, 0x28, 0x28, 0x88, 0xAA, 0xAA, 0x2A, 0x4E, 0x9C, 0x38, 0xC1, 0x96, 0x2D, 0x5B, + 0xD8, 0xB3, 0x67, 0x0F, 0x96, 0xDA, 0x5A, 0xEE, 0xBA, 0xAD, 0x3F, 0x73, 0x9F, 0x99, 0x42, 0xAF, + 0x6E, 0xD1, 0xA0, 0x39, 0x21, 0x21, 0x54, 0x95, 0x13, 0x67, 0xCE, 0xF3, 0xA7, 0x25, 0xAB, 0xF8, + 0x76, 0x7B, 0x1A, 0x55, 0xE6, 0x1A, 0xDB, 0x23, 0x08, 0x00, 0x02, 0x7C, 0xBD, 0x49, 0xEA, 0x19, + 0xC3, 0xD1, 0xAC, 0xF3, 0x14, 0x97, 0x55, 0xA2, 0x28, 0x0A, 0xE1, 0xE1, 0xE1, 0x24, 0x27, 0x27, + 0x33, 0x7B, 0xF6, 0x6C, 0xC2, 0xC2, 0xC2, 0xAE, 0xE8, 0xB2, 0xBA, 0xBA, 0x9A, 0xD4, 0xD4, 0x54, + 0x96, 0x2E, 0x5D, 0xCA, 0xF7, 0xDF, 0x7F, 0x4F, 0x65, 0x65, 0xA5, 0xE3, 0x69, 0x2B, 0xB0, 0x03, + 0xF8, 0x13, 0x90, 0x82, 0x13, 0x62, 0xAC, 0x25, 0x0C, 0x71, 0x03, 0x26, 0x03, 0x7F, 0x41, 0xAE, + 0x13, 0x80, 0xB4, 0xED, 0x4C, 0x99, 0x32, 0x85, 0x99, 0x33, 0x67, 0xD2, 0xA3, 0x47, 0x8F, 0xAB, + 0x5E, 0x28, 0x84, 0x60, 0xC6, 0x8C, 0x19, 0x2C, 0x58, 0xB0, 0x80, 0xA9, 0xF7, 0x8E, 0x64, 0xC9, + 0x2B, 0xBF, 0xB3, 0x79, 0xDE, 0x84, 0xA4, 0x85, 0x22, 0x87, 0x52, 0x67, 0xA9, 0x63, 0xEB, 0xDE, + 0x43, 0xFC, 0x73, 0xE5, 0xF7, 0x6C, 0x4F, 0x3F, 0x42, 0x65, 0xB5, 0x59, 0x0E, 0x52, 0x51, 0x11, + 0x42, 0x3E, 0x8B, 0x5E, 0xA7, 0x92, 0xD8, 0x2D, 0x9A, 0x69, 0x13, 0x47, 0x32, 0xE5, 0x9E, 0xFF, + 0x20, 0xD0, 0xDF, 0xD7, 0x39, 0x66, 0x38, 0x30, 0xA5, 0xDA, 0x64, 0x66, 0xD7, 0x81, 0x13, 0x6C, + 0xD9, 0x77, 0x98, 0xAC, 0xDC, 0x02, 0x54, 0x45, 0xA1, 0x67, 0x4C, 0x04, 0x63, 0x6E, 0x4D, 0x62, + 0x50, 0xAF, 0x6E, 0x7C, 0xBA, 0x6E, 0x3B, 0x4F, 0xCE, 0x59, 0x4A, 0x78, 0x44, 0x24, 0x5F, 0x7E, + 0xF9, 0x25, 0x43, 0x87, 0x0E, 0x45, 0xA7, 0xBB, 0xF6, 0x72, 0x6B, 0x36, 0x9B, 0xD9, 0xB6, 0x6D, + 0x1B, 0x0B, 0x17, 0x2E, 0x64, 0xD3, 0xA6, 0x4D, 0x8E, 0x81, 0x76, 0x20, 0xE3, 0xBA, 0xDE, 0x04, + 0x96, 0xD0, 0xCC, 0xCE, 0xDE, 0x59, 0x86, 0xF8, 0x02, 0xFF, 0x0B, 0x3C, 0x83, 0x0C, 0x09, 0x05, + 0x20, 0x31, 0x31, 0x91, 0x3F, 0xFE, 0xF1, 0x8F, 0xDC, 0x7B, 0xEF, 0xBD, 0xB8, 0xBB, 0x37, 0xAD, + 0x60, 0x9C, 0x39, 0x73, 0x86, 0x31, 0x63, 0xC7, 0x92, 0x9B, 0x73, 0x96, 0x7F, 0xCD, 0x7B, 0x9E, + 0xBB, 0x6E, 0x1F, 0x08, 0xD6, 0x26, 0x88, 0xA8, 0x53, 0xA9, 0xAA, 0x32, 0xF1, 0xF3, 0xF1, 0x33, + 0xEC, 0x3C, 0x70, 0x82, 0xE3, 0xD9, 0xB9, 0x54, 0x5C, 0xAA, 0xC6, 0xD3, 0xC3, 0x40, 0x4C, 0x78, + 0x30, 0x83, 0x13, 0xBB, 0x33, 0xA4, 0x6F, 0x1C, 0xE1, 0x21, 0x81, 0x36, 0xE1, 0x20, 0x9C, 0x67, + 0x86, 0xE3, 0x53, 0xAB, 0x2A, 0x08, 0xD0, 0xEA, 0xAC, 0xA0, 0x80, 0xAA, 0xD3, 0xD5, 0x4F, 0x96, + 0xBC, 0xA2, 0x52, 0xEE, 0x7A, 0xF2, 0xAF, 0x1C, 0x3D, 0x9B, 0xC7, 0x8A, 0xE5, 0xCB, 0x99, 0x34, + 0x69, 0x92, 0xD3, 0x5D, 0x57, 0x56, 0x56, 0xB2, 0x62, 0xC5, 0x0A, 0xE6, 0xCD, 0x9B, 0xC7, 0x89, + 0x13, 0x27, 0x1C, 0x4F, 0xD5, 0x00, 0xCB, 0x80, 0x57, 0x81, 0xE2, 0xB6, 0x30, 0x24, 0x10, 0x29, + 0xA2, 0xFE, 0x0B, 0x9B, 0xF6, 0xA4, 0xD7, 0xEB, 0x79, 0xE0, 0x81, 0x07, 0xF8, 0xF3, 0x9F, 0xFF, + 0x4C, 0x7C, 0x7C, 0x7C, 0xB3, 0x1D, 0x2C, 0x59, 0xB2, 0x84, 0xE9, 0xD3, 0xA7, 0x33, 0x6C, 0x40, + 0x02, 0xDF, 0xBE, 0xF3, 0x02, 0x01, 0xBE, 0xDE, 0xD7, 0x26, 0xA4, 0x9D, 0x60, 0x80, 0xB0, 0x6A, + 0x68, 0x9A, 0x86, 0xAA, 0x28, 0x28, 0x3A, 0x1D, 0x28, 0x8A, 0x9C, 0x11, 0xAD, 0x61, 0x84, 0xB3, + 0x50, 0x14, 0x5E, 0x5A, 0xB4, 0x9C, 0xBF, 0x2D, 0x5B, 0x43, 0x72, 0x72, 0x32, 0x9F, 0x7E, 0xFA, + 0x29, 0x6E, 0x6E, 0x6E, 0x2D, 0xEA, 0x22, 0x33, 0x33, 0x93, 0xD7, 0x5F, 0x7F, 0x9D, 0x15, 0x2B, + 0x56, 0x38, 0xCE, 0x16, 0x0D, 0x19, 0x01, 0x39, 0x13, 0x99, 0xCB, 0x72, 0x05, 0x9A, 0x33, 0x2E, + 0x86, 0x00, 0xFF, 0x40, 0xAA, 0xB5, 0x7A, 0x90, 0x22, 0xEA, 0x85, 0x17, 0x5E, 0x60, 0xC9, 0x92, + 0x25, 0x4E, 0x31, 0xC3, 0x6C, 0x36, 0xB3, 0x6E, 0xDD, 0x3A, 0x00, 0x26, 0x0C, 0xBF, 0x99, 0x00, + 0x7F, 0x9F, 0xE6, 0x89, 0x29, 0x90, 0x33, 0xC8, 0xAA, 0xA1, 0x00, 0x3A, 0x55, 0x95, 0xAA, 0xB0, + 0xA6, 0x81, 0xD5, 0xEA, 0x5A, 0x66, 0x00, 0xA8, 0x0A, 0x13, 0x86, 0x0F, 0x22, 0xC0, 0xD7, 0x8B, + 0x94, 0x94, 0x14, 0x32, 0x33, 0x33, 0x5B, 0xDC, 0x45, 0xCF, 0x9E, 0x3D, 0x59, 0xBC, 0x78, 0x31, + 0x73, 0xE6, 0xCC, 0x71, 0xF4, 0x09, 0xA9, 0xC0, 0x43, 0xC8, 0x7D, 0x4B, 0xC4, 0x55, 0x6F, 0x7D, + 0x8D, 0x3E, 0x8D, 0x34, 0xEC, 0x2D, 0x54, 0x80, 0x90, 0x90, 0x10, 0xDE, 0x79, 0xE7, 0x1D, 0x5E, + 0x7D, 0xF5, 0x55, 0xFC, 0xFD, 0xFD, 0x9D, 0x1A, 0xD8, 0xF1, 0xE3, 0xC7, 0xF9, 0x69, 0xF7, 0x6E, + 0x42, 0x02, 0xFD, 0x18, 0x3B, 0xA4, 0x9F, 0x7D, 0xFD, 0xBC, 0xBE, 0xA1, 0x69, 0xF4, 0xED, 0x11, + 0xC3, 0x2D, 0x89, 0x3D, 0xB8, 0x70, 0xE1, 0x02, 0x5B, 0xB7, 0x6E, 0x6D, 0x55, 0x37, 0x5E, 0x5E, + 0x5E, 0x3C, 0xF5, 0xD4, 0x53, 0x7C, 0xF0, 0xC1, 0x07, 0xC4, 0xC6, 0xC6, 0x3A, 0x9E, 0xBA, 0x1F, + 0x98, 0x03, 0x5C, 0x41, 0xC4, 0xA6, 0x18, 0xE2, 0x89, 0x4C, 0x1D, 0x98, 0x8C, 0x4D, 0xAC, 0x45, + 0x45, 0x45, 0xB1, 0x68, 0xD1, 0x22, 0xA6, 0x4D, 0x9B, 0xD6, 0xA2, 0xE9, 0xBB, 0x7D, 0xFB, 0x76, + 0x8A, 0x8B, 0x8A, 0xB8, 0xB5, 0x4F, 0x4F, 0xE2, 0xBB, 0x46, 0xB6, 0x6C, 0x01, 0xEE, 0x2C, 0x08, + 0xF0, 0xF6, 0xF6, 0x64, 0xDC, 0xD0, 0x01, 0x00, 0x6C, 0xD8, 0xB0, 0x01, 0xB3, 0xD9, 0xDC, 0xAA, + 0xAE, 0x54, 0x55, 0x65, 0xE2, 0xC4, 0x89, 0x2C, 0x5D, 0xBA, 0xF4, 0x72, 0xA5, 0xE7, 0x11, 0xE4, + 0xBA, 0xDC, 0xC8, 0xC1, 0x75, 0x35, 0x86, 0x28, 0xC0, 0xFF, 0x20, 0xC5, 0x94, 0x0A, 0x92, 0x19, + 0xEF, 0xBE, 0xFB, 0x2E, 0x0F, 0x3D, 0xF4, 0x90, 0xD3, 0xBB, 0x68, 0x90, 0xE2, 0x6A, 0xD3, 0xA6, + 0x4D, 0x00, 0x8C, 0x19, 0x92, 0x84, 0x87, 0xE7, 0x8D, 0x11, 0x42, 0x0A, 0x80, 0x80, 0x11, 0x83, + 0x12, 0x09, 0xF2, 0xF7, 0x21, 0x2D, 0x2D, 0x9D, 0xAC, 0xAC, 0xAC, 0x36, 0x75, 0x37, 0x6A, 0xD4, + 0x28, 0x16, 0x2D, 0x5A, 0x44, 0x54, 0x54, 0x94, 0xBD, 0x49, 0x87, 0xCC, 0x0A, 0xB8, 0xDF, 0xF1, + 0xFF, 0xAE, 0xC6, 0x90, 0x31, 0xC8, 0x0D, 0x8D, 0x01, 0xC0, 0x68, 0x34, 0x32, 0x6F, 0xDE, 0xBC, + 0x46, 0xF9, 0x19, 0xCE, 0x22, 0x3B, 0x3B, 0x9B, 0xF4, 0xFD, 0xFB, 0x09, 0xF2, 0xF7, 0x61, 0xF8, + 0x80, 0x5E, 0x37, 0x86, 0xB8, 0xB2, 0x43, 0x68, 0xC4, 0xC5, 0x44, 0x30, 0x20, 0x3E, 0x96, 0xFC, + 0xFC, 0x3C, 0x76, 0xED, 0xDA, 0xD5, 0xE6, 0x2E, 0xC7, 0x8E, 0x1D, 0xCB, 0x1B, 0x6F, 0xBC, 0xE1, + 0xE8, 0x06, 0xF6, 0x43, 0x66, 0x89, 0xDD, 0x64, 0x6F, 0xB8, 0x9C, 0x21, 0x91, 0x48, 0x51, 0x15, + 0x0A, 0xD2, 0xA9, 0xFF, 0xF2, 0xCB, 0x2F, 0xF3, 0xD0, 0x43, 0x0F, 0xB5, 0x6A, 0x00, 0xE9, 0xE9, + 0xE9, 0xE4, 0x5D, 0xC8, 0xA3, 0x4F, 0xF7, 0x18, 0x7A, 0x44, 0x87, 0x3B, 0xBF, 0x18, 0xAB, 0x2A, + 0xA8, 0xAA, 0x4C, 0xCC, 0x01, 0xD0, 0xA9, 0x52, 0xBB, 0x6A, 0x2D, 0x54, 0x05, 0x54, 0x15, 0xAB, + 0xA6, 0x61, 0xD5, 0xB4, 0xFA, 0xFE, 0xAF, 0x09, 0x01, 0x5E, 0x5E, 0x9E, 0x0C, 0x1F, 0xD8, 0x1B, + 0x80, 0x9D, 0x3B, 0x77, 0xA2, 0xB5, 0x83, 0xB8, 0x4D, 0x4E, 0x4E, 0x66, 0xFA, 0xF4, 0xE9, 0x8E, + 0x4D, 0xFD, 0x90, 0x41, 0xDB, 0x2A, 0x34, 0x96, 0x5F, 0x0A, 0x32, 0x21, 0xE5, 0x36, 0x7B, 0xC3, + 0x23, 0x8F, 0x3C, 0xC2, 0xF4, 0xE9, 0xD3, 0x5B, 0x1D, 0xA8, 0x20, 0xDD, 0xB7, 0x82, 0xDB, 0xFA, + 0xC5, 0xE3, 0xE3, 0xED, 0x09, 0x5A, 0x33, 0x0C, 0x51, 0x14, 0xAC, 0x9A, 0x46, 0xFA, 0xA1, 0x93, + 0xFC, 0x7B, 0xE7, 0x7E, 0x4E, 0x9D, 0xCB, 0xC7, 0xDB, 0xD3, 0xC0, 0x6D, 0x49, 0xF1, 0x8C, 0xBB, + 0x7D, 0x20, 0xA1, 0x41, 0x01, 0x2D, 0x5F, 0x83, 0x14, 0x85, 0x53, 0x39, 0x79, 0xFC, 0x6B, 0xCB, + 0x5E, 0xD2, 0x8F, 0x67, 0x61, 0xB5, 0x6A, 0x24, 0x76, 0x8F, 0xE6, 0xFE, 0x11, 0xB7, 0xD0, 0x37, + 0xEE, 0xA6, 0x6B, 0xAB, 0x99, 0x8A, 0xC2, 0xAD, 0x7D, 0x7B, 0xE2, 0xAE, 0xD7, 0x91, 0x91, 0x91, + 0x41, 0x49, 0x49, 0x49, 0x9B, 0xA3, 0x68, 0xDC, 0xDC, 0xDC, 0x78, 0xE6, 0x99, 0x67, 0x48, 0x49, + 0x49, 0x61, 0xEF, 0xDE, 0xBD, 0xF6, 0xE6, 0xC9, 0xC0, 0x72, 0x60, 0xBF, 0x23, 0x43, 0xFA, 0x03, + 0x53, 0xED, 0x07, 0x7D, 0xFA, 0xF4, 0xE1, 0xC5, 0x17, 0x5F, 0xC4, 0xCB, 0xCB, 0xCB, 0xE9, 0x9B, + 0x39, 0xA2, 0xAC, 0xAC, 0x8C, 0xFD, 0xFB, 0xF7, 0xA3, 0x53, 0x15, 0x86, 0xF4, 0xED, 0x09, 0x8A, + 0x4A, 0x73, 0x91, 0xFB, 0xB5, 0x96, 0x3A, 0x16, 0xAE, 0xFC, 0x9E, 0x39, 0x1F, 0x7F, 0x43, 0xE1, + 0xC5, 0xF2, 0xFA, 0xF6, 0x65, 0xDF, 0x6C, 0x65, 0xD8, 0x80, 0x04, 0xDE, 0x79, 0x76, 0x2A, 0xFD, + 0x13, 0x62, 0x9D, 0x67, 0x8A, 0xA2, 0xF0, 0x7D, 0xEA, 0x7E, 0x9E, 0x7D, 0xE7, 0x53, 0x8E, 0x9D, + 0x69, 0x50, 0xFB, 0xBF, 0xDE, 0xBC, 0x9B, 0x0F, 0xD7, 0x6E, 0xE6, 0x2F, 0xFF, 0x93, 0xCC, 0xA3, + 0xE3, 0xFF, 0x03, 0xB5, 0xA9, 0xD9, 0xA7, 0x69, 0xF4, 0x8E, 0xED, 0x42, 0xD7, 0x88, 0x10, 0x4E, + 0x67, 0x65, 0x71, 0xF2, 0xE4, 0xC9, 0x76, 0x09, 0x6B, 0x8A, 0x8A, 0x8A, 0x62, 0xE6, 0xCC, 0x99, + 0x4C, 0x9D, 0x3A, 0xD5, 0xAE, 0x2C, 0x44, 0x00, 0x8F, 0x02, 0x19, 0xF6, 0x17, 0x44, 0x05, 0xA6, + 0x61, 0x33, 0x89, 0xB8, 0xBB, 0xBB, 0x33, 0x6B, 0xD6, 0xAC, 0x26, 0x4D, 0x21, 0xCE, 0xE0, 0xEC, + 0xD9, 0xB3, 0x64, 0x9E, 0x3A, 0x45, 0x44, 0x70, 0x20, 0xBD, 0xBB, 0x75, 0x01, 0xD1, 0x0C, 0x11, + 0x55, 0x95, 0x55, 0x9B, 0x7E, 0xE2, 0xD5, 0xF7, 0xBE, 0x6A, 0xC4, 0x0C, 0x2F, 0x2F, 0x2F, 0xFC, + 0xFC, 0xFD, 0xD9, 0x96, 0x7E, 0x94, 0x67, 0xDE, 0xFE, 0x88, 0x82, 0xE2, 0x8B, 0xCE, 0x89, 0x2F, + 0x55, 0xE5, 0xF0, 0xE9, 0x1C, 0x66, 0xBC, 0xFD, 0x71, 0x23, 0x66, 0x18, 0x0C, 0x06, 0xC2, 0xC2, + 0xC2, 0x28, 0x2C, 0xAB, 0xE2, 0xF9, 0x7F, 0x7C, 0xCE, 0x96, 0x7D, 0x87, 0x9B, 0x16, 0x5F, 0x42, + 0x10, 0x1E, 0xE4, 0x4F, 0xBF, 0xB8, 0x9B, 0xA8, 0xBA, 0x74, 0x89, 0xB4, 0xB4, 0xB4, 0x36, 0x33, + 0xC3, 0x8E, 0x71, 0xE3, 0xC6, 0x31, 0x7C, 0xF8, 0x70, 0xC7, 0xA6, 0x7B, 0x80, 0x04, 0xFB, 0x48, + 0x12, 0x80, 0xFB, 0xEC, 0x67, 0x46, 0x8C, 0x18, 0xC1, 0x03, 0x0F, 0x3C, 0xD0, 0xA6, 0x1B, 0x1E, + 0x3D, 0x7A, 0x94, 0xD2, 0x92, 0x12, 0xE2, 0xBB, 0x46, 0x12, 0x19, 0x62, 0xBC, 0xB6, 0xB8, 0x52, + 0x14, 0xCA, 0x2B, 0x2E, 0xF1, 0xFE, 0xEA, 0x8D, 0x54, 0x99, 0x1A, 0xD4, 0xCB, 0xBE, 0x7D, 0xFB, + 0xB2, 0x72, 0xE5, 0x4A, 0x36, 0x6F, 0xDE, 0xCC, 0x13, 0x4F, 0x3C, 0xC1, 0x4F, 0x87, 0x32, 0xF9, + 0x2E, 0x25, 0x4D, 0xAE, 0x09, 0xCD, 0x41, 0x08, 0xBE, 0x58, 0xBF, 0x83, 0xCC, 0x9C, 0x86, 0x78, + 0x5C, 0xA3, 0xD1, 0xC8, 0xFC, 0xF9, 0xF3, 0x49, 0x49, 0x49, 0xE1, 0xBD, 0xF7, 0xDE, 0x45, 0xE8, + 0xDD, 0xF9, 0x60, 0xCD, 0x26, 0x2C, 0xB5, 0x4D, 0x47, 0xF2, 0xE8, 0xDD, 0xDD, 0xE4, 0x0C, 0x07, + 0xF6, 0xEC, 0xD9, 0xE3, 0x98, 0xB0, 0xD3, 0x26, 0xF8, 0xF9, 0xF9, 0x31, 0x79, 0xF2, 0x64, 0xC7, + 0x68, 0xFA, 0x58, 0x60, 0xBC, 0x9D, 0x21, 0xE3, 0xB1, 0xCD, 0x0E, 0x83, 0xC1, 0xC0, 0xB4, 0x69, + 0xD3, 0x9C, 0xDE, 0xF8, 0x35, 0x85, 0x43, 0x87, 0x0E, 0x01, 0x90, 0xD8, 0x3D, 0x06, 0x2F, 0x8F, + 0x66, 0xD4, 0x5D, 0x45, 0xE1, 0x6C, 0x5E, 0x11, 0xC7, 0xCE, 0x9C, 0x6F, 0xD4, 0xFC, 0xE4, 0x93, + 0x4F, 0x32, 0x7E, 0xFC, 0x78, 0x06, 0x0C, 0x18, 0xC0, 0x8B, 0x2F, 0xBE, 0x48, 0x74, 0xD7, 0x9B, + 0x48, 0xFD, 0xF9, 0x78, 0xD3, 0x76, 0x30, 0x07, 0x98, 0xCC, 0x35, 0xEC, 0x3D, 0x72, 0xAA, 0x51, + 0xDB, 0x98, 0x31, 0x63, 0x78, 0xFC, 0xF1, 0xC7, 0x89, 0x8B, 0x8B, 0xE3, 0xB1, 0xC7, 0x1E, 0x63, + 0xC2, 0x84, 0x09, 0xA4, 0x1F, 0x3B, 0x4D, 0x71, 0x59, 0xE5, 0x35, 0x66, 0x9D, 0x42, 0xBF, 0xB8, + 0x9B, 0x70, 0xD7, 0xEB, 0x38, 0x7E, 0xFC, 0x38, 0xE5, 0xE5, 0xE5, 0xCD, 0xDE, 0xDB, 0x59, 0x8C, + 0x1A, 0x35, 0x8A, 0xEE, 0xDD, 0xEB, 0x73, 0x7E, 0x74, 0xC0, 0x44, 0x15, 0xB9, 0x5B, 0xBC, 0xDB, + 0xDE, 0xDA, 0xB7, 0x6F, 0x5F, 0x46, 0x8F, 0x1E, 0xDD, 0xA6, 0x1B, 0x59, 0x2C, 0x16, 0x8E, 0x1E, + 0x3D, 0x2A, 0xFB, 0xEB, 0x11, 0xD3, 0xBC, 0x46, 0xA3, 0x80, 0xB9, 0xD6, 0x42, 0xAD, 0xA5, 0xF1, + 0xDB, 0x27, 0x1C, 0xB4, 0x32, 0x21, 0x04, 0x08, 0x41, 0xB5, 0xB9, 0x06, 0xAD, 0x39, 0x6D, 0x4D, + 0x01, 0xAB, 0x55, 0xC3, 0x5C, 0xD3, 0xF8, 0xCD, 0xB7, 0x58, 0x2C, 0xF5, 0x9A, 0x92, 0xA6, 0x69, + 0xD4, 0xD6, 0xD6, 0x52, 0x6B, 0xA9, 0xA3, 0xCE, 0x6A, 0x6D, 0xDA, 0xAA, 0x27, 0x34, 0x62, 0x23, + 0x43, 0x09, 0x35, 0xFA, 0x93, 0x9D, 0x9D, 0x4D, 0x4A, 0x4A, 0x0A, 0x15, 0x15, 0x15, 0x8D, 0xC6, + 0xD6, 0x52, 0x54, 0x57, 0x57, 0x93, 0x9E, 0x9E, 0xCE, 0xFB, 0xEF, 0xBF, 0x7F, 0x79, 0xE0, 0x5D, + 0x92, 0x1E, 0x48, 0x44, 0x66, 0xCA, 0x02, 0x70, 0xF7, 0xDD, 0x77, 0x13, 0x1C, 0xDC, 0x22, 0x9F, + 0xCA, 0x15, 0xA8, 0xA8, 0xA8, 0xE0, 0xCC, 0x99, 0x33, 0x78, 0xB8, 0xEB, 0xE9, 0x19, 0x13, 0x4E, + 0xB3, 0x1B, 0x10, 0x21, 0x08, 0x0F, 0x0A, 0x20, 0xD4, 0xE8, 0x47, 0x45, 0x55, 0x83, 0x75, 0x7A, + 0xD1, 0xA2, 0x45, 0x44, 0x44, 0x44, 0x10, 0x15, 0x15, 0xC5, 0x87, 0x1F, 0x7E, 0xC8, 0xE9, 0xAC, + 0xD3, 0x3C, 0x3C, 0xA2, 0x9F, 0xB4, 0xCC, 0x5E, 0x6B, 0x61, 0x17, 0xE0, 0xE5, 0x61, 0xA0, 0x47, + 0x74, 0x38, 0xBB, 0x0E, 0x36, 0x58, 0x5C, 0x37, 0x6E, 0xDC, 0xC8, 0xDC, 0xB9, 0x73, 0x19, 0x33, + 0x66, 0x0C, 0x3B, 0x76, 0xEC, 0xE0, 0xBB, 0xEF, 0xD6, 0x31, 0xA0, 0x47, 0x24, 0x81, 0xBE, 0xDE, + 0x4D, 0x0F, 0x51, 0x40, 0xA8, 0xD1, 0x9F, 0xAE, 0x11, 0x21, 0xA4, 0x1E, 0x38, 0xC1, 0x6F, 0x7F, + 0xFB, 0x5B, 0x12, 0x12, 0x12, 0x18, 0x32, 0x64, 0x08, 0x83, 0x07, 0x0F, 0xA6, 0x7B, 0xF7, 0xEE, + 0x44, 0x45, 0x45, 0x11, 0x18, 0x18, 0x88, 0xC1, 0x60, 0x40, 0xA7, 0xD3, 0xD5, 0x6F, 0x9E, 0x35, + 0x4D, 0xC3, 0x62, 0xB1, 0x50, 0x5D, 0x5D, 0x4D, 0x71, 0x71, 0x31, 0xA7, 0x4F, 0x9F, 0x26, 0x2D, + 0x2D, 0x8D, 0x94, 0x94, 0x14, 0x32, 0x32, 0x32, 0x28, 0x2E, 0xBE, 0xC2, 0xE8, 0x9B, 0xAB, 0x47, + 0xAA, 0xB9, 0x46, 0x00, 0x6F, 0x6F, 0x6F, 0x46, 0x8C, 0x18, 0xD1, 0x26, 0x66, 0x00, 0x14, 0x14, + 0x14, 0x90, 0x97, 0x9F, 0x4F, 0x90, 0xBF, 0x2F, 0x51, 0xA1, 0xC6, 0xE6, 0x37, 0x84, 0x9A, 0xA0, + 0x4B, 0x58, 0x10, 0xE3, 0x6E, 0x1F, 0xC8, 0x3F, 0x97, 0xAF, 0xAF, 0x6F, 0x3E, 0x7C, 0xF8, 0x30, + 0x0F, 0x3F, 0xFC, 0x30, 0xEE, 0xEE, 0xEE, 0x94, 0x57, 0x54, 0x10, 0x66, 0xF4, 0x63, 0xC2, 0xF0, + 0x41, 0x4E, 0x8D, 0x41, 0x75, 0xD3, 0x31, 0x69, 0xF4, 0xAD, 0xAC, 0xD9, 0xBA, 0x87, 0x4B, 0x36, + 0xBF, 0x4A, 0x65, 0x65, 0x25, 0xAF, 0xBD, 0xF6, 0x1A, 0x73, 0xE6, 0xCC, 0xA1, 0xBA, 0xBA, 0x1A, + 0x10, 0x3C, 0x74, 0xC7, 0x6D, 0xF8, 0xF8, 0x78, 0x35, 0xCD, 0x60, 0x21, 0xF0, 0xF1, 0xF2, 0x20, + 0xBE, 0x6B, 0x24, 0xA9, 0x07, 0x4E, 0x50, 0x5E, 0x5E, 0xCE, 0x9E, 0x3D, 0x7B, 0xD8, 0xB3, 0x67, + 0x0F, 0x3A, 0x9D, 0x0E, 0x1F, 0x1F, 0x1F, 0x42, 0x42, 0x42, 0x88, 0x88, 0x88, 0x20, 0x28, 0x28, + 0x08, 0x5F, 0x5F, 0x5F, 0x0C, 0x06, 0x03, 0x9A, 0xA6, 0x51, 0x5D, 0x5D, 0x4D, 0x59, 0x59, 0x19, + 0x85, 0x85, 0x85, 0x14, 0x14, 0x14, 0x50, 0x52, 0x52, 0xD2, 0x94, 0x09, 0x46, 0x43, 0x66, 0xF6, + 0xBE, 0xAA, 0x47, 0x3A, 0xE8, 0x55, 0x80, 0x2E, 0x5D, 0xBA, 0x90, 0x90, 0x90, 0xD0, 0x6A, 0x46, + 0x98, 0xCD, 0x66, 0x32, 0x32, 0x32, 0x58, 0xB8, 0x70, 0x21, 0x45, 0x85, 0x45, 0x0C, 0x4C, 0x88, + 0x25, 0xC8, 0xDF, 0xD7, 0xA9, 0x0D, 0xA1, 0xAA, 0x53, 0x99, 0xF9, 0xC8, 0x3D, 0x1C, 0x3C, 0x79, + 0x96, 0x6D, 0xE9, 0x47, 0xEA, 0xDB, 0x4D, 0x26, 0x13, 0x26, 0x93, 0x09, 0x1F, 0x4F, 0x0F, 0x66, + 0x3F, 0x76, 0x1F, 0x37, 0xF7, 0xEE, 0xEE, 0x9C, 0xDA, 0x6B, 0xD5, 0xB8, 0xEB, 0xB6, 0xFE, 0x3C, + 0x9D, 0x7C, 0x37, 0xF3, 0x3E, 0x5F, 0x47, 0x8D, 0x6D, 0xE1, 0xB6, 0x5A, 0xAD, 0x54, 0x56, 0x56, + 0xA2, 0x53, 0x55, 0x7E, 0x33, 0x6E, 0x38, 0x53, 0xC6, 0x0D, 0x6B, 0x76, 0x7C, 0x8A, 0x4E, 0x27, + 0x35, 0xC5, 0xCB, 0x6F, 0x61, 0xB5, 0x52, 0x5E, 0x5E, 0x4E, 0x79, 0x79, 0x39, 0xA7, 0x4E, 0x9D, + 0xA2, 0x15, 0xA8, 0x46, 0x46, 0x79, 0xAE, 0x04, 0xD6, 0x00, 0xE7, 0xF5, 0xC8, 0x48, 0x09, 0x40, + 0x9A, 0x8C, 0x5B, 0x2A, 0xAE, 0xEA, 0xEA, 0xEA, 0x38, 0x7F, 0xFE, 0x3C, 0x5B, 0xB7, 0x6E, 0x65, + 0xCD, 0x9A, 0x35, 0xEC, 0xDA, 0xB5, 0xAB, 0x5E, 0x2E, 0x46, 0x04, 0x07, 0xE0, 0xED, 0x61, 0x70, + 0x6E, 0x87, 0xAE, 0x09, 0x6E, 0x8A, 0x0A, 0xE5, 0xE3, 0x3F, 0x3D, 0xC9, 0x3F, 0x97, 0xAF, 0x67, + 0xDD, 0xCE, 0x74, 0x8A, 0x4A, 0x2B, 0x70, 0x73, 0xD3, 0xD3, 0x3B, 0xB6, 0x0B, 0xBF, 0x7B, 0x70, + 0x0C, 0xF7, 0x8F, 0xBA, 0x15, 0x55, 0x55, 0x9C, 0x36, 0xC1, 0xB8, 0xBB, 0xB9, 0xF1, 0xF2, 0xE3, + 0x0F, 0xD2, 0xA3, 0x4B, 0x38, 0x1F, 0x7D, 0xB7, 0x8D, 0x53, 0xE7, 0xF2, 0xD1, 0x34, 0x8D, 0xE8, + 0xB0, 0x20, 0x92, 0xEF, 0x1C, 0xCA, 0xB4, 0x89, 0xA3, 0xF1, 0x6F, 0xCE, 0x37, 0x63, 0x43, 0xD7, + 0x88, 0x10, 0x74, 0x3A, 0x15, 0xAB, 0x54, 0x28, 0x34, 0xA4, 0x93, 0xC9, 0x1B, 0x59, 0xC0, 0xC6, + 0x59, 0x33, 0x42, 0x1D, 0x32, 0x0E, 0xE1, 0x14, 0x32, 0x38, 0xE4, 0x47, 0x64, 0xD8, 0x54, 0x99, + 0xFD, 0x1F, 0xF4, 0x38, 0xD8, 0xE5, 0x2D, 0x16, 0x0B, 0x07, 0x0F, 0x1E, 0x24, 0x2A, 0x2A, 0x0A, + 0x3F, 0x3F, 0x3F, 0x0C, 0x06, 0x03, 0xAA, 0xCD, 0x17, 0xA1, 0x69, 0x1A, 0x75, 0x75, 0x75, 0x98, + 0x4C, 0x26, 0x4A, 0x4B, 0x4B, 0xC9, 0xCE, 0xCE, 0xE6, 0xC0, 0x81, 0x03, 0xEC, 0xDE, 0xBD, 0x9B, + 0x7D, 0xFB, 0xF6, 0x71, 0xEE, 0xDC, 0xB9, 0x2B, 0xEA, 0x94, 0x44, 0x86, 0x04, 0xE2, 0xEE, 0xD6, + 0x82, 0x68, 0x7D, 0x4D, 0xD0, 0x35, 0x32, 0x84, 0xB7, 0x9E, 0x99, 0xC2, 0xAC, 0xC9, 0xE3, 0x29, + 0xBC, 0x58, 0x8E, 0xC1, 0xDD, 0x8D, 0xE8, 0xB0, 0x20, 0x7C, 0x7D, 0xBC, 0x6D, 0x8E, 0x29, 0xE7, + 0xBB, 0x43, 0x08, 0x3C, 0x0D, 0x6E, 0x4C, 0xBD, 0x6F, 0x34, 0x93, 0x46, 0x0F, 0x21, 0xBF, 0xF8, + 0x22, 0x56, 0x4D, 0x10, 0x16, 0xE4, 0x4F, 0xA0, 0xBF, 0xAF, 0xA4, 0xA2, 0x53, 0x8B, 0xB3, 0x5C, + 0xE3, 0x3C, 0xDD, 0xDD, 0xB9, 0x24, 0xD5, 0xF2, 0x3A, 0xE0, 0x0F, 0xC8, 0x52, 0x4E, 0x7D, 0x80, + 0x18, 0x64, 0x5C, 0x5A, 0x28, 0x32, 0x11, 0x54, 0x8F, 0xD4, 0x9A, 0xAA, 0x6D, 0xC4, 0x2E, 0x45, + 0xC6, 0x6F, 0x1D, 0x47, 0x56, 0x27, 0x3A, 0x8B, 0x2C, 0x6C, 0x73, 0xC5, 0xCD, 0xF5, 0x38, 0x64, + 0x92, 0x6E, 0xDC, 0xB8, 0x91, 0x3D, 0x7B, 0xF6, 0x10, 0x1A, 0x1A, 0x4A, 0x68, 0x68, 0x28, 0x46, + 0xA3, 0x11, 0x2F, 0x2F, 0x2F, 0x54, 0x55, 0xA5, 0xB6, 0xB6, 0x96, 0xCA, 0xCA, 0x4A, 0x8A, 0x8B, + 0x8B, 0x29, 0x2C, 0x2C, 0xA4, 0xA4, 0xA4, 0x04, 0x93, 0xC9, 0x74, 0x4D, 0x6D, 0x23, 0x24, 0xD0, + 0x5F, 0x6A, 0x58, 0x2D, 0x31, 0x77, 0x68, 0x02, 0x9D, 0xA2, 0x10, 0x15, 0x16, 0x44, 0x54, 0x78, + 0x70, 0x3D, 0x61, 0x5B, 0x6D, 0xB6, 0x17, 0x80, 0xD0, 0xF0, 0xF3, 0xF1, 0xC2, 0xCF, 0xD7, 0xBB, + 0xA1, 0xBF, 0x96, 0x68, 0x49, 0x02, 0x42, 0x02, 0xFD, 0xF0, 0xF5, 0xF6, 0xB0, 0x33, 0xC4, 0x1D, + 0x39, 0x4B, 0x76, 0xD8, 0x7E, 0x20, 0x67, 0x89, 0x3B, 0x52, 0xFC, 0xEB, 0x6C, 0xC7, 0x16, 0x1B, + 0xF3, 0x9C, 0xAE, 0x6C, 0xA7, 0x07, 0x7E, 0x02, 0x46, 0x83, 0xD4, 0x0A, 0xCA, 0xCA, 0xCA, 0x28, + 0x2B, 0x2B, 0xE3, 0xE4, 0xC9, 0x93, 0x2D, 0x7D, 0xF4, 0x3A, 0xE0, 0x02, 0xD2, 0xCB, 0xE8, 0x09, + 0x10, 0xE4, 0xEF, 0xD3, 0x7A, 0xA3, 0x60, 0x4B, 0x89, 0xE6, 0xCA, 0xFE, 0x84, 0x20, 0xD0, 0xD7, + 0x9B, 0x40, 0x3F, 0x1F, 0xF2, 0x8A, 0xCB, 0xEC, 0xAD, 0x51, 0x97, 0xFF, 0x17, 0xD2, 0x6F, 0xDE, + 0x26, 0xE8, 0x91, 0x36, 0xF9, 0x67, 0x80, 0xE1, 0xC8, 0xCD, 0xA1, 0x0F, 0xCE, 0xC9, 0xC4, 0x3A, + 0xE4, 0xB4, 0xCB, 0x46, 0xCA, 0xC1, 0x6D, 0xC0, 0x79, 0x64, 0x15, 0xB7, 0xAE, 0x00, 0x7E, 0xDE, + 0xED, 0x9A, 0xED, 0xD5, 0x89, 0x10, 0x78, 0x7B, 0x7A, 0x60, 0xF4, 0xF3, 0x71, 0x6C, 0x0C, 0x72, + 0xC5, 0x9D, 0xF4, 0x48, 0xB9, 0xF6, 0x7B, 0x64, 0x40, 0x57, 0x37, 0xE4, 0xBE, 0xA4, 0x2B, 0xD2, + 0x14, 0x1F, 0x8C, 0x9C, 0x86, 0x3A, 0xA4, 0x65, 0xB0, 0x0C, 0x29, 0x0F, 0xCF, 0x03, 0x27, 0x69, + 0x90, 0x87, 0x17, 0x91, 0x6F, 0x48, 0x4F, 0x1C, 0xEA, 0x61, 0x79, 0x7A, 0x18, 0x3A, 0xAF, 0x88, + 0x60, 0x7B, 0x42, 0x80, 0x9B, 0x5E, 0x87, 0xBF, 0x4F, 0x23, 0x43, 0x6B, 0xDB, 0x4C, 0x19, 0x4D, + 0xC0, 0xBE, 0xE2, 0xD6, 0x21, 0x6B, 0x1E, 0xE6, 0x03, 0x76, 0x4F, 0x8C, 0x62, 0x3B, 0xEF, 0xB8, + 0xCD, 0xAE, 0xE3, 0xDA, 0x26, 0x5B, 0x9D, 0xFD, 0xFF, 0x55, 0x45, 0xC1, 0x5D, 0xAF, 0xBB, 0xB1, + 0x9C, 0x52, 0xD7, 0x22, 0x94, 0x5E, 0x87, 0x6F, 0xE3, 0x19, 0xEF, 0x47, 0xC3, 0x8B, 0xDA, 0x7E, + 0xF7, 0xB9, 0xC6, 0x39, 0xC1, 0x2F, 0xB4, 0xD6, 0x60, 0x6B, 0xA0, 0x2A, 0x0A, 0x9E, 0x86, 0x46, + 0xB1, 0x67, 0x9E, 0xB8, 0x80, 0x21, 0xED, 0x9D, 0x63, 0x58, 0x3F, 0x1F, 0x84, 0x10, 0xD2, 0x3B, + 0xF7, 0x4B, 0x10, 0x59, 0x00, 0x8A, 0x82, 0xA1, 0xB1, 0x0A, 0x6F, 0xD7, 0xA4, 0xDA, 0x15, 0xED, + 0xCD, 0x90, 0x1A, 0xA0, 0x16, 0x40, 0x13, 0x82, 0x6A, 0x73, 0xED, 0x2F, 0x46, 0x64, 0x01, 0x97, + 0x07, 0x78, 0xDC, 0x30, 0x0C, 0x31, 0xD9, 0x0F, 0x2A, 0xAA, 0x4C, 0x6D, 0xE8, 0xEA, 0x3A, 0x83, + 0x10, 0xD2, 0x2A, 0xDC, 0x00, 0x0D, 0x17, 0xBC, 0x6E, 0xED, 0xCD, 0x10, 0x13, 0xB2, 0xCE, 0x09, + 0x00, 0x45, 0xA5, 0xE5, 0xAE, 0x8F, 0x32, 0xEC, 0x20, 0x08, 0x21, 0x30, 0x35, 0x36, 0xE7, 0x9B, + 0x70, 0x41, 0x35, 0x39, 0x57, 0x30, 0xA4, 0xBE, 0x70, 0xC0, 0x85, 0xE2, 0x8B, 0x88, 0x1B, 0x21, + 0x30, 0xCE, 0x09, 0x58, 0x35, 0x8D, 0x4B, 0xD5, 0x8D, 0x66, 0xFC, 0x0D, 0xC1, 0x90, 0x1A, 0x1C, + 0x82, 0x88, 0xCF, 0xE6, 0x15, 0x61, 0x32, 0xB7, 0x79, 0xF3, 0xDA, 0xF9, 0x50, 0xA0, 0xA6, 0xB6, + 0x8E, 0x92, 0xF2, 0x4B, 0x8E, 0xAD, 0xC5, 0xDC, 0x00, 0x22, 0x0B, 0xE4, 0x66, 0x11, 0x80, 0x9C, + 0xFC, 0x62, 0xF9, 0x10, 0x6D, 0x89, 0xA9, 0xBA, 0x2E, 0xA0, 0x70, 0xC9, 0x64, 0x96, 0xAE, 0xDE, + 0x06, 0xB4, 0x7B, 0xF1, 0x32, 0x70, 0x5D, 0x69, 0x8D, 0x5A, 0x80, 0xFC, 0x92, 0x32, 0x4E, 0x9D, + 0xCB, 0x77, 0x2E, 0x28, 0xE1, 0x7A, 0x86, 0xA2, 0x50, 0x50, 0x5A, 0x4E, 0x51, 0x43, 0x34, 0x8C, + 0x40, 0x5A, 0x2B, 0xDA, 0x1D, 0xAE, 0x60, 0xC8, 0x49, 0x64, 0x26, 0x2A, 0x55, 0xA6, 0x2B, 0x03, + 0x0D, 0x6E, 0x48, 0x28, 0x0A, 0xA7, 0xCE, 0xE5, 0x53, 0x7E, 0xA9, 0xDE, 0xBD, 0x5C, 0x89, 0xF4, + 0x69, 0xB4, 0x3B, 0x5C, 0xC1, 0x90, 0x73, 0xC8, 0xCF, 0x4E, 0x00, 0xB0, 0x65, 0xDF, 0x61, 0xAA, + 0xAB, 0xCD, 0x9D, 0xBF, 0x41, 0x54, 0x14, 0x19, 0x92, 0xDA, 0x9A, 0x28, 0x4C, 0x21, 0xD8, 0x77, + 0xE4, 0x14, 0x96, 0xBA, 0xFA, 0x35, 0x3C, 0x1F, 0x69, 0xC3, 0x6B, 0x77, 0xB8, 0x82, 0x21, 0x26, + 0xE4, 0x57, 0x6E, 0x00, 0x48, 0x3F, 0x96, 0xC5, 0xE1, 0x53, 0x39, 0xAD, 0x23, 0x84, 0x1D, 0x8A, + 0xD2, 0x40, 0xD0, 0x96, 0xAE, 0x47, 0x0A, 0xA0, 0xD3, 0x51, 0x71, 0xA9, 0x9A, 0x9D, 0xE9, 0x47, + 0x39, 0x9E, 0xD5, 0xC2, 0x4F, 0x82, 0x28, 0x0A, 0xE5, 0x95, 0x97, 0xD8, 0x91, 0x71, 0xDC, 0xB1, + 0xF5, 0x20, 0x36, 0x29, 0xD0, 0xDE, 0x70, 0xD5, 0x67, 0x18, 0x36, 0xDB, 0x06, 0x1C, 0x52, 0x52, + 0x5E, 0xC9, 0xAA, 0x4D, 0xBB, 0x19, 0xDC, 0xA7, 0xF5, 0x51, 0x90, 0xCB, 0x37, 0xEC, 0x64, 0xF7, + 0xA1, 0x4C, 0x46, 0xDF, 0xD2, 0x87, 0x61, 0x03, 0x7B, 0x39, 0x9F, 0xE8, 0xA9, 0x28, 0x54, 0x9B, + 0x6B, 0xF8, 0xF1, 0xA7, 0x03, 0x2C, 0x59, 0xB3, 0x91, 0xED, 0xFB, 0x8F, 0xD2, 0x3B, 0x36, 0x9A, + 0xB5, 0xF3, 0x9E, 0x27, 0x2A, 0x2C, 0xC8, 0xB9, 0x3D, 0x92, 0xAA, 0xB0, 0xF7, 0xC8, 0x69, 0x0E, + 0x64, 0x66, 0xDB, 0x5B, 0x84, 0xED, 0xF9, 0x5C, 0x62, 0xE7, 0x73, 0x55, 0x8D, 0x8E, 0x12, 0x64, + 0xAC, 0x70, 0x1F, 0x80, 0x0B, 0xC5, 0xA5, 0x8C, 0x1D, 0xD2, 0x8F, 0x90, 0xA0, 0x80, 0x96, 0x6D, + 0x14, 0x6D, 0x8B, 0xE9, 0xF4, 0xD7, 0xDF, 0xE7, 0xDB, 0x94, 0x34, 0xD6, 0x6E, 0xDF, 0xC7, 0xB6, + 0xB4, 0x23, 0x18, 0xFD, 0x7C, 0xE8, 0xD9, 0x35, 0xB2, 0xE9, 0x98, 0x5C, 0xDB, 0xB5, 0x85, 0x17, + 0xCB, 0xF9, 0xDF, 0x7F, 0x7C, 0xC6, 0x6B, 0xEF, 0x7F, 0xC5, 0xB1, 0xEC, 0x5C, 0x2C, 0x75, 0x56, + 0xAA, 0xCC, 0x35, 0xDC, 0x3F, 0x62, 0x30, 0x51, 0xE1, 0xCE, 0x31, 0xA4, 0xCE, 0x6A, 0xE5, 0x8D, + 0x65, 0xFF, 0x62, 0xEF, 0xE1, 0xFA, 0x25, 0xE3, 0x3C, 0x32, 0x13, 0xB9, 0xB8, 0xD9, 0x8B, 0x5B, + 0x01, 0x57, 0xD5, 0xDF, 0xAB, 0x45, 0x3A, 0xAA, 0xAA, 0x01, 0xB2, 0x2F, 0x14, 0xB1, 0x74, 0xED, + 0x16, 0xB4, 0x56, 0x84, 0x61, 0x6A, 0x9A, 0x46, 0x8D, 0x45, 0x7A, 0x40, 0xCD, 0x35, 0xB5, 0xA4, + 0x1E, 0x38, 0xC1, 0xB4, 0x3F, 0x2D, 0xE6, 0x93, 0xEF, 0xB6, 0x35, 0xBD, 0x2E, 0xD9, 0x66, 0xC6, + 0x4B, 0x0B, 0x97, 0xB3, 0x74, 0xED, 0x16, 0xCC, 0x0E, 0xA1, 0xA2, 0x31, 0xE1, 0xC1, 0x44, 0x85, + 0x19, 0x9B, 0x8F, 0xC4, 0x07, 0xD0, 0xA9, 0xEC, 0x3B, 0x72, 0x8A, 0x75, 0x3B, 0xD2, 0x1D, 0x5B, + 0xBF, 0x47, 0xFA, 0xD2, 0x5D, 0x02, 0x57, 0x16, 0x44, 0xDC, 0x82, 0x8C, 0xAA, 0x00, 0xE0, 0xCB, + 0xEF, 0x77, 0xB0, 0xEB, 0xE0, 0x49, 0xB9, 0x0E, 0x38, 0x0B, 0x21, 0x08, 0x33, 0x06, 0x70, 0xD7, + 0x6D, 0xFD, 0xEB, 0x9B, 0xBC, 0x3D, 0x0D, 0x18, 0xDC, 0xDD, 0x78, 0xE5, 0xDD, 0x15, 0xEC, 0xFC, + 0xF9, 0xC4, 0xD5, 0xD7, 0x26, 0x45, 0x61, 0xD5, 0xC6, 0x9F, 0xF8, 0xF4, 0xDF, 0xDB, 0x19, 0x79, + 0x73, 0x62, 0xFD, 0xF5, 0xC1, 0x01, 0xBE, 0x3C, 0x3F, 0xE5, 0x5E, 0x19, 0x6B, 0xEC, 0x44, 0xF4, + 0xA3, 0xD9, 0x5C, 0xC3, 0xA2, 0xAF, 0x7E, 0xA0, 0xE8, 0x62, 0x85, 0xBD, 0xB5, 0x14, 0x17, 0x7F, + 0xD8, 0xC5, 0x95, 0x65, 0x85, 0x2C, 0x48, 0xD1, 0x75, 0x2F, 0xE0, 0x51, 0x65, 0xAA, 0xA1, 0xE8, + 0x62, 0x05, 0xF7, 0x0C, 0x1D, 0x88, 0x87, 0xC1, 0xF9, 0xA2, 0x39, 0x8A, 0xAA, 0x92, 0xD4, 0xB3, + 0x2B, 0x25, 0x65, 0x95, 0x14, 0x94, 0x94, 0x73, 0xEF, 0xF0, 0x9B, 0x99, 0xFD, 0xD8, 0x44, 0xBE, + 0x4D, 0x49, 0x27, 0x33, 0x27, 0x8F, 0x7B, 0x87, 0x0D, 0xC2, 0xE0, 0xD8, 0x9F, 0xA2, 0x90, 0x5B, + 0x58, 0xC2, 0xEF, 0xDF, 0x5A, 0x86, 0x5E, 0xA7, 0x63, 0xD9, 0x1F, 0x9F, 0xE0, 0x81, 0x91, 0xB7, + 0x12, 0xDF, 0x35, 0x82, 0x19, 0x0F, 0x8F, 0x63, 0xDC, 0xED, 0x03, 0x9D, 0xDB, 0x16, 0xE9, 0x54, + 0x56, 0x6F, 0xDA, 0xCD, 0x9C, 0x8F, 0xBF, 0x71, 0xD4, 0xAE, 0xBE, 0x44, 0x7E, 0x15, 0xC1, 0x65, + 0xF6, 0x20, 0x57, 0xD7, 0x79, 0x3A, 0x87, 0x0C, 0x33, 0x1A, 0x0C, 0x70, 0xE6, 0x42, 0x21, 0x46, + 0x3F, 0x6F, 0x7E, 0x95, 0x14, 0xD7, 0x22, 0x2D, 0xD8, 0xD7, 0xDB, 0x8B, 0x3B, 0x6F, 0xEB, 0xCF, + 0x83, 0xA3, 0x87, 0x30, 0x69, 0xF4, 0x10, 0x92, 0xE2, 0x63, 0x11, 0x42, 0xE3, 0x93, 0x75, 0xDB, + 0xE9, 0xD3, 0x3D, 0x9A, 0xC4, 0x9E, 0x31, 0x0D, 0x6F, 0xBC, 0x4E, 0xE5, 0x8B, 0x7F, 0xA7, 0xF0, + 0xD9, 0xFA, 0x14, 0x5E, 0xFD, 0xAF, 0x87, 0xB8, 0x7F, 0xD4, 0xAD, 0x04, 0xFA, 0x7B, 0x73, 0x4B, + 0xDF, 0x38, 0x62, 0x22, 0x42, 0x9C, 0x13, 0x09, 0xAA, 0xCA, 0x89, 0xEC, 0x5C, 0x9E, 0x7A, 0x6B, + 0x19, 0xB9, 0x85, 0xF5, 0xB1, 0xB7, 0x39, 0xC0, 0xB3, 0x34, 0x91, 0x5F, 0xDE, 0x5E, 0x70, 0x35, + 0x43, 0x34, 0xE4, 0x46, 0x71, 0x14, 0x10, 0xAA, 0x69, 0x82, 0x03, 0x27, 0xCF, 0xD2, 0x3F, 0x3E, + 0x96, 0xEE, 0x31, 0x11, 0x2D, 0x5A, 0xE0, 0xDD, 0x74, 0x3A, 0x8C, 0x81, 0x7E, 0x78, 0xB8, 0xCB, + 0x0C, 0xE0, 0xB8, 0xAE, 0x91, 0x6C, 0xDE, 0x7B, 0x88, 0xFC, 0x92, 0x8B, 0xDC, 0x3F, 0xE2, 0x96, + 0xFA, 0x05, 0xBE, 0xB6, 0xD6, 0xC2, 0x5F, 0x96, 0x7E, 0x8D, 0x97, 0x87, 0x81, 0x37, 0x9F, 0xFE, + 0x0D, 0x3E, 0x9E, 0x86, 0x86, 0x88, 0x13, 0x67, 0xEE, 0xA7, 0x28, 0x94, 0x55, 0x56, 0xF1, 0xEC, + 0xDF, 0x3F, 0x61, 0x6B, 0x5A, 0x7D, 0x04, 0xA5, 0x15, 0xF9, 0x71, 0x81, 0xD5, 0x2E, 0xA6, 0x57, + 0x87, 0xD4, 0x2E, 0x3F, 0x8D, 0xAC, 0x04, 0x51, 0x09, 0x50, 0x50, 0x2A, 0x35, 0x9F, 0xA3, 0xA7, + 0x72, 0x5A, 0xB6, 0x9E, 0x40, 0x43, 0x05, 0x07, 0x21, 0x08, 0x31, 0xFA, 0xF3, 0xDB, 0x09, 0x23, + 0x38, 0x73, 0xA1, 0x88, 0xCA, 0x2A, 0x53, 0xFD, 0x5E, 0xA5, 0xFC, 0x52, 0x35, 0x39, 0xF9, 0xC5, + 0xFC, 0xE7, 0xD8, 0xDB, 0x08, 0x0B, 0x0E, 0x68, 0xB1, 0x56, 0x67, 0xAE, 0xAD, 0xE5, 0xAF, 0x4B, + 0x57, 0xB3, 0x7A, 0xF3, 0x1E, 0xC7, 0x33, 0xDF, 0x21, 0x4B, 0x2E, 0xB9, 0x1C, 0x1D, 0x55, 0xE5, + 0x78, 0x35, 0xF0, 0x1E, 0x36, 0xEB, 0xE8, 0xCF, 0x27, 0xB2, 0x99, 0x31, 0xF7, 0x23, 0x72, 0x72, + 0x0B, 0x5B, 0xBF, 0x61, 0x14, 0x82, 0x31, 0x43, 0xFA, 0xD1, 0x2D, 0x2A, 0x94, 0x3A, 0x87, 0x7C, + 0x91, 0x3A, 0xAB, 0x95, 0x40, 0x3F, 0x1F, 0xC6, 0xDE, 0x9A, 0xD4, 0x32, 0x5B, 0xAC, 0xA2, 0x60, + 0xAE, 0xB5, 0x30, 0xE7, 0xA3, 0xB5, 0x2C, 0xFC, 0x6A, 0x83, 0x74, 0x3F, 0x4B, 0x1C, 0x01, 0x5E, + 0xC1, 0x21, 0xDC, 0xD3, 0x95, 0xE8, 0xA8, 0x5A, 0x81, 0x1A, 0x90, 0x81, 0x0C, 0x13, 0xEA, 0x05, + 0x90, 0x95, 0x5B, 0xC8, 0xC9, 0xB3, 0x17, 0xB8, 0xBD, 0x7F, 0x82, 0x73, 0xE5, 0x36, 0x2E, 0x87, + 0x00, 0x7F, 0x1F, 0x4F, 0x06, 0x27, 0xF6, 0x20, 0xD4, 0xE8, 0x57, 0x2F, 0xB2, 0xF4, 0x3A, 0x1D, + 0x91, 0x21, 0x46, 0x6E, 0xE9, 0xDD, 0x1D, 0x37, 0x9D, 0x93, 0x8F, 0xA7, 0xAA, 0x54, 0x56, 0x9B, + 0xF9, 0xDB, 0xD2, 0xD5, 0xCC, 0xFD, 0xFC, 0xBB, 0xFA, 0xC0, 0x6C, 0x64, 0xE0, 0xDF, 0x13, 0xC8, + 0x60, 0xC2, 0x0E, 0x41, 0x47, 0x16, 0x6F, 0xAC, 0x46, 0x7E, 0x65, 0x73, 0x10, 0x32, 0x16, 0x96, + 0xCC, 0x73, 0xF9, 0x1C, 0x3A, 0x95, 0xC3, 0xA0, 0x84, 0x6E, 0x84, 0xB6, 0x54, 0xBC, 0x20, 0x23, + 0x41, 0x02, 0xFC, 0x7D, 0x1A, 0x6D, 0x10, 0xDD, 0xF4, 0x3A, 0xE2, 0x6E, 0x8A, 0x72, 0x9E, 0x19, + 0x3A, 0x95, 0xF3, 0xF9, 0xC5, 0xBC, 0xF0, 0xCF, 0xCF, 0x79, 0x77, 0xF5, 0x8F, 0xD4, 0x5A, 0xEA, + 0xA3, 0x3E, 0x8B, 0x90, 0x45, 0x62, 0xBE, 0xE9, 0x40, 0x1A, 0x75, 0x78, 0x35, 0xCD, 0x8B, 0x48, + 0xA6, 0x0C, 0xC4, 0x96, 0x42, 0x77, 0x26, 0xB7, 0x90, 0x9D, 0x3F, 0x1F, 0x27, 0x36, 0x3C, 0x84, + 0xD8, 0xE8, 0xF0, 0x6B, 0xEF, 0xBE, 0xAF, 0x86, 0xAB, 0xF1, 0xD0, 0x49, 0x93, 0x88, 0x26, 0x20, + 0x25, 0xED, 0x08, 0x4F, 0xCE, 0x59, 0xCA, 0xB7, 0xDB, 0xD3, 0xB0, 0x36, 0x6C, 0x16, 0x0B, 0x90, + 0xCC, 0x58, 0xD1, 0xC1, 0xF4, 0xE9, 0x94, 0xF2, 0xA6, 0x85, 0xC8, 0x4F, 0x6B, 0xF7, 0xC5, 0x16, + 0x72, 0x5A, 0x50, 0x5A, 0xCE, 0x86, 0x9F, 0x7E, 0xA6, 0xA6, 0xA6, 0x96, 0x5E, 0x37, 0x45, 0xC9, + 0x04, 0x1A, 0x57, 0xC1, 0x66, 0xA4, 0xCC, 0x2D, 0x28, 0xE1, 0xEF, 0x9F, 0x7F, 0xC7, 0xEC, 0x05, + 0x5F, 0x34, 0xCA, 0xD2, 0x45, 0x2A, 0x21, 0x4F, 0x22, 0xF3, 0x35, 0x3A, 0x3C, 0x20, 0xA0, 0xB3, + 0xEA, 0xCD, 0x16, 0x21, 0x2D, 0xC2, 0x5D, 0x90, 0x5F, 0x8D, 0x56, 0x4D, 0xE6, 0x5A, 0x76, 0x64, + 0x1C, 0x27, 0xF5, 0xE7, 0xE3, 0xF8, 0x79, 0x79, 0x10, 0x13, 0x1E, 0x8C, 0xA1, 0xB9, 0x64, 0xD1, + 0x96, 0x40, 0x95, 0x96, 0xE2, 0xC2, 0xD2, 0x32, 0xBE, 0xF8, 0xF7, 0x0E, 0x9E, 0x7D, 0xE7, 0x13, + 0x56, 0x6D, 0xFC, 0xC9, 0x1E, 0xCD, 0x0E, 0x92, 0xF8, 0xDB, 0x91, 0xC5, 0x13, 0x5A, 0x57, 0xFE, + 0xA7, 0x1D, 0xD0, 0xD9, 0x5E, 0x8A, 0x40, 0xA4, 0x68, 0xF8, 0x3D, 0x0E, 0xDF, 0x3E, 0xF7, 0x34, + 0xB8, 0x33, 0x6C, 0x40, 0x2F, 0xA6, 0x8C, 0x1B, 0xCE, 0xE8, 0xC1, 0x7D, 0x09, 0x0F, 0x09, 0x40, + 0x51, 0x75, 0x36, 0x95, 0xD7, 0xC9, 0x1C, 0x11, 0x45, 0xB1, 0x79, 0x2A, 0x15, 0x6A, 0x6B, 0x6A, + 0x38, 0x95, 0x93, 0xCF, 0xBA, 0x9D, 0xE9, 0x7C, 0xB5, 0xF1, 0x27, 0x0E, 0x9C, 0x3C, 0x7B, 0x79, + 0x48, 0x4F, 0x39, 0xF0, 0x21, 0xF2, 0x23, 0x98, 0x2E, 0x71, 0xCD, 0x3A, 0x8B, 0xCE, 0x66, 0x08, + 0x48, 0x17, 0xC0, 0x9D, 0xC0, 0x8B, 0xC8, 0x62, 0xC4, 0xF5, 0xB3, 0xD6, 0x4D, 0xAF, 0x23, 0xBE, + 0x6B, 0x24, 0x23, 0x6F, 0xEE, 0xC3, 0xA8, 0x5B, 0x12, 0xE9, 0xD3, 0x3D, 0x86, 0x88, 0xE0, 0x40, + 0xBC, 0x3C, 0xDC, 0x1B, 0xAA, 0xCB, 0x35, 0x82, 0x00, 0x4D, 0x50, 0x6B, 0xB1, 0x50, 0x56, 0x51, + 0xC5, 0x99, 0x0B, 0x85, 0xEC, 0x3B, 0x7A, 0x9A, 0x2D, 0xFB, 0x0E, 0xB3, 0xFB, 0x50, 0x26, 0xF9, + 0x25, 0x65, 0x97, 0xE7, 0xB3, 0xD4, 0x21, 0x3F, 0xA5, 0x3A, 0x17, 0xF9, 0x01, 0xCC, 0x4E, 0x0F, + 0x9D, 0xBD, 0x1E, 0x18, 0x62, 0x47, 0x28, 0xB2, 0xB4, 0xC7, 0x34, 0xA4, 0x7A, 0xDC, 0x68, 0x6C, + 0xEE, 0x6E, 0x7A, 0x42, 0x8D, 0xFE, 0x74, 0x8B, 0x0C, 0x25, 0x36, 0x2A, 0x8C, 0x2E, 0xA1, 0x46, + 0x82, 0xFC, 0x7D, 0xF0, 0xF2, 0x34, 0xA0, 0x2A, 0x2A, 0xE6, 0x5A, 0x0B, 0x15, 0x97, 0xAA, 0xB9, + 0x50, 0x7C, 0x91, 0x9C, 0xFC, 0x62, 0xCE, 0xE4, 0x16, 0x72, 0xBE, 0xB0, 0x84, 0x8A, 0xAA, 0xAB, + 0x26, 0x15, 0xD5, 0x21, 0x93, 0x2C, 0x97, 0x02, 0x5F, 0x21, 0x8D, 0x86, 0xFF, 0x8F, 0xAB, 0x40, + 0x41, 0xA6, 0x44, 0xBC, 0x88, 0xDC, 0xB7, 0xD4, 0xD0, 0x82, 0xEF, 0xA2, 0x3B, 0xF1, 0x2B, 0x03, + 0x7E, 0x40, 0x32, 0x3D, 0xB4, 0xB3, 0x1F, 0xB6, 0x29, 0x02, 0x5C, 0xAF, 0x08, 0x45, 0xD6, 0x06, + 0xBE, 0x0B, 0xF8, 0x15, 0x72, 0xEF, 0xE2, 0x6C, 0x32, 0x91, 0x1D, 0x16, 0xA4, 0x23, 0xE9, 0x38, + 0x32, 0xA1, 0x68, 0x13, 0x72, 0x66, 0x54, 0x75, 0xF6, 0xC3, 0x35, 0x85, 0xEB, 0x99, 0x21, 0x76, + 0xE8, 0x90, 0x16, 0xE3, 0x3E, 0x48, 0xAB, 0x71, 0x5F, 0xA0, 0x07, 0x92, 0x61, 0x01, 0x34, 0xE4, + 0xF5, 0xD5, 0x22, 0x09, 0x5D, 0x8C, 0xF4, 0xEA, 0x1D, 0x45, 0xA6, 0x1C, 0x67, 0x20, 0x23, 0x44, + 0x2A, 0x5B, 0x76, 0xDB, 0xCE, 0xC1, 0xFF, 0x01, 0xCE, 0x34, 0xF5, 0xEC, 0x2D, 0xA9, 0x9C, 0xA8, + 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3A, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x32, 0x2D, 0x30, 0x31, 0x2D, 0x33, 0x31, 0x54, 0x31, + 0x33, 0x3A, 0x34, 0x31, 0x3A, 0x31, 0x38, 0x2D, 0x30, 0x38, 0x3A, 0x30, 0x30, 0xED, 0x4F, 0xCC, + 0x0D, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3A, 0x6D, 0x6F, + 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x32, 0x2D, 0x30, 0x31, 0x2D, 0x33, 0x31, 0x54, + 0x31, 0x33, 0x3A, 0x34, 0x31, 0x3A, 0x31, 0x38, 0x2D, 0x30, 0x38, 0x3A, 0x30, 0x30, 0x9C, 0x12, + 0x74, 0xB1, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, + 0x72, 0x65, 0x00, 0x77, 0x77, 0x77, 0x2E, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2E, + 0x6F, 0x72, 0x67, 0x9B, 0xEE, 0x3C, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82}; \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_List/Copy_Messages_List.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_List/Copy_Messages_List.ino index 3a1511777..663f1e28d 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_List/Copy_Messages_List.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_List/Copy_Messages_List.ino @@ -1,220 +1,220 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to copy messages from the mailbox to other folder. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* Define the MessageList class to add the message to copy */ - MessageList toCopy; - - /* Add message uid to copy to the list */ - toCopy.add(3); - toCopy.add(4); - - // imap.createFolder("test"); - - /* Copy all messages in the list to the folder "test" */ - if (imap.copyMessages(&toCopy, F("test"))) - MailClient.printf("\nMessages copied\n"); - - /* Delete all messages in the list from the opened folder (move to trash) */ - // imap.deleteMessages(&toCopy); - - // imap.deleteolder("test"); - // imap.deleteolder("test2"); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to copy messages from the mailbox to other folder. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Define the MessageList class to add the message to copy */ + MessageList toCopy; + + /* Add message uid to copy to the list */ + toCopy.add(3); + toCopy.add(4); + + // imap.createFolder("test"); + + /* Copy all messages in the list to the folder "test" */ + if (imap.copyMessages(&toCopy, F("test"))) + MailClient.printf("\nMessages copied\n"); + + /* Delete all messages in the list from the opened folder (move to trash) */ + // imap.deleteMessages(&toCopy); + + // imap.deleteolder("test"); + // imap.deleteolder("test2"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_Message_Numbers_Ranges/Copy_Messages_Message_Numbers_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_Message_Numbers_Ranges/Copy_Messages_Message_Numbers_Ranges.ino index 958037525..292dd2461 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_Message_Numbers_Ranges/Copy_Messages_Message_Numbers_Ranges.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_Message_Numbers_Ranges/Copy_Messages_Message_Numbers_Ranges.ino @@ -1,214 +1,214 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to copy messages from the mailbox to other folder using message numbers ranges. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* Copy all messages using message sequence ranges (last 10 message numbers) to the folder "test"*/ - int msg_last = imap.selectedFolder().msgCount(); - int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; - - String sequence_set2 = String(msg_begin) + ":" + String(msg_last); - - if (imap.copyMessages(sequence_set2, false /* if sequence set are message numbers not UIDs */, F("test"))) - MailClient.printf("\nCopying messages using message numbers ranges success\n"); - else - MailClient.printf("\nError, copying messages using message numbers ranges\n"); - - // imap.deleteolder("test"); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to copy messages from the mailbox to other folder using message numbers ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Copy all messages using message sequence ranges (last 10 message numbers) to the folder "test"*/ + int msg_last = imap.selectedFolder().msgCount(); + int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; + + String sequence_set2 = String(msg_begin) + ":" + String(msg_last); + + if (imap.copyMessages(sequence_set2, false /* if sequence set are message numbers not UIDs */, F("test"))) + MailClient.printf("\nCopying messages using message numbers ranges success\n"); + else + MailClient.printf("\nError, copying messages using message numbers ranges\n"); + + // imap.deleteolder("test"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_UIDs_Ranges/Copy_Messages_UIDs_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_UIDs_Ranges/Copy_Messages_UIDs_Ranges.ino index 1fdc5c6bf..7978844bc 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_UIDs_Ranges/Copy_Messages_UIDs_Ranges.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Copy_Messages/Copy_Messages_UIDs_Ranges/Copy_Messages_UIDs_Ranges.ino @@ -1,214 +1,214 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to copy messages from the mailbox to other folder using UIDs ranges. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* Copy all messages using UIDs ranges (last 10 UIDs) to the folder "test" */ - int uid_last = imap.getUID(imap.selectedFolder().msgCount()); - int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; - - String sequence_set1 = String(uid_begin) + ":" + String(uid_last); - - if (imap.copyMessages(sequence_set1, true /* if sequence set are the UIDs */, F("test"))) - MailClient.printf("\nCopying messages using UIDs ranges success\n"); - else - MailClient.printf("\nError, copying messages using UIDs ranges\n"); - - // imap.deleteolder("test"); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to copy messages from the mailbox to other folder using UIDs ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Copy all messages using UIDs ranges (last 10 UIDs) to the folder "test" */ + int uid_last = imap.getUID(imap.selectedFolder().msgCount()); + int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; + + String sequence_set1 = String(uid_begin) + ":" + String(uid_last); + + if (imap.copyMessages(sequence_set1, true /* if sequence set are the UIDs */, F("test"))) + MailClient.printf("\nCopying messages using UIDs ranges success\n"); + else + MailClient.printf("\nError, copying messages using UIDs ranges\n"); + + // imap.deleteolder("test"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Character_Decoding/Custom_Character_Decoding.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Character_Decoding/Custom_Character_Decoding.ino index f703bd316..2940e144b 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Character_Decoding/Custom_Character_Decoding.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Character_Decoding/Custom_Character_Decoding.ino @@ -1,498 +1,498 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt - */ - -// This example shows how to read Email with custom character decoding for local language. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** Assign SD card type and FS used in src/ESP_Mail_FS.h and - * change the config for that card interfaces in src/extras/SDHelper.h - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// Provide the SD card interfaces setting and mounting -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status); - -/* Callback function to decode the string based on character set of the content */ -void customCharacterDecodingCallback(IMAP_Decoding_Info *decoding); - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -/* Print all messages from the message list */ -void printMessages(std::vector &msgItems, bool headerOnly); - -/* Print all attachments info from the message */ -void printAttacements(std::vector &atts); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - -#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h - // Mount SD card. - SD_Card_Mounting(); // See src/extras/SDHelper.h -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - /* Set the callback function to decode the string based on the caracter set of string */ - imap.characterDecodingCallback(customCharacterDecodingCallback); - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Set the storage to save the downloaded files and attachments */ - imap_data.storage.saved_path = F("/email_data"); - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - imap_data.storage.type = esp_mail_file_storage_type_sd; - - /** Set to download headers, text and html messaeges, - * attachments and inline images respectively. - */ - imap_data.download.header = true; - imap_data.download.text = true; - imap_data.download.html = true; - imap_data.download.attachment = true; - imap_data.download.inlineImg = true; - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option imap_data.limit.msg_size. - * The whole message can be download through imap_data.download.text - * or imap_data.download.html which not depends on these enable options. - */ - imap_data.enable.html = true; - imap_data.enable.text = true; - - /* Set to enable the sort the result by message UID in the decending order */ - imap_data.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - imap_data.enable.download_status = true; - - /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud - , to allow case sensitive parse, uncomment below line*/ - // imap_data.enable.header_case_sensitive = true; - - /* Set the limit of number of messages in the search results */ - imap_data.limit.search = 5; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - imap_data.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - imap_data.limit.attachment_size = 1024 * 1024 * 5; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* {Optional} */ - printSelectedMailboxInfo(imap.selectedFolder()); - - /** Message UID to fetch or read e.g. 100. - * In this case we will get the UID from the max message number (lastest message) - */ - imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); - - // or fetch via the message sequence number - // imap_data.fetch.number = imap.selectedFolder().msgCount(); - - // if both imap_data.fetch.uid and imap_data.fetch.number were set, - // then total 2 messages will be fetched i.e. one using uid and other using number. - - /* Set seen flag */ - - // The message with "Seen" flagged means the message was already read or seen by user. - // The default value of this option is set to false. - // If you want to set the message flag as "Seen", set this option to true. - // If this option is false, the message flag was unchanged. - // To set or remove flag from message, see Set_Flags.ino example. - - // imap_data.fetch.set_seen = true; - - /* Read or search the Email and close the session */ - - // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, - // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag - // to message, see the Set_Flags.ino example. - MailClient.readMail(&imap); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); -} - -void loop() -{ -} - -void To_UTF8(IMAP_Decoding_Info *decoding) -{ - decoding->decodedString = "fake decoded string "; // return the decoded string -} - -void customCharacterDecodingCallback(IMAP_Decoding_Info *decoding) -{ - // Serial.println("***** Data Type *****"); - // 0 or IMAP_Decoding_Info::message_part_type_header or - // 1 or IMAP_Decoding_Info::message_part_type_text - // Serial.println(decoding->type); - - // Serial.println("***** Charset *****"); - // Serial.println(decoding->charset); - // Serial.println("***** String to Decode *****"); - // Serial.println(decoding->encoded); - - // The original or decoded string should be return to the process via - // decoding->decodedString - - // Then rturn the decoded string back to the process. - if (strlen(decoding->charset) == 0 || strcasecmp(decoding->charset, "utf-8") == 0 || strcasecmp(decoding->charset, "us-ascii") == 0) // return original - decoding->decodedString = decoding->data; - else // decode to UTF-8 or ASCII - To_UTF8(decoding); -} - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status) -{ - /* Print the current status */ - MailClient.printf(status.info()); - - /* Show the result when reading finished */ - if (status.success()) - { - /* Print the result */ - /* Get the message list from the message list data */ - IMAP_MSG_List msgList = imap.data(); - printMessages(msgList.msgItems, imap.headerOnly()); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } -} - -void printAttacements(std::vector &atts) -{ - MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); - for (size_t j = 0; j < atts.size(); j++) - { - IMAP_Attach_Item att = atts[j]; - /** att.type can be - * esp_mail_att_type_none or 0 - * esp_mail_att_type_attachment or 1 - * esp_mail_att_type_inline or 2 - */ - MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); - } - Serial.println(); -} - -void printMessages(std::vector &msgItems, bool headerOnly) -{ - - /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and - * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename - * (> 13 characters) is not support in the SD.h library. - * To show how its original file name, use imap.fileList(). - */ - // Serial.println(imap.fileList()); - - for (size_t i = 0; i < msgItems.size(); i++) - { - - /* Iterate to get each message data through the message item data */ - IMAP_MSG_Item msg = msgItems[i]; - - Serial.println("****************************"); - MailClient.printf("Number: %d\n", msg.msgNo); - MailClient.printf("UID: %d\n", msg.UID); - - // The attachment status in search may be true in case the "multipart/mixed" - // content type header was set with no real attachtment included. - MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); - - MailClient.printf("Messsage-ID: %s\n", msg.ID); - - if (strlen(msg.flags)) - MailClient.printf("Flags: %s\n", msg.flags); - if (strlen(msg.acceptLang)) - MailClient.printf("Accept Language: %s\n", msg.acceptLang); - if (strlen(msg.contentLang)) - MailClient.printf("Content Language: %s\n", msg.contentLang); - if (strlen(msg.from)) - MailClient.printf("From: %s\n", msg.from); - if (strlen(msg.sender)) - MailClient.printf("Sender: %s\n", msg.sender); - if (strlen(msg.to)) - MailClient.printf("To: %s\n", msg.to); - if (strlen(msg.cc)) - MailClient.printf("CC: %s\n", msg.cc); - if (strlen(msg.bcc)) - MailClient.printf("BCC: %s\n", msg.bcc); - if (strlen(msg.date)) - { - MailClient.printf("Date: %s\n", msg.date); - MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); - } - if (strlen(msg.subject)) - MailClient.printf("Subject: %s\n", msg.subject); - if (strlen(msg.reply_to)) - MailClient.printf("Reply-To: %s\n", msg.reply_to); - if (strlen(msg.return_path)) - MailClient.printf("Return-Path: %s\n", msg.return_path); - if (strlen(msg.in_reply_to)) - MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); - if (strlen(msg.references)) - MailClient.printf("References: %s\n", msg.references); - if (strlen(msg.comments)) - MailClient.printf("Comments: %s\n", msg.comments); - if (strlen(msg.keywords)) - MailClient.printf("Keywords: %s\n", msg.keywords); - - /* If the result contains the message info (Fetch mode) */ - if (!headerOnly) - { - if (strlen(msg.text.content)) - MailClient.printf("Text Message: %s\n", msg.text.content); - if (strlen(msg.text.charSet)) - MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); - if (strlen(msg.text.transfer_encoding)) - MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - if (strlen(msg.html.content)) - MailClient.printf("HTML Message: %s\n", msg.html.content); - if (strlen(msg.html.charSet)) - MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); - if (strlen(msg.html.transfer_encoding)) - MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.rfc822.size() > 0) - { - MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - printMessages(msg.rfc822, headerOnly); - } - - if (msg.attachments.size() > 0) - printAttacements(msg.attachments); - } - - Serial.println(); - } +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +// This example shows how to read Email with custom character decoding for local language. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// Provide the SD card interfaces setting and mounting +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Callback function to decode the string based on character set of the content */ +void customCharacterDecodingCallback(IMAP_Decoding_Info *decoding); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + +#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h + // Mount SD card. + SD_Card_Mounting(); // See src/extras/SDHelper.h +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /* Set the callback function to decode the string based on the caracter set of string */ + imap.characterDecodingCallback(customCharacterDecodingCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_sd; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /** Message UID to fetch or read e.g. 100. + * In this case we will get the UID from the max message number (lastest message) + */ + imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); + + // or fetch via the message sequence number + // imap_data.fetch.number = imap.selectedFolder().msgCount(); + + // if both imap_data.fetch.uid and imap_data.fetch.number were set, + // then total 2 messages will be fetched i.e. one using uid and other using number. + + /* Set seen flag */ + + // The message with "Seen" flagged means the message was already read or seen by user. + // The default value of this option is set to false. + // If you want to set the message flag as "Seen", set this option to true. + // If this option is false, the message flag was unchanged. + // To set or remove flag from message, see Set_Flags.ino example. + + // imap_data.fetch.set_seen = true; + + /* Read or search the Email and close the session */ + + // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, + // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag + // to message, see the Set_Flags.ino example. + MailClient.readMail(&imap); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void loop() +{ +} + +void To_UTF8(IMAP_Decoding_Info *decoding) +{ + decoding->decodedString = "fake decoded string "; // return the decoded string +} + +void customCharacterDecodingCallback(IMAP_Decoding_Info *decoding) +{ + // Serial.println("***** Data Type *****"); + // 0 or IMAP_Decoding_Info::message_part_type_header or + // 1 or IMAP_Decoding_Info::message_part_type_text + // Serial.println(decoding->type); + + // Serial.println("***** Charset *****"); + // Serial.println(decoding->charset); + // Serial.println("***** String to Decode *****"); + // Serial.println(decoding->encoded); + + // The original or decoded string should be return to the process via + // decoding->decodedString + + // Then rturn the decoded string back to the process. + if (strlen(decoding->charset) == 0 || strcasecmp(decoding->charset, "utf-8") == 0 || strcasecmp(decoding->charset, "us-ascii") == 0) // return original + decoding->decodedString = decoding->data; + else // decode to UTF-8 or ASCII + To_UTF8(decoding); +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + MailClient.printf(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and + * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename + * (> 13 characters) is not support in the SD.h library. + * To show how its original file name, use imap.fileList(). + */ + // Serial.println(imap.fileList()); + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Append_Message/Append_Message.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Append_Message/Append_Message.ino index 9ef89294e..ec7c20219 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Append_Message/Append_Message.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Append_Message/Append_Message.ino @@ -1,221 +1,221 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to append new message to mailbox using the custom IMAP command. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void customCommandCallback(IMAP_Response res) -{ - // The server responses will included tagged and/or untagged data. - - // Tagged data is the status which begins with command identifier (tag) i.e. "A01" in this case. - // Tagged status responses included OK, NO, BAD, PREAUTH and BYE. - - // Untagged data is the information or result of the request which begins with * - - // When you send multiple commands with different tag simultaneously, - // tag will be used as command identifier. - - MailClient.printf("> C: TAG %s\n", res.tag.c_str()); - MailClient.printf("< S: %s\n", res.text.c_str()); - - if (res.completed) - { - MailClient.printf("> C: Response finished with status %s\n\n", res.status.c_str()); - } -} - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - - /* Connect to the server */ - if (!imap.customConnect(&config, customCommandCallback, F("A01") /* tag */)) - return; - - String cmd = F("LOGIN "); - cmd += AUTHOR_EMAIL; - cmd += F(" "); - cmd += AUTHOR_PASSWORD; - - // You can also assign tag to the begining of the command e.g. "A01 FETCH 1 UID" - // Do not assign tag to command when you assign tag to the last parameter of function. - - imap.sendCustomCommand(cmd, customCommandCallback, F("A02") /* tag */); - - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in.\n"); - else - Serial.println("\nConnected with no Auth.\n"); - - imap.sendCustomCommand(F("SELECT \"INBOX\""), customCommandCallback, F("A03") /* tag */); - - imap.sendCustomCommand(F("LIST \"\" *"), customCommandCallback, F("A04") /* tag */); - - String appendMsg = "Date: Thu, 16 Jun 2022 12:30:25 -0800 (PST)\r\n"; - - appendMsg += "From: Jack \r\n"; - - appendMsg += "Subject: Greeting from ESP Mail\r\n"; - - appendMsg += "To: joe@host.com\r\n"; - - appendMsg += "Message-Id: \r\n"; - - appendMsg += "MIME-Version: 1.0\r\n"; - - appendMsg += "Content-Type: text/plain; charset=\"us-ascii\"\r\n"; - - appendMsg += "Content-transfer-encoding: 7bit\r\n"; - - appendMsg += "\r\n"; - - appendMsg += "Hello Joe, this is the append message\r\n"; - - String appendMsgCmd = "APPEND INBOX {" + String(appendMsg.length()) + "}"; - - imap.sendCustomCommand(appendMsgCmd, customCommandCallback, F("A05") /* tag */); - - imap.sendCustomData(appendMsg, true /* flag states the last data to send */); -} - -void loop() -{ -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to append new message to mailbox using the custom IMAP command. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void customCommandCallback(IMAP_Response res) +{ + // The server responses will included tagged and/or untagged data. + + // Tagged data is the status which begins with command identifier (tag) i.e. "A01" in this case. + // Tagged status responses included OK, NO, BAD, PREAUTH and BYE. + + // Untagged data is the information or result of the request which begins with * + + // When you send multiple commands with different tag simultaneously, + // tag will be used as command identifier. + + MailClient.printf("> C: TAG %s\n", res.tag.c_str()); + MailClient.printf("< S: %s\n", res.text.c_str()); + + if (res.completed) + { + MailClient.printf("> C: Response finished with status %s\n\n", res.status.c_str()); + } +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + + /* Connect to the server */ + if (!imap.customConnect(&config, customCommandCallback, F("A01") /* tag */)) + return; + + String cmd = F("LOGIN "); + cmd += AUTHOR_EMAIL; + cmd += F(" "); + cmd += AUTHOR_PASSWORD; + + // You can also assign tag to the begining of the command e.g. "A01 FETCH 1 UID" + // Do not assign tag to command when you assign tag to the last parameter of function. + + imap.sendCustomCommand(cmd, customCommandCallback, F("A02") /* tag */); + + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in.\n"); + else + Serial.println("\nConnected with no Auth.\n"); + + imap.sendCustomCommand(F("SELECT \"INBOX\""), customCommandCallback, F("A03") /* tag */); + + imap.sendCustomCommand(F("LIST \"\" *"), customCommandCallback, F("A04") /* tag */); + + String appendMsg = "Date: Thu, 16 Jun 2022 12:30:25 -0800 (PST)\r\n"; + + appendMsg += "From: Jack \r\n"; + + appendMsg += "Subject: Greeting from ESP Mail\r\n"; + + appendMsg += "To: joe@host.com\r\n"; + + appendMsg += "Message-Id: \r\n"; + + appendMsg += "MIME-Version: 1.0\r\n"; + + appendMsg += "Content-Type: text/plain; charset=\"us-ascii\"\r\n"; + + appendMsg += "Content-transfer-encoding: 7bit\r\n"; + + appendMsg += "\r\n"; + + appendMsg += "Hello Joe, this is the append message\r\n"; + + String appendMsgCmd = "APPEND INBOX {" + String(appendMsg.length()) + "}"; + + imap.sendCustomCommand(appendMsgCmd, customCommandCallback, F("A05") /* tag */); + + imap.sendCustomData(appendMsg, true /* flag states the last data to send */); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Basic_Auth/Basic_Auth.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Basic_Auth/Basic_Auth.ino index 9485ee7e6..76161f0f5 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Basic_Auth/Basic_Auth.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Basic_Auth/Basic_Auth.ino @@ -1,197 +1,197 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to send custom IMAP command and get the response. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void customCommandCallback(IMAP_Response res) -{ - // The server responses will included tagged and/or untagged data. - - // Tagged data is the status which begins with command identifier (tag) i.e. "A01" in this case. - // Tagged status responses included OK, NO, BAD, PREAUTH and BYE. - - // Untagged data is the information or result of the request which begins with * - - // When you send multiple commands with different tag simultaneously, - // tag will be used as command identifier. - - MailClient.printf("> C: TAG %s\n", res.tag.c_str()); - MailClient.printf("< S: %s\n", res.text.c_str()); - - if (res.completed) - { - MailClient.printf("> C: Response finished with status %s\n\n", res.status.c_str()); - } -} - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - // This debug required for showing debug info from imap.connect - imap.debug(1); - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in.\n"); - else - Serial.println("\nConnected with no Auth.\n"); - - // You can also assign tag to the begining of the command e.g. "A01 FETCH 1 UID" - // Do not assign tag to command when you assign tag to the last parameter of function. - - imap.sendCustomCommand(F("SELECT \"INBOX\""), customCommandCallback, F("A01") /* tag */); - - imap.sendCustomCommand(F("LIST \"\" *"), customCommandCallback, F("A02") /* tag */); - - imap.sendCustomCommand(F("FETCH 1 UID"), customCommandCallback, F("A03") /* tag */); -} - -void loop() -{ -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send custom IMAP command and get the response. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void customCommandCallback(IMAP_Response res) +{ + // The server responses will included tagged and/or untagged data. + + // Tagged data is the status which begins with command identifier (tag) i.e. "A01" in this case. + // Tagged status responses included OK, NO, BAD, PREAUTH and BYE. + + // Untagged data is the information or result of the request which begins with * + + // When you send multiple commands with different tag simultaneously, + // tag will be used as command identifier. + + MailClient.printf("> C: TAG %s\n", res.tag.c_str()); + MailClient.printf("< S: %s\n", res.text.c_str()); + + if (res.completed) + { + MailClient.printf("> C: Response finished with status %s\n\n", res.status.c_str()); + } +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + // This debug required for showing debug info from imap.connect + imap.debug(1); + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in.\n"); + else + Serial.println("\nConnected with no Auth.\n"); + + // You can also assign tag to the begining of the command e.g. "A01 FETCH 1 UID" + // Do not assign tag to command when you assign tag to the last parameter of function. + + imap.sendCustomCommand(F("SELECT \"INBOX\""), customCommandCallback, F("A01") /* tag */); + + imap.sendCustomCommand(F("LIST \"\" *"), customCommandCallback, F("A02") /* tag */); + + imap.sendCustomCommand(F("FETCH 1 UID"), customCommandCallback, F("A03") /* tag */); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Custom_Auth/Custom_Auth.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Custom_Auth/Custom_Auth.ino index afb3ef9c2..c0b16c43e 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Custom_Auth/Custom_Auth.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Custom_Auth/Custom_Auth.ino @@ -1,197 +1,197 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to send custom IMAP command and get the response. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void customCommandCallback(IMAP_Response res) -{ - // The server responses will included tagged and/or untagged data. - - // Tagged data is the status which begins with command identifier (tag) i.e. "A01" in this case. - // Tagged status responses included OK, NO, BAD, PREAUTH and BYE. - - // Untagged data is the information or result of the request which begins with * - - // When you send multiple commands with different tag simultaneously, - // tag will be used as command identifier. - - MailClient.printf("> C: TAG %s\n", res.tag.c_str()); - MailClient.printf("< S: %s\n", res.text.c_str()); - - if (res.completed) - { - MailClient.printf("> C: Response finished with status %s\n\n", res.status.c_str()); - } -} - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - - /* Connect to the server */ - if (!imap.customConnect(&config, customCommandCallback, F("A01") /* tag */)) - return; - - String cmd = F("LOGIN "); - cmd += AUTHOR_EMAIL; - cmd += F(" "); - cmd += AUTHOR_PASSWORD; - - // You can also assign tag to the begining of the command e.g. "A01 FETCH 1 UID" - // Do not assign tag to command when you assign tag to the last parameter of function. - - imap.sendCustomCommand(cmd, customCommandCallback, F("A02") /* tag */); - - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in.\n"); - else - Serial.println("\nConnected with no Auth.\n"); - - imap.sendCustomCommand(F("SELECT \"INBOX\""), customCommandCallback, F("A03") /* tag */); - - imap.sendCustomCommand(F("LIST \"\" *"), customCommandCallback, F("A04") /* tag */); - - imap.sendCustomCommand(F("FETCH 1 UID"), customCommandCallback, F("A05") /* tag */); -} - -void loop() -{ -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send custom IMAP command and get the response. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void customCommandCallback(IMAP_Response res) +{ + // The server responses will included tagged and/or untagged data. + + // Tagged data is the status which begins with command identifier (tag) i.e. "A01" in this case. + // Tagged status responses included OK, NO, BAD, PREAUTH and BYE. + + // Untagged data is the information or result of the request which begins with * + + // When you send multiple commands with different tag simultaneously, + // tag will be used as command identifier. + + MailClient.printf("> C: TAG %s\n", res.tag.c_str()); + MailClient.printf("< S: %s\n", res.text.c_str()); + + if (res.completed) + { + MailClient.printf("> C: Response finished with status %s\n\n", res.status.c_str()); + } +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + + /* Connect to the server */ + if (!imap.customConnect(&config, customCommandCallback, F("A01") /* tag */)) + return; + + String cmd = F("LOGIN "); + cmd += AUTHOR_EMAIL; + cmd += F(" "); + cmd += AUTHOR_PASSWORD; + + // You can also assign tag to the begining of the command e.g. "A01 FETCH 1 UID" + // Do not assign tag to command when you assign tag to the last parameter of function. + + imap.sendCustomCommand(cmd, customCommandCallback, F("A02") /* tag */); + + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in.\n"); + else + Serial.println("\nConnected with no Auth.\n"); + + imap.sendCustomCommand(F("SELECT \"INBOX\""), customCommandCallback, F("A03") /* tag */); + + imap.sendCustomCommand(F("LIST \"\" *"), customCommandCallback, F("A04") /* tag */); + + imap.sendCustomCommand(F("FETCH 1 UID"), customCommandCallback, F("A05") /* tag */); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Idle/Idle.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Idle/Idle.ino index 5a704e6bc..0acd5846b 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Idle/Idle.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Command/Idle/Idle.ino @@ -1,220 +1,220 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to receive mailbox updates by sending the custom IMAP command IDLE. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -unsigned long lastIdleTerminatedMillis = 0; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void customCommandCallback(IMAP_Response res) -{ - // The server responses will included tagged and/or untagged data. - - // Tagged data is the status which begins with command identifier (tag) i.e. "A01" in this case. - // Tagged status responses included OK, NO, BAD, PREAUTH and BYE. - - // Untagged data is the information or result of the request which begins with * - - // When you send multiple commands with different tag simultaneously, - // tag will be used as command identifier. - - MailClient.printf("> C: TAG %s\n", res.tag.c_str()); - MailClient.printf("< S: %s\n", res.text.c_str()); - - if (res.completed) - { - MailClient.printf("> C: Response finished with status %s\n\n", res.status.c_str()); - } -} - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - - /* Connect to the server */ - if (!imap.customConnect(&config, customCommandCallback, F("A01") /* tag */)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in.\n"); - else - Serial.println("\nConnected with no Auth.\n"); - - String cmd = F("LOGIN "); - cmd += AUTHOR_EMAIL; - cmd += F(" "); - cmd += AUTHOR_PASSWORD; - - // You can also assign tag to the begining of the command e.g. "A01 FETCH 1 UID" - // Do not assign tag to command when you assign tag to the last parameter of function. - - imap.sendCustomCommand(cmd, customCommandCallback, F("A02") /* tag */); - - imap.sendCustomCommand(F("SELECT \"INBOX\""), customCommandCallback, F("A03") /* tag */); - - imap.sendCustomCommand(F("LIST \"\" *"), customCommandCallback, F("A04") /* tag */); -} - -void loop() -{ - - if (imap.connected()) - { - if (!imap.sendCustomCommand(F("IDLE"), customCommandCallback, F("A05") /* tag */)) - { - // If error, need to re-connect if imap.connected() returns false and re-log in again - Serial.println("\nTCP connection closed!"); - return; - } - - if (millis() - lastIdleTerminatedMillis > 20 * 60 * 1000) // terminate the IDLE every 20 min. - { - lastIdleTerminatedMillis = millis(); - imap.sendCustomCommand(F("DONE"), customCommandCallback, "" /* don't include tag for DONE command */); - } - } -} - -/** - * The server MAY consider a client inactive if it has an IDLE command - * running, and if such a server has an inactivity timeout it MAY log - * the client off implicitly at the end of its timeout period. Because - * of that, clients using IDLE are advised to terminate the IDLE and - * re-issue it at least every 29 minutes to avoid being logged off. +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to receive mailbox updates by sending the custom IMAP command IDLE. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +unsigned long lastIdleTerminatedMillis = 0; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void customCommandCallback(IMAP_Response res) +{ + // The server responses will included tagged and/or untagged data. + + // Tagged data is the status which begins with command identifier (tag) i.e. "A01" in this case. + // Tagged status responses included OK, NO, BAD, PREAUTH and BYE. + + // Untagged data is the information or result of the request which begins with * + + // When you send multiple commands with different tag simultaneously, + // tag will be used as command identifier. + + MailClient.printf("> C: TAG %s\n", res.tag.c_str()); + MailClient.printf("< S: %s\n", res.text.c_str()); + + if (res.completed) + { + MailClient.printf("> C: Response finished with status %s\n\n", res.status.c_str()); + } +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + + /* Connect to the server */ + if (!imap.customConnect(&config, customCommandCallback, F("A01") /* tag */)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in.\n"); + else + Serial.println("\nConnected with no Auth.\n"); + + String cmd = F("LOGIN "); + cmd += AUTHOR_EMAIL; + cmd += F(" "); + cmd += AUTHOR_PASSWORD; + + // You can also assign tag to the begining of the command e.g. "A01 FETCH 1 UID" + // Do not assign tag to command when you assign tag to the last parameter of function. + + imap.sendCustomCommand(cmd, customCommandCallback, F("A02") /* tag */); + + imap.sendCustomCommand(F("SELECT \"INBOX\""), customCommandCallback, F("A03") /* tag */); + + imap.sendCustomCommand(F("LIST \"\" *"), customCommandCallback, F("A04") /* tag */); +} + +void loop() +{ + + if (imap.connected()) + { + if (!imap.sendCustomCommand(F("IDLE"), customCommandCallback, F("A05") /* tag */)) + { + // If error, need to re-connect if imap.connected() returns false and re-log in again + Serial.println("\nTCP connection closed!"); + return; + } + + if (millis() - lastIdleTerminatedMillis > 20 * 60 * 1000) // terminate the IDLE every 20 min. + { + lastIdleTerminatedMillis = millis(); + imap.sendCustomCommand(F("DONE"), customCommandCallback, "" /* don't include tag for DONE command */); + } + } +} + +/** + * The server MAY consider a client inactive if it has an IDLE command + * running, and if such a server has an inactivity timeout it MAY log + * the client off implicitly at the end of its timeout period. Because + * of that, clients using IDLE are advised to terminate the IDLE and + * re-issue it at least every 29 minutes to avoid being logged off. */ \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Ports/Custom_Ports.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Ports/Custom_Ports.ino index b870aa5ab..1616480b8 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Ports/Custom_Ports.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Custom_Ports/Custom_Ports.ino @@ -1,256 +1,256 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to assign the custom ports with protocols to access IMAP server. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 // Plain or TLS with STARTTLS - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT esp_mail_imap_port_143 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Set the ports and protocols - * The port that assigned with config.server.port will map with the - * protocol assigned here - */ - - config.ports_functions.list = new port_function[2]; - config.ports_functions.size = 2; - - config.ports_functions.list[0].port = 143; - config.ports_functions.list[0].protocol = esp_mail_protocol_tls; - - config.ports_functions.list[1].port = 993; - config.ports_functions.list[1].protocol = esp_mail_protocol_ssl; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* {Optional} */ - printSelectedMailboxInfo(imap.selectedFolder()); - - /* Close the seeion in case the session is still open */ - imap.closeSession(); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); -} - -void loop() -{ -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to assign the custom ports with protocols to access IMAP server. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 // Plain or TLS with STARTTLS + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT esp_mail_imap_port_143 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Set the ports and protocols + * The port that assigned with config.server.port will map with the + * protocol assigned here + */ + + config.ports_functions.list = new port_function[2]; + config.ports_functions.size = 2; + + config.ports_functions.list[0].port = 143; + config.ports_functions.list[0].protocol = esp_mail_protocol_tls; + + config.ports_functions.list[1].port = 993; + config.ports_functions.list[1].protocol = esp_mail_protocol_ssl; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /* Close the seeion in case the session is still open */ + imap.closeSession(); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Data_Stream_Callback/Data_Stream_Callback.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Data_Stream_Callback/Data_Stream_Callback.ino index c06f4342e..35a7d9ee3 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Data_Stream_Callback/Data_Stream_Callback.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Data_Stream_Callback/Data_Stream_Callback.ino @@ -1,368 +1,368 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to read Email and collect the stream data to print or store via the callback function. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** Assign SD card type and FS used in src/ESP_Mail_FS.h and - * change the config for that card interfaces in src/extras/SDHelper.h - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// Provide the SD card interfaces setting and mounting -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -void mimeDataStreamCallback(MIME_Data_Stream_Info streaminfo); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -int progress = 0; -int lastProgress = -1; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - -#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h - // Mount SD card. - SD_Card_Mounting(); // See src/extras/SDHelper.h -#endif - - /* Set the callback function to get MIME Data stream */ - imap.mimeDataStreamCallback(mimeDataStreamCallback); - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Set the storage to save the downloaded files and attachments */ - imap_data.storage.saved_path = F("/email_data"); - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - imap_data.storage.type = esp_mail_file_storage_type_sd; - - /** Set to download headers, text and html messaeges, - * attachments and inline images respectively. - */ - imap_data.download.header = true; - imap_data.download.text = true; - imap_data.download.html = true; - imap_data.download.attachment = true; - imap_data.download.inlineImg = true; - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option imap_data.limit.msg_size. - * The whole message can be download through imap_data.download.text - * or imap_data.download.html which not depends on these enable options. - */ - imap_data.enable.html = true; - imap_data.enable.text = true; - - /* Set to enable the sort the result by message UID in the decending order */ - imap_data.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - imap_data.enable.download_status = true; - - /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud - , to allow case sensitive parse, uncomment below line*/ - // imap_data.enable.header_case_sensitive = true; - - /* Set the limit of number of messages in the search results */ - imap_data.limit.search = 5; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - imap_data.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - imap_data.limit.attachment_size = 1024 * 1024 * 5; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /** Message UID to fetch or read e.g. 100. - * In this case we will get the UID from the max message number (lastest message) - */ - imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); - - /* Set seen flag */ - - // The message with "Seen" flagged means the message was already read or seen by user. - // The default value of this option is set to false. - // If you want to set the message flag as "Seen", set this option to true. - // If this option is false, the message flag was unchanged. - // To set or remove flag from message, see Set_Flags.ino example. - - // imap_data.fetch.set_seen = true; - - /* Read or search the Email and close the session */ - - // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, - // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag - // to message, see the Set_Flags.ino example. - MailClient.readMail(&imap); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); -} - -void loop() -{ -} - -void mimeDataStreamCallback(MIME_Data_Stream_Info streaminfo) -{ - if (streaminfo.isFirstData) - { - progress = 0; - lastProgress = -1; - - Serial.print("Message UID: "); - Serial.println(streaminfo.uid); - - Serial.print("Content Type: "); - Serial.println(streaminfo.type); - - Serial.print("Content Disposition: "); - Serial.println(streaminfo.disposition); - - Serial.print("Text Character Set: "); - Serial.println(streaminfo.charSet); - - Serial.print("Content Transfer Encoding: "); - Serial.println(streaminfo.transfer_encoding); - - // The total octets of encoded or non-encoded MIME content. - // The size of decoded content may be different. - Serial.print("Total Octets: "); - Serial.println(streaminfo.octet_size); - - if (strcmp(streaminfo.disposition, "attachment") == 0 || strcmp(streaminfo.disposition, "inline") == 0) - { - - if (strcmp(streaminfo.disposition, "inline") == 0) - { - Serial.print("Content ID: "); - Serial.println(streaminfo.cid); - } - - Serial.print("Name: "); - Serial.println(streaminfo.name); - - Serial.print("File Name: "); - Serial.println(streaminfo.filename); - - Serial.print("Size: "); - Serial.println(streaminfo.size); - - Serial.print("Content Description: "); - Serial.println(streaminfo.description); - - Serial.print("Creation Date: "); - Serial.println(streaminfo.date); - } - - Serial.println("Content:"); - } - - progress = 100 * streaminfo.octet_count / streaminfo.octet_size; - - if (progress != lastProgress && (progress == 0 || progress == 100 || lastProgress + 5 <= progress)) - { - - lastProgress = progress; - - // The size of current decoded chunk data - Serial.print("Data Length: "); - Serial.print(streaminfo.data_size); - - Serial.print(", Reading %: "); - Serial.println(progress); - } - - // Decoded chunk data is available here - if (streaminfo.data) - { - - // If streaminfo.transfer_encoding is 'base64', - // to print or send null terminated string from stream data - - /** - char str[streaminfo.data_size + 1]; - memcpy(str, streaminfo.data, streaminfo.data_size); - str[streaminfo.data_size] = 0; - Serial.print(str); - */ - - // If streaminfo.transfer_encoding is not 'base64', the string can be - // taken directly from casting streaminfo.data as (const char*)streaminfo.data - - // To write data to file (if fs is File class object that open in appended mode) - // fs.write((uint8_t *)streaminfo.data, streaminfo.data_size); - - // streaminfo.data_size is not more than 512 - } - - if (streaminfo.isLastData) - { - Serial.println(); - Serial.println(); - } +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to read Email and collect the stream data to print or store via the callback function. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// Provide the SD card interfaces setting and mounting +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +void mimeDataStreamCallback(MIME_Data_Stream_Info streaminfo); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +int progress = 0; +int lastProgress = -1; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + +#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h + // Mount SD card. + SD_Card_Mounting(); // See src/extras/SDHelper.h +#endif + + /* Set the callback function to get MIME Data stream */ + imap.mimeDataStreamCallback(mimeDataStreamCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_sd; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /** Message UID to fetch or read e.g. 100. + * In this case we will get the UID from the max message number (lastest message) + */ + imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); + + /* Set seen flag */ + + // The message with "Seen" flagged means the message was already read or seen by user. + // The default value of this option is set to false. + // If you want to set the message flag as "Seen", set this option to true. + // If this option is false, the message flag was unchanged. + // To set or remove flag from message, see Set_Flags.ino example. + + // imap_data.fetch.set_seen = true; + + /* Read or search the Email and close the session */ + + // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, + // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag + // to message, see the Set_Flags.ino example. + MailClient.readMail(&imap); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void loop() +{ +} + +void mimeDataStreamCallback(MIME_Data_Stream_Info streaminfo) +{ + if (streaminfo.isFirstData) + { + progress = 0; + lastProgress = -1; + + Serial.print("Message UID: "); + Serial.println(streaminfo.uid); + + Serial.print("Content Type: "); + Serial.println(streaminfo.type); + + Serial.print("Content Disposition: "); + Serial.println(streaminfo.disposition); + + Serial.print("Text Character Set: "); + Serial.println(streaminfo.charSet); + + Serial.print("Content Transfer Encoding: "); + Serial.println(streaminfo.transfer_encoding); + + // The total octets of encoded or non-encoded MIME content. + // The size of decoded content may be different. + Serial.print("Total Octets: "); + Serial.println(streaminfo.octet_size); + + if (strcmp(streaminfo.disposition, "attachment") == 0 || strcmp(streaminfo.disposition, "inline") == 0) + { + + if (strcmp(streaminfo.disposition, "inline") == 0) + { + Serial.print("Content ID: "); + Serial.println(streaminfo.cid); + } + + Serial.print("Name: "); + Serial.println(streaminfo.name); + + Serial.print("File Name: "); + Serial.println(streaminfo.filename); + + Serial.print("Size: "); + Serial.println(streaminfo.size); + + Serial.print("Content Description: "); + Serial.println(streaminfo.description); + + Serial.print("Creation Date: "); + Serial.println(streaminfo.date); + } + + Serial.println("Content:"); + } + + progress = 100 * streaminfo.octet_count / streaminfo.octet_size; + + if (progress != lastProgress && (progress == 0 || progress == 100 || lastProgress + 5 <= progress)) + { + + lastProgress = progress; + + // The size of current decoded chunk data + Serial.print("Data Length: "); + Serial.print(streaminfo.data_size); + + Serial.print(", Reading %: "); + Serial.println(progress); + } + + // Decoded chunk data is available here + if (streaminfo.data) + { + + // If streaminfo.transfer_encoding is 'base64', + // to print or send null terminated string from stream data + + /** + char str[streaminfo.data_size + 1]; + memcpy(str, streaminfo.data, streaminfo.data_size); + str[streaminfo.data_size] = 0; + Serial.print(str); + */ + + // If streaminfo.transfer_encoding is not 'base64', the string can be + // taken directly from casting streaminfo.data as (const char*)streaminfo.data + + // To write data to file (if fs is File class object that open in appended mode) + // fs.write((uint8_t *)streaminfo.data, streaminfo.data_size); + + // streaminfo.data_size is not more than 512 + } + + if (streaminfo.isLastData) + { + Serial.println(); + Serial.println(); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_List/Delete_Messages_List.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_List/Delete_Messages_List.ino index 42020a5c9..51379247d 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_List/Delete_Messages_List.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_List/Delete_Messages_List.ino @@ -1,218 +1,218 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to delete messages from the mailbox. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* Define the MessageList class to add the message to delete */ - MessageList toDelete; - - /** Add message uid to delete to the list - * In this case we will delete last 10 messages by get the UID of these message - * and add it to the list - */ - for (int i = imap.selectedFolder().msgCount(); i > (int)imap.selectedFolder().msgCount() - 10 && i > 0; i--) - toDelete.add(imap.getUID(i)); - - /* Delete all messages in the list (move to trash) */ - if (imap.deleteMessages(&toDelete)) - Serial.println("\nMessages deleted"); - - /* Delete all messages permanently by assign the second param to true*/ - // imap.deleteMessages(&toDelete, true); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to delete messages from the mailbox. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Define the MessageList class to add the message to delete */ + MessageList toDelete; + + /** Add message uid to delete to the list + * In this case we will delete last 10 messages by get the UID of these message + * and add it to the list + */ + for (int i = imap.selectedFolder().msgCount(); i > (int)imap.selectedFolder().msgCount() - 10 && i > 0; i--) + toDelete.add(imap.getUID(i)); + + /* Delete all messages in the list (move to trash) */ + if (imap.deleteMessages(&toDelete)) + Serial.println("\nMessages deleted"); + + /* Delete all messages permanently by assign the second param to true*/ + // imap.deleteMessages(&toDelete, true); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_Message_Numbers_Ranges/Delete_Messages_Message_Numbers_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_Message_Numbers_Ranges/Delete_Messages_Message_Numbers_Ranges.ino index 8d589e625..f4221f17e 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_Message_Numbers_Ranges/Delete_Messages_Message_Numbers_Ranges.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_Message_Numbers_Ranges/Delete_Messages_Message_Numbers_Ranges.ino @@ -1,229 +1,229 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to delete messages from the mailbox using message numbers ranges. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* Copy all messages using UIDs ranges (last 10 message numbers) to the folder "test" */ - int msg_last = imap.selectedFolder().msgCount(); - int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; - - String sequence_set1 = String(msg_begin) + ":" + String(msg_last); - - if (imap.copyMessages(sequence_set1, true /* if sequence set are the UIDs */, F("test"))) - Serial.println("\nCopying messages using message numbers ranges success"); - else - Serial.println("\nError, copying messages using message numbers ranges"); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("test"))) - return; - - delay(10000); - - /* Delete all messages using UIDs ranges (last 10 message numbers) from the folder "test" */ - msg_last = imap.selectedFolder().msgCount(); - msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; - - sequence_set1 = String(msg_begin) + ":" + String(msg_last); - - if (imap.deleteMessages(sequence_set1, true /* if sequence set are the UIDs */, false)) - Serial.println("\nDeleting messages using message numbers ranges success"); - else - Serial.println("\nError, Deleting messages using message numbers ranges"); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to delete messages from the mailbox using message numbers ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Copy all messages using UIDs ranges (last 10 message numbers) to the folder "test" */ + int msg_last = imap.selectedFolder().msgCount(); + int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; + + String sequence_set1 = String(msg_begin) + ":" + String(msg_last); + + if (imap.copyMessages(sequence_set1, true /* if sequence set are the UIDs */, F("test"))) + Serial.println("\nCopying messages using message numbers ranges success"); + else + Serial.println("\nError, copying messages using message numbers ranges"); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("test"))) + return; + + delay(10000); + + /* Delete all messages using UIDs ranges (last 10 message numbers) from the folder "test" */ + msg_last = imap.selectedFolder().msgCount(); + msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; + + sequence_set1 = String(msg_begin) + ":" + String(msg_last); + + if (imap.deleteMessages(sequence_set1, true /* if sequence set are the UIDs */, false)) + Serial.println("\nDeleting messages using message numbers ranges success"); + else + Serial.println("\nError, Deleting messages using message numbers ranges"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_UIDs_Ranges/Delete_Messages_UIDs_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_UIDs_Ranges/Delete_Messages_UIDs_Ranges.ino index cb0c90d7f..086e27a32 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_UIDs_Ranges/Delete_Messages_UIDs_Ranges.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Delete_Messages/Delete_Messages_UIDs_Ranges/Delete_Messages_UIDs_Ranges.ino @@ -1,229 +1,229 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to delete messages from the mailbox using UIDs ranges. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* Copy all messages using UIDs ranges (last 10 UIDs) to the folder "test" */ - int uid_last = imap.getUID(imap.selectedFolder().msgCount()); - int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; - - String sequence_set1 = String(uid_begin) + ":" + String(uid_last); - - if (imap.copyMessages(sequence_set1, true /* if sequence set are the UIDs */, F("test"))) - Serial.println("Copying messages using UIDs ranges success"); - else - Serial.println("Error, copying messages using UIDs ranges"); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("test"))) - return; - - delay(10000); - - /* Delete all messages using UIDs ranges (last 10 UIDs) from the folder "test" */ - uid_last = imap.getUID(imap.selectedFolder().msgCount()); - uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; - - sequence_set1 = String(uid_begin) + ":" + String(uid_last); - - if (imap.deleteMessages(sequence_set1, true /* if sequence set are the UIDs */, false)) - Serial.println("Deleting messages using UIDs ranges success"); - else - Serial.println("Error, Deleting messages using UIDs ranges"); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to delete messages from the mailbox using UIDs ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Copy all messages using UIDs ranges (last 10 UIDs) to the folder "test" */ + int uid_last = imap.getUID(imap.selectedFolder().msgCount()); + int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; + + String sequence_set1 = String(uid_begin) + ":" + String(uid_last); + + if (imap.copyMessages(sequence_set1, true /* if sequence set are the UIDs */, F("test"))) + Serial.println("Copying messages using UIDs ranges success"); + else + Serial.println("Error, copying messages using UIDs ranges"); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("test"))) + return; + + delay(10000); + + /* Delete all messages using UIDs ranges (last 10 UIDs) from the folder "test" */ + uid_last = imap.getUID(imap.selectedFolder().msgCount()); + uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; + + sequence_set1 = String(uid_begin) + ":" + String(uid_last); + + if (imap.deleteMessages(sequence_set1, true /* if sequence set are the UIDs */, false)) + Serial.println("Deleting messages using UIDs ranges success"); + else + Serial.println("Error, Deleting messages using UIDs ranges"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/External_Client/External_Client.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/External_Client/External_Client.ino index 65e11b7b3..165c4b115 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/External_Client/External_Client.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/External_Client/External_Client.ino @@ -1,334 +1,334 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt - */ - -/** - * This example shows how to send Email using EthernetClient. - * - * This example used ESP32 and WIZnet W5500 Ethernet module. - * - * Please see examples/SMTP/Ethernet and examples/SMTP/External_Client for more usage - */ - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include - -#include - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -#define IMAP_HOST "" -#define IMAP_PORT 993 - -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -void imapCallback(IMAP_Status status); - -void printAllMailboxesInfo(IMAPSession &imap); - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -void printMessages(std::vector &msgItems, bool headerOnly); - -void printAttacements(std::vector &atts); - -IMAPSession imap; - -EthernetClient eth_client; - -void networkConnection() -{ - // Reset the network connection - WiFi.disconnect(); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - Serial.print("Connecting to Wi-Fi"); - unsigned long ms = millis(); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); - if (millis() - ms >= 5000) - { - Serial.println(" failed!"); - return; - } - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); -} - -void networkStatusRequestCallback() -{ - imap.setNetworkStatus(WiFi.status() == WL_CONNECTED); -} - -void setup() -{ - - Serial.begin(115200); - - Serial.println(); - - MailClient.networkReconnect(true); - - // The WiFi credentials are required for SAMD21 - // due to it does not have reconnect feature. - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); - - networkConnection(); - - imap.debug(1); - - /* - For internal NTP client - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - MailClient.setUDPClient(&udp_client, 0 /* GMT offset */); - - MailClient.networkReconnect(true); - - imap.callback(imapCallback); - - Session_Config config; - - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - IMAP_Data imap_data; - - imap_data.search.criteria.clear(); - - imap_data.search.unseen_msg = true; - - imap_data.storage.saved_path = F("/email_data"); - - imap_data.storage.type = esp_mail_file_storage_type_flash; - - imap_data.download.header = true; - imap_data.download.text = true; - imap_data.download.html = true; - imap_data.download.attachment = true; - imap_data.download.inlineImg = true; - - imap_data.enable.html = true; - imap_data.enable.text = true; - - imap_data.enable.recent_sort = true; - - imap_data.enable.download_status = true; - - imap_data.limit.search = 5; - - imap_data.limit.msg_size = 512; - - imap_data.limit.attachment_size = 1024 * 1024 * 5; - - imap.setClient(ð_client); - - imap.networkConnectionRequestCallback(networkConnection); - - imap.networkStatusRequestCallback(networkStatusRequestCallback); - - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - printAllMailboxesInfo(imap); - - if (!imap.selectFolder(F("INBOX"))) - return; - - printSelectedMailboxInfo(imap.selectedFolder()); - - imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); - - MailClient.readMail(&imap); - - imap.empty(); -} - -void loop() -{ -} - -void imapCallback(IMAP_Status status) -{ - Serial.println(status.info()); - - if (status.success()) - { - IMAP_MSG_List msgList = imap.data(); - printMessages(msgList.msgItems, imap.headerOnly()); - imap.empty(); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - FoldersCollection folders; - - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } -} - -void printAttacements(std::vector &atts) -{ - MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); - for (size_t j = 0; j < atts.size(); j++) - { - IMAP_Attach_Item att = atts[j]; - MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); - } - Serial.println(); -} - -void printMessages(std::vector &msgItems, bool headerOnly) -{ - - for (size_t i = 0; i < msgItems.size(); i++) - { - IMAP_MSG_Item msg = msgItems[i]; - - Serial.println("****************************"); - MailClient.printf("Number: %d\n", msg.msgNo); - MailClient.printf("UID: %d\n", msg.UID); - - // The attachment status in search may be true in case the "multipart/mixed" - // content type header was set with no real attachtment included. - MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); - - MailClient.printf("Messsage-ID: %s\n", msg.ID); - - if (strlen(msg.flags)) - MailClient.printf("Flags: %s\n", msg.flags); - if (strlen(msg.acceptLang)) - MailClient.printf("Accept Language: %s\n", msg.acceptLang); - if (strlen(msg.contentLang)) - MailClient.printf("Content Language: %s\n", msg.contentLang); - if (strlen(msg.from)) - MailClient.printf("From: %s\n", msg.from); - if (strlen(msg.sender)) - MailClient.printf("Sender: %s\n", msg.sender); - if (strlen(msg.to)) - MailClient.printf("To: %s\n", msg.to); - if (strlen(msg.cc)) - MailClient.printf("CC: %s\n", msg.cc); - if (strlen(msg.bcc)) - MailClient.printf("BCC: %s\n", msg.bcc); - if (strlen(msg.date)) - { - MailClient.printf("Date: %s\n", msg.date); - MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); - } - if (strlen(msg.subject)) - MailClient.printf("Subject: %s\n", msg.subject); - if (strlen(msg.reply_to)) - MailClient.printf("Reply-To: %s\n", msg.reply_to); - if (strlen(msg.return_path)) - MailClient.printf("Return-Path: %s\n", msg.return_path); - if (strlen(msg.in_reply_to)) - MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); - if (strlen(msg.references)) - MailClient.printf("References: %s\n", msg.references); - if (strlen(msg.comments)) - MailClient.printf("Comments: %s\n", msg.comments); - if (strlen(msg.keywords)) - MailClient.printf("Keywords: %s\n", msg.keywords); - - if (!headerOnly) - { - if (strlen(msg.text.content)) - MailClient.printf("Text Message: %s\n", msg.text.content); - if (strlen(msg.text.charSet)) - MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); - if (strlen(msg.text.transfer_encoding)) - MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - if (strlen(msg.html.content)) - MailClient.printf("HTML Message: %s\n", msg.html.content); - if (strlen(msg.html.charSet)) - MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); - if (strlen(msg.html.transfer_encoding)) - MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.rfc822.size() > 0) - { - MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - printMessages(msg.rfc822, headerOnly); - } - - if (msg.attachments.size() > 0) - printAttacements(msg.attachments); - } - - Serial.println(); - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +/** + * This example shows how to send Email using EthernetClient. + * + * This example used ESP32 and WIZnet W5500 Ethernet module. + * + * Please see examples/SMTP/Ethernet and examples/SMTP/External_Client for more usage + */ + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include + +#include + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define IMAP_HOST "" +#define IMAP_PORT 993 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +void imapCallback(IMAP_Status status); + +void printAllMailboxesInfo(IMAPSession &imap); + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +void printMessages(std::vector &msgItems, bool headerOnly); + +void printAttacements(std::vector &atts); + +IMAPSession imap; + +EthernetClient eth_client; + +void networkConnection() +{ + // Reset the network connection + WiFi.disconnect(); + + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + Serial.print("Connecting to Wi-Fi"); + unsigned long ms = millis(); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); + if (millis() - ms >= 5000) + { + Serial.println(" failed!"); + return; + } + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); +} + +void networkStatusRequestCallback() +{ + imap.setNetworkStatus(WiFi.status() == WL_CONNECTED); +} + +void setup() +{ + + Serial.begin(115200); + + Serial.println(); + + MailClient.networkReconnect(true); + + // The WiFi credentials are required for SAMD21 + // due to it does not have reconnect feature. + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); + + networkConnection(); + + imap.debug(1); + + /* + For internal NTP client + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + MailClient.setUDPClient(&udp_client, 0 /* GMT offset */); + + MailClient.networkReconnect(true); + + imap.callback(imapCallback); + + Session_Config config; + + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + IMAP_Data imap_data; + + imap_data.search.criteria.clear(); + + imap_data.search.unseen_msg = true; + + imap_data.storage.saved_path = F("/email_data"); + + imap_data.storage.type = esp_mail_file_storage_type_flash; + + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + imap_data.enable.html = true; + imap_data.enable.text = true; + + imap_data.enable.recent_sort = true; + + imap_data.enable.download_status = true; + + imap_data.limit.search = 5; + + imap_data.limit.msg_size = 512; + + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + imap.setClient(ð_client); + + imap.networkConnectionRequestCallback(networkConnection); + + imap.networkStatusRequestCallback(networkStatusRequestCallback); + + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + printAllMailboxesInfo(imap); + + if (!imap.selectFolder(F("INBOX"))) + return; + + printSelectedMailboxInfo(imap.selectedFolder()); + + imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); + + MailClient.readMail(&imap); + + imap.empty(); +} + +void loop() +{ +} + +void imapCallback(IMAP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + FoldersCollection folders; + + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + for (size_t i = 0; i < msgItems.size(); i++) + { + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Firmware_Update_Attachment/Firmware_Update_Attachment.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Firmware_Update_Attachment/Firmware_Update_Attachment.ino index 15f706daa..5bea6e380 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Firmware_Update_Attachment/Firmware_Update_Attachment.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Firmware_Update_Attachment/Firmware_Update_Attachment.ino @@ -1,464 +1,464 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to read Email and update firmware if firmware file name in attachments matches. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// Provide the SD card interfaces setting and mounting -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status); - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -/* Print all messages from the message list */ -void printMessages(std::vector &msgItems, bool headerOnly); - -/* Print all attachments info from the message */ -void printAttacements(std::vector &atts); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - -#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h - // Mount SD card. - SD_Card_Mounting(); // See src/extras/SDHelper.h -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Set the storage to save the downloaded files and attachments */ - imap_data.storage.saved_path = F("/email_data"); - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option imap_data.limit.msg_size. - * The whole message can be download through imap_data.download.text - * or imap_data.download.html which not depends on these enable options. - */ - imap_data.enable.html = true; - imap_data.enable.text = true; - - /* Assign the attachment filename to compare, update firmware if it matches */ - imap_data.firmware_update.attach_filename = "firmware.bin"; - /* save (download) firmware to file? */ - imap_data.firmware_update.save_to_file = false; - - /** - * Device will reboot in if imap.isFirmwareUpdated() returns true in imapCallback function. - * To disable firmware update, call imap_data.firmware_update.attach_filename.clear(); or - * imap_data.firmware_update.attach_filename = ""; - * - */ - - /* Set to enable the sort the result by message UID in the decending order */ - imap_data.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - imap_data.enable.download_status = true; - - /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud - , to allow case sensitive parse, uncomment below line*/ - // imap_data.enable.header_case_sensitive = true; - - /* Set the limit of number of messages in the search results */ - imap_data.limit.search = 5; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - imap_data.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - imap_data.limit.attachment_size = 1024 * 1024 * 5; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* {Optional} */ - printSelectedMailboxInfo(imap.selectedFolder()); - - /** Message UID to fetch or read e.g. 100. - * In this case we will get the UID from the max message number (lastest message) - */ - imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); - - // or fetch via the message sequence number - // imap_data.fetch.number = imap.selectedFolder().msgCount(); - - // if both imap_data.fetch.uid and imap_data.fetch.number were set, - // then total 2 messages will be fetched i.e. one using uid and other using number. - - /* Set seen flag */ - - // The message with "Seen" flagged means the message was already read or seen by user. - // The default value of this option is set to false. - // If you want to set the message flag as "Seen", set this option to true. - // If this option is false, the message flag was unchanged. - // To set or remove flag from message, see Set_Flags.ino example. - - // imap_data.fetch.set_seen = true; - - /* Read or search the Email and close the session */ - - // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, - // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag - // to message, see the Set_Flags.ino example. - MailClient.readMail(&imap); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); -} - -void loop() -{ -} - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Show the result when reading finished */ - if (status.success()) - { - /* Print the result */ - /* Get the message list from the message list data */ - IMAP_MSG_List msgList = imap.data(); - printMessages(msgList.msgItems, imap.headerOnly()); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - - if (imap.isFirmwareUpdateSuccess()) - { - Serial.println("****************************"); - Serial.println("Firmware is already updated, restarting device..."); - delay(2000); -#if defined(ESP32) || defined(ESP8266) - ESP.restart(); -#elif defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_NANO_RP2040_CONNECT) - rp2040.restart(); -#endif - } - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } -} - -void printAttacements(std::vector &atts) -{ - MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); - for (size_t j = 0; j < atts.size(); j++) - { - IMAP_Attach_Item att = atts[j]; - /** att.type can be - * esp_mail_att_type_none or 0 - * esp_mail_att_type_attachment or 1 - * esp_mail_att_type_inline or 2 - */ - MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); - } - Serial.println(); -} - -void printMessages(std::vector &msgItems, bool headerOnly) -{ - - /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and - * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename - * (> 13 characters) is not support in the SD.h library. - * To show how its original file name, use imap.fileList(). - */ - // Serial.println(imap.fileList()); - - for (size_t i = 0; i < msgItems.size(); i++) - { - - /* Iterate to get each message data through the message item data */ - IMAP_MSG_Item msg = msgItems[i]; - - Serial.println("****************************"); - MailClient.printf("Number: %d\n", msg.msgNo); - MailClient.printf("UID: %d\n", msg.UID); - - // The attachment status in search may be true in case the "multipart/mixed" - // content type header was set with no real attachtment included. - MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); - - MailClient.printf("Messsage-ID: %s\n", msg.ID); - - if (strlen(msg.flags)) - MailClient.printf("Flags: %s\n", msg.flags); - if (strlen(msg.acceptLang)) - MailClient.printf("Accept Language: %s\n", msg.acceptLang); - if (strlen(msg.contentLang)) - MailClient.printf("Content Language: %s\n", msg.contentLang); - if (strlen(msg.from)) - MailClient.printf("From: %s\n", msg.from); - if (strlen(msg.sender)) - MailClient.printf("Sender: %s\n", msg.sender); - if (strlen(msg.to)) - MailClient.printf("To: %s\n", msg.to); - if (strlen(msg.cc)) - MailClient.printf("CC: %s\n", msg.cc); - if (strlen(msg.bcc)) - MailClient.printf("BCC: %s\n", msg.bcc); - if (strlen(msg.date)) - { - MailClient.printf("Date: %s\n", msg.date); - MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); - } - if (strlen(msg.subject)) - MailClient.printf("Subject: %s\n", msg.subject); - if (strlen(msg.reply_to)) - MailClient.printf("Reply-To: %s\n", msg.reply_to); - if (strlen(msg.return_path)) - MailClient.printf("Return-Path: %s\n", msg.return_path); - if (strlen(msg.in_reply_to)) - MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); - if (strlen(msg.references)) - MailClient.printf("References: %s\n", msg.references); - if (strlen(msg.comments)) - MailClient.printf("Comments: %s\n", msg.comments); - if (strlen(msg.keywords)) - MailClient.printf("Keywords: %s\n", msg.keywords); - - /* If the result contains the message info (Fetch mode) */ - if (!headerOnly) - { - if (strlen(msg.text.content)) - MailClient.printf("Text Message: %s\n", msg.text.content); - if (strlen(msg.text.charSet)) - MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); - if (strlen(msg.text.transfer_encoding)) - MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - if (strlen(msg.html.content)) - MailClient.printf("HTML Message: %s\n", msg.html.content); - if (strlen(msg.html.charSet)) - MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); - if (strlen(msg.html.transfer_encoding)) - MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.rfc822.size() > 0) - { - MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - printMessages(msg.rfc822, headerOnly); - } - - if (msg.attachments.size() > 0) - printAttacements(msg.attachments); - } - - Serial.println(); - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to read Email and update firmware if firmware file name in attachments matches. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// Provide the SD card interfaces setting and mounting +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + +#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h + // Mount SD card. + SD_Card_Mounting(); // See src/extras/SDHelper.h +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Assign the attachment filename to compare, update firmware if it matches */ + imap_data.firmware_update.attach_filename = "firmware.bin"; + /* save (download) firmware to file? */ + imap_data.firmware_update.save_to_file = false; + + /** + * Device will reboot in if imap.isFirmwareUpdated() returns true in imapCallback function. + * To disable firmware update, call imap_data.firmware_update.attach_filename.clear(); or + * imap_data.firmware_update.attach_filename = ""; + * + */ + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /** Message UID to fetch or read e.g. 100. + * In this case we will get the UID from the max message number (lastest message) + */ + imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); + + // or fetch via the message sequence number + // imap_data.fetch.number = imap.selectedFolder().msgCount(); + + // if both imap_data.fetch.uid and imap_data.fetch.number were set, + // then total 2 messages will be fetched i.e. one using uid and other using number. + + /* Set seen flag */ + + // The message with "Seen" flagged means the message was already read or seen by user. + // The default value of this option is set to false. + // If you want to set the message flag as "Seen", set this option to true. + // If this option is false, the message flag was unchanged. + // To set or remove flag from message, see Set_Flags.ino example. + + // imap_data.fetch.set_seen = true; + + /* Read or search the Email and close the session */ + + // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, + // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag + // to message, see the Set_Flags.ino example. + MailClient.readMail(&imap); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void loop() +{ +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + + if (imap.isFirmwareUpdateSuccess()) + { + Serial.println("****************************"); + Serial.println("Firmware is already updated, restarting device..."); + delay(2000); +#if defined(ESP32) || defined(ESP8266) + ESP.restart(); +#elif defined(ARDUINO_ARCH_RP2040) && !defined(ARDUINO_NANO_RP2040_CONNECT) + rp2040.restart(); +#endif + } + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and + * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename + * (> 13 characters) is not support in the SD.h library. + * To show how its original file name, use imap.fileList(). + */ + // Serial.println(imap.fileList()); + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Get_Quota/Get_Quota.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Get_Quota/Get_Quota.ino index aae7f050d..4010247e9 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Get_Quota/Get_Quota.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Get_Quota/Get_Quota.ino @@ -1,215 +1,215 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to get the quota root's resource usage and limits. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - IMAP_Quota_Root_Info info; - - Serial.println("\nGet quota root..."); - - if (!imap.getQuota("", &info)) - { - Serial.println("Get quota root failed"); - } - else - { - MailClient.printf("Quota root: %s, Resource name: %s, Usage (k): %d, Limit (k): %d\n", info.quota_root.c_str(), info.name.c_str(), (int)info.usage, (int)info.limit); - } - - IMAP_Quota_Roots_List quota_roots; - - Serial.println("\nGet quota roots list for INBOX folder..."); - - if (!imap.getQuotaRoot("INBOX", "a_roots)) - { - Serial.println("\nGet quota roots list failed"); - } - else - { - for (size_t i = 0; i < quota_roots.size(); i++) - MailClient.printf("%d, Quota root: %s, Resource name: %s, Usage (k): %d, Limit (k): %d\n", (int)i + 1, quota_roots[i].quota_root.c_str(), quota_roots[i].name.c_str(), (int)quota_roots[i].usage, (int)quota_roots[i].limit); - } - - Serial.println("\nSet quota root..."); - - info.name = "STORAGE"; - info.limit = 1024 * 1024; // 1048576 k or 1 G. - - if (!imap.setQuota("", &info)) - { - Serial.println("\nSet quota root failed"); - } - else - { - Serial.println("\nSet quota root success"); - } - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to get the quota root's resource usage and limits. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + IMAP_Quota_Root_Info info; + + Serial.println("\nGet quota root..."); + + if (!imap.getQuota("", &info)) + { + Serial.println("Get quota root failed"); + } + else + { + MailClient.printf("Quota root: %s, Resource name: %s, Usage (k): %d, Limit (k): %d\n", info.quota_root.c_str(), info.name.c_str(), (int)info.usage, (int)info.limit); + } + + IMAP_Quota_Roots_List quota_roots; + + Serial.println("\nGet quota roots list for INBOX folder..."); + + if (!imap.getQuotaRoot("INBOX", "a_roots)) + { + Serial.println("\nGet quota roots list failed"); + } + else + { + for (size_t i = 0; i < quota_roots.size(); i++) + MailClient.printf("%d, Quota root: %s, Resource name: %s, Usage (k): %d, Limit (k): %d\n", (int)i + 1, quota_roots[i].quota_root.c_str(), quota_roots[i].name.c_str(), (int)quota_roots[i].usage, (int)quota_roots[i].limit); + } + + Serial.println("\nSet quota root..."); + + info.name = "STORAGE"; + info.limit = 1024 * 1024; // 1048576 k or 1 G. + + if (!imap.setQuota("", &info)) + { + Serial.println("\nSet quota root failed"); + } + else + { + Serial.println("\nSet quota root success"); + } + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Mailbox_Changes_Notification/Mailbox_Changes_Notification.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Mailbox_Changes_Notification/Mailbox_Changes_Notification.ino index 271a9f53a..0e01773f8 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Mailbox_Changes_Notification/Mailbox_Changes_Notification.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Mailbox_Changes_Notification/Mailbox_Changes_Notification.ino @@ -1,446 +1,446 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to get notification in realtime when incoming message arrived and other mailbox changes. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Print the selected folder update info */ -void printPollingStatus(IMAPSession &imap); - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status); - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -/* Print all messages from the message list */ -void printMessages(std::vector &msgItems, bool headerOnly); - -/* Print all attachments info from the message */ -void printAttacements(std::vector &atts); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -/* Declare the global used Session_Config for user defined session credentials */ -Session_Config config; - -/* Define the IMAP_Data object used for user defined IMAP operating options. */ -IMAP_Data imap_data; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void connectWiFi() -{ - WiFi.disconnect(); - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); -} - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - connectWiFi(); - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /** Assign internet connection handler function - * in case of lost internet connection for re-listening the mailbox. - */ - config.network_connection_handler = connectWiFi; - - // You can use TCP KeepAlive for more reliable of listen (idle) operation, please read this for detail. - // https://github.com/mobizt/ESP-Mail-Client#using-tcp-session-keepalive-in-esp8266-and-esp32 - // You can use keepAlive in ESP8266 core version newer than v3.1.2. - // Or you can use git version (v3.1.2) https://github.com/esp8266/Arduino -#if defined(ESP32) - imap.keepAlive(5, 5, 1); -#endif - - /* Set the TCP response read timeout in seconds */ - // smtp.setTCPTimeout(10); - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* {Optional} */ - printSelectedMailboxInfo(imap.selectedFolder()); -} - -void loop() -{ - /* imap.connect and imap.selectFolder or imap.openFolder nedded to be called once prior to listen */ - - // Listen for mailbox changes - if (!imap.listen()) - return; - - // Check the changes - if (imap.folderChanged()) - printPollingStatus(imap); - - // To stop listen, use imap.stopListen(); and to listen again, call imap.listen() -} - -void printPollingStatus(IMAPSession &imap) -{ - /* Declare the selected folder info class to get the info of selected mailbox folder */ - SelectedFolderInfo sFolder = imap.selectedFolder(); - - /* Show the mailbox info */ - MailClient.printf("\nMailbox status changed\n----------------------\nTotal Messages: %d\n", sFolder.msgCount()); - - if (sFolder.pollingStatus().type == imap_polling_status_type_new_message) - { - - MailClient.printf("New message %d, has been addedd, reading message...\n", (int)sFolder.pollingStatus().messageNum); - - // if (sFolder.recentCount() > 0) - // MailClient.printf("\nMesssage count which recent flag set: %d\n", sFolder.recentCount()); - - // we need to stop polling before do anything - imap.stopListen(); - - // Get the UID of new message and fetch - imap_data.fetch.uid = imap.getUID(sFolder.pollingStatus().messageNum); - MailClient.readMail(&imap, false); - } - else if (sFolder.pollingStatus().type == imap_polling_status_type_remove_message) - MailClient.printf("Message %d, has been removed\n\n", (int)sFolder.pollingStatus().messageNum); - else if (sFolder.pollingStatus().type == imap_polling_status_type_fetch_message) - MailClient.printf("Message %d, has been fetched with the argument %s\n\n", (int)sFolder.pollingStatus().messageNum, sFolder.pollingStatus().argument.c_str()); -} - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Show the result when reading finished */ - if (status.success()) - { - /* Print the result */ - /* Get the message list from the message list data */ - IMAP_MSG_List msgList = imap.data(); - printMessages(msgList.msgItems, imap.headerOnly()); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } -} - -void printAttacements(std::vector &atts) -{ - MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); - for (size_t j = 0; j < atts.size(); j++) - { - IMAP_Attach_Item att = atts[j]; - /** att.type can be - * esp_mail_att_type_none or 0 - * esp_mail_att_type_attachment or 1 - * esp_mail_att_type_inline or 2 - */ - MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); - } - Serial.println(); -} - -void printMessages(std::vector &msgItems, bool headerOnly) -{ - - for (size_t i = 0; i < msgItems.size(); i++) - { - - /* Iterate to get each message data through the message item data */ - IMAP_MSG_Item msg = msgItems[i]; - - Serial.println("****************************"); - MailClient.printf("Number: %d\n", msg.msgNo); - MailClient.printf("UID: %d\n", msg.UID); - - // The attachment status in search may be true in case the "multipart/mixed" - // content type header was set with no real attachtment included. - MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); - - MailClient.printf("Messsage-ID: %s\n", msg.ID); - - if (strlen(msg.flags)) - MailClient.printf("Flags: %s\n", msg.flags); - if (strlen(msg.acceptLang)) - MailClient.printf("Accept Language: %s\n", msg.acceptLang); - if (strlen(msg.contentLang)) - MailClient.printf("Content Language: %s\n", msg.contentLang); - if (strlen(msg.from)) - MailClient.printf("From: %s\n", msg.from); - if (strlen(msg.sender)) - MailClient.printf("Sender: %s\n", msg.sender); - if (strlen(msg.to)) - MailClient.printf("To: %s\n", msg.to); - if (strlen(msg.cc)) - MailClient.printf("CC: %s\n", msg.cc); - if (strlen(msg.bcc)) - MailClient.printf("BCC: %s\n", msg.bcc); - if (strlen(msg.date)) - { - MailClient.printf("Date: %s\n", msg.date); - MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); - } - if (strlen(msg.subject)) - MailClient.printf("Subject: %s\n", msg.subject); - if (strlen(msg.reply_to)) - MailClient.printf("Reply-To: %s\n", msg.reply_to); - if (strlen(msg.return_path)) - MailClient.printf("Return-Path: %s\n", msg.return_path); - if (strlen(msg.in_reply_to)) - MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); - if (strlen(msg.references)) - MailClient.printf("References: %s\n", msg.references); - if (strlen(msg.comments)) - MailClient.printf("Comments: %s\n", msg.comments); - if (strlen(msg.keywords)) - MailClient.printf("Keywords: %s\n", msg.keywords); - - /* If the result contains the message info (Fetch mode) */ - if (!headerOnly) - { - if (strlen(msg.text.content)) - MailClient.printf("Text Message: %s\n", msg.text.content); - if (strlen(msg.text.charSet)) - MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); - if (strlen(msg.text.transfer_encoding)) - MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - if (strlen(msg.html.content)) - MailClient.printf("HTML Message: %s\n", msg.html.content); - if (strlen(msg.html.charSet)) - MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); - if (strlen(msg.html.transfer_encoding)) - MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.rfc822.size() > 0) - { - MailClient.printf("RFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - printMessages(msg.rfc822, headerOnly); - } - } - - Serial.println(); - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to get notification in realtime when incoming message arrived and other mailbox changes. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the selected folder update info */ +void printPollingStatus(IMAPSession &imap); + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +/* Declare the global used Session_Config for user defined session credentials */ +Session_Config config; + +/* Define the IMAP_Data object used for user defined IMAP operating options. */ +IMAP_Data imap_data; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void connectWiFi() +{ + WiFi.disconnect(); + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + connectWiFi(); + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /** Assign internet connection handler function + * in case of lost internet connection for re-listening the mailbox. + */ + config.network_connection_handler = connectWiFi; + + // You can use TCP KeepAlive for more reliable of listen (idle) operation, please read this for detail. + // https://github.com/mobizt/ESP-Mail-Client#using-tcp-session-keepalive-in-esp8266-and-esp32 + // You can use keepAlive in ESP8266 core version newer than v3.1.2. + // Or you can use git version (v3.1.2) https://github.com/esp8266/Arduino +#if defined(ESP32) + imap.keepAlive(5, 5, 1); +#endif + + /* Set the TCP response read timeout in seconds */ + // smtp.setTCPTimeout(10); + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); +} + +void loop() +{ + /* imap.connect and imap.selectFolder or imap.openFolder nedded to be called once prior to listen */ + + // Listen for mailbox changes + if (!imap.listen()) + return; + + // Check the changes + if (imap.folderChanged()) + printPollingStatus(imap); + + // To stop listen, use imap.stopListen(); and to listen again, call imap.listen() +} + +void printPollingStatus(IMAPSession &imap) +{ + /* Declare the selected folder info class to get the info of selected mailbox folder */ + SelectedFolderInfo sFolder = imap.selectedFolder(); + + /* Show the mailbox info */ + MailClient.printf("\nMailbox status changed\n----------------------\nTotal Messages: %d\n", sFolder.msgCount()); + + if (sFolder.pollingStatus().type == imap_polling_status_type_new_message) + { + + MailClient.printf("New message %d, has been addedd, reading message...\n", (int)sFolder.pollingStatus().messageNum); + + // if (sFolder.recentCount() > 0) + // MailClient.printf("\nMesssage count which recent flag set: %d\n", sFolder.recentCount()); + + // we need to stop polling before do anything + imap.stopListen(); + + // Get the UID of new message and fetch + imap_data.fetch.uid = imap.getUID(sFolder.pollingStatus().messageNum); + MailClient.readMail(&imap, false); + } + else if (sFolder.pollingStatus().type == imap_polling_status_type_remove_message) + MailClient.printf("Message %d, has been removed\n\n", (int)sFolder.pollingStatus().messageNum); + else if (sFolder.pollingStatus().type == imap_polling_status_type_fetch_message) + MailClient.printf("Message %d, has been fetched with the argument %s\n\n", (int)sFolder.pollingStatus().messageNum, sFolder.pollingStatus().argument.c_str()); +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("RFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_List/Move_Messages_List.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_List/Move_Messages_List.ino index bf95fcc20..5a779ea54 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_List/Move_Messages_List.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_List/Move_Messages_List.ino @@ -1,214 +1,214 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to move messages from the mailbox to other folder. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* Define the MessageList class to add the message to move */ - MessageList toMove; - - /* Add message uid to move to the list */ - toMove.add(3); - toMove.add(4); - - // imap.createFolder("test"); - - /* Move all messages in the list to the folder "test" */ - if (imap.moveMessages(&toMove, F("test"))) - Serial.println("\nMessages moved"); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to move messages from the mailbox to other folder. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Define the MessageList class to add the message to move */ + MessageList toMove; + + /* Add message uid to move to the list */ + toMove.add(3); + toMove.add(4); + + // imap.createFolder("test"); + + /* Move all messages in the list to the folder "test" */ + if (imap.moveMessages(&toMove, F("test"))) + Serial.println("\nMessages moved"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_Message_Numbers_Ranges/Move_Messages_Message_Numbers_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_Message_Numbers_Ranges/Move_Messages_Message_Numbers_Ranges.ino index 329c9db99..48b21c2e0 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_Message_Numbers_Ranges/Move_Messages_Message_Numbers_Ranges.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_Message_Numbers_Ranges/Move_Messages_Message_Numbers_Ranges.ino @@ -1,213 +1,213 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to move messages from the mailbox to other folder using message numbers ranges. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* Move all messages using message sequence ranges (last 10 message numbers) to the folder "test"*/ - int msg_last = imap.selectedFolder().msgCount(); - int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; - - String sequence_set2 = String(msg_begin) + ":" + String(msg_last); - - if (imap.moveMessages(sequence_set2, false /* if sequence set are message numbers not UIDs */, F("test"))) - Serial.println("\nMoving messages using message numbers ranges success"); - else - Serial.println("\nError, moving messages using message numbers ranges"); - - // imap.deleteolder("test"); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to move messages from the mailbox to other folder using message numbers ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Move all messages using message sequence ranges (last 10 message numbers) to the folder "test"*/ + int msg_last = imap.selectedFolder().msgCount(); + int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; + + String sequence_set2 = String(msg_begin) + ":" + String(msg_last); + + if (imap.moveMessages(sequence_set2, false /* if sequence set are message numbers not UIDs */, F("test"))) + Serial.println("\nMoving messages using message numbers ranges success"); + else + Serial.println("\nError, moving messages using message numbers ranges"); + + // imap.deleteolder("test"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_UIDs_Ranges/Move_Messages_UIDs_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_UIDs_Ranges/Move_Messages_UIDs_Ranges.ino index 3d75cc065..97a631fe5 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_UIDs_Ranges/Move_Messages_UIDs_Ranges.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Move_Messages/Move_Messages_UIDs_Ranges/Move_Messages_UIDs_Ranges.ino @@ -1,214 +1,214 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to move messages from the mailbox to other folder using UIDs ranges. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* Move all messages using UIDs ranges (last 10 UIDs) to the folder "test" */ - int uid_last = imap.getUID(imap.selectedFolder().msgCount()); - int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; - - String sequence_set1 = String(uid_begin) + ":" + String(uid_last); - - if (imap.moveMessages(sequence_set1, true /* if sequence set are the UIDs */, F("test"))) - Serial.println("\nMoving messages using UIDs ranges success"); - else - Serial.println("\nError, moving messages using UIDs ranges"); - - // imap.deleteolder("test"); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to move messages from the mailbox to other folder using UIDs ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* Move all messages using UIDs ranges (last 10 UIDs) to the folder "test" */ + int uid_last = imap.getUID(imap.selectedFolder().msgCount()); + int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; + + String sequence_set1 = String(uid_begin) + ":" + String(uid_last); + + if (imap.moveMessages(sequence_set1, true /* if sequence set are the UIDs */, F("test"))) + Serial.println("\nMoving messages using UIDs ranges success"); + else + Serial.println("\nError, moving messages using UIDs ranges"); + + // imap.deleteolder("test"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Namespaces/Namespaces.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Namespaces/Namespaces.ino index 533d90dcf..5e7dceee5 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Namespaces/Namespaces.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Namespaces/Namespaces.ino @@ -1,216 +1,216 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to get the namespaces. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - IMAP_Namespaces_List ns_list; - - Serial.println("\nGet namespaces..."); - - if (!imap.getNamespace(&ns_list)) - { - Serial.println("\nGet namespaces failed"); - } - else - { - if (ns_list.personal_namespaces.size() > 0) - { - Serial.println("\nPersonal Namespaces..."); - for (size_t i = 0; i < ns_list.personal_namespaces.size(); i++) - { - MailClient.printf("Prefix: %s, Delimiter: %s\n", ns_list.personal_namespaces[i].prefix.c_str(), ns_list.personal_namespaces[i].delimiter.c_str()); - } - } - - if (ns_list.other_users_namespaces.size() > 0) - { - Serial.println("\nOther Users Namespaces..."); - for (size_t i = 0; i < ns_list.other_users_namespaces.size(); i++) - { - MailClient.printf("Prefix: %s, Delimiter: %s\n", ns_list.other_users_namespaces[i].prefix.c_str(), ns_list.other_users_namespaces[i].delimiter.c_str()); - } - } - - if (ns_list.shared_namespaces.size() > 0) - { - Serial.println("\nShared Namespaces..."); - for (size_t i = 0; i < ns_list.shared_namespaces.size(); i++) - { - MailClient.printf("Prefix: %s, Delimiter: %s\n", ns_list.shared_namespaces[i].prefix.c_str(), ns_list.shared_namespaces[i].delimiter.c_str()); - } - } - } - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to get the namespaces. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + IMAP_Namespaces_List ns_list; + + Serial.println("\nGet namespaces..."); + + if (!imap.getNamespace(&ns_list)) + { + Serial.println("\nGet namespaces failed"); + } + else + { + if (ns_list.personal_namespaces.size() > 0) + { + Serial.println("\nPersonal Namespaces..."); + for (size_t i = 0; i < ns_list.personal_namespaces.size(); i++) + { + MailClient.printf("Prefix: %s, Delimiter: %s\n", ns_list.personal_namespaces[i].prefix.c_str(), ns_list.personal_namespaces[i].delimiter.c_str()); + } + } + + if (ns_list.other_users_namespaces.size() > 0) + { + Serial.println("\nOther Users Namespaces..."); + for (size_t i = 0; i < ns_list.other_users_namespaces.size(); i++) + { + MailClient.printf("Prefix: %s, Delimiter: %s\n", ns_list.other_users_namespaces[i].prefix.c_str(), ns_list.other_users_namespaces[i].delimiter.c_str()); + } + } + + if (ns_list.shared_namespaces.size() > 0) + { + Serial.println("\nShared Namespaces..."); + for (size_t i = 0; i < ns_list.shared_namespaces.size(); i++) + { + MailClient.printf("Prefix: %s, Delimiter: %s\n", ns_list.shared_namespaces[i].prefix.c_str(), ns_list.shared_namespaces[i].delimiter.c_str()); + } + } + } + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Email_Access_Token/Read_Email_Access_Token.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Email_Access_Token/Read_Email_Access_Token.ino index 26b32a91b..f3cce8165 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Email_Access_Token/Read_Email_Access_Token.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Email_Access_Token/Read_Email_Access_Token.ino @@ -1,472 +1,472 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example will log in with the SASL XOAUTH2 mechanisme using OAuth2.0 access token. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" - -/** The OAuth2.0 access token - * The generation, exchange and refresh of the access token are not available - * in this library. - * - * To test this using GMail, get the OAuth2.0 access token from this web site - * https://developers.google.com/oauthplayground/ - * - * 1. Select the following scope (in Step 1) from Gmail API V1 - * https://mail.google.com/ - * https://mail.google.com/ - * - * 2. Click Authorize APIs button. - * 3. Cick Exchangeauthorization code for tokens. - * 4. From the response, look at access_token from the JSON payload node. - * 5. Copy that access token and paste to the AUTHOR_ACCESS_TOKEN value. - * - * The token will be expired in 3600 seconds (1 Hr). - * The AUTHOR_EMAIL above is the Email address that you granted to access the Gmail services. - */ -#define AUTHOR_ACCESS_TOKEN "" - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status); - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -/* Print all messages from the message list */ -void printMessages(std::vector &msgItems, bool headerOnly); - -/* Print all attachments info from the message */ -void printAttacements(std::vector &atts); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.accessToken = AUTHOR_ACCESS_TOKEN; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Message UID to fetch or read e.g. 100 */ - imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); - - /* Set seen flag*/ - // imap_data.fetch.set_seen = true; - - /* Search criteria */ - imap_data.search.criteria.clear(); - - /* Also search the unseen message */ - imap_data.search.unseen_msg = true; - - /* Set the storage to save the downloaded files and attachments */ - imap_data.storage.saved_path = F("/email_data"); - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - imap_data.storage.type = esp_mail_file_storage_type_flash; - - /** Set to download headers, text and html messaeges, - * attachments and inline images respectively. - */ - imap_data.download.header = true; - imap_data.download.text = true; - imap_data.download.html = true; - imap_data.download.attachment = true; - imap_data.download.inlineImg = true; - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option imap_data.limit.msg_size. - * The whole message can be download through imap_data.download.text - * or imap_data.download.html which not depends on these enable options. - */ - imap_data.enable.html = true; - imap_data.enable.text = true; - - /* Set to enable the sort the result by message UID in the decending order */ - imap_data.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - imap_data.enable.download_status = true; - - /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud - , to allow case sensitive parse, uncomment below line*/ - // imap_data.enable.header_case_sensitive = true; - - /* Set the limit of number of messages in the search results */ - imap_data.limit.search = 5; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - imap_data.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - imap_data.limit.attachment_size = 1024 * 1024 * 5; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* {Optional} */ - printSelectedMailboxInfo(imap.selectedFolder()); - - /* Read or search the Email and close the session */ - - // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, - // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag - // to message, see the Set_Flags.ino example. - MailClient.readMail(&imap); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); -} - -void loop() -{ -} - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Show the result when reading finished */ - if (status.success()) - { - /* Print the result */ - /* Get the message list from the message list data */ - IMAP_MSG_List msgList = imap.data(); - printMessages(msgList.msgItems, imap.headerOnly()); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } -} - -void printAttacements(std::vector &atts) -{ - MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); - for (size_t j = 0; j < atts.size(); j++) - { - IMAP_Attach_Item att = atts[j]; - /** att.type can be - * esp_mail_att_type_none or 0 - * esp_mail_att_type_attachment or 1 - * esp_mail_att_type_inline or 2 - */ - MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); - } - Serial.println(); -} - -void printMessages(std::vector &msgItems, bool headerOnly) -{ - - /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and - * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename - * (> 13 characters) is not support in the SD.h library. - * To show how its original file name, use imap.fileList(). - */ - // Serial.println(imap.fileList()); - - for (size_t i = 0; i < msgItems.size(); i++) - { - - /* Iterate to get each message data through the message item data */ - IMAP_MSG_Item msg = msgItems[i]; - - Serial.println("****************************"); - MailClient.printf("Number: %d\n", msg.msgNo); - MailClient.printf("UID: %d\n", msg.UID); - - // The attachment status in search may be true in case the "multipart/mixed" - // content type header was set with no real attachtment included. - MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); - - MailClient.printf("Messsage-ID: %s\n", msg.ID); - - if (strlen(msg.flags)) - MailClient.printf("Flags: %s\n", msg.flags); - if (strlen(msg.acceptLang)) - MailClient.printf("Accept Language: %s\n", msg.acceptLang); - if (strlen(msg.contentLang)) - MailClient.printf("Content Language: %s\n", msg.contentLang); - if (strlen(msg.from)) - MailClient.printf("From: %s\n", msg.from); - if (strlen(msg.sender)) - MailClient.printf("Sender: %s\n", msg.sender); - if (strlen(msg.to)) - MailClient.printf("To: %s\n", msg.to); - if (strlen(msg.cc)) - MailClient.printf("CC: %s\n", msg.cc); - if (strlen(msg.bcc)) - MailClient.printf("BCC: %s\n", msg.bcc); - if (strlen(msg.date)) - { - MailClient.printf("Date: %s\n", msg.date); - MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); - } - if (strlen(msg.subject)) - MailClient.printf("Subject: %s\n", msg.subject); - if (strlen(msg.reply_to)) - MailClient.printf("Reply-To: %s\n", msg.reply_to); - if (strlen(msg.return_path)) - MailClient.printf("Return-Path: %s\n", msg.return_path); - if (strlen(msg.in_reply_to)) - MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); - if (strlen(msg.references)) - MailClient.printf("References: %s\n", msg.references); - if (strlen(msg.comments)) - MailClient.printf("Comments: %s\n", msg.comments); - if (strlen(msg.keywords)) - MailClient.printf("Keywords: %s\n", msg.keywords); - - /* If the result contains the message info (Fetch mode) */ - if (!headerOnly) - { - if (strlen(msg.text.content)) - MailClient.printf("Text Message: %s\n", msg.text.content); - if (strlen(msg.text.charSet)) - MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); - if (strlen(msg.text.transfer_encoding)) - MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - if (strlen(msg.html.content)) - MailClient.printf("HTML Message: %s\n", msg.html.content); - if (strlen(msg.html.charSet)) - MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); - if (strlen(msg.html.transfer_encoding)) - MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.rfc822.size() > 0) - { - MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - printMessages(msg.rfc822, headerOnly); - } - - if (msg.attachments.size() > 0) - printAttacements(msg.attachments); - } - - Serial.println(); - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example will log in with the SASL XOAUTH2 mechanisme using OAuth2.0 access token. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only IMAP functions, you can exclude the SMTP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" + +/** The OAuth2.0 access token + * The generation, exchange and refresh of the access token are not available + * in this library. + * + * To test this using GMail, get the OAuth2.0 access token from this web site + * https://developers.google.com/oauthplayground/ + * + * 1. Select the following scope (in Step 1) from Gmail API V1 + * https://mail.google.com/ + * https://mail.google.com/ + * + * 2. Click Authorize APIs button. + * 3. Cick Exchangeauthorization code for tokens. + * 4. From the response, look at access_token from the JSON payload node. + * 5. Copy that access token and paste to the AUTHOR_ACCESS_TOKEN value. + * + * The token will be expired in 3600 seconds (1 Hr). + * The AUTHOR_EMAIL above is the Email address that you granted to access the Gmail services. + */ +#define AUTHOR_ACCESS_TOKEN "" + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.accessToken = AUTHOR_ACCESS_TOKEN; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Message UID to fetch or read e.g. 100 */ + imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); + + /* Set seen flag*/ + // imap_data.fetch.set_seen = true; + + /* Search criteria */ + imap_data.search.criteria.clear(); + + /* Also search the unseen message */ + imap_data.search.unseen_msg = true; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_flash; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /* Read or search the Email and close the session */ + + // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, + // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag + // to message, see the Set_Flags.ino example. + MailClient.readMail(&imap); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void loop() +{ +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and + * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename + * (> 13 characters) is not support in the SD.h library. + * To show how its original file name, use imap.fileList(). + */ + // Serial.println(imap.fileList()); + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Sequence_Set/Read_Sequence_Set.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Sequence_Set/Read_Sequence_Set.ino index 63ce16c97..0afe9318a 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Sequence_Set/Read_Sequence_Set.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Sequence_Set/Read_Sequence_Set.ino @@ -1,477 +1,477 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to read Email using UIDs ranges or message numbers ranges. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** Assign SD card type and FS used in src/ESP_Mail_FS.h and - * change the config for that card interfaces in src/extras/SDHelper.h - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status); - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -/* Print all messages from the message list */ -void printMessages(std::vector &msgItems, bool headerOnly); - -/* Print all attachments info from the message */ -void printAttacements(std::vector &atts); - -/* Declare the Session_Config for user defined session credentials */ -Session_Config config; - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -/* Define the IMAP_Data object used for user defined IMAP operating options. */ -IMAP_Data imap_data; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void readEmailsUIDS() -{ - - int uid_last = imap.getUID(imap.selectedFolder().msgCount()); - int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; - - // Fetch last 10 UIDs - String sequence_set = String(uid_begin) + ":" + String(uid_last); - - imap_data.fetch.sequence_set.string = sequence_set; - - imap_data.fetch.sequence_set.UID = true; // The sequence set are UIDs ranges - - imap_data.fetch.sequence_set.headerOnly = true; // Do not fetch the content, header only - - MailClient.readMail(&imap, false /* do not close sessiopn */); - - imap_data.limit.fetch = 5; // Set the limit of number of messages in the fetch results -} - -void readEmailsNumbers() -{ - int msg_last = imap.selectedFolder().msgCount(); - int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; - - String sequence_set = String(msg_begin) + ":" + String(msg_last); - - imap_data.fetch.sequence_set.string = sequence_set; - - imap_data.fetch.sequence_set.UID = false; // The sequence set are not UIDs - - imap_data.fetch.sequence_set.headerOnly = true; // Do not fetch the content, header only - - imap_data.limit.fetch = 5; // Set the limit of number of messages in the fetch results - - // Read Email and close session - MailClient.readMail(&imap); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); -} - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Set the storage to save the downloaded files and attachments */ - imap_data.storage.saved_path = F("/email_data"); - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option imap_data.limit.msg_size. - * The whole message can be download through imap_data.download.text - * or imap_data.download.html which not depends on these enable options. - */ - imap_data.enable.html = true; - imap_data.enable.text = true; - - /* Set to enable the sort the result by message UID in the decending order */ - imap_data.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - imap_data.enable.download_status = true; - - /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud - , to allow case sensitive parse, uncomment below line*/ - // imap_data.enable.header_case_sensitive = true; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - imap_data.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - imap_data.limit.attachment_size = 1024 * 1024 * 5; - - // If ID extension was supported by IMAP server, assign the client identification - // name, version, vendor, os, os_version, support_url, address, command, arguments, environment - // Server ID can be optained from imap.serverID() after calling imap.connect and imap.id. - - // imap_data.identification.name = "User"; - // imap_data.identification.version = "1.0"; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - // Client identification can be sent to server later with - /** - * IMAP_Identification iden; - * iden.name = "user"; - * iden.version = "1.0"; - * - * if (imap.id(&iden)) - * { - * Serial.println("\nSend Identification success"); - * Serial.println(imap.serverID()); - * } - * else - * MailClient.printf("nIdentification sending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); - */ - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* {Optional} */ - printSelectedMailboxInfo(imap.selectedFolder()); - - Serial.println("::::::::::::::::: Reading Emails using the UIDs ranges ::::::::::::::::"); - readEmailsUIDS(); - - Serial.println("::::::::::: Reading Emails using the message numbers ranges :::::::::::"); - readEmailsNumbers(); -} - -void loop() -{ -} - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Show the result when reading finished */ - if (status.success()) - { - /* Print the result */ - /* Get the message list from the message list data */ - IMAP_MSG_List msgList = imap.data(); - printMessages(msgList.msgItems, imap.headerOnly()); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } -} - -void printAttacements(std::vector &atts) -{ - MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); - for (size_t j = 0; j < atts.size(); j++) - { - IMAP_Attach_Item att = atts[j]; - /** att.type can be - * esp_mail_att_type_none or 0 - * esp_mail_att_type_attachment or 1 - * esp_mail_att_type_inline or 2 - */ - MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); - } - Serial.println(); -} - -void printMessages(std::vector &msgItems, bool headerOnly) -{ - - /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and - * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename - * (> 13 characters) is not support in the SD.h library. - * To show how its original file name, use imap.fileList(). - */ - // Serial.println(imap.fileList()); - - for (size_t i = 0; i < msgItems.size(); i++) - { - - /* Iterate to get each message data through the message item data */ - IMAP_MSG_Item msg = msgItems[i]; - - Serial.println("****************************"); - MailClient.printf("Number: %d\n", msg.msgNo); - MailClient.printf("UID: %d\n", msg.UID); - - // The attachment status in search may be true in case the "multipart/mixed" - // content type header was set with no real attachtment included. - MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); - - MailClient.printf("Messsage-ID: %s\n", msg.ID); - - if (strlen(msg.flags)) - MailClient.printf("Flags: %s\n", msg.flags); - if (strlen(msg.acceptLang)) - MailClient.printf("Accept Language: %s\n", msg.acceptLang); - if (strlen(msg.contentLang)) - MailClient.printf("Content Language: %s\n", msg.contentLang); - if (strlen(msg.from)) - MailClient.printf("From: %s\n", msg.from); - if (strlen(msg.sender)) - MailClient.printf("Sender: %s\n", msg.sender); - if (strlen(msg.to)) - MailClient.printf("To: %s\n", msg.to); - if (strlen(msg.cc)) - MailClient.printf("CC: %s\n", msg.cc); - if (strlen(msg.bcc)) - MailClient.printf("BCC: %s\n", msg.bcc); - if (strlen(msg.date)) - { - MailClient.printf("Date: %s\n", msg.date); - MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); - } - if (strlen(msg.subject)) - MailClient.printf("Subject: %s\n", msg.subject); - if (strlen(msg.reply_to)) - MailClient.printf("Reply-To: %s\n", msg.reply_to); - if (strlen(msg.return_path)) - MailClient.printf("Return-Path: %s\n", msg.return_path); - if (strlen(msg.in_reply_to)) - MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); - if (strlen(msg.references)) - MailClient.printf("References: %s\n", msg.references); - if (strlen(msg.comments)) - MailClient.printf("Comments: %s\n", msg.comments); - if (strlen(msg.keywords)) - MailClient.printf("Keywords: %s\n", msg.keywords); - - /* If the result contains the message info (Fetch mode) */ - if (!headerOnly) - { - if (strlen(msg.text.content)) - MailClient.printf("Text Message: %s\n", msg.text.content); - if (strlen(msg.text.charSet)) - MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); - if (strlen(msg.text.transfer_encoding)) - MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - if (strlen(msg.html.content)) - MailClient.printf("HTML Message: %s\n", msg.html.content); - if (strlen(msg.html.charSet)) - MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); - if (strlen(msg.html.transfer_encoding)) - MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.rfc822.size() > 0) - { - MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - printMessages(msg.rfc822, headerOnly); - } - - if (msg.attachments.size() > 0) - printAttacements(msg.attachments); - } - - Serial.println(); - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to read Email using UIDs ranges or message numbers ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the Session_Config for user defined session credentials */ +Session_Config config; + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +/* Define the IMAP_Data object used for user defined IMAP operating options. */ +IMAP_Data imap_data; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void readEmailsUIDS() +{ + + int uid_last = imap.getUID(imap.selectedFolder().msgCount()); + int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; + + // Fetch last 10 UIDs + String sequence_set = String(uid_begin) + ":" + String(uid_last); + + imap_data.fetch.sequence_set.string = sequence_set; + + imap_data.fetch.sequence_set.UID = true; // The sequence set are UIDs ranges + + imap_data.fetch.sequence_set.headerOnly = true; // Do not fetch the content, header only + + MailClient.readMail(&imap, false /* do not close sessiopn */); + + imap_data.limit.fetch = 5; // Set the limit of number of messages in the fetch results +} + +void readEmailsNumbers() +{ + int msg_last = imap.selectedFolder().msgCount(); + int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; + + String sequence_set = String(msg_begin) + ":" + String(msg_last); + + imap_data.fetch.sequence_set.string = sequence_set; + + imap_data.fetch.sequence_set.UID = false; // The sequence set are not UIDs + + imap_data.fetch.sequence_set.headerOnly = true; // Do not fetch the content, header only + + imap_data.limit.fetch = 5; // Set the limit of number of messages in the fetch results + + // Read Email and close session + MailClient.readMail(&imap); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + // If ID extension was supported by IMAP server, assign the client identification + // name, version, vendor, os, os_version, support_url, address, command, arguments, environment + // Server ID can be optained from imap.serverID() after calling imap.connect and imap.id. + + // imap_data.identification.name = "User"; + // imap_data.identification.version = "1.0"; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + // Client identification can be sent to server later with + /** + * IMAP_Identification iden; + * iden.name = "user"; + * iden.version = "1.0"; + * + * if (imap.id(&iden)) + * { + * Serial.println("\nSend Identification success"); + * Serial.println(imap.serverID()); + * } + * else + * MailClient.printf("nIdentification sending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + */ + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + Serial.println("::::::::::::::::: Reading Emails using the UIDs ranges ::::::::::::::::"); + readEmailsUIDS(); + + Serial.println("::::::::::: Reading Emails using the message numbers ranges :::::::::::"); + readEmailsNumbers(); +} + +void loop() +{ +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and + * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename + * (> 13 characters) is not support in the SD.h library. + * To show how its original file name, use imap.fileList(). + */ + // Serial.println(imap.fileList()); + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email/Read_Single_Email.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email/Read_Single_Email.ino index c8533ed92..e5a22e613 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email/Read_Single_Email.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email/Read_Single_Email.ino @@ -1,516 +1,516 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to read Email and store the message in SD card. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** Assign SD card type and FS used in src/ESP_Mail_FS.h and - * change the config for that card interfaces in src/extras/SDHelper.h - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// Provide the SD card interfaces setting and mounting -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status); - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -/* Print all messages from the message list */ -void printMessages(std::vector &msgItems, bool headerOnly); - -/* Print all attachments info from the message */ -void printAttacements(std::vector &atts); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - -#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h - // Mount SD card. - SD_Card_Mounting(); // See src/extras/SDHelper.h -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Set the storage to save the downloaded files and attachments */ - imap_data.storage.saved_path = F("/email_data"); - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - imap_data.storage.type = esp_mail_file_storage_type_sd; - - /** Set to download headers, text and html messaeges, - * attachments and inline images respectively. - */ - imap_data.download.header = true; - imap_data.download.text = true; - imap_data.download.html = true; - imap_data.download.attachment = true; - imap_data.download.inlineImg = true; - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option imap_data.limit.msg_size. - * The whole message can be download through imap_data.download.text - * or imap_data.download.html which not depends on these enable options. - */ - imap_data.enable.html = true; - imap_data.enable.text = true; - - /* Set to enable the sort the result by message UID in the decending order */ - imap_data.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - imap_data.enable.download_status = true; - - /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud - , to allow case sensitive parse, uncomment below line*/ - // imap_data.enable.header_case_sensitive = true; - - /* Set the limit of number of messages in the search results */ - imap_data.limit.search = 5; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - imap_data.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - imap_data.limit.attachment_size = 1024 * 1024 * 5; - - // If ID extension was supported by IMAP server, assign the client identification - // name, version, vendor, os, os_version, support_url, address, command, arguments, environment - // Server ID can be optained from imap.serverID() after calling imap.connect and imap.id. - - // imap_data.identification.name = "User"; - // imap_data.identification.version = "1.0"; - - /* Set the TCP response read timeout in seconds */ - // imap.setTCPTimeout(10); - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - /** Or connect without log in and log in later - - if (!imap.connect(&config, &imap_data, false)) - return; - - if (!imap.loginWithPassword(AUTHOR_EMAIL, AUTHOR_PASSWORD)) - return; - */ - - // Client identification can be sent to server later with - /** - * IMAP_Identification iden; - * iden.name = "user"; - * iden.version = "1.0"; - * - * if (imap.id(&iden)) - * { - * Serial.println("\nSend Identification success"); - * Serial.println(imap.serverID()); - * } - * else - * MailClient.printf("nIdentification sending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); - */ - - if (!imap.isLoggedIn()) - { - Serial.println("\nNot yet logged in."); - } - else - { - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - } - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* {Optional} */ - printSelectedMailboxInfo(imap.selectedFolder()); - - /** Message UID to fetch or read e.g. 100. - * In this case we will get the UID from the max message number (lastest message) - */ - imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); - - // if IMAP server supports CONDSTORE extension, the modification sequence can be assign to fetch command - // Note that modsequence value supports in this library is 32-bit integer - imap_data.fetch.modsequence = 123; - - // To fetch only header part - // imap_data.fetch.headerOnly = true; - - // or fetch via the message sequence number - // imap_data.fetch.number = imap.selectedFolder().msgCount(); - - // if both imap_data.fetch.uid and imap_data.fetch.number were set, - // then total 2 messages will be fetched i.e. one using uid and other using number. - - /* Set seen flag */ - - // The message with "Seen" flagged means the message was already read or seen by user. - // The default value of this option is set to false. - // If you want to set the message flag as "Seen", set this option to true. - // If this option is false, the message flag was unchanged. - // To set or remove flag from message, see Set_Flags.ino example. - - // imap_data.fetch.set_seen = true; - - /* Fetch or read only message header */ - // imap_data.fetch.headerOnly = true; - - /* Read or search the Email and close the session */ - - // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, - // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag - // to message, see the Set_Flags.ino example. - MailClient.readMail(&imap); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); -} - -void loop() -{ -} - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Show the result when reading finished */ - if (status.success()) - { - /* Print the result */ - /* Get the message list from the message list data */ - IMAP_MSG_List msgList = imap.data(); - printMessages(msgList.msgItems, imap.headerOnly()); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } -} - -void printAttacements(std::vector &atts) -{ - MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); - for (size_t j = 0; j < atts.size(); j++) - { - IMAP_Attach_Item att = atts[j]; - /** att.type can be - * esp_mail_att_type_none or 0 - * esp_mail_att_type_attachment or 1 - * esp_mail_att_type_inline or 2 - */ - MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); - } - Serial.println(); -} - -void printMessages(std::vector &msgItems, bool headerOnly) -{ - - /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and - * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename - * (> 13 characters) is not support in the SD.h library. - * To show how its original file name, use imap.fileList(). - */ - // Serial.println(imap.fileList()); - - for (size_t i = 0; i < msgItems.size(); i++) - { - - /* Iterate to get each message data through the message item data */ - IMAP_MSG_Item msg = msgItems[i]; - - Serial.println("****************************"); - MailClient.printf("Number: %d\n", msg.msgNo); - MailClient.printf("UID: %d\n", msg.UID); - - // The attachment status in search may be true in case the "multipart/mixed" - // content type header was set with no real attachtment included. - MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); - - MailClient.printf("Messsage-ID: %s\n", msg.ID); - - if (strlen(msg.flags)) - MailClient.printf("Flags: %s\n", msg.flags); - if (strlen(msg.acceptLang)) - MailClient.printf("Accept Language: %s\n", msg.acceptLang); - if (strlen(msg.contentLang)) - MailClient.printf("Content Language: %s\n", msg.contentLang); - if (strlen(msg.from)) - MailClient.printf("From: %s\n", msg.from); - if (strlen(msg.sender)) - MailClient.printf("Sender: %s\n", msg.sender); - if (strlen(msg.to)) - MailClient.printf("To: %s\n", msg.to); - if (strlen(msg.cc)) - MailClient.printf("CC: %s\n", msg.cc); - if (strlen(msg.bcc)) - MailClient.printf("BCC: %s\n", msg.bcc); - if (strlen(msg.date)) - { - MailClient.printf("Date: %s\n", msg.date); - MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); - } - if (strlen(msg.subject)) - MailClient.printf("Subject: %s\n", msg.subject); - if (strlen(msg.reply_to)) - MailClient.printf("Reply-To: %s\n", msg.reply_to); - if (strlen(msg.return_path)) - MailClient.printf("Return-Path: %s\n", msg.return_path); - if (strlen(msg.in_reply_to)) - MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); - if (strlen(msg.references)) - MailClient.printf("References: %s\n", msg.references); - if (strlen(msg.comments)) - MailClient.printf("Comments: %s\n", msg.comments); - if (strlen(msg.keywords)) - MailClient.printf("Keywords: %s\n", msg.keywords); - - /* If the result contains the message info (Fetch mode) */ - if (!headerOnly) - { - if (strlen(msg.text.content)) - MailClient.printf("Text Message: %s\n", msg.text.content); - if (strlen(msg.text.charSet)) - MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); - if (strlen(msg.text.transfer_encoding)) - MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - if (strlen(msg.html.content)) - MailClient.printf("HTML Message: %s\n", msg.html.content); - if (strlen(msg.html.charSet)) - MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); - if (strlen(msg.html.transfer_encoding)) - MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.rfc822.size() > 0) - { - MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - printMessages(msg.rfc822, headerOnly); - } - - if (msg.attachments.size() > 0) - printAttacements(msg.attachments); - } - - Serial.println(); - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to read Email and store the message in SD card. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// Provide the SD card interfaces setting and mounting +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + +#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h + // Mount SD card. + SD_Card_Mounting(); // See src/extras/SDHelper.h +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_sd; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + // If ID extension was supported by IMAP server, assign the client identification + // name, version, vendor, os, os_version, support_url, address, command, arguments, environment + // Server ID can be optained from imap.serverID() after calling imap.connect and imap.id. + + // imap_data.identification.name = "User"; + // imap_data.identification.version = "1.0"; + + /* Set the TCP response read timeout in seconds */ + // imap.setTCPTimeout(10); + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + /** Or connect without log in and log in later + + if (!imap.connect(&config, &imap_data, false)) + return; + + if (!imap.loginWithPassword(AUTHOR_EMAIL, AUTHOR_PASSWORD)) + return; + */ + + // Client identification can be sent to server later with + /** + * IMAP_Identification iden; + * iden.name = "user"; + * iden.version = "1.0"; + * + * if (imap.id(&iden)) + * { + * Serial.println("\nSend Identification success"); + * Serial.println(imap.serverID()); + * } + * else + * MailClient.printf("nIdentification sending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + */ + + if (!imap.isLoggedIn()) + { + Serial.println("\nNot yet logged in."); + } + else + { + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /** Message UID to fetch or read e.g. 100. + * In this case we will get the UID from the max message number (lastest message) + */ + imap_data.fetch.uid = imap.getUID(imap.selectedFolder().msgCount()); + + // if IMAP server supports CONDSTORE extension, the modification sequence can be assign to fetch command + // Note that modsequence value supports in this library is 32-bit integer + imap_data.fetch.modsequence = 123; + + // To fetch only header part + // imap_data.fetch.headerOnly = true; + + // or fetch via the message sequence number + // imap_data.fetch.number = imap.selectedFolder().msgCount(); + + // if both imap_data.fetch.uid and imap_data.fetch.number were set, + // then total 2 messages will be fetched i.e. one using uid and other using number. + + /* Set seen flag */ + + // The message with "Seen" flagged means the message was already read or seen by user. + // The default value of this option is set to false. + // If you want to set the message flag as "Seen", set this option to true. + // If this option is false, the message flag was unchanged. + // To set or remove flag from message, see Set_Flags.ino example. + + // imap_data.fetch.set_seen = true; + + /* Fetch or read only message header */ + // imap_data.fetch.headerOnly = true; + + /* Read or search the Email and close the session */ + + // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, + // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag + // to message, see the Set_Flags.ino example. + MailClient.readMail(&imap); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void loop() +{ +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and + * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename + * (> 13 characters) is not support in the SD.h library. + * To show how its original file name, use imap.fileList(). + */ + // Serial.println(imap.fileList()); + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email_Loop/Read_Single_Email_Loop.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email_Loop/Read_Single_Email_Loop.ino index 96d1d5568..b7639f03d 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email_Loop/Read_Single_Email_Loop.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email_Loop/Read_Single_Email_Loop.ino @@ -1,561 +1,561 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to read Email repeatedly. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -/** Assign SD card type and FS used in src/ESP_Mail_FS.h and - * change the config for that card interfaces in src/extras/SDHelper.h - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// Provide the SD card interfaces setting and mounting -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status); - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -/* Print all messages from the message list */ -void printMessages(std::vector &msgItems, bool headerOnly); - -/* Print all attachments info from the message */ -void printAttacements(std::vector &atts); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -unsigned long readMillis = 0; -int totalMessage = 0; -int msgNum = 0; -int sign = -1; - -/* Declare the global used Session_Config for user defined session credentials */ -Session_Config config; - -/* Define the IMAP_Data object used for user defined IMAP operating options. */ -IMAP_Data imap_data; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -// For Free Heap checking -#include "HeapStat.h" -HeapStat heapInfo; - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - -#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h - // Mount SD card. - SD_Card_Mounting(); // See src/extras/SDHelper.h -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Message UID to fetch or read */ - imap_data.fetch.uid.clear(); - - /* Search criteria */ - imap_data.search.criteria.clear(); - - /* Also search the unseen message */ - imap_data.search.unseen_msg = true; - - /* Set the storage to save the downloaded files and attachments */ - imap_data.storage.saved_path = F("/email_data"); - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - imap_data.storage.type = esp_mail_file_storage_type_sd; - - /** Set to download headers, text and html messaeges, - * attachments and inline images respectively. - */ - imap_data.download.header = false; - imap_data.download.text = false; - imap_data.download.html = false; - imap_data.download.attachment = false; - imap_data.download.inlineImg = false; - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option imap_data.limit.msg_size. - * The whole message can be download through imap_data.download.text - * or imap_data.download.html which not depends on these enable options. - */ - imap_data.enable.html = true; - imap_data.enable.text = true; - - /* Set to enable the sort the result by message UID in the decending order */ - imap_data.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - imap_data.enable.download_status = true; - - /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud - , to allow case sensitive parse, uncomment below line*/ - // imap_data.enable.header_case_sensitive = true; - - /* Set the limit of number of messages in the search results */ - imap_data.limit.search = 5; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - imap_data.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - imap_data.limit.attachment_size = 1024 * 1024 * 5; - - // If ID extension was supported by IMAP server, assign the client identification - // name, version, vendor, os, os_version, support_url, address, command, arguments, environment - // Server ID can be optained from imap.serverID() after calling imap.connect and imap.id. - - // imap_data.identification.name = "User"; - // imap_data.identification.version = "1.0"; - - /* Set the TCP response read timeout in seconds */ - // imap.setTCPTimeout(10); - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - // Client identification can be sent to server later with - /** - * IMAP_Identification iden; - * iden.name = "user"; - * iden.version = "1.0"; - * - * if (imap.id(&iden)) - * { - * Serial.println("\nSend Identification success"); - * Serial.println(imap.serverID()); - * } - * else - * MailClient.printf("nIdentification sending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); - */ - - if (!imap.isLoggedIn()) - { - Serial.println("\nNot yet logged in."); - } - else - { - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - } - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* {Optional} */ - printSelectedMailboxInfo(imap.selectedFolder()); - - totalMessage = imap.selectedFolder().msgCount(); - - /* Start fetch from last message */ - msgNum = totalMessage; - sign = -1; // count down - - /* To start fetch from first message */ - // msgNum = 1; - // sign = 1;// count up -} - -void loop() -{ - if (millis() - readMillis > 10000 || readMillis == 0) - { - readMillis = millis(); - - // If session was closed, reconnect and re-select the mailbox - if (!imap.connected()) - { - if (!imap.connect(&config, &imap_data)) - return; - - if (!imap.selectFolder(F("INBOX"))) - return; - - if (totalMessage == 0) - { - totalMessage = imap.selectedFolder().msgCount(); - msgNum = totalMessage; - sign = -1; - } - } - - if (msgNum <= 0) - { - msgNum = 1; - sign = 1; - } - else if (msgNum >= totalMessage) - { - msgNum = totalMessage; - sign = -1; - } - - /* Message number to fetch or read */ - imap_data.fetch.number = msgNum; - - /* Set seen flag */ - // imap_data.fetch.set_seen = true; - - /* Fetch or read only message header */ - // imap_data.fetch.headerOnly = true; - - /** Read or search the Email and keep the TCP session to open - * The second parameter is for close the session. - */ - - // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, - // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag - // to message, see the Set_Flags.ino example. - if (MailClient.readMail(&imap, false)) - msgNum += sign; - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - - msgNum += sign; - } -} - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Show the result when reading finished */ - if (status.success()) - { - /* Print the result */ - /* Get the message list from the message list data */ - IMAP_MSG_List msgList = imap.data(); - printMessages(msgList.msgItems, imap.headerOnly()); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - - // Collect memory info - heapInfo.collect(); - - // Print memory info - heapInfo.print(); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } -} - -void printAttacements(std::vector &atts) -{ - MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); - for (size_t j = 0; j < atts.size(); j++) - { - IMAP_Attach_Item att = atts[j]; - /** att.type can be - * esp_mail_att_type_none or 0 - * esp_mail_att_type_attachment or 1 - * esp_mail_att_type_inline or 2 - */ - MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); - } - Serial.println(); -} - -void printMessages(std::vector &msgItems, bool headerOnly) -{ - /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and - * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename - * (> 13 characters) is not support in the SD.h library. - * To show how its original file name, use imap.fileList(). - */ - // Serial.println(imap.fileList()); - - for (size_t i = 0; i < msgItems.size(); i++) - { - - /* Iterate to get each message data through the message item data */ - IMAP_MSG_Item msg = msgItems[i]; - - Serial.println("****************************"); - MailClient.printf("Number: %d\n", msg.msgNo); - MailClient.printf("UID: %d\n", msg.UID); - - // The attachment status in search may be true in case the "multipart/mixed" - // content type header was set with no real attachtment included. - MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); - - MailClient.printf("Messsage-ID: %s\n", msg.ID); - - if (strlen(msg.flags)) - MailClient.printf("Flags: %s\n", msg.flags); - if (strlen(msg.acceptLang)) - MailClient.printf("Accept Language: %s\n", msg.acceptLang); - if (strlen(msg.contentLang)) - MailClient.printf("Content Language: %s\n", msg.contentLang); - if (strlen(msg.from)) - MailClient.printf("From: %s\n", msg.from); - if (strlen(msg.sender)) - MailClient.printf("Sender: %s\n", msg.sender); - if (strlen(msg.to)) - MailClient.printf("To: %s\n", msg.to); - if (strlen(msg.cc)) - MailClient.printf("CC: %s\n", msg.cc); - if (strlen(msg.bcc)) - MailClient.printf("BCC: %s\n", msg.bcc); - if (strlen(msg.date)) - { - MailClient.printf("Date: %s\n", msg.date); - MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); - } - if (strlen(msg.subject)) - MailClient.printf("Subject: %s\n", msg.subject); - if (strlen(msg.reply_to)) - MailClient.printf("Reply-To: %s\n", msg.reply_to); - if (strlen(msg.return_path)) - MailClient.printf("Return-Path: %s\n", msg.return_path); - if (strlen(msg.in_reply_to)) - MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); - if (strlen(msg.references)) - MailClient.printf("References: %s\n", msg.references); - if (strlen(msg.comments)) - MailClient.printf("Comments: %s\n", msg.comments); - if (strlen(msg.keywords)) - MailClient.printf("Keywords: %s\n", msg.keywords); - - /* If the result contains the message info (Fetch mode) */ - if (!headerOnly) - { - if (strlen(msg.text.content)) - MailClient.printf("Text Message: %s\n", msg.text.content); - if (strlen(msg.text.charSet)) - MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); - if (strlen(msg.text.transfer_encoding)) - MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - if (strlen(msg.html.content)) - MailClient.printf("HTML Message: %s\n", msg.html.content); - if (strlen(msg.html.charSet)) - MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); - if (strlen(msg.html.transfer_encoding)) - MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.rfc822.size() > 0) - { - MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - printMessages(msg.rfc822, headerOnly); - } - - if (msg.attachments.size() > 0) - printAttacements(msg.attachments); - } - - Serial.println(); - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to read Email repeatedly. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// Provide the SD card interfaces setting and mounting +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +unsigned long readMillis = 0; +int totalMessage = 0; +int msgNum = 0; +int sign = -1; + +/* Declare the global used Session_Config for user defined session credentials */ +Session_Config config; + +/* Define the IMAP_Data object used for user defined IMAP operating options. */ +IMAP_Data imap_data; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +// For Free Heap checking +#include "HeapStat.h" +HeapStat heapInfo; + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + +#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h + // Mount SD card. + SD_Card_Mounting(); // See src/extras/SDHelper.h +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Message UID to fetch or read */ + imap_data.fetch.uid.clear(); + + /* Search criteria */ + imap_data.search.criteria.clear(); + + /* Also search the unseen message */ + imap_data.search.unseen_msg = true; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_sd; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = false; + imap_data.download.text = false; + imap_data.download.html = false; + imap_data.download.attachment = false; + imap_data.download.inlineImg = false; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + // If ID extension was supported by IMAP server, assign the client identification + // name, version, vendor, os, os_version, support_url, address, command, arguments, environment + // Server ID can be optained from imap.serverID() after calling imap.connect and imap.id. + + // imap_data.identification.name = "User"; + // imap_data.identification.version = "1.0"; + + /* Set the TCP response read timeout in seconds */ + // imap.setTCPTimeout(10); + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + // Client identification can be sent to server later with + /** + * IMAP_Identification iden; + * iden.name = "user"; + * iden.version = "1.0"; + * + * if (imap.id(&iden)) + * { + * Serial.println("\nSend Identification success"); + * Serial.println(imap.serverID()); + * } + * else + * MailClient.printf("nIdentification sending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + */ + + if (!imap.isLoggedIn()) + { + Serial.println("\nNot yet logged in."); + } + else + { + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + totalMessage = imap.selectedFolder().msgCount(); + + /* Start fetch from last message */ + msgNum = totalMessage; + sign = -1; // count down + + /* To start fetch from first message */ + // msgNum = 1; + // sign = 1;// count up +} + +void loop() +{ + if (millis() - readMillis > 10000 || readMillis == 0) + { + readMillis = millis(); + + // If session was closed, reconnect and re-select the mailbox + if (!imap.connected()) + { + if (!imap.connect(&config, &imap_data)) + return; + + if (!imap.selectFolder(F("INBOX"))) + return; + + if (totalMessage == 0) + { + totalMessage = imap.selectedFolder().msgCount(); + msgNum = totalMessage; + sign = -1; + } + } + + if (msgNum <= 0) + { + msgNum = 1; + sign = 1; + } + else if (msgNum >= totalMessage) + { + msgNum = totalMessage; + sign = -1; + } + + /* Message number to fetch or read */ + imap_data.fetch.number = msgNum; + + /* Set seen flag */ + // imap_data.fetch.set_seen = true; + + /* Fetch or read only message header */ + // imap_data.fetch.headerOnly = true; + + /** Read or search the Email and keep the TCP session to open + * The second parameter is for close the session. + */ + + // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, + // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag + // to message, see the Set_Flags.ino example. + if (MailClient.readMail(&imap, false)) + msgNum += sign; + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + + msgNum += sign; + } +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + + // Collect memory info + heapInfo.collect(); + + // Print memory info + heapInfo.print(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + /** In devices other than ESP8266 and ESP32, if SD card was chosen as filestorage and + * the standard SD.h library included in ESP_Mail_FS.h, files will be renamed due to long filename + * (> 13 characters) is not support in the SD.h library. + * To show how its original file name, use imap.fileList(). + */ + // Serial.println(imap.fileList()); + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email_Loop_Silent_Mode/Read_Single_Email_Loop_Silent_Mode.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email_Loop_Silent_Mode/Read_Single_Email_Loop_Silent_Mode.ino index 94183bbd7..f756de8ac 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email_Loop_Silent_Mode/Read_Single_Email_Loop_Silent_Mode.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Read_Single_Email_Loop_Silent_Mode/Read_Single_Email_Loop_Silent_Mode.ino @@ -1,402 +1,402 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to read Email repeatedly. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** - * To use library in silent mode (no debug printing and callback), please define this macro in src/ESP_Mail_FS.h. - * #define SILENT_MODE - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -#define IMAP_HOST "" - -#define IMAP_PORT 993 - -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -void printImapData(IMAP_Status status); - -void printAllMailboxesInfo(IMAPSession &imap); - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -void printMessages(std::vector &msgItems, bool headerOnly); - -void printAttacements(std::vector &atts); - -IMAPSession imap; - -unsigned long readMillis = 0; -int totalMessage = 0; -int msgNum = 0; -int sign = -1; - -Session_Config config; - -IMAP_Data imap_data; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -// For Free Heap checking -#include "HeapStat.h" -HeapStat heapInfo; - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - MailClient.networkReconnect(true); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - -#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h - // Mount SD card. - SD_Card_Mounting(); // See src/extras/SDHelper.h -#endif - - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - imap_data.fetch.uid.clear(); - - imap_data.search.criteria.clear(); - - imap_data.search.unseen_msg = true; - - imap_data.storage.saved_path = F("/email_data"); - - imap_data.storage.type = esp_mail_file_storage_type_sd; - - imap_data.download.header = false; - imap_data.download.text = false; - imap_data.download.html = false; - imap_data.download.attachment = false; - imap_data.download.inlineImg = false; - - imap_data.enable.html = true; - imap_data.enable.text = true; - - imap_data.enable.recent_sort = true; - - imap_data.enable.download_status = true; - - imap_data.limit.search = 5; - - imap_data.limit.msg_size = 512; - - imap_data.limit.attachment_size = 1024 * 1024 * 5; - - if (!imap.connect(&config, &imap_data)) - { - MailClient.printf("Connection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); - return; - } - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - printAllMailboxesInfo(imap); - - if (!imap.selectFolder(F("INBOX"))) - { - MailClient.printf("Folder selection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); - return; - } - - printSelectedMailboxInfo(imap.selectedFolder()); - - totalMessage = imap.selectedFolder().msgCount(); - - msgNum = totalMessage; - sign = -1; // count down -} - -void loop() -{ - if (millis() - readMillis > 10000 || readMillis == 0) - { - readMillis = millis(); - - if (!imap.connected()) - { - if (!imap.connect(&config, &imap_data)) - return; - - if (!imap.selectFolder(F("INBOX"))) - return; - - if (totalMessage == 0) - { - totalMessage = imap.selectedFolder().msgCount(); - msgNum = totalMessage; - sign = -1; - } - } - - if (msgNum <= 0) - { - msgNum = 1; - sign = 1; - } - else if (msgNum >= totalMessage) - { - msgNum = totalMessage; - sign = -1; - } - - imap_data.fetch.number = msgNum; - - if (MailClient.readMail(&imap, false)) - { - printImapData(imap.status()); - } - else - { - MailClient.printf("Message reading error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); - } - - imap.empty(); - - msgNum += sign; - } -} - -void printImapData(IMAP_Status status) -{ - - if (status.success()) - { - IMAP_MSG_List msgList = imap.data(); - printMessages(msgList.msgItems, imap.headerOnly()); - - imap.empty(); - - heapInfo.collect(); - - heapInfo.print(); - - Serial.println(); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - - FoldersCollection folders; - - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } -} - -void printAttacements(std::vector &atts) -{ - MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); - for (size_t j = 0; j < atts.size(); j++) - { - IMAP_Attach_Item att = atts[j]; - MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); - } - Serial.println(); -} - -void printMessages(std::vector &msgItems, bool headerOnly) -{ - - for (size_t i = 0; i < msgItems.size(); i++) - { - - IMAP_MSG_Item msg = msgItems[i]; - - Serial.println("****************************"); - MailClient.printf("Number: %d\n", msg.msgNo); - MailClient.printf("UID: %d\n", msg.UID); - - // The attachment status in search may be true in case the "multipart/mixed" - // content type header was set with no real attachtment included. - MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); - - MailClient.printf("Messsage-ID: %s\n", msg.ID); - - if (strlen(msg.flags)) - MailClient.printf("Flags: %s\n", msg.flags); - if (strlen(msg.acceptLang)) - MailClient.printf("Accept Language: %s\n", msg.acceptLang); - if (strlen(msg.contentLang)) - MailClient.printf("Content Language: %s\n", msg.contentLang); - if (strlen(msg.from)) - MailClient.printf("From: %s\n", msg.from); - if (strlen(msg.sender)) - MailClient.printf("Sender: %s\n", msg.sender); - if (strlen(msg.to)) - MailClient.printf("To: %s\n", msg.to); - if (strlen(msg.cc)) - MailClient.printf("CC: %s\n", msg.cc); - if (strlen(msg.bcc)) - MailClient.printf("BCC: %s\n", msg.bcc); - if (strlen(msg.date)) - { - MailClient.printf("Date: %s\n", msg.date); - MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); - } - if (strlen(msg.subject)) - MailClient.printf("Subject: %s\n", msg.subject); - if (strlen(msg.reply_to)) - MailClient.printf("Reply-To: %s\n", msg.reply_to); - if (strlen(msg.return_path)) - MailClient.printf("Return-Path: %s\n", msg.return_path); - if (strlen(msg.in_reply_to)) - MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); - if (strlen(msg.references)) - MailClient.printf("References: %s\n", msg.references); - if (strlen(msg.comments)) - MailClient.printf("Comments: %s\n", msg.comments); - if (strlen(msg.keywords)) - MailClient.printf("Keywords: %s\n", msg.keywords); - - if (!headerOnly) - { - if (strlen(msg.text.content)) - MailClient.printf("Text Message: %s\n", msg.text.content); - if (strlen(msg.text.charSet)) - MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); - if (strlen(msg.text.transfer_encoding)) - MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - if (strlen(msg.html.content)) - MailClient.printf("HTML Message: %s\n", msg.html.content); - if (strlen(msg.html.charSet)) - MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); - if (strlen(msg.html.transfer_encoding)) - MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.rfc822.size() > 0) - { - MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - printMessages(msg.rfc822, headerOnly); - } - - if (msg.attachments.size() > 0) - printAttacements(msg.attachments); - } - - Serial.println(); - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to read Email repeatedly. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** + * To use library in silent mode (no debug printing and callback), please define this macro in src/ESP_Mail_FS.h. + * #define SILENT_MODE + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define IMAP_HOST "" + +#define IMAP_PORT 993 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +void printImapData(IMAP_Status status); + +void printAllMailboxesInfo(IMAPSession &imap); + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +void printMessages(std::vector &msgItems, bool headerOnly); + +void printAttacements(std::vector &atts); + +IMAPSession imap; + +unsigned long readMillis = 0; +int totalMessage = 0; +int msgNum = 0; +int sign = -1; + +Session_Config config; + +IMAP_Data imap_data; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +// For Free Heap checking +#include "HeapStat.h" +HeapStat heapInfo; + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + MailClient.networkReconnect(true); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + +#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h + // Mount SD card. + SD_Card_Mounting(); // See src/extras/SDHelper.h +#endif + + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + imap_data.fetch.uid.clear(); + + imap_data.search.criteria.clear(); + + imap_data.search.unseen_msg = true; + + imap_data.storage.saved_path = F("/email_data"); + + imap_data.storage.type = esp_mail_file_storage_type_sd; + + imap_data.download.header = false; + imap_data.download.text = false; + imap_data.download.html = false; + imap_data.download.attachment = false; + imap_data.download.inlineImg = false; + + imap_data.enable.html = true; + imap_data.enable.text = true; + + imap_data.enable.recent_sort = true; + + imap_data.enable.download_status = true; + + imap_data.limit.search = 5; + + imap_data.limit.msg_size = 512; + + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + if (!imap.connect(&config, &imap_data)) + { + MailClient.printf("Connection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + return; + } + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + printAllMailboxesInfo(imap); + + if (!imap.selectFolder(F("INBOX"))) + { + MailClient.printf("Folder selection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + return; + } + + printSelectedMailboxInfo(imap.selectedFolder()); + + totalMessage = imap.selectedFolder().msgCount(); + + msgNum = totalMessage; + sign = -1; // count down +} + +void loop() +{ + if (millis() - readMillis > 10000 || readMillis == 0) + { + readMillis = millis(); + + if (!imap.connected()) + { + if (!imap.connect(&config, &imap_data)) + return; + + if (!imap.selectFolder(F("INBOX"))) + return; + + if (totalMessage == 0) + { + totalMessage = imap.selectedFolder().msgCount(); + msgNum = totalMessage; + sign = -1; + } + } + + if (msgNum <= 0) + { + msgNum = 1; + sign = 1; + } + else if (msgNum >= totalMessage) + { + msgNum = totalMessage; + sign = -1; + } + + imap_data.fetch.number = msgNum; + + if (MailClient.readMail(&imap, false)) + { + printImapData(imap.status()); + } + else + { + MailClient.printf("Message reading error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + } + + imap.empty(); + + msgNum += sign; + } +} + +void printImapData(IMAP_Status status) +{ + + if (status.success()) + { + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + imap.empty(); + + heapInfo.collect(); + + heapInfo.print(); + + Serial.println(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + + FoldersCollection folders; + + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + for (size_t i = 0; i < msgItems.size(); i++) + { + + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_And_Read/Search_And_Read.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_And_Read/Search_And_Read.ino index 7ad828a1e..400d923b1 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_And_Read/Search_And_Read.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_And_Read/Search_And_Read.ino @@ -1,352 +1,352 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to search the unread messages and read them. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** - * To use library in silent mode (no debug printing and callback), please define this macro in src/ESP_Mail_FS.h. - * #define SILENT_MODE - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -#define IMAP_HOST "" - -#define IMAP_PORT 993 - -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -void imapCallback(IMAP_Status status); - -void printAllMailboxesInfo(IMAPSession &imap); - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -void printMessageData(); - -IMAPSession imap; - -Session_Config config; - -IMAP_Data imap_data; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -// Max messages in the search result -int max_result = 5; - -// Array to store the UID of messages in search result -int msg_uid[5]; - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - MailClient.networkReconnect(true); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - // Clear all these fetch options to perform search - imap_data.fetch.uid.clear(); - imap_data.fetch.number.clear(); - imap_data.fetch.sequence_set.string.clear(); - - imap_data.search.unseen_msg = true; - - // Don't download all to filesystem - imap_data.download.header = false; - imap_data.download.text = false; - imap_data.download.html = false; - imap_data.download.attachment = false; - imap_data.download.inlineImg = false; - - // Store html/text message body in IMAPSession object - imap_data.enable.html = true; - imap_data.enable.text = true; - - imap_data.enable.recent_sort = true; - - // Max messages in the search result - imap_data.limit.search = max_result; - - imap_data.limit.msg_size = 128; - - if (!imap.connect(&config, &imap_data)) - { - MailClient.printf("Connection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); - return; - } - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - printAllMailboxesInfo(imap); - - if (!imap.selectFolder(F("INBOX"))) - { - MailClient.printf("Folder selection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); - return; - } - - printSelectedMailboxInfo(imap.selectedFolder()); - - // We search the unseen messages first to get its UID and stored in msg_uid. - imap_data.search.criteria = F("SEARCH UNSEEN"); - - MailClient.readMail(&imap, false /* keep session open for fetching message in opened mailbox later */); - - // We already get the search result message, fetch it - - // Fetch the messages using UID stored in msg_uid one by one - for (int i = 0; i < max_result; i++) - { - imap_data.search.criteria.clear(); - - // Mark this message as read - MailClient.addFlag(&imap, msg_uid[i], F("\\Seen"), false /* Close session */, false /* Ignore response */); - - // Now Fech message by UID stored in msg_uid - imap_data.fetch.uid = msg_uid[i]; - - MailClient.readMail(&imap, false /* keep session open for fetching message in opened mailbox later */); - } - - imap.closeSession(); - imap.empty(); -} - -void loop() -{ -} - -void imapCallback(IMAP_Status status) -{ - Serial.println(status.info()); - - if (status.success()) - { - // If this is the search result (imap contains only header info), - // store the message UID that we can fetch for its body later. - if (imap.headerOnly()) - { - max_result = imap.data().msgItems.size(); - for (size_t i = 0; i < imap.data().msgItems.size(); i++) - msg_uid[i] = imap.data().msgItems[i].UID; - } - else - { - // This is the fetch result, print the whole message (header + body) - printMessageData(); - } - - imap.empty(); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - - FoldersCollection folders; - - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } -} - -void printMessageData() -{ - - IMAP_MSG_Item msg = imap.data().msgItems[0]; // msgItems contains only one message from fetch - - Serial.println("****************************"); - - MailClient.printf("Number: %d\n", msg.msgNo); - MailClient.printf("UID: %d\n", msg.UID); - - // The attachment status in search may be true in case the "multipart/mixed" - // content type header was set with no real attachtment included. - MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); - - MailClient.printf("Messsage-ID: %s\n", msg.ID); - - if (strlen(msg.flags)) - MailClient.printf("Flags: %s\n", msg.flags); - if (strlen(msg.acceptLang)) - MailClient.printf("Accept Language: %s\n", msg.acceptLang); - if (strlen(msg.contentLang)) - MailClient.printf("Content Language: %s\n", msg.contentLang); - if (strlen(msg.from)) - MailClient.printf("From: %s\n", msg.from); - if (strlen(msg.sender)) - MailClient.printf("Sender: %s\n", msg.sender); - if (strlen(msg.to)) - MailClient.printf("To: %s\n", msg.to); - if (strlen(msg.cc)) - MailClient.printf("CC: %s\n", msg.cc); - if (strlen(msg.bcc)) - MailClient.printf("BCC: %s\n", msg.bcc); - if (strlen(msg.date)) - { - MailClient.printf("Date: %s\n", msg.date); - MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); - } - if (strlen(msg.subject)) - MailClient.printf("Subject: %s\n", msg.subject); - if (strlen(msg.reply_to)) - MailClient.printf("Reply-To: %s\n", msg.reply_to); - if (strlen(msg.return_path)) - MailClient.printf("Return-Path: %s\n", msg.return_path); - if (strlen(msg.in_reply_to)) - MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); - if (strlen(msg.references)) - MailClient.printf("References: %s\n", msg.references); - if (strlen(msg.comments)) - MailClient.printf("Comments: %s\n", msg.comments); - if (strlen(msg.keywords)) - MailClient.printf("Keywords: %s\n", msg.keywords); - - if (strlen(msg.text.content)) - MailClient.printf("Text Message: %s\n", msg.text.content); - if (strlen(msg.text.charSet)) - MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); - if (strlen(msg.text.transfer_encoding)) - MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - if (strlen(msg.html.content)) - MailClient.printf("HTML Message: %s\n", msg.html.content); - if (strlen(msg.html.charSet)) - MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); - if (strlen(msg.html.transfer_encoding)) - MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - Serial.println(); +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to search the unread messages and read them. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** + * To use library in silent mode (no debug printing and callback), please define this macro in src/ESP_Mail_FS.h. + * #define SILENT_MODE + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define IMAP_HOST "" + +#define IMAP_PORT 993 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +void imapCallback(IMAP_Status status); + +void printAllMailboxesInfo(IMAPSession &imap); + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +void printMessageData(); + +IMAPSession imap; + +Session_Config config; + +IMAP_Data imap_data; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +// Max messages in the search result +int max_result = 5; + +// Array to store the UID of messages in search result +int msg_uid[5]; + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + MailClient.networkReconnect(true); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + // Clear all these fetch options to perform search + imap_data.fetch.uid.clear(); + imap_data.fetch.number.clear(); + imap_data.fetch.sequence_set.string.clear(); + + imap_data.search.unseen_msg = true; + + // Don't download all to filesystem + imap_data.download.header = false; + imap_data.download.text = false; + imap_data.download.html = false; + imap_data.download.attachment = false; + imap_data.download.inlineImg = false; + + // Store html/text message body in IMAPSession object + imap_data.enable.html = true; + imap_data.enable.text = true; + + imap_data.enable.recent_sort = true; + + // Max messages in the search result + imap_data.limit.search = max_result; + + imap_data.limit.msg_size = 128; + + if (!imap.connect(&config, &imap_data)) + { + MailClient.printf("Connection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + return; + } + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + printAllMailboxesInfo(imap); + + if (!imap.selectFolder(F("INBOX"))) + { + MailClient.printf("Folder selection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + return; + } + + printSelectedMailboxInfo(imap.selectedFolder()); + + // We search the unseen messages first to get its UID and stored in msg_uid. + imap_data.search.criteria = F("SEARCH UNSEEN"); + + MailClient.readMail(&imap, false /* keep session open for fetching message in opened mailbox later */); + + // We already get the search result message, fetch it + + // Fetch the messages using UID stored in msg_uid one by one + for (int i = 0; i < max_result; i++) + { + imap_data.search.criteria.clear(); + + // Mark this message as read + MailClient.addFlag(&imap, msg_uid[i], F("\\Seen"), false /* Close session */, false /* Ignore response */); + + // Now Fech message by UID stored in msg_uid + imap_data.fetch.uid = msg_uid[i]; + + MailClient.readMail(&imap, false /* keep session open for fetching message in opened mailbox later */); + } + + imap.closeSession(); + imap.empty(); +} + +void loop() +{ +} + +void imapCallback(IMAP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + // If this is the search result (imap contains only header info), + // store the message UID that we can fetch for its body later. + if (imap.headerOnly()) + { + max_result = imap.data().msgItems.size(); + for (size_t i = 0; i < imap.data().msgItems.size(); i++) + msg_uid[i] = imap.data().msgItems[i].UID; + } + else + { + // This is the fetch result, print the whole message (header + body) + printMessageData(); + } + + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + + FoldersCollection folders; + + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printMessageData() +{ + + IMAP_MSG_Item msg = imap.data().msgItems[0]; // msgItems contains only one message from fetch + + Serial.println("****************************"); + + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + Serial.println(); } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_Emails/Search_Emails.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_Emails/Search_Emails.ino index 597b25652..eba0c5b49 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_Emails/Search_Emails.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_Emails/Search_Emails.ino @@ -1,533 +1,533 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt - */ - -// This example shows how to search all messages with the keywords in the opened mailbox folder. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 // Plain or TLS with STARTTLS - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT esp_mail_imap_port_143 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status); - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -/* Print all messages from the message list */ -void printMessages(std::vector &msgItems, bool headerOnly); - -/* Print all attachments info from the message */ -void printAttacements(std::vector &atts); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Declare the IMAP_Data object used for user defined IMAP operating options - * and contains the IMAP operating result - */ - IMAP_Data imap_data; - - /* We will clear fetching message UID as it used to determine the reading mode i.e., search and fetch */ - imap_data.fetch.uid.clear(); - - /** Search criteria - * - * A search key can also be a parenthesized list of one or more search keys - * (e.g., for use with the OR and NOT keys). - * - * Since IMAP protocol uses Polish notation, the search criteria which in the polish notation form can be. - * - * To search the message from "someone@email.com" with the subject "my subject" since 1 Jan 2021, your search criteria can be - * UID SEARCH (OR SUBJECT "my subject" FROM "someone@email.com") SINCE "Fri, 1 Jan 2021 21:52:25 -0800" - * - * To search the message from "mail1@domain.com" or from "mail2@domain.com", the search criteria will be - * UID SEARCH OR FROM mail1@domain.com FROM mail2@domain.com - * - * For more details on using parentheses, AND, OR and NOT search keys in search criteria. - * https://www.limilabs.com/blog/imap-search-requires-parentheses - * - *For keywords used in search criteria, see - * https://github.com/mobizt/ESP-Mail-Client/tree/master/src#search-criteria - * - * Use "SEARCH UNSEEN" for unread messages search - * Use "SEARCH RECENT" for messages with the \\RECENT flag set - * Use "ON _date_" for messages with Date header matching _date_ - * Use "BEFORE _date_" for messages with Date header before _date_ - */ - imap_data.search.criteria = F("SEARCH RECENT"); - - /* Also search the unseen message */ - imap_data.search.unseen_msg = true; - - /* Set the storage to save the downloaded files and attachments */ - imap_data.storage.saved_path = F("/email_data"); - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - imap_data.storage.type = esp_mail_file_storage_type_flash; - - /** Set to download headers, text and html messaeges, - * attachments and inline images respectively. - */ - imap_data.download.header = true; - imap_data.download.text = true; - imap_data.download.html = true; - imap_data.download.attachment = true; - imap_data.download.inlineImg = true; - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option imap_data.limit.msg_size. - * The whole message can be download through imap_data.download.text - * or imap_data.download.html which not depends on these enable options. - */ - imap_data.enable.html = true; - imap_data.enable.text = true; - - /* Set to enable the sort the result by message UID in the decending order */ - imap_data.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - imap_data.enable.download_status = true; - - /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud - , to allow case sensitive parse, uncomment below line*/ - // imap_data.enable.header_case_sensitive = true; - - /* Set the limit of number of messages in the search results */ - imap_data.limit.search = 5; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - imap_data.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - imap_data.limit.attachment_size = 1024 * 1024 * 5; - - // If ID extension was supported by IMAP server, assign the client identification - // name, version, vendor, os, os_version, support_url, address, command, arguments, environment - // Server ID can be optained from imap.serverID() after calling imap.connect and imap.id. - - // imap_data.identification.name = "User"; - // imap_data.identification.version = "1.0"; - - /* Set the TCP response read timeout in seconds */ - // imap.setTCPTimeout(10); - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - /** Or connect without log in and log in later - - if (!imap.connect(&config, &imap_data, false)) - return; - - if (!imap.loginWithPassword(AUTHOR_EMAIL, AUTHOR_PASSWORD)) - return; - */ - - // Client identification can be sent to server later with - /** - * IMAP_Identification iden; - * iden.name = "user"; - * iden.version = "1.0"; - * - * if (imap.id(&iden)) - * { - * Serial.println("\nSend Identification success"); - * Serial.println(imap.serverID()); - * } - * else - * MailClient.printf("nIdentification sending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); - */ - - if (!imap.isLoggedIn()) - { - Serial.println("\nNot yet logged in."); - } - else - { - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - } - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* {Optional} */ - printSelectedMailboxInfo(imap.selectedFolder()); - - /** Read or search the Email and keep the TCP session to open - * The second parameter is for close the session. - */ - MailClient.readMail(&imap, false); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - - /** Open or select other mailbox folder - * The folder that previousely opened will be closed - */ - if (imap.selectFolder(F("Junk"))) - { - /* {Optional} */ - printSelectedMailboxInfo(imap.selectedFolder()); - - /** Config to search all messages in the opened mailboax (Search mode) - * For keywords used in search criteria, see - * https://github.com/mobizt/ESP-Mail-Client/tree/master/src#search-criteria - */ - imap_data.search.criteria = F("SEARCH ALL"); // or "SEARCH NEW" for recent received messages - - /* We will clear fetching message UID as it used to determine the reading mode i.e., search and fetch */ - imap_data.fetch.uid.clear(); - - /* Search the Email and close the session */ - MailClient.readMail(&imap); - } - - /* Close the seeion in case the session is still open */ - imap.closeSession(); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); -} - -void loop() -{ -} - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Show the result when reading finished */ - if (status.success()) - { - /* Print the result */ - /* Get the message list from the message list data */ - IMAP_MSG_List msgList = imap.data(); - printMessages(msgList.msgItems, imap.headerOnly()); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } -} - -void printAttacements(std::vector &atts) -{ - MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); - for (size_t j = 0; j < atts.size(); j++) - { - IMAP_Attach_Item att = atts[j]; - /** att.type can be - * esp_mail_att_type_none or 0 - * esp_mail_att_type_attachment or 1 - * esp_mail_att_type_inline or 2 - */ - MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); - } - Serial.println(); -} - -void printMessages(std::vector &msgItems, bool headerOnly) -{ - - for (size_t i = 0; i < msgItems.size(); i++) - { - - /* Iterate to get each message data through the message item data */ - IMAP_MSG_Item msg = msgItems[i]; - - Serial.println("****************************"); - // Message sequence number - MailClient.printf("Number: %d\n", msg.msgNo); - // Message UID - MailClient.printf("UID: %d\n", msg.UID); - - // The attachment status in search may be true in case the "multipart/mixed" - // content type header was set with no real attachtment included. - MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); - - MailClient.printf("Messsage-ID: %s\n", msg.ID); - - if (strlen(msg.flags)) - MailClient.printf("Flags: %s\n", msg.flags); - if (strlen(msg.acceptLang)) - MailClient.printf("Accept Language: %s\n", msg.acceptLang); - if (strlen(msg.contentLang)) - MailClient.printf("Content Language: %s\n", msg.contentLang); - if (strlen(msg.from)) - MailClient.printf("From: %s\n", msg.from); - if (strlen(msg.sender)) - MailClient.printf("Sender: %s\n", msg.sender); - if (strlen(msg.to)) - MailClient.printf("To: %s\n", msg.to); - if (strlen(msg.cc)) - MailClient.printf("CC: %s\n", msg.cc); - if (strlen(msg.bcc)) - MailClient.printf("BCC: %s\n", msg.bcc); - if (strlen(msg.date)) - { - MailClient.printf("Date: %s\n", msg.date); - MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); - } - if (strlen(msg.subject)) - MailClient.printf("Subject: %s\n", msg.subject); - if (strlen(msg.reply_to)) - MailClient.printf("Reply-To: %s\n", msg.reply_to); - if (strlen(msg.return_path)) - MailClient.printf("Return-Path: %s\n", msg.return_path); - if (strlen(msg.in_reply_to)) - MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); - if (strlen(msg.references)) - MailClient.printf("References: %s\n", msg.references); - if (strlen(msg.comments)) - MailClient.printf("Comments: %s\n", msg.comments); - if (strlen(msg.keywords)) - MailClient.printf("Keywords: %s\n", msg.keywords); - - /* If the result contains the message info (Fetch mode) */ - if (!headerOnly) - { - if (strlen(msg.text.content)) - MailClient.printf("Text Message: %s\n", msg.text.content); - if (strlen(msg.text.charSet)) - MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); - if (strlen(msg.text.transfer_encoding)) - MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - if (strlen(msg.html.content)) - MailClient.printf("HTML Message: %s\n", msg.html.content); - if (strlen(msg.html.charSet)) - MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); - if (strlen(msg.html.transfer_encoding)) - MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.rfc822.size() > 0) - { - MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - printMessages(msg.rfc822, headerOnly); - } - - if (msg.attachments.size() > 0) - printAttacements(msg.attachments); - } - - Serial.println(); - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +// This example shows how to search all messages with the keywords in the opened mailbox folder. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 // Plain or TLS with STARTTLS + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT esp_mail_imap_port_143 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Print all messages from the message list */ +void printMessages(std::vector &msgItems, bool headerOnly); + +/* Print all attachments info from the message */ +void printAttacements(std::vector &atts); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Declare the IMAP_Data object used for user defined IMAP operating options + * and contains the IMAP operating result + */ + IMAP_Data imap_data; + + /* We will clear fetching message UID as it used to determine the reading mode i.e., search and fetch */ + imap_data.fetch.uid.clear(); + + /** Search criteria + * + * A search key can also be a parenthesized list of one or more search keys + * (e.g., for use with the OR and NOT keys). + * + * Since IMAP protocol uses Polish notation, the search criteria which in the polish notation form can be. + * + * To search the message from "someone@email.com" with the subject "my subject" since 1 Jan 2021, your search criteria can be + * UID SEARCH (OR SUBJECT "my subject" FROM "someone@email.com") SINCE "Fri, 1 Jan 2021 21:52:25 -0800" + * + * To search the message from "mail1@domain.com" or from "mail2@domain.com", the search criteria will be + * UID SEARCH OR FROM mail1@domain.com FROM mail2@domain.com + * + * For more details on using parentheses, AND, OR and NOT search keys in search criteria. + * https://www.limilabs.com/blog/imap-search-requires-parentheses + * + *For keywords used in search criteria, see + * https://github.com/mobizt/ESP-Mail-Client/tree/master/src#search-criteria + * + * Use "SEARCH UNSEEN" for unread messages search + * Use "SEARCH RECENT" for messages with the \\RECENT flag set + * Use "ON _date_" for messages with Date header matching _date_ + * Use "BEFORE _date_" for messages with Date header before _date_ + */ + imap_data.search.criteria = F("SEARCH RECENT"); + + /* Also search the unseen message */ + imap_data.search.unseen_msg = true; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_flash; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Header fields parsing is case insensitive by default to avoid uppercase header in some server e.g. iCloud + , to allow case sensitive parse, uncomment below line*/ + // imap_data.enable.header_case_sensitive = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + // If ID extension was supported by IMAP server, assign the client identification + // name, version, vendor, os, os_version, support_url, address, command, arguments, environment + // Server ID can be optained from imap.serverID() after calling imap.connect and imap.id. + + // imap_data.identification.name = "User"; + // imap_data.identification.version = "1.0"; + + /* Set the TCP response read timeout in seconds */ + // imap.setTCPTimeout(10); + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + /** Or connect without log in and log in later + + if (!imap.connect(&config, &imap_data, false)) + return; + + if (!imap.loginWithPassword(AUTHOR_EMAIL, AUTHOR_PASSWORD)) + return; + */ + + // Client identification can be sent to server later with + /** + * IMAP_Identification iden; + * iden.name = "user"; + * iden.version = "1.0"; + * + * if (imap.id(&iden)) + * { + * Serial.println("\nSend Identification success"); + * Serial.println(imap.serverID()); + * } + * else + * MailClient.printf("nIdentification sending error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + */ + + if (!imap.isLoggedIn()) + { + Serial.println("\nNot yet logged in."); + } + else + { + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /** Read or search the Email and keep the TCP session to open + * The second parameter is for close the session. + */ + MailClient.readMail(&imap, false); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + + /** Open or select other mailbox folder + * The folder that previousely opened will be closed + */ + if (imap.selectFolder(F("Junk"))) + { + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /** Config to search all messages in the opened mailboax (Search mode) + * For keywords used in search criteria, see + * https://github.com/mobizt/ESP-Mail-Client/tree/master/src#search-criteria + */ + imap_data.search.criteria = F("SEARCH ALL"); // or "SEARCH NEW" for recent received messages + + /* We will clear fetching message UID as it used to determine the reading mode i.e., search and fetch */ + imap_data.fetch.uid.clear(); + + /* Search the Email and close the session */ + MailClient.readMail(&imap); + } + + /* Close the seeion in case the session is still open */ + imap.closeSession(); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); +} + +void loop() +{ +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + /* Print the result */ + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + /** att.type can be + * esp_mail_att_type_none or 0 + * esp_mail_att_type_attachment or 1 + * esp_mail_att_type_inline or 2 + */ + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + for (size_t i = 0; i < msgItems.size(); i++) + { + + /* Iterate to get each message data through the message item data */ + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + // Message sequence number + MailClient.printf("Number: %d\n", msg.msgNo); + // Message UID + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + /* If the result contains the message info (Fetch mode) */ + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_Emails_Silent_Mode/Search_Emails_Silent_Mode.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_Emails_Silent_Mode/Search_Emails_Silent_Mode.ino index 5f6367ef8..b57802576 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_Emails_Silent_Mode/Search_Emails_Silent_Mode.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Search_Emails_Silent_Mode/Search_Emails_Silent_Mode.ino @@ -1,327 +1,327 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to search all messages with the keywords in the opened mailbox folder. - -/** - * To use library in silent mode (no debug printing and callback), please define this macro in src/ESP_Mail_FS.h. - * #define SILENT_MODE - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -#define IMAP_HOST "" - -#define IMAP_PORT esp_mail_imap_port_143 - -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -void printImapData(IMAP_Status status); - -void printAllMailboxesInfo(IMAPSession &imap); - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -void printMessages(std::vector &msgItems, bool headerOnly); - -void printAttacements(std::vector &atts); - -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - MailClient.networkReconnect(true); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - Session_Config config; - - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - IMAP_Data imap_data; - - imap_data.fetch.uid.clear(); - - imap_data.search.criteria = F("SEARCH RECENT"); - - imap_data.search.unseen_msg = true; - - imap_data.storage.saved_path = F("/email_data"); - - imap_data.storage.type = esp_mail_file_storage_type_flash; - - imap_data.download.header = true; - imap_data.download.text = true; - imap_data.download.html = true; - imap_data.download.attachment = true; - imap_data.download.inlineImg = true; - - imap_data.enable.html = true; - imap_data.enable.text = true; - - imap_data.enable.recent_sort = true; - - imap_data.enable.download_status = true; - - imap_data.limit.search = 5; - - imap_data.limit.msg_size = 512; - - imap_data.limit.attachment_size = 1024 * 1024 * 5; - - imap.setTCPTimeout(10); - - if (!imap.connect(&config, &imap_data)) - { - MailClient.printf("Connection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); - return; - } - - if (imap.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - printAllMailboxesInfo(imap); - - if (!imap.selectFolder(F("INBOX"))) - { - MailClient.printf("Folder selection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); - return; - } - - printSelectedMailboxInfo(imap.selectedFolder()); - - if (MailClient.readMail(&imap, false)) - { - printImapData(imap.status()); - } - else - { - MailClient.printf("Message searching error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); - } - - imap.closeSession(); - - imap.empty(); -} - -void loop() -{ -} - -void printImapData(IMAP_Status status) -{ - - if (status.success()) - { - MailClient.printf("\nFound %d messages\n\n", imap.selectedFolder().searchCount()); - - IMAP_MSG_List msgList = imap.data(); - printMessages(msgList.msgItems, imap.headerOnly()); - - imap.empty(); - } -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - FoldersCollection folders; - - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } -} - -void printAttacements(std::vector &atts) -{ - MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); - for (size_t j = 0; j < atts.size(); j++) - { - IMAP_Attach_Item att = atts[j]; - MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); - } - Serial.println(); -} - -void printMessages(std::vector &msgItems, bool headerOnly) -{ - - for (size_t i = 0; i < msgItems.size(); i++) - { - IMAP_MSG_Item msg = msgItems[i]; - - Serial.println("****************************"); - - MailClient.printf("Number: %d\n", msg.msgNo); - MailClient.printf("UID: %d\n", msg.UID); - - // The attachment status in search may be true in case the "multipart/mixed" - // content type header was set with no real attachtment included. - MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); - - MailClient.printf("Messsage-ID: %s\n", msg.ID); - - if (strlen(msg.flags)) - MailClient.printf("Flags: %s\n", msg.flags); - if (strlen(msg.acceptLang)) - MailClient.printf("Accept Language: %s\n", msg.acceptLang); - if (strlen(msg.contentLang)) - MailClient.printf("Content Language: %s\n", msg.contentLang); - if (strlen(msg.from)) - MailClient.printf("From: %s\n", msg.from); - if (strlen(msg.sender)) - MailClient.printf("Sender: %s\n", msg.sender); - if (strlen(msg.to)) - MailClient.printf("To: %s\n", msg.to); - if (strlen(msg.cc)) - MailClient.printf("CC: %s\n", msg.cc); - if (strlen(msg.bcc)) - MailClient.printf("BCC: %s\n", msg.bcc); - if (strlen(msg.date)) - { - MailClient.printf("Date: %s\n", msg.date); - MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); - } - if (strlen(msg.subject)) - MailClient.printf("Subject: %s\n", msg.subject); - if (strlen(msg.reply_to)) - MailClient.printf("Reply-To: %s\n", msg.reply_to); - if (strlen(msg.return_path)) - MailClient.printf("Return-Path: %s\n", msg.return_path); - if (strlen(msg.in_reply_to)) - MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); - if (strlen(msg.references)) - MailClient.printf("References: %s\n", msg.references); - if (strlen(msg.comments)) - MailClient.printf("Comments: %s\n", msg.comments); - if (strlen(msg.keywords)) - MailClient.printf("Keywords: %s\n", msg.keywords); - - if (!headerOnly) - { - if (strlen(msg.text.content)) - MailClient.printf("Text Message: %s\n", msg.text.content); - if (strlen(msg.text.charSet)) - MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); - if (strlen(msg.text.transfer_encoding)) - MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); - if (strlen(msg.html.content)) - MailClient.printf("HTML Message: %s\n", msg.html.content); - if (strlen(msg.html.charSet)) - MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); - if (strlen(msg.html.transfer_encoding)) - MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); - - if (msg.rfc822.size() > 0) - { - MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); - printMessages(msg.rfc822, headerOnly); - } - - if (msg.attachments.size() > 0) - printAttacements(msg.attachments); - } - - Serial.println(); - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to search all messages with the keywords in the opened mailbox folder. + +/** + * To use library in silent mode (no debug printing and callback), please define this macro in src/ESP_Mail_FS.h. + * #define SILENT_MODE + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define IMAP_HOST "" + +#define IMAP_PORT esp_mail_imap_port_143 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +void printImapData(IMAP_Status status); + +void printAllMailboxesInfo(IMAPSession &imap); + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +void printMessages(std::vector &msgItems, bool headerOnly); + +void printAttacements(std::vector &atts); + +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + MailClient.networkReconnect(true); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + Session_Config config; + + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + IMAP_Data imap_data; + + imap_data.fetch.uid.clear(); + + imap_data.search.criteria = F("SEARCH RECENT"); + + imap_data.search.unseen_msg = true; + + imap_data.storage.saved_path = F("/email_data"); + + imap_data.storage.type = esp_mail_file_storage_type_flash; + + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + imap_data.enable.html = true; + imap_data.enable.text = true; + + imap_data.enable.recent_sort = true; + + imap_data.enable.download_status = true; + + imap_data.limit.search = 5; + + imap_data.limit.msg_size = 512; + + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + imap.setTCPTimeout(10); + + if (!imap.connect(&config, &imap_data)) + { + MailClient.printf("Connection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + return; + } + + if (imap.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + printAllMailboxesInfo(imap); + + if (!imap.selectFolder(F("INBOX"))) + { + MailClient.printf("Folder selection error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + return; + } + + printSelectedMailboxInfo(imap.selectedFolder()); + + if (MailClient.readMail(&imap, false)) + { + printImapData(imap.status()); + } + else + { + MailClient.printf("Message searching error, Error Code: %d, Reason: %s", imap.errorCode(), imap.errorReason().c_str()); + } + + imap.closeSession(); + + imap.empty(); +} + +void loop() +{ +} + +void printImapData(IMAP_Status status) +{ + + if (status.success()) + { + MailClient.printf("\nFound %d messages\n\n", imap.selectedFolder().searchCount()); + + IMAP_MSG_List msgList = imap.data(); + printMessages(msgList.msgItems, imap.headerOnly()); + + imap.empty(); + } +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + FoldersCollection folders; + + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} + +void printAttacements(std::vector &atts) +{ + MailClient.printf("Attachment: %d file(s)\n****************************\n", atts.size()); + for (size_t j = 0; j < atts.size(); j++) + { + IMAP_Attach_Item att = atts[j]; + MailClient.printf("%d. Filename: %s, Name: %s, Size: %d, MIME: %s, Type: %s, Description: %s, Creation Date: %s\n", j + 1, att.filename, att.name, att.size, att.mime, att.type == esp_mail_att_type_attachment ? "attachment" : "inline", att.description, att.creationDate); + } + Serial.println(); +} + +void printMessages(std::vector &msgItems, bool headerOnly) +{ + + for (size_t i = 0; i < msgItems.size(); i++) + { + IMAP_MSG_Item msg = msgItems[i]; + + Serial.println("****************************"); + + MailClient.printf("Number: %d\n", msg.msgNo); + MailClient.printf("UID: %d\n", msg.UID); + + // The attachment status in search may be true in case the "multipart/mixed" + // content type header was set with no real attachtment included. + MailClient.printf("Attachment: %s\n", msg.hasAttachment ? "yes" : "no"); + + MailClient.printf("Messsage-ID: %s\n", msg.ID); + + if (strlen(msg.flags)) + MailClient.printf("Flags: %s\n", msg.flags); + if (strlen(msg.acceptLang)) + MailClient.printf("Accept Language: %s\n", msg.acceptLang); + if (strlen(msg.contentLang)) + MailClient.printf("Content Language: %s\n", msg.contentLang); + if (strlen(msg.from)) + MailClient.printf("From: %s\n", msg.from); + if (strlen(msg.sender)) + MailClient.printf("Sender: %s\n", msg.sender); + if (strlen(msg.to)) + MailClient.printf("To: %s\n", msg.to); + if (strlen(msg.cc)) + MailClient.printf("CC: %s\n", msg.cc); + if (strlen(msg.bcc)) + MailClient.printf("BCC: %s\n", msg.bcc); + if (strlen(msg.date)) + { + MailClient.printf("Date: %s\n", msg.date); + MailClient.printf("Timestamp: %d\n", (int)MailClient.Time.getTimestamp(msg.date)); + } + if (strlen(msg.subject)) + MailClient.printf("Subject: %s\n", msg.subject); + if (strlen(msg.reply_to)) + MailClient.printf("Reply-To: %s\n", msg.reply_to); + if (strlen(msg.return_path)) + MailClient.printf("Return-Path: %s\n", msg.return_path); + if (strlen(msg.in_reply_to)) + MailClient.printf("In-Reply-To: %s\n", msg.in_reply_to); + if (strlen(msg.references)) + MailClient.printf("References: %s\n", msg.references); + if (strlen(msg.comments)) + MailClient.printf("Comments: %s\n", msg.comments); + if (strlen(msg.keywords)) + MailClient.printf("Keywords: %s\n", msg.keywords); + + if (!headerOnly) + { + if (strlen(msg.text.content)) + MailClient.printf("Text Message: %s\n", msg.text.content); + if (strlen(msg.text.charSet)) + MailClient.printf("Text Message Charset: %s\n", msg.text.charSet); + if (strlen(msg.text.transfer_encoding)) + MailClient.printf("Text Message Transfer Encoding: %s\n", msg.text.transfer_encoding); + if (strlen(msg.html.content)) + MailClient.printf("HTML Message: %s\n", msg.html.content); + if (strlen(msg.html.charSet)) + MailClient.printf("HTML Message Charset: %s\n", msg.html.charSet); + if (strlen(msg.html.transfer_encoding)) + MailClient.printf("HTML Message Transfer Encoding: %s\n\n", msg.html.transfer_encoding); + + if (msg.rfc822.size() > 0) + { + MailClient.printf("\r\nRFC822 Messages: %d message(s)\n****************************\n", msg.rfc822.size()); + printMessages(msg.rfc822, headerOnly); + } + + if (msg.attachments.size() > 0) + printAttacements(msg.attachments); + } + + Serial.println(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_List/Set_Flags_List.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_List/Set_Flags_List.ino index 3aedc9021..5713424d2 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_List/Set_Flags_List.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_List/Set_Flags_List.ino @@ -1,339 +1,339 @@ -/** - * This example shows how to set messages flags. - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt - * - */ - -// This example shows how to set messages flags. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Set seen flag */ - // imap_data.fetch.set_seen = true; - - /* Search criteria */ - imap_data.search.criteria.clear(); - - /* Also search the unseen message */ - imap_data.search.unseen_msg = true; - - /* Set the storage to save the downloaded files and attachments */ - imap_data.storage.saved_path = F("/email_data"); - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - imap_data.storage.type = esp_mail_file_storage_type_flash; - - /** Set to download headers, text and html messaeges, - * attachments and inline images respectively. - */ - imap_data.download.header = true; - imap_data.download.text = true; - imap_data.download.html = true; - imap_data.download.attachment = true; - imap_data.download.inlineImg = true; - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option imap_data.limit.msg_size. - * The whole message can be download through imap_data.download.text - * or imap_data.download.html which not depends on these enable options. - */ - imap_data.enable.html = true; - imap_data.enable.text = true; - - /* Set to enable the sort the result by message UID in the decending order */ - imap_data.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - imap_data.enable.download_status = true; - - /* Set the limit of number of messages in the search results */ - imap_data.limit.search = 5; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - imap_data.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - imap_data.limit.attachment_size = 1024 * 1024 * 5; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* {Optional} */ - printSelectedMailboxInfo(imap.selectedFolder()); - - /* Message UID to fetch or read e.g. 100 */ - int uid = imap.getUID(imap.selectedFolder().msgCount()); - - /** Set \Seen and \Answered to flags for message with UID - * The seesion will keep open. - */ - if (MailClient.setFlag(&imap, uid, F("\\Seen \\Answered"), false)) - Serial.println("\nSetting FLAG success"); - else - Serial.println("\nError, setting FLAG"); - - /* Add \Seen and \Answered to flags for message with UID 100 */ - // MailClient.addFlag(imap, 100, "\\Seen \\Answered", false); - - /* Remove \Seen and \Answered from flags for message with UID 100 */ - // MailClient.removeFlag(imap, 100, "\\Seen \\Answered", false); - - /* Remove Seen and Answered flags from messages using UID ranges (last 10 UIDs) */ - int uid_last = imap.getUID(imap.selectedFolder().msgCount()); - int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; - - String sequence_set1 = String(uid_begin) + ":" + String(uid_last); - - if (MailClient.removeFlag(&imap, sequence_set1, true /* if sequence set are the UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) - Serial.println("\nRemoving FLAG with UIDs ranges success"); - else - Serial.println("\nError, removing FLAG with UIDs ranges"); - - /* Remove Seen and Answered flags from messages using message sequence ranges (last 10 message numbers) */ - int msg_last = imap.selectedFolder().msgCount(); - int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; - - String sequence_set2 = String(msg_begin) + ":" + String(msg_last); - - if (MailClient.removeFlag(&imap, sequence_set2, false /* if sequence set are message numbers not UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) - Serial.println("\nRemoving FLAG with message numbers ranges success"); - else - Serial.println("\nError, removing FLAG with message numbers ranges"); - - imap_data.fetch.uid = uid; - - /* Read or search the Email and close the session */ - MailClient.readMail(&imap); - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } -} +/** + * This example shows how to set messages flags. + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + * + */ + +// This example shows how to set messages flags. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Set seen flag */ + // imap_data.fetch.set_seen = true; + + /* Search criteria */ + imap_data.search.criteria.clear(); + + /* Also search the unseen message */ + imap_data.search.unseen_msg = true; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_flash; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /* Message UID to fetch or read e.g. 100 */ + int uid = imap.getUID(imap.selectedFolder().msgCount()); + + /** Set \Seen and \Answered to flags for message with UID + * The seesion will keep open. + */ + if (MailClient.setFlag(&imap, uid, F("\\Seen \\Answered"), false)) + Serial.println("\nSetting FLAG success"); + else + Serial.println("\nError, setting FLAG"); + + /* Add \Seen and \Answered to flags for message with UID 100 */ + // MailClient.addFlag(imap, 100, "\\Seen \\Answered", false); + + /* Remove \Seen and \Answered from flags for message with UID 100 */ + // MailClient.removeFlag(imap, 100, "\\Seen \\Answered", false); + + /* Remove Seen and Answered flags from messages using UID ranges (last 10 UIDs) */ + int uid_last = imap.getUID(imap.selectedFolder().msgCount()); + int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; + + String sequence_set1 = String(uid_begin) + ":" + String(uid_last); + + if (MailClient.removeFlag(&imap, sequence_set1, true /* if sequence set are the UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) + Serial.println("\nRemoving FLAG with UIDs ranges success"); + else + Serial.println("\nError, removing FLAG with UIDs ranges"); + + /* Remove Seen and Answered flags from messages using message sequence ranges (last 10 message numbers) */ + int msg_last = imap.selectedFolder().msgCount(); + int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; + + String sequence_set2 = String(msg_begin) + ":" + String(msg_last); + + if (MailClient.removeFlag(&imap, sequence_set2, false /* if sequence set are message numbers not UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) + Serial.println("\nRemoving FLAG with message numbers ranges success"); + else + Serial.println("\nError, removing FLAG with message numbers ranges"); + + imap_data.fetch.uid = uid; + + /* Read or search the Email and close the session */ + MailClient.readMail(&imap); + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_Message_Numbers_Ranges/Set_Flags_Message_Numbers_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_Message_Numbers_Ranges/Set_Flags_Message_Numbers_Ranges.ino index 0e2645f25..2379fd789 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_Message_Numbers_Ranges/Set_Flags_Message_Numbers_Ranges.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_Message_Numbers_Ranges/Set_Flags_Message_Numbers_Ranges.ino @@ -1,309 +1,309 @@ -/** - * This example shows how to set messages flags. - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt - * - */ - -// This example shows how to set messages flags using message numbers ranges. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Set seen flag */ - // imap_data.fetch.set_seen = true; - - /* Search criteria */ - imap_data.search.criteria.clear(); - - /* Also search the unseen message */ - imap_data.search.unseen_msg = true; - - /* Set the storage to save the downloaded files and attachments */ - imap_data.storage.saved_path = F("/email_data"); - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - imap_data.storage.type = esp_mail_file_storage_type_flash; - - /** Set to download headers, text and html messaeges, - * attachments and inline images respectively. - */ - imap_data.download.header = true; - imap_data.download.text = true; - imap_data.download.html = true; - imap_data.download.attachment = true; - imap_data.download.inlineImg = true; - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option imap_data.limit.msg_size. - * The whole message can be download through imap_data.download.text - * or imap_data.download.html which not depends on these enable options. - */ - imap_data.enable.html = true; - imap_data.enable.text = true; - - /* Set to enable the sort the result by message UID in the decending order */ - imap_data.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - imap_data.enable.download_status = true; - - /* Set the limit of number of messages in the search results */ - imap_data.limit.search = 5; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - imap_data.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - imap_data.limit.attachment_size = 1024 * 1024 * 5; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* {Optional} */ - printSelectedMailboxInfo(imap.selectedFolder()); - - /* Add Seen and Answered flags from messages using message numbers ranges (last 10 message numbers) */ - int msg_last = imap.selectedFolder().msgCount(); - int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; - - String sequence_set1 = String(msg_begin) + ":" + String(msg_last); - - if (MailClient.addFlag(&imap, sequence_set1, false /* if sequence set are message numbers not UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) - Serial.println("\nAdding FLAG with message numbers ranges success"); - else - Serial.println("\nError, adding FLAG with message numbers ranges"); - - /* Remove Seen and Answered flags from messages using message numbers ranges (last 10 message numbers) */ - if (MailClient.removeFlag(&imap, sequence_set1, false /* if sequence set are message numbers not UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) - Serial.println("\nRemoving FLAG with message numbers ranges success"); - else - Serial.println("\nError, removing FLAG with message numbers ranges"); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } -} +/** + * This example shows how to set messages flags. + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + * + */ + +// This example shows how to set messages flags using message numbers ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Set seen flag */ + // imap_data.fetch.set_seen = true; + + /* Search criteria */ + imap_data.search.criteria.clear(); + + /* Also search the unseen message */ + imap_data.search.unseen_msg = true; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_flash; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /* Add Seen and Answered flags from messages using message numbers ranges (last 10 message numbers) */ + int msg_last = imap.selectedFolder().msgCount(); + int msg_begin = msg_last > 10 ? msg_last - 10 : msg_last; + + String sequence_set1 = String(msg_begin) + ":" + String(msg_last); + + if (MailClient.addFlag(&imap, sequence_set1, false /* if sequence set are message numbers not UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) + Serial.println("\nAdding FLAG with message numbers ranges success"); + else + Serial.println("\nError, adding FLAG with message numbers ranges"); + + /* Remove Seen and Answered flags from messages using message numbers ranges (last 10 message numbers) */ + if (MailClient.removeFlag(&imap, sequence_set1, false /* if sequence set are message numbers not UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) + Serial.println("\nRemoving FLAG with message numbers ranges success"); + else + Serial.println("\nError, removing FLAG with message numbers ranges"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_UIDs_Ranges/Set_Flags_UIDs_Ranges.ino b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_UIDs_Ranges/Set_Flags_UIDs_Ranges.ino index 4e3ccc2ad..77d7955a7 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_UIDs_Ranges/Set_Flags_UIDs_Ranges.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/IMAP/Set_Flags/Set_Flags_UIDs_Ranges/Set_Flags_UIDs_Ranges.ino @@ -1,310 +1,310 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to set messages flags. - -// This example shows how to set messages flags using UIDs ranges. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For ESP8266, with BearSSL WiFi Client - * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which - * may cause your device out of memory reset in case the memory - * allocation error. - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en - * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha - * - * Some Gmail user still not able to sign in using account password even above options were set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" - -/** The imap port e.g. - * 143 or esp_mail_imap_port_143 - * 993 or esp_mail_imap_port_993 - */ -#define IMAP_PORT 993 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Print the list of mailbox folders */ -void printAllMailboxesInfo(IMAPSession &imap); - -/* Print the selected folder info */ -void printSelectedMailboxInfo(SelectedFolderInfo sFolder); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - imap.debug(1); - - /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from - * MailClient.sdBegin function which may be different for ESP32 and ESP8266 - * For ESP32, assign all of SPI pins - * MailClient.sdBegin(14,2,15,13) - * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 - * And for ESP8266, assign the CS pins of SPI port - * MailClient.sdBegin(15) - * Which pin 15 is the CS pin of SD card adapter - */ - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = IMAP_HOST; - config.server.port = IMAP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Define the IMAP_Data object used for user defined IMAP operating options. */ - IMAP_Data imap_data; - - /* Set seen flag */ - // imap_data.fetch.set_seen = true; - - /* Search criteria */ - imap_data.search.criteria.clear(); - - /* Also search the unseen message */ - imap_data.search.unseen_msg = true; - - /* Set the storage to save the downloaded files and attachments */ - imap_data.storage.saved_path = F("/email_data"); - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - imap_data.storage.type = esp_mail_file_storage_type_flash; - - /** Set to download headers, text and html messaeges, - * attachments and inline images respectively. - */ - imap_data.download.header = true; - imap_data.download.text = true; - imap_data.download.html = true; - imap_data.download.attachment = true; - imap_data.download.inlineImg = true; - - /** Set to enable the results i.e. html and text messaeges - * which the content stored in the IMAPSession object is limited - * by the option imap_data.limit.msg_size. - * The whole message can be download through imap_data.download.text - * or imap_data.download.html which not depends on these enable options. - */ - imap_data.enable.html = true; - imap_data.enable.text = true; - - /* Set to enable the sort the result by message UID in the decending order */ - imap_data.enable.recent_sort = true; - - /* Set to report the download progress via the default serial port */ - imap_data.enable.download_status = true; - - /* Set the limit of number of messages in the search results */ - imap_data.limit.search = 5; - - /** Set the maximum size of message stored in - * IMAPSession object in byte - */ - imap_data.limit.msg_size = 512; - - /** Set the maximum attachments and inline images files size - * that can be downloaded in byte. - * The file which its size is largger than this limit may be saved - * as truncated file. - */ - imap_data.limit.attachment_size = 1024 * 1024 * 5; - - /* Connect to the server */ - if (!imap.connect(&config, &imap_data)) - return; - - /* {Optional} */ - printAllMailboxesInfo(imap); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - /* {Optional} */ - printSelectedMailboxInfo(imap.selectedFolder()); - - /* Add Seen and Answered flags from messages using UID ranges (last 10 UIDs) */ - int uid_last = imap.getUID(imap.selectedFolder().msgCount()); - int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; - - String sequence_set1 = String(uid_begin) + ":" + String(uid_last); - - if (MailClient.addFlag(&imap, sequence_set1, true /* if sequence set are the UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) - Serial.println("\nAdding FLAG with UIDs ranges success"); - else - Serial.println("\nError, adding FLAG with UIDs ranges"); - - /* Remove Seen and Answered flags from messages using UID ranges (last 10 UIDs) */ - if (MailClient.removeFlag(&imap, sequence_set1, true /* if sequence set are the UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) - Serial.println("\nRemoving FLAG with UIDs ranges success"); - else - Serial.println("\nError, removing FLAG with UIDs ranges"); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -void printAllMailboxesInfo(IMAPSession &imap) -{ - /* Declare the folder collection class to get the list of mailbox folders */ - FoldersCollection folders; - - /* Get the mailbox folders */ - if (imap.getFolders(folders)) - { - for (size_t i = 0; i < folders.size(); i++) - { - /* Iterate each folder info using the folder info item data */ - FolderInfo folderInfo = folders.info(i); - MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); - } - } -} - -void printSelectedMailboxInfo(SelectedFolderInfo sFolder) -{ - /* Show the mailbox info */ - MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); - MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); - MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); - if (sFolder.unseenIndex() > 0) - MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); - else - MailClient.printf("Unseen Messages: No\n"); - - if (sFolder.modSeqSupported()) - MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); - for (size_t i = 0; i < sFolder.flagCount(); i++) - MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); - - if (sFolder.flagCount(true)) - { - for (size_t i = 0; i < sFolder.flagCount(true); i++) - MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to set messages flags. + +// This example shows how to set messages flags using UIDs ranges. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For ESP8266, with BearSSL WiFi Client + * The memory reserved for completed valid SSL response from IMAP is 16 kbytes which + * may cause your device out of memory reset in case the memory + * allocation error. + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, IMAP option should be enabled. https://support.google.com/mail/answer/7126229?hl=en + * and also https://accounts.google.com/b/0/DisplayUnlockCaptcha + * + * Some Gmail user still not able to sign in using account password even above options were set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" + +/** The imap port e.g. + * 143 or esp_mail_imap_port_143 + * 993 or esp_mail_imap_port_993 + */ +#define IMAP_PORT 993 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Print the list of mailbox folders */ +void printAllMailboxesInfo(IMAPSession &imap); + +/* Print the selected folder info */ +void printSelectedMailboxInfo(SelectedFolderInfo sFolder); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + imap.debug(1); + + /** In case the SD card/adapter was used for the file storagge, the SPI pins can be configure from + * MailClient.sdBegin function which may be different for ESP32 and ESP8266 + * For ESP32, assign all of SPI pins + * MailClient.sdBegin(14,2,15,13) + * Which SCK = 14, MISO = 2, MOSI = 15 and SS = 13 + * And for ESP8266, assign the CS pins of SPI port + * MailClient.sdBegin(15) + * Which pin 15 is the CS pin of SD card adapter + */ + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = IMAP_HOST; + config.server.port = IMAP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Define the IMAP_Data object used for user defined IMAP operating options. */ + IMAP_Data imap_data; + + /* Set seen flag */ + // imap_data.fetch.set_seen = true; + + /* Search criteria */ + imap_data.search.criteria.clear(); + + /* Also search the unseen message */ + imap_data.search.unseen_msg = true; + + /* Set the storage to save the downloaded files and attachments */ + imap_data.storage.saved_path = F("/email_data"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + imap_data.storage.type = esp_mail_file_storage_type_flash; + + /** Set to download headers, text and html messaeges, + * attachments and inline images respectively. + */ + imap_data.download.header = true; + imap_data.download.text = true; + imap_data.download.html = true; + imap_data.download.attachment = true; + imap_data.download.inlineImg = true; + + /** Set to enable the results i.e. html and text messaeges + * which the content stored in the IMAPSession object is limited + * by the option imap_data.limit.msg_size. + * The whole message can be download through imap_data.download.text + * or imap_data.download.html which not depends on these enable options. + */ + imap_data.enable.html = true; + imap_data.enable.text = true; + + /* Set to enable the sort the result by message UID in the decending order */ + imap_data.enable.recent_sort = true; + + /* Set to report the download progress via the default serial port */ + imap_data.enable.download_status = true; + + /* Set the limit of number of messages in the search results */ + imap_data.limit.search = 5; + + /** Set the maximum size of message stored in + * IMAPSession object in byte + */ + imap_data.limit.msg_size = 512; + + /** Set the maximum attachments and inline images files size + * that can be downloaded in byte. + * The file which its size is largger than this limit may be saved + * as truncated file. + */ + imap_data.limit.attachment_size = 1024 * 1024 * 5; + + /* Connect to the server */ + if (!imap.connect(&config, &imap_data)) + return; + + /* {Optional} */ + printAllMailboxesInfo(imap); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + /* {Optional} */ + printSelectedMailboxInfo(imap.selectedFolder()); + + /* Add Seen and Answered flags from messages using UID ranges (last 10 UIDs) */ + int uid_last = imap.getUID(imap.selectedFolder().msgCount()); + int uid_begin = uid_last > 10 ? uid_last - 10 : uid_last; + + String sequence_set1 = String(uid_begin) + ":" + String(uid_last); + + if (MailClient.addFlag(&imap, sequence_set1, true /* if sequence set are the UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) + Serial.println("\nAdding FLAG with UIDs ranges success"); + else + Serial.println("\nError, adding FLAG with UIDs ranges"); + + /* Remove Seen and Answered flags from messages using UID ranges (last 10 UIDs) */ + if (MailClient.removeFlag(&imap, sequence_set1, true /* if sequence set are the UIDs */, F("\\Seen \\Answered"), false /* Close session */, false /* Ignore response */)) + Serial.println("\nRemoving FLAG with UIDs ranges success"); + else + Serial.println("\nError, removing FLAG with UIDs ranges"); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void printAllMailboxesInfo(IMAPSession &imap) +{ + /* Declare the folder collection class to get the list of mailbox folders */ + FoldersCollection folders; + + /* Get the mailbox folders */ + if (imap.getFolders(folders)) + { + for (size_t i = 0; i < folders.size(); i++) + { + /* Iterate each folder info using the folder info item data */ + FolderInfo folderInfo = folders.info(i); + MailClient.printf("%s%s%s", i == 0 ? "\nAvailable folders: " : ", ", folderInfo.name, i == folders.size() - 1 ? "\n" : ""); + } + } +} + +void printSelectedMailboxInfo(SelectedFolderInfo sFolder) +{ + /* Show the mailbox info */ + MailClient.printf("\nInfo of the selected folder\nTotal Messages: %d\n", sFolder.msgCount()); + MailClient.printf("UID Validity: %d\n", sFolder.uidValidity()); + MailClient.printf("Predicted next UID: %d\n", sFolder.nextUID()); + if (sFolder.unseenIndex() > 0) + MailClient.printf("First Unseen Message Number: %d\n", sFolder.unseenIndex()); + else + MailClient.printf("Unseen Messages: No\n"); + + if (sFolder.modSeqSupported()) + MailClient.printf("Highest Modification Sequence: %llu\n", sFolder.highestModSeq()); + for (size_t i = 0; i < sFolder.flagCount(); i++) + MailClient.printf("%s%s%s", i == 0 ? "Flags: " : ", ", sFolder.flag(i).c_str(), i == sFolder.flagCount() - 1 ? "\n" : ""); + + if (sFolder.flagCount(true)) + { + for (size_t i = 0; i < sFolder.flagCount(true); i++) + MailClient.printf("%s%s%s", i == 0 ? "Permanent Flags: " : ", ", sFolder.flag(i, true).c_str(), i == sFolder.flagCount(true) - 1 ? "\n" : ""); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/Basic_Auth/Basic_Auth.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/Basic_Auth/Basic_Auth.ino index c43a149eb..47dda4a29 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/Basic_Auth/Basic_Auth.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/Basic_Auth/Basic_Auth.ino @@ -1,219 +1,219 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example showes how to send Email using custom commands. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 // See STARTTLS.ino example - */ -#define SMTP_PORT esp_mail_smtp_port_465 // port 465 is not available for Outlook.com - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" - "-----END CERTIFICATE-----\n"; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void customCommandCallback(SMTP_Response res) -{ - - // The res.id is the command identifier number that use to identify the source of command. - - // The command identifier number can be set via the last parameter of customConnect and sendCustomCommand functions. - - // If command identifier number was not set in those functions, the res.id received will be auto increased and begins with 0 - - MailClient.printf("> C: Command ID %d\n", res.id); - MailClient.printf("< S: %s\n", res.text.c_str()); - - if (res.statusCode > 0) - { - MailClient.printf("> C: Response finished with status code %d\n\n", res.statusCode); - } -} - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /* Connect to the server */ - if (!smtp.connect(&config)) - return; - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - // Please don't forget to change sender@xxxxxx.com to your email - if (smtp.sendCustomCommand(F("MAIL FROM:"), customCommandCallback) != 250) - { - smtp.closeSession(); - return; - } - - // Please don't forget to change recipient@xxxxx.com with your recipient email - if (smtp.sendCustomCommand(F("RCPT TO:"), customCommandCallback) != 250) - { - smtp.closeSession(); - return; - } - - if (smtp.sendCustomCommand(F("DATA"), customCommandCallback) != 354) - { - smtp.closeSession(); - return; - } - - // Send data with command which terminated with dot '.' - if (smtp.sendCustomCommand(F("Subject: Test sending Email\r\nHello World!\r\n."), customCommandCallback) != 250) - { - smtp.closeSession(); - return; - } - - // Do not use this command in ESP8266 due to memory leaks in ESP8266 core BearSSL. - // smtp.sendCustomCommand(F("QUIT"), customCommandCallback); - - smtp.closeSession(); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example showes how to send Email using custom commands. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 // See STARTTLS.ino example + */ +#define SMTP_PORT esp_mail_smtp_port_465 // port 465 is not available for Outlook.com + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" + "-----END CERTIFICATE-----\n"; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void customCommandCallback(SMTP_Response res) +{ + + // The res.id is the command identifier number that use to identify the source of command. + + // The command identifier number can be set via the last parameter of customConnect and sendCustomCommand functions. + + // If command identifier number was not set in those functions, the res.id received will be auto increased and begins with 0 + + MailClient.printf("> C: Command ID %d\n", res.id); + MailClient.printf("< S: %s\n", res.text.c_str()); + + if (res.statusCode > 0) + { + MailClient.printf("> C: Response finished with status code %d\n\n", res.statusCode); + } +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* Connect to the server */ + if (!smtp.connect(&config)) + return; + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + // Please don't forget to change sender@xxxxxx.com to your email + if (smtp.sendCustomCommand(F("MAIL FROM:"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + // Please don't forget to change recipient@xxxxx.com with your recipient email + if (smtp.sendCustomCommand(F("RCPT TO:"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(F("DATA"), customCommandCallback) != 354) + { + smtp.closeSession(); + return; + } + + // Send data with command which terminated with dot '.' + if (smtp.sendCustomCommand(F("Subject: Test sending Email\r\nHello World!\r\n."), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + // Do not use this command in ESP8266 due to memory leaks in ESP8266 core BearSSL. + // smtp.sendCustomCommand(F("QUIT"), customCommandCallback); + + smtp.closeSession(); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/Custom_Auth/Custom_Auth.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/Custom_Auth/Custom_Auth.ino index 13f50920c..d1b2dac04 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/Custom_Auth/Custom_Auth.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/Custom_Auth/Custom_Auth.ino @@ -1,248 +1,248 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example showes how to send Email using custom commands. - - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 // See STARTTLS.ino example - */ -#define SMTP_PORT esp_mail_smtp_port_465 // port 465 is not available for Outlook.com - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" - "-----END CERTIFICATE-----\n"; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void customCommandCallback(SMTP_Response res) -{ - - // The res.id is the command identifier number that use to identify the source of command. - - // The command identifier number can be set via the last parameter of customConnect and sendCustomCommand functions. - - // If command identifier number was not set in those functions, the res.id received will be auto increased and begins with 0 - - MailClient.printf("> C: Command ID %d\n", res.id); - MailClient.printf("< S: %s\n", res.text.c_str()); - - if (res.statusCode > 0) - { - MailClient.printf("> C: Response finished with status code %d\n\n", res.statusCode); - } -} - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /* Connect to the server */ - if (smtp.customConnect(&config /* session credentials */, customCommandCallback) != 220) - { - Serial.println("! E: Unable to connect to server"); - return; - } - - if (smtp.sendCustomCommand(F("EHLO 127.0.0.1"), customCommandCallback) != 250) - { - smtp.closeSession(); - return; - } - - if (smtp.sendCustomCommand(F("AUTH LOGIN"), customCommandCallback) != 334) - { - smtp.closeSession(); - return; - } - - if (smtp.sendCustomCommand(MailClient.toBase64(config.login.email), customCommandCallback) != 334) - { - smtp.closeSession(); - return; - } - - if (smtp.sendCustomCommand(MailClient.toBase64(config.login.password), customCommandCallback) != 235) - { - smtp.closeSession(); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("Successfully logged in.\n"); - else - Serial.println("Connected with no Auth.\n"); - - // Please don't forget to change sender@xxxxxx.com to your email - if (smtp.sendCustomCommand(F("MAIL FROM:"), customCommandCallback) != 250) - { - smtp.closeSession(); - return; - } - - // Please don't forget to change recipient@xxxxx.com with your recipient email - if (smtp.sendCustomCommand(F("RCPT TO:"), customCommandCallback) != 250) - { - smtp.closeSession(); - return; - } - - if (smtp.sendCustomCommand(F("DATA"), customCommandCallback) != 354) - { - smtp.closeSession(); - return; - } - - if (!smtp.sendCustomData(F("Subject: Test sending Email\r\n"))) - { - smtp.closeSession(); - return; - } - - if (!smtp.sendCustomData(F("Hello World!\r\n"))) - { - smtp.closeSession(); - return; - } - - if (smtp.sendCustomCommand(F("."), customCommandCallback) != 250) - { - smtp.closeSession(); - return; - } - - // Do not use this command in ESP8266 due to memory leaks in ESP8266 core BearSSL. - // smtp.sendCustomCommand(F("QUIT"), customCommandCallback); - - smtp.closeSession(); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example showes how to send Email using custom commands. + + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 // See STARTTLS.ino example + */ +#define SMTP_PORT esp_mail_smtp_port_465 // port 465 is not available for Outlook.com + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" + "-----END CERTIFICATE-----\n"; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void customCommandCallback(SMTP_Response res) +{ + + // The res.id is the command identifier number that use to identify the source of command. + + // The command identifier number can be set via the last parameter of customConnect and sendCustomCommand functions. + + // If command identifier number was not set in those functions, the res.id received will be auto increased and begins with 0 + + MailClient.printf("> C: Command ID %d\n", res.id); + MailClient.printf("< S: %s\n", res.text.c_str()); + + if (res.statusCode > 0) + { + MailClient.printf("> C: Response finished with status code %d\n\n", res.statusCode); + } +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /* Connect to the server */ + if (smtp.customConnect(&config /* session credentials */, customCommandCallback) != 220) + { + Serial.println("! E: Unable to connect to server"); + return; + } + + if (smtp.sendCustomCommand(F("EHLO 127.0.0.1"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(F("AUTH LOGIN"), customCommandCallback) != 334) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(MailClient.toBase64(config.login.email), customCommandCallback) != 334) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(MailClient.toBase64(config.login.password), customCommandCallback) != 235) + { + smtp.closeSession(); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("Successfully logged in.\n"); + else + Serial.println("Connected with no Auth.\n"); + + // Please don't forget to change sender@xxxxxx.com to your email + if (smtp.sendCustomCommand(F("MAIL FROM:"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + // Please don't forget to change recipient@xxxxx.com with your recipient email + if (smtp.sendCustomCommand(F("RCPT TO:"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(F("DATA"), customCommandCallback) != 354) + { + smtp.closeSession(); + return; + } + + if (!smtp.sendCustomData(F("Subject: Test sending Email\r\n"))) + { + smtp.closeSession(); + return; + } + + if (!smtp.sendCustomData(F("Hello World!\r\n"))) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(F("."), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + // Do not use this command in ESP8266 due to memory leaks in ESP8266 core BearSSL. + // smtp.sendCustomCommand(F("QUIT"), customCommandCallback); + + smtp.closeSession(); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/STARTTLS/STARTTLS.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/STARTTLS/STARTTLS.ino index 64788c799..0d770d595 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/STARTTLS/STARTTLS.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Command/STARTTLS/STARTTLS.ino @@ -1,268 +1,268 @@ - - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example showes how to send Email using custom commands. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 // port 465 is not available for Outlook.com - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 // for STARTTLS - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" - "-----END CERTIFICATE-----\n"; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void customCommandCallback(SMTP_Response res) -{ - - // The res.id is the command identifier number that use to identify the source of command. - - // The command identifier number can be set via the last parameter of customConnect and sendCustomCommand functions. - - // If command identifier number was not set in those functions, the res.id received will be auto increased and begins with 0 - - MailClient.printf("> C: Command ID %d\n", res.id); - MailClient.printf("< S: %s\n", res.text.c_str()); - - if (res.statusCode > 0) - { - MailClient.printf("> C: Response finished with status code %d\n\n", res.statusCode); - } -} - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - bool tls = false; - - /* Connect to the server */ - if (smtp.customConnect(&config /* session credentials */, customCommandCallback) != 220) - { - Serial.println("! E: Unable to connect to server"); - return; - } - -init: - - if (smtp.sendCustomCommand(F("EHLO 127.0.0.1"), customCommandCallback) != 250) - { - smtp.closeSession(); - return; - } - - // Only for SMTP port 587 in supported server that accepts STARTTLS - - if (!tls) - { - if (smtp.sendCustomCommand(F("STARTTLS"), customCommandCallback) != 220) - { - smtp.closeSession(); - return; - } - - tls = true; - - // Send greeting again - goto init; - } - - if (smtp.sendCustomCommand(F("AUTH LOGIN"), customCommandCallback) != 334) - { - smtp.closeSession(); - return; - } - - if (smtp.sendCustomCommand(MailClient.toBase64(config.login.email), customCommandCallback) != 334) - { - smtp.closeSession(); - return; - } - - if (smtp.sendCustomCommand(MailClient.toBase64(config.login.password), customCommandCallback) != 235) - { - smtp.closeSession(); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("Successfully logged in.\n"); - else - Serial.println("Connected with no Auth.\n"); - - // Please don't forget to change sender@xxxxxx.com to your email - if (smtp.sendCustomCommand(F("MAIL FROM:"), customCommandCallback) != 250) - { - smtp.closeSession(); - return; - } - - // Please don't forget to change recipient@xxxxx.com with your recipient email - if (smtp.sendCustomCommand(F("RCPT TO:"), customCommandCallback) != 250) - { - smtp.closeSession(); - return; - } - - if (smtp.sendCustomCommand(F("DATA"), customCommandCallback) != 354) - { - smtp.closeSession(); - return; - } - - if (!smtp.sendCustomData(F("Subject: Test sending Email\r\n"))) - { - smtp.closeSession(); - return; - } - - if (!smtp.sendCustomData(F("Hello World!\r\n"))) - { - smtp.closeSession(); - return; - } - - if (smtp.sendCustomCommand(F("."), customCommandCallback) != 250) - { - smtp.closeSession(); - return; - } - - // Do not use this command in ESP8266 due to memory leaks in ESP8266 core BearSSL. - // smtp.sendCustomCommand(F("QUIT"), customCommandCallback); - - smtp.closeSession(); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} + + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example showes how to send Email using custom commands. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 // port 465 is not available for Outlook.com + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 // for STARTTLS + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" + "-----END CERTIFICATE-----\n"; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void customCommandCallback(SMTP_Response res) +{ + + // The res.id is the command identifier number that use to identify the source of command. + + // The command identifier number can be set via the last parameter of customConnect and sendCustomCommand functions. + + // If command identifier number was not set in those functions, the res.id received will be auto increased and begins with 0 + + MailClient.printf("> C: Command ID %d\n", res.id); + MailClient.printf("< S: %s\n", res.text.c_str()); + + if (res.statusCode > 0) + { + MailClient.printf("> C: Response finished with status code %d\n\n", res.statusCode); + } +} + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + bool tls = false; + + /* Connect to the server */ + if (smtp.customConnect(&config /* session credentials */, customCommandCallback) != 220) + { + Serial.println("! E: Unable to connect to server"); + return; + } + +init: + + if (smtp.sendCustomCommand(F("EHLO 127.0.0.1"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + // Only for SMTP port 587 in supported server that accepts STARTTLS + + if (!tls) + { + if (smtp.sendCustomCommand(F("STARTTLS"), customCommandCallback) != 220) + { + smtp.closeSession(); + return; + } + + tls = true; + + // Send greeting again + goto init; + } + + if (smtp.sendCustomCommand(F("AUTH LOGIN"), customCommandCallback) != 334) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(MailClient.toBase64(config.login.email), customCommandCallback) != 334) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(MailClient.toBase64(config.login.password), customCommandCallback) != 235) + { + smtp.closeSession(); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("Successfully logged in.\n"); + else + Serial.println("Connected with no Auth.\n"); + + // Please don't forget to change sender@xxxxxx.com to your email + if (smtp.sendCustomCommand(F("MAIL FROM:"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + // Please don't forget to change recipient@xxxxx.com with your recipient email + if (smtp.sendCustomCommand(F("RCPT TO:"), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(F("DATA"), customCommandCallback) != 354) + { + smtp.closeSession(); + return; + } + + if (!smtp.sendCustomData(F("Subject: Test sending Email\r\n"))) + { + smtp.closeSession(); + return; + } + + if (!smtp.sendCustomData(F("Hello World!\r\n"))) + { + smtp.closeSession(); + return; + } + + if (smtp.sendCustomCommand(F("."), customCommandCallback) != 250) + { + smtp.closeSession(); + return; + } + + // Do not use this command in ESP8266 due to memory leaks in ESP8266 core BearSSL. + // smtp.sendCustomCommand(F("QUIT"), customCommandCallback); + + smtp.closeSession(); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Ports/Custom_Ports.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Ports/Custom_Ports.ino index 95b1b0330..6cca11865 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Ports/Custom_Ports.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Custom_Ports/Custom_Ports.ino @@ -1,376 +1,376 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example showes how to send text Email via the custom port. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT 2525 // non-standard port (TLS) - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" - "-----END CERTIFICATE-----\n"; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /** Set the ports and protocols - * This allows non-standard port to work with this library - * The port that assigned with config.server.port will map with the - * protocol assigned here - */ - - config.ports_functions.list = new port_function[4]; - config.ports_functions.size = 4; - - config.ports_functions.list[0].port = 25; - config.ports_functions.list[0].protocol = esp_mail_protocol_plain_text; - - config.ports_functions.list[1].port = 465; - config.ports_functions.list[1].protocol = esp_mail_protocol_ssl; - - config.ports_functions.list[2].port = 587; - config.ports_functions.list[2].protocol = esp_mail_protocol_tls; - - config.ports_functions.list[3].port = 2525; - config.ports_functions.list[3].protocol = esp_mail_protocol_tls; - - /** In ESP32, timezone environment will not keep after wake up boot from sleep. - * The local time will equal to GMT time. - * - * To sync or set time with NTP server with the valid local time after wake up boot, - * set both gmt and day light offsets to 0 and assign the timezone environment string e.g. - - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 0; - config.time.day_light_offset = 0; - config.time.timezone_env_string = "JST-9"; // for Tokyo - - * The library will get (sync) the time from NTP server without GMT time offset adjustment - * and set the timezone environment variable later. - * - * This timezone environment string will be stored to flash or SD file named "/tz_env.txt" - * which set via config.time.timezone_file. - * - * See the timezone environment string list from - * https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv - * - */ - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); // This witll be used with 'MAIL FROM' command and 'From' header field. - message.sender.email = AUTHOR_EMAIL; // This witll be used with 'From' header field. - message.subject = F("Test sending plain text Email"); - message.addRecipient(F("Someone"), RECIPIENT_EMAIL); // This will be used with RCPT TO command and 'To' header field. - - String textMsg = "This is simple plain text message"; - message.text.content = textMsg; - - /** If the message to send is a large string, to reduce the memory used from internal copying while sending, - * you can assign string to message.text.blob by cast your string to uint8_t array like this - * - * String myBigString = "..... ......"; - * message.text.blob.data = (uint8_t *)myBigString.c_str(); - * message.text.blob.size = myBigString.length(); - * - * or assign string to message.text.nonCopyContent, like this - * - * message.text.nonCopyContent = myBigString.c_str(); - * - * Only base64 encoding is supported for content transfer encoding in this case. - */ - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.text.charSet = F("us-ascii"); - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - // If this is a reply message - // message.in_reply_to = ""; - // message.references = " "; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - // message.response.reply_to = "someone@somemail.com"; - // message.response.return_path = "someone@somemail.com"; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader(F("Message-ID: ")); - - // For Root CA certificate verification (ESP8266 and ESP32 only) - // config.certificate.cert_data = rootCACert; - // or - // config.certificate.cert_file = "/path/to/der/file"; - // config.certificate.cert_file_storage_type = esp_mail_file_storage_type_flash; // esp_mail_file_storage_type_sd - // config.certificate.verify = true; - - // The WiFiNINA firmware the Root CA certification can be added via the option in Firmware update tool in Arduino IDE - - /* Connect to server with the session config */ - - // Library will be trying to sync the time with NTP server if time is never sync or set. - // This is 10 seconds blocking process. - // If time reading was timed out, the error "NTP server time reading timed out" will show via debug and callback function. - // You can manually sync time by yourself with NTP library or calling configTime in ESP32 and ESP8266. - // Time can be set manually with provided timestamp to function smtp.setSystemTime. - - /* Connect to the server */ - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } -} + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example showes how to send text Email via the custom port. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT 2525 // non-standard port (TLS) + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" + "-----END CERTIFICATE-----\n"; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /** Set the ports and protocols + * This allows non-standard port to work with this library + * The port that assigned with config.server.port will map with the + * protocol assigned here + */ + + config.ports_functions.list = new port_function[4]; + config.ports_functions.size = 4; + + config.ports_functions.list[0].port = 25; + config.ports_functions.list[0].protocol = esp_mail_protocol_plain_text; + + config.ports_functions.list[1].port = 465; + config.ports_functions.list[1].protocol = esp_mail_protocol_ssl; + + config.ports_functions.list[2].port = 587; + config.ports_functions.list[2].protocol = esp_mail_protocol_tls; + + config.ports_functions.list[3].port = 2525; + config.ports_functions.list[3].protocol = esp_mail_protocol_tls; + + /** In ESP32, timezone environment will not keep after wake up boot from sleep. + * The local time will equal to GMT time. + * + * To sync or set time with NTP server with the valid local time after wake up boot, + * set both gmt and day light offsets to 0 and assign the timezone environment string e.g. + + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 0; + config.time.day_light_offset = 0; + config.time.timezone_env_string = "JST-9"; // for Tokyo + + * The library will get (sync) the time from NTP server without GMT time offset adjustment + * and set the timezone environment variable later. + * + * This timezone environment string will be stored to flash or SD file named "/tz_env.txt" + * which set via config.time.timezone_file. + * + * See the timezone environment string list from + * https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv + * + */ + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); // This witll be used with 'MAIL FROM' command and 'From' header field. + message.sender.email = AUTHOR_EMAIL; // This witll be used with 'From' header field. + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); // This will be used with RCPT TO command and 'To' header field. + + String textMsg = "This is simple plain text message"; + message.text.content = textMsg; + + /** If the message to send is a large string, to reduce the memory used from internal copying while sending, + * you can assign string to message.text.blob by cast your string to uint8_t array like this + * + * String myBigString = "..... ......"; + * message.text.blob.data = (uint8_t *)myBigString.c_str(); + * message.text.blob.size = myBigString.length(); + * + * or assign string to message.text.nonCopyContent, like this + * + * message.text.nonCopyContent = myBigString.c_str(); + * + * Only base64 encoding is supported for content transfer encoding in this case. + */ + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + // If this is a reply message + // message.in_reply_to = ""; + // message.references = " "; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + // message.response.reply_to = "someone@somemail.com"; + // message.response.return_path = "someone@somemail.com"; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + // For Root CA certificate verification (ESP8266 and ESP32 only) + // config.certificate.cert_data = rootCACert; + // or + // config.certificate.cert_file = "/path/to/der/file"; + // config.certificate.cert_file_storage_type = esp_mail_file_storage_type_flash; // esp_mail_file_storage_type_sd + // config.certificate.verify = true; + + // The WiFiNINA firmware the Root CA certification can be added via the option in Firmware update tool in Arduino IDE + + /* Connect to server with the session config */ + + // Library will be trying to sync the time with NTP server if time is never sync or set. + // This is 10 seconds blocking process. + // If time reading was timed out, the error "NTP server time reading timed out" will show via debug and callback function. + // You can manually sync time by yourself with NTP library or calling configTime in ESP32 and ESP8266. + // Time can be set manually with provided timestamp to function smtp.setSystemTime. + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP32/Send_Text/Send_Text.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP32/Send_Text/Send_Text.ino index 60a05519e..d357179d9 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP32/Send_Text/Send_Text.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP32/Send_Text/Send_Text.ino @@ -1,287 +1,287 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to send Email using ESP32 and LAN8720 Ethernet module. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** - * There are many sources for LAN8720 and ESP32 interconnection on the internet which may - * work for your LAN8720 board. - * - * Some methods worked unless no IP is available. - * - * This modification and interconnection provided in this example are mostly worked as - * the 50 MHz clock was created internally in ESP32 which GPIO 17 is set to be output of this clock - * and feeds to the LAN8720 chip XTAL input. - * - * The on-board LAN8720 50 MHz XTAL chip will be disabled by connect its enable pin or pin 1 to GND. - * - * Please see the images in the folder "modified_LAN8720_board_images" for how to modify the LAN8720 board. - * - * The LAN8720 Ethernet modified board and ESP32 board wiring connection. - * - * ESP32 LAN8720 - * - * GPIO17 - EMAC_CLK_OUT_180 nINT/REFCLK - LAN8720 XTAL1/CLKIN 4k7 Pulldown - * GPIO22 - EMAC_TXD1 TX1 - * GPIO19 - EMAC_TXD0 TX0 - * GPIO21 - EMAC_TX_EN TX_EN - * GPIO26 - EMAC_RXD1 RX1 - * GPIO25 - EMAC_RXD0 RX0 - * GPIO27 - EMAC_RX_DV CRS - * GPIO23 - MDC MDC - * GPIO18 - MDIO MDIO - * GND GND - * 3V3 VCC - * - * - * ESP32 Arduino SDK native Ethernet using ETH.h is currently support Ethernet PHY chips - * - * LAN8720, TLK101, RTL8201, DP83848, DM9051, KSZ8041 and KSZ8081. - * - * For ESP32 and other SPI MAC Ethernet modules, the external Client was used, - * see examples/SMTP/External_Client/EthernetClient/EthernetClient.ino - * - */ - -#include - -#ifdef ETH_CLK_MODE -#undef ETH_CLK_MODE -#endif -#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT // RMII clock output from GPIO17 - -// Pin# of the enable signal for the external crystal oscillator (-1 to disable) -#define ETH_POWER_PIN -1 - -// Type of the Ethernet PHY (LAN8720 or TLK110) -#define ETH_TYPE ETH_PHY_LAN8720 - -// I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110) -#define ETH_ADDR 1 - -// Pin# of the I²C clock signal for the Ethernet PHY -#define ETH_MDC_PIN 23 - -// Pin# of the I²C IO signal for the Ethernet PHY -#define ETH_MDIO_PIN 18 - -static bool eth_connected = false; - -#define SMTP_HOST "" -#define SMTP_PORT 25 - -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" -#define RECIPIENT_EMAIL "" - -SMTPSession smtp; - -void smtpCallback(SMTP_Status status); - -unsigned long sendMillis = 0; - -void WiFiEvent(WiFiEvent_t event) -{ - // Do not run any function here to prevent stack overflow or nested interrupt - -#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) - - switch (event) - { - case ARDUINO_EVENT_ETH_START: - Serial.println("ETH Started"); - // set eth hostname here - ETH.setHostname("esp32-ethernet"); - break; - case ARDUINO_EVENT_ETH_CONNECTED: - Serial.println("ETH Connected"); - break; - case ARDUINO_EVENT_ETH_GOT_IP: - Serial.print("ETH MAC: "); - Serial.print(ETH.macAddress()); - Serial.print(", IPv4: "); - Serial.print(ETH.localIP()); - if (ETH.fullDuplex()) - { - Serial.print(", FULL_DUPLEX"); - } - Serial.print(", "); - Serial.print(ETH.linkSpeed()); - Serial.println("Mbps"); - eth_connected = true; - break; - case ARDUINO_EVENT_ETH_DISCONNECTED: - Serial.println("ETH Disconnected"); - eth_connected = false; - break; - case ARDUINO_EVENT_ETH_STOP: - Serial.println("ETH Stopped"); - eth_connected = false; - break; - default: - break; - } - -#else - switch (event) - { - case SYSTEM_EVENT_ETH_START: - Serial.println("ETH Started"); - // set eth hostname here - ETH.setHostname("esp32-ethernet"); - break; - case SYSTEM_EVENT_ETH_CONNECTED: - Serial.println("ETH Connected"); - break; - case SYSTEM_EVENT_ETH_GOT_IP: - Serial.print("ETH MAC: "); - Serial.print(ETH.macAddress()); - Serial.print(", IPv4: "); - Serial.print(ETH.localIP()); - if (ETH.fullDuplex()) - { - Serial.print(", FULL_DUPLEX"); - } - Serial.print(", "); - Serial.print(ETH.linkSpeed()); - Serial.println("Mbps"); - eth_connected = true; - break; - case SYSTEM_EVENT_ETH_DISCONNECTED: - Serial.println("ETH Disconnected"); - eth_connected = false; - break; - case SYSTEM_EVENT_ETH_STOP: - Serial.println("ETH Stopped"); - eth_connected = false; - break; - default: - break; - } -#endif -} - -void sendMail() -{ - - smtp.debug(1); - - smtp.callback(smtpCallback); - - Session_Config config; - - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - SMTP_Message message; - - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - message.subject = F("Test sending plain text Email"); - message.addRecipient(F("Someone"), RECIPIENT_EMAIL); - - String textMsg = "This is simple plain text message"; - message.text.content = textMsg; - - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - if (!MailClient.sendMail(&smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); -} - -void setup() -{ - Serial.begin(115200); - Serial.println(); - - WiFi.onEvent(WiFiEvent); - - ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE); -} - -void loop() -{ - if (eth_connected && (millis() - sendMillis > 300000 || sendMillis == 0)) - { - sendMillis = millis(); - sendMail(); - } -} - -void smtpCallback(SMTP_Status status) -{ - Serial.println(status.info()); - - if (status.success()) - { - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - - SMTP_Result result = smtp.sendingResult.getItem(i); - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - smtp.sendingResult.clear(); - } -} + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email using ESP32 and LAN8720 Ethernet module. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** + * There are many sources for LAN8720 and ESP32 interconnection on the internet which may + * work for your LAN8720 board. + * + * Some methods worked unless no IP is available. + * + * This modification and interconnection provided in this example are mostly worked as + * the 50 MHz clock was created internally in ESP32 which GPIO 17 is set to be output of this clock + * and feeds to the LAN8720 chip XTAL input. + * + * The on-board LAN8720 50 MHz XTAL chip will be disabled by connect its enable pin or pin 1 to GND. + * + * Please see the images in the folder "modified_LAN8720_board_images" for how to modify the LAN8720 board. + * + * The LAN8720 Ethernet modified board and ESP32 board wiring connection. + * + * ESP32 LAN8720 + * + * GPIO17 - EMAC_CLK_OUT_180 nINT/REFCLK - LAN8720 XTAL1/CLKIN 4k7 Pulldown + * GPIO22 - EMAC_TXD1 TX1 + * GPIO19 - EMAC_TXD0 TX0 + * GPIO21 - EMAC_TX_EN TX_EN + * GPIO26 - EMAC_RXD1 RX1 + * GPIO25 - EMAC_RXD0 RX0 + * GPIO27 - EMAC_RX_DV CRS + * GPIO23 - MDC MDC + * GPIO18 - MDIO MDIO + * GND GND + * 3V3 VCC + * + * + * ESP32 Arduino SDK native Ethernet using ETH.h is currently support Ethernet PHY chips + * + * LAN8720, TLK101, RTL8201, DP83848, DM9051, KSZ8041 and KSZ8081. + * + * For ESP32 and other SPI MAC Ethernet modules, the external Client was used, + * see examples/SMTP/External_Client/EthernetClient/EthernetClient.ino + * + */ + +#include + +#ifdef ETH_CLK_MODE +#undef ETH_CLK_MODE +#endif +#define ETH_CLK_MODE ETH_CLOCK_GPIO17_OUT // RMII clock output from GPIO17 + +// Pin# of the enable signal for the external crystal oscillator (-1 to disable) +#define ETH_POWER_PIN -1 + +// Type of the Ethernet PHY (LAN8720 or TLK110) +#define ETH_TYPE ETH_PHY_LAN8720 + +// I²C-address of Ethernet PHY (0 or 1 for LAN8720, 31 for TLK110) +#define ETH_ADDR 1 + +// Pin# of the I²C clock signal for the Ethernet PHY +#define ETH_MDC_PIN 23 + +// Pin# of the I²C IO signal for the Ethernet PHY +#define ETH_MDIO_PIN 18 + +static bool eth_connected = false; + +#define SMTP_HOST "" +#define SMTP_PORT 25 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" +#define RECIPIENT_EMAIL "" + +SMTPSession smtp; + +void smtpCallback(SMTP_Status status); + +unsigned long sendMillis = 0; + +void WiFiEvent(WiFiEvent_t event) +{ + // Do not run any function here to prevent stack overflow or nested interrupt + +#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(4, 4, 0) + + switch (event) + { + case ARDUINO_EVENT_ETH_START: + Serial.println("ETH Started"); + // set eth hostname here + ETH.setHostname("esp32-ethernet"); + break; + case ARDUINO_EVENT_ETH_CONNECTED: + Serial.println("ETH Connected"); + break; + case ARDUINO_EVENT_ETH_GOT_IP: + Serial.print("ETH MAC: "); + Serial.print(ETH.macAddress()); + Serial.print(", IPv4: "); + Serial.print(ETH.localIP()); + if (ETH.fullDuplex()) + { + Serial.print(", FULL_DUPLEX"); + } + Serial.print(", "); + Serial.print(ETH.linkSpeed()); + Serial.println("Mbps"); + eth_connected = true; + break; + case ARDUINO_EVENT_ETH_DISCONNECTED: + Serial.println("ETH Disconnected"); + eth_connected = false; + break; + case ARDUINO_EVENT_ETH_STOP: + Serial.println("ETH Stopped"); + eth_connected = false; + break; + default: + break; + } + +#else + switch (event) + { + case SYSTEM_EVENT_ETH_START: + Serial.println("ETH Started"); + // set eth hostname here + ETH.setHostname("esp32-ethernet"); + break; + case SYSTEM_EVENT_ETH_CONNECTED: + Serial.println("ETH Connected"); + break; + case SYSTEM_EVENT_ETH_GOT_IP: + Serial.print("ETH MAC: "); + Serial.print(ETH.macAddress()); + Serial.print(", IPv4: "); + Serial.print(ETH.localIP()); + if (ETH.fullDuplex()) + { + Serial.print(", FULL_DUPLEX"); + } + Serial.print(", "); + Serial.print(ETH.linkSpeed()); + Serial.println("Mbps"); + eth_connected = true; + break; + case SYSTEM_EVENT_ETH_DISCONNECTED: + Serial.println("ETH Disconnected"); + eth_connected = false; + break; + case SYSTEM_EVENT_ETH_STOP: + Serial.println("ETH Stopped"); + eth_connected = false; + break; + default: + break; + } +#endif +} + +void sendMail() +{ + + smtp.debug(1); + + smtp.callback(smtpCallback); + + Session_Config config; + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + SMTP_Message message; + + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + String textMsg = "This is simple plain text message"; + message.text.content = textMsg; + + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); +} + +void setup() +{ + Serial.begin(115200); + Serial.println(); + + WiFi.onEvent(WiFiEvent); + + ETH.begin(ETH_ADDR, ETH_POWER_PIN, ETH_MDC_PIN, ETH_MDIO_PIN, ETH_TYPE, ETH_CLK_MODE); +} + +void loop() +{ + if (eth_connected && (millis() - sendMillis > 300000 || sendMillis == 0)) + { + sendMillis = millis(); + sendMail(); + } +} + +void smtpCallback(SMTP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP8266/Send_Text/Send_Text.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP8266/Send_Text/Send_Text.ino index 4f677fa88..b6893d436 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP8266/Send_Text/Send_Text.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Ethernet/ESP8266/Send_Text/Send_Text.ino @@ -1,230 +1,230 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to send Email using ESP8266 and ENC28J60 Ethernet module. - -// This example requires ESP8266 Arduino Core SDK v3.x.x - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** - * - * The ENC28J60 Ethernet module and ESP8266 board, SPI port wiring connection. - * - * ESP8266 (Wemos D1 Mini or NodeMCU) ENC28J60 - * - * GPIO12 (D6) - MISO SO - * GPIO13 (D7) - MOSI SI - * GPIO14 (D5) - SCK SCK - * GPIO16 (D0) - CS CS - * GND GND - * 3V3 VCC - * - */ - -#if defined(ESP8266) -#include -#endif - -#include -// #include -// #include - -/** - * For ENC28J60 ethernet module, uncomment this line in ESP_Mail_FS.h - #define ENABLE_ESP8266_ENC28J60_ETH - - * For W5500 ethernet module, uncomment this line in ESP_Mail_FS.h - #define ENABLE_ESP8266_W5500_ETH - - * For W5100 ethernet module, uncomment this line in ESP_Mail_FS.h - #define ENABLE_ESP8266_W5100_ETH -*/ - -#include - -#define SMTP_HOST "" -#define SMTP_PORT 25 - -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" -#define RECIPIENT_EMAIL "" - -SMTPSession smtp; - -void smtpCallback(SMTP_Status status); - -unsigned long sendMillis = 0; - -#ifdef ESP8266_CORE_SDK_V3_X_X - -#define ETH_CS_PIN 16 // D0 -ENC28J60lwIP eth(ETH_CS_PIN); -// Wiznet5100lwIP eth(ETH_CS_PIN); -// Wiznet5500lwIP eth(ETH_CS_PIN); - -#endif - -void sendMail() -{ - - smtp.debug(1); - - smtp.callback(smtpCallback); - - Session_Config config; - - /* Assign the pointer to Ethernet module lwip interface */ -#ifdef ESP8266_CORE_SDK_V3_X_X -#if defined(ENABLE_ESP8266_ENC28J60_ETH) - config.spi_ethernet_module.enc28j60 = ð -#elif defined(ENABLE_ESP8266_W5100_ETH) - config.spi_ethernet_module.w5100 = ð -#elif defined(ENABLE_ESP8266_W5500_ETH) - config.spi_ethernet_module.w5500 = ð -#endif -#endif - - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - SMTP_Message message; - - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - message.subject = F("Test sending plain text Email"); - message.addRecipient(F("Someone"), RECIPIENT_EMAIL); - - String textMsg = "This is simple plain text message"; - message.text.content = textMsg; - - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - if (!MailClient.sendMail(&smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); -} - -void setup() -{ - Serial.begin(115200); - Serial.println(); - -#ifdef ESP8266_CORE_SDK_V3_X_X - - SPI.begin(); - SPI.setClockDivider(SPI_CLOCK_DIV4); // 4 MHz? - SPI.setBitOrder(MSBFIRST); - SPI.setDataMode(SPI_MODE0); - eth.setDefault(); // use ethernet for default route - if (!eth.begin()) - { - Serial.println("ethernet hardware not found ... sleeping"); - while (1) - { - delay(1000); - } - } - else - { - Serial.print("connecting ethernet"); - while (!eth.connected()) - { - Serial.print("."); - delay(1000); - } - } - Serial.println(); - Serial.print("ethernet IP address: "); - Serial.println(eth.localIP()); - -#else - Serial.println("This example requires ESP8266 Arduino Core SDK v3.x.x, please update."); -#endif -} - -void loop() -{ -#ifdef ESP8266_CORE_SDK_V3_X_X - if (millis() - sendMillis > 300000 || sendMillis == 0) - { - sendMillis = millis(); - sendMail(); - } -#endif -} - -void smtpCallback(SMTP_Status status) -{ - Serial.println(status.info()); - - if (status.success()) - { - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - - SMTP_Result result = smtp.sendingResult.getItem(i); - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - smtp.sendingResult.clear(); - } + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email using ESP8266 and ENC28J60 Ethernet module. + +// This example requires ESP8266 Arduino Core SDK v3.x.x + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** + * + * The ENC28J60 Ethernet module and ESP8266 board, SPI port wiring connection. + * + * ESP8266 (Wemos D1 Mini or NodeMCU) ENC28J60 + * + * GPIO12 (D6) - MISO SO + * GPIO13 (D7) - MOSI SI + * GPIO14 (D5) - SCK SCK + * GPIO16 (D0) - CS CS + * GND GND + * 3V3 VCC + * + */ + +#if defined(ESP8266) +#include +#endif + +#include +// #include +// #include + +/** + * For ENC28J60 ethernet module, uncomment this line in ESP_Mail_FS.h + #define ENABLE_ESP8266_ENC28J60_ETH + + * For W5500 ethernet module, uncomment this line in ESP_Mail_FS.h + #define ENABLE_ESP8266_W5500_ETH + + * For W5100 ethernet module, uncomment this line in ESP_Mail_FS.h + #define ENABLE_ESP8266_W5100_ETH +*/ + +#include + +#define SMTP_HOST "" +#define SMTP_PORT 25 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" +#define RECIPIENT_EMAIL "" + +SMTPSession smtp; + +void smtpCallback(SMTP_Status status); + +unsigned long sendMillis = 0; + +#ifdef ESP8266_CORE_SDK_V3_X_X + +#define ETH_CS_PIN 16 // D0 +ENC28J60lwIP eth(ETH_CS_PIN); +// Wiznet5100lwIP eth(ETH_CS_PIN); +// Wiznet5500lwIP eth(ETH_CS_PIN); + +#endif + +void sendMail() +{ + + smtp.debug(1); + + smtp.callback(smtpCallback); + + Session_Config config; + + /* Assign the pointer to Ethernet module lwip interface */ +#ifdef ESP8266_CORE_SDK_V3_X_X +#if defined(ENABLE_ESP8266_ENC28J60_ETH) + config.spi_ethernet_module.enc28j60 = ð +#elif defined(ENABLE_ESP8266_W5100_ETH) + config.spi_ethernet_module.w5100 = ð +#elif defined(ENABLE_ESP8266_W5500_ETH) + config.spi_ethernet_module.w5500 = ð +#endif +#endif + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + SMTP_Message message; + + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + String textMsg = "This is simple plain text message"; + message.text.content = textMsg; + + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); +} + +void setup() +{ + Serial.begin(115200); + Serial.println(); + +#ifdef ESP8266_CORE_SDK_V3_X_X + + SPI.begin(); + SPI.setClockDivider(SPI_CLOCK_DIV4); // 4 MHz? + SPI.setBitOrder(MSBFIRST); + SPI.setDataMode(SPI_MODE0); + eth.setDefault(); // use ethernet for default route + if (!eth.begin()) + { + Serial.println("ethernet hardware not found ... sleeping"); + while (1) + { + delay(1000); + } + } + else + { + Serial.print("connecting ethernet"); + while (!eth.connected()) + { + Serial.print("."); + delay(1000); + } + } + Serial.println(); + Serial.print("ethernet IP address: "); + Serial.println(eth.localIP()); + +#else + Serial.println("This example requires ESP8266 Arduino Core SDK v3.x.x, please update."); +#endif +} + +void loop() +{ +#ifdef ESP8266_CORE_SDK_V3_X_X + if (millis() - sendMillis > 300000 || sendMillis == 0) + { + sendMillis = millis(); + sendMail(); + } +#endif +} + +void smtpCallback(SMTP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + smtp.sendingResult.clear(); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/EthernetClient/EthernetClient.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/EthernetClient/EthernetClient.ino index ec9fd07ef..48e953659 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/EthernetClient/EthernetClient.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/EthernetClient/EthernetClient.ino @@ -1,224 +1,224 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -/** - * This example shows how to send Email using EthernetClient. - * - * This example used ESP32 and WIZnet W5500 Ethernet module. - * - * For ESP32 and LAN8720 see examples/SMTP/Ethernet/ESP32/Send_Text.ino - * - * ESP32 Arduino SDK native Ethernet using ETH.h is currently support Ethernet PHY chips - * - * LAN8720, TLK101, RTL8201, DP83848, DM9051, KSZ8041 and KSZ8081. - * - * For ESP8266, the native Ethernet is currently supported ENC28J60, W5100 and W5500. - * - * You do not need to set external Client with native Ethernet support PHY/MAC chips. - * - * - */ - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include - -#include - -#include - -#define SMTP_HOST "smtp.gmail.com" -#define SMTP_PORT 587 - -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" -#define RECIPIENT_EMAIL "" - -#define WIZNET_RESET_PIN 26 // Connect W5500 Reset pin to GPIO 26 of ESP32 -#define WIZNET_CS_PIN 5 // Connect W5500 CS pin to GPIO 5 of ESP32 -#define WIZNET_MISO_PIN 19 // Connect W5500 MISO pin to GPIO 19 of ESP32 -#define WIZNET_MOSI_PIN 23 // Connect W5500 MOSI pin to GPIO 23 of ESP32 -#define WIZNET_SCLK_PIN 18 // Connect W5500 SCLK pin to GPIO 18 of ESP32 - -unsigned long sentMillis = 0; - -const int analog_pin = 34; - -uint8_t Eth_MAC[] = {0x02, 0xF0, 0x0D, 0xBE, 0xEF, 0x01}; - -SMTPSession smtp; - -EthernetClient eth_client; - -void smtpCallback(SMTP_Status status); - -void ResetEthernet() -{ - Serial.println("Resetting WIZnet W5500 Ethernet Board... "); - pinMode(WIZNET_RESET_PIN, OUTPUT); - digitalWrite(WIZNET_RESET_PIN, HIGH); - delay(200); - digitalWrite(WIZNET_RESET_PIN, LOW); - delay(50); - digitalWrite(WIZNET_RESET_PIN, HIGH); - delay(200); -} - -void networkConnection() -{ - - Ethernet.init(WIZNET_CS_PIN); - - ResetEthernet(); - - Serial.println("Starting Ethernet connection..."); - Ethernet.begin(Eth_MAC); - - unsigned long to = millis(); - - while (Ethernet.linkStatus() == LinkOFF || millis() - to < 2000) - { - delay(100); - } - - if (Ethernet.linkStatus() == LinkON) - { - Serial.print("Connected with IP "); - Serial.println(Ethernet.localIP()); - } - else - { - Serial.println("Can't connect"); - } -} - -void networkStatusRequestCallback() -{ - smtp.setNetworkStatus(Ethernet.linkStatus() == LinkON); -} - -void sendEmail() -{ - - Session_Config config; - - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - config.login.user_domain = F("127.0.0.1"); - - SMTP_Message message; - - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - message.subject = F("Test sending plain text Email"); - - message.addRecipient(F("Someone"), RECIPIENT_EMAIL); - - message.text.content = "This is simple plain text message"; - - smtp.setClient(ð_client); - - smtp.networkConnectionRequestCallback(networkConnection); - - smtp.networkStatusRequestCallback(networkStatusRequestCallback); - - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - if (!MailClient.sendMail(&smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void setup() -{ - - Serial.begin(115200); - - Serial.println(); - - networkConnection(); - - /* - For internal NTP client - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - MailClient.setUDPClient(&udp_client, 0 /* GMT offset */); - - smtp.debug(1); - - smtp.callback(smtpCallback); -} - -void loop() -{ - if (millis() - sentMillis > 120000 || sentMillis == 0) - { - sentMillis = millis(); - sendEmail(); - } -} - -void smtpCallback(SMTP_Status status) -{ - Serial.println(status.info()); - - if (status.success()) - { - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - SMTP_Result result = smtp.sendingResult.getItem(i); - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - smtp.sendingResult.clear(); - } +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +/** + * This example shows how to send Email using EthernetClient. + * + * This example used ESP32 and WIZnet W5500 Ethernet module. + * + * For ESP32 and LAN8720 see examples/SMTP/Ethernet/ESP32/Send_Text.ino + * + * ESP32 Arduino SDK native Ethernet using ETH.h is currently support Ethernet PHY chips + * + * LAN8720, TLK101, RTL8201, DP83848, DM9051, KSZ8041 and KSZ8081. + * + * For ESP8266, the native Ethernet is currently supported ENC28J60, W5100 and W5500. + * + * You do not need to set external Client with native Ethernet support PHY/MAC chips. + * + * + */ + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include + +#include + +#include + +#define SMTP_HOST "smtp.gmail.com" +#define SMTP_PORT 587 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" +#define RECIPIENT_EMAIL "" + +#define WIZNET_RESET_PIN 26 // Connect W5500 Reset pin to GPIO 26 of ESP32 +#define WIZNET_CS_PIN 5 // Connect W5500 CS pin to GPIO 5 of ESP32 +#define WIZNET_MISO_PIN 19 // Connect W5500 MISO pin to GPIO 19 of ESP32 +#define WIZNET_MOSI_PIN 23 // Connect W5500 MOSI pin to GPIO 23 of ESP32 +#define WIZNET_SCLK_PIN 18 // Connect W5500 SCLK pin to GPIO 18 of ESP32 + +unsigned long sentMillis = 0; + +const int analog_pin = 34; + +uint8_t Eth_MAC[] = {0x02, 0xF0, 0x0D, 0xBE, 0xEF, 0x01}; + +SMTPSession smtp; + +EthernetClient eth_client; + +void smtpCallback(SMTP_Status status); + +void ResetEthernet() +{ + Serial.println("Resetting WIZnet W5500 Ethernet Board... "); + pinMode(WIZNET_RESET_PIN, OUTPUT); + digitalWrite(WIZNET_RESET_PIN, HIGH); + delay(200); + digitalWrite(WIZNET_RESET_PIN, LOW); + delay(50); + digitalWrite(WIZNET_RESET_PIN, HIGH); + delay(200); +} + +void networkConnection() +{ + + Ethernet.init(WIZNET_CS_PIN); + + ResetEthernet(); + + Serial.println("Starting Ethernet connection..."); + Ethernet.begin(Eth_MAC); + + unsigned long to = millis(); + + while (Ethernet.linkStatus() == LinkOFF || millis() - to < 2000) + { + delay(100); + } + + if (Ethernet.linkStatus() == LinkON) + { + Serial.print("Connected with IP "); + Serial.println(Ethernet.localIP()); + } + else + { + Serial.println("Can't connect"); + } +} + +void networkStatusRequestCallback() +{ + smtp.setNetworkStatus(Ethernet.linkStatus() == LinkON); +} + +void sendEmail() +{ + + Session_Config config; + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + config.login.user_domain = F("127.0.0.1"); + + SMTP_Message message; + + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email"); + + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + message.text.content = "This is simple plain text message"; + + smtp.setClient(ð_client); + + smtp.networkConnectionRequestCallback(networkConnection); + + smtp.networkStatusRequestCallback(networkStatusRequestCallback); + + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void setup() +{ + + Serial.begin(115200); + + Serial.println(); + + networkConnection(); + + /* + For internal NTP client + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + MailClient.setUDPClient(&udp_client, 0 /* GMT offset */); + + smtp.debug(1); + + smtp.callback(smtpCallback); +} + +void loop() +{ + if (millis() - sentMillis > 120000 || sentMillis == 0) + { + sentMillis = millis(); + sendEmail(); + } +} + +void smtpCallback(SMTP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + smtp.sendingResult.clear(); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/GSMClient/GSMClient.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/GSMClient/GSMClient.ino index 9d1026d4e..d386795e1 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/GSMClient/GSMClient.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/GSMClient/GSMClient.ino @@ -1,213 +1,213 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt - */ - -// This example used TTGO T-A7670 (ESP32 with SIMCom SIMA7670) and TinyGSMClient. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -// To allow TinyGSM library integration, the following macro should be defined in src/ESP_Mail_FS.h or -// your custom config file src/Custom_ESP_Mail_FS.h. -// #define TINY_GSM_MODEM_SIM7600 - -#define TINY_GSM_MODEM_SIM7600 // SIMA7670 Compatible with SIM7600 AT instructions - -// Set serial for debug console (to the Serial Monitor, default speed 115200) -#define SerialMon Serial - -// Set serial for AT commands (to the module) -// Use Hardware Serial on Mega, Leonardo, Micro -#define SerialAT Serial1 - -// See all AT commands, if wanted -// #define DUMP_AT_COMMANDS - -// Define the serial console for debug prints, if needed -#define TINY_GSM_DEBUG SerialMon - -#define TINY_GSM_USE_GPRS true -#define TINY_GSM_USE_WIFI false - -// set GSM PIN, if any -#define GSM_PIN "" - -// Your GPRS credentials, if any -const char apn[] = "YourAPN"; -const char gprsUser[] = ""; -const char gprsPass[] = ""; - -#define uS_TO_S_FACTOR 1000000ULL // Conversion factor for micro seconds to seconds -#define TIME_TO_SLEEP 600 // Time ESP32 will go to sleep (in seconds) - -#define UART_BAUD 115200 -#define PIN_DTR 25 -#define PIN_TX 26 -#define PIN_RX 27 -#define PWR_PIN 4 -#define BAT_ADC 35 -#define BAT_EN 12 -#define PIN_RI 33 -#define PIN_DTR 25 -#define RESET 5 - -#define SD_MISO 2 -#define SD_MOSI 15 -#define SD_SCLK 14 -#define SD_CS 13 - -#include -#include - -TinyGsm modem(SerialAT); - -TinyGsmClient gsm_client(modem); - -#define SMTP_HOST "" -#define SMTP_PORT esp_mail_smtp_port_587 -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" -#define RECIPIENT_EMAIL "" - -SMTPSession smtp; - -void smtpCallback(SMTP_Status status); - -void setup() -{ - - SerialMon.begin(115200); - - smtp.debug(1); - - smtp.callback(smtpCallback); - - delay(10); - pinMode(BAT_EN, OUTPUT); - digitalWrite(BAT_EN, HIGH); - - // A7670 Reset - pinMode(RESET, OUTPUT); - digitalWrite(RESET, LOW); - delay(100); - digitalWrite(RESET, HIGH); - delay(3000); - digitalWrite(RESET, LOW); - - pinMode(PWR_PIN, OUTPUT); - digitalWrite(PWR_PIN, LOW); - delay(100); - digitalWrite(PWR_PIN, HIGH); - delay(1000); - digitalWrite(PWR_PIN, LOW); - - DBG("Wait..."); - - delay(3000); - - SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX); - - // Restart takes quite some time - // To skip it, call init() instead of restart() - DBG("Initializing modem..."); - if (!modem.init()) - { - DBG("Failed to restart modem, delaying 10s and retrying"); - return; - } - - /* - 2 Automatic - 13 GSM Only - 14 WCDMA Only - 38 LTE Only - */ - modem.setNetworkMode(38); - if (modem.waitResponse(10000L) != 1) - { - DBG(" setNetworkMode faill"); - } - - String name = modem.getModemName(); - DBG("Modem Name:", name); - - String modemInfo = modem.getModemInfo(); - DBG("Modem Info:", modemInfo); - - Session_Config config; - - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - config.login.user_domain = F("127.0.0.1"); - - SMTP_Message message; - - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - message.subject = F("Test sending plain text Email using GSM module"); - message.addRecipient(F("Someone"), RECIPIENT_EMAIL); - - message.text.content = "This is simple plain text message"; - - smtp.setGSMClient(&gsm_client, &modem, GSM_PIN, apn, gprsUser, gprsPass); - - smtp.connect(&config); - - if (!MailClient.sendMail(&smtp, &message)) - Serial.println("Error sending Email, " + smtp.errorReason()); -} - -void loop() -{ -} - -void smtpCallback(SMTP_Status status) -{ - Serial.println(status.info()); - - if (status.success()) - { - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - SMTP_Result result = smtp.sendingResult.getItem(i); - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - smtp.sendingResult.clear(); - } + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +// This example used TTGO T-A7670 (ESP32 with SIMCom SIMA7670) and TinyGSMClient. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +// To allow TinyGSM library integration, the following macro should be defined in src/ESP_Mail_FS.h or +// your custom config file src/Custom_ESP_Mail_FS.h. +// #define TINY_GSM_MODEM_SIM7600 + +#define TINY_GSM_MODEM_SIM7600 // SIMA7670 Compatible with SIM7600 AT instructions + +// Set serial for debug console (to the Serial Monitor, default speed 115200) +#define SerialMon Serial + +// Set serial for AT commands (to the module) +// Use Hardware Serial on Mega, Leonardo, Micro +#define SerialAT Serial1 + +// See all AT commands, if wanted +// #define DUMP_AT_COMMANDS + +// Define the serial console for debug prints, if needed +#define TINY_GSM_DEBUG SerialMon + +#define TINY_GSM_USE_GPRS true +#define TINY_GSM_USE_WIFI false + +// set GSM PIN, if any +#define GSM_PIN "" + +// Your GPRS credentials, if any +const char apn[] = "YourAPN"; +const char gprsUser[] = ""; +const char gprsPass[] = ""; + +#define uS_TO_S_FACTOR 1000000ULL // Conversion factor for micro seconds to seconds +#define TIME_TO_SLEEP 600 // Time ESP32 will go to sleep (in seconds) + +#define UART_BAUD 115200 +#define PIN_DTR 25 +#define PIN_TX 26 +#define PIN_RX 27 +#define PWR_PIN 4 +#define BAT_ADC 35 +#define BAT_EN 12 +#define PIN_RI 33 +#define PIN_DTR 25 +#define RESET 5 + +#define SD_MISO 2 +#define SD_MOSI 15 +#define SD_SCLK 14 +#define SD_CS 13 + +#include +#include + +TinyGsm modem(SerialAT); + +TinyGsmClient gsm_client(modem); + +#define SMTP_HOST "" +#define SMTP_PORT esp_mail_smtp_port_587 +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" +#define RECIPIENT_EMAIL "" + +SMTPSession smtp; + +void smtpCallback(SMTP_Status status); + +void setup() +{ + + SerialMon.begin(115200); + + smtp.debug(1); + + smtp.callback(smtpCallback); + + delay(10); + pinMode(BAT_EN, OUTPUT); + digitalWrite(BAT_EN, HIGH); + + // A7670 Reset + pinMode(RESET, OUTPUT); + digitalWrite(RESET, LOW); + delay(100); + digitalWrite(RESET, HIGH); + delay(3000); + digitalWrite(RESET, LOW); + + pinMode(PWR_PIN, OUTPUT); + digitalWrite(PWR_PIN, LOW); + delay(100); + digitalWrite(PWR_PIN, HIGH); + delay(1000); + digitalWrite(PWR_PIN, LOW); + + DBG("Wait..."); + + delay(3000); + + SerialAT.begin(UART_BAUD, SERIAL_8N1, PIN_RX, PIN_TX); + + // Restart takes quite some time + // To skip it, call init() instead of restart() + DBG("Initializing modem..."); + if (!modem.init()) + { + DBG("Failed to restart modem, delaying 10s and retrying"); + return; + } + + /* + 2 Automatic + 13 GSM Only + 14 WCDMA Only + 38 LTE Only + */ + modem.setNetworkMode(38); + if (modem.waitResponse(10000L) != 1) + { + DBG(" setNetworkMode faill"); + } + + String name = modem.getModemName(); + DBG("Modem Name:", name); + + String modemInfo = modem.getModemInfo(); + DBG("Modem Info:", modemInfo); + + Session_Config config; + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + config.login.user_domain = F("127.0.0.1"); + + SMTP_Message message; + + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email using GSM module"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + message.text.content = "This is simple plain text message"; + + smtp.setGSMClient(&gsm_client, &modem, GSM_PIN, apn, gprsUser, gprsPass); + + smtp.connect(&config); + + if (!MailClient.sendMail(&smtp, &message)) + Serial.println("Error sending Email, " + smtp.errorReason()); +} + +void loop() +{ +} + +void smtpCallback(SMTP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + smtp.sendingResult.clear(); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/WiFiClient/WiFiClient.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/WiFiClient/WiFiClient.ino index 6e80e1101..7e519e320 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/WiFiClient/WiFiClient.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/External_Client/WiFiClient/WiFiClient.ino @@ -1,187 +1,187 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to send Email using external WiFiClient. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -#define SMTP_HOST "" -#define SMTP_PORT esp_mail_smtp_port_587 -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" -#define RECIPIENT_EMAIL "" - -SMTPSession smtp; - -WiFiClient wifi_client; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void smtpCallback(SMTP_Status status); - -void networkStatusRequestCallback() -{ - smtp.setNetworkStatus(WiFi.status() == WL_CONNECTED); -} - -void networkConnectionRequestCallback() -{ - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); -} - -void setup() -{ - - Serial.begin(115200); - - networkConnectionRequestCallback(); - - MailClient.networkReconnect(true); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - smtp.debug(1); - - smtp.callback(smtpCallback); - - Session_Config config; - - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - config.login.user_domain = F("127.0.0.1"); - - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - - smtp.setClient(&wifi_client); - - smtp.networkStatusRequestCallback(networkStatusRequestCallback); - - smtp.networkConnectionRequestCallback(networkConnectionRequestCallback); - - smtp.connect(&config); - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - SMTP_Message message; - - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - message.subject = F("Test sending plain text Email"); - message.addRecipient(F("Someone"), RECIPIENT_EMAIL); - - message.text.content = "This is simple plain text message"; - - if (!MailClient.sendMail(&smtp, &message)) - Serial.println("Error sending Email, " + smtp.errorReason()); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -void smtpCallback(SMTP_Status status) -{ - Serial.println(status.info()); - - if (status.success()) - { - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - SMTP_Result result = smtp.sendingResult.getItem(i); - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - smtp.sendingResult.clear(); - } -} + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email using external WiFiClient. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define SMTP_HOST "" +#define SMTP_PORT esp_mail_smtp_port_587 +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" +#define RECIPIENT_EMAIL "" + +SMTPSession smtp; + +WiFiClient wifi_client; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void smtpCallback(SMTP_Status status); + +void networkStatusRequestCallback() +{ + smtp.setNetworkStatus(WiFi.status() == WL_CONNECTED); +} + +void networkConnectionRequestCallback() +{ + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); +} + +void setup() +{ + + Serial.begin(115200); + + networkConnectionRequestCallback(); + + MailClient.networkReconnect(true); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + smtp.debug(1); + + smtp.callback(smtpCallback); + + Session_Config config; + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + config.login.user_domain = F("127.0.0.1"); + + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + + smtp.setClient(&wifi_client); + + smtp.networkStatusRequestCallback(networkStatusRequestCallback); + + smtp.networkConnectionRequestCallback(networkConnectionRequestCallback); + + smtp.connect(&config); + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + SMTP_Message message; + + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + message.text.content = "This is simple plain text message"; + + if (!MailClient.sendMail(&smtp, &message)) + Serial.println("Error sending Email, " + smtp.errorReason()); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +void smtpCallback(SMTP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Reply_Text/Reply_Text.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Reply_Text/Reply_Text.ino index 76ce8091b..43fd7e7d8 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Reply_Text/Reply_Text.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Reply_Text/Reply_Text.ino @@ -1,497 +1,497 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example showes how to send a reply message when specific email was received. - -// The account 2 will send Hello message to account 1. - -// The account 1 will poll the mailbox for incoming message, when new message received with matched subject -// and sent from account 2, the account 1 will send a reply messsage to account 2. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ -#define IMAP_HOST "" -#define IMAP_PORT 993 - -#define IMAP_AUTHOR_EMAIL "" -#define IMAP_AUTHOR_PASSWORD "" - -#define REPLY_SMTP_AUTHOR_EMAIL "" -#define REPLY_SMTP_AUTHOR_PASSWORD "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define REPLY_SMTP_PORT 587 -#define REPLY_SMTP_HOST "" - -#define HELLO_SMTP_AUTHOR_EMAIL "" -#define HELLO_SMTP_AUTHOR_PASSWORD "" - -#define HELLO_SMTP_PORT 587 -#define HELLO_SMTP_HOST "" - -void setupIMAP(); - -bool setupHelloSMTP(); - -bool setupReplySMTP(); - -void sendHelloMessage(); - -void sendReplyMessage(const char *subject, const char *reply_email, const char *msgID, const char *references); - -/* Print the selected folder update info */ -void printPollingStatus(IMAPSession &imap); - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status); - -/* Callback function to get the Email sending status */ -void helloSMTPCallback(SMTP_Status status); - -void replySMTPCallback(SMTP_Status status); - -/* Declare the global used IMAPSession object for IMAP transport */ -IMAPSession imap; - -/* Declare the global used Session_Config for user defined IMAP session credentials */ -Session_Config imap_config; - -/** Define the IMAP_Data object used for user defined IMAP operating options - * and contains the IMAP operating result - */ -IMAP_Data imap_data; - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession hello_smtp; -SMTPSession reply_smtp; - -/* Declare the global used Session_Config for user defined SMTP session credentials */ -Session_Config hello_smtp_config; -Session_Config reply_smtp_config; - -bool imapSetupOk = false; - -unsigned long helloSendingMillis = 0; - -String sendingSubject = "ESP Mail Hello Test!"; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Setup and connect to IMAP server... "); - - setupIMAP(); - - if (!imapSetupOk) - return; -} - -void loop() -{ - - /* imap.connect and imap.selectFolder or imap.openFolder nedded to be called once prior to listen */ - - // Listen for mailbox changes - if (!imap.listen()) - return; - - // Check the changes - if (imap.folderChanged()) - printPollingStatus(imap); - - // To stop listen, use imap.stopListen(); and to listen again, call imap.listen() - - if (millis() - helloSendingMillis > 5 * 60 * 1000 || helloSendingMillis == 0) - { - helloSendingMillis = millis(); - Serial.print("Sending Hello message... "); - sendHelloMessage(); - } -} - -void setupIMAP() -{ - imap.debug(1); - - /* Set the callback function to get the reading results */ - imap.callback(imapCallback); - - /* Set the imap app config */ - imap_config.server.host_name = IMAP_HOST; - imap_config.server.port = IMAP_PORT; - imap_config.login.email = IMAP_AUTHOR_EMAIL; - imap_config.login.password = IMAP_AUTHOR_PASSWORD; - - /* Connect to the server */ - if (!imap.connect(&imap_config, &imap_data)) - return; - - if (imap.isAuthenticated()) - Serial.println("\nIMAP client, successfully logged in."); - else - Serial.println("\nIMAP client, connected with no Auth."); - - /* Open or select the mailbox folder to read or search the message */ - if (!imap.selectFolder(F("INBOX"))) - return; - - imapSetupOk = true; -} - -bool setupHelloSMTP() -{ - hello_smtp.debug(1); - - /* Set the callback function to get the sending results */ - hello_smtp.callback(helloSMTPCallback); - - /* Set the session config */ - hello_smtp_config.server.host_name = HELLO_SMTP_HOST; - hello_smtp_config.server.port = HELLO_SMTP_PORT; - hello_smtp_config.login.email = HELLO_SMTP_AUTHOR_EMAIL; - hello_smtp_config.login.password = HELLO_SMTP_AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - hello_smtp_config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - hello_smtp_config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - hello_smtp_config.time.gmt_offset = 3; - hello_smtp_config.time.day_light_offset = 0; - - /* Connect to the server */ - if (!hello_smtp.connect(&hello_smtp_config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", hello_smtp.statusCode(), hello_smtp.errorCode(), hello_smtp.errorReason().c_str()); - return false; - } - - if (imap.isAuthenticated()) - Serial.println("\nHello SMTP client, successfully logged in."); - else - Serial.println("\nHello SMTP client, connected with no Auth."); - - return true; -} - -bool setupReplySMTP() -{ - reply_smtp.debug(1); - - /* Set the callback function to get the sending results */ - reply_smtp.callback(replySMTPCallback); - - /* Set the session config */ - reply_smtp_config.server.host_name = REPLY_SMTP_HOST; - reply_smtp_config.server.port = REPLY_SMTP_PORT; - reply_smtp_config.login.email = REPLY_SMTP_AUTHOR_EMAIL; - reply_smtp_config.login.password = REPLY_SMTP_AUTHOR_PASSWORD; - reply_smtp_config.login.user_domain = F("127.0.0.1"); - - /* Connect to the server */ - if (!reply_smtp.connect(&reply_smtp_config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", reply_smtp.statusCode(), reply_smtp.errorCode(), reply_smtp.errorReason().c_str()); - return false; - } - - if (imap.isAuthenticated()) - Serial.println("\nReply SMTP client, successfully logged in."); - else - Serial.println("\nReply SMTP client, connected with no Auth."); - - return true; -} - -void sendHelloMessage() -{ - - if (!setupHelloSMTP()) - return; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = HELLO_SMTP_AUTHOR_EMAIL; - message.subject = sendingSubject.c_str(); - message.addRecipient(F("Me"), IMAP_AUTHOR_EMAIL); - message.response.reply_to = HELLO_SMTP_AUTHOR_EMAIL; // only email address, excluded < and > - message.text.content = F("Hello Me!"); - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&hello_smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", hello_smtp.statusCode(), hello_smtp.errorCode(), hello_smtp.errorReason().c_str()); -} - -void sendReplyMessage(const char *subject, const char *reply_email, const char *msgID, const char *references) -{ - - if (!setupReplySMTP()) - return; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = REPLY_SMTP_AUTHOR_EMAIL; - String reSubject = "RE: "; - reSubject += subject; - message.subject = reSubject; - message.addRecipient(F("Me"), reply_email); - - message.in_reply_to = msgID; - - String ref = references; - if (strlen(references) > 0) - ref += " "; - ref += msgID; - - message.references = ref; - message.text.content = F("Yeah!, it works."); - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&reply_smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", reply_smtp.statusCode(), reply_smtp.errorCode(), reply_smtp.errorReason().c_str()); -} - -void printPollingStatus(IMAPSession &imap) -{ - /* Declare the selected folder info class to get the info of selected mailbox folder */ - SelectedFolderInfo sFolder = imap.selectedFolder(); - - if (sFolder.pollingStatus().type == imap_polling_status_type_new_message) - { - /* Show the mailbox info */ - MailClient.printf("\nMailbox status changed\n----------------------\nTotal Messages: %d\n", sFolder.msgCount()); - - MailClient.printf("New message %d, has been addedd, reading message...\n", (int)sFolder.pollingStatus().messageNum); - - // we need to stop polling before do anything - imap.stopListen(); - - // Get the UID of new message and fetch - imap_data.fetch.uid = imap.getUID(sFolder.pollingStatus().messageNum); - - // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, - // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag - // to message, see the Set_Flags.ino example. - MailClient.readMail(&imap, false); - } -} - -/* Callback function to get the Email reading status */ -void imapCallback(IMAP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Show the result when reading finished */ - if (status.success()) - { - - /* Get the message list from the message list data */ - IMAP_MSG_List msgList = imap.data(); - - if (strcmp(msgList.msgItems[0].subject, sendingSubject.c_str()) == 0) - { - Serial.print("Sending Reply message... "); - std::string replyEmail = msgList.msgItems[0].reply_to; - - // remove < at the beginning and > at the end. - replyEmail.erase(0, 1); - replyEmail.pop_back(); - - sendReplyMessage(msgList.msgItems[0].subject, replyEmail.c_str(), msgList.msgItems[0].ID, msgList.msgItems[0].references); - } - - /* Clear all stored data in IMAPSession object */ - imap.empty(); - } -} - -/* Callback function to get the Email sending status */ -void helloSMTPCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < hello_smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = hello_smtp.sendingResult.getItem(i); - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up - hello_smtp.sendingResult.clear(); - } -} - -void replySMTPCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < reply_smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = reply_smtp.sendingResult.getItem(i); - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - reply_smtp.sendingResult.clear(); - } -} + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example showes how to send a reply message when specific email was received. + +// The account 2 will send Hello message to account 1. + +// The account 1 will poll the mailbox for incoming message, when new message received with matched subject +// and sent from account 2, the account 1 will send a reply messsage to account 2. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/* The imap host name e.g. imap.gmail.com for GMail or outlook.office365.com for Outlook */ +#define IMAP_HOST "" +#define IMAP_PORT 993 + +#define IMAP_AUTHOR_EMAIL "" +#define IMAP_AUTHOR_PASSWORD "" + +#define REPLY_SMTP_AUTHOR_EMAIL "" +#define REPLY_SMTP_AUTHOR_PASSWORD "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define REPLY_SMTP_PORT 587 +#define REPLY_SMTP_HOST "" + +#define HELLO_SMTP_AUTHOR_EMAIL "" +#define HELLO_SMTP_AUTHOR_PASSWORD "" + +#define HELLO_SMTP_PORT 587 +#define HELLO_SMTP_HOST "" + +void setupIMAP(); + +bool setupHelloSMTP(); + +bool setupReplySMTP(); + +void sendHelloMessage(); + +void sendReplyMessage(const char *subject, const char *reply_email, const char *msgID, const char *references); + +/* Print the selected folder update info */ +void printPollingStatus(IMAPSession &imap); + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status); + +/* Callback function to get the Email sending status */ +void helloSMTPCallback(SMTP_Status status); + +void replySMTPCallback(SMTP_Status status); + +/* Declare the global used IMAPSession object for IMAP transport */ +IMAPSession imap; + +/* Declare the global used Session_Config for user defined IMAP session credentials */ +Session_Config imap_config; + +/** Define the IMAP_Data object used for user defined IMAP operating options + * and contains the IMAP operating result + */ +IMAP_Data imap_data; + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession hello_smtp; +SMTPSession reply_smtp; + +/* Declare the global used Session_Config for user defined SMTP session credentials */ +Session_Config hello_smtp_config; +Session_Config reply_smtp_config; + +bool imapSetupOk = false; + +unsigned long helloSendingMillis = 0; + +String sendingSubject = "ESP Mail Hello Test!"; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Setup and connect to IMAP server... "); + + setupIMAP(); + + if (!imapSetupOk) + return; +} + +void loop() +{ + + /* imap.connect and imap.selectFolder or imap.openFolder nedded to be called once prior to listen */ + + // Listen for mailbox changes + if (!imap.listen()) + return; + + // Check the changes + if (imap.folderChanged()) + printPollingStatus(imap); + + // To stop listen, use imap.stopListen(); and to listen again, call imap.listen() + + if (millis() - helloSendingMillis > 5 * 60 * 1000 || helloSendingMillis == 0) + { + helloSendingMillis = millis(); + Serial.print("Sending Hello message... "); + sendHelloMessage(); + } +} + +void setupIMAP() +{ + imap.debug(1); + + /* Set the callback function to get the reading results */ + imap.callback(imapCallback); + + /* Set the imap app config */ + imap_config.server.host_name = IMAP_HOST; + imap_config.server.port = IMAP_PORT; + imap_config.login.email = IMAP_AUTHOR_EMAIL; + imap_config.login.password = IMAP_AUTHOR_PASSWORD; + + /* Connect to the server */ + if (!imap.connect(&imap_config, &imap_data)) + return; + + if (imap.isAuthenticated()) + Serial.println("\nIMAP client, successfully logged in."); + else + Serial.println("\nIMAP client, connected with no Auth."); + + /* Open or select the mailbox folder to read or search the message */ + if (!imap.selectFolder(F("INBOX"))) + return; + + imapSetupOk = true; +} + +bool setupHelloSMTP() +{ + hello_smtp.debug(1); + + /* Set the callback function to get the sending results */ + hello_smtp.callback(helloSMTPCallback); + + /* Set the session config */ + hello_smtp_config.server.host_name = HELLO_SMTP_HOST; + hello_smtp_config.server.port = HELLO_SMTP_PORT; + hello_smtp_config.login.email = HELLO_SMTP_AUTHOR_EMAIL; + hello_smtp_config.login.password = HELLO_SMTP_AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + hello_smtp_config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + hello_smtp_config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + hello_smtp_config.time.gmt_offset = 3; + hello_smtp_config.time.day_light_offset = 0; + + /* Connect to the server */ + if (!hello_smtp.connect(&hello_smtp_config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", hello_smtp.statusCode(), hello_smtp.errorCode(), hello_smtp.errorReason().c_str()); + return false; + } + + if (imap.isAuthenticated()) + Serial.println("\nHello SMTP client, successfully logged in."); + else + Serial.println("\nHello SMTP client, connected with no Auth."); + + return true; +} + +bool setupReplySMTP() +{ + reply_smtp.debug(1); + + /* Set the callback function to get the sending results */ + reply_smtp.callback(replySMTPCallback); + + /* Set the session config */ + reply_smtp_config.server.host_name = REPLY_SMTP_HOST; + reply_smtp_config.server.port = REPLY_SMTP_PORT; + reply_smtp_config.login.email = REPLY_SMTP_AUTHOR_EMAIL; + reply_smtp_config.login.password = REPLY_SMTP_AUTHOR_PASSWORD; + reply_smtp_config.login.user_domain = F("127.0.0.1"); + + /* Connect to the server */ + if (!reply_smtp.connect(&reply_smtp_config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", reply_smtp.statusCode(), reply_smtp.errorCode(), reply_smtp.errorReason().c_str()); + return false; + } + + if (imap.isAuthenticated()) + Serial.println("\nReply SMTP client, successfully logged in."); + else + Serial.println("\nReply SMTP client, connected with no Auth."); + + return true; +} + +void sendHelloMessage() +{ + + if (!setupHelloSMTP()) + return; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = HELLO_SMTP_AUTHOR_EMAIL; + message.subject = sendingSubject.c_str(); + message.addRecipient(F("Me"), IMAP_AUTHOR_EMAIL); + message.response.reply_to = HELLO_SMTP_AUTHOR_EMAIL; // only email address, excluded < and > + message.text.content = F("Hello Me!"); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&hello_smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", hello_smtp.statusCode(), hello_smtp.errorCode(), hello_smtp.errorReason().c_str()); +} + +void sendReplyMessage(const char *subject, const char *reply_email, const char *msgID, const char *references) +{ + + if (!setupReplySMTP()) + return; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = REPLY_SMTP_AUTHOR_EMAIL; + String reSubject = "RE: "; + reSubject += subject; + message.subject = reSubject; + message.addRecipient(F("Me"), reply_email); + + message.in_reply_to = msgID; + + String ref = references; + if (strlen(references) > 0) + ref += " "; + ref += msgID; + + message.references = ref; + message.text.content = F("Yeah!, it works."); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&reply_smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", reply_smtp.statusCode(), reply_smtp.errorCode(), reply_smtp.errorReason().c_str()); +} + +void printPollingStatus(IMAPSession &imap) +{ + /* Declare the selected folder info class to get the info of selected mailbox folder */ + SelectedFolderInfo sFolder = imap.selectedFolder(); + + if (sFolder.pollingStatus().type == imap_polling_status_type_new_message) + { + /* Show the mailbox info */ + MailClient.printf("\nMailbox status changed\n----------------------\nTotal Messages: %d\n", sFolder.msgCount()); + + MailClient.printf("New message %d, has been addedd, reading message...\n", (int)sFolder.pollingStatus().messageNum); + + // we need to stop polling before do anything + imap.stopListen(); + + // Get the UID of new message and fetch + imap_data.fetch.uid = imap.getUID(sFolder.pollingStatus().messageNum); + + // When message was fetched or read, the /Seen flag will not set or message remained in unseen or unread status, + // as this is the purpose of library (not UI application), user can set the message status as read by set \Seen flag + // to message, see the Set_Flags.ino example. + MailClient.readMail(&imap, false); + } +} + +/* Callback function to get the Email reading status */ +void imapCallback(IMAP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Show the result when reading finished */ + if (status.success()) + { + + /* Get the message list from the message list data */ + IMAP_MSG_List msgList = imap.data(); + + if (strcmp(msgList.msgItems[0].subject, sendingSubject.c_str()) == 0) + { + Serial.print("Sending Reply message... "); + std::string replyEmail = msgList.msgItems[0].reply_to; + + // remove < at the beginning and > at the end. + replyEmail.erase(0, 1); + replyEmail.pop_back(); + + sendReplyMessage(msgList.msgItems[0].subject, replyEmail.c_str(), msgList.msgItems[0].ID, msgList.msgItems[0].references); + } + + /* Clear all stored data in IMAPSession object */ + imap.empty(); + } +} + +/* Callback function to get the Email sending status */ +void helloSMTPCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + struct tm dt; + + for (size_t i = 0; i < hello_smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = hello_smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up + hello_smtp.sendingResult.clear(); + } +} + +void replySMTPCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + struct tm dt; + + for (size_t i = 0; i < reply_smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = reply_smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + reply_smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Access_Token/Send_Access_Token.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Access_Token/Send_Access_Token.ino index cb0cdb6bf..30547dc89 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Access_Token/Send_Access_Token.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Access_Token/Send_Access_Token.ino @@ -1,304 +1,304 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to log in with the SASL XOAUTH2 mechanisme using OAuth2.0 access token and send Email. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** For Gmail, to send the Email via port 465 (SSL), less secure app option - * should be enabled in the account settings. https://myaccount.google.com/lesssecureapps?pli=1 - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT 25 - -/* The user Email for OAuth2.0 access token */ -#define AUTHOR_EMAIL "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/** The OAuth2.0 access token - * The generation, exchange and refresh of the access token are not available - * in this library. - * - * To test this using GMail, get the OAuth2.0 access token from this web site - * https://developers.google.com/oauthplayground/ - * - * - * 1. Select the following scope (in Step 1) from Gmail API V1 - * https://mail.google.com/ - * https://mail.google.com/ - * - * 2. Click Authorize APIs button. - * 3. Cick Exchangeauthorization code for tokens. - * 4. From the response, look at access_token from the JSON payload node. - * 5. Copy that access token and paste to the AUTHOR_ACCESS_TOKEN value. - * - * The token will be expired in 3600 seconds (1 Hr). - * The AUTHOR_EMAIL above is the Email address that you granted to access the Gmail services. - */ -#define AUTHOR_ACCESS_TOKEN "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.accessToken = AUTHOR_ACCESS_TOKEN; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - message.subject = F("Test sending Email using Access token"); - message.addRecipient(F("Admin"), RECIPIENT_EMAIL); - - message.text.content = F("This is simple plain text message"); - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.text.charSet = F("us-ascii"); - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Connect to the server */ - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* Set the custom message header */ - message.addHeader(F("Message-ID: ")); - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to log in with the SASL XOAUTH2 mechanisme using OAuth2.0 access token and send Email. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** For Gmail, to send the Email via port 465 (SSL), less secure app option + * should be enabled in the account settings. https://myaccount.google.com/lesssecureapps?pli=1 + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT 25 + +/* The user Email for OAuth2.0 access token */ +#define AUTHOR_EMAIL "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/** The OAuth2.0 access token + * The generation, exchange and refresh of the access token are not available + * in this library. + * + * To test this using GMail, get the OAuth2.0 access token from this web site + * https://developers.google.com/oauthplayground/ + * + * + * 1. Select the following scope (in Step 1) from Gmail API V1 + * https://mail.google.com/ + * https://mail.google.com/ + * + * 2. Click Authorize APIs button. + * 3. Cick Exchangeauthorization code for tokens. + * 4. From the response, look at access_token from the JSON payload node. + * 5. Copy that access token and paste to the AUTHOR_ACCESS_TOKEN value. + * + * The token will be expired in 3600 seconds (1 Hr). + * The AUTHOR_EMAIL above is the Email address that you granted to access the Gmail services. + */ +#define AUTHOR_ACCESS_TOKEN "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.accessToken = AUTHOR_ACCESS_TOKEN; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending Email using Access token"); + message.addRecipient(F("Admin"), RECIPIENT_EMAIL); + + message.text.content = F("This is simple plain text message"); + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Blob/Send_Attachment_Blob.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Blob/Send_Attachment_Blob.ino index b408c8f81..7f74f2591 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Blob/Send_Attachment_Blob.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Blob/Send_Attachment_Blob.ino @@ -1,369 +1,369 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to send Email with attachments and inline images. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -/* This is for attachment data */ -#include "blob_data.h" - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /* Declare the message class */ - SMTP_Message message; - - /* Enable the chunked data transfer with pipelining for large message if server supported */ - message.enable.chunking = true; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - - message.subject = F("Test sending Email with attachments and inline images"); - message.addRecipient(F("user1"), RECIPIENT_EMAIL); - - message.html.content = F("This message contains 3 inline images and 1 attachment file.

"); - - /** The HTML text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.html.charSet = F("utf-8"); - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; - - message.text.content = F("This message contains 3 inline images and 1 attachment file.\r\nThe inline images were not shown in the plain text message."); - message.text.charSet = F("utf-8"); - message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader(F("Message-ID: ")); - - /* The attachment data item */ - SMTP_Attachment att[4]; - int attIndex = 0; - - /** Set the inline image info e.g. - * file name, MIME type, BLOB data, BLOB data size, - * transfer encoding (should be base64 for inline image) - */ - att[attIndex].descr.filename = F("firebase_logo.png"); - att[attIndex].descr.mime = F("image/png"); - att[attIndex].blob.data = firebase_logo_png; - att[attIndex].blob.size = sizeof(firebase_logo_png); - att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add inline image to the message */ - message.addInlineImage(att[attIndex]); - - /** Set the inline image info e.g. - * file name, MIME type, BLOB data, BLOB data size. - * The default transfer encoding is base64. - */ - attIndex++; - att[attIndex].descr.filename = F("tree.gif"); - att[attIndex].descr.mime = F("image/gif"); - att[attIndex].blob.data = tree_img_gif; - att[attIndex].blob.size = sizeof(tree_img_gif); - att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add inline image to the message */ - message.addInlineImage(att[attIndex]); - - /** Set the inline image info e.g. - * file name, MIME type, BLOB data, BLOB data size. - * The default transfer encoding is base64. - */ - attIndex++; - att[attIndex].descr.filename = F("bird.gif"); - att[attIndex].descr.mime = F("image/gif"); - att[attIndex].blob.data = bird_img_gif; - att[attIndex].blob.size = sizeof(bird_img_gif); - att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add inline image to the message */ - message.addInlineImage(att[attIndex]); - - /* Prepare the attachment data (from ram) */ - uint8_t *a = new uint8_t[512]; - int j = 0; - - for (int i = 0; i < 512; i++) - { - a[i] = j; - j++; - if (j > 255) - j = 0; - } - - /** Set the attachment info e.g. - * file name, MIME type, BLOB data, BLOB data size. - * The default transfer encoding is base64. - */ - attIndex++; - att[attIndex].descr.filename = F("test.dat"); - att[attIndex].descr.mime = F("application/octet-stream"); - att[attIndex].blob.data = a; - att[attIndex].blob.size = 512; - att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - /* Add attachment to the message */ - message.addAttachment(att[attIndex]); - - /* Connect to the server */ - if (!smtp.connect(&config)) - return; - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* Start sending the Email and close the session */ - if (!MailClient.sendMail(&smtp, &message, true)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email with attachments and inline images. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +/* This is for attachment data */ +#include "blob_data.h" + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Enable the chunked data transfer with pipelining for large message if server supported */ + message.enable.chunking = true; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + + message.subject = F("Test sending Email with attachments and inline images"); + message.addRecipient(F("user1"), RECIPIENT_EMAIL); + + message.html.content = F("This message contains 3 inline images and 1 attachment file.

"); + + /** The HTML text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("utf-8"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; + + message.text.content = F("This message contains 3 inline images and 1 attachment file.\r\nThe inline images were not shown in the plain text message."); + message.text.charSet = F("utf-8"); + message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* The attachment data item */ + SMTP_Attachment att[4]; + int attIndex = 0; + + /** Set the inline image info e.g. + * file name, MIME type, BLOB data, BLOB data size, + * transfer encoding (should be base64 for inline image) + */ + att[attIndex].descr.filename = F("firebase_logo.png"); + att[attIndex].descr.mime = F("image/png"); + att[attIndex].blob.data = firebase_logo_png; + att[attIndex].blob.size = sizeof(firebase_logo_png); + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att[attIndex]); + + /** Set the inline image info e.g. + * file name, MIME type, BLOB data, BLOB data size. + * The default transfer encoding is base64. + */ + attIndex++; + att[attIndex].descr.filename = F("tree.gif"); + att[attIndex].descr.mime = F("image/gif"); + att[attIndex].blob.data = tree_img_gif; + att[attIndex].blob.size = sizeof(tree_img_gif); + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att[attIndex]); + + /** Set the inline image info e.g. + * file name, MIME type, BLOB data, BLOB data size. + * The default transfer encoding is base64. + */ + attIndex++; + att[attIndex].descr.filename = F("bird.gif"); + att[attIndex].descr.mime = F("image/gif"); + att[attIndex].blob.data = bird_img_gif; + att[attIndex].blob.size = sizeof(bird_img_gif); + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att[attIndex]); + + /* Prepare the attachment data (from ram) */ + uint8_t *a = new uint8_t[512]; + int j = 0; + + for (int i = 0; i < 512; i++) + { + a[i] = j; + j++; + if (j > 255) + j = 0; + } + + /** Set the attachment info e.g. + * file name, MIME type, BLOB data, BLOB data size. + * The default transfer encoding is base64. + */ + attIndex++; + att[attIndex].descr.filename = F("test.dat"); + att[attIndex].descr.mime = F("application/octet-stream"); + att[attIndex].blob.data = a; + att[attIndex].blob.size = 512; + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + /* Add attachment to the message */ + message.addAttachment(att[attIndex]); + + /* Connect to the server */ + if (!smtp.connect(&config)) + return; + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending the Email and close the session */ + if (!MailClient.sendMail(&smtp, &message, true)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Blob/blob_data.h b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Blob/blob_data.h index c853cded3..a3463307a 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Blob/blob_data.h +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Blob/blob_data.h @@ -1,1851 +1,1851 @@ -#include - -static const uint8_t firebase_logo_png[] PROGMEM = { - 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x02, 0x58, 0x08, 0x06, 0x00, 0x00, 0x00, 0x9A, 0x76, 0x82, - 0x70, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00, - 0x00, 0x04, 0x67, 0x41, 0x4D, 0x41, 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, 0x61, 0x05, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x00, 0x0E, 0xC3, 0x01, 0xC7, - 0x6F, 0xA8, 0x64, 0x00, 0x00, 0x55, 0x14, 0x49, 0x44, 0x41, 0x54, 0x78, 0x5E, 0xED, 0xDD, 0x59, - 0x90, 0x1D, 0xF5, 0x81, 0xE7, 0x7B, 0x3F, 0xF4, 0xC3, 0x84, 0x91, 0x40, 0x6E, 0xEF, 0xC6, 0x8B, - 0x30, 0x92, 0x4A, 0x1B, 0x58, 0x98, 0xCD, 0xA0, 0xA5, 0x4A, 0x12, 0x20, 0x6C, 0x9A, 0xB6, 0xBA, - 0x01, 0x63, 0x4F, 0x3F, 0x8C, 0x1E, 0x26, 0xC2, 0xF7, 0xE5, 0xC6, 0x25, 0xE2, 0xDE, 0x97, 0x3B, - 0x7D, 0x67, 0xAC, 0x6E, 0x63, 0x63, 0x83, 0x8D, 0xBC, 0xB1, 0x99, 0xA5, 0x10, 0x08, 0xED, 0x52, - 0x69, 0xAD, 0x92, 0xA0, 0xBB, 0xAB, 0xA7, 0xED, 0x6E, 0x77, 0xB7, 0x81, 0x42, 0x9B, 0x99, 0x89, - 0x89, 0xDB, 0x9A, 0xB9, 0x0E, 0x2F, 0x2C, 0x76, 0x61, 0x16, 0x49, 0x85, 0xA4, 0xFC, 0xDF, 0xFF, - 0x3F, 0x4F, 0xE6, 0xA9, 0x3C, 0x79, 0x7E, 0xE7, 0x9C, 0xCC, 0x3C, 0x99, 0x75, 0xCE, 0xC9, 0xFA, - 0x7E, 0x22, 0x7E, 0xA1, 0x6E, 0x2F, 0x42, 0xC2, 0x94, 0xE2, 0xFF, 0x8D, 0x7F, 0x65, 0x9E, 0xF7, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x28, 0x82, 0x79, 0x6E, 0xCD, 0x80, 0xBF, 0xC3, 0x5F, 0x58, 0x12, 0xFC, - 0x4B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x1F, 0x73, 0x78, 0xCD, 0x3A, 0xEF, 0xB9, 0x35, 0x63, 0xE6, - 0xB9, 0x9B, 0x4D, 0x75, 0xCF, 0xAE, 0xF1, 0xE7, 0x3D, 0x7B, 0xD3, 0xA0, 0x0B, 0x92, 0xE0, 0x3F, - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x98, 0x91, 0x35, 0xB3, 0xEB, 0xC2, 0x23, 0x12, 0x1F, 0xD1, - 0x79, 0x87, 0xD7, 0x6C, 0x08, 0xFE, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x8E, 0xFB, 0x16, 0x2B, - 0xEF, 0xD9, 0x35, 0xE3, 0x95, 0xE0, 0xB8, 0xD1, 0x98, 0x03, 0x57, 0x19, 0xB3, 0x7B, 0xAE, 0x31, - 0x3B, 0x3E, 0x65, 0xCC, 0xB6, 0x8F, 0x1A, 0xB3, 0xF3, 0xD3, 0xC6, 0x0C, 0x2D, 0x34, 0x66, 0x78, - 0xD9, 0x64, 0x84, 0x3C, 0x7B, 0xD3, 0x60, 0xF0, 0x5F, 0x07, 0x00, 0x00, 0x00, 0x80, 0xE4, 0xAA, - 0x37, 0x1F, 0x2E, 0x3C, 0x76, 0x7C, 0xC2, 0x98, 0xED, 0x1F, 0xAB, 0x84, 0x87, 0xDA, 0x2E, 0x1B, - 0x26, 0x87, 0x6F, 0xA8, 0x84, 0xC8, 0xA1, 0x9B, 0xD6, 0x06, 0x3F, 0x05, 0x00, 0x00, 0x00, 0x00, - 0xB4, 0xE6, 0x9E, 0xF9, 0xF0, 0xE3, 0x63, 0xCF, 0xA2, 0x4A, 0x78, 0x34, 0x8B, 0x8F, 0x70, 0xDB, - 0x3F, 0x6E, 0xCC, 0xC8, 0x0A, 0xF7, 0xAD, 0x58, 0xE3, 0x66, 0xB4, 0x7F, 0x56, 0xF0, 0x53, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x73, 0xDE, 0x73, 0x37, 0x9F, 0x34, 0xFB, 0xAF, 0x48, 0x1E, 0x1F, 0xE1, - 0x76, 0x5E, 0x62, 0xCC, 0xE1, 0xD5, 0x76, 0x37, 0xAE, 0x0F, 0x7E, 0x2A, 0x00, 0x00, 0x00, 0x00, - 0x68, 0xCC, 0x3D, 0x78, 0x6E, 0x0E, 0xAF, 0x4A, 0x1F, 0x1F, 0xFE, 0x3E, 0x62, 0xCC, 0xBE, 0xCF, - 0x18, 0xEF, 0xF0, 0x4D, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x68, 0xCD, 0xFF, 0x8C, 0x8F, 0xBD, - 0x97, 0x67, 0x8B, 0x0F, 0xB7, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x20, 0x19, 0x1B, - 0x20, 0xEB, 0xCD, 0xAE, 0x4F, 0xC7, 0xE2, 0xA2, 0xD5, 0x82, 0xF8, 0x08, 0xB7, 0x67, 0xB1, 0x31, - 0xCF, 0xDE, 0x64, 0xDC, 0x6D, 0x4A, 0xF0, 0xD3, 0x02, 0x00, 0x00, 0x00, 0x40, 0x3D, 0xEF, 0xB9, - 0x9B, 0x07, 0x75, 0x64, 0x34, 0x5A, 0x2C, 0x3E, 0xC2, 0x1D, 0x1A, 0xE0, 0xB5, 0xBC, 0x00, 0x00, - 0x00, 0x00, 0x9A, 0xF3, 0x0E, 0x2E, 0x1B, 0xD5, 0xA1, 0xA1, 0x26, 0xC2, 0x23, 0xDC, 0xD0, 0x02, - 0x6E, 0x41, 0x00, 0x00, 0x00, 0x00, 0x34, 0xE7, 0x1D, 0xB8, 0x76, 0x5C, 0xC7, 0x46, 0x7C, 0x22, - 0x3A, 0xE2, 0x1B, 0x59, 0x6E, 0xBC, 0xC3, 0x37, 0x8E, 0x06, 0x3F, 0x35, 0x00, 0x00, 0x00, 0x00, - 0x4C, 0x72, 0x6F, 0xAE, 0x32, 0xFB, 0x96, 0xD8, 0x78, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x0D, 0xB5, - 0x5D, 0x73, 0x2A, 0xB7, 0x20, 0xCF, 0xAD, 0x19, 0x08, 0xFE, 0x12, 0x00, 0x00, 0x00, 0x00, 0x50, - 0xE1, 0xBF, 0x01, 0x6B, 0x77, 0x9F, 0x8D, 0x07, 0x15, 0x1D, 0xE1, 0x44, 0x68, 0x34, 0xDB, 0xF0, - 0xF5, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xE7, 0x7F, 0x02, 0xFA, 0xAE, 0xB9, 0x36, 0x1C, - 0x54, 0x78, 0xB8, 0x89, 0xC0, 0x68, 0xB5, 0x5D, 0x97, 0x1A, 0xF3, 0xEC, 0x8D, 0xC6, 0x3C, 0xB7, - 0x9A, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x93, 0x6C, 0x80, 0xAC, 0xD7, 0xE1, 0xE1, 0x26, 0xE2, - 0xA2, 0xE5, 0x3E, 0x5C, 0xD9, 0x81, 0xAB, 0x8C, 0xF7, 0xEC, 0x0D, 0x27, 0x83, 0xBF, 0x0C, 0x00, - 0x00, 0x00, 0x00, 0xBC, 0xE7, 0x3D, 0xDE, 0xF0, 0x8A, 0x06, 0x6F, 0xC0, 0x52, 0x71, 0xD1, 0x6A, - 0x41, 0x7C, 0xB8, 0xED, 0xF8, 0x44, 0xE5, 0x16, 0xE4, 0xF0, 0x8D, 0xEB, 0x82, 0xBF, 0x14, 0x00, - 0x00, 0x00, 0x80, 0xE9, 0xCE, 0x3B, 0x70, 0xFD, 0xC9, 0xDC, 0xE3, 0x23, 0x1C, 0xB7, 0x20, 0x00, - 0x00, 0x00, 0x00, 0xA2, 0xCC, 0xFE, 0x2B, 0x6D, 0x2C, 0x14, 0x10, 0x1F, 0x6E, 0xEE, 0x16, 0xE4, - 0xF0, 0x2A, 0x77, 0x0B, 0xB2, 0x3E, 0xF8, 0xCB, 0x01, 0x00, 0x00, 0x00, 0x98, 0xAE, 0x6C, 0x18, - 0x2C, 0x31, 0x7B, 0x2E, 0xB3, 0xB1, 0x50, 0x40, 0x7C, 0x84, 0xDB, 0x77, 0xB9, 0x7B, 0x23, 0xD6, - 0xB8, 0x7B, 0xDD, 0x6F, 0xF0, 0x97, 0x05, 0x00, 0x00, 0x00, 0x30, 0x1D, 0x99, 0x43, 0x37, 0xAD, - 0x9D, 0x7C, 0x03, 0x96, 0x8A, 0x8B, 0x56, 0x13, 0xC1, 0x11, 0xDF, 0xF6, 0x8F, 0x71, 0x0B, 0x02, - 0x00, 0x00, 0x00, 0x20, 0x78, 0x03, 0xD6, 0xF6, 0x8F, 0xDB, 0x50, 0x50, 0x71, 0xD1, 0x6A, 0x22, - 0x36, 0x1A, 0x8D, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xB3, 0x37, 0x0D, 0xEA, 0xB8, 0x68, - 0x35, 0x11, 0x19, 0xAD, 0x76, 0xA8, 0xDF, 0x3D, 0x90, 0x3E, 0x18, 0xFC, 0xA5, 0x01, 0x00, 0x00, - 0x00, 0x4C, 0x37, 0xDE, 0x81, 0x6B, 0x46, 0x75, 0x60, 0x34, 0x9B, 0x88, 0x8B, 0x56, 0xDB, 0xFA, - 0x21, 0x63, 0x86, 0xE6, 0x57, 0x5E, 0xCB, 0x3B, 0xB2, 0x66, 0x76, 0xF0, 0x97, 0x07, 0x00, 0x00, - 0x00, 0x30, 0x9D, 0x98, 0x03, 0x57, 0xDB, 0x40, 0x50, 0x91, 0xD1, 0x68, 0x22, 0x2E, 0x5A, 0xCD, - 0xC5, 0x47, 0x38, 0x6E, 0x41, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC9, 0xDD, 0x44, 0x98, 0x7D, 0x9F, - 0xB1, 0x91, 0xA0, 0x42, 0x43, 0x4D, 0xC4, 0x45, 0xAB, 0x45, 0xE3, 0xC3, 0x6D, 0xF7, 0xDC, 0xCA, - 0x2D, 0xC8, 0x73, 0xAB, 0x07, 0x82, 0x5F, 0x06, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC0, 0x3C, 0xB7, - 0x66, 0xC0, 0xEC, 0x9E, 0x67, 0x43, 0x41, 0xC5, 0x46, 0x7C, 0x22, 0x2E, 0x5A, 0x2D, 0x1E, 0x1F, - 0xE1, 0x86, 0xAF, 0x73, 0x0F, 0xA4, 0x8F, 0x06, 0xBF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x81, - 0xF7, 0xEC, 0x4D, 0x77, 0x99, 0x9D, 0x97, 0xD8, 0x58, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x8B, 0x56, - 0x53, 0xE1, 0x11, 0x6E, 0xD7, 0xA7, 0xB9, 0x05, 0x01, 0x00, 0x00, 0x00, 0xA6, 0x1B, 0xEF, 0xF0, - 0x8D, 0x1B, 0x74, 0x70, 0x44, 0x27, 0xE2, 0xA2, 0xD5, 0x54, 0x74, 0xC4, 0xC7, 0x2D, 0x08, 0x00, - 0x00, 0x00, 0x30, 0xBD, 0x78, 0x07, 0xAF, 0x6F, 0xF1, 0x06, 0x2C, 0x11, 0x17, 0xAD, 0xA6, 0x62, - 0x43, 0xCD, 0x7D, 0xF6, 0x88, 0xBB, 0x05, 0x39, 0x7C, 0xE3, 0xBA, 0xE0, 0x97, 0x03, 0x00, 0x00, - 0x00, 0xA0, 0xCC, 0xBC, 0x03, 0xD7, 0x9D, 0xD4, 0xE1, 0xE1, 0x26, 0xE2, 0xA2, 0xD5, 0x54, 0x68, - 0x34, 0xDB, 0xFE, 0x2B, 0xDD, 0x1B, 0xB1, 0x4E, 0x06, 0xBF, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x65, - 0xD6, 0xF8, 0x0D, 0x58, 0x22, 0x2E, 0x5A, 0x4D, 0x05, 0x46, 0xAB, 0xB9, 0x5B, 0x90, 0xC3, 0x37, - 0x70, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x94, 0x9D, 0xFF, 0x06, 0xAC, 0xA1, 0x05, 0x36, 0x1E, 0x3A, - 0x14, 0x1F, 0xFE, 0x3E, 0x68, 0x5C, 0x04, 0x79, 0x87, 0x6E, 0x18, 0x37, 0xA3, 0xFD, 0xB3, 0x82, - 0x5F, 0x1A, 0x00, 0x00, 0x00, 0x80, 0xB2, 0x71, 0xB7, 0x0E, 0x66, 0xD7, 0x1C, 0x1B, 0x10, 0x1D, - 0x8C, 0x0F, 0x37, 0xF7, 0xD7, 0x3D, 0xB4, 0xD2, 0x98, 0xC3, 0xAB, 0xD7, 0x07, 0xBF, 0x34, 0x00, - 0x00, 0x00, 0x00, 0x65, 0x63, 0x03, 0x64, 0xBD, 0xD9, 0x7E, 0x71, 0x25, 0x00, 0x3A, 0x15, 0x1F, - 0xE1, 0xF6, 0x5E, 0xC6, 0x2D, 0x08, 0x00, 0x00, 0x00, 0x50, 0x66, 0xDE, 0xC8, 0xCA, 0xA1, 0xAE, - 0x88, 0x0F, 0xB7, 0xE0, 0x16, 0xC4, 0x3B, 0xBC, 0x7A, 0x43, 0xF0, 0xCB, 0x03, 0x00, 0x00, 0x00, - 0x50, 0x26, 0xDE, 0xC1, 0x6B, 0xC7, 0xBA, 0x22, 0x3E, 0xC2, 0xED, 0xEE, 0xAB, 0x3C, 0x90, 0x3E, - 0xB2, 0x66, 0x76, 0xF0, 0x4B, 0x04, 0x00, 0x00, 0x00, 0x50, 0x16, 0x66, 0xFF, 0x67, 0x75, 0x5C, - 0xB4, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0xD1, 0x11, 0xDF, 0xC8, 0x0A, 0xE3, 0x1D, 0x5A, 0x3D, 0x18, - 0xFC, 0x12, 0x01, 0x00, 0x00, 0x00, 0x94, 0x81, 0xBB, 0x65, 0x30, 0xFB, 0x2E, 0xD7, 0x81, 0xD1, - 0x6C, 0x32, 0x2C, 0x92, 0x4C, 0xC4, 0x86, 0x1A, 0xB7, 0x20, 0x00, 0x00, 0x00, 0x40, 0xF9, 0x98, - 0xE7, 0x56, 0x0F, 0x98, 0x5D, 0x97, 0xEA, 0xC8, 0x68, 0x34, 0x19, 0x16, 0x49, 0x26, 0x42, 0xA3, - 0xD9, 0x0E, 0x7E, 0xCE, 0x78, 0x87, 0x6F, 0x18, 0x0D, 0x7E, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x7A, - 0x9D, 0xFF, 0x06, 0xAC, 0x1D, 0x9F, 0xD0, 0xA1, 0xA1, 0x26, 0xC3, 0x22, 0xC9, 0x44, 0x60, 0xB4, - 0xDA, 0xCE, 0x4B, 0x82, 0x5B, 0x90, 0xD5, 0x03, 0xC1, 0x2F, 0x17, 0x00, 0x00, 0x00, 0x40, 0x2F, - 0xF3, 0x9E, 0xBD, 0x61, 0x50, 0x86, 0x86, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0x71, 0x91, 0x74, 0x07, - 0xAF, 0x35, 0xDE, 0xE1, 0x55, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x65, 0xE0, 0x1D, 0xBC, 0x6E, - 0x54, 0xC6, 0x46, 0x7C, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, 0x6D, 0xF9, 0x80, 0x31, 0x3B, - 0x67, 0xBB, 0x0F, 0x26, 0x34, 0xE6, 0xD0, 0xAA, 0xB5, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, 0x40, - 0xAF, 0xF2, 0x0E, 0x5C, 0x33, 0x2E, 0x83, 0x23, 0x3A, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, - 0x5C, 0x7C, 0x84, 0xDB, 0x77, 0x85, 0xFB, 0x5C, 0x90, 0x93, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, - 0x40, 0x2F, 0x72, 0x9F, 0x36, 0xDE, 0xF2, 0x0D, 0x58, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, - 0x45, 0xE3, 0xC3, 0x6D, 0xDB, 0xC7, 0x2A, 0xB7, 0x20, 0x87, 0x57, 0xAD, 0x0B, 0x7E, 0xE9, 0x00, - 0x00, 0x00, 0x00, 0x7A, 0x8D, 0xFF, 0x06, 0xAC, 0xDD, 0x73, 0xEB, 0xA3, 0x23, 0x9C, 0x0C, 0x8B, - 0x24, 0x13, 0x51, 0x91, 0x74, 0xF1, 0xF8, 0x08, 0xC7, 0x2D, 0x08, 0x00, 0x00, 0x00, 0xD0, 0xDB, - 0xCC, 0xE1, 0x1B, 0xD7, 0x35, 0x7C, 0x05, 0xAF, 0x0C, 0x8B, 0x24, 0x13, 0x51, 0x91, 0x74, 0x2A, - 0x3C, 0xC2, 0x6D, 0xB5, 0xBF, 0xA6, 0x43, 0x03, 0xEE, 0x26, 0x64, 0x7D, 0xF0, 0xCB, 0x07, 0x00, - 0x00, 0x00, 0xD0, 0x4B, 0xFC, 0x57, 0xF0, 0xF6, 0x42, 0x7C, 0x84, 0xDB, 0xB3, 0xD8, 0x7D, 0x3A, - 0xFA, 0xB8, 0xFB, 0xD6, 0xB1, 0xE0, 0xB7, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x57, 0x78, 0xC3, 0xCB, - 0xEB, 0xDF, 0x80, 0x25, 0xC3, 0x22, 0xC9, 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x0D, 0x35, 0x6E, 0x41, - 0x00, 0x00, 0x00, 0x80, 0xDE, 0xE5, 0x1D, 0xBC, 0x76, 0xAC, 0x67, 0xE2, 0x23, 0xDC, 0x9E, 0x45, - 0xC6, 0x3B, 0xB4, 0x6A, 0xDC, 0x8C, 0xF4, 0xCF, 0x0E, 0x7E, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x7A, - 0x81, 0xD9, 0x7F, 0x45, 0x6F, 0xC5, 0x87, 0xBF, 0xF7, 0x1B, 0x33, 0xB2, 0xCC, 0x46, 0xC8, 0xCA, - 0xC1, 0xE0, 0xB7, 0x01, 0x00, 0x00, 0x00, 0xA0, 0xDB, 0x99, 0xC3, 0x37, 0x2E, 0x71, 0xB7, 0x09, - 0x3D, 0x17, 0x1F, 0x6E, 0xEE, 0xCD, 0x5D, 0x87, 0x57, 0xD9, 0x10, 0xE9, 0xCD, 0x5B, 0x10, 0xF7, - 0xEB, 0xB6, 0x1B, 0x08, 0xC6, 0x4D, 0x0E, 0x00, 0x00, 0x00, 0xCA, 0xCF, 0x1C, 0xBA, 0x69, 0xAD, - 0xFF, 0x06, 0x2C, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x5A, 0x10, 0x1F, - 0xE1, 0x7A, 0xEC, 0x16, 0xC4, 0xFF, 0xCC, 0x95, 0x91, 0xFE, 0xF5, 0xDE, 0xA1, 0x81, 0x93, 0xFE, - 0x73, 0x2C, 0x91, 0xF9, 0xFF, 0x9A, 0xFD, 0xF7, 0x78, 0xB8, 0x1E, 0x00, 0x00, 0x00, 0xA5, 0x55, - 0x79, 0x03, 0xD6, 0x47, 0x6D, 0x10, 0xA8, 0xB8, 0x68, 0x35, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, - 0xD5, 0x62, 0xF1, 0xE1, 0xB6, 0xF3, 0x53, 0xC1, 0x2D, 0xC8, 0xEA, 0x81, 0xE0, 0xB7, 0xD4, 0xB5, - 0xCC, 0xA1, 0xFE, 0xB5, 0xDE, 0xC8, 0xC0, 0x78, 0x3C, 0x3C, 0xE2, 0xAB, 0xFC, 0x67, 0xFA, 0xD7, - 0x06, 0xFF, 0x35, 0x00, 0x00, 0x00, 0xA0, 0x3C, 0xBC, 0x67, 0x6F, 0x18, 0xD4, 0x71, 0xD1, 0x6A, - 0x22, 0x2A, 0x92, 0x4E, 0xC6, 0x45, 0xAB, 0x89, 0xF8, 0x08, 0x77, 0xF0, 0x1A, 0xE3, 0x1D, 0x5E, - 0x39, 0x1A, 0xFC, 0x96, 0xBA, 0x92, 0x19, 0xE9, 0x5F, 0x57, 0x8D, 0x8C, 0x91, 0xE5, 0xFE, 0x43, - 0xF4, 0x66, 0xC7, 0xC7, 0x6B, 0xE7, 0xFE, 0x35, 0xF7, 0xEF, 0xF9, 0xFF, 0x99, 0x7E, 0x37, 0x3E, - 0xF1, 0x1D, 0x00, 0x00, 0x00, 0xE5, 0xE2, 0x1D, 0xB8, 0x7A, 0x54, 0x07, 0x46, 0xB3, 0x89, 0xA8, - 0x48, 0x3A, 0x19, 0x17, 0xAD, 0x26, 0xA2, 0x23, 0xBA, 0x2E, 0xBF, 0x05, 0xB1, 0x21, 0x31, 0xBB, - 0x7A, 0xF3, 0x31, 0x34, 0xBF, 0xF2, 0x6B, 0xDE, 0x3C, 0x4B, 0xCF, 0xFD, 0x7B, 0x43, 0x7D, 0x7E, - 0x80, 0x78, 0x23, 0x2B, 0x78, 0xCB, 0x17, 0x00, 0x00, 0x00, 0xCA, 0xC5, 0xEC, 0xBF, 0xD2, 0x86, - 0x81, 0x8A, 0x8C, 0x46, 0x13, 0x51, 0x91, 0x74, 0x32, 0x2E, 0x5A, 0x2D, 0x12, 0x1A, 0xCD, 0xE6, - 0x6E, 0x41, 0x0E, 0xAD, 0x1A, 0x0B, 0x7E, 0x5B, 0x5D, 0xC5, 0xC6, 0xC7, 0x90, 0x1F, 0x1F, 0xBB, - 0x3E, 0xAD, 0xA3, 0xA3, 0x66, 0x17, 0x55, 0xB6, 0xF3, 0x92, 0x4A, 0x84, 0x0C, 0xAF, 0xE8, 0xEA, - 0x9B, 0x1D, 0x00, 0x00, 0x00, 0x20, 0x31, 0xFF, 0x81, 0xE8, 0xBD, 0x97, 0xDB, 0x38, 0x50, 0xA1, - 0xA1, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x9A, 0x08, 0x8D, 0x46, 0x73, 0xCF, 0xB1, 0xB8, - 0x5B, 0x90, 0xC3, 0xAB, 0xBA, 0xEA, 0xDB, 0x96, 0x6C, 0x44, 0x0C, 0xF8, 0xF1, 0xE1, 0xDE, 0xD8, - 0x25, 0x83, 0x23, 0xBA, 0x20, 0x3E, 0x62, 0x11, 0xE2, 0x7E, 0x8E, 0xE0, 0xA7, 0x03, 0x00, 0x00, - 0x00, 0x7A, 0x97, 0x79, 0x6E, 0xF5, 0x80, 0x7F, 0x30, 0x96, 0xB1, 0x11, 0x9F, 0x88, 0x8A, 0xA4, - 0x93, 0x71, 0xD1, 0x6A, 0x22, 0x32, 0x5A, 0x6D, 0xDF, 0x12, 0xE3, 0x1D, 0x5E, 0x75, 0x32, 0xF8, - 0xED, 0x75, 0x05, 0xEF, 0xD0, 0xC0, 0xA8, 0x39, 0x70, 0x55, 0x10, 0x18, 0xCD, 0x16, 0x8B, 0x8F, - 0x70, 0xFB, 0xAF, 0xE4, 0x16, 0x04, 0x00, 0x00, 0x00, 0xE5, 0xE0, 0x3D, 0x7B, 0xC3, 0x5D, 0x66, - 0xC7, 0xA7, 0x6C, 0x24, 0xA8, 0xE0, 0x88, 0x4E, 0x44, 0x45, 0xD2, 0xC9, 0xB8, 0x68, 0x35, 0x11, - 0x17, 0x49, 0x16, 0xDC, 0x82, 0x78, 0x87, 0x56, 0xDD, 0x15, 0xFC, 0x16, 0x3B, 0xAA, 0x7A, 0xFB, - 0xE1, 0x1E, 0x30, 0x97, 0xD1, 0x11, 0x4E, 0x84, 0x47, 0xB8, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, - 0x00, 0x80, 0x72, 0xF0, 0x0E, 0xDF, 0xB8, 0x41, 0x07, 0x47, 0x74, 0x22, 0x2A, 0x92, 0x4E, 0xC6, - 0x45, 0xAB, 0x89, 0xB0, 0x48, 0xB3, 0x3D, 0x0B, 0x8D, 0x37, 0xB2, 0x72, 0xBC, 0x1B, 0x3E, 0x4B, - 0x23, 0xD9, 0xED, 0x87, 0x88, 0x8E, 0xF8, 0xB8, 0x05, 0x01, 0x00, 0x00, 0x40, 0x19, 0x78, 0x07, - 0xAF, 0x6B, 0xF1, 0x06, 0x2C, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, 0xD5, 0x44, 0x50, 0xA4, 0xDA, - 0x1F, 0x57, 0xFE, 0xDA, 0x23, 0x2B, 0xEC, 0x56, 0xAE, 0x0F, 0x7E, 0x9B, 0x1D, 0xE1, 0x3E, 0xC7, - 0xC3, 0xBF, 0xFD, 0x70, 0x7F, 0x1F, 0x65, 0x78, 0xB8, 0x89, 0xD8, 0x50, 0xF3, 0x7F, 0x4F, 0xFD, - 0xC6, 0x1C, 0xE4, 0xB3, 0x41, 0x00, 0x00, 0x00, 0xD0, 0xC3, 0xBC, 0x03, 0x9F, 0x3B, 0x59, 0x1F, - 0x1D, 0xE1, 0x22, 0x31, 0x91, 0x76, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xD9, 0xF8, 0x08, - 0xD7, 0x05, 0xB7, 0x20, 0xFE, 0xA7, 0x9A, 0xBB, 0x07, 0xFC, 0x65, 0x78, 0xB8, 0x89, 0xD0, 0x68, - 0xB6, 0xBD, 0x97, 0xB9, 0x5B, 0x90, 0xAE, 0x7A, 0xBE, 0x05, 0x00, 0x00, 0x00, 0x48, 0xA5, 0xF1, - 0x1B, 0xB0, 0x44, 0x54, 0x24, 0x9D, 0x8C, 0x8B, 0x56, 0x53, 0x41, 0x91, 0x66, 0x91, 0xF8, 0x70, - 0x73, 0xBF, 0x8E, 0xE1, 0xA5, 0xEE, 0x13, 0xC5, 0x37, 0x04, 0xBF, 0xD5, 0x29, 0x65, 0xC2, 0x0F, - 0x1D, 0x74, 0x7F, 0x2F, 0xF3, 0x88, 0x0F, 0x37, 0xF7, 0x7B, 0xF2, 0x9F, 0x05, 0x59, 0xCE, 0x87, - 0x13, 0x02, 0x00, 0x00, 0xA0, 0xF7, 0xF8, 0x6F, 0xC0, 0x72, 0x1F, 0x8A, 0x57, 0xB6, 0xF8, 0x08, - 0xB7, 0x6B, 0x8E, 0x31, 0x87, 0x56, 0xBA, 0x43, 0xFB, 0x94, 0x7F, 0x90, 0x5F, 0xF3, 0xDB, 0x0F, - 0x11, 0x17, 0x49, 0xB7, 0x67, 0xB1, 0xF1, 0x86, 0x97, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x80, 0xDE, - 0x63, 0x0E, 0xDD, 0xB4, 0xD6, 0xFF, 0x60, 0xBC, 0x32, 0xC6, 0x47, 0x38, 0x77, 0x0B, 0x72, 0x68, - 0xE5, 0x60, 0xF0, 0x5B, 0x9E, 0x12, 0xCD, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0xDD, 0x33, 0x17, 0xDA, - 0xDF, 0x93, 0xFD, 0x7B, 0x66, 0x7F, 0x4F, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0xE7, 0x98, 0xC3, - 0x37, 0xAE, 0xF7, 0x5F, 0x5B, 0x5B, 0xD6, 0xF8, 0x70, 0x0B, 0x6F, 0x41, 0x0E, 0xF7, 0x2F, 0x09, - 0x7E, 0xDB, 0x85, 0x72, 0xCF, 0x9C, 0xF8, 0xB7, 0x1F, 0xEE, 0x66, 0x29, 0xEF, 0xF8, 0x08, 0xB7, - 0x7B, 0x9E, 0xF1, 0x46, 0x96, 0x8F, 0x9B, 0xA1, 0xCE, 0xBF, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, - 0xCC, 0x1B, 0x59, 0x39, 0x54, 0xEA, 0xF8, 0x08, 0x77, 0xE0, 0x6A, 0x77, 0x0B, 0x32, 0x25, 0xAF, - 0xB0, 0x35, 0x23, 0xFD, 0xEB, 0xCD, 0xC8, 0x72, 0xFB, 0xD7, 0xB5, 0xBF, 0xC6, 0x22, 0xE2, 0xC3, - 0x6D, 0xF3, 0xFB, 0xC2, 0x5B, 0x90, 0x8E, 0xBE, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, 0xC5, 0xDB, - 0x7F, 0xED, 0x58, 0xE9, 0xE3, 0xC3, 0x6D, 0xC7, 0x27, 0xC3, 0x67, 0x41, 0x0A, 0xFD, 0x20, 0x3F, - 0xFF, 0xF6, 0x63, 0x64, 0x60, 0xBC, 0xFE, 0xF6, 0x43, 0x44, 0x45, 0xD2, 0xC5, 0xE3, 0x23, 0x1C, - 0xB7, 0x20, 0x00, 0x00, 0x00, 0xE8, 0x35, 0x66, 0xDF, 0x12, 0x1D, 0x15, 0x49, 0x27, 0xE3, 0xA2, - 0xD5, 0x54, 0x50, 0xA4, 0x99, 0x08, 0x8C, 0x56, 0x73, 0x37, 0x06, 0x53, 0x70, 0x0B, 0xA2, 0x6F, - 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8F, 0x70, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0x97, 0x98, - 0x91, 0x35, 0xB3, 0xDD, 0xE7, 0x4A, 0xC8, 0xB0, 0x48, 0x32, 0x19, 0x17, 0xAD, 0x16, 0x8F, 0x89, - 0xB4, 0x13, 0x71, 0xD1, 0x6A, 0xEE, 0xA0, 0xEE, 0xB6, 0xED, 0x63, 0x95, 0x5B, 0x90, 0x43, 0xC5, - 0x7C, 0x90, 0x9F, 0xBE, 0xFD, 0x10, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0xE2, 0xE3, 0x16, 0x04, 0x00, - 0x00, 0x00, 0xBD, 0xC2, 0x8C, 0xAC, 0x1E, 0x30, 0x3B, 0x2F, 0xD1, 0x71, 0xD1, 0x6A, 0x32, 0x2E, - 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0x30, 0x3E, 0xC2, 0xED, 0xFD, 0x8C, 0xBB, - 0x05, 0x29, 0xE4, 0x15, 0xB6, 0xEE, 0xF3, 0x46, 0xCC, 0xF0, 0xF5, 0xF6, 0xAF, 0x33, 0x45, 0xF1, - 0x11, 0xEE, 0xE0, 0xE7, 0x6C, 0x84, 0xAC, 0xE8, 0xC8, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x89, - 0x99, 0xC3, 0xAB, 0xD7, 0x9B, 0xED, 0x17, 0xEB, 0xC0, 0x68, 0x36, 0x19, 0x17, 0xAD, 0xA6, 0x82, - 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x5A, 0x3C, 0x3E, 0xDC, 0xB6, 0x7E, 0x38, 0x7C, 0x16, 0x24, 0xD7, - 0x57, 0xD8, 0xDA, 0x9F, 0x6F, 0xB6, 0xFF, 0xDA, 0x5D, 0xF7, 0x4A, 0xE3, 0xA9, 0x8C, 0x0F, 0xB7, - 0x9D, 0xB3, 0xED, 0xEF, 0x67, 0x85, 0xFB, 0x3D, 0x4D, 0xF9, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, - 0x89, 0x79, 0x87, 0x57, 0x6F, 0x90, 0x81, 0xD1, 0x6C, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, - 0x89, 0xB8, 0x68, 0x35, 0x15, 0x1F, 0xE1, 0x82, 0x5B, 0x10, 0xF7, 0x2D, 0x53, 0xC1, 0xDF, 0x8A, - 0xB6, 0x79, 0x87, 0x06, 0x06, 0x27, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8C, 0x24, 0x73, - 0xB7, 0x20, 0xC3, 0x2B, 0xA6, 0xF4, 0xB3, 0x4E, 0x00, 0x00, 0x00, 0x80, 0x54, 0xBC, 0x83, 0x9F, - 0x1B, 0x95, 0x91, 0xD1, 0x68, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0x35, - 0x15, 0x1D, 0xD1, 0xB9, 0x5F, 0x97, 0x7F, 0x63, 0xB0, 0x32, 0x97, 0x87, 0xB7, 0x6B, 0x6F, 0x3F, - 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8B, 0xA4, 0xE3, 0x16, 0x04, 0x00, 0x00, 0x00, 0xDD, 0xCE, 0xDB, - 0x7F, 0xD5, 0xB8, 0x0C, 0x0D, 0xB5, 0xBA, 0xB0, 0x48, 0x32, 0x15, 0x14, 0x69, 0x26, 0xE2, 0xA2, - 0xD5, 0x54, 0x70, 0xA8, 0x0D, 0x2D, 0x30, 0xDE, 0xC8, 0xCA, 0xF1, 0x3C, 0x6E, 0x41, 0xFC, 0xDB, - 0x8F, 0x03, 0xD7, 0xDA, 0x9F, 0x57, 0x44, 0x45, 0xD2, 0xA9, 0xA8, 0x48, 0x3B, 0xF7, 0x96, 0xAF, - 0xE1, 0x65, 0xDC, 0x82, 0x34, 0x60, 0xC6, 0xFE, 0xC3, 0x2C, 0xF3, 0xF2, 0xBF, 0x5F, 0x67, 0x4E, - 0x7C, 0x65, 0x7D, 0x64, 0x6B, 0xDD, 0xBF, 0x1E, 0xFC, 0x47, 0x00, 0x00, 0x00, 0x50, 0x14, 0x77, - 0xF0, 0x4E, 0xFC, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, - 0x0A, 0x8D, 0x46, 0x73, 0xBF, 0xC6, 0x1C, 0x6E, 0x41, 0xDC, 0xA7, 0xAB, 0xFB, 0xB7, 0x1F, 0xEE, - 0x59, 0x1A, 0x15, 0x16, 0x49, 0xA6, 0x62, 0x22, 0xCB, 0xB6, 0x7F, 0xD4, 0xFE, 0x7E, 0x96, 0xDB, - 0x2D, 0x2D, 0xF4, 0xB3, 0x4E, 0x7A, 0x8D, 0x0B, 0x0C, 0xEF, 0xC4, 0x97, 0x07, 0xCD, 0x2F, 0xBE, - 0x62, 0xE4, 0x4E, 0x7C, 0xC9, 0xF8, 0xFF, 0x3E, 0x21, 0x02, 0x00, 0x00, 0x50, 0x1C, 0xFF, 0x0D, - 0x58, 0xBB, 0xE6, 0xE8, 0xE0, 0x88, 0xAE, 0x2E, 0x2C, 0x92, 0x4C, 0x05, 0x45, 0x9A, 0x89, 0xB8, - 0x68, 0x35, 0x15, 0x19, 0xAD, 0xE6, 0xBF, 0xC2, 0x76, 0xE5, 0x78, 0x3B, 0xDF, 0xB6, 0xE4, 0x1D, - 0x1A, 0x18, 0x35, 0xFB, 0xAF, 0xB4, 0x3F, 0x9F, 0x08, 0x8B, 0x24, 0x53, 0x21, 0x91, 0x69, 0x33, - 0x2B, 0xDB, 0x7F, 0x85, 0xF1, 0x86, 0x97, 0x4F, 0xC9, 0x27, 0xBE, 0xF7, 0x02, 0x73, 0xFC, 0xDF, - 0x2F, 0xF1, 0x7E, 0xF1, 0xE5, 0xF1, 0xDA, 0xE0, 0xB8, 0xDD, 0x98, 0xE3, 0x5F, 0xF4, 0xC3, 0x23, - 0xFA, 0xAF, 0xFB, 0xFF, 0x39, 0xFB, 0x9F, 0x0F, 0xFE, 0xAB, 0x00, 0x00, 0x00, 0xC8, 0x93, 0x39, - 0x7C, 0xE3, 0xBA, 0x96, 0xAF, 0xE0, 0x95, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, - 0xAB, 0xA9, 0xB8, 0x48, 0xBA, 0xE1, 0xEB, 0x8D, 0xFB, 0x16, 0xAA, 0xE0, 0x6F, 0x4B, 0x2A, 0x36, - 0x5C, 0x06, 0xEC, 0xB2, 0xDF, 0x7E, 0xC8, 0x90, 0xC8, 0xB2, 0x20, 0x3E, 0xDC, 0xB8, 0x05, 0xA9, - 0xAA, 0x89, 0x0F, 0x17, 0x1D, 0x2F, 0xD9, 0xFF, 0xAD, 0x5E, 0xB0, 0xB1, 0xF8, 0xFC, 0x92, 0xC9, - 0xBD, 0x70, 0xB5, 0xFD, 0xD7, 0x57, 0x55, 0xFE, 0x7D, 0x22, 0x04, 0x00, 0x00, 0xA0, 0x38, 0xFE, - 0x2B, 0x78, 0x55, 0x74, 0x84, 0x93, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, - 0xA9, 0xA8, 0x48, 0xBC, 0x59, 0x95, 0x07, 0xC7, 0xDD, 0xB7, 0x50, 0x65, 0xB8, 0x05, 0xF1, 0x86, - 0x57, 0x64, 0xBF, 0xFD, 0x90, 0x21, 0x91, 0x65, 0x91, 0xF8, 0x08, 0xC7, 0x2D, 0x48, 0x6D, 0x7C, - 0x1C, 0xB9, 0xB1, 0x36, 0x3A, 0xD4, 0x5C, 0x98, 0x1C, 0xFD, 0x42, 0x25, 0x42, 0x4E, 0x7C, 0x85, - 0x1B, 0x24, 0x00, 0x00, 0x80, 0xBC, 0x79, 0x07, 0x97, 0x35, 0x7E, 0x03, 0x96, 0x8C, 0x8B, 0x56, - 0x53, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0x85, 0x1F, 0x16, 0x68, 0xE7, - 0x6E, 0x41, 0x46, 0x06, 0x86, 0x82, 0xBF, 0x35, 0x89, 0xB4, 0x75, 0xFB, 0x21, 0x43, 0x22, 0xCB, - 0x44, 0x7C, 0xB8, 0x6D, 0xFD, 0xD0, 0xB4, 0xBE, 0x05, 0xA9, 0x89, 0x0F, 0x77, 0xEB, 0xA1, 0x82, - 0xA3, 0xD1, 0x5C, 0xAC, 0xF8, 0x37, 0x26, 0x5F, 0x29, 0xE4, 0xD3, 0xF2, 0x01, 0x00, 0x00, 0xA6, - 0x2D, 0x6F, 0xFF, 0x35, 0x63, 0xC4, 0x47, 0xB0, 0xED, 0x1F, 0xB7, 0x87, 0x75, 0xFF, 0x16, 0x24, - 0xF1, 0x81, 0xDD, 0x1B, 0x59, 0x31, 0xE6, 0x3F, 0xC4, 0xAF, 0x02, 0xA3, 0xD9, 0x64, 0x48, 0x64, - 0x99, 0x08, 0x8F, 0xE8, 0xF6, 0x2C, 0xB2, 0x51, 0xB5, 0x7C, 0x2C, 0xF8, 0xE5, 0x4E, 0x1B, 0x6D, - 0xC5, 0x47, 0xB8, 0x63, 0x7F, 0xE2, 0x3F, 0x94, 0x1E, 0xFC, 0x94, 0x00, 0x00, 0x00, 0xC8, 0x83, - 0xD9, 0xF7, 0x19, 0xE2, 0xC3, 0xED, 0x99, 0x60, 0xFB, 0xAF, 0x32, 0xDE, 0xF0, 0x40, 0xA2, 0x6F, - 0xBD, 0xB1, 0xA1, 0xB2, 0xCE, 0xBF, 0xFD, 0x70, 0x7F, 0xCF, 0x54, 0x64, 0x34, 0x9A, 0x0C, 0x89, - 0x2C, 0x13, 0xC1, 0x11, 0x9F, 0xFB, 0x7B, 0xEB, 0xDF, 0x82, 0x2C, 0xCF, 0xF5, 0x13, 0xDF, 0xBB, - 0x59, 0x2E, 0xF1, 0xE1, 0xF6, 0xC2, 0xD5, 0xEE, 0xDB, 0xB0, 0x4E, 0x06, 0x3F, 0x2D, 0x00, 0x00, - 0x00, 0xDA, 0x65, 0x0E, 0xDF, 0xB8, 0xC4, 0x0C, 0x2D, 0x9C, 0xBE, 0xF1, 0x11, 0x46, 0x47, 0xF0, - 0x7F, 0x7B, 0x6E, 0xDB, 0x3F, 0xEE, 0xBE, 0x0D, 0x2B, 0xD1, 0x2D, 0x88, 0x37, 0xBC, 0xE2, 0x64, - 0xEA, 0xDB, 0x0F, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, 0xD1, 0xDC, 0x2D, 0xC8, 0xF0, 0xB2, 0x69, - 0x71, 0x90, 0xCE, 0x2D, 0x3E, 0xC2, 0x1D, 0xBB, 0xC5, 0x04, 0x3F, 0x35, 0x00, 0x00, 0x00, 0xDA, - 0x65, 0x0E, 0xAD, 0x5A, 0x5B, 0xF3, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, - 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0xAB, 0x8F, 0x0F, 0x3F, 0x3C, 0xC2, 0x6D, 0xB2, 0xDB, 0x7B, - 0x85, 0x39, 0x3F, 0x3C, 0xD0, 0xF4, 0xC0, 0x9E, 0xE9, 0xF6, 0x43, 0x86, 0x44, 0x96, 0x89, 0xC8, - 0x68, 0x36, 0xF7, 0xF7, 0x79, 0x1A, 0xDC, 0x82, 0xE4, 0x1E, 0x1F, 0xCF, 0x7F, 0xC6, 0x98, 0x23, - 0x37, 0x18, 0xF3, 0xF2, 0x9D, 0x7C, 0x9E, 0x0A, 0x00, 0x00, 0x40, 0x1E, 0xFC, 0x37, 0x60, 0x6D, - 0xFB, 0xC8, 0xF4, 0x8D, 0x8F, 0x68, 0x78, 0xB8, 0xB9, 0xF8, 0x70, 0xDB, 0xFC, 0x21, 0xF7, 0x6D, - 0x58, 0xEE, 0x16, 0xA4, 0xE1, 0x81, 0xDD, 0xBF, 0xFD, 0xD8, 0xB3, 0xD0, 0xFE, 0x7C, 0x22, 0x34, - 0xD4, 0x64, 0x48, 0x64, 0x99, 0x08, 0x8C, 0x24, 0x1B, 0x9A, 0x5F, 0xEA, 0x5B, 0x90, 0x42, 0xE2, - 0xC3, 0x6D, 0xEC, 0x3A, 0x17, 0x20, 0xD3, 0xE6, 0xDB, 0xD7, 0x00, 0x00, 0x00, 0x0A, 0xE5, 0x1D, - 0x5A, 0x3D, 0x38, 0xED, 0xE2, 0x23, 0x12, 0x20, 0xD5, 0xE8, 0x88, 0xC4, 0xC7, 0xF9, 0x70, 0x43, - 0x97, 0x9B, 0x73, 0x07, 0xF5, 0x2D, 0xC8, 0xF9, 0x91, 0xFE, 0xF5, 0x66, 0x78, 0x99, 0xFD, 0xB9, - 0xDC, 0xAF, 0x49, 0xC4, 0x46, 0x7C, 0x32, 0x24, 0xB2, 0x4C, 0x84, 0x45, 0xD2, 0xB9, 0xDF, 0xF7, - 0xF0, 0xF5, 0xEE, 0x16, 0xA4, 0xAD, 0x4F, 0x7C, 0xEF, 0x46, 0x85, 0xC5, 0x87, 0xDB, 0x0B, 0x57, - 0x19, 0x73, 0xE2, 0xCE, 0xD2, 0xFD, 0x3D, 0x03, 0x00, 0x00, 0xE8, 0x08, 0x6F, 0xDF, 0x55, 0xA3, - 0x3A, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xC5, 0xC2, 0x22, 0xC9, 0x64, 0x54, 0x24, 0x5D, 0x24, - 0x3E, 0x82, 0xD5, 0xDC, 0x78, 0x84, 0xD1, 0xF1, 0x74, 0x64, 0x9B, 0x3F, 0x64, 0xCE, 0x1F, 0x5C, - 0x6E, 0xCE, 0x0D, 0xF7, 0xDF, 0x15, 0xFC, 0xED, 0xF2, 0x99, 0xA1, 0xFE, 0x59, 0xE7, 0x47, 0x56, - 0x8C, 0x9B, 0xDD, 0x7D, 0xF6, 0x60, 0x2F, 0x62, 0x23, 0x3E, 0x19, 0x12, 0x59, 0x26, 0xA2, 0x22, - 0xED, 0x76, 0xCF, 0x35, 0xDE, 0xC8, 0xB2, 0x71, 0xF7, 0x7B, 0x08, 0x7E, 0x3B, 0x3D, 0xAF, 0xD0, - 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x9F, 0x07, 0x02, 0x00, 0x00, 0x90, 0x07, 0xB3, 0xEF, 0x0A, - 0x7B, 0xB8, 0x57, 0x81, 0xD1, 0x6C, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, 0x48, - 0xBA, 0x48, 0x78, 0x44, 0x6F, 0x3E, 0xE2, 0xB7, 0x1E, 0x7E, 0x78, 0xBC, 0xCF, 0x9C, 0x7B, 0x6A, - 0x72, 0xE7, 0x77, 0xCE, 0x77, 0xB7, 0x20, 0x35, 0x07, 0xF6, 0xF3, 0x07, 0xFB, 0xD7, 0x7B, 0xC3, - 0xCB, 0x8C, 0xE7, 0x6E, 0x3F, 0x5A, 0x05, 0x88, 0x0C, 0x89, 0x2C, 0x13, 0x31, 0x91, 0x76, 0x9B, - 0x66, 0xD8, 0x1F, 0xED, 0xAF, 0xA9, 0x44, 0xB7, 0x20, 0x53, 0x11, 0x1F, 0x6E, 0xDE, 0xD1, 0x5B, - 0xA6, 0xDD, 0x6B, 0x8C, 0x01, 0x00, 0x00, 0x72, 0x67, 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x8B, 0xED, - 0x01, 0x5F, 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x58, 0x24, 0x99, 0x8C, 0x8A, 0xA4, - 0x8B, 0xC4, 0x47, 0x83, 0x00, 0x09, 0xE3, 0xE3, 0x5C, 0x24, 0x3E, 0xCE, 0x6E, 0x0C, 0xF6, 0xD4, - 0xFB, 0xCD, 0xF9, 0x03, 0xCB, 0x8D, 0x8B, 0x0E, 0xFF, 0xEF, 0x99, 0x0D, 0x91, 0x73, 0xC3, 0x2B, - 0xC6, 0xBD, 0x5D, 0x7D, 0xF6, 0xBF, 0x7F, 0x91, 0x3F, 0xFF, 0x50, 0xAF, 0x42, 0x44, 0x86, 0x44, - 0x96, 0x89, 0x98, 0x48, 0x3B, 0x17, 0x1F, 0xE1, 0x4A, 0x72, 0x0B, 0x32, 0x55, 0xF1, 0xE1, 0xEF, - 0xE8, 0xE7, 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xBB, 0xCC, 0xC8, 0xEA, 0x01, 0xB3, 0xEB, 0x52, - 0x7B, 0xC8, 0x57, 0xA1, 0xA1, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, - 0x4B, 0x1F, 0x1F, 0xD5, 0xF0, 0x78, 0xD2, 0x6D, 0x96, 0xBF, 0x73, 0x3B, 0xE6, 0x9B, 0xB3, 0x07, - 0x2A, 0xB7, 0x20, 0x2E, 0x44, 0xCE, 0x1F, 0x5C, 0x66, 0xFF, 0xFB, 0x7F, 0xDC, 0x3C, 0x40, 0x64, - 0x48, 0x64, 0x99, 0x88, 0x89, 0xB4, 0x8B, 0xC6, 0x87, 0x9B, 0xFB, 0xB5, 0x1E, 0xBC, 0xB6, 0xA7, - 0x6F, 0x41, 0xA6, 0x34, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0xEC, 0x5F, 0x33, 0xF8, 0xCB, 0x03, 0x00, - 0x00, 0x20, 0x0B, 0xEF, 0xD0, 0xAA, 0xBB, 0xCC, 0xF6, 0x4F, 0xD8, 0x83, 0xBE, 0x8A, 0x8D, 0xF8, - 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, 0x74, 0xB1, 0xF8, 0x08, 0x02, 0x24, - 0x49, 0x7C, 0xBC, 0x6B, 0xE3, 0xE3, 0xDD, 0xC1, 0x59, 0x93, 0xDB, 0xF8, 0x7E, 0x73, 0x6E, 0xEF, - 0xF5, 0xE6, 0xDC, 0x81, 0x81, 0x51, 0xF7, 0xED, 0x58, 0xE7, 0xB7, 0x5F, 0x62, 0xFF, 0xBB, 0x36, - 0x3E, 0xDC, 0x54, 0x84, 0xC8, 0x90, 0xC8, 0x32, 0x11, 0x13, 0x69, 0x17, 0x8F, 0x8F, 0x70, 0x3B, - 0x3E, 0xE9, 0x02, 0xC4, 0xBD, 0xE5, 0x6B, 0x76, 0xF0, 0x8F, 0x43, 0xCF, 0x98, 0xF2, 0xF8, 0x70, - 0x1B, 0x5B, 0x66, 0xCC, 0x89, 0xAF, 0xAC, 0x0D, 0x7E, 0x09, 0x00, 0x00, 0x00, 0xC8, 0xC2, 0x3B, - 0xBC, 0x7A, 0x83, 0x8E, 0x8D, 0xF8, 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, - 0x74, 0x3A, 0x3E, 0xEA, 0x02, 0xC4, 0x86, 0x47, 0xF8, 0xCC, 0x47, 0x3C, 0x3E, 0x26, 0xDC, 0x9E, - 0xA8, 0xCC, 0xFD, 0xFF, 0x67, 0xB7, 0x7C, 0xDA, 0x4C, 0x3C, 0xD3, 0x6F, 0xCE, 0x0D, 0xD9, 0x10, - 0x79, 0xCA, 0xFD, 0x77, 0x2F, 0xD2, 0x11, 0xB2, 0x49, 0x85, 0x44, 0x96, 0x89, 0x98, 0x48, 0x3B, - 0x15, 0x1E, 0xD1, 0x1D, 0xBC, 0xD6, 0xBD, 0x96, 0x77, 0x30, 0xF8, 0xC7, 0xA1, 0x27, 0x74, 0x24, - 0x3E, 0xDC, 0x5E, 0xBC, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0xB4, 0xCB, 0x3B, 0x78, 0x4D, 0x82, - 0x37, 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0xE1, 0x11, - 0x2E, 0x1E, 0x1F, 0xE1, 0xED, 0x47, 0xE4, 0x99, 0x0F, 0x17, 0x1F, 0xD1, 0xF0, 0x98, 0x78, 0x3C, - 0x98, 0xFB, 0xBF, 0x1F, 0x9B, 0x65, 0x4E, 0x3F, 0x72, 0x9D, 0x39, 0xF3, 0xF0, 0x25, 0x7E, 0x80, - 0x9C, 0xF3, 0x1F, 0x58, 0x8F, 0x05, 0x88, 0x8B, 0x8F, 0x5C, 0x02, 0x44, 0xC4, 0x44, 0xDA, 0xA9, - 0xE0, 0x88, 0xAF, 0xC7, 0x6E, 0x41, 0x3A, 0x16, 0x1F, 0xC1, 0xBC, 0x5F, 0xDC, 0x39, 0x14, 0xFC, - 0x52, 0x00, 0x00, 0x00, 0x90, 0x85, 0xB7, 0xFF, 0xEA, 0x93, 0x3A, 0x3A, 0xC2, 0xA9, 0xA0, 0x48, - 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x78, 0xB8, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, - 0xDE, 0x7E, 0xD4, 0x7E, 0xEB, 0x55, 0x34, 0x3E, 0xCE, 0xD8, 0xE8, 0x38, 0xF3, 0xF8, 0xFB, 0x82, - 0x55, 0x22, 0xE4, 0xF4, 0xFD, 0x17, 0x99, 0x53, 0xF7, 0x5E, 0x6C, 0x4E, 0xDD, 0x7D, 0x91, 0x39, - 0x6B, 0xFF, 0x33, 0x75, 0xB7, 0x20, 0x36, 0x3C, 0xDC, 0xDA, 0x0F, 0x10, 0x11, 0x13, 0x69, 0xA7, - 0x62, 0xA3, 0xD1, 0x7A, 0xE4, 0x16, 0xA4, 0xD3, 0xF1, 0xE1, 0xE6, 0x1D, 0xFB, 0x53, 0xDE, 0x84, - 0x05, 0x00, 0x00, 0xD0, 0x8E, 0xE6, 0x6F, 0xC0, 0x52, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, - 0x46, 0x45, 0xD2, 0xC5, 0xA2, 0x23, 0xBA, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDC, 0x7E, 0xD4, 0x7C, - 0xDB, 0x55, 0x18, 0x1F, 0x8F, 0xD9, 0xF0, 0xB0, 0x3B, 0x1D, 0xFC, 0x78, 0xE6, 0x91, 0xF7, 0xF9, - 0xE1, 0x11, 0xEE, 0xF4, 0x7D, 0x36, 0x42, 0x36, 0x4E, 0x46, 0x88, 0xF7, 0x74, 0x25, 0x3E, 0xAA, - 0x01, 0x92, 0x39, 0x42, 0x44, 0x4C, 0xA4, 0x9D, 0x8A, 0x8C, 0x66, 0xDB, 0x7E, 0x71, 0xD7, 0xDF, - 0x82, 0x74, 0x43, 0x7C, 0xF8, 0x3B, 0x76, 0x0B, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xC8, 0xCA, 0x7F, - 0x03, 0xD6, 0xEE, 0x79, 0xF6, 0xE0, 0x5F, 0xFE, 0xF8, 0x70, 0x3F, 0x36, 0xBF, 0xFD, 0xB0, 0xF1, - 0xE1, 0x02, 0x24, 0x88, 0x0F, 0x17, 0x1E, 0xA7, 0x1F, 0x9D, 0xDC, 0xA9, 0x7B, 0x67, 0xD5, 0x04, - 0x88, 0xDB, 0xBB, 0x3F, 0x0E, 0x02, 0xE4, 0xA9, 0x0B, 0xED, 0xCF, 0x67, 0xE3, 0x23, 0x1E, 0x21, - 0x32, 0x30, 0x9A, 0x4D, 0xC4, 0x44, 0xDA, 0xA9, 0xC0, 0x48, 0xB2, 0x7D, 0x57, 0x18, 0x6F, 0x78, - 0x79, 0x57, 0x7E, 0xD0, 0x5E, 0xD7, 0xC4, 0x87, 0x9B, 0x7B, 0x13, 0xD6, 0xCB, 0x77, 0xF6, 0xDC, - 0x43, 0xFB, 0x00, 0x00, 0x00, 0x5D, 0xC1, 0x1C, 0x5A, 0xB5, 0xD6, 0xEC, 0x9C, 0x6D, 0x0F, 0xFF, - 0x25, 0x8E, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDD, 0x7E, 0xB8, 0xD7, 0xEC, 0x46, 0x6F, - 0x3F, 0xE2, 0xF1, 0x71, 0xFA, 0x81, 0xDA, 0xDB, 0x8F, 0x70, 0xEE, 0x16, 0xE4, 0xDC, 0x93, 0x76, - 0x1B, 0x2F, 0xF2, 0x23, 0xA4, 0x26, 0x40, 0x5C, 0x50, 0xA4, 0x8A, 0x10, 0x11, 0x13, 0x69, 0xA7, - 0xC2, 0x22, 0xE9, 0xB6, 0x7D, 0x24, 0xB8, 0x05, 0x59, 0x3A, 0x10, 0xFC, 0xE3, 0xD1, 0x15, 0xBA, - 0x2A, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0xB3, 0xAB, 0xFE, 0x1E, 0x01, 0x00, 0x00, 0xF4, - 0x0C, 0x73, 0x78, 0xF5, 0x7A, 0xB3, 0xF5, 0xC3, 0x36, 0x00, 0x4A, 0x1C, 0x1F, 0xC1, 0xD4, 0xED, - 0xC7, 0x59, 0x3F, 0x40, 0x6C, 0x7C, 0xB8, 0xDB, 0x8F, 0xC8, 0xB7, 0x5E, 0x55, 0xC3, 0xE3, 0xC7, - 0x95, 0xA9, 0xDB, 0x0F, 0x7F, 0x5F, 0xBF, 0xD0, 0xBC, 0xFB, 0x48, 0x25, 0x40, 0xCE, 0xB5, 0x75, - 0x0B, 0x22, 0x62, 0x22, 0xED, 0x54, 0x54, 0xA4, 0x9D, 0xBB, 0x05, 0x39, 0xB8, 0xAC, 0x6B, 0x6E, - 0x41, 0xBA, 0x2E, 0x3E, 0xDC, 0x78, 0x13, 0x16, 0x00, 0x00, 0x40, 0x76, 0xDE, 0xC8, 0x8A, 0xA1, - 0xD2, 0xC7, 0x47, 0xC3, 0xDB, 0x8F, 0x59, 0xD5, 0xF8, 0xA8, 0xDE, 0x7E, 0x84, 0xF1, 0x11, 0x84, - 0x87, 0x1F, 0x1F, 0x3F, 0xD2, 0xB7, 0x1F, 0x2E, 0x3E, 0xDC, 0x4E, 0x7F, 0xEB, 0x42, 0x73, 0xB6, - 0xAD, 0x5B, 0x10, 0x11, 0x13, 0x69, 0xA7, 0x62, 0x22, 0xCB, 0xB6, 0xD9, 0x18, 0x1D, 0x5E, 0xD6, - 0x15, 0xB7, 0x20, 0x5D, 0x19, 0x1F, 0xC1, 0xBC, 0x13, 0x5F, 0xEE, 0xA9, 0xD7, 0x16, 0x03, 0x00, - 0x00, 0x74, 0x0D, 0x6F, 0xDF, 0x55, 0x63, 0x65, 0xBF, 0xF9, 0x70, 0xAB, 0xBF, 0xFD, 0x88, 0x04, - 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x70, 0x44, 0x02, 0xE4, 0x94, 0x7B, 0xE8, 0xDC, 0xED, 0xDB, 0xE2, - 0xF6, 0x23, 0x88, 0x8F, 0x70, 0x13, 0x0F, 0x64, 0xBD, 0x05, 0x11, 0x31, 0x91, 0x76, 0x2A, 0x24, - 0x32, 0xED, 0x82, 0xCA, 0xF6, 0x5C, 0xD6, 0xF1, 0x5B, 0x90, 0x6E, 0x8E, 0x0F, 0x37, 0xEF, 0xF8, - 0x9F, 0x75, 0xE5, 0xB3, 0x32, 0x00, 0x00, 0x00, 0x5D, 0xCF, 0xEC, 0xBD, 0xDC, 0x86, 0x40, 0x89, - 0xE3, 0x23, 0xC1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xC1, 0xB7, 0x5E, 0x9D, 0x0A, 0x03, 0xE4, 0x07, - 0xAD, 0xE3, 0xC3, 0xED, 0xF4, 0x3D, 0x2D, 0x6E, 0x41, 0xE4, 0x44, 0x4C, 0xA4, 0x9D, 0x0C, 0x89, - 0x2C, 0x0B, 0xE2, 0xC3, 0xCD, 0xFD, 0xFD, 0xF5, 0x6F, 0x41, 0x96, 0xAF, 0x0B, 0xFE, 0x31, 0x99, - 0x52, 0xDD, 0x1E, 0x1F, 0xFE, 0x8E, 0xFF, 0x29, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x48, 0xCB, 0xBD, - 0x72, 0xD5, 0xEC, 0x59, 0x64, 0x63, 0x40, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0xBA, 0xA0, - 0x48, 0x33, 0x11, 0x1A, 0x8D, 0x16, 0x0F, 0x90, 0xE0, 0xF6, 0xE3, 0x6C, 0x92, 0xDB, 0x8F, 0x87, - 0xED, 0xEE, 0x69, 0x1D, 0x1F, 0xE1, 0xC2, 0x5B, 0x90, 0x64, 0x6F, 0xC4, 0x12, 0x31, 0x91, 0x76, - 0x32, 0x24, 0xB2, 0x2C, 0x12, 0x1F, 0xE1, 0x86, 0x16, 0x1A, 0xEF, 0xE0, 0xD2, 0x93, 0xC1, 0x3F, - 0x2A, 0x53, 0xA6, 0x27, 0xE2, 0xC3, 0xED, 0xC8, 0x6A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0x90, 0x96, - 0xFF, 0x0A, 0xDE, 0x9D, 0x9F, 0xB2, 0x41, 0xA0, 0xA2, 0x22, 0xE9, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, - 0x8A, 0xA4, 0x13, 0x91, 0xA1, 0x66, 0x83, 0xA3, 0x1A, 0x1F, 0x36, 0x3C, 0x12, 0xDF, 0x7E, 0x44, - 0xBF, 0xF5, 0xEA, 0xFB, 0xB1, 0xDB, 0x0F, 0x11, 0x1D, 0xD1, 0x25, 0xBF, 0x05, 0x11, 0x31, 0x91, - 0x76, 0x32, 0x24, 0xB2, 0x4C, 0xC4, 0x87, 0x9B, 0xFB, 0x7B, 0x3D, 0xC5, 0xB7, 0x20, 0x3D, 0x13, - 0x1F, 0x3F, 0xBF, 0xDC, 0x98, 0xB1, 0x15, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x20, 0x2D, 0x73, 0x78, - 0xE5, 0x7A, 0xB3, 0xED, 0xA3, 0x36, 0x0A, 0x54, 0x58, 0x24, 0x99, 0x88, 0x8B, 0x56, 0xAB, 0x0B, - 0x8A, 0x34, 0x8B, 0x45, 0x46, 0xB3, 0x45, 0x03, 0xC4, 0xAE, 0x12, 0x1F, 0x36, 0x0E, 0xC2, 0x00, - 0x69, 0xF4, 0xDA, 0xDD, 0x46, 0xB7, 0x1F, 0x22, 0x38, 0xD4, 0x26, 0x7E, 0x50, 0x09, 0x90, 0x9A, - 0x67, 0x41, 0x82, 0x10, 0xA9, 0xDC, 0x82, 0x88, 0x98, 0x48, 0x3B, 0x19, 0x12, 0x59, 0x26, 0xC2, - 0x23, 0xBA, 0x29, 0xBC, 0x05, 0xE9, 0xA9, 0xF8, 0x70, 0x7B, 0xF1, 0x3A, 0x63, 0x7F, 0xBD, 0x77, - 0x05, 0xBF, 0x7C, 0x00, 0x00, 0x00, 0x24, 0xE1, 0x1D, 0x5E, 0xB9, 0x41, 0x87, 0x45, 0x92, 0x89, - 0xB8, 0x68, 0x35, 0x19, 0x15, 0x49, 0x17, 0x0B, 0x8C, 0x66, 0x8B, 0xC5, 0x47, 0xE5, 0xF6, 0x23, - 0x12, 0x1F, 0xCD, 0x6E, 0x3F, 0xC2, 0x00, 0x89, 0xDE, 0x7E, 0x88, 0xD0, 0x68, 0xB8, 0x6F, 0x5C, - 0x68, 0xCE, 0x3E, 0xD1, 0xE0, 0x16, 0x64, 0x93, 0x88, 0x89, 0xB4, 0x93, 0x21, 0x91, 0x65, 0x22, - 0x38, 0xE2, 0x73, 0x7F, 0xDF, 0x0F, 0x5E, 0x57, 0xF8, 0x2D, 0x48, 0xCF, 0xC5, 0x47, 0x30, 0xEF, - 0xC4, 0x9D, 0x1B, 0x82, 0xDF, 0x02, 0x00, 0x00, 0x00, 0x92, 0xF0, 0x0E, 0x5E, 0x3D, 0xAA, 0xE3, - 0xA2, 0xD5, 0x44, 0x5C, 0xB4, 0x5A, 0x5D, 0x50, 0xA4, 0x59, 0x2C, 0x30, 0x9A, 0xAD, 0x41, 0x7C, - 0xF8, 0xB7, 0x1F, 0x2E, 0x3E, 0xD4, 0xED, 0x47, 0x10, 0x1F, 0xD5, 0xDB, 0x8F, 0x87, 0xEC, 0xBE, - 0x91, 0x21, 0x3E, 0x82, 0x85, 0xB7, 0x20, 0xE7, 0x9F, 0x72, 0x7F, 0xDD, 0x20, 0x42, 0x9E, 0x9E, - 0x69, 0x7F, 0x2D, 0x2E, 0x20, 0x82, 0xA9, 0xB8, 0x68, 0x35, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, - 0xD1, 0x76, 0xCD, 0x31, 0xDE, 0xF0, 0xD2, 0x71, 0x33, 0xD4, 0x3F, 0x2B, 0xF8, 0xC7, 0x26, 0x57, - 0xBD, 0x1A, 0x1F, 0x7E, 0x80, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x74, 0xBC, 0xFD, 0x9F, 0x1D, - 0xD7, 0x81, 0xD1, 0x6C, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xC5, 0x02, 0xA3, 0xD5, 0xEA, - 0x02, 0x24, 0x88, 0x8F, 0xF8, 0xED, 0x47, 0x10, 0x1F, 0xF2, 0xD9, 0x8F, 0xFB, 0x83, 0xDB, 0x0F, - 0x11, 0x17, 0x89, 0x16, 0xBB, 0x05, 0x39, 0x1F, 0xC4, 0x47, 0x5B, 0x01, 0x22, 0x43, 0x22, 0xCB, - 0x44, 0x64, 0x34, 0x9B, 0x7B, 0x66, 0xC5, 0xDD, 0x82, 0x1C, 0x5C, 0x9A, 0xFB, 0x07, 0xEF, 0xF5, - 0x72, 0x7C, 0xB8, 0x79, 0xC7, 0xFE, 0x64, 0x3C, 0xF8, 0xAD, 0x00, 0x00, 0x00, 0xA0, 0x15, 0x33, - 0xDA, 0x3F, 0x2B, 0xFD, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x8B, 0xC5, 0x45, - 0x92, 0xC5, 0xE3, 0x23, 0x7A, 0xFB, 0x11, 0xC4, 0x47, 0xCD, 0x9B, 0xAF, 0x1A, 0xDD, 0x7E, 0xA8, - 0xB0, 0x48, 0xB1, 0x33, 0xDF, 0xBB, 0x70, 0xF2, 0x59, 0x90, 0xA7, 0x6C, 0x7C, 0xB4, 0x13, 0x21, - 0x32, 0x24, 0xB2, 0x4C, 0x04, 0x46, 0x92, 0x15, 0x70, 0x0B, 0xD2, 0xEB, 0xF1, 0xE1, 0xEF, 0xC8, - 0x4D, 0xC6, 0x8C, 0xFD, 0x87, 0x42, 0x6E, 0x86, 0x00, 0x00, 0x00, 0x4A, 0xC7, 0x7F, 0x03, 0xD6, - 0xAE, 0x4F, 0xDB, 0x48, 0x50, 0xA1, 0xA1, 0x26, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, - 0x8B, 0x56, 0xB3, 0xD1, 0x31, 0x19, 0x20, 0x17, 0x55, 0x02, 0x24, 0xB8, 0xFD, 0xA8, 0xBE, 0x76, - 0xB7, 0x7A, 0xFB, 0xF1, 0xBE, 0xC6, 0xB7, 0x1F, 0x22, 0x28, 0xB2, 0xEC, 0xEC, 0x63, 0x2E, 0x42, - 0x2A, 0x01, 0xE2, 0xDF, 0x82, 0x64, 0x89, 0x10, 0x19, 0x12, 0x59, 0x26, 0xC2, 0x22, 0xE9, 0x72, - 0xBE, 0x05, 0x29, 0x45, 0x7C, 0xB8, 0xBD, 0x34, 0xC0, 0x9B, 0xB0, 0x00, 0x00, 0x00, 0x92, 0x32, - 0x87, 0x57, 0xAD, 0x4B, 0xFE, 0x0A, 0x5E, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x61, - 0x91, 0x74, 0xF1, 0xF8, 0xC8, 0x74, 0xFB, 0xA1, 0x63, 0x22, 0xFD, 0x66, 0x9A, 0x33, 0xF7, 0xCF, - 0x34, 0x67, 0x9F, 0x9C, 0x8C, 0x90, 0xD4, 0x01, 0x22, 0x43, 0x22, 0xCB, 0x44, 0x54, 0xA4, 0xDD, - 0xCE, 0xD9, 0xC6, 0x1B, 0xBE, 0xBE, 0xED, 0x5B, 0x90, 0xD2, 0xC4, 0x87, 0x1B, 0x6F, 0xC2, 0x02, - 0x00, 0x00, 0x48, 0xCE, 0xB8, 0x57, 0xF0, 0xCA, 0xD8, 0x88, 0x4F, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, - 0x48, 0x3A, 0x11, 0x16, 0x49, 0xE6, 0x6E, 0x3F, 0xEC, 0x8F, 0x7E, 0x7C, 0xC4, 0x6E, 0x3F, 0xEA, - 0x9F, 0xFD, 0x68, 0x70, 0xFB, 0x71, 0x5F, 0xFB, 0xDF, 0x7A, 0x55, 0xD9, 0xCC, 0xEA, 0xDE, 0x0D, - 0x6E, 0x41, 0xCE, 0x35, 0xBA, 0x05, 0x51, 0xE1, 0xE1, 0x26, 0x43, 0x22, 0xCB, 0x44, 0x4C, 0x64, - 0xDA, 0x7B, 0x8D, 0x39, 0x70, 0xB5, 0x7B, 0x2D, 0xEF, 0x60, 0xF0, 0x8F, 0x50, 0x6A, 0xA5, 0x8A, - 0x0F, 0xB7, 0xE7, 0xAF, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x49, 0x79, 0x07, 0xAF, 0x4B, 0xF0, - 0x06, 0x2C, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x51, 0x91, 0x66, 0xE1, 0xCD, 0x47, - 0x83, 0xDB, 0x8F, 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0x78, 0x30, 0xAF, 0x6F, 0xBD, 0x9A, 0x8C, 0x0F, - 0xB7, 0x4C, 0xB7, 0x20, 0x32, 0x24, 0xB2, 0x4C, 0x85, 0x44, 0x96, 0xD9, 0xF8, 0x70, 0xDB, 0xFE, - 0x71, 0xF7, 0x6D, 0x58, 0xC6, 0x8C, 0x5C, 0x9B, 0xFA, 0x13, 0xC0, 0x4B, 0x17, 0x1F, 0xC1, 0xBC, - 0x13, 0x77, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x24, 0xBC, 0x7D, 0x57, 0x8E, 0xE9, 0xE8, 0x08, - 0x27, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, 0x8A, 0xA4, 0xF3, 0x6F, 0x3F, 0x82, 0xF8, - 0x88, 0xDD, 0x7E, 0xA8, 0x67, 0x3F, 0xEA, 0x3F, 0x74, 0xD0, 0xC6, 0x47, 0x2E, 0xB7, 0x1F, 0xB5, - 0xF1, 0x11, 0xEE, 0xDD, 0x47, 0x5A, 0x3C, 0x0B, 0xD2, 0x0B, 0xF1, 0xF1, 0x74, 0xB0, 0xFD, 0xE9, - 0x6F, 0x41, 0xCA, 0x1A, 0x1F, 0x6E, 0xDE, 0xB1, 0x5B, 0xA6, 0xE4, 0x83, 0x1A, 0x01, 0x00, 0x00, - 0x7A, 0x9E, 0xD9, 0x7B, 0x99, 0x8D, 0x06, 0x15, 0x1E, 0x6E, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, - 0xD2, 0xC5, 0x82, 0x22, 0xED, 0xC2, 0xF0, 0x68, 0x70, 0xFB, 0x51, 0xF7, 0xEC, 0x47, 0x10, 0x20, - 0x95, 0xDB, 0x0F, 0x1B, 0x1F, 0xB9, 0xDC, 0x7E, 0xE8, 0xF8, 0x70, 0x3B, 0x7D, 0xEF, 0x4C, 0x73, - 0xAE, 0xD1, 0x2D, 0x88, 0x1F, 0x1D, 0x3D, 0x12, 0x1F, 0xF6, 0xFF, 0xF6, 0xB6, 0x7F, 0xDC, 0x05, - 0x48, 0xE2, 0x5B, 0x90, 0x32, 0xC7, 0x87, 0xBF, 0x23, 0x37, 0x99, 0xE0, 0xB7, 0x0A, 0x00, 0x00, - 0x80, 0x46, 0xCC, 0xE1, 0xFE, 0x25, 0x66, 0x68, 0xBE, 0x0D, 0x87, 0x72, 0xC4, 0x47, 0xCB, 0xDB, - 0x0F, 0x11, 0x1F, 0x95, 0xDB, 0x0F, 0x1B, 0x1E, 0xB9, 0xDC, 0x7E, 0xE8, 0xF0, 0x88, 0x2E, 0xBC, - 0x05, 0x69, 0xF8, 0x2C, 0x88, 0x0C, 0x89, 0x2C, 0x53, 0x21, 0x91, 0x65, 0x22, 0x3E, 0xEC, 0x8F, - 0xFE, 0xF6, 0x7C, 0xC6, 0x9C, 0x3F, 0x70, 0xFD, 0x50, 0xF0, 0x8F, 0x53, 0x43, 0xA5, 0x8F, 0x0F, - 0x37, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x9A, 0xFF, 0x0A, 0x5E, 0xF9, 0x06, 0x2C, 0x11, 0x17, - 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x50, 0xA4, 0x9A, 0x8D, 0x8F, 0x30, 0x3C, 0xC2, 0xF8, 0x48, - 0x7A, 0xFB, 0xF1, 0x63, 0x1B, 0x1E, 0x2E, 0x40, 0x7E, 0xD8, 0xEE, 0xED, 0x87, 0x0E, 0x8E, 0xF8, - 0xDC, 0x2D, 0x48, 0xE3, 0x67, 0x41, 0x54, 0x48, 0x64, 0x99, 0x0A, 0x89, 0x2C, 0x6B, 0x12, 0x1F, - 0x4F, 0xBD, 0xD7, 0x9C, 0xDF, 0xF2, 0x21, 0x73, 0x7E, 0xFF, 0x32, 0x73, 0x76, 0xFF, 0xD2, 0x86, - 0x07, 0xEF, 0x69, 0x11, 0x1F, 0x6E, 0x2F, 0x5E, 0xE7, 0x02, 0x64, 0x5D, 0xF0, 0xDB, 0x06, 0x00, - 0x00, 0x80, 0xE2, 0xBF, 0x01, 0x6B, 0xEB, 0x87, 0x6C, 0x40, 0xF4, 0x7E, 0x7C, 0x64, 0xB9, 0xFD, - 0xA8, 0xC6, 0x87, 0xBB, 0xFD, 0xF8, 0x56, 0x3B, 0xB7, 0x1F, 0x3A, 0x36, 0x1A, 0x6D, 0xE2, 0x21, - 0x75, 0x0B, 0x32, 0xC3, 0x9F, 0x0E, 0x8A, 0x34, 0x53, 0x21, 0x91, 0x65, 0x2D, 0xE2, 0xC3, 0x6D, - 0xE3, 0x05, 0xE6, 0xFC, 0xEE, 0x25, 0xE6, 0xDC, 0xDE, 0x65, 0xF2, 0x01, 0xEC, 0x69, 0x13, 0x1F, - 0x6E, 0xCF, 0x5F, 0x69, 0xCC, 0x89, 0x3B, 0x73, 0xFF, 0x94, 0x78, 0x00, 0x00, 0x80, 0x52, 0xF1, - 0x0E, 0xAD, 0x1C, 0xEC, 0xF9, 0xF8, 0xC8, 0x78, 0xFB, 0x71, 0xEA, 0x51, 0x1B, 0x1D, 0xB9, 0xDC, - 0x7E, 0xE8, 0xC8, 0x68, 0xB6, 0xD3, 0xF7, 0xC4, 0x6F, 0x41, 0x2A, 0xF1, 0xD1, 0x7E, 0x80, 0xA8, - 0x90, 0xC8, 0xB2, 0x64, 0xF1, 0x71, 0xEE, 0x49, 0xBB, 0x4D, 0x1F, 0x76, 0x01, 0x62, 0xCE, 0x0E, - 0xD5, 0xDE, 0x82, 0x4C, 0xAB, 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x6F, 0xC2, 0x02, 0x00, 0x00, - 0x68, 0xC6, 0xDB, 0x77, 0x45, 0xE4, 0x15, 0xBC, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xA9, - 0xA0, 0x48, 0xB3, 0x20, 0x3E, 0x82, 0xA5, 0xBB, 0xFD, 0x88, 0xC4, 0x47, 0x5B, 0xB7, 0x1F, 0x3A, - 0x30, 0x92, 0x6C, 0xE2, 0x81, 0xE8, 0x2D, 0x88, 0x8D, 0x8F, 0xB6, 0x23, 0x44, 0x85, 0x44, 0x96, - 0x25, 0x8F, 0x8F, 0xB3, 0x83, 0x76, 0x4F, 0x5C, 0x60, 0xDE, 0xDD, 0xB1, 0xC4, 0x4C, 0xEC, 0x5E, - 0x5E, 0x3D, 0x7C, 0x4F, 0xC7, 0xF8, 0x70, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x2D, 0x98, 0x7D, - 0xF6, 0x70, 0xD7, 0xEB, 0xF1, 0x91, 0xE6, 0xF6, 0x23, 0x8C, 0x8F, 0x5C, 0x6E, 0x3F, 0x74, 0x58, - 0x24, 0x5D, 0xE5, 0x16, 0x64, 0xA6, 0x8D, 0x10, 0x1B, 0x20, 0x4F, 0xB5, 0x1B, 0x20, 0x2A, 0x24, - 0xB2, 0x2C, 0x43, 0x7C, 0x3C, 0x7E, 0x81, 0x39, 0x33, 0xF8, 0x41, 0x17, 0x20, 0xE6, 0xF4, 0x8E, - 0xA5, 0x03, 0xD3, 0x35, 0x3E, 0xFC, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x00, 0x34, 0x62, - 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x0B, 0x75, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, - 0x66, 0x91, 0xF8, 0x08, 0xA6, 0x6E, 0x3F, 0xAA, 0x01, 0x52, 0x73, 0xFB, 0x31, 0xAB, 0xFE, 0xF6, - 0xE3, 0x9B, 0x2A, 0x2E, 0x5A, 0x4D, 0x47, 0x45, 0x9A, 0xBD, 0xF3, 0xD7, 0x33, 0xCC, 0x99, 0x1F, - 0x4E, 0x06, 0x48, 0xF6, 0x5B, 0x10, 0x15, 0x12, 0x59, 0x96, 0x31, 0x3E, 0x1E, 0x9D, 0x61, 0x4E, - 0xFF, 0xD8, 0xEE, 0x99, 0x45, 0x66, 0xE2, 0xC0, 0xAA, 0x93, 0xD3, 0x36, 0x3E, 0xDC, 0x8E, 0xAC, - 0x32, 0xE6, 0xF8, 0x1D, 0x4B, 0x82, 0x2F, 0x31, 0x00, 0x00, 0x00, 0x44, 0x99, 0x91, 0xFE, 0x01, - 0xB3, 0xF3, 0x12, 0x1D, 0x18, 0xCD, 0x26, 0xA3, 0x22, 0xE9, 0x54, 0x50, 0xA4, 0x59, 0x2C, 0x3E, - 0x12, 0xDC, 0x7E, 0x4C, 0xB8, 0x00, 0x79, 0xDC, 0xDD, 0x7E, 0xC4, 0xE2, 0xC3, 0xED, 0x7B, 0x59, - 0xBE, 0xF5, 0x4A, 0x07, 0x45, 0x9A, 0xB9, 0xF8, 0xF0, 0x77, 0xF7, 0x0C, 0x7B, 0x90, 0x6F, 0xE7, - 0x16, 0x44, 0x85, 0x44, 0x96, 0xB5, 0x17, 0x1F, 0xA7, 0x1E, 0x76, 0x01, 0x32, 0xDB, 0x98, 0x63, - 0x77, 0x9A, 0x69, 0x1B, 0x1F, 0x3F, 0xBF, 0xCC, 0x98, 0x17, 0x3F, 0x67, 0xCC, 0x89, 0x2F, 0xAD, - 0x0D, 0xBE, 0xC4, 0x00, 0x00, 0x00, 0x10, 0xE5, 0x1D, 0x5A, 0x75, 0x97, 0xD9, 0x7E, 0xB1, 0x8E, - 0x8C, 0x46, 0x93, 0x51, 0x91, 0x74, 0x2A, 0x28, 0xD2, 0x2C, 0x16, 0x1F, 0x2A, 0x40, 0x1A, 0x3E, - 0xFB, 0x61, 0xE3, 0x23, 0x97, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0x56, 0x8D, 0x8F, 0x60, 0x67, 0xBE, - 0x5F, 0x09, 0x90, 0x73, 0xD1, 0x5B, 0x90, 0x20, 0x44, 0x74, 0x74, 0x84, 0x53, 0x21, 0x91, 0x65, - 0x39, 0xC4, 0xC7, 0xD3, 0x1F, 0x33, 0xDE, 0xD1, 0xDB, 0xA7, 0x77, 0x7C, 0xB8, 0x3D, 0xFF, 0x59, - 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x88, 0x19, 0x59, 0xB9, 0x5E, 0x46, 0x46, 0xA3, 0xC9, 0xA8, - 0x48, 0x3A, 0x15, 0x14, 0x69, 0x56, 0x1F, 0x1E, 0xD5, 0xF8, 0xB0, 0xE1, 0x31, 0x79, 0xFB, 0x11, - 0xF9, 0xD6, 0xAB, 0xEA, 0xED, 0xC7, 0x45, 0x95, 0xDB, 0x0F, 0xBB, 0xF6, 0x6E, 0x3F, 0x74, 0x50, - 0xA4, 0x59, 0x3C, 0x3E, 0xFC, 0x65, 0xBA, 0x05, 0x51, 0x21, 0x91, 0x65, 0xC4, 0x47, 0xFB, 0x0B, - 0xE2, 0x23, 0x98, 0xF7, 0x8B, 0x3B, 0x5B, 0x7E, 0x30, 0x23, 0x00, 0x00, 0xC0, 0xB4, 0xE4, 0x1D, - 0xB8, 0x7A, 0x54, 0x86, 0x86, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, 0x66, 0xB1, 0xF8, 0x88, - 0x07, 0x88, 0x5D, 0xF5, 0x5B, 0xAF, 0xC2, 0x00, 0xA9, 0x3E, 0x78, 0x6E, 0xE3, 0xC3, 0x06, 0x48, - 0xFB, 0xB7, 0x1F, 0x3A, 0x28, 0xD2, 0x4C, 0xC6, 0x47, 0xB0, 0xF0, 0x16, 0xC4, 0xBD, 0x92, 0xB7, - 0xF5, 0x2D, 0x88, 0x0A, 0x89, 0x2C, 0x23, 0x3E, 0xDA, 0x5F, 0x6D, 0x7C, 0xF8, 0x01, 0x72, 0xF4, - 0xD6, 0xB1, 0xE0, 0x4B, 0x0C, 0x00, 0x00, 0x00, 0x51, 0xDE, 0xFE, 0x2B, 0x4F, 0xCA, 0xD8, 0x88, - 0x4F, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x78, 0x88, 0xF8, 0x08, 0x6F, 0x3F, 0x6A, - 0x1E, 0x3C, 0xF7, 0x6F, 0x3F, 0x2E, 0x9A, 0xBC, 0xFD, 0x08, 0xE3, 0x23, 0x0C, 0x90, 0xFB, 0xD3, - 0xDC, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x1D, 0x35, 0x73, 0xB7, 0x20, 0x8F, 0x4D, 0xDE, 0x82, - 0xF8, 0x11, 0x62, 0x63, 0xA3, 0x3E, 0x40, 0x54, 0x48, 0x64, 0x19, 0xF1, 0xD1, 0xFE, 0xEA, 0xE3, - 0xC3, 0xDF, 0xB1, 0x2F, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x00, 0x25, 0xD1, 0x1B, 0xB0, 0x64, 0x54, - 0x24, 0x9D, 0x0A, 0x8A, 0x34, 0x8B, 0x85, 0x47, 0x93, 0xF8, 0xA8, 0x3E, 0x78, 0x5E, 0xBD, 0xFD, - 0xB0, 0xF1, 0x11, 0xDE, 0x7E, 0xC4, 0xE3, 0xE3, 0x21, 0xBB, 0xBB, 0x55, 0x68, 0xA8, 0xE9, 0xA0, - 0x48, 0x33, 0x19, 0x1C, 0x62, 0xA7, 0xBF, 0x3B, 0x23, 0x78, 0x16, 0xA4, 0xC1, 0xB7, 0x62, 0x3D, - 0xAD, 0x42, 0x22, 0xCB, 0x88, 0x8F, 0xF6, 0x27, 0xC2, 0x23, 0x1C, 0x6F, 0xC2, 0x02, 0x00, 0x00, - 0xA8, 0xE7, 0xBF, 0x01, 0x6B, 0xD7, 0x1C, 0x1D, 0x1D, 0xE1, 0x64, 0x54, 0x24, 0x9D, 0x0A, 0x8A, - 0x34, 0x8B, 0x85, 0x47, 0x38, 0x15, 0x20, 0xF1, 0xD7, 0xEE, 0x3E, 0x39, 0x19, 0x1F, 0xF2, 0xCD, - 0x57, 0x89, 0x6F, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0A, 0x8D, 0x66, 0x7B, 0x37, 0x7E, 0x0B, 0x12, - 0x46, 0x88, 0x8B, 0x8F, 0x70, 0x32, 0x2A, 0x92, 0x8E, 0xF8, 0x68, 0x7F, 0x22, 0x3A, 0xA2, 0x7B, - 0xF1, 0x7A, 0x63, 0x5E, 0xBE, 0xB3, 0xE6, 0x53, 0xE1, 0x01, 0x00, 0x00, 0xA6, 0x3D, 0x73, 0xA8, - 0x7F, 0xAD, 0xD9, 0xF1, 0x49, 0x1D, 0x1E, 0x6E, 0x32, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, 0xC5, - 0xA2, 0x23, 0xBA, 0x78, 0x7C, 0x44, 0x6F, 0x3F, 0x82, 0xF8, 0x98, 0xBC, 0xFD, 0x10, 0xDF, 0x7A, - 0x95, 0xF8, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xA9, 0xC0, 0x68, 0x35, 0x77, 0x0B, 0x52, 0xF7, 0xE1, - 0x84, 0x36, 0x3A, 0xF2, 0x09, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xE0, 0x88, 0xEF, 0x85, 0xAB, 0x79, - 0x13, 0x16, 0x00, 0x00, 0x40, 0x9C, 0xFF, 0x06, 0xAC, 0xAD, 0x1F, 0xEC, 0xB9, 0xF8, 0x68, 0x74, - 0xFB, 0xE1, 0xE2, 0xE3, 0x6C, 0x2C, 0x3E, 0xB2, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x17, - 0x49, 0xF7, 0xEE, 0x8F, 0x2B, 0x01, 0xE2, 0xBF, 0x96, 0xF7, 0x29, 0x1B, 0x1F, 0x6E, 0xD1, 0x08, - 0x91, 0x71, 0xD1, 0x6A, 0xC4, 0x47, 0xFB, 0x13, 0xB1, 0xD1, 0x60, 0xDE, 0x89, 0x2F, 0x0D, 0x06, - 0x5F, 0x6A, 0x00, 0x00, 0x00, 0x70, 0xBC, 0xE1, 0xE5, 0x43, 0x3D, 0x15, 0x1F, 0x6E, 0xF1, 0xF8, - 0x88, 0xDE, 0x7E, 0xB8, 0xF8, 0x68, 0x75, 0xFB, 0xF1, 0xA0, 0x9D, 0x0C, 0x8E, 0xE8, 0x74, 0x50, - 0xA4, 0x99, 0x8A, 0x8A, 0x34, 0x3B, 0xFD, 0xED, 0xE0, 0x16, 0xE4, 0x49, 0x1B, 0x20, 0x36, 0x0A, - 0xEA, 0x02, 0x24, 0x75, 0x84, 0x10, 0x1F, 0xED, 0x4F, 0x87, 0x46, 0xA3, 0x79, 0x47, 0x6F, 0x1D, - 0x0D, 0xBE, 0xD4, 0x00, 0x00, 0x00, 0xE0, 0x78, 0x7B, 0xAF, 0xA8, 0x7F, 0x05, 0xAF, 0x8C, 0x8A, - 0xA4, 0x53, 0x41, 0x91, 0x66, 0x22, 0x38, 0xA2, 0xB3, 0xD1, 0xE1, 0x7E, 0xAC, 0xBB, 0xFD, 0xB0, - 0xF1, 0x71, 0x6E, 0xE3, 0x45, 0xC9, 0x6E, 0x3F, 0xEE, 0x6B, 0x75, 0xFB, 0xA1, 0x83, 0x22, 0xCD, - 0x54, 0x50, 0x64, 0xD9, 0xBB, 0xF6, 0xD0, 0x1F, 0x06, 0x48, 0x7B, 0xB7, 0x20, 0xC4, 0x47, 0xFB, - 0xD3, 0x91, 0xD1, 0x74, 0xC7, 0x6E, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x51, 0x66, 0xEF, 0xE2, - 0xDE, 0x89, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x08, 0x03, 0x24, 0x88, 0x8F, 0x78, 0x80, 0xD4, - 0xC5, 0x47, 0xCB, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0xA6, 0x42, 0x22, 0xDB, 0x2E, 0x30, 0xA7, 0xBF, - 0x6D, 0xA3, 0x60, 0x70, 0x32, 0x42, 0x6A, 0x02, 0xC4, 0x85, 0x45, 0xA2, 0x08, 0x21, 0x3E, 0xDA, - 0x9F, 0x88, 0x8B, 0x24, 0x73, 0x6F, 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x1B, 0x00, 0x00, - 0xC0, 0xF4, 0x66, 0x46, 0xFA, 0x67, 0xD7, 0xBC, 0x82, 0x57, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, - 0x33, 0x11, 0x1B, 0xF1, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, 0xDF, 0x7E, 0xD8, 0xF0, 0x10, 0xB7, 0x1F, - 0xF2, 0x43, 0x07, 0x9B, 0xDE, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x76, 0x41, 0x75, - 0xE1, 0x2D, 0xC8, 0xB9, 0x4C, 0xB7, 0x20, 0xC4, 0x47, 0xFB, 0x13, 0x61, 0x91, 0x74, 0x63, 0xCB, - 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xC8, 0x7F, 0x05, 0x6F, 0xF8, 0x06, 0x2C, 0x19, 0x15, 0x49, - 0xA7, 0x82, 0x22, 0xCD, 0x62, 0xA1, 0xD1, 0x68, 0x61, 0x78, 0x84, 0xF1, 0xE1, 0xF6, 0xD4, 0x85, - 0x35, 0xDF, 0x7A, 0x15, 0x0F, 0x90, 0x53, 0x2E, 0x40, 0xC2, 0xDB, 0x8F, 0x1F, 0xD9, 0xC9, 0xF0, - 0x70, 0xD3, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x6C, 0x32, 0x3E, 0xDC, 0x4E, 0x7D, 0xD3, 0xC5, - 0x41, 0x96, 0x5B, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xA8, 0x48, 0xB3, 0x17, 0x3F, 0xC7, 0x9B, 0xB0, - 0x00, 0x00, 0x00, 0x42, 0xFE, 0x1B, 0xB0, 0xB6, 0x7D, 0xC4, 0x1E, 0xEE, 0x55, 0x54, 0x24, 0x9D, - 0x0A, 0x8A, 0x34, 0x13, 0xA1, 0xA1, 0x66, 0xA3, 0xC3, 0xFD, 0x58, 0x7B, 0xFB, 0x61, 0xE3, 0x23, - 0xCD, 0xED, 0xC7, 0xB7, 0x1A, 0xDD, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x56, 0x1B, - 0x1F, 0xE1, 0x26, 0x7E, 0x94, 0xF6, 0x16, 0x84, 0xF8, 0x68, 0x7F, 0x22, 0x28, 0x32, 0x8C, 0x37, - 0x61, 0x01, 0x00, 0x00, 0x04, 0xBC, 0x91, 0x81, 0x0D, 0x3A, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, - 0xC5, 0x22, 0xA3, 0xD9, 0xC2, 0xF0, 0x88, 0xC4, 0x47, 0xA2, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x68, - 0xD7, 0xA3, 0xF1, 0xE1, 0xD6, 0xF2, 0x16, 0x84, 0xF8, 0xC8, 0x79, 0x3A, 0x26, 0xB2, 0xCC, 0x3B, - 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0x38, 0xDE, 0x81, 0xAB, 0x47, 0x75, 0x58, 0x24, 0x99, - 0x0A, 0x8A, 0x34, 0x13, 0x91, 0xD1, 0x62, 0xD5, 0x00, 0x09, 0xE3, 0xA3, 0xED, 0xDB, 0x0F, 0x1D, - 0x14, 0x69, 0xA6, 0x43, 0x22, 0xCB, 0x74, 0x78, 0x44, 0x17, 0xDE, 0x82, 0xB8, 0x78, 0x68, 0x7C, - 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x12, 0x59, 0xE7, 0x1D, 0xBB, 0x65, 0x3C, 0xF8, 0x92, 0x03, - 0x00, 0x00, 0x98, 0xDE, 0xBC, 0x7D, 0x57, 0x8C, 0xEB, 0xB8, 0x68, 0x35, 0x15, 0x14, 0x69, 0xA6, - 0x03, 0xA3, 0xE1, 0x6A, 0x6E, 0x3F, 0x6C, 0x7C, 0x34, 0xBB, 0xFD, 0x08, 0xE3, 0xA3, 0xE5, 0xED, - 0x87, 0x0E, 0x8A, 0x34, 0xD3, 0x21, 0x91, 0x65, 0x3A, 0x38, 0xE2, 0xF3, 0x6F, 0x41, 0x1E, 0x6F, - 0x76, 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x11, 0x6D, 0xCD, 0xBD, 0x09, 0x6B, 0xEC, 0x8B, 0xB3, - 0x82, 0x2F, 0x3B, 0x00, 0x00, 0x80, 0xE9, 0xCB, 0x0C, 0x2D, 0xB0, 0x07, 0x7C, 0x15, 0x18, 0xCD, - 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x60, 0x24, 0x58, 0x18, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xB9, 0x1F, - 0xC9, 0x6E, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0E, 0x89, 0x2C, 0xD3, 0xB1, 0xD1, 0x68, 0x67, 0xBE, - 0x2F, 0x9E, 0x05, 0xF1, 0x43, 0x24, 0x12, 0x1E, 0x6E, 0xC4, 0x47, 0x86, 0x89, 0x78, 0xC8, 0x63, - 0x63, 0xCB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x80, 0xFF, 0x06, 0xAC, 0x9D, 0xB3, 0xED, 0xE1, 0x5E, - 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0x33, 0x1D, 0x17, 0x4D, 0x17, 0xB9, 0xF9, 0xF0, 0xE3, 0x43, - 0xDC, 0x7E, 0x4C, 0xB8, 0x3D, 0x1E, 0xB9, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xE5, 0x89, 0x0F, - 0x7F, 0x77, 0xAB, 0x5B, 0x90, 0x4A, 0x68, 0x18, 0x1B, 0x19, 0xC4, 0x47, 0xD6, 0x89, 0x70, 0xC8, - 0x65, 0x8B, 0x8D, 0x79, 0xF1, 0x5A, 0xE3, 0xFD, 0xE2, 0x4B, 0x77, 0x05, 0x5F, 0x7A, 0x00, 0x00, - 0x00, 0xD3, 0x93, 0x0D, 0x90, 0x75, 0x66, 0xC7, 0x27, 0xEC, 0x21, 0x5F, 0x85, 0x86, 0x9A, 0x0A, - 0x8A, 0x34, 0x13, 0x71, 0x91, 0x64, 0x61, 0x7C, 0xC4, 0x6E, 0x3F, 0x12, 0x3F, 0xFB, 0xF1, 0xCD, - 0x12, 0xC5, 0x47, 0xB0, 0x33, 0xDF, 0x8B, 0x3E, 0x0B, 0x52, 0x89, 0x8C, 0x70, 0x2E, 0x40, 0xC2, - 0xF0, 0x20, 0x3E, 0x92, 0x4E, 0x85, 0x43, 0x1E, 0xB3, 0xF1, 0xE1, 0x66, 0x7F, 0xED, 0xDE, 0x89, - 0x3B, 0x36, 0x04, 0x5F, 0x7A, 0x00, 0x00, 0x00, 0xD3, 0x93, 0xFF, 0x0A, 0x5E, 0x19, 0x1A, 0x6A, - 0x2A, 0x28, 0xD2, 0x4C, 0x84, 0x45, 0xAB, 0xD9, 0xF0, 0xA8, 0xC6, 0x87, 0x0D, 0x8F, 0xC9, 0xDB, - 0x8F, 0xD8, 0xB7, 0x5E, 0x45, 0x6F, 0x3F, 0xEC, 0x1A, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, - 0x12, 0x59, 0xA6, 0xC3, 0x22, 0xF1, 0xAA, 0xB7, 0x20, 0x36, 0x40, 0x36, 0xBA, 0xC0, 0x08, 0x82, - 0x23, 0x12, 0x1E, 0xC4, 0x47, 0xD2, 0xA9, 0x70, 0xC8, 0x63, 0x41, 0x7C, 0x04, 0xF3, 0x4E, 0xFC, - 0x39, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x9B, 0x77, 0xF0, 0xBA, 0x84, 0x6F, 0xC0, 0x52, 0x41, - 0x91, 0x66, 0xB1, 0xB0, 0x48, 0x3A, 0x17, 0x20, 0xE1, 0xCD, 0x87, 0x5D, 0xF5, 0x5B, 0xAF, 0xE4, - 0xB3, 0x1F, 0x17, 0xB5, 0xB8, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x04, 0x45, - 0x86, 0x9D, 0xFE, 0xCE, 0x7B, 0xFD, 0xB0, 0x08, 0x23, 0xA4, 0x1A, 0x1C, 0x2E, 0x3E, 0x82, 0x28, - 0x21, 0x3E, 0x5A, 0x4D, 0x85, 0x43, 0x1E, 0xAB, 0x8D, 0x0F, 0x3F, 0x40, 0x8E, 0x7D, 0x81, 0x37, - 0x61, 0x01, 0x00, 0x80, 0xE9, 0xCD, 0xDB, 0xFB, 0xD9, 0x31, 0x1D, 0x1C, 0xD1, 0xA9, 0xA0, 0x48, - 0xB3, 0x58, 0x54, 0x24, 0x5D, 0x2C, 0x3E, 0xC2, 0xDB, 0x8F, 0xBA, 0xF8, 0x88, 0xDE, 0x7E, 0x84, - 0xF1, 0x11, 0x06, 0xC8, 0x86, 0xF0, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xE9, 0x90, 0xC8, 0x32, 0x1D, - 0x13, 0xA9, 0xF7, 0x57, 0xEF, 0xF5, 0xF7, 0xEE, 0xA3, 0x93, 0x01, 0x12, 0x9F, 0x1F, 0x27, 0x2E, - 0x3C, 0x88, 0x8F, 0x06, 0x53, 0xE1, 0x90, 0xC7, 0xEA, 0xE3, 0xC3, 0xDF, 0x91, 0x1B, 0x4C, 0xF0, - 0xA5, 0x07, 0x00, 0x00, 0x30, 0x3D, 0x99, 0x3D, 0xF6, 0x50, 0x24, 0xA3, 0x23, 0x9C, 0x0A, 0x8A, - 0x34, 0x8B, 0x45, 0x45, 0xD2, 0x35, 0x88, 0x8F, 0xEA, 0x83, 0xE7, 0xEA, 0xF6, 0x23, 0x1E, 0x1F, - 0x0F, 0xD9, 0xDD, 0x5D, 0xEE, 0xF8, 0x70, 0x73, 0xB7, 0x20, 0x7E, 0x60, 0xD8, 0x9D, 0x7B, 0xD2, - 0x86, 0x87, 0xDD, 0xB9, 0x68, 0x7C, 0xD8, 0xF0, 0x38, 0x6B, 0xC3, 0x83, 0xF8, 0x88, 0x4F, 0x85, - 0x43, 0x1E, 0x8B, 0x45, 0x47, 0x74, 0x2F, 0xAD, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xFA, 0x32, - 0x87, 0xFB, 0x97, 0x98, 0xDD, 0xF3, 0xEC, 0x81, 0x5F, 0x85, 0x87, 0x9B, 0x0A, 0x8A, 0x34, 0x8B, - 0x45, 0x45, 0x9A, 0xD9, 0xE8, 0xA8, 0x0B, 0x90, 0x26, 0xDF, 0x7A, 0x25, 0xDF, 0x7C, 0x75, 0xBF, - 0xBB, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x45, 0xE2, 0x23, - 0x9C, 0xBB, 0x05, 0xF1, 0x43, 0x63, 0xD0, 0xC6, 0x88, 0x0D, 0x90, 0xB3, 0xB1, 0x6F, 0xB9, 0x7A, - 0xF7, 0x31, 0xE2, 0xA3, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x88, 0x8E, 0xE8, 0x5E, 0xBC, 0xD6, 0x06, - 0xC8, 0x1D, 0xEB, 0x82, 0x2F, 0x41, 0x00, 0x00, 0x80, 0xE9, 0xC5, 0x7F, 0x05, 0x6F, 0xC3, 0x37, - 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x15, 0x49, 0xF7, 0x8C, 0x88, 0x8F, 0xE8, 0xED, 0x87, 0x8B, - 0x8F, 0x9A, 0x00, 0x11, 0xDF, 0x7A, 0xE5, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, - 0x26, 0x42, 0x22, 0xCB, 0x44, 0x7C, 0xBC, 0xBD, 0xFE, 0xBD, 0xE6, 0xD4, 0x3D, 0x36, 0x42, 0x5C, - 0x68, 0xB8, 0xE0, 0x70, 0x21, 0x12, 0xFC, 0xE8, 0xFE, 0xB5, 0x09, 0x17, 0x1F, 0x36, 0x3C, 0x4E, - 0x3F, 0x42, 0x7C, 0x54, 0xA6, 0xC2, 0x21, 0x8F, 0x89, 0xE0, 0x88, 0xCF, 0xFD, 0xBE, 0x4E, 0xDC, - 0xB1, 0x3E, 0xF8, 0x12, 0x04, 0x00, 0x00, 0x98, 0x5E, 0xFC, 0x37, 0x60, 0x6D, 0xF9, 0x80, 0x3D, - 0xF4, 0x77, 0x5F, 0x7C, 0x34, 0xBA, 0xFD, 0x50, 0xAF, 0xDD, 0xD5, 0xB7, 0x1F, 0xED, 0x7F, 0xEB, - 0x95, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0x0D, 0xE2, 0x23, 0xDC, 0x99, 0x07, 0x6D, 0x6C, - 0x3C, 0x3E, 0xA3, 0x12, 0x22, 0x41, 0x78, 0x4C, 0x3C, 0x7A, 0x81, 0x7F, 0xEB, 0x41, 0x7C, 0x84, - 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x6C, 0x34, 0x98, 0x77, 0xE2, 0x0E, 0xDE, 0x84, 0x05, 0x00, 0x00, - 0xA6, 0x27, 0xEF, 0xD0, 0xCA, 0xC1, 0xAE, 0x8B, 0x8F, 0x5C, 0x6E, 0x3F, 0x2E, 0x6A, 0xFB, 0xF6, - 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0xD6, 0xD7, 0xEC, 0xBF, 0xF6, - 0x4D, 0x17, 0x1D, 0x33, 0xFC, 0x9D, 0xB1, 0xE1, 0xE1, 0xE6, 0x7F, 0xCB, 0x55, 0x18, 0x1F, 0x4F, - 0x11, 0x1F, 0xC5, 0x4C, 0x87, 0x46, 0xA3, 0x79, 0xC7, 0xBE, 0x70, 0x32, 0xF8, 0x12, 0x04, 0x00, - 0x00, 0x98, 0x5E, 0xBC, 0xBD, 0x57, 0xC4, 0x5E, 0xC1, 0xAB, 0x82, 0x22, 0xCD, 0x44, 0x54, 0x24, - 0x5D, 0x24, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0xA3, 0xFE, 0xD9, 0x0F, 0x75, 0xFB, 0x61, 0xE3, 0xE3, - 0xBE, 0xF6, 0x6E, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x4B, 0x10, 0x1F, 0x6F, 0x7D, - 0xED, 0x02, 0xF3, 0xD6, 0x7F, 0xB9, 0xC0, 0x9C, 0xFA, 0xA1, 0x0D, 0x0D, 0x77, 0xE3, 0xF1, 0x63, - 0x1B, 0x1F, 0x41, 0x78, 0xBC, 0xF3, 0x90, 0xFD, 0x91, 0xF8, 0x28, 0x68, 0x3A, 0x32, 0x9A, 0xEE, - 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x4C, 0x4F, 0x66, 0xAF, 0x3D, 0xF0, 0x75, 0x53, 0x7C, - 0x04, 0x01, 0xD2, 0xEC, 0xF6, 0x23, 0x1E, 0x20, 0x75, 0xF1, 0xF1, 0x60, 0x7B, 0x0F, 0x9E, 0xEB, - 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x96, 0x22, 0x3E, 0xDE, 0xFC, 0xCF, 0xF6, 0xC7, 0xBB, 0x6D, - 0x84, 0x04, 0xD1, 0xE1, 0xEF, 0x41, 0xE2, 0x43, 0x87, 0x43, 0x1E, 0x13, 0x71, 0x91, 0x64, 0x47, - 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xFD, 0x98, 0xD1, 0xFE, 0x59, 0x66, 0x68, 0x81, 0x0D, - 0x80, 0xEE, 0x8A, 0x0F, 0xF7, 0xA3, 0xBA, 0xFD, 0x50, 0xCF, 0x7E, 0xD4, 0x7E, 0xE8, 0xA0, 0x0D, - 0x8F, 0x87, 0xDB, 0xBB, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x2C, 0x65, 0x7C, 0xB8, - 0xFD, 0xE1, 0xFF, 0xB1, 0xFF, 0xFF, 0x77, 0x66, 0x98, 0xB7, 0x1F, 0x98, 0x69, 0x67, 0xE3, 0x63, - 0x23, 0xF1, 0x51, 0xCC, 0x44, 0x58, 0x24, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x2F, 0xAD, 0x0D, 0xBE, - 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0xFF, 0x0D, 0x58, 0x3B, 0x67, 0xDB, 0x08, 0x50, 0x41, 0x91, - 0x66, 0x22, 0x2A, 0x92, 0x2E, 0x1A, 0x1F, 0x41, 0x80, 0x34, 0xBB, 0xFD, 0x70, 0xF1, 0x11, 0x0F, - 0x90, 0x6A, 0x7C, 0xB4, 0x79, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, 0x64, 0x59, 0xC6, 0xF8, - 0x78, 0xE3, 0x2F, 0x67, 0x98, 0xF1, 0xFF, 0x3C, 0xC3, 0xBC, 0xF5, 0x23, 0xFB, 0x7B, 0x7A, 0x92, - 0xF8, 0x28, 0x66, 0x22, 0x2A, 0xD2, 0xEC, 0xF9, 0x2B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x7E, - 0xBC, 0x43, 0xAB, 0xEE, 0x32, 0xDB, 0x3E, 0x6A, 0x43, 0x40, 0x45, 0x45, 0xD2, 0x89, 0xA8, 0x48, - 0x3A, 0x11, 0x1F, 0xEE, 0xC7, 0xD4, 0xB7, 0x1F, 0x61, 0x7C, 0xB8, 0xDB, 0x8F, 0x7B, 0xB3, 0xDD, - 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x4E, 0x7C, 0xFC, 0xA7, 0x19, 0xE6, 0xF7, - 0xFF, 0xF7, 0x0C, 0xF3, 0xE6, 0x03, 0xC4, 0x47, 0x31, 0x13, 0x41, 0x91, 0x61, 0xDE, 0x2F, 0xEE, - 0x18, 0x0A, 0xBE, 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0x33, 0xD2, 0xBF, 0x5E, 0x47, 0x45, 0xD2, - 0x89, 0xA8, 0x48, 0xBA, 0x78, 0x7C, 0xB8, 0x85, 0xE1, 0x11, 0xC6, 0x47, 0xAB, 0xDB, 0x0F, 0xFF, - 0x5B, 0xAF, 0x82, 0xF8, 0x70, 0xFB, 0xA1, 0x9D, 0x88, 0x8B, 0x56, 0xD3, 0x21, 0x91, 0x65, 0x22, - 0x24, 0xB2, 0x2C, 0x87, 0xF8, 0x78, 0xE3, 0xDB, 0x36, 0x3E, 0x5E, 0x22, 0x3E, 0xF2, 0x9F, 0x8E, - 0x89, 0x2C, 0xF3, 0x8E, 0xDE, 0x3C, 0x16, 0x7C, 0x29, 0x02, 0x00, 0x00, 0x4C, 0x0F, 0xDE, 0x81, - 0xAB, 0x46, 0x75, 0x58, 0x24, 0x99, 0x88, 0x8A, 0xA4, 0x6B, 0x10, 0x1F, 0xEE, 0xC7, 0x54, 0xB7, - 0x1F, 0xD1, 0xF8, 0x70, 0xB7, 0x1F, 0xDF, 0x4A, 0x7F, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, - 0x64, 0x19, 0xF1, 0x91, 0xC3, 0x54, 0x38, 0xE4, 0x31, 0x1D, 0x12, 0x99, 0xC7, 0x9B, 0xB0, 0x00, - 0x00, 0xC0, 0x74, 0xE3, 0xED, 0xFF, 0xEC, 0x49, 0x1D, 0x17, 0xAD, 0x26, 0xA2, 0x22, 0xE9, 0xE2, - 0xE1, 0x11, 0x2E, 0x0C, 0x8F, 0x30, 0x3E, 0x9A, 0xDD, 0x7E, 0x3C, 0x76, 0x91, 0x39, 0xFD, 0xA8, - 0x0D, 0x8E, 0x36, 0x6F, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, - 0x0A, 0x87, 0x3C, 0x26, 0x02, 0xA2, 0xDD, 0xB9, 0x37, 0x61, 0x1D, 0xBF, 0x63, 0x49, 0xF0, 0xE5, - 0x08, 0x00, 0x00, 0x50, 0x7E, 0x66, 0x68, 0xBE, 0x8D, 0x02, 0x15, 0x18, 0xCD, 0x26, 0xA2, 0x22, - 0xE9, 0x54, 0x78, 0x44, 0x96, 0xE8, 0xF6, 0x23, 0x88, 0x8F, 0x76, 0x6F, 0x3F, 0x74, 0x48, 0x64, - 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0x26, 0xE2, 0x21, 0x8F, 0xBD, - 0x78, 0x1D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x87, 0xFF, 0x06, 0xAC, 0x5D, 0x9F, 0xB6, 0x61, - 0xA0, 0x22, 0xA3, 0xD1, 0x44, 0x54, 0x24, 0x9D, 0x08, 0x8E, 0xEA, 0x92, 0xDE, 0x7E, 0x3C, 0x6E, - 0x03, 0x24, 0x8C, 0x8F, 0x68, 0x80, 0xFC, 0x80, 0xF8, 0x20, 0x3E, 0x54, 0x38, 0xE4, 0x31, 0x11, - 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x3E, 0xCC, 0xA1, 0xFE, 0xB5, - 0x66, 0xC7, 0xC7, 0x6D, 0x1C, 0xA8, 0xD0, 0x50, 0x13, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0x62, 0x53, - 0xB7, 0x1F, 0xD1, 0x00, 0xF1, 0xE3, 0xA3, 0xD1, 0xED, 0xC7, 0x37, 0x75, 0x68, 0xA8, 0xE9, 0x90, - 0xC8, 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x44, 0x43, 0xCE, - 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xDA, 0xF0, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0x36, 0x10, 0x54, - 0x6C, 0xC4, 0x27, 0xA2, 0x22, 0xE9, 0x44, 0x6C, 0xD4, 0x2C, 0xC1, 0xED, 0x87, 0xFB, 0xD6, 0xAB, - 0x89, 0xC7, 0x2E, 0x9C, 0xBC, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xC9, 0x6F, 0x3F, 0x74, 0x48, - 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0xA6, 0x83, 0x21, 0xEF, - 0x79, 0x47, 0xFF, 0x64, 0x34, 0xF8, 0x92, 0x04, 0x00, 0x00, 0x28, 0x37, 0x6F, 0x78, 0xE9, 0x90, - 0x8E, 0x8D, 0xF8, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8E, 0xF8, 0xE2, 0x01, 0xA2, 0x9E, 0xFD, 0x78, - 0xDC, 0xC6, 0x47, 0x9B, 0xB7, 0x1F, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x11, 0x1F, 0x39, - 0x4C, 0x85, 0x43, 0x1E, 0xD3, 0xB1, 0x50, 0xC8, 0x8E, 0x7D, 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, - 0xE9, 0xC1, 0xDB, 0xBB, 0x24, 0xC1, 0x2B, 0x78, 0x45, 0x54, 0x24, 0x9D, 0x8A, 0x8D, 0xE8, 0x6C, - 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, 0x47, 0xEC, 0x5B, 0xAF, 0x9E, 0xB8, 0x70, 0xF2, - 0xF6, 0xC3, 0x2E, 0xCB, 0xED, 0x87, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, - 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x24, 0x14, 0xB6, 0x45, 0x95, 0x37, 0x61, 0xBD, 0x7C, 0xE7, 0xEC, - 0xE0, 0xCB, 0x12, 0x00, 0x00, 0xA0, 0xBC, 0xCC, 0x1E, 0x7B, 0xF8, 0x91, 0xD1, 0x11, 0x4E, 0x44, - 0x45, 0xD2, 0xA9, 0xE0, 0x88, 0x2F, 0x1A, 0x20, 0x76, 0xD5, 0x6F, 0xBD, 0x8A, 0x06, 0x88, 0x8B, - 0x0F, 0xFF, 0xF6, 0xE3, 0xC2, 0xFA, 0xDB, 0x8F, 0x87, 0xEC, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, - 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xB3, - 0x5F, 0x7F, 0x6E, 0x2F, 0x7E, 0xCE, 0x05, 0xC8, 0x40, 0xF0, 0x65, 0x09, 0x00, 0x00, 0x50, 0x4E, - 0x66, 0xA4, 0x7F, 0x76, 0xF3, 0x57, 0xF0, 0x8A, 0xA8, 0x48, 0x3A, 0x15, 0x1B, 0xF1, 0xC5, 0xE2, - 0x23, 0xBC, 0xFD, 0xA8, 0x7D, 0xF0, 0xDC, 0xC6, 0x47, 0xF4, 0xF6, 0x23, 0xFE, 0xAD, 0x57, 0xF7, - 0xB7, 0xBE, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, - 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x16, 0xC4, 0x87, 0x1F, 0x20, 0xD7, 0xF0, 0x26, 0x2C, 0x00, 0x00, - 0x50, 0x7E, 0xFE, 0x2B, 0x78, 0x1B, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, 0xA9, 0xD8, 0x88, 0xAF, - 0x41, 0x7C, 0x54, 0x1F, 0x3C, 0x77, 0xB3, 0xF1, 0x51, 0x73, 0xFB, 0x11, 0x7F, 0xF0, 0xDC, 0xDD, - 0x7E, 0xDC, 0xAD, 0xA3, 0x23, 0x9C, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, - 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0xB5, 0x48, 0x7C, 0x04, 0xF3, 0x4E, 0x7C, 0x69, 0x30, - 0xF8, 0xD2, 0x04, 0x00, 0x00, 0x28, 0x27, 0xFF, 0x0D, 0x58, 0x5B, 0x3F, 0x64, 0xA3, 0x61, 0x8A, - 0xE3, 0xC3, 0x4D, 0x05, 0x48, 0xCD, 0xB7, 0x5E, 0xD9, 0xF8, 0x70, 0xB7, 0x1F, 0x41, 0x7C, 0x64, - 0xB9, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x56, 0x1F, 0x1F, 0x6E, 0xDE, 0xF1, 0x3F, 0xE5, 0x4D, 0x58, 0x00, 0x00, - 0xA0, 0xDC, 0xBC, 0x91, 0x81, 0x0D, 0x1D, 0x89, 0x0F, 0xB7, 0x78, 0x7C, 0x54, 0x6F, 0x3F, 0x2E, - 0xAC, 0xC6, 0xC7, 0xE4, 0xED, 0x47, 0x2C, 0x3E, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, - 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xF1, 0xE1, - 0xEF, 0xD8, 0x2D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x94, 0x9B, 0x77, 0xE0, 0xAA, 0xD8, 0x1B, 0xB0, - 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x8C, 0x46, 0xB3, 0xD1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0x44, 0x02, - 0x24, 0x8C, 0x0F, 0xF9, 0xB9, 0x1F, 0xDF, 0x69, 0x7C, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, - 0x64, 0x59, 0x34, 0x3A, 0x88, 0x8F, 0x8C, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x11, - 0x1D, 0xD1, 0xB9, 0x37, 0x61, 0x8D, 0x7D, 0x71, 0x56, 0xF0, 0xE5, 0x09, 0x00, 0x00, 0x50, 0x3E, - 0xDE, 0xBE, 0x25, 0xE3, 0x53, 0x1E, 0x1F, 0x6E, 0xF1, 0xF8, 0x48, 0x7B, 0xFB, 0xF1, 0xA0, 0x9D, - 0x08, 0x0F, 0x37, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x52, 0xC4, 0x47, 0x18, 0x20, 0x2E, - 0x3E, 0xFE, 0x40, 0x7C, 0x44, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x38, 0xE2, - 0x1B, 0x5B, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB9, 0x4D, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, - 0xA9, 0xC0, 0x68, 0x36, 0x1B, 0x1D, 0xEE, 0x47, 0x75, 0xFB, 0x11, 0x0D, 0x90, 0xA6, 0xB7, 0x1F, - 0xF7, 0xE9, 0xDB, 0x0F, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x22, 0xF1, 0x11, 0xAE, 0x3E, - 0x3E, 0xEC, 0x5C, 0x78, 0x84, 0xB7, 0x1F, 0xC4, 0x47, 0x6C, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, - 0xA2, 0x26, 0x62, 0x43, 0xED, 0xC5, 0x6B, 0x8C, 0xF7, 0x8B, 0x2F, 0xDD, 0x15, 0x7C, 0x79, 0x02, - 0x00, 0x00, 0x94, 0x8B, 0xFF, 0x06, 0xAC, 0x9D, 0x9F, 0xD2, 0x51, 0x91, 0x74, 0xF1, 0xB8, 0x48, - 0xB2, 0x30, 0x3C, 0xC2, 0xF8, 0xF0, 0x03, 0x64, 0x66, 0x35, 0x3E, 0x6A, 0xDF, 0x7C, 0x95, 0xFC, - 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0x76, 0x24, 0x3E, 0xE2, - 0x37, 0x1F, 0x6F, 0x04, 0xF1, 0xF1, 0x07, 0xE2, 0xA3, 0xA0, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x34, - 0x9A, 0xCC, 0x3B, 0x71, 0xC7, 0x86, 0xE0, 0x4B, 0x14, 0x00, 0x00, 0xA0, 0x5C, 0x6C, 0x80, 0xAC, - 0x33, 0xDB, 0x2F, 0xD6, 0x61, 0x91, 0x64, 0x2A, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0xF6, - 0xF6, 0xC3, 0xC6, 0x47, 0x83, 0x67, 0x3F, 0xEA, 0x3E, 0x74, 0xD0, 0xBD, 0xF9, 0x4A, 0xDC, 0x7E, - 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x22, 0x3E, 0xA2, 0x37, 0x1F, 0x61, 0x7C, 0x84, - 0x37, 0x1F, 0xC4, 0x47, 0x38, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x91, 0xD1, 0x6C, - 0xDE, 0x89, 0x3F, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x9C, 0xFC, 0x57, 0xF0, 0xAA, 0xB0, 0x48, - 0xB2, 0x78, 0x58, 0x24, 0x5D, 0x18, 0x1E, 0x61, 0x7C, 0x3C, 0x3D, 0xB3, 0xE6, 0xF6, 0xA3, 0xEE, - 0xD9, 0x0F, 0x1B, 0x20, 0xA7, 0xA2, 0x01, 0xF2, 0x23, 0xBB, 0x1E, 0x8C, 0x0F, 0xB7, 0xBA, 0x00, - 0x69, 0x10, 0x1F, 0xE3, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0xC0, - 0x68, 0x35, 0xEF, 0xD8, 0x17, 0xC6, 0x83, 0x2F, 0x51, 0x00, 0x00, 0x80, 0x72, 0xF1, 0x0E, 0x5C, - 0x33, 0x2A, 0xE3, 0xA2, 0xD5, 0x54, 0x58, 0x24, 0x99, 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, - 0xF1, 0x11, 0xBD, 0xFD, 0x88, 0xC5, 0x47, 0xDD, 0xED, 0xC7, 0xB7, 0x6A, 0x6F, 0x3F, 0x74, 0x48, - 0x64, 0x99, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x56, 0x17, 0x1F, 0xEA, 0x8D, 0x57, 0xC4, 0x47, - 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x71, 0x91, 0x68, 0x47, 0x56, 0xF3, 0x26, - 0x2C, 0x00, 0x00, 0x50, 0x4E, 0xDE, 0xDE, 0x25, 0x63, 0x32, 0x30, 0x9A, 0x2D, 0x1E, 0x15, 0x69, - 0x16, 0x86, 0x47, 0x18, 0x1F, 0x69, 0x6F, 0x3F, 0x7E, 0x68, 0x57, 0xB6, 0xF8, 0x70, 0x37, 0x1F, - 0x2E, 0x3E, 0xDC, 0x43, 0xE7, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, - 0xA8, 0x48, 0xB3, 0x97, 0x56, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x4E, 0x66, 0xCF, 0x42, 0x1D, - 0x19, 0x8D, 0xA6, 0xA2, 0x22, 0xE5, 0x2A, 0x01, 0x32, 0xB3, 0xED, 0xDB, 0x0F, 0x1D, 0x12, 0x59, - 0x26, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0xB5, 0x8C, 0x8F, 0xBF, 0x9C, 0xFC, 0xAC, 0x8F, 0x3F, - 0xDC, 0x4B, 0x7C, 0x14, 0x33, 0x15, 0x09, 0x45, 0x4D, 0x04, 0x45, 0xDA, 0xBD, 0x78, 0x8D, 0x0D, - 0x90, 0x3B, 0xD6, 0x05, 0x5F, 0xA6, 0x00, 0x00, 0x00, 0xE5, 0x60, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, - 0xE6, 0xE8, 0xD0, 0x50, 0x13, 0x31, 0x91, 0x6A, 0xD5, 0xDB, 0x8F, 0x20, 0x3E, 0x9A, 0xDD, 0x7E, - 0x84, 0xF1, 0xD1, 0xE0, 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, - 0x0D, 0xE3, 0x23, 0x08, 0x90, 0xE8, 0x07, 0x0D, 0x12, 0x1F, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, - 0xA2, 0x26, 0x62, 0x22, 0xCB, 0x9E, 0xB7, 0x7F, 0x3F, 0x4E, 0xDC, 0xB1, 0x3E, 0xF8, 0x52, 0x05, - 0x00, 0x00, 0x28, 0x07, 0xFF, 0x15, 0xBC, 0x49, 0xDF, 0x80, 0xA5, 0x82, 0x22, 0xC3, 0xFC, 0xF8, - 0x88, 0xDD, 0x7E, 0x54, 0x03, 0xA4, 0xD5, 0xED, 0xC7, 0x3D, 0xBD, 0x1B, 0x1F, 0x95, 0xD7, 0xED, - 0x12, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x24, 0xDA, 0x18, 0x6F, - 0xC2, 0x02, 0x00, 0x00, 0xA5, 0xE3, 0xBF, 0x01, 0x6B, 0xEB, 0x07, 0x75, 0x70, 0x44, 0x27, 0x42, - 0x22, 0xF5, 0xC2, 0x9B, 0x8F, 0x26, 0xB7, 0x1F, 0x13, 0x2E, 0x40, 0x1E, 0x8B, 0xDC, 0x7E, 0x84, - 0xF1, 0xE1, 0xF6, 0xBD, 0xCA, 0xB7, 0x5E, 0xE9, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x26, 0xC2, - 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x11, 0xD1, 0xCE, - 0xBC, 0x63, 0x5F, 0x38, 0x19, 0x7C, 0xA9, 0x02, 0x00, 0x00, 0x94, 0x83, 0x37, 0xBC, 0x62, 0x50, - 0x06, 0x47, 0x74, 0x2A, 0x26, 0xB2, 0x2C, 0x8C, 0x8F, 0xD8, 0xED, 0x47, 0xE2, 0x67, 0x3F, 0xBE, - 0xC9, 0xB7, 0x5D, 0x25, 0x9B, 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, - 0x2A, 0x12, 0x8A, 0x9A, 0x0E, 0x88, 0xB6, 0x77, 0x64, 0xB5, 0x09, 0xBE, 0x54, 0x01, 0x00, 0x00, - 0xCA, 0xC1, 0xDB, 0x7B, 0x79, 0xF3, 0x57, 0xF0, 0xAA, 0x90, 0x48, 0xBB, 0x4D, 0x6E, 0x93, 0xE1, - 0x31, 0x79, 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xFC, 0xF6, 0x43, 0x87, 0x44, - 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0x0D, 0xE3, 0xC3, 0x3D, 0x70, 0x1E, 0x8B, 0x8F, - 0xF1, 0xFF, 0x32, 0xCB, 0x9C, 0xFF, 0xD7, 0x5B, 0x83, 0xF8, 0x58, 0x65, 0x0F, 0xFA, 0x2A, 0x28, - 0xD2, 0x4C, 0x84, 0x43, 0x1E, 0x93, 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, - 0x4D, 0x84, 0x43, 0x5E, 0x3B, 0xB2, 0x92, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF1, 0xF6, 0x2C, - 0x1A, 0x97, 0xE1, 0xE1, 0xA6, 0x62, 0x22, 0xCB, 0x6C, 0x78, 0x44, 0x6F, 0x3F, 0xAA, 0xDF, 0x7A, - 0x15, 0x06, 0x48, 0xCD, 0x6B, 0x77, 0x2F, 0x94, 0xB7, 0x1F, 0xEF, 0x7C, 0x23, 0xAF, 0xDB, 0x0F, - 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x2D, 0x6D, 0x7C, 0x9C, 0xFB, 0xE9, 0x17, 0x2A, 0xF1, 0x71, - 0xD4, 0xFE, 0x28, 0x83, 0x22, 0xCD, 0x44, 0x38, 0xE4, 0x31, 0x19, 0x0E, 0x79, 0x4C, 0x85, 0x43, - 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x44, 0x34, 0xE4, 0x39, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xCA, 0xC4, - 0x0C, 0xF5, 0xCF, 0x32, 0x43, 0x7D, 0x53, 0x1A, 0x1F, 0xE1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xCD, - 0x9E, 0xFD, 0x70, 0xF1, 0x71, 0x7F, 0x5E, 0xB7, 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, - 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x82, 0x21, 0xEF, 0xB9, 0xFF, - 0x6D, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0x0B, 0xFF, 0x0D, 0x58, 0x3B, 0x3E, 0x39, 0xE5, 0xF1, - 0x51, 0x7D, 0xF0, 0x5C, 0xDD, 0x7E, 0xC4, 0x1E, 0x3C, 0x7F, 0xE7, 0x41, 0x1B, 0x1F, 0x5F, 0x57, - 0x31, 0x91, 0x76, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x62, 0xA1, 0xA0, 0x79, 0x27, 0xEE, 0xE0, 0x4D, 0x58, 0x00, 0x00, - 0xA0, 0x1C, 0xBC, 0xE1, 0xFE, 0xBB, 0xCC, 0xB6, 0x8F, 0x14, 0x13, 0x1F, 0xCF, 0x54, 0xE2, 0xA3, - 0x2E, 0x40, 0xE2, 0xAF, 0xDD, 0x75, 0xB7, 0x1F, 0x41, 0x7C, 0xC4, 0x6F, 0x3F, 0xDE, 0x79, 0xD8, - 0xC6, 0xC7, 0x77, 0xF3, 0xF8, 0xD6, 0x2B, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, - 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xA1, 0x50, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, - 0x82, 0x2F, 0x59, 0x00, 0x00, 0x80, 0xDE, 0xE6, 0xBF, 0x82, 0xB7, 0xA8, 0xF8, 0x08, 0x02, 0xA4, - 0xE1, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0x8A, 0xC7, 0x47, 0x2E, 0xB7, 0x1F, 0x22, 0x24, - 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0xA6, - 0x23, 0xA1, 0xD0, 0x1D, 0xB9, 0x91, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF0, 0x0E, 0x5C, 0x33, - 0xF9, 0x06, 0x2C, 0x19, 0x12, 0x59, 0x36, 0x19, 0x1F, 0x8D, 0x6E, 0x3F, 0xAA, 0xAF, 0xDD, 0xAD, - 0xDE, 0x7E, 0x5C, 0x14, 0xBB, 0xFD, 0xB0, 0xE1, 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, - 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x38, 0x98, - 0x8A, 0xBD, 0x34, 0x60, 0xCC, 0xF1, 0x3B, 0x96, 0x04, 0x5F, 0xB6, 0x00, 0x00, 0x00, 0xBD, 0xCB, - 0xDB, 0x77, 0xC5, 0xC9, 0x42, 0xE2, 0xA3, 0xAD, 0xDB, 0x8F, 0x20, 0x3E, 0x1E, 0x68, 0xF7, 0xF6, - 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, - 0x50, 0xD4, 0x44, 0x18, 0x4C, 0xD5, 0xDC, 0x9B, 0xB0, 0x4E, 0x7C, 0x69, 0x6D, 0xF0, 0x65, 0x0B, - 0x00, 0x00, 0xD0, 0xBB, 0xCC, 0xEE, 0xBE, 0x48, 0x3C, 0xB4, 0xBB, 0xDA, 0xF8, 0x70, 0x3F, 0xAA, - 0xDB, 0x8F, 0xFA, 0x67, 0x3F, 0xA2, 0xB7, 0x1F, 0x41, 0x7C, 0xB8, 0xDD, 0xDB, 0xCE, 0xED, 0x87, - 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, - 0xA8, 0x89, 0x28, 0x98, 0xCA, 0xBD, 0x70, 0x25, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xCF, 0x1C, - 0xE8, 0x5F, 0x62, 0x76, 0xCE, 0x0E, 0xE2, 0xA1, 0xDD, 0x45, 0xE2, 0x23, 0x08, 0x90, 0x66, 0xB7, - 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xE1, 0x6E, 0x3F, 0x64, 0x58, 0x24, 0x99, 0x08, 0x89, 0x2C, - 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x20, - 0xE8, 0xC0, 0xBC, 0xE3, 0xB7, 0x0F, 0x05, 0x5F, 0xBA, 0x00, 0x00, 0x00, 0xBD, 0xC9, 0x1C, 0x5C, - 0xB6, 0xD6, 0x6C, 0xFF, 0x58, 0x10, 0x10, 0xED, 0xAC, 0x3E, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0x43, - 0x3D, 0xFB, 0x51, 0xF9, 0xD0, 0xC1, 0x0B, 0x27, 0x03, 0xE4, 0x21, 0xBB, 0xCC, 0xB7, 0x1F, 0x22, - 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, - 0xA6, 0x63, 0xA0, 0x13, 0xF3, 0x8E, 0xDE, 0xC2, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x33, 0x23, - 0xCB, 0xD7, 0x9B, 0xCD, 0xEF, 0xB3, 0xB1, 0xA0, 0xA2, 0x22, 0xE9, 0x62, 0xF1, 0xE1, 0x16, 0x86, - 0x47, 0x18, 0x1F, 0xB1, 0xDB, 0x8F, 0xBA, 0x67, 0x3F, 0x1E, 0xB5, 0xF1, 0xE1, 0x02, 0xA4, 0xED, - 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, - 0x45, 0x42, 0x51, 0xD3, 0x21, 0xD0, 0xB1, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, - 0xE6, 0x1D, 0xB8, 0x7E, 0xA8, 0x36, 0x26, 0xD2, 0x4E, 0xC7, 0x87, 0xFB, 0xB1, 0xE9, 0xED, 0x47, - 0x2C, 0x3E, 0xEA, 0x6E, 0x3F, 0xEE, 0xC9, 0x72, 0xFB, 0x21, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, - 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x00, 0x3A, 0x3D, 0xF7, - 0x26, 0xAC, 0x97, 0xEF, 0x9C, 0x1D, 0x7C, 0xF9, 0x02, 0x00, 0x00, 0xF4, 0x1E, 0x6F, 0xEF, 0x65, - 0xA3, 0xF5, 0x51, 0x91, 0x74, 0xB1, 0xF0, 0x08, 0x17, 0x86, 0x47, 0x18, 0x1F, 0x4D, 0x6F, 0x3F, - 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x4E, 0x06, 0x46, 0xB3, 0x89, 0x90, 0xC8, - 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, - 0xFC, 0x77, 0xC3, 0x5E, 0xFC, 0x9C, 0x31, 0xC7, 0x6E, 0x1B, 0x08, 0xBE, 0x7C, 0x01, 0x00, 0x00, - 0x7A, 0x8F, 0xD9, 0x63, 0x0F, 0x5B, 0x32, 0x2E, 0x5A, 0x4D, 0x84, 0x47, 0x64, 0xC9, 0x6E, 0x3F, - 0x2A, 0xF1, 0xD1, 0xFE, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, - 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xFE, 0xDD, 0x32, 0xDE, 0x84, 0x05, 0x00, - 0x00, 0x7A, 0x99, 0x19, 0xE9, 0x9F, 0x6D, 0x76, 0xCF, 0xB3, 0xC1, 0xA0, 0x02, 0xA3, 0xD9, 0x74, - 0x74, 0xF8, 0x4B, 0x7C, 0xFB, 0x31, 0xD3, 0x9C, 0x09, 0xE3, 0xA3, 0xAD, 0xDB, 0x0F, 0x11, 0x12, - 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xFE, 0x2E, 0x9B, 0x77, 0xE2, 0xF6, 0xC1, 0xE0, 0x4B, 0x18, 0x00, 0x00, 0xA0, 0xB7, 0xD8, - 0x00, 0x19, 0x48, 0xFF, 0x06, 0x2C, 0x11, 0x1D, 0xB1, 0xA9, 0xDB, 0x8F, 0x6A, 0x80, 0x84, 0xF1, - 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, - 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7F, 0xB7, 0xCD, 0x3B, 0xFA, 0x85, 0xD1, 0xE0, 0x4B, - 0x18, 0x00, 0x00, 0xA0, 0xB7, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0x3E, 0x60, 0xA3, 0x41, 0x85, - 0x86, 0x9A, 0x0E, 0x8E, 0xEA, 0x12, 0xDC, 0x7E, 0x4C, 0x3C, 0x31, 0xD3, 0x4C, 0x3C, 0x16, 0xB9, - 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0xFB, 0xC4, 0x47, 0x65, 0x22, 0x1C, 0xF2, 0x98, 0x0C, 0x87, 0x3C, - 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0xB0, 0xDF, 0x95, 0x3B, 0x76, 0x0B, 0x6F, - 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xC9, 0x1B, 0x59, 0xB1, 0xA1, 0x3E, 0x32, 0x1A, 0x4D, 0x04, 0x47, - 0x7C, 0xF1, 0x00, 0xA9, 0x7B, 0xF6, 0xC3, 0xC6, 0x47, 0xB3, 0xDB, 0x8F, 0x6F, 0xA8, 0xD0, 0x50, - 0x13, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, - 0x14, 0x35, 0x71, 0xC8, 0xEF, 0xE6, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xAB, 0xBC, 0x7D, 0x57, - 0x24, 0x7C, 0x03, 0x96, 0x88, 0x8D, 0xE8, 0x6C, 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, - 0x47, 0xE4, 0x5B, 0xAF, 0x06, 0x6D, 0x7C, 0x44, 0x6F, 0x3F, 0xEC, 0x6A, 0x6E, 0x3F, 0x36, 0x24, - 0xBD, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, - 0x54, 0x24, 0x14, 0x35, 0x71, 0xC0, 0xEF, 0xF6, 0x8D, 0x2D, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0xA0, - 0x37, 0x79, 0x7B, 0x2F, 0x1B, 0xAF, 0x8F, 0x8D, 0xF8, 0x62, 0xB1, 0xA1, 0x16, 0x0D, 0x10, 0xBB, - 0xEA, 0xB7, 0x5E, 0x85, 0x01, 0x62, 0xE3, 0x63, 0xF2, 0xF6, 0x63, 0x66, 0x1B, 0xB7, 0x1F, 0x22, - 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, - 0x26, 0x0E, 0xF7, 0xBD, 0xB0, 0x17, 0xAF, 0x31, 0xDE, 0x2F, 0x6E, 0xBF, 0x2B, 0xF8, 0x32, 0x06, - 0x00, 0x00, 0xE8, 0x1D, 0xAD, 0xDF, 0x80, 0x15, 0x0B, 0x0D, 0xB5, 0x58, 0x7C, 0x84, 0xB7, 0x1F, - 0x93, 0x0F, 0x9E, 0xDB, 0xF8, 0x88, 0xDF, 0x7E, 0x84, 0xF1, 0x11, 0x06, 0x48, 0xA2, 0xDB, 0x0F, - 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, - 0x51, 0x13, 0x07, 0xFB, 0x1E, 0x9A, 0x77, 0xFC, 0x8E, 0x0D, 0xC1, 0x97, 0x31, 0x00, 0x00, 0x40, - 0x6F, 0xF0, 0xDF, 0x80, 0xB5, 0x73, 0xB6, 0x8D, 0x08, 0x15, 0x1E, 0x6E, 0xB1, 0xD0, 0x50, 0x6B, - 0x10, 0x1F, 0xD5, 0x07, 0xCF, 0x37, 0xCE, 0xAC, 0xBF, 0xFD, 0x08, 0xE2, 0xA3, 0x7A, 0xFB, 0xF1, - 0xA0, 0xDD, 0xD7, 0x55, 0x70, 0x44, 0x27, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, - 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0x50, 0xDF, 0x4B, 0xF3, 0x8E, 0xDE, 0xCA, - 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x31, 0x23, 0xCB, 0xD7, 0x35, 0x7E, 0x05, 0x6F, 0x2C, 0x34, - 0x1A, 0x4D, 0x05, 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x41, 0x7C, 0xC8, 0x37, - 0x5F, 0x7D, 0xB7, 0xD5, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, - 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7D, 0xAF, 0xCD, 0x3B, 0xFA, 0xF9, 0xF1, - 0xE0, 0x4B, 0x19, 0x00, 0x00, 0xA0, 0x37, 0xD8, 0x00, 0x59, 0x5F, 0x1F, 0x1E, 0x29, 0xE2, 0xC3, - 0x2D, 0x1E, 0x1F, 0xD5, 0xDB, 0x8F, 0xC9, 0xF8, 0xA8, 0x79, 0xF3, 0x55, 0xEA, 0xDB, 0x0F, 0x11, - 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, - 0xD3, 0x87, 0xF9, 0x9E, 0x9C, 0x7B, 0x13, 0xD6, 0xD8, 0x17, 0x67, 0x05, 0x5F, 0xCE, 0x00, 0x00, - 0x00, 0xDD, 0xCF, 0x3B, 0x70, 0xD5, 0x50, 0xBB, 0xF1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0xD4, 0xDD, - 0x7E, 0x5C, 0x98, 0xE1, 0xF6, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, - 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBE, 0x97, 0x37, 0xB6, 0x9C, 0x37, 0x61, - 0x01, 0x00, 0x80, 0xDE, 0xE2, 0xED, 0xBD, 0x7C, 0x2C, 0x73, 0x7C, 0xB8, 0xC5, 0xE3, 0xC3, 0x0F, - 0x90, 0x19, 0x39, 0xDD, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, - 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xC0, 0xF7, 0xFA, 0x78, 0x13, 0x16, 0x00, 0x00, - 0xE8, 0x35, 0x66, 0x68, 0x81, 0x0D, 0x89, 0xEC, 0xF1, 0xE1, 0x7E, 0xAC, 0xBD, 0xFD, 0xB0, 0xF1, - 0x11, 0xFB, 0xF6, 0xAB, 0xA6, 0xB7, 0x1F, 0xF7, 0x35, 0xBA, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, - 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x78, 0x2F, - 0xC3, 0x9E, 0xBF, 0x9C, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, 0x61, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, - 0x2E, 0xB5, 0x11, 0x91, 0x21, 0x3E, 0xDC, 0xC2, 0xF0, 0x08, 0xE3, 0xE3, 0xE9, 0x19, 0x35, 0xB7, - 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xF1, 0x80, 0x1D, 0xF1, 0x91, 0xCF, 0x64, 0x38, 0xE4, 0x31, - 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x07, 0xF7, 0x12, 0xCD, 0x3B, 0xFE, 0x67, 0xBC, - 0x09, 0x0B, 0x00, 0x00, 0xF4, 0x06, 0xFF, 0x15, 0xBC, 0xFE, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, - 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, 0xF1, 0xD1, 0xE0, 0xD9, 0x0F, 0xF9, 0xA1, 0x83, 0xF7, - 0xAA, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, - 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x87, 0xF6, 0x32, 0xCD, 0x3B, 0xFA, 0xF9, 0x93, 0xC1, 0x97, 0x34, - 0x00, 0x00, 0x40, 0x77, 0xF3, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0xF5, 0x71, 0x91, 0x64, 0x61, 0x78, - 0x84, 0xF1, 0x11, 0xBB, 0xFD, 0xA8, 0x7B, 0xF6, 0xC3, 0x06, 0xC8, 0x29, 0x17, 0x20, 0x4D, 0x6F, - 0x3F, 0x44, 0x48, 0x64, 0x99, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, - 0x09, 0x45, 0x4D, 0x1F, 0xD8, 0x4B, 0xB7, 0x23, 0xAB, 0x4C, 0xF0, 0x25, 0x0D, 0x00, 0x00, 0xD0, - 0xDD, 0xBC, 0xE1, 0x65, 0x83, 0x32, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0x12, 0x20, 0x33, - 0xF4, 0xED, 0x47, 0x2C, 0x3E, 0x5A, 0xDF, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, - 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA8, 0x97, 0x75, 0x63, 0xCB, - 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0D, 0xDE, 0xDE, 0xCB, 0x46, 0xEB, 0xE2, 0x22, 0xC9, 0xAA, - 0xB7, 0x1F, 0x41, 0x7C, 0x24, 0xBD, 0xFD, 0x08, 0x03, 0xE4, 0x07, 0x76, 0xC4, 0x47, 0x7B, 0x93, - 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0xBA, 0x7F, - 0x5D, 0x68, 0xCC, 0x0B, 0x57, 0x1B, 0x73, 0xFC, 0x8E, 0x75, 0xC1, 0x97, 0x35, 0x00, 0x00, 0x40, - 0xF7, 0xF2, 0xF6, 0x2C, 0x18, 0x97, 0x81, 0xD1, 0x6C, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0x59, 0x6F, - 0x3F, 0xEE, 0x89, 0xDE, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, - 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2E, 0x3E, 0xDC, 0x7E, 0x6E, - 0xFF, 0x99, 0x38, 0x71, 0xDB, 0xFA, 0xE0, 0xCB, 0x1A, 0x00, 0x00, 0xA0, 0x3B, 0x99, 0xA1, 0xFE, - 0x59, 0x66, 0xF7, 0xDC, 0xFA, 0xC0, 0x68, 0xB5, 0xF0, 0xE6, 0x23, 0x97, 0xDB, 0x0F, 0x11, 0x12, - 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xF4, 0xB2, 0x2E, 0x8C, 0x8F, 0x60, 0xDE, 0x89, 0xDB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, - 0x6E, 0x66, 0x64, 0xE9, 0x80, 0xD9, 0xF1, 0x71, 0x1D, 0x19, 0xCD, 0x16, 0xC6, 0x47, 0xDB, 0xB7, - 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, - 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x5D, 0x2C, 0x3E, 0xFC, 0x00, 0x39, 0x7A, 0x33, 0x6F, 0xC2, - 0x02, 0x00, 0x00, 0xDD, 0xCD, 0x1B, 0x5E, 0x7E, 0x97, 0xD9, 0xFA, 0x21, 0x1D, 0x19, 0x8D, 0x16, - 0x8F, 0x8F, 0x66, 0xB7, 0x1F, 0x61, 0x7C, 0xC8, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, - 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, - 0xC4, 0x87, 0xBF, 0x23, 0x37, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xDD, 0xFC, 0x57, 0xF0, 0xAA, - 0xC8, 0x68, 0x34, 0x1B, 0x1D, 0x8D, 0x6E, 0x3F, 0xAA, 0x01, 0xD2, 0xEA, 0xF6, 0xE3, 0x1B, 0xC4, - 0x47, 0xA6, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, - 0x65, 0x9D, 0x0A, 0x8F, 0x70, 0x2F, 0xF5, 0xBB, 0x07, 0xD1, 0x97, 0x04, 0x5F, 0xDE, 0x00, 0x00, - 0x00, 0xDD, 0xC7, 0x3B, 0x70, 0x75, 0xF2, 0x37, 0x60, 0x45, 0xE3, 0xC3, 0x86, 0x47, 0xA3, 0xDB, - 0x8F, 0x09, 0x17, 0x20, 0x8F, 0x45, 0x6E, 0x3F, 0xC2, 0xF8, 0x70, 0xDB, 0xE0, 0xBE, 0xF5, 0x4A, - 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, - 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xD1, 0x11, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x3F, 0x5F, 0x1B, - 0x7C, 0x79, 0x03, 0x00, 0x00, 0x74, 0x1F, 0x6F, 0xDF, 0xE5, 0x27, 0x65, 0x6C, 0xC4, 0x17, 0xC4, - 0x47, 0xA3, 0xDB, 0x8F, 0xC4, 0xCF, 0x7E, 0x7C, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, - 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xC1, - 0x11, 0x1F, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xDD, 0x2E, 0xD1, 0x1B, 0xB0, 0xE2, 0xF1, 0x51, 0x73, - 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xED, 0xED, 0x47, 0x4E, 0xDF, 0x7A, 0x25, - 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, - 0xB2, 0x4E, 0xC5, 0x46, 0x83, 0x79, 0xC7, 0x6F, 0x1F, 0x0A, 0xBE, 0xBC, 0x01, 0x00, 0x00, 0xBA, - 0x8B, 0x39, 0x70, 0xFD, 0x12, 0xB3, 0xF3, 0x53, 0x3A, 0x3A, 0xC2, 0x45, 0xE2, 0xA3, 0x1A, 0x20, - 0x76, 0xD5, 0x6F, 0xBD, 0x0A, 0x03, 0xA4, 0xE6, 0xB5, 0xBB, 0x33, 0xC5, 0xED, 0xC7, 0xCC, 0x7C, - 0x6E, 0x3F, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, - 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0xC8, 0x68, 0x36, 0xEF, 0xC8, 0x9A, 0xB1, 0xE0, 0x4B, 0x1C, 0x00, - 0x00, 0xA0, 0xBB, 0x98, 0x83, 0xCB, 0xD6, 0x9A, 0xED, 0x1F, 0xD5, 0xE1, 0xE1, 0x16, 0x09, 0x8F, - 0x68, 0x7C, 0x84, 0xB7, 0x1F, 0x35, 0x0F, 0x9E, 0x37, 0x7A, 0xF6, 0xC3, 0x0F, 0x10, 0x1B, 0x1F, - 0xDF, 0xCD, 0xE1, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, - 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x08, 0x8C, 0x96, 0x3B, 0xBA, 0x86, 0x37, 0x61, 0x01, - 0x00, 0x80, 0xEE, 0xE4, 0xBF, 0x01, 0x6B, 0xF3, 0xAC, 0x4C, 0xF1, 0x51, 0x7D, 0xF0, 0x5C, 0xDD, - 0x7E, 0x04, 0xF1, 0x51, 0xB9, 0xFD, 0xB0, 0xF1, 0xF1, 0xA0, 0xDD, 0xD7, 0x45, 0x50, 0xA4, 0x99, - 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, - 0xCB, 0x3A, 0x15, 0x17, 0x49, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB7, 0xF2, 0x0E, 0x7C, 0x6E, - 0x28, 0x49, 0x7C, 0xD4, 0x05, 0x48, 0xFC, 0xB5, 0xBB, 0xEE, 0xF6, 0x23, 0x88, 0x8F, 0xDA, 0x37, - 0x5F, 0xD9, 0xF0, 0xC8, 0xE3, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x0A, 0x8B, 0xA4, 0x7B, 0xE1, 0x5A, 0x63, - 0x8E, 0xDD, 0x36, 0x10, 0x7C, 0x99, 0x03, 0x00, 0x00, 0x74, 0x0F, 0x6F, 0xEF, 0x65, 0xF5, 0xAF, - 0xE0, 0x8D, 0x44, 0x87, 0x8C, 0x8F, 0xE8, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0xAA, 0xDE, - 0x7E, 0x04, 0xF1, 0xD1, 0xEE, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, - 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x15, 0x69, 0xF6, 0xFC, 0x67, 0x79, - 0x13, 0x16, 0x00, 0x00, 0xE8, 0x4E, 0x66, 0x8F, 0x3D, 0xEC, 0xB4, 0x88, 0x0F, 0x37, 0x75, 0xFB, - 0x51, 0x7D, 0xED, 0x6E, 0xF5, 0xF6, 0xE3, 0xC2, 0xC8, 0xED, 0x47, 0x10, 0x1F, 0xED, 0xDE, 0x7E, - 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x62, 0x07, - 0xF4, 0x32, 0x4F, 0x05, 0x45, 0x86, 0x79, 0x27, 0x6E, 0x1B, 0x0C, 0xBE, 0xCC, 0x01, 0x00, 0x00, - 0xBA, 0x83, 0x19, 0xE9, 0x9F, 0x5D, 0xF3, 0x0A, 0xDE, 0x48, 0x70, 0x44, 0x97, 0xFE, 0xF6, 0x63, - 0xE6, 0x64, 0x80, 0x3C, 0x60, 0xA7, 0xC2, 0x22, 0xC9, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, - 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0x90, 0xC8, 0x3A, 0xEF, - 0xC8, 0xE7, 0x47, 0x83, 0x2F, 0x75, 0x00, 0x00, 0x80, 0xEE, 0x60, 0x46, 0x96, 0x0E, 0x54, 0xDF, - 0x80, 0x15, 0x09, 0x8E, 0xF8, 0xD4, 0xED, 0x47, 0xFD, 0xB3, 0x1F, 0xE1, 0xED, 0x47, 0x24, 0x3E, - 0xDC, 0xEE, 0xCD, 0x78, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, - 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x44, 0x44, 0x5B, 0xE3, 0x4D, 0x58, 0x00, 0x00, - 0xA0, 0xDB, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0xDE, 0x2F, 0xA3, 0x23, 0x5C, 0xB3, 0xDB, 0x8F, - 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0xC8, 0x7A, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, - 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x05, 0x44, 0xBB, 0x73, 0x6F, - 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x3B, 0x00, 0x00, 0x40, 0xE7, 0x79, 0x23, 0xCB, 0x36, - 0xA8, 0xE8, 0x88, 0x4E, 0xDD, 0x7E, 0xD4, 0x3F, 0xFB, 0xE1, 0x3E, 0x74, 0xD0, 0xBD, 0x7A, 0x37, - 0x12, 0x20, 0xEE, 0x43, 0x07, 0xB3, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, - 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xF1, 0x90, 0xC7, 0x5E, 0xBC, - 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, 0xEE, 0xE2, 0xED, 0xBD, 0x62, 0x54, 0x45, 0x47, 0xB8, 0x66, - 0xB7, 0x1F, 0xD5, 0x67, 0x3F, 0xFC, 0xD7, 0xEE, 0x06, 0xF1, 0xE1, 0xD6, 0xCE, 0xED, 0x87, 0x08, - 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, - 0x3A, 0x15, 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x2E, 0xDE, 0xDE, - 0xC5, 0xE3, 0x2A, 0x3C, 0xC2, 0x35, 0xBD, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC5, 0x87, 0xBA, 0xFD, - 0xB8, 0x27, 0xE5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, - 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x0D, 0x39, 0xCF, 0x3B, 0xB6, 0x96, 0x37, 0x61, - 0x01, 0x00, 0x80, 0xEE, 0xE1, 0xBF, 0x01, 0x2B, 0x12, 0x1C, 0xD1, 0xB5, 0xBC, 0xFD, 0xB0, 0xF1, - 0x31, 0xF1, 0xD8, 0x8C, 0xDA, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x60, 0xA7, 0x22, 0xA3, 0xD1, 0x44, - 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, - 0xD6, 0x89, 0x58, 0x28, 0x62, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0E, 0xFE, - 0x1B, 0xB0, 0x76, 0x7C, 0x52, 0xC6, 0x87, 0x5B, 0xCB, 0xDB, 0x8F, 0x30, 0x3E, 0xDA, 0xBD, 0xFD, - 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, - 0x7A, 0x59, 0x27, 0x42, 0xA1, 0xA8, 0x79, 0x47, 0x6F, 0x1E, 0x0F, 0xBE, 0xE4, 0x01, 0x00, 0x00, - 0x3A, 0xCB, 0x8C, 0x2C, 0x5F, 0x67, 0xB6, 0x7D, 0xA4, 0x75, 0x7C, 0xC8, 0xDB, 0x8F, 0x19, 0xF9, - 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, - 0xC4, 0x21, 0xBD, 0xAC, 0x13, 0x91, 0x50, 0xE8, 0xDC, 0x9B, 0xB0, 0xC6, 0xBE, 0x38, 0x2B, 0xF8, - 0xB2, 0x07, 0x00, 0x00, 0xE8, 0x1C, 0x1B, 0x20, 0xEB, 0x55, 0x7C, 0xB8, 0xA9, 0xDB, 0x0F, 0x3F, - 0x40, 0x44, 0x7C, 0x64, 0xBE, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, - 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA1, 0xE8, 0xF1, 0x26, 0x2C, 0x00, - 0x00, 0xD0, 0x2D, 0xBC, 0x03, 0x57, 0x0D, 0x35, 0x8C, 0x0F, 0x1B, 0x1E, 0xF2, 0xF6, 0xE3, 0x09, - 0x1B, 0x1F, 0x2E, 0x40, 0x1E, 0x8D, 0xDC, 0x7E, 0x84, 0xF1, 0xE1, 0xB6, 0x81, 0xF8, 0xA8, 0x9B, - 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xA9, - 0x38, 0x98, 0x8A, 0xBD, 0x70, 0xB5, 0xF1, 0x7E, 0x71, 0xFB, 0x5D, 0xC1, 0x97, 0x3D, 0x00, 0x00, - 0x40, 0xE7, 0x78, 0x7B, 0x2F, 0x1B, 0x6B, 0x18, 0x20, 0x6E, 0x91, 0xDB, 0x0F, 0x17, 0x1F, 0x67, - 0x07, 0x67, 0xD4, 0xDE, 0x7E, 0xA8, 0x67, 0x3F, 0xBE, 0x21, 0x62, 0x23, 0x3E, 0x11, 0x1E, 0x6E, - 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2A, - 0x0C, 0xA6, 0x70, 0xDE, 0xF1, 0xDB, 0x36, 0x04, 0x5F, 0xF6, 0x00, 0x00, 0x00, 0x9D, 0x63, 0x86, - 0xE6, 0xEB, 0xF8, 0xA8, 0xB9, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC6, 0x47, 0x1E, 0xB7, 0x1F, 0x22, - 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, - 0xEB, 0x44, 0x10, 0x4C, 0xF5, 0xBC, 0xE3, 0x7F, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x67, 0x99, - 0x91, 0xFE, 0xD9, 0x66, 0xE7, 0x25, 0x3A, 0x40, 0xEC, 0xA2, 0xDF, 0x7A, 0x75, 0xEE, 0xC9, 0x19, - 0xE6, 0xAC, 0x8D, 0x8F, 0xC9, 0xDB, 0x8F, 0x19, 0xFA, 0xD9, 0x8F, 0x56, 0xB7, 0x1F, 0x22, 0x3C, - 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, - 0x44, 0x0C, 0x74, 0x62, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x74, 0x9C, 0xFF, 0x0A, 0xDE, 0xD8, 0x1B, - 0xB0, 0x6A, 0xBE, 0xF5, 0xCA, 0xEE, 0x9C, 0x0B, 0x10, 0x17, 0x1F, 0xF1, 0xDB, 0x8F, 0x68, 0x7C, - 0x84, 0x01, 0x72, 0x7F, 0x8B, 0xDB, 0x0F, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, - 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x22, 0x04, 0x3A, 0xB6, 0x97, 0x56, 0x99, - 0xE0, 0x4B, 0x1F, 0x00, 0x00, 0xA0, 0x33, 0xFC, 0x37, 0x60, 0x6D, 0xFE, 0xE3, 0x86, 0xF1, 0x51, - 0xB9, 0xFD, 0xB0, 0xF1, 0xD1, 0xE0, 0xF6, 0xC3, 0xC5, 0x47, 0xF5, 0xF6, 0xE3, 0x41, 0xBB, 0xAF, - 0x8B, 0xE8, 0x08, 0x27, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, - 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x45, 0x40, 0x27, 0x37, 0xB6, 0x8C, 0x37, 0x61, 0x01, 0x00, - 0x80, 0xCE, 0xF2, 0x86, 0x97, 0x0D, 0x36, 0xBC, 0xFD, 0x08, 0xE2, 0xA3, 0xE6, 0xF6, 0x23, 0x88, - 0x8F, 0x9A, 0xDB, 0x8F, 0xF0, 0xD9, 0x8F, 0xEF, 0x36, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, - 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA0, - 0xD3, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0xF2, 0x07, 0x00, 0x00, 0x98, 0x7A, - 0xDE, 0xDE, 0xCB, 0x46, 0x1B, 0xDE, 0x7E, 0x6C, 0xBC, 0xA0, 0x26, 0x3E, 0xEA, 0x3E, 0x74, 0x30, - 0xE9, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, - 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x75, 0xF8, 0xEF, 0xF8, 0x16, 0xD8, 0x5F, 0x9B, 0xFD, 0xDF, 0xE1, - 0xC4, 0x6D, 0xEB, 0x83, 0x2F, 0x7F, 0x00, 0x00, 0x80, 0xA9, 0xE7, 0xED, 0x9E, 0x3F, 0xAE, 0x6F, - 0x3F, 0x6C, 0x7C, 0x84, 0xDF, 0x7A, 0x55, 0x73, 0xFB, 0x31, 0x33, 0xDD, 0xED, 0x87, 0x08, 0x0F, - 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0xB1, 0x78, 0x20, 0x14, 0x39, 0x71, 0x48, 0x2F, 0xEB, - 0xE4, 0xE1, 0xBF, 0xD3, 0xB3, 0xF1, 0x11, 0xCC, 0x3B, 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x80, - 0xCE, 0x30, 0x43, 0xFD, 0xB3, 0xCC, 0xEE, 0xB9, 0x32, 0x3E, 0x72, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, - 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, - 0x0F, 0xFF, 0x9D, 0xDE, 0x64, 0x7C, 0xF8, 0x01, 0x72, 0xF4, 0xE6, 0x93, 0xC1, 0x1F, 0x01, 0x00, - 0x00, 0x00, 0x53, 0xCB, 0x7F, 0x03, 0xD6, 0xF6, 0x8B, 0x6B, 0x03, 0x24, 0x8C, 0x0F, 0xF9, 0xEC, - 0x47, 0x83, 0xDB, 0x8F, 0x7B, 0xC5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, - 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x6A, 0xE3, - 0xC3, 0xDF, 0x91, 0x1B, 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0C, 0x33, 0xB2, 0x7C, 0x9D, 0xD9, - 0xFA, 0xC1, 0xC8, 0xED, 0x87, 0x8D, 0x8F, 0xD8, 0xED, 0x47, 0xED, 0x9B, 0xAF, 0x44, 0x7C, 0x3C, - 0x60, 0x47, 0x7C, 0x14, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, - 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x11, 0x1F, 0x6E, 0x2F, 0xF5, 0xF3, 0x26, 0x2C, 0x00, 0x00, 0xD0, - 0x19, 0xE6, 0xE0, 0xF2, 0xF5, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xEC, 0xC7, - 0xE9, 0x78, 0x80, 0xB8, 0x0F, 0x1D, 0x8C, 0xDF, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, - 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, - 0x84, 0x47, 0x38, 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x00, 0x00, 0x00, 0x60, - 0xEA, 0x78, 0xFB, 0xAE, 0x1E, 0xAD, 0x89, 0x8F, 0x24, 0xCF, 0x7E, 0xB8, 0x35, 0xBA, 0xFD, 0x10, - 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, - 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x88, 0x8E, 0xE8, 0xDC, 0x3F, 0x67, 0xBC, 0x09, 0x0B, 0x00, - 0x00, 0x74, 0x82, 0xB7, 0xF7, 0xF2, 0x93, 0x7E, 0x7C, 0x34, 0xBA, 0xFD, 0x88, 0xC6, 0x87, 0xBA, - 0xFD, 0xF8, 0x76, 0xE4, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, - 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x38, 0xC4, 0xBC, - 0xE3, 0xB7, 0x0F, 0x05, 0x7F, 0x0C, 0x00, 0x00, 0x00, 0x4C, 0x1D, 0x6F, 0xE7, 0x9C, 0xF4, 0xB7, - 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x8E, 0xF8, 0xC8, 0x71, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, - 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x36, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, - 0x82, 0x3F, 0x06, 0x00, 0x00, 0x00, 0xA6, 0x86, 0x39, 0x70, 0xFD, 0x12, 0x6F, 0xFB, 0x27, 0xB2, - 0xDF, 0x7E, 0xDC, 0x13, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, - 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x87, 0x46, 0xC3, - 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xD5, 0xCC, 0xC1, 0x65, 0x6B, 0xBD, 0xAD, 0x1F, 0x6E, 0xEF, - 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, - 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x30, 0x5A, 0xCD, 0xBD, 0x09, 0xEB, 0xF8, - 0x1D, 0x4B, 0x82, 0x3F, 0x0E, 0x00, 0x00, 0x00, 0x8A, 0x77, 0xFE, 0xE0, 0xD2, 0xF5, 0xDE, 0xA6, - 0x0B, 0x33, 0xDE, 0x7E, 0x10, 0x1F, 0xF9, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, - 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC4, 0x45, 0x92, 0xBD, 0x70, 0x0D, 0x6F, 0xC2, - 0x02, 0x00, 0x00, 0x53, 0xEB, 0xFC, 0xFE, 0x6B, 0x06, 0xB3, 0xDD, 0x7E, 0xCC, 0x90, 0xE1, 0xE1, - 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, - 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x8B, 0xA4, 0x7B, 0xFE, 0x0A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xA6, - 0xD6, 0xF9, 0xDD, 0x8B, 0x47, 0xA3, 0xB7, 0x1F, 0xD5, 0x00, 0x89, 0xC5, 0x47, 0xDD, 0xED, 0xC7, - 0xDD, 0xC4, 0x47, 0xFB, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, - 0xE4, 0xE1, 0xBF, 0xD3, 0x13, 0x51, 0x91, 0x72, 0xDE, 0xB1, 0xB5, 0xBC, 0x09, 0x0B, 0x00, 0x00, - 0x4C, 0x1D, 0x6F, 0xF7, 0x42, 0x79, 0xFB, 0x31, 0xE1, 0x02, 0xE4, 0xD1, 0xC8, 0xED, 0x47, 0x18, - 0x1F, 0x6E, 0xF7, 0xEB, 0x6F, 0xBD, 0x22, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, - 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x07, 0x45, 0xDA, 0x79, 0x47, 0x3E, - 0x3F, 0x1A, 0xFC, 0x71, 0x00, 0x00, 0x00, 0x50, 0x2C, 0x33, 0xD2, 0x3F, 0xDB, 0xDB, 0x31, 0x27, - 0xDD, 0xB3, 0x1F, 0x0F, 0xCE, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, - 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x98, 0xC8, 0xB4, 0xA3, - 0x6B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x1A, 0x66, 0xFF, 0xD2, 0x81, 0xF3, 0x5B, 0x3E, 0x6C, - 0x03, 0x24, 0xF2, 0xAD, 0x57, 0xCD, 0x6E, 0x3F, 0x1E, 0xB2, 0xF1, 0x21, 0x6E, 0x3F, 0x88, 0x8F, - 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, - 0xD3, 0x13, 0x11, 0xD1, 0xCE, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0x73, 0x76, 0xF0, 0xC7, 0x02, 0x00, - 0x00, 0x40, 0x71, 0xCE, 0xED, 0x5F, 0x7A, 0xD7, 0xF9, 0x4D, 0xEF, 0x9B, 0x7C, 0xF6, 0xA3, 0xE6, - 0xC1, 0xF3, 0x19, 0xB5, 0xCF, 0x7E, 0xB8, 0xF8, 0x78, 0xA0, 0xFE, 0xF6, 0x83, 0xF8, 0x48, 0x33, - 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, - 0x11, 0x10, 0xED, 0xCE, 0xBD, 0x09, 0xEB, 0xD8, 0x6D, 0x03, 0xC1, 0x1F, 0x0B, 0x00, 0x00, 0x00, - 0xC5, 0x39, 0x7F, 0x60, 0xD9, 0x86, 0x9A, 0x07, 0xCF, 0xA3, 0xB7, 0x1F, 0xD1, 0xF8, 0x78, 0xD8, - 0x86, 0x87, 0x0B, 0x90, 0xEF, 0xD4, 0xDE, 0x7E, 0x10, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x21, 0x8F, 0xF1, - 0x26, 0x2C, 0x00, 0x00, 0x30, 0x55, 0xCE, 0xEF, 0x5E, 0x32, 0xEA, 0xC7, 0x47, 0x83, 0xDB, 0x0F, - 0x17, 0x1F, 0xA7, 0xC2, 0xF8, 0x70, 0xB7, 0x1F, 0x7F, 0x4D, 0x7C, 0x64, 0x9B, 0x0A, 0x87, 0x3C, - 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x87, 0x1C, - 0xE7, 0x9D, 0xB8, 0x6D, 0x30, 0xF8, 0x63, 0x01, 0x00, 0x00, 0xA0, 0x38, 0xE7, 0x76, 0x2E, 0x3A, - 0x59, 0x73, 0xFB, 0x11, 0xC4, 0x47, 0xF5, 0xD9, 0x8F, 0x30, 0x3E, 0x62, 0xB7, 0x1F, 0xC4, 0x47, - 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, - 0xE9, 0xE9, 0x68, 0xC8, 0x73, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0xDE, 0xF9, - 0xED, 0x73, 0xAA, 0xF1, 0x51, 0xF7, 0xA1, 0x83, 0x8F, 0xCC, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, - 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, - 0xE9, 0x60, 0xC8, 0x7D, 0x47, 0x3F, 0xCF, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB1, 0xCE, 0xEE, 0x5F, - 0x3A, 0x70, 0x6E, 0xCB, 0x27, 0x63, 0xB7, 0x1F, 0x33, 0x2B, 0xCF, 0x7E, 0x44, 0xE3, 0xC3, 0xED, - 0xDE, 0xCA, 0xED, 0x07, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, - 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x14, 0x8A, 0x9A, 0x7B, 0x13, 0xD6, 0xD8, 0x17, - 0x67, 0x05, 0x7F, 0x3C, 0x00, 0x00, 0x00, 0xE4, 0xEF, 0xDC, 0xDE, 0xE5, 0xEB, 0xCE, 0x6D, 0xFA, - 0x48, 0xEC, 0xF6, 0x63, 0x46, 0x35, 0x3E, 0xAA, 0x01, 0xF2, 0x23, 0x3B, 0xE2, 0x23, 0xE5, 0x54, - 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x44, - 0x24, 0x14, 0xB9, 0x17, 0xAF, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x58, 0xE7, 0xF7, 0x2E, 0x5F, - 0x5F, 0xF7, 0xEC, 0xC7, 0x8F, 0x27, 0x03, 0xA4, 0x7A, 0xFB, 0xF1, 0xED, 0x0B, 0x88, 0x8F, 0x54, - 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, - 0x13, 0x81, 0x50, 0xF4, 0x5E, 0xB8, 0xCA, 0x78, 0xBF, 0xB8, 0xFD, 0xAE, 0xE0, 0x8F, 0x07, 0x00, - 0x00, 0x80, 0xFC, 0x9D, 0xDB, 0x7D, 0xD5, 0x50, 0xCD, 0x9B, 0xAF, 0xC2, 0xF8, 0x88, 0x06, 0xC8, - 0x8F, 0x66, 0x10, 0x1F, 0xA9, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, - 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x60, 0x8A, 0xE6, 0x1D, 0xBF, 0x6D, 0x43, 0xF0, 0xC7, - 0x03, 0x00, 0x00, 0x40, 0xFE, 0xCE, 0xED, 0xB8, 0x6C, 0x6C, 0xF2, 0xF6, 0xE3, 0x02, 0x79, 0xFB, - 0xF1, 0x76, 0xE4, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x06, 0x53, 0x35, 0xDE, 0x84, 0x05, 0x00, - 0x00, 0x0A, 0x75, 0x76, 0xDB, 0xFC, 0xE0, 0xF6, 0xC3, 0xC6, 0x87, 0x78, 0xF6, 0xE3, 0xED, 0x1F, - 0x4C, 0xDE, 0x7E, 0x10, 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, - 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0xA3, 0x60, 0x2A, 0xE7, 0x1D, 0xBD, 0x79, 0x3C, 0xF8, - 0xE3, 0x01, 0x00, 0x00, 0x20, 0x5F, 0x66, 0xA8, 0x7F, 0xF6, 0xD9, 0xCD, 0x97, 0x04, 0xF1, 0x51, - 0x7B, 0xFB, 0x71, 0x2A, 0xBC, 0xFD, 0xF8, 0x66, 0xE5, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, - 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x04, - 0x53, 0xBE, 0x97, 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x8C, 0xB3, 0x43, 0x4B, 0x07, 0xDE, - 0xDD, 0xF8, 0xE1, 0x6A, 0x80, 0x9C, 0xB6, 0x01, 0x52, 0xF3, 0xEC, 0xC7, 0xF7, 0x2B, 0xB7, 0x1F, - 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, - 0xF0, 0xDF, 0xE9, 0x89, 0x10, 0xE8, 0xD4, 0xC6, 0x96, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x0C, - 0x1B, 0x20, 0xEB, 0x27, 0x06, 0xDF, 0x57, 0x73, 0xFB, 0x11, 0x7D, 0xFE, 0xC3, 0xDD, 0x7E, 0x10, - 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, - 0x7F, 0xA7, 0x27, 0x22, 0xA0, 0x93, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0x63, - 0x02, 0x00, 0x00, 0x20, 0x3F, 0xEF, 0xEE, 0x59, 0x3A, 0xE8, 0xDF, 0x7E, 0x88, 0xF8, 0x70, 0xB7, - 0x1F, 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, - 0xF2, 0xF0, 0xDF, 0xE9, 0x89, 0x00, 0xE8, 0xF4, 0xDC, 0x3F, 0x17, 0x27, 0x6E, 0x5B, 0x1F, 0xFC, - 0x31, 0x01, 0x00, 0x00, 0x90, 0x9F, 0x89, 0x6D, 0x8B, 0x47, 0xEB, 0xDE, 0x7C, 0x15, 0xDE, 0x7E, - 0xDC, 0x4D, 0x7C, 0x34, 0x9F, 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xE9, 0x65, - 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xE2, 0xF0, 0xDF, 0x25, 0xF3, 0x8E, 0xAF, 0xE5, 0x4D, 0x58, 0x00, - 0x00, 0x20, 0x7F, 0x13, 0x5B, 0xFA, 0xC6, 0xE5, 0xC3, 0xE7, 0xF7, 0xBB, 0x6F, 0xBD, 0x22, 0x3E, - 0x1A, 0x4F, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, - 0x4E, 0x4F, 0x1F, 0xFC, 0xBB, 0x65, 0xDE, 0xD1, 0x9B, 0x4F, 0x06, 0x7F, 0x4C, 0x00, 0x00, 0x00, - 0xE4, 0xC3, 0x0C, 0xF5, 0xCF, 0x7A, 0xF7, 0x99, 0x39, 0x95, 0xF8, 0xB0, 0x8B, 0x3E, 0x7C, 0xFE, - 0xD6, 0x5F, 0x11, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, - 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFD, 0x5D, 0xB5, 0x97, 0x56, 0x9A, 0xE0, 0x8F, 0x0A, - 0x00, 0x00, 0x80, 0x7C, 0xB8, 0x37, 0x60, 0x4D, 0x6C, 0xFC, 0x98, 0x0D, 0x90, 0x0B, 0xCC, 0xE9, - 0x47, 0xEC, 0xDC, 0xED, 0x87, 0x0B, 0x90, 0xFB, 0x6D, 0x80, 0x10, 0x1F, 0x0D, 0xA6, 0xC2, 0x21, - 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xFB, - 0xDD, 0x38, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x7C, 0xDD, 0xC4, 0x13, 0x1F, - 0x30, 0xA7, 0xFD, 0x00, 0x09, 0xBE, 0xFD, 0xEA, 0xE1, 0x99, 0xFE, 0xED, 0x07, 0xF1, 0xA1, 0xA6, - 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, - 0x0E, 0xFA, 0xDD, 0x3A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x74, 0x7D, 0x78, - 0xFB, 0x71, 0xCA, 0xCD, 0xDD, 0x7E, 0x7C, 0x67, 0x06, 0xF1, 0x21, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF9, 0xDD, 0x3C, - 0xF7, 0xCF, 0x3D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x79, 0x9A, 0xD8, 0x79, 0xD5, 0x68, 0xF5, 0xDB, - 0xAF, 0xDC, 0x0D, 0x88, 0x7B, 0xF6, 0xE3, 0x6B, 0xC4, 0x47, 0xFD, 0x54, 0x38, 0xE4, 0x31, 0x15, - 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, 0x01, 0xBF, 0x07, 0xC6, - 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xAE, 0x26, 0xB6, 0x5D, 0x76, 0xB2, 0x7A, 0x03, 0xF2, 0xF0, 0x0C, - 0xF3, 0xF6, 0x7D, 0xC1, 0xED, 0x87, 0x8D, 0x8F, 0x3F, 0x10, 0x1F, 0xC1, 0x54, 0x38, 0xE4, 0x31, - 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0xE1, 0xBE, 0x17, - 0xE6, 0x1D, 0x59, 0x33, 0x16, 0xFC, 0x71, 0x01, 0x00, 0x00, 0xD0, 0xBE, 0x09, 0xFF, 0x0D, 0x58, - 0x93, 0xB7, 0x1F, 0x6F, 0x7E, 0x6D, 0xF2, 0xE6, 0xE3, 0x0D, 0xE2, 0xC3, 0x4E, 0x85, 0x43, 0x1E, - 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xEC, 0x7B, - 0x66, 0x47, 0x6E, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x20, 0x1F, 0x13, 0x43, 0xD7, 0x2F, 0x99, 0x78, - 0xFA, 0x13, 0xE6, 0xCC, 0xA3, 0x95, 0xCF, 0xFF, 0x70, 0xB7, 0x1F, 0x95, 0xF8, 0xB8, 0xC0, 0xBF, - 0xF9, 0x78, 0x83, 0xF8, 0x28, 0x68, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, - 0xDF, 0xE9, 0x89, 0x03, 0x7D, 0xAF, 0xED, 0xA5, 0x7E, 0xF7, 0x20, 0xFA, 0x92, 0xE0, 0x8F, 0x0D, - 0x00, 0x00, 0x80, 0xEC, 0xCE, 0x0C, 0x2D, 0x5B, 0x3B, 0xF1, 0xE4, 0x87, 0x2B, 0x9F, 0x01, 0xF2, - 0x60, 0xE5, 0xB5, 0xBB, 0xD5, 0xDB, 0x8F, 0xAF, 0xD9, 0xF8, 0xF8, 0x47, 0xE2, 0x23, 0xFF, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF3, 0xBD, 0x38, - 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x03, 0x00, 0x00, 0x20, 0x3B, 0xF7, 0x06, - 0xAC, 0x89, 0xC7, 0x2F, 0xF2, 0x03, 0xE4, 0xED, 0x6F, 0x55, 0x9E, 0xFB, 0x20, 0x3E, 0xDC, 0x54, - 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, - 0x41, 0xBE, 0x57, 0xE7, 0xBE, 0x26, 0x78, 0x13, 0x16, 0x00, 0x00, 0xC8, 0xC3, 0xD9, 0x5D, 0xD7, - 0x0C, 0x4E, 0x3C, 0x36, 0xC3, 0x9C, 0x71, 0xCF, 0x7E, 0x04, 0x6F, 0xBD, 0xFA, 0xC3, 0x7A, 0xE2, - 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, - 0xF1, 0x3D, 0xBB, 0xF9, 0xFE, 0xBC, 0xE3, 0xB7, 0x0D, 0x05, 0x7F, 0x6C, 0x00, 0x00, 0x00, 0x64, - 0xF7, 0xEE, 0xB6, 0xC5, 0xA3, 0x13, 0x8F, 0xCF, 0x30, 0xEF, 0x7C, 0xBB, 0x72, 0xFB, 0xF1, 0xE6, - 0x5F, 0x5D, 0x44, 0x7C, 0x14, 0x32, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, - 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x57, 0x89, 0x0F, 0x3F, 0x40, 0x8E, 0xDC, 0xCC, 0x9B, 0xB0, - 0x00, 0x00, 0x40, 0xFB, 0xCE, 0x6D, 0x5F, 0x60, 0x26, 0x1E, 0xB9, 0xC0, 0xBC, 0xE5, 0x5E, 0xBB, - 0xFB, 0xD7, 0xC4, 0x47, 0x31, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, - 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0xE1, 0xEF, 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, - 0x00, 0xB4, 0xC7, 0x0C, 0x5D, 0x3B, 0xFB, 0xDC, 0xB6, 0x4B, 0xCD, 0x3B, 0xDF, 0xB4, 0x01, 0xF2, - 0x75, 0xE2, 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, - 0xA7, 0x0E, 0xF1, 0xBD, 0xBA, 0x58, 0x7C, 0xB8, 0xBD, 0xB4, 0xC2, 0x98, 0x97, 0xBF, 0x38, 0x3B, - 0xF8, 0xE3, 0x03, 0x00, 0x00, 0x20, 0xBD, 0xB3, 0xFB, 0x97, 0x0E, 0xBC, 0xFB, 0xD8, 0x87, 0xCC, - 0xDB, 0x77, 0x5F, 0x64, 0xCE, 0x13, 0x1F, 0x05, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, - 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x89, 0xF8, 0x70, 0x7B, 0xE1, 0x6A, 0x63, - 0x8E, 0xDD, 0x36, 0x10, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDE, 0x99, 0x5D, 0x9F, 0xBB, 0xEB, - 0xD4, 0x86, 0x0F, 0x98, 0xF3, 0xFF, 0x44, 0x7C, 0xE4, 0x3F, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, - 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x27, 0xC2, 0x23, 0x98, 0xF7, 0xAF, - 0x4B, 0xCC, 0xE9, 0x9F, 0xDD, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x76, 0xAF, 0x3D, 0x70, 0xED, - 0x86, 0xF1, 0xDD, 0xAB, 0xCD, 0xD9, 0x17, 0xBF, 0x44, 0x7C, 0xE4, 0x3A, 0x15, 0x09, 0x45, 0x4D, - 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0xA7, 0xC3, 0xC3, 0xED, - 0xD4, 0xB3, 0xF3, 0xCC, 0xEF, 0x77, 0xCC, 0x31, 0xBF, 0xDB, 0x77, 0xD3, 0x60, 0xF0, 0xC7, 0x07, - 0x00, 0x00, 0x40, 0x7A, 0xAF, 0xEF, 0xB9, 0x75, 0xF8, 0xF7, 0x07, 0x6F, 0x35, 0xBF, 0xDF, 0xB7, - 0xD2, 0xBC, 0x79, 0xE0, 0x32, 0x73, 0xFE, 0x9F, 0x55, 0x54, 0x24, 0x9D, 0x08, 0x87, 0x3C, 0x26, - 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, - 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0x4E, 0x87, 0xC7, 0x99, 0xBF, 0xEB, 0x33, 0xE3, 0xBB, - 0xE6, 0x9A, 0xDF, 0x6D, 0xB3, 0xF1, 0xE1, 0xB6, 0x67, 0x39, 0xAF, 0xE2, 0x05, 0x00, 0x00, 0xD9, - 0xFD, 0xF3, 0xFF, 0xFE, 0x17, 0x17, 0xFE, 0x76, 0xFB, 0xEA, 0xFB, 0x7E, 0xB7, 0x6D, 0xF1, 0x5B, - 0xBF, 0xDF, 0xB9, 0xD8, 0xB8, 0xBD, 0x7D, 0xE8, 0x72, 0xFF, 0x5B, 0x2D, 0x74, 0x64, 0x34, 0x9A, - 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, - 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0xAE, 0x3E, 0x3C, 0xCE, 0xFE, - 0x43, 0x9F, 0x79, 0x73, 0xEF, 0x64, 0x78, 0xBC, 0xBE, 0x75, 0xCE, 0xF8, 0xEF, 0xB6, 0x5D, 0xBA, - 0x7E, 0xB4, 0xFF, 0x3D, 0x7F, 0x14, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDD, 0x7F, 0xBF, 0xFB, - 0x33, 0x17, 0xBF, 0xB6, 0x79, 0xF1, 0x96, 0x30, 0x42, 0xC6, 0x77, 0x2F, 0x36, 0xA7, 0xFF, 0xC6, - 0x1E, 0xD4, 0x65, 0x6C, 0xC4, 0x27, 0xC2, 0x21, 0x8F, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, 0xDF, - 0xAB, 0xAB, 0x0D, 0x8F, 0xF3, 0xFF, 0x34, 0xDF, 0xBC, 0xB5, 0x3F, 0x72, 0xE3, 0x61, 0xF7, 0xEA, - 0x33, 0x73, 0x7E, 0x34, 0x3E, 0xF4, 0xA9, 0x59, 0xC1, 0x1F, 0x17, 0x00, 0x00, 0x00, 0xF9, 0xF9, - 0xEF, 0xDF, 0x5D, 0xF2, 0x99, 0xD7, 0xB6, 0x2C, 0xFA, 0x59, 0x18, 0x22, 0x6F, 0xEC, 0xB9, 0xCC, - 0x4C, 0xFC, 0xBD, 0x0B, 0x02, 0x15, 0x1E, 0x6E, 0xB1, 0x68, 0xC8, 0x6B, 0x32, 0x1C, 0xF2, 0x98, - 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, - 0x3A, 0xC4, 0xF7, 0xEA, 0x26, 0xC3, 0xC3, 0xFB, 0xE7, 0xF9, 0xE6, 0x9D, 0x91, 0x79, 0x35, 0xE1, - 0xF1, 0xDA, 0xE6, 0x4B, 0xF7, 0x8F, 0x6F, 0xE9, 0xE3, 0xB5, 0xBB, 0x00, 0x00, 0xA0, 0x78, 0xFF, - 0xEB, 0xA1, 0xCB, 0xBE, 0xF8, 0xBB, 0x6D, 0x8B, 0x7E, 0x19, 0x86, 0x88, 0x7B, 0x3E, 0xE4, 0xEC, - 0x4F, 0x5D, 0x1C, 0x10, 0x1F, 0xF5, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, - 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0x51, 0x7D, 0xC0, 0x3C, 0x08, 0x8F, 0xD7, - 0xB7, 0x5E, 0x3A, 0xF6, 0xDA, 0x96, 0x4B, 0x79, 0xDD, 0x2E, 0x00, 0x00, 0x98, 0x5A, 0xA3, 0xFD, - 0xFD, 0x7F, 0xF4, 0xAB, 0x27, 0x2E, 0xFB, 0x3F, 0xA2, 0xCF, 0x87, 0xBC, 0x35, 0xEC, 0x1E, 0x54, - 0x17, 0xD1, 0x90, 0xD7, 0x64, 0x38, 0xE4, 0x31, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x55, 0xC2, 0x23, 0xFE, - 0x80, 0xB9, 0x8D, 0x8E, 0x5F, 0xBE, 0xBE, 0x7D, 0xEE, 0xBA, 0xE0, 0x8F, 0x00, 0x00, 0x00, 0x80, - 0xCE, 0xF8, 0xD5, 0x23, 0x57, 0x7E, 0xE0, 0x37, 0x4F, 0x2E, 0xDE, 0x30, 0x19, 0x22, 0x8B, 0xCC, - 0xE9, 0xBF, 0xB9, 0xCC, 0x78, 0xFF, 0x2A, 0x02, 0xA2, 0x9D, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, - 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, - 0xDF, 0xAB, 0x6B, 0xFC, 0x80, 0x39, 0xCF, 0x79, 0x00, 0x00, 0x80, 0xAE, 0x72, 0xF2, 0x91, 0xC5, - 0xF3, 0x5F, 0x7D, 0x66, 0xF1, 0x0E, 0x17, 0x20, 0x6E, 0xE3, 0xBB, 0x17, 0x99, 0x33, 0x7F, 0x67, - 0x0F, 0xE2, 0x2A, 0x26, 0xD2, 0x4E, 0x86, 0x43, 0x1E, 0x8B, 0x47, 0x43, 0x5E, 0x53, 0x91, 0x50, - 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x73, 0xEA, 0x01, - 0xF3, 0xDF, 0x6D, 0xBD, 0x74, 0xF0, 0xBF, 0x7D, 0x67, 0xDE, 0x07, 0x82, 0x2F, 0x73, 0x00, 0x00, - 0x80, 0xEE, 0xF3, 0xAB, 0x8D, 0x8B, 0xD6, 0xBC, 0xFA, 0xCC, 0xC2, 0x9F, 0x87, 0x21, 0xF2, 0xC6, - 0x9E, 0xC5, 0xE6, 0xDD, 0x7F, 0xB0, 0x87, 0x7D, 0x15, 0x16, 0x49, 0x26, 0xC3, 0x21, 0x8F, 0xA9, - 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, - 0x83, 0x7C, 0xAF, 0xCD, 0xFB, 0xE7, 0x05, 0x75, 0x0F, 0x98, 0xDB, 0x8D, 0xFE, 0x7F, 0x8F, 0x5E, - 0x3A, 0x27, 0xF8, 0xB2, 0x06, 0x00, 0x00, 0xE8, 0x6E, 0xFE, 0xF3, 0x21, 0x83, 0x8B, 0xFF, 0xE2, - 0x77, 0xDB, 0x16, 0xFE, 0x32, 0x0C, 0x91, 0x37, 0x0F, 0x2C, 0x36, 0x67, 0x7F, 0x6A, 0x0F, 0xFE, - 0x2A, 0x32, 0x1A, 0x4D, 0x86, 0x43, 0x1E, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, - 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x87, 0xF9, 0x5E, 0xDB, 0xE9, 0xBF, 0xE9, 0xAB, - 0x79, 0xC0, 0xFC, 0xB5, 0x67, 0xE6, 0x1C, 0xE3, 0x01, 0x73, 0x00, 0x00, 0xD0, 0xB3, 0x6C, 0x88, - 0xFC, 0xBB, 0x57, 0x37, 0x2F, 0xBA, 0xE7, 0x77, 0xDB, 0x16, 0xBD, 0x15, 0x86, 0xC8, 0xDB, 0x87, - 0x12, 0x3E, 0xA8, 0x2E, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, - 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xC3, 0x7C, 0x2F, 0x6D, 0xE2, 0xEF, 0xE7, 0xF3, - 0x80, 0x39, 0x00, 0x00, 0x28, 0xAF, 0x93, 0xF7, 0x2E, 0xFC, 0xC8, 0x2B, 0x9B, 0x16, 0x3F, 0x1A, - 0x46, 0x88, 0x7B, 0x3E, 0xA4, 0xE9, 0x83, 0xEA, 0x32, 0x1C, 0xF2, 0x98, 0x0A, 0x87, 0x3C, 0xA6, - 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x3E, 0xD0, 0xF7, 0xCA, - 0xCE, 0xFE, 0xC3, 0x7C, 0xF3, 0xE6, 0x5E, 0xF7, 0xED, 0x56, 0x95, 0xF8, 0xE0, 0x01, 0x73, 0x00, - 0x00, 0x50, 0x6A, 0xFF, 0xE3, 0xFE, 0xCF, 0x2C, 0x7A, 0x75, 0xF3, 0xA2, 0xE7, 0xA2, 0x21, 0x32, - 0xF1, 0xF7, 0x36, 0x0C, 0x88, 0x8F, 0x84, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, - 0x7D, 0xA8, 0xEF, 0x85, 0x9D, 0xFF, 0xA7, 0x05, 0xE6, 0xED, 0x83, 0x7D, 0x41, 0x78, 0x04, 0x37, - 0x1F, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0xA6, 0x8B, 0x5F, 0x3E, 0xB6, 0xF8, 0x96, 0xD7, 0xB7, 0x2E, - 0x7C, 0x39, 0x0C, 0x11, 0xF7, 0xA0, 0xBA, 0xFF, 0x7C, 0x88, 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, - 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xF6, - 0xDD, 0x3E, 0xF7, 0x80, 0xF9, 0xA9, 0x67, 0xA3, 0xE1, 0xE1, 0xC7, 0x07, 0x0F, 0x98, 0x03, 0x00, - 0x80, 0xE9, 0xC7, 0x3D, 0xA8, 0xFE, 0xDB, 0xA7, 0x17, 0x7F, 0xF5, 0xF5, 0xAD, 0x8B, 0x7E, 0xE3, - 0x22, 0xE4, 0x77, 0x3B, 0x16, 0x9A, 0x37, 0xF7, 0x2F, 0x32, 0xE7, 0xFE, 0xD1, 0x1D, 0xEC, 0x55, - 0x44, 0x64, 0x5D, 0x3C, 0x1A, 0xF2, 0x9A, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, - 0xFC, 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xED, 0xAB, 0x3C, 0x60, 0x3E, 0x19, 0x1E, 0xAF, 0x3D, 0x33, - 0x97, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x7E, 0xF5, 0xC8, 0xBC, 0x0F, 0xFC, 0xE6, 0xE9, 0x85, 0xF7, - 0xBD, 0xBE, 0x75, 0xC1, 0x5B, 0x2E, 0x42, 0xDC, 0xDE, 0x1E, 0x59, 0x6C, 0xBC, 0x7F, 0x51, 0x31, - 0x91, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, - 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xCD, 0xAB, 0x3C, 0x60, 0x1E, 0x3E, 0xE7, 0x61, 0xC3, 0x63, 0xCB, - 0x5C, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x88, 0x1B, 0xFB, 0x4F, 0x9F, 0xB9, 0xF8, 0x95, 0xCD, 0x0B, - 0xB7, 0x84, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCD, 0xA9, 0xE7, 0xDA, 0x09, 0x11, 0x15, 0x0E, 0x79, - 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC0, 0xEF, - 0xD6, 0xD5, 0x3E, 0x60, 0x3E, 0xD7, 0xBC, 0xBE, 0x75, 0xEE, 0xB8, 0xFD, 0x91, 0x07, 0xCC, 0x01, - 0x00, 0x00, 0x9A, 0xF9, 0x9F, 0x0F, 0x2D, 0x5A, 0xFA, 0xEA, 0xE6, 0x85, 0x3F, 0x0B, 0x43, 0x64, - 0x7C, 0x68, 0x91, 0x39, 0x33, 0xEA, 0x0E, 0xFE, 0x2A, 0x32, 0x1A, 0x2D, 0x1E, 0x0D, 0x79, 0x4D, - 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC8, 0xEF, 0xC6, - 0xD5, 0x3F, 0x60, 0x6E, 0xB7, 0x75, 0x0E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA4, 0xF1, 0xBF, 0x1E, - 0x5A, 0xF0, 0xC5, 0xD7, 0xB6, 0x2E, 0xF8, 0x65, 0x18, 0x22, 0x6F, 0xEC, 0x5D, 0x64, 0xCE, 0xFE, - 0xC4, 0x45, 0x80, 0x0A, 0x8E, 0xE8, 0xE2, 0xD1, 0x90, 0xD7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, - 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x07, 0xFD, 0x6E, 0x9B, 0x7E, 0xC0, 0x7C, 0x2E, 0x0F, - 0x98, 0x03, 0x00, 0x00, 0x64, 0xE5, 0x1E, 0x54, 0xFF, 0xF5, 0xC6, 0x45, 0x7F, 0x19, 0x7D, 0x3E, - 0xC4, 0x3D, 0xA8, 0x7E, 0xFE, 0x67, 0x2A, 0x3C, 0xDC, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, - 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0x61, 0xBF, 0xDB, 0xC6, 0x03, 0xE6, - 0x00, 0x00, 0x00, 0x05, 0x72, 0x0F, 0xAA, 0xFF, 0xFA, 0xC9, 0x85, 0x1B, 0xC2, 0x08, 0x71, 0x7B, - 0xE7, 0x70, 0xFC, 0xF9, 0x10, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, - 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xD8, 0xEF, 0xA6, 0xF1, 0x80, 0x39, 0x00, 0x00, 0xC0, 0x14, - 0x3A, 0xF9, 0xC8, 0xE2, 0xF9, 0xBF, 0xDD, 0xB4, 0x60, 0x47, 0x18, 0x21, 0xE1, 0x83, 0xEA, 0x3A, - 0x1C, 0xF2, 0x58, 0x3C, 0x10, 0x8A, 0x9C, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, - 0x03, 0x7F, 0xB7, 0x8C, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x3A, 0xE8, 0x57, 0x1B, 0x17, 0xAD, 0x79, - 0x65, 0xD3, 0x82, 0x9F, 0x57, 0x42, 0x64, 0x81, 0x19, 0x1F, 0x5A, 0x68, 0xCE, 0x8C, 0xBA, 0x43, - 0xBC, 0x8A, 0x88, 0xAC, 0x8B, 0x07, 0x42, 0x91, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, - 0x3D, 0x7D, 0xE8, 0xEF, 0x86, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x40, 0x97, 0xA8, 0x7C, 0x90, 0xE1, - 0xC2, 0xAF, 0xBE, 0xB6, 0x75, 0xFE, 0x2F, 0x5D, 0x84, 0xB8, 0xBD, 0xB9, 0x7F, 0xA1, 0x39, 0xFB, - 0x13, 0x77, 0xA0, 0x57, 0x41, 0x91, 0x66, 0xF1, 0x40, 0x28, 0x72, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, - 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFE, 0x9D, 0x5E, 0xA3, 0x07, 0xCC, 0x4F, 0x7E, 0xE7, 0x53, 0xF3, - 0x83, 0x2F, 0x01, 0x00, 0x00, 0x00, 0x74, 0xC2, 0x60, 0xFF, 0xA7, 0xFE, 0xDD, 0xAB, 0x9B, 0x16, - 0xDC, 0xF3, 0xFA, 0xD6, 0xF9, 0x6F, 0x85, 0x21, 0xF2, 0xF6, 0x88, 0x7B, 0x50, 0x5D, 0x85, 0x45, - 0x92, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFF, - 0x9D, 0x9E, 0x7A, 0xC0, 0xFC, 0xB7, 0x1B, 0xE7, 0xDE, 0x10, 0xFC, 0x23, 0x0F, 0x00, 0x00, 0x80, - 0x6E, 0xF0, 0xFF, 0x7E, 0x63, 0xF1, 0x87, 0x7F, 0xF3, 0xD4, 0x82, 0x47, 0xC3, 0x08, 0x71, 0x3B, - 0xF5, 0xDC, 0x22, 0xE3, 0xFD, 0x8B, 0x8A, 0x8C, 0x46, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, - 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xFE, 0x3B, 0xB9, 0xF8, 0x03, 0xE6, 0xEE, 0x39, 0x8F, - 0x57, 0x9F, 0xBE, 0xF4, 0x3F, 0x06, 0xFF, 0x88, 0x03, 0x00, 0x00, 0xA0, 0x1B, 0xFD, 0x8F, 0xFB, - 0x17, 0x2C, 0x7A, 0x75, 0xF3, 0x82, 0x9F, 0x85, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCC, 0xE9, 0xBF, - 0x75, 0x07, 0x61, 0x15, 0x1C, 0xD1, 0xA9, 0x48, 0x28, 0x6A, 0xB1, 0x03, 0x7A, 0x99, 0x27, 0x0F, - 0xFF, 0x9D, 0x9E, 0x0E, 0x80, 0x4E, 0xAD, 0xEE, 0x01, 0xF3, 0xCD, 0x73, 0xDE, 0xB2, 0x3F, 0xF2, - 0x80, 0x39, 0x00, 0x00, 0x40, 0x2F, 0xF9, 0xE5, 0xC3, 0xF3, 0x6F, 0x79, 0x75, 0xCB, 0x82, 0x97, - 0xC3, 0x10, 0x71, 0x0F, 0xAA, 0x4F, 0xFC, 0x57, 0x77, 0xF8, 0x27, 0x3E, 0xA6, 0x6C, 0xF2, 0xF0, - 0xDF, 0xE9, 0xE9, 0x08, 0xE8, 0xC4, 0x1A, 0x3D, 0x60, 0x3E, 0xBE, 0xA5, 0x6F, 0x76, 0xF0, 0x8F, - 0x31, 0x00, 0x00, 0x00, 0x7A, 0x49, 0xF8, 0xA0, 0x7A, 0xF4, 0xF9, 0x10, 0xF7, 0xA0, 0xFA, 0xB9, - 0x7F, 0x74, 0x21, 0x40, 0x7C, 0x14, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x74, 0x08, 0x4C, 0xF5, 0x1A, - 0x3D, 0x60, 0xFE, 0xEB, 0xC7, 0x3E, 0x7D, 0x55, 0xF0, 0x8F, 0x2E, 0x00, 0x00, 0x00, 0x7A, 0x99, - 0xFB, 0x20, 0xC3, 0xDF, 0x6C, 0x9C, 0x7F, 0x5F, 0xED, 0x83, 0xEA, 0x0B, 0xCD, 0xF9, 0x9F, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x63, 0x60, 0xAA, 0x17, - 0x7F, 0xC0, 0xFC, 0xF5, 0x6D, 0x73, 0x4E, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x40, 0x49, 0xFD, 0xDB, - 0x83, 0x7D, 0x7D, 0xAF, 0x6C, 0x5E, 0xB0, 0xA5, 0x12, 0x21, 0xF3, 0xCD, 0xEF, 0x77, 0xCD, 0x37, - 0xA7, 0x9E, 0x5B, 0x68, 0xBC, 0x7F, 0x51, 0xC1, 0x90, 0xE7, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, - 0xFF, 0x4E, 0x4F, 0xC7, 0xC0, 0x54, 0x8E, 0x07, 0xCC, 0x01, 0x00, 0x00, 0xA6, 0xB1, 0xFF, 0xF9, - 0xD0, 0xBC, 0xA5, 0xAF, 0x6E, 0xEE, 0xFB, 0x99, 0x8B, 0x90, 0x30, 0x44, 0xCE, 0x8C, 0xBA, 0x03, - 0xB4, 0x8A, 0x87, 0x76, 0x17, 0x3B, 0xA0, 0x97, 0x79, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x20, 0x98, - 0xAA, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xAA, 0x7E, 0xF5, 0x58, 0xDF, 0x5F, 0x54, 0x3E, 0xC8, - 0xB0, 0x12, 0x22, 0xE3, 0x43, 0xF6, 0xC0, 0xF8, 0x13, 0x77, 0x98, 0x56, 0x21, 0x91, 0x65, 0xB1, - 0x03, 0x7A, 0x99, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x82, 0xA9, 0x18, 0x0F, 0x98, 0x03, 0x00, - 0x00, 0x40, 0x72, 0x0F, 0xAA, 0xFF, 0x7A, 0x63, 0xDF, 0x5F, 0xBE, 0xBE, 0xB5, 0xEF, 0xAD, 0x30, - 0x44, 0xDE, 0xDC, 0x6F, 0x0F, 0x90, 0x6D, 0x3F, 0x1F, 0x22, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, - 0x77, 0x7A, 0x3A, 0x0C, 0x8A, 0x1E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x20, 0x11, 0xFF, 0x41, 0xF5, - 0xA7, 0xFA, 0x1E, 0x0D, 0x23, 0xC4, 0xCD, 0x3D, 0xA8, 0x9E, 0xED, 0xF9, 0x10, 0x71, 0x48, 0x2F, - 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x71, 0x50, 0xF4, 0xCE, 0xFC, 0xDD, 0x7C, 0x1E, 0x30, 0x07, - 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x41, 0xF5, 0x57, 0x9F, 0x99, 0x3F, 0x12, 0x46, 0x48, 0xFA, 0x07, - 0xD5, 0xC5, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x41, 0x91, 0x73, 0xCF, 0x79, - 0xF0, 0x80, 0x39, 0x00, 0x00, 0x00, 0xDA, 0xF2, 0xAB, 0x27, 0xFA, 0xD6, 0x44, 0x1F, 0x54, 0x77, - 0xCF, 0x87, 0xB4, 0x7E, 0x50, 0x3D, 0x76, 0x40, 0x2F, 0xF3, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x81, - 0x50, 0xD4, 0xCE, 0xFD, 0x94, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x90, 0xA3, 0xCA, 0x07, 0x19, 0xF6, - 0x7D, 0x35, 0xFA, 0xA0, 0xBA, 0x7B, 0x3E, 0x44, 0x3F, 0xA8, 0x1E, 0x3B, 0xA0, 0x97, 0x79, 0xF2, - 0xF0, 0xDF, 0xE9, 0xE9, 0x48, 0x28, 0x62, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x42, 0xB9, 0xE7, - 0x43, 0x5E, 0xDD, 0xD4, 0x77, 0x4F, 0xF4, 0x41, 0xF5, 0xB7, 0x0E, 0x46, 0x1F, 0x54, 0x17, 0x87, - 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0A, 0x79, 0x2F, 0x7C, 0xC0, 0x3C, 0xFA, 0x9C, - 0x87, 0x1D, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA0, 0x18, 0x47, 0xBF, 0xB1, 0xF8, 0xC3, 0xAF, 0x6C, - 0xEE, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0x3B, 0x87, 0xEC, 0xC1, 0xF4, 0x5F, 0xC4, 0x41, 0xBD, 0x8C, - 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x42, 0xDE, 0x53, 0x0F, 0x98, 0xFF, 0xFA, 0xE1, 0x4B, 0x6F, - 0x0E, 0xFE, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xE3, 0x3F, 0xA8, 0xEE, 0x9E, 0x0F, 0xD9, 0xDE, - 0x67, 0xDC, 0x7E, 0xBF, 0xB3, 0xCF, 0x9C, 0x7A, 0xCE, 0x1E, 0x54, 0xD5, 0xA1, 0xBD, 0x2C, 0x93, - 0x87, 0xFF, 0x4E, 0xAF, 0x3E, 0x14, 0xF2, 0x9E, 0x7A, 0xC0, 0xFC, 0xD7, 0x83, 0x73, 0xFE, 0xB7, - 0xE0, 0x1F, 0x05, 0x00, 0x00, 0x00, 0x60, 0xEA, 0xFC, 0xF2, 0xE1, 0xB9, 0xB7, 0xBC, 0xB6, 0xB5, - 0xEF, 0x97, 0x61, 0x88, 0x8C, 0xEF, 0x9E, 0x6F, 0x26, 0xFE, 0xAB, 0x3D, 0x18, 0xAB, 0x03, 0x7C, - 0x2F, 0x4F, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0C, 0x79, 0x4D, 0x3D, 0x60, 0xFE, 0xDA, 0xA6, 0x39, - 0x77, 0xF3, 0x80, 0x39, 0x00, 0x00, 0x00, 0x3A, 0xCA, 0x7F, 0x50, 0xFD, 0xC9, 0xBE, 0xAF, 0xBE, - 0xBE, 0x65, 0xDE, 0x5B, 0x61, 0x88, 0xBC, 0xB9, 0x6F, 0xBE, 0x39, 0xFB, 0x13, 0x7B, 0x48, 0x56, - 0x87, 0xF9, 0x5E, 0x9B, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x1A, 0xF2, 0x98, 0x7A, 0xC0, 0xFC, 0xD5, - 0xCD, 0x73, 0x37, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xBA, 0x8A, 0x7B, 0x50, 0xFD, 0xB7, 0x9B, - 0xFA, 0xEE, 0x09, 0x23, 0xC4, 0xED, 0xED, 0x61, 0xF7, 0xA0, 0xBA, 0x38, 0xD4, 0xF7, 0xCA, 0xE4, - 0xE1, 0xBF, 0xD3, 0xD3, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0x3D, 0xC9, 0x3D, - 0x1F, 0xF2, 0xCA, 0xA6, 0xBE, 0x2D, 0xD1, 0x10, 0x71, 0xCF, 0x87, 0xF4, 0xDC, 0x83, 0xEA, 0xF2, - 0xF0, 0xDF, 0xE9, 0xE9, 0x78, 0x68, 0x77, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x9E, 0x57, 0xF9, - 0x20, 0xC3, 0x79, 0x35, 0x0F, 0xAA, 0x9F, 0xFE, 0x5B, 0x7B, 0xE0, 0x55, 0x87, 0xFD, 0x6E, 0x9B, - 0x3C, 0xFC, 0x77, 0x7A, 0xF5, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xA5, 0xF3, - 0xAB, 0xC7, 0xFA, 0xFE, 0x22, 0xFE, 0xA0, 0x7A, 0x57, 0x3F, 0x1F, 0x22, 0x0F, 0xFF, 0x9D, 0x9E, - 0x0E, 0x88, 0xAC, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0x94, 0x9A, 0x7B, 0x50, 0xFD, 0xB5, 0x2D, - 0xF3, 0xBE, 0x1E, 0x7F, 0x50, 0xFD, 0xDC, 0x3F, 0xDA, 0xC3, 0xB5, 0x8A, 0x80, 0x4E, 0x4D, 0x1E, - 0xFE, 0x3B, 0x3D, 0x1D, 0x11, 0x59, 0xC6, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x98, 0x56, 0xDC, 0x83, - 0xEA, 0xBF, 0x79, 0xAA, 0xEF, 0xC7, 0x61, 0x84, 0xB8, 0x75, 0xCD, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, - 0xE9, 0xE9, 0x90, 0x48, 0xBB, 0x46, 0x0F, 0x98, 0xBF, 0xB6, 0xE5, 0xD2, 0x81, 0xE0, 0x7F, 0x1A, - 0x00, 0x00, 0x00, 0xA0, 0xBC, 0xFC, 0x0F, 0x32, 0xDC, 0xD4, 0x37, 0x12, 0x46, 0x48, 0xF8, 0x41, - 0x86, 0x1D, 0x7B, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x13, 0x69, 0xA7, 0x1E, 0x30, 0x7F, - 0xE5, 0xC9, 0x39, 0xB7, 0x07, 0xFF, 0x53, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x87, 0x7B, 0x50, 0xFD, - 0xB5, 0x2D, 0xF3, 0x8E, 0x85, 0x21, 0xE2, 0x9E, 0x0F, 0x39, 0x33, 0x6A, 0x0F, 0xDF, 0x2A, 0x12, - 0x8A, 0x9A, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x26, 0xD2, 0x4C, 0x3D, 0x60, 0xFE, 0xCA, 0xA6, 0xB9, - 0xFF, 0x57, 0xF0, 0xB7, 0x1E, 0x00, 0x00, 0x00, 0x98, 0x9E, 0xC2, 0x0F, 0x32, 0x8C, 0x3E, 0xA8, - 0xFE, 0xC6, 0x9E, 0x29, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x14, 0x49, 0x17, 0x7F, - 0xC0, 0xDC, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x98, 0xF0, 0x83, 0x0C, 0xE3, 0x0F, 0xAA, - 0x17, 0xF6, 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2A, 0x92, 0x8C, 0x07, 0xCC, 0x01, 0x00, - 0x00, 0x80, 0x0C, 0x5E, 0x79, 0x72, 0xCE, 0xA5, 0xF1, 0x0F, 0x32, 0x74, 0x0F, 0xAA, 0xE7, 0xFA, - 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2C, 0x5A, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, - 0x1C, 0xFC, 0x7A, 0x63, 0xDF, 0x55, 0xAF, 0x6E, 0x9E, 0xF7, 0x4F, 0x61, 0x84, 0x84, 0x0F, 0xAA, - 0xCB, 0xA0, 0x48, 0x33, 0x79, 0xF8, 0xEF, 0xF4, 0xEA, 0xC3, 0x22, 0xC9, 0x78, 0xC0, 0x1C, 0x00, - 0x00, 0x00, 0xC8, 0xD9, 0x2F, 0x1F, 0x9E, 0x7B, 0x4B, 0xFC, 0x83, 0x0C, 0x33, 0x3F, 0xA8, 0x2E, - 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x8B, 0x66, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, 0x40, 0xFE, - 0x07, 0x19, 0x6E, 0xEE, 0xFB, 0x3F, 0xE3, 0xCF, 0x87, 0xA4, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, - 0x3D, 0x1D, 0x18, 0x8D, 0xA6, 0x1E, 0x30, 0xFF, 0xED, 0xC6, 0x4B, 0xBF, 0xC5, 0x03, 0xE6, 0x00, - 0x00, 0x00, 0x40, 0x01, 0xC2, 0x07, 0xD5, 0xC3, 0x08, 0x71, 0x7B, 0xEB, 0x40, 0x82, 0x07, 0xD5, - 0xE5, 0xE1, 0xBF, 0xD3, 0xD3, 0x91, 0xA1, 0xE6, 0x9E, 0xF3, 0x88, 0x3F, 0x60, 0xFE, 0xCA, 0x53, - 0x73, 0xB6, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x00, 0x30, 0x05, 0xDC, 0x07, 0x19, 0xBE, 0xBE, 0x75, - 0xDE, 0xFE, 0x68, 0x88, 0xBC, 0x73, 0xA8, 0xC1, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xD0, - 0x88, 0x4F, 0x3D, 0x60, 0xFE, 0xDA, 0xE6, 0x39, 0x3F, 0xE1, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, - 0x03, 0xDC, 0x07, 0x19, 0xC6, 0x1F, 0x54, 0x3F, 0xFD, 0xB7, 0xF6, 0xF0, 0x5E, 0x82, 0xF8, 0x70, - 0x0F, 0x98, 0xD7, 0x3C, 0xE7, 0xC1, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x40, 0x77, 0x88, 0x7F, 0x90, - 0xE1, 0xF8, 0xEE, 0x3E, 0x33, 0xF1, 0xF7, 0xEE, 0x20, 0xAF, 0x02, 0xA0, 0x93, 0xAB, 0x0F, 0x8D, - 0xF8, 0xDC, 0x03, 0xE6, 0x6F, 0x0C, 0xD5, 0x3F, 0x60, 0x3E, 0xDA, 0xFF, 0x9E, 0x3F, 0x0A, 0x7E, - 0xBB, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xCD, 0x7F, 0x50, 0x7D, 0xCB, 0xBC, 0xAF, 0x57, 0x1E, 0x54, - 0xB7, 0x07, 0x78, 0xBB, 0x37, 0xF7, 0xF5, 0xD9, 0x03, 0xBD, 0x3B, 0xD8, 0xAB, 0x18, 0x98, 0xEA, - 0xD5, 0xC7, 0x46, 0x74, 0xEE, 0x83, 0x04, 0x79, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xE8, 0x31, 0xEE, - 0x41, 0xF5, 0x57, 0x36, 0xCD, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0xDB, 0xC3, 0xF3, 0xED, 0x01, 0x5F, - 0x45, 0xC1, 0x54, 0x4D, 0x47, 0x87, 0x1B, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x00, 0x25, 0xF0, 0x6F, - 0x1B, 0xFA, 0xFA, 0x5E, 0xDB, 0x32, 0xF7, 0x27, 0x61, 0x84, 0xFC, 0x7E, 0xE7, 0x3C, 0x73, 0xEA, - 0xD9, 0xF9, 0xF6, 0xC0, 0xAF, 0x02, 0xA1, 0xC8, 0x35, 0x0E, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, - 0x00, 0x4A, 0xE6, 0x57, 0x4F, 0x5C, 0xBA, 0xC6, 0x86, 0xC8, 0xB1, 0x68, 0x88, 0x9C, 0xF9, 0x3B, - 0x17, 0x01, 0x2A, 0x16, 0xF2, 0x5E, 0x7D, 0x78, 0xB8, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0x50, - 0x62, 0xEE, 0x01, 0xEE, 0xDF, 0x3E, 0x39, 0xF7, 0xAB, 0xAF, 0x6F, 0x9B, 0x37, 0x1E, 0x86, 0x88, - 0x7B, 0x50, 0xBD, 0xD8, 0xE7, 0x43, 0xEA, 0xC3, 0x83, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x69, - 0xA4, 0xF2, 0x41, 0x86, 0x73, 0xEF, 0x79, 0x7D, 0xCB, 0xDC, 0x9A, 0x07, 0xD5, 0xCF, 0xFD, 0x34, - 0xEF, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, 0xA6, 0xB1, 0x57, 0x9E, 0x9C, - 0x73, 0xA9, 0x7A, 0x50, 0x3D, 0x9F, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, - 0xE0, 0x7B, 0x6D, 0x47, 0xDF, 0x40, 0xE5, 0x83, 0x0C, 0x27, 0x43, 0xE4, 0x8D, 0x3D, 0x7D, 0xFE, - 0x33, 0x22, 0xD9, 0xDE, 0x9A, 0x55, 0x79, 0xB8, 0xDC, 0x3D, 0xE3, 0x11, 0xBF, 0xF1, 0xE0, 0x01, - 0x73, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x57, 0x9E, 0x99, 0x73, 0xDB, 0xEB, 0xDB, 0xE7, 0x9E, 0x8C, - 0x86, 0x48, 0x18, 0x23, 0xEF, 0x1C, 0x9A, 0x6F, 0x4E, 0xFF, 0xCD, 0x7C, 0xFF, 0x79, 0x91, 0xF8, - 0x0D, 0x89, 0xFB, 0xFF, 0xDD, 0xBF, 0xEE, 0xFE, 0xFD, 0x77, 0x0E, 0xF5, 0xD5, 0x3C, 0xDF, 0x11, - 0xCE, 0x3D, 0x60, 0x6E, 0x7F, 0xEE, 0x75, 0xC1, 0x5F, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xDC, - 0x1B, 0xB3, 0x5E, 0x79, 0x66, 0xEE, 0x70, 0x3C, 0x44, 0x5A, 0x2E, 0x16, 0x1D, 0x95, 0xCD, 0x19, - 0xFA, 0xF5, 0xA3, 0x97, 0xDE, 0x1C, 0xFC, 0xD4, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xB9, 0x87, 0xD5, - 0x7F, 0xB3, 0x71, 0xDE, 0x9D, 0xAF, 0x3E, 0x3D, 0xEF, 0xA1, 0x57, 0x37, 0xCF, 0x7D, 0x59, 0x46, - 0x47, 0xB8, 0x20, 0x38, 0x5E, 0xDB, 0x3C, 0xF7, 0xD8, 0xAB, 0xCF, 0xCC, 0x7D, 0xDA, 0xDD, 0x76, - 0xFC, 0xB7, 0xEF, 0xCC, 0xFB, 0x40, 0xF0, 0x53, 0x01, 0x00, 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x35, - 0xB9, 0xFE, 0x07, 0x1B, 0xEE, 0xE8, 0x1B, 0x88, 0xEF, 0xDF, 0x36, 0xCC, 0xEE, 0x0B, 0xFE, 0x63, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xD0, 0x15, 0xDE, 0xF3, 0x9E, 0xFF, 0x1F, 0x5B, 0xE2, 0x94, 0x1D, 0x86, - 0x86, 0x23, 0x09, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82}; - -static const uint8_t tree_img_gif[] PROGMEM = { - - 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x28, 0x00, 0x3C, 0x00, 0x83, 0x0B, 0x00, 0x00, 0xFF, 0xFF, - 0x00, 0x21, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x94, 0x00, 0x00, 0xB5, 0x00, 0x00, - 0xDE, 0x00, 0x00, 0xFF, 0x00, 0x6B, 0x00, 0x00, 0xFF, 0x33, 0x33, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, - 0xFF, 0xFF, 0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0x00, 0xCC, 0x00, 0x00, 0x21, 0xFF, 0x0B, - 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0xA0, 0x0F, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, - 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, - 0x8C, 0xCA, 0xE8, 0x85, 0xE8, 0xA5, 0xAC, 0x67, 0xEA, 0x8A, 0xE5, 0x2B, 0x2F, 0xE3, 0x31, 0xCE, - 0xAF, 0x41, 0x1C, 0xB8, 0x1B, 0x24, 0x80, 0x04, 0xAF, 0x87, 0x02, 0x26, 0x88, 0xA1, 0x07, 0x60, - 0xB9, 0x44, 0x82, 0x04, 0x02, 0x80, 0x61, 0x30, 0x70, 0x6E, 0x0C, 0x86, 0x03, 0x60, 0x20, 0xB0, - 0x6A, 0xA8, 0xD3, 0x03, 0x21, 0xEC, 0xAD, 0x18, 0x12, 0xE8, 0xF4, 0xB1, 0x4C, 0x51, 0xA0, 0x07, - 0xEA, 0x07, 0x5B, 0xF2, 0x70, 0x13, 0x76, 0xD4, 0xA8, 0xBC, 0xBC, 0xEA, 0x1F, 0x06, 0x77, 0x51, - 0x73, 0x50, 0x0A, 0x80, 0x7F, 0x04, 0x4C, 0x4D, 0x65, 0x06, 0x0A, 0x3B, 0x3B, 0x62, 0x5A, 0x53, - 0x65, 0x05, 0x02, 0x04, 0x68, 0x0C, 0x6A, 0x00, 0x5D, 0x5E, 0x0F, 0x0F, 0x6A, 0x98, 0x6A, 0x09, - 0x7B, 0x56, 0x9D, 0x09, 0x0C, 0xA7, 0xA7, 0x7F, 0x06, 0x9D, 0xA3, 0x44, 0x02, 0x01, 0x03, 0x90, - 0x0C, 0x87, 0x03, 0x06, 0x02, 0x05, 0x56, 0x06, 0x01, 0x02, 0x53, 0xB1, 0xB3, 0x04, 0x79, 0xAF, - 0x55, 0x48, 0x51, 0xB0, 0x87, 0xC0, 0x7F, 0x07, 0x95, 0x05, 0x85, 0x44, 0xB6, 0x00, 0x05, 0x53, - 0x96, 0x6A, 0x60, 0x02, 0x0A, 0x48, 0x89, 0x00, 0x07, 0xA1, 0x69, 0x7D, 0x2B, 0x3D, 0x9D, 0x41, - 0xA1, 0x04, 0xA0, 0xDD, 0x9D, 0x38, 0x02, 0xE1, 0x6A, 0x07, 0x62, 0x0C, 0x77, 0xE6, 0xAD, 0x2F, - 0x05, 0x01, 0xB6, 0x90, 0x07, 0xA8, 0xA7, 0x54, 0xB5, 0xBC, 0x06, 0x33, 0x50, 0x53, 0x3A, 0x00, - 0x39, 0x62, 0x10, 0x6B, 0xDF, 0xBE, 0x19, 0x03, 0x18, 0x40, 0xA9, 0x15, 0x4B, 0xCC, 0x0E, 0x77, - 0x3B, 0x04, 0xC4, 0x02, 0x38, 0x43, 0x21, 0x96, 0x2C, 0xD3, 0xD6, 0x81, 0x01, 0x26, 0x2A, 0xFB, - 0xDE, 0x07, 0x7C, 0x0A, 0xB7, 0x71, 0x1B, 0x79, 0xEE, 0xC5, 0x83, 0x72, 0xDD, 0x84, 0xBC, 0x4B, - 0x13, 0xA4, 0x13, 0x15, 0x17, 0xAB, 0x18, 0x78, 0x4A, 0x43, 0x40, 0x81, 0x43, 0x76, 0x8E, 0xB6, - 0x04, 0x7C, 0x19, 0x02, 0x98, 0xC4, 0x86, 0x35, 0xBD, 0xE1, 0x1C, 0x90, 0x4D, 0x62, 0xBF, 0x14, - 0xFC, 0x7E, 0x02, 0x1A, 0x60, 0xD3, 0xD1, 0x9D, 0x3B, 0x3A, 0x09, 0xFC, 0x44, 0xB1, 0xD0, 0x96, - 0x8E, 0x43, 0x8D, 0x9E, 0xDA, 0xDB, 0x22, 0x11, 0x8A, 0x42, 0x10, 0x5C, 0x00, 0x1A, 0x2D, 0x38, - 0xF2, 0x0E, 0xA0, 0x4A, 0x03, 0x4E, 0xA2, 0xF0, 0xF4, 0x80, 0x17, 0x95, 0x8C, 0x23, 0xD1, 0xD8, - 0x12, 0x00, 0x92, 0x03, 0xAB, 0x99, 0x23, 0x71, 0x3E, 0x8D, 0xEB, 0x6E, 0x18, 0x07, 0x66, 0x23, - 0x05, 0x3E, 0x72, 0xE4, 0x06, 0x0D, 0x81, 0x02, 0xE4, 0x36, 0x5D, 0xD9, 0xA5, 0xC0, 0xAD, 0x59, - 0xA2, 0x86, 0x6E, 0xD6, 0xC4, 0x73, 0xEB, 0x15, 0xA5, 0xC5, 0xDE, 0x14, 0xF4, 0x62, 0x07, 0xC0, - 0xE9, 0x9D, 0xCC, 0x58, 0x02, 0x14, 0xA0, 0x84, 0x45, 0x83, 0x68, 0x7A, 0x8D, 0x81, 0x66, 0xC3, - 0xE9, 0xD0, 0xA6, 0x3E, 0x03, 0xF3, 0x80, 0x7D, 0x90, 0xD8, 0x58, 0xA2, 0x59, 0x2D, 0x90, 0x68, - 0xD6, 0x64, 0x17, 0x76, 0x5A, 0x23, 0xBF, 0x13, 0x58, 0x89, 0x7A, 0xC3, 0xF0, 0x8F, 0xB6, 0xB8, - 0x4B, 0xD3, 0x74, 0x52, 0x50, 0x92, 0xC2, 0x03, 0xD1, 0x78, 0xD7, 0x89, 0x4C, 0x23, 0x26, 0x6E, - 0x82, 0xCC, 0x15, 0x5E, 0x05, 0x08, 0x30, 0x06, 0x8A, 0x75, 0x64, 0xFA, 0x42, 0xF1, 0x12, 0xAD, - 0x60, 0xDE, 0x51, 0x0A, 0x94, 0xBA, 0x5E, 0x2C, 0x8C, 0x86, 0xDD, 0x3D, 0xDE, 0x8F, 0x0A, 0x70, - 0x51, 0x5F, 0xFE, 0xF2, 0x84, 0xD1, 0xD0, 0xA6, 0x68, 0xB7, 0x96, 0x62, 0x14, 0x0C, 0xC1, 0xB7, - 0x90, 0x68, 0x72, 0xD1, 0x7C, 0xD9, 0x3D, 0xA3, 0x94, 0x35, 0xDE, 0x54, 0x06, 0x92, 0x51, 0x50, - 0x68, 0xC2, 0xC5, 0x44, 0xB7, 0x30, 0x70, 0xDE, 0x6A, 0x49, 0x69, 0x86, 0xC5, 0x2D, 0xA3, 0x29, - 0x04, 0x05, 0x2F, 0xD9, 0xC4, 0x02, 0x0C, 0x6C, 0x0C, 0x48, 0xB0, 0x94, 0x01, 0xDA, 0x3C, 0xF2, - 0x56, 0x21, 0xFA, 0xE8, 0xA3, 0xA1, 0x55, 0x12, 0xE9, 0xF4, 0x56, 0x42, 0xF8, 0x50, 0x00, 0x40, - 0x08, 0x08, 0xD4, 0x88, 0x80, 0x05, 0x33, 0x66, 0x10, 0xA2, 0x0C, 0xDC, 0xA0, 0xB0, 0xA3, 0x0B, - 0x71, 0xCD, 0xB1, 0x80, 0x75, 0x69, 0x20, 0x41, 0xE4, 0x91, 0x6B, 0x64, 0x10, 0x01, 0x00, 0x21, - 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, 0x00, - 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, 0x8C, - 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0x31, 0x1C, 0x34, - 0x1B, 0x24, 0x4C, 0x82, 0xE7, 0x28, 0x5E, 0x02, 0x78, 0x7A, 0x30, 0x8E, 0x47, 0x62, 0x48, 0x20, - 0x60, 0xD8, 0x06, 0x4A, 0x8E, 0xC1, 0x70, 0x60, 0x0C, 0x04, 0xD1, 0xCD, 0x60, 0x60, 0x3B, 0x10, - 0xBA, 0x59, 0x8B, 0x21, 0x41, 0x2E, 0x0F, 0xC3, 0x16, 0xF2, 0xC0, 0xAC, 0x40, 0x4F, 0x1E, 0x80, - 0x04, 0x81, 0x70, 0xD8, 0x0A, 0x14, 0x0F, 0xF7, 0x42, 0x00, 0xA0, 0xD6, 0x09, 0x0A, 0x81, 0x81, - 0x68, 0x00, 0x85, 0x85, 0x7F, 0x07, 0x07, 0x0A, 0x06, 0x7A, 0x06, 0x00, 0x74, 0x74, 0x5E, 0x8A, - 0x36, 0x68, 0x05, 0x7C, 0x66, 0x3D, 0x64, 0x58, 0x61, 0x0F, 0x0F, 0x66, 0x64, 0x99, 0x64, 0x79, - 0x9C, 0x9E, 0xA0, 0x48, 0x4E, 0x9D, 0xA3, 0x4A, 0x02, 0x01, 0x37, 0x90, 0x55, 0x04, 0x5C, 0x02, - 0x05, 0x59, 0x06, 0x01, 0x02, 0x4F, 0x89, 0x55, 0x76, 0xAC, 0x50, 0xAB, 0x0A, 0xAD, 0x7F, 0xB1, - 0x75, 0x07, 0x02, 0x04, 0x05, 0x00, 0xBE, 0x39, 0x06, 0x77, 0x05, 0x36, 0x04, 0x9F, 0x5B, 0xCC, - 0x00, 0x4A, 0x82, 0x81, 0x07, 0x9F, 0x65, 0x86, 0x85, 0x40, 0x9D, 0x0A, 0x9F, 0x0C, 0xD0, 0x9F, - 0x00, 0x9D, 0x39, 0x02, 0xDE, 0x66, 0xB0, 0x73, 0xE2, 0x09, 0xE4, 0xAA, 0x2F, 0x05, 0x01, 0xCC, - 0x5E, 0xA7, 0x56, 0x75, 0xD2, 0xB8, 0x8C, 0x2F, 0x4C, 0x36, 0x06, 0xB1, 0x73, 0xE1, 0x88, 0xC9, - 0x92, 0x45, 0x43, 0x96, 0x00, 0x2E, 0x37, 0xE8, 0x79, 0x99, 0x53, 0xEC, 0x86, 0x0D, 0x06, 0x05, - 0xF3, 0x51, 0x61, 0x57, 0xE6, 0x9E, 0xBF, 0x35, 0x0C, 0xDE, 0x81, 0xE8, 0x64, 0x10, 0xFB, 0x5B, - 0xB6, 0x6C, 0xF5, 0x56, 0x94, 0x22, 0x13, 0xA7, 0xE2, 0x9C, 0x04, 0xDF, 0xCA, 0x74, 0xB2, 0xB2, - 0xC2, 0x40, 0x2A, 0x92, 0x72, 0x20, 0x45, 0x52, 0xE0, 0x45, 0x1A, 0x01, 0x2B, 0xCA, 0x3E, 0xC4, - 0x3A, 0x38, 0x60, 0xDB, 0x23, 0x86, 0xD6, 0x14, 0x0C, 0x20, 0xC0, 0x84, 0xCB, 0x8A, 0x7C, 0x3C, - 0x1F, 0x25, 0x94, 0xA9, 0x80, 0x21, 0x17, 0xA2, 0x5B, 0x4E, 0x34, 0x91, 0xE5, 0x2F, 0x99, 0x4C, - 0xA0, 0x89, 0xEC, 0x5C, 0xC1, 0xB5, 0x89, 0xC3, 0x15, 0x2B, 0xCC, 0x10, 0xD6, 0xF9, 0x38, 0x67, - 0xA8, 0xB1, 0x01, 0xE5, 0x40, 0xD4, 0x7B, 0x42, 0xF1, 0x63, 0x02, 0x66, 0x02, 0x12, 0xA4, 0xFA, - 0x90, 0x2A, 0x54, 0xB6, 0x44, 0xEB, 0xDA, 0x96, 0x19, 0x9A, 0x53, 0x43, 0x01, 0xBB, 0x64, 0x84, - 0xAE, 0xC3, 0xBB, 0xB0, 0xCC, 0x31, 0x40, 0x5D, 0x35, 0xD8, 0x62, 0x82, 0x6B, 0x68, 0xAC, 0xA6, - 0x43, 0xF1, 0xD2, 0x01, 0x20, 0xE9, 0x8A, 0x25, 0x05, 0x96, 0x36, 0xD8, 0x8A, 0xD7, 0xD8, 0x46, - 0xD0, 0x85, 0xEB, 0x7E, 0x72, 0x31, 0x10, 0x54, 0x9F, 0x85, 0x00, 0xF1, 0xA6, 0x1C, 0x94, 0x2C, - 0x34, 0xB2, 0x17, 0x9F, 0x5B, 0xB8, 0x14, 0x80, 0xFC, 0x41, 0x28, 0x63, 0xC7, 0x03, 0x9A, 0x4A, - 0x32, 0x9C, 0x2C, 0x2B, 0x2E, 0x40, 0x72, 0x63, 0x59, 0x48, 0x85, 0x47, 0x8D, 0xD8, 0xC8, 0xD9, - 0xE2, 0xF0, 0x55, 0x99, 0x4A, 0xE3, 0x82, 0x07, 0x41, 0x3F, 0x25, 0x92, 0xAE, 0xD7, 0x4C, 0x3C, - 0xE7, 0xAC, 0x02, 0x04, 0x58, 0xC4, 0xC4, 0xAD, 0x9C, 0x1B, 0xB1, 0x3F, 0xE1, 0x42, 0x3D, 0x4B, - 0x9E, 0x85, 0xCB, 0x57, 0xA6, 0x30, 0x4B, 0x97, 0x88, 0x26, 0xA2, 0x03, 0x7F, 0x8B, 0x72, 0x2D, - 0x90, 0x79, 0x02, 0xFD, 0x59, 0x36, 0xB2, 0xF3, 0x41, 0x2A, 0x65, 0xAD, 0x75, 0x64, 0x3A, 0x0C, - 0x48, 0xB4, 0x15, 0x35, 0x13, 0xE0, 0xC2, 0xC0, 0x2D, 0xB1, 0x15, 0x95, 0x0C, 0x13, 0x97, 0x59, - 0x73, 0x90, 0x01, 0xF5, 0xAC, 0x36, 0x8D, 0x79, 0x12, 0x40, 0xB8, 0x45, 0x22, 0xB8, 0xF8, 0xC4, - 0x0C, 0x7D, 0xB3, 0x31, 0x96, 0xCF, 0x00, 0x01, 0x76, 0x41, 0x80, 0x4F, 0x0B, 0x80, 0x78, 0x4A, - 0x24, 0x5B, 0x8C, 0x18, 0xDB, 0x8A, 0x0A, 0xF0, 0xC3, 0x15, 0x88, 0x08, 0xF1, 0xC5, 0xC7, 0x3C, - 0x13, 0x40, 0x94, 0x01, 0x81, 0x13, 0x20, 0xA0, 0x23, 0x02, 0x27, 0xE0, 0x58, 0x63, 0x08, 0xD9, - 0xE8, 0x41, 0x81, 0x5B, 0x42, 0x7A, 0x57, 0x86, 0x12, 0x46, 0x26, 0x79, 0x46, 0x06, 0x11, 0x00, - 0x00, 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, - 0x3C, 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, - 0xE4, 0x8C, 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0xA1, - 0x1C, 0x34, 0x1B, 0x24, 0x4A, 0x82, 0xE7, 0x27, 0x85, 0x50, 0x08, 0x0C, 0x3D, 0x12, 0xBC, 0xC4, - 0xA3, 0x18, 0x12, 0x08, 0x14, 0x86, 0xC1, 0x80, 0xC9, 0x31, 0x18, 0x0E, 0x84, 0x81, 0x80, 0xBA, - 0x91, 0x46, 0xB1, 0x51, 0x06, 0xD7, 0x62, 0x40, 0x9A, 0x91, 0xE2, 0x71, 0xA5, 0x37, 0x40, 0x33, - 0xDE, 0xE9, 0xF1, 0xE3, 0xA1, 0x20, 0x10, 0x0E, 0x52, 0x01, 0x63, 0xA9, 0x5E, 0x0C, 0x85, 0x03, - 0x76, 0x7A, 0x7D, 0x0B, 0x4E, 0x03, 0x75, 0x78, 0x77, 0x78, 0x06, 0x84, 0x51, 0x37, 0x8A, 0x77, - 0x02, 0x51, 0x6A, 0x05, 0x02, 0x04, 0x67, 0x67, 0x5B, 0x72, 0x47, 0x98, 0x98, 0x7C, 0x5C, 0x73, - 0x66, 0x58, 0x07, 0x8B, 0x0F, 0x00, 0x9F, 0x45, 0x02, 0x01, 0x03, 0xA3, 0x0C, 0x89, 0x03, 0x06, - 0x02, 0x00, 0x5C, 0x06, 0x01, 0x92, 0x52, 0x07, 0xAE, 0x59, 0x03, 0x00, 0xBD, 0xBD, 0x4C, 0x02, - 0x05, 0xAB, 0xB9, 0x70, 0x0C, 0xAC, 0x96, 0x00, 0x52, 0x45, 0x36, 0xC1, 0x51, 0x97, 0x0C, 0x66, - 0x5E, 0x00, 0x8C, 0x4C, 0x0A, 0x05, 0x5F, 0x68, 0x98, 0x4E, 0x56, 0x40, 0x7F, 0x3D, 0x67, 0x97, - 0x9D, 0x73, 0x39, 0x02, 0x74, 0x9C, 0x48, 0xA4, 0x76, 0x76, 0x66, 0x73, 0xA8, 0x2C, 0x05, 0x50, - 0x02, 0xA3, 0xA3, 0x59, 0x78, 0x5E, 0x92, 0xD4, 0x2C, 0xDB, 0xB0, 0x59, 0x76, 0x07, 0x00, 0x78, - 0x16, 0x09, 0x80, 0xF5, 0xE4, 0x05, 0xC1, 0x81, 0x5F, 0xB0, 0x10, 0x00, 0xA0, 0xEE, 0xC0, 0xC0, - 0x03, 0x8E, 0x68, 0x68, 0xB1, 0x72, 0xE5, 0x92, 0xAF, 0x5E, 0xF6, 0x0C, 0x10, 0xF0, 0x86, 0x62, - 0xFB, 0xCE, 0xC1, 0x03, 0x98, 0x00, 0x74, 0x42, 0x42, 0xE7, 0xC5, 0xB9, 0x4E, 0xFF, 0xC2, 0x9D, - 0x99, 0xA3, 0x60, 0x0A, 0x0A, 0x03, 0xED, 0xC0, 0xDD, 0xF1, 0x47, 0xCF, 0xCB, 0x2E, 0x97, 0x20, - 0x92, 0x0D, 0x64, 0x85, 0xA5, 0x65, 0x43, 0x2C, 0x3C, 0x19, 0x10, 0x30, 0x94, 0x2F, 0x27, 0xBE, - 0x9D, 0x87, 0x78, 0xCE, 0x54, 0x47, 0xC0, 0x98, 0xC6, 0x9D, 0x39, 0x2F, 0xC6, 0xB2, 0xF1, 0x87, - 0x29, 0x96, 0x62, 0xC6, 0xB6, 0x69, 0xE2, 0xC0, 0x2B, 0x4A, 0x2C, 0x58, 0x49, 0x47, 0xDA, 0x11, - 0x6A, 0x69, 0xC0, 0xB8, 0x10, 0x22, 0x1F, 0xDC, 0x0A, 0xF4, 0x6D, 0x64, 0x02, 0x06, 0xB1, 0x04, - 0x28, 0x39, 0xBB, 0xA1, 0xDD, 0x49, 0x4C, 0xE9, 0xD4, 0xB9, 0x4D, 0x0A, 0xA2, 0x40, 0x81, 0x91, - 0x81, 0x68, 0x2E, 0x35, 0x43, 0xA0, 0xC0, 0x50, 0x05, 0x1F, 0x6A, 0x39, 0xB9, 0x65, 0x47, 0x4A, - 0xBF, 0xBC, 0xF4, 0xF0, 0x04, 0xE3, 0x98, 0xA1, 0x96, 0x02, 0x5B, 0x5E, 0x71, 0xA5, 0x53, 0xA8, - 0x4E, 0x68, 0x16, 0x2B, 0x01, 0xFC, 0x42, 0x29, 0x4A, 0x21, 0xF4, 0xE8, 0x87, 0x0A, 0xA5, 0x04, - 0xDA, 0xDC, 0x94, 0x95, 0x6A, 0x03, 0xC2, 0x5A, 0x6E, 0xF0, 0x66, 0xC8, 0x0E, 0xC0, 0x99, 0x20, - 0xDF, 0x16, 0x93, 0xAC, 0x91, 0x64, 0x16, 0x0B, 0xED, 0x14, 0x70, 0xF2, 0xC2, 0x6B, 0x75, 0x27, - 0x68, 0x81, 0xDA, 0x90, 0xB4, 0x0B, 0xDC, 0x74, 0xC8, 0x8B, 0x67, 0xB0, 0xBC, 0x75, 0x2B, 0xCC, - 0x5D, 0xA1, 0x00, 0xD8, 0x09, 0xC4, 0x3D, 0x23, 0x92, 0xB0, 0x6B, 0x29, 0xDA, 0x6A, 0x55, 0x12, - 0x46, 0x7A, 0x41, 0xA5, 0x81, 0xF8, 0x62, 0x25, 0xE8, 0x4E, 0x2A, 0x60, 0x22, 0x52, 0x05, 0xB4, - 0xB4, 0x94, 0x14, 0xAC, 0x12, 0x05, 0xBF, 0xCD, 0xB4, 0x60, 0xA7, 0x6F, 0x66, 0x65, 0xE7, 0x57, - 0xC7, 0xA3, 0xC8, 0x67, 0x85, 0x16, 0x5B, 0x49, 0xF0, 0x84, 0x2A, 0x48, 0x19, 0x92, 0x47, 0x30, - 0x4E, 0x00, 0x60, 0xC9, 0x57, 0x71, 0x79, 0x03, 0x51, 0x30, 0xD3, 0x4C, 0xA0, 0xC0, 0x4E, 0xA4, - 0x1C, 0x45, 0x51, 0x2C, 0x7E, 0x39, 0xB8, 0x18, 0x3E, 0x04, 0xB5, 0x04, 0x14, 0x6C, 0xB3, 0xF8, - 0xF1, 0xC7, 0x3C, 0x00, 0xAA, 0xC6, 0xCB, 0x45, 0xFC, 0x21, 0xD5, 0x52, 0x72, 0x17, 0x95, 0x88, - 0xD8, 0x09, 0x08, 0x00, 0x80, 0x00, 0x02, 0x28, 0x94, 0x28, 0xC1, 0x8C, 0x20, 0x20, 0xD1, 0x5D, - 0x02, 0x27, 0xE8, 0x88, 0x82, 0x5B, 0x84, 0x2C, 0xE0, 0xD6, 0x19, 0x4C, 0x1C, 0xA9, 0xA4, 0x19, - 0x1B, 0x44, 0x00, 0x00, 0x21, 0xFE, 0x19, 0x42, 0x6F, 0x79, 0x27, 0x73, 0x20, 0x48, 0x61, 0x70, - 0x70, 0x79, 0x20, 0x48, 0x6F, 0x6C, 0x69, 0x64, 0x61, 0x79, 0x73, 0x20, 0x50, 0x61, 0x67, 0x65, - 0x00, 0x3B - -}; - -static const uint8_t bird_img_gif[] PROGMEM = { - 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x74, 0x00, 0x4E, 0x00, 0xCC, 0x13, 0x00, 0xFF, 0xFF, 0xFF, - 0xEF, 0xFF, 0xFF, 0xBD, 0xE7, 0xE7, 0xD6, 0xEF, 0xEF, 0x63, 0x63, 0x63, 0xAD, 0xAD, 0xAD, 0xCE, - 0xCE, 0xCE, 0xD6, 0xDE, 0xDE, 0x4A, 0x4A, 0x4A, 0x7B, 0x84, 0x84, 0x94, 0x9C, 0x9C, 0xE7, 0xE7, - 0xE7, 0x84, 0x94, 0x94, 0xB5, 0xC6, 0xC6, 0x73, 0x7B, 0x7B, 0x31, 0x31, 0x31, 0xF7, 0xF7, 0xF7, - 0x18, 0x10, 0x10, 0xCE, 0x63, 0x39, 0x6B, 0x39, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xFF, 0x0B, - 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x4B, - 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0xAE, 0xEC, 0x68, 0x2C, - 0x6D, 0x2C, 0xCF, 0x74, 0x6D, 0x03, 0x46, 0x84, 0x40, 0x77, 0xEF, 0xFF, 0x40, 0x51, 0x42, 0x41, - 0x0C, 0x1A, 0x8F, 0x48, 0x13, 0xC1, 0xD0, 0x20, 0x00, 0x0E, 0x8E, 0x42, 0x72, 0x4A, 0xAD, 0x21, - 0x0E, 0xCD, 0x05, 0xE1, 0x80, 0xA8, 0x7A, 0xBF, 0x29, 0xC2, 0xA0, 0x91, 0x28, 0x34, 0x02, 0x5D, - 0xB0, 0x5A, 0xFD, 0x08, 0x34, 0x14, 0x84, 0x00, 0x7A, 0x4D, 0xF7, 0x22, 0xDC, 0x89, 0xB8, 0xC1, - 0xB9, 0x80, 0xD5, 0xFF, 0x40, 0x0B, 0x77, 0x0C, 0x0F, 0x05, 0x01, 0x0C, 0x0A, 0x0B, 0x0F, 0x08, - 0x06, 0x80, 0x8E, 0x37, 0x7B, 0x01, 0x09, 0x11, 0x03, 0x68, 0x5C, 0x4C, 0x0A, 0x8F, 0x9A, 0x33, - 0x06, 0x09, 0x01, 0x0E, 0x71, 0x68, 0x88, 0x92, 0x07, 0x9B, 0xA6, 0x2C, 0x0A, 0x86, 0x07, 0x95, - 0x05, 0x04, 0xA1, 0x5D, 0x8D, 0xA7, 0xB2, 0x26, 0x09, 0x06, 0x72, 0x72, 0x0E, 0x94, 0x01, 0xA9, - 0x04, 0x08, 0x52, 0xB3, 0xC0, 0x00, 0x09, 0x95, 0xB7, 0x0D, 0x86, 0x01, 0x04, 0x0A, 0xC3, 0x09, - 0x34, 0x43, 0xC1, 0x54, 0x0E, 0xB7, 0xD2, 0x87, 0xAE, 0xBB, 0x99, 0x32, 0x7B, 0x0E, 0xCF, 0x49, - 0x0B, 0xD1, 0xD3, 0x72, 0x0C, 0xDE, 0x57, 0x33, 0xBE, 0xCC, 0xDB, 0x47, 0x05, 0x0C, 0xDF, 0xD3, - 0x05, 0xD7, 0x31, 0x0C, 0xE1, 0xA5, 0xE7, 0x46, 0xBE, 0xEB, 0xD2, 0x04, 0x05, 0xBF, 0x2C, 0x5C, - 0x4D, 0xF3, 0x46, 0x0B, 0x11, 0x56, 0xD9, 0x3B, 0x14, 0x01, 0x14, 0x0F, 0x16, 0x04, 0x1A, 0x30, - 0x28, 0x00, 0x81, 0xA1, 0x3F, 0x1F, 0xAD, 0x02, 0x10, 0x5B, 0x87, 0x6F, 0x0E, 0x8B, 0x02, 0x0E, - 0x04, 0x5C, 0x41, 0x10, 0xF0, 0x61, 0x8F, 0x25, 0x03, 0x26, 0xDA, 0x43, 0xC4, 0x42, 0x8B, 0x00, - 0x05, 0x0E, 0x7C, 0xFF, 0xED, 0xF0, 0x68, 0x83, 0x8B, 0x44, 0x91, 0xDF, 0x06, 0xAC, 0x54, 0x01, - 0x21, 0xA1, 0x80, 0x07, 0x0F, 0x1A, 0x38, 0x70, 0xC7, 0x72, 0x46, 0xC2, 0x97, 0x03, 0x3F, 0xC5, - 0x52, 0xE1, 0x80, 0x81, 0x00, 0x01, 0x19, 0x1B, 0x3C, 0x38, 0xD8, 0x53, 0xC6, 0x81, 0x38, 0x21, - 0x61, 0x4A, 0xEB, 0xB7, 0x42, 0x01, 0x82, 0xA3, 0x58, 0x7D, 0xC9, 0x6B, 0x1A, 0x63, 0x0B, 0xD0, - 0x81, 0x11, 0x08, 0x74, 0x44, 0x61, 0xE0, 0x01, 0xD6, 0xA3, 0x05, 0x16, 0x2D, 0xE5, 0xDA, 0xC2, - 0x80, 0xB7, 0x90, 0x41, 0xCB, 0xA4, 0x39, 0xC1, 0xEF, 0x2C, 0x56, 0xAA, 0x6C, 0x57, 0x38, 0xA8, - 0x14, 0x35, 0xA8, 0x35, 0x14, 0x10, 0x10, 0x34, 0xB0, 0x9B, 0xD5, 0x4F, 0xDE, 0x14, 0x06, 0x8E, - 0xF5, 0x1D, 0xC8, 0x25, 0x85, 0x83, 0xC1, 0x84, 0x05, 0x20, 0x32, 0x30, 0xF4, 0x30, 0x2D, 0x39, - 0x8B, 0x07, 0x32, 0x42, 0xA1, 0x00, 0x72, 0xE4, 0x45, 0x08, 0x7C, 0x59, 0x36, 0x91, 0x18, 0x73, - 0xE6, 0x6F, 0x79, 0x38, 0x2B, 0x88, 0x7C, 0x54, 0xE7, 0xE0, 0x2D, 0xA3, 0x4B, 0x78, 0x7A, 0x79, - 0x7A, 0x1A, 0xCE, 0x04, 0x4C, 0x85, 0xAC, 0x66, 0x7D, 0x96, 0x80, 0xB9, 0xD8, 0x22, 0x4A, 0x4B, - 0x14, 0x00, 0x97, 0xF1, 0xD3, 0x12, 0x3B, 0x79, 0x9F, 0x45, 0xC0, 0x13, 0xB8, 0xB7, 0xE1, 0xC5, - 0x19, 0x33, 0xEB, 0x53, 0xD3, 0xA8, 0x72, 0x01, 0x0D, 0x44, 0x97, 0x5C, 0x90, 0x7B, 0x9B, 0x01, - 0x05, 0xA6, 0x89, 0xFB, 0x3D, 0x54, 0x20, 0x81, 0xDA, 0x8C, 0xD7, 0x91, 0x16, 0x22, 0x91, 0xF8, - 0x80, 0x9F, 0x86, 0x08, 0x1E, 0xF4, 0xF2, 0xD5, 0x7D, 0x96, 0x18, 0xCC, 0x47, 0xA3, 0xDB, 0x7B, - 0xCA, 0x60, 0x40, 0xCA, 0xF4, 0x58, 0x81, 0xE2, 0x42, 0x04, 0x11, 0x4C, 0x80, 0x53, 0x7C, 0x3F, - 0xC9, 0xB1, 0xC7, 0xFF, 0x7A, 0xC1, 0x18, 0xA0, 0x0E, 0x7E, 0xC4, 0x49, 0xA5, 0x99, 0x67, 0xD7, - 0xA5, 0xB4, 0x15, 0x04, 0x93, 0x48, 0xA0, 0xA1, 0x81, 0x7C, 0x49, 0xB3, 0xC7, 0x38, 0xF6, 0x11, - 0x13, 0x52, 0x7E, 0x12, 0xAE, 0x63, 0xC0, 0x55, 0x00, 0x82, 0x62, 0xD8, 0x08, 0x0B, 0x24, 0xA0, - 0xA1, 0x86, 0x57, 0x3C, 0xF0, 0xE0, 0x2D, 0x05, 0x68, 0x67, 0x4A, 0x27, 0xB7, 0x0C, 0x80, 0x95, - 0x7E, 0x41, 0x11, 0x80, 0x5E, 0x85, 0xBF, 0x9D, 0xD0, 0xC0, 0x04, 0x2F, 0x2E, 0x62, 0xCB, 0x34, - 0x03, 0xE4, 0xB1, 0xA2, 0x23, 0x5E, 0x41, 0xC8, 0x63, 0x50, 0x0E, 0x9A, 0x75, 0x5D, 0x68, 0x5B, - 0x9D, 0xA0, 0x45, 0x04, 0x38, 0x2D, 0x72, 0xCC, 0x34, 0x7B, 0x24, 0xF2, 0x88, 0x5B, 0x39, 0xEA, - 0x18, 0xE1, 0x78, 0xD2, 0x58, 0x05, 0x20, 0x6C, 0x2B, 0xD4, 0x78, 0x64, 0x89, 0x6E, 0xB8, 0xF2, - 0xC2, 0x1F, 0x4D, 0xBE, 0x44, 0x22, 0x99, 0x72, 0xE4, 0x01, 0x60, 0x19, 0x31, 0x68, 0xB1, 0xC4, - 0x78, 0x50, 0xF4, 0xE2, 0x9B, 0x43, 0x5E, 0x80, 0x99, 0xE3, 0x8E, 0x6C, 0x4E, 0xE3, 0x63, 0x7A, - 0xD9, 0x55, 0xD6, 0x82, 0x4E, 0x04, 0x30, 0xD0, 0xC0, 0x01, 0x7C, 0x2A, 0xE4, 0xA3, 0xA2, 0x47, - 0xDC, 0x37, 0xE8, 0x9C, 0xE3, 0xC9, 0x64, 0x9D, 0x72, 0x70, 0x54, 0x29, 0x03, 0x04, 0xDF, 0xE5, - 0xE1, 0x4A, 0x19, 0x06, 0xB0, 0xD9, 0xC4, 0x66, 0x48, 0x7C, 0x27, 0xCD, 0x88, 0x98, 0x92, 0x89, - 0xE2, 0x75, 0x69, 0x2D, 0x69, 0xC3, 0x02, 0x07, 0xA4, 0x03, 0x8A, 0x2B, 0x8E, 0xC2, 0x04, 0x05, - 0x03, 0x48, 0x3C, 0x17, 0x5E, 0xAB, 0x7E, 0x61, 0x04, 0x20, 0x03, 0x33, 0x21, 0x01, 0xC1, 0x02, - 0xDF, 0x81, 0x52, 0x8B, 0x34, 0xAD, 0xC8, 0x6A, 0x43, 0x3E, 0x48, 0x9E, 0xF5, 0x24, 0x45, 0xAF, - 0xF2, 0x96, 0x9D, 0xFF, 0x03, 0xF5, 0x51, 0xD1, 0xA2, 0x03, 0x90, 0xCA, 0xF1, 0x94, 0x3E, 0x37, - 0x68, 0x81, 0xA4, 0x98, 0xC0, 0x9A, 0xF8, 0xC0, 0x8F, 0xCA, 0x39, 0xA0, 0xCD, 0x1F, 0x0B, 0x10, - 0x21, 0x0D, 0x03, 0xB8, 0x7D, 0x74, 0x64, 0x98, 0xD2, 0x16, 0x8A, 0x0C, 0xBA, 0xCA, 0x29, 0xF5, - 0x48, 0x8B, 0x53, 0xA1, 0x19, 0x03, 0xA8, 0x18, 0x85, 0xB2, 0x2A, 0xB9, 0x63, 0x06, 0x45, 0x06, - 0x80, 0x48, 0x05, 0xC9, 0x6E, 0x9C, 0x4F, 0xE1, 0xA3, 0xC2, 0x77, 0xF0, 0x16, 0x95, 0x4B, 0xB7, - 0xF4, 0x12, 0xEA, 0x57, 0x59, 0x14, 0xB2, 0x46, 0x08, 0xB8, 0x8E, 0x08, 0x72, 0x06, 0xB3, 0x3E, - 0xA6, 0xF2, 0x28, 0x46, 0x8B, 0x2C, 0xEB, 0xED, 0x03, 0xF3, 0x56, 0x5C, 0xF0, 0x40, 0xE6, 0xED, - 0xA6, 0x9C, 0x7C, 0xD9, 0x02, 0xA2, 0x48, 0xCA, 0x98, 0x25, 0xD6, 0xCE, 0x4E, 0x14, 0x2B, 0x18, - 0xE7, 0xC0, 0xE5, 0xAE, 0x93, 0x00, 0xC2, 0x45, 0x01, 0xB3, 0xC0, 0x8C, 0x74, 0xFA, 0xF7, 0x80, - 0x84, 0xAC, 0xAE, 0x6C, 0xCF, 0x00, 0x04, 0xA4, 0x47, 0x2C, 0x02, 0xCE, 0x6A, 0xF2, 0x06, 0x9D, - 0x98, 0xE5, 0x3C, 0xB0, 0x98, 0xB5, 0x4D, 0xD3, 0x40, 0x04, 0x05, 0x28, 0x57, 0x40, 0x04, 0x0A, - 0x50, 0x2A, 0x4B, 0x02, 0x1F, 0x53, 0xBD, 0x74, 0x54, 0x59, 0xBF, 0x1B, 0x5A, 0x41, 0xAC, 0x65, - 0xA7, 0xF0, 0x33, 0x0C, 0x58, 0x6D, 0xB6, 0x69, 0x68, 0x4F, 0x2B, 0x87, 0x55, 0xB7, 0x38, 0x50, - 0xC8, 0x5D, 0x7E, 0x8A, 0x1D, 0x0C, 0x04, 0x8F, 0xCD, 0x1D, 0x94, 0xDD, 0x4F, 0xA1, 0xEC, 0xA1, - 0x7C, 0xAD, 0x8D, 0xC5, 0x52, 0x4D, 0xBE, 0x0A, 0x3E, 0x9E, 0x55, 0x32, 0xDA, 0xA3, 0x37, 0x03, - 0xBD, 0x44, 0x3D, 0x8F, 0x55, 0x34, 0x3B, 0x6E, 0x4F, 0x03, 0x99, 0x73, 0x89, 0x93, 0xE5, 0xFE, - 0x74, 0x13, 0xB7, 0xCB, 0xE6, 0xA4, 0x4B, 0x63, 0x90, 0x65, 0xED, 0x16, 0x25, 0x77, 0xE9, 0x54, - 0x67, 0x11, 0xDB, 0x89, 0x44, 0xB3, 0x6E, 0xF6, 0x89, 0x7E, 0x37, 0x05, 0x47, 0xE7, 0xB2, 0xFB, - 0xF5, 0x2D, 0x70, 0xDD, 0x80, 0x37, 0xDE, 0x0A, 0x8E, 0xFB, 0x06, 0x1C, 0x00, 0x4D, 0xE0, 0x1E, - 0x80, 0x0C, 0x73, 0xFB, 0x47, 0x00, 0xE8, 0x2C, 0x89, 0x6E, 0xCF, 0x0C, 0x66, 0x87, 0x64, 0x55, - 0x73, 0x87, 0xB5, 0xD2, 0x39, 0xF2, 0x54, 0xA3, 0xAD, 0x24, 0xEF, 0x09, 0xC4, 0x2E, 0x47, 0x0C, - 0x83, 0x4F, 0x44, 0x6E, 0x25, 0xA9, 0x0C, 0x8F, 0x43, 0xE0, 0xD3, 0xB4, 0x30, 0x50, 0x54, 0xF9, - 0x41, 0x57, 0xC9, 0x63, 0xE6, 0x03, 0x00, 0xC1, 0xED, 0xE9, 0xAB, 0x60, 0x4F, 0x62, 0x94, 0x41, - 0x2A, 0xFE, 0x01, 0x56, 0x11, 0x10, 0xB3, 0x65, 0x4F, 0x11, 0xCC, 0x37, 0x4A, 0x10, 0x2C, 0x8E, - 0x3C, 0x80, 0x40, 0x3A, 0x30, 0x20, 0x02, 0x96, 0x10, 0x3F, 0x13, 0x64, 0xA7, 0x1E, 0x17, 0x53, - 0x90, 0x02, 0x28, 0x87, 0x00, 0xB2, 0xC1, 0xE0, 0x29, 0x08, 0x24, 0x50, 0xC9, 0xFE, 0x37, 0x3C, - 0x28, 0x30, 0x67, 0x75, 0x01, 0x9C, 0x20, 0x4E, 0x0A, 0xE0, 0xAC, 0xAF, 0x21, 0x90, 0x3E, 0x0D, - 0x4C, 0x41, 0xBB, 0x42, 0x13, 0x05, 0x63, 0xA4, 0x64, 0x81, 0x43, 0x28, 0x40, 0xED, 0x44, 0x00, - 0x01, 0x2C, 0x78, 0x29, 0x85, 0x2C, 0x38, 0x56, 0x62, 0x1A, 0xC0, 0x1D, 0x35, 0x84, 0x00, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, - 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, - 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, - 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, - 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, - 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, - 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, - 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, - 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, - 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, - 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, - 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, - 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, - 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, - 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, - 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, - 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, - 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, - 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, - 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, - 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, - 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, - 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, - 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, - 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, - 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, - 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, - 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, - 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, - 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, - 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, - 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, - 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, - 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, - 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, - 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, - 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, - 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, - 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, - 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, - 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, - 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, - 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, - 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, - 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, - 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, - 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, - 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, - 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, - 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, - 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, - 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, - 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, - 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, - 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, - 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, - 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, - 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, - 0x0D, 0x21, 0x00, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, - 0x00, 0x6A, 0x00, 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, - 0xAE, 0x6C, 0xEB, 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, - 0x0A, 0xC7, 0x03, 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, - 0xA4, 0x10, 0xA8, 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, - 0x9E, 0x18, 0x02, 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, - 0xD4, 0x81, 0x01, 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, - 0x0D, 0x08, 0x05, 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, - 0x04, 0x06, 0x10, 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, - 0x93, 0x09, 0x0C, 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, - 0x0C, 0x39, 0x9A, 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, - 0xAB, 0x5B, 0x4A, 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, - 0x0D, 0x0D, 0x07, 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, - 0x0E, 0x7B, 0x04, 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, - 0x92, 0x0C, 0x0E, 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, - 0x5B, 0x03, 0x0E, 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, - 0x98, 0xBE, 0x73, 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, - 0xB0, 0x6A, 0xA3, 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, - 0xBC, 0xA5, 0x0C, 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, - 0x04, 0x32, 0x53, 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, - 0x67, 0x8E, 0xA2, 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, - 0x33, 0xA0, 0x2B, 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, - 0x0E, 0x10, 0xC0, 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, - 0x0A, 0x08, 0xF8, 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, - 0x1D, 0x8A, 0x47, 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, - 0x22, 0x22, 0x82, 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, - 0x6B, 0x50, 0xE0, 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, - 0xA3, 0x2D, 0x60, 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, - 0x94, 0x14, 0x7F, 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, - 0x05, 0x30, 0x4A, 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, - 0x53, 0x20, 0xC1, 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, - 0x10, 0x03, 0x80, 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, - 0x26, 0x0F, 0x28, 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, - 0xC6, 0x0A, 0x02, 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, - 0xA0, 0xC0, 0x28, 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, - 0x42, 0x01, 0x5A, 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, - 0x88, 0x33, 0x14, 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, - 0x6A, 0xC4, 0x80, 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, - 0x28, 0xC2, 0xE2, 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, - 0x21, 0xA4, 0x0C, 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, - 0x4A, 0x93, 0x29, 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, - 0x94, 0x0C, 0x38, 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, - 0x56, 0x74, 0x54, 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, - 0x99, 0x83, 0x8A, 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, - 0x10, 0x02, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, - 0x6A, 0x00, 0x2E, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x00, 0x40, 0x62, 0xB9, 0x28, 0x08, 0x41, 0x28, - 0x4B, 0xE9, 0xBE, 0x70, 0x2C, 0xCF, 0x74, 0x6D, 0xDF, 0xE5, 0xF1, 0x3C, 0x69, 0x52, 0x24, 0x0F, - 0x82, 0xE1, 0x60, 0x00, 0x26, 0x5A, 0xB8, 0xA4, 0x72, 0xC9, 0x94, 0xE9, 0x22, 0x12, 0xC9, 0x64, - 0xF2, 0x18, 0x04, 0xAE, 0xD7, 0x01, 0xB0, 0xD0, 0xEC, 0x7A, 0xBF, 0x31, 0x48, 0x61, 0x12, 0x95, - 0x32, 0x02, 0x8E, 0x06, 0x36, 0x70, 0x50, 0x21, 0xC1, 0xF0, 0x78, 0x72, 0x91, 0x20, 0x4B, 0x55, - 0x85, 0xF5, 0xB5, 0x81, 0xE0, 0xCA, 0xFF, 0x80, 0x32, 0x0D, 0x0F, 0x53, 0x11, 0x11, 0x04, 0x07, - 0x7A, 0x57, 0x0E, 0x04, 0x6F, 0x81, 0x8F, 0x7F, 0x0B, 0x2A, 0x06, 0x94, 0x6A, 0x8A, 0x01, 0x06, - 0x04, 0x05, 0x07, 0x0B, 0x0B, 0x44, 0x94, 0xA0, 0x43, 0x24, 0x90, 0xA4, 0x37, 0x05, 0x04, 0x96, - 0x97, 0x58, 0x45, 0x09, 0x0A, 0x0C, 0x0C, 0x0A, 0x05, 0x0D, 0xB3, 0x05, 0x0A, 0x09, 0x0C, 0x05, - 0x06, 0xA3, 0x4D, 0x9F, 0xA0, 0x0B, 0xBB, 0xA5, 0x33, 0x6D, 0x08, 0x0C, 0x89, 0xAA, 0xC7, 0x8A, - 0x07, 0xAE, 0x3E, 0xC0, 0x32, 0x10, 0x07, 0x3F, 0x2A, 0x0E, 0x8C, 0x2A, 0x08, 0xD6, 0x29, 0x0E, - 0xB9, 0xCD, 0xC1, 0x22, 0x10, 0x45, 0xD2, 0xB8, 0x07, 0x56, 0x97, 0x22, 0xC8, 0x01, 0x0D, 0x0C, - 0x3E, 0x9C, 0x25, 0xCF, 0xA7, 0x04, 0xD9, 0xE2, 0xC8, 0x03, 0xD0, 0x09, 0x04, 0xD6, 0x09, 0xBA, - 0xDC, 0x30, 0x10, 0x0B, 0x06, 0xB6, 0x2A, 0x04, 0x12, 0xDC, 0x52, 0x40, 0x90, 0x60, 0x81, 0x5C, - 0x07, 0x20, 0xA8, 0x1A, 0xD0, 0x20, 0x01, 0x35, 0x07, 0x3C, 0x1C, 0x18, 0x30, 0x87, 0xCC, 0x00, - 0x03, 0x02, 0x0F, 0x12, 0x34, 0xD8, 0xA6, 0xCF, 0x44, 0xA7, 0x8F, 0x9D, 0x0E, 0x88, 0xAC, 0x75, - 0x6B, 0x22, 0xC5, 0x4B, 0x44, 0x4E, 0xFF, 0x26, 0x63, 0x80, 0x20, 0xE3, 0x81, 0x8E, 0x5D, 0x0E, - 0xA4, 0x33, 0xA6, 0x92, 0x8D, 0x03, 0x04, 0x35, 0x2F, 0x35, 0xC0, 0x98, 0xE0, 0x25, 0x4C, 0x26, - 0x07, 0x7C, 0xE4, 0xBC, 0x82, 0x40, 0xE1, 0x50, 0x3D, 0xCA, 0x52, 0x38, 0xFA, 0x89, 0xE3, 0x47, - 0xCE, 0x1F, 0x00, 0x8E, 0xAA, 0x02, 0xC2, 0x80, 0xE9, 0x92, 0x86, 0x2A, 0x0D, 0x3C, 0xA0, 0x29, - 0x55, 0xD1, 0x00, 0x8C, 0x06, 0xAC, 0x26, 0x31, 0x80, 0xC0, 0x24, 0x32, 0x04, 0x09, 0xBA, 0x9A, - 0x1B, 0x94, 0x80, 0xA3, 0x58, 0x18, 0x5A, 0xCF, 0x1C, 0x13, 0x78, 0x69, 0x9C, 0xDA, 0x2C, 0x04, - 0x22, 0x34, 0x78, 0x6B, 0x03, 0x82, 0x02, 0x44, 0x97, 0x5E, 0xD5, 0x1D, 0x60, 0xF7, 0xEE, 0xB9, - 0x07, 0x61, 0xF9, 0xD6, 0x58, 0xC0, 0x20, 0xDB, 0x1A, 0x82, 0x0B, 0x09, 0x17, 0xBE, 0xFB, 0x55, - 0x81, 0xE2, 0x1B, 0x99, 0x10, 0x39, 0xF6, 0x2A, 0x99, 0xB0, 0x61, 0x3D, 0x0E, 0x2F, 0xDF, 0x18, - 0x94, 0x87, 0xF3, 0x00, 0x01, 0x02, 0x24, 0x7F, 0x7E, 0x8C, 0x60, 0xA9, 0x68, 0x17, 0x6D, 0xCC, - 0x62, 0x91, 0x8C, 0x1A, 0x75, 0xE7, 0x2B, 0x30, 0xBA, 0xF2, 0xF1, 0xF9, 0xDA, 0x45, 0x26, 0xAE, - 0x59, 0x4E, 0xD7, 0x4E, 0xED, 0x19, 0xF7, 0x8C, 0xA3, 0x5A, 0xF7, 0xF6, 0x16, 0xF1, 0xC3, 0x68, - 0x70, 0xE1, 0xC3, 0x8B, 0xAF, 0xA1, 0x31, 0xF4, 0xB4, 0xD2, 0xD7, 0x10, 0x60, 0xE9, 0x21, 0x3C, - 0x3C, 0xFA, 0x64, 0xE3, 0x32, 0x6A, 0xD2, 0x56, 0xF0, 0xC0, 0x0F, 0x5F, 0x3A, 0xA9, 0x02, 0x70, - 0xEF, 0x4E, 0x5C, 0x3A, 0x68, 0xD7, 0xE5, 0x54, 0x72, 0xB7, 0xF2, 0xD5, 0xBC, 0xD5, 0xA0, 0x34, - 0xD7, 0xDB, 0x6E, 0xAF, 0x5A, 0x95, 0x03, 0xDE, 0x2F, 0x98, 0x73, 0xDB, 0x70, 0x01, 0xC4, 0xF2, - 0x96, 0x45, 0xB3, 0x41, 0x67, 0x5B, 0xFF, 0x7F, 0xE6, 0x00, 0x20, 0x51, 0x0C, 0xF2, 0xD0, 0x47, - 0x9C, 0x7A, 0xEA, 0x91, 0x07, 0x20, 0x4C, 0x05, 0xC8, 0xA5, 0x9E, 0x70, 0xA7, 0x31, 0x78, 0x92, - 0x24, 0x89, 0xB9, 0x70, 0x4C, 0x26, 0x41, 0x04, 0xA4, 0x40, 0x03, 0x19, 0x32, 0x72, 0xC8, 0x85, - 0x1D, 0xB9, 0x92, 0x20, 0x7F, 0xEE, 0x9D, 0x94, 0xE1, 0x49, 0x0C, 0xDD, 0x84, 0x16, 0x79, 0x11, - 0xF4, 0x11, 0x0B, 0x42, 0x62, 0x41, 0x70, 0xCB, 0x73, 0x1E, 0x0E, 0xE5, 0x20, 0x70, 0x7B, 0x10, - 0x40, 0x58, 0x5E, 0xC4, 0xE4, 0x23, 0x42, 0x02, 0x86, 0x34, 0xA2, 0x98, 0x24, 0x0A, 0x00, 0x19, - 0x63, 0x4E, 0xFD, 0x10, 0x43, 0x93, 0x32, 0x79, 0xF1, 0x90, 0x42, 0x88, 0x2E, 0x2C, 0xF0, 0x80, - 0x21, 0x0F, 0x30, 0x00, 0x5F, 0x30, 0x62, 0xF4, 0xB1, 0x61, 0x90, 0x47, 0x39, 0x18, 0xCB, 0x3F, - 0xEF, 0xF8, 0x60, 0xC0, 0x2F, 0x36, 0x3C, 0xB1, 0x22, 0x53, 0x99, 0x20, 0x90, 0x08, 0x9A, 0x5D, - 0x79, 0xD9, 0x80, 0x00, 0x29, 0xB4, 0xD6, 0x04, 0x59, 0x2C, 0xFC, 0x24, 0x13, 0x2A, 0x78, 0x76, - 0xF5, 0x95, 0x03, 0x0C, 0xA0, 0xA6, 0xA3, 0x17, 0x6E, 0x3D, 0xB2, 0xC0, 0x0F, 0x0A, 0x10, 0xB9, - 0xDA, 0x39, 0x08, 0x08, 0x90, 0x86, 0x00, 0x4E, 0x2E, 0x17, 0x86, 0x3B, 0xA5, 0x4D, 0xAA, 0x87, - 0x42, 0xAF, 0x0C, 0xE2, 0x00, 0xA6, 0x63, 0x8A, 0xF6, 0xA8, 0x0A, 0x91, 0x06, 0xF0, 0x4B, 0x9E, - 0xCE, 0x29, 0xF2, 0x17, 0x4B, 0x96, 0x16, 0x50, 0xA9, 0x9F, 0x9A, 0x02, 0x50, 0x00, 0x23, 0x81, - 0x9E, 0x1A, 0x41, 0x94, 0x47, 0x31, 0x10, 0xE6, 0x01, 0xD3, 0x98, 0xA5, 0x10, 0x2A, 0x2D, 0xF1, - 0x21, 0x46, 0x40, 0xB5, 0xDA, 0x8A, 0xD8, 0x02, 0x0D, 0x21, 0x9A, 0x80, 0x99, 0x98, 0xE0, 0x63, - 0xCE, 0x10, 0x01, 0xC8, 0x7A, 0xC2, 0x79, 0x11, 0x50, 0x65, 0x26, 0x2B, 0x9F, 0x64, 0xF9, 0xD1, - 0xE8, 0x93, 0x29, 0x32, 0x30, 0x84, 0x03, 0x0A, 0x28, 0x04, 0x2C, 0x46, 0x0B, 0x5C, 0x91, 0xAE, - 0x22, 0x64, 0x21, 0xB0, 0x13, 0x30, 0x99, 0xDC, 0xB4, 0xD3, 0xB3, 0xE9, 0x00, 0x50, 0x6A, 0xB2, - 0x00, 0xB4, 0xD1, 0x42, 0x50, 0x42, 0x00, 0xF6, 0x55, 0x51, 0xAA, 0x6A, 0x82, 0x09, 0x22, 0x08, - 0x38, 0xB0, 0x4D, 0xB7, 0x88, 0x2C, 0x60, 0x0D, 0x8B, 0xF8, 0xBE, 0x90, 0x89, 0x02, 0x0E, 0xE0, - 0x03, 0x81, 0xC0, 0x99, 0xDC, 0xAA, 0x2A, 0x44, 0xB3, 0xF8, 0xE9, 0x16, 0x04, 0x08, 0xD8, 0xC2, - 0x1C, 0x97, 0x0D, 0xCB, 0xE0, 0xC9, 0x28, 0x3A, 0x28, 0xF3, 0x5F, 0x6B, 0xBF, 0xD9, 0x72, 0xC4, - 0x62, 0x1D, 0x7F, 0x1B, 0x72, 0x0D, 0xCA, 0xBC, 0xD4, 0x86, 0x2D, 0x3E, 0xB9, 0xBC, 0x5C, 0x08, - 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, 0x6A, 0x00, - 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, 0xAE, 0x6C, 0xEB, - 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, 0x0A, 0xC7, 0x03, - 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, 0xA4, 0x10, 0xA8, - 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, 0x9E, 0x18, 0x02, - 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, 0xD4, 0x81, 0x01, - 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, 0x0D, 0x08, 0x05, - 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, 0x04, 0x06, 0x10, - 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, 0x93, 0x09, 0x0C, - 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, 0x0C, 0x39, 0x9A, - 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, 0xAB, 0x5B, 0x4A, - 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, 0x0D, 0x0D, 0x07, - 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, 0x0E, 0x7B, 0x04, - 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, 0x92, 0x0C, 0x0E, - 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, 0x5B, 0x03, 0x0E, - 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, 0x98, 0xBE, 0x73, - 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, 0xB0, 0x6A, 0xA3, - 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, 0xBC, 0xA5, 0x0C, - 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, 0x04, 0x32, 0x53, - 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, 0x67, 0x8E, 0xA2, - 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, 0x33, 0xA0, 0x2B, - 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, 0x0E, 0x10, 0xC0, - 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, 0x0A, 0x08, 0xF8, - 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, 0x1D, 0x8A, 0x47, - 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, 0x22, 0x22, 0x82, - 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, 0x6B, 0x50, 0xE0, - 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, 0xA3, 0x2D, 0x60, - 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, 0x94, 0x14, 0x7F, - 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, 0x05, 0x30, 0x4A, - 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, 0x53, 0x20, 0xC1, - 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, 0x10, 0x03, 0x80, - 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, 0x26, 0x0F, 0x28, - 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, 0xC6, 0x0A, 0x02, - 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, 0xA0, 0xC0, 0x28, - 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, 0x42, 0x01, 0x5A, - 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, 0x88, 0x33, 0x14, - 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, 0x6A, 0xC4, 0x80, - 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, 0x28, 0xC2, 0xE2, - 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, 0x21, 0xA4, 0x0C, - 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, 0x4A, 0x93, 0x29, - 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, 0x94, 0x0C, 0x38, - 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, 0x56, 0x74, 0x54, - 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, 0x99, 0x83, 0x8A, - 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, 0x10, 0x02, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, - 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, - 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, - 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, - 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, - 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, - 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, - 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, - 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, - 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, - 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, - 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, - 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, - 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, - 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, - 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, - 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, - 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, - 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, - 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, - 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, - 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, - 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, - 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, - 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, - 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, - 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, - 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, - 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, - 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, - 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, - 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, - 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, - 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, - 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, - 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, - 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, - 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, - 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, - 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, - 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, - 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, - 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, - 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, - 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, - 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, - 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, - 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, - 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, - 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, - 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, - 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, - 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, - 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, - 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, - 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, - 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, - 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, - 0x0D, 0x21, 0x00, 0x00, 0x3B}; +#include + +static const uint8_t firebase_logo_png[] PROGMEM = { + 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x02, 0x58, 0x08, 0x06, 0x00, 0x00, 0x00, 0x9A, 0x76, 0x82, + 0x70, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00, + 0x00, 0x04, 0x67, 0x41, 0x4D, 0x41, 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, 0x61, 0x05, 0x00, 0x00, + 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x00, 0x0E, 0xC3, 0x01, 0xC7, + 0x6F, 0xA8, 0x64, 0x00, 0x00, 0x55, 0x14, 0x49, 0x44, 0x41, 0x54, 0x78, 0x5E, 0xED, 0xDD, 0x59, + 0x90, 0x1D, 0xF5, 0x81, 0xE7, 0x7B, 0x3F, 0xF4, 0xC3, 0x84, 0x91, 0x40, 0x6E, 0xEF, 0xC6, 0x8B, + 0x30, 0x92, 0x4A, 0x1B, 0x58, 0x98, 0xCD, 0xA0, 0xA5, 0x4A, 0x12, 0x20, 0x6C, 0x9A, 0xB6, 0xBA, + 0x01, 0x63, 0x4F, 0x3F, 0x8C, 0x1E, 0x26, 0xC2, 0xF7, 0xE5, 0xC6, 0x25, 0xE2, 0xDE, 0x97, 0x3B, + 0x7D, 0x67, 0xAC, 0x6E, 0x63, 0x63, 0x83, 0x8D, 0xBC, 0xB1, 0x99, 0xA5, 0x10, 0x08, 0xED, 0x52, + 0x69, 0xAD, 0x92, 0xA0, 0xBB, 0xAB, 0xA7, 0xED, 0x6E, 0x77, 0xB7, 0x81, 0x42, 0x9B, 0x99, 0x89, + 0x89, 0xDB, 0x9A, 0xB9, 0x0E, 0x2F, 0x2C, 0x76, 0x61, 0x16, 0x49, 0x85, 0xA4, 0xFC, 0xDF, 0xFF, + 0x3F, 0x4F, 0xE6, 0xA9, 0x3C, 0x79, 0x7E, 0xE7, 0x9C, 0xCC, 0x3C, 0x99, 0x75, 0xCE, 0xC9, 0xFA, + 0x7E, 0x22, 0x7E, 0xA1, 0x6E, 0x2F, 0x42, 0xC2, 0x94, 0xE2, 0xFF, 0x8D, 0x7F, 0x65, 0x9E, 0xF7, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x82, 0x79, 0x6E, 0xCD, 0x80, 0xBF, 0xC3, 0x5F, 0x58, 0x12, 0xFC, + 0x4B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x1F, 0x73, 0x78, 0xCD, 0x3A, 0xEF, 0xB9, 0x35, 0x63, 0xE6, + 0xB9, 0x9B, 0x4D, 0x75, 0xCF, 0xAE, 0xF1, 0xE7, 0x3D, 0x7B, 0xD3, 0xA0, 0x0B, 0x92, 0xE0, 0x3F, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x98, 0x91, 0x35, 0xB3, 0xEB, 0xC2, 0x23, 0x12, 0x1F, 0xD1, + 0x79, 0x87, 0xD7, 0x6C, 0x08, 0xFE, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x8E, 0xFB, 0x16, 0x2B, + 0xEF, 0xD9, 0x35, 0xE3, 0x95, 0xE0, 0xB8, 0xD1, 0x98, 0x03, 0x57, 0x19, 0xB3, 0x7B, 0xAE, 0x31, + 0x3B, 0x3E, 0x65, 0xCC, 0xB6, 0x8F, 0x1A, 0xB3, 0xF3, 0xD3, 0xC6, 0x0C, 0x2D, 0x34, 0x66, 0x78, + 0xD9, 0x64, 0x84, 0x3C, 0x7B, 0xD3, 0x60, 0xF0, 0x5F, 0x07, 0x00, 0x00, 0x00, 0x80, 0xE4, 0xAA, + 0x37, 0x1F, 0x2E, 0x3C, 0x76, 0x7C, 0xC2, 0x98, 0xED, 0x1F, 0xAB, 0x84, 0x87, 0xDA, 0x2E, 0x1B, + 0x26, 0x87, 0x6F, 0xA8, 0x84, 0xC8, 0xA1, 0x9B, 0xD6, 0x06, 0x3F, 0x05, 0x00, 0x00, 0x00, 0x00, + 0xB4, 0xE6, 0x9E, 0xF9, 0xF0, 0xE3, 0x63, 0xCF, 0xA2, 0x4A, 0x78, 0x34, 0x8B, 0x8F, 0x70, 0xDB, + 0x3F, 0x6E, 0xCC, 0xC8, 0x0A, 0xF7, 0xAD, 0x58, 0xE3, 0x66, 0xB4, 0x7F, 0x56, 0xF0, 0x53, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x73, 0xDE, 0x73, 0x37, 0x9F, 0x34, 0xFB, 0xAF, 0x48, 0x1E, 0x1F, 0xE1, + 0x76, 0x5E, 0x62, 0xCC, 0xE1, 0xD5, 0x76, 0x37, 0xAE, 0x0F, 0x7E, 0x2A, 0x00, 0x00, 0x00, 0x00, + 0x68, 0xCC, 0x3D, 0x78, 0x6E, 0x0E, 0xAF, 0x4A, 0x1F, 0x1F, 0xFE, 0x3E, 0x62, 0xCC, 0xBE, 0xCF, + 0x18, 0xEF, 0xF0, 0x4D, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x68, 0xCD, 0xFF, 0x8C, 0x8F, 0xBD, + 0x97, 0x67, 0x8B, 0x0F, 0xB7, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x20, 0x19, 0x1B, + 0x20, 0xEB, 0xCD, 0xAE, 0x4F, 0xC7, 0xE2, 0xA2, 0xD5, 0x82, 0xF8, 0x08, 0xB7, 0x67, 0xB1, 0x31, + 0xCF, 0xDE, 0x64, 0xDC, 0x6D, 0x4A, 0xF0, 0xD3, 0x02, 0x00, 0x00, 0x00, 0x40, 0x3D, 0xEF, 0xB9, + 0x9B, 0x07, 0x75, 0x64, 0x34, 0x5A, 0x2C, 0x3E, 0xC2, 0x1D, 0x1A, 0xE0, 0xB5, 0xBC, 0x00, 0x00, + 0x00, 0x00, 0x9A, 0xF3, 0x0E, 0x2E, 0x1B, 0xD5, 0xA1, 0xA1, 0x26, 0xC2, 0x23, 0xDC, 0xD0, 0x02, + 0x6E, 0x41, 0x00, 0x00, 0x00, 0x00, 0x34, 0xE7, 0x1D, 0xB8, 0x76, 0x5C, 0xC7, 0x46, 0x7C, 0x22, + 0x3A, 0xE2, 0x1B, 0x59, 0x6E, 0xBC, 0xC3, 0x37, 0x8E, 0x06, 0x3F, 0x35, 0x00, 0x00, 0x00, 0x00, + 0x4C, 0x72, 0x6F, 0xAE, 0x32, 0xFB, 0x96, 0xD8, 0x78, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x0D, 0xB5, + 0x5D, 0x73, 0x2A, 0xB7, 0x20, 0xCF, 0xAD, 0x19, 0x08, 0xFE, 0x12, 0x00, 0x00, 0x00, 0x00, 0x50, + 0xE1, 0xBF, 0x01, 0x6B, 0x77, 0x9F, 0x8D, 0x07, 0x15, 0x1D, 0xE1, 0x44, 0x68, 0x34, 0xDB, 0xF0, + 0xF5, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xE7, 0x7F, 0x02, 0xFA, 0xAE, 0xB9, 0x36, 0x1C, + 0x54, 0x78, 0xB8, 0x89, 0xC0, 0x68, 0xB5, 0x5D, 0x97, 0x1A, 0xF3, 0xEC, 0x8D, 0xC6, 0x3C, 0xB7, + 0x9A, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x93, 0x6C, 0x80, 0xAC, 0xD7, 0xE1, 0xE1, 0x26, 0xE2, + 0xA2, 0xE5, 0x3E, 0x5C, 0xD9, 0x81, 0xAB, 0x8C, 0xF7, 0xEC, 0x0D, 0x27, 0x83, 0xBF, 0x0C, 0x00, + 0x00, 0x00, 0x00, 0xBC, 0xE7, 0x3D, 0xDE, 0xF0, 0x8A, 0x06, 0x6F, 0xC0, 0x52, 0x71, 0xD1, 0x6A, + 0x41, 0x7C, 0xB8, 0xED, 0xF8, 0x44, 0xE5, 0x16, 0xE4, 0xF0, 0x8D, 0xEB, 0x82, 0xBF, 0x14, 0x00, + 0x00, 0x00, 0x80, 0xE9, 0xCE, 0x3B, 0x70, 0xFD, 0xC9, 0xDC, 0xE3, 0x23, 0x1C, 0xB7, 0x20, 0x00, + 0x00, 0x00, 0x00, 0xA2, 0xCC, 0xFE, 0x2B, 0x6D, 0x2C, 0x14, 0x10, 0x1F, 0x6E, 0xEE, 0x16, 0xE4, + 0xF0, 0x2A, 0x77, 0x0B, 0xB2, 0x3E, 0xF8, 0xCB, 0x01, 0x00, 0x00, 0x00, 0x98, 0xAE, 0x6C, 0x18, + 0x2C, 0x31, 0x7B, 0x2E, 0xB3, 0xB1, 0x50, 0x40, 0x7C, 0x84, 0xDB, 0x77, 0xB9, 0x7B, 0x23, 0xD6, + 0xB8, 0x7B, 0xDD, 0x6F, 0xF0, 0x97, 0x05, 0x00, 0x00, 0x00, 0x30, 0x1D, 0x99, 0x43, 0x37, 0xAD, + 0x9D, 0x7C, 0x03, 0x96, 0x8A, 0x8B, 0x56, 0x13, 0xC1, 0x11, 0xDF, 0xF6, 0x8F, 0x71, 0x0B, 0x02, + 0x00, 0x00, 0x00, 0x20, 0x78, 0x03, 0xD6, 0xF6, 0x8F, 0xDB, 0x50, 0x50, 0x71, 0xD1, 0x6A, 0x22, + 0x36, 0x1A, 0x8D, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xB3, 0x37, 0x0D, 0xEA, 0xB8, 0x68, + 0x35, 0x11, 0x19, 0xAD, 0x76, 0xA8, 0xDF, 0x3D, 0x90, 0x3E, 0x18, 0xFC, 0xA5, 0x01, 0x00, 0x00, + 0x00, 0x4C, 0x37, 0xDE, 0x81, 0x6B, 0x46, 0x75, 0x60, 0x34, 0x9B, 0x88, 0x8B, 0x56, 0xDB, 0xFA, + 0x21, 0x63, 0x86, 0xE6, 0x57, 0x5E, 0xCB, 0x3B, 0xB2, 0x66, 0x76, 0xF0, 0x97, 0x07, 0x00, 0x00, + 0x00, 0x30, 0x9D, 0x98, 0x03, 0x57, 0xDB, 0x40, 0x50, 0x91, 0xD1, 0x68, 0x22, 0x2E, 0x5A, 0xCD, + 0xC5, 0x47, 0x38, 0x6E, 0x41, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC9, 0xDD, 0x44, 0x98, 0x7D, 0x9F, + 0xB1, 0x91, 0xA0, 0x42, 0x43, 0x4D, 0xC4, 0x45, 0xAB, 0x45, 0xE3, 0xC3, 0x6D, 0xF7, 0xDC, 0xCA, + 0x2D, 0xC8, 0x73, 0xAB, 0x07, 0x82, 0x5F, 0x06, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC0, 0x3C, 0xB7, + 0x66, 0xC0, 0xEC, 0x9E, 0x67, 0x43, 0x41, 0xC5, 0x46, 0x7C, 0x22, 0x2E, 0x5A, 0x2D, 0x1E, 0x1F, + 0xE1, 0x86, 0xAF, 0x73, 0x0F, 0xA4, 0x8F, 0x06, 0xBF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x81, + 0xF7, 0xEC, 0x4D, 0x77, 0x99, 0x9D, 0x97, 0xD8, 0x58, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x8B, 0x56, + 0x53, 0xE1, 0x11, 0x6E, 0xD7, 0xA7, 0xB9, 0x05, 0x01, 0x00, 0x00, 0x00, 0xA6, 0x1B, 0xEF, 0xF0, + 0x8D, 0x1B, 0x74, 0x70, 0x44, 0x27, 0xE2, 0xA2, 0xD5, 0x54, 0x74, 0xC4, 0xC7, 0x2D, 0x08, 0x00, + 0x00, 0x00, 0x30, 0xBD, 0x78, 0x07, 0xAF, 0x6F, 0xF1, 0x06, 0x2C, 0x11, 0x17, 0xAD, 0xA6, 0x62, + 0x43, 0xCD, 0x7D, 0xF6, 0x88, 0xBB, 0x05, 0x39, 0x7C, 0xE3, 0xBA, 0xE0, 0x97, 0x03, 0x00, 0x00, + 0x00, 0xA0, 0xCC, 0xBC, 0x03, 0xD7, 0x9D, 0xD4, 0xE1, 0xE1, 0x26, 0xE2, 0xA2, 0xD5, 0x54, 0x68, + 0x34, 0xDB, 0xFE, 0x2B, 0xDD, 0x1B, 0xB1, 0x4E, 0x06, 0xBF, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x65, + 0xD6, 0xF8, 0x0D, 0x58, 0x22, 0x2E, 0x5A, 0x4D, 0x05, 0x46, 0xAB, 0xB9, 0x5B, 0x90, 0xC3, 0x37, + 0x70, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x94, 0x9D, 0xFF, 0x06, 0xAC, 0xA1, 0x05, 0x36, 0x1E, 0x3A, + 0x14, 0x1F, 0xFE, 0x3E, 0x68, 0x5C, 0x04, 0x79, 0x87, 0x6E, 0x18, 0x37, 0xA3, 0xFD, 0xB3, 0x82, + 0x5F, 0x1A, 0x00, 0x00, 0x00, 0x80, 0xB2, 0x71, 0xB7, 0x0E, 0x66, 0xD7, 0x1C, 0x1B, 0x10, 0x1D, + 0x8C, 0x0F, 0x37, 0xF7, 0xD7, 0x3D, 0xB4, 0xD2, 0x98, 0xC3, 0xAB, 0xD7, 0x07, 0xBF, 0x34, 0x00, + 0x00, 0x00, 0x00, 0x65, 0x63, 0x03, 0x64, 0xBD, 0xD9, 0x7E, 0x71, 0x25, 0x00, 0x3A, 0x15, 0x1F, + 0xE1, 0xF6, 0x5E, 0xC6, 0x2D, 0x08, 0x00, 0x00, 0x00, 0x50, 0x66, 0xDE, 0xC8, 0xCA, 0xA1, 0xAE, + 0x88, 0x0F, 0xB7, 0xE0, 0x16, 0xC4, 0x3B, 0xBC, 0x7A, 0x43, 0xF0, 0xCB, 0x03, 0x00, 0x00, 0x00, + 0x50, 0x26, 0xDE, 0xC1, 0x6B, 0xC7, 0xBA, 0x22, 0x3E, 0xC2, 0xED, 0xEE, 0xAB, 0x3C, 0x90, 0x3E, + 0xB2, 0x66, 0x76, 0xF0, 0x4B, 0x04, 0x00, 0x00, 0x00, 0x50, 0x16, 0x66, 0xFF, 0x67, 0x75, 0x5C, + 0xB4, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0xD1, 0x11, 0xDF, 0xC8, 0x0A, 0xE3, 0x1D, 0x5A, 0x3D, 0x18, + 0xFC, 0x12, 0x01, 0x00, 0x00, 0x00, 0x94, 0x81, 0xBB, 0x65, 0x30, 0xFB, 0x2E, 0xD7, 0x81, 0xD1, + 0x6C, 0x32, 0x2C, 0x92, 0x4C, 0xC4, 0x86, 0x1A, 0xB7, 0x20, 0x00, 0x00, 0x00, 0x40, 0xF9, 0x98, + 0xE7, 0x56, 0x0F, 0x98, 0x5D, 0x97, 0xEA, 0xC8, 0x68, 0x34, 0x19, 0x16, 0x49, 0x26, 0x42, 0xA3, + 0xD9, 0x0E, 0x7E, 0xCE, 0x78, 0x87, 0x6F, 0x18, 0x0D, 0x7E, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x7A, + 0x9D, 0xFF, 0x06, 0xAC, 0x1D, 0x9F, 0xD0, 0xA1, 0xA1, 0x26, 0xC3, 0x22, 0xC9, 0x44, 0x60, 0xB4, + 0xDA, 0xCE, 0x4B, 0x82, 0x5B, 0x90, 0xD5, 0x03, 0xC1, 0x2F, 0x17, 0x00, 0x00, 0x00, 0x40, 0x2F, + 0xF3, 0x9E, 0xBD, 0x61, 0x50, 0x86, 0x86, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0x71, 0x91, 0x74, 0x07, + 0xAF, 0x35, 0xDE, 0xE1, 0x55, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x65, 0xE0, 0x1D, 0xBC, 0x6E, + 0x54, 0xC6, 0x46, 0x7C, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, 0x6D, 0xF9, 0x80, 0x31, 0x3B, + 0x67, 0xBB, 0x0F, 0x26, 0x34, 0xE6, 0xD0, 0xAA, 0xB5, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, 0x40, + 0xAF, 0xF2, 0x0E, 0x5C, 0x33, 0x2E, 0x83, 0x23, 0x3A, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, + 0x5C, 0x7C, 0x84, 0xDB, 0x77, 0x85, 0xFB, 0x5C, 0x90, 0x93, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, + 0x40, 0x2F, 0x72, 0x9F, 0x36, 0xDE, 0xF2, 0x0D, 0x58, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, + 0x45, 0xE3, 0xC3, 0x6D, 0xDB, 0xC7, 0x2A, 0xB7, 0x20, 0x87, 0x57, 0xAD, 0x0B, 0x7E, 0xE9, 0x00, + 0x00, 0x00, 0x00, 0x7A, 0x8D, 0xFF, 0x06, 0xAC, 0xDD, 0x73, 0xEB, 0xA3, 0x23, 0x9C, 0x0C, 0x8B, + 0x24, 0x13, 0x51, 0x91, 0x74, 0xF1, 0xF8, 0x08, 0xC7, 0x2D, 0x08, 0x00, 0x00, 0x00, 0xD0, 0xDB, + 0xCC, 0xE1, 0x1B, 0xD7, 0x35, 0x7C, 0x05, 0xAF, 0x0C, 0x8B, 0x24, 0x13, 0x51, 0x91, 0x74, 0x2A, + 0x3C, 0xC2, 0x6D, 0xB5, 0xBF, 0xA6, 0x43, 0x03, 0xEE, 0x26, 0x64, 0x7D, 0xF0, 0xCB, 0x07, 0x00, + 0x00, 0x00, 0xD0, 0x4B, 0xFC, 0x57, 0xF0, 0xF6, 0x42, 0x7C, 0x84, 0xDB, 0xB3, 0xD8, 0x7D, 0x3A, + 0xFA, 0xB8, 0xFB, 0xD6, 0xB1, 0xE0, 0xB7, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x57, 0x78, 0xC3, 0xCB, + 0xEB, 0xDF, 0x80, 0x25, 0xC3, 0x22, 0xC9, 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x0D, 0x35, 0x6E, 0x41, + 0x00, 0x00, 0x00, 0x80, 0xDE, 0xE5, 0x1D, 0xBC, 0x76, 0xAC, 0x67, 0xE2, 0x23, 0xDC, 0x9E, 0x45, + 0xC6, 0x3B, 0xB4, 0x6A, 0xDC, 0x8C, 0xF4, 0xCF, 0x0E, 0x7E, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x7A, + 0x81, 0xD9, 0x7F, 0x45, 0x6F, 0xC5, 0x87, 0xBF, 0xF7, 0x1B, 0x33, 0xB2, 0xCC, 0x46, 0xC8, 0xCA, + 0xC1, 0xE0, 0xB7, 0x01, 0x00, 0x00, 0x00, 0xA0, 0xDB, 0x99, 0xC3, 0x37, 0x2E, 0x71, 0xB7, 0x09, + 0x3D, 0x17, 0x1F, 0x6E, 0xEE, 0xCD, 0x5D, 0x87, 0x57, 0xD9, 0x10, 0xE9, 0xCD, 0x5B, 0x10, 0xF7, + 0xEB, 0xB6, 0x1B, 0x08, 0xC6, 0x4D, 0x0E, 0x00, 0x00, 0x00, 0xCA, 0xCF, 0x1C, 0xBA, 0x69, 0xAD, + 0xFF, 0x06, 0x2C, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x5A, 0x10, 0x1F, + 0xE1, 0x7A, 0xEC, 0x16, 0xC4, 0xFF, 0xCC, 0x95, 0x91, 0xFE, 0xF5, 0xDE, 0xA1, 0x81, 0x93, 0xFE, + 0x73, 0x2C, 0x91, 0xF9, 0xFF, 0x9A, 0xFD, 0xF7, 0x78, 0xB8, 0x1E, 0x00, 0x00, 0x00, 0xA5, 0x55, + 0x79, 0x03, 0xD6, 0x47, 0x6D, 0x10, 0xA8, 0xB8, 0x68, 0x35, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, + 0xD5, 0x62, 0xF1, 0xE1, 0xB6, 0xF3, 0x53, 0xC1, 0x2D, 0xC8, 0xEA, 0x81, 0xE0, 0xB7, 0xD4, 0xB5, + 0xCC, 0xA1, 0xFE, 0xB5, 0xDE, 0xC8, 0xC0, 0x78, 0x3C, 0x3C, 0xE2, 0xAB, 0xFC, 0x67, 0xFA, 0xD7, + 0x06, 0xFF, 0x35, 0x00, 0x00, 0x00, 0xA0, 0x3C, 0xBC, 0x67, 0x6F, 0x18, 0xD4, 0x71, 0xD1, 0x6A, + 0x22, 0x2A, 0x92, 0x4E, 0xC6, 0x45, 0xAB, 0x89, 0xF8, 0x08, 0x77, 0xF0, 0x1A, 0xE3, 0x1D, 0x5E, + 0x39, 0x1A, 0xFC, 0x96, 0xBA, 0x92, 0x19, 0xE9, 0x5F, 0x57, 0x8D, 0x8C, 0x91, 0xE5, 0xFE, 0x43, + 0xF4, 0x66, 0xC7, 0xC7, 0x6B, 0xE7, 0xFE, 0x35, 0xF7, 0xEF, 0xF9, 0xFF, 0x99, 0x7E, 0x37, 0x3E, + 0xF1, 0x1D, 0x00, 0x00, 0x00, 0xE5, 0xE2, 0x1D, 0xB8, 0x7A, 0x54, 0x07, 0x46, 0xB3, 0x89, 0xA8, + 0x48, 0x3A, 0x19, 0x17, 0xAD, 0x26, 0xA2, 0x23, 0xBA, 0x2E, 0xBF, 0x05, 0xB1, 0x21, 0x31, 0xBB, + 0x7A, 0xF3, 0x31, 0x34, 0xBF, 0xF2, 0x6B, 0xDE, 0x3C, 0x4B, 0xCF, 0xFD, 0x7B, 0x43, 0x7D, 0x7E, + 0x80, 0x78, 0x23, 0x2B, 0x78, 0xCB, 0x17, 0x00, 0x00, 0x00, 0xCA, 0xC5, 0xEC, 0xBF, 0xD2, 0x86, + 0x81, 0x8A, 0x8C, 0x46, 0x13, 0x51, 0x91, 0x74, 0x32, 0x2E, 0x5A, 0x2D, 0x12, 0x1A, 0xCD, 0xE6, + 0x6E, 0x41, 0x0E, 0xAD, 0x1A, 0x0B, 0x7E, 0x5B, 0x5D, 0xC5, 0xC6, 0xC7, 0x90, 0x1F, 0x1F, 0xBB, + 0x3E, 0xAD, 0xA3, 0xA3, 0x66, 0x17, 0x55, 0xB6, 0xF3, 0x92, 0x4A, 0x84, 0x0C, 0xAF, 0xE8, 0xEA, + 0x9B, 0x1D, 0x00, 0x00, 0x00, 0x20, 0x31, 0xFF, 0x81, 0xE8, 0xBD, 0x97, 0xDB, 0x38, 0x50, 0xA1, + 0xA1, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x9A, 0x08, 0x8D, 0x46, 0x73, 0xCF, 0xB1, 0xB8, + 0x5B, 0x90, 0xC3, 0xAB, 0xBA, 0xEA, 0xDB, 0x96, 0x6C, 0x44, 0x0C, 0xF8, 0xF1, 0xE1, 0xDE, 0xD8, + 0x25, 0x83, 0x23, 0xBA, 0x20, 0x3E, 0x62, 0x11, 0xE2, 0x7E, 0x8E, 0xE0, 0xA7, 0x03, 0x00, 0x00, + 0x00, 0x7A, 0x97, 0x79, 0x6E, 0xF5, 0x80, 0x7F, 0x30, 0x96, 0xB1, 0x11, 0x9F, 0x88, 0x8A, 0xA4, + 0x93, 0x71, 0xD1, 0x6A, 0x22, 0x32, 0x5A, 0x6D, 0xDF, 0x12, 0xE3, 0x1D, 0x5E, 0x75, 0x32, 0xF8, + 0xED, 0x75, 0x05, 0xEF, 0xD0, 0xC0, 0xA8, 0x39, 0x70, 0x55, 0x10, 0x18, 0xCD, 0x16, 0x8B, 0x8F, + 0x70, 0xFB, 0xAF, 0xE4, 0x16, 0x04, 0x00, 0x00, 0x00, 0xE5, 0xE0, 0x3D, 0x7B, 0xC3, 0x5D, 0x66, + 0xC7, 0xA7, 0x6C, 0x24, 0xA8, 0xE0, 0x88, 0x4E, 0x44, 0x45, 0xD2, 0xC9, 0xB8, 0x68, 0x35, 0x11, + 0x17, 0x49, 0x16, 0xDC, 0x82, 0x78, 0x87, 0x56, 0xDD, 0x15, 0xFC, 0x16, 0x3B, 0xAA, 0x7A, 0xFB, + 0xE1, 0x1E, 0x30, 0x97, 0xD1, 0x11, 0x4E, 0x84, 0x47, 0xB8, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, + 0x00, 0x80, 0x72, 0xF0, 0x0E, 0xDF, 0xB8, 0x41, 0x07, 0x47, 0x74, 0x22, 0x2A, 0x92, 0x4E, 0xC6, + 0x45, 0xAB, 0x89, 0xB0, 0x48, 0xB3, 0x3D, 0x0B, 0x8D, 0x37, 0xB2, 0x72, 0xBC, 0x1B, 0x3E, 0x4B, + 0x23, 0xD9, 0xED, 0x87, 0x88, 0x8E, 0xF8, 0xB8, 0x05, 0x01, 0x00, 0x00, 0x40, 0x19, 0x78, 0x07, + 0xAF, 0x6B, 0xF1, 0x06, 0x2C, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, 0xD5, 0x44, 0x50, 0xA4, 0xDA, + 0x1F, 0x57, 0xFE, 0xDA, 0x23, 0x2B, 0xEC, 0x56, 0xAE, 0x0F, 0x7E, 0x9B, 0x1D, 0xE1, 0x3E, 0xC7, + 0xC3, 0xBF, 0xFD, 0x70, 0x7F, 0x1F, 0x65, 0x78, 0xB8, 0x89, 0xD8, 0x50, 0xF3, 0x7F, 0x4F, 0xFD, + 0xC6, 0x1C, 0xE4, 0xB3, 0x41, 0x00, 0x00, 0x00, 0xD0, 0xC3, 0xBC, 0x03, 0x9F, 0x3B, 0x59, 0x1F, + 0x1D, 0xE1, 0x22, 0x31, 0x91, 0x76, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xD9, 0xF8, 0x08, + 0xD7, 0x05, 0xB7, 0x20, 0xFE, 0xA7, 0x9A, 0xBB, 0x07, 0xFC, 0x65, 0x78, 0xB8, 0x89, 0xD0, 0x68, + 0xB6, 0xBD, 0x97, 0xB9, 0x5B, 0x90, 0xAE, 0x7A, 0xBE, 0x05, 0x00, 0x00, 0x00, 0x48, 0xA5, 0xF1, + 0x1B, 0xB0, 0x44, 0x54, 0x24, 0x9D, 0x8C, 0x8B, 0x56, 0x53, 0x41, 0x91, 0x66, 0x91, 0xF8, 0x70, + 0x73, 0xBF, 0x8E, 0xE1, 0xA5, 0xEE, 0x13, 0xC5, 0x37, 0x04, 0xBF, 0xD5, 0x29, 0x65, 0xC2, 0x0F, + 0x1D, 0x74, 0x7F, 0x2F, 0xF3, 0x88, 0x0F, 0x37, 0xF7, 0x7B, 0xF2, 0x9F, 0x05, 0x59, 0xCE, 0x87, + 0x13, 0x02, 0x00, 0x00, 0xA0, 0xF7, 0xF8, 0x6F, 0xC0, 0x72, 0x1F, 0x8A, 0x57, 0xB6, 0xF8, 0x08, + 0xB7, 0x6B, 0x8E, 0x31, 0x87, 0x56, 0xBA, 0x43, 0xFB, 0x94, 0x7F, 0x90, 0x5F, 0xF3, 0xDB, 0x0F, + 0x11, 0x17, 0x49, 0xB7, 0x67, 0xB1, 0xF1, 0x86, 0x97, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x80, 0xDE, + 0x63, 0x0E, 0xDD, 0xB4, 0xD6, 0xFF, 0x60, 0xBC, 0x32, 0xC6, 0x47, 0x38, 0x77, 0x0B, 0x72, 0x68, + 0xE5, 0x60, 0xF0, 0x5B, 0x9E, 0x12, 0xCD, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0xDD, 0x33, 0x17, 0xDA, + 0xDF, 0x93, 0xFD, 0x7B, 0x66, 0x7F, 0x4F, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0xE7, 0x98, 0xC3, + 0x37, 0xAE, 0xF7, 0x5F, 0x5B, 0x5B, 0xD6, 0xF8, 0x70, 0x0B, 0x6F, 0x41, 0x0E, 0xF7, 0x2F, 0x09, + 0x7E, 0xDB, 0x85, 0x72, 0xCF, 0x9C, 0xF8, 0xB7, 0x1F, 0xEE, 0x66, 0x29, 0xEF, 0xF8, 0x08, 0xB7, + 0x7B, 0x9E, 0xF1, 0x46, 0x96, 0x8F, 0x9B, 0xA1, 0xCE, 0xBF, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, + 0xCC, 0x1B, 0x59, 0x39, 0x54, 0xEA, 0xF8, 0x08, 0x77, 0xE0, 0x6A, 0x77, 0x0B, 0x32, 0x25, 0xAF, + 0xB0, 0x35, 0x23, 0xFD, 0xEB, 0xCD, 0xC8, 0x72, 0xFB, 0xD7, 0xB5, 0xBF, 0xC6, 0x22, 0xE2, 0xC3, + 0x6D, 0xF3, 0xFB, 0xC2, 0x5B, 0x90, 0x8E, 0xBE, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, 0xC5, 0xDB, + 0x7F, 0xED, 0x58, 0xE9, 0xE3, 0xC3, 0x6D, 0xC7, 0x27, 0xC3, 0x67, 0x41, 0x0A, 0xFD, 0x20, 0x3F, + 0xFF, 0xF6, 0x63, 0x64, 0x60, 0xBC, 0xFE, 0xF6, 0x43, 0x44, 0x45, 0xD2, 0xC5, 0xE3, 0x23, 0x1C, + 0xB7, 0x20, 0x00, 0x00, 0x00, 0xE8, 0x35, 0x66, 0xDF, 0x12, 0x1D, 0x15, 0x49, 0x27, 0xE3, 0xA2, + 0xD5, 0x54, 0x50, 0xA4, 0x99, 0x08, 0x8C, 0x56, 0x73, 0x37, 0x06, 0x53, 0x70, 0x0B, 0xA2, 0x6F, + 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8F, 0x70, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0x97, 0x98, + 0x91, 0x35, 0xB3, 0xDD, 0xE7, 0x4A, 0xC8, 0xB0, 0x48, 0x32, 0x19, 0x17, 0xAD, 0x16, 0x8F, 0x89, + 0xB4, 0x13, 0x71, 0xD1, 0x6A, 0xEE, 0xA0, 0xEE, 0xB6, 0xED, 0x63, 0x95, 0x5B, 0x90, 0x43, 0xC5, + 0x7C, 0x90, 0x9F, 0xBE, 0xFD, 0x10, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0xE2, 0xE3, 0x16, 0x04, 0x00, + 0x00, 0x00, 0xBD, 0xC2, 0x8C, 0xAC, 0x1E, 0x30, 0x3B, 0x2F, 0xD1, 0x71, 0xD1, 0x6A, 0x32, 0x2E, + 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0x30, 0x3E, 0xC2, 0xED, 0xFD, 0x8C, 0xBB, + 0x05, 0x29, 0xE4, 0x15, 0xB6, 0xEE, 0xF3, 0x46, 0xCC, 0xF0, 0xF5, 0xF6, 0xAF, 0x33, 0x45, 0xF1, + 0x11, 0xEE, 0xE0, 0xE7, 0x6C, 0x84, 0xAC, 0xE8, 0xC8, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x89, + 0x99, 0xC3, 0xAB, 0xD7, 0x9B, 0xED, 0x17, 0xEB, 0xC0, 0x68, 0x36, 0x19, 0x17, 0xAD, 0xA6, 0x82, + 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x5A, 0x3C, 0x3E, 0xDC, 0xB6, 0x7E, 0x38, 0x7C, 0x16, 0x24, 0xD7, + 0x57, 0xD8, 0xDA, 0x9F, 0x6F, 0xB6, 0xFF, 0xDA, 0x5D, 0xF7, 0x4A, 0xE3, 0xA9, 0x8C, 0x0F, 0xB7, + 0x9D, 0xB3, 0xED, 0xEF, 0x67, 0x85, 0xFB, 0x3D, 0x4D, 0xF9, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, + 0x89, 0x79, 0x87, 0x57, 0x6F, 0x90, 0x81, 0xD1, 0x6C, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, + 0x89, 0xB8, 0x68, 0x35, 0x15, 0x1F, 0xE1, 0x82, 0x5B, 0x10, 0xF7, 0x2D, 0x53, 0xC1, 0xDF, 0x8A, + 0xB6, 0x79, 0x87, 0x06, 0x06, 0x27, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8C, 0x24, 0x73, + 0xB7, 0x20, 0xC3, 0x2B, 0xA6, 0xF4, 0xB3, 0x4E, 0x00, 0x00, 0x00, 0x80, 0x54, 0xBC, 0x83, 0x9F, + 0x1B, 0x95, 0x91, 0xD1, 0x68, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0x35, + 0x15, 0x1D, 0xD1, 0xB9, 0x5F, 0x97, 0x7F, 0x63, 0xB0, 0x32, 0x97, 0x87, 0xB7, 0x6B, 0x6F, 0x3F, + 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8B, 0xA4, 0xE3, 0x16, 0x04, 0x00, 0x00, 0x00, 0xDD, 0xCE, 0xDB, + 0x7F, 0xD5, 0xB8, 0x0C, 0x0D, 0xB5, 0xBA, 0xB0, 0x48, 0x32, 0x15, 0x14, 0x69, 0x26, 0xE2, 0xA2, + 0xD5, 0x54, 0x70, 0xA8, 0x0D, 0x2D, 0x30, 0xDE, 0xC8, 0xCA, 0xF1, 0x3C, 0x6E, 0x41, 0xFC, 0xDB, + 0x8F, 0x03, 0xD7, 0xDA, 0x9F, 0x57, 0x44, 0x45, 0xD2, 0xA9, 0xA8, 0x48, 0x3B, 0xF7, 0x96, 0xAF, + 0xE1, 0x65, 0xDC, 0x82, 0x34, 0x60, 0xC6, 0xFE, 0xC3, 0x2C, 0xF3, 0xF2, 0xBF, 0x5F, 0x67, 0x4E, + 0x7C, 0x65, 0x7D, 0x64, 0x6B, 0xDD, 0xBF, 0x1E, 0xFC, 0x47, 0x00, 0x00, 0x00, 0x50, 0x14, 0x77, + 0xF0, 0x4E, 0xFC, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, + 0x0A, 0x8D, 0x46, 0x73, 0xBF, 0xC6, 0x1C, 0x6E, 0x41, 0xDC, 0xA7, 0xAB, 0xFB, 0xB7, 0x1F, 0xEE, + 0x59, 0x1A, 0x15, 0x16, 0x49, 0xA6, 0x62, 0x22, 0xCB, 0xB6, 0x7F, 0xD4, 0xFE, 0x7E, 0x96, 0xDB, + 0x2D, 0x2D, 0xF4, 0xB3, 0x4E, 0x7A, 0x8D, 0x0B, 0x0C, 0xEF, 0xC4, 0x97, 0x07, 0xCD, 0x2F, 0xBE, + 0x62, 0xE4, 0x4E, 0x7C, 0xC9, 0xF8, 0xFF, 0x3E, 0x21, 0x02, 0x00, 0x00, 0x50, 0x1C, 0xFF, 0x0D, + 0x58, 0xBB, 0xE6, 0xE8, 0xE0, 0x88, 0xAE, 0x2E, 0x2C, 0x92, 0x4C, 0x05, 0x45, 0x9A, 0x89, 0xB8, + 0x68, 0x35, 0x15, 0x19, 0xAD, 0xE6, 0xBF, 0xC2, 0x76, 0xE5, 0x78, 0x3B, 0xDF, 0xB6, 0xE4, 0x1D, + 0x1A, 0x18, 0x35, 0xFB, 0xAF, 0xB4, 0x3F, 0x9F, 0x08, 0x8B, 0x24, 0x53, 0x21, 0x91, 0x69, 0x33, + 0x2B, 0xDB, 0x7F, 0x85, 0xF1, 0x86, 0x97, 0x4F, 0xC9, 0x27, 0xBE, 0xF7, 0x02, 0x73, 0xFC, 0xDF, + 0x2F, 0xF1, 0x7E, 0xF1, 0xE5, 0xF1, 0xDA, 0xE0, 0xB8, 0xDD, 0x98, 0xE3, 0x5F, 0xF4, 0xC3, 0x23, + 0xFA, 0xAF, 0xFB, 0xFF, 0x39, 0xFB, 0x9F, 0x0F, 0xFE, 0xAB, 0x00, 0x00, 0x00, 0xC8, 0x93, 0x39, + 0x7C, 0xE3, 0xBA, 0x96, 0xAF, 0xE0, 0x95, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, + 0xAB, 0xA9, 0xB8, 0x48, 0xBA, 0xE1, 0xEB, 0x8D, 0xFB, 0x16, 0xAA, 0xE0, 0x6F, 0x4B, 0x2A, 0x36, + 0x5C, 0x06, 0xEC, 0xB2, 0xDF, 0x7E, 0xC8, 0x90, 0xC8, 0xB2, 0x20, 0x3E, 0xDC, 0xB8, 0x05, 0xA9, + 0xAA, 0x89, 0x0F, 0x17, 0x1D, 0x2F, 0xD9, 0xFF, 0xAD, 0x5E, 0xB0, 0xB1, 0xF8, 0xFC, 0x92, 0xC9, + 0xBD, 0x70, 0xB5, 0xFD, 0xD7, 0x57, 0x55, 0xFE, 0x7D, 0x22, 0x04, 0x00, 0x00, 0xA0, 0x38, 0xFE, + 0x2B, 0x78, 0x55, 0x74, 0x84, 0x93, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, + 0xA9, 0xA8, 0x48, 0xBC, 0x59, 0x95, 0x07, 0xC7, 0xDD, 0xB7, 0x50, 0x65, 0xB8, 0x05, 0xF1, 0x86, + 0x57, 0x64, 0xBF, 0xFD, 0x90, 0x21, 0x91, 0x65, 0x91, 0xF8, 0x08, 0xC7, 0x2D, 0x48, 0x6D, 0x7C, + 0x1C, 0xB9, 0xB1, 0x36, 0x3A, 0xD4, 0x5C, 0x98, 0x1C, 0xFD, 0x42, 0x25, 0x42, 0x4E, 0x7C, 0x85, + 0x1B, 0x24, 0x00, 0x00, 0x80, 0xBC, 0x79, 0x07, 0x97, 0x35, 0x7E, 0x03, 0x96, 0x8C, 0x8B, 0x56, + 0x53, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0x85, 0x1F, 0x16, 0x68, 0xE7, + 0x6E, 0x41, 0x46, 0x06, 0x86, 0x82, 0xBF, 0x35, 0x89, 0xB4, 0x75, 0xFB, 0x21, 0x43, 0x22, 0xCB, + 0x44, 0x7C, 0xB8, 0x6D, 0xFD, 0xD0, 0xB4, 0xBE, 0x05, 0xA9, 0x89, 0x0F, 0x77, 0xEB, 0xA1, 0x82, + 0xA3, 0xD1, 0x5C, 0xAC, 0xF8, 0x37, 0x26, 0x5F, 0x29, 0xE4, 0xD3, 0xF2, 0x01, 0x00, 0x00, 0xA6, + 0x2D, 0x6F, 0xFF, 0x35, 0x63, 0xC4, 0x47, 0xB0, 0xED, 0x1F, 0xB7, 0x87, 0x75, 0xFF, 0x16, 0x24, + 0xF1, 0x81, 0xDD, 0x1B, 0x59, 0x31, 0xE6, 0x3F, 0xC4, 0xAF, 0x02, 0xA3, 0xD9, 0x64, 0x48, 0x64, + 0x99, 0x08, 0x8F, 0xE8, 0xF6, 0x2C, 0xB2, 0x51, 0xB5, 0x7C, 0x2C, 0xF8, 0xE5, 0x4E, 0x1B, 0x6D, + 0xC5, 0x47, 0xB8, 0x63, 0x7F, 0xE2, 0x3F, 0x94, 0x1E, 0xFC, 0x94, 0x00, 0x00, 0x00, 0xC8, 0x83, + 0xD9, 0xF7, 0x19, 0xE2, 0xC3, 0xED, 0x99, 0x60, 0xFB, 0xAF, 0x32, 0xDE, 0xF0, 0x40, 0xA2, 0x6F, + 0xBD, 0xB1, 0xA1, 0xB2, 0xCE, 0xBF, 0xFD, 0x70, 0x7F, 0xCF, 0x54, 0x64, 0x34, 0x9A, 0x0C, 0x89, + 0x2C, 0x13, 0xC1, 0x11, 0x9F, 0xFB, 0x7B, 0xEB, 0xDF, 0x82, 0x2C, 0xCF, 0xF5, 0x13, 0xDF, 0xBB, + 0x59, 0x2E, 0xF1, 0xE1, 0xF6, 0xC2, 0xD5, 0xEE, 0xDB, 0xB0, 0x4E, 0x06, 0x3F, 0x2D, 0x00, 0x00, + 0x00, 0xDA, 0x65, 0x0E, 0xDF, 0xB8, 0xC4, 0x0C, 0x2D, 0x9C, 0xBE, 0xF1, 0x11, 0x46, 0x47, 0xF0, + 0x7F, 0x7B, 0x6E, 0xDB, 0x3F, 0xEE, 0xBE, 0x0D, 0x2B, 0xD1, 0x2D, 0x88, 0x37, 0xBC, 0xE2, 0x64, + 0xEA, 0xDB, 0x0F, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, 0xD1, 0xDC, 0x2D, 0xC8, 0xF0, 0xB2, 0x69, + 0x71, 0x90, 0xCE, 0x2D, 0x3E, 0xC2, 0x1D, 0xBB, 0xC5, 0x04, 0x3F, 0x35, 0x00, 0x00, 0x00, 0xDA, + 0x65, 0x0E, 0xAD, 0x5A, 0x5B, 0xF3, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, + 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0xAB, 0x8F, 0x0F, 0x3F, 0x3C, 0xC2, 0x6D, 0xB2, 0xDB, 0x7B, + 0x85, 0x39, 0x3F, 0x3C, 0xD0, 0xF4, 0xC0, 0x9E, 0xE9, 0xF6, 0x43, 0x86, 0x44, 0x96, 0x89, 0xC8, + 0x68, 0x36, 0xF7, 0xF7, 0x79, 0x1A, 0xDC, 0x82, 0xE4, 0x1E, 0x1F, 0xCF, 0x7F, 0xC6, 0x98, 0x23, + 0x37, 0x18, 0xF3, 0xF2, 0x9D, 0x7C, 0x9E, 0x0A, 0x00, 0x00, 0x40, 0x1E, 0xFC, 0x37, 0x60, 0x6D, + 0xFB, 0xC8, 0xF4, 0x8D, 0x8F, 0x68, 0x78, 0xB8, 0xB9, 0xF8, 0x70, 0xDB, 0xFC, 0x21, 0xF7, 0x6D, + 0x58, 0xEE, 0x16, 0xA4, 0xE1, 0x81, 0xDD, 0xBF, 0xFD, 0xD8, 0xB3, 0xD0, 0xFE, 0x7C, 0x22, 0x34, + 0xD4, 0x64, 0x48, 0x64, 0x99, 0x08, 0x8C, 0x24, 0x1B, 0x9A, 0x5F, 0xEA, 0x5B, 0x90, 0x42, 0xE2, + 0xC3, 0x6D, 0xEC, 0x3A, 0x17, 0x20, 0xD3, 0xE6, 0xDB, 0xD7, 0x00, 0x00, 0x00, 0x0A, 0xE5, 0x1D, + 0x5A, 0x3D, 0x38, 0xED, 0xE2, 0x23, 0x12, 0x20, 0xD5, 0xE8, 0x88, 0xC4, 0xC7, 0xF9, 0x70, 0x43, + 0x97, 0x9B, 0x73, 0x07, 0xF5, 0x2D, 0xC8, 0xF9, 0x91, 0xFE, 0xF5, 0x66, 0x78, 0x99, 0xFD, 0xB9, + 0xDC, 0xAF, 0x49, 0xC4, 0x46, 0x7C, 0x32, 0x24, 0xB2, 0x4C, 0x84, 0x45, 0xD2, 0xB9, 0xDF, 0xF7, + 0xF0, 0xF5, 0xEE, 0x16, 0xA4, 0xAD, 0x4F, 0x7C, 0xEF, 0x46, 0x85, 0xC5, 0x87, 0xDB, 0x0B, 0x57, + 0x19, 0x73, 0xE2, 0xCE, 0xD2, 0xFD, 0x3D, 0x03, 0x00, 0x00, 0xE8, 0x08, 0x6F, 0xDF, 0x55, 0xA3, + 0x3A, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xC5, 0xC2, 0x22, 0xC9, 0x64, 0x54, 0x24, 0x5D, 0x24, + 0x3E, 0x82, 0xD5, 0xDC, 0x78, 0x84, 0xD1, 0xF1, 0x74, 0x64, 0x9B, 0x3F, 0x64, 0xCE, 0x1F, 0x5C, + 0x6E, 0xCE, 0x0D, 0xF7, 0xDF, 0x15, 0xFC, 0xED, 0xF2, 0x99, 0xA1, 0xFE, 0x59, 0xE7, 0x47, 0x56, + 0x8C, 0x9B, 0xDD, 0x7D, 0xF6, 0x60, 0x2F, 0x62, 0x23, 0x3E, 0x19, 0x12, 0x59, 0x26, 0xA2, 0x22, + 0xED, 0x76, 0xCF, 0x35, 0xDE, 0xC8, 0xB2, 0x71, 0xF7, 0x7B, 0x08, 0x7E, 0x3B, 0x3D, 0xAF, 0xD0, + 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x9F, 0x07, 0x02, 0x00, 0x00, 0x90, 0x07, 0xB3, 0xEF, 0x0A, + 0x7B, 0xB8, 0x57, 0x81, 0xD1, 0x6C, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, 0x48, + 0xBA, 0x48, 0x78, 0x44, 0x6F, 0x3E, 0xE2, 0xB7, 0x1E, 0x7E, 0x78, 0xBC, 0xCF, 0x9C, 0x7B, 0x6A, + 0x72, 0xE7, 0x77, 0xCE, 0x77, 0xB7, 0x20, 0x35, 0x07, 0xF6, 0xF3, 0x07, 0xFB, 0xD7, 0x7B, 0xC3, + 0xCB, 0x8C, 0xE7, 0x6E, 0x3F, 0x5A, 0x05, 0x88, 0x0C, 0x89, 0x2C, 0x13, 0x31, 0x91, 0x76, 0x9B, + 0x66, 0xD8, 0x1F, 0xED, 0xAF, 0xA9, 0x44, 0xB7, 0x20, 0x53, 0x11, 0x1F, 0x6E, 0xDE, 0xD1, 0x5B, + 0xA6, 0xDD, 0x6B, 0x8C, 0x01, 0x00, 0x00, 0x72, 0x67, 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x8B, 0xED, + 0x01, 0x5F, 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x58, 0x24, 0x99, 0x8C, 0x8A, 0xA4, + 0x8B, 0xC4, 0x47, 0x83, 0x00, 0x09, 0xE3, 0xE3, 0x5C, 0x24, 0x3E, 0xCE, 0x6E, 0x0C, 0xF6, 0xD4, + 0xFB, 0xCD, 0xF9, 0x03, 0xCB, 0x8D, 0x8B, 0x0E, 0xFF, 0xEF, 0x99, 0x0D, 0x91, 0x73, 0xC3, 0x2B, + 0xC6, 0xBD, 0x5D, 0x7D, 0xF6, 0xBF, 0x7F, 0x91, 0x3F, 0xFF, 0x50, 0xAF, 0x42, 0x44, 0x86, 0x44, + 0x96, 0x89, 0x98, 0x48, 0x3B, 0x17, 0x1F, 0xE1, 0x4A, 0x72, 0x0B, 0x32, 0x55, 0xF1, 0xE1, 0xEF, + 0xE8, 0xE7, 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xBB, 0xCC, 0xC8, 0xEA, 0x01, 0xB3, 0xEB, 0x52, + 0x7B, 0xC8, 0x57, 0xA1, 0xA1, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, + 0x4B, 0x1F, 0x1F, 0xD5, 0xF0, 0x78, 0xD2, 0x6D, 0x96, 0xBF, 0x73, 0x3B, 0xE6, 0x9B, 0xB3, 0x07, + 0x2A, 0xB7, 0x20, 0x2E, 0x44, 0xCE, 0x1F, 0x5C, 0x66, 0xFF, 0xFB, 0x7F, 0xDC, 0x3C, 0x40, 0x64, + 0x48, 0x64, 0x99, 0x88, 0x89, 0xB4, 0x8B, 0xC6, 0x87, 0x9B, 0xFB, 0xB5, 0x1E, 0xBC, 0xB6, 0xA7, + 0x6F, 0x41, 0xA6, 0x34, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0xEC, 0x5F, 0x33, 0xF8, 0xCB, 0x03, 0x00, + 0x00, 0x20, 0x0B, 0xEF, 0xD0, 0xAA, 0xBB, 0xCC, 0xF6, 0x4F, 0xD8, 0x83, 0xBE, 0x8A, 0x8D, 0xF8, + 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, 0x74, 0xB1, 0xF8, 0x08, 0x02, 0x24, + 0x49, 0x7C, 0xBC, 0x6B, 0xE3, 0xE3, 0xDD, 0xC1, 0x59, 0x93, 0xDB, 0xF8, 0x7E, 0x73, 0x6E, 0xEF, + 0xF5, 0xE6, 0xDC, 0x81, 0x81, 0x51, 0xF7, 0xED, 0x58, 0xE7, 0xB7, 0x5F, 0x62, 0xFF, 0xBB, 0x36, + 0x3E, 0xDC, 0x54, 0x84, 0xC8, 0x90, 0xC8, 0x32, 0x11, 0x13, 0x69, 0x17, 0x8F, 0x8F, 0x70, 0x3B, + 0x3E, 0xE9, 0x02, 0xC4, 0xBD, 0xE5, 0x6B, 0x76, 0xF0, 0x8F, 0x43, 0xCF, 0x98, 0xF2, 0xF8, 0x70, + 0x1B, 0x5B, 0x66, 0xCC, 0x89, 0xAF, 0xAC, 0x0D, 0x7E, 0x09, 0x00, 0x00, 0x00, 0xC8, 0xC2, 0x3B, + 0xBC, 0x7A, 0x83, 0x8E, 0x8D, 0xF8, 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, + 0x74, 0x3A, 0x3E, 0xEA, 0x02, 0xC4, 0x86, 0x47, 0xF8, 0xCC, 0x47, 0x3C, 0x3E, 0x26, 0xDC, 0x9E, + 0xA8, 0xCC, 0xFD, 0xFF, 0x67, 0xB7, 0x7C, 0xDA, 0x4C, 0x3C, 0xD3, 0x6F, 0xCE, 0x0D, 0xD9, 0x10, + 0x79, 0xCA, 0xFD, 0x77, 0x2F, 0xD2, 0x11, 0xB2, 0x49, 0x85, 0x44, 0x96, 0x89, 0x98, 0x48, 0x3B, + 0x15, 0x1E, 0xD1, 0x1D, 0xBC, 0xD6, 0xBD, 0x96, 0x77, 0x30, 0xF8, 0xC7, 0xA1, 0x27, 0x74, 0x24, + 0x3E, 0xDC, 0x5E, 0xBC, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0xB4, 0xCB, 0x3B, 0x78, 0x4D, 0x82, + 0x37, 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0xE1, 0x11, + 0x2E, 0x1E, 0x1F, 0xE1, 0xED, 0x47, 0xE4, 0x99, 0x0F, 0x17, 0x1F, 0xD1, 0xF0, 0x98, 0x78, 0x3C, + 0x98, 0xFB, 0xBF, 0x1F, 0x9B, 0x65, 0x4E, 0x3F, 0x72, 0x9D, 0x39, 0xF3, 0xF0, 0x25, 0x7E, 0x80, + 0x9C, 0xF3, 0x1F, 0x58, 0x8F, 0x05, 0x88, 0x8B, 0x8F, 0x5C, 0x02, 0x44, 0xC4, 0x44, 0xDA, 0xA9, + 0xE0, 0x88, 0xAF, 0xC7, 0x6E, 0x41, 0x3A, 0x16, 0x1F, 0xC1, 0xBC, 0x5F, 0xDC, 0x39, 0x14, 0xFC, + 0x52, 0x00, 0x00, 0x00, 0x90, 0x85, 0xB7, 0xFF, 0xEA, 0x93, 0x3A, 0x3A, 0xC2, 0xA9, 0xA0, 0x48, + 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x78, 0xB8, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, + 0xDE, 0x7E, 0xD4, 0x7E, 0xEB, 0x55, 0x34, 0x3E, 0xCE, 0xD8, 0xE8, 0x38, 0xF3, 0xF8, 0xFB, 0x82, + 0x55, 0x22, 0xE4, 0xF4, 0xFD, 0x17, 0x99, 0x53, 0xF7, 0x5E, 0x6C, 0x4E, 0xDD, 0x7D, 0x91, 0x39, + 0x6B, 0xFF, 0x33, 0x75, 0xB7, 0x20, 0x36, 0x3C, 0xDC, 0xDA, 0x0F, 0x10, 0x11, 0x13, 0x69, 0xA7, + 0x62, 0xA3, 0xD1, 0x7A, 0xE4, 0x16, 0xA4, 0xD3, 0xF1, 0xE1, 0xE6, 0x1D, 0xFB, 0x53, 0xDE, 0x84, + 0x05, 0x00, 0x00, 0xD0, 0x8E, 0xE6, 0x6F, 0xC0, 0x52, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, + 0x46, 0x45, 0xD2, 0xC5, 0xA2, 0x23, 0xBA, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDC, 0x7E, 0xD4, 0x7C, + 0xDB, 0x55, 0x18, 0x1F, 0x8F, 0xD9, 0xF0, 0xB0, 0x3B, 0x1D, 0xFC, 0x78, 0xE6, 0x91, 0xF7, 0xF9, + 0xE1, 0x11, 0xEE, 0xF4, 0x7D, 0x36, 0x42, 0x36, 0x4E, 0x46, 0x88, 0xF7, 0x74, 0x25, 0x3E, 0xAA, + 0x01, 0x92, 0x39, 0x42, 0x44, 0x4C, 0xA4, 0x9D, 0x8A, 0x8C, 0x66, 0xDB, 0x7E, 0x71, 0xD7, 0xDF, + 0x82, 0x74, 0x43, 0x7C, 0xF8, 0x3B, 0x76, 0x0B, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xC8, 0xCA, 0x7F, + 0x03, 0xD6, 0xEE, 0x79, 0xF6, 0xE0, 0x5F, 0xFE, 0xF8, 0x70, 0x3F, 0x36, 0xBF, 0xFD, 0xB0, 0xF1, + 0xE1, 0x02, 0x24, 0x88, 0x0F, 0x17, 0x1E, 0xA7, 0x1F, 0x9D, 0xDC, 0xA9, 0x7B, 0x67, 0xD5, 0x04, + 0x88, 0xDB, 0xBB, 0x3F, 0x0E, 0x02, 0xE4, 0xA9, 0x0B, 0xED, 0xCF, 0x67, 0xE3, 0x23, 0x1E, 0x21, + 0x32, 0x30, 0x9A, 0x4D, 0xC4, 0x44, 0xDA, 0xA9, 0xC0, 0x48, 0xB2, 0x7D, 0x57, 0x18, 0x6F, 0x78, + 0x79, 0x57, 0x7E, 0xD0, 0x5E, 0xD7, 0xC4, 0x87, 0x9B, 0x7B, 0x13, 0xD6, 0xCB, 0x77, 0xF6, 0xDC, + 0x43, 0xFB, 0x00, 0x00, 0x00, 0x5D, 0xC1, 0x1C, 0x5A, 0xB5, 0xD6, 0xEC, 0x9C, 0x6D, 0x0F, 0xFF, + 0x25, 0x8E, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDD, 0x7E, 0xB8, 0xD7, 0xEC, 0x46, 0x6F, + 0x3F, 0xE2, 0xF1, 0x71, 0xFA, 0x81, 0xDA, 0xDB, 0x8F, 0x70, 0xEE, 0x16, 0xE4, 0xDC, 0x93, 0x76, + 0x1B, 0x2F, 0xF2, 0x23, 0xA4, 0x26, 0x40, 0x5C, 0x50, 0xA4, 0x8A, 0x10, 0x11, 0x13, 0x69, 0xA7, + 0xC2, 0x22, 0xE9, 0xB6, 0x7D, 0x24, 0xB8, 0x05, 0x59, 0x3A, 0x10, 0xFC, 0xE3, 0xD1, 0x15, 0xBA, + 0x2A, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0xB3, 0xAB, 0xFE, 0x1E, 0x01, 0x00, 0x00, 0xF4, + 0x0C, 0x73, 0x78, 0xF5, 0x7A, 0xB3, 0xF5, 0xC3, 0x36, 0x00, 0x4A, 0x1C, 0x1F, 0xC1, 0xD4, 0xED, + 0xC7, 0x59, 0x3F, 0x40, 0x6C, 0x7C, 0xB8, 0xDB, 0x8F, 0xC8, 0xB7, 0x5E, 0x55, 0xC3, 0xE3, 0xC7, + 0x95, 0xA9, 0xDB, 0x0F, 0x7F, 0x5F, 0xBF, 0xD0, 0xBC, 0xFB, 0x48, 0x25, 0x40, 0xCE, 0xB5, 0x75, + 0x0B, 0x22, 0x62, 0x22, 0xED, 0x54, 0x54, 0xA4, 0x9D, 0xBB, 0x05, 0x39, 0xB8, 0xAC, 0x6B, 0x6E, + 0x41, 0xBA, 0x2E, 0x3E, 0xDC, 0x78, 0x13, 0x16, 0x00, 0x00, 0x40, 0x76, 0xDE, 0xC8, 0x8A, 0xA1, + 0xD2, 0xC7, 0x47, 0xC3, 0xDB, 0x8F, 0x59, 0xD5, 0xF8, 0xA8, 0xDE, 0x7E, 0x84, 0xF1, 0x11, 0x84, + 0x87, 0x1F, 0x1F, 0x3F, 0xD2, 0xB7, 0x1F, 0x2E, 0x3E, 0xDC, 0x4E, 0x7F, 0xEB, 0x42, 0x73, 0xB6, + 0xAD, 0x5B, 0x10, 0x11, 0x13, 0x69, 0xA7, 0x62, 0x22, 0xCB, 0xB6, 0xD9, 0x18, 0x1D, 0x5E, 0xD6, + 0x15, 0xB7, 0x20, 0x5D, 0x19, 0x1F, 0xC1, 0xBC, 0x13, 0x5F, 0xEE, 0xA9, 0xD7, 0x16, 0x03, 0x00, + 0x00, 0x74, 0x0D, 0x6F, 0xDF, 0x55, 0x63, 0x65, 0xBF, 0xF9, 0x70, 0xAB, 0xBF, 0xFD, 0x88, 0x04, + 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x70, 0x44, 0x02, 0xE4, 0x94, 0x7B, 0xE8, 0xDC, 0xED, 0xDB, 0xE2, + 0xF6, 0x23, 0x88, 0x8F, 0x70, 0x13, 0x0F, 0x64, 0xBD, 0x05, 0x11, 0x31, 0x91, 0x76, 0x2A, 0x24, + 0x32, 0xED, 0x82, 0xCA, 0xF6, 0x5C, 0xD6, 0xF1, 0x5B, 0x90, 0x6E, 0x8E, 0x0F, 0x37, 0xEF, 0xF8, + 0x9F, 0x75, 0xE5, 0xB3, 0x32, 0x00, 0x00, 0x00, 0x5D, 0xCF, 0xEC, 0xBD, 0xDC, 0x86, 0x40, 0x89, + 0xE3, 0x23, 0xC1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xC1, 0xB7, 0x5E, 0x9D, 0x0A, 0x03, 0xE4, 0x07, + 0xAD, 0xE3, 0xC3, 0xED, 0xF4, 0x3D, 0x2D, 0x6E, 0x41, 0xE4, 0x44, 0x4C, 0xA4, 0x9D, 0x0C, 0x89, + 0x2C, 0x0B, 0xE2, 0xC3, 0xCD, 0xFD, 0xFD, 0xF5, 0x6F, 0x41, 0x96, 0xAF, 0x0B, 0xFE, 0x31, 0x99, + 0x52, 0xDD, 0x1E, 0x1F, 0xFE, 0x8E, 0xFF, 0x29, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x48, 0xCB, 0xBD, + 0x72, 0xD5, 0xEC, 0x59, 0x64, 0x63, 0x40, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0xBA, 0xA0, + 0x48, 0x33, 0x11, 0x1A, 0x8D, 0x16, 0x0F, 0x90, 0xE0, 0xF6, 0xE3, 0x6C, 0x92, 0xDB, 0x8F, 0x87, + 0xED, 0xEE, 0x69, 0x1D, 0x1F, 0xE1, 0xC2, 0x5B, 0x90, 0x64, 0x6F, 0xC4, 0x12, 0x31, 0x91, 0x76, + 0x32, 0x24, 0xB2, 0x2C, 0x12, 0x1F, 0xE1, 0x86, 0x16, 0x1A, 0xEF, 0xE0, 0xD2, 0x93, 0xC1, 0x3F, + 0x2A, 0x53, 0xA6, 0x27, 0xE2, 0xC3, 0xED, 0xC8, 0x6A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0x90, 0x96, + 0xFF, 0x0A, 0xDE, 0x9D, 0x9F, 0xB2, 0x41, 0xA0, 0xA2, 0x22, 0xE9, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, + 0x8A, 0xA4, 0x13, 0x91, 0xA1, 0x66, 0x83, 0xA3, 0x1A, 0x1F, 0x36, 0x3C, 0x12, 0xDF, 0x7E, 0x44, + 0xBF, 0xF5, 0xEA, 0xFB, 0xB1, 0xDB, 0x0F, 0x11, 0x1D, 0xD1, 0x25, 0xBF, 0x05, 0x11, 0x31, 0x91, + 0x76, 0x32, 0x24, 0xB2, 0x4C, 0xC4, 0x87, 0x9B, 0xFB, 0x7B, 0x3D, 0xC5, 0xB7, 0x20, 0x3D, 0x13, + 0x1F, 0x3F, 0xBF, 0xDC, 0x98, 0xB1, 0x15, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x20, 0x2D, 0x73, 0x78, + 0xE5, 0x7A, 0xB3, 0xED, 0xA3, 0x36, 0x0A, 0x54, 0x58, 0x24, 0x99, 0x88, 0x8B, 0x56, 0xAB, 0x0B, + 0x8A, 0x34, 0x8B, 0x45, 0x46, 0xB3, 0x45, 0x03, 0xC4, 0xAE, 0x12, 0x1F, 0x36, 0x0E, 0xC2, 0x00, + 0x69, 0xF4, 0xDA, 0xDD, 0x46, 0xB7, 0x1F, 0x22, 0x38, 0xD4, 0x26, 0x7E, 0x50, 0x09, 0x90, 0x9A, + 0x67, 0x41, 0x82, 0x10, 0xA9, 0xDC, 0x82, 0x88, 0x98, 0x48, 0x3B, 0x19, 0x12, 0x59, 0x26, 0xC2, + 0x23, 0xBA, 0x29, 0xBC, 0x05, 0xE9, 0xA9, 0xF8, 0x70, 0x7B, 0xF1, 0x3A, 0x63, 0x7F, 0xBD, 0x77, + 0x05, 0xBF, 0x7C, 0x00, 0x00, 0x00, 0x24, 0xE1, 0x1D, 0x5E, 0xB9, 0x41, 0x87, 0x45, 0x92, 0x89, + 0xB8, 0x68, 0x35, 0x19, 0x15, 0x49, 0x17, 0x0B, 0x8C, 0x66, 0x8B, 0xC5, 0x47, 0xE5, 0xF6, 0x23, + 0x12, 0x1F, 0xCD, 0x6E, 0x3F, 0xC2, 0x00, 0x89, 0xDE, 0x7E, 0x88, 0xD0, 0x68, 0xB8, 0x6F, 0x5C, + 0x68, 0xCE, 0x3E, 0xD1, 0xE0, 0x16, 0x64, 0x93, 0x88, 0x89, 0xB4, 0x93, 0x21, 0x91, 0x65, 0x22, + 0x38, 0xE2, 0x73, 0x7F, 0xDF, 0x0F, 0x5E, 0x57, 0xF8, 0x2D, 0x48, 0xCF, 0xC5, 0x47, 0x30, 0xEF, + 0xC4, 0x9D, 0x1B, 0x82, 0xDF, 0x02, 0x00, 0x00, 0x00, 0x92, 0xF0, 0x0E, 0x5E, 0x3D, 0xAA, 0xE3, + 0xA2, 0xD5, 0x44, 0x5C, 0xB4, 0x5A, 0x5D, 0x50, 0xA4, 0x59, 0x2C, 0x30, 0x9A, 0xAD, 0x41, 0x7C, + 0xF8, 0xB7, 0x1F, 0x2E, 0x3E, 0xD4, 0xED, 0x47, 0x10, 0x1F, 0xD5, 0xDB, 0x8F, 0x87, 0xEC, 0xBE, + 0x91, 0x21, 0x3E, 0x82, 0x85, 0xB7, 0x20, 0xE7, 0x9F, 0x72, 0x7F, 0xDD, 0x20, 0x42, 0x9E, 0x9E, + 0x69, 0x7F, 0x2D, 0x2E, 0x20, 0x82, 0xA9, 0xB8, 0x68, 0x35, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, + 0xD1, 0x76, 0xCD, 0x31, 0xDE, 0xF0, 0xD2, 0x71, 0x33, 0xD4, 0x3F, 0x2B, 0xF8, 0xC7, 0x26, 0x57, + 0xBD, 0x1A, 0x1F, 0x7E, 0x80, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x74, 0xBC, 0xFD, 0x9F, 0x1D, + 0xD7, 0x81, 0xD1, 0x6C, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xC5, 0x02, 0xA3, 0xD5, 0xEA, + 0x02, 0x24, 0x88, 0x8F, 0xF8, 0xED, 0x47, 0x10, 0x1F, 0xF2, 0xD9, 0x8F, 0xFB, 0x83, 0xDB, 0x0F, + 0x11, 0x17, 0x89, 0x16, 0xBB, 0x05, 0x39, 0x1F, 0xC4, 0x47, 0x5B, 0x01, 0x22, 0x43, 0x22, 0xCB, + 0x44, 0x64, 0x34, 0x9B, 0x7B, 0x66, 0xC5, 0xDD, 0x82, 0x1C, 0x5C, 0x9A, 0xFB, 0x07, 0xEF, 0xF5, + 0x72, 0x7C, 0xB8, 0x79, 0xC7, 0xFE, 0x64, 0x3C, 0xF8, 0xAD, 0x00, 0x00, 0x00, 0xA0, 0x15, 0x33, + 0xDA, 0x3F, 0x2B, 0xFD, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x8B, 0xC5, 0x45, + 0x92, 0xC5, 0xE3, 0x23, 0x7A, 0xFB, 0x11, 0xC4, 0x47, 0xCD, 0x9B, 0xAF, 0x1A, 0xDD, 0x7E, 0xA8, + 0xB0, 0x48, 0xB1, 0x33, 0xDF, 0xBB, 0x70, 0xF2, 0x59, 0x90, 0xA7, 0x6C, 0x7C, 0xB4, 0x13, 0x21, + 0x32, 0x24, 0xB2, 0x4C, 0x04, 0x46, 0x92, 0x15, 0x70, 0x0B, 0xD2, 0xEB, 0xF1, 0xE1, 0xEF, 0xC8, + 0x4D, 0xC6, 0x8C, 0xFD, 0x87, 0x42, 0x6E, 0x86, 0x00, 0x00, 0x00, 0x4A, 0xC7, 0x7F, 0x03, 0xD6, + 0xAE, 0x4F, 0xDB, 0x48, 0x50, 0xA1, 0xA1, 0x26, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, + 0x8B, 0x56, 0xB3, 0xD1, 0x31, 0x19, 0x20, 0x17, 0x55, 0x02, 0x24, 0xB8, 0xFD, 0xA8, 0xBE, 0x76, + 0xB7, 0x7A, 0xFB, 0xF1, 0xBE, 0xC6, 0xB7, 0x1F, 0x22, 0x28, 0xB2, 0xEC, 0xEC, 0x63, 0x2E, 0x42, + 0x2A, 0x01, 0xE2, 0xDF, 0x82, 0x64, 0x89, 0x10, 0x19, 0x12, 0x59, 0x26, 0xC2, 0x22, 0xE9, 0x72, + 0xBE, 0x05, 0x29, 0x45, 0x7C, 0xB8, 0xBD, 0x34, 0xC0, 0x9B, 0xB0, 0x00, 0x00, 0x00, 0x92, 0x32, + 0x87, 0x57, 0xAD, 0x4B, 0xFE, 0x0A, 0x5E, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x61, + 0x91, 0x74, 0xF1, 0xF8, 0xC8, 0x74, 0xFB, 0xA1, 0x63, 0x22, 0xFD, 0x66, 0x9A, 0x33, 0xF7, 0xCF, + 0x34, 0x67, 0x9F, 0x9C, 0x8C, 0x90, 0xD4, 0x01, 0x22, 0x43, 0x22, 0xCB, 0x44, 0x54, 0xA4, 0xDD, + 0xCE, 0xD9, 0xC6, 0x1B, 0xBE, 0xBE, 0xED, 0x5B, 0x90, 0xD2, 0xC4, 0x87, 0x1B, 0x6F, 0xC2, 0x02, + 0x00, 0x00, 0x48, 0xCE, 0xB8, 0x57, 0xF0, 0xCA, 0xD8, 0x88, 0x4F, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, + 0x48, 0x3A, 0x11, 0x16, 0x49, 0xE6, 0x6E, 0x3F, 0xEC, 0x8F, 0x7E, 0x7C, 0xC4, 0x6E, 0x3F, 0xEA, + 0x9F, 0xFD, 0x68, 0x70, 0xFB, 0x71, 0x5F, 0xFB, 0xDF, 0x7A, 0x55, 0xD9, 0xCC, 0xEA, 0xDE, 0x0D, + 0x6E, 0x41, 0xCE, 0x35, 0xBA, 0x05, 0x51, 0xE1, 0xE1, 0x26, 0x43, 0x22, 0xCB, 0x44, 0x4C, 0x64, + 0xDA, 0x7B, 0x8D, 0x39, 0x70, 0xB5, 0x7B, 0x2D, 0xEF, 0x60, 0xF0, 0x8F, 0x50, 0x6A, 0xA5, 0x8A, + 0x0F, 0xB7, 0xE7, 0xAF, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x49, 0x79, 0x07, 0xAF, 0x4B, 0xF0, + 0x06, 0x2C, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x51, 0x91, 0x66, 0xE1, 0xCD, 0x47, + 0x83, 0xDB, 0x8F, 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0x78, 0x30, 0xAF, 0x6F, 0xBD, 0x9A, 0x8C, 0x0F, + 0xB7, 0x4C, 0xB7, 0x20, 0x32, 0x24, 0xB2, 0x4C, 0x85, 0x44, 0x96, 0xD9, 0xF8, 0x70, 0xDB, 0xFE, + 0x71, 0xF7, 0x6D, 0x58, 0xC6, 0x8C, 0x5C, 0x9B, 0xFA, 0x13, 0xC0, 0x4B, 0x17, 0x1F, 0xC1, 0xBC, + 0x13, 0x77, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x24, 0xBC, 0x7D, 0x57, 0x8E, 0xE9, 0xE8, 0x08, + 0x27, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, 0x8A, 0xA4, 0xF3, 0x6F, 0x3F, 0x82, 0xF8, + 0x88, 0xDD, 0x7E, 0xA8, 0x67, 0x3F, 0xEA, 0x3F, 0x74, 0xD0, 0xC6, 0x47, 0x2E, 0xB7, 0x1F, 0xB5, + 0xF1, 0x11, 0xEE, 0xDD, 0x47, 0x5A, 0x3C, 0x0B, 0xD2, 0x0B, 0xF1, 0xF1, 0x74, 0xB0, 0xFD, 0xE9, + 0x6F, 0x41, 0xCA, 0x1A, 0x1F, 0x6E, 0xDE, 0xB1, 0x5B, 0xA6, 0xE4, 0x83, 0x1A, 0x01, 0x00, 0x00, + 0x7A, 0x9E, 0xD9, 0x7B, 0x99, 0x8D, 0x06, 0x15, 0x1E, 0x6E, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, + 0xD2, 0xC5, 0x82, 0x22, 0xED, 0xC2, 0xF0, 0x68, 0x70, 0xFB, 0x51, 0xF7, 0xEC, 0x47, 0x10, 0x20, + 0x95, 0xDB, 0x0F, 0x1B, 0x1F, 0xB9, 0xDC, 0x7E, 0xE8, 0xF8, 0x70, 0x3B, 0x7D, 0xEF, 0x4C, 0x73, + 0xAE, 0xD1, 0x2D, 0x88, 0x1F, 0x1D, 0x3D, 0x12, 0x1F, 0xF6, 0xFF, 0xF6, 0xB6, 0x7F, 0xDC, 0x05, + 0x48, 0xE2, 0x5B, 0x90, 0x32, 0xC7, 0x87, 0xBF, 0x23, 0x37, 0x99, 0xE0, 0xB7, 0x0A, 0x00, 0x00, + 0x80, 0x46, 0xCC, 0xE1, 0xFE, 0x25, 0x66, 0x68, 0xBE, 0x0D, 0x87, 0x72, 0xC4, 0x47, 0xCB, 0xDB, + 0x0F, 0x11, 0x1F, 0x95, 0xDB, 0x0F, 0x1B, 0x1E, 0xB9, 0xDC, 0x7E, 0xE8, 0xF0, 0x88, 0x2E, 0xBC, + 0x05, 0x69, 0xF8, 0x2C, 0x88, 0x0C, 0x89, 0x2C, 0x53, 0x21, 0x91, 0x65, 0x22, 0x3E, 0xEC, 0x8F, + 0xFE, 0xF6, 0x7C, 0xC6, 0x9C, 0x3F, 0x70, 0xFD, 0x50, 0xF0, 0x8F, 0x53, 0x43, 0xA5, 0x8F, 0x0F, + 0x37, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x9A, 0xFF, 0x0A, 0x5E, 0xF9, 0x06, 0x2C, 0x11, 0x17, + 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x50, 0xA4, 0x9A, 0x8D, 0x8F, 0x30, 0x3C, 0xC2, 0xF8, 0x48, + 0x7A, 0xFB, 0xF1, 0x63, 0x1B, 0x1E, 0x2E, 0x40, 0x7E, 0xD8, 0xEE, 0xED, 0x87, 0x0E, 0x8E, 0xF8, + 0xDC, 0x2D, 0x48, 0xE3, 0x67, 0x41, 0x54, 0x48, 0x64, 0x99, 0x0A, 0x89, 0x2C, 0x6B, 0x12, 0x1F, + 0x4F, 0xBD, 0xD7, 0x9C, 0xDF, 0xF2, 0x21, 0x73, 0x7E, 0xFF, 0x32, 0x73, 0x76, 0xFF, 0xD2, 0x86, + 0x07, 0xEF, 0x69, 0x11, 0x1F, 0x6E, 0x2F, 0x5E, 0xE7, 0x02, 0x64, 0x5D, 0xF0, 0xDB, 0x06, 0x00, + 0x00, 0x80, 0xE2, 0xBF, 0x01, 0x6B, 0xEB, 0x87, 0x6C, 0x40, 0xF4, 0x7E, 0x7C, 0x64, 0xB9, 0xFD, + 0xA8, 0xC6, 0x87, 0xBB, 0xFD, 0xF8, 0x56, 0x3B, 0xB7, 0x1F, 0x3A, 0x36, 0x1A, 0x6D, 0xE2, 0x21, + 0x75, 0x0B, 0x32, 0xC3, 0x9F, 0x0E, 0x8A, 0x34, 0x53, 0x21, 0x91, 0x65, 0x2D, 0xE2, 0xC3, 0x6D, + 0xE3, 0x05, 0xE6, 0xFC, 0xEE, 0x25, 0xE6, 0xDC, 0xDE, 0x65, 0xF2, 0x01, 0xEC, 0x69, 0x13, 0x1F, + 0x6E, 0xCF, 0x5F, 0x69, 0xCC, 0x89, 0x3B, 0x73, 0xFF, 0x94, 0x78, 0x00, 0x00, 0x80, 0x52, 0xF1, + 0x0E, 0xAD, 0x1C, 0xEC, 0xF9, 0xF8, 0xC8, 0x78, 0xFB, 0x71, 0xEA, 0x51, 0x1B, 0x1D, 0xB9, 0xDC, + 0x7E, 0xE8, 0xC8, 0x68, 0xB6, 0xD3, 0xF7, 0xC4, 0x6F, 0x41, 0x2A, 0xF1, 0xD1, 0x7E, 0x80, 0xA8, + 0x90, 0xC8, 0xB2, 0x64, 0xF1, 0x71, 0xEE, 0x49, 0xBB, 0x4D, 0x1F, 0x76, 0x01, 0x62, 0xCE, 0x0E, + 0xD5, 0xDE, 0x82, 0x4C, 0xAB, 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x6F, 0xC2, 0x02, 0x00, 0x00, + 0x68, 0xC6, 0xDB, 0x77, 0x45, 0xE4, 0x15, 0xBC, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xA9, + 0xA0, 0x48, 0xB3, 0x20, 0x3E, 0x82, 0xA5, 0xBB, 0xFD, 0x88, 0xC4, 0x47, 0x5B, 0xB7, 0x1F, 0x3A, + 0x30, 0x92, 0x6C, 0xE2, 0x81, 0xE8, 0x2D, 0x88, 0x8D, 0x8F, 0xB6, 0x23, 0x44, 0x85, 0x44, 0x96, + 0x25, 0x8F, 0x8F, 0xB3, 0x83, 0x76, 0x4F, 0x5C, 0x60, 0xDE, 0xDD, 0xB1, 0xC4, 0x4C, 0xEC, 0x5E, + 0x5E, 0x3D, 0x7C, 0x4F, 0xC7, 0xF8, 0x70, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x2D, 0x98, 0x7D, + 0xF6, 0x70, 0xD7, 0xEB, 0xF1, 0x91, 0xE6, 0xF6, 0x23, 0x8C, 0x8F, 0x5C, 0x6E, 0x3F, 0x74, 0x58, + 0x24, 0x5D, 0xE5, 0x16, 0x64, 0xA6, 0x8D, 0x10, 0x1B, 0x20, 0x4F, 0xB5, 0x1B, 0x20, 0x2A, 0x24, + 0xB2, 0x2C, 0x43, 0x7C, 0x3C, 0x7E, 0x81, 0x39, 0x33, 0xF8, 0x41, 0x17, 0x20, 0xE6, 0xF4, 0x8E, + 0xA5, 0x03, 0xD3, 0x35, 0x3E, 0xFC, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x00, 0x34, 0x62, + 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x0B, 0x75, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, + 0x66, 0x91, 0xF8, 0x08, 0xA6, 0x6E, 0x3F, 0xAA, 0x01, 0x52, 0x73, 0xFB, 0x31, 0xAB, 0xFE, 0xF6, + 0xE3, 0x9B, 0x2A, 0x2E, 0x5A, 0x4D, 0x47, 0x45, 0x9A, 0xBD, 0xF3, 0xD7, 0x33, 0xCC, 0x99, 0x1F, + 0x4E, 0x06, 0x48, 0xF6, 0x5B, 0x10, 0x15, 0x12, 0x59, 0x96, 0x31, 0x3E, 0x1E, 0x9D, 0x61, 0x4E, + 0xFF, 0xD8, 0xEE, 0x99, 0x45, 0x66, 0xE2, 0xC0, 0xAA, 0x93, 0xD3, 0x36, 0x3E, 0xDC, 0x8E, 0xAC, + 0x32, 0xE6, 0xF8, 0x1D, 0x4B, 0x82, 0x2F, 0x31, 0x00, 0x00, 0x00, 0x44, 0x99, 0x91, 0xFE, 0x01, + 0xB3, 0xF3, 0x12, 0x1D, 0x18, 0xCD, 0x26, 0xA3, 0x22, 0xE9, 0x54, 0x50, 0xA4, 0x59, 0x2C, 0x3E, + 0x12, 0xDC, 0x7E, 0x4C, 0xB8, 0x00, 0x79, 0xDC, 0xDD, 0x7E, 0xC4, 0xE2, 0xC3, 0xED, 0x7B, 0x59, + 0xBE, 0xF5, 0x4A, 0x07, 0x45, 0x9A, 0xB9, 0xF8, 0xF0, 0x77, 0xF7, 0x0C, 0x7B, 0x90, 0x6F, 0xE7, + 0x16, 0x44, 0x85, 0x44, 0x96, 0xB5, 0x17, 0x1F, 0xA7, 0x1E, 0x76, 0x01, 0x32, 0xDB, 0x98, 0x63, + 0x77, 0x9A, 0x69, 0x1B, 0x1F, 0x3F, 0xBF, 0xCC, 0x98, 0x17, 0x3F, 0x67, 0xCC, 0x89, 0x2F, 0xAD, + 0x0D, 0xBE, 0xC4, 0x00, 0x00, 0x00, 0x10, 0xE5, 0x1D, 0x5A, 0x75, 0x97, 0xD9, 0x7E, 0xB1, 0x8E, + 0x8C, 0x46, 0x93, 0x51, 0x91, 0x74, 0x2A, 0x28, 0xD2, 0x2C, 0x16, 0x1F, 0x2A, 0x40, 0x1A, 0x3E, + 0xFB, 0x61, 0xE3, 0x23, 0x97, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0x56, 0x8D, 0x8F, 0x60, 0x67, 0xBE, + 0x5F, 0x09, 0x90, 0x73, 0xD1, 0x5B, 0x90, 0x20, 0x44, 0x74, 0x74, 0x84, 0x53, 0x21, 0x91, 0x65, + 0x39, 0xC4, 0xC7, 0xD3, 0x1F, 0x33, 0xDE, 0xD1, 0xDB, 0xA7, 0x77, 0x7C, 0xB8, 0x3D, 0xFF, 0x59, + 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x88, 0x19, 0x59, 0xB9, 0x5E, 0x46, 0x46, 0xA3, 0xC9, 0xA8, + 0x48, 0x3A, 0x15, 0x14, 0x69, 0x56, 0x1F, 0x1E, 0xD5, 0xF8, 0xB0, 0xE1, 0x31, 0x79, 0xFB, 0x11, + 0xF9, 0xD6, 0xAB, 0xEA, 0xED, 0xC7, 0x45, 0x95, 0xDB, 0x0F, 0xBB, 0xF6, 0x6E, 0x3F, 0x74, 0x50, + 0xA4, 0x59, 0x3C, 0x3E, 0xFC, 0x65, 0xBA, 0x05, 0x51, 0x21, 0x91, 0x65, 0xC4, 0x47, 0xFB, 0x0B, + 0xE2, 0x23, 0x98, 0xF7, 0x8B, 0x3B, 0x5B, 0x7E, 0x30, 0x23, 0x00, 0x00, 0xC0, 0xB4, 0xE4, 0x1D, + 0xB8, 0x7A, 0x54, 0x86, 0x86, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, 0x66, 0xB1, 0xF8, 0x88, + 0x07, 0x88, 0x5D, 0xF5, 0x5B, 0xAF, 0xC2, 0x00, 0xA9, 0x3E, 0x78, 0x6E, 0xE3, 0xC3, 0x06, 0x48, + 0xFB, 0xB7, 0x1F, 0x3A, 0x28, 0xD2, 0x4C, 0xC6, 0x47, 0xB0, 0xF0, 0x16, 0xC4, 0xBD, 0x92, 0xB7, + 0xF5, 0x2D, 0x88, 0x0A, 0x89, 0x2C, 0x23, 0x3E, 0xDA, 0x5F, 0x6D, 0x7C, 0xF8, 0x01, 0x72, 0xF4, + 0xD6, 0xB1, 0xE0, 0x4B, 0x0C, 0x00, 0x00, 0x00, 0x51, 0xDE, 0xFE, 0x2B, 0x4F, 0xCA, 0xD8, 0x88, + 0x4F, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x78, 0x88, 0xF8, 0x08, 0x6F, 0x3F, 0x6A, + 0x1E, 0x3C, 0xF7, 0x6F, 0x3F, 0x2E, 0x9A, 0xBC, 0xFD, 0x08, 0xE3, 0x23, 0x0C, 0x90, 0xFB, 0xD3, + 0xDC, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x1D, 0x35, 0x73, 0xB7, 0x20, 0x8F, 0x4D, 0xDE, 0x82, + 0xF8, 0x11, 0x62, 0x63, 0xA3, 0x3E, 0x40, 0x54, 0x48, 0x64, 0x19, 0xF1, 0xD1, 0xFE, 0xEA, 0xE3, + 0xC3, 0xDF, 0xB1, 0x2F, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x00, 0x25, 0xD1, 0x1B, 0xB0, 0x64, 0x54, + 0x24, 0x9D, 0x0A, 0x8A, 0x34, 0x8B, 0x85, 0x47, 0x93, 0xF8, 0xA8, 0x3E, 0x78, 0x5E, 0xBD, 0xFD, + 0xB0, 0xF1, 0x11, 0xDE, 0x7E, 0xC4, 0xE3, 0xE3, 0x21, 0xBB, 0xBB, 0x55, 0x68, 0xA8, 0xE9, 0xA0, + 0x48, 0x33, 0x19, 0x1C, 0x62, 0xA7, 0xBF, 0x3B, 0x23, 0x78, 0x16, 0xA4, 0xC1, 0xB7, 0x62, 0x3D, + 0xAD, 0x42, 0x22, 0xCB, 0x88, 0x8F, 0xF6, 0x27, 0xC2, 0x23, 0x1C, 0x6F, 0xC2, 0x02, 0x00, 0x00, + 0xA8, 0xE7, 0xBF, 0x01, 0x6B, 0xD7, 0x1C, 0x1D, 0x1D, 0xE1, 0x64, 0x54, 0x24, 0x9D, 0x0A, 0x8A, + 0x34, 0x8B, 0x85, 0x47, 0x38, 0x15, 0x20, 0xF1, 0xD7, 0xEE, 0x3E, 0x39, 0x19, 0x1F, 0xF2, 0xCD, + 0x57, 0x89, 0x6F, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0A, 0x8D, 0x66, 0x7B, 0x37, 0x7E, 0x0B, 0x12, + 0x46, 0x88, 0x8B, 0x8F, 0x70, 0x32, 0x2A, 0x92, 0x8E, 0xF8, 0x68, 0x7F, 0x22, 0x3A, 0xA2, 0x7B, + 0xF1, 0x7A, 0x63, 0x5E, 0xBE, 0xB3, 0xE6, 0x53, 0xE1, 0x01, 0x00, 0x00, 0xA6, 0x3D, 0x73, 0xA8, + 0x7F, 0xAD, 0xD9, 0xF1, 0x49, 0x1D, 0x1E, 0x6E, 0x32, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, 0xC5, + 0xA2, 0x23, 0xBA, 0x78, 0x7C, 0x44, 0x6F, 0x3F, 0x82, 0xF8, 0x98, 0xBC, 0xFD, 0x10, 0xDF, 0x7A, + 0x95, 0xF8, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xA9, 0xC0, 0x68, 0x35, 0x77, 0x0B, 0x52, 0xF7, 0xE1, + 0x84, 0x36, 0x3A, 0xF2, 0x09, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xE0, 0x88, 0xEF, 0x85, 0xAB, 0x79, + 0x13, 0x16, 0x00, 0x00, 0x40, 0x9C, 0xFF, 0x06, 0xAC, 0xAD, 0x1F, 0xEC, 0xB9, 0xF8, 0x68, 0x74, + 0xFB, 0xE1, 0xE2, 0xE3, 0x6C, 0x2C, 0x3E, 0xB2, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x17, + 0x49, 0xF7, 0xEE, 0x8F, 0x2B, 0x01, 0xE2, 0xBF, 0x96, 0xF7, 0x29, 0x1B, 0x1F, 0x6E, 0xD1, 0x08, + 0x91, 0x71, 0xD1, 0x6A, 0xC4, 0x47, 0xFB, 0x13, 0xB1, 0xD1, 0x60, 0xDE, 0x89, 0x2F, 0x0D, 0x06, + 0x5F, 0x6A, 0x00, 0x00, 0x00, 0x70, 0xBC, 0xE1, 0xE5, 0x43, 0x3D, 0x15, 0x1F, 0x6E, 0xF1, 0xF8, + 0x88, 0xDE, 0x7E, 0xB8, 0xF8, 0x68, 0x75, 0xFB, 0xF1, 0xA0, 0x9D, 0x0C, 0x8E, 0xE8, 0x74, 0x50, + 0xA4, 0x99, 0x8A, 0x8A, 0x34, 0x3B, 0xFD, 0xED, 0xE0, 0x16, 0xE4, 0x49, 0x1B, 0x20, 0x36, 0x0A, + 0xEA, 0x02, 0x24, 0x75, 0x84, 0x10, 0x1F, 0xED, 0x4F, 0x87, 0x46, 0xA3, 0x79, 0x47, 0x6F, 0x1D, + 0x0D, 0xBE, 0xD4, 0x00, 0x00, 0x00, 0xE0, 0x78, 0x7B, 0xAF, 0xA8, 0x7F, 0x05, 0xAF, 0x8C, 0x8A, + 0xA4, 0x53, 0x41, 0x91, 0x66, 0x22, 0x38, 0xA2, 0xB3, 0xD1, 0xE1, 0x7E, 0xAC, 0xBB, 0xFD, 0xB0, + 0xF1, 0x71, 0x6E, 0xE3, 0x45, 0xC9, 0x6E, 0x3F, 0xEE, 0x6B, 0x75, 0xFB, 0xA1, 0x83, 0x22, 0xCD, + 0x54, 0x50, 0x64, 0xD9, 0xBB, 0xF6, 0xD0, 0x1F, 0x06, 0x48, 0x7B, 0xB7, 0x20, 0xC4, 0x47, 0xFB, + 0xD3, 0x91, 0xD1, 0x74, 0xC7, 0x6E, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x51, 0x66, 0xEF, 0xE2, + 0xDE, 0x89, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x08, 0x03, 0x24, 0x88, 0x8F, 0x78, 0x80, 0xD4, + 0xC5, 0x47, 0xCB, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0xA6, 0x42, 0x22, 0xDB, 0x2E, 0x30, 0xA7, 0xBF, + 0x6D, 0xA3, 0x60, 0x70, 0x32, 0x42, 0x6A, 0x02, 0xC4, 0x85, 0x45, 0xA2, 0x08, 0x21, 0x3E, 0xDA, + 0x9F, 0x88, 0x8B, 0x24, 0x73, 0x6F, 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x1B, 0x00, 0x00, + 0xC0, 0xF4, 0x66, 0x46, 0xFA, 0x67, 0xD7, 0xBC, 0x82, 0x57, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, + 0x33, 0x11, 0x1B, 0xF1, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, 0xDF, 0x7E, 0xD8, 0xF0, 0x10, 0xB7, 0x1F, + 0xF2, 0x43, 0x07, 0x9B, 0xDE, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x76, 0x41, 0x75, + 0xE1, 0x2D, 0xC8, 0xB9, 0x4C, 0xB7, 0x20, 0xC4, 0x47, 0xFB, 0x13, 0x61, 0x91, 0x74, 0x63, 0xCB, + 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xC8, 0x7F, 0x05, 0x6F, 0xF8, 0x06, 0x2C, 0x19, 0x15, 0x49, + 0xA7, 0x82, 0x22, 0xCD, 0x62, 0xA1, 0xD1, 0x68, 0x61, 0x78, 0x84, 0xF1, 0xE1, 0xF6, 0xD4, 0x85, + 0x35, 0xDF, 0x7A, 0x15, 0x0F, 0x90, 0x53, 0x2E, 0x40, 0xC2, 0xDB, 0x8F, 0x1F, 0xD9, 0xC9, 0xF0, + 0x70, 0xD3, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x6C, 0x32, 0x3E, 0xDC, 0x4E, 0x7D, 0xD3, 0xC5, + 0x41, 0x96, 0x5B, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xA8, 0x48, 0xB3, 0x17, 0x3F, 0xC7, 0x9B, 0xB0, + 0x00, 0x00, 0x00, 0x42, 0xFE, 0x1B, 0xB0, 0xB6, 0x7D, 0xC4, 0x1E, 0xEE, 0x55, 0x54, 0x24, 0x9D, + 0x0A, 0x8A, 0x34, 0x13, 0xA1, 0xA1, 0x66, 0xA3, 0xC3, 0xFD, 0x58, 0x7B, 0xFB, 0x61, 0xE3, 0x23, + 0xCD, 0xED, 0xC7, 0xB7, 0x1A, 0xDD, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x56, 0x1B, + 0x1F, 0xE1, 0x26, 0x7E, 0x94, 0xF6, 0x16, 0x84, 0xF8, 0x68, 0x7F, 0x22, 0x28, 0x32, 0x8C, 0x37, + 0x61, 0x01, 0x00, 0x00, 0x04, 0xBC, 0x91, 0x81, 0x0D, 0x3A, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, + 0xC5, 0x22, 0xA3, 0xD9, 0xC2, 0xF0, 0x88, 0xC4, 0x47, 0xA2, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x68, + 0xD7, 0xA3, 0xF1, 0xE1, 0xD6, 0xF2, 0x16, 0x84, 0xF8, 0xC8, 0x79, 0x3A, 0x26, 0xB2, 0xCC, 0x3B, + 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0x38, 0xDE, 0x81, 0xAB, 0x47, 0x75, 0x58, 0x24, 0x99, + 0x0A, 0x8A, 0x34, 0x13, 0x91, 0xD1, 0x62, 0xD5, 0x00, 0x09, 0xE3, 0xA3, 0xED, 0xDB, 0x0F, 0x1D, + 0x14, 0x69, 0xA6, 0x43, 0x22, 0xCB, 0x74, 0x78, 0x44, 0x17, 0xDE, 0x82, 0xB8, 0x78, 0x68, 0x7C, + 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x12, 0x59, 0xE7, 0x1D, 0xBB, 0x65, 0x3C, 0xF8, 0x92, 0x03, + 0x00, 0x00, 0x98, 0xDE, 0xBC, 0x7D, 0x57, 0x8C, 0xEB, 0xB8, 0x68, 0x35, 0x15, 0x14, 0x69, 0xA6, + 0x03, 0xA3, 0xE1, 0x6A, 0x6E, 0x3F, 0x6C, 0x7C, 0x34, 0xBB, 0xFD, 0x08, 0xE3, 0xA3, 0xE5, 0xED, + 0x87, 0x0E, 0x8A, 0x34, 0xD3, 0x21, 0x91, 0x65, 0x3A, 0x38, 0xE2, 0xF3, 0x6F, 0x41, 0x1E, 0x6F, + 0x76, 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x11, 0x6D, 0xCD, 0xBD, 0x09, 0x6B, 0xEC, 0x8B, 0xB3, + 0x82, 0x2F, 0x3B, 0x00, 0x00, 0x80, 0xE9, 0xCB, 0x0C, 0x2D, 0xB0, 0x07, 0x7C, 0x15, 0x18, 0xCD, + 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x60, 0x24, 0x58, 0x18, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xB9, 0x1F, + 0xC9, 0x6E, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0E, 0x89, 0x2C, 0xD3, 0xB1, 0xD1, 0x68, 0x67, 0xBE, + 0x2F, 0x9E, 0x05, 0xF1, 0x43, 0x24, 0x12, 0x1E, 0x6E, 0xC4, 0x47, 0x86, 0x89, 0x78, 0xC8, 0x63, + 0x63, 0xCB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x80, 0xFF, 0x06, 0xAC, 0x9D, 0xB3, 0xED, 0xE1, 0x5E, + 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0x33, 0x1D, 0x17, 0x4D, 0x17, 0xB9, 0xF9, 0xF0, 0xE3, 0x43, + 0xDC, 0x7E, 0x4C, 0xB8, 0x3D, 0x1E, 0xB9, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xE5, 0x89, 0x0F, + 0x7F, 0x77, 0xAB, 0x5B, 0x90, 0x4A, 0x68, 0x18, 0x1B, 0x19, 0xC4, 0x47, 0xD6, 0x89, 0x70, 0xC8, + 0x65, 0x8B, 0x8D, 0x79, 0xF1, 0x5A, 0xE3, 0xFD, 0xE2, 0x4B, 0x77, 0x05, 0x5F, 0x7A, 0x00, 0x00, + 0x00, 0xD3, 0x93, 0x0D, 0x90, 0x75, 0x66, 0xC7, 0x27, 0xEC, 0x21, 0x5F, 0x85, 0x86, 0x9A, 0x0A, + 0x8A, 0x34, 0x13, 0x71, 0x91, 0x64, 0x61, 0x7C, 0xC4, 0x6E, 0x3F, 0x12, 0x3F, 0xFB, 0xF1, 0xCD, + 0x12, 0xC5, 0x47, 0xB0, 0x33, 0xDF, 0x8B, 0x3E, 0x0B, 0x52, 0x89, 0x8C, 0x70, 0x2E, 0x40, 0xC2, + 0xF0, 0x20, 0x3E, 0x92, 0x4E, 0x85, 0x43, 0x1E, 0xB3, 0xF1, 0xE1, 0x66, 0x7F, 0xED, 0xDE, 0x89, + 0x3B, 0x36, 0x04, 0x5F, 0x7A, 0x00, 0x00, 0x00, 0xD3, 0x93, 0xFF, 0x0A, 0x5E, 0x19, 0x1A, 0x6A, + 0x2A, 0x28, 0xD2, 0x4C, 0x84, 0x45, 0xAB, 0xD9, 0xF0, 0xA8, 0xC6, 0x87, 0x0D, 0x8F, 0xC9, 0xDB, + 0x8F, 0xD8, 0xB7, 0x5E, 0x45, 0x6F, 0x3F, 0xEC, 0x1A, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, + 0x12, 0x59, 0xA6, 0xC3, 0x22, 0xF1, 0xAA, 0xB7, 0x20, 0x36, 0x40, 0x36, 0xBA, 0xC0, 0x08, 0x82, + 0x23, 0x12, 0x1E, 0xC4, 0x47, 0xD2, 0xA9, 0x70, 0xC8, 0x63, 0x41, 0x7C, 0x04, 0xF3, 0x4E, 0xFC, + 0x39, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x9B, 0x77, 0xF0, 0xBA, 0x84, 0x6F, 0xC0, 0x52, 0x41, + 0x91, 0x66, 0xB1, 0xB0, 0x48, 0x3A, 0x17, 0x20, 0xE1, 0xCD, 0x87, 0x5D, 0xF5, 0x5B, 0xAF, 0xE4, + 0xB3, 0x1F, 0x17, 0xB5, 0xB8, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x04, 0x45, + 0x86, 0x9D, 0xFE, 0xCE, 0x7B, 0xFD, 0xB0, 0x08, 0x23, 0xA4, 0x1A, 0x1C, 0x2E, 0x3E, 0x82, 0x28, + 0x21, 0x3E, 0x5A, 0x4D, 0x85, 0x43, 0x1E, 0xAB, 0x8D, 0x0F, 0x3F, 0x40, 0x8E, 0x7D, 0x81, 0x37, + 0x61, 0x01, 0x00, 0x80, 0xE9, 0xCD, 0xDB, 0xFB, 0xD9, 0x31, 0x1D, 0x1C, 0xD1, 0xA9, 0xA0, 0x48, + 0xB3, 0x58, 0x54, 0x24, 0x5D, 0x2C, 0x3E, 0xC2, 0xDB, 0x8F, 0xBA, 0xF8, 0x88, 0xDE, 0x7E, 0x84, + 0xF1, 0x11, 0x06, 0xC8, 0x86, 0xF0, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xE9, 0x90, 0xC8, 0x32, 0x1D, + 0x13, 0xA9, 0xF7, 0x57, 0xEF, 0xF5, 0xF7, 0xEE, 0xA3, 0x93, 0x01, 0x12, 0x9F, 0x1F, 0x27, 0x2E, + 0x3C, 0x88, 0x8F, 0x06, 0x53, 0xE1, 0x90, 0xC7, 0xEA, 0xE3, 0xC3, 0xDF, 0x91, 0x1B, 0x4C, 0xF0, + 0xA5, 0x07, 0x00, 0x00, 0x30, 0x3D, 0x99, 0x3D, 0xF6, 0x50, 0x24, 0xA3, 0x23, 0x9C, 0x0A, 0x8A, + 0x34, 0x8B, 0x45, 0x45, 0xD2, 0x35, 0x88, 0x8F, 0xEA, 0x83, 0xE7, 0xEA, 0xF6, 0x23, 0x1E, 0x1F, + 0x0F, 0xD9, 0xDD, 0x5D, 0xEE, 0xF8, 0x70, 0x73, 0xB7, 0x20, 0x7E, 0x60, 0xD8, 0x9D, 0x7B, 0xD2, + 0x86, 0x87, 0xDD, 0xB9, 0x68, 0x7C, 0xD8, 0xF0, 0x38, 0x6B, 0xC3, 0x83, 0xF8, 0x88, 0x4F, 0x85, + 0x43, 0x1E, 0x8B, 0x45, 0x47, 0x74, 0x2F, 0xAD, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xFA, 0x32, + 0x87, 0xFB, 0x97, 0x98, 0xDD, 0xF3, 0xEC, 0x81, 0x5F, 0x85, 0x87, 0x9B, 0x0A, 0x8A, 0x34, 0x8B, + 0x45, 0x45, 0x9A, 0xD9, 0xE8, 0xA8, 0x0B, 0x90, 0x26, 0xDF, 0x7A, 0x25, 0xDF, 0x7C, 0x75, 0xBF, + 0xBB, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x45, 0xE2, 0x23, + 0x9C, 0xBB, 0x05, 0xF1, 0x43, 0x63, 0xD0, 0xC6, 0x88, 0x0D, 0x90, 0xB3, 0xB1, 0x6F, 0xB9, 0x7A, + 0xF7, 0x31, 0xE2, 0xA3, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x88, 0x8E, 0xE8, 0x5E, 0xBC, 0xD6, 0x06, + 0xC8, 0x1D, 0xEB, 0x82, 0x2F, 0x41, 0x00, 0x00, 0x80, 0xE9, 0xC5, 0x7F, 0x05, 0x6F, 0xC3, 0x37, + 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x15, 0x49, 0xF7, 0x8C, 0x88, 0x8F, 0xE8, 0xED, 0x87, 0x8B, + 0x8F, 0x9A, 0x00, 0x11, 0xDF, 0x7A, 0xE5, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, + 0x26, 0x42, 0x22, 0xCB, 0x44, 0x7C, 0xBC, 0xBD, 0xFE, 0xBD, 0xE6, 0xD4, 0x3D, 0x36, 0x42, 0x5C, + 0x68, 0xB8, 0xE0, 0x70, 0x21, 0x12, 0xFC, 0xE8, 0xFE, 0xB5, 0x09, 0x17, 0x1F, 0x36, 0x3C, 0x4E, + 0x3F, 0x42, 0x7C, 0x54, 0xA6, 0xC2, 0x21, 0x8F, 0x89, 0xE0, 0x88, 0xCF, 0xFD, 0xBE, 0x4E, 0xDC, + 0xB1, 0x3E, 0xF8, 0x12, 0x04, 0x00, 0x00, 0x98, 0x5E, 0xFC, 0x37, 0x60, 0x6D, 0xF9, 0x80, 0x3D, + 0xF4, 0x77, 0x5F, 0x7C, 0x34, 0xBA, 0xFD, 0x50, 0xAF, 0xDD, 0xD5, 0xB7, 0x1F, 0xED, 0x7F, 0xEB, + 0x95, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0x0D, 0xE2, 0x23, 0xDC, 0x99, 0x07, 0x6D, 0x6C, + 0x3C, 0x3E, 0xA3, 0x12, 0x22, 0x41, 0x78, 0x4C, 0x3C, 0x7A, 0x81, 0x7F, 0xEB, 0x41, 0x7C, 0x84, + 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x6C, 0x34, 0x98, 0x77, 0xE2, 0x0E, 0xDE, 0x84, 0x05, 0x00, 0x00, + 0xA6, 0x27, 0xEF, 0xD0, 0xCA, 0xC1, 0xAE, 0x8B, 0x8F, 0x5C, 0x6E, 0x3F, 0x2E, 0x6A, 0xFB, 0xF6, + 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0xD6, 0xD7, 0xEC, 0xBF, 0xF6, + 0x4D, 0x17, 0x1D, 0x33, 0xFC, 0x9D, 0xB1, 0xE1, 0xE1, 0xE6, 0x7F, 0xCB, 0x55, 0x18, 0x1F, 0x4F, + 0x11, 0x1F, 0xC5, 0x4C, 0x87, 0x46, 0xA3, 0x79, 0xC7, 0xBE, 0x70, 0x32, 0xF8, 0x12, 0x04, 0x00, + 0x00, 0x98, 0x5E, 0xBC, 0xBD, 0x57, 0xC4, 0x5E, 0xC1, 0xAB, 0x82, 0x22, 0xCD, 0x44, 0x54, 0x24, + 0x5D, 0x24, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0xA3, 0xFE, 0xD9, 0x0F, 0x75, 0xFB, 0x61, 0xE3, 0xE3, + 0xBE, 0xF6, 0x6E, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x4B, 0x10, 0x1F, 0x6F, 0x7D, + 0xED, 0x02, 0xF3, 0xD6, 0x7F, 0xB9, 0xC0, 0x9C, 0xFA, 0xA1, 0x0D, 0x0D, 0x77, 0xE3, 0xF1, 0x63, + 0x1B, 0x1F, 0x41, 0x78, 0xBC, 0xF3, 0x90, 0xFD, 0x91, 0xF8, 0x28, 0x68, 0x3A, 0x32, 0x9A, 0xEE, + 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x4C, 0x4F, 0x66, 0xAF, 0x3D, 0xF0, 0x75, 0x53, 0x7C, + 0x04, 0x01, 0xD2, 0xEC, 0xF6, 0x23, 0x1E, 0x20, 0x75, 0xF1, 0xF1, 0x60, 0x7B, 0x0F, 0x9E, 0xEB, + 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x96, 0x22, 0x3E, 0xDE, 0xFC, 0xCF, 0xF6, 0xC7, 0xBB, 0x6D, + 0x84, 0x04, 0xD1, 0xE1, 0xEF, 0x41, 0xE2, 0x43, 0x87, 0x43, 0x1E, 0x13, 0x71, 0x91, 0x64, 0x47, + 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xFD, 0x98, 0xD1, 0xFE, 0x59, 0x66, 0x68, 0x81, 0x0D, + 0x80, 0xEE, 0x8A, 0x0F, 0xF7, 0xA3, 0xBA, 0xFD, 0x50, 0xCF, 0x7E, 0xD4, 0x7E, 0xE8, 0xA0, 0x0D, + 0x8F, 0x87, 0xDB, 0xBB, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x2C, 0x65, 0x7C, 0xB8, + 0xFD, 0xE1, 0xFF, 0xB1, 0xFF, 0xFF, 0x77, 0x66, 0x98, 0xB7, 0x1F, 0x98, 0x69, 0x67, 0xE3, 0x63, + 0x23, 0xF1, 0x51, 0xCC, 0x44, 0x58, 0x24, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x2F, 0xAD, 0x0D, 0xBE, + 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0xFF, 0x0D, 0x58, 0x3B, 0x67, 0xDB, 0x08, 0x50, 0x41, 0x91, + 0x66, 0x22, 0x2A, 0x92, 0x2E, 0x1A, 0x1F, 0x41, 0x80, 0x34, 0xBB, 0xFD, 0x70, 0xF1, 0x11, 0x0F, + 0x90, 0x6A, 0x7C, 0xB4, 0x79, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, 0x64, 0x59, 0xC6, 0xF8, + 0x78, 0xE3, 0x2F, 0x67, 0x98, 0xF1, 0xFF, 0x3C, 0xC3, 0xBC, 0xF5, 0x23, 0xFB, 0x7B, 0x7A, 0x92, + 0xF8, 0x28, 0x66, 0x22, 0x2A, 0xD2, 0xEC, 0xF9, 0x2B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x7E, + 0xBC, 0x43, 0xAB, 0xEE, 0x32, 0xDB, 0x3E, 0x6A, 0x43, 0x40, 0x45, 0x45, 0xD2, 0x89, 0xA8, 0x48, + 0x3A, 0x11, 0x1F, 0xEE, 0xC7, 0xD4, 0xB7, 0x1F, 0x61, 0x7C, 0xB8, 0xDB, 0x8F, 0x7B, 0xB3, 0xDD, + 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x4E, 0x7C, 0xFC, 0xA7, 0x19, 0xE6, 0xF7, + 0xFF, 0xF7, 0x0C, 0xF3, 0xE6, 0x03, 0xC4, 0x47, 0x31, 0x13, 0x41, 0x91, 0x61, 0xDE, 0x2F, 0xEE, + 0x18, 0x0A, 0xBE, 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0x33, 0xD2, 0xBF, 0x5E, 0x47, 0x45, 0xD2, + 0x89, 0xA8, 0x48, 0xBA, 0x78, 0x7C, 0xB8, 0x85, 0xE1, 0x11, 0xC6, 0x47, 0xAB, 0xDB, 0x0F, 0xFF, + 0x5B, 0xAF, 0x82, 0xF8, 0x70, 0xFB, 0xA1, 0x9D, 0x88, 0x8B, 0x56, 0xD3, 0x21, 0x91, 0x65, 0x22, + 0x24, 0xB2, 0x2C, 0x87, 0xF8, 0x78, 0xE3, 0xDB, 0x36, 0x3E, 0x5E, 0x22, 0x3E, 0xF2, 0x9F, 0x8E, + 0x89, 0x2C, 0xF3, 0x8E, 0xDE, 0x3C, 0x16, 0x7C, 0x29, 0x02, 0x00, 0x00, 0x4C, 0x0F, 0xDE, 0x81, + 0xAB, 0x46, 0x75, 0x58, 0x24, 0x99, 0x88, 0x8A, 0xA4, 0x6B, 0x10, 0x1F, 0xEE, 0xC7, 0x54, 0xB7, + 0x1F, 0xD1, 0xF8, 0x70, 0xB7, 0x1F, 0xDF, 0x4A, 0x7F, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, + 0x64, 0x19, 0xF1, 0x91, 0xC3, 0x54, 0x38, 0xE4, 0x31, 0x1D, 0x12, 0x99, 0xC7, 0x9B, 0xB0, 0x00, + 0x00, 0xC0, 0x74, 0xE3, 0xED, 0xFF, 0xEC, 0x49, 0x1D, 0x17, 0xAD, 0x26, 0xA2, 0x22, 0xE9, 0xE2, + 0xE1, 0x11, 0x2E, 0x0C, 0x8F, 0x30, 0x3E, 0x9A, 0xDD, 0x7E, 0x3C, 0x76, 0x91, 0x39, 0xFD, 0xA8, + 0x0D, 0x8E, 0x36, 0x6F, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, + 0x0A, 0x87, 0x3C, 0x26, 0x02, 0xA2, 0xDD, 0xB9, 0x37, 0x61, 0x1D, 0xBF, 0x63, 0x49, 0xF0, 0xE5, + 0x08, 0x00, 0x00, 0x50, 0x7E, 0x66, 0x68, 0xBE, 0x8D, 0x02, 0x15, 0x18, 0xCD, 0x26, 0xA2, 0x22, + 0xE9, 0x54, 0x78, 0x44, 0x96, 0xE8, 0xF6, 0x23, 0x88, 0x8F, 0x76, 0x6F, 0x3F, 0x74, 0x48, 0x64, + 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0x26, 0xE2, 0x21, 0x8F, 0xBD, + 0x78, 0x1D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x87, 0xFF, 0x06, 0xAC, 0x5D, 0x9F, 0xB6, 0x61, + 0xA0, 0x22, 0xA3, 0xD1, 0x44, 0x54, 0x24, 0x9D, 0x08, 0x8E, 0xEA, 0x92, 0xDE, 0x7E, 0x3C, 0x6E, + 0x03, 0x24, 0x8C, 0x8F, 0x68, 0x80, 0xFC, 0x80, 0xF8, 0x20, 0x3E, 0x54, 0x38, 0xE4, 0x31, 0x11, + 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x3E, 0xCC, 0xA1, 0xFE, 0xB5, + 0x66, 0xC7, 0xC7, 0x6D, 0x1C, 0xA8, 0xD0, 0x50, 0x13, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0x62, 0x53, + 0xB7, 0x1F, 0xD1, 0x00, 0xF1, 0xE3, 0xA3, 0xD1, 0xED, 0xC7, 0x37, 0x75, 0x68, 0xA8, 0xE9, 0x90, + 0xC8, 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x44, 0x43, 0xCE, + 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xDA, 0xF0, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0x36, 0x10, 0x54, + 0x6C, 0xC4, 0x27, 0xA2, 0x22, 0xE9, 0x44, 0x6C, 0xD4, 0x2C, 0xC1, 0xED, 0x87, 0xFB, 0xD6, 0xAB, + 0x89, 0xC7, 0x2E, 0x9C, 0xBC, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xC9, 0x6F, 0x3F, 0x74, 0x48, + 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0xA6, 0x83, 0x21, 0xEF, + 0x79, 0x47, 0xFF, 0x64, 0x34, 0xF8, 0x92, 0x04, 0x00, 0x00, 0x28, 0x37, 0x6F, 0x78, 0xE9, 0x90, + 0x8E, 0x8D, 0xF8, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8E, 0xF8, 0xE2, 0x01, 0xA2, 0x9E, 0xFD, 0x78, + 0xDC, 0xC6, 0x47, 0x9B, 0xB7, 0x1F, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x11, 0x1F, 0x39, + 0x4C, 0x85, 0x43, 0x1E, 0xD3, 0xB1, 0x50, 0xC8, 0x8E, 0x7D, 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, + 0xE9, 0xC1, 0xDB, 0xBB, 0x24, 0xC1, 0x2B, 0x78, 0x45, 0x54, 0x24, 0x9D, 0x8A, 0x8D, 0xE8, 0x6C, + 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, 0x47, 0xEC, 0x5B, 0xAF, 0x9E, 0xB8, 0x70, 0xF2, + 0xF6, 0xC3, 0x2E, 0xCB, 0xED, 0x87, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, + 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x24, 0x14, 0xB6, 0x45, 0x95, 0x37, 0x61, 0xBD, 0x7C, 0xE7, 0xEC, + 0xE0, 0xCB, 0x12, 0x00, 0x00, 0xA0, 0xBC, 0xCC, 0x1E, 0x7B, 0xF8, 0x91, 0xD1, 0x11, 0x4E, 0x44, + 0x45, 0xD2, 0xA9, 0xE0, 0x88, 0x2F, 0x1A, 0x20, 0x76, 0xD5, 0x6F, 0xBD, 0x8A, 0x06, 0x88, 0x8B, + 0x0F, 0xFF, 0xF6, 0xE3, 0xC2, 0xFA, 0xDB, 0x8F, 0x87, 0xEC, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, + 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xB3, + 0x5F, 0x7F, 0x6E, 0x2F, 0x7E, 0xCE, 0x05, 0xC8, 0x40, 0xF0, 0x65, 0x09, 0x00, 0x00, 0x50, 0x4E, + 0x66, 0xA4, 0x7F, 0x76, 0xF3, 0x57, 0xF0, 0x8A, 0xA8, 0x48, 0x3A, 0x15, 0x1B, 0xF1, 0xC5, 0xE2, + 0x23, 0xBC, 0xFD, 0xA8, 0x7D, 0xF0, 0xDC, 0xC6, 0x47, 0xF4, 0xF6, 0x23, 0xFE, 0xAD, 0x57, 0xF7, + 0xB7, 0xBE, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, + 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x16, 0xC4, 0x87, 0x1F, 0x20, 0xD7, 0xF0, 0x26, 0x2C, 0x00, 0x00, + 0x50, 0x7E, 0xFE, 0x2B, 0x78, 0x1B, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, 0xA9, 0xD8, 0x88, 0xAF, + 0x41, 0x7C, 0x54, 0x1F, 0x3C, 0x77, 0xB3, 0xF1, 0x51, 0x73, 0xFB, 0x11, 0x7F, 0xF0, 0xDC, 0xDD, + 0x7E, 0xDC, 0xAD, 0xA3, 0x23, 0x9C, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, + 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0xB5, 0x48, 0x7C, 0x04, 0xF3, 0x4E, 0x7C, 0x69, 0x30, + 0xF8, 0xD2, 0x04, 0x00, 0x00, 0x28, 0x27, 0xFF, 0x0D, 0x58, 0x5B, 0x3F, 0x64, 0xA3, 0x61, 0x8A, + 0xE3, 0xC3, 0x4D, 0x05, 0x48, 0xCD, 0xB7, 0x5E, 0xD9, 0xF8, 0x70, 0xB7, 0x1F, 0x41, 0x7C, 0x64, + 0xB9, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x56, 0x1F, 0x1F, 0x6E, 0xDE, 0xF1, 0x3F, 0xE5, 0x4D, 0x58, 0x00, 0x00, + 0xA0, 0xDC, 0xBC, 0x91, 0x81, 0x0D, 0x1D, 0x89, 0x0F, 0xB7, 0x78, 0x7C, 0x54, 0x6F, 0x3F, 0x2E, + 0xAC, 0xC6, 0xC7, 0xE4, 0xED, 0x47, 0x2C, 0x3E, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, + 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xF1, 0xE1, + 0xEF, 0xD8, 0x2D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x94, 0x9B, 0x77, 0xE0, 0xAA, 0xD8, 0x1B, 0xB0, + 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x8C, 0x46, 0xB3, 0xD1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0x44, 0x02, + 0x24, 0x8C, 0x0F, 0xF9, 0xB9, 0x1F, 0xDF, 0x69, 0x7C, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, + 0x64, 0x59, 0x34, 0x3A, 0x88, 0x8F, 0x8C, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x11, + 0x1D, 0xD1, 0xB9, 0x37, 0x61, 0x8D, 0x7D, 0x71, 0x56, 0xF0, 0xE5, 0x09, 0x00, 0x00, 0x50, 0x3E, + 0xDE, 0xBE, 0x25, 0xE3, 0x53, 0x1E, 0x1F, 0x6E, 0xF1, 0xF8, 0x48, 0x7B, 0xFB, 0xF1, 0xA0, 0x9D, + 0x08, 0x0F, 0x37, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x52, 0xC4, 0x47, 0x18, 0x20, 0x2E, + 0x3E, 0xFE, 0x40, 0x7C, 0x44, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x38, 0xE2, + 0x1B, 0x5B, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB9, 0x4D, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, + 0xA9, 0xC0, 0x68, 0x36, 0x1B, 0x1D, 0xEE, 0x47, 0x75, 0xFB, 0x11, 0x0D, 0x90, 0xA6, 0xB7, 0x1F, + 0xF7, 0xE9, 0xDB, 0x0F, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x22, 0xF1, 0x11, 0xAE, 0x3E, + 0x3E, 0xEC, 0x5C, 0x78, 0x84, 0xB7, 0x1F, 0xC4, 0x47, 0x6C, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, + 0xA2, 0x26, 0x62, 0x43, 0xED, 0xC5, 0x6B, 0x8C, 0xF7, 0x8B, 0x2F, 0xDD, 0x15, 0x7C, 0x79, 0x02, + 0x00, 0x00, 0x94, 0x8B, 0xFF, 0x06, 0xAC, 0x9D, 0x9F, 0xD2, 0x51, 0x91, 0x74, 0xF1, 0xB8, 0x48, + 0xB2, 0x30, 0x3C, 0xC2, 0xF8, 0xF0, 0x03, 0x64, 0x66, 0x35, 0x3E, 0x6A, 0xDF, 0x7C, 0x95, 0xFC, + 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0x76, 0x24, 0x3E, 0xE2, + 0x37, 0x1F, 0x6F, 0x04, 0xF1, 0xF1, 0x07, 0xE2, 0xA3, 0xA0, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x34, + 0x9A, 0xCC, 0x3B, 0x71, 0xC7, 0x86, 0xE0, 0x4B, 0x14, 0x00, 0x00, 0xA0, 0x5C, 0x6C, 0x80, 0xAC, + 0x33, 0xDB, 0x2F, 0xD6, 0x61, 0x91, 0x64, 0x2A, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0xF6, + 0xF6, 0xC3, 0xC6, 0x47, 0x83, 0x67, 0x3F, 0xEA, 0x3E, 0x74, 0xD0, 0xBD, 0xF9, 0x4A, 0xDC, 0x7E, + 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x22, 0x3E, 0xA2, 0x37, 0x1F, 0x61, 0x7C, 0x84, + 0x37, 0x1F, 0xC4, 0x47, 0x38, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x91, 0xD1, 0x6C, + 0xDE, 0x89, 0x3F, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x9C, 0xFC, 0x57, 0xF0, 0xAA, 0xB0, 0x48, + 0xB2, 0x78, 0x58, 0x24, 0x5D, 0x18, 0x1E, 0x61, 0x7C, 0x3C, 0x3D, 0xB3, 0xE6, 0xF6, 0xA3, 0xEE, + 0xD9, 0x0F, 0x1B, 0x20, 0xA7, 0xA2, 0x01, 0xF2, 0x23, 0xBB, 0x1E, 0x8C, 0x0F, 0xB7, 0xBA, 0x00, + 0x69, 0x10, 0x1F, 0xE3, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0xC0, + 0x68, 0x35, 0xEF, 0xD8, 0x17, 0xC6, 0x83, 0x2F, 0x51, 0x00, 0x00, 0x80, 0x72, 0xF1, 0x0E, 0x5C, + 0x33, 0x2A, 0xE3, 0xA2, 0xD5, 0x54, 0x58, 0x24, 0x99, 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, + 0xF1, 0x11, 0xBD, 0xFD, 0x88, 0xC5, 0x47, 0xDD, 0xED, 0xC7, 0xB7, 0x6A, 0x6F, 0x3F, 0x74, 0x48, + 0x64, 0x99, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x56, 0x17, 0x1F, 0xEA, 0x8D, 0x57, 0xC4, 0x47, + 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x71, 0x91, 0x68, 0x47, 0x56, 0xF3, 0x26, + 0x2C, 0x00, 0x00, 0x50, 0x4E, 0xDE, 0xDE, 0x25, 0x63, 0x32, 0x30, 0x9A, 0x2D, 0x1E, 0x15, 0x69, + 0x16, 0x86, 0x47, 0x18, 0x1F, 0x69, 0x6F, 0x3F, 0x7E, 0x68, 0x57, 0xB6, 0xF8, 0x70, 0x37, 0x1F, + 0x2E, 0x3E, 0xDC, 0x43, 0xE7, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, + 0xA8, 0x48, 0xB3, 0x97, 0x56, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x4E, 0x66, 0xCF, 0x42, 0x1D, + 0x19, 0x8D, 0xA6, 0xA2, 0x22, 0xE5, 0x2A, 0x01, 0x32, 0xB3, 0xED, 0xDB, 0x0F, 0x1D, 0x12, 0x59, + 0x26, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0xB5, 0x8C, 0x8F, 0xBF, 0x9C, 0xFC, 0xAC, 0x8F, 0x3F, + 0xDC, 0x4B, 0x7C, 0x14, 0x33, 0x15, 0x09, 0x45, 0x4D, 0x04, 0x45, 0xDA, 0xBD, 0x78, 0x8D, 0x0D, + 0x90, 0x3B, 0xD6, 0x05, 0x5F, 0xA6, 0x00, 0x00, 0x00, 0xE5, 0x60, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, + 0xE6, 0xE8, 0xD0, 0x50, 0x13, 0x31, 0x91, 0x6A, 0xD5, 0xDB, 0x8F, 0x20, 0x3E, 0x9A, 0xDD, 0x7E, + 0x84, 0xF1, 0xD1, 0xE0, 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, + 0x0D, 0xE3, 0x23, 0x08, 0x90, 0xE8, 0x07, 0x0D, 0x12, 0x1F, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, + 0xA2, 0x26, 0x62, 0x22, 0xCB, 0x9E, 0xB7, 0x7F, 0x3F, 0x4E, 0xDC, 0xB1, 0x3E, 0xF8, 0x52, 0x05, + 0x00, 0x00, 0x28, 0x07, 0xFF, 0x15, 0xBC, 0x49, 0xDF, 0x80, 0xA5, 0x82, 0x22, 0xC3, 0xFC, 0xF8, + 0x88, 0xDD, 0x7E, 0x54, 0x03, 0xA4, 0xD5, 0xED, 0xC7, 0x3D, 0xBD, 0x1B, 0x1F, 0x95, 0xD7, 0xED, + 0x12, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x24, 0xDA, 0x18, 0x6F, + 0xC2, 0x02, 0x00, 0x00, 0xA5, 0xE3, 0xBF, 0x01, 0x6B, 0xEB, 0x07, 0x75, 0x70, 0x44, 0x27, 0x42, + 0x22, 0xF5, 0xC2, 0x9B, 0x8F, 0x26, 0xB7, 0x1F, 0x13, 0x2E, 0x40, 0x1E, 0x8B, 0xDC, 0x7E, 0x84, + 0xF1, 0xE1, 0xF6, 0xBD, 0xCA, 0xB7, 0x5E, 0xE9, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x26, 0xC2, + 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x11, 0xD1, 0xCE, + 0xBC, 0x63, 0x5F, 0x38, 0x19, 0x7C, 0xA9, 0x02, 0x00, 0x00, 0x94, 0x83, 0x37, 0xBC, 0x62, 0x50, + 0x06, 0x47, 0x74, 0x2A, 0x26, 0xB2, 0x2C, 0x8C, 0x8F, 0xD8, 0xED, 0x47, 0xE2, 0x67, 0x3F, 0xBE, + 0xC9, 0xB7, 0x5D, 0x25, 0x9B, 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, + 0x2A, 0x12, 0x8A, 0x9A, 0x0E, 0x88, 0xB6, 0x77, 0x64, 0xB5, 0x09, 0xBE, 0x54, 0x01, 0x00, 0x00, + 0xCA, 0xC1, 0xDB, 0x7B, 0x79, 0xF3, 0x57, 0xF0, 0xAA, 0x90, 0x48, 0xBB, 0x4D, 0x6E, 0x93, 0xE1, + 0x31, 0x79, 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xFC, 0xF6, 0x43, 0x87, 0x44, + 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0x0D, 0xE3, 0xC3, 0x3D, 0x70, 0x1E, 0x8B, 0x8F, + 0xF1, 0xFF, 0x32, 0xCB, 0x9C, 0xFF, 0xD7, 0x5B, 0x83, 0xF8, 0x58, 0x65, 0x0F, 0xFA, 0x2A, 0x28, + 0xD2, 0x4C, 0x84, 0x43, 0x1E, 0x93, 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, + 0x4D, 0x84, 0x43, 0x5E, 0x3B, 0xB2, 0x92, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF1, 0xF6, 0x2C, + 0x1A, 0x97, 0xE1, 0xE1, 0xA6, 0x62, 0x22, 0xCB, 0x6C, 0x78, 0x44, 0x6F, 0x3F, 0xAA, 0xDF, 0x7A, + 0x15, 0x06, 0x48, 0xCD, 0x6B, 0x77, 0x2F, 0x94, 0xB7, 0x1F, 0xEF, 0x7C, 0x23, 0xAF, 0xDB, 0x0F, + 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x2D, 0x6D, 0x7C, 0x9C, 0xFB, 0xE9, 0x17, 0x2A, 0xF1, 0x71, + 0xD4, 0xFE, 0x28, 0x83, 0x22, 0xCD, 0x44, 0x38, 0xE4, 0x31, 0x19, 0x0E, 0x79, 0x4C, 0x85, 0x43, + 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x44, 0x34, 0xE4, 0x39, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xCA, 0xC4, + 0x0C, 0xF5, 0xCF, 0x32, 0x43, 0x7D, 0x53, 0x1A, 0x1F, 0xE1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xCD, + 0x9E, 0xFD, 0x70, 0xF1, 0x71, 0x7F, 0x5E, 0xB7, 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, + 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x82, 0x21, 0xEF, 0xB9, 0xFF, + 0x6D, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0x0B, 0xFF, 0x0D, 0x58, 0x3B, 0x3E, 0x39, 0xE5, 0xF1, + 0x51, 0x7D, 0xF0, 0x5C, 0xDD, 0x7E, 0xC4, 0x1E, 0x3C, 0x7F, 0xE7, 0x41, 0x1B, 0x1F, 0x5F, 0x57, + 0x31, 0x91, 0x76, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x62, 0xA1, 0xA0, 0x79, 0x27, 0xEE, 0xE0, 0x4D, 0x58, 0x00, 0x00, + 0xA0, 0x1C, 0xBC, 0xE1, 0xFE, 0xBB, 0xCC, 0xB6, 0x8F, 0x14, 0x13, 0x1F, 0xCF, 0x54, 0xE2, 0xA3, + 0x2E, 0x40, 0xE2, 0xAF, 0xDD, 0x75, 0xB7, 0x1F, 0x41, 0x7C, 0xC4, 0x6F, 0x3F, 0xDE, 0x79, 0xD8, + 0xC6, 0xC7, 0x77, 0xF3, 0xF8, 0xD6, 0x2B, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, + 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xA1, 0x50, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, + 0x82, 0x2F, 0x59, 0x00, 0x00, 0x80, 0xDE, 0xE6, 0xBF, 0x82, 0xB7, 0xA8, 0xF8, 0x08, 0x02, 0xA4, + 0xE1, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0x8A, 0xC7, 0x47, 0x2E, 0xB7, 0x1F, 0x22, 0x24, + 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0xA6, + 0x23, 0xA1, 0xD0, 0x1D, 0xB9, 0x91, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF0, 0x0E, 0x5C, 0x33, + 0xF9, 0x06, 0x2C, 0x19, 0x12, 0x59, 0x36, 0x19, 0x1F, 0x8D, 0x6E, 0x3F, 0xAA, 0xAF, 0xDD, 0xAD, + 0xDE, 0x7E, 0x5C, 0x14, 0xBB, 0xFD, 0xB0, 0xE1, 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, + 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x38, 0x98, + 0x8A, 0xBD, 0x34, 0x60, 0xCC, 0xF1, 0x3B, 0x96, 0x04, 0x5F, 0xB6, 0x00, 0x00, 0x00, 0xBD, 0xCB, + 0xDB, 0x77, 0xC5, 0xC9, 0x42, 0xE2, 0xA3, 0xAD, 0xDB, 0x8F, 0x20, 0x3E, 0x1E, 0x68, 0xF7, 0xF6, + 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, + 0x50, 0xD4, 0x44, 0x18, 0x4C, 0xD5, 0xDC, 0x9B, 0xB0, 0x4E, 0x7C, 0x69, 0x6D, 0xF0, 0x65, 0x0B, + 0x00, 0x00, 0xD0, 0xBB, 0xCC, 0xEE, 0xBE, 0x48, 0x3C, 0xB4, 0xBB, 0xDA, 0xF8, 0x70, 0x3F, 0xAA, + 0xDB, 0x8F, 0xFA, 0x67, 0x3F, 0xA2, 0xB7, 0x1F, 0x41, 0x7C, 0xB8, 0xDD, 0xDB, 0xCE, 0xED, 0x87, + 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, + 0xA8, 0x89, 0x28, 0x98, 0xCA, 0xBD, 0x70, 0x25, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xCF, 0x1C, + 0xE8, 0x5F, 0x62, 0x76, 0xCE, 0x0E, 0xE2, 0xA1, 0xDD, 0x45, 0xE2, 0x23, 0x08, 0x90, 0x66, 0xB7, + 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xE1, 0x6E, 0x3F, 0x64, 0x58, 0x24, 0x99, 0x08, 0x89, 0x2C, + 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x20, + 0xE8, 0xC0, 0xBC, 0xE3, 0xB7, 0x0F, 0x05, 0x5F, 0xBA, 0x00, 0x00, 0x00, 0xBD, 0xC9, 0x1C, 0x5C, + 0xB6, 0xD6, 0x6C, 0xFF, 0x58, 0x10, 0x10, 0xED, 0xAC, 0x3E, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0x43, + 0x3D, 0xFB, 0x51, 0xF9, 0xD0, 0xC1, 0x0B, 0x27, 0x03, 0xE4, 0x21, 0xBB, 0xCC, 0xB7, 0x1F, 0x22, + 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, + 0xA6, 0x63, 0xA0, 0x13, 0xF3, 0x8E, 0xDE, 0xC2, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x33, 0x23, + 0xCB, 0xD7, 0x9B, 0xCD, 0xEF, 0xB3, 0xB1, 0xA0, 0xA2, 0x22, 0xE9, 0x62, 0xF1, 0xE1, 0x16, 0x86, + 0x47, 0x18, 0x1F, 0xB1, 0xDB, 0x8F, 0xBA, 0x67, 0x3F, 0x1E, 0xB5, 0xF1, 0xE1, 0x02, 0xA4, 0xED, + 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, + 0x45, 0x42, 0x51, 0xD3, 0x21, 0xD0, 0xB1, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, + 0xE6, 0x1D, 0xB8, 0x7E, 0xA8, 0x36, 0x26, 0xD2, 0x4E, 0xC7, 0x87, 0xFB, 0xB1, 0xE9, 0xED, 0x47, + 0x2C, 0x3E, 0xEA, 0x6E, 0x3F, 0xEE, 0xC9, 0x72, 0xFB, 0x21, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, + 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x00, 0x3A, 0x3D, 0xF7, + 0x26, 0xAC, 0x97, 0xEF, 0x9C, 0x1D, 0x7C, 0xF9, 0x02, 0x00, 0x00, 0xF4, 0x1E, 0x6F, 0xEF, 0x65, + 0xA3, 0xF5, 0x51, 0x91, 0x74, 0xB1, 0xF0, 0x08, 0x17, 0x86, 0x47, 0x18, 0x1F, 0x4D, 0x6F, 0x3F, + 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x4E, 0x06, 0x46, 0xB3, 0x89, 0x90, 0xC8, + 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, + 0xFC, 0x77, 0xC3, 0x5E, 0xFC, 0x9C, 0x31, 0xC7, 0x6E, 0x1B, 0x08, 0xBE, 0x7C, 0x01, 0x00, 0x00, + 0x7A, 0x8F, 0xD9, 0x63, 0x0F, 0x5B, 0x32, 0x2E, 0x5A, 0x4D, 0x84, 0x47, 0x64, 0xC9, 0x6E, 0x3F, + 0x2A, 0xF1, 0xD1, 0xFE, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, + 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xFE, 0xDD, 0x32, 0xDE, 0x84, 0x05, 0x00, + 0x00, 0x7A, 0x99, 0x19, 0xE9, 0x9F, 0x6D, 0x76, 0xCF, 0xB3, 0xC1, 0xA0, 0x02, 0xA3, 0xD9, 0x74, + 0x74, 0xF8, 0x4B, 0x7C, 0xFB, 0x31, 0xD3, 0x9C, 0x09, 0xE3, 0xA3, 0xAD, 0xDB, 0x0F, 0x11, 0x12, + 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xFE, 0x2E, 0x9B, 0x77, 0xE2, 0xF6, 0xC1, 0xE0, 0x4B, 0x18, 0x00, 0x00, 0xA0, 0xB7, 0xD8, + 0x00, 0x19, 0x48, 0xFF, 0x06, 0x2C, 0x11, 0x1D, 0xB1, 0xA9, 0xDB, 0x8F, 0x6A, 0x80, 0x84, 0xF1, + 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, + 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7F, 0xB7, 0xCD, 0x3B, 0xFA, 0x85, 0xD1, 0xE0, 0x4B, + 0x18, 0x00, 0x00, 0xA0, 0xB7, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0x3E, 0x60, 0xA3, 0x41, 0x85, + 0x86, 0x9A, 0x0E, 0x8E, 0xEA, 0x12, 0xDC, 0x7E, 0x4C, 0x3C, 0x31, 0xD3, 0x4C, 0x3C, 0x16, 0xB9, + 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0xFB, 0xC4, 0x47, 0x65, 0x22, 0x1C, 0xF2, 0x98, 0x0C, 0x87, 0x3C, + 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0xB0, 0xDF, 0x95, 0x3B, 0x76, 0x0B, 0x6F, + 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xC9, 0x1B, 0x59, 0xB1, 0xA1, 0x3E, 0x32, 0x1A, 0x4D, 0x04, 0x47, + 0x7C, 0xF1, 0x00, 0xA9, 0x7B, 0xF6, 0xC3, 0xC6, 0x47, 0xB3, 0xDB, 0x8F, 0x6F, 0xA8, 0xD0, 0x50, + 0x13, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, + 0x14, 0x35, 0x71, 0xC8, 0xEF, 0xE6, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xAB, 0xBC, 0x7D, 0x57, + 0x24, 0x7C, 0x03, 0x96, 0x88, 0x8D, 0xE8, 0x6C, 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, + 0x47, 0xE4, 0x5B, 0xAF, 0x06, 0x6D, 0x7C, 0x44, 0x6F, 0x3F, 0xEC, 0x6A, 0x6E, 0x3F, 0x36, 0x24, + 0xBD, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, + 0x54, 0x24, 0x14, 0x35, 0x71, 0xC0, 0xEF, 0xF6, 0x8D, 0x2D, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0xA0, + 0x37, 0x79, 0x7B, 0x2F, 0x1B, 0xAF, 0x8F, 0x8D, 0xF8, 0x62, 0xB1, 0xA1, 0x16, 0x0D, 0x10, 0xBB, + 0xEA, 0xB7, 0x5E, 0x85, 0x01, 0x62, 0xE3, 0x63, 0xF2, 0xF6, 0x63, 0x66, 0x1B, 0xB7, 0x1F, 0x22, + 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, + 0x26, 0x0E, 0xF7, 0xBD, 0xB0, 0x17, 0xAF, 0x31, 0xDE, 0x2F, 0x6E, 0xBF, 0x2B, 0xF8, 0x32, 0x06, + 0x00, 0x00, 0xE8, 0x1D, 0xAD, 0xDF, 0x80, 0x15, 0x0B, 0x0D, 0xB5, 0x58, 0x7C, 0x84, 0xB7, 0x1F, + 0x93, 0x0F, 0x9E, 0xDB, 0xF8, 0x88, 0xDF, 0x7E, 0x84, 0xF1, 0x11, 0x06, 0x48, 0xA2, 0xDB, 0x0F, + 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, + 0x51, 0x13, 0x07, 0xFB, 0x1E, 0x9A, 0x77, 0xFC, 0x8E, 0x0D, 0xC1, 0x97, 0x31, 0x00, 0x00, 0x40, + 0x6F, 0xF0, 0xDF, 0x80, 0xB5, 0x73, 0xB6, 0x8D, 0x08, 0x15, 0x1E, 0x6E, 0xB1, 0xD0, 0x50, 0x6B, + 0x10, 0x1F, 0xD5, 0x07, 0xCF, 0x37, 0xCE, 0xAC, 0xBF, 0xFD, 0x08, 0xE2, 0xA3, 0x7A, 0xFB, 0xF1, + 0xA0, 0xDD, 0xD7, 0x55, 0x70, 0x44, 0x27, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, + 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0x50, 0xDF, 0x4B, 0xF3, 0x8E, 0xDE, 0xCA, + 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x31, 0x23, 0xCB, 0xD7, 0x35, 0x7E, 0x05, 0x6F, 0x2C, 0x34, + 0x1A, 0x4D, 0x05, 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x41, 0x7C, 0xC8, 0x37, + 0x5F, 0x7D, 0xB7, 0xD5, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, + 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7D, 0xAF, 0xCD, 0x3B, 0xFA, 0xF9, 0xF1, + 0xE0, 0x4B, 0x19, 0x00, 0x00, 0xA0, 0x37, 0xD8, 0x00, 0x59, 0x5F, 0x1F, 0x1E, 0x29, 0xE2, 0xC3, + 0x2D, 0x1E, 0x1F, 0xD5, 0xDB, 0x8F, 0xC9, 0xF8, 0xA8, 0x79, 0xF3, 0x55, 0xEA, 0xDB, 0x0F, 0x11, + 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, + 0xD3, 0x87, 0xF9, 0x9E, 0x9C, 0x7B, 0x13, 0xD6, 0xD8, 0x17, 0x67, 0x05, 0x5F, 0xCE, 0x00, 0x00, + 0x00, 0xDD, 0xCF, 0x3B, 0x70, 0xD5, 0x50, 0xBB, 0xF1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0xD4, 0xDD, + 0x7E, 0x5C, 0x98, 0xE1, 0xF6, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, + 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBE, 0x97, 0x37, 0xB6, 0x9C, 0x37, 0x61, + 0x01, 0x00, 0x80, 0xDE, 0xE2, 0xED, 0xBD, 0x7C, 0x2C, 0x73, 0x7C, 0xB8, 0xC5, 0xE3, 0xC3, 0x0F, + 0x90, 0x19, 0x39, 0xDD, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, + 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xC0, 0xF7, 0xFA, 0x78, 0x13, 0x16, 0x00, 0x00, + 0xE8, 0x35, 0x66, 0x68, 0x81, 0x0D, 0x89, 0xEC, 0xF1, 0xE1, 0x7E, 0xAC, 0xBD, 0xFD, 0xB0, 0xF1, + 0x11, 0xFB, 0xF6, 0xAB, 0xA6, 0xB7, 0x1F, 0xF7, 0x35, 0xBA, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, + 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x78, 0x2F, + 0xC3, 0x9E, 0xBF, 0x9C, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, 0x61, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, + 0x2E, 0xB5, 0x11, 0x91, 0x21, 0x3E, 0xDC, 0xC2, 0xF0, 0x08, 0xE3, 0xE3, 0xE9, 0x19, 0x35, 0xB7, + 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xF1, 0x80, 0x1D, 0xF1, 0x91, 0xCF, 0x64, 0x38, 0xE4, 0x31, + 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x07, 0xF7, 0x12, 0xCD, 0x3B, 0xFE, 0x67, 0xBC, + 0x09, 0x0B, 0x00, 0x00, 0xF4, 0x06, 0xFF, 0x15, 0xBC, 0xFE, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, + 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, 0xF1, 0xD1, 0xE0, 0xD9, 0x0F, 0xF9, 0xA1, 0x83, 0xF7, + 0xAA, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, + 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x87, 0xF6, 0x32, 0xCD, 0x3B, 0xFA, 0xF9, 0x93, 0xC1, 0x97, 0x34, + 0x00, 0x00, 0x40, 0x77, 0xF3, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0xF5, 0x71, 0x91, 0x64, 0x61, 0x78, + 0x84, 0xF1, 0x11, 0xBB, 0xFD, 0xA8, 0x7B, 0xF6, 0xC3, 0x06, 0xC8, 0x29, 0x17, 0x20, 0x4D, 0x6F, + 0x3F, 0x44, 0x48, 0x64, 0x99, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, + 0x09, 0x45, 0x4D, 0x1F, 0xD8, 0x4B, 0xB7, 0x23, 0xAB, 0x4C, 0xF0, 0x25, 0x0D, 0x00, 0x00, 0xD0, + 0xDD, 0xBC, 0xE1, 0x65, 0x83, 0x32, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0x12, 0x20, 0x33, + 0xF4, 0xED, 0x47, 0x2C, 0x3E, 0x5A, 0xDF, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, + 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA8, 0x97, 0x75, 0x63, 0xCB, + 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0D, 0xDE, 0xDE, 0xCB, 0x46, 0xEB, 0xE2, 0x22, 0xC9, 0xAA, + 0xB7, 0x1F, 0x41, 0x7C, 0x24, 0xBD, 0xFD, 0x08, 0x03, 0xE4, 0x07, 0x76, 0xC4, 0x47, 0x7B, 0x93, + 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0xBA, 0x7F, + 0x5D, 0x68, 0xCC, 0x0B, 0x57, 0x1B, 0x73, 0xFC, 0x8E, 0x75, 0xC1, 0x97, 0x35, 0x00, 0x00, 0x40, + 0xF7, 0xF2, 0xF6, 0x2C, 0x18, 0x97, 0x81, 0xD1, 0x6C, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0x59, 0x6F, + 0x3F, 0xEE, 0x89, 0xDE, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, + 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2E, 0x3E, 0xDC, 0x7E, 0x6E, + 0xFF, 0x99, 0x38, 0x71, 0xDB, 0xFA, 0xE0, 0xCB, 0x1A, 0x00, 0x00, 0xA0, 0x3B, 0x99, 0xA1, 0xFE, + 0x59, 0x66, 0xF7, 0xDC, 0xFA, 0xC0, 0x68, 0xB5, 0xF0, 0xE6, 0x23, 0x97, 0xDB, 0x0F, 0x11, 0x12, + 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xF4, 0xB2, 0x2E, 0x8C, 0x8F, 0x60, 0xDE, 0x89, 0xDB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, + 0x6E, 0x66, 0x64, 0xE9, 0x80, 0xD9, 0xF1, 0x71, 0x1D, 0x19, 0xCD, 0x16, 0xC6, 0x47, 0xDB, 0xB7, + 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, + 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x5D, 0x2C, 0x3E, 0xFC, 0x00, 0x39, 0x7A, 0x33, 0x6F, 0xC2, + 0x02, 0x00, 0x00, 0xDD, 0xCD, 0x1B, 0x5E, 0x7E, 0x97, 0xD9, 0xFA, 0x21, 0x1D, 0x19, 0x8D, 0x16, + 0x8F, 0x8F, 0x66, 0xB7, 0x1F, 0x61, 0x7C, 0xC8, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, + 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, + 0xC4, 0x87, 0xBF, 0x23, 0x37, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xDD, 0xFC, 0x57, 0xF0, 0xAA, + 0xC8, 0x68, 0x34, 0x1B, 0x1D, 0x8D, 0x6E, 0x3F, 0xAA, 0x01, 0xD2, 0xEA, 0xF6, 0xE3, 0x1B, 0xC4, + 0x47, 0xA6, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, + 0x65, 0x9D, 0x0A, 0x8F, 0x70, 0x2F, 0xF5, 0xBB, 0x07, 0xD1, 0x97, 0x04, 0x5F, 0xDE, 0x00, 0x00, + 0x00, 0xDD, 0xC7, 0x3B, 0x70, 0x75, 0xF2, 0x37, 0x60, 0x45, 0xE3, 0xC3, 0x86, 0x47, 0xA3, 0xDB, + 0x8F, 0x09, 0x17, 0x20, 0x8F, 0x45, 0x6E, 0x3F, 0xC2, 0xF8, 0x70, 0xDB, 0xE0, 0xBE, 0xF5, 0x4A, + 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, + 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xD1, 0x11, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x3F, 0x5F, 0x1B, + 0x7C, 0x79, 0x03, 0x00, 0x00, 0x74, 0x1F, 0x6F, 0xDF, 0xE5, 0x27, 0x65, 0x6C, 0xC4, 0x17, 0xC4, + 0x47, 0xA3, 0xDB, 0x8F, 0xC4, 0xCF, 0x7E, 0x7C, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, + 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xC1, + 0x11, 0x1F, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xDD, 0x2E, 0xD1, 0x1B, 0xB0, 0xE2, 0xF1, 0x51, 0x73, + 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xED, 0xED, 0x47, 0x4E, 0xDF, 0x7A, 0x25, + 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, + 0xB2, 0x4E, 0xC5, 0x46, 0x83, 0x79, 0xC7, 0x6F, 0x1F, 0x0A, 0xBE, 0xBC, 0x01, 0x00, 0x00, 0xBA, + 0x8B, 0x39, 0x70, 0xFD, 0x12, 0xB3, 0xF3, 0x53, 0x3A, 0x3A, 0xC2, 0x45, 0xE2, 0xA3, 0x1A, 0x20, + 0x76, 0xD5, 0x6F, 0xBD, 0x0A, 0x03, 0xA4, 0xE6, 0xB5, 0xBB, 0x33, 0xC5, 0xED, 0xC7, 0xCC, 0x7C, + 0x6E, 0x3F, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, + 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0xC8, 0x68, 0x36, 0xEF, 0xC8, 0x9A, 0xB1, 0xE0, 0x4B, 0x1C, 0x00, + 0x00, 0xA0, 0xBB, 0x98, 0x83, 0xCB, 0xD6, 0x9A, 0xED, 0x1F, 0xD5, 0xE1, 0xE1, 0x16, 0x09, 0x8F, + 0x68, 0x7C, 0x84, 0xB7, 0x1F, 0x35, 0x0F, 0x9E, 0x37, 0x7A, 0xF6, 0xC3, 0x0F, 0x10, 0x1B, 0x1F, + 0xDF, 0xCD, 0xE1, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, + 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x08, 0x8C, 0x96, 0x3B, 0xBA, 0x86, 0x37, 0x61, 0x01, + 0x00, 0x80, 0xEE, 0xE4, 0xBF, 0x01, 0x6B, 0xF3, 0xAC, 0x4C, 0xF1, 0x51, 0x7D, 0xF0, 0x5C, 0xDD, + 0x7E, 0x04, 0xF1, 0x51, 0xB9, 0xFD, 0xB0, 0xF1, 0xF1, 0xA0, 0xDD, 0xD7, 0x45, 0x50, 0xA4, 0x99, + 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, + 0xCB, 0x3A, 0x15, 0x17, 0x49, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB7, 0xF2, 0x0E, 0x7C, 0x6E, + 0x28, 0x49, 0x7C, 0xD4, 0x05, 0x48, 0xFC, 0xB5, 0xBB, 0xEE, 0xF6, 0x23, 0x88, 0x8F, 0xDA, 0x37, + 0x5F, 0xD9, 0xF0, 0xC8, 0xE3, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x0A, 0x8B, 0xA4, 0x7B, 0xE1, 0x5A, 0x63, + 0x8E, 0xDD, 0x36, 0x10, 0x7C, 0x99, 0x03, 0x00, 0x00, 0x74, 0x0F, 0x6F, 0xEF, 0x65, 0xF5, 0xAF, + 0xE0, 0x8D, 0x44, 0x87, 0x8C, 0x8F, 0xE8, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0xAA, 0xDE, + 0x7E, 0x04, 0xF1, 0xD1, 0xEE, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, + 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x15, 0x69, 0xF6, 0xFC, 0x67, 0x79, + 0x13, 0x16, 0x00, 0x00, 0xE8, 0x4E, 0x66, 0x8F, 0x3D, 0xEC, 0xB4, 0x88, 0x0F, 0x37, 0x75, 0xFB, + 0x51, 0x7D, 0xED, 0x6E, 0xF5, 0xF6, 0xE3, 0xC2, 0xC8, 0xED, 0x47, 0x10, 0x1F, 0xED, 0xDE, 0x7E, + 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x62, 0x07, + 0xF4, 0x32, 0x4F, 0x05, 0x45, 0x86, 0x79, 0x27, 0x6E, 0x1B, 0x0C, 0xBE, 0xCC, 0x01, 0x00, 0x00, + 0xBA, 0x83, 0x19, 0xE9, 0x9F, 0x5D, 0xF3, 0x0A, 0xDE, 0x48, 0x70, 0x44, 0x97, 0xFE, 0xF6, 0x63, + 0xE6, 0x64, 0x80, 0x3C, 0x60, 0xA7, 0xC2, 0x22, 0xC9, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, + 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0x90, 0xC8, 0x3A, 0xEF, + 0xC8, 0xE7, 0x47, 0x83, 0x2F, 0x75, 0x00, 0x00, 0x80, 0xEE, 0x60, 0x46, 0x96, 0x0E, 0x54, 0xDF, + 0x80, 0x15, 0x09, 0x8E, 0xF8, 0xD4, 0xED, 0x47, 0xFD, 0xB3, 0x1F, 0xE1, 0xED, 0x47, 0x24, 0x3E, + 0xDC, 0xEE, 0xCD, 0x78, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, + 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x44, 0x44, 0x5B, 0xE3, 0x4D, 0x58, 0x00, 0x00, + 0xA0, 0xDB, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0xDE, 0x2F, 0xA3, 0x23, 0x5C, 0xB3, 0xDB, 0x8F, + 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0xC8, 0x7A, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, + 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x05, 0x44, 0xBB, 0x73, 0x6F, + 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x3B, 0x00, 0x00, 0x40, 0xE7, 0x79, 0x23, 0xCB, 0x36, + 0xA8, 0xE8, 0x88, 0x4E, 0xDD, 0x7E, 0xD4, 0x3F, 0xFB, 0xE1, 0x3E, 0x74, 0xD0, 0xBD, 0x7A, 0x37, + 0x12, 0x20, 0xEE, 0x43, 0x07, 0xB3, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, + 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xF1, 0x90, 0xC7, 0x5E, 0xBC, + 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, 0xEE, 0xE2, 0xED, 0xBD, 0x62, 0x54, 0x45, 0x47, 0xB8, 0x66, + 0xB7, 0x1F, 0xD5, 0x67, 0x3F, 0xFC, 0xD7, 0xEE, 0x06, 0xF1, 0xE1, 0xD6, 0xCE, 0xED, 0x87, 0x08, + 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, + 0x3A, 0x15, 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x2E, 0xDE, 0xDE, + 0xC5, 0xE3, 0x2A, 0x3C, 0xC2, 0x35, 0xBD, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC5, 0x87, 0xBA, 0xFD, + 0xB8, 0x27, 0xE5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, + 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x0D, 0x39, 0xCF, 0x3B, 0xB6, 0x96, 0x37, 0x61, + 0x01, 0x00, 0x80, 0xEE, 0xE1, 0xBF, 0x01, 0x2B, 0x12, 0x1C, 0xD1, 0xB5, 0xBC, 0xFD, 0xB0, 0xF1, + 0x31, 0xF1, 0xD8, 0x8C, 0xDA, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x60, 0xA7, 0x22, 0xA3, 0xD1, 0x44, + 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, + 0xD6, 0x89, 0x58, 0x28, 0x62, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0E, 0xFE, + 0x1B, 0xB0, 0x76, 0x7C, 0x52, 0xC6, 0x87, 0x5B, 0xCB, 0xDB, 0x8F, 0x30, 0x3E, 0xDA, 0xBD, 0xFD, + 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, + 0x7A, 0x59, 0x27, 0x42, 0xA1, 0xA8, 0x79, 0x47, 0x6F, 0x1E, 0x0F, 0xBE, 0xE4, 0x01, 0x00, 0x00, + 0x3A, 0xCB, 0x8C, 0x2C, 0x5F, 0x67, 0xB6, 0x7D, 0xA4, 0x75, 0x7C, 0xC8, 0xDB, 0x8F, 0x19, 0xF9, + 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, + 0xC4, 0x21, 0xBD, 0xAC, 0x13, 0x91, 0x50, 0xE8, 0xDC, 0x9B, 0xB0, 0xC6, 0xBE, 0x38, 0x2B, 0xF8, + 0xB2, 0x07, 0x00, 0x00, 0xE8, 0x1C, 0x1B, 0x20, 0xEB, 0x55, 0x7C, 0xB8, 0xA9, 0xDB, 0x0F, 0x3F, + 0x40, 0x44, 0x7C, 0x64, 0xBE, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, + 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA1, 0xE8, 0xF1, 0x26, 0x2C, 0x00, + 0x00, 0xD0, 0x2D, 0xBC, 0x03, 0x57, 0x0D, 0x35, 0x8C, 0x0F, 0x1B, 0x1E, 0xF2, 0xF6, 0xE3, 0x09, + 0x1B, 0x1F, 0x2E, 0x40, 0x1E, 0x8D, 0xDC, 0x7E, 0x84, 0xF1, 0xE1, 0xB6, 0x81, 0xF8, 0xA8, 0x9B, + 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xA9, + 0x38, 0x98, 0x8A, 0xBD, 0x70, 0xB5, 0xF1, 0x7E, 0x71, 0xFB, 0x5D, 0xC1, 0x97, 0x3D, 0x00, 0x00, + 0x40, 0xE7, 0x78, 0x7B, 0x2F, 0x1B, 0x6B, 0x18, 0x20, 0x6E, 0x91, 0xDB, 0x0F, 0x17, 0x1F, 0x67, + 0x07, 0x67, 0xD4, 0xDE, 0x7E, 0xA8, 0x67, 0x3F, 0xBE, 0x21, 0x62, 0x23, 0x3E, 0x11, 0x1E, 0x6E, + 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2A, + 0x0C, 0xA6, 0x70, 0xDE, 0xF1, 0xDB, 0x36, 0x04, 0x5F, 0xF6, 0x00, 0x00, 0x00, 0x9D, 0x63, 0x86, + 0xE6, 0xEB, 0xF8, 0xA8, 0xB9, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC6, 0x47, 0x1E, 0xB7, 0x1F, 0x22, + 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, + 0xEB, 0x44, 0x10, 0x4C, 0xF5, 0xBC, 0xE3, 0x7F, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x67, 0x99, + 0x91, 0xFE, 0xD9, 0x66, 0xE7, 0x25, 0x3A, 0x40, 0xEC, 0xA2, 0xDF, 0x7A, 0x75, 0xEE, 0xC9, 0x19, + 0xE6, 0xAC, 0x8D, 0x8F, 0xC9, 0xDB, 0x8F, 0x19, 0xFA, 0xD9, 0x8F, 0x56, 0xB7, 0x1F, 0x22, 0x3C, + 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, + 0x44, 0x0C, 0x74, 0x62, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x74, 0x9C, 0xFF, 0x0A, 0xDE, 0xD8, 0x1B, + 0xB0, 0x6A, 0xBE, 0xF5, 0xCA, 0xEE, 0x9C, 0x0B, 0x10, 0x17, 0x1F, 0xF1, 0xDB, 0x8F, 0x68, 0x7C, + 0x84, 0x01, 0x72, 0x7F, 0x8B, 0xDB, 0x0F, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, + 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x22, 0x04, 0x3A, 0xB6, 0x97, 0x56, 0x99, + 0xE0, 0x4B, 0x1F, 0x00, 0x00, 0xA0, 0x33, 0xFC, 0x37, 0x60, 0x6D, 0xFE, 0xE3, 0x86, 0xF1, 0x51, + 0xB9, 0xFD, 0xB0, 0xF1, 0xD1, 0xE0, 0xF6, 0xC3, 0xC5, 0x47, 0xF5, 0xF6, 0xE3, 0x41, 0xBB, 0xAF, + 0x8B, 0xE8, 0x08, 0x27, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, + 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x45, 0x40, 0x27, 0x37, 0xB6, 0x8C, 0x37, 0x61, 0x01, 0x00, + 0x80, 0xCE, 0xF2, 0x86, 0x97, 0x0D, 0x36, 0xBC, 0xFD, 0x08, 0xE2, 0xA3, 0xE6, 0xF6, 0x23, 0x88, + 0x8F, 0x9A, 0xDB, 0x8F, 0xF0, 0xD9, 0x8F, 0xEF, 0x36, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, + 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA0, + 0xD3, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0xF2, 0x07, 0x00, 0x00, 0x98, 0x7A, + 0xDE, 0xDE, 0xCB, 0x46, 0x1B, 0xDE, 0x7E, 0x6C, 0xBC, 0xA0, 0x26, 0x3E, 0xEA, 0x3E, 0x74, 0x30, + 0xE9, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, + 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x75, 0xF8, 0xEF, 0xF8, 0x16, 0xD8, 0x5F, 0x9B, 0xFD, 0xDF, 0xE1, + 0xC4, 0x6D, 0xEB, 0x83, 0x2F, 0x7F, 0x00, 0x00, 0x80, 0xA9, 0xE7, 0xED, 0x9E, 0x3F, 0xAE, 0x6F, + 0x3F, 0x6C, 0x7C, 0x84, 0xDF, 0x7A, 0x55, 0x73, 0xFB, 0x31, 0x33, 0xDD, 0xED, 0x87, 0x08, 0x0F, + 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0xB1, 0x78, 0x20, 0x14, 0x39, 0x71, 0x48, 0x2F, 0xEB, + 0xE4, 0xE1, 0xBF, 0xD3, 0xB3, 0xF1, 0x11, 0xCC, 0x3B, 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x80, + 0xCE, 0x30, 0x43, 0xFD, 0xB3, 0xCC, 0xEE, 0xB9, 0x32, 0x3E, 0x72, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, + 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, + 0x0F, 0xFF, 0x9D, 0xDE, 0x64, 0x7C, 0xF8, 0x01, 0x72, 0xF4, 0xE6, 0x93, 0xC1, 0x1F, 0x01, 0x00, + 0x00, 0x00, 0x53, 0xCB, 0x7F, 0x03, 0xD6, 0xF6, 0x8B, 0x6B, 0x03, 0x24, 0x8C, 0x0F, 0xF9, 0xEC, + 0x47, 0x83, 0xDB, 0x8F, 0x7B, 0xC5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, + 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x6A, 0xE3, + 0xC3, 0xDF, 0x91, 0x1B, 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0C, 0x33, 0xB2, 0x7C, 0x9D, 0xD9, + 0xFA, 0xC1, 0xC8, 0xED, 0x87, 0x8D, 0x8F, 0xD8, 0xED, 0x47, 0xED, 0x9B, 0xAF, 0x44, 0x7C, 0x3C, + 0x60, 0x47, 0x7C, 0x14, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, + 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x11, 0x1F, 0x6E, 0x2F, 0xF5, 0xF3, 0x26, 0x2C, 0x00, 0x00, 0xD0, + 0x19, 0xE6, 0xE0, 0xF2, 0xF5, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xEC, 0xC7, + 0xE9, 0x78, 0x80, 0xB8, 0x0F, 0x1D, 0x8C, 0xDF, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, + 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, + 0x84, 0x47, 0x38, 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x00, 0x00, 0x00, 0x60, + 0xEA, 0x78, 0xFB, 0xAE, 0x1E, 0xAD, 0x89, 0x8F, 0x24, 0xCF, 0x7E, 0xB8, 0x35, 0xBA, 0xFD, 0x10, + 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, + 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x88, 0x8E, 0xE8, 0xDC, 0x3F, 0x67, 0xBC, 0x09, 0x0B, 0x00, + 0x00, 0x74, 0x82, 0xB7, 0xF7, 0xF2, 0x93, 0x7E, 0x7C, 0x34, 0xBA, 0xFD, 0x88, 0xC6, 0x87, 0xBA, + 0xFD, 0xF8, 0x76, 0xE4, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, + 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x38, 0xC4, 0xBC, + 0xE3, 0xB7, 0x0F, 0x05, 0x7F, 0x0C, 0x00, 0x00, 0x00, 0x4C, 0x1D, 0x6F, 0xE7, 0x9C, 0xF4, 0xB7, + 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x8E, 0xF8, 0xC8, 0x71, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, + 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x36, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, + 0x82, 0x3F, 0x06, 0x00, 0x00, 0x00, 0xA6, 0x86, 0x39, 0x70, 0xFD, 0x12, 0x6F, 0xFB, 0x27, 0xB2, + 0xDF, 0x7E, 0xDC, 0x13, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, + 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x87, 0x46, 0xC3, + 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xD5, 0xCC, 0xC1, 0x65, 0x6B, 0xBD, 0xAD, 0x1F, 0x6E, 0xEF, + 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, + 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x30, 0x5A, 0xCD, 0xBD, 0x09, 0xEB, 0xF8, + 0x1D, 0x4B, 0x82, 0x3F, 0x0E, 0x00, 0x00, 0x00, 0x8A, 0x77, 0xFE, 0xE0, 0xD2, 0xF5, 0xDE, 0xA6, + 0x0B, 0x33, 0xDE, 0x7E, 0x10, 0x1F, 0xF9, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, + 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC4, 0x45, 0x92, 0xBD, 0x70, 0x0D, 0x6F, 0xC2, + 0x02, 0x00, 0x00, 0x53, 0xEB, 0xFC, 0xFE, 0x6B, 0x06, 0xB3, 0xDD, 0x7E, 0xCC, 0x90, 0xE1, 0xE1, + 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, + 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x8B, 0xA4, 0x7B, 0xFE, 0x0A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xA6, + 0xD6, 0xF9, 0xDD, 0x8B, 0x47, 0xA3, 0xB7, 0x1F, 0xD5, 0x00, 0x89, 0xC5, 0x47, 0xDD, 0xED, 0xC7, + 0xDD, 0xC4, 0x47, 0xFB, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, + 0xE4, 0xE1, 0xBF, 0xD3, 0x13, 0x51, 0x91, 0x72, 0xDE, 0xB1, 0xB5, 0xBC, 0x09, 0x0B, 0x00, 0x00, + 0x4C, 0x1D, 0x6F, 0xF7, 0x42, 0x79, 0xFB, 0x31, 0xE1, 0x02, 0xE4, 0xD1, 0xC8, 0xED, 0x47, 0x18, + 0x1F, 0x6E, 0xF7, 0xEB, 0x6F, 0xBD, 0x22, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, + 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x07, 0x45, 0xDA, 0x79, 0x47, 0x3E, + 0x3F, 0x1A, 0xFC, 0x71, 0x00, 0x00, 0x00, 0x50, 0x2C, 0x33, 0xD2, 0x3F, 0xDB, 0xDB, 0x31, 0x27, + 0xDD, 0xB3, 0x1F, 0x0F, 0xCE, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, + 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x98, 0xC8, 0xB4, 0xA3, + 0x6B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x1A, 0x66, 0xFF, 0xD2, 0x81, 0xF3, 0x5B, 0x3E, 0x6C, + 0x03, 0x24, 0xF2, 0xAD, 0x57, 0xCD, 0x6E, 0x3F, 0x1E, 0xB2, 0xF1, 0x21, 0x6E, 0x3F, 0x88, 0x8F, + 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, + 0xD3, 0x13, 0x11, 0xD1, 0xCE, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0x73, 0x76, 0xF0, 0xC7, 0x02, 0x00, + 0x00, 0x40, 0x71, 0xCE, 0xED, 0x5F, 0x7A, 0xD7, 0xF9, 0x4D, 0xEF, 0x9B, 0x7C, 0xF6, 0xA3, 0xE6, + 0xC1, 0xF3, 0x19, 0xB5, 0xCF, 0x7E, 0xB8, 0xF8, 0x78, 0xA0, 0xFE, 0xF6, 0x83, 0xF8, 0x48, 0x33, + 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, + 0x11, 0x10, 0xED, 0xCE, 0xBD, 0x09, 0xEB, 0xD8, 0x6D, 0x03, 0xC1, 0x1F, 0x0B, 0x00, 0x00, 0x00, + 0xC5, 0x39, 0x7F, 0x60, 0xD9, 0x86, 0x9A, 0x07, 0xCF, 0xA3, 0xB7, 0x1F, 0xD1, 0xF8, 0x78, 0xD8, + 0x86, 0x87, 0x0B, 0x90, 0xEF, 0xD4, 0xDE, 0x7E, 0x10, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x21, 0x8F, 0xF1, + 0x26, 0x2C, 0x00, 0x00, 0x30, 0x55, 0xCE, 0xEF, 0x5E, 0x32, 0xEA, 0xC7, 0x47, 0x83, 0xDB, 0x0F, + 0x17, 0x1F, 0xA7, 0xC2, 0xF8, 0x70, 0xB7, 0x1F, 0x7F, 0x4D, 0x7C, 0x64, 0x9B, 0x0A, 0x87, 0x3C, + 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x87, 0x1C, + 0xE7, 0x9D, 0xB8, 0x6D, 0x30, 0xF8, 0x63, 0x01, 0x00, 0x00, 0xA0, 0x38, 0xE7, 0x76, 0x2E, 0x3A, + 0x59, 0x73, 0xFB, 0x11, 0xC4, 0x47, 0xF5, 0xD9, 0x8F, 0x30, 0x3E, 0x62, 0xB7, 0x1F, 0xC4, 0x47, + 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, + 0xE9, 0xE9, 0x68, 0xC8, 0x73, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0xDE, 0xF9, + 0xED, 0x73, 0xAA, 0xF1, 0x51, 0xF7, 0xA1, 0x83, 0x8F, 0xCC, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, + 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, + 0xE9, 0x60, 0xC8, 0x7D, 0x47, 0x3F, 0xCF, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB1, 0xCE, 0xEE, 0x5F, + 0x3A, 0x70, 0x6E, 0xCB, 0x27, 0x63, 0xB7, 0x1F, 0x33, 0x2B, 0xCF, 0x7E, 0x44, 0xE3, 0xC3, 0xED, + 0xDE, 0xCA, 0xED, 0x07, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, + 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x14, 0x8A, 0x9A, 0x7B, 0x13, 0xD6, 0xD8, 0x17, + 0x67, 0x05, 0x7F, 0x3C, 0x00, 0x00, 0x00, 0xE4, 0xEF, 0xDC, 0xDE, 0xE5, 0xEB, 0xCE, 0x6D, 0xFA, + 0x48, 0xEC, 0xF6, 0x63, 0x46, 0x35, 0x3E, 0xAA, 0x01, 0xF2, 0x23, 0x3B, 0xE2, 0x23, 0xE5, 0x54, + 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x44, + 0x24, 0x14, 0xB9, 0x17, 0xAF, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x58, 0xE7, 0xF7, 0x2E, 0x5F, + 0x5F, 0xF7, 0xEC, 0xC7, 0x8F, 0x27, 0x03, 0xA4, 0x7A, 0xFB, 0xF1, 0xED, 0x0B, 0x88, 0x8F, 0x54, + 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, + 0x13, 0x81, 0x50, 0xF4, 0x5E, 0xB8, 0xCA, 0x78, 0xBF, 0xB8, 0xFD, 0xAE, 0xE0, 0x8F, 0x07, 0x00, + 0x00, 0x80, 0xFC, 0x9D, 0xDB, 0x7D, 0xD5, 0x50, 0xCD, 0x9B, 0xAF, 0xC2, 0xF8, 0x88, 0x06, 0xC8, + 0x8F, 0x66, 0x10, 0x1F, 0xA9, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, + 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x60, 0x8A, 0xE6, 0x1D, 0xBF, 0x6D, 0x43, 0xF0, 0xC7, + 0x03, 0x00, 0x00, 0x40, 0xFE, 0xCE, 0xED, 0xB8, 0x6C, 0x6C, 0xF2, 0xF6, 0xE3, 0x02, 0x79, 0xFB, + 0xF1, 0x76, 0xE4, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x06, 0x53, 0x35, 0xDE, 0x84, 0x05, 0x00, + 0x00, 0x0A, 0x75, 0x76, 0xDB, 0xFC, 0xE0, 0xF6, 0xC3, 0xC6, 0x87, 0x78, 0xF6, 0xE3, 0xED, 0x1F, + 0x4C, 0xDE, 0x7E, 0x10, 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, + 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0xA3, 0x60, 0x2A, 0xE7, 0x1D, 0xBD, 0x79, 0x3C, 0xF8, + 0xE3, 0x01, 0x00, 0x00, 0x20, 0x5F, 0x66, 0xA8, 0x7F, 0xF6, 0xD9, 0xCD, 0x97, 0x04, 0xF1, 0x51, + 0x7B, 0xFB, 0x71, 0x2A, 0xBC, 0xFD, 0xF8, 0x66, 0xE5, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, + 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x04, + 0x53, 0xBE, 0x97, 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x8C, 0xB3, 0x43, 0x4B, 0x07, 0xDE, + 0xDD, 0xF8, 0xE1, 0x6A, 0x80, 0x9C, 0xB6, 0x01, 0x52, 0xF3, 0xEC, 0xC7, 0xF7, 0x2B, 0xB7, 0x1F, + 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, + 0xF0, 0xDF, 0xE9, 0x89, 0x10, 0xE8, 0xD4, 0xC6, 0x96, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x0C, + 0x1B, 0x20, 0xEB, 0x27, 0x06, 0xDF, 0x57, 0x73, 0xFB, 0x11, 0x7D, 0xFE, 0xC3, 0xDD, 0x7E, 0x10, + 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, + 0x7F, 0xA7, 0x27, 0x22, 0xA0, 0x93, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0x63, + 0x02, 0x00, 0x00, 0x20, 0x3F, 0xEF, 0xEE, 0x59, 0x3A, 0xE8, 0xDF, 0x7E, 0x88, 0xF8, 0x70, 0xB7, + 0x1F, 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, + 0xF2, 0xF0, 0xDF, 0xE9, 0x89, 0x00, 0xE8, 0xF4, 0xDC, 0x3F, 0x17, 0x27, 0x6E, 0x5B, 0x1F, 0xFC, + 0x31, 0x01, 0x00, 0x00, 0x90, 0x9F, 0x89, 0x6D, 0x8B, 0x47, 0xEB, 0xDE, 0x7C, 0x15, 0xDE, 0x7E, + 0xDC, 0x4D, 0x7C, 0x34, 0x9F, 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xE9, 0x65, + 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xE2, 0xF0, 0xDF, 0x25, 0xF3, 0x8E, 0xAF, 0xE5, 0x4D, 0x58, 0x00, + 0x00, 0x20, 0x7F, 0x13, 0x5B, 0xFA, 0xC6, 0xE5, 0xC3, 0xE7, 0xF7, 0xBB, 0x6F, 0xBD, 0x22, 0x3E, + 0x1A, 0x4F, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, + 0x4E, 0x4F, 0x1F, 0xFC, 0xBB, 0x65, 0xDE, 0xD1, 0x9B, 0x4F, 0x06, 0x7F, 0x4C, 0x00, 0x00, 0x00, + 0xE4, 0xC3, 0x0C, 0xF5, 0xCF, 0x7A, 0xF7, 0x99, 0x39, 0x95, 0xF8, 0xB0, 0x8B, 0x3E, 0x7C, 0xFE, + 0xD6, 0x5F, 0x11, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, + 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFD, 0x5D, 0xB5, 0x97, 0x56, 0x9A, 0xE0, 0x8F, 0x0A, + 0x00, 0x00, 0x80, 0x7C, 0xB8, 0x37, 0x60, 0x4D, 0x6C, 0xFC, 0x98, 0x0D, 0x90, 0x0B, 0xCC, 0xE9, + 0x47, 0xEC, 0xDC, 0xED, 0x87, 0x0B, 0x90, 0xFB, 0x6D, 0x80, 0x10, 0x1F, 0x0D, 0xA6, 0xC2, 0x21, + 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xFB, + 0xDD, 0x38, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x7C, 0xDD, 0xC4, 0x13, 0x1F, + 0x30, 0xA7, 0xFD, 0x00, 0x09, 0xBE, 0xFD, 0xEA, 0xE1, 0x99, 0xFE, 0xED, 0x07, 0xF1, 0xA1, 0xA6, + 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, + 0x0E, 0xFA, 0xDD, 0x3A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x74, 0x7D, 0x78, + 0xFB, 0x71, 0xCA, 0xCD, 0xDD, 0x7E, 0x7C, 0x67, 0x06, 0xF1, 0x21, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF9, 0xDD, 0x3C, + 0xF7, 0xCF, 0x3D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x79, 0x9A, 0xD8, 0x79, 0xD5, 0x68, 0xF5, 0xDB, + 0xAF, 0xDC, 0x0D, 0x88, 0x7B, 0xF6, 0xE3, 0x6B, 0xC4, 0x47, 0xFD, 0x54, 0x38, 0xE4, 0x31, 0x15, + 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, 0x01, 0xBF, 0x07, 0xC6, + 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xAE, 0x26, 0xB6, 0x5D, 0x76, 0xB2, 0x7A, 0x03, 0xF2, 0xF0, 0x0C, + 0xF3, 0xF6, 0x7D, 0xC1, 0xED, 0x87, 0x8D, 0x8F, 0x3F, 0x10, 0x1F, 0xC1, 0x54, 0x38, 0xE4, 0x31, + 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0xE1, 0xBE, 0x17, + 0xE6, 0x1D, 0x59, 0x33, 0x16, 0xFC, 0x71, 0x01, 0x00, 0x00, 0xD0, 0xBE, 0x09, 0xFF, 0x0D, 0x58, + 0x93, 0xB7, 0x1F, 0x6F, 0x7E, 0x6D, 0xF2, 0xE6, 0xE3, 0x0D, 0xE2, 0xC3, 0x4E, 0x85, 0x43, 0x1E, + 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xEC, 0x7B, + 0x66, 0x47, 0x6E, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x20, 0x1F, 0x13, 0x43, 0xD7, 0x2F, 0x99, 0x78, + 0xFA, 0x13, 0xE6, 0xCC, 0xA3, 0x95, 0xCF, 0xFF, 0x70, 0xB7, 0x1F, 0x95, 0xF8, 0xB8, 0xC0, 0xBF, + 0xF9, 0x78, 0x83, 0xF8, 0x28, 0x68, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, + 0xDF, 0xE9, 0x89, 0x03, 0x7D, 0xAF, 0xED, 0xA5, 0x7E, 0xF7, 0x20, 0xFA, 0x92, 0xE0, 0x8F, 0x0D, + 0x00, 0x00, 0x80, 0xEC, 0xCE, 0x0C, 0x2D, 0x5B, 0x3B, 0xF1, 0xE4, 0x87, 0x2B, 0x9F, 0x01, 0xF2, + 0x60, 0xE5, 0xB5, 0xBB, 0xD5, 0xDB, 0x8F, 0xAF, 0xD9, 0xF8, 0xF8, 0x47, 0xE2, 0x23, 0xFF, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF3, 0xBD, 0x38, + 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x03, 0x00, 0x00, 0x20, 0x3B, 0xF7, 0x06, + 0xAC, 0x89, 0xC7, 0x2F, 0xF2, 0x03, 0xE4, 0xED, 0x6F, 0x55, 0x9E, 0xFB, 0x20, 0x3E, 0xDC, 0x54, + 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, + 0x41, 0xBE, 0x57, 0xE7, 0xBE, 0x26, 0x78, 0x13, 0x16, 0x00, 0x00, 0xC8, 0xC3, 0xD9, 0x5D, 0xD7, + 0x0C, 0x4E, 0x3C, 0x36, 0xC3, 0x9C, 0x71, 0xCF, 0x7E, 0x04, 0x6F, 0xBD, 0xFA, 0xC3, 0x7A, 0xE2, + 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, + 0xF1, 0x3D, 0xBB, 0xF9, 0xFE, 0xBC, 0xE3, 0xB7, 0x0D, 0x05, 0x7F, 0x6C, 0x00, 0x00, 0x00, 0x64, + 0xF7, 0xEE, 0xB6, 0xC5, 0xA3, 0x13, 0x8F, 0xCF, 0x30, 0xEF, 0x7C, 0xBB, 0x72, 0xFB, 0xF1, 0xE6, + 0x5F, 0x5D, 0x44, 0x7C, 0x14, 0x32, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, + 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x57, 0x89, 0x0F, 0x3F, 0x40, 0x8E, 0xDC, 0xCC, 0x9B, 0xB0, + 0x00, 0x00, 0x40, 0xFB, 0xCE, 0x6D, 0x5F, 0x60, 0x26, 0x1E, 0xB9, 0xC0, 0xBC, 0xE5, 0x5E, 0xBB, + 0xFB, 0xD7, 0xC4, 0x47, 0x31, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, + 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0xE1, 0xEF, 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, + 0x00, 0xB4, 0xC7, 0x0C, 0x5D, 0x3B, 0xFB, 0xDC, 0xB6, 0x4B, 0xCD, 0x3B, 0xDF, 0xB4, 0x01, 0xF2, + 0x75, 0xE2, 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, + 0xA7, 0x0E, 0xF1, 0xBD, 0xBA, 0x58, 0x7C, 0xB8, 0xBD, 0xB4, 0xC2, 0x98, 0x97, 0xBF, 0x38, 0x3B, + 0xF8, 0xE3, 0x03, 0x00, 0x00, 0x20, 0xBD, 0xB3, 0xFB, 0x97, 0x0E, 0xBC, 0xFB, 0xD8, 0x87, 0xCC, + 0xDB, 0x77, 0x5F, 0x64, 0xCE, 0x13, 0x1F, 0x05, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, + 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x89, 0xF8, 0x70, 0x7B, 0xE1, 0x6A, 0x63, + 0x8E, 0xDD, 0x36, 0x10, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDE, 0x99, 0x5D, 0x9F, 0xBB, 0xEB, + 0xD4, 0x86, 0x0F, 0x98, 0xF3, 0xFF, 0x44, 0x7C, 0xE4, 0x3F, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, + 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x27, 0xC2, 0x23, 0x98, 0xF7, 0xAF, + 0x4B, 0xCC, 0xE9, 0x9F, 0xDD, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x76, 0xAF, 0x3D, 0x70, 0xED, + 0x86, 0xF1, 0xDD, 0xAB, 0xCD, 0xD9, 0x17, 0xBF, 0x44, 0x7C, 0xE4, 0x3A, 0x15, 0x09, 0x45, 0x4D, + 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0xA7, 0xC3, 0xC3, 0xED, + 0xD4, 0xB3, 0xF3, 0xCC, 0xEF, 0x77, 0xCC, 0x31, 0xBF, 0xDB, 0x77, 0xD3, 0x60, 0xF0, 0xC7, 0x07, + 0x00, 0x00, 0x40, 0x7A, 0xAF, 0xEF, 0xB9, 0x75, 0xF8, 0xF7, 0x07, 0x6F, 0x35, 0xBF, 0xDF, 0xB7, + 0xD2, 0xBC, 0x79, 0xE0, 0x32, 0x73, 0xFE, 0x9F, 0x55, 0x54, 0x24, 0x9D, 0x08, 0x87, 0x3C, 0x26, + 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, + 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0x4E, 0x87, 0xC7, 0x99, 0xBF, 0xEB, 0x33, 0xE3, 0xBB, + 0xE6, 0x9A, 0xDF, 0x6D, 0xB3, 0xF1, 0xE1, 0xB6, 0x67, 0x39, 0xAF, 0xE2, 0x05, 0x00, 0x00, 0xD9, + 0xFD, 0xF3, 0xFF, 0xFE, 0x17, 0x17, 0xFE, 0x76, 0xFB, 0xEA, 0xFB, 0x7E, 0xB7, 0x6D, 0xF1, 0x5B, + 0xBF, 0xDF, 0xB9, 0xD8, 0xB8, 0xBD, 0x7D, 0xE8, 0x72, 0xFF, 0x5B, 0x2D, 0x74, 0x64, 0x34, 0x9A, + 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, + 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0xAE, 0x3E, 0x3C, 0xCE, 0xFE, + 0x43, 0x9F, 0x79, 0x73, 0xEF, 0x64, 0x78, 0xBC, 0xBE, 0x75, 0xCE, 0xF8, 0xEF, 0xB6, 0x5D, 0xBA, + 0x7E, 0xB4, 0xFF, 0x3D, 0x7F, 0x14, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDD, 0x7F, 0xBF, 0xFB, + 0x33, 0x17, 0xBF, 0xB6, 0x79, 0xF1, 0x96, 0x30, 0x42, 0xC6, 0x77, 0x2F, 0x36, 0xA7, 0xFF, 0xC6, + 0x1E, 0xD4, 0x65, 0x6C, 0xC4, 0x27, 0xC2, 0x21, 0x8F, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, 0xDF, + 0xAB, 0xAB, 0x0D, 0x8F, 0xF3, 0xFF, 0x34, 0xDF, 0xBC, 0xB5, 0x3F, 0x72, 0xE3, 0x61, 0xF7, 0xEA, + 0x33, 0x73, 0x7E, 0x34, 0x3E, 0xF4, 0xA9, 0x59, 0xC1, 0x1F, 0x17, 0x00, 0x00, 0x00, 0xF9, 0xF9, + 0xEF, 0xDF, 0x5D, 0xF2, 0x99, 0xD7, 0xB6, 0x2C, 0xFA, 0x59, 0x18, 0x22, 0x6F, 0xEC, 0xB9, 0xCC, + 0x4C, 0xFC, 0xBD, 0x0B, 0x02, 0x15, 0x1E, 0x6E, 0xB1, 0x68, 0xC8, 0x6B, 0x32, 0x1C, 0xF2, 0x98, + 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, + 0x3A, 0xC4, 0xF7, 0xEA, 0x26, 0xC3, 0xC3, 0xFB, 0xE7, 0xF9, 0xE6, 0x9D, 0x91, 0x79, 0x35, 0xE1, + 0xF1, 0xDA, 0xE6, 0x4B, 0xF7, 0x8F, 0x6F, 0xE9, 0xE3, 0xB5, 0xBB, 0x00, 0x00, 0xA0, 0x78, 0xFF, + 0xEB, 0xA1, 0xCB, 0xBE, 0xF8, 0xBB, 0x6D, 0x8B, 0x7E, 0x19, 0x86, 0x88, 0x7B, 0x3E, 0xE4, 0xEC, + 0x4F, 0x5D, 0x1C, 0x10, 0x1F, 0xF5, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, + 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0x51, 0x7D, 0xC0, 0x3C, 0x08, 0x8F, 0xD7, + 0xB7, 0x5E, 0x3A, 0xF6, 0xDA, 0x96, 0x4B, 0x79, 0xDD, 0x2E, 0x00, 0x00, 0x98, 0x5A, 0xA3, 0xFD, + 0xFD, 0x7F, 0xF4, 0xAB, 0x27, 0x2E, 0xFB, 0x3F, 0xA2, 0xCF, 0x87, 0xBC, 0x35, 0xEC, 0x1E, 0x54, + 0x17, 0xD1, 0x90, 0xD7, 0x64, 0x38, 0xE4, 0x31, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x55, 0xC2, 0x23, 0xFE, + 0x80, 0xB9, 0x8D, 0x8E, 0x5F, 0xBE, 0xBE, 0x7D, 0xEE, 0xBA, 0xE0, 0x8F, 0x00, 0x00, 0x00, 0x80, + 0xCE, 0xF8, 0xD5, 0x23, 0x57, 0x7E, 0xE0, 0x37, 0x4F, 0x2E, 0xDE, 0x30, 0x19, 0x22, 0x8B, 0xCC, + 0xE9, 0xBF, 0xB9, 0xCC, 0x78, 0xFF, 0x2A, 0x02, 0xA2, 0x9D, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, + 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, + 0xDF, 0xAB, 0x6B, 0xFC, 0x80, 0x39, 0xCF, 0x79, 0x00, 0x00, 0x80, 0xAE, 0x72, 0xF2, 0x91, 0xC5, + 0xF3, 0x5F, 0x7D, 0x66, 0xF1, 0x0E, 0x17, 0x20, 0x6E, 0xE3, 0xBB, 0x17, 0x99, 0x33, 0x7F, 0x67, + 0x0F, 0xE2, 0x2A, 0x26, 0xD2, 0x4E, 0x86, 0x43, 0x1E, 0x8B, 0x47, 0x43, 0x5E, 0x53, 0x91, 0x50, + 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x73, 0xEA, 0x01, + 0xF3, 0xDF, 0x6D, 0xBD, 0x74, 0xF0, 0xBF, 0x7D, 0x67, 0xDE, 0x07, 0x82, 0x2F, 0x73, 0x00, 0x00, + 0x80, 0xEE, 0xF3, 0xAB, 0x8D, 0x8B, 0xD6, 0xBC, 0xFA, 0xCC, 0xC2, 0x9F, 0x87, 0x21, 0xF2, 0xC6, + 0x9E, 0xC5, 0xE6, 0xDD, 0x7F, 0xB0, 0x87, 0x7D, 0x15, 0x16, 0x49, 0x26, 0xC3, 0x21, 0x8F, 0xA9, + 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, + 0x83, 0x7C, 0xAF, 0xCD, 0xFB, 0xE7, 0x05, 0x75, 0x0F, 0x98, 0xDB, 0x8D, 0xFE, 0x7F, 0x8F, 0x5E, + 0x3A, 0x27, 0xF8, 0xB2, 0x06, 0x00, 0x00, 0xE8, 0x6E, 0xFE, 0xF3, 0x21, 0x83, 0x8B, 0xFF, 0xE2, + 0x77, 0xDB, 0x16, 0xFE, 0x32, 0x0C, 0x91, 0x37, 0x0F, 0x2C, 0x36, 0x67, 0x7F, 0x6A, 0x0F, 0xFE, + 0x2A, 0x32, 0x1A, 0x4D, 0x86, 0x43, 0x1E, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, + 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x87, 0xF9, 0x5E, 0xDB, 0xE9, 0xBF, 0xE9, 0xAB, + 0x79, 0xC0, 0xFC, 0xB5, 0x67, 0xE6, 0x1C, 0xE3, 0x01, 0x73, 0x00, 0x00, 0xD0, 0xB3, 0x6C, 0x88, + 0xFC, 0xBB, 0x57, 0x37, 0x2F, 0xBA, 0xE7, 0x77, 0xDB, 0x16, 0xBD, 0x15, 0x86, 0xC8, 0xDB, 0x87, + 0x12, 0x3E, 0xA8, 0x2E, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, + 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xC3, 0x7C, 0x2F, 0x6D, 0xE2, 0xEF, 0xE7, 0xF3, + 0x80, 0x39, 0x00, 0x00, 0x28, 0xAF, 0x93, 0xF7, 0x2E, 0xFC, 0xC8, 0x2B, 0x9B, 0x16, 0x3F, 0x1A, + 0x46, 0x88, 0x7B, 0x3E, 0xA4, 0xE9, 0x83, 0xEA, 0x32, 0x1C, 0xF2, 0x98, 0x0A, 0x87, 0x3C, 0xA6, + 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x3E, 0xD0, 0xF7, 0xCA, + 0xCE, 0xFE, 0xC3, 0x7C, 0xF3, 0xE6, 0x5E, 0xF7, 0xED, 0x56, 0x95, 0xF8, 0xE0, 0x01, 0x73, 0x00, + 0x00, 0x50, 0x6A, 0xFF, 0xE3, 0xFE, 0xCF, 0x2C, 0x7A, 0x75, 0xF3, 0xA2, 0xE7, 0xA2, 0x21, 0x32, + 0xF1, 0xF7, 0x36, 0x0C, 0x88, 0x8F, 0x84, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, + 0x7D, 0xA8, 0xEF, 0x85, 0x9D, 0xFF, 0xA7, 0x05, 0xE6, 0xED, 0x83, 0x7D, 0x41, 0x78, 0x04, 0x37, + 0x1F, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0xA6, 0x8B, 0x5F, 0x3E, 0xB6, 0xF8, 0x96, 0xD7, 0xB7, 0x2E, + 0x7C, 0x39, 0x0C, 0x11, 0xF7, 0xA0, 0xBA, 0xFF, 0x7C, 0x88, 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, + 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xF6, + 0xDD, 0x3E, 0xF7, 0x80, 0xF9, 0xA9, 0x67, 0xA3, 0xE1, 0xE1, 0xC7, 0x07, 0x0F, 0x98, 0x03, 0x00, + 0x80, 0xE9, 0xC7, 0x3D, 0xA8, 0xFE, 0xDB, 0xA7, 0x17, 0x7F, 0xF5, 0xF5, 0xAD, 0x8B, 0x7E, 0xE3, + 0x22, 0xE4, 0x77, 0x3B, 0x16, 0x9A, 0x37, 0xF7, 0x2F, 0x32, 0xE7, 0xFE, 0xD1, 0x1D, 0xEC, 0x55, + 0x44, 0x64, 0x5D, 0x3C, 0x1A, 0xF2, 0x9A, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, + 0xFC, 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xED, 0xAB, 0x3C, 0x60, 0x3E, 0x19, 0x1E, 0xAF, 0x3D, 0x33, + 0x97, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x7E, 0xF5, 0xC8, 0xBC, 0x0F, 0xFC, 0xE6, 0xE9, 0x85, 0xF7, + 0xBD, 0xBE, 0x75, 0xC1, 0x5B, 0x2E, 0x42, 0xDC, 0xDE, 0x1E, 0x59, 0x6C, 0xBC, 0x7F, 0x51, 0x31, + 0x91, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, + 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xCD, 0xAB, 0x3C, 0x60, 0x1E, 0x3E, 0xE7, 0x61, 0xC3, 0x63, 0xCB, + 0x5C, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x88, 0x1B, 0xFB, 0x4F, 0x9F, 0xB9, 0xF8, 0x95, 0xCD, 0x0B, + 0xB7, 0x84, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCD, 0xA9, 0xE7, 0xDA, 0x09, 0x11, 0x15, 0x0E, 0x79, + 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC0, 0xEF, + 0xD6, 0xD5, 0x3E, 0x60, 0x3E, 0xD7, 0xBC, 0xBE, 0x75, 0xEE, 0xB8, 0xFD, 0x91, 0x07, 0xCC, 0x01, + 0x00, 0x00, 0x9A, 0xF9, 0x9F, 0x0F, 0x2D, 0x5A, 0xFA, 0xEA, 0xE6, 0x85, 0x3F, 0x0B, 0x43, 0x64, + 0x7C, 0x68, 0x91, 0x39, 0x33, 0xEA, 0x0E, 0xFE, 0x2A, 0x32, 0x1A, 0x2D, 0x1E, 0x0D, 0x79, 0x4D, + 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC8, 0xEF, 0xC6, + 0xD5, 0x3F, 0x60, 0x6E, 0xB7, 0x75, 0x0E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA4, 0xF1, 0xBF, 0x1E, + 0x5A, 0xF0, 0xC5, 0xD7, 0xB6, 0x2E, 0xF8, 0x65, 0x18, 0x22, 0x6F, 0xEC, 0x5D, 0x64, 0xCE, 0xFE, + 0xC4, 0x45, 0x80, 0x0A, 0x8E, 0xE8, 0xE2, 0xD1, 0x90, 0xD7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, + 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x07, 0xFD, 0x6E, 0x9B, 0x7E, 0xC0, 0x7C, 0x2E, 0x0F, + 0x98, 0x03, 0x00, 0x00, 0x64, 0xE5, 0x1E, 0x54, 0xFF, 0xF5, 0xC6, 0x45, 0x7F, 0x19, 0x7D, 0x3E, + 0xC4, 0x3D, 0xA8, 0x7E, 0xFE, 0x67, 0x2A, 0x3C, 0xDC, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, + 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0x61, 0xBF, 0xDB, 0xC6, 0x03, 0xE6, + 0x00, 0x00, 0x00, 0x05, 0x72, 0x0F, 0xAA, 0xFF, 0xFA, 0xC9, 0x85, 0x1B, 0xC2, 0x08, 0x71, 0x7B, + 0xE7, 0x70, 0xFC, 0xF9, 0x10, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, + 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xD8, 0xEF, 0xA6, 0xF1, 0x80, 0x39, 0x00, 0x00, 0xC0, 0x14, + 0x3A, 0xF9, 0xC8, 0xE2, 0xF9, 0xBF, 0xDD, 0xB4, 0x60, 0x47, 0x18, 0x21, 0xE1, 0x83, 0xEA, 0x3A, + 0x1C, 0xF2, 0x58, 0x3C, 0x10, 0x8A, 0x9C, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, + 0x03, 0x7F, 0xB7, 0x8C, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x3A, 0xE8, 0x57, 0x1B, 0x17, 0xAD, 0x79, + 0x65, 0xD3, 0x82, 0x9F, 0x57, 0x42, 0x64, 0x81, 0x19, 0x1F, 0x5A, 0x68, 0xCE, 0x8C, 0xBA, 0x43, + 0xBC, 0x8A, 0x88, 0xAC, 0x8B, 0x07, 0x42, 0x91, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, + 0x3D, 0x7D, 0xE8, 0xEF, 0x86, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x40, 0x97, 0xA8, 0x7C, 0x90, 0xE1, + 0xC2, 0xAF, 0xBE, 0xB6, 0x75, 0xFE, 0x2F, 0x5D, 0x84, 0xB8, 0xBD, 0xB9, 0x7F, 0xA1, 0x39, 0xFB, + 0x13, 0x77, 0xA0, 0x57, 0x41, 0x91, 0x66, 0xF1, 0x40, 0x28, 0x72, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, + 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFE, 0x9D, 0x5E, 0xA3, 0x07, 0xCC, 0x4F, 0x7E, 0xE7, 0x53, 0xF3, + 0x83, 0x2F, 0x01, 0x00, 0x00, 0x00, 0x74, 0xC2, 0x60, 0xFF, 0xA7, 0xFE, 0xDD, 0xAB, 0x9B, 0x16, + 0xDC, 0xF3, 0xFA, 0xD6, 0xF9, 0x6F, 0x85, 0x21, 0xF2, 0xF6, 0x88, 0x7B, 0x50, 0x5D, 0x85, 0x45, + 0x92, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFF, + 0x9D, 0x9E, 0x7A, 0xC0, 0xFC, 0xB7, 0x1B, 0xE7, 0xDE, 0x10, 0xFC, 0x23, 0x0F, 0x00, 0x00, 0x80, + 0x6E, 0xF0, 0xFF, 0x7E, 0x63, 0xF1, 0x87, 0x7F, 0xF3, 0xD4, 0x82, 0x47, 0xC3, 0x08, 0x71, 0x3B, + 0xF5, 0xDC, 0x22, 0xE3, 0xFD, 0x8B, 0x8A, 0x8C, 0x46, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, + 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xFE, 0x3B, 0xB9, 0xF8, 0x03, 0xE6, 0xEE, 0x39, 0x8F, + 0x57, 0x9F, 0xBE, 0xF4, 0x3F, 0x06, 0xFF, 0x88, 0x03, 0x00, 0x00, 0xA0, 0x1B, 0xFD, 0x8F, 0xFB, + 0x17, 0x2C, 0x7A, 0x75, 0xF3, 0x82, 0x9F, 0x85, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCC, 0xE9, 0xBF, + 0x75, 0x07, 0x61, 0x15, 0x1C, 0xD1, 0xA9, 0x48, 0x28, 0x6A, 0xB1, 0x03, 0x7A, 0x99, 0x27, 0x0F, + 0xFF, 0x9D, 0x9E, 0x0E, 0x80, 0x4E, 0xAD, 0xEE, 0x01, 0xF3, 0xCD, 0x73, 0xDE, 0xB2, 0x3F, 0xF2, + 0x80, 0x39, 0x00, 0x00, 0x40, 0x2F, 0xF9, 0xE5, 0xC3, 0xF3, 0x6F, 0x79, 0x75, 0xCB, 0x82, 0x97, + 0xC3, 0x10, 0x71, 0x0F, 0xAA, 0x4F, 0xFC, 0x57, 0x77, 0xF8, 0x27, 0x3E, 0xA6, 0x6C, 0xF2, 0xF0, + 0xDF, 0xE9, 0xE9, 0x08, 0xE8, 0xC4, 0x1A, 0x3D, 0x60, 0x3E, 0xBE, 0xA5, 0x6F, 0x76, 0xF0, 0x8F, + 0x31, 0x00, 0x00, 0x00, 0x7A, 0x49, 0xF8, 0xA0, 0x7A, 0xF4, 0xF9, 0x10, 0xF7, 0xA0, 0xFA, 0xB9, + 0x7F, 0x74, 0x21, 0x40, 0x7C, 0x14, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x74, 0x08, 0x4C, 0xF5, 0x1A, + 0x3D, 0x60, 0xFE, 0xEB, 0xC7, 0x3E, 0x7D, 0x55, 0xF0, 0x8F, 0x2E, 0x00, 0x00, 0x00, 0x7A, 0x99, + 0xFB, 0x20, 0xC3, 0xDF, 0x6C, 0x9C, 0x7F, 0x5F, 0xED, 0x83, 0xEA, 0x0B, 0xCD, 0xF9, 0x9F, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x63, 0x60, 0xAA, 0x17, + 0x7F, 0xC0, 0xFC, 0xF5, 0x6D, 0x73, 0x4E, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x40, 0x49, 0xFD, 0xDB, + 0x83, 0x7D, 0x7D, 0xAF, 0x6C, 0x5E, 0xB0, 0xA5, 0x12, 0x21, 0xF3, 0xCD, 0xEF, 0x77, 0xCD, 0x37, + 0xA7, 0x9E, 0x5B, 0x68, 0xBC, 0x7F, 0x51, 0xC1, 0x90, 0xE7, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, + 0xFF, 0x4E, 0x4F, 0xC7, 0xC0, 0x54, 0x8E, 0x07, 0xCC, 0x01, 0x00, 0x00, 0xA6, 0xB1, 0xFF, 0xF9, + 0xD0, 0xBC, 0xA5, 0xAF, 0x6E, 0xEE, 0xFB, 0x99, 0x8B, 0x90, 0x30, 0x44, 0xCE, 0x8C, 0xBA, 0x03, + 0xB4, 0x8A, 0x87, 0x76, 0x17, 0x3B, 0xA0, 0x97, 0x79, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x20, 0x98, + 0xAA, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xAA, 0x7E, 0xF5, 0x58, 0xDF, 0x5F, 0x54, 0x3E, 0xC8, + 0xB0, 0x12, 0x22, 0xE3, 0x43, 0xF6, 0xC0, 0xF8, 0x13, 0x77, 0x98, 0x56, 0x21, 0x91, 0x65, 0xB1, + 0x03, 0x7A, 0x99, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x82, 0xA9, 0x18, 0x0F, 0x98, 0x03, 0x00, + 0x00, 0x40, 0x72, 0x0F, 0xAA, 0xFF, 0x7A, 0x63, 0xDF, 0x5F, 0xBE, 0xBE, 0xB5, 0xEF, 0xAD, 0x30, + 0x44, 0xDE, 0xDC, 0x6F, 0x0F, 0x90, 0x6D, 0x3F, 0x1F, 0x22, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, + 0x77, 0x7A, 0x3A, 0x0C, 0x8A, 0x1E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x20, 0x11, 0xFF, 0x41, 0xF5, + 0xA7, 0xFA, 0x1E, 0x0D, 0x23, 0xC4, 0xCD, 0x3D, 0xA8, 0x9E, 0xED, 0xF9, 0x10, 0x71, 0x48, 0x2F, + 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x71, 0x50, 0xF4, 0xCE, 0xFC, 0xDD, 0x7C, 0x1E, 0x30, 0x07, + 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x41, 0xF5, 0x57, 0x9F, 0x99, 0x3F, 0x12, 0x46, 0x48, 0xFA, 0x07, + 0xD5, 0xC5, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x41, 0x91, 0x73, 0xCF, 0x79, + 0xF0, 0x80, 0x39, 0x00, 0x00, 0x00, 0xDA, 0xF2, 0xAB, 0x27, 0xFA, 0xD6, 0x44, 0x1F, 0x54, 0x77, + 0xCF, 0x87, 0xB4, 0x7E, 0x50, 0x3D, 0x76, 0x40, 0x2F, 0xF3, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x81, + 0x50, 0xD4, 0xCE, 0xFD, 0x94, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x90, 0xA3, 0xCA, 0x07, 0x19, 0xF6, + 0x7D, 0x35, 0xFA, 0xA0, 0xBA, 0x7B, 0x3E, 0x44, 0x3F, 0xA8, 0x1E, 0x3B, 0xA0, 0x97, 0x79, 0xF2, + 0xF0, 0xDF, 0xE9, 0xE9, 0x48, 0x28, 0x62, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x42, 0xB9, 0xE7, + 0x43, 0x5E, 0xDD, 0xD4, 0x77, 0x4F, 0xF4, 0x41, 0xF5, 0xB7, 0x0E, 0x46, 0x1F, 0x54, 0x17, 0x87, + 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0A, 0x79, 0x2F, 0x7C, 0xC0, 0x3C, 0xFA, 0x9C, + 0x87, 0x1D, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA0, 0x18, 0x47, 0xBF, 0xB1, 0xF8, 0xC3, 0xAF, 0x6C, + 0xEE, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0x3B, 0x87, 0xEC, 0xC1, 0xF4, 0x5F, 0xC4, 0x41, 0xBD, 0x8C, + 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x42, 0xDE, 0x53, 0x0F, 0x98, 0xFF, 0xFA, 0xE1, 0x4B, 0x6F, + 0x0E, 0xFE, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xE3, 0x3F, 0xA8, 0xEE, 0x9E, 0x0F, 0xD9, 0xDE, + 0x67, 0xDC, 0x7E, 0xBF, 0xB3, 0xCF, 0x9C, 0x7A, 0xCE, 0x1E, 0x54, 0xD5, 0xA1, 0xBD, 0x2C, 0x93, + 0x87, 0xFF, 0x4E, 0xAF, 0x3E, 0x14, 0xF2, 0x9E, 0x7A, 0xC0, 0xFC, 0xD7, 0x83, 0x73, 0xFE, 0xB7, + 0xE0, 0x1F, 0x05, 0x00, 0x00, 0x00, 0x60, 0xEA, 0xFC, 0xF2, 0xE1, 0xB9, 0xB7, 0xBC, 0xB6, 0xB5, + 0xEF, 0x97, 0x61, 0x88, 0x8C, 0xEF, 0x9E, 0x6F, 0x26, 0xFE, 0xAB, 0x3D, 0x18, 0xAB, 0x03, 0x7C, + 0x2F, 0x4F, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0C, 0x79, 0x4D, 0x3D, 0x60, 0xFE, 0xDA, 0xA6, 0x39, + 0x77, 0xF3, 0x80, 0x39, 0x00, 0x00, 0x00, 0x3A, 0xCA, 0x7F, 0x50, 0xFD, 0xC9, 0xBE, 0xAF, 0xBE, + 0xBE, 0x65, 0xDE, 0x5B, 0x61, 0x88, 0xBC, 0xB9, 0x6F, 0xBE, 0x39, 0xFB, 0x13, 0x7B, 0x48, 0x56, + 0x87, 0xF9, 0x5E, 0x9B, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x1A, 0xF2, 0x98, 0x7A, 0xC0, 0xFC, 0xD5, + 0xCD, 0x73, 0x37, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xBA, 0x8A, 0x7B, 0x50, 0xFD, 0xB7, 0x9B, + 0xFA, 0xEE, 0x09, 0x23, 0xC4, 0xED, 0xED, 0x61, 0xF7, 0xA0, 0xBA, 0x38, 0xD4, 0xF7, 0xCA, 0xE4, + 0xE1, 0xBF, 0xD3, 0xD3, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0x3D, 0xC9, 0x3D, + 0x1F, 0xF2, 0xCA, 0xA6, 0xBE, 0x2D, 0xD1, 0x10, 0x71, 0xCF, 0x87, 0xF4, 0xDC, 0x83, 0xEA, 0xF2, + 0xF0, 0xDF, 0xE9, 0xE9, 0x78, 0x68, 0x77, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x9E, 0x57, 0xF9, + 0x20, 0xC3, 0x79, 0x35, 0x0F, 0xAA, 0x9F, 0xFE, 0x5B, 0x7B, 0xE0, 0x55, 0x87, 0xFD, 0x6E, 0x9B, + 0x3C, 0xFC, 0x77, 0x7A, 0xF5, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xA5, 0xF3, + 0xAB, 0xC7, 0xFA, 0xFE, 0x22, 0xFE, 0xA0, 0x7A, 0x57, 0x3F, 0x1F, 0x22, 0x0F, 0xFF, 0x9D, 0x9E, + 0x0E, 0x88, 0xAC, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0x94, 0x9A, 0x7B, 0x50, 0xFD, 0xB5, 0x2D, + 0xF3, 0xBE, 0x1E, 0x7F, 0x50, 0xFD, 0xDC, 0x3F, 0xDA, 0xC3, 0xB5, 0x8A, 0x80, 0x4E, 0x4D, 0x1E, + 0xFE, 0x3B, 0x3D, 0x1D, 0x11, 0x59, 0xC6, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x98, 0x56, 0xDC, 0x83, + 0xEA, 0xBF, 0x79, 0xAA, 0xEF, 0xC7, 0x61, 0x84, 0xB8, 0x75, 0xCD, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, + 0xE9, 0xE9, 0x90, 0x48, 0xBB, 0x46, 0x0F, 0x98, 0xBF, 0xB6, 0xE5, 0xD2, 0x81, 0xE0, 0x7F, 0x1A, + 0x00, 0x00, 0x00, 0xA0, 0xBC, 0xFC, 0x0F, 0x32, 0xDC, 0xD4, 0x37, 0x12, 0x46, 0x48, 0xF8, 0x41, + 0x86, 0x1D, 0x7B, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x13, 0x69, 0xA7, 0x1E, 0x30, 0x7F, + 0xE5, 0xC9, 0x39, 0xB7, 0x07, 0xFF, 0x53, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x87, 0x7B, 0x50, 0xFD, + 0xB5, 0x2D, 0xF3, 0x8E, 0x85, 0x21, 0xE2, 0x9E, 0x0F, 0x39, 0x33, 0x6A, 0x0F, 0xDF, 0x2A, 0x12, + 0x8A, 0x9A, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x26, 0xD2, 0x4C, 0x3D, 0x60, 0xFE, 0xCA, 0xA6, 0xB9, + 0xFF, 0x57, 0xF0, 0xB7, 0x1E, 0x00, 0x00, 0x00, 0x98, 0x9E, 0xC2, 0x0F, 0x32, 0x8C, 0x3E, 0xA8, + 0xFE, 0xC6, 0x9E, 0x29, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x14, 0x49, 0x17, 0x7F, + 0xC0, 0xDC, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x98, 0xF0, 0x83, 0x0C, 0xE3, 0x0F, 0xAA, + 0x17, 0xF6, 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2A, 0x92, 0x8C, 0x07, 0xCC, 0x01, 0x00, + 0x00, 0x80, 0x0C, 0x5E, 0x79, 0x72, 0xCE, 0xA5, 0xF1, 0x0F, 0x32, 0x74, 0x0F, 0xAA, 0xE7, 0xFA, + 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2C, 0x5A, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, + 0x1C, 0xFC, 0x7A, 0x63, 0xDF, 0x55, 0xAF, 0x6E, 0x9E, 0xF7, 0x4F, 0x61, 0x84, 0x84, 0x0F, 0xAA, + 0xCB, 0xA0, 0x48, 0x33, 0x79, 0xF8, 0xEF, 0xF4, 0xEA, 0xC3, 0x22, 0xC9, 0x78, 0xC0, 0x1C, 0x00, + 0x00, 0x00, 0xC8, 0xD9, 0x2F, 0x1F, 0x9E, 0x7B, 0x4B, 0xFC, 0x83, 0x0C, 0x33, 0x3F, 0xA8, 0x2E, + 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x8B, 0x66, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, 0x40, 0xFE, + 0x07, 0x19, 0x6E, 0xEE, 0xFB, 0x3F, 0xE3, 0xCF, 0x87, 0xA4, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, + 0x3D, 0x1D, 0x18, 0x8D, 0xA6, 0x1E, 0x30, 0xFF, 0xED, 0xC6, 0x4B, 0xBF, 0xC5, 0x03, 0xE6, 0x00, + 0x00, 0x00, 0x40, 0x01, 0xC2, 0x07, 0xD5, 0xC3, 0x08, 0x71, 0x7B, 0xEB, 0x40, 0x82, 0x07, 0xD5, + 0xE5, 0xE1, 0xBF, 0xD3, 0xD3, 0x91, 0xA1, 0xE6, 0x9E, 0xF3, 0x88, 0x3F, 0x60, 0xFE, 0xCA, 0x53, + 0x73, 0xB6, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x00, 0x30, 0x05, 0xDC, 0x07, 0x19, 0xBE, 0xBE, 0x75, + 0xDE, 0xFE, 0x68, 0x88, 0xBC, 0x73, 0xA8, 0xC1, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xD0, + 0x88, 0x4F, 0x3D, 0x60, 0xFE, 0xDA, 0xE6, 0x39, 0x3F, 0xE1, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, + 0x03, 0xDC, 0x07, 0x19, 0xC6, 0x1F, 0x54, 0x3F, 0xFD, 0xB7, 0xF6, 0xF0, 0x5E, 0x82, 0xF8, 0x70, + 0x0F, 0x98, 0xD7, 0x3C, 0xE7, 0xC1, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x40, 0x77, 0x88, 0x7F, 0x90, + 0xE1, 0xF8, 0xEE, 0x3E, 0x33, 0xF1, 0xF7, 0xEE, 0x20, 0xAF, 0x02, 0xA0, 0x93, 0xAB, 0x0F, 0x8D, + 0xF8, 0xDC, 0x03, 0xE6, 0x6F, 0x0C, 0xD5, 0x3F, 0x60, 0x3E, 0xDA, 0xFF, 0x9E, 0x3F, 0x0A, 0x7E, + 0xBB, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xCD, 0x7F, 0x50, 0x7D, 0xCB, 0xBC, 0xAF, 0x57, 0x1E, 0x54, + 0xB7, 0x07, 0x78, 0xBB, 0x37, 0xF7, 0xF5, 0xD9, 0x03, 0xBD, 0x3B, 0xD8, 0xAB, 0x18, 0x98, 0xEA, + 0xD5, 0xC7, 0x46, 0x74, 0xEE, 0x83, 0x04, 0x79, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xE8, 0x31, 0xEE, + 0x41, 0xF5, 0x57, 0x36, 0xCD, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0xDB, 0xC3, 0xF3, 0xED, 0x01, 0x5F, + 0x45, 0xC1, 0x54, 0x4D, 0x47, 0x87, 0x1B, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x00, 0x25, 0xF0, 0x6F, + 0x1B, 0xFA, 0xFA, 0x5E, 0xDB, 0x32, 0xF7, 0x27, 0x61, 0x84, 0xFC, 0x7E, 0xE7, 0x3C, 0x73, 0xEA, + 0xD9, 0xF9, 0xF6, 0xC0, 0xAF, 0x02, 0xA1, 0xC8, 0x35, 0x0E, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, + 0x00, 0x4A, 0xE6, 0x57, 0x4F, 0x5C, 0xBA, 0xC6, 0x86, 0xC8, 0xB1, 0x68, 0x88, 0x9C, 0xF9, 0x3B, + 0x17, 0x01, 0x2A, 0x16, 0xF2, 0x5E, 0x7D, 0x78, 0xB8, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0x50, + 0x62, 0xEE, 0x01, 0xEE, 0xDF, 0x3E, 0x39, 0xF7, 0xAB, 0xAF, 0x6F, 0x9B, 0x37, 0x1E, 0x86, 0x88, + 0x7B, 0x50, 0xBD, 0xD8, 0xE7, 0x43, 0xEA, 0xC3, 0x83, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x69, + 0xA4, 0xF2, 0x41, 0x86, 0x73, 0xEF, 0x79, 0x7D, 0xCB, 0xDC, 0x9A, 0x07, 0xD5, 0xCF, 0xFD, 0x34, + 0xEF, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, 0xA6, 0xB1, 0x57, 0x9E, 0x9C, + 0x73, 0xA9, 0x7A, 0x50, 0x3D, 0x9F, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, + 0xE0, 0x7B, 0x6D, 0x47, 0xDF, 0x40, 0xE5, 0x83, 0x0C, 0x27, 0x43, 0xE4, 0x8D, 0x3D, 0x7D, 0xFE, + 0x33, 0x22, 0xD9, 0xDE, 0x9A, 0x55, 0x79, 0xB8, 0xDC, 0x3D, 0xE3, 0x11, 0xBF, 0xF1, 0xE0, 0x01, + 0x73, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x57, 0x9E, 0x99, 0x73, 0xDB, 0xEB, 0xDB, 0xE7, 0x9E, 0x8C, + 0x86, 0x48, 0x18, 0x23, 0xEF, 0x1C, 0x9A, 0x6F, 0x4E, 0xFF, 0xCD, 0x7C, 0xFF, 0x79, 0x91, 0xF8, + 0x0D, 0x89, 0xFB, 0xFF, 0xDD, 0xBF, 0xEE, 0xFE, 0xFD, 0x77, 0x0E, 0xF5, 0xD5, 0x3C, 0xDF, 0x11, + 0xCE, 0x3D, 0x60, 0x6E, 0x7F, 0xEE, 0x75, 0xC1, 0x5F, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xDC, + 0x1B, 0xB3, 0x5E, 0x79, 0x66, 0xEE, 0x70, 0x3C, 0x44, 0x5A, 0x2E, 0x16, 0x1D, 0x95, 0xCD, 0x19, + 0xFA, 0xF5, 0xA3, 0x97, 0xDE, 0x1C, 0xFC, 0xD4, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xB9, 0x87, 0xD5, + 0x7F, 0xB3, 0x71, 0xDE, 0x9D, 0xAF, 0x3E, 0x3D, 0xEF, 0xA1, 0x57, 0x37, 0xCF, 0x7D, 0x59, 0x46, + 0x47, 0xB8, 0x20, 0x38, 0x5E, 0xDB, 0x3C, 0xF7, 0xD8, 0xAB, 0xCF, 0xCC, 0x7D, 0xDA, 0xDD, 0x76, + 0xFC, 0xB7, 0xEF, 0xCC, 0xFB, 0x40, 0xF0, 0x53, 0x01, 0x00, 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x35, + 0xB9, 0xFE, 0x07, 0x1B, 0xEE, 0xE8, 0x1B, 0x88, 0xEF, 0xDF, 0x36, 0xCC, 0xEE, 0x0B, 0xFE, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xD0, 0x15, 0xDE, 0xF3, 0x9E, 0xFF, 0x1F, 0x5B, 0xE2, 0x94, 0x1D, 0x86, + 0x86, 0x23, 0x09, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82}; + +static const uint8_t tree_img_gif[] PROGMEM = { + + 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x28, 0x00, 0x3C, 0x00, 0x83, 0x0B, 0x00, 0x00, 0xFF, 0xFF, + 0x00, 0x21, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x94, 0x00, 0x00, 0xB5, 0x00, 0x00, + 0xDE, 0x00, 0x00, 0xFF, 0x00, 0x6B, 0x00, 0x00, 0xFF, 0x33, 0x33, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0x00, 0xCC, 0x00, 0x00, 0x21, 0xFF, 0x0B, + 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0xA0, 0x0F, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, + 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, + 0x8C, 0xCA, 0xE8, 0x85, 0xE8, 0xA5, 0xAC, 0x67, 0xEA, 0x8A, 0xE5, 0x2B, 0x2F, 0xE3, 0x31, 0xCE, + 0xAF, 0x41, 0x1C, 0xB8, 0x1B, 0x24, 0x80, 0x04, 0xAF, 0x87, 0x02, 0x26, 0x88, 0xA1, 0x07, 0x60, + 0xB9, 0x44, 0x82, 0x04, 0x02, 0x80, 0x61, 0x30, 0x70, 0x6E, 0x0C, 0x86, 0x03, 0x60, 0x20, 0xB0, + 0x6A, 0xA8, 0xD3, 0x03, 0x21, 0xEC, 0xAD, 0x18, 0x12, 0xE8, 0xF4, 0xB1, 0x4C, 0x51, 0xA0, 0x07, + 0xEA, 0x07, 0x5B, 0xF2, 0x70, 0x13, 0x76, 0xD4, 0xA8, 0xBC, 0xBC, 0xEA, 0x1F, 0x06, 0x77, 0x51, + 0x73, 0x50, 0x0A, 0x80, 0x7F, 0x04, 0x4C, 0x4D, 0x65, 0x06, 0x0A, 0x3B, 0x3B, 0x62, 0x5A, 0x53, + 0x65, 0x05, 0x02, 0x04, 0x68, 0x0C, 0x6A, 0x00, 0x5D, 0x5E, 0x0F, 0x0F, 0x6A, 0x98, 0x6A, 0x09, + 0x7B, 0x56, 0x9D, 0x09, 0x0C, 0xA7, 0xA7, 0x7F, 0x06, 0x9D, 0xA3, 0x44, 0x02, 0x01, 0x03, 0x90, + 0x0C, 0x87, 0x03, 0x06, 0x02, 0x05, 0x56, 0x06, 0x01, 0x02, 0x53, 0xB1, 0xB3, 0x04, 0x79, 0xAF, + 0x55, 0x48, 0x51, 0xB0, 0x87, 0xC0, 0x7F, 0x07, 0x95, 0x05, 0x85, 0x44, 0xB6, 0x00, 0x05, 0x53, + 0x96, 0x6A, 0x60, 0x02, 0x0A, 0x48, 0x89, 0x00, 0x07, 0xA1, 0x69, 0x7D, 0x2B, 0x3D, 0x9D, 0x41, + 0xA1, 0x04, 0xA0, 0xDD, 0x9D, 0x38, 0x02, 0xE1, 0x6A, 0x07, 0x62, 0x0C, 0x77, 0xE6, 0xAD, 0x2F, + 0x05, 0x01, 0xB6, 0x90, 0x07, 0xA8, 0xA7, 0x54, 0xB5, 0xBC, 0x06, 0x33, 0x50, 0x53, 0x3A, 0x00, + 0x39, 0x62, 0x10, 0x6B, 0xDF, 0xBE, 0x19, 0x03, 0x18, 0x40, 0xA9, 0x15, 0x4B, 0xCC, 0x0E, 0x77, + 0x3B, 0x04, 0xC4, 0x02, 0x38, 0x43, 0x21, 0x96, 0x2C, 0xD3, 0xD6, 0x81, 0x01, 0x26, 0x2A, 0xFB, + 0xDE, 0x07, 0x7C, 0x0A, 0xB7, 0x71, 0x1B, 0x79, 0xEE, 0xC5, 0x83, 0x72, 0xDD, 0x84, 0xBC, 0x4B, + 0x13, 0xA4, 0x13, 0x15, 0x17, 0xAB, 0x18, 0x78, 0x4A, 0x43, 0x40, 0x81, 0x43, 0x76, 0x8E, 0xB6, + 0x04, 0x7C, 0x19, 0x02, 0x98, 0xC4, 0x86, 0x35, 0xBD, 0xE1, 0x1C, 0x90, 0x4D, 0x62, 0xBF, 0x14, + 0xFC, 0x7E, 0x02, 0x1A, 0x60, 0xD3, 0xD1, 0x9D, 0x3B, 0x3A, 0x09, 0xFC, 0x44, 0xB1, 0xD0, 0x96, + 0x8E, 0x43, 0x8D, 0x9E, 0xDA, 0xDB, 0x22, 0x11, 0x8A, 0x42, 0x10, 0x5C, 0x00, 0x1A, 0x2D, 0x38, + 0xF2, 0x0E, 0xA0, 0x4A, 0x03, 0x4E, 0xA2, 0xF0, 0xF4, 0x80, 0x17, 0x95, 0x8C, 0x23, 0xD1, 0xD8, + 0x12, 0x00, 0x92, 0x03, 0xAB, 0x99, 0x23, 0x71, 0x3E, 0x8D, 0xEB, 0x6E, 0x18, 0x07, 0x66, 0x23, + 0x05, 0x3E, 0x72, 0xE4, 0x06, 0x0D, 0x81, 0x02, 0xE4, 0x36, 0x5D, 0xD9, 0xA5, 0xC0, 0xAD, 0x59, + 0xA2, 0x86, 0x6E, 0xD6, 0xC4, 0x73, 0xEB, 0x15, 0xA5, 0xC5, 0xDE, 0x14, 0xF4, 0x62, 0x07, 0xC0, + 0xE9, 0x9D, 0xCC, 0x58, 0x02, 0x14, 0xA0, 0x84, 0x45, 0x83, 0x68, 0x7A, 0x8D, 0x81, 0x66, 0xC3, + 0xE9, 0xD0, 0xA6, 0x3E, 0x03, 0xF3, 0x80, 0x7D, 0x90, 0xD8, 0x58, 0xA2, 0x59, 0x2D, 0x90, 0x68, + 0xD6, 0x64, 0x17, 0x76, 0x5A, 0x23, 0xBF, 0x13, 0x58, 0x89, 0x7A, 0xC3, 0xF0, 0x8F, 0xB6, 0xB8, + 0x4B, 0xD3, 0x74, 0x52, 0x50, 0x92, 0xC2, 0x03, 0xD1, 0x78, 0xD7, 0x89, 0x4C, 0x23, 0x26, 0x6E, + 0x82, 0xCC, 0x15, 0x5E, 0x05, 0x08, 0x30, 0x06, 0x8A, 0x75, 0x64, 0xFA, 0x42, 0xF1, 0x12, 0xAD, + 0x60, 0xDE, 0x51, 0x0A, 0x94, 0xBA, 0x5E, 0x2C, 0x8C, 0x86, 0xDD, 0x3D, 0xDE, 0x8F, 0x0A, 0x70, + 0x51, 0x5F, 0xFE, 0xF2, 0x84, 0xD1, 0xD0, 0xA6, 0x68, 0xB7, 0x96, 0x62, 0x14, 0x0C, 0xC1, 0xB7, + 0x90, 0x68, 0x72, 0xD1, 0x7C, 0xD9, 0x3D, 0xA3, 0x94, 0x35, 0xDE, 0x54, 0x06, 0x92, 0x51, 0x50, + 0x68, 0xC2, 0xC5, 0x44, 0xB7, 0x30, 0x70, 0xDE, 0x6A, 0x49, 0x69, 0x86, 0xC5, 0x2D, 0xA3, 0x29, + 0x04, 0x05, 0x2F, 0xD9, 0xC4, 0x02, 0x0C, 0x6C, 0x0C, 0x48, 0xB0, 0x94, 0x01, 0xDA, 0x3C, 0xF2, + 0x56, 0x21, 0xFA, 0xE8, 0xA3, 0xA1, 0x55, 0x12, 0xE9, 0xF4, 0x56, 0x42, 0xF8, 0x50, 0x00, 0x40, + 0x08, 0x08, 0xD4, 0x88, 0x80, 0x05, 0x33, 0x66, 0x10, 0xA2, 0x0C, 0xDC, 0xA0, 0xB0, 0xA3, 0x0B, + 0x71, 0xCD, 0xB1, 0x80, 0x75, 0x69, 0x20, 0x41, 0xE4, 0x91, 0x6B, 0x64, 0x10, 0x01, 0x00, 0x21, + 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, 0x00, + 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, 0x8C, + 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0x31, 0x1C, 0x34, + 0x1B, 0x24, 0x4C, 0x82, 0xE7, 0x28, 0x5E, 0x02, 0x78, 0x7A, 0x30, 0x8E, 0x47, 0x62, 0x48, 0x20, + 0x60, 0xD8, 0x06, 0x4A, 0x8E, 0xC1, 0x70, 0x60, 0x0C, 0x04, 0xD1, 0xCD, 0x60, 0x60, 0x3B, 0x10, + 0xBA, 0x59, 0x8B, 0x21, 0x41, 0x2E, 0x0F, 0xC3, 0x16, 0xF2, 0xC0, 0xAC, 0x40, 0x4F, 0x1E, 0x80, + 0x04, 0x81, 0x70, 0xD8, 0x0A, 0x14, 0x0F, 0xF7, 0x42, 0x00, 0xA0, 0xD6, 0x09, 0x0A, 0x81, 0x81, + 0x68, 0x00, 0x85, 0x85, 0x7F, 0x07, 0x07, 0x0A, 0x06, 0x7A, 0x06, 0x00, 0x74, 0x74, 0x5E, 0x8A, + 0x36, 0x68, 0x05, 0x7C, 0x66, 0x3D, 0x64, 0x58, 0x61, 0x0F, 0x0F, 0x66, 0x64, 0x99, 0x64, 0x79, + 0x9C, 0x9E, 0xA0, 0x48, 0x4E, 0x9D, 0xA3, 0x4A, 0x02, 0x01, 0x37, 0x90, 0x55, 0x04, 0x5C, 0x02, + 0x05, 0x59, 0x06, 0x01, 0x02, 0x4F, 0x89, 0x55, 0x76, 0xAC, 0x50, 0xAB, 0x0A, 0xAD, 0x7F, 0xB1, + 0x75, 0x07, 0x02, 0x04, 0x05, 0x00, 0xBE, 0x39, 0x06, 0x77, 0x05, 0x36, 0x04, 0x9F, 0x5B, 0xCC, + 0x00, 0x4A, 0x82, 0x81, 0x07, 0x9F, 0x65, 0x86, 0x85, 0x40, 0x9D, 0x0A, 0x9F, 0x0C, 0xD0, 0x9F, + 0x00, 0x9D, 0x39, 0x02, 0xDE, 0x66, 0xB0, 0x73, 0xE2, 0x09, 0xE4, 0xAA, 0x2F, 0x05, 0x01, 0xCC, + 0x5E, 0xA7, 0x56, 0x75, 0xD2, 0xB8, 0x8C, 0x2F, 0x4C, 0x36, 0x06, 0xB1, 0x73, 0xE1, 0x88, 0xC9, + 0x92, 0x45, 0x43, 0x96, 0x00, 0x2E, 0x37, 0xE8, 0x79, 0x99, 0x53, 0xEC, 0x86, 0x0D, 0x06, 0x05, + 0xF3, 0x51, 0x61, 0x57, 0xE6, 0x9E, 0xBF, 0x35, 0x0C, 0xDE, 0x81, 0xE8, 0x64, 0x10, 0xFB, 0x5B, + 0xB6, 0x6C, 0xF5, 0x56, 0x94, 0x22, 0x13, 0xA7, 0xE2, 0x9C, 0x04, 0xDF, 0xCA, 0x74, 0xB2, 0xB2, + 0xC2, 0x40, 0x2A, 0x92, 0x72, 0x20, 0x45, 0x52, 0xE0, 0x45, 0x1A, 0x01, 0x2B, 0xCA, 0x3E, 0xC4, + 0x3A, 0x38, 0x60, 0xDB, 0x23, 0x86, 0xD6, 0x14, 0x0C, 0x20, 0xC0, 0x84, 0xCB, 0x8A, 0x7C, 0x3C, + 0x1F, 0x25, 0x94, 0xA9, 0x80, 0x21, 0x17, 0xA2, 0x5B, 0x4E, 0x34, 0x91, 0xE5, 0x2F, 0x99, 0x4C, + 0xA0, 0x89, 0xEC, 0x5C, 0xC1, 0xB5, 0x89, 0xC3, 0x15, 0x2B, 0xCC, 0x10, 0xD6, 0xF9, 0x38, 0x67, + 0xA8, 0xB1, 0x01, 0xE5, 0x40, 0xD4, 0x7B, 0x42, 0xF1, 0x63, 0x02, 0x66, 0x02, 0x12, 0xA4, 0xFA, + 0x90, 0x2A, 0x54, 0xB6, 0x44, 0xEB, 0xDA, 0x96, 0x19, 0x9A, 0x53, 0x43, 0x01, 0xBB, 0x64, 0x84, + 0xAE, 0xC3, 0xBB, 0xB0, 0xCC, 0x31, 0x40, 0x5D, 0x35, 0xD8, 0x62, 0x82, 0x6B, 0x68, 0xAC, 0xA6, + 0x43, 0xF1, 0xD2, 0x01, 0x20, 0xE9, 0x8A, 0x25, 0x05, 0x96, 0x36, 0xD8, 0x8A, 0xD7, 0xD8, 0x46, + 0xD0, 0x85, 0xEB, 0x7E, 0x72, 0x31, 0x10, 0x54, 0x9F, 0x85, 0x00, 0xF1, 0xA6, 0x1C, 0x94, 0x2C, + 0x34, 0xB2, 0x17, 0x9F, 0x5B, 0xB8, 0x14, 0x80, 0xFC, 0x41, 0x28, 0x63, 0xC7, 0x03, 0x9A, 0x4A, + 0x32, 0x9C, 0x2C, 0x2B, 0x2E, 0x40, 0x72, 0x63, 0x59, 0x48, 0x85, 0x47, 0x8D, 0xD8, 0xC8, 0xD9, + 0xE2, 0xF0, 0x55, 0x99, 0x4A, 0xE3, 0x82, 0x07, 0x41, 0x3F, 0x25, 0x92, 0xAE, 0xD7, 0x4C, 0x3C, + 0xE7, 0xAC, 0x02, 0x04, 0x58, 0xC4, 0xC4, 0xAD, 0x9C, 0x1B, 0xB1, 0x3F, 0xE1, 0x42, 0x3D, 0x4B, + 0x9E, 0x85, 0xCB, 0x57, 0xA6, 0x30, 0x4B, 0x97, 0x88, 0x26, 0xA2, 0x03, 0x7F, 0x8B, 0x72, 0x2D, + 0x90, 0x79, 0x02, 0xFD, 0x59, 0x36, 0xB2, 0xF3, 0x41, 0x2A, 0x65, 0xAD, 0x75, 0x64, 0x3A, 0x0C, + 0x48, 0xB4, 0x15, 0x35, 0x13, 0xE0, 0xC2, 0xC0, 0x2D, 0xB1, 0x15, 0x95, 0x0C, 0x13, 0x97, 0x59, + 0x73, 0x90, 0x01, 0xF5, 0xAC, 0x36, 0x8D, 0x79, 0x12, 0x40, 0xB8, 0x45, 0x22, 0xB8, 0xF8, 0xC4, + 0x0C, 0x7D, 0xB3, 0x31, 0x96, 0xCF, 0x00, 0x01, 0x76, 0x41, 0x80, 0x4F, 0x0B, 0x80, 0x78, 0x4A, + 0x24, 0x5B, 0x8C, 0x18, 0xDB, 0x8A, 0x0A, 0xF0, 0xC3, 0x15, 0x88, 0x08, 0xF1, 0xC5, 0xC7, 0x3C, + 0x13, 0x40, 0x94, 0x01, 0x81, 0x13, 0x20, 0xA0, 0x23, 0x02, 0x27, 0xE0, 0x58, 0x63, 0x08, 0xD9, + 0xE8, 0x41, 0x81, 0x5B, 0x42, 0x7A, 0x57, 0x86, 0x12, 0x46, 0x26, 0x79, 0x46, 0x06, 0x11, 0x00, + 0x00, 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x3C, 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, + 0xE4, 0x8C, 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0xA1, + 0x1C, 0x34, 0x1B, 0x24, 0x4A, 0x82, 0xE7, 0x27, 0x85, 0x50, 0x08, 0x0C, 0x3D, 0x12, 0xBC, 0xC4, + 0xA3, 0x18, 0x12, 0x08, 0x14, 0x86, 0xC1, 0x80, 0xC9, 0x31, 0x18, 0x0E, 0x84, 0x81, 0x80, 0xBA, + 0x91, 0x46, 0xB1, 0x51, 0x06, 0xD7, 0x62, 0x40, 0x9A, 0x91, 0xE2, 0x71, 0xA5, 0x37, 0x40, 0x33, + 0xDE, 0xE9, 0xF1, 0xE3, 0xA1, 0x20, 0x10, 0x0E, 0x52, 0x01, 0x63, 0xA9, 0x5E, 0x0C, 0x85, 0x03, + 0x76, 0x7A, 0x7D, 0x0B, 0x4E, 0x03, 0x75, 0x78, 0x77, 0x78, 0x06, 0x84, 0x51, 0x37, 0x8A, 0x77, + 0x02, 0x51, 0x6A, 0x05, 0x02, 0x04, 0x67, 0x67, 0x5B, 0x72, 0x47, 0x98, 0x98, 0x7C, 0x5C, 0x73, + 0x66, 0x58, 0x07, 0x8B, 0x0F, 0x00, 0x9F, 0x45, 0x02, 0x01, 0x03, 0xA3, 0x0C, 0x89, 0x03, 0x06, + 0x02, 0x00, 0x5C, 0x06, 0x01, 0x92, 0x52, 0x07, 0xAE, 0x59, 0x03, 0x00, 0xBD, 0xBD, 0x4C, 0x02, + 0x05, 0xAB, 0xB9, 0x70, 0x0C, 0xAC, 0x96, 0x00, 0x52, 0x45, 0x36, 0xC1, 0x51, 0x97, 0x0C, 0x66, + 0x5E, 0x00, 0x8C, 0x4C, 0x0A, 0x05, 0x5F, 0x68, 0x98, 0x4E, 0x56, 0x40, 0x7F, 0x3D, 0x67, 0x97, + 0x9D, 0x73, 0x39, 0x02, 0x74, 0x9C, 0x48, 0xA4, 0x76, 0x76, 0x66, 0x73, 0xA8, 0x2C, 0x05, 0x50, + 0x02, 0xA3, 0xA3, 0x59, 0x78, 0x5E, 0x92, 0xD4, 0x2C, 0xDB, 0xB0, 0x59, 0x76, 0x07, 0x00, 0x78, + 0x16, 0x09, 0x80, 0xF5, 0xE4, 0x05, 0xC1, 0x81, 0x5F, 0xB0, 0x10, 0x00, 0xA0, 0xEE, 0xC0, 0xC0, + 0x03, 0x8E, 0x68, 0x68, 0xB1, 0x72, 0xE5, 0x92, 0xAF, 0x5E, 0xF6, 0x0C, 0x10, 0xF0, 0x86, 0x62, + 0xFB, 0xCE, 0xC1, 0x03, 0x98, 0x00, 0x74, 0x42, 0x42, 0xE7, 0xC5, 0xB9, 0x4E, 0xFF, 0xC2, 0x9D, + 0x99, 0xA3, 0x60, 0x0A, 0x0A, 0x03, 0xED, 0xC0, 0xDD, 0xF1, 0x47, 0xCF, 0xCB, 0x2E, 0x97, 0x20, + 0x92, 0x0D, 0x64, 0x85, 0xA5, 0x65, 0x43, 0x2C, 0x3C, 0x19, 0x10, 0x30, 0x94, 0x2F, 0x27, 0xBE, + 0x9D, 0x87, 0x78, 0xCE, 0x54, 0x47, 0xC0, 0x98, 0xC6, 0x9D, 0x39, 0x2F, 0xC6, 0xB2, 0xF1, 0x87, + 0x29, 0x96, 0x62, 0xC6, 0xB6, 0x69, 0xE2, 0xC0, 0x2B, 0x4A, 0x2C, 0x58, 0x49, 0x47, 0xDA, 0x11, + 0x6A, 0x69, 0xC0, 0xB8, 0x10, 0x22, 0x1F, 0xDC, 0x0A, 0xF4, 0x6D, 0x64, 0x02, 0x06, 0xB1, 0x04, + 0x28, 0x39, 0xBB, 0xA1, 0xDD, 0x49, 0x4C, 0xE9, 0xD4, 0xB9, 0x4D, 0x0A, 0xA2, 0x40, 0x81, 0x91, + 0x81, 0x68, 0x2E, 0x35, 0x43, 0xA0, 0xC0, 0x50, 0x05, 0x1F, 0x6A, 0x39, 0xB9, 0x65, 0x47, 0x4A, + 0xBF, 0xBC, 0xF4, 0xF0, 0x04, 0xE3, 0x98, 0xA1, 0x96, 0x02, 0x5B, 0x5E, 0x71, 0xA5, 0x53, 0xA8, + 0x4E, 0x68, 0x16, 0x2B, 0x01, 0xFC, 0x42, 0x29, 0x4A, 0x21, 0xF4, 0xE8, 0x87, 0x0A, 0xA5, 0x04, + 0xDA, 0xDC, 0x94, 0x95, 0x6A, 0x03, 0xC2, 0x5A, 0x6E, 0xF0, 0x66, 0xC8, 0x0E, 0xC0, 0x99, 0x20, + 0xDF, 0x16, 0x93, 0xAC, 0x91, 0x64, 0x16, 0x0B, 0xED, 0x14, 0x70, 0xF2, 0xC2, 0x6B, 0x75, 0x27, + 0x68, 0x81, 0xDA, 0x90, 0xB4, 0x0B, 0xDC, 0x74, 0xC8, 0x8B, 0x67, 0xB0, 0xBC, 0x75, 0x2B, 0xCC, + 0x5D, 0xA1, 0x00, 0xD8, 0x09, 0xC4, 0x3D, 0x23, 0x92, 0xB0, 0x6B, 0x29, 0xDA, 0x6A, 0x55, 0x12, + 0x46, 0x7A, 0x41, 0xA5, 0x81, 0xF8, 0x62, 0x25, 0xE8, 0x4E, 0x2A, 0x60, 0x22, 0x52, 0x05, 0xB4, + 0xB4, 0x94, 0x14, 0xAC, 0x12, 0x05, 0xBF, 0xCD, 0xB4, 0x60, 0xA7, 0x6F, 0x66, 0x65, 0xE7, 0x57, + 0xC7, 0xA3, 0xC8, 0x67, 0x85, 0x16, 0x5B, 0x49, 0xF0, 0x84, 0x2A, 0x48, 0x19, 0x92, 0x47, 0x30, + 0x4E, 0x00, 0x60, 0xC9, 0x57, 0x71, 0x79, 0x03, 0x51, 0x30, 0xD3, 0x4C, 0xA0, 0xC0, 0x4E, 0xA4, + 0x1C, 0x45, 0x51, 0x2C, 0x7E, 0x39, 0xB8, 0x18, 0x3E, 0x04, 0xB5, 0x04, 0x14, 0x6C, 0xB3, 0xF8, + 0xF1, 0xC7, 0x3C, 0x00, 0xAA, 0xC6, 0xCB, 0x45, 0xFC, 0x21, 0xD5, 0x52, 0x72, 0x17, 0x95, 0x88, + 0xD8, 0x09, 0x08, 0x00, 0x80, 0x00, 0x02, 0x28, 0x94, 0x28, 0xC1, 0x8C, 0x20, 0x20, 0xD1, 0x5D, + 0x02, 0x27, 0xE8, 0x88, 0x82, 0x5B, 0x84, 0x2C, 0xE0, 0xD6, 0x19, 0x4C, 0x1C, 0xA9, 0xA4, 0x19, + 0x1B, 0x44, 0x00, 0x00, 0x21, 0xFE, 0x19, 0x42, 0x6F, 0x79, 0x27, 0x73, 0x20, 0x48, 0x61, 0x70, + 0x70, 0x79, 0x20, 0x48, 0x6F, 0x6C, 0x69, 0x64, 0x61, 0x79, 0x73, 0x20, 0x50, 0x61, 0x67, 0x65, + 0x00, 0x3B + +}; + +static const uint8_t bird_img_gif[] PROGMEM = { + 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x74, 0x00, 0x4E, 0x00, 0xCC, 0x13, 0x00, 0xFF, 0xFF, 0xFF, + 0xEF, 0xFF, 0xFF, 0xBD, 0xE7, 0xE7, 0xD6, 0xEF, 0xEF, 0x63, 0x63, 0x63, 0xAD, 0xAD, 0xAD, 0xCE, + 0xCE, 0xCE, 0xD6, 0xDE, 0xDE, 0x4A, 0x4A, 0x4A, 0x7B, 0x84, 0x84, 0x94, 0x9C, 0x9C, 0xE7, 0xE7, + 0xE7, 0x84, 0x94, 0x94, 0xB5, 0xC6, 0xC6, 0x73, 0x7B, 0x7B, 0x31, 0x31, 0x31, 0xF7, 0xF7, 0xF7, + 0x18, 0x10, 0x10, 0xCE, 0x63, 0x39, 0x6B, 0x39, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xFF, 0x0B, + 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x4B, + 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0xAE, 0xEC, 0x68, 0x2C, + 0x6D, 0x2C, 0xCF, 0x74, 0x6D, 0x03, 0x46, 0x84, 0x40, 0x77, 0xEF, 0xFF, 0x40, 0x51, 0x42, 0x41, + 0x0C, 0x1A, 0x8F, 0x48, 0x13, 0xC1, 0xD0, 0x20, 0x00, 0x0E, 0x8E, 0x42, 0x72, 0x4A, 0xAD, 0x21, + 0x0E, 0xCD, 0x05, 0xE1, 0x80, 0xA8, 0x7A, 0xBF, 0x29, 0xC2, 0xA0, 0x91, 0x28, 0x34, 0x02, 0x5D, + 0xB0, 0x5A, 0xFD, 0x08, 0x34, 0x14, 0x84, 0x00, 0x7A, 0x4D, 0xF7, 0x22, 0xDC, 0x89, 0xB8, 0xC1, + 0xB9, 0x80, 0xD5, 0xFF, 0x40, 0x0B, 0x77, 0x0C, 0x0F, 0x05, 0x01, 0x0C, 0x0A, 0x0B, 0x0F, 0x08, + 0x06, 0x80, 0x8E, 0x37, 0x7B, 0x01, 0x09, 0x11, 0x03, 0x68, 0x5C, 0x4C, 0x0A, 0x8F, 0x9A, 0x33, + 0x06, 0x09, 0x01, 0x0E, 0x71, 0x68, 0x88, 0x92, 0x07, 0x9B, 0xA6, 0x2C, 0x0A, 0x86, 0x07, 0x95, + 0x05, 0x04, 0xA1, 0x5D, 0x8D, 0xA7, 0xB2, 0x26, 0x09, 0x06, 0x72, 0x72, 0x0E, 0x94, 0x01, 0xA9, + 0x04, 0x08, 0x52, 0xB3, 0xC0, 0x00, 0x09, 0x95, 0xB7, 0x0D, 0x86, 0x01, 0x04, 0x0A, 0xC3, 0x09, + 0x34, 0x43, 0xC1, 0x54, 0x0E, 0xB7, 0xD2, 0x87, 0xAE, 0xBB, 0x99, 0x32, 0x7B, 0x0E, 0xCF, 0x49, + 0x0B, 0xD1, 0xD3, 0x72, 0x0C, 0xDE, 0x57, 0x33, 0xBE, 0xCC, 0xDB, 0x47, 0x05, 0x0C, 0xDF, 0xD3, + 0x05, 0xD7, 0x31, 0x0C, 0xE1, 0xA5, 0xE7, 0x46, 0xBE, 0xEB, 0xD2, 0x04, 0x05, 0xBF, 0x2C, 0x5C, + 0x4D, 0xF3, 0x46, 0x0B, 0x11, 0x56, 0xD9, 0x3B, 0x14, 0x01, 0x14, 0x0F, 0x16, 0x04, 0x1A, 0x30, + 0x28, 0x00, 0x81, 0xA1, 0x3F, 0x1F, 0xAD, 0x02, 0x10, 0x5B, 0x87, 0x6F, 0x0E, 0x8B, 0x02, 0x0E, + 0x04, 0x5C, 0x41, 0x10, 0xF0, 0x61, 0x8F, 0x25, 0x03, 0x26, 0xDA, 0x43, 0xC4, 0x42, 0x8B, 0x00, + 0x05, 0x0E, 0x7C, 0xFF, 0xED, 0xF0, 0x68, 0x83, 0x8B, 0x44, 0x91, 0xDF, 0x06, 0xAC, 0x54, 0x01, + 0x21, 0xA1, 0x80, 0x07, 0x0F, 0x1A, 0x38, 0x70, 0xC7, 0x72, 0x46, 0xC2, 0x97, 0x03, 0x3F, 0xC5, + 0x52, 0xE1, 0x80, 0x81, 0x00, 0x01, 0x19, 0x1B, 0x3C, 0x38, 0xD8, 0x53, 0xC6, 0x81, 0x38, 0x21, + 0x61, 0x4A, 0xEB, 0xB7, 0x42, 0x01, 0x82, 0xA3, 0x58, 0x7D, 0xC9, 0x6B, 0x1A, 0x63, 0x0B, 0xD0, + 0x81, 0x11, 0x08, 0x74, 0x44, 0x61, 0xE0, 0x01, 0xD6, 0xA3, 0x05, 0x16, 0x2D, 0xE5, 0xDA, 0xC2, + 0x80, 0xB7, 0x90, 0x41, 0xCB, 0xA4, 0x39, 0xC1, 0xEF, 0x2C, 0x56, 0xAA, 0x6C, 0x57, 0x38, 0xA8, + 0x14, 0x35, 0xA8, 0x35, 0x14, 0x10, 0x10, 0x34, 0xB0, 0x9B, 0xD5, 0x4F, 0xDE, 0x14, 0x06, 0x8E, + 0xF5, 0x1D, 0xC8, 0x25, 0x85, 0x83, 0xC1, 0x84, 0x05, 0x20, 0x32, 0x30, 0xF4, 0x30, 0x2D, 0x39, + 0x8B, 0x07, 0x32, 0x42, 0xA1, 0x00, 0x72, 0xE4, 0x45, 0x08, 0x7C, 0x59, 0x36, 0x91, 0x18, 0x73, + 0xE6, 0x6F, 0x79, 0x38, 0x2B, 0x88, 0x7C, 0x54, 0xE7, 0xE0, 0x2D, 0xA3, 0x4B, 0x78, 0x7A, 0x79, + 0x7A, 0x1A, 0xCE, 0x04, 0x4C, 0x85, 0xAC, 0x66, 0x7D, 0x96, 0x80, 0xB9, 0xD8, 0x22, 0x4A, 0x4B, + 0x14, 0x00, 0x97, 0xF1, 0xD3, 0x12, 0x3B, 0x79, 0x9F, 0x45, 0xC0, 0x13, 0xB8, 0xB7, 0xE1, 0xC5, + 0x19, 0x33, 0xEB, 0x53, 0xD3, 0xA8, 0x72, 0x01, 0x0D, 0x44, 0x97, 0x5C, 0x90, 0x7B, 0x9B, 0x01, + 0x05, 0xA6, 0x89, 0xFB, 0x3D, 0x54, 0x20, 0x81, 0xDA, 0x8C, 0xD7, 0x91, 0x16, 0x22, 0x91, 0xF8, + 0x80, 0x9F, 0x86, 0x08, 0x1E, 0xF4, 0xF2, 0xD5, 0x7D, 0x96, 0x18, 0xCC, 0x47, 0xA3, 0xDB, 0x7B, + 0xCA, 0x60, 0x40, 0xCA, 0xF4, 0x58, 0x81, 0xE2, 0x42, 0x04, 0x11, 0x4C, 0x80, 0x53, 0x7C, 0x3F, + 0xC9, 0xB1, 0xC7, 0xFF, 0x7A, 0xC1, 0x18, 0xA0, 0x0E, 0x7E, 0xC4, 0x49, 0xA5, 0x99, 0x67, 0xD7, + 0xA5, 0xB4, 0x15, 0x04, 0x93, 0x48, 0xA0, 0xA1, 0x81, 0x7C, 0x49, 0xB3, 0xC7, 0x38, 0xF6, 0x11, + 0x13, 0x52, 0x7E, 0x12, 0xAE, 0x63, 0xC0, 0x55, 0x00, 0x82, 0x62, 0xD8, 0x08, 0x0B, 0x24, 0xA0, + 0xA1, 0x86, 0x57, 0x3C, 0xF0, 0xE0, 0x2D, 0x05, 0x68, 0x67, 0x4A, 0x27, 0xB7, 0x0C, 0x80, 0x95, + 0x7E, 0x41, 0x11, 0x80, 0x5E, 0x85, 0xBF, 0x9D, 0xD0, 0xC0, 0x04, 0x2F, 0x2E, 0x62, 0xCB, 0x34, + 0x03, 0xE4, 0xB1, 0xA2, 0x23, 0x5E, 0x41, 0xC8, 0x63, 0x50, 0x0E, 0x9A, 0x75, 0x5D, 0x68, 0x5B, + 0x9D, 0xA0, 0x45, 0x04, 0x38, 0x2D, 0x72, 0xCC, 0x34, 0x7B, 0x24, 0xF2, 0x88, 0x5B, 0x39, 0xEA, + 0x18, 0xE1, 0x78, 0xD2, 0x58, 0x05, 0x20, 0x6C, 0x2B, 0xD4, 0x78, 0x64, 0x89, 0x6E, 0xB8, 0xF2, + 0xC2, 0x1F, 0x4D, 0xBE, 0x44, 0x22, 0x99, 0x72, 0xE4, 0x01, 0x60, 0x19, 0x31, 0x68, 0xB1, 0xC4, + 0x78, 0x50, 0xF4, 0xE2, 0x9B, 0x43, 0x5E, 0x80, 0x99, 0xE3, 0x8E, 0x6C, 0x4E, 0xE3, 0x63, 0x7A, + 0xD9, 0x55, 0xD6, 0x82, 0x4E, 0x04, 0x30, 0xD0, 0xC0, 0x01, 0x7C, 0x2A, 0xE4, 0xA3, 0xA2, 0x47, + 0xDC, 0x37, 0xE8, 0x9C, 0xE3, 0xC9, 0x64, 0x9D, 0x72, 0x70, 0x54, 0x29, 0x03, 0x04, 0xDF, 0xE5, + 0xE1, 0x4A, 0x19, 0x06, 0xB0, 0xD9, 0xC4, 0x66, 0x48, 0x7C, 0x27, 0xCD, 0x88, 0x98, 0x92, 0x89, + 0xE2, 0x75, 0x69, 0x2D, 0x69, 0xC3, 0x02, 0x07, 0xA4, 0x03, 0x8A, 0x2B, 0x8E, 0xC2, 0x04, 0x05, + 0x03, 0x48, 0x3C, 0x17, 0x5E, 0xAB, 0x7E, 0x61, 0x04, 0x20, 0x03, 0x33, 0x21, 0x01, 0xC1, 0x02, + 0xDF, 0x81, 0x52, 0x8B, 0x34, 0xAD, 0xC8, 0x6A, 0x43, 0x3E, 0x48, 0x9E, 0xF5, 0x24, 0x45, 0xAF, + 0xF2, 0x96, 0x9D, 0xFF, 0x03, 0xF5, 0x51, 0xD1, 0xA2, 0x03, 0x90, 0xCA, 0xF1, 0x94, 0x3E, 0x37, + 0x68, 0x81, 0xA4, 0x98, 0xC0, 0x9A, 0xF8, 0xC0, 0x8F, 0xCA, 0x39, 0xA0, 0xCD, 0x1F, 0x0B, 0x10, + 0x21, 0x0D, 0x03, 0xB8, 0x7D, 0x74, 0x64, 0x98, 0xD2, 0x16, 0x8A, 0x0C, 0xBA, 0xCA, 0x29, 0xF5, + 0x48, 0x8B, 0x53, 0xA1, 0x19, 0x03, 0xA8, 0x18, 0x85, 0xB2, 0x2A, 0xB9, 0x63, 0x06, 0x45, 0x06, + 0x80, 0x48, 0x05, 0xC9, 0x6E, 0x9C, 0x4F, 0xE1, 0xA3, 0xC2, 0x77, 0xF0, 0x16, 0x95, 0x4B, 0xB7, + 0xF4, 0x12, 0xEA, 0x57, 0x59, 0x14, 0xB2, 0x46, 0x08, 0xB8, 0x8E, 0x08, 0x72, 0x06, 0xB3, 0x3E, + 0xA6, 0xF2, 0x28, 0x46, 0x8B, 0x2C, 0xEB, 0xED, 0x03, 0xF3, 0x56, 0x5C, 0xF0, 0x40, 0xE6, 0xED, + 0xA6, 0x9C, 0x7C, 0xD9, 0x02, 0xA2, 0x48, 0xCA, 0x98, 0x25, 0xD6, 0xCE, 0x4E, 0x14, 0x2B, 0x18, + 0xE7, 0xC0, 0xE5, 0xAE, 0x93, 0x00, 0xC2, 0x45, 0x01, 0xB3, 0xC0, 0x8C, 0x74, 0xFA, 0xF7, 0x80, + 0x84, 0xAC, 0xAE, 0x6C, 0xCF, 0x00, 0x04, 0xA4, 0x47, 0x2C, 0x02, 0xCE, 0x6A, 0xF2, 0x06, 0x9D, + 0x98, 0xE5, 0x3C, 0xB0, 0x98, 0xB5, 0x4D, 0xD3, 0x40, 0x04, 0x05, 0x28, 0x57, 0x40, 0x04, 0x0A, + 0x50, 0x2A, 0x4B, 0x02, 0x1F, 0x53, 0xBD, 0x74, 0x54, 0x59, 0xBF, 0x1B, 0x5A, 0x41, 0xAC, 0x65, + 0xA7, 0xF0, 0x33, 0x0C, 0x58, 0x6D, 0xB6, 0x69, 0x68, 0x4F, 0x2B, 0x87, 0x55, 0xB7, 0x38, 0x50, + 0xC8, 0x5D, 0x7E, 0x8A, 0x1D, 0x0C, 0x04, 0x8F, 0xCD, 0x1D, 0x94, 0xDD, 0x4F, 0xA1, 0xEC, 0xA1, + 0x7C, 0xAD, 0x8D, 0xC5, 0x52, 0x4D, 0xBE, 0x0A, 0x3E, 0x9E, 0x55, 0x32, 0xDA, 0xA3, 0x37, 0x03, + 0xBD, 0x44, 0x3D, 0x8F, 0x55, 0x34, 0x3B, 0x6E, 0x4F, 0x03, 0x99, 0x73, 0x89, 0x93, 0xE5, 0xFE, + 0x74, 0x13, 0xB7, 0xCB, 0xE6, 0xA4, 0x4B, 0x63, 0x90, 0x65, 0xED, 0x16, 0x25, 0x77, 0xE9, 0x54, + 0x67, 0x11, 0xDB, 0x89, 0x44, 0xB3, 0x6E, 0xF6, 0x89, 0x7E, 0x37, 0x05, 0x47, 0xE7, 0xB2, 0xFB, + 0xF5, 0x2D, 0x70, 0xDD, 0x80, 0x37, 0xDE, 0x0A, 0x8E, 0xFB, 0x06, 0x1C, 0x00, 0x4D, 0xE0, 0x1E, + 0x80, 0x0C, 0x73, 0xFB, 0x47, 0x00, 0xE8, 0x2C, 0x89, 0x6E, 0xCF, 0x0C, 0x66, 0x87, 0x64, 0x55, + 0x73, 0x87, 0xB5, 0xD2, 0x39, 0xF2, 0x54, 0xA3, 0xAD, 0x24, 0xEF, 0x09, 0xC4, 0x2E, 0x47, 0x0C, + 0x83, 0x4F, 0x44, 0x6E, 0x25, 0xA9, 0x0C, 0x8F, 0x43, 0xE0, 0xD3, 0xB4, 0x30, 0x50, 0x54, 0xF9, + 0x41, 0x57, 0xC9, 0x63, 0xE6, 0x03, 0x00, 0xC1, 0xED, 0xE9, 0xAB, 0x60, 0x4F, 0x62, 0x94, 0x41, + 0x2A, 0xFE, 0x01, 0x56, 0x11, 0x10, 0xB3, 0x65, 0x4F, 0x11, 0xCC, 0x37, 0x4A, 0x10, 0x2C, 0x8E, + 0x3C, 0x80, 0x40, 0x3A, 0x30, 0x20, 0x02, 0x96, 0x10, 0x3F, 0x13, 0x64, 0xA7, 0x1E, 0x17, 0x53, + 0x90, 0x02, 0x28, 0x87, 0x00, 0xB2, 0xC1, 0xE0, 0x29, 0x08, 0x24, 0x50, 0xC9, 0xFE, 0x37, 0x3C, + 0x28, 0x30, 0x67, 0x75, 0x01, 0x9C, 0x20, 0x4E, 0x0A, 0xE0, 0xAC, 0xAF, 0x21, 0x90, 0x3E, 0x0D, + 0x4C, 0x41, 0xBB, 0x42, 0x13, 0x05, 0x63, 0xA4, 0x64, 0x81, 0x43, 0x28, 0x40, 0xED, 0x44, 0x00, + 0x01, 0x2C, 0x78, 0x29, 0x85, 0x2C, 0x38, 0x56, 0x62, 0x1A, 0xC0, 0x1D, 0x35, 0x84, 0x00, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, + 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, + 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, + 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, + 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, + 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, + 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, + 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, + 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, + 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, + 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, + 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, + 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, + 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, + 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, + 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, + 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, + 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, + 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, + 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, + 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, + 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, + 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, + 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, + 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, + 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, + 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, + 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, + 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, + 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, + 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, + 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, + 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, + 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, + 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, + 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, + 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, + 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, + 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, + 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, + 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, + 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, + 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, + 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, + 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, + 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, + 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, + 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, + 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, + 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, + 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, + 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, + 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, + 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, + 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, + 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, + 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, + 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, + 0x0D, 0x21, 0x00, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, + 0x00, 0x6A, 0x00, 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, + 0xAE, 0x6C, 0xEB, 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, + 0x0A, 0xC7, 0x03, 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, + 0xA4, 0x10, 0xA8, 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, + 0x9E, 0x18, 0x02, 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, + 0xD4, 0x81, 0x01, 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, + 0x0D, 0x08, 0x05, 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, + 0x04, 0x06, 0x10, 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, + 0x93, 0x09, 0x0C, 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, + 0x0C, 0x39, 0x9A, 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, + 0xAB, 0x5B, 0x4A, 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, + 0x0D, 0x0D, 0x07, 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, + 0x0E, 0x7B, 0x04, 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, + 0x92, 0x0C, 0x0E, 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, + 0x5B, 0x03, 0x0E, 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, + 0x98, 0xBE, 0x73, 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, + 0xB0, 0x6A, 0xA3, 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, + 0xBC, 0xA5, 0x0C, 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, + 0x04, 0x32, 0x53, 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, + 0x67, 0x8E, 0xA2, 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, + 0x33, 0xA0, 0x2B, 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, + 0x0E, 0x10, 0xC0, 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, + 0x0A, 0x08, 0xF8, 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, + 0x1D, 0x8A, 0x47, 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, + 0x22, 0x22, 0x82, 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, + 0x6B, 0x50, 0xE0, 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, + 0xA3, 0x2D, 0x60, 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, + 0x94, 0x14, 0x7F, 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, + 0x05, 0x30, 0x4A, 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, + 0x53, 0x20, 0xC1, 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, + 0x10, 0x03, 0x80, 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, + 0x26, 0x0F, 0x28, 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, + 0xC6, 0x0A, 0x02, 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, + 0xA0, 0xC0, 0x28, 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, + 0x42, 0x01, 0x5A, 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, + 0x88, 0x33, 0x14, 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, + 0x6A, 0xC4, 0x80, 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, + 0x28, 0xC2, 0xE2, 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, + 0x21, 0xA4, 0x0C, 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, + 0x4A, 0x93, 0x29, 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, + 0x94, 0x0C, 0x38, 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, + 0x56, 0x74, 0x54, 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, + 0x99, 0x83, 0x8A, 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, + 0x10, 0x02, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, + 0x6A, 0x00, 0x2E, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x00, 0x40, 0x62, 0xB9, 0x28, 0x08, 0x41, 0x28, + 0x4B, 0xE9, 0xBE, 0x70, 0x2C, 0xCF, 0x74, 0x6D, 0xDF, 0xE5, 0xF1, 0x3C, 0x69, 0x52, 0x24, 0x0F, + 0x82, 0xE1, 0x60, 0x00, 0x26, 0x5A, 0xB8, 0xA4, 0x72, 0xC9, 0x94, 0xE9, 0x22, 0x12, 0xC9, 0x64, + 0xF2, 0x18, 0x04, 0xAE, 0xD7, 0x01, 0xB0, 0xD0, 0xEC, 0x7A, 0xBF, 0x31, 0x48, 0x61, 0x12, 0x95, + 0x32, 0x02, 0x8E, 0x06, 0x36, 0x70, 0x50, 0x21, 0xC1, 0xF0, 0x78, 0x72, 0x91, 0x20, 0x4B, 0x55, + 0x85, 0xF5, 0xB5, 0x81, 0xE0, 0xCA, 0xFF, 0x80, 0x32, 0x0D, 0x0F, 0x53, 0x11, 0x11, 0x04, 0x07, + 0x7A, 0x57, 0x0E, 0x04, 0x6F, 0x81, 0x8F, 0x7F, 0x0B, 0x2A, 0x06, 0x94, 0x6A, 0x8A, 0x01, 0x06, + 0x04, 0x05, 0x07, 0x0B, 0x0B, 0x44, 0x94, 0xA0, 0x43, 0x24, 0x90, 0xA4, 0x37, 0x05, 0x04, 0x96, + 0x97, 0x58, 0x45, 0x09, 0x0A, 0x0C, 0x0C, 0x0A, 0x05, 0x0D, 0xB3, 0x05, 0x0A, 0x09, 0x0C, 0x05, + 0x06, 0xA3, 0x4D, 0x9F, 0xA0, 0x0B, 0xBB, 0xA5, 0x33, 0x6D, 0x08, 0x0C, 0x89, 0xAA, 0xC7, 0x8A, + 0x07, 0xAE, 0x3E, 0xC0, 0x32, 0x10, 0x07, 0x3F, 0x2A, 0x0E, 0x8C, 0x2A, 0x08, 0xD6, 0x29, 0x0E, + 0xB9, 0xCD, 0xC1, 0x22, 0x10, 0x45, 0xD2, 0xB8, 0x07, 0x56, 0x97, 0x22, 0xC8, 0x01, 0x0D, 0x0C, + 0x3E, 0x9C, 0x25, 0xCF, 0xA7, 0x04, 0xD9, 0xE2, 0xC8, 0x03, 0xD0, 0x09, 0x04, 0xD6, 0x09, 0xBA, + 0xDC, 0x30, 0x10, 0x0B, 0x06, 0xB6, 0x2A, 0x04, 0x12, 0xDC, 0x52, 0x40, 0x90, 0x60, 0x81, 0x5C, + 0x07, 0x20, 0xA8, 0x1A, 0xD0, 0x20, 0x01, 0x35, 0x07, 0x3C, 0x1C, 0x18, 0x30, 0x87, 0xCC, 0x00, + 0x03, 0x02, 0x0F, 0x12, 0x34, 0xD8, 0xA6, 0xCF, 0x44, 0xA7, 0x8F, 0x9D, 0x0E, 0x88, 0xAC, 0x75, + 0x6B, 0x22, 0xC5, 0x4B, 0x44, 0x4E, 0xFF, 0x26, 0x63, 0x80, 0x20, 0xE3, 0x81, 0x8E, 0x5D, 0x0E, + 0xA4, 0x33, 0xA6, 0x92, 0x8D, 0x03, 0x04, 0x35, 0x2F, 0x35, 0xC0, 0x98, 0xE0, 0x25, 0x4C, 0x26, + 0x07, 0x7C, 0xE4, 0xBC, 0x82, 0x40, 0xE1, 0x50, 0x3D, 0xCA, 0x52, 0x38, 0xFA, 0x89, 0xE3, 0x47, + 0xCE, 0x1F, 0x00, 0x8E, 0xAA, 0x02, 0xC2, 0x80, 0xE9, 0x92, 0x86, 0x2A, 0x0D, 0x3C, 0xA0, 0x29, + 0x55, 0xD1, 0x00, 0x8C, 0x06, 0xAC, 0x26, 0x31, 0x80, 0xC0, 0x24, 0x32, 0x04, 0x09, 0xBA, 0x9A, + 0x1B, 0x94, 0x80, 0xA3, 0x58, 0x18, 0x5A, 0xCF, 0x1C, 0x13, 0x78, 0x69, 0x9C, 0xDA, 0x2C, 0x04, + 0x22, 0x34, 0x78, 0x6B, 0x03, 0x82, 0x02, 0x44, 0x97, 0x5E, 0xD5, 0x1D, 0x60, 0xF7, 0xEE, 0xB9, + 0x07, 0x61, 0xF9, 0xD6, 0x58, 0xC0, 0x20, 0xDB, 0x1A, 0x82, 0x0B, 0x09, 0x17, 0xBE, 0xFB, 0x55, + 0x81, 0xE2, 0x1B, 0x99, 0x10, 0x39, 0xF6, 0x2A, 0x99, 0xB0, 0x61, 0x3D, 0x0E, 0x2F, 0xDF, 0x18, + 0x94, 0x87, 0xF3, 0x00, 0x01, 0x02, 0x24, 0x7F, 0x7E, 0x8C, 0x60, 0xA9, 0x68, 0x17, 0x6D, 0xCC, + 0x62, 0x91, 0x8C, 0x1A, 0x75, 0xE7, 0x2B, 0x30, 0xBA, 0xF2, 0xF1, 0xF9, 0xDA, 0x45, 0x26, 0xAE, + 0x59, 0x4E, 0xD7, 0x4E, 0xED, 0x19, 0xF7, 0x8C, 0xA3, 0x5A, 0xF7, 0xF6, 0x16, 0xF1, 0xC3, 0x68, + 0x70, 0xE1, 0xC3, 0x8B, 0xAF, 0xA1, 0x31, 0xF4, 0xB4, 0xD2, 0xD7, 0x10, 0x60, 0xE9, 0x21, 0x3C, + 0x3C, 0xFA, 0x64, 0xE3, 0x32, 0x6A, 0xD2, 0x56, 0xF0, 0xC0, 0x0F, 0x5F, 0x3A, 0xA9, 0x02, 0x70, + 0xEF, 0x4E, 0x5C, 0x3A, 0x68, 0xD7, 0xE5, 0x54, 0x72, 0xB7, 0xF2, 0xD5, 0xBC, 0xD5, 0xA0, 0x34, + 0xD7, 0xDB, 0x6E, 0xAF, 0x5A, 0x95, 0x03, 0xDE, 0x2F, 0x98, 0x73, 0xDB, 0x70, 0x01, 0xC4, 0xF2, + 0x96, 0x45, 0xB3, 0x41, 0x67, 0x5B, 0xFF, 0x7F, 0xE6, 0x00, 0x20, 0x51, 0x0C, 0xF2, 0xD0, 0x47, + 0x9C, 0x7A, 0xEA, 0x91, 0x07, 0x20, 0x4C, 0x05, 0xC8, 0xA5, 0x9E, 0x70, 0xA7, 0x31, 0x78, 0x92, + 0x24, 0x89, 0xB9, 0x70, 0x4C, 0x26, 0x41, 0x04, 0xA4, 0x40, 0x03, 0x19, 0x32, 0x72, 0xC8, 0x85, + 0x1D, 0xB9, 0x92, 0x20, 0x7F, 0xEE, 0x9D, 0x94, 0xE1, 0x49, 0x0C, 0xDD, 0x84, 0x16, 0x79, 0x11, + 0xF4, 0x11, 0x0B, 0x42, 0x62, 0x41, 0x70, 0xCB, 0x73, 0x1E, 0x0E, 0xE5, 0x20, 0x70, 0x7B, 0x10, + 0x40, 0x58, 0x5E, 0xC4, 0xE4, 0x23, 0x42, 0x02, 0x86, 0x34, 0xA2, 0x98, 0x24, 0x0A, 0x00, 0x19, + 0x63, 0x4E, 0xFD, 0x10, 0x43, 0x93, 0x32, 0x79, 0xF1, 0x90, 0x42, 0x88, 0x2E, 0x2C, 0xF0, 0x80, + 0x21, 0x0F, 0x30, 0x00, 0x5F, 0x30, 0x62, 0xF4, 0xB1, 0x61, 0x90, 0x47, 0x39, 0x18, 0xCB, 0x3F, + 0xEF, 0xF8, 0x60, 0xC0, 0x2F, 0x36, 0x3C, 0xB1, 0x22, 0x53, 0x99, 0x20, 0x90, 0x08, 0x9A, 0x5D, + 0x79, 0xD9, 0x80, 0x00, 0x29, 0xB4, 0xD6, 0x04, 0x59, 0x2C, 0xFC, 0x24, 0x13, 0x2A, 0x78, 0x76, + 0xF5, 0x95, 0x03, 0x0C, 0xA0, 0xA6, 0xA3, 0x17, 0x6E, 0x3D, 0xB2, 0xC0, 0x0F, 0x0A, 0x10, 0xB9, + 0xDA, 0x39, 0x08, 0x08, 0x90, 0x86, 0x00, 0x4E, 0x2E, 0x17, 0x86, 0x3B, 0xA5, 0x4D, 0xAA, 0x87, + 0x42, 0xAF, 0x0C, 0xE2, 0x00, 0xA6, 0x63, 0x8A, 0xF6, 0xA8, 0x0A, 0x91, 0x06, 0xF0, 0x4B, 0x9E, + 0xCE, 0x29, 0xF2, 0x17, 0x4B, 0x96, 0x16, 0x50, 0xA9, 0x9F, 0x9A, 0x02, 0x50, 0x00, 0x23, 0x81, + 0x9E, 0x1A, 0x41, 0x94, 0x47, 0x31, 0x10, 0xE6, 0x01, 0xD3, 0x98, 0xA5, 0x10, 0x2A, 0x2D, 0xF1, + 0x21, 0x46, 0x40, 0xB5, 0xDA, 0x8A, 0xD8, 0x02, 0x0D, 0x21, 0x9A, 0x80, 0x99, 0x98, 0xE0, 0x63, + 0xCE, 0x10, 0x01, 0xC8, 0x7A, 0xC2, 0x79, 0x11, 0x50, 0x65, 0x26, 0x2B, 0x9F, 0x64, 0xF9, 0xD1, + 0xE8, 0x93, 0x29, 0x32, 0x30, 0x84, 0x03, 0x0A, 0x28, 0x04, 0x2C, 0x46, 0x0B, 0x5C, 0x91, 0xAE, + 0x22, 0x64, 0x21, 0xB0, 0x13, 0x30, 0x99, 0xDC, 0xB4, 0xD3, 0xB3, 0xE9, 0x00, 0x50, 0x6A, 0xB2, + 0x00, 0xB4, 0xD1, 0x42, 0x50, 0x42, 0x00, 0xF6, 0x55, 0x51, 0xAA, 0x6A, 0x82, 0x09, 0x22, 0x08, + 0x38, 0xB0, 0x4D, 0xB7, 0x88, 0x2C, 0x60, 0x0D, 0x8B, 0xF8, 0xBE, 0x90, 0x89, 0x02, 0x0E, 0xE0, + 0x03, 0x81, 0xC0, 0x99, 0xDC, 0xAA, 0x2A, 0x44, 0xB3, 0xF8, 0xE9, 0x16, 0x04, 0x08, 0xD8, 0xC2, + 0x1C, 0x97, 0x0D, 0xCB, 0xE0, 0xC9, 0x28, 0x3A, 0x28, 0xF3, 0x5F, 0x6B, 0xBF, 0xD9, 0x72, 0xC4, + 0x62, 0x1D, 0x7F, 0x1B, 0x72, 0x0D, 0xCA, 0xBC, 0xD4, 0x86, 0x2D, 0x3E, 0xB9, 0xBC, 0x5C, 0x08, + 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, 0x6A, 0x00, + 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, 0xAE, 0x6C, 0xEB, + 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, 0x0A, 0xC7, 0x03, + 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, 0xA4, 0x10, 0xA8, + 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, 0x9E, 0x18, 0x02, + 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, 0xD4, 0x81, 0x01, + 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, 0x0D, 0x08, 0x05, + 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, 0x04, 0x06, 0x10, + 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, 0x93, 0x09, 0x0C, + 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, 0x0C, 0x39, 0x9A, + 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, 0xAB, 0x5B, 0x4A, + 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, 0x0D, 0x0D, 0x07, + 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, 0x0E, 0x7B, 0x04, + 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, 0x92, 0x0C, 0x0E, + 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, 0x5B, 0x03, 0x0E, + 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, 0x98, 0xBE, 0x73, + 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, 0xB0, 0x6A, 0xA3, + 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, 0xBC, 0xA5, 0x0C, + 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, 0x04, 0x32, 0x53, + 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, 0x67, 0x8E, 0xA2, + 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, 0x33, 0xA0, 0x2B, + 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, 0x0E, 0x10, 0xC0, + 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, 0x0A, 0x08, 0xF8, + 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, 0x1D, 0x8A, 0x47, + 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, 0x22, 0x22, 0x82, + 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, 0x6B, 0x50, 0xE0, + 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, 0xA3, 0x2D, 0x60, + 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, 0x94, 0x14, 0x7F, + 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, 0x05, 0x30, 0x4A, + 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, 0x53, 0x20, 0xC1, + 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, 0x10, 0x03, 0x80, + 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, 0x26, 0x0F, 0x28, + 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, 0xC6, 0x0A, 0x02, + 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, 0xA0, 0xC0, 0x28, + 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, 0x42, 0x01, 0x5A, + 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, 0x88, 0x33, 0x14, + 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, 0x6A, 0xC4, 0x80, + 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, 0x28, 0xC2, 0xE2, + 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, 0x21, 0xA4, 0x0C, + 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, 0x4A, 0x93, 0x29, + 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, 0x94, 0x0C, 0x38, + 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, 0x56, 0x74, 0x54, + 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, 0x99, 0x83, 0x8A, + 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, 0x10, 0x02, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, + 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, + 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, + 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, + 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, + 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, + 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, + 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, + 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, + 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, + 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, + 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, + 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, + 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, + 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, + 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, + 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, + 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, + 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, + 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, + 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, + 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, + 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, + 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, + 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, + 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, + 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, + 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, + 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, + 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, + 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, + 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, + 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, + 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, + 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, + 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, + 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, + 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, + 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, + 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, + 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, + 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, + 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, + 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, + 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, + 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, + 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, + 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, + 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, + 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, + 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, + 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, + 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, + 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, + 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, + 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, + 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, + 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, + 0x0D, 0x21, 0x00, 0x00, 0x3B}; diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_File/Send_Attachment_File.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_File/Send_Attachment_File.ino index d615e9f3a..d27e29d03 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_File/Send_Attachment_File.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_File/Send_Attachment_File.ino @@ -1,443 +1,443 @@ - - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to send Email with attachments and inline images stored in SD card. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** Assign SD card type and FS used in src/ESP_Mail_FS.h and - * change the config for that card interfaces in src/extras/SDHelper.h - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// Provide the SD card interfaces setting and mounting -#include - -// To use only SMTP functions, you can exclude the IMAP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - -#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h - - // Mount SD card. - SD_Card_Mounting(); // See src/extras/SDHelper.h - - Serial.println("Preparing SD file attachments..."); - - const char *orangeImg = "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAoUlEQVR42u3RMQ0AMAgAsCFgftHLiQpsENJaaFT+fqwRQoQgRAhChCBECEKECBGCECEIEYIQIQgRghCECEGIEIQIQYgQhCBECEKEIEQIQoQgBCFCECIEIUIQIgQhCBGCECEIEYIQIQhBiBCECEGIEIQIQQhChCBECEKEIEQIQhAiBCFCECIEIUIQghAhCBGCECEIEYIQIUKEIEQIQoQg5LoBGi/oCaOpTXoAAAAASUVORK5CYII="; - - // Write demo data to file - - static uint8_t buf[512]; - -// SDFat? -#if defined(ESP_MAIL_USE_SDFAT) // ESP_MAIL_USE_SDFAT is auto defined when you set to use SdFat in src/ESP_Mail_FS.h - SdFile file; - file.open("/orange.png", O_RDWR | O_CREAT); - file.print(orangeImg); - file.close(); - - file.open("/bin1.dat", O_RDWR | O_CREAT); - buf[0] = 'H'; - buf[1] = 'E'; - buf[2] = 'A'; - buf[3] = 'D'; - file.write(buf, 4); - - size_t i; - - for (i = 0; i < 4; i++) - { - memset(buf, i + 1, 512); - file.write(buf, 512); - } - - buf[0] = 'T'; - buf[1] = 'A'; - buf[2] = 'I'; - buf[3] = 'L'; - file.write(buf, 4); - file.close(); - -#else - -#if defined(ESP32) - File file = ESP_MAIL_DEFAULT_SD_FS.open("/orange.png", FILE_WRITE); -#else - File file = ESP_MAIL_DEFAULT_SD_FS.open("/orange.png", "w"); -#endif - file.print(orangeImg); - file.close(); - -#if defined(ESP32) - file = ESP_MAIL_DEFAULT_SD_FS.open("/bin1.dat", FILE_WRITE); -#else - file = ESP_MAIL_DEFAULT_SD_FS.open("/bin1.dat", "w"); -#endif - - buf[0] = 'H'; - buf[1] = 'E'; - buf[2] = 'A'; - buf[3] = 'D'; - file.write(buf, 4); - - size_t i; - - for (i = 0; i < 4; i++) - { - memset(buf, i + 1, 512); - file.write(buf, 512); - } - - buf[0] = 'T'; - buf[1] = 'A'; - buf[2] = 'I'; - buf[3] = 'L'; - file.write(buf, 4); - file.close(); -#endif - -#endif - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /* Declare the message class */ - SMTP_Message message; - - /* Enable the chunked data transfer with pipelining for large message if server supported */ - message.enable.chunking = true; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - - message.subject = F("Test sending Email with attachments and inline images from SD card and Flash"); - - message.addRecipient(F("user1"), RECIPIENT_EMAIL); - - /** Two alternative content versions are sending in this example e.g. plain text and html */ - String htmlMsg = "This message contains 1 inline image and 1 attachment file.

"; - - message.html.content = htmlMsg; - - /** The HTML text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.html.charSet = F("utf-8"); - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; - - message.text.content = F("This message contains 1 inline image and 1 attachment file.\r\nThe inline image will not show in the plain text message."); - - message.text.charSet = F("utf-8"); - message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader(F("Message-ID: ")); - - /* The attachment data item */ - SMTP_Attachment att[2]; - int attIndex = 0; - - /** Set the inline image info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - att[attIndex].descr.filename = F("orange.png"); - att[attIndex].descr.mime = F("image/png"); - att[attIndex].file.path = F("/orange.png"); - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - att[attIndex].file.storage_type = esp_mail_file_storage_type_sd; - - /* Need to be base64 transfer encoding for inline image */ - att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /** The orange.png file is already base64 encoded file. - * Then set the content encoding to match the transfer encoding - * which no encoding was taken place prior to sending. - */ - att[attIndex].descr.content_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add inline image to the message */ - message.addInlineImage(att[attIndex]); - - /** Set the attachment info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - - attIndex++; - att[attIndex].descr.filename = F("bin1.dat"); - att[attIndex].descr.mime = F("application/octet-stream"); // binary data - att[attIndex].descr.description = F("This is binary data"); - att[attIndex].file.path = F("/bin1.dat"); - att[attIndex].file.storage_type = esp_mail_file_storage_type_sd; - att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add attachment to the message */ - message.addAttachment(att[attIndex]); - - /* Connect to the server */ - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* Start sending the Email and close the session */ - if (!MailClient.sendMail(&smtp, &message, true)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } + + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email with attachments and inline images stored in SD card. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// Provide the SD card interfaces setting and mounting +#include + +// To use only SMTP functions, you can exclude the IMAP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + +#if defined(ESP_MAIL_DEFAULT_SD_FS) // defined in src/ESP_Mail_FS.h + + // Mount SD card. + SD_Card_Mounting(); // See src/extras/SDHelper.h + + Serial.println("Preparing SD file attachments..."); + + const char *orangeImg = "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAoUlEQVR42u3RMQ0AMAgAsCFgftHLiQpsENJaaFT+fqwRQoQgRAhChCBECEKECBGCECEIEYIQIQgRghCECEGIEIQIQYgQhCBECEKEIEQIQoQgBCFCECIEIUIQIgQhCBGCECEIEYIQIQhBiBCECEGIEIQIQQhChCBECEKEIEQIQhAiBCFCECIEIUIQghAhCBGCECEIEYIQIUKEIEQIQoQg5LoBGi/oCaOpTXoAAAAASUVORK5CYII="; + + // Write demo data to file + + static uint8_t buf[512]; + +// SDFat? +#if defined(ESP_MAIL_USE_SDFAT) // ESP_MAIL_USE_SDFAT is auto defined when you set to use SdFat in src/ESP_Mail_FS.h + SdFile file; + file.open("/orange.png", O_RDWR | O_CREAT); + file.print(orangeImg); + file.close(); + + file.open("/bin1.dat", O_RDWR | O_CREAT); + buf[0] = 'H'; + buf[1] = 'E'; + buf[2] = 'A'; + buf[3] = 'D'; + file.write(buf, 4); + + size_t i; + + for (i = 0; i < 4; i++) + { + memset(buf, i + 1, 512); + file.write(buf, 512); + } + + buf[0] = 'T'; + buf[1] = 'A'; + buf[2] = 'I'; + buf[3] = 'L'; + file.write(buf, 4); + file.close(); + +#else + +#if defined(ESP32) + File file = ESP_MAIL_DEFAULT_SD_FS.open("/orange.png", FILE_WRITE); +#else + File file = ESP_MAIL_DEFAULT_SD_FS.open("/orange.png", "w"); +#endif + file.print(orangeImg); + file.close(); + +#if defined(ESP32) + file = ESP_MAIL_DEFAULT_SD_FS.open("/bin1.dat", FILE_WRITE); +#else + file = ESP_MAIL_DEFAULT_SD_FS.open("/bin1.dat", "w"); +#endif + + buf[0] = 'H'; + buf[1] = 'E'; + buf[2] = 'A'; + buf[3] = 'D'; + file.write(buf, 4); + + size_t i; + + for (i = 0; i < 4; i++) + { + memset(buf, i + 1, 512); + file.write(buf, 512); + } + + buf[0] = 'T'; + buf[1] = 'A'; + buf[2] = 'I'; + buf[3] = 'L'; + file.write(buf, 4); + file.close(); +#endif + +#endif + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Enable the chunked data transfer with pipelining for large message if server supported */ + message.enable.chunking = true; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + + message.subject = F("Test sending Email with attachments and inline images from SD card and Flash"); + + message.addRecipient(F("user1"), RECIPIENT_EMAIL); + + /** Two alternative content versions are sending in this example e.g. plain text and html */ + String htmlMsg = "This message contains 1 inline image and 1 attachment file.

"; + + message.html.content = htmlMsg; + + /** The HTML text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("utf-8"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; + + message.text.content = F("This message contains 1 inline image and 1 attachment file.\r\nThe inline image will not show in the plain text message."); + + message.text.charSet = F("utf-8"); + message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* The attachment data item */ + SMTP_Attachment att[2]; + int attIndex = 0; + + /** Set the inline image info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + att[attIndex].descr.filename = F("orange.png"); + att[attIndex].descr.mime = F("image/png"); + att[attIndex].file.path = F("/orange.png"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + att[attIndex].file.storage_type = esp_mail_file_storage_type_sd; + + /* Need to be base64 transfer encoding for inline image */ + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /** The orange.png file is already base64 encoded file. + * Then set the content encoding to match the transfer encoding + * which no encoding was taken place prior to sending. + */ + att[attIndex].descr.content_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att[attIndex]); + + /** Set the attachment info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + + attIndex++; + att[attIndex].descr.filename = F("bin1.dat"); + att[attIndex].descr.mime = F("application/octet-stream"); // binary data + att[attIndex].descr.description = F("This is binary data"); + att[attIndex].file.path = F("/bin1.dat"); + att[attIndex].file.storage_type = esp_mail_file_storage_type_sd; + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add attachment to the message */ + message.addAttachment(att[attIndex]); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending the Email and close the session */ + if (!MailClient.sendMail(&smtp, &message, true)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Flash/Send_Attachment_Flash.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Flash/Send_Attachment_Flash.ino index 49ef4f54f..a91c9ed92 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Flash/Send_Attachment_Flash.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_Flash/Send_Attachment_Flash.ino @@ -1,411 +1,411 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to send Email with attachments and inline images stored in SPIFFS/LittleFS filesystem. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -/** Assign SD card type and FS used in src/ESP_Mail_FS.h and - * change the config for that card interfaces in src/extras/SDHelper.h - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only SMTP functions, you can exclude the IMAP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - -#if defined(ESP_MAIL_DEFAULT_FLASH_FS) // defined in src/ESP_Mail_FS.h - - // Mount SPIFFS/LittleFS filesystem. - ESP_MAIL_DEFAULT_FLASH_FS.begin(); - - Serial.println("Preparing flash file attachments..."); - - const char *orangeImg = "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAoUlEQVR42u3RMQ0AMAgAsCFgftHLiQpsENJaaFT+fqwRQoQgRAhChCBECEKECBGCECEIEYIQIQgRghCECEGIEIQIQYgQhCBECEKEIEQIQoQgBCFCECIEIUIQIgQhCBGCECEIEYIQIQhBiBCECEGIEIQIQQhChCBECEKEIEQIQhAiBCFCECIEIUIQghAhCBGCECEIEYIQIUKEIEQIQoQg5LoBGi/oCaOpTXoAAAAASUVORK5CYII="; - - // Write demo data to file - - static uint8_t buf[512]; - -#if defined(ESP32) - File file = ESP_MAIL_DEFAULT_FLASH_FS.open("/orange.png", FILE_WRITE); -#else - File file = ESP_MAIL_DEFAULT_FLASH_FS.open("/orange.png", "w"); -#endif - - file.print(orangeImg); - file.close(); - -#if defined(ESP32) - file = ESP_MAIL_DEFAULT_FLASH_FS.open("/bin1.dat", FILE_WRITE); -#else - file = ESP_MAIL_DEFAULT_FLASH_FS.open("/bin1.dat", "w"); -#endif - - buf[0] = 'H'; - buf[1] = 'E'; - buf[2] = 'A'; - buf[3] = 'D'; - file.write(buf, 4); - - size_t i; - - for (i = 0; i < 4; i++) - { - memset(buf, i + 1, 512); - file.write(buf, 512); - } - - buf[0] = 'T'; - buf[1] = 'A'; - buf[2] = 'I'; - buf[3] = 'L'; - file.write(buf, 4); - file.close(); - -#endif - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /* Declare the message class */ - SMTP_Message message; - - /* Enable the chunked data transfer with pipelining for large message if server supported */ - message.enable.chunking = true; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - - message.subject = F("Test sending Email with attachments and inline images from flash filesystem"); - - message.addRecipient(F("user1"), RECIPIENT_EMAIL); - - /** Two alternative content versions are sending in this example e.g. plain text and html */ - String htmlMsg = "This message contains 1 inline image and 1 attachment file.

"; - - message.html.content = htmlMsg; - - /** The HTML text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.html.charSet = F("utf-8"); - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; - - message.text.content = F("This message contains 1 inline image and 1 attachment file.\r\nThe inline image will not show in the plain text message."); - - message.text.charSet = F("utf-8"); - message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader(F("Message-ID: ")); - - /* The attachment data item */ - SMTP_Attachment att[2]; - int attIndex = 0; - - /** Set the inline image info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - att[attIndex].descr.filename = F("orange.png"); - att[attIndex].descr.mime = F("image/png"); - att[attIndex].file.path = F("/orange.png"); - - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - att[attIndex].file.storage_type = esp_mail_file_storage_type_flash; - - /* Need to be base64 transfer encoding for inline image */ - att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /** The orange.png file is already base64 encoded file. - * Then set the content encoding to match the transfer encoding - * which no encoding was taken place prior to sending. - */ - att[attIndex].descr.content_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add inline image to the message */ - message.addInlineImage(att[attIndex]); - - /** Set the attachment info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - - attIndex++; - att[attIndex].descr.filename = F("bin1.dat"); - att[attIndex].descr.mime = F("application/octet-stream"); // binary data - att[attIndex].descr.description = F("This is binary data"); - att[attIndex].file.path = F("/bin1.dat"); - att[attIndex].file.storage_type = esp_mail_file_storage_type_flash; - att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add attachment to the message */ - message.addAttachment(att[attIndex]); - - /* Connect to the server */ - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* Start sending the Email and close the session */ - if (!MailClient.sendMail(&smtp, &message, true)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email with attachments and inline images stored in SPIFFS/LittleFS filesystem. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +/** Assign SD card type and FS used in src/ESP_Mail_FS.h and + * change the config for that card interfaces in src/extras/SDHelper.h + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only SMTP functions, you can exclude the IMAP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + +#if defined(ESP_MAIL_DEFAULT_FLASH_FS) // defined in src/ESP_Mail_FS.h + + // Mount SPIFFS/LittleFS filesystem. + ESP_MAIL_DEFAULT_FLASH_FS.begin(); + + Serial.println("Preparing flash file attachments..."); + + const char *orangeImg = "iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAAoUlEQVR42u3RMQ0AMAgAsCFgftHLiQpsENJaaFT+fqwRQoQgRAhChCBECEKECBGCECEIEYIQIQgRghCECEGIEIQIQYgQhCBECEKEIEQIQoQgBCFCECIEIUIQIgQhCBGCECEIEYIQIQhBiBCECEGIEIQIQQhChCBECEKEIEQIQhAiBCFCECIEIUIQghAhCBGCECEIEYIQIUKEIEQIQoQg5LoBGi/oCaOpTXoAAAAASUVORK5CYII="; + + // Write demo data to file + + static uint8_t buf[512]; + +#if defined(ESP32) + File file = ESP_MAIL_DEFAULT_FLASH_FS.open("/orange.png", FILE_WRITE); +#else + File file = ESP_MAIL_DEFAULT_FLASH_FS.open("/orange.png", "w"); +#endif + + file.print(orangeImg); + file.close(); + +#if defined(ESP32) + file = ESP_MAIL_DEFAULT_FLASH_FS.open("/bin1.dat", FILE_WRITE); +#else + file = ESP_MAIL_DEFAULT_FLASH_FS.open("/bin1.dat", "w"); +#endif + + buf[0] = 'H'; + buf[1] = 'E'; + buf[2] = 'A'; + buf[3] = 'D'; + file.write(buf, 4); + + size_t i; + + for (i = 0; i < 4; i++) + { + memset(buf, i + 1, 512); + file.write(buf, 512); + } + + buf[0] = 'T'; + buf[1] = 'A'; + buf[2] = 'I'; + buf[3] = 'L'; + file.write(buf, 4); + file.close(); + +#endif + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Enable the chunked data transfer with pipelining for large message if server supported */ + message.enable.chunking = true; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + + message.subject = F("Test sending Email with attachments and inline images from flash filesystem"); + + message.addRecipient(F("user1"), RECIPIENT_EMAIL); + + /** Two alternative content versions are sending in this example e.g. plain text and html */ + String htmlMsg = "This message contains 1 inline image and 1 attachment file.

"; + + message.html.content = htmlMsg; + + /** The HTML text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("utf-8"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; + + message.text.content = F("This message contains 1 inline image and 1 attachment file.\r\nThe inline image will not show in the plain text message."); + + message.text.charSet = F("utf-8"); + message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* The attachment data item */ + SMTP_Attachment att[2]; + int attIndex = 0; + + /** Set the inline image info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + att[attIndex].descr.filename = F("orange.png"); + att[attIndex].descr.mime = F("image/png"); + att[attIndex].file.path = F("/orange.png"); + + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + att[attIndex].file.storage_type = esp_mail_file_storage_type_flash; + + /* Need to be base64 transfer encoding for inline image */ + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /** The orange.png file is already base64 encoded file. + * Then set the content encoding to match the transfer encoding + * which no encoding was taken place prior to sending. + */ + att[attIndex].descr.content_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att[attIndex]); + + /** Set the attachment info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + + attIndex++; + att[attIndex].descr.filename = F("bin1.dat"); + att[attIndex].descr.mime = F("application/octet-stream"); // binary data + att[attIndex].descr.description = F("This is binary data"); + att[attIndex].file.path = F("/bin1.dat"); + att[attIndex].file.storage_type = esp_mail_file_storage_type_flash; + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add attachment to the message */ + message.addAttachment(att[attIndex]); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending the Email and close the session */ + if (!MailClient.sendMail(&smtp, &message, true)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_PSRAM/Send_Attachment_PSRAM.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_PSRAM/Send_Attachment_PSRAM.ino index 2cd102ea6..4ea0ec390 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_PSRAM/Send_Attachment_PSRAM.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Attachment_PSRAM/Send_Attachment_PSRAM.ino @@ -1,318 +1,318 @@ - - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to send Email with attachment stored in PSRAM (ESP32 only). - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) -#include -#elif defined(ESP8266) -#include -#endif - -#include - -// To use only SMTP functions, you can exclude the IMAP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" - "-----END CERTIFICATE-----\n"; - -void setup() -{ - - Serial.begin(115200); - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - message.subject = F("Test sending plain text Email with PSRAM attachment"); - message.addRecipient(F("Someone"), RECIPIENT_EMAIL); - - String textMsg = "This is simple plain text message with PSRAM attachment"; - message.text.content = textMsg; - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.text.charSet = F("us-ascii"); - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - // If this is a reply message - // message.in_reply_to = ""; - // message.references = " "; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - // message.response.reply_to = "someone@somemail.com"; - // message.response.return_path = "someone@somemail.com"; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader(F("Message-ID: ")); - - // For Root CA certificate verification (ESP8266 and ESP32 only) - // config.certificate.cert_data = rootCACert; - // or - // config.certificate.cert_file = "/path/to/der/file"; - // config.certificate.cert_file_storage_type = esp_mail_file_storage_type_flash; // esp_mail_file_storage_type_sd - // config.certificate.verify = true; - - // The WiFiNINA firmware the Root CA certification can be added via the option in Firmware update tool in Arduino IDE - - /* The attachment data item */ - SMTP_Attachment att[1]; - int attIndex = 0; - -#if defined(ESP32) - - int dlen = 3 * 1024 * 1024 + 512 * 1024; - uint8_t *data = (uint8_t *)ps_malloc(dlen); - - if (psramFound()) - { - memset(data, 0xff, dlen); - - att[attIndex].descr.filename = F("data.dat"); - att[attIndex].descr.mime = F("application/octet-stream"); - att[attIndex].descr.description = F("This is binary data"); - att[attIndex].blob.data = data; - att[attIndex].blob.size = dlen; - att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add inline image to the message */ - message.addInlineImage(att[attIndex]); - } - -#endif - - /* Connect to the server */ - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } -} + + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email with attachment stored in PSRAM (ESP32 only). + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) +#include +#elif defined(ESP8266) +#include +#endif + +#include + +// To use only SMTP functions, you can exclude the IMAP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" + "-----END CERTIFICATE-----\n"; + +void setup() +{ + + Serial.begin(115200); + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email with PSRAM attachment"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + String textMsg = "This is simple plain text message with PSRAM attachment"; + message.text.content = textMsg; + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + // If this is a reply message + // message.in_reply_to = ""; + // message.references = " "; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + // message.response.reply_to = "someone@somemail.com"; + // message.response.return_path = "someone@somemail.com"; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + // For Root CA certificate verification (ESP8266 and ESP32 only) + // config.certificate.cert_data = rootCACert; + // or + // config.certificate.cert_file = "/path/to/der/file"; + // config.certificate.cert_file_storage_type = esp_mail_file_storage_type_flash; // esp_mail_file_storage_type_sd + // config.certificate.verify = true; + + // The WiFiNINA firmware the Root CA certification can be added via the option in Firmware update tool in Arduino IDE + + /* The attachment data item */ + SMTP_Attachment att[1]; + int attIndex = 0; + +#if defined(ESP32) + + int dlen = 3 * 1024 * 1024 + 512 * 1024; + uint8_t *data = (uint8_t *)ps_malloc(dlen); + + if (psramFound()) + { + memset(data, 0xff, dlen); + + att[attIndex].descr.filename = F("data.dat"); + att[attIndex].descr.mime = F("application/octet-stream"); + att[attIndex].descr.description = F("This is binary data"); + att[attIndex].blob.data = data; + att[attIndex].blob.size = dlen; + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att[attIndex]); + } + +#endif + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Camera_Image/ESP_Camera/ESP_Camera.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Camera_Image/ESP_Camera/ESP_Camera.ino index ca1d27850..718689e76 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Camera_Image/ESP_Camera/ESP_Camera.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Camera_Image/ESP_Camera/ESP_Camera.ino @@ -1,325 +1,325 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -/** - * This example shows how to send Email with inline image from ESP32 camera module. - * - * The ESP32 board used in this example is ESP32 PSRAM Timer Camera X (OV3660). - */ - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) -#include -#endif - -#include - -#include "esp_camera.h" - -// =================== -// Select camera model -// =================== -//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM -#define CAMERA_MODEL_ESP_EYE // Has PSRAM -//#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM -//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM -//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM -//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM -//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM -//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM -//#define CAMERA_MODEL_AI_THINKER // Has PSRAM -//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM -//#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM -// ** Espressif Internal Boards ** -//#define CAMERA_MODEL_ESP32_CAM_BOARD -//#define CAMERA_MODEL_ESP32S2_CAM_BOARD -//#define CAMERA_MODEL_ESP32S3_CAM_LCD -//#define CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3 // Has PSRAM -//#define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM -#include "camera_pins.h" - -// The camera_pins.h was taken from -//https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/Camera/CameraWebServer - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -void setup() -{ - - Serial.begin(115200); - - Serial.println(); - - camera_config_t camCfg; - camCfg.ledc_channel = LEDC_CHANNEL_0; - camCfg.ledc_timer = LEDC_TIMER_0; - camCfg.pin_d0 = Y2_GPIO_NUM; - camCfg.pin_d1 = Y3_GPIO_NUM; - camCfg.pin_d2 = Y4_GPIO_NUM; - camCfg.pin_d3 = Y5_GPIO_NUM; - camCfg.pin_d4 = Y6_GPIO_NUM; - camCfg.pin_d5 = Y7_GPIO_NUM; - camCfg.pin_d6 = Y8_GPIO_NUM; - camCfg.pin_d7 = Y9_GPIO_NUM; - camCfg.pin_xclk = XCLK_GPIO_NUM; - camCfg.pin_pclk = PCLK_GPIO_NUM; - camCfg.pin_vsync = VSYNC_GPIO_NUM; - camCfg.pin_href = HREF_GPIO_NUM; - camCfg.pin_sscb_sda = SIOD_GPIO_NUM; - camCfg.pin_sscb_scl = SIOC_GPIO_NUM; - camCfg.pin_pwdn = PWDN_GPIO_NUM; - camCfg.pin_reset = RESET_GPIO_NUM; - camCfg.xclk_freq_hz = 20000000; - camCfg.pixel_format = PIXFORMAT_JPEG; - camCfg.frame_size = FRAMESIZE_QXGA; - camCfg.jpeg_quality = 10; - camCfg.fb_count = 2; - - // camera init - esp_err_t err = esp_camera_init(&camCfg); - if (err != ESP_OK) - { - Serial.printf("Camera init failed with error 0x%x", err); - return; - } - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /* Declare the message class */ - SMTP_Message message; - - /* Enable the chunked data transfer with pipelining for large message if server supported */ - message.enable.chunking = true; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - - message.subject = F("Test sending camera image"); - message.addRecipient(F("user1"), RECIPIENT_EMAIL); - - message.html.content = F("The camera image.

\"esp32"); - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) <- not supported for message from blob and file - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - /** The HTML text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.html.charSet = F("utf-8"); - - camera_fb_t *fb = esp_camera_fb_get(); - - SMTP_Attachment att; - - /** Set the inline image info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - att.descr.filename = F("camera.jpg"); - att.descr.mime = F("image/jpg"); - - att.blob.data = fb->buf; - att.blob.size = fb->len; - - att.descr.content_id = F("image-001"); // The content id (cid) of camera.jpg image in the src tag - - /* Need to be base64 transfer encoding for inline image */ - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add inline image to the message */ - message.addInlineImage(att); - - /* Connect to the server */ - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* Start sending the Email and close the session */ - if (!MailClient.sendMail(&smtp, &message, true)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +/** + * This example shows how to send Email with inline image from ESP32 camera module. + * + * The ESP32 board used in this example is ESP32 PSRAM Timer Camera X (OV3660). + */ + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) +#include +#endif + +#include + +#include "esp_camera.h" + +// =================== +// Select camera model +// =================== +//#define CAMERA_MODEL_WROVER_KIT // Has PSRAM +#define CAMERA_MODEL_ESP_EYE // Has PSRAM +//#define CAMERA_MODEL_ESP32S3_EYE // Has PSRAM +//#define CAMERA_MODEL_M5STACK_PSRAM // Has PSRAM +//#define CAMERA_MODEL_M5STACK_V2_PSRAM // M5Camera version B Has PSRAM +//#define CAMERA_MODEL_M5STACK_WIDE // Has PSRAM +//#define CAMERA_MODEL_M5STACK_ESP32CAM // No PSRAM +//#define CAMERA_MODEL_M5STACK_UNITCAM // No PSRAM +//#define CAMERA_MODEL_AI_THINKER // Has PSRAM +//#define CAMERA_MODEL_TTGO_T_JOURNAL // No PSRAM +//#define CAMERA_MODEL_XIAO_ESP32S3 // Has PSRAM +// ** Espressif Internal Boards ** +//#define CAMERA_MODEL_ESP32_CAM_BOARD +//#define CAMERA_MODEL_ESP32S2_CAM_BOARD +//#define CAMERA_MODEL_ESP32S3_CAM_LCD +//#define CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3 // Has PSRAM +//#define CAMERA_MODEL_DFRobot_Romeo_ESP32S3 // Has PSRAM +#include "camera_pins.h" + +// The camera_pins.h was taken from +//https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/Camera/CameraWebServer + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +void setup() +{ + + Serial.begin(115200); + + Serial.println(); + + camera_config_t camCfg; + camCfg.ledc_channel = LEDC_CHANNEL_0; + camCfg.ledc_timer = LEDC_TIMER_0; + camCfg.pin_d0 = Y2_GPIO_NUM; + camCfg.pin_d1 = Y3_GPIO_NUM; + camCfg.pin_d2 = Y4_GPIO_NUM; + camCfg.pin_d3 = Y5_GPIO_NUM; + camCfg.pin_d4 = Y6_GPIO_NUM; + camCfg.pin_d5 = Y7_GPIO_NUM; + camCfg.pin_d6 = Y8_GPIO_NUM; + camCfg.pin_d7 = Y9_GPIO_NUM; + camCfg.pin_xclk = XCLK_GPIO_NUM; + camCfg.pin_pclk = PCLK_GPIO_NUM; + camCfg.pin_vsync = VSYNC_GPIO_NUM; + camCfg.pin_href = HREF_GPIO_NUM; + camCfg.pin_sscb_sda = SIOD_GPIO_NUM; + camCfg.pin_sscb_scl = SIOC_GPIO_NUM; + camCfg.pin_pwdn = PWDN_GPIO_NUM; + camCfg.pin_reset = RESET_GPIO_NUM; + camCfg.xclk_freq_hz = 20000000; + camCfg.pixel_format = PIXFORMAT_JPEG; + camCfg.frame_size = FRAMESIZE_QXGA; + camCfg.jpeg_quality = 10; + camCfg.fb_count = 2; + + // camera init + esp_err_t err = esp_camera_init(&camCfg); + if (err != ESP_OK) + { + Serial.printf("Camera init failed with error 0x%x", err); + return; + } + + Serial.print("Connecting to AP"); + + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(200); + } + + Serial.println(""); + Serial.println("WiFi connected."); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Enable the chunked data transfer with pipelining for large message if server supported */ + message.enable.chunking = true; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + + message.subject = F("Test sending camera image"); + message.addRecipient(F("user1"), RECIPIENT_EMAIL); + + message.html.content = F("The camera image.

\"esp32"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) <- not supported for message from blob and file + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + /** The HTML text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("utf-8"); + + camera_fb_t *fb = esp_camera_fb_get(); + + SMTP_Attachment att; + + /** Set the inline image info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + att.descr.filename = F("camera.jpg"); + att.descr.mime = F("image/jpg"); + + att.blob.data = fb->buf; + att.blob.size = fb->len; + + att.descr.content_id = F("image-001"); // The content id (cid) of camera.jpg image in the src tag + + /* Need to be base64 transfer encoding for inline image */ + att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending the Email and close the session */ + if (!MailClient.sendMail(&smtp, &message, true)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Camera_Image/ESP_Camera/camera_pins.h b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Camera_Image/ESP_Camera/camera_pins.h index fdbdd1a31..34e4957e6 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Camera_Image/ESP_Camera/camera_pins.h +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Camera_Image/ESP_Camera/camera_pins.h @@ -1,317 +1,317 @@ - -#if defined(CAMERA_MODEL_WROVER_KIT) -#define PWDN_GPIO_NUM -1 -#define RESET_GPIO_NUM -1 -#define XCLK_GPIO_NUM 21 -#define SIOD_GPIO_NUM 26 -#define SIOC_GPIO_NUM 27 - -#define Y9_GPIO_NUM 35 -#define Y8_GPIO_NUM 34 -#define Y7_GPIO_NUM 39 -#define Y6_GPIO_NUM 36 -#define Y5_GPIO_NUM 19 -#define Y4_GPIO_NUM 18 -#define Y3_GPIO_NUM 5 -#define Y2_GPIO_NUM 4 -#define VSYNC_GPIO_NUM 25 -#define HREF_GPIO_NUM 23 -#define PCLK_GPIO_NUM 22 - -#elif defined(CAMERA_MODEL_ESP_EYE) -#define PWDN_GPIO_NUM -1 -#define RESET_GPIO_NUM -1 -#define XCLK_GPIO_NUM 4 -#define SIOD_GPIO_NUM 18 -#define SIOC_GPIO_NUM 23 - -#define Y9_GPIO_NUM 36 -#define Y8_GPIO_NUM 37 -#define Y7_GPIO_NUM 38 -#define Y6_GPIO_NUM 39 -#define Y5_GPIO_NUM 35 -#define Y4_GPIO_NUM 14 -#define Y3_GPIO_NUM 13 -#define Y2_GPIO_NUM 34 -#define VSYNC_GPIO_NUM 5 -#define HREF_GPIO_NUM 27 -#define PCLK_GPIO_NUM 25 - -#define LED_GPIO_NUM 22 - -#elif defined(CAMERA_MODEL_M5STACK_PSRAM) -#define PWDN_GPIO_NUM -1 -#define RESET_GPIO_NUM 15 -#define XCLK_GPIO_NUM 27 -#define SIOD_GPIO_NUM 25 -#define SIOC_GPIO_NUM 23 - -#define Y9_GPIO_NUM 19 -#define Y8_GPIO_NUM 36 -#define Y7_GPIO_NUM 18 -#define Y6_GPIO_NUM 39 -#define Y5_GPIO_NUM 5 -#define Y4_GPIO_NUM 34 -#define Y3_GPIO_NUM 35 -#define Y2_GPIO_NUM 32 -#define VSYNC_GPIO_NUM 22 -#define HREF_GPIO_NUM 26 -#define PCLK_GPIO_NUM 21 - -#elif defined(CAMERA_MODEL_M5STACK_V2_PSRAM) -#define PWDN_GPIO_NUM -1 -#define RESET_GPIO_NUM 15 -#define XCLK_GPIO_NUM 27 -#define SIOD_GPIO_NUM 22 -#define SIOC_GPIO_NUM 23 - -#define Y9_GPIO_NUM 19 -#define Y8_GPIO_NUM 36 -#define Y7_GPIO_NUM 18 -#define Y6_GPIO_NUM 39 -#define Y5_GPIO_NUM 5 -#define Y4_GPIO_NUM 34 -#define Y3_GPIO_NUM 35 -#define Y2_GPIO_NUM 32 -#define VSYNC_GPIO_NUM 25 -#define HREF_GPIO_NUM 26 -#define PCLK_GPIO_NUM 21 - -#elif defined(CAMERA_MODEL_M5STACK_WIDE) -#define PWDN_GPIO_NUM -1 -#define RESET_GPIO_NUM 15 -#define XCLK_GPIO_NUM 27 -#define SIOD_GPIO_NUM 22 -#define SIOC_GPIO_NUM 23 - -#define Y9_GPIO_NUM 19 -#define Y8_GPIO_NUM 36 -#define Y7_GPIO_NUM 18 -#define Y6_GPIO_NUM 39 -#define Y5_GPIO_NUM 5 -#define Y4_GPIO_NUM 34 -#define Y3_GPIO_NUM 35 -#define Y2_GPIO_NUM 32 -#define VSYNC_GPIO_NUM 25 -#define HREF_GPIO_NUM 26 -#define PCLK_GPIO_NUM 21 - -#define LED_GPIO_NUM 2 - -#elif defined(CAMERA_MODEL_M5STACK_ESP32CAM) -#define PWDN_GPIO_NUM -1 -#define RESET_GPIO_NUM 15 -#define XCLK_GPIO_NUM 27 -#define SIOD_GPIO_NUM 25 -#define SIOC_GPIO_NUM 23 - -#define Y9_GPIO_NUM 19 -#define Y8_GPIO_NUM 36 -#define Y7_GPIO_NUM 18 -#define Y6_GPIO_NUM 39 -#define Y5_GPIO_NUM 5 -#define Y4_GPIO_NUM 34 -#define Y3_GPIO_NUM 35 -#define Y2_GPIO_NUM 17 -#define VSYNC_GPIO_NUM 22 -#define HREF_GPIO_NUM 26 -#define PCLK_GPIO_NUM 21 - -#elif defined(CAMERA_MODEL_M5STACK_UNITCAM) -#define PWDN_GPIO_NUM -1 -#define RESET_GPIO_NUM 15 -#define XCLK_GPIO_NUM 27 -#define SIOD_GPIO_NUM 25 -#define SIOC_GPIO_NUM 23 - -#define Y9_GPIO_NUM 19 -#define Y8_GPIO_NUM 36 -#define Y7_GPIO_NUM 18 -#define Y6_GPIO_NUM 39 -#define Y5_GPIO_NUM 5 -#define Y4_GPIO_NUM 34 -#define Y3_GPIO_NUM 35 -#define Y2_GPIO_NUM 32 -#define VSYNC_GPIO_NUM 22 -#define HREF_GPIO_NUM 26 -#define PCLK_GPIO_NUM 21 - -#elif defined(CAMERA_MODEL_AI_THINKER) -#define PWDN_GPIO_NUM 32 -#define RESET_GPIO_NUM -1 -#define XCLK_GPIO_NUM 0 -#define SIOD_GPIO_NUM 26 -#define SIOC_GPIO_NUM 27 - -#define Y9_GPIO_NUM 35 -#define Y8_GPIO_NUM 34 -#define Y7_GPIO_NUM 39 -#define Y6_GPIO_NUM 36 -#define Y5_GPIO_NUM 21 -#define Y4_GPIO_NUM 19 -#define Y3_GPIO_NUM 18 -#define Y2_GPIO_NUM 5 -#define VSYNC_GPIO_NUM 25 -#define HREF_GPIO_NUM 23 -#define PCLK_GPIO_NUM 22 - -// 4 for flash led or 33 for normal led -#define LED_GPIO_NUM 4 - -#elif defined(CAMERA_MODEL_TTGO_T_JOURNAL) -#define PWDN_GPIO_NUM 0 -#define RESET_GPIO_NUM 15 -#define XCLK_GPIO_NUM 27 -#define SIOD_GPIO_NUM 25 -#define SIOC_GPIO_NUM 23 - -#define Y9_GPIO_NUM 19 -#define Y8_GPIO_NUM 36 -#define Y7_GPIO_NUM 18 -#define Y6_GPIO_NUM 39 -#define Y5_GPIO_NUM 5 -#define Y4_GPIO_NUM 34 -#define Y3_GPIO_NUM 35 -#define Y2_GPIO_NUM 17 -#define VSYNC_GPIO_NUM 22 -#define HREF_GPIO_NUM 26 -#define PCLK_GPIO_NUM 21 - -#elif defined(CAMERA_MODEL_XIAO_ESP32S3) -#define PWDN_GPIO_NUM -1 -#define RESET_GPIO_NUM -1 -#define XCLK_GPIO_NUM 10 -#define SIOD_GPIO_NUM 40 -#define SIOC_GPIO_NUM 39 - -#define Y9_GPIO_NUM 48 -#define Y8_GPIO_NUM 11 -#define Y7_GPIO_NUM 12 -#define Y6_GPIO_NUM 14 -#define Y5_GPIO_NUM 16 -#define Y4_GPIO_NUM 18 -#define Y3_GPIO_NUM 17 -#define Y2_GPIO_NUM 15 -#define VSYNC_GPIO_NUM 38 -#define HREF_GPIO_NUM 47 -#define PCLK_GPIO_NUM 13 - -#elif defined(CAMERA_MODEL_ESP32_CAM_BOARD) -// The 18 pin header on the board has Y5 and Y3 swapped -#define USE_BOARD_HEADER 0 -#define PWDN_GPIO_NUM 32 -#define RESET_GPIO_NUM 33 -#define XCLK_GPIO_NUM 4 -#define SIOD_GPIO_NUM 18 -#define SIOC_GPIO_NUM 23 - -#define Y9_GPIO_NUM 36 -#define Y8_GPIO_NUM 19 -#define Y7_GPIO_NUM 21 -#define Y6_GPIO_NUM 39 -#if USE_BOARD_HEADER -#define Y5_GPIO_NUM 13 -#else -#define Y5_GPIO_NUM 35 -#endif -#define Y4_GPIO_NUM 14 -#if USE_BOARD_HEADER -#define Y3_GPIO_NUM 35 -#else -#define Y3_GPIO_NUM 13 -#endif -#define Y2_GPIO_NUM 34 -#define VSYNC_GPIO_NUM 5 -#define HREF_GPIO_NUM 27 -#define PCLK_GPIO_NUM 25 - -#elif defined(CAMERA_MODEL_ESP32S3_CAM_LCD) -#define PWDN_GPIO_NUM -1 -#define RESET_GPIO_NUM -1 -#define XCLK_GPIO_NUM 40 -#define SIOD_GPIO_NUM 17 -#define SIOC_GPIO_NUM 18 - -#define Y9_GPIO_NUM 39 -#define Y8_GPIO_NUM 41 -#define Y7_GPIO_NUM 42 -#define Y6_GPIO_NUM 12 -#define Y5_GPIO_NUM 3 -#define Y4_GPIO_NUM 14 -#define Y3_GPIO_NUM 47 -#define Y2_GPIO_NUM 13 -#define VSYNC_GPIO_NUM 21 -#define HREF_GPIO_NUM 38 -#define PCLK_GPIO_NUM 11 - -#elif defined(CAMERA_MODEL_ESP32S2_CAM_BOARD) -// The 18 pin header on the board has Y5 and Y3 swapped -#define USE_BOARD_HEADER 0 -#define PWDN_GPIO_NUM 1 -#define RESET_GPIO_NUM 2 -#define XCLK_GPIO_NUM 42 -#define SIOD_GPIO_NUM 41 -#define SIOC_GPIO_NUM 18 - -#define Y9_GPIO_NUM 16 -#define Y8_GPIO_NUM 39 -#define Y7_GPIO_NUM 40 -#define Y6_GPIO_NUM 15 -#if USE_BOARD_HEADER -#define Y5_GPIO_NUM 12 -#else -#define Y5_GPIO_NUM 13 -#endif -#define Y4_GPIO_NUM 5 -#if USE_BOARD_HEADER -#define Y3_GPIO_NUM 13 -#else -#define Y3_GPIO_NUM 12 -#endif -#define Y2_GPIO_NUM 14 -#define VSYNC_GPIO_NUM 38 -#define HREF_GPIO_NUM 4 -#define PCLK_GPIO_NUM 3 - -#elif defined(CAMERA_MODEL_ESP32S3_EYE) -#define PWDN_GPIO_NUM -1 -#define RESET_GPIO_NUM -1 -#define XCLK_GPIO_NUM 15 -#define SIOD_GPIO_NUM 4 -#define SIOC_GPIO_NUM 5 - -#define Y2_GPIO_NUM 11 -#define Y3_GPIO_NUM 9 -#define Y4_GPIO_NUM 8 -#define Y5_GPIO_NUM 10 -#define Y6_GPIO_NUM 12 -#define Y7_GPIO_NUM 18 -#define Y8_GPIO_NUM 17 -#define Y9_GPIO_NUM 16 - -#define VSYNC_GPIO_NUM 6 -#define HREF_GPIO_NUM 7 -#define PCLK_GPIO_NUM 13 - -#elif defined(CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3) || defined(CAMERA_MODEL_DFRobot_Romeo_ESP32S3) -#define PWDN_GPIO_NUM -1 -#define RESET_GPIO_NUM -1 -#define XCLK_GPIO_NUM 45 -#define SIOD_GPIO_NUM 1 -#define SIOC_GPIO_NUM 2 - -#define Y9_GPIO_NUM 48 -#define Y8_GPIO_NUM 46 -#define Y7_GPIO_NUM 8 -#define Y6_GPIO_NUM 7 -#define Y5_GPIO_NUM 4 -#define Y4_GPIO_NUM 41 -#define Y3_GPIO_NUM 40 -#define Y2_GPIO_NUM 39 -#define VSYNC_GPIO_NUM 6 -#define HREF_GPIO_NUM 42 -#define PCLK_GPIO_NUM 5 - -#else -#error "Camera model not selected" + +#if defined(CAMERA_MODEL_WROVER_KIT) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 21 +#define SIOD_GPIO_NUM 26 +#define SIOC_GPIO_NUM 27 + +#define Y9_GPIO_NUM 35 +#define Y8_GPIO_NUM 34 +#define Y7_GPIO_NUM 39 +#define Y6_GPIO_NUM 36 +#define Y5_GPIO_NUM 19 +#define Y4_GPIO_NUM 18 +#define Y3_GPIO_NUM 5 +#define Y2_GPIO_NUM 4 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 23 +#define PCLK_GPIO_NUM 22 + +#elif defined(CAMERA_MODEL_ESP_EYE) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 4 +#define SIOD_GPIO_NUM 18 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 36 +#define Y8_GPIO_NUM 37 +#define Y7_GPIO_NUM 38 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 35 +#define Y4_GPIO_NUM 14 +#define Y3_GPIO_NUM 13 +#define Y2_GPIO_NUM 34 +#define VSYNC_GPIO_NUM 5 +#define HREF_GPIO_NUM 27 +#define PCLK_GPIO_NUM 25 + +#define LED_GPIO_NUM 22 + +#elif defined(CAMERA_MODEL_M5STACK_PSRAM) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 25 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 32 +#define VSYNC_GPIO_NUM 22 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_M5STACK_V2_PSRAM) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 22 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 32 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_M5STACK_WIDE) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 22 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 32 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#define LED_GPIO_NUM 2 + +#elif defined(CAMERA_MODEL_M5STACK_ESP32CAM) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 25 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 17 +#define VSYNC_GPIO_NUM 22 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_M5STACK_UNITCAM) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 25 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 32 +#define VSYNC_GPIO_NUM 22 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_AI_THINKER) +#define PWDN_GPIO_NUM 32 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 0 +#define SIOD_GPIO_NUM 26 +#define SIOC_GPIO_NUM 27 + +#define Y9_GPIO_NUM 35 +#define Y8_GPIO_NUM 34 +#define Y7_GPIO_NUM 39 +#define Y6_GPIO_NUM 36 +#define Y5_GPIO_NUM 21 +#define Y4_GPIO_NUM 19 +#define Y3_GPIO_NUM 18 +#define Y2_GPIO_NUM 5 +#define VSYNC_GPIO_NUM 25 +#define HREF_GPIO_NUM 23 +#define PCLK_GPIO_NUM 22 + +// 4 for flash led or 33 for normal led +#define LED_GPIO_NUM 4 + +#elif defined(CAMERA_MODEL_TTGO_T_JOURNAL) +#define PWDN_GPIO_NUM 0 +#define RESET_GPIO_NUM 15 +#define XCLK_GPIO_NUM 27 +#define SIOD_GPIO_NUM 25 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 19 +#define Y8_GPIO_NUM 36 +#define Y7_GPIO_NUM 18 +#define Y6_GPIO_NUM 39 +#define Y5_GPIO_NUM 5 +#define Y4_GPIO_NUM 34 +#define Y3_GPIO_NUM 35 +#define Y2_GPIO_NUM 17 +#define VSYNC_GPIO_NUM 22 +#define HREF_GPIO_NUM 26 +#define PCLK_GPIO_NUM 21 + +#elif defined(CAMERA_MODEL_XIAO_ESP32S3) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 10 +#define SIOD_GPIO_NUM 40 +#define SIOC_GPIO_NUM 39 + +#define Y9_GPIO_NUM 48 +#define Y8_GPIO_NUM 11 +#define Y7_GPIO_NUM 12 +#define Y6_GPIO_NUM 14 +#define Y5_GPIO_NUM 16 +#define Y4_GPIO_NUM 18 +#define Y3_GPIO_NUM 17 +#define Y2_GPIO_NUM 15 +#define VSYNC_GPIO_NUM 38 +#define HREF_GPIO_NUM 47 +#define PCLK_GPIO_NUM 13 + +#elif defined(CAMERA_MODEL_ESP32_CAM_BOARD) +// The 18 pin header on the board has Y5 and Y3 swapped +#define USE_BOARD_HEADER 0 +#define PWDN_GPIO_NUM 32 +#define RESET_GPIO_NUM 33 +#define XCLK_GPIO_NUM 4 +#define SIOD_GPIO_NUM 18 +#define SIOC_GPIO_NUM 23 + +#define Y9_GPIO_NUM 36 +#define Y8_GPIO_NUM 19 +#define Y7_GPIO_NUM 21 +#define Y6_GPIO_NUM 39 +#if USE_BOARD_HEADER +#define Y5_GPIO_NUM 13 +#else +#define Y5_GPIO_NUM 35 +#endif +#define Y4_GPIO_NUM 14 +#if USE_BOARD_HEADER +#define Y3_GPIO_NUM 35 +#else +#define Y3_GPIO_NUM 13 +#endif +#define Y2_GPIO_NUM 34 +#define VSYNC_GPIO_NUM 5 +#define HREF_GPIO_NUM 27 +#define PCLK_GPIO_NUM 25 + +#elif defined(CAMERA_MODEL_ESP32S3_CAM_LCD) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 40 +#define SIOD_GPIO_NUM 17 +#define SIOC_GPIO_NUM 18 + +#define Y9_GPIO_NUM 39 +#define Y8_GPIO_NUM 41 +#define Y7_GPIO_NUM 42 +#define Y6_GPIO_NUM 12 +#define Y5_GPIO_NUM 3 +#define Y4_GPIO_NUM 14 +#define Y3_GPIO_NUM 47 +#define Y2_GPIO_NUM 13 +#define VSYNC_GPIO_NUM 21 +#define HREF_GPIO_NUM 38 +#define PCLK_GPIO_NUM 11 + +#elif defined(CAMERA_MODEL_ESP32S2_CAM_BOARD) +// The 18 pin header on the board has Y5 and Y3 swapped +#define USE_BOARD_HEADER 0 +#define PWDN_GPIO_NUM 1 +#define RESET_GPIO_NUM 2 +#define XCLK_GPIO_NUM 42 +#define SIOD_GPIO_NUM 41 +#define SIOC_GPIO_NUM 18 + +#define Y9_GPIO_NUM 16 +#define Y8_GPIO_NUM 39 +#define Y7_GPIO_NUM 40 +#define Y6_GPIO_NUM 15 +#if USE_BOARD_HEADER +#define Y5_GPIO_NUM 12 +#else +#define Y5_GPIO_NUM 13 +#endif +#define Y4_GPIO_NUM 5 +#if USE_BOARD_HEADER +#define Y3_GPIO_NUM 13 +#else +#define Y3_GPIO_NUM 12 +#endif +#define Y2_GPIO_NUM 14 +#define VSYNC_GPIO_NUM 38 +#define HREF_GPIO_NUM 4 +#define PCLK_GPIO_NUM 3 + +#elif defined(CAMERA_MODEL_ESP32S3_EYE) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 15 +#define SIOD_GPIO_NUM 4 +#define SIOC_GPIO_NUM 5 + +#define Y2_GPIO_NUM 11 +#define Y3_GPIO_NUM 9 +#define Y4_GPIO_NUM 8 +#define Y5_GPIO_NUM 10 +#define Y6_GPIO_NUM 12 +#define Y7_GPIO_NUM 18 +#define Y8_GPIO_NUM 17 +#define Y9_GPIO_NUM 16 + +#define VSYNC_GPIO_NUM 6 +#define HREF_GPIO_NUM 7 +#define PCLK_GPIO_NUM 13 + +#elif defined(CAMERA_MODEL_DFRobot_FireBeetle2_ESP32S3) || defined(CAMERA_MODEL_DFRobot_Romeo_ESP32S3) +#define PWDN_GPIO_NUM -1 +#define RESET_GPIO_NUM -1 +#define XCLK_GPIO_NUM 45 +#define SIOD_GPIO_NUM 1 +#define SIOC_GPIO_NUM 2 + +#define Y9_GPIO_NUM 48 +#define Y8_GPIO_NUM 46 +#define Y7_GPIO_NUM 8 +#define Y6_GPIO_NUM 7 +#define Y5_GPIO_NUM 4 +#define Y4_GPIO_NUM 41 +#define Y3_GPIO_NUM 40 +#define Y2_GPIO_NUM 39 +#define VSYNC_GPIO_NUM 6 +#define HREF_GPIO_NUM 42 +#define PCLK_GPIO_NUM 5 + +#else +#error "Camera model not selected" #endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Embedded_Message/Send_Embedded_Message.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Embedded_Message/Send_Embedded_Message.ino index 2f4da480e..9dec4f50c 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Embedded_Message/Send_Embedded_Message.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Embedded_Message/Send_Embedded_Message.ino @@ -1,303 +1,303 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to send Email which the html and text message will be embedded as attachment or inline content. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -// To use only SMTP functions, you can exclude the IMAP from compilation, see ESP_Mail_FS.h. - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - message.subject = F("Test sending message as embedded files"); - message.addRecipient(F("Admin"), RECIPIENT_EMAIL); - - message.html.content = F("This is html message"); - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.html.charSet = F("utf-8"); - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; - - /* Enable to send this message body as file */ - message.html.embed.enable = true; - - /* The name of embedded file */ - message.html.embed.filename = F("test.html"); - - /** The embedded type - * esp_mail_smtp_embed_message_type_attachment or 0 - * esp_mail_smtp_embed_message_type_inline or 1 - */ - message.html.embed.type = esp_mail_smtp_embed_message_type_attachment; - - message.text.content = F("This is simple plain text message"); - message.text.charSet = F("utf-8"); - message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; - message.text.embed.enable = true; - message.text.embed.filename = F("test.txt"); - message.text.embed.type = esp_mail_smtp_embed_message_type_inline; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - /* Set the custom message header */ - message.addHeader(F("Message-ID: ")); - - /* Connect to the server */ - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email which the html and text message will be embedded as attachment or inline content. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +// To use only SMTP functions, you can exclude the IMAP from compilation, see ESP_Mail_FS.h. + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending message as embedded files"); + message.addRecipient(F("Admin"), RECIPIENT_EMAIL); + + message.html.content = F("This is html message"); + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("utf-8"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; + + /* Enable to send this message body as file */ + message.html.embed.enable = true; + + /* The name of embedded file */ + message.html.embed.filename = F("test.html"); + + /** The embedded type + * esp_mail_smtp_embed_message_type_attachment or 0 + * esp_mail_smtp_embed_message_type_inline or 1 + */ + message.html.embed.type = esp_mail_smtp_embed_message_type_attachment; + + message.text.content = F("This is simple plain text message"); + message.text.charSet = F("utf-8"); + message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; + message.text.embed.enable = true; + message.text.embed.filename = F("test.txt"); + message.text.embed.type = esp_mail_smtp_embed_message_type_inline; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Enriched_Text/Send_Enriched_Text.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Enriched_Text/Send_Enriched_Text.ino index 99c162a6b..be7199644 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Enriched_Text/Send_Enriched_Text.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Enriched_Text/Send_Enriched_Text.ino @@ -1,293 +1,293 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to send Email in enriched text version. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - message.subject = F("Test sending enriched text Email"); - message.addRecipient(F("Someone"), RECIPIENT_EMAIL); - - message.text.content = F("This is enriched as defined in RFC 1896\r\n\r\nIsn't it cool?"); - - message.text.content_type = F("text/enriched"); - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.text.charSet = F("us-ascii"); - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader(F("Message-ID: ")); - - /* Connect to the server */ - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email in enriched text version. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending enriched text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + message.text.content = F("This is enriched as defined in RFC 1896\r\n\r\nIsn't it cool?"); + + message.text.content_type = F("text/enriched"); + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Flash_Message_with_Inline_Image/Send_Flash_Message_with_Inline_Image.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Flash_Message_with_Inline_Image/Send_Flash_Message_with_Inline_Image.ino index dacf96434..61110feba 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Flash_Message_with_Inline_Image/Send_Flash_Message_with_Inline_Image.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Flash_Message_with_Inline_Image/Send_Flash_Message_with_Inline_Image.ino @@ -1,370 +1,370 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to send Email with inline images stored in flash memory. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -// The file systems for flash and sd memory can be changed in ESP_Mail_FS.h. - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - Serial.println("Mounting flash..."); - - const char *html = "This message contains inline image.

\"orange"; - const char *base64Img = "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAkGBggGBQkIBwgKCQkKDRYODQwMDRoTFBAWHxwhIB8cHh4jJzIqIyUvJR4eKzssLzM1ODg4ISo9QTw2QTI3ODX/2wBDAQkKCg0LDRkODhk1JB4kNTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTX/wgARCAFoAoADAREAAhEBAxEB/8QAGwABAQEBAQEBAQAAAAAAAAAAAAECAwUGBAf/xAAbAQEBAQADAQEAAAAAAAAAAAAAAQIDBAUGB//aAAwDAQACEAMQAAAAn5/+igVVBAAAFIWJQsAAAgAAAAAAAoIAAAAgKFBAAUIWAAAAAAASUIoKFCwAAAAAAAACUQAAAAACAAoICgAgKFCAAAAFECUAAAACCWgoAsAAAAAAAACoBCgAQACACghSAAUBCkCgAAAAAAAoIAACDN0BSFECkKAAAAAACpCgEKBABAKQAAAAUIAAoEAABSFACiUAAEgAloALQgARQAAAAEAAABBRAAAoBCkAFCAAABYCVSFAChAUAAIAEAKACgCgskKAAAAEAAABBRAAAoIAABUAABAFEoAAUKIAAAAARAFtEAoAAoACABFCQFAACAAAUAAQFAQAAAgAM7fIe10tRuXcu866YvXG95v6uLf7+rsKEABSAAIUUgUCiAAAQAUCQAAUIAABQACAFIAAAAQCoTkz/Gvtvi4zpdTW869Tqet+7rd39fDz+10ez7HR0AAAIUgAQtCgAAAAWJZRABBSFhRECgAAFABCkAAAAIACUG5/F/t/h86xELT2uj7fs9D1fQ63Y9Dr8nq9LQAAABSAAoAAAFAACCxAVAAKEQBQAAUAgAAAAABACUGp/GfuPh+WsELT3vP933PO9f8Af1+b9HHv1+jQAUAEKQALQACgJABQRKAECABQgFAgCgAAAAAAgoAQCgs/jn2/xPDfEID6Hzvd+g8z2f08XJ349ex0tQoCgAQpCpCrCgBRCoAEAgAqAABCywABRAoAAAAAIBQAgJQWfx/7b4n83JxCA+i873fovL9vrx67Y17PR0CgAAAAgKWVRICikKRKAEQAQUgKAlgAUARQAAAAQAUBBUAGp/Ivtfi/x8nAID6Lzfd+i8v2uuN9c32ehukWghQSgAAlUKIEKAAgFCIAIAAKEsACgCAAAABSACgIKgILP5L9r8Z+Hl64gPofO9z6Pyvc6410zfZ6PJQAAQpAUEKoAAAoAEgFQBAWIABBQCwBQAABAUAAAJQgIBp/J/s/jPP5usBD6Dzva+k8r3emd9cX2ejyAUgUAAAgqgAAAAUklCAACoAEEFABYFAAAEBQAAEFQEAJX8q+y+N83sdUCHv+f7P0vle90xvpm+z0eSwACiAAAJpQAAAABUAhZABUAASCgFAgUAAAAAAgBKAgoZr+XfX/AB3k9rqUA9zoex9N5Pv9Ma6Z17HS5NZFAACoAAaigAAAABBQJABUAgLIBQCiBQAAAQoIAAShBQhmv5j9d8f4/b6dAPb6Xr/TeP8AQdc63nXsdLk1mikAAIAKG8gKRRQEhQAgpCogCoAQIFAKIAFBACkKQACoCChAZr+Z/W/I+L3OjQD2en631HjfQ9c63nXr9Pk1i0AEAtgKRB0yBQAAQACoAKiACUhUCBQCiABQECILaQACoQCoCUP5p9Z8l4fd6AoPY6fqfU+N9H1zrWdev0+TeKBKpFAEKEh1yAKAAIVACCgJQJAKAiABQCgACKkAUKAgIKAgoZP5z9V8p8/3/OoB63U9L6rxfpeudbzr1upybxQCgCAUAOuIIFACkCoAQUBBRIAKEARQAACkLBAChZAogFCAVCL/ADz6n5X530PMAHqdX0frPF+l6Y1vOvW6nLvFAqwChACg64glqAFIUioABEoCUFQBBBQBFAIUAASUloICwAVAShCL/P8A6j5b5v0fMBB6XW9D67xPpumNdJv1enybxQpKoAQAEO2IChSBKsAgUEEFCWFEFEEAoEAAAUJCgLAABQgBKgJb8D9N8v8AL+n5IoPR63f+w8P6npi9Jv1OnydMUKKBABQEOuJSKAAAAQAJKCoAQUFCCRSgEAKQsCpBaEBUKQAGaAlvwv0fzXyfreMLA/fwdz7LwvrOuLvO/U6vJ0xRFAgLUABDtiAoAAAEQAWQUIKAgFCCwABQQApBFJVABAAQVACW/E/Q/PfJet4sog/bw9v7Lwfqu2Nbzv1OrydMWEtpAAQAVDvxyBaQApACJQAlAkVYFQACoBSFgAAAAAAAAShCAWw+P93w/kvX8aWElfp4+f7LwfqeuNdM79LrcnXjqooAlIUInPc/NzZ9PpbBQoIAAIACUBAKJBQAlAAEUAAAAAAEBKKSEoo+X9jy/lvW8qCzFxpr67xPo+uN9M79Lq8nXFgUCan5+XPLc5bzx3nlqCx9F5nYBQAAACIAIAASgsikUBBSFBQIAEKKEKSAqAEFRYSvC9Lp/P8Ao9LedamtSq/Z1+z3xyduPfp9Tl6S/n5Jy5M8tTnqctTUAZoll1Hv+dziKAKQFIEQASgAIKEsKQKgAoAECkKCUBCkAICVCWiV5fd4fH7fX3Nal1LZdKIu5cVqEVS2BVsDcuoh7fQ5RFAAFIEACQUABBQlgACoAABQAAAQAAgoQzaJWdTzO3xfg7HHrNssoWXSpRV3mwoUUAABPc8/mgUAAAEACQCgBBQgsAKJYAAAoBAAAQCoTT83NjhyTjvPHknHUxRIShqWy1bLqWwWqNS2KqJZmqgsuo9jo8oAAAAEKEQBQEAFCAAWCUAAAAAlhRnU/NzT83Lx8OTPHkcdZ3m7xqgGKzqctZzVLLqXtjdl3LvOhmpUSqilWwkVAez0eUAAAAAAiAKAgAFQACwQCgAgonPkn5ebPLc/PyZ5anPTeUUgsoKJZChSZrNSkVRuXpjVWywpqIUlZqwBT2ehygCFAAAAQAACoAEgoBQELBZx5Jw5MceSfn5M/m5cw6YtgsqILLRULFLKJUJZixbYzVXebAVbEoF1LY1FUBCoez0OSrAACgAAIBAUBABURQShw5s/n5MceTPDc4cksbySywACrcqozZLM0illoWgiys3IBZWbN51qWxVFgpM0NRVsCHtdHlKgAACkAKEAhQEKSUs/LzY57nPU4cmfz7mosZKUiUsooUZSWStRZdyolZsxpE1KLFUCUAWyxFFsal1LmtRVgQZsgtsnt9DmKgAAAAUBAARXHkn5+XHDkz+fkzy3NZWWiM2CmpYZsok0ozVgUhLIblssBQZrNmbBqWrYlFRV1GdIagupdQlpCgAESWex0eagAKgKQFBDU4cmePJOPJjjucdSkjNixFNSw1GpZZirGixnUylWxQCAAhK1LqICrYlnPUzqQsupdQUtIVYllpDSwsaNZtISoZufZ6PNQAFEBjefz8ueO5y5M89TlqazSZoWBC2ZCCm5cljcozZK1CFZslWLAsolgsShmty7zRBViVmrErnqCy6lFWIWliqigiKsaiy6l9TqcipCuW5+flx+fln5+TMM10yzRLKAiWZrRYAhm5pCmpbErUpM1LEblETNkKuoollhaWJUM2bl3KlzYWWCEFAVUCiKtlpqXUZsxqQESn6cXjuc9TluZBY1LZQBLLLSiJZmhYGozSyFBDUVcpqBLJWTUajGpKQNLrKqjRkVZZZmyFXpm6lxWbKCEoWWwqENFlsopmyxVBInDlxCy1RmyllsuozYqBdQLEqIIaECVLAKQJYlWNSiGdQmoxW5ZWE0WWrrNVYJKssrKShuWwWWRSCVK1m0ENSixqFsKIIPyc3GqxrOlRKFBc2CpZbLSVYAiCiJUsAAzYNRmwbzdTVTFma1FWxLMUssus2lXUtjFUJKzZihuXUWXNWCkVmrFgujJKqCy2BU/Ny8dlqiygApFqM2ClWJvNlEhKsUzZSAApiylliDpLc2VLOepqN51qKctZlShrN3LqXUQzZLLLDOmbCWa6SolAFshZZDUsFkIlLLU//EAEYQAAEDAQMJBgIIAwQLAAAAAAEAAhEDBBASBQYgITFBYXGxEzAyQFFyM1AiNENgc4GR0aGywRQlUoIVIyQ1NkRTYnDC4f/aAAgBAQABPwDyE3z5yfMzoToDRH3CHyAf+FR9wh87n5eO7HlXmKbiNoBQy/bR9u79AhnFbR9t+rAhnJbd72fmwIZz2r0on/L/APU3OivvpUf4oZzv30Kf5OKGc3rZ/wBHoZy0t9B/5OCsmV6drqhjKVQE7zEedHyp2tpCdVeHGHuQtFUbKj/1QtlcbKr/ANULfaBsqvQylaR9osn2h9ehiedcpgVCjKyewU6rBx7gXjy48gPLVRFRw4nRyMJsp9xVCmrOwKzaq7OaHejRn5oNoVoEWmpweeujkETZXe9UmqmMLVZzFZnMd6O7nzQ8qPEOatww2+uPSo7roBZvfVanvVBiaqGqqzmNIfcEbRzWUxGVLV+K7roBZtCaFX3BMTVS+I3mPIjTHy/eOayxqyzbPxn9To5r/Cr82piaqfjHPux8jHmstiMuW3hXf/MdHNbZaP8AKmpqZtCH3HzgEZw2/wDHf1OjmrttI9qampm0fKh507FnKIzkt347tHNXx2jkE1BNTdnyEdwPOnYs6RGc1u/FKGhmuYr1/YOqamoJh1D7jFZ2/wDE9t946DRzX+tVvZ/UJqagmbBy+VDup8kVngIzotfNv8o0c2PrtX8P+oTU1BU/A3kEPOjuRpDSGhHkM8hGc9p5M/lFwvzZ+vv/AAympqCp66beQ84Lgh3o70d9nsIzkq8WM6aObZjKJ9hTU1BUfhN5DTHywXTonvCs+RGcPOkzRzc/3oPYU1BBUfgs9o+QT5DfcdAXnvSs+9WXWfgN6nRzeMZWZyd0KaggqGugz2/Ix5AaRuPeZ/CMs0fwB1cpUqVKyAf73o/n0KaggrP9XZy+aToDv8/x/eNm40f/AGOjkPVlihzTE1BWb6uzl8xGhPks/wAf7VZD603ddHI2rK1n96Ympqs31dnLzQ0BfKlDRHn8/WS+xcnrAuzWBYVkvVlOz+8dUxBBWb6u3vKlpo0/HUaE/KlMGGU6j/ygd4O7HyPPVmNtj5v/AKLsF/ZyUbK7eEbM7cFY6ZZb6JO6oOqYmpqsuuzt0iYT8oWam4tNdmL0GvonZVpjwUqr+Yw9U7KdY+GmxvEnF+ydbLQ/bWI9gDU4l+suLj6uMoSgD5YaAuHns6mY6Nm4OchQCbZ0LIhYwdqGTqYeHAQQZTar27gUy0N3ghUqjX7HKymLOAnVGsEuIA4mE7KFnZtqtPt19E7KrB4KdR3P6KOVKp8LGM5yUbXXftrOHtgItDzL5cfVxnqg2FhWFFiwIMUfJh5TLzMVClweeiZSQpIUl2aDEGKPQI059AgaoYGio8Abg5dlJ1ieJQYVgQYVBCg3An0UkIOQUcFCHkR3Y83Ke9tNsvc1vMwsp16Vei1tOo15DpOHWgPQKD6KCsPC4IKY2hShKgELCsPFBkIcQsBO5YFhaN6DmhdodzVLigO9HyWUTCq5TsdHx2miOAfJ/gnZaofZsr1eLaUD+MJ+WK32dkjjUqfsnZRtrtr6dP2056p9avV8des7hMdEGRuB4kSiSu1K7Y7AV2j/APEhUcVjKmd0oNulCVJWtBpO9BoG9bEJRneVhHogAPQLkEGu9EGefHeypTnhgl5DRxMJ+VLIzUazXcGDF0VTLX/Qs1R/F8M/dOypbX7BZ6X6vRtFreIfa6vKmAzonWWnUM1A6ofWo4uTKQp6qQaz2iEHOG3Wsbd4QwnYUWLAU4FEIhNQCamQRJKAbuchTYd6FELsQFs3FTvlfqg70ClEJrD6LAoAWMLEdEd+PKSgVVtNKj8Wqyn7nAJ+WbINTKhqcKbC5OyyT8KzP51HhvSU/KlqfsNKnybi6o2mu/x2mseTsPRdmycRY0n1Os/xQUAXAraoQWpFih7dhQqPG0LtGngoa5GmFgXZoNcpcgJMlNJahXEawu2lB4O+4H1CDPUyvoNWMIvX0kJUXATpDy40ZUqrbrNQ1Va9JnN0lf6YspnB2j/awp+WH7KdCOL3/sn5Rtb9lRjB6MZ+6ealX41es/gahhMo0meFjP0U3QsCwFCRcAi24FTeeSDwi0ORoqXt3rtfVqLz6JrkCiFKgKPQosNweUHneFjahhcsC1jcpKxLGVJ87KmJJT8oWWkTjr0wfQOk/wAFUy1RHw6dapybHVOyxXfOCgxnvfPRPtlsqf8AMFnCm0DrKfT7XXVfUq+95KZTYzU1jW8hdChYVhuFwKkKJRYoLUSUCgbgpUoEHcsAUEKVqWAINgoyEHQdYQM70HFqkFQNoK1rVvCwgrAixAuGwoPcg4bxCDgiT5mYReBJJgKrlax0dTq7eTdfRHLNJwmlSrP5tw9U7Klod4KVNnFxLv2T7Zan7a7m+wBqc0Vfi4qnvcXdU1oYIYA3ldru/O8BQgVqULDeHEIOCD/zWoosRYti1oOQchdJulQ07kGoSEGbysAWBBqDUGLBdK13QFhCLFCghAnytS22elqfXYOTp6J+VaOvAypU5NjrCdlaqfBRYz3vnon261P21sAO6m0BFoqyapfU97pTabWD6DQ1SgZuwXNi7DcCgpui6b4uDm+kKLgpuwLs1hNweVKEOUKCgLpGwohqF30eKHBykrE1AArChIUoRfAUDvycIJJgJ+ULKwwa7OTTPROytSE4KdV/5R1T8q1nTgpU2cXuJ6J1stL9tcjhTaAnf6zXULqh9XuJQ1amgN5LaiLtaa5RiuBuIuBugFFim6VKCgKLhChQhI2IP/xBAYthUXa7ixGmiwgoSgUHkIPlqEbAsKwuC4EKFqQhQFJCxSFAQLgsfqEHBywqLoWDuZT69Kn8SoxnudCflayt2PL/AGNJTssbqdneeLnBv7o5StT9nZU+QLuqNe0VJx2mpybDeiNJpMubjPq4z1Q1CBA7g3hy2qEDdChAoOQKgKNKAi1C4i9tQ79abhdsMFEEKb9SwLCiAnMTZCDyEHzcBdrCEIC4BQVChSUKhQqjeEHNcsOhKqWuhSkPqsaRxTsrUB4cb+TVUyxVMilQA4ucv7da3iH1QPYIXaVH+J7jzchSY3Y0XygdAoJt8KERdCEhA7ii2FJQN0XByBUqAiFKnSEqAsKwolNqkIOY/wD7SixFAhawpUDcdGEJu5G4BQgYQIucEQo9QtVweRsKdluh9kyrV5NjqnZYtDtTLOxnvfPROtlseJNdrOFNic+o/wCJWqvn1cg0AGBBQCChBFNKcINwUII6GooXSVruF0IOhETsuBm+FsQcoTpG9NcHLWgSECgSgQhAuKFxChQQmvLdhTaodqeEGA62lOChABbL5CBF5lSsSn0KAWxYisSBlQRcGhYDwNxQMtuPhQF7UbiVKnUhowpi4acKYukoPuACIRTXrU4LCJQai24FAoEoISCoBRkXkKBdMGQhVO/WgWv2FFpQF8Suz9FrCD0IO9EINWBAkIOQAI2oNUBTeCgYEIlUxtlTfBulFyMoG4HQAUXQgh3BQ23FNJGxAhyBWpFqhNIUXFiNwKDljQTSsAdrCghAqVCLbgUKpCDwboIQIF5YCsJCBvBRUldoQu0O8Jjg66YTSgEB6BQgFqQIF8KAg0LVeJF0JutqIWrebxN0aUKEFF7DPAqFCLUQmOhCHISEWByLS1RcHoQCmv8AW4HVB1hFgOsIghA3FiLFhuDiEHnY5QCsCi6UEWKXBYgVBWtQCsFwKD1IK//EAC4RAAIBAQUHBQEAAgMAAAAAAAABEQIDBBAgMRIwMjNAQWAFEyFQURQiQmFxkP/aAAgBAgEBPwD/AMGKVLP5aPw/ks/w/ks/w/jsx3Kg/iX6O5f8n8T/AEru+wtfB7PiQqUbKNik9un8PZoLWhUsZVUWrleD0cSKdMt41KmVMq0fg9HEijhWW9alTGVaeD06os+BZb3qirCrTwenUsuBZb5qh4PTwenUseWst97Dwfg61LHlr/rLfew8H4PTqXflU5b7oh4Pwdal25VOW+6IfhKLpyKct94UPF+DIufIpy3zhHi/BkXHkU5b5wDxfg9w5FOW+cGSrwf0/kLLeuXkq18GR6dyFlvXLyV6+D+ncnLeeW8levg/pvJy3nlPJXr4P6XynlvHKY8a+LwZHpfA8tvy2PGvi8H9Lf8AjUSSTha8DHjXxbxWdTFYPu/uvTXCqNo2zbQq0VuaWPGvXNDYrGt9hWD7sVjSKihdvvbi4k2jbPcPcPecQNJjoHSytSxUNisaxWH6xWNKFTSuxJJJJJJP3d1cSbRJJJJOEnwbRJJPgMCpbLGh0a5J3Mk4zhBH2qpZTd7SrRCutXdiu9Hdis7NdhKlaIkRBskIjfTkn65Utiu9o+wrsv8AZisbJa/IlQtKT3KloOva1wjGRZmfJLNpm1kjJOEEfUwU2dVeiFdqxXZd6hWNmhU0rRG09zOEIh4SSSTk2TZIxk+SCPqIKbGurRCu1fcV3p7sVnZrsJpaIdbeSSd3GG0fBBBG5gjCcYII66GKxtHohXZ/7MVhQtWKizXYVUaDqb1xkknPO6nLOEZ5Jw+CCCOrSbFd7R6IV2fdisaFqKihaITa0G56OScYIzzjJOMk55JwjpIFY1vsK7vuxWFC1YrOhdiY0Np98k5J6OScYI3kEdRDYrGv8Fd33YrChasVFC7Exp0E72M0kk4wRhJO5hEEYTjO5hlNnVVoK71iu67sVjZoSpWiNp9HBHQRnknBPCCN7BBGWBWdT7Cu9RTd6Vqz27NaIhEvpo6XZIgnpFlgV1q7iu9C1ZsWa0R8dkTlXXIjdrGCMF0MZZyr6KMJwnfxnnCMk4RhO4eeOlW4TyzljGcs4wRmncQQNfUPcJ5IwjGRYyTkjCeg/8QALBEAAgECBAYCAgEFAAAAAAAAAAERAhIFEyBgAwQQMjNQMUAwURQhQUJhkP/aAAgBAwEBPwD/AIMMz/8AZns/kGexcYzjOM0pqnY9fayviVS/6mbX+zOr/Z/I4n7FzXE/ZyvEq4lMsRTSUqNj1fDK+56eR7ClFKFser4ZxO56cP7ClCFser4Zxe96cN7WU7Jfwzjd704Z2sWyavhnH8j04X8PohbHfwzmPK9OF/3EIWx2c15qtOFf5CELZHN+arThXzUIQtjv4Od89WnC+5iFsnnvPVpwzufRbJxDz1acM72LZWIeerThvk0LY+I+d6cO8ouiFsfEvO9OH+bQtj4n5tPIeZaFsfFfKSSSSch5loWx8W8i08j5loWx8W7kQR15PzIXVbHxSmWi0tLS05byoQhC/HJci/3XP0zBlGUZLHwmcGmK0L4EIWqS9GYXlzJfvOapksMsyjKFwEnInAmJlJKL0Xl7Ln0jRHvOMpLS0gggjpHWOkbClIraZGyJHXSZiMx/ouqJfWSSSdgSh1ozC+olssElqjShdIII0z7C5GYi9lzJeqPxRpkknVPqZL0XozGXVdEtMfnkkX4JJ9PejML2SyCFojXH3Z+7KL6TML2S/SR6S5F5ey59IRH2oI9TKLkXl5c/SwR1n7skl6MwuZL9ZBH0pJ13IvMxl7JI9ZP2pM1GYy6ol+zn7EaF9+fYr3Ek/nknUvRr1n//2Q=="; - -#if defined(ESP32) || defined(ESP8266) -#if defined(ESP32) - if (ESP_MAIL_DEFAULT_FLASH_FS.begin(true)) -#elif defined(ESP8266) - if (ESP_MAIL_DEFAULT_FLASH_FS.begin()) -#endif - { - - // ESP_MAIL_DEFAULT_FLASH_FS.format(); - - if (ESP_MAIL_DEFAULT_FLASH_FS.exists("/base64Img.jpg")) - ESP_MAIL_DEFAULT_FLASH_FS.remove("/base64Img.jpg"); - - Serial.println("Preparing flash file attachments..."); - -#if defined(ESP32) - File file = ESP_MAIL_DEFAULT_FLASH_FS.open("/base64Img.jpg", FILE_WRITE); -#elif defined(ESP8266) - File file = ESP_MAIL_DEFAULT_FLASH_FS.open("/base64Img.jpg", "w"); -#endif - file.print(base64Img); - file.close(); - -#if defined(ESP32) - file = ESP_MAIL_DEFAULT_FLASH_FS.open("/msg.html", FILE_WRITE); -#elif defined(ESP8266) - file = ESP_MAIL_DEFAULT_FLASH_FS.open("/msg.html", "w"); -#endif - file.print(html); - file.close(); - } - else - { - Serial.println("Flash filesystem monting Failed"); - } -#endif - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /* Declare the message class */ - SMTP_Message message; - - /* Enable the chunked data transfer with pipelining for large message if server supported */ - message.enable.chunking = true; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - - message.subject = F("Test sending base64 inline image stored in flash memory"); - message.addRecipient(F("user1"), RECIPIENT_EMAIL); - - /* Two alternative content versions are sending in this example e.g. plain text and html */ - - /* Assign blob data (in flash or ram) as HTML message */ - message.html.blob.data = (const uint8_t *)html; - message.html.blob.size = strlen(html); - - // Or get the content from file - // message.html.file.name = "/msg.html"; - // message.html.file.type = esp_mail_file_storage_type_flash; - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) <- not supported for message from blob and file - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - /** The HTML text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.html.charSet = F("utf-8"); - - message.text.content = F("This message contains inline image.\r\nThe inline image was not shown in the plain text message."); - message.text.charSet = F("utf-8"); - message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* Set the custom message header */ - message.addHeader(F("Message-ID: ")); - - /* The attachment data item */ - SMTP_Attachment att; - /** Set the inline image info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - att.descr.filename = F("base64Img.jpg"); - att.descr.mime = F("image/jpg"); - -#if defined(ESP32) || defined(ESP8266) - att.file.path = F("/base64Img.jpg"); - /** The file storage type e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - att.file.storage_type = esp_mail_file_storage_type_flash; -#elif defined(ARDUINO_ARCH_SAMD) - att.blob.data = (const uint8_t *)base64Img; - att.blob.size = sizeof(base64Img); -#endif - - att.descr.content_id = F("image-001"); // The content id (cid) of orange image in the src tag - - /* Need to be base64 transfer encoding for inline image */ - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /** The attach image file is already base64 encoded file. - * Then set the content encoding to match the transfer encoding - * which no encoding was taken place prior to sending. - */ - att.descr.content_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add inline image to the message */ - message.addInlineImage(att); - - /* Connect to the server */ - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* Start sending the Email and close the session */ - if (!MailClient.sendMail(&smtp, &message, true)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email with inline images stored in flash memory. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +// The file systems for flash and sd memory can be changed in ESP_Mail_FS.h. + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + Serial.println("Mounting flash..."); + + const char *html = "This message contains inline image.

\"orange"; + const char *base64Img = "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAkGBggGBQkIBwgKCQkKDRYODQwMDRoTFBAWHxwhIB8cHh4jJzIqIyUvJR4eKzssLzM1ODg4ISo9QTw2QTI3ODX/2wBDAQkKCg0LDRkODhk1JB4kNTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTU1NTX/wgARCAFoAoADAREAAhEBAxEB/8QAGwABAQEBAQEBAQAAAAAAAAAAAAECAwUGBAf/xAAbAQEBAQADAQEAAAAAAAAAAAAAAQIDBAUGB//aAAwDAQACEAMQAAAAn5/+igVVBAAAFIWJQsAAAgAAAAAAAoIAAAAgKFBAAUIWAAAAAAASUIoKFCwAAAAAAAACUQAAAAACAAoICgAgKFCAAAAFECUAAAACCWgoAsAAAAAAAACoBCgAQACACghSAAUBCkCgAAAAAAAoIAACDN0BSFECkKAAAAAACpCgEKBABAKQAAAAUIAAoEAABSFACiUAAEgAloALQgARQAAAAEAAABBRAAAoBCkAFCAAABYCVSFAChAUAAIAEAKACgCgskKAAAAEAAABBRAAAoIAABUAABAFEoAAUKIAAAAARAFtEAoAAoACABFCQFAACAAAUAAQFAQAAAgAM7fIe10tRuXcu866YvXG95v6uLf7+rsKEABSAAIUUgUCiAAAQAUCQAAUIAABQACAFIAAAAQCoTkz/Gvtvi4zpdTW869Tqet+7rd39fDz+10ez7HR0AAAIUgAQtCgAAAAWJZRABBSFhRECgAAFABCkAAAAIACUG5/F/t/h86xELT2uj7fs9D1fQ63Y9Dr8nq9LQAAABSAAoAAAFAACCxAVAAKEQBQAAUAgAAAAABACUGp/GfuPh+WsELT3vP933PO9f8Af1+b9HHv1+jQAUAEKQALQACgJABQRKAECABQgFAgCgAAAAAAgoAQCgs/jn2/xPDfEID6Hzvd+g8z2f08XJ349ex0tQoCgAQpCpCrCgBRCoAEAgAqAABCywABRAoAAAAAIBQAgJQWfx/7b4n83JxCA+i873fovL9vrx67Y17PR0CgAAAAgKWVRICikKRKAEQAQUgKAlgAUARQAAAAQAUBBUAGp/Ivtfi/x8nAID6Lzfd+i8v2uuN9c32ehukWghQSgAAlUKIEKAAgFCIAIAAKEsACgCAAAABSACgIKgILP5L9r8Z+Hl64gPofO9z6Pyvc6410zfZ6PJQAAQpAUEKoAAAoAEgFQBAWIABBQCwBQAABAUAAAJQgIBp/J/s/jPP5usBD6Dzva+k8r3emd9cX2ejyAUgUAAAgqgAAAAUklCAACoAEEFABYFAAAEBQAAEFQEAJX8q+y+N83sdUCHv+f7P0vle90xvpm+z0eSwACiAAAJpQAAAABUAhZABUAASCgFAgUAAAAAAgBKAgoZr+XfX/AB3k9rqUA9zoex9N5Pv9Ma6Z17HS5NZFAACoAAaigAAAABBQJABUAgLIBQCiBQAAAQoIAAShBQhmv5j9d8f4/b6dAPb6Xr/TeP8AQdc63nXsdLk1mikAAIAKG8gKRRQEhQAgpCogCoAQIFAKIAFBACkKQACoCChAZr+Z/W/I+L3OjQD2en631HjfQ9c63nXr9Pk1i0AEAtgKRB0yBQAAQACoAKiACUhUCBQCiABQECILaQACoQCoCUP5p9Z8l4fd6AoPY6fqfU+N9H1zrWdev0+TeKBKpFAEKEh1yAKAAIVACCgJQJAKAiABQCgACKkAUKAgIKAgoZP5z9V8p8/3/OoB63U9L6rxfpeudbzr1upybxQCgCAUAOuIIFACkCoAQUBBRIAKEARQAACkLBAChZAogFCAVCL/ADz6n5X530PMAHqdX0frPF+l6Y1vOvW6nLvFAqwChACg64glqAFIUioABEoCUFQBBBQBFAIUAASUloICwAVAShCL/P8A6j5b5v0fMBB6XW9D67xPpumNdJv1enybxQpKoAQAEO2IChSBKsAgUEEFCWFEFEEAoEAAAUJCgLAABQgBKgJb8D9N8v8AL+n5IoPR63f+w8P6npi9Jv1OnydMUKKBABQEOuJSKAAAAQAJKCoAQUFCCRSgEAKQsCpBaEBUKQAGaAlvwv0fzXyfreMLA/fwdz7LwvrOuLvO/U6vJ0xRFAgLUABDtiAoAAAEQAWQUIKAgFCCwABQQApBFJVABAAQVACW/E/Q/PfJet4sog/bw9v7Lwfqu2Nbzv1OrydMWEtpAAQAVDvxyBaQApACJQAlAkVYFQACoBSFgAAAAAAAAShCAWw+P93w/kvX8aWElfp4+f7LwfqeuNdM79LrcnXjqooAlIUInPc/NzZ9PpbBQoIAAIACUBAKJBQAlAAEUAAAAAAEBKKSEoo+X9jy/lvW8qCzFxpr67xPo+uN9M79Lq8nXFgUCan5+XPLc5bzx3nlqCx9F5nYBQAAACIAIAASgsikUBBSFBQIAEKKEKSAqAEFRYSvC9Lp/P8Ao9LedamtSq/Z1+z3xyduPfp9Tl6S/n5Jy5M8tTnqctTUAZoll1Hv+dziKAKQFIEQASgAIKEsKQKgAoAECkKCUBCkAICVCWiV5fd4fH7fX3Nal1LZdKIu5cVqEVS2BVsDcuoh7fQ5RFAAFIEACQUABBQlgACoAABQAAAQAAgoQzaJWdTzO3xfg7HHrNssoWXSpRV3mwoUUAABPc8/mgUAAAEACQCgBBQgsAKJYAAAoBAAAQCoTT83NjhyTjvPHknHUxRIShqWy1bLqWwWqNS2KqJZmqgsuo9jo8oAAAAEKEQBQEAFCAAWCUAAAAAlhRnU/NzT83Lx8OTPHkcdZ3m7xqgGKzqctZzVLLqXtjdl3LvOhmpUSqilWwkVAez0eUAAAAAAiAKAgAFQACwQCgAgonPkn5ebPLc/PyZ5anPTeUUgsoKJZChSZrNSkVRuXpjVWywpqIUlZqwBT2ehygCFAAAAQAACoAEgoBQELBZx5Jw5MceSfn5M/m5cw6YtgsqILLRULFLKJUJZixbYzVXebAVbEoF1LY1FUBCoez0OSrAACgAAIBAUBABURQShw5s/n5MceTPDc4cksbySywACrcqozZLM0illoWgiys3IBZWbN51qWxVFgpM0NRVsCHtdHlKgAACkAKEAhQEKSUs/LzY57nPU4cmfz7mosZKUiUsooUZSWStRZdyolZsxpE1KLFUCUAWyxFFsal1LmtRVgQZsgtsnt9DmKgAAAAUBAARXHkn5+XHDkz+fkzy3NZWWiM2CmpYZsok0ozVgUhLIblssBQZrNmbBqWrYlFRV1GdIagupdQlpCgAESWex0eagAKgKQFBDU4cmePJOPJjjucdSkjNixFNSw1GpZZirGixnUylWxQCAAhK1LqICrYlnPUzqQsupdQUtIVYllpDSwsaNZtISoZufZ6PNQAFEBjefz8ueO5y5M89TlqazSZoWBC2ZCCm5cljcozZK1CFZslWLAsolgsShmty7zRBViVmrErnqCy6lFWIWliqigiKsaiy6l9TqcipCuW5+flx+fln5+TMM10yzRLKAiWZrRYAhm5pCmpbErUpM1LEblETNkKuoollhaWJUM2bl3KlzYWWCEFAVUCiKtlpqXUZsxqQESn6cXjuc9TluZBY1LZQBLLLSiJZmhYGozSyFBDUVcpqBLJWTUajGpKQNLrKqjRkVZZZmyFXpm6lxWbKCEoWWwqENFlsopmyxVBInDlxCy1RmyllsuozYqBdQLEqIIaECVLAKQJYlWNSiGdQmoxW5ZWE0WWrrNVYJKssrKShuWwWWRSCVK1m0ENSixqFsKIIPyc3GqxrOlRKFBc2CpZbLSVYAiCiJUsAAzYNRmwbzdTVTFma1FWxLMUssus2lXUtjFUJKzZihuXUWXNWCkVmrFgujJKqCy2BU/Ny8dlqiygApFqM2ClWJvNlEhKsUzZSAApiylliDpLc2VLOepqN51qKctZlShrN3LqXUQzZLLLDOmbCWa6SolAFshZZDUsFkIlLLU//EAEYQAAEDAQMJBgIIAwQLAAAAAAEAAhEDBBASBQYgITFBYXGxEzAyQFFyM1AiNENgc4GR0aGywRQlUoIVIyQ1NkRTYnDC4f/aAAgBAQABPwDyE3z5yfMzoToDRH3CHyAf+FR9wh87n5eO7HlXmKbiNoBQy/bR9u79AhnFbR9t+rAhnJbd72fmwIZz2r0on/L/APU3OivvpUf4oZzv30Kf5OKGc3rZ/wBHoZy0t9B/5OCsmV6drqhjKVQE7zEedHyp2tpCdVeHGHuQtFUbKj/1QtlcbKr/ANULfaBsqvQylaR9osn2h9ehiedcpgVCjKyewU6rBx7gXjy48gPLVRFRw4nRyMJsp9xVCmrOwKzaq7OaHejRn5oNoVoEWmpweeujkETZXe9UmqmMLVZzFZnMd6O7nzQ8qPEOatww2+uPSo7roBZvfVanvVBiaqGqqzmNIfcEbRzWUxGVLV+K7roBZtCaFX3BMTVS+I3mPIjTHy/eOayxqyzbPxn9To5r/Cr82piaqfjHPux8jHmstiMuW3hXf/MdHNbZaP8AKmpqZtCH3HzgEZw2/wDHf1OjmrttI9qampm0fKh507FnKIzkt347tHNXx2jkE1BNTdnyEdwPOnYs6RGc1u/FKGhmuYr1/YOqamoJh1D7jFZ2/wDE9t946DRzX+tVvZ/UJqagmbBy+VDup8kVngIzotfNv8o0c2PrtX8P+oTU1BU/A3kEPOjuRpDSGhHkM8hGc9p5M/lFwvzZ+vv/AAympqCp66beQ84Lgh3o70d9nsIzkq8WM6aObZjKJ9hTU1BUfhN5DTHywXTonvCs+RGcPOkzRzc/3oPYU1BBUfgs9o+QT5DfcdAXnvSs+9WXWfgN6nRzeMZWZyd0KaggqGugz2/Ix5AaRuPeZ/CMs0fwB1cpUqVKyAf73o/n0KaggrP9XZy+aToDv8/x/eNm40f/AGOjkPVlihzTE1BWb6uzl8xGhPks/wAf7VZD603ddHI2rK1n96Ympqs31dnLzQ0BfKlDRHn8/WS+xcnrAuzWBYVkvVlOz+8dUxBBWb6u3vKlpo0/HUaE/KlMGGU6j/ygd4O7HyPPVmNtj5v/AKLsF/ZyUbK7eEbM7cFY6ZZb6JO6oOqYmpqsuuzt0iYT8oWam4tNdmL0GvonZVpjwUqr+Yw9U7KdY+GmxvEnF+ydbLQ/bWI9gDU4l+suLj6uMoSgD5YaAuHns6mY6Nm4OchQCbZ0LIhYwdqGTqYeHAQQZTar27gUy0N3ghUqjX7HKymLOAnVGsEuIA4mE7KFnZtqtPt19E7KrB4KdR3P6KOVKp8LGM5yUbXXftrOHtgItDzL5cfVxnqg2FhWFFiwIMUfJh5TLzMVClweeiZSQpIUl2aDEGKPQI059AgaoYGio8Abg5dlJ1ieJQYVgQYVBCg3An0UkIOQUcFCHkR3Y83Ke9tNsvc1vMwsp16Vei1tOo15DpOHWgPQKD6KCsPC4IKY2hShKgELCsPFBkIcQsBO5YFhaN6DmhdodzVLigO9HyWUTCq5TsdHx2miOAfJ/gnZaofZsr1eLaUD+MJ+WK32dkjjUqfsnZRtrtr6dP2056p9avV8des7hMdEGRuB4kSiSu1K7Y7AV2j/APEhUcVjKmd0oNulCVJWtBpO9BoG9bEJRneVhHogAPQLkEGu9EGefHeypTnhgl5DRxMJ+VLIzUazXcGDF0VTLX/Qs1R/F8M/dOypbX7BZ6X6vRtFreIfa6vKmAzonWWnUM1A6ofWo4uTKQp6qQaz2iEHOG3Wsbd4QwnYUWLAU4FEIhNQCamQRJKAbuchTYd6FELsQFs3FTvlfqg70ClEJrD6LAoAWMLEdEd+PKSgVVtNKj8Wqyn7nAJ+WbINTKhqcKbC5OyyT8KzP51HhvSU/KlqfsNKnybi6o2mu/x2mseTsPRdmycRY0n1Os/xQUAXAraoQWpFih7dhQqPG0LtGngoa5GmFgXZoNcpcgJMlNJahXEawu2lB4O+4H1CDPUyvoNWMIvX0kJUXATpDy40ZUqrbrNQ1Va9JnN0lf6YspnB2j/awp+WH7KdCOL3/sn5Rtb9lRjB6MZ+6ealX41es/gahhMo0meFjP0U3QsCwFCRcAi24FTeeSDwi0ORoqXt3rtfVqLz6JrkCiFKgKPQosNweUHneFjahhcsC1jcpKxLGVJ87KmJJT8oWWkTjr0wfQOk/wAFUy1RHw6dapybHVOyxXfOCgxnvfPRPtlsqf8AMFnCm0DrKfT7XXVfUq+95KZTYzU1jW8hdChYVhuFwKkKJRYoLUSUCgbgpUoEHcsAUEKVqWAINgoyEHQdYQM70HFqkFQNoK1rVvCwgrAixAuGwoPcg4bxCDgiT5mYReBJJgKrlax0dTq7eTdfRHLNJwmlSrP5tw9U7Klod4KVNnFxLv2T7Zan7a7m+wBqc0Vfi4qnvcXdU1oYIYA3ldru/O8BQgVqULDeHEIOCD/zWoosRYti1oOQchdJulQ07kGoSEGbysAWBBqDUGLBdK13QFhCLFCghAnytS22elqfXYOTp6J+VaOvAypU5NjrCdlaqfBRYz3vnon261P21sAO6m0BFoqyapfU97pTabWD6DQ1SgZuwXNi7DcCgpui6b4uDm+kKLgpuwLs1hNweVKEOUKCgLpGwohqF30eKHBykrE1AArChIUoRfAUDvycIJJgJ+ULKwwa7OTTPROytSE4KdV/5R1T8q1nTgpU2cXuJ6J1stL9tcjhTaAnf6zXULqh9XuJQ1amgN5LaiLtaa5RiuBuIuBugFFim6VKCgKLhChQhI2IP/xBAYthUXa7ixGmiwgoSgUHkIPlqEbAsKwuC4EKFqQhQFJCxSFAQLgsfqEHBywqLoWDuZT69Kn8SoxnudCflayt2PL/AGNJTssbqdneeLnBv7o5StT9nZU+QLuqNe0VJx2mpybDeiNJpMubjPq4z1Q1CBA7g3hy2qEDdChAoOQKgKNKAi1C4i9tQ79abhdsMFEEKb9SwLCiAnMTZCDyEHzcBdrCEIC4BQVChSUKhQqjeEHNcsOhKqWuhSkPqsaRxTsrUB4cb+TVUyxVMilQA4ucv7da3iH1QPYIXaVH+J7jzchSY3Y0XygdAoJt8KERdCEhA7ii2FJQN0XByBUqAiFKnSEqAsKwolNqkIOY/wD7SixFAhawpUDcdGEJu5G4BQgYQIucEQo9QtVweRsKdluh9kyrV5NjqnZYtDtTLOxnvfPROtlseJNdrOFNic+o/wCJWqvn1cg0AGBBQCChBFNKcINwUII6GooXSVruF0IOhETsuBm+FsQcoTpG9NcHLWgSECgSgQhAuKFxChQQmvLdhTaodqeEGA62lOChABbL5CBF5lSsSn0KAWxYisSBlQRcGhYDwNxQMtuPhQF7UbiVKnUhowpi4acKYukoPuACIRTXrU4LCJQai24FAoEoISCoBRkXkKBdMGQhVO/WgWv2FFpQF8Suz9FrCD0IO9EINWBAkIOQAI2oNUBTeCgYEIlUxtlTfBulFyMoG4HQAUXQgh3BQ23FNJGxAhyBWpFqhNIUXFiNwKDljQTSsAdrCghAqVCLbgUKpCDwboIQIF5YCsJCBvBRUldoQu0O8Jjg66YTSgEB6BQgFqQIF8KAg0LVeJF0JutqIWrebxN0aUKEFF7DPAqFCLUQmOhCHISEWByLS1RcHoQCmv8AW4HVB1hFgOsIghA3FiLFhuDiEHnY5QCsCi6UEWKXBYgVBWtQCsFwKD1IK//EAC4RAAIBAQUHBQEAAgMAAAAAAAABEQIDBBAgMRIwMjNAQWAFEyFQURQiQmFxkP/aAAgBAgEBPwD/AMGKVLP5aPw/ks/w/ks/w/jsx3Kg/iX6O5f8n8T/AEru+wtfB7PiQqUbKNik9un8PZoLWhUsZVUWrleD0cSKdMt41KmVMq0fg9HEijhWW9alTGVaeD06os+BZb3qirCrTwenUsuBZb5qh4PTwenUseWst97Dwfg61LHlr/rLfew8H4PTqXflU5b7oh4Pwdal25VOW+6IfhKLpyKct94UPF+DIufIpy3zhHi/BkXHkU5b5wDxfg9w5FOW+cGSrwf0/kLLeuXkq18GR6dyFlvXLyV6+D+ncnLeeW8levg/pvJy3nlPJXr4P6XynlvHKY8a+LwZHpfA8tvy2PGvi8H9Lf8AjUSSTha8DHjXxbxWdTFYPu/uvTXCqNo2zbQq0VuaWPGvXNDYrGt9hWD7sVjSKihdvvbi4k2jbPcPcPecQNJjoHSytSxUNisaxWH6xWNKFTSuxJJJJJJP3d1cSbRJJJJOEnwbRJJPgMCpbLGh0a5J3Mk4zhBH2qpZTd7SrRCutXdiu9Hdis7NdhKlaIkRBskIjfTkn65Utiu9o+wrsv8AZisbJa/IlQtKT3KloOva1wjGRZmfJLNpm1kjJOEEfUwU2dVeiFdqxXZd6hWNmhU0rRG09zOEIh4SSSTk2TZIxk+SCPqIKbGurRCu1fcV3p7sVnZrsJpaIdbeSSd3GG0fBBBG5gjCcYII66GKxtHohXZ/7MVhQtWKizXYVUaDqb1xkknPO6nLOEZ5Jw+CCCOrSbFd7R6IV2fdisaFqKihaITa0G56OScYIzzjJOMk55JwjpIFY1vsK7vuxWFC1YrOhdiY0Np98k5J6OScYI3kEdRDYrGv8Fd33YrChasVFC7Exp0E72M0kk4wRhJO5hEEYTjO5hlNnVVoK71iu67sVjZoSpWiNp9HBHQRnknBPCCN7BBGWBWdT7Cu9RTd6Vqz27NaIhEvpo6XZIgnpFlgV1q7iu9C1ZsWa0R8dkTlXXIjdrGCMF0MZZyr6KMJwnfxnnCMk4RhO4eeOlW4TyzljGcs4wRmncQQNfUPcJ5IwjGRYyTkjCeg/8QALBEAAgECBAYCAgEFAAAAAAAAAAERAhIFEyBgAwQQMjNQMUAwURQhQUJhkP/aAAgBAwEBPwD/AIMMz/8AZns/kGexcYzjOM0pqnY9fayviVS/6mbX+zOr/Z/I4n7FzXE/ZyvEq4lMsRTSUqNj1fDK+56eR7ClFKFser4ZxO56cP7ClCFser4Zxe96cN7WU7Jfwzjd704Z2sWyavhnH8j04X8PohbHfwzmPK9OF/3EIWx2c15qtOFf5CELZHN+arThXzUIQtjv4Od89WnC+5iFsnnvPVpwzufRbJxDz1acM72LZWIeerThvk0LY+I+d6cO8ouiFsfEvO9OH+bQtj4n5tPIeZaFsfFfKSSSSch5loWx8W8i08j5loWx8W7kQR15PzIXVbHxSmWi0tLS05byoQhC/HJci/3XP0zBlGUZLHwmcGmK0L4EIWqS9GYXlzJfvOapksMsyjKFwEnInAmJlJKL0Xl7Ln0jRHvOMpLS0gggjpHWOkbClIraZGyJHXSZiMx/ouqJfWSSSdgSh1ozC+olssElqjShdIII0z7C5GYi9lzJeqPxRpkknVPqZL0XozGXVdEtMfnkkX4JJ9PejML2SyCFojXH3Z+7KL6TML2S/SR6S5F5ey59IRH2oI9TKLkXl5c/SwR1n7skl6MwuZL9ZBH0pJ13IvMxl7JI9ZP2pM1GYy6ol+zn7EaF9+fYr3Ek/nknUvRr1n//2Q=="; + +#if defined(ESP32) || defined(ESP8266) +#if defined(ESP32) + if (ESP_MAIL_DEFAULT_FLASH_FS.begin(true)) +#elif defined(ESP8266) + if (ESP_MAIL_DEFAULT_FLASH_FS.begin()) +#endif + { + + // ESP_MAIL_DEFAULT_FLASH_FS.format(); + + if (ESP_MAIL_DEFAULT_FLASH_FS.exists("/base64Img.jpg")) + ESP_MAIL_DEFAULT_FLASH_FS.remove("/base64Img.jpg"); + + Serial.println("Preparing flash file attachments..."); + +#if defined(ESP32) + File file = ESP_MAIL_DEFAULT_FLASH_FS.open("/base64Img.jpg", FILE_WRITE); +#elif defined(ESP8266) + File file = ESP_MAIL_DEFAULT_FLASH_FS.open("/base64Img.jpg", "w"); +#endif + file.print(base64Img); + file.close(); + +#if defined(ESP32) + file = ESP_MAIL_DEFAULT_FLASH_FS.open("/msg.html", FILE_WRITE); +#elif defined(ESP8266) + file = ESP_MAIL_DEFAULT_FLASH_FS.open("/msg.html", "w"); +#endif + file.print(html); + file.close(); + } + else + { + Serial.println("Flash filesystem monting Failed"); + } +#endif + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Enable the chunked data transfer with pipelining for large message if server supported */ + message.enable.chunking = true; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + + message.subject = F("Test sending base64 inline image stored in flash memory"); + message.addRecipient(F("user1"), RECIPIENT_EMAIL); + + /* Two alternative content versions are sending in this example e.g. plain text and html */ + + /* Assign blob data (in flash or ram) as HTML message */ + message.html.blob.data = (const uint8_t *)html; + message.html.blob.size = strlen(html); + + // Or get the content from file + // message.html.file.name = "/msg.html"; + // message.html.file.type = esp_mail_file_storage_type_flash; + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) <- not supported for message from blob and file + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + /** The HTML text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("utf-8"); + + message.text.content = F("This message contains inline image.\r\nThe inline image was not shown in the plain text message."); + message.text.charSet = F("utf-8"); + message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* The attachment data item */ + SMTP_Attachment att; + /** Set the inline image info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + att.descr.filename = F("base64Img.jpg"); + att.descr.mime = F("image/jpg"); + +#if defined(ESP32) || defined(ESP8266) + att.file.path = F("/base64Img.jpg"); + /** The file storage type e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + att.file.storage_type = esp_mail_file_storage_type_flash; +#elif defined(ARDUINO_ARCH_SAMD) + att.blob.data = (const uint8_t *)base64Img; + att.blob.size = sizeof(base64Img); +#endif + + att.descr.content_id = F("image-001"); // The content id (cid) of orange image in the src tag + + /* Need to be base64 transfer encoding for inline image */ + att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /** The attach image file is already base64 encoded file. + * Then set the content encoding to match the transfer encoding + * which no encoding was taken place prior to sending. + */ + att.descr.content_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add inline image to the message */ + message.addInlineImage(att); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending the Email and close the session */ + if (!MailClient.sendMail(&smtp, &message, true)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_HTML/Send_HTML.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_HTML/Send_HTML.ino index 1a4af3860..d1d9fffd5 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_HTML/Send_HTML.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_HTML/Send_HTML.ino @@ -1,301 +1,301 @@ - - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to send html message. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /* The full message sending logs can now save to file */ - /* Since v3.0.4, the sent logs stored in smtp.sendingResult will store only the latest message logs */ - // config.sentLogs.filename = "/path/to/log/file"; - // config.sentLogs.storage_type = esp_mail_file_storage_type_flash; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - message.subject = F("Test sending html Email"); - message.addRecipient(F("Admin"), RECIPIENT_EMAIL); - - String htmlMsg = "

This is the html text message.

The message was sent via ESP device.

"; - message.html.content = htmlMsg; - - /** The html text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.html.charSet = F("us-ascii"); - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader(F("Message-ID: ")); - - /* Set the TCP response read timeout in seconds */ - // smtp.setTCPTimeout(10); - - /* Connect to the server */ - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } + + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send html message. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* The full message sending logs can now save to file */ + /* Since v3.0.4, the sent logs stored in smtp.sendingResult will store only the latest message logs */ + // config.sentLogs.filename = "/path/to/log/file"; + // config.sentLogs.storage_type = esp_mail_file_storage_type_flash; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending html Email"); + message.addRecipient(F("Admin"), RECIPIENT_EMAIL); + + String htmlMsg = "

This is the html text message.

The message was sent via ESP device.

"; + message.html.content = htmlMsg; + + /** The html text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* Set the TCP response read timeout in seconds */ + // smtp.setTCPTimeout(10); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Parallel_Attachment/Send_Parallel_Attachment.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Parallel_Attachment/Send_Parallel_Attachment.ino index bb7221272..27a05456a 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Parallel_Attachment/Send_Parallel_Attachment.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Parallel_Attachment/Send_Parallel_Attachment.ino @@ -1,334 +1,334 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt - * -*/ - - -/** - * This example shows how to send Email with media e.g. audio and images as parallen attachments, - * and play or display them simultaneously on the Email client (depends on the Mail client supports). - */ - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -/* This is for attachment data */ -#include "data.h" - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /* Declare the message class */ - SMTP_Message message; - - /* Enable the chunked data transfer with pipelining for large message if server supported */ - message.enable.chunking = true; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - - message.subject = F("Test sending Email with parallel attachments"); - message.addRecipient(F("user1"), RECIPIENT_EMAIL); - - message.html.content = F("This message contains image and audio file which will play on the Mail client in parallel or simultaneously (depends on the client supports)."); - - /** The HTML text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.html.charSet = F("utf-8"); - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; - - message.text.content = F("This message contains image and audio file which will play on the Mail client in parallel or simultaneously (depends on the client supports)."); - message.text.charSet = F("us-ascii"); - message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader(F("Message-ID: ")); - - /* The attachment data item */ - SMTP_Attachment att; - - /** Set the attachment info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - att.descr.filename = F("haun.png"); - att.descr.mime = F("image/png"); - att.blob.data = shaun_png; - att.blob.size = sizeof(shaun_png); - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - message.addParallelAttachment(att); - - /** Set the attachment info e.g. - * file name, MIME type, file path, file storage type, - * transfer encoding and content encoding - */ - message.resetAttachItem(att); // Clear the attach item data to reuse - att.descr.filename = F("mu_law.wav"); - att.descr.mime = F("audio/basic"); - att.blob.data = mu_law_wave; - att.blob.size = sizeof(mu_law_wave); - att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - message.addParallelAttachment(att); - - /* Connect to the server */ - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - - /* Start sending the Email and close the session */ - if (!MailClient.sendMail(&smtp, &message, true)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } -} + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + * +*/ + + +/** + * This example shows how to send Email with media e.g. audio and images as parallen attachments, + * and play or display them simultaneously on the Email client (depends on the Mail client supports). + */ + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +/* This is for attachment data */ +#include "data.h" + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Enable the chunked data transfer with pipelining for large message if server supported */ + message.enable.chunking = true; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + + message.subject = F("Test sending Email with parallel attachments"); + message.addRecipient(F("user1"), RECIPIENT_EMAIL); + + message.html.content = F("This message contains image and audio file which will play on the Mail client in parallel or simultaneously (depends on the client supports)."); + + /** The HTML text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.html.charSet = F("utf-8"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.html.transfer_encoding = Content_Transfer_Encoding::enc_qp; + + message.text.content = F("This message contains image and audio file which will play on the Mail client in parallel or simultaneously (depends on the client supports)."); + message.text.charSet = F("us-ascii"); + message.text.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* The attachment data item */ + SMTP_Attachment att; + + /** Set the attachment info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + att.descr.filename = F("haun.png"); + att.descr.mime = F("image/png"); + att.blob.data = shaun_png; + att.blob.size = sizeof(shaun_png); + att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + message.addParallelAttachment(att); + + /** Set the attachment info e.g. + * file name, MIME type, file path, file storage type, + * transfer encoding and content encoding + */ + message.resetAttachItem(att); // Clear the attach item data to reuse + att.descr.filename = F("mu_law.wav"); + att.descr.mime = F("audio/basic"); + att.blob.data = mu_law_wave; + att.blob.size = sizeof(mu_law_wave); + att.descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + message.addParallelAttachment(att); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + + /* Start sending the Email and close the session */ + if (!MailClient.sendMail(&smtp, &message, true)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Parallel_Attachment/data.h b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Parallel_Attachment/data.h index c7a88aeab..0b73e9752 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Parallel_Attachment/data.h +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Parallel_Attachment/data.h @@ -1,1957 +1,1957 @@ -#include - -static const uint8_t mu_law_wave[] PROGMEM = { -0x52, 0x49, 0x46, 0x46, 0x84, 0x5D, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20, -0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, -0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x66, 0x61, 0x63, 0x74, 0x04, 0x00, 0x00, 0x00, 0x00, 0x5D, -0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x5D, 0x00, 0x00, 0xFB, 0xFD, 0xFF, 0xFE, 0xFF, 0x7F, -0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7C, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7C, 0x7D, -0x7C, 0x7C, 0x7D, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7E, 0xFF, 0x7F, -0x7D, 0x7C, 0x7B, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7C, 0x7C, 0x7B, -0x7B, 0x7B, 0x7A, 0x7A, 0x7B, 0x7A, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x7C, 0x7E, -0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x79, 0x79, 0x7B, 0x7B, 0x7B, 0x7C, 0x7C, 0x7E, 0xFF, 0xFE, 0xFE, -0xFF, 0x7E, 0x7C, 0x7D, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x79, 0x78, 0x79, -0x7A, 0x79, 0x78, 0x78, 0x78, 0x77, 0x78, 0x78, 0x79, 0x79, 0x78, 0x77, 0x77, 0x78, 0x78, 0x79, -0x7A, 0x79, 0x79, 0x78, 0x78, 0x7A, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, -0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFC, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF8, 0xF8, -0xF7, 0xF7, 0xF8, 0xF9, 0xF9, 0xFB, 0xFC, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFE, -0xFF, 0xFF, 0xFE, 0x7E, 0x7D, 0x7D, 0x7C, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x7C, -0x7B, 0x7A, 0x79, 0x79, 0x79, 0x77, 0x77, 0x78, 0x79, 0x7B, 0x7C, 0x7B, 0x7B, 0x7C, 0x7B, 0x7B, -0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x79, 0x79, -0x78, 0x77, 0x77, 0x79, 0x79, 0x79, 0x7B, 0x7B, 0x7A, 0x7C, 0x7E, 0x7D, 0x7E, 0x7E, 0x7C, 0x7C, -0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x79, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x78, 0x78, 0x7A, 0x7A, 0x79, -0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFC, 0xFB, 0xFB, 0xFC, -0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFE, 0xFF, 0x7E, 0x7E, 0xFF, 0xFF, 0x7E, 0x7E, 0x7D, 0x7B, -0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, -0x7C, 0x7B, 0x79, 0x7A, 0x7A, 0x7A, 0x7A, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7C, 0x79, 0x79, 0x7A, -0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7C, 0x7C, 0x7C, 0x7E, 0x7D, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0xFE, -0xFD, 0xFD, 0xFB, 0xFB, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, -0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7D, 0x7E, 0x7D, 0x7B, 0x7B, 0x7B, 0x79, 0x78, 0x77, -0x78, 0x78, 0x77, 0x77, 0x77, 0x78, 0x78, 0x76, 0x76, 0x75, 0x73, 0x73, 0x73, 0x72, 0x73, 0x73, -0x74, 0x74, 0x74, 0x75, 0x77, 0x78, 0x78, 0x77, 0x76, 0x77, 0x76, 0x76, 0x78, 0x79, 0x79, 0x79, -0x78, 0x79, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7E, -0x7E, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFE, 0xFF, 0xFD, 0xFE, 0x7F, 0xFF, -0x7F, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7E, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7D, 0x7F, -0xFF, 0xFF, 0xFE, 0xFE, 0x7F, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7C, 0x7D, -0x7D, 0x7D, 0x7D, 0x7E, 0x7F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFF, 0xFE, 0xFC, 0xFD, 0xFC, 0xFC, 0xFD, -0xFC, 0xFB, 0xFB, 0xFC, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFD, 0xFE, -0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7D, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7D, 0x7B, 0x7B, 0x79, -0x78, 0x78, 0x78, 0x76, 0x74, 0x74, 0x73, 0x72, 0x75, 0x77, 0x77, 0x76, 0x75, 0x75, 0x76, 0x77, -0x77, 0x76, 0x74, 0x74, 0x74, 0x74, 0x76, 0x76, 0x76, 0x77, 0x75, 0x76, 0x78, 0x79, 0x77, 0x77, -0x79, 0x7B, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7D, 0x7F, 0x7E, 0xFF, 0xFF, 0x7F, 0xFE, 0xFC, 0xFE, -0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFD, 0xFC, 0xFE, 0xFF, 0x7E, 0x7F, 0x7F, 0x7D, 0x7E, 0xFF, 0x7F, -0x7F, 0xFF, 0x7F, 0x7E, 0x7D, 0x7E, 0xFF, 0x7E, 0x7F, 0x7F, 0x7C, 0x7D, 0x7F, 0x7D, 0x7E, 0x7E, -0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7B, 0x7D, 0x7B, 0x7A, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7C, -0x7D, 0x7E, 0x7F, 0xFF, 0x7F, 0x7F, 0x7F, 0xFF, 0xFD, 0xFD, 0xFD, 0xFC, 0xFB, 0xFB, 0xFB, 0xFB, -0xFA, 0xFB, 0xFB, 0xFB, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x7E, 0x7E, 0x7D, 0x7B, 0x7B, 0x7B, -0x78, 0x79, 0x78, 0x75, 0x76, 0x76, 0x76, 0x76, 0x74, 0x74, 0x73, 0x73, 0x74, 0x73, 0x72, 0x73, -0x75, 0x75, 0x74, 0x76, 0x74, 0x72, 0x73, 0x74, 0x75, 0x75, 0x76, 0x77, 0x77, 0x78, 0x77, 0x77, -0x77, 0x78, 0x78, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x7A, 0x79, 0x7B, 0x7C, 0x7B, 0x7B, -0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7C, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, -0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, -0xFE, 0x7E, 0x7E, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7E, 0xFF, 0x7E, 0x7E, 0x7E, 0x7D, -0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFD, 0xFC, 0xFE, 0x7F, 0x7E, 0x7E, 0x7F, 0xFF, 0xFF, -0x7F, 0x7E, 0x7D, 0x7D, 0x7D, 0x7B, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, 0x7D, 0x7C, 0x7C, -0x7D, 0x7C, 0x7C, 0x7E, 0x7E, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFF, -0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, -0xFB, 0xFB, 0xFA, 0xFB, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, -0x7E, 0x7E, 0x7E, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7F, -0x7D, 0x7B, 0x7C, 0x7C, 0x7D, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7E, -0x7F, 0x7E, 0x7D, 0x7C, 0x7B, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x78, 0x77, 0x77, 0x76, 0x74, 0x73, -0x72, 0x73, 0x74, 0x75, 0x77, 0x78, 0x78, 0x79, 0x79, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, -0x7C, 0x7D, 0x7E, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, 0x7D, 0x7C, 0x7B, -0x7A, 0x7B, 0x7B, 0x7A, 0x7A, 0x79, 0x79, 0x7A, 0x79, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x79, 0x79, -0x79, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7A, 0x7B, 0x7C, 0x7B, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7F, -0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7D, 0x7D, -0x7D, 0x7D, 0x7E, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7F, 0x7F, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7F, 0x7F, 0x7E, -0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, -0x7A, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, -0x7D, 0x7E, 0xFF, 0x7E, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7A, 0x7A, -0x7A, 0x79, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, 0x7D, 0x7C, 0x7C, 0x7A, 0x79, 0x79, 0x78, 0x78, -0x78, 0x77, 0x77, 0x76, 0x75, 0x74, 0x74, 0x74, 0x73, 0x73, 0x73, 0x73, 0x74, 0x74, 0x76, 0x75, -0x74, 0x75, 0x77, 0x78, 0x78, 0x7A, 0x7B, 0x7D, 0xFF, 0xFE, 0xFE, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, -0xFC, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, -0xF8, 0xFA, 0xF8, 0xF6, 0xF7, 0xF7, 0xF8, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFB, -0xFB, 0xFB, 0xFD, 0xFE, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, 0xFE, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, -0x7F, 0x7E, 0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0xFD, 0xFE, 0xFF, -0xFE, 0xFE, 0xFD, 0xFE, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7E, 0x7F, -0x7D, 0x7D, 0x7E, 0x7E, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x79, 0x77, 0x78, 0x79, 0x78, 0x77, 0x76, -0x76, 0x75, 0x73, 0x74, 0x73, 0x71, 0x70, 0x70, 0x71, 0x72, 0x71, 0x71, 0x70, 0x6F, 0x6F, 0x6F, -0x70, 0x71, 0x71, 0x72, 0x73, 0x74, 0x74, 0x74, 0x76, 0x77, 0x76, 0x78, 0x79, 0x79, 0x79, 0x78, -0x7A, 0x7B, 0x7B, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, -0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7D, -0x7D, 0x7D, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7C, 0x7A, 0x78, 0x79, 0x78, 0x77, -0x76, 0x78, 0x79, 0x78, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7A, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, -0x7E, 0xFF, 0xFD, 0xFC, 0xFC, 0xFA, 0xF9, 0xFA, 0xFB, 0xFA, 0xF9, 0xF8, 0xF8, 0xF9, 0xFA, 0xF9, -0xF9, 0xF9, 0xF9, 0xF9, 0xF8, 0xF7, 0xF9, 0xF9, 0xF8, 0xF8, 0xFA, 0xFB, 0xFA, 0xFB, 0xFD, 0xFD, -0xFC, 0xFD, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFF, 0x7F, 0x7F, 0x7E, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, -0x7A, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x75, 0x76, 0x77, 0x76, 0x75, 0x76, 0x76, 0x75, 0x76, 0x77, -0x78, 0x79, 0x7B, 0x7B, 0x7B, 0x7A, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7A, 0x7B, 0x7B, 0x7A, -0x7B, 0x7D, 0x7E, 0x7B, 0x7C, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFC, 0xFD, 0xFE, 0xFF, -0xFE, 0xFF, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7D, 0x7F, 0x7F, 0x7C, 0x7B, -0x7A, 0x78, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7C, 0x7C, 0x7A, 0x7B, 0x7C, 0x7C, 0x7B, 0x7C, 0x7C, -0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x79, 0x7A, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, -0x7D, 0xFE, 0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFA, 0xF8, 0xF8, 0xF9, 0xF8, 0xF5, 0xF4, 0xF7, 0xF8, -0xF8, 0xF8, 0xF9, 0xFB, 0xFC, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7B, -0x7A, 0x7B, 0x7B, 0x7A, 0x78, 0x78, 0x77, 0x76, 0x76, 0x75, 0x76, 0x76, 0x76, 0x77, 0x75, 0x75, -0x76, 0x75, 0x76, 0x76, 0x78, 0x78, 0x77, 0x78, 0x76, 0x74, 0x75, 0x77, 0x79, 0x7A, 0x7A, 0x7B, -0x7C, 0x7D, 0x7D, 0x7D, 0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0x7F, 0xFF, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, -0xFE, 0x7F, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0xFF, 0xFD, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, -0xFC, 0xFD, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7C, -0x7B, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x7A, 0x7C, 0x7A, 0x7B, 0x7C, 0x7C, 0x7E, 0x7E, 0xFF, -0xFF, 0x7F, 0x7F, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, -0x7C, 0x7D, 0xFF, 0x7E, 0x7C, 0x7D, 0xFF, 0xFF, 0xFF, 0xFD, 0xFD, 0xFF, 0x7E, 0x7F, 0x7E, 0x7E, -0x7F, 0x7E, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x79, -0x77, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7C, 0x7D, 0x7D, 0x7E, 0xFD, 0xFD, 0xFE, 0xFC, 0xFC, 0xFB, -0xFB, 0xFC, 0xFB, 0xFB, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, -0xFF, 0xFF, 0xFD, 0xFC, 0xFD, 0xFD, 0xFC, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7D, 0x7C, 0x7D, 0x7E, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, -0x7B, 0x7C, 0x7D, 0x7B, 0x7B, 0x7C, 0x7A, 0x78, 0x78, 0x78, 0x77, 0x75, 0x75, 0x75, 0x73, 0x72, -0x72, 0x72, 0x71, 0x71, 0x72, 0x72, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x74, 0x74, -0x75, 0x76, 0x76, 0x76, 0x77, 0x78, 0x77, 0x78, 0x79, 0x77, 0x78, 0x78, 0x79, 0x7A, 0x7A, 0x7A, -0x7A, 0x79, 0x77, 0x76, 0x76, 0x78, 0x78, 0x77, 0x77, 0x77, 0x75, 0x74, 0x74, 0x75, 0x75, 0x76, -0x79, 0x79, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7D, 0xFF, 0xFD, 0xFD, 0xFE, 0xFF, 0xFE, 0xFC, -0xF9, 0xF9, 0xFB, 0xFA, 0xF9, 0xF8, 0xF8, 0xF8, 0xF6, 0xF4, 0xF6, 0xF8, 0xF7, 0xF7, 0xF9, 0xF9, -0xF9, 0xF8, 0xF8, 0xFB, 0xFA, 0xF9, 0xFA, 0xFB, 0xFC, 0xFE, 0xFC, 0xFD, 0xFF, 0x7E, 0x7F, 0x7E, -0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, 0x7A, 0x7A, 0x79, 0x79, 0x78, 0x77, 0x78, -0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, 0x7F, 0xFE, 0xFE, 0xFD, 0xFD, -0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0xFC, 0xFB, 0xFC, -0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, -0x7C, 0x7B, 0x7B, 0x7C, 0x79, 0x79, 0x79, 0x78, 0x76, 0x75, 0x76, 0x78, 0x77, 0x76, 0x76, 0x77, -0x76, 0x74, 0x74, 0x75, 0x75, 0x75, 0x74, 0x74, 0x76, 0x77, 0x78, 0x7A, 0x7C, 0x7B, 0x7A, 0x7D, -0x7E, 0x7E, 0x7C, 0x7D, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFE, 0xFF, -0xFF, 0x7F, 0x7E, 0x7F, 0xFF, 0xFE, 0xFD, 0xFF, 0xFE, 0xFC, 0xFB, 0xFC, 0xFE, 0xFD, 0xFC, 0xFE, -0xFF, 0xFE, 0xFD, 0xFF, 0x7E, 0x7F, 0xFE, 0xFC, 0xFD, 0xFE, 0xFD, 0xFD, 0xFE, 0x7F, 0x7E, 0xFF, -0xFF, 0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7E, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, -0x7E, 0x7D, 0x7E, 0xFF, 0xFF, 0xFE, 0xFD, 0xFF, 0x7D, 0x7A, 0x79, 0x79, 0x7A, 0x7C, 0x7B, 0x7B, -0x7D, 0x7E, 0x7E, 0x7D, 0xFF, 0xFF, 0x7F, 0x7F, 0x7E, 0x7B, 0x7A, 0x7A, 0x7A, 0x78, 0x77, 0x77, -0x77, 0x78, 0x78, 0x76, 0x76, 0x76, 0x76, 0x74, 0x74, 0x73, 0x74, 0x74, 0x75, 0x74, 0x72, 0x74, -0x76, 0x74, 0x74, 0x76, 0x76, 0x74, 0x73, 0x73, 0x72, 0x73, 0x74, 0x76, 0x77, 0x75, 0x73, 0x75, -0x77, 0x78, 0x75, 0x75, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7B, -0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7D, 0x7C, 0x7D, 0x7B, 0x7C, 0x7F, -0xFF, 0xFF, 0x7E, 0x7D, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x79, 0x77, 0x77, -0x78, 0x76, 0x76, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x7B, 0x7C, 0x7B, 0x7C, 0x7D, 0xFF, -0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFB, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, -0xFA, 0xF9, 0xF9, 0xF7, 0xF7, 0xF7, 0xF4, 0xF4, 0xF4, 0xF2, 0xEF, 0xEE, 0xEF, 0xF2, 0xF2, 0xF1, -0xF2, 0xF5, 0xF5, 0xF3, 0xF1, 0xF2, 0xF5, 0xF7, 0xF8, 0xFA, 0xFB, 0xFC, 0xFC, 0xFB, 0xFC, 0xFC, -0xFD, 0xFF, 0x7F, 0x7E, 0x7C, 0x7A, 0x7A, 0x78, 0x77, 0x76, 0x75, 0x75, 0x74, 0x71, 0x70, 0x71, -0x71, 0x71, 0x70, 0x6F, 0x71, 0x71, 0x71, 0x73, 0x75, 0x77, 0x77, 0x76, 0x79, 0x7A, 0x79, 0x79, -0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7F, 0xFF, 0xFE, 0xFF, 0x7E, 0x7D, 0x7E, 0x7E, 0x7D, 0x7D, -0x7E, 0x7C, 0x7C, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x77, 0x75, 0x75, 0x76, 0x78, 0x79, 0x78, -0x7A, 0x7C, 0x7C, 0x7A, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7B, 0x7D, 0x7D, 0x7C, -0x7C, 0x7E, 0xFF, 0x7F, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0xFF, 0x7F, 0x7E, -0x7D, 0x7D, 0xFF, 0xFF, 0x7F, 0xFF, 0xFC, 0xFC, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xFB, 0xFB, -0xF9, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0x7F, 0x7F, 0x7E, 0x7D, 0x7E, 0x7D, 0x7B, 0x7C, 0x7B, -0x7B, 0x7C, 0x7C, 0x7A, 0x78, 0x78, 0x7B, 0x7A, 0x77, 0x75, 0x76, 0x75, 0x76, 0x76, 0x76, 0x76, -0x78, 0x79, 0x78, 0x75, 0x75, 0x76, 0x77, 0x7A, 0x7D, 0xFF, 0xFC, 0xFB, 0xFA, 0xFA, 0xFB, 0xFA, -0xFB, 0xFB, 0xFC, 0xFD, 0xFD, 0x7E, 0x78, 0x76, 0x72, 0x70, 0x71, 0x75, 0x77, 0x77, 0x79, 0x7A, -0x7A, 0x7A, 0x7B, 0xFF, 0xFB, 0xFA, 0xF9, 0xFB, 0xFD, 0xFE, 0x7E, 0x7F, 0xFF, 0xFC, 0xF6, 0xF3, -0xF7, 0xFC, 0xFF, 0x7A, 0x73, 0x6E, 0x6C, 0x6D, 0x6E, 0x6E, 0x6E, 0x6E, 0x6F, 0x74, 0x73, 0x72, -0x75, 0x7A, 0x7D, 0x7D, 0xFF, 0xFF, 0x7C, 0x7C, 0x7D, 0x7B, 0x7A, 0x79, 0x7B, 0xFF, 0xFF, 0x7D, -0x7C, 0xFF, 0xFE, 0x7D, 0xFC, 0xF3, 0xF6, 0xFC, 0xFE, 0xFE, 0xFF, 0x78, 0x75, 0x79, 0x7A, 0x7E, -0xF8, 0xF6, 0xF6, 0xF2, 0xEF, 0xEE, 0xF0, 0xF7, 0xFD, 0xFE, 0xFD, 0x7B, 0x77, 0x7C, 0xFF, 0xFB, -0xFD, 0x7D, 0xFF, 0x7C, 0x78, 0x7A, 0x7A, 0xFF, 0xF9, 0xF5, 0xF1, 0xF4, 0xFA, 0xFC, 0xFC, 0xFA, -0xF8, 0xFA, 0xFB, 0xFA, 0xFB, 0xFC, 0xFD, 0xFF, 0x7D, 0x7B, 0x7D, 0x7E, 0x7A, 0x76, 0x76, 0x75, -0x72, 0x75, 0x7B, 0x7D, 0x7A, 0x7A, 0x7D, 0xFF, 0x7C, 0x7C, 0xFF, 0x7D, 0x7A, 0x7B, 0x7C, 0x7E, -0xFC, 0xFC, 0x7F, 0xFE, 0xFD, 0xFE, 0xFC, 0xF8, 0xF9, 0xFA, 0xFB, 0xFE, 0x7E, 0x79, 0x72, 0x72, -0x74, 0x76, 0x78, 0x76, 0x78, 0x7A, 0x75, 0x76, 0x77, 0x75, 0x73, 0x73, 0x73, 0x73, 0x74, 0x73, -0x73, 0x77, 0x78, 0x79, 0x79, 0x7A, 0x79, 0x73, 0x73, 0x7B, 0x7C, 0x7C, 0xFC, 0xFC, 0xFE, 0x7F, -0x76, 0x73, 0x76, 0x73, 0x73, 0x78, 0x7C, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0x7D, 0x7B, 0x7B, -0x7C, 0x7A, 0x78, 0x7B, 0x7B, 0x7D, 0x7F, 0x7A, 0x77, 0x73, 0x6F, 0x70, 0x72, 0x73, 0x72, 0x72, -0x73, 0x74, 0x74, 0x76, 0x7D, 0xFE, 0x7D, 0x7C, 0x7C, 0x78, 0x76, 0x77, 0x79, 0x7B, 0xFF, 0xFD, -0xFE, 0x7E, 0x7B, 0x7A, 0x78, 0x78, 0x7B, 0x7C, 0x7C, 0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x79, 0x7B, -0xFF, 0xFA, 0xF9, 0xFD, 0x7E, 0x7D, 0x7C, 0x7B, 0x7E, 0xFE, 0xFC, 0xFF, 0x7E, 0xFE, 0xFD, 0xFE, -0xFD, 0xFC, 0xFB, 0xFC, 0xFC, 0xFD, 0xF9, 0xF3, 0xF2, 0xF3, 0xF4, 0xF6, 0xF6, 0xF8, 0xFA, 0xFC, -0xFB, 0xF7, 0xF9, 0xFC, 0xFC, 0xFD, 0xFD, 0x7E, 0x7C, 0x7F, 0xFF, 0x7D, 0x7A, 0x7A, 0x7B, 0x78, -0x78, 0x78, 0x75, 0x75, 0x76, 0x79, 0x7A, 0x79, 0x7C, 0x7F, 0xFD, 0xFF, 0x7E, 0xFF, 0x7D, 0x79, -0x77, 0x78, 0x79, 0x78, 0x79, 0x7C, 0x7D, 0x7F, 0x7E, 0x7E, 0xFE, 0xFC, 0xF8, 0xF7, 0xFA, 0xFB, -0xFC, 0xFD, 0xFF, 0x7D, 0x7E, 0x7F, 0xFF, 0x7D, 0x7B, 0x7D, 0xFE, 0xF9, 0xF5, 0xF6, 0xF6, 0xF4, -0xF6, 0xFA, 0xFE, 0x7D, 0x79, 0x78, 0x77, 0x77, 0x7A, 0x7E, 0xFE, 0xFF, 0xFF, 0xFA, 0xFA, 0xFE, -0x7C, 0x75, 0x71, 0x72, 0x74, 0x75, 0x74, 0x75, 0x75, 0x77, 0x79, 0x79, 0x77, 0x74, 0x74, 0x74, -0x72, 0x71, 0x70, 0x71, 0x70, 0x6F, 0x72, 0x73, 0x72, 0x73, 0x71, 0x70, 0x73, 0x78, 0x7A, 0x78, -0x77, 0x77, 0x76, 0x74, 0x73, 0x72, 0x70, 0x71, 0x75, 0x78, 0x7B, 0x7F, 0xFF, 0xFE, 0xFB, 0xFD, -0x7E, 0xFF, 0xFD, 0x7F, 0x7C, 0x7B, 0x7F, 0xFD, 0xFF, 0xFE, 0xFC, 0xFE, 0xFD, 0xFC, 0xFA, 0xF7, -0xF7, 0xFB, 0xFD, 0xFE, 0x7E, 0x7C, 0x7B, 0x7A, 0x7B, 0x79, 0x75, 0x75, 0x76, 0x78, 0x7D, 0xFF, -0x7E, 0x7D, 0x7E, 0x7C, 0x77, 0x75, 0x76, 0x76, 0x78, 0x7E, 0xFD, 0xFB, 0xFC, 0xFD, 0xFE, 0x7C, -0x78, 0x78, 0x7A, 0x7B, 0x7E, 0x7E, 0x7D, 0x7D, 0x7C, 0x7A, 0x78, 0x79, 0x7B, 0x7A, 0x7D, 0xFC, -0xFD, 0x7E, 0xFF, 0xFB, 0xF7, 0xF6, 0xF7, 0xF7, 0xF6, 0xFA, 0xFF, 0xFE, 0xFD, 0xFF, 0x7D, 0xFF, -0xFC, 0xFB, 0xF9, 0xFD, 0xFE, 0xFD, 0x7E, 0x79, 0x76, 0x71, 0x6F, 0x6E, 0x6E, 0x6F, 0x72, 0x76, -0x7A, 0x7E, 0xFF, 0xFF, 0x7C, 0x7B, 0x7C, 0x7B, 0x7A, 0x79, 0x7A, 0x7E, 0xFF, 0xFF, 0x7E, 0x7D, -0x7D, 0x7E, 0x7C, 0x78, 0x79, 0x7A, 0x7B, 0xFF, 0xFF, 0x7F, 0x7E, 0x7B, 0x79, 0x79, 0x76, 0x72, -0x73, 0x7B, 0xFF, 0xFE, 0xFB, 0xFA, 0xFA, 0xFC, 0x7D, 0x78, 0x77, 0x78, 0x79, 0x79, 0x78, 0x79, -0x77, 0x73, 0x74, 0x76, 0x77, 0x79, 0x7A, 0x7B, 0x7F, 0xFD, 0xFE, 0xFF, 0x7F, 0x7E, 0x7E, 0x7C, -0x78, 0x78, 0x7B, 0x7B, 0x7A, 0x7C, 0x7F, 0xFE, 0xFD, 0xFE, 0x7E, 0xFF, 0xFD, 0xFC, 0xF9, 0xF5, -0xF2, 0xF0, 0xF2, 0xF3, 0xF0, 0xF1, 0xF2, 0xF1, 0xF4, 0xF7, 0xF8, 0xFC, 0xFC, 0xF6, 0xF3, 0xF4, -0xF5, 0xF5, 0xF6, 0xFB, 0xFF, 0xFF, 0xFF, 0x7D, 0x7D, 0x7E, 0x7D, 0x79, 0x75, 0x74, 0x75, 0x72, -0x72, 0x75, 0x75, 0x74, 0x77, 0x7A, 0x7A, 0x7A, 0x7A, 0x77, 0x74, 0x73, 0x72, 0x74, 0x75, 0x76, -0x77, 0x74, 0x74, 0x77, 0x79, 0x79, 0x79, 0x78, 0x77, 0x74, 0x70, 0x6F, 0x70, 0x6F, 0x6E, 0x6E, -0x6E, 0x6F, 0x6F, 0x72, 0x75, 0x72, 0x74, 0x79, 0x7B, 0x7B, 0x7B, 0x7D, 0xFF, 0x7E, 0x7F, 0xFE, -0xFE, 0x7F, 0x7D, 0x7D, 0xFF, 0xFD, 0xFE, 0x7E, 0x7D, 0x7D, 0x7E, 0x7C, 0x79, 0x77, 0x75, 0x76, -0x77, 0x78, 0x78, 0x74, 0x75, 0x7A, 0x7F, 0xFB, 0xF9, 0xF9, 0xF8, 0xFD, 0x7E, 0x7B, 0x76, 0x78, -0x7B, 0x7C, 0x7E, 0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x7C, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x7D, 0x7B, -0x7B, 0x79, 0x79, 0x7A, 0x7D, 0xFF, 0x7F, 0x7F, 0xFF, 0xFD, 0xFB, 0xFD, 0xFE, 0xFE, 0xFF, 0x7D, -0x7C, 0x7F, 0xFB, 0xF7, 0xF6, 0xFC, 0x7F, 0xFF, 0xFE, 0xFB, 0xFD, 0xFE, 0xFC, 0xFD, 0xFE, 0x7C, -0x76, 0x74, 0x74, 0x79, 0x79, 0x76, 0x77, 0x79, 0x7C, 0x7D, 0x7B, 0x7B, 0x7B, 0x7E, 0xFD, 0xFB, -0xF9, 0xF9, 0xFE, 0x7C, 0x79, 0x79, 0x77, 0x76, 0x79, 0x7B, 0x7D, 0x7C, 0x7C, 0x7D, 0x7C, 0x78, -0x75, 0x74, 0x72, 0x72, 0x73, 0x71, 0x70, 0x73, 0x78, 0x7C, 0x7D, 0x7E, 0xFF, 0x7F, 0x7F, 0x7D, -0x7A, 0x78, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x7B, 0xFF, 0xFF, 0xFD, 0xFC, 0xFC, 0xFA, 0xF9, -0xF8, 0xF9, 0xFE, 0x7E, 0xFF, 0xFE, 0xFE, 0x7D, 0x7A, 0x78, 0x75, 0x75, 0x77, 0x7A, 0x7A, 0x79, -0x7B, 0x7D, 0xFF, 0xFD, 0xFC, 0xFC, 0xFB, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xFB, 0xFA, 0xF9, 0xF7, -0xF8, 0xFA, 0xF8, 0xF9, 0xFC, 0xFD, 0xFD, 0xFC, 0xF9, 0xF7, 0xF8, 0xFC, 0x7E, 0x7B, 0x7A, 0x7A, -0x79, 0x79, 0x7A, 0x7A, 0x7A, 0x77, 0x72, 0x72, 0x74, 0x76, 0x7B, 0x7C, 0x7B, 0x7D, 0x7E, 0x7D, -0x7D, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x78, 0x78, 0x79, 0x79, 0x79, 0x78, 0x79, 0x7B, 0x7C, 0x7C, -0x7A, 0x7A, 0x77, 0x75, 0x75, 0x74, 0x73, 0x70, 0x6E, 0x6E, 0x6E, 0x6F, 0x72, 0x75, 0x77, 0x7A, -0x7D, 0x7D, 0x7D, 0x7E, 0xFF, 0x7D, 0x7A, 0x7A, 0x7A, 0x7B, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7F, -0x7D, 0x7B, 0x78, 0x75, 0x73, 0x74, 0x75, 0x75, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7D, 0xFE, 0xFC, -0xF9, 0xF8, 0xF8, 0xF8, 0xF6, 0xF5, 0xF6, 0xF8, 0xFB, 0xFC, 0xFB, 0xFD, 0xFF, 0x7E, 0x7D, 0x7C, -0x7C, 0x7B, 0x7C, 0x7B, 0x79, 0x79, 0x7A, 0x79, 0x76, 0x74, 0x72, 0x72, 0x73, 0x74, 0x75, 0x77, -0x78, 0x78, 0x78, 0x77, 0x76, 0x75, 0x75, 0x78, 0x7A, 0x79, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0x7F, -0xFE, 0xFC, 0xFC, 0xFC, 0xFA, 0xF8, 0xF7, 0xF7, 0xF8, 0xF7, 0xF5, 0xF5, 0xF5, 0xF4, 0xF5, 0xF6, -0xF7, 0xF8, 0xF9, 0xFB, 0xFE, 0x7F, 0x7D, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7D, 0x7A, 0x7A, 0x7A, -0x7A, 0x79, 0x79, 0x79, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x7A, 0x7A, 0x79, 0x77, 0x76, -0x77, 0x77, 0x77, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7B, -0x78, 0x78, 0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0x7F, 0x7F, 0xFE, -0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFE, 0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, -0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x76, 0x77, 0x78, 0x77, 0x79, -0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7D, 0x7B, 0x7B, 0x7D, 0x7C, 0x7D, 0xFF, 0x7E, -0xFF, 0xFD, 0xFB, 0xF9, 0xF8, 0xF9, 0xF9, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF3, 0xF5, 0xF6, 0xF6, -0xF7, 0xF9, 0xFB, 0xFB, 0xFA, 0xFA, 0xFB, 0xFC, 0xFB, 0xFD, 0xFD, 0xFB, 0xFB, 0xFB, 0xFA, 0xF8, -0xF8, 0xF9, 0xFB, 0xFD, 0x7E, 0x7B, 0x78, 0x78, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x75, 0x75, -0x73, 0x71, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6E, 0x6E, 0x6F, 0x6F, 0x6E, 0x6E, 0x6E, 0x6D, -0x6D, 0x6E, 0x6D, 0x6D, 0x6E, 0x6F, 0x70, 0x72, 0x73, 0x74, 0x75, 0x79, 0x7C, 0x7D, 0x7E, 0xFF, -0xFF, 0xFF, 0xFD, 0xFC, 0xFA, 0xF9, 0xFB, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0x7E, 0x7B, 0x7A, -0x79, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7C, 0x7C, 0x7B, 0x79, 0x79, 0x78, 0x78, 0x79, 0x7A, 0x7C, -0x7E, 0x7E, 0x7E, 0x7C, 0x7B, 0x7A, 0x7A, 0x7A, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x7D, 0xFF, 0xFD, -0xFC, 0xFB, 0xFA, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFB, 0xFB, -0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFD, 0xFC, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, 0xF7, -0xF6, 0xF7, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0x7E, 0x7D, 0x7C, 0x7C, -0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, -0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7B, 0x78, 0x77, 0x76, 0x75, 0x75, 0x75, 0x76, 0x76, 0x75, 0x76, -0x77, 0x78, 0x78, 0x78, 0x79, 0x79, 0x7B, 0x7D, 0x7D, 0x7E, 0x7F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFE, -0xFD, 0xFB, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFF, 0x7F, 0x7E, 0x7C, 0x7C, 0x7B, -0x7A, 0x7A, 0x7A, 0x78, 0x78, 0x77, 0x77, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 0x7D, 0x7B, -0x7A, 0x7B, 0x7C, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7A, 0x7B, 0x7F, 0xFD, 0x7D, 0x79, 0xFE, -0xFA, 0xFE, 0xFC, 0xF8, 0xFC, 0xFF, 0xFF, 0xFE, 0xFB, 0xFC, 0x7F, 0xFF, 0x7F, 0x7C, 0x7D, 0x7D, -0x7E, 0x7E, 0x7B, 0x7A, 0x7A, 0x7B, 0x7C, 0x7E, 0x7E, 0x7C, 0x7B, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, -0x7D, 0x7E, 0x7F, 0x7E, 0x7F, 0xFF, 0xFE, 0xFD, 0xFE, 0xFF, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7E, -0x7D, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x7A, 0x7A, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x75, 0x74, 0x73, -0x74, 0x75, 0x74, 0x74, 0x75, 0x75, 0x75, 0x76, 0x77, 0x76, 0x77, 0x77, 0x79, 0x7B, 0x7C, 0x7D, -0x7D, 0x7D, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFE, 0xFD, 0xFE, 0xFF, 0xFE, 0xFD, 0xFB, 0xFC, 0xFD, -0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7E, -0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, -0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, -0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7F, 0x7F, 0x7E, -0x7D, 0x7C, 0x7B, 0x7B, 0x79, 0x77, 0x77, 0x78, 0x76, 0x76, 0x78, 0x7A, 0x78, 0x78, 0x78, 0x77, -0x77, 0x76, 0x75, 0x76, 0x75, 0x75, 0x77, 0x77, 0x76, 0x74, 0x74, 0x75, 0x76, 0x75, 0x76, 0x76, -0x75, 0x76, 0x76, 0x75, 0x74, 0x73, 0x74, 0x74, 0x75, 0x76, 0x76, 0x77, 0x78, 0x7A, 0x7A, 0x7B, -0x7C, 0x7B, 0x7D, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFE, 0xFD, 0xFD, 0xFD, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0xFE, -0xFE, 0xFE, 0x7F, 0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFD, 0xFD, 0xFD, -0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0xFE, 0xFC, 0xFA, 0xF9, 0xF8, 0xF8, 0xF8, 0xF9, 0xFA, -0xFD, 0xFE, 0xFC, 0xFD, 0xFE, 0xFE, 0xFF, 0x7F, 0xFF, 0x7E, 0x7D, 0x7B, 0x79, 0x79, 0x7B, 0x7C, -0x7C, 0x7D, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7B, 0x7B, 0x7A, 0x77, 0x78, 0x75, 0x75, 0x76, 0x76, -0x78, 0x75, 0x76, 0x77, 0x73, 0x75, 0x73, 0x77, 0x76, 0x73, 0x78, 0x73, 0x78, 0x77, 0x75, 0x7B, -0x70, 0x7E, 0x68, 0x5B, 0xE4, 0xD9, 0x77, 0x66, 0x5F, 0x6B, 0xEB, 0x78, 0x6B, 0xEC, 0xE9, 0x67, -0x5A, 0x62, 0xF8, 0xE2, 0xF1, 0x6B, 0x6F, 0x72, 0x6E, 0x6D, 0x72, 0xEF, 0xE7, 0xF7, 0x6D, 0x6A, -0x70, 0x7B, 0xFC, 0xF5, 0xED, 0xEF, 0x7D, 0x71, 0x70, 0xFF, 0xEE, 0xEF, 0xF8, 0xFC, 0x7B, 0x73, -0x6F, 0x71, 0x7E, 0xF2, 0xF2, 0x76, 0x67, 0x68, 0x78, 0xF7, 0xF5, 0xFC, 0x7E, 0x7B, 0x73, 0x70, -0x79, 0xF4, 0xEB, 0xEC, 0xF8, 0x7C, 0x7B, 0xFF, 0xF6, 0xEF, 0xEF, 0xF4, 0xF8, 0xFE, 0x7D, 0xFE, -0xF8, 0xF4, 0xF4, 0xF9, 0xFE, 0x7E, 0x7C, 0x7C, 0xFD, 0xF8, 0xF8, 0xFD, 0x7D, 0x7A, 0x79, 0x7C, -0xFF, 0xFD, 0xFB, 0xFC, 0x7D, 0x7B, 0x7D, 0x7F, 0xFD, 0xFD, 0xFF, 0x7E, 0x7C, 0x7A, 0x79, 0x7C, -0x7E, 0x7D, 0x7D, 0x7B, 0x78, 0x79, 0x7B, 0x7A, 0x78, 0x79, 0x77, 0x76, 0x78, 0x71, 0x70, 0x78, -0x7E, 0xF6, 0xFE, 0x67, 0x68, 0xF4, 0xEF, 0x74, 0x69, 0x6A, 0xFF, 0x7E, 0x6E, 0xF2, 0xFB, 0x69, -0x66, 0x69, 0xDD, 0xD9, 0x71, 0x7B, 0x74, 0x5F, 0x69, 0x61, 0x6A, 0xE6, 0xEC, 0x66, 0x55, 0x50, -0x5C, 0xFB, 0xED, 0xF5, 0xFA, 0x6F, 0x6E, 0x7B, 0xE8, 0xCF, 0xC7, 0xC6, 0xCA, 0xCB, 0xDB, 0x3A, -0x2E, 0x49, 0xBD, 0xB7, 0xC6, 0x4D, 0x41, 0x4B, 0x49, 0x4D, 0xD9, 0xBF, 0xC2, 0xFD, 0x3F, 0x3D, -0x51, 0xDF, 0xCD, 0xCC, 0xD5, 0xF4, 0x50, 0x46, 0x4D, 0xF0, 0xCB, 0xCA, 0xDA, 0x61, 0x51, 0x52, -0x5B, 0xE6, 0xD0, 0xCE, 0xDC, 0x5D, 0x53, 0x51, 0x6A, 0xF9, 0x48, 0x67, 0xC2, 0xE0, 0x5F, 0x5B, -0x4C, 0x71, 0xFA, 0x6E, 0xCE, 0xCF, 0x7A, 0x64, 0x79, 0xD8, 0xCE, 0xD1, 0xCD, 0xC3, 0xC5, 0xCD, -0xC7, 0xDC, 0x42, 0x3E, 0x53, 0xD2, 0xC0, 0xDE, 0x44, 0x48, 0x58, 0x53, 0x59, 0xFA, 0xD9, 0xD6, -0x5E, 0x43, 0x47, 0x61, 0xE1, 0xD8, 0xEA, 0x64, 0x46, 0x3C, 0x51, 0x7F, 0x77, 0xD0, 0xF6, 0x4B, -0x4B, 0x4A, 0x6F, 0xCA, 0xC6, 0xC9, 0xC7, 0xC2, 0xC8, 0xBD, 0xB0, 0xAB, 0xBB, 0x1F, 0x19, 0x5F, -0xA3, 0xA5, 0xBA, 0x30, 0x30, 0x47, 0x31, 0x37, 0xBC, 0xAB, 0xB8, 0x3D, 0x2B, 0x30, 0x4E, 0xBD, -0xB4, 0xC4, 0x5D, 0x3F, 0x38, 0x41, 0x6E, 0xC8, 0xC1, 0xDC, 0x4B, 0x3B, 0x3F, 0xE5, 0xBF, 0xBC, -0xC8, 0xE5, 0xDE, 0xC0, 0xAE, 0xAD, 0xAF, 0xC1, 0x20, 0x1A, 0x63, 0xA8, 0xA7, 0xB5, 0x36, 0x2E, -0x3D, 0x32, 0x3F, 0xBD, 0xB1, 0xC1, 0x39, 0x2E, 0x42, 0xE8, 0xCA, 0xC3, 0xDB, 0x5F, 0x47, 0x39, -0x47, 0xD5, 0xCB, 0xD1, 0x70, 0x4B, 0x4D, 0xF0, 0xC1, 0xB3, 0xAE, 0xB4, 0xBE, 0xB8, 0xB8, 0x34, -0x1C, 0x27, 0xB6, 0xA3, 0xAC, 0x4F, 0x2C, 0x32, 0x3B, 0x3E, 0xEB, 0xB9, 0xBB, 0x45, 0x2E, 0x39, -0x60, 0xC3, 0xBB, 0xD8, 0x4D, 0x45, 0x41, 0x57, 0xD6, 0xDE, 0x79, 0x5D, 0x50, 0x5B, 0xDB, 0xBE, -0xB4, 0xB3, 0xBC, 0xC4, 0xB6, 0xAC, 0xC2, 0x26, 0x1A, 0x30, 0xAB, 0xA9, 0xBB, 0x61, 0x33, 0x30, -0x36, 0x39, 0xCF, 0xB9, 0x64, 0x41, 0x42, 0x3E, 0x5E, 0xD3, 0xCF, 0xC4, 0xEC, 0x47, 0x56, 0x5C, -0x50, 0x57, 0x62, 0xDF, 0xD2, 0xD3, 0xC4, 0xB6, 0xB3, 0xBA, 0xB8, 0xAD, 0xAF, 0x3C, 0x1C, 0x1E, -0xCB, 0xA1, 0xA9, 0xFE, 0x2D, 0x2C, 0x39, 0x3D, 0x64, 0xBE, 0xD5, 0x4B, 0x42, 0x3A, 0x40, 0xEC, -0xC4, 0xBE, 0xD1, 0x4A, 0x3E, 0x47, 0x62, 0xE4, 0xD7, 0xD6, 0xDC, 0xDE, 0xCD, 0xB6, 0xAD, 0xAE, -0xAC, 0xAD, 0xE6, 0x22, 0x19, 0x2E, 0xA6, 0x9E, 0xB2, 0x39, 0x28, 0x2D, 0x39, 0x4E, 0xC2, 0xBE, -0x5B, 0x3E, 0x3B, 0x3C, 0x58, 0xC6, 0xBD, 0xC7, 0x60, 0x3F, 0x3F, 0x51, 0xED, 0xCF, 0xC8, 0xD1, -0xE0, 0xD9, 0xBC, 0xAC, 0xAB, 0xAB, 0xA9, 0xC2, 0x25, 0x17, 0x22, 0xAE, 0x9D, 0xA9, 0x47, 0x26, -0x29, 0x34, 0x47, 0xC5, 0xBB, 0x77, 0x3F, 0x3A, 0x38, 0x4E, 0xC6, 0xBC, 0xBE, 0xE6, 0x3D, 0x39, -0x43, 0x67, 0xCE, 0xC7, 0xD6, 0xED, 0xD9, 0xBD, 0xAB, 0xAB, 0xAE, 0xA9, 0xB4, 0x30, 0x1A, 0x1B, -0xD5, 0x9D, 0xA3, 0xDA, 0x2A, 0x26, 0x31, 0x3C, 0x6C, 0xBF, 0xCE, 0x5E, 0x42, 0x32, 0x3C, 0xD6, -0xBC, 0xB8, 0xCC, 0x3F, 0x37, 0x3B, 0x51, 0xCC, 0xC1, 0xCC, 0xE2, 0xDE, 0xBD, 0xAC, 0xAA, 0xA9, -0xA7, 0xC5, 0x26, 0x18, 0x1F, 0xB7, 0x9D, 0xA6, 0xDF, 0x2B, 0x26, 0x2D, 0x37, 0xEB, 0xBA, 0xCB, -0x5E, 0x3C, 0x30, 0x44, 0xC9, 0xBB, 0xB8, 0xCF, 0x3D, 0x34, 0x3B, 0x5F, 0xC1, 0xBE, 0xCE, 0xD6, -0xCE, 0xB8, 0xAB, 0xAA, 0xA4, 0xA8, 0x42, 0x1C, 0x18, 0x31, 0xA4, 0x9F, 0xAF, 0x48, 0x29, 0x28, -0x2C, 0x37, 0xCC, 0xBA, 0xC7, 0x57, 0x30, 0x31, 0x5A, 0xC6, 0xB6, 0xB7, 0x5F, 0x38, 0x34, 0x3D, -0xE2, 0xBD, 0xBD, 0xC7, 0xD2, 0xCA, 0xB2, 0xAB, 0xA7, 0xA2, 0xB3, 0x29, 0x18, 0x1C, 0xD2, 0x9F, -0xA5, 0xBC, 0x3A, 0x2A, 0x29, 0x2A, 0x3E, 0xC3, 0xBB, 0xC1, 0x43, 0x2D, 0x3A, 0xF5, 0xC1, 0xB5, -0xBE, 0x4F, 0x36, 0x32, 0x3F, 0xD2, 0xBB, 0xBA, 0xBE, 0xC5, 0xBF, 0xB1, 0xAB, 0xA4, 0xA7, 0x75, -0x1F, 0x18, 0x27, 0xAE, 0xA2, 0xAD, 0xD6, 0x36, 0x2B, 0x28, 0x2C, 0x4E, 0xC2, 0xB8, 0xC9, 0x35, -0x2F, 0x42, 0x71, 0xBA, 0xB4, 0xD2, 0x44, 0x34, 0x34, 0x4C, 0xCD, 0xBE, 0xBB, 0xB9, 0xBC, 0xB3, -0xAE, 0xAB, 0xA3, 0xB0, 0x2C, 0x1A, 0x1C, 0x5F, 0xA4, 0xA9, 0xBA, 0x6F, 0x34, 0x28, 0x26, 0x32, -0x77, 0xB9, 0xB3, 0x5E, 0x32, 0x38, 0x40, 0xD8, 0xB6, 0xBE, 0xF4, 0x40, 0x34, 0x3A, 0x5B, 0xC7, -0xB7, 0xB4, 0xB7, 0xB4, 0xB2, 0xAE, 0xA5, 0xAB, 0x3B, 0x1D, 0x1B, 0x34, 0xAE, 0xAA, 0xB4, 0xC7, -0x42, 0x2C, 0x25, 0x2B, 0x43, 0xCF, 0xB5, 0xBE, 0x3F, 0x38, 0x3D, 0x4D, 0xC4, 0xBD, 0xCF, 0x5D, -0x3E, 0x38, 0x43, 0xE4, 0xBF, 0xB4, 0xAF, 0xB0, 0xAF, 0xAE, 0xA8, 0xA7, 0xF6, 0x21, 0x1A, 0x27, -0xBA, 0xAC, 0xB5, 0xB9, 0xE2, 0x36, 0x26, 0x25, 0x33, 0x4E, 0xBA, 0xB2, 0x64, 0x41, 0x3F, 0x3D, -0xE6, 0xC6, 0xCD, 0xD4, 0x50, 0x3D, 0x3C, 0x48, 0xD4, 0xB9, 0xAF, 0xAD, 0xAE, 0xAE, 0xAA, 0xA7, -0xC0, 0x2A, 0x1B, 0x1F, 0x65, 0xAF, 0xB5, 0xB5, 0xBF, 0x4C, 0x2C, 0x23, 0x2A, 0x37, 0xE6, 0xAF, -0xBC, 0x5B, 0x4B, 0x3B, 0x49, 0xCF, 0xCE, 0xD0, 0xDE, 0x4F, 0x40, 0x3F, 0x57, 0xC7, 0xB3, 0xAA, -0xA9, 0xAC, 0xAE, 0xA9, 0xAE, 0x3B, 0x1E, 0x1E, 0x37, 0xBA, 0xB7, 0xB7, 0xB5, 0xC9, 0x3A, 0x26, -0x27, 0x2E, 0x37, 0xC1, 0xB1, 0xCA, 0xE8, 0x49, 0x3E, 0x62, 0x78, 0xEF, 0xD7, 0x69, 0x4F, 0x44, -0x48, 0xFB, 0xC5, 0xAF, 0xA9, 0xA8, 0xAA, 0xAB, 0xAA, 0xCF, 0x26, 0x1C, 0x22, 0x4A, 0xBD, 0xBB, -0xAF, 0xB1, 0xD7, 0x31, 0x25, 0x27, 0x28, 0x38, 0xB9, 0xB6, 0xC3, 0xCB, 0x4B, 0x45, 0x4E, 0x47, -0x62, 0xE0, 0xF9, 0x5C, 0x4C, 0x5C, 0xE4, 0xBF, 0xAD, 0xA8, 0xA5, 0xA7, 0xA9, 0xB2, 0x36, 0x20, -0x1E, 0x29, 0x56, 0xCC, 0xB8, 0xAC, 0xB5, 0xFA, 0x2F, 0x28, 0x25, 0x25, 0x45, 0xBE, 0xBF, 0xB8, -0xC5, 0x5F, 0x54, 0x41, 0x43, 0x4F, 0x56, 0x75, 0x70, 0xFE, 0xE2, 0xD3, 0xB9, 0xAD, 0xA8, 0xA6, -0xA6, 0xA8, 0xCA, 0x2D, 0x22, 0x21, 0x2E, 0x47, 0x77, 0xB4, 0xAD, 0xB7, 0xDC, 0x39, 0x2D, 0x24, -0x28, 0x40, 0x5A, 0xC7, 0xB5, 0xBD, 0xC0, 0xDB, 0x4E, 0x4C, 0x40, 0x44, 0x4E, 0x56, 0xDA, 0xCC, -0xC0, 0xB1, 0xAC, 0xA7, 0xA5, 0xA6, 0xAD, 0x4F, 0x2A, 0x23, 0x25, 0x2F, 0x39, 0x6C, 0xB6, 0xB1, -0xB7, 0xD6, 0x43, 0x2F, 0x26, 0x2C, 0x35, 0x3A, 0xDF, 0xC7, 0xBE, 0xBA, 0xCB, 0xD4, 0x6E, 0x48, -0x44, 0x3E, 0x4A, 0x6C, 0xD6, 0xB9, 0xB0, 0xA8, 0xA4, 0xA5, 0xA4, 0xB5, 0x42, 0x2C, 0x23, 0x27, -0x2B, 0x2E, 0x55, 0xC2, 0xB9, 0xB6, 0xC5, 0xF4, 0x3C, 0x32, 0x34, 0x2F, 0x37, 0x4A, 0x5B, 0xCF, -0xC9, 0xC6, 0xC0, 0xCA, 0xCF, 0xF4, 0x52, 0x51, 0x4E, 0xF8, 0xC4, 0xB7, 0xAD, 0xA9, 0xA6, 0xA7, -0xB8, 0x5D, 0x38, 0x2F, 0x2E, 0x2B, 0x2C, 0x35, 0x42, 0x5D, 0x7D, 0xE3, 0xDF, 0x6F, 0x73, 0x5A, -0x4D, 0x55, 0x4F, 0x4F, 0x58, 0x5C, 0x6E, 0xFA, 0xE2, 0xD4, 0xD4, 0xD6, 0xD9, 0xD6, 0xCC, 0xC6, -0xBF, 0xBB, 0xB8, 0xB6, 0xBC, 0xC9, 0xDC, 0x60, 0x59, 0x53, 0x4A, 0x49, 0x46, 0x45, 0x46, 0x43, -0x45, 0x45, 0x49, 0x56, 0x5A, 0x5D, 0x6E, 0x72, 0x7C, 0x74, 0x6D, 0x7A, 0x7A, 0xFC, 0xED, 0xE8, -0xEB, 0xFF, 0xFD, 0xEC, 0xDE, 0xD2, 0xCC, 0xC7, 0xC5, 0xCA, 0xD2, 0xD9, 0xDB, 0xD4, 0xCF, 0xD1, -0xD9, 0xE7, 0xFC, 0x6E, 0x60, 0x57, 0x50, 0x4C, 0x49, 0x47, 0x46, 0x45, 0x47, 0x4A, 0x4D, 0x4F, -0x4F, 0x53, 0x5A, 0x5F, 0x62, 0x60, 0x62, 0x6B, 0x77, 0xEC, 0xD8, 0xCC, 0xC7, 0xC7, 0xCB, 0xCF, -0xD3, 0xD3, 0xCE, 0xCB, 0xCA, 0xCC, 0xCF, 0xD4, 0xD9, 0xDF, 0xEB, 0xFE, 0x6A, 0x58, 0x4D, 0x46, -0x43, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x52, 0x54, 0x55, 0x54, 0x57, 0x5C, 0x61, 0x72, 0xE5, -0xD4, 0xCC, 0xCB, 0xCD, 0xD0, 0xD4, 0xD3, 0xD1, 0xD0, 0xCF, 0xD1, 0xD2, 0xD4, 0xD6, 0xD9, 0xDB, -0xDB, 0xDD, 0xEC, 0x6B, 0x59, 0x53, 0x54, 0x57, 0x59, 0x58, 0x57, 0x5A, 0x5C, 0x5A, 0x55, 0x52, -0x52, 0x51, 0x51, 0x57, 0x61, 0xFC, 0xE3, 0xDF, 0xE0, 0xE4, 0xE3, 0xE0, 0xDF, 0xDE, 0xDD, 0xDE, -0xDD, 0xDF, 0xE0, 0xDF, 0xDC, 0xD9, 0xDC, 0xE7, 0x7E, 0x6B, 0x6D, 0x7C, 0xEE, 0xE6, 0xE7, 0xEA, -0xEC, 0xF5, 0x7A, 0x6A, 0x61, 0x5A, 0x51, 0x4F, 0x50, 0x55, 0x5D, 0x62, 0x63, 0x60, 0x5F, 0x61, -0x65, 0x68, 0x6D, 0x75, 0xFA, 0xF1, 0xF1, 0xEE, 0xE6, 0xDD, 0xDB, 0xDE, 0xEB, 0x79, 0x6B, 0x6F, -0xF7, 0xE2, 0xDC, 0xDB, 0xDA, 0xDA, 0xDC, 0xDD, 0xDE, 0xE0, 0xF1, 0x6B, 0x5F, 0x5F, 0x66, 0x6B, -0x6A, 0x65, 0x5E, 0x5B, 0x5A, 0x59, 0x5A, 0x5C, 0x5E, 0x5E, 0x5E, 0x5E, 0x68, 0xFC, 0xE8, 0xE5, -0xEB, 0xFB, 0x71, 0x6D, 0x78, 0xEE, 0xE2, 0xDE, 0xDD, 0xDC, 0xDE, 0xDF, 0xDC, 0xD9, 0xD9, 0xE0, -0xED, 0xF0, 0xEC, 0xE4, 0xE2, 0xE6, 0xEE, 0x7C, 0x6D, 0x65, 0x5E, 0x5E, 0x62, 0x64, 0x61, 0x5C, -0x5B, 0x5F, 0x70, 0xF7, 0xF8, 0x78, 0x6B, 0x65, 0x61, 0x69, 0xFA, 0xE9, 0xE5, 0xE2, 0xE5, 0xEA, -0xED, 0xEB, 0xE5, 0xE5, 0xED, 0xF9, 0xFC, 0xEF, 0xE3, 0xDE, 0xDE, 0xE1, 0xE9, 0xF4, 0x74, 0x6A, -0x6B, 0x6F, 0x6F, 0x67, 0x5E, 0x5C, 0x5F, 0x6A, 0x6F, 0x6C, 0x66, 0x5F, 0x5D, 0x5E, 0x64, 0x6F, -0xFE, 0xEF, 0xEC, 0xF2, 0xFD, 0x7E, 0xFB, 0xF6, 0xFF, 0x6F, 0x6A, 0x6A, 0x74, 0xF4, 0xE9, 0xE4, -0xE7, 0xEE, 0x7D, 0x6A, 0x69, 0x6F, 0xFE, 0xF7, 0x7B, 0x6B, 0x68, 0x6E, 0x79, 0x78, 0x6F, 0x69, -0x62, 0x5F, 0x60, 0x66, 0x72, 0xF6, 0xEB, 0xEC, 0xF3, 0xFC, 0xFA, 0xF2, 0xF2, 0xFE, 0x70, 0x69, -0x69, 0x71, 0xF7, 0xE8, 0xE3, 0xE4, 0xED, 0x76, 0x69, 0x6A, 0x6F, 0x7E, 0xFB, 0x7D, 0x75, 0x73, -0x7C, 0xFB, 0xFC, 0x7D, 0x73, 0x6D, 0x6A, 0x69, 0x6F, 0xFD, 0xEC, 0xE8, 0xED, 0xF6, 0xF7, 0xF1, -0xED, 0xEF, 0xF6, 0x7E, 0x76, 0x78, 0xFB, 0xEC, 0xE2, 0xDE, 0xE0, 0xEB, 0xFE, 0x73, 0x73, 0x7E, -0xFA, 0xFC, 0xFF, 0x7B, 0x7D, 0xFC, 0xFE, 0x7B, 0x74, 0x6F, 0x6D, 0x6C, 0x6E, 0x77, 0xFA, 0xEE, -0xED, 0xF6, 0x7A, 0x73, 0x77, 0x7B, 0x7C, 0x78, 0x6E, 0x6B, 0x6F, 0x7C, 0xEF, 0xE7, 0xE2, 0xE6, -0xF2, 0x7A, 0x71, 0x75, 0x7D, 0xFE, 0xFD, 0xFD, 0xFB, 0xF5, 0xF7, 0xFE, 0x77, 0x6E, 0x6A, 0x67, -0x67, 0x6C, 0x76, 0xF7, 0xEE, 0xEF, 0xFA, 0x7B, 0x78, 0x7B, 0xFF, 0x7F, 0x78, 0x6F, 0x6C, 0x6C, -0x72, 0xFE, 0xEF, 0xEC, 0xEF, 0xFD, 0x76, 0x70, 0x71, 0x75, 0x7A, 0x7E, 0x7E, 0xFF, 0xFC, 0xFD, -0x7C, 0x73, 0x6D, 0x69, 0x65, 0x63, 0x65, 0x6B, 0x79, 0xFB, 0xFD, 0x78, 0x70, 0x70, 0x74, 0x79, -0x7C, 0x7B, 0x79, 0x77, 0x78, 0x7F, 0xF4, 0xED, 0xED, 0xF2, 0xFB, 0x7A, 0x74, 0x74, 0x76, 0x7A, -0x7F, 0xFB, 0xF5, 0xF4, 0xF6, 0xFA, 0x7D, 0x75, 0x6E, 0x6B, 0x6B, 0x6F, 0x7D, 0xF3, 0xEF, 0xF4, -0x7E, 0x78, 0x7A, 0xFF, 0xFA, 0xF7, 0xF5, 0xF4, 0xF4, 0xF1, 0xED, 0xE9, 0xE6, 0xE8, 0xEE, 0xF8, -0x7F, 0x7C, 0x7A, 0x7A, 0x7B, 0x7D, 0xFD, 0xF8, 0xF8, 0xF9, 0xFC, 0x7D, 0x74, 0x6C, 0x69, 0x69, -0x6C, 0x76, 0xFA, 0xF6, 0xFD, 0x78, 0x71, 0x6F, 0x6F, 0x6F, 0x71, 0x74, 0x77, 0x7C, 0xFD, 0xF5, -0xEC, 0xE9, 0xEA, 0xEF, 0xFB, 0x7A, 0x74, 0x73, 0x73, 0x73, 0x73, 0x78, 0x7E, 0xFE, 0xFD, 0xFE, -0x7B, 0x74, 0x6D, 0x68, 0x66, 0x69, 0x6F, 0x7B, 0x7F, 0x7C, 0x77, 0x73, 0x72, 0x6F, 0x6D, 0x6D, -0x6D, 0x6D, 0x6E, 0x72, 0x7A, 0xFA, 0xF1, 0xEE, 0xEF, 0xF6, 0xFD, 0x7D, 0x7B, 0x7A, 0x78, 0x78, -0x79, 0x79, 0x7A, 0x7C, 0x7D, 0x7E, 0x7D, 0x77, 0x70, 0x6E, 0x71, 0x79, 0x7E, 0x7E, 0x7E, 0x7D, -0x7E, 0x7D, 0x7C, 0x7A, 0x78, 0x76, 0x74, 0x73, 0x75, 0x7A, 0xFC, 0xF6, 0xF4, 0xF4, 0xF6, 0xF6, -0xF6, 0xF9, 0xF9, 0xF7, 0xF5, 0xF3, 0xF1, 0xF1, 0xF3, 0xF5, 0xF7, 0xFA, 0x7B, 0x6F, 0x6D, 0x6D, -0x6F, 0x6F, 0x6E, 0x6E, 0x70, 0x70, 0x71, 0x74, 0x78, 0x7C, 0x7D, 0x7E, 0x7D, 0xFF, 0xFB, 0xF7, -0xF4, 0xF4, 0xF6, 0xF8, 0xFB, 0xFD, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x7F, 0xFF, 0xFC, 0xF8, -0xF9, 0xFD, 0x7D, 0x7C, 0x7F, 0xFE, 0x7E, 0x7C, 0x7A, 0x79, 0x77, 0x75, 0x75, 0x76, 0x79, 0x76, -0x71, 0x6F, 0x6F, 0x71, 0x76, 0x78, 0x78, 0x78, 0x7B, 0x7D, 0x7A, 0x77, 0x76, 0x76, 0x78, 0x79, -0x78, 0x79, 0x7C, 0xFD, 0xF4, 0xF1, 0xF2, 0xF5, 0xF9, 0xFB, 0x7F, 0x79, 0x76, 0x76, 0x78, 0x77, -0x77, 0x7B, 0xFF, 0xFA, 0xF6, 0xF6, 0xF7, 0xF6, 0xF6, 0xF7, 0xF9, 0xFA, 0xF9, 0xF6, 0xF6, 0xF9, -0xFB, 0xFE, 0x7F, 0x7E, 0x7C, 0x79, 0x7A, 0xFE, 0xF5, 0xEF, 0xEE, 0xEF, 0xF1, 0xF3, 0xF4, 0xFB, -0x79, 0x73, 0x72, 0x6E, 0x6B, 0x68, 0x68, 0x6C, 0x73, 0x7A, 0x7C, 0x7B, 0x7B, 0x7D, 0x7D, 0xFD, -0xF6, 0xF0, 0xEE, 0xEF, 0xF6, 0xFB, 0xFF, 0x7D, 0x7F, 0x7D, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, 0x7B, -0x7A, 0xFF, 0xFD, 0xFF, 0x7E, 0x7A, 0x75, 0x74, 0x71, 0x6F, 0x6F, 0x70, 0x77, 0x7A, 0x78, 0x75, -0x72, 0x75, 0x73, 0x6F, 0x6F, 0x70, 0x75, 0x77, 0x76, 0x78, 0x75, 0x78, 0x7B, 0x7B, 0x7F, 0x7B, -0x7E, 0x7F, 0x7E, 0x7E, 0x77, 0x79, 0x73, 0x71, 0x71, 0x6B, 0x6F, 0x60, 0x5B, 0x6F, 0x72, 0x69, -0x71, 0x72, 0x7E, 0xFC, 0xF7, 0xEE, 0xF4, 0xFB, 0x7E, 0x7E, 0xFC, 0xF9, 0xFD, 0x7F, 0xFC, 0x72, -0x78, 0x64, 0x53, 0x71, 0xDF, 0xF0, 0xEB, 0xE9, 0xF0, 0x7C, 0x7B, 0xEA, 0xF6, 0x7E, 0x79, 0x6C, -0x79, 0x5F, 0x5B, 0xEC, 0xE2, 0xEF, 0xED, 0xF1, 0xF7, 0xFE, 0x7C, 0xFE, 0x75, 0x6E, 0x75, 0x79, -0x7A, 0x72, 0x6E, 0x75, 0x7A, 0x7B, 0x77, 0x77, 0xFE, 0xF8, 0xF6, 0xF5, 0xEB, 0xE9, 0xEC, 0xE8, -0xEE, 0xEC, 0xED, 0x77, 0xFD, 0x61, 0x51, 0x66, 0xE7, 0xDC, 0xD8, 0xD3, 0xD3, 0x6C, 0x52, 0x63, -0x6F, 0x73, 0x7F, 0xFB, 0xF4, 0x79, 0x7B, 0xF1, 0xED, 0xEC, 0xFA, 0x76, 0x7A, 0x74, 0x6B, 0x6B, -0x75, 0x7C, 0x7C, 0x79, 0xFE, 0xF6, 0xFE, 0x7A, 0x71, 0x75, 0xFF, 0x70, 0x6D, 0x6E, 0x69, 0x66, -0x5E, 0x62, 0xFA, 0xEA, 0xE5, 0xE0, 0xE1, 0xE5, 0xEE, 0xF1, 0xE5, 0xE4, 0xEA, 0xE8, 0xE7, 0xE7, -0xE3, 0xE7, 0xE8, 0xE8, 0xEF, 0xF7, 0x78, 0x6E, 0x6D, 0x60, 0x5A, 0x57, 0x54, 0x53, 0x51, 0x50, -0x52, 0x54, 0x57, 0x59, 0x5D, 0x67, 0x70, 0x7B, 0xF5, 0xE5, 0xDA, 0xD5, 0xD2, 0xCD, 0xC4, 0xBE, -0xBB, 0xB7, 0xB5, 0xBB, 0xCB, 0xDE, 0xE9, 0x56, 0x3F, 0x3A, 0x39, 0x3B, 0x3B, 0x3A, 0x3F, 0x4E, -0x5D, 0x69, 0xF2, 0xDD, 0xD9, 0xE2, 0xF3, 0xF4, 0x72, 0x5C, 0x53, 0x4E, 0x4D, 0x4E, 0x4E, 0x4F, -0x58, 0x7E, 0xDA, 0xCB, 0xBF, 0xBA, 0xB7, 0xB4, 0xB0, 0xAE, 0xB2, 0xBE, 0xD7, 0x70, 0x4E, 0x3B, -0x32, 0x30, 0x33, 0x35, 0x35, 0x3A, 0x49, 0x5F, 0x7E, 0xEF, 0xE1, 0xD2, 0xD1, 0xE6, 0xEF, 0xF7, -0x5F, 0x4F, 0x48, 0x48, 0x4B, 0x48, 0x4B, 0x55, 0x72, 0xE1, 0xD2, 0xC2, 0xBA, 0xB6, 0xB3, 0xB0, -0xAD, 0xAE, 0xBA, 0xD0, 0x64, 0x4C, 0x3C, 0x30, 0x2E, 0x2F, 0x33, 0x35, 0x3A, 0x47, 0x6C, 0xE6, -0xEB, 0xD0, 0xC6, 0xCC, 0xD6, 0xE3, 0xEF, 0x69, 0x4E, 0x4B, 0x4B, 0x47, 0x46, 0x48, 0x4F, 0x61, -0xFE, 0xD1, 0xBE, 0xB8, 0xB5, 0xB2, 0xAF, 0xAD, 0xAE, 0xBA, 0xCD, 0x5F, 0x47, 0x3B, 0x2F, 0x2D, -0x2E, 0x30, 0x35, 0x3B, 0x47, 0x6C, 0xF4, 0xE2, 0xCB, 0xC7, 0xCD, 0xD7, 0xDD, 0xE3, 0x6E, 0x4E, -0x4A, 0x4B, 0x48, 0x47, 0x4A, 0x5B, 0xE4, 0xD3, 0xC0, 0xB7, 0xB3, 0xB0, 0xAF, 0xAC, 0xAC, 0xB3, -0xC4, 0x7D, 0x4C, 0x3E, 0x30, 0x2C, 0x2E, 0x31, 0x35, 0x3A, 0x45, 0x62, 0xFA, 0xEB, 0xCE, 0xCA, -0xD2, 0xDA, 0xE7, 0xE9, 0x6D, 0x4C, 0x49, 0x49, 0x47, 0x48, 0x4C, 0x68, 0xD7, 0xCA, 0xBC, 0xB5, -0xB2, 0xB0, 0xAE, 0xAC, 0xAE, 0xB9, 0xCE, 0x5D, 0x45, 0x39, 0x2F, 0x2D, 0x2E, 0x31, 0x36, 0x3B, -0x47, 0x5C, 0x6E, 0xE4, 0xD3, 0xD3, 0xD4, 0xDA, 0xDE, 0xEB, 0x5B, 0x4D, 0x4A, 0x47, 0x48, 0x49, -0x54, 0xEB, 0xCE, 0xBE, 0xB8, 0xB7, 0xB3, 0xB3, 0xB5, 0xB3, 0xBB, 0xC9, 0xC8, 0xED, 0x47, 0x42, -0x3A, 0x36, 0x37, 0x34, 0x39, 0x3E, 0x3F, 0x47, 0x4E, 0x65, 0xDE, 0xEC, 0xDC, 0xCE, 0xD9, 0xEB, -0x5F, 0x54, 0x51, 0x47, 0x46, 0x4C, 0x58, 0xFC, 0xD8, 0xC4, 0xBB, 0xBA, 0xB8, 0xB5, 0xB2, 0xAF, -0xB0, 0xB6, 0xBD, 0xCC, 0x66, 0x47, 0x3B, 0x34, 0x32, 0x32, 0x34, 0x38, 0x3B, 0x3F, 0x4B, 0x58, -0x69, 0xE9, 0xD9, 0xD4, 0xDB, 0x77, 0x5C, 0x59, 0x4F, 0x4A, 0x4B, 0x51, 0x69, 0xE0, 0xCE, 0xC2, -0xBD, 0xBC, 0xBA, 0xB8, 0xB7, 0xB4, 0xB2, 0xB7, 0xC3, 0xCE, 0xD4, 0x67, 0x44, 0x3D, 0x3C, 0x3B, -0x38, 0x38, 0x3B, 0x3F, 0x42, 0x46, 0x4E, 0x5F, 0x6A, 0x6B, 0xFD, 0xF7, 0x70, 0x5C, 0x54, 0x58, -0x58, 0x53, 0x5B, 0x73, 0xE5, 0xD2, 0xCA, 0xC6, 0xC2, 0xBF, 0xBE, 0xBE, 0xBD, 0xBB, 0xBC, 0xC3, -0xCA, 0xD0, 0xE2, 0x5F, 0x4E, 0x4A, 0x44, 0x3E, 0x3D, 0x3D, 0x3F, 0x42, 0x44, 0x4B, 0x55, 0x57, -0x5F, 0x69, 0x68, 0x63, 0x58, 0x56, 0x5B, 0x56, 0x57, 0x66, 0x79, 0xE8, 0xD9, 0xCF, 0xCB, 0xCB, -0xC8, 0xC4, 0xC5, 0xC6, 0xC9, 0xC9, 0xC6, 0xCD, 0xD4, 0xD8, 0xE2, 0xF1, 0x66, 0x5C, 0x57, 0x4C, -0x49, 0x49, 0x48, 0x49, 0x49, 0x4B, 0x51, 0x51, 0x4F, 0x53, 0x56, 0x58, 0x58, 0x54, 0x58, 0x5F, -0x5E, 0x5B, 0x63, 0xF2, 0xE5, 0xE5, 0xD7, 0xCF, 0xD2, 0xD6, 0xD1, 0xCF, 0xD6, 0xD6, 0xD2, 0xCF, -0xCE, 0xD0, 0xD8, 0xDB, 0xDB, 0xE5, 0x6D, 0x67, 0x65, 0x5C, 0x58, 0x54, 0x59, 0x5D, 0x57, 0x57, -0x5B, 0x5B, 0x59, 0x56, 0x57, 0x5A, 0x56, 0x52, 0x5A, 0x5C, 0x5D, 0x7D, 0xF1, 0xF3, 0xE7, 0xE3, -0xDF, 0xDB, 0xDA, 0xE7, 0xEC, 0xDE, 0xE5, 0xE9, 0xE6, 0xE4, 0xD6, 0xDF, 0xF8, 0xDE, 0xE9, 0x7C, -0xEE, 0xFB, 0x7A, 0x6B, 0x65, 0xFF, 0x79, 0x69, 0x6B, 0x63, 0x65, 0x62, 0x56, 0x5A, 0x60, 0x55, -0x58, 0x62, 0x5E, 0x64, 0x79, 0x7C, 0x78, 0xED, 0xE1, 0xEC, 0xF0, 0xE4, 0xF0, 0x6E, 0x7C, 0xED, -0xDD, 0xDB, 0xFE, 0x73, 0xED, 0xF0, 0xFF, 0xF9, 0xDE, 0xDC, 0x76, 0x6E, 0xFB, 0x7B, 0xFB, 0x6F, -0x6F, 0xEF, 0x7B, 0x6E, 0xF8, 0xE9, 0x7E, 0x5B, 0x5F, 0xF3, 0xFD, 0x67, 0x74, 0xEA, 0xEF, 0x77, -0x6D, 0x7C, 0xE8, 0xE2, 0xEE, 0xFB, 0xE6, 0xED, 0x66, 0x6C, 0x7B, 0x7C, 0xF4, 0xEF, 0xE2, 0xE6, -0x72, 0x70, 0xF0, 0xEE, 0x6E, 0x6B, 0xFB, 0xF5, 0xF6, 0x71, 0x6A, 0x6C, 0x65, 0x67, 0x5F, 0x5D, -0x6B, 0x62, 0x65, 0xFD, 0xED, 0xE9, 0xF2, 0xED, 0xE3, 0xE7, 0xE4, 0xE8, 0xED, 0xEF, 0x66, 0x5E, -0x79, 0x7E, 0x78, 0xF5, 0xFA, 0x79, 0x7A, 0xF5, 0xE7, 0xE2, 0xE4, 0xF2, 0xFF, 0x73, 0x66, 0x6B, -0x70, 0xFD, 0xEF, 0x6F, 0x67, 0x5F, 0x5C, 0x6B, 0x6E, 0x78, 0x77, 0x6D, 0xF1, 0xF4, 0xF8, 0xE5, -0xE9, 0xEB, 0xEC, 0xEF, 0xEF, 0xF0, 0xE7, 0xED, 0x6B, 0x6F, 0xF0, 0xFF, 0x6A, 0x6F, 0x7E, 0x6F, -0x69, 0xED, 0xDF, 0xFF, 0x7C, 0xEB, 0xF3, 0xF8, 0x7E, 0x7A, 0xFB, 0x6E, 0x5E, 0x60, 0x70, 0x7A, -0xFC, 0xF4, 0xFF, 0xEF, 0xF5, 0x72, 0xF1, 0xEC, 0xEA, 0xE1, 0xE9, 0xED, 0xF2, 0xFC, 0xE7, 0xF0, -0x68, 0x76, 0xEF, 0xF4, 0xF9, 0x77, 0x79, 0xFB, 0xFC, 0xF6, 0xEE, 0xE9, 0xF2, 0x6D, 0x70, 0x6F, -0x6F, 0xFE, 0x6A, 0x69, 0x7F, 0x6F, 0x6F, 0x79, 0x78, 0x77, 0x6E, 0xFE, 0xEE, 0xF0, 0xEF, 0x7E, -0xF4, 0xE9, 0xF8, 0xFD, 0x7C, 0x77, 0x7D, 0x78, 0x7D, 0xFE, 0x79, 0x72, 0x6E, 0x72, 0x7B, 0x73, -0x6B, 0x74, 0x76, 0x6C, 0x72, 0x70, 0x75, 0x6D, 0x5A, 0x5C, 0x6A, 0x77, 0xFE, 0x71, 0x7A, 0xF2, -0xE9, 0xE7, 0xEA, 0xDE, 0xE6, 0xF5, 0xEB, 0xF5, 0xEE, 0xEA, 0xF3, 0xEE, 0xF4, 0xEE, 0xF5, 0x73, -0xF4, 0xF6, 0x73, 0x7C, 0xEC, 0xE9, 0x72, 0x67, 0x6C, 0x70, 0x6E, 0x69, 0x6F, 0x68, 0x5D, 0x64, -0x71, 0x75, 0x6B, 0x6D, 0xF9, 0x79, 0x6F, 0xF4, 0xEA, 0xF5, 0x79, 0x7B, 0x7D, 0xFA, 0xF3, 0xF7, -0xF4, 0xF4, 0xF9, 0x7F, 0x77, 0x7F, 0xF5, 0xFD, 0x71, 0x71, 0x7B, 0x78, 0x7A, 0x73, 0x68, 0x71, -0x7A, 0x6B, 0x6C, 0x6E, 0x69, 0x6E, 0x71, 0x6C, 0x69, 0x6C, 0x7A, 0x7D, 0xF6, 0xEB, 0xF4, 0xF2, -0xF4, 0x78, 0xF8, 0xF1, 0xF6, 0xFE, 0x71, 0x75, 0x7C, 0x7B, 0x7D, 0x7E, 0xFB, 0x7E, 0x77, 0x76, -0xFF, 0xF7, 0x79, 0x70, 0x6E, 0x6C, 0x71, 0x6F, 0x6C, 0x6A, 0x70, 0x6E, 0x5F, 0x65, 0x6C, 0x66, -0x6D, 0x7A, 0xF1, 0x78, 0x6B, 0xED, 0xFB, 0x6C, 0x7C, 0x74, 0xF1, 0xEC, 0x76, 0xF9, 0xF8, 0x75, -0x71, 0x7A, 0xEC, 0xFA, 0x6C, 0x76, 0x7C, 0x7F, 0x6E, 0x6A, 0x76, 0x6C, 0x76, 0xF2, 0x7C, 0x76, -0x66, 0x62, 0x7D, 0xF9, 0x78, 0x69, 0x6A, 0xF8, 0x78, 0x6D, 0xFC, 0xF8, 0xF3, 0xF7, 0x7D, 0xEF, -0xF1, 0x7C, 0xF1, 0xE9, 0xEB, 0xEE, 0xF3, 0xFD, 0x73, 0x7D, 0xFA, 0x74, 0x78, 0x7A, 0x6E, 0x70, -0x76, 0x73, 0x6F, 0x6D, 0x6C, 0x68, 0x6D, 0x7D, 0x6E, 0x64, 0x6D, 0xFC, 0xFA, 0x71, 0x6F, 0xFF, -0x70, 0x70, 0xF0, 0xEE, 0xEF, 0xEB, 0xEC, 0xEC, 0xED, 0xF0, 0xEE, 0xE9, 0xEB, 0xF8, 0xFB, 0xED, -0xE9, 0xF7, 0xFF, 0xED, 0xEE, 0xEF, 0xF3, 0x6E, 0x70, 0xF3, 0xFF, 0x6F, 0x6F, 0x6F, 0x79, 0x7C, -0x79, 0x7E, 0x77, 0x6E, 0x6E, 0x7B, 0x7C, 0x6B, 0x72, 0xF6, 0xFF, 0x7D, 0x7D, 0x72, 0x78, 0xFB, -0xFD, 0xFB, 0xFA, 0x7D, 0x7A, 0x6D, 0x68, 0x74, 0x75, 0xF1, 0xE7, 0x7B, 0x76, 0x6B, 0x66, 0xFD, -0x73, 0x68, 0x6B, 0x73, 0x7C, 0x62, 0x64, 0x70, 0x64, 0x6D, 0x79, 0x70, 0x70, 0x74, 0xF8, 0x7C, -0x7C, 0xF8, 0x6B, 0x70, 0xF9, 0x7D, 0xF1, 0xF0, 0xFF, 0x7F, 0xF8, 0xED, 0xF2, 0xFC, 0xFF, 0x76, -0x7B, 0x7C, 0xFE, 0xFE, 0x6C, 0x7C, 0xED, 0x79, 0x77, 0x71, 0x69, 0x76, 0x7A, 0x76, 0x7A, 0x6F, -0x6E, 0x6E, 0x73, 0xFF, 0x78, 0x76, 0x7F, 0x7A, 0x6F, 0x78, 0xFE, 0x77, 0xFB, 0xEE, 0xEE, 0xF1, -0x7A, 0xFB, 0xEE, 0x75, 0x70, 0xFE, 0x7D, 0x72, 0x6D, 0x6F, 0x7B, 0xFB, 0xF9, 0x7C, 0x7E, 0x7A, -0x70, 0x76, 0x7B, 0xF7, 0xF5, 0x70, 0x74, 0xFF, 0x78, 0xFA, 0xFC, 0x79, 0x78, 0x6D, 0x7A, 0xFA, -0x77, 0xFC, 0xF4, 0xF1, 0xF1, 0xF7, 0xEB, 0xED, 0xFB, 0xF7, 0xEF, 0xF2, 0x78, 0x79, 0xF0, 0xF3, -0xFC, 0xFC, 0x7E, 0x77, 0xFF, 0xFC, 0x78, 0xF6, 0xF9, 0x6F, 0x7A, 0x78, 0x6F, 0xFF, 0xF9, 0x7E, -0x76, 0x72, 0x76, 0x78, 0x79, 0xFD, 0xFA, 0x7A, 0x7E, 0xF1, 0xFB, 0x7A, 0xF2, 0xEF, 0xFF, 0x74, -0x75, 0x7E, 0xFF, 0xF6, 0xE9, 0xF4, 0x71, 0x74, 0x74, 0x7C, 0xF8, 0x79, 0x75, 0x74, 0x73, 0xF9, -0xFE, 0xFF, 0xFA, 0x6A, 0x6C, 0xFE, 0x70, 0x72, 0x7C, 0x7D, 0x70, 0x67, 0x6F, 0x76, 0x7B, 0xF0, -0x7E, 0x6E, 0x6E, 0x76, 0xF1, 0xF2, 0x7A, 0x72, 0x7B, 0xFD, 0x79, 0x77, 0x6E, 0x6A, 0x6D, 0x6E, -0x74, 0x72, 0x77, 0xF5, 0x7C, 0x6D, 0x6C, 0x6D, 0x70, 0x76, 0xFD, 0xFC, 0xFF, 0xFE, 0xFE, 0xFA, -0x7D, 0x77, 0x74, 0x6F, 0xFB, 0xFA, 0x71, 0xFC, 0xF8, 0xFE, 0xEB, 0xE5, 0xEE, 0x7F, 0xF6, 0xED, -0xFA, 0x78, 0xF6, 0xF1, 0xF8, 0xF6, 0x79, 0x70, 0x7C, 0x75, 0x78, 0xF6, 0xFA, 0xFC, 0xFB, 0x7B, -0x7D, 0xF9, 0xF7, 0xF7, 0x7E, 0x6B, 0x68, 0xFA, 0xE6, 0xEE, 0x7B, 0x7B, 0x79, 0x7E, 0xFB, 0xF2, -0xEA, 0xEE, 0xF1, 0xF6, 0x79, 0xFB, 0xF0, 0xFB, 0xFF, 0xF0, 0xEE, 0xF4, 0xEF, 0xFB, 0x6F, 0x6C, -0x72, 0xFF, 0x71, 0x6C, 0x6A, 0x6D, 0xF4, 0xFB, 0x7C, 0xF3, 0xFA, 0xFC, 0x6F, 0x73, 0xFB, 0x72, -0x7D, 0x78, 0x76, 0xEF, 0xF3, 0x7C, 0x71, 0xFA, 0xF2, 0xFB, 0xEF, 0xF0, 0xEA, 0xFD, 0x6B, 0xED, -0xF2, 0x77, 0x6E, 0x6D, 0xFD, 0x64, 0xF3, 0xDF, 0x5C, 0x61, 0xED, 0xF2, 0x7E, 0x66, 0x73, 0x6E, -0x66, 0xFF, 0x6F, 0x72, 0x70, 0x66, 0xF3, 0xF7, 0x6F, 0x72, 0x75, 0xED, 0xEF, 0xF4, 0xED, 0xEF, -0xEF, 0x6E, 0x6F, 0xF7, 0x72, 0x7E, 0x78, 0x6F, 0xF9, 0x77, 0xFC, 0xF4, 0x6C, 0x66, 0x6A, 0x76, -0x65, 0x5C, 0x6D, 0xFF, 0xF8, 0xEA, 0xE2, 0xEF, 0x65, 0x70, 0xEB, 0xE8, 0xE2, 0xDF, 0xDA, 0xD9, -0xE3, 0xF0, 0xFA, 0xE6, 0xDD, 0xDF, 0xDF, 0xE0, 0xE4, 0xFC, 0x63, 0x60, 0x64, 0x63, 0x66, 0x78, -0x65, 0x57, 0x60, 0x67, 0x64, 0x67, 0x5F, 0x6E, 0xF3, 0x7F, 0x75, 0xFE, 0xEA, 0xF4, 0xF8, 0xE0, -0xE0, 0xE4, 0xE3, 0xE7, 0xEA, 0xFB, 0x6F, 0x6E, 0x75, 0x72, 0x68, 0x6E, 0x77, 0x74, 0x6D, 0x73, -0xF9, 0x74, 0xF2, 0xE2, 0xEF, 0xDE, 0xDD, 0x79, 0xFD, 0xF4, 0x6F, 0x6A, 0x6E, 0xFE, 0x7A, 0x68, -0x60, 0x63, 0x6B, 0x66, 0x67, 0x76, 0xFE, 0x78, 0x65, 0x63, 0x7A, 0xFF, 0x72, 0x72, 0x74, 0x7D, -0x7C, 0x6B, 0x72, 0xEF, 0xF6, 0x73, 0x74, 0x7C, 0x74, 0x68, 0x68, 0x73, 0xFA, 0xF6, 0x6F, 0x67, -0x6F, 0x6D, 0x6A, 0x69, 0x68, 0x74, 0x6D, 0x64, 0x6F, 0x75, 0x77, 0xFA, 0x7F, 0xF5, 0xEF, 0x78, -0x77, 0x7D, 0x7A, 0xFE, 0x77, 0x73, 0xF8, 0xF4, 0xFE, 0x6F, 0x71, 0xF7, 0x74, 0x79, 0xEF, 0x7B, -0xF9, 0xFA, 0x68, 0x71, 0x7F, 0x76, 0x73, 0x71, 0x7D, 0x7D, 0x65, 0x5D, 0x69, 0x6E, 0x5F, 0x67, -0x6F, 0x6D, 0xFF, 0x7F, 0x6E, 0x6F, 0x73, 0x77, 0xF2, 0xDE, 0xD4, 0xD0, 0xD0, 0xCF, 0xCE, 0xD0, -0xD2, 0xD6, 0xDA, 0xDB, 0xE7, 0x6D, 0x5B, 0x52, 0x4C, 0x47, 0x44, 0x43, 0x44, 0x47, 0x49, 0x4B, -0x4E, 0x52, 0x56, 0x5A, 0x5D, 0x64, 0x75, 0xE6, 0xCF, 0xC5, 0xBF, 0xBD, 0xBB, 0xB7, 0xB5, 0xB1, -0xAF, 0xB5, 0xC1, 0xDF, 0x51, 0x44, 0x3A, 0x33, 0x33, 0x37, 0x3D, 0x44, 0x48, 0x4D, 0x51, 0x54, -0x53, 0x4D, 0x49, 0x44, 0x43, 0x45, 0x46, 0x4C, 0x54, 0x65, 0xE4, 0xCF, 0xC4, 0xBB, 0xB4, 0xAF, -0xAD, 0xAC, 0xAA, 0xAB, 0xB5, 0xD1, 0x49, 0x3B, 0x35, 0x2F, 0x2D, 0x32, 0x3D, 0x4E, 0x57, 0x51, -0x4F, 0x50, 0x4C, 0x42, 0x3D, 0x3F, 0x46, 0x4A, 0x4F, 0x5E, 0xEC, 0xD9, 0xDA, 0xD2, 0xC8, 0xBE, -0xB7, 0xB0, 0xAD, 0xAB, 0xA9, 0xA8, 0xAD, 0xC4, 0x48, 0x36, 0x31, 0x2E, 0x2D, 0x30, 0x3E, 0x67, -0xE2, 0x63, 0x47, 0x43, 0x42, 0x39, 0x36, 0x3B, 0x46, 0x6B, 0xE1, 0xDB, 0xCC, 0xC8, 0xCC, 0xD7, -0xDD, 0xC6, 0xBA, 0xB2, 0xAC, 0xAA, 0xA7, 0xA7, 0xB0, 0x69, 0x32, 0x2D, 0x2D, 0x2C, 0x2D, 0x39, -0xF1, 0xC2, 0xCA, 0x5E, 0x3D, 0x38, 0x34, 0x2E, 0x2F, 0x3E, 0x69, 0xCC, 0xC3, 0xBD, 0xBD, 0xC2, -0xCD, 0xEC, 0xF4, 0xCD, 0xC0, 0xB7, 0xAC, 0xA7, 0xA4, 0xA4, 0xB7, 0x3A, 0x2A, 0x29, 0x2A, 0x2B, -0x30, 0x56, 0xBA, 0xB6, 0xCD, 0x4A, 0x33, 0x2C, 0x2C, 0x2B, 0x34, 0x65, 0xC3, 0xBB, 0xBB, 0xBC, -0xC1, 0xDA, 0x7F, 0x6A, 0x75, 0xD1, 0xC2, 0xB8, 0xAC, 0xA6, 0xA5, 0xA4, 0xB0, 0x35, 0x23, 0x25, -0x29, 0x2F, 0x38, 0x73, 0xB3, 0xAF, 0xC8, 0x3E, 0x2E, 0x29, 0x26, 0x2C, 0x3D, 0xDF, 0xB8, 0xB5, -0xBB, 0xC5, 0xE7, 0x5A, 0x53, 0x68, 0xD9, 0xC8, 0xBA, 0xB3, 0xAD, 0xA8, 0xA7, 0xA6, 0xAF, 0x34, -0x1F, 0x24, 0x2E, 0x3B, 0x48, 0xDA, 0xB3, 0xB0, 0xD6, 0x33, 0x29, 0x29, 0x29, 0x2F, 0x5B, 0xC3, -0xB9, 0xB8, 0xC1, 0xDB, 0x53, 0x46, 0x4E, 0xEE, 0xCB, 0xC5, 0xBF, 0xBA, 0xB6, 0xAE, 0xAA, 0xA8, -0xAA, 0xDB, 0x26, 0x20, 0x2B, 0x3E, 0x5E, 0xEE, 0xC1, 0xB6, 0xC1, 0x3F, 0x2A, 0x29, 0x2A, 0x2F, -0x4F, 0xCA, 0xC0, 0xBE, 0xC5, 0xDC, 0x51, 0x44, 0x4B, 0x7D, 0xCB, 0xC5, 0xC5, 0xC2, 0xBF, 0xBD, -0xB1, 0xA9, 0xA8, 0xAA, 0xCB, 0x28, 0x20, 0x2C, 0x44, 0x7E, 0xDE, 0xC8, 0xBB, 0xC6, 0x3F, 0x2B, -0x29, 0x2E, 0x35, 0x4C, 0xCB, 0xBF, 0xC3, 0xCA, 0xE6, 0x4E, 0x43, 0x44, 0x6A, 0xC8, 0xC3, 0xC3, -0xC8, 0xC8, 0xBE, 0xB5, 0xAB, 0xA7, 0xA8, 0xBC, 0x2D, 0x1F, 0x29, 0x42, 0xD7, 0xD0, 0xCD, 0xBF, -0xC5, 0x4C, 0x2E, 0x2B, 0x2F, 0x36, 0x4A, 0xD7, 0xBE, 0xBD, 0xD5, 0x74, 0x50, 0x42, 0x45, 0x53, -0xD1, 0xBE, 0xBE, 0xC5, 0xD2, 0xCD, 0xBC, 0xAE, 0xA7, 0xA7, 0xB5, 0x36, 0x21, 0x28, 0x41, 0xD1, -0xC9, 0xD4, 0xCB, 0xCB, 0x51, 0x31, 0x2B, 0x2F, 0x39, 0x47, 0xE9, 0xC5, 0xC0, 0xCD, 0xED, 0x50, -0x3F, 0x3F, 0x52, 0xCD, 0xBB, 0xBC, 0xC6, 0xDE, 0xE7, 0xCB, 0xB5, 0xA8, 0xA4, 0xA9, 0xCC, 0x28, -0x20, 0x2E, 0x6F, 0xC2, 0xCF, 0xF7, 0xDA, 0xEB, 0x3F, 0x2E, 0x2D, 0x34, 0x3E, 0x5D, 0xCD, 0xBF, -0xC7, 0x73, 0x53, 0x43, 0x3C, 0x49, 0xDD, 0xBC, 0xB7, 0xC2, 0xE4, 0x62, 0xEC, 0xBD, 0xAA, 0xA3, -0xA4, 0xB3, 0x32, 0x1F, 0x26, 0x42, 0xC3, 0xC0, 0xF2, 0x68, 0x73, 0x4D, 0x37, 0x2D, 0x2F, 0x39, -0x47, 0xDD, 0xC2, 0xBE, 0xD2, 0x4A, 0x3E, 0x3B, 0x42, 0xEB, 0xBE, 0xB5, 0xB9, 0xD5, 0x54, 0x54, -0xCB, 0xAD, 0xA3, 0xA2, 0xAC, 0x4D, 0x23, 0x21, 0x34, 0xCF, 0xBA, 0xD0, 0x5E, 0x73, 0x5D, 0x43, -0x34, 0x30, 0x38, 0x3C, 0x46, 0xCE, 0xB9, 0xBE, 0x5F, 0x3E, 0x3B, 0x3E, 0x62, 0xC0, 0xB5, 0xB6, -0xC9, 0x54, 0x48, 0xE3, 0xB1, 0xA4, 0xA0, 0xA6, 0xC3, 0x2B, 0x1E, 0x29, 0x5D, 0xB9, 0xBD, 0x72, -0x50, 0x5B, 0x50, 0x3C, 0x30, 0x30, 0x36, 0x3F, 0x7C, 0xC0, 0xBA, 0xD0, 0x45, 0x3A, 0x38, 0x46, -0xCB, 0xB7, 0xB5, 0xC4, 0x5A, 0x48, 0x62, 0xBA, 0xA8, 0xA1, 0xA3, 0xB0, 0x3C, 0x20, 0x20, 0x39, -0xBD, 0xB1, 0xC7, 0x4F, 0x4A, 0x4E, 0x48, 0x35, 0x2E, 0x31, 0x39, 0x56, 0xC0, 0xB8, 0xC2, 0x4D, -0x39, 0x37, 0x3E, 0xE2, 0xBC, 0xB6, 0xBB, 0xDC, 0x4B, 0x4A, 0xD3, 0xAE, 0xA3, 0xA0, 0xA8, 0xD5, -0x29, 0x1F, 0x2B, 0xE3, 0xB3, 0xBA, 0x65, 0x47, 0x4C, 0x4F, 0x3D, 0x2F, 0x2D, 0x30, 0x41, 0xCB, -0xB7, 0xBA, 0x76, 0x3D, 0x38, 0x39, 0x51, 0xC5, 0xB6, 0xB6, 0xCC, 0x50, 0x46, 0x7E, 0xB4, 0xA6, -0xA1, 0xA4, 0xB8, 0x35, 0x20, 0x25, 0x48, 0xB8, 0xB5, 0xDB, 0x47, 0x47, 0x52, 0x4A, 0x34, 0x2D, -0x2E, 0x39, 0xEC, 0xBA, 0xB6, 0xCF, 0x3F, 0x38, 0x37, 0x41, 0xD0, 0xB8, 0xB4, 0xBF, 0x6A, 0x4A, -0x5B, 0xBC, 0xA8, 0xA1, 0xA2, 0xAF, 0x3E, 0x22, 0x24, 0x3E, 0xBA, 0xB3, 0xD4, 0x45, 0x41, 0x4F, -0x52, 0x37, 0x2D, 0x2D, 0x36, 0x65, 0xBB, 0xB6, 0xC9, 0x46, 0x38, 0x35, 0x3D, 0xDC, 0xB7, 0xB0, -0xBA, 0xF0, 0x48, 0x4E, 0xC1, 0xAA, 0xA2, 0xA1, 0xAB, 0x5E, 0x27, 0x21, 0x32, 0xC7, 0xB4, 0xC8, -0x48, 0x3E, 0x4B, 0x58, 0x3D, 0x2E, 0x2C, 0x2F, 0x48, 0xBF, 0xB5, 0xBF, 0x4C, 0x36, 0x34, 0x3A, -0x67, 0xBC, 0xB2, 0xB7, 0xD6, 0x4C, 0x4A, 0xCE, 0xAD, 0xA3, 0xA0, 0xA7, 0xD8, 0x29, 0x20, 0x2F, -0xD2, 0xB5, 0xC4, 0x4C, 0x40, 0x4B, 0x64, 0x44, 0x2F, 0x2C, 0x2D, 0x3F, 0xC4, 0xB4, 0xB9, 0x5F, -0x39, 0x36, 0x39, 0x5D, 0xBE, 0xB3, 0xB4, 0xC8, 0x59, 0x4B, 0xDC, 0xAF, 0xA3, 0x9F, 0xA5, 0xC5, -0x2C, 0x21, 0x2C, 0xFB, 0xB9, 0xC1, 0x53, 0x42, 0x4A, 0x5F, 0x49, 0x31, 0x2C, 0x2C, 0x3A, 0xCF, -0xB6, 0xBA, 0xF7, 0x3E, 0x39, 0x3A, 0x4C, 0xCA, 0xB7, 0xB4, 0xBF, 0x79, 0x4D, 0xE5, 0xB1, 0xA4, -0x9F, 0xA4, 0xC6, 0x2B, 0x20, 0x2C, 0xEC, 0xB7, 0xC1, 0x57, 0x43, 0x49, 0x5C, 0x47, 0x31, 0x2C, -0x2C, 0x39, 0xD3, 0xB7, 0xBA, 0xDC, 0x46, 0x3C, 0x39, 0x47, 0xCE, 0xB9, 0xB5, 0xBD, 0xDE, 0x5E, -0xD3, 0xB0, 0xA4, 0xA0, 0xA6, 0xCF, 0x2A, 0x21, 0x2D, 0xF6, 0xBB, 0xC8, 0x55, 0x44, 0x48, 0x51, -0x3F, 0x2F, 0x2C, 0x2D, 0x3B, 0xD8, 0xBC, 0xBF, 0xE7, 0x4E, 0x45, 0x3C, 0x44, 0xEB, 0xBE, 0xB5, -0xBA, 0xCA, 0xE3, 0xC9, 0xAF, 0xA5, 0xA0, 0xA7, 0xE6, 0x28, 0x22, 0x2E, 0xEA, 0xBD, 0xC8, 0x5D, -0x46, 0x4A, 0x4D, 0x3B, 0x2F, 0x2D, 0x2F, 0x3F, 0xD0, 0xBE, 0xC3, 0xE6, 0x56, 0x4B, 0x43, 0x4C, -0xFA, 0xC8, 0xBB, 0xBB, 0xC3, 0xC8, 0xBD, 0xAE, 0xA7, 0xA3, 0xAA, 0x6C, 0x2A, 0x25, 0x30, 0x5A, -0xCD, 0xD3, 0x5F, 0x4D, 0x50, 0x4C, 0x3B, 0x2F, 0x2D, 0x2F, 0x3D, 0xE6, 0xCC, 0xD3, 0xDA, 0xDB, -0x79, 0x55, 0x56, 0x68, 0xE0, 0xCA, 0xC2, 0xC0, 0xBC, 0xB1, 0xAB, 0xA6, 0xA5, 0xAE, 0x53, 0x2C, -0x29, 0x30, 0x41, 0x59, 0x62, 0x53, 0x57, 0x7F, 0x5D, 0x40, 0x35, 0x2E, 0x2F, 0x3D, 0x58, 0x78, -0xE5, 0xCD, 0xC8, 0xCF, 0xDA, 0xEC, 0x7B, 0xE4, 0xD1, 0xCA, 0xC4, 0xBA, 0xB0, 0xAC, 0xAA, 0xAB, -0xBA, 0x4F, 0x39, 0x39, 0x3D, 0x3F, 0x42, 0x3D, 0x3C, 0x45, 0x51, 0x52, 0x4C, 0x42, 0x3B, 0x3E, -0x4A, 0x4C, 0x4D, 0x57, 0x69, 0xEE, 0xDE, 0xE4, 0xFD, 0xED, 0xDC, 0xD3, 0xCD, 0xCA, 0xC3, 0xBD, -0xB9, 0xB6, 0xB8, 0xC3, 0xCE, 0xC8, 0xC1, 0xC5, 0xCE, 0xF9, 0x4A, 0x3F, 0x3F, 0x41, 0x3F, 0x3D, -0x39, 0x38, 0x3B, 0x3C, 0x3A, 0x3C, 0x43, 0x4C, 0x52, 0x58, 0x5B, 0x59, 0x65, 0xDC, 0xCB, 0xC3, -0xBD, 0xB8, 0xB6, 0xB2, 0xAF, 0xB2, 0xB6, 0xB2, 0xB0, 0xB6, 0xBF, 0xD7, 0x4F, 0x40, 0x3F, 0x3D, -0x3A, 0x35, 0x2F, 0x2D, 0x2F, 0x32, 0x33, 0x34, 0x39, 0x3E, 0x46, 0x51, 0x59, 0x5C, 0x6F, 0xD8, -0xC6, 0xBD, 0xB8, 0xB4, 0xB2, 0xAF, 0xAC, 0xAD, 0xAF, 0xAE, 0xAE, 0xB2, 0xBC, 0xCF, 0x55, 0x42, -0x3E, 0x3B, 0x36, 0x31, 0x2D, 0x2A, 0x2B, 0x2F, 0x32, 0x33, 0x36, 0x3B, 0x40, 0x4A, 0x57, 0x69, -0xEE, 0xD6, 0xC8, 0xBF, 0xB9, 0xB3, 0xB1, 0xAF, 0xAC, 0xAB, 0xAE, 0xAF, 0xAF, 0xB1, 0xB9, 0xC6, -0x75, 0x46, 0x3D, 0x3A, 0x36, 0x30, 0x2D, 0x2B, 0x2A, 0x2D, 0x31, 0x34, 0x36, 0x39, 0x3E, 0x46, -0x56, 0x77, 0xE3, 0xD4, 0xCA, 0xC3, 0xBD, 0xB6, 0xB1, 0xAF, 0xAC, 0xAB, 0xAC, 0xAF, 0xAF, 0xB0, -0xB5, 0xBE, 0xDA, 0x4E, 0x3E, 0x3A, 0x36, 0x31, 0x2D, 0x2C, 0x2B, 0x2C, 0x2F, 0x32, 0x34, 0x38, -0x3D, 0x43, 0x4D, 0x66, 0xE7, 0xD6, 0xCB, 0xC5, 0xC0, 0xBA, 0xB3, 0xAF, 0xAD, 0xAB, 0xAC, 0xAE, -0xAF, 0xAF, 0xB3, 0xBB, 0xCD, 0x5A, 0x40, 0x3A, 0x36, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, 0x2F, 0x31, -0x32, 0x38, 0x3D, 0x41, 0x4B, 0x5C, 0xF8, 0xD8, 0xCA, 0xC3, 0xBF, 0xBA, 0xB4, 0xB0, 0xAD, 0xAB, -0xAB, 0xAE, 0xAF, 0xB0, 0xB3, 0xBA, 0xC9, 0x68, 0x46, 0x3C, 0x37, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, -0x2F, 0x30, 0x31, 0x36, 0x3C, 0x3F, 0x49, 0x58, 0x70, 0xDD, 0xCA, 0xC2, 0xBE, 0xB9, 0xB3, 0xB0, -0xAD, 0xAA, 0xAB, 0xAE, 0xAF, 0xAF, 0xB4, 0xBC, 0xCB, 0x61, 0x46, 0x3D, 0x36, 0x30, 0x2E, 0x2C, -0x2B, 0x2D, 0x2F, 0x2F, 0x31, 0x37, 0x3B, 0x3F, 0x4B, 0x5C, 0xFF, 0xD8, 0xC8, 0xC1, 0xBC, 0xB6, -0xB2, 0xAF, 0xAC, 0xAA, 0xAB, 0xAD, 0xAE, 0xAF, 0xB5, 0xBD, 0xCF, 0x5C, 0x45, 0x3C, 0x35, 0x2F, -0x2D, 0x2C, 0x2C, 0x2D, 0x2F, 0x2F, 0x32, 0x37, 0x3B, 0x3F, 0x4B, 0x5F, 0xEE, 0xD4, 0xC8, 0xC1, -0xBC, 0xB5, 0xB0, 0xAE, 0xAB, 0xAA, 0xAB, 0xAD, 0xAF, 0xB1, 0xB7, 0xC0, 0xD9, 0x53, 0x42, 0x3B, -0x34, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x30, 0x33, 0x37, 0x3C, 0x43, 0x4D, 0x5E, 0xEC, 0xD0, -0xC7, 0xC0, 0xBB, 0xB6, 0xB0, 0xAE, 0xAB, 0xAA, 0xAC, 0xAE, 0xAF, 0xB3, 0xB9, 0xC5, 0xE2, 0x4E, -0x3F, 0x39, 0x32, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x2F, 0x33, 0x39, 0x3D, 0x44, 0x4F, 0x65, -0xE3, 0xCE, 0xC5, 0xBF, 0xBA, 0xB4, 0xAF, 0xAD, 0xAA, 0xAA, 0xAC, 0xAE, 0xB0, 0xB5, 0xBB, 0xC8, -0xF8, 0x4C, 0x3E, 0x38, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, 0x2E, 0x2F, 0x31, 0x35, 0x39, 0x3E, 0x4A, -0x5C, 0xF9, 0xD8, 0xCB, 0xC2, 0xBC, 0xB7, 0xB2, 0xAE, 0xAB, 0xA9, 0xAA, 0xAC, 0xAE, 0xB2, 0xB8, -0xBE, 0xCE, 0x72, 0x48, 0x3B, 0x34, 0x2F, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x31, 0x36, 0x3A, -0x3E, 0x4A, 0x5F, 0xEA, 0xD0, 0xC9, 0xC1, 0xBB, 0xB5, 0xB0, 0xAE, 0xAB, 0xA9, 0xAB, 0xAC, 0xAE, -0xB4, 0xBB, 0xC4, 0xD6, 0x60, 0x45, 0x39, 0x30, 0x2D, 0x2C, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x32, -0x35, 0x3A, 0x43, 0x51, 0x6A, 0xDF, 0xCB, 0xC3, 0xBD, 0xB8, 0xB2, 0xAE, 0xAC, 0xAA, 0xAA, 0xAB, -0xAC, 0xAF, 0xB7, 0xBD, 0xCC, 0xF1, 0x51, 0x3F, 0x36, 0x2F, 0x2D, 0x2B, 0x2A, 0x2C, 0x2D, 0x2E, -0x2F, 0x33, 0x37, 0x3B, 0x45, 0x58, 0x77, 0xD5, 0xC8, 0xC0, 0xBB, 0xB6, 0xB1, 0xAE, 0xAB, 0xA9, -0xAA, 0xAB, 0xAC, 0xB1, 0xB9, 0xC0, 0xD3, 0x6A, 0x4A, 0x3C, 0x33, 0x2E, 0x2D, 0x2B, 0x2B, 0x2C, -0x2D, 0x2E, 0x31, 0x34, 0x38, 0x3F, 0x4C, 0x5D, 0xEA, 0xCE, 0xC6, 0xBE, 0xB8, 0xB4, 0xAF, 0xAD, -0xAB, 0xAA, 0xAA, 0xAB, 0xAD, 0xB2, 0xB9, 0xC3, 0xD8, 0x61, 0x47, 0x3A, 0x32, 0x2E, 0x2C, 0x2B, -0x2C, 0x2C, 0x2D, 0x2F, 0x31, 0x34, 0x38, 0x3F, 0x4D, 0x62, 0xDD, 0xCC, 0xC3, 0xBC, 0xB7, 0xB2, -0xAE, 0xAC, 0xAA, 0xAA, 0xAA, 0xAB, 0xAE, 0xB3, 0xBA, 0xC6, 0xE1, 0x55, 0x41, 0x37, 0x30, 0x2D, -0x2B, 0x2A, 0x2B, 0x2C, 0x2D, 0x2F, 0x31, 0x34, 0x39, 0x40, 0x4D, 0x6A, 0xD8, 0xC9, 0xC1, 0xBC, -0xB7, 0xB2, 0xAE, 0xAC, 0xAA, 0xAA, 0xAB, 0xAC, 0xAF, 0xB7, 0xBB, 0xC6, 0x79, 0x55, 0x44, 0x37, -0x30, 0x2D, 0x2C, 0x2B, 0x2C, 0x2D, 0x2D, 0x2F, 0x33, 0x35, 0x39, 0x42, 0x51, 0x6C, 0xDA, 0xCA, -0xC4, 0xBE, 0xBA, 0xB6, 0xB0, 0xAD, 0xAC, 0xAC, 0xAC, 0xAD, 0xAF, 0xB4, 0xB9, 0xC0, 0xD0, 0x65, -0x47, 0x3A, 0x32, 0x2F, 0x2C, 0x2B, 0x2B, 0x2C, 0x2D, 0x2E, 0x31, 0x36, 0x3A, 0x3F, 0x4A, 0x5E, -0xDC, 0xCC, 0xC4, 0xBE, 0xBA, 0xB6, 0xB2, 0xAF, 0xAE, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB8, 0xBE, -0xCA, 0xE6, 0x4F, 0x3F, 0x38, 0x31, 0x2E, 0x2C, 0x2C, 0x2C, 0x2D, 0x2F, 0x31, 0x35, 0x3A, 0x3F, -0x4B, 0x64, 0xDD, 0xCB, 0xC3, 0xBD, 0xBA, 0xB7, 0xB4, 0xB1, 0xAF, 0xAE, 0xAE, 0xB0, 0xB3, 0xB5, -0xB9, 0xBE, 0xC6, 0xD3, 0x74, 0x4E, 0x40, 0x3A, 0x35, 0x32, 0x30, 0x2F, 0x2F, 0x30, 0x33, 0x36, -0x3A, 0x3F, 0x48, 0x52, 0x6C, 0xDF, 0xCE, 0xC7, 0xC1, 0xBE, 0xBB, 0xB9, 0xB8, 0xB7, 0xB6, 0xB6, -0xB7, 0xB9, 0xBB, 0xBE, 0xC4, 0xCA, 0xD9, 0x6C, 0x50, 0x45, 0x3D, 0x3A, 0x37, 0x35, 0x35, 0x35, -0x36, 0x37, 0x39, 0x3C, 0x3F, 0x46, 0x4F, 0x5E, 0xF1, 0xD9, 0xCF, 0xCC, 0xC9, 0xC5, 0xC1, 0xBE, -0xBC, 0xBC, 0xBC, 0xBD, 0xBF, 0xC2, 0xC4, 0xC7, 0xCC, 0xD5, 0xE8, 0x64, 0x52, 0x4A, 0x45, 0x41, -0x3F, 0x3E, 0x3D, 0x3D, 0x3E, 0x41, 0x45, 0x49, 0x4D, 0x53, 0x5C, 0x71, 0xE9, 0xDD, 0xD6, 0xD1, -0xCE, 0xCB, 0xC9, 0xC8, 0xC8, 0xC7, 0xC7, 0xC8, 0xC9, 0xCC, 0xCF, 0xD4, 0xDA, 0xE4, 0xF7, 0x69, -0x5B, 0x53, 0x4F, 0x4E, 0x4D, 0x4D, 0x4D, 0x4E, 0x51, 0x58, 0x5F, 0x68, 0x6F, 0x77, 0xFC, 0xEE, -0xE8, 0xE5, 0xE1, 0xDD, 0xDE, 0xDE, 0xDE, 0xE2, 0xE6, 0xE6, 0xEB, 0xF0, 0xED, 0xEA, 0xEC, 0xEE, -0xF8, 0x6A, 0x5C, 0x57, 0x55, 0x56, 0x58, 0x59, 0x58, 0x58, 0x5B, 0x5E, 0x63, 0x71, 0xF7, 0xEE, -0xE9, 0xE3, 0xE4, 0xE8, 0xE7, 0xEA, 0xEE, 0xEE, 0xF2, 0xFB, 0xFF, 0x7B, 0x74, 0x6E, 0x6B, 0x65, -0x60, 0x65, 0x67, 0x61, 0x60, 0x61, 0x5E, 0x5E, 0x62, 0x69, 0x70, 0x7F, 0xF6, 0xF2, 0xEC, 0xE7, -0xE6, 0xE3, 0xDF, 0xDE, 0xDE, 0xDD, 0xDE, 0xE0, 0xE5, 0xEC, 0xF6, 0x7F, 0x78, 0x75, 0x70, 0x6B, -0x64, 0x5E, 0x5A, 0x58, 0x58, 0x59, 0x5A, 0x5C, 0x5D, 0x5E, 0x61, 0x67, 0x6C, 0x75, 0xF8, 0xEC, -0xE6, 0xE0, 0xDD, 0xDD, 0xDE, 0xDF, 0xE0, 0xE2, 0xE2, 0xE4, 0xE6, 0xE9, 0xEE, 0xF9, 0x7D, 0x75, -0x6E, 0x6A, 0x65, 0x61, 0x5E, 0x5C, 0x5B, 0x5C, 0x5D, 0x5E, 0x60, 0x63, 0x66, 0x6C, 0x76, 0xFA, -0xEE, 0xE9, 0xE4, 0xE1, 0xDF, 0xDD, 0xDE, 0xDF, 0xE2, 0xE6, 0xEA, 0xEE, 0xF4, 0xFA, 0x7E, 0x7A, -0x75, 0x72, 0x74, 0x74, 0x71, 0x70, 0x6D, 0x6A, 0x6A, 0x6B, 0x6D, 0x70, 0x74, 0x78, 0x7A, 0x7D, -0xFA, 0xF0, 0xEA, 0xE5, 0xE3, 0xE2, 0xE0, 0xDF, 0xE1, 0xE3, 0xE4, 0xE8, 0xEB, 0xEE, 0xF4, 0xFB, -0x7E, 0x75, 0x6D, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x65, 0x64, 0x63, 0x64, 0x66, 0x69, 0x6D, 0x72, -0x77, 0x7B, 0xFE, 0xF7, 0xF0, 0xEB, 0xE8, 0xE7, 0xE6, 0xE6, 0xE6, 0xE7, 0xE7, 0xE8, 0xEA, 0xED, -0xF3, 0xFC, 0x79, 0x72, 0x6F, 0x6C, 0x6B, 0x6B, 0x69, 0x66, 0x64, 0x63, 0x62, 0x63, 0x67, 0x6C, -0x73, 0x7C, 0xFE, 0xFD, 0xFA, 0xF4, 0xEE, 0xEA, 0xE5, 0xE1, 0xE1, 0xE2, 0xE5, 0xE9, 0xED, 0xEF, -0xF1, 0xF2, 0xF4, 0xF8, 0xFF, 0x76, 0x6E, 0x6A, 0x68, 0x67, 0x66, 0x65, 0x64, 0x62, 0x61, 0x61, -0x63, 0x67, 0x6B, 0x72, 0x7E, 0xFA, 0xF5, 0xF1, 0xEE, 0xED, 0xEC, 0xE9, 0xE8, 0xE7, 0xE7, 0xE9, -0xEC, 0xF0, 0xF9, 0x7D, 0x77, 0x73, 0x70, 0x6F, 0x6E, 0x6C, 0x69, 0x67, 0x65, 0x66, 0x66, 0x68, -0x69, 0x69, 0x6A, 0x6C, 0x6E, 0x75, 0x7F, 0xF8, 0xF1, 0xED, 0xEB, 0xEA, 0xEA, 0xEB, 0xEB, 0xEB, -0xEA, 0xE9, 0xEA, 0xEC, 0xEF, 0xF4, 0xFB, 0x7D, 0x77, 0x73, 0x71, 0x6F, 0x6D, 0x6B, 0x69, 0x67, -0x66, 0x67, 0x68, 0x69, 0x6B, 0x6D, 0x6F, 0x74, 0x79, 0x7F, 0xF9, 0xF3, 0xEF, 0xEE, 0xEE, 0xEE, -0xEE, 0xED, 0xED, 0xED, 0xEE, 0xEC, 0xEC, 0xF1, 0xF3, 0xF6, 0xFD, 0xFF, 0x7D, 0x78, 0x78, 0x76, -0x70, 0x6F, 0x6E, 0x6D, 0x6D, 0x6E, 0x6F, 0x71, 0x73, 0x77, 0x7B, 0x7D, 0xFF, 0xFB, 0xF8, 0xF8, -0xFA, 0xFB, 0xFE, 0x7E, 0x7D, 0x7A, 0x79, 0x7A, 0x76, 0x76, 0x76, 0x72, 0x70, 0x6F, 0x6D, 0x6E, -0x6D, 0x6B, 0x6E, 0x65, 0x66, 0x57, 0x41, 0x59, 0xC7, 0x62, 0x57, 0xCD, 0x64, 0x6B, 0xCC, 0x6D, -0xF6, 0xD1, 0x69, 0x6E, 0xDA, 0x7D, 0x61, 0xEE, 0xF1, 0xFD, 0xFF, 0x6E, 0xE7, 0x74, 0x66, 0xE9, -0x6A, 0xFC, 0xF2, 0x64, 0xEE, 0x6F, 0x6B, 0x7B, 0x69, 0xF2, 0x68, 0x74, 0xEC, 0x5F, 0xED, 0xFC, -0x5F, 0xDE, 0x72, 0x65, 0xDC, 0x51, 0x4C, 0xE8, 0x5F, 0xEF, 0xD7, 0x4E, 0xF3, 0xF9, 0x52, 0xC3, -0xE2, 0x56, 0xC9, 0x5B, 0x59, 0xE4, 0x50, 0x53, 0x47, 0x66, 0xF9, 0x47, 0xC9, 0xCB, 0x59, 0xD4, -0x55, 0x58, 0xD3, 0x5C, 0xF9, 0xCE, 0xD7, 0x6D, 0x61, 0xDB, 0xE4, 0xE8, 0x70, 0x79, 0xCD, 0x6B, -0x5D, 0xEC, 0x66, 0xDC, 0x6C, 0x5F, 0xD3, 0xF9, 0xFB, 0x66, 0x55, 0xDE, 0xFB, 0x64, 0xD7, 0xDA, -0xF1, 0xF1, 0xF1, 0xE5, 0xDB, 0xF4, 0x75, 0xDF, 0xE7, 0xFD, 0x79, 0xEC, 0xD9, 0xF0, 0x6E, 0xF5, -0xE4, 0xE5, 0x64, 0x74, 0xDF, 0x7D, 0x68, 0x75, 0xF0, 0xFD, 0x7B, 0xFC, 0x7B, 0xDE, 0xEF, 0x64, -0xDF, 0xE8, 0xFF, 0xE9, 0xFF, 0xE2, 0xE1, 0x76, 0xF6, 0xEF, 0xEC, 0xF9, 0x6D, 0x7C, 0x73, 0x6D, -0x69, 0x67, 0x76, 0x75, 0x73, 0x64, 0x66, 0xFD, 0x60, 0x5F, 0x77, 0x67, 0x70, 0x74, 0x60, 0x78, -0x7A, 0x5C, 0x67, 0x79, 0x6C, 0x77, 0x63, 0x63, 0xEF, 0x6C, 0x66, 0x73, 0x6D, 0xF8, 0x72, 0x74, -0xE6, 0xFB, 0x7B, 0xF3, 0xF6, 0xF1, 0xFE, 0x7B, 0xF5, 0xF1, 0x6D, 0x63, 0x75, 0x6E, 0x60, 0x64, -0x67, 0x67, 0x68, 0x67, 0x67, 0x6C, 0x64, 0x5B, 0x65, 0x6E, 0x69, 0x72, 0x76, 0x74, 0xFE, 0xFD, -0xFF, 0xF6, 0xF3, 0x7C, 0x7A, 0xFC, 0xFE, 0xFB, 0x7E, 0x75, 0xF5, 0xEE, 0xFC, 0xF7, 0xF3, 0xFF, -0xFE, 0x74, 0x6B, 0x6F, 0x6D, 0x6A, 0x6C, 0x6A, 0x7A, 0xF9, 0x71, 0x7C, 0xF5, 0x7C, 0x7B, 0x7F, -0xFE, 0x72, 0x6E, 0xFF, 0x6F, 0x66, 0x6B, 0x6A, 0x6E, 0x76, 0x71, 0x7C, 0x7A, 0x6E, 0x6C, 0x69, -0x6C, 0x6D, 0x63, 0x65, 0x6A, 0x66, 0x63, 0x65, 0x6C, 0x68, 0x64, 0x69, 0x6A, 0x6E, 0x79, 0x7B, -0x78, 0x6D, 0x6E, 0x79, 0x77, 0xFA, 0xED, 0xEF, 0xEF, 0xEC, 0xE8, 0xEF, 0xFB, 0xF6, 0xEF, 0xEE, -0xF7, 0xF9, 0xF3, 0xF7, 0xF1, 0xF3, 0xFD, 0xFD, 0x7A, 0x7B, 0xFE, 0x79, 0x7C, 0x7B, 0x6E, 0x72, -0x7A, 0x72, 0x71, 0x79, 0x79, 0x6F, 0x6F, 0x78, 0x74, 0x72, 0x7B, 0x72, 0x78, 0xF6, 0xF7, 0xF9, -0x78, 0x79, 0xEE, 0xF5, 0x74, 0x76, 0x7A, 0xFE, 0x7E, 0x75, 0x7A, 0x7E, 0x74, 0x70, 0x7D, 0xF8, -0xF8, 0x7D, 0x77, 0xF8, 0xF0, 0x7F, 0x7E, 0xF2, 0xED, 0xF0, 0xF4, 0xEB, 0xE9, 0xFE, 0x74, 0xEF, -0xE1, 0xE0, 0xDC, 0xD9, 0xD7, 0xD3, 0xD7, 0xDD, 0xD9, 0xD9, 0xDF, 0xE6, 0xEB, 0xF2, 0x78, 0x65, -0x61, 0x65, 0x5F, 0x5A, 0x5B, 0x5B, 0x5A, 0x5C, 0x5B, 0x5D, 0x5E, 0x5C, 0x5B, 0x5B, 0x5B, 0x5C, -0x5E, 0x6B, 0xEA, 0xD9, 0xD2, 0xD1, 0xCD, 0xC8, 0xC6, 0xC5, 0xC5, 0xC3, 0xC3, 0xC6, 0xCA, 0xD2, -0xE8, 0x67, 0x51, 0x49, 0x42, 0x3D, 0x3D, 0x3E, 0x3F, 0x41, 0x44, 0x49, 0x4E, 0x50, 0x55, 0x5A, -0x5F, 0x6F, 0xEF, 0xDA, 0xCD, 0xCA, 0xC8, 0xC4, 0xBF, 0xBD, 0xBB, 0xB9, 0xB7, 0xB6, 0xBA, 0xC2, -0xCC, 0xE2, 0x56, 0x43, 0x3B, 0x39, 0x37, 0x36, 0x37, 0x3B, 0x3E, 0x42, 0x47, 0x4B, 0x51, 0x5A, -0x5B, 0x5E, 0x67, 0x7A, 0xED, 0xE8, 0xDB, 0xCF, 0xCB, 0xC5, 0xBD, 0xB9, 0xB6, 0xB2, 0xB0, 0xB4, -0xB9, 0xBF, 0xCD, 0xFC, 0x49, 0x3B, 0x37, 0x33, 0x31, 0x32, 0x33, 0x38, 0x3E, 0x45, 0x4F, 0x5F, -0x74, 0xF0, 0xEF, 0xF1, 0xF4, 0xFF, 0x77, 0x72, 0xFB, 0xE4, 0xD9, 0xCE, 0xC3, 0xBA, 0xB6, 0xB2, -0xB0, 0xB2, 0xB6, 0xBB, 0xC8, 0xE4, 0x51, 0x3E, 0x38, 0x33, 0x2F, 0x2F, 0x31, 0x35, 0x3A, 0x3E, -0x49, 0x5D, 0xFE, 0xE4, 0xDD, 0xD9, 0xD9, 0xE1, 0xEB, 0xEE, 0xEE, 0xE7, 0xDD, 0xD2, 0xC7, 0xBD, -0xB9, 0xB5, 0xB2, 0xB5, 0xB8, 0xBB, 0xC6, 0xDA, 0x5F, 0x45, 0x3D, 0x37, 0x33, 0x31, 0x31, 0x35, -0x39, 0x3D, 0x45, 0x53, 0x6F, 0xE3, 0xD9, 0xD0, 0xCF, 0xD2, 0xD5, 0xD9, 0xD9, 0xD8, 0xD4, 0xCE, -0xC8, 0xC0, 0xBD, 0xB9, 0xB8, 0xBB, 0xBD, 0xC1, 0xCD, 0xDF, 0x5F, 0x4A, 0x41, 0x3B, 0x37, 0x36, -0x35, 0x36, 0x3A, 0x3D, 0x44, 0x4E, 0x5F, 0xEC, 0xDB, 0xD6, 0xD2, 0xD4, 0xD6, 0xDA, 0xDD, 0xDB, -0xD8, 0xD2, 0xCD, 0xC9, 0xC3, 0xBF, 0xBE, 0xBF, 0xC3, 0xC4, 0xCA, 0xD6, 0xED, 0x5E, 0x50, 0x48, -0x3F, 0x3C, 0x3B, 0x3A, 0x3A, 0x3D, 0x40, 0x4A, 0x55, 0x6A, 0xE6, 0xDC, 0xD8, 0xD6, 0xD8, 0xD8, -0xDB, 0xDE, 0xDF, 0xE2, 0xDE, 0xDC, 0xD9, 0xD0, 0xCB, 0xC8, 0xC8, 0xCC, 0xCD, 0xCD, 0xD1, 0xDB, -0xF2, 0x67, 0x5B, 0x51, 0x49, 0x44, 0x42, 0x41, 0x42, 0x44, 0x49, 0x4E, 0x55, 0x5C, 0x6A, 0x7E, -0xF3, 0xED, 0xED, 0xEF, 0xEC, 0xED, 0xF4, 0xF7, 0xF0, 0xEB, 0xE4, 0xDF, 0xDA, 0xD2, 0xCD, 0xCC, -0xCC, 0xCF, 0xCF, 0xCE, 0xD3, 0xDB, 0xE7, 0x7C, 0x69, 0x5E, 0x54, 0x4F, 0x4E, 0x4D, 0x4E, 0x4F, -0x52, 0x58, 0x5B, 0x5E, 0x63, 0x67, 0x6B, 0x6B, 0x6A, 0x6B, 0x6C, 0x6E, 0x6F, 0x73, 0x7D, 0xF3, -0xEA, 0xE1, 0xDC, 0xD8, 0xD3, 0xD1, 0xCF, 0xCE, 0xD1, 0xD2, 0xD2, 0xD6, 0xDB, 0xE2, 0xEF, 0xFD, -0x73, 0x66, 0x5F, 0x5C, 0x5A, 0x59, 0x58, 0x56, 0x56, 0x57, 0x57, 0x58, 0x58, 0x5A, 0x5C, 0x5D, -0x61, 0x65, 0x6A, 0x74, 0x7E, 0xF4, 0xEA, 0xE2, 0xDD, 0xDA, 0xD7, 0xD5, 0xD2, 0xD1, 0xD0, 0xD1, -0xD3, 0xD3, 0xD4, 0xD7, 0xDB, 0xE0, 0xE8, 0xEF, 0x7B, 0x69, 0x5F, 0x5B, 0x57, 0x53, 0x50, 0x4F, -0x4F, 0x4F, 0x4F, 0x50, 0x52, 0x56, 0x59, 0x5C, 0x60, 0x68, 0x6E, 0x7A, 0xFB, 0xF1, 0xEB, 0xE7, -0xE2, 0xDE, 0xDC, 0xDA, 0xD7, 0xD5, 0xD3, 0xD3, 0xD3, 0xD5, 0xD5, 0xD8, 0xDC, 0xE4, 0xF2, 0x78, -0x6A, 0x5E, 0x59, 0x55, 0x52, 0x50, 0x4F, 0x4F, 0x50, 0x52, 0x55, 0x58, 0x5A, 0x5D, 0x61, 0x64, -0x69, 0x6E, 0x74, 0xFF, 0xF6, 0xEE, 0xE9, 0xE4, 0xDF, 0xDC, 0xD8, 0xD5, 0xD2, 0xD0, 0xD1, 0xD1, -0xD2, 0xD6, 0xD7, 0xDA, 0xDF, 0xE8, 0xF8, 0x71, 0x69, 0x60, 0x5C, 0x58, 0x56, 0x54, 0x53, 0x53, -0x53, 0x55, 0x56, 0x58, 0x5A, 0x5C, 0x5F, 0x63, 0x69, 0x71, 0xFF, 0xEF, 0xEA, 0xE6, 0xE1, 0xDF, -0xDE, 0xDB, 0xDA, 0xDA, 0xD7, 0xD4, 0xD1, 0xD1, 0xD2, 0xD4, 0xD7, 0xD8, 0xDB, 0xE1, 0xED, 0x78, -0x69, 0x61, 0x5A, 0x53, 0x50, 0x4F, 0x4E, 0x4F, 0x4F, 0x51, 0x55, 0x59, 0x5D, 0x60, 0x65, 0x6C, -0x6F, 0x76, 0x7E, 0xFC, 0xF5, 0xF2, 0xF2, 0xED, 0xE7, 0xE1, 0xDD, 0xD9, 0xD4, 0xCE, 0xCB, 0xCA, -0xC8, 0xCA, 0xCF, 0xD0, 0xD7, 0xE6, 0x7C, 0x5E, 0x53, 0x4F, 0x4C, 0x4A, 0x4A, 0x4A, 0x4C, 0x4E, -0x4F, 0x51, 0x57, 0x5D, 0x62, 0x66, 0x69, 0x6D, 0x6D, 0x67, 0x63, 0x65, 0x6B, 0x70, 0x75, 0xFE, -0xEA, 0xDC, 0xD3, 0xCE, 0xC9, 0xC2, 0xBE, 0xBC, 0xBC, 0xC1, 0xC8, 0xCB, 0xDC, 0x69, 0x50, 0x46, -0x42, 0x3F, 0x3D, 0x3D, 0x3F, 0x43, 0x4B, 0x4F, 0x55, 0x61, 0x6F, 0xFC, 0xF0, 0xFA, 0xFD, 0x7B, -0x63, 0x5A, 0x54, 0x52, 0x54, 0x58, 0x62, 0x7D, 0xDE, 0xCC, 0xC4, 0xBC, 0xB6, 0xB1, 0xAE, 0xB2, -0xBA, 0xC1, 0xDA, 0x5A, 0x45, 0x38, 0x33, 0x32, 0x33, 0x36, 0x3A, 0x3E, 0x4B, 0x66, 0xEA, 0xD6, -0xCE, 0xCF, 0xD3, 0xE0, 0x6E, 0x5C, 0x51, 0x4D, 0x4B, 0x4A, 0x4F, 0x5B, 0x7A, 0xD6, 0xC6, 0xBA, -0xB1, 0xAE, 0xAA, 0xAA, 0xAF, 0xBA, 0xD1, 0x4E, 0x3D, 0x31, 0x2B, 0x2B, 0x2C, 0x30, 0x38, 0x3E, -0x4E, 0xEA, 0xCD, 0xC7, 0xC8, 0xCB, 0xCE, 0xDD, 0x64, 0x4F, 0x48, 0x48, 0x47, 0x46, 0x4D, 0x62, -0xDD, 0xCA, 0xBD, 0xB1, 0xAC, 0xA9, 0xA7, 0xAA, 0xB2, 0xC4, 0x51, 0x3A, 0x2F, 0x29, 0x28, 0x2A, -0x2E, 0x39, 0x45, 0x5A, 0xDB, 0xC8, 0xC2, 0xC5, 0xCD, 0xD5, 0xE8, 0x5B, 0x4C, 0x46, 0x47, 0x4C, -0x4E, 0x59, 0xF3, 0xD3, 0xC6, 0xBE, 0xB5, 0xAD, 0xAA, 0xA6, 0xA8, 0xB2, 0xC5, 0x54, 0x38, 0x2F, -0x28, 0x26, 0x2A, 0x2F, 0x3A, 0x4B, 0x73, 0xCF, 0xC5, 0xC4, 0xC9, 0xD9, 0xF8, 0x5F, 0x4C, 0x47, -0x47, 0x48, 0x4F, 0x5A, 0x74, 0xD9, 0xCE, 0xC7, 0xBF, 0xBA, 0xB0, 0xAC, 0xAA, 0xA9, 0xB0, 0xC5, -0x5C, 0x3B, 0x30, 0x2B, 0x27, 0x29, 0x2E, 0x39, 0x49, 0x6C, 0xD2, 0xC7, 0xC5, 0xCA, 0xDA, 0x7A, -0x5E, 0x4D, 0x48, 0x49, 0x4B, 0x52, 0x5E, 0x70, 0xDC, 0xCE, 0xC9, 0xC4, 0xBE, 0xB5, 0xAE, 0xAC, -0xAA, 0xAD, 0xBB, 0xE1, 0x43, 0x35, 0x2E, 0x29, 0x28, 0x2B, 0x32, 0x3D, 0x4E, 0x7E, 0xD2, 0xC9, -0xC7, 0xCC, 0xDF, 0xFE, 0x61, 0x4F, 0x4C, 0x4B, 0x4C, 0x54, 0x5D, 0x72, 0xDA, 0xCE, 0xC7, 0xC0, -0xB9, 0xB0, 0xAD, 0xAA, 0xAA, 0xB1, 0xC5, 0x5D, 0x3D, 0x33, 0x2C, 0x29, 0x29, 0x2D, 0x35, 0x3F, -0x4F, 0x78, 0xD7, 0xCA, 0xC7, 0xCD, 0xD9, 0xE3, 0x71, 0x5C, 0x54, 0x4D, 0x4E, 0x55, 0x5A, 0x6E, -0xE3, 0xD3, 0xC8, 0xBE, 0xB6, 0xAF, 0xAC, 0xAA, 0xAC, 0xB7, 0xCE, 0x53, 0x3D, 0x34, 0x2D, 0x2A, -0x2A, 0x2E, 0x35, 0x3E, 0x4A, 0x5C, 0xE5, 0xCD, 0xC8, 0xCB, 0xCE, 0xD5, 0xE2, 0xF7, 0x66, 0x57, -0x54, 0x56, 0x5B, 0x6E, 0xE7, 0xD5, 0xC9, 0xBE, 0xB6, 0xB1, 0xAE, 0xAE, 0xB4, 0xBE, 0xD3, 0x5C, -0x46, 0x3C, 0x34, 0x30, 0x2F, 0x32, 0x38, 0x3E, 0x45, 0x4E, 0x69, 0xDC, 0xCF, 0xCD, 0xCF, 0xD3, -0xD9, 0xDF, 0xEF, 0x6F, 0x68, 0x67, 0x6F, 0xF7, 0xE7, 0xDC, 0xD2, 0xC8, 0xC1, 0xBE, 0xBC, 0xBD, -0xC3, 0xCB, 0xD5, 0xEA, 0x6A, 0x58, 0x4D, 0x47, 0x43, 0x43, 0x44, 0x47, 0x4A, 0x4D, 0x52, 0x5D, -0x6D, 0x78, 0x77, 0x78, 0x76, 0x73, 0x75, 0x72, 0x72, 0x78, 0x7E, 0xF6, 0xEB, 0xE3, 0xDC, 0xD6, -0xD2, 0xCF, 0xCE, 0xCE, 0xCD, 0xCF, 0xD2, 0xD4, 0xD7, 0xDA, 0xDD, 0xE3, 0xEF, 0x7A, 0x6C, 0x65, -0x5F, 0x5B, 0x57, 0x53, 0x4F, 0x4E, 0x4D, 0x4C, 0x4A, 0x4A, 0x4A, 0x4B, 0x4D, 0x4F, 0x53, 0x59, -0x5F, 0x6C, 0xFE, 0xEC, 0xE3, 0xDE, 0xDC, 0xDA, 0xD9, 0xD8, 0xD7, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, -0xD8, 0xDA, 0xDC, 0xDE, 0xE3, 0xEC, 0xFB, 0x6F, 0x63, 0x5B, 0x55, 0x4F, 0x4D, 0x4C, 0x4B, 0x4C, -0x4C, 0x4D, 0x4F, 0x53, 0x58, 0x5E, 0x67, 0x73, 0xFB, 0xEE, 0xE8, 0xE3, 0xDF, 0xDC, 0xDA, 0xD9, -0xD8, 0xD8, 0xD8, 0xD9, 0xDB, 0xDD, 0xDF, 0xE1, 0xE5, 0xE9, 0xEE, 0xF6, 0x7C, 0x6E, 0x66, 0x5F, -0x5C, 0x5A, 0x58, 0x56, 0x56, 0x57, 0x58, 0x5A, 0x5D, 0x60, 0x66, 0x6D, 0x74, 0x7C, 0xFB, 0xF4, -0xEE, 0xEA, 0xE7, 0xE5, 0xE4, 0xE4, 0xE4, 0xE7, 0xEA, 0xEC, 0xED, 0xED, 0xEC, 0xED, 0xEC, 0xED, -0xEE, 0xF1, 0xF9, 0x7F, 0x79, 0x75, 0x70, 0x6D, 0x6C, 0x6C, 0x6E, 0x73, 0x79, 0xFE, 0xF9, 0xF3, -0xEE, 0xEB, 0xE9, 0xE8, 0xE6, 0xE5, 0xE6, 0xE8, 0xEA, 0xED, 0xF1, 0xF8, 0xFD, 0x7E, 0x7E, 0xFE, -0xFC, 0xF9, 0xF5, 0xF5, 0xF6, 0xFB, 0x7C, 0x77, 0x71, 0x6E, 0x6C, 0x6A, 0x69, 0x69, 0x6B, 0x6E, -0x70, 0x75, 0x7A, 0xFE, 0xF6, 0xF1, 0xEE, 0xEC, 0xEB, 0xEB, 0xEC, 0xEE, 0xF1, 0xF5, 0xFB, 0x7D, -0x7B, 0x7A, 0x7C, 0xFE, 0xFA, 0xF4, 0xF1, 0xF0, 0xF0, 0xF3, 0xF7, 0xFB, 0xFD, 0xFF, 0xFF, 0x7F, -0x7F, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0xFD, 0xFC, 0xFA, 0xF5, 0xF4, 0xF1, 0xEF, 0xEF, 0xEF, 0xF0, -0xF4, 0xF8, 0xFD, 0x7D, 0x78, 0x77, 0x78, 0x7A, 0x7C, 0x7C, 0x7E, 0x7C, 0x7A, 0x79, 0x76, 0x77, -0x78, 0x77, 0x7B, 0x7E, 0xFF, 0xFD, 0xFD, 0xFE, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0x7E, 0xFE, 0xFB, -0xFA, 0xF9, 0xFA, 0xFB, 0xFE, 0x7F, 0x7C, 0x79, 0x78, 0x77, 0x77, 0x7A, 0x7C, 0x7D, 0x7E, 0x7B, -0x77, 0x74, 0x71, 0x6F, 0x6E, 0x6E, 0x6F, 0x6F, 0x70, 0x71, 0x73, 0x74, 0x76, 0x76, 0x75, 0x76, -0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x77, 0x74, 0x72, 0x70, 0x6F, 0x6E, 0x6E, 0x6E, 0x70, 0x74, -0x78, 0x7B, 0x7D, 0x7D, 0x7C, 0x7C, 0x7A, 0x76, 0x72, 0x71, 0x70, 0x70, 0x70, 0x71, 0x72, 0x72, -0x74, 0x76, 0x78, 0x7B, 0x7F, 0xFE, 0xFC, 0xF9, 0xF6, 0xF5, 0xF7, 0xFC, 0xFF, 0x7C, 0x79, 0x78, -0x77, 0x77, 0x77, 0x7A, 0x7E, 0xFE, 0xFC, 0xFA, 0xF8, 0xF8, 0xFA, 0xFC, 0xFE, 0x7D, 0x7A, 0x76, -0x74, 0x74, 0x73, 0x75, 0x76, 0x76, 0x78, 0x7A, 0x7C, 0x7E, 0xFF, 0xFB, 0xF9, 0xF8, 0xF9, 0xFD, -0x7E, 0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x78, 0x7C, 0x7F, 0xFB, 0xF6, 0xF5, 0xF2, 0xF2, 0xF3, -0xF4, 0xF7, 0xF8, 0xFA, 0xFC, 0xFE, 0xFF, 0xFF, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFA, -0xF7, 0xF6, 0xF8, 0xFC, 0x7F, 0x7C, 0x79, 0x72, 0x6F, 0x6E, 0x6E, 0x6E, 0x6F, 0x73, 0x77, 0x77, -0x7B, 0x7D, 0x7E, 0x7F, 0x7E, 0x7C, 0x7A, 0x77, 0x75, 0x71, 0x6F, 0x6E, 0x6D, 0x6E, 0x6F, 0x70, -0x73, 0x74, 0x77, 0x79, 0x7C, 0x7D, 0x7D, 0x7D, 0x7B, 0x7A, 0x79, 0x76, 0x73, 0x70, 0x6F, 0x71, -0x73, 0x78, 0x7B, 0x7F, 0xFB, 0xF8, 0xF5, 0xF3, 0xF5, 0xF6, 0xF6, 0xF8, 0xF9, 0xFC, 0xFE, 0xFF, -0x7F, 0xFF, 0xFD, 0xFC, 0xFC, 0xFB, 0xF7, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF6, 0xF7, 0xF9, -0xFA, 0xFC, 0xFF, 0xFF, 0x7F, 0x7F, 0xFE, 0xFD, 0xFE, 0xFD, 0xFB, 0xFB, 0xFC, 0xFE, 0x7E, 0x7C, -0x7A, 0x79, 0x77, 0x76, 0x77, 0x77, 0x78, 0x78, 0x79, 0x7C, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, -0x7D, 0x7E, 0x7C, 0x7E, 0x7F, 0x7E, 0x7E, 0xFF, 0xFD, 0xFC, 0xFB, 0xF8, 0xF8, 0xFA, 0xFA, 0xFC, -0xFE, 0x7D, 0x78, 0x75, 0x72, 0x70, 0x70, 0x73, 0x75, 0x76, 0x78, 0x79, 0x79, 0x7A, 0x79, 0x78, -0x77, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x79, 0x7A, 0x7B, 0x7D, 0x7F, 0xFC, 0xF8, 0xF6, -0xF4, 0xF2, 0xF3, 0xF7, 0xF9, 0xFB, 0x7E, 0x78, 0x75, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x74, -0x75, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x78, 0x78, 0x78, 0x77, 0x75, 0x75, 0x76, 0x79, 0x7B, -0x7C, 0x7E, 0xFE, 0xFC, 0xF9, 0xF6, 0xF5, 0xF6, 0xF7, 0xF9, 0xFC, 0xFE, 0x7C, 0x79, 0x77, 0x76, -0x75, 0x74, 0x74, 0x75, 0x74, 0x76, 0x77, 0x78, 0x79, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x78, 0x78, -0x77, 0x76, 0x77, 0x77, 0x77, 0x78, 0x7A, 0x7C, 0xFF, 0xFD, 0xFA, 0xF8, 0xF6, 0xF7, 0xF8, 0xF7, -0xF8, 0xF8, 0xF8, 0xF9, 0xFA, 0xF9, 0xF9, 0xFA, 0xFB, 0xFB, 0xFB, 0xFD, 0xFD, 0xFC, 0xFD, 0xFE, -0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7B, 0x7A, 0x79, 0x79, 0x79, 0x78, 0x79, 0x7B, 0x7C, 0x7C, 0x7C, -0x7C, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x71, 0x70, 0x6F, 0x6F, 0x6E, -0x6D, 0x6C, 0x6C, 0x6D, 0x6E, 0x6E, 0x6E, 0x6F, 0x6E, 0x6F, 0x70, 0x70, 0x72, 0x75, 0x78, 0x7B, -0x7B, 0x7C, 0x7D, 0xFF, 0xFD, 0xFC, 0xFA, 0xFA, 0xF9, 0xF7, 0xF7, 0xF7, 0xF7, 0xF8, 0xF8, 0xF9, -0xFA, 0xFA, 0xFA, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFB, -0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFF, 0x7F, 0xFC, 0xFA, 0xFB, 0xFA, 0xFA, 0xF9, -0xFA, 0xFC, 0xFC, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, 0xFE, 0xFD, 0xFC, 0xFD, 0xFA, 0xFA, 0xF9, 0xF8, -0xFA, 0xF8, 0xFA, 0xFA, 0xFB, 0xFE, 0xFB, 0xFF, 0xFD, 0xFD, 0xFF, 0xFB, 0xFF, 0xFA, 0xFC, 0x7F, -0xFC, 0x70, 0x6A, 0x64, 0x61, 0x67, 0x6C, 0x73, 0x61, 0x60, 0x5A, 0x47, 0x53, 0xDF, 0x7D, 0x6F, -0x71, 0x69, 0x7F, 0x72, 0x70, 0x68, 0x5A, 0x5B, 0x59, 0x55, 0x5A, 0x5D, 0x4E, 0x46, 0x51, 0x77, -0xF6, 0xEC, 0xE8, 0xE6, 0xE5, 0xE4, 0xE1, 0xE5, 0xFD, 0x60, 0x65, 0xE6, 0xDB, 0xDD, 0xE1, 0xE4, -0xE2, 0xDC, 0xD4, 0xCF, 0xCF, 0xCF, 0xD1, 0xD2, 0xCF, 0xCD, 0xCC, 0xCD, 0xD0, 0xD4, 0xD7, 0xD5, -0xCE, 0xCD, 0xD3, 0xD9, 0xDB, 0xDA, 0xD9, 0xDC, 0xE2, 0xE5, 0xF1, 0xEE, 0xD7, 0xD2, 0xD9, 0xDC, -0xDD, 0xD9, 0xDC, 0xE7, 0xDF, 0xD9, 0xDD, 0x74, 0x62, 0xFC, 0xE9, 0xF2, 0x6C, 0x5D, 0x5D, 0x61, -0x6B, 0x6C, 0x5C, 0x5D, 0x70, 0x64, 0x5B, 0x6D, 0x78, 0x61, 0x57, 0x58, 0x65, 0x62, 0x53, 0x51, -0x69, 0xF5, 0x59, 0x53, 0x69, 0x68, 0x54, 0x4F, 0x67, 0xFA, 0x5B, 0x58, 0x5D, 0x60, 0x5D, 0x4E, -0x53, 0x61, 0x5A, 0x5F, 0x63, 0x61, 0x5E, 0x4C, 0x4C, 0x5A, 0x6B, 0xF7, 0x58, 0x47, 0x51, 0x6D, -0x68, 0x5A, 0x55, 0x53, 0x4A, 0x4E, 0xEE, 0xE1, 0x56, 0x46, 0x4D, 0x74, 0x70, 0x59, 0x53, 0x4C, -0x4E, 0x62, 0xF2, 0xF3, 0x5A, 0x4A, 0x4F, 0x6D, 0x6B, 0x57, 0x63, 0xED, 0x79, 0x69, 0x62, 0x5D, -0x6C, 0x67, 0x5E, 0xF5, 0xEA, 0x69, 0x63, 0x76, 0xFA, 0x6A, 0x59, 0x5D, 0xFB, 0xF6, 0x72, 0xFB, -0x71, 0x5D, 0x65, 0x7D, 0xFC, 0x79, 0xFB, 0xE9, 0xE2, 0xDD, 0xE3, 0xF9, 0xFA, 0xF3, 0xEA, 0xEC, -0x7D, 0xF1, 0xE5, 0xF2, 0x78, 0x6D, 0x6D, 0xED, 0xE4, 0xE5, 0xE4, 0xF6, 0x7A, 0xF8, 0xE5, 0xDC, -0xEA, 0xDF, 0xCF, 0xD3, 0xE7, 0x6C, 0x78, 0xCF, 0xC9, 0xD5, 0x7E, 0x64, 0x7E, 0xD7, 0xCF, 0xD7, -0xE0, 0xE8, 0xDC, 0xCB, 0xC5, 0xCC, 0xE6, 0x73, 0xE9, 0xD2, 0xC9, 0xCA, 0xD3, 0xED, 0x68, 0xF3, -0xD9, 0xDA, 0xDC, 0xDA, 0xD7, 0xDB, 0xE1, 0xE1, 0xEA, 0x69, 0x59, 0x60, 0xEE, 0xE0, 0xDC, 0xDF, -0xE5, 0xDD, 0xE1, 0xED, 0xED, 0xF4, 0xF6, 0xF2, 0xEE, 0xED, 0xFC, 0x6F, 0x64, 0x5C, 0x5C, 0x61, -0x76, 0xEA, 0xE1, 0xEB, 0x73, 0x66, 0x60, 0x69, 0xFB, 0x7E, 0x70, 0x76, 0xFF, 0x78, 0x73, 0xEB, -0xE2, 0x6F, 0x5C, 0x69, 0xE9, 0xDB, 0xDE, 0x73, 0x5E, 0x6D, 0xED, 0xEB, 0xF4, 0xFF, 0x77, 0xFD, -0xE7, 0xE2, 0xFB, 0x66, 0x69, 0xFE, 0xFA, 0x6B, 0x63, 0x69, 0x74, 0x74, 0x66, 0x63, 0x6F, 0xFB, -0xFD, 0x73, 0x71, 0x7B, 0xF4, 0xE8, 0xE2, 0xE8, 0xF2, 0xEB, 0xDE, 0xDC, 0xDE, 0xE2, 0xE7, 0xE5, -0xDF, 0xDF, 0xE8, 0xFC, 0x6D, 0x6A, 0x66, 0x5C, 0x53, 0x51, 0x56, 0x5B, 0x59, 0x56, 0x56, 0x5A, -0x5E, 0x5A, 0x53, 0x53, 0x59, 0x5D, 0x5F, 0x64, 0x74, 0xE9, 0xD6, 0xCB, 0xCB, 0xD3, 0xDC, 0xD4, -0xC8, 0xC1, 0xBF, 0xBE, 0xBE, 0xC5, 0xCE, 0xDC, 0xEA, 0x68, 0x4B, 0x3E, 0x3B, 0x3B, 0x3D, 0x3E, -0x41, 0x45, 0x47, 0x48, 0x4A, 0x4C, 0x4A, 0x47, 0x49, 0x4F, 0x5E, 0x6D, 0xF5, 0xDB, 0xCC, 0xC5, -0xC1, 0xBF, 0xBE, 0xBC, 0xBA, 0xB7, 0xB2, 0xAF, 0xAE, 0xB7, 0xDA, 0x43, 0x38, 0x35, 0x32, 0x31, -0x33, 0x3A, 0x46, 0x54, 0x5D, 0x56, 0x4A, 0x44, 0x43, 0x46, 0x44, 0x3F, 0x40, 0x4B, 0x61, 0x7B, -0xFD, 0xE7, 0xD4, 0xCA, 0xC5, 0xBF, 0xBB, 0xB6, 0xB1, 0xAF, 0xAD, 0xAC, 0xAC, 0xB4, 0xD8, 0x3C, -0x2D, 0x2B, 0x2D, 0x2F, 0x37, 0x41, 0x54, 0x76, 0xFF, 0x68, 0x54, 0x46, 0x40, 0x44, 0x49, 0x4A, -0x49, 0x4C, 0x5C, 0xFB, 0xE9, 0xE5, 0xDB, 0xCE, 0xC8, 0xC3, 0xBE, 0xBA, 0xB6, 0xB1, 0xAE, 0xAB, -0xA9, 0xAB, 0xBD, 0x3F, 0x2A, 0x26, 0x2A, 0x31, 0x3A, 0x43, 0x58, 0xE9, 0xDB, 0xE8, 0x5E, 0x46, -0x3C, 0x3D, 0x48, 0x55, 0x56, 0x55, 0x61, 0xF3, 0xE8, 0xE6, 0xDC, 0xCF, 0xC9, 0xC0, 0xB9, 0xB4, -0xB3, 0xB3, 0xAF, 0xAA, 0xA8, 0xAF, 0x75, 0x2C, 0x22, 0x24, 0x2D, 0x3F, 0x56, 0x72, 0xE0, 0xCF, -0xD4, 0x59, 0x3F, 0x38, 0x38, 0x3E, 0x4C, 0x68, 0xE8, 0xE3, 0xEA, 0x7E, 0x67, 0x64, 0x79, 0xDC, -0xCB, 0xBF, 0xB7, 0xB1, 0xAF, 0xAE, 0xAC, 0xAA, 0xB1, 0x56, 0x29, 0x1F, 0x20, 0x2B, 0x45, 0xD1, -0xC4, 0xC7, 0xCB, 0xD8, 0x4B, 0x33, 0x2E, 0x34, 0x42, 0x6D, 0xCD, 0xC5, 0xC8, 0xD1, 0xE0, 0x69, -0x52, 0x52, 0x6D, 0xD4, 0xC6, 0xBB, 0xB1, 0xAC, 0xAB, 0xAA, 0xA8, 0xAE, 0x68, 0x28, 0x1D, 0x1E, -0x2B, 0x53, 0xBC, 0xB6, 0xBD, 0xCA, 0xE1, 0x4E, 0x33, 0x2A, 0x2C, 0x3B, 0x7D, 0xBF, 0xBB, 0xC1, -0xD5, 0xED, 0x6A, 0x4F, 0x4C, 0x58, 0x7E, 0xD6, 0xC7, 0xBB, 0xB2, 0xAD, 0xA9, 0xA6, 0xA9, 0xC3, -0x2D, 0x1D, 0x1B, 0x23, 0x41, 0xBC, 0xAF, 0xB5, 0xC2, 0xDE, 0x4F, 0x3B, 0x2D, 0x27, 0x2D, 0x49, -0xC3, 0xB5, 0xB9, 0xCB, 0x64, 0x54, 0x56, 0x51, 0x58, 0x75, 0xE3, 0xD1, 0xCA, 0xC1, 0xB6, 0xAB, -0xA6, 0xA3, 0xA6, 0xC0, 0x2B, 0x1C, 0x1A, 0x24, 0x4D, 0xB0, 0xAA, 0xB0, 0xC3, 0xF0, 0x46, 0x38, -0x2D, 0x28, 0x2B, 0x4C, 0xBC, 0xB2, 0xB6, 0xD1, 0x4B, 0x46, 0x4F, 0x58, 0x61, 0xEE, 0xE1, 0xDB, -0xCF, 0xCB, 0xBD, 0xAE, 0xA7, 0xA3, 0xA2, 0xB6, 0x2C, 0x1B, 0x19, 0x21, 0x52, 0xAB, 0xA5, 0xAE, -0xC9, 0x4F, 0x3B, 0x37, 0x32, 0x2A, 0x2A, 0x3D, 0xC9, 0xB2, 0xB1, 0xCA, 0x44, 0x3D, 0x49, 0x5F, -0xDD, 0xD8, 0x77, 0x6E, 0xED, 0xDB, 0xC7, 0xB7, 0xAB, 0xA5, 0xA3, 0xA6, 0xC8, 0x26, 0x1A, 0x1A, -0x27, 0xC5, 0xA4, 0xA3, 0xAF, 0xE9, 0x3B, 0x33, 0x34, 0x31, 0x2D, 0x31, 0x57, 0xBF, 0xB3, 0xBA, -0x78, 0x41, 0x3E, 0x4E, 0xDC, 0xCE, 0xD4, 0x78, 0x5B, 0x67, 0xDC, 0xC4, 0xB7, 0xAC, 0xA6, 0xA5, -0xA5, 0xBA, 0x2C, 0x1B, 0x19, 0x23, 0xD8, 0xA3, 0x9F, 0xAB, 0xDA, 0x34, 0x2D, 0x30, 0x33, 0x33, -0x37, 0x54, 0xC1, 0xB7, 0xBD, 0x6E, 0x41, 0x3D, 0x4A, 0xD8, 0xCA, 0xD0, 0xEB, 0x56, 0x54, 0x74, -0xCE, 0xBD, 0xAF, 0xA8, 0xA6, 0xA5, 0xAE, 0x3B, 0x1E, 0x19, 0x1E, 0x43, 0xA8, 0x9E, 0xA6, 0xC8, -0x33, 0x29, 0x2C, 0x32, 0x39, 0x3D, 0x4E, 0xCD, 0xBE, 0xC2, 0xFF, 0x40, 0x3D, 0x48, 0xE0, 0xC4, -0xCB, 0xEA, 0x4F, 0x48, 0x59, 0xD7, 0xBE, 0xB5, 0xAD, 0xA9, 0xA9, 0xA7, 0xB3, 0x34, 0x1D, 0x19, -0x20, 0xEE, 0xA2, 0x9D, 0xA8, 0x60, 0x2A, 0x26, 0x2D, 0x3B, 0x4A, 0x4E, 0x64, 0xCE, 0xC6, 0xCF, -0x57, 0x42, 0x47, 0x67, 0xCB, 0xC3, 0xD4, 0x5C, 0x48, 0x47, 0x63, 0xCA, 0xBA, 0xB2, 0xAE, 0xAC, -0xAC, 0xAB, 0xB3, 0x3D, 0x1F, 0x1B, 0x20, 0x51, 0xA5, 0x9E, 0xA8, 0x6C, 0x2A, 0x24, 0x2B, 0x3E, -0x5E, 0x6C, 0x66, 0xFA, 0xE0, 0xE4, 0x60, 0x4B, 0x4E, 0x71, 0xD2, 0xC8, 0xD8, 0x5A, 0x4A, 0x49, -0x6E, 0xC6, 0xB9, 0xB3, 0xB1, 0xAF, 0xAE, 0xAC, 0xAF, 0x48, 0x21, 0x1B, 0x1F, 0x4C, 0xA5, 0x9D, -0xA7, 0x64, 0x28, 0x23, 0x2C, 0x4A, 0xD6, 0xD9, 0x61, 0x59, 0x6C, 0xEF, 0xF8, 0x5B, 0x5B, 0xEE, -0xD5, 0xCD, 0xDB, 0x5C, 0x4D, 0x4C, 0x6E, 0xC8, 0xBB, 0xB8, 0xB8, 0xB6, 0xB3, 0xAD, 0xA8, 0xBC, -0x2D, 0x1D, 0x1B, 0x2B, 0xB7, 0x9F, 0xA1, 0xB9, 0x33, 0x23, 0x28, 0x3A, 0xEB, 0xCF, 0x77, 0x50, -0x56, 0x6E, 0xE2, 0x73, 0x55, 0x5D, 0xE6, 0xCF, 0xD9, 0x5B, 0x4B, 0x47, 0x59, 0xD2, 0xC3, 0xBD, -0xBD, 0xBC, 0xB6, 0xAE, 0xA9, 0xAB, 0x68, 0x24, 0x1B, 0x1E, 0x3C, 0xAA, 0x9E, 0xA6, 0xDE, 0x2A, -0x23, 0x2C, 0x47, 0xD1, 0xCE, 0x72, 0x55, 0x58, 0x6A, 0x78, 0x5D, 0x5B, 0xF9, 0xDA, 0xD3, 0xDE, -0x5A, 0x49, 0x4A, 0x5F, 0xD1, 0xC0, 0xBD, 0xBC, 0xB9, 0xB3, 0xAD, 0xA9, 0xB1, 0x3C, 0x1F, 0x1C, -0x24, 0xE1, 0xA4, 0x9F, 0xAD, 0x44, 0x26, 0x25, 0x32, 0x6E, 0xC3, 0xCD, 0x64, 0x4F, 0x4F, 0x62, -0x70, 0x5C, 0x68, 0xE1, 0xD4, 0xD3, 0xF6, 0x4E, 0x45, 0x4B, 0x78, 0xCA, 0xBE, 0xBC, 0xBC, 0xB8, -0xB3, 0xAC, 0xA9, 0xBC, 0x2F, 0x1E, 0x1C, 0x2A, 0xBC, 0xA0, 0xA1, 0xB7, 0x35, 0x24, 0x28, 0x3B, -0xD8, 0xC4, 0xDC, 0x53, 0x4B, 0x4F, 0x67, 0x6D, 0x65, 0xEA, 0xDB, 0xD5, 0xDA, 0x5E, 0x4B, 0x48, -0x53, 0xDB, 0xC4, 0xBD, 0xBD, 0xBB, 0xB5, 0xAE, 0xA8, 0xAB, 0x75, 0x25, 0x1B, 0x1E, 0x3D, 0xAA, -0x9E, 0xA6, 0xDC, 0x2B, 0x25, 0x2E, 0x4E, 0xCC, 0xCC, 0x66, 0x4B, 0x4C, 0x5A, 0x74, 0x6C, 0x6D, -0xDF, 0xD6, 0xD6, 0xED, 0x4D, 0x43, 0x46, 0x59, 0xD0, 0xBF, 0xBC, 0xBB, 0xB8, 0xB3, 0xAD, 0xA9, -0xB3, 0x38, 0x1E, 0x1B, 0x24, 0xCF, 0xA2, 0x9F, 0xAF, 0x3E, 0x26, 0x27, 0x36, 0x6A, 0xCD, 0xE6, -0x4F, 0x4D, 0x55, 0x6E, 0xEF, 0x63, 0x7B, 0xDA, 0xDB, 0xDF, 0x5F, 0x49, 0x47, 0x4F, 0xE8, 0xC5, -0xBD, 0xBC, 0xBB, 0xB6, 0xAF, 0xAA, 0xAA, 0xCD, 0x29, 0x1C, 0x1D, 0x34, 0xAE, 0x9F, 0xA4, 0xC7, -0x2E, 0x25, 0x2C, 0x41, 0xDB, 0xD2, 0x75, 0x5B, 0x59, 0x60, 0x6E, 0x5B, 0x5C, 0xDF, 0xD0, 0xD8, -0x74, 0x4B, 0x43, 0x4B, 0x6E, 0xCC, 0xBF, 0xBD, 0xBE, 0xBC, 0xB5, 0xAD, 0xA8, 0xAD, 0x4B, 0x22, -0x1C, 0x22, 0x65, 0xA6, 0x9F, 0xAC, 0x4C, 0x2A, 0x28, 0x33, 0x50, 0xDE, 0xF2, 0x65, 0x7C, 0xF8, -0x79, 0x5A, 0x4B, 0x5E, 0xD7, 0xCF, 0xD6, 0x5F, 0x45, 0x43, 0x4C, 0xFB, 0xC9, 0xBF, 0xBD, 0xBC, -0xB8, 0xB2, 0xAD, 0xAA, 0xB7, 0x38, 0x20, 0x1D, 0x29, 0xC6, 0xA5, 0xA4, 0xB8, 0x3C, 0x2A, 0x2C, -0x39, 0x53, 0x7F, 0x6F, 0x79, 0xE8, 0xF9, 0x61, 0x4D, 0x4B, 0xFF, 0xD0, 0xD3, 0xEC, 0x4F, 0x45, -0x49, 0x58, 0xDF, 0xC7, 0xBF, 0xBD, 0xBB, 0xB5, 0xAF, 0xA9, 0xAA, 0xCA, 0x2C, 0x1D, 0x1E, 0x36, -0xB1, 0xA2, 0xA8, 0xCE, 0x33, 0x2B, 0x30, 0x3E, 0x4F, 0x5A, 0x6D, 0xD8, 0xD2, 0xF5, 0x4F, 0x46, -0x54, 0xD4, 0xCA, 0xD7, 0x65, 0x48, 0x43, 0x4C, 0x61, 0xD7, 0xC4, 0xBF, 0xBD, 0xB7, 0xB1, 0xAD, -0xAA, 0xB0, 0x48, 0x23, 0x1D, 0x24, 0x5D, 0xAA, 0xA4, 0xB0, 0x56, 0x30, 0x2E, 0x34, 0x3E, 0x47, -0x52, 0xE3, 0xC9, 0xCE, 0x65, 0x45, 0x43, 0x6A, 0xCE, 0xCD, 0xDE, 0x58, 0x49, 0x49, 0x4F, 0x6D, -0xD1, 0xC0, 0xBB, 0xB6, 0xAF, 0xAE, 0xAA, 0xAB, 0xCF, 0x2B, 0x1D, 0x1E, 0x36, 0xB2, 0xA4, 0xA9, -0xC7, 0x3B, 0x2F, 0x31, 0x37, 0x3D, 0x46, 0x6E, 0xC7, 0xC5, 0xE5, 0x4C, 0x41, 0x50, 0xD5, 0xCB, -0xDF, 0x58, 0x4C, 0x49, 0x4E, 0x62, 0xE4, 0xC8, 0xBD, 0xB9, 0xB4, 0xAF, 0xAD, 0xA9, 0xB2, 0x41, -0x22, 0x1D, 0x26, 0xEB, 0xAA, 0xA6, 0xB3, 0x5D, 0x38, 0x32, 0x32, 0x34, 0x39, 0x4D, 0xCC, 0xBD, -0xC7, 0x60, 0x44, 0x47, 0x6D, 0xDC, 0xE2, 0xEF, 0x63, 0x58, 0x50, 0x4D, 0x5A, 0xDB, 0xC3, 0xBA, -0xB3, 0xAF, 0xAD, 0xAC, 0xAE, 0xD3, 0x2D, 0x1F, 0x20, 0x38, 0xB9, 0xA9, 0xAD, 0xC4, 0x4C, 0x39, -0x33, 0x30, 0x32, 0x3C, 0xFA, 0xBE, 0xBE, 0xD5, 0x51, 0x46, 0x4F, 0x6F, 0x7B, 0x65, 0x68, 0x76, -0x60, 0x54, 0x52, 0x61, 0xCF, 0xBF, 0xB7, 0xAE, 0xAC, 0xAB, 0xAB, 0xBC, 0x39, 0x22, 0x1E, 0x2B, -0xE7, 0xAF, 0xAC, 0xB6, 0xD1, 0x4E, 0x3A, 0x2F, 0x2D, 0x31, 0x45, 0xCC, 0xBC, 0xC2, 0xDA, 0x58, -0x4D, 0x55, 0x52, 0x52, 0x68, 0xED, 0xF4, 0x66, 0x55, 0x59, 0xEF, 0xCE, 0xBF, 0xB5, 0xAD, 0xAB, -0xAB, 0xAE, 0xCC, 0x31, 0x22, 0x22, 0x2F, 0xE8, 0xB6, 0xB1, 0xB8, 0xC4, 0x73, 0x3D, 0x2F, 0x2B, -0x2F, 0x3F, 0xDD, 0xC0, 0xBF, 0xC7, 0xD8, 0x73, 0x55, 0x46, 0x44, 0x53, 0x7B, 0xEE, 0xED, 0xF2, -0xED, 0xDC, 0xCF, 0xC1, 0xB3, 0xAC, 0xA9, 0xA9, 0xB2, 0x58, 0x2C, 0x24, 0x28, 0x36, 0x5C, 0xC7, -0xBA, 0xB6, 0xB7, 0xCA, 0x49, 0x34, 0x2D, 0x2E, 0x37, 0x49, 0xE0, 0xC4, 0xBD, 0xBE, 0xC7, 0xEA, -0x4C, 0x42, 0x44, 0x49, 0x50, 0x69, 0xDD, 0xD0, 0xCB, 0xC6, 0xBD, 0xB3, 0xAD, 0xAB, 0xAB, 0xBA, -0x49, 0x2F, 0x2B, 0x2D, 0x32, 0x3A, 0x4B, 0xD6, 0xBC, 0xB6, 0xBD, 0xD7, 0x51, 0x3D, 0x36, 0x34, -0x37, 0x3E, 0x52, 0xDE, 0xC8, 0xC3, 0xC7, 0xCE, 0xDE, 0x72, 0x56, 0x4F, 0x53, 0x5D, 0xFF, 0xDA, -0xC9, 0xBD, 0xB7, 0xB4, 0xB2, 0xB6, 0xC6, 0x62, 0x47, 0x3F, 0x3D, 0x3B, 0x3B, 0x40, 0x4E, 0x6F, -0xEC, 0x7B, 0x67, 0x5E, 0x5B, 0x59, 0x55, 0x5A, 0x65, 0x5E, 0x5A, 0x5F, 0x61, 0x5E, 0x63, 0x65, -0x61, 0x6D, 0xF5, 0xFA, 0x7A, 0x77, 0x77, 0xFF, 0xEB, 0xDC, 0xD5, 0xCE, 0xCA, 0xC8, 0xC8, 0xCD, -0xD9, 0xEC, 0x76, 0x70, 0xFD, 0xED, 0xEA, 0xEE, 0x7D, 0x66, 0x59, 0x53, 0x50, 0x4F, 0x50, 0x54, -0x56, 0x58, 0x59, 0x5A, 0x5A, 0x5C, 0x5F, 0x6B, 0xF6, 0xE5, 0xE1, 0xE7, 0xEF, 0xF5, 0xF2, 0xEA, -0xDF, 0xD8, 0xCE, 0xC8, 0xC4, 0xC5, 0xCB, 0xD4, 0xDF, 0xE9, 0xE7, 0xE1, 0xDD, 0xDB, 0xDE, 0xEE, -0x68, 0x57, 0x4F, 0x4D, 0x4D, 0x4E, 0x4F, 0x4F, 0x52, 0x54, 0x53, 0x51, 0x53, 0x57, 0x5E, 0x6F, -0xFA, 0xEF, 0xEF, 0xF3, 0xF1, 0xF1, 0xEE, 0xE6, 0xDE, 0xD6, 0xCF, 0xCD, 0xCE, 0xD3, 0xDA, 0xDC, -0xDF, 0xDF, 0xD9, 0xD5, 0xD4, 0xD7, 0xE0, 0xFE, 0x6B, 0x5F, 0x5A, 0x58, 0x56, 0x54, 0x54, 0x53, -0x53, 0x50, 0x4E, 0x4F, 0x52, 0x56, 0x5C, 0x64, 0x67, 0x66, 0x69, 0x6C, 0x6D, 0x74, 0xFA, 0xEC, -0xDF, 0xD7, 0xD6, 0xDD, 0xE6, 0xF3, 0x7B, 0xF7, 0xE8, 0xDC, 0xD3, 0xD0, 0xD2, 0xD9, 0xE1, 0xE7, -0xEB, 0xF6, 0x7B, 0x74, 0x6F, 0x6B, 0x66, 0x5E, 0x59, 0x55, 0x53, 0x52, 0x56, 0x59, 0x5C, 0x61, -0x5F, 0x64, 0x65, 0x62, 0x6F, 0x7B, 0xFC, 0xE4, 0xDC, 0xD9, 0xE2, 0x7E, 0xFF, 0xFE, 0xFF, 0xEE, -0xDF, 0xD8, 0xD6, 0xD7, 0xDB, 0xDD, 0xDD, 0xE8, 0xE7, 0xE3, 0xEA, 0xE7, 0xF9, 0x72, 0x7C, 0x5F, -0x56, 0x58, 0x58, 0x56, 0x57, 0x57, 0x53, 0x54, 0x4A, 0x42, 0x4F, 0x67, 0x6A, 0xE0, 0xD4, 0xD8, -0xD7, 0xDD, 0xFD, 0xFE, 0xE4, 0x7B, 0xFF, 0xD9, 0xDF, 0xDE, 0xD7, 0xDA, 0xCF, 0xCF, 0xD3, 0xCD, -0xD3, 0xDF, 0xDD, 0xDE, 0xF3, 0x6D, 0x5F, 0x55, 0x54, 0x55, 0x51, 0x51, 0x50, 0x4F, 0x51, 0x53, -0x57, 0x59, 0x60, 0x73, 0xFB, 0xE7, 0xE1, 0xEA, 0xF4, 0x7D, 0x6D, 0x6F, 0x7F, 0x78, 0xF5, 0xE7, -0xEA, 0xE0, 0xDE, 0xD9, 0xCD, 0xCB, 0xC5, 0xC2, 0xC5, 0xCB, 0xDB, 0xDD, 0xEC, 0x53, 0x4C, 0x45, -0x42, 0x49, 0x48, 0x49, 0x4D, 0x51, 0x5A, 0x55, 0x55, 0x5D, 0x64, 0xF4, 0xED, 0xF5, 0xEB, 0xF2, -0x7A, 0x6D, 0x60, 0x5E, 0x6E, 0xF3, 0xF7, 0xE9, 0xDF, 0xDD, 0xD4, 0xCD, 0xC8, 0xC1, 0xBC, 0xB8, -0xB5, 0xB8, 0xC7, 0xF5, 0x52, 0x3E, 0x38, 0x37, 0x36, 0x3D, 0x4B, 0x59, 0xFD, 0xDF, 0xE3, 0xFE, -0x5C, 0x54, 0x52, 0x4E, 0x50, 0x55, 0x5D, 0xFF, 0xF2, 0xF1, 0xE9, 0xFB, 0xFD, 0x74, 0x5E, 0x62, -0x7A, 0xE3, 0xD2, 0xCA, 0xC0, 0xB9, 0xB1, 0xAD, 0xAE, 0xBC, 0x68, 0x3E, 0x31, 0x2D, 0x2E, 0x30, -0x3B, 0x5B, 0xD4, 0xC7, 0xC9, 0xD6, 0x65, 0x4A, 0x46, 0x3E, 0x3D, 0x47, 0x51, 0x7F, 0xD5, 0xD0, -0xCE, 0xD2, 0xE2, 0x6E, 0x57, 0x55, 0x61, 0xEA, 0xCD, 0xBE, 0xB7, 0xB2, 0xAD, 0xAB, 0xB0, 0xCE, -0x40, 0x2F, 0x2B, 0x2D, 0x2F, 0x38, 0x59, 0xCA, 0xBD, 0xBE, 0xCF, 0x70, 0x45, 0x39, 0x3A, 0x3B, -0x3F, 0x5D, 0xD9, 0xCB, 0xC4, 0xC5, 0xCF, 0xEA, 0x62, 0x52, 0x50, 0x5C, 0x7E, 0xD1, 0xBE, 0xB5, -0xAF, 0xAE, 0xAB, 0xAC, 0xC2, 0x44, 0x2F, 0x2A, 0x2D, 0x32, 0x38, 0x55, 0xC6, 0xBA, 0xBC, 0xCF, -0x5B, 0x40, 0x36, 0x34, 0x38, 0x40, 0x66, 0xCD, 0xC4, 0xC2, 0xC6, 0xD1, 0xFE, 0x52, 0x4C, 0x4F, -0x5C, 0xEF, 0xCF, 0xC1, 0xB7, 0xAF, 0xAD, 0xAB, 0xAD, 0xC9, 0x3C, 0x2D, 0x29, 0x2D, 0x35, 0x3D, -0xF1, 0xBD, 0xB8, 0xBF, 0xE1, 0x4C, 0x3C, 0x32, 0x31, 0x39, 0x47, 0xF7, 0xCB, 0xC4, 0xC2, 0xC7, -0xD9, 0x6F, 0x54, 0x4D, 0x4F, 0x5D, 0xEF, 0xCF, 0xC1, 0xB8, 0xAF, 0xAD, 0xAB, 0xAC, 0xC9, 0x3A, -0x2C, 0x29, 0x2D, 0x37, 0x44, 0xD8, 0xB9, 0xB7, 0xC4, 0x6C, 0x44, 0x38, 0x31, 0x30, 0x39, 0x4E, -0xDF, 0xCA, 0xC5, 0xC6, 0xCD, 0xEF, 0x5E, 0x5A, 0x53, 0x55, 0x64, 0xE8, 0xCD, 0xC4, 0xBB, 0xB0, -0xAC, 0xAA, 0xAC, 0xD0, 0x36, 0x2C, 0x2B, 0x2E, 0x39, 0x4A, 0xCB, 0xB6, 0xB7, 0xC8, 0x5D, 0x43, -0x39, 0x31, 0x32, 0x3D, 0x58, 0xD9, 0xCD, 0xCA, 0xC9, 0xD6, 0x73, 0x62, 0x63, 0x62, 0x68, 0x72, -0xE9, 0xCE, 0xC6, 0xBB, 0xAF, 0xAD, 0xAB, 0xAE, 0xD7, 0x38, 0x2D, 0x2C, 0x2F, 0x3B, 0x4F, 0xCA, -0xB6, 0xB8, 0xCB, 0x5D, 0x41, 0x39, 0x32, 0x33, 0x3E, 0x59, 0xDC, 0xCF, 0xCD, 0xCB, 0xD8, 0x63, -0x53, 0x5A, 0x5E, 0x61, 0x6F, 0xEA, 0xCF, 0xC6, 0xBC, 0xB0, 0xAD, 0xAB, 0xAE, 0xEE, 0x32, 0x2C, -0x2C, 0x30, 0x3B, 0x50, 0xC9, 0xB6, 0xB9, 0xCF, 0x5D, 0x47, 0x3A, 0x32, 0x33, 0x3F, 0x63, 0xDB, -0xD5, 0xCC, 0xC8, 0xD7, 0x66, 0x56, 0x58, 0x5C, 0x5A, 0x5B, 0x7E, 0xCE, 0xC4, 0xBB, 0xB0, 0xAD, -0xAB, 0xAF, 0x7B, 0x2F, 0x2C, 0x2E, 0x31, 0x39, 0x52, 0xC6, 0xB6, 0xBA, 0xD1, 0x5C, 0x4E, 0x3E, -0x32, 0x33, 0x3F, 0x64, 0xEA, 0xFD, 0xCE, 0xC2, 0xD0, 0x6C, 0x57, 0x5D, 0x64, 0x56, 0x53, 0x6C, -0xCE, 0xC4, 0xBD, 0xB1, 0xAD, 0xAA, 0xAE, 0x6F, 0x31, 0x2F, 0x31, 0x31, 0x37, 0x4F, 0xC5, 0xB6, -0xBA, 0xD2, 0xFC, 0x60, 0x45, 0x36, 0x35, 0x41, 0x56, 0xF8, 0xF2, 0xE4, 0xC6, 0xC8, 0x7C, 0x5A, -0x6A, 0x6A, 0x57, 0x52, 0x5B, 0xDA, 0xC6, 0xC0, 0xB6, 0xAE, 0xAA, 0xAC, 0xDD, 0x33, 0x30, 0x35, -0x31, 0x30, 0x42, 0xCE, 0xBA, 0xBA, 0xCC, 0xD9, 0xD9, 0x53, 0x3A, 0x35, 0x3E, 0x4D, 0x52, 0x60, -0xD6, 0xC5, 0xD2, 0x71, 0xE7, 0x7C, 0x55, 0x53, 0x51, 0x5B, 0xEE, 0xDC, 0xD3, 0xBE, 0xB2, 0xB0, -0xAD, 0xAE, 0x67, 0x31, 0x38, 0x39, 0x2F, 0x32, 0x49, 0xD5, 0xBE, 0xBF, 0xCF, 0xCD, 0xCA, 0x5C, -0x3D, 0x3C, 0x41, 0x41, 0x47, 0x5D, 0xE1, 0xC9, 0xC7, 0xD4, 0xDD, 0xFC, 0x51, 0x4C, 0x4C, 0x4C, -0x5F, 0xE2, 0xDC, 0xCA, 0xBF, 0xBD, 0xB9, 0xB5, 0xAF, 0xBA, 0x43, 0x35, 0x44, 0x3E, 0x2F, 0x36, -0x53, 0xD4, 0xC8, 0xCC, 0xD1, 0xC3, 0xC5, 0x5E, 0x41, 0x45, 0x49, 0x42, 0x44, 0x55, 0xE9, 0xD0, -0xD1, 0xDA, 0xD6, 0xD7, 0xFD, 0x5A, 0x58, 0x5B, 0x5A, 0x5B, 0x5F, 0x6C, 0x7A, 0xE1, 0xD3, 0xD2, -0xCC, 0xC8, 0xC4, 0xBF, 0xBD, 0xBA, 0xC2, 0x49, 0x3C, 0x4C, 0x41, 0x35, 0x3B, 0x52, 0xF3, 0xD6, -0xD1, 0xCE, 0xC3, 0xC6, 0x7A, 0x53, 0x57, 0x4E, 0x44, 0x46, 0x4F, 0x64, 0xE8, 0xDF, 0xDD, 0xD4, -0xD6, 0xEC, 0x56, 0x49, 0x54, 0x5E, 0x4F, 0x57, 0xFA, 0xE1, 0xDC, 0xE0, 0xE3, 0xD6, 0xD0, 0xDC, -0xD9, 0xC9, 0xC2, 0xBD, 0xC5, 0x58, 0x50, 0xE6, 0x4B, 0x37, 0x3F, 0x4F, 0x4D, 0x52, 0x6D, 0xDD, -0xC8, 0xC8, 0xDC, 0xDC, 0xD1, 0x72, 0x4A, 0x4A, 0x4E, 0x4B, 0x4E, 0x57, 0x6A, 0xDF, 0xD7, 0xDB, -0xD5, 0xCF, 0xDA, 0xF4, 0x74, 0x67, 0x5E, 0x5E, 0x5E, 0x66, 0xF9, 0xED, 0xEC, 0xE8, 0xE4, 0xE8, -0xF4, 0xF7, 0x60, 0x52, 0x6D, 0xF3, 0x5B, 0x66, 0xE7, 0xE1, 0xE0, 0xDF, 0xDF, 0xD8, 0xD1, 0xEA, -0x6B, 0xD9, 0xD1, 0xE5, 0xE6, 0xCC, 0xC4, 0xE7, 0x52, 0xEA, 0xE4, 0x4C, 0x48, 0x59, 0x5D, 0x59, -0x5D, 0x60, 0xF7, 0xDF, 0x79, 0x6A, 0xDF, 0xDC, 0xFE, 0xF8, 0xE2, 0xF0, 0x6F, 0x6B, 0x61, 0x5F, -0x62, 0x5D, 0x5E, 0x6C, 0x76, 0x70, 0xF7, 0xE5, 0xE6, 0xE7, 0xE5, 0xEA, 0xF4, 0x7D, 0x6C, 0x66, -0x68, 0x66, 0x66, 0x73, 0xF8, 0xF3, 0xF4, 0xF6, 0xFB, 0x7E, 0x7A, 0x7E, 0xF6, 0xEF, 0xED, 0xE9, -0xE9, 0xEF, 0xFB, 0x78, 0x6E, 0x69, 0x64, 0x63, 0x68, 0x6E, 0x74, 0x7B, 0xFA, 0xF6, 0xF3, 0xFF, -0x6B, 0x69, 0x69, 0x60, 0x5F, 0x65, 0x6C, 0x73, 0x7C, 0xF3, 0xEB, 0xE9, 0xEA, 0xE8, 0xE6, 0xE6, -0xE7, 0xE4, 0xDE, 0xDD, 0xE2, 0xE2, 0xE1, 0xE9, 0xF8, 0x77, 0x6B, 0x62, 0x5D, 0x5B, 0x5A, 0x59, -0x5A, 0x5B, 0x5D, 0x5E, 0x5E, 0x5E, 0x5F, 0x62, 0x67, 0x6D, 0x78, 0xFA, 0xF2, 0xEE, 0xEF, 0xF3, -0xF7, 0xF8, 0xFA, 0xFE, 0xFA, 0xF3, 0xF1, 0xEF, 0xEA, 0xE7, 0xE5, 0xE6, 0xE9, 0xEF, 0xFB, 0x79, -0x70, 0x6C, 0x6A, 0x6C, 0x6F, 0x77, 0x7C, 0xFD, 0xFB, 0x7F, 0x73, 0x6C, 0x69, 0x69, 0x6C, 0x73, -0xFA, 0xED, 0xE9, 0xE5, 0xE1, 0xE4, 0xE8, 0xE8, 0xE7, 0xE7, 0xE5, 0xE2, 0xE0, 0xDD, 0xDC, 0xE1, -0xE3, 0xE2, 0xEC, 0x7C, 0x6C, 0x63, 0x5D, 0x5B, 0x59, 0x58, 0x5A, 0x5B, 0x5B, 0x5C, 0x5F, 0x60, -0x5F, 0x60, 0x65, 0x6A, 0x75, 0xF8, 0xEC, 0xE7, 0xE6, 0xE7, 0xEA, 0xF0, 0xF8, 0xF9, 0xF4, 0xED, -0xE9, 0xE5, 0xE3, 0xE3, 0xE6, 0xEB, 0xF6, 0x76, 0x6C, 0x67, 0x62, 0x5F, 0x61, 0x64, 0x69, 0x6F, -0x73, 0x73, 0x75, 0x75, 0x70, 0x6E, 0x6F, 0x6E, 0x6E, 0x75, 0xFE, 0xF3, 0xEC, 0xE9, 0xE9, 0xE9, -0xED, 0xFA, 0x7A, 0x74, 0x71, 0x72, 0x73, 0x74, 0x7A, 0xFF, 0xFF, 0x7B, 0x72, 0x6E, 0x6D, 0x6C, -0x6C, 0x6E, 0x73, 0x7C, 0xFC, 0xF7, 0xF0, 0xEB, 0xE6, 0xE0, 0xDD, 0xDB, 0xDB, 0xDB, 0xDC, 0xDF, -0xE2, 0xE3, 0xE8, 0xF2, 0x7D, 0x6C, 0x61, 0x5D, 0x5A, 0x58, 0x59, 0x5C, 0x5E, 0x61, 0x66, 0x69, -0x6A, 0x6B, 0x6C, 0x6B, 0x6C, 0x75, 0xFE, 0xF7, 0xEE, 0xEA, 0xE8, 0xE6, 0xE9, 0xEC, 0xEB, 0xEB, -0xEE, 0xF0, 0xF2, 0xF6, 0xF9, 0xFD, 0x7F, 0xFF, 0x7C, 0x74, 0x6D, 0x69, 0x66, 0x64, 0x64, 0x68, -0x6B, 0x6D, 0x75, 0x7D, 0xFC, 0xF8, 0xFA, 0xFC, 0xFA, 0xF7, 0xF5, 0xF0, 0xEB, 0xE6, 0xE4, 0xE5, -0xE9, 0xED, 0xF2, 0xFC, 0x7A, 0x74, 0x6E, 0x6C, 0x6A, 0x69, 0x69, 0x6A, 0x6B, 0x6D, 0x6E, 0x6E, -0x6D, 0x6E, 0x70, 0x71, 0x74, 0x79, 0x7B, 0x7E, 0xFB, 0xF6, 0xF8, 0xF9, 0xF6, 0xF5, 0xF8, 0xFA, -0xF7, 0xF0, 0xEE, 0xF0, 0xF7, 0xFC, 0x7D, 0x73, 0x6C, 0x6B, 0x6B, 0x6A, 0x6B, 0x6B, 0x6B, 0x6B, -0x6C, 0x6D, 0x6D, 0x6E, 0x71, 0x71, 0x71, 0x72, 0x77, 0x7D, 0xFC, 0xF7, 0xF3, 0xED, 0xEB, 0xEB, -0xEE, 0xF4, 0xF9, 0xFE, 0x79, 0x77, 0x7B, 0x7F, 0x7F, 0xFF, 0xFF, 0x7B, 0x77, 0x76, 0x77, 0x79, -0x79, 0x7A, 0x7C, 0xFF, 0xFC, 0xFC, 0xFA, 0xF8, 0xF9, 0xF9, 0xFA, 0xFD, 0xFE, 0xFD, 0xFA, 0xF8, -0xF5, 0xF2, 0xF1, 0xF2, 0xF4, 0xF8, 0xFE, 0x7C, 0x79, 0x77, 0x77, 0x7A, 0x7E, 0x7F, 0x7C, 0x79, -0x78, 0x75, 0x73, 0x72, 0x71, 0x73, 0x75, 0x76, 0x78, 0x7D, 0xFD, 0xFB, 0xFC, 0xFF, 0x7D, 0x79, -0x76, 0x76, 0x77, 0x7C, 0xFB, 0xF5, 0xF3, 0xF3, 0xF3, 0xF7, 0x7D, 0x74, 0x6F, 0x6D, 0x6B, 0x6C, -0x6E, 0x73, 0x77, 0x77, 0x77, 0x7A, 0x7A, 0x76, 0x73, 0x72, 0x6F, 0x6D, 0x6B, 0x6C, 0x6F, 0x76, -0x7A, 0x7D, 0xFE, 0xFC, 0x7E, 0x7A, 0x75, 0x71, 0x6E, 0x6D, 0x6E, 0x71, 0x77, 0x7D, 0xFE, 0xFC, -0xFC, 0xFE, 0xFF, 0x7D, 0x7B, 0x7C, 0x7E, 0xFF, 0xFF, 0xFC, 0xF9, 0xF7, 0xF6, 0xF8, 0xFA, 0xFC, -0xFF, 0x7E, 0x7F, 0xFF, 0xFD, 0xFB, 0xF7, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFD, 0x7D, 0x7A, 0x7A, -0x7D, 0x7E, 0x7F, 0xFF, 0xFE, 0xFE, 0x7E, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0xFF, 0xFD, 0xFD, 0xFD, -0xFB, 0xF8, 0xF7, 0xF9, 0xFD, 0x7C, 0x79, 0x78, 0x78, 0x77, 0x77, 0x76, 0x75, 0x75, 0x75, 0x75, -0x75, 0x74, 0x76, 0x78, 0x79, 0x7B, 0x7D, 0x7F, 0xFD, 0xFB, 0xFF, 0x7A, 0x79, 0x7D, 0xFE, 0xFD, -0xFD, 0xFC, 0xFD, 0xFA, 0xF5, 0xF2, 0xF3, 0xF6, 0xF8, 0xF9, 0xFC, 0xFF, 0xFD, 0xF8, 0xF5, 0xF5, -0xF6, 0xFA, 0xFC, 0xFD, 0x7F, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x77, 0x7B, 0x7E, 0x7E, 0x7E, 0x7F, -0x7E, 0x7C, 0x79, 0x76, 0x76, 0x78, 0x79, 0x78, 0x7B, 0x7E, 0xFF, 0x7F, 0x7C, 0x7A, 0x78, 0x75, -0x73, 0x73, 0x74, 0x76, 0x77, 0x78, 0x7B, 0x7B, 0x79, 0x79, 0x78, 0x77, 0x78, 0x74, 0x71, 0x72, -0x73, 0x76, 0x77, 0x77, 0x79, 0x79, 0x77, 0x76, 0x75, 0x76, 0x78, 0x7B, 0x7F, 0xFC, 0xFB, 0xFB, -0xFA, 0xFB, 0xFE, 0x7C, 0x79, 0x79, 0x78, 0x78, 0x7B, 0xFF, 0xFD, 0xFD, 0xFC, 0xFC, 0xFE, 0x7E, -0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x78, 0x79, 0x7A, 0x7C, 0x7C, 0x7C, 0x7B, 0x77, 0x78, 0x7A, -0x7A, 0x7A, 0x7C, 0x7E, 0xFF, 0x7F, 0x7F, 0xFF, 0xFF, 0x7F, 0x7E, 0x7F, 0x7E, 0x7C, 0x7A, 0x7A, -0x79, 0x79, 0x7B, 0x7E, 0x7E, 0x7F, 0xFD, 0xFC, 0xFD, 0xFD, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, -0xFF, 0x7E, 0x7D, 0x7F, 0xFF, 0xFF, 0xFE, 0xFC, 0xFB, 0xFC, 0xFC, 0xFE, 0x7E, 0x7F, 0x7E, 0x7B, -0x7C, 0x7D, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x77, 0x7A, -0x7C, 0x7D, 0x7E, 0x7E, 0x7C, 0x79, 0x76, 0x77, 0x79, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0x7D, -0x7D, 0x7C, 0x7A, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x7C, 0x7E, 0x7D, 0x7E, 0x7E, 0x7C, 0x7B, 0x7C, -0x7C, 0x7C, 0x7D, 0xFF, 0xFC, 0xFB, 0xFB, 0xFC, 0xFF, 0x7C, 0x79, 0x77, 0x74, 0x75, 0x77, 0x7A, -0x7D, 0x7E, 0xFF, 0xFD, 0xFD, 0xFE, 0x7E, 0x7D, 0x7D, 0x7B, 0x7A, 0x7B, 0x7D, 0x7E, 0xFE, 0xFD, -0xFF, 0x7F, 0x7D, 0x7B, 0x7A, 0x78, 0x76, 0x76, 0x79, 0x7C, 0x7E, 0xFF, 0xFF, 0x7F, 0x7E, 0x7C, -0x7A, 0x79, 0x78, 0x78, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0x7F, 0x7E, 0x7D, 0x7B, 0x7A, -0x7B, 0x7C, 0x7D, 0xFE, 0xFC, 0xFA, 0xF9, 0xFA, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFA, 0xF8, 0xF7, -0xF6, 0xF7, 0xF9, 0xFB, 0xFE, 0x7E, 0x7C, 0x7A, 0x79, 0x79, 0x7B, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, -0x7E, 0x7C, 0x7B, 0x79, 0x7A, 0x7C, 0x7C, 0x7E, 0x7E, 0x7F, 0xFF, 0x7F, 0x7E, 0x7C, 0x7B, 0x79, -0x77, 0x76, 0x76, 0x78, 0x7B, 0x7B, 0x7B, 0x7A, 0x7A, 0x7A, 0x77, 0x77, 0x78, 0x78, 0x79, 0x7B, -0x7D, 0x79, 0x79, 0x7E, 0x79, 0x78, 0x79, 0x78, 0x7A, 0x78, 0x7D, 0x7D, 0x7C, 0xFF, 0x7D, 0x7F, -0x7E, 0x7B, 0x7A, 0x76, 0x79, 0x76, 0x78, 0x7B, 0x79, 0xFF, 0x7D, 0xFB, 0xFD, 0x7D, 0xF9, 0x7B, -0xFF, 0x79, 0x75, 0xFF, 0x6E, 0x7F, 0x71, 0x73, 0x79, 0x51, 0x60, 0xE2, 0x6F, 0x7D, 0xF7, 0xF5, -0x77, 0x72, 0xE4, 0x50, 0x4C, 0xDE, 0xFB, 0x66, 0xE5, 0xF6, 0x6F, 0x6C, 0xE7, 0xDC, 0x6E, 0xFD, -0xE6, 0x7E, 0xE9, 0x77, 0x62, 0xE3, 0xE9, 0x6C, 0x71, 0xEA, 0xDE, 0x75, 0x7E, 0xE8, 0x75, 0xF8, -0x7A, 0xFC, 0xF2, 0x65, 0xF8, 0xEE, 0xF9, 0xF4, 0x73, 0xE4, 0xF9, 0x6E, 0xE5, 0x75, 0x67, 0x5A, -0x50, 0x57, 0x5A, 0x7D, 0x6C, 0x64, 0xDA, 0xED, 0x64, 0xEA, 0xE9, 0xF5, 0x7E, 0x6F, 0xFC, 0xF2, -0x66, 0x63, 0xF7, 0x7D, 0x78, 0xF6, 0xF8, 0xE1, 0xE2, 0xF9, 0xEB, 0xE4, 0xED, 0xFE, 0xFA, 0xF6, -0xF1, 0xF2, 0x6F, 0xFE, 0xE8, 0xFF, 0x7F, 0xEA, 0xE8, 0xED, 0xEE, 0xEA, 0xEB, 0xED, 0xF8, 0xEF, -0xE8, 0x7F, 0xF5, 0xE6, 0xF7, 0xF2, 0xF3, 0xF2, 0xDF, 0xEB, 0xF5, 0xE3, 0xEC, 0xF2, 0xEF, 0xFC, -0xED, 0xEF, 0xFD, 0xED, 0xF0, 0x7C, 0x77, 0xFE, 0xF1, 0x77, 0x79, 0xEF, 0xF6, 0xF8, 0xFB, 0x72, -0x75, 0x79, 0x78, 0x70, 0x6E, 0x7C, 0x7D, 0x74, 0x79, 0x77, 0x6E, 0x71, 0x7D, 0x6F, 0x6B, 0x7D, -0xFE, 0x76, 0x7A, 0x7D, 0x7F, 0x75, 0x6C, 0x7B, 0xF7, 0x7A, 0x7B, 0x7E, 0x74, 0x79, 0x75, 0x70, -0x7C, 0x79, 0xFD, 0xF6, 0x6E, 0x6E, 0x7B, 0x6B, 0x67, 0x6D, 0x6E, 0x6A, 0x67, 0x6A, 0x6D, 0x6F, -0x6B, 0x67, 0x6D, 0x6C, 0x65, 0x63, 0x5E, 0x65, 0x6A, 0x5F, 0x68, 0x6C, 0x60, 0x6C, 0x7D, 0x6D, -0x6E, 0x7D, 0x7C, 0xFF, 0xEE, 0xEB, 0xEC, 0xE3, 0xDE, 0xE1, 0xE4, 0xE0, 0xE8, 0xF8, 0xEE, 0xFA, -0x6D, 0x69, 0x5C, 0x58, 0x59, 0x53, 0x50, 0x4E, 0x4D, 0x4E, 0x4F, 0x4F, 0x53, 0x51, 0x51, 0x54, -0x55, 0x56, 0x5A, 0x5E, 0x69, 0xF7, 0xE2, 0xD8, 0xCF, 0xCE, 0xCD, 0xCC, 0xCE, 0xCE, 0xCA, 0xC7, -0xC2, 0xBF, 0xBE, 0xBD, 0xC2, 0xD5, 0xF1, 0x62, 0x4B, 0x3F, 0x3D, 0x3D, 0x3E, 0x40, 0x42, 0x4A, -0x51, 0x51, 0x51, 0x55, 0x56, 0x4F, 0x4D, 0x4E, 0x50, 0x52, 0x55, 0x5C, 0x69, 0xFA, 0xE4, 0xD9, -0xCD, 0xC9, 0xC5, 0xC1, 0xBF, 0xBB, 0xBB, 0xBD, 0xB9, 0xB7, 0xB5, 0xB7, 0xC8, 0xDD, 0x61, 0x43, -0x3C, 0x38, 0x38, 0x3D, 0x40, 0x46, 0x4E, 0x5A, 0x60, 0x5D, 0x5B, 0x5B, 0x5A, 0x58, 0x56, 0x58, -0x5C, 0x5E, 0x5E, 0x64, 0x6B, 0x6D, 0xF9, 0xED, 0xE5, 0xDC, 0xD9, 0xD2, 0xCC, 0xC5, 0xBF, 0xBF, -0xBA, 0xB7, 0xB6, 0xB1, 0xB7, 0xCB, 0xFA, 0x49, 0x3A, 0x35, 0x31, 0x33, 0x3A, 0x42, 0x4C, 0x5C, -0xFD, 0xE1, 0xEE, 0x68, 0x66, 0x5C, 0x51, 0x4F, 0x4D, 0x55, 0x5F, 0x5D, 0x64, 0x71, 0xFA, 0xED, -0xEF, 0xEB, 0xDE, 0xD3, 0xCC, 0xC3, 0xBE, 0xBD, 0xB9, 0xB8, 0xB5, 0xAF, 0xB7, 0xCC, 0x60, 0x3F, -0x39, 0x34, 0x2F, 0x31, 0x3A, 0x47, 0x56, 0x6F, 0xE3, 0xDA, 0xD5, 0xEC, 0x56, 0x50, 0x4E, 0x4B, -0x4B, 0x4C, 0x57, 0x7B, 0xE7, 0xE0, 0xDC, 0xD5, 0xD6, 0xDE, 0xEC, 0xEF, 0xDE, 0xD7, 0xCC, 0xC1, -0xBD, 0xB8, 0xB5, 0xB4, 0xB0, 0xB6, 0xCB, 0x58, 0x3E, 0x38, 0x34, 0x2F, 0x2F, 0x38, 0x45, 0x59, -0x7D, 0xDD, 0xD1, 0xCE, 0xDD, 0x63, 0x53, 0x4E, 0x4C, 0x4A, 0x4B, 0x53, 0x69, 0xE7, 0xDB, 0xD5, -0xD0, 0xCE, 0xD3, 0xDC, 0xE4, 0xEA, 0xE8, 0xE2, 0xD5, 0xC8, 0xC0, 0xBB, 0xB8, 0xB5, 0xB2, 0xB9, -0xD1, 0x54, 0x40, 0x3A, 0x34, 0x2F, 0x2F, 0x36, 0x3F, 0x4C, 0x5B, 0x7E, 0xDE, 0xD4, 0xDB, 0xFF, -0x62, 0x58, 0x55, 0x53, 0x4F, 0x52, 0x5D, 0x6F, 0xF0, 0xE4, 0xDE, 0xDA, 0xD8, 0xDC, 0xE1, 0xE5, -0xDF, 0xDC, 0xD6, 0xCC, 0xC6, 0xC1, 0xBE, 0xBB, 0xB8, 0xBC, 0xCE, 0x67, 0x4B, 0x44, 0x3E, 0x38, -0x35, 0x37, 0x3D, 0x45, 0x4B, 0x53, 0x61, 0xFA, 0xE4, 0xEC, 0x7F, 0x79, 0x78, 0x79, 0x70, 0x68, -0x68, 0x70, 0x7B, 0x7D, 0x7D, 0xF9, 0xEE, 0xEA, 0xE8, 0xE6, 0xE1, 0xDB, 0xD6, 0xCF, 0xCB, 0xC8, -0xC5, 0xC1, 0xBE, 0xBF, 0xC7, 0xD5, 0xF9, 0x5F, 0x55, 0x4A, 0x42, 0x3E, 0x3E, 0x41, 0x45, 0x48, -0x4C, 0x56, 0x5F, 0x6F, 0xF8, 0xEF, 0xE7, 0xE4, 0xE6, 0xE2, 0xEA, 0xF5, 0xFD, 0x75, 0x75, 0x79, -0x75, 0x76, 0x7E, 0xFA, 0xF1, 0xE9, 0xE0, 0xDA, 0xD3, 0xCF, 0xCC, 0xCA, 0xC7, 0xC4, 0xC5, 0xCC, -0xD3, 0xDF, 0xFF, 0x69, 0x58, 0x4C, 0x47, 0x43, 0x42, 0x42, 0x43, 0x46, 0x4C, 0x55, 0x59, 0x62, -0x77, 0xFD, 0xEE, 0xEC, 0xF3, 0xEC, 0xF2, 0x76, 0x76, 0x6F, 0x6E, 0x79, 0x79, 0x7F, 0xF3, 0xED, -0xE4, 0xDD, 0xDB, 0xD7, 0xD3, 0xD0, 0xCE, 0xCC, 0xCB, 0xCA, 0xCC, 0xD1, 0xD6, 0xDD, 0xEA, 0x7E, -0x62, 0x56, 0x4F, 0x4C, 0x49, 0x48, 0x49, 0x4C, 0x50, 0x56, 0x58, 0x5C, 0x67, 0x6F, 0x6C, 0x6E, -0x6D, 0x6A, 0x6F, 0x6D, 0x6B, 0x6E, 0x6D, 0x76, 0xFA, 0xF9, 0xF1, 0xEB, 0xE7, 0xE1, 0xDE, 0xDD, -0xDB, 0xD8, 0xD7, 0xD4, 0xD2, 0xD0, 0xCF, 0xD4, 0xD8, 0xDA, 0xDF, 0xEA, 0xF8, 0x6D, 0x60, 0x5C, -0x58, 0x56, 0x56, 0x56, 0x57, 0x59, 0x5B, 0x5B, 0x5A, 0x5C, 0x5F, 0x5F, 0x5F, 0x63, 0x66, 0x6B, -0x72, 0x77, 0x7E, 0xF7, 0xF0, 0xEC, 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xEA, 0xE7, 0xE6, 0xE5, -0xE3, 0xE1, 0xDD, 0xDA, 0xD9, 0xD8, 0xDD, 0xDF, 0xDD, 0xE0, 0xE7, 0xEE, 0xFE, 0x74, 0x6C, 0x62, -0x5C, 0x59, 0x56, 0x54, 0x52, 0x51, 0x51, 0x52, 0x55, 0x58, 0x59, 0x5D, 0x62, 0x68, 0x70, 0x75, -0x7D, 0xF9, 0xF8, 0xF4, 0xF5, 0xF9, 0xF5, 0xF3, 0xF3, 0xF2, 0xF2, 0xEF, 0xED, 0xEB, 0xEA, 0xE6, -0xE3, 0xE0, 0xDC, 0xDA, 0xD7, 0xD8, 0xDB, 0xDB, 0xDA, 0xDC, 0xDF, 0xE8, 0xF6, 0x7F, 0x6E, 0x60, -0x5B, 0x58, 0x56, 0x54, 0x53, 0x52, 0x53, 0x59, 0x5C, 0x5E, 0x63, 0x68, 0x6F, 0x7B, 0x7C, 0xFF, -0xFC, 0xFC, 0xFB, 0xFC, 0xFD, 0xF8, 0xF7, 0xF6, 0xF4, 0xF5, 0xF3, 0xF0, 0xEF, 0xED, 0xEB, 0xE8, -0xE4, 0xE0, 0xDD, 0xDA, 0xD9, 0xDA, 0xDC, 0xDC, 0xDC, 0xE0, 0xE9, 0xF8, 0x76, 0x6B, 0x61, 0x5C, -0x5A, 0x5A, 0x5A, 0x5B, 0x5C, 0x5E, 0x62, 0x67, 0x6B, 0x6D, 0x6F, 0x72, 0x75, 0x76, 0x76, 0x75, -0x74, 0x79, 0x7E, 0x7B, 0x78, 0x7D, 0xFB, 0xFB, 0xFD, 0xFA, 0xF6, 0xF5, 0xF2, 0xEF, 0xEC, 0xE9, -0xE4, 0xDF, 0xDE, 0xDE, 0xE0, 0xE7, 0xEA, 0xEC, 0xF2, 0xFE, 0x76, 0x6F, 0x6F, 0x6D, 0x6A, 0x6A, -0x6B, 0x6C, 0x6C, 0x69, 0x67, 0x67, 0x66, 0x65, 0x64, 0x64, 0x65, 0x66, 0x67, 0x69, 0x6B, 0x6E, -0x71, 0x76, 0x7A, 0x7D, 0xFE, 0xFC, 0xFA, 0xF8, 0xF4, 0xF0, 0xEE, 0xEC, 0xEA, 0xE9, 0xE8, 0xE9, -0xEB, 0xEB, 0xEC, 0xED, 0xEE, 0xED, 0xEB, 0xE9, 0xEA, 0xE9, 0xE9, 0xEA, 0xEC, 0xF0, 0xF6, 0xFD, -0x78, 0x71, 0x6D, 0x69, 0x67, 0x66, 0x65, 0x65, 0x66, 0x67, 0x66, 0x66, 0x67, 0x67, 0x66, 0x66, -0x69, 0x6B, 0x6D, 0x73, 0x7A, 0xFE, 0xF7, 0xF3, 0xEF, 0xEE, 0xEE, 0xEC, 0xEB, 0xEA, 0xE8, 0xE7, -0xE5, 0xE3, 0xE1, 0xE1, 0xE1, 0xE3, 0xE6, 0xE8, 0xEB, 0xEF, 0xF8, 0x7E, 0x75, 0x6F, 0x6B, 0x69, -0x67, 0x66, 0x65, 0x65, 0x66, 0x67, 0x67, 0x68, 0x68, 0x69, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, -0x70, 0x6F, 0x6F, 0x6F, 0x72, 0x75, 0x79, 0xFF, 0xFB, 0xF6, 0xF2, 0xEF, 0xEE, 0xED, 0xEE, 0xF0, -0xF3, 0xF6, 0xF8, 0xFC, 0xFF, 0x7D, 0x79, 0x76, 0x72, 0x6E, 0x6D, 0x6B, 0x6B, 0x6C, 0x6C, 0x6D, -0x6E, 0x71, 0x76, 0x7B, 0xFF, 0xFE, 0xFD, 0xFC, 0xFD, 0x7F, 0x7B, 0x78, 0x75, 0x74, 0x75, 0x77, -0x7A, 0x7E, 0xFC, 0xF9, 0xF6, 0xF5, 0xF4, 0xF4, 0xF5, 0xF7, 0xF8, 0xF8, 0xF7, 0xF6, 0xF5, 0xF5, -0xF6, 0xF8, 0xFA, 0xFC, 0x7F, 0x7B, 0x79, 0x78, 0x77, 0x77, 0x79, 0x7D, 0xFD, 0xF9, 0xF4, 0xF2, -0xF1, 0xF1, 0xF3, 0xF5, 0xFA, 0xFE, 0x7F, 0xFF, 0xFD, 0xFC, 0xFB, 0xF7, 0xF5, 0xF4, 0xF4, 0xF6, -0xF8, 0xFB, 0xFD, 0xFF, 0x7E, 0x7E, 0x7E, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7E, 0x7B, 0x79, 0x77, -0x76, 0x75, 0x74, 0x74, 0x75, 0x78, 0x7C, 0x7F, 0xFE, 0xFD, 0xFE, 0xFF, 0x7E, 0x7C, 0x7B, 0x79, -0x79, 0x7A, 0x7D, 0xFE, 0xFC, 0xFA, 0xF8, 0xF8, 0xF9, 0xFB, 0xFD, 0x7F, 0x7B, 0x78, 0x76, 0x75, -0x74, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x75, 0x76, 0x76, 0x77, 0x7A, 0x7C, -0x7E, 0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7C, 0x7A, 0x78, 0x77, 0x77, 0x76, 0x79, 0x7B, 0x7E, 0xFF, -0xFE, 0xFD, 0xFD, 0xFF, 0x7E, 0x7C, 0x7C, 0x7B, 0x79, 0x78, 0x78, 0x78, 0x77, 0x75, 0x74, 0x74, -0x74, 0x74, 0x75, 0x76, 0x79, 0x7C, 0x7E, 0xFF, 0xFC, 0xF8, 0xF7, 0xF6, 0xF7, 0xF7, 0xF7, 0xF9, -0xFC, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7F, 0xFF, 0xFC, 0xFB, 0xFA, 0xF8, 0xF8, 0xF8, 0xF6, 0xF5, -0xF5, 0xF4, 0xF4, 0xF5, 0xF7, 0xF8, 0xFA, 0xFD, 0x7F, 0x7E, 0x7D, 0x7C, 0x7C, 0x7D, 0x7E, 0xFE, -0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF9, 0xF9, 0xFA, 0xFB, 0xFD, 0xFF, 0x7E, 0x7D, 0x79, 0x77, 0x75, -0x72, 0x71, 0x70, 0x70, 0x70, 0x71, 0x71, 0x70, 0x71, 0x72, 0x71, 0x72, 0x71, 0x72, 0x73, 0x72, -0x72, 0x71, 0x71, 0x71, 0x72, 0x74, 0x74, 0x76, 0x77, 0x77, 0x77, 0x78, 0x77, 0x78, 0x78, 0x78, -0x7A, 0x7C, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFD, 0xFF, 0x7E, 0x7D, 0x7B, 0x7C, 0x7B, -0x7B, 0x7B, 0x7B, 0x7B, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7B, 0x7C, 0x7E, 0xFF, 0xFD, -0xFB, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0xFF, 0x7F, 0x7D, 0x7C, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7D, -0x7F, 0x7F, 0xFF, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, -0xFF, 0xFF, 0xFF, 0xFD, 0xFA, 0xF9, 0xF7, 0xF5, 0xF4, 0xF3, 0xF1, 0xF1, 0xF1, 0xF1, 0xF2, 0xF2, -0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xFA, 0xFC, 0xFE, 0xFE, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, -0x7F, 0x7D, 0x7C, 0x7D, 0x7B, 0x7A, 0x7D, 0x7B, 0x7B, 0x7C, 0x7B, 0x7B, 0x7B, 0x79, 0x78, 0x77, -0x77, 0x76, 0x75, 0x76, 0x75, 0x74, 0x74, 0x75, 0x74, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73, 0x74, -0x72, 0x70, 0x70, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x70, 0x70, 0x70, 0x71, 0x72, 0x73, 0x73, 0x76, -0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7B, 0x7D, 0x7E, 0x7D, 0x7F, 0x7D, 0x7C, 0x7B, 0x7B, 0x7C, -0x7B, 0x7B, 0x7A, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0xFF, 0x7D, 0x7E, 0x7C, 0x7C, 0x7B, 0x78, -0x7C, 0x7A, 0x7C, 0x7D, 0x7B, 0x7E, 0x7C, 0x7F, 0x7D, 0x7A, 0x7E, 0x78, 0x7B, 0x6F, 0x68, 0x5C, -0x4C, 0x58, 0xDD, 0xE1, 0xEB, 0xE1, 0xE9, 0xEF, 0xF8, 0xE9, 0xE1, 0xED, 0xF9, 0xFC, 0xF2, 0xED, -0x7D, 0x76, 0xFB, 0xF9, 0x7C, 0x70, 0x6F, 0x78, 0x79, 0x6D, 0x6D, 0x76, 0x7D, 0xFE, 0x7A, 0x79, -0xFC, 0xFD, 0xFD, 0xFA, 0xFB, 0xFA, 0xFC, 0xFF, 0xFC, 0xFC, 0xFE, 0xFD, 0xFE, 0xFB, 0xFB, 0xFE, -0xFE, 0x7E, 0x7D, 0x7C, 0x7C, 0x7B, 0x78, 0x7D, 0x7D, 0xFF, 0xFA, 0xFF, 0xF9, 0xF9, 0xFA, 0xF7, -0x7F, 0xF9, 0x7A, 0x7A, 0x6F, 0x51, 0x52, 0x6E, 0x71, 0xF1, 0xD8, 0xD3, 0xDB, 0xEF, 0xE2, 0xDB, -0xED, 0xF6, 0xF3, 0xEF, 0xF4, 0x6A, 0x74, 0x73, 0x57, 0x5E, 0x77, 0x6E, 0xFD, 0xF4, 0xFC, 0x7D, -0x73, 0xE9, 0xDE, 0xE2, 0xDE, 0xE3, 0xE5, 0xE8, 0xFA, 0xF7, 0xFA, 0x6F, 0x6C, 0x6A, 0x6B, 0x6A, -0x66, 0x6B, 0x75, 0x70, 0x74, 0xFA, 0xFB, 0xFD, 0xF8, 0xF3, 0xF2, 0xFB, 0xF5, 0xED, 0xEF, 0xEB, -0xE5, 0xDF, 0xDA, 0xD7, 0xD5, 0xD3, 0xD3, 0xD4, 0xD8, 0xE0, 0xEE, 0x76, 0x5D, 0x53, 0x4D, 0x49, -0x46, 0x43, 0x42, 0x43, 0x43, 0x45, 0x48, 0x4B, 0x4F, 0x57, 0x60, 0x6D, 0xF7, 0xE3, 0xDB, 0xD4, -0xCF, 0xCB, 0xC8, 0xC4, 0xBE, 0xBC, 0xB9, 0xB4, 0xB6, 0xBC, 0xC1, 0xC3, 0xD5, 0x4F, 0x4B, 0x43, -0x36, 0x33, 0x34, 0x32, 0x31, 0x36, 0x3B, 0x3F, 0x48, 0x60, 0xDF, 0xD2, 0xC9, 0xC1, 0xC3, 0xC6, -0xC7, 0xCF, 0xE3, 0x67, 0x56, 0x47, 0x3E, 0x3F, 0x3C, 0x3B, 0x43, 0x48, 0x4F, 0xFA, 0xD5, 0xC5, -0xBD, 0xB7, 0xB1, 0xAE, 0xAC, 0xAE, 0xB1, 0xB5, 0xC0, 0xD7, 0x5D, 0x40, 0x38, 0x31, 0x2E, 0x2D, -0x2C, 0x2E, 0x32, 0x37, 0x3F, 0x4F, 0xF8, 0xD0, 0xC4, 0xBC, 0xBB, 0xBB, 0xBB, 0xBE, 0xC7, 0xD0, -0xF1, 0x56, 0x48, 0x40, 0x3D, 0x3B, 0x3D, 0x42, 0x49, 0x63, 0xDA, 0xCB, 0xBC, 0xB6, 0xB0, 0xAE, -0xAF, 0xAF, 0xB4, 0xBC, 0xC6, 0xFE, 0x4C, 0x3E, 0x34, 0x30, 0x2E, 0x2D, 0x2E, 0x30, 0x35, 0x3C, -0x46, 0x62, 0xDE, 0xCA, 0xBE, 0xBD, 0xBB, 0xBA, 0xBD, 0xC3, 0xCB, 0xDC, 0x6B, 0x59, 0x51, 0x52, -0x60, 0xFF, 0xD5, 0xC4, 0xBE, 0xBC, 0xBA, 0xB9, 0xBB, 0xC3, 0xC8, 0xD6, 0x5A, 0x4C, 0x42, 0x39, -0x36, 0x35, 0x32, 0x34, 0x36, 0x39, 0x41, 0x47, 0x58, 0xE0, 0xDA, 0xC9, 0xC1, 0xC4, 0xC0, 0xC0, -0xC6, 0xCA, 0xD1, 0xDC, 0xF3, 0x6E, 0xFC, 0xE8, 0xDB, 0xCB, 0xC2, 0xBE, 0xBD, 0xBE, 0xBD, 0xC0, -0xCD, 0xCE, 0xEC, 0x4E, 0x4C, 0x40, 0x38, 0x39, 0x37, 0x35, 0x38, 0x38, 0x3B, 0x43, 0x49, 0x54, -0xEA, 0xDB, 0xCE, 0xC5, 0xC5, 0xC3, 0xC1, 0xC7, 0xCA, 0xCF, 0xDB, 0xE9, 0xFD, 0xF7, 0xE9, 0xDD, -0xCE, 0xC6, 0xC1, 0xBF, 0xC0, 0xBF, 0xC3, 0xCF, 0xD0, 0xE6, 0x51, 0x4E, 0x43, 0x3A, 0x3B, 0x38, -0x35, 0x38, 0x38, 0x3A, 0x3F, 0x44, 0x4E, 0x5F, 0xEF, 0xD7, 0xCD, 0xC8, 0xC6, 0xC4, 0xC6, 0xC9, -0xCC, 0xD4, 0xDD, 0xE6, 0xE1, 0xDA, 0xD7, 0xCA, 0xC3, 0xC4, 0xC4, 0xC1, 0xC3, 0xCC, 0xCF, 0xD8, -0x60, 0x54, 0x4E, 0x3F, 0x3D, 0x3D, 0x39, 0x3A, 0x3C, 0x3B, 0x3D, 0x47, 0x48, 0x51, 0x79, 0xFA, -0xDD, 0xCD, 0xCF, 0xCC, 0xC8, 0xCD, 0xCE, 0xCE, 0xD7, 0xDC, 0xDC, 0xD7, 0xD4, 0xCC, 0xC3, 0xC1, -0xBF, 0xBF, 0xC2, 0xC1, 0xCE, 0xDB, 0xDD, 0x54, 0x4C, 0x49, 0x3C, 0x3B, 0x3B, 0x38, 0x3A, 0x3B, -0x3C, 0x3E, 0x48, 0x4C, 0x55, 0xF3, 0xEC, 0xDB, 0xCD, 0xD1, 0xCD, 0xCB, 0xD2, 0xD1, 0xD6, 0xDD, -0xE1, 0xE2, 0xD7, 0xD3, 0xCA, 0xC0, 0xBE, 0xBE, 0xBF, 0xBE, 0xC1, 0xCF, 0xD0, 0xED, 0x4E, 0x4D, -0x41, 0x3A, 0x3A, 0x37, 0x35, 0x38, 0x3A, 0x3A, 0x3F, 0x49, 0x4A, 0x62, 0xE7, 0xEA, 0xCE, 0xCB, -0xCF, 0xC8, 0xCB, 0xD1, 0xCF, 0xD7, 0xE2, 0xE5, 0xE5, 0xDF, 0xD5, 0xCC, 0xC5, 0xBE, 0xBE, 0xC0, -0xBC, 0xC0, 0xCD, 0xC8, 0xDC, 0x58, 0x5B, 0x47, 0x3C, 0x3D, 0x39, 0x36, 0x39, 0x3A, 0x39, 0x3E, -0x47, 0x49, 0x59, 0xEA, 0xEC, 0xD0, 0xC9, 0xCD, 0xC7, 0xC8, 0xCE, 0xCD, 0xD2, 0xDC, 0xDF, 0xDF, -0xDD, 0xD6, 0xCB, 0xC6, 0xBF, 0xBF, 0xC4, 0xBD, 0xC4, 0xD1, 0xC9, 0xEF, 0x55, 0x5D, 0x43, 0x3D, -0x3E, 0x38, 0x37, 0x3A, 0x3A, 0x3A, 0x3E, 0x45, 0x48, 0x56, 0x74, 0xF8, 0xD8, 0xCF, 0xD0, 0xCB, -0xCB, 0xCE, 0xCE, 0xD2, 0xD9, 0xDC, 0xDC, 0xD7, 0xD3, 0xCA, 0xC4, 0xC0, 0xBF, 0xC2, 0xBE, 0xC3, -0xCF, 0xCB, 0xE5, 0x58, 0x5C, 0x45, 0x3D, 0x3E, 0x39, 0x37, 0x39, 0x3A, 0x3A, 0x3D, 0x45, 0x46, -0x52, 0x79, 0x73, 0xD7, 0xCD, 0xD1, 0xC8, 0xC8, 0xCD, 0xCA, 0xCF, 0xD5, 0xD7, 0xDC, 0xDA, 0xD4, -0xCD, 0xC7, 0xC1, 0xC0, 0xC5, 0xBF, 0xC2, 0xD1, 0xCA, 0xDA, 0x5A, 0x68, 0x4C, 0x3E, 0x42, 0x3B, -0x38, 0x3B, 0x3A, 0x3A, 0x3D, 0x42, 0x44, 0x4B, 0x62, 0x66, 0xF1, 0xD0, 0xD6, 0xCD, 0xC8, 0xCE, -0xCA, 0xCB, 0xD1, 0xCF, 0xD2, 0xD2, 0xCE, 0xC9, 0xC5, 0xC1, 0xBF, 0xC5, 0xC1, 0xC0, 0xD3, 0xCE, -0xD6, 0x57, 0x5F, 0x4E, 0x3E, 0x41, 0x3D, 0x39, 0x3B, 0x3B, 0x3A, 0x3D, 0x42, 0x44, 0x4C, 0x5A, -0x5E, 0xEC, 0xDD, 0xDC, 0xCE, 0xD0, 0xD1, 0xCD, 0xD4, 0xD4, 0xD4, 0xDA, 0xD3, 0xCE, 0xCB, 0xC4, -0xBF, 0xBE, 0xC2, 0xBE, 0xBF, 0xCD, 0xCB, 0xD5, 0x5B, 0x5F, 0x4D, 0x3E, 0x3F, 0x3B, 0x37, 0x39, -0x3A, 0x39, 0x3C, 0x3F, 0x42, 0x4B, 0x59, 0x61, 0xEA, 0xDA, 0xD6, 0xCD, 0xCD, 0xCE, 0xCD, 0xCF, -0xD3, 0xD6, 0xDA, 0xD7, 0xD2, 0xCE, 0xC7, 0xC2, 0xBF, 0xC0, 0xC1, 0xBE, 0xC8, 0xCE, 0xCB, 0x79, -0x5A, 0x5C, 0x41, 0x3F, 0x3E, 0x38, 0x39, 0x3A, 0x39, 0x3A, 0x3E, 0x42, 0x45, 0x51, 0x62, 0x65, -0xDD, 0xD5, 0xD7, 0xCA, 0xCC, 0xCE, 0xCA, 0xCE, 0xD0, 0xCF, 0xCF, 0xCD, 0xC9, 0xC4, 0xBF, 0xBD, -0xBE, 0xBF, 0xBD, 0xC5, 0xCE, 0xCB, 0xF8, 0x58, 0x5B, 0x43, 0x3E, 0x3E, 0x39, 0x38, 0x3A, 0x39, -0x3A, 0x3E, 0x44, 0x45, 0x51, 0x6E, 0x69, 0xDC, 0xCF, 0xD7, 0xCA, 0xCB, 0xD0, 0xCC, 0xD1, 0xD5, -0xD5, 0xD5, 0xCF, 0xCB, 0xC5, 0xBF, 0xBC, 0xBD, 0xBF, 0xBB, 0xC3, 0xCC, 0xC8, 0xEF, 0x5B, 0x5D, -0x41, 0x3D, 0x3D, 0x37, 0x37, 0x38, 0x37, 0x38, 0x3B, 0x41, 0x43, 0x4E, 0x6B, 0x67, 0xDC, 0xCE, -0xD4, 0xC9, 0xC8, 0xCE, 0xCA, 0xCE, 0xD5, 0xD4, 0xD5, 0xD3, 0xCE, 0xC7, 0xC3, 0xBE, 0xBE, 0xC3, -0xBD, 0xC2, 0xD0, 0xC9, 0xDE, 0x57, 0x61, 0x47, 0x3D, 0x3F, 0x39, 0x36, 0x38, 0x38, 0x38, 0x3A, -0x41, 0x40, 0x48, 0x6A, 0x5C, 0xF7, 0xCD, 0xDB, 0xCD, 0xC6, 0xD1, 0xCC, 0xCC, 0xD6, 0xD5, 0xD3, -0xCF, 0xCE, 0xC6, 0xC0, 0xBF, 0xBE, 0xBF, 0xBE, 0xC0, 0xCC, 0xCB, 0xDB, 0x5D, 0x5B, 0x49, 0x3E, -0x3E, 0x39, 0x37, 0x38, 0x38, 0x38, 0x3B, 0x40, 0x42, 0x4A, 0x63, 0x66, 0xE5, 0xCE, 0xD0, 0xCA, -0xC7, 0xCA, 0xCA, 0xCC, 0xCE, 0xD1, 0xCF, 0xCC, 0xCC, 0xC4, 0xBF, 0xBF, 0xBE, 0xC0, 0xBE, 0xC2, -0xCE, 0xCC, 0xE2, 0x58, 0x59, 0x47, 0x3D, 0x3D, 0x39, 0x37, 0x39, 0x39, 0x39, 0x3C, 0x40, 0x44, -0x4D, 0x5D, 0x6F, 0xE0, 0xD4, 0xCF, 0xCC, 0xCB, 0xCB, 0xCD, 0xCF, 0xCF, 0xD4, 0xD1, 0xCC, 0xCA, -0xC4, 0xBF, 0xBD, 0xBF, 0xBF, 0xBE, 0xC7, 0xCF, 0xCE, 0x79, 0x52, 0x51, 0x41, 0x3C, 0x3B, 0x38, -0x36, 0x38, 0x39, 0x38, 0x3D, 0x44, 0x44, 0x55, 0x70, 0x76, 0xD5, 0xCF, 0xCF, 0xC9, 0xCB, 0xCB, -0xCD, 0xD1, 0xD1, 0xD9, 0xD2, 0xCD, 0xCD, 0xC4, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xC9, 0xCF, 0xD0, -0x6A, 0x53, 0x4F, 0x3F, 0x3C, 0x3B, 0x38, 0x37, 0x38, 0x39, 0x3A, 0x3E, 0x44, 0x4A, 0x56, 0x75, -0xE7, 0xD7, 0xCD, 0xCB, 0xCA, 0xC9, 0xCA, 0xCD, 0xCE, 0xCF, 0xD3, 0xCE, 0xCA, 0xC7, 0xC0, 0xBE, -0xBE, 0xBF, 0xBF, 0xC1, 0xCD, 0xD2, 0xDB, 0x5C, 0x4F, 0x4A, 0x3E, 0x3C, 0x3B, 0x39, 0x38, 0x3A, -0x3A, 0x3C, 0x43, 0x46, 0x4E, 0x71, 0x7A, 0xDD, 0xCE, 0xD0, 0xCB, 0xCA, 0xCD, 0xCC, 0xD1, 0xD2, -0xD5, 0xD7, 0xCC, 0xCC, 0xC7, 0xBE, 0xBF, 0xBF, 0xBE, 0xC0, 0xC6, 0xCD, 0xD5, 0xEE, 0x54, 0x4D, -0x45, 0x3C, 0x3B, 0x39, 0x37, 0x38, 0x39, 0x3A, 0x3E, 0x44, 0x4A, 0x59, 0x71, 0xE8, 0xD4, 0xCE, -0xCC, 0xC9, 0xCB, 0xCB, 0xCE, 0xD2, 0xD4, 0xD7, 0xD2, 0xCD, 0xCB, 0xC4, 0xBF, 0xBF, 0xC0, 0xC0, -0xC0, 0xC9, 0xD1, 0xD8, 0x73, 0x52, 0x4B, 0x42, 0x3C, 0x3A, 0x39, 0x38, 0x38, 0x39, 0x3C, 0x3F, -0x41, 0x4E, 0x5D, 0x63, 0xDF, 0xD3, 0xD1, 0xCD, 0xCB, 0xCC, 0xD1, 0xD1, 0xD3, 0xDE, 0xDA, 0xD1, -0xCF, 0xCC, 0xC4, 0xBF, 0xC2, 0xC2, 0xBF, 0xC6, 0xCD, 0xD2, 0xE3, 0x63, 0x4F, 0x4A, 0x42, 0x3C, -0x3B, 0x3A, 0x39, 0x3A, 0x3B, 0x3F, 0x42, 0x47, 0x5A, 0x62, 0x7C, 0xD5, 0xD2, 0xCF, 0xCC, 0xCD, -0xCE, 0xD5, 0xD6, 0xD9, 0xE0, 0xD9, 0xD2, 0xCE, 0xCB, 0xC4, 0xBF, 0xC2, 0xC2, 0xBF, 0xC6, 0xCD, -0xD4, 0xE2, 0x67, 0x4F, 0x4B, 0x43, 0x3D, 0x3C, 0x3B, 0x3B, 0x3B, 0x3C, 0x42, 0x43, 0x49, 0x60, -0x6B, 0xF5, 0xD4, 0xD2, 0xD0, 0xD2, 0xD2, 0xD4, 0xDF, 0xDD, 0xDF, 0xEA, 0xDC, 0xD5, 0xD0, 0xCB, -0xC4, 0xC0, 0xC2, 0xBF, 0xC0, 0xC7, 0xC9, 0xD0, 0xDD, 0x7A, 0x57, 0x52, 0x48, 0x3F, 0x3F, 0x3D, -0x3C, 0x3C, 0x3D, 0x42, 0x44, 0x49, 0x5B, 0x64, 0x7C, 0xDE, 0xDB, 0xDB, 0xDC, 0xDA, 0xDF, 0xEE, -0xE9, 0xE6, 0xE8, 0xE3, 0xDB, 0xD0, 0xCD, 0xCC, 0xC5, 0xC3, 0xC5, 0xC2, 0xC3, 0xC8, 0xCD, 0xD1, -0xDE, 0x6F, 0x5B, 0x50, 0x4A, 0x44, 0x40, 0x3F, 0x3E, 0x3E, 0x42, 0x43, 0x47, 0x4F, 0x58, 0x5F, -0x69, 0xF6, 0xED, 0xF7, 0xEB, 0xE8, 0xEA, 0xEC, 0xE8, 0xE0, 0xE0, 0xDD, 0xD7, 0xD0, 0xCE, 0xCC, -0xC8, 0xC7, 0xC6, 0xC4, 0xC8, 0xC9, 0xCB, 0xD2, 0xDA, 0xEF, 0x71, 0x5B, 0x4F, 0x4E, 0x49, 0x45, -0x46, 0x45, 0x47, 0x47, 0x4A, 0x4E, 0x4E, 0x54, 0x5A, 0x5D, 0x62, 0x65, 0x70, 0x6C, 0x69, 0xFA, -0x7A, 0x7A, 0xE6, 0xE2, 0xDF, 0xDA, 0xD5, 0xCF, 0xD1, 0xD1, 0xCB, 0xCE, 0xD4, 0xCE, 0xD1, 0xD9, -0xDB, 0xE0, 0xE1, 0xEE, 0x6A, 0x74, 0x6C, 0x5A, 0x5B, 0x5A, 0x56, 0x56, 0x53, 0x56, 0x57, 0x53, -0x57, 0x5B, 0x59, 0x59, 0x5D, 0x65, 0x60, 0x61, 0x6F, 0x73, 0xF7, 0xEF, 0xEA, 0xDD, 0xDF, 0xDC, -0xD5, 0xD8, 0xDC, 0xDC, 0xDA, 0xDF, 0xE5, 0xE1, 0xEB, 0xED, 0xED, 0xFC, 0xFF, 0x70, 0x6C, 0x6C, -0x66, 0x5F, 0x5F, 0x62, 0x5F, 0x60, 0x60, 0x5A, 0x5F, 0x64, 0x5C, 0x64, 0x6E, 0x5F, 0x5E, 0x69, -0x6B, 0x7B, 0xF0, 0xFA, 0xE9, 0xE4, 0xE8, 0xDF, 0xE6, 0xEB, 0xE1, 0xE2, 0xE6, 0xE3, 0xE8, 0xED, -0xE5, 0xFC, 0x71, 0xE9, 0xFE, 0x7A, 0xEC, 0x73, 0x7E, 0x77, 0x64, 0xFD, 0x74, 0x66, 0x7B, 0x6C, -0x6B, 0x72, 0x6A, 0x79, 0x73, 0x71, 0xF4, 0x79, 0xFC, 0xEF, 0xF9, 0xEB, 0xF1, 0xF0, 0xE2, 0xE3, -0xE0, 0xE2, 0xE3, 0xEB, 0xFC, 0xEA, 0xF8, 0x6F, 0x70, 0x69, 0x77, 0x6C, 0x6D, 0xEF, 0x6B, 0x67, -0x6D, 0x65, 0x76, 0x75, 0x6F, 0x7E, 0x69, 0x67, 0x6F, 0x68, 0x6F, 0x73, 0x68, 0x69, 0x68, 0x69, -0x75, 0xFA, 0xEE, 0xF2, 0xEA, 0xDE, 0xE2, 0xE7, 0xE5, 0xEB, 0xF3, 0xED, 0xE8, 0xF7, 0x7F, 0xFA, -0x74, 0x6A, 0x68, 0x65, 0x66, 0x68, 0x64, 0x65, 0x68, 0x64, 0x6D, 0x77, 0x72, 0x70, 0x69, 0x77, -0x78, 0x64, 0x6B, 0x68, 0x60, 0x66, 0x67, 0x67, 0x61, 0x6D, 0xEB, 0xE8, 0xEC, 0xEB, 0xEA, 0xF7, -0xF5, 0xE2, 0xE5, 0xF6, 0xF8, 0xF0, 0x7E, 0x77, 0xFA, 0x76, 0x77, 0x7D, 0x6E, 0x74, 0x74, 0x72, -0x72, 0x6D, 0x75, 0x74, 0x74, 0x75, 0x76, 0xEF, 0xEE, 0xEF, 0xEA, 0xFA, 0x7F, 0xF2, 0xF6, 0xF7, -0xEF, 0xEA, 0xE4, 0xE5, 0xE7, 0xE3, 0xE9, 0xEC, 0xE8, 0xEB, 0xF0, 0xF8, 0xFC, 0x7F, 0x73, 0x73, -0x70, 0x72, 0x75, 0x69, 0x67, 0x6A, 0x6C, 0x6D, 0x6C, 0x70, 0x6D, 0x6D, 0x78, 0x72, 0x6F, 0x6E, -0x6C, 0x6F, 0x77, 0xF7, 0xEF, 0xF1, 0xF6, 0xF4, 0xF1, 0xFC, 0xF8, 0xEE, 0xF0, 0xEE, 0xEF, 0xEF, -0xEC, 0xEE, 0xF3, 0xF4, 0x76, 0x69, 0x77, 0xFA, 0x70, 0x75, 0x7E, 0x6E, 0x6D, 0x6E, 0x6E, 0x6E, -0x6D, 0x70, 0x74, 0x79, 0xFE, 0x7D, 0x78, 0x7C, 0x7A, 0x75, 0x78, 0x75, 0x70, 0x7C, 0xFC, 0xFB, -0xF4, 0xF3, 0xED, 0xEC, 0xF6, 0xF1, 0xEF, 0xF6, 0xF0, 0xFB, 0x7A, 0x7C, 0x74, 0x79, 0x74, 0x6C, -0x6C, 0x63, 0x67, 0x6C, 0x62, 0x66, 0x67, 0x68, 0x6C, 0x6A, 0x7D, 0x78, 0x6B, 0x7B, 0x71, 0x75, -0xFB, 0x75, 0x76, 0x7E, 0xEE, 0xED, 0xFA, 0xE8, 0xEE, 0x7F, 0xE4, 0xE9, 0xED, 0xE1, 0xEC, 0xEE, -0xE6, 0xF6, 0xFE, 0xF7, 0xFF, 0x7B, 0x72, 0x7C, 0x7F, 0x6B, 0x6C, 0x66, 0x67, 0x71, 0x66, 0x72, -0xFF, 0x69, 0x7B, 0xF7, 0xFF, 0xF3, 0xF6, 0xF3, 0xF2, 0xEE, 0xED, 0xFF, 0xF6, 0xED, 0xFB, 0xF2, -0xE9, 0xF0, 0xEC, 0xE6, 0xF4, 0xF2, 0xF5, 0x7C, 0xED, 0x7E, 0x6B, 0x7B, 0x77, 0xFE, 0x7A, 0x69, -0x68, 0x60, 0x65, 0x66, 0x61, 0x71, 0x74, 0x74, 0xFC, 0x7E, 0xFA, 0xFF, 0x7E, 0xF9, 0xFB, 0xEE, -0xED, 0xEF, 0xEF, 0xF4, 0xEC, 0xEC, 0xF2, 0xF0, 0xEF, 0xED, 0xF4, 0xF6, 0xEF, 0xFD, 0xF8, 0xF1, -0x77, 0x74, 0x7A, 0x70, 0x6F, 0x79, 0x76, 0x6A, 0x68, 0x6C, 0x6C, 0x69, 0x65, 0x66, 0x6E, 0x73, -0x6C, 0x6D, 0x7A, 0x79, 0x7A, 0xFE, 0x73, 0x72, 0x7A, 0x7E, 0xF3, 0xEF, 0xEE, 0xF1, 0xF6, 0xEC, -0xEF, 0xFA, 0xEE, 0xF5, 0xFE, 0xF2, 0xF0, 0xF7, 0xFA, 0xF9, 0xFB, 0xFB, 0x7A, 0x6B, 0x6B, 0x72, -0x6C, 0x6A, 0x76, 0x74, 0x6E, 0x72, 0x6C, 0x6B, 0x6F, 0x6B, 0x6E, 0x71, 0x6D, 0x75, 0x76, 0x70, -0x78, 0x7C, 0xFA, 0xF2, 0xF7, 0xF1, 0xED, 0xF3, 0xF4, 0xF6, 0xFA, 0xF0, 0xEF, 0xFD, 0x7B, 0xFF, -0x78, 0x6C, 0x70, 0x72, 0x6E, 0x73, 0x6D, 0x6D, 0x6D, 0x65, 0x65, 0x69, 0x6F, 0x70, 0x6B, 0x6E, -0x71, 0x6E, 0x6E, 0x6F, 0x7A, 0x7D, 0x7E, 0xEF, 0xF4, 0x7D, 0xFB, 0xF3, 0xEC, 0xEB, 0xF0, 0xEF, -0xEE, 0xEE, 0xF3, 0xF0, 0xED, 0xFF, 0xFF, 0xF3, 0x7E, 0xFB, 0xFF, 0x73, 0x7E, 0x7A, 0x76, 0x6F, -0x6C, 0x7A, 0x74, 0x6F, 0xFF, 0x7B, 0x79, 0xF7, 0xF5, 0xFB, 0xF6, 0xF3, 0x7E, 0x7D, 0xFA, 0xFD, -0xF6, 0xF5, 0x7D, 0x7B, 0x7A, 0xFF, 0xFB, 0x7D, 0x75, 0x76, 0xF3, 0xF3, 0x78, 0xFE, 0x76, 0x6B, -0x7B, 0xFB, 0x75, 0x69, 0x6C, 0xF6, 0xF6, 0x7B, 0x6F, 0x69, 0x6E, 0x72, 0x70, 0x74, 0x78, 0xFF, -0x7F, 0xFD, 0xF5, 0xF8, 0xF5, 0xF9, 0x75, 0x74, 0x7D, 0xF7, 0xFB, 0x70, 0x7E, 0xE9, 0xEF, 0xF7, -0xE6, 0xED, 0x74, 0x7A, 0xF7, 0x7D, 0x71, 0x77, 0xFE, 0xF6, 0xFC, 0x6B, 0x6B, 0x72, 0x69, 0x6D, -0x7B, 0x7C, 0xFD, 0x6F, 0x6B, 0xFC, 0x7F, 0x73, 0xF9, 0xF5, 0x70, 0x6E, 0xFD, 0xFF, 0x7C, 0xFB, -0x70, 0x76, 0xEF, 0x7D, 0x75, 0xFB, 0xF6, 0xEF, 0xF6, 0x7C, 0x79, 0x76, 0xFE, 0x7D, 0x73, 0xFD, -0xFE, 0x76, 0x6E, 0x66, 0x6B, 0x75, 0x6D, 0x7D, 0xF2, 0x6D, 0x75, 0xED, 0x7A, 0x6D, 0x7E, 0xF9, -0xFE, 0x6E, 0x78, 0xF4, 0x6E, 0x73, 0xF8, 0x74, 0xFF, 0xFE, 0x77, 0xF6, 0x7C, 0x71, 0x7F, 0x7E, -0x7E, 0x79, 0x78, 0x7C, 0x6E, 0x6F, 0x70, 0x6D, 0xFD, 0xFA, 0x6C, 0x6B, 0x71, 0x70, 0x7B, 0x7A, -0x7C, 0xFD, 0x6D, 0x75, 0xED, 0xF8, 0xFC, 0xF7, 0xFB, 0xEE, 0xEF, 0x79, 0xFF, 0xED, 0xF8, 0x7A, -0xF1, 0xED, 0xF7, 0xFC, 0xF8, 0xF1, 0xF8, 0x79, 0x7D, 0xF6, 0x78, 0x6E, 0xFD, 0xFB, 0x72, 0x6E, -0x6C, 0x74, 0xFE, 0xFF, 0xF7, 0xFE, 0x6D, 0x75, 0x79, 0x6F, 0x7C, 0x7D, 0x76, 0x78, 0x7A, 0x7F, -0x75, 0x7D, 0xF7, 0xF8, 0xEF, 0x7B, 0x7A, 0xF3, 0xFF, 0xEF, 0xF8, 0xFE, 0xF6, 0x6E, 0xF4, 0xED, -0x6F, 0x7C, 0x74, 0x75, 0xF2, 0x7C, 0x75, 0xF9, 0xEE, 0xFF, 0x70, 0x7C, 0x7F, 0xFD, 0xFD, 0xFA, -0x79, 0x6C, 0x7C, 0x7F, 0xFD, 0xF3, 0x78, 0xFE, 0xF7, 0xFC, 0xED, 0xF1, 0xFD, 0xFE, 0x7D, 0xF4, -0xED, 0xF4, 0xFA, 0xFD, 0x70, 0x73, 0xF6, 0xFF, 0x7D, 0xF7, 0x79, 0x72, 0x78, 0x7D, 0x77, 0x6E, -0x71, 0x6C, 0x6A, 0x7D, 0x74, 0x71, 0x7D, 0x6E, 0x79, 0xF8, 0x70, 0x7C, 0xFE, 0x6D, 0x6F, 0x6E, -0x6D, 0x7D, 0xFD, 0xFB, 0xFA, 0x7C, 0xFD, 0xFA, 0xF7, 0xF4, 0xFD, 0x7B, 0x76, 0x7D, 0xF3, 0xF5, -0xFD, 0xF5, 0xED, 0x7A, 0x6D, 0xF5, 0x7C, 0x76, 0xEF, 0x77, 0x6E, 0xFF, 0x74, 0x79, 0xFD, 0x76, -0x7A, 0x7E, 0x7B, 0x7D, 0x78, 0x73, 0x7A, 0xFB, 0xFB, 0x7E, 0xFB, 0xF2, 0xF8, 0xF9, 0xFB, 0xFE, -0xF5, 0xF6, 0xF9, 0x7E, 0x73, 0xF7, 0xFA, 0x74, 0xFC, 0x7B, 0x70, 0xFF, 0xFC, 0x7E, 0x7C, 0xFE, -0xFF, 0x7C, 0xFC, 0x7E, 0x79, 0xFF, 0x7C, 0x79, 0x79, 0x79, 0x7A, 0x79, 0x7A, 0x7C, 0x7A, 0x75, -0x72, 0x7C, 0xFC, 0xFE, 0xFE, 0xFC, 0xF9, 0xFE, 0xFE, 0xFA, 0x7C, 0xFD, 0xFC, 0x77, 0x7B, 0x7A, -0x73, 0x78, 0x7A, 0x78, 0x7B, 0x77, 0x6E, 0x70, 0x7B, 0x7A, 0x72, 0x74, 0x76, 0x75, 0x77, 0x75, -0x70, 0x6F, 0x6F, 0x6F, 0x74, 0x77, 0x72, 0x6F, 0x70, 0x79, 0x79, 0x6F, 0x7E, 0xFA, 0x72, 0x79, -0x79, 0x78, 0xFE, 0x78, 0xFF, 0xFE, 0x76, 0xFF, 0xFF, 0x7D, 0xFF, 0x7E, 0x7B, 0x78, 0x7C, 0x75, -0x75, 0xFF, 0xFF, 0xF8, 0xF6, 0xFD, 0xF5, 0xF4, 0xF6, 0xFC, 0x7C, 0x7C, 0x7B, 0xFC, 0xFD, 0xFD, -0xFD, 0x77, 0x7A, 0x7F, 0x7E, 0xFC, 0xFA, 0xF7, 0xFF, 0xFE, 0xF1, 0xFD, 0xFD, 0xF0, 0xF9, 0xF8, -0xEE, 0xEF, 0xF8, 0x7E, 0x79, 0x77, 0x6C, 0x66, 0x6A, 0x68, 0x67, 0x71, 0x74, 0x77, 0x7E, 0x7B, -0xFD, 0xFD, 0x7F, 0xFF, 0x79, 0xFE, 0xFE, 0x75, 0x78, 0x7A, 0x74, 0x70, 0x76, 0x77, 0x75, 0x7C, -0x7C, 0x79, 0x78, 0x77, 0x78, 0x7C, 0x7E, 0x77, 0x74, 0x79, 0x77, 0x78, 0x78, 0x77, 0x7B, 0x78, -0x77, 0x77, 0x7A, 0xFE, 0x7D, 0xFE, 0xF6, 0xFB, 0xFC, 0xF8, 0xF6, 0xFA, 0xFD, 0xFB, 0xFC, 0x7D, -0x7B, 0xFB, 0xF5, 0xFC, 0xFF, 0xFD, 0xFE, 0xFF, 0x7F, 0xFC, 0xF8, 0xFF, 0x7F, 0xF7, 0xF9, 0xFA, -0xF9, 0xFB, 0xFA, 0xFA, 0xFA, 0xF8, 0xF8, 0xFD, 0x7E, 0xF8, 0xF7, 0xEF, 0xE0, 0xE1, 0xF7, 0x6E, -0x69, 0x65, 0x5C, 0x5B, 0x61, 0x69, 0x6E, 0x76, 0xF8, 0xEF, 0xF2, 0xEB, 0xE3, 0xDE, 0xE2, 0xFA, -0x66, 0x5B, 0x5F, 0x6E, 0x6E, 0xFB, 0xED, 0xED, 0xEC, 0xF8, 0x7E, 0x7B, 0x6E, 0x67, 0x60, 0x65, -0x6E, 0x6F, 0x78, 0xFB, 0x7E, 0x7D, 0xFA, 0xF9, 0xF7, 0xF5, 0xF7, 0xEE, 0xEB, 0xF3, 0xFA, 0x7A, -0x6D, 0x69, 0x6A, 0x69, 0x64, 0x69, 0x6E, 0x6F, 0x78, 0xFB, 0xFB, 0x7C, 0xF8, 0xF1, 0xFB, 0xF4, -0xF9, 0x7D, 0xF8, 0x7D, 0xFD, 0xF3, 0x7C, 0xFD, 0xF4, 0x7A, 0x6F, 0x79, 0xFF, 0x75, 0x78, 0xFA, -0xFB, 0xFE, 0xFB, 0xF9, 0xFE, 0xFF, 0xFF, 0xFC, 0xF5, 0xFD, 0x79, 0xFF, 0xF9, 0xFA, 0xFF, 0xFF, -0x7B, 0x74, 0x75, 0x6F, 0x71, 0x7D, 0x74, 0x75, 0x79, 0x71, 0x77, 0x7E, 0x7E, 0x7C, 0x74, 0x71, -0x77, 0x7A, 0x7F, 0xFB, 0x72, 0x69, 0x74, 0x74, 0x6A, 0x74, 0x7E, 0x79, 0x76, 0x74, 0x7F, 0x7C, -0x76, 0xF8, 0xF8, 0x7E, 0x7D, 0x7E, 0xFE, 0x77, 0x7B, 0xF8, 0x7B, 0xFF, 0xF3, 0xFC, 0xFF, 0xFE, -0xFD, 0xF5, 0xF6, 0xF3, 0xF2, 0xFA, 0xF8, 0xF3, 0xFB, 0x7E, 0xFA, 0xFA, 0x7E, 0xFE, 0xFC, 0x7C, -0x78, 0x7D, 0xFB, 0xF3, 0xFD, 0x74, 0xF7, 0xF5, 0x76, 0xF9, 0xF8, 0xFF, 0xF5, 0x76, 0x7B, 0xFA, -0x77, 0xFD, 0x7C, 0x77, 0x7D, 0x6F, 0x7D, 0xF7, 0xFC, 0xFD, 0x7B, 0xF5, 0xF8, 0x7A, 0xF4, 0xFB, -0x77, 0x7B, 0x76, 0x74, 0x7D, 0x7E, 0x72, 0x71, 0x70, 0x70, 0x77, 0x70, 0x7B, 0xFD, 0x6F, 0x72, -0x7D, 0x7A, 0x71, 0x79, 0xF8, 0x77, 0x6F, 0x74, 0x7A, 0x78, 0x7C, 0xF6, 0x7C, 0xFB, 0x7D, 0x6C, -0xEF, 0xFC, 0x6D, 0xF1, 0xF5, 0x7D, 0x79, 0xFA, 0xF5, 0x75, 0xF4, 0x7C, 0xFC, 0xE6, 0x68, 0x78, -0xE4, 0x6E, 0x77, 0xF2, 0x7E, 0x70, 0x69, 0xF9, 0xF7, 0x6C, 0x74, 0xF3, 0xEE, 0x79, 0x7E, 0xFB, -0x7A, 0xF6, 0x6C, 0x6B, 0xED, 0x77, 0x6A, 0x70, 0x6F, 0xFC, 0x7E, 0x79, 0xF2, 0xEE, 0xF8, 0x7D, -0xEF, 0xEB, 0x7E, 0x72, 0x7D, 0x74, 0x6B, 0xFA, 0xE5, 0xE7, 0xE4, 0xEB, 0xF8, 0xEC, 0xEA, 0xF3, -0xFB, 0xFA, 0xEF, 0xF6, 0x7C, 0xFF, 0x7B, 0x72, 0x78, 0x7C, 0x6F, 0x6E, 0xFF, 0xFF, 0x75, 0x74, -0x74, 0x76, 0x6C, 0x6A, 0x7F, 0x78, 0x6D, 0x74, 0x6E, 0x76, 0x7B, 0x69, 0x6B, 0x79, 0x72, 0x6A, -0x6D, 0x77, 0xFD, 0xFC, 0x6F, 0x7C, 0xEE, 0x76, 0x69, 0x74, 0xFB, 0x74, 0x6A, 0x7D, 0xF0, 0xFF, -0x6B, 0x71, 0xEF, 0x7D, 0x74, 0xF8, 0x75, 0x74, 0x77, 0x6C, 0x6E, 0x71, 0x73, 0x72, 0x70, 0xF4, -0xF0, 0x79, 0x7B, 0xFB, 0xF3, 0xF4, 0x78, 0x79, 0xF7, 0xFC, 0x6E, 0x70, 0xF8, 0xF8, 0x79, 0x6D, -0x70, 0xFB, 0x6E, 0x64, 0x6B, 0x72, 0x6F, 0x65, 0x71, 0xFC, 0x71, 0x76, 0x6E, 0x71, 0xF9, 0xFF, -0xFD, 0x73, 0x7A, 0xFF, 0x66, 0x70, 0xFE, 0x79, 0xFD, 0x7D, 0xF1, 0xF6, 0x76, 0x79, 0x6D, 0x79, -0xFF, 0x72, 0x7F, 0xF8, 0xF0, 0xFF, 0x71, 0xEC, 0xE9, 0x7C, 0x7C, 0xF1, 0xF7, 0xF7, 0xF5, 0xFA, -0xF1, 0x7C, 0x70, 0x7D, 0xFB, 0xF4, 0x7C, 0x7D, 0xF6, 0xFD, 0xEF, 0xF6, 0xEE, 0xE1, 0xEE, 0xF4, -0xF3, 0xEE, 0xF4, 0x78, 0xEC, 0xF7, 0x72, 0x74, 0x6E, 0xF5, 0x6A, 0x7B, 0xDF, 0x69, 0x7F, 0xE7, -0x6F, 0x7C, 0x68, 0xF4, 0xEE, 0x5C, 0x72, 0x6B, 0x6D, 0xEC, 0x60, 0x7E, 0xEB, 0x66, 0x6D, 0x6A, -0x7A, 0xFF, 0x6A, 0x6E, 0x74, 0xED, 0x79, 0x6B, 0xED, 0xFA, 0xFC, 0x70, 0x65, 0xF6, 0x75, 0x67, -0x78, 0x78, 0xF4, 0xFF, 0x5F, 0xF9, 0xE3, 0x6D, 0xF1, 0x7A, 0x70, 0xDB, 0x6A, 0xF9, 0xDC, 0x66, -0xDB, 0xF8, 0x65, 0xD6, 0x6A, 0xF2, 0xE6, 0x5E, 0xE1, 0x76, 0x6F, 0xF5, 0x65, 0xEF, 0x5F, 0x66, -0x6F, 0x5A, 0xFB, 0x5E, 0x65, 0x7E, 0x60, 0xF2, 0x5D, 0x72, 0xE8, 0x5A, 0xEA, 0x6E, 0x62, 0xE4, -0x5E, 0x6F, 0x74, 0x67, 0xEA, 0x64, 0x77, 0xF3, 0x69, 0xF1, 0x6B, 0x6E, 0xEB, 0x74, 0x74, 0x74, -0xF6, 0xF5, 0x66, 0xF5, 0xF7, 0x6C, 0xE9, 0x70, 0x6F, 0xE4, 0x6E, 0xF0, 0xF4, 0x63, 0xE1, 0xFE, -0x6D, 0xE4, 0x6D, 0xF2, 0xEF, 0x6C, 0xE8, 0x7B, 0xFC, 0xED, 0x74, 0xEB, 0xFE, 0xFC, 0xEF, 0x6D, -0xEC, 0xFB, 0x71, 0xEB, 0x77, 0xF3, 0xF8, 0x6F, 0xE9, 0xFE, 0xFC, 0xEE, 0x6F, 0xEB, 0xED, 0x7A, -0xEE, 0xF4, 0xF3, 0xF8, 0xF1, 0xEE, 0x79, 0xF4, 0xF3, 0xFC, 0xF1, 0x7C, 0xF4, 0xF9, 0x76, 0xE8, -0xF8, 0x75, 0xE3, 0x7B, 0x6E, 0xE0, 0x75, 0x72, 0xE3, 0x6C, 0xF8, 0xE7, 0x6D, 0xEA, 0xF4, 0x75, -0xEA, 0x71, 0xFA, 0xED, 0x6A, 0xF2, 0xFB, 0x70, 0xEB, 0x6F, 0x71, 0xEE, 0x6C, 0xF6, 0xF2, 0x68, -0xF3, 0xF8, 0x6D, 0x7A, 0xFC, 0x75, 0x6D, 0xF3, 0x6E, 0x6E, 0xEE, 0x61, 0x7C, 0xFE, 0x60, 0xF2, -0x6D, 0x78, 0x7C, 0x63, 0xEB, 0x64, 0x71, 0xED, 0x5C, 0xEB, 0x6F, 0x69, 0xEA, 0x5D, 0xE7, 0xF8, -0x5E, 0xE6, 0x6F, 0xFA, 0x79, 0x72, 0xE8, 0x5E, 0xE9, 0xFB, 0x5F, 0xDE, 0x61, 0xFA, 0xE3, 0x5A, -0xE3, 0x79, 0x62, 0xDF, 0x64, 0x76, 0xE4, 0x63, 0xFE, 0xE9, 0x64, 0xF8, 0xE6, 0x5F, 0xF2, 0xE8, -0x62, 0xE7, 0xFB, 0x6A, 0xF0, 0x77, 0xF9, 0x77, 0xE9, 0x78, 0x59, 0xE3, 0x71, 0x6C, 0xDF, 0x5F, -0xEF, 0xE9, 0x5F, 0xFA, 0x76, 0xF9, 0x7D, 0x67, 0xEE, 0x7B, 0x6F, 0x7E, 0x6B, 0x6D, 0xF7, 0x6E, -0x6B, 0xF0, 0x63, 0xF0, 0x75, 0x57, 0xD4, 0x59, 0x57, 0xCD, 0x4F, 0xEE, 0xDE, 0x4B, 0xCF, 0x68, -0x5B, 0xD4, 0x50, 0xE0, 0xEF, 0x54, 0xD5, 0x57, 0x6A, 0xD3, 0x54, 0x79, 0xDF, 0x5E, 0xFC, 0xE6, -0x5F, 0x71, 0xE0, 0x64, 0x76, 0xFC, 0x5D, 0xEA, 0xF8, 0x58, 0x79, 0xDB, 0x68, 0x59, 0xDF, 0x76, -0x64, 0xDA, 0x63, 0x5A, 0xD9, 0xE0, 0x51, 0xF3, 0xD3, 0x4D, 0xDE, 0xCF, 0x3F, 0xDA, 0xC2, 0x41, -0x6A, 0xC3, 0x50, 0x55, 0xC6, 0x5A, 0x4B, 0xC2, 0x7A, 0x46, 0xCA, 0xDF, 0x4C, 0xD8, 0xDE, 0x4F, -0xE2, 0xD2, 0x4D, 0x6B, 0xCD, 0x5C, 0x56, 0xD8, 0xEB, 0x54, 0xEF, 0xDE, 0x4F, 0x78, 0xD7, 0x54, -0x5B, 0xDA, 0xFA, 0x56, 0xF6, 0xE9, 0x58, 0xF1, 0xE5, 0x59, 0x6D, 0xE8, 0x7B, 0x64, 0x7E, 0xE2, -0x60, 0x6D, 0xDC, 0x63, 0x67, 0xDC, 0x6F, 0x62, 0xE2, 0x7B, 0x60, 0xEC, 0xF3, 0x67, 0x77, 0xF1, -0x7C, 0x75, 0xF0, 0x79, 0x6F, 0xED, 0x76, 0x6B, 0xF3, 0xFF, 0x74, 0xF4, 0xF8, 0x6B, 0x6C, 0xE6, -0xE7, 0x61, 0x79, 0xDD, 0x6F, 0x77, 0xDE, 0x6D, 0x6E, 0xE4, 0x7E, 0xF9, 0xE8, 0x6D, 0x6F, 0xDE, -0xEF, 0x5C, 0xEF, 0xDB, 0x64, 0x6B, 0xDF, 0xF9, 0x6C, 0xF4, 0xF5, 0x72, 0xF5, 0xF7, 0x66, 0x7D, -0xE9, 0x7D, 0x70, 0x79, 0xF6, 0x7B, 0x6C, 0xF3, 0xF2, 0x6A, 0x76, 0xED, 0x79, 0x6B, 0xF2, 0xF1, -0x6B, 0x78, 0xEF, 0x73, 0x74, 0xED, 0x73, 0x6A, 0xEB, 0xF2, 0x64, 0x6F, 0xE2, 0xF8, 0x5E, 0xF3, -0xE8, 0x64, 0x74, 0xEF, 0x7B, 0x77, 0x74, 0x78, 0x6D, 0xF8, 0xEA, 0x63, 0x68, 0xEC, 0xEF, 0x6E, -0x63, 0xEE, 0xFA, 0x5F, 0xE5, 0xEB, 0x58, 0x73, 0xD1, 0xF3, 0x4D, 0xF2, 0xCD, 0x5D, 0x54, 0xDF, -0xDD, 0x61, 0x5B, 0xD9, 0xDF, 0x50, 0xF0, 0xD3, 0x5F, 0x5D, 0xE4, 0xDF, 0x6E, 0x5B, 0xED, 0xD8, -0x68, 0x56, 0xEA, 0xD3, 0x70, 0x52, 0xF0, 0xD3, 0x74, 0x57, 0xF5, 0xD8, 0x6A, 0x58, 0xE4, 0xE2, -0x5C, 0x7A, 0xD8, 0x77, 0x5A, 0xE8, 0xD9, 0x73, 0x5F, 0x7D, 0xE3, 0xEC, 0x73, 0x72, 0x6E, 0xF6, -0xDF, 0xF7, 0x62, 0x6B, 0xE5, 0xDD, 0x6B, 0x58, 0xF7, 0xDB, 0x73, 0x5E, 0x75, 0x7E, 0xF6, 0xFE, -0x66, 0x71, 0x7B, 0x7E, 0xEE, 0x6C, 0x6B, 0xEB, 0x76, 0x6C, 0xEA, 0x7A, 0x67, 0xE5, 0xE8, 0x5F, -0x75, 0xDE, 0xEE, 0x6F, 0x7A, 0xED, 0xE8, 0xF8, 0xFB, 0xF4, 0x78, 0xF1, 0xE4, 0x6E, 0x62, 0xEB, -0xEC, 0x65, 0x6D, 0x7E, 0x6B, 0x69, 0x6E, 0x72, 0x78, 0x68, 0x5E, 0x74, 0xE9, 0x6F, 0x5E, 0x72, -0xEB, 0x7A, 0x6F, 0xF1, 0x78, 0x75, 0xE5, 0xE6, 0xE2, 0xDD, 0xE0, 0xD6, 0xD1, 0xD5, 0xD1, 0xD3, -0xDE, 0xE0, 0xDD, 0xE9, 0x68, 0x57, 0x52, 0x50, 0x4B, 0x48, 0x48, 0x48, 0x48, 0x4B, 0x51, 0x56, -0x56, 0x5D, 0x68, 0x6A, 0x69, 0x7C, 0xE8, 0xED, 0xED, 0xDC, 0xD5, 0xCD, 0xCB, 0xCD, 0xC5, 0xBE, -0xBE, 0xBC, 0xBC, 0xBF, 0xC5, 0xD2, 0x72, 0x52, 0x48, 0x40, 0x3C, 0x39, 0x39, 0x3B, 0x3D, 0x40, -0x4A, 0x5A, 0x6C, 0x7E, 0xDF, 0xCF, 0xCE, 0xDB, 0x6F, 0x63, 0x6E, 0x60, 0x4D, 0x47, 0x4D, 0x5E, -0x7C, 0xFA, 0xE4, 0xCD, 0xC1, 0xBD, 0xBC, 0xBA, 0xB7, 0xB4, 0xB5, 0xBE, 0xD7, 0xEB, 0xF2, 0x4E, -0x3B, 0x36, 0x37, 0x39, 0x38, 0x39, 0x3D, 0x48, 0x58, 0xFE, 0xDA, 0xD6, 0xD8, 0xCF, 0xC8, 0xCD, -0xF3, 0x5A, 0x59, 0x58, 0x4E, 0x47, 0x48, 0x4F, 0x5F, 0xF2, 0xD9, 0xCE, 0xC6, 0xBF, 0xBB, 0xBA, -0xB9, 0xB7, 0xB5, 0xB7, 0xC0, 0xD9, 0x68, 0x57, 0x49, 0x3B, 0x35, 0x35, 0x38, 0x3A, 0x3B, 0x3F, -0x4B, 0x60, 0xE7, 0xD8, 0xD5, 0xD4, 0xCE, 0xCA, 0xCF, 0xF9, 0x59, 0x51, 0x4E, 0x4C, 0x48, 0x46, -0x49, 0x56, 0xFB, 0xD9, 0xD1, 0xC9, 0xBE, 0xB8, 0xB6, 0xB5, 0xB3, 0xB2, 0xB6, 0xC3, 0xE5, 0x60, -0x4E, 0x3F, 0x37, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x41, 0x4E, 0x6F, 0xDA, 0xD2, 0xD4, 0xD1, 0xCA, -0xC9, 0xD7, 0x6F, 0x59, 0x4D, 0x47, 0x47, 0x48, 0x45, 0x46, 0x52, 0xEE, 0xD7, 0xD0, 0xC7, 0xBC, -0xB5, 0xB3, 0xB3, 0xB1, 0xB0, 0xB7, 0xCA, 0x68, 0x4F, 0x45, 0x3B, 0x32, 0x2E, 0x30, 0x35, 0x39, -0x3D, 0x44, 0x52, 0xEC, 0xD0, 0xCF, 0xD3, 0xD0, 0xCD, 0xCF, 0xE3, 0x63, 0x5B, 0x59, 0x52, 0x4D, -0x4C, 0x4F, 0x5A, 0x6D, 0xE5, 0xD2, 0xC8, 0xBE, 0xB9, 0xB5, 0xB3, 0xB1, 0xAF, 0xB1, 0xBD, 0xE3, -0x53, 0x4B, 0x40, 0x35, 0x2E, 0x2F, 0x34, 0x39, 0x3B, 0x3F, 0x4C, 0x75, 0xDA, 0xD6, 0xD2, 0xCE, -0xCE, 0xD0, 0xD9, 0xEF, 0x62, 0x56, 0x55, 0x55, 0x4F, 0x4E, 0x52, 0x61, 0xEF, 0xDB, 0xCC, 0xBF, -0xB9, 0xB5, 0xB3, 0xB0, 0xAE, 0xB4, 0xC8, 0x63, 0x4D, 0x45, 0x39, 0x2E, 0x2C, 0x2F, 0x35, 0x38, -0x3B, 0x43, 0x5A, 0xDD, 0xCE, 0xCD, 0xCC, 0xCB, 0xCD, 0xD2, 0xDE, 0x76, 0x5A, 0x52, 0x53, 0x51, -0x4E, 0x4F, 0x5C, 0x7C, 0xE2, 0xD2, 0xC5, 0xBB, 0xB5, 0xB2, 0xB0, 0xAE, 0xAE, 0xB6, 0xCF, 0x55, -0x48, 0x3F, 0x34, 0x2C, 0x2C, 0x2F, 0x36, 0x39, 0x3D, 0x4A, 0x7D, 0xCE, 0xCA, 0xCB, 0xCB, 0xCB, -0xCD, 0xD9, 0x76, 0x59, 0x4F, 0x4C, 0x4C, 0x4A, 0x4C, 0x54, 0x68, 0xEC, 0xD8, 0xCB, 0xBF, 0xB8, -0xB3, 0xB0, 0xAE, 0xAD, 0xAE, 0xBC, 0xF5, 0x4C, 0x43, 0x39, 0x2E, 0x2A, 0x2D, 0x32, 0x37, 0x3B, -0x44, 0x5F, 0xD5, 0xC8, 0xC7, 0xC9, 0xCB, 0xCE, 0xD3, 0xE9, 0x5A, 0x4D, 0x4D, 0x4D, 0x4B, 0x4B, -0x50, 0x63, 0xF6, 0xDE, 0xCE, 0xC5, 0xBD, 0xB7, 0xB2, 0xB0, 0xAF, 0xAD, 0xAF, 0xBF, 0x5E, 0x45, -0x40, 0x37, 0x2C, 0x29, 0x2D, 0x34, 0x38, 0x3C, 0x48, 0x77, 0xCD, 0xC6, 0xC7, 0xCB, 0xCB, 0xCF, -0xE9, 0x59, 0x4E, 0x4B, 0x47, 0x44, 0x47, 0x4D, 0x57, 0x69, 0xEB, 0xD7, 0xCA, 0xBF, 0xB9, 0xB3, -0xAF, 0xAE, 0xAD, 0xAC, 0xB5, 0xDE, 0x49, 0x43, 0x3B, 0x2D, 0x28, 0x2A, 0x30, 0x36, 0x3A, 0x44, -0x6A, 0xCD, 0xC2, 0xC2, 0xC6, 0xCA, 0xCC, 0xD8, 0x60, 0x4C, 0x48, 0x46, 0x44, 0x43, 0x49, 0x54, -0x68, 0xEC, 0xD8, 0xCB, 0xC2, 0xBC, 0xB8, 0xB2, 0xAF, 0xAE, 0xAE, 0xAE, 0xBA, 0x74, 0x45, 0x3F, -0x36, 0x2C, 0x29, 0x2C, 0x32, 0x37, 0x3E, 0x4E, 0xE3, 0xC7, 0xC2, 0xC5, 0xC6, 0xC8, 0xD2, 0x71, -0x52, 0x4D, 0x49, 0x42, 0x41, 0x47, 0x51, 0x60, 0x7B, 0xDE, 0xCE, 0xC6, 0xC0, 0xBE, 0xB9, 0xB2, -0xAF, 0xAF, 0xAE, 0xAE, 0xBC, 0x6B, 0x47, 0x3F, 0x34, 0x2C, 0x2A, 0x2D, 0x32, 0x39, 0x3F, 0x4F, -0xDF, 0xC5, 0xC4, 0xCD, 0xCA, 0xC7, 0xDB, 0x5A, 0x4E, 0x4D, 0x48, 0x42, 0x40, 0x45, 0x54, 0x6F, -0x74, 0xEC, 0xCD, 0xC4, 0xC4, 0xC1, 0xBB, 0xB3, 0xAF, 0xB0, 0xAE, 0xAE, 0xBC, 0x6F, 0x4A, 0x3F, -0x34, 0x2C, 0x2B, 0x2E, 0x34, 0x3B, 0x42, 0x56, 0xCF, 0xBF, 0xC2, 0xCB, 0xC6, 0xC6, 0xE6, 0x52, -0x4B, 0x47, 0x45, 0x3F, 0x3D, 0x45, 0x5E, 0x7A, 0x72, 0xDB, 0xC7, 0xC3, 0xC5, 0xC2, 0xBC, 0xB5, -0xB1, 0xB3, 0xB0, 0xAE, 0xB9, 0xF0, 0x4C, 0x43, 0x38, 0x2E, 0x2B, 0x2D, 0x34, 0x3A, 0x3E, 0x4F, -0xD3, 0xC1, 0xC4, 0xCD, 0xCC, 0xC8, 0xDE, 0x4D, 0x45, 0x47, 0x47, 0x41, 0x3D, 0x47, 0x6D, 0xF7, -0x79, 0xDA, 0xC9, 0xC6, 0xC8, 0xC9, 0xC0, 0xB8, 0xB4, 0xB5, 0xB0, 0xAC, 0xB1, 0xCF, 0x5A, 0x4E, -0x3E, 0x30, 0x2B, 0x2D, 0x33, 0x38, 0x3B, 0x48, 0xDC, 0xC4, 0xC5, 0xCA, 0xCB, 0xCB, 0xD9, 0x50, -0x46, 0x4B, 0x46, 0x3E, 0x3F, 0x48, 0x55, 0x76, 0x7E, 0xE3, 0xCA, 0xC9, 0xCE, 0xCB, 0xC6, 0xBE, -0xBA, 0xB8, 0xB4, 0xAE, 0xAE, 0xBD, 0xEA, 0x62, 0x48, 0x35, 0x2D, 0x2C, 0x30, 0x35, 0x37, 0x3F, -0x6F, 0xCB, 0xCA, 0xC9, 0xC7, 0xCE, 0xD9, 0x60, 0x46, 0x46, 0x48, 0x40, 0x40, 0x49, 0x52, 0x69, -0xED, 0xE1, 0xD1, 0xCC, 0xD0, 0xD2, 0xD0, 0xCD, 0xC2, 0xBD, 0xB9, 0xB2, 0xAE, 0xAF, 0xBA, 0xE0, -0x67, 0x4C, 0x34, 0x2D, 0x2E, 0x30, 0x34, 0x37, 0x41, 0xF4, 0xCD, 0xCC, 0xC7, 0xC5, 0xD0, 0xED, -0x64, 0x4D, 0x45, 0x47, 0x43, 0x44, 0x4F, 0x51, 0x69, 0xD9, 0xDD, 0xD1, 0xCB, 0xD1, 0xCF, 0xD2, -0xCD, 0xBF, 0xBC, 0xB8, 0xB0, 0xAD, 0xAE, 0xBC, 0xD9, 0x76, 0x48, 0x32, 0x2D, 0x2F, 0x30, 0x32, -0x38, 0x49, 0xE6, 0xD1, 0xCB, 0xC1, 0xC1, 0xD2, 0x7A, 0x6F, 0x51, 0x42, 0x43, 0x45, 0x4A, 0x4D, -0x4E, 0x72, 0xD7, 0xDB, 0xD8, 0xCE, 0xCF, 0xD7, 0xDD, 0xD3, 0xC6, 0xBF, 0xBB, 0xB3, 0xAD, 0xAE, -0xB8, 0xCD, 0xE2, 0x52, 0x35, 0x2E, 0x2F, 0x2F, 0x2F, 0x35, 0x43, 0x62, 0xE5, 0xCF, 0xC1, 0xC0, -0xD1, 0xE1, 0xDB, 0x5E, 0x46, 0x49, 0x4D, 0x4A, 0x49, 0x51, 0x6A, 0xEE, 0xEB, 0xDE, 0xD0, 0xD4, -0xDF, 0xDC, 0xD7, 0xCF, 0xC5, 0xBE, 0xB7, 0xB1, 0xAE, 0xAF, 0xBC, 0xD3, 0xE7, 0x48, 0x31, 0x2E, -0x2F, 0x2E, 0x2F, 0x36, 0x44, 0x5B, 0xF4, 0xCC, 0xBF, 0xC2, 0xD4, 0xD1, 0xCF, 0x59, 0x4B, 0x51, -0x4B, 0x46, 0x44, 0x4C, 0x56, 0x51, 0x66, 0xE5, 0xE6, 0xE0, 0xDF, 0xD6, 0xD1, 0xCD, 0xC0, 0xBB, -0xB7, 0xB0, 0xAD, 0xB0, 0xBD, 0xCE, 0xEF, 0x44, 0x31, 0x2F, 0x30, 0x2E, 0x2E, 0x39, 0x46, 0x56, -0xF0, 0xC7, 0xBD, 0xC2, 0xC9, 0xC8, 0xCC, 0x7A, 0x50, 0x57, 0x4F, 0x42, 0x42, 0x4A, 0x4C, 0x4C, -0x5D, 0xEF, 0xEE, 0xE3, 0xD6, 0xD1, 0xD2, 0xCC, 0xC0, 0xBC, 0xBA, 0xB3, 0xAE, 0xAF, 0xBA, 0xC9, -0xD6, 0x4F, 0x36, 0x30, 0x30, 0x2E, 0x2D, 0x34, 0x3E, 0x45, 0x5C, 0xCF, 0xC1, 0xC0, 0xC1, 0xC0, -0xC9, 0xD9, 0xF5, 0x54, 0x4A, 0x47, 0x40, 0x41, 0x42, 0x45, 0x4E, 0x53, 0x68, 0xE8, 0xE1, 0xD1, -0xCD, 0xCC, 0xC5, 0xBF, 0xBB, 0xB8, 0xB4, 0xAF, 0xB0, 0xBD, 0xCB, 0xD8, 0x4B, 0x36, 0x34, 0x33, -0x2E, 0x2E, 0x37, 0x3D, 0x44, 0x62, 0xCD, 0xC4, 0xC0, 0xBE, 0xBF, 0xC5, 0xCF, 0xEE, 0x66, 0x4F, -0x45, 0x43, 0x40, 0x41, 0x44, 0x47, 0x51, 0x5B, 0x71, 0xDD, 0xD8, 0xCE, 0xC8, 0xC6, 0xC1, 0xBD, -0xB9, 0xB7, 0xB2, 0xAF, 0xB9, 0xC3, 0xCC, 0x71, 0x40, 0x37, 0x36, 0x31, 0x2E, 0x33, 0x3A, 0x3D, -0x4A, 0xE6, 0xCF, 0xC7, 0xBE, 0xBF, 0xC2, 0xCA, 0xD3, 0xE6, 0x50, 0x4C, 0x4B, 0x3E, 0x3E, 0x43, -0x41, 0x47, 0x4D, 0x59, 0x75, 0xE4, 0xD0, 0xCC, 0xC9, 0xC3, 0xBF, 0xBD, 0xBB, 0xB8, 0xB3, 0xB3, -0xBB, 0xC3, 0xCD, 0x6A, 0x42, 0x3A, 0x38, 0x31, 0x30, 0x36, 0x39, 0x3C, 0x4B, 0x7A, 0xDB, 0xCB, -0xC1, 0xC3, 0xC5, 0xC5, 0xD5, 0xE5, 0x6B, 0x4E, 0x4C, 0x43, 0x40, 0x45, 0x42, 0x48, 0x50, 0x55, -0x6C, 0xE8, 0xD7, 0xCD, 0xCC, 0xC7, 0xC3, 0xC0, 0xBD, 0xBC, 0xB8, 0xB2, 0xB5, 0xBD, 0xC2, 0xD0, -0x5D, 0x45, 0x3C, 0x38, 0x32, 0x32, 0x37, 0x37, 0x3C, 0x4C, 0x5E, 0xEE, 0xCD, 0xC5, 0xC8, 0xC6, -0xC5, 0xD0, 0xE2, 0xF9, 0x5D, 0x4D, 0x47, 0x46, 0x42, 0x41, 0x47, 0x4B, 0x4E, 0x63, 0xEA, 0xE3, -0xD3, 0xC9, 0xCB, 0xC8, 0xC0, 0xBF, 0xBD, 0xBA, 0xB5, 0xB6, 0xBC, 0xC1, 0xCC, 0x7E, 0x4B, 0x3F, -0x3B, 0x35, 0x32, 0x37, 0x37, 0x3A, 0x45, 0x50, 0x6D, 0xD7, 0xC8, 0xC6, 0xC7, 0xC2, 0xCA, 0xD7, -0xDB, 0x6D, 0x59, 0x4F, 0x48, 0x48, 0x45, 0x46, 0x4D, 0x4F, 0x5E, 0xFF, 0xE6, 0xD7, 0xD4, 0xCF, -0xD1, 0xD5, 0xD0, 0xD3, 0xCD, 0xC6, 0xC1, 0xBA, 0xB8, 0xBB, 0xC2, 0xC4, 0xCD, 0x58, 0x4C, 0x48, -0x39, 0x36, 0x39, 0x36, 0x37, 0x3E, 0x44, 0x4B, 0x66, 0xDC, 0xD4, 0xCA, 0xC3, 0xC5, 0xC7, 0xCA, -0xCE, 0xDD, 0x6D, 0x5F, 0x4F, 0x46, 0x47, 0x46, 0x43, 0x49, 0x4E, 0x53, 0x65, 0xF1, 0xE4, 0xD9, -0xCF, 0xCE, 0xCD, 0xC6, 0xC3, 0xC0, 0xBA, 0xB7, 0xB7, 0xBD, 0xC4, 0xC5, 0xFD, 0x4A, 0x4C, 0x3B, -0x33, 0x37, 0x34, 0x32, 0x3A, 0x3F, 0x47, 0x5B, 0xDC, 0xCB, 0xC8, 0xBE, 0xBC, 0xC3, 0xC0, 0xC7, -0xDE, 0xEC, 0x5B, 0x49, 0x45, 0x3F, 0x3E, 0x3F, 0x40, 0x49, 0x4E, 0x5B, 0xEF, 0xDF, 0xD4, 0xCC, -0xCA, 0xC7, 0xC5, 0xC3, 0xBF, 0xBD, 0xBB, 0xB8, 0xB8, 0xC0, 0xCB, 0xCA, 0x68, 0x45, 0x4D, 0x3D, -0x35, 0x3C, 0x3A, 0x38, 0x41, 0x49, 0x4D, 0x69, 0xDB, 0xD3, 0xCD, 0xC5, 0xC6, 0xCC, 0xCB, 0xD0, -0xEB, 0x76, 0x5C, 0x4C, 0x48, 0x44, 0x41, 0x41, 0x44, 0x49, 0x4E, 0x5D, 0x7E, 0xE6, 0xD4, 0xCE, -0xCE, 0xCB, 0xCB, 0xCE, 0xCE, 0xCA, 0xC9, 0xC6, 0xBE, 0xBC, 0xC6, 0xCA, 0xC4, 0xE0, 0x58, 0x77, -0x4A, 0x3D, 0x45, 0x3D, 0x39, 0x3F, 0x41, 0x40, 0x4C, 0x61, 0x6D, 0xE7, 0xCE, 0xCC, 0xCC, 0xC9, -0xCA, 0xD1, 0xDB, 0xE2, 0x66, 0x54, 0x50, 0x48, 0x45, 0x47, 0x47, 0x4B, 0x51, 0x5A, 0x71, 0xEB, -0xDD, 0xD5, 0xD2, 0xCF, 0xCC, 0xCC, 0xCA, 0xC4, 0xC3, 0xBF, 0xB9, 0xBD, 0xCB, 0xC0, 0xC9, 0x56, -0x71, 0x5A, 0x3A, 0x3F, 0x3E, 0x34, 0x3A, 0x3E, 0x3C, 0x42, 0x54, 0x62, 0x73, 0xCF, 0xC8, 0xCC, -0xC3, 0xC3, 0xCD, 0xCF, 0xDD, 0x6D, 0x56, 0x4D, 0x48, 0x42, 0x42, 0x44, 0x45, 0x4D, 0x57, 0x61, -0xED, 0xDB, 0xD5, 0xCD, 0xCD, 0xCD, 0xCD, 0xD0, 0xCD, 0xD1, 0xCA, 0xC4, 0xC7, 0xBA, 0xC2, 0xD8, -0xBB, 0xD7, 0x53, 0xCC, 0x4E, 0x3E, 0x57, 0x3E, 0x3B, 0x43, 0x3F, 0x3E, 0x46, 0x52, 0x50, 0x60, -0xD6, 0xD9, 0xD4, 0xC6, 0xCA, 0xCF, 0xCB, 0xD5, 0xF4, 0xFB, 0x5D, 0x4E, 0x4C, 0x4B, 0x46, 0x45, -0x4F, 0x4E, 0x4D, 0x7E, 0x6F, 0x71, 0xD4, 0xE1, 0xDF, 0xCE, 0xD9, 0xD5, 0xCD, 0xCD, 0xC5, 0xBF, -0xB9, 0xBA, 0xC6, 0xBA, 0xBF, 0x6C, 0xCE, 0xFB, 0x3D, 0x4D, 0x40, 0x35, 0x3C, 0x3B, 0x38, 0x3E, -0x47, 0x4B, 0x52, 0xDF, 0xD8, 0xD6, 0xC3, 0xC6, 0xCB, 0xC5, 0xCD, 0xDD, 0xE4, 0x6B, 0x50, 0x4D, -0x49, 0x44, 0x45, 0x47, 0x48, 0x49, 0x50, 0x5D, 0x5C, 0xEE, 0xDD, 0xE7, 0xD1, 0xD5, 0xDC, 0xD0, -0xDA, 0xD8, 0xD1, 0xCD, 0xC6, 0xBF, 0xBA, 0xC1, 0xC4, 0xBA, 0xD3, 0xE1, 0xCC, 0x4D, 0x49, 0x4F, -0x3B, 0x3B, 0x3E, 0x3A, 0x3C, 0x42, 0x4A, 0x4C, 0x6D, 0xD9, 0xDC, 0xC9, 0xC4, 0xCA, 0xC6, 0xC8, -0xD0, 0xD8, 0xE5, 0x68, 0x58, 0x53, 0x4C, 0x4A, 0x4B, 0x4C, 0x4E, 0x56, 0x5F, 0x69, 0xEA, 0xE0, -0xE8, 0xD5, 0xDD, 0xE7, 0xD9, 0xFB, 0xF9, 0xF5, 0x64, 0x75, 0x6D, 0xF5, 0xE5, 0xD8, 0xC8, 0xC4, -0xBB, 0xBF, 0xC4, 0xB7, 0xCC, 0xD6, 0xC3, 0x56, 0x52, 0x5F, 0x3D, 0x3E, 0x3E, 0x39, 0x3A, 0x3D, -0x41, 0x41, 0x4F, 0x6B, 0x63, 0xD6, 0xCD, 0xD1, 0xC7, 0xC8, 0xCE, 0xCE, 0xD6, 0xE8, 0x71, 0x67, -0x55, 0x4F, 0x52, 0x4D, 0x4F, 0x56, 0x56, 0x5E, 0x6D, 0x7E, 0xF5, 0xDF, 0xE3, 0xEE, 0xDC, 0x7B, -0x73, 0xED, 0x5C, 0x6A, 0x69, 0x5B, 0x70, 0x6D, 0xEF, 0xE1, 0xCF, 0xC8, 0xC4, 0xB9, 0xC5, 0xC2, -0xB6, 0xDC, 0xCD, 0xC3, 0x49, 0x60, 0x57, 0x3A, 0x40, 0x3D, 0x38, 0x3A, 0x3E, 0x3F, 0x3E, 0x53, -0x58, 0x59, 0xD3, 0xD7, 0xD2, 0xC4, 0xC9, 0xCA, 0xC8, 0xCD, 0xD8, 0xDE, 0xEE, 0x5F, 0x5D, 0x59, -0x4F, 0x54, 0x56, 0x54, 0x5D, 0x69, 0x6D, 0xF2, 0xE1, 0xDF, 0xDB, 0xD8, 0xDD, 0xE8, 0xEB, 0x71, -0x5D, 0x66, 0x56, 0x52, 0x62, 0x52, 0x5C, 0x74, 0x63, 0xE2, 0xDD, 0xD4, 0xCA, 0xC9, 0xBF, 0xC0, -0xBB, 0xBB, 0xCC, 0xBB, 0xC8, 0x68, 0xC8, 0x58, 0x44, 0x5D, 0x3C, 0x3B, 0x40, 0x3A, 0x3B, 0x3F, -0x44, 0x43, 0x52, 0x7A, 0x62, 0xD4, 0xCB, 0xD1, 0xC3, 0xC4, 0xC8, 0xC5, 0xCA, 0xD0, 0xD9, 0xE1, -0x6C, 0x5C, 0x5B, 0x4E, 0x4D, 0x50, 0x4C, 0x50, 0x58, 0x58, 0x63, 0x79, 0xFE, 0xED, 0xE1, 0xE7, -0xEE, 0xE6, 0xFB, 0x6D, 0x7A, 0x61, 0x5D, 0x62, 0x59, 0x5B, 0x5E, 0x5C, 0x64, 0x69, 0x72, 0xFE, -0xF1, 0xE6, 0xE2, 0xDB, 0xD9, 0xD6, 0xD3, 0xD3, 0xD0, 0xD0, 0xCF, 0xCE, 0xCD, 0xCD, 0xDA, 0xDB, -0xDA, 0x64, 0x69, 0x63, 0x4C, 0x4F, 0x4D, 0x46, 0x4A, 0x4A, 0x48, 0x4D, 0x52, 0x52, 0x5C, 0x70, -0x71, 0xEB, 0xDC, 0xDE, 0xD7, 0xD4, 0xD8, 0xD5, 0xD7, 0xDD, 0xDF, 0xE7, 0xFD, 0x71, 0x69, 0x5D, -0x5A, 0x5A, 0x57, 0x56, 0x5B, 0x59, 0x5A, 0x69, 0x62, 0x6A, 0xF5, 0x73, 0xF1, 0xE7, 0xF4, 0xE6, -0xE6, 0xEE, 0xEA, 0xED, 0xF5, 0xF1, 0xED, 0xF0, 0xEA, 0xE4, 0xE7, 0xDF, 0xDE, 0xDF, 0xDC, 0xDE, -0xDF, 0xE1, 0xE8, 0xEE, 0xFD, 0x77, 0x6B, 0x64, 0x61, 0x5C, 0x5C, 0x5C, 0x5B, 0x5F, 0x61, 0x67, -0x6E, 0x78, 0xF8, 0xF1, 0xEA, 0xE5, 0xE4, 0xE2, 0xE1, 0xE5, 0xEA, 0xED, 0xFA, 0x77, 0x6E, 0x66, -0x62, 0x5D, 0x5C, 0x5A, 0x59, 0x59, 0x59, 0x5B, 0x5C, 0x5D, 0x64, 0x64, 0x6C, 0x77, 0x7C, 0xEE, -0xEB, 0xE0, 0xDB, 0xD7, 0xCF, 0xCF, 0xCA, 0xC8, 0xC5, 0xC4, 0xCD, 0xC7, 0xCB, 0xE8, 0xD3, 0xFD, -0x55, 0x67, 0x4B, 0x45, 0x48, 0x40, 0x3F, 0x42, 0x43, 0x43, 0x4A, 0x50, 0x50, 0x6C, 0xF5, 0xF2, -0xD4, 0xD2, 0xD1, 0xCB, 0xCC, 0xCE, 0xCE, 0xD0, 0xDA, 0xDC, 0xDF, 0xFD, 0x7D, 0x6F, 0x5E, 0x5F, -0x5D, 0x59, 0x5A, 0x5C, 0x5C, 0x5F, 0x68, 0x68, 0x6F, 0xFC, 0xFC, 0xEF, 0xE9, 0xEB, 0xE9, 0xE9, -0xED, 0xEF, 0xF2, 0xF8, 0xFE, 0xFE, 0x7C, 0x7C, 0x7E, 0x79, 0xFE, 0xFB, 0xFE, 0xF7, 0xF6, 0xF9, -0xF6, 0xF8, 0xFD, 0xFF, 0x7C, 0x73, 0x70, 0x6E, 0x6A, 0x6A, 0x69, 0x68, 0x6A, 0x6B, 0x6C, 0x6F, -0x74, 0x79, 0xFF, 0xFA, 0xF8, 0xF2, 0xF4, 0xF6, 0xF3, 0xFE, 0xFB, 0x74, 0x62, 0x69, 0x5F, 0x5A, -0x66, 0x5B, 0x5D, 0x70, 0x61, 0x78, 0xED, 0xF4, 0xDB, 0xD7, 0xD0, 0xCB, 0xC9, 0xC3, 0xCC, 0xC9, -0xC4, 0xDD, 0xD2, 0xD7, 0x59, 0x6E, 0x57, 0x45, 0x4B, 0x45, 0x3F, 0x43, 0x44, 0x43, 0x49, 0x51, -0x4F, 0x5E, 0xFB, 0x70, 0xDE, 0xD8, 0xDC, 0xD1, 0xD2, 0xD7, 0xD4, 0xD6, 0xDD, 0xDF, 0xDF, 0xF1, -0xF2, 0xF2, 0x6F, 0x73, 0x72, 0x69, 0x6D, 0x6F, 0x6D, 0x72, 0x7B, 0x79, 0x7E, 0xF8, 0xFD, 0xF9, -0xF6, 0xFD, 0xFA, 0xFA, 0xFD, 0xFB, 0xFB, 0xFD, 0xFA, 0xF6, 0xF8, 0xF3, 0xF2, 0xF4, 0xEF, 0xF1, -0xF4, 0xF2, 0xF6, 0xF9, 0xF8, 0xF9, 0xFD, 0xFD, 0xFC, 0x7F, 0x7E, 0x7D, 0x79, 0x76, 0x74, 0x71, -0x6F, 0x6E, 0x6C, 0x6C, 0x6D, 0x6B, 0x6C, 0x6D, 0x6C, 0x71, 0x71, 0x70, 0x7E, 0x79, 0x7C, 0xFA, -0x7B, 0xFD, 0xFC, 0x7A, 0xFE, 0x7C, 0x78, 0x7B, 0x76, 0x76, 0x78, 0x77, 0x77, 0x7C, 0x7E, 0xFF, -0xF2, 0xF3, 0xED, 0xE7, 0xE8, 0xE0, 0xDE, 0xDC, 0xD7, 0xD8, 0xD3, 0xD4, 0xDA, 0xD7, 0xDF, 0xEB, -0xED, 0x6A, 0x60, 0x5C, 0x52, 0x4F, 0x4D, 0x4B, 0x4A, 0x4B, 0x4B, 0x4D, 0x50, 0x54, 0x5B, 0x66, -0x6F, 0xF1, 0xE6, 0xDF, 0xDA, 0xD8, 0xD8, 0xD7, 0xD9, 0xDB, 0xDE, 0xE2, 0xEA, 0xF1, 0xFA, 0x78, -0x70, 0x6D, 0x69, 0x68, 0x66, 0x65, 0x65, 0x66, 0x66, 0x67, 0x6A, 0x6B, 0x6C, 0x70, 0x74, 0x79, -0xFB, 0xF5, 0xEF, 0xEB, 0xE9, 0xE6, 0xE3, 0xE2, 0xE1, 0xE0, 0xE0, 0xE0, 0xE1, 0xE3, 0xE3, 0xE6, -0xE9, 0xEB, 0xEF, 0xF7, 0x7F, 0x75, 0x6E, 0x6A, 0x66, 0x62, 0x61, 0x5F, 0x5F, 0x60, 0x5F, 0x62, -0x65, 0x66, 0x6C, 0x6E, 0x72, 0x7D, 0xFE, 0xF6, 0xEF, 0xED, 0xE9, 0xE7, 0xE4, 0xE3, 0xE0, 0xDF, -0xE1, 0xDF, 0xE1, 0xE3, 0xE3, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xED, 0xF5, 0xF6, 0xF9, 0x75, -0x76, 0x6E, 0x66, 0x65, 0x5E, 0x5B, 0x5A, 0x56, 0x55, 0x54, 0x53, 0x54, 0x55, 0x57, 0x59, 0x5D, -0x60, 0x66, 0x70, 0x79, 0xFA, 0xF0, 0xEE, 0xEC, 0xED, 0xED, 0xF0, 0xF5, 0xF8, 0xFF, 0xFD, 0x7E, -0x7D, 0xFE, 0x7E, 0xFD, 0xF8, 0xF6, 0xEF, 0xED, 0xEB, 0xE8, 0xE4, 0xE3, 0xE0, 0xDF, 0xDE, 0xDC, -0xDD, 0xDC, 0xDD, 0xE1, 0xE2, 0xE9, 0xF3, 0x7A, 0x65, 0x61, 0x5B, 0x56, 0x56, 0x51, 0x50, 0x52, -0x50, 0x55, 0x58, 0x59, 0x5F, 0x68, 0x70, 0xFC, 0xEE, 0xE9, 0xE4, 0xE1, 0xE4, 0xE4, 0xE7, 0xED, -0xEE, 0xF8, 0xFF, 0x7D, 0x76, 0x76, 0x7A, 0x7B, 0xFF, 0xF9, 0xF7, 0xF1, 0xED, 0xED, 0xEB, 0xE9, -0xEA, 0xEA, 0xEC, 0xED, 0xEE, 0xF0, 0xF1, 0xF2, 0xF2, 0xF3, 0xF0, 0xF1, 0xF3, 0xEF, 0xF3, 0xF5, -0xF4, 0xFB, 0xFC, 0xFC, 0x7C, 0x7A, 0x76, 0x70, 0x6F, 0x6F, 0x6C, 0x6C, 0x6C, 0x68, 0x6B, 0x6B, -0x68, 0x6D, 0x6B, 0x6B, 0x6F, 0x6E, 0x70, 0x77, 0x76, 0x7A, 0x7F, 0xFF, 0xFD, 0xF6, 0xF7, 0xF5, -0xEF, 0xF4, 0xF1, 0xEF, 0xF2, 0xEE, 0xF0, 0xF1, 0xEE, 0xF0, 0xF1, 0xF1, 0xF2, 0xF6, 0xF9, 0xFA, -0x7F, 0x7E, 0x7A, 0x76, 0x7A, 0x73, 0x72, 0x74, 0x6F, 0x73, 0x75, 0x73, 0x75, 0x74, 0x76, 0x73, -0x77, 0x7A, 0x76, 0x7E, 0x78, 0x76, 0x7E, 0x76, 0x7A, 0x79, 0x74, 0x7D, 0x77, 0x77, 0x79, 0x74, -0x76, 0x77, 0x7A, 0x79, 0x7C, 0xFF, 0x79, 0xFC, 0xFA, 0x7E, 0xF4, 0xF9, 0xFC, 0xF6, 0x7E, 0xFF, -0xFF, 0x7B, 0x7C, 0x77, 0x75, 0x76, 0x78, 0x76, 0x74, 0x7B, 0x74, 0x75, 0x7E, 0x74, 0x7B, 0x7C, -0x72, 0x7A, 0x77, 0x74, 0x7A, 0x75, 0x72, 0x73, 0x72, 0x6E, 0x6E, 0x70, 0x6D, 0x70, 0x71, 0x6E, -0x75, 0x73, 0x72, 0x79, 0x78, 0x7B, 0xFF, 0xFF, 0xFD, 0xFA, 0xFC, 0xFB, 0xF7, 0xFD, 0xFE, 0xFA, -0x7D, 0x7D, 0xFE, 0x79, 0x7B, 0x7C, 0x7B, 0x7E, 0x7E, 0xFD, 0xFA, 0xFA, 0xF7, 0xF8, 0xF9, 0xF9, -0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x7D, 0x7B, 0x77, 0x78, 0x74, 0x71, 0x74, 0x6F, 0x6F, 0x71, 0x6D, -0x6F, 0x71, 0x6F, 0x73, 0x74, 0x77, 0x7B, 0x7D, 0x7F, 0xFF, 0xFC, 0xFE, 0xFB, 0xF8, 0xFB, 0xF7, -0xF9, 0xFE, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0x7E, 0x7C, 0x7E, 0x7B, 0x7B, 0x7E, 0x7C, 0xFF, 0xFE, -0xFE, 0xFB, 0xFE, 0xFF, 0xFD, 0xFE, 0x7E, 0x7F, 0x7A, 0x78, 0x79, 0x75, 0x74, 0x75, 0x73, 0x75, -0x77, 0x77, 0x79, 0x7B, 0x7D, 0xFF, 0xFA, 0xF8, 0xF4, 0xF2, 0xF5, 0xF1, 0xF2, 0xF6, 0xF3, 0xF6, -0xFA, 0xFB, 0xFC, 0x7D, 0x7A, 0x7A, 0x74, 0x77, 0x78, 0x74, 0x7A, 0x77, 0x7A, 0xFF, 0x7F, 0xF9, -0xFB, 0xFB, 0xF9, 0xFF, 0x7F, 0x7C, 0x7A, 0x77, 0x72, 0x73, 0x6E, 0x6E, 0x6E, 0x6D, 0x70, 0x70, -0x75, 0x7D, 0x7B, 0xFE, 0xFD, 0xFF, 0xFC, 0xFF, 0x7E, 0xFF, 0x7E, 0x7A, 0x79, 0x76, 0x6F, 0x72, -0x72, 0x6F, 0x73, 0x6F, 0x6E, 0x74, 0x72, 0x74, 0x7C, 0x7C, 0xFF, 0xF9, 0xFA, 0xF9, 0xF5, 0xF7, -0xF7, 0xF5, 0xFA, 0xFA, 0xF7, 0xFA, 0xF9, 0xF8, 0xFC, 0xF9, 0xF8, 0xFA, 0xF6, 0xF9, 0xFC, 0xFA, -0xFD, 0xFE, 0xFD, 0xFF, 0x7E, 0x7E, 0x7D, 0x7A, 0x7C, 0x7B, 0x79, 0x7C, 0x7B, 0x7B, 0xFF, 0x7E, -0xFF, 0xFC, 0xFE, 0xFE, 0xFB, 0xFD, 0x7C, 0x7F, 0x7F, 0x76, 0x78, 0x78, 0x74, 0x78, 0x78, 0x78, -0x7B, 0x7A, 0x7A, 0x79, 0x77, 0x78, 0x79, 0x78, 0x7A, 0x7B, 0x7A, 0x7C, 0x7F, 0x7D, 0xFF, 0xFC, -0xFD, 0xFA, 0xFB, 0xFD, 0xFE, 0xFF, 0x7F, 0x7D, 0x7C, 0x7A, 0x7B, 0x7D, 0x7D, 0x7E, 0x7E, 0x7D, -0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7F, 0xFF, 0xFE, 0xFC, 0xFC, 0xFB, -0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xFB, 0xFB, 0xFD, 0xFF, 0x7D, 0x7B, 0x7B, 0x7A, 0x77, 0x77, 0x78, -0x77, 0x77, 0x79, 0x7A, 0x7B, 0x7B, 0x7D, 0x7E, 0xFF, 0xFE, 0xFE, 0xFD, 0xFC, 0xFC, 0xFC, 0xFC, -0xFE, 0xFF, 0xFF, 0x7E, 0x7B, 0x78, 0x77, 0x76, 0x74, 0x73, 0x73, 0x71, 0x72, 0x73, 0x73, 0x74, -0x75, 0x76, 0x77, 0x77, 0x78, 0x78, 0x7A, 0x7D, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0x7F, 0x7E, 0x7D, 0x7D, 0x7C, 0x7A, 0x79, 0x79, 0x78, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7A, -0x79, 0x7B, 0x7B, 0x7B, 0x7C, 0x7A, 0x7A, 0x79, 0x78, 0x78, 0x76, 0x76, 0x75, 0x73, 0x73, 0x73, -0x74, 0x77, 0x79, 0x7A, 0x7D, 0x7F, 0xFE, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFF, -0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, -0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4C, 0x49, 0x53, 0x54, 0x4A, 0x00, -0x00, 0x00, 0x49, 0x4E, 0x46, 0x4F, 0x49, 0x53, 0x46, 0x54, 0x3E, 0x00, 0x00, 0x00, 0x46, 0x69, -0x6C, 0x65, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x6F, -0x6C, 0x64, 0x57, 0x61, 0x76, 0x65, 0x2E, 0x20, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x57, 0x61, 0x76, -0x65, 0x20, 0x63, 0x6F, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, -0x43, 0x68, 0x72, 0x69, 0x73, 0x20, 0x43, 0x72, 0x61, 0x69, 0x67, 0x00 - -}; - -static const uint8_t shaun_png[] PROGMEM = { - 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x57, 0x08, 0x06, 0x00, 0x00, 0x00, 0xF2, 0x0C, 0xE0, - 0x57, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4B, 0x47, 0x44, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xA0, - 0xBD, 0xA7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x42, 0x8A, 0x00, - 0x00, 0x42, 0x8A, 0x01, 0x34, 0xA8, 0x6C, 0x25, 0x00, 0x00, 0x00, 0x09, 0x76, 0x70, 0x41, 0x67, - 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x57, 0x00, 0x73, 0x4D, 0x3B, 0xD6, 0x00, 0x00, 0x1B, - 0x47, 0x49, 0x44, 0x41, 0x54, 0x78, 0xDA, 0xED, 0x9D, 0x79, 0x74, 0x14, 0x55, 0xBE, 0xC7, 0x3F, - 0x55, 0xDD, 0x49, 0x67, 0x5F, 0x3A, 0x7B, 0x42, 0x82, 0x61, 0x49, 0x02, 0x81, 0xB0, 0x29, 0x32, - 0x22, 0x3C, 0x16, 0x41, 0x45, 0x10, 0x15, 0x7D, 0x13, 0x65, 0xD0, 0x81, 0xE3, 0x7B, 0xCC, 0xD3, - 0x51, 0x04, 0xF5, 0xE1, 0xB8, 0xCE, 0xE6, 0x28, 0x22, 0x23, 0x33, 0x2C, 0x2A, 0x22, 0xEE, 0x02, - 0x22, 0x0C, 0x2A, 0x83, 0x28, 0x7B, 0x20, 0xC8, 0x92, 0x10, 0xD9, 0x97, 0x40, 0x08, 0x81, 0x90, - 0x3D, 0x64, 0x21, 0xE9, 0x4E, 0x3A, 0x5D, 0xF7, 0xFD, 0x71, 0xBB, 0x93, 0x0E, 0x10, 0xD2, 0x59, - 0x3A, 0x01, 0xCF, 0xFB, 0x9E, 0xD3, 0xE7, 0xA4, 0x6E, 0xA5, 0x6E, 0xDD, 0xFA, 0xFD, 0xEA, 0xFE, - 0xEE, 0xEF, 0xFE, 0xB6, 0x52, 0xB8, 0xFE, 0xA1, 0x03, 0x7A, 0x01, 0x43, 0x81, 0x9B, 0x80, 0x6A, - 0x60, 0x3F, 0xA0, 0x02, 0x8F, 0x00, 0xB7, 0x03, 0xA1, 0x80, 0x00, 0x72, 0x81, 0xAD, 0xC0, 0xC7, - 0xC0, 0x6E, 0xA0, 0xAE, 0xB3, 0x07, 0xFF, 0x4B, 0x43, 0x30, 0xF0, 0x67, 0x20, 0x1B, 0xB0, 0x20, - 0x89, 0xAE, 0x01, 0x95, 0x40, 0xB9, 0xED, 0xF8, 0x6A, 0xBF, 0x3C, 0xDB, 0x75, 0x81, 0xCD, 0xF4, - 0xAF, 0x03, 0x8C, 0x40, 0x2C, 0xD0, 0x13, 0x88, 0x00, 0x0C, 0x9D, 0xF9, 0xC0, 0x4A, 0x27, 0xDD, - 0xD7, 0x13, 0x88, 0x07, 0xFA, 0x03, 0x51, 0x36, 0x22, 0xE4, 0x03, 0x87, 0x80, 0x83, 0x48, 0x62, - 0x1B, 0x81, 0x85, 0x40, 0x72, 0x2B, 0xC7, 0xA9, 0x01, 0x5F, 0x00, 0x2F, 0x03, 0x35, 0xB6, 0xE3, - 0x0A, 0xDB, 0xDF, 0xDE, 0xC0, 0x48, 0x60, 0x22, 0x30, 0x08, 0xC9, 0x78, 0x3D, 0x92, 0xD1, 0x99, - 0xC0, 0x0F, 0xC0, 0x5A, 0xE0, 0x5C, 0x47, 0x13, 0xA6, 0xA3, 0x19, 0xA2, 0x07, 0x46, 0x00, 0x4F, - 0x22, 0x45, 0x4D, 0xD0, 0x65, 0x63, 0xB8, 0x84, 0x14, 0x47, 0xEF, 0x03, 0x09, 0xC0, 0x4B, 0x48, - 0xD1, 0x44, 0x40, 0x40, 0x00, 0x31, 0x31, 0x31, 0x54, 0x56, 0x56, 0x92, 0x93, 0x93, 0x83, 0xD5, - 0x6A, 0x25, 0x3A, 0x3A, 0x9A, 0x89, 0x13, 0x27, 0x32, 0x60, 0xC0, 0x00, 0xAC, 0x56, 0x2B, 0xBB, - 0x77, 0xEF, 0x66, 0xDD, 0xBA, 0x75, 0x14, 0x16, 0x16, 0xDA, 0xFB, 0xAB, 0x03, 0x4E, 0x23, 0x67, - 0x4D, 0x9D, 0x8D, 0xC0, 0xFB, 0x90, 0x22, 0xF0, 0x1E, 0xC0, 0xAB, 0x89, 0x71, 0x6A, 0xC0, 0x11, - 0xE0, 0x0D, 0xE0, 0x6B, 0xE4, 0xEC, 0xFC, 0xC5, 0xC1, 0x07, 0x78, 0x0D, 0x28, 0xA5, 0x69, 0x51, - 0x63, 0xFF, 0x99, 0x80, 0x2A, 0xFB, 0xF1, 0xC0, 0x81, 0x03, 0xC5, 0xA6, 0x4D, 0x9B, 0x44, 0x49, - 0x49, 0x89, 0xC8, 0xCA, 0xCA, 0x12, 0xAF, 0xBF, 0xFE, 0xBA, 0x78, 0xFC, 0xF1, 0xC7, 0x45, 0x5A, - 0x5A, 0x9A, 0xD0, 0x34, 0x4D, 0xD8, 0x51, 0x57, 0x57, 0x27, 0xB6, 0x6E, 0xDD, 0x2A, 0xFA, 0xF7, - 0xEF, 0xDF, 0x5C, 0xFF, 0x8D, 0x7E, 0x8A, 0xA2, 0x08, 0x55, 0x55, 0xAF, 0x76, 0xAE, 0x02, 0x78, - 0x0E, 0xF9, 0x22, 0x75, 0x08, 0x3A, 0x6A, 0x86, 0x78, 0x02, 0x7F, 0x05, 0x9E, 0x02, 0xDC, 0x00, - 0x14, 0x45, 0x21, 0x24, 0x24, 0x84, 0xE8, 0xE8, 0x68, 0xDC, 0xDD, 0xDD, 0xB9, 0x70, 0xE1, 0x02, - 0xB9, 0xB9, 0xB9, 0xD4, 0xD5, 0x35, 0x5E, 0x87, 0xBD, 0xBC, 0xBC, 0x58, 0xB1, 0x62, 0x05, 0x13, - 0x26, 0x4C, 0xA8, 0x6F, 0x13, 0x42, 0x20, 0x84, 0x40, 0x55, 0xD5, 0xAB, 0xDE, 0x6C, 0xD7, 0xAE, - 0x5D, 0x3C, 0xFC, 0xF0, 0xC3, 0xE4, 0xE4, 0xE4, 0x34, 0xFD, 0xE0, 0x8A, 0x42, 0x7C, 0x7C, 0x3C, - 0xF7, 0xDC, 0x73, 0x0F, 0xFD, 0xFA, 0xF5, 0xC3, 0xC3, 0xC3, 0x83, 0xEC, 0xEC, 0x6C, 0x36, 0x6C, - 0xD8, 0x40, 0x6A, 0x6A, 0x2A, 0x35, 0x35, 0x35, 0xF6, 0x7F, 0xAD, 0xB4, 0x8D, 0xFB, 0x73, 0xC0, - 0xDA, 0x41, 0xF4, 0x72, 0x39, 0x7E, 0x8F, 0x7C, 0xEB, 0x05, 0x20, 0xC2, 0xC2, 0xC2, 0xC4, 0x2B, - 0xAF, 0xBC, 0x22, 0x0E, 0x1E, 0x3C, 0x28, 0x2E, 0x5E, 0xBC, 0x28, 0x2A, 0x2A, 0x2A, 0x44, 0x56, - 0x56, 0x96, 0x58, 0xBC, 0x78, 0xB1, 0x48, 0x48, 0x48, 0x68, 0xF4, 0x96, 0xC6, 0xC4, 0xC4, 0x88, - 0x33, 0x67, 0xCE, 0x88, 0x96, 0xE2, 0xE3, 0x8F, 0x3F, 0x16, 0x77, 0xDE, 0x79, 0xA7, 0x78, 0xFE, - 0xF9, 0xE7, 0xC5, 0xBB, 0xEF, 0xBE, 0x2B, 0xDE, 0x7E, 0xFB, 0x6D, 0xF1, 0xE0, 0x83, 0x0F, 0x0A, - 0xA3, 0xD1, 0x28, 0xDC, 0xDC, 0xDC, 0xC4, 0xD4, 0xA9, 0x53, 0xC5, 0xE9, 0xD3, 0xA7, 0xAF, 0xB8, - 0xAE, 0xA2, 0xA2, 0x42, 0x2C, 0x58, 0xB0, 0x40, 0x04, 0x07, 0x07, 0x3B, 0x8E, 0xA3, 0x00, 0x58, - 0x0D, 0xFC, 0x0E, 0x08, 0xEF, 0x6C, 0x62, 0xB6, 0x15, 0x7D, 0x80, 0x33, 0xF6, 0x87, 0x8B, 0x8D, - 0x8D, 0x15, 0xEB, 0xD7, 0xAF, 0x6F, 0x24, 0x6A, 0x1C, 0x91, 0x91, 0x91, 0x21, 0x06, 0x0F, 0x1E, - 0x2C, 0x00, 0x61, 0x30, 0x18, 0xC4, 0xAF, 0x7F, 0xFD, 0x6B, 0x51, 0x51, 0x51, 0xD1, 0x62, 0x86, - 0x58, 0xAD, 0x56, 0x61, 0x36, 0x9B, 0x1B, 0xDD, 0xA7, 0xA6, 0xA6, 0x46, 0xEC, 0xD8, 0xB1, 0x43, - 0xAC, 0x5A, 0xB5, 0x4A, 0x94, 0x97, 0x97, 0x37, 0x79, 0xAD, 0xA6, 0x69, 0x62, 0xF1, 0xE2, 0xC5, - 0xC2, 0xC3, 0xC3, 0xE3, 0x72, 0x11, 0x66, 0x05, 0x76, 0x02, 0x43, 0x3A, 0x9B, 0xA8, 0x6D, 0xC1, - 0xDB, 0xF6, 0x07, 0xF2, 0xF5, 0xF5, 0x15, 0x2B, 0x56, 0xAC, 0x68, 0x96, 0x98, 0xC7, 0x8E, 0x1D, - 0x13, 0xF3, 0xE7, 0xCF, 0x17, 0x1B, 0x36, 0x6C, 0x10, 0xA5, 0xA5, 0xA5, 0x2D, 0x66, 0x46, 0x7B, - 0xA0, 0xB2, 0xB2, 0x52, 0x4C, 0x98, 0x30, 0xA1, 0xA9, 0x75, 0xE7, 0x00, 0x52, 0x31, 0x68, 0x77, - 0xB8, 0x7A, 0x0D, 0x89, 0x02, 0x36, 0xDA, 0x07, 0x3F, 0x79, 0xF2, 0x64, 0x3E, 0xFC, 0xF0, 0x43, - 0x0C, 0x86, 0x4E, 0x55, 0xF5, 0x9D, 0xC6, 0xC1, 0x83, 0x07, 0x59, 0xBB, 0x76, 0x2D, 0x16, 0x8B, - 0x85, 0x94, 0x94, 0x14, 0x52, 0x53, 0x53, 0xB1, 0x5A, 0xEB, 0x97, 0x91, 0xF7, 0x91, 0xDA, 0xE2, - 0x0D, 0xB5, 0xAE, 0x8C, 0x07, 0xCC, 0x80, 0xF0, 0xF4, 0xF4, 0x14, 0xEB, 0xD6, 0xAD, 0xEB, 0x94, - 0xB7, 0xBD, 0x3D, 0x50, 0x54, 0x54, 0x24, 0x92, 0x93, 0x93, 0x1D, 0x67, 0x49, 0x36, 0xD0, 0xBD, - 0xB3, 0x09, 0xDC, 0x12, 0x84, 0x00, 0xAB, 0xEC, 0x0F, 0x10, 0x1F, 0x1F, 0x2F, 0x72, 0x73, 0x73, - 0x3B, 0x9B, 0xAE, 0x6D, 0xC2, 0x96, 0x2D, 0x5B, 0x84, 0x8F, 0x8F, 0x8F, 0xA3, 0x6A, 0x7E, 0x47, - 0x7B, 0x13, 0x4D, 0x6D, 0x7B, 0x17, 0x57, 0x85, 0x37, 0x72, 0x53, 0x35, 0xC9, 0xDE, 0xD0, 0xAD, - 0x5B, 0x37, 0x8C, 0x46, 0xA3, 0x8B, 0x6E, 0xD7, 0x31, 0xF0, 0xF5, 0xF5, 0x45, 0xAF, 0xAF, 0xDF, - 0x92, 0xA8, 0x80, 0x47, 0x7B, 0xDF, 0xC3, 0x55, 0x0C, 0xF9, 0x4F, 0xE0, 0x37, 0xD8, 0xD6, 0xA8, - 0x84, 0x84, 0x04, 0x9E, 0x7E, 0xFA, 0x69, 0x3C, 0x3C, 0xDA, 0x7D, 0xFC, 0x1D, 0x8A, 0x5D, 0xBB, - 0x76, 0x51, 0x56, 0x56, 0x66, 0x3F, 0xAC, 0x42, 0xDA, 0xCC, 0xDA, 0x15, 0xAE, 0xD8, 0x81, 0x1A, - 0x81, 0xC7, 0xB1, 0x19, 0xE9, 0x12, 0x12, 0x12, 0xF8, 0xEC, 0xB3, 0xCF, 0xB8, 0xF9, 0xE6, 0x9B, - 0x5D, 0x44, 0xA6, 0x8E, 0x43, 0x5E, 0x5E, 0x23, 0xFA, 0x0B, 0x5C, 0xF7, 0x42, 0xB7, 0x2B, 0x46, - 0x21, 0x6D, 0x52, 0x42, 0xAF, 0xD7, 0x8B, 0x25, 0x4B, 0x96, 0x74, 0xB6, 0xE8, 0x6F, 0x37, 0xEC, - 0xDD, 0xBB, 0x57, 0x84, 0x86, 0x86, 0x3A, 0x2E, 0xEC, 0xB3, 0xDB, 0x9B, 0x78, 0xAE, 0xE0, 0x70, - 0x12, 0x72, 0x0D, 0xA1, 0x6B, 0xD7, 0xAE, 0x8C, 0x1D, 0x3B, 0xD6, 0x85, 0xBC, 0xEF, 0x58, 0x24, - 0x25, 0x25, 0x31, 0x64, 0x48, 0xA3, 0x3D, 0xE1, 0x2D, 0xB4, 0xB3, 0x94, 0x71, 0x05, 0x43, 0x22, - 0xED, 0x7F, 0x44, 0x47, 0x47, 0x13, 0x12, 0x12, 0xE2, 0x1A, 0xEA, 0x74, 0x02, 0x0C, 0x06, 0x03, - 0x89, 0x89, 0x89, 0x8E, 0x4D, 0x51, 0x48, 0x3B, 0x5D, 0xBB, 0xC1, 0x15, 0x0C, 0xA9, 0xEF, 0x53, - 0xA7, 0xD3, 0x35, 0x69, 0x00, 0xBC, 0x51, 0xE1, 0xEB, 0xEB, 0xEB, 0x78, 0x68, 0xE0, 0x06, 0x98, - 0x21, 0xF5, 0xCE, 0x88, 0xBC, 0xBC, 0x3C, 0x47, 0xAD, 0xE4, 0x17, 0x81, 0xD2, 0xD2, 0x52, 0xC7, - 0xC3, 0x6A, 0xDA, 0xD9, 0x57, 0xE2, 0x0A, 0x86, 0x1C, 0x46, 0xEE, 0xCE, 0xC9, 0xCA, 0xCA, 0x22, - 0x35, 0x35, 0xD5, 0x65, 0xC4, 0xE9, 0x68, 0x54, 0x55, 0x55, 0x91, 0x91, 0x91, 0xE1, 0xD8, 0x94, - 0x8D, 0x64, 0xCA, 0x75, 0x8D, 0x70, 0xE0, 0x67, 0x6C, 0x9A, 0xC8, 0xD0, 0xA1, 0x43, 0x45, 0x76, - 0x76, 0x76, 0x67, 0x2B, 0x48, 0xED, 0x82, 0x1F, 0x7E, 0xF8, 0x41, 0xF8, 0xF9, 0xF9, 0x39, 0x6A, - 0x59, 0x4F, 0x74, 0x36, 0xB1, 0x9D, 0xC5, 0x73, 0x48, 0xA3, 0x9B, 0x00, 0xC4, 0xC8, 0x91, 0x23, - 0xC5, 0x8F, 0x3F, 0xFE, 0x28, 0xCC, 0x66, 0xB3, 0xCB, 0x88, 0x65, 0xB5, 0x5A, 0x5D, 0xCA, 0x8C, - 0xAC, 0xAC, 0x2C, 0x31, 0x6C, 0xD8, 0x30, 0x47, 0x66, 0x64, 0x01, 0x71, 0x9D, 0x4D, 0x68, 0x67, - 0x61, 0x04, 0xD6, 0x39, 0x0C, 0x5E, 0xF8, 0xF8, 0xF8, 0x88, 0x05, 0x0B, 0x16, 0xB8, 0x84, 0x58, - 0x99, 0x99, 0x99, 0x62, 0xFA, 0xF4, 0xE9, 0x62, 0xD9, 0xB2, 0x65, 0xC2, 0x64, 0x32, 0x5D, 0x71, - 0x5E, 0xD3, 0x34, 0x71, 0xEE, 0xDC, 0x39, 0x91, 0x97, 0x97, 0xD7, 0xAA, 0xFE, 0x4F, 0x9E, 0x3C, - 0x29, 0x46, 0x8C, 0x18, 0x71, 0xB9, 0x09, 0xFE, 0xF5, 0xCE, 0x26, 0xB2, 0xB3, 0x08, 0x46, 0x5A, - 0x79, 0x1B, 0x31, 0x04, 0x10, 0x49, 0x49, 0x49, 0x22, 0x27, 0x27, 0xA7, 0x5D, 0x99, 0x61, 0xB5, - 0x5A, 0xC5, 0x8C, 0x19, 0x33, 0x04, 0x20, 0xBC, 0xBC, 0xBC, 0xC4, 0xA3, 0x8F, 0x3E, 0x2A, 0x36, - 0x6F, 0xDE, 0x2C, 0xCE, 0x9F, 0x3F, 0x2F, 0x0A, 0x0B, 0x0B, 0xC5, 0xE1, 0xC3, 0x87, 0xC5, 0xDC, - 0xB9, 0x73, 0x45, 0x42, 0x42, 0x82, 0x18, 0x33, 0x66, 0x8C, 0x28, 0x28, 0x28, 0x68, 0xF1, 0x3D, - 0x96, 0x2E, 0x5D, 0x7A, 0x39, 0x33, 0x34, 0x60, 0x3B, 0xF0, 0xDF, 0x40, 0x37, 0x64, 0x38, 0xD1, - 0x75, 0x87, 0x28, 0xA4, 0xEF, 0x79, 0x2F, 0x36, 0x93, 0x3B, 0x57, 0x09, 0x26, 0x98, 0x35, 0x6B, - 0x56, 0xBB, 0x8A, 0xAE, 0x6D, 0xDB, 0xB6, 0x89, 0xD0, 0xD0, 0x50, 0xE1, 0xED, 0x69, 0x10, 0xE1, - 0xC1, 0x01, 0x02, 0x10, 0x9E, 0x5E, 0x5E, 0xA2, 0x5B, 0xB7, 0xEE, 0xA2, 0x57, 0xAF, 0x5E, 0x22, - 0x38, 0x24, 0x44, 0x28, 0x8A, 0x22, 0x00, 0xE1, 0xE6, 0xE6, 0x26, 0x3E, 0xFA, 0xE8, 0xA3, 0x16, - 0xDF, 0x63, 0xCD, 0x9A, 0x35, 0x42, 0xAF, 0xD7, 0x5F, 0xCD, 0x51, 0x55, 0x87, 0x14, 0x5D, 0x0B, - 0x80, 0x5B, 0x01, 0xF7, 0xB6, 0x12, 0xB1, 0x3D, 0x38, 0x1B, 0x0A, 0x4C, 0x07, 0xE6, 0x21, 0x0D, - 0x8A, 0x5D, 0x70, 0xD0, 0xCD, 0x75, 0x3A, 0x1D, 0xE1, 0xE1, 0xE1, 0x24, 0x25, 0x25, 0x61, 0x36, - 0x9B, 0x49, 0x4D, 0x4D, 0xC5, 0x64, 0x32, 0xD1, 0xB7, 0x6F, 0x5F, 0x7C, 0x7C, 0x7C, 0x00, 0x19, - 0xB4, 0x50, 0x50, 0x50, 0x40, 0x59, 0x59, 0x19, 0xBE, 0xBE, 0xBE, 0x28, 0x8A, 0x73, 0x7E, 0xB3, - 0xEC, 0xEC, 0x6C, 0x9E, 0x7E, 0xFA, 0x69, 0x8E, 0x1D, 0x3B, 0xC6, 0x8C, 0x87, 0xC7, 0x31, 0x77, - 0xC6, 0x14, 0x02, 0xFD, 0x7C, 0xA8, 0xAA, 0x36, 0x51, 0x5A, 0x5A, 0x42, 0x65, 0x45, 0x39, 0x81, - 0x3E, 0x06, 0xEE, 0xFC, 0x55, 0x7F, 0x86, 0x0D, 0x48, 0x20, 0xFD, 0xE8, 0x69, 0xB2, 0xB3, 0xCF, - 0x72, 0xC7, 0x1D, 0x77, 0xB4, 0xC8, 0xF2, 0xBC, 0x7E, 0xFD, 0x7A, 0x36, 0x6C, 0xD8, 0x80, 0x9F, - 0x9F, 0x1F, 0x3A, 0x9D, 0x0E, 0x8B, 0xA5, 0x5E, 0xD3, 0x55, 0x91, 0xC1, 0x78, 0x83, 0x81, 0xFB, - 0x81, 0xDE, 0x40, 0x11, 0xD2, 0xE8, 0xA8, 0xB5, 0x03, 0x6D, 0x5B, 0x04, 0x37, 0xA4, 0x68, 0x4A, - 0x45, 0xBE, 0x29, 0x8D, 0x66, 0x42, 0x97, 0x2E, 0x5D, 0xC4, 0x23, 0x8F, 0x3C, 0x22, 0x3E, 0xF9, - 0xE4, 0x13, 0x71, 0xEC, 0xD8, 0x31, 0x51, 0x55, 0x55, 0x25, 0x5E, 0x7A, 0xE9, 0x25, 0x01, 0x08, - 0x9D, 0x4E, 0x27, 0x06, 0x0E, 0x1A, 0x24, 0x66, 0xCF, 0x9E, 0x2D, 0xE6, 0xCF, 0x9F, 0x2F, 0x66, - 0xCE, 0x9C, 0x29, 0xFA, 0xF4, 0xE9, 0x23, 0x7A, 0xF7, 0xEE, 0x2D, 0xD6, 0xAC, 0x59, 0xE3, 0xD4, - 0x02, 0x9D, 0x99, 0x99, 0x29, 0xC6, 0x8D, 0x1B, 0x27, 0x95, 0x86, 0x9B, 0x13, 0x45, 0xEE, 0x86, - 0x25, 0x42, 0x64, 0xAC, 0x16, 0x5A, 0xFA, 0x2A, 0x51, 0xB6, 0xED, 0x63, 0x71, 0xFA, 0x9B, 0x05, - 0xE2, 0xF8, 0xD7, 0xF3, 0xC5, 0x85, 0x0D, 0xEF, 0x0B, 0xCB, 0xDE, 0x15, 0xA2, 0x74, 0xFB, 0x27, - 0x62, 0xFC, 0xB0, 0x41, 0x02, 0x10, 0x77, 0xDF, 0x7D, 0xB7, 0x38, 0x7A, 0xF4, 0x68, 0xA3, 0xFE, - 0x34, 0x4D, 0x13, 0xFB, 0xF7, 0xEF, 0x17, 0x6F, 0xBD, 0xF5, 0x96, 0xD8, 0xBD, 0x7B, 0xB7, 0xB0, - 0x58, 0x2C, 0xC2, 0x62, 0xB1, 0x88, 0x6D, 0xDB, 0xB6, 0x89, 0xB8, 0xB8, 0x38, 0xE1, 0xEE, 0xEE, - 0x2E, 0xDE, 0x7B, 0xEF, 0x3D, 0xB1, 0x69, 0xD3, 0x26, 0xF1, 0xDC, 0x73, 0xCF, 0x89, 0x7E, 0xFD, - 0xFA, 0x09, 0x77, 0x77, 0xF7, 0xAB, 0xCD, 0x9A, 0x12, 0xE0, 0x03, 0x64, 0x10, 0x60, 0x87, 0xC5, - 0xBD, 0x45, 0x20, 0x67, 0x44, 0x99, 0xE3, 0x60, 0x74, 0x3A, 0x9D, 0x48, 0x4A, 0x4A, 0x12, 0x6F, - 0xBE, 0xF9, 0xA6, 0x38, 0x76, 0xEC, 0x98, 0xB0, 0x58, 0x2C, 0xF5, 0x0F, 0x6C, 0x32, 0x99, 0xC4, - 0xA4, 0x49, 0x93, 0x04, 0x20, 0xBA, 0x84, 0x1A, 0x85, 0xA7, 0xC1, 0xAD, 0xD1, 0x83, 0x78, 0xB8, - 0xBB, 0x09, 0x9D, 0xAA, 0x8A, 0xA0, 0xA0, 0x20, 0xF1, 0xDA, 0x6B, 0xAF, 0x89, 0xB3, 0x67, 0xCF, - 0x5E, 0x35, 0x10, 0xA2, 0xA2, 0xA2, 0x42, 0xAC, 0x5C, 0xB9, 0x52, 0x0C, 0x18, 0x30, 0x40, 0x00, - 0xE2, 0x96, 0xDE, 0xDD, 0xC5, 0xC1, 0x95, 0x6F, 0x0B, 0xB1, 0xFF, 0x6B, 0x21, 0xD2, 0xBE, 0x92, - 0xBF, 0xF4, 0x55, 0x42, 0xEC, 0x5F, 0x25, 0xDB, 0xD2, 0x57, 0xC9, 0xB6, 0xFD, 0x5F, 0x8B, 0xC3, - 0x5F, 0xFD, 0x5D, 0x0C, 0x4E, 0xEC, 0x21, 0x00, 0xD1, 0xA3, 0x47, 0x0F, 0xF1, 0x87, 0x3F, 0xFC, - 0x41, 0xAC, 0x5A, 0xB5, 0x4A, 0xAC, 0x5C, 0xB9, 0x52, 0xCC, 0x9A, 0x35, 0x4B, 0xC4, 0xC4, 0xC4, - 0x08, 0x40, 0x84, 0x87, 0x87, 0x8B, 0xFB, 0xEE, 0xBB, 0x4F, 0x4C, 0x9C, 0x38, 0xB1, 0xDE, 0x98, - 0x38, 0x79, 0xF2, 0xE4, 0xFA, 0x60, 0x0B, 0x4D, 0xD3, 0x44, 0x7E, 0x7E, 0xBE, 0x58, 0xBE, 0x7C, - 0xB9, 0x18, 0x3F, 0x7E, 0xBC, 0xF0, 0xF5, 0xF5, 0xBD, 0x1A, 0x63, 0xCE, 0x21, 0x8D, 0x8F, 0xC1, - 0x2D, 0x21, 0x6C, 0x4B, 0x39, 0xA8, 0x20, 0x83, 0x9E, 0x5F, 0x07, 0x86, 0x39, 0x5E, 0x1F, 0x17, - 0x17, 0xC7, 0xF4, 0xE9, 0xD3, 0x49, 0x4E, 0x4E, 0x26, 0x32, 0x32, 0xF2, 0x8A, 0x0B, 0x77, 0xEC, - 0xD8, 0xC1, 0x84, 0x09, 0x13, 0xF0, 0xD4, 0x2B, 0x2C, 0xFF, 0xDB, 0x33, 0x58, 0xEA, 0xEA, 0x48, - 0x3B, 0x7A, 0x9A, 0xD2, 0x8A, 0x4B, 0x04, 0x07, 0xF8, 0x31, 0xA8, 0x57, 0x37, 0x52, 0x7F, 0x3E, - 0xCE, 0x3F, 0x96, 0xAF, 0xA7, 0xEC, 0x52, 0x35, 0x71, 0xF1, 0xF1, 0xDC, 0x39, 0x76, 0x2C, 0x03, - 0x07, 0x0E, 0x24, 0x28, 0x28, 0x88, 0xAA, 0xAA, 0x2A, 0x4E, 0x9C, 0x38, 0xC1, 0x96, 0x2D, 0x5B, - 0xD8, 0xB3, 0x67, 0x0F, 0x96, 0xDA, 0x5A, 0xEE, 0xBA, 0xAD, 0x3F, 0x73, 0x9F, 0x99, 0x42, 0xAF, - 0x6E, 0xD1, 0xA0, 0x39, 0x21, 0x21, 0x54, 0x95, 0x13, 0x67, 0xCE, 0xF3, 0xA7, 0x25, 0xAB, 0xF8, - 0x76, 0x7B, 0x1A, 0x55, 0xE6, 0x1A, 0xDB, 0x23, 0x08, 0x00, 0x02, 0x7C, 0xBD, 0x49, 0xEA, 0x19, - 0xC3, 0xD1, 0xAC, 0xF3, 0x14, 0x97, 0x55, 0xA2, 0x28, 0x0A, 0xE1, 0xE1, 0xE1, 0x24, 0x27, 0x27, - 0x33, 0x7B, 0xF6, 0x6C, 0xC2, 0xC2, 0xC2, 0xAE, 0xE8, 0xB2, 0xBA, 0xBA, 0x9A, 0xD4, 0xD4, 0x54, - 0x96, 0x2E, 0x5D, 0xCA, 0xF7, 0xDF, 0x7F, 0x4F, 0x65, 0x65, 0xA5, 0xE3, 0x69, 0x2B, 0xB0, 0x03, - 0xF8, 0x13, 0x90, 0x82, 0x13, 0x62, 0xAC, 0x25, 0x0C, 0x71, 0x03, 0x26, 0x03, 0x7F, 0x41, 0xAE, - 0x13, 0x80, 0xB4, 0xED, 0x4C, 0x99, 0x32, 0x85, 0x99, 0x33, 0x67, 0xD2, 0xA3, 0x47, 0x8F, 0xAB, - 0x5E, 0x28, 0x84, 0x60, 0xC6, 0x8C, 0x19, 0x2C, 0x58, 0xB0, 0x80, 0xA9, 0xF7, 0x8E, 0x64, 0xC9, - 0x2B, 0xBF, 0xB3, 0x79, 0xDE, 0x84, 0xA4, 0x85, 0x22, 0x87, 0x52, 0x67, 0xA9, 0x63, 0xEB, 0xDE, - 0x43, 0xFC, 0x73, 0xE5, 0xF7, 0x6C, 0x4F, 0x3F, 0x42, 0x65, 0xB5, 0x59, 0x0E, 0x52, 0x51, 0x11, - 0x42, 0x3E, 0x8B, 0x5E, 0xA7, 0x92, 0xD8, 0x2D, 0x9A, 0x69, 0x13, 0x47, 0x32, 0xE5, 0x9E, 0xFF, - 0x20, 0xD0, 0xDF, 0xD7, 0x39, 0x66, 0x38, 0x30, 0xA5, 0xDA, 0x64, 0x66, 0xD7, 0x81, 0x13, 0x6C, - 0xD9, 0x77, 0x98, 0xAC, 0xDC, 0x02, 0x54, 0x45, 0xA1, 0x67, 0x4C, 0x04, 0x63, 0x6E, 0x4D, 0x62, - 0x50, 0xAF, 0x6E, 0x7C, 0xBA, 0x6E, 0x3B, 0x4F, 0xCE, 0x59, 0x4A, 0x78, 0x44, 0x24, 0x5F, 0x7E, - 0xF9, 0x25, 0x43, 0x87, 0x0E, 0x45, 0xA7, 0xBB, 0xF6, 0x72, 0x6B, 0x36, 0x9B, 0xD9, 0xB6, 0x6D, - 0x1B, 0x0B, 0x17, 0x2E, 0x64, 0xD3, 0xA6, 0x4D, 0x8E, 0x81, 0x76, 0x20, 0xE3, 0xBA, 0xDE, 0x04, - 0x96, 0xD0, 0xCC, 0xCE, 0xDE, 0x59, 0x86, 0xF8, 0x02, 0xFF, 0x0B, 0x3C, 0x83, 0x0C, 0x09, 0x05, - 0x20, 0x31, 0x31, 0x91, 0x3F, 0xFE, 0xF1, 0x8F, 0xDC, 0x7B, 0xEF, 0xBD, 0xB8, 0xBB, 0x37, 0xAD, - 0x60, 0x9C, 0x39, 0x73, 0x86, 0x31, 0x63, 0xC7, 0x92, 0x9B, 0x73, 0x96, 0x7F, 0xCD, 0x7B, 0x9E, - 0xBB, 0x6E, 0x1F, 0x08, 0xD6, 0x26, 0x88, 0xA8, 0x53, 0xA9, 0xAA, 0x32, 0xF1, 0xF3, 0xF1, 0x33, - 0xEC, 0x3C, 0x70, 0x82, 0xE3, 0xD9, 0xB9, 0x54, 0x5C, 0xAA, 0xC6, 0xD3, 0xC3, 0x40, 0x4C, 0x78, - 0x30, 0x83, 0x13, 0xBB, 0x33, 0xA4, 0x6F, 0x1C, 0xE1, 0x21, 0x81, 0x36, 0xE1, 0x20, 0x9C, 0x67, - 0x86, 0xE3, 0x53, 0xAB, 0x2A, 0x08, 0xD0, 0xEA, 0xAC, 0xA0, 0x80, 0xAA, 0xD3, 0xD5, 0x4F, 0x96, - 0xBC, 0xA2, 0x52, 0xEE, 0x7A, 0xF2, 0xAF, 0x1C, 0x3D, 0x9B, 0xC7, 0x8A, 0xE5, 0xCB, 0x99, 0x34, - 0x69, 0x92, 0xD3, 0x5D, 0x57, 0x56, 0x56, 0xB2, 0x62, 0xC5, 0x0A, 0xE6, 0xCD, 0x9B, 0xC7, 0x89, - 0x13, 0x27, 0x1C, 0x4F, 0xD5, 0x00, 0xCB, 0x80, 0x57, 0x81, 0xE2, 0xB6, 0x30, 0x24, 0x10, 0x29, - 0xA2, 0xFE, 0x0B, 0x9B, 0xF6, 0xA4, 0xD7, 0xEB, 0x79, 0xE0, 0x81, 0x07, 0xF8, 0xF3, 0x9F, 0xFF, - 0x4C, 0x7C, 0x7C, 0x7C, 0xB3, 0x1D, 0x2C, 0x59, 0xB2, 0x84, 0xE9, 0xD3, 0xA7, 0x33, 0x6C, 0x40, - 0x02, 0xDF, 0xBE, 0xF3, 0x02, 0x01, 0xBE, 0xDE, 0xD7, 0x26, 0xA4, 0x9D, 0x60, 0x80, 0xB0, 0x6A, - 0x68, 0x9A, 0x86, 0xAA, 0x28, 0x28, 0x3A, 0x1D, 0x28, 0x8A, 0x9C, 0x11, 0xAD, 0x61, 0x84, 0xB3, - 0x50, 0x14, 0x5E, 0x5A, 0xB4, 0x9C, 0xBF, 0x2D, 0x5B, 0x43, 0x72, 0x72, 0x32, 0x9F, 0x7E, 0xFA, - 0x29, 0x6E, 0x6E, 0x6E, 0x2D, 0xEA, 0x22, 0x33, 0x33, 0x93, 0xD7, 0x5F, 0x7F, 0x9D, 0x15, 0x2B, - 0x56, 0x38, 0xCE, 0x16, 0x0D, 0x19, 0x01, 0x39, 0x13, 0x99, 0xCB, 0x72, 0x05, 0x9A, 0x33, 0x2E, - 0x86, 0x00, 0xFF, 0x40, 0xAA, 0xB5, 0x7A, 0x90, 0x22, 0xEA, 0x85, 0x17, 0x5E, 0x60, 0xC9, 0x92, - 0x25, 0x4E, 0x31, 0xC3, 0x6C, 0x36, 0xB3, 0x6E, 0xDD, 0x3A, 0x00, 0x26, 0x0C, 0xBF, 0x99, 0x00, - 0x7F, 0x9F, 0xE6, 0x89, 0x29, 0x90, 0x33, 0xC8, 0xAA, 0xA1, 0x00, 0x3A, 0x55, 0x95, 0xAA, 0xB0, - 0xA6, 0x81, 0xD5, 0xEA, 0x5A, 0x66, 0x00, 0xA8, 0x0A, 0x13, 0x86, 0x0F, 0x22, 0xC0, 0xD7, 0x8B, - 0x94, 0x94, 0x14, 0x32, 0x33, 0x33, 0x5B, 0xDC, 0x45, 0xCF, 0x9E, 0x3D, 0x59, 0xBC, 0x78, 0x31, - 0x73, 0xE6, 0xCC, 0x71, 0xF4, 0x09, 0xA9, 0xC0, 0x43, 0xC8, 0x7D, 0x4B, 0xC4, 0x55, 0x6F, 0x7D, - 0x8D, 0x3E, 0x8D, 0x34, 0xEC, 0x2D, 0x54, 0x80, 0x90, 0x90, 0x10, 0xDE, 0x79, 0xE7, 0x1D, 0x5E, - 0x7D, 0xF5, 0x55, 0xFC, 0xFD, 0xFD, 0x9D, 0x1A, 0xD8, 0xF1, 0xE3, 0xC7, 0xF9, 0x69, 0xF7, 0x6E, - 0x42, 0x02, 0xFD, 0x18, 0x3B, 0xA4, 0x9F, 0x7D, 0xFD, 0xBC, 0xBE, 0xA1, 0x69, 0xF4, 0xED, 0x11, - 0xC3, 0x2D, 0x89, 0x3D, 0xB8, 0x70, 0xE1, 0x02, 0x5B, 0xB7, 0x6E, 0x6D, 0x55, 0x37, 0x5E, 0x5E, - 0x5E, 0x3C, 0xF5, 0xD4, 0x53, 0x7C, 0xF0, 0xC1, 0x07, 0xC4, 0xC6, 0xC6, 0x3A, 0x9E, 0xBA, 0x1F, - 0x98, 0x03, 0x5C, 0x41, 0xC4, 0xA6, 0x18, 0xE2, 0x89, 0x4C, 0x1D, 0x98, 0x8C, 0x4D, 0xAC, 0x45, - 0x45, 0x45, 0xB1, 0x68, 0xD1, 0x22, 0xA6, 0x4D, 0x9B, 0xD6, 0xA2, 0xE9, 0xBB, 0x7D, 0xFB, 0x76, - 0x8A, 0x8B, 0x8A, 0xB8, 0xB5, 0x4F, 0x4F, 0xE2, 0xBB, 0x46, 0xB6, 0x6C, 0x01, 0xEE, 0x2C, 0x08, - 0xF0, 0xF6, 0xF6, 0x64, 0xDC, 0xD0, 0x01, 0x00, 0x6C, 0xD8, 0xB0, 0x01, 0xB3, 0xD9, 0xDC, 0xAA, - 0xAE, 0x54, 0x55, 0x65, 0xE2, 0xC4, 0x89, 0x2C, 0x5D, 0xBA, 0xF4, 0x72, 0xA5, 0xE7, 0x11, 0xE4, - 0xBA, 0xDC, 0xC8, 0xC1, 0x75, 0x35, 0x86, 0x28, 0xC0, 0xFF, 0x20, 0xC5, 0x94, 0x0A, 0x92, 0x19, - 0xEF, 0xBE, 0xFB, 0x2E, 0x0F, 0x3D, 0xF4, 0x90, 0xD3, 0xBB, 0x68, 0x90, 0xE2, 0x6A, 0xD3, 0xA6, - 0x4D, 0x00, 0x8C, 0x19, 0x92, 0x84, 0x87, 0xE7, 0x8D, 0x11, 0x42, 0x0A, 0x80, 0x80, 0x11, 0x83, - 0x12, 0x09, 0xF2, 0xF7, 0x21, 0x2D, 0x2D, 0x9D, 0xAC, 0xAC, 0xAC, 0x36, 0x75, 0x37, 0x6A, 0xD4, - 0x28, 0x16, 0x2D, 0x5A, 0x44, 0x54, 0x54, 0x94, 0xBD, 0x49, 0x87, 0xCC, 0x0A, 0xB8, 0xDF, 0xF1, - 0xFF, 0xAE, 0xC6, 0x90, 0x31, 0xC8, 0x0D, 0x8D, 0x01, 0xC0, 0x68, 0x34, 0x32, 0x6F, 0xDE, 0xBC, - 0x46, 0xF9, 0x19, 0xCE, 0x22, 0x3B, 0x3B, 0x9B, 0xF4, 0xFD, 0xFB, 0x09, 0xF2, 0xF7, 0x61, 0xF8, - 0x80, 0x5E, 0x37, 0x86, 0xB8, 0xB2, 0x43, 0x68, 0xC4, 0xC5, 0x44, 0x30, 0x20, 0x3E, 0x96, 0xFC, - 0xFC, 0x3C, 0x76, 0xED, 0xDA, 0xD5, 0xE6, 0x2E, 0xC7, 0x8E, 0x1D, 0xCB, 0x1B, 0x6F, 0xBC, 0xE1, - 0xE8, 0x06, 0xF6, 0x43, 0x66, 0x89, 0xDD, 0x64, 0x6F, 0xB8, 0x9C, 0x21, 0x91, 0x48, 0x51, 0x15, - 0x0A, 0xD2, 0xA9, 0xFF, 0xF2, 0xCB, 0x2F, 0xF3, 0xD0, 0x43, 0x0F, 0xB5, 0x6A, 0x00, 0xE9, 0xE9, - 0xE9, 0xE4, 0x5D, 0xC8, 0xA3, 0x4F, 0xF7, 0x18, 0x7A, 0x44, 0x87, 0x3B, 0xBF, 0x18, 0xAB, 0x2A, - 0xA8, 0xAA, 0x4C, 0xCC, 0x01, 0xD0, 0xA9, 0x52, 0xBB, 0x6A, 0x2D, 0x54, 0x05, 0x54, 0x15, 0xAB, - 0xA6, 0x61, 0xD5, 0xB4, 0xFA, 0xFE, 0xAF, 0x09, 0x01, 0x5E, 0x5E, 0x9E, 0x0C, 0x1F, 0xD8, 0x1B, - 0x80, 0x9D, 0x3B, 0x77, 0xA2, 0xB5, 0x83, 0xB8, 0x4D, 0x4E, 0x4E, 0x66, 0xFA, 0xF4, 0xE9, 0x8E, - 0x4D, 0xFD, 0x90, 0x41, 0xDB, 0x2A, 0x34, 0x96, 0x5F, 0x0A, 0x32, 0x21, 0xE5, 0x36, 0x7B, 0xC3, - 0x23, 0x8F, 0x3C, 0xC2, 0xF4, 0xE9, 0xD3, 0x5B, 0x1D, 0xA8, 0x20, 0xDD, 0xB7, 0x82, 0xDB, 0xFA, - 0xC5, 0xE3, 0xE3, 0xED, 0x09, 0x5A, 0x33, 0x0C, 0x51, 0x14, 0xAC, 0x9A, 0x46, 0xFA, 0xA1, 0x93, - 0xFC, 0x7B, 0xE7, 0x7E, 0x4E, 0x9D, 0xCB, 0xC7, 0xDB, 0xD3, 0xC0, 0x6D, 0x49, 0xF1, 0x8C, 0xBB, - 0x7D, 0x20, 0xA1, 0x41, 0x01, 0x2D, 0x5F, 0x83, 0x14, 0x85, 0x53, 0x39, 0x79, 0xFC, 0x6B, 0xCB, - 0x5E, 0xD2, 0x8F, 0x67, 0x61, 0xB5, 0x6A, 0x24, 0x76, 0x8F, 0xE6, 0xFE, 0x11, 0xB7, 0xD0, 0x37, - 0xEE, 0xA6, 0x6B, 0xAB, 0x99, 0x8A, 0xC2, 0xAD, 0x7D, 0x7B, 0xE2, 0xAE, 0xD7, 0x91, 0x91, 0x91, - 0x41, 0x49, 0x49, 0x49, 0x9B, 0xA3, 0x68, 0xDC, 0xDC, 0xDC, 0x78, 0xE6, 0x99, 0x67, 0x48, 0x49, - 0x49, 0x61, 0xEF, 0xDE, 0xBD, 0xF6, 0xE6, 0xC9, 0xC0, 0x72, 0x60, 0xBF, 0x23, 0x43, 0xFA, 0x03, - 0x53, 0xED, 0x07, 0x7D, 0xFA, 0xF4, 0xE1, 0xC5, 0x17, 0x5F, 0xC4, 0xCB, 0xCB, 0xCB, 0xE9, 0x9B, - 0x39, 0xA2, 0xAC, 0xAC, 0x8C, 0xFD, 0xFB, 0xF7, 0xA3, 0x53, 0x15, 0x86, 0xF4, 0xED, 0x09, 0x8A, - 0x4A, 0x73, 0x91, 0xFB, 0xB5, 0x96, 0x3A, 0x16, 0xAE, 0xFC, 0x9E, 0x39, 0x1F, 0x7F, 0x43, 0xE1, - 0xC5, 0xF2, 0xFA, 0xF6, 0x65, 0xDF, 0x6C, 0x65, 0xD8, 0x80, 0x04, 0xDE, 0x79, 0x76, 0x2A, 0xFD, - 0x13, 0x62, 0x9D, 0x67, 0x8A, 0xA2, 0xF0, 0x7D, 0xEA, 0x7E, 0x9E, 0x7D, 0xE7, 0x53, 0x8E, 0x9D, - 0x69, 0x50, 0xFB, 0xBF, 0xDE, 0xBC, 0x9B, 0x0F, 0xD7, 0x6E, 0xE6, 0x2F, 0xFF, 0x93, 0xCC, 0xA3, - 0xE3, 0xFF, 0x03, 0xB5, 0xA9, 0xD9, 0xA7, 0x69, 0xF4, 0x8E, 0xED, 0x42, 0xD7, 0x88, 0x10, 0x4E, - 0x67, 0x65, 0x71, 0xF2, 0xE4, 0xC9, 0x76, 0x09, 0x6B, 0x8A, 0x8A, 0x8A, 0x62, 0xE6, 0xCC, 0x99, - 0x4C, 0x9D, 0x3A, 0xD5, 0xAE, 0x2C, 0x44, 0x00, 0x8F, 0x02, 0x19, 0xF6, 0x17, 0x44, 0x05, 0xA6, - 0x61, 0x33, 0x89, 0xB8, 0xBB, 0xBB, 0x33, 0x6B, 0xD6, 0xAC, 0x26, 0x4D, 0x21, 0xCE, 0xE0, 0xEC, - 0xD9, 0xB3, 0x64, 0x9E, 0x3A, 0x45, 0x44, 0x70, 0x20, 0xBD, 0xBB, 0x75, 0x01, 0xD1, 0x0C, 0x11, - 0x55, 0x95, 0x55, 0x9B, 0x7E, 0xE2, 0xD5, 0xF7, 0xBE, 0x6A, 0xC4, 0x0C, 0x2F, 0x2F, 0x2F, 0xFC, - 0xFC, 0xFD, 0xD9, 0x96, 0x7E, 0x94, 0x67, 0xDE, 0xFE, 0x88, 0x82, 0xE2, 0x8B, 0xCE, 0x89, 0x2F, - 0x55, 0xE5, 0xF0, 0xE9, 0x1C, 0x66, 0xBC, 0xFD, 0x71, 0x23, 0x66, 0x18, 0x0C, 0x06, 0xC2, 0xC2, - 0xC2, 0x28, 0x2C, 0xAB, 0xE2, 0xF9, 0x7F, 0x7C, 0xCE, 0x96, 0x7D, 0x87, 0x9B, 0x16, 0x5F, 0x42, - 0x10, 0x1E, 0xE4, 0x4F, 0xBF, 0xB8, 0x9B, 0xA8, 0xBA, 0x74, 0x89, 0xB4, 0xB4, 0xB4, 0x36, 0x33, - 0xC3, 0x8E, 0x71, 0xE3, 0xC6, 0x31, 0x7C, 0xF8, 0x70, 0xC7, 0xA6, 0x7B, 0x80, 0x04, 0xFB, 0x48, - 0x12, 0x80, 0xFB, 0xEC, 0x67, 0x46, 0x8C, 0x18, 0xC1, 0x03, 0x0F, 0x3C, 0xD0, 0xA6, 0x1B, 0x1E, - 0x3D, 0x7A, 0x94, 0xD2, 0x92, 0x12, 0xE2, 0xBB, 0x46, 0x12, 0x19, 0x62, 0xBC, 0xB6, 0xB8, 0x52, - 0x14, 0xCA, 0x2B, 0x2E, 0xF1, 0xFE, 0xEA, 0x8D, 0x54, 0x99, 0x1A, 0xD4, 0xCB, 0xBE, 0x7D, 0xFB, - 0xB2, 0x72, 0xE5, 0x4A, 0x36, 0x6F, 0xDE, 0xCC, 0x13, 0x4F, 0x3C, 0xC1, 0x4F, 0x87, 0x32, 0xF9, - 0x2E, 0x25, 0x4D, 0xAE, 0x09, 0xCD, 0x41, 0x08, 0xBE, 0x58, 0xBF, 0x83, 0xCC, 0x9C, 0x86, 0x78, - 0x5C, 0xA3, 0xD1, 0xC8, 0xFC, 0xF9, 0xF3, 0x49, 0x49, 0x49, 0xE1, 0xBD, 0xF7, 0xDE, 0x45, 0xE8, - 0xDD, 0xF9, 0x60, 0xCD, 0x26, 0x2C, 0xB5, 0x4D, 0x47, 0xF2, 0xE8, 0xDD, 0xDD, 0xE4, 0x0C, 0x07, - 0xF6, 0xEC, 0xD9, 0xE3, 0x98, 0xB0, 0xD3, 0x26, 0xF8, 0xF9, 0xF9, 0x31, 0x79, 0xF2, 0x64, 0xC7, - 0x68, 0xFA, 0x58, 0x60, 0xBC, 0x9D, 0x21, 0xE3, 0xB1, 0xCD, 0x0E, 0x83, 0xC1, 0xC0, 0xB4, 0x69, - 0xD3, 0x9C, 0xDE, 0xF8, 0x35, 0x85, 0x43, 0x87, 0x0E, 0x01, 0x90, 0xD8, 0x3D, 0x06, 0x2F, 0x8F, - 0x66, 0xD4, 0x5D, 0x45, 0xE1, 0x6C, 0x5E, 0x11, 0xC7, 0xCE, 0x9C, 0x6F, 0xD4, 0xFC, 0xE4, 0x93, - 0x4F, 0x32, 0x7E, 0xFC, 0x78, 0x06, 0x0C, 0x18, 0xC0, 0x8B, 0x2F, 0xBE, 0x48, 0x74, 0xD7, 0x9B, - 0x48, 0xFD, 0xF9, 0x78, 0xD3, 0x76, 0x30, 0x07, 0x98, 0xCC, 0x35, 0xEC, 0x3D, 0x72, 0xAA, 0x51, - 0xDB, 0x98, 0x31, 0x63, 0x78, 0xFC, 0xF1, 0xC7, 0x89, 0x8B, 0x8B, 0xE3, 0xB1, 0xC7, 0x1E, 0x63, - 0xC2, 0x84, 0x09, 0xA4, 0x1F, 0x3B, 0x4D, 0x71, 0x59, 0xE5, 0x35, 0x66, 0x9D, 0x42, 0xBF, 0xB8, - 0x9B, 0x70, 0xD7, 0xEB, 0x38, 0x7E, 0xFC, 0x38, 0xE5, 0xE5, 0xE5, 0xCD, 0xDE, 0xDB, 0x59, 0x8C, - 0x1A, 0x35, 0x8A, 0xEE, 0xDD, 0xEB, 0x73, 0x7E, 0x74, 0xC0, 0x44, 0x15, 0xB9, 0x5B, 0xBC, 0xDB, - 0xDE, 0xDA, 0xB7, 0x6F, 0x5F, 0x46, 0x8F, 0x1E, 0xDD, 0xA6, 0x1B, 0x59, 0x2C, 0x16, 0x8E, 0x1E, - 0x3D, 0x2A, 0xFB, 0xEB, 0x11, 0xD3, 0xBC, 0x46, 0xA3, 0x80, 0xB9, 0xD6, 0x42, 0xAD, 0xA5, 0xF1, - 0xDB, 0x27, 0x1C, 0xB4, 0x32, 0x21, 0x04, 0x08, 0x41, 0xB5, 0xB9, 0x06, 0xAD, 0x39, 0x6D, 0x4D, - 0x01, 0xAB, 0x55, 0xC3, 0x5C, 0xD3, 0xF8, 0xCD, 0xB7, 0x58, 0x2C, 0xF5, 0x9A, 0x92, 0xA6, 0x69, - 0xD4, 0xD6, 0xD6, 0x52, 0x6B, 0xA9, 0xA3, 0xCE, 0x6A, 0x6D, 0xDA, 0xAA, 0x27, 0x34, 0x62, 0x23, - 0x43, 0x09, 0x35, 0xFA, 0x93, 0x9D, 0x9D, 0x4D, 0x4A, 0x4A, 0x0A, 0x15, 0x15, 0x15, 0x8D, 0xC6, - 0xD6, 0x52, 0x54, 0x57, 0x57, 0x93, 0x9E, 0x9E, 0xCE, 0xFB, 0xEF, 0xBF, 0x7F, 0x79, 0xE0, 0x5D, - 0x92, 0x1E, 0x48, 0x44, 0x66, 0xCA, 0x02, 0x70, 0xF7, 0xDD, 0x77, 0x13, 0x1C, 0xDC, 0x22, 0x9F, - 0xCA, 0x15, 0xA8, 0xA8, 0xA8, 0xE0, 0xCC, 0x99, 0x33, 0x78, 0xB8, 0xEB, 0xE9, 0x19, 0x13, 0x4E, - 0xB3, 0x1B, 0x10, 0x21, 0x08, 0x0F, 0x0A, 0x20, 0xD4, 0xE8, 0x47, 0x45, 0x55, 0x83, 0x75, 0x7A, - 0xD1, 0xA2, 0x45, 0x44, 0x44, 0x44, 0x10, 0x15, 0x15, 0xC5, 0x87, 0x1F, 0x7E, 0xC8, 0xE9, 0xAC, - 0xD3, 0x3C, 0x3C, 0xA2, 0x9F, 0xB4, 0xCC, 0x5E, 0x6B, 0x61, 0x17, 0xE0, 0xE5, 0x61, 0xA0, 0x47, - 0x74, 0x38, 0xBB, 0x0E, 0x36, 0x58, 0x5C, 0x37, 0x6E, 0xDC, 0xC8, 0xDC, 0xB9, 0x73, 0x19, 0x33, - 0x66, 0x0C, 0x3B, 0x76, 0xEC, 0xE0, 0xBB, 0xEF, 0xD6, 0x31, 0xA0, 0x47, 0x24, 0x81, 0xBE, 0xDE, - 0x4D, 0x0F, 0x51, 0x40, 0xA8, 0xD1, 0x9F, 0xAE, 0x11, 0x21, 0xA4, 0x1E, 0x38, 0xC1, 0x6F, 0x7F, - 0xFB, 0x5B, 0x12, 0x12, 0x12, 0x18, 0x32, 0x64, 0x08, 0x83, 0x07, 0x0F, 0xA6, 0x7B, 0xF7, 0xEE, - 0x44, 0x45, 0x45, 0x11, 0x18, 0x18, 0x88, 0xC1, 0x60, 0x40, 0xA7, 0xD3, 0xD5, 0x6F, 0x9E, 0x35, - 0x4D, 0xC3, 0x62, 0xB1, 0x50, 0x5D, 0x5D, 0x4D, 0x71, 0x71, 0x31, 0xA7, 0x4F, 0x9F, 0x26, 0x2D, - 0x2D, 0x8D, 0x94, 0x94, 0x14, 0x32, 0x32, 0x32, 0x28, 0x2E, 0xBE, 0xC2, 0xE8, 0x9B, 0xAB, 0x47, - 0xAA, 0xB9, 0x46, 0x00, 0x6F, 0x6F, 0x6F, 0x46, 0x8C, 0x18, 0xD1, 0x26, 0x66, 0x00, 0x14, 0x14, - 0x14, 0x90, 0x97, 0x9F, 0x4F, 0x90, 0xBF, 0x2F, 0x51, 0xA1, 0xC6, 0xE6, 0x37, 0x84, 0x9A, 0xA0, - 0x4B, 0x58, 0x10, 0xE3, 0x6E, 0x1F, 0xC8, 0x3F, 0x97, 0xAF, 0xAF, 0x6F, 0x3E, 0x7C, 0xF8, 0x30, - 0x0F, 0x3F, 0xFC, 0x30, 0xEE, 0xEE, 0xEE, 0x94, 0x57, 0x54, 0x10, 0x66, 0xF4, 0x63, 0xC2, 0xF0, - 0x41, 0x4E, 0x8D, 0x41, 0x75, 0xD3, 0x31, 0x69, 0xF4, 0xAD, 0xAC, 0xD9, 0xBA, 0x87, 0x4B, 0x36, - 0xBF, 0x4A, 0x65, 0x65, 0x25, 0xAF, 0xBD, 0xF6, 0x1A, 0x73, 0xE6, 0xCC, 0xA1, 0xBA, 0xBA, 0x1A, - 0x10, 0x3C, 0x74, 0xC7, 0x6D, 0xF8, 0xF8, 0x78, 0x35, 0xCD, 0x60, 0x21, 0xF0, 0xF1, 0xF2, 0x20, - 0xBE, 0x6B, 0x24, 0xA9, 0x07, 0x4E, 0x50, 0x5E, 0x5E, 0xCE, 0x9E, 0x3D, 0x7B, 0xD8, 0xB3, 0x67, - 0x0F, 0x3A, 0x9D, 0x0E, 0x1F, 0x1F, 0x1F, 0x42, 0x42, 0x42, 0x88, 0x88, 0x88, 0x20, 0x28, 0x28, - 0x08, 0x5F, 0x5F, 0x5F, 0x0C, 0x06, 0x03, 0x9A, 0xA6, 0x51, 0x5D, 0x5D, 0x4D, 0x59, 0x59, 0x19, - 0x85, 0x85, 0x85, 0x14, 0x14, 0x14, 0x50, 0x52, 0x52, 0xD2, 0x94, 0x09, 0x46, 0x43, 0x66, 0xF6, - 0xBE, 0xAA, 0x47, 0x3A, 0xE8, 0x55, 0x80, 0x2E, 0x5D, 0xBA, 0x90, 0x90, 0x90, 0xD0, 0x6A, 0x46, - 0x98, 0xCD, 0x66, 0x32, 0x32, 0x32, 0x58, 0xB8, 0x70, 0x21, 0x45, 0x85, 0x45, 0x0C, 0x4C, 0x88, - 0x25, 0xC8, 0xDF, 0xD7, 0xA9, 0x0D, 0xA1, 0xAA, 0x53, 0x99, 0xF9, 0xC8, 0x3D, 0x1C, 0x3C, 0x79, - 0x96, 0x6D, 0xE9, 0x47, 0xEA, 0xDB, 0x4D, 0x26, 0x13, 0x26, 0x93, 0x09, 0x1F, 0x4F, 0x0F, 0x66, - 0x3F, 0x76, 0x1F, 0x37, 0xF7, 0xEE, 0xEE, 0x9C, 0xDA, 0x6B, 0xD5, 0xB8, 0xEB, 0xB6, 0xFE, 0x3C, - 0x9D, 0x7C, 0x37, 0xF3, 0x3E, 0x5F, 0x47, 0x8D, 0x6D, 0xE1, 0xB6, 0x5A, 0xAD, 0x54, 0x56, 0x56, - 0xA2, 0x53, 0x55, 0x7E, 0x33, 0x6E, 0x38, 0x53, 0xC6, 0x0D, 0x6B, 0x76, 0x7C, 0x8A, 0x4E, 0x27, - 0x35, 0xC5, 0xCB, 0x6F, 0x61, 0xB5, 0x52, 0x5E, 0x5E, 0x4E, 0x79, 0x79, 0x39, 0xA7, 0x4E, 0x9D, - 0xA2, 0x15, 0xA8, 0x46, 0x46, 0x79, 0xAE, 0x04, 0xD6, 0x00, 0xE7, 0xF5, 0xC8, 0x48, 0x09, 0x40, - 0x9A, 0x8C, 0x5B, 0x2A, 0xAE, 0xEA, 0xEA, 0xEA, 0x38, 0x7F, 0xFE, 0x3C, 0x5B, 0xB7, 0x6E, 0x65, - 0xCD, 0x9A, 0x35, 0xEC, 0xDA, 0xB5, 0xAB, 0x5E, 0x2E, 0x46, 0x04, 0x07, 0xE0, 0xED, 0x61, 0x70, - 0x6E, 0x87, 0xAE, 0x09, 0x6E, 0x8A, 0x0A, 0xE5, 0xE3, 0x3F, 0x3D, 0xC9, 0x3F, 0x97, 0xAF, 0x67, - 0xDD, 0xCE, 0x74, 0x8A, 0x4A, 0x2B, 0x70, 0x73, 0xD3, 0xD3, 0x3B, 0xB6, 0x0B, 0xBF, 0x7B, 0x70, - 0x0C, 0xF7, 0x8F, 0xBA, 0x15, 0x55, 0x55, 0x9C, 0x36, 0xC1, 0xB8, 0xBB, 0xB9, 0xF1, 0xF2, 0xE3, - 0x0F, 0xD2, 0xA3, 0x4B, 0x38, 0x1F, 0x7D, 0xB7, 0x8D, 0x53, 0xE7, 0xF2, 0xD1, 0x34, 0x8D, 0xE8, - 0xB0, 0x20, 0x92, 0xEF, 0x1C, 0xCA, 0xB4, 0x89, 0xA3, 0xF1, 0x6F, 0xCE, 0x37, 0x63, 0x43, 0xD7, - 0x88, 0x10, 0x74, 0x3A, 0x15, 0xAB, 0x54, 0x28, 0x34, 0xA4, 0x93, 0xC9, 0x1B, 0x59, 0xC0, 0xC6, - 0x59, 0x33, 0x42, 0x1D, 0x32, 0x0E, 0xE1, 0x14, 0x32, 0x38, 0xE4, 0x47, 0x64, 0xD8, 0x54, 0x99, - 0xFD, 0x1F, 0xF4, 0x38, 0xD8, 0xE5, 0x2D, 0x16, 0x0B, 0x07, 0x0F, 0x1E, 0x24, 0x2A, 0x2A, 0x0A, - 0x3F, 0x3F, 0x3F, 0x0C, 0x06, 0x03, 0xAA, 0xCD, 0x17, 0xA1, 0x69, 0x1A, 0x75, 0x75, 0x75, 0x98, - 0x4C, 0x26, 0x4A, 0x4B, 0x4B, 0xC9, 0xCE, 0xCE, 0xE6, 0xC0, 0x81, 0x03, 0xEC, 0xDE, 0xBD, 0x9B, - 0x7D, 0xFB, 0xF6, 0x71, 0xEE, 0xDC, 0xB9, 0x2B, 0xEA, 0x94, 0x44, 0x86, 0x04, 0xE2, 0xEE, 0xD6, - 0x82, 0x68, 0x7D, 0x4D, 0xD0, 0x35, 0x32, 0x84, 0xB7, 0x9E, 0x99, 0xC2, 0xAC, 0xC9, 0xE3, 0x29, - 0xBC, 0x58, 0x8E, 0xC1, 0xDD, 0x8D, 0xE8, 0xB0, 0x20, 0x7C, 0x7D, 0xBC, 0x6D, 0x8E, 0x29, 0xE7, - 0xBB, 0x43, 0x08, 0x3C, 0x0D, 0x6E, 0x4C, 0xBD, 0x6F, 0x34, 0x93, 0x46, 0x0F, 0x21, 0xBF, 0xF8, - 0x22, 0x56, 0x4D, 0x10, 0x16, 0xE4, 0x4F, 0xA0, 0xBF, 0xAF, 0xA4, 0xA2, 0x53, 0x8B, 0xB3, 0x5C, - 0xE3, 0x3C, 0xDD, 0xDD, 0xB9, 0x24, 0xD5, 0xF2, 0x3A, 0xE0, 0x0F, 0xC8, 0x52, 0x4E, 0x7D, 0x80, - 0x18, 0x64, 0x5C, 0x5A, 0x28, 0x32, 0x11, 0x54, 0x8F, 0xD4, 0x9A, 0xAA, 0x6D, 0xC4, 0x2E, 0x45, - 0xC6, 0x6F, 0x1D, 0x47, 0x56, 0x27, 0x3A, 0x8B, 0x2C, 0x6C, 0x73, 0xC5, 0xCD, 0xF5, 0x38, 0x64, - 0x92, 0x6E, 0xDC, 0xB8, 0x91, 0x3D, 0x7B, 0xF6, 0x10, 0x1A, 0x1A, 0x4A, 0x68, 0x68, 0x28, 0x46, - 0xA3, 0x11, 0x2F, 0x2F, 0x2F, 0x54, 0x55, 0xA5, 0xB6, 0xB6, 0x96, 0xCA, 0xCA, 0x4A, 0x8A, 0x8B, - 0x8B, 0x29, 0x2C, 0x2C, 0xA4, 0xA4, 0xA4, 0x04, 0x93, 0xC9, 0x74, 0x4D, 0x6D, 0x23, 0x24, 0xD0, - 0x5F, 0x6A, 0x58, 0x2D, 0x31, 0x77, 0x68, 0x02, 0x9D, 0xA2, 0x10, 0x15, 0x16, 0x44, 0x54, 0x78, - 0x70, 0x3D, 0x61, 0x5B, 0x6D, 0xB6, 0x17, 0x80, 0xD0, 0xF0, 0xF3, 0xF1, 0xC2, 0xCF, 0xD7, 0xBB, - 0xA1, 0xBF, 0x96, 0x68, 0x49, 0x02, 0x42, 0x02, 0xFD, 0xF0, 0xF5, 0xF6, 0xB0, 0x33, 0xC4, 0x1D, - 0x39, 0x4B, 0x76, 0xD8, 0x7E, 0x20, 0x67, 0x89, 0x3B, 0x52, 0xFC, 0xEB, 0x6C, 0xC7, 0x16, 0x1B, - 0xF3, 0x9C, 0xAE, 0x6C, 0xA7, 0x07, 0x7E, 0x02, 0x46, 0x83, 0xD4, 0x0A, 0xCA, 0xCA, 0xCA, 0x28, - 0x2B, 0x2B, 0xE3, 0xE4, 0xC9, 0x93, 0x2D, 0x7D, 0xF4, 0x3A, 0xE0, 0x02, 0xD2, 0xCB, 0xE8, 0x09, - 0x10, 0xE4, 0xEF, 0xD3, 0x7A, 0xA3, 0x60, 0x4B, 0x89, 0xE6, 0xCA, 0xFE, 0x84, 0x20, 0xD0, 0xD7, - 0x9B, 0x40, 0x3F, 0x1F, 0xF2, 0x8A, 0xCB, 0xEC, 0xAD, 0x51, 0x97, 0xFF, 0x17, 0xD2, 0x6F, 0xDE, - 0x26, 0xE8, 0x91, 0x36, 0xF9, 0x67, 0x80, 0xE1, 0xC8, 0xCD, 0xA1, 0x0F, 0xCE, 0xC9, 0xC4, 0x3A, - 0xE4, 0xB4, 0xCB, 0x46, 0xCA, 0xC1, 0x6D, 0xC0, 0x79, 0x64, 0x15, 0xB7, 0xAE, 0x00, 0x7E, 0xDE, - 0xED, 0x9A, 0xED, 0xD5, 0x89, 0x10, 0x78, 0x7B, 0x7A, 0x60, 0xF4, 0xF3, 0x71, 0x6C, 0x0C, 0x72, - 0xC5, 0x9D, 0xF4, 0x48, 0xB9, 0xF6, 0x7B, 0x64, 0x40, 0x57, 0x37, 0xE4, 0xBE, 0xA4, 0x2B, 0xD2, - 0x14, 0x1F, 0x8C, 0x9C, 0x86, 0x3A, 0xA4, 0x65, 0xB0, 0x0C, 0x29, 0x0F, 0xCF, 0x03, 0x27, 0x69, - 0x90, 0x87, 0x17, 0x91, 0x6F, 0x48, 0x4F, 0x1C, 0xEA, 0x61, 0x79, 0x7A, 0x18, 0x3A, 0xAF, 0x88, - 0x60, 0x7B, 0x42, 0x80, 0x9B, 0x5E, 0x87, 0xBF, 0x4F, 0x23, 0x43, 0x6B, 0xDB, 0x4C, 0x19, 0x4D, - 0xC0, 0xBE, 0xE2, 0xD6, 0x21, 0x6B, 0x1E, 0xE6, 0x03, 0x76, 0x4F, 0x8C, 0x62, 0x3B, 0xEF, 0xB8, - 0xCD, 0xAE, 0xE3, 0xDA, 0x26, 0x5B, 0x9D, 0xFD, 0xFF, 0x55, 0x45, 0xC1, 0x5D, 0xAF, 0xBB, 0xB1, - 0x9C, 0x52, 0xD7, 0x22, 0x94, 0x5E, 0x87, 0x6F, 0xE3, 0x19, 0xEF, 0x47, 0xC3, 0x8B, 0xDA, 0x7E, - 0xF7, 0xB9, 0xC6, 0x39, 0xC1, 0x2F, 0xB4, 0xD6, 0x60, 0x6B, 0xA0, 0x2A, 0x0A, 0x9E, 0x86, 0x46, - 0xB1, 0x67, 0x9E, 0xB8, 0x80, 0x21, 0xED, 0x9D, 0x63, 0x58, 0x3F, 0x1F, 0x84, 0x10, 0xD2, 0x3B, - 0xF7, 0x4B, 0x10, 0x59, 0x00, 0x8A, 0x82, 0xA1, 0xB1, 0x0A, 0x6F, 0xD7, 0xA4, 0xDA, 0x15, 0xED, - 0xCD, 0x90, 0x1A, 0xA0, 0x16, 0x40, 0x13, 0x82, 0x6A, 0x73, 0xED, 0x2F, 0x46, 0x64, 0x01, 0x97, - 0x07, 0x78, 0xDC, 0x30, 0x0C, 0x31, 0xD9, 0x0F, 0x2A, 0xAA, 0x4C, 0x6D, 0xE8, 0xEA, 0x3A, 0x83, - 0x10, 0xD2, 0x2A, 0xDC, 0x00, 0x0D, 0x17, 0xBC, 0x6E, 0xED, 0xCD, 0x10, 0x13, 0xB2, 0xCE, 0x09, - 0x00, 0x45, 0xA5, 0xE5, 0xAE, 0x8F, 0x32, 0xEC, 0x20, 0x08, 0x21, 0x30, 0x35, 0x36, 0xE7, 0x9B, - 0x70, 0x41, 0x35, 0x39, 0x57, 0x30, 0xA4, 0xBE, 0x70, 0xC0, 0x85, 0xE2, 0x8B, 0x88, 0x1B, 0x21, - 0x30, 0xCE, 0x09, 0x58, 0x35, 0x8D, 0x4B, 0xD5, 0x8D, 0x66, 0xFC, 0x0D, 0xC1, 0x90, 0x1A, 0x1C, - 0x82, 0x88, 0xCF, 0xE6, 0x15, 0x61, 0x32, 0xB7, 0x79, 0xF3, 0xDA, 0xF9, 0x50, 0xA0, 0xA6, 0xB6, - 0x8E, 0x92, 0xF2, 0x4B, 0x8E, 0xAD, 0xC5, 0xDC, 0x00, 0x22, 0x0B, 0xE4, 0x66, 0x11, 0x80, 0x9C, - 0xFC, 0x62, 0xF9, 0x10, 0x6D, 0x89, 0xA9, 0xBA, 0x2E, 0xA0, 0x70, 0xC9, 0x64, 0x96, 0xAE, 0xDE, - 0x06, 0xB4, 0x7B, 0xF1, 0x32, 0x70, 0x5D, 0x69, 0x8D, 0x5A, 0x80, 0xFC, 0x92, 0x32, 0x4E, 0x9D, - 0xCB, 0x77, 0x2E, 0x28, 0xE1, 0x7A, 0x86, 0xA2, 0x50, 0x50, 0x5A, 0x4E, 0x51, 0x43, 0x34, 0x8C, - 0x40, 0x5A, 0x2B, 0xDA, 0x1D, 0xAE, 0x60, 0xC8, 0x49, 0x64, 0x26, 0x2A, 0x55, 0xA6, 0x2B, 0x03, - 0x0D, 0x6E, 0x48, 0x28, 0x0A, 0xA7, 0xCE, 0xE5, 0x53, 0x7E, 0xA9, 0xDE, 0xBD, 0x5C, 0x89, 0xF4, - 0x69, 0xB4, 0x3B, 0x5C, 0xC1, 0x90, 0x73, 0xC8, 0xCF, 0x4E, 0x00, 0xB0, 0x65, 0xDF, 0x61, 0xAA, - 0xAB, 0xCD, 0x9D, 0xBF, 0x41, 0x54, 0x14, 0x19, 0x92, 0xDA, 0x9A, 0x28, 0x4C, 0x21, 0xD8, 0x77, - 0xE4, 0x14, 0x96, 0xBA, 0xFA, 0x35, 0x3C, 0x1F, 0x69, 0xC3, 0x6B, 0x77, 0xB8, 0x82, 0x21, 0x26, - 0xE4, 0x57, 0x6E, 0x00, 0x48, 0x3F, 0x96, 0xC5, 0xE1, 0x53, 0x39, 0xAD, 0x23, 0x84, 0x1D, 0x8A, - 0xD2, 0x40, 0xD0, 0x96, 0xAE, 0x47, 0x0A, 0xA0, 0xD3, 0x51, 0x71, 0xA9, 0x9A, 0x9D, 0xE9, 0x47, - 0x39, 0x9E, 0xD5, 0xC2, 0x4F, 0x82, 0x28, 0x0A, 0xE5, 0x95, 0x97, 0xD8, 0x91, 0x71, 0xDC, 0xB1, - 0xF5, 0x20, 0x36, 0x29, 0xD0, 0xDE, 0x70, 0xD5, 0x67, 0x18, 0x36, 0xDB, 0x06, 0x1C, 0x52, 0x52, - 0x5E, 0xC9, 0xAA, 0x4D, 0xBB, 0x19, 0xDC, 0xA7, 0xF5, 0x51, 0x90, 0xCB, 0x37, 0xEC, 0x64, 0xF7, - 0xA1, 0x4C, 0x46, 0xDF, 0xD2, 0x87, 0x61, 0x03, 0x7B, 0x39, 0x9F, 0xE8, 0xA9, 0x28, 0x54, 0x9B, - 0x6B, 0xF8, 0xF1, 0xA7, 0x03, 0x2C, 0x59, 0xB3, 0x91, 0xED, 0xFB, 0x8F, 0xD2, 0x3B, 0x36, 0x9A, - 0xB5, 0xF3, 0x9E, 0x27, 0x2A, 0x2C, 0xC8, 0xB9, 0x3D, 0x92, 0xAA, 0xB0, 0xF7, 0xC8, 0x69, 0x0E, - 0x64, 0x66, 0xDB, 0x5B, 0x84, 0xED, 0xF9, 0x5C, 0x62, 0xE7, 0x73, 0x55, 0x8D, 0x8E, 0x12, 0x64, - 0xAC, 0x70, 0x1F, 0x80, 0x0B, 0xC5, 0xA5, 0x8C, 0x1D, 0xD2, 0x8F, 0x90, 0xA0, 0x80, 0x96, 0x6D, - 0x14, 0x6D, 0x8B, 0xE9, 0xF4, 0xD7, 0xDF, 0xE7, 0xDB, 0x94, 0x34, 0xD6, 0x6E, 0xDF, 0xC7, 0xB6, - 0xB4, 0x23, 0x18, 0xFD, 0x7C, 0xE8, 0xD9, 0x35, 0xB2, 0xE9, 0x98, 0x5C, 0xDB, 0xB5, 0x85, 0x17, - 0xCB, 0xF9, 0xDF, 0x7F, 0x7C, 0xC6, 0x6B, 0xEF, 0x7F, 0xC5, 0xB1, 0xEC, 0x5C, 0x2C, 0x75, 0x56, - 0xAA, 0xCC, 0x35, 0xDC, 0x3F, 0x62, 0x30, 0x51, 0xE1, 0xCE, 0x31, 0xA4, 0xCE, 0x6A, 0xE5, 0x8D, - 0x65, 0xFF, 0x62, 0xEF, 0xE1, 0xFA, 0x25, 0xE3, 0x3C, 0x32, 0x13, 0xB9, 0xB8, 0xD9, 0x8B, 0x5B, - 0x01, 0x57, 0xD5, 0xDF, 0xAB, 0x45, 0x3A, 0xAA, 0xAA, 0x01, 0xB2, 0x2F, 0x14, 0xB1, 0x74, 0xED, - 0x16, 0xB4, 0x56, 0x84, 0x61, 0x6A, 0x9A, 0x46, 0x8D, 0x45, 0x7A, 0x40, 0xCD, 0x35, 0xB5, 0xA4, - 0x1E, 0x38, 0xC1, 0xB4, 0x3F, 0x2D, 0xE6, 0x93, 0xEF, 0xB6, 0x35, 0xBD, 0x2E, 0xD9, 0x66, 0xC6, - 0x4B, 0x0B, 0x97, 0xB3, 0x74, 0xED, 0x16, 0xCC, 0x0E, 0xA1, 0xA2, 0x31, 0xE1, 0xC1, 0x44, 0x85, - 0x19, 0x9B, 0x8F, 0xC4, 0x07, 0xD0, 0xA9, 0xEC, 0x3B, 0x72, 0x8A, 0x75, 0x3B, 0xD2, 0x1D, 0x5B, - 0xBF, 0x47, 0xFA, 0xD2, 0x5D, 0x02, 0x57, 0x16, 0x44, 0xDC, 0x82, 0x8C, 0xAA, 0x00, 0xE0, 0xCB, - 0xEF, 0x77, 0xB0, 0xEB, 0xE0, 0x49, 0xB9, 0x0E, 0x38, 0x0B, 0x21, 0x08, 0x33, 0x06, 0x70, 0xD7, - 0x6D, 0xFD, 0xEB, 0x9B, 0xBC, 0x3D, 0x0D, 0x18, 0xDC, 0xDD, 0x78, 0xE5, 0xDD, 0x15, 0xEC, 0xFC, - 0xF9, 0xC4, 0xD5, 0xD7, 0x26, 0x45, 0x61, 0xD5, 0xC6, 0x9F, 0xF8, 0xF4, 0xDF, 0xDB, 0x19, 0x79, - 0x73, 0x62, 0xFD, 0xF5, 0xC1, 0x01, 0xBE, 0x3C, 0x3F, 0xE5, 0x5E, 0x19, 0x6B, 0xEC, 0x44, 0xF4, - 0xA3, 0xD9, 0x5C, 0xC3, 0xA2, 0xAF, 0x7E, 0xA0, 0xE8, 0x62, 0x85, 0xBD, 0xB5, 0x14, 0x17, 0x7F, - 0xD8, 0xC5, 0x95, 0x65, 0x85, 0x2C, 0x48, 0xD1, 0x75, 0x2F, 0xE0, 0x51, 0x65, 0xAA, 0xA1, 0xE8, - 0x62, 0x05, 0xF7, 0x0C, 0x1D, 0x88, 0x87, 0xC1, 0xF9, 0xA2, 0x39, 0x8A, 0xAA, 0x92, 0xD4, 0xB3, - 0x2B, 0x25, 0x65, 0x95, 0x14, 0x94, 0x94, 0x73, 0xEF, 0xF0, 0x9B, 0x99, 0xFD, 0xD8, 0x44, 0xBE, - 0x4D, 0x49, 0x27, 0x33, 0x27, 0x8F, 0x7B, 0x87, 0x0D, 0xC2, 0xE0, 0xD8, 0x9F, 0xA2, 0x90, 0x5B, - 0x58, 0xC2, 0xEF, 0xDF, 0x5A, 0x86, 0x5E, 0xA7, 0x63, 0xD9, 0x1F, 0x9F, 0xE0, 0x81, 0x91, 0xB7, - 0x12, 0xDF, 0x35, 0x82, 0x19, 0x0F, 0x8F, 0x63, 0xDC, 0xED, 0x03, 0x9D, 0xDB, 0x16, 0xE9, 0x54, - 0x56, 0x6F, 0xDA, 0xCD, 0x9C, 0x8F, 0xBF, 0x71, 0xD4, 0xAE, 0xBE, 0x44, 0x7E, 0x15, 0xC1, 0x65, - 0xF6, 0x20, 0x57, 0xD7, 0x79, 0x3A, 0x87, 0x0C, 0x33, 0x1A, 0x0C, 0x70, 0xE6, 0x42, 0x21, 0x46, - 0x3F, 0x6F, 0x7E, 0x95, 0x14, 0xD7, 0x22, 0x2D, 0xD8, 0xD7, 0xDB, 0x8B, 0x3B, 0x6F, 0xEB, 0xCF, - 0x83, 0xA3, 0x87, 0x30, 0x69, 0xF4, 0x10, 0x92, 0xE2, 0x63, 0x11, 0x42, 0xE3, 0x93, 0x75, 0xDB, - 0xE9, 0xD3, 0x3D, 0x9A, 0xC4, 0x9E, 0x31, 0x0D, 0x6F, 0xBC, 0x4E, 0xE5, 0x8B, 0x7F, 0xA7, 0xF0, - 0xD9, 0xFA, 0x14, 0x5E, 0xFD, 0xAF, 0x87, 0xB8, 0x7F, 0xD4, 0xAD, 0x04, 0xFA, 0x7B, 0x73, 0x4B, - 0xDF, 0x38, 0x62, 0x22, 0x42, 0x9C, 0x13, 0x09, 0xAA, 0xCA, 0x89, 0xEC, 0x5C, 0x9E, 0x7A, 0x6B, - 0x19, 0xB9, 0x85, 0xF5, 0xB1, 0xB7, 0x39, 0xC0, 0xB3, 0x34, 0x91, 0x5F, 0xDE, 0x5E, 0x70, 0x35, - 0x43, 0x34, 0xE4, 0x46, 0x71, 0x14, 0x10, 0xAA, 0x69, 0x82, 0x03, 0x27, 0xCF, 0xD2, 0x3F, 0x3E, - 0x96, 0xEE, 0x31, 0x11, 0x2D, 0x5A, 0xE0, 0xDD, 0x74, 0x3A, 0x8C, 0x81, 0x7E, 0x78, 0xB8, 0xCB, - 0x0C, 0xE0, 0xB8, 0xAE, 0x91, 0x6C, 0xDE, 0x7B, 0x88, 0xFC, 0x92, 0x8B, 0xDC, 0x3F, 0xE2, 0x96, - 0xFA, 0x05, 0xBE, 0xB6, 0xD6, 0xC2, 0x5F, 0x96, 0x7E, 0x8D, 0x97, 0x87, 0x81, 0x37, 0x9F, 0xFE, - 0x0D, 0x3E, 0x9E, 0x86, 0x86, 0x88, 0x13, 0x67, 0xEE, 0xA7, 0x28, 0x94, 0x55, 0x56, 0xF1, 0xEC, - 0xDF, 0x3F, 0x61, 0x6B, 0x5A, 0x7D, 0x04, 0xA5, 0x15, 0xF9, 0x71, 0x81, 0xD5, 0x2E, 0xA6, 0x57, - 0x87, 0xD4, 0x2E, 0x3F, 0x8D, 0xAC, 0x04, 0x51, 0x09, 0x50, 0x50, 0x2A, 0x35, 0x9F, 0xA3, 0xA7, - 0x72, 0x5A, 0xB6, 0x9E, 0x40, 0x43, 0x05, 0x07, 0x21, 0x08, 0x31, 0xFA, 0xF3, 0xDB, 0x09, 0x23, - 0x38, 0x73, 0xA1, 0x88, 0xCA, 0x2A, 0x53, 0xFD, 0x5E, 0xA5, 0xFC, 0x52, 0x35, 0x39, 0xF9, 0xC5, - 0xFC, 0xE7, 0xD8, 0xDB, 0x08, 0x0B, 0x0E, 0x68, 0xB1, 0x56, 0x67, 0xAE, 0xAD, 0xE5, 0xAF, 0x4B, - 0x57, 0xB3, 0x7A, 0xF3, 0x1E, 0xC7, 0x33, 0xDF, 0x21, 0x4B, 0x2E, 0xB9, 0x1C, 0x1D, 0x55, 0xE5, - 0x78, 0x35, 0xF0, 0x1E, 0x36, 0xEB, 0xE8, 0xCF, 0x27, 0xB2, 0x99, 0x31, 0xF7, 0x23, 0x72, 0x72, - 0x0B, 0x5B, 0xBF, 0x61, 0x14, 0x82, 0x31, 0x43, 0xFA, 0xD1, 0x2D, 0x2A, 0x94, 0x3A, 0x87, 0x7C, - 0x91, 0x3A, 0xAB, 0x95, 0x40, 0x3F, 0x1F, 0xC6, 0xDE, 0x9A, 0xD4, 0x32, 0x5B, 0xAC, 0xA2, 0x60, - 0xAE, 0xB5, 0x30, 0xE7, 0xA3, 0xB5, 0x2C, 0xFC, 0x6A, 0x83, 0x74, 0x3F, 0x4B, 0x1C, 0x01, 0x5E, - 0xC1, 0x21, 0xDC, 0xD3, 0x95, 0xE8, 0xA8, 0x5A, 0x81, 0x1A, 0x90, 0x81, 0x0C, 0x13, 0xEA, 0x05, - 0x90, 0x95, 0x5B, 0xC8, 0xC9, 0xB3, 0x17, 0xB8, 0xBD, 0x7F, 0x82, 0x73, 0xE5, 0x36, 0x2E, 0x87, - 0x00, 0x7F, 0x1F, 0x4F, 0x06, 0x27, 0xF6, 0x20, 0xD4, 0xE8, 0x57, 0x2F, 0xB2, 0xF4, 0x3A, 0x1D, - 0x91, 0x21, 0x46, 0x6E, 0xE9, 0xDD, 0x1D, 0x37, 0x9D, 0x93, 0x8F, 0xA7, 0xAA, 0x54, 0x56, 0x9B, - 0xF9, 0xDB, 0xD2, 0xD5, 0xCC, 0xFD, 0xFC, 0xBB, 0xFA, 0xC0, 0x6C, 0x64, 0xE0, 0xDF, 0x13, 0xC8, - 0x60, 0xC2, 0x0E, 0x41, 0x47, 0x16, 0x6F, 0xAC, 0x46, 0x7E, 0x65, 0x73, 0x10, 0x32, 0x16, 0x96, - 0xCC, 0x73, 0xF9, 0x1C, 0x3A, 0x95, 0xC3, 0xA0, 0x84, 0x6E, 0x84, 0xB6, 0x54, 0xBC, 0x20, 0x23, - 0x41, 0x02, 0xFC, 0x7D, 0x1A, 0x6D, 0x10, 0xDD, 0xF4, 0x3A, 0xE2, 0x6E, 0x8A, 0x72, 0x9E, 0x19, - 0x3A, 0x95, 0xF3, 0xF9, 0xC5, 0xBC, 0xF0, 0xCF, 0xCF, 0x79, 0x77, 0xF5, 0x8F, 0xD4, 0x5A, 0xEA, - 0xA3, 0x3E, 0x8B, 0x90, 0x45, 0x62, 0xBE, 0xE9, 0x40, 0x1A, 0x75, 0x78, 0x35, 0xCD, 0x8B, 0x48, - 0xA6, 0x0C, 0xC4, 0x96, 0x42, 0x77, 0x26, 0xB7, 0x90, 0x9D, 0x3F, 0x1F, 0x27, 0x36, 0x3C, 0x84, - 0xD8, 0xE8, 0xF0, 0x6B, 0xEF, 0xBE, 0xAF, 0x86, 0xAB, 0xF1, 0xD0, 0x49, 0x93, 0x88, 0x26, 0x20, - 0x25, 0xED, 0x08, 0x4F, 0xCE, 0x59, 0xCA, 0xB7, 0xDB, 0xD3, 0xB0, 0x36, 0x6C, 0x16, 0x0B, 0x90, - 0xCC, 0x58, 0xD1, 0xC1, 0xF4, 0xE9, 0x94, 0xF2, 0xA6, 0x85, 0xC8, 0x4F, 0x6B, 0xF7, 0xC5, 0x16, - 0x72, 0x5A, 0x50, 0x5A, 0xCE, 0x86, 0x9F, 0x7E, 0xA6, 0xA6, 0xA6, 0x96, 0x5E, 0x37, 0x45, 0xC9, - 0x04, 0x1A, 0x57, 0xC1, 0x66, 0xA4, 0xCC, 0x2D, 0x28, 0xE1, 0xEF, 0x9F, 0x7F, 0xC7, 0xEC, 0x05, - 0x5F, 0x34, 0xCA, 0xD2, 0x45, 0x2A, 0x21, 0x4F, 0x22, 0xF3, 0x35, 0x3A, 0x3C, 0x20, 0xA0, 0xB3, - 0xEA, 0xCD, 0x16, 0x21, 0x2D, 0xC2, 0x5D, 0x90, 0x5F, 0x8D, 0x56, 0x4D, 0xE6, 0x5A, 0x76, 0x64, - 0x1C, 0x27, 0xF5, 0xE7, 0xE3, 0xF8, 0x79, 0x79, 0x10, 0x13, 0x1E, 0x8C, 0xA1, 0xB9, 0x64, 0xD1, - 0x96, 0x40, 0x95, 0x96, 0xE2, 0xC2, 0xD2, 0x32, 0xBE, 0xF8, 0xF7, 0x0E, 0x9E, 0x7D, 0xE7, 0x13, - 0x56, 0x6D, 0xFC, 0xC9, 0x1E, 0xCD, 0x0E, 0x92, 0xF8, 0xDB, 0x91, 0xC5, 0x13, 0x5A, 0x57, 0xFE, - 0xA7, 0x1D, 0xD0, 0xD9, 0x5E, 0x8A, 0x40, 0xA4, 0x68, 0xF8, 0x3D, 0x0E, 0xDF, 0x3E, 0xF7, 0x34, - 0xB8, 0x33, 0x6C, 0x40, 0x2F, 0xA6, 0x8C, 0x1B, 0xCE, 0xE8, 0xC1, 0x7D, 0x09, 0x0F, 0x09, 0x40, - 0x51, 0x75, 0x36, 0x95, 0xD7, 0xC9, 0x1C, 0x11, 0x45, 0xB1, 0x79, 0x2A, 0x15, 0x6A, 0x6B, 0x6A, - 0x38, 0x95, 0x93, 0xCF, 0xBA, 0x9D, 0xE9, 0x7C, 0xB5, 0xF1, 0x27, 0x0E, 0x9C, 0x3C, 0x7B, 0x79, - 0x48, 0x4F, 0x39, 0xF0, 0x21, 0xF2, 0x23, 0x98, 0x2E, 0x71, 0xCD, 0x3A, 0x8B, 0xCE, 0x66, 0x08, - 0x48, 0x17, 0xC0, 0x9D, 0xC0, 0x8B, 0xC8, 0x62, 0xC4, 0xF5, 0xB3, 0xD6, 0x4D, 0xAF, 0x23, 0xBE, - 0x6B, 0x24, 0x23, 0x6F, 0xEE, 0xC3, 0xA8, 0x5B, 0x12, 0xE9, 0xD3, 0x3D, 0x86, 0x88, 0xE0, 0x40, - 0xBC, 0x3C, 0xDC, 0x1B, 0xAA, 0xCB, 0x35, 0x82, 0x00, 0x4D, 0x50, 0x6B, 0xB1, 0x50, 0x56, 0x51, - 0xC5, 0x99, 0x0B, 0x85, 0xEC, 0x3B, 0x7A, 0x9A, 0x2D, 0xFB, 0x0E, 0xB3, 0xFB, 0x50, 0x26, 0xF9, - 0x25, 0x65, 0x97, 0xE7, 0xB3, 0xD4, 0x21, 0x3F, 0xA5, 0x3A, 0x17, 0xF9, 0x01, 0xCC, 0x4E, 0x0F, - 0x9D, 0xBD, 0x1E, 0x18, 0x62, 0x47, 0x28, 0xB2, 0xB4, 0xC7, 0x34, 0xA4, 0x7A, 0xDC, 0x68, 0x6C, - 0xEE, 0x6E, 0x7A, 0x42, 0x8D, 0xFE, 0x74, 0x8B, 0x0C, 0x25, 0x36, 0x2A, 0x8C, 0x2E, 0xA1, 0x46, - 0x82, 0xFC, 0x7D, 0xF0, 0xF2, 0x34, 0xA0, 0x2A, 0x2A, 0xE6, 0x5A, 0x0B, 0x15, 0x97, 0xAA, 0xB9, - 0x50, 0x7C, 0x91, 0x9C, 0xFC, 0x62, 0xCE, 0xE4, 0x16, 0x72, 0xBE, 0xB0, 0x84, 0x8A, 0xAA, 0xAB, - 0x26, 0x15, 0xD5, 0x21, 0x93, 0x2C, 0x97, 0x02, 0x5F, 0x21, 0x8D, 0x86, 0xFF, 0x8F, 0xAB, 0x40, - 0x41, 0xA6, 0x44, 0xBC, 0x88, 0xDC, 0xB7, 0xD4, 0xD0, 0x82, 0xEF, 0xA2, 0x3B, 0xF1, 0x2B, 0x03, - 0x7E, 0x40, 0x32, 0x3D, 0xB4, 0xB3, 0x1F, 0xB6, 0x29, 0x02, 0x5C, 0xAF, 0x08, 0x45, 0xD6, 0x06, - 0xBE, 0x0B, 0xF8, 0x15, 0x72, 0xEF, 0xE2, 0x6C, 0x32, 0x91, 0x1D, 0x16, 0xA4, 0x23, 0xE9, 0x38, - 0x32, 0xA1, 0x68, 0x13, 0x72, 0x66, 0x54, 0x75, 0xF6, 0xC3, 0x35, 0x85, 0xEB, 0x99, 0x21, 0x76, - 0xE8, 0x90, 0x16, 0xE3, 0x3E, 0x48, 0xAB, 0x71, 0x5F, 0xA0, 0x07, 0x92, 0x61, 0x01, 0x34, 0xE4, - 0xF5, 0xD5, 0x22, 0x09, 0x5D, 0x8C, 0xF4, 0xEA, 0x1D, 0x45, 0xA6, 0x1C, 0x67, 0x20, 0x23, 0x44, - 0x2A, 0x5B, 0x76, 0xDB, 0xCE, 0xC1, 0xFF, 0x01, 0xCE, 0x34, 0xF5, 0xEC, 0x2D, 0xA9, 0x9C, 0xA8, - 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3A, 0x63, 0x72, 0x65, - 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x32, 0x2D, 0x30, 0x31, 0x2D, 0x33, 0x31, 0x54, 0x31, - 0x33, 0x3A, 0x34, 0x31, 0x3A, 0x31, 0x38, 0x2D, 0x30, 0x38, 0x3A, 0x30, 0x30, 0xED, 0x4F, 0xCC, - 0x0D, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3A, 0x6D, 0x6F, - 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x32, 0x2D, 0x30, 0x31, 0x2D, 0x33, 0x31, 0x54, - 0x31, 0x33, 0x3A, 0x34, 0x31, 0x3A, 0x31, 0x38, 0x2D, 0x30, 0x38, 0x3A, 0x30, 0x30, 0x9C, 0x12, - 0x74, 0xB1, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, - 0x72, 0x65, 0x00, 0x77, 0x77, 0x77, 0x2E, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2E, - 0x6F, 0x72, 0x67, 0x9B, 0xEE, 0x3C, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, +#include + +static const uint8_t mu_law_wave[] PROGMEM = { +0x52, 0x49, 0x46, 0x46, 0x84, 0x5D, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, 0x20, +0x12, 0x00, 0x00, 0x00, 0x07, 0x00, 0x01, 0x00, 0x40, 0x1F, 0x00, 0x00, 0x40, 0x1F, 0x00, 0x00, +0x01, 0x00, 0x08, 0x00, 0x00, 0x00, 0x66, 0x61, 0x63, 0x74, 0x04, 0x00, 0x00, 0x00, 0x00, 0x5D, +0x00, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x5D, 0x00, 0x00, 0xFB, 0xFD, 0xFF, 0xFE, 0xFF, 0x7F, +0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7C, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7C, 0x7D, +0x7C, 0x7C, 0x7D, 0x7F, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0x7E, 0xFF, 0x7F, +0x7D, 0x7C, 0x7B, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7C, 0x7C, 0x7B, +0x7B, 0x7B, 0x7A, 0x7A, 0x7B, 0x7A, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x7C, 0x7E, +0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x79, 0x79, 0x7B, 0x7B, 0x7B, 0x7C, 0x7C, 0x7E, 0xFF, 0xFE, 0xFE, +0xFF, 0x7E, 0x7C, 0x7D, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x79, 0x78, 0x79, +0x7A, 0x79, 0x78, 0x78, 0x78, 0x77, 0x78, 0x78, 0x79, 0x79, 0x78, 0x77, 0x77, 0x78, 0x78, 0x79, +0x7A, 0x79, 0x79, 0x78, 0x78, 0x7A, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, +0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFC, 0xF9, 0xF9, 0xF9, 0xF9, 0xF9, 0xF8, 0xF8, +0xF7, 0xF7, 0xF8, 0xF9, 0xF9, 0xFB, 0xFC, 0xFC, 0xFD, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFE, +0xFF, 0xFF, 0xFE, 0x7E, 0x7D, 0x7D, 0x7C, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x7C, +0x7B, 0x7A, 0x79, 0x79, 0x79, 0x77, 0x77, 0x78, 0x79, 0x7B, 0x7C, 0x7B, 0x7B, 0x7C, 0x7B, 0x7B, +0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x79, 0x79, +0x78, 0x77, 0x77, 0x79, 0x79, 0x79, 0x7B, 0x7B, 0x7A, 0x7C, 0x7E, 0x7D, 0x7E, 0x7E, 0x7C, 0x7C, +0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x79, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x78, 0x78, 0x7A, 0x7A, 0x79, +0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFC, 0xFB, 0xFB, 0xFC, +0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFE, 0xFF, 0x7E, 0x7E, 0xFF, 0xFF, 0x7E, 0x7E, 0x7D, 0x7B, +0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, +0x7C, 0x7B, 0x79, 0x7A, 0x7A, 0x7A, 0x7A, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7C, 0x79, 0x79, 0x7A, +0x7A, 0x7A, 0x7A, 0x7A, 0x7A, 0x7C, 0x7C, 0x7C, 0x7E, 0x7D, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0xFE, +0xFD, 0xFD, 0xFB, 0xFB, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, +0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7D, 0x7E, 0x7D, 0x7B, 0x7B, 0x7B, 0x79, 0x78, 0x77, +0x78, 0x78, 0x77, 0x77, 0x77, 0x78, 0x78, 0x76, 0x76, 0x75, 0x73, 0x73, 0x73, 0x72, 0x73, 0x73, +0x74, 0x74, 0x74, 0x75, 0x77, 0x78, 0x78, 0x77, 0x76, 0x77, 0x76, 0x76, 0x78, 0x79, 0x79, 0x79, +0x78, 0x79, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7E, +0x7E, 0x7F, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFD, 0xFE, 0xFF, 0xFD, 0xFE, 0x7F, 0xFF, +0x7F, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7E, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7D, 0x7F, +0xFF, 0xFF, 0xFE, 0xFE, 0x7F, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7C, 0x7D, +0x7D, 0x7D, 0x7D, 0x7E, 0x7F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFF, 0xFE, 0xFC, 0xFD, 0xFC, 0xFC, 0xFD, +0xFC, 0xFB, 0xFB, 0xFC, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFC, 0xFD, 0xFE, +0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7D, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7D, 0x7B, 0x7B, 0x79, +0x78, 0x78, 0x78, 0x76, 0x74, 0x74, 0x73, 0x72, 0x75, 0x77, 0x77, 0x76, 0x75, 0x75, 0x76, 0x77, +0x77, 0x76, 0x74, 0x74, 0x74, 0x74, 0x76, 0x76, 0x76, 0x77, 0x75, 0x76, 0x78, 0x79, 0x77, 0x77, +0x79, 0x7B, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7D, 0x7F, 0x7E, 0xFF, 0xFF, 0x7F, 0xFE, 0xFC, 0xFE, +0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFD, 0xFC, 0xFE, 0xFF, 0x7E, 0x7F, 0x7F, 0x7D, 0x7E, 0xFF, 0x7F, +0x7F, 0xFF, 0x7F, 0x7E, 0x7D, 0x7E, 0xFF, 0x7E, 0x7F, 0x7F, 0x7C, 0x7D, 0x7F, 0x7D, 0x7E, 0x7E, +0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7B, 0x7D, 0x7B, 0x7A, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7C, +0x7D, 0x7E, 0x7F, 0xFF, 0x7F, 0x7F, 0x7F, 0xFF, 0xFD, 0xFD, 0xFD, 0xFC, 0xFB, 0xFB, 0xFB, 0xFB, +0xFA, 0xFB, 0xFB, 0xFB, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFF, 0x7E, 0x7E, 0x7D, 0x7B, 0x7B, 0x7B, +0x78, 0x79, 0x78, 0x75, 0x76, 0x76, 0x76, 0x76, 0x74, 0x74, 0x73, 0x73, 0x74, 0x73, 0x72, 0x73, +0x75, 0x75, 0x74, 0x76, 0x74, 0x72, 0x73, 0x74, 0x75, 0x75, 0x76, 0x77, 0x77, 0x78, 0x77, 0x77, +0x77, 0x78, 0x78, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x79, 0x79, 0x7A, 0x79, 0x7B, 0x7C, 0x7B, 0x7B, +0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7C, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, +0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, +0xFE, 0x7E, 0x7E, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7E, 0xFF, 0x7E, 0x7E, 0x7E, 0x7D, +0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFD, 0xFC, 0xFE, 0x7F, 0x7E, 0x7E, 0x7F, 0xFF, 0xFF, +0x7F, 0x7E, 0x7D, 0x7D, 0x7D, 0x7B, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, 0x7D, 0x7C, 0x7C, +0x7D, 0x7C, 0x7C, 0x7E, 0x7E, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7F, 0x7F, 0xFF, 0xFF, +0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFB, +0xFB, 0xFB, 0xFA, 0xFB, 0xFC, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, +0x7E, 0x7E, 0x7E, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7E, 0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7F, +0x7D, 0x7B, 0x7C, 0x7C, 0x7D, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7E, +0x7F, 0x7E, 0x7D, 0x7C, 0x7B, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x78, 0x77, 0x77, 0x76, 0x74, 0x73, +0x72, 0x73, 0x74, 0x75, 0x77, 0x78, 0x78, 0x79, 0x79, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, +0x7C, 0x7D, 0x7E, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, 0x7D, 0x7C, 0x7B, +0x7A, 0x7B, 0x7B, 0x7A, 0x7A, 0x79, 0x79, 0x7A, 0x79, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x79, 0x79, +0x79, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7A, 0x7B, 0x7C, 0x7B, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7F, +0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7D, 0x7D, +0x7D, 0x7D, 0x7E, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7F, 0x7F, 0x7E, 0x7F, 0x7E, 0x7E, 0x7F, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7F, 0x7F, 0x7E, +0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, +0x7A, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, +0x7D, 0x7E, 0xFF, 0x7E, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7A, 0x7A, +0x7A, 0x79, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, 0x7D, 0x7C, 0x7C, 0x7A, 0x79, 0x79, 0x78, 0x78, +0x78, 0x77, 0x77, 0x76, 0x75, 0x74, 0x74, 0x74, 0x73, 0x73, 0x73, 0x73, 0x74, 0x74, 0x76, 0x75, +0x74, 0x75, 0x77, 0x78, 0x78, 0x7A, 0x7B, 0x7D, 0xFF, 0xFE, 0xFE, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, +0xFC, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, 0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, +0xF8, 0xFA, 0xF8, 0xF6, 0xF7, 0xF7, 0xF8, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFB, +0xFB, 0xFB, 0xFD, 0xFE, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, 0xFE, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, +0x7F, 0x7E, 0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0xFD, 0xFE, 0xFF, +0xFE, 0xFE, 0xFD, 0xFE, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7E, 0x7F, +0x7D, 0x7D, 0x7E, 0x7E, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x79, 0x77, 0x78, 0x79, 0x78, 0x77, 0x76, +0x76, 0x75, 0x73, 0x74, 0x73, 0x71, 0x70, 0x70, 0x71, 0x72, 0x71, 0x71, 0x70, 0x6F, 0x6F, 0x6F, +0x70, 0x71, 0x71, 0x72, 0x73, 0x74, 0x74, 0x74, 0x76, 0x77, 0x76, 0x78, 0x79, 0x79, 0x79, 0x78, +0x7A, 0x7B, 0x7B, 0x7D, 0x7E, 0x7E, 0x7E, 0x7E, 0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, +0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7D, +0x7D, 0x7D, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7C, 0x7A, 0x78, 0x79, 0x78, 0x77, +0x76, 0x78, 0x79, 0x78, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7A, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, +0x7E, 0xFF, 0xFD, 0xFC, 0xFC, 0xFA, 0xF9, 0xFA, 0xFB, 0xFA, 0xF9, 0xF8, 0xF8, 0xF9, 0xFA, 0xF9, +0xF9, 0xF9, 0xF9, 0xF9, 0xF8, 0xF7, 0xF9, 0xF9, 0xF8, 0xF8, 0xFA, 0xFB, 0xFA, 0xFB, 0xFD, 0xFD, +0xFC, 0xFD, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFF, 0x7F, 0x7F, 0x7E, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, +0x7A, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x75, 0x76, 0x77, 0x76, 0x75, 0x76, 0x76, 0x75, 0x76, 0x77, +0x78, 0x79, 0x7B, 0x7B, 0x7B, 0x7A, 0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7A, 0x7B, 0x7B, 0x7A, +0x7B, 0x7D, 0x7E, 0x7B, 0x7C, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFF, 0xFE, 0xFC, 0xFD, 0xFE, 0xFF, +0xFE, 0xFF, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7B, 0x7D, 0x7F, 0x7F, 0x7C, 0x7B, +0x7A, 0x78, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7C, 0x7C, 0x7A, 0x7B, 0x7C, 0x7C, 0x7B, 0x7C, 0x7C, +0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x79, 0x7A, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, +0x7D, 0xFE, 0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFA, 0xF8, 0xF8, 0xF9, 0xF8, 0xF5, 0xF4, 0xF7, 0xF8, +0xF8, 0xF8, 0xF9, 0xFB, 0xFC, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7B, +0x7A, 0x7B, 0x7B, 0x7A, 0x78, 0x78, 0x77, 0x76, 0x76, 0x75, 0x76, 0x76, 0x76, 0x77, 0x75, 0x75, +0x76, 0x75, 0x76, 0x76, 0x78, 0x78, 0x77, 0x78, 0x76, 0x74, 0x75, 0x77, 0x79, 0x7A, 0x7A, 0x7B, +0x7C, 0x7D, 0x7D, 0x7D, 0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0x7F, 0xFF, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, +0xFE, 0x7F, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7E, 0xFF, 0xFD, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, +0xFC, 0xFD, 0xFE, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0x7E, 0x7D, 0x7C, +0x7B, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7A, 0x7A, 0x7C, 0x7A, 0x7B, 0x7C, 0x7C, 0x7E, 0x7E, 0xFF, +0xFF, 0x7F, 0x7F, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, +0x7C, 0x7D, 0xFF, 0x7E, 0x7C, 0x7D, 0xFF, 0xFF, 0xFF, 0xFD, 0xFD, 0xFF, 0x7E, 0x7F, 0x7E, 0x7E, +0x7F, 0x7E, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x79, +0x77, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7C, 0x7D, 0x7D, 0x7E, 0xFD, 0xFD, 0xFE, 0xFC, 0xFC, 0xFB, +0xFB, 0xFC, 0xFB, 0xFB, 0xFA, 0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, 0xFD, +0xFF, 0xFF, 0xFD, 0xFC, 0xFD, 0xFD, 0xFC, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0x7E, 0x7D, 0x7D, 0x7C, 0x7D, 0x7E, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, +0x7B, 0x7C, 0x7D, 0x7B, 0x7B, 0x7C, 0x7A, 0x78, 0x78, 0x78, 0x77, 0x75, 0x75, 0x75, 0x73, 0x72, +0x72, 0x72, 0x71, 0x71, 0x72, 0x72, 0x72, 0x72, 0x73, 0x73, 0x73, 0x74, 0x75, 0x75, 0x74, 0x74, +0x75, 0x76, 0x76, 0x76, 0x77, 0x78, 0x77, 0x78, 0x79, 0x77, 0x78, 0x78, 0x79, 0x7A, 0x7A, 0x7A, +0x7A, 0x79, 0x77, 0x76, 0x76, 0x78, 0x78, 0x77, 0x77, 0x77, 0x75, 0x74, 0x74, 0x75, 0x75, 0x76, +0x79, 0x79, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7D, 0xFF, 0xFD, 0xFD, 0xFE, 0xFF, 0xFE, 0xFC, +0xF9, 0xF9, 0xFB, 0xFA, 0xF9, 0xF8, 0xF8, 0xF8, 0xF6, 0xF4, 0xF6, 0xF8, 0xF7, 0xF7, 0xF9, 0xF9, +0xF9, 0xF8, 0xF8, 0xFB, 0xFA, 0xF9, 0xFA, 0xFB, 0xFC, 0xFE, 0xFC, 0xFD, 0xFF, 0x7E, 0x7F, 0x7E, +0x7C, 0x7C, 0x7C, 0x7D, 0x7D, 0x7B, 0x7B, 0x7A, 0x79, 0x7A, 0x7A, 0x79, 0x79, 0x78, 0x77, 0x78, +0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7D, 0x7E, 0x7D, 0x7D, 0x7F, 0xFE, 0xFE, 0xFD, 0xFD, +0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFE, 0xFC, 0xFB, 0xFC, +0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, +0x7C, 0x7B, 0x7B, 0x7C, 0x79, 0x79, 0x79, 0x78, 0x76, 0x75, 0x76, 0x78, 0x77, 0x76, 0x76, 0x77, +0x76, 0x74, 0x74, 0x75, 0x75, 0x75, 0x74, 0x74, 0x76, 0x77, 0x78, 0x7A, 0x7C, 0x7B, 0x7A, 0x7D, +0x7E, 0x7E, 0x7C, 0x7D, 0x7F, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFE, 0xFF, +0xFF, 0x7F, 0x7E, 0x7F, 0xFF, 0xFE, 0xFD, 0xFF, 0xFE, 0xFC, 0xFB, 0xFC, 0xFE, 0xFD, 0xFC, 0xFE, +0xFF, 0xFE, 0xFD, 0xFF, 0x7E, 0x7F, 0xFE, 0xFC, 0xFD, 0xFE, 0xFD, 0xFD, 0xFE, 0x7F, 0x7E, 0xFF, +0xFF, 0x7F, 0xFF, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, 0x7E, 0x7E, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, +0x7E, 0x7D, 0x7E, 0xFF, 0xFF, 0xFE, 0xFD, 0xFF, 0x7D, 0x7A, 0x79, 0x79, 0x7A, 0x7C, 0x7B, 0x7B, +0x7D, 0x7E, 0x7E, 0x7D, 0xFF, 0xFF, 0x7F, 0x7F, 0x7E, 0x7B, 0x7A, 0x7A, 0x7A, 0x78, 0x77, 0x77, +0x77, 0x78, 0x78, 0x76, 0x76, 0x76, 0x76, 0x74, 0x74, 0x73, 0x74, 0x74, 0x75, 0x74, 0x72, 0x74, +0x76, 0x74, 0x74, 0x76, 0x76, 0x74, 0x73, 0x73, 0x72, 0x73, 0x74, 0x76, 0x77, 0x75, 0x73, 0x75, +0x77, 0x78, 0x75, 0x75, 0x78, 0x78, 0x78, 0x78, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7B, +0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7F, 0x7F, 0x7D, 0x7C, 0x7D, 0x7B, 0x7C, 0x7F, +0xFF, 0xFF, 0x7E, 0x7D, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, 0x7A, 0x7A, 0x7B, 0x7B, 0x79, 0x77, 0x77, +0x78, 0x76, 0x76, 0x78, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x7B, 0x7C, 0x7B, 0x7C, 0x7D, 0xFF, +0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFB, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, +0xFA, 0xF9, 0xF9, 0xF7, 0xF7, 0xF7, 0xF4, 0xF4, 0xF4, 0xF2, 0xEF, 0xEE, 0xEF, 0xF2, 0xF2, 0xF1, +0xF2, 0xF5, 0xF5, 0xF3, 0xF1, 0xF2, 0xF5, 0xF7, 0xF8, 0xFA, 0xFB, 0xFC, 0xFC, 0xFB, 0xFC, 0xFC, +0xFD, 0xFF, 0x7F, 0x7E, 0x7C, 0x7A, 0x7A, 0x78, 0x77, 0x76, 0x75, 0x75, 0x74, 0x71, 0x70, 0x71, +0x71, 0x71, 0x70, 0x6F, 0x71, 0x71, 0x71, 0x73, 0x75, 0x77, 0x77, 0x76, 0x79, 0x7A, 0x79, 0x79, +0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7F, 0xFF, 0xFE, 0xFF, 0x7E, 0x7D, 0x7E, 0x7E, 0x7D, 0x7D, +0x7E, 0x7C, 0x7C, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x77, 0x75, 0x75, 0x76, 0x78, 0x79, 0x78, +0x7A, 0x7C, 0x7C, 0x7A, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7A, 0x79, 0x7A, 0x7B, 0x7D, 0x7D, 0x7C, +0x7C, 0x7E, 0xFF, 0x7F, 0x7D, 0x7E, 0x7F, 0x7D, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0xFF, 0x7F, 0x7E, +0x7D, 0x7D, 0xFF, 0xFF, 0x7F, 0xFF, 0xFC, 0xFC, 0xFD, 0xFD, 0xFC, 0xFB, 0xFA, 0xFA, 0xFB, 0xFB, +0xF9, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0x7F, 0x7F, 0x7E, 0x7D, 0x7E, 0x7D, 0x7B, 0x7C, 0x7B, +0x7B, 0x7C, 0x7C, 0x7A, 0x78, 0x78, 0x7B, 0x7A, 0x77, 0x75, 0x76, 0x75, 0x76, 0x76, 0x76, 0x76, +0x78, 0x79, 0x78, 0x75, 0x75, 0x76, 0x77, 0x7A, 0x7D, 0xFF, 0xFC, 0xFB, 0xFA, 0xFA, 0xFB, 0xFA, +0xFB, 0xFB, 0xFC, 0xFD, 0xFD, 0x7E, 0x78, 0x76, 0x72, 0x70, 0x71, 0x75, 0x77, 0x77, 0x79, 0x7A, +0x7A, 0x7A, 0x7B, 0xFF, 0xFB, 0xFA, 0xF9, 0xFB, 0xFD, 0xFE, 0x7E, 0x7F, 0xFF, 0xFC, 0xF6, 0xF3, +0xF7, 0xFC, 0xFF, 0x7A, 0x73, 0x6E, 0x6C, 0x6D, 0x6E, 0x6E, 0x6E, 0x6E, 0x6F, 0x74, 0x73, 0x72, +0x75, 0x7A, 0x7D, 0x7D, 0xFF, 0xFF, 0x7C, 0x7C, 0x7D, 0x7B, 0x7A, 0x79, 0x7B, 0xFF, 0xFF, 0x7D, +0x7C, 0xFF, 0xFE, 0x7D, 0xFC, 0xF3, 0xF6, 0xFC, 0xFE, 0xFE, 0xFF, 0x78, 0x75, 0x79, 0x7A, 0x7E, +0xF8, 0xF6, 0xF6, 0xF2, 0xEF, 0xEE, 0xF0, 0xF7, 0xFD, 0xFE, 0xFD, 0x7B, 0x77, 0x7C, 0xFF, 0xFB, +0xFD, 0x7D, 0xFF, 0x7C, 0x78, 0x7A, 0x7A, 0xFF, 0xF9, 0xF5, 0xF1, 0xF4, 0xFA, 0xFC, 0xFC, 0xFA, +0xF8, 0xFA, 0xFB, 0xFA, 0xFB, 0xFC, 0xFD, 0xFF, 0x7D, 0x7B, 0x7D, 0x7E, 0x7A, 0x76, 0x76, 0x75, +0x72, 0x75, 0x7B, 0x7D, 0x7A, 0x7A, 0x7D, 0xFF, 0x7C, 0x7C, 0xFF, 0x7D, 0x7A, 0x7B, 0x7C, 0x7E, +0xFC, 0xFC, 0x7F, 0xFE, 0xFD, 0xFE, 0xFC, 0xF8, 0xF9, 0xFA, 0xFB, 0xFE, 0x7E, 0x79, 0x72, 0x72, +0x74, 0x76, 0x78, 0x76, 0x78, 0x7A, 0x75, 0x76, 0x77, 0x75, 0x73, 0x73, 0x73, 0x73, 0x74, 0x73, +0x73, 0x77, 0x78, 0x79, 0x79, 0x7A, 0x79, 0x73, 0x73, 0x7B, 0x7C, 0x7C, 0xFC, 0xFC, 0xFE, 0x7F, +0x76, 0x73, 0x76, 0x73, 0x73, 0x78, 0x7C, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0x7D, 0x7B, 0x7B, +0x7C, 0x7A, 0x78, 0x7B, 0x7B, 0x7D, 0x7F, 0x7A, 0x77, 0x73, 0x6F, 0x70, 0x72, 0x73, 0x72, 0x72, +0x73, 0x74, 0x74, 0x76, 0x7D, 0xFE, 0x7D, 0x7C, 0x7C, 0x78, 0x76, 0x77, 0x79, 0x7B, 0xFF, 0xFD, +0xFE, 0x7E, 0x7B, 0x7A, 0x78, 0x78, 0x7B, 0x7C, 0x7C, 0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x79, 0x7B, +0xFF, 0xFA, 0xF9, 0xFD, 0x7E, 0x7D, 0x7C, 0x7B, 0x7E, 0xFE, 0xFC, 0xFF, 0x7E, 0xFE, 0xFD, 0xFE, +0xFD, 0xFC, 0xFB, 0xFC, 0xFC, 0xFD, 0xF9, 0xF3, 0xF2, 0xF3, 0xF4, 0xF6, 0xF6, 0xF8, 0xFA, 0xFC, +0xFB, 0xF7, 0xF9, 0xFC, 0xFC, 0xFD, 0xFD, 0x7E, 0x7C, 0x7F, 0xFF, 0x7D, 0x7A, 0x7A, 0x7B, 0x78, +0x78, 0x78, 0x75, 0x75, 0x76, 0x79, 0x7A, 0x79, 0x7C, 0x7F, 0xFD, 0xFF, 0x7E, 0xFF, 0x7D, 0x79, +0x77, 0x78, 0x79, 0x78, 0x79, 0x7C, 0x7D, 0x7F, 0x7E, 0x7E, 0xFE, 0xFC, 0xF8, 0xF7, 0xFA, 0xFB, +0xFC, 0xFD, 0xFF, 0x7D, 0x7E, 0x7F, 0xFF, 0x7D, 0x7B, 0x7D, 0xFE, 0xF9, 0xF5, 0xF6, 0xF6, 0xF4, +0xF6, 0xFA, 0xFE, 0x7D, 0x79, 0x78, 0x77, 0x77, 0x7A, 0x7E, 0xFE, 0xFF, 0xFF, 0xFA, 0xFA, 0xFE, +0x7C, 0x75, 0x71, 0x72, 0x74, 0x75, 0x74, 0x75, 0x75, 0x77, 0x79, 0x79, 0x77, 0x74, 0x74, 0x74, +0x72, 0x71, 0x70, 0x71, 0x70, 0x6F, 0x72, 0x73, 0x72, 0x73, 0x71, 0x70, 0x73, 0x78, 0x7A, 0x78, +0x77, 0x77, 0x76, 0x74, 0x73, 0x72, 0x70, 0x71, 0x75, 0x78, 0x7B, 0x7F, 0xFF, 0xFE, 0xFB, 0xFD, +0x7E, 0xFF, 0xFD, 0x7F, 0x7C, 0x7B, 0x7F, 0xFD, 0xFF, 0xFE, 0xFC, 0xFE, 0xFD, 0xFC, 0xFA, 0xF7, +0xF7, 0xFB, 0xFD, 0xFE, 0x7E, 0x7C, 0x7B, 0x7A, 0x7B, 0x79, 0x75, 0x75, 0x76, 0x78, 0x7D, 0xFF, +0x7E, 0x7D, 0x7E, 0x7C, 0x77, 0x75, 0x76, 0x76, 0x78, 0x7E, 0xFD, 0xFB, 0xFC, 0xFD, 0xFE, 0x7C, +0x78, 0x78, 0x7A, 0x7B, 0x7E, 0x7E, 0x7D, 0x7D, 0x7C, 0x7A, 0x78, 0x79, 0x7B, 0x7A, 0x7D, 0xFC, +0xFD, 0x7E, 0xFF, 0xFB, 0xF7, 0xF6, 0xF7, 0xF7, 0xF6, 0xFA, 0xFF, 0xFE, 0xFD, 0xFF, 0x7D, 0xFF, +0xFC, 0xFB, 0xF9, 0xFD, 0xFE, 0xFD, 0x7E, 0x79, 0x76, 0x71, 0x6F, 0x6E, 0x6E, 0x6F, 0x72, 0x76, +0x7A, 0x7E, 0xFF, 0xFF, 0x7C, 0x7B, 0x7C, 0x7B, 0x7A, 0x79, 0x7A, 0x7E, 0xFF, 0xFF, 0x7E, 0x7D, +0x7D, 0x7E, 0x7C, 0x78, 0x79, 0x7A, 0x7B, 0xFF, 0xFF, 0x7F, 0x7E, 0x7B, 0x79, 0x79, 0x76, 0x72, +0x73, 0x7B, 0xFF, 0xFE, 0xFB, 0xFA, 0xFA, 0xFC, 0x7D, 0x78, 0x77, 0x78, 0x79, 0x79, 0x78, 0x79, +0x77, 0x73, 0x74, 0x76, 0x77, 0x79, 0x7A, 0x7B, 0x7F, 0xFD, 0xFE, 0xFF, 0x7F, 0x7E, 0x7E, 0x7C, +0x78, 0x78, 0x7B, 0x7B, 0x7A, 0x7C, 0x7F, 0xFE, 0xFD, 0xFE, 0x7E, 0xFF, 0xFD, 0xFC, 0xF9, 0xF5, +0xF2, 0xF0, 0xF2, 0xF3, 0xF0, 0xF1, 0xF2, 0xF1, 0xF4, 0xF7, 0xF8, 0xFC, 0xFC, 0xF6, 0xF3, 0xF4, +0xF5, 0xF5, 0xF6, 0xFB, 0xFF, 0xFF, 0xFF, 0x7D, 0x7D, 0x7E, 0x7D, 0x79, 0x75, 0x74, 0x75, 0x72, +0x72, 0x75, 0x75, 0x74, 0x77, 0x7A, 0x7A, 0x7A, 0x7A, 0x77, 0x74, 0x73, 0x72, 0x74, 0x75, 0x76, +0x77, 0x74, 0x74, 0x77, 0x79, 0x79, 0x79, 0x78, 0x77, 0x74, 0x70, 0x6F, 0x70, 0x6F, 0x6E, 0x6E, +0x6E, 0x6F, 0x6F, 0x72, 0x75, 0x72, 0x74, 0x79, 0x7B, 0x7B, 0x7B, 0x7D, 0xFF, 0x7E, 0x7F, 0xFE, +0xFE, 0x7F, 0x7D, 0x7D, 0xFF, 0xFD, 0xFE, 0x7E, 0x7D, 0x7D, 0x7E, 0x7C, 0x79, 0x77, 0x75, 0x76, +0x77, 0x78, 0x78, 0x74, 0x75, 0x7A, 0x7F, 0xFB, 0xF9, 0xF9, 0xF8, 0xFD, 0x7E, 0x7B, 0x76, 0x78, +0x7B, 0x7C, 0x7E, 0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x7C, 0xFF, 0xFF, 0xFF, 0xFE, 0xFE, 0x7D, 0x7B, +0x7B, 0x79, 0x79, 0x7A, 0x7D, 0xFF, 0x7F, 0x7F, 0xFF, 0xFD, 0xFB, 0xFD, 0xFE, 0xFE, 0xFF, 0x7D, +0x7C, 0x7F, 0xFB, 0xF7, 0xF6, 0xFC, 0x7F, 0xFF, 0xFE, 0xFB, 0xFD, 0xFE, 0xFC, 0xFD, 0xFE, 0x7C, +0x76, 0x74, 0x74, 0x79, 0x79, 0x76, 0x77, 0x79, 0x7C, 0x7D, 0x7B, 0x7B, 0x7B, 0x7E, 0xFD, 0xFB, +0xF9, 0xF9, 0xFE, 0x7C, 0x79, 0x79, 0x77, 0x76, 0x79, 0x7B, 0x7D, 0x7C, 0x7C, 0x7D, 0x7C, 0x78, +0x75, 0x74, 0x72, 0x72, 0x73, 0x71, 0x70, 0x73, 0x78, 0x7C, 0x7D, 0x7E, 0xFF, 0x7F, 0x7F, 0x7D, +0x7A, 0x78, 0x76, 0x76, 0x76, 0x76, 0x77, 0x77, 0x7B, 0xFF, 0xFF, 0xFD, 0xFC, 0xFC, 0xFA, 0xF9, +0xF8, 0xF9, 0xFE, 0x7E, 0xFF, 0xFE, 0xFE, 0x7D, 0x7A, 0x78, 0x75, 0x75, 0x77, 0x7A, 0x7A, 0x79, +0x7B, 0x7D, 0xFF, 0xFD, 0xFC, 0xFC, 0xFB, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xFB, 0xFA, 0xF9, 0xF7, +0xF8, 0xFA, 0xF8, 0xF9, 0xFC, 0xFD, 0xFD, 0xFC, 0xF9, 0xF7, 0xF8, 0xFC, 0x7E, 0x7B, 0x7A, 0x7A, +0x79, 0x79, 0x7A, 0x7A, 0x7A, 0x77, 0x72, 0x72, 0x74, 0x76, 0x7B, 0x7C, 0x7B, 0x7D, 0x7E, 0x7D, +0x7D, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x78, 0x78, 0x79, 0x79, 0x79, 0x78, 0x79, 0x7B, 0x7C, 0x7C, +0x7A, 0x7A, 0x77, 0x75, 0x75, 0x74, 0x73, 0x70, 0x6E, 0x6E, 0x6E, 0x6F, 0x72, 0x75, 0x77, 0x7A, +0x7D, 0x7D, 0x7D, 0x7E, 0xFF, 0x7D, 0x7A, 0x7A, 0x7A, 0x7B, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7F, +0x7D, 0x7B, 0x78, 0x75, 0x73, 0x74, 0x75, 0x75, 0x78, 0x79, 0x7A, 0x79, 0x79, 0x7D, 0xFE, 0xFC, +0xF9, 0xF8, 0xF8, 0xF8, 0xF6, 0xF5, 0xF6, 0xF8, 0xFB, 0xFC, 0xFB, 0xFD, 0xFF, 0x7E, 0x7D, 0x7C, +0x7C, 0x7B, 0x7C, 0x7B, 0x79, 0x79, 0x7A, 0x79, 0x76, 0x74, 0x72, 0x72, 0x73, 0x74, 0x75, 0x77, +0x78, 0x78, 0x78, 0x77, 0x76, 0x75, 0x75, 0x78, 0x7A, 0x79, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0x7F, +0xFE, 0xFC, 0xFC, 0xFC, 0xFA, 0xF8, 0xF7, 0xF7, 0xF8, 0xF7, 0xF5, 0xF5, 0xF5, 0xF4, 0xF5, 0xF6, +0xF7, 0xF8, 0xF9, 0xFB, 0xFE, 0x7F, 0x7D, 0x7C, 0x7D, 0x7E, 0x7E, 0x7E, 0x7D, 0x7A, 0x7A, 0x7A, +0x7A, 0x79, 0x79, 0x79, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x7B, 0x7A, 0x7A, 0x7A, 0x79, 0x77, 0x76, +0x77, 0x77, 0x77, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0x7E, 0x7B, +0x78, 0x78, 0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7E, 0x7E, 0x7E, 0x7E, 0x7F, 0xFF, 0x7F, 0x7F, 0xFE, +0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFD, 0xFD, 0xFC, 0xFE, 0x7F, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, +0x7B, 0x7A, 0x7B, 0x7B, 0x7B, 0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x76, 0x77, 0x78, 0x77, 0x79, +0x7A, 0x7A, 0x7B, 0x7C, 0x7C, 0x7B, 0x7A, 0x7B, 0x7D, 0x7B, 0x7B, 0x7D, 0x7C, 0x7D, 0xFF, 0x7E, +0xFF, 0xFD, 0xFB, 0xF9, 0xF8, 0xF9, 0xF9, 0xF7, 0xF6, 0xF5, 0xF4, 0xF3, 0xF3, 0xF5, 0xF6, 0xF6, +0xF7, 0xF9, 0xFB, 0xFB, 0xFA, 0xFA, 0xFB, 0xFC, 0xFB, 0xFD, 0xFD, 0xFB, 0xFB, 0xFB, 0xFA, 0xF8, +0xF8, 0xF9, 0xFB, 0xFD, 0x7E, 0x7B, 0x78, 0x78, 0x77, 0x77, 0x77, 0x76, 0x76, 0x76, 0x75, 0x75, +0x73, 0x71, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x6E, 0x6E, 0x6F, 0x6F, 0x6E, 0x6E, 0x6E, 0x6D, +0x6D, 0x6E, 0x6D, 0x6D, 0x6E, 0x6F, 0x70, 0x72, 0x73, 0x74, 0x75, 0x79, 0x7C, 0x7D, 0x7E, 0xFF, +0xFF, 0xFF, 0xFD, 0xFC, 0xFA, 0xF9, 0xFB, 0xFD, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, 0x7E, 0x7B, 0x7A, +0x79, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7C, 0x7C, 0x7B, 0x79, 0x79, 0x78, 0x78, 0x79, 0x7A, 0x7C, +0x7E, 0x7E, 0x7E, 0x7C, 0x7B, 0x7A, 0x7A, 0x7A, 0x78, 0x78, 0x79, 0x79, 0x7A, 0x7D, 0xFF, 0xFD, +0xFC, 0xFB, 0xFA, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFE, 0xFE, 0xFC, 0xFB, 0xFB, 0xFB, +0xFB, 0xFC, 0xFD, 0xFD, 0xFD, 0xFE, 0xFD, 0xFC, 0xFC, 0xFB, 0xFA, 0xFA, 0xF9, 0xF9, 0xF8, 0xF7, +0xF6, 0xF7, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0x7E, 0x7D, 0x7C, 0x7C, +0x7C, 0x7A, 0x7A, 0x79, 0x79, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, 0x7C, +0x7C, 0x7C, 0x7D, 0x7D, 0x7C, 0x7B, 0x78, 0x77, 0x76, 0x75, 0x75, 0x75, 0x76, 0x76, 0x75, 0x76, +0x77, 0x78, 0x78, 0x78, 0x79, 0x79, 0x7B, 0x7D, 0x7D, 0x7E, 0x7F, 0x7F, 0xFF, 0xFE, 0xFE, 0xFE, +0xFD, 0xFB, 0xFB, 0xFB, 0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFF, 0x7F, 0x7E, 0x7C, 0x7C, 0x7B, +0x7A, 0x7A, 0x7A, 0x78, 0x78, 0x77, 0x77, 0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7B, 0x7C, 0x7D, 0x7B, +0x7A, 0x7B, 0x7C, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7B, 0x7A, 0x7B, 0x7F, 0xFD, 0x7D, 0x79, 0xFE, +0xFA, 0xFE, 0xFC, 0xF8, 0xFC, 0xFF, 0xFF, 0xFE, 0xFB, 0xFC, 0x7F, 0xFF, 0x7F, 0x7C, 0x7D, 0x7D, +0x7E, 0x7E, 0x7B, 0x7A, 0x7A, 0x7B, 0x7C, 0x7E, 0x7E, 0x7C, 0x7B, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, +0x7D, 0x7E, 0x7F, 0x7E, 0x7F, 0xFF, 0xFE, 0xFD, 0xFE, 0xFF, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7E, +0x7D, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x7A, 0x7A, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x75, 0x74, 0x73, +0x74, 0x75, 0x74, 0x74, 0x75, 0x75, 0x75, 0x76, 0x77, 0x76, 0x77, 0x77, 0x79, 0x7B, 0x7C, 0x7D, +0x7D, 0x7D, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFE, 0xFD, 0xFE, 0xFF, 0xFE, 0xFD, 0xFB, 0xFC, 0xFD, +0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0x7F, 0x7D, 0x7E, +0x7F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFD, 0xFE, 0xFE, 0xFE, 0xFE, +0xFF, 0xFF, 0xFF, 0xFF, 0x7F, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, +0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7C, 0x7D, 0x7D, 0x7D, 0x7D, 0x7D, 0x7E, 0x7E, 0x7F, 0x7F, 0x7E, +0x7D, 0x7C, 0x7B, 0x7B, 0x79, 0x77, 0x77, 0x78, 0x76, 0x76, 0x78, 0x7A, 0x78, 0x78, 0x78, 0x77, +0x77, 0x76, 0x75, 0x76, 0x75, 0x75, 0x77, 0x77, 0x76, 0x74, 0x74, 0x75, 0x76, 0x75, 0x76, 0x76, +0x75, 0x76, 0x76, 0x75, 0x74, 0x73, 0x74, 0x74, 0x75, 0x76, 0x76, 0x77, 0x78, 0x7A, 0x7A, 0x7B, +0x7C, 0x7B, 0x7D, 0x7E, 0x7D, 0x7D, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFE, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFE, 0xFD, 0xFD, 0xFD, 0xFF, 0x7F, 0xFE, 0xFF, 0xFF, 0xFE, +0xFE, 0xFE, 0x7F, 0x7E, 0xFF, 0xFE, 0xFE, 0xFE, 0xFF, 0xFF, 0xFE, 0xFF, 0xFF, 0xFD, 0xFD, 0xFD, +0xFE, 0xFF, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0xFE, 0xFC, 0xFA, 0xF9, 0xF8, 0xF8, 0xF8, 0xF9, 0xFA, +0xFD, 0xFE, 0xFC, 0xFD, 0xFE, 0xFE, 0xFF, 0x7F, 0xFF, 0x7E, 0x7D, 0x7B, 0x79, 0x79, 0x7B, 0x7C, +0x7C, 0x7D, 0x7E, 0x7F, 0x7E, 0x7D, 0x7D, 0x7B, 0x7B, 0x7A, 0x77, 0x78, 0x75, 0x75, 0x76, 0x76, +0x78, 0x75, 0x76, 0x77, 0x73, 0x75, 0x73, 0x77, 0x76, 0x73, 0x78, 0x73, 0x78, 0x77, 0x75, 0x7B, +0x70, 0x7E, 0x68, 0x5B, 0xE4, 0xD9, 0x77, 0x66, 0x5F, 0x6B, 0xEB, 0x78, 0x6B, 0xEC, 0xE9, 0x67, +0x5A, 0x62, 0xF8, 0xE2, 0xF1, 0x6B, 0x6F, 0x72, 0x6E, 0x6D, 0x72, 0xEF, 0xE7, 0xF7, 0x6D, 0x6A, +0x70, 0x7B, 0xFC, 0xF5, 0xED, 0xEF, 0x7D, 0x71, 0x70, 0xFF, 0xEE, 0xEF, 0xF8, 0xFC, 0x7B, 0x73, +0x6F, 0x71, 0x7E, 0xF2, 0xF2, 0x76, 0x67, 0x68, 0x78, 0xF7, 0xF5, 0xFC, 0x7E, 0x7B, 0x73, 0x70, +0x79, 0xF4, 0xEB, 0xEC, 0xF8, 0x7C, 0x7B, 0xFF, 0xF6, 0xEF, 0xEF, 0xF4, 0xF8, 0xFE, 0x7D, 0xFE, +0xF8, 0xF4, 0xF4, 0xF9, 0xFE, 0x7E, 0x7C, 0x7C, 0xFD, 0xF8, 0xF8, 0xFD, 0x7D, 0x7A, 0x79, 0x7C, +0xFF, 0xFD, 0xFB, 0xFC, 0x7D, 0x7B, 0x7D, 0x7F, 0xFD, 0xFD, 0xFF, 0x7E, 0x7C, 0x7A, 0x79, 0x7C, +0x7E, 0x7D, 0x7D, 0x7B, 0x78, 0x79, 0x7B, 0x7A, 0x78, 0x79, 0x77, 0x76, 0x78, 0x71, 0x70, 0x78, +0x7E, 0xF6, 0xFE, 0x67, 0x68, 0xF4, 0xEF, 0x74, 0x69, 0x6A, 0xFF, 0x7E, 0x6E, 0xF2, 0xFB, 0x69, +0x66, 0x69, 0xDD, 0xD9, 0x71, 0x7B, 0x74, 0x5F, 0x69, 0x61, 0x6A, 0xE6, 0xEC, 0x66, 0x55, 0x50, +0x5C, 0xFB, 0xED, 0xF5, 0xFA, 0x6F, 0x6E, 0x7B, 0xE8, 0xCF, 0xC7, 0xC6, 0xCA, 0xCB, 0xDB, 0x3A, +0x2E, 0x49, 0xBD, 0xB7, 0xC6, 0x4D, 0x41, 0x4B, 0x49, 0x4D, 0xD9, 0xBF, 0xC2, 0xFD, 0x3F, 0x3D, +0x51, 0xDF, 0xCD, 0xCC, 0xD5, 0xF4, 0x50, 0x46, 0x4D, 0xF0, 0xCB, 0xCA, 0xDA, 0x61, 0x51, 0x52, +0x5B, 0xE6, 0xD0, 0xCE, 0xDC, 0x5D, 0x53, 0x51, 0x6A, 0xF9, 0x48, 0x67, 0xC2, 0xE0, 0x5F, 0x5B, +0x4C, 0x71, 0xFA, 0x6E, 0xCE, 0xCF, 0x7A, 0x64, 0x79, 0xD8, 0xCE, 0xD1, 0xCD, 0xC3, 0xC5, 0xCD, +0xC7, 0xDC, 0x42, 0x3E, 0x53, 0xD2, 0xC0, 0xDE, 0x44, 0x48, 0x58, 0x53, 0x59, 0xFA, 0xD9, 0xD6, +0x5E, 0x43, 0x47, 0x61, 0xE1, 0xD8, 0xEA, 0x64, 0x46, 0x3C, 0x51, 0x7F, 0x77, 0xD0, 0xF6, 0x4B, +0x4B, 0x4A, 0x6F, 0xCA, 0xC6, 0xC9, 0xC7, 0xC2, 0xC8, 0xBD, 0xB0, 0xAB, 0xBB, 0x1F, 0x19, 0x5F, +0xA3, 0xA5, 0xBA, 0x30, 0x30, 0x47, 0x31, 0x37, 0xBC, 0xAB, 0xB8, 0x3D, 0x2B, 0x30, 0x4E, 0xBD, +0xB4, 0xC4, 0x5D, 0x3F, 0x38, 0x41, 0x6E, 0xC8, 0xC1, 0xDC, 0x4B, 0x3B, 0x3F, 0xE5, 0xBF, 0xBC, +0xC8, 0xE5, 0xDE, 0xC0, 0xAE, 0xAD, 0xAF, 0xC1, 0x20, 0x1A, 0x63, 0xA8, 0xA7, 0xB5, 0x36, 0x2E, +0x3D, 0x32, 0x3F, 0xBD, 0xB1, 0xC1, 0x39, 0x2E, 0x42, 0xE8, 0xCA, 0xC3, 0xDB, 0x5F, 0x47, 0x39, +0x47, 0xD5, 0xCB, 0xD1, 0x70, 0x4B, 0x4D, 0xF0, 0xC1, 0xB3, 0xAE, 0xB4, 0xBE, 0xB8, 0xB8, 0x34, +0x1C, 0x27, 0xB6, 0xA3, 0xAC, 0x4F, 0x2C, 0x32, 0x3B, 0x3E, 0xEB, 0xB9, 0xBB, 0x45, 0x2E, 0x39, +0x60, 0xC3, 0xBB, 0xD8, 0x4D, 0x45, 0x41, 0x57, 0xD6, 0xDE, 0x79, 0x5D, 0x50, 0x5B, 0xDB, 0xBE, +0xB4, 0xB3, 0xBC, 0xC4, 0xB6, 0xAC, 0xC2, 0x26, 0x1A, 0x30, 0xAB, 0xA9, 0xBB, 0x61, 0x33, 0x30, +0x36, 0x39, 0xCF, 0xB9, 0x64, 0x41, 0x42, 0x3E, 0x5E, 0xD3, 0xCF, 0xC4, 0xEC, 0x47, 0x56, 0x5C, +0x50, 0x57, 0x62, 0xDF, 0xD2, 0xD3, 0xC4, 0xB6, 0xB3, 0xBA, 0xB8, 0xAD, 0xAF, 0x3C, 0x1C, 0x1E, +0xCB, 0xA1, 0xA9, 0xFE, 0x2D, 0x2C, 0x39, 0x3D, 0x64, 0xBE, 0xD5, 0x4B, 0x42, 0x3A, 0x40, 0xEC, +0xC4, 0xBE, 0xD1, 0x4A, 0x3E, 0x47, 0x62, 0xE4, 0xD7, 0xD6, 0xDC, 0xDE, 0xCD, 0xB6, 0xAD, 0xAE, +0xAC, 0xAD, 0xE6, 0x22, 0x19, 0x2E, 0xA6, 0x9E, 0xB2, 0x39, 0x28, 0x2D, 0x39, 0x4E, 0xC2, 0xBE, +0x5B, 0x3E, 0x3B, 0x3C, 0x58, 0xC6, 0xBD, 0xC7, 0x60, 0x3F, 0x3F, 0x51, 0xED, 0xCF, 0xC8, 0xD1, +0xE0, 0xD9, 0xBC, 0xAC, 0xAB, 0xAB, 0xA9, 0xC2, 0x25, 0x17, 0x22, 0xAE, 0x9D, 0xA9, 0x47, 0x26, +0x29, 0x34, 0x47, 0xC5, 0xBB, 0x77, 0x3F, 0x3A, 0x38, 0x4E, 0xC6, 0xBC, 0xBE, 0xE6, 0x3D, 0x39, +0x43, 0x67, 0xCE, 0xC7, 0xD6, 0xED, 0xD9, 0xBD, 0xAB, 0xAB, 0xAE, 0xA9, 0xB4, 0x30, 0x1A, 0x1B, +0xD5, 0x9D, 0xA3, 0xDA, 0x2A, 0x26, 0x31, 0x3C, 0x6C, 0xBF, 0xCE, 0x5E, 0x42, 0x32, 0x3C, 0xD6, +0xBC, 0xB8, 0xCC, 0x3F, 0x37, 0x3B, 0x51, 0xCC, 0xC1, 0xCC, 0xE2, 0xDE, 0xBD, 0xAC, 0xAA, 0xA9, +0xA7, 0xC5, 0x26, 0x18, 0x1F, 0xB7, 0x9D, 0xA6, 0xDF, 0x2B, 0x26, 0x2D, 0x37, 0xEB, 0xBA, 0xCB, +0x5E, 0x3C, 0x30, 0x44, 0xC9, 0xBB, 0xB8, 0xCF, 0x3D, 0x34, 0x3B, 0x5F, 0xC1, 0xBE, 0xCE, 0xD6, +0xCE, 0xB8, 0xAB, 0xAA, 0xA4, 0xA8, 0x42, 0x1C, 0x18, 0x31, 0xA4, 0x9F, 0xAF, 0x48, 0x29, 0x28, +0x2C, 0x37, 0xCC, 0xBA, 0xC7, 0x57, 0x30, 0x31, 0x5A, 0xC6, 0xB6, 0xB7, 0x5F, 0x38, 0x34, 0x3D, +0xE2, 0xBD, 0xBD, 0xC7, 0xD2, 0xCA, 0xB2, 0xAB, 0xA7, 0xA2, 0xB3, 0x29, 0x18, 0x1C, 0xD2, 0x9F, +0xA5, 0xBC, 0x3A, 0x2A, 0x29, 0x2A, 0x3E, 0xC3, 0xBB, 0xC1, 0x43, 0x2D, 0x3A, 0xF5, 0xC1, 0xB5, +0xBE, 0x4F, 0x36, 0x32, 0x3F, 0xD2, 0xBB, 0xBA, 0xBE, 0xC5, 0xBF, 0xB1, 0xAB, 0xA4, 0xA7, 0x75, +0x1F, 0x18, 0x27, 0xAE, 0xA2, 0xAD, 0xD6, 0x36, 0x2B, 0x28, 0x2C, 0x4E, 0xC2, 0xB8, 0xC9, 0x35, +0x2F, 0x42, 0x71, 0xBA, 0xB4, 0xD2, 0x44, 0x34, 0x34, 0x4C, 0xCD, 0xBE, 0xBB, 0xB9, 0xBC, 0xB3, +0xAE, 0xAB, 0xA3, 0xB0, 0x2C, 0x1A, 0x1C, 0x5F, 0xA4, 0xA9, 0xBA, 0x6F, 0x34, 0x28, 0x26, 0x32, +0x77, 0xB9, 0xB3, 0x5E, 0x32, 0x38, 0x40, 0xD8, 0xB6, 0xBE, 0xF4, 0x40, 0x34, 0x3A, 0x5B, 0xC7, +0xB7, 0xB4, 0xB7, 0xB4, 0xB2, 0xAE, 0xA5, 0xAB, 0x3B, 0x1D, 0x1B, 0x34, 0xAE, 0xAA, 0xB4, 0xC7, +0x42, 0x2C, 0x25, 0x2B, 0x43, 0xCF, 0xB5, 0xBE, 0x3F, 0x38, 0x3D, 0x4D, 0xC4, 0xBD, 0xCF, 0x5D, +0x3E, 0x38, 0x43, 0xE4, 0xBF, 0xB4, 0xAF, 0xB0, 0xAF, 0xAE, 0xA8, 0xA7, 0xF6, 0x21, 0x1A, 0x27, +0xBA, 0xAC, 0xB5, 0xB9, 0xE2, 0x36, 0x26, 0x25, 0x33, 0x4E, 0xBA, 0xB2, 0x64, 0x41, 0x3F, 0x3D, +0xE6, 0xC6, 0xCD, 0xD4, 0x50, 0x3D, 0x3C, 0x48, 0xD4, 0xB9, 0xAF, 0xAD, 0xAE, 0xAE, 0xAA, 0xA7, +0xC0, 0x2A, 0x1B, 0x1F, 0x65, 0xAF, 0xB5, 0xB5, 0xBF, 0x4C, 0x2C, 0x23, 0x2A, 0x37, 0xE6, 0xAF, +0xBC, 0x5B, 0x4B, 0x3B, 0x49, 0xCF, 0xCE, 0xD0, 0xDE, 0x4F, 0x40, 0x3F, 0x57, 0xC7, 0xB3, 0xAA, +0xA9, 0xAC, 0xAE, 0xA9, 0xAE, 0x3B, 0x1E, 0x1E, 0x37, 0xBA, 0xB7, 0xB7, 0xB5, 0xC9, 0x3A, 0x26, +0x27, 0x2E, 0x37, 0xC1, 0xB1, 0xCA, 0xE8, 0x49, 0x3E, 0x62, 0x78, 0xEF, 0xD7, 0x69, 0x4F, 0x44, +0x48, 0xFB, 0xC5, 0xAF, 0xA9, 0xA8, 0xAA, 0xAB, 0xAA, 0xCF, 0x26, 0x1C, 0x22, 0x4A, 0xBD, 0xBB, +0xAF, 0xB1, 0xD7, 0x31, 0x25, 0x27, 0x28, 0x38, 0xB9, 0xB6, 0xC3, 0xCB, 0x4B, 0x45, 0x4E, 0x47, +0x62, 0xE0, 0xF9, 0x5C, 0x4C, 0x5C, 0xE4, 0xBF, 0xAD, 0xA8, 0xA5, 0xA7, 0xA9, 0xB2, 0x36, 0x20, +0x1E, 0x29, 0x56, 0xCC, 0xB8, 0xAC, 0xB5, 0xFA, 0x2F, 0x28, 0x25, 0x25, 0x45, 0xBE, 0xBF, 0xB8, +0xC5, 0x5F, 0x54, 0x41, 0x43, 0x4F, 0x56, 0x75, 0x70, 0xFE, 0xE2, 0xD3, 0xB9, 0xAD, 0xA8, 0xA6, +0xA6, 0xA8, 0xCA, 0x2D, 0x22, 0x21, 0x2E, 0x47, 0x77, 0xB4, 0xAD, 0xB7, 0xDC, 0x39, 0x2D, 0x24, +0x28, 0x40, 0x5A, 0xC7, 0xB5, 0xBD, 0xC0, 0xDB, 0x4E, 0x4C, 0x40, 0x44, 0x4E, 0x56, 0xDA, 0xCC, +0xC0, 0xB1, 0xAC, 0xA7, 0xA5, 0xA6, 0xAD, 0x4F, 0x2A, 0x23, 0x25, 0x2F, 0x39, 0x6C, 0xB6, 0xB1, +0xB7, 0xD6, 0x43, 0x2F, 0x26, 0x2C, 0x35, 0x3A, 0xDF, 0xC7, 0xBE, 0xBA, 0xCB, 0xD4, 0x6E, 0x48, +0x44, 0x3E, 0x4A, 0x6C, 0xD6, 0xB9, 0xB0, 0xA8, 0xA4, 0xA5, 0xA4, 0xB5, 0x42, 0x2C, 0x23, 0x27, +0x2B, 0x2E, 0x55, 0xC2, 0xB9, 0xB6, 0xC5, 0xF4, 0x3C, 0x32, 0x34, 0x2F, 0x37, 0x4A, 0x5B, 0xCF, +0xC9, 0xC6, 0xC0, 0xCA, 0xCF, 0xF4, 0x52, 0x51, 0x4E, 0xF8, 0xC4, 0xB7, 0xAD, 0xA9, 0xA6, 0xA7, +0xB8, 0x5D, 0x38, 0x2F, 0x2E, 0x2B, 0x2C, 0x35, 0x42, 0x5D, 0x7D, 0xE3, 0xDF, 0x6F, 0x73, 0x5A, +0x4D, 0x55, 0x4F, 0x4F, 0x58, 0x5C, 0x6E, 0xFA, 0xE2, 0xD4, 0xD4, 0xD6, 0xD9, 0xD6, 0xCC, 0xC6, +0xBF, 0xBB, 0xB8, 0xB6, 0xBC, 0xC9, 0xDC, 0x60, 0x59, 0x53, 0x4A, 0x49, 0x46, 0x45, 0x46, 0x43, +0x45, 0x45, 0x49, 0x56, 0x5A, 0x5D, 0x6E, 0x72, 0x7C, 0x74, 0x6D, 0x7A, 0x7A, 0xFC, 0xED, 0xE8, +0xEB, 0xFF, 0xFD, 0xEC, 0xDE, 0xD2, 0xCC, 0xC7, 0xC5, 0xCA, 0xD2, 0xD9, 0xDB, 0xD4, 0xCF, 0xD1, +0xD9, 0xE7, 0xFC, 0x6E, 0x60, 0x57, 0x50, 0x4C, 0x49, 0x47, 0x46, 0x45, 0x47, 0x4A, 0x4D, 0x4F, +0x4F, 0x53, 0x5A, 0x5F, 0x62, 0x60, 0x62, 0x6B, 0x77, 0xEC, 0xD8, 0xCC, 0xC7, 0xC7, 0xCB, 0xCF, +0xD3, 0xD3, 0xCE, 0xCB, 0xCA, 0xCC, 0xCF, 0xD4, 0xD9, 0xDF, 0xEB, 0xFE, 0x6A, 0x58, 0x4D, 0x46, +0x43, 0x44, 0x46, 0x48, 0x4A, 0x4C, 0x4E, 0x52, 0x54, 0x55, 0x54, 0x57, 0x5C, 0x61, 0x72, 0xE5, +0xD4, 0xCC, 0xCB, 0xCD, 0xD0, 0xD4, 0xD3, 0xD1, 0xD0, 0xCF, 0xD1, 0xD2, 0xD4, 0xD6, 0xD9, 0xDB, +0xDB, 0xDD, 0xEC, 0x6B, 0x59, 0x53, 0x54, 0x57, 0x59, 0x58, 0x57, 0x5A, 0x5C, 0x5A, 0x55, 0x52, +0x52, 0x51, 0x51, 0x57, 0x61, 0xFC, 0xE3, 0xDF, 0xE0, 0xE4, 0xE3, 0xE0, 0xDF, 0xDE, 0xDD, 0xDE, +0xDD, 0xDF, 0xE0, 0xDF, 0xDC, 0xD9, 0xDC, 0xE7, 0x7E, 0x6B, 0x6D, 0x7C, 0xEE, 0xE6, 0xE7, 0xEA, +0xEC, 0xF5, 0x7A, 0x6A, 0x61, 0x5A, 0x51, 0x4F, 0x50, 0x55, 0x5D, 0x62, 0x63, 0x60, 0x5F, 0x61, +0x65, 0x68, 0x6D, 0x75, 0xFA, 0xF1, 0xF1, 0xEE, 0xE6, 0xDD, 0xDB, 0xDE, 0xEB, 0x79, 0x6B, 0x6F, +0xF7, 0xE2, 0xDC, 0xDB, 0xDA, 0xDA, 0xDC, 0xDD, 0xDE, 0xE0, 0xF1, 0x6B, 0x5F, 0x5F, 0x66, 0x6B, +0x6A, 0x65, 0x5E, 0x5B, 0x5A, 0x59, 0x5A, 0x5C, 0x5E, 0x5E, 0x5E, 0x5E, 0x68, 0xFC, 0xE8, 0xE5, +0xEB, 0xFB, 0x71, 0x6D, 0x78, 0xEE, 0xE2, 0xDE, 0xDD, 0xDC, 0xDE, 0xDF, 0xDC, 0xD9, 0xD9, 0xE0, +0xED, 0xF0, 0xEC, 0xE4, 0xE2, 0xE6, 0xEE, 0x7C, 0x6D, 0x65, 0x5E, 0x5E, 0x62, 0x64, 0x61, 0x5C, +0x5B, 0x5F, 0x70, 0xF7, 0xF8, 0x78, 0x6B, 0x65, 0x61, 0x69, 0xFA, 0xE9, 0xE5, 0xE2, 0xE5, 0xEA, +0xED, 0xEB, 0xE5, 0xE5, 0xED, 0xF9, 0xFC, 0xEF, 0xE3, 0xDE, 0xDE, 0xE1, 0xE9, 0xF4, 0x74, 0x6A, +0x6B, 0x6F, 0x6F, 0x67, 0x5E, 0x5C, 0x5F, 0x6A, 0x6F, 0x6C, 0x66, 0x5F, 0x5D, 0x5E, 0x64, 0x6F, +0xFE, 0xEF, 0xEC, 0xF2, 0xFD, 0x7E, 0xFB, 0xF6, 0xFF, 0x6F, 0x6A, 0x6A, 0x74, 0xF4, 0xE9, 0xE4, +0xE7, 0xEE, 0x7D, 0x6A, 0x69, 0x6F, 0xFE, 0xF7, 0x7B, 0x6B, 0x68, 0x6E, 0x79, 0x78, 0x6F, 0x69, +0x62, 0x5F, 0x60, 0x66, 0x72, 0xF6, 0xEB, 0xEC, 0xF3, 0xFC, 0xFA, 0xF2, 0xF2, 0xFE, 0x70, 0x69, +0x69, 0x71, 0xF7, 0xE8, 0xE3, 0xE4, 0xED, 0x76, 0x69, 0x6A, 0x6F, 0x7E, 0xFB, 0x7D, 0x75, 0x73, +0x7C, 0xFB, 0xFC, 0x7D, 0x73, 0x6D, 0x6A, 0x69, 0x6F, 0xFD, 0xEC, 0xE8, 0xED, 0xF6, 0xF7, 0xF1, +0xED, 0xEF, 0xF6, 0x7E, 0x76, 0x78, 0xFB, 0xEC, 0xE2, 0xDE, 0xE0, 0xEB, 0xFE, 0x73, 0x73, 0x7E, +0xFA, 0xFC, 0xFF, 0x7B, 0x7D, 0xFC, 0xFE, 0x7B, 0x74, 0x6F, 0x6D, 0x6C, 0x6E, 0x77, 0xFA, 0xEE, +0xED, 0xF6, 0x7A, 0x73, 0x77, 0x7B, 0x7C, 0x78, 0x6E, 0x6B, 0x6F, 0x7C, 0xEF, 0xE7, 0xE2, 0xE6, +0xF2, 0x7A, 0x71, 0x75, 0x7D, 0xFE, 0xFD, 0xFD, 0xFB, 0xF5, 0xF7, 0xFE, 0x77, 0x6E, 0x6A, 0x67, +0x67, 0x6C, 0x76, 0xF7, 0xEE, 0xEF, 0xFA, 0x7B, 0x78, 0x7B, 0xFF, 0x7F, 0x78, 0x6F, 0x6C, 0x6C, +0x72, 0xFE, 0xEF, 0xEC, 0xEF, 0xFD, 0x76, 0x70, 0x71, 0x75, 0x7A, 0x7E, 0x7E, 0xFF, 0xFC, 0xFD, +0x7C, 0x73, 0x6D, 0x69, 0x65, 0x63, 0x65, 0x6B, 0x79, 0xFB, 0xFD, 0x78, 0x70, 0x70, 0x74, 0x79, +0x7C, 0x7B, 0x79, 0x77, 0x78, 0x7F, 0xF4, 0xED, 0xED, 0xF2, 0xFB, 0x7A, 0x74, 0x74, 0x76, 0x7A, +0x7F, 0xFB, 0xF5, 0xF4, 0xF6, 0xFA, 0x7D, 0x75, 0x6E, 0x6B, 0x6B, 0x6F, 0x7D, 0xF3, 0xEF, 0xF4, +0x7E, 0x78, 0x7A, 0xFF, 0xFA, 0xF7, 0xF5, 0xF4, 0xF4, 0xF1, 0xED, 0xE9, 0xE6, 0xE8, 0xEE, 0xF8, +0x7F, 0x7C, 0x7A, 0x7A, 0x7B, 0x7D, 0xFD, 0xF8, 0xF8, 0xF9, 0xFC, 0x7D, 0x74, 0x6C, 0x69, 0x69, +0x6C, 0x76, 0xFA, 0xF6, 0xFD, 0x78, 0x71, 0x6F, 0x6F, 0x6F, 0x71, 0x74, 0x77, 0x7C, 0xFD, 0xF5, +0xEC, 0xE9, 0xEA, 0xEF, 0xFB, 0x7A, 0x74, 0x73, 0x73, 0x73, 0x73, 0x78, 0x7E, 0xFE, 0xFD, 0xFE, +0x7B, 0x74, 0x6D, 0x68, 0x66, 0x69, 0x6F, 0x7B, 0x7F, 0x7C, 0x77, 0x73, 0x72, 0x6F, 0x6D, 0x6D, +0x6D, 0x6D, 0x6E, 0x72, 0x7A, 0xFA, 0xF1, 0xEE, 0xEF, 0xF6, 0xFD, 0x7D, 0x7B, 0x7A, 0x78, 0x78, +0x79, 0x79, 0x7A, 0x7C, 0x7D, 0x7E, 0x7D, 0x77, 0x70, 0x6E, 0x71, 0x79, 0x7E, 0x7E, 0x7E, 0x7D, +0x7E, 0x7D, 0x7C, 0x7A, 0x78, 0x76, 0x74, 0x73, 0x75, 0x7A, 0xFC, 0xF6, 0xF4, 0xF4, 0xF6, 0xF6, +0xF6, 0xF9, 0xF9, 0xF7, 0xF5, 0xF3, 0xF1, 0xF1, 0xF3, 0xF5, 0xF7, 0xFA, 0x7B, 0x6F, 0x6D, 0x6D, +0x6F, 0x6F, 0x6E, 0x6E, 0x70, 0x70, 0x71, 0x74, 0x78, 0x7C, 0x7D, 0x7E, 0x7D, 0xFF, 0xFB, 0xF7, +0xF4, 0xF4, 0xF6, 0xF8, 0xFB, 0xFD, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFF, 0x7F, 0xFF, 0xFC, 0xF8, +0xF9, 0xFD, 0x7D, 0x7C, 0x7F, 0xFE, 0x7E, 0x7C, 0x7A, 0x79, 0x77, 0x75, 0x75, 0x76, 0x79, 0x76, +0x71, 0x6F, 0x6F, 0x71, 0x76, 0x78, 0x78, 0x78, 0x7B, 0x7D, 0x7A, 0x77, 0x76, 0x76, 0x78, 0x79, +0x78, 0x79, 0x7C, 0xFD, 0xF4, 0xF1, 0xF2, 0xF5, 0xF9, 0xFB, 0x7F, 0x79, 0x76, 0x76, 0x78, 0x77, +0x77, 0x7B, 0xFF, 0xFA, 0xF6, 0xF6, 0xF7, 0xF6, 0xF6, 0xF7, 0xF9, 0xFA, 0xF9, 0xF6, 0xF6, 0xF9, +0xFB, 0xFE, 0x7F, 0x7E, 0x7C, 0x79, 0x7A, 0xFE, 0xF5, 0xEF, 0xEE, 0xEF, 0xF1, 0xF3, 0xF4, 0xFB, +0x79, 0x73, 0x72, 0x6E, 0x6B, 0x68, 0x68, 0x6C, 0x73, 0x7A, 0x7C, 0x7B, 0x7B, 0x7D, 0x7D, 0xFD, +0xF6, 0xF0, 0xEE, 0xEF, 0xF6, 0xFB, 0xFF, 0x7D, 0x7F, 0x7D, 0x7A, 0x7A, 0x7B, 0x7C, 0x7D, 0x7B, +0x7A, 0xFF, 0xFD, 0xFF, 0x7E, 0x7A, 0x75, 0x74, 0x71, 0x6F, 0x6F, 0x70, 0x77, 0x7A, 0x78, 0x75, +0x72, 0x75, 0x73, 0x6F, 0x6F, 0x70, 0x75, 0x77, 0x76, 0x78, 0x75, 0x78, 0x7B, 0x7B, 0x7F, 0x7B, +0x7E, 0x7F, 0x7E, 0x7E, 0x77, 0x79, 0x73, 0x71, 0x71, 0x6B, 0x6F, 0x60, 0x5B, 0x6F, 0x72, 0x69, +0x71, 0x72, 0x7E, 0xFC, 0xF7, 0xEE, 0xF4, 0xFB, 0x7E, 0x7E, 0xFC, 0xF9, 0xFD, 0x7F, 0xFC, 0x72, +0x78, 0x64, 0x53, 0x71, 0xDF, 0xF0, 0xEB, 0xE9, 0xF0, 0x7C, 0x7B, 0xEA, 0xF6, 0x7E, 0x79, 0x6C, +0x79, 0x5F, 0x5B, 0xEC, 0xE2, 0xEF, 0xED, 0xF1, 0xF7, 0xFE, 0x7C, 0xFE, 0x75, 0x6E, 0x75, 0x79, +0x7A, 0x72, 0x6E, 0x75, 0x7A, 0x7B, 0x77, 0x77, 0xFE, 0xF8, 0xF6, 0xF5, 0xEB, 0xE9, 0xEC, 0xE8, +0xEE, 0xEC, 0xED, 0x77, 0xFD, 0x61, 0x51, 0x66, 0xE7, 0xDC, 0xD8, 0xD3, 0xD3, 0x6C, 0x52, 0x63, +0x6F, 0x73, 0x7F, 0xFB, 0xF4, 0x79, 0x7B, 0xF1, 0xED, 0xEC, 0xFA, 0x76, 0x7A, 0x74, 0x6B, 0x6B, +0x75, 0x7C, 0x7C, 0x79, 0xFE, 0xF6, 0xFE, 0x7A, 0x71, 0x75, 0xFF, 0x70, 0x6D, 0x6E, 0x69, 0x66, +0x5E, 0x62, 0xFA, 0xEA, 0xE5, 0xE0, 0xE1, 0xE5, 0xEE, 0xF1, 0xE5, 0xE4, 0xEA, 0xE8, 0xE7, 0xE7, +0xE3, 0xE7, 0xE8, 0xE8, 0xEF, 0xF7, 0x78, 0x6E, 0x6D, 0x60, 0x5A, 0x57, 0x54, 0x53, 0x51, 0x50, +0x52, 0x54, 0x57, 0x59, 0x5D, 0x67, 0x70, 0x7B, 0xF5, 0xE5, 0xDA, 0xD5, 0xD2, 0xCD, 0xC4, 0xBE, +0xBB, 0xB7, 0xB5, 0xBB, 0xCB, 0xDE, 0xE9, 0x56, 0x3F, 0x3A, 0x39, 0x3B, 0x3B, 0x3A, 0x3F, 0x4E, +0x5D, 0x69, 0xF2, 0xDD, 0xD9, 0xE2, 0xF3, 0xF4, 0x72, 0x5C, 0x53, 0x4E, 0x4D, 0x4E, 0x4E, 0x4F, +0x58, 0x7E, 0xDA, 0xCB, 0xBF, 0xBA, 0xB7, 0xB4, 0xB0, 0xAE, 0xB2, 0xBE, 0xD7, 0x70, 0x4E, 0x3B, +0x32, 0x30, 0x33, 0x35, 0x35, 0x3A, 0x49, 0x5F, 0x7E, 0xEF, 0xE1, 0xD2, 0xD1, 0xE6, 0xEF, 0xF7, +0x5F, 0x4F, 0x48, 0x48, 0x4B, 0x48, 0x4B, 0x55, 0x72, 0xE1, 0xD2, 0xC2, 0xBA, 0xB6, 0xB3, 0xB0, +0xAD, 0xAE, 0xBA, 0xD0, 0x64, 0x4C, 0x3C, 0x30, 0x2E, 0x2F, 0x33, 0x35, 0x3A, 0x47, 0x6C, 0xE6, +0xEB, 0xD0, 0xC6, 0xCC, 0xD6, 0xE3, 0xEF, 0x69, 0x4E, 0x4B, 0x4B, 0x47, 0x46, 0x48, 0x4F, 0x61, +0xFE, 0xD1, 0xBE, 0xB8, 0xB5, 0xB2, 0xAF, 0xAD, 0xAE, 0xBA, 0xCD, 0x5F, 0x47, 0x3B, 0x2F, 0x2D, +0x2E, 0x30, 0x35, 0x3B, 0x47, 0x6C, 0xF4, 0xE2, 0xCB, 0xC7, 0xCD, 0xD7, 0xDD, 0xE3, 0x6E, 0x4E, +0x4A, 0x4B, 0x48, 0x47, 0x4A, 0x5B, 0xE4, 0xD3, 0xC0, 0xB7, 0xB3, 0xB0, 0xAF, 0xAC, 0xAC, 0xB3, +0xC4, 0x7D, 0x4C, 0x3E, 0x30, 0x2C, 0x2E, 0x31, 0x35, 0x3A, 0x45, 0x62, 0xFA, 0xEB, 0xCE, 0xCA, +0xD2, 0xDA, 0xE7, 0xE9, 0x6D, 0x4C, 0x49, 0x49, 0x47, 0x48, 0x4C, 0x68, 0xD7, 0xCA, 0xBC, 0xB5, +0xB2, 0xB0, 0xAE, 0xAC, 0xAE, 0xB9, 0xCE, 0x5D, 0x45, 0x39, 0x2F, 0x2D, 0x2E, 0x31, 0x36, 0x3B, +0x47, 0x5C, 0x6E, 0xE4, 0xD3, 0xD3, 0xD4, 0xDA, 0xDE, 0xEB, 0x5B, 0x4D, 0x4A, 0x47, 0x48, 0x49, +0x54, 0xEB, 0xCE, 0xBE, 0xB8, 0xB7, 0xB3, 0xB3, 0xB5, 0xB3, 0xBB, 0xC9, 0xC8, 0xED, 0x47, 0x42, +0x3A, 0x36, 0x37, 0x34, 0x39, 0x3E, 0x3F, 0x47, 0x4E, 0x65, 0xDE, 0xEC, 0xDC, 0xCE, 0xD9, 0xEB, +0x5F, 0x54, 0x51, 0x47, 0x46, 0x4C, 0x58, 0xFC, 0xD8, 0xC4, 0xBB, 0xBA, 0xB8, 0xB5, 0xB2, 0xAF, +0xB0, 0xB6, 0xBD, 0xCC, 0x66, 0x47, 0x3B, 0x34, 0x32, 0x32, 0x34, 0x38, 0x3B, 0x3F, 0x4B, 0x58, +0x69, 0xE9, 0xD9, 0xD4, 0xDB, 0x77, 0x5C, 0x59, 0x4F, 0x4A, 0x4B, 0x51, 0x69, 0xE0, 0xCE, 0xC2, +0xBD, 0xBC, 0xBA, 0xB8, 0xB7, 0xB4, 0xB2, 0xB7, 0xC3, 0xCE, 0xD4, 0x67, 0x44, 0x3D, 0x3C, 0x3B, +0x38, 0x38, 0x3B, 0x3F, 0x42, 0x46, 0x4E, 0x5F, 0x6A, 0x6B, 0xFD, 0xF7, 0x70, 0x5C, 0x54, 0x58, +0x58, 0x53, 0x5B, 0x73, 0xE5, 0xD2, 0xCA, 0xC6, 0xC2, 0xBF, 0xBE, 0xBE, 0xBD, 0xBB, 0xBC, 0xC3, +0xCA, 0xD0, 0xE2, 0x5F, 0x4E, 0x4A, 0x44, 0x3E, 0x3D, 0x3D, 0x3F, 0x42, 0x44, 0x4B, 0x55, 0x57, +0x5F, 0x69, 0x68, 0x63, 0x58, 0x56, 0x5B, 0x56, 0x57, 0x66, 0x79, 0xE8, 0xD9, 0xCF, 0xCB, 0xCB, +0xC8, 0xC4, 0xC5, 0xC6, 0xC9, 0xC9, 0xC6, 0xCD, 0xD4, 0xD8, 0xE2, 0xF1, 0x66, 0x5C, 0x57, 0x4C, +0x49, 0x49, 0x48, 0x49, 0x49, 0x4B, 0x51, 0x51, 0x4F, 0x53, 0x56, 0x58, 0x58, 0x54, 0x58, 0x5F, +0x5E, 0x5B, 0x63, 0xF2, 0xE5, 0xE5, 0xD7, 0xCF, 0xD2, 0xD6, 0xD1, 0xCF, 0xD6, 0xD6, 0xD2, 0xCF, +0xCE, 0xD0, 0xD8, 0xDB, 0xDB, 0xE5, 0x6D, 0x67, 0x65, 0x5C, 0x58, 0x54, 0x59, 0x5D, 0x57, 0x57, +0x5B, 0x5B, 0x59, 0x56, 0x57, 0x5A, 0x56, 0x52, 0x5A, 0x5C, 0x5D, 0x7D, 0xF1, 0xF3, 0xE7, 0xE3, +0xDF, 0xDB, 0xDA, 0xE7, 0xEC, 0xDE, 0xE5, 0xE9, 0xE6, 0xE4, 0xD6, 0xDF, 0xF8, 0xDE, 0xE9, 0x7C, +0xEE, 0xFB, 0x7A, 0x6B, 0x65, 0xFF, 0x79, 0x69, 0x6B, 0x63, 0x65, 0x62, 0x56, 0x5A, 0x60, 0x55, +0x58, 0x62, 0x5E, 0x64, 0x79, 0x7C, 0x78, 0xED, 0xE1, 0xEC, 0xF0, 0xE4, 0xF0, 0x6E, 0x7C, 0xED, +0xDD, 0xDB, 0xFE, 0x73, 0xED, 0xF0, 0xFF, 0xF9, 0xDE, 0xDC, 0x76, 0x6E, 0xFB, 0x7B, 0xFB, 0x6F, +0x6F, 0xEF, 0x7B, 0x6E, 0xF8, 0xE9, 0x7E, 0x5B, 0x5F, 0xF3, 0xFD, 0x67, 0x74, 0xEA, 0xEF, 0x77, +0x6D, 0x7C, 0xE8, 0xE2, 0xEE, 0xFB, 0xE6, 0xED, 0x66, 0x6C, 0x7B, 0x7C, 0xF4, 0xEF, 0xE2, 0xE6, +0x72, 0x70, 0xF0, 0xEE, 0x6E, 0x6B, 0xFB, 0xF5, 0xF6, 0x71, 0x6A, 0x6C, 0x65, 0x67, 0x5F, 0x5D, +0x6B, 0x62, 0x65, 0xFD, 0xED, 0xE9, 0xF2, 0xED, 0xE3, 0xE7, 0xE4, 0xE8, 0xED, 0xEF, 0x66, 0x5E, +0x79, 0x7E, 0x78, 0xF5, 0xFA, 0x79, 0x7A, 0xF5, 0xE7, 0xE2, 0xE4, 0xF2, 0xFF, 0x73, 0x66, 0x6B, +0x70, 0xFD, 0xEF, 0x6F, 0x67, 0x5F, 0x5C, 0x6B, 0x6E, 0x78, 0x77, 0x6D, 0xF1, 0xF4, 0xF8, 0xE5, +0xE9, 0xEB, 0xEC, 0xEF, 0xEF, 0xF0, 0xE7, 0xED, 0x6B, 0x6F, 0xF0, 0xFF, 0x6A, 0x6F, 0x7E, 0x6F, +0x69, 0xED, 0xDF, 0xFF, 0x7C, 0xEB, 0xF3, 0xF8, 0x7E, 0x7A, 0xFB, 0x6E, 0x5E, 0x60, 0x70, 0x7A, +0xFC, 0xF4, 0xFF, 0xEF, 0xF5, 0x72, 0xF1, 0xEC, 0xEA, 0xE1, 0xE9, 0xED, 0xF2, 0xFC, 0xE7, 0xF0, +0x68, 0x76, 0xEF, 0xF4, 0xF9, 0x77, 0x79, 0xFB, 0xFC, 0xF6, 0xEE, 0xE9, 0xF2, 0x6D, 0x70, 0x6F, +0x6F, 0xFE, 0x6A, 0x69, 0x7F, 0x6F, 0x6F, 0x79, 0x78, 0x77, 0x6E, 0xFE, 0xEE, 0xF0, 0xEF, 0x7E, +0xF4, 0xE9, 0xF8, 0xFD, 0x7C, 0x77, 0x7D, 0x78, 0x7D, 0xFE, 0x79, 0x72, 0x6E, 0x72, 0x7B, 0x73, +0x6B, 0x74, 0x76, 0x6C, 0x72, 0x70, 0x75, 0x6D, 0x5A, 0x5C, 0x6A, 0x77, 0xFE, 0x71, 0x7A, 0xF2, +0xE9, 0xE7, 0xEA, 0xDE, 0xE6, 0xF5, 0xEB, 0xF5, 0xEE, 0xEA, 0xF3, 0xEE, 0xF4, 0xEE, 0xF5, 0x73, +0xF4, 0xF6, 0x73, 0x7C, 0xEC, 0xE9, 0x72, 0x67, 0x6C, 0x70, 0x6E, 0x69, 0x6F, 0x68, 0x5D, 0x64, +0x71, 0x75, 0x6B, 0x6D, 0xF9, 0x79, 0x6F, 0xF4, 0xEA, 0xF5, 0x79, 0x7B, 0x7D, 0xFA, 0xF3, 0xF7, +0xF4, 0xF4, 0xF9, 0x7F, 0x77, 0x7F, 0xF5, 0xFD, 0x71, 0x71, 0x7B, 0x78, 0x7A, 0x73, 0x68, 0x71, +0x7A, 0x6B, 0x6C, 0x6E, 0x69, 0x6E, 0x71, 0x6C, 0x69, 0x6C, 0x7A, 0x7D, 0xF6, 0xEB, 0xF4, 0xF2, +0xF4, 0x78, 0xF8, 0xF1, 0xF6, 0xFE, 0x71, 0x75, 0x7C, 0x7B, 0x7D, 0x7E, 0xFB, 0x7E, 0x77, 0x76, +0xFF, 0xF7, 0x79, 0x70, 0x6E, 0x6C, 0x71, 0x6F, 0x6C, 0x6A, 0x70, 0x6E, 0x5F, 0x65, 0x6C, 0x66, +0x6D, 0x7A, 0xF1, 0x78, 0x6B, 0xED, 0xFB, 0x6C, 0x7C, 0x74, 0xF1, 0xEC, 0x76, 0xF9, 0xF8, 0x75, +0x71, 0x7A, 0xEC, 0xFA, 0x6C, 0x76, 0x7C, 0x7F, 0x6E, 0x6A, 0x76, 0x6C, 0x76, 0xF2, 0x7C, 0x76, +0x66, 0x62, 0x7D, 0xF9, 0x78, 0x69, 0x6A, 0xF8, 0x78, 0x6D, 0xFC, 0xF8, 0xF3, 0xF7, 0x7D, 0xEF, +0xF1, 0x7C, 0xF1, 0xE9, 0xEB, 0xEE, 0xF3, 0xFD, 0x73, 0x7D, 0xFA, 0x74, 0x78, 0x7A, 0x6E, 0x70, +0x76, 0x73, 0x6F, 0x6D, 0x6C, 0x68, 0x6D, 0x7D, 0x6E, 0x64, 0x6D, 0xFC, 0xFA, 0x71, 0x6F, 0xFF, +0x70, 0x70, 0xF0, 0xEE, 0xEF, 0xEB, 0xEC, 0xEC, 0xED, 0xF0, 0xEE, 0xE9, 0xEB, 0xF8, 0xFB, 0xED, +0xE9, 0xF7, 0xFF, 0xED, 0xEE, 0xEF, 0xF3, 0x6E, 0x70, 0xF3, 0xFF, 0x6F, 0x6F, 0x6F, 0x79, 0x7C, +0x79, 0x7E, 0x77, 0x6E, 0x6E, 0x7B, 0x7C, 0x6B, 0x72, 0xF6, 0xFF, 0x7D, 0x7D, 0x72, 0x78, 0xFB, +0xFD, 0xFB, 0xFA, 0x7D, 0x7A, 0x6D, 0x68, 0x74, 0x75, 0xF1, 0xE7, 0x7B, 0x76, 0x6B, 0x66, 0xFD, +0x73, 0x68, 0x6B, 0x73, 0x7C, 0x62, 0x64, 0x70, 0x64, 0x6D, 0x79, 0x70, 0x70, 0x74, 0xF8, 0x7C, +0x7C, 0xF8, 0x6B, 0x70, 0xF9, 0x7D, 0xF1, 0xF0, 0xFF, 0x7F, 0xF8, 0xED, 0xF2, 0xFC, 0xFF, 0x76, +0x7B, 0x7C, 0xFE, 0xFE, 0x6C, 0x7C, 0xED, 0x79, 0x77, 0x71, 0x69, 0x76, 0x7A, 0x76, 0x7A, 0x6F, +0x6E, 0x6E, 0x73, 0xFF, 0x78, 0x76, 0x7F, 0x7A, 0x6F, 0x78, 0xFE, 0x77, 0xFB, 0xEE, 0xEE, 0xF1, +0x7A, 0xFB, 0xEE, 0x75, 0x70, 0xFE, 0x7D, 0x72, 0x6D, 0x6F, 0x7B, 0xFB, 0xF9, 0x7C, 0x7E, 0x7A, +0x70, 0x76, 0x7B, 0xF7, 0xF5, 0x70, 0x74, 0xFF, 0x78, 0xFA, 0xFC, 0x79, 0x78, 0x6D, 0x7A, 0xFA, +0x77, 0xFC, 0xF4, 0xF1, 0xF1, 0xF7, 0xEB, 0xED, 0xFB, 0xF7, 0xEF, 0xF2, 0x78, 0x79, 0xF0, 0xF3, +0xFC, 0xFC, 0x7E, 0x77, 0xFF, 0xFC, 0x78, 0xF6, 0xF9, 0x6F, 0x7A, 0x78, 0x6F, 0xFF, 0xF9, 0x7E, +0x76, 0x72, 0x76, 0x78, 0x79, 0xFD, 0xFA, 0x7A, 0x7E, 0xF1, 0xFB, 0x7A, 0xF2, 0xEF, 0xFF, 0x74, +0x75, 0x7E, 0xFF, 0xF6, 0xE9, 0xF4, 0x71, 0x74, 0x74, 0x7C, 0xF8, 0x79, 0x75, 0x74, 0x73, 0xF9, +0xFE, 0xFF, 0xFA, 0x6A, 0x6C, 0xFE, 0x70, 0x72, 0x7C, 0x7D, 0x70, 0x67, 0x6F, 0x76, 0x7B, 0xF0, +0x7E, 0x6E, 0x6E, 0x76, 0xF1, 0xF2, 0x7A, 0x72, 0x7B, 0xFD, 0x79, 0x77, 0x6E, 0x6A, 0x6D, 0x6E, +0x74, 0x72, 0x77, 0xF5, 0x7C, 0x6D, 0x6C, 0x6D, 0x70, 0x76, 0xFD, 0xFC, 0xFF, 0xFE, 0xFE, 0xFA, +0x7D, 0x77, 0x74, 0x6F, 0xFB, 0xFA, 0x71, 0xFC, 0xF8, 0xFE, 0xEB, 0xE5, 0xEE, 0x7F, 0xF6, 0xED, +0xFA, 0x78, 0xF6, 0xF1, 0xF8, 0xF6, 0x79, 0x70, 0x7C, 0x75, 0x78, 0xF6, 0xFA, 0xFC, 0xFB, 0x7B, +0x7D, 0xF9, 0xF7, 0xF7, 0x7E, 0x6B, 0x68, 0xFA, 0xE6, 0xEE, 0x7B, 0x7B, 0x79, 0x7E, 0xFB, 0xF2, +0xEA, 0xEE, 0xF1, 0xF6, 0x79, 0xFB, 0xF0, 0xFB, 0xFF, 0xF0, 0xEE, 0xF4, 0xEF, 0xFB, 0x6F, 0x6C, +0x72, 0xFF, 0x71, 0x6C, 0x6A, 0x6D, 0xF4, 0xFB, 0x7C, 0xF3, 0xFA, 0xFC, 0x6F, 0x73, 0xFB, 0x72, +0x7D, 0x78, 0x76, 0xEF, 0xF3, 0x7C, 0x71, 0xFA, 0xF2, 0xFB, 0xEF, 0xF0, 0xEA, 0xFD, 0x6B, 0xED, +0xF2, 0x77, 0x6E, 0x6D, 0xFD, 0x64, 0xF3, 0xDF, 0x5C, 0x61, 0xED, 0xF2, 0x7E, 0x66, 0x73, 0x6E, +0x66, 0xFF, 0x6F, 0x72, 0x70, 0x66, 0xF3, 0xF7, 0x6F, 0x72, 0x75, 0xED, 0xEF, 0xF4, 0xED, 0xEF, +0xEF, 0x6E, 0x6F, 0xF7, 0x72, 0x7E, 0x78, 0x6F, 0xF9, 0x77, 0xFC, 0xF4, 0x6C, 0x66, 0x6A, 0x76, +0x65, 0x5C, 0x6D, 0xFF, 0xF8, 0xEA, 0xE2, 0xEF, 0x65, 0x70, 0xEB, 0xE8, 0xE2, 0xDF, 0xDA, 0xD9, +0xE3, 0xF0, 0xFA, 0xE6, 0xDD, 0xDF, 0xDF, 0xE0, 0xE4, 0xFC, 0x63, 0x60, 0x64, 0x63, 0x66, 0x78, +0x65, 0x57, 0x60, 0x67, 0x64, 0x67, 0x5F, 0x6E, 0xF3, 0x7F, 0x75, 0xFE, 0xEA, 0xF4, 0xF8, 0xE0, +0xE0, 0xE4, 0xE3, 0xE7, 0xEA, 0xFB, 0x6F, 0x6E, 0x75, 0x72, 0x68, 0x6E, 0x77, 0x74, 0x6D, 0x73, +0xF9, 0x74, 0xF2, 0xE2, 0xEF, 0xDE, 0xDD, 0x79, 0xFD, 0xF4, 0x6F, 0x6A, 0x6E, 0xFE, 0x7A, 0x68, +0x60, 0x63, 0x6B, 0x66, 0x67, 0x76, 0xFE, 0x78, 0x65, 0x63, 0x7A, 0xFF, 0x72, 0x72, 0x74, 0x7D, +0x7C, 0x6B, 0x72, 0xEF, 0xF6, 0x73, 0x74, 0x7C, 0x74, 0x68, 0x68, 0x73, 0xFA, 0xF6, 0x6F, 0x67, +0x6F, 0x6D, 0x6A, 0x69, 0x68, 0x74, 0x6D, 0x64, 0x6F, 0x75, 0x77, 0xFA, 0x7F, 0xF5, 0xEF, 0x78, +0x77, 0x7D, 0x7A, 0xFE, 0x77, 0x73, 0xF8, 0xF4, 0xFE, 0x6F, 0x71, 0xF7, 0x74, 0x79, 0xEF, 0x7B, +0xF9, 0xFA, 0x68, 0x71, 0x7F, 0x76, 0x73, 0x71, 0x7D, 0x7D, 0x65, 0x5D, 0x69, 0x6E, 0x5F, 0x67, +0x6F, 0x6D, 0xFF, 0x7F, 0x6E, 0x6F, 0x73, 0x77, 0xF2, 0xDE, 0xD4, 0xD0, 0xD0, 0xCF, 0xCE, 0xD0, +0xD2, 0xD6, 0xDA, 0xDB, 0xE7, 0x6D, 0x5B, 0x52, 0x4C, 0x47, 0x44, 0x43, 0x44, 0x47, 0x49, 0x4B, +0x4E, 0x52, 0x56, 0x5A, 0x5D, 0x64, 0x75, 0xE6, 0xCF, 0xC5, 0xBF, 0xBD, 0xBB, 0xB7, 0xB5, 0xB1, +0xAF, 0xB5, 0xC1, 0xDF, 0x51, 0x44, 0x3A, 0x33, 0x33, 0x37, 0x3D, 0x44, 0x48, 0x4D, 0x51, 0x54, +0x53, 0x4D, 0x49, 0x44, 0x43, 0x45, 0x46, 0x4C, 0x54, 0x65, 0xE4, 0xCF, 0xC4, 0xBB, 0xB4, 0xAF, +0xAD, 0xAC, 0xAA, 0xAB, 0xB5, 0xD1, 0x49, 0x3B, 0x35, 0x2F, 0x2D, 0x32, 0x3D, 0x4E, 0x57, 0x51, +0x4F, 0x50, 0x4C, 0x42, 0x3D, 0x3F, 0x46, 0x4A, 0x4F, 0x5E, 0xEC, 0xD9, 0xDA, 0xD2, 0xC8, 0xBE, +0xB7, 0xB0, 0xAD, 0xAB, 0xA9, 0xA8, 0xAD, 0xC4, 0x48, 0x36, 0x31, 0x2E, 0x2D, 0x30, 0x3E, 0x67, +0xE2, 0x63, 0x47, 0x43, 0x42, 0x39, 0x36, 0x3B, 0x46, 0x6B, 0xE1, 0xDB, 0xCC, 0xC8, 0xCC, 0xD7, +0xDD, 0xC6, 0xBA, 0xB2, 0xAC, 0xAA, 0xA7, 0xA7, 0xB0, 0x69, 0x32, 0x2D, 0x2D, 0x2C, 0x2D, 0x39, +0xF1, 0xC2, 0xCA, 0x5E, 0x3D, 0x38, 0x34, 0x2E, 0x2F, 0x3E, 0x69, 0xCC, 0xC3, 0xBD, 0xBD, 0xC2, +0xCD, 0xEC, 0xF4, 0xCD, 0xC0, 0xB7, 0xAC, 0xA7, 0xA4, 0xA4, 0xB7, 0x3A, 0x2A, 0x29, 0x2A, 0x2B, +0x30, 0x56, 0xBA, 0xB6, 0xCD, 0x4A, 0x33, 0x2C, 0x2C, 0x2B, 0x34, 0x65, 0xC3, 0xBB, 0xBB, 0xBC, +0xC1, 0xDA, 0x7F, 0x6A, 0x75, 0xD1, 0xC2, 0xB8, 0xAC, 0xA6, 0xA5, 0xA4, 0xB0, 0x35, 0x23, 0x25, +0x29, 0x2F, 0x38, 0x73, 0xB3, 0xAF, 0xC8, 0x3E, 0x2E, 0x29, 0x26, 0x2C, 0x3D, 0xDF, 0xB8, 0xB5, +0xBB, 0xC5, 0xE7, 0x5A, 0x53, 0x68, 0xD9, 0xC8, 0xBA, 0xB3, 0xAD, 0xA8, 0xA7, 0xA6, 0xAF, 0x34, +0x1F, 0x24, 0x2E, 0x3B, 0x48, 0xDA, 0xB3, 0xB0, 0xD6, 0x33, 0x29, 0x29, 0x29, 0x2F, 0x5B, 0xC3, +0xB9, 0xB8, 0xC1, 0xDB, 0x53, 0x46, 0x4E, 0xEE, 0xCB, 0xC5, 0xBF, 0xBA, 0xB6, 0xAE, 0xAA, 0xA8, +0xAA, 0xDB, 0x26, 0x20, 0x2B, 0x3E, 0x5E, 0xEE, 0xC1, 0xB6, 0xC1, 0x3F, 0x2A, 0x29, 0x2A, 0x2F, +0x4F, 0xCA, 0xC0, 0xBE, 0xC5, 0xDC, 0x51, 0x44, 0x4B, 0x7D, 0xCB, 0xC5, 0xC5, 0xC2, 0xBF, 0xBD, +0xB1, 0xA9, 0xA8, 0xAA, 0xCB, 0x28, 0x20, 0x2C, 0x44, 0x7E, 0xDE, 0xC8, 0xBB, 0xC6, 0x3F, 0x2B, +0x29, 0x2E, 0x35, 0x4C, 0xCB, 0xBF, 0xC3, 0xCA, 0xE6, 0x4E, 0x43, 0x44, 0x6A, 0xC8, 0xC3, 0xC3, +0xC8, 0xC8, 0xBE, 0xB5, 0xAB, 0xA7, 0xA8, 0xBC, 0x2D, 0x1F, 0x29, 0x42, 0xD7, 0xD0, 0xCD, 0xBF, +0xC5, 0x4C, 0x2E, 0x2B, 0x2F, 0x36, 0x4A, 0xD7, 0xBE, 0xBD, 0xD5, 0x74, 0x50, 0x42, 0x45, 0x53, +0xD1, 0xBE, 0xBE, 0xC5, 0xD2, 0xCD, 0xBC, 0xAE, 0xA7, 0xA7, 0xB5, 0x36, 0x21, 0x28, 0x41, 0xD1, +0xC9, 0xD4, 0xCB, 0xCB, 0x51, 0x31, 0x2B, 0x2F, 0x39, 0x47, 0xE9, 0xC5, 0xC0, 0xCD, 0xED, 0x50, +0x3F, 0x3F, 0x52, 0xCD, 0xBB, 0xBC, 0xC6, 0xDE, 0xE7, 0xCB, 0xB5, 0xA8, 0xA4, 0xA9, 0xCC, 0x28, +0x20, 0x2E, 0x6F, 0xC2, 0xCF, 0xF7, 0xDA, 0xEB, 0x3F, 0x2E, 0x2D, 0x34, 0x3E, 0x5D, 0xCD, 0xBF, +0xC7, 0x73, 0x53, 0x43, 0x3C, 0x49, 0xDD, 0xBC, 0xB7, 0xC2, 0xE4, 0x62, 0xEC, 0xBD, 0xAA, 0xA3, +0xA4, 0xB3, 0x32, 0x1F, 0x26, 0x42, 0xC3, 0xC0, 0xF2, 0x68, 0x73, 0x4D, 0x37, 0x2D, 0x2F, 0x39, +0x47, 0xDD, 0xC2, 0xBE, 0xD2, 0x4A, 0x3E, 0x3B, 0x42, 0xEB, 0xBE, 0xB5, 0xB9, 0xD5, 0x54, 0x54, +0xCB, 0xAD, 0xA3, 0xA2, 0xAC, 0x4D, 0x23, 0x21, 0x34, 0xCF, 0xBA, 0xD0, 0x5E, 0x73, 0x5D, 0x43, +0x34, 0x30, 0x38, 0x3C, 0x46, 0xCE, 0xB9, 0xBE, 0x5F, 0x3E, 0x3B, 0x3E, 0x62, 0xC0, 0xB5, 0xB6, +0xC9, 0x54, 0x48, 0xE3, 0xB1, 0xA4, 0xA0, 0xA6, 0xC3, 0x2B, 0x1E, 0x29, 0x5D, 0xB9, 0xBD, 0x72, +0x50, 0x5B, 0x50, 0x3C, 0x30, 0x30, 0x36, 0x3F, 0x7C, 0xC0, 0xBA, 0xD0, 0x45, 0x3A, 0x38, 0x46, +0xCB, 0xB7, 0xB5, 0xC4, 0x5A, 0x48, 0x62, 0xBA, 0xA8, 0xA1, 0xA3, 0xB0, 0x3C, 0x20, 0x20, 0x39, +0xBD, 0xB1, 0xC7, 0x4F, 0x4A, 0x4E, 0x48, 0x35, 0x2E, 0x31, 0x39, 0x56, 0xC0, 0xB8, 0xC2, 0x4D, +0x39, 0x37, 0x3E, 0xE2, 0xBC, 0xB6, 0xBB, 0xDC, 0x4B, 0x4A, 0xD3, 0xAE, 0xA3, 0xA0, 0xA8, 0xD5, +0x29, 0x1F, 0x2B, 0xE3, 0xB3, 0xBA, 0x65, 0x47, 0x4C, 0x4F, 0x3D, 0x2F, 0x2D, 0x30, 0x41, 0xCB, +0xB7, 0xBA, 0x76, 0x3D, 0x38, 0x39, 0x51, 0xC5, 0xB6, 0xB6, 0xCC, 0x50, 0x46, 0x7E, 0xB4, 0xA6, +0xA1, 0xA4, 0xB8, 0x35, 0x20, 0x25, 0x48, 0xB8, 0xB5, 0xDB, 0x47, 0x47, 0x52, 0x4A, 0x34, 0x2D, +0x2E, 0x39, 0xEC, 0xBA, 0xB6, 0xCF, 0x3F, 0x38, 0x37, 0x41, 0xD0, 0xB8, 0xB4, 0xBF, 0x6A, 0x4A, +0x5B, 0xBC, 0xA8, 0xA1, 0xA2, 0xAF, 0x3E, 0x22, 0x24, 0x3E, 0xBA, 0xB3, 0xD4, 0x45, 0x41, 0x4F, +0x52, 0x37, 0x2D, 0x2D, 0x36, 0x65, 0xBB, 0xB6, 0xC9, 0x46, 0x38, 0x35, 0x3D, 0xDC, 0xB7, 0xB0, +0xBA, 0xF0, 0x48, 0x4E, 0xC1, 0xAA, 0xA2, 0xA1, 0xAB, 0x5E, 0x27, 0x21, 0x32, 0xC7, 0xB4, 0xC8, +0x48, 0x3E, 0x4B, 0x58, 0x3D, 0x2E, 0x2C, 0x2F, 0x48, 0xBF, 0xB5, 0xBF, 0x4C, 0x36, 0x34, 0x3A, +0x67, 0xBC, 0xB2, 0xB7, 0xD6, 0x4C, 0x4A, 0xCE, 0xAD, 0xA3, 0xA0, 0xA7, 0xD8, 0x29, 0x20, 0x2F, +0xD2, 0xB5, 0xC4, 0x4C, 0x40, 0x4B, 0x64, 0x44, 0x2F, 0x2C, 0x2D, 0x3F, 0xC4, 0xB4, 0xB9, 0x5F, +0x39, 0x36, 0x39, 0x5D, 0xBE, 0xB3, 0xB4, 0xC8, 0x59, 0x4B, 0xDC, 0xAF, 0xA3, 0x9F, 0xA5, 0xC5, +0x2C, 0x21, 0x2C, 0xFB, 0xB9, 0xC1, 0x53, 0x42, 0x4A, 0x5F, 0x49, 0x31, 0x2C, 0x2C, 0x3A, 0xCF, +0xB6, 0xBA, 0xF7, 0x3E, 0x39, 0x3A, 0x4C, 0xCA, 0xB7, 0xB4, 0xBF, 0x79, 0x4D, 0xE5, 0xB1, 0xA4, +0x9F, 0xA4, 0xC6, 0x2B, 0x20, 0x2C, 0xEC, 0xB7, 0xC1, 0x57, 0x43, 0x49, 0x5C, 0x47, 0x31, 0x2C, +0x2C, 0x39, 0xD3, 0xB7, 0xBA, 0xDC, 0x46, 0x3C, 0x39, 0x47, 0xCE, 0xB9, 0xB5, 0xBD, 0xDE, 0x5E, +0xD3, 0xB0, 0xA4, 0xA0, 0xA6, 0xCF, 0x2A, 0x21, 0x2D, 0xF6, 0xBB, 0xC8, 0x55, 0x44, 0x48, 0x51, +0x3F, 0x2F, 0x2C, 0x2D, 0x3B, 0xD8, 0xBC, 0xBF, 0xE7, 0x4E, 0x45, 0x3C, 0x44, 0xEB, 0xBE, 0xB5, +0xBA, 0xCA, 0xE3, 0xC9, 0xAF, 0xA5, 0xA0, 0xA7, 0xE6, 0x28, 0x22, 0x2E, 0xEA, 0xBD, 0xC8, 0x5D, +0x46, 0x4A, 0x4D, 0x3B, 0x2F, 0x2D, 0x2F, 0x3F, 0xD0, 0xBE, 0xC3, 0xE6, 0x56, 0x4B, 0x43, 0x4C, +0xFA, 0xC8, 0xBB, 0xBB, 0xC3, 0xC8, 0xBD, 0xAE, 0xA7, 0xA3, 0xAA, 0x6C, 0x2A, 0x25, 0x30, 0x5A, +0xCD, 0xD3, 0x5F, 0x4D, 0x50, 0x4C, 0x3B, 0x2F, 0x2D, 0x2F, 0x3D, 0xE6, 0xCC, 0xD3, 0xDA, 0xDB, +0x79, 0x55, 0x56, 0x68, 0xE0, 0xCA, 0xC2, 0xC0, 0xBC, 0xB1, 0xAB, 0xA6, 0xA5, 0xAE, 0x53, 0x2C, +0x29, 0x30, 0x41, 0x59, 0x62, 0x53, 0x57, 0x7F, 0x5D, 0x40, 0x35, 0x2E, 0x2F, 0x3D, 0x58, 0x78, +0xE5, 0xCD, 0xC8, 0xCF, 0xDA, 0xEC, 0x7B, 0xE4, 0xD1, 0xCA, 0xC4, 0xBA, 0xB0, 0xAC, 0xAA, 0xAB, +0xBA, 0x4F, 0x39, 0x39, 0x3D, 0x3F, 0x42, 0x3D, 0x3C, 0x45, 0x51, 0x52, 0x4C, 0x42, 0x3B, 0x3E, +0x4A, 0x4C, 0x4D, 0x57, 0x69, 0xEE, 0xDE, 0xE4, 0xFD, 0xED, 0xDC, 0xD3, 0xCD, 0xCA, 0xC3, 0xBD, +0xB9, 0xB6, 0xB8, 0xC3, 0xCE, 0xC8, 0xC1, 0xC5, 0xCE, 0xF9, 0x4A, 0x3F, 0x3F, 0x41, 0x3F, 0x3D, +0x39, 0x38, 0x3B, 0x3C, 0x3A, 0x3C, 0x43, 0x4C, 0x52, 0x58, 0x5B, 0x59, 0x65, 0xDC, 0xCB, 0xC3, +0xBD, 0xB8, 0xB6, 0xB2, 0xAF, 0xB2, 0xB6, 0xB2, 0xB0, 0xB6, 0xBF, 0xD7, 0x4F, 0x40, 0x3F, 0x3D, +0x3A, 0x35, 0x2F, 0x2D, 0x2F, 0x32, 0x33, 0x34, 0x39, 0x3E, 0x46, 0x51, 0x59, 0x5C, 0x6F, 0xD8, +0xC6, 0xBD, 0xB8, 0xB4, 0xB2, 0xAF, 0xAC, 0xAD, 0xAF, 0xAE, 0xAE, 0xB2, 0xBC, 0xCF, 0x55, 0x42, +0x3E, 0x3B, 0x36, 0x31, 0x2D, 0x2A, 0x2B, 0x2F, 0x32, 0x33, 0x36, 0x3B, 0x40, 0x4A, 0x57, 0x69, +0xEE, 0xD6, 0xC8, 0xBF, 0xB9, 0xB3, 0xB1, 0xAF, 0xAC, 0xAB, 0xAE, 0xAF, 0xAF, 0xB1, 0xB9, 0xC6, +0x75, 0x46, 0x3D, 0x3A, 0x36, 0x30, 0x2D, 0x2B, 0x2A, 0x2D, 0x31, 0x34, 0x36, 0x39, 0x3E, 0x46, +0x56, 0x77, 0xE3, 0xD4, 0xCA, 0xC3, 0xBD, 0xB6, 0xB1, 0xAF, 0xAC, 0xAB, 0xAC, 0xAF, 0xAF, 0xB0, +0xB5, 0xBE, 0xDA, 0x4E, 0x3E, 0x3A, 0x36, 0x31, 0x2D, 0x2C, 0x2B, 0x2C, 0x2F, 0x32, 0x34, 0x38, +0x3D, 0x43, 0x4D, 0x66, 0xE7, 0xD6, 0xCB, 0xC5, 0xC0, 0xBA, 0xB3, 0xAF, 0xAD, 0xAB, 0xAC, 0xAE, +0xAF, 0xAF, 0xB3, 0xBB, 0xCD, 0x5A, 0x40, 0x3A, 0x36, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, 0x2F, 0x31, +0x32, 0x38, 0x3D, 0x41, 0x4B, 0x5C, 0xF8, 0xD8, 0xCA, 0xC3, 0xBF, 0xBA, 0xB4, 0xB0, 0xAD, 0xAB, +0xAB, 0xAE, 0xAF, 0xB0, 0xB3, 0xBA, 0xC9, 0x68, 0x46, 0x3C, 0x37, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, +0x2F, 0x30, 0x31, 0x36, 0x3C, 0x3F, 0x49, 0x58, 0x70, 0xDD, 0xCA, 0xC2, 0xBE, 0xB9, 0xB3, 0xB0, +0xAD, 0xAA, 0xAB, 0xAE, 0xAF, 0xAF, 0xB4, 0xBC, 0xCB, 0x61, 0x46, 0x3D, 0x36, 0x30, 0x2E, 0x2C, +0x2B, 0x2D, 0x2F, 0x2F, 0x31, 0x37, 0x3B, 0x3F, 0x4B, 0x5C, 0xFF, 0xD8, 0xC8, 0xC1, 0xBC, 0xB6, +0xB2, 0xAF, 0xAC, 0xAA, 0xAB, 0xAD, 0xAE, 0xAF, 0xB5, 0xBD, 0xCF, 0x5C, 0x45, 0x3C, 0x35, 0x2F, +0x2D, 0x2C, 0x2C, 0x2D, 0x2F, 0x2F, 0x32, 0x37, 0x3B, 0x3F, 0x4B, 0x5F, 0xEE, 0xD4, 0xC8, 0xC1, +0xBC, 0xB5, 0xB0, 0xAE, 0xAB, 0xAA, 0xAB, 0xAD, 0xAF, 0xB1, 0xB7, 0xC0, 0xD9, 0x53, 0x42, 0x3B, +0x34, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x30, 0x33, 0x37, 0x3C, 0x43, 0x4D, 0x5E, 0xEC, 0xD0, +0xC7, 0xC0, 0xBB, 0xB6, 0xB0, 0xAE, 0xAB, 0xAA, 0xAC, 0xAE, 0xAF, 0xB3, 0xB9, 0xC5, 0xE2, 0x4E, +0x3F, 0x39, 0x32, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x2F, 0x33, 0x39, 0x3D, 0x44, 0x4F, 0x65, +0xE3, 0xCE, 0xC5, 0xBF, 0xBA, 0xB4, 0xAF, 0xAD, 0xAA, 0xAA, 0xAC, 0xAE, 0xB0, 0xB5, 0xBB, 0xC8, +0xF8, 0x4C, 0x3E, 0x38, 0x31, 0x2E, 0x2C, 0x2B, 0x2C, 0x2E, 0x2F, 0x31, 0x35, 0x39, 0x3E, 0x4A, +0x5C, 0xF9, 0xD8, 0xCB, 0xC2, 0xBC, 0xB7, 0xB2, 0xAE, 0xAB, 0xA9, 0xAA, 0xAC, 0xAE, 0xB2, 0xB8, +0xBE, 0xCE, 0x72, 0x48, 0x3B, 0x34, 0x2F, 0x2E, 0x2C, 0x2B, 0x2C, 0x2D, 0x2F, 0x31, 0x36, 0x3A, +0x3E, 0x4A, 0x5F, 0xEA, 0xD0, 0xC9, 0xC1, 0xBB, 0xB5, 0xB0, 0xAE, 0xAB, 0xA9, 0xAB, 0xAC, 0xAE, +0xB4, 0xBB, 0xC4, 0xD6, 0x60, 0x45, 0x39, 0x30, 0x2D, 0x2C, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x32, +0x35, 0x3A, 0x43, 0x51, 0x6A, 0xDF, 0xCB, 0xC3, 0xBD, 0xB8, 0xB2, 0xAE, 0xAC, 0xAA, 0xAA, 0xAB, +0xAC, 0xAF, 0xB7, 0xBD, 0xCC, 0xF1, 0x51, 0x3F, 0x36, 0x2F, 0x2D, 0x2B, 0x2A, 0x2C, 0x2D, 0x2E, +0x2F, 0x33, 0x37, 0x3B, 0x45, 0x58, 0x77, 0xD5, 0xC8, 0xC0, 0xBB, 0xB6, 0xB1, 0xAE, 0xAB, 0xA9, +0xAA, 0xAB, 0xAC, 0xB1, 0xB9, 0xC0, 0xD3, 0x6A, 0x4A, 0x3C, 0x33, 0x2E, 0x2D, 0x2B, 0x2B, 0x2C, +0x2D, 0x2E, 0x31, 0x34, 0x38, 0x3F, 0x4C, 0x5D, 0xEA, 0xCE, 0xC6, 0xBE, 0xB8, 0xB4, 0xAF, 0xAD, +0xAB, 0xAA, 0xAA, 0xAB, 0xAD, 0xB2, 0xB9, 0xC3, 0xD8, 0x61, 0x47, 0x3A, 0x32, 0x2E, 0x2C, 0x2B, +0x2C, 0x2C, 0x2D, 0x2F, 0x31, 0x34, 0x38, 0x3F, 0x4D, 0x62, 0xDD, 0xCC, 0xC3, 0xBC, 0xB7, 0xB2, +0xAE, 0xAC, 0xAA, 0xAA, 0xAA, 0xAB, 0xAE, 0xB3, 0xBA, 0xC6, 0xE1, 0x55, 0x41, 0x37, 0x30, 0x2D, +0x2B, 0x2A, 0x2B, 0x2C, 0x2D, 0x2F, 0x31, 0x34, 0x39, 0x40, 0x4D, 0x6A, 0xD8, 0xC9, 0xC1, 0xBC, +0xB7, 0xB2, 0xAE, 0xAC, 0xAA, 0xAA, 0xAB, 0xAC, 0xAF, 0xB7, 0xBB, 0xC6, 0x79, 0x55, 0x44, 0x37, +0x30, 0x2D, 0x2C, 0x2B, 0x2C, 0x2D, 0x2D, 0x2F, 0x33, 0x35, 0x39, 0x42, 0x51, 0x6C, 0xDA, 0xCA, +0xC4, 0xBE, 0xBA, 0xB6, 0xB0, 0xAD, 0xAC, 0xAC, 0xAC, 0xAD, 0xAF, 0xB4, 0xB9, 0xC0, 0xD0, 0x65, +0x47, 0x3A, 0x32, 0x2F, 0x2C, 0x2B, 0x2B, 0x2C, 0x2D, 0x2E, 0x31, 0x36, 0x3A, 0x3F, 0x4A, 0x5E, +0xDC, 0xCC, 0xC4, 0xBE, 0xBA, 0xB6, 0xB2, 0xAF, 0xAE, 0xAC, 0xAD, 0xAE, 0xAF, 0xB2, 0xB8, 0xBE, +0xCA, 0xE6, 0x4F, 0x3F, 0x38, 0x31, 0x2E, 0x2C, 0x2C, 0x2C, 0x2D, 0x2F, 0x31, 0x35, 0x3A, 0x3F, +0x4B, 0x64, 0xDD, 0xCB, 0xC3, 0xBD, 0xBA, 0xB7, 0xB4, 0xB1, 0xAF, 0xAE, 0xAE, 0xB0, 0xB3, 0xB5, +0xB9, 0xBE, 0xC6, 0xD3, 0x74, 0x4E, 0x40, 0x3A, 0x35, 0x32, 0x30, 0x2F, 0x2F, 0x30, 0x33, 0x36, +0x3A, 0x3F, 0x48, 0x52, 0x6C, 0xDF, 0xCE, 0xC7, 0xC1, 0xBE, 0xBB, 0xB9, 0xB8, 0xB7, 0xB6, 0xB6, +0xB7, 0xB9, 0xBB, 0xBE, 0xC4, 0xCA, 0xD9, 0x6C, 0x50, 0x45, 0x3D, 0x3A, 0x37, 0x35, 0x35, 0x35, +0x36, 0x37, 0x39, 0x3C, 0x3F, 0x46, 0x4F, 0x5E, 0xF1, 0xD9, 0xCF, 0xCC, 0xC9, 0xC5, 0xC1, 0xBE, +0xBC, 0xBC, 0xBC, 0xBD, 0xBF, 0xC2, 0xC4, 0xC7, 0xCC, 0xD5, 0xE8, 0x64, 0x52, 0x4A, 0x45, 0x41, +0x3F, 0x3E, 0x3D, 0x3D, 0x3E, 0x41, 0x45, 0x49, 0x4D, 0x53, 0x5C, 0x71, 0xE9, 0xDD, 0xD6, 0xD1, +0xCE, 0xCB, 0xC9, 0xC8, 0xC8, 0xC7, 0xC7, 0xC8, 0xC9, 0xCC, 0xCF, 0xD4, 0xDA, 0xE4, 0xF7, 0x69, +0x5B, 0x53, 0x4F, 0x4E, 0x4D, 0x4D, 0x4D, 0x4E, 0x51, 0x58, 0x5F, 0x68, 0x6F, 0x77, 0xFC, 0xEE, +0xE8, 0xE5, 0xE1, 0xDD, 0xDE, 0xDE, 0xDE, 0xE2, 0xE6, 0xE6, 0xEB, 0xF0, 0xED, 0xEA, 0xEC, 0xEE, +0xF8, 0x6A, 0x5C, 0x57, 0x55, 0x56, 0x58, 0x59, 0x58, 0x58, 0x5B, 0x5E, 0x63, 0x71, 0xF7, 0xEE, +0xE9, 0xE3, 0xE4, 0xE8, 0xE7, 0xEA, 0xEE, 0xEE, 0xF2, 0xFB, 0xFF, 0x7B, 0x74, 0x6E, 0x6B, 0x65, +0x60, 0x65, 0x67, 0x61, 0x60, 0x61, 0x5E, 0x5E, 0x62, 0x69, 0x70, 0x7F, 0xF6, 0xF2, 0xEC, 0xE7, +0xE6, 0xE3, 0xDF, 0xDE, 0xDE, 0xDD, 0xDE, 0xE0, 0xE5, 0xEC, 0xF6, 0x7F, 0x78, 0x75, 0x70, 0x6B, +0x64, 0x5E, 0x5A, 0x58, 0x58, 0x59, 0x5A, 0x5C, 0x5D, 0x5E, 0x61, 0x67, 0x6C, 0x75, 0xF8, 0xEC, +0xE6, 0xE0, 0xDD, 0xDD, 0xDE, 0xDF, 0xE0, 0xE2, 0xE2, 0xE4, 0xE6, 0xE9, 0xEE, 0xF9, 0x7D, 0x75, +0x6E, 0x6A, 0x65, 0x61, 0x5E, 0x5C, 0x5B, 0x5C, 0x5D, 0x5E, 0x60, 0x63, 0x66, 0x6C, 0x76, 0xFA, +0xEE, 0xE9, 0xE4, 0xE1, 0xDF, 0xDD, 0xDE, 0xDF, 0xE2, 0xE6, 0xEA, 0xEE, 0xF4, 0xFA, 0x7E, 0x7A, +0x75, 0x72, 0x74, 0x74, 0x71, 0x70, 0x6D, 0x6A, 0x6A, 0x6B, 0x6D, 0x70, 0x74, 0x78, 0x7A, 0x7D, +0xFA, 0xF0, 0xEA, 0xE5, 0xE3, 0xE2, 0xE0, 0xDF, 0xE1, 0xE3, 0xE4, 0xE8, 0xEB, 0xEE, 0xF4, 0xFB, +0x7E, 0x75, 0x6D, 0x6B, 0x6A, 0x69, 0x68, 0x67, 0x65, 0x64, 0x63, 0x64, 0x66, 0x69, 0x6D, 0x72, +0x77, 0x7B, 0xFE, 0xF7, 0xF0, 0xEB, 0xE8, 0xE7, 0xE6, 0xE6, 0xE6, 0xE7, 0xE7, 0xE8, 0xEA, 0xED, +0xF3, 0xFC, 0x79, 0x72, 0x6F, 0x6C, 0x6B, 0x6B, 0x69, 0x66, 0x64, 0x63, 0x62, 0x63, 0x67, 0x6C, +0x73, 0x7C, 0xFE, 0xFD, 0xFA, 0xF4, 0xEE, 0xEA, 0xE5, 0xE1, 0xE1, 0xE2, 0xE5, 0xE9, 0xED, 0xEF, +0xF1, 0xF2, 0xF4, 0xF8, 0xFF, 0x76, 0x6E, 0x6A, 0x68, 0x67, 0x66, 0x65, 0x64, 0x62, 0x61, 0x61, +0x63, 0x67, 0x6B, 0x72, 0x7E, 0xFA, 0xF5, 0xF1, 0xEE, 0xED, 0xEC, 0xE9, 0xE8, 0xE7, 0xE7, 0xE9, +0xEC, 0xF0, 0xF9, 0x7D, 0x77, 0x73, 0x70, 0x6F, 0x6E, 0x6C, 0x69, 0x67, 0x65, 0x66, 0x66, 0x68, +0x69, 0x69, 0x6A, 0x6C, 0x6E, 0x75, 0x7F, 0xF8, 0xF1, 0xED, 0xEB, 0xEA, 0xEA, 0xEB, 0xEB, 0xEB, +0xEA, 0xE9, 0xEA, 0xEC, 0xEF, 0xF4, 0xFB, 0x7D, 0x77, 0x73, 0x71, 0x6F, 0x6D, 0x6B, 0x69, 0x67, +0x66, 0x67, 0x68, 0x69, 0x6B, 0x6D, 0x6F, 0x74, 0x79, 0x7F, 0xF9, 0xF3, 0xEF, 0xEE, 0xEE, 0xEE, +0xEE, 0xED, 0xED, 0xED, 0xEE, 0xEC, 0xEC, 0xF1, 0xF3, 0xF6, 0xFD, 0xFF, 0x7D, 0x78, 0x78, 0x76, +0x70, 0x6F, 0x6E, 0x6D, 0x6D, 0x6E, 0x6F, 0x71, 0x73, 0x77, 0x7B, 0x7D, 0xFF, 0xFB, 0xF8, 0xF8, +0xFA, 0xFB, 0xFE, 0x7E, 0x7D, 0x7A, 0x79, 0x7A, 0x76, 0x76, 0x76, 0x72, 0x70, 0x6F, 0x6D, 0x6E, +0x6D, 0x6B, 0x6E, 0x65, 0x66, 0x57, 0x41, 0x59, 0xC7, 0x62, 0x57, 0xCD, 0x64, 0x6B, 0xCC, 0x6D, +0xF6, 0xD1, 0x69, 0x6E, 0xDA, 0x7D, 0x61, 0xEE, 0xF1, 0xFD, 0xFF, 0x6E, 0xE7, 0x74, 0x66, 0xE9, +0x6A, 0xFC, 0xF2, 0x64, 0xEE, 0x6F, 0x6B, 0x7B, 0x69, 0xF2, 0x68, 0x74, 0xEC, 0x5F, 0xED, 0xFC, +0x5F, 0xDE, 0x72, 0x65, 0xDC, 0x51, 0x4C, 0xE8, 0x5F, 0xEF, 0xD7, 0x4E, 0xF3, 0xF9, 0x52, 0xC3, +0xE2, 0x56, 0xC9, 0x5B, 0x59, 0xE4, 0x50, 0x53, 0x47, 0x66, 0xF9, 0x47, 0xC9, 0xCB, 0x59, 0xD4, +0x55, 0x58, 0xD3, 0x5C, 0xF9, 0xCE, 0xD7, 0x6D, 0x61, 0xDB, 0xE4, 0xE8, 0x70, 0x79, 0xCD, 0x6B, +0x5D, 0xEC, 0x66, 0xDC, 0x6C, 0x5F, 0xD3, 0xF9, 0xFB, 0x66, 0x55, 0xDE, 0xFB, 0x64, 0xD7, 0xDA, +0xF1, 0xF1, 0xF1, 0xE5, 0xDB, 0xF4, 0x75, 0xDF, 0xE7, 0xFD, 0x79, 0xEC, 0xD9, 0xF0, 0x6E, 0xF5, +0xE4, 0xE5, 0x64, 0x74, 0xDF, 0x7D, 0x68, 0x75, 0xF0, 0xFD, 0x7B, 0xFC, 0x7B, 0xDE, 0xEF, 0x64, +0xDF, 0xE8, 0xFF, 0xE9, 0xFF, 0xE2, 0xE1, 0x76, 0xF6, 0xEF, 0xEC, 0xF9, 0x6D, 0x7C, 0x73, 0x6D, +0x69, 0x67, 0x76, 0x75, 0x73, 0x64, 0x66, 0xFD, 0x60, 0x5F, 0x77, 0x67, 0x70, 0x74, 0x60, 0x78, +0x7A, 0x5C, 0x67, 0x79, 0x6C, 0x77, 0x63, 0x63, 0xEF, 0x6C, 0x66, 0x73, 0x6D, 0xF8, 0x72, 0x74, +0xE6, 0xFB, 0x7B, 0xF3, 0xF6, 0xF1, 0xFE, 0x7B, 0xF5, 0xF1, 0x6D, 0x63, 0x75, 0x6E, 0x60, 0x64, +0x67, 0x67, 0x68, 0x67, 0x67, 0x6C, 0x64, 0x5B, 0x65, 0x6E, 0x69, 0x72, 0x76, 0x74, 0xFE, 0xFD, +0xFF, 0xF6, 0xF3, 0x7C, 0x7A, 0xFC, 0xFE, 0xFB, 0x7E, 0x75, 0xF5, 0xEE, 0xFC, 0xF7, 0xF3, 0xFF, +0xFE, 0x74, 0x6B, 0x6F, 0x6D, 0x6A, 0x6C, 0x6A, 0x7A, 0xF9, 0x71, 0x7C, 0xF5, 0x7C, 0x7B, 0x7F, +0xFE, 0x72, 0x6E, 0xFF, 0x6F, 0x66, 0x6B, 0x6A, 0x6E, 0x76, 0x71, 0x7C, 0x7A, 0x6E, 0x6C, 0x69, +0x6C, 0x6D, 0x63, 0x65, 0x6A, 0x66, 0x63, 0x65, 0x6C, 0x68, 0x64, 0x69, 0x6A, 0x6E, 0x79, 0x7B, +0x78, 0x6D, 0x6E, 0x79, 0x77, 0xFA, 0xED, 0xEF, 0xEF, 0xEC, 0xE8, 0xEF, 0xFB, 0xF6, 0xEF, 0xEE, +0xF7, 0xF9, 0xF3, 0xF7, 0xF1, 0xF3, 0xFD, 0xFD, 0x7A, 0x7B, 0xFE, 0x79, 0x7C, 0x7B, 0x6E, 0x72, +0x7A, 0x72, 0x71, 0x79, 0x79, 0x6F, 0x6F, 0x78, 0x74, 0x72, 0x7B, 0x72, 0x78, 0xF6, 0xF7, 0xF9, +0x78, 0x79, 0xEE, 0xF5, 0x74, 0x76, 0x7A, 0xFE, 0x7E, 0x75, 0x7A, 0x7E, 0x74, 0x70, 0x7D, 0xF8, +0xF8, 0x7D, 0x77, 0xF8, 0xF0, 0x7F, 0x7E, 0xF2, 0xED, 0xF0, 0xF4, 0xEB, 0xE9, 0xFE, 0x74, 0xEF, +0xE1, 0xE0, 0xDC, 0xD9, 0xD7, 0xD3, 0xD7, 0xDD, 0xD9, 0xD9, 0xDF, 0xE6, 0xEB, 0xF2, 0x78, 0x65, +0x61, 0x65, 0x5F, 0x5A, 0x5B, 0x5B, 0x5A, 0x5C, 0x5B, 0x5D, 0x5E, 0x5C, 0x5B, 0x5B, 0x5B, 0x5C, +0x5E, 0x6B, 0xEA, 0xD9, 0xD2, 0xD1, 0xCD, 0xC8, 0xC6, 0xC5, 0xC5, 0xC3, 0xC3, 0xC6, 0xCA, 0xD2, +0xE8, 0x67, 0x51, 0x49, 0x42, 0x3D, 0x3D, 0x3E, 0x3F, 0x41, 0x44, 0x49, 0x4E, 0x50, 0x55, 0x5A, +0x5F, 0x6F, 0xEF, 0xDA, 0xCD, 0xCA, 0xC8, 0xC4, 0xBF, 0xBD, 0xBB, 0xB9, 0xB7, 0xB6, 0xBA, 0xC2, +0xCC, 0xE2, 0x56, 0x43, 0x3B, 0x39, 0x37, 0x36, 0x37, 0x3B, 0x3E, 0x42, 0x47, 0x4B, 0x51, 0x5A, +0x5B, 0x5E, 0x67, 0x7A, 0xED, 0xE8, 0xDB, 0xCF, 0xCB, 0xC5, 0xBD, 0xB9, 0xB6, 0xB2, 0xB0, 0xB4, +0xB9, 0xBF, 0xCD, 0xFC, 0x49, 0x3B, 0x37, 0x33, 0x31, 0x32, 0x33, 0x38, 0x3E, 0x45, 0x4F, 0x5F, +0x74, 0xF0, 0xEF, 0xF1, 0xF4, 0xFF, 0x77, 0x72, 0xFB, 0xE4, 0xD9, 0xCE, 0xC3, 0xBA, 0xB6, 0xB2, +0xB0, 0xB2, 0xB6, 0xBB, 0xC8, 0xE4, 0x51, 0x3E, 0x38, 0x33, 0x2F, 0x2F, 0x31, 0x35, 0x3A, 0x3E, +0x49, 0x5D, 0xFE, 0xE4, 0xDD, 0xD9, 0xD9, 0xE1, 0xEB, 0xEE, 0xEE, 0xE7, 0xDD, 0xD2, 0xC7, 0xBD, +0xB9, 0xB5, 0xB2, 0xB5, 0xB8, 0xBB, 0xC6, 0xDA, 0x5F, 0x45, 0x3D, 0x37, 0x33, 0x31, 0x31, 0x35, +0x39, 0x3D, 0x45, 0x53, 0x6F, 0xE3, 0xD9, 0xD0, 0xCF, 0xD2, 0xD5, 0xD9, 0xD9, 0xD8, 0xD4, 0xCE, +0xC8, 0xC0, 0xBD, 0xB9, 0xB8, 0xBB, 0xBD, 0xC1, 0xCD, 0xDF, 0x5F, 0x4A, 0x41, 0x3B, 0x37, 0x36, +0x35, 0x36, 0x3A, 0x3D, 0x44, 0x4E, 0x5F, 0xEC, 0xDB, 0xD6, 0xD2, 0xD4, 0xD6, 0xDA, 0xDD, 0xDB, +0xD8, 0xD2, 0xCD, 0xC9, 0xC3, 0xBF, 0xBE, 0xBF, 0xC3, 0xC4, 0xCA, 0xD6, 0xED, 0x5E, 0x50, 0x48, +0x3F, 0x3C, 0x3B, 0x3A, 0x3A, 0x3D, 0x40, 0x4A, 0x55, 0x6A, 0xE6, 0xDC, 0xD8, 0xD6, 0xD8, 0xD8, +0xDB, 0xDE, 0xDF, 0xE2, 0xDE, 0xDC, 0xD9, 0xD0, 0xCB, 0xC8, 0xC8, 0xCC, 0xCD, 0xCD, 0xD1, 0xDB, +0xF2, 0x67, 0x5B, 0x51, 0x49, 0x44, 0x42, 0x41, 0x42, 0x44, 0x49, 0x4E, 0x55, 0x5C, 0x6A, 0x7E, +0xF3, 0xED, 0xED, 0xEF, 0xEC, 0xED, 0xF4, 0xF7, 0xF0, 0xEB, 0xE4, 0xDF, 0xDA, 0xD2, 0xCD, 0xCC, +0xCC, 0xCF, 0xCF, 0xCE, 0xD3, 0xDB, 0xE7, 0x7C, 0x69, 0x5E, 0x54, 0x4F, 0x4E, 0x4D, 0x4E, 0x4F, +0x52, 0x58, 0x5B, 0x5E, 0x63, 0x67, 0x6B, 0x6B, 0x6A, 0x6B, 0x6C, 0x6E, 0x6F, 0x73, 0x7D, 0xF3, +0xEA, 0xE1, 0xDC, 0xD8, 0xD3, 0xD1, 0xCF, 0xCE, 0xD1, 0xD2, 0xD2, 0xD6, 0xDB, 0xE2, 0xEF, 0xFD, +0x73, 0x66, 0x5F, 0x5C, 0x5A, 0x59, 0x58, 0x56, 0x56, 0x57, 0x57, 0x58, 0x58, 0x5A, 0x5C, 0x5D, +0x61, 0x65, 0x6A, 0x74, 0x7E, 0xF4, 0xEA, 0xE2, 0xDD, 0xDA, 0xD7, 0xD5, 0xD2, 0xD1, 0xD0, 0xD1, +0xD3, 0xD3, 0xD4, 0xD7, 0xDB, 0xE0, 0xE8, 0xEF, 0x7B, 0x69, 0x5F, 0x5B, 0x57, 0x53, 0x50, 0x4F, +0x4F, 0x4F, 0x4F, 0x50, 0x52, 0x56, 0x59, 0x5C, 0x60, 0x68, 0x6E, 0x7A, 0xFB, 0xF1, 0xEB, 0xE7, +0xE2, 0xDE, 0xDC, 0xDA, 0xD7, 0xD5, 0xD3, 0xD3, 0xD3, 0xD5, 0xD5, 0xD8, 0xDC, 0xE4, 0xF2, 0x78, +0x6A, 0x5E, 0x59, 0x55, 0x52, 0x50, 0x4F, 0x4F, 0x50, 0x52, 0x55, 0x58, 0x5A, 0x5D, 0x61, 0x64, +0x69, 0x6E, 0x74, 0xFF, 0xF6, 0xEE, 0xE9, 0xE4, 0xDF, 0xDC, 0xD8, 0xD5, 0xD2, 0xD0, 0xD1, 0xD1, +0xD2, 0xD6, 0xD7, 0xDA, 0xDF, 0xE8, 0xF8, 0x71, 0x69, 0x60, 0x5C, 0x58, 0x56, 0x54, 0x53, 0x53, +0x53, 0x55, 0x56, 0x58, 0x5A, 0x5C, 0x5F, 0x63, 0x69, 0x71, 0xFF, 0xEF, 0xEA, 0xE6, 0xE1, 0xDF, +0xDE, 0xDB, 0xDA, 0xDA, 0xD7, 0xD4, 0xD1, 0xD1, 0xD2, 0xD4, 0xD7, 0xD8, 0xDB, 0xE1, 0xED, 0x78, +0x69, 0x61, 0x5A, 0x53, 0x50, 0x4F, 0x4E, 0x4F, 0x4F, 0x51, 0x55, 0x59, 0x5D, 0x60, 0x65, 0x6C, +0x6F, 0x76, 0x7E, 0xFC, 0xF5, 0xF2, 0xF2, 0xED, 0xE7, 0xE1, 0xDD, 0xD9, 0xD4, 0xCE, 0xCB, 0xCA, +0xC8, 0xCA, 0xCF, 0xD0, 0xD7, 0xE6, 0x7C, 0x5E, 0x53, 0x4F, 0x4C, 0x4A, 0x4A, 0x4A, 0x4C, 0x4E, +0x4F, 0x51, 0x57, 0x5D, 0x62, 0x66, 0x69, 0x6D, 0x6D, 0x67, 0x63, 0x65, 0x6B, 0x70, 0x75, 0xFE, +0xEA, 0xDC, 0xD3, 0xCE, 0xC9, 0xC2, 0xBE, 0xBC, 0xBC, 0xC1, 0xC8, 0xCB, 0xDC, 0x69, 0x50, 0x46, +0x42, 0x3F, 0x3D, 0x3D, 0x3F, 0x43, 0x4B, 0x4F, 0x55, 0x61, 0x6F, 0xFC, 0xF0, 0xFA, 0xFD, 0x7B, +0x63, 0x5A, 0x54, 0x52, 0x54, 0x58, 0x62, 0x7D, 0xDE, 0xCC, 0xC4, 0xBC, 0xB6, 0xB1, 0xAE, 0xB2, +0xBA, 0xC1, 0xDA, 0x5A, 0x45, 0x38, 0x33, 0x32, 0x33, 0x36, 0x3A, 0x3E, 0x4B, 0x66, 0xEA, 0xD6, +0xCE, 0xCF, 0xD3, 0xE0, 0x6E, 0x5C, 0x51, 0x4D, 0x4B, 0x4A, 0x4F, 0x5B, 0x7A, 0xD6, 0xC6, 0xBA, +0xB1, 0xAE, 0xAA, 0xAA, 0xAF, 0xBA, 0xD1, 0x4E, 0x3D, 0x31, 0x2B, 0x2B, 0x2C, 0x30, 0x38, 0x3E, +0x4E, 0xEA, 0xCD, 0xC7, 0xC8, 0xCB, 0xCE, 0xDD, 0x64, 0x4F, 0x48, 0x48, 0x47, 0x46, 0x4D, 0x62, +0xDD, 0xCA, 0xBD, 0xB1, 0xAC, 0xA9, 0xA7, 0xAA, 0xB2, 0xC4, 0x51, 0x3A, 0x2F, 0x29, 0x28, 0x2A, +0x2E, 0x39, 0x45, 0x5A, 0xDB, 0xC8, 0xC2, 0xC5, 0xCD, 0xD5, 0xE8, 0x5B, 0x4C, 0x46, 0x47, 0x4C, +0x4E, 0x59, 0xF3, 0xD3, 0xC6, 0xBE, 0xB5, 0xAD, 0xAA, 0xA6, 0xA8, 0xB2, 0xC5, 0x54, 0x38, 0x2F, +0x28, 0x26, 0x2A, 0x2F, 0x3A, 0x4B, 0x73, 0xCF, 0xC5, 0xC4, 0xC9, 0xD9, 0xF8, 0x5F, 0x4C, 0x47, +0x47, 0x48, 0x4F, 0x5A, 0x74, 0xD9, 0xCE, 0xC7, 0xBF, 0xBA, 0xB0, 0xAC, 0xAA, 0xA9, 0xB0, 0xC5, +0x5C, 0x3B, 0x30, 0x2B, 0x27, 0x29, 0x2E, 0x39, 0x49, 0x6C, 0xD2, 0xC7, 0xC5, 0xCA, 0xDA, 0x7A, +0x5E, 0x4D, 0x48, 0x49, 0x4B, 0x52, 0x5E, 0x70, 0xDC, 0xCE, 0xC9, 0xC4, 0xBE, 0xB5, 0xAE, 0xAC, +0xAA, 0xAD, 0xBB, 0xE1, 0x43, 0x35, 0x2E, 0x29, 0x28, 0x2B, 0x32, 0x3D, 0x4E, 0x7E, 0xD2, 0xC9, +0xC7, 0xCC, 0xDF, 0xFE, 0x61, 0x4F, 0x4C, 0x4B, 0x4C, 0x54, 0x5D, 0x72, 0xDA, 0xCE, 0xC7, 0xC0, +0xB9, 0xB0, 0xAD, 0xAA, 0xAA, 0xB1, 0xC5, 0x5D, 0x3D, 0x33, 0x2C, 0x29, 0x29, 0x2D, 0x35, 0x3F, +0x4F, 0x78, 0xD7, 0xCA, 0xC7, 0xCD, 0xD9, 0xE3, 0x71, 0x5C, 0x54, 0x4D, 0x4E, 0x55, 0x5A, 0x6E, +0xE3, 0xD3, 0xC8, 0xBE, 0xB6, 0xAF, 0xAC, 0xAA, 0xAC, 0xB7, 0xCE, 0x53, 0x3D, 0x34, 0x2D, 0x2A, +0x2A, 0x2E, 0x35, 0x3E, 0x4A, 0x5C, 0xE5, 0xCD, 0xC8, 0xCB, 0xCE, 0xD5, 0xE2, 0xF7, 0x66, 0x57, +0x54, 0x56, 0x5B, 0x6E, 0xE7, 0xD5, 0xC9, 0xBE, 0xB6, 0xB1, 0xAE, 0xAE, 0xB4, 0xBE, 0xD3, 0x5C, +0x46, 0x3C, 0x34, 0x30, 0x2F, 0x32, 0x38, 0x3E, 0x45, 0x4E, 0x69, 0xDC, 0xCF, 0xCD, 0xCF, 0xD3, +0xD9, 0xDF, 0xEF, 0x6F, 0x68, 0x67, 0x6F, 0xF7, 0xE7, 0xDC, 0xD2, 0xC8, 0xC1, 0xBE, 0xBC, 0xBD, +0xC3, 0xCB, 0xD5, 0xEA, 0x6A, 0x58, 0x4D, 0x47, 0x43, 0x43, 0x44, 0x47, 0x4A, 0x4D, 0x52, 0x5D, +0x6D, 0x78, 0x77, 0x78, 0x76, 0x73, 0x75, 0x72, 0x72, 0x78, 0x7E, 0xF6, 0xEB, 0xE3, 0xDC, 0xD6, +0xD2, 0xCF, 0xCE, 0xCE, 0xCD, 0xCF, 0xD2, 0xD4, 0xD7, 0xDA, 0xDD, 0xE3, 0xEF, 0x7A, 0x6C, 0x65, +0x5F, 0x5B, 0x57, 0x53, 0x4F, 0x4E, 0x4D, 0x4C, 0x4A, 0x4A, 0x4A, 0x4B, 0x4D, 0x4F, 0x53, 0x59, +0x5F, 0x6C, 0xFE, 0xEC, 0xE3, 0xDE, 0xDC, 0xDA, 0xD9, 0xD8, 0xD7, 0xD6, 0xD6, 0xD6, 0xD6, 0xD6, +0xD8, 0xDA, 0xDC, 0xDE, 0xE3, 0xEC, 0xFB, 0x6F, 0x63, 0x5B, 0x55, 0x4F, 0x4D, 0x4C, 0x4B, 0x4C, +0x4C, 0x4D, 0x4F, 0x53, 0x58, 0x5E, 0x67, 0x73, 0xFB, 0xEE, 0xE8, 0xE3, 0xDF, 0xDC, 0xDA, 0xD9, +0xD8, 0xD8, 0xD8, 0xD9, 0xDB, 0xDD, 0xDF, 0xE1, 0xE5, 0xE9, 0xEE, 0xF6, 0x7C, 0x6E, 0x66, 0x5F, +0x5C, 0x5A, 0x58, 0x56, 0x56, 0x57, 0x58, 0x5A, 0x5D, 0x60, 0x66, 0x6D, 0x74, 0x7C, 0xFB, 0xF4, +0xEE, 0xEA, 0xE7, 0xE5, 0xE4, 0xE4, 0xE4, 0xE7, 0xEA, 0xEC, 0xED, 0xED, 0xEC, 0xED, 0xEC, 0xED, +0xEE, 0xF1, 0xF9, 0x7F, 0x79, 0x75, 0x70, 0x6D, 0x6C, 0x6C, 0x6E, 0x73, 0x79, 0xFE, 0xF9, 0xF3, +0xEE, 0xEB, 0xE9, 0xE8, 0xE6, 0xE5, 0xE6, 0xE8, 0xEA, 0xED, 0xF1, 0xF8, 0xFD, 0x7E, 0x7E, 0xFE, +0xFC, 0xF9, 0xF5, 0xF5, 0xF6, 0xFB, 0x7C, 0x77, 0x71, 0x6E, 0x6C, 0x6A, 0x69, 0x69, 0x6B, 0x6E, +0x70, 0x75, 0x7A, 0xFE, 0xF6, 0xF1, 0xEE, 0xEC, 0xEB, 0xEB, 0xEC, 0xEE, 0xF1, 0xF5, 0xFB, 0x7D, +0x7B, 0x7A, 0x7C, 0xFE, 0xFA, 0xF4, 0xF1, 0xF0, 0xF0, 0xF3, 0xF7, 0xFB, 0xFD, 0xFF, 0xFF, 0x7F, +0x7F, 0xFE, 0xFE, 0xFE, 0xFF, 0x7F, 0xFD, 0xFC, 0xFA, 0xF5, 0xF4, 0xF1, 0xEF, 0xEF, 0xEF, 0xF0, +0xF4, 0xF8, 0xFD, 0x7D, 0x78, 0x77, 0x78, 0x7A, 0x7C, 0x7C, 0x7E, 0x7C, 0x7A, 0x79, 0x76, 0x77, +0x78, 0x77, 0x7B, 0x7E, 0xFF, 0xFD, 0xFD, 0xFE, 0xFF, 0xFF, 0x7F, 0x7F, 0xFF, 0x7E, 0xFE, 0xFB, +0xFA, 0xF9, 0xFA, 0xFB, 0xFE, 0x7F, 0x7C, 0x79, 0x78, 0x77, 0x77, 0x7A, 0x7C, 0x7D, 0x7E, 0x7B, +0x77, 0x74, 0x71, 0x6F, 0x6E, 0x6E, 0x6F, 0x6F, 0x70, 0x71, 0x73, 0x74, 0x76, 0x76, 0x75, 0x76, +0x77, 0x77, 0x77, 0x78, 0x78, 0x78, 0x77, 0x74, 0x72, 0x70, 0x6F, 0x6E, 0x6E, 0x6E, 0x70, 0x74, +0x78, 0x7B, 0x7D, 0x7D, 0x7C, 0x7C, 0x7A, 0x76, 0x72, 0x71, 0x70, 0x70, 0x70, 0x71, 0x72, 0x72, +0x74, 0x76, 0x78, 0x7B, 0x7F, 0xFE, 0xFC, 0xF9, 0xF6, 0xF5, 0xF7, 0xFC, 0xFF, 0x7C, 0x79, 0x78, +0x77, 0x77, 0x77, 0x7A, 0x7E, 0xFE, 0xFC, 0xFA, 0xF8, 0xF8, 0xFA, 0xFC, 0xFE, 0x7D, 0x7A, 0x76, +0x74, 0x74, 0x73, 0x75, 0x76, 0x76, 0x78, 0x7A, 0x7C, 0x7E, 0xFF, 0xFB, 0xF9, 0xF8, 0xF9, 0xFD, +0x7E, 0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x78, 0x7C, 0x7F, 0xFB, 0xF6, 0xF5, 0xF2, 0xF2, 0xF3, +0xF4, 0xF7, 0xF8, 0xFA, 0xFC, 0xFE, 0xFF, 0xFF, 0x7E, 0x7E, 0xFF, 0xFF, 0xFF, 0xFE, 0xFC, 0xFA, +0xF7, 0xF6, 0xF8, 0xFC, 0x7F, 0x7C, 0x79, 0x72, 0x6F, 0x6E, 0x6E, 0x6E, 0x6F, 0x73, 0x77, 0x77, +0x7B, 0x7D, 0x7E, 0x7F, 0x7E, 0x7C, 0x7A, 0x77, 0x75, 0x71, 0x6F, 0x6E, 0x6D, 0x6E, 0x6F, 0x70, +0x73, 0x74, 0x77, 0x79, 0x7C, 0x7D, 0x7D, 0x7D, 0x7B, 0x7A, 0x79, 0x76, 0x73, 0x70, 0x6F, 0x71, +0x73, 0x78, 0x7B, 0x7F, 0xFB, 0xF8, 0xF5, 0xF3, 0xF5, 0xF6, 0xF6, 0xF8, 0xF9, 0xFC, 0xFE, 0xFF, +0x7F, 0xFF, 0xFD, 0xFC, 0xFC, 0xFB, 0xF7, 0xF6, 0xF6, 0xF5, 0xF5, 0xF5, 0xF5, 0xF6, 0xF7, 0xF9, +0xFA, 0xFC, 0xFF, 0xFF, 0x7F, 0x7F, 0xFE, 0xFD, 0xFE, 0xFD, 0xFB, 0xFB, 0xFC, 0xFE, 0x7E, 0x7C, +0x7A, 0x79, 0x77, 0x76, 0x77, 0x77, 0x78, 0x78, 0x79, 0x7C, 0x7B, 0x7B, 0x7C, 0x7C, 0x7C, 0x7C, +0x7D, 0x7E, 0x7C, 0x7E, 0x7F, 0x7E, 0x7E, 0xFF, 0xFD, 0xFC, 0xFB, 0xF8, 0xF8, 0xFA, 0xFA, 0xFC, +0xFE, 0x7D, 0x78, 0x75, 0x72, 0x70, 0x70, 0x73, 0x75, 0x76, 0x78, 0x79, 0x79, 0x7A, 0x79, 0x78, +0x77, 0x76, 0x76, 0x76, 0x77, 0x77, 0x77, 0x77, 0x79, 0x7A, 0x7B, 0x7D, 0x7F, 0xFC, 0xF8, 0xF6, +0xF4, 0xF2, 0xF3, 0xF7, 0xF9, 0xFB, 0x7E, 0x78, 0x75, 0x73, 0x73, 0x73, 0x73, 0x73, 0x73, 0x74, +0x75, 0x77, 0x77, 0x78, 0x78, 0x78, 0x79, 0x78, 0x78, 0x78, 0x77, 0x75, 0x75, 0x76, 0x79, 0x7B, +0x7C, 0x7E, 0xFE, 0xFC, 0xF9, 0xF6, 0xF5, 0xF6, 0xF7, 0xF9, 0xFC, 0xFE, 0x7C, 0x79, 0x77, 0x76, +0x75, 0x74, 0x74, 0x75, 0x74, 0x76, 0x77, 0x78, 0x79, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x78, 0x78, +0x77, 0x76, 0x77, 0x77, 0x77, 0x78, 0x7A, 0x7C, 0xFF, 0xFD, 0xFA, 0xF8, 0xF6, 0xF7, 0xF8, 0xF7, +0xF8, 0xF8, 0xF8, 0xF9, 0xFA, 0xF9, 0xF9, 0xFA, 0xFB, 0xFB, 0xFB, 0xFD, 0xFD, 0xFC, 0xFD, 0xFE, +0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7B, 0x7A, 0x79, 0x79, 0x79, 0x78, 0x79, 0x7B, 0x7C, 0x7C, 0x7C, +0x7C, 0x7B, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x75, 0x74, 0x73, 0x71, 0x70, 0x6F, 0x6F, 0x6E, +0x6D, 0x6C, 0x6C, 0x6D, 0x6E, 0x6E, 0x6E, 0x6F, 0x6E, 0x6F, 0x70, 0x70, 0x72, 0x75, 0x78, 0x7B, +0x7B, 0x7C, 0x7D, 0xFF, 0xFD, 0xFC, 0xFA, 0xFA, 0xF9, 0xF7, 0xF7, 0xF7, 0xF7, 0xF8, 0xF8, 0xF9, +0xFA, 0xFA, 0xFA, 0xF9, 0xF9, 0xFA, 0xFA, 0xFA, 0xFA, 0xFB, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFB, +0xFB, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFC, 0xFD, 0xFF, 0x7F, 0xFC, 0xFA, 0xFB, 0xFA, 0xFA, 0xF9, +0xFA, 0xFC, 0xFC, 0xFE, 0xFF, 0xFE, 0xFF, 0xFE, 0xFE, 0xFD, 0xFC, 0xFD, 0xFA, 0xFA, 0xF9, 0xF8, +0xFA, 0xF8, 0xFA, 0xFA, 0xFB, 0xFE, 0xFB, 0xFF, 0xFD, 0xFD, 0xFF, 0xFB, 0xFF, 0xFA, 0xFC, 0x7F, +0xFC, 0x70, 0x6A, 0x64, 0x61, 0x67, 0x6C, 0x73, 0x61, 0x60, 0x5A, 0x47, 0x53, 0xDF, 0x7D, 0x6F, +0x71, 0x69, 0x7F, 0x72, 0x70, 0x68, 0x5A, 0x5B, 0x59, 0x55, 0x5A, 0x5D, 0x4E, 0x46, 0x51, 0x77, +0xF6, 0xEC, 0xE8, 0xE6, 0xE5, 0xE4, 0xE1, 0xE5, 0xFD, 0x60, 0x65, 0xE6, 0xDB, 0xDD, 0xE1, 0xE4, +0xE2, 0xDC, 0xD4, 0xCF, 0xCF, 0xCF, 0xD1, 0xD2, 0xCF, 0xCD, 0xCC, 0xCD, 0xD0, 0xD4, 0xD7, 0xD5, +0xCE, 0xCD, 0xD3, 0xD9, 0xDB, 0xDA, 0xD9, 0xDC, 0xE2, 0xE5, 0xF1, 0xEE, 0xD7, 0xD2, 0xD9, 0xDC, +0xDD, 0xD9, 0xDC, 0xE7, 0xDF, 0xD9, 0xDD, 0x74, 0x62, 0xFC, 0xE9, 0xF2, 0x6C, 0x5D, 0x5D, 0x61, +0x6B, 0x6C, 0x5C, 0x5D, 0x70, 0x64, 0x5B, 0x6D, 0x78, 0x61, 0x57, 0x58, 0x65, 0x62, 0x53, 0x51, +0x69, 0xF5, 0x59, 0x53, 0x69, 0x68, 0x54, 0x4F, 0x67, 0xFA, 0x5B, 0x58, 0x5D, 0x60, 0x5D, 0x4E, +0x53, 0x61, 0x5A, 0x5F, 0x63, 0x61, 0x5E, 0x4C, 0x4C, 0x5A, 0x6B, 0xF7, 0x58, 0x47, 0x51, 0x6D, +0x68, 0x5A, 0x55, 0x53, 0x4A, 0x4E, 0xEE, 0xE1, 0x56, 0x46, 0x4D, 0x74, 0x70, 0x59, 0x53, 0x4C, +0x4E, 0x62, 0xF2, 0xF3, 0x5A, 0x4A, 0x4F, 0x6D, 0x6B, 0x57, 0x63, 0xED, 0x79, 0x69, 0x62, 0x5D, +0x6C, 0x67, 0x5E, 0xF5, 0xEA, 0x69, 0x63, 0x76, 0xFA, 0x6A, 0x59, 0x5D, 0xFB, 0xF6, 0x72, 0xFB, +0x71, 0x5D, 0x65, 0x7D, 0xFC, 0x79, 0xFB, 0xE9, 0xE2, 0xDD, 0xE3, 0xF9, 0xFA, 0xF3, 0xEA, 0xEC, +0x7D, 0xF1, 0xE5, 0xF2, 0x78, 0x6D, 0x6D, 0xED, 0xE4, 0xE5, 0xE4, 0xF6, 0x7A, 0xF8, 0xE5, 0xDC, +0xEA, 0xDF, 0xCF, 0xD3, 0xE7, 0x6C, 0x78, 0xCF, 0xC9, 0xD5, 0x7E, 0x64, 0x7E, 0xD7, 0xCF, 0xD7, +0xE0, 0xE8, 0xDC, 0xCB, 0xC5, 0xCC, 0xE6, 0x73, 0xE9, 0xD2, 0xC9, 0xCA, 0xD3, 0xED, 0x68, 0xF3, +0xD9, 0xDA, 0xDC, 0xDA, 0xD7, 0xDB, 0xE1, 0xE1, 0xEA, 0x69, 0x59, 0x60, 0xEE, 0xE0, 0xDC, 0xDF, +0xE5, 0xDD, 0xE1, 0xED, 0xED, 0xF4, 0xF6, 0xF2, 0xEE, 0xED, 0xFC, 0x6F, 0x64, 0x5C, 0x5C, 0x61, +0x76, 0xEA, 0xE1, 0xEB, 0x73, 0x66, 0x60, 0x69, 0xFB, 0x7E, 0x70, 0x76, 0xFF, 0x78, 0x73, 0xEB, +0xE2, 0x6F, 0x5C, 0x69, 0xE9, 0xDB, 0xDE, 0x73, 0x5E, 0x6D, 0xED, 0xEB, 0xF4, 0xFF, 0x77, 0xFD, +0xE7, 0xE2, 0xFB, 0x66, 0x69, 0xFE, 0xFA, 0x6B, 0x63, 0x69, 0x74, 0x74, 0x66, 0x63, 0x6F, 0xFB, +0xFD, 0x73, 0x71, 0x7B, 0xF4, 0xE8, 0xE2, 0xE8, 0xF2, 0xEB, 0xDE, 0xDC, 0xDE, 0xE2, 0xE7, 0xE5, +0xDF, 0xDF, 0xE8, 0xFC, 0x6D, 0x6A, 0x66, 0x5C, 0x53, 0x51, 0x56, 0x5B, 0x59, 0x56, 0x56, 0x5A, +0x5E, 0x5A, 0x53, 0x53, 0x59, 0x5D, 0x5F, 0x64, 0x74, 0xE9, 0xD6, 0xCB, 0xCB, 0xD3, 0xDC, 0xD4, +0xC8, 0xC1, 0xBF, 0xBE, 0xBE, 0xC5, 0xCE, 0xDC, 0xEA, 0x68, 0x4B, 0x3E, 0x3B, 0x3B, 0x3D, 0x3E, +0x41, 0x45, 0x47, 0x48, 0x4A, 0x4C, 0x4A, 0x47, 0x49, 0x4F, 0x5E, 0x6D, 0xF5, 0xDB, 0xCC, 0xC5, +0xC1, 0xBF, 0xBE, 0xBC, 0xBA, 0xB7, 0xB2, 0xAF, 0xAE, 0xB7, 0xDA, 0x43, 0x38, 0x35, 0x32, 0x31, +0x33, 0x3A, 0x46, 0x54, 0x5D, 0x56, 0x4A, 0x44, 0x43, 0x46, 0x44, 0x3F, 0x40, 0x4B, 0x61, 0x7B, +0xFD, 0xE7, 0xD4, 0xCA, 0xC5, 0xBF, 0xBB, 0xB6, 0xB1, 0xAF, 0xAD, 0xAC, 0xAC, 0xB4, 0xD8, 0x3C, +0x2D, 0x2B, 0x2D, 0x2F, 0x37, 0x41, 0x54, 0x76, 0xFF, 0x68, 0x54, 0x46, 0x40, 0x44, 0x49, 0x4A, +0x49, 0x4C, 0x5C, 0xFB, 0xE9, 0xE5, 0xDB, 0xCE, 0xC8, 0xC3, 0xBE, 0xBA, 0xB6, 0xB1, 0xAE, 0xAB, +0xA9, 0xAB, 0xBD, 0x3F, 0x2A, 0x26, 0x2A, 0x31, 0x3A, 0x43, 0x58, 0xE9, 0xDB, 0xE8, 0x5E, 0x46, +0x3C, 0x3D, 0x48, 0x55, 0x56, 0x55, 0x61, 0xF3, 0xE8, 0xE6, 0xDC, 0xCF, 0xC9, 0xC0, 0xB9, 0xB4, +0xB3, 0xB3, 0xAF, 0xAA, 0xA8, 0xAF, 0x75, 0x2C, 0x22, 0x24, 0x2D, 0x3F, 0x56, 0x72, 0xE0, 0xCF, +0xD4, 0x59, 0x3F, 0x38, 0x38, 0x3E, 0x4C, 0x68, 0xE8, 0xE3, 0xEA, 0x7E, 0x67, 0x64, 0x79, 0xDC, +0xCB, 0xBF, 0xB7, 0xB1, 0xAF, 0xAE, 0xAC, 0xAA, 0xB1, 0x56, 0x29, 0x1F, 0x20, 0x2B, 0x45, 0xD1, +0xC4, 0xC7, 0xCB, 0xD8, 0x4B, 0x33, 0x2E, 0x34, 0x42, 0x6D, 0xCD, 0xC5, 0xC8, 0xD1, 0xE0, 0x69, +0x52, 0x52, 0x6D, 0xD4, 0xC6, 0xBB, 0xB1, 0xAC, 0xAB, 0xAA, 0xA8, 0xAE, 0x68, 0x28, 0x1D, 0x1E, +0x2B, 0x53, 0xBC, 0xB6, 0xBD, 0xCA, 0xE1, 0x4E, 0x33, 0x2A, 0x2C, 0x3B, 0x7D, 0xBF, 0xBB, 0xC1, +0xD5, 0xED, 0x6A, 0x4F, 0x4C, 0x58, 0x7E, 0xD6, 0xC7, 0xBB, 0xB2, 0xAD, 0xA9, 0xA6, 0xA9, 0xC3, +0x2D, 0x1D, 0x1B, 0x23, 0x41, 0xBC, 0xAF, 0xB5, 0xC2, 0xDE, 0x4F, 0x3B, 0x2D, 0x27, 0x2D, 0x49, +0xC3, 0xB5, 0xB9, 0xCB, 0x64, 0x54, 0x56, 0x51, 0x58, 0x75, 0xE3, 0xD1, 0xCA, 0xC1, 0xB6, 0xAB, +0xA6, 0xA3, 0xA6, 0xC0, 0x2B, 0x1C, 0x1A, 0x24, 0x4D, 0xB0, 0xAA, 0xB0, 0xC3, 0xF0, 0x46, 0x38, +0x2D, 0x28, 0x2B, 0x4C, 0xBC, 0xB2, 0xB6, 0xD1, 0x4B, 0x46, 0x4F, 0x58, 0x61, 0xEE, 0xE1, 0xDB, +0xCF, 0xCB, 0xBD, 0xAE, 0xA7, 0xA3, 0xA2, 0xB6, 0x2C, 0x1B, 0x19, 0x21, 0x52, 0xAB, 0xA5, 0xAE, +0xC9, 0x4F, 0x3B, 0x37, 0x32, 0x2A, 0x2A, 0x3D, 0xC9, 0xB2, 0xB1, 0xCA, 0x44, 0x3D, 0x49, 0x5F, +0xDD, 0xD8, 0x77, 0x6E, 0xED, 0xDB, 0xC7, 0xB7, 0xAB, 0xA5, 0xA3, 0xA6, 0xC8, 0x26, 0x1A, 0x1A, +0x27, 0xC5, 0xA4, 0xA3, 0xAF, 0xE9, 0x3B, 0x33, 0x34, 0x31, 0x2D, 0x31, 0x57, 0xBF, 0xB3, 0xBA, +0x78, 0x41, 0x3E, 0x4E, 0xDC, 0xCE, 0xD4, 0x78, 0x5B, 0x67, 0xDC, 0xC4, 0xB7, 0xAC, 0xA6, 0xA5, +0xA5, 0xBA, 0x2C, 0x1B, 0x19, 0x23, 0xD8, 0xA3, 0x9F, 0xAB, 0xDA, 0x34, 0x2D, 0x30, 0x33, 0x33, +0x37, 0x54, 0xC1, 0xB7, 0xBD, 0x6E, 0x41, 0x3D, 0x4A, 0xD8, 0xCA, 0xD0, 0xEB, 0x56, 0x54, 0x74, +0xCE, 0xBD, 0xAF, 0xA8, 0xA6, 0xA5, 0xAE, 0x3B, 0x1E, 0x19, 0x1E, 0x43, 0xA8, 0x9E, 0xA6, 0xC8, +0x33, 0x29, 0x2C, 0x32, 0x39, 0x3D, 0x4E, 0xCD, 0xBE, 0xC2, 0xFF, 0x40, 0x3D, 0x48, 0xE0, 0xC4, +0xCB, 0xEA, 0x4F, 0x48, 0x59, 0xD7, 0xBE, 0xB5, 0xAD, 0xA9, 0xA9, 0xA7, 0xB3, 0x34, 0x1D, 0x19, +0x20, 0xEE, 0xA2, 0x9D, 0xA8, 0x60, 0x2A, 0x26, 0x2D, 0x3B, 0x4A, 0x4E, 0x64, 0xCE, 0xC6, 0xCF, +0x57, 0x42, 0x47, 0x67, 0xCB, 0xC3, 0xD4, 0x5C, 0x48, 0x47, 0x63, 0xCA, 0xBA, 0xB2, 0xAE, 0xAC, +0xAC, 0xAB, 0xB3, 0x3D, 0x1F, 0x1B, 0x20, 0x51, 0xA5, 0x9E, 0xA8, 0x6C, 0x2A, 0x24, 0x2B, 0x3E, +0x5E, 0x6C, 0x66, 0xFA, 0xE0, 0xE4, 0x60, 0x4B, 0x4E, 0x71, 0xD2, 0xC8, 0xD8, 0x5A, 0x4A, 0x49, +0x6E, 0xC6, 0xB9, 0xB3, 0xB1, 0xAF, 0xAE, 0xAC, 0xAF, 0x48, 0x21, 0x1B, 0x1F, 0x4C, 0xA5, 0x9D, +0xA7, 0x64, 0x28, 0x23, 0x2C, 0x4A, 0xD6, 0xD9, 0x61, 0x59, 0x6C, 0xEF, 0xF8, 0x5B, 0x5B, 0xEE, +0xD5, 0xCD, 0xDB, 0x5C, 0x4D, 0x4C, 0x6E, 0xC8, 0xBB, 0xB8, 0xB8, 0xB6, 0xB3, 0xAD, 0xA8, 0xBC, +0x2D, 0x1D, 0x1B, 0x2B, 0xB7, 0x9F, 0xA1, 0xB9, 0x33, 0x23, 0x28, 0x3A, 0xEB, 0xCF, 0x77, 0x50, +0x56, 0x6E, 0xE2, 0x73, 0x55, 0x5D, 0xE6, 0xCF, 0xD9, 0x5B, 0x4B, 0x47, 0x59, 0xD2, 0xC3, 0xBD, +0xBD, 0xBC, 0xB6, 0xAE, 0xA9, 0xAB, 0x68, 0x24, 0x1B, 0x1E, 0x3C, 0xAA, 0x9E, 0xA6, 0xDE, 0x2A, +0x23, 0x2C, 0x47, 0xD1, 0xCE, 0x72, 0x55, 0x58, 0x6A, 0x78, 0x5D, 0x5B, 0xF9, 0xDA, 0xD3, 0xDE, +0x5A, 0x49, 0x4A, 0x5F, 0xD1, 0xC0, 0xBD, 0xBC, 0xB9, 0xB3, 0xAD, 0xA9, 0xB1, 0x3C, 0x1F, 0x1C, +0x24, 0xE1, 0xA4, 0x9F, 0xAD, 0x44, 0x26, 0x25, 0x32, 0x6E, 0xC3, 0xCD, 0x64, 0x4F, 0x4F, 0x62, +0x70, 0x5C, 0x68, 0xE1, 0xD4, 0xD3, 0xF6, 0x4E, 0x45, 0x4B, 0x78, 0xCA, 0xBE, 0xBC, 0xBC, 0xB8, +0xB3, 0xAC, 0xA9, 0xBC, 0x2F, 0x1E, 0x1C, 0x2A, 0xBC, 0xA0, 0xA1, 0xB7, 0x35, 0x24, 0x28, 0x3B, +0xD8, 0xC4, 0xDC, 0x53, 0x4B, 0x4F, 0x67, 0x6D, 0x65, 0xEA, 0xDB, 0xD5, 0xDA, 0x5E, 0x4B, 0x48, +0x53, 0xDB, 0xC4, 0xBD, 0xBD, 0xBB, 0xB5, 0xAE, 0xA8, 0xAB, 0x75, 0x25, 0x1B, 0x1E, 0x3D, 0xAA, +0x9E, 0xA6, 0xDC, 0x2B, 0x25, 0x2E, 0x4E, 0xCC, 0xCC, 0x66, 0x4B, 0x4C, 0x5A, 0x74, 0x6C, 0x6D, +0xDF, 0xD6, 0xD6, 0xED, 0x4D, 0x43, 0x46, 0x59, 0xD0, 0xBF, 0xBC, 0xBB, 0xB8, 0xB3, 0xAD, 0xA9, +0xB3, 0x38, 0x1E, 0x1B, 0x24, 0xCF, 0xA2, 0x9F, 0xAF, 0x3E, 0x26, 0x27, 0x36, 0x6A, 0xCD, 0xE6, +0x4F, 0x4D, 0x55, 0x6E, 0xEF, 0x63, 0x7B, 0xDA, 0xDB, 0xDF, 0x5F, 0x49, 0x47, 0x4F, 0xE8, 0xC5, +0xBD, 0xBC, 0xBB, 0xB6, 0xAF, 0xAA, 0xAA, 0xCD, 0x29, 0x1C, 0x1D, 0x34, 0xAE, 0x9F, 0xA4, 0xC7, +0x2E, 0x25, 0x2C, 0x41, 0xDB, 0xD2, 0x75, 0x5B, 0x59, 0x60, 0x6E, 0x5B, 0x5C, 0xDF, 0xD0, 0xD8, +0x74, 0x4B, 0x43, 0x4B, 0x6E, 0xCC, 0xBF, 0xBD, 0xBE, 0xBC, 0xB5, 0xAD, 0xA8, 0xAD, 0x4B, 0x22, +0x1C, 0x22, 0x65, 0xA6, 0x9F, 0xAC, 0x4C, 0x2A, 0x28, 0x33, 0x50, 0xDE, 0xF2, 0x65, 0x7C, 0xF8, +0x79, 0x5A, 0x4B, 0x5E, 0xD7, 0xCF, 0xD6, 0x5F, 0x45, 0x43, 0x4C, 0xFB, 0xC9, 0xBF, 0xBD, 0xBC, +0xB8, 0xB2, 0xAD, 0xAA, 0xB7, 0x38, 0x20, 0x1D, 0x29, 0xC6, 0xA5, 0xA4, 0xB8, 0x3C, 0x2A, 0x2C, +0x39, 0x53, 0x7F, 0x6F, 0x79, 0xE8, 0xF9, 0x61, 0x4D, 0x4B, 0xFF, 0xD0, 0xD3, 0xEC, 0x4F, 0x45, +0x49, 0x58, 0xDF, 0xC7, 0xBF, 0xBD, 0xBB, 0xB5, 0xAF, 0xA9, 0xAA, 0xCA, 0x2C, 0x1D, 0x1E, 0x36, +0xB1, 0xA2, 0xA8, 0xCE, 0x33, 0x2B, 0x30, 0x3E, 0x4F, 0x5A, 0x6D, 0xD8, 0xD2, 0xF5, 0x4F, 0x46, +0x54, 0xD4, 0xCA, 0xD7, 0x65, 0x48, 0x43, 0x4C, 0x61, 0xD7, 0xC4, 0xBF, 0xBD, 0xB7, 0xB1, 0xAD, +0xAA, 0xB0, 0x48, 0x23, 0x1D, 0x24, 0x5D, 0xAA, 0xA4, 0xB0, 0x56, 0x30, 0x2E, 0x34, 0x3E, 0x47, +0x52, 0xE3, 0xC9, 0xCE, 0x65, 0x45, 0x43, 0x6A, 0xCE, 0xCD, 0xDE, 0x58, 0x49, 0x49, 0x4F, 0x6D, +0xD1, 0xC0, 0xBB, 0xB6, 0xAF, 0xAE, 0xAA, 0xAB, 0xCF, 0x2B, 0x1D, 0x1E, 0x36, 0xB2, 0xA4, 0xA9, +0xC7, 0x3B, 0x2F, 0x31, 0x37, 0x3D, 0x46, 0x6E, 0xC7, 0xC5, 0xE5, 0x4C, 0x41, 0x50, 0xD5, 0xCB, +0xDF, 0x58, 0x4C, 0x49, 0x4E, 0x62, 0xE4, 0xC8, 0xBD, 0xB9, 0xB4, 0xAF, 0xAD, 0xA9, 0xB2, 0x41, +0x22, 0x1D, 0x26, 0xEB, 0xAA, 0xA6, 0xB3, 0x5D, 0x38, 0x32, 0x32, 0x34, 0x39, 0x4D, 0xCC, 0xBD, +0xC7, 0x60, 0x44, 0x47, 0x6D, 0xDC, 0xE2, 0xEF, 0x63, 0x58, 0x50, 0x4D, 0x5A, 0xDB, 0xC3, 0xBA, +0xB3, 0xAF, 0xAD, 0xAC, 0xAE, 0xD3, 0x2D, 0x1F, 0x20, 0x38, 0xB9, 0xA9, 0xAD, 0xC4, 0x4C, 0x39, +0x33, 0x30, 0x32, 0x3C, 0xFA, 0xBE, 0xBE, 0xD5, 0x51, 0x46, 0x4F, 0x6F, 0x7B, 0x65, 0x68, 0x76, +0x60, 0x54, 0x52, 0x61, 0xCF, 0xBF, 0xB7, 0xAE, 0xAC, 0xAB, 0xAB, 0xBC, 0x39, 0x22, 0x1E, 0x2B, +0xE7, 0xAF, 0xAC, 0xB6, 0xD1, 0x4E, 0x3A, 0x2F, 0x2D, 0x31, 0x45, 0xCC, 0xBC, 0xC2, 0xDA, 0x58, +0x4D, 0x55, 0x52, 0x52, 0x68, 0xED, 0xF4, 0x66, 0x55, 0x59, 0xEF, 0xCE, 0xBF, 0xB5, 0xAD, 0xAB, +0xAB, 0xAE, 0xCC, 0x31, 0x22, 0x22, 0x2F, 0xE8, 0xB6, 0xB1, 0xB8, 0xC4, 0x73, 0x3D, 0x2F, 0x2B, +0x2F, 0x3F, 0xDD, 0xC0, 0xBF, 0xC7, 0xD8, 0x73, 0x55, 0x46, 0x44, 0x53, 0x7B, 0xEE, 0xED, 0xF2, +0xED, 0xDC, 0xCF, 0xC1, 0xB3, 0xAC, 0xA9, 0xA9, 0xB2, 0x58, 0x2C, 0x24, 0x28, 0x36, 0x5C, 0xC7, +0xBA, 0xB6, 0xB7, 0xCA, 0x49, 0x34, 0x2D, 0x2E, 0x37, 0x49, 0xE0, 0xC4, 0xBD, 0xBE, 0xC7, 0xEA, +0x4C, 0x42, 0x44, 0x49, 0x50, 0x69, 0xDD, 0xD0, 0xCB, 0xC6, 0xBD, 0xB3, 0xAD, 0xAB, 0xAB, 0xBA, +0x49, 0x2F, 0x2B, 0x2D, 0x32, 0x3A, 0x4B, 0xD6, 0xBC, 0xB6, 0xBD, 0xD7, 0x51, 0x3D, 0x36, 0x34, +0x37, 0x3E, 0x52, 0xDE, 0xC8, 0xC3, 0xC7, 0xCE, 0xDE, 0x72, 0x56, 0x4F, 0x53, 0x5D, 0xFF, 0xDA, +0xC9, 0xBD, 0xB7, 0xB4, 0xB2, 0xB6, 0xC6, 0x62, 0x47, 0x3F, 0x3D, 0x3B, 0x3B, 0x40, 0x4E, 0x6F, +0xEC, 0x7B, 0x67, 0x5E, 0x5B, 0x59, 0x55, 0x5A, 0x65, 0x5E, 0x5A, 0x5F, 0x61, 0x5E, 0x63, 0x65, +0x61, 0x6D, 0xF5, 0xFA, 0x7A, 0x77, 0x77, 0xFF, 0xEB, 0xDC, 0xD5, 0xCE, 0xCA, 0xC8, 0xC8, 0xCD, +0xD9, 0xEC, 0x76, 0x70, 0xFD, 0xED, 0xEA, 0xEE, 0x7D, 0x66, 0x59, 0x53, 0x50, 0x4F, 0x50, 0x54, +0x56, 0x58, 0x59, 0x5A, 0x5A, 0x5C, 0x5F, 0x6B, 0xF6, 0xE5, 0xE1, 0xE7, 0xEF, 0xF5, 0xF2, 0xEA, +0xDF, 0xD8, 0xCE, 0xC8, 0xC4, 0xC5, 0xCB, 0xD4, 0xDF, 0xE9, 0xE7, 0xE1, 0xDD, 0xDB, 0xDE, 0xEE, +0x68, 0x57, 0x4F, 0x4D, 0x4D, 0x4E, 0x4F, 0x4F, 0x52, 0x54, 0x53, 0x51, 0x53, 0x57, 0x5E, 0x6F, +0xFA, 0xEF, 0xEF, 0xF3, 0xF1, 0xF1, 0xEE, 0xE6, 0xDE, 0xD6, 0xCF, 0xCD, 0xCE, 0xD3, 0xDA, 0xDC, +0xDF, 0xDF, 0xD9, 0xD5, 0xD4, 0xD7, 0xE0, 0xFE, 0x6B, 0x5F, 0x5A, 0x58, 0x56, 0x54, 0x54, 0x53, +0x53, 0x50, 0x4E, 0x4F, 0x52, 0x56, 0x5C, 0x64, 0x67, 0x66, 0x69, 0x6C, 0x6D, 0x74, 0xFA, 0xEC, +0xDF, 0xD7, 0xD6, 0xDD, 0xE6, 0xF3, 0x7B, 0xF7, 0xE8, 0xDC, 0xD3, 0xD0, 0xD2, 0xD9, 0xE1, 0xE7, +0xEB, 0xF6, 0x7B, 0x74, 0x6F, 0x6B, 0x66, 0x5E, 0x59, 0x55, 0x53, 0x52, 0x56, 0x59, 0x5C, 0x61, +0x5F, 0x64, 0x65, 0x62, 0x6F, 0x7B, 0xFC, 0xE4, 0xDC, 0xD9, 0xE2, 0x7E, 0xFF, 0xFE, 0xFF, 0xEE, +0xDF, 0xD8, 0xD6, 0xD7, 0xDB, 0xDD, 0xDD, 0xE8, 0xE7, 0xE3, 0xEA, 0xE7, 0xF9, 0x72, 0x7C, 0x5F, +0x56, 0x58, 0x58, 0x56, 0x57, 0x57, 0x53, 0x54, 0x4A, 0x42, 0x4F, 0x67, 0x6A, 0xE0, 0xD4, 0xD8, +0xD7, 0xDD, 0xFD, 0xFE, 0xE4, 0x7B, 0xFF, 0xD9, 0xDF, 0xDE, 0xD7, 0xDA, 0xCF, 0xCF, 0xD3, 0xCD, +0xD3, 0xDF, 0xDD, 0xDE, 0xF3, 0x6D, 0x5F, 0x55, 0x54, 0x55, 0x51, 0x51, 0x50, 0x4F, 0x51, 0x53, +0x57, 0x59, 0x60, 0x73, 0xFB, 0xE7, 0xE1, 0xEA, 0xF4, 0x7D, 0x6D, 0x6F, 0x7F, 0x78, 0xF5, 0xE7, +0xEA, 0xE0, 0xDE, 0xD9, 0xCD, 0xCB, 0xC5, 0xC2, 0xC5, 0xCB, 0xDB, 0xDD, 0xEC, 0x53, 0x4C, 0x45, +0x42, 0x49, 0x48, 0x49, 0x4D, 0x51, 0x5A, 0x55, 0x55, 0x5D, 0x64, 0xF4, 0xED, 0xF5, 0xEB, 0xF2, +0x7A, 0x6D, 0x60, 0x5E, 0x6E, 0xF3, 0xF7, 0xE9, 0xDF, 0xDD, 0xD4, 0xCD, 0xC8, 0xC1, 0xBC, 0xB8, +0xB5, 0xB8, 0xC7, 0xF5, 0x52, 0x3E, 0x38, 0x37, 0x36, 0x3D, 0x4B, 0x59, 0xFD, 0xDF, 0xE3, 0xFE, +0x5C, 0x54, 0x52, 0x4E, 0x50, 0x55, 0x5D, 0xFF, 0xF2, 0xF1, 0xE9, 0xFB, 0xFD, 0x74, 0x5E, 0x62, +0x7A, 0xE3, 0xD2, 0xCA, 0xC0, 0xB9, 0xB1, 0xAD, 0xAE, 0xBC, 0x68, 0x3E, 0x31, 0x2D, 0x2E, 0x30, +0x3B, 0x5B, 0xD4, 0xC7, 0xC9, 0xD6, 0x65, 0x4A, 0x46, 0x3E, 0x3D, 0x47, 0x51, 0x7F, 0xD5, 0xD0, +0xCE, 0xD2, 0xE2, 0x6E, 0x57, 0x55, 0x61, 0xEA, 0xCD, 0xBE, 0xB7, 0xB2, 0xAD, 0xAB, 0xB0, 0xCE, +0x40, 0x2F, 0x2B, 0x2D, 0x2F, 0x38, 0x59, 0xCA, 0xBD, 0xBE, 0xCF, 0x70, 0x45, 0x39, 0x3A, 0x3B, +0x3F, 0x5D, 0xD9, 0xCB, 0xC4, 0xC5, 0xCF, 0xEA, 0x62, 0x52, 0x50, 0x5C, 0x7E, 0xD1, 0xBE, 0xB5, +0xAF, 0xAE, 0xAB, 0xAC, 0xC2, 0x44, 0x2F, 0x2A, 0x2D, 0x32, 0x38, 0x55, 0xC6, 0xBA, 0xBC, 0xCF, +0x5B, 0x40, 0x36, 0x34, 0x38, 0x40, 0x66, 0xCD, 0xC4, 0xC2, 0xC6, 0xD1, 0xFE, 0x52, 0x4C, 0x4F, +0x5C, 0xEF, 0xCF, 0xC1, 0xB7, 0xAF, 0xAD, 0xAB, 0xAD, 0xC9, 0x3C, 0x2D, 0x29, 0x2D, 0x35, 0x3D, +0xF1, 0xBD, 0xB8, 0xBF, 0xE1, 0x4C, 0x3C, 0x32, 0x31, 0x39, 0x47, 0xF7, 0xCB, 0xC4, 0xC2, 0xC7, +0xD9, 0x6F, 0x54, 0x4D, 0x4F, 0x5D, 0xEF, 0xCF, 0xC1, 0xB8, 0xAF, 0xAD, 0xAB, 0xAC, 0xC9, 0x3A, +0x2C, 0x29, 0x2D, 0x37, 0x44, 0xD8, 0xB9, 0xB7, 0xC4, 0x6C, 0x44, 0x38, 0x31, 0x30, 0x39, 0x4E, +0xDF, 0xCA, 0xC5, 0xC6, 0xCD, 0xEF, 0x5E, 0x5A, 0x53, 0x55, 0x64, 0xE8, 0xCD, 0xC4, 0xBB, 0xB0, +0xAC, 0xAA, 0xAC, 0xD0, 0x36, 0x2C, 0x2B, 0x2E, 0x39, 0x4A, 0xCB, 0xB6, 0xB7, 0xC8, 0x5D, 0x43, +0x39, 0x31, 0x32, 0x3D, 0x58, 0xD9, 0xCD, 0xCA, 0xC9, 0xD6, 0x73, 0x62, 0x63, 0x62, 0x68, 0x72, +0xE9, 0xCE, 0xC6, 0xBB, 0xAF, 0xAD, 0xAB, 0xAE, 0xD7, 0x38, 0x2D, 0x2C, 0x2F, 0x3B, 0x4F, 0xCA, +0xB6, 0xB8, 0xCB, 0x5D, 0x41, 0x39, 0x32, 0x33, 0x3E, 0x59, 0xDC, 0xCF, 0xCD, 0xCB, 0xD8, 0x63, +0x53, 0x5A, 0x5E, 0x61, 0x6F, 0xEA, 0xCF, 0xC6, 0xBC, 0xB0, 0xAD, 0xAB, 0xAE, 0xEE, 0x32, 0x2C, +0x2C, 0x30, 0x3B, 0x50, 0xC9, 0xB6, 0xB9, 0xCF, 0x5D, 0x47, 0x3A, 0x32, 0x33, 0x3F, 0x63, 0xDB, +0xD5, 0xCC, 0xC8, 0xD7, 0x66, 0x56, 0x58, 0x5C, 0x5A, 0x5B, 0x7E, 0xCE, 0xC4, 0xBB, 0xB0, 0xAD, +0xAB, 0xAF, 0x7B, 0x2F, 0x2C, 0x2E, 0x31, 0x39, 0x52, 0xC6, 0xB6, 0xBA, 0xD1, 0x5C, 0x4E, 0x3E, +0x32, 0x33, 0x3F, 0x64, 0xEA, 0xFD, 0xCE, 0xC2, 0xD0, 0x6C, 0x57, 0x5D, 0x64, 0x56, 0x53, 0x6C, +0xCE, 0xC4, 0xBD, 0xB1, 0xAD, 0xAA, 0xAE, 0x6F, 0x31, 0x2F, 0x31, 0x31, 0x37, 0x4F, 0xC5, 0xB6, +0xBA, 0xD2, 0xFC, 0x60, 0x45, 0x36, 0x35, 0x41, 0x56, 0xF8, 0xF2, 0xE4, 0xC6, 0xC8, 0x7C, 0x5A, +0x6A, 0x6A, 0x57, 0x52, 0x5B, 0xDA, 0xC6, 0xC0, 0xB6, 0xAE, 0xAA, 0xAC, 0xDD, 0x33, 0x30, 0x35, +0x31, 0x30, 0x42, 0xCE, 0xBA, 0xBA, 0xCC, 0xD9, 0xD9, 0x53, 0x3A, 0x35, 0x3E, 0x4D, 0x52, 0x60, +0xD6, 0xC5, 0xD2, 0x71, 0xE7, 0x7C, 0x55, 0x53, 0x51, 0x5B, 0xEE, 0xDC, 0xD3, 0xBE, 0xB2, 0xB0, +0xAD, 0xAE, 0x67, 0x31, 0x38, 0x39, 0x2F, 0x32, 0x49, 0xD5, 0xBE, 0xBF, 0xCF, 0xCD, 0xCA, 0x5C, +0x3D, 0x3C, 0x41, 0x41, 0x47, 0x5D, 0xE1, 0xC9, 0xC7, 0xD4, 0xDD, 0xFC, 0x51, 0x4C, 0x4C, 0x4C, +0x5F, 0xE2, 0xDC, 0xCA, 0xBF, 0xBD, 0xB9, 0xB5, 0xAF, 0xBA, 0x43, 0x35, 0x44, 0x3E, 0x2F, 0x36, +0x53, 0xD4, 0xC8, 0xCC, 0xD1, 0xC3, 0xC5, 0x5E, 0x41, 0x45, 0x49, 0x42, 0x44, 0x55, 0xE9, 0xD0, +0xD1, 0xDA, 0xD6, 0xD7, 0xFD, 0x5A, 0x58, 0x5B, 0x5A, 0x5B, 0x5F, 0x6C, 0x7A, 0xE1, 0xD3, 0xD2, +0xCC, 0xC8, 0xC4, 0xBF, 0xBD, 0xBA, 0xC2, 0x49, 0x3C, 0x4C, 0x41, 0x35, 0x3B, 0x52, 0xF3, 0xD6, +0xD1, 0xCE, 0xC3, 0xC6, 0x7A, 0x53, 0x57, 0x4E, 0x44, 0x46, 0x4F, 0x64, 0xE8, 0xDF, 0xDD, 0xD4, +0xD6, 0xEC, 0x56, 0x49, 0x54, 0x5E, 0x4F, 0x57, 0xFA, 0xE1, 0xDC, 0xE0, 0xE3, 0xD6, 0xD0, 0xDC, +0xD9, 0xC9, 0xC2, 0xBD, 0xC5, 0x58, 0x50, 0xE6, 0x4B, 0x37, 0x3F, 0x4F, 0x4D, 0x52, 0x6D, 0xDD, +0xC8, 0xC8, 0xDC, 0xDC, 0xD1, 0x72, 0x4A, 0x4A, 0x4E, 0x4B, 0x4E, 0x57, 0x6A, 0xDF, 0xD7, 0xDB, +0xD5, 0xCF, 0xDA, 0xF4, 0x74, 0x67, 0x5E, 0x5E, 0x5E, 0x66, 0xF9, 0xED, 0xEC, 0xE8, 0xE4, 0xE8, +0xF4, 0xF7, 0x60, 0x52, 0x6D, 0xF3, 0x5B, 0x66, 0xE7, 0xE1, 0xE0, 0xDF, 0xDF, 0xD8, 0xD1, 0xEA, +0x6B, 0xD9, 0xD1, 0xE5, 0xE6, 0xCC, 0xC4, 0xE7, 0x52, 0xEA, 0xE4, 0x4C, 0x48, 0x59, 0x5D, 0x59, +0x5D, 0x60, 0xF7, 0xDF, 0x79, 0x6A, 0xDF, 0xDC, 0xFE, 0xF8, 0xE2, 0xF0, 0x6F, 0x6B, 0x61, 0x5F, +0x62, 0x5D, 0x5E, 0x6C, 0x76, 0x70, 0xF7, 0xE5, 0xE6, 0xE7, 0xE5, 0xEA, 0xF4, 0x7D, 0x6C, 0x66, +0x68, 0x66, 0x66, 0x73, 0xF8, 0xF3, 0xF4, 0xF6, 0xFB, 0x7E, 0x7A, 0x7E, 0xF6, 0xEF, 0xED, 0xE9, +0xE9, 0xEF, 0xFB, 0x78, 0x6E, 0x69, 0x64, 0x63, 0x68, 0x6E, 0x74, 0x7B, 0xFA, 0xF6, 0xF3, 0xFF, +0x6B, 0x69, 0x69, 0x60, 0x5F, 0x65, 0x6C, 0x73, 0x7C, 0xF3, 0xEB, 0xE9, 0xEA, 0xE8, 0xE6, 0xE6, +0xE7, 0xE4, 0xDE, 0xDD, 0xE2, 0xE2, 0xE1, 0xE9, 0xF8, 0x77, 0x6B, 0x62, 0x5D, 0x5B, 0x5A, 0x59, +0x5A, 0x5B, 0x5D, 0x5E, 0x5E, 0x5E, 0x5F, 0x62, 0x67, 0x6D, 0x78, 0xFA, 0xF2, 0xEE, 0xEF, 0xF3, +0xF7, 0xF8, 0xFA, 0xFE, 0xFA, 0xF3, 0xF1, 0xEF, 0xEA, 0xE7, 0xE5, 0xE6, 0xE9, 0xEF, 0xFB, 0x79, +0x70, 0x6C, 0x6A, 0x6C, 0x6F, 0x77, 0x7C, 0xFD, 0xFB, 0x7F, 0x73, 0x6C, 0x69, 0x69, 0x6C, 0x73, +0xFA, 0xED, 0xE9, 0xE5, 0xE1, 0xE4, 0xE8, 0xE8, 0xE7, 0xE7, 0xE5, 0xE2, 0xE0, 0xDD, 0xDC, 0xE1, +0xE3, 0xE2, 0xEC, 0x7C, 0x6C, 0x63, 0x5D, 0x5B, 0x59, 0x58, 0x5A, 0x5B, 0x5B, 0x5C, 0x5F, 0x60, +0x5F, 0x60, 0x65, 0x6A, 0x75, 0xF8, 0xEC, 0xE7, 0xE6, 0xE7, 0xEA, 0xF0, 0xF8, 0xF9, 0xF4, 0xED, +0xE9, 0xE5, 0xE3, 0xE3, 0xE6, 0xEB, 0xF6, 0x76, 0x6C, 0x67, 0x62, 0x5F, 0x61, 0x64, 0x69, 0x6F, +0x73, 0x73, 0x75, 0x75, 0x70, 0x6E, 0x6F, 0x6E, 0x6E, 0x75, 0xFE, 0xF3, 0xEC, 0xE9, 0xE9, 0xE9, +0xED, 0xFA, 0x7A, 0x74, 0x71, 0x72, 0x73, 0x74, 0x7A, 0xFF, 0xFF, 0x7B, 0x72, 0x6E, 0x6D, 0x6C, +0x6C, 0x6E, 0x73, 0x7C, 0xFC, 0xF7, 0xF0, 0xEB, 0xE6, 0xE0, 0xDD, 0xDB, 0xDB, 0xDB, 0xDC, 0xDF, +0xE2, 0xE3, 0xE8, 0xF2, 0x7D, 0x6C, 0x61, 0x5D, 0x5A, 0x58, 0x59, 0x5C, 0x5E, 0x61, 0x66, 0x69, +0x6A, 0x6B, 0x6C, 0x6B, 0x6C, 0x75, 0xFE, 0xF7, 0xEE, 0xEA, 0xE8, 0xE6, 0xE9, 0xEC, 0xEB, 0xEB, +0xEE, 0xF0, 0xF2, 0xF6, 0xF9, 0xFD, 0x7F, 0xFF, 0x7C, 0x74, 0x6D, 0x69, 0x66, 0x64, 0x64, 0x68, +0x6B, 0x6D, 0x75, 0x7D, 0xFC, 0xF8, 0xFA, 0xFC, 0xFA, 0xF7, 0xF5, 0xF0, 0xEB, 0xE6, 0xE4, 0xE5, +0xE9, 0xED, 0xF2, 0xFC, 0x7A, 0x74, 0x6E, 0x6C, 0x6A, 0x69, 0x69, 0x6A, 0x6B, 0x6D, 0x6E, 0x6E, +0x6D, 0x6E, 0x70, 0x71, 0x74, 0x79, 0x7B, 0x7E, 0xFB, 0xF6, 0xF8, 0xF9, 0xF6, 0xF5, 0xF8, 0xFA, +0xF7, 0xF0, 0xEE, 0xF0, 0xF7, 0xFC, 0x7D, 0x73, 0x6C, 0x6B, 0x6B, 0x6A, 0x6B, 0x6B, 0x6B, 0x6B, +0x6C, 0x6D, 0x6D, 0x6E, 0x71, 0x71, 0x71, 0x72, 0x77, 0x7D, 0xFC, 0xF7, 0xF3, 0xED, 0xEB, 0xEB, +0xEE, 0xF4, 0xF9, 0xFE, 0x79, 0x77, 0x7B, 0x7F, 0x7F, 0xFF, 0xFF, 0x7B, 0x77, 0x76, 0x77, 0x79, +0x79, 0x7A, 0x7C, 0xFF, 0xFC, 0xFC, 0xFA, 0xF8, 0xF9, 0xF9, 0xFA, 0xFD, 0xFE, 0xFD, 0xFA, 0xF8, +0xF5, 0xF2, 0xF1, 0xF2, 0xF4, 0xF8, 0xFE, 0x7C, 0x79, 0x77, 0x77, 0x7A, 0x7E, 0x7F, 0x7C, 0x79, +0x78, 0x75, 0x73, 0x72, 0x71, 0x73, 0x75, 0x76, 0x78, 0x7D, 0xFD, 0xFB, 0xFC, 0xFF, 0x7D, 0x79, +0x76, 0x76, 0x77, 0x7C, 0xFB, 0xF5, 0xF3, 0xF3, 0xF3, 0xF7, 0x7D, 0x74, 0x6F, 0x6D, 0x6B, 0x6C, +0x6E, 0x73, 0x77, 0x77, 0x77, 0x7A, 0x7A, 0x76, 0x73, 0x72, 0x6F, 0x6D, 0x6B, 0x6C, 0x6F, 0x76, +0x7A, 0x7D, 0xFE, 0xFC, 0x7E, 0x7A, 0x75, 0x71, 0x6E, 0x6D, 0x6E, 0x71, 0x77, 0x7D, 0xFE, 0xFC, +0xFC, 0xFE, 0xFF, 0x7D, 0x7B, 0x7C, 0x7E, 0xFF, 0xFF, 0xFC, 0xF9, 0xF7, 0xF6, 0xF8, 0xFA, 0xFC, +0xFF, 0x7E, 0x7F, 0xFF, 0xFD, 0xFB, 0xF7, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFD, 0x7D, 0x7A, 0x7A, +0x7D, 0x7E, 0x7F, 0xFF, 0xFE, 0xFE, 0x7E, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0xFF, 0xFD, 0xFD, 0xFD, +0xFB, 0xF8, 0xF7, 0xF9, 0xFD, 0x7C, 0x79, 0x78, 0x78, 0x77, 0x77, 0x76, 0x75, 0x75, 0x75, 0x75, +0x75, 0x74, 0x76, 0x78, 0x79, 0x7B, 0x7D, 0x7F, 0xFD, 0xFB, 0xFF, 0x7A, 0x79, 0x7D, 0xFE, 0xFD, +0xFD, 0xFC, 0xFD, 0xFA, 0xF5, 0xF2, 0xF3, 0xF6, 0xF8, 0xF9, 0xFC, 0xFF, 0xFD, 0xF8, 0xF5, 0xF5, +0xF6, 0xFA, 0xFC, 0xFD, 0x7F, 0x7A, 0x78, 0x76, 0x75, 0x75, 0x77, 0x7B, 0x7E, 0x7E, 0x7E, 0x7F, +0x7E, 0x7C, 0x79, 0x76, 0x76, 0x78, 0x79, 0x78, 0x7B, 0x7E, 0xFF, 0x7F, 0x7C, 0x7A, 0x78, 0x75, +0x73, 0x73, 0x74, 0x76, 0x77, 0x78, 0x7B, 0x7B, 0x79, 0x79, 0x78, 0x77, 0x78, 0x74, 0x71, 0x72, +0x73, 0x76, 0x77, 0x77, 0x79, 0x79, 0x77, 0x76, 0x75, 0x76, 0x78, 0x7B, 0x7F, 0xFC, 0xFB, 0xFB, +0xFA, 0xFB, 0xFE, 0x7C, 0x79, 0x79, 0x78, 0x78, 0x7B, 0xFF, 0xFD, 0xFD, 0xFC, 0xFC, 0xFE, 0x7E, +0x7A, 0x78, 0x77, 0x75, 0x75, 0x76, 0x78, 0x79, 0x7A, 0x7C, 0x7C, 0x7C, 0x7B, 0x77, 0x78, 0x7A, +0x7A, 0x7A, 0x7C, 0x7E, 0xFF, 0x7F, 0x7F, 0xFF, 0xFF, 0x7F, 0x7E, 0x7F, 0x7E, 0x7C, 0x7A, 0x7A, +0x79, 0x79, 0x7B, 0x7E, 0x7E, 0x7F, 0xFD, 0xFC, 0xFD, 0xFD, 0xFE, 0xFD, 0xFD, 0xFE, 0xFE, 0xFE, +0xFF, 0x7E, 0x7D, 0x7F, 0xFF, 0xFF, 0xFE, 0xFC, 0xFB, 0xFC, 0xFC, 0xFE, 0x7E, 0x7F, 0x7E, 0x7B, +0x7C, 0x7D, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7A, 0x7A, 0x79, 0x78, 0x77, 0x76, 0x77, 0x7A, +0x7C, 0x7D, 0x7E, 0x7E, 0x7C, 0x79, 0x76, 0x77, 0x79, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0x7D, +0x7D, 0x7C, 0x7A, 0x78, 0x78, 0x78, 0x79, 0x7A, 0x7C, 0x7E, 0x7D, 0x7E, 0x7E, 0x7C, 0x7B, 0x7C, +0x7C, 0x7C, 0x7D, 0xFF, 0xFC, 0xFB, 0xFB, 0xFC, 0xFF, 0x7C, 0x79, 0x77, 0x74, 0x75, 0x77, 0x7A, +0x7D, 0x7E, 0xFF, 0xFD, 0xFD, 0xFE, 0x7E, 0x7D, 0x7D, 0x7B, 0x7A, 0x7B, 0x7D, 0x7E, 0xFE, 0xFD, +0xFF, 0x7F, 0x7D, 0x7B, 0x7A, 0x78, 0x76, 0x76, 0x79, 0x7C, 0x7E, 0xFF, 0xFF, 0x7F, 0x7E, 0x7C, +0x7A, 0x79, 0x78, 0x78, 0x77, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0x7F, 0x7E, 0x7D, 0x7B, 0x7A, +0x7B, 0x7C, 0x7D, 0xFE, 0xFC, 0xFA, 0xF9, 0xFA, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFA, 0xF8, 0xF7, +0xF6, 0xF7, 0xF9, 0xFB, 0xFE, 0x7E, 0x7C, 0x7A, 0x79, 0x79, 0x7B, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, +0x7E, 0x7C, 0x7B, 0x79, 0x7A, 0x7C, 0x7C, 0x7E, 0x7E, 0x7F, 0xFF, 0x7F, 0x7E, 0x7C, 0x7B, 0x79, +0x77, 0x76, 0x76, 0x78, 0x7B, 0x7B, 0x7B, 0x7A, 0x7A, 0x7A, 0x77, 0x77, 0x78, 0x78, 0x79, 0x7B, +0x7D, 0x79, 0x79, 0x7E, 0x79, 0x78, 0x79, 0x78, 0x7A, 0x78, 0x7D, 0x7D, 0x7C, 0xFF, 0x7D, 0x7F, +0x7E, 0x7B, 0x7A, 0x76, 0x79, 0x76, 0x78, 0x7B, 0x79, 0xFF, 0x7D, 0xFB, 0xFD, 0x7D, 0xF9, 0x7B, +0xFF, 0x79, 0x75, 0xFF, 0x6E, 0x7F, 0x71, 0x73, 0x79, 0x51, 0x60, 0xE2, 0x6F, 0x7D, 0xF7, 0xF5, +0x77, 0x72, 0xE4, 0x50, 0x4C, 0xDE, 0xFB, 0x66, 0xE5, 0xF6, 0x6F, 0x6C, 0xE7, 0xDC, 0x6E, 0xFD, +0xE6, 0x7E, 0xE9, 0x77, 0x62, 0xE3, 0xE9, 0x6C, 0x71, 0xEA, 0xDE, 0x75, 0x7E, 0xE8, 0x75, 0xF8, +0x7A, 0xFC, 0xF2, 0x65, 0xF8, 0xEE, 0xF9, 0xF4, 0x73, 0xE4, 0xF9, 0x6E, 0xE5, 0x75, 0x67, 0x5A, +0x50, 0x57, 0x5A, 0x7D, 0x6C, 0x64, 0xDA, 0xED, 0x64, 0xEA, 0xE9, 0xF5, 0x7E, 0x6F, 0xFC, 0xF2, +0x66, 0x63, 0xF7, 0x7D, 0x78, 0xF6, 0xF8, 0xE1, 0xE2, 0xF9, 0xEB, 0xE4, 0xED, 0xFE, 0xFA, 0xF6, +0xF1, 0xF2, 0x6F, 0xFE, 0xE8, 0xFF, 0x7F, 0xEA, 0xE8, 0xED, 0xEE, 0xEA, 0xEB, 0xED, 0xF8, 0xEF, +0xE8, 0x7F, 0xF5, 0xE6, 0xF7, 0xF2, 0xF3, 0xF2, 0xDF, 0xEB, 0xF5, 0xE3, 0xEC, 0xF2, 0xEF, 0xFC, +0xED, 0xEF, 0xFD, 0xED, 0xF0, 0x7C, 0x77, 0xFE, 0xF1, 0x77, 0x79, 0xEF, 0xF6, 0xF8, 0xFB, 0x72, +0x75, 0x79, 0x78, 0x70, 0x6E, 0x7C, 0x7D, 0x74, 0x79, 0x77, 0x6E, 0x71, 0x7D, 0x6F, 0x6B, 0x7D, +0xFE, 0x76, 0x7A, 0x7D, 0x7F, 0x75, 0x6C, 0x7B, 0xF7, 0x7A, 0x7B, 0x7E, 0x74, 0x79, 0x75, 0x70, +0x7C, 0x79, 0xFD, 0xF6, 0x6E, 0x6E, 0x7B, 0x6B, 0x67, 0x6D, 0x6E, 0x6A, 0x67, 0x6A, 0x6D, 0x6F, +0x6B, 0x67, 0x6D, 0x6C, 0x65, 0x63, 0x5E, 0x65, 0x6A, 0x5F, 0x68, 0x6C, 0x60, 0x6C, 0x7D, 0x6D, +0x6E, 0x7D, 0x7C, 0xFF, 0xEE, 0xEB, 0xEC, 0xE3, 0xDE, 0xE1, 0xE4, 0xE0, 0xE8, 0xF8, 0xEE, 0xFA, +0x6D, 0x69, 0x5C, 0x58, 0x59, 0x53, 0x50, 0x4E, 0x4D, 0x4E, 0x4F, 0x4F, 0x53, 0x51, 0x51, 0x54, +0x55, 0x56, 0x5A, 0x5E, 0x69, 0xF7, 0xE2, 0xD8, 0xCF, 0xCE, 0xCD, 0xCC, 0xCE, 0xCE, 0xCA, 0xC7, +0xC2, 0xBF, 0xBE, 0xBD, 0xC2, 0xD5, 0xF1, 0x62, 0x4B, 0x3F, 0x3D, 0x3D, 0x3E, 0x40, 0x42, 0x4A, +0x51, 0x51, 0x51, 0x55, 0x56, 0x4F, 0x4D, 0x4E, 0x50, 0x52, 0x55, 0x5C, 0x69, 0xFA, 0xE4, 0xD9, +0xCD, 0xC9, 0xC5, 0xC1, 0xBF, 0xBB, 0xBB, 0xBD, 0xB9, 0xB7, 0xB5, 0xB7, 0xC8, 0xDD, 0x61, 0x43, +0x3C, 0x38, 0x38, 0x3D, 0x40, 0x46, 0x4E, 0x5A, 0x60, 0x5D, 0x5B, 0x5B, 0x5A, 0x58, 0x56, 0x58, +0x5C, 0x5E, 0x5E, 0x64, 0x6B, 0x6D, 0xF9, 0xED, 0xE5, 0xDC, 0xD9, 0xD2, 0xCC, 0xC5, 0xBF, 0xBF, +0xBA, 0xB7, 0xB6, 0xB1, 0xB7, 0xCB, 0xFA, 0x49, 0x3A, 0x35, 0x31, 0x33, 0x3A, 0x42, 0x4C, 0x5C, +0xFD, 0xE1, 0xEE, 0x68, 0x66, 0x5C, 0x51, 0x4F, 0x4D, 0x55, 0x5F, 0x5D, 0x64, 0x71, 0xFA, 0xED, +0xEF, 0xEB, 0xDE, 0xD3, 0xCC, 0xC3, 0xBE, 0xBD, 0xB9, 0xB8, 0xB5, 0xAF, 0xB7, 0xCC, 0x60, 0x3F, +0x39, 0x34, 0x2F, 0x31, 0x3A, 0x47, 0x56, 0x6F, 0xE3, 0xDA, 0xD5, 0xEC, 0x56, 0x50, 0x4E, 0x4B, +0x4B, 0x4C, 0x57, 0x7B, 0xE7, 0xE0, 0xDC, 0xD5, 0xD6, 0xDE, 0xEC, 0xEF, 0xDE, 0xD7, 0xCC, 0xC1, +0xBD, 0xB8, 0xB5, 0xB4, 0xB0, 0xB6, 0xCB, 0x58, 0x3E, 0x38, 0x34, 0x2F, 0x2F, 0x38, 0x45, 0x59, +0x7D, 0xDD, 0xD1, 0xCE, 0xDD, 0x63, 0x53, 0x4E, 0x4C, 0x4A, 0x4B, 0x53, 0x69, 0xE7, 0xDB, 0xD5, +0xD0, 0xCE, 0xD3, 0xDC, 0xE4, 0xEA, 0xE8, 0xE2, 0xD5, 0xC8, 0xC0, 0xBB, 0xB8, 0xB5, 0xB2, 0xB9, +0xD1, 0x54, 0x40, 0x3A, 0x34, 0x2F, 0x2F, 0x36, 0x3F, 0x4C, 0x5B, 0x7E, 0xDE, 0xD4, 0xDB, 0xFF, +0x62, 0x58, 0x55, 0x53, 0x4F, 0x52, 0x5D, 0x6F, 0xF0, 0xE4, 0xDE, 0xDA, 0xD8, 0xDC, 0xE1, 0xE5, +0xDF, 0xDC, 0xD6, 0xCC, 0xC6, 0xC1, 0xBE, 0xBB, 0xB8, 0xBC, 0xCE, 0x67, 0x4B, 0x44, 0x3E, 0x38, +0x35, 0x37, 0x3D, 0x45, 0x4B, 0x53, 0x61, 0xFA, 0xE4, 0xEC, 0x7F, 0x79, 0x78, 0x79, 0x70, 0x68, +0x68, 0x70, 0x7B, 0x7D, 0x7D, 0xF9, 0xEE, 0xEA, 0xE8, 0xE6, 0xE1, 0xDB, 0xD6, 0xCF, 0xCB, 0xC8, +0xC5, 0xC1, 0xBE, 0xBF, 0xC7, 0xD5, 0xF9, 0x5F, 0x55, 0x4A, 0x42, 0x3E, 0x3E, 0x41, 0x45, 0x48, +0x4C, 0x56, 0x5F, 0x6F, 0xF8, 0xEF, 0xE7, 0xE4, 0xE6, 0xE2, 0xEA, 0xF5, 0xFD, 0x75, 0x75, 0x79, +0x75, 0x76, 0x7E, 0xFA, 0xF1, 0xE9, 0xE0, 0xDA, 0xD3, 0xCF, 0xCC, 0xCA, 0xC7, 0xC4, 0xC5, 0xCC, +0xD3, 0xDF, 0xFF, 0x69, 0x58, 0x4C, 0x47, 0x43, 0x42, 0x42, 0x43, 0x46, 0x4C, 0x55, 0x59, 0x62, +0x77, 0xFD, 0xEE, 0xEC, 0xF3, 0xEC, 0xF2, 0x76, 0x76, 0x6F, 0x6E, 0x79, 0x79, 0x7F, 0xF3, 0xED, +0xE4, 0xDD, 0xDB, 0xD7, 0xD3, 0xD0, 0xCE, 0xCC, 0xCB, 0xCA, 0xCC, 0xD1, 0xD6, 0xDD, 0xEA, 0x7E, +0x62, 0x56, 0x4F, 0x4C, 0x49, 0x48, 0x49, 0x4C, 0x50, 0x56, 0x58, 0x5C, 0x67, 0x6F, 0x6C, 0x6E, +0x6D, 0x6A, 0x6F, 0x6D, 0x6B, 0x6E, 0x6D, 0x76, 0xFA, 0xF9, 0xF1, 0xEB, 0xE7, 0xE1, 0xDE, 0xDD, +0xDB, 0xD8, 0xD7, 0xD4, 0xD2, 0xD0, 0xCF, 0xD4, 0xD8, 0xDA, 0xDF, 0xEA, 0xF8, 0x6D, 0x60, 0x5C, +0x58, 0x56, 0x56, 0x56, 0x57, 0x59, 0x5B, 0x5B, 0x5A, 0x5C, 0x5F, 0x5F, 0x5F, 0x63, 0x66, 0x6B, +0x72, 0x77, 0x7E, 0xF7, 0xF0, 0xEC, 0xE9, 0xE9, 0xE8, 0xE8, 0xE8, 0xE8, 0xEA, 0xE7, 0xE6, 0xE5, +0xE3, 0xE1, 0xDD, 0xDA, 0xD9, 0xD8, 0xDD, 0xDF, 0xDD, 0xE0, 0xE7, 0xEE, 0xFE, 0x74, 0x6C, 0x62, +0x5C, 0x59, 0x56, 0x54, 0x52, 0x51, 0x51, 0x52, 0x55, 0x58, 0x59, 0x5D, 0x62, 0x68, 0x70, 0x75, +0x7D, 0xF9, 0xF8, 0xF4, 0xF5, 0xF9, 0xF5, 0xF3, 0xF3, 0xF2, 0xF2, 0xEF, 0xED, 0xEB, 0xEA, 0xE6, +0xE3, 0xE0, 0xDC, 0xDA, 0xD7, 0xD8, 0xDB, 0xDB, 0xDA, 0xDC, 0xDF, 0xE8, 0xF6, 0x7F, 0x6E, 0x60, +0x5B, 0x58, 0x56, 0x54, 0x53, 0x52, 0x53, 0x59, 0x5C, 0x5E, 0x63, 0x68, 0x6F, 0x7B, 0x7C, 0xFF, +0xFC, 0xFC, 0xFB, 0xFC, 0xFD, 0xF8, 0xF7, 0xF6, 0xF4, 0xF5, 0xF3, 0xF0, 0xEF, 0xED, 0xEB, 0xE8, +0xE4, 0xE0, 0xDD, 0xDA, 0xD9, 0xDA, 0xDC, 0xDC, 0xDC, 0xE0, 0xE9, 0xF8, 0x76, 0x6B, 0x61, 0x5C, +0x5A, 0x5A, 0x5A, 0x5B, 0x5C, 0x5E, 0x62, 0x67, 0x6B, 0x6D, 0x6F, 0x72, 0x75, 0x76, 0x76, 0x75, +0x74, 0x79, 0x7E, 0x7B, 0x78, 0x7D, 0xFB, 0xFB, 0xFD, 0xFA, 0xF6, 0xF5, 0xF2, 0xEF, 0xEC, 0xE9, +0xE4, 0xDF, 0xDE, 0xDE, 0xE0, 0xE7, 0xEA, 0xEC, 0xF2, 0xFE, 0x76, 0x6F, 0x6F, 0x6D, 0x6A, 0x6A, +0x6B, 0x6C, 0x6C, 0x69, 0x67, 0x67, 0x66, 0x65, 0x64, 0x64, 0x65, 0x66, 0x67, 0x69, 0x6B, 0x6E, +0x71, 0x76, 0x7A, 0x7D, 0xFE, 0xFC, 0xFA, 0xF8, 0xF4, 0xF0, 0xEE, 0xEC, 0xEA, 0xE9, 0xE8, 0xE9, +0xEB, 0xEB, 0xEC, 0xED, 0xEE, 0xED, 0xEB, 0xE9, 0xEA, 0xE9, 0xE9, 0xEA, 0xEC, 0xF0, 0xF6, 0xFD, +0x78, 0x71, 0x6D, 0x69, 0x67, 0x66, 0x65, 0x65, 0x66, 0x67, 0x66, 0x66, 0x67, 0x67, 0x66, 0x66, +0x69, 0x6B, 0x6D, 0x73, 0x7A, 0xFE, 0xF7, 0xF3, 0xEF, 0xEE, 0xEE, 0xEC, 0xEB, 0xEA, 0xE8, 0xE7, +0xE5, 0xE3, 0xE1, 0xE1, 0xE1, 0xE3, 0xE6, 0xE8, 0xEB, 0xEF, 0xF8, 0x7E, 0x75, 0x6F, 0x6B, 0x69, +0x67, 0x66, 0x65, 0x65, 0x66, 0x67, 0x67, 0x68, 0x68, 0x69, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, +0x70, 0x6F, 0x6F, 0x6F, 0x72, 0x75, 0x79, 0xFF, 0xFB, 0xF6, 0xF2, 0xEF, 0xEE, 0xED, 0xEE, 0xF0, +0xF3, 0xF6, 0xF8, 0xFC, 0xFF, 0x7D, 0x79, 0x76, 0x72, 0x6E, 0x6D, 0x6B, 0x6B, 0x6C, 0x6C, 0x6D, +0x6E, 0x71, 0x76, 0x7B, 0xFF, 0xFE, 0xFD, 0xFC, 0xFD, 0x7F, 0x7B, 0x78, 0x75, 0x74, 0x75, 0x77, +0x7A, 0x7E, 0xFC, 0xF9, 0xF6, 0xF5, 0xF4, 0xF4, 0xF5, 0xF7, 0xF8, 0xF8, 0xF7, 0xF6, 0xF5, 0xF5, +0xF6, 0xF8, 0xFA, 0xFC, 0x7F, 0x7B, 0x79, 0x78, 0x77, 0x77, 0x79, 0x7D, 0xFD, 0xF9, 0xF4, 0xF2, +0xF1, 0xF1, 0xF3, 0xF5, 0xFA, 0xFE, 0x7F, 0xFF, 0xFD, 0xFC, 0xFB, 0xF7, 0xF5, 0xF4, 0xF4, 0xF6, +0xF8, 0xFB, 0xFD, 0xFF, 0x7E, 0x7E, 0x7E, 0xFF, 0x7F, 0x7D, 0x7D, 0x7E, 0x7E, 0x7B, 0x79, 0x77, +0x76, 0x75, 0x74, 0x74, 0x75, 0x78, 0x7C, 0x7F, 0xFE, 0xFD, 0xFE, 0xFF, 0x7E, 0x7C, 0x7B, 0x79, +0x79, 0x7A, 0x7D, 0xFE, 0xFC, 0xFA, 0xF8, 0xF8, 0xF9, 0xFB, 0xFD, 0x7F, 0x7B, 0x78, 0x76, 0x75, +0x74, 0x73, 0x73, 0x73, 0x74, 0x74, 0x74, 0x74, 0x74, 0x74, 0x75, 0x76, 0x76, 0x77, 0x7A, 0x7C, +0x7E, 0xFF, 0xFF, 0xFF, 0x7F, 0x7D, 0x7C, 0x7A, 0x78, 0x77, 0x77, 0x76, 0x79, 0x7B, 0x7E, 0xFF, +0xFE, 0xFD, 0xFD, 0xFF, 0x7E, 0x7C, 0x7C, 0x7B, 0x79, 0x78, 0x78, 0x78, 0x77, 0x75, 0x74, 0x74, +0x74, 0x74, 0x75, 0x76, 0x79, 0x7C, 0x7E, 0xFF, 0xFC, 0xF8, 0xF7, 0xF6, 0xF7, 0xF7, 0xF7, 0xF9, +0xFC, 0xFF, 0x7E, 0x7D, 0x7C, 0x7D, 0x7F, 0xFF, 0xFC, 0xFB, 0xFA, 0xF8, 0xF8, 0xF8, 0xF6, 0xF5, +0xF5, 0xF4, 0xF4, 0xF5, 0xF7, 0xF8, 0xFA, 0xFD, 0x7F, 0x7E, 0x7D, 0x7C, 0x7C, 0x7D, 0x7E, 0xFE, +0xFD, 0xFC, 0xFB, 0xFA, 0xF9, 0xF9, 0xF9, 0xFA, 0xFB, 0xFD, 0xFF, 0x7E, 0x7D, 0x79, 0x77, 0x75, +0x72, 0x71, 0x70, 0x70, 0x70, 0x71, 0x71, 0x70, 0x71, 0x72, 0x71, 0x72, 0x71, 0x72, 0x73, 0x72, +0x72, 0x71, 0x71, 0x71, 0x72, 0x74, 0x74, 0x76, 0x77, 0x77, 0x77, 0x78, 0x77, 0x78, 0x78, 0x78, +0x7A, 0x7C, 0x7C, 0x7D, 0x7E, 0x7F, 0xFF, 0xFF, 0xFE, 0xFD, 0xFF, 0x7E, 0x7D, 0x7B, 0x7C, 0x7B, +0x7B, 0x7B, 0x7B, 0x7B, 0x7C, 0x7B, 0x7A, 0x7B, 0x7B, 0x7A, 0x7B, 0x7B, 0x7C, 0x7E, 0xFF, 0xFD, +0xFB, 0xFB, 0xFB, 0xFB, 0xFC, 0xFE, 0xFF, 0x7F, 0x7D, 0x7C, 0x7B, 0x7A, 0x7A, 0x7B, 0x7B, 0x7D, +0x7F, 0x7F, 0xFF, 0xFD, 0xFD, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFE, 0xFF, +0xFF, 0xFF, 0xFF, 0xFD, 0xFA, 0xF9, 0xF7, 0xF5, 0xF4, 0xF3, 0xF1, 0xF1, 0xF1, 0xF1, 0xF2, 0xF2, +0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xFA, 0xFC, 0xFE, 0xFE, 0xFF, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, 0x7F, +0x7F, 0x7D, 0x7C, 0x7D, 0x7B, 0x7A, 0x7D, 0x7B, 0x7B, 0x7C, 0x7B, 0x7B, 0x7B, 0x79, 0x78, 0x77, +0x77, 0x76, 0x75, 0x76, 0x75, 0x74, 0x74, 0x75, 0x74, 0x73, 0x74, 0x74, 0x74, 0x74, 0x73, 0x74, +0x72, 0x70, 0x70, 0x6F, 0x6F, 0x6F, 0x6F, 0x6F, 0x70, 0x70, 0x70, 0x71, 0x72, 0x73, 0x73, 0x76, +0x79, 0x79, 0x79, 0x7A, 0x7B, 0x7C, 0x7B, 0x7D, 0x7E, 0x7D, 0x7F, 0x7D, 0x7C, 0x7B, 0x7B, 0x7C, +0x7B, 0x7B, 0x7A, 0x78, 0x7A, 0x7B, 0x7D, 0x7E, 0x7E, 0xFF, 0x7D, 0x7E, 0x7C, 0x7C, 0x7B, 0x78, +0x7C, 0x7A, 0x7C, 0x7D, 0x7B, 0x7E, 0x7C, 0x7F, 0x7D, 0x7A, 0x7E, 0x78, 0x7B, 0x6F, 0x68, 0x5C, +0x4C, 0x58, 0xDD, 0xE1, 0xEB, 0xE1, 0xE9, 0xEF, 0xF8, 0xE9, 0xE1, 0xED, 0xF9, 0xFC, 0xF2, 0xED, +0x7D, 0x76, 0xFB, 0xF9, 0x7C, 0x70, 0x6F, 0x78, 0x79, 0x6D, 0x6D, 0x76, 0x7D, 0xFE, 0x7A, 0x79, +0xFC, 0xFD, 0xFD, 0xFA, 0xFB, 0xFA, 0xFC, 0xFF, 0xFC, 0xFC, 0xFE, 0xFD, 0xFE, 0xFB, 0xFB, 0xFE, +0xFE, 0x7E, 0x7D, 0x7C, 0x7C, 0x7B, 0x78, 0x7D, 0x7D, 0xFF, 0xFA, 0xFF, 0xF9, 0xF9, 0xFA, 0xF7, +0x7F, 0xF9, 0x7A, 0x7A, 0x6F, 0x51, 0x52, 0x6E, 0x71, 0xF1, 0xD8, 0xD3, 0xDB, 0xEF, 0xE2, 0xDB, +0xED, 0xF6, 0xF3, 0xEF, 0xF4, 0x6A, 0x74, 0x73, 0x57, 0x5E, 0x77, 0x6E, 0xFD, 0xF4, 0xFC, 0x7D, +0x73, 0xE9, 0xDE, 0xE2, 0xDE, 0xE3, 0xE5, 0xE8, 0xFA, 0xF7, 0xFA, 0x6F, 0x6C, 0x6A, 0x6B, 0x6A, +0x66, 0x6B, 0x75, 0x70, 0x74, 0xFA, 0xFB, 0xFD, 0xF8, 0xF3, 0xF2, 0xFB, 0xF5, 0xED, 0xEF, 0xEB, +0xE5, 0xDF, 0xDA, 0xD7, 0xD5, 0xD3, 0xD3, 0xD4, 0xD8, 0xE0, 0xEE, 0x76, 0x5D, 0x53, 0x4D, 0x49, +0x46, 0x43, 0x42, 0x43, 0x43, 0x45, 0x48, 0x4B, 0x4F, 0x57, 0x60, 0x6D, 0xF7, 0xE3, 0xDB, 0xD4, +0xCF, 0xCB, 0xC8, 0xC4, 0xBE, 0xBC, 0xB9, 0xB4, 0xB6, 0xBC, 0xC1, 0xC3, 0xD5, 0x4F, 0x4B, 0x43, +0x36, 0x33, 0x34, 0x32, 0x31, 0x36, 0x3B, 0x3F, 0x48, 0x60, 0xDF, 0xD2, 0xC9, 0xC1, 0xC3, 0xC6, +0xC7, 0xCF, 0xE3, 0x67, 0x56, 0x47, 0x3E, 0x3F, 0x3C, 0x3B, 0x43, 0x48, 0x4F, 0xFA, 0xD5, 0xC5, +0xBD, 0xB7, 0xB1, 0xAE, 0xAC, 0xAE, 0xB1, 0xB5, 0xC0, 0xD7, 0x5D, 0x40, 0x38, 0x31, 0x2E, 0x2D, +0x2C, 0x2E, 0x32, 0x37, 0x3F, 0x4F, 0xF8, 0xD0, 0xC4, 0xBC, 0xBB, 0xBB, 0xBB, 0xBE, 0xC7, 0xD0, +0xF1, 0x56, 0x48, 0x40, 0x3D, 0x3B, 0x3D, 0x42, 0x49, 0x63, 0xDA, 0xCB, 0xBC, 0xB6, 0xB0, 0xAE, +0xAF, 0xAF, 0xB4, 0xBC, 0xC6, 0xFE, 0x4C, 0x3E, 0x34, 0x30, 0x2E, 0x2D, 0x2E, 0x30, 0x35, 0x3C, +0x46, 0x62, 0xDE, 0xCA, 0xBE, 0xBD, 0xBB, 0xBA, 0xBD, 0xC3, 0xCB, 0xDC, 0x6B, 0x59, 0x51, 0x52, +0x60, 0xFF, 0xD5, 0xC4, 0xBE, 0xBC, 0xBA, 0xB9, 0xBB, 0xC3, 0xC8, 0xD6, 0x5A, 0x4C, 0x42, 0x39, +0x36, 0x35, 0x32, 0x34, 0x36, 0x39, 0x41, 0x47, 0x58, 0xE0, 0xDA, 0xC9, 0xC1, 0xC4, 0xC0, 0xC0, +0xC6, 0xCA, 0xD1, 0xDC, 0xF3, 0x6E, 0xFC, 0xE8, 0xDB, 0xCB, 0xC2, 0xBE, 0xBD, 0xBE, 0xBD, 0xC0, +0xCD, 0xCE, 0xEC, 0x4E, 0x4C, 0x40, 0x38, 0x39, 0x37, 0x35, 0x38, 0x38, 0x3B, 0x43, 0x49, 0x54, +0xEA, 0xDB, 0xCE, 0xC5, 0xC5, 0xC3, 0xC1, 0xC7, 0xCA, 0xCF, 0xDB, 0xE9, 0xFD, 0xF7, 0xE9, 0xDD, +0xCE, 0xC6, 0xC1, 0xBF, 0xC0, 0xBF, 0xC3, 0xCF, 0xD0, 0xE6, 0x51, 0x4E, 0x43, 0x3A, 0x3B, 0x38, +0x35, 0x38, 0x38, 0x3A, 0x3F, 0x44, 0x4E, 0x5F, 0xEF, 0xD7, 0xCD, 0xC8, 0xC6, 0xC4, 0xC6, 0xC9, +0xCC, 0xD4, 0xDD, 0xE6, 0xE1, 0xDA, 0xD7, 0xCA, 0xC3, 0xC4, 0xC4, 0xC1, 0xC3, 0xCC, 0xCF, 0xD8, +0x60, 0x54, 0x4E, 0x3F, 0x3D, 0x3D, 0x39, 0x3A, 0x3C, 0x3B, 0x3D, 0x47, 0x48, 0x51, 0x79, 0xFA, +0xDD, 0xCD, 0xCF, 0xCC, 0xC8, 0xCD, 0xCE, 0xCE, 0xD7, 0xDC, 0xDC, 0xD7, 0xD4, 0xCC, 0xC3, 0xC1, +0xBF, 0xBF, 0xC2, 0xC1, 0xCE, 0xDB, 0xDD, 0x54, 0x4C, 0x49, 0x3C, 0x3B, 0x3B, 0x38, 0x3A, 0x3B, +0x3C, 0x3E, 0x48, 0x4C, 0x55, 0xF3, 0xEC, 0xDB, 0xCD, 0xD1, 0xCD, 0xCB, 0xD2, 0xD1, 0xD6, 0xDD, +0xE1, 0xE2, 0xD7, 0xD3, 0xCA, 0xC0, 0xBE, 0xBE, 0xBF, 0xBE, 0xC1, 0xCF, 0xD0, 0xED, 0x4E, 0x4D, +0x41, 0x3A, 0x3A, 0x37, 0x35, 0x38, 0x3A, 0x3A, 0x3F, 0x49, 0x4A, 0x62, 0xE7, 0xEA, 0xCE, 0xCB, +0xCF, 0xC8, 0xCB, 0xD1, 0xCF, 0xD7, 0xE2, 0xE5, 0xE5, 0xDF, 0xD5, 0xCC, 0xC5, 0xBE, 0xBE, 0xC0, +0xBC, 0xC0, 0xCD, 0xC8, 0xDC, 0x58, 0x5B, 0x47, 0x3C, 0x3D, 0x39, 0x36, 0x39, 0x3A, 0x39, 0x3E, +0x47, 0x49, 0x59, 0xEA, 0xEC, 0xD0, 0xC9, 0xCD, 0xC7, 0xC8, 0xCE, 0xCD, 0xD2, 0xDC, 0xDF, 0xDF, +0xDD, 0xD6, 0xCB, 0xC6, 0xBF, 0xBF, 0xC4, 0xBD, 0xC4, 0xD1, 0xC9, 0xEF, 0x55, 0x5D, 0x43, 0x3D, +0x3E, 0x38, 0x37, 0x3A, 0x3A, 0x3A, 0x3E, 0x45, 0x48, 0x56, 0x74, 0xF8, 0xD8, 0xCF, 0xD0, 0xCB, +0xCB, 0xCE, 0xCE, 0xD2, 0xD9, 0xDC, 0xDC, 0xD7, 0xD3, 0xCA, 0xC4, 0xC0, 0xBF, 0xC2, 0xBE, 0xC3, +0xCF, 0xCB, 0xE5, 0x58, 0x5C, 0x45, 0x3D, 0x3E, 0x39, 0x37, 0x39, 0x3A, 0x3A, 0x3D, 0x45, 0x46, +0x52, 0x79, 0x73, 0xD7, 0xCD, 0xD1, 0xC8, 0xC8, 0xCD, 0xCA, 0xCF, 0xD5, 0xD7, 0xDC, 0xDA, 0xD4, +0xCD, 0xC7, 0xC1, 0xC0, 0xC5, 0xBF, 0xC2, 0xD1, 0xCA, 0xDA, 0x5A, 0x68, 0x4C, 0x3E, 0x42, 0x3B, +0x38, 0x3B, 0x3A, 0x3A, 0x3D, 0x42, 0x44, 0x4B, 0x62, 0x66, 0xF1, 0xD0, 0xD6, 0xCD, 0xC8, 0xCE, +0xCA, 0xCB, 0xD1, 0xCF, 0xD2, 0xD2, 0xCE, 0xC9, 0xC5, 0xC1, 0xBF, 0xC5, 0xC1, 0xC0, 0xD3, 0xCE, +0xD6, 0x57, 0x5F, 0x4E, 0x3E, 0x41, 0x3D, 0x39, 0x3B, 0x3B, 0x3A, 0x3D, 0x42, 0x44, 0x4C, 0x5A, +0x5E, 0xEC, 0xDD, 0xDC, 0xCE, 0xD0, 0xD1, 0xCD, 0xD4, 0xD4, 0xD4, 0xDA, 0xD3, 0xCE, 0xCB, 0xC4, +0xBF, 0xBE, 0xC2, 0xBE, 0xBF, 0xCD, 0xCB, 0xD5, 0x5B, 0x5F, 0x4D, 0x3E, 0x3F, 0x3B, 0x37, 0x39, +0x3A, 0x39, 0x3C, 0x3F, 0x42, 0x4B, 0x59, 0x61, 0xEA, 0xDA, 0xD6, 0xCD, 0xCD, 0xCE, 0xCD, 0xCF, +0xD3, 0xD6, 0xDA, 0xD7, 0xD2, 0xCE, 0xC7, 0xC2, 0xBF, 0xC0, 0xC1, 0xBE, 0xC8, 0xCE, 0xCB, 0x79, +0x5A, 0x5C, 0x41, 0x3F, 0x3E, 0x38, 0x39, 0x3A, 0x39, 0x3A, 0x3E, 0x42, 0x45, 0x51, 0x62, 0x65, +0xDD, 0xD5, 0xD7, 0xCA, 0xCC, 0xCE, 0xCA, 0xCE, 0xD0, 0xCF, 0xCF, 0xCD, 0xC9, 0xC4, 0xBF, 0xBD, +0xBE, 0xBF, 0xBD, 0xC5, 0xCE, 0xCB, 0xF8, 0x58, 0x5B, 0x43, 0x3E, 0x3E, 0x39, 0x38, 0x3A, 0x39, +0x3A, 0x3E, 0x44, 0x45, 0x51, 0x6E, 0x69, 0xDC, 0xCF, 0xD7, 0xCA, 0xCB, 0xD0, 0xCC, 0xD1, 0xD5, +0xD5, 0xD5, 0xCF, 0xCB, 0xC5, 0xBF, 0xBC, 0xBD, 0xBF, 0xBB, 0xC3, 0xCC, 0xC8, 0xEF, 0x5B, 0x5D, +0x41, 0x3D, 0x3D, 0x37, 0x37, 0x38, 0x37, 0x38, 0x3B, 0x41, 0x43, 0x4E, 0x6B, 0x67, 0xDC, 0xCE, +0xD4, 0xC9, 0xC8, 0xCE, 0xCA, 0xCE, 0xD5, 0xD4, 0xD5, 0xD3, 0xCE, 0xC7, 0xC3, 0xBE, 0xBE, 0xC3, +0xBD, 0xC2, 0xD0, 0xC9, 0xDE, 0x57, 0x61, 0x47, 0x3D, 0x3F, 0x39, 0x36, 0x38, 0x38, 0x38, 0x3A, +0x41, 0x40, 0x48, 0x6A, 0x5C, 0xF7, 0xCD, 0xDB, 0xCD, 0xC6, 0xD1, 0xCC, 0xCC, 0xD6, 0xD5, 0xD3, +0xCF, 0xCE, 0xC6, 0xC0, 0xBF, 0xBE, 0xBF, 0xBE, 0xC0, 0xCC, 0xCB, 0xDB, 0x5D, 0x5B, 0x49, 0x3E, +0x3E, 0x39, 0x37, 0x38, 0x38, 0x38, 0x3B, 0x40, 0x42, 0x4A, 0x63, 0x66, 0xE5, 0xCE, 0xD0, 0xCA, +0xC7, 0xCA, 0xCA, 0xCC, 0xCE, 0xD1, 0xCF, 0xCC, 0xCC, 0xC4, 0xBF, 0xBF, 0xBE, 0xC0, 0xBE, 0xC2, +0xCE, 0xCC, 0xE2, 0x58, 0x59, 0x47, 0x3D, 0x3D, 0x39, 0x37, 0x39, 0x39, 0x39, 0x3C, 0x40, 0x44, +0x4D, 0x5D, 0x6F, 0xE0, 0xD4, 0xCF, 0xCC, 0xCB, 0xCB, 0xCD, 0xCF, 0xCF, 0xD4, 0xD1, 0xCC, 0xCA, +0xC4, 0xBF, 0xBD, 0xBF, 0xBF, 0xBE, 0xC7, 0xCF, 0xCE, 0x79, 0x52, 0x51, 0x41, 0x3C, 0x3B, 0x38, +0x36, 0x38, 0x39, 0x38, 0x3D, 0x44, 0x44, 0x55, 0x70, 0x76, 0xD5, 0xCF, 0xCF, 0xC9, 0xCB, 0xCB, +0xCD, 0xD1, 0xD1, 0xD9, 0xD2, 0xCD, 0xCD, 0xC4, 0xBF, 0xBF, 0xBF, 0xBF, 0xBF, 0xC9, 0xCF, 0xD0, +0x6A, 0x53, 0x4F, 0x3F, 0x3C, 0x3B, 0x38, 0x37, 0x38, 0x39, 0x3A, 0x3E, 0x44, 0x4A, 0x56, 0x75, +0xE7, 0xD7, 0xCD, 0xCB, 0xCA, 0xC9, 0xCA, 0xCD, 0xCE, 0xCF, 0xD3, 0xCE, 0xCA, 0xC7, 0xC0, 0xBE, +0xBE, 0xBF, 0xBF, 0xC1, 0xCD, 0xD2, 0xDB, 0x5C, 0x4F, 0x4A, 0x3E, 0x3C, 0x3B, 0x39, 0x38, 0x3A, +0x3A, 0x3C, 0x43, 0x46, 0x4E, 0x71, 0x7A, 0xDD, 0xCE, 0xD0, 0xCB, 0xCA, 0xCD, 0xCC, 0xD1, 0xD2, +0xD5, 0xD7, 0xCC, 0xCC, 0xC7, 0xBE, 0xBF, 0xBF, 0xBE, 0xC0, 0xC6, 0xCD, 0xD5, 0xEE, 0x54, 0x4D, +0x45, 0x3C, 0x3B, 0x39, 0x37, 0x38, 0x39, 0x3A, 0x3E, 0x44, 0x4A, 0x59, 0x71, 0xE8, 0xD4, 0xCE, +0xCC, 0xC9, 0xCB, 0xCB, 0xCE, 0xD2, 0xD4, 0xD7, 0xD2, 0xCD, 0xCB, 0xC4, 0xBF, 0xBF, 0xC0, 0xC0, +0xC0, 0xC9, 0xD1, 0xD8, 0x73, 0x52, 0x4B, 0x42, 0x3C, 0x3A, 0x39, 0x38, 0x38, 0x39, 0x3C, 0x3F, +0x41, 0x4E, 0x5D, 0x63, 0xDF, 0xD3, 0xD1, 0xCD, 0xCB, 0xCC, 0xD1, 0xD1, 0xD3, 0xDE, 0xDA, 0xD1, +0xCF, 0xCC, 0xC4, 0xBF, 0xC2, 0xC2, 0xBF, 0xC6, 0xCD, 0xD2, 0xE3, 0x63, 0x4F, 0x4A, 0x42, 0x3C, +0x3B, 0x3A, 0x39, 0x3A, 0x3B, 0x3F, 0x42, 0x47, 0x5A, 0x62, 0x7C, 0xD5, 0xD2, 0xCF, 0xCC, 0xCD, +0xCE, 0xD5, 0xD6, 0xD9, 0xE0, 0xD9, 0xD2, 0xCE, 0xCB, 0xC4, 0xBF, 0xC2, 0xC2, 0xBF, 0xC6, 0xCD, +0xD4, 0xE2, 0x67, 0x4F, 0x4B, 0x43, 0x3D, 0x3C, 0x3B, 0x3B, 0x3B, 0x3C, 0x42, 0x43, 0x49, 0x60, +0x6B, 0xF5, 0xD4, 0xD2, 0xD0, 0xD2, 0xD2, 0xD4, 0xDF, 0xDD, 0xDF, 0xEA, 0xDC, 0xD5, 0xD0, 0xCB, +0xC4, 0xC0, 0xC2, 0xBF, 0xC0, 0xC7, 0xC9, 0xD0, 0xDD, 0x7A, 0x57, 0x52, 0x48, 0x3F, 0x3F, 0x3D, +0x3C, 0x3C, 0x3D, 0x42, 0x44, 0x49, 0x5B, 0x64, 0x7C, 0xDE, 0xDB, 0xDB, 0xDC, 0xDA, 0xDF, 0xEE, +0xE9, 0xE6, 0xE8, 0xE3, 0xDB, 0xD0, 0xCD, 0xCC, 0xC5, 0xC3, 0xC5, 0xC2, 0xC3, 0xC8, 0xCD, 0xD1, +0xDE, 0x6F, 0x5B, 0x50, 0x4A, 0x44, 0x40, 0x3F, 0x3E, 0x3E, 0x42, 0x43, 0x47, 0x4F, 0x58, 0x5F, +0x69, 0xF6, 0xED, 0xF7, 0xEB, 0xE8, 0xEA, 0xEC, 0xE8, 0xE0, 0xE0, 0xDD, 0xD7, 0xD0, 0xCE, 0xCC, +0xC8, 0xC7, 0xC6, 0xC4, 0xC8, 0xC9, 0xCB, 0xD2, 0xDA, 0xEF, 0x71, 0x5B, 0x4F, 0x4E, 0x49, 0x45, +0x46, 0x45, 0x47, 0x47, 0x4A, 0x4E, 0x4E, 0x54, 0x5A, 0x5D, 0x62, 0x65, 0x70, 0x6C, 0x69, 0xFA, +0x7A, 0x7A, 0xE6, 0xE2, 0xDF, 0xDA, 0xD5, 0xCF, 0xD1, 0xD1, 0xCB, 0xCE, 0xD4, 0xCE, 0xD1, 0xD9, +0xDB, 0xE0, 0xE1, 0xEE, 0x6A, 0x74, 0x6C, 0x5A, 0x5B, 0x5A, 0x56, 0x56, 0x53, 0x56, 0x57, 0x53, +0x57, 0x5B, 0x59, 0x59, 0x5D, 0x65, 0x60, 0x61, 0x6F, 0x73, 0xF7, 0xEF, 0xEA, 0xDD, 0xDF, 0xDC, +0xD5, 0xD8, 0xDC, 0xDC, 0xDA, 0xDF, 0xE5, 0xE1, 0xEB, 0xED, 0xED, 0xFC, 0xFF, 0x70, 0x6C, 0x6C, +0x66, 0x5F, 0x5F, 0x62, 0x5F, 0x60, 0x60, 0x5A, 0x5F, 0x64, 0x5C, 0x64, 0x6E, 0x5F, 0x5E, 0x69, +0x6B, 0x7B, 0xF0, 0xFA, 0xE9, 0xE4, 0xE8, 0xDF, 0xE6, 0xEB, 0xE1, 0xE2, 0xE6, 0xE3, 0xE8, 0xED, +0xE5, 0xFC, 0x71, 0xE9, 0xFE, 0x7A, 0xEC, 0x73, 0x7E, 0x77, 0x64, 0xFD, 0x74, 0x66, 0x7B, 0x6C, +0x6B, 0x72, 0x6A, 0x79, 0x73, 0x71, 0xF4, 0x79, 0xFC, 0xEF, 0xF9, 0xEB, 0xF1, 0xF0, 0xE2, 0xE3, +0xE0, 0xE2, 0xE3, 0xEB, 0xFC, 0xEA, 0xF8, 0x6F, 0x70, 0x69, 0x77, 0x6C, 0x6D, 0xEF, 0x6B, 0x67, +0x6D, 0x65, 0x76, 0x75, 0x6F, 0x7E, 0x69, 0x67, 0x6F, 0x68, 0x6F, 0x73, 0x68, 0x69, 0x68, 0x69, +0x75, 0xFA, 0xEE, 0xF2, 0xEA, 0xDE, 0xE2, 0xE7, 0xE5, 0xEB, 0xF3, 0xED, 0xE8, 0xF7, 0x7F, 0xFA, +0x74, 0x6A, 0x68, 0x65, 0x66, 0x68, 0x64, 0x65, 0x68, 0x64, 0x6D, 0x77, 0x72, 0x70, 0x69, 0x77, +0x78, 0x64, 0x6B, 0x68, 0x60, 0x66, 0x67, 0x67, 0x61, 0x6D, 0xEB, 0xE8, 0xEC, 0xEB, 0xEA, 0xF7, +0xF5, 0xE2, 0xE5, 0xF6, 0xF8, 0xF0, 0x7E, 0x77, 0xFA, 0x76, 0x77, 0x7D, 0x6E, 0x74, 0x74, 0x72, +0x72, 0x6D, 0x75, 0x74, 0x74, 0x75, 0x76, 0xEF, 0xEE, 0xEF, 0xEA, 0xFA, 0x7F, 0xF2, 0xF6, 0xF7, +0xEF, 0xEA, 0xE4, 0xE5, 0xE7, 0xE3, 0xE9, 0xEC, 0xE8, 0xEB, 0xF0, 0xF8, 0xFC, 0x7F, 0x73, 0x73, +0x70, 0x72, 0x75, 0x69, 0x67, 0x6A, 0x6C, 0x6D, 0x6C, 0x70, 0x6D, 0x6D, 0x78, 0x72, 0x6F, 0x6E, +0x6C, 0x6F, 0x77, 0xF7, 0xEF, 0xF1, 0xF6, 0xF4, 0xF1, 0xFC, 0xF8, 0xEE, 0xF0, 0xEE, 0xEF, 0xEF, +0xEC, 0xEE, 0xF3, 0xF4, 0x76, 0x69, 0x77, 0xFA, 0x70, 0x75, 0x7E, 0x6E, 0x6D, 0x6E, 0x6E, 0x6E, +0x6D, 0x70, 0x74, 0x79, 0xFE, 0x7D, 0x78, 0x7C, 0x7A, 0x75, 0x78, 0x75, 0x70, 0x7C, 0xFC, 0xFB, +0xF4, 0xF3, 0xED, 0xEC, 0xF6, 0xF1, 0xEF, 0xF6, 0xF0, 0xFB, 0x7A, 0x7C, 0x74, 0x79, 0x74, 0x6C, +0x6C, 0x63, 0x67, 0x6C, 0x62, 0x66, 0x67, 0x68, 0x6C, 0x6A, 0x7D, 0x78, 0x6B, 0x7B, 0x71, 0x75, +0xFB, 0x75, 0x76, 0x7E, 0xEE, 0xED, 0xFA, 0xE8, 0xEE, 0x7F, 0xE4, 0xE9, 0xED, 0xE1, 0xEC, 0xEE, +0xE6, 0xF6, 0xFE, 0xF7, 0xFF, 0x7B, 0x72, 0x7C, 0x7F, 0x6B, 0x6C, 0x66, 0x67, 0x71, 0x66, 0x72, +0xFF, 0x69, 0x7B, 0xF7, 0xFF, 0xF3, 0xF6, 0xF3, 0xF2, 0xEE, 0xED, 0xFF, 0xF6, 0xED, 0xFB, 0xF2, +0xE9, 0xF0, 0xEC, 0xE6, 0xF4, 0xF2, 0xF5, 0x7C, 0xED, 0x7E, 0x6B, 0x7B, 0x77, 0xFE, 0x7A, 0x69, +0x68, 0x60, 0x65, 0x66, 0x61, 0x71, 0x74, 0x74, 0xFC, 0x7E, 0xFA, 0xFF, 0x7E, 0xF9, 0xFB, 0xEE, +0xED, 0xEF, 0xEF, 0xF4, 0xEC, 0xEC, 0xF2, 0xF0, 0xEF, 0xED, 0xF4, 0xF6, 0xEF, 0xFD, 0xF8, 0xF1, +0x77, 0x74, 0x7A, 0x70, 0x6F, 0x79, 0x76, 0x6A, 0x68, 0x6C, 0x6C, 0x69, 0x65, 0x66, 0x6E, 0x73, +0x6C, 0x6D, 0x7A, 0x79, 0x7A, 0xFE, 0x73, 0x72, 0x7A, 0x7E, 0xF3, 0xEF, 0xEE, 0xF1, 0xF6, 0xEC, +0xEF, 0xFA, 0xEE, 0xF5, 0xFE, 0xF2, 0xF0, 0xF7, 0xFA, 0xF9, 0xFB, 0xFB, 0x7A, 0x6B, 0x6B, 0x72, +0x6C, 0x6A, 0x76, 0x74, 0x6E, 0x72, 0x6C, 0x6B, 0x6F, 0x6B, 0x6E, 0x71, 0x6D, 0x75, 0x76, 0x70, +0x78, 0x7C, 0xFA, 0xF2, 0xF7, 0xF1, 0xED, 0xF3, 0xF4, 0xF6, 0xFA, 0xF0, 0xEF, 0xFD, 0x7B, 0xFF, +0x78, 0x6C, 0x70, 0x72, 0x6E, 0x73, 0x6D, 0x6D, 0x6D, 0x65, 0x65, 0x69, 0x6F, 0x70, 0x6B, 0x6E, +0x71, 0x6E, 0x6E, 0x6F, 0x7A, 0x7D, 0x7E, 0xEF, 0xF4, 0x7D, 0xFB, 0xF3, 0xEC, 0xEB, 0xF0, 0xEF, +0xEE, 0xEE, 0xF3, 0xF0, 0xED, 0xFF, 0xFF, 0xF3, 0x7E, 0xFB, 0xFF, 0x73, 0x7E, 0x7A, 0x76, 0x6F, +0x6C, 0x7A, 0x74, 0x6F, 0xFF, 0x7B, 0x79, 0xF7, 0xF5, 0xFB, 0xF6, 0xF3, 0x7E, 0x7D, 0xFA, 0xFD, +0xF6, 0xF5, 0x7D, 0x7B, 0x7A, 0xFF, 0xFB, 0x7D, 0x75, 0x76, 0xF3, 0xF3, 0x78, 0xFE, 0x76, 0x6B, +0x7B, 0xFB, 0x75, 0x69, 0x6C, 0xF6, 0xF6, 0x7B, 0x6F, 0x69, 0x6E, 0x72, 0x70, 0x74, 0x78, 0xFF, +0x7F, 0xFD, 0xF5, 0xF8, 0xF5, 0xF9, 0x75, 0x74, 0x7D, 0xF7, 0xFB, 0x70, 0x7E, 0xE9, 0xEF, 0xF7, +0xE6, 0xED, 0x74, 0x7A, 0xF7, 0x7D, 0x71, 0x77, 0xFE, 0xF6, 0xFC, 0x6B, 0x6B, 0x72, 0x69, 0x6D, +0x7B, 0x7C, 0xFD, 0x6F, 0x6B, 0xFC, 0x7F, 0x73, 0xF9, 0xF5, 0x70, 0x6E, 0xFD, 0xFF, 0x7C, 0xFB, +0x70, 0x76, 0xEF, 0x7D, 0x75, 0xFB, 0xF6, 0xEF, 0xF6, 0x7C, 0x79, 0x76, 0xFE, 0x7D, 0x73, 0xFD, +0xFE, 0x76, 0x6E, 0x66, 0x6B, 0x75, 0x6D, 0x7D, 0xF2, 0x6D, 0x75, 0xED, 0x7A, 0x6D, 0x7E, 0xF9, +0xFE, 0x6E, 0x78, 0xF4, 0x6E, 0x73, 0xF8, 0x74, 0xFF, 0xFE, 0x77, 0xF6, 0x7C, 0x71, 0x7F, 0x7E, +0x7E, 0x79, 0x78, 0x7C, 0x6E, 0x6F, 0x70, 0x6D, 0xFD, 0xFA, 0x6C, 0x6B, 0x71, 0x70, 0x7B, 0x7A, +0x7C, 0xFD, 0x6D, 0x75, 0xED, 0xF8, 0xFC, 0xF7, 0xFB, 0xEE, 0xEF, 0x79, 0xFF, 0xED, 0xF8, 0x7A, +0xF1, 0xED, 0xF7, 0xFC, 0xF8, 0xF1, 0xF8, 0x79, 0x7D, 0xF6, 0x78, 0x6E, 0xFD, 0xFB, 0x72, 0x6E, +0x6C, 0x74, 0xFE, 0xFF, 0xF7, 0xFE, 0x6D, 0x75, 0x79, 0x6F, 0x7C, 0x7D, 0x76, 0x78, 0x7A, 0x7F, +0x75, 0x7D, 0xF7, 0xF8, 0xEF, 0x7B, 0x7A, 0xF3, 0xFF, 0xEF, 0xF8, 0xFE, 0xF6, 0x6E, 0xF4, 0xED, +0x6F, 0x7C, 0x74, 0x75, 0xF2, 0x7C, 0x75, 0xF9, 0xEE, 0xFF, 0x70, 0x7C, 0x7F, 0xFD, 0xFD, 0xFA, +0x79, 0x6C, 0x7C, 0x7F, 0xFD, 0xF3, 0x78, 0xFE, 0xF7, 0xFC, 0xED, 0xF1, 0xFD, 0xFE, 0x7D, 0xF4, +0xED, 0xF4, 0xFA, 0xFD, 0x70, 0x73, 0xF6, 0xFF, 0x7D, 0xF7, 0x79, 0x72, 0x78, 0x7D, 0x77, 0x6E, +0x71, 0x6C, 0x6A, 0x7D, 0x74, 0x71, 0x7D, 0x6E, 0x79, 0xF8, 0x70, 0x7C, 0xFE, 0x6D, 0x6F, 0x6E, +0x6D, 0x7D, 0xFD, 0xFB, 0xFA, 0x7C, 0xFD, 0xFA, 0xF7, 0xF4, 0xFD, 0x7B, 0x76, 0x7D, 0xF3, 0xF5, +0xFD, 0xF5, 0xED, 0x7A, 0x6D, 0xF5, 0x7C, 0x76, 0xEF, 0x77, 0x6E, 0xFF, 0x74, 0x79, 0xFD, 0x76, +0x7A, 0x7E, 0x7B, 0x7D, 0x78, 0x73, 0x7A, 0xFB, 0xFB, 0x7E, 0xFB, 0xF2, 0xF8, 0xF9, 0xFB, 0xFE, +0xF5, 0xF6, 0xF9, 0x7E, 0x73, 0xF7, 0xFA, 0x74, 0xFC, 0x7B, 0x70, 0xFF, 0xFC, 0x7E, 0x7C, 0xFE, +0xFF, 0x7C, 0xFC, 0x7E, 0x79, 0xFF, 0x7C, 0x79, 0x79, 0x79, 0x7A, 0x79, 0x7A, 0x7C, 0x7A, 0x75, +0x72, 0x7C, 0xFC, 0xFE, 0xFE, 0xFC, 0xF9, 0xFE, 0xFE, 0xFA, 0x7C, 0xFD, 0xFC, 0x77, 0x7B, 0x7A, +0x73, 0x78, 0x7A, 0x78, 0x7B, 0x77, 0x6E, 0x70, 0x7B, 0x7A, 0x72, 0x74, 0x76, 0x75, 0x77, 0x75, +0x70, 0x6F, 0x6F, 0x6F, 0x74, 0x77, 0x72, 0x6F, 0x70, 0x79, 0x79, 0x6F, 0x7E, 0xFA, 0x72, 0x79, +0x79, 0x78, 0xFE, 0x78, 0xFF, 0xFE, 0x76, 0xFF, 0xFF, 0x7D, 0xFF, 0x7E, 0x7B, 0x78, 0x7C, 0x75, +0x75, 0xFF, 0xFF, 0xF8, 0xF6, 0xFD, 0xF5, 0xF4, 0xF6, 0xFC, 0x7C, 0x7C, 0x7B, 0xFC, 0xFD, 0xFD, +0xFD, 0x77, 0x7A, 0x7F, 0x7E, 0xFC, 0xFA, 0xF7, 0xFF, 0xFE, 0xF1, 0xFD, 0xFD, 0xF0, 0xF9, 0xF8, +0xEE, 0xEF, 0xF8, 0x7E, 0x79, 0x77, 0x6C, 0x66, 0x6A, 0x68, 0x67, 0x71, 0x74, 0x77, 0x7E, 0x7B, +0xFD, 0xFD, 0x7F, 0xFF, 0x79, 0xFE, 0xFE, 0x75, 0x78, 0x7A, 0x74, 0x70, 0x76, 0x77, 0x75, 0x7C, +0x7C, 0x79, 0x78, 0x77, 0x78, 0x7C, 0x7E, 0x77, 0x74, 0x79, 0x77, 0x78, 0x78, 0x77, 0x7B, 0x78, +0x77, 0x77, 0x7A, 0xFE, 0x7D, 0xFE, 0xF6, 0xFB, 0xFC, 0xF8, 0xF6, 0xFA, 0xFD, 0xFB, 0xFC, 0x7D, +0x7B, 0xFB, 0xF5, 0xFC, 0xFF, 0xFD, 0xFE, 0xFF, 0x7F, 0xFC, 0xF8, 0xFF, 0x7F, 0xF7, 0xF9, 0xFA, +0xF9, 0xFB, 0xFA, 0xFA, 0xFA, 0xF8, 0xF8, 0xFD, 0x7E, 0xF8, 0xF7, 0xEF, 0xE0, 0xE1, 0xF7, 0x6E, +0x69, 0x65, 0x5C, 0x5B, 0x61, 0x69, 0x6E, 0x76, 0xF8, 0xEF, 0xF2, 0xEB, 0xE3, 0xDE, 0xE2, 0xFA, +0x66, 0x5B, 0x5F, 0x6E, 0x6E, 0xFB, 0xED, 0xED, 0xEC, 0xF8, 0x7E, 0x7B, 0x6E, 0x67, 0x60, 0x65, +0x6E, 0x6F, 0x78, 0xFB, 0x7E, 0x7D, 0xFA, 0xF9, 0xF7, 0xF5, 0xF7, 0xEE, 0xEB, 0xF3, 0xFA, 0x7A, +0x6D, 0x69, 0x6A, 0x69, 0x64, 0x69, 0x6E, 0x6F, 0x78, 0xFB, 0xFB, 0x7C, 0xF8, 0xF1, 0xFB, 0xF4, +0xF9, 0x7D, 0xF8, 0x7D, 0xFD, 0xF3, 0x7C, 0xFD, 0xF4, 0x7A, 0x6F, 0x79, 0xFF, 0x75, 0x78, 0xFA, +0xFB, 0xFE, 0xFB, 0xF9, 0xFE, 0xFF, 0xFF, 0xFC, 0xF5, 0xFD, 0x79, 0xFF, 0xF9, 0xFA, 0xFF, 0xFF, +0x7B, 0x74, 0x75, 0x6F, 0x71, 0x7D, 0x74, 0x75, 0x79, 0x71, 0x77, 0x7E, 0x7E, 0x7C, 0x74, 0x71, +0x77, 0x7A, 0x7F, 0xFB, 0x72, 0x69, 0x74, 0x74, 0x6A, 0x74, 0x7E, 0x79, 0x76, 0x74, 0x7F, 0x7C, +0x76, 0xF8, 0xF8, 0x7E, 0x7D, 0x7E, 0xFE, 0x77, 0x7B, 0xF8, 0x7B, 0xFF, 0xF3, 0xFC, 0xFF, 0xFE, +0xFD, 0xF5, 0xF6, 0xF3, 0xF2, 0xFA, 0xF8, 0xF3, 0xFB, 0x7E, 0xFA, 0xFA, 0x7E, 0xFE, 0xFC, 0x7C, +0x78, 0x7D, 0xFB, 0xF3, 0xFD, 0x74, 0xF7, 0xF5, 0x76, 0xF9, 0xF8, 0xFF, 0xF5, 0x76, 0x7B, 0xFA, +0x77, 0xFD, 0x7C, 0x77, 0x7D, 0x6F, 0x7D, 0xF7, 0xFC, 0xFD, 0x7B, 0xF5, 0xF8, 0x7A, 0xF4, 0xFB, +0x77, 0x7B, 0x76, 0x74, 0x7D, 0x7E, 0x72, 0x71, 0x70, 0x70, 0x77, 0x70, 0x7B, 0xFD, 0x6F, 0x72, +0x7D, 0x7A, 0x71, 0x79, 0xF8, 0x77, 0x6F, 0x74, 0x7A, 0x78, 0x7C, 0xF6, 0x7C, 0xFB, 0x7D, 0x6C, +0xEF, 0xFC, 0x6D, 0xF1, 0xF5, 0x7D, 0x79, 0xFA, 0xF5, 0x75, 0xF4, 0x7C, 0xFC, 0xE6, 0x68, 0x78, +0xE4, 0x6E, 0x77, 0xF2, 0x7E, 0x70, 0x69, 0xF9, 0xF7, 0x6C, 0x74, 0xF3, 0xEE, 0x79, 0x7E, 0xFB, +0x7A, 0xF6, 0x6C, 0x6B, 0xED, 0x77, 0x6A, 0x70, 0x6F, 0xFC, 0x7E, 0x79, 0xF2, 0xEE, 0xF8, 0x7D, +0xEF, 0xEB, 0x7E, 0x72, 0x7D, 0x74, 0x6B, 0xFA, 0xE5, 0xE7, 0xE4, 0xEB, 0xF8, 0xEC, 0xEA, 0xF3, +0xFB, 0xFA, 0xEF, 0xF6, 0x7C, 0xFF, 0x7B, 0x72, 0x78, 0x7C, 0x6F, 0x6E, 0xFF, 0xFF, 0x75, 0x74, +0x74, 0x76, 0x6C, 0x6A, 0x7F, 0x78, 0x6D, 0x74, 0x6E, 0x76, 0x7B, 0x69, 0x6B, 0x79, 0x72, 0x6A, +0x6D, 0x77, 0xFD, 0xFC, 0x6F, 0x7C, 0xEE, 0x76, 0x69, 0x74, 0xFB, 0x74, 0x6A, 0x7D, 0xF0, 0xFF, +0x6B, 0x71, 0xEF, 0x7D, 0x74, 0xF8, 0x75, 0x74, 0x77, 0x6C, 0x6E, 0x71, 0x73, 0x72, 0x70, 0xF4, +0xF0, 0x79, 0x7B, 0xFB, 0xF3, 0xF4, 0x78, 0x79, 0xF7, 0xFC, 0x6E, 0x70, 0xF8, 0xF8, 0x79, 0x6D, +0x70, 0xFB, 0x6E, 0x64, 0x6B, 0x72, 0x6F, 0x65, 0x71, 0xFC, 0x71, 0x76, 0x6E, 0x71, 0xF9, 0xFF, +0xFD, 0x73, 0x7A, 0xFF, 0x66, 0x70, 0xFE, 0x79, 0xFD, 0x7D, 0xF1, 0xF6, 0x76, 0x79, 0x6D, 0x79, +0xFF, 0x72, 0x7F, 0xF8, 0xF0, 0xFF, 0x71, 0xEC, 0xE9, 0x7C, 0x7C, 0xF1, 0xF7, 0xF7, 0xF5, 0xFA, +0xF1, 0x7C, 0x70, 0x7D, 0xFB, 0xF4, 0x7C, 0x7D, 0xF6, 0xFD, 0xEF, 0xF6, 0xEE, 0xE1, 0xEE, 0xF4, +0xF3, 0xEE, 0xF4, 0x78, 0xEC, 0xF7, 0x72, 0x74, 0x6E, 0xF5, 0x6A, 0x7B, 0xDF, 0x69, 0x7F, 0xE7, +0x6F, 0x7C, 0x68, 0xF4, 0xEE, 0x5C, 0x72, 0x6B, 0x6D, 0xEC, 0x60, 0x7E, 0xEB, 0x66, 0x6D, 0x6A, +0x7A, 0xFF, 0x6A, 0x6E, 0x74, 0xED, 0x79, 0x6B, 0xED, 0xFA, 0xFC, 0x70, 0x65, 0xF6, 0x75, 0x67, +0x78, 0x78, 0xF4, 0xFF, 0x5F, 0xF9, 0xE3, 0x6D, 0xF1, 0x7A, 0x70, 0xDB, 0x6A, 0xF9, 0xDC, 0x66, +0xDB, 0xF8, 0x65, 0xD6, 0x6A, 0xF2, 0xE6, 0x5E, 0xE1, 0x76, 0x6F, 0xF5, 0x65, 0xEF, 0x5F, 0x66, +0x6F, 0x5A, 0xFB, 0x5E, 0x65, 0x7E, 0x60, 0xF2, 0x5D, 0x72, 0xE8, 0x5A, 0xEA, 0x6E, 0x62, 0xE4, +0x5E, 0x6F, 0x74, 0x67, 0xEA, 0x64, 0x77, 0xF3, 0x69, 0xF1, 0x6B, 0x6E, 0xEB, 0x74, 0x74, 0x74, +0xF6, 0xF5, 0x66, 0xF5, 0xF7, 0x6C, 0xE9, 0x70, 0x6F, 0xE4, 0x6E, 0xF0, 0xF4, 0x63, 0xE1, 0xFE, +0x6D, 0xE4, 0x6D, 0xF2, 0xEF, 0x6C, 0xE8, 0x7B, 0xFC, 0xED, 0x74, 0xEB, 0xFE, 0xFC, 0xEF, 0x6D, +0xEC, 0xFB, 0x71, 0xEB, 0x77, 0xF3, 0xF8, 0x6F, 0xE9, 0xFE, 0xFC, 0xEE, 0x6F, 0xEB, 0xED, 0x7A, +0xEE, 0xF4, 0xF3, 0xF8, 0xF1, 0xEE, 0x79, 0xF4, 0xF3, 0xFC, 0xF1, 0x7C, 0xF4, 0xF9, 0x76, 0xE8, +0xF8, 0x75, 0xE3, 0x7B, 0x6E, 0xE0, 0x75, 0x72, 0xE3, 0x6C, 0xF8, 0xE7, 0x6D, 0xEA, 0xF4, 0x75, +0xEA, 0x71, 0xFA, 0xED, 0x6A, 0xF2, 0xFB, 0x70, 0xEB, 0x6F, 0x71, 0xEE, 0x6C, 0xF6, 0xF2, 0x68, +0xF3, 0xF8, 0x6D, 0x7A, 0xFC, 0x75, 0x6D, 0xF3, 0x6E, 0x6E, 0xEE, 0x61, 0x7C, 0xFE, 0x60, 0xF2, +0x6D, 0x78, 0x7C, 0x63, 0xEB, 0x64, 0x71, 0xED, 0x5C, 0xEB, 0x6F, 0x69, 0xEA, 0x5D, 0xE7, 0xF8, +0x5E, 0xE6, 0x6F, 0xFA, 0x79, 0x72, 0xE8, 0x5E, 0xE9, 0xFB, 0x5F, 0xDE, 0x61, 0xFA, 0xE3, 0x5A, +0xE3, 0x79, 0x62, 0xDF, 0x64, 0x76, 0xE4, 0x63, 0xFE, 0xE9, 0x64, 0xF8, 0xE6, 0x5F, 0xF2, 0xE8, +0x62, 0xE7, 0xFB, 0x6A, 0xF0, 0x77, 0xF9, 0x77, 0xE9, 0x78, 0x59, 0xE3, 0x71, 0x6C, 0xDF, 0x5F, +0xEF, 0xE9, 0x5F, 0xFA, 0x76, 0xF9, 0x7D, 0x67, 0xEE, 0x7B, 0x6F, 0x7E, 0x6B, 0x6D, 0xF7, 0x6E, +0x6B, 0xF0, 0x63, 0xF0, 0x75, 0x57, 0xD4, 0x59, 0x57, 0xCD, 0x4F, 0xEE, 0xDE, 0x4B, 0xCF, 0x68, +0x5B, 0xD4, 0x50, 0xE0, 0xEF, 0x54, 0xD5, 0x57, 0x6A, 0xD3, 0x54, 0x79, 0xDF, 0x5E, 0xFC, 0xE6, +0x5F, 0x71, 0xE0, 0x64, 0x76, 0xFC, 0x5D, 0xEA, 0xF8, 0x58, 0x79, 0xDB, 0x68, 0x59, 0xDF, 0x76, +0x64, 0xDA, 0x63, 0x5A, 0xD9, 0xE0, 0x51, 0xF3, 0xD3, 0x4D, 0xDE, 0xCF, 0x3F, 0xDA, 0xC2, 0x41, +0x6A, 0xC3, 0x50, 0x55, 0xC6, 0x5A, 0x4B, 0xC2, 0x7A, 0x46, 0xCA, 0xDF, 0x4C, 0xD8, 0xDE, 0x4F, +0xE2, 0xD2, 0x4D, 0x6B, 0xCD, 0x5C, 0x56, 0xD8, 0xEB, 0x54, 0xEF, 0xDE, 0x4F, 0x78, 0xD7, 0x54, +0x5B, 0xDA, 0xFA, 0x56, 0xF6, 0xE9, 0x58, 0xF1, 0xE5, 0x59, 0x6D, 0xE8, 0x7B, 0x64, 0x7E, 0xE2, +0x60, 0x6D, 0xDC, 0x63, 0x67, 0xDC, 0x6F, 0x62, 0xE2, 0x7B, 0x60, 0xEC, 0xF3, 0x67, 0x77, 0xF1, +0x7C, 0x75, 0xF0, 0x79, 0x6F, 0xED, 0x76, 0x6B, 0xF3, 0xFF, 0x74, 0xF4, 0xF8, 0x6B, 0x6C, 0xE6, +0xE7, 0x61, 0x79, 0xDD, 0x6F, 0x77, 0xDE, 0x6D, 0x6E, 0xE4, 0x7E, 0xF9, 0xE8, 0x6D, 0x6F, 0xDE, +0xEF, 0x5C, 0xEF, 0xDB, 0x64, 0x6B, 0xDF, 0xF9, 0x6C, 0xF4, 0xF5, 0x72, 0xF5, 0xF7, 0x66, 0x7D, +0xE9, 0x7D, 0x70, 0x79, 0xF6, 0x7B, 0x6C, 0xF3, 0xF2, 0x6A, 0x76, 0xED, 0x79, 0x6B, 0xF2, 0xF1, +0x6B, 0x78, 0xEF, 0x73, 0x74, 0xED, 0x73, 0x6A, 0xEB, 0xF2, 0x64, 0x6F, 0xE2, 0xF8, 0x5E, 0xF3, +0xE8, 0x64, 0x74, 0xEF, 0x7B, 0x77, 0x74, 0x78, 0x6D, 0xF8, 0xEA, 0x63, 0x68, 0xEC, 0xEF, 0x6E, +0x63, 0xEE, 0xFA, 0x5F, 0xE5, 0xEB, 0x58, 0x73, 0xD1, 0xF3, 0x4D, 0xF2, 0xCD, 0x5D, 0x54, 0xDF, +0xDD, 0x61, 0x5B, 0xD9, 0xDF, 0x50, 0xF0, 0xD3, 0x5F, 0x5D, 0xE4, 0xDF, 0x6E, 0x5B, 0xED, 0xD8, +0x68, 0x56, 0xEA, 0xD3, 0x70, 0x52, 0xF0, 0xD3, 0x74, 0x57, 0xF5, 0xD8, 0x6A, 0x58, 0xE4, 0xE2, +0x5C, 0x7A, 0xD8, 0x77, 0x5A, 0xE8, 0xD9, 0x73, 0x5F, 0x7D, 0xE3, 0xEC, 0x73, 0x72, 0x6E, 0xF6, +0xDF, 0xF7, 0x62, 0x6B, 0xE5, 0xDD, 0x6B, 0x58, 0xF7, 0xDB, 0x73, 0x5E, 0x75, 0x7E, 0xF6, 0xFE, +0x66, 0x71, 0x7B, 0x7E, 0xEE, 0x6C, 0x6B, 0xEB, 0x76, 0x6C, 0xEA, 0x7A, 0x67, 0xE5, 0xE8, 0x5F, +0x75, 0xDE, 0xEE, 0x6F, 0x7A, 0xED, 0xE8, 0xF8, 0xFB, 0xF4, 0x78, 0xF1, 0xE4, 0x6E, 0x62, 0xEB, +0xEC, 0x65, 0x6D, 0x7E, 0x6B, 0x69, 0x6E, 0x72, 0x78, 0x68, 0x5E, 0x74, 0xE9, 0x6F, 0x5E, 0x72, +0xEB, 0x7A, 0x6F, 0xF1, 0x78, 0x75, 0xE5, 0xE6, 0xE2, 0xDD, 0xE0, 0xD6, 0xD1, 0xD5, 0xD1, 0xD3, +0xDE, 0xE0, 0xDD, 0xE9, 0x68, 0x57, 0x52, 0x50, 0x4B, 0x48, 0x48, 0x48, 0x48, 0x4B, 0x51, 0x56, +0x56, 0x5D, 0x68, 0x6A, 0x69, 0x7C, 0xE8, 0xED, 0xED, 0xDC, 0xD5, 0xCD, 0xCB, 0xCD, 0xC5, 0xBE, +0xBE, 0xBC, 0xBC, 0xBF, 0xC5, 0xD2, 0x72, 0x52, 0x48, 0x40, 0x3C, 0x39, 0x39, 0x3B, 0x3D, 0x40, +0x4A, 0x5A, 0x6C, 0x7E, 0xDF, 0xCF, 0xCE, 0xDB, 0x6F, 0x63, 0x6E, 0x60, 0x4D, 0x47, 0x4D, 0x5E, +0x7C, 0xFA, 0xE4, 0xCD, 0xC1, 0xBD, 0xBC, 0xBA, 0xB7, 0xB4, 0xB5, 0xBE, 0xD7, 0xEB, 0xF2, 0x4E, +0x3B, 0x36, 0x37, 0x39, 0x38, 0x39, 0x3D, 0x48, 0x58, 0xFE, 0xDA, 0xD6, 0xD8, 0xCF, 0xC8, 0xCD, +0xF3, 0x5A, 0x59, 0x58, 0x4E, 0x47, 0x48, 0x4F, 0x5F, 0xF2, 0xD9, 0xCE, 0xC6, 0xBF, 0xBB, 0xBA, +0xB9, 0xB7, 0xB5, 0xB7, 0xC0, 0xD9, 0x68, 0x57, 0x49, 0x3B, 0x35, 0x35, 0x38, 0x3A, 0x3B, 0x3F, +0x4B, 0x60, 0xE7, 0xD8, 0xD5, 0xD4, 0xCE, 0xCA, 0xCF, 0xF9, 0x59, 0x51, 0x4E, 0x4C, 0x48, 0x46, +0x49, 0x56, 0xFB, 0xD9, 0xD1, 0xC9, 0xBE, 0xB8, 0xB6, 0xB5, 0xB3, 0xB2, 0xB6, 0xC3, 0xE5, 0x60, +0x4E, 0x3F, 0x37, 0x32, 0x34, 0x37, 0x39, 0x3C, 0x41, 0x4E, 0x6F, 0xDA, 0xD2, 0xD4, 0xD1, 0xCA, +0xC9, 0xD7, 0x6F, 0x59, 0x4D, 0x47, 0x47, 0x48, 0x45, 0x46, 0x52, 0xEE, 0xD7, 0xD0, 0xC7, 0xBC, +0xB5, 0xB3, 0xB3, 0xB1, 0xB0, 0xB7, 0xCA, 0x68, 0x4F, 0x45, 0x3B, 0x32, 0x2E, 0x30, 0x35, 0x39, +0x3D, 0x44, 0x52, 0xEC, 0xD0, 0xCF, 0xD3, 0xD0, 0xCD, 0xCF, 0xE3, 0x63, 0x5B, 0x59, 0x52, 0x4D, +0x4C, 0x4F, 0x5A, 0x6D, 0xE5, 0xD2, 0xC8, 0xBE, 0xB9, 0xB5, 0xB3, 0xB1, 0xAF, 0xB1, 0xBD, 0xE3, +0x53, 0x4B, 0x40, 0x35, 0x2E, 0x2F, 0x34, 0x39, 0x3B, 0x3F, 0x4C, 0x75, 0xDA, 0xD6, 0xD2, 0xCE, +0xCE, 0xD0, 0xD9, 0xEF, 0x62, 0x56, 0x55, 0x55, 0x4F, 0x4E, 0x52, 0x61, 0xEF, 0xDB, 0xCC, 0xBF, +0xB9, 0xB5, 0xB3, 0xB0, 0xAE, 0xB4, 0xC8, 0x63, 0x4D, 0x45, 0x39, 0x2E, 0x2C, 0x2F, 0x35, 0x38, +0x3B, 0x43, 0x5A, 0xDD, 0xCE, 0xCD, 0xCC, 0xCB, 0xCD, 0xD2, 0xDE, 0x76, 0x5A, 0x52, 0x53, 0x51, +0x4E, 0x4F, 0x5C, 0x7C, 0xE2, 0xD2, 0xC5, 0xBB, 0xB5, 0xB2, 0xB0, 0xAE, 0xAE, 0xB6, 0xCF, 0x55, +0x48, 0x3F, 0x34, 0x2C, 0x2C, 0x2F, 0x36, 0x39, 0x3D, 0x4A, 0x7D, 0xCE, 0xCA, 0xCB, 0xCB, 0xCB, +0xCD, 0xD9, 0x76, 0x59, 0x4F, 0x4C, 0x4C, 0x4A, 0x4C, 0x54, 0x68, 0xEC, 0xD8, 0xCB, 0xBF, 0xB8, +0xB3, 0xB0, 0xAE, 0xAD, 0xAE, 0xBC, 0xF5, 0x4C, 0x43, 0x39, 0x2E, 0x2A, 0x2D, 0x32, 0x37, 0x3B, +0x44, 0x5F, 0xD5, 0xC8, 0xC7, 0xC9, 0xCB, 0xCE, 0xD3, 0xE9, 0x5A, 0x4D, 0x4D, 0x4D, 0x4B, 0x4B, +0x50, 0x63, 0xF6, 0xDE, 0xCE, 0xC5, 0xBD, 0xB7, 0xB2, 0xB0, 0xAF, 0xAD, 0xAF, 0xBF, 0x5E, 0x45, +0x40, 0x37, 0x2C, 0x29, 0x2D, 0x34, 0x38, 0x3C, 0x48, 0x77, 0xCD, 0xC6, 0xC7, 0xCB, 0xCB, 0xCF, +0xE9, 0x59, 0x4E, 0x4B, 0x47, 0x44, 0x47, 0x4D, 0x57, 0x69, 0xEB, 0xD7, 0xCA, 0xBF, 0xB9, 0xB3, +0xAF, 0xAE, 0xAD, 0xAC, 0xB5, 0xDE, 0x49, 0x43, 0x3B, 0x2D, 0x28, 0x2A, 0x30, 0x36, 0x3A, 0x44, +0x6A, 0xCD, 0xC2, 0xC2, 0xC6, 0xCA, 0xCC, 0xD8, 0x60, 0x4C, 0x48, 0x46, 0x44, 0x43, 0x49, 0x54, +0x68, 0xEC, 0xD8, 0xCB, 0xC2, 0xBC, 0xB8, 0xB2, 0xAF, 0xAE, 0xAE, 0xAE, 0xBA, 0x74, 0x45, 0x3F, +0x36, 0x2C, 0x29, 0x2C, 0x32, 0x37, 0x3E, 0x4E, 0xE3, 0xC7, 0xC2, 0xC5, 0xC6, 0xC8, 0xD2, 0x71, +0x52, 0x4D, 0x49, 0x42, 0x41, 0x47, 0x51, 0x60, 0x7B, 0xDE, 0xCE, 0xC6, 0xC0, 0xBE, 0xB9, 0xB2, +0xAF, 0xAF, 0xAE, 0xAE, 0xBC, 0x6B, 0x47, 0x3F, 0x34, 0x2C, 0x2A, 0x2D, 0x32, 0x39, 0x3F, 0x4F, +0xDF, 0xC5, 0xC4, 0xCD, 0xCA, 0xC7, 0xDB, 0x5A, 0x4E, 0x4D, 0x48, 0x42, 0x40, 0x45, 0x54, 0x6F, +0x74, 0xEC, 0xCD, 0xC4, 0xC4, 0xC1, 0xBB, 0xB3, 0xAF, 0xB0, 0xAE, 0xAE, 0xBC, 0x6F, 0x4A, 0x3F, +0x34, 0x2C, 0x2B, 0x2E, 0x34, 0x3B, 0x42, 0x56, 0xCF, 0xBF, 0xC2, 0xCB, 0xC6, 0xC6, 0xE6, 0x52, +0x4B, 0x47, 0x45, 0x3F, 0x3D, 0x45, 0x5E, 0x7A, 0x72, 0xDB, 0xC7, 0xC3, 0xC5, 0xC2, 0xBC, 0xB5, +0xB1, 0xB3, 0xB0, 0xAE, 0xB9, 0xF0, 0x4C, 0x43, 0x38, 0x2E, 0x2B, 0x2D, 0x34, 0x3A, 0x3E, 0x4F, +0xD3, 0xC1, 0xC4, 0xCD, 0xCC, 0xC8, 0xDE, 0x4D, 0x45, 0x47, 0x47, 0x41, 0x3D, 0x47, 0x6D, 0xF7, +0x79, 0xDA, 0xC9, 0xC6, 0xC8, 0xC9, 0xC0, 0xB8, 0xB4, 0xB5, 0xB0, 0xAC, 0xB1, 0xCF, 0x5A, 0x4E, +0x3E, 0x30, 0x2B, 0x2D, 0x33, 0x38, 0x3B, 0x48, 0xDC, 0xC4, 0xC5, 0xCA, 0xCB, 0xCB, 0xD9, 0x50, +0x46, 0x4B, 0x46, 0x3E, 0x3F, 0x48, 0x55, 0x76, 0x7E, 0xE3, 0xCA, 0xC9, 0xCE, 0xCB, 0xC6, 0xBE, +0xBA, 0xB8, 0xB4, 0xAE, 0xAE, 0xBD, 0xEA, 0x62, 0x48, 0x35, 0x2D, 0x2C, 0x30, 0x35, 0x37, 0x3F, +0x6F, 0xCB, 0xCA, 0xC9, 0xC7, 0xCE, 0xD9, 0x60, 0x46, 0x46, 0x48, 0x40, 0x40, 0x49, 0x52, 0x69, +0xED, 0xE1, 0xD1, 0xCC, 0xD0, 0xD2, 0xD0, 0xCD, 0xC2, 0xBD, 0xB9, 0xB2, 0xAE, 0xAF, 0xBA, 0xE0, +0x67, 0x4C, 0x34, 0x2D, 0x2E, 0x30, 0x34, 0x37, 0x41, 0xF4, 0xCD, 0xCC, 0xC7, 0xC5, 0xD0, 0xED, +0x64, 0x4D, 0x45, 0x47, 0x43, 0x44, 0x4F, 0x51, 0x69, 0xD9, 0xDD, 0xD1, 0xCB, 0xD1, 0xCF, 0xD2, +0xCD, 0xBF, 0xBC, 0xB8, 0xB0, 0xAD, 0xAE, 0xBC, 0xD9, 0x76, 0x48, 0x32, 0x2D, 0x2F, 0x30, 0x32, +0x38, 0x49, 0xE6, 0xD1, 0xCB, 0xC1, 0xC1, 0xD2, 0x7A, 0x6F, 0x51, 0x42, 0x43, 0x45, 0x4A, 0x4D, +0x4E, 0x72, 0xD7, 0xDB, 0xD8, 0xCE, 0xCF, 0xD7, 0xDD, 0xD3, 0xC6, 0xBF, 0xBB, 0xB3, 0xAD, 0xAE, +0xB8, 0xCD, 0xE2, 0x52, 0x35, 0x2E, 0x2F, 0x2F, 0x2F, 0x35, 0x43, 0x62, 0xE5, 0xCF, 0xC1, 0xC0, +0xD1, 0xE1, 0xDB, 0x5E, 0x46, 0x49, 0x4D, 0x4A, 0x49, 0x51, 0x6A, 0xEE, 0xEB, 0xDE, 0xD0, 0xD4, +0xDF, 0xDC, 0xD7, 0xCF, 0xC5, 0xBE, 0xB7, 0xB1, 0xAE, 0xAF, 0xBC, 0xD3, 0xE7, 0x48, 0x31, 0x2E, +0x2F, 0x2E, 0x2F, 0x36, 0x44, 0x5B, 0xF4, 0xCC, 0xBF, 0xC2, 0xD4, 0xD1, 0xCF, 0x59, 0x4B, 0x51, +0x4B, 0x46, 0x44, 0x4C, 0x56, 0x51, 0x66, 0xE5, 0xE6, 0xE0, 0xDF, 0xD6, 0xD1, 0xCD, 0xC0, 0xBB, +0xB7, 0xB0, 0xAD, 0xB0, 0xBD, 0xCE, 0xEF, 0x44, 0x31, 0x2F, 0x30, 0x2E, 0x2E, 0x39, 0x46, 0x56, +0xF0, 0xC7, 0xBD, 0xC2, 0xC9, 0xC8, 0xCC, 0x7A, 0x50, 0x57, 0x4F, 0x42, 0x42, 0x4A, 0x4C, 0x4C, +0x5D, 0xEF, 0xEE, 0xE3, 0xD6, 0xD1, 0xD2, 0xCC, 0xC0, 0xBC, 0xBA, 0xB3, 0xAE, 0xAF, 0xBA, 0xC9, +0xD6, 0x4F, 0x36, 0x30, 0x30, 0x2E, 0x2D, 0x34, 0x3E, 0x45, 0x5C, 0xCF, 0xC1, 0xC0, 0xC1, 0xC0, +0xC9, 0xD9, 0xF5, 0x54, 0x4A, 0x47, 0x40, 0x41, 0x42, 0x45, 0x4E, 0x53, 0x68, 0xE8, 0xE1, 0xD1, +0xCD, 0xCC, 0xC5, 0xBF, 0xBB, 0xB8, 0xB4, 0xAF, 0xB0, 0xBD, 0xCB, 0xD8, 0x4B, 0x36, 0x34, 0x33, +0x2E, 0x2E, 0x37, 0x3D, 0x44, 0x62, 0xCD, 0xC4, 0xC0, 0xBE, 0xBF, 0xC5, 0xCF, 0xEE, 0x66, 0x4F, +0x45, 0x43, 0x40, 0x41, 0x44, 0x47, 0x51, 0x5B, 0x71, 0xDD, 0xD8, 0xCE, 0xC8, 0xC6, 0xC1, 0xBD, +0xB9, 0xB7, 0xB2, 0xAF, 0xB9, 0xC3, 0xCC, 0x71, 0x40, 0x37, 0x36, 0x31, 0x2E, 0x33, 0x3A, 0x3D, +0x4A, 0xE6, 0xCF, 0xC7, 0xBE, 0xBF, 0xC2, 0xCA, 0xD3, 0xE6, 0x50, 0x4C, 0x4B, 0x3E, 0x3E, 0x43, +0x41, 0x47, 0x4D, 0x59, 0x75, 0xE4, 0xD0, 0xCC, 0xC9, 0xC3, 0xBF, 0xBD, 0xBB, 0xB8, 0xB3, 0xB3, +0xBB, 0xC3, 0xCD, 0x6A, 0x42, 0x3A, 0x38, 0x31, 0x30, 0x36, 0x39, 0x3C, 0x4B, 0x7A, 0xDB, 0xCB, +0xC1, 0xC3, 0xC5, 0xC5, 0xD5, 0xE5, 0x6B, 0x4E, 0x4C, 0x43, 0x40, 0x45, 0x42, 0x48, 0x50, 0x55, +0x6C, 0xE8, 0xD7, 0xCD, 0xCC, 0xC7, 0xC3, 0xC0, 0xBD, 0xBC, 0xB8, 0xB2, 0xB5, 0xBD, 0xC2, 0xD0, +0x5D, 0x45, 0x3C, 0x38, 0x32, 0x32, 0x37, 0x37, 0x3C, 0x4C, 0x5E, 0xEE, 0xCD, 0xC5, 0xC8, 0xC6, +0xC5, 0xD0, 0xE2, 0xF9, 0x5D, 0x4D, 0x47, 0x46, 0x42, 0x41, 0x47, 0x4B, 0x4E, 0x63, 0xEA, 0xE3, +0xD3, 0xC9, 0xCB, 0xC8, 0xC0, 0xBF, 0xBD, 0xBA, 0xB5, 0xB6, 0xBC, 0xC1, 0xCC, 0x7E, 0x4B, 0x3F, +0x3B, 0x35, 0x32, 0x37, 0x37, 0x3A, 0x45, 0x50, 0x6D, 0xD7, 0xC8, 0xC6, 0xC7, 0xC2, 0xCA, 0xD7, +0xDB, 0x6D, 0x59, 0x4F, 0x48, 0x48, 0x45, 0x46, 0x4D, 0x4F, 0x5E, 0xFF, 0xE6, 0xD7, 0xD4, 0xCF, +0xD1, 0xD5, 0xD0, 0xD3, 0xCD, 0xC6, 0xC1, 0xBA, 0xB8, 0xBB, 0xC2, 0xC4, 0xCD, 0x58, 0x4C, 0x48, +0x39, 0x36, 0x39, 0x36, 0x37, 0x3E, 0x44, 0x4B, 0x66, 0xDC, 0xD4, 0xCA, 0xC3, 0xC5, 0xC7, 0xCA, +0xCE, 0xDD, 0x6D, 0x5F, 0x4F, 0x46, 0x47, 0x46, 0x43, 0x49, 0x4E, 0x53, 0x65, 0xF1, 0xE4, 0xD9, +0xCF, 0xCE, 0xCD, 0xC6, 0xC3, 0xC0, 0xBA, 0xB7, 0xB7, 0xBD, 0xC4, 0xC5, 0xFD, 0x4A, 0x4C, 0x3B, +0x33, 0x37, 0x34, 0x32, 0x3A, 0x3F, 0x47, 0x5B, 0xDC, 0xCB, 0xC8, 0xBE, 0xBC, 0xC3, 0xC0, 0xC7, +0xDE, 0xEC, 0x5B, 0x49, 0x45, 0x3F, 0x3E, 0x3F, 0x40, 0x49, 0x4E, 0x5B, 0xEF, 0xDF, 0xD4, 0xCC, +0xCA, 0xC7, 0xC5, 0xC3, 0xBF, 0xBD, 0xBB, 0xB8, 0xB8, 0xC0, 0xCB, 0xCA, 0x68, 0x45, 0x4D, 0x3D, +0x35, 0x3C, 0x3A, 0x38, 0x41, 0x49, 0x4D, 0x69, 0xDB, 0xD3, 0xCD, 0xC5, 0xC6, 0xCC, 0xCB, 0xD0, +0xEB, 0x76, 0x5C, 0x4C, 0x48, 0x44, 0x41, 0x41, 0x44, 0x49, 0x4E, 0x5D, 0x7E, 0xE6, 0xD4, 0xCE, +0xCE, 0xCB, 0xCB, 0xCE, 0xCE, 0xCA, 0xC9, 0xC6, 0xBE, 0xBC, 0xC6, 0xCA, 0xC4, 0xE0, 0x58, 0x77, +0x4A, 0x3D, 0x45, 0x3D, 0x39, 0x3F, 0x41, 0x40, 0x4C, 0x61, 0x6D, 0xE7, 0xCE, 0xCC, 0xCC, 0xC9, +0xCA, 0xD1, 0xDB, 0xE2, 0x66, 0x54, 0x50, 0x48, 0x45, 0x47, 0x47, 0x4B, 0x51, 0x5A, 0x71, 0xEB, +0xDD, 0xD5, 0xD2, 0xCF, 0xCC, 0xCC, 0xCA, 0xC4, 0xC3, 0xBF, 0xB9, 0xBD, 0xCB, 0xC0, 0xC9, 0x56, +0x71, 0x5A, 0x3A, 0x3F, 0x3E, 0x34, 0x3A, 0x3E, 0x3C, 0x42, 0x54, 0x62, 0x73, 0xCF, 0xC8, 0xCC, +0xC3, 0xC3, 0xCD, 0xCF, 0xDD, 0x6D, 0x56, 0x4D, 0x48, 0x42, 0x42, 0x44, 0x45, 0x4D, 0x57, 0x61, +0xED, 0xDB, 0xD5, 0xCD, 0xCD, 0xCD, 0xCD, 0xD0, 0xCD, 0xD1, 0xCA, 0xC4, 0xC7, 0xBA, 0xC2, 0xD8, +0xBB, 0xD7, 0x53, 0xCC, 0x4E, 0x3E, 0x57, 0x3E, 0x3B, 0x43, 0x3F, 0x3E, 0x46, 0x52, 0x50, 0x60, +0xD6, 0xD9, 0xD4, 0xC6, 0xCA, 0xCF, 0xCB, 0xD5, 0xF4, 0xFB, 0x5D, 0x4E, 0x4C, 0x4B, 0x46, 0x45, +0x4F, 0x4E, 0x4D, 0x7E, 0x6F, 0x71, 0xD4, 0xE1, 0xDF, 0xCE, 0xD9, 0xD5, 0xCD, 0xCD, 0xC5, 0xBF, +0xB9, 0xBA, 0xC6, 0xBA, 0xBF, 0x6C, 0xCE, 0xFB, 0x3D, 0x4D, 0x40, 0x35, 0x3C, 0x3B, 0x38, 0x3E, +0x47, 0x4B, 0x52, 0xDF, 0xD8, 0xD6, 0xC3, 0xC6, 0xCB, 0xC5, 0xCD, 0xDD, 0xE4, 0x6B, 0x50, 0x4D, +0x49, 0x44, 0x45, 0x47, 0x48, 0x49, 0x50, 0x5D, 0x5C, 0xEE, 0xDD, 0xE7, 0xD1, 0xD5, 0xDC, 0xD0, +0xDA, 0xD8, 0xD1, 0xCD, 0xC6, 0xBF, 0xBA, 0xC1, 0xC4, 0xBA, 0xD3, 0xE1, 0xCC, 0x4D, 0x49, 0x4F, +0x3B, 0x3B, 0x3E, 0x3A, 0x3C, 0x42, 0x4A, 0x4C, 0x6D, 0xD9, 0xDC, 0xC9, 0xC4, 0xCA, 0xC6, 0xC8, +0xD0, 0xD8, 0xE5, 0x68, 0x58, 0x53, 0x4C, 0x4A, 0x4B, 0x4C, 0x4E, 0x56, 0x5F, 0x69, 0xEA, 0xE0, +0xE8, 0xD5, 0xDD, 0xE7, 0xD9, 0xFB, 0xF9, 0xF5, 0x64, 0x75, 0x6D, 0xF5, 0xE5, 0xD8, 0xC8, 0xC4, +0xBB, 0xBF, 0xC4, 0xB7, 0xCC, 0xD6, 0xC3, 0x56, 0x52, 0x5F, 0x3D, 0x3E, 0x3E, 0x39, 0x3A, 0x3D, +0x41, 0x41, 0x4F, 0x6B, 0x63, 0xD6, 0xCD, 0xD1, 0xC7, 0xC8, 0xCE, 0xCE, 0xD6, 0xE8, 0x71, 0x67, +0x55, 0x4F, 0x52, 0x4D, 0x4F, 0x56, 0x56, 0x5E, 0x6D, 0x7E, 0xF5, 0xDF, 0xE3, 0xEE, 0xDC, 0x7B, +0x73, 0xED, 0x5C, 0x6A, 0x69, 0x5B, 0x70, 0x6D, 0xEF, 0xE1, 0xCF, 0xC8, 0xC4, 0xB9, 0xC5, 0xC2, +0xB6, 0xDC, 0xCD, 0xC3, 0x49, 0x60, 0x57, 0x3A, 0x40, 0x3D, 0x38, 0x3A, 0x3E, 0x3F, 0x3E, 0x53, +0x58, 0x59, 0xD3, 0xD7, 0xD2, 0xC4, 0xC9, 0xCA, 0xC8, 0xCD, 0xD8, 0xDE, 0xEE, 0x5F, 0x5D, 0x59, +0x4F, 0x54, 0x56, 0x54, 0x5D, 0x69, 0x6D, 0xF2, 0xE1, 0xDF, 0xDB, 0xD8, 0xDD, 0xE8, 0xEB, 0x71, +0x5D, 0x66, 0x56, 0x52, 0x62, 0x52, 0x5C, 0x74, 0x63, 0xE2, 0xDD, 0xD4, 0xCA, 0xC9, 0xBF, 0xC0, +0xBB, 0xBB, 0xCC, 0xBB, 0xC8, 0x68, 0xC8, 0x58, 0x44, 0x5D, 0x3C, 0x3B, 0x40, 0x3A, 0x3B, 0x3F, +0x44, 0x43, 0x52, 0x7A, 0x62, 0xD4, 0xCB, 0xD1, 0xC3, 0xC4, 0xC8, 0xC5, 0xCA, 0xD0, 0xD9, 0xE1, +0x6C, 0x5C, 0x5B, 0x4E, 0x4D, 0x50, 0x4C, 0x50, 0x58, 0x58, 0x63, 0x79, 0xFE, 0xED, 0xE1, 0xE7, +0xEE, 0xE6, 0xFB, 0x6D, 0x7A, 0x61, 0x5D, 0x62, 0x59, 0x5B, 0x5E, 0x5C, 0x64, 0x69, 0x72, 0xFE, +0xF1, 0xE6, 0xE2, 0xDB, 0xD9, 0xD6, 0xD3, 0xD3, 0xD0, 0xD0, 0xCF, 0xCE, 0xCD, 0xCD, 0xDA, 0xDB, +0xDA, 0x64, 0x69, 0x63, 0x4C, 0x4F, 0x4D, 0x46, 0x4A, 0x4A, 0x48, 0x4D, 0x52, 0x52, 0x5C, 0x70, +0x71, 0xEB, 0xDC, 0xDE, 0xD7, 0xD4, 0xD8, 0xD5, 0xD7, 0xDD, 0xDF, 0xE7, 0xFD, 0x71, 0x69, 0x5D, +0x5A, 0x5A, 0x57, 0x56, 0x5B, 0x59, 0x5A, 0x69, 0x62, 0x6A, 0xF5, 0x73, 0xF1, 0xE7, 0xF4, 0xE6, +0xE6, 0xEE, 0xEA, 0xED, 0xF5, 0xF1, 0xED, 0xF0, 0xEA, 0xE4, 0xE7, 0xDF, 0xDE, 0xDF, 0xDC, 0xDE, +0xDF, 0xE1, 0xE8, 0xEE, 0xFD, 0x77, 0x6B, 0x64, 0x61, 0x5C, 0x5C, 0x5C, 0x5B, 0x5F, 0x61, 0x67, +0x6E, 0x78, 0xF8, 0xF1, 0xEA, 0xE5, 0xE4, 0xE2, 0xE1, 0xE5, 0xEA, 0xED, 0xFA, 0x77, 0x6E, 0x66, +0x62, 0x5D, 0x5C, 0x5A, 0x59, 0x59, 0x59, 0x5B, 0x5C, 0x5D, 0x64, 0x64, 0x6C, 0x77, 0x7C, 0xEE, +0xEB, 0xE0, 0xDB, 0xD7, 0xCF, 0xCF, 0xCA, 0xC8, 0xC5, 0xC4, 0xCD, 0xC7, 0xCB, 0xE8, 0xD3, 0xFD, +0x55, 0x67, 0x4B, 0x45, 0x48, 0x40, 0x3F, 0x42, 0x43, 0x43, 0x4A, 0x50, 0x50, 0x6C, 0xF5, 0xF2, +0xD4, 0xD2, 0xD1, 0xCB, 0xCC, 0xCE, 0xCE, 0xD0, 0xDA, 0xDC, 0xDF, 0xFD, 0x7D, 0x6F, 0x5E, 0x5F, +0x5D, 0x59, 0x5A, 0x5C, 0x5C, 0x5F, 0x68, 0x68, 0x6F, 0xFC, 0xFC, 0xEF, 0xE9, 0xEB, 0xE9, 0xE9, +0xED, 0xEF, 0xF2, 0xF8, 0xFE, 0xFE, 0x7C, 0x7C, 0x7E, 0x79, 0xFE, 0xFB, 0xFE, 0xF7, 0xF6, 0xF9, +0xF6, 0xF8, 0xFD, 0xFF, 0x7C, 0x73, 0x70, 0x6E, 0x6A, 0x6A, 0x69, 0x68, 0x6A, 0x6B, 0x6C, 0x6F, +0x74, 0x79, 0xFF, 0xFA, 0xF8, 0xF2, 0xF4, 0xF6, 0xF3, 0xFE, 0xFB, 0x74, 0x62, 0x69, 0x5F, 0x5A, +0x66, 0x5B, 0x5D, 0x70, 0x61, 0x78, 0xED, 0xF4, 0xDB, 0xD7, 0xD0, 0xCB, 0xC9, 0xC3, 0xCC, 0xC9, +0xC4, 0xDD, 0xD2, 0xD7, 0x59, 0x6E, 0x57, 0x45, 0x4B, 0x45, 0x3F, 0x43, 0x44, 0x43, 0x49, 0x51, +0x4F, 0x5E, 0xFB, 0x70, 0xDE, 0xD8, 0xDC, 0xD1, 0xD2, 0xD7, 0xD4, 0xD6, 0xDD, 0xDF, 0xDF, 0xF1, +0xF2, 0xF2, 0x6F, 0x73, 0x72, 0x69, 0x6D, 0x6F, 0x6D, 0x72, 0x7B, 0x79, 0x7E, 0xF8, 0xFD, 0xF9, +0xF6, 0xFD, 0xFA, 0xFA, 0xFD, 0xFB, 0xFB, 0xFD, 0xFA, 0xF6, 0xF8, 0xF3, 0xF2, 0xF4, 0xEF, 0xF1, +0xF4, 0xF2, 0xF6, 0xF9, 0xF8, 0xF9, 0xFD, 0xFD, 0xFC, 0x7F, 0x7E, 0x7D, 0x79, 0x76, 0x74, 0x71, +0x6F, 0x6E, 0x6C, 0x6C, 0x6D, 0x6B, 0x6C, 0x6D, 0x6C, 0x71, 0x71, 0x70, 0x7E, 0x79, 0x7C, 0xFA, +0x7B, 0xFD, 0xFC, 0x7A, 0xFE, 0x7C, 0x78, 0x7B, 0x76, 0x76, 0x78, 0x77, 0x77, 0x7C, 0x7E, 0xFF, +0xF2, 0xF3, 0xED, 0xE7, 0xE8, 0xE0, 0xDE, 0xDC, 0xD7, 0xD8, 0xD3, 0xD4, 0xDA, 0xD7, 0xDF, 0xEB, +0xED, 0x6A, 0x60, 0x5C, 0x52, 0x4F, 0x4D, 0x4B, 0x4A, 0x4B, 0x4B, 0x4D, 0x50, 0x54, 0x5B, 0x66, +0x6F, 0xF1, 0xE6, 0xDF, 0xDA, 0xD8, 0xD8, 0xD7, 0xD9, 0xDB, 0xDE, 0xE2, 0xEA, 0xF1, 0xFA, 0x78, +0x70, 0x6D, 0x69, 0x68, 0x66, 0x65, 0x65, 0x66, 0x66, 0x67, 0x6A, 0x6B, 0x6C, 0x70, 0x74, 0x79, +0xFB, 0xF5, 0xEF, 0xEB, 0xE9, 0xE6, 0xE3, 0xE2, 0xE1, 0xE0, 0xE0, 0xE0, 0xE1, 0xE3, 0xE3, 0xE6, +0xE9, 0xEB, 0xEF, 0xF7, 0x7F, 0x75, 0x6E, 0x6A, 0x66, 0x62, 0x61, 0x5F, 0x5F, 0x60, 0x5F, 0x62, +0x65, 0x66, 0x6C, 0x6E, 0x72, 0x7D, 0xFE, 0xF6, 0xEF, 0xED, 0xE9, 0xE7, 0xE4, 0xE3, 0xE0, 0xDF, +0xE1, 0xDF, 0xE1, 0xE3, 0xE3, 0xE7, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xED, 0xF5, 0xF6, 0xF9, 0x75, +0x76, 0x6E, 0x66, 0x65, 0x5E, 0x5B, 0x5A, 0x56, 0x55, 0x54, 0x53, 0x54, 0x55, 0x57, 0x59, 0x5D, +0x60, 0x66, 0x70, 0x79, 0xFA, 0xF0, 0xEE, 0xEC, 0xED, 0xED, 0xF0, 0xF5, 0xF8, 0xFF, 0xFD, 0x7E, +0x7D, 0xFE, 0x7E, 0xFD, 0xF8, 0xF6, 0xEF, 0xED, 0xEB, 0xE8, 0xE4, 0xE3, 0xE0, 0xDF, 0xDE, 0xDC, +0xDD, 0xDC, 0xDD, 0xE1, 0xE2, 0xE9, 0xF3, 0x7A, 0x65, 0x61, 0x5B, 0x56, 0x56, 0x51, 0x50, 0x52, +0x50, 0x55, 0x58, 0x59, 0x5F, 0x68, 0x70, 0xFC, 0xEE, 0xE9, 0xE4, 0xE1, 0xE4, 0xE4, 0xE7, 0xED, +0xEE, 0xF8, 0xFF, 0x7D, 0x76, 0x76, 0x7A, 0x7B, 0xFF, 0xF9, 0xF7, 0xF1, 0xED, 0xED, 0xEB, 0xE9, +0xEA, 0xEA, 0xEC, 0xED, 0xEE, 0xF0, 0xF1, 0xF2, 0xF2, 0xF3, 0xF0, 0xF1, 0xF3, 0xEF, 0xF3, 0xF5, +0xF4, 0xFB, 0xFC, 0xFC, 0x7C, 0x7A, 0x76, 0x70, 0x6F, 0x6F, 0x6C, 0x6C, 0x6C, 0x68, 0x6B, 0x6B, +0x68, 0x6D, 0x6B, 0x6B, 0x6F, 0x6E, 0x70, 0x77, 0x76, 0x7A, 0x7F, 0xFF, 0xFD, 0xF6, 0xF7, 0xF5, +0xEF, 0xF4, 0xF1, 0xEF, 0xF2, 0xEE, 0xF0, 0xF1, 0xEE, 0xF0, 0xF1, 0xF1, 0xF2, 0xF6, 0xF9, 0xFA, +0x7F, 0x7E, 0x7A, 0x76, 0x7A, 0x73, 0x72, 0x74, 0x6F, 0x73, 0x75, 0x73, 0x75, 0x74, 0x76, 0x73, +0x77, 0x7A, 0x76, 0x7E, 0x78, 0x76, 0x7E, 0x76, 0x7A, 0x79, 0x74, 0x7D, 0x77, 0x77, 0x79, 0x74, +0x76, 0x77, 0x7A, 0x79, 0x7C, 0xFF, 0x79, 0xFC, 0xFA, 0x7E, 0xF4, 0xF9, 0xFC, 0xF6, 0x7E, 0xFF, +0xFF, 0x7B, 0x7C, 0x77, 0x75, 0x76, 0x78, 0x76, 0x74, 0x7B, 0x74, 0x75, 0x7E, 0x74, 0x7B, 0x7C, +0x72, 0x7A, 0x77, 0x74, 0x7A, 0x75, 0x72, 0x73, 0x72, 0x6E, 0x6E, 0x70, 0x6D, 0x70, 0x71, 0x6E, +0x75, 0x73, 0x72, 0x79, 0x78, 0x7B, 0xFF, 0xFF, 0xFD, 0xFA, 0xFC, 0xFB, 0xF7, 0xFD, 0xFE, 0xFA, +0x7D, 0x7D, 0xFE, 0x79, 0x7B, 0x7C, 0x7B, 0x7E, 0x7E, 0xFD, 0xFA, 0xFA, 0xF7, 0xF8, 0xF9, 0xF9, +0xFB, 0xFC, 0xFD, 0xFE, 0xFF, 0x7D, 0x7B, 0x77, 0x78, 0x74, 0x71, 0x74, 0x6F, 0x6F, 0x71, 0x6D, +0x6F, 0x71, 0x6F, 0x73, 0x74, 0x77, 0x7B, 0x7D, 0x7F, 0xFF, 0xFC, 0xFE, 0xFB, 0xF8, 0xFB, 0xF7, +0xF9, 0xFE, 0xFB, 0xFE, 0xFF, 0xFF, 0xFF, 0x7E, 0x7C, 0x7E, 0x7B, 0x7B, 0x7E, 0x7C, 0xFF, 0xFE, +0xFE, 0xFB, 0xFE, 0xFF, 0xFD, 0xFE, 0x7E, 0x7F, 0x7A, 0x78, 0x79, 0x75, 0x74, 0x75, 0x73, 0x75, +0x77, 0x77, 0x79, 0x7B, 0x7D, 0xFF, 0xFA, 0xF8, 0xF4, 0xF2, 0xF5, 0xF1, 0xF2, 0xF6, 0xF3, 0xF6, +0xFA, 0xFB, 0xFC, 0x7D, 0x7A, 0x7A, 0x74, 0x77, 0x78, 0x74, 0x7A, 0x77, 0x7A, 0xFF, 0x7F, 0xF9, +0xFB, 0xFB, 0xF9, 0xFF, 0x7F, 0x7C, 0x7A, 0x77, 0x72, 0x73, 0x6E, 0x6E, 0x6E, 0x6D, 0x70, 0x70, +0x75, 0x7D, 0x7B, 0xFE, 0xFD, 0xFF, 0xFC, 0xFF, 0x7E, 0xFF, 0x7E, 0x7A, 0x79, 0x76, 0x6F, 0x72, +0x72, 0x6F, 0x73, 0x6F, 0x6E, 0x74, 0x72, 0x74, 0x7C, 0x7C, 0xFF, 0xF9, 0xFA, 0xF9, 0xF5, 0xF7, +0xF7, 0xF5, 0xFA, 0xFA, 0xF7, 0xFA, 0xF9, 0xF8, 0xFC, 0xF9, 0xF8, 0xFA, 0xF6, 0xF9, 0xFC, 0xFA, +0xFD, 0xFE, 0xFD, 0xFF, 0x7E, 0x7E, 0x7D, 0x7A, 0x7C, 0x7B, 0x79, 0x7C, 0x7B, 0x7B, 0xFF, 0x7E, +0xFF, 0xFC, 0xFE, 0xFE, 0xFB, 0xFD, 0x7C, 0x7F, 0x7F, 0x76, 0x78, 0x78, 0x74, 0x78, 0x78, 0x78, +0x7B, 0x7A, 0x7A, 0x79, 0x77, 0x78, 0x79, 0x78, 0x7A, 0x7B, 0x7A, 0x7C, 0x7F, 0x7D, 0xFF, 0xFC, +0xFD, 0xFA, 0xFB, 0xFD, 0xFE, 0xFF, 0x7F, 0x7D, 0x7C, 0x7A, 0x7B, 0x7D, 0x7D, 0x7E, 0x7E, 0x7D, +0x7D, 0x7C, 0x7C, 0x7C, 0x7C, 0x7D, 0x7C, 0x7B, 0x7C, 0x7D, 0x7F, 0xFF, 0xFE, 0xFC, 0xFC, 0xFB, +0xFB, 0xFB, 0xFB, 0xFA, 0xFA, 0xFB, 0xFB, 0xFD, 0xFF, 0x7D, 0x7B, 0x7B, 0x7A, 0x77, 0x77, 0x78, +0x77, 0x77, 0x79, 0x7A, 0x7B, 0x7B, 0x7D, 0x7E, 0xFF, 0xFE, 0xFE, 0xFD, 0xFC, 0xFC, 0xFC, 0xFC, +0xFE, 0xFF, 0xFF, 0x7E, 0x7B, 0x78, 0x77, 0x76, 0x74, 0x73, 0x73, 0x71, 0x72, 0x73, 0x73, 0x74, +0x75, 0x76, 0x77, 0x77, 0x78, 0x78, 0x7A, 0x7D, 0x7D, 0x7E, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0x7F, 0x7E, 0x7D, 0x7D, 0x7C, 0x7A, 0x79, 0x79, 0x78, 0x77, 0x78, 0x79, 0x7A, 0x7A, 0x7B, 0x7A, +0x79, 0x7B, 0x7B, 0x7B, 0x7C, 0x7A, 0x7A, 0x79, 0x78, 0x78, 0x76, 0x76, 0x75, 0x73, 0x73, 0x73, +0x74, 0x77, 0x79, 0x7A, 0x7D, 0x7F, 0xFE, 0xFD, 0xFD, 0xFD, 0xFC, 0xFC, 0xFD, 0xFD, 0xFE, 0xFF, +0xFF, 0xFF, 0x7F, 0x7E, 0x7E, 0x7D, 0x7C, 0x7C, 0x7C, 0x7B, 0x7B, 0x7C, 0x7D, 0x7D, 0x7D, 0x7E, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, +0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x4C, 0x49, 0x53, 0x54, 0x4A, 0x00, +0x00, 0x00, 0x49, 0x4E, 0x46, 0x4F, 0x49, 0x53, 0x46, 0x54, 0x3E, 0x00, 0x00, 0x00, 0x46, 0x69, +0x6C, 0x65, 0x20, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x47, 0x6F, +0x6C, 0x64, 0x57, 0x61, 0x76, 0x65, 0x2E, 0x20, 0x20, 0x47, 0x6F, 0x6C, 0x64, 0x57, 0x61, 0x76, +0x65, 0x20, 0x63, 0x6F, 0x70, 0x79, 0x72, 0x69, 0x67, 0x68, 0x74, 0x20, 0x28, 0x43, 0x29, 0x20, +0x43, 0x68, 0x72, 0x69, 0x73, 0x20, 0x43, 0x72, 0x61, 0x69, 0x67, 0x00 + +}; + +static const uint8_t shaun_png[] PROGMEM = { + 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x57, 0x08, 0x06, 0x00, 0x00, 0x00, 0xF2, 0x0C, 0xE0, + 0x57, 0x00, 0x00, 0x00, 0x06, 0x62, 0x4B, 0x47, 0x44, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0xFF, 0xA0, + 0xBD, 0xA7, 0x93, 0x00, 0x00, 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x42, 0x8A, 0x00, + 0x00, 0x42, 0x8A, 0x01, 0x34, 0xA8, 0x6C, 0x25, 0x00, 0x00, 0x00, 0x09, 0x76, 0x70, 0x41, 0x67, + 0x00, 0x00, 0x00, 0x64, 0x00, 0x00, 0x00, 0x57, 0x00, 0x73, 0x4D, 0x3B, 0xD6, 0x00, 0x00, 0x1B, + 0x47, 0x49, 0x44, 0x41, 0x54, 0x78, 0xDA, 0xED, 0x9D, 0x79, 0x74, 0x14, 0x55, 0xBE, 0xC7, 0x3F, + 0x55, 0xDD, 0x49, 0x67, 0x5F, 0x3A, 0x7B, 0x42, 0x82, 0x61, 0x49, 0x02, 0x81, 0xB0, 0x29, 0x32, + 0x22, 0x3C, 0x16, 0x41, 0x45, 0x10, 0x15, 0x7D, 0x13, 0x65, 0xD0, 0x81, 0xE3, 0x7B, 0xCC, 0xD3, + 0x51, 0x04, 0xF5, 0xE1, 0xB8, 0xCE, 0xE6, 0x28, 0x22, 0x23, 0x33, 0x2C, 0x2A, 0x22, 0xEE, 0x02, + 0x22, 0x0C, 0x2A, 0x83, 0x28, 0x7B, 0x20, 0xC8, 0x92, 0x10, 0xD9, 0x97, 0x40, 0x08, 0x81, 0x90, + 0x3D, 0x64, 0x21, 0xE9, 0x4E, 0x3A, 0x5D, 0xF7, 0xFD, 0x71, 0xBB, 0x93, 0x0E, 0x10, 0xD2, 0x59, + 0x3A, 0x01, 0xCF, 0xFB, 0x9E, 0xD3, 0xE7, 0xA4, 0x6E, 0xA5, 0x6E, 0xDD, 0xFA, 0xFD, 0xEA, 0xFE, + 0xEE, 0xEF, 0xFE, 0xB6, 0x52, 0xB8, 0xFE, 0xA1, 0x03, 0x7A, 0x01, 0x43, 0x81, 0x9B, 0x80, 0x6A, + 0x60, 0x3F, 0xA0, 0x02, 0x8F, 0x00, 0xB7, 0x03, 0xA1, 0x80, 0x00, 0x72, 0x81, 0xAD, 0xC0, 0xC7, + 0xC0, 0x6E, 0xA0, 0xAE, 0xB3, 0x07, 0xFF, 0x4B, 0x43, 0x30, 0xF0, 0x67, 0x20, 0x1B, 0xB0, 0x20, + 0x89, 0xAE, 0x01, 0x95, 0x40, 0xB9, 0xED, 0xF8, 0x6A, 0xBF, 0x3C, 0xDB, 0x75, 0x81, 0xCD, 0xF4, + 0xAF, 0x03, 0x8C, 0x40, 0x2C, 0xD0, 0x13, 0x88, 0x00, 0x0C, 0x9D, 0xF9, 0xC0, 0x4A, 0x27, 0xDD, + 0xD7, 0x13, 0x88, 0x07, 0xFA, 0x03, 0x51, 0x36, 0x22, 0xE4, 0x03, 0x87, 0x80, 0x83, 0x48, 0x62, + 0x1B, 0x81, 0x85, 0x40, 0x72, 0x2B, 0xC7, 0xA9, 0x01, 0x5F, 0x00, 0x2F, 0x03, 0x35, 0xB6, 0xE3, + 0x0A, 0xDB, 0xDF, 0xDE, 0xC0, 0x48, 0x60, 0x22, 0x30, 0x08, 0xC9, 0x78, 0x3D, 0x92, 0xD1, 0x99, + 0xC0, 0x0F, 0xC0, 0x5A, 0xE0, 0x5C, 0x47, 0x13, 0xA6, 0xA3, 0x19, 0xA2, 0x07, 0x46, 0x00, 0x4F, + 0x22, 0x45, 0x4D, 0xD0, 0x65, 0x63, 0xB8, 0x84, 0x14, 0x47, 0xEF, 0x03, 0x09, 0xC0, 0x4B, 0x48, + 0xD1, 0x44, 0x40, 0x40, 0x00, 0x31, 0x31, 0x31, 0x54, 0x56, 0x56, 0x92, 0x93, 0x93, 0x83, 0xD5, + 0x6A, 0x25, 0x3A, 0x3A, 0x9A, 0x89, 0x13, 0x27, 0x32, 0x60, 0xC0, 0x00, 0xAC, 0x56, 0x2B, 0xBB, + 0x77, 0xEF, 0x66, 0xDD, 0xBA, 0x75, 0x14, 0x16, 0x16, 0xDA, 0xFB, 0xAB, 0x03, 0x4E, 0x23, 0x67, + 0x4D, 0x9D, 0x8D, 0xC0, 0xFB, 0x90, 0x22, 0xF0, 0x1E, 0xC0, 0xAB, 0x89, 0x71, 0x6A, 0xC0, 0x11, + 0xE0, 0x0D, 0xE0, 0x6B, 0xE4, 0xEC, 0xFC, 0xC5, 0xC1, 0x07, 0x78, 0x0D, 0x28, 0xA5, 0x69, 0x51, + 0x63, 0xFF, 0x99, 0x80, 0x2A, 0xFB, 0xF1, 0xC0, 0x81, 0x03, 0xC5, 0xA6, 0x4D, 0x9B, 0x44, 0x49, + 0x49, 0x89, 0xC8, 0xCA, 0xCA, 0x12, 0xAF, 0xBF, 0xFE, 0xBA, 0x78, 0xFC, 0xF1, 0xC7, 0x45, 0x5A, + 0x5A, 0x9A, 0xD0, 0x34, 0x4D, 0xD8, 0x51, 0x57, 0x57, 0x27, 0xB6, 0x6E, 0xDD, 0x2A, 0xFA, 0xF7, + 0xEF, 0xDF, 0x5C, 0xFF, 0x8D, 0x7E, 0x8A, 0xA2, 0x08, 0x55, 0x55, 0xAF, 0x76, 0xAE, 0x02, 0x78, + 0x0E, 0xF9, 0x22, 0x75, 0x08, 0x3A, 0x6A, 0x86, 0x78, 0x02, 0x7F, 0x05, 0x9E, 0x02, 0xDC, 0x00, + 0x14, 0x45, 0x21, 0x24, 0x24, 0x84, 0xE8, 0xE8, 0x68, 0xDC, 0xDD, 0xDD, 0xB9, 0x70, 0xE1, 0x02, + 0xB9, 0xB9, 0xB9, 0xD4, 0xD5, 0x35, 0x5E, 0x87, 0xBD, 0xBC, 0xBC, 0x58, 0xB1, 0x62, 0x05, 0x13, + 0x26, 0x4C, 0xA8, 0x6F, 0x13, 0x42, 0x20, 0x84, 0x40, 0x55, 0xD5, 0xAB, 0xDE, 0x6C, 0xD7, 0xAE, + 0x5D, 0x3C, 0xFC, 0xF0, 0xC3, 0xE4, 0xE4, 0xE4, 0x34, 0xFD, 0xE0, 0x8A, 0x42, 0x7C, 0x7C, 0x3C, + 0xF7, 0xDC, 0x73, 0x0F, 0xFD, 0xFA, 0xF5, 0xC3, 0xC3, 0xC3, 0x83, 0xEC, 0xEC, 0x6C, 0x36, 0x6C, + 0xD8, 0x40, 0x6A, 0x6A, 0x2A, 0x35, 0x35, 0x35, 0xF6, 0x7F, 0xAD, 0xB4, 0x8D, 0xFB, 0x73, 0xC0, + 0xDA, 0x41, 0xF4, 0x72, 0x39, 0x7E, 0x8F, 0x7C, 0xEB, 0x05, 0x20, 0xC2, 0xC2, 0xC2, 0xC4, 0x2B, + 0xAF, 0xBC, 0x22, 0x0E, 0x1E, 0x3C, 0x28, 0x2E, 0x5E, 0xBC, 0x28, 0x2A, 0x2A, 0x2A, 0x44, 0x56, + 0x56, 0x96, 0x58, 0xBC, 0x78, 0xB1, 0x48, 0x48, 0x48, 0x68, 0xF4, 0x96, 0xC6, 0xC4, 0xC4, 0x88, + 0x33, 0x67, 0xCE, 0x88, 0x96, 0xE2, 0xE3, 0x8F, 0x3F, 0x16, 0x77, 0xDE, 0x79, 0xA7, 0x78, 0xFE, + 0xF9, 0xE7, 0xC5, 0xBB, 0xEF, 0xBE, 0x2B, 0xDE, 0x7E, 0xFB, 0x6D, 0xF1, 0xE0, 0x83, 0x0F, 0x0A, + 0xA3, 0xD1, 0x28, 0xDC, 0xDC, 0xDC, 0xC4, 0xD4, 0xA9, 0x53, 0xC5, 0xE9, 0xD3, 0xA7, 0xAF, 0xB8, + 0xAE, 0xA2, 0xA2, 0x42, 0x2C, 0x58, 0xB0, 0x40, 0x04, 0x07, 0x07, 0x3B, 0x8E, 0xA3, 0x00, 0x58, + 0x0D, 0xFC, 0x0E, 0x08, 0xEF, 0x6C, 0x62, 0xB6, 0x15, 0x7D, 0x80, 0x33, 0xF6, 0x87, 0x8B, 0x8D, + 0x8D, 0x15, 0xEB, 0xD7, 0xAF, 0x6F, 0x24, 0x6A, 0x1C, 0x91, 0x91, 0x91, 0x21, 0x06, 0x0F, 0x1E, + 0x2C, 0x00, 0x61, 0x30, 0x18, 0xC4, 0xAF, 0x7F, 0xFD, 0x6B, 0x51, 0x51, 0x51, 0xD1, 0x62, 0x86, + 0x58, 0xAD, 0x56, 0x61, 0x36, 0x9B, 0x1B, 0xDD, 0xA7, 0xA6, 0xA6, 0x46, 0xEC, 0xD8, 0xB1, 0x43, + 0xAC, 0x5A, 0xB5, 0x4A, 0x94, 0x97, 0x97, 0x37, 0x79, 0xAD, 0xA6, 0x69, 0x62, 0xF1, 0xE2, 0xC5, + 0xC2, 0xC3, 0xC3, 0xE3, 0x72, 0x11, 0x66, 0x05, 0x76, 0x02, 0x43, 0x3A, 0x9B, 0xA8, 0x6D, 0xC1, + 0xDB, 0xF6, 0x07, 0xF2, 0xF5, 0xF5, 0x15, 0x2B, 0x56, 0xAC, 0x68, 0x96, 0x98, 0xC7, 0x8E, 0x1D, + 0x13, 0xF3, 0xE7, 0xCF, 0x17, 0x1B, 0x36, 0x6C, 0x10, 0xA5, 0xA5, 0xA5, 0x2D, 0x66, 0x46, 0x7B, + 0xA0, 0xB2, 0xB2, 0x52, 0x4C, 0x98, 0x30, 0xA1, 0xA9, 0x75, 0xE7, 0x00, 0x52, 0x31, 0x68, 0x77, + 0xB8, 0x7A, 0x0D, 0x89, 0x02, 0x36, 0xDA, 0x07, 0x3F, 0x79, 0xF2, 0x64, 0x3E, 0xFC, 0xF0, 0x43, + 0x0C, 0x86, 0x4E, 0x55, 0xF5, 0x9D, 0xC6, 0xC1, 0x83, 0x07, 0x59, 0xBB, 0x76, 0x2D, 0x16, 0x8B, + 0x85, 0x94, 0x94, 0x14, 0x52, 0x53, 0x53, 0xB1, 0x5A, 0xEB, 0x97, 0x91, 0xF7, 0x91, 0xDA, 0xE2, + 0x0D, 0xB5, 0xAE, 0x8C, 0x07, 0xCC, 0x80, 0xF0, 0xF4, 0xF4, 0x14, 0xEB, 0xD6, 0xAD, 0xEB, 0x94, + 0xB7, 0xBD, 0x3D, 0x50, 0x54, 0x54, 0x24, 0x92, 0x93, 0x93, 0x1D, 0x67, 0x49, 0x36, 0xD0, 0xBD, + 0xB3, 0x09, 0xDC, 0x12, 0x84, 0x00, 0xAB, 0xEC, 0x0F, 0x10, 0x1F, 0x1F, 0x2F, 0x72, 0x73, 0x73, + 0x3B, 0x9B, 0xAE, 0x6D, 0xC2, 0x96, 0x2D, 0x5B, 0x84, 0x8F, 0x8F, 0x8F, 0xA3, 0x6A, 0x7E, 0x47, + 0x7B, 0x13, 0x4D, 0x6D, 0x7B, 0x17, 0x57, 0x85, 0x37, 0x72, 0x53, 0x35, 0xC9, 0xDE, 0xD0, 0xAD, + 0x5B, 0x37, 0x8C, 0x46, 0xA3, 0x8B, 0x6E, 0xD7, 0x31, 0xF0, 0xF5, 0xF5, 0x45, 0xAF, 0xAF, 0xDF, + 0x92, 0xA8, 0x80, 0x47, 0x7B, 0xDF, 0xC3, 0x55, 0x0C, 0xF9, 0x4F, 0xE0, 0x37, 0xD8, 0xD6, 0xA8, + 0x84, 0x84, 0x04, 0x9E, 0x7E, 0xFA, 0x69, 0x3C, 0x3C, 0xDA, 0x7D, 0xFC, 0x1D, 0x8A, 0x5D, 0xBB, + 0x76, 0x51, 0x56, 0x56, 0x66, 0x3F, 0xAC, 0x42, 0xDA, 0xCC, 0xDA, 0x15, 0xAE, 0xD8, 0x81, 0x1A, + 0x81, 0xC7, 0xB1, 0x19, 0xE9, 0x12, 0x12, 0x12, 0xF8, 0xEC, 0xB3, 0xCF, 0xB8, 0xF9, 0xE6, 0x9B, + 0x5D, 0x44, 0xA6, 0x8E, 0x43, 0x5E, 0x5E, 0x23, 0xFA, 0x0B, 0x5C, 0xF7, 0x42, 0xB7, 0x2B, 0x46, + 0x21, 0x6D, 0x52, 0x42, 0xAF, 0xD7, 0x8B, 0x25, 0x4B, 0x96, 0x74, 0xB6, 0xE8, 0x6F, 0x37, 0xEC, + 0xDD, 0xBB, 0x57, 0x84, 0x86, 0x86, 0x3A, 0x2E, 0xEC, 0xB3, 0xDB, 0x9B, 0x78, 0xAE, 0xE0, 0x70, + 0x12, 0x72, 0x0D, 0xA1, 0x6B, 0xD7, 0xAE, 0x8C, 0x1D, 0x3B, 0xD6, 0x85, 0xBC, 0xEF, 0x58, 0x24, + 0x25, 0x25, 0x31, 0x64, 0x48, 0xA3, 0x3D, 0xE1, 0x2D, 0xB4, 0xB3, 0x94, 0x71, 0x05, 0x43, 0x22, + 0xED, 0x7F, 0x44, 0x47, 0x47, 0x13, 0x12, 0x12, 0xE2, 0x1A, 0xEA, 0x74, 0x02, 0x0C, 0x06, 0x03, + 0x89, 0x89, 0x89, 0x8E, 0x4D, 0x51, 0x48, 0x3B, 0x5D, 0xBB, 0xC1, 0x15, 0x0C, 0xA9, 0xEF, 0x53, + 0xA7, 0xD3, 0x35, 0x69, 0x00, 0xBC, 0x51, 0xE1, 0xEB, 0xEB, 0xEB, 0x78, 0x68, 0xE0, 0x06, 0x98, + 0x21, 0xF5, 0xCE, 0x88, 0xBC, 0xBC, 0x3C, 0x47, 0xAD, 0xE4, 0x17, 0x81, 0xD2, 0xD2, 0x52, 0xC7, + 0xC3, 0x6A, 0xDA, 0xD9, 0x57, 0xE2, 0x0A, 0x86, 0x1C, 0x46, 0xEE, 0xCE, 0xC9, 0xCA, 0xCA, 0x22, + 0x35, 0x35, 0xD5, 0x65, 0xC4, 0xE9, 0x68, 0x54, 0x55, 0x55, 0x91, 0x91, 0x91, 0xE1, 0xD8, 0x94, + 0x8D, 0x64, 0xCA, 0x75, 0x8D, 0x70, 0xE0, 0x67, 0x6C, 0x9A, 0xC8, 0xD0, 0xA1, 0x43, 0x45, 0x76, + 0x76, 0x76, 0x67, 0x2B, 0x48, 0xED, 0x82, 0x1F, 0x7E, 0xF8, 0x41, 0xF8, 0xF9, 0xF9, 0x39, 0x6A, + 0x59, 0x4F, 0x74, 0x36, 0xB1, 0x9D, 0xC5, 0x73, 0x48, 0xA3, 0x9B, 0x00, 0xC4, 0xC8, 0x91, 0x23, + 0xC5, 0x8F, 0x3F, 0xFE, 0x28, 0xCC, 0x66, 0xB3, 0xCB, 0x88, 0x65, 0xB5, 0x5A, 0x5D, 0xCA, 0x8C, + 0xAC, 0xAC, 0x2C, 0x31, 0x6C, 0xD8, 0x30, 0x47, 0x66, 0x64, 0x01, 0x71, 0x9D, 0x4D, 0x68, 0x67, + 0x61, 0x04, 0xD6, 0x39, 0x0C, 0x5E, 0xF8, 0xF8, 0xF8, 0x88, 0x05, 0x0B, 0x16, 0xB8, 0x84, 0x58, + 0x99, 0x99, 0x99, 0x62, 0xFA, 0xF4, 0xE9, 0x62, 0xD9, 0xB2, 0x65, 0xC2, 0x64, 0x32, 0x5D, 0x71, + 0x5E, 0xD3, 0x34, 0x71, 0xEE, 0xDC, 0x39, 0x91, 0x97, 0x97, 0xD7, 0xAA, 0xFE, 0x4F, 0x9E, 0x3C, + 0x29, 0x46, 0x8C, 0x18, 0x71, 0xB9, 0x09, 0xFE, 0xF5, 0xCE, 0x26, 0xB2, 0xB3, 0x08, 0x46, 0x5A, + 0x79, 0x1B, 0x31, 0x04, 0x10, 0x49, 0x49, 0x49, 0x22, 0x27, 0x27, 0xA7, 0x5D, 0x99, 0x61, 0xB5, + 0x5A, 0xC5, 0x8C, 0x19, 0x33, 0x04, 0x20, 0xBC, 0xBC, 0xBC, 0xC4, 0xA3, 0x8F, 0x3E, 0x2A, 0x36, + 0x6F, 0xDE, 0x2C, 0xCE, 0x9F, 0x3F, 0x2F, 0x0A, 0x0B, 0x0B, 0xC5, 0xE1, 0xC3, 0x87, 0xC5, 0xDC, + 0xB9, 0x73, 0x45, 0x42, 0x42, 0x82, 0x18, 0x33, 0x66, 0x8C, 0x28, 0x28, 0x28, 0x68, 0xF1, 0x3D, + 0x96, 0x2E, 0x5D, 0x7A, 0x39, 0x33, 0x34, 0x60, 0x3B, 0xF0, 0xDF, 0x40, 0x37, 0x64, 0x38, 0xD1, + 0x75, 0x87, 0x28, 0xA4, 0xEF, 0x79, 0x2F, 0x36, 0x93, 0x3B, 0x57, 0x09, 0x26, 0x98, 0x35, 0x6B, + 0x56, 0xBB, 0x8A, 0xAE, 0x6D, 0xDB, 0xB6, 0x89, 0xD0, 0xD0, 0x50, 0xE1, 0xED, 0x69, 0x10, 0xE1, + 0xC1, 0x01, 0x02, 0x10, 0x9E, 0x5E, 0x5E, 0xA2, 0x5B, 0xB7, 0xEE, 0xA2, 0x57, 0xAF, 0x5E, 0x22, + 0x38, 0x24, 0x44, 0x28, 0x8A, 0x22, 0x00, 0xE1, 0xE6, 0xE6, 0x26, 0x3E, 0xFA, 0xE8, 0xA3, 0x16, + 0xDF, 0x63, 0xCD, 0x9A, 0x35, 0x42, 0xAF, 0xD7, 0x5F, 0xCD, 0x51, 0x55, 0x87, 0x14, 0x5D, 0x0B, + 0x80, 0x5B, 0x01, 0xF7, 0xB6, 0x12, 0xB1, 0x3D, 0x38, 0x1B, 0x0A, 0x4C, 0x07, 0xE6, 0x21, 0x0D, + 0x8A, 0x5D, 0x70, 0xD0, 0xCD, 0x75, 0x3A, 0x1D, 0xE1, 0xE1, 0xE1, 0x24, 0x25, 0x25, 0x61, 0x36, + 0x9B, 0x49, 0x4D, 0x4D, 0xC5, 0x64, 0x32, 0xD1, 0xB7, 0x6F, 0x5F, 0x7C, 0x7C, 0x7C, 0x00, 0x19, + 0xB4, 0x50, 0x50, 0x50, 0x40, 0x59, 0x59, 0x19, 0xBE, 0xBE, 0xBE, 0x28, 0x8A, 0x73, 0x7E, 0xB3, + 0xEC, 0xEC, 0x6C, 0x9E, 0x7E, 0xFA, 0x69, 0x8E, 0x1D, 0x3B, 0xC6, 0x8C, 0x87, 0xC7, 0x31, 0x77, + 0xC6, 0x14, 0x02, 0xFD, 0x7C, 0xA8, 0xAA, 0x36, 0x51, 0x5A, 0x5A, 0x42, 0x65, 0x45, 0x39, 0x81, + 0x3E, 0x06, 0xEE, 0xFC, 0x55, 0x7F, 0x86, 0x0D, 0x48, 0x20, 0xFD, 0xE8, 0x69, 0xB2, 0xB3, 0xCF, + 0x72, 0xC7, 0x1D, 0x77, 0xB4, 0xC8, 0xF2, 0xBC, 0x7E, 0xFD, 0x7A, 0x36, 0x6C, 0xD8, 0x80, 0x9F, + 0x9F, 0x1F, 0x3A, 0x9D, 0x0E, 0x8B, 0xA5, 0x5E, 0xD3, 0x55, 0x91, 0xC1, 0x78, 0x83, 0x81, 0xFB, + 0x81, 0xDE, 0x40, 0x11, 0xD2, 0xE8, 0xA8, 0xB5, 0x03, 0x6D, 0x5B, 0x04, 0x37, 0xA4, 0x68, 0x4A, + 0x45, 0xBE, 0x29, 0x8D, 0x66, 0x42, 0x97, 0x2E, 0x5D, 0xC4, 0x23, 0x8F, 0x3C, 0x22, 0x3E, 0xF9, + 0xE4, 0x13, 0x71, 0xEC, 0xD8, 0x31, 0x51, 0x55, 0x55, 0x25, 0x5E, 0x7A, 0xE9, 0x25, 0x01, 0x08, + 0x9D, 0x4E, 0x27, 0x06, 0x0E, 0x1A, 0x24, 0x66, 0xCF, 0x9E, 0x2D, 0xE6, 0xCF, 0x9F, 0x2F, 0x66, + 0xCE, 0x9C, 0x29, 0xFA, 0xF4, 0xE9, 0x23, 0x7A, 0xF7, 0xEE, 0x2D, 0xD6, 0xAC, 0x59, 0xE3, 0xD4, + 0x02, 0x9D, 0x99, 0x99, 0x29, 0xC6, 0x8D, 0x1B, 0x27, 0x95, 0x86, 0x9B, 0x13, 0x45, 0xEE, 0x86, + 0x25, 0x42, 0x64, 0xAC, 0x16, 0x5A, 0xFA, 0x2A, 0x51, 0xB6, 0xED, 0x63, 0x71, 0xFA, 0x9B, 0x05, + 0xE2, 0xF8, 0xD7, 0xF3, 0xC5, 0x85, 0x0D, 0xEF, 0x0B, 0xCB, 0xDE, 0x15, 0xA2, 0x74, 0xFB, 0x27, + 0x62, 0xFC, 0xB0, 0x41, 0x02, 0x10, 0x77, 0xDF, 0x7D, 0xB7, 0x38, 0x7A, 0xF4, 0x68, 0xA3, 0xFE, + 0x34, 0x4D, 0x13, 0xFB, 0xF7, 0xEF, 0x17, 0x6F, 0xBD, 0xF5, 0x96, 0xD8, 0xBD, 0x7B, 0xB7, 0xB0, + 0x58, 0x2C, 0xC2, 0x62, 0xB1, 0x88, 0x6D, 0xDB, 0xB6, 0x89, 0xB8, 0xB8, 0x38, 0xE1, 0xEE, 0xEE, + 0x2E, 0xDE, 0x7B, 0xEF, 0x3D, 0xB1, 0x69, 0xD3, 0x26, 0xF1, 0xDC, 0x73, 0xCF, 0x89, 0x7E, 0xFD, + 0xFA, 0x09, 0x77, 0x77, 0xF7, 0xAB, 0xCD, 0x9A, 0x12, 0xE0, 0x03, 0x64, 0x10, 0x60, 0x87, 0xC5, + 0xBD, 0x45, 0x20, 0x67, 0x44, 0x99, 0xE3, 0x60, 0x74, 0x3A, 0x9D, 0x48, 0x4A, 0x4A, 0x12, 0x6F, + 0xBE, 0xF9, 0xA6, 0x38, 0x76, 0xEC, 0x98, 0xB0, 0x58, 0x2C, 0xF5, 0x0F, 0x6C, 0x32, 0x99, 0xC4, + 0xA4, 0x49, 0x93, 0x04, 0x20, 0xBA, 0x84, 0x1A, 0x85, 0xA7, 0xC1, 0xAD, 0xD1, 0x83, 0x78, 0xB8, + 0xBB, 0x09, 0x9D, 0xAA, 0x8A, 0xA0, 0xA0, 0x20, 0xF1, 0xDA, 0x6B, 0xAF, 0x89, 0xB3, 0x67, 0xCF, + 0x5E, 0x35, 0x10, 0xA2, 0xA2, 0xA2, 0x42, 0xAC, 0x5C, 0xB9, 0x52, 0x0C, 0x18, 0x30, 0x40, 0x00, + 0xE2, 0x96, 0xDE, 0xDD, 0xC5, 0xC1, 0x95, 0x6F, 0x0B, 0xB1, 0xFF, 0x6B, 0x21, 0xD2, 0xBE, 0x92, + 0xBF, 0xF4, 0x55, 0x42, 0xEC, 0x5F, 0x25, 0xDB, 0xD2, 0x57, 0xC9, 0xB6, 0xFD, 0x5F, 0x8B, 0xC3, + 0x5F, 0xFD, 0x5D, 0x0C, 0x4E, 0xEC, 0x21, 0x00, 0xD1, 0xA3, 0x47, 0x0F, 0xF1, 0x87, 0x3F, 0xFC, + 0x41, 0xAC, 0x5A, 0xB5, 0x4A, 0xAC, 0x5C, 0xB9, 0x52, 0xCC, 0x9A, 0x35, 0x4B, 0xC4, 0xC4, 0xC4, + 0x08, 0x40, 0x84, 0x87, 0x87, 0x8B, 0xFB, 0xEE, 0xBB, 0x4F, 0x4C, 0x9C, 0x38, 0xB1, 0xDE, 0x98, + 0x38, 0x79, 0xF2, 0xE4, 0xFA, 0x60, 0x0B, 0x4D, 0xD3, 0x44, 0x7E, 0x7E, 0xBE, 0x58, 0xBE, 0x7C, + 0xB9, 0x18, 0x3F, 0x7E, 0xBC, 0xF0, 0xF5, 0xF5, 0xBD, 0x1A, 0x63, 0xCE, 0x21, 0x8D, 0x8F, 0xC1, + 0x2D, 0x21, 0x6C, 0x4B, 0x39, 0xA8, 0x20, 0x83, 0x9E, 0x5F, 0x07, 0x86, 0x39, 0x5E, 0x1F, 0x17, + 0x17, 0xC7, 0xF4, 0xE9, 0xD3, 0x49, 0x4E, 0x4E, 0x26, 0x32, 0x32, 0xF2, 0x8A, 0x0B, 0x77, 0xEC, + 0xD8, 0xC1, 0x84, 0x09, 0x13, 0xF0, 0xD4, 0x2B, 0x2C, 0xFF, 0xDB, 0x33, 0x58, 0xEA, 0xEA, 0x48, + 0x3B, 0x7A, 0x9A, 0xD2, 0x8A, 0x4B, 0x04, 0x07, 0xF8, 0x31, 0xA8, 0x57, 0x37, 0x52, 0x7F, 0x3E, + 0xCE, 0x3F, 0x96, 0xAF, 0xA7, 0xEC, 0x52, 0x35, 0x71, 0xF1, 0xF1, 0xDC, 0x39, 0x76, 0x2C, 0x03, + 0x07, 0x0E, 0x24, 0x28, 0x28, 0x88, 0xAA, 0xAA, 0x2A, 0x4E, 0x9C, 0x38, 0xC1, 0x96, 0x2D, 0x5B, + 0xD8, 0xB3, 0x67, 0x0F, 0x96, 0xDA, 0x5A, 0xEE, 0xBA, 0xAD, 0x3F, 0x73, 0x9F, 0x99, 0x42, 0xAF, + 0x6E, 0xD1, 0xA0, 0x39, 0x21, 0x21, 0x54, 0x95, 0x13, 0x67, 0xCE, 0xF3, 0xA7, 0x25, 0xAB, 0xF8, + 0x76, 0x7B, 0x1A, 0x55, 0xE6, 0x1A, 0xDB, 0x23, 0x08, 0x00, 0x02, 0x7C, 0xBD, 0x49, 0xEA, 0x19, + 0xC3, 0xD1, 0xAC, 0xF3, 0x14, 0x97, 0x55, 0xA2, 0x28, 0x0A, 0xE1, 0xE1, 0xE1, 0x24, 0x27, 0x27, + 0x33, 0x7B, 0xF6, 0x6C, 0xC2, 0xC2, 0xC2, 0xAE, 0xE8, 0xB2, 0xBA, 0xBA, 0x9A, 0xD4, 0xD4, 0x54, + 0x96, 0x2E, 0x5D, 0xCA, 0xF7, 0xDF, 0x7F, 0x4F, 0x65, 0x65, 0xA5, 0xE3, 0x69, 0x2B, 0xB0, 0x03, + 0xF8, 0x13, 0x90, 0x82, 0x13, 0x62, 0xAC, 0x25, 0x0C, 0x71, 0x03, 0x26, 0x03, 0x7F, 0x41, 0xAE, + 0x13, 0x80, 0xB4, 0xED, 0x4C, 0x99, 0x32, 0x85, 0x99, 0x33, 0x67, 0xD2, 0xA3, 0x47, 0x8F, 0xAB, + 0x5E, 0x28, 0x84, 0x60, 0xC6, 0x8C, 0x19, 0x2C, 0x58, 0xB0, 0x80, 0xA9, 0xF7, 0x8E, 0x64, 0xC9, + 0x2B, 0xBF, 0xB3, 0x79, 0xDE, 0x84, 0xA4, 0x85, 0x22, 0x87, 0x52, 0x67, 0xA9, 0x63, 0xEB, 0xDE, + 0x43, 0xFC, 0x73, 0xE5, 0xF7, 0x6C, 0x4F, 0x3F, 0x42, 0x65, 0xB5, 0x59, 0x0E, 0x52, 0x51, 0x11, + 0x42, 0x3E, 0x8B, 0x5E, 0xA7, 0x92, 0xD8, 0x2D, 0x9A, 0x69, 0x13, 0x47, 0x32, 0xE5, 0x9E, 0xFF, + 0x20, 0xD0, 0xDF, 0xD7, 0x39, 0x66, 0x38, 0x30, 0xA5, 0xDA, 0x64, 0x66, 0xD7, 0x81, 0x13, 0x6C, + 0xD9, 0x77, 0x98, 0xAC, 0xDC, 0x02, 0x54, 0x45, 0xA1, 0x67, 0x4C, 0x04, 0x63, 0x6E, 0x4D, 0x62, + 0x50, 0xAF, 0x6E, 0x7C, 0xBA, 0x6E, 0x3B, 0x4F, 0xCE, 0x59, 0x4A, 0x78, 0x44, 0x24, 0x5F, 0x7E, + 0xF9, 0x25, 0x43, 0x87, 0x0E, 0x45, 0xA7, 0xBB, 0xF6, 0x72, 0x6B, 0x36, 0x9B, 0xD9, 0xB6, 0x6D, + 0x1B, 0x0B, 0x17, 0x2E, 0x64, 0xD3, 0xA6, 0x4D, 0x8E, 0x81, 0x76, 0x20, 0xE3, 0xBA, 0xDE, 0x04, + 0x96, 0xD0, 0xCC, 0xCE, 0xDE, 0x59, 0x86, 0xF8, 0x02, 0xFF, 0x0B, 0x3C, 0x83, 0x0C, 0x09, 0x05, + 0x20, 0x31, 0x31, 0x91, 0x3F, 0xFE, 0xF1, 0x8F, 0xDC, 0x7B, 0xEF, 0xBD, 0xB8, 0xBB, 0x37, 0xAD, + 0x60, 0x9C, 0x39, 0x73, 0x86, 0x31, 0x63, 0xC7, 0x92, 0x9B, 0x73, 0x96, 0x7F, 0xCD, 0x7B, 0x9E, + 0xBB, 0x6E, 0x1F, 0x08, 0xD6, 0x26, 0x88, 0xA8, 0x53, 0xA9, 0xAA, 0x32, 0xF1, 0xF3, 0xF1, 0x33, + 0xEC, 0x3C, 0x70, 0x82, 0xE3, 0xD9, 0xB9, 0x54, 0x5C, 0xAA, 0xC6, 0xD3, 0xC3, 0x40, 0x4C, 0x78, + 0x30, 0x83, 0x13, 0xBB, 0x33, 0xA4, 0x6F, 0x1C, 0xE1, 0x21, 0x81, 0x36, 0xE1, 0x20, 0x9C, 0x67, + 0x86, 0xE3, 0x53, 0xAB, 0x2A, 0x08, 0xD0, 0xEA, 0xAC, 0xA0, 0x80, 0xAA, 0xD3, 0xD5, 0x4F, 0x96, + 0xBC, 0xA2, 0x52, 0xEE, 0x7A, 0xF2, 0xAF, 0x1C, 0x3D, 0x9B, 0xC7, 0x8A, 0xE5, 0xCB, 0x99, 0x34, + 0x69, 0x92, 0xD3, 0x5D, 0x57, 0x56, 0x56, 0xB2, 0x62, 0xC5, 0x0A, 0xE6, 0xCD, 0x9B, 0xC7, 0x89, + 0x13, 0x27, 0x1C, 0x4F, 0xD5, 0x00, 0xCB, 0x80, 0x57, 0x81, 0xE2, 0xB6, 0x30, 0x24, 0x10, 0x29, + 0xA2, 0xFE, 0x0B, 0x9B, 0xF6, 0xA4, 0xD7, 0xEB, 0x79, 0xE0, 0x81, 0x07, 0xF8, 0xF3, 0x9F, 0xFF, + 0x4C, 0x7C, 0x7C, 0x7C, 0xB3, 0x1D, 0x2C, 0x59, 0xB2, 0x84, 0xE9, 0xD3, 0xA7, 0x33, 0x6C, 0x40, + 0x02, 0xDF, 0xBE, 0xF3, 0x02, 0x01, 0xBE, 0xDE, 0xD7, 0x26, 0xA4, 0x9D, 0x60, 0x80, 0xB0, 0x6A, + 0x68, 0x9A, 0x86, 0xAA, 0x28, 0x28, 0x3A, 0x1D, 0x28, 0x8A, 0x9C, 0x11, 0xAD, 0x61, 0x84, 0xB3, + 0x50, 0x14, 0x5E, 0x5A, 0xB4, 0x9C, 0xBF, 0x2D, 0x5B, 0x43, 0x72, 0x72, 0x32, 0x9F, 0x7E, 0xFA, + 0x29, 0x6E, 0x6E, 0x6E, 0x2D, 0xEA, 0x22, 0x33, 0x33, 0x93, 0xD7, 0x5F, 0x7F, 0x9D, 0x15, 0x2B, + 0x56, 0x38, 0xCE, 0x16, 0x0D, 0x19, 0x01, 0x39, 0x13, 0x99, 0xCB, 0x72, 0x05, 0x9A, 0x33, 0x2E, + 0x86, 0x00, 0xFF, 0x40, 0xAA, 0xB5, 0x7A, 0x90, 0x22, 0xEA, 0x85, 0x17, 0x5E, 0x60, 0xC9, 0x92, + 0x25, 0x4E, 0x31, 0xC3, 0x6C, 0x36, 0xB3, 0x6E, 0xDD, 0x3A, 0x00, 0x26, 0x0C, 0xBF, 0x99, 0x00, + 0x7F, 0x9F, 0xE6, 0x89, 0x29, 0x90, 0x33, 0xC8, 0xAA, 0xA1, 0x00, 0x3A, 0x55, 0x95, 0xAA, 0xB0, + 0xA6, 0x81, 0xD5, 0xEA, 0x5A, 0x66, 0x00, 0xA8, 0x0A, 0x13, 0x86, 0x0F, 0x22, 0xC0, 0xD7, 0x8B, + 0x94, 0x94, 0x14, 0x32, 0x33, 0x33, 0x5B, 0xDC, 0x45, 0xCF, 0x9E, 0x3D, 0x59, 0xBC, 0x78, 0x31, + 0x73, 0xE6, 0xCC, 0x71, 0xF4, 0x09, 0xA9, 0xC0, 0x43, 0xC8, 0x7D, 0x4B, 0xC4, 0x55, 0x6F, 0x7D, + 0x8D, 0x3E, 0x8D, 0x34, 0xEC, 0x2D, 0x54, 0x80, 0x90, 0x90, 0x10, 0xDE, 0x79, 0xE7, 0x1D, 0x5E, + 0x7D, 0xF5, 0x55, 0xFC, 0xFD, 0xFD, 0x9D, 0x1A, 0xD8, 0xF1, 0xE3, 0xC7, 0xF9, 0x69, 0xF7, 0x6E, + 0x42, 0x02, 0xFD, 0x18, 0x3B, 0xA4, 0x9F, 0x7D, 0xFD, 0xBC, 0xBE, 0xA1, 0x69, 0xF4, 0xED, 0x11, + 0xC3, 0x2D, 0x89, 0x3D, 0xB8, 0x70, 0xE1, 0x02, 0x5B, 0xB7, 0x6E, 0x6D, 0x55, 0x37, 0x5E, 0x5E, + 0x5E, 0x3C, 0xF5, 0xD4, 0x53, 0x7C, 0xF0, 0xC1, 0x07, 0xC4, 0xC6, 0xC6, 0x3A, 0x9E, 0xBA, 0x1F, + 0x98, 0x03, 0x5C, 0x41, 0xC4, 0xA6, 0x18, 0xE2, 0x89, 0x4C, 0x1D, 0x98, 0x8C, 0x4D, 0xAC, 0x45, + 0x45, 0x45, 0xB1, 0x68, 0xD1, 0x22, 0xA6, 0x4D, 0x9B, 0xD6, 0xA2, 0xE9, 0xBB, 0x7D, 0xFB, 0x76, + 0x8A, 0x8B, 0x8A, 0xB8, 0xB5, 0x4F, 0x4F, 0xE2, 0xBB, 0x46, 0xB6, 0x6C, 0x01, 0xEE, 0x2C, 0x08, + 0xF0, 0xF6, 0xF6, 0x64, 0xDC, 0xD0, 0x01, 0x00, 0x6C, 0xD8, 0xB0, 0x01, 0xB3, 0xD9, 0xDC, 0xAA, + 0xAE, 0x54, 0x55, 0x65, 0xE2, 0xC4, 0x89, 0x2C, 0x5D, 0xBA, 0xF4, 0x72, 0xA5, 0xE7, 0x11, 0xE4, + 0xBA, 0xDC, 0xC8, 0xC1, 0x75, 0x35, 0x86, 0x28, 0xC0, 0xFF, 0x20, 0xC5, 0x94, 0x0A, 0x92, 0x19, + 0xEF, 0xBE, 0xFB, 0x2E, 0x0F, 0x3D, 0xF4, 0x90, 0xD3, 0xBB, 0x68, 0x90, 0xE2, 0x6A, 0xD3, 0xA6, + 0x4D, 0x00, 0x8C, 0x19, 0x92, 0x84, 0x87, 0xE7, 0x8D, 0x11, 0x42, 0x0A, 0x80, 0x80, 0x11, 0x83, + 0x12, 0x09, 0xF2, 0xF7, 0x21, 0x2D, 0x2D, 0x9D, 0xAC, 0xAC, 0xAC, 0x36, 0x75, 0x37, 0x6A, 0xD4, + 0x28, 0x16, 0x2D, 0x5A, 0x44, 0x54, 0x54, 0x94, 0xBD, 0x49, 0x87, 0xCC, 0x0A, 0xB8, 0xDF, 0xF1, + 0xFF, 0xAE, 0xC6, 0x90, 0x31, 0xC8, 0x0D, 0x8D, 0x01, 0xC0, 0x68, 0x34, 0x32, 0x6F, 0xDE, 0xBC, + 0x46, 0xF9, 0x19, 0xCE, 0x22, 0x3B, 0x3B, 0x9B, 0xF4, 0xFD, 0xFB, 0x09, 0xF2, 0xF7, 0x61, 0xF8, + 0x80, 0x5E, 0x37, 0x86, 0xB8, 0xB2, 0x43, 0x68, 0xC4, 0xC5, 0x44, 0x30, 0x20, 0x3E, 0x96, 0xFC, + 0xFC, 0x3C, 0x76, 0xED, 0xDA, 0xD5, 0xE6, 0x2E, 0xC7, 0x8E, 0x1D, 0xCB, 0x1B, 0x6F, 0xBC, 0xE1, + 0xE8, 0x06, 0xF6, 0x43, 0x66, 0x89, 0xDD, 0x64, 0x6F, 0xB8, 0x9C, 0x21, 0x91, 0x48, 0x51, 0x15, + 0x0A, 0xD2, 0xA9, 0xFF, 0xF2, 0xCB, 0x2F, 0xF3, 0xD0, 0x43, 0x0F, 0xB5, 0x6A, 0x00, 0xE9, 0xE9, + 0xE9, 0xE4, 0x5D, 0xC8, 0xA3, 0x4F, 0xF7, 0x18, 0x7A, 0x44, 0x87, 0x3B, 0xBF, 0x18, 0xAB, 0x2A, + 0xA8, 0xAA, 0x4C, 0xCC, 0x01, 0xD0, 0xA9, 0x52, 0xBB, 0x6A, 0x2D, 0x54, 0x05, 0x54, 0x15, 0xAB, + 0xA6, 0x61, 0xD5, 0xB4, 0xFA, 0xFE, 0xAF, 0x09, 0x01, 0x5E, 0x5E, 0x9E, 0x0C, 0x1F, 0xD8, 0x1B, + 0x80, 0x9D, 0x3B, 0x77, 0xA2, 0xB5, 0x83, 0xB8, 0x4D, 0x4E, 0x4E, 0x66, 0xFA, 0xF4, 0xE9, 0x8E, + 0x4D, 0xFD, 0x90, 0x41, 0xDB, 0x2A, 0x34, 0x96, 0x5F, 0x0A, 0x32, 0x21, 0xE5, 0x36, 0x7B, 0xC3, + 0x23, 0x8F, 0x3C, 0xC2, 0xF4, 0xE9, 0xD3, 0x5B, 0x1D, 0xA8, 0x20, 0xDD, 0xB7, 0x82, 0xDB, 0xFA, + 0xC5, 0xE3, 0xE3, 0xED, 0x09, 0x5A, 0x33, 0x0C, 0x51, 0x14, 0xAC, 0x9A, 0x46, 0xFA, 0xA1, 0x93, + 0xFC, 0x7B, 0xE7, 0x7E, 0x4E, 0x9D, 0xCB, 0xC7, 0xDB, 0xD3, 0xC0, 0x6D, 0x49, 0xF1, 0x8C, 0xBB, + 0x7D, 0x20, 0xA1, 0x41, 0x01, 0x2D, 0x5F, 0x83, 0x14, 0x85, 0x53, 0x39, 0x79, 0xFC, 0x6B, 0xCB, + 0x5E, 0xD2, 0x8F, 0x67, 0x61, 0xB5, 0x6A, 0x24, 0x76, 0x8F, 0xE6, 0xFE, 0x11, 0xB7, 0xD0, 0x37, + 0xEE, 0xA6, 0x6B, 0xAB, 0x99, 0x8A, 0xC2, 0xAD, 0x7D, 0x7B, 0xE2, 0xAE, 0xD7, 0x91, 0x91, 0x91, + 0x41, 0x49, 0x49, 0x49, 0x9B, 0xA3, 0x68, 0xDC, 0xDC, 0xDC, 0x78, 0xE6, 0x99, 0x67, 0x48, 0x49, + 0x49, 0x61, 0xEF, 0xDE, 0xBD, 0xF6, 0xE6, 0xC9, 0xC0, 0x72, 0x60, 0xBF, 0x23, 0x43, 0xFA, 0x03, + 0x53, 0xED, 0x07, 0x7D, 0xFA, 0xF4, 0xE1, 0xC5, 0x17, 0x5F, 0xC4, 0xCB, 0xCB, 0xCB, 0xE9, 0x9B, + 0x39, 0xA2, 0xAC, 0xAC, 0x8C, 0xFD, 0xFB, 0xF7, 0xA3, 0x53, 0x15, 0x86, 0xF4, 0xED, 0x09, 0x8A, + 0x4A, 0x73, 0x91, 0xFB, 0xB5, 0x96, 0x3A, 0x16, 0xAE, 0xFC, 0x9E, 0x39, 0x1F, 0x7F, 0x43, 0xE1, + 0xC5, 0xF2, 0xFA, 0xF6, 0x65, 0xDF, 0x6C, 0x65, 0xD8, 0x80, 0x04, 0xDE, 0x79, 0x76, 0x2A, 0xFD, + 0x13, 0x62, 0x9D, 0x67, 0x8A, 0xA2, 0xF0, 0x7D, 0xEA, 0x7E, 0x9E, 0x7D, 0xE7, 0x53, 0x8E, 0x9D, + 0x69, 0x50, 0xFB, 0xBF, 0xDE, 0xBC, 0x9B, 0x0F, 0xD7, 0x6E, 0xE6, 0x2F, 0xFF, 0x93, 0xCC, 0xA3, + 0xE3, 0xFF, 0x03, 0xB5, 0xA9, 0xD9, 0xA7, 0x69, 0xF4, 0x8E, 0xED, 0x42, 0xD7, 0x88, 0x10, 0x4E, + 0x67, 0x65, 0x71, 0xF2, 0xE4, 0xC9, 0x76, 0x09, 0x6B, 0x8A, 0x8A, 0x8A, 0x62, 0xE6, 0xCC, 0x99, + 0x4C, 0x9D, 0x3A, 0xD5, 0xAE, 0x2C, 0x44, 0x00, 0x8F, 0x02, 0x19, 0xF6, 0x17, 0x44, 0x05, 0xA6, + 0x61, 0x33, 0x89, 0xB8, 0xBB, 0xBB, 0x33, 0x6B, 0xD6, 0xAC, 0x26, 0x4D, 0x21, 0xCE, 0xE0, 0xEC, + 0xD9, 0xB3, 0x64, 0x9E, 0x3A, 0x45, 0x44, 0x70, 0x20, 0xBD, 0xBB, 0x75, 0x01, 0xD1, 0x0C, 0x11, + 0x55, 0x95, 0x55, 0x9B, 0x7E, 0xE2, 0xD5, 0xF7, 0xBE, 0x6A, 0xC4, 0x0C, 0x2F, 0x2F, 0x2F, 0xFC, + 0xFC, 0xFD, 0xD9, 0x96, 0x7E, 0x94, 0x67, 0xDE, 0xFE, 0x88, 0x82, 0xE2, 0x8B, 0xCE, 0x89, 0x2F, + 0x55, 0xE5, 0xF0, 0xE9, 0x1C, 0x66, 0xBC, 0xFD, 0x71, 0x23, 0x66, 0x18, 0x0C, 0x06, 0xC2, 0xC2, + 0xC2, 0x28, 0x2C, 0xAB, 0xE2, 0xF9, 0x7F, 0x7C, 0xCE, 0x96, 0x7D, 0x87, 0x9B, 0x16, 0x5F, 0x42, + 0x10, 0x1E, 0xE4, 0x4F, 0xBF, 0xB8, 0x9B, 0xA8, 0xBA, 0x74, 0x89, 0xB4, 0xB4, 0xB4, 0x36, 0x33, + 0xC3, 0x8E, 0x71, 0xE3, 0xC6, 0x31, 0x7C, 0xF8, 0x70, 0xC7, 0xA6, 0x7B, 0x80, 0x04, 0xFB, 0x48, + 0x12, 0x80, 0xFB, 0xEC, 0x67, 0x46, 0x8C, 0x18, 0xC1, 0x03, 0x0F, 0x3C, 0xD0, 0xA6, 0x1B, 0x1E, + 0x3D, 0x7A, 0x94, 0xD2, 0x92, 0x12, 0xE2, 0xBB, 0x46, 0x12, 0x19, 0x62, 0xBC, 0xB6, 0xB8, 0x52, + 0x14, 0xCA, 0x2B, 0x2E, 0xF1, 0xFE, 0xEA, 0x8D, 0x54, 0x99, 0x1A, 0xD4, 0xCB, 0xBE, 0x7D, 0xFB, + 0xB2, 0x72, 0xE5, 0x4A, 0x36, 0x6F, 0xDE, 0xCC, 0x13, 0x4F, 0x3C, 0xC1, 0x4F, 0x87, 0x32, 0xF9, + 0x2E, 0x25, 0x4D, 0xAE, 0x09, 0xCD, 0x41, 0x08, 0xBE, 0x58, 0xBF, 0x83, 0xCC, 0x9C, 0x86, 0x78, + 0x5C, 0xA3, 0xD1, 0xC8, 0xFC, 0xF9, 0xF3, 0x49, 0x49, 0x49, 0xE1, 0xBD, 0xF7, 0xDE, 0x45, 0xE8, + 0xDD, 0xF9, 0x60, 0xCD, 0x26, 0x2C, 0xB5, 0x4D, 0x47, 0xF2, 0xE8, 0xDD, 0xDD, 0xE4, 0x0C, 0x07, + 0xF6, 0xEC, 0xD9, 0xE3, 0x98, 0xB0, 0xD3, 0x26, 0xF8, 0xF9, 0xF9, 0x31, 0x79, 0xF2, 0x64, 0xC7, + 0x68, 0xFA, 0x58, 0x60, 0xBC, 0x9D, 0x21, 0xE3, 0xB1, 0xCD, 0x0E, 0x83, 0xC1, 0xC0, 0xB4, 0x69, + 0xD3, 0x9C, 0xDE, 0xF8, 0x35, 0x85, 0x43, 0x87, 0x0E, 0x01, 0x90, 0xD8, 0x3D, 0x06, 0x2F, 0x8F, + 0x66, 0xD4, 0x5D, 0x45, 0xE1, 0x6C, 0x5E, 0x11, 0xC7, 0xCE, 0x9C, 0x6F, 0xD4, 0xFC, 0xE4, 0x93, + 0x4F, 0x32, 0x7E, 0xFC, 0x78, 0x06, 0x0C, 0x18, 0xC0, 0x8B, 0x2F, 0xBE, 0x48, 0x74, 0xD7, 0x9B, + 0x48, 0xFD, 0xF9, 0x78, 0xD3, 0x76, 0x30, 0x07, 0x98, 0xCC, 0x35, 0xEC, 0x3D, 0x72, 0xAA, 0x51, + 0xDB, 0x98, 0x31, 0x63, 0x78, 0xFC, 0xF1, 0xC7, 0x89, 0x8B, 0x8B, 0xE3, 0xB1, 0xC7, 0x1E, 0x63, + 0xC2, 0x84, 0x09, 0xA4, 0x1F, 0x3B, 0x4D, 0x71, 0x59, 0xE5, 0x35, 0x66, 0x9D, 0x42, 0xBF, 0xB8, + 0x9B, 0x70, 0xD7, 0xEB, 0x38, 0x7E, 0xFC, 0x38, 0xE5, 0xE5, 0xE5, 0xCD, 0xDE, 0xDB, 0x59, 0x8C, + 0x1A, 0x35, 0x8A, 0xEE, 0xDD, 0xEB, 0x73, 0x7E, 0x74, 0xC0, 0x44, 0x15, 0xB9, 0x5B, 0xBC, 0xDB, + 0xDE, 0xDA, 0xB7, 0x6F, 0x5F, 0x46, 0x8F, 0x1E, 0xDD, 0xA6, 0x1B, 0x59, 0x2C, 0x16, 0x8E, 0x1E, + 0x3D, 0x2A, 0xFB, 0xEB, 0x11, 0xD3, 0xBC, 0x46, 0xA3, 0x80, 0xB9, 0xD6, 0x42, 0xAD, 0xA5, 0xF1, + 0xDB, 0x27, 0x1C, 0xB4, 0x32, 0x21, 0x04, 0x08, 0x41, 0xB5, 0xB9, 0x06, 0xAD, 0x39, 0x6D, 0x4D, + 0x01, 0xAB, 0x55, 0xC3, 0x5C, 0xD3, 0xF8, 0xCD, 0xB7, 0x58, 0x2C, 0xF5, 0x9A, 0x92, 0xA6, 0x69, + 0xD4, 0xD6, 0xD6, 0x52, 0x6B, 0xA9, 0xA3, 0xCE, 0x6A, 0x6D, 0xDA, 0xAA, 0x27, 0x34, 0x62, 0x23, + 0x43, 0x09, 0x35, 0xFA, 0x93, 0x9D, 0x9D, 0x4D, 0x4A, 0x4A, 0x0A, 0x15, 0x15, 0x15, 0x8D, 0xC6, + 0xD6, 0x52, 0x54, 0x57, 0x57, 0x93, 0x9E, 0x9E, 0xCE, 0xFB, 0xEF, 0xBF, 0x7F, 0x79, 0xE0, 0x5D, + 0x92, 0x1E, 0x48, 0x44, 0x66, 0xCA, 0x02, 0x70, 0xF7, 0xDD, 0x77, 0x13, 0x1C, 0xDC, 0x22, 0x9F, + 0xCA, 0x15, 0xA8, 0xA8, 0xA8, 0xE0, 0xCC, 0x99, 0x33, 0x78, 0xB8, 0xEB, 0xE9, 0x19, 0x13, 0x4E, + 0xB3, 0x1B, 0x10, 0x21, 0x08, 0x0F, 0x0A, 0x20, 0xD4, 0xE8, 0x47, 0x45, 0x55, 0x83, 0x75, 0x7A, + 0xD1, 0xA2, 0x45, 0x44, 0x44, 0x44, 0x10, 0x15, 0x15, 0xC5, 0x87, 0x1F, 0x7E, 0xC8, 0xE9, 0xAC, + 0xD3, 0x3C, 0x3C, 0xA2, 0x9F, 0xB4, 0xCC, 0x5E, 0x6B, 0x61, 0x17, 0xE0, 0xE5, 0x61, 0xA0, 0x47, + 0x74, 0x38, 0xBB, 0x0E, 0x36, 0x58, 0x5C, 0x37, 0x6E, 0xDC, 0xC8, 0xDC, 0xB9, 0x73, 0x19, 0x33, + 0x66, 0x0C, 0x3B, 0x76, 0xEC, 0xE0, 0xBB, 0xEF, 0xD6, 0x31, 0xA0, 0x47, 0x24, 0x81, 0xBE, 0xDE, + 0x4D, 0x0F, 0x51, 0x40, 0xA8, 0xD1, 0x9F, 0xAE, 0x11, 0x21, 0xA4, 0x1E, 0x38, 0xC1, 0x6F, 0x7F, + 0xFB, 0x5B, 0x12, 0x12, 0x12, 0x18, 0x32, 0x64, 0x08, 0x83, 0x07, 0x0F, 0xA6, 0x7B, 0xF7, 0xEE, + 0x44, 0x45, 0x45, 0x11, 0x18, 0x18, 0x88, 0xC1, 0x60, 0x40, 0xA7, 0xD3, 0xD5, 0x6F, 0x9E, 0x35, + 0x4D, 0xC3, 0x62, 0xB1, 0x50, 0x5D, 0x5D, 0x4D, 0x71, 0x71, 0x31, 0xA7, 0x4F, 0x9F, 0x26, 0x2D, + 0x2D, 0x8D, 0x94, 0x94, 0x14, 0x32, 0x32, 0x32, 0x28, 0x2E, 0xBE, 0xC2, 0xE8, 0x9B, 0xAB, 0x47, + 0xAA, 0xB9, 0x46, 0x00, 0x6F, 0x6F, 0x6F, 0x46, 0x8C, 0x18, 0xD1, 0x26, 0x66, 0x00, 0x14, 0x14, + 0x14, 0x90, 0x97, 0x9F, 0x4F, 0x90, 0xBF, 0x2F, 0x51, 0xA1, 0xC6, 0xE6, 0x37, 0x84, 0x9A, 0xA0, + 0x4B, 0x58, 0x10, 0xE3, 0x6E, 0x1F, 0xC8, 0x3F, 0x97, 0xAF, 0xAF, 0x6F, 0x3E, 0x7C, 0xF8, 0x30, + 0x0F, 0x3F, 0xFC, 0x30, 0xEE, 0xEE, 0xEE, 0x94, 0x57, 0x54, 0x10, 0x66, 0xF4, 0x63, 0xC2, 0xF0, + 0x41, 0x4E, 0x8D, 0x41, 0x75, 0xD3, 0x31, 0x69, 0xF4, 0xAD, 0xAC, 0xD9, 0xBA, 0x87, 0x4B, 0x36, + 0xBF, 0x4A, 0x65, 0x65, 0x25, 0xAF, 0xBD, 0xF6, 0x1A, 0x73, 0xE6, 0xCC, 0xA1, 0xBA, 0xBA, 0x1A, + 0x10, 0x3C, 0x74, 0xC7, 0x6D, 0xF8, 0xF8, 0x78, 0x35, 0xCD, 0x60, 0x21, 0xF0, 0xF1, 0xF2, 0x20, + 0xBE, 0x6B, 0x24, 0xA9, 0x07, 0x4E, 0x50, 0x5E, 0x5E, 0xCE, 0x9E, 0x3D, 0x7B, 0xD8, 0xB3, 0x67, + 0x0F, 0x3A, 0x9D, 0x0E, 0x1F, 0x1F, 0x1F, 0x42, 0x42, 0x42, 0x88, 0x88, 0x88, 0x20, 0x28, 0x28, + 0x08, 0x5F, 0x5F, 0x5F, 0x0C, 0x06, 0x03, 0x9A, 0xA6, 0x51, 0x5D, 0x5D, 0x4D, 0x59, 0x59, 0x19, + 0x85, 0x85, 0x85, 0x14, 0x14, 0x14, 0x50, 0x52, 0x52, 0xD2, 0x94, 0x09, 0x46, 0x43, 0x66, 0xF6, + 0xBE, 0xAA, 0x47, 0x3A, 0xE8, 0x55, 0x80, 0x2E, 0x5D, 0xBA, 0x90, 0x90, 0x90, 0xD0, 0x6A, 0x46, + 0x98, 0xCD, 0x66, 0x32, 0x32, 0x32, 0x58, 0xB8, 0x70, 0x21, 0x45, 0x85, 0x45, 0x0C, 0x4C, 0x88, + 0x25, 0xC8, 0xDF, 0xD7, 0xA9, 0x0D, 0xA1, 0xAA, 0x53, 0x99, 0xF9, 0xC8, 0x3D, 0x1C, 0x3C, 0x79, + 0x96, 0x6D, 0xE9, 0x47, 0xEA, 0xDB, 0x4D, 0x26, 0x13, 0x26, 0x93, 0x09, 0x1F, 0x4F, 0x0F, 0x66, + 0x3F, 0x76, 0x1F, 0x37, 0xF7, 0xEE, 0xEE, 0x9C, 0xDA, 0x6B, 0xD5, 0xB8, 0xEB, 0xB6, 0xFE, 0x3C, + 0x9D, 0x7C, 0x37, 0xF3, 0x3E, 0x5F, 0x47, 0x8D, 0x6D, 0xE1, 0xB6, 0x5A, 0xAD, 0x54, 0x56, 0x56, + 0xA2, 0x53, 0x55, 0x7E, 0x33, 0x6E, 0x38, 0x53, 0xC6, 0x0D, 0x6B, 0x76, 0x7C, 0x8A, 0x4E, 0x27, + 0x35, 0xC5, 0xCB, 0x6F, 0x61, 0xB5, 0x52, 0x5E, 0x5E, 0x4E, 0x79, 0x79, 0x39, 0xA7, 0x4E, 0x9D, + 0xA2, 0x15, 0xA8, 0x46, 0x46, 0x79, 0xAE, 0x04, 0xD6, 0x00, 0xE7, 0xF5, 0xC8, 0x48, 0x09, 0x40, + 0x9A, 0x8C, 0x5B, 0x2A, 0xAE, 0xEA, 0xEA, 0xEA, 0x38, 0x7F, 0xFE, 0x3C, 0x5B, 0xB7, 0x6E, 0x65, + 0xCD, 0x9A, 0x35, 0xEC, 0xDA, 0xB5, 0xAB, 0x5E, 0x2E, 0x46, 0x04, 0x07, 0xE0, 0xED, 0x61, 0x70, + 0x6E, 0x87, 0xAE, 0x09, 0x6E, 0x8A, 0x0A, 0xE5, 0xE3, 0x3F, 0x3D, 0xC9, 0x3F, 0x97, 0xAF, 0x67, + 0xDD, 0xCE, 0x74, 0x8A, 0x4A, 0x2B, 0x70, 0x73, 0xD3, 0xD3, 0x3B, 0xB6, 0x0B, 0xBF, 0x7B, 0x70, + 0x0C, 0xF7, 0x8F, 0xBA, 0x15, 0x55, 0x55, 0x9C, 0x36, 0xC1, 0xB8, 0xBB, 0xB9, 0xF1, 0xF2, 0xE3, + 0x0F, 0xD2, 0xA3, 0x4B, 0x38, 0x1F, 0x7D, 0xB7, 0x8D, 0x53, 0xE7, 0xF2, 0xD1, 0x34, 0x8D, 0xE8, + 0xB0, 0x20, 0x92, 0xEF, 0x1C, 0xCA, 0xB4, 0x89, 0xA3, 0xF1, 0x6F, 0xCE, 0x37, 0x63, 0x43, 0xD7, + 0x88, 0x10, 0x74, 0x3A, 0x15, 0xAB, 0x54, 0x28, 0x34, 0xA4, 0x93, 0xC9, 0x1B, 0x59, 0xC0, 0xC6, + 0x59, 0x33, 0x42, 0x1D, 0x32, 0x0E, 0xE1, 0x14, 0x32, 0x38, 0xE4, 0x47, 0x64, 0xD8, 0x54, 0x99, + 0xFD, 0x1F, 0xF4, 0x38, 0xD8, 0xE5, 0x2D, 0x16, 0x0B, 0x07, 0x0F, 0x1E, 0x24, 0x2A, 0x2A, 0x0A, + 0x3F, 0x3F, 0x3F, 0x0C, 0x06, 0x03, 0xAA, 0xCD, 0x17, 0xA1, 0x69, 0x1A, 0x75, 0x75, 0x75, 0x98, + 0x4C, 0x26, 0x4A, 0x4B, 0x4B, 0xC9, 0xCE, 0xCE, 0xE6, 0xC0, 0x81, 0x03, 0xEC, 0xDE, 0xBD, 0x9B, + 0x7D, 0xFB, 0xF6, 0x71, 0xEE, 0xDC, 0xB9, 0x2B, 0xEA, 0x94, 0x44, 0x86, 0x04, 0xE2, 0xEE, 0xD6, + 0x82, 0x68, 0x7D, 0x4D, 0xD0, 0x35, 0x32, 0x84, 0xB7, 0x9E, 0x99, 0xC2, 0xAC, 0xC9, 0xE3, 0x29, + 0xBC, 0x58, 0x8E, 0xC1, 0xDD, 0x8D, 0xE8, 0xB0, 0x20, 0x7C, 0x7D, 0xBC, 0x6D, 0x8E, 0x29, 0xE7, + 0xBB, 0x43, 0x08, 0x3C, 0x0D, 0x6E, 0x4C, 0xBD, 0x6F, 0x34, 0x93, 0x46, 0x0F, 0x21, 0xBF, 0xF8, + 0x22, 0x56, 0x4D, 0x10, 0x16, 0xE4, 0x4F, 0xA0, 0xBF, 0xAF, 0xA4, 0xA2, 0x53, 0x8B, 0xB3, 0x5C, + 0xE3, 0x3C, 0xDD, 0xDD, 0xB9, 0x24, 0xD5, 0xF2, 0x3A, 0xE0, 0x0F, 0xC8, 0x52, 0x4E, 0x7D, 0x80, + 0x18, 0x64, 0x5C, 0x5A, 0x28, 0x32, 0x11, 0x54, 0x8F, 0xD4, 0x9A, 0xAA, 0x6D, 0xC4, 0x2E, 0x45, + 0xC6, 0x6F, 0x1D, 0x47, 0x56, 0x27, 0x3A, 0x8B, 0x2C, 0x6C, 0x73, 0xC5, 0xCD, 0xF5, 0x38, 0x64, + 0x92, 0x6E, 0xDC, 0xB8, 0x91, 0x3D, 0x7B, 0xF6, 0x10, 0x1A, 0x1A, 0x4A, 0x68, 0x68, 0x28, 0x46, + 0xA3, 0x11, 0x2F, 0x2F, 0x2F, 0x54, 0x55, 0xA5, 0xB6, 0xB6, 0x96, 0xCA, 0xCA, 0x4A, 0x8A, 0x8B, + 0x8B, 0x29, 0x2C, 0x2C, 0xA4, 0xA4, 0xA4, 0x04, 0x93, 0xC9, 0x74, 0x4D, 0x6D, 0x23, 0x24, 0xD0, + 0x5F, 0x6A, 0x58, 0x2D, 0x31, 0x77, 0x68, 0x02, 0x9D, 0xA2, 0x10, 0x15, 0x16, 0x44, 0x54, 0x78, + 0x70, 0x3D, 0x61, 0x5B, 0x6D, 0xB6, 0x17, 0x80, 0xD0, 0xF0, 0xF3, 0xF1, 0xC2, 0xCF, 0xD7, 0xBB, + 0xA1, 0xBF, 0x96, 0x68, 0x49, 0x02, 0x42, 0x02, 0xFD, 0xF0, 0xF5, 0xF6, 0xB0, 0x33, 0xC4, 0x1D, + 0x39, 0x4B, 0x76, 0xD8, 0x7E, 0x20, 0x67, 0x89, 0x3B, 0x52, 0xFC, 0xEB, 0x6C, 0xC7, 0x16, 0x1B, + 0xF3, 0x9C, 0xAE, 0x6C, 0xA7, 0x07, 0x7E, 0x02, 0x46, 0x83, 0xD4, 0x0A, 0xCA, 0xCA, 0xCA, 0x28, + 0x2B, 0x2B, 0xE3, 0xE4, 0xC9, 0x93, 0x2D, 0x7D, 0xF4, 0x3A, 0xE0, 0x02, 0xD2, 0xCB, 0xE8, 0x09, + 0x10, 0xE4, 0xEF, 0xD3, 0x7A, 0xA3, 0x60, 0x4B, 0x89, 0xE6, 0xCA, 0xFE, 0x84, 0x20, 0xD0, 0xD7, + 0x9B, 0x40, 0x3F, 0x1F, 0xF2, 0x8A, 0xCB, 0xEC, 0xAD, 0x51, 0x97, 0xFF, 0x17, 0xD2, 0x6F, 0xDE, + 0x26, 0xE8, 0x91, 0x36, 0xF9, 0x67, 0x80, 0xE1, 0xC8, 0xCD, 0xA1, 0x0F, 0xCE, 0xC9, 0xC4, 0x3A, + 0xE4, 0xB4, 0xCB, 0x46, 0xCA, 0xC1, 0x6D, 0xC0, 0x79, 0x64, 0x15, 0xB7, 0xAE, 0x00, 0x7E, 0xDE, + 0xED, 0x9A, 0xED, 0xD5, 0x89, 0x10, 0x78, 0x7B, 0x7A, 0x60, 0xF4, 0xF3, 0x71, 0x6C, 0x0C, 0x72, + 0xC5, 0x9D, 0xF4, 0x48, 0xB9, 0xF6, 0x7B, 0x64, 0x40, 0x57, 0x37, 0xE4, 0xBE, 0xA4, 0x2B, 0xD2, + 0x14, 0x1F, 0x8C, 0x9C, 0x86, 0x3A, 0xA4, 0x65, 0xB0, 0x0C, 0x29, 0x0F, 0xCF, 0x03, 0x27, 0x69, + 0x90, 0x87, 0x17, 0x91, 0x6F, 0x48, 0x4F, 0x1C, 0xEA, 0x61, 0x79, 0x7A, 0x18, 0x3A, 0xAF, 0x88, + 0x60, 0x7B, 0x42, 0x80, 0x9B, 0x5E, 0x87, 0xBF, 0x4F, 0x23, 0x43, 0x6B, 0xDB, 0x4C, 0x19, 0x4D, + 0xC0, 0xBE, 0xE2, 0xD6, 0x21, 0x6B, 0x1E, 0xE6, 0x03, 0x76, 0x4F, 0x8C, 0x62, 0x3B, 0xEF, 0xB8, + 0xCD, 0xAE, 0xE3, 0xDA, 0x26, 0x5B, 0x9D, 0xFD, 0xFF, 0x55, 0x45, 0xC1, 0x5D, 0xAF, 0xBB, 0xB1, + 0x9C, 0x52, 0xD7, 0x22, 0x94, 0x5E, 0x87, 0x6F, 0xE3, 0x19, 0xEF, 0x47, 0xC3, 0x8B, 0xDA, 0x7E, + 0xF7, 0xB9, 0xC6, 0x39, 0xC1, 0x2F, 0xB4, 0xD6, 0x60, 0x6B, 0xA0, 0x2A, 0x0A, 0x9E, 0x86, 0x46, + 0xB1, 0x67, 0x9E, 0xB8, 0x80, 0x21, 0xED, 0x9D, 0x63, 0x58, 0x3F, 0x1F, 0x84, 0x10, 0xD2, 0x3B, + 0xF7, 0x4B, 0x10, 0x59, 0x00, 0x8A, 0x82, 0xA1, 0xB1, 0x0A, 0x6F, 0xD7, 0xA4, 0xDA, 0x15, 0xED, + 0xCD, 0x90, 0x1A, 0xA0, 0x16, 0x40, 0x13, 0x82, 0x6A, 0x73, 0xED, 0x2F, 0x46, 0x64, 0x01, 0x97, + 0x07, 0x78, 0xDC, 0x30, 0x0C, 0x31, 0xD9, 0x0F, 0x2A, 0xAA, 0x4C, 0x6D, 0xE8, 0xEA, 0x3A, 0x83, + 0x10, 0xD2, 0x2A, 0xDC, 0x00, 0x0D, 0x17, 0xBC, 0x6E, 0xED, 0xCD, 0x10, 0x13, 0xB2, 0xCE, 0x09, + 0x00, 0x45, 0xA5, 0xE5, 0xAE, 0x8F, 0x32, 0xEC, 0x20, 0x08, 0x21, 0x30, 0x35, 0x36, 0xE7, 0x9B, + 0x70, 0x41, 0x35, 0x39, 0x57, 0x30, 0xA4, 0xBE, 0x70, 0xC0, 0x85, 0xE2, 0x8B, 0x88, 0x1B, 0x21, + 0x30, 0xCE, 0x09, 0x58, 0x35, 0x8D, 0x4B, 0xD5, 0x8D, 0x66, 0xFC, 0x0D, 0xC1, 0x90, 0x1A, 0x1C, + 0x82, 0x88, 0xCF, 0xE6, 0x15, 0x61, 0x32, 0xB7, 0x79, 0xF3, 0xDA, 0xF9, 0x50, 0xA0, 0xA6, 0xB6, + 0x8E, 0x92, 0xF2, 0x4B, 0x8E, 0xAD, 0xC5, 0xDC, 0x00, 0x22, 0x0B, 0xE4, 0x66, 0x11, 0x80, 0x9C, + 0xFC, 0x62, 0xF9, 0x10, 0x6D, 0x89, 0xA9, 0xBA, 0x2E, 0xA0, 0x70, 0xC9, 0x64, 0x96, 0xAE, 0xDE, + 0x06, 0xB4, 0x7B, 0xF1, 0x32, 0x70, 0x5D, 0x69, 0x8D, 0x5A, 0x80, 0xFC, 0x92, 0x32, 0x4E, 0x9D, + 0xCB, 0x77, 0x2E, 0x28, 0xE1, 0x7A, 0x86, 0xA2, 0x50, 0x50, 0x5A, 0x4E, 0x51, 0x43, 0x34, 0x8C, + 0x40, 0x5A, 0x2B, 0xDA, 0x1D, 0xAE, 0x60, 0xC8, 0x49, 0x64, 0x26, 0x2A, 0x55, 0xA6, 0x2B, 0x03, + 0x0D, 0x6E, 0x48, 0x28, 0x0A, 0xA7, 0xCE, 0xE5, 0x53, 0x7E, 0xA9, 0xDE, 0xBD, 0x5C, 0x89, 0xF4, + 0x69, 0xB4, 0x3B, 0x5C, 0xC1, 0x90, 0x73, 0xC8, 0xCF, 0x4E, 0x00, 0xB0, 0x65, 0xDF, 0x61, 0xAA, + 0xAB, 0xCD, 0x9D, 0xBF, 0x41, 0x54, 0x14, 0x19, 0x92, 0xDA, 0x9A, 0x28, 0x4C, 0x21, 0xD8, 0x77, + 0xE4, 0x14, 0x96, 0xBA, 0xFA, 0x35, 0x3C, 0x1F, 0x69, 0xC3, 0x6B, 0x77, 0xB8, 0x82, 0x21, 0x26, + 0xE4, 0x57, 0x6E, 0x00, 0x48, 0x3F, 0x96, 0xC5, 0xE1, 0x53, 0x39, 0xAD, 0x23, 0x84, 0x1D, 0x8A, + 0xD2, 0x40, 0xD0, 0x96, 0xAE, 0x47, 0x0A, 0xA0, 0xD3, 0x51, 0x71, 0xA9, 0x9A, 0x9D, 0xE9, 0x47, + 0x39, 0x9E, 0xD5, 0xC2, 0x4F, 0x82, 0x28, 0x0A, 0xE5, 0x95, 0x97, 0xD8, 0x91, 0x71, 0xDC, 0xB1, + 0xF5, 0x20, 0x36, 0x29, 0xD0, 0xDE, 0x70, 0xD5, 0x67, 0x18, 0x36, 0xDB, 0x06, 0x1C, 0x52, 0x52, + 0x5E, 0xC9, 0xAA, 0x4D, 0xBB, 0x19, 0xDC, 0xA7, 0xF5, 0x51, 0x90, 0xCB, 0x37, 0xEC, 0x64, 0xF7, + 0xA1, 0x4C, 0x46, 0xDF, 0xD2, 0x87, 0x61, 0x03, 0x7B, 0x39, 0x9F, 0xE8, 0xA9, 0x28, 0x54, 0x9B, + 0x6B, 0xF8, 0xF1, 0xA7, 0x03, 0x2C, 0x59, 0xB3, 0x91, 0xED, 0xFB, 0x8F, 0xD2, 0x3B, 0x36, 0x9A, + 0xB5, 0xF3, 0x9E, 0x27, 0x2A, 0x2C, 0xC8, 0xB9, 0x3D, 0x92, 0xAA, 0xB0, 0xF7, 0xC8, 0x69, 0x0E, + 0x64, 0x66, 0xDB, 0x5B, 0x84, 0xED, 0xF9, 0x5C, 0x62, 0xE7, 0x73, 0x55, 0x8D, 0x8E, 0x12, 0x64, + 0xAC, 0x70, 0x1F, 0x80, 0x0B, 0xC5, 0xA5, 0x8C, 0x1D, 0xD2, 0x8F, 0x90, 0xA0, 0x80, 0x96, 0x6D, + 0x14, 0x6D, 0x8B, 0xE9, 0xF4, 0xD7, 0xDF, 0xE7, 0xDB, 0x94, 0x34, 0xD6, 0x6E, 0xDF, 0xC7, 0xB6, + 0xB4, 0x23, 0x18, 0xFD, 0x7C, 0xE8, 0xD9, 0x35, 0xB2, 0xE9, 0x98, 0x5C, 0xDB, 0xB5, 0x85, 0x17, + 0xCB, 0xF9, 0xDF, 0x7F, 0x7C, 0xC6, 0x6B, 0xEF, 0x7F, 0xC5, 0xB1, 0xEC, 0x5C, 0x2C, 0x75, 0x56, + 0xAA, 0xCC, 0x35, 0xDC, 0x3F, 0x62, 0x30, 0x51, 0xE1, 0xCE, 0x31, 0xA4, 0xCE, 0x6A, 0xE5, 0x8D, + 0x65, 0xFF, 0x62, 0xEF, 0xE1, 0xFA, 0x25, 0xE3, 0x3C, 0x32, 0x13, 0xB9, 0xB8, 0xD9, 0x8B, 0x5B, + 0x01, 0x57, 0xD5, 0xDF, 0xAB, 0x45, 0x3A, 0xAA, 0xAA, 0x01, 0xB2, 0x2F, 0x14, 0xB1, 0x74, 0xED, + 0x16, 0xB4, 0x56, 0x84, 0x61, 0x6A, 0x9A, 0x46, 0x8D, 0x45, 0x7A, 0x40, 0xCD, 0x35, 0xB5, 0xA4, + 0x1E, 0x38, 0xC1, 0xB4, 0x3F, 0x2D, 0xE6, 0x93, 0xEF, 0xB6, 0x35, 0xBD, 0x2E, 0xD9, 0x66, 0xC6, + 0x4B, 0x0B, 0x97, 0xB3, 0x74, 0xED, 0x16, 0xCC, 0x0E, 0xA1, 0xA2, 0x31, 0xE1, 0xC1, 0x44, 0x85, + 0x19, 0x9B, 0x8F, 0xC4, 0x07, 0xD0, 0xA9, 0xEC, 0x3B, 0x72, 0x8A, 0x75, 0x3B, 0xD2, 0x1D, 0x5B, + 0xBF, 0x47, 0xFA, 0xD2, 0x5D, 0x02, 0x57, 0x16, 0x44, 0xDC, 0x82, 0x8C, 0xAA, 0x00, 0xE0, 0xCB, + 0xEF, 0x77, 0xB0, 0xEB, 0xE0, 0x49, 0xB9, 0x0E, 0x38, 0x0B, 0x21, 0x08, 0x33, 0x06, 0x70, 0xD7, + 0x6D, 0xFD, 0xEB, 0x9B, 0xBC, 0x3D, 0x0D, 0x18, 0xDC, 0xDD, 0x78, 0xE5, 0xDD, 0x15, 0xEC, 0xFC, + 0xF9, 0xC4, 0xD5, 0xD7, 0x26, 0x45, 0x61, 0xD5, 0xC6, 0x9F, 0xF8, 0xF4, 0xDF, 0xDB, 0x19, 0x79, + 0x73, 0x62, 0xFD, 0xF5, 0xC1, 0x01, 0xBE, 0x3C, 0x3F, 0xE5, 0x5E, 0x19, 0x6B, 0xEC, 0x44, 0xF4, + 0xA3, 0xD9, 0x5C, 0xC3, 0xA2, 0xAF, 0x7E, 0xA0, 0xE8, 0x62, 0x85, 0xBD, 0xB5, 0x14, 0x17, 0x7F, + 0xD8, 0xC5, 0x95, 0x65, 0x85, 0x2C, 0x48, 0xD1, 0x75, 0x2F, 0xE0, 0x51, 0x65, 0xAA, 0xA1, 0xE8, + 0x62, 0x05, 0xF7, 0x0C, 0x1D, 0x88, 0x87, 0xC1, 0xF9, 0xA2, 0x39, 0x8A, 0xAA, 0x92, 0xD4, 0xB3, + 0x2B, 0x25, 0x65, 0x95, 0x14, 0x94, 0x94, 0x73, 0xEF, 0xF0, 0x9B, 0x99, 0xFD, 0xD8, 0x44, 0xBE, + 0x4D, 0x49, 0x27, 0x33, 0x27, 0x8F, 0x7B, 0x87, 0x0D, 0xC2, 0xE0, 0xD8, 0x9F, 0xA2, 0x90, 0x5B, + 0x58, 0xC2, 0xEF, 0xDF, 0x5A, 0x86, 0x5E, 0xA7, 0x63, 0xD9, 0x1F, 0x9F, 0xE0, 0x81, 0x91, 0xB7, + 0x12, 0xDF, 0x35, 0x82, 0x19, 0x0F, 0x8F, 0x63, 0xDC, 0xED, 0x03, 0x9D, 0xDB, 0x16, 0xE9, 0x54, + 0x56, 0x6F, 0xDA, 0xCD, 0x9C, 0x8F, 0xBF, 0x71, 0xD4, 0xAE, 0xBE, 0x44, 0x7E, 0x15, 0xC1, 0x65, + 0xF6, 0x20, 0x57, 0xD7, 0x79, 0x3A, 0x87, 0x0C, 0x33, 0x1A, 0x0C, 0x70, 0xE6, 0x42, 0x21, 0x46, + 0x3F, 0x6F, 0x7E, 0x95, 0x14, 0xD7, 0x22, 0x2D, 0xD8, 0xD7, 0xDB, 0x8B, 0x3B, 0x6F, 0xEB, 0xCF, + 0x83, 0xA3, 0x87, 0x30, 0x69, 0xF4, 0x10, 0x92, 0xE2, 0x63, 0x11, 0x42, 0xE3, 0x93, 0x75, 0xDB, + 0xE9, 0xD3, 0x3D, 0x9A, 0xC4, 0x9E, 0x31, 0x0D, 0x6F, 0xBC, 0x4E, 0xE5, 0x8B, 0x7F, 0xA7, 0xF0, + 0xD9, 0xFA, 0x14, 0x5E, 0xFD, 0xAF, 0x87, 0xB8, 0x7F, 0xD4, 0xAD, 0x04, 0xFA, 0x7B, 0x73, 0x4B, + 0xDF, 0x38, 0x62, 0x22, 0x42, 0x9C, 0x13, 0x09, 0xAA, 0xCA, 0x89, 0xEC, 0x5C, 0x9E, 0x7A, 0x6B, + 0x19, 0xB9, 0x85, 0xF5, 0xB1, 0xB7, 0x39, 0xC0, 0xB3, 0x34, 0x91, 0x5F, 0xDE, 0x5E, 0x70, 0x35, + 0x43, 0x34, 0xE4, 0x46, 0x71, 0x14, 0x10, 0xAA, 0x69, 0x82, 0x03, 0x27, 0xCF, 0xD2, 0x3F, 0x3E, + 0x96, 0xEE, 0x31, 0x11, 0x2D, 0x5A, 0xE0, 0xDD, 0x74, 0x3A, 0x8C, 0x81, 0x7E, 0x78, 0xB8, 0xCB, + 0x0C, 0xE0, 0xB8, 0xAE, 0x91, 0x6C, 0xDE, 0x7B, 0x88, 0xFC, 0x92, 0x8B, 0xDC, 0x3F, 0xE2, 0x96, + 0xFA, 0x05, 0xBE, 0xB6, 0xD6, 0xC2, 0x5F, 0x96, 0x7E, 0x8D, 0x97, 0x87, 0x81, 0x37, 0x9F, 0xFE, + 0x0D, 0x3E, 0x9E, 0x86, 0x86, 0x88, 0x13, 0x67, 0xEE, 0xA7, 0x28, 0x94, 0x55, 0x56, 0xF1, 0xEC, + 0xDF, 0x3F, 0x61, 0x6B, 0x5A, 0x7D, 0x04, 0xA5, 0x15, 0xF9, 0x71, 0x81, 0xD5, 0x2E, 0xA6, 0x57, + 0x87, 0xD4, 0x2E, 0x3F, 0x8D, 0xAC, 0x04, 0x51, 0x09, 0x50, 0x50, 0x2A, 0x35, 0x9F, 0xA3, 0xA7, + 0x72, 0x5A, 0xB6, 0x9E, 0x40, 0x43, 0x05, 0x07, 0x21, 0x08, 0x31, 0xFA, 0xF3, 0xDB, 0x09, 0x23, + 0x38, 0x73, 0xA1, 0x88, 0xCA, 0x2A, 0x53, 0xFD, 0x5E, 0xA5, 0xFC, 0x52, 0x35, 0x39, 0xF9, 0xC5, + 0xFC, 0xE7, 0xD8, 0xDB, 0x08, 0x0B, 0x0E, 0x68, 0xB1, 0x56, 0x67, 0xAE, 0xAD, 0xE5, 0xAF, 0x4B, + 0x57, 0xB3, 0x7A, 0xF3, 0x1E, 0xC7, 0x33, 0xDF, 0x21, 0x4B, 0x2E, 0xB9, 0x1C, 0x1D, 0x55, 0xE5, + 0x78, 0x35, 0xF0, 0x1E, 0x36, 0xEB, 0xE8, 0xCF, 0x27, 0xB2, 0x99, 0x31, 0xF7, 0x23, 0x72, 0x72, + 0x0B, 0x5B, 0xBF, 0x61, 0x14, 0x82, 0x31, 0x43, 0xFA, 0xD1, 0x2D, 0x2A, 0x94, 0x3A, 0x87, 0x7C, + 0x91, 0x3A, 0xAB, 0x95, 0x40, 0x3F, 0x1F, 0xC6, 0xDE, 0x9A, 0xD4, 0x32, 0x5B, 0xAC, 0xA2, 0x60, + 0xAE, 0xB5, 0x30, 0xE7, 0xA3, 0xB5, 0x2C, 0xFC, 0x6A, 0x83, 0x74, 0x3F, 0x4B, 0x1C, 0x01, 0x5E, + 0xC1, 0x21, 0xDC, 0xD3, 0x95, 0xE8, 0xA8, 0x5A, 0x81, 0x1A, 0x90, 0x81, 0x0C, 0x13, 0xEA, 0x05, + 0x90, 0x95, 0x5B, 0xC8, 0xC9, 0xB3, 0x17, 0xB8, 0xBD, 0x7F, 0x82, 0x73, 0xE5, 0x36, 0x2E, 0x87, + 0x00, 0x7F, 0x1F, 0x4F, 0x06, 0x27, 0xF6, 0x20, 0xD4, 0xE8, 0x57, 0x2F, 0xB2, 0xF4, 0x3A, 0x1D, + 0x91, 0x21, 0x46, 0x6E, 0xE9, 0xDD, 0x1D, 0x37, 0x9D, 0x93, 0x8F, 0xA7, 0xAA, 0x54, 0x56, 0x9B, + 0xF9, 0xDB, 0xD2, 0xD5, 0xCC, 0xFD, 0xFC, 0xBB, 0xFA, 0xC0, 0x6C, 0x64, 0xE0, 0xDF, 0x13, 0xC8, + 0x60, 0xC2, 0x0E, 0x41, 0x47, 0x16, 0x6F, 0xAC, 0x46, 0x7E, 0x65, 0x73, 0x10, 0x32, 0x16, 0x96, + 0xCC, 0x73, 0xF9, 0x1C, 0x3A, 0x95, 0xC3, 0xA0, 0x84, 0x6E, 0x84, 0xB6, 0x54, 0xBC, 0x20, 0x23, + 0x41, 0x02, 0xFC, 0x7D, 0x1A, 0x6D, 0x10, 0xDD, 0xF4, 0x3A, 0xE2, 0x6E, 0x8A, 0x72, 0x9E, 0x19, + 0x3A, 0x95, 0xF3, 0xF9, 0xC5, 0xBC, 0xF0, 0xCF, 0xCF, 0x79, 0x77, 0xF5, 0x8F, 0xD4, 0x5A, 0xEA, + 0xA3, 0x3E, 0x8B, 0x90, 0x45, 0x62, 0xBE, 0xE9, 0x40, 0x1A, 0x75, 0x78, 0x35, 0xCD, 0x8B, 0x48, + 0xA6, 0x0C, 0xC4, 0x96, 0x42, 0x77, 0x26, 0xB7, 0x90, 0x9D, 0x3F, 0x1F, 0x27, 0x36, 0x3C, 0x84, + 0xD8, 0xE8, 0xF0, 0x6B, 0xEF, 0xBE, 0xAF, 0x86, 0xAB, 0xF1, 0xD0, 0x49, 0x93, 0x88, 0x26, 0x20, + 0x25, 0xED, 0x08, 0x4F, 0xCE, 0x59, 0xCA, 0xB7, 0xDB, 0xD3, 0xB0, 0x36, 0x6C, 0x16, 0x0B, 0x90, + 0xCC, 0x58, 0xD1, 0xC1, 0xF4, 0xE9, 0x94, 0xF2, 0xA6, 0x85, 0xC8, 0x4F, 0x6B, 0xF7, 0xC5, 0x16, + 0x72, 0x5A, 0x50, 0x5A, 0xCE, 0x86, 0x9F, 0x7E, 0xA6, 0xA6, 0xA6, 0x96, 0x5E, 0x37, 0x45, 0xC9, + 0x04, 0x1A, 0x57, 0xC1, 0x66, 0xA4, 0xCC, 0x2D, 0x28, 0xE1, 0xEF, 0x9F, 0x7F, 0xC7, 0xEC, 0x05, + 0x5F, 0x34, 0xCA, 0xD2, 0x45, 0x2A, 0x21, 0x4F, 0x22, 0xF3, 0x35, 0x3A, 0x3C, 0x20, 0xA0, 0xB3, + 0xEA, 0xCD, 0x16, 0x21, 0x2D, 0xC2, 0x5D, 0x90, 0x5F, 0x8D, 0x56, 0x4D, 0xE6, 0x5A, 0x76, 0x64, + 0x1C, 0x27, 0xF5, 0xE7, 0xE3, 0xF8, 0x79, 0x79, 0x10, 0x13, 0x1E, 0x8C, 0xA1, 0xB9, 0x64, 0xD1, + 0x96, 0x40, 0x95, 0x96, 0xE2, 0xC2, 0xD2, 0x32, 0xBE, 0xF8, 0xF7, 0x0E, 0x9E, 0x7D, 0xE7, 0x13, + 0x56, 0x6D, 0xFC, 0xC9, 0x1E, 0xCD, 0x0E, 0x92, 0xF8, 0xDB, 0x91, 0xC5, 0x13, 0x5A, 0x57, 0xFE, + 0xA7, 0x1D, 0xD0, 0xD9, 0x5E, 0x8A, 0x40, 0xA4, 0x68, 0xF8, 0x3D, 0x0E, 0xDF, 0x3E, 0xF7, 0x34, + 0xB8, 0x33, 0x6C, 0x40, 0x2F, 0xA6, 0x8C, 0x1B, 0xCE, 0xE8, 0xC1, 0x7D, 0x09, 0x0F, 0x09, 0x40, + 0x51, 0x75, 0x36, 0x95, 0xD7, 0xC9, 0x1C, 0x11, 0x45, 0xB1, 0x79, 0x2A, 0x15, 0x6A, 0x6B, 0x6A, + 0x38, 0x95, 0x93, 0xCF, 0xBA, 0x9D, 0xE9, 0x7C, 0xB5, 0xF1, 0x27, 0x0E, 0x9C, 0x3C, 0x7B, 0x79, + 0x48, 0x4F, 0x39, 0xF0, 0x21, 0xF2, 0x23, 0x98, 0x2E, 0x71, 0xCD, 0x3A, 0x8B, 0xCE, 0x66, 0x08, + 0x48, 0x17, 0xC0, 0x9D, 0xC0, 0x8B, 0xC8, 0x62, 0xC4, 0xF5, 0xB3, 0xD6, 0x4D, 0xAF, 0x23, 0xBE, + 0x6B, 0x24, 0x23, 0x6F, 0xEE, 0xC3, 0xA8, 0x5B, 0x12, 0xE9, 0xD3, 0x3D, 0x86, 0x88, 0xE0, 0x40, + 0xBC, 0x3C, 0xDC, 0x1B, 0xAA, 0xCB, 0x35, 0x82, 0x00, 0x4D, 0x50, 0x6B, 0xB1, 0x50, 0x56, 0x51, + 0xC5, 0x99, 0x0B, 0x85, 0xEC, 0x3B, 0x7A, 0x9A, 0x2D, 0xFB, 0x0E, 0xB3, 0xFB, 0x50, 0x26, 0xF9, + 0x25, 0x65, 0x97, 0xE7, 0xB3, 0xD4, 0x21, 0x3F, 0xA5, 0x3A, 0x17, 0xF9, 0x01, 0xCC, 0x4E, 0x0F, + 0x9D, 0xBD, 0x1E, 0x18, 0x62, 0x47, 0x28, 0xB2, 0xB4, 0xC7, 0x34, 0xA4, 0x7A, 0xDC, 0x68, 0x6C, + 0xEE, 0x6E, 0x7A, 0x42, 0x8D, 0xFE, 0x74, 0x8B, 0x0C, 0x25, 0x36, 0x2A, 0x8C, 0x2E, 0xA1, 0x46, + 0x82, 0xFC, 0x7D, 0xF0, 0xF2, 0x34, 0xA0, 0x2A, 0x2A, 0xE6, 0x5A, 0x0B, 0x15, 0x97, 0xAA, 0xB9, + 0x50, 0x7C, 0x91, 0x9C, 0xFC, 0x62, 0xCE, 0xE4, 0x16, 0x72, 0xBE, 0xB0, 0x84, 0x8A, 0xAA, 0xAB, + 0x26, 0x15, 0xD5, 0x21, 0x93, 0x2C, 0x97, 0x02, 0x5F, 0x21, 0x8D, 0x86, 0xFF, 0x8F, 0xAB, 0x40, + 0x41, 0xA6, 0x44, 0xBC, 0x88, 0xDC, 0xB7, 0xD4, 0xD0, 0x82, 0xEF, 0xA2, 0x3B, 0xF1, 0x2B, 0x03, + 0x7E, 0x40, 0x32, 0x3D, 0xB4, 0xB3, 0x1F, 0xB6, 0x29, 0x02, 0x5C, 0xAF, 0x08, 0x45, 0xD6, 0x06, + 0xBE, 0x0B, 0xF8, 0x15, 0x72, 0xEF, 0xE2, 0x6C, 0x32, 0x91, 0x1D, 0x16, 0xA4, 0x23, 0xE9, 0x38, + 0x32, 0xA1, 0x68, 0x13, 0x72, 0x66, 0x54, 0x75, 0xF6, 0xC3, 0x35, 0x85, 0xEB, 0x99, 0x21, 0x76, + 0xE8, 0x90, 0x16, 0xE3, 0x3E, 0x48, 0xAB, 0x71, 0x5F, 0xA0, 0x07, 0x92, 0x61, 0x01, 0x34, 0xE4, + 0xF5, 0xD5, 0x22, 0x09, 0x5D, 0x8C, 0xF4, 0xEA, 0x1D, 0x45, 0xA6, 0x1C, 0x67, 0x20, 0x23, 0x44, + 0x2A, 0x5B, 0x76, 0xDB, 0xCE, 0xC1, 0xFF, 0x01, 0xCE, 0x34, 0xF5, 0xEC, 0x2D, 0xA9, 0x9C, 0xA8, + 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3A, 0x63, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x00, 0x32, 0x30, 0x31, 0x32, 0x2D, 0x30, 0x31, 0x2D, 0x33, 0x31, 0x54, 0x31, + 0x33, 0x3A, 0x34, 0x31, 0x3A, 0x31, 0x38, 0x2D, 0x30, 0x38, 0x3A, 0x30, 0x30, 0xED, 0x4F, 0xCC, + 0x0D, 0x00, 0x00, 0x00, 0x25, 0x74, 0x45, 0x58, 0x74, 0x64, 0x61, 0x74, 0x65, 0x3A, 0x6D, 0x6F, + 0x64, 0x69, 0x66, 0x79, 0x00, 0x32, 0x30, 0x31, 0x32, 0x2D, 0x30, 0x31, 0x2D, 0x33, 0x31, 0x54, + 0x31, 0x33, 0x3A, 0x34, 0x31, 0x3A, 0x31, 0x38, 0x2D, 0x30, 0x38, 0x3A, 0x30, 0x30, 0x9C, 0x12, + 0x74, 0xB1, 0x00, 0x00, 0x00, 0x19, 0x74, 0x45, 0x58, 0x74, 0x53, 0x6F, 0x66, 0x74, 0x77, 0x61, + 0x72, 0x65, 0x00, 0x77, 0x77, 0x77, 0x2E, 0x69, 0x6E, 0x6B, 0x73, 0x63, 0x61, 0x70, 0x65, 0x2E, + 0x6F, 0x72, 0x67, 0x9B, 0xEE, 0x3C, 0x1A, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82}; \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_RFC822_Attachment/Send_RFC822_Attachment.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_RFC822_Attachment/Send_RFC822_Attachment.ino index 49a98ed09..e467dbfd1 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_RFC822_Attachment/Send_RFC822_Attachment.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_RFC822_Attachment/Send_RFC822_Attachment.ino @@ -1,360 +1,360 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to send Email message with attachment - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -/* This is for attachment data */ -#include "image.h" - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - message.subject = F("Test sending Email with rfc822 attachment"); - message.addRecipient(F("Someone"), RECIPIENT_EMAIL); - - message.text.content = F("This is simple plain text message with rfc822 attachment"); - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.text.charSet = F("us-ascii"); - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - /* Set the custom message header */ - message.addHeader(F("Message-ID: ")); - - SMTP_Message rfc822; - rfc822.messageID = F("1234@local.machine.example"); - rfc822.from.name = F("rob"); - rfc822.from.email = F("rob@example.com"); - rfc822.sender.name = F("steve"); - rfc822.sender.email = F("steve@example.com"); - - // This date field will set by default if the device time was already set or set date field manually - rfc822.date = MailClient.Time.getDateTimeString(); - - rfc822.subject = F("Test rfc822 message"); - rfc822.comments = F("This is comment"); - rfc822.addRecipient(F("joe"), F("joe@example.com")); - rfc822.response.reply_to = F("rob@example.com"); - rfc822.text.charSet = F("utf-8"); - rfc822.text.content = F("This is rfc822 text message"); - rfc822.text.transfer_encoding = Content_Transfer_Encoding::enc_qp; - - rfc822.html.charSet = F("utf-8"); - rfc822.html.content = F("This is rfc822 html message"); - rfc822.html.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* The attachment data item */ - SMTP_Attachment att[2]; - int attIndex = 0; - - /** Set the attachment info e.g. - * file name, MIME type, BLOB data, BLOB data size, - * and transfer encoding - */ - att[attIndex].descr.filename = F("firebase_logo.png"); - att[attIndex].descr.mime = F("image/png"); - att[attIndex].blob.data = firebase_png; - att[attIndex].blob.size = sizeof(firebase_png); - att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; - - /* Add the attachment to the rfc822 message */ -#if defined(ESP32) || defined(ESP8266) - rfc822.addAttachment(att[attIndex]); // Required more stack and may fail on SAMD -#endif - /* Prepare other attachment data */ - uint8_t *a = new uint8_t[512]; - int j = 0; - - for (int i = 0; i < 512; i++) - { - a[i] = j; - j++; - if (j > 255) - j = 0; - } - - /** Set the attachment info e.g. - * file name, MIME type, BLOB data, BLOB data size. - * The default transfer encoding is base64. - */ - attIndex++; - att[attIndex].descr.filename = F("test.dat"); - att[attIndex].descr.mime = F("application/octet-stream"); - att[attIndex].blob.data = a; - att[attIndex].blob.size = 512; - - /* Add this attachment to the message */ - message.addAttachment(att[attIndex]); - - /* Add rfc822 message in the message */ - message.addMessage(rfc822); - - /* Connect to the server */ - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (!smtp.isLoggedIn()) - { - Serial.println("\nNot yet logged in."); - } - else - { - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - } - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } -} + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send Email message with attachment + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +/* This is for attachment data */ +#include "image.h" + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending Email with rfc822 attachment"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + message.text.content = F("This is simple plain text message with rfc822 attachment"); + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + SMTP_Message rfc822; + rfc822.messageID = F("1234@local.machine.example"); + rfc822.from.name = F("rob"); + rfc822.from.email = F("rob@example.com"); + rfc822.sender.name = F("steve"); + rfc822.sender.email = F("steve@example.com"); + + // This date field will set by default if the device time was already set or set date field manually + rfc822.date = MailClient.Time.getDateTimeString(); + + rfc822.subject = F("Test rfc822 message"); + rfc822.comments = F("This is comment"); + rfc822.addRecipient(F("joe"), F("joe@example.com")); + rfc822.response.reply_to = F("rob@example.com"); + rfc822.text.charSet = F("utf-8"); + rfc822.text.content = F("This is rfc822 text message"); + rfc822.text.transfer_encoding = Content_Transfer_Encoding::enc_qp; + + rfc822.html.charSet = F("utf-8"); + rfc822.html.content = F("This is rfc822 html message"); + rfc822.html.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* The attachment data item */ + SMTP_Attachment att[2]; + int attIndex = 0; + + /** Set the attachment info e.g. + * file name, MIME type, BLOB data, BLOB data size, + * and transfer encoding + */ + att[attIndex].descr.filename = F("firebase_logo.png"); + att[attIndex].descr.mime = F("image/png"); + att[attIndex].blob.data = firebase_png; + att[attIndex].blob.size = sizeof(firebase_png); + att[attIndex].descr.transfer_encoding = Content_Transfer_Encoding::enc_base64; + + /* Add the attachment to the rfc822 message */ +#if defined(ESP32) || defined(ESP8266) + rfc822.addAttachment(att[attIndex]); // Required more stack and may fail on SAMD +#endif + /* Prepare other attachment data */ + uint8_t *a = new uint8_t[512]; + int j = 0; + + for (int i = 0; i < 512; i++) + { + a[i] = j; + j++; + if (j > 255) + j = 0; + } + + /** Set the attachment info e.g. + * file name, MIME type, BLOB data, BLOB data size. + * The default transfer encoding is base64. + */ + attIndex++; + att[attIndex].descr.filename = F("test.dat"); + att[attIndex].descr.mime = F("application/octet-stream"); + att[attIndex].blob.data = a; + att[attIndex].blob.size = 512; + + /* Add this attachment to the message */ + message.addAttachment(att[attIndex]); + + /* Add rfc822 message in the message */ + message.addMessage(rfc822); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (!smtp.isLoggedIn()) + { + Serial.println("\nNot yet logged in."); + } + else + { + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_RFC822_Attachment/image.h b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_RFC822_Attachment/image.h index 5ddd6829b..80ce0a0e7 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_RFC822_Attachment/image.h +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_RFC822_Attachment/image.h @@ -1,1851 +1,1851 @@ -#include - -static const uint8_t firebase_png[] PROGMEM = { - 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, - 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x02, 0x58, 0x08, 0x06, 0x00, 0x00, 0x00, 0x9A, 0x76, 0x82, - 0x70, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00, - 0x00, 0x04, 0x67, 0x41, 0x4D, 0x41, 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, 0x61, 0x05, 0x00, 0x00, - 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x00, 0x0E, 0xC3, 0x01, 0xC7, - 0x6F, 0xA8, 0x64, 0x00, 0x00, 0x55, 0x14, 0x49, 0x44, 0x41, 0x54, 0x78, 0x5E, 0xED, 0xDD, 0x59, - 0x90, 0x1D, 0xF5, 0x81, 0xE7, 0x7B, 0x3F, 0xF4, 0xC3, 0x84, 0x91, 0x40, 0x6E, 0xEF, 0xC6, 0x8B, - 0x30, 0x92, 0x4A, 0x1B, 0x58, 0x98, 0xCD, 0xA0, 0xA5, 0x4A, 0x12, 0x20, 0x6C, 0x9A, 0xB6, 0xBA, - 0x01, 0x63, 0x4F, 0x3F, 0x8C, 0x1E, 0x26, 0xC2, 0xF7, 0xE5, 0xC6, 0x25, 0xE2, 0xDE, 0x97, 0x3B, - 0x7D, 0x67, 0xAC, 0x6E, 0x63, 0x63, 0x83, 0x8D, 0xBC, 0xB1, 0x99, 0xA5, 0x10, 0x08, 0xED, 0x52, - 0x69, 0xAD, 0x92, 0xA0, 0xBB, 0xAB, 0xA7, 0xED, 0x6E, 0x77, 0xB7, 0x81, 0x42, 0x9B, 0x99, 0x89, - 0x89, 0xDB, 0x9A, 0xB9, 0x0E, 0x2F, 0x2C, 0x76, 0x61, 0x16, 0x49, 0x85, 0xA4, 0xFC, 0xDF, 0xFF, - 0x3F, 0x4F, 0xE6, 0xA9, 0x3C, 0x79, 0x7E, 0xE7, 0x9C, 0xCC, 0x3C, 0x99, 0x75, 0xCE, 0xC9, 0xFA, - 0x7E, 0x22, 0x7E, 0xA1, 0x6E, 0x2F, 0x42, 0xC2, 0x94, 0xE2, 0xFF, 0x8D, 0x7F, 0x65, 0x9E, 0xF7, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x28, 0x82, 0x79, 0x6E, 0xCD, 0x80, 0xBF, 0xC3, 0x5F, 0x58, 0x12, 0xFC, - 0x4B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x1F, 0x73, 0x78, 0xCD, 0x3A, 0xEF, 0xB9, 0x35, 0x63, 0xE6, - 0xB9, 0x9B, 0x4D, 0x75, 0xCF, 0xAE, 0xF1, 0xE7, 0x3D, 0x7B, 0xD3, 0xA0, 0x0B, 0x92, 0xE0, 0x3F, - 0x0A, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x98, 0x91, 0x35, 0xB3, 0xEB, 0xC2, 0x23, 0x12, 0x1F, 0xD1, - 0x79, 0x87, 0xD7, 0x6C, 0x08, 0xFE, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x8E, 0xFB, 0x16, 0x2B, - 0xEF, 0xD9, 0x35, 0xE3, 0x95, 0xE0, 0xB8, 0xD1, 0x98, 0x03, 0x57, 0x19, 0xB3, 0x7B, 0xAE, 0x31, - 0x3B, 0x3E, 0x65, 0xCC, 0xB6, 0x8F, 0x1A, 0xB3, 0xF3, 0xD3, 0xC6, 0x0C, 0x2D, 0x34, 0x66, 0x78, - 0xD9, 0x64, 0x84, 0x3C, 0x7B, 0xD3, 0x60, 0xF0, 0x5F, 0x07, 0x00, 0x00, 0x00, 0x80, 0xE4, 0xAA, - 0x37, 0x1F, 0x2E, 0x3C, 0x76, 0x7C, 0xC2, 0x98, 0xED, 0x1F, 0xAB, 0x84, 0x87, 0xDA, 0x2E, 0x1B, - 0x26, 0x87, 0x6F, 0xA8, 0x84, 0xC8, 0xA1, 0x9B, 0xD6, 0x06, 0x3F, 0x05, 0x00, 0x00, 0x00, 0x00, - 0xB4, 0xE6, 0x9E, 0xF9, 0xF0, 0xE3, 0x63, 0xCF, 0xA2, 0x4A, 0x78, 0x34, 0x8B, 0x8F, 0x70, 0xDB, - 0x3F, 0x6E, 0xCC, 0xC8, 0x0A, 0xF7, 0xAD, 0x58, 0xE3, 0x66, 0xB4, 0x7F, 0x56, 0xF0, 0x53, 0x01, - 0x00, 0x00, 0x00, 0x40, 0x73, 0xDE, 0x73, 0x37, 0x9F, 0x34, 0xFB, 0xAF, 0x48, 0x1E, 0x1F, 0xE1, - 0x76, 0x5E, 0x62, 0xCC, 0xE1, 0xD5, 0x76, 0x37, 0xAE, 0x0F, 0x7E, 0x2A, 0x00, 0x00, 0x00, 0x00, - 0x68, 0xCC, 0x3D, 0x78, 0x6E, 0x0E, 0xAF, 0x4A, 0x1F, 0x1F, 0xFE, 0x3E, 0x62, 0xCC, 0xBE, 0xCF, - 0x18, 0xEF, 0xF0, 0x4D, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x68, 0xCD, 0xFF, 0x8C, 0x8F, 0xBD, - 0x97, 0x67, 0x8B, 0x0F, 0xB7, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x20, 0x19, 0x1B, - 0x20, 0xEB, 0xCD, 0xAE, 0x4F, 0xC7, 0xE2, 0xA2, 0xD5, 0x82, 0xF8, 0x08, 0xB7, 0x67, 0xB1, 0x31, - 0xCF, 0xDE, 0x64, 0xDC, 0x6D, 0x4A, 0xF0, 0xD3, 0x02, 0x00, 0x00, 0x00, 0x40, 0x3D, 0xEF, 0xB9, - 0x9B, 0x07, 0x75, 0x64, 0x34, 0x5A, 0x2C, 0x3E, 0xC2, 0x1D, 0x1A, 0xE0, 0xB5, 0xBC, 0x00, 0x00, - 0x00, 0x00, 0x9A, 0xF3, 0x0E, 0x2E, 0x1B, 0xD5, 0xA1, 0xA1, 0x26, 0xC2, 0x23, 0xDC, 0xD0, 0x02, - 0x6E, 0x41, 0x00, 0x00, 0x00, 0x00, 0x34, 0xE7, 0x1D, 0xB8, 0x76, 0x5C, 0xC7, 0x46, 0x7C, 0x22, - 0x3A, 0xE2, 0x1B, 0x59, 0x6E, 0xBC, 0xC3, 0x37, 0x8E, 0x06, 0x3F, 0x35, 0x00, 0x00, 0x00, 0x00, - 0x4C, 0x72, 0x6F, 0xAE, 0x32, 0xFB, 0x96, 0xD8, 0x78, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x0D, 0xB5, - 0x5D, 0x73, 0x2A, 0xB7, 0x20, 0xCF, 0xAD, 0x19, 0x08, 0xFE, 0x12, 0x00, 0x00, 0x00, 0x00, 0x50, - 0xE1, 0xBF, 0x01, 0x6B, 0x77, 0x9F, 0x8D, 0x07, 0x15, 0x1D, 0xE1, 0x44, 0x68, 0x34, 0xDB, 0xF0, - 0xF5, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xE7, 0x7F, 0x02, 0xFA, 0xAE, 0xB9, 0x36, 0x1C, - 0x54, 0x78, 0xB8, 0x89, 0xC0, 0x68, 0xB5, 0x5D, 0x97, 0x1A, 0xF3, 0xEC, 0x8D, 0xC6, 0x3C, 0xB7, - 0x9A, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x93, 0x6C, 0x80, 0xAC, 0xD7, 0xE1, 0xE1, 0x26, 0xE2, - 0xA2, 0xE5, 0x3E, 0x5C, 0xD9, 0x81, 0xAB, 0x8C, 0xF7, 0xEC, 0x0D, 0x27, 0x83, 0xBF, 0x0C, 0x00, - 0x00, 0x00, 0x00, 0xBC, 0xE7, 0x3D, 0xDE, 0xF0, 0x8A, 0x06, 0x6F, 0xC0, 0x52, 0x71, 0xD1, 0x6A, - 0x41, 0x7C, 0xB8, 0xED, 0xF8, 0x44, 0xE5, 0x16, 0xE4, 0xF0, 0x8D, 0xEB, 0x82, 0xBF, 0x14, 0x00, - 0x00, 0x00, 0x80, 0xE9, 0xCE, 0x3B, 0x70, 0xFD, 0xC9, 0xDC, 0xE3, 0x23, 0x1C, 0xB7, 0x20, 0x00, - 0x00, 0x00, 0x00, 0xA2, 0xCC, 0xFE, 0x2B, 0x6D, 0x2C, 0x14, 0x10, 0x1F, 0x6E, 0xEE, 0x16, 0xE4, - 0xF0, 0x2A, 0x77, 0x0B, 0xB2, 0x3E, 0xF8, 0xCB, 0x01, 0x00, 0x00, 0x00, 0x98, 0xAE, 0x6C, 0x18, - 0x2C, 0x31, 0x7B, 0x2E, 0xB3, 0xB1, 0x50, 0x40, 0x7C, 0x84, 0xDB, 0x77, 0xB9, 0x7B, 0x23, 0xD6, - 0xB8, 0x7B, 0xDD, 0x6F, 0xF0, 0x97, 0x05, 0x00, 0x00, 0x00, 0x30, 0x1D, 0x99, 0x43, 0x37, 0xAD, - 0x9D, 0x7C, 0x03, 0x96, 0x8A, 0x8B, 0x56, 0x13, 0xC1, 0x11, 0xDF, 0xF6, 0x8F, 0x71, 0x0B, 0x02, - 0x00, 0x00, 0x00, 0x20, 0x78, 0x03, 0xD6, 0xF6, 0x8F, 0xDB, 0x50, 0x50, 0x71, 0xD1, 0x6A, 0x22, - 0x36, 0x1A, 0x8D, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xB3, 0x37, 0x0D, 0xEA, 0xB8, 0x68, - 0x35, 0x11, 0x19, 0xAD, 0x76, 0xA8, 0xDF, 0x3D, 0x90, 0x3E, 0x18, 0xFC, 0xA5, 0x01, 0x00, 0x00, - 0x00, 0x4C, 0x37, 0xDE, 0x81, 0x6B, 0x46, 0x75, 0x60, 0x34, 0x9B, 0x88, 0x8B, 0x56, 0xDB, 0xFA, - 0x21, 0x63, 0x86, 0xE6, 0x57, 0x5E, 0xCB, 0x3B, 0xB2, 0x66, 0x76, 0xF0, 0x97, 0x07, 0x00, 0x00, - 0x00, 0x30, 0x9D, 0x98, 0x03, 0x57, 0xDB, 0x40, 0x50, 0x91, 0xD1, 0x68, 0x22, 0x2E, 0x5A, 0xCD, - 0xC5, 0x47, 0x38, 0x6E, 0x41, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC9, 0xDD, 0x44, 0x98, 0x7D, 0x9F, - 0xB1, 0x91, 0xA0, 0x42, 0x43, 0x4D, 0xC4, 0x45, 0xAB, 0x45, 0xE3, 0xC3, 0x6D, 0xF7, 0xDC, 0xCA, - 0x2D, 0xC8, 0x73, 0xAB, 0x07, 0x82, 0x5F, 0x06, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC0, 0x3C, 0xB7, - 0x66, 0xC0, 0xEC, 0x9E, 0x67, 0x43, 0x41, 0xC5, 0x46, 0x7C, 0x22, 0x2E, 0x5A, 0x2D, 0x1E, 0x1F, - 0xE1, 0x86, 0xAF, 0x73, 0x0F, 0xA4, 0x8F, 0x06, 0xBF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x81, - 0xF7, 0xEC, 0x4D, 0x77, 0x99, 0x9D, 0x97, 0xD8, 0x58, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x8B, 0x56, - 0x53, 0xE1, 0x11, 0x6E, 0xD7, 0xA7, 0xB9, 0x05, 0x01, 0x00, 0x00, 0x00, 0xA6, 0x1B, 0xEF, 0xF0, - 0x8D, 0x1B, 0x74, 0x70, 0x44, 0x27, 0xE2, 0xA2, 0xD5, 0x54, 0x74, 0xC4, 0xC7, 0x2D, 0x08, 0x00, - 0x00, 0x00, 0x30, 0xBD, 0x78, 0x07, 0xAF, 0x6F, 0xF1, 0x06, 0x2C, 0x11, 0x17, 0xAD, 0xA6, 0x62, - 0x43, 0xCD, 0x7D, 0xF6, 0x88, 0xBB, 0x05, 0x39, 0x7C, 0xE3, 0xBA, 0xE0, 0x97, 0x03, 0x00, 0x00, - 0x00, 0xA0, 0xCC, 0xBC, 0x03, 0xD7, 0x9D, 0xD4, 0xE1, 0xE1, 0x26, 0xE2, 0xA2, 0xD5, 0x54, 0x68, - 0x34, 0xDB, 0xFE, 0x2B, 0xDD, 0x1B, 0xB1, 0x4E, 0x06, 0xBF, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x65, - 0xD6, 0xF8, 0x0D, 0x58, 0x22, 0x2E, 0x5A, 0x4D, 0x05, 0x46, 0xAB, 0xB9, 0x5B, 0x90, 0xC3, 0x37, - 0x70, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x94, 0x9D, 0xFF, 0x06, 0xAC, 0xA1, 0x05, 0x36, 0x1E, 0x3A, - 0x14, 0x1F, 0xFE, 0x3E, 0x68, 0x5C, 0x04, 0x79, 0x87, 0x6E, 0x18, 0x37, 0xA3, 0xFD, 0xB3, 0x82, - 0x5F, 0x1A, 0x00, 0x00, 0x00, 0x80, 0xB2, 0x71, 0xB7, 0x0E, 0x66, 0xD7, 0x1C, 0x1B, 0x10, 0x1D, - 0x8C, 0x0F, 0x37, 0xF7, 0xD7, 0x3D, 0xB4, 0xD2, 0x98, 0xC3, 0xAB, 0xD7, 0x07, 0xBF, 0x34, 0x00, - 0x00, 0x00, 0x00, 0x65, 0x63, 0x03, 0x64, 0xBD, 0xD9, 0x7E, 0x71, 0x25, 0x00, 0x3A, 0x15, 0x1F, - 0xE1, 0xF6, 0x5E, 0xC6, 0x2D, 0x08, 0x00, 0x00, 0x00, 0x50, 0x66, 0xDE, 0xC8, 0xCA, 0xA1, 0xAE, - 0x88, 0x0F, 0xB7, 0xE0, 0x16, 0xC4, 0x3B, 0xBC, 0x7A, 0x43, 0xF0, 0xCB, 0x03, 0x00, 0x00, 0x00, - 0x50, 0x26, 0xDE, 0xC1, 0x6B, 0xC7, 0xBA, 0x22, 0x3E, 0xC2, 0xED, 0xEE, 0xAB, 0x3C, 0x90, 0x3E, - 0xB2, 0x66, 0x76, 0xF0, 0x4B, 0x04, 0x00, 0x00, 0x00, 0x50, 0x16, 0x66, 0xFF, 0x67, 0x75, 0x5C, - 0xB4, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0xD1, 0x11, 0xDF, 0xC8, 0x0A, 0xE3, 0x1D, 0x5A, 0x3D, 0x18, - 0xFC, 0x12, 0x01, 0x00, 0x00, 0x00, 0x94, 0x81, 0xBB, 0x65, 0x30, 0xFB, 0x2E, 0xD7, 0x81, 0xD1, - 0x6C, 0x32, 0x2C, 0x92, 0x4C, 0xC4, 0x86, 0x1A, 0xB7, 0x20, 0x00, 0x00, 0x00, 0x40, 0xF9, 0x98, - 0xE7, 0x56, 0x0F, 0x98, 0x5D, 0x97, 0xEA, 0xC8, 0x68, 0x34, 0x19, 0x16, 0x49, 0x26, 0x42, 0xA3, - 0xD9, 0x0E, 0x7E, 0xCE, 0x78, 0x87, 0x6F, 0x18, 0x0D, 0x7E, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x7A, - 0x9D, 0xFF, 0x06, 0xAC, 0x1D, 0x9F, 0xD0, 0xA1, 0xA1, 0x26, 0xC3, 0x22, 0xC9, 0x44, 0x60, 0xB4, - 0xDA, 0xCE, 0x4B, 0x82, 0x5B, 0x90, 0xD5, 0x03, 0xC1, 0x2F, 0x17, 0x00, 0x00, 0x00, 0x40, 0x2F, - 0xF3, 0x9E, 0xBD, 0x61, 0x50, 0x86, 0x86, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0x71, 0x91, 0x74, 0x07, - 0xAF, 0x35, 0xDE, 0xE1, 0x55, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x65, 0xE0, 0x1D, 0xBC, 0x6E, - 0x54, 0xC6, 0x46, 0x7C, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, 0x6D, 0xF9, 0x80, 0x31, 0x3B, - 0x67, 0xBB, 0x0F, 0x26, 0x34, 0xE6, 0xD0, 0xAA, 0xB5, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, 0x40, - 0xAF, 0xF2, 0x0E, 0x5C, 0x33, 0x2E, 0x83, 0x23, 0x3A, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, - 0x5C, 0x7C, 0x84, 0xDB, 0x77, 0x85, 0xFB, 0x5C, 0x90, 0x93, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, - 0x40, 0x2F, 0x72, 0x9F, 0x36, 0xDE, 0xF2, 0x0D, 0x58, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, - 0x45, 0xE3, 0xC3, 0x6D, 0xDB, 0xC7, 0x2A, 0xB7, 0x20, 0x87, 0x57, 0xAD, 0x0B, 0x7E, 0xE9, 0x00, - 0x00, 0x00, 0x00, 0x7A, 0x8D, 0xFF, 0x06, 0xAC, 0xDD, 0x73, 0xEB, 0xA3, 0x23, 0x9C, 0x0C, 0x8B, - 0x24, 0x13, 0x51, 0x91, 0x74, 0xF1, 0xF8, 0x08, 0xC7, 0x2D, 0x08, 0x00, 0x00, 0x00, 0xD0, 0xDB, - 0xCC, 0xE1, 0x1B, 0xD7, 0x35, 0x7C, 0x05, 0xAF, 0x0C, 0x8B, 0x24, 0x13, 0x51, 0x91, 0x74, 0x2A, - 0x3C, 0xC2, 0x6D, 0xB5, 0xBF, 0xA6, 0x43, 0x03, 0xEE, 0x26, 0x64, 0x7D, 0xF0, 0xCB, 0x07, 0x00, - 0x00, 0x00, 0xD0, 0x4B, 0xFC, 0x57, 0xF0, 0xF6, 0x42, 0x7C, 0x84, 0xDB, 0xB3, 0xD8, 0x7D, 0x3A, - 0xFA, 0xB8, 0xFB, 0xD6, 0xB1, 0xE0, 0xB7, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x57, 0x78, 0xC3, 0xCB, - 0xEB, 0xDF, 0x80, 0x25, 0xC3, 0x22, 0xC9, 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x0D, 0x35, 0x6E, 0x41, - 0x00, 0x00, 0x00, 0x80, 0xDE, 0xE5, 0x1D, 0xBC, 0x76, 0xAC, 0x67, 0xE2, 0x23, 0xDC, 0x9E, 0x45, - 0xC6, 0x3B, 0xB4, 0x6A, 0xDC, 0x8C, 0xF4, 0xCF, 0x0E, 0x7E, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x7A, - 0x81, 0xD9, 0x7F, 0x45, 0x6F, 0xC5, 0x87, 0xBF, 0xF7, 0x1B, 0x33, 0xB2, 0xCC, 0x46, 0xC8, 0xCA, - 0xC1, 0xE0, 0xB7, 0x01, 0x00, 0x00, 0x00, 0xA0, 0xDB, 0x99, 0xC3, 0x37, 0x2E, 0x71, 0xB7, 0x09, - 0x3D, 0x17, 0x1F, 0x6E, 0xEE, 0xCD, 0x5D, 0x87, 0x57, 0xD9, 0x10, 0xE9, 0xCD, 0x5B, 0x10, 0xF7, - 0xEB, 0xB6, 0x1B, 0x08, 0xC6, 0x4D, 0x0E, 0x00, 0x00, 0x00, 0xCA, 0xCF, 0x1C, 0xBA, 0x69, 0xAD, - 0xFF, 0x06, 0x2C, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x5A, 0x10, 0x1F, - 0xE1, 0x7A, 0xEC, 0x16, 0xC4, 0xFF, 0xCC, 0x95, 0x91, 0xFE, 0xF5, 0xDE, 0xA1, 0x81, 0x93, 0xFE, - 0x73, 0x2C, 0x91, 0xF9, 0xFF, 0x9A, 0xFD, 0xF7, 0x78, 0xB8, 0x1E, 0x00, 0x00, 0x00, 0xA5, 0x55, - 0x79, 0x03, 0xD6, 0x47, 0x6D, 0x10, 0xA8, 0xB8, 0x68, 0x35, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, - 0xD5, 0x62, 0xF1, 0xE1, 0xB6, 0xF3, 0x53, 0xC1, 0x2D, 0xC8, 0xEA, 0x81, 0xE0, 0xB7, 0xD4, 0xB5, - 0xCC, 0xA1, 0xFE, 0xB5, 0xDE, 0xC8, 0xC0, 0x78, 0x3C, 0x3C, 0xE2, 0xAB, 0xFC, 0x67, 0xFA, 0xD7, - 0x06, 0xFF, 0x35, 0x00, 0x00, 0x00, 0xA0, 0x3C, 0xBC, 0x67, 0x6F, 0x18, 0xD4, 0x71, 0xD1, 0x6A, - 0x22, 0x2A, 0x92, 0x4E, 0xC6, 0x45, 0xAB, 0x89, 0xF8, 0x08, 0x77, 0xF0, 0x1A, 0xE3, 0x1D, 0x5E, - 0x39, 0x1A, 0xFC, 0x96, 0xBA, 0x92, 0x19, 0xE9, 0x5F, 0x57, 0x8D, 0x8C, 0x91, 0xE5, 0xFE, 0x43, - 0xF4, 0x66, 0xC7, 0xC7, 0x6B, 0xE7, 0xFE, 0x35, 0xF7, 0xEF, 0xF9, 0xFF, 0x99, 0x7E, 0x37, 0x3E, - 0xF1, 0x1D, 0x00, 0x00, 0x00, 0xE5, 0xE2, 0x1D, 0xB8, 0x7A, 0x54, 0x07, 0x46, 0xB3, 0x89, 0xA8, - 0x48, 0x3A, 0x19, 0x17, 0xAD, 0x26, 0xA2, 0x23, 0xBA, 0x2E, 0xBF, 0x05, 0xB1, 0x21, 0x31, 0xBB, - 0x7A, 0xF3, 0x31, 0x34, 0xBF, 0xF2, 0x6B, 0xDE, 0x3C, 0x4B, 0xCF, 0xFD, 0x7B, 0x43, 0x7D, 0x7E, - 0x80, 0x78, 0x23, 0x2B, 0x78, 0xCB, 0x17, 0x00, 0x00, 0x00, 0xCA, 0xC5, 0xEC, 0xBF, 0xD2, 0x86, - 0x81, 0x8A, 0x8C, 0x46, 0x13, 0x51, 0x91, 0x74, 0x32, 0x2E, 0x5A, 0x2D, 0x12, 0x1A, 0xCD, 0xE6, - 0x6E, 0x41, 0x0E, 0xAD, 0x1A, 0x0B, 0x7E, 0x5B, 0x5D, 0xC5, 0xC6, 0xC7, 0x90, 0x1F, 0x1F, 0xBB, - 0x3E, 0xAD, 0xA3, 0xA3, 0x66, 0x17, 0x55, 0xB6, 0xF3, 0x92, 0x4A, 0x84, 0x0C, 0xAF, 0xE8, 0xEA, - 0x9B, 0x1D, 0x00, 0x00, 0x00, 0x20, 0x31, 0xFF, 0x81, 0xE8, 0xBD, 0x97, 0xDB, 0x38, 0x50, 0xA1, - 0xA1, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x9A, 0x08, 0x8D, 0x46, 0x73, 0xCF, 0xB1, 0xB8, - 0x5B, 0x90, 0xC3, 0xAB, 0xBA, 0xEA, 0xDB, 0x96, 0x6C, 0x44, 0x0C, 0xF8, 0xF1, 0xE1, 0xDE, 0xD8, - 0x25, 0x83, 0x23, 0xBA, 0x20, 0x3E, 0x62, 0x11, 0xE2, 0x7E, 0x8E, 0xE0, 0xA7, 0x03, 0x00, 0x00, - 0x00, 0x7A, 0x97, 0x79, 0x6E, 0xF5, 0x80, 0x7F, 0x30, 0x96, 0xB1, 0x11, 0x9F, 0x88, 0x8A, 0xA4, - 0x93, 0x71, 0xD1, 0x6A, 0x22, 0x32, 0x5A, 0x6D, 0xDF, 0x12, 0xE3, 0x1D, 0x5E, 0x75, 0x32, 0xF8, - 0xED, 0x75, 0x05, 0xEF, 0xD0, 0xC0, 0xA8, 0x39, 0x70, 0x55, 0x10, 0x18, 0xCD, 0x16, 0x8B, 0x8F, - 0x70, 0xFB, 0xAF, 0xE4, 0x16, 0x04, 0x00, 0x00, 0x00, 0xE5, 0xE0, 0x3D, 0x7B, 0xC3, 0x5D, 0x66, - 0xC7, 0xA7, 0x6C, 0x24, 0xA8, 0xE0, 0x88, 0x4E, 0x44, 0x45, 0xD2, 0xC9, 0xB8, 0x68, 0x35, 0x11, - 0x17, 0x49, 0x16, 0xDC, 0x82, 0x78, 0x87, 0x56, 0xDD, 0x15, 0xFC, 0x16, 0x3B, 0xAA, 0x7A, 0xFB, - 0xE1, 0x1E, 0x30, 0x97, 0xD1, 0x11, 0x4E, 0x84, 0x47, 0xB8, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, - 0x00, 0x80, 0x72, 0xF0, 0x0E, 0xDF, 0xB8, 0x41, 0x07, 0x47, 0x74, 0x22, 0x2A, 0x92, 0x4E, 0xC6, - 0x45, 0xAB, 0x89, 0xB0, 0x48, 0xB3, 0x3D, 0x0B, 0x8D, 0x37, 0xB2, 0x72, 0xBC, 0x1B, 0x3E, 0x4B, - 0x23, 0xD9, 0xED, 0x87, 0x88, 0x8E, 0xF8, 0xB8, 0x05, 0x01, 0x00, 0x00, 0x40, 0x19, 0x78, 0x07, - 0xAF, 0x6B, 0xF1, 0x06, 0x2C, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, 0xD5, 0x44, 0x50, 0xA4, 0xDA, - 0x1F, 0x57, 0xFE, 0xDA, 0x23, 0x2B, 0xEC, 0x56, 0xAE, 0x0F, 0x7E, 0x9B, 0x1D, 0xE1, 0x3E, 0xC7, - 0xC3, 0xBF, 0xFD, 0x70, 0x7F, 0x1F, 0x65, 0x78, 0xB8, 0x89, 0xD8, 0x50, 0xF3, 0x7F, 0x4F, 0xFD, - 0xC6, 0x1C, 0xE4, 0xB3, 0x41, 0x00, 0x00, 0x00, 0xD0, 0xC3, 0xBC, 0x03, 0x9F, 0x3B, 0x59, 0x1F, - 0x1D, 0xE1, 0x22, 0x31, 0x91, 0x76, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xD9, 0xF8, 0x08, - 0xD7, 0x05, 0xB7, 0x20, 0xFE, 0xA7, 0x9A, 0xBB, 0x07, 0xFC, 0x65, 0x78, 0xB8, 0x89, 0xD0, 0x68, - 0xB6, 0xBD, 0x97, 0xB9, 0x5B, 0x90, 0xAE, 0x7A, 0xBE, 0x05, 0x00, 0x00, 0x00, 0x48, 0xA5, 0xF1, - 0x1B, 0xB0, 0x44, 0x54, 0x24, 0x9D, 0x8C, 0x8B, 0x56, 0x53, 0x41, 0x91, 0x66, 0x91, 0xF8, 0x70, - 0x73, 0xBF, 0x8E, 0xE1, 0xA5, 0xEE, 0x13, 0xC5, 0x37, 0x04, 0xBF, 0xD5, 0x29, 0x65, 0xC2, 0x0F, - 0x1D, 0x74, 0x7F, 0x2F, 0xF3, 0x88, 0x0F, 0x37, 0xF7, 0x7B, 0xF2, 0x9F, 0x05, 0x59, 0xCE, 0x87, - 0x13, 0x02, 0x00, 0x00, 0xA0, 0xF7, 0xF8, 0x6F, 0xC0, 0x72, 0x1F, 0x8A, 0x57, 0xB6, 0xF8, 0x08, - 0xB7, 0x6B, 0x8E, 0x31, 0x87, 0x56, 0xBA, 0x43, 0xFB, 0x94, 0x7F, 0x90, 0x5F, 0xF3, 0xDB, 0x0F, - 0x11, 0x17, 0x49, 0xB7, 0x67, 0xB1, 0xF1, 0x86, 0x97, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x80, 0xDE, - 0x63, 0x0E, 0xDD, 0xB4, 0xD6, 0xFF, 0x60, 0xBC, 0x32, 0xC6, 0x47, 0x38, 0x77, 0x0B, 0x72, 0x68, - 0xE5, 0x60, 0xF0, 0x5B, 0x9E, 0x12, 0xCD, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0xDD, 0x33, 0x17, 0xDA, - 0xDF, 0x93, 0xFD, 0x7B, 0x66, 0x7F, 0x4F, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0xE7, 0x98, 0xC3, - 0x37, 0xAE, 0xF7, 0x5F, 0x5B, 0x5B, 0xD6, 0xF8, 0x70, 0x0B, 0x6F, 0x41, 0x0E, 0xF7, 0x2F, 0x09, - 0x7E, 0xDB, 0x85, 0x72, 0xCF, 0x9C, 0xF8, 0xB7, 0x1F, 0xEE, 0x66, 0x29, 0xEF, 0xF8, 0x08, 0xB7, - 0x7B, 0x9E, 0xF1, 0x46, 0x96, 0x8F, 0x9B, 0xA1, 0xCE, 0xBF, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, - 0xCC, 0x1B, 0x59, 0x39, 0x54, 0xEA, 0xF8, 0x08, 0x77, 0xE0, 0x6A, 0x77, 0x0B, 0x32, 0x25, 0xAF, - 0xB0, 0x35, 0x23, 0xFD, 0xEB, 0xCD, 0xC8, 0x72, 0xFB, 0xD7, 0xB5, 0xBF, 0xC6, 0x22, 0xE2, 0xC3, - 0x6D, 0xF3, 0xFB, 0xC2, 0x5B, 0x90, 0x8E, 0xBE, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, 0xC5, 0xDB, - 0x7F, 0xED, 0x58, 0xE9, 0xE3, 0xC3, 0x6D, 0xC7, 0x27, 0xC3, 0x67, 0x41, 0x0A, 0xFD, 0x20, 0x3F, - 0xFF, 0xF6, 0x63, 0x64, 0x60, 0xBC, 0xFE, 0xF6, 0x43, 0x44, 0x45, 0xD2, 0xC5, 0xE3, 0x23, 0x1C, - 0xB7, 0x20, 0x00, 0x00, 0x00, 0xE8, 0x35, 0x66, 0xDF, 0x12, 0x1D, 0x15, 0x49, 0x27, 0xE3, 0xA2, - 0xD5, 0x54, 0x50, 0xA4, 0x99, 0x08, 0x8C, 0x56, 0x73, 0x37, 0x06, 0x53, 0x70, 0x0B, 0xA2, 0x6F, - 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8F, 0x70, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0x97, 0x98, - 0x91, 0x35, 0xB3, 0xDD, 0xE7, 0x4A, 0xC8, 0xB0, 0x48, 0x32, 0x19, 0x17, 0xAD, 0x16, 0x8F, 0x89, - 0xB4, 0x13, 0x71, 0xD1, 0x6A, 0xEE, 0xA0, 0xEE, 0xB6, 0xED, 0x63, 0x95, 0x5B, 0x90, 0x43, 0xC5, - 0x7C, 0x90, 0x9F, 0xBE, 0xFD, 0x10, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0xE2, 0xE3, 0x16, 0x04, 0x00, - 0x00, 0x00, 0xBD, 0xC2, 0x8C, 0xAC, 0x1E, 0x30, 0x3B, 0x2F, 0xD1, 0x71, 0xD1, 0x6A, 0x32, 0x2E, - 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0x30, 0x3E, 0xC2, 0xED, 0xFD, 0x8C, 0xBB, - 0x05, 0x29, 0xE4, 0x15, 0xB6, 0xEE, 0xF3, 0x46, 0xCC, 0xF0, 0xF5, 0xF6, 0xAF, 0x33, 0x45, 0xF1, - 0x11, 0xEE, 0xE0, 0xE7, 0x6C, 0x84, 0xAC, 0xE8, 0xC8, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x89, - 0x99, 0xC3, 0xAB, 0xD7, 0x9B, 0xED, 0x17, 0xEB, 0xC0, 0x68, 0x36, 0x19, 0x17, 0xAD, 0xA6, 0x82, - 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x5A, 0x3C, 0x3E, 0xDC, 0xB6, 0x7E, 0x38, 0x7C, 0x16, 0x24, 0xD7, - 0x57, 0xD8, 0xDA, 0x9F, 0x6F, 0xB6, 0xFF, 0xDA, 0x5D, 0xF7, 0x4A, 0xE3, 0xA9, 0x8C, 0x0F, 0xB7, - 0x9D, 0xB3, 0xED, 0xEF, 0x67, 0x85, 0xFB, 0x3D, 0x4D, 0xF9, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, - 0x89, 0x79, 0x87, 0x57, 0x6F, 0x90, 0x81, 0xD1, 0x6C, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, - 0x89, 0xB8, 0x68, 0x35, 0x15, 0x1F, 0xE1, 0x82, 0x5B, 0x10, 0xF7, 0x2D, 0x53, 0xC1, 0xDF, 0x8A, - 0xB6, 0x79, 0x87, 0x06, 0x06, 0x27, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8C, 0x24, 0x73, - 0xB7, 0x20, 0xC3, 0x2B, 0xA6, 0xF4, 0xB3, 0x4E, 0x00, 0x00, 0x00, 0x80, 0x54, 0xBC, 0x83, 0x9F, - 0x1B, 0x95, 0x91, 0xD1, 0x68, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0x35, - 0x15, 0x1D, 0xD1, 0xB9, 0x5F, 0x97, 0x7F, 0x63, 0xB0, 0x32, 0x97, 0x87, 0xB7, 0x6B, 0x6F, 0x3F, - 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8B, 0xA4, 0xE3, 0x16, 0x04, 0x00, 0x00, 0x00, 0xDD, 0xCE, 0xDB, - 0x7F, 0xD5, 0xB8, 0x0C, 0x0D, 0xB5, 0xBA, 0xB0, 0x48, 0x32, 0x15, 0x14, 0x69, 0x26, 0xE2, 0xA2, - 0xD5, 0x54, 0x70, 0xA8, 0x0D, 0x2D, 0x30, 0xDE, 0xC8, 0xCA, 0xF1, 0x3C, 0x6E, 0x41, 0xFC, 0xDB, - 0x8F, 0x03, 0xD7, 0xDA, 0x9F, 0x57, 0x44, 0x45, 0xD2, 0xA9, 0xA8, 0x48, 0x3B, 0xF7, 0x96, 0xAF, - 0xE1, 0x65, 0xDC, 0x82, 0x34, 0x60, 0xC6, 0xFE, 0xC3, 0x2C, 0xF3, 0xF2, 0xBF, 0x5F, 0x67, 0x4E, - 0x7C, 0x65, 0x7D, 0x64, 0x6B, 0xDD, 0xBF, 0x1E, 0xFC, 0x47, 0x00, 0x00, 0x00, 0x50, 0x14, 0x77, - 0xF0, 0x4E, 0xFC, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, - 0x0A, 0x8D, 0x46, 0x73, 0xBF, 0xC6, 0x1C, 0x6E, 0x41, 0xDC, 0xA7, 0xAB, 0xFB, 0xB7, 0x1F, 0xEE, - 0x59, 0x1A, 0x15, 0x16, 0x49, 0xA6, 0x62, 0x22, 0xCB, 0xB6, 0x7F, 0xD4, 0xFE, 0x7E, 0x96, 0xDB, - 0x2D, 0x2D, 0xF4, 0xB3, 0x4E, 0x7A, 0x8D, 0x0B, 0x0C, 0xEF, 0xC4, 0x97, 0x07, 0xCD, 0x2F, 0xBE, - 0x62, 0xE4, 0x4E, 0x7C, 0xC9, 0xF8, 0xFF, 0x3E, 0x21, 0x02, 0x00, 0x00, 0x50, 0x1C, 0xFF, 0x0D, - 0x58, 0xBB, 0xE6, 0xE8, 0xE0, 0x88, 0xAE, 0x2E, 0x2C, 0x92, 0x4C, 0x05, 0x45, 0x9A, 0x89, 0xB8, - 0x68, 0x35, 0x15, 0x19, 0xAD, 0xE6, 0xBF, 0xC2, 0x76, 0xE5, 0x78, 0x3B, 0xDF, 0xB6, 0xE4, 0x1D, - 0x1A, 0x18, 0x35, 0xFB, 0xAF, 0xB4, 0x3F, 0x9F, 0x08, 0x8B, 0x24, 0x53, 0x21, 0x91, 0x69, 0x33, - 0x2B, 0xDB, 0x7F, 0x85, 0xF1, 0x86, 0x97, 0x4F, 0xC9, 0x27, 0xBE, 0xF7, 0x02, 0x73, 0xFC, 0xDF, - 0x2F, 0xF1, 0x7E, 0xF1, 0xE5, 0xF1, 0xDA, 0xE0, 0xB8, 0xDD, 0x98, 0xE3, 0x5F, 0xF4, 0xC3, 0x23, - 0xFA, 0xAF, 0xFB, 0xFF, 0x39, 0xFB, 0x9F, 0x0F, 0xFE, 0xAB, 0x00, 0x00, 0x00, 0xC8, 0x93, 0x39, - 0x7C, 0xE3, 0xBA, 0x96, 0xAF, 0xE0, 0x95, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, - 0xAB, 0xA9, 0xB8, 0x48, 0xBA, 0xE1, 0xEB, 0x8D, 0xFB, 0x16, 0xAA, 0xE0, 0x6F, 0x4B, 0x2A, 0x36, - 0x5C, 0x06, 0xEC, 0xB2, 0xDF, 0x7E, 0xC8, 0x90, 0xC8, 0xB2, 0x20, 0x3E, 0xDC, 0xB8, 0x05, 0xA9, - 0xAA, 0x89, 0x0F, 0x17, 0x1D, 0x2F, 0xD9, 0xFF, 0xAD, 0x5E, 0xB0, 0xB1, 0xF8, 0xFC, 0x92, 0xC9, - 0xBD, 0x70, 0xB5, 0xFD, 0xD7, 0x57, 0x55, 0xFE, 0x7D, 0x22, 0x04, 0x00, 0x00, 0xA0, 0x38, 0xFE, - 0x2B, 0x78, 0x55, 0x74, 0x84, 0x93, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, - 0xA9, 0xA8, 0x48, 0xBC, 0x59, 0x95, 0x07, 0xC7, 0xDD, 0xB7, 0x50, 0x65, 0xB8, 0x05, 0xF1, 0x86, - 0x57, 0x64, 0xBF, 0xFD, 0x90, 0x21, 0x91, 0x65, 0x91, 0xF8, 0x08, 0xC7, 0x2D, 0x48, 0x6D, 0x7C, - 0x1C, 0xB9, 0xB1, 0x36, 0x3A, 0xD4, 0x5C, 0x98, 0x1C, 0xFD, 0x42, 0x25, 0x42, 0x4E, 0x7C, 0x85, - 0x1B, 0x24, 0x00, 0x00, 0x80, 0xBC, 0x79, 0x07, 0x97, 0x35, 0x7E, 0x03, 0x96, 0x8C, 0x8B, 0x56, - 0x53, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0x85, 0x1F, 0x16, 0x68, 0xE7, - 0x6E, 0x41, 0x46, 0x06, 0x86, 0x82, 0xBF, 0x35, 0x89, 0xB4, 0x75, 0xFB, 0x21, 0x43, 0x22, 0xCB, - 0x44, 0x7C, 0xB8, 0x6D, 0xFD, 0xD0, 0xB4, 0xBE, 0x05, 0xA9, 0x89, 0x0F, 0x77, 0xEB, 0xA1, 0x82, - 0xA3, 0xD1, 0x5C, 0xAC, 0xF8, 0x37, 0x26, 0x5F, 0x29, 0xE4, 0xD3, 0xF2, 0x01, 0x00, 0x00, 0xA6, - 0x2D, 0x6F, 0xFF, 0x35, 0x63, 0xC4, 0x47, 0xB0, 0xED, 0x1F, 0xB7, 0x87, 0x75, 0xFF, 0x16, 0x24, - 0xF1, 0x81, 0xDD, 0x1B, 0x59, 0x31, 0xE6, 0x3F, 0xC4, 0xAF, 0x02, 0xA3, 0xD9, 0x64, 0x48, 0x64, - 0x99, 0x08, 0x8F, 0xE8, 0xF6, 0x2C, 0xB2, 0x51, 0xB5, 0x7C, 0x2C, 0xF8, 0xE5, 0x4E, 0x1B, 0x6D, - 0xC5, 0x47, 0xB8, 0x63, 0x7F, 0xE2, 0x3F, 0x94, 0x1E, 0xFC, 0x94, 0x00, 0x00, 0x00, 0xC8, 0x83, - 0xD9, 0xF7, 0x19, 0xE2, 0xC3, 0xED, 0x99, 0x60, 0xFB, 0xAF, 0x32, 0xDE, 0xF0, 0x40, 0xA2, 0x6F, - 0xBD, 0xB1, 0xA1, 0xB2, 0xCE, 0xBF, 0xFD, 0x70, 0x7F, 0xCF, 0x54, 0x64, 0x34, 0x9A, 0x0C, 0x89, - 0x2C, 0x13, 0xC1, 0x11, 0x9F, 0xFB, 0x7B, 0xEB, 0xDF, 0x82, 0x2C, 0xCF, 0xF5, 0x13, 0xDF, 0xBB, - 0x59, 0x2E, 0xF1, 0xE1, 0xF6, 0xC2, 0xD5, 0xEE, 0xDB, 0xB0, 0x4E, 0x06, 0x3F, 0x2D, 0x00, 0x00, - 0x00, 0xDA, 0x65, 0x0E, 0xDF, 0xB8, 0xC4, 0x0C, 0x2D, 0x9C, 0xBE, 0xF1, 0x11, 0x46, 0x47, 0xF0, - 0x7F, 0x7B, 0x6E, 0xDB, 0x3F, 0xEE, 0xBE, 0x0D, 0x2B, 0xD1, 0x2D, 0x88, 0x37, 0xBC, 0xE2, 0x64, - 0xEA, 0xDB, 0x0F, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, 0xD1, 0xDC, 0x2D, 0xC8, 0xF0, 0xB2, 0x69, - 0x71, 0x90, 0xCE, 0x2D, 0x3E, 0xC2, 0x1D, 0xBB, 0xC5, 0x04, 0x3F, 0x35, 0x00, 0x00, 0x00, 0xDA, - 0x65, 0x0E, 0xAD, 0x5A, 0x5B, 0xF3, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, - 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0xAB, 0x8F, 0x0F, 0x3F, 0x3C, 0xC2, 0x6D, 0xB2, 0xDB, 0x7B, - 0x85, 0x39, 0x3F, 0x3C, 0xD0, 0xF4, 0xC0, 0x9E, 0xE9, 0xF6, 0x43, 0x86, 0x44, 0x96, 0x89, 0xC8, - 0x68, 0x36, 0xF7, 0xF7, 0x79, 0x1A, 0xDC, 0x82, 0xE4, 0x1E, 0x1F, 0xCF, 0x7F, 0xC6, 0x98, 0x23, - 0x37, 0x18, 0xF3, 0xF2, 0x9D, 0x7C, 0x9E, 0x0A, 0x00, 0x00, 0x40, 0x1E, 0xFC, 0x37, 0x60, 0x6D, - 0xFB, 0xC8, 0xF4, 0x8D, 0x8F, 0x68, 0x78, 0xB8, 0xB9, 0xF8, 0x70, 0xDB, 0xFC, 0x21, 0xF7, 0x6D, - 0x58, 0xEE, 0x16, 0xA4, 0xE1, 0x81, 0xDD, 0xBF, 0xFD, 0xD8, 0xB3, 0xD0, 0xFE, 0x7C, 0x22, 0x34, - 0xD4, 0x64, 0x48, 0x64, 0x99, 0x08, 0x8C, 0x24, 0x1B, 0x9A, 0x5F, 0xEA, 0x5B, 0x90, 0x42, 0xE2, - 0xC3, 0x6D, 0xEC, 0x3A, 0x17, 0x20, 0xD3, 0xE6, 0xDB, 0xD7, 0x00, 0x00, 0x00, 0x0A, 0xE5, 0x1D, - 0x5A, 0x3D, 0x38, 0xED, 0xE2, 0x23, 0x12, 0x20, 0xD5, 0xE8, 0x88, 0xC4, 0xC7, 0xF9, 0x70, 0x43, - 0x97, 0x9B, 0x73, 0x07, 0xF5, 0x2D, 0xC8, 0xF9, 0x91, 0xFE, 0xF5, 0x66, 0x78, 0x99, 0xFD, 0xB9, - 0xDC, 0xAF, 0x49, 0xC4, 0x46, 0x7C, 0x32, 0x24, 0xB2, 0x4C, 0x84, 0x45, 0xD2, 0xB9, 0xDF, 0xF7, - 0xF0, 0xF5, 0xEE, 0x16, 0xA4, 0xAD, 0x4F, 0x7C, 0xEF, 0x46, 0x85, 0xC5, 0x87, 0xDB, 0x0B, 0x57, - 0x19, 0x73, 0xE2, 0xCE, 0xD2, 0xFD, 0x3D, 0x03, 0x00, 0x00, 0xE8, 0x08, 0x6F, 0xDF, 0x55, 0xA3, - 0x3A, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xC5, 0xC2, 0x22, 0xC9, 0x64, 0x54, 0x24, 0x5D, 0x24, - 0x3E, 0x82, 0xD5, 0xDC, 0x78, 0x84, 0xD1, 0xF1, 0x74, 0x64, 0x9B, 0x3F, 0x64, 0xCE, 0x1F, 0x5C, - 0x6E, 0xCE, 0x0D, 0xF7, 0xDF, 0x15, 0xFC, 0xED, 0xF2, 0x99, 0xA1, 0xFE, 0x59, 0xE7, 0x47, 0x56, - 0x8C, 0x9B, 0xDD, 0x7D, 0xF6, 0x60, 0x2F, 0x62, 0x23, 0x3E, 0x19, 0x12, 0x59, 0x26, 0xA2, 0x22, - 0xED, 0x76, 0xCF, 0x35, 0xDE, 0xC8, 0xB2, 0x71, 0xF7, 0x7B, 0x08, 0x7E, 0x3B, 0x3D, 0xAF, 0xD0, - 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x9F, 0x07, 0x02, 0x00, 0x00, 0x90, 0x07, 0xB3, 0xEF, 0x0A, - 0x7B, 0xB8, 0x57, 0x81, 0xD1, 0x6C, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, 0x48, - 0xBA, 0x48, 0x78, 0x44, 0x6F, 0x3E, 0xE2, 0xB7, 0x1E, 0x7E, 0x78, 0xBC, 0xCF, 0x9C, 0x7B, 0x6A, - 0x72, 0xE7, 0x77, 0xCE, 0x77, 0xB7, 0x20, 0x35, 0x07, 0xF6, 0xF3, 0x07, 0xFB, 0xD7, 0x7B, 0xC3, - 0xCB, 0x8C, 0xE7, 0x6E, 0x3F, 0x5A, 0x05, 0x88, 0x0C, 0x89, 0x2C, 0x13, 0x31, 0x91, 0x76, 0x9B, - 0x66, 0xD8, 0x1F, 0xED, 0xAF, 0xA9, 0x44, 0xB7, 0x20, 0x53, 0x11, 0x1F, 0x6E, 0xDE, 0xD1, 0x5B, - 0xA6, 0xDD, 0x6B, 0x8C, 0x01, 0x00, 0x00, 0x72, 0x67, 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x8B, 0xED, - 0x01, 0x5F, 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x58, 0x24, 0x99, 0x8C, 0x8A, 0xA4, - 0x8B, 0xC4, 0x47, 0x83, 0x00, 0x09, 0xE3, 0xE3, 0x5C, 0x24, 0x3E, 0xCE, 0x6E, 0x0C, 0xF6, 0xD4, - 0xFB, 0xCD, 0xF9, 0x03, 0xCB, 0x8D, 0x8B, 0x0E, 0xFF, 0xEF, 0x99, 0x0D, 0x91, 0x73, 0xC3, 0x2B, - 0xC6, 0xBD, 0x5D, 0x7D, 0xF6, 0xBF, 0x7F, 0x91, 0x3F, 0xFF, 0x50, 0xAF, 0x42, 0x44, 0x86, 0x44, - 0x96, 0x89, 0x98, 0x48, 0x3B, 0x17, 0x1F, 0xE1, 0x4A, 0x72, 0x0B, 0x32, 0x55, 0xF1, 0xE1, 0xEF, - 0xE8, 0xE7, 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xBB, 0xCC, 0xC8, 0xEA, 0x01, 0xB3, 0xEB, 0x52, - 0x7B, 0xC8, 0x57, 0xA1, 0xA1, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, - 0x4B, 0x1F, 0x1F, 0xD5, 0xF0, 0x78, 0xD2, 0x6D, 0x96, 0xBF, 0x73, 0x3B, 0xE6, 0x9B, 0xB3, 0x07, - 0x2A, 0xB7, 0x20, 0x2E, 0x44, 0xCE, 0x1F, 0x5C, 0x66, 0xFF, 0xFB, 0x7F, 0xDC, 0x3C, 0x40, 0x64, - 0x48, 0x64, 0x99, 0x88, 0x89, 0xB4, 0x8B, 0xC6, 0x87, 0x9B, 0xFB, 0xB5, 0x1E, 0xBC, 0xB6, 0xA7, - 0x6F, 0x41, 0xA6, 0x34, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0xEC, 0x5F, 0x33, 0xF8, 0xCB, 0x03, 0x00, - 0x00, 0x20, 0x0B, 0xEF, 0xD0, 0xAA, 0xBB, 0xCC, 0xF6, 0x4F, 0xD8, 0x83, 0xBE, 0x8A, 0x8D, 0xF8, - 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, 0x74, 0xB1, 0xF8, 0x08, 0x02, 0x24, - 0x49, 0x7C, 0xBC, 0x6B, 0xE3, 0xE3, 0xDD, 0xC1, 0x59, 0x93, 0xDB, 0xF8, 0x7E, 0x73, 0x6E, 0xEF, - 0xF5, 0xE6, 0xDC, 0x81, 0x81, 0x51, 0xF7, 0xED, 0x58, 0xE7, 0xB7, 0x5F, 0x62, 0xFF, 0xBB, 0x36, - 0x3E, 0xDC, 0x54, 0x84, 0xC8, 0x90, 0xC8, 0x32, 0x11, 0x13, 0x69, 0x17, 0x8F, 0x8F, 0x70, 0x3B, - 0x3E, 0xE9, 0x02, 0xC4, 0xBD, 0xE5, 0x6B, 0x76, 0xF0, 0x8F, 0x43, 0xCF, 0x98, 0xF2, 0xF8, 0x70, - 0x1B, 0x5B, 0x66, 0xCC, 0x89, 0xAF, 0xAC, 0x0D, 0x7E, 0x09, 0x00, 0x00, 0x00, 0xC8, 0xC2, 0x3B, - 0xBC, 0x7A, 0x83, 0x8E, 0x8D, 0xF8, 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, - 0x74, 0x3A, 0x3E, 0xEA, 0x02, 0xC4, 0x86, 0x47, 0xF8, 0xCC, 0x47, 0x3C, 0x3E, 0x26, 0xDC, 0x9E, - 0xA8, 0xCC, 0xFD, 0xFF, 0x67, 0xB7, 0x7C, 0xDA, 0x4C, 0x3C, 0xD3, 0x6F, 0xCE, 0x0D, 0xD9, 0x10, - 0x79, 0xCA, 0xFD, 0x77, 0x2F, 0xD2, 0x11, 0xB2, 0x49, 0x85, 0x44, 0x96, 0x89, 0x98, 0x48, 0x3B, - 0x15, 0x1E, 0xD1, 0x1D, 0xBC, 0xD6, 0xBD, 0x96, 0x77, 0x30, 0xF8, 0xC7, 0xA1, 0x27, 0x74, 0x24, - 0x3E, 0xDC, 0x5E, 0xBC, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0xB4, 0xCB, 0x3B, 0x78, 0x4D, 0x82, - 0x37, 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0xE1, 0x11, - 0x2E, 0x1E, 0x1F, 0xE1, 0xED, 0x47, 0xE4, 0x99, 0x0F, 0x17, 0x1F, 0xD1, 0xF0, 0x98, 0x78, 0x3C, - 0x98, 0xFB, 0xBF, 0x1F, 0x9B, 0x65, 0x4E, 0x3F, 0x72, 0x9D, 0x39, 0xF3, 0xF0, 0x25, 0x7E, 0x80, - 0x9C, 0xF3, 0x1F, 0x58, 0x8F, 0x05, 0x88, 0x8B, 0x8F, 0x5C, 0x02, 0x44, 0xC4, 0x44, 0xDA, 0xA9, - 0xE0, 0x88, 0xAF, 0xC7, 0x6E, 0x41, 0x3A, 0x16, 0x1F, 0xC1, 0xBC, 0x5F, 0xDC, 0x39, 0x14, 0xFC, - 0x52, 0x00, 0x00, 0x00, 0x90, 0x85, 0xB7, 0xFF, 0xEA, 0x93, 0x3A, 0x3A, 0xC2, 0xA9, 0xA0, 0x48, - 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x78, 0xB8, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, - 0xDE, 0x7E, 0xD4, 0x7E, 0xEB, 0x55, 0x34, 0x3E, 0xCE, 0xD8, 0xE8, 0x38, 0xF3, 0xF8, 0xFB, 0x82, - 0x55, 0x22, 0xE4, 0xF4, 0xFD, 0x17, 0x99, 0x53, 0xF7, 0x5E, 0x6C, 0x4E, 0xDD, 0x7D, 0x91, 0x39, - 0x6B, 0xFF, 0x33, 0x75, 0xB7, 0x20, 0x36, 0x3C, 0xDC, 0xDA, 0x0F, 0x10, 0x11, 0x13, 0x69, 0xA7, - 0x62, 0xA3, 0xD1, 0x7A, 0xE4, 0x16, 0xA4, 0xD3, 0xF1, 0xE1, 0xE6, 0x1D, 0xFB, 0x53, 0xDE, 0x84, - 0x05, 0x00, 0x00, 0xD0, 0x8E, 0xE6, 0x6F, 0xC0, 0x52, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, - 0x46, 0x45, 0xD2, 0xC5, 0xA2, 0x23, 0xBA, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDC, 0x7E, 0xD4, 0x7C, - 0xDB, 0x55, 0x18, 0x1F, 0x8F, 0xD9, 0xF0, 0xB0, 0x3B, 0x1D, 0xFC, 0x78, 0xE6, 0x91, 0xF7, 0xF9, - 0xE1, 0x11, 0xEE, 0xF4, 0x7D, 0x36, 0x42, 0x36, 0x4E, 0x46, 0x88, 0xF7, 0x74, 0x25, 0x3E, 0xAA, - 0x01, 0x92, 0x39, 0x42, 0x44, 0x4C, 0xA4, 0x9D, 0x8A, 0x8C, 0x66, 0xDB, 0x7E, 0x71, 0xD7, 0xDF, - 0x82, 0x74, 0x43, 0x7C, 0xF8, 0x3B, 0x76, 0x0B, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xC8, 0xCA, 0x7F, - 0x03, 0xD6, 0xEE, 0x79, 0xF6, 0xE0, 0x5F, 0xFE, 0xF8, 0x70, 0x3F, 0x36, 0xBF, 0xFD, 0xB0, 0xF1, - 0xE1, 0x02, 0x24, 0x88, 0x0F, 0x17, 0x1E, 0xA7, 0x1F, 0x9D, 0xDC, 0xA9, 0x7B, 0x67, 0xD5, 0x04, - 0x88, 0xDB, 0xBB, 0x3F, 0x0E, 0x02, 0xE4, 0xA9, 0x0B, 0xED, 0xCF, 0x67, 0xE3, 0x23, 0x1E, 0x21, - 0x32, 0x30, 0x9A, 0x4D, 0xC4, 0x44, 0xDA, 0xA9, 0xC0, 0x48, 0xB2, 0x7D, 0x57, 0x18, 0x6F, 0x78, - 0x79, 0x57, 0x7E, 0xD0, 0x5E, 0xD7, 0xC4, 0x87, 0x9B, 0x7B, 0x13, 0xD6, 0xCB, 0x77, 0xF6, 0xDC, - 0x43, 0xFB, 0x00, 0x00, 0x00, 0x5D, 0xC1, 0x1C, 0x5A, 0xB5, 0xD6, 0xEC, 0x9C, 0x6D, 0x0F, 0xFF, - 0x25, 0x8E, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDD, 0x7E, 0xB8, 0xD7, 0xEC, 0x46, 0x6F, - 0x3F, 0xE2, 0xF1, 0x71, 0xFA, 0x81, 0xDA, 0xDB, 0x8F, 0x70, 0xEE, 0x16, 0xE4, 0xDC, 0x93, 0x76, - 0x1B, 0x2F, 0xF2, 0x23, 0xA4, 0x26, 0x40, 0x5C, 0x50, 0xA4, 0x8A, 0x10, 0x11, 0x13, 0x69, 0xA7, - 0xC2, 0x22, 0xE9, 0xB6, 0x7D, 0x24, 0xB8, 0x05, 0x59, 0x3A, 0x10, 0xFC, 0xE3, 0xD1, 0x15, 0xBA, - 0x2A, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0xB3, 0xAB, 0xFE, 0x1E, 0x01, 0x00, 0x00, 0xF4, - 0x0C, 0x73, 0x78, 0xF5, 0x7A, 0xB3, 0xF5, 0xC3, 0x36, 0x00, 0x4A, 0x1C, 0x1F, 0xC1, 0xD4, 0xED, - 0xC7, 0x59, 0x3F, 0x40, 0x6C, 0x7C, 0xB8, 0xDB, 0x8F, 0xC8, 0xB7, 0x5E, 0x55, 0xC3, 0xE3, 0xC7, - 0x95, 0xA9, 0xDB, 0x0F, 0x7F, 0x5F, 0xBF, 0xD0, 0xBC, 0xFB, 0x48, 0x25, 0x40, 0xCE, 0xB5, 0x75, - 0x0B, 0x22, 0x62, 0x22, 0xED, 0x54, 0x54, 0xA4, 0x9D, 0xBB, 0x05, 0x39, 0xB8, 0xAC, 0x6B, 0x6E, - 0x41, 0xBA, 0x2E, 0x3E, 0xDC, 0x78, 0x13, 0x16, 0x00, 0x00, 0x40, 0x76, 0xDE, 0xC8, 0x8A, 0xA1, - 0xD2, 0xC7, 0x47, 0xC3, 0xDB, 0x8F, 0x59, 0xD5, 0xF8, 0xA8, 0xDE, 0x7E, 0x84, 0xF1, 0x11, 0x84, - 0x87, 0x1F, 0x1F, 0x3F, 0xD2, 0xB7, 0x1F, 0x2E, 0x3E, 0xDC, 0x4E, 0x7F, 0xEB, 0x42, 0x73, 0xB6, - 0xAD, 0x5B, 0x10, 0x11, 0x13, 0x69, 0xA7, 0x62, 0x22, 0xCB, 0xB6, 0xD9, 0x18, 0x1D, 0x5E, 0xD6, - 0x15, 0xB7, 0x20, 0x5D, 0x19, 0x1F, 0xC1, 0xBC, 0x13, 0x5F, 0xEE, 0xA9, 0xD7, 0x16, 0x03, 0x00, - 0x00, 0x74, 0x0D, 0x6F, 0xDF, 0x55, 0x63, 0x65, 0xBF, 0xF9, 0x70, 0xAB, 0xBF, 0xFD, 0x88, 0x04, - 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x70, 0x44, 0x02, 0xE4, 0x94, 0x7B, 0xE8, 0xDC, 0xED, 0xDB, 0xE2, - 0xF6, 0x23, 0x88, 0x8F, 0x70, 0x13, 0x0F, 0x64, 0xBD, 0x05, 0x11, 0x31, 0x91, 0x76, 0x2A, 0x24, - 0x32, 0xED, 0x82, 0xCA, 0xF6, 0x5C, 0xD6, 0xF1, 0x5B, 0x90, 0x6E, 0x8E, 0x0F, 0x37, 0xEF, 0xF8, - 0x9F, 0x75, 0xE5, 0xB3, 0x32, 0x00, 0x00, 0x00, 0x5D, 0xCF, 0xEC, 0xBD, 0xDC, 0x86, 0x40, 0x89, - 0xE3, 0x23, 0xC1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xC1, 0xB7, 0x5E, 0x9D, 0x0A, 0x03, 0xE4, 0x07, - 0xAD, 0xE3, 0xC3, 0xED, 0xF4, 0x3D, 0x2D, 0x6E, 0x41, 0xE4, 0x44, 0x4C, 0xA4, 0x9D, 0x0C, 0x89, - 0x2C, 0x0B, 0xE2, 0xC3, 0xCD, 0xFD, 0xFD, 0xF5, 0x6F, 0x41, 0x96, 0xAF, 0x0B, 0xFE, 0x31, 0x99, - 0x52, 0xDD, 0x1E, 0x1F, 0xFE, 0x8E, 0xFF, 0x29, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x48, 0xCB, 0xBD, - 0x72, 0xD5, 0xEC, 0x59, 0x64, 0x63, 0x40, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0xBA, 0xA0, - 0x48, 0x33, 0x11, 0x1A, 0x8D, 0x16, 0x0F, 0x90, 0xE0, 0xF6, 0xE3, 0x6C, 0x92, 0xDB, 0x8F, 0x87, - 0xED, 0xEE, 0x69, 0x1D, 0x1F, 0xE1, 0xC2, 0x5B, 0x90, 0x64, 0x6F, 0xC4, 0x12, 0x31, 0x91, 0x76, - 0x32, 0x24, 0xB2, 0x2C, 0x12, 0x1F, 0xE1, 0x86, 0x16, 0x1A, 0xEF, 0xE0, 0xD2, 0x93, 0xC1, 0x3F, - 0x2A, 0x53, 0xA6, 0x27, 0xE2, 0xC3, 0xED, 0xC8, 0x6A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0x90, 0x96, - 0xFF, 0x0A, 0xDE, 0x9D, 0x9F, 0xB2, 0x41, 0xA0, 0xA2, 0x22, 0xE9, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, - 0x8A, 0xA4, 0x13, 0x91, 0xA1, 0x66, 0x83, 0xA3, 0x1A, 0x1F, 0x36, 0x3C, 0x12, 0xDF, 0x7E, 0x44, - 0xBF, 0xF5, 0xEA, 0xFB, 0xB1, 0xDB, 0x0F, 0x11, 0x1D, 0xD1, 0x25, 0xBF, 0x05, 0x11, 0x31, 0x91, - 0x76, 0x32, 0x24, 0xB2, 0x4C, 0xC4, 0x87, 0x9B, 0xFB, 0x7B, 0x3D, 0xC5, 0xB7, 0x20, 0x3D, 0x13, - 0x1F, 0x3F, 0xBF, 0xDC, 0x98, 0xB1, 0x15, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x20, 0x2D, 0x73, 0x78, - 0xE5, 0x7A, 0xB3, 0xED, 0xA3, 0x36, 0x0A, 0x54, 0x58, 0x24, 0x99, 0x88, 0x8B, 0x56, 0xAB, 0x0B, - 0x8A, 0x34, 0x8B, 0x45, 0x46, 0xB3, 0x45, 0x03, 0xC4, 0xAE, 0x12, 0x1F, 0x36, 0x0E, 0xC2, 0x00, - 0x69, 0xF4, 0xDA, 0xDD, 0x46, 0xB7, 0x1F, 0x22, 0x38, 0xD4, 0x26, 0x7E, 0x50, 0x09, 0x90, 0x9A, - 0x67, 0x41, 0x82, 0x10, 0xA9, 0xDC, 0x82, 0x88, 0x98, 0x48, 0x3B, 0x19, 0x12, 0x59, 0x26, 0xC2, - 0x23, 0xBA, 0x29, 0xBC, 0x05, 0xE9, 0xA9, 0xF8, 0x70, 0x7B, 0xF1, 0x3A, 0x63, 0x7F, 0xBD, 0x77, - 0x05, 0xBF, 0x7C, 0x00, 0x00, 0x00, 0x24, 0xE1, 0x1D, 0x5E, 0xB9, 0x41, 0x87, 0x45, 0x92, 0x89, - 0xB8, 0x68, 0x35, 0x19, 0x15, 0x49, 0x17, 0x0B, 0x8C, 0x66, 0x8B, 0xC5, 0x47, 0xE5, 0xF6, 0x23, - 0x12, 0x1F, 0xCD, 0x6E, 0x3F, 0xC2, 0x00, 0x89, 0xDE, 0x7E, 0x88, 0xD0, 0x68, 0xB8, 0x6F, 0x5C, - 0x68, 0xCE, 0x3E, 0xD1, 0xE0, 0x16, 0x64, 0x93, 0x88, 0x89, 0xB4, 0x93, 0x21, 0x91, 0x65, 0x22, - 0x38, 0xE2, 0x73, 0x7F, 0xDF, 0x0F, 0x5E, 0x57, 0xF8, 0x2D, 0x48, 0xCF, 0xC5, 0x47, 0x30, 0xEF, - 0xC4, 0x9D, 0x1B, 0x82, 0xDF, 0x02, 0x00, 0x00, 0x00, 0x92, 0xF0, 0x0E, 0x5E, 0x3D, 0xAA, 0xE3, - 0xA2, 0xD5, 0x44, 0x5C, 0xB4, 0x5A, 0x5D, 0x50, 0xA4, 0x59, 0x2C, 0x30, 0x9A, 0xAD, 0x41, 0x7C, - 0xF8, 0xB7, 0x1F, 0x2E, 0x3E, 0xD4, 0xED, 0x47, 0x10, 0x1F, 0xD5, 0xDB, 0x8F, 0x87, 0xEC, 0xBE, - 0x91, 0x21, 0x3E, 0x82, 0x85, 0xB7, 0x20, 0xE7, 0x9F, 0x72, 0x7F, 0xDD, 0x20, 0x42, 0x9E, 0x9E, - 0x69, 0x7F, 0x2D, 0x2E, 0x20, 0x82, 0xA9, 0xB8, 0x68, 0x35, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, - 0xD1, 0x76, 0xCD, 0x31, 0xDE, 0xF0, 0xD2, 0x71, 0x33, 0xD4, 0x3F, 0x2B, 0xF8, 0xC7, 0x26, 0x57, - 0xBD, 0x1A, 0x1F, 0x7E, 0x80, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x74, 0xBC, 0xFD, 0x9F, 0x1D, - 0xD7, 0x81, 0xD1, 0x6C, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xC5, 0x02, 0xA3, 0xD5, 0xEA, - 0x02, 0x24, 0x88, 0x8F, 0xF8, 0xED, 0x47, 0x10, 0x1F, 0xF2, 0xD9, 0x8F, 0xFB, 0x83, 0xDB, 0x0F, - 0x11, 0x17, 0x89, 0x16, 0xBB, 0x05, 0x39, 0x1F, 0xC4, 0x47, 0x5B, 0x01, 0x22, 0x43, 0x22, 0xCB, - 0x44, 0x64, 0x34, 0x9B, 0x7B, 0x66, 0xC5, 0xDD, 0x82, 0x1C, 0x5C, 0x9A, 0xFB, 0x07, 0xEF, 0xF5, - 0x72, 0x7C, 0xB8, 0x79, 0xC7, 0xFE, 0x64, 0x3C, 0xF8, 0xAD, 0x00, 0x00, 0x00, 0xA0, 0x15, 0x33, - 0xDA, 0x3F, 0x2B, 0xFD, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x8B, 0xC5, 0x45, - 0x92, 0xC5, 0xE3, 0x23, 0x7A, 0xFB, 0x11, 0xC4, 0x47, 0xCD, 0x9B, 0xAF, 0x1A, 0xDD, 0x7E, 0xA8, - 0xB0, 0x48, 0xB1, 0x33, 0xDF, 0xBB, 0x70, 0xF2, 0x59, 0x90, 0xA7, 0x6C, 0x7C, 0xB4, 0x13, 0x21, - 0x32, 0x24, 0xB2, 0x4C, 0x04, 0x46, 0x92, 0x15, 0x70, 0x0B, 0xD2, 0xEB, 0xF1, 0xE1, 0xEF, 0xC8, - 0x4D, 0xC6, 0x8C, 0xFD, 0x87, 0x42, 0x6E, 0x86, 0x00, 0x00, 0x00, 0x4A, 0xC7, 0x7F, 0x03, 0xD6, - 0xAE, 0x4F, 0xDB, 0x48, 0x50, 0xA1, 0xA1, 0x26, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, - 0x8B, 0x56, 0xB3, 0xD1, 0x31, 0x19, 0x20, 0x17, 0x55, 0x02, 0x24, 0xB8, 0xFD, 0xA8, 0xBE, 0x76, - 0xB7, 0x7A, 0xFB, 0xF1, 0xBE, 0xC6, 0xB7, 0x1F, 0x22, 0x28, 0xB2, 0xEC, 0xEC, 0x63, 0x2E, 0x42, - 0x2A, 0x01, 0xE2, 0xDF, 0x82, 0x64, 0x89, 0x10, 0x19, 0x12, 0x59, 0x26, 0xC2, 0x22, 0xE9, 0x72, - 0xBE, 0x05, 0x29, 0x45, 0x7C, 0xB8, 0xBD, 0x34, 0xC0, 0x9B, 0xB0, 0x00, 0x00, 0x00, 0x92, 0x32, - 0x87, 0x57, 0xAD, 0x4B, 0xFE, 0x0A, 0x5E, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x61, - 0x91, 0x74, 0xF1, 0xF8, 0xC8, 0x74, 0xFB, 0xA1, 0x63, 0x22, 0xFD, 0x66, 0x9A, 0x33, 0xF7, 0xCF, - 0x34, 0x67, 0x9F, 0x9C, 0x8C, 0x90, 0xD4, 0x01, 0x22, 0x43, 0x22, 0xCB, 0x44, 0x54, 0xA4, 0xDD, - 0xCE, 0xD9, 0xC6, 0x1B, 0xBE, 0xBE, 0xED, 0x5B, 0x90, 0xD2, 0xC4, 0x87, 0x1B, 0x6F, 0xC2, 0x02, - 0x00, 0x00, 0x48, 0xCE, 0xB8, 0x57, 0xF0, 0xCA, 0xD8, 0x88, 0x4F, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, - 0x48, 0x3A, 0x11, 0x16, 0x49, 0xE6, 0x6E, 0x3F, 0xEC, 0x8F, 0x7E, 0x7C, 0xC4, 0x6E, 0x3F, 0xEA, - 0x9F, 0xFD, 0x68, 0x70, 0xFB, 0x71, 0x5F, 0xFB, 0xDF, 0x7A, 0x55, 0xD9, 0xCC, 0xEA, 0xDE, 0x0D, - 0x6E, 0x41, 0xCE, 0x35, 0xBA, 0x05, 0x51, 0xE1, 0xE1, 0x26, 0x43, 0x22, 0xCB, 0x44, 0x4C, 0x64, - 0xDA, 0x7B, 0x8D, 0x39, 0x70, 0xB5, 0x7B, 0x2D, 0xEF, 0x60, 0xF0, 0x8F, 0x50, 0x6A, 0xA5, 0x8A, - 0x0F, 0xB7, 0xE7, 0xAF, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x49, 0x79, 0x07, 0xAF, 0x4B, 0xF0, - 0x06, 0x2C, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x51, 0x91, 0x66, 0xE1, 0xCD, 0x47, - 0x83, 0xDB, 0x8F, 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0x78, 0x30, 0xAF, 0x6F, 0xBD, 0x9A, 0x8C, 0x0F, - 0xB7, 0x4C, 0xB7, 0x20, 0x32, 0x24, 0xB2, 0x4C, 0x85, 0x44, 0x96, 0xD9, 0xF8, 0x70, 0xDB, 0xFE, - 0x71, 0xF7, 0x6D, 0x58, 0xC6, 0x8C, 0x5C, 0x9B, 0xFA, 0x13, 0xC0, 0x4B, 0x17, 0x1F, 0xC1, 0xBC, - 0x13, 0x77, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x24, 0xBC, 0x7D, 0x57, 0x8E, 0xE9, 0xE8, 0x08, - 0x27, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, 0x8A, 0xA4, 0xF3, 0x6F, 0x3F, 0x82, 0xF8, - 0x88, 0xDD, 0x7E, 0xA8, 0x67, 0x3F, 0xEA, 0x3F, 0x74, 0xD0, 0xC6, 0x47, 0x2E, 0xB7, 0x1F, 0xB5, - 0xF1, 0x11, 0xEE, 0xDD, 0x47, 0x5A, 0x3C, 0x0B, 0xD2, 0x0B, 0xF1, 0xF1, 0x74, 0xB0, 0xFD, 0xE9, - 0x6F, 0x41, 0xCA, 0x1A, 0x1F, 0x6E, 0xDE, 0xB1, 0x5B, 0xA6, 0xE4, 0x83, 0x1A, 0x01, 0x00, 0x00, - 0x7A, 0x9E, 0xD9, 0x7B, 0x99, 0x8D, 0x06, 0x15, 0x1E, 0x6E, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, - 0xD2, 0xC5, 0x82, 0x22, 0xED, 0xC2, 0xF0, 0x68, 0x70, 0xFB, 0x51, 0xF7, 0xEC, 0x47, 0x10, 0x20, - 0x95, 0xDB, 0x0F, 0x1B, 0x1F, 0xB9, 0xDC, 0x7E, 0xE8, 0xF8, 0x70, 0x3B, 0x7D, 0xEF, 0x4C, 0x73, - 0xAE, 0xD1, 0x2D, 0x88, 0x1F, 0x1D, 0x3D, 0x12, 0x1F, 0xF6, 0xFF, 0xF6, 0xB6, 0x7F, 0xDC, 0x05, - 0x48, 0xE2, 0x5B, 0x90, 0x32, 0xC7, 0x87, 0xBF, 0x23, 0x37, 0x99, 0xE0, 0xB7, 0x0A, 0x00, 0x00, - 0x80, 0x46, 0xCC, 0xE1, 0xFE, 0x25, 0x66, 0x68, 0xBE, 0x0D, 0x87, 0x72, 0xC4, 0x47, 0xCB, 0xDB, - 0x0F, 0x11, 0x1F, 0x95, 0xDB, 0x0F, 0x1B, 0x1E, 0xB9, 0xDC, 0x7E, 0xE8, 0xF0, 0x88, 0x2E, 0xBC, - 0x05, 0x69, 0xF8, 0x2C, 0x88, 0x0C, 0x89, 0x2C, 0x53, 0x21, 0x91, 0x65, 0x22, 0x3E, 0xEC, 0x8F, - 0xFE, 0xF6, 0x7C, 0xC6, 0x9C, 0x3F, 0x70, 0xFD, 0x50, 0xF0, 0x8F, 0x53, 0x43, 0xA5, 0x8F, 0x0F, - 0x37, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x9A, 0xFF, 0x0A, 0x5E, 0xF9, 0x06, 0x2C, 0x11, 0x17, - 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x50, 0xA4, 0x9A, 0x8D, 0x8F, 0x30, 0x3C, 0xC2, 0xF8, 0x48, - 0x7A, 0xFB, 0xF1, 0x63, 0x1B, 0x1E, 0x2E, 0x40, 0x7E, 0xD8, 0xEE, 0xED, 0x87, 0x0E, 0x8E, 0xF8, - 0xDC, 0x2D, 0x48, 0xE3, 0x67, 0x41, 0x54, 0x48, 0x64, 0x99, 0x0A, 0x89, 0x2C, 0x6B, 0x12, 0x1F, - 0x4F, 0xBD, 0xD7, 0x9C, 0xDF, 0xF2, 0x21, 0x73, 0x7E, 0xFF, 0x32, 0x73, 0x76, 0xFF, 0xD2, 0x86, - 0x07, 0xEF, 0x69, 0x11, 0x1F, 0x6E, 0x2F, 0x5E, 0xE7, 0x02, 0x64, 0x5D, 0xF0, 0xDB, 0x06, 0x00, - 0x00, 0x80, 0xE2, 0xBF, 0x01, 0x6B, 0xEB, 0x87, 0x6C, 0x40, 0xF4, 0x7E, 0x7C, 0x64, 0xB9, 0xFD, - 0xA8, 0xC6, 0x87, 0xBB, 0xFD, 0xF8, 0x56, 0x3B, 0xB7, 0x1F, 0x3A, 0x36, 0x1A, 0x6D, 0xE2, 0x21, - 0x75, 0x0B, 0x32, 0xC3, 0x9F, 0x0E, 0x8A, 0x34, 0x53, 0x21, 0x91, 0x65, 0x2D, 0xE2, 0xC3, 0x6D, - 0xE3, 0x05, 0xE6, 0xFC, 0xEE, 0x25, 0xE6, 0xDC, 0xDE, 0x65, 0xF2, 0x01, 0xEC, 0x69, 0x13, 0x1F, - 0x6E, 0xCF, 0x5F, 0x69, 0xCC, 0x89, 0x3B, 0x73, 0xFF, 0x94, 0x78, 0x00, 0x00, 0x80, 0x52, 0xF1, - 0x0E, 0xAD, 0x1C, 0xEC, 0xF9, 0xF8, 0xC8, 0x78, 0xFB, 0x71, 0xEA, 0x51, 0x1B, 0x1D, 0xB9, 0xDC, - 0x7E, 0xE8, 0xC8, 0x68, 0xB6, 0xD3, 0xF7, 0xC4, 0x6F, 0x41, 0x2A, 0xF1, 0xD1, 0x7E, 0x80, 0xA8, - 0x90, 0xC8, 0xB2, 0x64, 0xF1, 0x71, 0xEE, 0x49, 0xBB, 0x4D, 0x1F, 0x76, 0x01, 0x62, 0xCE, 0x0E, - 0xD5, 0xDE, 0x82, 0x4C, 0xAB, 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x6F, 0xC2, 0x02, 0x00, 0x00, - 0x68, 0xC6, 0xDB, 0x77, 0x45, 0xE4, 0x15, 0xBC, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xA9, - 0xA0, 0x48, 0xB3, 0x20, 0x3E, 0x82, 0xA5, 0xBB, 0xFD, 0x88, 0xC4, 0x47, 0x5B, 0xB7, 0x1F, 0x3A, - 0x30, 0x92, 0x6C, 0xE2, 0x81, 0xE8, 0x2D, 0x88, 0x8D, 0x8F, 0xB6, 0x23, 0x44, 0x85, 0x44, 0x96, - 0x25, 0x8F, 0x8F, 0xB3, 0x83, 0x76, 0x4F, 0x5C, 0x60, 0xDE, 0xDD, 0xB1, 0xC4, 0x4C, 0xEC, 0x5E, - 0x5E, 0x3D, 0x7C, 0x4F, 0xC7, 0xF8, 0x70, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x2D, 0x98, 0x7D, - 0xF6, 0x70, 0xD7, 0xEB, 0xF1, 0x91, 0xE6, 0xF6, 0x23, 0x8C, 0x8F, 0x5C, 0x6E, 0x3F, 0x74, 0x58, - 0x24, 0x5D, 0xE5, 0x16, 0x64, 0xA6, 0x8D, 0x10, 0x1B, 0x20, 0x4F, 0xB5, 0x1B, 0x20, 0x2A, 0x24, - 0xB2, 0x2C, 0x43, 0x7C, 0x3C, 0x7E, 0x81, 0x39, 0x33, 0xF8, 0x41, 0x17, 0x20, 0xE6, 0xF4, 0x8E, - 0xA5, 0x03, 0xD3, 0x35, 0x3E, 0xFC, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x00, 0x34, 0x62, - 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x0B, 0x75, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, - 0x66, 0x91, 0xF8, 0x08, 0xA6, 0x6E, 0x3F, 0xAA, 0x01, 0x52, 0x73, 0xFB, 0x31, 0xAB, 0xFE, 0xF6, - 0xE3, 0x9B, 0x2A, 0x2E, 0x5A, 0x4D, 0x47, 0x45, 0x9A, 0xBD, 0xF3, 0xD7, 0x33, 0xCC, 0x99, 0x1F, - 0x4E, 0x06, 0x48, 0xF6, 0x5B, 0x10, 0x15, 0x12, 0x59, 0x96, 0x31, 0x3E, 0x1E, 0x9D, 0x61, 0x4E, - 0xFF, 0xD8, 0xEE, 0x99, 0x45, 0x66, 0xE2, 0xC0, 0xAA, 0x93, 0xD3, 0x36, 0x3E, 0xDC, 0x8E, 0xAC, - 0x32, 0xE6, 0xF8, 0x1D, 0x4B, 0x82, 0x2F, 0x31, 0x00, 0x00, 0x00, 0x44, 0x99, 0x91, 0xFE, 0x01, - 0xB3, 0xF3, 0x12, 0x1D, 0x18, 0xCD, 0x26, 0xA3, 0x22, 0xE9, 0x54, 0x50, 0xA4, 0x59, 0x2C, 0x3E, - 0x12, 0xDC, 0x7E, 0x4C, 0xB8, 0x00, 0x79, 0xDC, 0xDD, 0x7E, 0xC4, 0xE2, 0xC3, 0xED, 0x7B, 0x59, - 0xBE, 0xF5, 0x4A, 0x07, 0x45, 0x9A, 0xB9, 0xF8, 0xF0, 0x77, 0xF7, 0x0C, 0x7B, 0x90, 0x6F, 0xE7, - 0x16, 0x44, 0x85, 0x44, 0x96, 0xB5, 0x17, 0x1F, 0xA7, 0x1E, 0x76, 0x01, 0x32, 0xDB, 0x98, 0x63, - 0x77, 0x9A, 0x69, 0x1B, 0x1F, 0x3F, 0xBF, 0xCC, 0x98, 0x17, 0x3F, 0x67, 0xCC, 0x89, 0x2F, 0xAD, - 0x0D, 0xBE, 0xC4, 0x00, 0x00, 0x00, 0x10, 0xE5, 0x1D, 0x5A, 0x75, 0x97, 0xD9, 0x7E, 0xB1, 0x8E, - 0x8C, 0x46, 0x93, 0x51, 0x91, 0x74, 0x2A, 0x28, 0xD2, 0x2C, 0x16, 0x1F, 0x2A, 0x40, 0x1A, 0x3E, - 0xFB, 0x61, 0xE3, 0x23, 0x97, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0x56, 0x8D, 0x8F, 0x60, 0x67, 0xBE, - 0x5F, 0x09, 0x90, 0x73, 0xD1, 0x5B, 0x90, 0x20, 0x44, 0x74, 0x74, 0x84, 0x53, 0x21, 0x91, 0x65, - 0x39, 0xC4, 0xC7, 0xD3, 0x1F, 0x33, 0xDE, 0xD1, 0xDB, 0xA7, 0x77, 0x7C, 0xB8, 0x3D, 0xFF, 0x59, - 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x88, 0x19, 0x59, 0xB9, 0x5E, 0x46, 0x46, 0xA3, 0xC9, 0xA8, - 0x48, 0x3A, 0x15, 0x14, 0x69, 0x56, 0x1F, 0x1E, 0xD5, 0xF8, 0xB0, 0xE1, 0x31, 0x79, 0xFB, 0x11, - 0xF9, 0xD6, 0xAB, 0xEA, 0xED, 0xC7, 0x45, 0x95, 0xDB, 0x0F, 0xBB, 0xF6, 0x6E, 0x3F, 0x74, 0x50, - 0xA4, 0x59, 0x3C, 0x3E, 0xFC, 0x65, 0xBA, 0x05, 0x51, 0x21, 0x91, 0x65, 0xC4, 0x47, 0xFB, 0x0B, - 0xE2, 0x23, 0x98, 0xF7, 0x8B, 0x3B, 0x5B, 0x7E, 0x30, 0x23, 0x00, 0x00, 0xC0, 0xB4, 0xE4, 0x1D, - 0xB8, 0x7A, 0x54, 0x86, 0x86, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, 0x66, 0xB1, 0xF8, 0x88, - 0x07, 0x88, 0x5D, 0xF5, 0x5B, 0xAF, 0xC2, 0x00, 0xA9, 0x3E, 0x78, 0x6E, 0xE3, 0xC3, 0x06, 0x48, - 0xFB, 0xB7, 0x1F, 0x3A, 0x28, 0xD2, 0x4C, 0xC6, 0x47, 0xB0, 0xF0, 0x16, 0xC4, 0xBD, 0x92, 0xB7, - 0xF5, 0x2D, 0x88, 0x0A, 0x89, 0x2C, 0x23, 0x3E, 0xDA, 0x5F, 0x6D, 0x7C, 0xF8, 0x01, 0x72, 0xF4, - 0xD6, 0xB1, 0xE0, 0x4B, 0x0C, 0x00, 0x00, 0x00, 0x51, 0xDE, 0xFE, 0x2B, 0x4F, 0xCA, 0xD8, 0x88, - 0x4F, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x78, 0x88, 0xF8, 0x08, 0x6F, 0x3F, 0x6A, - 0x1E, 0x3C, 0xF7, 0x6F, 0x3F, 0x2E, 0x9A, 0xBC, 0xFD, 0x08, 0xE3, 0x23, 0x0C, 0x90, 0xFB, 0xD3, - 0xDC, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x1D, 0x35, 0x73, 0xB7, 0x20, 0x8F, 0x4D, 0xDE, 0x82, - 0xF8, 0x11, 0x62, 0x63, 0xA3, 0x3E, 0x40, 0x54, 0x48, 0x64, 0x19, 0xF1, 0xD1, 0xFE, 0xEA, 0xE3, - 0xC3, 0xDF, 0xB1, 0x2F, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x00, 0x25, 0xD1, 0x1B, 0xB0, 0x64, 0x54, - 0x24, 0x9D, 0x0A, 0x8A, 0x34, 0x8B, 0x85, 0x47, 0x93, 0xF8, 0xA8, 0x3E, 0x78, 0x5E, 0xBD, 0xFD, - 0xB0, 0xF1, 0x11, 0xDE, 0x7E, 0xC4, 0xE3, 0xE3, 0x21, 0xBB, 0xBB, 0x55, 0x68, 0xA8, 0xE9, 0xA0, - 0x48, 0x33, 0x19, 0x1C, 0x62, 0xA7, 0xBF, 0x3B, 0x23, 0x78, 0x16, 0xA4, 0xC1, 0xB7, 0x62, 0x3D, - 0xAD, 0x42, 0x22, 0xCB, 0x88, 0x8F, 0xF6, 0x27, 0xC2, 0x23, 0x1C, 0x6F, 0xC2, 0x02, 0x00, 0x00, - 0xA8, 0xE7, 0xBF, 0x01, 0x6B, 0xD7, 0x1C, 0x1D, 0x1D, 0xE1, 0x64, 0x54, 0x24, 0x9D, 0x0A, 0x8A, - 0x34, 0x8B, 0x85, 0x47, 0x38, 0x15, 0x20, 0xF1, 0xD7, 0xEE, 0x3E, 0x39, 0x19, 0x1F, 0xF2, 0xCD, - 0x57, 0x89, 0x6F, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0A, 0x8D, 0x66, 0x7B, 0x37, 0x7E, 0x0B, 0x12, - 0x46, 0x88, 0x8B, 0x8F, 0x70, 0x32, 0x2A, 0x92, 0x8E, 0xF8, 0x68, 0x7F, 0x22, 0x3A, 0xA2, 0x7B, - 0xF1, 0x7A, 0x63, 0x5E, 0xBE, 0xB3, 0xE6, 0x53, 0xE1, 0x01, 0x00, 0x00, 0xA6, 0x3D, 0x73, 0xA8, - 0x7F, 0xAD, 0xD9, 0xF1, 0x49, 0x1D, 0x1E, 0x6E, 0x32, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, 0xC5, - 0xA2, 0x23, 0xBA, 0x78, 0x7C, 0x44, 0x6F, 0x3F, 0x82, 0xF8, 0x98, 0xBC, 0xFD, 0x10, 0xDF, 0x7A, - 0x95, 0xF8, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xA9, 0xC0, 0x68, 0x35, 0x77, 0x0B, 0x52, 0xF7, 0xE1, - 0x84, 0x36, 0x3A, 0xF2, 0x09, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xE0, 0x88, 0xEF, 0x85, 0xAB, 0x79, - 0x13, 0x16, 0x00, 0x00, 0x40, 0x9C, 0xFF, 0x06, 0xAC, 0xAD, 0x1F, 0xEC, 0xB9, 0xF8, 0x68, 0x74, - 0xFB, 0xE1, 0xE2, 0xE3, 0x6C, 0x2C, 0x3E, 0xB2, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x17, - 0x49, 0xF7, 0xEE, 0x8F, 0x2B, 0x01, 0xE2, 0xBF, 0x96, 0xF7, 0x29, 0x1B, 0x1F, 0x6E, 0xD1, 0x08, - 0x91, 0x71, 0xD1, 0x6A, 0xC4, 0x47, 0xFB, 0x13, 0xB1, 0xD1, 0x60, 0xDE, 0x89, 0x2F, 0x0D, 0x06, - 0x5F, 0x6A, 0x00, 0x00, 0x00, 0x70, 0xBC, 0xE1, 0xE5, 0x43, 0x3D, 0x15, 0x1F, 0x6E, 0xF1, 0xF8, - 0x88, 0xDE, 0x7E, 0xB8, 0xF8, 0x68, 0x75, 0xFB, 0xF1, 0xA0, 0x9D, 0x0C, 0x8E, 0xE8, 0x74, 0x50, - 0xA4, 0x99, 0x8A, 0x8A, 0x34, 0x3B, 0xFD, 0xED, 0xE0, 0x16, 0xE4, 0x49, 0x1B, 0x20, 0x36, 0x0A, - 0xEA, 0x02, 0x24, 0x75, 0x84, 0x10, 0x1F, 0xED, 0x4F, 0x87, 0x46, 0xA3, 0x79, 0x47, 0x6F, 0x1D, - 0x0D, 0xBE, 0xD4, 0x00, 0x00, 0x00, 0xE0, 0x78, 0x7B, 0xAF, 0xA8, 0x7F, 0x05, 0xAF, 0x8C, 0x8A, - 0xA4, 0x53, 0x41, 0x91, 0x66, 0x22, 0x38, 0xA2, 0xB3, 0xD1, 0xE1, 0x7E, 0xAC, 0xBB, 0xFD, 0xB0, - 0xF1, 0x71, 0x6E, 0xE3, 0x45, 0xC9, 0x6E, 0x3F, 0xEE, 0x6B, 0x75, 0xFB, 0xA1, 0x83, 0x22, 0xCD, - 0x54, 0x50, 0x64, 0xD9, 0xBB, 0xF6, 0xD0, 0x1F, 0x06, 0x48, 0x7B, 0xB7, 0x20, 0xC4, 0x47, 0xFB, - 0xD3, 0x91, 0xD1, 0x74, 0xC7, 0x6E, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x51, 0x66, 0xEF, 0xE2, - 0xDE, 0x89, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x08, 0x03, 0x24, 0x88, 0x8F, 0x78, 0x80, 0xD4, - 0xC5, 0x47, 0xCB, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0xA6, 0x42, 0x22, 0xDB, 0x2E, 0x30, 0xA7, 0xBF, - 0x6D, 0xA3, 0x60, 0x70, 0x32, 0x42, 0x6A, 0x02, 0xC4, 0x85, 0x45, 0xA2, 0x08, 0x21, 0x3E, 0xDA, - 0x9F, 0x88, 0x8B, 0x24, 0x73, 0x6F, 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x1B, 0x00, 0x00, - 0xC0, 0xF4, 0x66, 0x46, 0xFA, 0x67, 0xD7, 0xBC, 0x82, 0x57, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, - 0x33, 0x11, 0x1B, 0xF1, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, 0xDF, 0x7E, 0xD8, 0xF0, 0x10, 0xB7, 0x1F, - 0xF2, 0x43, 0x07, 0x9B, 0xDE, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x76, 0x41, 0x75, - 0xE1, 0x2D, 0xC8, 0xB9, 0x4C, 0xB7, 0x20, 0xC4, 0x47, 0xFB, 0x13, 0x61, 0x91, 0x74, 0x63, 0xCB, - 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xC8, 0x7F, 0x05, 0x6F, 0xF8, 0x06, 0x2C, 0x19, 0x15, 0x49, - 0xA7, 0x82, 0x22, 0xCD, 0x62, 0xA1, 0xD1, 0x68, 0x61, 0x78, 0x84, 0xF1, 0xE1, 0xF6, 0xD4, 0x85, - 0x35, 0xDF, 0x7A, 0x15, 0x0F, 0x90, 0x53, 0x2E, 0x40, 0xC2, 0xDB, 0x8F, 0x1F, 0xD9, 0xC9, 0xF0, - 0x70, 0xD3, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x6C, 0x32, 0x3E, 0xDC, 0x4E, 0x7D, 0xD3, 0xC5, - 0x41, 0x96, 0x5B, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xA8, 0x48, 0xB3, 0x17, 0x3F, 0xC7, 0x9B, 0xB0, - 0x00, 0x00, 0x00, 0x42, 0xFE, 0x1B, 0xB0, 0xB6, 0x7D, 0xC4, 0x1E, 0xEE, 0x55, 0x54, 0x24, 0x9D, - 0x0A, 0x8A, 0x34, 0x13, 0xA1, 0xA1, 0x66, 0xA3, 0xC3, 0xFD, 0x58, 0x7B, 0xFB, 0x61, 0xE3, 0x23, - 0xCD, 0xED, 0xC7, 0xB7, 0x1A, 0xDD, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x56, 0x1B, - 0x1F, 0xE1, 0x26, 0x7E, 0x94, 0xF6, 0x16, 0x84, 0xF8, 0x68, 0x7F, 0x22, 0x28, 0x32, 0x8C, 0x37, - 0x61, 0x01, 0x00, 0x00, 0x04, 0xBC, 0x91, 0x81, 0x0D, 0x3A, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, - 0xC5, 0x22, 0xA3, 0xD9, 0xC2, 0xF0, 0x88, 0xC4, 0x47, 0xA2, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x68, - 0xD7, 0xA3, 0xF1, 0xE1, 0xD6, 0xF2, 0x16, 0x84, 0xF8, 0xC8, 0x79, 0x3A, 0x26, 0xB2, 0xCC, 0x3B, - 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0x38, 0xDE, 0x81, 0xAB, 0x47, 0x75, 0x58, 0x24, 0x99, - 0x0A, 0x8A, 0x34, 0x13, 0x91, 0xD1, 0x62, 0xD5, 0x00, 0x09, 0xE3, 0xA3, 0xED, 0xDB, 0x0F, 0x1D, - 0x14, 0x69, 0xA6, 0x43, 0x22, 0xCB, 0x74, 0x78, 0x44, 0x17, 0xDE, 0x82, 0xB8, 0x78, 0x68, 0x7C, - 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x12, 0x59, 0xE7, 0x1D, 0xBB, 0x65, 0x3C, 0xF8, 0x92, 0x03, - 0x00, 0x00, 0x98, 0xDE, 0xBC, 0x7D, 0x57, 0x8C, 0xEB, 0xB8, 0x68, 0x35, 0x15, 0x14, 0x69, 0xA6, - 0x03, 0xA3, 0xE1, 0x6A, 0x6E, 0x3F, 0x6C, 0x7C, 0x34, 0xBB, 0xFD, 0x08, 0xE3, 0xA3, 0xE5, 0xED, - 0x87, 0x0E, 0x8A, 0x34, 0xD3, 0x21, 0x91, 0x65, 0x3A, 0x38, 0xE2, 0xF3, 0x6F, 0x41, 0x1E, 0x6F, - 0x76, 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x11, 0x6D, 0xCD, 0xBD, 0x09, 0x6B, 0xEC, 0x8B, 0xB3, - 0x82, 0x2F, 0x3B, 0x00, 0x00, 0x80, 0xE9, 0xCB, 0x0C, 0x2D, 0xB0, 0x07, 0x7C, 0x15, 0x18, 0xCD, - 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x60, 0x24, 0x58, 0x18, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xB9, 0x1F, - 0xC9, 0x6E, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0E, 0x89, 0x2C, 0xD3, 0xB1, 0xD1, 0x68, 0x67, 0xBE, - 0x2F, 0x9E, 0x05, 0xF1, 0x43, 0x24, 0x12, 0x1E, 0x6E, 0xC4, 0x47, 0x86, 0x89, 0x78, 0xC8, 0x63, - 0x63, 0xCB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x80, 0xFF, 0x06, 0xAC, 0x9D, 0xB3, 0xED, 0xE1, 0x5E, - 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0x33, 0x1D, 0x17, 0x4D, 0x17, 0xB9, 0xF9, 0xF0, 0xE3, 0x43, - 0xDC, 0x7E, 0x4C, 0xB8, 0x3D, 0x1E, 0xB9, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xE5, 0x89, 0x0F, - 0x7F, 0x77, 0xAB, 0x5B, 0x90, 0x4A, 0x68, 0x18, 0x1B, 0x19, 0xC4, 0x47, 0xD6, 0x89, 0x70, 0xC8, - 0x65, 0x8B, 0x8D, 0x79, 0xF1, 0x5A, 0xE3, 0xFD, 0xE2, 0x4B, 0x77, 0x05, 0x5F, 0x7A, 0x00, 0x00, - 0x00, 0xD3, 0x93, 0x0D, 0x90, 0x75, 0x66, 0xC7, 0x27, 0xEC, 0x21, 0x5F, 0x85, 0x86, 0x9A, 0x0A, - 0x8A, 0x34, 0x13, 0x71, 0x91, 0x64, 0x61, 0x7C, 0xC4, 0x6E, 0x3F, 0x12, 0x3F, 0xFB, 0xF1, 0xCD, - 0x12, 0xC5, 0x47, 0xB0, 0x33, 0xDF, 0x8B, 0x3E, 0x0B, 0x52, 0x89, 0x8C, 0x70, 0x2E, 0x40, 0xC2, - 0xF0, 0x20, 0x3E, 0x92, 0x4E, 0x85, 0x43, 0x1E, 0xB3, 0xF1, 0xE1, 0x66, 0x7F, 0xED, 0xDE, 0x89, - 0x3B, 0x36, 0x04, 0x5F, 0x7A, 0x00, 0x00, 0x00, 0xD3, 0x93, 0xFF, 0x0A, 0x5E, 0x19, 0x1A, 0x6A, - 0x2A, 0x28, 0xD2, 0x4C, 0x84, 0x45, 0xAB, 0xD9, 0xF0, 0xA8, 0xC6, 0x87, 0x0D, 0x8F, 0xC9, 0xDB, - 0x8F, 0xD8, 0xB7, 0x5E, 0x45, 0x6F, 0x3F, 0xEC, 0x1A, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, - 0x12, 0x59, 0xA6, 0xC3, 0x22, 0xF1, 0xAA, 0xB7, 0x20, 0x36, 0x40, 0x36, 0xBA, 0xC0, 0x08, 0x82, - 0x23, 0x12, 0x1E, 0xC4, 0x47, 0xD2, 0xA9, 0x70, 0xC8, 0x63, 0x41, 0x7C, 0x04, 0xF3, 0x4E, 0xFC, - 0x39, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x9B, 0x77, 0xF0, 0xBA, 0x84, 0x6F, 0xC0, 0x52, 0x41, - 0x91, 0x66, 0xB1, 0xB0, 0x48, 0x3A, 0x17, 0x20, 0xE1, 0xCD, 0x87, 0x5D, 0xF5, 0x5B, 0xAF, 0xE4, - 0xB3, 0x1F, 0x17, 0xB5, 0xB8, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x04, 0x45, - 0x86, 0x9D, 0xFE, 0xCE, 0x7B, 0xFD, 0xB0, 0x08, 0x23, 0xA4, 0x1A, 0x1C, 0x2E, 0x3E, 0x82, 0x28, - 0x21, 0x3E, 0x5A, 0x4D, 0x85, 0x43, 0x1E, 0xAB, 0x8D, 0x0F, 0x3F, 0x40, 0x8E, 0x7D, 0x81, 0x37, - 0x61, 0x01, 0x00, 0x80, 0xE9, 0xCD, 0xDB, 0xFB, 0xD9, 0x31, 0x1D, 0x1C, 0xD1, 0xA9, 0xA0, 0x48, - 0xB3, 0x58, 0x54, 0x24, 0x5D, 0x2C, 0x3E, 0xC2, 0xDB, 0x8F, 0xBA, 0xF8, 0x88, 0xDE, 0x7E, 0x84, - 0xF1, 0x11, 0x06, 0xC8, 0x86, 0xF0, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xE9, 0x90, 0xC8, 0x32, 0x1D, - 0x13, 0xA9, 0xF7, 0x57, 0xEF, 0xF5, 0xF7, 0xEE, 0xA3, 0x93, 0x01, 0x12, 0x9F, 0x1F, 0x27, 0x2E, - 0x3C, 0x88, 0x8F, 0x06, 0x53, 0xE1, 0x90, 0xC7, 0xEA, 0xE3, 0xC3, 0xDF, 0x91, 0x1B, 0x4C, 0xF0, - 0xA5, 0x07, 0x00, 0x00, 0x30, 0x3D, 0x99, 0x3D, 0xF6, 0x50, 0x24, 0xA3, 0x23, 0x9C, 0x0A, 0x8A, - 0x34, 0x8B, 0x45, 0x45, 0xD2, 0x35, 0x88, 0x8F, 0xEA, 0x83, 0xE7, 0xEA, 0xF6, 0x23, 0x1E, 0x1F, - 0x0F, 0xD9, 0xDD, 0x5D, 0xEE, 0xF8, 0x70, 0x73, 0xB7, 0x20, 0x7E, 0x60, 0xD8, 0x9D, 0x7B, 0xD2, - 0x86, 0x87, 0xDD, 0xB9, 0x68, 0x7C, 0xD8, 0xF0, 0x38, 0x6B, 0xC3, 0x83, 0xF8, 0x88, 0x4F, 0x85, - 0x43, 0x1E, 0x8B, 0x45, 0x47, 0x74, 0x2F, 0xAD, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xFA, 0x32, - 0x87, 0xFB, 0x97, 0x98, 0xDD, 0xF3, 0xEC, 0x81, 0x5F, 0x85, 0x87, 0x9B, 0x0A, 0x8A, 0x34, 0x8B, - 0x45, 0x45, 0x9A, 0xD9, 0xE8, 0xA8, 0x0B, 0x90, 0x26, 0xDF, 0x7A, 0x25, 0xDF, 0x7C, 0x75, 0xBF, - 0xBB, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x45, 0xE2, 0x23, - 0x9C, 0xBB, 0x05, 0xF1, 0x43, 0x63, 0xD0, 0xC6, 0x88, 0x0D, 0x90, 0xB3, 0xB1, 0x6F, 0xB9, 0x7A, - 0xF7, 0x31, 0xE2, 0xA3, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x88, 0x8E, 0xE8, 0x5E, 0xBC, 0xD6, 0x06, - 0xC8, 0x1D, 0xEB, 0x82, 0x2F, 0x41, 0x00, 0x00, 0x80, 0xE9, 0xC5, 0x7F, 0x05, 0x6F, 0xC3, 0x37, - 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x15, 0x49, 0xF7, 0x8C, 0x88, 0x8F, 0xE8, 0xED, 0x87, 0x8B, - 0x8F, 0x9A, 0x00, 0x11, 0xDF, 0x7A, 0xE5, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, - 0x26, 0x42, 0x22, 0xCB, 0x44, 0x7C, 0xBC, 0xBD, 0xFE, 0xBD, 0xE6, 0xD4, 0x3D, 0x36, 0x42, 0x5C, - 0x68, 0xB8, 0xE0, 0x70, 0x21, 0x12, 0xFC, 0xE8, 0xFE, 0xB5, 0x09, 0x17, 0x1F, 0x36, 0x3C, 0x4E, - 0x3F, 0x42, 0x7C, 0x54, 0xA6, 0xC2, 0x21, 0x8F, 0x89, 0xE0, 0x88, 0xCF, 0xFD, 0xBE, 0x4E, 0xDC, - 0xB1, 0x3E, 0xF8, 0x12, 0x04, 0x00, 0x00, 0x98, 0x5E, 0xFC, 0x37, 0x60, 0x6D, 0xF9, 0x80, 0x3D, - 0xF4, 0x77, 0x5F, 0x7C, 0x34, 0xBA, 0xFD, 0x50, 0xAF, 0xDD, 0xD5, 0xB7, 0x1F, 0xED, 0x7F, 0xEB, - 0x95, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0x0D, 0xE2, 0x23, 0xDC, 0x99, 0x07, 0x6D, 0x6C, - 0x3C, 0x3E, 0xA3, 0x12, 0x22, 0x41, 0x78, 0x4C, 0x3C, 0x7A, 0x81, 0x7F, 0xEB, 0x41, 0x7C, 0x84, - 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x6C, 0x34, 0x98, 0x77, 0xE2, 0x0E, 0xDE, 0x84, 0x05, 0x00, 0x00, - 0xA6, 0x27, 0xEF, 0xD0, 0xCA, 0xC1, 0xAE, 0x8B, 0x8F, 0x5C, 0x6E, 0x3F, 0x2E, 0x6A, 0xFB, 0xF6, - 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0xD6, 0xD7, 0xEC, 0xBF, 0xF6, - 0x4D, 0x17, 0x1D, 0x33, 0xFC, 0x9D, 0xB1, 0xE1, 0xE1, 0xE6, 0x7F, 0xCB, 0x55, 0x18, 0x1F, 0x4F, - 0x11, 0x1F, 0xC5, 0x4C, 0x87, 0x46, 0xA3, 0x79, 0xC7, 0xBE, 0x70, 0x32, 0xF8, 0x12, 0x04, 0x00, - 0x00, 0x98, 0x5E, 0xBC, 0xBD, 0x57, 0xC4, 0x5E, 0xC1, 0xAB, 0x82, 0x22, 0xCD, 0x44, 0x54, 0x24, - 0x5D, 0x24, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0xA3, 0xFE, 0xD9, 0x0F, 0x75, 0xFB, 0x61, 0xE3, 0xE3, - 0xBE, 0xF6, 0x6E, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x4B, 0x10, 0x1F, 0x6F, 0x7D, - 0xED, 0x02, 0xF3, 0xD6, 0x7F, 0xB9, 0xC0, 0x9C, 0xFA, 0xA1, 0x0D, 0x0D, 0x77, 0xE3, 0xF1, 0x63, - 0x1B, 0x1F, 0x41, 0x78, 0xBC, 0xF3, 0x90, 0xFD, 0x91, 0xF8, 0x28, 0x68, 0x3A, 0x32, 0x9A, 0xEE, - 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x4C, 0x4F, 0x66, 0xAF, 0x3D, 0xF0, 0x75, 0x53, 0x7C, - 0x04, 0x01, 0xD2, 0xEC, 0xF6, 0x23, 0x1E, 0x20, 0x75, 0xF1, 0xF1, 0x60, 0x7B, 0x0F, 0x9E, 0xEB, - 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x96, 0x22, 0x3E, 0xDE, 0xFC, 0xCF, 0xF6, 0xC7, 0xBB, 0x6D, - 0x84, 0x04, 0xD1, 0xE1, 0xEF, 0x41, 0xE2, 0x43, 0x87, 0x43, 0x1E, 0x13, 0x71, 0x91, 0x64, 0x47, - 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xFD, 0x98, 0xD1, 0xFE, 0x59, 0x66, 0x68, 0x81, 0x0D, - 0x80, 0xEE, 0x8A, 0x0F, 0xF7, 0xA3, 0xBA, 0xFD, 0x50, 0xCF, 0x7E, 0xD4, 0x7E, 0xE8, 0xA0, 0x0D, - 0x8F, 0x87, 0xDB, 0xBB, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x2C, 0x65, 0x7C, 0xB8, - 0xFD, 0xE1, 0xFF, 0xB1, 0xFF, 0xFF, 0x77, 0x66, 0x98, 0xB7, 0x1F, 0x98, 0x69, 0x67, 0xE3, 0x63, - 0x23, 0xF1, 0x51, 0xCC, 0x44, 0x58, 0x24, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x2F, 0xAD, 0x0D, 0xBE, - 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0xFF, 0x0D, 0x58, 0x3B, 0x67, 0xDB, 0x08, 0x50, 0x41, 0x91, - 0x66, 0x22, 0x2A, 0x92, 0x2E, 0x1A, 0x1F, 0x41, 0x80, 0x34, 0xBB, 0xFD, 0x70, 0xF1, 0x11, 0x0F, - 0x90, 0x6A, 0x7C, 0xB4, 0x79, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, 0x64, 0x59, 0xC6, 0xF8, - 0x78, 0xE3, 0x2F, 0x67, 0x98, 0xF1, 0xFF, 0x3C, 0xC3, 0xBC, 0xF5, 0x23, 0xFB, 0x7B, 0x7A, 0x92, - 0xF8, 0x28, 0x66, 0x22, 0x2A, 0xD2, 0xEC, 0xF9, 0x2B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x7E, - 0xBC, 0x43, 0xAB, 0xEE, 0x32, 0xDB, 0x3E, 0x6A, 0x43, 0x40, 0x45, 0x45, 0xD2, 0x89, 0xA8, 0x48, - 0x3A, 0x11, 0x1F, 0xEE, 0xC7, 0xD4, 0xB7, 0x1F, 0x61, 0x7C, 0xB8, 0xDB, 0x8F, 0x7B, 0xB3, 0xDD, - 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x4E, 0x7C, 0xFC, 0xA7, 0x19, 0xE6, 0xF7, - 0xFF, 0xF7, 0x0C, 0xF3, 0xE6, 0x03, 0xC4, 0x47, 0x31, 0x13, 0x41, 0x91, 0x61, 0xDE, 0x2F, 0xEE, - 0x18, 0x0A, 0xBE, 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0x33, 0xD2, 0xBF, 0x5E, 0x47, 0x45, 0xD2, - 0x89, 0xA8, 0x48, 0xBA, 0x78, 0x7C, 0xB8, 0x85, 0xE1, 0x11, 0xC6, 0x47, 0xAB, 0xDB, 0x0F, 0xFF, - 0x5B, 0xAF, 0x82, 0xF8, 0x70, 0xFB, 0xA1, 0x9D, 0x88, 0x8B, 0x56, 0xD3, 0x21, 0x91, 0x65, 0x22, - 0x24, 0xB2, 0x2C, 0x87, 0xF8, 0x78, 0xE3, 0xDB, 0x36, 0x3E, 0x5E, 0x22, 0x3E, 0xF2, 0x9F, 0x8E, - 0x89, 0x2C, 0xF3, 0x8E, 0xDE, 0x3C, 0x16, 0x7C, 0x29, 0x02, 0x00, 0x00, 0x4C, 0x0F, 0xDE, 0x81, - 0xAB, 0x46, 0x75, 0x58, 0x24, 0x99, 0x88, 0x8A, 0xA4, 0x6B, 0x10, 0x1F, 0xEE, 0xC7, 0x54, 0xB7, - 0x1F, 0xD1, 0xF8, 0x70, 0xB7, 0x1F, 0xDF, 0x4A, 0x7F, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, - 0x64, 0x19, 0xF1, 0x91, 0xC3, 0x54, 0x38, 0xE4, 0x31, 0x1D, 0x12, 0x99, 0xC7, 0x9B, 0xB0, 0x00, - 0x00, 0xC0, 0x74, 0xE3, 0xED, 0xFF, 0xEC, 0x49, 0x1D, 0x17, 0xAD, 0x26, 0xA2, 0x22, 0xE9, 0xE2, - 0xE1, 0x11, 0x2E, 0x0C, 0x8F, 0x30, 0x3E, 0x9A, 0xDD, 0x7E, 0x3C, 0x76, 0x91, 0x39, 0xFD, 0xA8, - 0x0D, 0x8E, 0x36, 0x6F, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, - 0x0A, 0x87, 0x3C, 0x26, 0x02, 0xA2, 0xDD, 0xB9, 0x37, 0x61, 0x1D, 0xBF, 0x63, 0x49, 0xF0, 0xE5, - 0x08, 0x00, 0x00, 0x50, 0x7E, 0x66, 0x68, 0xBE, 0x8D, 0x02, 0x15, 0x18, 0xCD, 0x26, 0xA2, 0x22, - 0xE9, 0x54, 0x78, 0x44, 0x96, 0xE8, 0xF6, 0x23, 0x88, 0x8F, 0x76, 0x6F, 0x3F, 0x74, 0x48, 0x64, - 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0x26, 0xE2, 0x21, 0x8F, 0xBD, - 0x78, 0x1D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x87, 0xFF, 0x06, 0xAC, 0x5D, 0x9F, 0xB6, 0x61, - 0xA0, 0x22, 0xA3, 0xD1, 0x44, 0x54, 0x24, 0x9D, 0x08, 0x8E, 0xEA, 0x92, 0xDE, 0x7E, 0x3C, 0x6E, - 0x03, 0x24, 0x8C, 0x8F, 0x68, 0x80, 0xFC, 0x80, 0xF8, 0x20, 0x3E, 0x54, 0x38, 0xE4, 0x31, 0x11, - 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x3E, 0xCC, 0xA1, 0xFE, 0xB5, - 0x66, 0xC7, 0xC7, 0x6D, 0x1C, 0xA8, 0xD0, 0x50, 0x13, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0x62, 0x53, - 0xB7, 0x1F, 0xD1, 0x00, 0xF1, 0xE3, 0xA3, 0xD1, 0xED, 0xC7, 0x37, 0x75, 0x68, 0xA8, 0xE9, 0x90, - 0xC8, 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x44, 0x43, 0xCE, - 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xDA, 0xF0, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0x36, 0x10, 0x54, - 0x6C, 0xC4, 0x27, 0xA2, 0x22, 0xE9, 0x44, 0x6C, 0xD4, 0x2C, 0xC1, 0xED, 0x87, 0xFB, 0xD6, 0xAB, - 0x89, 0xC7, 0x2E, 0x9C, 0xBC, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xC9, 0x6F, 0x3F, 0x74, 0x48, - 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0xA6, 0x83, 0x21, 0xEF, - 0x79, 0x47, 0xFF, 0x64, 0x34, 0xF8, 0x92, 0x04, 0x00, 0x00, 0x28, 0x37, 0x6F, 0x78, 0xE9, 0x90, - 0x8E, 0x8D, 0xF8, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8E, 0xF8, 0xE2, 0x01, 0xA2, 0x9E, 0xFD, 0x78, - 0xDC, 0xC6, 0x47, 0x9B, 0xB7, 0x1F, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x11, 0x1F, 0x39, - 0x4C, 0x85, 0x43, 0x1E, 0xD3, 0xB1, 0x50, 0xC8, 0x8E, 0x7D, 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, - 0xE9, 0xC1, 0xDB, 0xBB, 0x24, 0xC1, 0x2B, 0x78, 0x45, 0x54, 0x24, 0x9D, 0x8A, 0x8D, 0xE8, 0x6C, - 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, 0x47, 0xEC, 0x5B, 0xAF, 0x9E, 0xB8, 0x70, 0xF2, - 0xF6, 0xC3, 0x2E, 0xCB, 0xED, 0x87, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, - 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x24, 0x14, 0xB6, 0x45, 0x95, 0x37, 0x61, 0xBD, 0x7C, 0xE7, 0xEC, - 0xE0, 0xCB, 0x12, 0x00, 0x00, 0xA0, 0xBC, 0xCC, 0x1E, 0x7B, 0xF8, 0x91, 0xD1, 0x11, 0x4E, 0x44, - 0x45, 0xD2, 0xA9, 0xE0, 0x88, 0x2F, 0x1A, 0x20, 0x76, 0xD5, 0x6F, 0xBD, 0x8A, 0x06, 0x88, 0x8B, - 0x0F, 0xFF, 0xF6, 0xE3, 0xC2, 0xFA, 0xDB, 0x8F, 0x87, 0xEC, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, - 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xB3, - 0x5F, 0x7F, 0x6E, 0x2F, 0x7E, 0xCE, 0x05, 0xC8, 0x40, 0xF0, 0x65, 0x09, 0x00, 0x00, 0x50, 0x4E, - 0x66, 0xA4, 0x7F, 0x76, 0xF3, 0x57, 0xF0, 0x8A, 0xA8, 0x48, 0x3A, 0x15, 0x1B, 0xF1, 0xC5, 0xE2, - 0x23, 0xBC, 0xFD, 0xA8, 0x7D, 0xF0, 0xDC, 0xC6, 0x47, 0xF4, 0xF6, 0x23, 0xFE, 0xAD, 0x57, 0xF7, - 0xB7, 0xBE, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, - 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x16, 0xC4, 0x87, 0x1F, 0x20, 0xD7, 0xF0, 0x26, 0x2C, 0x00, 0x00, - 0x50, 0x7E, 0xFE, 0x2B, 0x78, 0x1B, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, 0xA9, 0xD8, 0x88, 0xAF, - 0x41, 0x7C, 0x54, 0x1F, 0x3C, 0x77, 0xB3, 0xF1, 0x51, 0x73, 0xFB, 0x11, 0x7F, 0xF0, 0xDC, 0xDD, - 0x7E, 0xDC, 0xAD, 0xA3, 0x23, 0x9C, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, - 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0xB5, 0x48, 0x7C, 0x04, 0xF3, 0x4E, 0x7C, 0x69, 0x30, - 0xF8, 0xD2, 0x04, 0x00, 0x00, 0x28, 0x27, 0xFF, 0x0D, 0x58, 0x5B, 0x3F, 0x64, 0xA3, 0x61, 0x8A, - 0xE3, 0xC3, 0x4D, 0x05, 0x48, 0xCD, 0xB7, 0x5E, 0xD9, 0xF8, 0x70, 0xB7, 0x1F, 0x41, 0x7C, 0x64, - 0xB9, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x56, 0x1F, 0x1F, 0x6E, 0xDE, 0xF1, 0x3F, 0xE5, 0x4D, 0x58, 0x00, 0x00, - 0xA0, 0xDC, 0xBC, 0x91, 0x81, 0x0D, 0x1D, 0x89, 0x0F, 0xB7, 0x78, 0x7C, 0x54, 0x6F, 0x3F, 0x2E, - 0xAC, 0xC6, 0xC7, 0xE4, 0xED, 0x47, 0x2C, 0x3E, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, - 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xF1, 0xE1, - 0xEF, 0xD8, 0x2D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x94, 0x9B, 0x77, 0xE0, 0xAA, 0xD8, 0x1B, 0xB0, - 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x8C, 0x46, 0xB3, 0xD1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0x44, 0x02, - 0x24, 0x8C, 0x0F, 0xF9, 0xB9, 0x1F, 0xDF, 0x69, 0x7C, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, - 0x64, 0x59, 0x34, 0x3A, 0x88, 0x8F, 0x8C, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x11, - 0x1D, 0xD1, 0xB9, 0x37, 0x61, 0x8D, 0x7D, 0x71, 0x56, 0xF0, 0xE5, 0x09, 0x00, 0x00, 0x50, 0x3E, - 0xDE, 0xBE, 0x25, 0xE3, 0x53, 0x1E, 0x1F, 0x6E, 0xF1, 0xF8, 0x48, 0x7B, 0xFB, 0xF1, 0xA0, 0x9D, - 0x08, 0x0F, 0x37, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x52, 0xC4, 0x47, 0x18, 0x20, 0x2E, - 0x3E, 0xFE, 0x40, 0x7C, 0x44, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x38, 0xE2, - 0x1B, 0x5B, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB9, 0x4D, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, - 0xA9, 0xC0, 0x68, 0x36, 0x1B, 0x1D, 0xEE, 0x47, 0x75, 0xFB, 0x11, 0x0D, 0x90, 0xA6, 0xB7, 0x1F, - 0xF7, 0xE9, 0xDB, 0x0F, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x22, 0xF1, 0x11, 0xAE, 0x3E, - 0x3E, 0xEC, 0x5C, 0x78, 0x84, 0xB7, 0x1F, 0xC4, 0x47, 0x6C, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, - 0xA2, 0x26, 0x62, 0x43, 0xED, 0xC5, 0x6B, 0x8C, 0xF7, 0x8B, 0x2F, 0xDD, 0x15, 0x7C, 0x79, 0x02, - 0x00, 0x00, 0x94, 0x8B, 0xFF, 0x06, 0xAC, 0x9D, 0x9F, 0xD2, 0x51, 0x91, 0x74, 0xF1, 0xB8, 0x48, - 0xB2, 0x30, 0x3C, 0xC2, 0xF8, 0xF0, 0x03, 0x64, 0x66, 0x35, 0x3E, 0x6A, 0xDF, 0x7C, 0x95, 0xFC, - 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0x76, 0x24, 0x3E, 0xE2, - 0x37, 0x1F, 0x6F, 0x04, 0xF1, 0xF1, 0x07, 0xE2, 0xA3, 0xA0, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x34, - 0x9A, 0xCC, 0x3B, 0x71, 0xC7, 0x86, 0xE0, 0x4B, 0x14, 0x00, 0x00, 0xA0, 0x5C, 0x6C, 0x80, 0xAC, - 0x33, 0xDB, 0x2F, 0xD6, 0x61, 0x91, 0x64, 0x2A, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0xF6, - 0xF6, 0xC3, 0xC6, 0x47, 0x83, 0x67, 0x3F, 0xEA, 0x3E, 0x74, 0xD0, 0xBD, 0xF9, 0x4A, 0xDC, 0x7E, - 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x22, 0x3E, 0xA2, 0x37, 0x1F, 0x61, 0x7C, 0x84, - 0x37, 0x1F, 0xC4, 0x47, 0x38, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x91, 0xD1, 0x6C, - 0xDE, 0x89, 0x3F, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x9C, 0xFC, 0x57, 0xF0, 0xAA, 0xB0, 0x48, - 0xB2, 0x78, 0x58, 0x24, 0x5D, 0x18, 0x1E, 0x61, 0x7C, 0x3C, 0x3D, 0xB3, 0xE6, 0xF6, 0xA3, 0xEE, - 0xD9, 0x0F, 0x1B, 0x20, 0xA7, 0xA2, 0x01, 0xF2, 0x23, 0xBB, 0x1E, 0x8C, 0x0F, 0xB7, 0xBA, 0x00, - 0x69, 0x10, 0x1F, 0xE3, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0xC0, - 0x68, 0x35, 0xEF, 0xD8, 0x17, 0xC6, 0x83, 0x2F, 0x51, 0x00, 0x00, 0x80, 0x72, 0xF1, 0x0E, 0x5C, - 0x33, 0x2A, 0xE3, 0xA2, 0xD5, 0x54, 0x58, 0x24, 0x99, 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, - 0xF1, 0x11, 0xBD, 0xFD, 0x88, 0xC5, 0x47, 0xDD, 0xED, 0xC7, 0xB7, 0x6A, 0x6F, 0x3F, 0x74, 0x48, - 0x64, 0x99, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x56, 0x17, 0x1F, 0xEA, 0x8D, 0x57, 0xC4, 0x47, - 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x71, 0x91, 0x68, 0x47, 0x56, 0xF3, 0x26, - 0x2C, 0x00, 0x00, 0x50, 0x4E, 0xDE, 0xDE, 0x25, 0x63, 0x32, 0x30, 0x9A, 0x2D, 0x1E, 0x15, 0x69, - 0x16, 0x86, 0x47, 0x18, 0x1F, 0x69, 0x6F, 0x3F, 0x7E, 0x68, 0x57, 0xB6, 0xF8, 0x70, 0x37, 0x1F, - 0x2E, 0x3E, 0xDC, 0x43, 0xE7, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, - 0xA8, 0x48, 0xB3, 0x97, 0x56, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x4E, 0x66, 0xCF, 0x42, 0x1D, - 0x19, 0x8D, 0xA6, 0xA2, 0x22, 0xE5, 0x2A, 0x01, 0x32, 0xB3, 0xED, 0xDB, 0x0F, 0x1D, 0x12, 0x59, - 0x26, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0xB5, 0x8C, 0x8F, 0xBF, 0x9C, 0xFC, 0xAC, 0x8F, 0x3F, - 0xDC, 0x4B, 0x7C, 0x14, 0x33, 0x15, 0x09, 0x45, 0x4D, 0x04, 0x45, 0xDA, 0xBD, 0x78, 0x8D, 0x0D, - 0x90, 0x3B, 0xD6, 0x05, 0x5F, 0xA6, 0x00, 0x00, 0x00, 0xE5, 0x60, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, - 0xE6, 0xE8, 0xD0, 0x50, 0x13, 0x31, 0x91, 0x6A, 0xD5, 0xDB, 0x8F, 0x20, 0x3E, 0x9A, 0xDD, 0x7E, - 0x84, 0xF1, 0xD1, 0xE0, 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, - 0x0D, 0xE3, 0x23, 0x08, 0x90, 0xE8, 0x07, 0x0D, 0x12, 0x1F, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, - 0xA2, 0x26, 0x62, 0x22, 0xCB, 0x9E, 0xB7, 0x7F, 0x3F, 0x4E, 0xDC, 0xB1, 0x3E, 0xF8, 0x52, 0x05, - 0x00, 0x00, 0x28, 0x07, 0xFF, 0x15, 0xBC, 0x49, 0xDF, 0x80, 0xA5, 0x82, 0x22, 0xC3, 0xFC, 0xF8, - 0x88, 0xDD, 0x7E, 0x54, 0x03, 0xA4, 0xD5, 0xED, 0xC7, 0x3D, 0xBD, 0x1B, 0x1F, 0x95, 0xD7, 0xED, - 0x12, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x24, 0xDA, 0x18, 0x6F, - 0xC2, 0x02, 0x00, 0x00, 0xA5, 0xE3, 0xBF, 0x01, 0x6B, 0xEB, 0x07, 0x75, 0x70, 0x44, 0x27, 0x42, - 0x22, 0xF5, 0xC2, 0x9B, 0x8F, 0x26, 0xB7, 0x1F, 0x13, 0x2E, 0x40, 0x1E, 0x8B, 0xDC, 0x7E, 0x84, - 0xF1, 0xE1, 0xF6, 0xBD, 0xCA, 0xB7, 0x5E, 0xE9, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x26, 0xC2, - 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x11, 0xD1, 0xCE, - 0xBC, 0x63, 0x5F, 0x38, 0x19, 0x7C, 0xA9, 0x02, 0x00, 0x00, 0x94, 0x83, 0x37, 0xBC, 0x62, 0x50, - 0x06, 0x47, 0x74, 0x2A, 0x26, 0xB2, 0x2C, 0x8C, 0x8F, 0xD8, 0xED, 0x47, 0xE2, 0x67, 0x3F, 0xBE, - 0xC9, 0xB7, 0x5D, 0x25, 0x9B, 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, - 0x2A, 0x12, 0x8A, 0x9A, 0x0E, 0x88, 0xB6, 0x77, 0x64, 0xB5, 0x09, 0xBE, 0x54, 0x01, 0x00, 0x00, - 0xCA, 0xC1, 0xDB, 0x7B, 0x79, 0xF3, 0x57, 0xF0, 0xAA, 0x90, 0x48, 0xBB, 0x4D, 0x6E, 0x93, 0xE1, - 0x31, 0x79, 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xFC, 0xF6, 0x43, 0x87, 0x44, - 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0x0D, 0xE3, 0xC3, 0x3D, 0x70, 0x1E, 0x8B, 0x8F, - 0xF1, 0xFF, 0x32, 0xCB, 0x9C, 0xFF, 0xD7, 0x5B, 0x83, 0xF8, 0x58, 0x65, 0x0F, 0xFA, 0x2A, 0x28, - 0xD2, 0x4C, 0x84, 0x43, 0x1E, 0x93, 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, - 0x4D, 0x84, 0x43, 0x5E, 0x3B, 0xB2, 0x92, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF1, 0xF6, 0x2C, - 0x1A, 0x97, 0xE1, 0xE1, 0xA6, 0x62, 0x22, 0xCB, 0x6C, 0x78, 0x44, 0x6F, 0x3F, 0xAA, 0xDF, 0x7A, - 0x15, 0x06, 0x48, 0xCD, 0x6B, 0x77, 0x2F, 0x94, 0xB7, 0x1F, 0xEF, 0x7C, 0x23, 0xAF, 0xDB, 0x0F, - 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x2D, 0x6D, 0x7C, 0x9C, 0xFB, 0xE9, 0x17, 0x2A, 0xF1, 0x71, - 0xD4, 0xFE, 0x28, 0x83, 0x22, 0xCD, 0x44, 0x38, 0xE4, 0x31, 0x19, 0x0E, 0x79, 0x4C, 0x85, 0x43, - 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x44, 0x34, 0xE4, 0x39, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xCA, 0xC4, - 0x0C, 0xF5, 0xCF, 0x32, 0x43, 0x7D, 0x53, 0x1A, 0x1F, 0xE1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xCD, - 0x9E, 0xFD, 0x70, 0xF1, 0x71, 0x7F, 0x5E, 0xB7, 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, - 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x82, 0x21, 0xEF, 0xB9, 0xFF, - 0x6D, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0x0B, 0xFF, 0x0D, 0x58, 0x3B, 0x3E, 0x39, 0xE5, 0xF1, - 0x51, 0x7D, 0xF0, 0x5C, 0xDD, 0x7E, 0xC4, 0x1E, 0x3C, 0x7F, 0xE7, 0x41, 0x1B, 0x1F, 0x5F, 0x57, - 0x31, 0x91, 0x76, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x62, 0xA1, 0xA0, 0x79, 0x27, 0xEE, 0xE0, 0x4D, 0x58, 0x00, 0x00, - 0xA0, 0x1C, 0xBC, 0xE1, 0xFE, 0xBB, 0xCC, 0xB6, 0x8F, 0x14, 0x13, 0x1F, 0xCF, 0x54, 0xE2, 0xA3, - 0x2E, 0x40, 0xE2, 0xAF, 0xDD, 0x75, 0xB7, 0x1F, 0x41, 0x7C, 0xC4, 0x6F, 0x3F, 0xDE, 0x79, 0xD8, - 0xC6, 0xC7, 0x77, 0xF3, 0xF8, 0xD6, 0x2B, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, - 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xA1, 0x50, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, - 0x82, 0x2F, 0x59, 0x00, 0x00, 0x80, 0xDE, 0xE6, 0xBF, 0x82, 0xB7, 0xA8, 0xF8, 0x08, 0x02, 0xA4, - 0xE1, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0x8A, 0xC7, 0x47, 0x2E, 0xB7, 0x1F, 0x22, 0x24, - 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0xA6, - 0x23, 0xA1, 0xD0, 0x1D, 0xB9, 0x91, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF0, 0x0E, 0x5C, 0x33, - 0xF9, 0x06, 0x2C, 0x19, 0x12, 0x59, 0x36, 0x19, 0x1F, 0x8D, 0x6E, 0x3F, 0xAA, 0xAF, 0xDD, 0xAD, - 0xDE, 0x7E, 0x5C, 0x14, 0xBB, 0xFD, 0xB0, 0xE1, 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, - 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x38, 0x98, - 0x8A, 0xBD, 0x34, 0x60, 0xCC, 0xF1, 0x3B, 0x96, 0x04, 0x5F, 0xB6, 0x00, 0x00, 0x00, 0xBD, 0xCB, - 0xDB, 0x77, 0xC5, 0xC9, 0x42, 0xE2, 0xA3, 0xAD, 0xDB, 0x8F, 0x20, 0x3E, 0x1E, 0x68, 0xF7, 0xF6, - 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, - 0x50, 0xD4, 0x44, 0x18, 0x4C, 0xD5, 0xDC, 0x9B, 0xB0, 0x4E, 0x7C, 0x69, 0x6D, 0xF0, 0x65, 0x0B, - 0x00, 0x00, 0xD0, 0xBB, 0xCC, 0xEE, 0xBE, 0x48, 0x3C, 0xB4, 0xBB, 0xDA, 0xF8, 0x70, 0x3F, 0xAA, - 0xDB, 0x8F, 0xFA, 0x67, 0x3F, 0xA2, 0xB7, 0x1F, 0x41, 0x7C, 0xB8, 0xDD, 0xDB, 0xCE, 0xED, 0x87, - 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, - 0xA8, 0x89, 0x28, 0x98, 0xCA, 0xBD, 0x70, 0x25, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xCF, 0x1C, - 0xE8, 0x5F, 0x62, 0x76, 0xCE, 0x0E, 0xE2, 0xA1, 0xDD, 0x45, 0xE2, 0x23, 0x08, 0x90, 0x66, 0xB7, - 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xE1, 0x6E, 0x3F, 0x64, 0x58, 0x24, 0x99, 0x08, 0x89, 0x2C, - 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x20, - 0xE8, 0xC0, 0xBC, 0xE3, 0xB7, 0x0F, 0x05, 0x5F, 0xBA, 0x00, 0x00, 0x00, 0xBD, 0xC9, 0x1C, 0x5C, - 0xB6, 0xD6, 0x6C, 0xFF, 0x58, 0x10, 0x10, 0xED, 0xAC, 0x3E, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0x43, - 0x3D, 0xFB, 0x51, 0xF9, 0xD0, 0xC1, 0x0B, 0x27, 0x03, 0xE4, 0x21, 0xBB, 0xCC, 0xB7, 0x1F, 0x22, - 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, - 0xA6, 0x63, 0xA0, 0x13, 0xF3, 0x8E, 0xDE, 0xC2, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x33, 0x23, - 0xCB, 0xD7, 0x9B, 0xCD, 0xEF, 0xB3, 0xB1, 0xA0, 0xA2, 0x22, 0xE9, 0x62, 0xF1, 0xE1, 0x16, 0x86, - 0x47, 0x18, 0x1F, 0xB1, 0xDB, 0x8F, 0xBA, 0x67, 0x3F, 0x1E, 0xB5, 0xF1, 0xE1, 0x02, 0xA4, 0xED, - 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, - 0x45, 0x42, 0x51, 0xD3, 0x21, 0xD0, 0xB1, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, - 0xE6, 0x1D, 0xB8, 0x7E, 0xA8, 0x36, 0x26, 0xD2, 0x4E, 0xC7, 0x87, 0xFB, 0xB1, 0xE9, 0xED, 0x47, - 0x2C, 0x3E, 0xEA, 0x6E, 0x3F, 0xEE, 0xC9, 0x72, 0xFB, 0x21, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, - 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x00, 0x3A, 0x3D, 0xF7, - 0x26, 0xAC, 0x97, 0xEF, 0x9C, 0x1D, 0x7C, 0xF9, 0x02, 0x00, 0x00, 0xF4, 0x1E, 0x6F, 0xEF, 0x65, - 0xA3, 0xF5, 0x51, 0x91, 0x74, 0xB1, 0xF0, 0x08, 0x17, 0x86, 0x47, 0x18, 0x1F, 0x4D, 0x6F, 0x3F, - 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x4E, 0x06, 0x46, 0xB3, 0x89, 0x90, 0xC8, - 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, - 0xFC, 0x77, 0xC3, 0x5E, 0xFC, 0x9C, 0x31, 0xC7, 0x6E, 0x1B, 0x08, 0xBE, 0x7C, 0x01, 0x00, 0x00, - 0x7A, 0x8F, 0xD9, 0x63, 0x0F, 0x5B, 0x32, 0x2E, 0x5A, 0x4D, 0x84, 0x47, 0x64, 0xC9, 0x6E, 0x3F, - 0x2A, 0xF1, 0xD1, 0xFE, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, - 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xFE, 0xDD, 0x32, 0xDE, 0x84, 0x05, 0x00, - 0x00, 0x7A, 0x99, 0x19, 0xE9, 0x9F, 0x6D, 0x76, 0xCF, 0xB3, 0xC1, 0xA0, 0x02, 0xA3, 0xD9, 0x74, - 0x74, 0xF8, 0x4B, 0x7C, 0xFB, 0x31, 0xD3, 0x9C, 0x09, 0xE3, 0xA3, 0xAD, 0xDB, 0x0F, 0x11, 0x12, - 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xFE, 0x2E, 0x9B, 0x77, 0xE2, 0xF6, 0xC1, 0xE0, 0x4B, 0x18, 0x00, 0x00, 0xA0, 0xB7, 0xD8, - 0x00, 0x19, 0x48, 0xFF, 0x06, 0x2C, 0x11, 0x1D, 0xB1, 0xA9, 0xDB, 0x8F, 0x6A, 0x80, 0x84, 0xF1, - 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, - 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7F, 0xB7, 0xCD, 0x3B, 0xFA, 0x85, 0xD1, 0xE0, 0x4B, - 0x18, 0x00, 0x00, 0xA0, 0xB7, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0x3E, 0x60, 0xA3, 0x41, 0x85, - 0x86, 0x9A, 0x0E, 0x8E, 0xEA, 0x12, 0xDC, 0x7E, 0x4C, 0x3C, 0x31, 0xD3, 0x4C, 0x3C, 0x16, 0xB9, - 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0xFB, 0xC4, 0x47, 0x65, 0x22, 0x1C, 0xF2, 0x98, 0x0C, 0x87, 0x3C, - 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0xB0, 0xDF, 0x95, 0x3B, 0x76, 0x0B, 0x6F, - 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xC9, 0x1B, 0x59, 0xB1, 0xA1, 0x3E, 0x32, 0x1A, 0x4D, 0x04, 0x47, - 0x7C, 0xF1, 0x00, 0xA9, 0x7B, 0xF6, 0xC3, 0xC6, 0x47, 0xB3, 0xDB, 0x8F, 0x6F, 0xA8, 0xD0, 0x50, - 0x13, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, - 0x14, 0x35, 0x71, 0xC8, 0xEF, 0xE6, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xAB, 0xBC, 0x7D, 0x57, - 0x24, 0x7C, 0x03, 0x96, 0x88, 0x8D, 0xE8, 0x6C, 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, - 0x47, 0xE4, 0x5B, 0xAF, 0x06, 0x6D, 0x7C, 0x44, 0x6F, 0x3F, 0xEC, 0x6A, 0x6E, 0x3F, 0x36, 0x24, - 0xBD, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, - 0x54, 0x24, 0x14, 0x35, 0x71, 0xC0, 0xEF, 0xF6, 0x8D, 0x2D, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0xA0, - 0x37, 0x79, 0x7B, 0x2F, 0x1B, 0xAF, 0x8F, 0x8D, 0xF8, 0x62, 0xB1, 0xA1, 0x16, 0x0D, 0x10, 0xBB, - 0xEA, 0xB7, 0x5E, 0x85, 0x01, 0x62, 0xE3, 0x63, 0xF2, 0xF6, 0x63, 0x66, 0x1B, 0xB7, 0x1F, 0x22, - 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, - 0x26, 0x0E, 0xF7, 0xBD, 0xB0, 0x17, 0xAF, 0x31, 0xDE, 0x2F, 0x6E, 0xBF, 0x2B, 0xF8, 0x32, 0x06, - 0x00, 0x00, 0xE8, 0x1D, 0xAD, 0xDF, 0x80, 0x15, 0x0B, 0x0D, 0xB5, 0x58, 0x7C, 0x84, 0xB7, 0x1F, - 0x93, 0x0F, 0x9E, 0xDB, 0xF8, 0x88, 0xDF, 0x7E, 0x84, 0xF1, 0x11, 0x06, 0x48, 0xA2, 0xDB, 0x0F, - 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, - 0x51, 0x13, 0x07, 0xFB, 0x1E, 0x9A, 0x77, 0xFC, 0x8E, 0x0D, 0xC1, 0x97, 0x31, 0x00, 0x00, 0x40, - 0x6F, 0xF0, 0xDF, 0x80, 0xB5, 0x73, 0xB6, 0x8D, 0x08, 0x15, 0x1E, 0x6E, 0xB1, 0xD0, 0x50, 0x6B, - 0x10, 0x1F, 0xD5, 0x07, 0xCF, 0x37, 0xCE, 0xAC, 0xBF, 0xFD, 0x08, 0xE2, 0xA3, 0x7A, 0xFB, 0xF1, - 0xA0, 0xDD, 0xD7, 0x55, 0x70, 0x44, 0x27, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, - 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0x50, 0xDF, 0x4B, 0xF3, 0x8E, 0xDE, 0xCA, - 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x31, 0x23, 0xCB, 0xD7, 0x35, 0x7E, 0x05, 0x6F, 0x2C, 0x34, - 0x1A, 0x4D, 0x05, 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x41, 0x7C, 0xC8, 0x37, - 0x5F, 0x7D, 0xB7, 0xD5, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, - 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7D, 0xAF, 0xCD, 0x3B, 0xFA, 0xF9, 0xF1, - 0xE0, 0x4B, 0x19, 0x00, 0x00, 0xA0, 0x37, 0xD8, 0x00, 0x59, 0x5F, 0x1F, 0x1E, 0x29, 0xE2, 0xC3, - 0x2D, 0x1E, 0x1F, 0xD5, 0xDB, 0x8F, 0xC9, 0xF8, 0xA8, 0x79, 0xF3, 0x55, 0xEA, 0xDB, 0x0F, 0x11, - 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, - 0xD3, 0x87, 0xF9, 0x9E, 0x9C, 0x7B, 0x13, 0xD6, 0xD8, 0x17, 0x67, 0x05, 0x5F, 0xCE, 0x00, 0x00, - 0x00, 0xDD, 0xCF, 0x3B, 0x70, 0xD5, 0x50, 0xBB, 0xF1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0xD4, 0xDD, - 0x7E, 0x5C, 0x98, 0xE1, 0xF6, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, - 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBE, 0x97, 0x37, 0xB6, 0x9C, 0x37, 0x61, - 0x01, 0x00, 0x80, 0xDE, 0xE2, 0xED, 0xBD, 0x7C, 0x2C, 0x73, 0x7C, 0xB8, 0xC5, 0xE3, 0xC3, 0x0F, - 0x90, 0x19, 0x39, 0xDD, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, - 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xC0, 0xF7, 0xFA, 0x78, 0x13, 0x16, 0x00, 0x00, - 0xE8, 0x35, 0x66, 0x68, 0x81, 0x0D, 0x89, 0xEC, 0xF1, 0xE1, 0x7E, 0xAC, 0xBD, 0xFD, 0xB0, 0xF1, - 0x11, 0xFB, 0xF6, 0xAB, 0xA6, 0xB7, 0x1F, 0xF7, 0x35, 0xBA, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, - 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x78, 0x2F, - 0xC3, 0x9E, 0xBF, 0x9C, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, 0x61, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, - 0x2E, 0xB5, 0x11, 0x91, 0x21, 0x3E, 0xDC, 0xC2, 0xF0, 0x08, 0xE3, 0xE3, 0xE9, 0x19, 0x35, 0xB7, - 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xF1, 0x80, 0x1D, 0xF1, 0x91, 0xCF, 0x64, 0x38, 0xE4, 0x31, - 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x07, 0xF7, 0x12, 0xCD, 0x3B, 0xFE, 0x67, 0xBC, - 0x09, 0x0B, 0x00, 0x00, 0xF4, 0x06, 0xFF, 0x15, 0xBC, 0xFE, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, - 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, 0xF1, 0xD1, 0xE0, 0xD9, 0x0F, 0xF9, 0xA1, 0x83, 0xF7, - 0xAA, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, - 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x87, 0xF6, 0x32, 0xCD, 0x3B, 0xFA, 0xF9, 0x93, 0xC1, 0x97, 0x34, - 0x00, 0x00, 0x40, 0x77, 0xF3, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0xF5, 0x71, 0x91, 0x64, 0x61, 0x78, - 0x84, 0xF1, 0x11, 0xBB, 0xFD, 0xA8, 0x7B, 0xF6, 0xC3, 0x06, 0xC8, 0x29, 0x17, 0x20, 0x4D, 0x6F, - 0x3F, 0x44, 0x48, 0x64, 0x99, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, - 0x09, 0x45, 0x4D, 0x1F, 0xD8, 0x4B, 0xB7, 0x23, 0xAB, 0x4C, 0xF0, 0x25, 0x0D, 0x00, 0x00, 0xD0, - 0xDD, 0xBC, 0xE1, 0x65, 0x83, 0x32, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0x12, 0x20, 0x33, - 0xF4, 0xED, 0x47, 0x2C, 0x3E, 0x5A, 0xDF, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, - 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA8, 0x97, 0x75, 0x63, 0xCB, - 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0D, 0xDE, 0xDE, 0xCB, 0x46, 0xEB, 0xE2, 0x22, 0xC9, 0xAA, - 0xB7, 0x1F, 0x41, 0x7C, 0x24, 0xBD, 0xFD, 0x08, 0x03, 0xE4, 0x07, 0x76, 0xC4, 0x47, 0x7B, 0x93, - 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0xBA, 0x7F, - 0x5D, 0x68, 0xCC, 0x0B, 0x57, 0x1B, 0x73, 0xFC, 0x8E, 0x75, 0xC1, 0x97, 0x35, 0x00, 0x00, 0x40, - 0xF7, 0xF2, 0xF6, 0x2C, 0x18, 0x97, 0x81, 0xD1, 0x6C, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0x59, 0x6F, - 0x3F, 0xEE, 0x89, 0xDE, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, - 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2E, 0x3E, 0xDC, 0x7E, 0x6E, - 0xFF, 0x99, 0x38, 0x71, 0xDB, 0xFA, 0xE0, 0xCB, 0x1A, 0x00, 0x00, 0xA0, 0x3B, 0x99, 0xA1, 0xFE, - 0x59, 0x66, 0xF7, 0xDC, 0xFA, 0xC0, 0x68, 0xB5, 0xF0, 0xE6, 0x23, 0x97, 0xDB, 0x0F, 0x11, 0x12, - 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xF4, 0xB2, 0x2E, 0x8C, 0x8F, 0x60, 0xDE, 0x89, 0xDB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, - 0x6E, 0x66, 0x64, 0xE9, 0x80, 0xD9, 0xF1, 0x71, 0x1D, 0x19, 0xCD, 0x16, 0xC6, 0x47, 0xDB, 0xB7, - 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, - 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x5D, 0x2C, 0x3E, 0xFC, 0x00, 0x39, 0x7A, 0x33, 0x6F, 0xC2, - 0x02, 0x00, 0x00, 0xDD, 0xCD, 0x1B, 0x5E, 0x7E, 0x97, 0xD9, 0xFA, 0x21, 0x1D, 0x19, 0x8D, 0x16, - 0x8F, 0x8F, 0x66, 0xB7, 0x1F, 0x61, 0x7C, 0xC8, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, - 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, - 0xC4, 0x87, 0xBF, 0x23, 0x37, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xDD, 0xFC, 0x57, 0xF0, 0xAA, - 0xC8, 0x68, 0x34, 0x1B, 0x1D, 0x8D, 0x6E, 0x3F, 0xAA, 0x01, 0xD2, 0xEA, 0xF6, 0xE3, 0x1B, 0xC4, - 0x47, 0xA6, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, - 0x65, 0x9D, 0x0A, 0x8F, 0x70, 0x2F, 0xF5, 0xBB, 0x07, 0xD1, 0x97, 0x04, 0x5F, 0xDE, 0x00, 0x00, - 0x00, 0xDD, 0xC7, 0x3B, 0x70, 0x75, 0xF2, 0x37, 0x60, 0x45, 0xE3, 0xC3, 0x86, 0x47, 0xA3, 0xDB, - 0x8F, 0x09, 0x17, 0x20, 0x8F, 0x45, 0x6E, 0x3F, 0xC2, 0xF8, 0x70, 0xDB, 0xE0, 0xBE, 0xF5, 0x4A, - 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, - 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xD1, 0x11, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x3F, 0x5F, 0x1B, - 0x7C, 0x79, 0x03, 0x00, 0x00, 0x74, 0x1F, 0x6F, 0xDF, 0xE5, 0x27, 0x65, 0x6C, 0xC4, 0x17, 0xC4, - 0x47, 0xA3, 0xDB, 0x8F, 0xC4, 0xCF, 0x7E, 0x7C, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, - 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xC1, - 0x11, 0x1F, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xDD, 0x2E, 0xD1, 0x1B, 0xB0, 0xE2, 0xF1, 0x51, 0x73, - 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xED, 0xED, 0x47, 0x4E, 0xDF, 0x7A, 0x25, - 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, - 0xB2, 0x4E, 0xC5, 0x46, 0x83, 0x79, 0xC7, 0x6F, 0x1F, 0x0A, 0xBE, 0xBC, 0x01, 0x00, 0x00, 0xBA, - 0x8B, 0x39, 0x70, 0xFD, 0x12, 0xB3, 0xF3, 0x53, 0x3A, 0x3A, 0xC2, 0x45, 0xE2, 0xA3, 0x1A, 0x20, - 0x76, 0xD5, 0x6F, 0xBD, 0x0A, 0x03, 0xA4, 0xE6, 0xB5, 0xBB, 0x33, 0xC5, 0xED, 0xC7, 0xCC, 0x7C, - 0x6E, 0x3F, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, - 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0xC8, 0x68, 0x36, 0xEF, 0xC8, 0x9A, 0xB1, 0xE0, 0x4B, 0x1C, 0x00, - 0x00, 0xA0, 0xBB, 0x98, 0x83, 0xCB, 0xD6, 0x9A, 0xED, 0x1F, 0xD5, 0xE1, 0xE1, 0x16, 0x09, 0x8F, - 0x68, 0x7C, 0x84, 0xB7, 0x1F, 0x35, 0x0F, 0x9E, 0x37, 0x7A, 0xF6, 0xC3, 0x0F, 0x10, 0x1B, 0x1F, - 0xDF, 0xCD, 0xE1, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, - 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x08, 0x8C, 0x96, 0x3B, 0xBA, 0x86, 0x37, 0x61, 0x01, - 0x00, 0x80, 0xEE, 0xE4, 0xBF, 0x01, 0x6B, 0xF3, 0xAC, 0x4C, 0xF1, 0x51, 0x7D, 0xF0, 0x5C, 0xDD, - 0x7E, 0x04, 0xF1, 0x51, 0xB9, 0xFD, 0xB0, 0xF1, 0xF1, 0xA0, 0xDD, 0xD7, 0x45, 0x50, 0xA4, 0x99, - 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, - 0xCB, 0x3A, 0x15, 0x17, 0x49, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB7, 0xF2, 0x0E, 0x7C, 0x6E, - 0x28, 0x49, 0x7C, 0xD4, 0x05, 0x48, 0xFC, 0xB5, 0xBB, 0xEE, 0xF6, 0x23, 0x88, 0x8F, 0xDA, 0x37, - 0x5F, 0xD9, 0xF0, 0xC8, 0xE3, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x0A, 0x8B, 0xA4, 0x7B, 0xE1, 0x5A, 0x63, - 0x8E, 0xDD, 0x36, 0x10, 0x7C, 0x99, 0x03, 0x00, 0x00, 0x74, 0x0F, 0x6F, 0xEF, 0x65, 0xF5, 0xAF, - 0xE0, 0x8D, 0x44, 0x87, 0x8C, 0x8F, 0xE8, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0xAA, 0xDE, - 0x7E, 0x04, 0xF1, 0xD1, 0xEE, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, - 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x15, 0x69, 0xF6, 0xFC, 0x67, 0x79, - 0x13, 0x16, 0x00, 0x00, 0xE8, 0x4E, 0x66, 0x8F, 0x3D, 0xEC, 0xB4, 0x88, 0x0F, 0x37, 0x75, 0xFB, - 0x51, 0x7D, 0xED, 0x6E, 0xF5, 0xF6, 0xE3, 0xC2, 0xC8, 0xED, 0x47, 0x10, 0x1F, 0xED, 0xDE, 0x7E, - 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x62, 0x07, - 0xF4, 0x32, 0x4F, 0x05, 0x45, 0x86, 0x79, 0x27, 0x6E, 0x1B, 0x0C, 0xBE, 0xCC, 0x01, 0x00, 0x00, - 0xBA, 0x83, 0x19, 0xE9, 0x9F, 0x5D, 0xF3, 0x0A, 0xDE, 0x48, 0x70, 0x44, 0x97, 0xFE, 0xF6, 0x63, - 0xE6, 0x64, 0x80, 0x3C, 0x60, 0xA7, 0xC2, 0x22, 0xC9, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, - 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0x90, 0xC8, 0x3A, 0xEF, - 0xC8, 0xE7, 0x47, 0x83, 0x2F, 0x75, 0x00, 0x00, 0x80, 0xEE, 0x60, 0x46, 0x96, 0x0E, 0x54, 0xDF, - 0x80, 0x15, 0x09, 0x8E, 0xF8, 0xD4, 0xED, 0x47, 0xFD, 0xB3, 0x1F, 0xE1, 0xED, 0x47, 0x24, 0x3E, - 0xDC, 0xEE, 0xCD, 0x78, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, - 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x44, 0x44, 0x5B, 0xE3, 0x4D, 0x58, 0x00, 0x00, - 0xA0, 0xDB, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0xDE, 0x2F, 0xA3, 0x23, 0x5C, 0xB3, 0xDB, 0x8F, - 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0xC8, 0x7A, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, - 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x05, 0x44, 0xBB, 0x73, 0x6F, - 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x3B, 0x00, 0x00, 0x40, 0xE7, 0x79, 0x23, 0xCB, 0x36, - 0xA8, 0xE8, 0x88, 0x4E, 0xDD, 0x7E, 0xD4, 0x3F, 0xFB, 0xE1, 0x3E, 0x74, 0xD0, 0xBD, 0x7A, 0x37, - 0x12, 0x20, 0xEE, 0x43, 0x07, 0xB3, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, - 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xF1, 0x90, 0xC7, 0x5E, 0xBC, - 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, 0xEE, 0xE2, 0xED, 0xBD, 0x62, 0x54, 0x45, 0x47, 0xB8, 0x66, - 0xB7, 0x1F, 0xD5, 0x67, 0x3F, 0xFC, 0xD7, 0xEE, 0x06, 0xF1, 0xE1, 0xD6, 0xCE, 0xED, 0x87, 0x08, - 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, - 0x3A, 0x15, 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x2E, 0xDE, 0xDE, - 0xC5, 0xE3, 0x2A, 0x3C, 0xC2, 0x35, 0xBD, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC5, 0x87, 0xBA, 0xFD, - 0xB8, 0x27, 0xE5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, - 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x0D, 0x39, 0xCF, 0x3B, 0xB6, 0x96, 0x37, 0x61, - 0x01, 0x00, 0x80, 0xEE, 0xE1, 0xBF, 0x01, 0x2B, 0x12, 0x1C, 0xD1, 0xB5, 0xBC, 0xFD, 0xB0, 0xF1, - 0x31, 0xF1, 0xD8, 0x8C, 0xDA, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x60, 0xA7, 0x22, 0xA3, 0xD1, 0x44, - 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, - 0xD6, 0x89, 0x58, 0x28, 0x62, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0E, 0xFE, - 0x1B, 0xB0, 0x76, 0x7C, 0x52, 0xC6, 0x87, 0x5B, 0xCB, 0xDB, 0x8F, 0x30, 0x3E, 0xDA, 0xBD, 0xFD, - 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, - 0x7A, 0x59, 0x27, 0x42, 0xA1, 0xA8, 0x79, 0x47, 0x6F, 0x1E, 0x0F, 0xBE, 0xE4, 0x01, 0x00, 0x00, - 0x3A, 0xCB, 0x8C, 0x2C, 0x5F, 0x67, 0xB6, 0x7D, 0xA4, 0x75, 0x7C, 0xC8, 0xDB, 0x8F, 0x19, 0xF9, - 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, - 0xC4, 0x21, 0xBD, 0xAC, 0x13, 0x91, 0x50, 0xE8, 0xDC, 0x9B, 0xB0, 0xC6, 0xBE, 0x38, 0x2B, 0xF8, - 0xB2, 0x07, 0x00, 0x00, 0xE8, 0x1C, 0x1B, 0x20, 0xEB, 0x55, 0x7C, 0xB8, 0xA9, 0xDB, 0x0F, 0x3F, - 0x40, 0x44, 0x7C, 0x64, 0xBE, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, - 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA1, 0xE8, 0xF1, 0x26, 0x2C, 0x00, - 0x00, 0xD0, 0x2D, 0xBC, 0x03, 0x57, 0x0D, 0x35, 0x8C, 0x0F, 0x1B, 0x1E, 0xF2, 0xF6, 0xE3, 0x09, - 0x1B, 0x1F, 0x2E, 0x40, 0x1E, 0x8D, 0xDC, 0x7E, 0x84, 0xF1, 0xE1, 0xB6, 0x81, 0xF8, 0xA8, 0x9B, - 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xA9, - 0x38, 0x98, 0x8A, 0xBD, 0x70, 0xB5, 0xF1, 0x7E, 0x71, 0xFB, 0x5D, 0xC1, 0x97, 0x3D, 0x00, 0x00, - 0x40, 0xE7, 0x78, 0x7B, 0x2F, 0x1B, 0x6B, 0x18, 0x20, 0x6E, 0x91, 0xDB, 0x0F, 0x17, 0x1F, 0x67, - 0x07, 0x67, 0xD4, 0xDE, 0x7E, 0xA8, 0x67, 0x3F, 0xBE, 0x21, 0x62, 0x23, 0x3E, 0x11, 0x1E, 0x6E, - 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2A, - 0x0C, 0xA6, 0x70, 0xDE, 0xF1, 0xDB, 0x36, 0x04, 0x5F, 0xF6, 0x00, 0x00, 0x00, 0x9D, 0x63, 0x86, - 0xE6, 0xEB, 0xF8, 0xA8, 0xB9, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC6, 0x47, 0x1E, 0xB7, 0x1F, 0x22, - 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, - 0xEB, 0x44, 0x10, 0x4C, 0xF5, 0xBC, 0xE3, 0x7F, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x67, 0x99, - 0x91, 0xFE, 0xD9, 0x66, 0xE7, 0x25, 0x3A, 0x40, 0xEC, 0xA2, 0xDF, 0x7A, 0x75, 0xEE, 0xC9, 0x19, - 0xE6, 0xAC, 0x8D, 0x8F, 0xC9, 0xDB, 0x8F, 0x19, 0xFA, 0xD9, 0x8F, 0x56, 0xB7, 0x1F, 0x22, 0x3C, - 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, - 0x44, 0x0C, 0x74, 0x62, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x74, 0x9C, 0xFF, 0x0A, 0xDE, 0xD8, 0x1B, - 0xB0, 0x6A, 0xBE, 0xF5, 0xCA, 0xEE, 0x9C, 0x0B, 0x10, 0x17, 0x1F, 0xF1, 0xDB, 0x8F, 0x68, 0x7C, - 0x84, 0x01, 0x72, 0x7F, 0x8B, 0xDB, 0x0F, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, - 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x22, 0x04, 0x3A, 0xB6, 0x97, 0x56, 0x99, - 0xE0, 0x4B, 0x1F, 0x00, 0x00, 0xA0, 0x33, 0xFC, 0x37, 0x60, 0x6D, 0xFE, 0xE3, 0x86, 0xF1, 0x51, - 0xB9, 0xFD, 0xB0, 0xF1, 0xD1, 0xE0, 0xF6, 0xC3, 0xC5, 0x47, 0xF5, 0xF6, 0xE3, 0x41, 0xBB, 0xAF, - 0x8B, 0xE8, 0x08, 0x27, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, - 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x45, 0x40, 0x27, 0x37, 0xB6, 0x8C, 0x37, 0x61, 0x01, 0x00, - 0x80, 0xCE, 0xF2, 0x86, 0x97, 0x0D, 0x36, 0xBC, 0xFD, 0x08, 0xE2, 0xA3, 0xE6, 0xF6, 0x23, 0x88, - 0x8F, 0x9A, 0xDB, 0x8F, 0xF0, 0xD9, 0x8F, 0xEF, 0x36, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, - 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA0, - 0xD3, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0xF2, 0x07, 0x00, 0x00, 0x98, 0x7A, - 0xDE, 0xDE, 0xCB, 0x46, 0x1B, 0xDE, 0x7E, 0x6C, 0xBC, 0xA0, 0x26, 0x3E, 0xEA, 0x3E, 0x74, 0x30, - 0xE9, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, - 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x75, 0xF8, 0xEF, 0xF8, 0x16, 0xD8, 0x5F, 0x9B, 0xFD, 0xDF, 0xE1, - 0xC4, 0x6D, 0xEB, 0x83, 0x2F, 0x7F, 0x00, 0x00, 0x80, 0xA9, 0xE7, 0xED, 0x9E, 0x3F, 0xAE, 0x6F, - 0x3F, 0x6C, 0x7C, 0x84, 0xDF, 0x7A, 0x55, 0x73, 0xFB, 0x31, 0x33, 0xDD, 0xED, 0x87, 0x08, 0x0F, - 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0xB1, 0x78, 0x20, 0x14, 0x39, 0x71, 0x48, 0x2F, 0xEB, - 0xE4, 0xE1, 0xBF, 0xD3, 0xB3, 0xF1, 0x11, 0xCC, 0x3B, 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x80, - 0xCE, 0x30, 0x43, 0xFD, 0xB3, 0xCC, 0xEE, 0xB9, 0x32, 0x3E, 0x72, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, - 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, - 0x0F, 0xFF, 0x9D, 0xDE, 0x64, 0x7C, 0xF8, 0x01, 0x72, 0xF4, 0xE6, 0x93, 0xC1, 0x1F, 0x01, 0x00, - 0x00, 0x00, 0x53, 0xCB, 0x7F, 0x03, 0xD6, 0xF6, 0x8B, 0x6B, 0x03, 0x24, 0x8C, 0x0F, 0xF9, 0xEC, - 0x47, 0x83, 0xDB, 0x8F, 0x7B, 0xC5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, - 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x6A, 0xE3, - 0xC3, 0xDF, 0x91, 0x1B, 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0C, 0x33, 0xB2, 0x7C, 0x9D, 0xD9, - 0xFA, 0xC1, 0xC8, 0xED, 0x87, 0x8D, 0x8F, 0xD8, 0xED, 0x47, 0xED, 0x9B, 0xAF, 0x44, 0x7C, 0x3C, - 0x60, 0x47, 0x7C, 0x14, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, - 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x11, 0x1F, 0x6E, 0x2F, 0xF5, 0xF3, 0x26, 0x2C, 0x00, 0x00, 0xD0, - 0x19, 0xE6, 0xE0, 0xF2, 0xF5, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xEC, 0xC7, - 0xE9, 0x78, 0x80, 0xB8, 0x0F, 0x1D, 0x8C, 0xDF, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, - 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, - 0x84, 0x47, 0x38, 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x00, 0x00, 0x00, 0x60, - 0xEA, 0x78, 0xFB, 0xAE, 0x1E, 0xAD, 0x89, 0x8F, 0x24, 0xCF, 0x7E, 0xB8, 0x35, 0xBA, 0xFD, 0x10, - 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, - 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x88, 0x8E, 0xE8, 0xDC, 0x3F, 0x67, 0xBC, 0x09, 0x0B, 0x00, - 0x00, 0x74, 0x82, 0xB7, 0xF7, 0xF2, 0x93, 0x7E, 0x7C, 0x34, 0xBA, 0xFD, 0x88, 0xC6, 0x87, 0xBA, - 0xFD, 0xF8, 0x76, 0xE4, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, - 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x38, 0xC4, 0xBC, - 0xE3, 0xB7, 0x0F, 0x05, 0x7F, 0x0C, 0x00, 0x00, 0x00, 0x4C, 0x1D, 0x6F, 0xE7, 0x9C, 0xF4, 0xB7, - 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x8E, 0xF8, 0xC8, 0x71, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, - 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x36, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, - 0x82, 0x3F, 0x06, 0x00, 0x00, 0x00, 0xA6, 0x86, 0x39, 0x70, 0xFD, 0x12, 0x6F, 0xFB, 0x27, 0xB2, - 0xDF, 0x7E, 0xDC, 0x13, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, - 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x87, 0x46, 0xC3, - 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xD5, 0xCC, 0xC1, 0x65, 0x6B, 0xBD, 0xAD, 0x1F, 0x6E, 0xEF, - 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, - 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x30, 0x5A, 0xCD, 0xBD, 0x09, 0xEB, 0xF8, - 0x1D, 0x4B, 0x82, 0x3F, 0x0E, 0x00, 0x00, 0x00, 0x8A, 0x77, 0xFE, 0xE0, 0xD2, 0xF5, 0xDE, 0xA6, - 0x0B, 0x33, 0xDE, 0x7E, 0x10, 0x1F, 0xF9, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, - 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC4, 0x45, 0x92, 0xBD, 0x70, 0x0D, 0x6F, 0xC2, - 0x02, 0x00, 0x00, 0x53, 0xEB, 0xFC, 0xFE, 0x6B, 0x06, 0xB3, 0xDD, 0x7E, 0xCC, 0x90, 0xE1, 0xE1, - 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, - 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x8B, 0xA4, 0x7B, 0xFE, 0x0A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xA6, - 0xD6, 0xF9, 0xDD, 0x8B, 0x47, 0xA3, 0xB7, 0x1F, 0xD5, 0x00, 0x89, 0xC5, 0x47, 0xDD, 0xED, 0xC7, - 0xDD, 0xC4, 0x47, 0xFB, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, - 0xE4, 0xE1, 0xBF, 0xD3, 0x13, 0x51, 0x91, 0x72, 0xDE, 0xB1, 0xB5, 0xBC, 0x09, 0x0B, 0x00, 0x00, - 0x4C, 0x1D, 0x6F, 0xF7, 0x42, 0x79, 0xFB, 0x31, 0xE1, 0x02, 0xE4, 0xD1, 0xC8, 0xED, 0x47, 0x18, - 0x1F, 0x6E, 0xF7, 0xEB, 0x6F, 0xBD, 0x22, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, - 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x07, 0x45, 0xDA, 0x79, 0x47, 0x3E, - 0x3F, 0x1A, 0xFC, 0x71, 0x00, 0x00, 0x00, 0x50, 0x2C, 0x33, 0xD2, 0x3F, 0xDB, 0xDB, 0x31, 0x27, - 0xDD, 0xB3, 0x1F, 0x0F, 0xCE, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, - 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x98, 0xC8, 0xB4, 0xA3, - 0x6B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x1A, 0x66, 0xFF, 0xD2, 0x81, 0xF3, 0x5B, 0x3E, 0x6C, - 0x03, 0x24, 0xF2, 0xAD, 0x57, 0xCD, 0x6E, 0x3F, 0x1E, 0xB2, 0xF1, 0x21, 0x6E, 0x3F, 0x88, 0x8F, - 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, - 0xD3, 0x13, 0x11, 0xD1, 0xCE, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0x73, 0x76, 0xF0, 0xC7, 0x02, 0x00, - 0x00, 0x40, 0x71, 0xCE, 0xED, 0x5F, 0x7A, 0xD7, 0xF9, 0x4D, 0xEF, 0x9B, 0x7C, 0xF6, 0xA3, 0xE6, - 0xC1, 0xF3, 0x19, 0xB5, 0xCF, 0x7E, 0xB8, 0xF8, 0x78, 0xA0, 0xFE, 0xF6, 0x83, 0xF8, 0x48, 0x33, - 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, - 0x11, 0x10, 0xED, 0xCE, 0xBD, 0x09, 0xEB, 0xD8, 0x6D, 0x03, 0xC1, 0x1F, 0x0B, 0x00, 0x00, 0x00, - 0xC5, 0x39, 0x7F, 0x60, 0xD9, 0x86, 0x9A, 0x07, 0xCF, 0xA3, 0xB7, 0x1F, 0xD1, 0xF8, 0x78, 0xD8, - 0x86, 0x87, 0x0B, 0x90, 0xEF, 0xD4, 0xDE, 0x7E, 0x10, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x21, 0x8F, 0xF1, - 0x26, 0x2C, 0x00, 0x00, 0x30, 0x55, 0xCE, 0xEF, 0x5E, 0x32, 0xEA, 0xC7, 0x47, 0x83, 0xDB, 0x0F, - 0x17, 0x1F, 0xA7, 0xC2, 0xF8, 0x70, 0xB7, 0x1F, 0x7F, 0x4D, 0x7C, 0x64, 0x9B, 0x0A, 0x87, 0x3C, - 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x87, 0x1C, - 0xE7, 0x9D, 0xB8, 0x6D, 0x30, 0xF8, 0x63, 0x01, 0x00, 0x00, 0xA0, 0x38, 0xE7, 0x76, 0x2E, 0x3A, - 0x59, 0x73, 0xFB, 0x11, 0xC4, 0x47, 0xF5, 0xD9, 0x8F, 0x30, 0x3E, 0x62, 0xB7, 0x1F, 0xC4, 0x47, - 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, - 0xE9, 0xE9, 0x68, 0xC8, 0x73, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0xDE, 0xF9, - 0xED, 0x73, 0xAA, 0xF1, 0x51, 0xF7, 0xA1, 0x83, 0x8F, 0xCC, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, - 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, - 0xE9, 0x60, 0xC8, 0x7D, 0x47, 0x3F, 0xCF, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB1, 0xCE, 0xEE, 0x5F, - 0x3A, 0x70, 0x6E, 0xCB, 0x27, 0x63, 0xB7, 0x1F, 0x33, 0x2B, 0xCF, 0x7E, 0x44, 0xE3, 0xC3, 0xED, - 0xDE, 0xCA, 0xED, 0x07, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, - 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x14, 0x8A, 0x9A, 0x7B, 0x13, 0xD6, 0xD8, 0x17, - 0x67, 0x05, 0x7F, 0x3C, 0x00, 0x00, 0x00, 0xE4, 0xEF, 0xDC, 0xDE, 0xE5, 0xEB, 0xCE, 0x6D, 0xFA, - 0x48, 0xEC, 0xF6, 0x63, 0x46, 0x35, 0x3E, 0xAA, 0x01, 0xF2, 0x23, 0x3B, 0xE2, 0x23, 0xE5, 0x54, - 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x44, - 0x24, 0x14, 0xB9, 0x17, 0xAF, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x58, 0xE7, 0xF7, 0x2E, 0x5F, - 0x5F, 0xF7, 0xEC, 0xC7, 0x8F, 0x27, 0x03, 0xA4, 0x7A, 0xFB, 0xF1, 0xED, 0x0B, 0x88, 0x8F, 0x54, - 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, - 0x13, 0x81, 0x50, 0xF4, 0x5E, 0xB8, 0xCA, 0x78, 0xBF, 0xB8, 0xFD, 0xAE, 0xE0, 0x8F, 0x07, 0x00, - 0x00, 0x80, 0xFC, 0x9D, 0xDB, 0x7D, 0xD5, 0x50, 0xCD, 0x9B, 0xAF, 0xC2, 0xF8, 0x88, 0x06, 0xC8, - 0x8F, 0x66, 0x10, 0x1F, 0xA9, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, - 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x60, 0x8A, 0xE6, 0x1D, 0xBF, 0x6D, 0x43, 0xF0, 0xC7, - 0x03, 0x00, 0x00, 0x40, 0xFE, 0xCE, 0xED, 0xB8, 0x6C, 0x6C, 0xF2, 0xF6, 0xE3, 0x02, 0x79, 0xFB, - 0xF1, 0x76, 0xE4, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x06, 0x53, 0x35, 0xDE, 0x84, 0x05, 0x00, - 0x00, 0x0A, 0x75, 0x76, 0xDB, 0xFC, 0xE0, 0xF6, 0xC3, 0xC6, 0x87, 0x78, 0xF6, 0xE3, 0xED, 0x1F, - 0x4C, 0xDE, 0x7E, 0x10, 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, - 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0xA3, 0x60, 0x2A, 0xE7, 0x1D, 0xBD, 0x79, 0x3C, 0xF8, - 0xE3, 0x01, 0x00, 0x00, 0x20, 0x5F, 0x66, 0xA8, 0x7F, 0xF6, 0xD9, 0xCD, 0x97, 0x04, 0xF1, 0x51, - 0x7B, 0xFB, 0x71, 0x2A, 0xBC, 0xFD, 0xF8, 0x66, 0xE5, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, - 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x04, - 0x53, 0xBE, 0x97, 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x8C, 0xB3, 0x43, 0x4B, 0x07, 0xDE, - 0xDD, 0xF8, 0xE1, 0x6A, 0x80, 0x9C, 0xB6, 0x01, 0x52, 0xF3, 0xEC, 0xC7, 0xF7, 0x2B, 0xB7, 0x1F, - 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, - 0xF0, 0xDF, 0xE9, 0x89, 0x10, 0xE8, 0xD4, 0xC6, 0x96, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x0C, - 0x1B, 0x20, 0xEB, 0x27, 0x06, 0xDF, 0x57, 0x73, 0xFB, 0x11, 0x7D, 0xFE, 0xC3, 0xDD, 0x7E, 0x10, - 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, - 0x7F, 0xA7, 0x27, 0x22, 0xA0, 0x93, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0x63, - 0x02, 0x00, 0x00, 0x20, 0x3F, 0xEF, 0xEE, 0x59, 0x3A, 0xE8, 0xDF, 0x7E, 0x88, 0xF8, 0x70, 0xB7, - 0x1F, 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, - 0xF2, 0xF0, 0xDF, 0xE9, 0x89, 0x00, 0xE8, 0xF4, 0xDC, 0x3F, 0x17, 0x27, 0x6E, 0x5B, 0x1F, 0xFC, - 0x31, 0x01, 0x00, 0x00, 0x90, 0x9F, 0x89, 0x6D, 0x8B, 0x47, 0xEB, 0xDE, 0x7C, 0x15, 0xDE, 0x7E, - 0xDC, 0x4D, 0x7C, 0x34, 0x9F, 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xE9, 0x65, - 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xE2, 0xF0, 0xDF, 0x25, 0xF3, 0x8E, 0xAF, 0xE5, 0x4D, 0x58, 0x00, - 0x00, 0x20, 0x7F, 0x13, 0x5B, 0xFA, 0xC6, 0xE5, 0xC3, 0xE7, 0xF7, 0xBB, 0x6F, 0xBD, 0x22, 0x3E, - 0x1A, 0x4F, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, - 0x4E, 0x4F, 0x1F, 0xFC, 0xBB, 0x65, 0xDE, 0xD1, 0x9B, 0x4F, 0x06, 0x7F, 0x4C, 0x00, 0x00, 0x00, - 0xE4, 0xC3, 0x0C, 0xF5, 0xCF, 0x7A, 0xF7, 0x99, 0x39, 0x95, 0xF8, 0xB0, 0x8B, 0x3E, 0x7C, 0xFE, - 0xD6, 0x5F, 0x11, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, - 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFD, 0x5D, 0xB5, 0x97, 0x56, 0x9A, 0xE0, 0x8F, 0x0A, - 0x00, 0x00, 0x80, 0x7C, 0xB8, 0x37, 0x60, 0x4D, 0x6C, 0xFC, 0x98, 0x0D, 0x90, 0x0B, 0xCC, 0xE9, - 0x47, 0xEC, 0xDC, 0xED, 0x87, 0x0B, 0x90, 0xFB, 0x6D, 0x80, 0x10, 0x1F, 0x0D, 0xA6, 0xC2, 0x21, - 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xFB, - 0xDD, 0x38, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x7C, 0xDD, 0xC4, 0x13, 0x1F, - 0x30, 0xA7, 0xFD, 0x00, 0x09, 0xBE, 0xFD, 0xEA, 0xE1, 0x99, 0xFE, 0xED, 0x07, 0xF1, 0xA1, 0xA6, - 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, - 0x0E, 0xFA, 0xDD, 0x3A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x74, 0x7D, 0x78, - 0xFB, 0x71, 0xCA, 0xCD, 0xDD, 0x7E, 0x7C, 0x67, 0x06, 0xF1, 0x21, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF9, 0xDD, 0x3C, - 0xF7, 0xCF, 0x3D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x79, 0x9A, 0xD8, 0x79, 0xD5, 0x68, 0xF5, 0xDB, - 0xAF, 0xDC, 0x0D, 0x88, 0x7B, 0xF6, 0xE3, 0x6B, 0xC4, 0x47, 0xFD, 0x54, 0x38, 0xE4, 0x31, 0x15, - 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, 0x01, 0xBF, 0x07, 0xC6, - 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xAE, 0x26, 0xB6, 0x5D, 0x76, 0xB2, 0x7A, 0x03, 0xF2, 0xF0, 0x0C, - 0xF3, 0xF6, 0x7D, 0xC1, 0xED, 0x87, 0x8D, 0x8F, 0x3F, 0x10, 0x1F, 0xC1, 0x54, 0x38, 0xE4, 0x31, - 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0xE1, 0xBE, 0x17, - 0xE6, 0x1D, 0x59, 0x33, 0x16, 0xFC, 0x71, 0x01, 0x00, 0x00, 0xD0, 0xBE, 0x09, 0xFF, 0x0D, 0x58, - 0x93, 0xB7, 0x1F, 0x6F, 0x7E, 0x6D, 0xF2, 0xE6, 0xE3, 0x0D, 0xE2, 0xC3, 0x4E, 0x85, 0x43, 0x1E, - 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xEC, 0x7B, - 0x66, 0x47, 0x6E, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x20, 0x1F, 0x13, 0x43, 0xD7, 0x2F, 0x99, 0x78, - 0xFA, 0x13, 0xE6, 0xCC, 0xA3, 0x95, 0xCF, 0xFF, 0x70, 0xB7, 0x1F, 0x95, 0xF8, 0xB8, 0xC0, 0xBF, - 0xF9, 0x78, 0x83, 0xF8, 0x28, 0x68, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, - 0xDF, 0xE9, 0x89, 0x03, 0x7D, 0xAF, 0xED, 0xA5, 0x7E, 0xF7, 0x20, 0xFA, 0x92, 0xE0, 0x8F, 0x0D, - 0x00, 0x00, 0x80, 0xEC, 0xCE, 0x0C, 0x2D, 0x5B, 0x3B, 0xF1, 0xE4, 0x87, 0x2B, 0x9F, 0x01, 0xF2, - 0x60, 0xE5, 0xB5, 0xBB, 0xD5, 0xDB, 0x8F, 0xAF, 0xD9, 0xF8, 0xF8, 0x47, 0xE2, 0x23, 0xFF, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF3, 0xBD, 0x38, - 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x03, 0x00, 0x00, 0x20, 0x3B, 0xF7, 0x06, - 0xAC, 0x89, 0xC7, 0x2F, 0xF2, 0x03, 0xE4, 0xED, 0x6F, 0x55, 0x9E, 0xFB, 0x20, 0x3E, 0xDC, 0x54, - 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, - 0x41, 0xBE, 0x57, 0xE7, 0xBE, 0x26, 0x78, 0x13, 0x16, 0x00, 0x00, 0xC8, 0xC3, 0xD9, 0x5D, 0xD7, - 0x0C, 0x4E, 0x3C, 0x36, 0xC3, 0x9C, 0x71, 0xCF, 0x7E, 0x04, 0x6F, 0xBD, 0xFA, 0xC3, 0x7A, 0xE2, - 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, - 0xF1, 0x3D, 0xBB, 0xF9, 0xFE, 0xBC, 0xE3, 0xB7, 0x0D, 0x05, 0x7F, 0x6C, 0x00, 0x00, 0x00, 0x64, - 0xF7, 0xEE, 0xB6, 0xC5, 0xA3, 0x13, 0x8F, 0xCF, 0x30, 0xEF, 0x7C, 0xBB, 0x72, 0xFB, 0xF1, 0xE6, - 0x5F, 0x5D, 0x44, 0x7C, 0x14, 0x32, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, - 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x57, 0x89, 0x0F, 0x3F, 0x40, 0x8E, 0xDC, 0xCC, 0x9B, 0xB0, - 0x00, 0x00, 0x40, 0xFB, 0xCE, 0x6D, 0x5F, 0x60, 0x26, 0x1E, 0xB9, 0xC0, 0xBC, 0xE5, 0x5E, 0xBB, - 0xFB, 0xD7, 0xC4, 0x47, 0x31, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, - 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0xE1, 0xEF, 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, - 0x00, 0xB4, 0xC7, 0x0C, 0x5D, 0x3B, 0xFB, 0xDC, 0xB6, 0x4B, 0xCD, 0x3B, 0xDF, 0xB4, 0x01, 0xF2, - 0x75, 0xE2, 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, - 0xA7, 0x0E, 0xF1, 0xBD, 0xBA, 0x58, 0x7C, 0xB8, 0xBD, 0xB4, 0xC2, 0x98, 0x97, 0xBF, 0x38, 0x3B, - 0xF8, 0xE3, 0x03, 0x00, 0x00, 0x20, 0xBD, 0xB3, 0xFB, 0x97, 0x0E, 0xBC, 0xFB, 0xD8, 0x87, 0xCC, - 0xDB, 0x77, 0x5F, 0x64, 0xCE, 0x13, 0x1F, 0x05, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, - 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x89, 0xF8, 0x70, 0x7B, 0xE1, 0x6A, 0x63, - 0x8E, 0xDD, 0x36, 0x10, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDE, 0x99, 0x5D, 0x9F, 0xBB, 0xEB, - 0xD4, 0x86, 0x0F, 0x98, 0xF3, 0xFF, 0x44, 0x7C, 0xE4, 0x3F, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, - 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x27, 0xC2, 0x23, 0x98, 0xF7, 0xAF, - 0x4B, 0xCC, 0xE9, 0x9F, 0xDD, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x76, 0xAF, 0x3D, 0x70, 0xED, - 0x86, 0xF1, 0xDD, 0xAB, 0xCD, 0xD9, 0x17, 0xBF, 0x44, 0x7C, 0xE4, 0x3A, 0x15, 0x09, 0x45, 0x4D, - 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0xA7, 0xC3, 0xC3, 0xED, - 0xD4, 0xB3, 0xF3, 0xCC, 0xEF, 0x77, 0xCC, 0x31, 0xBF, 0xDB, 0x77, 0xD3, 0x60, 0xF0, 0xC7, 0x07, - 0x00, 0x00, 0x40, 0x7A, 0xAF, 0xEF, 0xB9, 0x75, 0xF8, 0xF7, 0x07, 0x6F, 0x35, 0xBF, 0xDF, 0xB7, - 0xD2, 0xBC, 0x79, 0xE0, 0x32, 0x73, 0xFE, 0x9F, 0x55, 0x54, 0x24, 0x9D, 0x08, 0x87, 0x3C, 0x26, - 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, - 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0x4E, 0x87, 0xC7, 0x99, 0xBF, 0xEB, 0x33, 0xE3, 0xBB, - 0xE6, 0x9A, 0xDF, 0x6D, 0xB3, 0xF1, 0xE1, 0xB6, 0x67, 0x39, 0xAF, 0xE2, 0x05, 0x00, 0x00, 0xD9, - 0xFD, 0xF3, 0xFF, 0xFE, 0x17, 0x17, 0xFE, 0x76, 0xFB, 0xEA, 0xFB, 0x7E, 0xB7, 0x6D, 0xF1, 0x5B, - 0xBF, 0xDF, 0xB9, 0xD8, 0xB8, 0xBD, 0x7D, 0xE8, 0x72, 0xFF, 0x5B, 0x2D, 0x74, 0x64, 0x34, 0x9A, - 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, - 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0xAE, 0x3E, 0x3C, 0xCE, 0xFE, - 0x43, 0x9F, 0x79, 0x73, 0xEF, 0x64, 0x78, 0xBC, 0xBE, 0x75, 0xCE, 0xF8, 0xEF, 0xB6, 0x5D, 0xBA, - 0x7E, 0xB4, 0xFF, 0x3D, 0x7F, 0x14, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDD, 0x7F, 0xBF, 0xFB, - 0x33, 0x17, 0xBF, 0xB6, 0x79, 0xF1, 0x96, 0x30, 0x42, 0xC6, 0x77, 0x2F, 0x36, 0xA7, 0xFF, 0xC6, - 0x1E, 0xD4, 0x65, 0x6C, 0xC4, 0x27, 0xC2, 0x21, 0x8F, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, - 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, 0xDF, - 0xAB, 0xAB, 0x0D, 0x8F, 0xF3, 0xFF, 0x34, 0xDF, 0xBC, 0xB5, 0x3F, 0x72, 0xE3, 0x61, 0xF7, 0xEA, - 0x33, 0x73, 0x7E, 0x34, 0x3E, 0xF4, 0xA9, 0x59, 0xC1, 0x1F, 0x17, 0x00, 0x00, 0x00, 0xF9, 0xF9, - 0xEF, 0xDF, 0x5D, 0xF2, 0x99, 0xD7, 0xB6, 0x2C, 0xFA, 0x59, 0x18, 0x22, 0x6F, 0xEC, 0xB9, 0xCC, - 0x4C, 0xFC, 0xBD, 0x0B, 0x02, 0x15, 0x1E, 0x6E, 0xB1, 0x68, 0xC8, 0x6B, 0x32, 0x1C, 0xF2, 0x98, - 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, - 0x3A, 0xC4, 0xF7, 0xEA, 0x26, 0xC3, 0xC3, 0xFB, 0xE7, 0xF9, 0xE6, 0x9D, 0x91, 0x79, 0x35, 0xE1, - 0xF1, 0xDA, 0xE6, 0x4B, 0xF7, 0x8F, 0x6F, 0xE9, 0xE3, 0xB5, 0xBB, 0x00, 0x00, 0xA0, 0x78, 0xFF, - 0xEB, 0xA1, 0xCB, 0xBE, 0xF8, 0xBB, 0x6D, 0x8B, 0x7E, 0x19, 0x86, 0x88, 0x7B, 0x3E, 0xE4, 0xEC, - 0x4F, 0x5D, 0x1C, 0x10, 0x1F, 0xF5, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, - 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0x51, 0x7D, 0xC0, 0x3C, 0x08, 0x8F, 0xD7, - 0xB7, 0x5E, 0x3A, 0xF6, 0xDA, 0x96, 0x4B, 0x79, 0xDD, 0x2E, 0x00, 0x00, 0x98, 0x5A, 0xA3, 0xFD, - 0xFD, 0x7F, 0xF4, 0xAB, 0x27, 0x2E, 0xFB, 0x3F, 0xA2, 0xCF, 0x87, 0xBC, 0x35, 0xEC, 0x1E, 0x54, - 0x17, 0xD1, 0x90, 0xD7, 0x64, 0x38, 0xE4, 0x31, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, - 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x55, 0xC2, 0x23, 0xFE, - 0x80, 0xB9, 0x8D, 0x8E, 0x5F, 0xBE, 0xBE, 0x7D, 0xEE, 0xBA, 0xE0, 0x8F, 0x00, 0x00, 0x00, 0x80, - 0xCE, 0xF8, 0xD5, 0x23, 0x57, 0x7E, 0xE0, 0x37, 0x4F, 0x2E, 0xDE, 0x30, 0x19, 0x22, 0x8B, 0xCC, - 0xE9, 0xBF, 0xB9, 0xCC, 0x78, 0xFF, 0x2A, 0x02, 0xA2, 0x9D, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, - 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, - 0xDF, 0xAB, 0x6B, 0xFC, 0x80, 0x39, 0xCF, 0x79, 0x00, 0x00, 0x80, 0xAE, 0x72, 0xF2, 0x91, 0xC5, - 0xF3, 0x5F, 0x7D, 0x66, 0xF1, 0x0E, 0x17, 0x20, 0x6E, 0xE3, 0xBB, 0x17, 0x99, 0x33, 0x7F, 0x67, - 0x0F, 0xE2, 0x2A, 0x26, 0xD2, 0x4E, 0x86, 0x43, 0x1E, 0x8B, 0x47, 0x43, 0x5E, 0x53, 0x91, 0x50, - 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x73, 0xEA, 0x01, - 0xF3, 0xDF, 0x6D, 0xBD, 0x74, 0xF0, 0xBF, 0x7D, 0x67, 0xDE, 0x07, 0x82, 0x2F, 0x73, 0x00, 0x00, - 0x80, 0xEE, 0xF3, 0xAB, 0x8D, 0x8B, 0xD6, 0xBC, 0xFA, 0xCC, 0xC2, 0x9F, 0x87, 0x21, 0xF2, 0xC6, - 0x9E, 0xC5, 0xE6, 0xDD, 0x7F, 0xB0, 0x87, 0x7D, 0x15, 0x16, 0x49, 0x26, 0xC3, 0x21, 0x8F, 0xA9, - 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, - 0x83, 0x7C, 0xAF, 0xCD, 0xFB, 0xE7, 0x05, 0x75, 0x0F, 0x98, 0xDB, 0x8D, 0xFE, 0x7F, 0x8F, 0x5E, - 0x3A, 0x27, 0xF8, 0xB2, 0x06, 0x00, 0x00, 0xE8, 0x6E, 0xFE, 0xF3, 0x21, 0x83, 0x8B, 0xFF, 0xE2, - 0x77, 0xDB, 0x16, 0xFE, 0x32, 0x0C, 0x91, 0x37, 0x0F, 0x2C, 0x36, 0x67, 0x7F, 0x6A, 0x0F, 0xFE, - 0x2A, 0x32, 0x1A, 0x4D, 0x86, 0x43, 0x1E, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, - 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x87, 0xF9, 0x5E, 0xDB, 0xE9, 0xBF, 0xE9, 0xAB, - 0x79, 0xC0, 0xFC, 0xB5, 0x67, 0xE6, 0x1C, 0xE3, 0x01, 0x73, 0x00, 0x00, 0xD0, 0xB3, 0x6C, 0x88, - 0xFC, 0xBB, 0x57, 0x37, 0x2F, 0xBA, 0xE7, 0x77, 0xDB, 0x16, 0xBD, 0x15, 0x86, 0xC8, 0xDB, 0x87, - 0x12, 0x3E, 0xA8, 0x2E, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, - 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xC3, 0x7C, 0x2F, 0x6D, 0xE2, 0xEF, 0xE7, 0xF3, - 0x80, 0x39, 0x00, 0x00, 0x28, 0xAF, 0x93, 0xF7, 0x2E, 0xFC, 0xC8, 0x2B, 0x9B, 0x16, 0x3F, 0x1A, - 0x46, 0x88, 0x7B, 0x3E, 0xA4, 0xE9, 0x83, 0xEA, 0x32, 0x1C, 0xF2, 0x98, 0x0A, 0x87, 0x3C, 0xA6, - 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x3E, 0xD0, 0xF7, 0xCA, - 0xCE, 0xFE, 0xC3, 0x7C, 0xF3, 0xE6, 0x5E, 0xF7, 0xED, 0x56, 0x95, 0xF8, 0xE0, 0x01, 0x73, 0x00, - 0x00, 0x50, 0x6A, 0xFF, 0xE3, 0xFE, 0xCF, 0x2C, 0x7A, 0x75, 0xF3, 0xA2, 0xE7, 0xA2, 0x21, 0x32, - 0xF1, 0xF7, 0x36, 0x0C, 0x88, 0x8F, 0x84, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, - 0x7D, 0xA8, 0xEF, 0x85, 0x9D, 0xFF, 0xA7, 0x05, 0xE6, 0xED, 0x83, 0x7D, 0x41, 0x78, 0x04, 0x37, - 0x1F, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0xA6, 0x8B, 0x5F, 0x3E, 0xB6, 0xF8, 0x96, 0xD7, 0xB7, 0x2E, - 0x7C, 0x39, 0x0C, 0x11, 0xF7, 0xA0, 0xBA, 0xFF, 0x7C, 0x88, 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, - 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xF6, - 0xDD, 0x3E, 0xF7, 0x80, 0xF9, 0xA9, 0x67, 0xA3, 0xE1, 0xE1, 0xC7, 0x07, 0x0F, 0x98, 0x03, 0x00, - 0x80, 0xE9, 0xC7, 0x3D, 0xA8, 0xFE, 0xDB, 0xA7, 0x17, 0x7F, 0xF5, 0xF5, 0xAD, 0x8B, 0x7E, 0xE3, - 0x22, 0xE4, 0x77, 0x3B, 0x16, 0x9A, 0x37, 0xF7, 0x2F, 0x32, 0xE7, 0xFE, 0xD1, 0x1D, 0xEC, 0x55, - 0x44, 0x64, 0x5D, 0x3C, 0x1A, 0xF2, 0x9A, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, - 0xFC, 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xED, 0xAB, 0x3C, 0x60, 0x3E, 0x19, 0x1E, 0xAF, 0x3D, 0x33, - 0x97, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x7E, 0xF5, 0xC8, 0xBC, 0x0F, 0xFC, 0xE6, 0xE9, 0x85, 0xF7, - 0xBD, 0xBE, 0x75, 0xC1, 0x5B, 0x2E, 0x42, 0xDC, 0xDE, 0x1E, 0x59, 0x6C, 0xBC, 0x7F, 0x51, 0x31, - 0x91, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, - 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xCD, 0xAB, 0x3C, 0x60, 0x1E, 0x3E, 0xE7, 0x61, 0xC3, 0x63, 0xCB, - 0x5C, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x88, 0x1B, 0xFB, 0x4F, 0x9F, 0xB9, 0xF8, 0x95, 0xCD, 0x0B, - 0xB7, 0x84, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCD, 0xA9, 0xE7, 0xDA, 0x09, 0x11, 0x15, 0x0E, 0x79, - 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC0, 0xEF, - 0xD6, 0xD5, 0x3E, 0x60, 0x3E, 0xD7, 0xBC, 0xBE, 0x75, 0xEE, 0xB8, 0xFD, 0x91, 0x07, 0xCC, 0x01, - 0x00, 0x00, 0x9A, 0xF9, 0x9F, 0x0F, 0x2D, 0x5A, 0xFA, 0xEA, 0xE6, 0x85, 0x3F, 0x0B, 0x43, 0x64, - 0x7C, 0x68, 0x91, 0x39, 0x33, 0xEA, 0x0E, 0xFE, 0x2A, 0x32, 0x1A, 0x2D, 0x1E, 0x0D, 0x79, 0x4D, - 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC8, 0xEF, 0xC6, - 0xD5, 0x3F, 0x60, 0x6E, 0xB7, 0x75, 0x0E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA4, 0xF1, 0xBF, 0x1E, - 0x5A, 0xF0, 0xC5, 0xD7, 0xB6, 0x2E, 0xF8, 0x65, 0x18, 0x22, 0x6F, 0xEC, 0x5D, 0x64, 0xCE, 0xFE, - 0xC4, 0x45, 0x80, 0x0A, 0x8E, 0xE8, 0xE2, 0xD1, 0x90, 0xD7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, - 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x07, 0xFD, 0x6E, 0x9B, 0x7E, 0xC0, 0x7C, 0x2E, 0x0F, - 0x98, 0x03, 0x00, 0x00, 0x64, 0xE5, 0x1E, 0x54, 0xFF, 0xF5, 0xC6, 0x45, 0x7F, 0x19, 0x7D, 0x3E, - 0xC4, 0x3D, 0xA8, 0x7E, 0xFE, 0x67, 0x2A, 0x3C, 0xDC, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, - 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0x61, 0xBF, 0xDB, 0xC6, 0x03, 0xE6, - 0x00, 0x00, 0x00, 0x05, 0x72, 0x0F, 0xAA, 0xFF, 0xFA, 0xC9, 0x85, 0x1B, 0xC2, 0x08, 0x71, 0x7B, - 0xE7, 0x70, 0xFC, 0xF9, 0x10, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, - 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xD8, 0xEF, 0xA6, 0xF1, 0x80, 0x39, 0x00, 0x00, 0xC0, 0x14, - 0x3A, 0xF9, 0xC8, 0xE2, 0xF9, 0xBF, 0xDD, 0xB4, 0x60, 0x47, 0x18, 0x21, 0xE1, 0x83, 0xEA, 0x3A, - 0x1C, 0xF2, 0x58, 0x3C, 0x10, 0x8A, 0x9C, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, - 0x03, 0x7F, 0xB7, 0x8C, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x3A, 0xE8, 0x57, 0x1B, 0x17, 0xAD, 0x79, - 0x65, 0xD3, 0x82, 0x9F, 0x57, 0x42, 0x64, 0x81, 0x19, 0x1F, 0x5A, 0x68, 0xCE, 0x8C, 0xBA, 0x43, - 0xBC, 0x8A, 0x88, 0xAC, 0x8B, 0x07, 0x42, 0x91, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, - 0x3D, 0x7D, 0xE8, 0xEF, 0x86, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x40, 0x97, 0xA8, 0x7C, 0x90, 0xE1, - 0xC2, 0xAF, 0xBE, 0xB6, 0x75, 0xFE, 0x2F, 0x5D, 0x84, 0xB8, 0xBD, 0xB9, 0x7F, 0xA1, 0x39, 0xFB, - 0x13, 0x77, 0xA0, 0x57, 0x41, 0x91, 0x66, 0xF1, 0x40, 0x28, 0x72, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, - 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFE, 0x9D, 0x5E, 0xA3, 0x07, 0xCC, 0x4F, 0x7E, 0xE7, 0x53, 0xF3, - 0x83, 0x2F, 0x01, 0x00, 0x00, 0x00, 0x74, 0xC2, 0x60, 0xFF, 0xA7, 0xFE, 0xDD, 0xAB, 0x9B, 0x16, - 0xDC, 0xF3, 0xFA, 0xD6, 0xF9, 0x6F, 0x85, 0x21, 0xF2, 0xF6, 0x88, 0x7B, 0x50, 0x5D, 0x85, 0x45, - 0x92, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFF, - 0x9D, 0x9E, 0x7A, 0xC0, 0xFC, 0xB7, 0x1B, 0xE7, 0xDE, 0x10, 0xFC, 0x23, 0x0F, 0x00, 0x00, 0x80, - 0x6E, 0xF0, 0xFF, 0x7E, 0x63, 0xF1, 0x87, 0x7F, 0xF3, 0xD4, 0x82, 0x47, 0xC3, 0x08, 0x71, 0x3B, - 0xF5, 0xDC, 0x22, 0xE3, 0xFD, 0x8B, 0x8A, 0x8C, 0x46, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, - 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xFE, 0x3B, 0xB9, 0xF8, 0x03, 0xE6, 0xEE, 0x39, 0x8F, - 0x57, 0x9F, 0xBE, 0xF4, 0x3F, 0x06, 0xFF, 0x88, 0x03, 0x00, 0x00, 0xA0, 0x1B, 0xFD, 0x8F, 0xFB, - 0x17, 0x2C, 0x7A, 0x75, 0xF3, 0x82, 0x9F, 0x85, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCC, 0xE9, 0xBF, - 0x75, 0x07, 0x61, 0x15, 0x1C, 0xD1, 0xA9, 0x48, 0x28, 0x6A, 0xB1, 0x03, 0x7A, 0x99, 0x27, 0x0F, - 0xFF, 0x9D, 0x9E, 0x0E, 0x80, 0x4E, 0xAD, 0xEE, 0x01, 0xF3, 0xCD, 0x73, 0xDE, 0xB2, 0x3F, 0xF2, - 0x80, 0x39, 0x00, 0x00, 0x40, 0x2F, 0xF9, 0xE5, 0xC3, 0xF3, 0x6F, 0x79, 0x75, 0xCB, 0x82, 0x97, - 0xC3, 0x10, 0x71, 0x0F, 0xAA, 0x4F, 0xFC, 0x57, 0x77, 0xF8, 0x27, 0x3E, 0xA6, 0x6C, 0xF2, 0xF0, - 0xDF, 0xE9, 0xE9, 0x08, 0xE8, 0xC4, 0x1A, 0x3D, 0x60, 0x3E, 0xBE, 0xA5, 0x6F, 0x76, 0xF0, 0x8F, - 0x31, 0x00, 0x00, 0x00, 0x7A, 0x49, 0xF8, 0xA0, 0x7A, 0xF4, 0xF9, 0x10, 0xF7, 0xA0, 0xFA, 0xB9, - 0x7F, 0x74, 0x21, 0x40, 0x7C, 0x14, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x74, 0x08, 0x4C, 0xF5, 0x1A, - 0x3D, 0x60, 0xFE, 0xEB, 0xC7, 0x3E, 0x7D, 0x55, 0xF0, 0x8F, 0x2E, 0x00, 0x00, 0x00, 0x7A, 0x99, - 0xFB, 0x20, 0xC3, 0xDF, 0x6C, 0x9C, 0x7F, 0x5F, 0xED, 0x83, 0xEA, 0x0B, 0xCD, 0xF9, 0x9F, 0xA9, - 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x63, 0x60, 0xAA, 0x17, - 0x7F, 0xC0, 0xFC, 0xF5, 0x6D, 0x73, 0x4E, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x40, 0x49, 0xFD, 0xDB, - 0x83, 0x7D, 0x7D, 0xAF, 0x6C, 0x5E, 0xB0, 0xA5, 0x12, 0x21, 0xF3, 0xCD, 0xEF, 0x77, 0xCD, 0x37, - 0xA7, 0x9E, 0x5B, 0x68, 0xBC, 0x7F, 0x51, 0xC1, 0x90, 0xE7, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, - 0xFF, 0x4E, 0x4F, 0xC7, 0xC0, 0x54, 0x8E, 0x07, 0xCC, 0x01, 0x00, 0x00, 0xA6, 0xB1, 0xFF, 0xF9, - 0xD0, 0xBC, 0xA5, 0xAF, 0x6E, 0xEE, 0xFB, 0x99, 0x8B, 0x90, 0x30, 0x44, 0xCE, 0x8C, 0xBA, 0x03, - 0xB4, 0x8A, 0x87, 0x76, 0x17, 0x3B, 0xA0, 0x97, 0x79, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x20, 0x98, - 0xAA, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xAA, 0x7E, 0xF5, 0x58, 0xDF, 0x5F, 0x54, 0x3E, 0xC8, - 0xB0, 0x12, 0x22, 0xE3, 0x43, 0xF6, 0xC0, 0xF8, 0x13, 0x77, 0x98, 0x56, 0x21, 0x91, 0x65, 0xB1, - 0x03, 0x7A, 0x99, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x82, 0xA9, 0x18, 0x0F, 0x98, 0x03, 0x00, - 0x00, 0x40, 0x72, 0x0F, 0xAA, 0xFF, 0x7A, 0x63, 0xDF, 0x5F, 0xBE, 0xBE, 0xB5, 0xEF, 0xAD, 0x30, - 0x44, 0xDE, 0xDC, 0x6F, 0x0F, 0x90, 0x6D, 0x3F, 0x1F, 0x22, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, - 0x77, 0x7A, 0x3A, 0x0C, 0x8A, 0x1E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x20, 0x11, 0xFF, 0x41, 0xF5, - 0xA7, 0xFA, 0x1E, 0x0D, 0x23, 0xC4, 0xCD, 0x3D, 0xA8, 0x9E, 0xED, 0xF9, 0x10, 0x71, 0x48, 0x2F, - 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x71, 0x50, 0xF4, 0xCE, 0xFC, 0xDD, 0x7C, 0x1E, 0x30, 0x07, - 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x41, 0xF5, 0x57, 0x9F, 0x99, 0x3F, 0x12, 0x46, 0x48, 0xFA, 0x07, - 0xD5, 0xC5, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x41, 0x91, 0x73, 0xCF, 0x79, - 0xF0, 0x80, 0x39, 0x00, 0x00, 0x00, 0xDA, 0xF2, 0xAB, 0x27, 0xFA, 0xD6, 0x44, 0x1F, 0x54, 0x77, - 0xCF, 0x87, 0xB4, 0x7E, 0x50, 0x3D, 0x76, 0x40, 0x2F, 0xF3, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x81, - 0x50, 0xD4, 0xCE, 0xFD, 0x94, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x90, 0xA3, 0xCA, 0x07, 0x19, 0xF6, - 0x7D, 0x35, 0xFA, 0xA0, 0xBA, 0x7B, 0x3E, 0x44, 0x3F, 0xA8, 0x1E, 0x3B, 0xA0, 0x97, 0x79, 0xF2, - 0xF0, 0xDF, 0xE9, 0xE9, 0x48, 0x28, 0x62, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x42, 0xB9, 0xE7, - 0x43, 0x5E, 0xDD, 0xD4, 0x77, 0x4F, 0xF4, 0x41, 0xF5, 0xB7, 0x0E, 0x46, 0x1F, 0x54, 0x17, 0x87, - 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0A, 0x79, 0x2F, 0x7C, 0xC0, 0x3C, 0xFA, 0x9C, - 0x87, 0x1D, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA0, 0x18, 0x47, 0xBF, 0xB1, 0xF8, 0xC3, 0xAF, 0x6C, - 0xEE, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0x3B, 0x87, 0xEC, 0xC1, 0xF4, 0x5F, 0xC4, 0x41, 0xBD, 0x8C, - 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x42, 0xDE, 0x53, 0x0F, 0x98, 0xFF, 0xFA, 0xE1, 0x4B, 0x6F, - 0x0E, 0xFE, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xE3, 0x3F, 0xA8, 0xEE, 0x9E, 0x0F, 0xD9, 0xDE, - 0x67, 0xDC, 0x7E, 0xBF, 0xB3, 0xCF, 0x9C, 0x7A, 0xCE, 0x1E, 0x54, 0xD5, 0xA1, 0xBD, 0x2C, 0x93, - 0x87, 0xFF, 0x4E, 0xAF, 0x3E, 0x14, 0xF2, 0x9E, 0x7A, 0xC0, 0xFC, 0xD7, 0x83, 0x73, 0xFE, 0xB7, - 0xE0, 0x1F, 0x05, 0x00, 0x00, 0x00, 0x60, 0xEA, 0xFC, 0xF2, 0xE1, 0xB9, 0xB7, 0xBC, 0xB6, 0xB5, - 0xEF, 0x97, 0x61, 0x88, 0x8C, 0xEF, 0x9E, 0x6F, 0x26, 0xFE, 0xAB, 0x3D, 0x18, 0xAB, 0x03, 0x7C, - 0x2F, 0x4F, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0C, 0x79, 0x4D, 0x3D, 0x60, 0xFE, 0xDA, 0xA6, 0x39, - 0x77, 0xF3, 0x80, 0x39, 0x00, 0x00, 0x00, 0x3A, 0xCA, 0x7F, 0x50, 0xFD, 0xC9, 0xBE, 0xAF, 0xBE, - 0xBE, 0x65, 0xDE, 0x5B, 0x61, 0x88, 0xBC, 0xB9, 0x6F, 0xBE, 0x39, 0xFB, 0x13, 0x7B, 0x48, 0x56, - 0x87, 0xF9, 0x5E, 0x9B, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x1A, 0xF2, 0x98, 0x7A, 0xC0, 0xFC, 0xD5, - 0xCD, 0x73, 0x37, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xBA, 0x8A, 0x7B, 0x50, 0xFD, 0xB7, 0x9B, - 0xFA, 0xEE, 0x09, 0x23, 0xC4, 0xED, 0xED, 0x61, 0xF7, 0xA0, 0xBA, 0x38, 0xD4, 0xF7, 0xCA, 0xE4, - 0xE1, 0xBF, 0xD3, 0xD3, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0x3D, 0xC9, 0x3D, - 0x1F, 0xF2, 0xCA, 0xA6, 0xBE, 0x2D, 0xD1, 0x10, 0x71, 0xCF, 0x87, 0xF4, 0xDC, 0x83, 0xEA, 0xF2, - 0xF0, 0xDF, 0xE9, 0xE9, 0x78, 0x68, 0x77, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x9E, 0x57, 0xF9, - 0x20, 0xC3, 0x79, 0x35, 0x0F, 0xAA, 0x9F, 0xFE, 0x5B, 0x7B, 0xE0, 0x55, 0x87, 0xFD, 0x6E, 0x9B, - 0x3C, 0xFC, 0x77, 0x7A, 0xF5, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xA5, 0xF3, - 0xAB, 0xC7, 0xFA, 0xFE, 0x22, 0xFE, 0xA0, 0x7A, 0x57, 0x3F, 0x1F, 0x22, 0x0F, 0xFF, 0x9D, 0x9E, - 0x0E, 0x88, 0xAC, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0x94, 0x9A, 0x7B, 0x50, 0xFD, 0xB5, 0x2D, - 0xF3, 0xBE, 0x1E, 0x7F, 0x50, 0xFD, 0xDC, 0x3F, 0xDA, 0xC3, 0xB5, 0x8A, 0x80, 0x4E, 0x4D, 0x1E, - 0xFE, 0x3B, 0x3D, 0x1D, 0x11, 0x59, 0xC6, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x98, 0x56, 0xDC, 0x83, - 0xEA, 0xBF, 0x79, 0xAA, 0xEF, 0xC7, 0x61, 0x84, 0xB8, 0x75, 0xCD, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, - 0xE9, 0xE9, 0x90, 0x48, 0xBB, 0x46, 0x0F, 0x98, 0xBF, 0xB6, 0xE5, 0xD2, 0x81, 0xE0, 0x7F, 0x1A, - 0x00, 0x00, 0x00, 0xA0, 0xBC, 0xFC, 0x0F, 0x32, 0xDC, 0xD4, 0x37, 0x12, 0x46, 0x48, 0xF8, 0x41, - 0x86, 0x1D, 0x7B, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x13, 0x69, 0xA7, 0x1E, 0x30, 0x7F, - 0xE5, 0xC9, 0x39, 0xB7, 0x07, 0xFF, 0x53, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x87, 0x7B, 0x50, 0xFD, - 0xB5, 0x2D, 0xF3, 0x8E, 0x85, 0x21, 0xE2, 0x9E, 0x0F, 0x39, 0x33, 0x6A, 0x0F, 0xDF, 0x2A, 0x12, - 0x8A, 0x9A, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x26, 0xD2, 0x4C, 0x3D, 0x60, 0xFE, 0xCA, 0xA6, 0xB9, - 0xFF, 0x57, 0xF0, 0xB7, 0x1E, 0x00, 0x00, 0x00, 0x98, 0x9E, 0xC2, 0x0F, 0x32, 0x8C, 0x3E, 0xA8, - 0xFE, 0xC6, 0x9E, 0x29, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x14, 0x49, 0x17, 0x7F, - 0xC0, 0xDC, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x98, 0xF0, 0x83, 0x0C, 0xE3, 0x0F, 0xAA, - 0x17, 0xF6, 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2A, 0x92, 0x8C, 0x07, 0xCC, 0x01, 0x00, - 0x00, 0x80, 0x0C, 0x5E, 0x79, 0x72, 0xCE, 0xA5, 0xF1, 0x0F, 0x32, 0x74, 0x0F, 0xAA, 0xE7, 0xFA, - 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2C, 0x5A, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, - 0x1C, 0xFC, 0x7A, 0x63, 0xDF, 0x55, 0xAF, 0x6E, 0x9E, 0xF7, 0x4F, 0x61, 0x84, 0x84, 0x0F, 0xAA, - 0xCB, 0xA0, 0x48, 0x33, 0x79, 0xF8, 0xEF, 0xF4, 0xEA, 0xC3, 0x22, 0xC9, 0x78, 0xC0, 0x1C, 0x00, - 0x00, 0x00, 0xC8, 0xD9, 0x2F, 0x1F, 0x9E, 0x7B, 0x4B, 0xFC, 0x83, 0x0C, 0x33, 0x3F, 0xA8, 0x2E, - 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x8B, 0x66, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, 0x40, 0xFE, - 0x07, 0x19, 0x6E, 0xEE, 0xFB, 0x3F, 0xE3, 0xCF, 0x87, 0xA4, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, - 0x3D, 0x1D, 0x18, 0x8D, 0xA6, 0x1E, 0x30, 0xFF, 0xED, 0xC6, 0x4B, 0xBF, 0xC5, 0x03, 0xE6, 0x00, - 0x00, 0x00, 0x40, 0x01, 0xC2, 0x07, 0xD5, 0xC3, 0x08, 0x71, 0x7B, 0xEB, 0x40, 0x82, 0x07, 0xD5, - 0xE5, 0xE1, 0xBF, 0xD3, 0xD3, 0x91, 0xA1, 0xE6, 0x9E, 0xF3, 0x88, 0x3F, 0x60, 0xFE, 0xCA, 0x53, - 0x73, 0xB6, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x00, 0x30, 0x05, 0xDC, 0x07, 0x19, 0xBE, 0xBE, 0x75, - 0xDE, 0xFE, 0x68, 0x88, 0xBC, 0x73, 0xA8, 0xC1, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xD0, - 0x88, 0x4F, 0x3D, 0x60, 0xFE, 0xDA, 0xE6, 0x39, 0x3F, 0xE1, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, - 0x03, 0xDC, 0x07, 0x19, 0xC6, 0x1F, 0x54, 0x3F, 0xFD, 0xB7, 0xF6, 0xF0, 0x5E, 0x82, 0xF8, 0x70, - 0x0F, 0x98, 0xD7, 0x3C, 0xE7, 0xC1, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x40, 0x77, 0x88, 0x7F, 0x90, - 0xE1, 0xF8, 0xEE, 0x3E, 0x33, 0xF1, 0xF7, 0xEE, 0x20, 0xAF, 0x02, 0xA0, 0x93, 0xAB, 0x0F, 0x8D, - 0xF8, 0xDC, 0x03, 0xE6, 0x6F, 0x0C, 0xD5, 0x3F, 0x60, 0x3E, 0xDA, 0xFF, 0x9E, 0x3F, 0x0A, 0x7E, - 0xBB, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xCD, 0x7F, 0x50, 0x7D, 0xCB, 0xBC, 0xAF, 0x57, 0x1E, 0x54, - 0xB7, 0x07, 0x78, 0xBB, 0x37, 0xF7, 0xF5, 0xD9, 0x03, 0xBD, 0x3B, 0xD8, 0xAB, 0x18, 0x98, 0xEA, - 0xD5, 0xC7, 0x46, 0x74, 0xEE, 0x83, 0x04, 0x79, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xE8, 0x31, 0xEE, - 0x41, 0xF5, 0x57, 0x36, 0xCD, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0xDB, 0xC3, 0xF3, 0xED, 0x01, 0x5F, - 0x45, 0xC1, 0x54, 0x4D, 0x47, 0x87, 0x1B, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x00, 0x25, 0xF0, 0x6F, - 0x1B, 0xFA, 0xFA, 0x5E, 0xDB, 0x32, 0xF7, 0x27, 0x61, 0x84, 0xFC, 0x7E, 0xE7, 0x3C, 0x73, 0xEA, - 0xD9, 0xF9, 0xF6, 0xC0, 0xAF, 0x02, 0xA1, 0xC8, 0x35, 0x0E, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, - 0x00, 0x4A, 0xE6, 0x57, 0x4F, 0x5C, 0xBA, 0xC6, 0x86, 0xC8, 0xB1, 0x68, 0x88, 0x9C, 0xF9, 0x3B, - 0x17, 0x01, 0x2A, 0x16, 0xF2, 0x5E, 0x7D, 0x78, 0xB8, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0x50, - 0x62, 0xEE, 0x01, 0xEE, 0xDF, 0x3E, 0x39, 0xF7, 0xAB, 0xAF, 0x6F, 0x9B, 0x37, 0x1E, 0x86, 0x88, - 0x7B, 0x50, 0xBD, 0xD8, 0xE7, 0x43, 0xEA, 0xC3, 0x83, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x69, - 0xA4, 0xF2, 0x41, 0x86, 0x73, 0xEF, 0x79, 0x7D, 0xCB, 0xDC, 0x9A, 0x07, 0xD5, 0xCF, 0xFD, 0x34, - 0xEF, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, 0xA6, 0xB1, 0x57, 0x9E, 0x9C, - 0x73, 0xA9, 0x7A, 0x50, 0x3D, 0x9F, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, - 0xE0, 0x7B, 0x6D, 0x47, 0xDF, 0x40, 0xE5, 0x83, 0x0C, 0x27, 0x43, 0xE4, 0x8D, 0x3D, 0x7D, 0xFE, - 0x33, 0x22, 0xD9, 0xDE, 0x9A, 0x55, 0x79, 0xB8, 0xDC, 0x3D, 0xE3, 0x11, 0xBF, 0xF1, 0xE0, 0x01, - 0x73, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x57, 0x9E, 0x99, 0x73, 0xDB, 0xEB, 0xDB, 0xE7, 0x9E, 0x8C, - 0x86, 0x48, 0x18, 0x23, 0xEF, 0x1C, 0x9A, 0x6F, 0x4E, 0xFF, 0xCD, 0x7C, 0xFF, 0x79, 0x91, 0xF8, - 0x0D, 0x89, 0xFB, 0xFF, 0xDD, 0xBF, 0xEE, 0xFE, 0xFD, 0x77, 0x0E, 0xF5, 0xD5, 0x3C, 0xDF, 0x11, - 0xCE, 0x3D, 0x60, 0x6E, 0x7F, 0xEE, 0x75, 0xC1, 0x5F, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xDC, - 0x1B, 0xB3, 0x5E, 0x79, 0x66, 0xEE, 0x70, 0x3C, 0x44, 0x5A, 0x2E, 0x16, 0x1D, 0x95, 0xCD, 0x19, - 0xFA, 0xF5, 0xA3, 0x97, 0xDE, 0x1C, 0xFC, 0xD4, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xB9, 0x87, 0xD5, - 0x7F, 0xB3, 0x71, 0xDE, 0x9D, 0xAF, 0x3E, 0x3D, 0xEF, 0xA1, 0x57, 0x37, 0xCF, 0x7D, 0x59, 0x46, - 0x47, 0xB8, 0x20, 0x38, 0x5E, 0xDB, 0x3C, 0xF7, 0xD8, 0xAB, 0xCF, 0xCC, 0x7D, 0xDA, 0xDD, 0x76, - 0xFC, 0xB7, 0xEF, 0xCC, 0xFB, 0x40, 0xF0, 0x53, 0x01, 0x00, 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x35, - 0xB9, 0xFE, 0x07, 0x1B, 0xEE, 0xE8, 0x1B, 0x88, 0xEF, 0xDF, 0x36, 0xCC, 0xEE, 0x0B, 0xFE, 0x63, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0xD0, 0x15, 0xDE, 0xF3, 0x9E, 0xFF, 0x1F, 0x5B, 0xE2, 0x94, 0x1D, 0x86, - 0x86, 0x23, 0x09, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82}; - -static const uint8_t tree_gif[] PROGMEM = { - - 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x28, 0x00, 0x3C, 0x00, 0x83, 0x0B, 0x00, 0x00, 0xFF, 0xFF, - 0x00, 0x21, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x94, 0x00, 0x00, 0xB5, 0x00, 0x00, - 0xDE, 0x00, 0x00, 0xFF, 0x00, 0x6B, 0x00, 0x00, 0xFF, 0x33, 0x33, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, - 0xFF, 0xFF, 0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0x00, 0xCC, 0x00, 0x00, 0x21, 0xFF, 0x0B, - 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0xA0, 0x0F, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, - 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, - 0x8C, 0xCA, 0xE8, 0x85, 0xE8, 0xA5, 0xAC, 0x67, 0xEA, 0x8A, 0xE5, 0x2B, 0x2F, 0xE3, 0x31, 0xCE, - 0xAF, 0x41, 0x1C, 0xB8, 0x1B, 0x24, 0x80, 0x04, 0xAF, 0x87, 0x02, 0x26, 0x88, 0xA1, 0x07, 0x60, - 0xB9, 0x44, 0x82, 0x04, 0x02, 0x80, 0x61, 0x30, 0x70, 0x6E, 0x0C, 0x86, 0x03, 0x60, 0x20, 0xB0, - 0x6A, 0xA8, 0xD3, 0x03, 0x21, 0xEC, 0xAD, 0x18, 0x12, 0xE8, 0xF4, 0xB1, 0x4C, 0x51, 0xA0, 0x07, - 0xEA, 0x07, 0x5B, 0xF2, 0x70, 0x13, 0x76, 0xD4, 0xA8, 0xBC, 0xBC, 0xEA, 0x1F, 0x06, 0x77, 0x51, - 0x73, 0x50, 0x0A, 0x80, 0x7F, 0x04, 0x4C, 0x4D, 0x65, 0x06, 0x0A, 0x3B, 0x3B, 0x62, 0x5A, 0x53, - 0x65, 0x05, 0x02, 0x04, 0x68, 0x0C, 0x6A, 0x00, 0x5D, 0x5E, 0x0F, 0x0F, 0x6A, 0x98, 0x6A, 0x09, - 0x7B, 0x56, 0x9D, 0x09, 0x0C, 0xA7, 0xA7, 0x7F, 0x06, 0x9D, 0xA3, 0x44, 0x02, 0x01, 0x03, 0x90, - 0x0C, 0x87, 0x03, 0x06, 0x02, 0x05, 0x56, 0x06, 0x01, 0x02, 0x53, 0xB1, 0xB3, 0x04, 0x79, 0xAF, - 0x55, 0x48, 0x51, 0xB0, 0x87, 0xC0, 0x7F, 0x07, 0x95, 0x05, 0x85, 0x44, 0xB6, 0x00, 0x05, 0x53, - 0x96, 0x6A, 0x60, 0x02, 0x0A, 0x48, 0x89, 0x00, 0x07, 0xA1, 0x69, 0x7D, 0x2B, 0x3D, 0x9D, 0x41, - 0xA1, 0x04, 0xA0, 0xDD, 0x9D, 0x38, 0x02, 0xE1, 0x6A, 0x07, 0x62, 0x0C, 0x77, 0xE6, 0xAD, 0x2F, - 0x05, 0x01, 0xB6, 0x90, 0x07, 0xA8, 0xA7, 0x54, 0xB5, 0xBC, 0x06, 0x33, 0x50, 0x53, 0x3A, 0x00, - 0x39, 0x62, 0x10, 0x6B, 0xDF, 0xBE, 0x19, 0x03, 0x18, 0x40, 0xA9, 0x15, 0x4B, 0xCC, 0x0E, 0x77, - 0x3B, 0x04, 0xC4, 0x02, 0x38, 0x43, 0x21, 0x96, 0x2C, 0xD3, 0xD6, 0x81, 0x01, 0x26, 0x2A, 0xFB, - 0xDE, 0x07, 0x7C, 0x0A, 0xB7, 0x71, 0x1B, 0x79, 0xEE, 0xC5, 0x83, 0x72, 0xDD, 0x84, 0xBC, 0x4B, - 0x13, 0xA4, 0x13, 0x15, 0x17, 0xAB, 0x18, 0x78, 0x4A, 0x43, 0x40, 0x81, 0x43, 0x76, 0x8E, 0xB6, - 0x04, 0x7C, 0x19, 0x02, 0x98, 0xC4, 0x86, 0x35, 0xBD, 0xE1, 0x1C, 0x90, 0x4D, 0x62, 0xBF, 0x14, - 0xFC, 0x7E, 0x02, 0x1A, 0x60, 0xD3, 0xD1, 0x9D, 0x3B, 0x3A, 0x09, 0xFC, 0x44, 0xB1, 0xD0, 0x96, - 0x8E, 0x43, 0x8D, 0x9E, 0xDA, 0xDB, 0x22, 0x11, 0x8A, 0x42, 0x10, 0x5C, 0x00, 0x1A, 0x2D, 0x38, - 0xF2, 0x0E, 0xA0, 0x4A, 0x03, 0x4E, 0xA2, 0xF0, 0xF4, 0x80, 0x17, 0x95, 0x8C, 0x23, 0xD1, 0xD8, - 0x12, 0x00, 0x92, 0x03, 0xAB, 0x99, 0x23, 0x71, 0x3E, 0x8D, 0xEB, 0x6E, 0x18, 0x07, 0x66, 0x23, - 0x05, 0x3E, 0x72, 0xE4, 0x06, 0x0D, 0x81, 0x02, 0xE4, 0x36, 0x5D, 0xD9, 0xA5, 0xC0, 0xAD, 0x59, - 0xA2, 0x86, 0x6E, 0xD6, 0xC4, 0x73, 0xEB, 0x15, 0xA5, 0xC5, 0xDE, 0x14, 0xF4, 0x62, 0x07, 0xC0, - 0xE9, 0x9D, 0xCC, 0x58, 0x02, 0x14, 0xA0, 0x84, 0x45, 0x83, 0x68, 0x7A, 0x8D, 0x81, 0x66, 0xC3, - 0xE9, 0xD0, 0xA6, 0x3E, 0x03, 0xF3, 0x80, 0x7D, 0x90, 0xD8, 0x58, 0xA2, 0x59, 0x2D, 0x90, 0x68, - 0xD6, 0x64, 0x17, 0x76, 0x5A, 0x23, 0xBF, 0x13, 0x58, 0x89, 0x7A, 0xC3, 0xF0, 0x8F, 0xB6, 0xB8, - 0x4B, 0xD3, 0x74, 0x52, 0x50, 0x92, 0xC2, 0x03, 0xD1, 0x78, 0xD7, 0x89, 0x4C, 0x23, 0x26, 0x6E, - 0x82, 0xCC, 0x15, 0x5E, 0x05, 0x08, 0x30, 0x06, 0x8A, 0x75, 0x64, 0xFA, 0x42, 0xF1, 0x12, 0xAD, - 0x60, 0xDE, 0x51, 0x0A, 0x94, 0xBA, 0x5E, 0x2C, 0x8C, 0x86, 0xDD, 0x3D, 0xDE, 0x8F, 0x0A, 0x70, - 0x51, 0x5F, 0xFE, 0xF2, 0x84, 0xD1, 0xD0, 0xA6, 0x68, 0xB7, 0x96, 0x62, 0x14, 0x0C, 0xC1, 0xB7, - 0x90, 0x68, 0x72, 0xD1, 0x7C, 0xD9, 0x3D, 0xA3, 0x94, 0x35, 0xDE, 0x54, 0x06, 0x92, 0x51, 0x50, - 0x68, 0xC2, 0xC5, 0x44, 0xB7, 0x30, 0x70, 0xDE, 0x6A, 0x49, 0x69, 0x86, 0xC5, 0x2D, 0xA3, 0x29, - 0x04, 0x05, 0x2F, 0xD9, 0xC4, 0x02, 0x0C, 0x6C, 0x0C, 0x48, 0xB0, 0x94, 0x01, 0xDA, 0x3C, 0xF2, - 0x56, 0x21, 0xFA, 0xE8, 0xA3, 0xA1, 0x55, 0x12, 0xE9, 0xF4, 0x56, 0x42, 0xF8, 0x50, 0x00, 0x40, - 0x08, 0x08, 0xD4, 0x88, 0x80, 0x05, 0x33, 0x66, 0x10, 0xA2, 0x0C, 0xDC, 0xA0, 0xB0, 0xA3, 0x0B, - 0x71, 0xCD, 0xB1, 0x80, 0x75, 0x69, 0x20, 0x41, 0xE4, 0x91, 0x6B, 0x64, 0x10, 0x01, 0x00, 0x21, - 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, 0x00, - 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, 0x8C, - 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0x31, 0x1C, 0x34, - 0x1B, 0x24, 0x4C, 0x82, 0xE7, 0x28, 0x5E, 0x02, 0x78, 0x7A, 0x30, 0x8E, 0x47, 0x62, 0x48, 0x20, - 0x60, 0xD8, 0x06, 0x4A, 0x8E, 0xC1, 0x70, 0x60, 0x0C, 0x04, 0xD1, 0xCD, 0x60, 0x60, 0x3B, 0x10, - 0xBA, 0x59, 0x8B, 0x21, 0x41, 0x2E, 0x0F, 0xC3, 0x16, 0xF2, 0xC0, 0xAC, 0x40, 0x4F, 0x1E, 0x80, - 0x04, 0x81, 0x70, 0xD8, 0x0A, 0x14, 0x0F, 0xF7, 0x42, 0x00, 0xA0, 0xD6, 0x09, 0x0A, 0x81, 0x81, - 0x68, 0x00, 0x85, 0x85, 0x7F, 0x07, 0x07, 0x0A, 0x06, 0x7A, 0x06, 0x00, 0x74, 0x74, 0x5E, 0x8A, - 0x36, 0x68, 0x05, 0x7C, 0x66, 0x3D, 0x64, 0x58, 0x61, 0x0F, 0x0F, 0x66, 0x64, 0x99, 0x64, 0x79, - 0x9C, 0x9E, 0xA0, 0x48, 0x4E, 0x9D, 0xA3, 0x4A, 0x02, 0x01, 0x37, 0x90, 0x55, 0x04, 0x5C, 0x02, - 0x05, 0x59, 0x06, 0x01, 0x02, 0x4F, 0x89, 0x55, 0x76, 0xAC, 0x50, 0xAB, 0x0A, 0xAD, 0x7F, 0xB1, - 0x75, 0x07, 0x02, 0x04, 0x05, 0x00, 0xBE, 0x39, 0x06, 0x77, 0x05, 0x36, 0x04, 0x9F, 0x5B, 0xCC, - 0x00, 0x4A, 0x82, 0x81, 0x07, 0x9F, 0x65, 0x86, 0x85, 0x40, 0x9D, 0x0A, 0x9F, 0x0C, 0xD0, 0x9F, - 0x00, 0x9D, 0x39, 0x02, 0xDE, 0x66, 0xB0, 0x73, 0xE2, 0x09, 0xE4, 0xAA, 0x2F, 0x05, 0x01, 0xCC, - 0x5E, 0xA7, 0x56, 0x75, 0xD2, 0xB8, 0x8C, 0x2F, 0x4C, 0x36, 0x06, 0xB1, 0x73, 0xE1, 0x88, 0xC9, - 0x92, 0x45, 0x43, 0x96, 0x00, 0x2E, 0x37, 0xE8, 0x79, 0x99, 0x53, 0xEC, 0x86, 0x0D, 0x06, 0x05, - 0xF3, 0x51, 0x61, 0x57, 0xE6, 0x9E, 0xBF, 0x35, 0x0C, 0xDE, 0x81, 0xE8, 0x64, 0x10, 0xFB, 0x5B, - 0xB6, 0x6C, 0xF5, 0x56, 0x94, 0x22, 0x13, 0xA7, 0xE2, 0x9C, 0x04, 0xDF, 0xCA, 0x74, 0xB2, 0xB2, - 0xC2, 0x40, 0x2A, 0x92, 0x72, 0x20, 0x45, 0x52, 0xE0, 0x45, 0x1A, 0x01, 0x2B, 0xCA, 0x3E, 0xC4, - 0x3A, 0x38, 0x60, 0xDB, 0x23, 0x86, 0xD6, 0x14, 0x0C, 0x20, 0xC0, 0x84, 0xCB, 0x8A, 0x7C, 0x3C, - 0x1F, 0x25, 0x94, 0xA9, 0x80, 0x21, 0x17, 0xA2, 0x5B, 0x4E, 0x34, 0x91, 0xE5, 0x2F, 0x99, 0x4C, - 0xA0, 0x89, 0xEC, 0x5C, 0xC1, 0xB5, 0x89, 0xC3, 0x15, 0x2B, 0xCC, 0x10, 0xD6, 0xF9, 0x38, 0x67, - 0xA8, 0xB1, 0x01, 0xE5, 0x40, 0xD4, 0x7B, 0x42, 0xF1, 0x63, 0x02, 0x66, 0x02, 0x12, 0xA4, 0xFA, - 0x90, 0x2A, 0x54, 0xB6, 0x44, 0xEB, 0xDA, 0x96, 0x19, 0x9A, 0x53, 0x43, 0x01, 0xBB, 0x64, 0x84, - 0xAE, 0xC3, 0xBB, 0xB0, 0xCC, 0x31, 0x40, 0x5D, 0x35, 0xD8, 0x62, 0x82, 0x6B, 0x68, 0xAC, 0xA6, - 0x43, 0xF1, 0xD2, 0x01, 0x20, 0xE9, 0x8A, 0x25, 0x05, 0x96, 0x36, 0xD8, 0x8A, 0xD7, 0xD8, 0x46, - 0xD0, 0x85, 0xEB, 0x7E, 0x72, 0x31, 0x10, 0x54, 0x9F, 0x85, 0x00, 0xF1, 0xA6, 0x1C, 0x94, 0x2C, - 0x34, 0xB2, 0x17, 0x9F, 0x5B, 0xB8, 0x14, 0x80, 0xFC, 0x41, 0x28, 0x63, 0xC7, 0x03, 0x9A, 0x4A, - 0x32, 0x9C, 0x2C, 0x2B, 0x2E, 0x40, 0x72, 0x63, 0x59, 0x48, 0x85, 0x47, 0x8D, 0xD8, 0xC8, 0xD9, - 0xE2, 0xF0, 0x55, 0x99, 0x4A, 0xE3, 0x82, 0x07, 0x41, 0x3F, 0x25, 0x92, 0xAE, 0xD7, 0x4C, 0x3C, - 0xE7, 0xAC, 0x02, 0x04, 0x58, 0xC4, 0xC4, 0xAD, 0x9C, 0x1B, 0xB1, 0x3F, 0xE1, 0x42, 0x3D, 0x4B, - 0x9E, 0x85, 0xCB, 0x57, 0xA6, 0x30, 0x4B, 0x97, 0x88, 0x26, 0xA2, 0x03, 0x7F, 0x8B, 0x72, 0x2D, - 0x90, 0x79, 0x02, 0xFD, 0x59, 0x36, 0xB2, 0xF3, 0x41, 0x2A, 0x65, 0xAD, 0x75, 0x64, 0x3A, 0x0C, - 0x48, 0xB4, 0x15, 0x35, 0x13, 0xE0, 0xC2, 0xC0, 0x2D, 0xB1, 0x15, 0x95, 0x0C, 0x13, 0x97, 0x59, - 0x73, 0x90, 0x01, 0xF5, 0xAC, 0x36, 0x8D, 0x79, 0x12, 0x40, 0xB8, 0x45, 0x22, 0xB8, 0xF8, 0xC4, - 0x0C, 0x7D, 0xB3, 0x31, 0x96, 0xCF, 0x00, 0x01, 0x76, 0x41, 0x80, 0x4F, 0x0B, 0x80, 0x78, 0x4A, - 0x24, 0x5B, 0x8C, 0x18, 0xDB, 0x8A, 0x0A, 0xF0, 0xC3, 0x15, 0x88, 0x08, 0xF1, 0xC5, 0xC7, 0x3C, - 0x13, 0x40, 0x94, 0x01, 0x81, 0x13, 0x20, 0xA0, 0x23, 0x02, 0x27, 0xE0, 0x58, 0x63, 0x08, 0xD9, - 0xE8, 0x41, 0x81, 0x5B, 0x42, 0x7A, 0x57, 0x86, 0x12, 0x46, 0x26, 0x79, 0x46, 0x06, 0x11, 0x00, - 0x00, 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, - 0x3C, 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, - 0xE4, 0x8C, 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0xA1, - 0x1C, 0x34, 0x1B, 0x24, 0x4A, 0x82, 0xE7, 0x27, 0x85, 0x50, 0x08, 0x0C, 0x3D, 0x12, 0xBC, 0xC4, - 0xA3, 0x18, 0x12, 0x08, 0x14, 0x86, 0xC1, 0x80, 0xC9, 0x31, 0x18, 0x0E, 0x84, 0x81, 0x80, 0xBA, - 0x91, 0x46, 0xB1, 0x51, 0x06, 0xD7, 0x62, 0x40, 0x9A, 0x91, 0xE2, 0x71, 0xA5, 0x37, 0x40, 0x33, - 0xDE, 0xE9, 0xF1, 0xE3, 0xA1, 0x20, 0x10, 0x0E, 0x52, 0x01, 0x63, 0xA9, 0x5E, 0x0C, 0x85, 0x03, - 0x76, 0x7A, 0x7D, 0x0B, 0x4E, 0x03, 0x75, 0x78, 0x77, 0x78, 0x06, 0x84, 0x51, 0x37, 0x8A, 0x77, - 0x02, 0x51, 0x6A, 0x05, 0x02, 0x04, 0x67, 0x67, 0x5B, 0x72, 0x47, 0x98, 0x98, 0x7C, 0x5C, 0x73, - 0x66, 0x58, 0x07, 0x8B, 0x0F, 0x00, 0x9F, 0x45, 0x02, 0x01, 0x03, 0xA3, 0x0C, 0x89, 0x03, 0x06, - 0x02, 0x00, 0x5C, 0x06, 0x01, 0x92, 0x52, 0x07, 0xAE, 0x59, 0x03, 0x00, 0xBD, 0xBD, 0x4C, 0x02, - 0x05, 0xAB, 0xB9, 0x70, 0x0C, 0xAC, 0x96, 0x00, 0x52, 0x45, 0x36, 0xC1, 0x51, 0x97, 0x0C, 0x66, - 0x5E, 0x00, 0x8C, 0x4C, 0x0A, 0x05, 0x5F, 0x68, 0x98, 0x4E, 0x56, 0x40, 0x7F, 0x3D, 0x67, 0x97, - 0x9D, 0x73, 0x39, 0x02, 0x74, 0x9C, 0x48, 0xA4, 0x76, 0x76, 0x66, 0x73, 0xA8, 0x2C, 0x05, 0x50, - 0x02, 0xA3, 0xA3, 0x59, 0x78, 0x5E, 0x92, 0xD4, 0x2C, 0xDB, 0xB0, 0x59, 0x76, 0x07, 0x00, 0x78, - 0x16, 0x09, 0x80, 0xF5, 0xE4, 0x05, 0xC1, 0x81, 0x5F, 0xB0, 0x10, 0x00, 0xA0, 0xEE, 0xC0, 0xC0, - 0x03, 0x8E, 0x68, 0x68, 0xB1, 0x72, 0xE5, 0x92, 0xAF, 0x5E, 0xF6, 0x0C, 0x10, 0xF0, 0x86, 0x62, - 0xFB, 0xCE, 0xC1, 0x03, 0x98, 0x00, 0x74, 0x42, 0x42, 0xE7, 0xC5, 0xB9, 0x4E, 0xFF, 0xC2, 0x9D, - 0x99, 0xA3, 0x60, 0x0A, 0x0A, 0x03, 0xED, 0xC0, 0xDD, 0xF1, 0x47, 0xCF, 0xCB, 0x2E, 0x97, 0x20, - 0x92, 0x0D, 0x64, 0x85, 0xA5, 0x65, 0x43, 0x2C, 0x3C, 0x19, 0x10, 0x30, 0x94, 0x2F, 0x27, 0xBE, - 0x9D, 0x87, 0x78, 0xCE, 0x54, 0x47, 0xC0, 0x98, 0xC6, 0x9D, 0x39, 0x2F, 0xC6, 0xB2, 0xF1, 0x87, - 0x29, 0x96, 0x62, 0xC6, 0xB6, 0x69, 0xE2, 0xC0, 0x2B, 0x4A, 0x2C, 0x58, 0x49, 0x47, 0xDA, 0x11, - 0x6A, 0x69, 0xC0, 0xB8, 0x10, 0x22, 0x1F, 0xDC, 0x0A, 0xF4, 0x6D, 0x64, 0x02, 0x06, 0xB1, 0x04, - 0x28, 0x39, 0xBB, 0xA1, 0xDD, 0x49, 0x4C, 0xE9, 0xD4, 0xB9, 0x4D, 0x0A, 0xA2, 0x40, 0x81, 0x91, - 0x81, 0x68, 0x2E, 0x35, 0x43, 0xA0, 0xC0, 0x50, 0x05, 0x1F, 0x6A, 0x39, 0xB9, 0x65, 0x47, 0x4A, - 0xBF, 0xBC, 0xF4, 0xF0, 0x04, 0xE3, 0x98, 0xA1, 0x96, 0x02, 0x5B, 0x5E, 0x71, 0xA5, 0x53, 0xA8, - 0x4E, 0x68, 0x16, 0x2B, 0x01, 0xFC, 0x42, 0x29, 0x4A, 0x21, 0xF4, 0xE8, 0x87, 0x0A, 0xA5, 0x04, - 0xDA, 0xDC, 0x94, 0x95, 0x6A, 0x03, 0xC2, 0x5A, 0x6E, 0xF0, 0x66, 0xC8, 0x0E, 0xC0, 0x99, 0x20, - 0xDF, 0x16, 0x93, 0xAC, 0x91, 0x64, 0x16, 0x0B, 0xED, 0x14, 0x70, 0xF2, 0xC2, 0x6B, 0x75, 0x27, - 0x68, 0x81, 0xDA, 0x90, 0xB4, 0x0B, 0xDC, 0x74, 0xC8, 0x8B, 0x67, 0xB0, 0xBC, 0x75, 0x2B, 0xCC, - 0x5D, 0xA1, 0x00, 0xD8, 0x09, 0xC4, 0x3D, 0x23, 0x92, 0xB0, 0x6B, 0x29, 0xDA, 0x6A, 0x55, 0x12, - 0x46, 0x7A, 0x41, 0xA5, 0x81, 0xF8, 0x62, 0x25, 0xE8, 0x4E, 0x2A, 0x60, 0x22, 0x52, 0x05, 0xB4, - 0xB4, 0x94, 0x14, 0xAC, 0x12, 0x05, 0xBF, 0xCD, 0xB4, 0x60, 0xA7, 0x6F, 0x66, 0x65, 0xE7, 0x57, - 0xC7, 0xA3, 0xC8, 0x67, 0x85, 0x16, 0x5B, 0x49, 0xF0, 0x84, 0x2A, 0x48, 0x19, 0x92, 0x47, 0x30, - 0x4E, 0x00, 0x60, 0xC9, 0x57, 0x71, 0x79, 0x03, 0x51, 0x30, 0xD3, 0x4C, 0xA0, 0xC0, 0x4E, 0xA4, - 0x1C, 0x45, 0x51, 0x2C, 0x7E, 0x39, 0xB8, 0x18, 0x3E, 0x04, 0xB5, 0x04, 0x14, 0x6C, 0xB3, 0xF8, - 0xF1, 0xC7, 0x3C, 0x00, 0xAA, 0xC6, 0xCB, 0x45, 0xFC, 0x21, 0xD5, 0x52, 0x72, 0x17, 0x95, 0x88, - 0xD8, 0x09, 0x08, 0x00, 0x80, 0x00, 0x02, 0x28, 0x94, 0x28, 0xC1, 0x8C, 0x20, 0x20, 0xD1, 0x5D, - 0x02, 0x27, 0xE8, 0x88, 0x82, 0x5B, 0x84, 0x2C, 0xE0, 0xD6, 0x19, 0x4C, 0x1C, 0xA9, 0xA4, 0x19, - 0x1B, 0x44, 0x00, 0x00, 0x21, 0xFE, 0x19, 0x42, 0x6F, 0x79, 0x27, 0x73, 0x20, 0x48, 0x61, 0x70, - 0x70, 0x79, 0x20, 0x48, 0x6F, 0x6C, 0x69, 0x64, 0x61, 0x79, 0x73, 0x20, 0x50, 0x61, 0x67, 0x65, - 0x00, 0x3B - -}; - -static const uint8_t bird_gif[] PROGMEM = { - 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x74, 0x00, 0x4E, 0x00, 0xCC, 0x13, 0x00, 0xFF, 0xFF, 0xFF, - 0xEF, 0xFF, 0xFF, 0xBD, 0xE7, 0xE7, 0xD6, 0xEF, 0xEF, 0x63, 0x63, 0x63, 0xAD, 0xAD, 0xAD, 0xCE, - 0xCE, 0xCE, 0xD6, 0xDE, 0xDE, 0x4A, 0x4A, 0x4A, 0x7B, 0x84, 0x84, 0x94, 0x9C, 0x9C, 0xE7, 0xE7, - 0xE7, 0x84, 0x94, 0x94, 0xB5, 0xC6, 0xC6, 0x73, 0x7B, 0x7B, 0x31, 0x31, 0x31, 0xF7, 0xF7, 0xF7, - 0x18, 0x10, 0x10, 0xCE, 0x63, 0x39, 0x6B, 0x39, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xFF, 0x0B, - 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x4B, - 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0xAE, 0xEC, 0x68, 0x2C, - 0x6D, 0x2C, 0xCF, 0x74, 0x6D, 0x03, 0x46, 0x84, 0x40, 0x77, 0xEF, 0xFF, 0x40, 0x51, 0x42, 0x41, - 0x0C, 0x1A, 0x8F, 0x48, 0x13, 0xC1, 0xD0, 0x20, 0x00, 0x0E, 0x8E, 0x42, 0x72, 0x4A, 0xAD, 0x21, - 0x0E, 0xCD, 0x05, 0xE1, 0x80, 0xA8, 0x7A, 0xBF, 0x29, 0xC2, 0xA0, 0x91, 0x28, 0x34, 0x02, 0x5D, - 0xB0, 0x5A, 0xFD, 0x08, 0x34, 0x14, 0x84, 0x00, 0x7A, 0x4D, 0xF7, 0x22, 0xDC, 0x89, 0xB8, 0xC1, - 0xB9, 0x80, 0xD5, 0xFF, 0x40, 0x0B, 0x77, 0x0C, 0x0F, 0x05, 0x01, 0x0C, 0x0A, 0x0B, 0x0F, 0x08, - 0x06, 0x80, 0x8E, 0x37, 0x7B, 0x01, 0x09, 0x11, 0x03, 0x68, 0x5C, 0x4C, 0x0A, 0x8F, 0x9A, 0x33, - 0x06, 0x09, 0x01, 0x0E, 0x71, 0x68, 0x88, 0x92, 0x07, 0x9B, 0xA6, 0x2C, 0x0A, 0x86, 0x07, 0x95, - 0x05, 0x04, 0xA1, 0x5D, 0x8D, 0xA7, 0xB2, 0x26, 0x09, 0x06, 0x72, 0x72, 0x0E, 0x94, 0x01, 0xA9, - 0x04, 0x08, 0x52, 0xB3, 0xC0, 0x00, 0x09, 0x95, 0xB7, 0x0D, 0x86, 0x01, 0x04, 0x0A, 0xC3, 0x09, - 0x34, 0x43, 0xC1, 0x54, 0x0E, 0xB7, 0xD2, 0x87, 0xAE, 0xBB, 0x99, 0x32, 0x7B, 0x0E, 0xCF, 0x49, - 0x0B, 0xD1, 0xD3, 0x72, 0x0C, 0xDE, 0x57, 0x33, 0xBE, 0xCC, 0xDB, 0x47, 0x05, 0x0C, 0xDF, 0xD3, - 0x05, 0xD7, 0x31, 0x0C, 0xE1, 0xA5, 0xE7, 0x46, 0xBE, 0xEB, 0xD2, 0x04, 0x05, 0xBF, 0x2C, 0x5C, - 0x4D, 0xF3, 0x46, 0x0B, 0x11, 0x56, 0xD9, 0x3B, 0x14, 0x01, 0x14, 0x0F, 0x16, 0x04, 0x1A, 0x30, - 0x28, 0x00, 0x81, 0xA1, 0x3F, 0x1F, 0xAD, 0x02, 0x10, 0x5B, 0x87, 0x6F, 0x0E, 0x8B, 0x02, 0x0E, - 0x04, 0x5C, 0x41, 0x10, 0xF0, 0x61, 0x8F, 0x25, 0x03, 0x26, 0xDA, 0x43, 0xC4, 0x42, 0x8B, 0x00, - 0x05, 0x0E, 0x7C, 0xFF, 0xED, 0xF0, 0x68, 0x83, 0x8B, 0x44, 0x91, 0xDF, 0x06, 0xAC, 0x54, 0x01, - 0x21, 0xA1, 0x80, 0x07, 0x0F, 0x1A, 0x38, 0x70, 0xC7, 0x72, 0x46, 0xC2, 0x97, 0x03, 0x3F, 0xC5, - 0x52, 0xE1, 0x80, 0x81, 0x00, 0x01, 0x19, 0x1B, 0x3C, 0x38, 0xD8, 0x53, 0xC6, 0x81, 0x38, 0x21, - 0x61, 0x4A, 0xEB, 0xB7, 0x42, 0x01, 0x82, 0xA3, 0x58, 0x7D, 0xC9, 0x6B, 0x1A, 0x63, 0x0B, 0xD0, - 0x81, 0x11, 0x08, 0x74, 0x44, 0x61, 0xE0, 0x01, 0xD6, 0xA3, 0x05, 0x16, 0x2D, 0xE5, 0xDA, 0xC2, - 0x80, 0xB7, 0x90, 0x41, 0xCB, 0xA4, 0x39, 0xC1, 0xEF, 0x2C, 0x56, 0xAA, 0x6C, 0x57, 0x38, 0xA8, - 0x14, 0x35, 0xA8, 0x35, 0x14, 0x10, 0x10, 0x34, 0xB0, 0x9B, 0xD5, 0x4F, 0xDE, 0x14, 0x06, 0x8E, - 0xF5, 0x1D, 0xC8, 0x25, 0x85, 0x83, 0xC1, 0x84, 0x05, 0x20, 0x32, 0x30, 0xF4, 0x30, 0x2D, 0x39, - 0x8B, 0x07, 0x32, 0x42, 0xA1, 0x00, 0x72, 0xE4, 0x45, 0x08, 0x7C, 0x59, 0x36, 0x91, 0x18, 0x73, - 0xE6, 0x6F, 0x79, 0x38, 0x2B, 0x88, 0x7C, 0x54, 0xE7, 0xE0, 0x2D, 0xA3, 0x4B, 0x78, 0x7A, 0x79, - 0x7A, 0x1A, 0xCE, 0x04, 0x4C, 0x85, 0xAC, 0x66, 0x7D, 0x96, 0x80, 0xB9, 0xD8, 0x22, 0x4A, 0x4B, - 0x14, 0x00, 0x97, 0xF1, 0xD3, 0x12, 0x3B, 0x79, 0x9F, 0x45, 0xC0, 0x13, 0xB8, 0xB7, 0xE1, 0xC5, - 0x19, 0x33, 0xEB, 0x53, 0xD3, 0xA8, 0x72, 0x01, 0x0D, 0x44, 0x97, 0x5C, 0x90, 0x7B, 0x9B, 0x01, - 0x05, 0xA6, 0x89, 0xFB, 0x3D, 0x54, 0x20, 0x81, 0xDA, 0x8C, 0xD7, 0x91, 0x16, 0x22, 0x91, 0xF8, - 0x80, 0x9F, 0x86, 0x08, 0x1E, 0xF4, 0xF2, 0xD5, 0x7D, 0x96, 0x18, 0xCC, 0x47, 0xA3, 0xDB, 0x7B, - 0xCA, 0x60, 0x40, 0xCA, 0xF4, 0x58, 0x81, 0xE2, 0x42, 0x04, 0x11, 0x4C, 0x80, 0x53, 0x7C, 0x3F, - 0xC9, 0xB1, 0xC7, 0xFF, 0x7A, 0xC1, 0x18, 0xA0, 0x0E, 0x7E, 0xC4, 0x49, 0xA5, 0x99, 0x67, 0xD7, - 0xA5, 0xB4, 0x15, 0x04, 0x93, 0x48, 0xA0, 0xA1, 0x81, 0x7C, 0x49, 0xB3, 0xC7, 0x38, 0xF6, 0x11, - 0x13, 0x52, 0x7E, 0x12, 0xAE, 0x63, 0xC0, 0x55, 0x00, 0x82, 0x62, 0xD8, 0x08, 0x0B, 0x24, 0xA0, - 0xA1, 0x86, 0x57, 0x3C, 0xF0, 0xE0, 0x2D, 0x05, 0x68, 0x67, 0x4A, 0x27, 0xB7, 0x0C, 0x80, 0x95, - 0x7E, 0x41, 0x11, 0x80, 0x5E, 0x85, 0xBF, 0x9D, 0xD0, 0xC0, 0x04, 0x2F, 0x2E, 0x62, 0xCB, 0x34, - 0x03, 0xE4, 0xB1, 0xA2, 0x23, 0x5E, 0x41, 0xC8, 0x63, 0x50, 0x0E, 0x9A, 0x75, 0x5D, 0x68, 0x5B, - 0x9D, 0xA0, 0x45, 0x04, 0x38, 0x2D, 0x72, 0xCC, 0x34, 0x7B, 0x24, 0xF2, 0x88, 0x5B, 0x39, 0xEA, - 0x18, 0xE1, 0x78, 0xD2, 0x58, 0x05, 0x20, 0x6C, 0x2B, 0xD4, 0x78, 0x64, 0x89, 0x6E, 0xB8, 0xF2, - 0xC2, 0x1F, 0x4D, 0xBE, 0x44, 0x22, 0x99, 0x72, 0xE4, 0x01, 0x60, 0x19, 0x31, 0x68, 0xB1, 0xC4, - 0x78, 0x50, 0xF4, 0xE2, 0x9B, 0x43, 0x5E, 0x80, 0x99, 0xE3, 0x8E, 0x6C, 0x4E, 0xE3, 0x63, 0x7A, - 0xD9, 0x55, 0xD6, 0x82, 0x4E, 0x04, 0x30, 0xD0, 0xC0, 0x01, 0x7C, 0x2A, 0xE4, 0xA3, 0xA2, 0x47, - 0xDC, 0x37, 0xE8, 0x9C, 0xE3, 0xC9, 0x64, 0x9D, 0x72, 0x70, 0x54, 0x29, 0x03, 0x04, 0xDF, 0xE5, - 0xE1, 0x4A, 0x19, 0x06, 0xB0, 0xD9, 0xC4, 0x66, 0x48, 0x7C, 0x27, 0xCD, 0x88, 0x98, 0x92, 0x89, - 0xE2, 0x75, 0x69, 0x2D, 0x69, 0xC3, 0x02, 0x07, 0xA4, 0x03, 0x8A, 0x2B, 0x8E, 0xC2, 0x04, 0x05, - 0x03, 0x48, 0x3C, 0x17, 0x5E, 0xAB, 0x7E, 0x61, 0x04, 0x20, 0x03, 0x33, 0x21, 0x01, 0xC1, 0x02, - 0xDF, 0x81, 0x52, 0x8B, 0x34, 0xAD, 0xC8, 0x6A, 0x43, 0x3E, 0x48, 0x9E, 0xF5, 0x24, 0x45, 0xAF, - 0xF2, 0x96, 0x9D, 0xFF, 0x03, 0xF5, 0x51, 0xD1, 0xA2, 0x03, 0x90, 0xCA, 0xF1, 0x94, 0x3E, 0x37, - 0x68, 0x81, 0xA4, 0x98, 0xC0, 0x9A, 0xF8, 0xC0, 0x8F, 0xCA, 0x39, 0xA0, 0xCD, 0x1F, 0x0B, 0x10, - 0x21, 0x0D, 0x03, 0xB8, 0x7D, 0x74, 0x64, 0x98, 0xD2, 0x16, 0x8A, 0x0C, 0xBA, 0xCA, 0x29, 0xF5, - 0x48, 0x8B, 0x53, 0xA1, 0x19, 0x03, 0xA8, 0x18, 0x85, 0xB2, 0x2A, 0xB9, 0x63, 0x06, 0x45, 0x06, - 0x80, 0x48, 0x05, 0xC9, 0x6E, 0x9C, 0x4F, 0xE1, 0xA3, 0xC2, 0x77, 0xF0, 0x16, 0x95, 0x4B, 0xB7, - 0xF4, 0x12, 0xEA, 0x57, 0x59, 0x14, 0xB2, 0x46, 0x08, 0xB8, 0x8E, 0x08, 0x72, 0x06, 0xB3, 0x3E, - 0xA6, 0xF2, 0x28, 0x46, 0x8B, 0x2C, 0xEB, 0xED, 0x03, 0xF3, 0x56, 0x5C, 0xF0, 0x40, 0xE6, 0xED, - 0xA6, 0x9C, 0x7C, 0xD9, 0x02, 0xA2, 0x48, 0xCA, 0x98, 0x25, 0xD6, 0xCE, 0x4E, 0x14, 0x2B, 0x18, - 0xE7, 0xC0, 0xE5, 0xAE, 0x93, 0x00, 0xC2, 0x45, 0x01, 0xB3, 0xC0, 0x8C, 0x74, 0xFA, 0xF7, 0x80, - 0x84, 0xAC, 0xAE, 0x6C, 0xCF, 0x00, 0x04, 0xA4, 0x47, 0x2C, 0x02, 0xCE, 0x6A, 0xF2, 0x06, 0x9D, - 0x98, 0xE5, 0x3C, 0xB0, 0x98, 0xB5, 0x4D, 0xD3, 0x40, 0x04, 0x05, 0x28, 0x57, 0x40, 0x04, 0x0A, - 0x50, 0x2A, 0x4B, 0x02, 0x1F, 0x53, 0xBD, 0x74, 0x54, 0x59, 0xBF, 0x1B, 0x5A, 0x41, 0xAC, 0x65, - 0xA7, 0xF0, 0x33, 0x0C, 0x58, 0x6D, 0xB6, 0x69, 0x68, 0x4F, 0x2B, 0x87, 0x55, 0xB7, 0x38, 0x50, - 0xC8, 0x5D, 0x7E, 0x8A, 0x1D, 0x0C, 0x04, 0x8F, 0xCD, 0x1D, 0x94, 0xDD, 0x4F, 0xA1, 0xEC, 0xA1, - 0x7C, 0xAD, 0x8D, 0xC5, 0x52, 0x4D, 0xBE, 0x0A, 0x3E, 0x9E, 0x55, 0x32, 0xDA, 0xA3, 0x37, 0x03, - 0xBD, 0x44, 0x3D, 0x8F, 0x55, 0x34, 0x3B, 0x6E, 0x4F, 0x03, 0x99, 0x73, 0x89, 0x93, 0xE5, 0xFE, - 0x74, 0x13, 0xB7, 0xCB, 0xE6, 0xA4, 0x4B, 0x63, 0x90, 0x65, 0xED, 0x16, 0x25, 0x77, 0xE9, 0x54, - 0x67, 0x11, 0xDB, 0x89, 0x44, 0xB3, 0x6E, 0xF6, 0x89, 0x7E, 0x37, 0x05, 0x47, 0xE7, 0xB2, 0xFB, - 0xF5, 0x2D, 0x70, 0xDD, 0x80, 0x37, 0xDE, 0x0A, 0x8E, 0xFB, 0x06, 0x1C, 0x00, 0x4D, 0xE0, 0x1E, - 0x80, 0x0C, 0x73, 0xFB, 0x47, 0x00, 0xE8, 0x2C, 0x89, 0x6E, 0xCF, 0x0C, 0x66, 0x87, 0x64, 0x55, - 0x73, 0x87, 0xB5, 0xD2, 0x39, 0xF2, 0x54, 0xA3, 0xAD, 0x24, 0xEF, 0x09, 0xC4, 0x2E, 0x47, 0x0C, - 0x83, 0x4F, 0x44, 0x6E, 0x25, 0xA9, 0x0C, 0x8F, 0x43, 0xE0, 0xD3, 0xB4, 0x30, 0x50, 0x54, 0xF9, - 0x41, 0x57, 0xC9, 0x63, 0xE6, 0x03, 0x00, 0xC1, 0xED, 0xE9, 0xAB, 0x60, 0x4F, 0x62, 0x94, 0x41, - 0x2A, 0xFE, 0x01, 0x56, 0x11, 0x10, 0xB3, 0x65, 0x4F, 0x11, 0xCC, 0x37, 0x4A, 0x10, 0x2C, 0x8E, - 0x3C, 0x80, 0x40, 0x3A, 0x30, 0x20, 0x02, 0x96, 0x10, 0x3F, 0x13, 0x64, 0xA7, 0x1E, 0x17, 0x53, - 0x90, 0x02, 0x28, 0x87, 0x00, 0xB2, 0xC1, 0xE0, 0x29, 0x08, 0x24, 0x50, 0xC9, 0xFE, 0x37, 0x3C, - 0x28, 0x30, 0x67, 0x75, 0x01, 0x9C, 0x20, 0x4E, 0x0A, 0xE0, 0xAC, 0xAF, 0x21, 0x90, 0x3E, 0x0D, - 0x4C, 0x41, 0xBB, 0x42, 0x13, 0x05, 0x63, 0xA4, 0x64, 0x81, 0x43, 0x28, 0x40, 0xED, 0x44, 0x00, - 0x01, 0x2C, 0x78, 0x29, 0x85, 0x2C, 0x38, 0x56, 0x62, 0x1A, 0xC0, 0x1D, 0x35, 0x84, 0x00, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, - 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, - 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, - 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, - 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, - 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, - 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, - 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, - 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, - 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, - 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, - 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, - 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, - 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, - 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, - 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, - 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, - 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, - 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, - 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, - 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, - 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, - 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, - 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, - 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, - 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, - 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, - 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, - 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, - 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, - 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, - 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, - 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, - 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, - 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, - 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, - 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, - 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, - 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, - 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, - 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, - 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, - 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, - 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, - 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, - 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, - 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, - 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, - 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, - 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, - 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, - 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, - 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, - 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, - 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, - 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, - 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, - 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, - 0x0D, 0x21, 0x00, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, - 0x00, 0x6A, 0x00, 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, - 0xAE, 0x6C, 0xEB, 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, - 0x0A, 0xC7, 0x03, 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, - 0xA4, 0x10, 0xA8, 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, - 0x9E, 0x18, 0x02, 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, - 0xD4, 0x81, 0x01, 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, - 0x0D, 0x08, 0x05, 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, - 0x04, 0x06, 0x10, 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, - 0x93, 0x09, 0x0C, 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, - 0x0C, 0x39, 0x9A, 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, - 0xAB, 0x5B, 0x4A, 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, - 0x0D, 0x0D, 0x07, 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, - 0x0E, 0x7B, 0x04, 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, - 0x92, 0x0C, 0x0E, 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, - 0x5B, 0x03, 0x0E, 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, - 0x98, 0xBE, 0x73, 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, - 0xB0, 0x6A, 0xA3, 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, - 0xBC, 0xA5, 0x0C, 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, - 0x04, 0x32, 0x53, 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, - 0x67, 0x8E, 0xA2, 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, - 0x33, 0xA0, 0x2B, 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, - 0x0E, 0x10, 0xC0, 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, - 0x0A, 0x08, 0xF8, 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, - 0x1D, 0x8A, 0x47, 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, - 0x22, 0x22, 0x82, 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, - 0x6B, 0x50, 0xE0, 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, - 0xA3, 0x2D, 0x60, 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, - 0x94, 0x14, 0x7F, 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, - 0x05, 0x30, 0x4A, 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, - 0x53, 0x20, 0xC1, 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, - 0x10, 0x03, 0x80, 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, - 0x26, 0x0F, 0x28, 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, - 0xC6, 0x0A, 0x02, 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, - 0xA0, 0xC0, 0x28, 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, - 0x42, 0x01, 0x5A, 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, - 0x88, 0x33, 0x14, 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, - 0x6A, 0xC4, 0x80, 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, - 0x28, 0xC2, 0xE2, 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, - 0x21, 0xA4, 0x0C, 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, - 0x4A, 0x93, 0x29, 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, - 0x94, 0x0C, 0x38, 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, - 0x56, 0x74, 0x54, 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, - 0x99, 0x83, 0x8A, 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, - 0x10, 0x02, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, - 0x6A, 0x00, 0x2E, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x00, 0x40, 0x62, 0xB9, 0x28, 0x08, 0x41, 0x28, - 0x4B, 0xE9, 0xBE, 0x70, 0x2C, 0xCF, 0x74, 0x6D, 0xDF, 0xE5, 0xF1, 0x3C, 0x69, 0x52, 0x24, 0x0F, - 0x82, 0xE1, 0x60, 0x00, 0x26, 0x5A, 0xB8, 0xA4, 0x72, 0xC9, 0x94, 0xE9, 0x22, 0x12, 0xC9, 0x64, - 0xF2, 0x18, 0x04, 0xAE, 0xD7, 0x01, 0xB0, 0xD0, 0xEC, 0x7A, 0xBF, 0x31, 0x48, 0x61, 0x12, 0x95, - 0x32, 0x02, 0x8E, 0x06, 0x36, 0x70, 0x50, 0x21, 0xC1, 0xF0, 0x78, 0x72, 0x91, 0x20, 0x4B, 0x55, - 0x85, 0xF5, 0xB5, 0x81, 0xE0, 0xCA, 0xFF, 0x80, 0x32, 0x0D, 0x0F, 0x53, 0x11, 0x11, 0x04, 0x07, - 0x7A, 0x57, 0x0E, 0x04, 0x6F, 0x81, 0x8F, 0x7F, 0x0B, 0x2A, 0x06, 0x94, 0x6A, 0x8A, 0x01, 0x06, - 0x04, 0x05, 0x07, 0x0B, 0x0B, 0x44, 0x94, 0xA0, 0x43, 0x24, 0x90, 0xA4, 0x37, 0x05, 0x04, 0x96, - 0x97, 0x58, 0x45, 0x09, 0x0A, 0x0C, 0x0C, 0x0A, 0x05, 0x0D, 0xB3, 0x05, 0x0A, 0x09, 0x0C, 0x05, - 0x06, 0xA3, 0x4D, 0x9F, 0xA0, 0x0B, 0xBB, 0xA5, 0x33, 0x6D, 0x08, 0x0C, 0x89, 0xAA, 0xC7, 0x8A, - 0x07, 0xAE, 0x3E, 0xC0, 0x32, 0x10, 0x07, 0x3F, 0x2A, 0x0E, 0x8C, 0x2A, 0x08, 0xD6, 0x29, 0x0E, - 0xB9, 0xCD, 0xC1, 0x22, 0x10, 0x45, 0xD2, 0xB8, 0x07, 0x56, 0x97, 0x22, 0xC8, 0x01, 0x0D, 0x0C, - 0x3E, 0x9C, 0x25, 0xCF, 0xA7, 0x04, 0xD9, 0xE2, 0xC8, 0x03, 0xD0, 0x09, 0x04, 0xD6, 0x09, 0xBA, - 0xDC, 0x30, 0x10, 0x0B, 0x06, 0xB6, 0x2A, 0x04, 0x12, 0xDC, 0x52, 0x40, 0x90, 0x60, 0x81, 0x5C, - 0x07, 0x20, 0xA8, 0x1A, 0xD0, 0x20, 0x01, 0x35, 0x07, 0x3C, 0x1C, 0x18, 0x30, 0x87, 0xCC, 0x00, - 0x03, 0x02, 0x0F, 0x12, 0x34, 0xD8, 0xA6, 0xCF, 0x44, 0xA7, 0x8F, 0x9D, 0x0E, 0x88, 0xAC, 0x75, - 0x6B, 0x22, 0xC5, 0x4B, 0x44, 0x4E, 0xFF, 0x26, 0x63, 0x80, 0x20, 0xE3, 0x81, 0x8E, 0x5D, 0x0E, - 0xA4, 0x33, 0xA6, 0x92, 0x8D, 0x03, 0x04, 0x35, 0x2F, 0x35, 0xC0, 0x98, 0xE0, 0x25, 0x4C, 0x26, - 0x07, 0x7C, 0xE4, 0xBC, 0x82, 0x40, 0xE1, 0x50, 0x3D, 0xCA, 0x52, 0x38, 0xFA, 0x89, 0xE3, 0x47, - 0xCE, 0x1F, 0x00, 0x8E, 0xAA, 0x02, 0xC2, 0x80, 0xE9, 0x92, 0x86, 0x2A, 0x0D, 0x3C, 0xA0, 0x29, - 0x55, 0xD1, 0x00, 0x8C, 0x06, 0xAC, 0x26, 0x31, 0x80, 0xC0, 0x24, 0x32, 0x04, 0x09, 0xBA, 0x9A, - 0x1B, 0x94, 0x80, 0xA3, 0x58, 0x18, 0x5A, 0xCF, 0x1C, 0x13, 0x78, 0x69, 0x9C, 0xDA, 0x2C, 0x04, - 0x22, 0x34, 0x78, 0x6B, 0x03, 0x82, 0x02, 0x44, 0x97, 0x5E, 0xD5, 0x1D, 0x60, 0xF7, 0xEE, 0xB9, - 0x07, 0x61, 0xF9, 0xD6, 0x58, 0xC0, 0x20, 0xDB, 0x1A, 0x82, 0x0B, 0x09, 0x17, 0xBE, 0xFB, 0x55, - 0x81, 0xE2, 0x1B, 0x99, 0x10, 0x39, 0xF6, 0x2A, 0x99, 0xB0, 0x61, 0x3D, 0x0E, 0x2F, 0xDF, 0x18, - 0x94, 0x87, 0xF3, 0x00, 0x01, 0x02, 0x24, 0x7F, 0x7E, 0x8C, 0x60, 0xA9, 0x68, 0x17, 0x6D, 0xCC, - 0x62, 0x91, 0x8C, 0x1A, 0x75, 0xE7, 0x2B, 0x30, 0xBA, 0xF2, 0xF1, 0xF9, 0xDA, 0x45, 0x26, 0xAE, - 0x59, 0x4E, 0xD7, 0x4E, 0xED, 0x19, 0xF7, 0x8C, 0xA3, 0x5A, 0xF7, 0xF6, 0x16, 0xF1, 0xC3, 0x68, - 0x70, 0xE1, 0xC3, 0x8B, 0xAF, 0xA1, 0x31, 0xF4, 0xB4, 0xD2, 0xD7, 0x10, 0x60, 0xE9, 0x21, 0x3C, - 0x3C, 0xFA, 0x64, 0xE3, 0x32, 0x6A, 0xD2, 0x56, 0xF0, 0xC0, 0x0F, 0x5F, 0x3A, 0xA9, 0x02, 0x70, - 0xEF, 0x4E, 0x5C, 0x3A, 0x68, 0xD7, 0xE5, 0x54, 0x72, 0xB7, 0xF2, 0xD5, 0xBC, 0xD5, 0xA0, 0x34, - 0xD7, 0xDB, 0x6E, 0xAF, 0x5A, 0x95, 0x03, 0xDE, 0x2F, 0x98, 0x73, 0xDB, 0x70, 0x01, 0xC4, 0xF2, - 0x96, 0x45, 0xB3, 0x41, 0x67, 0x5B, 0xFF, 0x7F, 0xE6, 0x00, 0x20, 0x51, 0x0C, 0xF2, 0xD0, 0x47, - 0x9C, 0x7A, 0xEA, 0x91, 0x07, 0x20, 0x4C, 0x05, 0xC8, 0xA5, 0x9E, 0x70, 0xA7, 0x31, 0x78, 0x92, - 0x24, 0x89, 0xB9, 0x70, 0x4C, 0x26, 0x41, 0x04, 0xA4, 0x40, 0x03, 0x19, 0x32, 0x72, 0xC8, 0x85, - 0x1D, 0xB9, 0x92, 0x20, 0x7F, 0xEE, 0x9D, 0x94, 0xE1, 0x49, 0x0C, 0xDD, 0x84, 0x16, 0x79, 0x11, - 0xF4, 0x11, 0x0B, 0x42, 0x62, 0x41, 0x70, 0xCB, 0x73, 0x1E, 0x0E, 0xE5, 0x20, 0x70, 0x7B, 0x10, - 0x40, 0x58, 0x5E, 0xC4, 0xE4, 0x23, 0x42, 0x02, 0x86, 0x34, 0xA2, 0x98, 0x24, 0x0A, 0x00, 0x19, - 0x63, 0x4E, 0xFD, 0x10, 0x43, 0x93, 0x32, 0x79, 0xF1, 0x90, 0x42, 0x88, 0x2E, 0x2C, 0xF0, 0x80, - 0x21, 0x0F, 0x30, 0x00, 0x5F, 0x30, 0x62, 0xF4, 0xB1, 0x61, 0x90, 0x47, 0x39, 0x18, 0xCB, 0x3F, - 0xEF, 0xF8, 0x60, 0xC0, 0x2F, 0x36, 0x3C, 0xB1, 0x22, 0x53, 0x99, 0x20, 0x90, 0x08, 0x9A, 0x5D, - 0x79, 0xD9, 0x80, 0x00, 0x29, 0xB4, 0xD6, 0x04, 0x59, 0x2C, 0xFC, 0x24, 0x13, 0x2A, 0x78, 0x76, - 0xF5, 0x95, 0x03, 0x0C, 0xA0, 0xA6, 0xA3, 0x17, 0x6E, 0x3D, 0xB2, 0xC0, 0x0F, 0x0A, 0x10, 0xB9, - 0xDA, 0x39, 0x08, 0x08, 0x90, 0x86, 0x00, 0x4E, 0x2E, 0x17, 0x86, 0x3B, 0xA5, 0x4D, 0xAA, 0x87, - 0x42, 0xAF, 0x0C, 0xE2, 0x00, 0xA6, 0x63, 0x8A, 0xF6, 0xA8, 0x0A, 0x91, 0x06, 0xF0, 0x4B, 0x9E, - 0xCE, 0x29, 0xF2, 0x17, 0x4B, 0x96, 0x16, 0x50, 0xA9, 0x9F, 0x9A, 0x02, 0x50, 0x00, 0x23, 0x81, - 0x9E, 0x1A, 0x41, 0x94, 0x47, 0x31, 0x10, 0xE6, 0x01, 0xD3, 0x98, 0xA5, 0x10, 0x2A, 0x2D, 0xF1, - 0x21, 0x46, 0x40, 0xB5, 0xDA, 0x8A, 0xD8, 0x02, 0x0D, 0x21, 0x9A, 0x80, 0x99, 0x98, 0xE0, 0x63, - 0xCE, 0x10, 0x01, 0xC8, 0x7A, 0xC2, 0x79, 0x11, 0x50, 0x65, 0x26, 0x2B, 0x9F, 0x64, 0xF9, 0xD1, - 0xE8, 0x93, 0x29, 0x32, 0x30, 0x84, 0x03, 0x0A, 0x28, 0x04, 0x2C, 0x46, 0x0B, 0x5C, 0x91, 0xAE, - 0x22, 0x64, 0x21, 0xB0, 0x13, 0x30, 0x99, 0xDC, 0xB4, 0xD3, 0xB3, 0xE9, 0x00, 0x50, 0x6A, 0xB2, - 0x00, 0xB4, 0xD1, 0x42, 0x50, 0x42, 0x00, 0xF6, 0x55, 0x51, 0xAA, 0x6A, 0x82, 0x09, 0x22, 0x08, - 0x38, 0xB0, 0x4D, 0xB7, 0x88, 0x2C, 0x60, 0x0D, 0x8B, 0xF8, 0xBE, 0x90, 0x89, 0x02, 0x0E, 0xE0, - 0x03, 0x81, 0xC0, 0x99, 0xDC, 0xAA, 0x2A, 0x44, 0xB3, 0xF8, 0xE9, 0x16, 0x04, 0x08, 0xD8, 0xC2, - 0x1C, 0x97, 0x0D, 0xCB, 0xE0, 0xC9, 0x28, 0x3A, 0x28, 0xF3, 0x5F, 0x6B, 0xBF, 0xD9, 0x72, 0xC4, - 0x62, 0x1D, 0x7F, 0x1B, 0x72, 0x0D, 0xCA, 0xBC, 0xD4, 0x86, 0x2D, 0x3E, 0xB9, 0xBC, 0x5C, 0x08, - 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, 0x6A, 0x00, - 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, 0xAE, 0x6C, 0xEB, - 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, 0x0A, 0xC7, 0x03, - 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, 0xA4, 0x10, 0xA8, - 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, 0x9E, 0x18, 0x02, - 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, 0xD4, 0x81, 0x01, - 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, 0x0D, 0x08, 0x05, - 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, 0x04, 0x06, 0x10, - 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, 0x93, 0x09, 0x0C, - 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, 0x0C, 0x39, 0x9A, - 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, 0xAB, 0x5B, 0x4A, - 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, 0x0D, 0x0D, 0x07, - 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, 0x0E, 0x7B, 0x04, - 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, 0x92, 0x0C, 0x0E, - 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, 0x5B, 0x03, 0x0E, - 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, 0x98, 0xBE, 0x73, - 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, 0xB0, 0x6A, 0xA3, - 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, 0xBC, 0xA5, 0x0C, - 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, 0x04, 0x32, 0x53, - 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, 0x67, 0x8E, 0xA2, - 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, 0x33, 0xA0, 0x2B, - 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, 0x0E, 0x10, 0xC0, - 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, 0x0A, 0x08, 0xF8, - 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, 0x1D, 0x8A, 0x47, - 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, 0x22, 0x22, 0x82, - 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, 0x6B, 0x50, 0xE0, - 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, 0xA3, 0x2D, 0x60, - 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, 0x94, 0x14, 0x7F, - 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, 0x05, 0x30, 0x4A, - 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, 0x53, 0x20, 0xC1, - 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, 0x10, 0x03, 0x80, - 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, 0x26, 0x0F, 0x28, - 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, 0xC6, 0x0A, 0x02, - 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, 0xA0, 0xC0, 0x28, - 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, 0x42, 0x01, 0x5A, - 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, 0x88, 0x33, 0x14, - 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, 0x6A, 0xC4, 0x80, - 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, 0x28, 0xC2, 0xE2, - 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, 0x21, 0xA4, 0x0C, - 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, 0x4A, 0x93, 0x29, - 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, 0x94, 0x0C, 0x38, - 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, 0x56, 0x74, 0x54, - 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, 0x99, 0x83, 0x8A, - 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, 0x10, 0x02, 0x00, - 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, - 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, - 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, - 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, - 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, - 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, - 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, - 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, - 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, - 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, - 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, - 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, - 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, - 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, - 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, - 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, - 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, - 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, - 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, - 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, - 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, - 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, - 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, - 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, - 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, - 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, - 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, - 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, - 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, - 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, - 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, - 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, - 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, - 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, - 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, - 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, - 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, - 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, - 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, - 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, - 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, - 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, - 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, - 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, - 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, - 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, - 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, - 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, - 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, - 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, - 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, - 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, - 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, - 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, - 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, - 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, - 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, - 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, - 0x0D, 0x21, 0x00, 0x00, 0x3B}; +#include + +static const uint8_t firebase_png[] PROGMEM = { + 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A, 0x00, 0x00, 0x00, 0x0D, 0x49, 0x48, 0x44, 0x52, + 0x00, 0x00, 0x03, 0x20, 0x00, 0x00, 0x02, 0x58, 0x08, 0x06, 0x00, 0x00, 0x00, 0x9A, 0x76, 0x82, + 0x70, 0x00, 0x00, 0x00, 0x01, 0x73, 0x52, 0x47, 0x42, 0x00, 0xAE, 0xCE, 0x1C, 0xE9, 0x00, 0x00, + 0x00, 0x04, 0x67, 0x41, 0x4D, 0x41, 0x00, 0x00, 0xB1, 0x8F, 0x0B, 0xFC, 0x61, 0x05, 0x00, 0x00, + 0x00, 0x09, 0x70, 0x48, 0x59, 0x73, 0x00, 0x00, 0x0E, 0xC3, 0x00, 0x00, 0x0E, 0xC3, 0x01, 0xC7, + 0x6F, 0xA8, 0x64, 0x00, 0x00, 0x55, 0x14, 0x49, 0x44, 0x41, 0x54, 0x78, 0x5E, 0xED, 0xDD, 0x59, + 0x90, 0x1D, 0xF5, 0x81, 0xE7, 0x7B, 0x3F, 0xF4, 0xC3, 0x84, 0x91, 0x40, 0x6E, 0xEF, 0xC6, 0x8B, + 0x30, 0x92, 0x4A, 0x1B, 0x58, 0x98, 0xCD, 0xA0, 0xA5, 0x4A, 0x12, 0x20, 0x6C, 0x9A, 0xB6, 0xBA, + 0x01, 0x63, 0x4F, 0x3F, 0x8C, 0x1E, 0x26, 0xC2, 0xF7, 0xE5, 0xC6, 0x25, 0xE2, 0xDE, 0x97, 0x3B, + 0x7D, 0x67, 0xAC, 0x6E, 0x63, 0x63, 0x83, 0x8D, 0xBC, 0xB1, 0x99, 0xA5, 0x10, 0x08, 0xED, 0x52, + 0x69, 0xAD, 0x92, 0xA0, 0xBB, 0xAB, 0xA7, 0xED, 0x6E, 0x77, 0xB7, 0x81, 0x42, 0x9B, 0x99, 0x89, + 0x89, 0xDB, 0x9A, 0xB9, 0x0E, 0x2F, 0x2C, 0x76, 0x61, 0x16, 0x49, 0x85, 0xA4, 0xFC, 0xDF, 0xFF, + 0x3F, 0x4F, 0xE6, 0xA9, 0x3C, 0x79, 0x7E, 0xE7, 0x9C, 0xCC, 0x3C, 0x99, 0x75, 0xCE, 0xC9, 0xFA, + 0x7E, 0x22, 0x7E, 0xA1, 0x6E, 0x2F, 0x42, 0xC2, 0x94, 0xE2, 0xFF, 0x8D, 0x7F, 0x65, 0x9E, 0xF7, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x28, 0x82, 0x79, 0x6E, 0xCD, 0x80, 0xBF, 0xC3, 0x5F, 0x58, 0x12, 0xFC, + 0x4B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x1F, 0x73, 0x78, 0xCD, 0x3A, 0xEF, 0xB9, 0x35, 0x63, 0xE6, + 0xB9, 0x9B, 0x4D, 0x75, 0xCF, 0xAE, 0xF1, 0xE7, 0x3D, 0x7B, 0xD3, 0xA0, 0x0B, 0x92, 0xE0, 0x3F, + 0x0A, 0x00, 0x00, 0x00, 0x00, 0xD9, 0x98, 0x91, 0x35, 0xB3, 0xEB, 0xC2, 0x23, 0x12, 0x1F, 0xD1, + 0x79, 0x87, 0xD7, 0x6C, 0x08, 0xFE, 0x6B, 0x00, 0x00, 0x00, 0x00, 0x90, 0x8E, 0xFB, 0x16, 0x2B, + 0xEF, 0xD9, 0x35, 0xE3, 0x95, 0xE0, 0xB8, 0xD1, 0x98, 0x03, 0x57, 0x19, 0xB3, 0x7B, 0xAE, 0x31, + 0x3B, 0x3E, 0x65, 0xCC, 0xB6, 0x8F, 0x1A, 0xB3, 0xF3, 0xD3, 0xC6, 0x0C, 0x2D, 0x34, 0x66, 0x78, + 0xD9, 0x64, 0x84, 0x3C, 0x7B, 0xD3, 0x60, 0xF0, 0x5F, 0x07, 0x00, 0x00, 0x00, 0x80, 0xE4, 0xAA, + 0x37, 0x1F, 0x2E, 0x3C, 0x76, 0x7C, 0xC2, 0x98, 0xED, 0x1F, 0xAB, 0x84, 0x87, 0xDA, 0x2E, 0x1B, + 0x26, 0x87, 0x6F, 0xA8, 0x84, 0xC8, 0xA1, 0x9B, 0xD6, 0x06, 0x3F, 0x05, 0x00, 0x00, 0x00, 0x00, + 0xB4, 0xE6, 0x9E, 0xF9, 0xF0, 0xE3, 0x63, 0xCF, 0xA2, 0x4A, 0x78, 0x34, 0x8B, 0x8F, 0x70, 0xDB, + 0x3F, 0x6E, 0xCC, 0xC8, 0x0A, 0xF7, 0xAD, 0x58, 0xE3, 0x66, 0xB4, 0x7F, 0x56, 0xF0, 0x53, 0x01, + 0x00, 0x00, 0x00, 0x40, 0x73, 0xDE, 0x73, 0x37, 0x9F, 0x34, 0xFB, 0xAF, 0x48, 0x1E, 0x1F, 0xE1, + 0x76, 0x5E, 0x62, 0xCC, 0xE1, 0xD5, 0x76, 0x37, 0xAE, 0x0F, 0x7E, 0x2A, 0x00, 0x00, 0x00, 0x00, + 0x68, 0xCC, 0x3D, 0x78, 0x6E, 0x0E, 0xAF, 0x4A, 0x1F, 0x1F, 0xFE, 0x3E, 0x62, 0xCC, 0xBE, 0xCF, + 0x18, 0xEF, 0xF0, 0x4D, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x68, 0xCD, 0xFF, 0x8C, 0x8F, 0xBD, + 0x97, 0x67, 0x8B, 0x0F, 0xB7, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x20, 0x19, 0x1B, + 0x20, 0xEB, 0xCD, 0xAE, 0x4F, 0xC7, 0xE2, 0xA2, 0xD5, 0x82, 0xF8, 0x08, 0xB7, 0x67, 0xB1, 0x31, + 0xCF, 0xDE, 0x64, 0xDC, 0x6D, 0x4A, 0xF0, 0xD3, 0x02, 0x00, 0x00, 0x00, 0x40, 0x3D, 0xEF, 0xB9, + 0x9B, 0x07, 0x75, 0x64, 0x34, 0x5A, 0x2C, 0x3E, 0xC2, 0x1D, 0x1A, 0xE0, 0xB5, 0xBC, 0x00, 0x00, + 0x00, 0x00, 0x9A, 0xF3, 0x0E, 0x2E, 0x1B, 0xD5, 0xA1, 0xA1, 0x26, 0xC2, 0x23, 0xDC, 0xD0, 0x02, + 0x6E, 0x41, 0x00, 0x00, 0x00, 0x00, 0x34, 0xE7, 0x1D, 0xB8, 0x76, 0x5C, 0xC7, 0x46, 0x7C, 0x22, + 0x3A, 0xE2, 0x1B, 0x59, 0x6E, 0xBC, 0xC3, 0x37, 0x8E, 0x06, 0x3F, 0x35, 0x00, 0x00, 0x00, 0x00, + 0x4C, 0x72, 0x6F, 0xAE, 0x32, 0xFB, 0x96, 0xD8, 0x78, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x0D, 0xB5, + 0x5D, 0x73, 0x2A, 0xB7, 0x20, 0xCF, 0xAD, 0x19, 0x08, 0xFE, 0x12, 0x00, 0x00, 0x00, 0x00, 0x50, + 0xE1, 0xBF, 0x01, 0x6B, 0x77, 0x9F, 0x8D, 0x07, 0x15, 0x1D, 0xE1, 0x44, 0x68, 0x34, 0xDB, 0xF0, + 0xF5, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xE7, 0x7F, 0x02, 0xFA, 0xAE, 0xB9, 0x36, 0x1C, + 0x54, 0x78, 0xB8, 0x89, 0xC0, 0x68, 0xB5, 0x5D, 0x97, 0x1A, 0xF3, 0xEC, 0x8D, 0xC6, 0x3C, 0xB7, + 0x9A, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0x93, 0x6C, 0x80, 0xAC, 0xD7, 0xE1, 0xE1, 0x26, 0xE2, + 0xA2, 0xE5, 0x3E, 0x5C, 0xD9, 0x81, 0xAB, 0x8C, 0xF7, 0xEC, 0x0D, 0x27, 0x83, 0xBF, 0x0C, 0x00, + 0x00, 0x00, 0x00, 0xBC, 0xE7, 0x3D, 0xDE, 0xF0, 0x8A, 0x06, 0x6F, 0xC0, 0x52, 0x71, 0xD1, 0x6A, + 0x41, 0x7C, 0xB8, 0xED, 0xF8, 0x44, 0xE5, 0x16, 0xE4, 0xF0, 0x8D, 0xEB, 0x82, 0xBF, 0x14, 0x00, + 0x00, 0x00, 0x80, 0xE9, 0xCE, 0x3B, 0x70, 0xFD, 0xC9, 0xDC, 0xE3, 0x23, 0x1C, 0xB7, 0x20, 0x00, + 0x00, 0x00, 0x00, 0xA2, 0xCC, 0xFE, 0x2B, 0x6D, 0x2C, 0x14, 0x10, 0x1F, 0x6E, 0xEE, 0x16, 0xE4, + 0xF0, 0x2A, 0x77, 0x0B, 0xB2, 0x3E, 0xF8, 0xCB, 0x01, 0x00, 0x00, 0x00, 0x98, 0xAE, 0x6C, 0x18, + 0x2C, 0x31, 0x7B, 0x2E, 0xB3, 0xB1, 0x50, 0x40, 0x7C, 0x84, 0xDB, 0x77, 0xB9, 0x7B, 0x23, 0xD6, + 0xB8, 0x7B, 0xDD, 0x6F, 0xF0, 0x97, 0x05, 0x00, 0x00, 0x00, 0x30, 0x1D, 0x99, 0x43, 0x37, 0xAD, + 0x9D, 0x7C, 0x03, 0x96, 0x8A, 0x8B, 0x56, 0x13, 0xC1, 0x11, 0xDF, 0xF6, 0x8F, 0x71, 0x0B, 0x02, + 0x00, 0x00, 0x00, 0x20, 0x78, 0x03, 0xD6, 0xF6, 0x8F, 0xDB, 0x50, 0x50, 0x71, 0xD1, 0x6A, 0x22, + 0x36, 0x1A, 0x8D, 0x5B, 0x10, 0x00, 0x00, 0x00, 0x00, 0xDE, 0xB3, 0x37, 0x0D, 0xEA, 0xB8, 0x68, + 0x35, 0x11, 0x19, 0xAD, 0x76, 0xA8, 0xDF, 0x3D, 0x90, 0x3E, 0x18, 0xFC, 0xA5, 0x01, 0x00, 0x00, + 0x00, 0x4C, 0x37, 0xDE, 0x81, 0x6B, 0x46, 0x75, 0x60, 0x34, 0x9B, 0x88, 0x8B, 0x56, 0xDB, 0xFA, + 0x21, 0x63, 0x86, 0xE6, 0x57, 0x5E, 0xCB, 0x3B, 0xB2, 0x66, 0x76, 0xF0, 0x97, 0x07, 0x00, 0x00, + 0x00, 0x30, 0x9D, 0x98, 0x03, 0x57, 0xDB, 0x40, 0x50, 0x91, 0xD1, 0x68, 0x22, 0x2E, 0x5A, 0xCD, + 0xC5, 0x47, 0x38, 0x6E, 0x41, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC9, 0xDD, 0x44, 0x98, 0x7D, 0x9F, + 0xB1, 0x91, 0xA0, 0x42, 0x43, 0x4D, 0xC4, 0x45, 0xAB, 0x45, 0xE3, 0xC3, 0x6D, 0xF7, 0xDC, 0xCA, + 0x2D, 0xC8, 0x73, 0xAB, 0x07, 0x82, 0x5F, 0x06, 0x00, 0x00, 0x00, 0x80, 0xE9, 0xC0, 0x3C, 0xB7, + 0x66, 0xC0, 0xEC, 0x9E, 0x67, 0x43, 0x41, 0xC5, 0x46, 0x7C, 0x22, 0x2E, 0x5A, 0x2D, 0x1E, 0x1F, + 0xE1, 0x86, 0xAF, 0x73, 0x0F, 0xA4, 0x8F, 0x06, 0xBF, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x81, + 0xF7, 0xEC, 0x4D, 0x77, 0x99, 0x9D, 0x97, 0xD8, 0x58, 0x50, 0xC1, 0x11, 0x9D, 0x88, 0x8B, 0x56, + 0x53, 0xE1, 0x11, 0x6E, 0xD7, 0xA7, 0xB9, 0x05, 0x01, 0x00, 0x00, 0x00, 0xA6, 0x1B, 0xEF, 0xF0, + 0x8D, 0x1B, 0x74, 0x70, 0x44, 0x27, 0xE2, 0xA2, 0xD5, 0x54, 0x74, 0xC4, 0xC7, 0x2D, 0x08, 0x00, + 0x00, 0x00, 0x30, 0xBD, 0x78, 0x07, 0xAF, 0x6F, 0xF1, 0x06, 0x2C, 0x11, 0x17, 0xAD, 0xA6, 0x62, + 0x43, 0xCD, 0x7D, 0xF6, 0x88, 0xBB, 0x05, 0x39, 0x7C, 0xE3, 0xBA, 0xE0, 0x97, 0x03, 0x00, 0x00, + 0x00, 0xA0, 0xCC, 0xBC, 0x03, 0xD7, 0x9D, 0xD4, 0xE1, 0xE1, 0x26, 0xE2, 0xA2, 0xD5, 0x54, 0x68, + 0x34, 0xDB, 0xFE, 0x2B, 0xDD, 0x1B, 0xB1, 0x4E, 0x06, 0xBF, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x65, + 0xD6, 0xF8, 0x0D, 0x58, 0x22, 0x2E, 0x5A, 0x4D, 0x05, 0x46, 0xAB, 0xB9, 0x5B, 0x90, 0xC3, 0x37, + 0x70, 0x0B, 0x02, 0x00, 0x00, 0x00, 0x94, 0x9D, 0xFF, 0x06, 0xAC, 0xA1, 0x05, 0x36, 0x1E, 0x3A, + 0x14, 0x1F, 0xFE, 0x3E, 0x68, 0x5C, 0x04, 0x79, 0x87, 0x6E, 0x18, 0x37, 0xA3, 0xFD, 0xB3, 0x82, + 0x5F, 0x1A, 0x00, 0x00, 0x00, 0x80, 0xB2, 0x71, 0xB7, 0x0E, 0x66, 0xD7, 0x1C, 0x1B, 0x10, 0x1D, + 0x8C, 0x0F, 0x37, 0xF7, 0xD7, 0x3D, 0xB4, 0xD2, 0x98, 0xC3, 0xAB, 0xD7, 0x07, 0xBF, 0x34, 0x00, + 0x00, 0x00, 0x00, 0x65, 0x63, 0x03, 0x64, 0xBD, 0xD9, 0x7E, 0x71, 0x25, 0x00, 0x3A, 0x15, 0x1F, + 0xE1, 0xF6, 0x5E, 0xC6, 0x2D, 0x08, 0x00, 0x00, 0x00, 0x50, 0x66, 0xDE, 0xC8, 0xCA, 0xA1, 0xAE, + 0x88, 0x0F, 0xB7, 0xE0, 0x16, 0xC4, 0x3B, 0xBC, 0x7A, 0x43, 0xF0, 0xCB, 0x03, 0x00, 0x00, 0x00, + 0x50, 0x26, 0xDE, 0xC1, 0x6B, 0xC7, 0xBA, 0x22, 0x3E, 0xC2, 0xED, 0xEE, 0xAB, 0x3C, 0x90, 0x3E, + 0xB2, 0x66, 0x76, 0xF0, 0x4B, 0x04, 0x00, 0x00, 0x00, 0x50, 0x16, 0x66, 0xFF, 0x67, 0x75, 0x5C, + 0xB4, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0xD1, 0x11, 0xDF, 0xC8, 0x0A, 0xE3, 0x1D, 0x5A, 0x3D, 0x18, + 0xFC, 0x12, 0x01, 0x00, 0x00, 0x00, 0x94, 0x81, 0xBB, 0x65, 0x30, 0xFB, 0x2E, 0xD7, 0x81, 0xD1, + 0x6C, 0x32, 0x2C, 0x92, 0x4C, 0xC4, 0x86, 0x1A, 0xB7, 0x20, 0x00, 0x00, 0x00, 0x40, 0xF9, 0x98, + 0xE7, 0x56, 0x0F, 0x98, 0x5D, 0x97, 0xEA, 0xC8, 0x68, 0x34, 0x19, 0x16, 0x49, 0x26, 0x42, 0xA3, + 0xD9, 0x0E, 0x7E, 0xCE, 0x78, 0x87, 0x6F, 0x18, 0x0D, 0x7E, 0xA9, 0x00, 0x00, 0x00, 0x00, 0x7A, + 0x9D, 0xFF, 0x06, 0xAC, 0x1D, 0x9F, 0xD0, 0xA1, 0xA1, 0x26, 0xC3, 0x22, 0xC9, 0x44, 0x60, 0xB4, + 0xDA, 0xCE, 0x4B, 0x82, 0x5B, 0x90, 0xD5, 0x03, 0xC1, 0x2F, 0x17, 0x00, 0x00, 0x00, 0x40, 0x2F, + 0xF3, 0x9E, 0xBD, 0x61, 0x50, 0x86, 0x86, 0x9A, 0x0C, 0x8B, 0x24, 0x13, 0x71, 0x91, 0x74, 0x07, + 0xAF, 0x35, 0xDE, 0xE1, 0x55, 0xDC, 0x82, 0x00, 0x00, 0x00, 0x00, 0x65, 0xE0, 0x1D, 0xBC, 0x6E, + 0x54, 0xC6, 0x46, 0x7C, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, 0x6D, 0xF9, 0x80, 0x31, 0x3B, + 0x67, 0xBB, 0x0F, 0x26, 0x34, 0xE6, 0xD0, 0xAA, 0xB5, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, 0x40, + 0xAF, 0xF2, 0x0E, 0x5C, 0x33, 0x2E, 0x83, 0x23, 0x3A, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, + 0x5C, 0x7C, 0x84, 0xDB, 0x77, 0x85, 0xFB, 0x5C, 0x90, 0x93, 0xC1, 0x2F, 0x19, 0x00, 0x00, 0x00, + 0x40, 0x2F, 0x72, 0x9F, 0x36, 0xDE, 0xF2, 0x0D, 0x58, 0x32, 0x2C, 0x92, 0x4C, 0x44, 0x45, 0xD2, + 0x45, 0xE3, 0xC3, 0x6D, 0xDB, 0xC7, 0x2A, 0xB7, 0x20, 0x87, 0x57, 0xAD, 0x0B, 0x7E, 0xE9, 0x00, + 0x00, 0x00, 0x00, 0x7A, 0x8D, 0xFF, 0x06, 0xAC, 0xDD, 0x73, 0xEB, 0xA3, 0x23, 0x9C, 0x0C, 0x8B, + 0x24, 0x13, 0x51, 0x91, 0x74, 0xF1, 0xF8, 0x08, 0xC7, 0x2D, 0x08, 0x00, 0x00, 0x00, 0xD0, 0xDB, + 0xCC, 0xE1, 0x1B, 0xD7, 0x35, 0x7C, 0x05, 0xAF, 0x0C, 0x8B, 0x24, 0x13, 0x51, 0x91, 0x74, 0x2A, + 0x3C, 0xC2, 0x6D, 0xB5, 0xBF, 0xA6, 0x43, 0x03, 0xEE, 0x26, 0x64, 0x7D, 0xF0, 0xCB, 0x07, 0x00, + 0x00, 0x00, 0xD0, 0x4B, 0xFC, 0x57, 0xF0, 0xF6, 0x42, 0x7C, 0x84, 0xDB, 0xB3, 0xD8, 0x7D, 0x3A, + 0xFA, 0xB8, 0xFB, 0xD6, 0xB1, 0xE0, 0xB7, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x57, 0x78, 0xC3, 0xCB, + 0xEB, 0xDF, 0x80, 0x25, 0xC3, 0x22, 0xC9, 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x0D, 0x35, 0x6E, 0x41, + 0x00, 0x00, 0x00, 0x80, 0xDE, 0xE5, 0x1D, 0xBC, 0x76, 0xAC, 0x67, 0xE2, 0x23, 0xDC, 0x9E, 0x45, + 0xC6, 0x3B, 0xB4, 0x6A, 0xDC, 0x8C, 0xF4, 0xCF, 0x0E, 0x7E, 0x1B, 0x00, 0x00, 0x00, 0x00, 0x7A, + 0x81, 0xD9, 0x7F, 0x45, 0x6F, 0xC5, 0x87, 0xBF, 0xF7, 0x1B, 0x33, 0xB2, 0xCC, 0x46, 0xC8, 0xCA, + 0xC1, 0xE0, 0xB7, 0x01, 0x00, 0x00, 0x00, 0xA0, 0xDB, 0x99, 0xC3, 0x37, 0x2E, 0x71, 0xB7, 0x09, + 0x3D, 0x17, 0x1F, 0x6E, 0xEE, 0xCD, 0x5D, 0x87, 0x57, 0xD9, 0x10, 0xE9, 0xCD, 0x5B, 0x10, 0xF7, + 0xEB, 0xB6, 0x1B, 0x08, 0xC6, 0x4D, 0x0E, 0x00, 0x00, 0x00, 0xCA, 0xCF, 0x1C, 0xBA, 0x69, 0xAD, + 0xFF, 0x06, 0x2C, 0x19, 0x16, 0x49, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x5A, 0x10, 0x1F, + 0xE1, 0x7A, 0xEC, 0x16, 0xC4, 0xFF, 0xCC, 0x95, 0x91, 0xFE, 0xF5, 0xDE, 0xA1, 0x81, 0x93, 0xFE, + 0x73, 0x2C, 0x91, 0xF9, 0xFF, 0x9A, 0xFD, 0xF7, 0x78, 0xB8, 0x1E, 0x00, 0x00, 0x00, 0xA5, 0x55, + 0x79, 0x03, 0xD6, 0x47, 0x6D, 0x10, 0xA8, 0xB8, 0x68, 0x35, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, + 0xD5, 0x62, 0xF1, 0xE1, 0xB6, 0xF3, 0x53, 0xC1, 0x2D, 0xC8, 0xEA, 0x81, 0xE0, 0xB7, 0xD4, 0xB5, + 0xCC, 0xA1, 0xFE, 0xB5, 0xDE, 0xC8, 0xC0, 0x78, 0x3C, 0x3C, 0xE2, 0xAB, 0xFC, 0x67, 0xFA, 0xD7, + 0x06, 0xFF, 0x35, 0x00, 0x00, 0x00, 0xA0, 0x3C, 0xBC, 0x67, 0x6F, 0x18, 0xD4, 0x71, 0xD1, 0x6A, + 0x22, 0x2A, 0x92, 0x4E, 0xC6, 0x45, 0xAB, 0x89, 0xF8, 0x08, 0x77, 0xF0, 0x1A, 0xE3, 0x1D, 0x5E, + 0x39, 0x1A, 0xFC, 0x96, 0xBA, 0x92, 0x19, 0xE9, 0x5F, 0x57, 0x8D, 0x8C, 0x91, 0xE5, 0xFE, 0x43, + 0xF4, 0x66, 0xC7, 0xC7, 0x6B, 0xE7, 0xFE, 0x35, 0xF7, 0xEF, 0xF9, 0xFF, 0x99, 0x7E, 0x37, 0x3E, + 0xF1, 0x1D, 0x00, 0x00, 0x00, 0xE5, 0xE2, 0x1D, 0xB8, 0x7A, 0x54, 0x07, 0x46, 0xB3, 0x89, 0xA8, + 0x48, 0x3A, 0x19, 0x17, 0xAD, 0x26, 0xA2, 0x23, 0xBA, 0x2E, 0xBF, 0x05, 0xB1, 0x21, 0x31, 0xBB, + 0x7A, 0xF3, 0x31, 0x34, 0xBF, 0xF2, 0x6B, 0xDE, 0x3C, 0x4B, 0xCF, 0xFD, 0x7B, 0x43, 0x7D, 0x7E, + 0x80, 0x78, 0x23, 0x2B, 0x78, 0xCB, 0x17, 0x00, 0x00, 0x00, 0xCA, 0xC5, 0xEC, 0xBF, 0xD2, 0x86, + 0x81, 0x8A, 0x8C, 0x46, 0x13, 0x51, 0x91, 0x74, 0x32, 0x2E, 0x5A, 0x2D, 0x12, 0x1A, 0xCD, 0xE6, + 0x6E, 0x41, 0x0E, 0xAD, 0x1A, 0x0B, 0x7E, 0x5B, 0x5D, 0xC5, 0xC6, 0xC7, 0x90, 0x1F, 0x1F, 0xBB, + 0x3E, 0xAD, 0xA3, 0xA3, 0x66, 0x17, 0x55, 0xB6, 0xF3, 0x92, 0x4A, 0x84, 0x0C, 0xAF, 0xE8, 0xEA, + 0x9B, 0x1D, 0x00, 0x00, 0x00, 0x20, 0x31, 0xFF, 0x81, 0xE8, 0xBD, 0x97, 0xDB, 0x38, 0x50, 0xA1, + 0xA1, 0x26, 0xA2, 0x22, 0xE9, 0x64, 0x5C, 0xB4, 0x9A, 0x08, 0x8D, 0x46, 0x73, 0xCF, 0xB1, 0xB8, + 0x5B, 0x90, 0xC3, 0xAB, 0xBA, 0xEA, 0xDB, 0x96, 0x6C, 0x44, 0x0C, 0xF8, 0xF1, 0xE1, 0xDE, 0xD8, + 0x25, 0x83, 0x23, 0xBA, 0x20, 0x3E, 0x62, 0x11, 0xE2, 0x7E, 0x8E, 0xE0, 0xA7, 0x03, 0x00, 0x00, + 0x00, 0x7A, 0x97, 0x79, 0x6E, 0xF5, 0x80, 0x7F, 0x30, 0x96, 0xB1, 0x11, 0x9F, 0x88, 0x8A, 0xA4, + 0x93, 0x71, 0xD1, 0x6A, 0x22, 0x32, 0x5A, 0x6D, 0xDF, 0x12, 0xE3, 0x1D, 0x5E, 0x75, 0x32, 0xF8, + 0xED, 0x75, 0x05, 0xEF, 0xD0, 0xC0, 0xA8, 0x39, 0x70, 0x55, 0x10, 0x18, 0xCD, 0x16, 0x8B, 0x8F, + 0x70, 0xFB, 0xAF, 0xE4, 0x16, 0x04, 0x00, 0x00, 0x00, 0xE5, 0xE0, 0x3D, 0x7B, 0xC3, 0x5D, 0x66, + 0xC7, 0xA7, 0x6C, 0x24, 0xA8, 0xE0, 0x88, 0x4E, 0x44, 0x45, 0xD2, 0xC9, 0xB8, 0x68, 0x35, 0x11, + 0x17, 0x49, 0x16, 0xDC, 0x82, 0x78, 0x87, 0x56, 0xDD, 0x15, 0xFC, 0x16, 0x3B, 0xAA, 0x7A, 0xFB, + 0xE1, 0x1E, 0x30, 0x97, 0xD1, 0x11, 0x4E, 0x84, 0x47, 0xB8, 0xED, 0x17, 0x73, 0x0B, 0x02, 0x00, + 0x00, 0x80, 0x72, 0xF0, 0x0E, 0xDF, 0xB8, 0x41, 0x07, 0x47, 0x74, 0x22, 0x2A, 0x92, 0x4E, 0xC6, + 0x45, 0xAB, 0x89, 0xB0, 0x48, 0xB3, 0x3D, 0x0B, 0x8D, 0x37, 0xB2, 0x72, 0xBC, 0x1B, 0x3E, 0x4B, + 0x23, 0xD9, 0xED, 0x87, 0x88, 0x8E, 0xF8, 0xB8, 0x05, 0x01, 0x00, 0x00, 0x40, 0x19, 0x78, 0x07, + 0xAF, 0x6B, 0xF1, 0x06, 0x2C, 0x11, 0x15, 0x49, 0x27, 0xE3, 0xA2, 0xD5, 0x44, 0x50, 0xA4, 0xDA, + 0x1F, 0x57, 0xFE, 0xDA, 0x23, 0x2B, 0xEC, 0x56, 0xAE, 0x0F, 0x7E, 0x9B, 0x1D, 0xE1, 0x3E, 0xC7, + 0xC3, 0xBF, 0xFD, 0x70, 0x7F, 0x1F, 0x65, 0x78, 0xB8, 0x89, 0xD8, 0x50, 0xF3, 0x7F, 0x4F, 0xFD, + 0xC6, 0x1C, 0xE4, 0xB3, 0x41, 0x00, 0x00, 0x00, 0xD0, 0xC3, 0xBC, 0x03, 0x9F, 0x3B, 0x59, 0x1F, + 0x1D, 0xE1, 0x22, 0x31, 0x91, 0x76, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xD9, 0xF8, 0x08, + 0xD7, 0x05, 0xB7, 0x20, 0xFE, 0xA7, 0x9A, 0xBB, 0x07, 0xFC, 0x65, 0x78, 0xB8, 0x89, 0xD0, 0x68, + 0xB6, 0xBD, 0x97, 0xB9, 0x5B, 0x90, 0xAE, 0x7A, 0xBE, 0x05, 0x00, 0x00, 0x00, 0x48, 0xA5, 0xF1, + 0x1B, 0xB0, 0x44, 0x54, 0x24, 0x9D, 0x8C, 0x8B, 0x56, 0x53, 0x41, 0x91, 0x66, 0x91, 0xF8, 0x70, + 0x73, 0xBF, 0x8E, 0xE1, 0xA5, 0xEE, 0x13, 0xC5, 0x37, 0x04, 0xBF, 0xD5, 0x29, 0x65, 0xC2, 0x0F, + 0x1D, 0x74, 0x7F, 0x2F, 0xF3, 0x88, 0x0F, 0x37, 0xF7, 0x7B, 0xF2, 0x9F, 0x05, 0x59, 0xCE, 0x87, + 0x13, 0x02, 0x00, 0x00, 0xA0, 0xF7, 0xF8, 0x6F, 0xC0, 0x72, 0x1F, 0x8A, 0x57, 0xB6, 0xF8, 0x08, + 0xB7, 0x6B, 0x8E, 0x31, 0x87, 0x56, 0xBA, 0x43, 0xFB, 0x94, 0x7F, 0x90, 0x5F, 0xF3, 0xDB, 0x0F, + 0x11, 0x17, 0x49, 0xB7, 0x67, 0xB1, 0xF1, 0x86, 0x97, 0x73, 0x0B, 0x02, 0x00, 0x00, 0x80, 0xDE, + 0x63, 0x0E, 0xDD, 0xB4, 0xD6, 0xFF, 0x60, 0xBC, 0x32, 0xC6, 0x47, 0x38, 0x77, 0x0B, 0x72, 0x68, + 0xE5, 0x60, 0xF0, 0x5B, 0x9E, 0x12, 0xCD, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0xDD, 0x33, 0x17, 0xDA, + 0xDF, 0x93, 0xFD, 0x7B, 0x66, 0x7F, 0x4F, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0xE7, 0x98, 0xC3, + 0x37, 0xAE, 0xF7, 0x5F, 0x5B, 0x5B, 0xD6, 0xF8, 0x70, 0x0B, 0x6F, 0x41, 0x0E, 0xF7, 0x2F, 0x09, + 0x7E, 0xDB, 0x85, 0x72, 0xCF, 0x9C, 0xF8, 0xB7, 0x1F, 0xEE, 0x66, 0x29, 0xEF, 0xF8, 0x08, 0xB7, + 0x7B, 0x9E, 0xF1, 0x46, 0x96, 0x8F, 0x9B, 0xA1, 0xCE, 0xBF, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, + 0xCC, 0x1B, 0x59, 0x39, 0x54, 0xEA, 0xF8, 0x08, 0x77, 0xE0, 0x6A, 0x77, 0x0B, 0x32, 0x25, 0xAF, + 0xB0, 0x35, 0x23, 0xFD, 0xEB, 0xCD, 0xC8, 0x72, 0xFB, 0xD7, 0xB5, 0xBF, 0xC6, 0x22, 0xE2, 0xC3, + 0x6D, 0xF3, 0xFB, 0xC2, 0x5B, 0x90, 0x8E, 0xBE, 0xE5, 0x0B, 0x00, 0x00, 0x00, 0x48, 0xC5, 0xDB, + 0x7F, 0xED, 0x58, 0xE9, 0xE3, 0xC3, 0x6D, 0xC7, 0x27, 0xC3, 0x67, 0x41, 0x0A, 0xFD, 0x20, 0x3F, + 0xFF, 0xF6, 0x63, 0x64, 0x60, 0xBC, 0xFE, 0xF6, 0x43, 0x44, 0x45, 0xD2, 0xC5, 0xE3, 0x23, 0x1C, + 0xB7, 0x20, 0x00, 0x00, 0x00, 0xE8, 0x35, 0x66, 0xDF, 0x12, 0x1D, 0x15, 0x49, 0x27, 0xE3, 0xA2, + 0xD5, 0x54, 0x50, 0xA4, 0x99, 0x08, 0x8C, 0x56, 0x73, 0x37, 0x06, 0x53, 0x70, 0x0B, 0xA2, 0x6F, + 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8F, 0x70, 0xDC, 0x82, 0x00, 0x00, 0x00, 0xA0, 0x97, 0x98, + 0x91, 0x35, 0xB3, 0xDD, 0xE7, 0x4A, 0xC8, 0xB0, 0x48, 0x32, 0x19, 0x17, 0xAD, 0x16, 0x8F, 0x89, + 0xB4, 0x13, 0x71, 0xD1, 0x6A, 0xEE, 0xA0, 0xEE, 0xB6, 0xED, 0x63, 0x95, 0x5B, 0x90, 0x43, 0xC5, + 0x7C, 0x90, 0x9F, 0xBE, 0xFD, 0x10, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0xE2, 0xE3, 0x16, 0x04, 0x00, + 0x00, 0x00, 0xBD, 0xC2, 0x8C, 0xAC, 0x1E, 0x30, 0x3B, 0x2F, 0xD1, 0x71, 0xD1, 0x6A, 0x32, 0x2E, + 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0x30, 0x3E, 0xC2, 0xED, 0xFD, 0x8C, 0xBB, + 0x05, 0x29, 0xE4, 0x15, 0xB6, 0xEE, 0xF3, 0x46, 0xCC, 0xF0, 0xF5, 0xF6, 0xAF, 0x33, 0x45, 0xF1, + 0x11, 0xEE, 0xE0, 0xE7, 0x6C, 0x84, 0xAC, 0xE8, 0xC8, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, 0x89, + 0x99, 0xC3, 0xAB, 0xD7, 0x9B, 0xED, 0x17, 0xEB, 0xC0, 0x68, 0x36, 0x19, 0x17, 0xAD, 0xA6, 0x82, + 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x5A, 0x3C, 0x3E, 0xDC, 0xB6, 0x7E, 0x38, 0x7C, 0x16, 0x24, 0xD7, + 0x57, 0xD8, 0xDA, 0x9F, 0x6F, 0xB6, 0xFF, 0xDA, 0x5D, 0xF7, 0x4A, 0xE3, 0xA9, 0x8C, 0x0F, 0xB7, + 0x9D, 0xB3, 0xED, 0xEF, 0x67, 0x85, 0xFB, 0x3D, 0x4D, 0xF9, 0x67, 0x9D, 0x00, 0x00, 0x00, 0x00, + 0x89, 0x79, 0x87, 0x57, 0x6F, 0x90, 0x81, 0xD1, 0x6C, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, + 0x89, 0xB8, 0x68, 0x35, 0x15, 0x1F, 0xE1, 0x82, 0x5B, 0x10, 0xF7, 0x2D, 0x53, 0xC1, 0xDF, 0x8A, + 0xB6, 0x79, 0x87, 0x06, 0x06, 0x27, 0x6F, 0x3F, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8C, 0x24, 0x73, + 0xB7, 0x20, 0xC3, 0x2B, 0xA6, 0xF4, 0xB3, 0x4E, 0x00, 0x00, 0x00, 0x80, 0x54, 0xBC, 0x83, 0x9F, + 0x1B, 0x95, 0x91, 0xD1, 0x68, 0x32, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0x35, + 0x15, 0x1D, 0xD1, 0xB9, 0x5F, 0x97, 0x7F, 0x63, 0xB0, 0x32, 0x97, 0x87, 0xB7, 0x6B, 0x6F, 0x3F, + 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8B, 0xA4, 0xE3, 0x16, 0x04, 0x00, 0x00, 0x00, 0xDD, 0xCE, 0xDB, + 0x7F, 0xD5, 0xB8, 0x0C, 0x0D, 0xB5, 0xBA, 0xB0, 0x48, 0x32, 0x15, 0x14, 0x69, 0x26, 0xE2, 0xA2, + 0xD5, 0x54, 0x70, 0xA8, 0x0D, 0x2D, 0x30, 0xDE, 0xC8, 0xCA, 0xF1, 0x3C, 0x6E, 0x41, 0xFC, 0xDB, + 0x8F, 0x03, 0xD7, 0xDA, 0x9F, 0x57, 0x44, 0x45, 0xD2, 0xA9, 0xA8, 0x48, 0x3B, 0xF7, 0x96, 0xAF, + 0xE1, 0x65, 0xDC, 0x82, 0x34, 0x60, 0xC6, 0xFE, 0xC3, 0x2C, 0xF3, 0xF2, 0xBF, 0x5F, 0x67, 0x4E, + 0x7C, 0x65, 0x7D, 0x64, 0x6B, 0xDD, 0xBF, 0x1E, 0xFC, 0x47, 0x00, 0x00, 0x00, 0x50, 0x14, 0x77, + 0xF0, 0x4E, 0xFC, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, + 0x0A, 0x8D, 0x46, 0x73, 0xBF, 0xC6, 0x1C, 0x6E, 0x41, 0xDC, 0xA7, 0xAB, 0xFB, 0xB7, 0x1F, 0xEE, + 0x59, 0x1A, 0x15, 0x16, 0x49, 0xA6, 0x62, 0x22, 0xCB, 0xB6, 0x7F, 0xD4, 0xFE, 0x7E, 0x96, 0xDB, + 0x2D, 0x2D, 0xF4, 0xB3, 0x4E, 0x7A, 0x8D, 0x0B, 0x0C, 0xEF, 0xC4, 0x97, 0x07, 0xCD, 0x2F, 0xBE, + 0x62, 0xE4, 0x4E, 0x7C, 0xC9, 0xF8, 0xFF, 0x3E, 0x21, 0x02, 0x00, 0x00, 0x50, 0x1C, 0xFF, 0x0D, + 0x58, 0xBB, 0xE6, 0xE8, 0xE0, 0x88, 0xAE, 0x2E, 0x2C, 0x92, 0x4C, 0x05, 0x45, 0x9A, 0x89, 0xB8, + 0x68, 0x35, 0x15, 0x19, 0xAD, 0xE6, 0xBF, 0xC2, 0x76, 0xE5, 0x78, 0x3B, 0xDF, 0xB6, 0xE4, 0x1D, + 0x1A, 0x18, 0x35, 0xFB, 0xAF, 0xB4, 0x3F, 0x9F, 0x08, 0x8B, 0x24, 0x53, 0x21, 0x91, 0x69, 0x33, + 0x2B, 0xDB, 0x7F, 0x85, 0xF1, 0x86, 0x97, 0x4F, 0xC9, 0x27, 0xBE, 0xF7, 0x02, 0x73, 0xFC, 0xDF, + 0x2F, 0xF1, 0x7E, 0xF1, 0xE5, 0xF1, 0xDA, 0xE0, 0xB8, 0xDD, 0x98, 0xE3, 0x5F, 0xF4, 0xC3, 0x23, + 0xFA, 0xAF, 0xFB, 0xFF, 0x39, 0xFB, 0x9F, 0x0F, 0xFE, 0xAB, 0x00, 0x00, 0x00, 0xC8, 0x93, 0x39, + 0x7C, 0xE3, 0xBA, 0x96, 0xAF, 0xE0, 0x95, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, + 0xAB, 0xA9, 0xB8, 0x48, 0xBA, 0xE1, 0xEB, 0x8D, 0xFB, 0x16, 0xAA, 0xE0, 0x6F, 0x4B, 0x2A, 0x36, + 0x5C, 0x06, 0xEC, 0xB2, 0xDF, 0x7E, 0xC8, 0x90, 0xC8, 0xB2, 0x20, 0x3E, 0xDC, 0xB8, 0x05, 0xA9, + 0xAA, 0x89, 0x0F, 0x17, 0x1D, 0x2F, 0xD9, 0xFF, 0xAD, 0x5E, 0xB0, 0xB1, 0xF8, 0xFC, 0x92, 0xC9, + 0xBD, 0x70, 0xB5, 0xFD, 0xD7, 0x57, 0x55, 0xFE, 0x7D, 0x22, 0x04, 0x00, 0x00, 0xA0, 0x38, 0xFE, + 0x2B, 0x78, 0x55, 0x74, 0x84, 0x93, 0x71, 0xD1, 0x6A, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, + 0xA9, 0xA8, 0x48, 0xBC, 0x59, 0x95, 0x07, 0xC7, 0xDD, 0xB7, 0x50, 0x65, 0xB8, 0x05, 0xF1, 0x86, + 0x57, 0x64, 0xBF, 0xFD, 0x90, 0x21, 0x91, 0x65, 0x91, 0xF8, 0x08, 0xC7, 0x2D, 0x48, 0x6D, 0x7C, + 0x1C, 0xB9, 0xB1, 0x36, 0x3A, 0xD4, 0x5C, 0x98, 0x1C, 0xFD, 0x42, 0x25, 0x42, 0x4E, 0x7C, 0x85, + 0x1B, 0x24, 0x00, 0x00, 0x80, 0xBC, 0x79, 0x07, 0x97, 0x35, 0x7E, 0x03, 0x96, 0x8C, 0x8B, 0x56, + 0x53, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0x85, 0x1F, 0x16, 0x68, 0xE7, + 0x6E, 0x41, 0x46, 0x06, 0x86, 0x82, 0xBF, 0x35, 0x89, 0xB4, 0x75, 0xFB, 0x21, 0x43, 0x22, 0xCB, + 0x44, 0x7C, 0xB8, 0x6D, 0xFD, 0xD0, 0xB4, 0xBE, 0x05, 0xA9, 0x89, 0x0F, 0x77, 0xEB, 0xA1, 0x82, + 0xA3, 0xD1, 0x5C, 0xAC, 0xF8, 0x37, 0x26, 0x5F, 0x29, 0xE4, 0xD3, 0xF2, 0x01, 0x00, 0x00, 0xA6, + 0x2D, 0x6F, 0xFF, 0x35, 0x63, 0xC4, 0x47, 0xB0, 0xED, 0x1F, 0xB7, 0x87, 0x75, 0xFF, 0x16, 0x24, + 0xF1, 0x81, 0xDD, 0x1B, 0x59, 0x31, 0xE6, 0x3F, 0xC4, 0xAF, 0x02, 0xA3, 0xD9, 0x64, 0x48, 0x64, + 0x99, 0x08, 0x8F, 0xE8, 0xF6, 0x2C, 0xB2, 0x51, 0xB5, 0x7C, 0x2C, 0xF8, 0xE5, 0x4E, 0x1B, 0x6D, + 0xC5, 0x47, 0xB8, 0x63, 0x7F, 0xE2, 0x3F, 0x94, 0x1E, 0xFC, 0x94, 0x00, 0x00, 0x00, 0xC8, 0x83, + 0xD9, 0xF7, 0x19, 0xE2, 0xC3, 0xED, 0x99, 0x60, 0xFB, 0xAF, 0x32, 0xDE, 0xF0, 0x40, 0xA2, 0x6F, + 0xBD, 0xB1, 0xA1, 0xB2, 0xCE, 0xBF, 0xFD, 0x70, 0x7F, 0xCF, 0x54, 0x64, 0x34, 0x9A, 0x0C, 0x89, + 0x2C, 0x13, 0xC1, 0x11, 0x9F, 0xFB, 0x7B, 0xEB, 0xDF, 0x82, 0x2C, 0xCF, 0xF5, 0x13, 0xDF, 0xBB, + 0x59, 0x2E, 0xF1, 0xE1, 0xF6, 0xC2, 0xD5, 0xEE, 0xDB, 0xB0, 0x4E, 0x06, 0x3F, 0x2D, 0x00, 0x00, + 0x00, 0xDA, 0x65, 0x0E, 0xDF, 0xB8, 0xC4, 0x0C, 0x2D, 0x9C, 0xBE, 0xF1, 0x11, 0x46, 0x47, 0xF0, + 0x7F, 0x7B, 0x6E, 0xDB, 0x3F, 0xEE, 0xBE, 0x0D, 0x2B, 0xD1, 0x2D, 0x88, 0x37, 0xBC, 0xE2, 0x64, + 0xEA, 0xDB, 0x0F, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, 0xD1, 0xDC, 0x2D, 0xC8, 0xF0, 0xB2, 0x69, + 0x71, 0x90, 0xCE, 0x2D, 0x3E, 0xC2, 0x1D, 0xBB, 0xC5, 0x04, 0x3F, 0x35, 0x00, 0x00, 0x00, 0xDA, + 0x65, 0x0E, 0xAD, 0x5A, 0x5B, 0xF3, 0x06, 0x2C, 0x19, 0x17, 0xAD, 0xA6, 0x82, 0x22, 0xCD, 0x44, + 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0xAB, 0x8F, 0x0F, 0x3F, 0x3C, 0xC2, 0x6D, 0xB2, 0xDB, 0x7B, + 0x85, 0x39, 0x3F, 0x3C, 0xD0, 0xF4, 0xC0, 0x9E, 0xE9, 0xF6, 0x43, 0x86, 0x44, 0x96, 0x89, 0xC8, + 0x68, 0x36, 0xF7, 0xF7, 0x79, 0x1A, 0xDC, 0x82, 0xE4, 0x1E, 0x1F, 0xCF, 0x7F, 0xC6, 0x98, 0x23, + 0x37, 0x18, 0xF3, 0xF2, 0x9D, 0x7C, 0x9E, 0x0A, 0x00, 0x00, 0x40, 0x1E, 0xFC, 0x37, 0x60, 0x6D, + 0xFB, 0xC8, 0xF4, 0x8D, 0x8F, 0x68, 0x78, 0xB8, 0xB9, 0xF8, 0x70, 0xDB, 0xFC, 0x21, 0xF7, 0x6D, + 0x58, 0xEE, 0x16, 0xA4, 0xE1, 0x81, 0xDD, 0xBF, 0xFD, 0xD8, 0xB3, 0xD0, 0xFE, 0x7C, 0x22, 0x34, + 0xD4, 0x64, 0x48, 0x64, 0x99, 0x08, 0x8C, 0x24, 0x1B, 0x9A, 0x5F, 0xEA, 0x5B, 0x90, 0x42, 0xE2, + 0xC3, 0x6D, 0xEC, 0x3A, 0x17, 0x20, 0xD3, 0xE6, 0xDB, 0xD7, 0x00, 0x00, 0x00, 0x0A, 0xE5, 0x1D, + 0x5A, 0x3D, 0x38, 0xED, 0xE2, 0x23, 0x12, 0x20, 0xD5, 0xE8, 0x88, 0xC4, 0xC7, 0xF9, 0x70, 0x43, + 0x97, 0x9B, 0x73, 0x07, 0xF5, 0x2D, 0xC8, 0xF9, 0x91, 0xFE, 0xF5, 0x66, 0x78, 0x99, 0xFD, 0xB9, + 0xDC, 0xAF, 0x49, 0xC4, 0x46, 0x7C, 0x32, 0x24, 0xB2, 0x4C, 0x84, 0x45, 0xD2, 0xB9, 0xDF, 0xF7, + 0xF0, 0xF5, 0xEE, 0x16, 0xA4, 0xAD, 0x4F, 0x7C, 0xEF, 0x46, 0x85, 0xC5, 0x87, 0xDB, 0x0B, 0x57, + 0x19, 0x73, 0xE2, 0xCE, 0xD2, 0xFD, 0x3D, 0x03, 0x00, 0x00, 0xE8, 0x08, 0x6F, 0xDF, 0x55, 0xA3, + 0x3A, 0x2E, 0x5A, 0x4D, 0x05, 0x45, 0x9A, 0xC5, 0xC2, 0x22, 0xC9, 0x64, 0x54, 0x24, 0x5D, 0x24, + 0x3E, 0x82, 0xD5, 0xDC, 0x78, 0x84, 0xD1, 0xF1, 0x74, 0x64, 0x9B, 0x3F, 0x64, 0xCE, 0x1F, 0x5C, + 0x6E, 0xCE, 0x0D, 0xF7, 0xDF, 0x15, 0xFC, 0xED, 0xF2, 0x99, 0xA1, 0xFE, 0x59, 0xE7, 0x47, 0x56, + 0x8C, 0x9B, 0xDD, 0x7D, 0xF6, 0x60, 0x2F, 0x62, 0x23, 0x3E, 0x19, 0x12, 0x59, 0x26, 0xA2, 0x22, + 0xED, 0x76, 0xCF, 0x35, 0xDE, 0xC8, 0xB2, 0x71, 0xF7, 0x7B, 0x08, 0x7E, 0x3B, 0x3D, 0xAF, 0xD0, + 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x9F, 0x07, 0x02, 0x00, 0x00, 0x90, 0x07, 0xB3, 0xEF, 0x0A, + 0x7B, 0xB8, 0x57, 0x81, 0xD1, 0x6C, 0x2A, 0x28, 0xD2, 0x4C, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, 0x48, + 0xBA, 0x48, 0x78, 0x44, 0x6F, 0x3E, 0xE2, 0xB7, 0x1E, 0x7E, 0x78, 0xBC, 0xCF, 0x9C, 0x7B, 0x6A, + 0x72, 0xE7, 0x77, 0xCE, 0x77, 0xB7, 0x20, 0x35, 0x07, 0xF6, 0xF3, 0x07, 0xFB, 0xD7, 0x7B, 0xC3, + 0xCB, 0x8C, 0xE7, 0x6E, 0x3F, 0x5A, 0x05, 0x88, 0x0C, 0x89, 0x2C, 0x13, 0x31, 0x91, 0x76, 0x9B, + 0x66, 0xD8, 0x1F, 0xED, 0xAF, 0xA9, 0x44, 0xB7, 0x20, 0x53, 0x11, 0x1F, 0x6E, 0xDE, 0xD1, 0x5B, + 0xA6, 0xDD, 0x6B, 0x8C, 0x01, 0x00, 0x00, 0x72, 0x67, 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x8B, 0xED, + 0x01, 0x5F, 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x58, 0x24, 0x99, 0x8C, 0x8A, 0xA4, + 0x8B, 0xC4, 0x47, 0x83, 0x00, 0x09, 0xE3, 0xE3, 0x5C, 0x24, 0x3E, 0xCE, 0x6E, 0x0C, 0xF6, 0xD4, + 0xFB, 0xCD, 0xF9, 0x03, 0xCB, 0x8D, 0x8B, 0x0E, 0xFF, 0xEF, 0x99, 0x0D, 0x91, 0x73, 0xC3, 0x2B, + 0xC6, 0xBD, 0x5D, 0x7D, 0xF6, 0xBF, 0x7F, 0x91, 0x3F, 0xFF, 0x50, 0xAF, 0x42, 0x44, 0x86, 0x44, + 0x96, 0x89, 0x98, 0x48, 0x3B, 0x17, 0x1F, 0xE1, 0x4A, 0x72, 0x0B, 0x32, 0x55, 0xF1, 0xE1, 0xEF, + 0xE8, 0xE7, 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xBB, 0xCC, 0xC8, 0xEA, 0x01, 0xB3, 0xEB, 0x52, + 0x7B, 0xC8, 0x57, 0xA1, 0xA1, 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, + 0x4B, 0x1F, 0x1F, 0xD5, 0xF0, 0x78, 0xD2, 0x6D, 0x96, 0xBF, 0x73, 0x3B, 0xE6, 0x9B, 0xB3, 0x07, + 0x2A, 0xB7, 0x20, 0x2E, 0x44, 0xCE, 0x1F, 0x5C, 0x66, 0xFF, 0xFB, 0x7F, 0xDC, 0x3C, 0x40, 0x64, + 0x48, 0x64, 0x99, 0x88, 0x89, 0xB4, 0x8B, 0xC6, 0x87, 0x9B, 0xFB, 0xB5, 0x1E, 0xBC, 0xB6, 0xA7, + 0x6F, 0x41, 0xA6, 0x34, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0xEC, 0x5F, 0x33, 0xF8, 0xCB, 0x03, 0x00, + 0x00, 0x20, 0x0B, 0xEF, 0xD0, 0xAA, 0xBB, 0xCC, 0xF6, 0x4F, 0xD8, 0x83, 0xBE, 0x8A, 0x8D, 0xF8, + 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, 0x74, 0xB1, 0xF8, 0x08, 0x02, 0x24, + 0x49, 0x7C, 0xBC, 0x6B, 0xE3, 0xE3, 0xDD, 0xC1, 0x59, 0x93, 0xDB, 0xF8, 0x7E, 0x73, 0x6E, 0xEF, + 0xF5, 0xE6, 0xDC, 0x81, 0x81, 0x51, 0xF7, 0xED, 0x58, 0xE7, 0xB7, 0x5F, 0x62, 0xFF, 0xBB, 0x36, + 0x3E, 0xDC, 0x54, 0x84, 0xC8, 0x90, 0xC8, 0x32, 0x11, 0x13, 0x69, 0x17, 0x8F, 0x8F, 0x70, 0x3B, + 0x3E, 0xE9, 0x02, 0xC4, 0xBD, 0xE5, 0x6B, 0x76, 0xF0, 0x8F, 0x43, 0xCF, 0x98, 0xF2, 0xF8, 0x70, + 0x1B, 0x5B, 0x66, 0xCC, 0x89, 0xAF, 0xAC, 0x0D, 0x7E, 0x09, 0x00, 0x00, 0x00, 0xC8, 0xC2, 0x3B, + 0xBC, 0x7A, 0x83, 0x8E, 0x8D, 0xF8, 0x54, 0x50, 0xA4, 0x99, 0x88, 0x8B, 0x56, 0x93, 0x51, 0x91, + 0x74, 0x3A, 0x3E, 0xEA, 0x02, 0xC4, 0x86, 0x47, 0xF8, 0xCC, 0x47, 0x3C, 0x3E, 0x26, 0xDC, 0x9E, + 0xA8, 0xCC, 0xFD, 0xFF, 0x67, 0xB7, 0x7C, 0xDA, 0x4C, 0x3C, 0xD3, 0x6F, 0xCE, 0x0D, 0xD9, 0x10, + 0x79, 0xCA, 0xFD, 0x77, 0x2F, 0xD2, 0x11, 0xB2, 0x49, 0x85, 0x44, 0x96, 0x89, 0x98, 0x48, 0x3B, + 0x15, 0x1E, 0xD1, 0x1D, 0xBC, 0xD6, 0xBD, 0x96, 0x77, 0x30, 0xF8, 0xC7, 0xA1, 0x27, 0x74, 0x24, + 0x3E, 0xDC, 0x5E, 0xBC, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0xB4, 0xCB, 0x3B, 0x78, 0x4D, 0x82, + 0x37, 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0xE1, 0x11, + 0x2E, 0x1E, 0x1F, 0xE1, 0xED, 0x47, 0xE4, 0x99, 0x0F, 0x17, 0x1F, 0xD1, 0xF0, 0x98, 0x78, 0x3C, + 0x98, 0xFB, 0xBF, 0x1F, 0x9B, 0x65, 0x4E, 0x3F, 0x72, 0x9D, 0x39, 0xF3, 0xF0, 0x25, 0x7E, 0x80, + 0x9C, 0xF3, 0x1F, 0x58, 0x8F, 0x05, 0x88, 0x8B, 0x8F, 0x5C, 0x02, 0x44, 0xC4, 0x44, 0xDA, 0xA9, + 0xE0, 0x88, 0xAF, 0xC7, 0x6E, 0x41, 0x3A, 0x16, 0x1F, 0xC1, 0xBC, 0x5F, 0xDC, 0x39, 0x14, 0xFC, + 0x52, 0x00, 0x00, 0x00, 0x90, 0x85, 0xB7, 0xFF, 0xEA, 0x93, 0x3A, 0x3A, 0xC2, 0xA9, 0xA0, 0x48, + 0x33, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x78, 0xB8, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, + 0xDE, 0x7E, 0xD4, 0x7E, 0xEB, 0x55, 0x34, 0x3E, 0xCE, 0xD8, 0xE8, 0x38, 0xF3, 0xF8, 0xFB, 0x82, + 0x55, 0x22, 0xE4, 0xF4, 0xFD, 0x17, 0x99, 0x53, 0xF7, 0x5E, 0x6C, 0x4E, 0xDD, 0x7D, 0x91, 0x39, + 0x6B, 0xFF, 0x33, 0x75, 0xB7, 0x20, 0x36, 0x3C, 0xDC, 0xDA, 0x0F, 0x10, 0x11, 0x13, 0x69, 0xA7, + 0x62, 0xA3, 0xD1, 0x7A, 0xE4, 0x16, 0xA4, 0xD3, 0xF1, 0xE1, 0xE6, 0x1D, 0xFB, 0x53, 0xDE, 0x84, + 0x05, 0x00, 0x00, 0xD0, 0x8E, 0xE6, 0x6F, 0xC0, 0x52, 0x41, 0x91, 0x66, 0x22, 0x2E, 0x5A, 0x4D, + 0x46, 0x45, 0xD2, 0xC5, 0xA2, 0x23, 0xBA, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDC, 0x7E, 0xD4, 0x7C, + 0xDB, 0x55, 0x18, 0x1F, 0x8F, 0xD9, 0xF0, 0xB0, 0x3B, 0x1D, 0xFC, 0x78, 0xE6, 0x91, 0xF7, 0xF9, + 0xE1, 0x11, 0xEE, 0xF4, 0x7D, 0x36, 0x42, 0x36, 0x4E, 0x46, 0x88, 0xF7, 0x74, 0x25, 0x3E, 0xAA, + 0x01, 0x92, 0x39, 0x42, 0x44, 0x4C, 0xA4, 0x9D, 0x8A, 0x8C, 0x66, 0xDB, 0x7E, 0x71, 0xD7, 0xDF, + 0x82, 0x74, 0x43, 0x7C, 0xF8, 0x3B, 0x76, 0x0B, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xC8, 0xCA, 0x7F, + 0x03, 0xD6, 0xEE, 0x79, 0xF6, 0xE0, 0x5F, 0xFE, 0xF8, 0x70, 0x3F, 0x36, 0xBF, 0xFD, 0xB0, 0xF1, + 0xE1, 0x02, 0x24, 0x88, 0x0F, 0x17, 0x1E, 0xA7, 0x1F, 0x9D, 0xDC, 0xA9, 0x7B, 0x67, 0xD5, 0x04, + 0x88, 0xDB, 0xBB, 0x3F, 0x0E, 0x02, 0xE4, 0xA9, 0x0B, 0xED, 0xCF, 0x67, 0xE3, 0x23, 0x1E, 0x21, + 0x32, 0x30, 0x9A, 0x4D, 0xC4, 0x44, 0xDA, 0xA9, 0xC0, 0x48, 0xB2, 0x7D, 0x57, 0x18, 0x6F, 0x78, + 0x79, 0x57, 0x7E, 0xD0, 0x5E, 0xD7, 0xC4, 0x87, 0x9B, 0x7B, 0x13, 0xD6, 0xCB, 0x77, 0xF6, 0xDC, + 0x43, 0xFB, 0x00, 0x00, 0x00, 0x5D, 0xC1, 0x1C, 0x5A, 0xB5, 0xD6, 0xEC, 0x9C, 0x6D, 0x0F, 0xFF, + 0x25, 0x8E, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x88, 0xDD, 0x7E, 0xB8, 0xD7, 0xEC, 0x46, 0x6F, + 0x3F, 0xE2, 0xF1, 0x71, 0xFA, 0x81, 0xDA, 0xDB, 0x8F, 0x70, 0xEE, 0x16, 0xE4, 0xDC, 0x93, 0x76, + 0x1B, 0x2F, 0xF2, 0x23, 0xA4, 0x26, 0x40, 0x5C, 0x50, 0xA4, 0x8A, 0x10, 0x11, 0x13, 0x69, 0xA7, + 0xC2, 0x22, 0xE9, 0xB6, 0x7D, 0x24, 0xB8, 0x05, 0x59, 0x3A, 0x10, 0xFC, 0xE3, 0xD1, 0x15, 0xBA, + 0x2A, 0x3E, 0xDC, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0xB3, 0xAB, 0xFE, 0x1E, 0x01, 0x00, 0x00, 0xF4, + 0x0C, 0x73, 0x78, 0xF5, 0x7A, 0xB3, 0xF5, 0xC3, 0x36, 0x00, 0x4A, 0x1C, 0x1F, 0xC1, 0xD4, 0xED, + 0xC7, 0x59, 0x3F, 0x40, 0x6C, 0x7C, 0xB8, 0xDB, 0x8F, 0xC8, 0xB7, 0x5E, 0x55, 0xC3, 0xE3, 0xC7, + 0x95, 0xA9, 0xDB, 0x0F, 0x7F, 0x5F, 0xBF, 0xD0, 0xBC, 0xFB, 0x48, 0x25, 0x40, 0xCE, 0xB5, 0x75, + 0x0B, 0x22, 0x62, 0x22, 0xED, 0x54, 0x54, 0xA4, 0x9D, 0xBB, 0x05, 0x39, 0xB8, 0xAC, 0x6B, 0x6E, + 0x41, 0xBA, 0x2E, 0x3E, 0xDC, 0x78, 0x13, 0x16, 0x00, 0x00, 0x40, 0x76, 0xDE, 0xC8, 0x8A, 0xA1, + 0xD2, 0xC7, 0x47, 0xC3, 0xDB, 0x8F, 0x59, 0xD5, 0xF8, 0xA8, 0xDE, 0x7E, 0x84, 0xF1, 0x11, 0x84, + 0x87, 0x1F, 0x1F, 0x3F, 0xD2, 0xB7, 0x1F, 0x2E, 0x3E, 0xDC, 0x4E, 0x7F, 0xEB, 0x42, 0x73, 0xB6, + 0xAD, 0x5B, 0x10, 0x11, 0x13, 0x69, 0xA7, 0x62, 0x22, 0xCB, 0xB6, 0xD9, 0x18, 0x1D, 0x5E, 0xD6, + 0x15, 0xB7, 0x20, 0x5D, 0x19, 0x1F, 0xC1, 0xBC, 0x13, 0x5F, 0xEE, 0xA9, 0xD7, 0x16, 0x03, 0x00, + 0x00, 0x74, 0x0D, 0x6F, 0xDF, 0x55, 0x63, 0x65, 0xBF, 0xF9, 0x70, 0xAB, 0xBF, 0xFD, 0x88, 0x04, + 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x70, 0x44, 0x02, 0xE4, 0x94, 0x7B, 0xE8, 0xDC, 0xED, 0xDB, 0xE2, + 0xF6, 0x23, 0x88, 0x8F, 0x70, 0x13, 0x0F, 0x64, 0xBD, 0x05, 0x11, 0x31, 0x91, 0x76, 0x2A, 0x24, + 0x32, 0xED, 0x82, 0xCA, 0xF6, 0x5C, 0xD6, 0xF1, 0x5B, 0x90, 0x6E, 0x8E, 0x0F, 0x37, 0xEF, 0xF8, + 0x9F, 0x75, 0xE5, 0xB3, 0x32, 0x00, 0x00, 0x00, 0x5D, 0xCF, 0xEC, 0xBD, 0xDC, 0x86, 0x40, 0x89, + 0xE3, 0x23, 0xC1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xC1, 0xB7, 0x5E, 0x9D, 0x0A, 0x03, 0xE4, 0x07, + 0xAD, 0xE3, 0xC3, 0xED, 0xF4, 0x3D, 0x2D, 0x6E, 0x41, 0xE4, 0x44, 0x4C, 0xA4, 0x9D, 0x0C, 0x89, + 0x2C, 0x0B, 0xE2, 0xC3, 0xCD, 0xFD, 0xFD, 0xF5, 0x6F, 0x41, 0x96, 0xAF, 0x0B, 0xFE, 0x31, 0x99, + 0x52, 0xDD, 0x1E, 0x1F, 0xFE, 0x8E, 0xFF, 0x29, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x48, 0xCB, 0xBD, + 0x72, 0xD5, 0xEC, 0x59, 0x64, 0x63, 0x40, 0x05, 0x45, 0x9A, 0x89, 0xB8, 0x68, 0xB5, 0xBA, 0xA0, + 0x48, 0x33, 0x11, 0x1A, 0x8D, 0x16, 0x0F, 0x90, 0xE0, 0xF6, 0xE3, 0x6C, 0x92, 0xDB, 0x8F, 0x87, + 0xED, 0xEE, 0x69, 0x1D, 0x1F, 0xE1, 0xC2, 0x5B, 0x90, 0x64, 0x6F, 0xC4, 0x12, 0x31, 0x91, 0x76, + 0x32, 0x24, 0xB2, 0x2C, 0x12, 0x1F, 0xE1, 0x86, 0x16, 0x1A, 0xEF, 0xE0, 0xD2, 0x93, 0xC1, 0x3F, + 0x2A, 0x53, 0xA6, 0x27, 0xE2, 0xC3, 0xED, 0xC8, 0x6A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0x90, 0x96, + 0xFF, 0x0A, 0xDE, 0x9D, 0x9F, 0xB2, 0x41, 0xA0, 0xA2, 0x22, 0xE9, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, + 0x8A, 0xA4, 0x13, 0x91, 0xA1, 0x66, 0x83, 0xA3, 0x1A, 0x1F, 0x36, 0x3C, 0x12, 0xDF, 0x7E, 0x44, + 0xBF, 0xF5, 0xEA, 0xFB, 0xB1, 0xDB, 0x0F, 0x11, 0x1D, 0xD1, 0x25, 0xBF, 0x05, 0x11, 0x31, 0x91, + 0x76, 0x32, 0x24, 0xB2, 0x4C, 0xC4, 0x87, 0x9B, 0xFB, 0x7B, 0x3D, 0xC5, 0xB7, 0x20, 0x3D, 0x13, + 0x1F, 0x3F, 0xBF, 0xDC, 0x98, 0xB1, 0x15, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x20, 0x2D, 0x73, 0x78, + 0xE5, 0x7A, 0xB3, 0xED, 0xA3, 0x36, 0x0A, 0x54, 0x58, 0x24, 0x99, 0x88, 0x8B, 0x56, 0xAB, 0x0B, + 0x8A, 0x34, 0x8B, 0x45, 0x46, 0xB3, 0x45, 0x03, 0xC4, 0xAE, 0x12, 0x1F, 0x36, 0x0E, 0xC2, 0x00, + 0x69, 0xF4, 0xDA, 0xDD, 0x46, 0xB7, 0x1F, 0x22, 0x38, 0xD4, 0x26, 0x7E, 0x50, 0x09, 0x90, 0x9A, + 0x67, 0x41, 0x82, 0x10, 0xA9, 0xDC, 0x82, 0x88, 0x98, 0x48, 0x3B, 0x19, 0x12, 0x59, 0x26, 0xC2, + 0x23, 0xBA, 0x29, 0xBC, 0x05, 0xE9, 0xA9, 0xF8, 0x70, 0x7B, 0xF1, 0x3A, 0x63, 0x7F, 0xBD, 0x77, + 0x05, 0xBF, 0x7C, 0x00, 0x00, 0x00, 0x24, 0xE1, 0x1D, 0x5E, 0xB9, 0x41, 0x87, 0x45, 0x92, 0x89, + 0xB8, 0x68, 0x35, 0x19, 0x15, 0x49, 0x17, 0x0B, 0x8C, 0x66, 0x8B, 0xC5, 0x47, 0xE5, 0xF6, 0x23, + 0x12, 0x1F, 0xCD, 0x6E, 0x3F, 0xC2, 0x00, 0x89, 0xDE, 0x7E, 0x88, 0xD0, 0x68, 0xB8, 0x6F, 0x5C, + 0x68, 0xCE, 0x3E, 0xD1, 0xE0, 0x16, 0x64, 0x93, 0x88, 0x89, 0xB4, 0x93, 0x21, 0x91, 0x65, 0x22, + 0x38, 0xE2, 0x73, 0x7F, 0xDF, 0x0F, 0x5E, 0x57, 0xF8, 0x2D, 0x48, 0xCF, 0xC5, 0x47, 0x30, 0xEF, + 0xC4, 0x9D, 0x1B, 0x82, 0xDF, 0x02, 0x00, 0x00, 0x00, 0x92, 0xF0, 0x0E, 0x5E, 0x3D, 0xAA, 0xE3, + 0xA2, 0xD5, 0x44, 0x5C, 0xB4, 0x5A, 0x5D, 0x50, 0xA4, 0x59, 0x2C, 0x30, 0x9A, 0xAD, 0x41, 0x7C, + 0xF8, 0xB7, 0x1F, 0x2E, 0x3E, 0xD4, 0xED, 0x47, 0x10, 0x1F, 0xD5, 0xDB, 0x8F, 0x87, 0xEC, 0xBE, + 0x91, 0x21, 0x3E, 0x82, 0x85, 0xB7, 0x20, 0xE7, 0x9F, 0x72, 0x7F, 0xDD, 0x20, 0x42, 0x9E, 0x9E, + 0x69, 0x7F, 0x2D, 0x2E, 0x20, 0x82, 0xA9, 0xB8, 0x68, 0x35, 0x19, 0x12, 0x59, 0x26, 0x62, 0xA3, + 0xD1, 0x76, 0xCD, 0x31, 0xDE, 0xF0, 0xD2, 0x71, 0x33, 0xD4, 0x3F, 0x2B, 0xF8, 0xC7, 0x26, 0x57, + 0xBD, 0x1A, 0x1F, 0x7E, 0x80, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x74, 0xBC, 0xFD, 0x9F, 0x1D, + 0xD7, 0x81, 0xD1, 0x6C, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xC5, 0x02, 0xA3, 0xD5, 0xEA, + 0x02, 0x24, 0x88, 0x8F, 0xF8, 0xED, 0x47, 0x10, 0x1F, 0xF2, 0xD9, 0x8F, 0xFB, 0x83, 0xDB, 0x0F, + 0x11, 0x17, 0x89, 0x16, 0xBB, 0x05, 0x39, 0x1F, 0xC4, 0x47, 0x5B, 0x01, 0x22, 0x43, 0x22, 0xCB, + 0x44, 0x64, 0x34, 0x9B, 0x7B, 0x66, 0xC5, 0xDD, 0x82, 0x1C, 0x5C, 0x9A, 0xFB, 0x07, 0xEF, 0xF5, + 0x72, 0x7C, 0xB8, 0x79, 0xC7, 0xFE, 0x64, 0x3C, 0xF8, 0xAD, 0x00, 0x00, 0x00, 0xA0, 0x15, 0x33, + 0xDA, 0x3F, 0x2B, 0xFD, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x8B, 0xC5, 0x45, + 0x92, 0xC5, 0xE3, 0x23, 0x7A, 0xFB, 0x11, 0xC4, 0x47, 0xCD, 0x9B, 0xAF, 0x1A, 0xDD, 0x7E, 0xA8, + 0xB0, 0x48, 0xB1, 0x33, 0xDF, 0xBB, 0x70, 0xF2, 0x59, 0x90, 0xA7, 0x6C, 0x7C, 0xB4, 0x13, 0x21, + 0x32, 0x24, 0xB2, 0x4C, 0x04, 0x46, 0x92, 0x15, 0x70, 0x0B, 0xD2, 0xEB, 0xF1, 0xE1, 0xEF, 0xC8, + 0x4D, 0xC6, 0x8C, 0xFD, 0x87, 0x42, 0x6E, 0x86, 0x00, 0x00, 0x00, 0x4A, 0xC7, 0x7F, 0x03, 0xD6, + 0xAE, 0x4F, 0xDB, 0x48, 0x50, 0xA1, 0xA1, 0x26, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, + 0x8B, 0x56, 0xB3, 0xD1, 0x31, 0x19, 0x20, 0x17, 0x55, 0x02, 0x24, 0xB8, 0xFD, 0xA8, 0xBE, 0x76, + 0xB7, 0x7A, 0xFB, 0xF1, 0xBE, 0xC6, 0xB7, 0x1F, 0x22, 0x28, 0xB2, 0xEC, 0xEC, 0x63, 0x2E, 0x42, + 0x2A, 0x01, 0xE2, 0xDF, 0x82, 0x64, 0x89, 0x10, 0x19, 0x12, 0x59, 0x26, 0xC2, 0x22, 0xE9, 0x72, + 0xBE, 0x05, 0x29, 0x45, 0x7C, 0xB8, 0xBD, 0x34, 0xC0, 0x9B, 0xB0, 0x00, 0x00, 0x00, 0x92, 0x32, + 0x87, 0x57, 0xAD, 0x4B, 0xFE, 0x0A, 0x5E, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x61, + 0x91, 0x74, 0xF1, 0xF8, 0xC8, 0x74, 0xFB, 0xA1, 0x63, 0x22, 0xFD, 0x66, 0x9A, 0x33, 0xF7, 0xCF, + 0x34, 0x67, 0x9F, 0x9C, 0x8C, 0x90, 0xD4, 0x01, 0x22, 0x43, 0x22, 0xCB, 0x44, 0x54, 0xA4, 0xDD, + 0xCE, 0xD9, 0xC6, 0x1B, 0xBE, 0xBE, 0xED, 0x5B, 0x90, 0xD2, 0xC4, 0x87, 0x1B, 0x6F, 0xC2, 0x02, + 0x00, 0x00, 0x48, 0xCE, 0xB8, 0x57, 0xF0, 0xCA, 0xD8, 0x88, 0x4F, 0xC4, 0x45, 0xAB, 0xC9, 0xA8, + 0x48, 0x3A, 0x11, 0x16, 0x49, 0xE6, 0x6E, 0x3F, 0xEC, 0x8F, 0x7E, 0x7C, 0xC4, 0x6E, 0x3F, 0xEA, + 0x9F, 0xFD, 0x68, 0x70, 0xFB, 0x71, 0x5F, 0xFB, 0xDF, 0x7A, 0x55, 0xD9, 0xCC, 0xEA, 0xDE, 0x0D, + 0x6E, 0x41, 0xCE, 0x35, 0xBA, 0x05, 0x51, 0xE1, 0xE1, 0x26, 0x43, 0x22, 0xCB, 0x44, 0x4C, 0x64, + 0xDA, 0x7B, 0x8D, 0x39, 0x70, 0xB5, 0x7B, 0x2D, 0xEF, 0x60, 0xF0, 0x8F, 0x50, 0x6A, 0xA5, 0x8A, + 0x0F, 0xB7, 0xE7, 0xAF, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x49, 0x79, 0x07, 0xAF, 0x4B, 0xF0, + 0x06, 0x2C, 0x11, 0x17, 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x62, 0x51, 0x91, 0x66, 0xE1, 0xCD, 0x47, + 0x83, 0xDB, 0x8F, 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0x78, 0x30, 0xAF, 0x6F, 0xBD, 0x9A, 0x8C, 0x0F, + 0xB7, 0x4C, 0xB7, 0x20, 0x32, 0x24, 0xB2, 0x4C, 0x85, 0x44, 0x96, 0xD9, 0xF8, 0x70, 0xDB, 0xFE, + 0x71, 0xF7, 0x6D, 0x58, 0xC6, 0x8C, 0x5C, 0x9B, 0xFA, 0x13, 0xC0, 0x4B, 0x17, 0x1F, 0xC1, 0xBC, + 0x13, 0x77, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x80, 0x24, 0xBC, 0x7D, 0x57, 0x8E, 0xE9, 0xE8, 0x08, + 0x27, 0xE2, 0xA2, 0xD5, 0x64, 0x54, 0x24, 0x9D, 0x88, 0x8A, 0xA4, 0xF3, 0x6F, 0x3F, 0x82, 0xF8, + 0x88, 0xDD, 0x7E, 0xA8, 0x67, 0x3F, 0xEA, 0x3F, 0x74, 0xD0, 0xC6, 0x47, 0x2E, 0xB7, 0x1F, 0xB5, + 0xF1, 0x11, 0xEE, 0xDD, 0x47, 0x5A, 0x3C, 0x0B, 0xD2, 0x0B, 0xF1, 0xF1, 0x74, 0xB0, 0xFD, 0xE9, + 0x6F, 0x41, 0xCA, 0x1A, 0x1F, 0x6E, 0xDE, 0xB1, 0x5B, 0xA6, 0xE4, 0x83, 0x1A, 0x01, 0x00, 0x00, + 0x7A, 0x9E, 0xD9, 0x7B, 0x99, 0x8D, 0x06, 0x15, 0x1E, 0x6E, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, + 0xD2, 0xC5, 0x82, 0x22, 0xED, 0xC2, 0xF0, 0x68, 0x70, 0xFB, 0x51, 0xF7, 0xEC, 0x47, 0x10, 0x20, + 0x95, 0xDB, 0x0F, 0x1B, 0x1F, 0xB9, 0xDC, 0x7E, 0xE8, 0xF8, 0x70, 0x3B, 0x7D, 0xEF, 0x4C, 0x73, + 0xAE, 0xD1, 0x2D, 0x88, 0x1F, 0x1D, 0x3D, 0x12, 0x1F, 0xF6, 0xFF, 0xF6, 0xB6, 0x7F, 0xDC, 0x05, + 0x48, 0xE2, 0x5B, 0x90, 0x32, 0xC7, 0x87, 0xBF, 0x23, 0x37, 0x99, 0xE0, 0xB7, 0x0A, 0x00, 0x00, + 0x80, 0x46, 0xCC, 0xE1, 0xFE, 0x25, 0x66, 0x68, 0xBE, 0x0D, 0x87, 0x72, 0xC4, 0x47, 0xCB, 0xDB, + 0x0F, 0x11, 0x1F, 0x95, 0xDB, 0x0F, 0x1B, 0x1E, 0xB9, 0xDC, 0x7E, 0xE8, 0xF0, 0x88, 0x2E, 0xBC, + 0x05, 0x69, 0xF8, 0x2C, 0x88, 0x0C, 0x89, 0x2C, 0x53, 0x21, 0x91, 0x65, 0x22, 0x3E, 0xEC, 0x8F, + 0xFE, 0xF6, 0x7C, 0xC6, 0x9C, 0x3F, 0x70, 0xFD, 0x50, 0xF0, 0x8F, 0x53, 0x43, 0xA5, 0x8F, 0x0F, + 0x37, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x9A, 0xFF, 0x0A, 0x5E, 0xF9, 0x06, 0x2C, 0x11, 0x17, + 0xAD, 0x26, 0xA3, 0x22, 0xE9, 0x44, 0x50, 0xA4, 0x9A, 0x8D, 0x8F, 0x30, 0x3C, 0xC2, 0xF8, 0x48, + 0x7A, 0xFB, 0xF1, 0x63, 0x1B, 0x1E, 0x2E, 0x40, 0x7E, 0xD8, 0xEE, 0xED, 0x87, 0x0E, 0x8E, 0xF8, + 0xDC, 0x2D, 0x48, 0xE3, 0x67, 0x41, 0x54, 0x48, 0x64, 0x99, 0x0A, 0x89, 0x2C, 0x6B, 0x12, 0x1F, + 0x4F, 0xBD, 0xD7, 0x9C, 0xDF, 0xF2, 0x21, 0x73, 0x7E, 0xFF, 0x32, 0x73, 0x76, 0xFF, 0xD2, 0x86, + 0x07, 0xEF, 0x69, 0x11, 0x1F, 0x6E, 0x2F, 0x5E, 0xE7, 0x02, 0x64, 0x5D, 0xF0, 0xDB, 0x06, 0x00, + 0x00, 0x80, 0xE2, 0xBF, 0x01, 0x6B, 0xEB, 0x87, 0x6C, 0x40, 0xF4, 0x7E, 0x7C, 0x64, 0xB9, 0xFD, + 0xA8, 0xC6, 0x87, 0xBB, 0xFD, 0xF8, 0x56, 0x3B, 0xB7, 0x1F, 0x3A, 0x36, 0x1A, 0x6D, 0xE2, 0x21, + 0x75, 0x0B, 0x32, 0xC3, 0x9F, 0x0E, 0x8A, 0x34, 0x53, 0x21, 0x91, 0x65, 0x2D, 0xE2, 0xC3, 0x6D, + 0xE3, 0x05, 0xE6, 0xFC, 0xEE, 0x25, 0xE6, 0xDC, 0xDE, 0x65, 0xF2, 0x01, 0xEC, 0x69, 0x13, 0x1F, + 0x6E, 0xCF, 0x5F, 0x69, 0xCC, 0x89, 0x3B, 0x73, 0xFF, 0x94, 0x78, 0x00, 0x00, 0x80, 0x52, 0xF1, + 0x0E, 0xAD, 0x1C, 0xEC, 0xF9, 0xF8, 0xC8, 0x78, 0xFB, 0x71, 0xEA, 0x51, 0x1B, 0x1D, 0xB9, 0xDC, + 0x7E, 0xE8, 0xC8, 0x68, 0xB6, 0xD3, 0xF7, 0xC4, 0x6F, 0x41, 0x2A, 0xF1, 0xD1, 0x7E, 0x80, 0xA8, + 0x90, 0xC8, 0xB2, 0x64, 0xF1, 0x71, 0xEE, 0x49, 0xBB, 0x4D, 0x1F, 0x76, 0x01, 0x62, 0xCE, 0x0E, + 0xD5, 0xDE, 0x82, 0x4C, 0xAB, 0xF8, 0x08, 0xE6, 0x9D, 0xF8, 0x32, 0x6F, 0xC2, 0x02, 0x00, 0x00, + 0x68, 0xC6, 0xDB, 0x77, 0x45, 0xE4, 0x15, 0xBC, 0x22, 0x2E, 0x5A, 0x4D, 0x46, 0x45, 0xD2, 0xA9, + 0xA0, 0x48, 0xB3, 0x20, 0x3E, 0x82, 0xA5, 0xBB, 0xFD, 0x88, 0xC4, 0x47, 0x5B, 0xB7, 0x1F, 0x3A, + 0x30, 0x92, 0x6C, 0xE2, 0x81, 0xE8, 0x2D, 0x88, 0x8D, 0x8F, 0xB6, 0x23, 0x44, 0x85, 0x44, 0x96, + 0x25, 0x8F, 0x8F, 0xB3, 0x83, 0x76, 0x4F, 0x5C, 0x60, 0xDE, 0xDD, 0xB1, 0xC4, 0x4C, 0xEC, 0x5E, + 0x5E, 0x3D, 0x7C, 0x4F, 0xC7, 0xF8, 0x70, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x2D, 0x98, 0x7D, + 0xF6, 0x70, 0xD7, 0xEB, 0xF1, 0x91, 0xE6, 0xF6, 0x23, 0x8C, 0x8F, 0x5C, 0x6E, 0x3F, 0x74, 0x58, + 0x24, 0x5D, 0xE5, 0x16, 0x64, 0xA6, 0x8D, 0x10, 0x1B, 0x20, 0x4F, 0xB5, 0x1B, 0x20, 0x2A, 0x24, + 0xB2, 0x2C, 0x43, 0x7C, 0x3C, 0x7E, 0x81, 0x39, 0x33, 0xF8, 0x41, 0x17, 0x20, 0xE6, 0xF4, 0x8E, + 0xA5, 0x03, 0xD3, 0x35, 0x3E, 0xFC, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x00, 0x34, 0x62, + 0x46, 0xFB, 0x67, 0x99, 0x3D, 0x0B, 0x75, 0x5C, 0xB4, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, + 0x66, 0x91, 0xF8, 0x08, 0xA6, 0x6E, 0x3F, 0xAA, 0x01, 0x52, 0x73, 0xFB, 0x31, 0xAB, 0xFE, 0xF6, + 0xE3, 0x9B, 0x2A, 0x2E, 0x5A, 0x4D, 0x47, 0x45, 0x9A, 0xBD, 0xF3, 0xD7, 0x33, 0xCC, 0x99, 0x1F, + 0x4E, 0x06, 0x48, 0xF6, 0x5B, 0x10, 0x15, 0x12, 0x59, 0x96, 0x31, 0x3E, 0x1E, 0x9D, 0x61, 0x4E, + 0xFF, 0xD8, 0xEE, 0x99, 0x45, 0x66, 0xE2, 0xC0, 0xAA, 0x93, 0xD3, 0x36, 0x3E, 0xDC, 0x8E, 0xAC, + 0x32, 0xE6, 0xF8, 0x1D, 0x4B, 0x82, 0x2F, 0x31, 0x00, 0x00, 0x00, 0x44, 0x99, 0x91, 0xFE, 0x01, + 0xB3, 0xF3, 0x12, 0x1D, 0x18, 0xCD, 0x26, 0xA3, 0x22, 0xE9, 0x54, 0x50, 0xA4, 0x59, 0x2C, 0x3E, + 0x12, 0xDC, 0x7E, 0x4C, 0xB8, 0x00, 0x79, 0xDC, 0xDD, 0x7E, 0xC4, 0xE2, 0xC3, 0xED, 0x7B, 0x59, + 0xBE, 0xF5, 0x4A, 0x07, 0x45, 0x9A, 0xB9, 0xF8, 0xF0, 0x77, 0xF7, 0x0C, 0x7B, 0x90, 0x6F, 0xE7, + 0x16, 0x44, 0x85, 0x44, 0x96, 0xB5, 0x17, 0x1F, 0xA7, 0x1E, 0x76, 0x01, 0x32, 0xDB, 0x98, 0x63, + 0x77, 0x9A, 0x69, 0x1B, 0x1F, 0x3F, 0xBF, 0xCC, 0x98, 0x17, 0x3F, 0x67, 0xCC, 0x89, 0x2F, 0xAD, + 0x0D, 0xBE, 0xC4, 0x00, 0x00, 0x00, 0x10, 0xE5, 0x1D, 0x5A, 0x75, 0x97, 0xD9, 0x7E, 0xB1, 0x8E, + 0x8C, 0x46, 0x93, 0x51, 0x91, 0x74, 0x2A, 0x28, 0xD2, 0x2C, 0x16, 0x1F, 0x2A, 0x40, 0x1A, 0x3E, + 0xFB, 0x61, 0xE3, 0x23, 0x97, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0x56, 0x8D, 0x8F, 0x60, 0x67, 0xBE, + 0x5F, 0x09, 0x90, 0x73, 0xD1, 0x5B, 0x90, 0x20, 0x44, 0x74, 0x74, 0x84, 0x53, 0x21, 0x91, 0x65, + 0x39, 0xC4, 0xC7, 0xD3, 0x1F, 0x33, 0xDE, 0xD1, 0xDB, 0xA7, 0x77, 0x7C, 0xB8, 0x3D, 0xFF, 0x59, + 0xDE, 0x84, 0x05, 0x00, 0x00, 0xD0, 0x88, 0x19, 0x59, 0xB9, 0x5E, 0x46, 0x46, 0xA3, 0xC9, 0xA8, + 0x48, 0x3A, 0x15, 0x14, 0x69, 0x56, 0x1F, 0x1E, 0xD5, 0xF8, 0xB0, 0xE1, 0x31, 0x79, 0xFB, 0x11, + 0xF9, 0xD6, 0xAB, 0xEA, 0xED, 0xC7, 0x45, 0x95, 0xDB, 0x0F, 0xBB, 0xF6, 0x6E, 0x3F, 0x74, 0x50, + 0xA4, 0x59, 0x3C, 0x3E, 0xFC, 0x65, 0xBA, 0x05, 0x51, 0x21, 0x91, 0x65, 0xC4, 0x47, 0xFB, 0x0B, + 0xE2, 0x23, 0x98, 0xF7, 0x8B, 0x3B, 0x5B, 0x7E, 0x30, 0x23, 0x00, 0x00, 0xC0, 0xB4, 0xE4, 0x1D, + 0xB8, 0x7A, 0x54, 0x86, 0x86, 0x9A, 0x8C, 0x8A, 0xA4, 0x53, 0x41, 0x91, 0x66, 0xB1, 0xF8, 0x88, + 0x07, 0x88, 0x5D, 0xF5, 0x5B, 0xAF, 0xC2, 0x00, 0xA9, 0x3E, 0x78, 0x6E, 0xE3, 0xC3, 0x06, 0x48, + 0xFB, 0xB7, 0x1F, 0x3A, 0x28, 0xD2, 0x4C, 0xC6, 0x47, 0xB0, 0xF0, 0x16, 0xC4, 0xBD, 0x92, 0xB7, + 0xF5, 0x2D, 0x88, 0x0A, 0x89, 0x2C, 0x23, 0x3E, 0xDA, 0x5F, 0x6D, 0x7C, 0xF8, 0x01, 0x72, 0xF4, + 0xD6, 0xB1, 0xE0, 0x4B, 0x0C, 0x00, 0x00, 0x00, 0x51, 0xDE, 0xFE, 0x2B, 0x4F, 0xCA, 0xD8, 0x88, + 0x4F, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, 0xB3, 0x58, 0x78, 0x88, 0xF8, 0x08, 0x6F, 0x3F, 0x6A, + 0x1E, 0x3C, 0xF7, 0x6F, 0x3F, 0x2E, 0x9A, 0xBC, 0xFD, 0x08, 0xE3, 0x23, 0x0C, 0x90, 0xFB, 0xD3, + 0xDC, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x1D, 0x35, 0x73, 0xB7, 0x20, 0x8F, 0x4D, 0xDE, 0x82, + 0xF8, 0x11, 0x62, 0x63, 0xA3, 0x3E, 0x40, 0x54, 0x48, 0x64, 0x19, 0xF1, 0xD1, 0xFE, 0xEA, 0xE3, + 0xC3, 0xDF, 0xB1, 0x2F, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x00, 0x25, 0xD1, 0x1B, 0xB0, 0x64, 0x54, + 0x24, 0x9D, 0x0A, 0x8A, 0x34, 0x8B, 0x85, 0x47, 0x93, 0xF8, 0xA8, 0x3E, 0x78, 0x5E, 0xBD, 0xFD, + 0xB0, 0xF1, 0x11, 0xDE, 0x7E, 0xC4, 0xE3, 0xE3, 0x21, 0xBB, 0xBB, 0x55, 0x68, 0xA8, 0xE9, 0xA0, + 0x48, 0x33, 0x19, 0x1C, 0x62, 0xA7, 0xBF, 0x3B, 0x23, 0x78, 0x16, 0xA4, 0xC1, 0xB7, 0x62, 0x3D, + 0xAD, 0x42, 0x22, 0xCB, 0x88, 0x8F, 0xF6, 0x27, 0xC2, 0x23, 0x1C, 0x6F, 0xC2, 0x02, 0x00, 0x00, + 0xA8, 0xE7, 0xBF, 0x01, 0x6B, 0xD7, 0x1C, 0x1D, 0x1D, 0xE1, 0x64, 0x54, 0x24, 0x9D, 0x0A, 0x8A, + 0x34, 0x8B, 0x85, 0x47, 0x38, 0x15, 0x20, 0xF1, 0xD7, 0xEE, 0x3E, 0x39, 0x19, 0x1F, 0xF2, 0xCD, + 0x57, 0x89, 0x6F, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0A, 0x8D, 0x66, 0x7B, 0x37, 0x7E, 0x0B, 0x12, + 0x46, 0x88, 0x8B, 0x8F, 0x70, 0x32, 0x2A, 0x92, 0x8E, 0xF8, 0x68, 0x7F, 0x22, 0x3A, 0xA2, 0x7B, + 0xF1, 0x7A, 0x63, 0x5E, 0xBE, 0xB3, 0xE6, 0x53, 0xE1, 0x01, 0x00, 0x00, 0xA6, 0x3D, 0x73, 0xA8, + 0x7F, 0xAD, 0xD9, 0xF1, 0x49, 0x1D, 0x1E, 0x6E, 0x32, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, 0xC5, + 0xA2, 0x23, 0xBA, 0x78, 0x7C, 0x44, 0x6F, 0x3F, 0x82, 0xF8, 0x98, 0xBC, 0xFD, 0x10, 0xDF, 0x7A, + 0x95, 0xF8, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xA9, 0xC0, 0x68, 0x35, 0x77, 0x0B, 0x52, 0xF7, 0xE1, + 0x84, 0x36, 0x3A, 0xF2, 0x09, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xE0, 0x88, 0xEF, 0x85, 0xAB, 0x79, + 0x13, 0x16, 0x00, 0x00, 0x40, 0x9C, 0xFF, 0x06, 0xAC, 0xAD, 0x1F, 0xEC, 0xB9, 0xF8, 0x68, 0x74, + 0xFB, 0xE1, 0xE2, 0xE3, 0x6C, 0x2C, 0x3E, 0xB2, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x15, 0x17, + 0x49, 0xF7, 0xEE, 0x8F, 0x2B, 0x01, 0xE2, 0xBF, 0x96, 0xF7, 0x29, 0x1B, 0x1F, 0x6E, 0xD1, 0x08, + 0x91, 0x71, 0xD1, 0x6A, 0xC4, 0x47, 0xFB, 0x13, 0xB1, 0xD1, 0x60, 0xDE, 0x89, 0x2F, 0x0D, 0x06, + 0x5F, 0x6A, 0x00, 0x00, 0x00, 0x70, 0xBC, 0xE1, 0xE5, 0x43, 0x3D, 0x15, 0x1F, 0x6E, 0xF1, 0xF8, + 0x88, 0xDE, 0x7E, 0xB8, 0xF8, 0x68, 0x75, 0xFB, 0xF1, 0xA0, 0x9D, 0x0C, 0x8E, 0xE8, 0x74, 0x50, + 0xA4, 0x99, 0x8A, 0x8A, 0x34, 0x3B, 0xFD, 0xED, 0xE0, 0x16, 0xE4, 0x49, 0x1B, 0x20, 0x36, 0x0A, + 0xEA, 0x02, 0x24, 0x75, 0x84, 0x10, 0x1F, 0xED, 0x4F, 0x87, 0x46, 0xA3, 0x79, 0x47, 0x6F, 0x1D, + 0x0D, 0xBE, 0xD4, 0x00, 0x00, 0x00, 0xE0, 0x78, 0x7B, 0xAF, 0xA8, 0x7F, 0x05, 0xAF, 0x8C, 0x8A, + 0xA4, 0x53, 0x41, 0x91, 0x66, 0x22, 0x38, 0xA2, 0xB3, 0xD1, 0xE1, 0x7E, 0xAC, 0xBB, 0xFD, 0xB0, + 0xF1, 0x71, 0x6E, 0xE3, 0x45, 0xC9, 0x6E, 0x3F, 0xEE, 0x6B, 0x75, 0xFB, 0xA1, 0x83, 0x22, 0xCD, + 0x54, 0x50, 0x64, 0xD9, 0xBB, 0xF6, 0xD0, 0x1F, 0x06, 0x48, 0x7B, 0xB7, 0x20, 0xC4, 0x47, 0xFB, + 0xD3, 0x91, 0xD1, 0x74, 0xC7, 0x6E, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x51, 0x66, 0xEF, 0xE2, + 0xDE, 0x89, 0x0F, 0xB7, 0x30, 0x3C, 0xC2, 0xF8, 0x08, 0x03, 0x24, 0x88, 0x8F, 0x78, 0x80, 0xD4, + 0xC5, 0x47, 0xCB, 0xDB, 0x0F, 0x1D, 0x14, 0x69, 0xA6, 0x42, 0x22, 0xDB, 0x2E, 0x30, 0xA7, 0xBF, + 0x6D, 0xA3, 0x60, 0x70, 0x32, 0x42, 0x6A, 0x02, 0xC4, 0x85, 0x45, 0xA2, 0x08, 0x21, 0x3E, 0xDA, + 0x9F, 0x88, 0x8B, 0x24, 0x73, 0x6F, 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x1B, 0x00, 0x00, + 0xC0, 0xF4, 0x66, 0x46, 0xFA, 0x67, 0xD7, 0xBC, 0x82, 0x57, 0x46, 0x45, 0xD2, 0xA9, 0xA0, 0x48, + 0x33, 0x11, 0x1B, 0xF1, 0xD9, 0xE8, 0x70, 0x3F, 0xD6, 0xDF, 0x7E, 0xD8, 0xF0, 0x10, 0xB7, 0x1F, + 0xF2, 0x43, 0x07, 0x9B, 0xDE, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x76, 0x41, 0x75, + 0xE1, 0x2D, 0xC8, 0xB9, 0x4C, 0xB7, 0x20, 0xC4, 0x47, 0xFB, 0x13, 0x61, 0x91, 0x74, 0x63, 0xCB, + 0x79, 0x13, 0x16, 0x00, 0x00, 0x40, 0xC8, 0x7F, 0x05, 0x6F, 0xF8, 0x06, 0x2C, 0x19, 0x15, 0x49, + 0xA7, 0x82, 0x22, 0xCD, 0x62, 0xA1, 0xD1, 0x68, 0x61, 0x78, 0x84, 0xF1, 0xE1, 0xF6, 0xD4, 0x85, + 0x35, 0xDF, 0x7A, 0x15, 0x0F, 0x90, 0x53, 0x2E, 0x40, 0xC2, 0xDB, 0x8F, 0x1F, 0xD9, 0xC9, 0xF0, + 0x70, 0xD3, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x6C, 0x32, 0x3E, 0xDC, 0x4E, 0x7D, 0xD3, 0xC5, + 0x41, 0x96, 0x5B, 0x10, 0xE2, 0xA3, 0xFD, 0x89, 0xA8, 0x48, 0xB3, 0x17, 0x3F, 0xC7, 0x9B, 0xB0, + 0x00, 0x00, 0x00, 0x42, 0xFE, 0x1B, 0xB0, 0xB6, 0x7D, 0xC4, 0x1E, 0xEE, 0x55, 0x54, 0x24, 0x9D, + 0x0A, 0x8A, 0x34, 0x13, 0xA1, 0xA1, 0x66, 0xA3, 0xC3, 0xFD, 0x58, 0x7B, 0xFB, 0x61, 0xE3, 0x23, + 0xCD, 0xED, 0xC7, 0xB7, 0x1A, 0xDD, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, 0x56, 0x1B, + 0x1F, 0xE1, 0x26, 0x7E, 0x94, 0xF6, 0x16, 0x84, 0xF8, 0x68, 0x7F, 0x22, 0x28, 0x32, 0x8C, 0x37, + 0x61, 0x01, 0x00, 0x00, 0x04, 0xBC, 0x91, 0x81, 0x0D, 0x3A, 0x2A, 0x92, 0x4E, 0x05, 0x45, 0x9A, + 0xC5, 0x22, 0xA3, 0xD9, 0xC2, 0xF0, 0x88, 0xC4, 0x47, 0xA2, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x68, + 0xD7, 0xA3, 0xF1, 0xE1, 0xD6, 0xF2, 0x16, 0x84, 0xF8, 0xC8, 0x79, 0x3A, 0x26, 0xB2, 0xCC, 0x3B, + 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x00, 0x38, 0xDE, 0x81, 0xAB, 0x47, 0x75, 0x58, 0x24, 0x99, + 0x0A, 0x8A, 0x34, 0x13, 0x91, 0xD1, 0x62, 0xD5, 0x00, 0x09, 0xE3, 0xA3, 0xED, 0xDB, 0x0F, 0x1D, + 0x14, 0x69, 0xA6, 0x43, 0x22, 0xCB, 0x74, 0x78, 0x44, 0x17, 0xDE, 0x82, 0xB8, 0x78, 0x68, 0x7C, + 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x12, 0x59, 0xE7, 0x1D, 0xBB, 0x65, 0x3C, 0xF8, 0x92, 0x03, + 0x00, 0x00, 0x98, 0xDE, 0xBC, 0x7D, 0x57, 0x8C, 0xEB, 0xB8, 0x68, 0x35, 0x15, 0x14, 0x69, 0xA6, + 0x03, 0xA3, 0xE1, 0x6A, 0x6E, 0x3F, 0x6C, 0x7C, 0x34, 0xBB, 0xFD, 0x08, 0xE3, 0xA3, 0xE5, 0xED, + 0x87, 0x0E, 0x8A, 0x34, 0xD3, 0x21, 0x91, 0x65, 0x3A, 0x38, 0xE2, 0xF3, 0x6F, 0x41, 0x1E, 0x6F, + 0x76, 0x0B, 0x42, 0x7C, 0xB4, 0x3F, 0x1D, 0x11, 0x6D, 0xCD, 0xBD, 0x09, 0x6B, 0xEC, 0x8B, 0xB3, + 0x82, 0x2F, 0x3B, 0x00, 0x00, 0x80, 0xE9, 0xCB, 0x0C, 0x2D, 0xB0, 0x07, 0x7C, 0x15, 0x18, 0xCD, + 0xA6, 0x82, 0x22, 0xCD, 0x44, 0x60, 0x24, 0x58, 0x18, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xB9, 0x1F, + 0xC9, 0x6E, 0x3F, 0x74, 0x50, 0xA4, 0x99, 0x0E, 0x89, 0x2C, 0xD3, 0xB1, 0xD1, 0x68, 0x67, 0xBE, + 0x2F, 0x9E, 0x05, 0xF1, 0x43, 0x24, 0x12, 0x1E, 0x6E, 0xC4, 0x47, 0x86, 0x89, 0x78, 0xC8, 0x63, + 0x63, 0xCB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x80, 0xFF, 0x06, 0xAC, 0x9D, 0xB3, 0xED, 0xE1, 0x5E, + 0x45, 0x46, 0xA3, 0xA9, 0xA0, 0x48, 0x33, 0x1D, 0x17, 0x4D, 0x17, 0xB9, 0xF9, 0xF0, 0xE3, 0x43, + 0xDC, 0x7E, 0x4C, 0xB8, 0x3D, 0x1E, 0xB9, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xE5, 0x89, 0x0F, + 0x7F, 0x77, 0xAB, 0x5B, 0x90, 0x4A, 0x68, 0x18, 0x1B, 0x19, 0xC4, 0x47, 0xD6, 0x89, 0x70, 0xC8, + 0x65, 0x8B, 0x8D, 0x79, 0xF1, 0x5A, 0xE3, 0xFD, 0xE2, 0x4B, 0x77, 0x05, 0x5F, 0x7A, 0x00, 0x00, + 0x00, 0xD3, 0x93, 0x0D, 0x90, 0x75, 0x66, 0xC7, 0x27, 0xEC, 0x21, 0x5F, 0x85, 0x86, 0x9A, 0x0A, + 0x8A, 0x34, 0x13, 0x71, 0x91, 0x64, 0x61, 0x7C, 0xC4, 0x6E, 0x3F, 0x12, 0x3F, 0xFB, 0xF1, 0xCD, + 0x12, 0xC5, 0x47, 0xB0, 0x33, 0xDF, 0x8B, 0x3E, 0x0B, 0x52, 0x89, 0x8C, 0x70, 0x2E, 0x40, 0xC2, + 0xF0, 0x20, 0x3E, 0x92, 0x4E, 0x85, 0x43, 0x1E, 0xB3, 0xF1, 0xE1, 0x66, 0x7F, 0xED, 0xDE, 0x89, + 0x3B, 0x36, 0x04, 0x5F, 0x7A, 0x00, 0x00, 0x00, 0xD3, 0x93, 0xFF, 0x0A, 0x5E, 0x19, 0x1A, 0x6A, + 0x2A, 0x28, 0xD2, 0x4C, 0x84, 0x45, 0xAB, 0xD9, 0xF0, 0xA8, 0xC6, 0x87, 0x0D, 0x8F, 0xC9, 0xDB, + 0x8F, 0xD8, 0xB7, 0x5E, 0x45, 0x6F, 0x3F, 0xEC, 0x1A, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, + 0x12, 0x59, 0xA6, 0xC3, 0x22, 0xF1, 0xAA, 0xB7, 0x20, 0x36, 0x40, 0x36, 0xBA, 0xC0, 0x08, 0x82, + 0x23, 0x12, 0x1E, 0xC4, 0x47, 0xD2, 0xA9, 0x70, 0xC8, 0x63, 0x41, 0x7C, 0x04, 0xF3, 0x4E, 0xFC, + 0x39, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x9B, 0x77, 0xF0, 0xBA, 0x84, 0x6F, 0xC0, 0x52, 0x41, + 0x91, 0x66, 0xB1, 0xB0, 0x48, 0x3A, 0x17, 0x20, 0xE1, 0xCD, 0x87, 0x5D, 0xF5, 0x5B, 0xAF, 0xE4, + 0xB3, 0x1F, 0x17, 0xB5, 0xB8, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x04, 0x45, + 0x86, 0x9D, 0xFE, 0xCE, 0x7B, 0xFD, 0xB0, 0x08, 0x23, 0xA4, 0x1A, 0x1C, 0x2E, 0x3E, 0x82, 0x28, + 0x21, 0x3E, 0x5A, 0x4D, 0x85, 0x43, 0x1E, 0xAB, 0x8D, 0x0F, 0x3F, 0x40, 0x8E, 0x7D, 0x81, 0x37, + 0x61, 0x01, 0x00, 0x80, 0xE9, 0xCD, 0xDB, 0xFB, 0xD9, 0x31, 0x1D, 0x1C, 0xD1, 0xA9, 0xA0, 0x48, + 0xB3, 0x58, 0x54, 0x24, 0x5D, 0x2C, 0x3E, 0xC2, 0xDB, 0x8F, 0xBA, 0xF8, 0x88, 0xDE, 0x7E, 0x84, + 0xF1, 0x11, 0x06, 0xC8, 0x86, 0xF0, 0xF6, 0x43, 0x07, 0x45, 0x9A, 0xE9, 0x90, 0xC8, 0x32, 0x1D, + 0x13, 0xA9, 0xF7, 0x57, 0xEF, 0xF5, 0xF7, 0xEE, 0xA3, 0x93, 0x01, 0x12, 0x9F, 0x1F, 0x27, 0x2E, + 0x3C, 0x88, 0x8F, 0x06, 0x53, 0xE1, 0x90, 0xC7, 0xEA, 0xE3, 0xC3, 0xDF, 0x91, 0x1B, 0x4C, 0xF0, + 0xA5, 0x07, 0x00, 0x00, 0x30, 0x3D, 0x99, 0x3D, 0xF6, 0x50, 0x24, 0xA3, 0x23, 0x9C, 0x0A, 0x8A, + 0x34, 0x8B, 0x45, 0x45, 0xD2, 0x35, 0x88, 0x8F, 0xEA, 0x83, 0xE7, 0xEA, 0xF6, 0x23, 0x1E, 0x1F, + 0x0F, 0xD9, 0xDD, 0x5D, 0xEE, 0xF8, 0x70, 0x73, 0xB7, 0x20, 0x7E, 0x60, 0xD8, 0x9D, 0x7B, 0xD2, + 0x86, 0x87, 0xDD, 0xB9, 0x68, 0x7C, 0xD8, 0xF0, 0x38, 0x6B, 0xC3, 0x83, 0xF8, 0x88, 0x4F, 0x85, + 0x43, 0x1E, 0x8B, 0x45, 0x47, 0x74, 0x2F, 0xAD, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xFA, 0x32, + 0x87, 0xFB, 0x97, 0x98, 0xDD, 0xF3, 0xEC, 0x81, 0x5F, 0x85, 0x87, 0x9B, 0x0A, 0x8A, 0x34, 0x8B, + 0x45, 0x45, 0x9A, 0xD9, 0xE8, 0xA8, 0x0B, 0x90, 0x26, 0xDF, 0x7A, 0x25, 0xDF, 0x7C, 0x75, 0xBF, + 0xBB, 0xFD, 0xD0, 0x41, 0x91, 0x66, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x45, 0xE2, 0x23, + 0x9C, 0xBB, 0x05, 0xF1, 0x43, 0x63, 0xD0, 0xC6, 0x88, 0x0D, 0x90, 0xB3, 0xB1, 0x6F, 0xB9, 0x7A, + 0xF7, 0x31, 0xE2, 0xA3, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x88, 0x8E, 0xE8, 0x5E, 0xBC, 0xD6, 0x06, + 0xC8, 0x1D, 0xEB, 0x82, 0x2F, 0x41, 0x00, 0x00, 0x80, 0xE9, 0xC5, 0x7F, 0x05, 0x6F, 0xC3, 0x37, + 0x60, 0xA9, 0xA0, 0x48, 0x33, 0x11, 0x15, 0x49, 0xF7, 0x8C, 0x88, 0x8F, 0xE8, 0xED, 0x87, 0x8B, + 0x8F, 0x9A, 0x00, 0x11, 0xDF, 0x7A, 0xE5, 0xDF, 0x7E, 0xE8, 0xA0, 0x48, 0x33, 0x1D, 0x12, 0x59, + 0x26, 0x42, 0x22, 0xCB, 0x44, 0x7C, 0xBC, 0xBD, 0xFE, 0xBD, 0xE6, 0xD4, 0x3D, 0x36, 0x42, 0x5C, + 0x68, 0xB8, 0xE0, 0x70, 0x21, 0x12, 0xFC, 0xE8, 0xFE, 0xB5, 0x09, 0x17, 0x1F, 0x36, 0x3C, 0x4E, + 0x3F, 0x42, 0x7C, 0x54, 0xA6, 0xC2, 0x21, 0x8F, 0x89, 0xE0, 0x88, 0xCF, 0xFD, 0xBE, 0x4E, 0xDC, + 0xB1, 0x3E, 0xF8, 0x12, 0x04, 0x00, 0x00, 0x98, 0x5E, 0xFC, 0x37, 0x60, 0x6D, 0xF9, 0x80, 0x3D, + 0xF4, 0x77, 0x5F, 0x7C, 0x34, 0xBA, 0xFD, 0x50, 0xAF, 0xDD, 0xD5, 0xB7, 0x1F, 0xED, 0x7F, 0xEB, + 0x95, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0x0D, 0xE2, 0x23, 0xDC, 0x99, 0x07, 0x6D, 0x6C, + 0x3C, 0x3E, 0xA3, 0x12, 0x22, 0x41, 0x78, 0x4C, 0x3C, 0x7A, 0x81, 0x7F, 0xEB, 0x41, 0x7C, 0x84, + 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x6C, 0x34, 0x98, 0x77, 0xE2, 0x0E, 0xDE, 0x84, 0x05, 0x00, 0x00, + 0xA6, 0x27, 0xEF, 0xD0, 0xCA, 0xC1, 0xAE, 0x8B, 0x8F, 0x5C, 0x6E, 0x3F, 0x2E, 0x6A, 0xFB, 0xF6, + 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0xD6, 0xD7, 0xEC, 0xBF, 0xF6, + 0x4D, 0x17, 0x1D, 0x33, 0xFC, 0x9D, 0xB1, 0xE1, 0xE1, 0xE6, 0x7F, 0xCB, 0x55, 0x18, 0x1F, 0x4F, + 0x11, 0x1F, 0xC5, 0x4C, 0x87, 0x46, 0xA3, 0x79, 0xC7, 0xBE, 0x70, 0x32, 0xF8, 0x12, 0x04, 0x00, + 0x00, 0x98, 0x5E, 0xBC, 0xBD, 0x57, 0xC4, 0x5E, 0xC1, 0xAB, 0x82, 0x22, 0xCD, 0x44, 0x54, 0x24, + 0x5D, 0x24, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0xA3, 0xFE, 0xD9, 0x0F, 0x75, 0xFB, 0x61, 0xE3, 0xE3, + 0xBE, 0xF6, 0x6E, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x4B, 0x10, 0x1F, 0x6F, 0x7D, + 0xED, 0x02, 0xF3, 0xD6, 0x7F, 0xB9, 0xC0, 0x9C, 0xFA, 0xA1, 0x0D, 0x0D, 0x77, 0xE3, 0xF1, 0x63, + 0x1B, 0x1F, 0x41, 0x78, 0xBC, 0xF3, 0x90, 0xFD, 0x91, 0xF8, 0x28, 0x68, 0x3A, 0x32, 0x9A, 0xEE, + 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x4C, 0x4F, 0x66, 0xAF, 0x3D, 0xF0, 0x75, 0x53, 0x7C, + 0x04, 0x01, 0xD2, 0xEC, 0xF6, 0x23, 0x1E, 0x20, 0x75, 0xF1, 0xF1, 0x60, 0x7B, 0x0F, 0x9E, 0xEB, + 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x96, 0x22, 0x3E, 0xDE, 0xFC, 0xCF, 0xF6, 0xC7, 0xBB, 0x6D, + 0x84, 0x04, 0xD1, 0xE1, 0xEF, 0x41, 0xE2, 0x43, 0x87, 0x43, 0x1E, 0x13, 0x71, 0x91, 0x64, 0x47, + 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xFD, 0x98, 0xD1, 0xFE, 0x59, 0x66, 0x68, 0x81, 0x0D, + 0x80, 0xEE, 0x8A, 0x0F, 0xF7, 0xA3, 0xBA, 0xFD, 0x50, 0xCF, 0x7E, 0xD4, 0x7E, 0xE8, 0xA0, 0x0D, + 0x8F, 0x87, 0xDB, 0xBB, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x2C, 0x65, 0x7C, 0xB8, + 0xFD, 0xE1, 0xFF, 0xB1, 0xFF, 0xFF, 0x77, 0x66, 0x98, 0xB7, 0x1F, 0x98, 0x69, 0x67, 0xE3, 0x63, + 0x23, 0xF1, 0x51, 0xCC, 0x44, 0x58, 0x24, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x2F, 0xAD, 0x0D, 0xBE, + 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0xFF, 0x0D, 0x58, 0x3B, 0x67, 0xDB, 0x08, 0x50, 0x41, 0x91, + 0x66, 0x22, 0x2A, 0x92, 0x2E, 0x1A, 0x1F, 0x41, 0x80, 0x34, 0xBB, 0xFD, 0x70, 0xF1, 0x11, 0x0F, + 0x90, 0x6A, 0x7C, 0xB4, 0x79, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, 0x64, 0x59, 0xC6, 0xF8, + 0x78, 0xE3, 0x2F, 0x67, 0x98, 0xF1, 0xFF, 0x3C, 0xC3, 0xBC, 0xF5, 0x23, 0xFB, 0x7B, 0x7A, 0x92, + 0xF8, 0x28, 0x66, 0x22, 0x2A, 0xD2, 0xEC, 0xF9, 0x2B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x7E, + 0xBC, 0x43, 0xAB, 0xEE, 0x32, 0xDB, 0x3E, 0x6A, 0x43, 0x40, 0x45, 0x45, 0xD2, 0x89, 0xA8, 0x48, + 0x3A, 0x11, 0x1F, 0xEE, 0xC7, 0xD4, 0xB7, 0x1F, 0x61, 0x7C, 0xB8, 0xDB, 0x8F, 0x7B, 0xB3, 0xDD, + 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x4E, 0x7C, 0xFC, 0xA7, 0x19, 0xE6, 0xF7, + 0xFF, 0xF7, 0x0C, 0xF3, 0xE6, 0x03, 0xC4, 0x47, 0x31, 0x13, 0x41, 0x91, 0x61, 0xDE, 0x2F, 0xEE, + 0x18, 0x0A, 0xBE, 0x14, 0x01, 0x00, 0x00, 0xA6, 0x07, 0x33, 0xD2, 0xBF, 0x5E, 0x47, 0x45, 0xD2, + 0x89, 0xA8, 0x48, 0xBA, 0x78, 0x7C, 0xB8, 0x85, 0xE1, 0x11, 0xC6, 0x47, 0xAB, 0xDB, 0x0F, 0xFF, + 0x5B, 0xAF, 0x82, 0xF8, 0x70, 0xFB, 0xA1, 0x9D, 0x88, 0x8B, 0x56, 0xD3, 0x21, 0x91, 0x65, 0x22, + 0x24, 0xB2, 0x2C, 0x87, 0xF8, 0x78, 0xE3, 0xDB, 0x36, 0x3E, 0x5E, 0x22, 0x3E, 0xF2, 0x9F, 0x8E, + 0x89, 0x2C, 0xF3, 0x8E, 0xDE, 0x3C, 0x16, 0x7C, 0x29, 0x02, 0x00, 0x00, 0x4C, 0x0F, 0xDE, 0x81, + 0xAB, 0x46, 0x75, 0x58, 0x24, 0x99, 0x88, 0x8A, 0xA4, 0x6B, 0x10, 0x1F, 0xEE, 0xC7, 0x54, 0xB7, + 0x1F, 0xD1, 0xF8, 0x70, 0xB7, 0x1F, 0xDF, 0x4A, 0x7F, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, + 0x64, 0x19, 0xF1, 0x91, 0xC3, 0x54, 0x38, 0xE4, 0x31, 0x1D, 0x12, 0x99, 0xC7, 0x9B, 0xB0, 0x00, + 0x00, 0xC0, 0x74, 0xE3, 0xED, 0xFF, 0xEC, 0x49, 0x1D, 0x17, 0xAD, 0x26, 0xA2, 0x22, 0xE9, 0xE2, + 0xE1, 0x11, 0x2E, 0x0C, 0x8F, 0x30, 0x3E, 0x9A, 0xDD, 0x7E, 0x3C, 0x76, 0x91, 0x39, 0xFD, 0xA8, + 0x0D, 0x8E, 0x36, 0x6F, 0x3F, 0x74, 0x48, 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, + 0x0A, 0x87, 0x3C, 0x26, 0x02, 0xA2, 0xDD, 0xB9, 0x37, 0x61, 0x1D, 0xBF, 0x63, 0x49, 0xF0, 0xE5, + 0x08, 0x00, 0x00, 0x50, 0x7E, 0x66, 0x68, 0xBE, 0x8D, 0x02, 0x15, 0x18, 0xCD, 0x26, 0xA2, 0x22, + 0xE9, 0x54, 0x78, 0x44, 0x96, 0xE8, 0xF6, 0x23, 0x88, 0x8F, 0x76, 0x6F, 0x3F, 0x74, 0x48, 0x64, + 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0x26, 0xE2, 0x21, 0x8F, 0xBD, + 0x78, 0x1D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xD3, 0x87, 0xFF, 0x06, 0xAC, 0x5D, 0x9F, 0xB6, 0x61, + 0xA0, 0x22, 0xA3, 0xD1, 0x44, 0x54, 0x24, 0x9D, 0x08, 0x8E, 0xEA, 0x92, 0xDE, 0x7E, 0x3C, 0x6E, + 0x03, 0x24, 0x8C, 0x8F, 0x68, 0x80, 0xFC, 0x80, 0xF8, 0x20, 0x3E, 0x54, 0x38, 0xE4, 0x31, 0x11, + 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x3E, 0xCC, 0xA1, 0xFE, 0xB5, + 0x66, 0xC7, 0xC7, 0x6D, 0x1C, 0xA8, 0xD0, 0x50, 0x13, 0x51, 0x91, 0x74, 0x2A, 0x3A, 0x62, 0x53, + 0xB7, 0x1F, 0xD1, 0x00, 0xF1, 0xE3, 0xA3, 0xD1, 0xED, 0xC7, 0x37, 0x75, 0x68, 0xA8, 0xE9, 0x90, + 0xC8, 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x44, 0x43, 0xCE, + 0xE3, 0x4D, 0x58, 0x00, 0x00, 0x60, 0xDA, 0xF0, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0x36, 0x10, 0x54, + 0x6C, 0xC4, 0x27, 0xA2, 0x22, 0xE9, 0x44, 0x6C, 0xD4, 0x2C, 0xC1, 0xED, 0x87, 0xFB, 0xD6, 0xAB, + 0x89, 0xC7, 0x2E, 0x9C, 0xBC, 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0x7B, 0xC9, 0x6F, 0x3F, 0x74, 0x48, + 0x64, 0x99, 0x08, 0x89, 0x2C, 0x23, 0x3E, 0x72, 0x98, 0x0A, 0x87, 0x3C, 0xA6, 0x83, 0x21, 0xEF, + 0x79, 0x47, 0xFF, 0x64, 0x34, 0xF8, 0x92, 0x04, 0x00, 0x00, 0x28, 0x37, 0x6F, 0x78, 0xE9, 0x90, + 0x8E, 0x8D, 0xF8, 0x44, 0x54, 0x24, 0x9D, 0x0A, 0x8E, 0xF8, 0xE2, 0x01, 0xA2, 0x9E, 0xFD, 0x78, + 0xDC, 0xC6, 0x47, 0x9B, 0xB7, 0x1F, 0x3A, 0x24, 0xB2, 0x4C, 0x84, 0x44, 0x96, 0x11, 0x1F, 0x39, + 0x4C, 0x85, 0x43, 0x1E, 0xD3, 0xB1, 0x50, 0xC8, 0x8E, 0x7D, 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, + 0xE9, 0xC1, 0xDB, 0xBB, 0x24, 0xC1, 0x2B, 0x78, 0x45, 0x54, 0x24, 0x9D, 0x8A, 0x8D, 0xE8, 0x6C, + 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, 0x47, 0xEC, 0x5B, 0xAF, 0x9E, 0xB8, 0x70, 0xF2, + 0xF6, 0xC3, 0x2E, 0xCB, 0xED, 0x87, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, + 0x53, 0xE1, 0x90, 0xC7, 0x44, 0x24, 0x14, 0xB6, 0x45, 0x95, 0x37, 0x61, 0xBD, 0x7C, 0xE7, 0xEC, + 0xE0, 0xCB, 0x12, 0x00, 0x00, 0xA0, 0xBC, 0xCC, 0x1E, 0x7B, 0xF8, 0x91, 0xD1, 0x11, 0x4E, 0x44, + 0x45, 0xD2, 0xA9, 0xE0, 0x88, 0x2F, 0x1A, 0x20, 0x76, 0xD5, 0x6F, 0xBD, 0x8A, 0x06, 0x88, 0x8B, + 0x0F, 0xFF, 0xF6, 0xE3, 0xC2, 0xFA, 0xDB, 0x8F, 0x87, 0xEC, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, + 0x32, 0x11, 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xB3, + 0x5F, 0x7F, 0x6E, 0x2F, 0x7E, 0xCE, 0x05, 0xC8, 0x40, 0xF0, 0x65, 0x09, 0x00, 0x00, 0x50, 0x4E, + 0x66, 0xA4, 0x7F, 0x76, 0xF3, 0x57, 0xF0, 0x8A, 0xA8, 0x48, 0x3A, 0x15, 0x1B, 0xF1, 0xC5, 0xE2, + 0x23, 0xBC, 0xFD, 0xA8, 0x7D, 0xF0, 0xDC, 0xC6, 0x47, 0xF4, 0xF6, 0x23, 0xFE, 0xAD, 0x57, 0xF7, + 0xB7, 0xBE, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, + 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x16, 0xC4, 0x87, 0x1F, 0x20, 0xD7, 0xF0, 0x26, 0x2C, 0x00, 0x00, + 0x50, 0x7E, 0xFE, 0x2B, 0x78, 0x1B, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, 0xA9, 0xD8, 0x88, 0xAF, + 0x41, 0x7C, 0x54, 0x1F, 0x3C, 0x77, 0xB3, 0xF1, 0x51, 0x73, 0xFB, 0x11, 0x7F, 0xF0, 0xDC, 0xDD, + 0x7E, 0xDC, 0xAD, 0xA3, 0x23, 0x9C, 0x0E, 0x89, 0x2C, 0x13, 0x21, 0x91, 0x65, 0xC4, 0x47, 0x0E, + 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0xB5, 0x48, 0x7C, 0x04, 0xF3, 0x4E, 0x7C, 0x69, 0x30, + 0xF8, 0xD2, 0x04, 0x00, 0x00, 0x28, 0x27, 0xFF, 0x0D, 0x58, 0x5B, 0x3F, 0x64, 0xA3, 0x61, 0x8A, + 0xE3, 0xC3, 0x4D, 0x05, 0x48, 0xCD, 0xB7, 0x5E, 0xD9, 0xF8, 0x70, 0xB7, 0x1F, 0x41, 0x7C, 0x64, + 0xB9, 0xFD, 0xD0, 0x21, 0x91, 0x65, 0x22, 0x24, 0xB2, 0x8C, 0xF8, 0xC8, 0x61, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x56, 0x1F, 0x1F, 0x6E, 0xDE, 0xF1, 0x3F, 0xE5, 0x4D, 0x58, 0x00, 0x00, + 0xA0, 0xDC, 0xBC, 0x91, 0x81, 0x0D, 0x1D, 0x89, 0x0F, 0xB7, 0x78, 0x7C, 0x54, 0x6F, 0x3F, 0x2E, + 0xAC, 0xC6, 0xC7, 0xE4, 0xED, 0x47, 0x2C, 0x3E, 0x12, 0xDC, 0x7E, 0xE8, 0x90, 0xC8, 0x32, 0x11, + 0x12, 0x59, 0x46, 0x7C, 0xE4, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xF1, 0xE1, + 0xEF, 0xD8, 0x2D, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x94, 0x9B, 0x77, 0xE0, 0xAA, 0xD8, 0x1B, 0xB0, + 0x44, 0x54, 0x24, 0x9D, 0x8A, 0x8C, 0x46, 0xB3, 0xD1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0x44, 0x02, + 0x24, 0x8C, 0x0F, 0xF9, 0xB9, 0x1F, 0xDF, 0x69, 0x7C, 0xFB, 0xA1, 0x43, 0x22, 0xCB, 0x44, 0x48, + 0x64, 0x59, 0x34, 0x3A, 0x88, 0x8F, 0x8C, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x11, + 0x1D, 0xD1, 0xB9, 0x37, 0x61, 0x8D, 0x7D, 0x71, 0x56, 0xF0, 0xE5, 0x09, 0x00, 0x00, 0x50, 0x3E, + 0xDE, 0xBE, 0x25, 0xE3, 0x53, 0x1E, 0x1F, 0x6E, 0xF1, 0xF8, 0x48, 0x7B, 0xFB, 0xF1, 0xA0, 0x9D, + 0x08, 0x0F, 0x37, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x52, 0xC4, 0x47, 0x18, 0x20, 0x2E, + 0x3E, 0xFE, 0x40, 0x7C, 0x44, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x38, 0xE2, + 0x1B, 0x5B, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB9, 0x4D, 0xBE, 0x01, 0x4B, 0x44, 0x45, 0xD2, + 0xA9, 0xC0, 0x68, 0x36, 0x1B, 0x1D, 0xEE, 0x47, 0x75, 0xFB, 0x11, 0x0D, 0x90, 0xA6, 0xB7, 0x1F, + 0xF7, 0xE9, 0xDB, 0x0F, 0x1D, 0x12, 0x59, 0x26, 0x42, 0x22, 0xCB, 0x22, 0xF1, 0x11, 0xAE, 0x3E, + 0x3E, 0xEC, 0x5C, 0x78, 0x84, 0xB7, 0x1F, 0xC4, 0x47, 0x6C, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, + 0xA2, 0x26, 0x62, 0x43, 0xED, 0xC5, 0x6B, 0x8C, 0xF7, 0x8B, 0x2F, 0xDD, 0x15, 0x7C, 0x79, 0x02, + 0x00, 0x00, 0x94, 0x8B, 0xFF, 0x06, 0xAC, 0x9D, 0x9F, 0xD2, 0x51, 0x91, 0x74, 0xF1, 0xB8, 0x48, + 0xB2, 0x30, 0x3C, 0xC2, 0xF8, 0xF0, 0x03, 0x64, 0x66, 0x35, 0x3E, 0x6A, 0xDF, 0x7C, 0x95, 0xFC, + 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0xB2, 0x16, 0xF1, 0xF1, 0x76, 0x24, 0x3E, 0xE2, + 0x37, 0x1F, 0x6F, 0x04, 0xF1, 0xF1, 0x07, 0xE2, 0xA3, 0xA0, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x34, + 0x9A, 0xCC, 0x3B, 0x71, 0xC7, 0x86, 0xE0, 0x4B, 0x14, 0x00, 0x00, 0xA0, 0x5C, 0x6C, 0x80, 0xAC, + 0x33, 0xDB, 0x2F, 0xD6, 0x61, 0x91, 0x64, 0x2A, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0xF6, + 0xF6, 0xC3, 0xC6, 0x47, 0x83, 0x67, 0x3F, 0xEA, 0x3E, 0x74, 0xD0, 0xBD, 0xF9, 0x4A, 0xDC, 0x7E, + 0xE8, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0xD6, 0x22, 0x3E, 0xA2, 0x37, 0x1F, 0x61, 0x7C, 0x84, + 0x37, 0x1F, 0xC4, 0x47, 0x38, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x91, 0xD1, 0x6C, + 0xDE, 0x89, 0x3F, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x9C, 0xFC, 0x57, 0xF0, 0xAA, 0xB0, 0x48, + 0xB2, 0x78, 0x58, 0x24, 0x5D, 0x18, 0x1E, 0x61, 0x7C, 0x3C, 0x3D, 0xB3, 0xE6, 0xF6, 0xA3, 0xEE, + 0xD9, 0x0F, 0x1B, 0x20, 0xA7, 0xA2, 0x01, 0xF2, 0x23, 0xBB, 0x1E, 0x8C, 0x0F, 0xB7, 0xBA, 0x00, + 0x69, 0x10, 0x1F, 0xE3, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0xC0, + 0x68, 0x35, 0xEF, 0xD8, 0x17, 0xC6, 0x83, 0x2F, 0x51, 0x00, 0x00, 0x80, 0x72, 0xF1, 0x0E, 0x5C, + 0x33, 0x2A, 0xE3, 0xA2, 0xD5, 0x54, 0x58, 0x24, 0x99, 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, + 0xF1, 0x11, 0xBD, 0xFD, 0x88, 0xC5, 0x47, 0xDD, 0xED, 0xC7, 0xB7, 0x6A, 0x6F, 0x3F, 0x74, 0x48, + 0x64, 0x99, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x56, 0x17, 0x1F, 0xEA, 0x8D, 0x57, 0xC4, 0x47, + 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x71, 0x91, 0x68, 0x47, 0x56, 0xF3, 0x26, + 0x2C, 0x00, 0x00, 0x50, 0x4E, 0xDE, 0xDE, 0x25, 0x63, 0x32, 0x30, 0x9A, 0x2D, 0x1E, 0x15, 0x69, + 0x16, 0x86, 0x47, 0x18, 0x1F, 0x69, 0x6F, 0x3F, 0x7E, 0x68, 0x57, 0xB6, 0xF8, 0x70, 0x37, 0x1F, + 0x2E, 0x3E, 0xDC, 0x43, 0xE7, 0xC4, 0x87, 0x9D, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, + 0xA8, 0x48, 0xB3, 0x97, 0x56, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x4E, 0x66, 0xCF, 0x42, 0x1D, + 0x19, 0x8D, 0xA6, 0xA2, 0x22, 0xE5, 0x2A, 0x01, 0x32, 0xB3, 0xED, 0xDB, 0x0F, 0x1D, 0x12, 0x59, + 0x26, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0xB5, 0x8C, 0x8F, 0xBF, 0x9C, 0xFC, 0xAC, 0x8F, 0x3F, + 0xDC, 0x4B, 0x7C, 0x14, 0x33, 0x15, 0x09, 0x45, 0x4D, 0x04, 0x45, 0xDA, 0xBD, 0x78, 0x8D, 0x0D, + 0x90, 0x3B, 0xD6, 0x05, 0x5F, 0xA6, 0x00, 0x00, 0x00, 0xE5, 0x60, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, + 0xE6, 0xE8, 0xD0, 0x50, 0x13, 0x31, 0x91, 0x6A, 0xD5, 0xDB, 0x8F, 0x20, 0x3E, 0x9A, 0xDD, 0x7E, + 0x84, 0xF1, 0xD1, 0xE0, 0xF6, 0x43, 0x87, 0x44, 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, + 0x0D, 0xE3, 0x23, 0x08, 0x90, 0xE8, 0x07, 0x0D, 0x12, 0x1F, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, + 0xA2, 0x26, 0x62, 0x22, 0xCB, 0x9E, 0xB7, 0x7F, 0x3F, 0x4E, 0xDC, 0xB1, 0x3E, 0xF8, 0x52, 0x05, + 0x00, 0x00, 0x28, 0x07, 0xFF, 0x15, 0xBC, 0x49, 0xDF, 0x80, 0xA5, 0x82, 0x22, 0xC3, 0xFC, 0xF8, + 0x88, 0xDD, 0x7E, 0x54, 0x03, 0xA4, 0xD5, 0xED, 0xC7, 0x3D, 0xBD, 0x1B, 0x1F, 0x95, 0xD7, 0xED, + 0x12, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x24, 0xDA, 0x18, 0x6F, + 0xC2, 0x02, 0x00, 0x00, 0xA5, 0xE3, 0xBF, 0x01, 0x6B, 0xEB, 0x07, 0x75, 0x70, 0x44, 0x27, 0x42, + 0x22, 0xF5, 0xC2, 0x9B, 0x8F, 0x26, 0xB7, 0x1F, 0x13, 0x2E, 0x40, 0x1E, 0x8B, 0xDC, 0x7E, 0x84, + 0xF1, 0xE1, 0xF6, 0xBD, 0xCA, 0xB7, 0x5E, 0xE9, 0x90, 0xC8, 0x32, 0x11, 0x12, 0x59, 0x26, 0xC2, + 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x11, 0xD1, 0xCE, + 0xBC, 0x63, 0x5F, 0x38, 0x19, 0x7C, 0xA9, 0x02, 0x00, 0x00, 0x94, 0x83, 0x37, 0xBC, 0x62, 0x50, + 0x06, 0x47, 0x74, 0x2A, 0x26, 0xB2, 0x2C, 0x8C, 0x8F, 0xD8, 0xED, 0x47, 0xE2, 0x67, 0x3F, 0xBE, + 0xC9, 0xB7, 0x5D, 0x25, 0x9B, 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, + 0x2A, 0x12, 0x8A, 0x9A, 0x0E, 0x88, 0xB6, 0x77, 0x64, 0xB5, 0x09, 0xBE, 0x54, 0x01, 0x00, 0x00, + 0xCA, 0xC1, 0xDB, 0x7B, 0x79, 0xF3, 0x57, 0xF0, 0xAA, 0x90, 0x48, 0xBB, 0x4D, 0x6E, 0x93, 0xE1, + 0x31, 0x79, 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xFC, 0xF6, 0x43, 0x87, 0x44, + 0x96, 0x89, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0x0D, 0xE3, 0xC3, 0x3D, 0x70, 0x1E, 0x8B, 0x8F, + 0xF1, 0xFF, 0x32, 0xCB, 0x9C, 0xFF, 0xD7, 0x5B, 0x83, 0xF8, 0x58, 0x65, 0x0F, 0xFA, 0x2A, 0x28, + 0xD2, 0x4C, 0x84, 0x43, 0x1E, 0x93, 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, + 0x4D, 0x84, 0x43, 0x5E, 0x3B, 0xB2, 0x92, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF1, 0xF6, 0x2C, + 0x1A, 0x97, 0xE1, 0xE1, 0xA6, 0x62, 0x22, 0xCB, 0x6C, 0x78, 0x44, 0x6F, 0x3F, 0xAA, 0xDF, 0x7A, + 0x15, 0x06, 0x48, 0xCD, 0x6B, 0x77, 0x2F, 0x94, 0xB7, 0x1F, 0xEF, 0x7C, 0x23, 0xAF, 0xDB, 0x0F, + 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x2D, 0x6D, 0x7C, 0x9C, 0xFB, 0xE9, 0x17, 0x2A, 0xF1, 0x71, + 0xD4, 0xFE, 0x28, 0x83, 0x22, 0xCD, 0x44, 0x38, 0xE4, 0x31, 0x19, 0x0E, 0x79, 0x4C, 0x85, 0x43, + 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x44, 0x34, 0xE4, 0x39, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xCA, 0xC4, + 0x0C, 0xF5, 0xCF, 0x32, 0x43, 0x7D, 0x53, 0x1A, 0x1F, 0xE1, 0xED, 0x47, 0xCD, 0x83, 0xE7, 0xCD, + 0x9E, 0xFD, 0x70, 0xF1, 0x71, 0x7F, 0x5E, 0xB7, 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, + 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x82, 0x21, 0xEF, 0xB9, 0xFF, + 0x6D, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0x0B, 0xFF, 0x0D, 0x58, 0x3B, 0x3E, 0x39, 0xE5, 0xF1, + 0x51, 0x7D, 0xF0, 0x5C, 0xDD, 0x7E, 0xC4, 0x1E, 0x3C, 0x7F, 0xE7, 0x41, 0x1B, 0x1F, 0x5F, 0x57, + 0x31, 0x91, 0x76, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x62, 0xA1, 0xA0, 0x79, 0x27, 0xEE, 0xE0, 0x4D, 0x58, 0x00, 0x00, + 0xA0, 0x1C, 0xBC, 0xE1, 0xFE, 0xBB, 0xCC, 0xB6, 0x8F, 0x14, 0x13, 0x1F, 0xCF, 0x54, 0xE2, 0xA3, + 0x2E, 0x40, 0xE2, 0xAF, 0xDD, 0x75, 0xB7, 0x1F, 0x41, 0x7C, 0xC4, 0x6F, 0x3F, 0xDE, 0x79, 0xD8, + 0xC6, 0xC7, 0x77, 0xF3, 0xF8, 0xD6, 0x2B, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, + 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0xD3, 0xA1, 0x50, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, + 0x82, 0x2F, 0x59, 0x00, 0x00, 0x80, 0xDE, 0xE6, 0xBF, 0x82, 0xB7, 0xA8, 0xF8, 0x08, 0x02, 0xA4, + 0xE1, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0x8A, 0xC7, 0x47, 0x2E, 0xB7, 0x1F, 0x22, 0x24, + 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0xA6, + 0x23, 0xA1, 0xD0, 0x1D, 0xB9, 0x91, 0x37, 0x61, 0x01, 0x00, 0x80, 0x72, 0xF0, 0x0E, 0x5C, 0x33, + 0xF9, 0x06, 0x2C, 0x19, 0x12, 0x59, 0x36, 0x19, 0x1F, 0x8D, 0x6E, 0x3F, 0xAA, 0xAF, 0xDD, 0xAD, + 0xDE, 0x7E, 0x5C, 0x14, 0xBB, 0xFD, 0xB0, 0xE1, 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, + 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x38, 0x98, + 0x8A, 0xBD, 0x34, 0x60, 0xCC, 0xF1, 0x3B, 0x96, 0x04, 0x5F, 0xB6, 0x00, 0x00, 0x00, 0xBD, 0xCB, + 0xDB, 0x77, 0xC5, 0xC9, 0x42, 0xE2, 0xA3, 0xAD, 0xDB, 0x8F, 0x20, 0x3E, 0x1E, 0x68, 0xF7, 0xF6, + 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, + 0x50, 0xD4, 0x44, 0x18, 0x4C, 0xD5, 0xDC, 0x9B, 0xB0, 0x4E, 0x7C, 0x69, 0x6D, 0xF0, 0x65, 0x0B, + 0x00, 0x00, 0xD0, 0xBB, 0xCC, 0xEE, 0xBE, 0x48, 0x3C, 0xB4, 0xBB, 0xDA, 0xF8, 0x70, 0x3F, 0xAA, + 0xDB, 0x8F, 0xFA, 0x67, 0x3F, 0xA2, 0xB7, 0x1F, 0x41, 0x7C, 0xB8, 0xDD, 0xDB, 0xCE, 0xED, 0x87, + 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, + 0xA8, 0x89, 0x28, 0x98, 0xCA, 0xBD, 0x70, 0x25, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xCF, 0x1C, + 0xE8, 0x5F, 0x62, 0x76, 0xCE, 0x0E, 0xE2, 0xA1, 0xDD, 0x45, 0xE2, 0x23, 0x08, 0x90, 0x66, 0xB7, + 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xE1, 0x6E, 0x3F, 0x64, 0x58, 0x24, 0x99, 0x08, 0x89, 0x2C, + 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x20, + 0xE8, 0xC0, 0xBC, 0xE3, 0xB7, 0x0F, 0x05, 0x5F, 0xBA, 0x00, 0x00, 0x00, 0xBD, 0xC9, 0x1C, 0x5C, + 0xB6, 0xD6, 0x6C, 0xFF, 0x58, 0x10, 0x10, 0xED, 0xAC, 0x3E, 0x3E, 0xDC, 0x8F, 0xEA, 0xF6, 0x43, + 0x3D, 0xFB, 0x51, 0xF9, 0xD0, 0xC1, 0x0B, 0x27, 0x03, 0xE4, 0x21, 0xBB, 0xCC, 0xB7, 0x1F, 0x22, + 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, + 0xA6, 0x63, 0xA0, 0x13, 0xF3, 0x8E, 0xDE, 0xC2, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x33, 0x23, + 0xCB, 0xD7, 0x9B, 0xCD, 0xEF, 0xB3, 0xB1, 0xA0, 0xA2, 0x22, 0xE9, 0x62, 0xF1, 0xE1, 0x16, 0x86, + 0x47, 0x18, 0x1F, 0xB1, 0xDB, 0x8F, 0xBA, 0x67, 0x3F, 0x1E, 0xB5, 0xF1, 0xE1, 0x02, 0xA4, 0xED, + 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, + 0x45, 0x42, 0x51, 0xD3, 0x21, 0xD0, 0xB1, 0x1D, 0xBD, 0x99, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, + 0xE6, 0x1D, 0xB8, 0x7E, 0xA8, 0x36, 0x26, 0xD2, 0x4E, 0xC7, 0x87, 0xFB, 0xB1, 0xE9, 0xED, 0x47, + 0x2C, 0x3E, 0xEA, 0x6E, 0x3F, 0xEE, 0xC9, 0x72, 0xFB, 0x21, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, + 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0x22, 0x00, 0x3A, 0x3D, 0xF7, + 0x26, 0xAC, 0x97, 0xEF, 0x9C, 0x1D, 0x7C, 0xF9, 0x02, 0x00, 0x00, 0xF4, 0x1E, 0x6F, 0xEF, 0x65, + 0xA3, 0xF5, 0x51, 0x91, 0x74, 0xB1, 0xF0, 0x08, 0x17, 0x86, 0x47, 0x18, 0x1F, 0x4D, 0x6F, 0x3F, + 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x4E, 0x06, 0x46, 0xB3, 0x89, 0x90, 0xC8, + 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, + 0xFC, 0x77, 0xC3, 0x5E, 0xFC, 0x9C, 0x31, 0xC7, 0x6E, 0x1B, 0x08, 0xBE, 0x7C, 0x01, 0x00, 0x00, + 0x7A, 0x8F, 0xD9, 0x63, 0x0F, 0x5B, 0x32, 0x2E, 0x5A, 0x4D, 0x84, 0x47, 0x64, 0xC9, 0x6E, 0x3F, + 0x2A, 0xF1, 0xD1, 0xFE, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, + 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xFE, 0xDD, 0x32, 0xDE, 0x84, 0x05, 0x00, + 0x00, 0x7A, 0x99, 0x19, 0xE9, 0x9F, 0x6D, 0x76, 0xCF, 0xB3, 0xC1, 0xA0, 0x02, 0xA3, 0xD9, 0x74, + 0x74, 0xF8, 0x4B, 0x7C, 0xFB, 0x31, 0xD3, 0x9C, 0x09, 0xE3, 0xA3, 0xAD, 0xDB, 0x0F, 0x11, 0x12, + 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xFE, 0x2E, 0x9B, 0x77, 0xE2, 0xF6, 0xC1, 0xE0, 0x4B, 0x18, 0x00, 0x00, 0xA0, 0xB7, 0xD8, + 0x00, 0x19, 0x48, 0xFF, 0x06, 0x2C, 0x11, 0x1D, 0xB1, 0xA9, 0xDB, 0x8F, 0x6A, 0x80, 0x84, 0xF1, + 0x91, 0xCB, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, + 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7F, 0xB7, 0xCD, 0x3B, 0xFA, 0x85, 0xD1, 0xE0, 0x4B, + 0x18, 0x00, 0x00, 0xA0, 0xB7, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0x3E, 0x60, 0xA3, 0x41, 0x85, + 0x86, 0x9A, 0x0E, 0x8E, 0xEA, 0x12, 0xDC, 0x7E, 0x4C, 0x3C, 0x31, 0xD3, 0x4C, 0x3C, 0x16, 0xB9, + 0xFD, 0x08, 0xE3, 0xC3, 0xED, 0xFB, 0xC4, 0x47, 0x65, 0x22, 0x1C, 0xF2, 0x98, 0x0C, 0x87, 0x3C, + 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0xB0, 0xDF, 0x95, 0x3B, 0x76, 0x0B, 0x6F, + 0xC2, 0x02, 0x00, 0x00, 0xBD, 0xC9, 0x1B, 0x59, 0xB1, 0xA1, 0x3E, 0x32, 0x1A, 0x4D, 0x04, 0x47, + 0x7C, 0xF1, 0x00, 0xA9, 0x7B, 0xF6, 0xC3, 0xC6, 0x47, 0xB3, 0xDB, 0x8F, 0x6F, 0xA8, 0xD0, 0x50, + 0x13, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, + 0x14, 0x35, 0x71, 0xC8, 0xEF, 0xE6, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xAB, 0xBC, 0x7D, 0x57, + 0x24, 0x7C, 0x03, 0x96, 0x88, 0x8D, 0xE8, 0x6C, 0x70, 0x54, 0xE3, 0xC3, 0x86, 0xC7, 0xE4, 0xED, + 0x47, 0xE4, 0x5B, 0xAF, 0x06, 0x6D, 0x7C, 0x44, 0x6F, 0x3F, 0xEC, 0x6A, 0x6E, 0x3F, 0x36, 0x24, + 0xBD, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, + 0x54, 0x24, 0x14, 0x35, 0x71, 0xC0, 0xEF, 0xF6, 0x8D, 0x2D, 0xE5, 0x4D, 0x58, 0x00, 0x00, 0xA0, + 0x37, 0x79, 0x7B, 0x2F, 0x1B, 0xAF, 0x8F, 0x8D, 0xF8, 0x62, 0xB1, 0xA1, 0x16, 0x0D, 0x10, 0xBB, + 0xEA, 0xB7, 0x5E, 0x85, 0x01, 0x62, 0xE3, 0x63, 0xF2, 0xF6, 0x63, 0x66, 0x1B, 0xB7, 0x1F, 0x22, + 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, + 0x26, 0x0E, 0xF7, 0xBD, 0xB0, 0x17, 0xAF, 0x31, 0xDE, 0x2F, 0x6E, 0xBF, 0x2B, 0xF8, 0x32, 0x06, + 0x00, 0x00, 0xE8, 0x1D, 0xAD, 0xDF, 0x80, 0x15, 0x0B, 0x0D, 0xB5, 0x58, 0x7C, 0x84, 0xB7, 0x1F, + 0x93, 0x0F, 0x9E, 0xDB, 0xF8, 0x88, 0xDF, 0x7E, 0x84, 0xF1, 0x11, 0x06, 0x48, 0xA2, 0xDB, 0x0F, + 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, + 0x51, 0x13, 0x07, 0xFB, 0x1E, 0x9A, 0x77, 0xFC, 0x8E, 0x0D, 0xC1, 0x97, 0x31, 0x00, 0x00, 0x40, + 0x6F, 0xF0, 0xDF, 0x80, 0xB5, 0x73, 0xB6, 0x8D, 0x08, 0x15, 0x1E, 0x6E, 0xB1, 0xD0, 0x50, 0x6B, + 0x10, 0x1F, 0xD5, 0x07, 0xCF, 0x37, 0xCE, 0xAC, 0xBF, 0xFD, 0x08, 0xE2, 0xA3, 0x7A, 0xFB, 0xF1, + 0xA0, 0xDD, 0xD7, 0x55, 0x70, 0x44, 0x27, 0x42, 0x22, 0xCB, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, + 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xFA, 0x50, 0xDF, 0x4B, 0xF3, 0x8E, 0xDE, 0xCA, + 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x6F, 0x31, 0x23, 0xCB, 0xD7, 0x35, 0x7E, 0x05, 0x6F, 0x2C, 0x34, + 0x1A, 0x4D, 0x05, 0x48, 0xF5, 0x5B, 0xAF, 0x6C, 0x7C, 0x84, 0xB7, 0x1F, 0x41, 0x7C, 0xC8, 0x37, + 0x5F, 0x7D, 0xB7, 0xD5, 0xED, 0x87, 0x08, 0x89, 0x2C, 0x13, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, + 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0xE9, 0x03, 0x7D, 0xAF, 0xCD, 0x3B, 0xFA, 0xF9, 0xF1, + 0xE0, 0x4B, 0x19, 0x00, 0x00, 0xA0, 0x37, 0xD8, 0x00, 0x59, 0x5F, 0x1F, 0x1E, 0x29, 0xE2, 0xC3, + 0x2D, 0x1E, 0x1F, 0xD5, 0xDB, 0x8F, 0xC9, 0xF8, 0xA8, 0x79, 0xF3, 0x55, 0xEA, 0xDB, 0x0F, 0x11, + 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, + 0xD3, 0x87, 0xF9, 0x9E, 0x9C, 0x7B, 0x13, 0xD6, 0xD8, 0x17, 0x67, 0x05, 0x5F, 0xCE, 0x00, 0x00, + 0x00, 0xDD, 0xCF, 0x3B, 0x70, 0xD5, 0x50, 0xBB, 0xF1, 0xA1, 0x6F, 0x3F, 0x6C, 0x7C, 0xD4, 0xDD, + 0x7E, 0x5C, 0x98, 0xE1, 0xF6, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, + 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBE, 0x97, 0x37, 0xB6, 0x9C, 0x37, 0x61, + 0x01, 0x00, 0x80, 0xDE, 0xE2, 0xED, 0xBD, 0x7C, 0x2C, 0x73, 0x7C, 0xB8, 0xC5, 0xE3, 0xC3, 0x0F, + 0x90, 0x19, 0x39, 0xDD, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, + 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xC0, 0xF7, 0xFA, 0x78, 0x13, 0x16, 0x00, 0x00, + 0xE8, 0x35, 0x66, 0x68, 0x81, 0x0D, 0x89, 0xEC, 0xF1, 0xE1, 0x7E, 0xAC, 0xBD, 0xFD, 0xB0, 0xF1, + 0x11, 0xFB, 0xF6, 0xAB, 0xA6, 0xB7, 0x1F, 0xF7, 0x35, 0xBA, 0xFD, 0x10, 0x21, 0x91, 0x65, 0x22, + 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x78, 0x2F, + 0xC3, 0x9E, 0xBF, 0x9C, 0x37, 0x61, 0x01, 0x00, 0x80, 0xDE, 0x61, 0x0E, 0xF4, 0x2F, 0x31, 0xBB, + 0x2E, 0xB5, 0x11, 0x91, 0x21, 0x3E, 0xDC, 0xC2, 0xF0, 0x08, 0xE3, 0xE3, 0xE9, 0x19, 0x35, 0xB7, + 0x1F, 0xB5, 0x6F, 0xBE, 0x12, 0xF1, 0xF1, 0x80, 0x1D, 0xF1, 0x91, 0xCF, 0x64, 0x38, 0xE4, 0x31, + 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x07, 0xF7, 0x12, 0xCD, 0x3B, 0xFE, 0x67, 0xBC, + 0x09, 0x0B, 0x00, 0x00, 0xF4, 0x06, 0xFF, 0x15, 0xBC, 0xFE, 0x1B, 0xB0, 0x44, 0x5C, 0xB4, 0x9A, + 0x8D, 0x0E, 0xF7, 0xE3, 0x64, 0x80, 0x04, 0xF1, 0xD1, 0xE0, 0xD9, 0x0F, 0xF9, 0xA1, 0x83, 0xF7, + 0xAA, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, + 0x4C, 0x45, 0x42, 0x51, 0xD3, 0x87, 0xF6, 0x32, 0xCD, 0x3B, 0xFA, 0xF9, 0x93, 0xC1, 0x97, 0x34, + 0x00, 0x00, 0x40, 0x77, 0xF3, 0xDF, 0x80, 0xB5, 0xE5, 0xFD, 0xF5, 0x71, 0x91, 0x64, 0x61, 0x78, + 0x84, 0xF1, 0x11, 0xBB, 0xFD, 0xA8, 0x7B, 0xF6, 0xC3, 0x06, 0xC8, 0x29, 0x17, 0x20, 0x4D, 0x6F, + 0x3F, 0x44, 0x48, 0x64, 0x99, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, + 0x09, 0x45, 0x4D, 0x1F, 0xD8, 0x4B, 0xB7, 0x23, 0xAB, 0x4C, 0xF0, 0x25, 0x0D, 0x00, 0x00, 0xD0, + 0xDD, 0xBC, 0xE1, 0x65, 0x83, 0x32, 0x2E, 0x5A, 0xCD, 0x46, 0x87, 0xFB, 0xB1, 0x12, 0x20, 0x33, + 0xF4, 0xED, 0x47, 0x2C, 0x3E, 0x5A, 0xDF, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, + 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA8, 0x97, 0x75, 0x63, 0xCB, + 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0D, 0xDE, 0xDE, 0xCB, 0x46, 0xEB, 0xE2, 0x22, 0xC9, 0xAA, + 0xB7, 0x1F, 0x41, 0x7C, 0x24, 0xBD, 0xFD, 0x08, 0x03, 0xE4, 0x07, 0x76, 0xC4, 0x47, 0x7B, 0x93, + 0xE1, 0x90, 0xC7, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0xBA, 0x7F, + 0x5D, 0x68, 0xCC, 0x0B, 0x57, 0x1B, 0x73, 0xFC, 0x8E, 0x75, 0xC1, 0x97, 0x35, 0x00, 0x00, 0x40, + 0xF7, 0xF2, 0xF6, 0x2C, 0x18, 0x97, 0x81, 0xD1, 0x6C, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0x59, 0x6F, + 0x3F, 0xEE, 0x89, 0xDE, 0x7E, 0x88, 0x90, 0xC8, 0x32, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, + 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2E, 0x3E, 0xDC, 0x7E, 0x6E, + 0xFF, 0x99, 0x38, 0x71, 0xDB, 0xFA, 0xE0, 0xCB, 0x1A, 0x00, 0x00, 0xA0, 0x3B, 0x99, 0xA1, 0xFE, + 0x59, 0x66, 0xF7, 0xDC, 0xFA, 0xC0, 0x68, 0xB5, 0xF0, 0xE6, 0x23, 0x97, 0xDB, 0x0F, 0x11, 0x12, + 0x59, 0x26, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xF4, 0xB2, 0x2E, 0x8C, 0x8F, 0x60, 0xDE, 0x89, 0xDB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, + 0x6E, 0x66, 0x64, 0xE9, 0x80, 0xD9, 0xF1, 0x71, 0x1D, 0x19, 0xCD, 0x16, 0xC6, 0x47, 0xDB, 0xB7, + 0x1F, 0x22, 0x24, 0xB2, 0x4C, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, + 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x5D, 0x2C, 0x3E, 0xFC, 0x00, 0x39, 0x7A, 0x33, 0x6F, 0xC2, + 0x02, 0x00, 0x00, 0xDD, 0xCD, 0x1B, 0x5E, 0x7E, 0x97, 0xD9, 0xFA, 0x21, 0x1D, 0x19, 0x8D, 0x16, + 0x8F, 0x8F, 0x66, 0xB7, 0x1F, 0x61, 0x7C, 0xC8, 0xDB, 0x0F, 0x11, 0x12, 0x59, 0x26, 0xC2, 0xC3, + 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, + 0xC4, 0x87, 0xBF, 0x23, 0x37, 0xF0, 0x26, 0x2C, 0x00, 0x00, 0xD0, 0xDD, 0xFC, 0x57, 0xF0, 0xAA, + 0xC8, 0x68, 0x34, 0x1B, 0x1D, 0x8D, 0x6E, 0x3F, 0xAA, 0x01, 0xD2, 0xEA, 0xF6, 0xE3, 0x1B, 0xC4, + 0x47, 0xA6, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, + 0x65, 0x9D, 0x0A, 0x8F, 0x70, 0x2F, 0xF5, 0xBB, 0x07, 0xD1, 0x97, 0x04, 0x5F, 0xDE, 0x00, 0x00, + 0x00, 0xDD, 0xC7, 0x3B, 0x70, 0x75, 0xF2, 0x37, 0x60, 0x45, 0xE3, 0xC3, 0x86, 0x47, 0xA3, 0xDB, + 0x8F, 0x09, 0x17, 0x20, 0x8F, 0x45, 0x6E, 0x3F, 0xC2, 0xF8, 0x70, 0xDB, 0xE0, 0xBE, 0xF5, 0x4A, + 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, + 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xD1, 0x11, 0x9D, 0x7B, 0x13, 0xD6, 0x89, 0x3F, 0x5F, 0x1B, + 0x7C, 0x79, 0x03, 0x00, 0x00, 0x74, 0x1F, 0x6F, 0xDF, 0xE5, 0x27, 0x65, 0x6C, 0xC4, 0x17, 0xC4, + 0x47, 0xA3, 0xDB, 0x8F, 0xC4, 0xCF, 0x7E, 0x7C, 0x43, 0x84, 0x44, 0x96, 0x89, 0xF0, 0x70, 0x23, + 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xC1, + 0x11, 0x1F, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0xDD, 0x2E, 0xD1, 0x1B, 0xB0, 0xE2, 0xF1, 0x51, 0x73, + 0xFB, 0x11, 0xF9, 0xD6, 0xAB, 0xF8, 0xED, 0x87, 0x5D, 0xED, 0xED, 0x47, 0x4E, 0xDF, 0x7A, 0x25, + 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, + 0xB2, 0x4E, 0xC5, 0x46, 0x83, 0x79, 0xC7, 0x6F, 0x1F, 0x0A, 0xBE, 0xBC, 0x01, 0x00, 0x00, 0xBA, + 0x8B, 0x39, 0x70, 0xFD, 0x12, 0xB3, 0xF3, 0x53, 0x3A, 0x3A, 0xC2, 0x45, 0xE2, 0xA3, 0x1A, 0x20, + 0x76, 0xD5, 0x6F, 0xBD, 0x0A, 0x03, 0xA4, 0xE6, 0xB5, 0xBB, 0x33, 0xC5, 0xED, 0xC7, 0xCC, 0x7C, + 0x6E, 0x3F, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, + 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0xC8, 0x68, 0x36, 0xEF, 0xC8, 0x9A, 0xB1, 0xE0, 0x4B, 0x1C, 0x00, + 0x00, 0xA0, 0xBB, 0x98, 0x83, 0xCB, 0xD6, 0x9A, 0xED, 0x1F, 0xD5, 0xE1, 0xE1, 0x16, 0x09, 0x8F, + 0x68, 0x7C, 0x84, 0xB7, 0x1F, 0x35, 0x0F, 0x9E, 0x37, 0x7A, 0xF6, 0xC3, 0x0F, 0x10, 0x1B, 0x1F, + 0xDF, 0xCD, 0xE1, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, + 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x08, 0x8C, 0x96, 0x3B, 0xBA, 0x86, 0x37, 0x61, 0x01, + 0x00, 0x80, 0xEE, 0xE4, 0xBF, 0x01, 0x6B, 0xF3, 0xAC, 0x4C, 0xF1, 0x51, 0x7D, 0xF0, 0x5C, 0xDD, + 0x7E, 0x04, 0xF1, 0x51, 0xB9, 0xFD, 0xB0, 0xF1, 0xF1, 0xA0, 0xDD, 0xD7, 0x45, 0x50, 0xA4, 0x99, + 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, + 0xCB, 0x3A, 0x15, 0x17, 0x49, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB7, 0xF2, 0x0E, 0x7C, 0x6E, + 0x28, 0x49, 0x7C, 0xD4, 0x05, 0x48, 0xFC, 0xB5, 0xBB, 0xEE, 0xF6, 0x23, 0x88, 0x8F, 0xDA, 0x37, + 0x5F, 0xD9, 0xF0, 0xC8, 0xE3, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x0A, 0x8B, 0xA4, 0x7B, 0xE1, 0x5A, 0x63, + 0x8E, 0xDD, 0x36, 0x10, 0x7C, 0x99, 0x03, 0x00, 0x00, 0x74, 0x0F, 0x6F, 0xEF, 0x65, 0xF5, 0xAF, + 0xE0, 0x8D, 0x44, 0x87, 0x8C, 0x8F, 0xE8, 0xED, 0x47, 0x10, 0x1F, 0x35, 0x6F, 0xBE, 0xAA, 0xDE, + 0x7E, 0x04, 0xF1, 0xD1, 0xEE, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, + 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x15, 0x69, 0xF6, 0xFC, 0x67, 0x79, + 0x13, 0x16, 0x00, 0x00, 0xE8, 0x4E, 0x66, 0x8F, 0x3D, 0xEC, 0xB4, 0x88, 0x0F, 0x37, 0x75, 0xFB, + 0x51, 0x7D, 0xED, 0x6E, 0xF5, 0xF6, 0xE3, 0xC2, 0xC8, 0xED, 0x47, 0x10, 0x1F, 0xED, 0xDE, 0x7E, + 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0x62, 0x07, + 0xF4, 0x32, 0x4F, 0x05, 0x45, 0x86, 0x79, 0x27, 0x6E, 0x1B, 0x0C, 0xBE, 0xCC, 0x01, 0x00, 0x00, + 0xBA, 0x83, 0x19, 0xE9, 0x9F, 0x5D, 0xF3, 0x0A, 0xDE, 0x48, 0x70, 0x44, 0x97, 0xFE, 0xF6, 0x63, + 0xE6, 0x64, 0x80, 0x3C, 0x60, 0xA7, 0xC2, 0x22, 0xC9, 0x44, 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, + 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0x89, 0x90, 0xC8, 0x3A, 0xEF, + 0xC8, 0xE7, 0x47, 0x83, 0x2F, 0x75, 0x00, 0x00, 0x80, 0xEE, 0x60, 0x46, 0x96, 0x0E, 0x54, 0xDF, + 0x80, 0x15, 0x09, 0x8E, 0xF8, 0xD4, 0xED, 0x47, 0xFD, 0xB3, 0x1F, 0xE1, 0xED, 0x47, 0x24, 0x3E, + 0xDC, 0xEE, 0xCD, 0x78, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, + 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x44, 0x44, 0x5B, 0xE3, 0x4D, 0x58, 0x00, 0x00, + 0xA0, 0xDB, 0x78, 0xC3, 0xCB, 0xEF, 0x32, 0x5B, 0xDE, 0x2F, 0xA3, 0x23, 0x5C, 0xB3, 0xDB, 0x8F, + 0xDA, 0x37, 0x5F, 0x89, 0xF8, 0xC8, 0x7A, 0xFB, 0x21, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, + 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x05, 0x44, 0xBB, 0x73, 0x6F, + 0xC2, 0x7A, 0xF9, 0xCE, 0xD9, 0xC1, 0x97, 0x3B, 0x00, 0x00, 0x40, 0xE7, 0x79, 0x23, 0xCB, 0x36, + 0xA8, 0xE8, 0x88, 0x4E, 0xDD, 0x7E, 0xD4, 0x3F, 0xFB, 0xE1, 0x3E, 0x74, 0xD0, 0xBD, 0x7A, 0x37, + 0x12, 0x20, 0xEE, 0x43, 0x07, 0xB3, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, + 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x53, 0xF1, 0x90, 0xC7, 0x5E, 0xBC, + 0x9E, 0x37, 0x61, 0x01, 0x00, 0x80, 0xEE, 0xE2, 0xED, 0xBD, 0x62, 0x54, 0x45, 0x47, 0xB8, 0x66, + 0xB7, 0x1F, 0xD5, 0x67, 0x3F, 0xFC, 0xD7, 0xEE, 0x06, 0xF1, 0xE1, 0xD6, 0xCE, 0xED, 0x87, 0x08, + 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, + 0x3A, 0x15, 0x0E, 0x79, 0xED, 0x85, 0xAB, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x2E, 0xDE, 0xDE, + 0xC5, 0xE3, 0x2A, 0x3C, 0xC2, 0x35, 0xBD, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC5, 0x87, 0xBA, 0xFD, + 0xB8, 0x27, 0xE5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, + 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x15, 0x0D, 0x39, 0xCF, 0x3B, 0xB6, 0x96, 0x37, 0x61, + 0x01, 0x00, 0x80, 0xEE, 0xE1, 0xBF, 0x01, 0x2B, 0x12, 0x1C, 0xD1, 0xB5, 0xBC, 0xFD, 0xB0, 0xF1, + 0x31, 0xF1, 0xD8, 0x8C, 0xDA, 0xDB, 0x8F, 0x30, 0x40, 0x7E, 0x60, 0xA7, 0x22, 0xA3, 0xD1, 0x44, + 0x78, 0xB8, 0x11, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, + 0xD6, 0x89, 0x58, 0x28, 0x62, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0E, 0xFE, + 0x1B, 0xB0, 0x76, 0x7C, 0x52, 0xC6, 0x87, 0x5B, 0xCB, 0xDB, 0x8F, 0x30, 0x3E, 0xDA, 0xBD, 0xFD, + 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, + 0x7A, 0x59, 0x27, 0x42, 0xA1, 0xA8, 0x79, 0x47, 0x6F, 0x1E, 0x0F, 0xBE, 0xE4, 0x01, 0x00, 0x00, + 0x3A, 0xCB, 0x8C, 0x2C, 0x5F, 0x67, 0xB6, 0x7D, 0xA4, 0x75, 0x7C, 0xC8, 0xDB, 0x8F, 0x19, 0xF9, + 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, + 0xC4, 0x21, 0xBD, 0xAC, 0x13, 0x91, 0x50, 0xE8, 0xDC, 0x9B, 0xB0, 0xC6, 0xBE, 0x38, 0x2B, 0xF8, + 0xB2, 0x07, 0x00, 0x00, 0xE8, 0x1C, 0x1B, 0x20, 0xEB, 0x55, 0x7C, 0xB8, 0xA9, 0xDB, 0x0F, 0x3F, + 0x40, 0x44, 0x7C, 0x64, 0xBE, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, + 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA1, 0xE8, 0xF1, 0x26, 0x2C, 0x00, + 0x00, 0xD0, 0x2D, 0xBC, 0x03, 0x57, 0x0D, 0x35, 0x8C, 0x0F, 0x1B, 0x1E, 0xF2, 0xF6, 0xE3, 0x09, + 0x1B, 0x1F, 0x2E, 0x40, 0x1E, 0x8D, 0xDC, 0x7E, 0x84, 0xF1, 0xE1, 0xB6, 0x81, 0xF8, 0xA8, 0x9B, + 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xA9, + 0x38, 0x98, 0x8A, 0xBD, 0x70, 0xB5, 0xF1, 0x7E, 0x71, 0xFB, 0x5D, 0xC1, 0x97, 0x3D, 0x00, 0x00, + 0x40, 0xE7, 0x78, 0x7B, 0x2F, 0x1B, 0x6B, 0x18, 0x20, 0x6E, 0x91, 0xDB, 0x0F, 0x17, 0x1F, 0x67, + 0x07, 0x67, 0xD4, 0xDE, 0x7E, 0xA8, 0x67, 0x3F, 0xBE, 0x21, 0x62, 0x23, 0x3E, 0x11, 0x1E, 0x6E, + 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x2A, + 0x0C, 0xA6, 0x70, 0xDE, 0xF1, 0xDB, 0x36, 0x04, 0x5F, 0xF6, 0x00, 0x00, 0x00, 0x9D, 0x63, 0x86, + 0xE6, 0xEB, 0xF8, 0xA8, 0xB9, 0xFD, 0x08, 0xBF, 0xF5, 0xCA, 0xC6, 0x47, 0x1E, 0xB7, 0x1F, 0x22, + 0x3C, 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, + 0xEB, 0x44, 0x10, 0x4C, 0xF5, 0xBC, 0xE3, 0x7F, 0xC6, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x67, 0x99, + 0x91, 0xFE, 0xD9, 0x66, 0xE7, 0x25, 0x3A, 0x40, 0xEC, 0xA2, 0xDF, 0x7A, 0x75, 0xEE, 0xC9, 0x19, + 0xE6, 0xAC, 0x8D, 0x8F, 0xC9, 0xDB, 0x8F, 0x19, 0xFA, 0xD9, 0x8F, 0x56, 0xB7, 0x1F, 0x22, 0x3C, + 0xDC, 0x88, 0x8F, 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, + 0x44, 0x0C, 0x74, 0x62, 0xBC, 0x09, 0x0B, 0x00, 0x00, 0x74, 0x9C, 0xFF, 0x0A, 0xDE, 0xD8, 0x1B, + 0xB0, 0x6A, 0xBE, 0xF5, 0xCA, 0xEE, 0x9C, 0x0B, 0x10, 0x17, 0x1F, 0xF1, 0xDB, 0x8F, 0x68, 0x7C, + 0x84, 0x01, 0x72, 0x7F, 0x8B, 0xDB, 0x0F, 0x11, 0x1E, 0x6E, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, + 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0x22, 0x04, 0x3A, 0xB6, 0x97, 0x56, 0x99, + 0xE0, 0x4B, 0x1F, 0x00, 0x00, 0xA0, 0x33, 0xFC, 0x37, 0x60, 0x6D, 0xFE, 0xE3, 0x86, 0xF1, 0x51, + 0xB9, 0xFD, 0xB0, 0xF1, 0xD1, 0xE0, 0xF6, 0xC3, 0xC5, 0x47, 0xF5, 0xF6, 0xE3, 0x41, 0xBB, 0xAF, + 0x8B, 0xE8, 0x08, 0x27, 0xC2, 0xC3, 0x8D, 0xF8, 0x48, 0x33, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, + 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x45, 0x40, 0x27, 0x37, 0xB6, 0x8C, 0x37, 0x61, 0x01, 0x00, + 0x80, 0xCE, 0xF2, 0x86, 0x97, 0x0D, 0x36, 0xBC, 0xFD, 0x08, 0xE2, 0xA3, 0xE6, 0xF6, 0x23, 0x88, + 0x8F, 0x9A, 0xDB, 0x8F, 0xF0, 0xD9, 0x8F, 0xEF, 0x36, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, 0x46, 0x7C, + 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0xA7, 0x02, 0xA0, + 0xD3, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0xF2, 0x07, 0x00, 0x00, 0x98, 0x7A, + 0xDE, 0xDE, 0xCB, 0x46, 0x1B, 0xDE, 0x7E, 0x6C, 0xBC, 0xA0, 0x26, 0x3E, 0xEA, 0x3E, 0x74, 0x30, + 0xE9, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, + 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x75, 0xF8, 0xEF, 0xF8, 0x16, 0xD8, 0x5F, 0x9B, 0xFD, 0xDF, 0xE1, + 0xC4, 0x6D, 0xEB, 0x83, 0x2F, 0x7F, 0x00, 0x00, 0x80, 0xA9, 0xE7, 0xED, 0x9E, 0x3F, 0xAE, 0x6F, + 0x3F, 0x6C, 0x7C, 0x84, 0xDF, 0x7A, 0x55, 0x73, 0xFB, 0x31, 0x33, 0xDD, 0xED, 0x87, 0x08, 0x0F, + 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, 0xE4, 0xB1, 0x78, 0x20, 0x14, 0x39, 0x71, 0x48, 0x2F, 0xEB, + 0xE4, 0xE1, 0xBF, 0xD3, 0xB3, 0xF1, 0x11, 0xCC, 0x3B, 0xBE, 0x96, 0x37, 0x61, 0x01, 0x00, 0x80, + 0xCE, 0x30, 0x43, 0xFD, 0xB3, 0xCC, 0xEE, 0xB9, 0x32, 0x3E, 0x72, 0xB9, 0xFD, 0x10, 0xE1, 0xE1, + 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, + 0x0F, 0xFF, 0x9D, 0xDE, 0x64, 0x7C, 0xF8, 0x01, 0x72, 0xF4, 0xE6, 0x93, 0xC1, 0x1F, 0x01, 0x00, + 0x00, 0x00, 0x53, 0xCB, 0x7F, 0x03, 0xD6, 0xF6, 0x8B, 0x6B, 0x03, 0x24, 0x8C, 0x0F, 0xF9, 0xEC, + 0x47, 0x83, 0xDB, 0x8F, 0x7B, 0xC5, 0xED, 0x87, 0x08, 0x0F, 0x37, 0xE2, 0x23, 0xCD, 0x54, 0x38, + 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x6A, 0xE3, + 0xC3, 0xDF, 0x91, 0x1B, 0x78, 0x13, 0x16, 0x00, 0x00, 0xE8, 0x0C, 0x33, 0xB2, 0x7C, 0x9D, 0xD9, + 0xFA, 0xC1, 0xC8, 0xED, 0x87, 0x8D, 0x8F, 0xD8, 0xED, 0x47, 0xED, 0x9B, 0xAF, 0x44, 0x7C, 0x3C, + 0x60, 0x47, 0x7C, 0x14, 0x30, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, + 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x11, 0x1F, 0x6E, 0x2F, 0xF5, 0xF3, 0x26, 0x2C, 0x00, 0x00, 0xD0, + 0x19, 0xE6, 0xE0, 0xF2, 0xF5, 0xD5, 0xDB, 0x0F, 0x1B, 0x1F, 0xD1, 0xDB, 0x0F, 0xF5, 0xEC, 0xC7, + 0xE9, 0x78, 0x80, 0xB8, 0x0F, 0x1D, 0x8C, 0xDF, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, + 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, + 0x84, 0x47, 0x38, 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x00, 0x00, 0x00, 0x60, + 0xEA, 0x78, 0xFB, 0xAE, 0x1E, 0xAD, 0x89, 0x8F, 0x24, 0xCF, 0x7E, 0xB8, 0x35, 0xBA, 0xFD, 0x10, + 0xE1, 0xE1, 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, + 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x88, 0x8E, 0xE8, 0xDC, 0x3F, 0x67, 0xBC, 0x09, 0x0B, 0x00, + 0x00, 0x74, 0x82, 0xB7, 0xF7, 0xF2, 0x93, 0x7E, 0x7C, 0x34, 0xBA, 0xFD, 0x88, 0xC6, 0x87, 0xBA, + 0xFD, 0xF8, 0x76, 0xE4, 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, + 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x38, 0xC4, 0xBC, + 0xE3, 0xB7, 0x0F, 0x05, 0x7F, 0x0C, 0x00, 0x00, 0x00, 0x4C, 0x1D, 0x6F, 0xE7, 0x9C, 0xF4, 0xB7, + 0x1F, 0x61, 0x80, 0xFC, 0xC0, 0x8E, 0xF8, 0xC8, 0x71, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, + 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x36, 0xD4, 0xBC, 0x23, 0x6B, 0xC6, + 0x82, 0x3F, 0x06, 0x00, 0x00, 0x00, 0xA6, 0x86, 0x39, 0x70, 0xFD, 0x12, 0x6F, 0xFB, 0x27, 0xB2, + 0xDF, 0x7E, 0xDC, 0x13, 0xDC, 0x7E, 0x88, 0xF0, 0x70, 0x23, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, + 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x87, 0x46, 0xC3, + 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x30, 0xD5, 0xCC, 0xC1, 0x65, 0x6B, 0xBD, 0xAD, 0x1F, 0x6E, 0xEF, + 0xF6, 0x43, 0x84, 0x87, 0x1B, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, + 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x30, 0x5A, 0xCD, 0xBD, 0x09, 0xEB, 0xF8, + 0x1D, 0x4B, 0x82, 0x3F, 0x0E, 0x00, 0x00, 0x00, 0x8A, 0x77, 0xFE, 0xE0, 0xD2, 0xF5, 0xDE, 0xA6, + 0x0B, 0x33, 0xDE, 0x7E, 0x10, 0x1F, 0xF9, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, + 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC4, 0x45, 0x92, 0xBD, 0x70, 0x0D, 0x6F, 0xC2, + 0x02, 0x00, 0x00, 0x53, 0xEB, 0xFC, 0xFE, 0x6B, 0x06, 0xB3, 0xDD, 0x7E, 0xCC, 0x90, 0xE1, 0xE1, + 0x46, 0x7C, 0xA4, 0x99, 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, + 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x8B, 0xA4, 0x7B, 0xFE, 0x0A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xA6, + 0xD6, 0xF9, 0xDD, 0x8B, 0x47, 0xA3, 0xB7, 0x1F, 0xD5, 0x00, 0x89, 0xC5, 0x47, 0xDD, 0xED, 0xC7, + 0xDD, 0xC4, 0x47, 0xFB, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, + 0xE4, 0xE1, 0xBF, 0xD3, 0x13, 0x51, 0x91, 0x72, 0xDE, 0xB1, 0xB5, 0xBC, 0x09, 0x0B, 0x00, 0x00, + 0x4C, 0x1D, 0x6F, 0xF7, 0x42, 0x79, 0xFB, 0x31, 0xE1, 0x02, 0xE4, 0xD1, 0xC8, 0xED, 0x47, 0x18, + 0x1F, 0x6E, 0xF7, 0xEB, 0x6F, 0xBD, 0x22, 0x3E, 0xD2, 0x4C, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, + 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x07, 0x45, 0xDA, 0x79, 0x47, 0x3E, + 0x3F, 0x1A, 0xFC, 0x71, 0x00, 0x00, 0x00, 0x50, 0x2C, 0x33, 0xD2, 0x3F, 0xDB, 0xDB, 0x31, 0x27, + 0xDD, 0xB3, 0x1F, 0x0F, 0xCE, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, + 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x98, 0xC8, 0xB4, 0xA3, + 0x6B, 0x78, 0x13, 0x16, 0x00, 0x00, 0x98, 0x1A, 0x66, 0xFF, 0xD2, 0x81, 0xF3, 0x5B, 0x3E, 0x6C, + 0x03, 0x24, 0xF2, 0xAD, 0x57, 0xCD, 0x6E, 0x3F, 0x1E, 0xB2, 0xF1, 0x21, 0x6E, 0x3F, 0x88, 0x8F, + 0x34, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, + 0xD3, 0x13, 0x11, 0xD1, 0xCE, 0xDC, 0x9B, 0xB0, 0x5E, 0xBE, 0x73, 0x76, 0xF0, 0xC7, 0x02, 0x00, + 0x00, 0x40, 0x71, 0xCE, 0xED, 0x5F, 0x7A, 0xD7, 0xF9, 0x4D, 0xEF, 0x9B, 0x7C, 0xF6, 0xA3, 0xE6, + 0xC1, 0xF3, 0x19, 0xB5, 0xCF, 0x7E, 0xB8, 0xF8, 0x78, 0xA0, 0xFE, 0xF6, 0x83, 0xF8, 0x48, 0x33, + 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, + 0x11, 0x10, 0xED, 0xCE, 0xBD, 0x09, 0xEB, 0xD8, 0x6D, 0x03, 0xC1, 0x1F, 0x0B, 0x00, 0x00, 0x00, + 0xC5, 0x39, 0x7F, 0x60, 0xD9, 0x86, 0x9A, 0x07, 0xCF, 0xA3, 0xB7, 0x1F, 0xD1, 0xF8, 0x78, 0xD8, + 0x86, 0x87, 0x0B, 0x90, 0xEF, 0xD4, 0xDE, 0x7E, 0x10, 0x1F, 0x69, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x21, 0x8F, 0xF1, + 0x26, 0x2C, 0x00, 0x00, 0x30, 0x55, 0xCE, 0xEF, 0x5E, 0x32, 0xEA, 0xC7, 0x47, 0x83, 0xDB, 0x0F, + 0x17, 0x1F, 0xA7, 0xC2, 0xF8, 0x70, 0xB7, 0x1F, 0x7F, 0x4D, 0x7C, 0x64, 0x9B, 0x0A, 0x87, 0x3C, + 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x08, 0x87, 0x1C, + 0xE7, 0x9D, 0xB8, 0x6D, 0x30, 0xF8, 0x63, 0x01, 0x00, 0x00, 0xA0, 0x38, 0xE7, 0x76, 0x2E, 0x3A, + 0x59, 0x73, 0xFB, 0x11, 0xC4, 0x47, 0xF5, 0xD9, 0x8F, 0x30, 0x3E, 0x62, 0xB7, 0x1F, 0xC4, 0x47, + 0x9A, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, + 0xE9, 0xE9, 0x68, 0xC8, 0x73, 0xDE, 0xD1, 0x5B, 0x79, 0x13, 0x16, 0x00, 0x00, 0x28, 0xDE, 0xF9, + 0xED, 0x73, 0xAA, 0xF1, 0x51, 0xF7, 0xA1, 0x83, 0x8F, 0xCC, 0x90, 0xB7, 0x1F, 0xC4, 0x47, 0x9A, + 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, + 0xE9, 0x60, 0xC8, 0x7D, 0x47, 0x3F, 0xCF, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xB1, 0xCE, 0xEE, 0x5F, + 0x3A, 0x70, 0x6E, 0xCB, 0x27, 0x63, 0xB7, 0x1F, 0x33, 0x2B, 0xCF, 0x7E, 0x44, 0xE3, 0xC3, 0xED, + 0xDE, 0xCA, 0xED, 0x07, 0xF1, 0x91, 0x66, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, + 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0x22, 0x14, 0x8A, 0x9A, 0x7B, 0x13, 0xD6, 0xD8, 0x17, + 0x67, 0x05, 0x7F, 0x3C, 0x00, 0x00, 0x00, 0xE4, 0xEF, 0xDC, 0xDE, 0xE5, 0xEB, 0xCE, 0x6D, 0xFA, + 0x48, 0xEC, 0xF6, 0x63, 0x46, 0x35, 0x3E, 0xAA, 0x01, 0xF2, 0x23, 0x3B, 0xE2, 0x23, 0xE5, 0x54, + 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x44, + 0x24, 0x14, 0xB9, 0x17, 0xAF, 0xE3, 0x4D, 0x58, 0x00, 0x00, 0xA0, 0x58, 0xE7, 0xF7, 0x2E, 0x5F, + 0x5F, 0xF7, 0xEC, 0xC7, 0x8F, 0x27, 0x03, 0xA4, 0x7A, 0xFB, 0xF1, 0xED, 0x0B, 0x88, 0x8F, 0x54, + 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, + 0x13, 0x81, 0x50, 0xF4, 0x5E, 0xB8, 0xCA, 0x78, 0xBF, 0xB8, 0xFD, 0xAE, 0xE0, 0x8F, 0x07, 0x00, + 0x00, 0x80, 0xFC, 0x9D, 0xDB, 0x7D, 0xD5, 0x50, 0xCD, 0x9B, 0xAF, 0xC2, 0xF8, 0x88, 0x06, 0xC8, + 0x8F, 0x66, 0x10, 0x1F, 0xA9, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, + 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0xE2, 0x60, 0x8A, 0xE6, 0x1D, 0xBF, 0x6D, 0x43, 0xF0, 0xC7, + 0x03, 0x00, 0x00, 0x40, 0xFE, 0xCE, 0xED, 0xB8, 0x6C, 0x6C, 0xF2, 0xF6, 0xE3, 0x02, 0x79, 0xFB, + 0xF1, 0x76, 0xE4, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x06, 0x53, 0x35, 0xDE, 0x84, 0x05, 0x00, + 0x00, 0x0A, 0x75, 0x76, 0xDB, 0xFC, 0xE0, 0xF6, 0xC3, 0xC6, 0x87, 0x78, 0xF6, 0xE3, 0xED, 0x1F, + 0x4C, 0xDE, 0x7E, 0x10, 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, + 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0xA3, 0x60, 0x2A, 0xE7, 0x1D, 0xBD, 0x79, 0x3C, 0xF8, + 0xE3, 0x01, 0x00, 0x00, 0x20, 0x5F, 0x66, 0xA8, 0x7F, 0xF6, 0xD9, 0xCD, 0x97, 0x04, 0xF1, 0x51, + 0x7B, 0xFB, 0x71, 0x2A, 0xBC, 0xFD, 0xF8, 0x66, 0xE5, 0xF6, 0x83, 0xF8, 0x68, 0x35, 0x15, 0x0E, + 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x04, + 0x53, 0xBE, 0x97, 0x56, 0xF2, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x8C, 0xB3, 0x43, 0x4B, 0x07, 0xDE, + 0xDD, 0xF8, 0xE1, 0x6A, 0x80, 0x9C, 0xB6, 0x01, 0x52, 0xF3, 0xEC, 0xC7, 0xF7, 0x2B, 0xB7, 0x1F, + 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, + 0xF0, 0xDF, 0xE9, 0x89, 0x10, 0xE8, 0xD4, 0xC6, 0x96, 0xF1, 0x26, 0x2C, 0x00, 0x00, 0x50, 0x0C, + 0x1B, 0x20, 0xEB, 0x27, 0x06, 0xDF, 0x57, 0x73, 0xFB, 0x11, 0x7D, 0xFE, 0xC3, 0xDD, 0x7E, 0x10, + 0x1F, 0xAD, 0xA6, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, + 0x7F, 0xA7, 0x27, 0x22, 0xA0, 0x93, 0x7B, 0xE1, 0x2A, 0x63, 0x8E, 0xDF, 0xB1, 0x2E, 0xF8, 0x63, + 0x02, 0x00, 0x00, 0x20, 0x3F, 0xEF, 0xEE, 0x59, 0x3A, 0xE8, 0xDF, 0x7E, 0x88, 0xF8, 0x70, 0xB7, + 0x1F, 0xC4, 0x47, 0xAB, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, + 0xF2, 0xF0, 0xDF, 0xE9, 0x89, 0x00, 0xE8, 0xF4, 0xDC, 0x3F, 0x17, 0x27, 0x6E, 0x5B, 0x1F, 0xFC, + 0x31, 0x01, 0x00, 0x00, 0x90, 0x9F, 0x89, 0x6D, 0x8B, 0x47, 0xEB, 0xDE, 0x7C, 0x15, 0xDE, 0x7E, + 0xDC, 0x4D, 0x7C, 0x34, 0x9F, 0x0A, 0x87, 0x3C, 0x16, 0x0F, 0x84, 0x22, 0x27, 0x0E, 0xE9, 0x65, + 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xE2, 0xF0, 0xDF, 0x25, 0xF3, 0x8E, 0xAF, 0xE5, 0x4D, 0x58, 0x00, + 0x00, 0x20, 0x7F, 0x13, 0x5B, 0xFA, 0xC6, 0xE5, 0xC3, 0xE7, 0xF7, 0xBB, 0x6F, 0xBD, 0x22, 0x3E, + 0x1A, 0x4F, 0x85, 0x43, 0x1E, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, + 0x4E, 0x4F, 0x1F, 0xFC, 0xBB, 0x65, 0xDE, 0xD1, 0x9B, 0x4F, 0x06, 0x7F, 0x4C, 0x00, 0x00, 0x00, + 0xE4, 0xC3, 0x0C, 0xF5, 0xCF, 0x7A, 0xF7, 0x99, 0x39, 0x95, 0xF8, 0xB0, 0x8B, 0x3E, 0x7C, 0xFE, + 0xD6, 0x5F, 0x11, 0x1F, 0x8D, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, + 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFD, 0x5D, 0xB5, 0x97, 0x56, 0x9A, 0xE0, 0x8F, 0x0A, + 0x00, 0x00, 0x80, 0x7C, 0xB8, 0x37, 0x60, 0x4D, 0x6C, 0xFC, 0x98, 0x0D, 0x90, 0x0B, 0xCC, 0xE9, + 0x47, 0xEC, 0xDC, 0xED, 0x87, 0x0B, 0x90, 0xFB, 0x6D, 0x80, 0x10, 0x1F, 0x0D, 0xA6, 0xC2, 0x21, + 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xFB, + 0xDD, 0x38, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x7C, 0xDD, 0xC4, 0x13, 0x1F, + 0x30, 0xA7, 0xFD, 0x00, 0x09, 0xBE, 0xFD, 0xEA, 0xE1, 0x99, 0xFE, 0xED, 0x07, 0xF1, 0xA1, 0xA6, + 0xC2, 0x21, 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, + 0x0E, 0xFA, 0xDD, 0x3A, 0xDE, 0x84, 0x05, 0x00, 0x00, 0xF2, 0x36, 0x31, 0xB4, 0x74, 0x7D, 0x78, + 0xFB, 0x71, 0xCA, 0xCD, 0xDD, 0x7E, 0x7C, 0x67, 0x06, 0xF1, 0x21, 0xA7, 0xC2, 0x21, 0x8F, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF9, 0xDD, 0x3C, + 0xF7, 0xCF, 0x3D, 0x6F, 0xC2, 0x02, 0x00, 0x00, 0x79, 0x9A, 0xD8, 0x79, 0xD5, 0x68, 0xF5, 0xDB, + 0xAF, 0xDC, 0x0D, 0x88, 0x7B, 0xF6, 0xE3, 0x6B, 0xC4, 0x47, 0xFD, 0x54, 0x38, 0xE4, 0x31, 0x15, + 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, 0x01, 0xBF, 0x07, 0xC6, + 0x9B, 0xB0, 0x00, 0x00, 0x40, 0xAE, 0x26, 0xB6, 0x5D, 0x76, 0xB2, 0x7A, 0x03, 0xF2, 0xF0, 0x0C, + 0xF3, 0xF6, 0x7D, 0xC1, 0xED, 0x87, 0x8D, 0x8F, 0x3F, 0x10, 0x1F, 0xC1, 0x54, 0x38, 0xE4, 0x31, + 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0xE1, 0xBE, 0x17, + 0xE6, 0x1D, 0x59, 0x33, 0x16, 0xFC, 0x71, 0x01, 0x00, 0x00, 0xD0, 0xBE, 0x09, 0xFF, 0x0D, 0x58, + 0x93, 0xB7, 0x1F, 0x6F, 0x7E, 0x6D, 0xF2, 0xE6, 0xE3, 0x0D, 0xE2, 0xC3, 0x4E, 0x85, 0x43, 0x1E, + 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xEC, 0x7B, + 0x66, 0x47, 0x6E, 0xE0, 0x4D, 0x58, 0x00, 0x00, 0x20, 0x1F, 0x13, 0x43, 0xD7, 0x2F, 0x99, 0x78, + 0xFA, 0x13, 0xE6, 0xCC, 0xA3, 0x95, 0xCF, 0xFF, 0x70, 0xB7, 0x1F, 0x95, 0xF8, 0xB8, 0xC0, 0xBF, + 0xF9, 0x78, 0x83, 0xF8, 0x28, 0x68, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, + 0xDF, 0xE9, 0x89, 0x03, 0x7D, 0xAF, 0xED, 0xA5, 0x7E, 0xF7, 0x20, 0xFA, 0x92, 0xE0, 0x8F, 0x0D, + 0x00, 0x00, 0x80, 0xEC, 0xCE, 0x0C, 0x2D, 0x5B, 0x3B, 0xF1, 0xE4, 0x87, 0x2B, 0x9F, 0x01, 0xF2, + 0x60, 0xE5, 0xB5, 0xBB, 0xD5, 0xDB, 0x8F, 0xAF, 0xD9, 0xF8, 0xF8, 0x47, 0xE2, 0x23, 0xFF, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, 0xF3, 0xBD, 0x38, + 0xF7, 0x26, 0xAC, 0x13, 0x7F, 0xBE, 0x36, 0xF8, 0x63, 0x03, 0x00, 0x00, 0x20, 0x3B, 0xF7, 0x06, + 0xAC, 0x89, 0xC7, 0x2F, 0xF2, 0x03, 0xE4, 0xED, 0x6F, 0x55, 0x9E, 0xFB, 0x20, 0x3E, 0xDC, 0x54, + 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xC4, + 0x41, 0xBE, 0x57, 0xE7, 0xBE, 0x26, 0x78, 0x13, 0x16, 0x00, 0x00, 0xC8, 0xC3, 0xD9, 0x5D, 0xD7, + 0x0C, 0x4E, 0x3C, 0x36, 0xC3, 0x9C, 0x71, 0xCF, 0x7E, 0x04, 0x6F, 0xBD, 0xFA, 0xC3, 0x7A, 0xE2, + 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0x27, 0x0E, + 0xF1, 0x3D, 0xBB, 0xF9, 0xFE, 0xBC, 0xE3, 0xB7, 0x0D, 0x05, 0x7F, 0x6C, 0x00, 0x00, 0x00, 0x64, + 0xF7, 0xEE, 0xB6, 0xC5, 0xA3, 0x13, 0x8F, 0xCF, 0x30, 0xEF, 0x7C, 0xBB, 0x72, 0xFB, 0xF1, 0xE6, + 0x5F, 0x5D, 0x44, 0x7C, 0x14, 0x32, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, + 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x57, 0x89, 0x0F, 0x3F, 0x40, 0x8E, 0xDC, 0xCC, 0x9B, 0xB0, + 0x00, 0x00, 0x40, 0xFB, 0xCE, 0x6D, 0x5F, 0x60, 0x26, 0x1E, 0xB9, 0xC0, 0xBC, 0xE5, 0x5E, 0xBB, + 0xFB, 0xD7, 0xC4, 0x47, 0x31, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, + 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0xE1, 0xEF, 0xE8, 0x4D, 0xBC, 0x09, 0x0B, 0x00, + 0x00, 0xB4, 0xC7, 0x0C, 0x5D, 0x3B, 0xFB, 0xDC, 0xB6, 0x4B, 0xCD, 0x3B, 0xDF, 0xB4, 0x01, 0xF2, + 0x75, 0xE2, 0xA3, 0x98, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, + 0xA7, 0x0E, 0xF1, 0xBD, 0xBA, 0x58, 0x7C, 0xB8, 0xBD, 0xB4, 0xC2, 0x98, 0x97, 0xBF, 0x38, 0x3B, + 0xF8, 0xE3, 0x03, 0x00, 0x00, 0x20, 0xBD, 0xB3, 0xFB, 0x97, 0x0E, 0xBC, 0xFB, 0xD8, 0x87, 0xCC, + 0xDB, 0x77, 0x5F, 0x64, 0xCE, 0x13, 0x1F, 0x05, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, + 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x89, 0xF8, 0x70, 0x7B, 0xE1, 0x6A, 0x63, + 0x8E, 0xDD, 0x36, 0x10, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDE, 0x99, 0x5D, 0x9F, 0xBB, 0xEB, + 0xD4, 0x86, 0x0F, 0x98, 0xF3, 0xFF, 0x44, 0x7C, 0xE4, 0x3F, 0x15, 0x09, 0x45, 0x4D, 0x1C, 0xD2, + 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0x27, 0xC2, 0x23, 0x98, 0xF7, 0xAF, + 0x4B, 0xCC, 0xE9, 0x9F, 0xDD, 0xCA, 0x9B, 0xB0, 0x00, 0x00, 0x40, 0x76, 0xAF, 0x3D, 0x70, 0xED, + 0x86, 0xF1, 0xDD, 0xAB, 0xCD, 0xD9, 0x17, 0xBF, 0x44, 0x7C, 0xE4, 0x3A, 0x15, 0x09, 0x45, 0x4D, + 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xD4, 0x21, 0xBE, 0x57, 0xA7, 0xC3, 0xC3, 0xED, + 0xD4, 0xB3, 0xF3, 0xCC, 0xEF, 0x77, 0xCC, 0x31, 0xBF, 0xDB, 0x77, 0xD3, 0x60, 0xF0, 0xC7, 0x07, + 0x00, 0x00, 0x40, 0x7A, 0xAF, 0xEF, 0xB9, 0x75, 0xF8, 0xF7, 0x07, 0x6F, 0x35, 0xBF, 0xDF, 0xB7, + 0xD2, 0xBC, 0x79, 0xE0, 0x32, 0x73, 0xFE, 0x9F, 0x55, 0x54, 0x24, 0x9D, 0x08, 0x87, 0x3C, 0x26, + 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, + 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0x4E, 0x87, 0xC7, 0x99, 0xBF, 0xEB, 0x33, 0xE3, 0xBB, + 0xE6, 0x9A, 0xDF, 0x6D, 0xB3, 0xF1, 0xE1, 0xB6, 0x67, 0x39, 0xAF, 0xE2, 0x05, 0x00, 0x00, 0xD9, + 0xFD, 0xF3, 0xFF, 0xFE, 0x17, 0x17, 0xFE, 0x76, 0xFB, 0xEA, 0xFB, 0x7E, 0xB7, 0x6D, 0xF1, 0x5B, + 0xBF, 0xDF, 0xB9, 0xD8, 0xB8, 0xBD, 0x7D, 0xE8, 0x72, 0xFF, 0x5B, 0x2D, 0x74, 0x64, 0x34, 0x9A, + 0x08, 0x87, 0x3C, 0x26, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, + 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xA9, 0x43, 0x7C, 0xAF, 0xAE, 0x3E, 0x3C, 0xCE, 0xFE, + 0x43, 0x9F, 0x79, 0x73, 0xEF, 0x64, 0x78, 0xBC, 0xBE, 0x75, 0xCE, 0xF8, 0xEF, 0xB6, 0x5D, 0xBA, + 0x7E, 0xB4, 0xFF, 0x3D, 0x7F, 0x14, 0xFC, 0xF1, 0x01, 0x00, 0x00, 0x90, 0xDD, 0x7F, 0xBF, 0xFB, + 0x33, 0x17, 0xBF, 0xB6, 0x79, 0xF1, 0x96, 0x30, 0x42, 0xC6, 0x77, 0x2F, 0x36, 0xA7, 0xFF, 0xC6, + 0x1E, 0xD4, 0x65, 0x6C, 0xC4, 0x27, 0xC2, 0x21, 0x8F, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, 0xF2, + 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, 0xDF, + 0xAB, 0xAB, 0x0D, 0x8F, 0xF3, 0xFF, 0x34, 0xDF, 0xBC, 0xB5, 0x3F, 0x72, 0xE3, 0x61, 0xF7, 0xEA, + 0x33, 0x73, 0x7E, 0x34, 0x3E, 0xF4, 0xA9, 0x59, 0xC1, 0x1F, 0x17, 0x00, 0x00, 0x00, 0xF9, 0xF9, + 0xEF, 0xDF, 0x5D, 0xF2, 0x99, 0xD7, 0xB6, 0x2C, 0xFA, 0x59, 0x18, 0x22, 0x6F, 0xEC, 0xB9, 0xCC, + 0x4C, 0xFC, 0xBD, 0x0B, 0x02, 0x15, 0x1E, 0x6E, 0xB1, 0x68, 0xC8, 0x6B, 0x32, 0x1C, 0xF2, 0x98, + 0x0A, 0x87, 0x3C, 0xA6, 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, + 0x3A, 0xC4, 0xF7, 0xEA, 0x26, 0xC3, 0xC3, 0xFB, 0xE7, 0xF9, 0xE6, 0x9D, 0x91, 0x79, 0x35, 0xE1, + 0xF1, 0xDA, 0xE6, 0x4B, 0xF7, 0x8F, 0x6F, 0xE9, 0xE3, 0xB5, 0xBB, 0x00, 0x00, 0xA0, 0x78, 0xFF, + 0xEB, 0xA1, 0xCB, 0xBE, 0xF8, 0xBB, 0x6D, 0x8B, 0x7E, 0x19, 0x86, 0x88, 0x7B, 0x3E, 0xE4, 0xEC, + 0x4F, 0x5D, 0x1C, 0x10, 0x1F, 0xF5, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, + 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x75, 0x93, 0xF1, 0x51, 0x7D, 0xC0, 0x3C, 0x08, 0x8F, 0xD7, + 0xB7, 0x5E, 0x3A, 0xF6, 0xDA, 0x96, 0x4B, 0x79, 0xDD, 0x2E, 0x00, 0x00, 0x98, 0x5A, 0xA3, 0xFD, + 0xFD, 0x7F, 0xF4, 0xAB, 0x27, 0x2E, 0xFB, 0x3F, 0xA2, 0xCF, 0x87, 0xBC, 0x35, 0xEC, 0x1E, 0x54, + 0x17, 0xD1, 0x90, 0xD7, 0x64, 0x38, 0xE4, 0x31, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, + 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x75, 0x88, 0xEF, 0xD5, 0x55, 0xC2, 0x23, 0xFE, + 0x80, 0xB9, 0x8D, 0x8E, 0x5F, 0xBE, 0xBE, 0x7D, 0xEE, 0xBA, 0xE0, 0x8F, 0x00, 0x00, 0x00, 0x80, + 0xCE, 0xF8, 0xD5, 0x23, 0x57, 0x7E, 0xE0, 0x37, 0x4F, 0x2E, 0xDE, 0x30, 0x19, 0x22, 0x8B, 0xCC, + 0xE9, 0xBF, 0xB9, 0xCC, 0x78, 0xFF, 0x2A, 0x02, 0xA2, 0x9D, 0xC9, 0x70, 0xC8, 0x63, 0x2A, 0x1C, + 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, 0x77, 0x7A, 0xEA, 0x10, + 0xDF, 0xAB, 0x6B, 0xFC, 0x80, 0x39, 0xCF, 0x79, 0x00, 0x00, 0x80, 0xAE, 0x72, 0xF2, 0x91, 0xC5, + 0xF3, 0x5F, 0x7D, 0x66, 0xF1, 0x0E, 0x17, 0x20, 0x6E, 0xE3, 0xBB, 0x17, 0x99, 0x33, 0x7F, 0x67, + 0x0F, 0xE2, 0x2A, 0x26, 0xD2, 0x4E, 0x86, 0x43, 0x1E, 0x8B, 0x47, 0x43, 0x5E, 0x53, 0x91, 0x50, + 0xD4, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1D, 0xE2, 0x7B, 0x73, 0xEA, 0x01, + 0xF3, 0xDF, 0x6D, 0xBD, 0x74, 0xF0, 0xBF, 0x7D, 0x67, 0xDE, 0x07, 0x82, 0x2F, 0x73, 0x00, 0x00, + 0x80, 0xEE, 0xF3, 0xAB, 0x8D, 0x8B, 0xD6, 0xBC, 0xFA, 0xCC, 0xC2, 0x9F, 0x87, 0x21, 0xF2, 0xC6, + 0x9E, 0xC5, 0xE6, 0xDD, 0x7F, 0xB0, 0x87, 0x7D, 0x15, 0x16, 0x49, 0x26, 0xC3, 0x21, 0x8F, 0xA9, + 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, + 0x83, 0x7C, 0xAF, 0xCD, 0xFB, 0xE7, 0x05, 0x75, 0x0F, 0x98, 0xDB, 0x8D, 0xFE, 0x7F, 0x8F, 0x5E, + 0x3A, 0x27, 0xF8, 0xB2, 0x06, 0x00, 0x00, 0xE8, 0x6E, 0xFE, 0xF3, 0x21, 0x83, 0x8B, 0xFF, 0xE2, + 0x77, 0xDB, 0x16, 0xFE, 0x32, 0x0C, 0x91, 0x37, 0x0F, 0x2C, 0x36, 0x67, 0x7F, 0x6A, 0x0F, 0xFE, + 0x2A, 0x32, 0x1A, 0x4D, 0x86, 0x43, 0x1E, 0x53, 0xE1, 0x90, 0xC7, 0x54, 0x24, 0x14, 0x35, 0x71, + 0x48, 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x87, 0xF9, 0x5E, 0xDB, 0xE9, 0xBF, 0xE9, 0xAB, + 0x79, 0xC0, 0xFC, 0xB5, 0x67, 0xE6, 0x1C, 0xE3, 0x01, 0x73, 0x00, 0x00, 0xD0, 0xB3, 0x6C, 0x88, + 0xFC, 0xBB, 0x57, 0x37, 0x2F, 0xBA, 0xE7, 0x77, 0xDB, 0x16, 0xBD, 0x15, 0x86, 0xC8, 0xDB, 0x87, + 0x12, 0x3E, 0xA8, 0x2E, 0xC3, 0x21, 0x8F, 0xA9, 0x70, 0xC8, 0x63, 0x2A, 0x12, 0x8A, 0x9A, 0x38, + 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xC3, 0x7C, 0x2F, 0x6D, 0xE2, 0xEF, 0xE7, 0xF3, + 0x80, 0x39, 0x00, 0x00, 0x28, 0xAF, 0x93, 0xF7, 0x2E, 0xFC, 0xC8, 0x2B, 0x9B, 0x16, 0x3F, 0x1A, + 0x46, 0x88, 0x7B, 0x3E, 0xA4, 0xE9, 0x83, 0xEA, 0x32, 0x1C, 0xF2, 0x98, 0x0A, 0x87, 0x3C, 0xA6, + 0x22, 0xA1, 0xA8, 0x89, 0x43, 0x7A, 0x59, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x3E, 0xD0, 0xF7, 0xCA, + 0xCE, 0xFE, 0xC3, 0x7C, 0xF3, 0xE6, 0x5E, 0xF7, 0xED, 0x56, 0x95, 0xF8, 0xE0, 0x01, 0x73, 0x00, + 0x00, 0x50, 0x6A, 0xFF, 0xE3, 0xFE, 0xCF, 0x2C, 0x7A, 0x75, 0xF3, 0xA2, 0xE7, 0xA2, 0x21, 0x32, + 0xF1, 0xF7, 0x36, 0x0C, 0x88, 0x8F, 0x84, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, + 0x7D, 0xA8, 0xEF, 0x85, 0x9D, 0xFF, 0xA7, 0x05, 0xE6, 0xED, 0x83, 0x7D, 0x41, 0x78, 0x04, 0x37, + 0x1F, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0xA6, 0x8B, 0x5F, 0x3E, 0xB6, 0xF8, 0x96, 0xD7, 0xB7, 0x2E, + 0x7C, 0x39, 0x0C, 0x11, 0xF7, 0xA0, 0xBA, 0xFF, 0x7C, 0x88, 0x0C, 0x87, 0x3C, 0xA6, 0xC2, 0x21, + 0x8F, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xF6, + 0xDD, 0x3E, 0xF7, 0x80, 0xF9, 0xA9, 0x67, 0xA3, 0xE1, 0xE1, 0xC7, 0x07, 0x0F, 0x98, 0x03, 0x00, + 0x80, 0xE9, 0xC7, 0x3D, 0xA8, 0xFE, 0xDB, 0xA7, 0x17, 0x7F, 0xF5, 0xF5, 0xAD, 0x8B, 0x7E, 0xE3, + 0x22, 0xE4, 0x77, 0x3B, 0x16, 0x9A, 0x37, 0xF7, 0x2F, 0x32, 0xE7, 0xFE, 0xD1, 0x1D, 0xEC, 0x55, + 0x44, 0x64, 0x5D, 0x3C, 0x1A, 0xF2, 0x9A, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, + 0xFC, 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xED, 0xAB, 0x3C, 0x60, 0x3E, 0x19, 0x1E, 0xAF, 0x3D, 0x33, + 0x97, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x7E, 0xF5, 0xC8, 0xBC, 0x0F, 0xFC, 0xE6, 0xE9, 0x85, 0xF7, + 0xBD, 0xBE, 0x75, 0xC1, 0x5B, 0x2E, 0x42, 0xDC, 0xDE, 0x1E, 0x59, 0x6C, 0xBC, 0x7F, 0x51, 0x31, + 0x91, 0x76, 0x2A, 0x1C, 0xF2, 0x98, 0x8A, 0x84, 0xA2, 0x26, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, + 0x77, 0x7A, 0xFA, 0x70, 0xDF, 0xCD, 0xAB, 0x3C, 0x60, 0x1E, 0x3E, 0xE7, 0x61, 0xC3, 0x63, 0xCB, + 0x5C, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x88, 0x1B, 0xFB, 0x4F, 0x9F, 0xB9, 0xF8, 0x95, 0xCD, 0x0B, + 0xB7, 0x84, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCD, 0xA9, 0xE7, 0xDA, 0x09, 0x11, 0x15, 0x0E, 0x79, + 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC0, 0xEF, + 0xD6, 0xD5, 0x3E, 0x60, 0x3E, 0xD7, 0xBC, 0xBE, 0x75, 0xEE, 0xB8, 0xFD, 0x91, 0x07, 0xCC, 0x01, + 0x00, 0x00, 0x9A, 0xF9, 0x9F, 0x0F, 0x2D, 0x5A, 0xFA, 0xEA, 0xE6, 0x85, 0x3F, 0x0B, 0x43, 0x64, + 0x7C, 0x68, 0x91, 0x39, 0x33, 0xEA, 0x0E, 0xFE, 0x2A, 0x32, 0x1A, 0x2D, 0x1E, 0x0D, 0x79, 0x4D, + 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xC8, 0xEF, 0xC6, + 0xD5, 0x3F, 0x60, 0x6E, 0xB7, 0x75, 0x0E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA4, 0xF1, 0xBF, 0x1E, + 0x5A, 0xF0, 0xC5, 0xD7, 0xB6, 0x2E, 0xF8, 0x65, 0x18, 0x22, 0x6F, 0xEC, 0x5D, 0x64, 0xCE, 0xFE, + 0xC4, 0x45, 0x80, 0x0A, 0x8E, 0xE8, 0xE2, 0xD1, 0x90, 0xD7, 0x54, 0x24, 0x14, 0x35, 0x71, 0x48, + 0x2F, 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x07, 0xFD, 0x6E, 0x9B, 0x7E, 0xC0, 0x7C, 0x2E, 0x0F, + 0x98, 0x03, 0x00, 0x00, 0x64, 0xE5, 0x1E, 0x54, 0xFF, 0xF5, 0xC6, 0x45, 0x7F, 0x19, 0x7D, 0x3E, + 0xC4, 0x3D, 0xA8, 0x7E, 0xFE, 0x67, 0x2A, 0x3C, 0xDC, 0x54, 0x38, 0xE4, 0x31, 0x15, 0x09, 0x45, + 0x4D, 0x1C, 0xD2, 0xCB, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0xF4, 0x61, 0xBF, 0xDB, 0xC6, 0x03, 0xE6, + 0x00, 0x00, 0x00, 0x05, 0x72, 0x0F, 0xAA, 0xFF, 0xFA, 0xC9, 0x85, 0x1B, 0xC2, 0x08, 0x71, 0x7B, + 0xE7, 0x70, 0xFC, 0xF9, 0x10, 0x15, 0x0E, 0x79, 0x4C, 0x45, 0x42, 0x51, 0x13, 0x87, 0xF4, 0xB2, + 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x7D, 0xD8, 0xEF, 0xA6, 0xF1, 0x80, 0x39, 0x00, 0x00, 0xC0, 0x14, + 0x3A, 0xF9, 0xC8, 0xE2, 0xF9, 0xBF, 0xDD, 0xB4, 0x60, 0x47, 0x18, 0x21, 0xE1, 0x83, 0xEA, 0x3A, + 0x1C, 0xF2, 0x58, 0x3C, 0x10, 0x8A, 0x9C, 0x38, 0xA4, 0x97, 0x75, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, + 0x03, 0x7F, 0xB7, 0x8C, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x3A, 0xE8, 0x57, 0x1B, 0x17, 0xAD, 0x79, + 0x65, 0xD3, 0x82, 0x9F, 0x57, 0x42, 0x64, 0x81, 0x19, 0x1F, 0x5A, 0x68, 0xCE, 0x8C, 0xBA, 0x43, + 0xBC, 0x8A, 0x88, 0xAC, 0x8B, 0x07, 0x42, 0x91, 0x13, 0x87, 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, + 0x3D, 0x7D, 0xE8, 0xEF, 0x86, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x40, 0x97, 0xA8, 0x7C, 0x90, 0xE1, + 0xC2, 0xAF, 0xBE, 0xB6, 0x75, 0xFE, 0x2F, 0x5D, 0x84, 0xB8, 0xBD, 0xB9, 0x7F, 0xA1, 0x39, 0xFB, + 0x13, 0x77, 0xA0, 0x57, 0x41, 0x91, 0x66, 0xF1, 0x40, 0x28, 0x72, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, + 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFE, 0x9D, 0x5E, 0xA3, 0x07, 0xCC, 0x4F, 0x7E, 0xE7, 0x53, 0xF3, + 0x83, 0x2F, 0x01, 0x00, 0x00, 0x00, 0x74, 0xC2, 0x60, 0xFF, 0xA7, 0xFE, 0xDD, 0xAB, 0x9B, 0x16, + 0xDC, 0xF3, 0xFA, 0xD6, 0xF9, 0x6F, 0x85, 0x21, 0xF2, 0xF6, 0x88, 0x7B, 0x50, 0x5D, 0x85, 0x45, + 0x92, 0xA9, 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x0F, 0xFF, + 0x9D, 0x9E, 0x7A, 0xC0, 0xFC, 0xB7, 0x1B, 0xE7, 0xDE, 0x10, 0xFC, 0x23, 0x0F, 0x00, 0x00, 0x80, + 0x6E, 0xF0, 0xFF, 0x7E, 0x63, 0xF1, 0x87, 0x7F, 0xF3, 0xD4, 0x82, 0x47, 0xC3, 0x08, 0x71, 0x3B, + 0xF5, 0xDC, 0x22, 0xE3, 0xFD, 0x8B, 0x8A, 0x8C, 0x46, 0x53, 0x91, 0x50, 0xD4, 0xC4, 0x21, 0xBD, + 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0x1F, 0xFE, 0x3B, 0xB9, 0xF8, 0x03, 0xE6, 0xEE, 0x39, 0x8F, + 0x57, 0x9F, 0xBE, 0xF4, 0x3F, 0x06, 0xFF, 0x88, 0x03, 0x00, 0x00, 0xA0, 0x1B, 0xFD, 0x8F, 0xFB, + 0x17, 0x2C, 0x7A, 0x75, 0xF3, 0x82, 0x9F, 0x85, 0x11, 0xF2, 0xFB, 0x5D, 0x0B, 0xCC, 0xE9, 0xBF, + 0x75, 0x07, 0x61, 0x15, 0x1C, 0xD1, 0xA9, 0x48, 0x28, 0x6A, 0xB1, 0x03, 0x7A, 0x99, 0x27, 0x0F, + 0xFF, 0x9D, 0x9E, 0x0E, 0x80, 0x4E, 0xAD, 0xEE, 0x01, 0xF3, 0xCD, 0x73, 0xDE, 0xB2, 0x3F, 0xF2, + 0x80, 0x39, 0x00, 0x00, 0x40, 0x2F, 0xF9, 0xE5, 0xC3, 0xF3, 0x6F, 0x79, 0x75, 0xCB, 0x82, 0x97, + 0xC3, 0x10, 0x71, 0x0F, 0xAA, 0x4F, 0xFC, 0x57, 0x77, 0xF8, 0x27, 0x3E, 0xA6, 0x6C, 0xF2, 0xF0, + 0xDF, 0xE9, 0xE9, 0x08, 0xE8, 0xC4, 0x1A, 0x3D, 0x60, 0x3E, 0xBE, 0xA5, 0x6F, 0x76, 0xF0, 0x8F, + 0x31, 0x00, 0x00, 0x00, 0x7A, 0x49, 0xF8, 0xA0, 0x7A, 0xF4, 0xF9, 0x10, 0xF7, 0xA0, 0xFA, 0xB9, + 0x7F, 0x74, 0x21, 0x40, 0x7C, 0x14, 0x3A, 0x79, 0xF8, 0xEF, 0xF4, 0x74, 0x08, 0x4C, 0xF5, 0x1A, + 0x3D, 0x60, 0xFE, 0xEB, 0xC7, 0x3E, 0x7D, 0x55, 0xF0, 0x8F, 0x2E, 0x00, 0x00, 0x00, 0x7A, 0x99, + 0xFB, 0x20, 0xC3, 0xDF, 0x6C, 0x9C, 0x7F, 0x5F, 0xED, 0x83, 0xEA, 0x0B, 0xCD, 0xF9, 0x9F, 0xA9, + 0x48, 0x28, 0x6A, 0xE2, 0x90, 0x5E, 0xD6, 0xC9, 0xC3, 0x7F, 0xA7, 0xA7, 0x63, 0x60, 0xAA, 0x17, + 0x7F, 0xC0, 0xFC, 0xF5, 0x6D, 0x73, 0x4E, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x40, 0x49, 0xFD, 0xDB, + 0x83, 0x7D, 0x7D, 0xAF, 0x6C, 0x5E, 0xB0, 0xA5, 0x12, 0x21, 0xF3, 0xCD, 0xEF, 0x77, 0xCD, 0x37, + 0xA7, 0x9E, 0x5B, 0x68, 0xBC, 0x7F, 0x51, 0xC1, 0x90, 0xE7, 0xC4, 0x21, 0xBD, 0xAC, 0x93, 0x87, + 0xFF, 0x4E, 0x4F, 0xC7, 0xC0, 0x54, 0x8E, 0x07, 0xCC, 0x01, 0x00, 0x00, 0xA6, 0xB1, 0xFF, 0xF9, + 0xD0, 0xBC, 0xA5, 0xAF, 0x6E, 0xEE, 0xFB, 0x99, 0x8B, 0x90, 0x30, 0x44, 0xCE, 0x8C, 0xBA, 0x03, + 0xB4, 0x8A, 0x87, 0x76, 0x17, 0x3B, 0xA0, 0x97, 0x79, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0x20, 0x98, + 0xAA, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xAA, 0x7E, 0xF5, 0x58, 0xDF, 0x5F, 0x54, 0x3E, 0xC8, + 0xB0, 0x12, 0x22, 0xE3, 0x43, 0xF6, 0xC0, 0xF8, 0x13, 0x77, 0x98, 0x56, 0x21, 0x91, 0x65, 0xB1, + 0x03, 0x7A, 0x99, 0x27, 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x82, 0xA9, 0x18, 0x0F, 0x98, 0x03, 0x00, + 0x00, 0x40, 0x72, 0x0F, 0xAA, 0xFF, 0x7A, 0x63, 0xDF, 0x5F, 0xBE, 0xBE, 0xB5, 0xEF, 0xAD, 0x30, + 0x44, 0xDE, 0xDC, 0x6F, 0x0F, 0x90, 0x6D, 0x3F, 0x1F, 0x22, 0x0E, 0xE9, 0x65, 0x9D, 0x3C, 0xFC, + 0x77, 0x7A, 0x3A, 0x0C, 0x8A, 0x1E, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x20, 0x11, 0xFF, 0x41, 0xF5, + 0xA7, 0xFA, 0x1E, 0x0D, 0x23, 0xC4, 0xCD, 0x3D, 0xA8, 0x9E, 0xED, 0xF9, 0x10, 0x71, 0x48, 0x2F, + 0xEB, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x71, 0x50, 0xF4, 0xCE, 0xFC, 0xDD, 0x7C, 0x1E, 0x30, 0x07, + 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x41, 0xF5, 0x57, 0x9F, 0x99, 0x3F, 0x12, 0x46, 0x48, 0xFA, 0x07, + 0xD5, 0xC5, 0x21, 0xBD, 0xAC, 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x41, 0x91, 0x73, 0xCF, 0x79, + 0xF0, 0x80, 0x39, 0x00, 0x00, 0x00, 0xDA, 0xF2, 0xAB, 0x27, 0xFA, 0xD6, 0x44, 0x1F, 0x54, 0x77, + 0xCF, 0x87, 0xB4, 0x7E, 0x50, 0x3D, 0x76, 0x40, 0x2F, 0xF3, 0xE4, 0xE1, 0xBF, 0xD3, 0xD3, 0x81, + 0x50, 0xD4, 0xCE, 0xFD, 0x94, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x90, 0xA3, 0xCA, 0x07, 0x19, 0xF6, + 0x7D, 0x35, 0xFA, 0xA0, 0xBA, 0x7B, 0x3E, 0x44, 0x3F, 0xA8, 0x1E, 0x3B, 0xA0, 0x97, 0x79, 0xF2, + 0xF0, 0xDF, 0xE9, 0xE9, 0x48, 0x28, 0x62, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x42, 0xB9, 0xE7, + 0x43, 0x5E, 0xDD, 0xD4, 0x77, 0x4F, 0xF4, 0x41, 0xF5, 0xB7, 0x0E, 0x46, 0x1F, 0x54, 0x17, 0x87, + 0xF4, 0xB2, 0x4E, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0A, 0x79, 0x2F, 0x7C, 0xC0, 0x3C, 0xFA, 0x9C, + 0x87, 0x1D, 0x0F, 0x98, 0x03, 0x00, 0x00, 0xA0, 0x18, 0x47, 0xBF, 0xB1, 0xF8, 0xC3, 0xAF, 0x6C, + 0xEE, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0x3B, 0x87, 0xEC, 0xC1, 0xF4, 0x5F, 0xC4, 0x41, 0xBD, 0x8C, + 0x93, 0x87, 0xFF, 0x4E, 0x4F, 0xC7, 0x42, 0xDE, 0x53, 0x0F, 0x98, 0xFF, 0xFA, 0xE1, 0x4B, 0x6F, + 0x0E, 0xFE, 0xD1, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xE3, 0x3F, 0xA8, 0xEE, 0x9E, 0x0F, 0xD9, 0xDE, + 0x67, 0xDC, 0x7E, 0xBF, 0xB3, 0xCF, 0x9C, 0x7A, 0xCE, 0x1E, 0x54, 0xD5, 0xA1, 0xBD, 0x2C, 0x93, + 0x87, 0xFF, 0x4E, 0xAF, 0x3E, 0x14, 0xF2, 0x9E, 0x7A, 0xC0, 0xFC, 0xD7, 0x83, 0x73, 0xFE, 0xB7, + 0xE0, 0x1F, 0x05, 0x00, 0x00, 0x00, 0x60, 0xEA, 0xFC, 0xF2, 0xE1, 0xB9, 0xB7, 0xBC, 0xB6, 0xB5, + 0xEF, 0x97, 0x61, 0x88, 0x8C, 0xEF, 0x9E, 0x6F, 0x26, 0xFE, 0xAB, 0x3D, 0x18, 0xAB, 0x03, 0x7C, + 0x2F, 0x4F, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x0C, 0x79, 0x4D, 0x3D, 0x60, 0xFE, 0xDA, 0xA6, 0x39, + 0x77, 0xF3, 0x80, 0x39, 0x00, 0x00, 0x00, 0x3A, 0xCA, 0x7F, 0x50, 0xFD, 0xC9, 0xBE, 0xAF, 0xBE, + 0xBE, 0x65, 0xDE, 0x5B, 0x61, 0x88, 0xBC, 0xB9, 0x6F, 0xBE, 0x39, 0xFB, 0x13, 0x7B, 0x48, 0x56, + 0x87, 0xF9, 0x5E, 0x9B, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x1A, 0xF2, 0x98, 0x7A, 0xC0, 0xFC, 0xD5, + 0xCD, 0x73, 0x37, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0xBA, 0x8A, 0x7B, 0x50, 0xFD, 0xB7, 0x9B, + 0xFA, 0xEE, 0x09, 0x23, 0xC4, 0xED, 0xED, 0x61, 0xF7, 0xA0, 0xBA, 0x38, 0xD4, 0xF7, 0xCA, 0xE4, + 0xE1, 0xBF, 0xD3, 0xD3, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0x3D, 0xC9, 0x3D, + 0x1F, 0xF2, 0xCA, 0xA6, 0xBE, 0x2D, 0xD1, 0x10, 0x71, 0xCF, 0x87, 0xF4, 0xDC, 0x83, 0xEA, 0xF2, + 0xF0, 0xDF, 0xE9, 0xE9, 0x78, 0x68, 0x77, 0x3C, 0x60, 0x0E, 0x00, 0x00, 0x80, 0x9E, 0x57, 0xF9, + 0x20, 0xC3, 0x79, 0x35, 0x0F, 0xAA, 0x9F, 0xFE, 0x5B, 0x7B, 0xE0, 0x55, 0x87, 0xFD, 0x6E, 0x9B, + 0x3C, 0xFC, 0x77, 0x7A, 0xF5, 0xE1, 0xD0, 0xEE, 0x78, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xA5, 0xF3, + 0xAB, 0xC7, 0xFA, 0xFE, 0x22, 0xFE, 0xA0, 0x7A, 0x57, 0x3F, 0x1F, 0x22, 0x0F, 0xFF, 0x9D, 0x9E, + 0x0E, 0x88, 0xAC, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0x94, 0x9A, 0x7B, 0x50, 0xFD, 0xB5, 0x2D, + 0xF3, 0xBE, 0x1E, 0x7F, 0x50, 0xFD, 0xDC, 0x3F, 0xDA, 0xC3, 0xB5, 0x8A, 0x80, 0x4E, 0x4D, 0x1E, + 0xFE, 0x3B, 0x3D, 0x1D, 0x11, 0x59, 0xC6, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x98, 0x56, 0xDC, 0x83, + 0xEA, 0xBF, 0x79, 0xAA, 0xEF, 0xC7, 0x61, 0x84, 0xB8, 0x75, 0xCD, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, + 0xE9, 0xE9, 0x90, 0x48, 0xBB, 0x46, 0x0F, 0x98, 0xBF, 0xB6, 0xE5, 0xD2, 0x81, 0xE0, 0x7F, 0x1A, + 0x00, 0x00, 0x00, 0xA0, 0xBC, 0xFC, 0x0F, 0x32, 0xDC, 0xD4, 0x37, 0x12, 0x46, 0x48, 0xF8, 0x41, + 0x86, 0x1D, 0x7B, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x13, 0x69, 0xA7, 0x1E, 0x30, 0x7F, + 0xE5, 0xC9, 0x39, 0xB7, 0x07, 0xFF, 0x53, 0x00, 0x00, 0x00, 0x00, 0xD3, 0x87, 0x7B, 0x50, 0xFD, + 0xB5, 0x2D, 0xF3, 0x8E, 0x85, 0x21, 0xE2, 0x9E, 0x0F, 0x39, 0x33, 0x6A, 0x0F, 0xDF, 0x2A, 0x12, + 0x8A, 0x9A, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x26, 0xD2, 0x4C, 0x3D, 0x60, 0xFE, 0xCA, 0xA6, 0xB9, + 0xFF, 0x57, 0xF0, 0xB7, 0x1E, 0x00, 0x00, 0x00, 0x98, 0x9E, 0xC2, 0x0F, 0x32, 0x8C, 0x3E, 0xA8, + 0xFE, 0xC6, 0x9E, 0x29, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, 0x3D, 0x1D, 0x14, 0x49, 0x17, 0x7F, + 0xC0, 0xDC, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x98, 0xF0, 0x83, 0x0C, 0xE3, 0x0F, 0xAA, + 0x17, 0xF6, 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2A, 0x92, 0x8C, 0x07, 0xCC, 0x01, 0x00, + 0x00, 0x80, 0x0C, 0x5E, 0x79, 0x72, 0xCE, 0xA5, 0xF1, 0x0F, 0x32, 0x74, 0x0F, 0xAA, 0xE7, 0xFA, + 0x7C, 0x88, 0x3C, 0xFC, 0x77, 0x7A, 0x3A, 0x2C, 0x5A, 0x8D, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, + 0x1C, 0xFC, 0x7A, 0x63, 0xDF, 0x55, 0xAF, 0x6E, 0x9E, 0xF7, 0x4F, 0x61, 0x84, 0x84, 0x0F, 0xAA, + 0xCB, 0xA0, 0x48, 0x33, 0x79, 0xF8, 0xEF, 0xF4, 0xEA, 0xC3, 0x22, 0xC9, 0x78, 0xC0, 0x1C, 0x00, + 0x00, 0x00, 0xC8, 0xD9, 0x2F, 0x1F, 0x9E, 0x7B, 0x4B, 0xFC, 0x83, 0x0C, 0x33, 0x3F, 0xA8, 0x2E, + 0x0F, 0xFF, 0x9D, 0x9E, 0x8E, 0x8B, 0x66, 0xE3, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, 0x40, 0xFE, + 0x07, 0x19, 0x6E, 0xEE, 0xFB, 0x3F, 0xE3, 0xCF, 0x87, 0xA4, 0x7A, 0x50, 0x5D, 0x1E, 0xFE, 0x3B, + 0x3D, 0x1D, 0x18, 0x8D, 0xA6, 0x1E, 0x30, 0xFF, 0xED, 0xC6, 0x4B, 0xBF, 0xC5, 0x03, 0xE6, 0x00, + 0x00, 0x00, 0x40, 0x01, 0xC2, 0x07, 0xD5, 0xC3, 0x08, 0x71, 0x7B, 0xEB, 0x40, 0x82, 0x07, 0xD5, + 0xE5, 0xE1, 0xBF, 0xD3, 0xD3, 0x91, 0xA1, 0xE6, 0x9E, 0xF3, 0x88, 0x3F, 0x60, 0xFE, 0xCA, 0x53, + 0x73, 0xB6, 0xF2, 0x80, 0x39, 0x00, 0x00, 0x00, 0x30, 0x05, 0xDC, 0x07, 0x19, 0xBE, 0xBE, 0x75, + 0xDE, 0xFE, 0x68, 0x88, 0xBC, 0x73, 0xA8, 0xC1, 0x83, 0xEA, 0xF2, 0xF0, 0xDF, 0xE9, 0xE9, 0xD0, + 0x88, 0x4F, 0x3D, 0x60, 0xFE, 0xDA, 0xE6, 0x39, 0x3F, 0xE1, 0x01, 0x73, 0x00, 0x00, 0x00, 0xA0, + 0x03, 0xDC, 0x07, 0x19, 0xC6, 0x1F, 0x54, 0x3F, 0xFD, 0xB7, 0xF6, 0xF0, 0x5E, 0x82, 0xF8, 0x70, + 0x0F, 0x98, 0xD7, 0x3C, 0xE7, 0xC1, 0x03, 0xE6, 0x00, 0x00, 0x00, 0x40, 0x77, 0x88, 0x7F, 0x90, + 0xE1, 0xF8, 0xEE, 0x3E, 0x33, 0xF1, 0xF7, 0xEE, 0x20, 0xAF, 0x02, 0xA0, 0x93, 0xAB, 0x0F, 0x8D, + 0xF8, 0xDC, 0x03, 0xE6, 0x6F, 0x0C, 0xD5, 0x3F, 0x60, 0x3E, 0xDA, 0xFF, 0x9E, 0x3F, 0x0A, 0x7E, + 0xBB, 0x00, 0x00, 0x00, 0x00, 0x3A, 0xCD, 0x7F, 0x50, 0x7D, 0xCB, 0xBC, 0xAF, 0x57, 0x1E, 0x54, + 0xB7, 0x07, 0x78, 0xBB, 0x37, 0xF7, 0xF5, 0xD9, 0x03, 0xBD, 0x3B, 0xD8, 0xAB, 0x18, 0x98, 0xEA, + 0xD5, 0xC7, 0x46, 0x74, 0xEE, 0x83, 0x04, 0x79, 0xC0, 0x1C, 0x00, 0x00, 0x00, 0xE8, 0x31, 0xEE, + 0x41, 0xF5, 0x57, 0x36, 0xCD, 0xDB, 0x12, 0x46, 0x88, 0xDB, 0xDB, 0xC3, 0xF3, 0xED, 0x01, 0x5F, + 0x45, 0xC1, 0x54, 0x4D, 0x47, 0x87, 0x1B, 0x0F, 0x98, 0x03, 0x00, 0x00, 0x00, 0x25, 0xF0, 0x6F, + 0x1B, 0xFA, 0xFA, 0x5E, 0xDB, 0x32, 0xF7, 0x27, 0x61, 0x84, 0xFC, 0x7E, 0xE7, 0x3C, 0x73, 0xEA, + 0xD9, 0xF9, 0xF6, 0xC0, 0xAF, 0x02, 0xA1, 0xC8, 0x35, 0x0E, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, + 0x00, 0x4A, 0xE6, 0x57, 0x4F, 0x5C, 0xBA, 0xC6, 0x86, 0xC8, 0xB1, 0x68, 0x88, 0x9C, 0xF9, 0x3B, + 0x17, 0x01, 0x2A, 0x16, 0xF2, 0x5E, 0x7D, 0x78, 0xB8, 0xF1, 0x80, 0x39, 0x00, 0x00, 0x00, 0x50, + 0x62, 0xEE, 0x01, 0xEE, 0xDF, 0x3E, 0x39, 0xF7, 0xAB, 0xAF, 0x6F, 0x9B, 0x37, 0x1E, 0x86, 0x88, + 0x7B, 0x50, 0xBD, 0xD8, 0xE7, 0x43, 0xEA, 0xC3, 0x83, 0x07, 0xCC, 0x01, 0x00, 0x00, 0x80, 0x69, + 0xA4, 0xF2, 0x41, 0x86, 0x73, 0xEF, 0x79, 0x7D, 0xCB, 0xDC, 0x9A, 0x07, 0xD5, 0xCF, 0xFD, 0x34, + 0xEF, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, 0xA6, 0xB1, 0x57, 0x9E, 0x9C, + 0x73, 0xA9, 0x7A, 0x50, 0x3D, 0x9F, 0x10, 0xA9, 0x0D, 0x0F, 0x1E, 0x30, 0x07, 0x00, 0x00, 0x00, + 0xE0, 0x7B, 0x6D, 0x47, 0xDF, 0x40, 0xE5, 0x83, 0x0C, 0x27, 0x43, 0xE4, 0x8D, 0x3D, 0x7D, 0xFE, + 0x33, 0x22, 0xD9, 0xDE, 0x9A, 0x55, 0x79, 0xB8, 0xDC, 0x3D, 0xE3, 0x11, 0xBF, 0xF1, 0xE0, 0x01, + 0x73, 0x00, 0x00, 0x00, 0x00, 0xBE, 0x57, 0x9E, 0x99, 0x73, 0xDB, 0xEB, 0xDB, 0xE7, 0x9E, 0x8C, + 0x86, 0x48, 0x18, 0x23, 0xEF, 0x1C, 0x9A, 0x6F, 0x4E, 0xFF, 0xCD, 0x7C, 0xFF, 0x79, 0x91, 0xF8, + 0x0D, 0x89, 0xFB, 0xFF, 0xDD, 0xBF, 0xEE, 0xFE, 0xFD, 0x77, 0x0E, 0xF5, 0xD5, 0x3C, 0xDF, 0x11, + 0xCE, 0x3D, 0x60, 0x6E, 0x7F, 0xEE, 0x75, 0xC1, 0x5F, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x2A, 0xDC, + 0x1B, 0xB3, 0x5E, 0x79, 0x66, 0xEE, 0x70, 0x3C, 0x44, 0x5A, 0x2E, 0x16, 0x1D, 0x95, 0xCD, 0x19, + 0xFA, 0xF5, 0xA3, 0x97, 0xDE, 0x1C, 0xFC, 0xD4, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xB9, 0x87, 0xD5, + 0x7F, 0xB3, 0x71, 0xDE, 0x9D, 0xAF, 0x3E, 0x3D, 0xEF, 0xA1, 0x57, 0x37, 0xCF, 0x7D, 0x59, 0x46, + 0x47, 0xB8, 0x20, 0x38, 0x5E, 0xDB, 0x3C, 0xF7, 0xD8, 0xAB, 0xCF, 0xCC, 0x7D, 0xDA, 0xDD, 0x76, + 0xFC, 0xB7, 0xEF, 0xCC, 0xFB, 0x40, 0xF0, 0x53, 0x01, 0x00, 0x00, 0x00, 0x40, 0x3A, 0xEE, 0x35, + 0xB9, 0xFE, 0x07, 0x1B, 0xEE, 0xE8, 0x1B, 0x88, 0xEF, 0xDF, 0x36, 0xCC, 0xEE, 0x0B, 0xFE, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xD0, 0x15, 0xDE, 0xF3, 0x9E, 0xFF, 0x1F, 0x5B, 0xE2, 0x94, 0x1D, 0x86, + 0x86, 0x23, 0x09, 0x00, 0x00, 0x00, 0x00, 0x49, 0x45, 0x4E, 0x44, 0xAE, 0x42, 0x60, 0x82}; + +static const uint8_t tree_gif[] PROGMEM = { + + 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x28, 0x00, 0x3C, 0x00, 0x83, 0x0B, 0x00, 0x00, 0xFF, 0xFF, + 0x00, 0x21, 0x00, 0x00, 0x4A, 0x00, 0x00, 0x6B, 0x00, 0x00, 0x94, 0x00, 0x00, 0xB5, 0x00, 0x00, + 0xDE, 0x00, 0x00, 0xFF, 0x00, 0x6B, 0x00, 0x00, 0xFF, 0x33, 0x33, 0xFF, 0xFF, 0x00, 0xFF, 0xFF, + 0xFF, 0xFF, 0xCC, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x99, 0x00, 0xCC, 0x00, 0x00, 0x21, 0xFF, 0x0B, + 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0xA0, 0x0F, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, + 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, + 0x8C, 0xCA, 0xE8, 0x85, 0xE8, 0xA5, 0xAC, 0x67, 0xEA, 0x8A, 0xE5, 0x2B, 0x2F, 0xE3, 0x31, 0xCE, + 0xAF, 0x41, 0x1C, 0xB8, 0x1B, 0x24, 0x80, 0x04, 0xAF, 0x87, 0x02, 0x26, 0x88, 0xA1, 0x07, 0x60, + 0xB9, 0x44, 0x82, 0x04, 0x02, 0x80, 0x61, 0x30, 0x70, 0x6E, 0x0C, 0x86, 0x03, 0x60, 0x20, 0xB0, + 0x6A, 0xA8, 0xD3, 0x03, 0x21, 0xEC, 0xAD, 0x18, 0x12, 0xE8, 0xF4, 0xB1, 0x4C, 0x51, 0xA0, 0x07, + 0xEA, 0x07, 0x5B, 0xF2, 0x70, 0x13, 0x76, 0xD4, 0xA8, 0xBC, 0xBC, 0xEA, 0x1F, 0x06, 0x77, 0x51, + 0x73, 0x50, 0x0A, 0x80, 0x7F, 0x04, 0x4C, 0x4D, 0x65, 0x06, 0x0A, 0x3B, 0x3B, 0x62, 0x5A, 0x53, + 0x65, 0x05, 0x02, 0x04, 0x68, 0x0C, 0x6A, 0x00, 0x5D, 0x5E, 0x0F, 0x0F, 0x6A, 0x98, 0x6A, 0x09, + 0x7B, 0x56, 0x9D, 0x09, 0x0C, 0xA7, 0xA7, 0x7F, 0x06, 0x9D, 0xA3, 0x44, 0x02, 0x01, 0x03, 0x90, + 0x0C, 0x87, 0x03, 0x06, 0x02, 0x05, 0x56, 0x06, 0x01, 0x02, 0x53, 0xB1, 0xB3, 0x04, 0x79, 0xAF, + 0x55, 0x48, 0x51, 0xB0, 0x87, 0xC0, 0x7F, 0x07, 0x95, 0x05, 0x85, 0x44, 0xB6, 0x00, 0x05, 0x53, + 0x96, 0x6A, 0x60, 0x02, 0x0A, 0x48, 0x89, 0x00, 0x07, 0xA1, 0x69, 0x7D, 0x2B, 0x3D, 0x9D, 0x41, + 0xA1, 0x04, 0xA0, 0xDD, 0x9D, 0x38, 0x02, 0xE1, 0x6A, 0x07, 0x62, 0x0C, 0x77, 0xE6, 0xAD, 0x2F, + 0x05, 0x01, 0xB6, 0x90, 0x07, 0xA8, 0xA7, 0x54, 0xB5, 0xBC, 0x06, 0x33, 0x50, 0x53, 0x3A, 0x00, + 0x39, 0x62, 0x10, 0x6B, 0xDF, 0xBE, 0x19, 0x03, 0x18, 0x40, 0xA9, 0x15, 0x4B, 0xCC, 0x0E, 0x77, + 0x3B, 0x04, 0xC4, 0x02, 0x38, 0x43, 0x21, 0x96, 0x2C, 0xD3, 0xD6, 0x81, 0x01, 0x26, 0x2A, 0xFB, + 0xDE, 0x07, 0x7C, 0x0A, 0xB7, 0x71, 0x1B, 0x79, 0xEE, 0xC5, 0x83, 0x72, 0xDD, 0x84, 0xBC, 0x4B, + 0x13, 0xA4, 0x13, 0x15, 0x17, 0xAB, 0x18, 0x78, 0x4A, 0x43, 0x40, 0x81, 0x43, 0x76, 0x8E, 0xB6, + 0x04, 0x7C, 0x19, 0x02, 0x98, 0xC4, 0x86, 0x35, 0xBD, 0xE1, 0x1C, 0x90, 0x4D, 0x62, 0xBF, 0x14, + 0xFC, 0x7E, 0x02, 0x1A, 0x60, 0xD3, 0xD1, 0x9D, 0x3B, 0x3A, 0x09, 0xFC, 0x44, 0xB1, 0xD0, 0x96, + 0x8E, 0x43, 0x8D, 0x9E, 0xDA, 0xDB, 0x22, 0x11, 0x8A, 0x42, 0x10, 0x5C, 0x00, 0x1A, 0x2D, 0x38, + 0xF2, 0x0E, 0xA0, 0x4A, 0x03, 0x4E, 0xA2, 0xF0, 0xF4, 0x80, 0x17, 0x95, 0x8C, 0x23, 0xD1, 0xD8, + 0x12, 0x00, 0x92, 0x03, 0xAB, 0x99, 0x23, 0x71, 0x3E, 0x8D, 0xEB, 0x6E, 0x18, 0x07, 0x66, 0x23, + 0x05, 0x3E, 0x72, 0xE4, 0x06, 0x0D, 0x81, 0x02, 0xE4, 0x36, 0x5D, 0xD9, 0xA5, 0xC0, 0xAD, 0x59, + 0xA2, 0x86, 0x6E, 0xD6, 0xC4, 0x73, 0xEB, 0x15, 0xA5, 0xC5, 0xDE, 0x14, 0xF4, 0x62, 0x07, 0xC0, + 0xE9, 0x9D, 0xCC, 0x58, 0x02, 0x14, 0xA0, 0x84, 0x45, 0x83, 0x68, 0x7A, 0x8D, 0x81, 0x66, 0xC3, + 0xE9, 0xD0, 0xA6, 0x3E, 0x03, 0xF3, 0x80, 0x7D, 0x90, 0xD8, 0x58, 0xA2, 0x59, 0x2D, 0x90, 0x68, + 0xD6, 0x64, 0x17, 0x76, 0x5A, 0x23, 0xBF, 0x13, 0x58, 0x89, 0x7A, 0xC3, 0xF0, 0x8F, 0xB6, 0xB8, + 0x4B, 0xD3, 0x74, 0x52, 0x50, 0x92, 0xC2, 0x03, 0xD1, 0x78, 0xD7, 0x89, 0x4C, 0x23, 0x26, 0x6E, + 0x82, 0xCC, 0x15, 0x5E, 0x05, 0x08, 0x30, 0x06, 0x8A, 0x75, 0x64, 0xFA, 0x42, 0xF1, 0x12, 0xAD, + 0x60, 0xDE, 0x51, 0x0A, 0x94, 0xBA, 0x5E, 0x2C, 0x8C, 0x86, 0xDD, 0x3D, 0xDE, 0x8F, 0x0A, 0x70, + 0x51, 0x5F, 0xFE, 0xF2, 0x84, 0xD1, 0xD0, 0xA6, 0x68, 0xB7, 0x96, 0x62, 0x14, 0x0C, 0xC1, 0xB7, + 0x90, 0x68, 0x72, 0xD1, 0x7C, 0xD9, 0x3D, 0xA3, 0x94, 0x35, 0xDE, 0x54, 0x06, 0x92, 0x51, 0x50, + 0x68, 0xC2, 0xC5, 0x44, 0xB7, 0x30, 0x70, 0xDE, 0x6A, 0x49, 0x69, 0x86, 0xC5, 0x2D, 0xA3, 0x29, + 0x04, 0x05, 0x2F, 0xD9, 0xC4, 0x02, 0x0C, 0x6C, 0x0C, 0x48, 0xB0, 0x94, 0x01, 0xDA, 0x3C, 0xF2, + 0x56, 0x21, 0xFA, 0xE8, 0xA3, 0xA1, 0x55, 0x12, 0xE9, 0xF4, 0x56, 0x42, 0xF8, 0x50, 0x00, 0x40, + 0x08, 0x08, 0xD4, 0x88, 0x80, 0x05, 0x33, 0x66, 0x10, 0xA2, 0x0C, 0xDC, 0xA0, 0xB0, 0xA3, 0x0B, + 0x71, 0xCD, 0xB1, 0x80, 0x75, 0x69, 0x20, 0x41, 0xE4, 0x91, 0x6B, 0x64, 0x10, 0x01, 0x00, 0x21, + 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, 0x3C, 0x00, + 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, 0xE4, 0x8C, + 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0x31, 0x1C, 0x34, + 0x1B, 0x24, 0x4C, 0x82, 0xE7, 0x28, 0x5E, 0x02, 0x78, 0x7A, 0x30, 0x8E, 0x47, 0x62, 0x48, 0x20, + 0x60, 0xD8, 0x06, 0x4A, 0x8E, 0xC1, 0x70, 0x60, 0x0C, 0x04, 0xD1, 0xCD, 0x60, 0x60, 0x3B, 0x10, + 0xBA, 0x59, 0x8B, 0x21, 0x41, 0x2E, 0x0F, 0xC3, 0x16, 0xF2, 0xC0, 0xAC, 0x40, 0x4F, 0x1E, 0x80, + 0x04, 0x81, 0x70, 0xD8, 0x0A, 0x14, 0x0F, 0xF7, 0x42, 0x00, 0xA0, 0xD6, 0x09, 0x0A, 0x81, 0x81, + 0x68, 0x00, 0x85, 0x85, 0x7F, 0x07, 0x07, 0x0A, 0x06, 0x7A, 0x06, 0x00, 0x74, 0x74, 0x5E, 0x8A, + 0x36, 0x68, 0x05, 0x7C, 0x66, 0x3D, 0x64, 0x58, 0x61, 0x0F, 0x0F, 0x66, 0x64, 0x99, 0x64, 0x79, + 0x9C, 0x9E, 0xA0, 0x48, 0x4E, 0x9D, 0xA3, 0x4A, 0x02, 0x01, 0x37, 0x90, 0x55, 0x04, 0x5C, 0x02, + 0x05, 0x59, 0x06, 0x01, 0x02, 0x4F, 0x89, 0x55, 0x76, 0xAC, 0x50, 0xAB, 0x0A, 0xAD, 0x7F, 0xB1, + 0x75, 0x07, 0x02, 0x04, 0x05, 0x00, 0xBE, 0x39, 0x06, 0x77, 0x05, 0x36, 0x04, 0x9F, 0x5B, 0xCC, + 0x00, 0x4A, 0x82, 0x81, 0x07, 0x9F, 0x65, 0x86, 0x85, 0x40, 0x9D, 0x0A, 0x9F, 0x0C, 0xD0, 0x9F, + 0x00, 0x9D, 0x39, 0x02, 0xDE, 0x66, 0xB0, 0x73, 0xE2, 0x09, 0xE4, 0xAA, 0x2F, 0x05, 0x01, 0xCC, + 0x5E, 0xA7, 0x56, 0x75, 0xD2, 0xB8, 0x8C, 0x2F, 0x4C, 0x36, 0x06, 0xB1, 0x73, 0xE1, 0x88, 0xC9, + 0x92, 0x45, 0x43, 0x96, 0x00, 0x2E, 0x37, 0xE8, 0x79, 0x99, 0x53, 0xEC, 0x86, 0x0D, 0x06, 0x05, + 0xF3, 0x51, 0x61, 0x57, 0xE6, 0x9E, 0xBF, 0x35, 0x0C, 0xDE, 0x81, 0xE8, 0x64, 0x10, 0xFB, 0x5B, + 0xB6, 0x6C, 0xF5, 0x56, 0x94, 0x22, 0x13, 0xA7, 0xE2, 0x9C, 0x04, 0xDF, 0xCA, 0x74, 0xB2, 0xB2, + 0xC2, 0x40, 0x2A, 0x92, 0x72, 0x20, 0x45, 0x52, 0xE0, 0x45, 0x1A, 0x01, 0x2B, 0xCA, 0x3E, 0xC4, + 0x3A, 0x38, 0x60, 0xDB, 0x23, 0x86, 0xD6, 0x14, 0x0C, 0x20, 0xC0, 0x84, 0xCB, 0x8A, 0x7C, 0x3C, + 0x1F, 0x25, 0x94, 0xA9, 0x80, 0x21, 0x17, 0xA2, 0x5B, 0x4E, 0x34, 0x91, 0xE5, 0x2F, 0x99, 0x4C, + 0xA0, 0x89, 0xEC, 0x5C, 0xC1, 0xB5, 0x89, 0xC3, 0x15, 0x2B, 0xCC, 0x10, 0xD6, 0xF9, 0x38, 0x67, + 0xA8, 0xB1, 0x01, 0xE5, 0x40, 0xD4, 0x7B, 0x42, 0xF1, 0x63, 0x02, 0x66, 0x02, 0x12, 0xA4, 0xFA, + 0x90, 0x2A, 0x54, 0xB6, 0x44, 0xEB, 0xDA, 0x96, 0x19, 0x9A, 0x53, 0x43, 0x01, 0xBB, 0x64, 0x84, + 0xAE, 0xC3, 0xBB, 0xB0, 0xCC, 0x31, 0x40, 0x5D, 0x35, 0xD8, 0x62, 0x82, 0x6B, 0x68, 0xAC, 0xA6, + 0x43, 0xF1, 0xD2, 0x01, 0x20, 0xE9, 0x8A, 0x25, 0x05, 0x96, 0x36, 0xD8, 0x8A, 0xD7, 0xD8, 0x46, + 0xD0, 0x85, 0xEB, 0x7E, 0x72, 0x31, 0x10, 0x54, 0x9F, 0x85, 0x00, 0xF1, 0xA6, 0x1C, 0x94, 0x2C, + 0x34, 0xB2, 0x17, 0x9F, 0x5B, 0xB8, 0x14, 0x80, 0xFC, 0x41, 0x28, 0x63, 0xC7, 0x03, 0x9A, 0x4A, + 0x32, 0x9C, 0x2C, 0x2B, 0x2E, 0x40, 0x72, 0x63, 0x59, 0x48, 0x85, 0x47, 0x8D, 0xD8, 0xC8, 0xD9, + 0xE2, 0xF0, 0x55, 0x99, 0x4A, 0xE3, 0x82, 0x07, 0x41, 0x3F, 0x25, 0x92, 0xAE, 0xD7, 0x4C, 0x3C, + 0xE7, 0xAC, 0x02, 0x04, 0x58, 0xC4, 0xC4, 0xAD, 0x9C, 0x1B, 0xB1, 0x3F, 0xE1, 0x42, 0x3D, 0x4B, + 0x9E, 0x85, 0xCB, 0x57, 0xA6, 0x30, 0x4B, 0x97, 0x88, 0x26, 0xA2, 0x03, 0x7F, 0x8B, 0x72, 0x2D, + 0x90, 0x79, 0x02, 0xFD, 0x59, 0x36, 0xB2, 0xF3, 0x41, 0x2A, 0x65, 0xAD, 0x75, 0x64, 0x3A, 0x0C, + 0x48, 0xB4, 0x15, 0x35, 0x13, 0xE0, 0xC2, 0xC0, 0x2D, 0xB1, 0x15, 0x95, 0x0C, 0x13, 0x97, 0x59, + 0x73, 0x90, 0x01, 0xF5, 0xAC, 0x36, 0x8D, 0x79, 0x12, 0x40, 0xB8, 0x45, 0x22, 0xB8, 0xF8, 0xC4, + 0x0C, 0x7D, 0xB3, 0x31, 0x96, 0xCF, 0x00, 0x01, 0x76, 0x41, 0x80, 0x4F, 0x0B, 0x80, 0x78, 0x4A, + 0x24, 0x5B, 0x8C, 0x18, 0xDB, 0x8A, 0x0A, 0xF0, 0xC3, 0x15, 0x88, 0x08, 0xF1, 0xC5, 0xC7, 0x3C, + 0x13, 0x40, 0x94, 0x01, 0x81, 0x13, 0x20, 0xA0, 0x23, 0x02, 0x27, 0xE0, 0x58, 0x63, 0x08, 0xD9, + 0xE8, 0x41, 0x81, 0x5B, 0x42, 0x7A, 0x57, 0x86, 0x12, 0x46, 0x26, 0x79, 0x46, 0x06, 0x11, 0x00, + 0x00, 0x21, 0xF9, 0x04, 0x09, 0x14, 0x00, 0x0B, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x28, 0x00, + 0x3C, 0x00, 0x03, 0x04, 0xFB, 0x70, 0xC9, 0x49, 0x6B, 0x75, 0x36, 0xEB, 0xBD, 0x31, 0xFF, 0xA0, + 0xE4, 0x8C, 0xA4, 0x17, 0x9E, 0x57, 0x89, 0xAE, 0xA9, 0xC9, 0xAE, 0xE3, 0x31, 0xBE, 0xAF, 0xA1, + 0x1C, 0x34, 0x1B, 0x24, 0x4A, 0x82, 0xE7, 0x27, 0x85, 0x50, 0x08, 0x0C, 0x3D, 0x12, 0xBC, 0xC4, + 0xA3, 0x18, 0x12, 0x08, 0x14, 0x86, 0xC1, 0x80, 0xC9, 0x31, 0x18, 0x0E, 0x84, 0x81, 0x80, 0xBA, + 0x91, 0x46, 0xB1, 0x51, 0x06, 0xD7, 0x62, 0x40, 0x9A, 0x91, 0xE2, 0x71, 0xA5, 0x37, 0x40, 0x33, + 0xDE, 0xE9, 0xF1, 0xE3, 0xA1, 0x20, 0x10, 0x0E, 0x52, 0x01, 0x63, 0xA9, 0x5E, 0x0C, 0x85, 0x03, + 0x76, 0x7A, 0x7D, 0x0B, 0x4E, 0x03, 0x75, 0x78, 0x77, 0x78, 0x06, 0x84, 0x51, 0x37, 0x8A, 0x77, + 0x02, 0x51, 0x6A, 0x05, 0x02, 0x04, 0x67, 0x67, 0x5B, 0x72, 0x47, 0x98, 0x98, 0x7C, 0x5C, 0x73, + 0x66, 0x58, 0x07, 0x8B, 0x0F, 0x00, 0x9F, 0x45, 0x02, 0x01, 0x03, 0xA3, 0x0C, 0x89, 0x03, 0x06, + 0x02, 0x00, 0x5C, 0x06, 0x01, 0x92, 0x52, 0x07, 0xAE, 0x59, 0x03, 0x00, 0xBD, 0xBD, 0x4C, 0x02, + 0x05, 0xAB, 0xB9, 0x70, 0x0C, 0xAC, 0x96, 0x00, 0x52, 0x45, 0x36, 0xC1, 0x51, 0x97, 0x0C, 0x66, + 0x5E, 0x00, 0x8C, 0x4C, 0x0A, 0x05, 0x5F, 0x68, 0x98, 0x4E, 0x56, 0x40, 0x7F, 0x3D, 0x67, 0x97, + 0x9D, 0x73, 0x39, 0x02, 0x74, 0x9C, 0x48, 0xA4, 0x76, 0x76, 0x66, 0x73, 0xA8, 0x2C, 0x05, 0x50, + 0x02, 0xA3, 0xA3, 0x59, 0x78, 0x5E, 0x92, 0xD4, 0x2C, 0xDB, 0xB0, 0x59, 0x76, 0x07, 0x00, 0x78, + 0x16, 0x09, 0x80, 0xF5, 0xE4, 0x05, 0xC1, 0x81, 0x5F, 0xB0, 0x10, 0x00, 0xA0, 0xEE, 0xC0, 0xC0, + 0x03, 0x8E, 0x68, 0x68, 0xB1, 0x72, 0xE5, 0x92, 0xAF, 0x5E, 0xF6, 0x0C, 0x10, 0xF0, 0x86, 0x62, + 0xFB, 0xCE, 0xC1, 0x03, 0x98, 0x00, 0x74, 0x42, 0x42, 0xE7, 0xC5, 0xB9, 0x4E, 0xFF, 0xC2, 0x9D, + 0x99, 0xA3, 0x60, 0x0A, 0x0A, 0x03, 0xED, 0xC0, 0xDD, 0xF1, 0x47, 0xCF, 0xCB, 0x2E, 0x97, 0x20, + 0x92, 0x0D, 0x64, 0x85, 0xA5, 0x65, 0x43, 0x2C, 0x3C, 0x19, 0x10, 0x30, 0x94, 0x2F, 0x27, 0xBE, + 0x9D, 0x87, 0x78, 0xCE, 0x54, 0x47, 0xC0, 0x98, 0xC6, 0x9D, 0x39, 0x2F, 0xC6, 0xB2, 0xF1, 0x87, + 0x29, 0x96, 0x62, 0xC6, 0xB6, 0x69, 0xE2, 0xC0, 0x2B, 0x4A, 0x2C, 0x58, 0x49, 0x47, 0xDA, 0x11, + 0x6A, 0x69, 0xC0, 0xB8, 0x10, 0x22, 0x1F, 0xDC, 0x0A, 0xF4, 0x6D, 0x64, 0x02, 0x06, 0xB1, 0x04, + 0x28, 0x39, 0xBB, 0xA1, 0xDD, 0x49, 0x4C, 0xE9, 0xD4, 0xB9, 0x4D, 0x0A, 0xA2, 0x40, 0x81, 0x91, + 0x81, 0x68, 0x2E, 0x35, 0x43, 0xA0, 0xC0, 0x50, 0x05, 0x1F, 0x6A, 0x39, 0xB9, 0x65, 0x47, 0x4A, + 0xBF, 0xBC, 0xF4, 0xF0, 0x04, 0xE3, 0x98, 0xA1, 0x96, 0x02, 0x5B, 0x5E, 0x71, 0xA5, 0x53, 0xA8, + 0x4E, 0x68, 0x16, 0x2B, 0x01, 0xFC, 0x42, 0x29, 0x4A, 0x21, 0xF4, 0xE8, 0x87, 0x0A, 0xA5, 0x04, + 0xDA, 0xDC, 0x94, 0x95, 0x6A, 0x03, 0xC2, 0x5A, 0x6E, 0xF0, 0x66, 0xC8, 0x0E, 0xC0, 0x99, 0x20, + 0xDF, 0x16, 0x93, 0xAC, 0x91, 0x64, 0x16, 0x0B, 0xED, 0x14, 0x70, 0xF2, 0xC2, 0x6B, 0x75, 0x27, + 0x68, 0x81, 0xDA, 0x90, 0xB4, 0x0B, 0xDC, 0x74, 0xC8, 0x8B, 0x67, 0xB0, 0xBC, 0x75, 0x2B, 0xCC, + 0x5D, 0xA1, 0x00, 0xD8, 0x09, 0xC4, 0x3D, 0x23, 0x92, 0xB0, 0x6B, 0x29, 0xDA, 0x6A, 0x55, 0x12, + 0x46, 0x7A, 0x41, 0xA5, 0x81, 0xF8, 0x62, 0x25, 0xE8, 0x4E, 0x2A, 0x60, 0x22, 0x52, 0x05, 0xB4, + 0xB4, 0x94, 0x14, 0xAC, 0x12, 0x05, 0xBF, 0xCD, 0xB4, 0x60, 0xA7, 0x6F, 0x66, 0x65, 0xE7, 0x57, + 0xC7, 0xA3, 0xC8, 0x67, 0x85, 0x16, 0x5B, 0x49, 0xF0, 0x84, 0x2A, 0x48, 0x19, 0x92, 0x47, 0x30, + 0x4E, 0x00, 0x60, 0xC9, 0x57, 0x71, 0x79, 0x03, 0x51, 0x30, 0xD3, 0x4C, 0xA0, 0xC0, 0x4E, 0xA4, + 0x1C, 0x45, 0x51, 0x2C, 0x7E, 0x39, 0xB8, 0x18, 0x3E, 0x04, 0xB5, 0x04, 0x14, 0x6C, 0xB3, 0xF8, + 0xF1, 0xC7, 0x3C, 0x00, 0xAA, 0xC6, 0xCB, 0x45, 0xFC, 0x21, 0xD5, 0x52, 0x72, 0x17, 0x95, 0x88, + 0xD8, 0x09, 0x08, 0x00, 0x80, 0x00, 0x02, 0x28, 0x94, 0x28, 0xC1, 0x8C, 0x20, 0x20, 0xD1, 0x5D, + 0x02, 0x27, 0xE8, 0x88, 0x82, 0x5B, 0x84, 0x2C, 0xE0, 0xD6, 0x19, 0x4C, 0x1C, 0xA9, 0xA4, 0x19, + 0x1B, 0x44, 0x00, 0x00, 0x21, 0xFE, 0x19, 0x42, 0x6F, 0x79, 0x27, 0x73, 0x20, 0x48, 0x61, 0x70, + 0x70, 0x79, 0x20, 0x48, 0x6F, 0x6C, 0x69, 0x64, 0x61, 0x79, 0x73, 0x20, 0x50, 0x61, 0x67, 0x65, + 0x00, 0x3B + +}; + +static const uint8_t bird_gif[] PROGMEM = { + 0x47, 0x49, 0x46, 0x38, 0x39, 0x61, 0x74, 0x00, 0x4E, 0x00, 0xCC, 0x13, 0x00, 0xFF, 0xFF, 0xFF, + 0xEF, 0xFF, 0xFF, 0xBD, 0xE7, 0xE7, 0xD6, 0xEF, 0xEF, 0x63, 0x63, 0x63, 0xAD, 0xAD, 0xAD, 0xCE, + 0xCE, 0xCE, 0xD6, 0xDE, 0xDE, 0x4A, 0x4A, 0x4A, 0x7B, 0x84, 0x84, 0x94, 0x9C, 0x9C, 0xE7, 0xE7, + 0xE7, 0x84, 0x94, 0x94, 0xB5, 0xC6, 0xC6, 0x73, 0x7B, 0x7B, 0x31, 0x31, 0x31, 0xF7, 0xF7, 0xF7, + 0x18, 0x10, 0x10, 0xCE, 0x63, 0x39, 0x6B, 0x39, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0xFF, 0x0B, + 0x4E, 0x45, 0x54, 0x53, 0x43, 0x41, 0x50, 0x45, 0x32, 0x2E, 0x30, 0x03, 0x01, 0x00, 0x00, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x00, 0x00, 0x74, 0x00, 0x4B, + 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0xAE, 0xEC, 0x68, 0x2C, + 0x6D, 0x2C, 0xCF, 0x74, 0x6D, 0x03, 0x46, 0x84, 0x40, 0x77, 0xEF, 0xFF, 0x40, 0x51, 0x42, 0x41, + 0x0C, 0x1A, 0x8F, 0x48, 0x13, 0xC1, 0xD0, 0x20, 0x00, 0x0E, 0x8E, 0x42, 0x72, 0x4A, 0xAD, 0x21, + 0x0E, 0xCD, 0x05, 0xE1, 0x80, 0xA8, 0x7A, 0xBF, 0x29, 0xC2, 0xA0, 0x91, 0x28, 0x34, 0x02, 0x5D, + 0xB0, 0x5A, 0xFD, 0x08, 0x34, 0x14, 0x84, 0x00, 0x7A, 0x4D, 0xF7, 0x22, 0xDC, 0x89, 0xB8, 0xC1, + 0xB9, 0x80, 0xD5, 0xFF, 0x40, 0x0B, 0x77, 0x0C, 0x0F, 0x05, 0x01, 0x0C, 0x0A, 0x0B, 0x0F, 0x08, + 0x06, 0x80, 0x8E, 0x37, 0x7B, 0x01, 0x09, 0x11, 0x03, 0x68, 0x5C, 0x4C, 0x0A, 0x8F, 0x9A, 0x33, + 0x06, 0x09, 0x01, 0x0E, 0x71, 0x68, 0x88, 0x92, 0x07, 0x9B, 0xA6, 0x2C, 0x0A, 0x86, 0x07, 0x95, + 0x05, 0x04, 0xA1, 0x5D, 0x8D, 0xA7, 0xB2, 0x26, 0x09, 0x06, 0x72, 0x72, 0x0E, 0x94, 0x01, 0xA9, + 0x04, 0x08, 0x52, 0xB3, 0xC0, 0x00, 0x09, 0x95, 0xB7, 0x0D, 0x86, 0x01, 0x04, 0x0A, 0xC3, 0x09, + 0x34, 0x43, 0xC1, 0x54, 0x0E, 0xB7, 0xD2, 0x87, 0xAE, 0xBB, 0x99, 0x32, 0x7B, 0x0E, 0xCF, 0x49, + 0x0B, 0xD1, 0xD3, 0x72, 0x0C, 0xDE, 0x57, 0x33, 0xBE, 0xCC, 0xDB, 0x47, 0x05, 0x0C, 0xDF, 0xD3, + 0x05, 0xD7, 0x31, 0x0C, 0xE1, 0xA5, 0xE7, 0x46, 0xBE, 0xEB, 0xD2, 0x04, 0x05, 0xBF, 0x2C, 0x5C, + 0x4D, 0xF3, 0x46, 0x0B, 0x11, 0x56, 0xD9, 0x3B, 0x14, 0x01, 0x14, 0x0F, 0x16, 0x04, 0x1A, 0x30, + 0x28, 0x00, 0x81, 0xA1, 0x3F, 0x1F, 0xAD, 0x02, 0x10, 0x5B, 0x87, 0x6F, 0x0E, 0x8B, 0x02, 0x0E, + 0x04, 0x5C, 0x41, 0x10, 0xF0, 0x61, 0x8F, 0x25, 0x03, 0x26, 0xDA, 0x43, 0xC4, 0x42, 0x8B, 0x00, + 0x05, 0x0E, 0x7C, 0xFF, 0xED, 0xF0, 0x68, 0x83, 0x8B, 0x44, 0x91, 0xDF, 0x06, 0xAC, 0x54, 0x01, + 0x21, 0xA1, 0x80, 0x07, 0x0F, 0x1A, 0x38, 0x70, 0xC7, 0x72, 0x46, 0xC2, 0x97, 0x03, 0x3F, 0xC5, + 0x52, 0xE1, 0x80, 0x81, 0x00, 0x01, 0x19, 0x1B, 0x3C, 0x38, 0xD8, 0x53, 0xC6, 0x81, 0x38, 0x21, + 0x61, 0x4A, 0xEB, 0xB7, 0x42, 0x01, 0x82, 0xA3, 0x58, 0x7D, 0xC9, 0x6B, 0x1A, 0x63, 0x0B, 0xD0, + 0x81, 0x11, 0x08, 0x74, 0x44, 0x61, 0xE0, 0x01, 0xD6, 0xA3, 0x05, 0x16, 0x2D, 0xE5, 0xDA, 0xC2, + 0x80, 0xB7, 0x90, 0x41, 0xCB, 0xA4, 0x39, 0xC1, 0xEF, 0x2C, 0x56, 0xAA, 0x6C, 0x57, 0x38, 0xA8, + 0x14, 0x35, 0xA8, 0x35, 0x14, 0x10, 0x10, 0x34, 0xB0, 0x9B, 0xD5, 0x4F, 0xDE, 0x14, 0x06, 0x8E, + 0xF5, 0x1D, 0xC8, 0x25, 0x85, 0x83, 0xC1, 0x84, 0x05, 0x20, 0x32, 0x30, 0xF4, 0x30, 0x2D, 0x39, + 0x8B, 0x07, 0x32, 0x42, 0xA1, 0x00, 0x72, 0xE4, 0x45, 0x08, 0x7C, 0x59, 0x36, 0x91, 0x18, 0x73, + 0xE6, 0x6F, 0x79, 0x38, 0x2B, 0x88, 0x7C, 0x54, 0xE7, 0xE0, 0x2D, 0xA3, 0x4B, 0x78, 0x7A, 0x79, + 0x7A, 0x1A, 0xCE, 0x04, 0x4C, 0x85, 0xAC, 0x66, 0x7D, 0x96, 0x80, 0xB9, 0xD8, 0x22, 0x4A, 0x4B, + 0x14, 0x00, 0x97, 0xF1, 0xD3, 0x12, 0x3B, 0x79, 0x9F, 0x45, 0xC0, 0x13, 0xB8, 0xB7, 0xE1, 0xC5, + 0x19, 0x33, 0xEB, 0x53, 0xD3, 0xA8, 0x72, 0x01, 0x0D, 0x44, 0x97, 0x5C, 0x90, 0x7B, 0x9B, 0x01, + 0x05, 0xA6, 0x89, 0xFB, 0x3D, 0x54, 0x20, 0x81, 0xDA, 0x8C, 0xD7, 0x91, 0x16, 0x22, 0x91, 0xF8, + 0x80, 0x9F, 0x86, 0x08, 0x1E, 0xF4, 0xF2, 0xD5, 0x7D, 0x96, 0x18, 0xCC, 0x47, 0xA3, 0xDB, 0x7B, + 0xCA, 0x60, 0x40, 0xCA, 0xF4, 0x58, 0x81, 0xE2, 0x42, 0x04, 0x11, 0x4C, 0x80, 0x53, 0x7C, 0x3F, + 0xC9, 0xB1, 0xC7, 0xFF, 0x7A, 0xC1, 0x18, 0xA0, 0x0E, 0x7E, 0xC4, 0x49, 0xA5, 0x99, 0x67, 0xD7, + 0xA5, 0xB4, 0x15, 0x04, 0x93, 0x48, 0xA0, 0xA1, 0x81, 0x7C, 0x49, 0xB3, 0xC7, 0x38, 0xF6, 0x11, + 0x13, 0x52, 0x7E, 0x12, 0xAE, 0x63, 0xC0, 0x55, 0x00, 0x82, 0x62, 0xD8, 0x08, 0x0B, 0x24, 0xA0, + 0xA1, 0x86, 0x57, 0x3C, 0xF0, 0xE0, 0x2D, 0x05, 0x68, 0x67, 0x4A, 0x27, 0xB7, 0x0C, 0x80, 0x95, + 0x7E, 0x41, 0x11, 0x80, 0x5E, 0x85, 0xBF, 0x9D, 0xD0, 0xC0, 0x04, 0x2F, 0x2E, 0x62, 0xCB, 0x34, + 0x03, 0xE4, 0xB1, 0xA2, 0x23, 0x5E, 0x41, 0xC8, 0x63, 0x50, 0x0E, 0x9A, 0x75, 0x5D, 0x68, 0x5B, + 0x9D, 0xA0, 0x45, 0x04, 0x38, 0x2D, 0x72, 0xCC, 0x34, 0x7B, 0x24, 0xF2, 0x88, 0x5B, 0x39, 0xEA, + 0x18, 0xE1, 0x78, 0xD2, 0x58, 0x05, 0x20, 0x6C, 0x2B, 0xD4, 0x78, 0x64, 0x89, 0x6E, 0xB8, 0xF2, + 0xC2, 0x1F, 0x4D, 0xBE, 0x44, 0x22, 0x99, 0x72, 0xE4, 0x01, 0x60, 0x19, 0x31, 0x68, 0xB1, 0xC4, + 0x78, 0x50, 0xF4, 0xE2, 0x9B, 0x43, 0x5E, 0x80, 0x99, 0xE3, 0x8E, 0x6C, 0x4E, 0xE3, 0x63, 0x7A, + 0xD9, 0x55, 0xD6, 0x82, 0x4E, 0x04, 0x30, 0xD0, 0xC0, 0x01, 0x7C, 0x2A, 0xE4, 0xA3, 0xA2, 0x47, + 0xDC, 0x37, 0xE8, 0x9C, 0xE3, 0xC9, 0x64, 0x9D, 0x72, 0x70, 0x54, 0x29, 0x03, 0x04, 0xDF, 0xE5, + 0xE1, 0x4A, 0x19, 0x06, 0xB0, 0xD9, 0xC4, 0x66, 0x48, 0x7C, 0x27, 0xCD, 0x88, 0x98, 0x92, 0x89, + 0xE2, 0x75, 0x69, 0x2D, 0x69, 0xC3, 0x02, 0x07, 0xA4, 0x03, 0x8A, 0x2B, 0x8E, 0xC2, 0x04, 0x05, + 0x03, 0x48, 0x3C, 0x17, 0x5E, 0xAB, 0x7E, 0x61, 0x04, 0x20, 0x03, 0x33, 0x21, 0x01, 0xC1, 0x02, + 0xDF, 0x81, 0x52, 0x8B, 0x34, 0xAD, 0xC8, 0x6A, 0x43, 0x3E, 0x48, 0x9E, 0xF5, 0x24, 0x45, 0xAF, + 0xF2, 0x96, 0x9D, 0xFF, 0x03, 0xF5, 0x51, 0xD1, 0xA2, 0x03, 0x90, 0xCA, 0xF1, 0x94, 0x3E, 0x37, + 0x68, 0x81, 0xA4, 0x98, 0xC0, 0x9A, 0xF8, 0xC0, 0x8F, 0xCA, 0x39, 0xA0, 0xCD, 0x1F, 0x0B, 0x10, + 0x21, 0x0D, 0x03, 0xB8, 0x7D, 0x74, 0x64, 0x98, 0xD2, 0x16, 0x8A, 0x0C, 0xBA, 0xCA, 0x29, 0xF5, + 0x48, 0x8B, 0x53, 0xA1, 0x19, 0x03, 0xA8, 0x18, 0x85, 0xB2, 0x2A, 0xB9, 0x63, 0x06, 0x45, 0x06, + 0x80, 0x48, 0x05, 0xC9, 0x6E, 0x9C, 0x4F, 0xE1, 0xA3, 0xC2, 0x77, 0xF0, 0x16, 0x95, 0x4B, 0xB7, + 0xF4, 0x12, 0xEA, 0x57, 0x59, 0x14, 0xB2, 0x46, 0x08, 0xB8, 0x8E, 0x08, 0x72, 0x06, 0xB3, 0x3E, + 0xA6, 0xF2, 0x28, 0x46, 0x8B, 0x2C, 0xEB, 0xED, 0x03, 0xF3, 0x56, 0x5C, 0xF0, 0x40, 0xE6, 0xED, + 0xA6, 0x9C, 0x7C, 0xD9, 0x02, 0xA2, 0x48, 0xCA, 0x98, 0x25, 0xD6, 0xCE, 0x4E, 0x14, 0x2B, 0x18, + 0xE7, 0xC0, 0xE5, 0xAE, 0x93, 0x00, 0xC2, 0x45, 0x01, 0xB3, 0xC0, 0x8C, 0x74, 0xFA, 0xF7, 0x80, + 0x84, 0xAC, 0xAE, 0x6C, 0xCF, 0x00, 0x04, 0xA4, 0x47, 0x2C, 0x02, 0xCE, 0x6A, 0xF2, 0x06, 0x9D, + 0x98, 0xE5, 0x3C, 0xB0, 0x98, 0xB5, 0x4D, 0xD3, 0x40, 0x04, 0x05, 0x28, 0x57, 0x40, 0x04, 0x0A, + 0x50, 0x2A, 0x4B, 0x02, 0x1F, 0x53, 0xBD, 0x74, 0x54, 0x59, 0xBF, 0x1B, 0x5A, 0x41, 0xAC, 0x65, + 0xA7, 0xF0, 0x33, 0x0C, 0x58, 0x6D, 0xB6, 0x69, 0x68, 0x4F, 0x2B, 0x87, 0x55, 0xB7, 0x38, 0x50, + 0xC8, 0x5D, 0x7E, 0x8A, 0x1D, 0x0C, 0x04, 0x8F, 0xCD, 0x1D, 0x94, 0xDD, 0x4F, 0xA1, 0xEC, 0xA1, + 0x7C, 0xAD, 0x8D, 0xC5, 0x52, 0x4D, 0xBE, 0x0A, 0x3E, 0x9E, 0x55, 0x32, 0xDA, 0xA3, 0x37, 0x03, + 0xBD, 0x44, 0x3D, 0x8F, 0x55, 0x34, 0x3B, 0x6E, 0x4F, 0x03, 0x99, 0x73, 0x89, 0x93, 0xE5, 0xFE, + 0x74, 0x13, 0xB7, 0xCB, 0xE6, 0xA4, 0x4B, 0x63, 0x90, 0x65, 0xED, 0x16, 0x25, 0x77, 0xE9, 0x54, + 0x67, 0x11, 0xDB, 0x89, 0x44, 0xB3, 0x6E, 0xF6, 0x89, 0x7E, 0x37, 0x05, 0x47, 0xE7, 0xB2, 0xFB, + 0xF5, 0x2D, 0x70, 0xDD, 0x80, 0x37, 0xDE, 0x0A, 0x8E, 0xFB, 0x06, 0x1C, 0x00, 0x4D, 0xE0, 0x1E, + 0x80, 0x0C, 0x73, 0xFB, 0x47, 0x00, 0xE8, 0x2C, 0x89, 0x6E, 0xCF, 0x0C, 0x66, 0x87, 0x64, 0x55, + 0x73, 0x87, 0xB5, 0xD2, 0x39, 0xF2, 0x54, 0xA3, 0xAD, 0x24, 0xEF, 0x09, 0xC4, 0x2E, 0x47, 0x0C, + 0x83, 0x4F, 0x44, 0x6E, 0x25, 0xA9, 0x0C, 0x8F, 0x43, 0xE0, 0xD3, 0xB4, 0x30, 0x50, 0x54, 0xF9, + 0x41, 0x57, 0xC9, 0x63, 0xE6, 0x03, 0x00, 0xC1, 0xED, 0xE9, 0xAB, 0x60, 0x4F, 0x62, 0x94, 0x41, + 0x2A, 0xFE, 0x01, 0x56, 0x11, 0x10, 0xB3, 0x65, 0x4F, 0x11, 0xCC, 0x37, 0x4A, 0x10, 0x2C, 0x8E, + 0x3C, 0x80, 0x40, 0x3A, 0x30, 0x20, 0x02, 0x96, 0x10, 0x3F, 0x13, 0x64, 0xA7, 0x1E, 0x17, 0x53, + 0x90, 0x02, 0x28, 0x87, 0x00, 0xB2, 0xC1, 0xE0, 0x29, 0x08, 0x24, 0x50, 0xC9, 0xFE, 0x37, 0x3C, + 0x28, 0x30, 0x67, 0x75, 0x01, 0x9C, 0x20, 0x4E, 0x0A, 0xE0, 0xAC, 0xAF, 0x21, 0x90, 0x3E, 0x0D, + 0x4C, 0x41, 0xBB, 0x42, 0x13, 0x05, 0x63, 0xA4, 0x64, 0x81, 0x43, 0x28, 0x40, 0xED, 0x44, 0x00, + 0x01, 0x2C, 0x78, 0x29, 0x85, 0x2C, 0x38, 0x56, 0x62, 0x1A, 0xC0, 0x1D, 0x35, 0x84, 0x00, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, + 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, + 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, + 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, + 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, + 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, + 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, + 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, + 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, + 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, + 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, + 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, + 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, + 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, + 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, + 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, + 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, + 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, + 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, + 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, + 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, + 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, + 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, + 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, + 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, + 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, + 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, + 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, + 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, + 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, + 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, + 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, + 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, + 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, + 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, + 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, + 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, + 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, + 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, + 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, + 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, + 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, + 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, + 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, + 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, + 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, + 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, + 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, + 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, + 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, + 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, + 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, + 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, + 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, + 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, + 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, + 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, + 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, + 0x0D, 0x21, 0x00, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, + 0x00, 0x6A, 0x00, 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, + 0xAE, 0x6C, 0xEB, 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, + 0x0A, 0xC7, 0x03, 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, + 0xA4, 0x10, 0xA8, 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, + 0x9E, 0x18, 0x02, 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, + 0xD4, 0x81, 0x01, 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, + 0x0D, 0x08, 0x05, 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, + 0x04, 0x06, 0x10, 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, + 0x93, 0x09, 0x0C, 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, + 0x0C, 0x39, 0x9A, 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, + 0xAB, 0x5B, 0x4A, 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, + 0x0D, 0x0D, 0x07, 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, + 0x0E, 0x7B, 0x04, 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, + 0x92, 0x0C, 0x0E, 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, + 0x5B, 0x03, 0x0E, 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, + 0x98, 0xBE, 0x73, 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, + 0xB0, 0x6A, 0xA3, 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, + 0xBC, 0xA5, 0x0C, 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, + 0x04, 0x32, 0x53, 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, + 0x67, 0x8E, 0xA2, 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, + 0x33, 0xA0, 0x2B, 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, + 0x0E, 0x10, 0xC0, 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, + 0x0A, 0x08, 0xF8, 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, + 0x1D, 0x8A, 0x47, 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, + 0x22, 0x22, 0x82, 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, + 0x6B, 0x50, 0xE0, 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, + 0xA3, 0x2D, 0x60, 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, + 0x94, 0x14, 0x7F, 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, + 0x05, 0x30, 0x4A, 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, + 0x53, 0x20, 0xC1, 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, + 0x10, 0x03, 0x80, 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, + 0x26, 0x0F, 0x28, 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, + 0xC6, 0x0A, 0x02, 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, + 0xA0, 0xC0, 0x28, 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, + 0x42, 0x01, 0x5A, 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, + 0x88, 0x33, 0x14, 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, + 0x6A, 0xC4, 0x80, 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, + 0x28, 0xC2, 0xE2, 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, + 0x21, 0xA4, 0x0C, 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, + 0x4A, 0x93, 0x29, 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, + 0x94, 0x0C, 0x38, 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, + 0x56, 0x74, 0x54, 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, + 0x99, 0x83, 0x8A, 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, + 0x10, 0x02, 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, + 0x6A, 0x00, 0x2E, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x00, 0x40, 0x62, 0xB9, 0x28, 0x08, 0x41, 0x28, + 0x4B, 0xE9, 0xBE, 0x70, 0x2C, 0xCF, 0x74, 0x6D, 0xDF, 0xE5, 0xF1, 0x3C, 0x69, 0x52, 0x24, 0x0F, + 0x82, 0xE1, 0x60, 0x00, 0x26, 0x5A, 0xB8, 0xA4, 0x72, 0xC9, 0x94, 0xE9, 0x22, 0x12, 0xC9, 0x64, + 0xF2, 0x18, 0x04, 0xAE, 0xD7, 0x01, 0xB0, 0xD0, 0xEC, 0x7A, 0xBF, 0x31, 0x48, 0x61, 0x12, 0x95, + 0x32, 0x02, 0x8E, 0x06, 0x36, 0x70, 0x50, 0x21, 0xC1, 0xF0, 0x78, 0x72, 0x91, 0x20, 0x4B, 0x55, + 0x85, 0xF5, 0xB5, 0x81, 0xE0, 0xCA, 0xFF, 0x80, 0x32, 0x0D, 0x0F, 0x53, 0x11, 0x11, 0x04, 0x07, + 0x7A, 0x57, 0x0E, 0x04, 0x6F, 0x81, 0x8F, 0x7F, 0x0B, 0x2A, 0x06, 0x94, 0x6A, 0x8A, 0x01, 0x06, + 0x04, 0x05, 0x07, 0x0B, 0x0B, 0x44, 0x94, 0xA0, 0x43, 0x24, 0x90, 0xA4, 0x37, 0x05, 0x04, 0x96, + 0x97, 0x58, 0x45, 0x09, 0x0A, 0x0C, 0x0C, 0x0A, 0x05, 0x0D, 0xB3, 0x05, 0x0A, 0x09, 0x0C, 0x05, + 0x06, 0xA3, 0x4D, 0x9F, 0xA0, 0x0B, 0xBB, 0xA5, 0x33, 0x6D, 0x08, 0x0C, 0x89, 0xAA, 0xC7, 0x8A, + 0x07, 0xAE, 0x3E, 0xC0, 0x32, 0x10, 0x07, 0x3F, 0x2A, 0x0E, 0x8C, 0x2A, 0x08, 0xD6, 0x29, 0x0E, + 0xB9, 0xCD, 0xC1, 0x22, 0x10, 0x45, 0xD2, 0xB8, 0x07, 0x56, 0x97, 0x22, 0xC8, 0x01, 0x0D, 0x0C, + 0x3E, 0x9C, 0x25, 0xCF, 0xA7, 0x04, 0xD9, 0xE2, 0xC8, 0x03, 0xD0, 0x09, 0x04, 0xD6, 0x09, 0xBA, + 0xDC, 0x30, 0x10, 0x0B, 0x06, 0xB6, 0x2A, 0x04, 0x12, 0xDC, 0x52, 0x40, 0x90, 0x60, 0x81, 0x5C, + 0x07, 0x20, 0xA8, 0x1A, 0xD0, 0x20, 0x01, 0x35, 0x07, 0x3C, 0x1C, 0x18, 0x30, 0x87, 0xCC, 0x00, + 0x03, 0x02, 0x0F, 0x12, 0x34, 0xD8, 0xA6, 0xCF, 0x44, 0xA7, 0x8F, 0x9D, 0x0E, 0x88, 0xAC, 0x75, + 0x6B, 0x22, 0xC5, 0x4B, 0x44, 0x4E, 0xFF, 0x26, 0x63, 0x80, 0x20, 0xE3, 0x81, 0x8E, 0x5D, 0x0E, + 0xA4, 0x33, 0xA6, 0x92, 0x8D, 0x03, 0x04, 0x35, 0x2F, 0x35, 0xC0, 0x98, 0xE0, 0x25, 0x4C, 0x26, + 0x07, 0x7C, 0xE4, 0xBC, 0x82, 0x40, 0xE1, 0x50, 0x3D, 0xCA, 0x52, 0x38, 0xFA, 0x89, 0xE3, 0x47, + 0xCE, 0x1F, 0x00, 0x8E, 0xAA, 0x02, 0xC2, 0x80, 0xE9, 0x92, 0x86, 0x2A, 0x0D, 0x3C, 0xA0, 0x29, + 0x55, 0xD1, 0x00, 0x8C, 0x06, 0xAC, 0x26, 0x31, 0x80, 0xC0, 0x24, 0x32, 0x04, 0x09, 0xBA, 0x9A, + 0x1B, 0x94, 0x80, 0xA3, 0x58, 0x18, 0x5A, 0xCF, 0x1C, 0x13, 0x78, 0x69, 0x9C, 0xDA, 0x2C, 0x04, + 0x22, 0x34, 0x78, 0x6B, 0x03, 0x82, 0x02, 0x44, 0x97, 0x5E, 0xD5, 0x1D, 0x60, 0xF7, 0xEE, 0xB9, + 0x07, 0x61, 0xF9, 0xD6, 0x58, 0xC0, 0x20, 0xDB, 0x1A, 0x82, 0x0B, 0x09, 0x17, 0xBE, 0xFB, 0x55, + 0x81, 0xE2, 0x1B, 0x99, 0x10, 0x39, 0xF6, 0x2A, 0x99, 0xB0, 0x61, 0x3D, 0x0E, 0x2F, 0xDF, 0x18, + 0x94, 0x87, 0xF3, 0x00, 0x01, 0x02, 0x24, 0x7F, 0x7E, 0x8C, 0x60, 0xA9, 0x68, 0x17, 0x6D, 0xCC, + 0x62, 0x91, 0x8C, 0x1A, 0x75, 0xE7, 0x2B, 0x30, 0xBA, 0xF2, 0xF1, 0xF9, 0xDA, 0x45, 0x26, 0xAE, + 0x59, 0x4E, 0xD7, 0x4E, 0xED, 0x19, 0xF7, 0x8C, 0xA3, 0x5A, 0xF7, 0xF6, 0x16, 0xF1, 0xC3, 0x68, + 0x70, 0xE1, 0xC3, 0x8B, 0xAF, 0xA1, 0x31, 0xF4, 0xB4, 0xD2, 0xD7, 0x10, 0x60, 0xE9, 0x21, 0x3C, + 0x3C, 0xFA, 0x64, 0xE3, 0x32, 0x6A, 0xD2, 0x56, 0xF0, 0xC0, 0x0F, 0x5F, 0x3A, 0xA9, 0x02, 0x70, + 0xEF, 0x4E, 0x5C, 0x3A, 0x68, 0xD7, 0xE5, 0x54, 0x72, 0xB7, 0xF2, 0xD5, 0xBC, 0xD5, 0xA0, 0x34, + 0xD7, 0xDB, 0x6E, 0xAF, 0x5A, 0x95, 0x03, 0xDE, 0x2F, 0x98, 0x73, 0xDB, 0x70, 0x01, 0xC4, 0xF2, + 0x96, 0x45, 0xB3, 0x41, 0x67, 0x5B, 0xFF, 0x7F, 0xE6, 0x00, 0x20, 0x51, 0x0C, 0xF2, 0xD0, 0x47, + 0x9C, 0x7A, 0xEA, 0x91, 0x07, 0x20, 0x4C, 0x05, 0xC8, 0xA5, 0x9E, 0x70, 0xA7, 0x31, 0x78, 0x92, + 0x24, 0x89, 0xB9, 0x70, 0x4C, 0x26, 0x41, 0x04, 0xA4, 0x40, 0x03, 0x19, 0x32, 0x72, 0xC8, 0x85, + 0x1D, 0xB9, 0x92, 0x20, 0x7F, 0xEE, 0x9D, 0x94, 0xE1, 0x49, 0x0C, 0xDD, 0x84, 0x16, 0x79, 0x11, + 0xF4, 0x11, 0x0B, 0x42, 0x62, 0x41, 0x70, 0xCB, 0x73, 0x1E, 0x0E, 0xE5, 0x20, 0x70, 0x7B, 0x10, + 0x40, 0x58, 0x5E, 0xC4, 0xE4, 0x23, 0x42, 0x02, 0x86, 0x34, 0xA2, 0x98, 0x24, 0x0A, 0x00, 0x19, + 0x63, 0x4E, 0xFD, 0x10, 0x43, 0x93, 0x32, 0x79, 0xF1, 0x90, 0x42, 0x88, 0x2E, 0x2C, 0xF0, 0x80, + 0x21, 0x0F, 0x30, 0x00, 0x5F, 0x30, 0x62, 0xF4, 0xB1, 0x61, 0x90, 0x47, 0x39, 0x18, 0xCB, 0x3F, + 0xEF, 0xF8, 0x60, 0xC0, 0x2F, 0x36, 0x3C, 0xB1, 0x22, 0x53, 0x99, 0x20, 0x90, 0x08, 0x9A, 0x5D, + 0x79, 0xD9, 0x80, 0x00, 0x29, 0xB4, 0xD6, 0x04, 0x59, 0x2C, 0xFC, 0x24, 0x13, 0x2A, 0x78, 0x76, + 0xF5, 0x95, 0x03, 0x0C, 0xA0, 0xA6, 0xA3, 0x17, 0x6E, 0x3D, 0xB2, 0xC0, 0x0F, 0x0A, 0x10, 0xB9, + 0xDA, 0x39, 0x08, 0x08, 0x90, 0x86, 0x00, 0x4E, 0x2E, 0x17, 0x86, 0x3B, 0xA5, 0x4D, 0xAA, 0x87, + 0x42, 0xAF, 0x0C, 0xE2, 0x00, 0xA6, 0x63, 0x8A, 0xF6, 0xA8, 0x0A, 0x91, 0x06, 0xF0, 0x4B, 0x9E, + 0xCE, 0x29, 0xF2, 0x17, 0x4B, 0x96, 0x16, 0x50, 0xA9, 0x9F, 0x9A, 0x02, 0x50, 0x00, 0x23, 0x81, + 0x9E, 0x1A, 0x41, 0x94, 0x47, 0x31, 0x10, 0xE6, 0x01, 0xD3, 0x98, 0xA5, 0x10, 0x2A, 0x2D, 0xF1, + 0x21, 0x46, 0x40, 0xB5, 0xDA, 0x8A, 0xD8, 0x02, 0x0D, 0x21, 0x9A, 0x80, 0x99, 0x98, 0xE0, 0x63, + 0xCE, 0x10, 0x01, 0xC8, 0x7A, 0xC2, 0x79, 0x11, 0x50, 0x65, 0x26, 0x2B, 0x9F, 0x64, 0xF9, 0xD1, + 0xE8, 0x93, 0x29, 0x32, 0x30, 0x84, 0x03, 0x0A, 0x28, 0x04, 0x2C, 0x46, 0x0B, 0x5C, 0x91, 0xAE, + 0x22, 0x64, 0x21, 0xB0, 0x13, 0x30, 0x99, 0xDC, 0xB4, 0xD3, 0xB3, 0xE9, 0x00, 0x50, 0x6A, 0xB2, + 0x00, 0xB4, 0xD1, 0x42, 0x50, 0x42, 0x00, 0xF6, 0x55, 0x51, 0xAA, 0x6A, 0x82, 0x09, 0x22, 0x08, + 0x38, 0xB0, 0x4D, 0xB7, 0x88, 0x2C, 0x60, 0x0D, 0x8B, 0xF8, 0xBE, 0x90, 0x89, 0x02, 0x0E, 0xE0, + 0x03, 0x81, 0xC0, 0x99, 0xDC, 0xAA, 0x2A, 0x44, 0xB3, 0xF8, 0xE9, 0x16, 0x04, 0x08, 0xD8, 0xC2, + 0x1C, 0x97, 0x0D, 0xCB, 0xE0, 0xC9, 0x28, 0x3A, 0x28, 0xF3, 0x5F, 0x6B, 0xBF, 0xD9, 0x72, 0xC4, + 0x62, 0x1D, 0x7F, 0x1B, 0x72, 0x0D, 0xCA, 0xBC, 0xD4, 0x86, 0x2D, 0x3E, 0xB9, 0xBC, 0x5C, 0x08, + 0x00, 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x20, 0x00, 0x6A, 0x00, + 0x25, 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0xE3, 0xA2, 0x14, 0xC6, 0x42, 0xAE, 0x6C, 0xEB, + 0xBE, 0x70, 0x2C, 0xCF, 0x2D, 0x94, 0x10, 0x4C, 0x71, 0x2C, 0x06, 0xF1, 0x24, 0x0A, 0xC7, 0x03, + 0x61, 0xA0, 0x19, 0x8F, 0xC8, 0x24, 0xCC, 0x10, 0x89, 0x48, 0x26, 0x93, 0x47, 0xA4, 0x10, 0xA8, + 0x56, 0x0B, 0x0F, 0xC2, 0x41, 0xC9, 0xED, 0x7A, 0x5B, 0x06, 0xC4, 0x44, 0x42, 0x9E, 0x18, 0x02, + 0x3A, 0x2B, 0xFA, 0xA1, 0xF8, 0xBA, 0xDF, 0xC9, 0xC6, 0xB8, 0xAC, 0x40, 0x30, 0xD4, 0x81, 0x01, + 0x81, 0xA0, 0x82, 0xFB, 0xFF, 0x2D, 0x0B, 0x0E, 0x73, 0x11, 0x6C, 0x78, 0x55, 0x0D, 0x08, 0x05, + 0x80, 0x8C, 0x8D, 0x05, 0x11, 0x08, 0x09, 0x09, 0x0E, 0x54, 0x87, 0x01, 0x0C, 0x04, 0x06, 0x10, + 0x8D, 0x9C, 0x6F, 0x0B, 0x38, 0x96, 0x78, 0x07, 0x05, 0x0A, 0x0C, 0x93, 0x0E, 0x93, 0x09, 0x0C, + 0x0A, 0x0D, 0x7D, 0x9D, 0xAF, 0x30, 0x75, 0x0E, 0x67, 0xA1, 0xB5, 0x79, 0xA3, 0x0C, 0x39, 0x9A, + 0xB0, 0xBC, 0x2B, 0x10, 0x0D, 0x37, 0x0E, 0xAC, 0x07, 0xB6, 0xB5, 0x03, 0x0D, 0xAB, 0x5B, 0x4A, + 0x07, 0x06, 0xCD, 0xCD, 0x3B, 0xBD, 0x32, 0x10, 0x3C, 0x0A, 0x37, 0x7B, 0x40, 0x0D, 0x0D, 0x07, + 0xDB, 0xDB, 0x03, 0xB5, 0x07, 0xA5, 0xCA, 0x30, 0x10, 0x06, 0xD5, 0x7B, 0x0E, 0x0E, 0x7B, 0x04, + 0x08, 0xEC, 0x08, 0x04, 0xC2, 0xBB, 0xD1, 0x31, 0x0B, 0xA3, 0xA4, 0xA6, 0x92, 0x92, 0x0C, 0x0E, + 0x0C, 0x0D, 0x10, 0x87, 0x03, 0xD5, 0x74, 0xB8, 0x82, 0x30, 0xEA, 0x5A, 0x1A, 0x5B, 0x03, 0x0E, + 0x00, 0x5B, 0x17, 0x29, 0x9E, 0xBC, 0x24, 0x0B, 0x0A, 0xEC, 0x23, 0x86, 0xE7, 0x98, 0xBE, 0x73, + 0x43, 0x66, 0x15, 0xB3, 0x55, 0xCE, 0x47, 0x82, 0x02, 0xAE, 0x1E, 0x1E, 0x39, 0xB0, 0x6A, 0xA3, + 0x25, 0x66, 0x26, 0x0F, 0xFF, 0x91, 0x44, 0xF0, 0x43, 0x9C, 0x48, 0x23, 0xC0, 0xBC, 0xA5, 0x0C, + 0x70, 0x80, 0x40, 0x83, 0x99, 0x96, 0x1A, 0x78, 0x74, 0xF9, 0x52, 0xC6, 0x82, 0x04, 0x32, 0x53, + 0x1A, 0x48, 0x80, 0x33, 0xD4, 0x80, 0x02, 0xEC, 0x42, 0xF6, 0x84, 0x21, 0x08, 0x67, 0x8E, 0xA2, + 0xB6, 0x12, 0x3C, 0x60, 0xB0, 0x74, 0xC6, 0x01, 0xA2, 0x1B, 0x75, 0xD2, 0x52, 0x33, 0xA0, 0x2B, + 0x54, 0x2B, 0x3E, 0x8A, 0x54, 0x5D, 0x42, 0xE4, 0x5B, 0x0E, 0x00, 0x56, 0xBA, 0x0E, 0x10, 0xC0, + 0x96, 0xAD, 0x57, 0xA8, 0x0D, 0x7E, 0x6C, 0x1A, 0xEB, 0xC2, 0xC0, 0x54, 0x4B, 0x0A, 0x08, 0xF8, + 0xCB, 0xB3, 0xB6, 0xAD, 0x5A, 0xB5, 0x5F, 0xC1, 0x46, 0x68, 0x40, 0xF7, 0x45, 0x1D, 0x8A, 0x47, + 0x23, 0xA1, 0xFD, 0xFB, 0x76, 0xA3, 0x42, 0x8A, 0x59, 0x1F, 0x10, 0x2E, 0xCC, 0x22, 0x22, 0x82, + 0x7D, 0x1F, 0xBD, 0x01, 0xFE, 0x0A, 0x20, 0xDB, 0x4C, 0x02, 0x6D, 0x96, 0xD2, 0x6B, 0x50, 0xE0, + 0x5E, 0x2E, 0x05, 0x29, 0x36, 0x05, 0x0E, 0x65, 0xE3, 0x66, 0x4A, 0x7D, 0x73, 0xA3, 0x2D, 0x60, + 0x90, 0xE5, 0x44, 0x0A, 0x66, 0xA4, 0xAB, 0x3D, 0x78, 0xB0, 0xC8, 0xCA, 0xDE, 0x94, 0x14, 0x7F, + 0x07, 0x28, 0x07, 0x79, 0x23, 0x52, 0xA5, 0xB0, 0xE8, 0x35, 0x03, 0x06, 0x04, 0x05, 0x30, 0x4A, + 0x2A, 0x68, 0x4E, 0xE2, 0x5D, 0x0B, 0x2D, 0x9A, 0x66, 0x0F, 0xEA, 0x35, 0x43, 0x53, 0x20, 0xC1, + 0x56, 0x93, 0x61, 0x78, 0xF6, 0xAC, 0xD9, 0xCF, 0x40, 0xE9, 0x3D, 0x20, 0x23, 0x10, 0x03, 0x80, + 0x54, 0x23, 0x00, 0x4C, 0x2A, 0x14, 0xE5, 0x25, 0xC1, 0xCC, 0x01, 0xBD, 0xE2, 0x26, 0x0F, 0x28, + 0xA2, 0xCC, 0x0C, 0x45, 0xEC, 0x30, 0x0D, 0x98, 0x97, 0xDD, 0x24, 0x04, 0x49, 0xC6, 0x0A, 0x02, + 0xC8, 0xB1, 0x50, 0xD4, 0xAA, 0x5A, 0xEE, 0x24, 0x48, 0x19, 0x00, 0xE4, 0xF4, 0xA0, 0xC0, 0x28, + 0x0A, 0xB0, 0xE2, 0x1B, 0x0D, 0x33, 0xA9, 0x25, 0x00, 0x52, 0x8B, 0x3C, 0xF8, 0x42, 0x01, 0x5A, + 0x1C, 0x62, 0x44, 0x86, 0x6B, 0x69, 0x46, 0x40, 0x87, 0x1E, 0x06, 0x02, 0x84, 0x88, 0x33, 0x14, + 0xF3, 0x57, 0x00, 0x6D, 0x09, 0x10, 0xC0, 0x09, 0x29, 0x2E, 0xE1, 0x80, 0x6B, 0x6A, 0xC4, 0x80, + 0x90, 0x66, 0x80, 0x69, 0xA6, 0xC0, 0x03, 0x0E, 0xD6, 0x28, 0x02, 0x04, 0x0C, 0x28, 0xC2, 0xE2, + 0x0A, 0x1C, 0xF9, 0xE0, 0xCE, 0x3E, 0x05, 0x94, 0xE6, 0x00, 0x02, 0x11, 0x68, 0x21, 0xA4, 0x0C, + 0x35, 0xB1, 0x11, 0x94, 0x49, 0x09, 0x35, 0xF0, 0x24, 0x0E, 0x48, 0x35, 0x61, 0x4A, 0x93, 0x29, + 0x4C, 0x69, 0xC4, 0x01, 0x42, 0x30, 0x70, 0x25, 0x1E, 0x20, 0x26, 0x44, 0x40, 0x94, 0x0C, 0x38, + 0xC4, 0x44, 0x13, 0x99, 0x1C, 0x10, 0x9B, 0x98, 0x34, 0x98, 0xC0, 0x4E, 0x9B, 0x56, 0x74, 0x54, + 0x08, 0x3B, 0x99, 0xB8, 0xF0, 0x48, 0x13, 0x4D, 0x88, 0x45, 0x27, 0x12, 0x0A, 0x99, 0x83, 0x8A, + 0x40, 0x73, 0xBE, 0x60, 0x57, 0x13, 0xA1, 0x0D, 0xFA, 0xD2, 0x6C, 0x93, 0x91, 0x10, 0x02, 0x00, + 0x21, 0xF9, 0x04, 0x09, 0x0A, 0x00, 0x00, 0x00, 0x2C, 0x00, 0x00, 0x17, 0x00, 0x6A, 0x00, 0x32, + 0x00, 0x00, 0x05, 0xFF, 0x20, 0x20, 0x8E, 0x64, 0x69, 0x9E, 0x68, 0xAA, 0x8A, 0x85, 0x02, 0xAD, + 0x70, 0x2C, 0xCF, 0x74, 0x5D, 0x26, 0x0C, 0x63, 0xD8, 0x7C, 0xEF, 0xFF, 0xA2, 0x05, 0x21, 0x80, + 0x58, 0x2C, 0x70, 0x0B, 0xA0, 0x72, 0xC9, 0x64, 0x34, 0x0C, 0x89, 0x86, 0x42, 0xC8, 0xAC, 0x5A, + 0x6B, 0x54, 0x46, 0x81, 0x11, 0x70, 0x5E, 0xBF, 0x60, 0x94, 0xA2, 0xB0, 0x40, 0x10, 0x00, 0x86, + 0x73, 0x23, 0x71, 0x08, 0xBB, 0xAF, 0x90, 0x73, 0xE2, 0x11, 0x28, 0x97, 0x1B, 0xBA, 0xB7, 0x7E, + 0xA9, 0x68, 0x04, 0x0A, 0x01, 0x01, 0x04, 0x39, 0x01, 0x50, 0x7B, 0x87, 0x3E, 0x0B, 0x5C, 0x81, + 0x5D, 0x0F, 0x03, 0x01, 0x78, 0x69, 0x05, 0x88, 0x94, 0x33, 0x0C, 0x8F, 0x8C, 0x0B, 0x81, 0x5A, + 0x08, 0x06, 0x2D, 0x3F, 0x0A, 0x0A, 0x33, 0x0B, 0x63, 0x0D, 0x49, 0x95, 0x26, 0x2D, 0x8C, 0xAB, + 0x05, 0x04, 0x7E, 0x0D, 0x67, 0x3C, 0x10, 0x09, 0x0A, 0x0C, 0x26, 0x10, 0x0E, 0x83, 0x05, 0x07, + 0x0B, 0x69, 0x0F, 0xB4, 0x0E, 0x0F, 0x9D, 0xA8, 0x24, 0x06, 0x08, 0xAB, 0xC8, 0x81, 0xA1, 0x3C, + 0x07, 0x0E, 0x6B, 0x6D, 0x25, 0x06, 0x11, 0x11, 0x12, 0x13, 0x13, 0x0F, 0x11, 0x80, 0xAC, 0xC2, + 0xD0, 0xA8, 0x65, 0x01, 0x98, 0xC9, 0x10, 0x66, 0x0E, 0x93, 0x32, 0x07, 0x38, 0x02, 0x0C, 0xB4, + 0xA2, 0x25, 0x07, 0x08, 0x13, 0x12, 0xF2, 0x13, 0x06, 0x7F, 0x07, 0xDB, 0xED, 0x95, 0xDF, 0xE1, + 0xC9, 0x63, 0x71, 0xDD, 0x29, 0x8E, 0xB8, 0x12, 0xA0, 0x2E, 0x94, 0x03, 0x14, 0xB0, 0xE4, 0x55, + 0x53, 0x80, 0x40, 0x01, 0xB2, 0x01, 0xB9, 0x4E, 0x21, 0x3A, 0x30, 0x64, 0x00, 0xBF, 0x64, 0x0B, + 0x1E, 0x48, 0x3C, 0x41, 0x2A, 0x0A, 0xC1, 0x8F, 0x05, 0x8A, 0x04, 0x74, 0x10, 0x4F, 0x42, 0x84, + 0x07, 0x0E, 0x93, 0xFF, 0x35, 0x40, 0x60, 0xEE, 0x90, 0x14, 0x70, 0x17, 0x91, 0x29, 0x48, 0x80, + 0x62, 0xC1, 0x16, 0x05, 0x1F, 0x73, 0x12, 0x9C, 0xB9, 0xA2, 0x40, 0x04, 0x04, 0x09, 0x82, 0x6A, + 0x4B, 0xC6, 0x80, 0x80, 0x81, 0x17, 0x7A, 0x0A, 0xD4, 0xB3, 0x18, 0x33, 0x10, 0x84, 0x5F, 0x6C, + 0x48, 0xB4, 0x1A, 0xA8, 0x53, 0x67, 0x82, 0x1D, 0x2B, 0x84, 0x2C, 0x4A, 0xB6, 0xEA, 0xC0, 0x4C, + 0x1C, 0xA6, 0x20, 0x20, 0xB5, 0x32, 0x05, 0x66, 0xD3, 0x40, 0x07, 0xA0, 0xD8, 0x12, 0xD1, 0xE0, + 0x41, 0x83, 0xAA, 0x55, 0x61, 0x31, 0xC8, 0xA7, 0x82, 0xA1, 0x83, 0x7A, 0x5C, 0x19, 0x41, 0x48, + 0xDB, 0x22, 0x47, 0xD0, 0xA3, 0x4C, 0x52, 0x32, 0x3D, 0x0B, 0x0E, 0x01, 0x34, 0x03, 0x6E, 0xE1, + 0xC2, 0xC5, 0x43, 0x57, 0x05, 0x04, 0x28, 0x04, 0x1C, 0x38, 0xB9, 0x97, 0x17, 0xD9, 0x81, 0x02, + 0x7F, 0xC7, 0xF6, 0x48, 0x10, 0x68, 0x80, 0x00, 0x8B, 0x95, 0x73, 0x8D, 0x38, 0xB0, 0xEE, 0xAD, + 0xE2, 0x8F, 0x0A, 0x08, 0x00, 0x94, 0x01, 0xA1, 0x17, 0x66, 0x02, 0xB0, 0x71, 0x84, 0x52, 0x9A, + 0x97, 0xB4, 0xEA, 0x1F, 0x07, 0xC1, 0x11, 0x24, 0xDC, 0xC0, 0xC1, 0x18, 0x00, 0xA4, 0x10, 0x30, + 0x38, 0x8D, 0xDA, 0xF0, 0x92, 0x05, 0x69, 0x0F, 0xA4, 0x55, 0xE0, 0x40, 0x32, 0xDE, 0xAE, 0xE5, + 0x7A, 0xE0, 0x02, 0xD0, 0x79, 0x77, 0x65, 0x70, 0xB0, 0x09, 0x14, 0x20, 0xFE, 0x51, 0xFB, 0xC6, + 0x2F, 0x8F, 0x85, 0x42, 0x40, 0x86, 0xF9, 0x7B, 0x0C, 0x5C, 0x8C, 0x3C, 0x7F, 0x26, 0xDC, 0x85, + 0xC0, 0x83, 0x41, 0xA6, 0x4F, 0x6B, 0x41, 0x04, 0xA1, 0xD5, 0x73, 0xB4, 0xDA, 0x35, 0xAB, 0xB8, + 0x8C, 0x23, 0xBD, 0xF5, 0xEB, 0x30, 0x41, 0xD0, 0xD6, 0x69, 0x6B, 0x34, 0x80, 0x0A, 0x04, 0xEB, + 0xA8, 0x14, 0x85, 0xFF, 0x7E, 0x41, 0x60, 0xE6, 0x40, 0x02, 0x05, 0x48, 0xE1, 0x47, 0x75, 0xBB, + 0xB1, 0xC7, 0xC8, 0x4A, 0xC4, 0xCD, 0x47, 0x0C, 0x2C, 0x31, 0x85, 0x64, 0x46, 0x64, 0x09, 0x20, + 0xF0, 0xC0, 0x2F, 0xF7, 0x39, 0xA0, 0x89, 0x7F, 0xEB, 0x01, 0x18, 0x88, 0x5A, 0xF1, 0xE5, 0xC4, + 0x40, 0x74, 0xC4, 0x00, 0xD0, 0x8C, 0x85, 0x03, 0x18, 0xD0, 0x21, 0x02, 0xD4, 0xA1, 0x98, 0xA2, + 0x8A, 0x10, 0x28, 0xF0, 0x00, 0x5C, 0x08, 0x30, 0xA8, 0x8F, 0x33, 0x2A, 0x5A, 0x46, 0x40, 0x02, + 0x27, 0xEA, 0xF8, 0x99, 0x8A, 0x88, 0x39, 0xA3, 0x13, 0x66, 0x34, 0xC5, 0x48, 0xC2, 0x2C, 0x29, + 0x15, 0x79, 0x9D, 0x7A, 0x15, 0xAA, 0xB8, 0x80, 0x6F, 0x39, 0xA1, 0x64, 0x9E, 0x94, 0x00, 0xF4, + 0x67, 0x65, 0x5E, 0x4C, 0x65, 0x79, 0x9D, 0x4D, 0x0E, 0x20, 0x20, 0xE2, 0x16, 0xCD, 0x09, 0x09, + 0x26, 0x00, 0x84, 0x8C, 0xC9, 0xD5, 0x60, 0xA0, 0x9D, 0x89, 0xC0, 0x84, 0x88, 0xDD, 0xF6, 0x66, + 0x0A, 0xCC, 0xC9, 0x79, 0x25, 0x7B, 0xE8, 0x34, 0xB4, 0x4A, 0x30, 0x06, 0xEE, 0x29, 0xC6, 0x03, + 0xF7, 0xF9, 0x69, 0xE5, 0x63, 0x04, 0xC4, 0x84, 0x98, 0x48, 0x86, 0x9A, 0x40, 0xD1, 0x56, 0x8A, + 0x56, 0x66, 0x40, 0x03, 0x52, 0xB0, 0x94, 0xE8, 0xA0, 0x1A, 0x45, 0x7A, 0x42, 0x01, 0xBE, 0x51, + 0x56, 0x29, 0x57, 0x97, 0x1A, 0x20, 0x6A, 0x65, 0x2B, 0x61, 0xE5, 0xA9, 0x3B, 0x09, 0x10, 0x50, + 0xE5, 0xA8, 0xA3, 0x0E, 0xA0, 0xDD, 0xAA, 0x27, 0x20, 0xA8, 0x1A, 0xAC, 0xB8, 0x0E, 0x42, 0xEB, + 0x09, 0x14, 0xBD, 0x3A, 0xA6, 0x08, 0xB8, 0x16, 0xE5, 0xE6, 0xAA, 0xAD, 0x9C, 0xCA, 0x55, 0x0C, + 0x8A, 0x32, 0xF4, 0x25, 0xAD, 0x47, 0xF8, 0xBA, 0xCA, 0x0C, 0x7E, 0x0E, 0xD0, 0x56, 0x4B, 0xBB, + 0x4A, 0x75, 0x6B, 0x8F, 0x32, 0x34, 0x44, 0x2B, 0x00, 0x6C, 0xAB, 0x55, 0xAB, 0xD5, 0xB1, 0x32, + 0xC8, 0xC9, 0x14, 0x24, 0xC3, 0x54, 0x5B, 0x02, 0x2C, 0x9B, 0x86, 0xFB, 0x27, 0x26, 0x1F, 0x3D, + 0x52, 0x00, 0xB5, 0xE6, 0x8A, 0xD0, 0xE3, 0x25, 0xC8, 0x20, 0x4B, 0xE6, 0x23, 0x59, 0xAE, 0xF7, + 0x8E, 0xAA, 0xF1, 0x92, 0x30, 0xA9, 0xB1, 0x29, 0xA0, 0x9A, 0x80, 0x6F, 0x7D, 0x98, 0x9A, 0x56, + 0xA6, 0x0F, 0xC0, 0xDB, 0x2F, 0x09, 0x3E, 0x3A, 0x60, 0x6C, 0x00, 0x23, 0x5C, 0xD9, 0x9B, 0x9A, + 0x0E, 0x4C, 0x33, 0x8D, 0x30, 0x47, 0x16, 0x30, 0xEC, 0xC2, 0xC0, 0xF9, 0x68, 0xD4, 0x75, 0xA4, + 0x6D, 0xA2, 0xE6, 0x91, 0x06, 0x9C, 0xF2, 0x8E, 0xC5, 0x51, 0x2C, 0xCB, 0x71, 0x09, 0x8C, 0x0E, + 0x92, 0xA8, 0x57, 0x27, 0xA9, 0xF9, 0xCB, 0x97, 0x19, 0xC5, 0xCC, 0xD2, 0xCA, 0x33, 0x78, 0x35, + 0xF0, 0x8B, 0xB9, 0xE8, 0x52, 0xF2, 0x02, 0x1B, 0x93, 0xA2, 0x32, 0xCE, 0x30, 0xB4, 0x36, 0xB4, + 0x0D, 0x21, 0x00, 0x00, 0x3B}; diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Reuse_Session/Send_Reuse_Session.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Reuse_Session/Send_Reuse_Session.ino index ed7d61396..c266b7d5b 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Reuse_Session/Send_Reuse_Session.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Reuse_Session/Send_Reuse_Session.ino @@ -1,242 +1,242 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example show how to login once for sending multiple messages. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -SMTPSession smtp; - -Session_Config config; - -void smtpCallback(SMTP_Status status); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -#include "HeapStat.h" -HeapStat heapInfo; - -unsigned long sentMillis = 0; - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - MailClient.networkReconnect(true); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - smtp.debug(1); - - smtp.callback(smtpCallback); - - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; -} - -void loop() -{ - if (millis() - sentMillis > 3 * 60 * 1000 || sentMillis == 0) - { - sentMillis = millis(); - - SMTP_Message message; - - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - message.subject = F("Send Email with session reusage"); - message.addRecipient(F("user"), RECIPIENT_EMAIL); - - message.html.content = F("

This is the HTML message.

"); - message.text.content = F("This is the text message"); - - Serial.println(); - Serial.println("Sending Email..."); - - if (!smtp.isLoggedIn()) - { - /* Set the TCP response read timeout in seconds */ - // smtp.setTCPTimeout(10); - - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - goto exit; - } - - if (!smtp.isLoggedIn()) - { - Serial.println("\nError, Not yet logged in."); - goto exit; - } - else - { - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - } - } - - if (!MailClient.sendMail(&smtp, &message, false)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - exit: - - heapInfo.collect(); - heapInfo.print(); - } -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - - Serial.println(status.info()); - - if (status.success()) - { - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - SMTP_Result result = smtp.sendingResult.getItem(i); - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - smtp.sendingResult.clear(); - } +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example show how to login once for sending multiple messages. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +SMTPSession smtp; + +Session_Config config; + +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +#include "HeapStat.h" +HeapStat heapInfo; + +unsigned long sentMillis = 0; + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + MailClient.networkReconnect(true); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + smtp.debug(1); + + smtp.callback(smtpCallback); + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; +} + +void loop() +{ + if (millis() - sentMillis > 3 * 60 * 1000 || sentMillis == 0) + { + sentMillis = millis(); + + SMTP_Message message; + + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Send Email with session reusage"); + message.addRecipient(F("user"), RECIPIENT_EMAIL); + + message.html.content = F("

This is the HTML message.

"); + message.text.content = F("This is the text message"); + + Serial.println(); + Serial.println("Sending Email..."); + + if (!smtp.isLoggedIn()) + { + /* Set the TCP response read timeout in seconds */ + // smtp.setTCPTimeout(10); + + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + goto exit; + } + + if (!smtp.isLoggedIn()) + { + Serial.println("\nError, Not yet logged in."); + goto exit; + } + else + { + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + } + + if (!MailClient.sendMail(&smtp, &message, false)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + exit: + + heapInfo.collect(); + heapInfo.print(); + } +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + + Serial.println(status.info()); + + if (status.success()) + { + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + smtp.sendingResult.clear(); + } } \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text _Silent_Mode/Send_Text_Silent_Mode.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text _Silent_Mode/Send_Text_Silent_Mode.ino index 2fa30a753..1c466144d 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text _Silent_Mode/Send_Text_Silent_Mode.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text _Silent_Mode/Send_Text_Silent_Mode.ino @@ -1,197 +1,197 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example showes how to send text message without callback and debug. - -/** - * To use library in silent mode (no debug printing and callback), please define this macro in src/ESP_Mail_FS.h. - * #define SILENT_MODE - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -#define SMTP_HOST "" - -#define SMTP_PORT esp_mail_smtp_port_587 - -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" -#define RECIPIENT_EMAIL "" - -SMTPSession smtp; - -void printSmtpData(SMTP_Status status); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - MailClient.networkReconnect(true); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - Session_Config config; - - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - SMTP_Message message; - - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - message.subject = F("Test sending plain text Email"); - message.addRecipient(F("Someone"), RECIPIENT_EMAIL); - - String textMsg = "This is simple plain text message"; - message.text.content = textMsg; - - message.text.charSet = F("us-ascii"); - - message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - message.addHeader(F("Message-ID: ")); - - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (!smtp.isLoggedIn()) - { - Serial.println("Not yet logged in."); - } - else - { - if (smtp.isAuthenticated()) - Serial.println("Successfully logged in."); - else - Serial.println("Connected with no Auth."); - } - - if (MailClient.sendMail(&smtp, &message)) - { - printSmtpData(smtp.status()); - } - else - { - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - } - - smtp.sendingResult.clear(); -} - -void loop() -{ -} - -void printSmtpData(SMTP_Status status) -{ - - if (status.success()) - { - - Serial.println("\n----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - - SMTP_Result result = smtp.sendingResult.getItem(i); - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - smtp.sendingResult.clear(); - } -} + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example showes how to send text message without callback and debug. + +/** + * To use library in silent mode (no debug printing and callback), please define this macro in src/ESP_Mail_FS.h. + * #define SILENT_MODE + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define SMTP_HOST "" + +#define SMTP_PORT esp_mail_smtp_port_587 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" +#define RECIPIENT_EMAIL "" + +SMTPSession smtp; + +void printSmtpData(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + MailClient.networkReconnect(true); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + Session_Config config; + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + SMTP_Message message; + + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + String textMsg = "This is simple plain text message"; + message.text.content = textMsg; + + message.text.charSet = F("us-ascii"); + + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + message.addHeader(F("Message-ID: ")); + + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (!smtp.isLoggedIn()) + { + Serial.println("Not yet logged in."); + } + else + { + if (smtp.isAuthenticated()) + Serial.println("Successfully logged in."); + else + Serial.println("Connected with no Auth."); + } + + if (MailClient.sendMail(&smtp, &message)) + { + printSmtpData(smtp.status()); + } + else + { + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + } + + smtp.sendingResult.clear(); +} + +void loop() +{ +} + +void printSmtpData(SMTP_Status status) +{ + + if (status.success()) + { + + Serial.println("\n----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text/Send_Text.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text/Send_Text.ino index ea9beee08..7e3b203b7 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text/Send_Text.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text/Send_Text.ino @@ -1,396 +1,396 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt - */ - -// This example showes how to send text message. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 // port 465 is not available for Outlook.com - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -// const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" -// "-----END CERTIFICATE-----\n"; - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /** If non-secure port is prefered (not allow SSL and TLS connection), use - * config.secure.mode = esp_mail_secure_mode_nonsecure; - * - * If SSL and TLS are always required, use - * config.secure.mode = esp_mail_secure_mode_ssl_tls; - * - * To disable SSL permanently (use less program space), define ESP_MAIL_DISABLE_SSL in ESP_Mail_FS.h - * or Custom_ESP_Mail_FS.h - */ - // config.secure.mode = esp_mail_secure_mode_nonsecure; - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /* The full message sending logs can now save to file */ - /* Since v3.0.4, the sent logs stored in smtp.sendingResult will store only the latest message logs */ - // config.sentLogs.filename = "/path/to/log/file"; - // config.sentLogs.storage_type = esp_mail_file_storage_type_flash; - - /** In ESP32, timezone environment will not keep after wake up boot from sleep. - * The local time will equal to GMT time. - * - * To sync or set time with NTP server with the valid local time after wake up boot, - * set both gmt and day light offsets to 0 and assign the timezone environment string e.g. - - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 0; - config.time.day_light_offset = 0; - config.time.timezone_env_string = "JST-9"; // for Tokyo - - * The library will get (sync) the time from NTP server without GMT time offset adjustment - * and set the timezone environment variable later. - * - * This timezone environment string will be stored to flash or SD file named "/tze.txt" - * which set via config.time.timezone_file. - * - * See the timezone environment string list from - * https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv - * - */ - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - - /** If author and sender are not identical - message.sender.name = F("Sender"); - message.sender.email = "sender@mail.com"; - message.author.name = F("ESP Mail"); - message.author.email = AUTHOR_EMAIL; // should be the same email as config.login.email - */ - - message.subject = F("Test sending plain text Email"); - message.addRecipient(F("Someone"), RECIPIENT_EMAIL); - - String textMsg = "This is simple plain text message"; - message.text.content = textMsg; - - /** If the message to send is a large string, to reduce the memory used from internal copying while sending, - * you can assign string to message.text.blob by cast your string to uint8_t array like this - * - * String myBigString = "..... ......"; - * message.text.blob.data = (uint8_t *)myBigString.c_str(); - * message.text.blob.size = myBigString.length(); - * - * or assign string to message.text.nonCopyContent, like this - * - * message.text.nonCopyContent = myBigString.c_str(); - * - * Only base64 encoding is supported for content transfer encoding in this case. - */ - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.text.charSet = F("us-ascii"); - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - // If this is a reply message - // message.in_reply_to = ""; - // message.references = " "; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - // message.response.reply_to = "someone@somemail.com"; - // message.response.return_path = "someone@somemail.com"; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader(F("Message-ID: ")); - - // For Root CA certificate verification (ESP8266 and ESP32 only) - // config.certificate.cert_data = rootCACert; - // or - // config.certificate.cert_file = "/path/to/der/file"; - // config.certificate.cert_file_storage_type = esp_mail_file_storage_type_flash; // esp_mail_file_storage_type_sd - // config.certificate.verify = true; - - // The WiFiNINA firmware the Root CA certification can be added via the option in Firmware update tool in Arduino IDE - - /* Connect to server with the session config */ - - // Library will be trying to sync the time with NTP server if time is never sync or set. - // This is 10 seconds blocking process. - // If time reading was timed out, the error "NTP server time reading timed out" will show via debug and callback function. - // You can manually sync time by yourself with NTP library or calling configTime in ESP32 and ESP8266. - // Time can be set manually with provided timestamp to function smtp.setSystemTime. - - /* Set the TCP response read timeout in seconds */ - // smtp.setTCPTimeout(10); - - /* Connect to the server */ - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - /** Or connect without log in and log in later - - if (!smtp.connect(&config, false)) - return; - - if (!smtp.loginWithPassword(AUTHOR_EMAIL, AUTHOR_PASSWORD)) - return; - */ - - if (!smtp.isLoggedIn()) - { - Serial.println("\nNot yet logged in."); - } - else - { - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - } - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } -} + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +// This example showes how to send text message. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 // port 465 is not available for Outlook.com + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +// const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" +// "-----END CERTIFICATE-----\n"; + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /** If non-secure port is prefered (not allow SSL and TLS connection), use + * config.secure.mode = esp_mail_secure_mode_nonsecure; + * + * If SSL and TLS are always required, use + * config.secure.mode = esp_mail_secure_mode_ssl_tls; + * + * To disable SSL permanently (use less program space), define ESP_MAIL_DISABLE_SSL in ESP_Mail_FS.h + * or Custom_ESP_Mail_FS.h + */ + // config.secure.mode = esp_mail_secure_mode_nonsecure; + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* The full message sending logs can now save to file */ + /* Since v3.0.4, the sent logs stored in smtp.sendingResult will store only the latest message logs */ + // config.sentLogs.filename = "/path/to/log/file"; + // config.sentLogs.storage_type = esp_mail_file_storage_type_flash; + + /** In ESP32, timezone environment will not keep after wake up boot from sleep. + * The local time will equal to GMT time. + * + * To sync or set time with NTP server with the valid local time after wake up boot, + * set both gmt and day light offsets to 0 and assign the timezone environment string e.g. + + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 0; + config.time.day_light_offset = 0; + config.time.timezone_env_string = "JST-9"; // for Tokyo + + * The library will get (sync) the time from NTP server without GMT time offset adjustment + * and set the timezone environment variable later. + * + * This timezone environment string will be stored to flash or SD file named "/tze.txt" + * which set via config.time.timezone_file. + * + * See the timezone environment string list from + * https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv + * + */ + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + + /** If author and sender are not identical + message.sender.name = F("Sender"); + message.sender.email = "sender@mail.com"; + message.author.name = F("ESP Mail"); + message.author.email = AUTHOR_EMAIL; // should be the same email as config.login.email + */ + + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + String textMsg = "This is simple plain text message"; + message.text.content = textMsg; + + /** If the message to send is a large string, to reduce the memory used from internal copying while sending, + * you can assign string to message.text.blob by cast your string to uint8_t array like this + * + * String myBigString = "..... ......"; + * message.text.blob.data = (uint8_t *)myBigString.c_str(); + * message.text.blob.size = myBigString.length(); + * + * or assign string to message.text.nonCopyContent, like this + * + * message.text.nonCopyContent = myBigString.c_str(); + * + * Only base64 encoding is supported for content transfer encoding in this case. + */ + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + // If this is a reply message + // message.in_reply_to = ""; + // message.references = " "; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + // message.response.reply_to = "someone@somemail.com"; + // message.response.return_path = "someone@somemail.com"; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + // For Root CA certificate verification (ESP8266 and ESP32 only) + // config.certificate.cert_data = rootCACert; + // or + // config.certificate.cert_file = "/path/to/der/file"; + // config.certificate.cert_file_storage_type = esp_mail_file_storage_type_flash; // esp_mail_file_storage_type_sd + // config.certificate.verify = true; + + // The WiFiNINA firmware the Root CA certification can be added via the option in Firmware update tool in Arduino IDE + + /* Connect to server with the session config */ + + // Library will be trying to sync the time with NTP server if time is never sync or set. + // This is 10 seconds blocking process. + // If time reading was timed out, the error "NTP server time reading timed out" will show via debug and callback function. + // You can manually sync time by yourself with NTP library or calling configTime in ESP32 and ESP8266. + // Time can be set manually with provided timestamp to function smtp.setSystemTime. + + /* Set the TCP response read timeout in seconds */ + // smtp.setTCPTimeout(10); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + /** Or connect without log in and log in later + + if (!smtp.connect(&config, false)) + return; + + if (!smtp.loginWithPassword(AUTHOR_EMAIL, AUTHOR_PASSWORD)) + return; + */ + + if (!smtp.isLoggedIn()) + { + Serial.println("\nNot yet logged in."); + } + else + { + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text_Flowed/Send_Text_Flowed.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text_Flowed/Send_Text_Flowed.ino index badb2b5a6..01ddfde7e 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text_Flowed/Send_Text_Flowed.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Send_Text_Flowed/Send_Text_Flowed.ino @@ -1,308 +1,308 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt -*/ - -// This example shows how to send text message with text wrapping. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, the app password will be used for log in - * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - -#if defined(ARDUINO_ARCH_SAMD) - while (!Serial) - ; -#endif - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /* Set the network reconnection option */ - MailClient.networkReconnect(true); - - // The WiFi credentials are required for Pico W - // due to it does not have reconnect feature. -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - /** Assign your host name or you public IPv4 or IPv6 only - * as this is the part of EHLO/HELO command to identify the client system - * to prevent connection rejection. - * If host name or public IP is not available, ignore this or - * use loopback address "127.0.0.1". - * - * Assign any text to this option may cause the connection rejection. - */ - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 3; - config.time.day_light_offset = 0; - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - message.subject = F("Test sending plain text Email"); - message.addRecipient(F("Someone"), RECIPIENT_EMAIL); - - /** The option to add soft line break to to the message for - * the long text message > 78 characters (rfc 3676) - * Some Servers may not compliant with this standard. - */ - message.text.flowed = true; - - /** if the option message.text.flowed is true, - * the following plain text message will be wrapped. - */ - message.text.content = F("The text below is the long quoted text which breaks into several lines.\r\n\r\n>> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\r\n\r\nThis is the normal short text.\r\n\r\nAnother long text, abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz."); - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.text.charSet = F("us-ascii"); - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader(F("Message-ID: ")); - - /* Connect to the server */ - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (!smtp.isLoggedIn()) - { - Serial.println("\nNot yet logged in."); - } - else - { - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - } - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } -} + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt +*/ + +// This example shows how to send text message with text wrapping. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, the app password will be used for log in + * Check out https://github.com/mobizt/ESP-Mail-Client#gmail-smtp-and-imap-required-app-passwords-to-sign-in + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + +#if defined(ARDUINO_ARCH_SAMD) + while (!Serial) + ; +#endif + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /* Set the network reconnection option */ + MailClient.networkReconnect(true); + + // The WiFi credentials are required for Pico W + // due to it does not have reconnect feature. +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + /** Assign your host name or you public IPv4 or IPv6 only + * as this is the part of EHLO/HELO command to identify the client system + * to prevent connection rejection. + * If host name or public IP is not available, ignore this or + * use loopback address "127.0.0.1". + * + * Assign any text to this option may cause the connection rejection. + */ + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 3; + config.time.day_light_offset = 0; + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + /** The option to add soft line break to to the message for + * the long text message > 78 characters (rfc 3676) + * Some Servers may not compliant with this standard. + */ + message.text.flowed = true; + + /** if the option message.text.flowed is true, + * the following plain text message will be wrapped. + */ + message.text.content = F("The text below is the long quoted text which breaks into several lines.\r\n\r\n>> Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.\r\n\r\nThis is the normal short text.\r\n\r\nAnother long text, abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz abcdefg hijklmnop qrstuv wxyz."); + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (!smtp.isLoggedIn()) + { + Serial.println("\nNot yet logged in."); + } + else + { + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Set_Time/Set_Time.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Set_Time/Set_Time.ino index fcf96414f..7f07fd9ae 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Set_Time/Set_Time.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Set_Time/Set_Time.ino @@ -1,253 +1,253 @@ - -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt - */ - -// This example showes how to set the library and/or device time manually. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#include "RTC.h" -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -#define SMTP_HOST "" -#define SMTP_PORT esp_mail_smtp_port_587 - -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" -#define RECIPIENT_EMAIL "" - -SMTPSession smtp; - -void smtpCallback(SMTP_Status status); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) -WiFiMulti multi; -#endif - -void setup() -{ - - Serial.begin(115200); - - Serial.println(); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - multi.addAP(WIFI_SSID, WIFI_PASSWORD); - multi.run(); -#else - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); -#endif - - Serial.print("Connecting to Wi-Fi"); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - unsigned long ms = millis(); -#endif - - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(300); -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - if (millis() - ms > 10000) - break; -#endif - } - Serial.println(); - Serial.print("Connected with IP: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - Serial.print("Waiting for NTP server time reading"); - -#if defined(ESP8266) || defined(ESP32) && !defined(ARDUINO_NANO_RP2040_CONNECT) - - configTime(0, 0, "pool.ntp.org", "time.nist.gov"); - while (time(nullptr) < ESP_MAIL_CLIENT_VALID_TS) - { - delay(100); - } - -#elif defined(ARDUINO_RASPBERRY_PI_PICO_W) - - configTime(10000, 0, "pool.ntp.org", "time.nist.gov"); - while (time(nullptr) < ESP_MAIL_CLIENT_VALID_TS) - { - delay(100); - } - -#elif __has_include() || __has_include() - time_t ts = 0; - do - { - ts = WiFi.getTime(); - delay(100); - } while (ts < ESP_MAIL_CLIENT_VALID_TS); - - float gmtOffset = 3.0; // GMT offset in hour - - smtp.setSystemTime(ts, gmtOffset); - -#elif __has_include() - - // see https://docs.arduino.cc/tutorials/uno-r4-wifi/rtc - - RTC.begin(); - - // RTCTime startTime(30, Month::JUNE, 2023, 13, 37, 00, DayOfWeek::WEDNESDAY, SaveLight::SAVING_TIME_ACTIVE); - // RTC.setTime(startTime); - - RTCTime currentTime; - - // Get current time from RTC - RTC.getTime(currentTime); - - float gmtOffset = 3.0; // GMT offset in hour - smtp.setSystemTime(currentTime.getUnixTime(), gmtOffset); - -#endif - - // To disable library internal NTP time reading, please comment or remove the following macro defined in src/ESP_Mail_FS.h - // #define ENABLE_NTP_TIME - - MailClient.networkReconnect(true); - -#if defined(ARDUINO_RASPBERRY_PI_PICO_W) - MailClient.clearAP(); - MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); -#endif - - smtp.debug(1); - - smtp.callback(smtpCallback); - - Session_Config config; - - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - - config.login.user_domain = F("127.0.0.1"); - - /** - * Once the system time (using smtp.setSystemTime) or device time was set before calling smtp.connect, the following config will - * not take effect when NTP time is enabled. - * - * config.time.ntp_server - * config.time.gmt_offset - * config.time.day_light_offset - * - * To reset the reference time and use config.time instead, call smtp.setSystemTime(0) whenever you want. - */ - - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); - message.sender.email = AUTHOR_EMAIL; - message.addRecipient(F("Someone"), RECIPIENT_EMAIL); - - /* The time format of timestamp to inject into subject or content as using in strftime C++ function */ - message.timestamp.tag = "#esp_mail_current_time"; - - /* The tag that will be replaced with current timestamp */ - message.timestamp.format = "%B %d, %Y %H:%M:%S"; - - message.subject = F("Test sending plain text Email (#esp_mail_current_time)"); - - message.text.content = "This is simple plain text message\n\nSent #esp_mail_current_time"; - - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - if (!smtp.isLoggedIn()) - { - Serial.println("\nNot yet logged in."); - } - else - { - if (smtp.isAuthenticated()) - Serial.println("\nSuccessfully logged in."); - else - Serial.println("\nConnected with no Auth."); - } - - if (!MailClient.sendMail(&smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); -} - -void loop() -{ -} - -void smtpCallback(SMTP_Status status) -{ - Serial.println(status.info()); - - if (status.success()) - { - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - - SMTP_Result result = smtp.sendingResult.getItem(i); - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - smtp.sendingResult.clear(); - } -} + +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +// This example showes how to set the library and/or device time manually. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#include "RTC.h" +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +#define SMTP_HOST "" +#define SMTP_PORT esp_mail_smtp_port_587 + +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" +#define RECIPIENT_EMAIL "" + +SMTPSession smtp; + +void smtpCallback(SMTP_Status status); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) +WiFiMulti multi; +#endif + +void setup() +{ + + Serial.begin(115200); + + Serial.println(); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + multi.addAP(WIFI_SSID, WIFI_PASSWORD); + multi.run(); +#else + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); +#endif + + Serial.print("Connecting to Wi-Fi"); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + unsigned long ms = millis(); +#endif + + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(300); +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + if (millis() - ms > 10000) + break; +#endif + } + Serial.println(); + Serial.print("Connected with IP: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + Serial.print("Waiting for NTP server time reading"); + +#if defined(ESP8266) || defined(ESP32) && !defined(ARDUINO_NANO_RP2040_CONNECT) + + configTime(0, 0, "pool.ntp.org", "time.nist.gov"); + while (time(nullptr) < ESP_MAIL_CLIENT_VALID_TS) + { + delay(100); + } + +#elif defined(ARDUINO_RASPBERRY_PI_PICO_W) + + configTime(10000, 0, "pool.ntp.org", "time.nist.gov"); + while (time(nullptr) < ESP_MAIL_CLIENT_VALID_TS) + { + delay(100); + } + +#elif __has_include() || __has_include() + time_t ts = 0; + do + { + ts = WiFi.getTime(); + delay(100); + } while (ts < ESP_MAIL_CLIENT_VALID_TS); + + float gmtOffset = 3.0; // GMT offset in hour + + smtp.setSystemTime(ts, gmtOffset); + +#elif __has_include() + + // see https://docs.arduino.cc/tutorials/uno-r4-wifi/rtc + + RTC.begin(); + + // RTCTime startTime(30, Month::JUNE, 2023, 13, 37, 00, DayOfWeek::WEDNESDAY, SaveLight::SAVING_TIME_ACTIVE); + // RTC.setTime(startTime); + + RTCTime currentTime; + + // Get current time from RTC + RTC.getTime(currentTime); + + float gmtOffset = 3.0; // GMT offset in hour + smtp.setSystemTime(currentTime.getUnixTime(), gmtOffset); + +#endif + + // To disable library internal NTP time reading, please comment or remove the following macro defined in src/ESP_Mail_FS.h + // #define ENABLE_NTP_TIME + + MailClient.networkReconnect(true); + +#if defined(ARDUINO_RASPBERRY_PI_PICO_W) + MailClient.clearAP(); + MailClient.addAP(WIFI_SSID, WIFI_PASSWORD); +#endif + + smtp.debug(1); + + smtp.callback(smtpCallback); + + Session_Config config; + + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + + config.login.user_domain = F("127.0.0.1"); + + /** + * Once the system time (using smtp.setSystemTime) or device time was set before calling smtp.connect, the following config will + * not take effect when NTP time is enabled. + * + * config.time.ntp_server + * config.time.gmt_offset + * config.time.day_light_offset + * + * To reset the reference time and use config.time instead, call smtp.setSystemTime(0) whenever you want. + */ + + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); + message.sender.email = AUTHOR_EMAIL; + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); + + /* The time format of timestamp to inject into subject or content as using in strftime C++ function */ + message.timestamp.tag = "#esp_mail_current_time"; + + /* The tag that will be replaced with current timestamp */ + message.timestamp.format = "%B %d, %Y %H:%M:%S"; + + message.subject = F("Test sending plain text Email (#esp_mail_current_time)"); + + message.text.content = "This is simple plain text message\n\nSent #esp_mail_current_time"; + + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + if (!smtp.isLoggedIn()) + { + Serial.println("\nNot yet logged in."); + } + else + { + if (smtp.isAuthenticated()) + Serial.println("\nSuccessfully logged in."); + else + Serial.println("\nConnected with no Auth."); + } + + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); +} + +void loop() +{ +} + +void smtpCallback(SMTP_Status status) +{ + Serial.println(status.info()); + + if (status.success()) + { + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + + SMTP_Result result = smtp.sendingResult.getItem(i); + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Sleep/Sleep.ino b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Sleep/Sleep.ino index 2902423aa..84868a46d 100644 --- a/lib/libesp32/ESP-Mail-Client/examples/SMTP/Sleep/Sleep.ino +++ b/lib/libesp32/ESP-Mail-Client/examples/SMTP/Sleep/Sleep.ino @@ -1,310 +1,310 @@ -/** - * Created by K. Suwatchai (Mobizt) - * - * Email: suwatchai@outlook.com - * - * Github: https://github.com/mobizt/ESP-Mail-Client - * - * Copyright (c) 2023 mobizt - */ - -// This example showes how the device time was resume after device woke up from sleep. - -/** Note for library update from v2.x.x to v3.x.x. - * - * Struct data names changed - * - * "ESP_Mail_Session" changes to "Session_Config" - * "IMAP_Config" changes to "IMAP_Data" - * - * Changes in the examples - * - * ESP_Mail_Session session; - * to - * Session_Config config; - * - * IMAP_Config config; - * to - * IMAP_Data imap_data; - */ - -#include -#if defined(ESP32) -#include -#else - -// Other Client defined here -// To use custom Client, define ENABLE_CUSTOM_CLIENT in src/ESP_Mail_FS.h. -// See the example Custom_Client.ino for how to use. - -#endif - -#include - -#define WIFI_SSID "" -#define WIFI_PASSWORD "" - -/** For Gmail, to send Email via port 465 (SSL), less secure app option - * should be enabled in the account settings. https://myaccount.google.com/lesssecureapps?pli=1 - * - * Some Gmail user still not able to sign in using account password even above option was set up, - * for this case, use "App Password" to sign in instead. - * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en - * - * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to - * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc - * - * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password - * and AUTHOR_EMAIL with your account email. - */ - -/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ -#define SMTP_HOST "" - -/** The smtp port e.g. - * 25 or esp_mail_smtp_port_25 - * 465 or esp_mail_smtp_port_465 - * 587 or esp_mail_smtp_port_587 - */ -#define SMTP_PORT esp_mail_smtp_port_587 // port 465 is not available for Outlook.com - -/* The log in credentials */ -#define AUTHOR_EMAIL "" -#define AUTHOR_PASSWORD "" - -/* Recipient email address */ -#define RECIPIENT_EMAIL "" - -/* Declare the global used SMTPSession object for SMTP transport */ -SMTPSession smtp; - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status); - -const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" - "-----END CERTIFICATE-----\n"; - -void sendEmail() -{ - /* Declare the Session_Config for user defined session credentials */ - Session_Config config; - - /* Set the session config */ - config.server.host_name = SMTP_HOST; - config.server.port = SMTP_PORT; - config.login.email = AUTHOR_EMAIL; - config.login.password = AUTHOR_PASSWORD; - config.login.user_domain = F("127.0.0.1"); - - /* - Set the NTP config time - For times east of the Prime Meridian use 0-12 - For times west of the Prime Meridian add 12 to the offset. - Ex. American/Denver GMT would be -6. 6 + 12 = 18 - See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets - */ - config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); - config.time.gmt_offset = 0; - config.time.day_light_offset = 0; - config.time.timezone_env_string = "JST-9"; // for Tokyo - - // See the timezone environment string list from https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv - - /* Declare the message class */ - SMTP_Message message; - - /* Set the message headers */ - message.sender.name = F("ESP Mail"); // This witll be used with 'MAIL FROM' command and 'From' header field. - message.sender.email = AUTHOR_EMAIL; // This witll be used with 'From' header field. - message.subject = F("Test sending plain text Email"); - message.addRecipient(F("Someone"), RECIPIENT_EMAIL); // This will be used with RCPT TO command and 'To' header field. - - String textMsg = "This is simple plain text message"; - message.text.content = textMsg; - - /** If the message to send is a large string, to reduce the memory used from internal copying while sending, - * you can assign string to message.text.blob by cast your string to uint8_t array like this - * - * String myBigString = "..... ......"; - * message.text.blob.data = (uint8_t *)myBigString.c_str(); - * message.text.blob.size = myBigString.length(); - * - * or assign string to message.text.nonCopyContent, like this - * - * message.text.nonCopyContent = myBigString.c_str(); - * - * Only base64 encoding is supported for content transfer encoding in this case. - */ - - /** The Plain text message character set e.g. - * us-ascii - * utf-8 - * utf-7 - * The default value is utf-8 - */ - message.text.charSet = F("us-ascii"); - - /** The content transfer encoding e.g. - * enc_7bit or "7bit" (not encoded) - * enc_qp or "quoted-printable" (encoded) - * enc_base64 or "base64" (encoded) - * enc_binary or "binary" (not encoded) - * enc_8bit or "8bit" (not encoded) - * The default value is "7bit" - */ - message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; - - // If this is a reply message - // message.in_reply_to = ""; - // message.references = " "; - - /** The message priority - * esp_mail_smtp_priority_high or 1 - * esp_mail_smtp_priority_normal or 3 - * esp_mail_smtp_priority_low or 5 - * The default value is esp_mail_smtp_priority_low - */ - message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; - - // message.response.reply_to = "someone@somemail.com"; - // message.response.return_path = "someone@somemail.com"; - - /** The Delivery Status Notifications e.g. - * esp_mail_smtp_notify_never - * esp_mail_smtp_notify_success - * esp_mail_smtp_notify_failure - * esp_mail_smtp_notify_delay - * The default value is esp_mail_smtp_notify_never - */ - // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; - - /* Set the custom message header */ - message.addHeader(F("Message-ID: ")); - - // For Root CA certificate verification (ESP8266 and ESP32 only) - // config.certificate.cert_data = rootCACert; - // or - // config.certificate.cert_file = "/path/to/der/file"; - // config.certificate.cert_file_storage_type = esp_mail_file_storage_type_flash; // esp_mail_file_storage_type_sd - // config.certificate.verify = true; - - // The WiFiNINA firmware the Root CA certification can be added via the option in Firmware update tool in Arduino IDE - - /* Connect to server with the session config */ - - // Library will be trying to sync the time with NTP server if time is never sync or set. - // This is 10 seconds blocking process. - // If time reading was timed out, the error "NTP server time reading timed out" will show via debug and callback function. - // You can manually sync time by yourself with NTP library or calling configTime in ESP32 and ESP8266. - // Time can be set manually with provided timestamp to function smtp.setSystemTime. - - /* Connect to the server */ - if (!smtp.connect(&config)) - { - MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - return; - } - - /* Start sending Email and close the session */ - if (!MailClient.sendMail(&smtp, &message)) - MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); - - // to clear sending result log - // smtp.sendingResult.clear(); - - MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); -} - -void setup() -{ - - Serial.begin(115200); - - Serial.println(); - - Serial.print("Connecting to AP"); - - WiFi.begin(WIFI_SSID, WIFI_PASSWORD); - while (WiFi.status() != WL_CONNECTED) - { - Serial.print("."); - delay(200); - } - - Serial.println(""); - Serial.println("WiFi connected."); - Serial.println("IP address: "); - Serial.println(WiFi.localIP()); - Serial.println(); - - /** Enable the debug via Serial port - * 0 for no debugging - * 1 for basic level debugging - * - * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h - */ - smtp.debug(1); - - /* Set the callback function to get the sending results */ - smtp.callback(smtpCallback); - - sendEmail(); - - // Sleep for 60 seconds - - Serial.println("Going to sleep for 60 seconds..."); - -#if defined(ESP32) - - esp_sleep_enable_timer_wakeup(60 * 1000000); - - esp_deep_sleep_start(); - -#endif -} - -void loop() -{ -} - -/* Callback function to get the Email sending status */ -void smtpCallback(SMTP_Status status) -{ - /* Print the current status */ - Serial.println(status.info()); - - /* Print the sending result */ - if (status.success()) - { - // MailClient.printf used in the examples is for format printing via debug Serial port - // that works for all supported Arduino platform SDKs e.g. AVR, SAMD, ESP32 and ESP8266. - // In ESP8266 and ESP32, you can use Serial.printf directly. - - Serial.println("----------------"); - MailClient.printf("Message sent success: %d\n", status.completedCount()); - MailClient.printf("Message sent failed: %d\n", status.failedCount()); - Serial.println("----------------\n"); - struct tm dt; - - for (size_t i = 0; i < smtp.sendingResult.size(); i++) - { - /* Get the result item */ - SMTP_Result result = smtp.sendingResult.getItem(i); - - // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if - // your device time was synched with NTP server. - // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. - // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) - - MailClient.printf("Message No: %d\n", i + 1); - MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); - MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); - MailClient.printf("Recipient: %s\n", result.recipients.c_str()); - MailClient.printf("Subject: %s\n", result.subject.c_str()); - } - Serial.println("----------------\n"); - - // You need to clear sending result as the memory usage will grow up. - smtp.sendingResult.clear(); - } -} +/** + * Created by K. Suwatchai (Mobizt) + * + * Email: suwatchai@outlook.com + * + * Github: https://github.com/mobizt/ESP-Mail-Client + * + * Copyright (c) 2023 mobizt + */ + +// This example showes how the device time was resume after device woke up from sleep. + +/** Note for library update from v2.x.x to v3.x.x. + * + * Struct data names changed + * + * "ESP_Mail_Session" changes to "Session_Config" + * "IMAP_Config" changes to "IMAP_Data" + * + * Changes in the examples + * + * ESP_Mail_Session session; + * to + * Session_Config config; + * + * IMAP_Config config; + * to + * IMAP_Data imap_data; + */ + +#include +#if defined(ESP32) +#include +#else + +// Other Client defined here +// To use custom Client, define ENABLE_CUSTOM_CLIENT in src/ESP_Mail_FS.h. +// See the example Custom_Client.ino for how to use. + +#endif + +#include + +#define WIFI_SSID "" +#define WIFI_PASSWORD "" + +/** For Gmail, to send Email via port 465 (SSL), less secure app option + * should be enabled in the account settings. https://myaccount.google.com/lesssecureapps?pli=1 + * + * Some Gmail user still not able to sign in using account password even above option was set up, + * for this case, use "App Password" to sign in instead. + * About Gmail "App Password", go to https://support.google.com/accounts/answer/185833?hl=en + * + * For Yahoo mail, log in to your yahoo mail in web browser and generate app password by go to + * https://login.yahoo.com/account/security/app-passwords/add/confirm?src=noSrc + * + * To use Gmai and Yahoo's App Password to sign in, define the AUTHOR_PASSWORD with your App Password + * and AUTHOR_EMAIL with your account email. + */ + +/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */ +#define SMTP_HOST "" + +/** The smtp port e.g. + * 25 or esp_mail_smtp_port_25 + * 465 or esp_mail_smtp_port_465 + * 587 or esp_mail_smtp_port_587 + */ +#define SMTP_PORT esp_mail_smtp_port_587 // port 465 is not available for Outlook.com + +/* The log in credentials */ +#define AUTHOR_EMAIL "" +#define AUTHOR_PASSWORD "" + +/* Recipient email address */ +#define RECIPIENT_EMAIL "" + +/* Declare the global used SMTPSession object for SMTP transport */ +SMTPSession smtp; + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status); + +const char rootCACert[] PROGMEM = "-----BEGIN CERTIFICATE-----\n" + "-----END CERTIFICATE-----\n"; + +void sendEmail() +{ + /* Declare the Session_Config for user defined session credentials */ + Session_Config config; + + /* Set the session config */ + config.server.host_name = SMTP_HOST; + config.server.port = SMTP_PORT; + config.login.email = AUTHOR_EMAIL; + config.login.password = AUTHOR_PASSWORD; + config.login.user_domain = F("127.0.0.1"); + + /* + Set the NTP config time + For times east of the Prime Meridian use 0-12 + For times west of the Prime Meridian add 12 to the offset. + Ex. American/Denver GMT would be -6. 6 + 12 = 18 + See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets + */ + config.time.ntp_server = F("pool.ntp.org,time.nist.gov"); + config.time.gmt_offset = 0; + config.time.day_light_offset = 0; + config.time.timezone_env_string = "JST-9"; // for Tokyo + + // See the timezone environment string list from https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv + + /* Declare the message class */ + SMTP_Message message; + + /* Set the message headers */ + message.sender.name = F("ESP Mail"); // This witll be used with 'MAIL FROM' command and 'From' header field. + message.sender.email = AUTHOR_EMAIL; // This witll be used with 'From' header field. + message.subject = F("Test sending plain text Email"); + message.addRecipient(F("Someone"), RECIPIENT_EMAIL); // This will be used with RCPT TO command and 'To' header field. + + String textMsg = "This is simple plain text message"; + message.text.content = textMsg; + + /** If the message to send is a large string, to reduce the memory used from internal copying while sending, + * you can assign string to message.text.blob by cast your string to uint8_t array like this + * + * String myBigString = "..... ......"; + * message.text.blob.data = (uint8_t *)myBigString.c_str(); + * message.text.blob.size = myBigString.length(); + * + * or assign string to message.text.nonCopyContent, like this + * + * message.text.nonCopyContent = myBigString.c_str(); + * + * Only base64 encoding is supported for content transfer encoding in this case. + */ + + /** The Plain text message character set e.g. + * us-ascii + * utf-8 + * utf-7 + * The default value is utf-8 + */ + message.text.charSet = F("us-ascii"); + + /** The content transfer encoding e.g. + * enc_7bit or "7bit" (not encoded) + * enc_qp or "quoted-printable" (encoded) + * enc_base64 or "base64" (encoded) + * enc_binary or "binary" (not encoded) + * enc_8bit or "8bit" (not encoded) + * The default value is "7bit" + */ + message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit; + + // If this is a reply message + // message.in_reply_to = ""; + // message.references = " "; + + /** The message priority + * esp_mail_smtp_priority_high or 1 + * esp_mail_smtp_priority_normal or 3 + * esp_mail_smtp_priority_low or 5 + * The default value is esp_mail_smtp_priority_low + */ + message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low; + + // message.response.reply_to = "someone@somemail.com"; + // message.response.return_path = "someone@somemail.com"; + + /** The Delivery Status Notifications e.g. + * esp_mail_smtp_notify_never + * esp_mail_smtp_notify_success + * esp_mail_smtp_notify_failure + * esp_mail_smtp_notify_delay + * The default value is esp_mail_smtp_notify_never + */ + // message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay; + + /* Set the custom message header */ + message.addHeader(F("Message-ID: ")); + + // For Root CA certificate verification (ESP8266 and ESP32 only) + // config.certificate.cert_data = rootCACert; + // or + // config.certificate.cert_file = "/path/to/der/file"; + // config.certificate.cert_file_storage_type = esp_mail_file_storage_type_flash; // esp_mail_file_storage_type_sd + // config.certificate.verify = true; + + // The WiFiNINA firmware the Root CA certification can be added via the option in Firmware update tool in Arduino IDE + + /* Connect to server with the session config */ + + // Library will be trying to sync the time with NTP server if time is never sync or set. + // This is 10 seconds blocking process. + // If time reading was timed out, the error "NTP server time reading timed out" will show via debug and callback function. + // You can manually sync time by yourself with NTP library or calling configTime in ESP32 and ESP8266. + // Time can be set manually with provided timestamp to function smtp.setSystemTime. + + /* Connect to the server */ + if (!smtp.connect(&config)) + { + MailClient.printf("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + return; + } + + /* Start sending Email and close the session */ + if (!MailClient.sendMail(&smtp, &message)) + MailClient.printf("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str()); + + // to clear sending result log + // smtp.sendingResult.clear(); + + MailClient.printf("Free Heap: %d\n", MailClient.getFreeHeap()); +} + +void setup() +{ + + Serial.begin(115200); + + Serial.println(); + + Serial.print("Connecting to AP"); + + WiFi.begin(WIFI_SSID, WIFI_PASSWORD); + while (WiFi.status() != WL_CONNECTED) + { + Serial.print("."); + delay(200); + } + + Serial.println(""); + Serial.println("WiFi connected."); + Serial.println("IP address: "); + Serial.println(WiFi.localIP()); + Serial.println(); + + /** Enable the debug via Serial port + * 0 for no debugging + * 1 for basic level debugging + * + * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h + */ + smtp.debug(1); + + /* Set the callback function to get the sending results */ + smtp.callback(smtpCallback); + + sendEmail(); + + // Sleep for 60 seconds + + Serial.println("Going to sleep for 60 seconds..."); + +#if defined(ESP32) + + esp_sleep_enable_timer_wakeup(60 * 1000000); + + esp_deep_sleep_start(); + +#endif +} + +void loop() +{ +} + +/* Callback function to get the Email sending status */ +void smtpCallback(SMTP_Status status) +{ + /* Print the current status */ + Serial.println(status.info()); + + /* Print the sending result */ + if (status.success()) + { + // MailClient.printf used in the examples is for format printing via debug Serial port + // that works for all supported Arduino platform SDKs e.g. AVR, SAMD, ESP32 and ESP8266. + // In ESP8266 and ESP32, you can use Serial.printf directly. + + Serial.println("----------------"); + MailClient.printf("Message sent success: %d\n", status.completedCount()); + MailClient.printf("Message sent failed: %d\n", status.failedCount()); + Serial.println("----------------\n"); + struct tm dt; + + for (size_t i = 0; i < smtp.sendingResult.size(); i++) + { + /* Get the result item */ + SMTP_Result result = smtp.sendingResult.getItem(i); + + // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if + // your device time was synched with NTP server. + // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970. + // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970) + + MailClient.printf("Message No: %d\n", i + 1); + MailClient.printf("Status: %s\n", result.completed ? "success" : "failed"); + MailClient.printf("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str()); + MailClient.printf("Recipient: %s\n", result.recipients.c_str()); + MailClient.printf("Subject: %s\n", result.subject.c_str()); + } + Serial.println("----------------\n"); + + // You need to clear sending result as the memory usage will grow up. + smtp.sendingResult.clear(); + } +} diff --git a/lib/libesp32/ESP-Mail-Client/keywords.txt b/lib/libesp32/ESP-Mail-Client/keywords.txt index 86c058045..377e10fb0 100644 --- a/lib/libesp32/ESP-Mail-Client/keywords.txt +++ b/lib/libesp32/ESP-Mail-Client/keywords.txt @@ -1,194 +1,194 @@ -###################################### -# Syntax Coloring Map ESP Mail Client -###################################### - -####################################### -# Classes and Structured Type (KEYWORD1) -####################################### - -MailClient KEYWORD1 -IMAPSession KEYWORD1 -SMTPSession KEYWORD1 -SMTP_Message KEYWORD1 -IMAP_Config KEYWORD1 -IMAP_Data KEYWORD2 -FoldersCollection KEYWORD1 -imapStatusCallback KEYWORD1 -IMAP_MSG_List KEYWORD1 -SelectedFolderInfo KEYWORD1 -ESP_Mail_Session KEYWORD1 -Session_Config KEYWORD1 -smtpStatusCallback KEYWORD1 -imapResponseCallback KEYWORD1 -SMTP_Attachment KEYWORD1 -SMTP_Result KEYWORD1 -IMAP_MSG_Item KEYWORD1 -Content_Transfer_Encoding KEYWORD1 -MessageList KEYWORD1 - -############################################### -# Methods and Functions (KEYWORD2) -############################################### - -sendMail KEYWORD2 -appendMessage KEYWORD2 -readMail KEYWORD2 -setFlag KEYWORD2 -addFlag KEYWORD2 -removeFlag KEYWORD2 -networkReconnect KEYWORD2 -sdBegin KEYWORD2 -sdMMCBegin KEYWORD2 -getFreeHeap KEYWORD2 -connect KEYWORD2 -loginWithPassword KEYWORD2 -loginWithAccessToken KEYWORD2 -isAuthenticated KEYWORD2 -isLoggedIn KEYWORD2 -connected KEYWORD2 -keepAlive KEYWORD2 -isKeepAlive KEYWORD2 -customConnect KEYWORD2 -closeSession KEYWORD2 -debug KEYWORD2 -getFolders KEYWORD2 -selectFolder KEYWORD2 -openFolder KEYWORD2 -closeFolder KEYWORD2 -callback KEYWORD2 -headerOnly KEYWORD2 -data KEYWORD2 -selectedFolder KEYWORD2 -errorReason KEYWORD2 -statusCode KEYWORD2 -statusMessage KEYWORD2 -errorCode KEYWORD2 -empty KEYWORD2 -resetAttachItem KEYWORD2 -clear KEYWORD2 -clearInlineimages KEYWORD2 -clearAttachments KEYWORD2 -clearRFC822Messages KEYWORD2 -clearRecipients KEYWORD2 -clearCc KEYWORD2 -clearBcc KEYWORD2 -clearHeader KEYWORD2 -addAttachment KEYWORD2 -addParallelAttachment KEYWORD2 -addInlineImage KEYWORD2 -addMessage KEYWORD2 -addRecipient KEYWORD2 -addCc KEYWORD2 -addBcc KEYWORD2 -addHeader KEYWORD2 -info KEYWORD2 -successs KEYWORD2 -completedCount KEYWORD2 -failedCount KEYWORD2 -getItem KEYWORD2 -size KEYWORD2 -flagCount KEYWORD2 -msgCount KEYWORD2 -recentCount KEYWORD2 -nextUID KEYWORD2 -pollingStatus KEYWORD2 -searchCount KEYWORD2 -availableMessages KEYWORD2 -flag KEYWORD2 -setClock KEYWORD2 -getUnixTime KEYWORD2 -getTimestamp KEYWORD2 -getYear KEYWORD2 -getMonth KEYWORD2 -getDay KEYWORD2 -getDayOfWeek KEYWORD2 -getDayOfWeekString KEYWORD2 -getHour KEYWORD2 -getMin KEYWORD2 -getSecond KEYWORD2 -getNumberOfDayThisYear KEYWORD2 -getTotalDays KEYWORD2 -dayofWeek KEYWORD2 -getCurrentSecond KEYWORD2 -getCurrentTimestamp KEYWORD2 -getTimeFromSec KEYWORD2 -getDateTimeString KEYWORD2 -copyMessages KEYWORD2 -moveMessages KEYWORD2 -deleteMessages KEYWORD2 -getQuota KEYWORD2 -setQuota KEYWORD2 -getQuotaRoot KEYWORD2 -getACL KEYWORD2 -setACL KEYWORD2 -deleteACL KEYWORD2 -myRights KEYWORD2 -enable KEYWORD2 -getNamespace KEYWORD2 -createFolder KEYWORD2 -renameFolder KEYWORD2 -getSubscribesMailboxes KEYWORD2 -subscribe KEYWORD2 -unSubscribe KEYWORD2 -deleteFolder KEYWORD2 -listen KEYWORD2 -stopListen KEYWORD2 -folderChanged KEYWORD2 -sendCustomCommand KEYWORD2 -sendCustomData KEYWORD2 -toBase64 KEYWORD2 -getFlags KEYWORD2 -getUID KEYWORD2 -setTCPTimeout KEYWORD2 -setClient KEYWORD2 -setGSMClient KEYWORD2 -connectionRequestCallback KEYWORD2 -connectionUpgradeRequestCallback KEYWORD2 -networkConnectionRequestCallback KEYWORD2 -networkDisconnectionRequestCallback KEYWORD2 -networkStatusRequestCallback KEYWORD2 -setSystemTime KEYWORD2 -mimeDataStreamCallback KEYWORD2 -characterDecodingCallback KEYWORD2 -clearAP KEYWORD2 -addAP KEYWORD2 -isFirmwareUpdated KEYWORD2 -id KEYWORD2 -serverID KEYWORD2 -fileList KEYWORD2 -status KEYWORD2 - -####################################### -# Struct (KEYWORD3) -####################################### - -esp_mail_email_info_t KEYWORD3 -esp_mail_plain_body_t KEYWORD3 -esp_mail_html_body_t KEYWORD3 -esp_mail_smtp_msg_response_t KEYWORD3 -esp_mail_smtp_enable_option_t KEYWORD3 -esp_mail_email_info_t KEYWORD3 -esp_mail_folder_info_item_t KEYWORD3 -esp_mail_sesson_sever_config_t KEYWORD3 -esp_mail_sesson_login_config_t KEYWORD3 -esp_mail_sesson_secure_config_t KEYWORD3 -esp_mail_sesson_cert_config_t KEYWORD3 -esp_mail_imap_fetch_config_t KEYWORD3 -esp_mail_imap_search_config_t KEYWORD3 -esp_mail_imap_limit_config_t KEYWORD3 -esp_mail_imap_enable_config_t KEYWORD3 -esp_mail_imap_download_config_t KEYWORD3 -esp_mail_imap_storage_config_t KEYWORD3 -esp_mail_imap_polling_status_t KEYWORD3 -IMAP_Polling_Status KEYWORD3 -IMAP_Identification KEYWORD3 - -esp_mail_file_storage_type_none KEYWORD3 -esp_mail_file_storage_type_flash KEYWORD3 -esp_mail_file_storage_type_sd KEYWORD3 - -###################################### -# Constants (LITERAL1) -####################################### - +###################################### +# Syntax Coloring Map ESP Mail Client +###################################### + +####################################### +# Classes and Structured Type (KEYWORD1) +####################################### + +MailClient KEYWORD1 +IMAPSession KEYWORD1 +SMTPSession KEYWORD1 +SMTP_Message KEYWORD1 +IMAP_Config KEYWORD1 +IMAP_Data KEYWORD2 +FoldersCollection KEYWORD1 +imapStatusCallback KEYWORD1 +IMAP_MSG_List KEYWORD1 +SelectedFolderInfo KEYWORD1 +ESP_Mail_Session KEYWORD1 +Session_Config KEYWORD1 +smtpStatusCallback KEYWORD1 +imapResponseCallback KEYWORD1 +SMTP_Attachment KEYWORD1 +SMTP_Result KEYWORD1 +IMAP_MSG_Item KEYWORD1 +Content_Transfer_Encoding KEYWORD1 +MessageList KEYWORD1 + +############################################### +# Methods and Functions (KEYWORD2) +############################################### + +sendMail KEYWORD2 +appendMessage KEYWORD2 +readMail KEYWORD2 +setFlag KEYWORD2 +addFlag KEYWORD2 +removeFlag KEYWORD2 +networkReconnect KEYWORD2 +sdBegin KEYWORD2 +sdMMCBegin KEYWORD2 +getFreeHeap KEYWORD2 +connect KEYWORD2 +loginWithPassword KEYWORD2 +loginWithAccessToken KEYWORD2 +isAuthenticated KEYWORD2 +isLoggedIn KEYWORD2 +connected KEYWORD2 +keepAlive KEYWORD2 +isKeepAlive KEYWORD2 +customConnect KEYWORD2 +closeSession KEYWORD2 +debug KEYWORD2 +getFolders KEYWORD2 +selectFolder KEYWORD2 +openFolder KEYWORD2 +closeFolder KEYWORD2 +callback KEYWORD2 +headerOnly KEYWORD2 +data KEYWORD2 +selectedFolder KEYWORD2 +errorReason KEYWORD2 +statusCode KEYWORD2 +statusMessage KEYWORD2 +errorCode KEYWORD2 +empty KEYWORD2 +resetAttachItem KEYWORD2 +clear KEYWORD2 +clearInlineimages KEYWORD2 +clearAttachments KEYWORD2 +clearRFC822Messages KEYWORD2 +clearRecipients KEYWORD2 +clearCc KEYWORD2 +clearBcc KEYWORD2 +clearHeader KEYWORD2 +addAttachment KEYWORD2 +addParallelAttachment KEYWORD2 +addInlineImage KEYWORD2 +addMessage KEYWORD2 +addRecipient KEYWORD2 +addCc KEYWORD2 +addBcc KEYWORD2 +addHeader KEYWORD2 +info KEYWORD2 +successs KEYWORD2 +completedCount KEYWORD2 +failedCount KEYWORD2 +getItem KEYWORD2 +size KEYWORD2 +flagCount KEYWORD2 +msgCount KEYWORD2 +recentCount KEYWORD2 +nextUID KEYWORD2 +pollingStatus KEYWORD2 +searchCount KEYWORD2 +availableMessages KEYWORD2 +flag KEYWORD2 +setClock KEYWORD2 +getUnixTime KEYWORD2 +getTimestamp KEYWORD2 +getYear KEYWORD2 +getMonth KEYWORD2 +getDay KEYWORD2 +getDayOfWeek KEYWORD2 +getDayOfWeekString KEYWORD2 +getHour KEYWORD2 +getMin KEYWORD2 +getSecond KEYWORD2 +getNumberOfDayThisYear KEYWORD2 +getTotalDays KEYWORD2 +dayofWeek KEYWORD2 +getCurrentSecond KEYWORD2 +getCurrentTimestamp KEYWORD2 +getTimeFromSec KEYWORD2 +getDateTimeString KEYWORD2 +copyMessages KEYWORD2 +moveMessages KEYWORD2 +deleteMessages KEYWORD2 +getQuota KEYWORD2 +setQuota KEYWORD2 +getQuotaRoot KEYWORD2 +getACL KEYWORD2 +setACL KEYWORD2 +deleteACL KEYWORD2 +myRights KEYWORD2 +enable KEYWORD2 +getNamespace KEYWORD2 +createFolder KEYWORD2 +renameFolder KEYWORD2 +getSubscribesMailboxes KEYWORD2 +subscribe KEYWORD2 +unSubscribe KEYWORD2 +deleteFolder KEYWORD2 +listen KEYWORD2 +stopListen KEYWORD2 +folderChanged KEYWORD2 +sendCustomCommand KEYWORD2 +sendCustomData KEYWORD2 +toBase64 KEYWORD2 +getFlags KEYWORD2 +getUID KEYWORD2 +setTCPTimeout KEYWORD2 +setClient KEYWORD2 +setGSMClient KEYWORD2 +connectionRequestCallback KEYWORD2 +connectionUpgradeRequestCallback KEYWORD2 +networkConnectionRequestCallback KEYWORD2 +networkDisconnectionRequestCallback KEYWORD2 +networkStatusRequestCallback KEYWORD2 +setSystemTime KEYWORD2 +mimeDataStreamCallback KEYWORD2 +characterDecodingCallback KEYWORD2 +clearAP KEYWORD2 +addAP KEYWORD2 +isFirmwareUpdated KEYWORD2 +id KEYWORD2 +serverID KEYWORD2 +fileList KEYWORD2 +status KEYWORD2 + +####################################### +# Struct (KEYWORD3) +####################################### + +esp_mail_email_info_t KEYWORD3 +esp_mail_plain_body_t KEYWORD3 +esp_mail_html_body_t KEYWORD3 +esp_mail_smtp_msg_response_t KEYWORD3 +esp_mail_smtp_enable_option_t KEYWORD3 +esp_mail_email_info_t KEYWORD3 +esp_mail_folder_info_item_t KEYWORD3 +esp_mail_sesson_sever_config_t KEYWORD3 +esp_mail_sesson_login_config_t KEYWORD3 +esp_mail_sesson_secure_config_t KEYWORD3 +esp_mail_sesson_cert_config_t KEYWORD3 +esp_mail_imap_fetch_config_t KEYWORD3 +esp_mail_imap_search_config_t KEYWORD3 +esp_mail_imap_limit_config_t KEYWORD3 +esp_mail_imap_enable_config_t KEYWORD3 +esp_mail_imap_download_config_t KEYWORD3 +esp_mail_imap_storage_config_t KEYWORD3 +esp_mail_imap_polling_status_t KEYWORD3 +IMAP_Polling_Status KEYWORD3 +IMAP_Identification KEYWORD3 + +esp_mail_file_storage_type_none KEYWORD3 +esp_mail_file_storage_type_flash KEYWORD3 +esp_mail_file_storage_type_sd KEYWORD3 + +###################################### +# Constants (LITERAL1) +####################################### + ESP_MAIL_PRINTF LITERAL1 \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/library.json b/lib/libesp32/ESP-Mail-Client/library.json index 6f1953984..c6a36c895 100644 --- a/lib/libesp32/ESP-Mail-Client/library.json +++ b/lib/libesp32/ESP-Mail-Client/library.json @@ -1,16 +1,16 @@ -{ - "name": "ESP Mail Client", - "version": "3.4.9", - "keywords": "communication, email, imap, smtp, esp32, esp8266, samd, arduino", - "description": "Arduino E-Mail Client Library to send, read and get incoming email notification for ESP32, ESP8266 and SAMD21 devices. The library also supported other Arduino Devices using Clients interfaces e.g. WiFiClient, EthernetClient, and GSMClient.", - "repository": { - "type": "git", - "url": "https://github.com/mobizt/ESP-Mail-Client.git" - }, - "authors": [{ - "name": "Mobizt", - "email": "suwatchai@outlook.com" - }], - "frameworks": "arduino", - "platforms": "espressif32, espressif8266, atmelsam, atmelavr, atmelmegaavr, ststm32, teensy, rp2040" -} +{ + "name": "ESP Mail Client", + "version": "3.4.9", + "keywords": "communication, email, imap, smtp, esp32, esp8266, samd, arduino", + "description": "Arduino E-Mail Client Library to send, read and get incoming email notification for ESP32, ESP8266 and SAMD21 devices. The library also supported other Arduino Devices using Clients interfaces e.g. WiFiClient, EthernetClient, and GSMClient.", + "repository": { + "type": "git", + "url": "https://github.com/mobizt/ESP-Mail-Client.git" + }, + "authors": [{ + "name": "Mobizt", + "email": "suwatchai@outlook.com" + }], + "frameworks": "arduino", + "platforms": "espressif32, espressif8266, atmelsam, atmelavr, atmelmegaavr, ststm32, teensy, rp2040" +} diff --git a/lib/libesp32/ESP-Mail-Client/library.properties b/lib/libesp32/ESP-Mail-Client/library.properties index 80b2d2c7e..64d6ab1ad 100644 --- a/lib/libesp32/ESP-Mail-Client/library.properties +++ b/lib/libesp32/ESP-Mail-Client/library.properties @@ -1,17 +1,17 @@ -name=ESP Mail Client - -version=3.4.9 - -author=Mobizt - -maintainer=Mobizt - -sentence=Arduino E-Mail Client Library to send, read and get incoming email notification for ESP32, ESP8266 and SAMD21 devices. - -paragraph=The library also supported other Arduino devices using Clients interfaces e.g. WiFiClient, EthernetClient, and GSMClient. - -category=Communication - -url=https://github.com/mobizt/ESP-Mail-Client - -architectures=esp8266,esp32,sam,samd,stm32,STM32F1,STM32F4,teensy,avr,megaavr,mbed_nano,mbed_rp2040,rp2040 +name=ESP Mail Client + +version=3.4.9 + +author=Mobizt + +maintainer=Mobizt + +sentence=Arduino E-Mail Client Library to send, read and get incoming email notification for ESP32, ESP8266 and SAMD21 devices. + +paragraph=The library also supported other Arduino devices using Clients interfaces e.g. WiFiClient, EthernetClient, and GSMClient. + +category=Communication + +url=https://github.com/mobizt/ESP-Mail-Client + +architectures=esp8266,esp32,sam,samd,stm32,STM32F1,STM32F4,teensy,avr,megaavr,mbed_nano,mbed_rp2040,rp2040 diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client.cpp b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client.cpp index 4c58543a2..dd10ceac2 100644 --- a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client.cpp +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client.cpp @@ -1,1933 +1,1933 @@ -#ifndef ESP_MAIL_CLIENT_CPP -#define ESP_MAIL_CLIENT_CPP - -#pragma GCC diagnostic ignored "-Wunused-but-set-variable" - -#include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30409) -#error "Mixed versions compilation." -#endif - -/** - * Mail Client Arduino Library for Arduino devices. - * - * Created August 28, 2023 - * - * This library allows Espressif's ESP32, ESP8266, SAMD and RP2040 Pico devices to send and read Email through the SMTP and IMAP servers. - * - * The MIT License (MIT) - * Copyright (c) 2023 K. Suwatchai (Mobizt) - * - * - * 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 "ESP_Mail_Client.h" -#include "ESP_Mail_Client_Version.h" - -#include "ESP_Mail_IMAP.h" -#include "ESP_Mail_SMTP.h" - -void ESP_Mail_Client::networkReconnect(bool reconnect) -{ -#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) && (defined(ESP32) || defined(ESP8266)) - WiFi.setAutoReconnect(reconnect); -#endif - networkAutoReconnect = reconnect; -} - -void ESP_Mail_Client::printf(const char *format, ...) -{ - int size = 2048; - char s[size]; - va_list va; - va_start(va, format); - vsnprintf(s, size, format, va); - va_end(va); - ESP_MAIL_DEFAULT_DEBUG_PORT.print(s); -} - -void ESP_Mail_Client::addAP(const String &ssid, const String &password) -{ - wifi.addAP(ssid, password); -} - -void ESP_Mail_Client::clearAP() -{ - wifi.clearAP(); -} - -#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) - -bool ESP_Mail_Client::sdBegin(int8_t ss, int8_t sck, int8_t miso, int8_t mosi, uint32_t frequency) -{ - return mbfs->sdBegin(ss, sck, miso, mosi, frequency); -} - -#if defined(ESP8266) || defined(MB_ARDUINO_PICO) -bool ESP_Mail_Client::sdBegin(SDFSConfig *sdFSConfig) -{ - return mbfs->sdFatBegin(sdFSConfig); -} -#endif - -#if defined(ESP32) -bool ESP_Mail_Client::sdBegin(int8_t ss, SPIClass *spiConfig, uint32_t frequency) -{ - return mbfs->sdSPIBegin(ss, spiConfig, frequency); -} -#endif - -#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) -bool ESP_Mail_Client::sdBegin(SdSpiConfig *sdFatSPIConfig, int8_t ss, int8_t sck, int8_t miso, int8_t mosi) -{ - return mbfs->sdFatBegin(sdFatSPIConfig, ss, sck, miso, mosi); -} - -bool ESP_Mail_Client::sdBegin(SdioConfig *sdFatSDIOConfig) -{ - return mbfs->sdFatBegin(sdFatSDIOConfig); -} -#endif - -#endif - -#if defined(ESP32) && defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD_MMC) - -bool ESP_Mail_Client::sdMMCBegin(const char *mountpoint, bool mode1bit, bool format_if_mount_failed) -{ - return mbfs->sdMMCBegin(mountpoint, mode1bit, format_if_mount_failed); -} - -#endif - -int ESP_Mail_Client::getFreeHeap() -{ -#if defined(MB_ARDUINO_ESP) - return ESP.getFreeHeap(); -#elif defined(MB_ARDUINO_PICO) - return rp2040.getFreeHeap(); -#else - return 0; -#endif -} - -// All following functions are for IMAP or SMTP only -#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) - -void ESP_Mail_Client::resumeNetwork(ESP_Mail_TCPClient *client) -{ - client->networkReconnect(); -} - -template -bool ESP_Mail_Client::sessionExisted(T sessionPtr) -{ - -#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) - - Session_Config *config = sessionPtr->_session_cfg; - _vectorImpl *configPtrList = &(sessionPtr->_configPtrList); - - if (config) - { - int ptr = toAddr(*config); - for (size_t i = 0; i < configPtrList->size(); i++) - { - if ((*configPtrList)[i] == ptr) - return true; - } - - sessionPtr->closeSession(); - sessionPtr->_responseStatus.errorCode = MAIL_CLIENT_ERROR_SESSION_CONFIG_WAS_NOT_ASSIGNED; - sessionPtr->_responseStatus.text.clear(); - } - -#endif - return false; -} - -void ESP_Mail_Client::debugPrintNewLine() -{ -#if !defined(SILENT_MODE) - esp_mail_debug_print("", true); -#endif -} - -template -void ESP_Mail_Client::callBackSendNewLine(T sessionPtr, bool success) -{ -#if defined(SESSION_DEBUG_ENABLED) - sendCallback(sessionPtr, "", false, success); -#endif -} - -void ESP_Mail_Client::appendTagSpace(MB_String &buf, PGM_P tag) -{ - buf += (tag == NULL) ? esp_mail_imap_tag_str : tag; - appendSpace(buf); -} - -template -void ESP_Mail_Client::appendList(MB_String &buf, _vectorImpl &list) -{ - for (size_t i = 0; i < list.size(); i++) - { - if (i > 0) - buf += esp_mail_str_8; /* "," */ - buf += list[i]; - } -} - -void ESP_Mail_Client::appendSpace(MB_String &buf) -{ - buf += esp_mail_str_2 /* " " */; -} - -void ESP_Mail_Client::appendSpace(MB_String &buf, bool withTag, PGM_P value) -{ - if (withTag) - appendTagSpace(buf); - buf += value; - appendSpace(buf); -} - -void ESP_Mail_Client::appendSpace(MB_String &buf, bool withTag, int nunArgs, ...) -{ - if (withTag) - appendTagSpace(buf); - - va_list ap; - va_start(ap, nunArgs); - PGM_P p = va_arg(ap, PGM_P); - if (p) - buf += p; - for (int i = 2; i <= nunArgs; i++) - { - appendSpace(buf); - p = va_arg(ap, PGM_P); - if (p) - buf += p; - } - va_end(ap); - appendSpace(buf); -} - -void ESP_Mail_Client::prependSpace(MB_String &buf, PGM_P value) -{ - appendSpace(buf); - buf += value; -} - -void ESP_Mail_Client::appendDot(MB_String &buf) -{ - buf += esp_mail_str_27; /* "." */ -} - -void ESP_Mail_Client::prependDot(MB_String &buf, PGM_P value) -{ - buf += esp_mail_str_27; /* "." */ - buf += value; -} - -void ESP_Mail_Client::joinStringSpace(MB_String &buf, bool withTag, int nunArgs, ...) -{ - if (withTag) - appendTagSpace(buf); - - va_list ap; - va_start(ap, nunArgs); - PGM_P p = va_arg(ap, PGM_P); - if (p) - buf += p; - for (int i = 2; i <= nunArgs; i++) - { - appendSpace(buf); - p = va_arg(ap, PGM_P); - if (p) - buf += p; - } - va_end(ap); -} - -void ESP_Mail_Client::appendImap4KeyValue(MB_String &buf, PGM_P key, PGM_P value) -{ - buf += esp_mail_str_11; /* "\"" */ - buf += key; - buf += esp_mail_str_11; /* "\"" */ - appendSpace(buf); - buf += esp_mail_str_11; /* "\"" */ - buf += value; - buf += esp_mail_str_11; /* "\"" */ -} - -void ESP_Mail_Client::joinStringDot(MB_String &buf, int nunArgs, ...) -{ - va_list ap; - va_start(ap, nunArgs); - PGM_P p = va_arg(ap, PGM_P); - if (p) - buf += p; - for (int i = 2; i <= nunArgs; i++) - { - buf += esp_mail_str_27; /* "." */ - p = va_arg(ap, PGM_P); - if (p) - buf += p; - } - va_end(ap); -} - -template -void ESP_Mail_Client::sendCallback(T sessionPtr, PGM_P info, bool prependCRLF, bool success) -{ - -#if defined(SESSION_DEBUG_ENABLED) - - sessionPtr->_cbData._info.clear(); - - if (prependCRLF) - appendNewline(sessionPtr->_cbData._info); - if (strlen_P(info) > 0) - { - sessionPtr->_cbData._info += esp_mail_str_33; /* "#### " */ - sessionPtr->_cbData._info += info; - } - sessionPtr->_cbData._success = success; - if (sessionPtr->_statusCallback && !sessionPtr->_customCmdResCallback) - sessionPtr->_statusCallback(sessionPtr->_cbData); - -#endif -} - -template -void ESP_Mail_Client::printDebug(T sessionPtr, PGM_P cbMsg, PGM_P dbMsg, esp_mail_debug_tag_type type, bool prependCRLF, bool success) -{ -#if defined(SESSION_DEBUG_ENABLED) - - if (sessionPtr->_statusCallback != NULL && !isResponseCB(sessionPtr)) - sendCallback(sessionPtr, cbMsg, prependCRLF, success); - else if (sessionPtr->_debug) - debugPrintNewLine(); - - if (sessionPtr->_debug) - esp_mail_debug_print_tag(dbMsg, type, true); - -#endif -} - -void ESP_Mail_Client::printProgress(int progress, int &lastProgress) -{ -#if !defined(SILENT_MODE) - if (progress > 100) - progress = 100; - - if (lastProgress != progress && (progress == 0 || progress == 100 || lastProgress + ESP_MAIL_PROGRESS_REPORT_STEP <= progress)) - { - int len = 16; - int curTick = progress * len / 100; - int lastTick = lastProgress * len / 100; - - if (curTick > lastTick || progress == 0 || progress == 100) - { - MB_String s; - for (int i = 0; i < len; i++) - { - if (i == 0) - s = '['; - s += i < progress * len / 100 ? '#' : ' '; - if (i == len - 1) - s += ']'; - } - appendSpace(s); - s += progress; - appendSpace(s); - s += esp_mail_str_24; /* "%" */ - esp_mail_debug_print_tag(s.c_str(), esp_mail_debug_tag_type_client, true); - } - - lastProgress = progress; - } -#endif -} - -void ESP_Mail_Client::setTimezone(const char *TZ_Var, const char *TZ_file) -{ - - if (!TZ_Var) - return; - -#if defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO) - if (strlen(TZ_Var) > 0) - { - -#if defined(ESP32) - - mb_fs_mem_storage_type type = mb_fs_mem_storage_type_undefined; - -#if defined(MBFS_FLASH_FS) - type = mb_fs_mem_storage_type_flash; -#elif defined(MBFS_SD_FS) - type = mb_fs_mem_storage_type_sd; -#endif - - if (type != mb_fs_mem_storage_type_undefined) - { - MB_String filename = TZ_file; - if (mbfs->open(filename, type, mb_fs_open_mode_write) > -1) - { - mbfs->print(type, TZ_Var); - mbfs->close(type); - } - } - -#endif - - setenv("TZ", TZ_Var, 1); - tzset(); - timezoneEnvSet = true; - } -#endif -} - -void ESP_Mail_Client::preparePortFunction(Session_Config *session_config, bool isSMTP, bool &secure, bool &secureMode, bool &ssl) -{ - - if (session_config->ports_functions.list) - { - if (session_config->ports_functions.use_internal_list) - { - session_config->ports_functions.use_internal_list = false; - delete[] session_config->ports_functions.list; - session_config->ports_functions.list = nullptr; - } - } - - if (!session_config->ports_functions.list) - { - if (isSMTP) - { -#if defined(ENABLE_SMTP) - session_config->ports_functions.use_internal_list = true; - session_config->ports_functions.list = new port_function[3]; - session_config->ports_functions.size = 3; - - for (int i = 0; i < 3; i++) - session_config->ports_functions.list[i] = smtp_ports[i]; -#endif - } - else - { -#if defined(ENABLE_IMAP) - session_config->ports_functions.use_internal_list = true; - session_config->ports_functions.list = new port_function[2]; - session_config->ports_functions.size = 2; - - for (int i = 0; i < 2; i++) - session_config->ports_functions.list[i] = imap_ports[i]; -#endif - } - } - - getPortFunction(session_config->server.port, session_config->ports_functions, secure, secureMode, ssl, session_config->secure.startTLS); -} - -void ESP_Mail_Client::getPortFunction(uint16_t port, struct esp_mail_ports_functions &ports_functions, bool &secure, bool &secureMode, bool &ssl, bool &starttls) -{ - for (size_t i = 0; i < ports_functions.size; i++) - { - if (ports_functions.list[i].port == port) - { - if (ports_functions.list[i].protocol == esp_mail_protocol_plain_text) - { - secure = false; - secureMode = false; - } - else - { - if (ports_functions.list[i].protocol == esp_mail_protocol_tls) - starttls = true; - - secureMode = !starttls; - - if (ports_functions.list[i].protocol == esp_mail_protocol_ssl) - ssl = true; - } - return; - } - } -} - -void ESP_Mail_Client::getTimezone(const char *TZ_file, MB_String &out) -{ - -#if defined(ESP32) - - mb_fs_mem_storage_type type = mb_fs_mem_storage_type_undefined; - -#if defined(MBFS_FLASH_FS) - type = mb_fs_mem_storage_type_flash; -#elif defined(MBFS_SD_FS) - type = mb_fs_mem_storage_type_sd; -#endif - - if (type != mb_fs_mem_storage_type_undefined) - { - MB_String filename = TZ_file; - - if (mbfs->open(filename, type, mb_fs_open_mode_read) > 0) - { - out.clear(); - while (mbfs->available(type)) - { - out += (char)mbfs->read(type); - } - mbfs->close(type); - } - } -#endif -} - -void ESP_Mail_Client::setTime(const char *TZ_Var, const char *TZ_file, bool wait, bool debugProgress) -{ - - timeStatus = Time.timeReady(); - - if (!timeStatus) - { - -#if defined(ENABLE_IMAP) || defined(ENABLE_SMTP) - -#if defined(ENABLE_NTP_TIME) - - if (WiFI_CONNECTED) - { - Time.readNTPTime(wait ? 10000 : 0, debugProgress); - } - else - { -#if !defined(SILENT_MODE) - esp_mail_debug_print_tag(esp_mail_error_client_str_4 /* "NTP server time reading cannot begin when valid time is required because of no WiFi capability/activity detected." */, esp_mail_debug_tag_type_warning, true); - esp_mail_debug_print_tag(esp_mail_error_client_str_5 /* "Please set the library reference time manually using smtp.setSystemTime or imap.setSystemTime." */, esp_mail_debug_tag_type_warning, true); -#endif - } - - getSetTimezoneEnv(TZ_file, TZ_Var); - -#elif !defined(SILENT_MODE) - esp_mail_debug_print_tag(esp_mail_error_client_str_5 /* "Please set the library reference time manually using smtp.setSystemTime or imap.setSystemTime." */, esp_mail_debug_tag_type_warning, true); -#endif - -#endif - } - - timeStatus = Time.timeReady(); -} - -void ESP_Mail_Client::getSetTimezoneEnv(const char *TZ_file, const char *TZ_Var) -{ - // set and get TZ environment variable - - MB_String timezone; - - // only ESP32 only - getTimezone(TZ_file, timezone); - - if (timezone.length() == 0) - timezone = TZ_Var; - - // if timezone string assign - setTimezone(timezone.c_str(), TZ_file); -} - -bool ESP_Mail_Client::validEmail(const char *s) -{ - MB_String str(s); - size_t at = str.find('@'); - size_t dot = str.find('.', at); - return (at != MB_String::npos) && (dot != MB_String::npos); -} - -#if defined(ENABLE_SMTP) && defined(ENABLE_IMAP) - -bool ESP_Mail_Client::mAppendMessage(IMAPSession *imap, SMTP_Message *msg, bool lastAppend, MB_StringPtr flags, MB_StringPtr dateTime) -{ - this->imap = imap; - calDataLen = true; - dataLen = 0; - imap_ts = 0; - - if (!sessionExisted(imap)) - return false; - - MB_String _flags = flags; - _flags.trim(); - - MB_String _dt = dateTime; - _dt.trim(); - - bool rfc822MSG = false; - - sendContent(nullptr, msg, false, rfc822MSG); - - MB_String cmd; - - if (!imap->_feature_capability[esp_mail_imap_read_capability_multiappend]) - { - lastAppend = true; - imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; - } - - if (imap->_prev_imap_cmd != esp_mail_imap_cmd_append) - joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_append].text, imap->_currentFolder.c_str()); - - appendSpace(cmd); - - if (_flags.length() > 0) - { - appendString(cmd, _flags.c_str(), false, false, esp_mail_string_mark_type_round_bracket); - appendSpace(cmd); - } - - if (_dt.length() > 0) - { - appendString(cmd, _dt.c_str(), false, false, esp_mail_string_mark_type_double_quote); - appendSpace(cmd); - } - - appendString(cmd, MB_String((int)dataLen).c_str(), false, false, esp_mail_string_mark_type_curly_bracket); - - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - { - imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; - return false; - } - - imap->_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_append; - - if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, false)) - { - imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; - return false; - } - - calDataLen = false; - - rfc822MSG = false; - - if (!sendContent(nullptr, msg, false, rfc822MSG)) - { - imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; - return false; - } - - if (lastAppend) - { - if (imapSend(imap, esp_mail_str_18 /* "\r\n" */, false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - { - imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; - return false; - } - - imap->_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_append_last; - - if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, false)) - { - imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; - return false; - } - - imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; - } - - if (!lastAppend) - imap->_prev_imap_cmd = esp_mail_imap_cmd_append; - else - { -#if !defined(SILENT_MODE) - altSendCallback(nullptr, esp_mail_cb_str_45 /* "Message append successfully" */, esp_mail_dbg_str_73 /* "message append successfully" */, esp_mail_debug_tag_type_client, true, false); -#endif - } - return true; -} - -#endif - -char *ESP_Mail_Client::getRandomUID() -{ - char *tmp = allocMem(36); - sprintf(tmp, "%d", (int)random(2000, 4000)); - return tmp; -} - -void ESP_Mail_Client::splitToken(const char *str, _vectorImpl &tk, const char *delim) -{ - char *p = allocMem(strlen(str)); - strcpy(p, str); - char *pp = p; - char *end = p; - MB_String tmp; - while (pp != NULL) - { - // See RFC2047.h - ESP_MAIL_STRSEP(&end, delim); - if (strlen(pp) > 0) - { - tmp = pp; - tk.push_back(tmp); - } - pp = end; - } - // release memory - freeMem(&p); -} - -int ESP_Mail_Client::strpos(const char *haystack, const char *needle, int offset, bool caseSensitive) -{ - if (!haystack || !needle) - return -1; - - int hlen = strlen(haystack); - int nlen = strlen(needle); - - if (hlen == 0 || nlen == 0) - return -1; - - int hidx = offset, nidx = 0; - while ((*(haystack + hidx) != '\0') && (*(needle + nidx) != '\0') && hidx < hlen) - { - - bool nm = caseSensitive ? *(needle + nidx) != *(haystack + hidx) : tolower(*(needle + nidx)) != tolower(*(haystack + hidx)); - - if (nm) - { - hidx++; - nidx = 0; - } - else - { - nidx++; - hidx++; - if (nidx == nlen) - return hidx - nidx; - } - } - - return -1; -} - -char *ESP_Mail_Client::subStr(const char *buf, PGM_P beginToken, PGM_P endToken, int beginPos, int endPos, bool caseSensitive) -{ - char *tmp = nullptr; - if (beginToken) - { - int p1 = strposP(buf, beginToken, beginPos, caseSensitive); - if (p1 != -1) - { - while (buf[p1 + strlen_P(beginToken)] == ' ' || buf[p1 + strlen_P(beginToken)] == '\r' || buf[p1 + strlen_P(beginToken)] == '\n') - { - p1++; - if (strlen(buf) <= p1 + strlen_P(beginToken)) - { - p1--; - break; - } - } - - int p2 = -1; - if (endPos == 0) - p2 = strposP(buf, endToken, p1 + strlen_P(beginToken), caseSensitive); - - if (p2 == -1) - p2 = strlen(buf); - - int len = p2 - p1 - strlen_P(beginToken); - int ofs = endToken ? strlen_P(endToken) : 1; - tmp = allocMem(len + ofs); - memcpy(tmp, &buf[p1 + strlen_P(beginToken)], len); - } - } - else - { - int p1 = strposP(buf, endToken, beginPos); - if (p1 != -1) - { - tmp = allocMem(p1); - memcpy(tmp, &buf[2], p1 - 1); - } - } - - return tmp; -} - -bool ESP_Mail_Client::getHeader(const char *buf, PGM_P beginToken, MB_String &out, bool caseSensitive) -{ - if (strcmpP(buf, 0, beginToken, caseSensitive)) - { - char *tmp = subStr(buf, beginToken, NULL, 0, -1, caseSensitive); - if (tmp) - { - out = tmp; - // release memory - freeMem(&tmp); - return true; - } - } - - return false; -} - -void ESP_Mail_Client::appendHeaderField(MB_String &buf, const char *name, PGM_P value, bool comma, bool newLine, esp_mail_string_mark_type type) -{ - appendHeaderName(buf, name); - appendString(buf, value, comma, newLine, type); -} - -void ESP_Mail_Client::appendAddressHeaderField(MB_String &buf, esp_mail_address_info_t &source, esp_mail_rfc822_header_field_types type, bool header, bool comma, bool newLine) -{ - // Construct header field. - if (header) - appendHeaderName(buf, rfc822_headers[type].text); - - if (type != esp_mail_rfc822_header_field_cc && type != esp_mail_rfc822_header_field_bcc && - source.name.length() > 0) - { - appendString(buf, source.name.c_str(), false, false, esp_mail_string_mark_type_double_quote); - // Add white space after name for SMTP to fix iCloud Mail Service IMAP search compatibility issue #278 - // This is not restricted by rfc2822. - appendSpace(buf); - } - - appendString(buf, source.email.c_str(), comma, newLine, esp_mail_string_mark_type_angle_bracket); -} - -void ESP_Mail_Client::appendHeaderName(MB_String &buf, const char *name, bool clear, bool lowercase, bool space) -{ - if (clear) - buf.clear(); - - if (lowercase) - appendLowerCaseString(buf, name); - else - buf += name; - buf += esp_mail_str_34; /* ":" */ - if (space) - appendSpace(buf); -} - -void ESP_Mail_Client::appendLowerCaseString(MB_String &buf, PGM_P value, bool clear) -{ - if (clear) - buf.clear(); - char *tmp = strP2Lower(value); - buf += tmp; - freeMem(&tmp); -} - -void ESP_Mail_Client::appendHeaderProp(MB_String &buf, PGM_P prop, const char *value, bool &firstProp, bool lowerCase, bool isString, bool newLine) -{ - if (firstProp) - buf += esp_mail_str_35; /* ";" */ - appendSpace(buf); - if (lowerCase) - appendLowerCaseString(buf, prop); - else - buf += prop; - buf += esp_mail_str_7; /* "=" */ - if (isString) - buf += esp_mail_str_11; /* "\"" */ - buf += value; - if (isString) - buf += esp_mail_str_11; /* "\"" */ - buf += esp_mail_str_35; /* ";" */ - if (newLine) - appendNewline(buf); - - firstProp = false; -} - -void ESP_Mail_Client::appendString(MB_String &buf, PGM_P value, bool comma, bool newLine, esp_mail_string_mark_type type) -{ - if (comma) - buf += esp_mail_str_8; /* "," */ - - switch (type) - { - case esp_mail_string_mark_type_double_quote: - buf += esp_mail_str_11; /* "\"" */ - break; - case esp_mail_string_mark_type_angle_bracket: - buf += esp_mail_str_19; /* "<" */ - break; - case esp_mail_string_mark_type_round_bracket: - buf += esp_mail_str_38; /* "(" */ - break; - case esp_mail_string_mark_type_curly_bracket: - buf += esp_mail_str_36; /* "{" */ - break; - case esp_mail_string_mark_type_square_bracket: - buf += esp_mail_str_40; /* "[" */ - break; - default: - break; - } - - if (value) - buf += value; - - switch (type) - { - case esp_mail_string_mark_type_double_quote: - buf += esp_mail_str_11; /* "\"" */ - break; - case esp_mail_string_mark_type_angle_bracket: - buf += esp_mail_str_20; /* ">" */ - break; - case esp_mail_string_mark_type_round_bracket: - buf += esp_mail_str_39; /* ")" */ - break; - case esp_mail_string_mark_type_curly_bracket: - buf += esp_mail_str_37; /* "}" */ - break; - case esp_mail_string_mark_type_square_bracket: - buf += esp_mail_str_41; /* "]" */ - break; - default: - break; - } - - if (newLine) - appendNewline(buf); -} - -void ESP_Mail_Client::maskString(MB_String &buf, int len) -{ - for (int i = 0; i < len; i++) - buf += esp_mail_str_3; /* "*" */ -} - -void ESP_Mail_Client::appendDomain(MB_String &buf, const char *domain) -{ - buf += strlen(domain) > 0 ? domain : pgm2Str(esp_mail_str_1 /* "127.0.0.1" */); -} - -void ESP_Mail_Client::appendEmbedMessage(MB_String &buf, esp_mail_message_body_t &body, bool isHtml) -{ - appendHeaderName(buf, message_headers[esp_mail_message_header_field_content_disposition].text); - appendString(buf, body.embed.type == esp_mail_smtp_embed_message_type_inline ? esp_mail_content_disposition_type_t::inline_ : esp_mail_content_disposition_type_t::attachment, false, false); - - PGM_P pgm = isHtml ? esp_mail_str_14 /* "msg.html" */ : esp_mail_str_13; /* "msg.txt" */ - MB_String filename; - if (body.embed.filename.length() > 0) - filename = body.embed.filename; - else - filename = pgm; - - bool firstProp = true; - appendHeaderProp(buf, message_headers[esp_mail_message_header_field_filename].text, filename.c_str(), firstProp, true, true, true); - - if (body.embed.type == esp_mail_smtp_embed_message_type_inline) - { - appendHeaderName(buf, message_headers[esp_mail_message_header_field_content_location].text); - body.embed.filename.length() > 0 ? appendString(buf, body.embed.filename.c_str(), false, true) : appendString(buf, pgm, false, true); - appendHeaderField(buf, message_headers[esp_mail_message_header_field_content_id].text, body._int.cid.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); - } -} - -void ESP_Mail_Client::appendNewline(MB_String &buf) -{ - buf += esp_mail_str_18; /* "\r\n" */ -} - -void ESP_Mail_Client::getExtfromMIME(const char *mime, MB_String &ext) -{ - ext.clear(); - for (int i = 0; i < esp_mail_file_extension_maxType; i++) - { - if (strcmp_P(mime, mimeinfo[i].mimeType) == 0) - { - ext = mimeinfo[i].endsWith; - break; - } - } - - if (ext.length() == 0) - ext = esp_mail_str_42; /* ".dat" */ -} - -MB_String ESP_Mail_Client::mGetBase64(MB_StringPtr str) -{ - MB_String data = str; - return encodeBase64Str((uint8_t *)(data.c_str()), data.length()); -} - -int ESP_Mail_Client::readLine(ESP_Mail_TCPClient *client, char *buf, int bufLen, bool withLineBreak, int &count, bool &ovf, unsigned long timeoutSec, bool &isTimeout) -{ - int ret = -1; - char c = 0; - char _c = 0; - int idx = 0; - ovf = idx >= bufLen; - bool lineBreak = false; - isTimeout = false; - - unsigned long ms = millis(); - - // Instead of relying on data available, we looks for line break until timed out or disconnected or overflown occurred. - while (idx < bufLen && client->connected() && (!lineBreak || client->available() /* data may not available sometimes */)) - { - if (millis() - ms >= timeoutSec * 1000) - { - isTimeout = true; - break; - } - - yield_impl(); - - ret = client->read(); - if (ret > -1) - { - c = (char)ret; - buf[idx++] = c; - count++; - if (_c == '\r' && c == '\n') - { - lineBreak = true; - if (!withLineBreak) - { - buf[idx - 2] = 0; - idx -= 2; - } - return idx; - } - _c = c; - - if (idx >= bufLen - 1) - { - ovf = true; - return idx; - } - } - } - return idx; -} - -template -bool ESP_Mail_Client::readResponse(T sessionPtr, char *buf, int bufLen, int &readLen, bool withLineBreak, int &count, MB_String &ovfBuf) -{ - bool ovf = false, isTimeout = false; - unsigned long timeoutSec = TCP_CLIENT_DEFAULT_TCP_TIMEOUT_SEC; - - do - { - timeoutSec = sessionPtr->client.tcpTimeout(); - int len = readLine(&(sessionPtr->client), buf, bufLen, withLineBreak, count, ovf, timeoutSec, isTimeout); - readLen += len; - if (len > 0 && (ovf || ovfBuf.length() > 0)) - ovfBuf += buf; - - } while (ovf); - - if (isTimeout) - return false; - - if (ovfBuf.length() > 0) - { - -#if defined(SESSION_DEBUG_ENABLED) - sessionPtr->_responseStatus.errorCode = MAIL_CLIENT_ERROR_BUFFER_OVERFLOW; - sessionPtr->_responseStatus.text.clear(); - if (sessionPtr->_debug) - esp_mail_debug_print_tag(sessionPtr->errorReason().c_str(), esp_mail_debug_tag_type_warning, true); -#endif - } - - return true; -} - -template -bool ESP_Mail_Client::reconnect(T sessionPtr, unsigned long dataTime, bool downloadRequest) -{ - if (!sessionPtr) - return false; - - sessionPtr->client.setSession(sessionPtr->_session_cfg); - networkStatus = sessionPtr->client.networkReady(); - - if (dataTime > 0) - { - if (millis() - dataTime > (unsigned long)sessionPtr->client.tcpTimeout()) - { - closeTCPSession(sessionPtr); - - if (sessionPtr->_sessionType == esp_mail_session_type_imap) - { -#if defined(ENABLE_IMAP) - IMAPSession *ss = (IMAPSession *)sessionPtr; - if (ss->_headers.size() > 0) - { - if (downloadRequest) - { - errorStatusCB(ss, nullptr, IMAP_STATUS_ERROR_DOWNLAD_TIMEOUT, true); - if (cPart(ss) && cHeader(ss)->part_headers.size() > 0) - cPart(ss)->download_error = ss->errorReason().c_str(); - } - else - { - errorStatusCB(ss, nullptr, MAIL_CLIENT_ERROR_READ_TIMEOUT, true); - if (cHeader(ss)) - cHeader(ss)->error_msg = ss->errorReason().c_str(); - } - } - else - { -#if !defined(SILENT_MODE) - if (sessionPtr->_debug) - esp_mail_debug_print_tag(esp_mail_error_network_str_9 /* "response read timed out" */, esp_mail_debug_tag_type_error, true); -#endif - } -#endif - } - else - { -#if defined(ENABLE_SMTP) - SMTPSession *ss = (SMTPSession *)sessionPtr; - errorStatusCB(ss, this->imap, MAIL_CLIENT_ERROR_READ_TIMEOUT, false); -#endif - } - return false; - } - } - - if (!networkStatus) - { - closeTCPSession(sessionPtr); - - if (sessionPtr->_sessionType == esp_mail_session_type_imap) - { -#if defined(ENABLE_IMAP) - IMAPSession *ss = (IMAPSession *)sessionPtr; - if (ss->_mbif._idleTimeMs > 0 || ss->_imap_cmd == esp_mail_imap_cmd_idle || ss->_imap_cmd == esp_mail_imap_cmd_done) - { - // defer the polling error report - if (millis() - ss->_last_polling_error_ms > 10000 && !sessionPtr->connected()) - { - ss->_last_polling_error_ms = millis(); - errorStatusCB(ss, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, true); - } - } - else if (millis() - ss->_last_network_error_ms > 1000) - { - ss->_last_network_error_ms = millis(); - errorStatusCB(ss, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, true); - } - - if (ss->_headers.size() > 0) - { - if (cPart(ss) && downloadRequest) - cPart(ss)->download_error = ss->errorReason().c_str(); - else if (cHeader(ss)) - cHeader(ss)->error_msg = ss->errorReason().c_str(); - } - -#endif - } - else - { -#if defined(ENABLE_SMTP) - SMTPSession *ss = (SMTPSession *)sessionPtr; - errorStatusCB(ss, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, false); -#endif - } - - if (millis() - _lastReconnectMillis > _reconnectTimeout && !sessionPtr->connected()) - { - if (sessionPtr->_session_cfg->network_connection_handler) - { - // dummy - sessionPtr->client.disconnect(); - sessionPtr->_session_cfg->network_connection_handler(); - } - else - { - if (MailClient.networkAutoReconnect) - MailClient.resumeNetwork(&(sessionPtr->client)); - } - - _lastReconnectMillis = millis(); - } - - networkStatus = sessionPtr->client.networkReady(); - } - - return networkStatus; -} - -template -void ESP_Mail_Client::sendCB(T sessionPtr, PGM_P info, bool prependCRLF, bool success) -{ - if (sessionPtr) - { - sessionPtr->_cbData._info.clear(); - - if (prependCRLF) - appendNewline(sessionPtr->_cbData._info); - if (strlen_P(info) > 0) - { - sessionPtr->_cbData._info += esp_mail_str_33; /* "#### " */ - sessionPtr->_cbData._info += info; - } - sessionPtr->_cbData._success = success; - if (sessionPtr->_statusCallback) - sessionPtr->_statusCallback(sessionPtr->_cbData); - } -} - -template -void ESP_Mail_Client::sendErrorCB(T sessionPtr, PGM_P info, bool prependCRLF, bool success) -{ -#if !defined(SILENT_MODE) - MB_String e = esp_mail_str_12; /* "Error, " */ - e += info; - sendCB(sessionPtr, e.c_str(), prependCRLF, success); -#endif -} - -template -void ESP_Mail_Client::errorStatusCB(T1 sessionPtr, T2 sessionPtr2, int error, bool clearLastStatus) -{ - - if (sessionPtr) - { - sessionPtr->_responseStatus.errorCode = error; - - if (clearLastStatus) - sessionPtr->_responseStatus.text.clear(); - -#if !defined(SILENT_MODE) - if (sessionPtr->_statusCallback && !sessionPtr->_customCmdResCallback) - sendErrorCB(sessionPtr, sessionPtr->errorReason().c_str(), false, false); - - if (sessionPtr->_debug && !sessionPtr->_customCmdResCallback) - esp_mail_debug_print_tag(sessionPtr->errorReason().c_str(), esp_mail_debug_tag_type_error, true); -#endif - } - else if (sessionPtr2 && !calDataLen) - errorStatusCB(sessionPtr2, nullptr, error, clearLastStatus); -} - -template -bool ESP_Mail_Client::isResponseCB(T sessionPtr) -{ -#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) - return sessionPtr->_customCmdResCallback != NULL; -#endif - return false; -} - -template -void ESP_Mail_Client::printLibInfo(T sessionPtr) -{ -#if defined(SESSION_DEBUG_ENABLED) - - if (sessionPtr->_statusCallback != NULL && !isResponseCB(sessionPtr)) - sendCallback(sessionPtr, - sessionPtr->_sessionType == esp_mail_session_type_smtp ? esp_mail_cb_str_1 /* "Connecting to SMTP server..." */ - : esp_mail_cb_str_15 /* "Connecting to IMAP server..." */, - false, false); - - if (sessionPtr->_debug && !isResponseCB(sessionPtr)) - { - MB_String dbMsg = esp_mail_version_str; /* "ESP Mail Client v" */ - dbMsg += ESP_MAIL_VERSION; - esp_mail_debug_print_tag(dbMsg.c_str(), esp_mail_debug_tag_type_client, true); - -#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) - if (ESP.getPsramSize() == 0 && !isResponseCB(sessionPtr)) - esp_mail_debug_print_tag(esp_mail_error_mem_str_4 /* "PSRAM was enabled but not detected." */, esp_mail_debug_tag_type_warning, true); -#endif - } - -#endif -} - -template -bool ESP_Mail_Client::beginConnection(Session_Config *session_config, T sessionPtr, bool secureMode) -{ - - sessionPtr->client.setWiFi(&wifi); - sessionPtr->client.setSession(session_config); - - if (!reconnect(sessionPtr)) - return false; - -#if defined(SESSION_DEBUG_ENABLED) - if (sessionPtr->_debug && !isResponseCB(sessionPtr)) - { - esp_mail_debug_print_tag(sessionPtr->_sessionType == esp_mail_session_type_smtp - ? esp_mail_dbg_str_2 /* "connecting to SMTP server" */ - : esp_mail_dbg_str_18 /* "connecting to IMAP server" */, - esp_mail_debug_tag_type_client, true); - - MB_String dbMsg = esp_mail_dbg_str_19; /* "Host > " */ - dbMsg += session_config->server.host_name; - esp_mail_debug_print_tag(dbMsg.c_str(), esp_mail_debug_tag_type_client, true); - - dbMsg = esp_mail_dbg_str_20; /* "Port > " */ - dbMsg += session_config->server.port; - esp_mail_debug_print_tag(dbMsg.c_str(), esp_mail_debug_tag_type_client, true); - } -#endif - - sessionPtr->client.begin(session_config->server.host_name.c_str(), session_config->server.port); - - sessionPtr->client.ethDNSWorkAround(); - - if (!sessionPtr->client.connect(secureMode, session_config->certificate.verify)) - { - if (sessionPtr->_sessionType == esp_mail_session_type_smtp) - { -#if defined(ENABLE_SMTP) - return handleSMTPError((SMTPSession *)sessionPtr, SMTP_STATUS_SERVER_CONNECT_FAILED, false); -#endif - } - else - { -#if defined(ENABLE_IMAP) - return handleIMAPError((IMAPSession *)sessionPtr, IMAP_STATUS_SERVER_CONNECT_FAILED, false); -#endif - } - } - - return true; -} - -template -bool ESP_Mail_Client::prepareTime(Session_Config *session_config, T sessionPtr) -{ - bool timeShouldBeValid = false; - - if (sessionPtr->_sessionType == esp_mail_session_type_smtp) - timeShouldBeValid = true; -#if !defined(ESP_MAIL_DISABLE_SSL) - else - timeShouldBeValid = session_config->certificate.cert_file.length() > 0 || session_config->cert_ptr != 0; -#endif - -#if defined(ENABLE_NTP_TIME) && defined(ESP_MAIL_WIFI_IS_AVAILABLE) - bool ntpEnabled = true; -#else - bool ntpEnabled = false; -#endif - -#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) - - if (session_config->time.ntp_server.length() > 0 || timeShouldBeValid) - { - - Time.begin(session_config->time.gmt_offset, session_config->time.day_light_offset, session_config->time.ntp_server.c_str()); - - if (!Time.timeReady()) - { - if (sessionPtr->client.type() == esp_mail_client_type_external_gsm_client) - { - int year = 0; - int month = 0; - int day = 0; - int hour = 0; - int min = 0; - int sec = 0; - float timezone = 0; - if (sessionPtr->client.gprsGetTime(year, month, day, hour, min, sec, timezone)) - Time.setTimestamp(Time.getTimestamp(year, month, day, hour, min, sec), timezone); - } - else if (session_config->time.ntp_server.length()) - { -#if defined(ENABLE_NTP_TIME) -#if !defined(SILENT_MODE) - if (sessionPtr->_debug && !isResponseCB(sessionPtr)) - esp_mail_debug_print_tag(esp_mail_dbg_str_21 /* "Reading time from NTP server" */, esp_mail_debug_tag_type_client, false); -#endif - - setTime(session_config->time.timezone_env_string.c_str(), session_config->time.timezone_file.c_str(), true, sessionPtr->_debug && !isResponseCB(sessionPtr)); -#endif - } - } - } - -#endif - -#if defined(ESP32) - if (Time.timeReady() && !timezoneEnvSet) - getSetTimezoneEnv(session_config->time.timezone_file.c_str(), session_config->time.timezone_env_string.c_str()); -#endif - - if (Time.timeReady()) - return true; - else if (WiFI_CONNECTED && timeShouldBeValid) - { - errorStatusCB(sessionPtr, nullptr, ntpEnabled && session_config->time.ntp_server.length() ? MAIL_CLIENT_ERROR_NTP_TIME_SYNC_TIMED_OUT : MAIL_CLIENT_ERROR_TIME_WAS_NOT_SET, false); - return false; - } - - return true; -} - -template -bool ESP_Mail_Client::sessionReady(T sessionPtr) -{ - // If network connection failure or tcp session closed, close session to clear resources. - if (!reconnect(sessionPtr) || !connected(sessionPtr)) - { - closeTCPSession(sessionPtr); - -#if defined(ENABLE_IMAP) - if (sessionPtr->_sessionType == esp_mail_session_type_imap && !connected(sessionPtr)) - errorStatusCB(sessionPtr, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, false); -#endif - - return false; - } - - return true; -} - -void ESP_Mail_Client::setCert(Session_Config *session_config, const char *ca) -{ - int ptr = reinterpret_cast(ca); - if (ptr != session_config->cert_ptr) - { - session_config->cert_updated = true; - session_config->cert_ptr = ptr; - } -} - -void ESP_Mail_Client::setSecure(ESP_Mail_TCPClient &client, Session_Config *session_config) -{ - - client.setMBFS(mbfs); - - client.setSession(session_config); - -#if !defined(ESP_MAIL_DISABLE_SSL) - - if (client.getCertType() == esp_mail_cert_type_undefined || session_config->cert_updated) - { - if (session_config->certificate.cert_file.length() > 0 || session_config->certificate.cert_data != NULL || session_config->cert_ptr > 0) - { - client.setClockReady(timeStatus); - } - - if (session_config->certificate.cert_file.length() == 0) - { - if (session_config->cert_ptr > 0) - client.setCACert(reinterpret_cast(session_config->cert_ptr)); - else if (session_config->certificate.cert_data != NULL) - client.setCACert(session_config->certificate.cert_data); - else - client.setCACert(NULL); - } - else - { - if (!client.setCertFile(session_config->certificate.cert_file.c_str(), mbfs_type session_config->certificate.cert_file_storage_type)) - client.setCACert(NULL); - } - session_config->cert_updated = false; - } -#endif -} - -void ESP_Mail_Client::appendMultipartContentType(MB_String &buf, esp_mail_multipart_types type, const char *boundary) -{ - bool firstProp = true; - appendHeaderField(buf, message_headers[esp_mail_message_header_field_content_type].text, multipart_types[type].text, false, false); - appendHeaderProp(buf, esp_mail_str_90 /* "boundary" */, boundary, firstProp, false, true, true); - appendNewline(buf); -} - -String ESP_Mail_Client::errorReason(bool isSMTP, int errorCode, const char *msg) -{ - MB_String ret; - -#if defined(ENABLE_ERROR_STRING) && !defined(SILENT_MODE) - - // If there is server meanningful response (msg) is available, return it instead - if (strlen(msg) > 0) - return msg; - - // The error code enums were defined in ESP_Mail_Error.h and MB_FS.h. - switch (errorCode) - { - - case TCP_CLIENT_ERROR_CONNECTION_REFUSED: - ret = esp_mail_error_network_str_7; /* "connection refused" */ - break; - case TCP_CLIENT_ERROR_SEND_DATA_FAILED: - ret = esp_mail_error_network_str_8; /* "data sending failed" */ - break; - case TCP_CLIENT_ERROR_NOT_INITIALIZED: - ret = esp_mail_error_client_str_1; /* "client and/or necessary callback functions are not yet assigned" */ - break; - case TCP_CLIENT_ERROR_NOT_CONNECTED: - ret = esp_mail_error_network_str_4; /* "not connected" */ - break; - - case MAIL_CLIENT_ERROR_CONNECTION_CLOSED: - ret = esp_mail_error_network_str_6; /* "connection closed" */ - break; - case MAIL_CLIENT_ERROR_READ_TIMEOUT: - ret = esp_mail_error_network_str_3; /* "response read timed out" */ - break; - case MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP: - ret = esp_mail_error_ssl_str_1; /* "fail to set up the SSL/TLS structure" */ - break; - case MAIL_CLIENT_ERROR_OUT_OF_MEMORY: - ret = esp_mail_error_mem_str_8; /* "out of memory" */ - break; - case MAIL_CLIENT_ERROR_NTP_TIME_SYNC_TIMED_OUT: - ret = esp_mail_error_network_str_2; /* "NTP server time reading timed out" */ - break; - case MAIL_CLIENT_ERROR_SESSION_CONFIG_WAS_NOT_ASSIGNED: - ret = esp_mail_error_session_str_1; /* "the Session_Config object was not assigned" */ - break; - case MAIL_CLIENT_ERROR_TIME_WAS_NOT_SET: - ret = esp_mail_error_time_str_1; /* "library or device time was not set" */ - break; - case MAIL_CLIENT_ERROR_NOT_YET_LOGIN: - ret = esp_mail_error_auth_str_3; /* "not yet log in" */ - break; - case MAIL_CLIENT_ERROR_BUFFER_OVERFLOW: - ret = esp_mail_error_mem_str_9; /* "buffer overflow" */ - break; - -#if defined(ENABLE_SMTP) - case SMTP_STATUS_SERVER_CONNECT_FAILED: - ret = esp_mail_error_network_str_1; /* "unable to connect to server" */ - break; - case SMTP_STATUS_SMTP_GREETING_GET_RESPONSE_FAILED: - ret = esp_mail_error_smtp_str_1; /* "SMTP server greeting failed" */ - break; - case SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED: - ret = esp_mail_error_smtp_str_1; /* "SMTP server greeting failed" */ - break; - case SMTP_STATUS_AUTHEN_NOT_SUPPORT: - ret = esp_mail_error_auth_str_1; /* "the provided SASL authentication mechanism is not support" */ - break; - case SMTP_STATUS_AUTHEN_FAILED: - ret = esp_mail_error_smtp_str_2; /* "authentication failed" */ - break; - case SMTP_STATUS_USER_LOGIN_FAILED: - ret = esp_mail_error_smtp_str_2; /* "authentication failed" */ - break; - case SMTP_STATUS_PASSWORD_LOGIN_FAILED: - ret = esp_mail_error_smtp_str_3; /* "login password is not valid" */ - break; - case SMTP_STATUS_SEND_HEADER_SENDER_FAILED: - ret = esp_mail_error_smtp_str_4; /* "send header failed" */ - break; - case SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED: - ret = esp_mail_error_smtp_str_9; /* "set recipient failed" */ - break; - case SMTP_STATUS_SEND_BODY_FAILED: - ret = esp_mail_error_smtp_str_5; /* "send body failed" */ - break; - case SMTP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED: - ret = esp_mail_error_auth_str_2; /* "OAuth2.0 log in was disabled for this server" */ - break; - case SMTP_STATUS_NO_VALID_RECIPIENTS_EXISTED: - ret = esp_mail_error_smtp_str_8; /* "some of the recipient Email address is not valid" */ - break; - case SMTP_STATUS_NO_VALID_SENDER_EXISTED: - ret = esp_mail_error_smtp_str_7; /* "sender Email address is not valid" */ - break; - case SMTP_STATUS_NO_SUPPORTED_AUTH: - ret = esp_mail_error_auth_str_1; /* "the provided SASL authentication mechanism is not support" */ - break; - case SMTP_STATUS_SEND_CUSTOM_COMMAND_FAILED: - ret = esp_mail_error_smtp_str_10; /* "send custom command failed" */ - break; - case SMTP_STATUS_XOAUTH2_AUTH_FAILED: - ret = esp_mail_error_smtp_str_11; /* "XOAuth2 authenticate failed" */ - break; - case SMTP_STATUS_UNDEFINED: - ret = esp_mail_error_smtp_str_12; /* "undefined error" */ - break; -#endif - -#if defined(ENABLE_IMAP) - case IMAP_STATUS_SERVER_CONNECT_FAILED: - ret = esp_mail_error_network_str_1; /* "unable to connect to server" */ - break; - case IMAP_STATUS_IMAP_RESPONSE_FAILED: - ret = esp_mail_error_imap_str_18; /* "server replied NO or BAD response" */ - break; - case IMAP_STATUS_AUTHENTICATE_FAILED: - ret = esp_mail_error_imap_str_19; /* "authenticate failed" */ - break; - case IMAP_STATUS_BAD_COMMAND: - ret = esp_mail_error_imap_str_17; /* "could not parse command" */ - break; - case IMAP_STATUS_STORE_FAILED: - ret = esp_mail_error_imap_str_20; /* "flags or keywords store failed" */ - break; - case IMAP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED: - ret = esp_mail_error_imap_str_21; /* "server is not support OAuth2 login" */ - break; - case IMAP_STATUS_NO_MESSAGE: - ret = esp_mail_error_imap_str_5; /* "some of the requested messages no longer exist" */ - break; - case IMAP_STATUS_ERROR_DOWNLAD_TIMEOUT: - ret = esp_mail_error_network_str_5; /* "connection timeout" */ - break; - case IMAP_STATUS_CLOSE_MAILBOX_FAILED: - ret = esp_mail_error_imap_str_3; /* "fail to close the mailbox" */ - break; - case IMAP_STATUS_OPEN_MAILBOX_FAILED: - ret = esp_mail_error_imap_str_4; /* "fail to open the mailbox" */ - break; - case IMAP_STATUS_LIST_MAILBOXS_FAILED: - ret = esp_mail_error_imap_str_1; /* "fail to list the mailboxes" */ - break; - case IMAP_STATUS_CHECK_CAPABILITIES_FAILED: - ret = esp_mail_error_imap_str_2; /* "fail to check the capabilities" */ - break; - case IMAP_STATUS_NO_SUPPORTED_AUTH: - ret = esp_mail_error_auth_str_1; /* "the provided SASL authentication mechanism is not support" */ - break; - case IMAP_STATUS_NO_MAILBOX_FOLDER_OPENED: - ret = esp_mail_error_imap_str_5; /* "no mailbox opened" */ - break; - case IMAP_STATUS_FIRMWARE_UPDATE_INIT_FAILED: - ret = esp_mail_error_imap_str_6; /* "firmware update initialization failed" */ - break; - case IMAP_STATUS_FIRMWARE_UPDATE_WRITE_FAILED: - ret = esp_mail_error_imap_str_7; /* "firmware update write failed" */ - break; - case IMAP_STATUS_FIRMWARE_UPDATE_END_FAILED: - ret = esp_mail_error_imap_str_8; /* "firmware update finalize failed" */ - break; - case IMAP_STATUS_CHANGEDSINC_MODSEQ_TEST_FAILED: - ret = esp_mail_error_imap_str_14; /* "no message changed since (assigned) modsec" */ - break; - case IMAP_STATUS_MODSEQ_WAS_NOT_SUPPORTED: - ret = esp_mail_error_imap_str_15; /* "CONDSTORE was not supported or modsec was not supported for selected mailbox" */ - break; - -#endif - -#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) - - case MB_FS_ERROR_FILE_IO_ERROR: - ret = esp_mail_error_mem_str_7; /* "file I/O error" */ - break; - case MB_FS_ERROR_FILE_NOT_FOUND: - ret = esp_mail_error_mem_str_6; /* "file not found." */ - break; - case MB_FS_ERROR_FLASH_STORAGE_IS_NOT_READY: - ret = esp_mail_error_mem_str_1; /* "flash Storage is not ready." */ - break; - case MB_FS_ERROR_SD_STORAGE_IS_NOT_READY: - ret = esp_mail_error_mem_str_2; /* "SD Storage is not ready." */ - break; - case MB_FS_ERROR_FILE_STILL_OPENED: - ret = esp_mail_error_mem_str_5; /* "file is still opened." */ - break; - -#endif - default: - break; - } - -#endif - - return ret.c_str(); -} - -template -void ESP_Mail_Client::closeTCPSession(T sessionPtr) -{ - if (!sessionPtr) - return; - - sessionPtr->client.stop(); - - _lastReconnectMillis = millis(); - - memset(sessionPtr->_auth_capability, 0, esp_mail_auth_capability_maxType); - memset(sessionPtr->_feature_capability, 0, - sessionPtr->_sessionType == esp_mail_session_type_smtp -#if defined(ENABLE_SMTP) - ? (int)esp_mail_smtp_send_capability_maxType -#else - ? 0 -#endif - : (int)esp_mail_imap_read_capability_maxType); - - sessionPtr->_authenticated = false; - sessionPtr->_loginStatus = false; -} - -template -bool ESP_Mail_Client::connected(T sessionPtr) -{ - return sessionPtr->client.connected(); -} - -size_t ESP_Mail_Client::getReservedLen(size_t len) -{ - return mbfs->getReservedLen(len); -} - -template -T ESP_Mail_Client::allocMem(size_t size, bool clear) -{ - return reinterpret_cast(mbfs->newP(size, clear)); -} - -void ESP_Mail_Client::freeMem(void *ptr) -{ - mbfs->delP(ptr); -} - -bool ESP_Mail_Client::strcmpP(const char *buf, int ofs, PGM_P beginToken, bool caseSensitive) -{ - if (ofs < 0) - { - int p = strposP(buf, beginToken, 0, caseSensitive); - if (p == -1) - return false; - ofs = p; - } - - char *tmp2 = allocMem(strlen_P(beginToken) + 1); - memcpy(tmp2, &buf[ofs], strlen_P(beginToken)); - tmp2[strlen_P(beginToken)] = 0; - MB_String s = beginToken; - bool ret = (strcasecmp(s.c_str(), tmp2) == 0); - // release memory - freeMem(&tmp2); - return ret; -} - -int ESP_Mail_Client::strposP(const char *buf, PGM_P beginToken, int ofs, bool caseSensitive) -{ - MB_String s = beginToken; - return strpos(buf, s.c_str(), ofs, caseSensitive); -} - -char *ESP_Mail_Client::strP(PGM_P pgm) -{ - size_t len = strlen_P(pgm) + 1; - char *buf = allocMem(len); - strcpy_P(buf, pgm); - buf[len - 1] = 0; - return buf; -} - -char *ESP_Mail_Client::strP2Lower(PGM_P pgm) -{ - size_t len = strlen_P(pgm) + 1; - char *buf = allocMem(len); - strcpy_P(buf, pgm); - - for (char *p = buf; *p; p++) - { - *p = tolower(*p); - } - - buf[len - 1] = 0; - return buf; -} - -void ESP_Mail_Client::strReplaceP(MB_String &buf, PGM_P name, PGM_P value) -{ - char *n = strP(name); - char *v = strP(value); - - buf.replaceAll(n, v); - - freeMem(&n); - freeMem(&v); -} - -bool ESP_Mail_Client::isOAuthError(char *buf, int bufLen, int &chunkIdx, int ofs) -{ - bool ret = false; - if (chunkIdx == 0) - { - size_t olen; - unsigned char *decoded = decodeBase64((const unsigned char *)(buf + ofs), bufLen - ofs, &olen); - if (decoded) - { - ret = strposP((char *)decoded, esp_mail_str_44 /* "{\"status\":" */, 0) > -1; - freeMem(&decoded); - } - chunkIdx++; - } - return ret; -} - -MB_String ESP_Mail_Client::getXOAUTH2String(const MB_String &email, const MB_String &accessToken) -{ - MB_String raw = esp_mail_str_45; /* "user=" */ - raw += email; - raw += esp_mail_str_46; /* "\1auth=Bearer " */ - raw += accessToken; - raw += esp_mail_str_43; /* "\1\1" */ - return encodeBase64Str((const unsigned char *)raw.c_str(), raw.length()); -} - -unsigned char *ESP_Mail_Client::decodeBase64(const unsigned char *src, size_t len, size_t *out_len) -{ - unsigned char *out, *pos, block[4], tmp; - size_t i, count, olen; - int pad = 0; - size_t extra_pad; - - unsigned char *dtable = allocMem(256); - - memset(dtable, 0x80, 256); - - for (i = 0; i < sizeof(b64_index_table) - 1; i++) - dtable[b64_index_table[i]] = (unsigned char)i; - dtable['='] = 0; - - count = 0; - for (i = 0; i < len; i++) - { - if (dtable[src[i]] != 0x80) - count++; - } - - if (count == 0) - goto exit; - - extra_pad = (4 - count % 4) % 4; - - olen = (count + extra_pad) / 4 * 3; - - pos = out = allocMem(olen); - - if (out == NULL) - goto exit; - - count = 0; - - for (i = 0; i < len + extra_pad; i++) - { - unsigned char val; - - if (i >= len) - val = '='; - else - val = src[i]; - tmp = dtable[val]; - if (tmp == 0x80) - continue; - - if (val == '=') - pad++; - block[count] = tmp; - count++; - if (count == 4) - { - *pos++ = (block[0] << 2) | (block[1] >> 4); - *pos++ = (block[1] << 4) | (block[2] >> 2); - *pos++ = (block[2] << 6) | block[3]; - count = 0; - if (pad) - { - if (pad == 1) - pos--; - else if (pad == 2) - pos -= 2; - else - { - // release memory - free(out); - goto exit; - } - break; - } - } - } - - *out_len = pos - out; - // release memory - freeMem(&dtable); - return out; -exit: - // release memory - freeMem(&dtable); - return nullptr; -} - -MB_String ESP_Mail_Client::encodeBase64Str(const unsigned char *src, size_t len) -{ - return encodeBase64Str((uint8_t *)src, len); -} - -MB_String ESP_Mail_Client::encodeBase64Str(uint8_t *src, size_t len) -{ - MB_String outStr; - unsigned char *out, *pos; - const unsigned char *end, *in; - size_t olen = 4 * ((len + 2) / 3); - if (olen < len) - return outStr; - - outStr.resize(olen); - out = (unsigned char *)&outStr[0]; - - end = src + len; - in = src; - pos = out; - - while (end - in >= 3) - { - *pos++ = b64_index_table[in[0] >> 2]; - *pos++ = b64_index_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; - *pos++ = b64_index_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; - *pos++ = b64_index_table[in[2] & 0x3f]; - in += 3; - } - - if (end - in) - { - *pos++ = b64_index_table[in[0] >> 2]; - if (end - in == 1) - { - *pos++ = b64_index_table[(in[0] & 0x03) << 4]; - *pos++ = '='; - } - else - { - *pos++ = b64_index_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; - *pos++ = b64_index_table[(in[1] & 0x0f) << 2]; - } - *pos++ = '='; - } - - return outStr; -} - -#endif - -ESP_Mail_Client MailClient = ESP_Mail_Client(); - -#endif /* ESP_MAIL_CLIENT_CPP */ +#ifndef ESP_MAIL_CLIENT_CPP +#define ESP_MAIL_CLIENT_CPP + +#pragma GCC diagnostic ignored "-Wunused-but-set-variable" + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +/** + * Mail Client Arduino Library for Arduino devices. + * + * Created August 28, 2023 + * + * This library allows Espressif's ESP32, ESP8266, SAMD and RP2040 Pico devices to send and read Email through the SMTP and IMAP servers. + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * 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 "ESP_Mail_Client.h" +#include "ESP_Mail_Client_Version.h" + +#include "ESP_Mail_IMAP.h" +#include "ESP_Mail_SMTP.h" + +void ESP_Mail_Client::networkReconnect(bool reconnect) +{ +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) && (defined(ESP32) || defined(ESP8266)) + WiFi.setAutoReconnect(reconnect); +#endif + networkAutoReconnect = reconnect; +} + +void ESP_Mail_Client::printf(const char *format, ...) +{ + int size = 2048; + char s[size]; + va_list va; + va_start(va, format); + vsnprintf(s, size, format, va); + va_end(va); + ESP_MAIL_DEFAULT_DEBUG_PORT.print(s); +} + +void ESP_Mail_Client::addAP(const String &ssid, const String &password) +{ + wifi.addAP(ssid, password); +} + +void ESP_Mail_Client::clearAP() +{ + wifi.clearAP(); +} + +#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) + +bool ESP_Mail_Client::sdBegin(int8_t ss, int8_t sck, int8_t miso, int8_t mosi, uint32_t frequency) +{ + return mbfs->sdBegin(ss, sck, miso, mosi, frequency); +} + +#if defined(ESP8266) || defined(MB_ARDUINO_PICO) +bool ESP_Mail_Client::sdBegin(SDFSConfig *sdFSConfig) +{ + return mbfs->sdFatBegin(sdFSConfig); +} +#endif + +#if defined(ESP32) +bool ESP_Mail_Client::sdBegin(int8_t ss, SPIClass *spiConfig, uint32_t frequency) +{ + return mbfs->sdSPIBegin(ss, spiConfig, frequency); +} +#endif + +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) +bool ESP_Mail_Client::sdBegin(SdSpiConfig *sdFatSPIConfig, int8_t ss, int8_t sck, int8_t miso, int8_t mosi) +{ + return mbfs->sdFatBegin(sdFatSPIConfig, ss, sck, miso, mosi); +} + +bool ESP_Mail_Client::sdBegin(SdioConfig *sdFatSDIOConfig) +{ + return mbfs->sdFatBegin(sdFatSDIOConfig); +} +#endif + +#endif + +#if defined(ESP32) && defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD_MMC) + +bool ESP_Mail_Client::sdMMCBegin(const char *mountpoint, bool mode1bit, bool format_if_mount_failed) +{ + return mbfs->sdMMCBegin(mountpoint, mode1bit, format_if_mount_failed); +} + +#endif + +int ESP_Mail_Client::getFreeHeap() +{ +#if defined(MB_ARDUINO_ESP) + return ESP.getFreeHeap(); +#elif defined(MB_ARDUINO_PICO) + return rp2040.getFreeHeap(); +#else + return 0; +#endif +} + +// All following functions are for IMAP or SMTP only +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + +void ESP_Mail_Client::resumeNetwork(ESP_Mail_TCPClient *client) +{ + client->networkReconnect(); +} + +template +bool ESP_Mail_Client::sessionExisted(T sessionPtr) +{ + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + + Session_Config *config = sessionPtr->_session_cfg; + _vectorImpl *configPtrList = &(sessionPtr->_configPtrList); + + if (config) + { + int ptr = toAddr(*config); + for (size_t i = 0; i < configPtrList->size(); i++) + { + if ((*configPtrList)[i] == ptr) + return true; + } + + sessionPtr->closeSession(); + sessionPtr->_responseStatus.errorCode = MAIL_CLIENT_ERROR_SESSION_CONFIG_WAS_NOT_ASSIGNED; + sessionPtr->_responseStatus.text.clear(); + } + +#endif + return false; +} + +void ESP_Mail_Client::debugPrintNewLine() +{ +#if !defined(SILENT_MODE) + esp_mail_debug_print("", true); +#endif +} + +template +void ESP_Mail_Client::callBackSendNewLine(T sessionPtr, bool success) +{ +#if defined(SESSION_DEBUG_ENABLED) + sendCallback(sessionPtr, "", false, success); +#endif +} + +void ESP_Mail_Client::appendTagSpace(MB_String &buf, PGM_P tag) +{ + buf += (tag == NULL) ? esp_mail_imap_tag_str : tag; + appendSpace(buf); +} + +template +void ESP_Mail_Client::appendList(MB_String &buf, _vectorImpl &list) +{ + for (size_t i = 0; i < list.size(); i++) + { + if (i > 0) + buf += esp_mail_str_8; /* "," */ + buf += list[i]; + } +} + +void ESP_Mail_Client::appendSpace(MB_String &buf) +{ + buf += esp_mail_str_2 /* " " */; +} + +void ESP_Mail_Client::appendSpace(MB_String &buf, bool withTag, PGM_P value) +{ + if (withTag) + appendTagSpace(buf); + buf += value; + appendSpace(buf); +} + +void ESP_Mail_Client::appendSpace(MB_String &buf, bool withTag, int nunArgs, ...) +{ + if (withTag) + appendTagSpace(buf); + + va_list ap; + va_start(ap, nunArgs); + PGM_P p = va_arg(ap, PGM_P); + if (p) + buf += p; + for (int i = 2; i <= nunArgs; i++) + { + appendSpace(buf); + p = va_arg(ap, PGM_P); + if (p) + buf += p; + } + va_end(ap); + appendSpace(buf); +} + +void ESP_Mail_Client::prependSpace(MB_String &buf, PGM_P value) +{ + appendSpace(buf); + buf += value; +} + +void ESP_Mail_Client::appendDot(MB_String &buf) +{ + buf += esp_mail_str_27; /* "." */ +} + +void ESP_Mail_Client::prependDot(MB_String &buf, PGM_P value) +{ + buf += esp_mail_str_27; /* "." */ + buf += value; +} + +void ESP_Mail_Client::joinStringSpace(MB_String &buf, bool withTag, int nunArgs, ...) +{ + if (withTag) + appendTagSpace(buf); + + va_list ap; + va_start(ap, nunArgs); + PGM_P p = va_arg(ap, PGM_P); + if (p) + buf += p; + for (int i = 2; i <= nunArgs; i++) + { + appendSpace(buf); + p = va_arg(ap, PGM_P); + if (p) + buf += p; + } + va_end(ap); +} + +void ESP_Mail_Client::appendImap4KeyValue(MB_String &buf, PGM_P key, PGM_P value) +{ + buf += esp_mail_str_11; /* "\"" */ + buf += key; + buf += esp_mail_str_11; /* "\"" */ + appendSpace(buf); + buf += esp_mail_str_11; /* "\"" */ + buf += value; + buf += esp_mail_str_11; /* "\"" */ +} + +void ESP_Mail_Client::joinStringDot(MB_String &buf, int nunArgs, ...) +{ + va_list ap; + va_start(ap, nunArgs); + PGM_P p = va_arg(ap, PGM_P); + if (p) + buf += p; + for (int i = 2; i <= nunArgs; i++) + { + buf += esp_mail_str_27; /* "." */ + p = va_arg(ap, PGM_P); + if (p) + buf += p; + } + va_end(ap); +} + +template +void ESP_Mail_Client::sendCallback(T sessionPtr, PGM_P info, bool prependCRLF, bool success) +{ + +#if defined(SESSION_DEBUG_ENABLED) + + sessionPtr->_cbData._info.clear(); + + if (prependCRLF) + appendNewline(sessionPtr->_cbData._info); + if (strlen_P(info) > 0) + { + sessionPtr->_cbData._info += esp_mail_str_33; /* "#### " */ + sessionPtr->_cbData._info += info; + } + sessionPtr->_cbData._success = success; + if (sessionPtr->_statusCallback && !sessionPtr->_customCmdResCallback) + sessionPtr->_statusCallback(sessionPtr->_cbData); + +#endif +} + +template +void ESP_Mail_Client::printDebug(T sessionPtr, PGM_P cbMsg, PGM_P dbMsg, esp_mail_debug_tag_type type, bool prependCRLF, bool success) +{ +#if defined(SESSION_DEBUG_ENABLED) + + if (sessionPtr->_statusCallback != NULL && !isResponseCB(sessionPtr)) + sendCallback(sessionPtr, cbMsg, prependCRLF, success); + else if (sessionPtr->_debug) + debugPrintNewLine(); + + if (sessionPtr->_debug) + esp_mail_debug_print_tag(dbMsg, type, true); + +#endif +} + +void ESP_Mail_Client::printProgress(int progress, int &lastProgress) +{ +#if !defined(SILENT_MODE) + if (progress > 100) + progress = 100; + + if (lastProgress != progress && (progress == 0 || progress == 100 || lastProgress + ESP_MAIL_PROGRESS_REPORT_STEP <= progress)) + { + int len = 16; + int curTick = progress * len / 100; + int lastTick = lastProgress * len / 100; + + if (curTick > lastTick || progress == 0 || progress == 100) + { + MB_String s; + for (int i = 0; i < len; i++) + { + if (i == 0) + s = '['; + s += i < progress * len / 100 ? '#' : ' '; + if (i == len - 1) + s += ']'; + } + appendSpace(s); + s += progress; + appendSpace(s); + s += esp_mail_str_24; /* "%" */ + esp_mail_debug_print_tag(s.c_str(), esp_mail_debug_tag_type_client, true); + } + + lastProgress = progress; + } +#endif +} + +void ESP_Mail_Client::setTimezone(const char *TZ_Var, const char *TZ_file) +{ + + if (!TZ_Var) + return; + +#if defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO) + if (strlen(TZ_Var) > 0) + { + +#if defined(ESP32) + + mb_fs_mem_storage_type type = mb_fs_mem_storage_type_undefined; + +#if defined(MBFS_FLASH_FS) + type = mb_fs_mem_storage_type_flash; +#elif defined(MBFS_SD_FS) + type = mb_fs_mem_storage_type_sd; +#endif + + if (type != mb_fs_mem_storage_type_undefined) + { + MB_String filename = TZ_file; + if (mbfs->open(filename, type, mb_fs_open_mode_write) > -1) + { + mbfs->print(type, TZ_Var); + mbfs->close(type); + } + } + +#endif + + setenv("TZ", TZ_Var, 1); + tzset(); + timezoneEnvSet = true; + } +#endif +} + +void ESP_Mail_Client::preparePortFunction(Session_Config *session_config, bool isSMTP, bool &secure, bool &secureMode, bool &ssl) +{ + + if (session_config->ports_functions.list) + { + if (session_config->ports_functions.use_internal_list) + { + session_config->ports_functions.use_internal_list = false; + delete[] session_config->ports_functions.list; + session_config->ports_functions.list = nullptr; + } + } + + if (!session_config->ports_functions.list) + { + if (isSMTP) + { +#if defined(ENABLE_SMTP) + session_config->ports_functions.use_internal_list = true; + session_config->ports_functions.list = new port_function[3]; + session_config->ports_functions.size = 3; + + for (int i = 0; i < 3; i++) + session_config->ports_functions.list[i] = smtp_ports[i]; +#endif + } + else + { +#if defined(ENABLE_IMAP) + session_config->ports_functions.use_internal_list = true; + session_config->ports_functions.list = new port_function[2]; + session_config->ports_functions.size = 2; + + for (int i = 0; i < 2; i++) + session_config->ports_functions.list[i] = imap_ports[i]; +#endif + } + } + + getPortFunction(session_config->server.port, session_config->ports_functions, secure, secureMode, ssl, session_config->secure.startTLS); +} + +void ESP_Mail_Client::getPortFunction(uint16_t port, struct esp_mail_ports_functions &ports_functions, bool &secure, bool &secureMode, bool &ssl, bool &starttls) +{ + for (size_t i = 0; i < ports_functions.size; i++) + { + if (ports_functions.list[i].port == port) + { + if (ports_functions.list[i].protocol == esp_mail_protocol_plain_text) + { + secure = false; + secureMode = false; + } + else + { + if (ports_functions.list[i].protocol == esp_mail_protocol_tls) + starttls = true; + + secureMode = !starttls; + + if (ports_functions.list[i].protocol == esp_mail_protocol_ssl) + ssl = true; + } + return; + } + } +} + +void ESP_Mail_Client::getTimezone(const char *TZ_file, MB_String &out) +{ + +#if defined(ESP32) + + mb_fs_mem_storage_type type = mb_fs_mem_storage_type_undefined; + +#if defined(MBFS_FLASH_FS) + type = mb_fs_mem_storage_type_flash; +#elif defined(MBFS_SD_FS) + type = mb_fs_mem_storage_type_sd; +#endif + + if (type != mb_fs_mem_storage_type_undefined) + { + MB_String filename = TZ_file; + + if (mbfs->open(filename, type, mb_fs_open_mode_read) > 0) + { + out.clear(); + while (mbfs->available(type)) + { + out += (char)mbfs->read(type); + } + mbfs->close(type); + } + } +#endif +} + +void ESP_Mail_Client::setTime(const char *TZ_Var, const char *TZ_file, bool wait, bool debugProgress) +{ + + timeStatus = Time.timeReady(); + + if (!timeStatus) + { + +#if defined(ENABLE_IMAP) || defined(ENABLE_SMTP) + +#if defined(ENABLE_NTP_TIME) + + if (WiFI_CONNECTED) + { + Time.readNTPTime(wait ? 10000 : 0, debugProgress); + } + else + { +#if !defined(SILENT_MODE) + esp_mail_debug_print_tag(esp_mail_error_client_str_4 /* "NTP server time reading cannot begin when valid time is required because of no WiFi capability/activity detected." */, esp_mail_debug_tag_type_warning, true); + esp_mail_debug_print_tag(esp_mail_error_client_str_5 /* "Please set the library reference time manually using smtp.setSystemTime or imap.setSystemTime." */, esp_mail_debug_tag_type_warning, true); +#endif + } + + getSetTimezoneEnv(TZ_file, TZ_Var); + +#elif !defined(SILENT_MODE) + esp_mail_debug_print_tag(esp_mail_error_client_str_5 /* "Please set the library reference time manually using smtp.setSystemTime or imap.setSystemTime." */, esp_mail_debug_tag_type_warning, true); +#endif + +#endif + } + + timeStatus = Time.timeReady(); +} + +void ESP_Mail_Client::getSetTimezoneEnv(const char *TZ_file, const char *TZ_Var) +{ + // set and get TZ environment variable + + MB_String timezone; + + // only ESP32 only + getTimezone(TZ_file, timezone); + + if (timezone.length() == 0) + timezone = TZ_Var; + + // if timezone string assign + setTimezone(timezone.c_str(), TZ_file); +} + +bool ESP_Mail_Client::validEmail(const char *s) +{ + MB_String str(s); + size_t at = str.find('@'); + size_t dot = str.find('.', at); + return (at != MB_String::npos) && (dot != MB_String::npos); +} + +#if defined(ENABLE_SMTP) && defined(ENABLE_IMAP) + +bool ESP_Mail_Client::mAppendMessage(IMAPSession *imap, SMTP_Message *msg, bool lastAppend, MB_StringPtr flags, MB_StringPtr dateTime) +{ + this->imap = imap; + calDataLen = true; + dataLen = 0; + imap_ts = 0; + + if (!sessionExisted(imap)) + return false; + + MB_String _flags = flags; + _flags.trim(); + + MB_String _dt = dateTime; + _dt.trim(); + + bool rfc822MSG = false; + + sendContent(nullptr, msg, false, rfc822MSG); + + MB_String cmd; + + if (!imap->_feature_capability[esp_mail_imap_read_capability_multiappend]) + { + lastAppend = true; + imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + } + + if (imap->_prev_imap_cmd != esp_mail_imap_cmd_append) + joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_append].text, imap->_currentFolder.c_str()); + + appendSpace(cmd); + + if (_flags.length() > 0) + { + appendString(cmd, _flags.c_str(), false, false, esp_mail_string_mark_type_round_bracket); + appendSpace(cmd); + } + + if (_dt.length() > 0) + { + appendString(cmd, _dt.c_str(), false, false, esp_mail_string_mark_type_double_quote); + appendSpace(cmd); + } + + appendString(cmd, MB_String((int)dataLen).c_str(), false, false, esp_mail_string_mark_type_curly_bracket); + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + { + imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + return false; + } + + imap->_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_append; + + if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, false)) + { + imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + return false; + } + + calDataLen = false; + + rfc822MSG = false; + + if (!sendContent(nullptr, msg, false, rfc822MSG)) + { + imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + return false; + } + + if (lastAppend) + { + if (imapSend(imap, esp_mail_str_18 /* "\r\n" */, false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + { + imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + return false; + } + + imap->_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_append_last; + + if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, false)) + { + imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + return false; + } + + imap->_prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + } + + if (!lastAppend) + imap->_prev_imap_cmd = esp_mail_imap_cmd_append; + else + { +#if !defined(SILENT_MODE) + altSendCallback(nullptr, esp_mail_cb_str_45 /* "Message append successfully" */, esp_mail_dbg_str_73 /* "message append successfully" */, esp_mail_debug_tag_type_client, true, false); +#endif + } + return true; +} + +#endif + +char *ESP_Mail_Client::getRandomUID() +{ + char *tmp = allocMem(36); + sprintf(tmp, "%d", (int)random(2000, 4000)); + return tmp; +} + +void ESP_Mail_Client::splitToken(const char *str, _vectorImpl &tk, const char *delim) +{ + char *p = allocMem(strlen(str)); + strcpy(p, str); + char *pp = p; + char *end = p; + MB_String tmp; + while (pp != NULL) + { + // See RFC2047.h + ESP_MAIL_STRSEP(&end, delim); + if (strlen(pp) > 0) + { + tmp = pp; + tk.push_back(tmp); + } + pp = end; + } + // release memory + freeMem(&p); +} + +int ESP_Mail_Client::strpos(const char *haystack, const char *needle, int offset, bool caseSensitive) +{ + if (!haystack || !needle) + return -1; + + int hlen = strlen(haystack); + int nlen = strlen(needle); + + if (hlen == 0 || nlen == 0) + return -1; + + int hidx = offset, nidx = 0; + while ((*(haystack + hidx) != '\0') && (*(needle + nidx) != '\0') && hidx < hlen) + { + + bool nm = caseSensitive ? *(needle + nidx) != *(haystack + hidx) : tolower(*(needle + nidx)) != tolower(*(haystack + hidx)); + + if (nm) + { + hidx++; + nidx = 0; + } + else + { + nidx++; + hidx++; + if (nidx == nlen) + return hidx - nidx; + } + } + + return -1; +} + +char *ESP_Mail_Client::subStr(const char *buf, PGM_P beginToken, PGM_P endToken, int beginPos, int endPos, bool caseSensitive) +{ + char *tmp = nullptr; + if (beginToken) + { + int p1 = strposP(buf, beginToken, beginPos, caseSensitive); + if (p1 != -1) + { + while (buf[p1 + strlen_P(beginToken)] == ' ' || buf[p1 + strlen_P(beginToken)] == '\r' || buf[p1 + strlen_P(beginToken)] == '\n') + { + p1++; + if (strlen(buf) <= p1 + strlen_P(beginToken)) + { + p1--; + break; + } + } + + int p2 = -1; + if (endPos == 0) + p2 = strposP(buf, endToken, p1 + strlen_P(beginToken), caseSensitive); + + if (p2 == -1) + p2 = strlen(buf); + + int len = p2 - p1 - strlen_P(beginToken); + int ofs = endToken ? strlen_P(endToken) : 1; + tmp = allocMem(len + ofs); + memcpy(tmp, &buf[p1 + strlen_P(beginToken)], len); + } + } + else + { + int p1 = strposP(buf, endToken, beginPos); + if (p1 != -1) + { + tmp = allocMem(p1); + memcpy(tmp, &buf[2], p1 - 1); + } + } + + return tmp; +} + +bool ESP_Mail_Client::getHeader(const char *buf, PGM_P beginToken, MB_String &out, bool caseSensitive) +{ + if (strcmpP(buf, 0, beginToken, caseSensitive)) + { + char *tmp = subStr(buf, beginToken, NULL, 0, -1, caseSensitive); + if (tmp) + { + out = tmp; + // release memory + freeMem(&tmp); + return true; + } + } + + return false; +} + +void ESP_Mail_Client::appendHeaderField(MB_String &buf, const char *name, PGM_P value, bool comma, bool newLine, esp_mail_string_mark_type type) +{ + appendHeaderName(buf, name); + appendString(buf, value, comma, newLine, type); +} + +void ESP_Mail_Client::appendAddressHeaderField(MB_String &buf, esp_mail_address_info_t &source, esp_mail_rfc822_header_field_types type, bool header, bool comma, bool newLine) +{ + // Construct header field. + if (header) + appendHeaderName(buf, rfc822_headers[type].text); + + if (type != esp_mail_rfc822_header_field_cc && type != esp_mail_rfc822_header_field_bcc && + source.name.length() > 0) + { + appendString(buf, source.name.c_str(), false, false, esp_mail_string_mark_type_double_quote); + // Add white space after name for SMTP to fix iCloud Mail Service IMAP search compatibility issue #278 + // This is not restricted by rfc2822. + appendSpace(buf); + } + + appendString(buf, source.email.c_str(), comma, newLine, esp_mail_string_mark_type_angle_bracket); +} + +void ESP_Mail_Client::appendHeaderName(MB_String &buf, const char *name, bool clear, bool lowercase, bool space) +{ + if (clear) + buf.clear(); + + if (lowercase) + appendLowerCaseString(buf, name); + else + buf += name; + buf += esp_mail_str_34; /* ":" */ + if (space) + appendSpace(buf); +} + +void ESP_Mail_Client::appendLowerCaseString(MB_String &buf, PGM_P value, bool clear) +{ + if (clear) + buf.clear(); + char *tmp = strP2Lower(value); + buf += tmp; + freeMem(&tmp); +} + +void ESP_Mail_Client::appendHeaderProp(MB_String &buf, PGM_P prop, const char *value, bool &firstProp, bool lowerCase, bool isString, bool newLine) +{ + if (firstProp) + buf += esp_mail_str_35; /* ";" */ + appendSpace(buf); + if (lowerCase) + appendLowerCaseString(buf, prop); + else + buf += prop; + buf += esp_mail_str_7; /* "=" */ + if (isString) + buf += esp_mail_str_11; /* "\"" */ + buf += value; + if (isString) + buf += esp_mail_str_11; /* "\"" */ + buf += esp_mail_str_35; /* ";" */ + if (newLine) + appendNewline(buf); + + firstProp = false; +} + +void ESP_Mail_Client::appendString(MB_String &buf, PGM_P value, bool comma, bool newLine, esp_mail_string_mark_type type) +{ + if (comma) + buf += esp_mail_str_8; /* "," */ + + switch (type) + { + case esp_mail_string_mark_type_double_quote: + buf += esp_mail_str_11; /* "\"" */ + break; + case esp_mail_string_mark_type_angle_bracket: + buf += esp_mail_str_19; /* "<" */ + break; + case esp_mail_string_mark_type_round_bracket: + buf += esp_mail_str_38; /* "(" */ + break; + case esp_mail_string_mark_type_curly_bracket: + buf += esp_mail_str_36; /* "{" */ + break; + case esp_mail_string_mark_type_square_bracket: + buf += esp_mail_str_40; /* "[" */ + break; + default: + break; + } + + if (value) + buf += value; + + switch (type) + { + case esp_mail_string_mark_type_double_quote: + buf += esp_mail_str_11; /* "\"" */ + break; + case esp_mail_string_mark_type_angle_bracket: + buf += esp_mail_str_20; /* ">" */ + break; + case esp_mail_string_mark_type_round_bracket: + buf += esp_mail_str_39; /* ")" */ + break; + case esp_mail_string_mark_type_curly_bracket: + buf += esp_mail_str_37; /* "}" */ + break; + case esp_mail_string_mark_type_square_bracket: + buf += esp_mail_str_41; /* "]" */ + break; + default: + break; + } + + if (newLine) + appendNewline(buf); +} + +void ESP_Mail_Client::maskString(MB_String &buf, int len) +{ + for (int i = 0; i < len; i++) + buf += esp_mail_str_3; /* "*" */ +} + +void ESP_Mail_Client::appendDomain(MB_String &buf, const char *domain) +{ + buf += strlen(domain) > 0 ? domain : pgm2Str(esp_mail_str_1 /* "127.0.0.1" */); +} + +void ESP_Mail_Client::appendEmbedMessage(MB_String &buf, esp_mail_message_body_t &body, bool isHtml) +{ + appendHeaderName(buf, message_headers[esp_mail_message_header_field_content_disposition].text); + appendString(buf, body.embed.type == esp_mail_smtp_embed_message_type_inline ? esp_mail_content_disposition_type_t::inline_ : esp_mail_content_disposition_type_t::attachment, false, false); + + PGM_P pgm = isHtml ? esp_mail_str_14 /* "msg.html" */ : esp_mail_str_13; /* "msg.txt" */ + MB_String filename; + if (body.embed.filename.length() > 0) + filename = body.embed.filename; + else + filename = pgm; + + bool firstProp = true; + appendHeaderProp(buf, message_headers[esp_mail_message_header_field_filename].text, filename.c_str(), firstProp, true, true, true); + + if (body.embed.type == esp_mail_smtp_embed_message_type_inline) + { + appendHeaderName(buf, message_headers[esp_mail_message_header_field_content_location].text); + body.embed.filename.length() > 0 ? appendString(buf, body.embed.filename.c_str(), false, true) : appendString(buf, pgm, false, true); + appendHeaderField(buf, message_headers[esp_mail_message_header_field_content_id].text, body._int.cid.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + } +} + +void ESP_Mail_Client::appendNewline(MB_String &buf) +{ + buf += esp_mail_str_18; /* "\r\n" */ +} + +void ESP_Mail_Client::getExtfromMIME(const char *mime, MB_String &ext) +{ + ext.clear(); + for (int i = 0; i < esp_mail_file_extension_maxType; i++) + { + if (strcmp_P(mime, mimeinfo[i].mimeType) == 0) + { + ext = mimeinfo[i].endsWith; + break; + } + } + + if (ext.length() == 0) + ext = esp_mail_str_42; /* ".dat" */ +} + +MB_String ESP_Mail_Client::mGetBase64(MB_StringPtr str) +{ + MB_String data = str; + return encodeBase64Str((uint8_t *)(data.c_str()), data.length()); +} + +int ESP_Mail_Client::readLine(ESP_Mail_TCPClient *client, char *buf, int bufLen, bool withLineBreak, int &count, bool &ovf, unsigned long timeoutSec, bool &isTimeout) +{ + int ret = -1; + char c = 0; + char _c = 0; + int idx = 0; + ovf = idx >= bufLen; + bool lineBreak = false; + isTimeout = false; + + unsigned long ms = millis(); + + // Instead of relying on data available, we looks for line break until timed out or disconnected or overflown occurred. + while (idx < bufLen && client->connected() && (!lineBreak || client->available() /* data may not available sometimes */)) + { + if (millis() - ms >= timeoutSec * 1000) + { + isTimeout = true; + break; + } + + yield_impl(); + + ret = client->read(); + if (ret > -1) + { + c = (char)ret; + buf[idx++] = c; + count++; + if (_c == '\r' && c == '\n') + { + lineBreak = true; + if (!withLineBreak) + { + buf[idx - 2] = 0; + idx -= 2; + } + return idx; + } + _c = c; + + if (idx >= bufLen - 1) + { + ovf = true; + return idx; + } + } + } + return idx; +} + +template +bool ESP_Mail_Client::readResponse(T sessionPtr, char *buf, int bufLen, int &readLen, bool withLineBreak, int &count, MB_String &ovfBuf) +{ + bool ovf = false, isTimeout = false; + unsigned long timeoutSec = TCP_CLIENT_DEFAULT_TCP_TIMEOUT_SEC; + + do + { + timeoutSec = sessionPtr->client.tcpTimeout(); + int len = readLine(&(sessionPtr->client), buf, bufLen, withLineBreak, count, ovf, timeoutSec, isTimeout); + readLen += len; + if (len > 0 && (ovf || ovfBuf.length() > 0)) + ovfBuf += buf; + + } while (ovf); + + if (isTimeout) + return false; + + if (ovfBuf.length() > 0) + { + +#if defined(SESSION_DEBUG_ENABLED) + sessionPtr->_responseStatus.errorCode = MAIL_CLIENT_ERROR_BUFFER_OVERFLOW; + sessionPtr->_responseStatus.text.clear(); + if (sessionPtr->_debug) + esp_mail_debug_print_tag(sessionPtr->errorReason().c_str(), esp_mail_debug_tag_type_warning, true); +#endif + } + + return true; +} + +template +bool ESP_Mail_Client::reconnect(T sessionPtr, unsigned long dataTime, bool downloadRequest) +{ + if (!sessionPtr) + return false; + + sessionPtr->client.setSession(sessionPtr->_session_cfg); + networkStatus = sessionPtr->client.networkReady(); + + if (dataTime > 0) + { + if (millis() - dataTime > (unsigned long)sessionPtr->client.tcpTimeout()) + { + closeTCPSession(sessionPtr); + + if (sessionPtr->_sessionType == esp_mail_session_type_imap) + { +#if defined(ENABLE_IMAP) + IMAPSession *ss = (IMAPSession *)sessionPtr; + if (ss->_headers.size() > 0) + { + if (downloadRequest) + { + errorStatusCB(ss, nullptr, IMAP_STATUS_ERROR_DOWNLAD_TIMEOUT, true); + if (cPart(ss) && cHeader(ss)->part_headers.size() > 0) + cPart(ss)->download_error = ss->errorReason().c_str(); + } + else + { + errorStatusCB(ss, nullptr, MAIL_CLIENT_ERROR_READ_TIMEOUT, true); + if (cHeader(ss)) + cHeader(ss)->error_msg = ss->errorReason().c_str(); + } + } + else + { +#if !defined(SILENT_MODE) + if (sessionPtr->_debug) + esp_mail_debug_print_tag(esp_mail_error_network_str_9 /* "response read timed out" */, esp_mail_debug_tag_type_error, true); +#endif + } +#endif + } + else + { +#if defined(ENABLE_SMTP) + SMTPSession *ss = (SMTPSession *)sessionPtr; + errorStatusCB(ss, this->imap, MAIL_CLIENT_ERROR_READ_TIMEOUT, false); +#endif + } + return false; + } + } + + if (!networkStatus) + { + closeTCPSession(sessionPtr); + + if (sessionPtr->_sessionType == esp_mail_session_type_imap) + { +#if defined(ENABLE_IMAP) + IMAPSession *ss = (IMAPSession *)sessionPtr; + if (ss->_mbif._idleTimeMs > 0 || ss->_imap_cmd == esp_mail_imap_cmd_idle || ss->_imap_cmd == esp_mail_imap_cmd_done) + { + // defer the polling error report + if (millis() - ss->_last_polling_error_ms > 10000 && !sessionPtr->connected()) + { + ss->_last_polling_error_ms = millis(); + errorStatusCB(ss, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, true); + } + } + else if (millis() - ss->_last_network_error_ms > 1000) + { + ss->_last_network_error_ms = millis(); + errorStatusCB(ss, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, true); + } + + if (ss->_headers.size() > 0) + { + if (cPart(ss) && downloadRequest) + cPart(ss)->download_error = ss->errorReason().c_str(); + else if (cHeader(ss)) + cHeader(ss)->error_msg = ss->errorReason().c_str(); + } + +#endif + } + else + { +#if defined(ENABLE_SMTP) + SMTPSession *ss = (SMTPSession *)sessionPtr; + errorStatusCB(ss, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, false); +#endif + } + + if (millis() - _lastReconnectMillis > _reconnectTimeout && !sessionPtr->connected()) + { + if (sessionPtr->_session_cfg->network_connection_handler) + { + // dummy + sessionPtr->client.disconnect(); + sessionPtr->_session_cfg->network_connection_handler(); + } + else + { + if (MailClient.networkAutoReconnect) + MailClient.resumeNetwork(&(sessionPtr->client)); + } + + _lastReconnectMillis = millis(); + } + + networkStatus = sessionPtr->client.networkReady(); + } + + return networkStatus; +} + +template +void ESP_Mail_Client::sendCB(T sessionPtr, PGM_P info, bool prependCRLF, bool success) +{ + if (sessionPtr) + { + sessionPtr->_cbData._info.clear(); + + if (prependCRLF) + appendNewline(sessionPtr->_cbData._info); + if (strlen_P(info) > 0) + { + sessionPtr->_cbData._info += esp_mail_str_33; /* "#### " */ + sessionPtr->_cbData._info += info; + } + sessionPtr->_cbData._success = success; + if (sessionPtr->_statusCallback) + sessionPtr->_statusCallback(sessionPtr->_cbData); + } +} + +template +void ESP_Mail_Client::sendErrorCB(T sessionPtr, PGM_P info, bool prependCRLF, bool success) +{ +#if !defined(SILENT_MODE) + MB_String e = esp_mail_str_12; /* "Error, " */ + e += info; + sendCB(sessionPtr, e.c_str(), prependCRLF, success); +#endif +} + +template +void ESP_Mail_Client::errorStatusCB(T1 sessionPtr, T2 sessionPtr2, int error, bool clearLastStatus) +{ + + if (sessionPtr) + { + sessionPtr->_responseStatus.errorCode = error; + + if (clearLastStatus) + sessionPtr->_responseStatus.text.clear(); + +#if !defined(SILENT_MODE) + if (sessionPtr->_statusCallback && !sessionPtr->_customCmdResCallback) + sendErrorCB(sessionPtr, sessionPtr->errorReason().c_str(), false, false); + + if (sessionPtr->_debug && !sessionPtr->_customCmdResCallback) + esp_mail_debug_print_tag(sessionPtr->errorReason().c_str(), esp_mail_debug_tag_type_error, true); +#endif + } + else if (sessionPtr2 && !calDataLen) + errorStatusCB(sessionPtr2, nullptr, error, clearLastStatus); +} + +template +bool ESP_Mail_Client::isResponseCB(T sessionPtr) +{ +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + return sessionPtr->_customCmdResCallback != NULL; +#endif + return false; +} + +template +void ESP_Mail_Client::printLibInfo(T sessionPtr) +{ +#if defined(SESSION_DEBUG_ENABLED) + + if (sessionPtr->_statusCallback != NULL && !isResponseCB(sessionPtr)) + sendCallback(sessionPtr, + sessionPtr->_sessionType == esp_mail_session_type_smtp ? esp_mail_cb_str_1 /* "Connecting to SMTP server..." */ + : esp_mail_cb_str_15 /* "Connecting to IMAP server..." */, + false, false); + + if (sessionPtr->_debug && !isResponseCB(sessionPtr)) + { + MB_String dbMsg = esp_mail_version_str; /* "ESP Mail Client v" */ + dbMsg += ESP_MAIL_VERSION; + esp_mail_debug_print_tag(dbMsg.c_str(), esp_mail_debug_tag_type_client, true); + +#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) + if (ESP.getPsramSize() == 0 && !isResponseCB(sessionPtr)) + esp_mail_debug_print_tag(esp_mail_error_mem_str_4 /* "PSRAM was enabled but not detected." */, esp_mail_debug_tag_type_warning, true); +#endif + } + +#endif +} + +template +bool ESP_Mail_Client::beginConnection(Session_Config *session_config, T sessionPtr, bool secureMode) +{ + + sessionPtr->client.setWiFi(&wifi); + sessionPtr->client.setSession(session_config); + + if (!reconnect(sessionPtr)) + return false; + +#if defined(SESSION_DEBUG_ENABLED) + if (sessionPtr->_debug && !isResponseCB(sessionPtr)) + { + esp_mail_debug_print_tag(sessionPtr->_sessionType == esp_mail_session_type_smtp + ? esp_mail_dbg_str_2 /* "connecting to SMTP server" */ + : esp_mail_dbg_str_18 /* "connecting to IMAP server" */, + esp_mail_debug_tag_type_client, true); + + MB_String dbMsg = esp_mail_dbg_str_19; /* "Host > " */ + dbMsg += session_config->server.host_name; + esp_mail_debug_print_tag(dbMsg.c_str(), esp_mail_debug_tag_type_client, true); + + dbMsg = esp_mail_dbg_str_20; /* "Port > " */ + dbMsg += session_config->server.port; + esp_mail_debug_print_tag(dbMsg.c_str(), esp_mail_debug_tag_type_client, true); + } +#endif + + sessionPtr->client.begin(session_config->server.host_name.c_str(), session_config->server.port); + + sessionPtr->client.ethDNSWorkAround(); + + if (!sessionPtr->client.connect(secureMode, session_config->certificate.verify)) + { + if (sessionPtr->_sessionType == esp_mail_session_type_smtp) + { +#if defined(ENABLE_SMTP) + return handleSMTPError((SMTPSession *)sessionPtr, SMTP_STATUS_SERVER_CONNECT_FAILED, false); +#endif + } + else + { +#if defined(ENABLE_IMAP) + return handleIMAPError((IMAPSession *)sessionPtr, IMAP_STATUS_SERVER_CONNECT_FAILED, false); +#endif + } + } + + return true; +} + +template +bool ESP_Mail_Client::prepareTime(Session_Config *session_config, T sessionPtr) +{ + bool timeShouldBeValid = false; + + if (sessionPtr->_sessionType == esp_mail_session_type_smtp) + timeShouldBeValid = true; +#if !defined(ESP_MAIL_DISABLE_SSL) + else + timeShouldBeValid = session_config->certificate.cert_file.length() > 0 || session_config->cert_ptr != 0; +#endif + +#if defined(ENABLE_NTP_TIME) && defined(ESP_MAIL_WIFI_IS_AVAILABLE) + bool ntpEnabled = true; +#else + bool ntpEnabled = false; +#endif + +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) + + if (session_config->time.ntp_server.length() > 0 || timeShouldBeValid) + { + + Time.begin(session_config->time.gmt_offset, session_config->time.day_light_offset, session_config->time.ntp_server.c_str()); + + if (!Time.timeReady()) + { + if (sessionPtr->client.type() == esp_mail_client_type_external_gsm_client) + { + int year = 0; + int month = 0; + int day = 0; + int hour = 0; + int min = 0; + int sec = 0; + float timezone = 0; + if (sessionPtr->client.gprsGetTime(year, month, day, hour, min, sec, timezone)) + Time.setTimestamp(Time.getTimestamp(year, month, day, hour, min, sec), timezone); + } + else if (session_config->time.ntp_server.length()) + { +#if defined(ENABLE_NTP_TIME) +#if !defined(SILENT_MODE) + if (sessionPtr->_debug && !isResponseCB(sessionPtr)) + esp_mail_debug_print_tag(esp_mail_dbg_str_21 /* "Reading time from NTP server" */, esp_mail_debug_tag_type_client, false); +#endif + + setTime(session_config->time.timezone_env_string.c_str(), session_config->time.timezone_file.c_str(), true, sessionPtr->_debug && !isResponseCB(sessionPtr)); +#endif + } + } + } + +#endif + +#if defined(ESP32) + if (Time.timeReady() && !timezoneEnvSet) + getSetTimezoneEnv(session_config->time.timezone_file.c_str(), session_config->time.timezone_env_string.c_str()); +#endif + + if (Time.timeReady()) + return true; + else if (WiFI_CONNECTED && timeShouldBeValid) + { + errorStatusCB(sessionPtr, nullptr, ntpEnabled && session_config->time.ntp_server.length() ? MAIL_CLIENT_ERROR_NTP_TIME_SYNC_TIMED_OUT : MAIL_CLIENT_ERROR_TIME_WAS_NOT_SET, false); + return false; + } + + return true; +} + +template +bool ESP_Mail_Client::sessionReady(T sessionPtr) +{ + // If network connection failure or tcp session closed, close session to clear resources. + if (!reconnect(sessionPtr) || !connected(sessionPtr)) + { + closeTCPSession(sessionPtr); + +#if defined(ENABLE_IMAP) + if (sessionPtr->_sessionType == esp_mail_session_type_imap && !connected(sessionPtr)) + errorStatusCB(sessionPtr, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, false); +#endif + + return false; + } + + return true; +} + +void ESP_Mail_Client::setCert(Session_Config *session_config, const char *ca) +{ + int ptr = reinterpret_cast(ca); + if (ptr != session_config->cert_ptr) + { + session_config->cert_updated = true; + session_config->cert_ptr = ptr; + } +} + +void ESP_Mail_Client::setSecure(ESP_Mail_TCPClient &client, Session_Config *session_config) +{ + + client.setMBFS(mbfs); + + client.setSession(session_config); + +#if !defined(ESP_MAIL_DISABLE_SSL) + + if (client.getCertType() == esp_mail_cert_type_undefined || session_config->cert_updated) + { + if (session_config->certificate.cert_file.length() > 0 || session_config->certificate.cert_data != NULL || session_config->cert_ptr > 0) + { + client.setClockReady(timeStatus); + } + + if (session_config->certificate.cert_file.length() == 0) + { + if (session_config->cert_ptr > 0) + client.setCACert(reinterpret_cast(session_config->cert_ptr)); + else if (session_config->certificate.cert_data != NULL) + client.setCACert(session_config->certificate.cert_data); + else + client.setCACert(NULL); + } + else + { + if (!client.setCertFile(session_config->certificate.cert_file.c_str(), mbfs_type session_config->certificate.cert_file_storage_type)) + client.setCACert(NULL); + } + session_config->cert_updated = false; + } +#endif +} + +void ESP_Mail_Client::appendMultipartContentType(MB_String &buf, esp_mail_multipart_types type, const char *boundary) +{ + bool firstProp = true; + appendHeaderField(buf, message_headers[esp_mail_message_header_field_content_type].text, multipart_types[type].text, false, false); + appendHeaderProp(buf, esp_mail_str_90 /* "boundary" */, boundary, firstProp, false, true, true); + appendNewline(buf); +} + +String ESP_Mail_Client::errorReason(bool isSMTP, int errorCode, const char *msg) +{ + MB_String ret; + +#if defined(ENABLE_ERROR_STRING) && !defined(SILENT_MODE) + + // If there is server meanningful response (msg) is available, return it instead + if (strlen(msg) > 0) + return msg; + + // The error code enums were defined in ESP_Mail_Error.h and MB_FS.h. + switch (errorCode) + { + + case TCP_CLIENT_ERROR_CONNECTION_REFUSED: + ret = esp_mail_error_network_str_7; /* "connection refused" */ + break; + case TCP_CLIENT_ERROR_SEND_DATA_FAILED: + ret = esp_mail_error_network_str_8; /* "data sending failed" */ + break; + case TCP_CLIENT_ERROR_NOT_INITIALIZED: + ret = esp_mail_error_client_str_1; /* "client and/or necessary callback functions are not yet assigned" */ + break; + case TCP_CLIENT_ERROR_NOT_CONNECTED: + ret = esp_mail_error_network_str_4; /* "not connected" */ + break; + + case MAIL_CLIENT_ERROR_CONNECTION_CLOSED: + ret = esp_mail_error_network_str_6; /* "connection closed" */ + break; + case MAIL_CLIENT_ERROR_READ_TIMEOUT: + ret = esp_mail_error_network_str_3; /* "response read timed out" */ + break; + case MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP: + ret = esp_mail_error_ssl_str_1; /* "fail to set up the SSL/TLS structure" */ + break; + case MAIL_CLIENT_ERROR_OUT_OF_MEMORY: + ret = esp_mail_error_mem_str_8; /* "out of memory" */ + break; + case MAIL_CLIENT_ERROR_NTP_TIME_SYNC_TIMED_OUT: + ret = esp_mail_error_network_str_2; /* "NTP server time reading timed out" */ + break; + case MAIL_CLIENT_ERROR_SESSION_CONFIG_WAS_NOT_ASSIGNED: + ret = esp_mail_error_session_str_1; /* "the Session_Config object was not assigned" */ + break; + case MAIL_CLIENT_ERROR_TIME_WAS_NOT_SET: + ret = esp_mail_error_time_str_1; /* "library or device time was not set" */ + break; + case MAIL_CLIENT_ERROR_NOT_YET_LOGIN: + ret = esp_mail_error_auth_str_3; /* "not yet log in" */ + break; + case MAIL_CLIENT_ERROR_BUFFER_OVERFLOW: + ret = esp_mail_error_mem_str_9; /* "buffer overflow" */ + break; + +#if defined(ENABLE_SMTP) + case SMTP_STATUS_SERVER_CONNECT_FAILED: + ret = esp_mail_error_network_str_1; /* "unable to connect to server" */ + break; + case SMTP_STATUS_SMTP_GREETING_GET_RESPONSE_FAILED: + ret = esp_mail_error_smtp_str_1; /* "SMTP server greeting failed" */ + break; + case SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED: + ret = esp_mail_error_smtp_str_1; /* "SMTP server greeting failed" */ + break; + case SMTP_STATUS_AUTHEN_NOT_SUPPORT: + ret = esp_mail_error_auth_str_1; /* "the provided SASL authentication mechanism is not support" */ + break; + case SMTP_STATUS_AUTHEN_FAILED: + ret = esp_mail_error_smtp_str_2; /* "authentication failed" */ + break; + case SMTP_STATUS_USER_LOGIN_FAILED: + ret = esp_mail_error_smtp_str_2; /* "authentication failed" */ + break; + case SMTP_STATUS_PASSWORD_LOGIN_FAILED: + ret = esp_mail_error_smtp_str_3; /* "login password is not valid" */ + break; + case SMTP_STATUS_SEND_HEADER_SENDER_FAILED: + ret = esp_mail_error_smtp_str_4; /* "send header failed" */ + break; + case SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED: + ret = esp_mail_error_smtp_str_9; /* "set recipient failed" */ + break; + case SMTP_STATUS_SEND_BODY_FAILED: + ret = esp_mail_error_smtp_str_5; /* "send body failed" */ + break; + case SMTP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED: + ret = esp_mail_error_auth_str_2; /* "OAuth2.0 log in was disabled for this server" */ + break; + case SMTP_STATUS_NO_VALID_RECIPIENTS_EXISTED: + ret = esp_mail_error_smtp_str_8; /* "some of the recipient Email address is not valid" */ + break; + case SMTP_STATUS_NO_VALID_SENDER_EXISTED: + ret = esp_mail_error_smtp_str_7; /* "sender Email address is not valid" */ + break; + case SMTP_STATUS_NO_SUPPORTED_AUTH: + ret = esp_mail_error_auth_str_1; /* "the provided SASL authentication mechanism is not support" */ + break; + case SMTP_STATUS_SEND_CUSTOM_COMMAND_FAILED: + ret = esp_mail_error_smtp_str_10; /* "send custom command failed" */ + break; + case SMTP_STATUS_XOAUTH2_AUTH_FAILED: + ret = esp_mail_error_smtp_str_11; /* "XOAuth2 authenticate failed" */ + break; + case SMTP_STATUS_UNDEFINED: + ret = esp_mail_error_smtp_str_12; /* "undefined error" */ + break; +#endif + +#if defined(ENABLE_IMAP) + case IMAP_STATUS_SERVER_CONNECT_FAILED: + ret = esp_mail_error_network_str_1; /* "unable to connect to server" */ + break; + case IMAP_STATUS_IMAP_RESPONSE_FAILED: + ret = esp_mail_error_imap_str_18; /* "server replied NO or BAD response" */ + break; + case IMAP_STATUS_AUTHENTICATE_FAILED: + ret = esp_mail_error_imap_str_19; /* "authenticate failed" */ + break; + case IMAP_STATUS_BAD_COMMAND: + ret = esp_mail_error_imap_str_17; /* "could not parse command" */ + break; + case IMAP_STATUS_STORE_FAILED: + ret = esp_mail_error_imap_str_20; /* "flags or keywords store failed" */ + break; + case IMAP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED: + ret = esp_mail_error_imap_str_21; /* "server is not support OAuth2 login" */ + break; + case IMAP_STATUS_NO_MESSAGE: + ret = esp_mail_error_imap_str_5; /* "some of the requested messages no longer exist" */ + break; + case IMAP_STATUS_ERROR_DOWNLAD_TIMEOUT: + ret = esp_mail_error_network_str_5; /* "connection timeout" */ + break; + case IMAP_STATUS_CLOSE_MAILBOX_FAILED: + ret = esp_mail_error_imap_str_3; /* "fail to close the mailbox" */ + break; + case IMAP_STATUS_OPEN_MAILBOX_FAILED: + ret = esp_mail_error_imap_str_4; /* "fail to open the mailbox" */ + break; + case IMAP_STATUS_LIST_MAILBOXS_FAILED: + ret = esp_mail_error_imap_str_1; /* "fail to list the mailboxes" */ + break; + case IMAP_STATUS_CHECK_CAPABILITIES_FAILED: + ret = esp_mail_error_imap_str_2; /* "fail to check the capabilities" */ + break; + case IMAP_STATUS_NO_SUPPORTED_AUTH: + ret = esp_mail_error_auth_str_1; /* "the provided SASL authentication mechanism is not support" */ + break; + case IMAP_STATUS_NO_MAILBOX_FOLDER_OPENED: + ret = esp_mail_error_imap_str_5; /* "no mailbox opened" */ + break; + case IMAP_STATUS_FIRMWARE_UPDATE_INIT_FAILED: + ret = esp_mail_error_imap_str_6; /* "firmware update initialization failed" */ + break; + case IMAP_STATUS_FIRMWARE_UPDATE_WRITE_FAILED: + ret = esp_mail_error_imap_str_7; /* "firmware update write failed" */ + break; + case IMAP_STATUS_FIRMWARE_UPDATE_END_FAILED: + ret = esp_mail_error_imap_str_8; /* "firmware update finalize failed" */ + break; + case IMAP_STATUS_CHANGEDSINC_MODSEQ_TEST_FAILED: + ret = esp_mail_error_imap_str_14; /* "no message changed since (assigned) modsec" */ + break; + case IMAP_STATUS_MODSEQ_WAS_NOT_SUPPORTED: + ret = esp_mail_error_imap_str_15; /* "CONDSTORE was not supported or modsec was not supported for selected mailbox" */ + break; + +#endif + +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) + + case MB_FS_ERROR_FILE_IO_ERROR: + ret = esp_mail_error_mem_str_7; /* "file I/O error" */ + break; + case MB_FS_ERROR_FILE_NOT_FOUND: + ret = esp_mail_error_mem_str_6; /* "file not found." */ + break; + case MB_FS_ERROR_FLASH_STORAGE_IS_NOT_READY: + ret = esp_mail_error_mem_str_1; /* "flash Storage is not ready." */ + break; + case MB_FS_ERROR_SD_STORAGE_IS_NOT_READY: + ret = esp_mail_error_mem_str_2; /* "SD Storage is not ready." */ + break; + case MB_FS_ERROR_FILE_STILL_OPENED: + ret = esp_mail_error_mem_str_5; /* "file is still opened." */ + break; + +#endif + default: + break; + } + +#endif + + return ret.c_str(); +} + +template +void ESP_Mail_Client::closeTCPSession(T sessionPtr) +{ + if (!sessionPtr) + return; + + sessionPtr->client.stop(); + + _lastReconnectMillis = millis(); + + memset(sessionPtr->_auth_capability, 0, esp_mail_auth_capability_maxType); + memset(sessionPtr->_feature_capability, 0, + sessionPtr->_sessionType == esp_mail_session_type_smtp +#if defined(ENABLE_SMTP) + ? (int)esp_mail_smtp_send_capability_maxType +#else + ? 0 +#endif + : (int)esp_mail_imap_read_capability_maxType); + + sessionPtr->_authenticated = false; + sessionPtr->_loginStatus = false; +} + +template +bool ESP_Mail_Client::connected(T sessionPtr) +{ + return sessionPtr->client.connected(); +} + +size_t ESP_Mail_Client::getReservedLen(size_t len) +{ + return mbfs->getReservedLen(len); +} + +template +T ESP_Mail_Client::allocMem(size_t size, bool clear) +{ + return reinterpret_cast(mbfs->newP(size, clear)); +} + +void ESP_Mail_Client::freeMem(void *ptr) +{ + mbfs->delP(ptr); +} + +bool ESP_Mail_Client::strcmpP(const char *buf, int ofs, PGM_P beginToken, bool caseSensitive) +{ + if (ofs < 0) + { + int p = strposP(buf, beginToken, 0, caseSensitive); + if (p == -1) + return false; + ofs = p; + } + + char *tmp2 = allocMem(strlen_P(beginToken) + 1); + memcpy(tmp2, &buf[ofs], strlen_P(beginToken)); + tmp2[strlen_P(beginToken)] = 0; + MB_String s = beginToken; + bool ret = (strcasecmp(s.c_str(), tmp2) == 0); + // release memory + freeMem(&tmp2); + return ret; +} + +int ESP_Mail_Client::strposP(const char *buf, PGM_P beginToken, int ofs, bool caseSensitive) +{ + MB_String s = beginToken; + return strpos(buf, s.c_str(), ofs, caseSensitive); +} + +char *ESP_Mail_Client::strP(PGM_P pgm) +{ + size_t len = strlen_P(pgm) + 1; + char *buf = allocMem(len); + strcpy_P(buf, pgm); + buf[len - 1] = 0; + return buf; +} + +char *ESP_Mail_Client::strP2Lower(PGM_P pgm) +{ + size_t len = strlen_P(pgm) + 1; + char *buf = allocMem(len); + strcpy_P(buf, pgm); + + for (char *p = buf; *p; p++) + { + *p = tolower(*p); + } + + buf[len - 1] = 0; + return buf; +} + +void ESP_Mail_Client::strReplaceP(MB_String &buf, PGM_P name, PGM_P value) +{ + char *n = strP(name); + char *v = strP(value); + + buf.replaceAll(n, v); + + freeMem(&n); + freeMem(&v); +} + +bool ESP_Mail_Client::isOAuthError(char *buf, int bufLen, int &chunkIdx, int ofs) +{ + bool ret = false; + if (chunkIdx == 0) + { + size_t olen; + unsigned char *decoded = decodeBase64((const unsigned char *)(buf + ofs), bufLen - ofs, &olen); + if (decoded) + { + ret = strposP((char *)decoded, esp_mail_str_44 /* "{\"status\":" */, 0) > -1; + freeMem(&decoded); + } + chunkIdx++; + } + return ret; +} + +MB_String ESP_Mail_Client::getXOAUTH2String(const MB_String &email, const MB_String &accessToken) +{ + MB_String raw = esp_mail_str_45; /* "user=" */ + raw += email; + raw += esp_mail_str_46; /* "\1auth=Bearer " */ + raw += accessToken; + raw += esp_mail_str_43; /* "\1\1" */ + return encodeBase64Str((const unsigned char *)raw.c_str(), raw.length()); +} + +unsigned char *ESP_Mail_Client::decodeBase64(const unsigned char *src, size_t len, size_t *out_len) +{ + unsigned char *out, *pos, block[4], tmp; + size_t i, count, olen; + int pad = 0; + size_t extra_pad; + + unsigned char *dtable = allocMem(256); + + memset(dtable, 0x80, 256); + + for (i = 0; i < sizeof(b64_index_table) - 1; i++) + dtable[b64_index_table[i]] = (unsigned char)i; + dtable['='] = 0; + + count = 0; + for (i = 0; i < len; i++) + { + if (dtable[src[i]] != 0x80) + count++; + } + + if (count == 0) + goto exit; + + extra_pad = (4 - count % 4) % 4; + + olen = (count + extra_pad) / 4 * 3; + + pos = out = allocMem(olen); + + if (out == NULL) + goto exit; + + count = 0; + + for (i = 0; i < len + extra_pad; i++) + { + unsigned char val; + + if (i >= len) + val = '='; + else + val = src[i]; + tmp = dtable[val]; + if (tmp == 0x80) + continue; + + if (val == '=') + pad++; + block[count] = tmp; + count++; + if (count == 4) + { + *pos++ = (block[0] << 2) | (block[1] >> 4); + *pos++ = (block[1] << 4) | (block[2] >> 2); + *pos++ = (block[2] << 6) | block[3]; + count = 0; + if (pad) + { + if (pad == 1) + pos--; + else if (pad == 2) + pos -= 2; + else + { + // release memory + free(out); + goto exit; + } + break; + } + } + } + + *out_len = pos - out; + // release memory + freeMem(&dtable); + return out; +exit: + // release memory + freeMem(&dtable); + return nullptr; +} + +MB_String ESP_Mail_Client::encodeBase64Str(const unsigned char *src, size_t len) +{ + return encodeBase64Str((uint8_t *)src, len); +} + +MB_String ESP_Mail_Client::encodeBase64Str(uint8_t *src, size_t len) +{ + MB_String outStr; + unsigned char *out, *pos; + const unsigned char *end, *in; + size_t olen = 4 * ((len + 2) / 3); + if (olen < len) + return outStr; + + outStr.resize(olen); + out = (unsigned char *)&outStr[0]; + + end = src + len; + in = src; + pos = out; + + while (end - in >= 3) + { + *pos++ = b64_index_table[in[0] >> 2]; + *pos++ = b64_index_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + *pos++ = b64_index_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; + *pos++ = b64_index_table[in[2] & 0x3f]; + in += 3; + } + + if (end - in) + { + *pos++ = b64_index_table[in[0] >> 2]; + if (end - in == 1) + { + *pos++ = b64_index_table[(in[0] & 0x03) << 4]; + *pos++ = '='; + } + else + { + *pos++ = b64_index_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + *pos++ = b64_index_table[(in[1] & 0x0f) << 2]; + } + *pos++ = '='; + } + + return outStr; +} + +#endif + +ESP_Mail_Client MailClient = ESP_Mail_Client(); + +#endif /* ESP_MAIL_CLIENT_CPP */ diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client.h index 69099a497..4f9286940 100644 --- a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client.h +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client.h @@ -1,2862 +1,2862 @@ -#ifndef ESP_MAIL_CLIENT_H -#define ESP_MAIL_CLIENT_H - -#include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30409) -#error "Mixed versions compilation." -#endif - -/** - * Mail Client Arduino Library for Arduino devices. - * - * Created August 28, 2023 - * - * This library allows Espressif's ESP32, ESP8266, SAMD and RP2040 Pico devices to send and read Email through the SMTP and IMAP servers. - * - * The MIT License (MIT) - * Copyright (c) 2023 K. Suwatchai (Mobizt) - * - * - * 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 "extras/RFC2047.h" -#include -#include - -#include -#include -#include - -#if __has_include() -#include -#endif - -#if __has_include() -#include -#endif - -#include "ESP_Mail_FS.h" -#include "ESP_Mail_Const.h" -#include "extras/MB_Time.h" - -#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) -#define ESP_MAIL_PRINTF ESP_MAIL_DEFAULT_DEBUG_PORT.printf -#else -#define ESP_MAIL_PRINTF MailClient.printf -#endif - -#if defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO) - -#define UPLOAD_CHUNKS_NUM 12 - -#if defined(ESP32) - -#define ESP_MAIL_MIN_MEM 70000 - -#elif defined(ESP8266) - -#define SD_CS_PIN 15 -#define ESP_MAIL_MIN_MEM 8000 - -#elif defined(MB_ARDUINO_PICO) - -#define ESP_MAIL_MIN_MEM 70000 -#define SD_CS_PIN PIN_SPI1_SS - -#endif - -#else - -#undef min -#undef max -#define ESP_MAIL_MIN_MEM 3000 -#define UPLOAD_CHUNKS_NUM 5 - -#ifdef __arm__ -// should use uinstd.h to define sbrk but Due causes a conflict -extern "C" char *sbrk(int incr); -#else // __ARM__ -extern char *__brkval; -#endif // __arm__ - -#endif - -#include "ESP_Mail_TCPClient.h" - -using namespace mb_string; - -class IMAPSession; -class SMTPSession; -class SMTP_Status; -class DownloadProgress; -class MessageData; - -#if defined(ENABLE_IMAP) - -class MessageList -{ -public: - friend class IMAPSession; - MessageList(){}; - ~MessageList() { clear(); }; - void add(int uid) - { - if (uid > 0) - _list.push_back(uid); - } - - void clear() { _list.clear(); } - -private: - _vectorImpl _list; -}; - -/* The class that provides the info of selected or opened mailbox folder */ -class SelectedFolderInfo -{ -public: - friend class ESP_Mail_Client; - friend class IMAPSession; - SelectedFolderInfo(){}; - ~SelectedFolderInfo() { clear(); }; - - /* Get the flags count for this mailbox */ - size_t flagCount(bool permanent = false) { return permanent ? _permanent_flags.size() : _flags.size(); }; - - /* Get the numbers of messages in this mailbox */ - size_t msgCount() { return _msgCount; }; - - /* Get the numbers of messages in this mailbox that recent flag was set */ - size_t recentCount() { return _recentCount; }; - - /* Get the order of message in number of message in this mailbox that reoved */ - /** - * The IMAP_Polling_Status has the properties e.g. type, messageNum, and argument. - * - * The type property is the type of status e.g.imap_polling_status_type_undefined, imap_polling_status_type_new_message, - * imap_polling_status_type_remove_message, and imap_polling_status_type_fetch_message. - * - * The messageNum property is message number or order from the total number of message that added, fetched or deleted. - * - * The argument property is the argument of commands e.g. FETCH - */ - IMAP_Polling_Status pollingStatus() { return _polling_status; }; - - /* Get the The unique identifier (UID) validity value */ - size_t uidValidity() { return _uidValidity; }; - - /* Get the predict next message UID */ - size_t nextUID() { return _nextUID; }; - - /* Get the index of first unseen message */ - size_t unseenIndex() { return _unseenMsgIndex; }; - - /* Get the highest modification sequence */ - uint64_t highestModSeq() { return strtoull(_highestModSeq.c_str(), NULL, 10); }; - - /* Check for the modification sequence supports */ - bool modSeqSupported() { return _highestModSeq.length() > 0 && !_nomodsec; }; - - /* Get the numbers of messages from search result based on the search criteria - */ - size_t searchCount() { return _searchCount; }; - - /* Get the numbers of messages to be stored in the ressult */ - size_t availableMessages() { return _availableItems; }; - - /* Get the flag argument at the specified index */ - String flag(size_t index, bool permanent = false) - { - size_t size = permanent ? _permanent_flags.size() : _flags.size(); - if (index < size) - return permanent ? _permanent_flags[index].c_str() : _flags[index].c_str(); - return ""; - } - -private: - void addFlag(const char *flag, bool permanent) - { - MB_String s = flag; - if (permanent) - _permanent_flags.push_back(s); - else - _flags.push_back(s); - }; - void clear() - { - for (size_t i = 0; i < _flags.size(); i++) - _flags[i].clear(); - _flags.clear(); - - for (size_t i = 0; i < _permanent_flags.size(); i++) - _permanent_flags[i].clear(); - _permanent_flags.clear(); - - _msgCount = 0; - _polling_status.argument.clear(); - _polling_status.messageNum = 0; - _polling_status.type = imap_polling_status_type_undefined; - _idleTimeMs = 0; - _searchCount = 0; - } - - size_t _msgCount = 0; - size_t _recentCount = 0; - size_t _uidValidity = 0; - size_t _nextUID = 0; - size_t _unseenMsgIndex = 0; - MB_String _highestModSeq; - size_t _searchCount = 0; - size_t _availableItems = 0; - unsigned long _idleTimeMs = 0; - bool _folderChanged = false; - bool _floderChangedState = false; - bool _nomodsec = false; - IMAP_Polling_Status _polling_status; - _vectorImpl _flags; - _vectorImpl _permanent_flags; -}; - -/* The class that provides the list of FolderInfo e.g. name, attributes and - * delimiter */ -class FoldersCollection -{ -public: - friend class ESP_Mail_Client; - friend class IMAPSession; - FoldersCollection(){}; - ~FoldersCollection() { clear(); }; - size_t size() { return _folders.size(); }; - - struct esp_mail_folder_info_item_t info(size_t index) - { - struct esp_mail_folder_info_item_t fd; - if (index < _folders.size()) - { - fd.name = _folders[index].name.c_str(); - fd.attributes = _folders[index].attributes.c_str(); - fd.delimiter = _folders[index].delimiter.c_str(); - } - return fd; - } - - esp_mail_folder_info_t operator[](size_t index) - { - if (index < _folders.size()) - return _folders[index]; - - return esp_mail_folder_info_t(); - } - -private: - void add(struct esp_mail_folder_info_t fd) { _folders.push_back(fd); }; - void clear() - { - for (size_t i = 0; i < _folders.size(); i++) - { - _folders[i].name.clear(); - _folders[i].attributes.clear(); - _folders[i].delimiter.clear(); - } - _folders.clear(); - } - _vectorImpl _folders; -}; - -/* The class that provides the list of IMAP_Quota_Root_Info e.g. resource name, used and limit */ -class IMAP_Quota_Roots_List -{ - friend class IMAPSession; - -public: - IMAP_Quota_Roots_List(){}; - ~IMAP_Quota_Roots_List() { clear(); }; - - size_t size() { return _quota_roots.size(); }; - - IMAP_Quota_Root_Info operator[](size_t index) - { - if (index < _quota_roots.size()) - return _quota_roots[index]; - - return IMAP_Quota_Root_Info(); - } - -private: - _vectorImpl _quota_roots; - - void add(IMAP_Quota_Root_Info v) - { - _quota_roots.push_back(v); - } - void clear() - { - _quota_roots.clear(); - } -}; - -/* The class that provides the list of IMAP_Namespaces */ -class IMAP_Namespaces -{ - friend class IMAPSession; - -public: - IMAP_Namespaces(){}; - ~IMAP_Namespaces() { clear(); }; - - size_t size() { return _ns_list.size(); }; - - IMAP_Namespace_Info operator[](size_t index) - { - if (index < _ns_list.size()) - return _ns_list[index]; - - return IMAP_Namespace_Info(); - } - -private: - _vectorImpl _ns_list; - - void add(IMAP_Namespace_Info v) - { - _ns_list.push_back(v); - } - void clear() - { - _ns_list.clear(); - } -}; - -/* The class that provides the list of IMAP_Namespaces */ -class IMAP_Rights_List -{ - friend class IMAPSession; - -public: - IMAP_Rights_List(){}; - ~IMAP_Rights_List() { clear(); }; - - size_t size() { return _rights_list.size(); }; - - IMAP_Rights_Info operator[](size_t index) - { - if (index < _rights_list.size()) - return _rights_list[index]; - - return IMAP_Rights_Info(); - } - -private: - _vectorImpl _rights_list; - - void add(IMAP_Rights_Info v) - { - _rights_list.push_back(v); - } - void clear() - { - _rights_list.clear(); - } -}; - -typedef struct esp_mail_imap_nanespace_list_t -{ - IMAP_Namespaces personal_namespaces; - IMAP_Namespaces other_users_namespaces; - IMAP_Namespaces shared_namespaces; -} IMAP_Namespaces_List; - -/* The class that provides the status of message feching and searching */ -class IMAP_Status -{ -public: - IMAP_Status(); - ~IMAP_Status(); - const char *info(); - bool success(); - void empty(); - friend class IMAPSession; - - MB_String _info; - bool _success = false; -}; - -typedef void (*imapStatusCallback)(IMAP_Status); -typedef void (*imapResponseCallback)(IMAP_Response); -typedef void (*MIMEDataStreamCallback)(MIME_Data_Stream_Info); -typedef void (*imapCharacterDecodingCallback)(IMAP_Decoding_Info *); - -#else - -enum esp_mail_imap_read_capability_types -{ - esp_mail_imap_read_capability_maxType -}; - -// Dummy class used in template functions (errorStatusCB). -class IMAPSession -{ -public: - struct IMAP_Status - { - public: - const char *info() { return ""; }; - bool success() { return false; }; - void empty(); - MB_String _info; - bool _success = false; - }; - - typedef void (*imapStatusCallback)(IMAP_Status); - MB_String errorReason() { return ""; } - bool _debug; - imapStatusCallback _statusCallback = nullptr; - void *_customCmdResCallback = nullptr; - esp_mail_session_type _sessionType = esp_mail_session_type_imap; - - struct esp_mail_imap_response_status_t - { - int errorCode = 0; - MB_String tag; - MB_String text; - MB_String status; - bool completed = false; - }; - - esp_mail_imap_response_status_t _responseStatus; - IMAP_Status _cbData; -}; -#endif - -#if defined(ENABLE_SMTP) - -/* The SMTP message class */ -class SMTP_Message -{ -public: - SMTP_Message() - { - text.content_type = "text/plain"; - html.content_type = "text/html"; - }; - - ~SMTP_Message() { clear(); }; - - void resetAttachItem(SMTP_Attachment &att) - { - att.blob.size = 0; - att.blob.data = nullptr; - att.file.path.clear(); - att.file.storage_type = esp_mail_file_storage_type_none; - att.descr.name.clear(); - att.descr.filename.clear(); - att.descr.transfer_encoding.clear(); - att.descr.content_encoding.clear(); - att.descr.mime.clear(); - att.descr.content_id.clear(); - att._int.att_type = esp_mail_att_type_none; - att._int.index = 0; - att._int.msg_uid = 0; - att._int.flash_blob = false; - att._int.xencoding = esp_mail_msg_xencoding_none; - att._int.parallel = false; - att._int.cid.clear(); - } - - void clear() - { - sender.name.clear(); - sender.email.clear(); - subject.clear(); - text.charSet.clear(); - text.content.clear(); - text.content_type.clear(); - text.embed.enable = false; - html.charSet.clear(); - html.content.clear(); - html.content_type.clear(); - html.embed.enable = false; - response.reply_to.clear(); - response.notify = esp_mail_smtp_notify::esp_mail_smtp_notify_never; - priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; - - for (size_t i = 0; i < _rcp.size(); i++) - { - _rcp[i].name.clear(); - _rcp[i].email.clear(); - } - - for (size_t i = 0; i < _cc.size(); i++) - _cc[i].email.clear(); - - for (size_t i = 0; i < _bcc.size(); i++) - _bcc[i].email.clear(); - - for (size_t i = 0; i < _hdr.size(); i++) - _hdr[i].clear(); - - for (size_t i = 0; i < _att.size(); i++) - { - _att[i].descr.filename.clear(); - _att[i].blob.data = nullptr; - _att[i].descr.mime.clear(); - _att[i].descr.name.clear(); - _att[i].blob.size = 0; - _att[i].descr.transfer_encoding.clear(); - _att[i].file.path.clear(); - _att[i].file.storage_type = esp_mail_file_storage_type_none; - } - - for (size_t i = 0; i < _parallel.size(); i++) - { - _parallel[i].descr.filename.clear(); - _parallel[i].blob.data = nullptr; - _parallel[i].descr.mime.clear(); - _parallel[i].descr.name.clear(); - _parallel[i].blob.size = 0; - _parallel[i].descr.transfer_encoding.clear(); - _parallel[i].file.path.clear(); - _parallel[i].file.storage_type = esp_mail_file_storage_type_none; - } - - _rcp.clear(); - _cc.clear(); - _bcc.clear(); - _hdr.clear(); - _att.clear(); - _parallel.clear(); - } - - /** Clear all the inline images - */ - void clearInlineimages() - { - for (int i = (int)_att.size() - 1; i >= 0; i--) - { - if (_att[i]._int.att_type == esp_mail_att_type_inline) - _att.erase(_att.begin() + i); - } - }; - - /* Clear all the attachments */ - void clearAttachments() - { - for (int i = (int)_att.size() - 1; i >= 0; i--) - { - if (_att[i]._int.att_type == esp_mail_att_type_attachment) - _att.erase(_att.begin() + i); - } - - for (int i = (int)_parallel.size() - 1; i >= 0; i--) - _parallel.erase(_parallel.begin() + i); - }; - - /** Clear all rfc822 message attachment - */ - void clearRFC822Messages() - { - for (int i = (int)_rfc822.size() - 1; i >= 0; i--) - { - _rfc822[i].clear(); - _rfc822.erase(_rfc822.begin() + i); - } - }; - - /** Clear the primary recipient mailboxes - */ - void clearRecipients() { _rcp.clear(); }; - - /** Clear the Carbon-copy recipient mailboxes - */ - void clearCc() { _cc.clear(); }; - - /** Clear the Blind-carbon-copy recipient mailboxes - */ - void clearBcc() { _bcc.clear(); }; - - /** Clear the custom message headers - */ - void clearHeader() { _hdr.clear(); }; - - /** Add attachment to the message - * - * @param att The SMTP_Attachment data item - */ - void addAttachment(SMTP_Attachment &att) - { - att._int.att_type = esp_mail_att_type_attachment; - att._int.parallel = false; - att._int.flash_blob = true; - _att.push_back(att); - }; - - /** Add parallel attachment to the message - * - * @param att The SMTP_Attachment data item - */ - void addParallelAttachment(SMTP_Attachment &att) - { - att._int.att_type = esp_mail_att_type_attachment; - att._int.parallel = true; - att._int.flash_blob = true; - _parallel.push_back(att); - }; - - /** Add inline image to the message - * - * @param att The SMTP_Attachment data item - */ - void addInlineImage(SMTP_Attachment &att) - { - att._int.flash_blob = true; - att._int.parallel = false; - att._int.att_type = esp_mail_att_type_inline; - att._int.cid = random(2000, 4000); - _att.push_back(att); - }; - - /** Add rfc822 message to the message - * - * @param msg The RFC822_Message class object - */ - void addMessage(SMTP_Message &msg) { _rfc822.push_back(msg); } - - /** Add the primary recipient mailbox to the message - * - * @param name The name of primary recipient - * @param email The Email address of primary recipient - */ - template - void addRecipient(T1 name, T2 email) - { - struct esp_mail_address_info_t rcp; - rcp.name = toStringPtr(name); - rcp.email = toStringPtr(email); - _rcp.push_back(rcp); - }; - - /** Add Carbon-copy recipient mailbox - * - * @param email The Email address of the secondary recipient - */ - template - void addCc(T email) - { - struct esp_mail_address_info_t cc; - cc.email = toStringPtr(email); - _cc.push_back(cc); - }; - - /** Add Blind-carbon-copy recipient mailbox - * - * @param email The Email address of the tertiary recipient - */ - template - void addBcc(T email) - { - struct esp_mail_address_info_t bcc; - bcc.email = toStringPtr(email); - _bcc.push_back(bcc); - }; - - /** Add the custom header to the message - * - * @param hdr The header name and value - */ - template - void addHeader(T hdr) - { - _hdr.push_back(MB_String().setPtr(toStringPtr(hdr))); - }; - - /* The message author config */ - struct esp_mail_address_info_t author; - - /* The message sender (agent or teansmitter) config */ - struct esp_mail_address_info_t sender; - - /* The topic of message */ - MB_String subject; - - /* The message type */ - byte type = esp_mail_msg_type_none; - - /* The PLAIN text message */ - esp_mail_plain_body_t text; - - /* The HTML text message */ - esp_mail_html_body_t html; - - /* The response config */ - struct esp_mail_smtp_msg_response_t response; - - /* The priority of the message */ - esp_mail_smtp_priority priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; - - /* The enable options */ - struct esp_mail_smtp_enable_option_t enable; - - /* The message from config */ - struct esp_mail_address_info_t from; - - /* The message identifier */ - MB_String messageID; - - /* The keywords or phrases, separated by commas */ - MB_String keywords; - - /* The comments about message */ - MB_String comments; - - /* The date of message */ - MB_String date; - - /* The field that contains the parent's message ID of the message to which this one is a reply */ - MB_String in_reply_to; - - /* The field that contains the parent's references (if any) and followed by the parent's message ID (if any) of the message to which this one is a reply */ - MB_String references; - - /* The timestamp value to replace in text */ - esp_mail_timestamp_value_t timestamp; - -private: - friend class ESP_Mail_Client; - _vectorImpl _rcp; - _vectorImpl _cc; - _vectorImpl _bcc; - _vectorImpl _hdr; - _vectorImpl _att; - _vectorImpl _parallel; - _vectorImpl _rfc822; -}; - -class SMTP_Status -{ -public: - friend class SMTPSession; - friend class ESP_Mail_Client; - - SMTP_Status(); - ~SMTP_Status(); - const char *info(); - bool success(); - void empty(); - size_t completedCount(); - size_t failedCount(); - -private: - MB_String _info; - bool _success = false; - size_t _sentSuccess = 0; - size_t _sentFailed = 0; -}; - -typedef void (*smtpStatusCallback)(SMTP_Status); -typedef void (*smtpResponseCallback)(SMTP_Response); - -#endif - -class ESP_Mail_Client -{ - -public: - ESP_Mail_Client() - { - mbfs = new MB_FS(); - }; - - ~ESP_Mail_Client() - { - if (mbfs) - delete mbfs; - mbfs = nullptr; - - wifi.clearAP(); - }; - -#if defined(ENABLE_SMTP) - /** Sending Email through the SMTP server - * - * @param smtp The pointer to SMTP session object which holds the data and the - * TCP client. - * @param msg The pointer to SMTP_Message class which contains the header, - * body, and attachments. - * @param closeSession The option to Close the SMTP session after sent. - * @return The boolean value indicates the success of operation. - */ - bool sendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession = true); -#endif - -#if defined(ENABLE_SMTP) && defined(ENABLE_IMAP) - /** Append message to the mailbox - * - * @param imap The pointer to IMAP session object which holds the data and the - * TCP client. - * @param msg The pointer to SMTP_Message class which contains the header, - * body, and attachments. - * @param lastAppend The last message to append (optional). In case of MULTIAPPEND extension - * is supported, set this to false will append messages in single APPEND command. - * @param flags The flags to set to this message (optional). - * @param dateTime The date/time to set to this message (optional). - * @return The boolean value indicates the success of operation. - */ - template - bool appendMessage(IMAPSession *imap, SMTP_Message *msg, bool lastAppend = true, T1 flags = "", T2 dateTime = "") { return mAppendMessage(imap, msg, lastAppend, toStringPtr(flags), toStringPtr(dateTime)); } -#endif - -#if defined(ENABLE_IMAP) - /** Reading Email through IMAP server. - * - * @param imap The pointer to IMAP session object which holds the data and - the TCP client. - - * @param closeSession The option to close the IMAP session after fetching or - searching the Email. - * @return The boolean value indicates the success of operation. - */ - bool readMail(IMAPSession *imap, bool closeSession = true); - - /** Set the argument to the Flags for the specified message. - * - * @param imap The pointer to IMAP session object which holds the data and the - * TCP client. - * @param msgUID The UID of the message. - * @param flags The flag list to set. - * @param closeSession The option to close the IMAP session after set flag. - * @param silent The option to ignore the response. - * @param modsequence The int32_t option for UNCHANGESINCE conditional test. - * @return The boolean value indicates the success of operation. - * - * The modsequence value can be used only if IMAP server supports Conditional STORE extension - * and the selected mailbox supports modsequences. - */ - template - bool setFlag(IMAPSession *imap, int msgUID, T flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(msgUID), toStringPtr(flags), esp_mail_imap_store_flag_type_set, closeSession, silent, true, modsequence); } - - /** Set the argument to the Flags for the specified message. - * - * @param imap The pointer to IMAP session object which holds the data and the - * TCP client. - * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. - * @param UID The option for sequenceSet whether it is UID or message sequence number. - * @param flags The flag list to set. - * @param closeSession The option to close the IMAP session after set flag. - * @param silent The option to ignore the response. - * @param modsequence The int32_t option for UNCHANGESINCE conditional test. - * @return The boolean value indicates the success of operation. - * - * The modsequence value can be used only if IMAP server supports Conditional STORE extension - * and the selected mailbox supports modsequences. - */ - template - bool setFlag(IMAPSession *imap, T1 sequenceSet, bool UID, T2 flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(sequenceSet), toStringPtr(flags), esp_mail_imap_store_flag_type_set, closeSession, silent, UID, modsequence); } - - /** Add the argument to the Flags for the specified message. - * - * @param imap The pointer to IMAP session object which holds the data and the - * TCP client. - * @param msgUID The UID of the message. - * @param flags The flag list to add. - * @param closeSession The option to close the IMAP session after add flag. - * @param silent The option to ignore the response. - * @param modsequence The int32_t option for UNCHANGESINCE conditional test. - * @return The boolean value indicates the success of operation. - * - * The modsequence value can be used only if IMAP server supports Conditional STORE extension - * and the selected mailbox supports modsequences. - */ - template - bool addFlag(IMAPSession *imap, int msgUID, T flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(msgUID), toStringPtr(flags), esp_mail_imap_store_flag_type_add, closeSession, silent, true, modsequence); } - - /** Add the argument to the Flags for the specified message. - * - * @param imap The pointer to IMAP session object which holds the data and the - * TCP client. - * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. - * @param UID The option for sequenceSet whether it is UID or message sequence number. - * @param flags The flag list to add. - * @param closeSession The option to close the IMAP session after set flag. - * @param silent The option to ignore the response. - * @param modsequence The int32_t option for UNCHANGESINCE conditional test. - * @return The boolean value indicates the success of operation. - * - * The modsequence value can be used only if IMAP server supports Conditional STORE extension - * and the selected mailbox supports modsequences. - */ - template - bool addFlag(IMAPSession *imap, T1 sequenceSet, bool UID, T2 flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(sequenceSet), toStringPtr(flags), esp_mail_imap_store_flag_type_add, closeSession, silent, UID, modsequence); } - - /** Remove the argument from the Flags for the specified message. - * - * @param imap The pointer to IMAP session object which holds the data and the - * TCP client. - * @param msgUID The UID of the message that flags to be removed. - * @param flags The flag list to remove. - * @param closeSession The option to close the IMAP session after remove flag. - * @param silent The option to ignore the response. - * @param modsequence The int32_t option for UNCHANGESINCE conditional test. - * @return The boolean value indicates the success of operation. - * - * The modsequence value can be used only if IMAP server supports Conditional STORE extension - * and the selected mailbox supports modsequences. - */ - template - bool removeFlag(IMAPSession *imap, int msgUID, T flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(msgUID), toStringPtr(flags), esp_mail_imap_store_flag_type_remove, closeSession, silent, true, modsequence); } - - /** Remove the argument from the Flags for the specified message. - * - * @param imap The pointer to IMAP session object which holds the data and the - * TCP client. - * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. - * @param UID The option for sequenceSet whether it is UID or message sequence number. - * @param flags The flag list to remove. - * @param closeSession The option to close the IMAP session after set flag. - * @param silent The option to ignore the response. - * @param modsequence The int32_t option for UNCHANGESINCE conditional test. - * @return The boolean value indicates the success of operation. - * - * The modsequence value can be used only if IMAP server supports Conditional STORE extension - * and the selected mailbox supports modsequences. - */ - template - bool removeFlag(IMAPSession *imap, T1 sequenceSet, bool UID, T2 flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(sequenceSet), toStringPtr(flags), esp_mail_imap_store_flag_type_remove, closeSession, silent, UID, modsequence); } - -#endif - - /** Reconnect WiFi or network if lost connection. - * - * @param reconnect The boolean to set/unset WiFi AP reconnection. - */ - void networkReconnect(bool reconnect); - - /* Obsoleted */ - void setUDPClient(void *client, float gmtOffset) {} - - /** Clear all WiFi access points assigned. - * - */ - void clearAP(); - - /** Add WiFi access point for non-ESP device to resume WiFi connection. - * - * @param ssid The WiFi SSID. - * @param password The WiFi password. - */ - void addAP(const String &ssid, const String &password); - - /** - * Formatted printing on debug port. - * - */ - void printf(const char *format, ...); - -#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) - - /** Initiate SD card with SPI port configuration. - * - * @param ss SPI Chip/Slave Select pin. - * @param sck SPI Clock pin. - * @param miso SPI MISO pin. - * @param mosi SPI MOSI pin. - * @param frequency The SPI frequency - * @return Boolean type status indicates the success of the operation. - */ - bool sdBegin(int8_t ss = -1, int8_t sck = -1, int8_t miso = -1, int8_t mosi = -1, uint32_t frequency = 4000000); - -#if defined(ESP8266) || defined(MB_ARDUINO_PICO) - - /** Initiate SD card with SD FS configurations (ESP8266 only). - * - * @param ss SPI Chip/Slave Select pin. - * @param sdFSConfig The pointer to SDFSConfig object (ESP8266 only). - * @return Boolean type status indicates the success of the operation. - */ - bool sdBegin(SDFSConfig *sdFSConfig); - -#endif - -#if defined(ESP32) - /** Initiate SD card with chip select and SPI configuration (ESP32 only). - * - * @param ss SPI Chip/Slave Select pin. - * @param spiConfig The pointer to SPIClass object for SPI configuartion. - * @param frequency The SPI frequency. - * @return Boolean type status indicates the success of the operation. - */ - bool sdBegin(int8_t ss, SPIClass *spiConfig = nullptr, uint32_t frequency = 4000000); -#endif - -#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) - /** Initiate SD card with SdFat SPI and pins configurations (with SdFat included only). - * - * @param sdFatSPIConfig The pointer to SdSpiConfig object for SdFat SPI configuration. - * @param ss SPI Chip/Slave Select pin. - * @param sck SPI Clock pin. - * @param miso SPI MISO pin. - * @param mosi SPI MOSI pin. - * @return Boolean type status indicates the success of the operation. - */ - bool sdBegin(SdSpiConfig *sdFatSPIConfig, int8_t ss = -1, int8_t sck = -1, int8_t miso = -1, int8_t mosi = -1); - - /** Initiate SD card with SdFat SDIO configuration (with SdFat included only). - * - * @param sdFatSDIOConfig The pointer to SdioConfig object for SdFat SDIO configuration. - * @return Boolean type status indicates the success of the operation. - */ - bool sdBegin(SdioConfig *sdFatSDIOConfig); - -#endif - -#endif - -#if defined(ESP32) && defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD_MMC) - /** Initialize the SD_MMC card (ESP32 only). - * - * @param mountpoint The mounting point. - * @param mode1bit Allow 1 bit data line (SPI mode). - * @param format_if_mount_failed Format SD_MMC card if mount failed. - * @return The boolean value indicates the success of operation. - */ - bool sdMMCBegin(const char *mountpoint = "/sdcard", bool mode1bit = false, bool format_if_mount_failed = false); -#endif - - /** Get free Heap memory. - * - * @return Free memory amount in byte. - */ - int getFreeHeap(); - - /** Get base64 encode string. - * - * @return String of base64 encoded string. - */ - template - String toBase64(T str) { return mGetBase64(toStringPtr(str)).c_str(); } - - MB_Time Time; - -#if defined(ENABLE_IMAP) - - // Get encoding type from character set string - esp_mail_char_decoding_scheme getEncodingFromCharset(const char *enc); - - // Decode Latin1 to UTF-8 - int decodeLatin1_UTF8(unsigned char *out, int *outlen, const unsigned char *in, int *inlen); - - // Decode TIS620 to UTF-8 - void decodeTIS620_UTF8(char *out, const char *in, size_t len); - - // handle rfc2047 Q (quoted printable) and B (base64) decodings - RFC2047_Decoder RFC2047Decoder; - -#endif - -private: - friend class SMTPSession; - friend class IMAPSession; - - MB_FS *mbfs = nullptr; - bool timeStatus = false; - time_t ts = 0; - bool networkAutoReconnect = true; - volatile bool networkStatus = false; - esp_mail_wifi_credentials_t wifi; - bool timezoneEnvSet = false; - - IMAPSession *imap = nullptr; - bool calDataLen = false; - uint32_t dataLen = 0; - uint32_t imap_ts = 0; - -#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) - - unsigned long _lastReconnectMillis = 0; - uint16_t _reconnectTimeout = ESP_MAIL_NETWORK_RECONNECT_TIMEOUT; - - // Resume network connection - void resumeNetwork(ESP_Mail_TCPClient *client); - - // Get the CRLF ending string w/wo CRLF included. Return the size of string read and the current octet read. - int readLine(ESP_Mail_TCPClient *client, char *buf, int bufLen, bool withLineBreak, int &count, bool &ovf, unsigned long timeoutSec, bool &isTimeout); - - // readLine with overflow handling. - template - bool readResponse(T sessionPtr, char *buf, int bufLen, int &readLen, bool withLineBreak, int &count, MB_String &ovfBuf); - - // Network reconnection and return the connection status - template - bool reconnect(T sessionPtr, unsigned long dataTime = 0, bool downloadRequest = false); - - // Send callback - template - void sendCB(T sessionPtr, PGM_P info = "", bool prependCRLF = false, bool success = false); - - // PGM string replacement - void strReplaceP(MB_String &buf, PGM_P key, PGM_P value); - - // Check for OAuth log in error response - bool isOAuthError(char *buf, int bufLen, int &chunkIdx, int ofs); - - // Get SASL XOAUTH2 string - MB_String getXOAUTH2String(const MB_String &email, const MB_String &accessToken); - - // Send error callback - template - void sendErrorCB(T sessionPtr, PGM_P info, bool prependCRLF = false, bool success = false); - - // Send the error status callback - template - void errorStatusCB(T1 sessionPtr, T2 sessionPtr2, int error, bool clearLastStatus); - - // Check response callback was assigned? - template - bool isResponseCB(T sessionPtr); - - // Print library info - template - void printLibInfo(T sessionPtr); - - // Begin server connection - template - bool beginConnection(Session_Config *session_config, T sessionPtr, bool secureMode); - - // Prepare system time - template - bool prepareTime(Session_Config *session_config, T sessionPtr); - - // Check for session. Close session If not ready. - template - bool sessionReady(T sessionPtr); - - // Set cert data - void setCert(Session_Config *session_cfg, const char *ca); - // Set secure data - void setSecure(ESP_Mail_TCPClient &client, Session_Config *session_config); - - void appendMultipartContentType(MB_String &buf, esp_mail_multipart_types type, const char *boundary); - - String errorReason(bool isSMTP, int errorCode, const char *msg); - - // Close TCP session and clear auth_capability, read/send_capability, connected and authenticate statuses - template - void closeTCPSession(T sessionPtr); - - // Get and set timezone - void getSetTimezoneEnv(const char *TZ_file, const char *TZ_Var); - - // Get TCP connected status - template - bool connected(T sessionPtr); - - // Get the memory allocation block size of multiple of 4 - size_t getReservedLen(size_t len); - - // Check Email for valid format - bool validEmail(const char *s); - - // Get random UID for SMTP content ID and IMAP attachment default file name - char *getRandomUID(); - - // Spit the string into token strings - void splitToken(const char *str, _vectorImpl &tk, const char *delim); - - // Decode base64 encoded string - unsigned char *decodeBase64(const unsigned char *src, size_t len, size_t *out_len); - - // Decode base64 encoded string - MB_String encodeBase64Str(const unsigned char *src, size_t len); - - // Decode base64 encoded string - MB_String encodeBase64Str(uint8_t *src, size_t len); - - // Decode base64 encoded string - MB_String mGetBase64(MB_StringPtr str); - - // Sub string - char *subStr(const char *buf, PGM_P beginToken, PGM_P endToken, int beginPos, int endPos = 0, bool caseSensitive = true); - - // Find string - int strpos(const char *haystack, const char *needle, int offset, bool caseSensitive = true); - - // Memory allocation - template - T allocMem(size_t size, bool clear = true); - - // Memory deallocation - void freeMem(void *ptr); - - // PGM string compare - bool strcmpP(const char *buf, int ofs, PGM_P beginToken, bool caseSensitive = true); - - // Find PGM string - int strposP(const char *buf, PGM_P beginToken, int ofs, bool caseSensitive = true); - - // Memory allocation for PGM string - char *strP(PGM_P pgm); - - // Memory allocation for PGM lower case string - char *strP2Lower(PGM_P pgm); - - // Set or sync device system time with NTP server - // Do not modify or remove - void setTime(const char *TZ_Var, const char *TZ_file, bool wait, bool debugProgress); - - // Set the device time zone via TZ environment variable - void setTimezone(const char *TZ_Var, const char *TZ_file); - - // Get TZ environment variable from file - // Do not modify or remove - void getTimezone(const char *TZ_file, MB_String &out); - - // Check the session existent - template - bool sessionExisted(T sessionPtr); - - // Send SMTP/IMAP callback - template - void sendCallback(T sessionPtr, PGM_P info, bool prependCRLF, bool success); - - // Send IMAP/SMTP response callback and print debug message - template - void printDebug(T sessionPtr, PGM_P cbMsg, PGM_P dbMsg, esp_mail_debug_tag_type type, bool prependCRLF, bool success); - - // Get header content from response based on the field name - bool getHeader(const char *buf, PGM_P beginToken, MB_String &out, bool caseSensitive); - - // Append header field to buffer - void appendHeaderField(MB_String &buf, const char *name, PGM_P value, bool comma, bool newLine, esp_mail_string_mark_type type = esp_mail_string_mark_type_none); - - // Append SMTP address header field - void appendAddressHeaderField(MB_String &buf, esp_mail_address_info_t &source, esp_mail_rfc822_header_field_types type, bool header, bool comma, bool newLine); - - // Append header field name to buffer - void appendHeaderName(MB_String &buf, const char *name, bool clear = false, bool lowercase = false, bool space = true); - - // Append lowercase string to buffer - void appendLowerCaseString(MB_String &buf, PGM_P value, bool clear = false); - - // Append header field property to buffer - void appendHeaderProp(MB_String &buf, PGM_P prop, const char *value, bool &firstProp, bool lowerCase, bool isString, bool newLine); - - // Append quote string to buffer - void appendString(MB_String &buf, PGM_P value, bool comma, bool newLine, esp_mail_string_mark_type type = esp_mail_string_mark_type_none); - - // Append list to buffer - template - void appendList(MB_String &buf, _vectorImpl &list); - - // Append space to buffer - void appendSpace(MB_String &buf); - - // Append space to buffer after value - void appendSpace(MB_String &buf, bool withTag, PGM_P value); - - // Append space to buffer after values - void appendSpace(MB_String &buf, bool withTag, int nunArgs, ...); - - // Append space to buffer before value - void prependSpace(MB_String &buf, PGM_P value); - - // Append dot to buffer - void appendDot(MB_String &buf); - - // Append IMAP string key value list - void appendImap4KeyValue(MB_String &buf, PGM_P key, PGM_P value); - - // Append dot to buffer before value - void prependDot(MB_String &buf, PGM_P value); - - // Join 2 strings to buffer with space - void joinStringSpace(MB_String &buf, bool withTag, int nunArgs, ...); - - // Join 2 strings to buffer with dot - void joinStringDot(MB_String &buf, int nunArgs, ...); - - // Append mask(*) string to buffer - void maskString(MB_String &buf, int len); - - // Append domain to buffer - void appendDomain(MB_String &buf, const char *domain); - - // Append embedded message header to buffer - void appendEmbedMessage(MB_String &buf, esp_mail_message_body_t &body, bool isHtml); - - // Append crlf to buffer - void appendNewline(MB_String &buf); - - // Append tag to the buffer - void appendTagSpace(MB_String &buf, PGM_P tag = NULL); - - // Print newline - void debugPrintNewLine(); - - // Send newline to callback - template - void callBackSendNewLine(T sessionPtr, bool success); - - // Print progress bar - void printProgress(int progress, int &lastProgress); - - // Get file extension with dot from MIME string - void getExtfromMIME(const char *mime, MB_String &ext); - - // Prepare ports - void preparePortFunction(Session_Config *session_config, bool isSMTP, bool &secure, bool &secureMode, bool &ssl); - - // Get operation config based on port and its protocol - void getPortFunction(uint16_t port, struct esp_mail_ports_functions &ports_functions, bool &secure, bool &secureMode, bool &ssl, bool &starttls); - -#endif - -#if defined(ENABLE_SMTP) - - // Encode Quoted Printable string - void encodeQP(const char *buf, char *out); - - // Add the soft line break to the long text line rfc 3676 - void formatFlowedText(MB_String &content); - - // Insert soft break - void softBreak(MB_String &content, const char *quoteMarks); - - // Get content type (MIME) from file extension - void getMIME(const char *ext, MB_String &mime); - - // Get content type (MIME) from file name - void mimeFromFile(const char *name, MB_String &mime); - - // Get MIME boundary string - MB_String getMIMEBoundary(size_t len); - - // Send Email function - bool mSendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession = true); - - // SMTP send data - size_t smtpSend(SMTPSession *smtp, PGM_P data, bool newline = false); - - // SMTP send data - size_t smtpSend(SMTPSession *smtp, int data, bool newline = false); - - // SMTP send data - size_t smtpSend(SMTPSession *smtp, uint8_t *data, size_t size); - - // Handle the error by sending callback and close session - bool handleSMTPError(SMTPSession *smtp, int err, bool ret = false); - - // Send parallel attachment RFC1521 - bool sendParallelAttachments(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary); - - // Send attachment - bool sendAttachments(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, bool parallel = false); - - // Send message content - bool sendContent(SMTPSession *smtp, SMTP_Message *msg, bool closeSession, bool rfc822MSG); - - // Send imap or smtp callback - void altSendCallback(SMTPSession *smtp, PGM_P cbMsg, PGM_P dbMsg, esp_mail_debug_tag_type type, bool prependCRLF, bool success); - - // Send message data - bool sendMSGData(SMTPSession *smtp, SMTP_Message *msg, bool closeSession, bool rfc822MSG); - - // Send RFC 822 message - bool sendRFC822Msg(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, bool closeSession, bool rfc822MSG); - - // Get RFC 822 message envelope - void getRFC822MsgEnvelope(SMTPSession *smtp, SMTP_Message *msg, MB_String &buf); - - // Append boundary string to buffer - void appendBoundaryString(MB_String &buf, const char *value, bool endMark, bool newLine); - - // Send BDAT command RFC 3030 - bool sendBDAT(SMTPSession *smtp, SMTP_Message *msg, int len, bool last); - - // Get transfer encoding - void getXEncoding(esp_mail_msg_xencoding &xencoding, const char *enc); - - // Set the unencoded xencoding enum for html, text and attachment from its xencoding string - void checkUnencodedData(SMTPSession *smtp, SMTP_Message *msg); - - // Check imap or smtp has callback set - bool altIsCB(SMTPSession *smtp); - - // Check imap or smtp has debug set - bool altIsDebug(SMTPSession *smtp); - - // Send BLOB attachment - bool sendBlobAttachment(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att); - - // Send file content - bool sendFile(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att); - - // Send imap or smtp storage error callback - void altSendStorageErrorCB(SMTPSession *smtp, int err); - - // Open file to send an attachment - bool openFileRead(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att, MB_String &buf, const MB_String &boundary, bool inlined); - - // Open text file or html file for to send message - bool openFileRead2(SMTPSession *smtp, SMTP_Message *msg, const char *path, esp_mail_file_storage_type storageType); - - // Send inline attachments - bool sendInline(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, byte type); - - // Send storage error callback - void sendStorageNotReadyError(SMTPSession *smtp, esp_mail_file_storage_type storageType); - - // Append message - bool mAppendMessage(IMAPSession *imap, SMTP_Message *msg, bool lastAppend, MB_StringPtr flags, MB_StringPtr dateTime); - - // Get numbers of attachment based on type - size_t numAtt(SMTPSession *smtp, esp_mail_attach_type type, SMTP_Message *msg); - - // Check for valid recipient Email - bool checkEmail(SMTPSession *smtp, SMTP_Message *msg); - - // Send text parts MIME message - bool sendPartText(SMTPSession *smtp, SMTP_Message *msg, byte type, const char *boundary); - - // Alternative string data sending to send imap APPEND data or smtp data - bool altSendData(MB_String &s, bool newLine, SMTPSession *smtp, SMTP_Message *msg, bool addSendResult, bool getResponse, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode); - - // Alternative bytes data sending to send imap APPEND data or smtp data - bool altSendData(uint8_t *data, size_t size, SMTPSession *smtp, SMTP_Message *msg, bool addSendResult, bool getResponse, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode); - - // Send MIME message - bool sendMSG(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary); - - // Get an attachment part header string - void getAttachHeader(MB_String &header, const MB_String &boundary, SMTP_Attachment *attach, size_t size, bool isInline); - - // Get RFC 8222 part header string - void getRFC822PartHeader(SMTPSession *smtp, MB_String &header, const MB_String &boundary); - - // Send BLOB type text part or html part MIME message - bool sendBlobBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type); - - // Send file type text part or html part MIME message - bool sendFileBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type); - - // Base64 and QP encodings for text and html messages and replace embeded attachment file name with content ID - void encodingText(SMTPSession *smtp, SMTP_Message *msg, uint8_t type, MB_String &content); - - // Blob or Stream available - int chunkAvailable(SMTPSession *smtp, esp_mail_smtp_send_base64_data_info_t &data_info); - - // Read chunk data of blob or file - int getChunk(SMTPSession *smtp, esp_mail_smtp_send_base64_data_info_t &data_info, unsigned char *rawChunk, bool base64); - - // Terminate chunk reading - void closeChunk(esp_mail_smtp_send_base64_data_info_t &data_info); - - // Get base64 encoded buffer or raw buffer - void getBuffer(bool base64, uint8_t *out, uint8_t *in, int &encodedCount, int &bufIndex, bool &dataReady, int &size, size_t chunkSize); - - // Send blob or file as base64 encoded chunk - bool sendBase64(SMTPSession *smtp, SMTP_Message *msg, esp_mail_smtp_send_base64_data_info_t &data_info, bool base64, bool report); - - // Save sending logs to file - void saveSendingLogs(SMTPSession *smtp, SMTP_Message *msg, bool result); - - // Get imap or smtp report progress var pointer - uint32_t altProgressPtr(SMTPSession *smtp); - - // Get SMTP response status (statusCode and text) - void getResponseStatus(const char *buf, esp_mail_smtp_status_code statusCode, int beginPos, struct esp_mail_smtp_response_status_t &status); - - // Parse SMTP authentication capability - void parseAuthCapability(SMTPSession *smtp, char *buf); - - // Add the sending result - bool addSendingResult(SMTPSession *smtp, SMTP_Message *msg, bool result, bool showResult); - - // Handle SMTP server authentication - bool smtpAuth(SMTPSession *smtp, bool &ssl); - - // Handle SMTP response - bool handleSMTPResponse(SMTPSession *smtp, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode); - - // Print the upload status to the debug port - void uploadReport(const char *filename, uint32_t pgAddr, int progress); - - // Get MB_FS object pointer - MB_FS *getMBFS(); - - // Set device system time - int setTimestamp(time_t ts); -#endif - -#if defined(ENABLE_IMAP) - - // Check if child part (part number string) is a member of the parent part (part number string) - // part number string format: .. - bool multipartMember(const MB_String &parent, const MB_String &child); - - // Decode string - int decodeChar(const char *s); - - // Decode Quoted Printable string - void decodeQP_UTF8(const char *buf, char *out); - - // Actually not decode because 7bit string is enencode string unless prepare valid 7bit string and do qp decoding - char *decode7Bit_UTF8(char *buf); - - // Actually not decode because 8bit string is enencode string unless prepare valid 8bit string - char *decode8Bit_UTF8(char *buf); - - // Decode string base on encoding - void decodeString(IMAPSession *imap, MB_String &string, const char *enc = ""); - - /** - * Encode a code point using UTF-8 - * - * @author Ondřej Hruška - * https://gist.github.com/MightyPork/52eda3e5677b4b03524e40c9f0ab1da5 - * - * @license MIT - * - * @param out - output buffer (min 5 characters), will be 0-terminated - * @param utf - code point 0-0x10FFFF - * @return number of bytes on success, 0 on failure (also produces U+FFFD, which uses 3 bytes) - */ - int encodeUnicode_UTF8(char *out, uint32_t utf); - - // Append headers fetch command - void appendHeadersFetchCommand(IMAPSession *imap, MB_String &cmd, int index, bool debug); - - // Append rfc822 headers fetch command - void appendRFC822HeadersFetchCommand(MB_String &cmd); - - // Get multipart MIME fetch command - bool getMultipartFechCmd(IMAPSession *imap, int msgIdx, MB_String &partText); - - // Fetch multipart MIME body header - bool fetchMultipartBodyHeader(IMAPSession *imap, int msgIdx); - - // Print body part fetching debug - void printBodyPartFechingDubug(IMAPSession *imap, const char *partNum, bool multiLevel); - - // Handle IMAP server authentication - bool imapAuth(IMAPSession *imap, bool &ssl); - - // Send IMAP command - bool sendFetchCommand(IMAPSession *imap, int msgIndex, esp_mail_imap_command cmdCase); - - // Send data - size_t imapSend(IMAPSession *imap, PGM_P data, bool newline = false); - - // Send data - size_t imapSend(IMAPSession *imap, int data, bool newline = false); - - // Send data - size_t imapSend(IMAPSession *imap, uint8_t *data, size_t size); - - // Log out - bool imapLogout(IMAPSession *imap); - - // Send storage error callback - void sendStorageNotReadyError(IMAPSession *imap, esp_mail_file_storage_type storageType); - - // Parse search response - int parseSearchResponse(IMAPSession *imap, esp_mail_imap_response_data &res, PGM_P tag, const char *key); - - // Parse header state - bool parseHeaderField(IMAPSession *imap, const char *buf, PGM_P beginToken, bool caseSensitive, struct esp_mail_message_header_t &header, int &headerState, int state); - - // Parse header response - void parseHeaderResponse(IMAPSession *imap, esp_mail_imap_response_data &res, bool caseSensitive = true); - - // Set the header based on state parsed - void collectHeaderField(IMAPSession *imap, char *buf, struct esp_mail_message_header_t &header, int state); - - // Get decoded header - bool getDecodedHeader(IMAPSession *imap, const char *buf, PGM_P beginToken, MB_String &out, bool caseSensitive); - - // Check attachment for firmware file - void checkFirmwareFile(IMAPSession *imap, const char *filename, struct esp_mail_message_part_info_t &part, bool defaultSize = false); - - // Parse part header response - void parsePartHeaderResponse(IMAPSession *imap, esp_mail_imap_response_data &res, bool caseSensitive = true); - - // Count char in string - int countChar(const char *buf, char find); - - // Store the value to string via its the pointer - bool storeStringPtr(IMAPSession *imap, uint32_t addr, MB_String &value, const char *buf); - - // Get part header properties - bool getPartHeaderProperties(IMAPSession *imap, const char *buf, PGM_P p, PGM_P e, bool num, MB_String &value, MB_String &old_value, esp_mail_char_decoding_scheme &scheme, bool caseSensitive); - - // Url decode for UTF-8 encoded header text - char *urlDecode(const char *str); - - // Reset the pointer to multiline response keeping string - void resetStringPtr(struct esp_mail_message_part_info_t &part); - - // Get current part - struct esp_mail_message_part_info_t *cPart(IMAPSession *imap); - - // Get current header - struct esp_mail_message_header_t *cHeader(IMAPSession *imap); - -#if !defined(MB_USE_STD_VECTOR) - // Decending sort - void numDecSort(_vectorImpl &arr); -#endif - - // Handle IMAP response - bool handleIMAPResponse(IMAPSession *imap, int errCode, bool closeSession); - - // Print the file download status via debug port - void downloadReport(IMAPSession *imap, int progress); - - // Print the message fetch status via debug port - void fetchReport(IMAPSession *imap, int progress, bool html); - - // Print the message search status via debug port - void searchReport(IMAPSession *imap, int progress); - - // Get current message num item - struct esp_mail_imap_msg_num_t cMSG(IMAPSession *imap); - - // Get current message Index - int cIdx(IMAPSession *imap); - - // Get IMAP response status e.g. OK, NO and Bad status enum value - esp_mail_imap_response_status imapResponseStatus(IMAPSession *imap, char *response, PGM_P tag); - - // Add header item to string buffer - void addHeaderItem(MB_String &str, esp_mail_message_header_t *header, bool json); - - // Get RFC822 header string pointer by index - int getRFC822HeaderPtr(int index, esp_mail_imap_rfc822_msg_header_item_t *header); - - // Add RFC822 headers to string buffer - void addRFC822Headers(MB_String &s, esp_mail_imap_rfc822_msg_header_item_t *header, bool json); - - // Add RFC822 header item to string buffer - void addRFC822HeaderItem(MB_String &s, esp_mail_imap_rfc822_msg_header_item_t *header, int index, bool json); - - // Add header string by name and value to string buffer - void addHeader(MB_String &s, const char *name, const char *s_value, int num_value, bool trim, bool isJson); - - // Save header string buffer to file - void saveHeader(IMAPSession *imap, bool json); - - // Send MIME stream to callback - void sendStreamCB(IMAPSession *imap, void *buf, size_t len, int chunkIndex, bool hrdBrk); - - // Prepare file path for saving - void prepareFilePath(IMAPSession *imap, MB_String &filePath, bool header); - - // Decode text and store it to buffer or file - void decodeText(IMAPSession *imap, esp_mail_imap_response_data &res); - - // Handle atachment parsing and download - bool parseAttachmentResponse(IMAPSession *imap, char *buf, esp_mail_imap_response_data &res); - - // Get List - char *getList(char *buf, bool &isList); - - // Parse mailbox folder open response - void parseFoldersResponse(IMAPSession *imap, char *buf, bool list); - - // Prepare alias (short name) file list for unsupported long file name filesystem - void prepareFileList(IMAPSession *imap, MB_String &filePath); - - // Parse capability response - bool parseCapabilityResponse(IMAPSession *imap, const char *buf, int &chunkIdx); - - // Parse Idle response - bool parseIdleResponse(IMAPSession *imap); - - // Append Fetch UID/Flags string to buffer - void appendFetchString(MB_String &buf, bool uid); - - // Parse command response - void parseCmdResponse(IMAPSession *imap, char *buf, PGM_P find); - - // Get flags - bool getFlags(IMAPSession *imap, char *buf, esp_mail_imap_response_types type); - - // Parse examine response - void parseExamineResponse(IMAPSession *imap, char *buf); - - // Handle the error by sending callback and close session - bool handleIMAPError(IMAPSession *imap, int err, bool ret); - - // Set Flag - bool mSetFlag(IMAPSession *imap, MB_StringPtr sequenceSet, MB_StringPtr flags, esp_mail_imap_store_flag_type type, bool closeSession, bool silent = false, bool UID = true, int32_t modsequence = -1); - -#endif -}; - -#if defined(ENABLE_IMAP) - -class IMAPSession -{ -public: - IMAPSession(Client *client); - IMAPSession(); - ~IMAPSession(); - - /** Set the tcp timeout. - * - * @param timeoutSec The tcp timeout in seconds. - */ - void setTCPTimeout(unsigned long timeoutSec); - - /** Assign custom Client from Arduino Clients. - * - * @param client The pointer to Arduino Client derived class e.g. WiFiClient, EthernetClient or GSMClient. - */ - void setClient(Client *client); - - /** Assign TinyGsm Clients. - * - * @param client The pointer to TinyGsmClient. - * @param modem The pointer to TinyGsm modem object. Modem should be initialized and/or set mode before transfering data. - * @param pin The SIM pin. - * @param apn The GPRS APN (Access Point Name). - * @param user The GPRS user. - * @param password The GPRS password. - */ - void setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password); - - /** Assign the callback function to handle the network connection for custom Client. - * - * @param networkConnectionCB The function that handles the network connection. - */ - void networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB); - - /** Assign the callback function to handle the network connection status acknowledgement. - * - * @param networkStatusCB The function that handle the network connection status acknowledgement. - */ - void networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB); - - /** Set the network status acknowledgement. - * - * @param status The network status. - */ - void setNetworkStatus(bool status); - - /** Set the BearSSL IO buffer size. - * - * @param rx The BearSSL receive buffer size in bytes. - * @param tx The BearSSL trasmit buffer size in bytes. - */ - void setSSLBufferSize(int rx = -1, int tx = -1); - - /** Begin the IMAP server connection. - * - * @param session_config The pointer to Session_Config structured data that keeps - * the server and log in details. - * @param imap_data The pointer to IMAP_Data structured data that keeps the - * operation options. - * @param login The bool option for login after server connection. - * @return The boolean value which indicates the success of operation. - */ - bool connect(Session_Config *session_config, IMAP_Data *imap_data, bool login = true); - - /** Log in to IMAP server using Email and password. - * - * @param email The IMAP server account email. - * @param password The IMAP server account password. - * @return The boolean value which indicates the success of operation. - */ - template - bool loginWithPassword(T1 email, T2 password) { return mLogin(toStringPtr(email), toStringPtr(password), false); }; - - /** Log in to IMAP server using Email and access token. - * - * @param email The IMAP server account email. - * @param token The Access token to log in. - * @return The boolean value which indicates the success of operation. - */ - template - bool loginWithAccessToken(T1 email, T2 token) { return mLogin(toStringPtr(email), toStringPtr(token), true); }; - - /** Send the client identification to the server - * - * @param identification The pointer to IMAP_Identification structured data that keeps - * the key properties e.g., name, version, os, os_version, vendor, support_url, address, - * date, command, arguments, and environment. - */ - bool id(IMAP_Identification *identification); - - /** Return the server ID returns from ID command. - * @return The server ID string. - */ - String serverID(); - - /** Return the SASL authentication status. - * @return The boolean value indicates SASL authentication status. - */ - bool isAuthenticated(); - - /** Return the log status. - * @return The boolean value log in status. - */ - bool isLoggedIn(); - - /** Return firmware update result when attachment filename matches. - * @return The boolean value indicates the firmware update status. - */ - bool isFirmwareUpdateSuccess(); - - /** Begin the IMAP server connection without authentication. - * - * @param session_config The pointer to Session_Config structured data that keeps - * the server and log in details. - * @param callback The callback function that accepts IMAP_Response as parameter. - * @param tag The tag that pass to the callback function. - * @return The boolean value indicates the success of operation. - */ - template - bool customConnect(Session_Config *session_config, imapResponseCallback callback, T tag = "") { return mCustomConnect(session_config, callback, toStringPtr(tag)); }; - - /** Close the IMAP session. - * - * @return The boolean value which indicates the success of operation. - */ - bool closeSession(); - - /** Get TCP connection status. - * - * @return The boolean value indicates the connection status. - */ - bool connected(); - - /** Set to enable the debug. - * - * @param level The level to enable the debug message - * level = 0, no debugging - * level = 1, basic level debugging - */ - void debug(int level); - - /** Get the list of all the mailbox folders since the TCP session was opened - * and user was authenticated. - * - * @param folders The FoldersCollection class that contains the collection of - * the - * FolderInfo structured data. - * @return The boolean value which indicates the success of operation. - */ - bool getFolders(FoldersCollection &folders); - - /** Select or open the mailbox folder to search or fetch the message inside. - * - * @param folderName The known mailbox folder name. The default name is INBOX. - * @param readOnly The option to open the mailbox for read only. Set this - * option to false when you wish - * to modify the Flags using the setFlag, addFlag and removeFlag functions. - * @return The boolean value which indicates the success of operation. - * - * @note: the function will exit immediately and return true if the time since previous success folder selection (open) - * with the same readOnly mode, is less than 5 seconds. - */ - template - bool selectFolder(T folderName, bool readOnly = true) { return mSelectFolder(toStringPtr(folderName), readOnly); } - - /** Open the mailbox folder to read or search the mesages. - * - * @param folderName The name of known mailbox folder to be opened. - * @param readOnly The option to open the mailbox for reading only. Set this - * option to false when you wish - * to modify the flags using the setFlag, addFlag and removeFlag functions. - * @return The boolean value which indicates the success of operation. - * - * @note: the function will exit immediately and return true if the time since previous success folder selection (open) - * with the same readOnly mode, is less than 5 seconds. - */ - template - bool openFolder(T folderName, bool readOnly = true) { return mOpenFolder(toStringPtr(folderName), readOnly); } - - /** Close the mailbox folder that was opened. - * - * @param expunge The option to allow emty the deleted flag set messages in case folder was open with editable mode. - * @return The boolean value which indicates the success of operation. - */ - bool closeFolder(bool expunge = false) { return mCloseFolder(expunge); } - - /** Create folder. - * - * @param folderName The name of folder to create. - * @return The boolean value which indicates the success of operation. - */ - template - bool createFolder(T folderName) { return mCreateFolder(toStringPtr(folderName)); } - - /** Rename folder. - * - * @param currentFolderName The name of folder to rename. - * @param newFolderName The new name of folder to rename. - * @return The boolean value which indicates the success of operation. - */ - template - bool renameFolder(T1 currentFolderName, T2 newFolderName) { return mRenameFolder(toStringPtr(currentFolderName), toStringPtr(newFolderName)); } - - /** Delete folder. - * - * @param folderName The name of folder to delete. - * @return The boolean value which indicates the success of operation. - */ - template - bool deleteFolder(T folderName) { return mDeleteFolder(toStringPtr(folderName)); } - - /** Get subscribes mailboxes. - * - * @param reference The reference name. - * @param mailbox The mailbox name with possible wildcards. - * @param folders The return FoldersCollection that contains the folder info e.g., name, attribute and delimiter. - * @return The boolean value which indicates the success of operation. - */ - template - bool getSubscribesMailboxes(T1 reference, T2 mailbox, FoldersCollection &folders) { return mGetSubscribesMailboxes(toStringPtr(reference), toStringPtr(mailbox), folders); } - - /** Subscribe mailbox. - * - * @param folderName The name of folder to subscribe. - * @return The boolean value which indicates the success of operation. - */ - template - bool subscribe(T folderName) { return mSubscribe(toStringPtr(folderName)); } - - /** Unsubscribe mailbox. - * - * @param folderName The name of folder to unsubscribe. - * @return The boolean value which indicates the success of operation. - */ - template - bool unSubscribe(T folderName) { return mUnSubscribe(toStringPtr(folderName)); } - - /** Get UID number in selected or opened mailbox. - * - * @param msgNum The message number or order in the total message numbers. - * @return UID number in selected or opened mailbox. - * - * @note Returns 0 when fail to get UID. - */ - int getUID(int msgNum); - - /** Get message flags in selected or opened mailbox. - * - * @param msgNum The message number or order in the total message numbers. - * @return Message flags in selected or opened mailbox. - * - * @note Returns empty string when fail to get flags. - */ - const char *getFlags(int msgNum); - - /** Send the custom IMAP command and get the result via callback. - * - * @param cmd The command string. - * @param callback The callback function that accepts IMAP_Response as parameter. - * @param tag The tag string to pass to the callback function. - * @return The boolean value which indicates the success of operation. - * - * @note imap.connect and imap.selectFolder or imap.openFolder are needed to call once prior to call this function. - */ - template - bool sendCustomCommand(T1 cmd, imapResponseCallback callback, T2 tag = "") { return mSendCustomCommand(toStringPtr(cmd), callback, toStringPtr(tag)); } - - /** Send the custom IMAP command data string. - * - * @param data The string data. - * @param last The flag represents the last data to send (optional). - * @return The boolean value which indicates the success of operation. - * - * @note Should be used after calling sendCustomCommand("APPEND xxxxxx"); - */ - template - bool sendCustomData(T data, bool lastData = false) { return mSendData(toStringPtr(data), lastData, esp_mail_imap_cmd_custom); } - - /** Send the custom IMAP command data. - * - * @param data The byte data. - * @param size The data size. - * @param lastData The flag represents the last data to send (optional). - * @return The boolean value which indicates the success of operation. - * - * @note Should be used after calling ssendCustomCommand("APPEND xxxxxx"); - */ - bool sendCustomData(uint8_t *data, size_t size, bool lastData = false) { return mSendData(data, size, lastData, esp_mail_imap_cmd_custom); } - - /** Copy the messages to the defined mailbox folder. - * - * @param toCopy The pointer to the MessageList class that contains the - * list of messages to copy. - * @param dest The destination folder that the messages to copy to. - * @return The boolean value which indicates the success of operation. - */ - template - bool copyMessages(MessageList *toCopy, T dest) { return mCopyMessages(toCopy, toStringPtr(dest)); } - - /** Copy the messages to the defined mailbox folder. - * - * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. - * @param UID The option for sequenceSet whether it is UID or message sequence number. - * @param dest The destination folder that the messages to copy to. - * @return The boolean value indicates the success of operation. - */ - template - bool copyMessages(T1 sequenceSet, bool UID, T2 dest) { return mCopyMessagesSet(toStringPtr(sequenceSet), UID, toStringPtr(dest)); } - - /** Move the messages to the defined mailbox folder. - * - * @param toMove The pointer to the MessageList class that contains the - * list of messages to move. - * @param dest The destination folder that the messages to move to. - * @return The boolean value which indicates the success of operation. - */ - template - bool moveMessages(MessageList *toCopy, T dest) { return mMoveMessages(toCopy, toStringPtr(dest)); } - - /** Move the messages to the defined mailbox folder. - * - * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. - * @param UID The option for sequenceSet whether it is UID or message sequence number. - * @param dest The destination folder that the messages to move to. - * @return The boolean value indicates the success of operation. - */ - template - bool moveMessages(T1 sequenceSet, bool UID, T2 dest) { return mMoveMessagesSet(toStringPtr(sequenceSet), UID, toStringPtr(dest)); } - - /** Delete the messages in the opened mailbox folder. - * - * @param toDelete The pointer to the MessageList class that contains the - * list of messages to delete. - * @param expunge The boolean option to expunge all messages. - * @param modsequence The int32_t option for UNCHANGESINCE conditional test. - * @return The boolean value which indicates the success of operation. - * - * The modsequence value can be used only if IMAP server supports Conditional STORE extension - * and the selected mailbox supports modsequences. - */ - bool deleteMessages(MessageList *toDelete, bool expunge = false, int32_t modsequence = -1) { return mDeleteMessages(toDelete, expunge, modsequence); } - - /** Delete the messages in the opened mailbox folder. - * - * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. - * @param UID The option for sequenceSet whether it is UID or message sequence number. - * @param expunge The boolean option to expunge all messages. - * @param modsequence The int32_t option for UNCHANGESINCE conditional test. - * @return The boolean value which indicates the success of operation. - * - * The modsequence value can be used only if IMAP server supports Conditional STORE extension - * and the selected mailbox supports modsequences. - */ - template - bool deleteMessages(T sequenceSet, bool UID, bool expunge = false, int32_t modsequence = -1) { return mDeleteMessagesSet(toStringPtr(sequenceSet), UID, expunge, modsequence); } - - /** Get the quota root's resource usage and limits. - * - * @param quotaRoot The quota root to get. - * @param info The pointer to IMAP_Quota_Root_Info that contains quota root's resource name, usage and limit. - * @return The boolean value which indicates the success of operation. - */ - template - bool getQuota(T quotaRoot, IMAP_Quota_Root_Info *info) { return mGetSetQuota(toStringPtr(quotaRoot), info, true); } - - /** Set the quota root's resource usage and limits. - * - * @param quotaRoot The quota root to set. - * @param data The pointer to IMAP_Quota_Root_Info that contains quota root's resource name, usage and limit. - * @return The boolean value which indicates the success of operation. - */ - template - bool setQuota(T quotaRoot, IMAP_Quota_Root_Info *data) { return mGetSetQuota(toStringPtr(quotaRoot), data, false); } - - /** Get the list of quota roots for the named mailbox. - * - * @param mailbox The mailbox name. - * @param quotaRootsList The pointer to IMAP_Quota_Roots_List that contains the list of IMAP_Quota_Root_Info. - * @return The boolean value which indicates the success of operation. - */ - template - bool getQuotaRoot(T mailbox, IMAP_Quota_Roots_List *quotaRootsList) { return mGetQuotaRoots(toStringPtr(mailbox), quotaRootsList); } - - /** Get the ACLs for a mailbox. - * - * @param mailbox The mailbox name. - * @param aclList The pointer to the returning IMAP_Rights_List object. - * @return The boolean value which indicates the success of operation. - */ - template - bool getACL(T mailbox, IMAP_Rights_List *aclList) { return mManageACL(toStringPtr(mailbox), aclList, nullptr, toStringPtr(""), esp_mail_imap_cmd_get_acl); }; - - /** Get the ACLs for a mailbox. - * - * @param mailbox The mailbox name. - * @param acl The pointer to the acl IMAP_Rights_Info to set. - * @return The boolean value which indicates the success of operation. - */ - template - bool setACL(T mailbox, IMAP_Rights_Info *acl) { return mManageACL(toStringPtr(mailbox), nullptr, acl, toStringPtr(""), esp_mail_imap_cmd_set_acl); }; - - /** Delete the ACLs set for identifier on mailbox. - * - * @param mailbox The mailbox name. - * @param identifier The identifier (user) to remove the rights. - * @return The boolean value which indicates the success of operation. - */ - template - bool deleteACL(T1 mailbox, T2 identifier) { return mManageACL(toStringPtr(mailbox), nullptr, nullptr, toStringPtr(identifier), esp_mail_imap_cmd_delete_acl); }; - - /** Show my ACLs for a mailbox. - * - * @param mailbox The mailbox name. - * @param acl The pointer to the returning IMAP_Rights_Info object. - * @return The boolean value which indicates the success of operation. - */ - template - bool myRights(T mailbox, IMAP_Rights_Info *acl) { return mManageACL(toStringPtr(mailbox), nullptr, acl, toStringPtr(""), esp_mail_imap_cmd_my_rights); }; - - /** Returns IMAP namespaces. - * - * @param mailbox The mailbox name. - * @param ns The pointer to the returning IMAP_Namespaces_List object. - * @return The boolean value which indicates the success of operation. - */ - bool getNamespace(IMAP_Namespaces_List *ns) { return mNamespace(ns); }; - - /** Enable IMAP capability. - * - * @param capability The mailbox name. - * @return The boolean value which indicates the success of operation. - */ - template - bool enable(T capability) { return mEnable(toStringPtr(capability)); }; - - /** Listen for the selected or open mailbox for updates. - * @return The boolean value which indicates the success of operation. - */ - bool listen() { return mListen(false); }; - - /** Stop listen for the mailbox for updates. - * @return The boolean value which indicates the success of operation. - */ - bool stopListen() { return mStopListen(false); }; - - /** Check for the selected or open mailbox updates. - * @return The boolean value which indicates the changes status of mailbox. - */ - bool folderChanged(); - - /** Send NOOP command to IMAP server. - * @return The boolean value which indicates the success of operation. - */ - bool noop(); - - /** Assign the callback function that returns the operating status when - * fetching or reading the Email. - * - * @param imapCallback The function that accepts the imapStatusCallback as - * parameter. - */ - void callback(imapStatusCallback imapCallback); - - /** Assign the callback function to decode the string based on the character set. - * - * @param callback The function that accepts the pointer to IMAP_Decoding_Info as parameter. - */ - void characterDecodingCallback(imapCharacterDecodingCallback callback); - - /** Assign the callback function that returns the MIME data stream from - * fetching or reading the Email. - * - * @param mimeDataStreamCallback The function that accepts the MIME_Stream_Info as - * parameter. - */ - void mimeDataStreamCallback(MIMEDataStreamCallback mimeDataStreamCallback); - - /** Determine if no message body contained in the search result and only the - * message header is available. - */ - bool headerOnly(); - - /** Get the message list from search or fetch the Emails - * - * @return The IMAP_MSG_List structured data which contains text and html - * contents, - * attachments, inline images, embedded rfc822 messages details for each - * message. - */ - IMAP_MSG_List data(); - - /** Get the details of the selected or opned mailbox folder - * - * @return The SelectedFolderInfo class which contains the info about flags, - * total messages, next UID, - * search count and the available messages count. - */ - SelectedFolderInfo selectedFolder(); - - /** Get the error details when readingg the Emails - * - * @return The string of error details. - */ - String errorReason(); - - /** Get the operating status error code. - * - * @return The int value of operating status error code. - * - * The negative value indicated error. - * See src/ESP_Mail_Error.h and extras/MB_FS.h - */ - int errorCode(); - - /** Clear all the cache data stored in the IMAP session object. - */ - void empty(); - - /** Get the status of message fetching and searching. - * - * @return The IMAP_Status object contains the fetching and searching statuses. - */ - IMAP_Status status(); - - /** Get the JSON string of file name list of files that stored in SD card. - * - * @return The JSON string of filenames. - * @note This will available only when standard SD library was used and file storage is SD. - */ - String fileList(); - - /** Set the current timestamp. - * - * @param ts The current timestamp. - * @param gmtOffset The GMT offset. - */ - void setSystemTime(time_t ts, float gmtOffset = 0); - - /** Setup TCP KeepAlive for internal TCP client. - * - * @param tcpKeepIdleSeconds lwIP TCP Keepalive idle in seconds. - * @param tcpKeepIntervalSeconds lwIP TCP Keepalive interval in seconds. - * @param tcpKeepCount lwIP TCP Keepalive count. - * - * For the TCP (KeepAlive) options, see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/lwip.html#tcp-options. - * - * If value of one of these parameters is zero, the TCP KeepAlive will be disabled. - * - * You can check the server connecting status, by exexuting .connected() which will return true when connection to the server is still alive. - */ - void keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount); - - /** Get TCP KeepAlive status. - * - * @return Boolean status of TCP KeepAlive. - */ - bool isKeepAlive(); - - friend class ESP_Mail_Client; - friend class foldderList; - -private: - // Log in to IMAP server - bool mLogin(MB_StringPtr email, MB_StringPtr password, bool isToken); - - // Clear message data - void clearMessageData(); - - // Check for valid UID or set wildcard * as UID - void checkUID(); - - // Check for valid saving file path or prepend / - void checkPath(); - - // Get message item by index - void getMessages(uint16_t messageIndex, struct esp_mail_imap_msg_item_t &msg); - - // Get RFC822 message item by index - void getRFC822Messages(uint16_t messageIndex, struct esp_mail_imap_msg_item_t &msg); - - // Close mailbox - bool closeMailbox(bool expunge = false); - - // Open mailbox - bool openMailbox(MB_StringPtr folder, esp_mail_imap_auth_mode mode, bool waitResponse, bool unselect); - - // Get folders list - bool getMailboxes(FoldersCollection &folders); - - // Get subscribes mailboxes - bool mGetSubscribesMailboxes(MB_StringPtr reference, MB_StringPtr mailbox, FoldersCollection &folders); - - // Subscribe the mailbox - bool mSubscribe(MB_StringPtr folder); - - // Unsubscribe the mailbox - bool mUnSubscribe(MB_StringPtr folder); - - // Get UID - int mGetUID(int msgNum); - - // Fetch by sequence set - bool mFetchSequenceSet(); - - // Return string from TAG prepended command - MB_String prependTag(PGM_P cmd, PGM_P tag = NULL); - - // Check capabilities - bool checkCapabilities(); - - // Listen mailbox changes - bool mListen(bool recon); - - // Stop listen mailbox - bool mStopListen(bool recon); - - // Send custom command - bool mSendCustomCommand(MB_StringPtr cmd, imapResponseCallback callback, MB_StringPtr tag); - - // Send data after sending APPEND command - bool mSendData(MB_StringPtr data, bool lastData, esp_mail_imap_command cmd); - - // Send data after sending APPEND command - bool mSendData(uint8_t *data, size_t size, bool lastData, esp_mail_imap_command cmd); - - // Delete folder - bool mDeleteFolder(MB_StringPtr folderName); - - // Create folder - bool mCreateFolder(MB_StringPtr folderName); - - // Rename folder - bool mRenameFolder(MB_StringPtr currentFolderName, MB_StringPtr newFolderName); - - // Copy message - bool copyMsg(MessageList *toCopy, const char *sequenceSet, bool UID, MB_StringPtr dest); - - // Copy message - bool mCopyMessages(MessageList *toCopy, MB_StringPtr dest); - - // Copy message using sequence set - bool mCopyMessagesSet(MB_StringPtr sequenceSet, bool UID, MB_StringPtr dest); - - // Move message - bool moveMsg(MessageList *toMove, const char *sequenceSet, bool UID, MB_StringPtr dest); - - // Move message - bool mMoveMessages(MessageList *toMove, MB_StringPtr dest); - - // Move message using sequence set - bool mMoveMessagesSet(MB_StringPtr sequenceSet, bool UID, MB_StringPtr dest); - - // Check for conditional STORE extention support - bool isCondStoreSupported(); - - // Check for mailbox mod-sequence support - bool isModseqSupported(); - - // add UNCHANGEDSINCE STORE modifier and CHANGEDSINCE FETCH modifier to command - void addModifier(MB_String &cmd, esp_mail_imap_command_types type, int32_t modsequence); - - // Delete message - bool deleteMsg(MessageList *toDelete, const char *sequenceSet, bool UID, bool expunge, int32_t modsequence = -1); - - // Delete messages - bool mDeleteMessages(MessageList *toDelete, bool expunge = false, int32_t modsequence = -1); - - // Delete messages - bool mDeleteMessagesSet(MB_StringPtr sequenceSet, bool UID, bool expunge = false, int32_t modsequence = -1); - - // Get or set the quota root's resource usage and limits. - bool mGetSetQuota(MB_StringPtr quotaRoot, IMAP_Quota_Root_Info *data, bool getMode); - - // Parse the IMAP_Quota_Root_info - void mParseQuota(const char *quota, IMAP_Quota_Root_Info *data); - - // Get the list of quota roots for the named mailbox. - bool mGetQuotaRoots(MB_StringPtr mailbox, IMAP_Quota_Roots_List *quotaRootsList); - - // Get or set ACL. - bool mManageACL(MB_StringPtr mailbox, IMAP_Rights_List *acl_list, IMAP_Rights_Info *acl, MB_StringPtr identifier, esp_mail_imap_command type); - - // Parse ACL - void parseACL(MB_String &acl_str, IMAP_Rights_List *right_list); - - // parse Rights - void parseRights(MB_String &righs_str, IMAP_Rights_Info *info); - - // Get Rights from IMAP_Rights_Info - void getRights(MB_String &righs_str, IMAP_Rights_Info *info); - - // Get namespace - bool mNamespace(IMAP_Namespaces_List *ns); - - // Enable the IMAP capability - bool mEnable(MB_StringPtr capability); - - // Parse namespaces - void parseNamespaces(MB_String &ns_str, IMAP_Namespaces *ns); - - // Close folder - bool mCloseFolder(bool expunge = false); - - // Open folder - bool mOpenFolder(MB_StringPtr folderName, bool readOnly); - - // Select folder - bool mSelectFolder(MB_StringPtr folderName, bool readOnly); - - // Custom TCP connection - bool mCustomConnect(Session_Config *session_config, imapResponseCallback callback, MB_StringPtr tag); - - // Append ID list to buffer - void appendIdList(MB_String &list, IMAP_Identification *identification); - - // Handle connection - bool handleConnection(Session_Config *session_config, IMAP_Data *imap_data, bool &ssl); - - // Start TCP connection - bool connect(bool &ssl); - - // Print features not supported debug error message - void printDebugNotSupported(); - - bool _sessionSSL = false; - bool _sessionLogin = false; - bool _loginStatus = false; - unsigned long _last_polling_error_ms = 0; - unsigned long _last_host_check_ms = 0; - unsigned long _last_server_connect_ms = 0; - unsigned long _last_network_error_ms = 0; - unsigned long tcpTimeout = TCP_CLIENT_DEFAULT_TCP_TIMEOUT_SEC; - struct esp_mail_imap_response_status_t _responseStatus; - int _cMsgIdx = 0; - int _cPartIdx = 0; - int _totalRead = 0; - _vectorImpl _headers; - - esp_mail_imap_command _imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_sasl_login; - esp_mail_imap_command _prev_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_sasl_login; - esp_mail_imap_command _imap_custom_cmd = esp_mail_imap_cmd_custom; - esp_mail_imap_command _prev_imap_custom_cmd = esp_mail_imap_cmd_custom; - bool _idle = false; - MB_String _cmd; - _vectorImpl _multipart_levels; - int _rfc822_part_count = 0; - bool _unseen = false; - bool _readOnlyMode = true; - bool _msgDownload = false; - bool _attDownload = false; - bool _storageReady = false; - bool _storageChecked = false; - - bool _auth_capability[esp_mail_auth_capability_maxType]; - bool _feature_capability[esp_mail_imap_read_capability_maxType]; - Session_Config *_session_cfg; - _vectorImpl _configPtrList; - MB_String _currentFolder; - bool _mailboxOpened = false; - unsigned long _lastSameFolderOpenMillis = 0; - MB_String _nextUID; - MB_String _unseenMsgIndex; - MB_String _flags_tmp; - MB_String _quota_tmp; - MB_String _quota_root_tmp; - MB_String _acl_tmp; - MB_String _ns_tmp; - MB_String _server_id_tmp; - MB_String _sdFileList; - - struct esp_mail_imap_data_config_t *_imap_data = nullptr; - - int _userHeaderOnly = -1; - bool _headerOnly = true; - bool _uidSearch = false; - bool _headerSaved = false; - bool _debug = false; - int _debugLevel = 0; - bool _secure = false; - bool _authenticated = false; - bool _isFirmwareUpdated = false; - imapStatusCallback _statusCallback = NULL; - imapResponseCallback _customCmdResCallback = NULL; - MIMEDataStreamCallback _mimeDataStreamCallback = NULL; - imapCharacterDecodingCallback _charDecCallback = NULL; - - _vectorImpl _imap_msg_num; - esp_mail_session_type _sessionType = esp_mail_session_type_imap; - - FoldersCollection _folders; - SelectedFolderInfo _mbif; - int _uid_tmp = 0; - int _lastProgress = -1; - - ESP_Mail_TCPClient client; - - IMAP_Status _cbData; -}; - -#endif - -#if defined(ENABLE_SMTP) - -class SendingResult -{ -private: - _vectorImpl _result; - - void add(SMTP_Result *r) - { - _result.push_back(*r); - } - -public: - friend class SMTPSession; - friend class ESP_Mail_Client; - SendingResult(){}; - ~SendingResult() { clear(); }; - - void clear() - { - for (size_t i = 0; i < _result.size(); i++) - { - _result[i].recipients.clear(); - _result[i].subject.clear(); - _result[i].timestamp = 0; - _result[i].completed = false; - } - _result.clear(); - } - - SMTP_Result getItem(size_t index) - { - SMTP_Result r; - if (index < _result.size()) - return _result[index]; - return r; - } - size_t size() { return _result.size(); }; -}; - -class SMTPSession -{ -public: - SMTPSession(Client *client); - SMTPSession(); - ~SMTPSession(); - - /** Set the tcp timeout. - * - * @param timeoutSec The tcp timeout in seconds. - */ - void setTCPTimeout(unsigned long timeoutSec); - - /** Assign custom Client from Arduino Clients. - * - * @param client The pointer to Arduino Client derived class e.g. WiFiClient, EthernetClient or GSMClient. - */ - void setClient(Client *client); - - /** Assign TinyGsm Clients. - * - * @param client The pointer to TinyGsmClient. - * @param modem The pointer to TinyGsm modem object. Modem should be initialized and/or set mode before transfering data. - * @param pin The SIM pin. - * @param apn The GPRS APN (Access Point Name). - * @param user The GPRS user. - * @param password The GPRS password. - */ - void setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password); - - /** Assign the callback function to handle the network connection for custom Client. - * - * @param networkConnectionCB The function that handles the network connection. - */ - void networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB); - - /** Assign the callback function to handle the network connection status acknowledgement. - * - * @param networkStatusCB The function that handle the network connection status acknowledgement. - */ - void networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB); - - /** Set the network status acknowledgement. - * - * @param status The network status. - */ - void setNetworkStatus(bool status); - - /** Set the BearSSL IO buffer size. - * - * @param rx The BearSSL receive buffer size in bytes. - * @param tx The BearSSL trasmit buffer size in bytes. - */ - void setSSLBufferSize(int rx = -1, int tx = -1); - - /** Begin the SMTP server connection. - * - * @param session_config The pointer to Session_Config structured data that keeps - * the server and log in details. - * @param login The bool option for login after server connection. - * @return The boolean value indicates the success of operation. - */ - bool connect(Session_Config *session_config, bool login = true); - - /** Log in to SMTP server using Email and password. - * - * @param email The SMTP server account email. - * @param password The SMTP server account password. - * @return The boolean value which indicates the success of operation. - */ - template - bool loginWithPassword(T1 email, T2 password) { return mLogin(toStringPtr(email), toStringPtr(password), false); }; - - /** Log in to SMTP server using Email and access token. - * - * @param email The SMTP server account email. - * @param token The Access token to log in. - * @return The boolean value which indicates the success of operation. - */ - template - bool loginWithAccessToken(T1 email, T2 token) { return mLogin(toStringPtr(email), toStringPtr(token), true); }; - - /** Return the SASL authentication status. - * @return The boolean value indicates SASL authentication status. - */ - bool isAuthenticated(); - - /** Return the log status. - * @return The boolean value indicates log in status. - */ - bool isLoggedIn(); - - /** Begin the SMTP server connection without authentication. - * - * @param session_config The pointer to Session_Config structured data that keeps - * the server and log in details. - * @param callback The callback function that accepts the SMTP_Response as parameter. - * @param commandID The command identifier number that will pass to the callback. - * @return The int value of status code. - * - * @note If commandID was not set or set to -1, the command identifier will be auto increased started from zero. - */ - int customConnect(Session_Config *session_config, smtpResponseCallback callback, int commandID = -1); - - /** Close the SMTP session. - * - */ - bool closeSession(); - - /** Get TCP connection status. - * - * @return The boolean value indicates the connection status. - */ - bool connected(); - - /** Send the custom SMTP command and get the result via callback. - * - * @param cmd The command string. - * @param callback The function that accepts the SMTP_Response as parameter. - * @param commandID The command identifier number that will pass to the callback. - * @return The integer value of response code. - * - * @note smtp.connect or smtp.customConnect is needed to call once prior to call this function. - * - * If commandID was not set or set to -1, the command identifier will be auto increased started from zero. - */ - template - int sendCustomCommand(T cmd, smtpResponseCallback callback, int commandID = -1) { return mSendCustomCommand(toStringPtr(cmd), callback, commandID); } - - /** Send the custom SMTP command data string. - * - * @param data The string data. - * @return The boolean value which indicates the success of operation. - * - * @note Should be used after calling sendCustomCommand("DATA"); - */ - template - bool sendCustomData(T data) { return mSendData(toStringPtr(data)); } - - /** Send the custom SMTP command data. - * - * @param data The byte data. - * @param size The data size. - * @return The boolean value which indicates the success of operation. - * - * @note Should be used after calling sendCustomCommand("DATA"); - */ - bool sendCustomData(uint8_t *data, size_t size) { return mSendData(data, size); } - - /** Set to enable the debug. - * - * @param level The level to enable the debug message - * level = 0, no debugging - * level = 1, basic level debugging - */ - void debug(int level); - - /** Get the error details when sending the Email - * - * @return The string of error details. - */ - String errorReason(); - - /** Get the SMTP server response status code. - * - * @return The int value of SMTP server response status code. - * - * See RFC 5321 standard's documentation. - */ - int statusCode(); - - /** Get the SMTP server response status message. - * - * @return The int value of SMTP server response status message. - * - */ - String statusMessage(); - - /** Get the operating status error code. - * - * @return The int value of operating status error code. - * - * The negative value indicated error. - * See src/ESP_Mail_Error.h and extras/MB_FS.h - */ - int errorCode(); - - /** Set the Email sending status callback function. - * - * @param smtpCallback The callback function that accept the - * smtpStatusCallback param. - */ - void callback(smtpStatusCallback smtpCallback); - - /** Get the status of message fetching and searching. - * - * @return The SMTP_Status object contains the sending status. - */ - SMTP_Status status(); - - /** Set the current timestamp. - * - * @param ts The current timestamp. - * @param gmtOffset The GMT offset. - */ - void setSystemTime(time_t ts, float gmtOffset = 0); - - /** Setup TCP KeepAlive for internal TCP client. - * - * @param tcpKeepIdleSeconds lwIP TCP Keepalive idle in seconds. - * @param tcpKeepIntervalSeconds lwIP TCP Keepalive interval in seconds. - * @param tcpKeepCount lwIP TCP Keepalive count. - * - * For the TCP (KeepAlive) options, see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/lwip.html#tcp-options. - * - * If value of one of these parameters is zero, the TCP KeepAlive will be disabled. - * - * You can check the server connecting status, by exexuting .connected() which will return true when connection to the server is still alive. - */ - void keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount); - - /** Get TCP KeepAlive status. - * - * @return Boolean status of TCP KeepAlive. - */ - bool isKeepAlive(); - - SendingResult sendingResult; - - friend class ESP_Mail_Client; - -private: - bool _sessionSSL = false; - bool _sessionLogin = false; - struct esp_mail_smtp_response_status_t _responseStatus; - int _sentSuccessCount = 0; - int _sentFailedCount = 0; - bool _chunkedEnable = false; - int _chunkCount = 0; - uint32_t ts = 0; - unsigned long tcpTimeout = TCP_CLIENT_DEFAULT_TCP_TIMEOUT_SEC; - - esp_mail_smtp_command _smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_greeting; - - bool _auth_capability[esp_mail_auth_capability_maxType]; - bool _feature_capability[esp_mail_smtp_send_capability_maxType]; - - Session_Config *_session_cfg = NULL; - _vectorImpl _configPtrList; - - bool _debug = false; - int _debugLevel = 0; - bool _secure = false; - bool _authenticated = false; - bool _loginStatus = false; - bool _waitForAuthenticate = false; - bool _canForward = false; - smtpStatusCallback _statusCallback = NULL; - smtpResponseCallback _customCmdResCallback = NULL; - int _commandID = -1; - bool _sdStorageReady = false; - bool _flashStorageReady = false; - bool _sdStorageChecked = false; - bool _flashStorageChecked = false; - - esp_mail_session_type _sessionType = esp_mail_session_type_smtp; - SMTP_Status _cbData; - struct esp_mail_smtp_msg_type_t _msgType; - int _lastProgress = -1; - - ESP_Mail_TCPClient client; - - // Start TCP connection - bool connect(bool &ssl); - - // Log in to SMTP server - bool mLogin(MB_StringPtr email, MB_StringPtr password, bool isToken); - - // Handle TCP connection - bool handleConnection(Session_Config *session_config, bool &ssl); - - // Send custom command - int mSendCustomCommand(MB_StringPtr cmd, smtpResponseCallback callback, int commandID = -1); - - // Send data after sending DATA command - bool mSendData(MB_StringPtr data); - - // Send data after sending DATA command - bool mSendData(uint8_t *data, size_t size); -}; - -#endif - -#if defined(ENABLE_SMTP) && defined(ENABLE_IMAP) - -class ESP_Mail_Message : public SMTP_Message -{ -public: - ESP_Mail_Message(){}; - ~ESP_Mail_Message(){}; -}; - -#endif - -extern ESP_Mail_Client MailClient; - -#endif /* ESP_MAIL_CLIENT_H */ +#ifndef ESP_MAIL_CLIENT_H +#define ESP_MAIL_CLIENT_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +/** + * Mail Client Arduino Library for Arduino devices. + * + * Created August 28, 2023 + * + * This library allows Espressif's ESP32, ESP8266, SAMD and RP2040 Pico devices to send and read Email through the SMTP and IMAP servers. + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * 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 "extras/RFC2047.h" +#include +#include + +#include +#include +#include + +#if __has_include() +#include +#endif + +#if __has_include() +#include +#endif + +#include "ESP_Mail_FS.h" +#include "ESP_Mail_Const.h" +#include "extras/MB_Time.h" + +#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) +#define ESP_MAIL_PRINTF ESP_MAIL_DEFAULT_DEBUG_PORT.printf +#else +#define ESP_MAIL_PRINTF MailClient.printf +#endif + +#if defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO) + +#define UPLOAD_CHUNKS_NUM 12 + +#if defined(ESP32) + +#define ESP_MAIL_MIN_MEM 70000 + +#elif defined(ESP8266) + +#define SD_CS_PIN 15 +#define ESP_MAIL_MIN_MEM 8000 + +#elif defined(MB_ARDUINO_PICO) + +#define ESP_MAIL_MIN_MEM 70000 +#define SD_CS_PIN PIN_SPI1_SS + +#endif + +#else + +#undef min +#undef max +#define ESP_MAIL_MIN_MEM 3000 +#define UPLOAD_CHUNKS_NUM 5 + +#ifdef __arm__ +// should use uinstd.h to define sbrk but Due causes a conflict +extern "C" char *sbrk(int incr); +#else // __ARM__ +extern char *__brkval; +#endif // __arm__ + +#endif + +#include "ESP_Mail_TCPClient.h" + +using namespace mb_string; + +class IMAPSession; +class SMTPSession; +class SMTP_Status; +class DownloadProgress; +class MessageData; + +#if defined(ENABLE_IMAP) + +class MessageList +{ +public: + friend class IMAPSession; + MessageList(){}; + ~MessageList() { clear(); }; + void add(int uid) + { + if (uid > 0) + _list.push_back(uid); + } + + void clear() { _list.clear(); } + +private: + _vectorImpl _list; +}; + +/* The class that provides the info of selected or opened mailbox folder */ +class SelectedFolderInfo +{ +public: + friend class ESP_Mail_Client; + friend class IMAPSession; + SelectedFolderInfo(){}; + ~SelectedFolderInfo() { clear(); }; + + /* Get the flags count for this mailbox */ + size_t flagCount(bool permanent = false) { return permanent ? _permanent_flags.size() : _flags.size(); }; + + /* Get the numbers of messages in this mailbox */ + size_t msgCount() { return _msgCount; }; + + /* Get the numbers of messages in this mailbox that recent flag was set */ + size_t recentCount() { return _recentCount; }; + + /* Get the order of message in number of message in this mailbox that reoved */ + /** + * The IMAP_Polling_Status has the properties e.g. type, messageNum, and argument. + * + * The type property is the type of status e.g.imap_polling_status_type_undefined, imap_polling_status_type_new_message, + * imap_polling_status_type_remove_message, and imap_polling_status_type_fetch_message. + * + * The messageNum property is message number or order from the total number of message that added, fetched or deleted. + * + * The argument property is the argument of commands e.g. FETCH + */ + IMAP_Polling_Status pollingStatus() { return _polling_status; }; + + /* Get the The unique identifier (UID) validity value */ + size_t uidValidity() { return _uidValidity; }; + + /* Get the predict next message UID */ + size_t nextUID() { return _nextUID; }; + + /* Get the index of first unseen message */ + size_t unseenIndex() { return _unseenMsgIndex; }; + + /* Get the highest modification sequence */ + uint64_t highestModSeq() { return strtoull(_highestModSeq.c_str(), NULL, 10); }; + + /* Check for the modification sequence supports */ + bool modSeqSupported() { return _highestModSeq.length() > 0 && !_nomodsec; }; + + /* Get the numbers of messages from search result based on the search criteria + */ + size_t searchCount() { return _searchCount; }; + + /* Get the numbers of messages to be stored in the ressult */ + size_t availableMessages() { return _availableItems; }; + + /* Get the flag argument at the specified index */ + String flag(size_t index, bool permanent = false) + { + size_t size = permanent ? _permanent_flags.size() : _flags.size(); + if (index < size) + return permanent ? _permanent_flags[index].c_str() : _flags[index].c_str(); + return ""; + } + +private: + void addFlag(const char *flag, bool permanent) + { + MB_String s = flag; + if (permanent) + _permanent_flags.push_back(s); + else + _flags.push_back(s); + }; + void clear() + { + for (size_t i = 0; i < _flags.size(); i++) + _flags[i].clear(); + _flags.clear(); + + for (size_t i = 0; i < _permanent_flags.size(); i++) + _permanent_flags[i].clear(); + _permanent_flags.clear(); + + _msgCount = 0; + _polling_status.argument.clear(); + _polling_status.messageNum = 0; + _polling_status.type = imap_polling_status_type_undefined; + _idleTimeMs = 0; + _searchCount = 0; + } + + size_t _msgCount = 0; + size_t _recentCount = 0; + size_t _uidValidity = 0; + size_t _nextUID = 0; + size_t _unseenMsgIndex = 0; + MB_String _highestModSeq; + size_t _searchCount = 0; + size_t _availableItems = 0; + unsigned long _idleTimeMs = 0; + bool _folderChanged = false; + bool _floderChangedState = false; + bool _nomodsec = false; + IMAP_Polling_Status _polling_status; + _vectorImpl _flags; + _vectorImpl _permanent_flags; +}; + +/* The class that provides the list of FolderInfo e.g. name, attributes and + * delimiter */ +class FoldersCollection +{ +public: + friend class ESP_Mail_Client; + friend class IMAPSession; + FoldersCollection(){}; + ~FoldersCollection() { clear(); }; + size_t size() { return _folders.size(); }; + + struct esp_mail_folder_info_item_t info(size_t index) + { + struct esp_mail_folder_info_item_t fd; + if (index < _folders.size()) + { + fd.name = _folders[index].name.c_str(); + fd.attributes = _folders[index].attributes.c_str(); + fd.delimiter = _folders[index].delimiter.c_str(); + } + return fd; + } + + esp_mail_folder_info_t operator[](size_t index) + { + if (index < _folders.size()) + return _folders[index]; + + return esp_mail_folder_info_t(); + } + +private: + void add(struct esp_mail_folder_info_t fd) { _folders.push_back(fd); }; + void clear() + { + for (size_t i = 0; i < _folders.size(); i++) + { + _folders[i].name.clear(); + _folders[i].attributes.clear(); + _folders[i].delimiter.clear(); + } + _folders.clear(); + } + _vectorImpl _folders; +}; + +/* The class that provides the list of IMAP_Quota_Root_Info e.g. resource name, used and limit */ +class IMAP_Quota_Roots_List +{ + friend class IMAPSession; + +public: + IMAP_Quota_Roots_List(){}; + ~IMAP_Quota_Roots_List() { clear(); }; + + size_t size() { return _quota_roots.size(); }; + + IMAP_Quota_Root_Info operator[](size_t index) + { + if (index < _quota_roots.size()) + return _quota_roots[index]; + + return IMAP_Quota_Root_Info(); + } + +private: + _vectorImpl _quota_roots; + + void add(IMAP_Quota_Root_Info v) + { + _quota_roots.push_back(v); + } + void clear() + { + _quota_roots.clear(); + } +}; + +/* The class that provides the list of IMAP_Namespaces */ +class IMAP_Namespaces +{ + friend class IMAPSession; + +public: + IMAP_Namespaces(){}; + ~IMAP_Namespaces() { clear(); }; + + size_t size() { return _ns_list.size(); }; + + IMAP_Namespace_Info operator[](size_t index) + { + if (index < _ns_list.size()) + return _ns_list[index]; + + return IMAP_Namespace_Info(); + } + +private: + _vectorImpl _ns_list; + + void add(IMAP_Namespace_Info v) + { + _ns_list.push_back(v); + } + void clear() + { + _ns_list.clear(); + } +}; + +/* The class that provides the list of IMAP_Namespaces */ +class IMAP_Rights_List +{ + friend class IMAPSession; + +public: + IMAP_Rights_List(){}; + ~IMAP_Rights_List() { clear(); }; + + size_t size() { return _rights_list.size(); }; + + IMAP_Rights_Info operator[](size_t index) + { + if (index < _rights_list.size()) + return _rights_list[index]; + + return IMAP_Rights_Info(); + } + +private: + _vectorImpl _rights_list; + + void add(IMAP_Rights_Info v) + { + _rights_list.push_back(v); + } + void clear() + { + _rights_list.clear(); + } +}; + +typedef struct esp_mail_imap_nanespace_list_t +{ + IMAP_Namespaces personal_namespaces; + IMAP_Namespaces other_users_namespaces; + IMAP_Namespaces shared_namespaces; +} IMAP_Namespaces_List; + +/* The class that provides the status of message feching and searching */ +class IMAP_Status +{ +public: + IMAP_Status(); + ~IMAP_Status(); + const char *info(); + bool success(); + void empty(); + friend class IMAPSession; + + MB_String _info; + bool _success = false; +}; + +typedef void (*imapStatusCallback)(IMAP_Status); +typedef void (*imapResponseCallback)(IMAP_Response); +typedef void (*MIMEDataStreamCallback)(MIME_Data_Stream_Info); +typedef void (*imapCharacterDecodingCallback)(IMAP_Decoding_Info *); + +#else + +enum esp_mail_imap_read_capability_types +{ + esp_mail_imap_read_capability_maxType +}; + +// Dummy class used in template functions (errorStatusCB). +class IMAPSession +{ +public: + struct IMAP_Status + { + public: + const char *info() { return ""; }; + bool success() { return false; }; + void empty(); + MB_String _info; + bool _success = false; + }; + + typedef void (*imapStatusCallback)(IMAP_Status); + MB_String errorReason() { return ""; } + bool _debug; + imapStatusCallback _statusCallback = nullptr; + void *_customCmdResCallback = nullptr; + esp_mail_session_type _sessionType = esp_mail_session_type_imap; + + struct esp_mail_imap_response_status_t + { + int errorCode = 0; + MB_String tag; + MB_String text; + MB_String status; + bool completed = false; + }; + + esp_mail_imap_response_status_t _responseStatus; + IMAP_Status _cbData; +}; +#endif + +#if defined(ENABLE_SMTP) + +/* The SMTP message class */ +class SMTP_Message +{ +public: + SMTP_Message() + { + text.content_type = "text/plain"; + html.content_type = "text/html"; + }; + + ~SMTP_Message() { clear(); }; + + void resetAttachItem(SMTP_Attachment &att) + { + att.blob.size = 0; + att.blob.data = nullptr; + att.file.path.clear(); + att.file.storage_type = esp_mail_file_storage_type_none; + att.descr.name.clear(); + att.descr.filename.clear(); + att.descr.transfer_encoding.clear(); + att.descr.content_encoding.clear(); + att.descr.mime.clear(); + att.descr.content_id.clear(); + att._int.att_type = esp_mail_att_type_none; + att._int.index = 0; + att._int.msg_uid = 0; + att._int.flash_blob = false; + att._int.xencoding = esp_mail_msg_xencoding_none; + att._int.parallel = false; + att._int.cid.clear(); + } + + void clear() + { + sender.name.clear(); + sender.email.clear(); + subject.clear(); + text.charSet.clear(); + text.content.clear(); + text.content_type.clear(); + text.embed.enable = false; + html.charSet.clear(); + html.content.clear(); + html.content_type.clear(); + html.embed.enable = false; + response.reply_to.clear(); + response.notify = esp_mail_smtp_notify::esp_mail_smtp_notify_never; + priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; + + for (size_t i = 0; i < _rcp.size(); i++) + { + _rcp[i].name.clear(); + _rcp[i].email.clear(); + } + + for (size_t i = 0; i < _cc.size(); i++) + _cc[i].email.clear(); + + for (size_t i = 0; i < _bcc.size(); i++) + _bcc[i].email.clear(); + + for (size_t i = 0; i < _hdr.size(); i++) + _hdr[i].clear(); + + for (size_t i = 0; i < _att.size(); i++) + { + _att[i].descr.filename.clear(); + _att[i].blob.data = nullptr; + _att[i].descr.mime.clear(); + _att[i].descr.name.clear(); + _att[i].blob.size = 0; + _att[i].descr.transfer_encoding.clear(); + _att[i].file.path.clear(); + _att[i].file.storage_type = esp_mail_file_storage_type_none; + } + + for (size_t i = 0; i < _parallel.size(); i++) + { + _parallel[i].descr.filename.clear(); + _parallel[i].blob.data = nullptr; + _parallel[i].descr.mime.clear(); + _parallel[i].descr.name.clear(); + _parallel[i].blob.size = 0; + _parallel[i].descr.transfer_encoding.clear(); + _parallel[i].file.path.clear(); + _parallel[i].file.storage_type = esp_mail_file_storage_type_none; + } + + _rcp.clear(); + _cc.clear(); + _bcc.clear(); + _hdr.clear(); + _att.clear(); + _parallel.clear(); + } + + /** Clear all the inline images + */ + void clearInlineimages() + { + for (int i = (int)_att.size() - 1; i >= 0; i--) + { + if (_att[i]._int.att_type == esp_mail_att_type_inline) + _att.erase(_att.begin() + i); + } + }; + + /* Clear all the attachments */ + void clearAttachments() + { + for (int i = (int)_att.size() - 1; i >= 0; i--) + { + if (_att[i]._int.att_type == esp_mail_att_type_attachment) + _att.erase(_att.begin() + i); + } + + for (int i = (int)_parallel.size() - 1; i >= 0; i--) + _parallel.erase(_parallel.begin() + i); + }; + + /** Clear all rfc822 message attachment + */ + void clearRFC822Messages() + { + for (int i = (int)_rfc822.size() - 1; i >= 0; i--) + { + _rfc822[i].clear(); + _rfc822.erase(_rfc822.begin() + i); + } + }; + + /** Clear the primary recipient mailboxes + */ + void clearRecipients() { _rcp.clear(); }; + + /** Clear the Carbon-copy recipient mailboxes + */ + void clearCc() { _cc.clear(); }; + + /** Clear the Blind-carbon-copy recipient mailboxes + */ + void clearBcc() { _bcc.clear(); }; + + /** Clear the custom message headers + */ + void clearHeader() { _hdr.clear(); }; + + /** Add attachment to the message + * + * @param att The SMTP_Attachment data item + */ + void addAttachment(SMTP_Attachment &att) + { + att._int.att_type = esp_mail_att_type_attachment; + att._int.parallel = false; + att._int.flash_blob = true; + _att.push_back(att); + }; + + /** Add parallel attachment to the message + * + * @param att The SMTP_Attachment data item + */ + void addParallelAttachment(SMTP_Attachment &att) + { + att._int.att_type = esp_mail_att_type_attachment; + att._int.parallel = true; + att._int.flash_blob = true; + _parallel.push_back(att); + }; + + /** Add inline image to the message + * + * @param att The SMTP_Attachment data item + */ + void addInlineImage(SMTP_Attachment &att) + { + att._int.flash_blob = true; + att._int.parallel = false; + att._int.att_type = esp_mail_att_type_inline; + att._int.cid = random(2000, 4000); + _att.push_back(att); + }; + + /** Add rfc822 message to the message + * + * @param msg The RFC822_Message class object + */ + void addMessage(SMTP_Message &msg) { _rfc822.push_back(msg); } + + /** Add the primary recipient mailbox to the message + * + * @param name The name of primary recipient + * @param email The Email address of primary recipient + */ + template + void addRecipient(T1 name, T2 email) + { + struct esp_mail_address_info_t rcp; + rcp.name = toStringPtr(name); + rcp.email = toStringPtr(email); + _rcp.push_back(rcp); + }; + + /** Add Carbon-copy recipient mailbox + * + * @param email The Email address of the secondary recipient + */ + template + void addCc(T email) + { + struct esp_mail_address_info_t cc; + cc.email = toStringPtr(email); + _cc.push_back(cc); + }; + + /** Add Blind-carbon-copy recipient mailbox + * + * @param email The Email address of the tertiary recipient + */ + template + void addBcc(T email) + { + struct esp_mail_address_info_t bcc; + bcc.email = toStringPtr(email); + _bcc.push_back(bcc); + }; + + /** Add the custom header to the message + * + * @param hdr The header name and value + */ + template + void addHeader(T hdr) + { + _hdr.push_back(MB_String().setPtr(toStringPtr(hdr))); + }; + + /* The message author config */ + struct esp_mail_address_info_t author; + + /* The message sender (agent or teansmitter) config */ + struct esp_mail_address_info_t sender; + + /* The topic of message */ + MB_String subject; + + /* The message type */ + byte type = esp_mail_msg_type_none; + + /* The PLAIN text message */ + esp_mail_plain_body_t text; + + /* The HTML text message */ + esp_mail_html_body_t html; + + /* The response config */ + struct esp_mail_smtp_msg_response_t response; + + /* The priority of the message */ + esp_mail_smtp_priority priority = esp_mail_smtp_priority::esp_mail_smtp_priority_normal; + + /* The enable options */ + struct esp_mail_smtp_enable_option_t enable; + + /* The message from config */ + struct esp_mail_address_info_t from; + + /* The message identifier */ + MB_String messageID; + + /* The keywords or phrases, separated by commas */ + MB_String keywords; + + /* The comments about message */ + MB_String comments; + + /* The date of message */ + MB_String date; + + /* The field that contains the parent's message ID of the message to which this one is a reply */ + MB_String in_reply_to; + + /* The field that contains the parent's references (if any) and followed by the parent's message ID (if any) of the message to which this one is a reply */ + MB_String references; + + /* The timestamp value to replace in text */ + esp_mail_timestamp_value_t timestamp; + +private: + friend class ESP_Mail_Client; + _vectorImpl _rcp; + _vectorImpl _cc; + _vectorImpl _bcc; + _vectorImpl _hdr; + _vectorImpl _att; + _vectorImpl _parallel; + _vectorImpl _rfc822; +}; + +class SMTP_Status +{ +public: + friend class SMTPSession; + friend class ESP_Mail_Client; + + SMTP_Status(); + ~SMTP_Status(); + const char *info(); + bool success(); + void empty(); + size_t completedCount(); + size_t failedCount(); + +private: + MB_String _info; + bool _success = false; + size_t _sentSuccess = 0; + size_t _sentFailed = 0; +}; + +typedef void (*smtpStatusCallback)(SMTP_Status); +typedef void (*smtpResponseCallback)(SMTP_Response); + +#endif + +class ESP_Mail_Client +{ + +public: + ESP_Mail_Client() + { + mbfs = new MB_FS(); + }; + + ~ESP_Mail_Client() + { + if (mbfs) + delete mbfs; + mbfs = nullptr; + + wifi.clearAP(); + }; + +#if defined(ENABLE_SMTP) + /** Sending Email through the SMTP server + * + * @param smtp The pointer to SMTP session object which holds the data and the + * TCP client. + * @param msg The pointer to SMTP_Message class which contains the header, + * body, and attachments. + * @param closeSession The option to Close the SMTP session after sent. + * @return The boolean value indicates the success of operation. + */ + bool sendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession = true); +#endif + +#if defined(ENABLE_SMTP) && defined(ENABLE_IMAP) + /** Append message to the mailbox + * + * @param imap The pointer to IMAP session object which holds the data and the + * TCP client. + * @param msg The pointer to SMTP_Message class which contains the header, + * body, and attachments. + * @param lastAppend The last message to append (optional). In case of MULTIAPPEND extension + * is supported, set this to false will append messages in single APPEND command. + * @param flags The flags to set to this message (optional). + * @param dateTime The date/time to set to this message (optional). + * @return The boolean value indicates the success of operation. + */ + template + bool appendMessage(IMAPSession *imap, SMTP_Message *msg, bool lastAppend = true, T1 flags = "", T2 dateTime = "") { return mAppendMessage(imap, msg, lastAppend, toStringPtr(flags), toStringPtr(dateTime)); } +#endif + +#if defined(ENABLE_IMAP) + /** Reading Email through IMAP server. + * + * @param imap The pointer to IMAP session object which holds the data and + the TCP client. + + * @param closeSession The option to close the IMAP session after fetching or + searching the Email. + * @return The boolean value indicates the success of operation. + */ + bool readMail(IMAPSession *imap, bool closeSession = true); + + /** Set the argument to the Flags for the specified message. + * + * @param imap The pointer to IMAP session object which holds the data and the + * TCP client. + * @param msgUID The UID of the message. + * @param flags The flag list to set. + * @param closeSession The option to close the IMAP session after set flag. + * @param silent The option to ignore the response. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + template + bool setFlag(IMAPSession *imap, int msgUID, T flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(msgUID), toStringPtr(flags), esp_mail_imap_store_flag_type_set, closeSession, silent, true, modsequence); } + + /** Set the argument to the Flags for the specified message. + * + * @param imap The pointer to IMAP session object which holds the data and the + * TCP client. + * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. + * @param UID The option for sequenceSet whether it is UID or message sequence number. + * @param flags The flag list to set. + * @param closeSession The option to close the IMAP session after set flag. + * @param silent The option to ignore the response. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + template + bool setFlag(IMAPSession *imap, T1 sequenceSet, bool UID, T2 flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(sequenceSet), toStringPtr(flags), esp_mail_imap_store_flag_type_set, closeSession, silent, UID, modsequence); } + + /** Add the argument to the Flags for the specified message. + * + * @param imap The pointer to IMAP session object which holds the data and the + * TCP client. + * @param msgUID The UID of the message. + * @param flags The flag list to add. + * @param closeSession The option to close the IMAP session after add flag. + * @param silent The option to ignore the response. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + template + bool addFlag(IMAPSession *imap, int msgUID, T flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(msgUID), toStringPtr(flags), esp_mail_imap_store_flag_type_add, closeSession, silent, true, modsequence); } + + /** Add the argument to the Flags for the specified message. + * + * @param imap The pointer to IMAP session object which holds the data and the + * TCP client. + * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. + * @param UID The option for sequenceSet whether it is UID or message sequence number. + * @param flags The flag list to add. + * @param closeSession The option to close the IMAP session after set flag. + * @param silent The option to ignore the response. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + template + bool addFlag(IMAPSession *imap, T1 sequenceSet, bool UID, T2 flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(sequenceSet), toStringPtr(flags), esp_mail_imap_store_flag_type_add, closeSession, silent, UID, modsequence); } + + /** Remove the argument from the Flags for the specified message. + * + * @param imap The pointer to IMAP session object which holds the data and the + * TCP client. + * @param msgUID The UID of the message that flags to be removed. + * @param flags The flag list to remove. + * @param closeSession The option to close the IMAP session after remove flag. + * @param silent The option to ignore the response. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + template + bool removeFlag(IMAPSession *imap, int msgUID, T flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(msgUID), toStringPtr(flags), esp_mail_imap_store_flag_type_remove, closeSession, silent, true, modsequence); } + + /** Remove the argument from the Flags for the specified message. + * + * @param imap The pointer to IMAP session object which holds the data and the + * TCP client. + * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. + * @param UID The option for sequenceSet whether it is UID or message sequence number. + * @param flags The flag list to remove. + * @param closeSession The option to close the IMAP session after set flag. + * @param silent The option to ignore the response. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + template + bool removeFlag(IMAPSession *imap, T1 sequenceSet, bool UID, T2 flags, bool closeSession, bool silent = false, int32_t modsequence = -1) { return mSetFlag(imap, toStringPtr(sequenceSet), toStringPtr(flags), esp_mail_imap_store_flag_type_remove, closeSession, silent, UID, modsequence); } + +#endif + + /** Reconnect WiFi or network if lost connection. + * + * @param reconnect The boolean to set/unset WiFi AP reconnection. + */ + void networkReconnect(bool reconnect); + + /* Obsoleted */ + void setUDPClient(void *client, float gmtOffset) {} + + /** Clear all WiFi access points assigned. + * + */ + void clearAP(); + + /** Add WiFi access point for non-ESP device to resume WiFi connection. + * + * @param ssid The WiFi SSID. + * @param password The WiFi password. + */ + void addAP(const String &ssid, const String &password); + + /** + * Formatted printing on debug port. + * + */ + void printf(const char *format, ...); + +#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) + + /** Initiate SD card with SPI port configuration. + * + * @param ss SPI Chip/Slave Select pin. + * @param sck SPI Clock pin. + * @param miso SPI MISO pin. + * @param mosi SPI MOSI pin. + * @param frequency The SPI frequency + * @return Boolean type status indicates the success of the operation. + */ + bool sdBegin(int8_t ss = -1, int8_t sck = -1, int8_t miso = -1, int8_t mosi = -1, uint32_t frequency = 4000000); + +#if defined(ESP8266) || defined(MB_ARDUINO_PICO) + + /** Initiate SD card with SD FS configurations (ESP8266 only). + * + * @param ss SPI Chip/Slave Select pin. + * @param sdFSConfig The pointer to SDFSConfig object (ESP8266 only). + * @return Boolean type status indicates the success of the operation. + */ + bool sdBegin(SDFSConfig *sdFSConfig); + +#endif + +#if defined(ESP32) + /** Initiate SD card with chip select and SPI configuration (ESP32 only). + * + * @param ss SPI Chip/Slave Select pin. + * @param spiConfig The pointer to SPIClass object for SPI configuartion. + * @param frequency The SPI frequency. + * @return Boolean type status indicates the success of the operation. + */ + bool sdBegin(int8_t ss, SPIClass *spiConfig = nullptr, uint32_t frequency = 4000000); +#endif + +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + /** Initiate SD card with SdFat SPI and pins configurations (with SdFat included only). + * + * @param sdFatSPIConfig The pointer to SdSpiConfig object for SdFat SPI configuration. + * @param ss SPI Chip/Slave Select pin. + * @param sck SPI Clock pin. + * @param miso SPI MISO pin. + * @param mosi SPI MOSI pin. + * @return Boolean type status indicates the success of the operation. + */ + bool sdBegin(SdSpiConfig *sdFatSPIConfig, int8_t ss = -1, int8_t sck = -1, int8_t miso = -1, int8_t mosi = -1); + + /** Initiate SD card with SdFat SDIO configuration (with SdFat included only). + * + * @param sdFatSDIOConfig The pointer to SdioConfig object for SdFat SDIO configuration. + * @return Boolean type status indicates the success of the operation. + */ + bool sdBegin(SdioConfig *sdFatSDIOConfig); + +#endif + +#endif + +#if defined(ESP32) && defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD_MMC) + /** Initialize the SD_MMC card (ESP32 only). + * + * @param mountpoint The mounting point. + * @param mode1bit Allow 1 bit data line (SPI mode). + * @param format_if_mount_failed Format SD_MMC card if mount failed. + * @return The boolean value indicates the success of operation. + */ + bool sdMMCBegin(const char *mountpoint = "/sdcard", bool mode1bit = false, bool format_if_mount_failed = false); +#endif + + /** Get free Heap memory. + * + * @return Free memory amount in byte. + */ + int getFreeHeap(); + + /** Get base64 encode string. + * + * @return String of base64 encoded string. + */ + template + String toBase64(T str) { return mGetBase64(toStringPtr(str)).c_str(); } + + MB_Time Time; + +#if defined(ENABLE_IMAP) + + // Get encoding type from character set string + esp_mail_char_decoding_scheme getEncodingFromCharset(const char *enc); + + // Decode Latin1 to UTF-8 + int decodeLatin1_UTF8(unsigned char *out, int *outlen, const unsigned char *in, int *inlen); + + // Decode TIS620 to UTF-8 + void decodeTIS620_UTF8(char *out, const char *in, size_t len); + + // handle rfc2047 Q (quoted printable) and B (base64) decodings + RFC2047_Decoder RFC2047Decoder; + +#endif + +private: + friend class SMTPSession; + friend class IMAPSession; + + MB_FS *mbfs = nullptr; + bool timeStatus = false; + time_t ts = 0; + bool networkAutoReconnect = true; + volatile bool networkStatus = false; + esp_mail_wifi_credentials_t wifi; + bool timezoneEnvSet = false; + + IMAPSession *imap = nullptr; + bool calDataLen = false; + uint32_t dataLen = 0; + uint32_t imap_ts = 0; + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + + unsigned long _lastReconnectMillis = 0; + uint16_t _reconnectTimeout = ESP_MAIL_NETWORK_RECONNECT_TIMEOUT; + + // Resume network connection + void resumeNetwork(ESP_Mail_TCPClient *client); + + // Get the CRLF ending string w/wo CRLF included. Return the size of string read and the current octet read. + int readLine(ESP_Mail_TCPClient *client, char *buf, int bufLen, bool withLineBreak, int &count, bool &ovf, unsigned long timeoutSec, bool &isTimeout); + + // readLine with overflow handling. + template + bool readResponse(T sessionPtr, char *buf, int bufLen, int &readLen, bool withLineBreak, int &count, MB_String &ovfBuf); + + // Network reconnection and return the connection status + template + bool reconnect(T sessionPtr, unsigned long dataTime = 0, bool downloadRequest = false); + + // Send callback + template + void sendCB(T sessionPtr, PGM_P info = "", bool prependCRLF = false, bool success = false); + + // PGM string replacement + void strReplaceP(MB_String &buf, PGM_P key, PGM_P value); + + // Check for OAuth log in error response + bool isOAuthError(char *buf, int bufLen, int &chunkIdx, int ofs); + + // Get SASL XOAUTH2 string + MB_String getXOAUTH2String(const MB_String &email, const MB_String &accessToken); + + // Send error callback + template + void sendErrorCB(T sessionPtr, PGM_P info, bool prependCRLF = false, bool success = false); + + // Send the error status callback + template + void errorStatusCB(T1 sessionPtr, T2 sessionPtr2, int error, bool clearLastStatus); + + // Check response callback was assigned? + template + bool isResponseCB(T sessionPtr); + + // Print library info + template + void printLibInfo(T sessionPtr); + + // Begin server connection + template + bool beginConnection(Session_Config *session_config, T sessionPtr, bool secureMode); + + // Prepare system time + template + bool prepareTime(Session_Config *session_config, T sessionPtr); + + // Check for session. Close session If not ready. + template + bool sessionReady(T sessionPtr); + + // Set cert data + void setCert(Session_Config *session_cfg, const char *ca); + // Set secure data + void setSecure(ESP_Mail_TCPClient &client, Session_Config *session_config); + + void appendMultipartContentType(MB_String &buf, esp_mail_multipart_types type, const char *boundary); + + String errorReason(bool isSMTP, int errorCode, const char *msg); + + // Close TCP session and clear auth_capability, read/send_capability, connected and authenticate statuses + template + void closeTCPSession(T sessionPtr); + + // Get and set timezone + void getSetTimezoneEnv(const char *TZ_file, const char *TZ_Var); + + // Get TCP connected status + template + bool connected(T sessionPtr); + + // Get the memory allocation block size of multiple of 4 + size_t getReservedLen(size_t len); + + // Check Email for valid format + bool validEmail(const char *s); + + // Get random UID for SMTP content ID and IMAP attachment default file name + char *getRandomUID(); + + // Spit the string into token strings + void splitToken(const char *str, _vectorImpl &tk, const char *delim); + + // Decode base64 encoded string + unsigned char *decodeBase64(const unsigned char *src, size_t len, size_t *out_len); + + // Decode base64 encoded string + MB_String encodeBase64Str(const unsigned char *src, size_t len); + + // Decode base64 encoded string + MB_String encodeBase64Str(uint8_t *src, size_t len); + + // Decode base64 encoded string + MB_String mGetBase64(MB_StringPtr str); + + // Sub string + char *subStr(const char *buf, PGM_P beginToken, PGM_P endToken, int beginPos, int endPos = 0, bool caseSensitive = true); + + // Find string + int strpos(const char *haystack, const char *needle, int offset, bool caseSensitive = true); + + // Memory allocation + template + T allocMem(size_t size, bool clear = true); + + // Memory deallocation + void freeMem(void *ptr); + + // PGM string compare + bool strcmpP(const char *buf, int ofs, PGM_P beginToken, bool caseSensitive = true); + + // Find PGM string + int strposP(const char *buf, PGM_P beginToken, int ofs, bool caseSensitive = true); + + // Memory allocation for PGM string + char *strP(PGM_P pgm); + + // Memory allocation for PGM lower case string + char *strP2Lower(PGM_P pgm); + + // Set or sync device system time with NTP server + // Do not modify or remove + void setTime(const char *TZ_Var, const char *TZ_file, bool wait, bool debugProgress); + + // Set the device time zone via TZ environment variable + void setTimezone(const char *TZ_Var, const char *TZ_file); + + // Get TZ environment variable from file + // Do not modify or remove + void getTimezone(const char *TZ_file, MB_String &out); + + // Check the session existent + template + bool sessionExisted(T sessionPtr); + + // Send SMTP/IMAP callback + template + void sendCallback(T sessionPtr, PGM_P info, bool prependCRLF, bool success); + + // Send IMAP/SMTP response callback and print debug message + template + void printDebug(T sessionPtr, PGM_P cbMsg, PGM_P dbMsg, esp_mail_debug_tag_type type, bool prependCRLF, bool success); + + // Get header content from response based on the field name + bool getHeader(const char *buf, PGM_P beginToken, MB_String &out, bool caseSensitive); + + // Append header field to buffer + void appendHeaderField(MB_String &buf, const char *name, PGM_P value, bool comma, bool newLine, esp_mail_string_mark_type type = esp_mail_string_mark_type_none); + + // Append SMTP address header field + void appendAddressHeaderField(MB_String &buf, esp_mail_address_info_t &source, esp_mail_rfc822_header_field_types type, bool header, bool comma, bool newLine); + + // Append header field name to buffer + void appendHeaderName(MB_String &buf, const char *name, bool clear = false, bool lowercase = false, bool space = true); + + // Append lowercase string to buffer + void appendLowerCaseString(MB_String &buf, PGM_P value, bool clear = false); + + // Append header field property to buffer + void appendHeaderProp(MB_String &buf, PGM_P prop, const char *value, bool &firstProp, bool lowerCase, bool isString, bool newLine); + + // Append quote string to buffer + void appendString(MB_String &buf, PGM_P value, bool comma, bool newLine, esp_mail_string_mark_type type = esp_mail_string_mark_type_none); + + // Append list to buffer + template + void appendList(MB_String &buf, _vectorImpl &list); + + // Append space to buffer + void appendSpace(MB_String &buf); + + // Append space to buffer after value + void appendSpace(MB_String &buf, bool withTag, PGM_P value); + + // Append space to buffer after values + void appendSpace(MB_String &buf, bool withTag, int nunArgs, ...); + + // Append space to buffer before value + void prependSpace(MB_String &buf, PGM_P value); + + // Append dot to buffer + void appendDot(MB_String &buf); + + // Append IMAP string key value list + void appendImap4KeyValue(MB_String &buf, PGM_P key, PGM_P value); + + // Append dot to buffer before value + void prependDot(MB_String &buf, PGM_P value); + + // Join 2 strings to buffer with space + void joinStringSpace(MB_String &buf, bool withTag, int nunArgs, ...); + + // Join 2 strings to buffer with dot + void joinStringDot(MB_String &buf, int nunArgs, ...); + + // Append mask(*) string to buffer + void maskString(MB_String &buf, int len); + + // Append domain to buffer + void appendDomain(MB_String &buf, const char *domain); + + // Append embedded message header to buffer + void appendEmbedMessage(MB_String &buf, esp_mail_message_body_t &body, bool isHtml); + + // Append crlf to buffer + void appendNewline(MB_String &buf); + + // Append tag to the buffer + void appendTagSpace(MB_String &buf, PGM_P tag = NULL); + + // Print newline + void debugPrintNewLine(); + + // Send newline to callback + template + void callBackSendNewLine(T sessionPtr, bool success); + + // Print progress bar + void printProgress(int progress, int &lastProgress); + + // Get file extension with dot from MIME string + void getExtfromMIME(const char *mime, MB_String &ext); + + // Prepare ports + void preparePortFunction(Session_Config *session_config, bool isSMTP, bool &secure, bool &secureMode, bool &ssl); + + // Get operation config based on port and its protocol + void getPortFunction(uint16_t port, struct esp_mail_ports_functions &ports_functions, bool &secure, bool &secureMode, bool &ssl, bool &starttls); + +#endif + +#if defined(ENABLE_SMTP) + + // Encode Quoted Printable string + void encodeQP(const char *buf, char *out); + + // Add the soft line break to the long text line rfc 3676 + void formatFlowedText(MB_String &content); + + // Insert soft break + void softBreak(MB_String &content, const char *quoteMarks); + + // Get content type (MIME) from file extension + void getMIME(const char *ext, MB_String &mime); + + // Get content type (MIME) from file name + void mimeFromFile(const char *name, MB_String &mime); + + // Get MIME boundary string + MB_String getMIMEBoundary(size_t len); + + // Send Email function + bool mSendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession = true); + + // SMTP send data + size_t smtpSend(SMTPSession *smtp, PGM_P data, bool newline = false); + + // SMTP send data + size_t smtpSend(SMTPSession *smtp, int data, bool newline = false); + + // SMTP send data + size_t smtpSend(SMTPSession *smtp, uint8_t *data, size_t size); + + // Handle the error by sending callback and close session + bool handleSMTPError(SMTPSession *smtp, int err, bool ret = false); + + // Send parallel attachment RFC1521 + bool sendParallelAttachments(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary); + + // Send attachment + bool sendAttachments(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, bool parallel = false); + + // Send message content + bool sendContent(SMTPSession *smtp, SMTP_Message *msg, bool closeSession, bool rfc822MSG); + + // Send imap or smtp callback + void altSendCallback(SMTPSession *smtp, PGM_P cbMsg, PGM_P dbMsg, esp_mail_debug_tag_type type, bool prependCRLF, bool success); + + // Send message data + bool sendMSGData(SMTPSession *smtp, SMTP_Message *msg, bool closeSession, bool rfc822MSG); + + // Send RFC 822 message + bool sendRFC822Msg(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, bool closeSession, bool rfc822MSG); + + // Get RFC 822 message envelope + void getRFC822MsgEnvelope(SMTPSession *smtp, SMTP_Message *msg, MB_String &buf); + + // Append boundary string to buffer + void appendBoundaryString(MB_String &buf, const char *value, bool endMark, bool newLine); + + // Send BDAT command RFC 3030 + bool sendBDAT(SMTPSession *smtp, SMTP_Message *msg, int len, bool last); + + // Get transfer encoding + void getXEncoding(esp_mail_msg_xencoding &xencoding, const char *enc); + + // Set the unencoded xencoding enum for html, text and attachment from its xencoding string + void checkUnencodedData(SMTPSession *smtp, SMTP_Message *msg); + + // Check imap or smtp has callback set + bool altIsCB(SMTPSession *smtp); + + // Check imap or smtp has debug set + bool altIsDebug(SMTPSession *smtp); + + // Send BLOB attachment + bool sendBlobAttachment(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att); + + // Send file content + bool sendFile(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att); + + // Send imap or smtp storage error callback + void altSendStorageErrorCB(SMTPSession *smtp, int err); + + // Open file to send an attachment + bool openFileRead(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att, MB_String &buf, const MB_String &boundary, bool inlined); + + // Open text file or html file for to send message + bool openFileRead2(SMTPSession *smtp, SMTP_Message *msg, const char *path, esp_mail_file_storage_type storageType); + + // Send inline attachments + bool sendInline(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, byte type); + + // Send storage error callback + void sendStorageNotReadyError(SMTPSession *smtp, esp_mail_file_storage_type storageType); + + // Append message + bool mAppendMessage(IMAPSession *imap, SMTP_Message *msg, bool lastAppend, MB_StringPtr flags, MB_StringPtr dateTime); + + // Get numbers of attachment based on type + size_t numAtt(SMTPSession *smtp, esp_mail_attach_type type, SMTP_Message *msg); + + // Check for valid recipient Email + bool checkEmail(SMTPSession *smtp, SMTP_Message *msg); + + // Send text parts MIME message + bool sendPartText(SMTPSession *smtp, SMTP_Message *msg, byte type, const char *boundary); + + // Alternative string data sending to send imap APPEND data or smtp data + bool altSendData(MB_String &s, bool newLine, SMTPSession *smtp, SMTP_Message *msg, bool addSendResult, bool getResponse, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode); + + // Alternative bytes data sending to send imap APPEND data or smtp data + bool altSendData(uint8_t *data, size_t size, SMTPSession *smtp, SMTP_Message *msg, bool addSendResult, bool getResponse, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode); + + // Send MIME message + bool sendMSG(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary); + + // Get an attachment part header string + void getAttachHeader(MB_String &header, const MB_String &boundary, SMTP_Attachment *attach, size_t size, bool isInline); + + // Get RFC 8222 part header string + void getRFC822PartHeader(SMTPSession *smtp, MB_String &header, const MB_String &boundary); + + // Send BLOB type text part or html part MIME message + bool sendBlobBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type); + + // Send file type text part or html part MIME message + bool sendFileBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type); + + // Base64 and QP encodings for text and html messages and replace embeded attachment file name with content ID + void encodingText(SMTPSession *smtp, SMTP_Message *msg, uint8_t type, MB_String &content); + + // Blob or Stream available + int chunkAvailable(SMTPSession *smtp, esp_mail_smtp_send_base64_data_info_t &data_info); + + // Read chunk data of blob or file + int getChunk(SMTPSession *smtp, esp_mail_smtp_send_base64_data_info_t &data_info, unsigned char *rawChunk, bool base64); + + // Terminate chunk reading + void closeChunk(esp_mail_smtp_send_base64_data_info_t &data_info); + + // Get base64 encoded buffer or raw buffer + void getBuffer(bool base64, uint8_t *out, uint8_t *in, int &encodedCount, int &bufIndex, bool &dataReady, int &size, size_t chunkSize); + + // Send blob or file as base64 encoded chunk + bool sendBase64(SMTPSession *smtp, SMTP_Message *msg, esp_mail_smtp_send_base64_data_info_t &data_info, bool base64, bool report); + + // Save sending logs to file + void saveSendingLogs(SMTPSession *smtp, SMTP_Message *msg, bool result); + + // Get imap or smtp report progress var pointer + uint32_t altProgressPtr(SMTPSession *smtp); + + // Get SMTP response status (statusCode and text) + void getResponseStatus(const char *buf, esp_mail_smtp_status_code statusCode, int beginPos, struct esp_mail_smtp_response_status_t &status); + + // Parse SMTP authentication capability + void parseAuthCapability(SMTPSession *smtp, char *buf); + + // Add the sending result + bool addSendingResult(SMTPSession *smtp, SMTP_Message *msg, bool result, bool showResult); + + // Handle SMTP server authentication + bool smtpAuth(SMTPSession *smtp, bool &ssl); + + // Handle SMTP response + bool handleSMTPResponse(SMTPSession *smtp, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode); + + // Print the upload status to the debug port + void uploadReport(const char *filename, uint32_t pgAddr, int progress); + + // Get MB_FS object pointer + MB_FS *getMBFS(); + + // Set device system time + int setTimestamp(time_t ts); +#endif + +#if defined(ENABLE_IMAP) + + // Check if child part (part number string) is a member of the parent part (part number string) + // part number string format: .. + bool multipartMember(const MB_String &parent, const MB_String &child); + + // Decode string + int decodeChar(const char *s); + + // Decode Quoted Printable string + void decodeQP_UTF8(const char *buf, char *out); + + // Actually not decode because 7bit string is enencode string unless prepare valid 7bit string and do qp decoding + char *decode7Bit_UTF8(char *buf); + + // Actually not decode because 8bit string is enencode string unless prepare valid 8bit string + char *decode8Bit_UTF8(char *buf); + + // Decode string base on encoding + void decodeString(IMAPSession *imap, MB_String &string, const char *enc = ""); + + /** + * Encode a code point using UTF-8 + * + * @author Ondřej Hruška + * https://gist.github.com/MightyPork/52eda3e5677b4b03524e40c9f0ab1da5 + * + * @license MIT + * + * @param out - output buffer (min 5 characters), will be 0-terminated + * @param utf - code point 0-0x10FFFF + * @return number of bytes on success, 0 on failure (also produces U+FFFD, which uses 3 bytes) + */ + int encodeUnicode_UTF8(char *out, uint32_t utf); + + // Append headers fetch command + void appendHeadersFetchCommand(IMAPSession *imap, MB_String &cmd, int index, bool debug); + + // Append rfc822 headers fetch command + void appendRFC822HeadersFetchCommand(MB_String &cmd); + + // Get multipart MIME fetch command + bool getMultipartFechCmd(IMAPSession *imap, int msgIdx, MB_String &partText); + + // Fetch multipart MIME body header + bool fetchMultipartBodyHeader(IMAPSession *imap, int msgIdx); + + // Print body part fetching debug + void printBodyPartFechingDubug(IMAPSession *imap, const char *partNum, bool multiLevel); + + // Handle IMAP server authentication + bool imapAuth(IMAPSession *imap, bool &ssl); + + // Send IMAP command + bool sendFetchCommand(IMAPSession *imap, int msgIndex, esp_mail_imap_command cmdCase); + + // Send data + size_t imapSend(IMAPSession *imap, PGM_P data, bool newline = false); + + // Send data + size_t imapSend(IMAPSession *imap, int data, bool newline = false); + + // Send data + size_t imapSend(IMAPSession *imap, uint8_t *data, size_t size); + + // Log out + bool imapLogout(IMAPSession *imap); + + // Send storage error callback + void sendStorageNotReadyError(IMAPSession *imap, esp_mail_file_storage_type storageType); + + // Parse search response + int parseSearchResponse(IMAPSession *imap, esp_mail_imap_response_data &res, PGM_P tag, const char *key); + + // Parse header state + bool parseHeaderField(IMAPSession *imap, const char *buf, PGM_P beginToken, bool caseSensitive, struct esp_mail_message_header_t &header, int &headerState, int state); + + // Parse header response + void parseHeaderResponse(IMAPSession *imap, esp_mail_imap_response_data &res, bool caseSensitive = true); + + // Set the header based on state parsed + void collectHeaderField(IMAPSession *imap, char *buf, struct esp_mail_message_header_t &header, int state); + + // Get decoded header + bool getDecodedHeader(IMAPSession *imap, const char *buf, PGM_P beginToken, MB_String &out, bool caseSensitive); + + // Check attachment for firmware file + void checkFirmwareFile(IMAPSession *imap, const char *filename, struct esp_mail_message_part_info_t &part, bool defaultSize = false); + + // Parse part header response + void parsePartHeaderResponse(IMAPSession *imap, esp_mail_imap_response_data &res, bool caseSensitive = true); + + // Count char in string + int countChar(const char *buf, char find); + + // Store the value to string via its the pointer + bool storeStringPtr(IMAPSession *imap, uint32_t addr, MB_String &value, const char *buf); + + // Get part header properties + bool getPartHeaderProperties(IMAPSession *imap, const char *buf, PGM_P p, PGM_P e, bool num, MB_String &value, MB_String &old_value, esp_mail_char_decoding_scheme &scheme, bool caseSensitive); + + // Url decode for UTF-8 encoded header text + char *urlDecode(const char *str); + + // Reset the pointer to multiline response keeping string + void resetStringPtr(struct esp_mail_message_part_info_t &part); + + // Get current part + struct esp_mail_message_part_info_t *cPart(IMAPSession *imap); + + // Get current header + struct esp_mail_message_header_t *cHeader(IMAPSession *imap); + +#if !defined(MB_USE_STD_VECTOR) + // Decending sort + void numDecSort(_vectorImpl &arr); +#endif + + // Handle IMAP response + bool handleIMAPResponse(IMAPSession *imap, int errCode, bool closeSession); + + // Print the file download status via debug port + void downloadReport(IMAPSession *imap, int progress); + + // Print the message fetch status via debug port + void fetchReport(IMAPSession *imap, int progress, bool html); + + // Print the message search status via debug port + void searchReport(IMAPSession *imap, int progress); + + // Get current message num item + struct esp_mail_imap_msg_num_t cMSG(IMAPSession *imap); + + // Get current message Index + int cIdx(IMAPSession *imap); + + // Get IMAP response status e.g. OK, NO and Bad status enum value + esp_mail_imap_response_status imapResponseStatus(IMAPSession *imap, char *response, PGM_P tag); + + // Add header item to string buffer + void addHeaderItem(MB_String &str, esp_mail_message_header_t *header, bool json); + + // Get RFC822 header string pointer by index + int getRFC822HeaderPtr(int index, esp_mail_imap_rfc822_msg_header_item_t *header); + + // Add RFC822 headers to string buffer + void addRFC822Headers(MB_String &s, esp_mail_imap_rfc822_msg_header_item_t *header, bool json); + + // Add RFC822 header item to string buffer + void addRFC822HeaderItem(MB_String &s, esp_mail_imap_rfc822_msg_header_item_t *header, int index, bool json); + + // Add header string by name and value to string buffer + void addHeader(MB_String &s, const char *name, const char *s_value, int num_value, bool trim, bool isJson); + + // Save header string buffer to file + void saveHeader(IMAPSession *imap, bool json); + + // Send MIME stream to callback + void sendStreamCB(IMAPSession *imap, void *buf, size_t len, int chunkIndex, bool hrdBrk); + + // Prepare file path for saving + void prepareFilePath(IMAPSession *imap, MB_String &filePath, bool header); + + // Decode text and store it to buffer or file + void decodeText(IMAPSession *imap, esp_mail_imap_response_data &res); + + // Handle atachment parsing and download + bool parseAttachmentResponse(IMAPSession *imap, char *buf, esp_mail_imap_response_data &res); + + // Get List + char *getList(char *buf, bool &isList); + + // Parse mailbox folder open response + void parseFoldersResponse(IMAPSession *imap, char *buf, bool list); + + // Prepare alias (short name) file list for unsupported long file name filesystem + void prepareFileList(IMAPSession *imap, MB_String &filePath); + + // Parse capability response + bool parseCapabilityResponse(IMAPSession *imap, const char *buf, int &chunkIdx); + + // Parse Idle response + bool parseIdleResponse(IMAPSession *imap); + + // Append Fetch UID/Flags string to buffer + void appendFetchString(MB_String &buf, bool uid); + + // Parse command response + void parseCmdResponse(IMAPSession *imap, char *buf, PGM_P find); + + // Get flags + bool getFlags(IMAPSession *imap, char *buf, esp_mail_imap_response_types type); + + // Parse examine response + void parseExamineResponse(IMAPSession *imap, char *buf); + + // Handle the error by sending callback and close session + bool handleIMAPError(IMAPSession *imap, int err, bool ret); + + // Set Flag + bool mSetFlag(IMAPSession *imap, MB_StringPtr sequenceSet, MB_StringPtr flags, esp_mail_imap_store_flag_type type, bool closeSession, bool silent = false, bool UID = true, int32_t modsequence = -1); + +#endif +}; + +#if defined(ENABLE_IMAP) + +class IMAPSession +{ +public: + IMAPSession(Client *client); + IMAPSession(); + ~IMAPSession(); + + /** Set the tcp timeout. + * + * @param timeoutSec The tcp timeout in seconds. + */ + void setTCPTimeout(unsigned long timeoutSec); + + /** Assign custom Client from Arduino Clients. + * + * @param client The pointer to Arduino Client derived class e.g. WiFiClient, EthernetClient or GSMClient. + */ + void setClient(Client *client); + + /** Assign TinyGsm Clients. + * + * @param client The pointer to TinyGsmClient. + * @param modem The pointer to TinyGsm modem object. Modem should be initialized and/or set mode before transfering data. + * @param pin The SIM pin. + * @param apn The GPRS APN (Access Point Name). + * @param user The GPRS user. + * @param password The GPRS password. + */ + void setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password); + + /** Assign the callback function to handle the network connection for custom Client. + * + * @param networkConnectionCB The function that handles the network connection. + */ + void networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB); + + /** Assign the callback function to handle the network connection status acknowledgement. + * + * @param networkStatusCB The function that handle the network connection status acknowledgement. + */ + void networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB); + + /** Set the network status acknowledgement. + * + * @param status The network status. + */ + void setNetworkStatus(bool status); + + /** Set the BearSSL IO buffer size. + * + * @param rx The BearSSL receive buffer size in bytes. + * @param tx The BearSSL trasmit buffer size in bytes. + */ + void setSSLBufferSize(int rx = -1, int tx = -1); + + /** Begin the IMAP server connection. + * + * @param session_config The pointer to Session_Config structured data that keeps + * the server and log in details. + * @param imap_data The pointer to IMAP_Data structured data that keeps the + * operation options. + * @param login The bool option for login after server connection. + * @return The boolean value which indicates the success of operation. + */ + bool connect(Session_Config *session_config, IMAP_Data *imap_data, bool login = true); + + /** Log in to IMAP server using Email and password. + * + * @param email The IMAP server account email. + * @param password The IMAP server account password. + * @return The boolean value which indicates the success of operation. + */ + template + bool loginWithPassword(T1 email, T2 password) { return mLogin(toStringPtr(email), toStringPtr(password), false); }; + + /** Log in to IMAP server using Email and access token. + * + * @param email The IMAP server account email. + * @param token The Access token to log in. + * @return The boolean value which indicates the success of operation. + */ + template + bool loginWithAccessToken(T1 email, T2 token) { return mLogin(toStringPtr(email), toStringPtr(token), true); }; + + /** Send the client identification to the server + * + * @param identification The pointer to IMAP_Identification structured data that keeps + * the key properties e.g., name, version, os, os_version, vendor, support_url, address, + * date, command, arguments, and environment. + */ + bool id(IMAP_Identification *identification); + + /** Return the server ID returns from ID command. + * @return The server ID string. + */ + String serverID(); + + /** Return the SASL authentication status. + * @return The boolean value indicates SASL authentication status. + */ + bool isAuthenticated(); + + /** Return the log status. + * @return The boolean value log in status. + */ + bool isLoggedIn(); + + /** Return firmware update result when attachment filename matches. + * @return The boolean value indicates the firmware update status. + */ + bool isFirmwareUpdateSuccess(); + + /** Begin the IMAP server connection without authentication. + * + * @param session_config The pointer to Session_Config structured data that keeps + * the server and log in details. + * @param callback The callback function that accepts IMAP_Response as parameter. + * @param tag The tag that pass to the callback function. + * @return The boolean value indicates the success of operation. + */ + template + bool customConnect(Session_Config *session_config, imapResponseCallback callback, T tag = "") { return mCustomConnect(session_config, callback, toStringPtr(tag)); }; + + /** Close the IMAP session. + * + * @return The boolean value which indicates the success of operation. + */ + bool closeSession(); + + /** Get TCP connection status. + * + * @return The boolean value indicates the connection status. + */ + bool connected(); + + /** Set to enable the debug. + * + * @param level The level to enable the debug message + * level = 0, no debugging + * level = 1, basic level debugging + */ + void debug(int level); + + /** Get the list of all the mailbox folders since the TCP session was opened + * and user was authenticated. + * + * @param folders The FoldersCollection class that contains the collection of + * the + * FolderInfo structured data. + * @return The boolean value which indicates the success of operation. + */ + bool getFolders(FoldersCollection &folders); + + /** Select or open the mailbox folder to search or fetch the message inside. + * + * @param folderName The known mailbox folder name. The default name is INBOX. + * @param readOnly The option to open the mailbox for read only. Set this + * option to false when you wish + * to modify the Flags using the setFlag, addFlag and removeFlag functions. + * @return The boolean value which indicates the success of operation. + * + * @note: the function will exit immediately and return true if the time since previous success folder selection (open) + * with the same readOnly mode, is less than 5 seconds. + */ + template + bool selectFolder(T folderName, bool readOnly = true) { return mSelectFolder(toStringPtr(folderName), readOnly); } + + /** Open the mailbox folder to read or search the mesages. + * + * @param folderName The name of known mailbox folder to be opened. + * @param readOnly The option to open the mailbox for reading only. Set this + * option to false when you wish + * to modify the flags using the setFlag, addFlag and removeFlag functions. + * @return The boolean value which indicates the success of operation. + * + * @note: the function will exit immediately and return true if the time since previous success folder selection (open) + * with the same readOnly mode, is less than 5 seconds. + */ + template + bool openFolder(T folderName, bool readOnly = true) { return mOpenFolder(toStringPtr(folderName), readOnly); } + + /** Close the mailbox folder that was opened. + * + * @param expunge The option to allow emty the deleted flag set messages in case folder was open with editable mode. + * @return The boolean value which indicates the success of operation. + */ + bool closeFolder(bool expunge = false) { return mCloseFolder(expunge); } + + /** Create folder. + * + * @param folderName The name of folder to create. + * @return The boolean value which indicates the success of operation. + */ + template + bool createFolder(T folderName) { return mCreateFolder(toStringPtr(folderName)); } + + /** Rename folder. + * + * @param currentFolderName The name of folder to rename. + * @param newFolderName The new name of folder to rename. + * @return The boolean value which indicates the success of operation. + */ + template + bool renameFolder(T1 currentFolderName, T2 newFolderName) { return mRenameFolder(toStringPtr(currentFolderName), toStringPtr(newFolderName)); } + + /** Delete folder. + * + * @param folderName The name of folder to delete. + * @return The boolean value which indicates the success of operation. + */ + template + bool deleteFolder(T folderName) { return mDeleteFolder(toStringPtr(folderName)); } + + /** Get subscribes mailboxes. + * + * @param reference The reference name. + * @param mailbox The mailbox name with possible wildcards. + * @param folders The return FoldersCollection that contains the folder info e.g., name, attribute and delimiter. + * @return The boolean value which indicates the success of operation. + */ + template + bool getSubscribesMailboxes(T1 reference, T2 mailbox, FoldersCollection &folders) { return mGetSubscribesMailboxes(toStringPtr(reference), toStringPtr(mailbox), folders); } + + /** Subscribe mailbox. + * + * @param folderName The name of folder to subscribe. + * @return The boolean value which indicates the success of operation. + */ + template + bool subscribe(T folderName) { return mSubscribe(toStringPtr(folderName)); } + + /** Unsubscribe mailbox. + * + * @param folderName The name of folder to unsubscribe. + * @return The boolean value which indicates the success of operation. + */ + template + bool unSubscribe(T folderName) { return mUnSubscribe(toStringPtr(folderName)); } + + /** Get UID number in selected or opened mailbox. + * + * @param msgNum The message number or order in the total message numbers. + * @return UID number in selected or opened mailbox. + * + * @note Returns 0 when fail to get UID. + */ + int getUID(int msgNum); + + /** Get message flags in selected or opened mailbox. + * + * @param msgNum The message number or order in the total message numbers. + * @return Message flags in selected or opened mailbox. + * + * @note Returns empty string when fail to get flags. + */ + const char *getFlags(int msgNum); + + /** Send the custom IMAP command and get the result via callback. + * + * @param cmd The command string. + * @param callback The callback function that accepts IMAP_Response as parameter. + * @param tag The tag string to pass to the callback function. + * @return The boolean value which indicates the success of operation. + * + * @note imap.connect and imap.selectFolder or imap.openFolder are needed to call once prior to call this function. + */ + template + bool sendCustomCommand(T1 cmd, imapResponseCallback callback, T2 tag = "") { return mSendCustomCommand(toStringPtr(cmd), callback, toStringPtr(tag)); } + + /** Send the custom IMAP command data string. + * + * @param data The string data. + * @param last The flag represents the last data to send (optional). + * @return The boolean value which indicates the success of operation. + * + * @note Should be used after calling sendCustomCommand("APPEND xxxxxx"); + */ + template + bool sendCustomData(T data, bool lastData = false) { return mSendData(toStringPtr(data), lastData, esp_mail_imap_cmd_custom); } + + /** Send the custom IMAP command data. + * + * @param data The byte data. + * @param size The data size. + * @param lastData The flag represents the last data to send (optional). + * @return The boolean value which indicates the success of operation. + * + * @note Should be used after calling ssendCustomCommand("APPEND xxxxxx"); + */ + bool sendCustomData(uint8_t *data, size_t size, bool lastData = false) { return mSendData(data, size, lastData, esp_mail_imap_cmd_custom); } + + /** Copy the messages to the defined mailbox folder. + * + * @param toCopy The pointer to the MessageList class that contains the + * list of messages to copy. + * @param dest The destination folder that the messages to copy to. + * @return The boolean value which indicates the success of operation. + */ + template + bool copyMessages(MessageList *toCopy, T dest) { return mCopyMessages(toCopy, toStringPtr(dest)); } + + /** Copy the messages to the defined mailbox folder. + * + * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. + * @param UID The option for sequenceSet whether it is UID or message sequence number. + * @param dest The destination folder that the messages to copy to. + * @return The boolean value indicates the success of operation. + */ + template + bool copyMessages(T1 sequenceSet, bool UID, T2 dest) { return mCopyMessagesSet(toStringPtr(sequenceSet), UID, toStringPtr(dest)); } + + /** Move the messages to the defined mailbox folder. + * + * @param toMove The pointer to the MessageList class that contains the + * list of messages to move. + * @param dest The destination folder that the messages to move to. + * @return The boolean value which indicates the success of operation. + */ + template + bool moveMessages(MessageList *toCopy, T dest) { return mMoveMessages(toCopy, toStringPtr(dest)); } + + /** Move the messages to the defined mailbox folder. + * + * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. + * @param UID The option for sequenceSet whether it is UID or message sequence number. + * @param dest The destination folder that the messages to move to. + * @return The boolean value indicates the success of operation. + */ + template + bool moveMessages(T1 sequenceSet, bool UID, T2 dest) { return mMoveMessagesSet(toStringPtr(sequenceSet), UID, toStringPtr(dest)); } + + /** Delete the messages in the opened mailbox folder. + * + * @param toDelete The pointer to the MessageList class that contains the + * list of messages to delete. + * @param expunge The boolean option to expunge all messages. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value which indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + bool deleteMessages(MessageList *toDelete, bool expunge = false, int32_t modsequence = -1) { return mDeleteMessages(toDelete, expunge, modsequence); } + + /** Delete the messages in the opened mailbox folder. + * + * @param sequenceSet The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number. + * @param UID The option for sequenceSet whether it is UID or message sequence number. + * @param expunge The boolean option to expunge all messages. + * @param modsequence The int32_t option for UNCHANGESINCE conditional test. + * @return The boolean value which indicates the success of operation. + * + * The modsequence value can be used only if IMAP server supports Conditional STORE extension + * and the selected mailbox supports modsequences. + */ + template + bool deleteMessages(T sequenceSet, bool UID, bool expunge = false, int32_t modsequence = -1) { return mDeleteMessagesSet(toStringPtr(sequenceSet), UID, expunge, modsequence); } + + /** Get the quota root's resource usage and limits. + * + * @param quotaRoot The quota root to get. + * @param info The pointer to IMAP_Quota_Root_Info that contains quota root's resource name, usage and limit. + * @return The boolean value which indicates the success of operation. + */ + template + bool getQuota(T quotaRoot, IMAP_Quota_Root_Info *info) { return mGetSetQuota(toStringPtr(quotaRoot), info, true); } + + /** Set the quota root's resource usage and limits. + * + * @param quotaRoot The quota root to set. + * @param data The pointer to IMAP_Quota_Root_Info that contains quota root's resource name, usage and limit. + * @return The boolean value which indicates the success of operation. + */ + template + bool setQuota(T quotaRoot, IMAP_Quota_Root_Info *data) { return mGetSetQuota(toStringPtr(quotaRoot), data, false); } + + /** Get the list of quota roots for the named mailbox. + * + * @param mailbox The mailbox name. + * @param quotaRootsList The pointer to IMAP_Quota_Roots_List that contains the list of IMAP_Quota_Root_Info. + * @return The boolean value which indicates the success of operation. + */ + template + bool getQuotaRoot(T mailbox, IMAP_Quota_Roots_List *quotaRootsList) { return mGetQuotaRoots(toStringPtr(mailbox), quotaRootsList); } + + /** Get the ACLs for a mailbox. + * + * @param mailbox The mailbox name. + * @param aclList The pointer to the returning IMAP_Rights_List object. + * @return The boolean value which indicates the success of operation. + */ + template + bool getACL(T mailbox, IMAP_Rights_List *aclList) { return mManageACL(toStringPtr(mailbox), aclList, nullptr, toStringPtr(""), esp_mail_imap_cmd_get_acl); }; + + /** Get the ACLs for a mailbox. + * + * @param mailbox The mailbox name. + * @param acl The pointer to the acl IMAP_Rights_Info to set. + * @return The boolean value which indicates the success of operation. + */ + template + bool setACL(T mailbox, IMAP_Rights_Info *acl) { return mManageACL(toStringPtr(mailbox), nullptr, acl, toStringPtr(""), esp_mail_imap_cmd_set_acl); }; + + /** Delete the ACLs set for identifier on mailbox. + * + * @param mailbox The mailbox name. + * @param identifier The identifier (user) to remove the rights. + * @return The boolean value which indicates the success of operation. + */ + template + bool deleteACL(T1 mailbox, T2 identifier) { return mManageACL(toStringPtr(mailbox), nullptr, nullptr, toStringPtr(identifier), esp_mail_imap_cmd_delete_acl); }; + + /** Show my ACLs for a mailbox. + * + * @param mailbox The mailbox name. + * @param acl The pointer to the returning IMAP_Rights_Info object. + * @return The boolean value which indicates the success of operation. + */ + template + bool myRights(T mailbox, IMAP_Rights_Info *acl) { return mManageACL(toStringPtr(mailbox), nullptr, acl, toStringPtr(""), esp_mail_imap_cmd_my_rights); }; + + /** Returns IMAP namespaces. + * + * @param mailbox The mailbox name. + * @param ns The pointer to the returning IMAP_Namespaces_List object. + * @return The boolean value which indicates the success of operation. + */ + bool getNamespace(IMAP_Namespaces_List *ns) { return mNamespace(ns); }; + + /** Enable IMAP capability. + * + * @param capability The mailbox name. + * @return The boolean value which indicates the success of operation. + */ + template + bool enable(T capability) { return mEnable(toStringPtr(capability)); }; + + /** Listen for the selected or open mailbox for updates. + * @return The boolean value which indicates the success of operation. + */ + bool listen() { return mListen(false); }; + + /** Stop listen for the mailbox for updates. + * @return The boolean value which indicates the success of operation. + */ + bool stopListen() { return mStopListen(false); }; + + /** Check for the selected or open mailbox updates. + * @return The boolean value which indicates the changes status of mailbox. + */ + bool folderChanged(); + + /** Send NOOP command to IMAP server. + * @return The boolean value which indicates the success of operation. + */ + bool noop(); + + /** Assign the callback function that returns the operating status when + * fetching or reading the Email. + * + * @param imapCallback The function that accepts the imapStatusCallback as + * parameter. + */ + void callback(imapStatusCallback imapCallback); + + /** Assign the callback function to decode the string based on the character set. + * + * @param callback The function that accepts the pointer to IMAP_Decoding_Info as parameter. + */ + void characterDecodingCallback(imapCharacterDecodingCallback callback); + + /** Assign the callback function that returns the MIME data stream from + * fetching or reading the Email. + * + * @param mimeDataStreamCallback The function that accepts the MIME_Stream_Info as + * parameter. + */ + void mimeDataStreamCallback(MIMEDataStreamCallback mimeDataStreamCallback); + + /** Determine if no message body contained in the search result and only the + * message header is available. + */ + bool headerOnly(); + + /** Get the message list from search or fetch the Emails + * + * @return The IMAP_MSG_List structured data which contains text and html + * contents, + * attachments, inline images, embedded rfc822 messages details for each + * message. + */ + IMAP_MSG_List data(); + + /** Get the details of the selected or opned mailbox folder + * + * @return The SelectedFolderInfo class which contains the info about flags, + * total messages, next UID, + * search count and the available messages count. + */ + SelectedFolderInfo selectedFolder(); + + /** Get the error details when readingg the Emails + * + * @return The string of error details. + */ + String errorReason(); + + /** Get the operating status error code. + * + * @return The int value of operating status error code. + * + * The negative value indicated error. + * See src/ESP_Mail_Error.h and extras/MB_FS.h + */ + int errorCode(); + + /** Clear all the cache data stored in the IMAP session object. + */ + void empty(); + + /** Get the status of message fetching and searching. + * + * @return The IMAP_Status object contains the fetching and searching statuses. + */ + IMAP_Status status(); + + /** Get the JSON string of file name list of files that stored in SD card. + * + * @return The JSON string of filenames. + * @note This will available only when standard SD library was used and file storage is SD. + */ + String fileList(); + + /** Set the current timestamp. + * + * @param ts The current timestamp. + * @param gmtOffset The GMT offset. + */ + void setSystemTime(time_t ts, float gmtOffset = 0); + + /** Setup TCP KeepAlive for internal TCP client. + * + * @param tcpKeepIdleSeconds lwIP TCP Keepalive idle in seconds. + * @param tcpKeepIntervalSeconds lwIP TCP Keepalive interval in seconds. + * @param tcpKeepCount lwIP TCP Keepalive count. + * + * For the TCP (KeepAlive) options, see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/lwip.html#tcp-options. + * + * If value of one of these parameters is zero, the TCP KeepAlive will be disabled. + * + * You can check the server connecting status, by exexuting .connected() which will return true when connection to the server is still alive. + */ + void keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount); + + /** Get TCP KeepAlive status. + * + * @return Boolean status of TCP KeepAlive. + */ + bool isKeepAlive(); + + friend class ESP_Mail_Client; + friend class foldderList; + +private: + // Log in to IMAP server + bool mLogin(MB_StringPtr email, MB_StringPtr password, bool isToken); + + // Clear message data + void clearMessageData(); + + // Check for valid UID or set wildcard * as UID + void checkUID(); + + // Check for valid saving file path or prepend / + void checkPath(); + + // Get message item by index + void getMessages(uint16_t messageIndex, struct esp_mail_imap_msg_item_t &msg); + + // Get RFC822 message item by index + void getRFC822Messages(uint16_t messageIndex, struct esp_mail_imap_msg_item_t &msg); + + // Close mailbox + bool closeMailbox(bool expunge = false); + + // Open mailbox + bool openMailbox(MB_StringPtr folder, esp_mail_imap_auth_mode mode, bool waitResponse, bool unselect); + + // Get folders list + bool getMailboxes(FoldersCollection &folders); + + // Get subscribes mailboxes + bool mGetSubscribesMailboxes(MB_StringPtr reference, MB_StringPtr mailbox, FoldersCollection &folders); + + // Subscribe the mailbox + bool mSubscribe(MB_StringPtr folder); + + // Unsubscribe the mailbox + bool mUnSubscribe(MB_StringPtr folder); + + // Get UID + int mGetUID(int msgNum); + + // Fetch by sequence set + bool mFetchSequenceSet(); + + // Return string from TAG prepended command + MB_String prependTag(PGM_P cmd, PGM_P tag = NULL); + + // Check capabilities + bool checkCapabilities(); + + // Listen mailbox changes + bool mListen(bool recon); + + // Stop listen mailbox + bool mStopListen(bool recon); + + // Send custom command + bool mSendCustomCommand(MB_StringPtr cmd, imapResponseCallback callback, MB_StringPtr tag); + + // Send data after sending APPEND command + bool mSendData(MB_StringPtr data, bool lastData, esp_mail_imap_command cmd); + + // Send data after sending APPEND command + bool mSendData(uint8_t *data, size_t size, bool lastData, esp_mail_imap_command cmd); + + // Delete folder + bool mDeleteFolder(MB_StringPtr folderName); + + // Create folder + bool mCreateFolder(MB_StringPtr folderName); + + // Rename folder + bool mRenameFolder(MB_StringPtr currentFolderName, MB_StringPtr newFolderName); + + // Copy message + bool copyMsg(MessageList *toCopy, const char *sequenceSet, bool UID, MB_StringPtr dest); + + // Copy message + bool mCopyMessages(MessageList *toCopy, MB_StringPtr dest); + + // Copy message using sequence set + bool mCopyMessagesSet(MB_StringPtr sequenceSet, bool UID, MB_StringPtr dest); + + // Move message + bool moveMsg(MessageList *toMove, const char *sequenceSet, bool UID, MB_StringPtr dest); + + // Move message + bool mMoveMessages(MessageList *toMove, MB_StringPtr dest); + + // Move message using sequence set + bool mMoveMessagesSet(MB_StringPtr sequenceSet, bool UID, MB_StringPtr dest); + + // Check for conditional STORE extention support + bool isCondStoreSupported(); + + // Check for mailbox mod-sequence support + bool isModseqSupported(); + + // add UNCHANGEDSINCE STORE modifier and CHANGEDSINCE FETCH modifier to command + void addModifier(MB_String &cmd, esp_mail_imap_command_types type, int32_t modsequence); + + // Delete message + bool deleteMsg(MessageList *toDelete, const char *sequenceSet, bool UID, bool expunge, int32_t modsequence = -1); + + // Delete messages + bool mDeleteMessages(MessageList *toDelete, bool expunge = false, int32_t modsequence = -1); + + // Delete messages + bool mDeleteMessagesSet(MB_StringPtr sequenceSet, bool UID, bool expunge = false, int32_t modsequence = -1); + + // Get or set the quota root's resource usage and limits. + bool mGetSetQuota(MB_StringPtr quotaRoot, IMAP_Quota_Root_Info *data, bool getMode); + + // Parse the IMAP_Quota_Root_info + void mParseQuota(const char *quota, IMAP_Quota_Root_Info *data); + + // Get the list of quota roots for the named mailbox. + bool mGetQuotaRoots(MB_StringPtr mailbox, IMAP_Quota_Roots_List *quotaRootsList); + + // Get or set ACL. + bool mManageACL(MB_StringPtr mailbox, IMAP_Rights_List *acl_list, IMAP_Rights_Info *acl, MB_StringPtr identifier, esp_mail_imap_command type); + + // Parse ACL + void parseACL(MB_String &acl_str, IMAP_Rights_List *right_list); + + // parse Rights + void parseRights(MB_String &righs_str, IMAP_Rights_Info *info); + + // Get Rights from IMAP_Rights_Info + void getRights(MB_String &righs_str, IMAP_Rights_Info *info); + + // Get namespace + bool mNamespace(IMAP_Namespaces_List *ns); + + // Enable the IMAP capability + bool mEnable(MB_StringPtr capability); + + // Parse namespaces + void parseNamespaces(MB_String &ns_str, IMAP_Namespaces *ns); + + // Close folder + bool mCloseFolder(bool expunge = false); + + // Open folder + bool mOpenFolder(MB_StringPtr folderName, bool readOnly); + + // Select folder + bool mSelectFolder(MB_StringPtr folderName, bool readOnly); + + // Custom TCP connection + bool mCustomConnect(Session_Config *session_config, imapResponseCallback callback, MB_StringPtr tag); + + // Append ID list to buffer + void appendIdList(MB_String &list, IMAP_Identification *identification); + + // Handle connection + bool handleConnection(Session_Config *session_config, IMAP_Data *imap_data, bool &ssl); + + // Start TCP connection + bool connect(bool &ssl); + + // Print features not supported debug error message + void printDebugNotSupported(); + + bool _sessionSSL = false; + bool _sessionLogin = false; + bool _loginStatus = false; + unsigned long _last_polling_error_ms = 0; + unsigned long _last_host_check_ms = 0; + unsigned long _last_server_connect_ms = 0; + unsigned long _last_network_error_ms = 0; + unsigned long tcpTimeout = TCP_CLIENT_DEFAULT_TCP_TIMEOUT_SEC; + struct esp_mail_imap_response_status_t _responseStatus; + int _cMsgIdx = 0; + int _cPartIdx = 0; + int _totalRead = 0; + _vectorImpl _headers; + + esp_mail_imap_command _imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_sasl_login; + esp_mail_imap_command _prev_imap_cmd = esp_mail_imap_command::esp_mail_imap_cmd_sasl_login; + esp_mail_imap_command _imap_custom_cmd = esp_mail_imap_cmd_custom; + esp_mail_imap_command _prev_imap_custom_cmd = esp_mail_imap_cmd_custom; + bool _idle = false; + MB_String _cmd; + _vectorImpl _multipart_levels; + int _rfc822_part_count = 0; + bool _unseen = false; + bool _readOnlyMode = true; + bool _msgDownload = false; + bool _attDownload = false; + bool _storageReady = false; + bool _storageChecked = false; + + bool _auth_capability[esp_mail_auth_capability_maxType]; + bool _feature_capability[esp_mail_imap_read_capability_maxType]; + Session_Config *_session_cfg; + _vectorImpl _configPtrList; + MB_String _currentFolder; + bool _mailboxOpened = false; + unsigned long _lastSameFolderOpenMillis = 0; + MB_String _nextUID; + MB_String _unseenMsgIndex; + MB_String _flags_tmp; + MB_String _quota_tmp; + MB_String _quota_root_tmp; + MB_String _acl_tmp; + MB_String _ns_tmp; + MB_String _server_id_tmp; + MB_String _sdFileList; + + struct esp_mail_imap_data_config_t *_imap_data = nullptr; + + int _userHeaderOnly = -1; + bool _headerOnly = true; + bool _uidSearch = false; + bool _headerSaved = false; + bool _debug = false; + int _debugLevel = 0; + bool _secure = false; + bool _authenticated = false; + bool _isFirmwareUpdated = false; + imapStatusCallback _statusCallback = NULL; + imapResponseCallback _customCmdResCallback = NULL; + MIMEDataStreamCallback _mimeDataStreamCallback = NULL; + imapCharacterDecodingCallback _charDecCallback = NULL; + + _vectorImpl _imap_msg_num; + esp_mail_session_type _sessionType = esp_mail_session_type_imap; + + FoldersCollection _folders; + SelectedFolderInfo _mbif; + int _uid_tmp = 0; + int _lastProgress = -1; + + ESP_Mail_TCPClient client; + + IMAP_Status _cbData; +}; + +#endif + +#if defined(ENABLE_SMTP) + +class SendingResult +{ +private: + _vectorImpl _result; + + void add(SMTP_Result *r) + { + _result.push_back(*r); + } + +public: + friend class SMTPSession; + friend class ESP_Mail_Client; + SendingResult(){}; + ~SendingResult() { clear(); }; + + void clear() + { + for (size_t i = 0; i < _result.size(); i++) + { + _result[i].recipients.clear(); + _result[i].subject.clear(); + _result[i].timestamp = 0; + _result[i].completed = false; + } + _result.clear(); + } + + SMTP_Result getItem(size_t index) + { + SMTP_Result r; + if (index < _result.size()) + return _result[index]; + return r; + } + size_t size() { return _result.size(); }; +}; + +class SMTPSession +{ +public: + SMTPSession(Client *client); + SMTPSession(); + ~SMTPSession(); + + /** Set the tcp timeout. + * + * @param timeoutSec The tcp timeout in seconds. + */ + void setTCPTimeout(unsigned long timeoutSec); + + /** Assign custom Client from Arduino Clients. + * + * @param client The pointer to Arduino Client derived class e.g. WiFiClient, EthernetClient or GSMClient. + */ + void setClient(Client *client); + + /** Assign TinyGsm Clients. + * + * @param client The pointer to TinyGsmClient. + * @param modem The pointer to TinyGsm modem object. Modem should be initialized and/or set mode before transfering data. + * @param pin The SIM pin. + * @param apn The GPRS APN (Access Point Name). + * @param user The GPRS user. + * @param password The GPRS password. + */ + void setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password); + + /** Assign the callback function to handle the network connection for custom Client. + * + * @param networkConnectionCB The function that handles the network connection. + */ + void networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB); + + /** Assign the callback function to handle the network connection status acknowledgement. + * + * @param networkStatusCB The function that handle the network connection status acknowledgement. + */ + void networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB); + + /** Set the network status acknowledgement. + * + * @param status The network status. + */ + void setNetworkStatus(bool status); + + /** Set the BearSSL IO buffer size. + * + * @param rx The BearSSL receive buffer size in bytes. + * @param tx The BearSSL trasmit buffer size in bytes. + */ + void setSSLBufferSize(int rx = -1, int tx = -1); + + /** Begin the SMTP server connection. + * + * @param session_config The pointer to Session_Config structured data that keeps + * the server and log in details. + * @param login The bool option for login after server connection. + * @return The boolean value indicates the success of operation. + */ + bool connect(Session_Config *session_config, bool login = true); + + /** Log in to SMTP server using Email and password. + * + * @param email The SMTP server account email. + * @param password The SMTP server account password. + * @return The boolean value which indicates the success of operation. + */ + template + bool loginWithPassword(T1 email, T2 password) { return mLogin(toStringPtr(email), toStringPtr(password), false); }; + + /** Log in to SMTP server using Email and access token. + * + * @param email The SMTP server account email. + * @param token The Access token to log in. + * @return The boolean value which indicates the success of operation. + */ + template + bool loginWithAccessToken(T1 email, T2 token) { return mLogin(toStringPtr(email), toStringPtr(token), true); }; + + /** Return the SASL authentication status. + * @return The boolean value indicates SASL authentication status. + */ + bool isAuthenticated(); + + /** Return the log status. + * @return The boolean value indicates log in status. + */ + bool isLoggedIn(); + + /** Begin the SMTP server connection without authentication. + * + * @param session_config The pointer to Session_Config structured data that keeps + * the server and log in details. + * @param callback The callback function that accepts the SMTP_Response as parameter. + * @param commandID The command identifier number that will pass to the callback. + * @return The int value of status code. + * + * @note If commandID was not set or set to -1, the command identifier will be auto increased started from zero. + */ + int customConnect(Session_Config *session_config, smtpResponseCallback callback, int commandID = -1); + + /** Close the SMTP session. + * + */ + bool closeSession(); + + /** Get TCP connection status. + * + * @return The boolean value indicates the connection status. + */ + bool connected(); + + /** Send the custom SMTP command and get the result via callback. + * + * @param cmd The command string. + * @param callback The function that accepts the SMTP_Response as parameter. + * @param commandID The command identifier number that will pass to the callback. + * @return The integer value of response code. + * + * @note smtp.connect or smtp.customConnect is needed to call once prior to call this function. + * + * If commandID was not set or set to -1, the command identifier will be auto increased started from zero. + */ + template + int sendCustomCommand(T cmd, smtpResponseCallback callback, int commandID = -1) { return mSendCustomCommand(toStringPtr(cmd), callback, commandID); } + + /** Send the custom SMTP command data string. + * + * @param data The string data. + * @return The boolean value which indicates the success of operation. + * + * @note Should be used after calling sendCustomCommand("DATA"); + */ + template + bool sendCustomData(T data) { return mSendData(toStringPtr(data)); } + + /** Send the custom SMTP command data. + * + * @param data The byte data. + * @param size The data size. + * @return The boolean value which indicates the success of operation. + * + * @note Should be used after calling sendCustomCommand("DATA"); + */ + bool sendCustomData(uint8_t *data, size_t size) { return mSendData(data, size); } + + /** Set to enable the debug. + * + * @param level The level to enable the debug message + * level = 0, no debugging + * level = 1, basic level debugging + */ + void debug(int level); + + /** Get the error details when sending the Email + * + * @return The string of error details. + */ + String errorReason(); + + /** Get the SMTP server response status code. + * + * @return The int value of SMTP server response status code. + * + * See RFC 5321 standard's documentation. + */ + int statusCode(); + + /** Get the SMTP server response status message. + * + * @return The int value of SMTP server response status message. + * + */ + String statusMessage(); + + /** Get the operating status error code. + * + * @return The int value of operating status error code. + * + * The negative value indicated error. + * See src/ESP_Mail_Error.h and extras/MB_FS.h + */ + int errorCode(); + + /** Set the Email sending status callback function. + * + * @param smtpCallback The callback function that accept the + * smtpStatusCallback param. + */ + void callback(smtpStatusCallback smtpCallback); + + /** Get the status of message fetching and searching. + * + * @return The SMTP_Status object contains the sending status. + */ + SMTP_Status status(); + + /** Set the current timestamp. + * + * @param ts The current timestamp. + * @param gmtOffset The GMT offset. + */ + void setSystemTime(time_t ts, float gmtOffset = 0); + + /** Setup TCP KeepAlive for internal TCP client. + * + * @param tcpKeepIdleSeconds lwIP TCP Keepalive idle in seconds. + * @param tcpKeepIntervalSeconds lwIP TCP Keepalive interval in seconds. + * @param tcpKeepCount lwIP TCP Keepalive count. + * + * For the TCP (KeepAlive) options, see https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/lwip.html#tcp-options. + * + * If value of one of these parameters is zero, the TCP KeepAlive will be disabled. + * + * You can check the server connecting status, by exexuting .connected() which will return true when connection to the server is still alive. + */ + void keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount); + + /** Get TCP KeepAlive status. + * + * @return Boolean status of TCP KeepAlive. + */ + bool isKeepAlive(); + + SendingResult sendingResult; + + friend class ESP_Mail_Client; + +private: + bool _sessionSSL = false; + bool _sessionLogin = false; + struct esp_mail_smtp_response_status_t _responseStatus; + int _sentSuccessCount = 0; + int _sentFailedCount = 0; + bool _chunkedEnable = false; + int _chunkCount = 0; + uint32_t ts = 0; + unsigned long tcpTimeout = TCP_CLIENT_DEFAULT_TCP_TIMEOUT_SEC; + + esp_mail_smtp_command _smtp_cmd = esp_mail_smtp_command::esp_mail_smtp_cmd_greeting; + + bool _auth_capability[esp_mail_auth_capability_maxType]; + bool _feature_capability[esp_mail_smtp_send_capability_maxType]; + + Session_Config *_session_cfg = NULL; + _vectorImpl _configPtrList; + + bool _debug = false; + int _debugLevel = 0; + bool _secure = false; + bool _authenticated = false; + bool _loginStatus = false; + bool _waitForAuthenticate = false; + bool _canForward = false; + smtpStatusCallback _statusCallback = NULL; + smtpResponseCallback _customCmdResCallback = NULL; + int _commandID = -1; + bool _sdStorageReady = false; + bool _flashStorageReady = false; + bool _sdStorageChecked = false; + bool _flashStorageChecked = false; + + esp_mail_session_type _sessionType = esp_mail_session_type_smtp; + SMTP_Status _cbData; + struct esp_mail_smtp_msg_type_t _msgType; + int _lastProgress = -1; + + ESP_Mail_TCPClient client; + + // Start TCP connection + bool connect(bool &ssl); + + // Log in to SMTP server + bool mLogin(MB_StringPtr email, MB_StringPtr password, bool isToken); + + // Handle TCP connection + bool handleConnection(Session_Config *session_config, bool &ssl); + + // Send custom command + int mSendCustomCommand(MB_StringPtr cmd, smtpResponseCallback callback, int commandID = -1); + + // Send data after sending DATA command + bool mSendData(MB_StringPtr data); + + // Send data after sending DATA command + bool mSendData(uint8_t *data, size_t size); +}; + +#endif + +#if defined(ENABLE_SMTP) && defined(ENABLE_IMAP) + +class ESP_Mail_Message : public SMTP_Message +{ +public: + ESP_Mail_Message(){}; + ~ESP_Mail_Message(){}; +}; + +#endif + +extern ESP_Mail_Client MailClient; + +#endif /* ESP_MAIL_CLIENT_H */ diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client_Version.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client_Version.h index 21cd038f6..a7da45a23 100644 --- a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client_Version.h +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Client_Version.h @@ -1,12 +1,12 @@ - -#pragma once - -#ifndef ESP_MAIL_VERSION - -#define ESP_MAIL_VERSION "3.4.9" -#define ESP_MAIL_VERSION_NUM 30409 - -/* The inconsistent file version checking to prevent mixed versions compilation. */ -#define VALID_VERSION_CHECK(ver) (ver == ESP_MAIL_VERSION_NUM) - + +#pragma once + +#ifndef ESP_MAIL_VERSION + +#define ESP_MAIL_VERSION "3.4.9" +#define ESP_MAIL_VERSION_NUM 30409 + +/* The inconsistent file version checking to prevent mixed versions compilation. */ +#define VALID_VERSION_CHECK(ver) (ver == ESP_MAIL_VERSION_NUM) + #endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Const.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Const.h index 195ab0b11..aa8ae5df5 100644 --- a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Const.h +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Const.h @@ -1,3492 +1,3492 @@ -// Created August 20, 2023 - -#pragma once - -#ifndef ESP_MAIL_CONST_H -#define ESP_MAIL_CONST_H - -#include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30409) -#error "Mixed versions compilation." -#endif - -#include -#include "ESP_Mail_FS.h" -#include "ESP_Mail_Error.h" -#include "extras/MB_FS.h" -#include "extras/RFC2047.h" -#include -#include - -#if defined(ESP_MAIL_DEBUG_PORT) -#define ESP_MAIL_DEFAULT_DEBUG_PORT ESP_MAIL_DEBUG_PORT -#else -#define ESP_MAIL_DEFAULT_DEBUG_PORT Serial -#endif - -#include -#include - -#define _vectorImpl std::vector -#define MB_VECTOR std::vector - -#if !defined(FPSTR) -#define FPSTR -#endif - -#include "extras/Networks_Provider.h" -#include "extras/ESP8266_Supports.h" - -#if defined(ESP8266) -#if __has_include() -#include -#endif -#endif - -#if defined(ENABLE_IMAP) && (defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO)) -#if defined(ESP32) -#include -#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) -#include -#endif -#define ESP_MAIL_OTA_UPDATE_ENABLED -#endif - -#if !defined(SILENT_MODE) && (defined(ENABLE_SMTP) || defined(ENABLE_IMAP)) -#define SESSION_DEBUG_ENABLED -#endif - -#define TCP_CLIENT_DEFAULT_TCP_TIMEOUT_SEC 30 - -#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) - -#define MAX_EMAIL_SEARCH_LIMIT 1000 -#define BASE64_CHUNKED_LEN 76 -#define FLOWED_TEXT_LEN 78 -#define QP_ENC_MSG_LEN 76 -#define ESP_MAIL_NETWORK_RECONNECT_TIMEOUT 10000 -#define ESP_MAIL_PROGRESS_REPORT_STEP 5 -#define ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED 0 -#define ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE 256 -#define ESP_MAIL_CLIENT_RESPONSE_BUFFER_SIZE 1024 // should be 1 k or more to prevent buffer overflow -#define ESP_MAIL_CLIENT_VALID_TS 1577836800 - -#endif - -typedef enum -{ - esp_mail_cert_type_undefined = -1, - esp_mail_cert_type_none = 0, - esp_mail_cert_type_data, - esp_mail_cert_type_file, - esp_mail_cert_type_bundle - -} esp_mail_cert_type; - -typedef enum -{ - esp_mail_client_type_undefined, - esp_mail_client_type_internal_basic_client, - esp_mail_client_type_external_basic_client, - esp_mail_client_type_external_gsm_client - -} esp_mail_client_type; - -/* The filesystem types enum */ -enum esp_mail_file_storage_type -{ - esp_mail_file_storage_type_none, - esp_mail_file_storage_type_flash, - esp_mail_file_storage_type_sd -}; - -/* The session types enum */ -enum esp_mail_session_type -{ - esp_mail_session_type_smtp, - esp_mail_session_type_imap -}; - -/* The secure connection mode preference */ -typedef enum -{ - // No preferences - esp_mail_secure_mode_undefined = 0, - // Always use SSL and TLS via STARTTLS rfc2595 section 3 and rfc3207 - esp_mail_secure_mode_ssl_tls, - // Plain text mode only (non SSL/TLS) - // To disable SSL/TLS permanently, define ESP_MAIL_DISABLE_SSL in ESP_Mail_FS.h - esp_mail_secure_mode_nonsecure - -} esp_mail_secure_mode; - -using namespace mb_string; - -#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) - -typedef void (*NetworkConnectionHandler)(void); - -/* The file types enum */ -enum esp_mail_file_extension -{ - /** The arrangement is related to mimeinfo struct. - * Do not modify or remove. - */ - esp_mail_file_extension_html, - esp_mail_file_extension_htm, - esp_mail_file_extension_css, - esp_mail_file_extension_txt, - esp_mail_file_extension_js, - esp_mail_file_extension_json, - esp_mail_file_extension_png, - esp_mail_file_extension_gif, - esp_mail_file_extension_jpg, - esp_mail_file_extension_ico, - esp_mail_file_extension_svg, - esp_mail_file_extension_ttf, - esp_mail_file_extension_otf, - esp_mail_file_extension_woff, - esp_mail_file_extension_woff2, - esp_mail_file_extension_eot, - esp_mail_file_extension_sfnt, - esp_mail_file_extension_xml, - esp_mail_file_extension_pdf, - esp_mail_file_extension_zip, - esp_mail_file_extension_gz, - esp_mail_file_extension_appcache, - esp_mail_file_extension_dat, - esp_mail_file_extension_binary, - esp_mail_file_extension_maxType -}; - -struct esp_mail_mime_prop_t -{ - char endsWith[10]; - char mimeType[30]; -}; - -const struct esp_mail_mime_prop_t mimeinfo[esp_mail_file_extension_maxType] PROGMEM = { - /** The arrangement is related to esp_mail_file_extension enum. - * Do not modify or remove. - */ - {".html", "text/html"}, - {".htm", "text/html"}, - {".css", "text/css"}, - {".txt", "text/plain"}, - {".js", "application/javascript"}, - {".json", "application/json"}, - {".png", "image/png"}, - {".gif", "image/gif"}, - {".jpg", "image/jpeg"}, - {".ico", "image/x-icon"}, - {".svg", "image/svg+xml"}, - {".ttf", "application/x-font-ttf"}, - {".otf", "application/x-font-opentype"}, - {".woff", "application/font-woff"}, - {".woff2", "application/font-woff2"}, - {".eot", "application/vnd.ms-fontobject"}, - {".sfnt", "application/font-sfnt"}, - {".xml", "text/xml"}, - {".pdf", "application/pdf"}, - {".zip", "application/zip"}, - {".gz", "application/x-gzip"}, - {".appcache", "text/cache-manifest"}, - {".dat", "application/dat"}, - {"", "application/octet-stream"}}; - -#if defined(ENABLE_SMTP) - -/* The SMTP commands types enum */ -enum esp_mail_smtp_command_types -{ - /** The SMTP commands per stansards. - * The arrangement is related to smtp_commands struct. - * Do not modify or remove. - */ - esp_mail_smtp_command_auth, - esp_mail_smtp_command_login, - esp_mail_smtp_command_helo, - esp_mail_smtp_command_ehlo, - esp_mail_smtp_command_quit, - esp_mail_smtp_command_mail, - esp_mail_smtp_command_rcpt, - esp_mail_smtp_command_data, - esp_mail_smtp_command_bdat, - esp_mail_smtp_command_last, - esp_mail_smtp_command_plain, - esp_mail_smtp_command_from, - esp_mail_smtp_command_to, - esp_mail_smtp_command_notify, - esp_mail_smtp_command_success, - esp_mail_smtp_command_failure, - esp_mail_smtp_command_delay, - esp_mail_smtp_command_body, - esp_mail_smtp_command_terminate, - esp_mail_smtp_command_starttls, - esp_mail_smtp_command_maxType -}; - -/* The SMTP server capability types enum (except for SASL) */ -enum esp_mail_smtp_send_capability_types -{ - /** The server capability keywords per standard. - * The arrangement is related to smtp_send_capabilities struct. - * Do not modify or remove. - */ - esp_mail_smtp_send_capability_binary_mime, - esp_mail_smtp_send_capability_8bit_mime, - esp_mail_smtp_send_capability_chunking, - esp_mail_smtp_send_capability_utf8, - esp_mail_smtp_send_capability_pipelining, - esp_mail_smtp_send_capability_dsn, - esp_mail_smtp_send_capability_esmtp, - esp_mail_smtp_send_capability_maxType -}; - -#endif - -#if defined(ENABLE_IMAP) - -/* The IMAP server response types enum */ -enum esp_mail_imap_response_types -{ - /** The IMAP response. - * The arrangement is related to imap_responses struct. - * Do not modify or remove. - */ - esp_mail_imap_response_ok, - esp_mail_imap_response_no, - esp_mail_imap_response_bad, - esp_mail_imap_response_list, - esp_mail_imap_response_flags, - esp_mail_imap_response_search, - esp_mail_imap_response_fetch, - esp_mail_imap_response_nil, - esp_mail_imap_response_uid, - esp_mail_imap_response_capability_untagged, - esp_mail_imap_response_capability, - esp_mail_imap_response_lsub, - esp_mail_imap_response_quota, - esp_mail_imap_response_quotaroot, - esp_mail_imap_response_acl, - esp_mail_imap_response_myrights, - esp_mail_imap_response_namespace, - esp_mail_imap_response_untagged, - esp_mail_imap_response_exists, - esp_mail_imap_response_expunge, - esp_mail_imap_response_recent, - esp_mail_imap_response_uidnext, - esp_mail_imap_response_unseen, - esp_mail_imap_response_id, - esp_mail_imap_response_highest_modsec, - esp_mail_imap_response_nomodsec, - esp_mail_imap_response_permanent_flags, - esp_mail_imap_response_uidvalidity, - esp_mail_imap_response_maxType -}; - -/* The IMAP commands types enum */ -enum esp_mail_imap_command_types -{ - /** The IMAP commands per standards. - * The arrangement is related to imap_commands struct. - * Do not modify or remove. - */ - esp_mail_imap_command_starttls, - esp_mail_imap_command_append, - esp_mail_imap_command_capability, - esp_mail_imap_command_authenticate, - esp_mail_imap_command_plain, - esp_mail_imap_command_uid, - esp_mail_imap_command_fetch, - esp_mail_imap_command_flags, - esp_mail_imap_command_login, - esp_mail_imap_command_list, - esp_mail_imap_command_examine, - esp_mail_imap_command_search, - esp_mail_imap_command_logout, - esp_mail_imap_command_body, - esp_mail_imap_command_mime, - esp_mail_imap_command_close, - esp_mail_imap_command_exists, - esp_mail_imap_command_peek, - esp_mail_imap_command_text, - esp_mail_imap_command_fields, - esp_mail_imap_command_header, - esp_mail_imap_command_new, - esp_mail_imap_command_all, - esp_mail_imap_command_select, - esp_mail_imap_command_expunge, - esp_mail_imap_command_create, - esp_mail_imap_command_delete, - esp_mail_imap_command_idle, - esp_mail_imap_command_done, - esp_mail_imap_command_recent, - esp_mail_imap_command_unseen, - esp_mail_imap_command_rename, - esp_mail_imap_command_lsub, - esp_mail_imap_command_subscribe, - esp_mail_imap_command_unsubscribe, - esp_mail_imap_command_silent, - esp_mail_imap_command_move, - esp_mail_imap_command_getquota, - esp_mail_imap_command_setquota, - esp_mail_imap_command_root, - esp_mail_imap_command_get_acl, - esp_mail_imap_command_set_acl, - esp_mail_imap_command_delete_acl, - esp_mail_imap_command_myrights, - esp_mail_imap_command_namespace, - esp_mail_imap_command_enable, - esp_mail_imap_command_xoauth2, - esp_mail_imap_command_store, - esp_mail_imap_command_plus_flags, - esp_mail_imap_command_minus_flags, - esp_mail_imap_command_copy, - esp_mail_imap_command_id, - esp_mail_imap_command_unselect, - esp_mail_imap_command_condstore, - esp_mail_imap_command_noop, - esp_mail_imap_command_unchangedsince, - esp_mail_imap_command_changedsince, - esp_mail_imap_command_modsec, - esp_mail_imap_command_maxType -}; - -/* The IMAP server capability types enum (except for SASL) */ -enum esp_mail_imap_read_capability_types -{ - /** The server capability keywords per standard. - * The arrangement is related imap_read_capabilities struct. - * Do not modify or remove. - */ - - esp_mail_imap_read_capability_imap4, - esp_mail_imap_read_capability_imap4rev1, - // rfc2177 - esp_mail_imap_read_capability_idle, - esp_mail_imap_read_capability_literal_plus, - esp_mail_imap_read_capability_literal_minus, - esp_mail_imap_read_capability_multiappend, - esp_mail_imap_read_capability_uidplus, - // rfc4314 - esp_mail_imap_read_capability_acl, - esp_mail_imap_read_capability_binary, - esp_mail_imap_read_capability_logindisable, - // rfc6851 - esp_mail_imap_read_capability_move, - // rfc2087 - esp_mail_imap_read_capability_quota, - // rfc2342 - esp_mail_imap_read_capability_namespace, - // rfc5161 - esp_mail_imap_read_capability_enable, - // rfc2971 - esp_mail_imap_read_capability_id, - esp_mail_imap_read_capability_unselect, - esp_mail_imap_read_capability_children, - // rfc7162 (rfc4551 obsoleted) - esp_mail_imap_read_capability_condstore, - esp_mail_imap_read_capability_auto_caps, - esp_mail_imap_read_capability_maxType -}; - -/* The Identification keys enum used for IMAP ID command */ -enum esp_mail_imap_identification_keys -{ - /** The identification keys per standard. - * The arrangement is related imap_identification_keys struct. - * Do not modify or remove. - */ - - esp_mail_imap_identification_key_name, - esp_mail_imap_identification_key_version, - esp_mail_imap_identification_key_os, - esp_mail_imap_identification_key_os_version, - esp_mail_imap_identification_key_vendor, - esp_mail_imap_identification_key_support_url, - esp_mail_imap_identification_key_address, - esp_mail_imap_identification_key_date, - esp_mail_imap_identification_key_command, - esp_mail_imap_identification_key_arguments, - esp_mail_imap_identification_key_environment, - esp_mail_imap_identification_key_maxType -}; - -#endif - -/* The character encoding types enum used for decoding */ -enum esp_mail_char_decoding_types -{ - /** Supported charactor encodings. - * The arrangement is related to char_decodings struct. - * Do not modify or remove. - */ - esp_mail_char_decoding_utf8, - esp_mail_char_decoding_iso_8859_1, - esp_mail_char_decoding_iso_8859_11, - esp_mail_char_decoding_tis_620, - esp_mail_char_decoding_windows_874, - esp_mail_char_decoding_maxType -}; - -/* The MIME multipart message types */ -enum esp_mail_multipart_types -{ - /** MultiPart MIME. - * The arrangement is related to multipart_types struct. - * Do not modify or remove. - */ - esp_mail_multipart_type_mixed, - esp_mail_multipart_type_related, - esp_mail_multipart_type_parallel, - esp_mail_multipart_type_alternative, - esp_mail_multipart_maxType -}; - -/* The rfc822 message header fileds types enum */ -enum esp_mail_rfc822_header_field_types -{ - /** The rfc822 message header fields. - * The arrangement is related to rfc822_headers struct. - * Do not modify or remove. - */ - esp_mail_rfc822_header_field_from, - esp_mail_rfc822_header_field_sender, - esp_mail_rfc822_header_field_to, - esp_mail_rfc822_header_field_cc, - esp_mail_rfc822_header_field_subject, - esp_mail_rfc822_header_field_date, - esp_mail_rfc822_header_field_msg_id, - esp_mail_rfc822_header_field_return_path, - esp_mail_rfc822_header_field_reply_to, - esp_mail_rfc822_header_field_in_reply_to, - esp_mail_rfc822_header_field_references, - esp_mail_rfc822_header_field_comments, - esp_mail_rfc822_header_field_keywords, - esp_mail_rfc822_header_field_bcc, - esp_mail_rfc822_header_field_flags, - esp_mail_rfc822_header_field_maxType -}; - -/* The message header fileds types enum and its subproperties enum */ -enum esp_mail_message_header_field_types -{ - /** Additional fields and props. - * Some are used for the library information data field name. - * The arrangement is related to message_headers struct. - * Do not modify or remove. - */ - esp_mail_message_header_field_number, - esp_mail_message_header_field_uid, - esp_mail_message_header_field_accept_language, - esp_mail_message_header_field_content_language, - esp_mail_message_header_field_filename, - esp_mail_message_header_field_name, - esp_mail_message_header_field_size, - esp_mail_message_header_field_mime, - esp_mail_message_header_field_type, - esp_mail_message_header_field_description, - esp_mail_message_header_field_creation_date, - esp_mail_message_header_field_x_priority, - esp_mail_message_header_field_x_msmail_priority, - esp_mail_message_header_field_importance, - esp_mail_message_header_field_content_type, - esp_mail_message_header_field_content_transfer_encoding, - esp_mail_message_header_field_content_disposition, - esp_mail_message_header_field_content_location, - esp_mail_message_header_field_content_id, - esp_mail_message_header_field_content_description, - esp_mail_message_header_field_mime_version, - esp_mail_message_header_field_charset, - esp_mail_message_header_field_format, - esp_mail_message_header_field_delsp, - esp_mail_message_header_field_modification_date, - esp_mail_message_header_field_maxType -}; - -/* The auth capability types enum which shared usage between SMTP and IMAP */ -enum esp_mail_auth_capability_types -{ - /** The server capability keywords per standard. - * The arrangement is related to smtp_auth_capabilities and imap_auth_capabilities structs. - * Do not modify or remove. - */ - - esp_mail_auth_capability_plain, - esp_mail_auth_capability_xoauth2, - esp_mail_auth_capability_cram_md5, - esp_mail_auth_capability_digest_md5, - esp_mail_auth_capability_login, - esp_mail_auth_capability_starttls, - // imap rfc4959 - esp_mail_auth_capability_sasl_ir, - - esp_mail_auth_capability_maxType, -}; - -/* The smessage types enum */ -enum esp_mail_message_type -{ - esp_mail_msg_type_none = 0, - esp_mail_msg_type_plain = 1, - esp_mail_msg_type_html = 2, - esp_mail_msg_type_enriched = 1 -}; - -/* The string mark types enum used in joinStringx functions */ -enum esp_mail_string_mark_type -{ - esp_mail_string_mark_type_none, - esp_mail_string_mark_type_double_quote, - esp_mail_string_mark_type_angle_bracket, - esp_mail_string_mark_type_round_bracket, - esp_mail_string_mark_type_curly_bracket, - esp_mail_string_mark_type_square_bracket -}; - -/* The debug TAG types enum */ -enum esp_mail_debug_tag_type -{ - esp_mail_debug_tag_type_client, - esp_mail_debug_tag_type_server, - esp_mail_debug_tag_type_error, - esp_mail_debug_tag_type_info, - esp_mail_debug_tag_type_warning -}; - -/* The embed attachment types enum */ -enum esp_mail_smtp_embed_message_type -{ - esp_mail_smtp_embed_message_type_attachment = 0, - esp_mail_smtp_embed_message_type_inline -}; - -/* The attachment types enum */ -enum esp_mail_attach_type -{ - esp_mail_att_type_none, - esp_mail_att_type_attachment, - esp_mail_att_type_inline -}; - -/* The debug levels for printing the debug information via Serial port */ -enum esp_mail_debug_level -{ - esp_mail_debug_level_none = 0, - esp_mail_debug_level_basic, - esp_mail_debug_level_maintainer = 0xfff, - esp_mail_debug_level_developer = esp_mail_debug_level_maintainer + 1 -}; - -/* The content transfer encoding enum */ -enum esp_mail_msg_xencoding -{ - esp_mail_msg_xencoding_none, - /* rfc2045 section 2.7 */ - esp_mail_msg_xencoding_7bit, - esp_mail_msg_xencoding_qp, - esp_mail_msg_xencoding_base64, - /* rfc2045 section 2.8 */ - esp_mail_msg_xencoding_8bit, - /* rfc2045 section 2.9 */ - esp_mail_msg_xencoding_binary -}; - -/* The port protocols enum */ -enum esp_mail_protocol -{ - esp_mail_protocol_plain_text, - esp_mail_protocol_ssl, - esp_mail_protocol_tls -}; - -/* The internal use strct */ -struct esp_mail_internal_use_t -{ - esp_mail_msg_xencoding xencoding = esp_mail_msg_xencoding_none; - MB_String cid; -}; - -/* The struct contains port number and its protocol */ -struct port_function -{ - uint16_t port; - esp_mail_protocol protocol; -}; - -/* The struct that contains the list of port_function and its size */ -struct esp_mail_ports_functions -{ - friend class IMAPSession; - friend class SMTPSession; - friend class esp_mail_session_config_t; - - uint16_t size = 0; - port_function *list = nullptr; - bool use_internal_list = false; -}; - -/* The content transfer encoding type struct */ -struct esp_mail_transfer_encoding_t -{ - /* The default 7-bit transfer encoding for US-ACII characters*/ - static constexpr const char *enc_7bit = "7bit"; - - /* The quoted printable transfer encoding for non-US-ASCII characters*/ - static constexpr const char *enc_qp = "quoted-printable"; - - /* The base64 encoded transfer encoding */ - static constexpr const char *enc_base64 = "base64"; - - /* The 8-bit transfer encoding for extended-US-ASCII characters*/ - static constexpr const char *enc_8bit = "8bit"; - - /* The binary transfer encoding for extended-US-ASCII characters with no line - * length limit*/ - static constexpr const char *enc_binary = "binary"; -}; - -/* The content disposition types strucr (rfc 2183) */ -struct esp_mail_content_disposition_type_t -{ - /** if it is intended to be displayed automatically - * upon display of the message. - */ - static constexpr const char *inline_ = "inline"; - - /** to indicate that they are separate from the main body - * of the mail message, and that their display should not - * be automatic, but contingent upon some further action of the user. - */ - static constexpr const char *attachment = "attachment"; -}; - -/* The file (SD/flash) message content struct used for providing SMTP message content from file */ -struct esp_mail_file_message_content_t -{ - /* The file path include its name */ - MB_String name; - - /** The type of file storages e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - esp_mail_file_storage_type type = esp_mail_file_storage_type_flash; -}; - -/* The blob or flash string message content struct used for providing SMTP message content from blob or flash string */ -struct esp_mail_blob_message_content_t -{ - /* The array of content in flash memory */ - const uint8_t *data = nullptr; - - /* The array size in bytes */ - size_t size = 0; -}; - -/* The option to embed this message content as a file */ -struct esp_mail_smtp_embed_message_body_t -{ - /* Enable to send this message body as file */ - bool enable = false; - - /* The name of embedded file */ - MB_String filename; - - /** The embedded type - * esp_mail_smtp_embed_message_type_attachment or 0 - * esp_mail_smtp_embed_message_type_inline or 1 - */ - esp_mail_smtp_embed_message_type type = esp_mail_smtp_embed_message_type_attachment; -}; - -/** This is the base struct for SMTP message. - * This is for input and later used as esp_mail_plain_body_t - * and esp_mail_html_body_t. - * Its members are similar to esp_mail_imap_plain_body_t - * and esp_mail_imap_html_body_t unless it contains - * MB_String object to hold the string. - */ -struct esp_mail_message_body_t -{ - /* The option to embed this message content as a file */ - struct esp_mail_smtp_embed_message_body_t embed; - - /* The PLAIN/HTML content of the message */ - MB_String content; - - const char *nonCopyContent = ""; - - /* The blob that contins PLAIN/HTML content of the message */ - struct esp_mail_blob_message_content_t blob; - - /* The file that contins PLAIN/HTML content of the message */ - struct esp_mail_file_message_content_t file; - - /* The charset of the PLAIN/HTML content of the message */ - MB_String charSet = "UTF-8"; - - /* The content type of message */ - MB_String content_type = mimeinfo[esp_mail_file_extension_txt].mimeType; - - /* The option to encode the content for data transfer */ - MB_String transfer_encoding = "7bit"; - - /* The option to send the PLAIN text with wrapping */ - bool flowed = false; - - /* The internal usage data */ - struct esp_mail_internal_use_t _int; -}; - -/** The PLAIN text body details of the fetching message. - * This is for output and its members are similar to - * esp_mail_message_body_t unless there is no string object - * to hold string data unless the pointer to the const strings - * in IMAPSession object. - */ -struct esp_mail_imap_plain_body_t -{ - /* The option to embed this message content as a file */ - struct esp_mail_smtp_embed_message_body_t embed; - - /* The PLAIN text content of the message */ - const char *content = ""; - - /* The blob that contins PLAIN text content of the message */ - struct esp_mail_blob_message_content_t blob; - - /* The file that contins PLAIN text content of the message */ - struct esp_mail_file_message_content_t file; - - /* The charset of the PLAIN text content of the message */ - const char *charSet = "UTF-8"; - - /* The content type of message */ - const char *content_type = mimeinfo[esp_mail_file_extension_txt].mimeType; - - /* The option to encode the content for data transfer */ - const char *transfer_encoding = "7bit"; - - /* The option to send the PLAIN text with wrapping */ - bool flowed = false; - - /* The internal usage data */ - struct esp_mail_internal_use_t _int; -}; - -/** The HTML body details of the fetching message. - * This is for output and its members are similar to - * esp_mail_message_body_t unless there is no string object - * to hold string data unless the pointer to the const strings - * in IMAPSession object. - */ -struct esp_mail_imap_html_body_t -{ - /* The option to embedded the content as a file */ - struct esp_mail_smtp_embed_message_body_t embed; - - /* The HTML content of the message */ - const char *content = ""; - - /* The blob that contins HTML content of the message */ - struct esp_mail_blob_message_content_t blob; - - /* The file that contins HTML content of the message */ - struct esp_mail_file_message_content_t file; - - /* The charset of the HTML content of the message */ - const char *charSet = "UTF-8"; - - /* The content type of message */ - const char *content_type = mimeinfo[esp_mail_file_extension_html].mimeType; - - /* The option to encode the content for data transfer */ - const char *transfer_encoding = "7bit"; - - /* The internal usage data */ - struct esp_mail_internal_use_t _int; -}; - -/* The PLAIN text body details of the message */ -typedef struct esp_mail_message_body_t esp_mail_plain_body_t; - -/* The HTML text body details of the message */ -typedef struct esp_mail_message_body_t esp_mail_html_body_t; - -/* The attachment info struct used for output */ -struct esp_mail_attachment_info_t -{ - const char *filename = ""; - const char *name = ""; - const char *creationDate = ""; - const char *mime = ""; - const char *description = ""; - esp_mail_attach_type type = esp_mail_att_type_none; - size_t size; -}; - -#if defined(ENABLE_SMTP) - -struct esp_mail_smtp_command_t -{ - char text[9]; -}; - -struct esp_mail_timestamp_value_t -{ - /* The time format of timestamp to inject into subject or content as using in strftime C++ function */ - MB_String format; - /* The tag that will be replaced with current timestamp */ - MB_String tag; -}; - -/** The SMTP commands per stansards. - * The arrangement is related to esp_mail_smtp_command_types enum. - * Do not modify or remove. - */ -const struct esp_mail_smtp_command_t smtp_commands[esp_mail_smtp_command_maxType] PROGMEM = { - "AUTH", - "LOGIN", - "HELO", - "EHLO", - "QUIT", - "MAIL", - "RCPT", - "DATA", - "BDAT", - "LAST", - "PLAIN", - "FROM:", - "TO:", - "NOTIFY", - "SUCCESS", - "FAILURE", - "DELAY", - "BODY", - "\r\n.\r\n", - "STARTTLS"}; - -struct esp_mail_smtp_commands_tokens -{ -public: - esp_mail_smtp_commands_tokens(bool pre) - { - preToken = pre; - } - MB_String operator[](size_t index) - { - MB_String s = preToken ? " " : smtp_commands[index].text; - s += !preToken ? " " : smtp_commands[index].text; - return s; - } - -private: - bool preToken = false; -}; - -// The smtp commands with leading space. -static esp_mail_smtp_commands_tokens smtp_cmd_pre_tokens(true); - -// The smtp commands with trailing space. -static esp_mail_smtp_commands_tokens smtp_cmd_post_tokens(false); - -#endif - -#if defined(ENABLE_IMAP) - -struct esp_mail_imap_command_t -{ - char text[15]; -}; - -/** The IMAP commands per standards. - * The arrangement is related to esp_mail_imap_command_types enum. - * Do not modify or remove. - */ -const struct esp_mail_imap_command_t imap_commands[esp_mail_imap_command_maxType] PROGMEM = { - "STARTTLS", - "APPEND", - "CAPABILITY", - "AUTHENTICATE", - "PLAIN", - "UID", - "FETCH", - "FLAGS", - "LOGIN", - "LIST", - "EXAMINE", - "SEARCH", - "LOGOUT", - "BODY", - "MIME", - "CLOSE", - "EXISTS", - "PEEK", - "TEXT", - "FIELDS", - "HEADER", - "NEW", - "ALL", - "SELECT", - "EXPUNGE", - "CREATE", - "DELETE", - "IDLE", - "DONE", - "RECENT", - "UNSEEN", - "RENAME", - "LSUB", - "SUBSCRIBE", - "UNSUBSCRIBE", - "SILENT", - "MOVE", - "GETQUOTA", - "SETQUOTA", - "ROOT", - "GETACL", - "SETACL", - "DELETEACL", - "MYRIGHTS", - "NAMESPACE", - "ENABLE", - "XOAUTH2", - "STORE", - "+FLAGS", - "-FLAGS", - "COPY", - "ID", - "UNSELECT", - "CONDSTORE", - "NOOP", - "UNCHANGEDSINCE", - "CHANGEDSINCE", - "MODSEC"}; - -struct esp_mail_imap_commands_tokens -{ -public: - esp_mail_imap_commands_tokens(bool pre) - { - preToken = pre; - } - MB_String operator[](size_t index) - { - MB_String s = preToken ? " " : imap_commands[index].text; - s += !preToken ? " " : imap_commands[index].text; - return s; - } - -private: - bool preToken = false; -}; - -// The imap commands with leading space. -static esp_mail_imap_commands_tokens imap_cmd_pre_tokens(true); - -// The imap commands with trailing space. -static esp_mail_imap_commands_tokens imap_cmd_post_tokens(false); - -struct esp_mail_imap_response_t -{ - char text[18]; -}; - -/** The IMAP response. - * The arrangement is related to esp_mail_imap_response_types enum. - * Do not modify or remove. - */ -const struct esp_mail_imap_response_t imap_responses[esp_mail_imap_response_maxType] PROGMEM = { - // Tagged - "OK ", - "NO ", - "BAD ", - // Untagged - "* LIST ", - "* FLAGS ", - "* SEARCH ", - " FETCH ", - " NIL ", - " UID ", - "* CAPABILITY ", - "CAPABILITY ", - "* LSUB ", - "* QUOTA ", - "* QUOTAROOT ", - "* ACL ", - "* MYRIGHTS ", - "* NAMESPACE ", - "* ", - " EXISTS", - " EXPUNGE", - " RECENT", - " [UIDNEXT ", - " [UNSEEN ", - "* ID ", - " [HIGHESTMODSEQ ", - " [NOMODSEQ]", - " [PERMANENTFLAGS ", - " [UIDVALIDITY "}; - -#endif - -struct esp_mail_char_decoding_t -{ - char text[12]; -}; - -/** Supported charactor encodings. - * The arrangement is related to esp_mail_char_decoding_types enum. - * Do not modify or remove. - */ -const struct esp_mail_char_decoding_t char_decodings[esp_mail_char_decoding_maxType] PROGMEM = { - "utf-8", - "iso-8859-1", - "iso-8859-11", - "tis-620", - "windows-874"}; - -struct esp_mail_multipart_t -{ - char text[22]; -}; - -/** MultiPart MIME. - * The arrangement is related to esp_mail_multipart_types enum. - * Do not modify or remove. - */ -const struct esp_mail_multipart_t multipart_types[esp_mail_multipart_maxType] PROGMEM = { - "multipart/mixed", - "multipart/related", - "multipart/parallel", - "multipart/alternative"}; - -struct esp_mail_rfc822_header_field_t -{ - char text[20]; - bool isNum; - bool trim; -}; - -/** The rfc822 message header fields. - * The arrangement is related to esp_mail_rfc822_header_field_types enum. - * Do not modify or remove. - */ -const struct esp_mail_rfc822_header_field_t rfc822_headers[esp_mail_rfc822_header_field_maxType] PROGMEM = { - {"From", false, true}, - {"Sender", false, true}, - {"To", false, true}, - {"Cc", false, true}, - {"Subject", false, false}, - {"Date", false, false}, - {"Message-ID", false, false}, - {"Return-Path", false, true}, - {"Reply-To", false, true}, - {"In-Reply-To", false, true}, - {"References", false, true}, - {"Comments", false, false}, - {"Keywords", false, false}, - {"Bcc", false, true}, - {"Flags", false, false}}; - -struct esp_mail_message_header_field_t -{ - char text[26]; -}; - -/** Additional fields and props. - * The arrangement is related to esp_mail_message_header_field_types enum. - * Do not modify or remove. - */ -const struct esp_mail_message_header_field_t message_headers[esp_mail_message_header_field_maxType] PROGMEM = { - "Number", - "UID", - "Accept-Language", - "Content-Language", - "Filename", - "Name", - "Size", - "MIME", - "Type", - "Description", - "Creation-Date", - "X-Priority", - "X-MSMail-Priority", - "Importance", - "Content-Type", - "Content-transfer-encoding", - "Content-Disposition", - "Content-Location", - "Content-ID", - "Content-Description", - "Mime-Version", - "Charset", - "format", - "delsp", - "Modification-Date"}; - -struct esp_mail_auth_capability_t -{ - char text[20]; -}; - -#if defined(ENABLE_SMTP) - -/** The server capability keywords per standard. - * The arrangement is related to esp_mail_auth_capability_types enum. - * Do not modify or remove. - */ -const struct esp_mail_auth_capability_t smtp_auth_capabilities[esp_mail_auth_capability_maxType] PROGMEM = { - "PLAIN", - "XOAUTH2", - "CRAM-MD5", - "DIGEST-MD5", - "LOGIN", - "STARTTLS", - "DUMMY_AUTH" /* SASL-IR */}; - -struct esp_mail_smtp_auth_tokens -{ -public: - esp_mail_smtp_auth_tokens(bool pre) - { - preToken = pre; - } - MB_String operator[](size_t index) - { - MB_String s = preToken ? " " : smtp_auth_capabilities[index].text; - s += !preToken ? " " : smtp_auth_capabilities[index].text; - return s; - } - -private: - bool preToken = false; -}; - -// The smtp auth capability with leading space. -static esp_mail_smtp_auth_tokens smtp_auth_cap_pre_tokens(true); -// The smtp auth capability with trailing space. -static esp_mail_smtp_auth_tokens smtp_auth_cap_post_tokens(false); - -struct esp_mail_smtp_send_capability_t -{ - char text[15]; -}; - -/** The server capability keywords per standard. - * The arrangement is related esp_mail_smtp_send_capability_types enum. - * Do not modify or remove. - */ -const struct esp_mail_smtp_send_capability_t smtp_send_capabilities[esp_mail_smtp_send_capability_maxType] PROGMEM = { - "BINARYMIME", - "8BITMIME", - "CHUNKING", - "SMTPUTF8", - "PIPELINING", - "DSN", - "" /* ESMTP */}; - -struct esp_mail_smtp_send_tokens -{ -public: - esp_mail_smtp_send_tokens(bool pre) - { - preToken = pre; - } - MB_String operator[](size_t index) - { - MB_String s = preToken ? " " : smtp_send_capabilities[index].text; - s += !preToken ? " " : smtp_send_capabilities[index].text; - return s; - } - -private: - bool preToken = false; -}; - -static esp_mail_smtp_send_tokens smtp_send_cap_pre_tokens(true); - -#endif - -#if defined(ENABLE_IMAP) - -/** The server capability keywords per standard. - * The arrangement is related esp_mail_auth_capability_types enum. - * Do not modify or remove. - */ -const struct esp_mail_auth_capability_t imap_auth_capabilities[esp_mail_auth_capability_maxType] PROGMEM = { - "AUTH=PLAIN", - "AUTH=XOAUTH2", - "CRAM-MD5", - "DIGEST-MD5", - "DUMMY_AUTH", /* Log in */ - "STARTTLS", - "SASL-IR"}; - -struct esp_mail_imap_auth_tokens -{ -public: - esp_mail_imap_auth_tokens(bool pre) - { - preToken = pre; - } - MB_String operator[](size_t index) - { - MB_String s = preToken ? " " : imap_auth_capabilities[index].text; - s += !preToken ? " " : imap_auth_capabilities[index].text; - return s; - } - -private: - bool preToken = false; -}; - -// The imap auth capability with leading space. -static esp_mail_imap_auth_tokens imap_auth_cap_pre_tokens(true); - -struct esp_mail_imap_read_capability_t -{ - char text[15]; -}; - -/** The server capability keywords per standard. - * The arrangement is related esp_mail_imap_read_capability_types enum. - * Do not modify or remove. - */ -const struct esp_mail_imap_read_capability_t imap_read_capabilities[esp_mail_imap_read_capability_maxType] PROGMEM = { - "IMAP4", - "IMAP4rev1", - "IDLE", - "LITERAL+", - "LITERAL-", - "MULTIAPPEND", - "UIDPLUS", - "ACL", - "BINARY", - "LOGINDISABLED", - "MOVE", - "QUOTA", - "NAMESPACE", - "ENABLE", - "ID", - "UNSELECT", - "CHILDREN", - "CONDSTORE" - "" /* Auto cap */}; - -struct esp_mail_imap_read_tokens -{ -public: - esp_mail_imap_read_tokens(bool pre) - { - preToken = pre; - } - MB_String operator[](size_t index) - { - MB_String s = preToken ? " " : imap_read_capabilities[index].text; - s += !preToken ? " " : imap_read_capabilities[index].text; - return s; - } - -private: - bool preToken = false; -}; - -// The imap auth capability with leading space. -static esp_mail_imap_read_tokens imap_read_cap_pre_tokens(true); - -// The imap auth capability with trailing space. -static esp_mail_imap_read_tokens imap_read_cap_post_tokens(false); - -struct esp_mail_imap_identification_key_t -{ - char text[15]; -}; - -/** The identification keys per standard. - * The arrangement is related esp_mail_imap_identification_key_types enum. - * Do not modify or remove. - */ -const struct esp_mail_imap_identification_key_t imap_identification_keys[esp_mail_imap_identification_key_maxType] PROGMEM = { - "name", - "version", - "os", - "os-version", - "vendor", - "support-url", - "address", - "date", - "command", - "arguments", - "environment"}; - -/* The IMAP ID data struct */ -typedef struct esp_mail_imap_identity_t -{ - MB_String name; - MB_String version; - MB_String os; - MB_String os_version; - MB_String vendor; - MB_String support_url; - MB_String address; - MB_String date; - MB_String command; - MB_String arguments; - MB_String environment; - -} IMAP_Identification; - -#endif - -#endif - -#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) -/* The email address info [SMTP_Message]*/ -struct esp_mail_address_info_t -{ - /* The name of Email author/sender */ - MB_String name; - - /* The Email address */ - MB_String email; -}; -#endif - -#if defined(ENABLE_SMTP) - -/* The SMTP message notification types enum */ -enum esp_mail_smtp_notify -{ - esp_mail_smtp_notify_never = 0, - esp_mail_smtp_notify_success = 1, - esp_mail_smtp_notify_failure = 2, - esp_mail_smtp_notify_delay = 4 -}; - -/* The SMTP status codes enum */ -enum esp_mail_smtp_status_code -{ - esp_mail_smtp_status_code_0, // default - - /* Positive Completion */ - esp_mail_smtp_status_code_211 = 221, // System status, or system help reply - esp_mail_smtp_status_code_214 = 214, // Help message(A response to the HELP command) - esp_mail_smtp_status_code_220 = 220, // Service ready - esp_mail_smtp_status_code_221 = 221, // Service closing transmission channel [RFC 2034] - esp_mail_smtp_status_code_235 = 235, // 2.7.0 Authentication succeeded[RFC 4954] - esp_mail_smtp_status_code_250 = 250, // Requested mail action okay, completed - esp_mail_smtp_status_code_251 = 251, // User not local; will forward - esp_mail_smtp_status_code_252 = 252, // Cannot verify the user, but it will - // try to deliver the message anyway - - /* Positive Intermediate */ - esp_mail_smtp_status_code_334 = 334, //(Server challenge - the text part - // contains the Base64 - encoded - // challenge)[RFC 4954] - esp_mail_smtp_status_code_354 = 354, // Start mail input - - /* Transient Negative Completion */ - /* "Transient Negative" means the error condition is temporary, and the action - may be requested again.*/ - esp_mail_smtp_status_code_421 = 421, // Service is unavailable because the server is shutting down. - esp_mail_smtp_status_code_432 = 432, // 4.7.12 A password transition is needed [RFC 4954] - esp_mail_smtp_status_code_450 = 450, // Requested mail action not taken: mailbox unavailable (e.g., - // mailbox busy or temporarily blocked for policy reasons) - esp_mail_smtp_status_code_451 = 451, // Requested action aborted : local error in processing - // e.g.IMAP server unavailable[RFC 4468] - esp_mail_smtp_status_code_452 = 452, // Requested action not taken : insufficient system storage - esp_mail_smtp_status_code_454 = 454, // 4.7.0 Temporary authentication failure[RFC 4954] - esp_mail_smtp_status_code_455 = 455, // Server unable to accommodate parameters - - /* Permanent Negative Completion */ - esp_mail_smtp_status_code_500 = 500, // Syntax error, command unrecognized - // (This may include errors such as - // command line too long) - // e.g. Authentication Exchange line is too long [RFC 4954] - esp_mail_smtp_status_code_501 = 501, // Syntax error in parameters or arguments - // e.g. 5.5.2 Cannot Base64-decode Client responses [RFC 4954] - // 5.7.0 Client initiated Authentication Exchange (only when the SASL - // mechanism specified that client does not begin the authentication exchange) - // [RFC 4954] - esp_mail_smtp_status_code_502 = 502, // Command not implemented - esp_mail_smtp_status_code_503 = 503, // Bad sequence of commands - esp_mail_smtp_status_code_504 = 504, // Command parameter is not implemented - // e.g. 5.5.4 Unrecognized authentication type [RFC 4954] - esp_mail_smtp_status_code_521 = 521, // Server does not accept mail [RFC 7504] - esp_mail_smtp_status_code_523 = 523, // Encryption Needed [RFC 5248] - esp_mail_smtp_status_code_530 = 530, // 5.7.0 Authentication required [RFC 4954] - esp_mail_smtp_status_code_534 = 534, // 5.7.9 Authentication mechanism is too weak [RFC 4954] - esp_mail_smtp_status_code_535 = 535, // 5.7.8 Authentication credentials invalid [RFC 4954] - esp_mail_smtp_status_code_538 = 538, // 5.7.11 Encryption required for - // requested authentication mechanism[RFC - // 4954] - esp_mail_smtp_status_code_550 = 550, // Requested action not taken: mailbox unavailable (e.g., mailbox not - // found, no access, or command rejected for policy reasons) - esp_mail_smtp_status_code_551 = 551, // User not local; please try - esp_mail_smtp_status_code_552 = 552, // Requested mail action aborted: exceeded storage allocation - esp_mail_smtp_status_code_553 = 553, // Requested action not taken: mailbox name not allowed - esp_mail_smtp_status_code_554 = 554, // Transaction has failed (Or, in the - // case of a connection-opening response, - // "No SMTP service here") - // e.g. 5.3.4 Message too big for system [RFC 4468] - esp_mail_smtp_status_code_556 = 556, // Domain does not accept mail[RFC 7504] -}; - -/* The SMTP ports enum */ -enum esp_mail_smtp_port -{ - esp_mail_smtp_port_25 = 25, // PLAIN/TLS with STARTTLS - esp_mail_smtp_port_465 = 465, // SSL - esp_mail_smtp_port_587 = 587, // TLS with STARTTLS -}; - -const struct port_function smtp_ports[3] = { - {esp_mail_smtp_port_25, esp_mail_protocol_plain_text}, - {esp_mail_smtp_port_465, esp_mail_protocol_ssl}, - {esp_mail_smtp_port_587, esp_mail_protocol_tls}}; - -/* The SMTP message response [SMTP_Message] */ -struct esp_mail_smtp_msg_response_t -{ - /* The author Email address to reply */ - MB_String reply_to; - - /* The sender Email address to return the message */ - MB_String return_path; - - /** The Delivery Status Notifications e.g. esp_mail_smtp_notify_never, - * esp_mail_smtp_notify_success, - * esp_mail_smtp_notify_failure, and - * esp_mail_smtp_notify_delay - */ - int notify = esp_mail_smtp_notify::esp_mail_smtp_notify_never; -}; - -/* The SMTP enable option [SMTP_Message] */ -struct esp_mail_smtp_enable_option_t -{ - /* Enable chunk data sending for large message */ - bool chunking = false; -}; - -/* The SMTP blob data attachment data [Session_Config] */ -struct esp_mail_attach_blob_t -{ - /* BLOB data (flash or ram) */ - const uint8_t *data = nullptr; - - /* BLOB data size in byte */ - size_t size = 0; -}; - -/* The SMTP file attachment data [Session_Config] */ -struct esp_mail_attach_file_t -{ - MB_String path; - /** The file storage type e.g. esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - esp_mail_file_storage_type storage_type = esp_mail_file_storage_type_none; -}; - -/* The SMTP attachment decription [Session_Config] */ -struct esp_mail_attach_descr_t -{ - /* The name of attachment */ - MB_String name; - - /* The attachment file name */ - MB_String filename; - - /* The MIME type of attachment */ - MB_String mime; - - /* The transfer encoding of attachment e.g. base64 */ - MB_String transfer_encoding = "base64"; - - /* The content encoding of attachment e.g. base64 */ - MB_String content_encoding; - - /* The content id of attachment file */ - MB_String content_id; - - /* The description of attachment file */ - MB_String description; -}; - -/* Used internally in esp_mail_attachment_t */ -struct esp_mail_attach_internal_t -{ - esp_mail_attach_type att_type = esp_mail_att_type_attachment; - int index = 0; - int msg_uid = 0; - bool flash_blob = false; - esp_mail_msg_xencoding xencoding = esp_mail_msg_xencoding_none; - bool parallel = false; - MB_String cid; -}; - -/* The struct used as SMTP_Attachment for SMTP and ESP_Mail_Attachment for IMAP */ -struct esp_mail_attachment_t -{ - /* The attachment description */ - struct esp_mail_attach_descr_t descr; - - /* The BLOB data config */ - struct esp_mail_attach_blob_t blob; - - /* The file data config */ - struct esp_mail_attach_file_t file; - - /* reserved for internal usage */ - struct esp_mail_attach_internal_t _int; -}; - -/* The struct used as SMTP_Result */ -struct esp_mail_smtp_send_status_t -{ - /* The status of the message */ - bool completed = false; - - /* The primary recipient mailbox of the message */ - MB_String recipients; - - /* The topic of the message */ - MB_String subject; - - /* The timestamp of the message */ - uint32_t timestamp = 0; -}; - -/* Used internally for SMTPSession */ -struct esp_mail_smtp_msg_type_t -{ - bool rfc822 = false; - int rfc822Idx = 0; -}; - -/* Used internally for holding base64 data sources */ -struct esp_mail_smtp_send_base64_data_info_t -{ - esp_mail_file_storage_type storageType = esp_mail_file_storage_type_none; - const char *filename = ""; - const uint8_t *rawPtr = nullptr; - bool flashMem = false; - size_t size = 0; - size_t dataIndex = 0; -}; - -/* SMTP commands types enum */ -enum esp_mail_smtp_command -{ - esp_mail_smtp_cmd_undefined, - esp_mail_smtp_cmd_initial_state, - esp_mail_smtp_cmd_greeting, - esp_mail_smtp_cmd_start_tls, - esp_mail_smtp_cmd_login_user, - esp_mail_smtp_cmd_auth_plain, - esp_mail_smtp_cmd_auth_login, - esp_mail_smtp_cmd_auth_xoauth2, - esp_mail_smtp_cmd_login_psw, - esp_mail_smtp_cmd_send_header_sender, - esp_mail_smtp_cmd_send_header_recipient, - esp_mail_smtp_cmd_send_body, - esp_mail_smtp_cmd_chunk_termination, - esp_mail_smtp_cmd_logout, - esp_mail_smtp_cmd_custom -}; - -/* SMTP message priority level enum */ -enum esp_mail_smtp_priority -{ - esp_mail_smtp_priority_high = 1, - esp_mail_smtp_priority_normal = 3, - esp_mail_smtp_priority_low = 5, -}; - -/* SMTP response data */ -typedef struct esp_mail_smtp_response_status_t -{ - /* The SMTP server response status code */ - int statusCode = 0; - - /* error code */ - int errorCode = 0; - int id = -1; - MB_String text; -} SMTP_Response; - -#endif - -#if defined(ENABLE_IMAP) - -enum esp_mail_imap_msg_num_type -{ - esp_mail_imap_msg_num_type_undefined, - esp_mail_imap_msg_num_type_uid, - esp_mail_imap_msg_num_type_number -}; - -enum esp_mail_imap_store_flag_type -{ - esp_mail_imap_store_flag_type_set, - esp_mail_imap_store_flag_type_add, - esp_mail_imap_store_flag_type_remove -}; - -enum esp_mail_char_decoding_scheme -{ - esp_mail_char_decoding_scheme_default = -1, - esp_mail_char_decoding_scheme_utf_8, - esp_mail_char_decoding_scheme_iso8859_1, - esp_mail_char_decoding_scheme_iso8859_11, - esp_mail_char_decoding_scheme_tis_620, - esp_mail_char_decoding_scheme_windows_874 -}; - -enum esp_mail_imap_rights_type_t -{ - /* a - administer (perform SETACL/DELETEACL/GETACL/LISTRIGHTS) */ - esp_mail_imap_rights_administer = 'a' - 'a', - /* c - RFC2086 (obsoleted) create (CREATE new sub-mailboxes in any implementation-defined hierarchy) */ - esp_mail_imap_rights_create_c = 'c' - 'a', - /* d - RFC2086 (obsoleted) delete (STORE DELETED flag, perform EXPUNGE) */ - esp_mail_imap_rights_delete_d = 'd' - 'a', - /* e - perform EXPUNGE and expunge as a part of CLOSE */ - esp_mail_imap_rights_expunge = 'e' - 'a', - /* i - insert (perform APPEND, COPY into mailbox) */ - esp_mail_imap_rights_insert = 'i' - 'a', - /* k - RFC4314 create mailboxes (CREATE new sub-mailboxes in any implementation-defined hierarchy, parent mailbox for the new mailbox name in RENAME)*/ - esp_mail_imap_rights_create = 'k' - 'a', - /* l - lookup (mailbox is visible to LIST/LSUB commands, SUBSCRIBE mailbox) */ - esp_mail_imap_rights_lookup = 'l' - 'a', - /* p - post (send mail to submission address for mailbox, not enforced by IMAP4 itself) */ - esp_mail_imap_rights_post = 'p' - 'a', - /* r - read (SELECT the mailbox, perform STATUS) */ - esp_mail_imap_rights_read = 'r' - 'a', - /* s - keep seen/unseen information across sessions (set or clear \SEEN flag via STORE, also set \SEEN during APPEND/COPY/ FETCH BODY[...]) */ - esp_mail_imap_rights_seen = 's' - 'a', - /* t - RFC4314 delete messages (set or clear \DELETED flag via STORE, set \DELETED flag during APPEND/COPY) */ - esp_mail_imap_rights_delete_message = 't' - 'a', - /* w - write (set or clear flags other than \SEEN and \DELETED via STORE, also set them during APPEND/COPY) */ - esp_mail_imap_rights_write = 'w' - 'a', - /* x - RFC4314 delete mailbox (DELETE mailbox, old mailbox name in RENAME) */ - esp_mail_imap_rights_delete_mailbox = 'x' - 'a', - - esp_mail_imap_rights_maxType = esp_mail_imap_rights_delete_mailbox + 1 -}; - -enum esp_mail_imap_port -{ - esp_mail_imap_port_143 = 143, // PLAIN/TLS with STARTTLS - esp_mail_imap_port_993 = 993, // SSL -}; - -const struct port_function imap_ports[2] = { - {esp_mail_imap_port_143, esp_mail_protocol_plain_text}, - {esp_mail_imap_port_993, esp_mail_protocol_ssl}}; - -enum esp_mail_imap_auth_mode -{ - esp_mail_imap_mode_examine, - esp_mail_imap_mode_select -}; - -enum esp_mail_imap_response_status -{ - esp_mail_imap_resp_unknown, - esp_mail_imap_resp_ok, - esp_mail_imap_resp_no, - esp_mail_imap_resp_bad -}; - -enum esp_mail_imap_polling_status_type -{ - imap_polling_status_type_undefined, - imap_polling_status_type_new_message, - imap_polling_status_type_remove_message, - imap_polling_status_type_fetch_message -}; - -enum esp_mail_imap_header_state -{ - esp_mail_imap_state_content_type = esp_mail_rfc822_header_field_maxType, - esp_mail_imap_state_content_transfer_encoding, - esp_mail_imap_state_accept_language, - esp_mail_imap_state_content_language, - esp_mail_imap_state_char_set, - esp_mail_imap_state_boundary -}; - -enum esp_mail_imap_command -{ - esp_mail_imap_cmd_capability, - esp_mail_imap_cmd_starttls, - esp_mail_imap_cmd_sasl_login, - esp_mail_imap_cmd_sasl_auth_plain, - esp_mail_imap_cmd_sasl_auth_oauth, - esp_mail_imap_cmd_list, - esp_mail_imap_cmd_lsub, - esp_mail_imap_cmd_subscribe, - esp_mail_imap_cmd_unsubscribe, - esp_mail_imap_cmd_select, - esp_mail_imap_cmd_examine, - esp_mail_imap_cmd_close, - esp_mail_imap_cmd_status, - esp_mail_imap_cmd_search, - esp_mail_imap_cmd_fetch_body_header, - esp_mail_imap_cmd_fetch_body_mime, - esp_mail_imap_cmd_fetch_body_text, - esp_mail_imap_cmd_fetch_body_attachment, - esp_mail_imap_cmd_fetch_body_inline, - esp_mail_imap_cmd_fetch_sequence_set, - esp_mail_imap_cmd_logout, - esp_mail_imap_cmd_store, - esp_mail_imap_cmd_move, - esp_mail_imap_cmd_get_quota, - esp_mail_imap_cmd_set_quota, - esp_mail_imap_cmd_get_quota_root, - esp_mail_imap_cmd_get_acl, - esp_mail_imap_cmd_set_acl, - esp_mail_imap_cmd_delete_acl, - esp_mail_imap_cmd_my_rights, - esp_mail_imap_cmd_namespace, - esp_mail_imap_cmd_expunge, - esp_mail_imap_cmd_create, - esp_mail_imap_cmd_rename, - esp_mail_imap_cmd_delete, - esp_mail_imap_cmd_idle, - esp_mail_imap_cmd_done, - esp_mail_imap_cmd_get_uid, - esp_mail_imap_cmd_get_flags, - esp_mail_imap_cmd_append, - esp_mail_imap_cmd_append_last, - esp_mail_imap_cmd_enable, - esp_mail_imap_cmd_id, - esp_mail_imap_cmd_unselect, - esp_mail_imap_cmd_noop, - esp_mail_imap_cmd_copy, - esp_mail_imap_cmd_custom -}; - -enum esp_mail_imap_mime_fetch_type -{ - esp_mail_imap_mime_fetch_type_part, - esp_mail_imap_mime_fetch_type_sub_part1, - esp_mail_imap_mime_fetch_type_sub_part2 -}; - -enum esp_mail_imap_header_type -{ - esp_mail_imap_header_from, - esp_mail_imap_header_to, - esp_mail_imap_header_cc, - esp_mail_imap_header_subject, - esp_mail_imap_header_date, - esp_mail_imap_header_msg_id, - esp_mail_imap_header_cont_lang, - esp_mail_imap_header_accept_lang -}; - -enum esp_mail_imap_multipart_sub_type -{ - esp_mail_imap_multipart_sub_type_none = 0, - esp_mail_imap_multipart_sub_type_mixed, - esp_mail_imap_multipart_sub_type_alternative, - esp_mail_imap_multipart_sub_type_parallel, - esp_mail_imap_multipart_sub_type_digest, - esp_mail_imap_multipart_sub_type_related, - esp_mail_imap_multipart_sub_type_report, -}; - -enum esp_mail_imap_message_sub_type -{ - esp_mail_imap_message_sub_type_none = 0, - esp_mail_imap_message_sub_type_rfc822, - esp_mail_imap_message_sub_type_delivery_status, - esp_mail_imap_message_sub_type_partial, - esp_mail_imap_message_sub_type_external_body, -}; - -typedef struct esp_mail_imap_response_status_t -{ - // No IMAP server response status code (statusCode), server returns OK, NO and BAD response instead - - /* error code */ - int errorCode = 0; - MB_String tag; - MB_String text; - MB_String status; - bool completed = false; - -public: - void clear(bool clearTag = true) - { - if (clearTag) - tag.clear(); - status.clear(); - text.clear(); - completed = false; - } -} IMAP_Response; - -struct esp_mail_imap_msg_num_t -{ - esp_mail_imap_msg_num_type type = esp_mail_imap_msg_num_type_undefined; - uint32_t value = 0; -}; - -__attribute__((used)) struct -{ - bool operator()(struct esp_mail_imap_msg_num_t a, struct esp_mail_imap_msg_num_t b) const { return a.value > b.value; } -} compareMore; - -struct esp_mail_imap_rfc822_msg_header_item_t -{ - MB_String header_items[esp_mail_rfc822_header_field_maxType]; -}; - -/* IMAP quota root info */ -typedef struct esp_mail_imap_quota_root_info_t -{ - /* The quota root */ - MB_String quota_root; - - /* The resource name e.g. STORAGE and MESSAGE */ - MB_String name; - - /* The resource usage in kilo octets */ - size_t usage = 0; - - /* The resource limit in kilo octets */ - size_t limit = 0; - -} IMAP_Quota_Root_Info; - -/* IMAP namespace info */ -typedef struct esp_mail_imap_namespace_info_t -{ - /* The leading prefix */ - MB_String prefix; - - /* The hierarchy delimiter */ - MB_String delimiter; - -} IMAP_Namespace_Info; - -typedef struct esp_mail_imap_rights_info_t -{ - MB_String identifier; - bool rights[esp_mail_imap_rights_maxType]; - -} IMAP_Rights_Info; - -/* descrete media types (rfc 2046) */ -struct esp_mail_imap_descrete_media_type_t -{ - /** textual information with subtypes - * "plain" - * "enriched" (rfc 1896 revised from richtext in rfc 1341) - * - * unrecognized subtypes and charset should be interpreted as - * application/octet-stream - * - * parameters: - * "charset" (rfc 2045) default is us-ascii - * for character set includes 8-bit characters - * and such characters are used in the body, Content-Transfer-Encoding - * header field and a corresponding encoding on the data are required - * - * ISO-8859-X where "X" is to be replaced, as - * necessary, for the parts of ISO-8859 [ISO-8859]. - */ - static constexpr const char *text = "text"; - - /** image data with subtypes (rfc 2048) - * "jpeg" - * "gif" - * - * unrecognized subtypes should be interpreted as application/octet-stream - */ - static constexpr const char *image = "image"; - - /** audio data with initial subtype - * "baic" -- for single channel audio encoded using 8bit ISDN mu-law [PCM] - * at a sample rate of 8000 Hz. - * - * Unrecognized subtypes of "audio" should at a miniumum be treated as - * "application/octet-stream" - */ - static constexpr const char *audio = "audio"; - - /** video data with initial subtype - * "mpeg" - * - * Unrecognized subtypes of "video" should at a minumum be treated as - * "application/octet-stream" - */ - static constexpr const char *video = "video"; - - /** some other kind of data, typically either - * uninterpreted binary data or information to be - * processed by an application with subtypes - * - * "octet-stream" -- uninterpreted binary data - * "PostScript" -- for the transport of PostScript material - * - * Other expected uses include spreadsheets, data for mail-based - * scheduling systems, and languages for "active" (computational) - * messaging, and word processing formats that are not directly readable. - * - * The octet-stream subtype parameters: - * TYPE, PADDING, NAME - */ - static constexpr const char *application = "application"; -}; - -/** composite media types (rfc 2046) - * - * As stated in the definition of the Content-Transfer-Encoding field - * [RFC 2045], no encoding other than "7bit", "8bit", or "binary" is - * permitted for entities of type "multipart". The "multipart" boundary - * delimiters and header fields are always represented as 7bit US-ASCII - * in any case (though the header fields may encode non-US-ASCII header - * text as per RFC 2047) and data within the body parts can be encoded - * on a part-by-part basis, with Content-Transfer-Encoding fields for - * each appropriate body part. - */ -struct esp_mail_imap_composite_media_type_t -{ - /** data consisting of multiple entities of independent data types - * The Content-Type field for multipart entities requires one parameter, - * "boundary". - * The boundary delimiter line is then defined as a line - * consisting entirely of two hyphen characters ("-", decimal value 45) - * followed by the boundary parameter value from the Content-Type header - * field, optional linear whitespace, and a terminating CRLF. - * - * NOTE: The CRLF preceding the boundary delimiter line is conceptually - * attached to the boundary so that it is possible to have a part that - * does not end with a CRLF (line break). Body parts that must be - * considered to end with line breaks, therefore, must have two CRLFs - * preceding the boundary delimiter line, the first of which is part of - * the preceding body part, and the second of which is part of the - * encapsulation boundary. - * - * Boundary delimiters must not appear within the encapsulated material, - * and must be no longer than 70 characters, not counting the two - * leading hyphens. - * - * The boundary delimiter line following the last body part is a - * distinguished delimiter that indicates that no further body parts - * will follow. Such a delimiter line is identical to the previous - * delimiter lines, with the addition of two more hyphens after the - * boundary parameter value. - * - * See rfc2049 Appendix A for a Complex Multipart Example - */ - static constexpr const char *multipart = "multipart"; - - /* an encapsulated message */ - static constexpr const char *message = "message"; -}; - -typedef struct esp_mail_imap_mime_data_stream_info_t -{ - /* message UID */ - uint32_t uid = 0; - - /* content type */ - const char *type = ""; - - /* disposition */ - const char *disposition = ""; - - /* content character set */ - const char *charSet = ""; - - /* text content flowed format parameter */ - bool flowed = false; - - /* text content format DelSp parameter */ - bool delsp = false; - - /* content transfer encoding */ - const char *transfer_encoding = ""; - - /* content ID */ - const char *cid = ""; - - /* content description */ - const char *description = ""; - - /* content file name */ - const char *filename = ""; - - /* content name */ - const char *name = ""; - - /* creation date */ - const char *date = ""; - - /* content size */ - size_t size = 0; - - /* octet size */ - size_t octet_size = 0; - - /* current octet count */ - int octet_count = 0; - - /* data size */ - size_t data_size = 0; - - /* data buffer */ - void *data = NULL; - - bool isFirstData = false; - - bool isLastData = false; - -} MIME_Data_Stream_Info; - -typedef struct esp_mail_imap_decoding_info -{ - enum message_part_type - { - message_part_type_header, - message_part_type_text - }; - - /* The character set of the string to decode */ - const char *charset = ""; - - /* The string to decode */ - const char *data = ""; - - /* The decoded string to be processed */ - MB_String decodedString; - - /** The type of data that currently processed - * 0 or IMAP_Decoding_Info::message_part_type_header - * 1 or IMAP_Decoding_Info::message_part_type_text - */ - message_part_type type = message_part_type_header; - -} IMAP_Decoding_Info; - -struct esp_mail_imap_media_text_sub_type_t -{ - static constexpr const char *plain = "plain"; - static constexpr const char *enriched = "enriched"; - static constexpr const char *html = "html"; -}; - -/* multipart sub types */ -struct esp_mail_imap_multipart_sub_type_t -{ - /* a generic mixed set of parts */ - static constexpr const char *mixed = "mixed"; - - /* the same data in multiple formats */ - static constexpr const char *alternative = "alternative"; - - /* parts intended to be viewed simultaneously */ - static constexpr const char *parallel = "parallel"; - - /* multipart entities in which each part has a default type of - * "message/rfc822" */ - static constexpr const char *digest = "digest"; - - /* for compound objects consisting of several inter-related body parts (rfc - * 2387) */ - static constexpr const char *related = "related"; - - /* rfc 3462 */ - static constexpr const char *report = "report"; -}; - -/* message body sub types */ -struct esp_mail_imap_message_sub_type_t -{ - /* body contains an encapsulated message, with the syntax of an RFC 822 - * message. */ - static constexpr const char *rfc822 = "rfc822"; - - /* to allow large objects to be delivered as several separate pieces of mail - */ - static constexpr const char *Partial = "Partial"; - - /* the actual body data are not included, but merely referenced */ - static constexpr const char *External_Body = "External-Body"; - - static constexpr const char *delivery_status = "delivery-status"; -}; - -/* IMAP polling status */ -typedef struct esp_mail_imap_polling_status_t -{ - /** The type of status e.g. imap_polling_status_type_undefined, imap_polling_status_type_new_message, - * imap_polling_status_type_fetch_message and imap_polling_status_type_remove_message. - */ - esp_mail_imap_polling_status_type type = imap_polling_status_type_undefined; - - /** Message number or order from the total number of message that added, fetched or deleted. - */ - size_t messageNum = 0; - - /** Argument of commands e.g. FETCH - */ - MB_String argument; -} IMAP_Polling_Status; - -struct esp_mail_message_part_info_t -{ - enum content_header_field - { - content_header_field_none, - content_header_field_type, - content_header_field_description, - content_header_field_id, - content_header_field_disposition, - content_header_field_transfer_enc, - content_header_field_ext - - }; - - int octetLen = 0; - int octetCount = 0; - int attach_data_size = 0; - int textLen = 0; - bool sizeProp = false; - int nestedLevel = 0; - - // pointer to the MB_String for storing multi-line header field content. - uint32_t stringPtr = 0; - esp_mail_char_decoding_scheme stringEnc = esp_mail_char_decoding_scheme_default; - - content_header_field cur_content_hdr = content_header_field_none; - - MB_String partNumStr; - MB_String partNumFetchStr; - MB_String text; - MB_String filename; - MB_String CID; - MB_String type; - MB_String save_path; - MB_String name; - MB_String content_disposition; - MB_String content_description; - MB_String content_type; - MB_String descr; - MB_String content_transfer_encoding; - MB_String creation_date; - MB_String modification_date; - MB_String charset; - MB_String download_error; - esp_mail_attach_type attach_type = esp_mail_att_type_none; - esp_mail_message_type msg_type = esp_mail_msg_type_none; - bool file_open_write = false; - bool multipart = false; - bool is_firmware_file = false; - bool save_to_file = true; - size_t firmware_downloaded_byte = 0; - esp_mail_imap_multipart_sub_type multipart_sub_type = esp_mail_imap_multipart_sub_type_none; - esp_mail_imap_message_sub_type message_sub_type = esp_mail_imap_message_sub_type_none; - bool rfc822_part = false; - int rfc822_msg_Idx = 0; - struct esp_mail_imap_rfc822_msg_header_item_t rfc822_header; - bool error = false; - bool plain_flowed = false; - bool plain_delsp = false; - esp_mail_msg_xencoding xencoding = esp_mail_msg_xencoding_none; -}; - -struct esp_mail_message_header_t -{ - int header_data_len = 0; - - struct esp_mail_imap_rfc822_msg_header_item_t header_fields; - - MB_String content_type; - MB_String content_transfer_encoding; - uint32_t message_uid = 0; - uint32_t message_no = 0; - MB_String boundary; - MB_String accept_language; - MB_String content_language; - MB_String char_set; - bool multipart = false; - bool rfc822_part = false; - bool hasAttachment = false; - int rfc822Idx = 0; - MB_String partNumStr; - - esp_mail_imap_multipart_sub_type multipart_sub_type = esp_mail_imap_multipart_sub_type_none; - esp_mail_imap_message_sub_type message_sub_type = esp_mail_imap_message_sub_type_none; - MB_String msgID; - MB_String flags; - MB_String error_msg; - bool error = false; - _vectorImpl part_headers; - int attachment_count = 0; - int sd_alias_file_count = 0; - int total_download_size = 0; - int downloaded_size = 0; - int total_attach_data_size = 0; - int downloaded_bytes = 0; - int message_data_count = 0; -}; - -/* Internal use */ -struct esp_mail_folder_info_t -{ - MB_String name; - MB_String attributes; - MB_String delimiter; -}; - -struct esp_mail_folder_info_item_t -{ - /* The name of folder */ - const char *name = ""; - - /* The attributes of folder */ - const char *attributes = ""; - - /* The delimeter of folder */ - const char *delimiter = ""; -}; - -struct esp_mail_imap_download_config_t -{ - /* To download the PLAIN text content of the message */ - bool text = false; - - /* To download the HTML content of the message */ - bool html = false; - - /* To download the attachments of the message */ - bool attachment = false; - - /* To download the inline image of the message */ - bool inlineImg = false; - - /* To download the rfc822 mesages in the message */ - bool rfc822 = false; - - /* To download the message header */ - bool header = false; -}; - -struct esp_mail_imap_enable_config_t -{ - /* To store the PLAIN text of the message in the IMAPSession */ - bool text = false; - - /* To store the HTML of the message in the IMAPSession */ - bool html = false; - - /* To store the rfc822 messages in the IMAPSession */ - bool rfc822 = false; - - /* To enable the download status via the serial port */ - bool download_status = false; - - /* To sort the message UID of the search result in descending order */ - bool recent_sort = false; - - /* To allow case sesitive in header parsing */ - bool header_case_sensitive = false; -}; - -struct esp_mail_imap_limit_config_t -{ - /* The maximum messages from the search result */ - size_t search = 10; - - /* The maximum messages from the sequence set fetching result */ - size_t fetch = 30; - - /** The maximum size of the memory buffer to store the message content. - * This is only limit for data to be stored in the IMAPSession. - */ - size_t msg_size = 1024; - - /* The maximum size of each attachment to download */ - size_t attachment_size = 1024 * 1024 * 5; - - /* The IMAP idle timeout in ms (1 min to 29 min). Default is 8 min */ - size_t imap_idle_timeout = 8 * 60 * 1000; - - /** The IMAP idle host check interval in ms (30 sec to imap_idle_timeout) - * for internet availability checking to ensure the connection is active. - * Default is 1 min. - */ - size_t imap_idle_host_check_interval = 60 * 1000; -}; - -struct esp_mail_imap_storage_config_t -{ - /* The path to save the downloaded file */ - MB_String saved_path; - - /** The type of file storages e.g. - * esp_mail_file_storage_type_none, - * esp_mail_file_storage_type_flash, and - * esp_mail_file_storage_type_sd - */ - esp_mail_file_storage_type type = esp_mail_file_storage_type_flash; -}; - -struct esp_mail_imap_search_config_t -{ - /* The search criteria */ - MB_String criteria; - - /* The option to search the unseen message */ - bool unseen_msg = false; -}; - -struct esp_mail_imap_sequence_set_t -{ - /* The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number */ - MB_String string; - - /* The option for sequenceSet whether it is UID or message sequence number */ - bool UID = false; - - /* The option for header only fetching */ - bool headerOnly = false; -}; - -struct esp_mail_imap_fetch_config_t -{ - /* The UID of message to fetch */ - MB_String uid; - - /* The message sequence number to fetch */ - MB_String number; - - /* The sequence set options */ - esp_mail_imap_sequence_set_t sequence_set; - - /* Set the message flag as seen */ - bool set_seen = false; - - /* The int32_t option for CHANGESINCE conditional test. */ - int32_t modsequence = 0; - - /* The config to fetch only the header */ - bool headerOnly = false; -}; - -struct esp_mail_imap_firmware_config_t -{ - /* Update firmware using message attachments if one of its filename matches. */ - MB_String attach_filename; - - /* Save firmware file */ - bool save_to_file = false; -}; - -struct esp_mail_imap_data_config_t -{ - /* The config for fetching */ - struct esp_mail_imap_fetch_config_t fetch; - - /* The config for search */ - struct esp_mail_imap_search_config_t search; - - /* The config about the limits */ - struct esp_mail_imap_limit_config_t limit; - - /* The config to enable the features */ - struct esp_mail_imap_enable_config_t enable; - - /* The config about downloads */ - struct esp_mail_imap_download_config_t download; - - /* The config about the storage and path to save the downloaded file */ - struct esp_mail_imap_storage_config_t storage; - - /* The config about firmware updates and downloads for ESP32, ESP8266 and Raspberry Pi Pico */ - struct esp_mail_imap_firmware_config_t firmware_update; - - IMAP_Identification identification; -}; - -/* Mail and MIME Header Fields */ -struct esp_mail_imap_msg_item_t -{ - friend class IMAPSession; - -public: - esp_mail_imap_msg_item_t() - { - text.content_type = mimeinfo[esp_mail_file_extension_txt].mimeType; - html.content_type = mimeinfo[esp_mail_file_extension_html].mimeType; - }; - - /* The message number */ - int msgNo = 0; - - /* The message UID */ - int UID = 0; - - /* The message identifier (RFC 4021) */ - const char *ID = ""; - - /* The language(s) for auto-responses (RFC 4021) */ - const char *acceptLang = ""; - - /* The language of message content (RFC 4021) */ - const char *contentLang = ""; - - /* The mailbox of message author (RFC 4021) */ - const char *from = ""; - - /* The charset of the mailbox of message author */ - // deprecated - const char *fromCharset = ""; - - /* The primary recipient mailbox (RFC 4021) */ - const char *to = ""; - - /* The charset of the primary recipient mailbox */ - // deprecated - const char *toCharset = ""; - - /* The Carbon-copy recipient mailboxes (RFC 4021) */ - const char *cc = ""; - - /* The charset of the Carbon-copy recipient mailbox header */ - // deprecated - const char *ccCharset = ""; - - /* The Blind-carbon-copy recipient mailboxes (RFC 4021) */ - const char *bcc = ""; - - /* The charset of the Blind-carbon-copy recipient mailbox header */ - // deprecated - const char *bccCharset = ""; - - /* The message date and time (RFC 4021) */ - const char *date = ""; - - /* The topic of message (RFC 4021) */ - const char *subject = ""; - - /* The topic of message charset */ - // deprecated - const char *subjectCharset = ""; - - /* The message flags */ - const char *flags = ""; - - /* The PLAIN text content of the message */ - esp_mail_imap_plain_body_t text; - - /* The HTML content of the message */ - esp_mail_imap_html_body_t html; - - /* rfc822 related */ - - /* The sender Email */ - const char *sender; - - /* The charset of the sender Email */ - // deprecated - const char *senderCharset = ""; - - /* The keywords or phrases, separated by commas */ - const char *keywords = ""; - - /* The comments about message */ - const char *comments = ""; - - /* The field that contains the parent's message ID of the message to which this one is a reply */ - const char *in_reply_to = ""; - - /* The field that contains the parent's references (if any) and followed by the parent's message ID (if any) of the message to which this one is a reply */ - const char *references = ""; - - /* The return recipient of the message */ - const char *return_path = ""; - - /* The Email address to reply */ - const char *reply_to; - - /* The error description from fetching the message */ - const char *fetchError = ""; - - /* The info about the attachments in the message */ - _vectorImpl attachments; - - /* The info about the rfc822 messages included in the message */ - _vectorImpl rfc822; - - /* The status for message that contains attachment */ - bool hasAttachment = false; - -private: - void setRFC822Headers(struct esp_mail_imap_rfc822_msg_header_item_t *rfc822_header) - { - from = rfc822_header->header_items[esp_mail_rfc822_header_field_from].c_str(); - sender = rfc822_header->header_items[esp_mail_rfc822_header_field_sender].c_str(); - to = rfc822_header->header_items[esp_mail_rfc822_header_field_to].c_str(); - cc = rfc822_header->header_items[esp_mail_rfc822_header_field_cc].c_str(); - subject = rfc822_header->header_items[esp_mail_rfc822_header_field_subject].c_str(); - date = rfc822_header->header_items[esp_mail_rfc822_header_field_date].c_str(); - ID = rfc822_header->header_items[esp_mail_rfc822_header_field_msg_id].c_str(); - return_path = rfc822_header->header_items[esp_mail_rfc822_header_field_return_path].c_str(); - reply_to = rfc822_header->header_items[esp_mail_rfc822_header_field_reply_to].c_str(); - in_reply_to = rfc822_header->header_items[esp_mail_rfc822_header_field_in_reply_to].c_str(); - references = rfc822_header->header_items[esp_mail_rfc822_header_field_references].c_str(); - comments = rfc822_header->header_items[esp_mail_rfc822_header_field_comments].c_str(); - keywords = rfc822_header->header_items[esp_mail_rfc822_header_field_keywords].c_str(); - bcc = rfc822_header->header_items[esp_mail_rfc822_header_field_bcc].c_str(); - flags = rfc822_header->header_items[esp_mail_rfc822_header_field_flags].c_str(); - text.charSet = ""; - text.content_type = ""; - text.transfer_encoding = ""; - html.charSet = ""; - html.content_type = ""; - html.transfer_encoding = ""; - } -}; - -struct esp_mail_imap_msg_list_t -{ - /* The info of a message */ - _vectorImpl msgItems; -}; - -struct esp_mail_imap_multipart_level_t -{ - uint8_t level = 0; - bool fetch_rfc822_header = false; - bool append_body_text = false; -}; - -struct esp_mail_imap_response_data -{ -public: - esp_mail_imap_response_status imapResp = esp_mail_imap_resp_unknown; - char *response = nullptr; - int readLen = 0; - long dataTime = millis(); - int chunkBufSize = 512; - int chunkIdx = 0; - bool isUntaggedResponse = false; - bool untaggedRespCompleted = false; - bool completedResponse = false; - bool endSearch = false; - struct esp_mail_message_header_t header; - struct esp_mail_message_part_info_t part; - MB_String filePath; - bool downloadRequest = false; - int octetCount = 0; - int octetLength = 0; - bool tmo = false; - int headerState = 0; - int searchCount = 0; - char *lastBuf = nullptr; - char *buf = nullptr; - - esp_mail_imap_response_data(int bufLen) { chunkBufSize = bufLen; }; - ~esp_mail_imap_response_data() { clear(); } - void clear() - { - if (response) - free(response); - if (lastBuf) - free(lastBuf); - if (buf) - free(buf); - - response = nullptr; - lastBuf = nullptr; - buf = nullptr; - } -}; - -#endif - -#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) - -struct esp_mail_link_internal_t -{ - MB_String cid; -}; - -struct esp_mail_sesson_cert_config_t -{ - /* The certificate data (base64 data) */ - const char *cert_data = NULL; - - /* The certificate file (DER format) */ - MB_String cert_file; - - /* The storage type */ - esp_mail_file_storage_type cert_file_storage_type; - - /* The cerificate verification option */ - bool verify = false; -}; - -struct esp_mail_smtp_logs_config_t -{ - - /* The log file path */ - MB_String filename; - - /* The storage type */ - esp_mail_file_storage_type storage_type; -}; - -struct esp_mail_sesson_sever_config_t -{ - /* The hostName of the server */ - MB_String host_name; - /* The port on the server to connect to */ - uint16_t port = 0; -}; - -/* The log in credentials */ -struct esp_mail_sesson_login_config_t -{ - /* The user Email address to log in */ - MB_String email; - - /* The user password to log in */ - MB_String password; - - /* The OAuth2.0 access token to log in */ - MB_String accessToken; - - /* The host name or public IP of client system */ - MB_String user_domain; -}; - -/* The device time config */ -struct esp_mail_sesson_time_config_t -{ - /* set the NTP servers (use comma to separate the servers) to let the library to set the time from NTP server */ - MB_String ntp_server; - - /* the GMT offset or time zone */ - float gmt_offset = 0; - - /* the day light saving offset */ - float day_light_offset = 0; - - /** TZ environment variable for local time setting - * See https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv - */ - MB_String timezone_env_string; - - /* the file path to store TZ environment variable */ - MB_String timezone_file = "/tze.txt"; -}; - -struct esp_mail_sesson_secure_config_t -{ - /** The option (obsoleted) to send the SMTP and IMAP commands to start the TLS connection rfc2595 section 3 and rfc3207 */ - bool startTLS = false; - - /* The secure connection mode preference */ - esp_mail_secure_mode mode = esp_mail_secure_mode_undefined; -}; - -struct esp_mail_spi_ethernet_module_t -{ -#if defined(ESP8266) && defined(ESP8266_CORE_SDK_V3_X_X) -#ifdef INC_ENC28J60_LWIP - ENC28J60lwIP *enc28j60 = nullptr; -#endif -#ifdef INC_W5100_LWIP - Wiznet5100lwIP *w5100 = nullptr; -#endif -#ifdef INC_W5500_LWIP - Wiznet5500lwIP *w5500 = nullptr; -#endif -#elif defined(MB_ARDUINO_PICO) - -#endif -}; - -struct esp_mail_session_config_t -{ - friend class IMAPSession; - friend class SMTPSession; - friend class ESP_Mail_Client; - - /* The server config */ - struct esp_mail_sesson_sever_config_t server; - - /* The log in config */ - struct esp_mail_sesson_login_config_t login; - - /* The device time config */ - struct esp_mail_sesson_time_config_t time; - - /* The secure config */ - struct esp_mail_sesson_secure_config_t secure; - - /* The certificate config */ - struct esp_mail_sesson_cert_config_t certificate; - - /* SPI Ethernet Module config for ESP8266 */ - struct esp_mail_spi_ethernet_module_t spi_ethernet_module; - - /* The callback function for WiFi connection */ - NetworkConnectionHandler network_connection_handler = NULL; - - /* specific ports and its protocols */ - struct esp_mail_ports_functions ports_functions; - - /* The mail sending logs config */ - struct esp_mail_smtp_logs_config_t sentLogs; - -public: - esp_mail_session_config_t(){}; - - ~esp_mail_session_config_t() - { - clear(); - aremovePtr(); - } - - void addPtr(_vectorImpl *listPtr, int ptr) - { - if (listPtr) - { - this->listPtr = listPtr; - bool existed = false; - - for (size_t i = 0; i < this->listPtr->size(); i++) - { - if ((*this->listPtr)[i] == ptr) - existed = true; - } - - if (!existed) - this->listPtr->push_back(ptr); - } - } - - void aremovePtr() - { - if (listPtr) - { - int ptr = toAddr(*this); - for (size_t i = 0; i < listPtr->size(); i++) - { - if ((*listPtr)[i] == ptr) - { - listPtr->erase(listPtr->begin() + i, listPtr->begin() + i + 1); - break; - } - } - } - } - - void clear() - { - server.host_name.clear(); - server.port = 0; - - secure.startTLS = false; - secure.mode = esp_mail_secure_mode_undefined; - - login.email.clear(); - login.password.clear(); - login.user_domain.clear(); - login.accessToken.clear(); - - time.day_light_offset = 0; - time.gmt_offset = 0; - time.ntp_server.clear(); - time.timezone_env_string.clear(); - - certificate.cert_data = ""; - certificate.cert_file = ""; - certificate.cert_file_storage_type = esp_mail_file_storage_type_none; - certificate.verify = false; - - clearPorts(); - } - -private: - int cert_ptr = 0; - bool cert_updated = false; - _vectorImpl *listPtr = nullptr; - - // Internal flags use to keep user sercure.startTLS and secure.mode. - bool int_start_tls = false; - esp_mail_secure_mode int_mode = esp_mail_secure_mode_undefined; - - void clearPorts() - { - if (ports_functions.list) - { - if (ports_functions.use_internal_list) - { - ports_functions.size = 0; - ports_functions.use_internal_list = false; - delete[] ports_functions.list; - ports_functions.list = nullptr; - } - } - } -}; - -/** The content transfer encoding - * enc_7bit or "7bit" - * enc_qp or "quoted-printable" - * enc_base64 or "base64" - * enc_binary or "binary" - * enc_8bit or "8bit" - */ -typedef struct esp_mail_transfer_encoding_t Content_Transfer_Encoding; - -/* The session configuations */ -typedef struct esp_mail_session_config_t ESP_Mail_Session; // obsoleted -typedef struct esp_mail_session_config_t Session_Config; - -#endif - -#if defined(ENABLE_SMTP) -/* The result from sending the Email */ -typedef struct esp_mail_smtp_send_status_t SMTP_Result; - -/* The attachment details for sending the Email */ -typedef struct esp_mail_attachment_t SMTP_Attachment; -#endif - -#if defined(ENABLE_SMTP) && defined(ENABLE_IMAP) - -typedef struct esp_mail_attachment_t ESP_Mail_Attachment; - -#endif - -#if defined(ENABLE_IMAP) -/* The info of the selected or open mailbox folder e.g. name, attributes and - * delimiter */ -typedef struct esp_mail_folder_info_item_t FolderInfo; -/* The attachment item details for a message which returned from fetching the - * Email */ -typedef struct esp_mail_attachment_info_t IMAP_Attach_Item; - -/** The IMAP operation configuations */ -typedef struct esp_mail_imap_data_config_t IMAP_Config; // obsoleted - -typedef struct esp_mail_imap_data_config_t IMAP_Data; - -/* The message item data of the IMAP_MSG_List which contains header, body and - * attachments info for eacch message*/ -typedef struct esp_mail_imap_msg_item_t IMAP_MSG_Item; - -/* The list that contains the message items from searching or fetching the Email - */ -typedef struct esp_mail_imap_msg_list_t IMAP_MSG_List; - -#endif - -struct esp_mail_wifi_credential_t -{ - MB_String ssid; - MB_String password; -}; - -struct esp_mail_wifi_credentials_t -{ - friend class ESP_Mail_Client; - friend class ESP_Mail_TCPClient; - -public: - esp_mail_wifi_credentials_t(){}; - ~esp_mail_wifi_credentials_t() - { - clearAP(); - clearMulti(); - }; - void addAP(const String &ssid, const String &password) - { - esp_mail_wifi_credential_t cred; - cred.ssid = ssid; - cred.password = password; - credentials.push_back(cred); - } - void clearAP() - { - credentials.clear(); - } - -private: - _vectorImpl credentials; -#if defined(ESP_MAIL_HAS_WIFIMULTI) - WiFiMulti *multi = nullptr; -#endif - - void reconnect() - { - if (credentials.size()) - { - disconnect(); - connect(); - } - } - - void connect() - { -#if defined(ESP_MAIL_HAS_WIFIMULTI) - - clearMulti(); - multi = new WiFiMulti(); - for (size_t i = 0; i < credentials.size(); i++) - multi->addAP(credentials[i].ssid.c_str(), credentials[i].password.c_str()); - - if (credentials.size() > 0) - multi->run(); - -#elif defined(ESP_MAIL_WIFI_IS_AVAILABLE) - WiFi.begin((CONST_STRING_CAST)credentials[0].ssid.c_str(), credentials[0].password.c_str()); -#endif - } - - void disconnect() - { -#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) - WiFi.disconnect(); -#endif - } - - void clearMulti() - { -#if defined(ESP_MAIL_HAS_WIFIMULTI) - if (multi) - delete multi; - multi = nullptr; -#endif - } -}; - -static const char esp_mail_imap_tag_str[] PROGMEM = "xmail"; - -#if !defined(SILENT_MODE) -static const char esp_mail_version_str[] PROGMEM = "ESP Mail Client v"; - -///////////////////////// -// SMTP debug string - -static const char esp_mail_dbg_str_1[] PROGMEM = "send command, STARTTLS"; -static const char esp_mail_dbg_str_2[] PROGMEM = "connecting to SMTP server"; - -#if defined(ENABLE_SMTP) -static const char esp_mail_dbg_str_3[] PROGMEM = "send Email"; -static const char esp_mail_dbg_str_4[] PROGMEM = "SMTP server connected"; -static const char esp_mail_dbg_str_5[] PROGMEM = "send SMTP command, EHLO"; -static const char esp_mail_dbg_str_6[] PROGMEM = "send SMTP command, AUTH LOGIN"; -static const char esp_mail_dbg_str_7[] PROGMEM = "send SMTP command, AUTH PLAIN"; -static const char esp_mail_dbg_str_8[] PROGMEM = "send message header"; -static const char esp_mail_dbg_str_9[] PROGMEM = "send message body"; -static const char esp_mail_dbg_str_10[] PROGMEM = "send attachments"; -static const char esp_mail_dbg_str_11[] PROGMEM = "terminate the SMTP session"; -static const char esp_mail_dbg_str_12[] PROGMEM = "message sent successfully"; -static const char esp_mail_dbg_str_13[] PROGMEM = "send next Email"; -static const char esp_mail_dbg_str_14[] PROGMEM = "send inline data"; -static const char esp_mail_dbg_str_15[] PROGMEM = "send smtp command, AUTH XOAUTH2"; -static const char esp_mail_dbg_str_16[] PROGMEM = "finishing the message sending"; -static const char esp_mail_dbg_str_17[] PROGMEM = "No ESMTP supported, send SMTP command, HELO"; -#endif - -///////////////////////// -// IMAP debug string -static const char esp_mail_dbg_str_18[] PROGMEM = "connecting to IMAP server"; -static const char esp_mail_dbg_str_19[] PROGMEM = "Host > "; -static const char esp_mail_dbg_str_20[] PROGMEM = "Port > "; -static const char esp_mail_dbg_str_21[] PROGMEM = "Reading time from NTP server"; -static const char esp_mail_dbg_str_22[] PROGMEM = "perform SSL/TLS handshake"; - -#if defined(ENABLE_IMAP) -static const char esp_mail_dbg_str_23[] PROGMEM = "get my ACL"; -static const char esp_mail_dbg_str_24[] PROGMEM = "checking the capability"; -static const char esp_mail_dbg_str_25[] PROGMEM = "fetching message "; -static const char esp_mail_dbg_str_26[] PROGMEM = "fetch message header"; -static const char esp_mail_dbg_str_27[] PROGMEM = "fetch body part header, "; -static const char esp_mail_dbg_str_28[] PROGMEM = "fetch body sub part header, "; -static const char esp_mail_dbg_str_29[] PROGMEM = "finished reading Email"; -static const char esp_mail_dbg_str_30[] PROGMEM = "UID is "; -static const char esp_mail_dbg_str_31[] PROGMEM = "log out completed"; -static const char esp_mail_dbg_str_32[] PROGMEM = "closing the "; -static const char esp_mail_dbg_str_33[] PROGMEM = "IMAP server connected"; -static const char esp_mail_dbg_str_34[] PROGMEM = "send IMAP command, LOGIN"; -static const char esp_mail_dbg_str_35[] PROGMEM = "send IMAP command, LIST"; -static const char esp_mail_dbg_str_36[] PROGMEM = "searching messages"; -static const char esp_mail_dbg_str_37[] PROGMEM = "send IMAP command, FETCH"; -static const char esp_mail_dbg_str_38[] PROGMEM = "send IMAP command, LOGOUT"; -static const char esp_mail_dbg_str_39[] PROGMEM = "message fetching completed"; -static const char esp_mail_dbg_str_40[] PROGMEM = "opening the mailbox folder"; -static const char esp_mail_dbg_str_41[] PROGMEM = "setting FLAG"; -static const char esp_mail_dbg_str_42[] PROGMEM = "adding FLAG"; -static const char esp_mail_dbg_str_43[] PROGMEM = "removing FLAG"; -static const char esp_mail_dbg_str_44[] PROGMEM = "send IMAP command, AUTHENTICATE PLAIN"; -static const char esp_mail_dbg_str_45[] PROGMEM = "send IMAP command, AUTH XOAUTH2"; -static const char esp_mail_dbg_str_46[] PROGMEM = "reading plain TEXT message"; -static const char esp_mail_dbg_str_47[] PROGMEM = "reading HTML message"; -static const char esp_mail_dbg_str_48[] PROGMEM = "copying message(s) to "; -static const char esp_mail_dbg_str_49[] PROGMEM = "creating folder"; -static const char esp_mail_dbg_str_50[] PROGMEM = "deleting folder"; -static const char esp_mail_dbg_str_51[] PROGMEM = "listening to "; -static const char esp_mail_dbg_str_52[] PROGMEM = " folder changes"; -static const char esp_mail_dbg_str_53[] PROGMEM = "polling established"; -static const char esp_mail_dbg_str_54[] PROGMEM = "Mailbox listening stopped"; -static const char esp_mail_dbg_str_55[] PROGMEM = "renaming folder"; -static const char esp_mail_dbg_str_56[] PROGMEM = "send IMAP command, LSUB"; -static const char esp_mail_dbg_str_57[] PROGMEM = "send IMAP command, SUBSCRIBE"; -static const char esp_mail_dbg_str_58[] PROGMEM = "send IMAP command, UNSUBSCRIBE"; -static const char esp_mail_dbg_str_59[] PROGMEM = "moving message(s) to "; -static const char esp_mail_dbg_str_60[] PROGMEM = "send IMAP command, GETQUOTA"; -static const char esp_mail_dbg_str_61[] PROGMEM = "send IMAP command, SETQUOTA"; -static const char esp_mail_dbg_str_62[] PROGMEM = "send IMAP command, GETQUOTAROOT"; -static const char esp_mail_dbg_str_63[] PROGMEM = "send IMAP command, GETACL"; -static const char esp_mail_dbg_str_64[] PROGMEM = "send IMAP command, SETACL"; -static const char esp_mail_dbg_str_65[] PROGMEM = "send IMAP command, DELETEACL"; -static const char esp_mail_dbg_str_66[] PROGMEM = "send IMAP command, MYRIGHTS"; -static const char esp_mail_dbg_str_67[] PROGMEM = "send IMAP command, NAMESPACE"; -static const char esp_mail_dbg_str_68[] PROGMEM = "selecting the "; -static const char esp_mail_dbg_str_69[] PROGMEM = "appending message"; -static const char esp_mail_dbg_str_70[] PROGMEM = "download attachment %d of %d"; -static const char esp_mail_dbg_str_71[] PROGMEM = "download HTML message"; -static const char esp_mail_dbg_str_72[] PROGMEM = "deleting the ACL"; -static const char esp_mail_dbg_str_73[] PROGMEM = "message append successfully"; -static const char esp_mail_dbg_str_74[] PROGMEM = "download plain TEXT message"; -static const char esp_mail_dbg_str_75[] PROGMEM = "deleting message(s)"; -static const char esp_mail_dbg_str_76[] PROGMEM = "check the capability"; -static const char esp_mail_dbg_str_77[] PROGMEM = "get the ACL"; -static const char esp_mail_dbg_str_78[] PROGMEM = "set the ACL"; -static const char esp_mail_dbg_str_79[] PROGMEM = "get UID"; -static const char esp_mail_dbg_str_80[] PROGMEM = "get Flags"; -static const char esp_mail_dbg_str_81[] PROGMEM = "delete folder"; -static const char esp_mail_dbg_str_82[] PROGMEM = "send IMAP command, ID"; -static const char esp_mail_dbg_str_83[] PROGMEM = "send IMAP command, NOOP"; -#endif - -///////////////////////// -// SMTP callback string - -static const char esp_mail_cb_str_1[] PROGMEM = "Connecting to SMTP server..."; -static const char esp_mail_cb_str_2[] PROGMEM = "Sending STARTTLS command..."; - -#if defined(ENABLE_SMTP) -static const char esp_mail_cb_str_3[] PROGMEM = "Sending greeting response..."; -static const char esp_mail_cb_str_4[] PROGMEM = "Sending message header..."; -static const char esp_mail_cb_str_5[] PROGMEM = "Sending message body..."; -static const char esp_mail_cb_str_6[] PROGMEM = "Sending attachments..."; -static const char esp_mail_cb_str_7[] PROGMEM = "Closing the session..."; -static const char esp_mail_cb_str_8[] PROGMEM = "Sending inline data..."; -static const char esp_mail_cb_str_9[] PROGMEM = "Sending Email..."; -static const char esp_mail_cb_str_10[] PROGMEM = "Sending next Email..."; -static const char esp_mail_cb_str_11[] PROGMEM = "Finishing the message sending..."; -static const char esp_mail_cb_str_12[] PROGMEM = "SMTP server connected, wait for greeting..."; -static const char esp_mail_cb_str_13[] PROGMEM = "Message sent successfully"; -#endif - -///////////////////////// -// IMAP callback string - -static const char esp_mail_cb_str_14[] PROGMEM = "Logging in..."; // shared with SMTP -static const char esp_mail_cb_str_15[] PROGMEM = "Connecting to IMAP server..."; - -#if defined(ENABLE_IMAP) - -static const char esp_mail_cb_str_16[] PROGMEM = "Reading the list of mailboxes..."; -static const char esp_mail_cb_str_17[] PROGMEM = "Checking the capability..."; -static const char esp_mail_cb_str_18[] PROGMEM = "Searching messages..."; -static const char esp_mail_cb_str_19[] PROGMEM = "Downloading attachments..."; -static const char esp_mail_cb_str_20[] PROGMEM = "Logging out..."; -static const char esp_mail_cb_str_21[] PROGMEM = "Saving message header to file..."; -static const char esp_mail_cb_str_22[] PROGMEM = "Get FLAG..."; -static const char esp_mail_cb_str_23[] PROGMEM = "Removing FLAG..."; -static const char esp_mail_cb_str_24[] PROGMEM = "Adding FLAG..."; -static const char esp_mail_cb_str_25[] PROGMEM = "Get UID..."; -static const char esp_mail_cb_str_26[] PROGMEM = "Setting FLAG..."; -static const char esp_mail_cb_str_27[] PROGMEM = "Closing the mailbox folder..."; -static const char esp_mail_cb_str_28[] PROGMEM = "Reading messages..."; -static const char esp_mail_cb_str_29[] PROGMEM = "Listening to mailbox changes..."; -static const char esp_mail_cb_str_30[] PROGMEM = "Listing the subscribed mailboxes..."; -static const char esp_mail_cb_str_31[] PROGMEM = "Subscribe mailbox..."; -static const char esp_mail_cb_str_32[] PROGMEM = "Unsubscribe mailbox..."; -static const char esp_mail_cb_str_33[] PROGMEM = "Get quota root resource usage and limit..."; -static const char esp_mail_cb_str_34[] PROGMEM = "Set quota root resource usage and limit..."; -static const char esp_mail_cb_str_35[] PROGMEM = "Get the list of quota roots..."; -static const char esp_mail_cb_str_36[] PROGMEM = "Get the ACL..."; -static const char esp_mail_cb_str_37[] PROGMEM = "Setting the ACL..."; -static const char esp_mail_cb_str_38[] PROGMEM = "Deleting the ACL..."; -static const char esp_mail_cb_str_39[] PROGMEM = "Get my ACL..."; -static const char esp_mail_cb_str_40[] PROGMEM = "Get namespace..."; -static const char esp_mail_cb_str_41[] PROGMEM = "Enable capability..."; -static const char esp_mail_cb_str_42[] PROGMEM = "Updating firmware..."; -static const char esp_mail_cb_str_43[] PROGMEM = "Downloading messages..."; -static const char esp_mail_cb_str_44[] PROGMEM = "Appending message..."; -static const char esp_mail_cb_str_45[] PROGMEM = "Message append successfully"; -static const char esp_mail_cb_str_46[] PROGMEM = "Finished reading Email"; -static const char esp_mail_cb_str_47[] PROGMEM = "Log out completed"; -static const char esp_mail_cb_str_48[] PROGMEM = "IMAP server connected"; -static const char esp_mail_cb_str_49[] PROGMEM = "Polling established"; -static const char esp_mail_cb_str_50[] PROGMEM = "Mailbox listening stopped"; -static const char esp_mail_cb_str_51[] PROGMEM = "Open the mailbox folder..."; -static const char esp_mail_cb_str_52[] PROGMEM = "Checking the capability..."; -static const char esp_mail_cb_str_53[] PROGMEM = "Renaming folder..."; -static const char esp_mail_cb_str_54[] PROGMEM = "UID is "; -static const char esp_mail_cb_str_55[] PROGMEM = "Get Flags..."; -static const char esp_mail_cb_str_56[] PROGMEM = "Deleting folder..."; -static const char esp_mail_cb_str_57[] PROGMEM = "Deleting message(s)..."; -static const char esp_mail_cb_str_58[] PROGMEM = "Copying message(s)..."; -static const char esp_mail_cb_str_59[] PROGMEM = "Creating folder..."; -static const char esp_mail_cb_str_60[] PROGMEM = "Moving message(s)..."; -static const char esp_mail_cb_str_61[] PROGMEM = "Send client identification..."; -static const char esp_mail_cb_str_62[] PROGMEM = "Send noop..."; -#endif - -#endif - -///////////////////////// -// Mem error string - -#if defined(ENABLE_ERROR_STRING) || !defined(SILENT_MODE) -#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) -static const char esp_mail_error_mem_str_1[] PROGMEM = "flash Storage is not ready."; -static const char esp_mail_error_mem_str_2[] PROGMEM = "SD Storage is not ready."; -static const char esp_mail_error_mem_str_3[] PROGMEM = "file does not exist or can't access"; -#endif -static const char esp_mail_error_mem_str_4[] PROGMEM = "PSRAM was enabled but not detected."; -#endif - -#if defined(ENABLE_ERROR_STRING) - -#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) -static const char esp_mail_error_mem_str_5[] PROGMEM = "file is still opened."; -static const char esp_mail_error_mem_str_6[] PROGMEM = "file not found."; -static const char esp_mail_error_mem_str_7[] PROGMEM = "file I/O error"; -#endif - -static const char esp_mail_error_mem_str_8[] PROGMEM = "out of memory"; -static const char esp_mail_error_mem_str_9[] PROGMEM = "buffer overflow"; - -#endif - -#if defined(MB_ARDUINO_PICO) -#if defined(ENABLE_ERROR_STRING) || !defined(SILENT_MODE) -static const char esp_mail_error_mem_str_10[] PROGMEM = "please make sure that the size of flash filesystem is not 0 in Pico."; -#endif -#endif - -///////////////////////// -// Client error string - -#if !defined(SILENT_MODE) -static const char esp_mail_error_client_str_1[] PROGMEM = "client and/or necessary callback functions are not yet assigned"; -static const char esp_mail_error_client_str_2[] PROGMEM = "network connection callback is required"; -static const char esp_mail_error_client_str_3[] PROGMEM = "network connection status callback is required"; -static const char esp_mail_error_client_str_4[] PROGMEM = "NTP server time reading cannot begin when valid time is required because of no WiFi capability/activity detected."; -static const char esp_mail_error_client_str_5[] PROGMEM = "Please set the library reference time manually using smtp.setSystemTime or imap.setSystemTime."; -#endif - -///////////////////////// -// Network error string - -#if !defined(SILENT_MODE) -static const char esp_mail_error_network_str_1[] PROGMEM = "unable to connect to server"; -#if defined(ENABLE_ERROR_STRING) -static const char esp_mail_error_network_str_2[] PROGMEM = "NTP server time reading timed out"; -static const char esp_mail_error_network_str_3[] PROGMEM = "response read timed out"; -static const char esp_mail_error_network_str_4[] PROGMEM = "not connected"; -static const char esp_mail_error_network_str_5[] PROGMEM = "connection timeout"; -static const char esp_mail_error_network_str_6[] PROGMEM = "connection closed"; -static const char esp_mail_error_network_str_7[] PROGMEM = "connection refused"; -static const char esp_mail_error_network_str_8[] PROGMEM = "data sending failed"; -#endif -#endif - -#if defined(ENABLE_ERROR_STRING) || !defined(SILENT_MODE) -static const char esp_mail_error_network_str_9[] PROGMEM = "response read timed out"; -#endif - -///////////////////////// -// SSL error string - -#if defined(ENABLE_ERROR_STRING) -static const char esp_mail_error_ssl_str_1[] PROGMEM = "fail to set up the SSL/TLS structure"; -#endif -#if defined(ENABLE_ERROR_STRING) || !defined(SILENT_MODE) -static const char esp_mail_error_ssl_str_2[] PROGMEM = "the alert SSL record received"; -static const char esp_mail_error_ssl_str_3[] PROGMEM = "make sure the SSL/TLS handshake was done before sending the data"; -#endif - -///////////////////////// -// Auth error string - -#if defined(ENABLE_ERROR_STRING) -static const char esp_mail_error_auth_str_1[] PROGMEM = "the provided SASL authentication mechanism is not support"; -static const char esp_mail_error_auth_str_2[] PROGMEM = "OAuth2.0 log in was disabled for this server"; -static const char esp_mail_error_auth_str_3[] PROGMEM = "not yet log in"; -#endif - -///////////////////////// -// Session error string - -#if defined(ENABLE_ERROR_STRING) -static const char esp_mail_error_session_str_1[] PROGMEM = "the Session_Config object was not assigned"; -#endif - -///////////////////////// -// Time error string -#if defined(ENABLE_ERROR_STRING) -static const char esp_mail_error_time_str_1[] PROGMEM = "library or device time was not set, see examples/SMTP/Set_Time.ino for manually time setting"; -#endif - -///////////////////////// -// SMTP error string -#if defined(ENABLE_SMTP) -#if defined(ENABLE_ERROR_STRING) -static const char esp_mail_error_smtp_str_1[] PROGMEM = "SMTP server greeting failed"; -static const char esp_mail_error_smtp_str_2[] PROGMEM = "authentication failed"; -static const char esp_mail_error_smtp_str_3[] PROGMEM = "login password is not valid"; -static const char esp_mail_error_smtp_str_4[] PROGMEM = "send header failed"; -static const char esp_mail_error_smtp_str_5[] PROGMEM = "send body failed"; -static const char esp_mail_error_smtp_str_7[] PROGMEM = "sender Email address is not valid"; -static const char esp_mail_error_smtp_str_8[] PROGMEM = "some of the recipient Email address is not valid"; -static const char esp_mail_error_smtp_str_9[] PROGMEM = "set recipient failed"; -static const char esp_mail_error_smtp_str_10[] PROGMEM = "send custom command failed"; -static const char esp_mail_error_smtp_str_11[] PROGMEM = "XOAuth2 authenticate failed"; -static const char esp_mail_error_smtp_str_12[] PROGMEM = "undefined error"; -#endif -#endif - -///////////////////////// -// IMAP error string -#if defined(ENABLE_IMAP) -#if defined(ENABLE_ERROR_STRING) -static const char esp_mail_error_imap_str_1[] PROGMEM = "fail to list the mailboxes"; -static const char esp_mail_error_imap_str_2[] PROGMEM = "fail to check the capabilities"; - -static const char esp_mail_error_imap_str_3[] PROGMEM = "fail to close the mailbox"; - -static const char esp_mail_error_imap_str_4[] PROGMEM = "fail to open the mailbox"; -static const char esp_mail_error_imap_str_5[] PROGMEM = "some of the requested messages no longer exist"; -static const char esp_mail_error_imap_str_6[] PROGMEM = "firmware update initialization failed"; -static const char esp_mail_error_imap_str_7[] PROGMEM = "firmware update write failed"; -static const char esp_mail_error_imap_str_8[] PROGMEM = "firmware update finalize failed"; - -#endif -#if defined(ENABLE_ERROR_STRING) || !defined(SILENT_MODE) -static const char esp_mail_error_imap_str_9[] PROGMEM = "no messages found for the specified search criteria"; -static const char esp_mail_error_imap_str_10[] PROGMEM = "no search criteria provided, then fetching the latest message"; -static const char esp_mail_error_imap_str_11[] PROGMEM = "no mailbox opened"; -static const char esp_mail_error_imap_str_12[] PROGMEM = "no content"; -static const char esp_mail_error_imap_str_13[] PROGMEM = "this feature was not supported"; -static const char esp_mail_error_imap_str_14[] PROGMEM = "no message changed since (assigned) modsec"; -static const char esp_mail_error_imap_str_15[] PROGMEM = "CONDSTORE was not supported or modsec was not supported for selected mailbox"; -static const char esp_mail_error_imap_str_17[] PROGMEM = "could not parse command"; -static const char esp_mail_error_imap_str_18[] PROGMEM = "server disconnected or returned error"; -static const char esp_mail_error_imap_str_19[] PROGMEM = "authenticate failed"; -static const char esp_mail_error_imap_str_20[] PROGMEM = "flags or keywords store failed"; -static const char esp_mail_error_imap_str_21[] PROGMEM = "server is not support OAuth2 login"; -#endif -#endif - -///////////////////////// -// General use string -static const char esp_mail_str_1[] PROGMEM = "127.0.0.1"; -static const char esp_mail_str_2[] PROGMEM = " "; -static const char esp_mail_str_3[] PROGMEM = "*"; -static const char esp_mail_str_4[] PROGMEM = "High"; -static const char esp_mail_str_5[] PROGMEM = "Normal"; -static const char esp_mail_str_6[] PROGMEM = "Low"; -static const char esp_mail_str_7[] PROGMEM = "="; -static const char esp_mail_str_8[] PROGMEM = ","; -static const char esp_mail_str_9[] PROGMEM = "--"; -static const char esp_mail_str_10[] PROGMEM = "/"; -static const char esp_mail_str_11[] PROGMEM = "\""; -static const char esp_mail_str_12[] PROGMEM = "Error, "; -static const char esp_mail_str_13[] PROGMEM = "msg.txt"; -static const char esp_mail_str_14[] PROGMEM = "msg.html"; -static const char esp_mail_str_15[] PROGMEM = "flash content message"; -static const char esp_mail_str_16[] PROGMEM = "file content message"; -static const char esp_mail_str_17[] PROGMEM = "cid:"; -static const char esp_mail_str_18[] PROGMEM = "\r\n"; -static const char esp_mail_str_19[] PROGMEM = "<"; -static const char esp_mail_str_20[] PROGMEM = ">"; -static const char esp_mail_str_21[] PROGMEM = "(\"name\" \"ESP Mail Client\" \"version\" \"%s\")"; -static const char esp_mail_str_22[] PROGMEM = "message/rfc822"; -static const char esp_mail_str_23[] PROGMEM = "upload"; -static const char esp_mail_str_24[] PROGMEM = "%"; -static const char esp_mail_str_25[] PROGMEM = "status code: "; -static const char esp_mail_str_26[] PROGMEM = ", text: "; -static const char esp_mail_str_27[] PROGMEM = "."; -static const char esp_mail_str_28[] PROGMEM = "> C: "; -static const char esp_mail_str_29[] PROGMEM = "< S: "; -static const char esp_mail_str_30[] PROGMEM = "! E: "; -static const char esp_mail_str_31[] PROGMEM = "! I: "; -static const char esp_mail_str_32[] PROGMEM = "! W: "; -static const char esp_mail_str_33[] PROGMEM = "#### "; -static const char esp_mail_str_34[] PROGMEM = ":"; -static const char esp_mail_str_35[] PROGMEM = ";"; -static const char esp_mail_str_36[] PROGMEM = "{"; -static const char esp_mail_str_37[] PROGMEM = "}"; -static const char esp_mail_str_38[] PROGMEM = "("; -static const char esp_mail_str_39[] PROGMEM = ")"; -static const char esp_mail_str_40[] PROGMEM = "["; -static const char esp_mail_str_41[] PROGMEM = "]"; -static const char esp_mail_str_42[] PROGMEM = "\r\n"; -static const char esp_mail_str_43[] PROGMEM = "\1\1"; -static const char esp_mail_str_44[] PROGMEM = "{\"status\":"; -static const char esp_mail_str_45[] PROGMEM = "user="; -static const char esp_mail_str_46[] PROGMEM = "\1auth=Bearer "; -static const char esp_mail_str_47[] PROGMEM = "0123456789ABCDEF"; -static const char esp_mail_str_48[] PROGMEM = "<0.0>"; -static const char esp_mail_str_49[] PROGMEM = "<0."; -static const char esp_mail_str_50[] PROGMEM = "Search limit: %d\nFound %d messages\nShow %d messages"; -static const char esp_mail_str_51[] PROGMEM = "1.0"; -static const char esp_mail_str_52[] PROGMEM = "Fetch message %d, UID: %d"; -static const char esp_mail_str_53[] PROGMEM = "Fetch message %d, Number: %d"; -static const char esp_mail_str_54[] PROGMEM = "Attachments (%d)"; -static const char esp_mail_str_55[] PROGMEM = "Free Heap: "; -static const char esp_mail_str_56[] PROGMEM = "content-"; -static const char esp_mail_str_58[] PROGMEM = "format=\"flowed\""; -static const char esp_mail_str_59[] PROGMEM = "format=flowed"; -static const char esp_mail_str_60[] PROGMEM = "delsp=\"yes\""; -static const char esp_mail_str_61[] PROGMEM = "delsp=yes"; -static const char esp_mail_str_62[] PROGMEM = "name"; -static const char esp_mail_str_63[] PROGMEM = "+ "; -static const char esp_mail_str_64[] PROGMEM = "boundary=\""; -static const char esp_mail_str_65[] PROGMEM = "/header.json"; -static const char esp_mail_str_66[] PROGMEM = "/header.txt"; -static const char esp_mail_str_67[] PROGMEM = "{\"Filename\":\""; -static const char esp_mail_str_68[] PROGMEM = "Index: "; -static const char esp_mail_str_69[] PROGMEM = ",\"RFC822\":"; -static const char esp_mail_str_70[] PROGMEM = "\r\n\r\nRFC822:\r\n"; -static const char esp_mail_str_71[] PROGMEM = ",\"Attachments\":{\"Count\":"; -static const char esp_mail_str_72[] PROGMEM = ",\"Files\":["; -static const char esp_mail_str_73[] PROGMEM = "\r\n\r\nAttachments ("; -static const char esp_mail_str_74[] PROGMEM = ")\r\n"; -static const char esp_mail_str_75[] PROGMEM = "]}"; -static const char esp_mail_str_76[] PROGMEM = "{\"Messages\":["; -static const char esp_mail_str_77[] PROGMEM = ",\""; -static const char esp_mail_str_78[] PROGMEM = "{\""; -static const char esp_mail_str_79[] PROGMEM = "\":\""; -static const char esp_mail_str_80[] PROGMEM = "{\"Renamed\":\""; -static const char esp_mail_str_81[] PROGMEM = "\",\"Original\":\""; -static const char esp_mail_str_82[] PROGMEM = "\"}]"; -static const char esp_mail_str_83[] PROGMEM = "_"; -static const char esp_mail_str_84[] PROGMEM = "message"; -static const char esp_mail_str_85[] PROGMEM = "rfc822"; -static const char esp_mail_str_86[] PROGMEM = "/msg"; -static const char esp_mail_str_87[] PROGMEM = "/rfc822_msg"; -static const char esp_mail_str_88[] PROGMEM = "polling established on "; -static const char esp_mail_str_89[] PROGMEM = " folder..."; -static const char esp_mail_str_90[] PROGMEM = "boundary"; -static const char esp_mail_str_91[] PROGMEM = "\\Deleted"; -static const char esp_mail_str_92[] PROGMEM = "Subject: %s"; -static const char esp_mail_str_93[] PROGMEM = "Message sent success: %d"; -static const char esp_mail_str_94[] PROGMEM = "Message sent failed: %d"; -static const char esp_mail_str_95[] PROGMEM = "Status: %s"; -static const char esp_mail_str_96[] PROGMEM = "Date/Time: %s"; -static const char esp_mail_str_97[] PROGMEM = "Recipient: %s"; -static const char esp_mail_str_98[] PROGMEM = "success"; -static const char esp_mail_str_99[] PROGMEM = "failed"; - -#if defined(ENABLE_SMTP) -static const char boundary_table[] PROGMEM = "=_abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; -#endif - -#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) - -static const unsigned char b64_index_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -static void __attribute__((used)) -appendDebugTag(MB_String &buf, esp_mail_debug_tag_type type, bool clear, PGM_P text = NULL) -{ - if (clear) - buf.clear(); - - switch (type) - { - case esp_mail_debug_tag_type_client: - buf += esp_mail_str_28; /* "> C: "*/ - break; - case esp_mail_debug_tag_type_server: - buf += esp_mail_str_29; /* "< S: " */ - break; - case esp_mail_debug_tag_type_error: - buf += esp_mail_str_30; /* "! E: "*/ - break; - case esp_mail_debug_tag_type_info: - buf += esp_mail_str_31; /* "! I: "*/ - break; - case esp_mail_debug_tag_type_warning: - buf += esp_mail_str_32; /* "! W: "*/ - break; - default: - break; - } - - if (text != NULL) - buf += text; -} - -static void __attribute__((used)) -yield_impl() -{ -#if defined(ARDUINO_ESP8266_MAJOR) && defined(ARDUINO_ESP8266_MINOR) && defined(ARDUINO_ESP8266_REVISION) && ((ARDUINO_ESP8266_MAJOR == 3 && ARDUINO_ESP8266_MINOR >= 1) || ARDUINO_ESP8266_MAJOR > 3) - esp_yield(); -#else - delay(0); -#endif -} - -// Print debug message w/wo new line to debug port -static void __attribute__((used)) -esp_mail_debug_print(PGM_P msg = "", bool newLine = true) -{ - yield_impl(); - if (newLine) - ESP_MAIL_DEFAULT_DEBUG_PORT.println(msg); - else - ESP_MAIL_DEFAULT_DEBUG_PORT.print(msg); -} - -static void __attribute__((used)) -esp_mail_debug_print_tag(PGM_P msg, esp_mail_debug_tag_type type, bool newLine = true, bool showTag = true) -{ - yield_impl(); - - MB_String s; - if (showTag) - appendDebugTag(s, type, false, msg); - else - s = msg; - - if (newLine) - ESP_MAIL_DEFAULT_DEBUG_PORT.println(s.c_str()); - else - ESP_MAIL_DEFAULT_DEBUG_PORT.print(s.c_str()); -} - -#endif - -typedef void (*ConnectionUpgradeRequestCallback)(void); -typedef void (*NetworkConnectionRequestCallback)(void); -typedef void (*NetworkDisconnectionRequestCallback)(void); -typedef void (*NetworkStatusRequestCallback)(void); -// Optional -typedef void (*ConnectionRequestCallback)(const char *, int); +// Created August 20, 2023 + +#pragma once + +#ifndef ESP_MAIL_CONST_H +#define ESP_MAIL_CONST_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +#include +#include "ESP_Mail_FS.h" +#include "ESP_Mail_Error.h" +#include "extras/MB_FS.h" +#include "extras/RFC2047.h" +#include +#include + +#if defined(ESP_MAIL_DEBUG_PORT) +#define ESP_MAIL_DEFAULT_DEBUG_PORT ESP_MAIL_DEBUG_PORT +#else +#define ESP_MAIL_DEFAULT_DEBUG_PORT Serial +#endif + +#include +#include + +#define _vectorImpl std::vector +#define MB_VECTOR std::vector + +#if !defined(FPSTR) +#define FPSTR +#endif + +#include "extras/Networks_Provider.h" +#include "extras/ESP8266_Supports.h" + +#if defined(ESP8266) +#if __has_include() +#include +#endif +#endif + +#if defined(ENABLE_IMAP) && (defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO)) +#if defined(ESP32) +#include +#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) +#include +#endif +#define ESP_MAIL_OTA_UPDATE_ENABLED +#endif + +#if !defined(SILENT_MODE) && (defined(ENABLE_SMTP) || defined(ENABLE_IMAP)) +#define SESSION_DEBUG_ENABLED +#endif + +#define TCP_CLIENT_DEFAULT_TCP_TIMEOUT_SEC 30 + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + +#define MAX_EMAIL_SEARCH_LIMIT 1000 +#define BASE64_CHUNKED_LEN 76 +#define FLOWED_TEXT_LEN 78 +#define QP_ENC_MSG_LEN 76 +#define ESP_MAIL_NETWORK_RECONNECT_TIMEOUT 10000 +#define ESP_MAIL_PROGRESS_REPORT_STEP 5 +#define ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED 0 +#define ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE 256 +#define ESP_MAIL_CLIENT_RESPONSE_BUFFER_SIZE 1024 // should be 1 k or more to prevent buffer overflow +#define ESP_MAIL_CLIENT_VALID_TS 1577836800 + +#endif + +typedef enum +{ + esp_mail_cert_type_undefined = -1, + esp_mail_cert_type_none = 0, + esp_mail_cert_type_data, + esp_mail_cert_type_file, + esp_mail_cert_type_bundle + +} esp_mail_cert_type; + +typedef enum +{ + esp_mail_client_type_undefined, + esp_mail_client_type_internal_basic_client, + esp_mail_client_type_external_basic_client, + esp_mail_client_type_external_gsm_client + +} esp_mail_client_type; + +/* The filesystem types enum */ +enum esp_mail_file_storage_type +{ + esp_mail_file_storage_type_none, + esp_mail_file_storage_type_flash, + esp_mail_file_storage_type_sd +}; + +/* The session types enum */ +enum esp_mail_session_type +{ + esp_mail_session_type_smtp, + esp_mail_session_type_imap +}; + +/* The secure connection mode preference */ +typedef enum +{ + // No preferences + esp_mail_secure_mode_undefined = 0, + // Always use SSL and TLS via STARTTLS rfc2595 section 3 and rfc3207 + esp_mail_secure_mode_ssl_tls, + // Plain text mode only (non SSL/TLS) + // To disable SSL/TLS permanently, define ESP_MAIL_DISABLE_SSL in ESP_Mail_FS.h + esp_mail_secure_mode_nonsecure + +} esp_mail_secure_mode; + +using namespace mb_string; + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + +typedef void (*NetworkConnectionHandler)(void); + +/* The file types enum */ +enum esp_mail_file_extension +{ + /** The arrangement is related to mimeinfo struct. + * Do not modify or remove. + */ + esp_mail_file_extension_html, + esp_mail_file_extension_htm, + esp_mail_file_extension_css, + esp_mail_file_extension_txt, + esp_mail_file_extension_js, + esp_mail_file_extension_json, + esp_mail_file_extension_png, + esp_mail_file_extension_gif, + esp_mail_file_extension_jpg, + esp_mail_file_extension_ico, + esp_mail_file_extension_svg, + esp_mail_file_extension_ttf, + esp_mail_file_extension_otf, + esp_mail_file_extension_woff, + esp_mail_file_extension_woff2, + esp_mail_file_extension_eot, + esp_mail_file_extension_sfnt, + esp_mail_file_extension_xml, + esp_mail_file_extension_pdf, + esp_mail_file_extension_zip, + esp_mail_file_extension_gz, + esp_mail_file_extension_appcache, + esp_mail_file_extension_dat, + esp_mail_file_extension_binary, + esp_mail_file_extension_maxType +}; + +struct esp_mail_mime_prop_t +{ + char endsWith[10]; + char mimeType[30]; +}; + +const struct esp_mail_mime_prop_t mimeinfo[esp_mail_file_extension_maxType] PROGMEM = { + /** The arrangement is related to esp_mail_file_extension enum. + * Do not modify or remove. + */ + {".html", "text/html"}, + {".htm", "text/html"}, + {".css", "text/css"}, + {".txt", "text/plain"}, + {".js", "application/javascript"}, + {".json", "application/json"}, + {".png", "image/png"}, + {".gif", "image/gif"}, + {".jpg", "image/jpeg"}, + {".ico", "image/x-icon"}, + {".svg", "image/svg+xml"}, + {".ttf", "application/x-font-ttf"}, + {".otf", "application/x-font-opentype"}, + {".woff", "application/font-woff"}, + {".woff2", "application/font-woff2"}, + {".eot", "application/vnd.ms-fontobject"}, + {".sfnt", "application/font-sfnt"}, + {".xml", "text/xml"}, + {".pdf", "application/pdf"}, + {".zip", "application/zip"}, + {".gz", "application/x-gzip"}, + {".appcache", "text/cache-manifest"}, + {".dat", "application/dat"}, + {"", "application/octet-stream"}}; + +#if defined(ENABLE_SMTP) + +/* The SMTP commands types enum */ +enum esp_mail_smtp_command_types +{ + /** The SMTP commands per stansards. + * The arrangement is related to smtp_commands struct. + * Do not modify or remove. + */ + esp_mail_smtp_command_auth, + esp_mail_smtp_command_login, + esp_mail_smtp_command_helo, + esp_mail_smtp_command_ehlo, + esp_mail_smtp_command_quit, + esp_mail_smtp_command_mail, + esp_mail_smtp_command_rcpt, + esp_mail_smtp_command_data, + esp_mail_smtp_command_bdat, + esp_mail_smtp_command_last, + esp_mail_smtp_command_plain, + esp_mail_smtp_command_from, + esp_mail_smtp_command_to, + esp_mail_smtp_command_notify, + esp_mail_smtp_command_success, + esp_mail_smtp_command_failure, + esp_mail_smtp_command_delay, + esp_mail_smtp_command_body, + esp_mail_smtp_command_terminate, + esp_mail_smtp_command_starttls, + esp_mail_smtp_command_maxType +}; + +/* The SMTP server capability types enum (except for SASL) */ +enum esp_mail_smtp_send_capability_types +{ + /** The server capability keywords per standard. + * The arrangement is related to smtp_send_capabilities struct. + * Do not modify or remove. + */ + esp_mail_smtp_send_capability_binary_mime, + esp_mail_smtp_send_capability_8bit_mime, + esp_mail_smtp_send_capability_chunking, + esp_mail_smtp_send_capability_utf8, + esp_mail_smtp_send_capability_pipelining, + esp_mail_smtp_send_capability_dsn, + esp_mail_smtp_send_capability_esmtp, + esp_mail_smtp_send_capability_maxType +}; + +#endif + +#if defined(ENABLE_IMAP) + +/* The IMAP server response types enum */ +enum esp_mail_imap_response_types +{ + /** The IMAP response. + * The arrangement is related to imap_responses struct. + * Do not modify or remove. + */ + esp_mail_imap_response_ok, + esp_mail_imap_response_no, + esp_mail_imap_response_bad, + esp_mail_imap_response_list, + esp_mail_imap_response_flags, + esp_mail_imap_response_search, + esp_mail_imap_response_fetch, + esp_mail_imap_response_nil, + esp_mail_imap_response_uid, + esp_mail_imap_response_capability_untagged, + esp_mail_imap_response_capability, + esp_mail_imap_response_lsub, + esp_mail_imap_response_quota, + esp_mail_imap_response_quotaroot, + esp_mail_imap_response_acl, + esp_mail_imap_response_myrights, + esp_mail_imap_response_namespace, + esp_mail_imap_response_untagged, + esp_mail_imap_response_exists, + esp_mail_imap_response_expunge, + esp_mail_imap_response_recent, + esp_mail_imap_response_uidnext, + esp_mail_imap_response_unseen, + esp_mail_imap_response_id, + esp_mail_imap_response_highest_modsec, + esp_mail_imap_response_nomodsec, + esp_mail_imap_response_permanent_flags, + esp_mail_imap_response_uidvalidity, + esp_mail_imap_response_maxType +}; + +/* The IMAP commands types enum */ +enum esp_mail_imap_command_types +{ + /** The IMAP commands per standards. + * The arrangement is related to imap_commands struct. + * Do not modify or remove. + */ + esp_mail_imap_command_starttls, + esp_mail_imap_command_append, + esp_mail_imap_command_capability, + esp_mail_imap_command_authenticate, + esp_mail_imap_command_plain, + esp_mail_imap_command_uid, + esp_mail_imap_command_fetch, + esp_mail_imap_command_flags, + esp_mail_imap_command_login, + esp_mail_imap_command_list, + esp_mail_imap_command_examine, + esp_mail_imap_command_search, + esp_mail_imap_command_logout, + esp_mail_imap_command_body, + esp_mail_imap_command_mime, + esp_mail_imap_command_close, + esp_mail_imap_command_exists, + esp_mail_imap_command_peek, + esp_mail_imap_command_text, + esp_mail_imap_command_fields, + esp_mail_imap_command_header, + esp_mail_imap_command_new, + esp_mail_imap_command_all, + esp_mail_imap_command_select, + esp_mail_imap_command_expunge, + esp_mail_imap_command_create, + esp_mail_imap_command_delete, + esp_mail_imap_command_idle, + esp_mail_imap_command_done, + esp_mail_imap_command_recent, + esp_mail_imap_command_unseen, + esp_mail_imap_command_rename, + esp_mail_imap_command_lsub, + esp_mail_imap_command_subscribe, + esp_mail_imap_command_unsubscribe, + esp_mail_imap_command_silent, + esp_mail_imap_command_move, + esp_mail_imap_command_getquota, + esp_mail_imap_command_setquota, + esp_mail_imap_command_root, + esp_mail_imap_command_get_acl, + esp_mail_imap_command_set_acl, + esp_mail_imap_command_delete_acl, + esp_mail_imap_command_myrights, + esp_mail_imap_command_namespace, + esp_mail_imap_command_enable, + esp_mail_imap_command_xoauth2, + esp_mail_imap_command_store, + esp_mail_imap_command_plus_flags, + esp_mail_imap_command_minus_flags, + esp_mail_imap_command_copy, + esp_mail_imap_command_id, + esp_mail_imap_command_unselect, + esp_mail_imap_command_condstore, + esp_mail_imap_command_noop, + esp_mail_imap_command_unchangedsince, + esp_mail_imap_command_changedsince, + esp_mail_imap_command_modsec, + esp_mail_imap_command_maxType +}; + +/* The IMAP server capability types enum (except for SASL) */ +enum esp_mail_imap_read_capability_types +{ + /** The server capability keywords per standard. + * The arrangement is related imap_read_capabilities struct. + * Do not modify or remove. + */ + + esp_mail_imap_read_capability_imap4, + esp_mail_imap_read_capability_imap4rev1, + // rfc2177 + esp_mail_imap_read_capability_idle, + esp_mail_imap_read_capability_literal_plus, + esp_mail_imap_read_capability_literal_minus, + esp_mail_imap_read_capability_multiappend, + esp_mail_imap_read_capability_uidplus, + // rfc4314 + esp_mail_imap_read_capability_acl, + esp_mail_imap_read_capability_binary, + esp_mail_imap_read_capability_logindisable, + // rfc6851 + esp_mail_imap_read_capability_move, + // rfc2087 + esp_mail_imap_read_capability_quota, + // rfc2342 + esp_mail_imap_read_capability_namespace, + // rfc5161 + esp_mail_imap_read_capability_enable, + // rfc2971 + esp_mail_imap_read_capability_id, + esp_mail_imap_read_capability_unselect, + esp_mail_imap_read_capability_children, + // rfc7162 (rfc4551 obsoleted) + esp_mail_imap_read_capability_condstore, + esp_mail_imap_read_capability_auto_caps, + esp_mail_imap_read_capability_maxType +}; + +/* The Identification keys enum used for IMAP ID command */ +enum esp_mail_imap_identification_keys +{ + /** The identification keys per standard. + * The arrangement is related imap_identification_keys struct. + * Do not modify or remove. + */ + + esp_mail_imap_identification_key_name, + esp_mail_imap_identification_key_version, + esp_mail_imap_identification_key_os, + esp_mail_imap_identification_key_os_version, + esp_mail_imap_identification_key_vendor, + esp_mail_imap_identification_key_support_url, + esp_mail_imap_identification_key_address, + esp_mail_imap_identification_key_date, + esp_mail_imap_identification_key_command, + esp_mail_imap_identification_key_arguments, + esp_mail_imap_identification_key_environment, + esp_mail_imap_identification_key_maxType +}; + +#endif + +/* The character encoding types enum used for decoding */ +enum esp_mail_char_decoding_types +{ + /** Supported charactor encodings. + * The arrangement is related to char_decodings struct. + * Do not modify or remove. + */ + esp_mail_char_decoding_utf8, + esp_mail_char_decoding_iso_8859_1, + esp_mail_char_decoding_iso_8859_11, + esp_mail_char_decoding_tis_620, + esp_mail_char_decoding_windows_874, + esp_mail_char_decoding_maxType +}; + +/* The MIME multipart message types */ +enum esp_mail_multipart_types +{ + /** MultiPart MIME. + * The arrangement is related to multipart_types struct. + * Do not modify or remove. + */ + esp_mail_multipart_type_mixed, + esp_mail_multipart_type_related, + esp_mail_multipart_type_parallel, + esp_mail_multipart_type_alternative, + esp_mail_multipart_maxType +}; + +/* The rfc822 message header fileds types enum */ +enum esp_mail_rfc822_header_field_types +{ + /** The rfc822 message header fields. + * The arrangement is related to rfc822_headers struct. + * Do not modify or remove. + */ + esp_mail_rfc822_header_field_from, + esp_mail_rfc822_header_field_sender, + esp_mail_rfc822_header_field_to, + esp_mail_rfc822_header_field_cc, + esp_mail_rfc822_header_field_subject, + esp_mail_rfc822_header_field_date, + esp_mail_rfc822_header_field_msg_id, + esp_mail_rfc822_header_field_return_path, + esp_mail_rfc822_header_field_reply_to, + esp_mail_rfc822_header_field_in_reply_to, + esp_mail_rfc822_header_field_references, + esp_mail_rfc822_header_field_comments, + esp_mail_rfc822_header_field_keywords, + esp_mail_rfc822_header_field_bcc, + esp_mail_rfc822_header_field_flags, + esp_mail_rfc822_header_field_maxType +}; + +/* The message header fileds types enum and its subproperties enum */ +enum esp_mail_message_header_field_types +{ + /** Additional fields and props. + * Some are used for the library information data field name. + * The arrangement is related to message_headers struct. + * Do not modify or remove. + */ + esp_mail_message_header_field_number, + esp_mail_message_header_field_uid, + esp_mail_message_header_field_accept_language, + esp_mail_message_header_field_content_language, + esp_mail_message_header_field_filename, + esp_mail_message_header_field_name, + esp_mail_message_header_field_size, + esp_mail_message_header_field_mime, + esp_mail_message_header_field_type, + esp_mail_message_header_field_description, + esp_mail_message_header_field_creation_date, + esp_mail_message_header_field_x_priority, + esp_mail_message_header_field_x_msmail_priority, + esp_mail_message_header_field_importance, + esp_mail_message_header_field_content_type, + esp_mail_message_header_field_content_transfer_encoding, + esp_mail_message_header_field_content_disposition, + esp_mail_message_header_field_content_location, + esp_mail_message_header_field_content_id, + esp_mail_message_header_field_content_description, + esp_mail_message_header_field_mime_version, + esp_mail_message_header_field_charset, + esp_mail_message_header_field_format, + esp_mail_message_header_field_delsp, + esp_mail_message_header_field_modification_date, + esp_mail_message_header_field_maxType +}; + +/* The auth capability types enum which shared usage between SMTP and IMAP */ +enum esp_mail_auth_capability_types +{ + /** The server capability keywords per standard. + * The arrangement is related to smtp_auth_capabilities and imap_auth_capabilities structs. + * Do not modify or remove. + */ + + esp_mail_auth_capability_plain, + esp_mail_auth_capability_xoauth2, + esp_mail_auth_capability_cram_md5, + esp_mail_auth_capability_digest_md5, + esp_mail_auth_capability_login, + esp_mail_auth_capability_starttls, + // imap rfc4959 + esp_mail_auth_capability_sasl_ir, + + esp_mail_auth_capability_maxType, +}; + +/* The smessage types enum */ +enum esp_mail_message_type +{ + esp_mail_msg_type_none = 0, + esp_mail_msg_type_plain = 1, + esp_mail_msg_type_html = 2, + esp_mail_msg_type_enriched = 1 +}; + +/* The string mark types enum used in joinStringx functions */ +enum esp_mail_string_mark_type +{ + esp_mail_string_mark_type_none, + esp_mail_string_mark_type_double_quote, + esp_mail_string_mark_type_angle_bracket, + esp_mail_string_mark_type_round_bracket, + esp_mail_string_mark_type_curly_bracket, + esp_mail_string_mark_type_square_bracket +}; + +/* The debug TAG types enum */ +enum esp_mail_debug_tag_type +{ + esp_mail_debug_tag_type_client, + esp_mail_debug_tag_type_server, + esp_mail_debug_tag_type_error, + esp_mail_debug_tag_type_info, + esp_mail_debug_tag_type_warning +}; + +/* The embed attachment types enum */ +enum esp_mail_smtp_embed_message_type +{ + esp_mail_smtp_embed_message_type_attachment = 0, + esp_mail_smtp_embed_message_type_inline +}; + +/* The attachment types enum */ +enum esp_mail_attach_type +{ + esp_mail_att_type_none, + esp_mail_att_type_attachment, + esp_mail_att_type_inline +}; + +/* The debug levels for printing the debug information via Serial port */ +enum esp_mail_debug_level +{ + esp_mail_debug_level_none = 0, + esp_mail_debug_level_basic, + esp_mail_debug_level_maintainer = 0xfff, + esp_mail_debug_level_developer = esp_mail_debug_level_maintainer + 1 +}; + +/* The content transfer encoding enum */ +enum esp_mail_msg_xencoding +{ + esp_mail_msg_xencoding_none, + /* rfc2045 section 2.7 */ + esp_mail_msg_xencoding_7bit, + esp_mail_msg_xencoding_qp, + esp_mail_msg_xencoding_base64, + /* rfc2045 section 2.8 */ + esp_mail_msg_xencoding_8bit, + /* rfc2045 section 2.9 */ + esp_mail_msg_xencoding_binary +}; + +/* The port protocols enum */ +enum esp_mail_protocol +{ + esp_mail_protocol_plain_text, + esp_mail_protocol_ssl, + esp_mail_protocol_tls +}; + +/* The internal use strct */ +struct esp_mail_internal_use_t +{ + esp_mail_msg_xencoding xencoding = esp_mail_msg_xencoding_none; + MB_String cid; +}; + +/* The struct contains port number and its protocol */ +struct port_function +{ + uint16_t port; + esp_mail_protocol protocol; +}; + +/* The struct that contains the list of port_function and its size */ +struct esp_mail_ports_functions +{ + friend class IMAPSession; + friend class SMTPSession; + friend class esp_mail_session_config_t; + + uint16_t size = 0; + port_function *list = nullptr; + bool use_internal_list = false; +}; + +/* The content transfer encoding type struct */ +struct esp_mail_transfer_encoding_t +{ + /* The default 7-bit transfer encoding for US-ACII characters*/ + static constexpr const char *enc_7bit = "7bit"; + + /* The quoted printable transfer encoding for non-US-ASCII characters*/ + static constexpr const char *enc_qp = "quoted-printable"; + + /* The base64 encoded transfer encoding */ + static constexpr const char *enc_base64 = "base64"; + + /* The 8-bit transfer encoding for extended-US-ASCII characters*/ + static constexpr const char *enc_8bit = "8bit"; + + /* The binary transfer encoding for extended-US-ASCII characters with no line + * length limit*/ + static constexpr const char *enc_binary = "binary"; +}; + +/* The content disposition types strucr (rfc 2183) */ +struct esp_mail_content_disposition_type_t +{ + /** if it is intended to be displayed automatically + * upon display of the message. + */ + static constexpr const char *inline_ = "inline"; + + /** to indicate that they are separate from the main body + * of the mail message, and that their display should not + * be automatic, but contingent upon some further action of the user. + */ + static constexpr const char *attachment = "attachment"; +}; + +/* The file (SD/flash) message content struct used for providing SMTP message content from file */ +struct esp_mail_file_message_content_t +{ + /* The file path include its name */ + MB_String name; + + /** The type of file storages e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + esp_mail_file_storage_type type = esp_mail_file_storage_type_flash; +}; + +/* The blob or flash string message content struct used for providing SMTP message content from blob or flash string */ +struct esp_mail_blob_message_content_t +{ + /* The array of content in flash memory */ + const uint8_t *data = nullptr; + + /* The array size in bytes */ + size_t size = 0; +}; + +/* The option to embed this message content as a file */ +struct esp_mail_smtp_embed_message_body_t +{ + /* Enable to send this message body as file */ + bool enable = false; + + /* The name of embedded file */ + MB_String filename; + + /** The embedded type + * esp_mail_smtp_embed_message_type_attachment or 0 + * esp_mail_smtp_embed_message_type_inline or 1 + */ + esp_mail_smtp_embed_message_type type = esp_mail_smtp_embed_message_type_attachment; +}; + +/** This is the base struct for SMTP message. + * This is for input and later used as esp_mail_plain_body_t + * and esp_mail_html_body_t. + * Its members are similar to esp_mail_imap_plain_body_t + * and esp_mail_imap_html_body_t unless it contains + * MB_String object to hold the string. + */ +struct esp_mail_message_body_t +{ + /* The option to embed this message content as a file */ + struct esp_mail_smtp_embed_message_body_t embed; + + /* The PLAIN/HTML content of the message */ + MB_String content; + + const char *nonCopyContent = ""; + + /* The blob that contins PLAIN/HTML content of the message */ + struct esp_mail_blob_message_content_t blob; + + /* The file that contins PLAIN/HTML content of the message */ + struct esp_mail_file_message_content_t file; + + /* The charset of the PLAIN/HTML content of the message */ + MB_String charSet = "UTF-8"; + + /* The content type of message */ + MB_String content_type = mimeinfo[esp_mail_file_extension_txt].mimeType; + + /* The option to encode the content for data transfer */ + MB_String transfer_encoding = "7bit"; + + /* The option to send the PLAIN text with wrapping */ + bool flowed = false; + + /* The internal usage data */ + struct esp_mail_internal_use_t _int; +}; + +/** The PLAIN text body details of the fetching message. + * This is for output and its members are similar to + * esp_mail_message_body_t unless there is no string object + * to hold string data unless the pointer to the const strings + * in IMAPSession object. + */ +struct esp_mail_imap_plain_body_t +{ + /* The option to embed this message content as a file */ + struct esp_mail_smtp_embed_message_body_t embed; + + /* The PLAIN text content of the message */ + const char *content = ""; + + /* The blob that contins PLAIN text content of the message */ + struct esp_mail_blob_message_content_t blob; + + /* The file that contins PLAIN text content of the message */ + struct esp_mail_file_message_content_t file; + + /* The charset of the PLAIN text content of the message */ + const char *charSet = "UTF-8"; + + /* The content type of message */ + const char *content_type = mimeinfo[esp_mail_file_extension_txt].mimeType; + + /* The option to encode the content for data transfer */ + const char *transfer_encoding = "7bit"; + + /* The option to send the PLAIN text with wrapping */ + bool flowed = false; + + /* The internal usage data */ + struct esp_mail_internal_use_t _int; +}; + +/** The HTML body details of the fetching message. + * This is for output and its members are similar to + * esp_mail_message_body_t unless there is no string object + * to hold string data unless the pointer to the const strings + * in IMAPSession object. + */ +struct esp_mail_imap_html_body_t +{ + /* The option to embedded the content as a file */ + struct esp_mail_smtp_embed_message_body_t embed; + + /* The HTML content of the message */ + const char *content = ""; + + /* The blob that contins HTML content of the message */ + struct esp_mail_blob_message_content_t blob; + + /* The file that contins HTML content of the message */ + struct esp_mail_file_message_content_t file; + + /* The charset of the HTML content of the message */ + const char *charSet = "UTF-8"; + + /* The content type of message */ + const char *content_type = mimeinfo[esp_mail_file_extension_html].mimeType; + + /* The option to encode the content for data transfer */ + const char *transfer_encoding = "7bit"; + + /* The internal usage data */ + struct esp_mail_internal_use_t _int; +}; + +/* The PLAIN text body details of the message */ +typedef struct esp_mail_message_body_t esp_mail_plain_body_t; + +/* The HTML text body details of the message */ +typedef struct esp_mail_message_body_t esp_mail_html_body_t; + +/* The attachment info struct used for output */ +struct esp_mail_attachment_info_t +{ + const char *filename = ""; + const char *name = ""; + const char *creationDate = ""; + const char *mime = ""; + const char *description = ""; + esp_mail_attach_type type = esp_mail_att_type_none; + size_t size; +}; + +#if defined(ENABLE_SMTP) + +struct esp_mail_smtp_command_t +{ + char text[9]; +}; + +struct esp_mail_timestamp_value_t +{ + /* The time format of timestamp to inject into subject or content as using in strftime C++ function */ + MB_String format; + /* The tag that will be replaced with current timestamp */ + MB_String tag; +}; + +/** The SMTP commands per stansards. + * The arrangement is related to esp_mail_smtp_command_types enum. + * Do not modify or remove. + */ +const struct esp_mail_smtp_command_t smtp_commands[esp_mail_smtp_command_maxType] PROGMEM = { + "AUTH", + "LOGIN", + "HELO", + "EHLO", + "QUIT", + "MAIL", + "RCPT", + "DATA", + "BDAT", + "LAST", + "PLAIN", + "FROM:", + "TO:", + "NOTIFY", + "SUCCESS", + "FAILURE", + "DELAY", + "BODY", + "\r\n.\r\n", + "STARTTLS"}; + +struct esp_mail_smtp_commands_tokens +{ +public: + esp_mail_smtp_commands_tokens(bool pre) + { + preToken = pre; + } + MB_String operator[](size_t index) + { + MB_String s = preToken ? " " : smtp_commands[index].text; + s += !preToken ? " " : smtp_commands[index].text; + return s; + } + +private: + bool preToken = false; +}; + +// The smtp commands with leading space. +static esp_mail_smtp_commands_tokens smtp_cmd_pre_tokens(true); + +// The smtp commands with trailing space. +static esp_mail_smtp_commands_tokens smtp_cmd_post_tokens(false); + +#endif + +#if defined(ENABLE_IMAP) + +struct esp_mail_imap_command_t +{ + char text[15]; +}; + +/** The IMAP commands per standards. + * The arrangement is related to esp_mail_imap_command_types enum. + * Do not modify or remove. + */ +const struct esp_mail_imap_command_t imap_commands[esp_mail_imap_command_maxType] PROGMEM = { + "STARTTLS", + "APPEND", + "CAPABILITY", + "AUTHENTICATE", + "PLAIN", + "UID", + "FETCH", + "FLAGS", + "LOGIN", + "LIST", + "EXAMINE", + "SEARCH", + "LOGOUT", + "BODY", + "MIME", + "CLOSE", + "EXISTS", + "PEEK", + "TEXT", + "FIELDS", + "HEADER", + "NEW", + "ALL", + "SELECT", + "EXPUNGE", + "CREATE", + "DELETE", + "IDLE", + "DONE", + "RECENT", + "UNSEEN", + "RENAME", + "LSUB", + "SUBSCRIBE", + "UNSUBSCRIBE", + "SILENT", + "MOVE", + "GETQUOTA", + "SETQUOTA", + "ROOT", + "GETACL", + "SETACL", + "DELETEACL", + "MYRIGHTS", + "NAMESPACE", + "ENABLE", + "XOAUTH2", + "STORE", + "+FLAGS", + "-FLAGS", + "COPY", + "ID", + "UNSELECT", + "CONDSTORE", + "NOOP", + "UNCHANGEDSINCE", + "CHANGEDSINCE", + "MODSEC"}; + +struct esp_mail_imap_commands_tokens +{ +public: + esp_mail_imap_commands_tokens(bool pre) + { + preToken = pre; + } + MB_String operator[](size_t index) + { + MB_String s = preToken ? " " : imap_commands[index].text; + s += !preToken ? " " : imap_commands[index].text; + return s; + } + +private: + bool preToken = false; +}; + +// The imap commands with leading space. +static esp_mail_imap_commands_tokens imap_cmd_pre_tokens(true); + +// The imap commands with trailing space. +static esp_mail_imap_commands_tokens imap_cmd_post_tokens(false); + +struct esp_mail_imap_response_t +{ + char text[18]; +}; + +/** The IMAP response. + * The arrangement is related to esp_mail_imap_response_types enum. + * Do not modify or remove. + */ +const struct esp_mail_imap_response_t imap_responses[esp_mail_imap_response_maxType] PROGMEM = { + // Tagged + "OK ", + "NO ", + "BAD ", + // Untagged + "* LIST ", + "* FLAGS ", + "* SEARCH ", + " FETCH ", + " NIL ", + " UID ", + "* CAPABILITY ", + "CAPABILITY ", + "* LSUB ", + "* QUOTA ", + "* QUOTAROOT ", + "* ACL ", + "* MYRIGHTS ", + "* NAMESPACE ", + "* ", + " EXISTS", + " EXPUNGE", + " RECENT", + " [UIDNEXT ", + " [UNSEEN ", + "* ID ", + " [HIGHESTMODSEQ ", + " [NOMODSEQ]", + " [PERMANENTFLAGS ", + " [UIDVALIDITY "}; + +#endif + +struct esp_mail_char_decoding_t +{ + char text[12]; +}; + +/** Supported charactor encodings. + * The arrangement is related to esp_mail_char_decoding_types enum. + * Do not modify or remove. + */ +const struct esp_mail_char_decoding_t char_decodings[esp_mail_char_decoding_maxType] PROGMEM = { + "utf-8", + "iso-8859-1", + "iso-8859-11", + "tis-620", + "windows-874"}; + +struct esp_mail_multipart_t +{ + char text[22]; +}; + +/** MultiPart MIME. + * The arrangement is related to esp_mail_multipart_types enum. + * Do not modify or remove. + */ +const struct esp_mail_multipart_t multipart_types[esp_mail_multipart_maxType] PROGMEM = { + "multipart/mixed", + "multipart/related", + "multipart/parallel", + "multipart/alternative"}; + +struct esp_mail_rfc822_header_field_t +{ + char text[20]; + bool isNum; + bool trim; +}; + +/** The rfc822 message header fields. + * The arrangement is related to esp_mail_rfc822_header_field_types enum. + * Do not modify or remove. + */ +const struct esp_mail_rfc822_header_field_t rfc822_headers[esp_mail_rfc822_header_field_maxType] PROGMEM = { + {"From", false, true}, + {"Sender", false, true}, + {"To", false, true}, + {"Cc", false, true}, + {"Subject", false, false}, + {"Date", false, false}, + {"Message-ID", false, false}, + {"Return-Path", false, true}, + {"Reply-To", false, true}, + {"In-Reply-To", false, true}, + {"References", false, true}, + {"Comments", false, false}, + {"Keywords", false, false}, + {"Bcc", false, true}, + {"Flags", false, false}}; + +struct esp_mail_message_header_field_t +{ + char text[26]; +}; + +/** Additional fields and props. + * The arrangement is related to esp_mail_message_header_field_types enum. + * Do not modify or remove. + */ +const struct esp_mail_message_header_field_t message_headers[esp_mail_message_header_field_maxType] PROGMEM = { + "Number", + "UID", + "Accept-Language", + "Content-Language", + "Filename", + "Name", + "Size", + "MIME", + "Type", + "Description", + "Creation-Date", + "X-Priority", + "X-MSMail-Priority", + "Importance", + "Content-Type", + "Content-transfer-encoding", + "Content-Disposition", + "Content-Location", + "Content-ID", + "Content-Description", + "Mime-Version", + "Charset", + "format", + "delsp", + "Modification-Date"}; + +struct esp_mail_auth_capability_t +{ + char text[20]; +}; + +#if defined(ENABLE_SMTP) + +/** The server capability keywords per standard. + * The arrangement is related to esp_mail_auth_capability_types enum. + * Do not modify or remove. + */ +const struct esp_mail_auth_capability_t smtp_auth_capabilities[esp_mail_auth_capability_maxType] PROGMEM = { + "PLAIN", + "XOAUTH2", + "CRAM-MD5", + "DIGEST-MD5", + "LOGIN", + "STARTTLS", + "DUMMY_AUTH" /* SASL-IR */}; + +struct esp_mail_smtp_auth_tokens +{ +public: + esp_mail_smtp_auth_tokens(bool pre) + { + preToken = pre; + } + MB_String operator[](size_t index) + { + MB_String s = preToken ? " " : smtp_auth_capabilities[index].text; + s += !preToken ? " " : smtp_auth_capabilities[index].text; + return s; + } + +private: + bool preToken = false; +}; + +// The smtp auth capability with leading space. +static esp_mail_smtp_auth_tokens smtp_auth_cap_pre_tokens(true); +// The smtp auth capability with trailing space. +static esp_mail_smtp_auth_tokens smtp_auth_cap_post_tokens(false); + +struct esp_mail_smtp_send_capability_t +{ + char text[15]; +}; + +/** The server capability keywords per standard. + * The arrangement is related esp_mail_smtp_send_capability_types enum. + * Do not modify or remove. + */ +const struct esp_mail_smtp_send_capability_t smtp_send_capabilities[esp_mail_smtp_send_capability_maxType] PROGMEM = { + "BINARYMIME", + "8BITMIME", + "CHUNKING", + "SMTPUTF8", + "PIPELINING", + "DSN", + "" /* ESMTP */}; + +struct esp_mail_smtp_send_tokens +{ +public: + esp_mail_smtp_send_tokens(bool pre) + { + preToken = pre; + } + MB_String operator[](size_t index) + { + MB_String s = preToken ? " " : smtp_send_capabilities[index].text; + s += !preToken ? " " : smtp_send_capabilities[index].text; + return s; + } + +private: + bool preToken = false; +}; + +static esp_mail_smtp_send_tokens smtp_send_cap_pre_tokens(true); + +#endif + +#if defined(ENABLE_IMAP) + +/** The server capability keywords per standard. + * The arrangement is related esp_mail_auth_capability_types enum. + * Do not modify or remove. + */ +const struct esp_mail_auth_capability_t imap_auth_capabilities[esp_mail_auth_capability_maxType] PROGMEM = { + "AUTH=PLAIN", + "AUTH=XOAUTH2", + "CRAM-MD5", + "DIGEST-MD5", + "DUMMY_AUTH", /* Log in */ + "STARTTLS", + "SASL-IR"}; + +struct esp_mail_imap_auth_tokens +{ +public: + esp_mail_imap_auth_tokens(bool pre) + { + preToken = pre; + } + MB_String operator[](size_t index) + { + MB_String s = preToken ? " " : imap_auth_capabilities[index].text; + s += !preToken ? " " : imap_auth_capabilities[index].text; + return s; + } + +private: + bool preToken = false; +}; + +// The imap auth capability with leading space. +static esp_mail_imap_auth_tokens imap_auth_cap_pre_tokens(true); + +struct esp_mail_imap_read_capability_t +{ + char text[15]; +}; + +/** The server capability keywords per standard. + * The arrangement is related esp_mail_imap_read_capability_types enum. + * Do not modify or remove. + */ +const struct esp_mail_imap_read_capability_t imap_read_capabilities[esp_mail_imap_read_capability_maxType] PROGMEM = { + "IMAP4", + "IMAP4rev1", + "IDLE", + "LITERAL+", + "LITERAL-", + "MULTIAPPEND", + "UIDPLUS", + "ACL", + "BINARY", + "LOGINDISABLED", + "MOVE", + "QUOTA", + "NAMESPACE", + "ENABLE", + "ID", + "UNSELECT", + "CHILDREN", + "CONDSTORE" + "" /* Auto cap */}; + +struct esp_mail_imap_read_tokens +{ +public: + esp_mail_imap_read_tokens(bool pre) + { + preToken = pre; + } + MB_String operator[](size_t index) + { + MB_String s = preToken ? " " : imap_read_capabilities[index].text; + s += !preToken ? " " : imap_read_capabilities[index].text; + return s; + } + +private: + bool preToken = false; +}; + +// The imap auth capability with leading space. +static esp_mail_imap_read_tokens imap_read_cap_pre_tokens(true); + +// The imap auth capability with trailing space. +static esp_mail_imap_read_tokens imap_read_cap_post_tokens(false); + +struct esp_mail_imap_identification_key_t +{ + char text[15]; +}; + +/** The identification keys per standard. + * The arrangement is related esp_mail_imap_identification_key_types enum. + * Do not modify or remove. + */ +const struct esp_mail_imap_identification_key_t imap_identification_keys[esp_mail_imap_identification_key_maxType] PROGMEM = { + "name", + "version", + "os", + "os-version", + "vendor", + "support-url", + "address", + "date", + "command", + "arguments", + "environment"}; + +/* The IMAP ID data struct */ +typedef struct esp_mail_imap_identity_t +{ + MB_String name; + MB_String version; + MB_String os; + MB_String os_version; + MB_String vendor; + MB_String support_url; + MB_String address; + MB_String date; + MB_String command; + MB_String arguments; + MB_String environment; + +} IMAP_Identification; + +#endif + +#endif + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) +/* The email address info [SMTP_Message]*/ +struct esp_mail_address_info_t +{ + /* The name of Email author/sender */ + MB_String name; + + /* The Email address */ + MB_String email; +}; +#endif + +#if defined(ENABLE_SMTP) + +/* The SMTP message notification types enum */ +enum esp_mail_smtp_notify +{ + esp_mail_smtp_notify_never = 0, + esp_mail_smtp_notify_success = 1, + esp_mail_smtp_notify_failure = 2, + esp_mail_smtp_notify_delay = 4 +}; + +/* The SMTP status codes enum */ +enum esp_mail_smtp_status_code +{ + esp_mail_smtp_status_code_0, // default + + /* Positive Completion */ + esp_mail_smtp_status_code_211 = 221, // System status, or system help reply + esp_mail_smtp_status_code_214 = 214, // Help message(A response to the HELP command) + esp_mail_smtp_status_code_220 = 220, // Service ready + esp_mail_smtp_status_code_221 = 221, // Service closing transmission channel [RFC 2034] + esp_mail_smtp_status_code_235 = 235, // 2.7.0 Authentication succeeded[RFC 4954] + esp_mail_smtp_status_code_250 = 250, // Requested mail action okay, completed + esp_mail_smtp_status_code_251 = 251, // User not local; will forward + esp_mail_smtp_status_code_252 = 252, // Cannot verify the user, but it will + // try to deliver the message anyway + + /* Positive Intermediate */ + esp_mail_smtp_status_code_334 = 334, //(Server challenge - the text part + // contains the Base64 - encoded + // challenge)[RFC 4954] + esp_mail_smtp_status_code_354 = 354, // Start mail input + + /* Transient Negative Completion */ + /* "Transient Negative" means the error condition is temporary, and the action + may be requested again.*/ + esp_mail_smtp_status_code_421 = 421, // Service is unavailable because the server is shutting down. + esp_mail_smtp_status_code_432 = 432, // 4.7.12 A password transition is needed [RFC 4954] + esp_mail_smtp_status_code_450 = 450, // Requested mail action not taken: mailbox unavailable (e.g., + // mailbox busy or temporarily blocked for policy reasons) + esp_mail_smtp_status_code_451 = 451, // Requested action aborted : local error in processing + // e.g.IMAP server unavailable[RFC 4468] + esp_mail_smtp_status_code_452 = 452, // Requested action not taken : insufficient system storage + esp_mail_smtp_status_code_454 = 454, // 4.7.0 Temporary authentication failure[RFC 4954] + esp_mail_smtp_status_code_455 = 455, // Server unable to accommodate parameters + + /* Permanent Negative Completion */ + esp_mail_smtp_status_code_500 = 500, // Syntax error, command unrecognized + // (This may include errors such as + // command line too long) + // e.g. Authentication Exchange line is too long [RFC 4954] + esp_mail_smtp_status_code_501 = 501, // Syntax error in parameters or arguments + // e.g. 5.5.2 Cannot Base64-decode Client responses [RFC 4954] + // 5.7.0 Client initiated Authentication Exchange (only when the SASL + // mechanism specified that client does not begin the authentication exchange) + // [RFC 4954] + esp_mail_smtp_status_code_502 = 502, // Command not implemented + esp_mail_smtp_status_code_503 = 503, // Bad sequence of commands + esp_mail_smtp_status_code_504 = 504, // Command parameter is not implemented + // e.g. 5.5.4 Unrecognized authentication type [RFC 4954] + esp_mail_smtp_status_code_521 = 521, // Server does not accept mail [RFC 7504] + esp_mail_smtp_status_code_523 = 523, // Encryption Needed [RFC 5248] + esp_mail_smtp_status_code_530 = 530, // 5.7.0 Authentication required [RFC 4954] + esp_mail_smtp_status_code_534 = 534, // 5.7.9 Authentication mechanism is too weak [RFC 4954] + esp_mail_smtp_status_code_535 = 535, // 5.7.8 Authentication credentials invalid [RFC 4954] + esp_mail_smtp_status_code_538 = 538, // 5.7.11 Encryption required for + // requested authentication mechanism[RFC + // 4954] + esp_mail_smtp_status_code_550 = 550, // Requested action not taken: mailbox unavailable (e.g., mailbox not + // found, no access, or command rejected for policy reasons) + esp_mail_smtp_status_code_551 = 551, // User not local; please try + esp_mail_smtp_status_code_552 = 552, // Requested mail action aborted: exceeded storage allocation + esp_mail_smtp_status_code_553 = 553, // Requested action not taken: mailbox name not allowed + esp_mail_smtp_status_code_554 = 554, // Transaction has failed (Or, in the + // case of a connection-opening response, + // "No SMTP service here") + // e.g. 5.3.4 Message too big for system [RFC 4468] + esp_mail_smtp_status_code_556 = 556, // Domain does not accept mail[RFC 7504] +}; + +/* The SMTP ports enum */ +enum esp_mail_smtp_port +{ + esp_mail_smtp_port_25 = 25, // PLAIN/TLS with STARTTLS + esp_mail_smtp_port_465 = 465, // SSL + esp_mail_smtp_port_587 = 587, // TLS with STARTTLS +}; + +const struct port_function smtp_ports[3] = { + {esp_mail_smtp_port_25, esp_mail_protocol_plain_text}, + {esp_mail_smtp_port_465, esp_mail_protocol_ssl}, + {esp_mail_smtp_port_587, esp_mail_protocol_tls}}; + +/* The SMTP message response [SMTP_Message] */ +struct esp_mail_smtp_msg_response_t +{ + /* The author Email address to reply */ + MB_String reply_to; + + /* The sender Email address to return the message */ + MB_String return_path; + + /** The Delivery Status Notifications e.g. esp_mail_smtp_notify_never, + * esp_mail_smtp_notify_success, + * esp_mail_smtp_notify_failure, and + * esp_mail_smtp_notify_delay + */ + int notify = esp_mail_smtp_notify::esp_mail_smtp_notify_never; +}; + +/* The SMTP enable option [SMTP_Message] */ +struct esp_mail_smtp_enable_option_t +{ + /* Enable chunk data sending for large message */ + bool chunking = false; +}; + +/* The SMTP blob data attachment data [Session_Config] */ +struct esp_mail_attach_blob_t +{ + /* BLOB data (flash or ram) */ + const uint8_t *data = nullptr; + + /* BLOB data size in byte */ + size_t size = 0; +}; + +/* The SMTP file attachment data [Session_Config] */ +struct esp_mail_attach_file_t +{ + MB_String path; + /** The file storage type e.g. esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + esp_mail_file_storage_type storage_type = esp_mail_file_storage_type_none; +}; + +/* The SMTP attachment decription [Session_Config] */ +struct esp_mail_attach_descr_t +{ + /* The name of attachment */ + MB_String name; + + /* The attachment file name */ + MB_String filename; + + /* The MIME type of attachment */ + MB_String mime; + + /* The transfer encoding of attachment e.g. base64 */ + MB_String transfer_encoding = "base64"; + + /* The content encoding of attachment e.g. base64 */ + MB_String content_encoding; + + /* The content id of attachment file */ + MB_String content_id; + + /* The description of attachment file */ + MB_String description; +}; + +/* Used internally in esp_mail_attachment_t */ +struct esp_mail_attach_internal_t +{ + esp_mail_attach_type att_type = esp_mail_att_type_attachment; + int index = 0; + int msg_uid = 0; + bool flash_blob = false; + esp_mail_msg_xencoding xencoding = esp_mail_msg_xencoding_none; + bool parallel = false; + MB_String cid; +}; + +/* The struct used as SMTP_Attachment for SMTP and ESP_Mail_Attachment for IMAP */ +struct esp_mail_attachment_t +{ + /* The attachment description */ + struct esp_mail_attach_descr_t descr; + + /* The BLOB data config */ + struct esp_mail_attach_blob_t blob; + + /* The file data config */ + struct esp_mail_attach_file_t file; + + /* reserved for internal usage */ + struct esp_mail_attach_internal_t _int; +}; + +/* The struct used as SMTP_Result */ +struct esp_mail_smtp_send_status_t +{ + /* The status of the message */ + bool completed = false; + + /* The primary recipient mailbox of the message */ + MB_String recipients; + + /* The topic of the message */ + MB_String subject; + + /* The timestamp of the message */ + uint32_t timestamp = 0; +}; + +/* Used internally for SMTPSession */ +struct esp_mail_smtp_msg_type_t +{ + bool rfc822 = false; + int rfc822Idx = 0; +}; + +/* Used internally for holding base64 data sources */ +struct esp_mail_smtp_send_base64_data_info_t +{ + esp_mail_file_storage_type storageType = esp_mail_file_storage_type_none; + const char *filename = ""; + const uint8_t *rawPtr = nullptr; + bool flashMem = false; + size_t size = 0; + size_t dataIndex = 0; +}; + +/* SMTP commands types enum */ +enum esp_mail_smtp_command +{ + esp_mail_smtp_cmd_undefined, + esp_mail_smtp_cmd_initial_state, + esp_mail_smtp_cmd_greeting, + esp_mail_smtp_cmd_start_tls, + esp_mail_smtp_cmd_login_user, + esp_mail_smtp_cmd_auth_plain, + esp_mail_smtp_cmd_auth_login, + esp_mail_smtp_cmd_auth_xoauth2, + esp_mail_smtp_cmd_login_psw, + esp_mail_smtp_cmd_send_header_sender, + esp_mail_smtp_cmd_send_header_recipient, + esp_mail_smtp_cmd_send_body, + esp_mail_smtp_cmd_chunk_termination, + esp_mail_smtp_cmd_logout, + esp_mail_smtp_cmd_custom +}; + +/* SMTP message priority level enum */ +enum esp_mail_smtp_priority +{ + esp_mail_smtp_priority_high = 1, + esp_mail_smtp_priority_normal = 3, + esp_mail_smtp_priority_low = 5, +}; + +/* SMTP response data */ +typedef struct esp_mail_smtp_response_status_t +{ + /* The SMTP server response status code */ + int statusCode = 0; + + /* error code */ + int errorCode = 0; + int id = -1; + MB_String text; +} SMTP_Response; + +#endif + +#if defined(ENABLE_IMAP) + +enum esp_mail_imap_msg_num_type +{ + esp_mail_imap_msg_num_type_undefined, + esp_mail_imap_msg_num_type_uid, + esp_mail_imap_msg_num_type_number +}; + +enum esp_mail_imap_store_flag_type +{ + esp_mail_imap_store_flag_type_set, + esp_mail_imap_store_flag_type_add, + esp_mail_imap_store_flag_type_remove +}; + +enum esp_mail_char_decoding_scheme +{ + esp_mail_char_decoding_scheme_default = -1, + esp_mail_char_decoding_scheme_utf_8, + esp_mail_char_decoding_scheme_iso8859_1, + esp_mail_char_decoding_scheme_iso8859_11, + esp_mail_char_decoding_scheme_tis_620, + esp_mail_char_decoding_scheme_windows_874 +}; + +enum esp_mail_imap_rights_type_t +{ + /* a - administer (perform SETACL/DELETEACL/GETACL/LISTRIGHTS) */ + esp_mail_imap_rights_administer = 'a' - 'a', + /* c - RFC2086 (obsoleted) create (CREATE new sub-mailboxes in any implementation-defined hierarchy) */ + esp_mail_imap_rights_create_c = 'c' - 'a', + /* d - RFC2086 (obsoleted) delete (STORE DELETED flag, perform EXPUNGE) */ + esp_mail_imap_rights_delete_d = 'd' - 'a', + /* e - perform EXPUNGE and expunge as a part of CLOSE */ + esp_mail_imap_rights_expunge = 'e' - 'a', + /* i - insert (perform APPEND, COPY into mailbox) */ + esp_mail_imap_rights_insert = 'i' - 'a', + /* k - RFC4314 create mailboxes (CREATE new sub-mailboxes in any implementation-defined hierarchy, parent mailbox for the new mailbox name in RENAME)*/ + esp_mail_imap_rights_create = 'k' - 'a', + /* l - lookup (mailbox is visible to LIST/LSUB commands, SUBSCRIBE mailbox) */ + esp_mail_imap_rights_lookup = 'l' - 'a', + /* p - post (send mail to submission address for mailbox, not enforced by IMAP4 itself) */ + esp_mail_imap_rights_post = 'p' - 'a', + /* r - read (SELECT the mailbox, perform STATUS) */ + esp_mail_imap_rights_read = 'r' - 'a', + /* s - keep seen/unseen information across sessions (set or clear \SEEN flag via STORE, also set \SEEN during APPEND/COPY/ FETCH BODY[...]) */ + esp_mail_imap_rights_seen = 's' - 'a', + /* t - RFC4314 delete messages (set or clear \DELETED flag via STORE, set \DELETED flag during APPEND/COPY) */ + esp_mail_imap_rights_delete_message = 't' - 'a', + /* w - write (set or clear flags other than \SEEN and \DELETED via STORE, also set them during APPEND/COPY) */ + esp_mail_imap_rights_write = 'w' - 'a', + /* x - RFC4314 delete mailbox (DELETE mailbox, old mailbox name in RENAME) */ + esp_mail_imap_rights_delete_mailbox = 'x' - 'a', + + esp_mail_imap_rights_maxType = esp_mail_imap_rights_delete_mailbox + 1 +}; + +enum esp_mail_imap_port +{ + esp_mail_imap_port_143 = 143, // PLAIN/TLS with STARTTLS + esp_mail_imap_port_993 = 993, // SSL +}; + +const struct port_function imap_ports[2] = { + {esp_mail_imap_port_143, esp_mail_protocol_plain_text}, + {esp_mail_imap_port_993, esp_mail_protocol_ssl}}; + +enum esp_mail_imap_auth_mode +{ + esp_mail_imap_mode_examine, + esp_mail_imap_mode_select +}; + +enum esp_mail_imap_response_status +{ + esp_mail_imap_resp_unknown, + esp_mail_imap_resp_ok, + esp_mail_imap_resp_no, + esp_mail_imap_resp_bad +}; + +enum esp_mail_imap_polling_status_type +{ + imap_polling_status_type_undefined, + imap_polling_status_type_new_message, + imap_polling_status_type_remove_message, + imap_polling_status_type_fetch_message +}; + +enum esp_mail_imap_header_state +{ + esp_mail_imap_state_content_type = esp_mail_rfc822_header_field_maxType, + esp_mail_imap_state_content_transfer_encoding, + esp_mail_imap_state_accept_language, + esp_mail_imap_state_content_language, + esp_mail_imap_state_char_set, + esp_mail_imap_state_boundary +}; + +enum esp_mail_imap_command +{ + esp_mail_imap_cmd_capability, + esp_mail_imap_cmd_starttls, + esp_mail_imap_cmd_sasl_login, + esp_mail_imap_cmd_sasl_auth_plain, + esp_mail_imap_cmd_sasl_auth_oauth, + esp_mail_imap_cmd_list, + esp_mail_imap_cmd_lsub, + esp_mail_imap_cmd_subscribe, + esp_mail_imap_cmd_unsubscribe, + esp_mail_imap_cmd_select, + esp_mail_imap_cmd_examine, + esp_mail_imap_cmd_close, + esp_mail_imap_cmd_status, + esp_mail_imap_cmd_search, + esp_mail_imap_cmd_fetch_body_header, + esp_mail_imap_cmd_fetch_body_mime, + esp_mail_imap_cmd_fetch_body_text, + esp_mail_imap_cmd_fetch_body_attachment, + esp_mail_imap_cmd_fetch_body_inline, + esp_mail_imap_cmd_fetch_sequence_set, + esp_mail_imap_cmd_logout, + esp_mail_imap_cmd_store, + esp_mail_imap_cmd_move, + esp_mail_imap_cmd_get_quota, + esp_mail_imap_cmd_set_quota, + esp_mail_imap_cmd_get_quota_root, + esp_mail_imap_cmd_get_acl, + esp_mail_imap_cmd_set_acl, + esp_mail_imap_cmd_delete_acl, + esp_mail_imap_cmd_my_rights, + esp_mail_imap_cmd_namespace, + esp_mail_imap_cmd_expunge, + esp_mail_imap_cmd_create, + esp_mail_imap_cmd_rename, + esp_mail_imap_cmd_delete, + esp_mail_imap_cmd_idle, + esp_mail_imap_cmd_done, + esp_mail_imap_cmd_get_uid, + esp_mail_imap_cmd_get_flags, + esp_mail_imap_cmd_append, + esp_mail_imap_cmd_append_last, + esp_mail_imap_cmd_enable, + esp_mail_imap_cmd_id, + esp_mail_imap_cmd_unselect, + esp_mail_imap_cmd_noop, + esp_mail_imap_cmd_copy, + esp_mail_imap_cmd_custom +}; + +enum esp_mail_imap_mime_fetch_type +{ + esp_mail_imap_mime_fetch_type_part, + esp_mail_imap_mime_fetch_type_sub_part1, + esp_mail_imap_mime_fetch_type_sub_part2 +}; + +enum esp_mail_imap_header_type +{ + esp_mail_imap_header_from, + esp_mail_imap_header_to, + esp_mail_imap_header_cc, + esp_mail_imap_header_subject, + esp_mail_imap_header_date, + esp_mail_imap_header_msg_id, + esp_mail_imap_header_cont_lang, + esp_mail_imap_header_accept_lang +}; + +enum esp_mail_imap_multipart_sub_type +{ + esp_mail_imap_multipart_sub_type_none = 0, + esp_mail_imap_multipart_sub_type_mixed, + esp_mail_imap_multipart_sub_type_alternative, + esp_mail_imap_multipart_sub_type_parallel, + esp_mail_imap_multipart_sub_type_digest, + esp_mail_imap_multipart_sub_type_related, + esp_mail_imap_multipart_sub_type_report, +}; + +enum esp_mail_imap_message_sub_type +{ + esp_mail_imap_message_sub_type_none = 0, + esp_mail_imap_message_sub_type_rfc822, + esp_mail_imap_message_sub_type_delivery_status, + esp_mail_imap_message_sub_type_partial, + esp_mail_imap_message_sub_type_external_body, +}; + +typedef struct esp_mail_imap_response_status_t +{ + // No IMAP server response status code (statusCode), server returns OK, NO and BAD response instead + + /* error code */ + int errorCode = 0; + MB_String tag; + MB_String text; + MB_String status; + bool completed = false; + +public: + void clear(bool clearTag = true) + { + if (clearTag) + tag.clear(); + status.clear(); + text.clear(); + completed = false; + } +} IMAP_Response; + +struct esp_mail_imap_msg_num_t +{ + esp_mail_imap_msg_num_type type = esp_mail_imap_msg_num_type_undefined; + uint32_t value = 0; +}; + +__attribute__((used)) struct +{ + bool operator()(struct esp_mail_imap_msg_num_t a, struct esp_mail_imap_msg_num_t b) const { return a.value > b.value; } +} compareMore; + +struct esp_mail_imap_rfc822_msg_header_item_t +{ + MB_String header_items[esp_mail_rfc822_header_field_maxType]; +}; + +/* IMAP quota root info */ +typedef struct esp_mail_imap_quota_root_info_t +{ + /* The quota root */ + MB_String quota_root; + + /* The resource name e.g. STORAGE and MESSAGE */ + MB_String name; + + /* The resource usage in kilo octets */ + size_t usage = 0; + + /* The resource limit in kilo octets */ + size_t limit = 0; + +} IMAP_Quota_Root_Info; + +/* IMAP namespace info */ +typedef struct esp_mail_imap_namespace_info_t +{ + /* The leading prefix */ + MB_String prefix; + + /* The hierarchy delimiter */ + MB_String delimiter; + +} IMAP_Namespace_Info; + +typedef struct esp_mail_imap_rights_info_t +{ + MB_String identifier; + bool rights[esp_mail_imap_rights_maxType]; + +} IMAP_Rights_Info; + +/* descrete media types (rfc 2046) */ +struct esp_mail_imap_descrete_media_type_t +{ + /** textual information with subtypes + * "plain" + * "enriched" (rfc 1896 revised from richtext in rfc 1341) + * + * unrecognized subtypes and charset should be interpreted as + * application/octet-stream + * + * parameters: + * "charset" (rfc 2045) default is us-ascii + * for character set includes 8-bit characters + * and such characters are used in the body, Content-Transfer-Encoding + * header field and a corresponding encoding on the data are required + * + * ISO-8859-X where "X" is to be replaced, as + * necessary, for the parts of ISO-8859 [ISO-8859]. + */ + static constexpr const char *text = "text"; + + /** image data with subtypes (rfc 2048) + * "jpeg" + * "gif" + * + * unrecognized subtypes should be interpreted as application/octet-stream + */ + static constexpr const char *image = "image"; + + /** audio data with initial subtype + * "baic" -- for single channel audio encoded using 8bit ISDN mu-law [PCM] + * at a sample rate of 8000 Hz. + * + * Unrecognized subtypes of "audio" should at a miniumum be treated as + * "application/octet-stream" + */ + static constexpr const char *audio = "audio"; + + /** video data with initial subtype + * "mpeg" + * + * Unrecognized subtypes of "video" should at a minumum be treated as + * "application/octet-stream" + */ + static constexpr const char *video = "video"; + + /** some other kind of data, typically either + * uninterpreted binary data or information to be + * processed by an application with subtypes + * + * "octet-stream" -- uninterpreted binary data + * "PostScript" -- for the transport of PostScript material + * + * Other expected uses include spreadsheets, data for mail-based + * scheduling systems, and languages for "active" (computational) + * messaging, and word processing formats that are not directly readable. + * + * The octet-stream subtype parameters: + * TYPE, PADDING, NAME + */ + static constexpr const char *application = "application"; +}; + +/** composite media types (rfc 2046) + * + * As stated in the definition of the Content-Transfer-Encoding field + * [RFC 2045], no encoding other than "7bit", "8bit", or "binary" is + * permitted for entities of type "multipart". The "multipart" boundary + * delimiters and header fields are always represented as 7bit US-ASCII + * in any case (though the header fields may encode non-US-ASCII header + * text as per RFC 2047) and data within the body parts can be encoded + * on a part-by-part basis, with Content-Transfer-Encoding fields for + * each appropriate body part. + */ +struct esp_mail_imap_composite_media_type_t +{ + /** data consisting of multiple entities of independent data types + * The Content-Type field for multipart entities requires one parameter, + * "boundary". + * The boundary delimiter line is then defined as a line + * consisting entirely of two hyphen characters ("-", decimal value 45) + * followed by the boundary parameter value from the Content-Type header + * field, optional linear whitespace, and a terminating CRLF. + * + * NOTE: The CRLF preceding the boundary delimiter line is conceptually + * attached to the boundary so that it is possible to have a part that + * does not end with a CRLF (line break). Body parts that must be + * considered to end with line breaks, therefore, must have two CRLFs + * preceding the boundary delimiter line, the first of which is part of + * the preceding body part, and the second of which is part of the + * encapsulation boundary. + * + * Boundary delimiters must not appear within the encapsulated material, + * and must be no longer than 70 characters, not counting the two + * leading hyphens. + * + * The boundary delimiter line following the last body part is a + * distinguished delimiter that indicates that no further body parts + * will follow. Such a delimiter line is identical to the previous + * delimiter lines, with the addition of two more hyphens after the + * boundary parameter value. + * + * See rfc2049 Appendix A for a Complex Multipart Example + */ + static constexpr const char *multipart = "multipart"; + + /* an encapsulated message */ + static constexpr const char *message = "message"; +}; + +typedef struct esp_mail_imap_mime_data_stream_info_t +{ + /* message UID */ + uint32_t uid = 0; + + /* content type */ + const char *type = ""; + + /* disposition */ + const char *disposition = ""; + + /* content character set */ + const char *charSet = ""; + + /* text content flowed format parameter */ + bool flowed = false; + + /* text content format DelSp parameter */ + bool delsp = false; + + /* content transfer encoding */ + const char *transfer_encoding = ""; + + /* content ID */ + const char *cid = ""; + + /* content description */ + const char *description = ""; + + /* content file name */ + const char *filename = ""; + + /* content name */ + const char *name = ""; + + /* creation date */ + const char *date = ""; + + /* content size */ + size_t size = 0; + + /* octet size */ + size_t octet_size = 0; + + /* current octet count */ + int octet_count = 0; + + /* data size */ + size_t data_size = 0; + + /* data buffer */ + void *data = NULL; + + bool isFirstData = false; + + bool isLastData = false; + +} MIME_Data_Stream_Info; + +typedef struct esp_mail_imap_decoding_info +{ + enum message_part_type + { + message_part_type_header, + message_part_type_text + }; + + /* The character set of the string to decode */ + const char *charset = ""; + + /* The string to decode */ + const char *data = ""; + + /* The decoded string to be processed */ + MB_String decodedString; + + /** The type of data that currently processed + * 0 or IMAP_Decoding_Info::message_part_type_header + * 1 or IMAP_Decoding_Info::message_part_type_text + */ + message_part_type type = message_part_type_header; + +} IMAP_Decoding_Info; + +struct esp_mail_imap_media_text_sub_type_t +{ + static constexpr const char *plain = "plain"; + static constexpr const char *enriched = "enriched"; + static constexpr const char *html = "html"; +}; + +/* multipart sub types */ +struct esp_mail_imap_multipart_sub_type_t +{ + /* a generic mixed set of parts */ + static constexpr const char *mixed = "mixed"; + + /* the same data in multiple formats */ + static constexpr const char *alternative = "alternative"; + + /* parts intended to be viewed simultaneously */ + static constexpr const char *parallel = "parallel"; + + /* multipart entities in which each part has a default type of + * "message/rfc822" */ + static constexpr const char *digest = "digest"; + + /* for compound objects consisting of several inter-related body parts (rfc + * 2387) */ + static constexpr const char *related = "related"; + + /* rfc 3462 */ + static constexpr const char *report = "report"; +}; + +/* message body sub types */ +struct esp_mail_imap_message_sub_type_t +{ + /* body contains an encapsulated message, with the syntax of an RFC 822 + * message. */ + static constexpr const char *rfc822 = "rfc822"; + + /* to allow large objects to be delivered as several separate pieces of mail + */ + static constexpr const char *Partial = "Partial"; + + /* the actual body data are not included, but merely referenced */ + static constexpr const char *External_Body = "External-Body"; + + static constexpr const char *delivery_status = "delivery-status"; +}; + +/* IMAP polling status */ +typedef struct esp_mail_imap_polling_status_t +{ + /** The type of status e.g. imap_polling_status_type_undefined, imap_polling_status_type_new_message, + * imap_polling_status_type_fetch_message and imap_polling_status_type_remove_message. + */ + esp_mail_imap_polling_status_type type = imap_polling_status_type_undefined; + + /** Message number or order from the total number of message that added, fetched or deleted. + */ + size_t messageNum = 0; + + /** Argument of commands e.g. FETCH + */ + MB_String argument; +} IMAP_Polling_Status; + +struct esp_mail_message_part_info_t +{ + enum content_header_field + { + content_header_field_none, + content_header_field_type, + content_header_field_description, + content_header_field_id, + content_header_field_disposition, + content_header_field_transfer_enc, + content_header_field_ext + + }; + + int octetLen = 0; + int octetCount = 0; + int attach_data_size = 0; + int textLen = 0; + bool sizeProp = false; + int nestedLevel = 0; + + // pointer to the MB_String for storing multi-line header field content. + uint32_t stringPtr = 0; + esp_mail_char_decoding_scheme stringEnc = esp_mail_char_decoding_scheme_default; + + content_header_field cur_content_hdr = content_header_field_none; + + MB_String partNumStr; + MB_String partNumFetchStr; + MB_String text; + MB_String filename; + MB_String CID; + MB_String type; + MB_String save_path; + MB_String name; + MB_String content_disposition; + MB_String content_description; + MB_String content_type; + MB_String descr; + MB_String content_transfer_encoding; + MB_String creation_date; + MB_String modification_date; + MB_String charset; + MB_String download_error; + esp_mail_attach_type attach_type = esp_mail_att_type_none; + esp_mail_message_type msg_type = esp_mail_msg_type_none; + bool file_open_write = false; + bool multipart = false; + bool is_firmware_file = false; + bool save_to_file = true; + size_t firmware_downloaded_byte = 0; + esp_mail_imap_multipart_sub_type multipart_sub_type = esp_mail_imap_multipart_sub_type_none; + esp_mail_imap_message_sub_type message_sub_type = esp_mail_imap_message_sub_type_none; + bool rfc822_part = false; + int rfc822_msg_Idx = 0; + struct esp_mail_imap_rfc822_msg_header_item_t rfc822_header; + bool error = false; + bool plain_flowed = false; + bool plain_delsp = false; + esp_mail_msg_xencoding xencoding = esp_mail_msg_xencoding_none; +}; + +struct esp_mail_message_header_t +{ + int header_data_len = 0; + + struct esp_mail_imap_rfc822_msg_header_item_t header_fields; + + MB_String content_type; + MB_String content_transfer_encoding; + uint32_t message_uid = 0; + uint32_t message_no = 0; + MB_String boundary; + MB_String accept_language; + MB_String content_language; + MB_String char_set; + bool multipart = false; + bool rfc822_part = false; + bool hasAttachment = false; + int rfc822Idx = 0; + MB_String partNumStr; + + esp_mail_imap_multipart_sub_type multipart_sub_type = esp_mail_imap_multipart_sub_type_none; + esp_mail_imap_message_sub_type message_sub_type = esp_mail_imap_message_sub_type_none; + MB_String msgID; + MB_String flags; + MB_String error_msg; + bool error = false; + _vectorImpl part_headers; + int attachment_count = 0; + int sd_alias_file_count = 0; + int total_download_size = 0; + int downloaded_size = 0; + int total_attach_data_size = 0; + int downloaded_bytes = 0; + int message_data_count = 0; +}; + +/* Internal use */ +struct esp_mail_folder_info_t +{ + MB_String name; + MB_String attributes; + MB_String delimiter; +}; + +struct esp_mail_folder_info_item_t +{ + /* The name of folder */ + const char *name = ""; + + /* The attributes of folder */ + const char *attributes = ""; + + /* The delimeter of folder */ + const char *delimiter = ""; +}; + +struct esp_mail_imap_download_config_t +{ + /* To download the PLAIN text content of the message */ + bool text = false; + + /* To download the HTML content of the message */ + bool html = false; + + /* To download the attachments of the message */ + bool attachment = false; + + /* To download the inline image of the message */ + bool inlineImg = false; + + /* To download the rfc822 mesages in the message */ + bool rfc822 = false; + + /* To download the message header */ + bool header = false; +}; + +struct esp_mail_imap_enable_config_t +{ + /* To store the PLAIN text of the message in the IMAPSession */ + bool text = false; + + /* To store the HTML of the message in the IMAPSession */ + bool html = false; + + /* To store the rfc822 messages in the IMAPSession */ + bool rfc822 = false; + + /* To enable the download status via the serial port */ + bool download_status = false; + + /* To sort the message UID of the search result in descending order */ + bool recent_sort = false; + + /* To allow case sesitive in header parsing */ + bool header_case_sensitive = false; +}; + +struct esp_mail_imap_limit_config_t +{ + /* The maximum messages from the search result */ + size_t search = 10; + + /* The maximum messages from the sequence set fetching result */ + size_t fetch = 30; + + /** The maximum size of the memory buffer to store the message content. + * This is only limit for data to be stored in the IMAPSession. + */ + size_t msg_size = 1024; + + /* The maximum size of each attachment to download */ + size_t attachment_size = 1024 * 1024 * 5; + + /* The IMAP idle timeout in ms (1 min to 29 min). Default is 8 min */ + size_t imap_idle_timeout = 8 * 60 * 1000; + + /** The IMAP idle host check interval in ms (30 sec to imap_idle_timeout) + * for internet availability checking to ensure the connection is active. + * Default is 1 min. + */ + size_t imap_idle_host_check_interval = 60 * 1000; +}; + +struct esp_mail_imap_storage_config_t +{ + /* The path to save the downloaded file */ + MB_String saved_path; + + /** The type of file storages e.g. + * esp_mail_file_storage_type_none, + * esp_mail_file_storage_type_flash, and + * esp_mail_file_storage_type_sd + */ + esp_mail_file_storage_type type = esp_mail_file_storage_type_flash; +}; + +struct esp_mail_imap_search_config_t +{ + /* The search criteria */ + MB_String criteria; + + /* The option to search the unseen message */ + bool unseen_msg = false; +}; + +struct esp_mail_imap_sequence_set_t +{ + /* The sequence set string i.g., unique identifier (UID) or message sequence number or ranges of UID or sequence number */ + MB_String string; + + /* The option for sequenceSet whether it is UID or message sequence number */ + bool UID = false; + + /* The option for header only fetching */ + bool headerOnly = false; +}; + +struct esp_mail_imap_fetch_config_t +{ + /* The UID of message to fetch */ + MB_String uid; + + /* The message sequence number to fetch */ + MB_String number; + + /* The sequence set options */ + esp_mail_imap_sequence_set_t sequence_set; + + /* Set the message flag as seen */ + bool set_seen = false; + + /* The int32_t option for CHANGESINCE conditional test. */ + int32_t modsequence = 0; + + /* The config to fetch only the header */ + bool headerOnly = false; +}; + +struct esp_mail_imap_firmware_config_t +{ + /* Update firmware using message attachments if one of its filename matches. */ + MB_String attach_filename; + + /* Save firmware file */ + bool save_to_file = false; +}; + +struct esp_mail_imap_data_config_t +{ + /* The config for fetching */ + struct esp_mail_imap_fetch_config_t fetch; + + /* The config for search */ + struct esp_mail_imap_search_config_t search; + + /* The config about the limits */ + struct esp_mail_imap_limit_config_t limit; + + /* The config to enable the features */ + struct esp_mail_imap_enable_config_t enable; + + /* The config about downloads */ + struct esp_mail_imap_download_config_t download; + + /* The config about the storage and path to save the downloaded file */ + struct esp_mail_imap_storage_config_t storage; + + /* The config about firmware updates and downloads for ESP32, ESP8266 and Raspberry Pi Pico */ + struct esp_mail_imap_firmware_config_t firmware_update; + + IMAP_Identification identification; +}; + +/* Mail and MIME Header Fields */ +struct esp_mail_imap_msg_item_t +{ + friend class IMAPSession; + +public: + esp_mail_imap_msg_item_t() + { + text.content_type = mimeinfo[esp_mail_file_extension_txt].mimeType; + html.content_type = mimeinfo[esp_mail_file_extension_html].mimeType; + }; + + /* The message number */ + int msgNo = 0; + + /* The message UID */ + int UID = 0; + + /* The message identifier (RFC 4021) */ + const char *ID = ""; + + /* The language(s) for auto-responses (RFC 4021) */ + const char *acceptLang = ""; + + /* The language of message content (RFC 4021) */ + const char *contentLang = ""; + + /* The mailbox of message author (RFC 4021) */ + const char *from = ""; + + /* The charset of the mailbox of message author */ + // deprecated + const char *fromCharset = ""; + + /* The primary recipient mailbox (RFC 4021) */ + const char *to = ""; + + /* The charset of the primary recipient mailbox */ + // deprecated + const char *toCharset = ""; + + /* The Carbon-copy recipient mailboxes (RFC 4021) */ + const char *cc = ""; + + /* The charset of the Carbon-copy recipient mailbox header */ + // deprecated + const char *ccCharset = ""; + + /* The Blind-carbon-copy recipient mailboxes (RFC 4021) */ + const char *bcc = ""; + + /* The charset of the Blind-carbon-copy recipient mailbox header */ + // deprecated + const char *bccCharset = ""; + + /* The message date and time (RFC 4021) */ + const char *date = ""; + + /* The topic of message (RFC 4021) */ + const char *subject = ""; + + /* The topic of message charset */ + // deprecated + const char *subjectCharset = ""; + + /* The message flags */ + const char *flags = ""; + + /* The PLAIN text content of the message */ + esp_mail_imap_plain_body_t text; + + /* The HTML content of the message */ + esp_mail_imap_html_body_t html; + + /* rfc822 related */ + + /* The sender Email */ + const char *sender; + + /* The charset of the sender Email */ + // deprecated + const char *senderCharset = ""; + + /* The keywords or phrases, separated by commas */ + const char *keywords = ""; + + /* The comments about message */ + const char *comments = ""; + + /* The field that contains the parent's message ID of the message to which this one is a reply */ + const char *in_reply_to = ""; + + /* The field that contains the parent's references (if any) and followed by the parent's message ID (if any) of the message to which this one is a reply */ + const char *references = ""; + + /* The return recipient of the message */ + const char *return_path = ""; + + /* The Email address to reply */ + const char *reply_to; + + /* The error description from fetching the message */ + const char *fetchError = ""; + + /* The info about the attachments in the message */ + _vectorImpl attachments; + + /* The info about the rfc822 messages included in the message */ + _vectorImpl rfc822; + + /* The status for message that contains attachment */ + bool hasAttachment = false; + +private: + void setRFC822Headers(struct esp_mail_imap_rfc822_msg_header_item_t *rfc822_header) + { + from = rfc822_header->header_items[esp_mail_rfc822_header_field_from].c_str(); + sender = rfc822_header->header_items[esp_mail_rfc822_header_field_sender].c_str(); + to = rfc822_header->header_items[esp_mail_rfc822_header_field_to].c_str(); + cc = rfc822_header->header_items[esp_mail_rfc822_header_field_cc].c_str(); + subject = rfc822_header->header_items[esp_mail_rfc822_header_field_subject].c_str(); + date = rfc822_header->header_items[esp_mail_rfc822_header_field_date].c_str(); + ID = rfc822_header->header_items[esp_mail_rfc822_header_field_msg_id].c_str(); + return_path = rfc822_header->header_items[esp_mail_rfc822_header_field_return_path].c_str(); + reply_to = rfc822_header->header_items[esp_mail_rfc822_header_field_reply_to].c_str(); + in_reply_to = rfc822_header->header_items[esp_mail_rfc822_header_field_in_reply_to].c_str(); + references = rfc822_header->header_items[esp_mail_rfc822_header_field_references].c_str(); + comments = rfc822_header->header_items[esp_mail_rfc822_header_field_comments].c_str(); + keywords = rfc822_header->header_items[esp_mail_rfc822_header_field_keywords].c_str(); + bcc = rfc822_header->header_items[esp_mail_rfc822_header_field_bcc].c_str(); + flags = rfc822_header->header_items[esp_mail_rfc822_header_field_flags].c_str(); + text.charSet = ""; + text.content_type = ""; + text.transfer_encoding = ""; + html.charSet = ""; + html.content_type = ""; + html.transfer_encoding = ""; + } +}; + +struct esp_mail_imap_msg_list_t +{ + /* The info of a message */ + _vectorImpl msgItems; +}; + +struct esp_mail_imap_multipart_level_t +{ + uint8_t level = 0; + bool fetch_rfc822_header = false; + bool append_body_text = false; +}; + +struct esp_mail_imap_response_data +{ +public: + esp_mail_imap_response_status imapResp = esp_mail_imap_resp_unknown; + char *response = nullptr; + int readLen = 0; + long dataTime = millis(); + int chunkBufSize = 512; + int chunkIdx = 0; + bool isUntaggedResponse = false; + bool untaggedRespCompleted = false; + bool completedResponse = false; + bool endSearch = false; + struct esp_mail_message_header_t header; + struct esp_mail_message_part_info_t part; + MB_String filePath; + bool downloadRequest = false; + int octetCount = 0; + int octetLength = 0; + bool tmo = false; + int headerState = 0; + int searchCount = 0; + char *lastBuf = nullptr; + char *buf = nullptr; + + esp_mail_imap_response_data(int bufLen) { chunkBufSize = bufLen; }; + ~esp_mail_imap_response_data() { clear(); } + void clear() + { + if (response) + free(response); + if (lastBuf) + free(lastBuf); + if (buf) + free(buf); + + response = nullptr; + lastBuf = nullptr; + buf = nullptr; + } +}; + +#endif + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + +struct esp_mail_link_internal_t +{ + MB_String cid; +}; + +struct esp_mail_sesson_cert_config_t +{ + /* The certificate data (base64 data) */ + const char *cert_data = NULL; + + /* The certificate file (DER format) */ + MB_String cert_file; + + /* The storage type */ + esp_mail_file_storage_type cert_file_storage_type; + + /* The cerificate verification option */ + bool verify = false; +}; + +struct esp_mail_smtp_logs_config_t +{ + + /* The log file path */ + MB_String filename; + + /* The storage type */ + esp_mail_file_storage_type storage_type; +}; + +struct esp_mail_sesson_sever_config_t +{ + /* The hostName of the server */ + MB_String host_name; + /* The port on the server to connect to */ + uint16_t port = 0; +}; + +/* The log in credentials */ +struct esp_mail_sesson_login_config_t +{ + /* The user Email address to log in */ + MB_String email; + + /* The user password to log in */ + MB_String password; + + /* The OAuth2.0 access token to log in */ + MB_String accessToken; + + /* The host name or public IP of client system */ + MB_String user_domain; +}; + +/* The device time config */ +struct esp_mail_sesson_time_config_t +{ + /* set the NTP servers (use comma to separate the servers) to let the library to set the time from NTP server */ + MB_String ntp_server; + + /* the GMT offset or time zone */ + float gmt_offset = 0; + + /* the day light saving offset */ + float day_light_offset = 0; + + /** TZ environment variable for local time setting + * See https://github.com/nayarsystems/posix_tz_db/blob/master/zones.csv + */ + MB_String timezone_env_string; + + /* the file path to store TZ environment variable */ + MB_String timezone_file = "/tze.txt"; +}; + +struct esp_mail_sesson_secure_config_t +{ + /** The option (obsoleted) to send the SMTP and IMAP commands to start the TLS connection rfc2595 section 3 and rfc3207 */ + bool startTLS = false; + + /* The secure connection mode preference */ + esp_mail_secure_mode mode = esp_mail_secure_mode_undefined; +}; + +struct esp_mail_spi_ethernet_module_t +{ +#if defined(ESP8266) && defined(ESP8266_CORE_SDK_V3_X_X) +#ifdef INC_ENC28J60_LWIP + ENC28J60lwIP *enc28j60 = nullptr; +#endif +#ifdef INC_W5100_LWIP + Wiznet5100lwIP *w5100 = nullptr; +#endif +#ifdef INC_W5500_LWIP + Wiznet5500lwIP *w5500 = nullptr; +#endif +#elif defined(MB_ARDUINO_PICO) + +#endif +}; + +struct esp_mail_session_config_t +{ + friend class IMAPSession; + friend class SMTPSession; + friend class ESP_Mail_Client; + + /* The server config */ + struct esp_mail_sesson_sever_config_t server; + + /* The log in config */ + struct esp_mail_sesson_login_config_t login; + + /* The device time config */ + struct esp_mail_sesson_time_config_t time; + + /* The secure config */ + struct esp_mail_sesson_secure_config_t secure; + + /* The certificate config */ + struct esp_mail_sesson_cert_config_t certificate; + + /* SPI Ethernet Module config for ESP8266 */ + struct esp_mail_spi_ethernet_module_t spi_ethernet_module; + + /* The callback function for WiFi connection */ + NetworkConnectionHandler network_connection_handler = NULL; + + /* specific ports and its protocols */ + struct esp_mail_ports_functions ports_functions; + + /* The mail sending logs config */ + struct esp_mail_smtp_logs_config_t sentLogs; + +public: + esp_mail_session_config_t(){}; + + ~esp_mail_session_config_t() + { + clear(); + aremovePtr(); + } + + void addPtr(_vectorImpl *listPtr, int ptr) + { + if (listPtr) + { + this->listPtr = listPtr; + bool existed = false; + + for (size_t i = 0; i < this->listPtr->size(); i++) + { + if ((*this->listPtr)[i] == ptr) + existed = true; + } + + if (!existed) + this->listPtr->push_back(ptr); + } + } + + void aremovePtr() + { + if (listPtr) + { + int ptr = toAddr(*this); + for (size_t i = 0; i < listPtr->size(); i++) + { + if ((*listPtr)[i] == ptr) + { + listPtr->erase(listPtr->begin() + i, listPtr->begin() + i + 1); + break; + } + } + } + } + + void clear() + { + server.host_name.clear(); + server.port = 0; + + secure.startTLS = false; + secure.mode = esp_mail_secure_mode_undefined; + + login.email.clear(); + login.password.clear(); + login.user_domain.clear(); + login.accessToken.clear(); + + time.day_light_offset = 0; + time.gmt_offset = 0; + time.ntp_server.clear(); + time.timezone_env_string.clear(); + + certificate.cert_data = ""; + certificate.cert_file = ""; + certificate.cert_file_storage_type = esp_mail_file_storage_type_none; + certificate.verify = false; + + clearPorts(); + } + +private: + int cert_ptr = 0; + bool cert_updated = false; + _vectorImpl *listPtr = nullptr; + + // Internal flags use to keep user sercure.startTLS and secure.mode. + bool int_start_tls = false; + esp_mail_secure_mode int_mode = esp_mail_secure_mode_undefined; + + void clearPorts() + { + if (ports_functions.list) + { + if (ports_functions.use_internal_list) + { + ports_functions.size = 0; + ports_functions.use_internal_list = false; + delete[] ports_functions.list; + ports_functions.list = nullptr; + } + } + } +}; + +/** The content transfer encoding + * enc_7bit or "7bit" + * enc_qp or "quoted-printable" + * enc_base64 or "base64" + * enc_binary or "binary" + * enc_8bit or "8bit" + */ +typedef struct esp_mail_transfer_encoding_t Content_Transfer_Encoding; + +/* The session configuations */ +typedef struct esp_mail_session_config_t ESP_Mail_Session; // obsoleted +typedef struct esp_mail_session_config_t Session_Config; + +#endif + +#if defined(ENABLE_SMTP) +/* The result from sending the Email */ +typedef struct esp_mail_smtp_send_status_t SMTP_Result; + +/* The attachment details for sending the Email */ +typedef struct esp_mail_attachment_t SMTP_Attachment; +#endif + +#if defined(ENABLE_SMTP) && defined(ENABLE_IMAP) + +typedef struct esp_mail_attachment_t ESP_Mail_Attachment; + +#endif + +#if defined(ENABLE_IMAP) +/* The info of the selected or open mailbox folder e.g. name, attributes and + * delimiter */ +typedef struct esp_mail_folder_info_item_t FolderInfo; +/* The attachment item details for a message which returned from fetching the + * Email */ +typedef struct esp_mail_attachment_info_t IMAP_Attach_Item; + +/** The IMAP operation configuations */ +typedef struct esp_mail_imap_data_config_t IMAP_Config; // obsoleted + +typedef struct esp_mail_imap_data_config_t IMAP_Data; + +/* The message item data of the IMAP_MSG_List which contains header, body and + * attachments info for eacch message*/ +typedef struct esp_mail_imap_msg_item_t IMAP_MSG_Item; + +/* The list that contains the message items from searching or fetching the Email + */ +typedef struct esp_mail_imap_msg_list_t IMAP_MSG_List; + +#endif + +struct esp_mail_wifi_credential_t +{ + MB_String ssid; + MB_String password; +}; + +struct esp_mail_wifi_credentials_t +{ + friend class ESP_Mail_Client; + friend class ESP_Mail_TCPClient; + +public: + esp_mail_wifi_credentials_t(){}; + ~esp_mail_wifi_credentials_t() + { + clearAP(); + clearMulti(); + }; + void addAP(const String &ssid, const String &password) + { + esp_mail_wifi_credential_t cred; + cred.ssid = ssid; + cred.password = password; + credentials.push_back(cred); + } + void clearAP() + { + credentials.clear(); + } + +private: + _vectorImpl credentials; +#if defined(ESP_MAIL_HAS_WIFIMULTI) + WiFiMulti *multi = nullptr; +#endif + + void reconnect() + { + if (credentials.size()) + { + disconnect(); + connect(); + } + } + + void connect() + { +#if defined(ESP_MAIL_HAS_WIFIMULTI) + + clearMulti(); + multi = new WiFiMulti(); + for (size_t i = 0; i < credentials.size(); i++) + multi->addAP(credentials[i].ssid.c_str(), credentials[i].password.c_str()); + + if (credentials.size() > 0) + multi->run(); + +#elif defined(ESP_MAIL_WIFI_IS_AVAILABLE) + WiFi.begin((CONST_STRING_CAST)credentials[0].ssid.c_str(), credentials[0].password.c_str()); +#endif + } + + void disconnect() + { +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) + WiFi.disconnect(); +#endif + } + + void clearMulti() + { +#if defined(ESP_MAIL_HAS_WIFIMULTI) + if (multi) + delete multi; + multi = nullptr; +#endif + } +}; + +static const char esp_mail_imap_tag_str[] PROGMEM = "xmail"; + +#if !defined(SILENT_MODE) +static const char esp_mail_version_str[] PROGMEM = "ESP Mail Client v"; + +///////////////////////// +// SMTP debug string + +static const char esp_mail_dbg_str_1[] PROGMEM = "send command, STARTTLS"; +static const char esp_mail_dbg_str_2[] PROGMEM = "connecting to SMTP server"; + +#if defined(ENABLE_SMTP) +static const char esp_mail_dbg_str_3[] PROGMEM = "send Email"; +static const char esp_mail_dbg_str_4[] PROGMEM = "SMTP server connected"; +static const char esp_mail_dbg_str_5[] PROGMEM = "send SMTP command, EHLO"; +static const char esp_mail_dbg_str_6[] PROGMEM = "send SMTP command, AUTH LOGIN"; +static const char esp_mail_dbg_str_7[] PROGMEM = "send SMTP command, AUTH PLAIN"; +static const char esp_mail_dbg_str_8[] PROGMEM = "send message header"; +static const char esp_mail_dbg_str_9[] PROGMEM = "send message body"; +static const char esp_mail_dbg_str_10[] PROGMEM = "send attachments"; +static const char esp_mail_dbg_str_11[] PROGMEM = "terminate the SMTP session"; +static const char esp_mail_dbg_str_12[] PROGMEM = "message sent successfully"; +static const char esp_mail_dbg_str_13[] PROGMEM = "send next Email"; +static const char esp_mail_dbg_str_14[] PROGMEM = "send inline data"; +static const char esp_mail_dbg_str_15[] PROGMEM = "send smtp command, AUTH XOAUTH2"; +static const char esp_mail_dbg_str_16[] PROGMEM = "finishing the message sending"; +static const char esp_mail_dbg_str_17[] PROGMEM = "No ESMTP supported, send SMTP command, HELO"; +#endif + +///////////////////////// +// IMAP debug string +static const char esp_mail_dbg_str_18[] PROGMEM = "connecting to IMAP server"; +static const char esp_mail_dbg_str_19[] PROGMEM = "Host > "; +static const char esp_mail_dbg_str_20[] PROGMEM = "Port > "; +static const char esp_mail_dbg_str_21[] PROGMEM = "Reading time from NTP server"; +static const char esp_mail_dbg_str_22[] PROGMEM = "perform SSL/TLS handshake"; + +#if defined(ENABLE_IMAP) +static const char esp_mail_dbg_str_23[] PROGMEM = "get my ACL"; +static const char esp_mail_dbg_str_24[] PROGMEM = "checking the capability"; +static const char esp_mail_dbg_str_25[] PROGMEM = "fetching message "; +static const char esp_mail_dbg_str_26[] PROGMEM = "fetch message header"; +static const char esp_mail_dbg_str_27[] PROGMEM = "fetch body part header, "; +static const char esp_mail_dbg_str_28[] PROGMEM = "fetch body sub part header, "; +static const char esp_mail_dbg_str_29[] PROGMEM = "finished reading Email"; +static const char esp_mail_dbg_str_30[] PROGMEM = "UID is "; +static const char esp_mail_dbg_str_31[] PROGMEM = "log out completed"; +static const char esp_mail_dbg_str_32[] PROGMEM = "closing the "; +static const char esp_mail_dbg_str_33[] PROGMEM = "IMAP server connected"; +static const char esp_mail_dbg_str_34[] PROGMEM = "send IMAP command, LOGIN"; +static const char esp_mail_dbg_str_35[] PROGMEM = "send IMAP command, LIST"; +static const char esp_mail_dbg_str_36[] PROGMEM = "searching messages"; +static const char esp_mail_dbg_str_37[] PROGMEM = "send IMAP command, FETCH"; +static const char esp_mail_dbg_str_38[] PROGMEM = "send IMAP command, LOGOUT"; +static const char esp_mail_dbg_str_39[] PROGMEM = "message fetching completed"; +static const char esp_mail_dbg_str_40[] PROGMEM = "opening the mailbox folder"; +static const char esp_mail_dbg_str_41[] PROGMEM = "setting FLAG"; +static const char esp_mail_dbg_str_42[] PROGMEM = "adding FLAG"; +static const char esp_mail_dbg_str_43[] PROGMEM = "removing FLAG"; +static const char esp_mail_dbg_str_44[] PROGMEM = "send IMAP command, AUTHENTICATE PLAIN"; +static const char esp_mail_dbg_str_45[] PROGMEM = "send IMAP command, AUTH XOAUTH2"; +static const char esp_mail_dbg_str_46[] PROGMEM = "reading plain TEXT message"; +static const char esp_mail_dbg_str_47[] PROGMEM = "reading HTML message"; +static const char esp_mail_dbg_str_48[] PROGMEM = "copying message(s) to "; +static const char esp_mail_dbg_str_49[] PROGMEM = "creating folder"; +static const char esp_mail_dbg_str_50[] PROGMEM = "deleting folder"; +static const char esp_mail_dbg_str_51[] PROGMEM = "listening to "; +static const char esp_mail_dbg_str_52[] PROGMEM = " folder changes"; +static const char esp_mail_dbg_str_53[] PROGMEM = "polling established"; +static const char esp_mail_dbg_str_54[] PROGMEM = "Mailbox listening stopped"; +static const char esp_mail_dbg_str_55[] PROGMEM = "renaming folder"; +static const char esp_mail_dbg_str_56[] PROGMEM = "send IMAP command, LSUB"; +static const char esp_mail_dbg_str_57[] PROGMEM = "send IMAP command, SUBSCRIBE"; +static const char esp_mail_dbg_str_58[] PROGMEM = "send IMAP command, UNSUBSCRIBE"; +static const char esp_mail_dbg_str_59[] PROGMEM = "moving message(s) to "; +static const char esp_mail_dbg_str_60[] PROGMEM = "send IMAP command, GETQUOTA"; +static const char esp_mail_dbg_str_61[] PROGMEM = "send IMAP command, SETQUOTA"; +static const char esp_mail_dbg_str_62[] PROGMEM = "send IMAP command, GETQUOTAROOT"; +static const char esp_mail_dbg_str_63[] PROGMEM = "send IMAP command, GETACL"; +static const char esp_mail_dbg_str_64[] PROGMEM = "send IMAP command, SETACL"; +static const char esp_mail_dbg_str_65[] PROGMEM = "send IMAP command, DELETEACL"; +static const char esp_mail_dbg_str_66[] PROGMEM = "send IMAP command, MYRIGHTS"; +static const char esp_mail_dbg_str_67[] PROGMEM = "send IMAP command, NAMESPACE"; +static const char esp_mail_dbg_str_68[] PROGMEM = "selecting the "; +static const char esp_mail_dbg_str_69[] PROGMEM = "appending message"; +static const char esp_mail_dbg_str_70[] PROGMEM = "download attachment %d of %d"; +static const char esp_mail_dbg_str_71[] PROGMEM = "download HTML message"; +static const char esp_mail_dbg_str_72[] PROGMEM = "deleting the ACL"; +static const char esp_mail_dbg_str_73[] PROGMEM = "message append successfully"; +static const char esp_mail_dbg_str_74[] PROGMEM = "download plain TEXT message"; +static const char esp_mail_dbg_str_75[] PROGMEM = "deleting message(s)"; +static const char esp_mail_dbg_str_76[] PROGMEM = "check the capability"; +static const char esp_mail_dbg_str_77[] PROGMEM = "get the ACL"; +static const char esp_mail_dbg_str_78[] PROGMEM = "set the ACL"; +static const char esp_mail_dbg_str_79[] PROGMEM = "get UID"; +static const char esp_mail_dbg_str_80[] PROGMEM = "get Flags"; +static const char esp_mail_dbg_str_81[] PROGMEM = "delete folder"; +static const char esp_mail_dbg_str_82[] PROGMEM = "send IMAP command, ID"; +static const char esp_mail_dbg_str_83[] PROGMEM = "send IMAP command, NOOP"; +#endif + +///////////////////////// +// SMTP callback string + +static const char esp_mail_cb_str_1[] PROGMEM = "Connecting to SMTP server..."; +static const char esp_mail_cb_str_2[] PROGMEM = "Sending STARTTLS command..."; + +#if defined(ENABLE_SMTP) +static const char esp_mail_cb_str_3[] PROGMEM = "Sending greeting response..."; +static const char esp_mail_cb_str_4[] PROGMEM = "Sending message header..."; +static const char esp_mail_cb_str_5[] PROGMEM = "Sending message body..."; +static const char esp_mail_cb_str_6[] PROGMEM = "Sending attachments..."; +static const char esp_mail_cb_str_7[] PROGMEM = "Closing the session..."; +static const char esp_mail_cb_str_8[] PROGMEM = "Sending inline data..."; +static const char esp_mail_cb_str_9[] PROGMEM = "Sending Email..."; +static const char esp_mail_cb_str_10[] PROGMEM = "Sending next Email..."; +static const char esp_mail_cb_str_11[] PROGMEM = "Finishing the message sending..."; +static const char esp_mail_cb_str_12[] PROGMEM = "SMTP server connected, wait for greeting..."; +static const char esp_mail_cb_str_13[] PROGMEM = "Message sent successfully"; +#endif + +///////////////////////// +// IMAP callback string + +static const char esp_mail_cb_str_14[] PROGMEM = "Logging in..."; // shared with SMTP +static const char esp_mail_cb_str_15[] PROGMEM = "Connecting to IMAP server..."; + +#if defined(ENABLE_IMAP) + +static const char esp_mail_cb_str_16[] PROGMEM = "Reading the list of mailboxes..."; +static const char esp_mail_cb_str_17[] PROGMEM = "Checking the capability..."; +static const char esp_mail_cb_str_18[] PROGMEM = "Searching messages..."; +static const char esp_mail_cb_str_19[] PROGMEM = "Downloading attachments..."; +static const char esp_mail_cb_str_20[] PROGMEM = "Logging out..."; +static const char esp_mail_cb_str_21[] PROGMEM = "Saving message header to file..."; +static const char esp_mail_cb_str_22[] PROGMEM = "Get FLAG..."; +static const char esp_mail_cb_str_23[] PROGMEM = "Removing FLAG..."; +static const char esp_mail_cb_str_24[] PROGMEM = "Adding FLAG..."; +static const char esp_mail_cb_str_25[] PROGMEM = "Get UID..."; +static const char esp_mail_cb_str_26[] PROGMEM = "Setting FLAG..."; +static const char esp_mail_cb_str_27[] PROGMEM = "Closing the mailbox folder..."; +static const char esp_mail_cb_str_28[] PROGMEM = "Reading messages..."; +static const char esp_mail_cb_str_29[] PROGMEM = "Listening to mailbox changes..."; +static const char esp_mail_cb_str_30[] PROGMEM = "Listing the subscribed mailboxes..."; +static const char esp_mail_cb_str_31[] PROGMEM = "Subscribe mailbox..."; +static const char esp_mail_cb_str_32[] PROGMEM = "Unsubscribe mailbox..."; +static const char esp_mail_cb_str_33[] PROGMEM = "Get quota root resource usage and limit..."; +static const char esp_mail_cb_str_34[] PROGMEM = "Set quota root resource usage and limit..."; +static const char esp_mail_cb_str_35[] PROGMEM = "Get the list of quota roots..."; +static const char esp_mail_cb_str_36[] PROGMEM = "Get the ACL..."; +static const char esp_mail_cb_str_37[] PROGMEM = "Setting the ACL..."; +static const char esp_mail_cb_str_38[] PROGMEM = "Deleting the ACL..."; +static const char esp_mail_cb_str_39[] PROGMEM = "Get my ACL..."; +static const char esp_mail_cb_str_40[] PROGMEM = "Get namespace..."; +static const char esp_mail_cb_str_41[] PROGMEM = "Enable capability..."; +static const char esp_mail_cb_str_42[] PROGMEM = "Updating firmware..."; +static const char esp_mail_cb_str_43[] PROGMEM = "Downloading messages..."; +static const char esp_mail_cb_str_44[] PROGMEM = "Appending message..."; +static const char esp_mail_cb_str_45[] PROGMEM = "Message append successfully"; +static const char esp_mail_cb_str_46[] PROGMEM = "Finished reading Email"; +static const char esp_mail_cb_str_47[] PROGMEM = "Log out completed"; +static const char esp_mail_cb_str_48[] PROGMEM = "IMAP server connected"; +static const char esp_mail_cb_str_49[] PROGMEM = "Polling established"; +static const char esp_mail_cb_str_50[] PROGMEM = "Mailbox listening stopped"; +static const char esp_mail_cb_str_51[] PROGMEM = "Open the mailbox folder..."; +static const char esp_mail_cb_str_52[] PROGMEM = "Checking the capability..."; +static const char esp_mail_cb_str_53[] PROGMEM = "Renaming folder..."; +static const char esp_mail_cb_str_54[] PROGMEM = "UID is "; +static const char esp_mail_cb_str_55[] PROGMEM = "Get Flags..."; +static const char esp_mail_cb_str_56[] PROGMEM = "Deleting folder..."; +static const char esp_mail_cb_str_57[] PROGMEM = "Deleting message(s)..."; +static const char esp_mail_cb_str_58[] PROGMEM = "Copying message(s)..."; +static const char esp_mail_cb_str_59[] PROGMEM = "Creating folder..."; +static const char esp_mail_cb_str_60[] PROGMEM = "Moving message(s)..."; +static const char esp_mail_cb_str_61[] PROGMEM = "Send client identification..."; +static const char esp_mail_cb_str_62[] PROGMEM = "Send noop..."; +#endif + +#endif + +///////////////////////// +// Mem error string + +#if defined(ENABLE_ERROR_STRING) || !defined(SILENT_MODE) +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) +static const char esp_mail_error_mem_str_1[] PROGMEM = "flash Storage is not ready."; +static const char esp_mail_error_mem_str_2[] PROGMEM = "SD Storage is not ready."; +static const char esp_mail_error_mem_str_3[] PROGMEM = "file does not exist or can't access"; +#endif +static const char esp_mail_error_mem_str_4[] PROGMEM = "PSRAM was enabled but not detected."; +#endif + +#if defined(ENABLE_ERROR_STRING) + +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) +static const char esp_mail_error_mem_str_5[] PROGMEM = "file is still opened."; +static const char esp_mail_error_mem_str_6[] PROGMEM = "file not found."; +static const char esp_mail_error_mem_str_7[] PROGMEM = "file I/O error"; +#endif + +static const char esp_mail_error_mem_str_8[] PROGMEM = "out of memory"; +static const char esp_mail_error_mem_str_9[] PROGMEM = "buffer overflow"; + +#endif + +#if defined(MB_ARDUINO_PICO) +#if defined(ENABLE_ERROR_STRING) || !defined(SILENT_MODE) +static const char esp_mail_error_mem_str_10[] PROGMEM = "please make sure that the size of flash filesystem is not 0 in Pico."; +#endif +#endif + +///////////////////////// +// Client error string + +#if !defined(SILENT_MODE) +static const char esp_mail_error_client_str_1[] PROGMEM = "client and/or necessary callback functions are not yet assigned"; +static const char esp_mail_error_client_str_2[] PROGMEM = "network connection callback is required"; +static const char esp_mail_error_client_str_3[] PROGMEM = "network connection status callback is required"; +static const char esp_mail_error_client_str_4[] PROGMEM = "NTP server time reading cannot begin when valid time is required because of no WiFi capability/activity detected."; +static const char esp_mail_error_client_str_5[] PROGMEM = "Please set the library reference time manually using smtp.setSystemTime or imap.setSystemTime."; +#endif + +///////////////////////// +// Network error string + +#if !defined(SILENT_MODE) +static const char esp_mail_error_network_str_1[] PROGMEM = "unable to connect to server"; +#if defined(ENABLE_ERROR_STRING) +static const char esp_mail_error_network_str_2[] PROGMEM = "NTP server time reading timed out"; +static const char esp_mail_error_network_str_3[] PROGMEM = "response read timed out"; +static const char esp_mail_error_network_str_4[] PROGMEM = "not connected"; +static const char esp_mail_error_network_str_5[] PROGMEM = "connection timeout"; +static const char esp_mail_error_network_str_6[] PROGMEM = "connection closed"; +static const char esp_mail_error_network_str_7[] PROGMEM = "connection refused"; +static const char esp_mail_error_network_str_8[] PROGMEM = "data sending failed"; +#endif +#endif + +#if defined(ENABLE_ERROR_STRING) || !defined(SILENT_MODE) +static const char esp_mail_error_network_str_9[] PROGMEM = "response read timed out"; +#endif + +///////////////////////// +// SSL error string + +#if defined(ENABLE_ERROR_STRING) +static const char esp_mail_error_ssl_str_1[] PROGMEM = "fail to set up the SSL/TLS structure"; +#endif +#if defined(ENABLE_ERROR_STRING) || !defined(SILENT_MODE) +static const char esp_mail_error_ssl_str_2[] PROGMEM = "the alert SSL record received"; +static const char esp_mail_error_ssl_str_3[] PROGMEM = "make sure the SSL/TLS handshake was done before sending the data"; +#endif + +///////////////////////// +// Auth error string + +#if defined(ENABLE_ERROR_STRING) +static const char esp_mail_error_auth_str_1[] PROGMEM = "the provided SASL authentication mechanism is not support"; +static const char esp_mail_error_auth_str_2[] PROGMEM = "OAuth2.0 log in was disabled for this server"; +static const char esp_mail_error_auth_str_3[] PROGMEM = "not yet log in"; +#endif + +///////////////////////// +// Session error string + +#if defined(ENABLE_ERROR_STRING) +static const char esp_mail_error_session_str_1[] PROGMEM = "the Session_Config object was not assigned"; +#endif + +///////////////////////// +// Time error string +#if defined(ENABLE_ERROR_STRING) +static const char esp_mail_error_time_str_1[] PROGMEM = "library or device time was not set, see examples/SMTP/Set_Time.ino for manually time setting"; +#endif + +///////////////////////// +// SMTP error string +#if defined(ENABLE_SMTP) +#if defined(ENABLE_ERROR_STRING) +static const char esp_mail_error_smtp_str_1[] PROGMEM = "SMTP server greeting failed"; +static const char esp_mail_error_smtp_str_2[] PROGMEM = "authentication failed"; +static const char esp_mail_error_smtp_str_3[] PROGMEM = "login password is not valid"; +static const char esp_mail_error_smtp_str_4[] PROGMEM = "send header failed"; +static const char esp_mail_error_smtp_str_5[] PROGMEM = "send body failed"; +static const char esp_mail_error_smtp_str_7[] PROGMEM = "sender Email address is not valid"; +static const char esp_mail_error_smtp_str_8[] PROGMEM = "some of the recipient Email address is not valid"; +static const char esp_mail_error_smtp_str_9[] PROGMEM = "set recipient failed"; +static const char esp_mail_error_smtp_str_10[] PROGMEM = "send custom command failed"; +static const char esp_mail_error_smtp_str_11[] PROGMEM = "XOAuth2 authenticate failed"; +static const char esp_mail_error_smtp_str_12[] PROGMEM = "undefined error"; +#endif +#endif + +///////////////////////// +// IMAP error string +#if defined(ENABLE_IMAP) +#if defined(ENABLE_ERROR_STRING) +static const char esp_mail_error_imap_str_1[] PROGMEM = "fail to list the mailboxes"; +static const char esp_mail_error_imap_str_2[] PROGMEM = "fail to check the capabilities"; + +static const char esp_mail_error_imap_str_3[] PROGMEM = "fail to close the mailbox"; + +static const char esp_mail_error_imap_str_4[] PROGMEM = "fail to open the mailbox"; +static const char esp_mail_error_imap_str_5[] PROGMEM = "some of the requested messages no longer exist"; +static const char esp_mail_error_imap_str_6[] PROGMEM = "firmware update initialization failed"; +static const char esp_mail_error_imap_str_7[] PROGMEM = "firmware update write failed"; +static const char esp_mail_error_imap_str_8[] PROGMEM = "firmware update finalize failed"; + +#endif +#if defined(ENABLE_ERROR_STRING) || !defined(SILENT_MODE) +static const char esp_mail_error_imap_str_9[] PROGMEM = "no messages found for the specified search criteria"; +static const char esp_mail_error_imap_str_10[] PROGMEM = "no search criteria provided, then fetching the latest message"; +static const char esp_mail_error_imap_str_11[] PROGMEM = "no mailbox opened"; +static const char esp_mail_error_imap_str_12[] PROGMEM = "no content"; +static const char esp_mail_error_imap_str_13[] PROGMEM = "this feature was not supported"; +static const char esp_mail_error_imap_str_14[] PROGMEM = "no message changed since (assigned) modsec"; +static const char esp_mail_error_imap_str_15[] PROGMEM = "CONDSTORE was not supported or modsec was not supported for selected mailbox"; +static const char esp_mail_error_imap_str_17[] PROGMEM = "could not parse command"; +static const char esp_mail_error_imap_str_18[] PROGMEM = "server disconnected or returned error"; +static const char esp_mail_error_imap_str_19[] PROGMEM = "authenticate failed"; +static const char esp_mail_error_imap_str_20[] PROGMEM = "flags or keywords store failed"; +static const char esp_mail_error_imap_str_21[] PROGMEM = "server is not support OAuth2 login"; +#endif +#endif + +///////////////////////// +// General use string +static const char esp_mail_str_1[] PROGMEM = "127.0.0.1"; +static const char esp_mail_str_2[] PROGMEM = " "; +static const char esp_mail_str_3[] PROGMEM = "*"; +static const char esp_mail_str_4[] PROGMEM = "High"; +static const char esp_mail_str_5[] PROGMEM = "Normal"; +static const char esp_mail_str_6[] PROGMEM = "Low"; +static const char esp_mail_str_7[] PROGMEM = "="; +static const char esp_mail_str_8[] PROGMEM = ","; +static const char esp_mail_str_9[] PROGMEM = "--"; +static const char esp_mail_str_10[] PROGMEM = "/"; +static const char esp_mail_str_11[] PROGMEM = "\""; +static const char esp_mail_str_12[] PROGMEM = "Error, "; +static const char esp_mail_str_13[] PROGMEM = "msg.txt"; +static const char esp_mail_str_14[] PROGMEM = "msg.html"; +static const char esp_mail_str_15[] PROGMEM = "flash content message"; +static const char esp_mail_str_16[] PROGMEM = "file content message"; +static const char esp_mail_str_17[] PROGMEM = "cid:"; +static const char esp_mail_str_18[] PROGMEM = "\r\n"; +static const char esp_mail_str_19[] PROGMEM = "<"; +static const char esp_mail_str_20[] PROGMEM = ">"; +static const char esp_mail_str_21[] PROGMEM = "(\"name\" \"ESP Mail Client\" \"version\" \"%s\")"; +static const char esp_mail_str_22[] PROGMEM = "message/rfc822"; +static const char esp_mail_str_23[] PROGMEM = "upload"; +static const char esp_mail_str_24[] PROGMEM = "%"; +static const char esp_mail_str_25[] PROGMEM = "status code: "; +static const char esp_mail_str_26[] PROGMEM = ", text: "; +static const char esp_mail_str_27[] PROGMEM = "."; +static const char esp_mail_str_28[] PROGMEM = "> C: "; +static const char esp_mail_str_29[] PROGMEM = "< S: "; +static const char esp_mail_str_30[] PROGMEM = "! E: "; +static const char esp_mail_str_31[] PROGMEM = "! I: "; +static const char esp_mail_str_32[] PROGMEM = "! W: "; +static const char esp_mail_str_33[] PROGMEM = "#### "; +static const char esp_mail_str_34[] PROGMEM = ":"; +static const char esp_mail_str_35[] PROGMEM = ";"; +static const char esp_mail_str_36[] PROGMEM = "{"; +static const char esp_mail_str_37[] PROGMEM = "}"; +static const char esp_mail_str_38[] PROGMEM = "("; +static const char esp_mail_str_39[] PROGMEM = ")"; +static const char esp_mail_str_40[] PROGMEM = "["; +static const char esp_mail_str_41[] PROGMEM = "]"; +static const char esp_mail_str_42[] PROGMEM = "\r\n"; +static const char esp_mail_str_43[] PROGMEM = "\1\1"; +static const char esp_mail_str_44[] PROGMEM = "{\"status\":"; +static const char esp_mail_str_45[] PROGMEM = "user="; +static const char esp_mail_str_46[] PROGMEM = "\1auth=Bearer "; +static const char esp_mail_str_47[] PROGMEM = "0123456789ABCDEF"; +static const char esp_mail_str_48[] PROGMEM = "<0.0>"; +static const char esp_mail_str_49[] PROGMEM = "<0."; +static const char esp_mail_str_50[] PROGMEM = "Search limit: %d\nFound %d messages\nShow %d messages"; +static const char esp_mail_str_51[] PROGMEM = "1.0"; +static const char esp_mail_str_52[] PROGMEM = "Fetch message %d, UID: %d"; +static const char esp_mail_str_53[] PROGMEM = "Fetch message %d, Number: %d"; +static const char esp_mail_str_54[] PROGMEM = "Attachments (%d)"; +static const char esp_mail_str_55[] PROGMEM = "Free Heap: "; +static const char esp_mail_str_56[] PROGMEM = "content-"; +static const char esp_mail_str_58[] PROGMEM = "format=\"flowed\""; +static const char esp_mail_str_59[] PROGMEM = "format=flowed"; +static const char esp_mail_str_60[] PROGMEM = "delsp=\"yes\""; +static const char esp_mail_str_61[] PROGMEM = "delsp=yes"; +static const char esp_mail_str_62[] PROGMEM = "name"; +static const char esp_mail_str_63[] PROGMEM = "+ "; +static const char esp_mail_str_64[] PROGMEM = "boundary=\""; +static const char esp_mail_str_65[] PROGMEM = "/header.json"; +static const char esp_mail_str_66[] PROGMEM = "/header.txt"; +static const char esp_mail_str_67[] PROGMEM = "{\"Filename\":\""; +static const char esp_mail_str_68[] PROGMEM = "Index: "; +static const char esp_mail_str_69[] PROGMEM = ",\"RFC822\":"; +static const char esp_mail_str_70[] PROGMEM = "\r\n\r\nRFC822:\r\n"; +static const char esp_mail_str_71[] PROGMEM = ",\"Attachments\":{\"Count\":"; +static const char esp_mail_str_72[] PROGMEM = ",\"Files\":["; +static const char esp_mail_str_73[] PROGMEM = "\r\n\r\nAttachments ("; +static const char esp_mail_str_74[] PROGMEM = ")\r\n"; +static const char esp_mail_str_75[] PROGMEM = "]}"; +static const char esp_mail_str_76[] PROGMEM = "{\"Messages\":["; +static const char esp_mail_str_77[] PROGMEM = ",\""; +static const char esp_mail_str_78[] PROGMEM = "{\""; +static const char esp_mail_str_79[] PROGMEM = "\":\""; +static const char esp_mail_str_80[] PROGMEM = "{\"Renamed\":\""; +static const char esp_mail_str_81[] PROGMEM = "\",\"Original\":\""; +static const char esp_mail_str_82[] PROGMEM = "\"}]"; +static const char esp_mail_str_83[] PROGMEM = "_"; +static const char esp_mail_str_84[] PROGMEM = "message"; +static const char esp_mail_str_85[] PROGMEM = "rfc822"; +static const char esp_mail_str_86[] PROGMEM = "/msg"; +static const char esp_mail_str_87[] PROGMEM = "/rfc822_msg"; +static const char esp_mail_str_88[] PROGMEM = "polling established on "; +static const char esp_mail_str_89[] PROGMEM = " folder..."; +static const char esp_mail_str_90[] PROGMEM = "boundary"; +static const char esp_mail_str_91[] PROGMEM = "\\Deleted"; +static const char esp_mail_str_92[] PROGMEM = "Subject: %s"; +static const char esp_mail_str_93[] PROGMEM = "Message sent success: %d"; +static const char esp_mail_str_94[] PROGMEM = "Message sent failed: %d"; +static const char esp_mail_str_95[] PROGMEM = "Status: %s"; +static const char esp_mail_str_96[] PROGMEM = "Date/Time: %s"; +static const char esp_mail_str_97[] PROGMEM = "Recipient: %s"; +static const char esp_mail_str_98[] PROGMEM = "success"; +static const char esp_mail_str_99[] PROGMEM = "failed"; + +#if defined(ENABLE_SMTP) +static const char boundary_table[] PROGMEM = "=_abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; +#endif + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + +static const unsigned char b64_index_table[65] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + +static void __attribute__((used)) +appendDebugTag(MB_String &buf, esp_mail_debug_tag_type type, bool clear, PGM_P text = NULL) +{ + if (clear) + buf.clear(); + + switch (type) + { + case esp_mail_debug_tag_type_client: + buf += esp_mail_str_28; /* "> C: "*/ + break; + case esp_mail_debug_tag_type_server: + buf += esp_mail_str_29; /* "< S: " */ + break; + case esp_mail_debug_tag_type_error: + buf += esp_mail_str_30; /* "! E: "*/ + break; + case esp_mail_debug_tag_type_info: + buf += esp_mail_str_31; /* "! I: "*/ + break; + case esp_mail_debug_tag_type_warning: + buf += esp_mail_str_32; /* "! W: "*/ + break; + default: + break; + } + + if (text != NULL) + buf += text; +} + +static void __attribute__((used)) +yield_impl() +{ +#if defined(ARDUINO_ESP8266_MAJOR) && defined(ARDUINO_ESP8266_MINOR) && defined(ARDUINO_ESP8266_REVISION) && ((ARDUINO_ESP8266_MAJOR == 3 && ARDUINO_ESP8266_MINOR >= 1) || ARDUINO_ESP8266_MAJOR > 3) + esp_yield(); +#else + delay(0); +#endif +} + +// Print debug message w/wo new line to debug port +static void __attribute__((used)) +esp_mail_debug_print(PGM_P msg = "", bool newLine = true) +{ + yield_impl(); + if (newLine) + ESP_MAIL_DEFAULT_DEBUG_PORT.println(msg); + else + ESP_MAIL_DEFAULT_DEBUG_PORT.print(msg); +} + +static void __attribute__((used)) +esp_mail_debug_print_tag(PGM_P msg, esp_mail_debug_tag_type type, bool newLine = true, bool showTag = true) +{ + yield_impl(); + + MB_String s; + if (showTag) + appendDebugTag(s, type, false, msg); + else + s = msg; + + if (newLine) + ESP_MAIL_DEFAULT_DEBUG_PORT.println(s.c_str()); + else + ESP_MAIL_DEFAULT_DEBUG_PORT.print(s.c_str()); +} + +#endif + +typedef void (*ConnectionUpgradeRequestCallback)(void); +typedef void (*NetworkConnectionRequestCallback)(void); +typedef void (*NetworkDisconnectionRequestCallback)(void); +typedef void (*NetworkStatusRequestCallback)(void); +// Optional +typedef void (*ConnectionRequestCallback)(const char *, int); #endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Error.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Error.h index 172e7f8d4..726e41505 100644 --- a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Error.h +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_Error.h @@ -1,86 +1,86 @@ -/** - * Created August 6, 2023 - */ -#pragma once - -#ifndef ESP_MAIL_ERROR_H -#define ESP_MAIL_ERROR_H - -#include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30409) -#error "Mixed versions compilation." -#endif - -#define TCP_CLIENT_ERROR_CONNECTION_REFUSED -1 -#define TCP_CLIENT_ERROR_SEND_DATA_FAILED -2 -#define TCP_CLIENT_ERROR_NOT_INITIALIZED -3 -#define TCP_CLIENT_ERROR_NOT_CONNECTED -4 - -#if defined(ENABLE_SMTP) - -#define SMTP_STATUS_SERVER_CONNECT_FAILED -100 -#define SMTP_STATUS_SMTP_GREETING_GET_RESPONSE_FAILED -101 -#define SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED -102 -#define SMTP_STATUS_AUTHEN_NOT_SUPPORT -103 -#define SMTP_STATUS_AUTHEN_FAILED -104 -#define SMTP_STATUS_USER_LOGIN_FAILED -105 -#define SMTP_STATUS_PASSWORD_LOGIN_FAILED -106 -#define SMTP_STATUS_SEND_HEADER_SENDER_FAILED -107 -#define SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED -108 -#define SMTP_STATUS_SEND_BODY_FAILED -109 -#define SMTP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED -110 -#define SMTP_STATUS_NO_VALID_RECIPIENTS_EXISTED -111 -#define SMTP_STATUS_NO_VALID_SENDER_EXISTED -112 -#define SMTP_STATUS_NO_SUPPORTED_AUTH -113 -#define SMTP_STATUS_SEND_CUSTOM_COMMAND_FAILED -114 -#define SMTP_STATUS_XOAUTH2_AUTH_FAILED -115 -#define SMTP_STATUS_UNDEFINED -116 -#endif - -#if defined(ENABLE_IMAP) - -#define IMAP_STATUS_SERVER_CONNECT_FAILED -200 -#define IMAP_STATUS_IMAP_RESPONSE_FAILED -201 -#define IMAP_STATUS_AUTHENTICATE_FAILED -202 -#define IMAP_STATUS_BAD_COMMAND -203 -#define IMAP_STATUS_STORE_FAILED -204 -#define IMAP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED -205 -#define IMAP_STATUS_NO_MESSAGE -206 -#define IMAP_STATUS_ERROR_DOWNLAD_TIMEOUT -207 -#define IMAP_STATUS_CLOSE_MAILBOX_FAILED -208 -#define IMAP_STATUS_OPEN_MAILBOX_FAILED -209 -#define IMAP_STATUS_LIST_MAILBOXS_FAILED -210 -#define IMAP_STATUS_CHECK_CAPABILITIES_FAILED -211 -#define IMAP_STATUS_NO_SUPPORTED_AUTH -212 -#define IMAP_STATUS_NO_MAILBOX_FOLDER_OPENED -213 -#define IMAP_STATUS_FIRMWARE_UPDATE_INIT_FAILED -214 -#define IMAP_STATUS_FIRMWARE_UPDATE_WRITE_FAILED -215 -#define IMAP_STATUS_FIRMWARE_UPDATE_END_FAILED -216 -#define IMAP_STATUS_CHANGEDSINC_MODSEQ_TEST_FAILED -217 -#define IMAP_STATUS_MODSEQ_WAS_NOT_SUPPORTED -218 -#endif - -/** - * MB_FS.h - #define MB_FS_ERROR_FILE_IO_ERROR -300 - #define MB_FS_ERROR_FILE_NOT_FOUND -301 - #define MB_FS_ERROR_FLASH_STORAGE_IS_NOT_READY -302 - #define MB_FS_ERROR_SD_STORAGE_IS_NOT_READY -303 - #define MB_FS_ERROR_FILE_STILL_OPENED -304 -*/ - -#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) - -#define MAIL_CLIENT_ERROR_CONNECTION_CLOSED -400 -#define MAIL_CLIENT_ERROR_READ_TIMEOUT -401 -#define MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP -402 -#define MAIL_CLIENT_ERROR_OUT_OF_MEMORY -403 -#define MAIL_CLIENT_ERROR_NTP_TIME_SYNC_TIMED_OUT -404 -#define MAIL_CLIENT_ERROR_SESSION_CONFIG_WAS_NOT_ASSIGNED -405 -#define MAIL_CLIENT_ERROR_TIME_WAS_NOT_SET -406 -#define MAIL_CLIENT_ERROR_NOT_YET_LOGIN -407 -#define MAIL_CLIENT_ERROR_BUFFER_OVERFLOW -408 - -#endif - +/** + * Created August 6, 2023 + */ +#pragma once + +#ifndef ESP_MAIL_ERROR_H +#define ESP_MAIL_ERROR_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +#define TCP_CLIENT_ERROR_CONNECTION_REFUSED -1 +#define TCP_CLIENT_ERROR_SEND_DATA_FAILED -2 +#define TCP_CLIENT_ERROR_NOT_INITIALIZED -3 +#define TCP_CLIENT_ERROR_NOT_CONNECTED -4 + +#if defined(ENABLE_SMTP) + +#define SMTP_STATUS_SERVER_CONNECT_FAILED -100 +#define SMTP_STATUS_SMTP_GREETING_GET_RESPONSE_FAILED -101 +#define SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED -102 +#define SMTP_STATUS_AUTHEN_NOT_SUPPORT -103 +#define SMTP_STATUS_AUTHEN_FAILED -104 +#define SMTP_STATUS_USER_LOGIN_FAILED -105 +#define SMTP_STATUS_PASSWORD_LOGIN_FAILED -106 +#define SMTP_STATUS_SEND_HEADER_SENDER_FAILED -107 +#define SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED -108 +#define SMTP_STATUS_SEND_BODY_FAILED -109 +#define SMTP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED -110 +#define SMTP_STATUS_NO_VALID_RECIPIENTS_EXISTED -111 +#define SMTP_STATUS_NO_VALID_SENDER_EXISTED -112 +#define SMTP_STATUS_NO_SUPPORTED_AUTH -113 +#define SMTP_STATUS_SEND_CUSTOM_COMMAND_FAILED -114 +#define SMTP_STATUS_XOAUTH2_AUTH_FAILED -115 +#define SMTP_STATUS_UNDEFINED -116 +#endif + +#if defined(ENABLE_IMAP) + +#define IMAP_STATUS_SERVER_CONNECT_FAILED -200 +#define IMAP_STATUS_IMAP_RESPONSE_FAILED -201 +#define IMAP_STATUS_AUTHENTICATE_FAILED -202 +#define IMAP_STATUS_BAD_COMMAND -203 +#define IMAP_STATUS_STORE_FAILED -204 +#define IMAP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED -205 +#define IMAP_STATUS_NO_MESSAGE -206 +#define IMAP_STATUS_ERROR_DOWNLAD_TIMEOUT -207 +#define IMAP_STATUS_CLOSE_MAILBOX_FAILED -208 +#define IMAP_STATUS_OPEN_MAILBOX_FAILED -209 +#define IMAP_STATUS_LIST_MAILBOXS_FAILED -210 +#define IMAP_STATUS_CHECK_CAPABILITIES_FAILED -211 +#define IMAP_STATUS_NO_SUPPORTED_AUTH -212 +#define IMAP_STATUS_NO_MAILBOX_FOLDER_OPENED -213 +#define IMAP_STATUS_FIRMWARE_UPDATE_INIT_FAILED -214 +#define IMAP_STATUS_FIRMWARE_UPDATE_WRITE_FAILED -215 +#define IMAP_STATUS_FIRMWARE_UPDATE_END_FAILED -216 +#define IMAP_STATUS_CHANGEDSINC_MODSEQ_TEST_FAILED -217 +#define IMAP_STATUS_MODSEQ_WAS_NOT_SUPPORTED -218 +#endif + +/** + * MB_FS.h + #define MB_FS_ERROR_FILE_IO_ERROR -300 + #define MB_FS_ERROR_FILE_NOT_FOUND -301 + #define MB_FS_ERROR_FLASH_STORAGE_IS_NOT_READY -302 + #define MB_FS_ERROR_SD_STORAGE_IS_NOT_READY -303 + #define MB_FS_ERROR_FILE_STILL_OPENED -304 +*/ + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + +#define MAIL_CLIENT_ERROR_CONNECTION_CLOSED -400 +#define MAIL_CLIENT_ERROR_READ_TIMEOUT -401 +#define MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP -402 +#define MAIL_CLIENT_ERROR_OUT_OF_MEMORY -403 +#define MAIL_CLIENT_ERROR_NTP_TIME_SYNC_TIMED_OUT -404 +#define MAIL_CLIENT_ERROR_SESSION_CONFIG_WAS_NOT_ASSIGNED -405 +#define MAIL_CLIENT_ERROR_TIME_WAS_NOT_SET -406 +#define MAIL_CLIENT_ERROR_NOT_YET_LOGIN -407 +#define MAIL_CLIENT_ERROR_BUFFER_OVERFLOW -408 + +#endif + #endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_FS.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_FS.h index b9c9755d5..2a20db836 100644 --- a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_FS.h +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_FS.h @@ -1,170 +1,170 @@ - - -#pragma once - -#ifndef ESP_MAIL_CONFIG_H -#define ESP_MAIL_CONFIG_H - -#include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30409) -#error "Mixed versions compilation." -#endif - -#include -#include "extras/MB_MCU.h" - -/** 📌 Predefined Build Options - * ⛔ Use following build flag to disable all predefined options. - * -D DISABLE_ALL_OPTIONS - */ - -/**📍 For enabling the device or library time setup from NTP server - * ⛔ Use following build flag to disable. - * -D DISABLE_NTP_TIME - */ -#define ENABLE_NTP_TIME - -/**📍 For enabling the error string from error reason - * ⛔ Use following build flag to disable. - * -D DISABLE_ERROR_STRING - */ -#define ENABLE_ERROR_STRING - -/**📍 For IMAP class compilation - * ⛔ Use following build flag to disable. - * -D DISABLE_IMAP - */ -#define ENABLE_IMAP - -/**📍 For SMTP class compilation - * ⛔ Use following build flag to disable. - * -D DISABLE_SMTP - */ -#define ENABLE_SMTP - -/**📍 For enabling PSRAM support - * ⛔ Use following build flag to disable. - * -D DISABLE_PSRAM - */ -#define ESP_MAIL_USE_PSRAM - -/**📌 For enabling flash filesystem support - * - * 📍 For SPIFFS - * #define ESP_MAIL_DEFAULT_FLASH_FS SPIFFS - * - * - * 📍 For LittleFS Filesystem - * #include - * #define ESP_MAIL_DEFAULT_FLASH_FS LittleFS - * - * - * 📍 For SPIFFS Filesystem - * #if defined(ESP32) - * #include - * #endif - * #define ESP_MAIL_DEFAULT_FLASH_FS SPIFFS - * - * - * 📍 For FAT Filesystem - * #include - * #define ESP_MAIL_DEFAULT_FLASH_FS FFat //For ESP32 FAT - * - * 🚫 Use following build flags to disable. - * -D DISABLE_FLASH or -DDISABLE_FLASH in PlatformIO - */ - -#if defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO) - -#if defined(ESP8266) || defined(MB_ARDUINO_PICO) - -#include -#define ESP_MAIL_DEFAULT_FLASH_FS LittleFS - -#elif defined(ESP_ARDUINO_VERSION) /* ESP32 core >= v2.0.x */ /* ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) */ - -#include -#define ESP_MAIL_DEFAULT_FLASH_FS LittleFS - -#else - -#include -#define ESP_MAIL_DEFAULT_FLASH_FS SPIFFS - -#endif - -#endif - -// For ESP32, format SPIFFS or FFat if mounting failed -#define ESP_MAIL_FORMAT_FLASH_IF_MOUNT_FAILED 1 - -/**📌 For enabling SD filesystem support - * - * 📍 For SD - * #include - * #define ESP_MAIL_DEFAULT_SD_FS SD - * #define ESP_MAIL_CARD_TYPE_SD 1 - * - * 📍 For SD MMC (ESP32) - * #include - * #define ESP_MAIL_DEFAULT_SD_FS SD_MMC //For ESP32 SDMMC - * #define ESP_MAIL_CARD_TYPE_SD_MMC 1 - * - * 📍 For SdFat on ESP32 and other devices except for ESP8266 - * #include //https://github.com/greiman/SdFat - * static SdFat sd_fat_fs; //should declare as static here - * #define ESP_MAIL_DEFAULT_SD_FS sd_fat_fs - * #define ESP_MAIL_CARD_TYPE_SD 1 - * #define ESP_MAIL_SD_FS_FILE SdFile - * - * - * ⛔ Use following build flags to disable. - * -D DISABLE_SD or -DDISABLE_SD in PlatformIO - */ -#if defined(ESP32) || defined(ESP8266) -#include -#define ESP_MAIL_DEFAULT_SD_FS SD -#define ESP_MAIL_CARD_TYPE_SD 1 -#elif defined(MB_ARDUINO_PICO) -// Use SDFS (ESP8266SdFat) instead of SD -#include -#define ESP_MAIL_DEFAULT_SD_FS SDFS -#define ESP_MAIL_CARD_TYPE_SD 1 -#endif - -/** 🔖 Optional Build Options - * - * 🏷️ For silent operation (no debug printing and callback) - * #define SILENT_MODE - * - * 🏷️ For ENC28J60 Ethernet module support in ESP8266 - * #define ENABLE_ESP8266_ENC28J60_ETH - * - * 🏷️ For W5500 Ethernet module support in ESP8266 - * #define ENABLE_ESP8266_W5500_ETH - * - * 🏷️ For W5100 Ethernet module support in ESP8266 - * #define ENABLE_ESP8266_W5100_ETH - * - * 🏷️ For disabling on-board WiFI functionality in case external Client usage - * #define ESP_MAIL_DISABLE_ONBOARD_WIFI - * - * 🏷️ For disabling native (sdk) Ethernet functionality in case external Client usage - * #define ESP_MAIL_DISABLE_NATIVE_ETHERNET - * - * 🏷️ For disabling SSL connection (also disabling TLS using STARTTLS) in MAP and SMTP application - * #define ESP_MAIL_DISABLE_SSL - * - * 🏷️ For debug port assignment if SILENT_MODE option was not set - * #define ESP_MAIL_DEBUG_PORT Serial - */ - -#define ENABLE_ESP8266_ENC28J60_ETH - -#if __has_include("Custom_ESP_Mail_FS.h") -#include "Custom_ESP_Mail_FS.h" -#endif - -#include "extras/Build_Options.h" - -#endif + + +#pragma once + +#ifndef ESP_MAIL_CONFIG_H +#define ESP_MAIL_CONFIG_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +#include +#include "extras/MB_MCU.h" + +/** 📌 Predefined Build Options + * ⛔ Use following build flag to disable all predefined options. + * -D DISABLE_ALL_OPTIONS + */ + +/**📍 For enabling the device or library time setup from NTP server + * ⛔ Use following build flag to disable. + * -D DISABLE_NTP_TIME + */ +#define ENABLE_NTP_TIME + +/**📍 For enabling the error string from error reason + * ⛔ Use following build flag to disable. + * -D DISABLE_ERROR_STRING + */ +#define ENABLE_ERROR_STRING + +/**📍 For IMAP class compilation + * ⛔ Use following build flag to disable. + * -D DISABLE_IMAP + */ +#define ENABLE_IMAP + +/**📍 For SMTP class compilation + * ⛔ Use following build flag to disable. + * -D DISABLE_SMTP + */ +#define ENABLE_SMTP + +/**📍 For enabling PSRAM support + * ⛔ Use following build flag to disable. + * -D DISABLE_PSRAM + */ +#define ESP_MAIL_USE_PSRAM + +/**📌 For enabling flash filesystem support + * + * 📍 For SPIFFS + * #define ESP_MAIL_DEFAULT_FLASH_FS SPIFFS + * + * + * 📍 For LittleFS Filesystem + * #include + * #define ESP_MAIL_DEFAULT_FLASH_FS LittleFS + * + * + * 📍 For SPIFFS Filesystem + * #if defined(ESP32) + * #include + * #endif + * #define ESP_MAIL_DEFAULT_FLASH_FS SPIFFS + * + * + * 📍 For FAT Filesystem + * #include + * #define ESP_MAIL_DEFAULT_FLASH_FS FFat //For ESP32 FAT + * + * 🚫 Use following build flags to disable. + * -D DISABLE_FLASH or -DDISABLE_FLASH in PlatformIO + */ + +#if defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO) + +#if defined(ESP8266) || defined(MB_ARDUINO_PICO) + +#include +#define ESP_MAIL_DEFAULT_FLASH_FS LittleFS + +#elif defined(ESP_ARDUINO_VERSION) /* ESP32 core >= v2.0.x */ /* ESP_ARDUINO_VERSION >= ESP_ARDUINO_VERSION_VAL(2, 0, 0) */ + +#include +#define ESP_MAIL_DEFAULT_FLASH_FS LittleFS + +#else + +#include +#define ESP_MAIL_DEFAULT_FLASH_FS SPIFFS + +#endif + +#endif + +// For ESP32, format SPIFFS or FFat if mounting failed +#define ESP_MAIL_FORMAT_FLASH_IF_MOUNT_FAILED 1 + +/**📌 For enabling SD filesystem support + * + * 📍 For SD + * #include + * #define ESP_MAIL_DEFAULT_SD_FS SD + * #define ESP_MAIL_CARD_TYPE_SD 1 + * + * 📍 For SD MMC (ESP32) + * #include + * #define ESP_MAIL_DEFAULT_SD_FS SD_MMC //For ESP32 SDMMC + * #define ESP_MAIL_CARD_TYPE_SD_MMC 1 + * + * 📍 For SdFat on ESP32 and other devices except for ESP8266 + * #include //https://github.com/greiman/SdFat + * static SdFat sd_fat_fs; //should declare as static here + * #define ESP_MAIL_DEFAULT_SD_FS sd_fat_fs + * #define ESP_MAIL_CARD_TYPE_SD 1 + * #define ESP_MAIL_SD_FS_FILE SdFile + * + * + * ⛔ Use following build flags to disable. + * -D DISABLE_SD or -DDISABLE_SD in PlatformIO + */ +#if defined(ESP32) || defined(ESP8266) +#include +#define ESP_MAIL_DEFAULT_SD_FS SD +#define ESP_MAIL_CARD_TYPE_SD 1 +#elif defined(MB_ARDUINO_PICO) +// Use SDFS (ESP8266SdFat) instead of SD +#include +#define ESP_MAIL_DEFAULT_SD_FS SDFS +#define ESP_MAIL_CARD_TYPE_SD 1 +#endif + +/** 🔖 Optional Build Options + * + * 🏷️ For silent operation (no debug printing and callback) + * #define SILENT_MODE + * + * 🏷️ For ENC28J60 Ethernet module support in ESP8266 + * #define ENABLE_ESP8266_ENC28J60_ETH + * + * 🏷️ For W5500 Ethernet module support in ESP8266 + * #define ENABLE_ESP8266_W5500_ETH + * + * 🏷️ For W5100 Ethernet module support in ESP8266 + * #define ENABLE_ESP8266_W5100_ETH + * + * 🏷️ For disabling on-board WiFI functionality in case external Client usage + * #define ESP_MAIL_DISABLE_ONBOARD_WIFI + * + * 🏷️ For disabling native (sdk) Ethernet functionality in case external Client usage + * #define ESP_MAIL_DISABLE_NATIVE_ETHERNET + * + * 🏷️ For disabling SSL connection (also disabling TLS using STARTTLS) in MAP and SMTP application + * #define ESP_MAIL_DISABLE_SSL + * + * 🏷️ For debug port assignment if SILENT_MODE option was not set + * #define ESP_MAIL_DEBUG_PORT Serial + */ + +#define ENABLE_ESP8266_ENC28J60_ETH + +#if __has_include("Custom_ESP_Mail_FS.h") +#include "Custom_ESP_Mail_FS.h" +#endif + +#include "extras/Build_Options.h" + +#endif diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_IMAP.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_IMAP.h index ddfdbed08..a0ef752e9 100644 --- a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_IMAP.h +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_IMAP.h @@ -1,6783 +1,6783 @@ - -#ifndef ESP_MAIL_IMAP_H -#define ESP_MAIL_IMAP_H - -#include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30409) -#error "Mixed versions compilation." -#endif - -/** - * Mail Client Arduino Library for Espressif's ESP32 and ESP8266, Raspberry Pi RP2040 Pico, and SAMD21 with u-blox NINA-W102 WiFi/Bluetooth module - * - * Created August 28, 2023 - * - * This library allows Espressif's ESP32, ESP8266, SAMD and RP2040 Pico devices to send and read Email through the SMTP and IMAP servers. - * - * The MIT License (MIT) - * Copyright (c) 2023 K. Suwatchai (Mobizt) - * - * - * 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 "ESP_Mail_Client_Version.h" -#include "ESP_Mail_Client.h" - -#if defined(ENABLE_IMAP) - -#if defined(MB_ARDUINO_PICO) -extern uint8_t _FS_start; -extern uint8_t _FS_end; -#endif - -int ESP_Mail_Client::decodeChar(const char *s) -{ - return 16 * hexval(*(s + 1)) + hexval(*(s + 2)); -} - -void ESP_Mail_Client::decodeQP_UTF8(const char *buf, char *out) -{ - char *tmp = strP(esp_mail_str_47 /* "0123456789ABCDEF" */); - int idx = 0; - while (*buf) - { - if (*buf != '=') - out[idx++] = *buf++; - else if (*(buf + 1) == '\r' && *(buf + 2) == '\n') - buf += 3; - else if (*(buf + 1) == '\n') - buf += 2; - else if (!strchr(tmp, *(buf + 1))) - out[idx++] = *buf++; - else if (!strchr(tmp, *(buf + 2))) - out[idx++] = *buf++; - else - { - out[idx++] = decodeChar(buf); - buf += 3; - } - } - - // release memory - freeMem(&tmp); -} - -char *ESP_Mail_Client::decode7Bit_UTF8(char *buf) -{ - MB_String s; - - // only non NULL and 7-bit ASCII are allowed - - // rfc2045 section 2.7 - - size_t len = buf ? strlen(buf) : 0; - - for (size_t i = 0; i < len; i++) - { - if (buf[i] > 0 && buf[i] < 128 && i < 998) - s.append(1, buf[i]); - } - - // some special chars can't send in 7bit unless encoded as queoted printable string - char *decoded = allocMem(s.length() + 10); - decodeQP_UTF8(s.c_str(), decoded); - s.clear(); - return decoded; -} - -char *ESP_Mail_Client::decode8Bit_UTF8(char *buf) -{ - MB_String s; - - // only non NULL and less than 998 octet length are allowed - - // rfc2045 section 2.8 - - size_t len = buf ? strlen(buf) : 0; - - for (size_t i = 0; i < len; i++) - { - if (buf[i] > 0 && i < 998) - s.append(1, buf[i]); - } - - char *decoded = allocMem(s.length() + 1); - strcpy(decoded, s.c_str()); - s.clear(); - return decoded; -} - -void ESP_Mail_Client::decodeString(IMAPSession *imap, MB_String &str, const char *enc) -{ - - size_t p1 = 0, p2 = 0; - MB_String headerEnc; - - if (strlen(enc) == 0) - { - while (str[p1] == ' ' && p1 < str.length() - 1) - p1++; - - if (str[p1] == '=' && str[p1 + 1] == '?') - { - p2 = str.find('?', p1 + 2); - if (p2 != MB_String::npos) - headerEnc = str.substr(p1 + 2, p2 - p1 - 2); - } - } - else - headerEnc = enc; - - int bufSize = str.length() + 10; - char *buf = allocMem(bufSize); - - // Content Q and B decodings - RFC2047Decoder.decode(mbfs, buf, str.c_str(), bufSize); - - // Char set decoding - esp_mail_char_decoding_scheme scheme = getEncodingFromCharset(headerEnc.c_str()); - if (imap->_charDecCallback) - { - IMAP_Decoding_Info decoding; - decoding.charset = headerEnc.c_str(); - decoding.data = buf; - decoding.type = IMAP_Decoding_Info::message_part_type_header; - - imap->_charDecCallback(&decoding); - - if (decoding.decodedString.length() > 0) - { - char *buf2 = allocMem(decoding.decodedString.length() + 1); - strcpy(buf2, decoding.decodedString.c_str()); - // release memory and point to new buffer - freeMem(&buf); - buf = buf2; - } - } - else if (scheme == esp_mail_char_decoding_scheme_iso8859_1) - { - int len = strlen(buf); - int olen = (len + 1) * 2; - unsigned char *out = allocMem(olen); - decodeLatin1_UTF8(out, &olen, (unsigned char *)buf, &len); - // release memory and point to new buffer - freeMem(&buf); - buf = (char *)out; - } - else if (scheme == esp_mail_char_decoding_scheme_tis_620 || scheme == esp_mail_char_decoding_scheme_iso8859_11 || scheme == esp_mail_char_decoding_scheme_windows_874) - { - size_t len2 = strlen(buf); - char *tmp = allocMem((len2 + 1) * 3); - decodeTIS620_UTF8(tmp, buf, len2); - // release memory and point to new buffer - freeMem(&buf); - buf = tmp; - } - - str = buf; - // release memory - freeMem(&buf); -} - -esp_mail_char_decoding_scheme ESP_Mail_Client::getEncodingFromCharset(const char *enc) -{ - esp_mail_char_decoding_scheme scheme = esp_mail_char_decoding_scheme_default; - - for (int i = esp_mail_char_decoding_utf8; i < esp_mail_char_decoding_maxType; i++) - { - if (strpos(enc, char_decodings[i].text, 0, false) > -1) - scheme = (esp_mail_char_decoding_scheme)i; - } - - return scheme; -} - -int ESP_Mail_Client::encodeUnicode_UTF8(char *out, uint32_t utf) -{ - if (utf <= 0x7F) - { - // Plain ASCII - out[0] = (char)utf; - out[1] = 0; - return 1; - } - else if (utf <= 0x07FF) - { - // 2-byte unicode - out[0] = (char)(((utf >> 6) & 0x1F) | 0xC0); - out[1] = (char)(((utf >> 0) & 0x3F) | 0x80); - out[2] = 0; - return 2; - } - else if (utf <= 0xFFFF) - { - // 3-byte unicode - out[0] = (char)(((utf >> 12) & 0x0F) | 0xE0); - out[1] = (char)(((utf >> 6) & 0x3F) | 0x80); - out[2] = (char)(((utf >> 0) & 0x3F) | 0x80); - out[3] = 0; - return 3; - } - else if (utf <= 0x10FFFF) - { - // 4-byte unicode - out[0] = (char)(((utf >> 18) & 0x07) | 0xF0); - out[1] = (char)(((utf >> 12) & 0x3F) | 0x80); - out[2] = (char)(((utf >> 6) & 0x3F) | 0x80); - out[3] = (char)(((utf >> 0) & 0x3F) | 0x80); - out[4] = 0; - return 4; - } - else - { - // error - use replacement character - out[0] = (char)0xEF; - out[1] = (char)0xBF; - out[2] = (char)0xBD; - out[3] = 0; - return 0; - } -} - -void ESP_Mail_Client::decodeTIS620_UTF8(char *out, const char *in, size_t len) -{ - // output is the 3-byte value UTF-8 - int j = 0; - for (size_t i = 0; i < len; i++) - { - if (in[i] < 0x80) - out[j++] = in[i]; - else if ((in[i] >= 0xa0 && in[i] < 0xdb) || (in[i] > 0xde && in[i] < 0xfc)) - { - int unicode = 0x0e00 + in[i] - 0xa0; - char o[5]; - memset(o, 0, 5); - int r = encodeUnicode_UTF8(o, unicode); - for (int x = 0; x < r; x++) - out[j++] = o[x]; - } - } -} - -int ESP_Mail_Client::decodeLatin1_UTF8(unsigned char *out, int *outlen, const unsigned char *in, int *inlen) -{ - unsigned char *outstart = out; - const unsigned char *base = in; - const unsigned char *processed = in; - unsigned char *outend = out + *outlen; - const unsigned char *inend; - unsigned int c; - int bits; - - inend = in + (*inlen); - while ((in < inend) && (out - outstart + 5 < *outlen)) - { - c = *in++; - - /* assertion: c is a single UTF-4 value */ - if (out >= outend) - break; - if (c < 0x80) - { - *out++ = c; - bits = -6; - } - else - { - *out++ = ((c >> 6) & 0x1F) | 0xC0; - bits = 0; - } - - for (; bits >= 0; bits -= 6) - { - if (out >= outend) - break; - *out++ = ((c >> bits) & 0x3F) | 0x80; - } - processed = (const unsigned char *)in; - } - *outlen = out - outstart; - *inlen = processed - base; - return (0); -} - -bool ESP_Mail_Client::sendFetchCommand(IMAPSession *imap, int msgIndex, esp_mail_imap_command cmdCase) -{ - - MB_String cmd, cmd2, cmd3; - appendHeadersFetchCommand(imap, cmd, msgIndex, false); - - if (cmdCase == esp_mail_imap_cmd_fetch_body_mime) - { - joinStringDot(cmd2, 2, imap_commands[esp_mail_imap_command_header].text, imap_commands[esp_mail_imap_command_fields].text); - appendSpace(cmd2); - joinStringSpace(cmd3, false, 2, message_headers[esp_mail_message_header_field_content_type].text, message_headers[esp_mail_message_header_field_content_transfer_encoding].text); - appendString(cmd2, cmd3.c_str(), false, false, esp_mail_string_mark_type_round_bracket); - } - else if (cmdCase == esp_mail_imap_cmd_fetch_body_text) - cmd2 = cPart(imap)->partNumFetchStr.length() > 0 ? cPart(imap)->partNumFetchStr.c_str() : imap_commands[esp_mail_imap_command_text].text; - else if (cmdCase == esp_mail_imap_cmd_fetch_body_attachment) - cmd2 = cPart(imap)->partNumFetchStr; - - if (cmd2.length() > 0) - appendString(cmd, cmd2.c_str(), false, false, esp_mail_string_mark_type_square_bracket); - - bool allowPartialFetch = (cmdCase == esp_mail_imap_cmd_fetch_body_attachment && cPart(imap)->is_firmware_file) ? false : true; - - if (imap->_mimeDataStreamCallback) - allowPartialFetch = false; - - if (allowPartialFetch) - { - // Apply partial fetch in case download was disabled. - if (!imap->_storageReady && imap->_attDownload && cmdCase == esp_mail_imap_cmd_fetch_body_attachment) - cmd += esp_mail_str_48; /* "<0.0>" */ // This case should not happen because the memory storage was previousely checked. - else if ((!imap->_msgDownload && cmdCase == esp_mail_imap_cmd_fetch_body_text) || (imap->_msgDownload && !imap->_storageReady)) - { - cmd += esp_mail_str_49; /* "<0." */ - cmd += imap->_imap_data->limit.msg_size; - cmd += esp_mail_str_20; /* ">" */ - } - } - - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - return true; -} - -bool ESP_Mail_Client::readMail(IMAPSession *imap, bool closeSession) -{ - if (!imap || !sessionExisted(imap)) - return false; - - imap->checkUID(); - imap->checkPath(); - imap->_cbData._success = false; - - if (!imap->connected()) - imap->_mailboxOpened = false; - - imap->_isFirmwareUpdated = false; - - MB_String buf, command, _uid; - - size_t readCount = 0; - imap->_multipart_levels.clear(); - - if (!reconnect(imap)) - return false; - - imap->_msgDownload = imap->_imap_data->download.text || imap->_imap_data->download.html; - imap->_attDownload = imap->_imap_data->download.attachment || imap->_imap_data->download.inlineImg; - - if (!imap->_storageChecked) - { - imap->_storageChecked = true; - imap->_storageReady = imap->_imap_data->download.header || (!imap->_imap_data->fetch.headerOnly && (imap->_msgDownload || imap->_attDownload)) ? mbfs->checkStorageReady(mbfs_type imap->_imap_data->storage.type) : true; - } - - bool readyToDownload = (imap->_msgDownload || imap->_attDownload) && imap->_storageReady; - - if (!imap->_storageReady) - sendStorageNotReadyError(imap, imap->_imap_data->storage.type); - -#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) - - int cmem = MailClient.getFreeHeap(); - - if (cmem < ESP_MAIL_MIN_MEM) - { -#if !defined(SILENT_MODE) - if (imap->_debug && imap->_statusCallback && !imap->_customCmdResCallback) - { - esp_mail_debug_print(); - errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_OUT_OF_MEMORY, true); - } -#endif - - goto out; - } -#endif - - if (!imap->connected() && !imap->_loginStatus) - { -#if !defined(SILENT_MODE) - if (imap->_debug && imap->_statusCallback && !imap->_customCmdResCallback) - { - esp_mail_debug_print(); - errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_NOT_YET_LOGIN, true); - } -#endif - return false; - } - - // new session - if (!imap->connected()) - { - // authenticate new - - bool ssl = false; - - if (!imap->connect(ssl)) - { - closeTCPSession(imap); - return false; - } - - if (!imapAuth(imap, ssl)) - { - closeTCPSession(imap); - return false; - } - } - else - { - // If time config changed, we will update time - MailClient.prepareTime(imap->_session_cfg, imap); - - // reuse session - for (size_t i = 0; i < imap->_headers.size(); i++) - imap->_headers[i].part_headers.clear(); - imap->_headers.clear(); - - if (imap->_imap_data->fetch.sequence_set.string.length() > 0 || imap->_imap_data->fetch.uid.length() > 0 || imap->_imap_data->fetch.number.length() > 0) - imap->_headerOnly = false; - else - imap->_headerOnly = true; - } - - imap->_rfc822_part_count = 0; - imap->_mbif._availableItems = 0; - imap->_imap_msg_num.clear(); - imap->_uidSearch = false; - imap->_mbif._searchCount = 0; - - if (imap->_currentFolder.length() == 0) - return handleIMAPError(imap, IMAP_STATUS_NO_MAILBOX_FOLDER_OPENED, false); - - if (!imap->_mailboxOpened || (imap->_imap_data->fetch.set_seen && !imap->_headerOnly && imap->_readOnlyMode)) - { - if (!imap->openFolder(imap->_currentFolder.c_str(), imap->_readOnlyMode && !imap->_imap_data->fetch.set_seen)) - return handleIMAPError(imap, IMAP_STATUS_OPEN_MAILBOX_FAILED, false); - } - - if (imap->_headerOnly) - { - if (imap->_imap_data->search.criteria.length() > 0) - { - command = esp_mail_imap_tag_str; - -#if !defined(SILENT_MODE) - printDebug(imap, - esp_mail_cb_str_18 /* "Searching messages..." */, - esp_mail_dbg_str_36 /* "searching messages" */, - esp_mail_debug_tag_type_client, - true, - false); - -#endif - - if (strposP(imap->_imap_data->search.criteria.c_str(), imap_cmd_post_tokens[esp_mail_imap_command_uid].c_str(), 0) != -1) - { - imap->_uidSearch = true; - command += imap_cmd_pre_tokens[esp_mail_imap_command_uid]; - } - - command += imap_cmd_pre_tokens[esp_mail_imap_command_search]; - - imap->_imap_data->search.criteria.trim(); - - MB_String tag; - appendTagSpace(tag); - - // Remove internal used reserved tag - if (strpos(imap->_imap_data->search.criteria.c_str(), tag.c_str(), 0, true) == 0) - imap->_imap_data->search.criteria.erase(0, tag.length()); - - for (size_t i = 0; i < imap->_imap_data->search.criteria.length(); i++) - { - if (imap->_imap_data->search.criteria[i] != ' ' && imap->_imap_data->search.criteria[i] != '\r' && imap->_imap_data->search.criteria[i] != '\n') - buf.append(1, imap->_imap_data->search.criteria[i]); - - if (imap->_imap_data->search.criteria[i] == ' ') - { - - if ((imap->_uidSearch && strcmp(buf.c_str(), imap_commands[esp_mail_imap_command_uid].text) == 0) || (imap->_unseen && buf.find(imap_commands[esp_mail_imap_command_all].text) != MB_String::npos)) - buf.clear(); - - if (strcmp(buf.c_str(), imap_commands[esp_mail_imap_command_search].text) != 0 && buf.length() > 0) - prependSpace(command, buf.c_str()); - - buf.clear(); - } - } - - if (imap->_unseen && strpos(imap->_imap_data->search.criteria.c_str(), imap_cmd_pre_tokens[esp_mail_imap_command_new].c_str(), 0) == -1) - command += imap_cmd_pre_tokens[esp_mail_imap_command_new]; - - if (buf.length() > 0) - prependSpace(command, buf.c_str()); - - if (!imap->isModseqSupported() && strpos(imap->_imap_data->search.criteria.c_str(), imap_cmd_pre_tokens[esp_mail_imap_command_modsec].c_str(), 0, false) != -1) - { - imap->_responseStatus.errorCode = IMAP_STATUS_MODSEQ_WAS_NOT_SUPPORTED; -#if !defined(SILENT_MODE) - - if (imap->_statusCallback) - sendErrorCB(imap, imap->errorReason().c_str(), false, false); - - if (imap->_debug) - esp_mail_debug_print_tag(imap->errorReason().c_str(), esp_mail_debug_tag_type_error, true); - -#endif - return false; - } - - if (imapSend(imap, command.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - command.clear(); - - imap->_imap_cmd = esp_mail_imap_cmd_search; - - if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, closeSession)) - return false; - -#if !defined(SILENT_MODE) - if (imap->_statusCallback) - { - callBackSendNewLine(imap, false); - if (imap->_imap_msg_num.size() > 0) - { - int bufLen = 100; - char *buf = allocMem(bufLen); - snprintf(buf, bufLen, pgm2Str(esp_mail_str_50 /* "Search limit: %d\nFound %d messages\nShow %d messages\n" */), (int)imap->_imap_data->limit.search, imap->_mbif._searchCount, (int)imap->_imap_msg_num.size()); - sendCallback(imap, buf, false, false); - // release memory - freeMem(&buf); - } - else - sendCallback(imap, esp_mail_error_imap_str_9 /* "no messages found for the specified search criteria" */, false, false); - } -#endif - } - else - { -#if !defined(SILENT_MODE) - if (imap->_statusCallback) - sendCallback(imap, esp_mail_error_imap_str_10 /* "no search criteria provided, then fetching the latest message" */, false, false); -#endif - imap->_mbif._availableItems++; - - esp_mail_imap_msg_num_t msg_num; - msg_num.type = esp_mail_imap_msg_num_type_number; - msg_num.value = (uint32_t)imap->_mbif._msgCount; - - imap->_imap_msg_num.push_back(msg_num); - imap->_headerOnly = false; - imap->_imap_data->fetch.number = imap->_mbif._msgCount; - } - } - else - { - - if (imap->_imap_data->fetch.sequence_set.string.length() > 0) - { - imap->_headerOnly = imap->_imap_data->fetch.sequence_set.headerOnly; - imap->mFetchSequenceSet(); - - imap->_mbif._availableItems = imap->_imap_msg_num.size(); - } - else - { - if (imap->_imap_data->fetch.uid.length() > 0) - { - imap->_mbif._availableItems++; - - esp_mail_imap_msg_num_t msg_num; - msg_num.type = esp_mail_imap_msg_num_type_uid; - msg_num.value = (uint32_t)atoi(imap->_imap_data->fetch.uid.c_str()); - - imap->_imap_msg_num.push_back(msg_num); - } - - if (imap->_imap_data->fetch.number.length() > 0) - { - imap->_mbif._availableItems++; - - esp_mail_imap_msg_num_t msg_num; - msg_num.type = esp_mail_imap_msg_num_type_number; - msg_num.value = (uint32_t)atoi(imap->_imap_data->fetch.number.c_str()); - - imap->_imap_msg_num.push_back(msg_num); - } - } - } - - if (imap->_imap_data->fetch.headerOnly) - imap->_headerOnly = true; - - for (size_t i = 0; i < imap->_imap_msg_num.size(); i++) - { - imap->_cMsgIdx = i; - imap->_totalRead++; - -#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) - if (MailClient.getFreeHeap() - (imap->_imap_data->limit.msg_size * (i + 1)) < ESP_MAIL_MIN_MEM) - { - errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_OUT_OF_MEMORY, true); - goto out; - } -#endif - -#if !defined(SILENT_MODE) - if (imap->_statusCallback) - { - readCount++; - int bufLen = 100; - PGM_P p = imap->_uidSearch || imap->_imap_msg_num[i].type == esp_mail_imap_msg_num_type_uid ? esp_mail_str_52 /* "Fetch message %d, UID: %d" */ : esp_mail_str_53 /* "Fetch message %d, Number: %d" */; - char *buf = allocMem(bufLen); - snprintf(buf, bufLen, pgm2Str(p), imap->_totalRead, (int)imap->_imap_msg_num[i].value); - sendCallback(imap, buf, true, false); - // release memory - freeMem(&buf); - } - - if (imap->_debug) - esp_mail_debug_print_tag(esp_mail_dbg_str_37 /* "send IMAP command, FETCH" */, esp_mail_debug_tag_type_client, true); -#endif - MB_String cmd; - appendHeadersFetchCommand(imap, cmd, i, true); - - // We fetch only known RFC822 headers because - // using Fetch RFC822.HEADER reurns all included unused headers - // which required more memory and network bandwidth. - MB_String cmd2; - appendRFC822HeadersFetchCommand(cmd2); - - appendString(cmd, cmd2.c_str(), false, false, esp_mail_string_mark_type_square_bracket); - - imap->addModifier(cmd, esp_mail_imap_command_changedsince, imap->_imap_data->fetch.modsequence); - - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - { - if (i < imap->_imap_msg_num.size() - 1) - continue; - return false; - } - - imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_header; - - int err = imap->_headerOnly ? IMAP_STATUS_IMAP_RESPONSE_FAILED : IMAP_STATUS_BAD_COMMAND; - - if (!handleIMAPResponse(imap, err, closeSession)) - { - if (i < imap->_imap_msg_num.size() - 1) - continue; - return false; - } - - if (!cHeader(imap)) - continue; - - if (imap->_imap_msg_num[i].type == esp_mail_imap_msg_num_type_number) - cHeader(imap)->message_uid = imap->mGetUID(cHeader(imap)->message_no); - - cHeader(imap)->flags = imap->getFlags(cHeader(imap)->message_no); - - if (!imap->_headerOnly) - { - imap->_cPartIdx = 0; - - // Reset attachment state if it was set by "multipart/mixed" content type header - cHeader(imap)->hasAttachment = false; - -#if !defined(SILENT_MODE) - if (imap->_debug) - debugPrintNewLine(); -#endif - - // multipart - if (cHeader(imap)->multipart) - { - struct esp_mail_imap_multipart_level_t mlevel; - mlevel.level = 1; - mlevel.fetch_rfc822_header = false; - mlevel.append_body_text = false; - imap->_multipart_levels.push_back(mlevel); - - if (!fetchMultipartBodyHeader(imap, i)) - return false; - } - else - { - // single part - if (imap->_debug) - printBodyPartFechingDubug(imap, "1", false); - - cHeader(imap)->partNumStr.clear(); - if (!sendFetchCommand(imap, i, esp_mail_imap_cmd_fetch_body_mime)) - return false; - - imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_mime; - if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, closeSession)) - return false; - } - - if (readyToDownload && imap->_imap_data->storage.saved_path.length() == 0) - imap->_imap_data->storage.saved_path = esp_mail_str_10; /* "/" */ - - if (cHeader(imap)->part_headers.size() > 0) - { - - cHeader(imap)->sd_alias_file_count = 0; - - imap->_sdFileList.clear(); - if (!mbfs->longNameSupported()) - imap->_sdFileList = esp_mail_str_40; /* "[" */ - -#if !defined(SILENT_MODE) - - if (cHeader(imap)->attachment_count > 0 && imap->_statusCallback) - { - int bufLen = 100; - char *buf = allocMem(bufLen); - snprintf(buf, bufLen, pgm2Str(esp_mail_str_54 /* "Attachments (%d)" */), cHeader(imap)->attachment_count); - callBackSendNewLine(imap, false); - sendCallback(imap, buf, false, false); - // release memory - freeMem(&buf); - - int count = 0; - - for (size_t j = 0; j < cHeader(imap)->part_headers.size(); j++) - { - imap->_cPartIdx = j; - if (!cPart(imap)->rfc822_part && cPart(imap)->attach_type != esp_mail_att_type_none) - { - count++; - MB_String str = count; - appendDot(str); - prependSpace(str, cPart(imap)->filename.c_str()); - sendCallback(imap, str.c_str(), false, false); - } - } - } - -#endif - - MB_String s1, s2; - int _idx1 = 0; - for (size_t j = 0; j < cHeader(imap)->part_headers.size(); j++) - { - imap->_cPartIdx = j; - if (cPart(imap)->rfc822_part) - { - s1 = cPart(imap)->partNumStr; - _idx1 = cPart(imap)->rfc822_msg_Idx; - } - else if (s1.length() > 0) - { - if (multipartMember(s1, cPart(imap)->partNumStr)) - { - cPart(imap)->message_sub_type = esp_mail_imap_message_sub_type_rfc822; - cPart(imap)->rfc822_msg_Idx = _idx1; - } - } - - if (cPart(imap)->multipart_sub_type == esp_mail_imap_multipart_sub_type_parallel) - s2 = cPart(imap)->partNumStr; - else if (s2.length() > 0) - { - if (multipartMember(s2, cPart(imap)->partNumStr)) - { - cPart(imap)->attach_type = esp_mail_att_type_attachment; - if (cPart(imap)->filename.length() == 0) - { - if (cPart(imap)->name.length() > 0) - cPart(imap)->filename = cPart(imap)->name; - else - { - char *uid = getRandomUID(); - cPart(imap)->filename = uid; - cPart(imap)->filename += mimeinfo[esp_mail_file_extension_dat].endsWith; - freeMem(&uid); - } - } - } - } - - checkFirmwareFile(imap, cPart(imap)->filename.c_str(), *cPart(imap), true); - } - - int attach_count = 0; - int ccnt = 0; - - for (size_t j = 0; j < cHeader(imap)->part_headers.size(); j++) - { - imap->_cPartIdx = j; - - if (cPart(imap)->rfc822_part || cPart(imap)->multipart_sub_type != esp_mail_imap_multipart_sub_type_none) - continue; - - bool rfc822_body_subtype = cPart(imap)->message_sub_type == esp_mail_imap_message_sub_type_rfc822 && cPart(imap)->attach_type != esp_mail_att_type_attachment; - - if (cPart(imap)->attach_type == esp_mail_att_type_none && (cPart(imap)->msg_type == esp_mail_msg_type_html || cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched)) - { - - bool ret = ((imap->_imap_data->enable.rfc822 || imap->_imap_data->download.rfc822) && rfc822_body_subtype) || (!rfc822_body_subtype && ((imap->_imap_data->enable.text && (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched)) || (imap->_imap_data->enable.html && cPart(imap)->msg_type == esp_mail_msg_type_html) || (cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->download.text))); - if (!ret) - continue; - -#if !defined(SILENT_MODE) - - if ((imap->_imap_data->download.rfc822 && rfc822_body_subtype) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->download.text)))) - { - - if (ccnt == 0 && imap->_statusCallback) - sendCallback(imap, esp_mail_cb_str_43 /* "Downloading messages..." */, true, false); - - if (imap->_debug) - { - debugPrintNewLine(); - if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) - esp_mail_debug_print_tag(esp_mail_dbg_str_74 /* "download plain TEXT message" */, esp_mail_debug_tag_type_client, true); - else if (cPart(imap)->msg_type == esp_mail_msg_type_html) - esp_mail_debug_print_tag(esp_mail_dbg_str_71 /* "download HTML message" */, esp_mail_debug_tag_type_client, true); - } - } - else - { - if (ccnt == 0) - sendCallback(imap, esp_mail_cb_str_28 /* "Reading messages..." */, true, false); - - if (imap->_debug) - { - debugPrintNewLine(); - if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) - esp_mail_debug_print_tag(esp_mail_dbg_str_46 /* "reading plain TEXT message" */, esp_mail_debug_tag_type_client, true); - else if (cPart(imap)->msg_type == esp_mail_msg_type_html) - esp_mail_debug_print_tag(esp_mail_dbg_str_47 /* "reading HTML message" */, esp_mail_debug_tag_type_client, true); - } - } - -#endif - - ccnt++; - - if (!sendFetchCommand(imap, i, esp_mail_imap_cmd_fetch_body_text)) - return false; - - imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_text; - if (!handleIMAPResponse(imap, IMAP_STATUS_IMAP_RESPONSE_FAILED, closeSession)) - return false; - } - else if (cPart(imap)->attach_type != esp_mail_att_type_none && (imap->_storageReady || cPart(imap)->is_firmware_file)) - { - - if (cPart(imap)->is_firmware_file || (imap->_imap_data->download.attachment && cPart(imap)->attach_type == esp_mail_att_type_attachment) || (imap->_imap_data->download.inlineImg && cPart(imap)->attach_type == esp_mail_att_type_inline)) - { -#if !defined(SILENT_MODE) - if (cPart(imap)->save_to_file) - { - - if (attach_count == 0 && imap->_statusCallback) - sendCallback(imap, esp_mail_cb_str_19 /* "Downloading attachments..." */, true, false); - - if (imap->_debug) - { - debugPrintNewLine(); - int bufLen = 100; - char *buf = allocMem(bufLen); - snprintf(buf, bufLen, pgm2Str(esp_mail_dbg_str_70 /* "download attachment %d of %d" */), attach_count + 1, (int)cHeader(imap)->attachment_count); - esp_mail_debug_print_tag(buf, esp_mail_debug_tag_type_client, true); - // release memory - freeMem(&buf); - - MB_String filePath = imap->_imap_data->storage.saved_path; - filePath += esp_mail_str_10; /* "/" */ - filePath += cHeader(imap)->message_uid; - filePath += esp_mail_str_10; /* "/" */ - filePath += cPart(imap)->filename; - - esp_mail_debug_print_tag(filePath.c_str(), esp_mail_debug_tag_type_client, true); - } - } -#endif - - attach_count++; - - if (cPart(imap)->octetLen <= (int)imap->_imap_data->limit.attachment_size) - { - - if (imap->_storageReady || cPart(imap)->is_firmware_file) - { - - if ((int)j < (int)cHeader(imap)->part_headers.size() - 1) - if (cHeader(imap)->part_headers[j + 1].octetLen > (int)imap->_imap_data->limit.attachment_size) - cHeader(imap)->downloaded_bytes += cHeader(imap)->part_headers[j + 1].octetLen; - - if (!sendFetchCommand(imap, i, esp_mail_imap_cmd_fetch_body_attachment)) - return false; - - imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_attachment; - if (!handleIMAPResponse(imap, IMAP_STATUS_IMAP_RESPONSE_FAILED, closeSession)) - return false; - - yield_impl(); - } - } - else - { - if ((int)j == (int)cHeader(imap)->part_headers.size() - 1) - cHeader(imap)->downloaded_bytes += cPart(imap)->octetLen; - } - } - } - } - } - - if (imap->_storageReady && imap->_imap_data->download.header && !imap->_headerSaved) - { -#if !defined(SILENT_MODE) - if (imap->_statusCallback) - sendCallback(imap, esp_mail_cb_str_21 /* "Saving message header to file..." */, true, false); - else if (imap->_debug) - debugPrintNewLine(); -#endif - - saveHeader(imap, false); - saveHeader(imap, true); - } - - // save files list to file - if (imap->_storageReady && imap->_sdFileList.length() > 0) - { - MB_String filepath = cHeader(imap)->message_uid; - filepath += mimeinfo[esp_mail_file_extension_txt].endsWith; - if (mbfs->open(filepath, mbfs_type imap->_imap_data->storage.type, mb_fs_open_mode_write) > -1) - { - mbfs->print(mbfs_type imap->_imap_data->storage.type, imap->_sdFileList.c_str()); - mbfs->close(mbfs_type imap->_imap_data->storage.type); - } - } - - imap->_cMsgIdx++; - } -#if !defined(SILENT_MODE) - if (imap->_debug) - { - MB_String str = esp_mail_str_55; /* "Free Heap: " */ - str += MailClient.getFreeHeap(); - esp_mail_debug_print_tag(str.c_str(), esp_mail_debug_tag_type_client, true); - } -#endif - } -#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) -out: -#endif - if (readCount < imap->_imap_msg_num.size()) - { - imap->_mbif._availableItems = readCount; - imap->_imap_msg_num.erase(imap->_imap_msg_num.begin() + readCount, imap->_imap_msg_num.end()); - } - - if (closeSession) - { - if (!imap->closeSession()) - return false; - } - else - { -#if !defined(SILENT_MODE) - printDebug(imap, - esp_mail_cb_str_46 /* "Finished reading Email" */, - esp_mail_dbg_str_29 /* "finished reading Email" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - } - - imap->_cbData._success = true; - -#if !defined(SILENT_MODE) - if (imap->_statusCallback) - callBackSendNewLine(imap, true); -#endif - - return true; -} - -void ESP_Mail_Client::appendHeadersFetchCommand(IMAPSession *imap, MB_String &cmd, int index, bool debug) -{ - if (imap->_uidSearch || imap->_imap_msg_num[index].type == esp_mail_imap_msg_num_type_uid) - appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_fetch].text); - else - appendSpace(cmd, true, imap_commands[esp_mail_imap_command_fetch].text); -#if !defined(SILENT_MODE) - if (debug && imap->_debug) - esp_mail_debug_print_tag(esp_mail_dbg_str_26 /* "fetch message header" */, esp_mail_debug_tag_type_client, true); -#endif - joinStringSpace(cmd, false, 2, MB_String((int)imap->_imap_msg_num[index].value).c_str(), imap_commands[esp_mail_imap_command_body].text); - - if (!imap->_imap_data->fetch.set_seen) - prependDot(cmd, imap_commands[esp_mail_imap_command_peek].text); -} - -void ESP_Mail_Client::appendRFC822HeadersFetchCommand(MB_String &cmd) -{ - joinStringDot(cmd, 2, imap_commands[esp_mail_imap_command_header].text, imap_commands[esp_mail_imap_command_fields].text); - appendSpace(cmd); - - MB_String cmd2; - - for (int i = 0; i < esp_mail_rfc822_header_field_maxType; i++) - appendSpace(cmd2, false, rfc822_headers[i].text); - - joinStringSpace(cmd2, false, 4, message_headers[esp_mail_message_header_field_content_type].text, - message_headers[esp_mail_message_header_field_content_transfer_encoding].text, - message_headers[esp_mail_message_header_field_content_language].text, - message_headers[esp_mail_message_header_field_accept_language].text); - - appendString(cmd, cmd2.c_str(), false, false, esp_mail_string_mark_type_round_bracket); -} - -bool ESP_Mail_Client::getMultipartFechCmd(IMAPSession *imap, int msgIdx, MB_String &partText) -{ - if (imap->_multipart_levels.size() == 0) - return false; - - int cLevel = imap->_multipart_levels.size() - 1; - - cHeader(imap)->partNumStr.clear(); - - appendHeadersFetchCommand(imap, partText, msgIdx, false); - - MB_String cmd1; - for (size_t i = 0; i < imap->_multipart_levels.size(); i++) - { - if (i > 0) - { - cmd1 += esp_mail_str_27; /* "." */ - cHeader(imap)->partNumStr += esp_mail_str_27; /* "." */ - } - - cmd1 += imap->_multipart_levels[i].level; - cHeader(imap)->partNumStr += imap->_multipart_levels[i].level; - } - - if (imap->_multipart_levels[cLevel].fetch_rfc822_header) - { - MB_String cmd2; - appendRFC822HeadersFetchCommand(cmd2); - prependDot(cmd1, cmd2.c_str()); - imap->_multipart_levels[cLevel].append_body_text = true; - } - else - prependDot(cmd1, imap_commands[esp_mail_imap_command_mime].text); - - appendString(partText, cmd1.c_str(), false, false, esp_mail_string_mark_type_square_bracket); - - imap->_multipart_levels[cLevel].fetch_rfc822_header = false; - - return true; -} - -bool ESP_Mail_Client::multipartMember(const MB_String &parent, const MB_String &child) -{ - if (parent.length() > child.length()) - return false; - - for (size_t i = 0; i < parent.length(); i++) - if (parent[i] != child[i]) - return false; - - return true; -} - -bool ESP_Mail_Client::fetchMultipartBodyHeader(IMAPSession *imap, int msgIdx) -{ - bool ret = true; - - if (!connected(imap)) - { - closeTCPSession(imap); - return false; - } - int cLevel = 0; - - // slower than BODYSTRUCTURE parsing but sure - do - { - -#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) - // Prevent stack overflow - if (MailClient.getFreeHeap() < ESP_MAIL_MIN_MEM) - { - errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_OUT_OF_MEMORY, true); - break; - } -#endif - - struct esp_mail_message_part_info_t *_cpart = &cHeader(imap)->part_headers[cHeader(imap)->message_data_count - 1]; - bool rfc822_body_subtype = _cpart->message_sub_type == esp_mail_imap_message_sub_type_rfc822 && _cpart->attach_type != esp_mail_att_type_attachment; - - MB_String cmd; - if (!getMultipartFechCmd(imap, msgIdx, cmd)) - return true; - - if (imap->_debug) - printBodyPartFechingDubug(imap, cHeader(imap)->partNumStr.c_str(), imap->_multipart_levels.size() > 1); - - // Try fetching the part and its sub parts hierarchically - // Some sub part may not exist at the current multipart level - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_mime; - ret = handleIMAPResponse(imap, IMAP_STATUS_IMAP_RESPONSE_FAILED, false); - - _cpart = &cHeader(imap)->part_headers[cHeader(imap)->message_data_count - 1]; - rfc822_body_subtype = _cpart->message_sub_type == esp_mail_imap_message_sub_type_rfc822 && _cpart->attach_type != esp_mail_att_type_attachment; - cLevel = imap->_multipart_levels.size() - 1; - - if (ret) - { - if (_cpart->multipart) - { - if (_cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_parallel || _cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_alternative || _cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_related || _cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_mixed) - { - struct esp_mail_imap_multipart_level_t mlevel; - mlevel.level = 1; - mlevel.fetch_rfc822_header = false; - mlevel.append_body_text = false; - imap->_multipart_levels.push_back(mlevel); - fetchMultipartBodyHeader(imap, msgIdx); - } - else - imap->_multipart_levels[cLevel].level++; - } - else - { - if (rfc822_body_subtype) - { - // Get additional rfc822 message header - imap->_multipart_levels[cLevel].fetch_rfc822_header = true; - fetchMultipartBodyHeader(imap, msgIdx); - } - else - { - if (imap->_multipart_levels[cLevel].append_body_text) - { - // single part rfc822 message body, append TEXT to the body fetch command - prependDot(_cpart->partNumFetchStr, imap_commands[esp_mail_imap_command_text].text); - imap->_multipart_levels[cLevel].append_body_text = false; - } - imap->_multipart_levels[cLevel].level++; - } - } - } - - } while (ret); - - imap->_multipart_levels.pop_back(); - - if (imap->_multipart_levels.size() > 0) - { - cLevel = imap->_multipart_levels.size() - 1; - imap->_multipart_levels[cLevel].level++; - } - - return true; -} - -void ESP_Mail_Client::printBodyPartFechingDubug(IMAPSession *imap, const char *partNum, bool multiLevel) -{ -#if !defined(SILENT_MODE) - MB_String str = multiLevel ? esp_mail_dbg_str_28 /* "fetch body sub part header, " */ : esp_mail_dbg_str_27; /* "fetch body part header, " */ - str += partNum; - esp_mail_debug_print_tag(str.c_str(), esp_mail_debug_tag_type_client, true); -#endif -} - -bool ESP_Mail_Client::imapAuth(IMAPSession *imap, bool &ssl) -{ - - if (!sessionExisted(imap)) - return false; - - imap->_auth_capability[esp_mail_auth_capability_login] = false; - - imap->_session_cfg->int_start_tls = imap->_session_cfg->secure.startTLS; - imap->_session_cfg->int_mode = imap->_session_cfg->secure.mode; - -#if !defined(ESP_MAIL_DISABLE_SSL) -unauthenticate: -#endif - - // capabilities may change after TLS negotiation - if (!imap->checkCapabilities()) - return false; - -#if !defined(ESP_MAIL_DISABLE_SSL) - - if (imap->_session_cfg->int_mode != esp_mail_secure_mode_nonsecure) - { - // start TLS when needed or the server issues - if ((imap->_auth_capability[esp_mail_auth_capability_starttls] || imap->_session_cfg->int_start_tls || imap->_session_cfg->int_mode == esp_mail_secure_mode_ssl_tls) && !ssl) - { -#if !defined(SILENT_MODE) - printDebug(imap, - esp_mail_cb_str_2 /* "Sending STARTTLS command..." */, - esp_mail_dbg_str_1 /* "send command, STARTTLS" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - - imapSend(imap, imap->prependTag(imap_commands[esp_mail_imap_command_starttls].text).c_str(), true); - - // rfc2595 section 3.1 - imap->_imap_cmd = esp_mail_imap_cmd_starttls; - if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, false)) - return false; - -#if !defined(SILENT_MODE) - if (imap->_debug) - esp_mail_debug_print_tag(esp_mail_dbg_str_22 /* "perform SSL/TLS handshake" */, esp_mail_debug_tag_type_client, true); -#endif - - // connect in secure mode - // do TLS handshake - - if (!imap->client.connectSSL(imap->_session_cfg->certificate.verify)) - return handleIMAPError(imap, MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP, false); - - // set the secure mode - imap->_session_cfg->int_start_tls = false; - imap->_session_cfg->int_mode = esp_mail_secure_mode_undefined; - ssl = true; - imap->_secure = true; - - // check the capabilitiy again to prevent the man in the middle attack - goto unauthenticate; - } - } - -#endif - - imap->clearMessageData(); - imap->_mailboxOpened = false; - - bool creds = imap->_session_cfg->login.email.length() > 0 && imap->_session_cfg->login.password.length() > 0; - bool sasl_auth_oauth = imap->_session_cfg->login.accessToken.length() > 0 && imap->_auth_capability[esp_mail_auth_capability_xoauth2]; - bool sasl_login = creds; - bool sasl_auth_plain = imap->_auth_capability[esp_mail_auth_capability_plain] && creds; - - bool supported_sasl = sasl_auth_oauth || sasl_login || sasl_auth_plain; - - if (!supported_sasl) - return handleIMAPError(imap, IMAP_STATUS_NO_SUPPORTED_AUTH, false); - - // rfc4959 - if (supported_sasl) - { -#if !defined(SILENT_MODE) - if (imap->_statusCallback) - sendCallback(imap, esp_mail_cb_str_14 /* "Logging in..." */, true, false); - else if (imap->_debug) - debugPrintNewLine(); -#endif - } - - if (sasl_auth_oauth) - { - - if (!imap->_auth_capability[esp_mail_auth_capability_xoauth2]) - { - handleIMAPError(imap, IMAP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED, false); - return false; - } - -#if !defined(SILENT_MODE) - if (imap->_debug) - esp_mail_debug_print_tag(esp_mail_dbg_str_45 /* "send IMAP command, AUTH XOAUTH2" */, esp_mail_debug_tag_type_client, true); -#endif - - MB_String cmd; - joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_authenticate].text, imap_commands[esp_mail_imap_command_xoauth2].text); - - if (imap->_auth_capability[esp_mail_auth_capability_sasl_ir]) - { - prependSpace(cmd, getXOAUTH2String(imap->_session_cfg->login.email, imap->_session_cfg->login.accessToken).c_str()); - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - } - else - { - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - imap->_imap_cmd = esp_mail_imap_cmd_sasl_auth_oauth; - if (!handleIMAPResponse(imap, IMAP_STATUS_AUTHENTICATE_FAILED, true)) - return false; - - cmd = getXOAUTH2String(imap->_session_cfg->login.email, imap->_session_cfg->login.accessToken); - - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - } - - imap->_imap_cmd = esp_mail_imap_cmd_sasl_auth_oauth; - if (!handleIMAPResponse(imap, IMAP_STATUS_AUTHENTICATE_FAILED, false)) - return false; - } - else if (sasl_auth_plain) - { - -#if !defined(SILENT_MODE) - if (imap->_debug) - esp_mail_debug_print_tag(esp_mail_dbg_str_44 /* "send IMAP command, AUTHENTICATE PLAIN" */, esp_mail_debug_tag_type_client, true); -#endif - - int len = imap->_session_cfg->login.email.length() + imap->_session_cfg->login.password.length() + 2; - uint8_t *tmp = allocMem(len); - memset(tmp, 0, len); - int p = 1; - memcpy(tmp + p, imap->_session_cfg->login.email.c_str(), imap->_session_cfg->login.email.length()); - p += imap->_session_cfg->login.email.length() + 1; - memcpy(tmp + p, imap->_session_cfg->login.password.c_str(), imap->_session_cfg->login.password.length()); - p += imap->_session_cfg->login.password.length(); - - MB_String cmd; - joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_authenticate].text, imap_commands[esp_mail_imap_command_plain].text); - - if (imap->_auth_capability[esp_mail_auth_capability_sasl_ir]) - { - prependSpace(cmd, encodeBase64Str(tmp, p).c_str()); - // release memory - freeMem(&tmp); - - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - } - else - { - - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - imap->_imap_cmd = esp_mail_imap_cmd_sasl_auth_plain; - - if (!handleIMAPResponse(imap, IMAP_STATUS_AUTHENTICATE_FAILED, true)) - return false; - - cmd = encodeBase64Str(tmp, p); - // release memory - freeMem(&tmp); - - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - } - - imap->_imap_cmd = esp_mail_imap_cmd_sasl_auth_plain; - if (!handleIMAPResponse(imap, IMAP_STATUS_AUTHENTICATE_FAILED, true)) - return false; - } - else if (sasl_login) - { - -#if !defined(SILENT_MODE) - if (imap->_debug) - esp_mail_debug_print_tag(esp_mail_dbg_str_34 /* "send IMAP command, LOGIN" */, esp_mail_debug_tag_type_client, true); -#endif - MB_String cmd; - joinStringSpace(cmd, true, 3, imap_commands[esp_mail_imap_command_login].text, imap->_session_cfg->login.email.c_str(), imap->_session_cfg->login.password.c_str()); - - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - imap->_imap_cmd = esp_mail_imap_cmd_sasl_login; - if (!handleIMAPResponse(imap, IMAP_STATUS_AUTHENTICATE_FAILED, true)) - return false; - } - - // auto capabilities after login? - if (!imap->_feature_capability[esp_mail_imap_read_capability_auto_caps]) - { - if (!imap->checkCapabilities()) - return false; - } - - if (imap->_feature_capability[esp_mail_imap_read_capability_id]) - { - if (!imap->id(&imap->_imap_data->identification)) - return false; - } - - if (supported_sasl) - imap->_authenticated = true; - - return true; -} - -bool ESP_Mail_Client::imapLogout(IMAPSession *imap) -{ - -#if defined(ESP8266) - return false; -#endif - - if (!sessionExisted(imap)) - return false; - -#if !defined(SILENT_MODE) - printDebug(imap, - esp_mail_cb_str_20 /* "Logging out..." */, - esp_mail_dbg_str_38 /* "send IMAP command, LOGOUT" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - - if (imapSend(imap, imap->prependTag(imap_commands[esp_mail_imap_command_logout].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - imap->_imap_cmd = esp_mail_imap_cmd_logout; - if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - imap->_authenticated = false; - -#if !defined(SILENT_MODE) - printDebug(imap, - esp_mail_cb_str_47 /* "Log out completed" */, - esp_mail_dbg_str_31 /* "log out completed" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - return true; -} - -size_t ESP_Mail_Client::imapSend(IMAPSession *imap, PGM_P data, bool newline) -{ - if (!imap || !sessionReady(imap)) - return 0; - - int sent = 0; - - MB_String s = data; - - int toSend = newline ? s.length() + 2 : s.length(); - - if (imap->_debug && imap->_debugLevel > esp_mail_debug_level_maintainer && !imap->_customCmdResCallback) - esp_mail_debug_print(s.c_str(), newline); - - sent = newline ? imap->client.println(s.c_str()) : imap->client.print(s.c_str()); - - if (sent != toSend) - { - errorStatusCB(imap, nullptr, sent, true); - sent = 0; - } - - return sent; -} - -size_t ESP_Mail_Client::imapSend(IMAPSession *imap, int data, bool newline) -{ - MB_String s = data; - return imapSend(imap, s.c_str(), newline); -} - -size_t ESP_Mail_Client::imapSend(IMAPSession *imap, uint8_t *data, size_t size) -{ - if (!imap || !sessionReady(imap)) - return 0; - - int sent = 0; - - sent = imap->client.write(data, size); - - if (sent != (int)size) - { - errorStatusCB(imap, nullptr, sent, true); - sent = 0; - } - - return sent; -} - -bool ESP_Mail_Client::mSetFlag(IMAPSession *imap, MB_StringPtr sequenceSet, MB_StringPtr flag, esp_mail_imap_store_flag_type type, bool closeSession, bool silent, bool UID, int32_t modsequence) -{ - if (!reconnect(imap)) - return false; - - if (!imap->connected()) - { - imap->_mailboxOpened = false; - return false; - } - - if (imap->_currentFolder.length() == 0) - { -#if !defined(SILENT_MODE) - printDebug(imap, - esp_mail_error_imap_str_11 /* "no mailbox opened" */, - esp_mail_error_imap_str_11 /* "no mailbox opened" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - } - else - { - if (imap->_readOnlyMode || !imap->_mailboxOpened) - { - if (!imap->selectFolder(imap->_currentFolder.c_str(), false)) - return false; - } - } - -#if !defined(SILENT_MODE) - PGM_P p1 = NULL; - PGM_P p2 = NULL; - if (type == esp_mail_imap_store_flag_type_set) - { - p1 = esp_mail_cb_str_26; /* "Setting FLAG..." */ - p2 = esp_mail_dbg_str_41; /* "setting FLAG" */ - } - else if (type == esp_mail_imap_store_flag_type_add) - { - p1 = esp_mail_cb_str_24; /* "Adding FLAG..." */ - p2 = esp_mail_dbg_str_42; /* "adding FLAG" */ - } - else - { - p1 = esp_mail_cb_str_23; /* "Removing FLAG..." */ - p2 = esp_mail_dbg_str_43; /* "removing FLAG" */ - } - - printDebug(imap, - p1, - p2, - esp_mail_debug_tag_type_client, - true, - false); -#endif - - if (!sessionExisted(imap)) - return false; - - MB_String cmd; - if (UID) - appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_store].text); - else - appendSpace(cmd, true, imap_commands[esp_mail_imap_command_store].text); - - cmd += sequenceSet; - - imap->addModifier(cmd, esp_mail_imap_command_unchangedsince, modsequence); - - if (type == esp_mail_imap_store_flag_type_set) - cmd += imap_cmd_pre_tokens[esp_mail_imap_command_flags]; - else if (type == esp_mail_imap_store_flag_type_add) - cmd += imap_cmd_pre_tokens[esp_mail_imap_command_plus_flags]; - else - cmd += imap_cmd_pre_tokens[esp_mail_imap_command_minus_flags]; - - if (silent) - prependDot(cmd, imap_commands[esp_mail_imap_command_silent].text); - - appendSpace(cmd); - appendString(cmd, MB_String(flag).c_str(), false, false, esp_mail_string_mark_type_round_bracket); - - if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - imap->_imap_cmd = esp_mail_imap_cmd_store; - - if (!handleIMAPResponse(imap, IMAP_STATUS_STORE_FAILED, false)) - return false; - - if (closeSession) - imap->closeSession(); - - return true; -} - -int ESP_Mail_Client::parseSearchResponse(IMAPSession *imap, esp_mail_imap_response_data &res, PGM_P tag, const char *key) -{ - int bufLen = res.chunkBufSize; - int ret = -1; - char c = 0; - int idx = 0; - int num = 0; - - size_t tagLen = strlen_P(tag); - MB_String _tag = tag; - - while (imap->client.available() > 0 && idx < bufLen) - { - yield_impl(); - - ret = imap->client.read(); - - if (ret > -1) - { - - if (idx >= bufLen - 1) - return idx; - - c = (char)ret; - - if (c == '\n') - c = ' '; - - res.response[idx++] = c; - - if (res.chunkIdx == 0) - { - // Search response parsing - if (strcmp(res.response, key) == 0) - { - res.chunkIdx++; - return 0; - } - else - { - // Status response parsing - res.imapResp = imapResponseStatus(imap, res.response, esp_mail_imap_tag_str); - - // Exit if error or complete (no messages found) - if (res.imapResp != esp_mail_imap_resp_unknown) - goto end_search; - } - } - else - { - if (c == ' ') - { - imap->_mbif._searchCount++; - if (imap->_imap_data->enable.recent_sort) - { - esp_mail_imap_msg_num_t msg_num; - msg_num.type = imap->_uidSearch ? esp_mail_imap_msg_num_type_uid : esp_mail_imap_msg_num_type_number; - msg_num.value = (uint32_t)atoi(res.response); - - imap->_imap_msg_num.push_back(msg_num); - - if (imap->_imap_msg_num.size() > imap->_imap_data->limit.search) - imap->_imap_msg_num.erase(imap->_imap_msg_num.begin()); - } - else - { - if (imap->_imap_msg_num.size() < imap->_imap_data->limit.search) - { - esp_mail_imap_msg_num_t msg_num; - msg_num.type = imap->_uidSearch ? esp_mail_imap_msg_num_type_uid : esp_mail_imap_msg_num_type_number; - msg_num.value = (uint32_t)atoi(res.response); - - imap->_imap_msg_num.push_back(msg_num); - } - } - - if (imap->_debug) - { - num = (float)(100.0f * imap->_mbif._searchCount / imap->_mbif._msgCount); - if (res.searchCount != num) - { - res.searchCount = num; - searchReport(imap, num); - } - } - - res.chunkIdx++; - return idx; - } - else if (idx >= (int)tagLen) - { - if (strpos(res.response, _tag.c_str(), 0, false) > -1) - { -#if defined(MB_USE_STD_VECTOR) - if (imap->_imap_data->enable.recent_sort) - std::sort(imap->_imap_msg_num.begin(), imap->_imap_msg_num.end(), compareMore); -#else - if (imap->_imap_data->enable.recent_sort) - numDecSort(imap->_imap_msg_num); -#endif - goto end_search; - } - } - } - } - } - - return idx; - -end_search: - - res.endSearch = true; - int read = imap->client.available(); - read = imap->client.readBytes(res.response + idx, read); - return idx + read; -} - -#if !defined(MB_USE_STD_VECTOR) -void ESP_Mail_Client::numDecSort(_vectorImpl &arr) -{ - - struct esp_mail_imap_msg_num_t tmp; - - for (size_t i = 0; i < arr.size(); ++i) - { - for (size_t j = i + 1; j < arr.size(); ++j) - { - if (arr[i].value < arr[j].value) - { - tmp = arr[i]; - arr[i] = arr[j]; - arr[j] = tmp; - } - } - } -} -#endif - -struct esp_mail_message_part_info_t *ESP_Mail_Client::cPart(IMAPSession *imap) -{ - if (cHeader(imap) && imap->_cPartIdx < (int)cHeader(imap)->part_headers.size()) - return &cHeader(imap)->part_headers[imap->_cPartIdx]; - return nullptr; -} - -struct esp_mail_message_header_t *ESP_Mail_Client::cHeader(IMAPSession *imap) -{ - if (cIdx(imap) < (int)imap->_headers.size()) - return &imap->_headers[cIdx(imap)]; - return nullptr; -} - -bool ESP_Mail_Client::parseHeaderField(IMAPSession *imap, const char *buf, PGM_P beginToken, bool caseSensitive, struct esp_mail_message_header_t &header, int &headerState, int state) -{ - if (strcmpP(buf, 0, beginToken, caseSensitive)) - { - headerState = state; - char *tmp = subStr(buf, beginToken, NULL, 0, -1, caseSensitive); - if (tmp) - { - collectHeaderField(imap, tmp, header, headerState); - // release memory - freeMem(&tmp); - return true; - } - } - - return false; -} - -void ESP_Mail_Client::parseHeaderResponse(IMAPSession *imap, esp_mail_imap_response_data &res, bool caseSensitive) -{ - char *tmp = nullptr; - if (res.chunkIdx == 0) - { - MB_String str; - joinStringDot(str, 2, imap_commands[esp_mail_imap_command_header].text, imap_commands[esp_mail_imap_command_fields].text); - - if (!res.isUntaggedResponse && strposP(res.response, str.c_str(), 0, caseSensitive) != -1 && res.response[0] == '*') - res.isUntaggedResponse = true; - - if (res.isUntaggedResponse && res.response[strlen(res.response) - 1] == '}') - res.untaggedRespCompleted = true; - - if (res.isUntaggedResponse && res.header.message_no == 0) - { - tmp = subStr(res.response, imap_responses[esp_mail_imap_response_untagged].text, imap_responses[esp_mail_imap_response_fetch].text, 0); - if (tmp) - { - res.header.message_no = atoi(tmp); - // release memory - freeMem(&tmp); - } - } - - if (res.isUntaggedResponse && res.untaggedRespCompleted) - { - tmp = subStr(res.response, esp_mail_str_36 /* "{" */, esp_mail_str_37 /* "}" */, 0, 0, caseSensitive); - if (tmp) - { - res.octetCount = 2; - res.header.header_data_len = atoi(tmp); - // release memory - freeMem(&tmp); - res.chunkIdx++; - } - } - } - else - { - if (res.octetCount > res.header.header_data_len + 2) - return; - - res.chunkIdx++; - - MB_String field; - - for (int i = esp_mail_rfc822_header_field_from; i < esp_mail_rfc822_header_field_maxType; i++) - { - appendHeaderName(field, rfc822_headers[i].text, true, false, false); - if (parseHeaderField(imap, res.response, field.c_str(), caseSensitive, res.header, res.headerState, i)) - return; - } - - appendHeaderName(field, message_headers[esp_mail_message_header_field_content_transfer_encoding].text, true, true, false); - - if (parseHeaderField(imap, res.response, field.c_str(), caseSensitive, res.header, res.headerState, esp_mail_imap_state_content_transfer_encoding)) - return; - - appendHeaderName(field, message_headers[esp_mail_message_header_field_accept_language].text, true, true, false); - - if (parseHeaderField(imap, res.response, field.c_str(), caseSensitive, res.header, res.headerState, esp_mail_imap_state_accept_language)) - return; - - appendHeaderName(field, message_headers[esp_mail_message_header_field_content_language].text, true, true, false); - - if (parseHeaderField(imap, res.response, field.c_str(), caseSensitive, res.header, res.headerState, esp_mail_imap_state_content_language)) - return; - - MB_String contentTypeName; - appendHeaderName(contentTypeName, message_headers[esp_mail_message_header_field_content_type].text, false, false, false); - if (strcmpP(res.response, 0, contentTypeName.c_str(), caseSensitive)) - { - res.headerState = esp_mail_imap_state_content_type; - tmp = subStr(res.response, contentTypeName.c_str(), esp_mail_str_35 /* ";" */, 0, 0, caseSensitive); - if (tmp) - { - // We set attachment status here as attachment should be included in multipart/mixed message, - // unless no real attachments included which we don't know until fetching the sub part. - if (strpos(tmp, esp_mail_imap_multipart_sub_type_t::mixed, 0, caseSensitive) != -1) - res.header.hasAttachment = true; - - collectHeaderField(imap, res.response, res.header, res.headerState); - // release memory - freeMem(&tmp); - } - } - } -} - -void ESP_Mail_Client::collectHeaderField(IMAPSession *imap, char *buf, struct esp_mail_message_header_t &header, int state) -{ - size_t i = 0; - while (buf[i] == ' ') - { - i++; - if (strlen(buf) <= i) - return; - } - - if (state < esp_mail_rfc822_header_field_maxType) - { - int ptr = getRFC822HeaderPtr(state, &header.header_fields); - if (ptr > 0) - { - *(addrTo(ptr)) += &buf[i]; - } - return; - } - - switch (state) - { - case esp_mail_imap_state_content_type: - header.content_type += &buf[i]; - break; - case esp_mail_imap_state_content_transfer_encoding: - header.content_transfer_encoding += &buf[i]; - break; - case esp_mail_imap_state_accept_language: - header.accept_language += &buf[i]; - break; - case esp_mail_imap_state_content_language: - header.content_language += &buf[i]; - break; - case esp_mail_imap_state_char_set: - header.char_set += &buf[i]; - break; - case esp_mail_imap_state_boundary: - header.boundary += &buf[i]; - break; - default: - break; - } -} - -bool ESP_Mail_Client::getDecodedHeader(IMAPSession *imap, const char *buf, PGM_P beginToken, MB_String &out, bool caseSensitive) -{ - if (getHeader(buf, beginToken, out, caseSensitive)) - { - // decode header text - decodeString(imap, out); - return true; - } - return false; -} - -void ESP_Mail_Client::checkFirmwareFile(IMAPSession *imap, const char *filename, struct esp_mail_message_part_info_t &part, bool defaultSize) -{ - if (strcmp(filename, imap->_imap_data->firmware_update.attach_filename.c_str()) == 0 && part.attach_type == esp_mail_att_type_attachment) - { - part.is_firmware_file = true; - // If no file size prop from Content-Disposition header - if (part.attach_data_size == 0 && defaultSize) - { -#if defined(ESP32) || defined(ESP8266) - int sketchFreeSpace = ESP.getFreeSketchSpace(); - part.attach_data_size = sketchFreeSpace ? sketchFreeSpace : 1024000; -#elif defined(MB_ARDUINO_PICO) - size_t spiffsSize = ((size_t)&_FS_end - (size_t)&_FS_start); - part.attach_data_size = spiffsSize ? spiffsSize / 2 : 1024000; -#endif - } - - if (!imap->_imap_data->firmware_update.save_to_file) - part.save_to_file = false; - } -} - -void ESP_Mail_Client::parsePartHeaderResponse(IMAPSession *imap, esp_mail_imap_response_data &res, bool caseSensitive) -{ - char *tmp = nullptr; - if (res.chunkIdx == 0) - { - tmp = subStr(res.response, imap_responses[esp_mail_imap_response_fetch].text, NULL, 0, -1); - if (tmp) - { - // release memory - freeMem(&tmp); - tmp = subStr(res.response, esp_mail_str_36 /* "{" */, esp_mail_str_37 /* "}" */, 0); - if (tmp) - { - res.chunkIdx++; - res.part.octetLen = atoi(tmp); - res.octetCount = 2; - // release memory - freeMem(&tmp); - } - } - } - else - { - MB_String value, old_value; - bool valueStored = false; - res.chunkIdx++; - - // if all octets read - - if (res.octetCount > res.part.octetLen) - { - - // Is inline attachment without content id or name or filename? - // It is supposed to be the inline message txt content, reset attach type to none - - if (res.part.attach_type == esp_mail_att_type_inline && res.part.CID.length() == 0) - res.part.attach_type = esp_mail_att_type_none; - - // Is attachment file extension missing? - // append extension - - if (res.part.attach_type == esp_mail_att_type_inline || res.part.attach_type == esp_mail_att_type_attachment) - { - if (res.part.filename.length() > 0 && res.part.filename.find('.') == MB_String::npos) - { - MB_String ext; - getExtfromMIME(res.part.content_type.c_str(), ext); - res.part.filename += ext; - } - - checkFirmwareFile(imap, res.part.filename.c_str(), res.part); - } - - return; - } - - // Content header field parse - if (strcmpP(res.response, 0, esp_mail_str_56 /* "content-" */, caseSensitive)) - { - // Content-Type - MB_String contentTypeName; - appendHeaderName(contentTypeName, message_headers[esp_mail_message_header_field_content_type].text, false, false, false); - if (strcmpP(res.response, 0, contentTypeName.c_str(), caseSensitive)) - { - - res.part.cur_content_hdr = esp_mail_message_part_info_t::content_header_field_type; - resetStringPtr(res.part); - - tmp = subStr(res.response, contentTypeName.c_str(), esp_mail_str_35 /* ";" */, 0, 0, caseSensitive); - if (tmp) - { - res.part.content_type = tmp; - // release memory - freeMem(&tmp); - int p1 = strposP(res.part.content_type.c_str(), esp_mail_imap_composite_media_type_t::multipart, 0, caseSensitive); - if (p1 != -1) - { - p1 += strlen(esp_mail_imap_composite_media_type_t::multipart) + 1; - res.part.multipart = true; - // inline or embedded images - if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::related, p1, caseSensitive) != -1) - res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_related; - // multiple text formats e.g. plain, html, enriched - else if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::alternative, p1, caseSensitive) != -1) - res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_alternative; - // medias - else if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::parallel, p1, caseSensitive) != -1) - res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_parallel; - // rfc822 encapsulated - else if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::digest, p1, caseSensitive) != -1) - res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_digest; - else if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::report, p1, caseSensitive) != -1) - res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_report; - // others can be attachments - else if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::mixed, p1, caseSensitive) != -1) - res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_mixed; - } - - p1 = strposP(res.part.content_type.c_str(), esp_mail_imap_composite_media_type_t::message, 0, caseSensitive); - if (p1 != -1) - { - p1 += strlen(esp_mail_imap_composite_media_type_t::message) + 1; - if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::rfc822, p1, caseSensitive) != -1) - res.part.message_sub_type = esp_mail_imap_message_sub_type_rfc822; - else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::Partial, p1, caseSensitive) != -1) - res.part.message_sub_type = esp_mail_imap_message_sub_type_partial; - else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::External_Body, p1, caseSensitive) != -1) - res.part.message_sub_type = esp_mail_imap_message_sub_type_external_body; - else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::delivery_status, p1, caseSensitive) != -1) - res.part.message_sub_type = esp_mail_imap_message_sub_type_delivery_status; - } - - p1 = strpos(res.part.content_type.c_str(), esp_mail_imap_descrete_media_type_t::text, 0, caseSensitive); - if (p1 != -1) - { - p1 += strlen(esp_mail_imap_descrete_media_type_t::text) + 1; - if (strpos(res.part.content_type.c_str(), esp_mail_imap_media_text_sub_type_t::plain, p1, caseSensitive) != -1) - res.part.msg_type = esp_mail_msg_type_plain; - else if (strpos(res.part.content_type.c_str(), esp_mail_imap_media_text_sub_type_t::enriched, p1, caseSensitive) != -1) - res.part.msg_type = esp_mail_msg_type_enriched; - else if (strpos(res.part.content_type.c_str(), esp_mail_imap_media_text_sub_type_t::html, p1, caseSensitive) != -1) - res.part.msg_type = esp_mail_msg_type_html; - else - res.part.msg_type = esp_mail_msg_type_plain; - } - } - } - - // Content-Description - MB_String contentDescrName; - appendHeaderName(contentDescrName, message_headers[esp_mail_message_header_field_content_description].text, false, true, false); - if (getDecodedHeader(imap, res.response, contentDescrName.c_str(), res.part.descr, caseSensitive)) - { - res.part.cur_content_hdr = esp_mail_message_part_info_t::content_header_field_description; - - tmp = subStr(res.response, contentDescrName.c_str(), NULL, 0, -1, caseSensitive); - if (tmp) - { - value = tmp; - // release memory - freeMem(&tmp); - - res.part.stringPtr = toAddr(res.part.content_description); - value.trim(); - if (value.length() == 0) - return; - } - } - - // Content-ID - MB_String contentIdName; - appendHeaderName(contentIdName, message_headers[esp_mail_message_header_field_content_id].text, false, true, false); - if (strcmpP(res.response, 0, contentIdName.c_str(), caseSensitive)) - { - tmp = subStr(res.response, contentIdName.c_str(), NULL, 0, -1, caseSensitive); - if (tmp) - { - res.part.CID = tmp; - // release memory - freeMem(&tmp); - res.part.CID.trim(); - - if (res.part.CID[0] == '<') - res.part.CID.erase(0, 1); - - if (res.part.CID[res.part.CID.length() - 1] == '>') - res.part.CID.erase(res.part.CID.length() - 1, 1); - - // if inline attachment file name was not assigned - if (res.part.attach_type == esp_mail_att_type_inline && res.part.filename.length() == 0) - { - // set filename from content id and append extension later - res.part.filename = res.part.CID; - res.part.name = res.part.filename; - } - } - - res.part.cur_content_hdr = esp_mail_message_part_info_t::content_header_field_id; - resetStringPtr(res.part); - } - - // Content-Disposition - MB_String contentDispositionName; - appendHeaderName(contentDispositionName, message_headers[esp_mail_message_header_field_content_disposition].text, false, true, false); - if (strcmpP(res.response, 0, contentDispositionName.c_str(), caseSensitive)) - { - - res.part.cur_content_hdr = esp_mail_message_part_info_t::content_header_field_disposition; - resetStringPtr(res.part); - - tmp = subStr(res.response, contentDispositionName.c_str(), esp_mail_str_35 /* ";" */, 0, 0, caseSensitive); - if (tmp) - { - // don't count altenative part text and html as embedded contents - if (cHeader(imap)->multipart_sub_type != esp_mail_imap_multipart_sub_type_alternative) - { - res.part.content_disposition = tmp; - if (caseSensitive) - { - if (strcmp(tmp, esp_mail_content_disposition_type_t::attachment) == 0) - res.part.attach_type = esp_mail_att_type_attachment; - else if (strcmp(tmp, esp_mail_content_disposition_type_t::inline_) == 0) - res.part.attach_type = esp_mail_att_type_inline; - } - else - { - if (strcasecmp(tmp, esp_mail_content_disposition_type_t::attachment) == 0) - res.part.attach_type = esp_mail_att_type_attachment; - else if (strcasecmp(tmp, esp_mail_content_disposition_type_t::inline_) == 0) - res.part.attach_type = esp_mail_att_type_inline; - } - } - // release memory - freeMem(&tmp); - } - } - - // Content-Transfer-Encoding - MB_String contentTEName; - appendHeaderName(contentTEName, message_headers[esp_mail_message_header_field_content_transfer_encoding].text, false, true, false); - if (strcmpP(res.response, 0, contentTEName.c_str(), caseSensitive)) - { - // store last text field - - res.part.cur_content_hdr = esp_mail_message_part_info_t::content_header_field_transfer_enc; - resetStringPtr(res.part); - - tmp = subStr(res.response, contentTEName.c_str(), NULL, 0, -1, caseSensitive); - if (tmp) - { - res.part.content_transfer_encoding = tmp; - - if (strcmpP(tmp, 0, esp_mail_transfer_encoding_t::enc_base64)) - res.part.xencoding = esp_mail_msg_xencoding_base64; - else if (strcmpP(tmp, 0, esp_mail_transfer_encoding_t::enc_qp)) - res.part.xencoding = esp_mail_msg_xencoding_qp; - else if (strcmpP(tmp, 0, esp_mail_transfer_encoding_t::enc_7bit)) - res.part.xencoding = esp_mail_msg_xencoding_7bit; - else if (strcmpP(tmp, 0, esp_mail_transfer_encoding_t::enc_8bit)) - res.part.xencoding = esp_mail_msg_xencoding_8bit; - else if (strcmpP(tmp, 0, esp_mail_transfer_encoding_t::enc_binary)) - res.part.xencoding = esp_mail_msg_xencoding_binary; - // release memory - freeMem(&tmp); - } - } - } - else - { - - if (res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_none) - { - - resetStringPtr(res.part); - - MB_String field; - for (int i = esp_mail_rfc822_header_field_from; i < esp_mail_rfc822_header_field_maxType; i++) - { - field = rfc822_headers[i].text; - field += esp_mail_str_34; /* ":" */ - ; - - int ptr = getRFC822HeaderPtr(i, &res.part.rfc822_header); - if (ptr > 0) - { - if (getDecodedHeader(imap, res.response, field.c_str(), *(addrTo(ptr)), caseSensitive)) - return; - } - } - } - } - - // parse content type header sub type properties - if (res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_type) - { - - if (res.part.msg_type == esp_mail_msg_type_plain || res.part.msg_type == esp_mail_msg_type_enriched) - { - MB_String charset; - appendLowerCaseString(charset, message_headers[esp_mail_message_header_field_charset].text, false); - // We have to check for both quotes string or non quote string - if (getPartHeaderProperties(imap, res.response, charset.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) - { - res.part.charset = value; - resetStringPtr(res.part); - } - else if (getPartHeaderProperties(imap, res.response, charset.c_str(), esp_mail_str_35 /* ";" */, true, value, old_value, res.part.stringEnc, caseSensitive)) - { - res.part.charset = value; - resetStringPtr(res.part); - } - - if (strposP(res.response, esp_mail_str_59 /* "format=flowed" */, 0, caseSensitive) > -1 || strposP(res.response, esp_mail_str_58 /* "format=\"flowed\"" */, 0, caseSensitive) > -1) - { - res.part.plain_flowed = true; - resetStringPtr(res.part); - } - - if (strposP(res.response, esp_mail_str_61 /* "delsp=yes" */, 0, caseSensitive) > -1 || strposP(res.response, esp_mail_str_60 /* "delsp=\"yes\"" */, 0, caseSensitive) > -1) - { - res.part.plain_delsp = true; - resetStringPtr(res.part); - } - } - - if (res.part.charset.length() == 0) - { - MB_String charset; - appendLowerCaseString(charset, message_headers[esp_mail_message_header_field_charset].text, false); - // We have to check for both quotes string or non quote string - if (getPartHeaderProperties(imap, res.response, charset.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) - { - res.part.charset = value; - resetStringPtr(res.part); - } - else if (getPartHeaderProperties(imap, res.response, charset.c_str(), esp_mail_str_35 /* ";" */, true, value, old_value, res.part.stringEnc, caseSensitive)) - { - res.part.charset = value; - resetStringPtr(res.part); - } - } - - MB_String name; - appendLowerCaseString(name, message_headers[esp_mail_message_header_field_name].text, false); - // We have to check for both quotes string or non quote string - if (getPartHeaderProperties(imap, res.response, name.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) - { - res.part.stringPtr = toAddr(res.part.name); - value.trim(); - if (value.length() == 0) - return; - } - else if (getPartHeaderProperties(imap, res.response, name.c_str(), esp_mail_str_35 /* ";" */, true, value, old_value, res.part.stringEnc, caseSensitive)) - { - res.part.stringPtr = toAddr(res.part.name); - value.trim(); - if (value.length() == 0) - return; - } - } - - // parse content disposition header sub type properties - if (res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_disposition && res.part.content_disposition.length() > 0) - { - // filename prop - MB_String filename; - appendLowerCaseString(filename, message_headers[esp_mail_message_header_field_filename].text, false); - // We have to check for both quotes string or non quote string - if (getPartHeaderProperties(imap, res.response, filename.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) - { - res.part.stringPtr = toAddr(res.part.filename); - value.trim(); - if (value.length() == 0) - return; - } - else if (getPartHeaderProperties(imap, res.response, filename.c_str(), esp_mail_str_35 /* ";" */, true, value, old_value, res.part.stringEnc, caseSensitive)) - { - res.part.stringPtr = toAddr(res.part.filename); - value.trim(); - if (value.length() == 0) - return; - } - - // size prop - MB_String size; - appendLowerCaseString(size, message_headers[esp_mail_message_header_field_size].text, false); - - if (getPartHeaderProperties(imap, res.response, size.c_str(), esp_mail_str_35 /* ";" */, true, value, old_value, res.part.stringEnc, caseSensitive)) - { - res.part.attach_data_size = atoi(value.c_str()); - cHeader(imap)->total_attach_data_size += res.part.attach_data_size; - res.part.sizeProp = true; - - if (!valueStored && old_value.length() > 0) - valueStored = storeStringPtr(imap, res.part.stringPtr, old_value, res.response); - resetStringPtr(res.part); - } - - // creation date prop - MB_String creationDate; - appendLowerCaseString(creationDate, message_headers[esp_mail_message_header_field_creation_date].text, false); - - if (getPartHeaderProperties(imap, res.response, creationDate.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) - { - res.part.creation_date = value; - if (!valueStored && old_value.length() > 0) - valueStored = storeStringPtr(imap, res.part.stringPtr, old_value, res.response); - resetStringPtr(res.part); - } - - // mod date prop - MB_String modDate; - appendLowerCaseString(modDate, message_headers[esp_mail_message_header_field_modification_date].text, false); - - if (getPartHeaderProperties(imap, res.response, modDate.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) - { - res.part.modification_date = value; - if (!valueStored && old_value.length() > 0) - valueStored = storeStringPtr(imap, res.part.stringPtr, old_value, res.response); - resetStringPtr(res.part); - } - } - - if (!valueStored && (res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_description || res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_type || res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_disposition)) - storeStringPtr(imap, res.part.stringPtr, value, res.response); - } -} - -void ESP_Mail_Client::resetStringPtr(struct esp_mail_message_part_info_t &part) -{ - part.stringPtr = 0; - part.stringEnc = esp_mail_char_decoding_scheme_default; -} - -int ESP_Mail_Client::countChar(const char *buf, char find) -{ - if (!buf) - return 0; - - int count = 0; - - for (size_t i = 0; i < strlen(buf); i++) - { - if (buf[i] == find) - count++; - } - - return count; -} - -bool ESP_Mail_Client::storeStringPtr(IMAPSession *imap, uint32_t addr, MB_String &value, const char *buf) -{ - if (addr) - { - MB_String *a = addrTo(addr); - MB_String s = value.length() > 0 ? value : buf; - - // is value string contains double quotes? - // trim it - if (countChar(s.c_str(), '"') == 2) - s.trim(); - - if (s[0] == '"') - s.erase(0, 1); - - if (s[s.length() - 1] == '"') - s.erase(s.length() - 1, 1); - - decodeString(imap, s); - - *a += s; - - return true; - } - - return false; -} - -bool ESP_Mail_Client::getPartHeaderProperties(IMAPSession *imap, const char *buf, PGM_P p, PGM_P e, bool num, MB_String &value, MB_String &old_value, esp_mail_char_decoding_scheme &scheme, bool caseSensitive) -{ - - MB_String str = p; - str += esp_mail_str_7; /* "=" */ - if (!num) - str += esp_mail_str_11; /* "\"" */ - - char *tmp = subStr(buf, str.c_str(), e, 0, 0, caseSensitive); - if (!tmp) - { - str = p; - str += esp_mail_str_7; /* "=" */ - tmp = subStr(buf, str.c_str(), e, 0, 0, caseSensitive); - if (tmp) - { - // other sub headers found? - int p2 = strposP(tmp, esp_mail_str_35 /* ";" */, 0, caseSensitive); - if (p2 > -1) - { - // release memory - freeMem(&tmp); - tmp = subStr(buf, str.c_str(), esp_mail_str_35 /* ";" */, 0, 0, caseSensitive); - } - // release memory in case above condition does not match - freeMem(&tmp); - } - else - { - // Extended notation rfc5987 - str = p; - str += esp_mail_str_3; /* "*" */ - int p2 = strpos(buf, str.c_str(), 0, caseSensitive); - if (p2 > -1) - { - int p3 = strposP(buf, esp_mail_str_3 /* "*" */, p2 + str.length() + 1, caseSensitive); - if (p3 > -1 && p3 < (int)strlen(buf)) - { - MB_String charset; - - p3 += 2; - - int p4 = strpos(buf, "'", p3, caseSensitive); - if (p4 > -1) - { - - scheme = getEncodingFromCharset(buf); - int c1 = p4 + 1; - p4 = strpos(buf, "'", p4 + 1, caseSensitive); - int c2 = p4; - if (c2 > -1) - { - charset.append(buf + c1, c2 - c1); - } - p3 = p4 + 1; - } - - int len = strlen(buf) - p3; - tmp = allocMem(len + 1); - - if (buf[strlen(buf) - 1] == ';') - len--; - - memcpy(tmp, &buf[p3], len); - - if (scheme == esp_mail_char_decoding_scheme_utf_8) - { - char *buf2 = urlDecode(tmp); - // release memory and point to new buffer - freeMem(&tmp); - tmp = buf2; - } - else if (imap->_charDecCallback) - { - IMAP_Decoding_Info decoding; - decoding.charset = charset.c_str(); - decoding.data = tmp; - decoding.type = IMAP_Decoding_Info::message_part_type_header; - - imap->_charDecCallback(&decoding); - - if (decoding.decodedString.length() > 0) - { - char *buf2 = allocMem(decoding.decodedString.length() + 1); - strcpy(buf2, decoding.decodedString.c_str()); - // release memory and point to new buffer - freeMem(&tmp); - tmp = buf2; - } - } - else if (scheme == esp_mail_char_decoding_scheme_iso8859_1) - { - int ilen = strlen(tmp); - int olen = (ilen + 1) * 2; - char *buf2 = allocMem(olen); - decodeLatin1_UTF8((unsigned char *)buf2, &olen, (unsigned char *)tmp, &ilen); - // release memory and point to new buffer - freeMem(&tmp); - tmp = buf2; - } - else if (scheme == esp_mail_char_decoding_scheme_tis_620 || scheme == esp_mail_char_decoding_scheme_iso8859_11 || scheme == esp_mail_char_decoding_scheme_windows_874) - { - int ilen = strlen(tmp); - char *buf2 = allocMem((ilen + 1) * 3); - decodeTIS620_UTF8(buf2, tmp, ilen); - // release memory and point to new buffer - freeMem(&tmp); - tmp = buf2; - } - } - } - } - } - - if (tmp) - { - old_value = value; - value = tmp; - // release memory - freeMem(&tmp); - return true; - } - - return false; -} - -char *ESP_Mail_Client::urlDecode(const char *str) -{ - int d = 0; /* whether or not the string is decoded */ - char *dStr = allocMem(strlen(str) + 1); - char eStr[] = "00"; /* for a hex code */ - - strcpy(dStr, str); - - while (!d) - { - d = 1; - size_t i; /* the counter for the string */ - - for (i = 0; i < strlen(dStr); ++i) - { - - if (dStr[i] == '%') - { - if (dStr[i + 1] == 0) - return dStr; - - if (isxdigit(dStr[i + 1]) && isxdigit(dStr[i + 2])) - { - d = 0; - - /* combine the next to numbers into one */ - eStr[0] = dStr[i + 1]; - eStr[1] = dStr[i + 2]; - - /* convert it to decimal */ - long int x = strtol(eStr, NULL, 16); - - /* remove the hex */ - memmove(&dStr[i + 1], &dStr[i + 3], strlen(&dStr[i + 3]) + 1); - - dStr[i] = x; - } - } - } - } - - return dStr; -} - -bool ESP_Mail_Client::handleIMAPResponse(IMAPSession *imap, int errCode, bool closeSession) -{ - - if (!reconnect(imap)) - return false; - - esp_mail_imap_response_data res(imap->client.available()); - imap->_lastProgress = -1; - - // Flag used for CRLF inclusion in response reading in case 8bit/binary attachment and base64 encoded and binary messages - bool withLineBreak = imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text && (cPart(imap)->xencoding == esp_mail_msg_xencoding_base64 || cPart(imap)->xencoding == esp_mail_msg_xencoding_binary); - withLineBreak |= imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment && cPart(imap)->xencoding != esp_mail_msg_xencoding_base64; - - // custom cmd IDLE?, waiting incoming server response - if (res.chunkBufSize == 0 && imap->_prev_imap_custom_cmd == imap->_imap_custom_cmd && imap->_imap_custom_cmd == esp_mail_imap_cmd_idle) - { - if (!reconnect(imap)) - return false; - - return true; - } - - while (imap->connected() && res.chunkBufSize <= 0) - { - - if (!reconnect(imap, res.dataTime)) - return false; - - if (!connected(imap)) - { -#if defined(ESP32) - if (imap->_imap_cmd == esp_mail_imap_cmd_logout) // suppress the error due to server closes the connection immediately in ESP32 core v2.0.4 - return true; -#endif - if (millis() - imap->_last_network_error_ms > 1000) - { - imap->_last_network_error_ms = millis(); - errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, true); - } - - return false; - } - res.chunkBufSize = imap->client.available(); - yield_impl(); - } - - res.dataTime = millis(); - - if (res.chunkBufSize > 0) - { - if (imap->_imap_cmd == esp_mail_imap_cmd_examine) - { - imap->_mbif.clear(); - imap->_nextUID.clear(); - imap->_unseenMsgIndex.clear(); - } - - if (imap->_imap_cmd == esp_mail_imap_cmd_search) - { - imap->_mbif._searchCount = 0; - imap->_imap_msg_num.clear(); - } - - // response buffer - res.chunkBufSize = ESP_MAIL_CLIENT_RESPONSE_BUFFER_SIZE; - res.response = allocMem(res.chunkBufSize + 1); - - if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) - res.lastBuf = allocMem(BASE64_CHUNKED_LEN + 1); - - while (!res.completedResponse) // looking for operation finishing - { - yield_impl(); - - if (imap->_imap_cmd == esp_mail_imap_cmd_append || (imap->_imap_custom_cmd == esp_mail_imap_cmd_append && imap->_imap_cmd == esp_mail_imap_cmd_custom && imap->_customCmdResCallback)) - { - // No waiting time out for APPEND - res.dataTime = millis(); - } - - if (!reconnect(imap, res.dataTime) || !connected(imap)) - { - - if (!connected(imap)) - { - - if (cPart(imap) && cPart(imap)->file_open_write) - mbfs->close(mbfs_type imap->_imap_data->storage.type); - -#if defined(ESP32) - if (imap->_imap_cmd == esp_mail_imap_cmd_logout) // suppress the error due to server closes the connection immediately in ESP32 core v2.0.4 - return true; -#endif - - if (millis() - imap->_last_network_error_ms > 1000) - { - imap->_last_network_error_ms = millis(); - errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, true); - } - - return false; - } - return false; - } - - res.chunkBufSize = imap->client.available(); - - if (res.chunkBufSize > 0) - { - res.chunkBufSize = ESP_MAIL_CLIENT_RESPONSE_BUFFER_SIZE; - - if (imap->_imap_cmd == esp_mail_imap_cmd_search) - { - - res.readLen = parseSearchResponse(imap, res, esp_mail_imap_tag_str, imap_responses[esp_mail_imap_response_search].text); - imap->_mbif._availableItems = imap->_imap_msg_num.size(); - - if (imap->_mbif._availableItems == 0) - { - res.imapResp = imapResponseStatus(imap, res.response, esp_mail_imap_tag_str); - - if (res.imapResp != esp_mail_imap_resp_unknown) - res.endSearch = true; - - if (res.imapResp == esp_mail_imap_resp_bad) - { - errorStatusCB(imap, nullptr, IMAP_STATUS_BAD_COMMAND, false); - return false; - } - } - } - else - { - // response read as chunk ended with CRLF or complete buffer size - int o = res.octetCount; - res.readLen = 0; - MB_String ovfBuf; - if (!readResponse(imap, res.response, res.chunkBufSize, res.readLen, withLineBreak, res.octetCount, ovfBuf)) - { - errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_READ_TIMEOUT, true); - return false; - } - - // If buffer overflown, copy from overflow buffer - if (ovfBuf.length() > 0) - { - // release memory - freeMem(&res.response); - res.response = allocMem(ovfBuf.length() + 1); - strcpy(res.response, ovfBuf.c_str()); - ovfBuf.clear(); - } - - if (res.readLen == 0 && o != res.octetCount && res.octetCount <= res.octetLength && cPart(imap)->xencoding != esp_mail_msg_xencoding_base64 && cPart(imap)->xencoding != esp_mail_msg_xencoding_binary && cPart(imap)->xencoding != esp_mail_msg_xencoding_qp) - { - strcpy_P(res.response, esp_mail_str_42 /* "\r\n" */); - res.readLen = 2; - } - } - - if (res.readLen) - { - if (imap->_debug && imap->_debugLevel > esp_mail_debug_level_basic && !imap->_customCmdResCallback) - { - if (imap->_imap_cmd != esp_mail_imap_cmd_search && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_text && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_attachment && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_inline) - esp_mail_debug_print((const char *)res.response, true); - } - - if (imap->_imap_cmd != esp_mail_imap_cmd_search || (imap->_imap_cmd == esp_mail_imap_cmd_search && res.endSearch)) - res.imapResp = imapResponseStatus(imap, res.response, esp_mail_imap_tag_str); - - if (res.imapResp != esp_mail_imap_resp_unknown) - { - - // We've got the right response, - // prepare to exit - - res.completedResponse = true; - - if (imap->_debug && imap->_debugLevel > esp_mail_debug_level_basic && !imap->_customCmdResCallback) - { - if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) - esp_mail_debug_print((const char *)res.response, true); - } - - MB_String ovfBuf; - - while (imap->client.available()) - { - - if (!readResponse(imap, res.response, res.chunkBufSize, res.readLen, true, res.octetCount, ovfBuf)) - { - errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_READ_TIMEOUT, true); - return false; - } - // If buffer overflown, copy from overflow buffer - if (ovfBuf.length() > 0) - { - // release memory - freeMem(&res.response); - res.response = allocMem(ovfBuf.length() + 1); - strcpy(res.response, ovfBuf.c_str()); - ovfBuf.clear(); - } - - if (res.readLen) - { - if (imap->_debug && imap->_debugLevel > esp_mail_debug_level_basic && !imap->_customCmdResCallback) - { - if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) - esp_mail_debug_print((const char *)res.response, true); - } - } - } - } - else - { - - // No response ever parsed - - if (imap->_imap_cmd == esp_mail_imap_cmd_sasl_auth_plain || imap->_imap_cmd == esp_mail_imap_cmd_sasl_auth_oauth) - { - if (imap->_imap_cmd == esp_mail_imap_cmd_sasl_auth_oauth) - { - if (isOAuthError(res.response, res.readLen, res.chunkIdx, 2)) - res.completedResponse = true; - } - - // In case SASL-IR extension does not support, check for initial zero-length server challenge first "+ " - if (!imap->_auth_capability[esp_mail_auth_capability_sasl_ir] && strcmp(res.response, pgm2Str(esp_mail_str_63 /* "+ " */)) == 0) - { - res.imapResp = esp_mail_imap_resp_ok; - res.completedResponse = true; - } - } - - if (imap->_imap_cmd == esp_mail_imap_cmd_sasl_login || imap->_imap_cmd == esp_mail_imap_cmd_sasl_auth_oauth || imap->_imap_cmd == esp_mail_imap_cmd_sasl_auth_plain) - { - int i = 0; - if (parseCapabilityResponse(imap, res.response, i)) - imap->_feature_capability[esp_mail_imap_read_capability_auto_caps] = true; - } - else if (imap->_imap_cmd == esp_mail_imap_cmd_custom && imap->_customCmdResCallback) - { - - res.imapResp = imapResponseStatus(imap, res.response, imap->_responseStatus.tag.c_str()); - - // get response or custom cmd APPEND or custom cmd IDLE? - if (res.imapResp > esp_mail_imap_resp_unknown || strposP(imap->_cmd.c_str(), imap_commands[esp_mail_imap_command_append].text, 0, false) > -1 || imap->_imap_custom_cmd == esp_mail_imap_cmd_idle) - res.completedResponse = true; - - imap->_responseStatus.text = res.response; - - imap->_customCmdResCallback(imap->_responseStatus); - - if (res.completedResponse) - return true; - } - else if (imap->_imap_cmd == esp_mail_imap_cmd_append) - { - res.imapResp = esp_mail_imap_resp_ok; - res.completedResponse = true; - } - else if (imap->_imap_cmd == esp_mail_imap_cmd_capability) - parseCapabilityResponse(imap, res.response, res.chunkIdx); - else if (imap->_imap_cmd == esp_mail_imap_cmd_list) - parseFoldersResponse(imap, res.response, true); - else if (imap->_imap_cmd == esp_mail_imap_cmd_lsub) - parseFoldersResponse(imap, res.response, false); - else if (imap->_imap_cmd == esp_mail_imap_cmd_select || imap->_imap_cmd == esp_mail_imap_cmd_examine) - parseExamineResponse(imap, res.response); - else if (imap->_imap_cmd == esp_mail_imap_cmd_get_uid) - { - MB_String str; - appendFetchString(str, true); - parseCmdResponse(imap, res.response, str.c_str()); - } - else if (imap->_imap_cmd == esp_mail_imap_cmd_get_flags) - { - MB_String str; - appendFetchString(str, false); - parseCmdResponse(imap, res.response, str.c_str()); - } - else if (imap->_imap_cmd == esp_mail_imap_cmd_get_quota) - parseCmdResponse(imap, res.response, imap_responses[esp_mail_imap_response_quota].text); - else if (imap->_imap_cmd == esp_mail_imap_cmd_id) - parseCmdResponse(imap, res.response, imap_responses[esp_mail_imap_response_id].text); - else if (imap->_imap_cmd == esp_mail_imap_cmd_get_quota_root) - { - parseCmdResponse(imap, res.response, imap_responses[esp_mail_imap_response_quotaroot].text); - imap->_quota_tmp.clear(); - parseCmdResponse(imap, res.response, imap_responses[esp_mail_imap_response_quota].text); - if (imap->_quota_tmp.length() > 0) - { - imap->_quota_root_tmp += (char)':'; - imap->_quota_root_tmp += imap->_quota_tmp; - } - } - else if (imap->_imap_cmd == esp_mail_imap_cmd_get_acl || imap->_imap_cmd == esp_mail_imap_cmd_my_rights) - parseCmdResponse(imap, res.response, imap->_imap_cmd == esp_mail_imap_cmd_get_acl ? imap_responses[esp_mail_imap_response_acl].text : imap_responses[esp_mail_imap_response_myrights].text); - else if (imap->_imap_cmd == esp_mail_imap_cmd_namespace) - parseCmdResponse(imap, res.response, imap_responses[esp_mail_imap_response_namespace].text); - else if (imap->_imap_cmd == esp_mail_imap_cmd_idle) - { - res.completedResponse = res.response[0] == '+'; - res.imapResp = esp_mail_imap_resp_ok; - - imap->_last_host_check_ms = millis(); - } - else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_sequence_set) - { - MB_String str; - appendFetchString(str, true); - parseCmdResponse(imap, res.response, str.c_str()); - } - else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_header) - { - - if (res.headerState == 0 && cMSG(imap).type == esp_mail_imap_msg_num_type_uid) - res.header.message_uid = cMSG(imap).value; - - int _st = res.headerState; - parseHeaderResponse(imap, res, imap->_imap_data->enable.header_case_sensitive); - if (_st == res.headerState && res.headerState > 0 && res.octetCount <= res.header.header_data_len) - collectHeaderField(imap, res.response, res.header, res.headerState); - } - else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_mime) - parsePartHeaderResponse(imap, res, imap->_imap_data->enable.header_case_sensitive); - else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text) - decodeText(imap, res); - else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) - { - - if (cPart(imap)->xencoding == esp_mail_msg_xencoding_base64) - { - // Multi-line chunked base64 string attachment handle - if (res.octetCount < res.octetLength && res.readLen < BASE64_CHUNKED_LEN) - { - if (strlen(res.lastBuf) > 0) - { - res.buf = allocMem(res.readLen + strlen(res.lastBuf) + 2); - strcpy(res.buf, res.lastBuf); - strcat(res.buf, res.response); - res.readLen = strlen(res.buf); - res.tmo = parseAttachmentResponse(imap, res.buf, res); - // release memory - freeMem(&res.buf); - memset(res.lastBuf, 0, BASE64_CHUNKED_LEN + 1); - if (!res.tmo) - break; - } - else if (res.readLen < BASE64_CHUNKED_LEN + 1) - strcpy(res.lastBuf, res.response); - } - else - { - res.tmo = parseAttachmentResponse(imap, res.response, res); - if (!res.tmo) - break; - } - } - else - res.tmo = parseAttachmentResponse(imap, res.response, res); - } - - res.dataTime = millis(); - } - } - memset(res.response, 0, res.chunkBufSize); - } - } - - if (imap->_imap_cmd == esp_mail_imap_cmd_search) - { - if (imap->_debug && res.searchCount > 0 && res.searchCount < 100) - { - searchReport(imap, 100); - } - } - } - - if ((res.imapResp != esp_mail_imap_resp_ok && imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_header && res.header.header_data_len == 0) || res.imapResp == esp_mail_imap_resp_no) - { - // We don't get any response - - if (res.imapResp == esp_mail_imap_resp_no) - imap->_responseStatus.errorCode = IMAP_STATUS_IMAP_RESPONSE_FAILED; - else if (imap->_imap_data->fetch.modsequence > -1 && imap->isModseqSupported() && res.imapResp == esp_mail_imap_resp_ok && res.header.header_data_len == 0) - imap->_responseStatus.errorCode = IMAP_STATUS_CHANGEDSINC_MODSEQ_TEST_FAILED; - else - imap->_responseStatus.errorCode = IMAP_STATUS_NO_MESSAGE; - -#if !defined(SILENT_MODE) - - if (imap->_statusCallback && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_mime) - sendErrorCB(imap, imap->errorReason().c_str(), false, false); - - if (imap->_debug && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_mime) - esp_mail_debug_print_tag(imap->errorReason().c_str(), esp_mail_debug_tag_type_error, true); - -#endif - - return false; - } - - // We've got OK or NO responses - - if (res.imapResp == esp_mail_imap_resp_ok) - { - // Response OK - - if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_header) - { - // Headers management - - char *buf = allocMem(res.header.content_type.length() + 1); - strcpy(buf, res.header.content_type.c_str()); - res.header.content_type.clear(); - - MB_String contentTypeName; - appendHeaderName(contentTypeName, message_headers[esp_mail_message_header_field_content_type].text, false, false, false); - - res.buf = subStr(buf, contentTypeName.c_str(), esp_mail_str_35 /* ";" */, 0, 0, false); - if (res.buf) - { - res.headerState = esp_mail_imap_state_content_type; - collectHeaderField(imap, res.buf, res.header, res.headerState); - // release memory - freeMem(&res.buf); - - if (res.header.content_type.length() > 0) - { - int p1 = strposP(res.header.content_type.c_str(), esp_mail_imap_composite_media_type_t::multipart, 0); - if (p1 != -1) - { - p1 += strlen(esp_mail_imap_composite_media_type_t::multipart) + 1; - res.header.multipart = true; - // inline or embedded images - if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::related, p1) != -1) - res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_related; - // multiple text formats e.g. plain, html, enriched - else if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::alternative, p1) != -1) - res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_alternative; - // medias - else if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::parallel, p1) != -1) - res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_parallel; - // rfc822 encapsulated - else if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::digest, p1) != -1) - res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_digest; - else if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::report, p1) != -1) - res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_report; - // others can be attachments - else if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::mixed, p1) != -1) - res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_mixed; - } - - p1 = strposP(res.header.content_type.c_str(), esp_mail_imap_composite_media_type_t::message, 0); - if (p1 != -1) - { - p1 += strlen(esp_mail_imap_composite_media_type_t::message) + 1; - if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::rfc822, p1) != -1) - { - res.header.rfc822_part = true; - res.header.message_sub_type = esp_mail_imap_message_sub_type_rfc822; - } - else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::Partial, p1) != -1) - res.header.message_sub_type = esp_mail_imap_message_sub_type_partial; - else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::External_Body, p1) != -1) - res.header.message_sub_type = esp_mail_imap_message_sub_type_external_body; - else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::delivery_status, p1) != -1) - res.header.message_sub_type = esp_mail_imap_message_sub_type_delivery_status; - } - } - - MB_String charset; - appendLowerCaseString(charset, message_headers[esp_mail_message_header_field_charset].text, false); - charset += esp_mail_str_7; /* "=" */ - - res.buf = subStr(buf, charset.c_str(), NULL, 0, -1, false); - if (res.buf) - { - res.headerState = esp_mail_imap_state_char_set; - collectHeaderField(imap, res.buf, res.header, res.headerState); - // release memory - freeMem(&res.buf); - } - - if (res.header.multipart) - { - if (strcmpP(buf, 0, esp_mail_str_64 /* "boundary=\"" */)) - { - res.buf = subStr(buf, esp_mail_str_64 /* "boundary=\"" */, esp_mail_str_11 /* "\"" */, 0, 0, false); - if (res.buf) - { - res.headerState = esp_mail_imap_state_boundary; - collectHeaderField(imap, res.buf, res.header, res.headerState); - // release memory - freeMem(&res.buf); - } - } - } - } - - // release memory - freeMem(&buf); - - // Decode the headers fields - - for (int i = esp_mail_rfc822_header_field_from; i < esp_mail_rfc822_header_field_maxType; i++) - { - if (i != esp_mail_rfc822_header_field_msg_id && i != esp_mail_rfc822_header_field_flags) - decodeString(imap, res.header.header_fields.header_items[i]); - } - - imap->_headers.push_back(res.header); - } - - if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_mime) - { - // Expect the octet length in the response for the existent part - if (res.part.octetLen > 0) - { - - res.part.partNumStr = cHeader(imap)->partNumStr; - res.part.partNumFetchStr = cHeader(imap)->partNumStr; - if (cHeader(imap)->part_headers.size() > 0) - { - - struct esp_mail_message_part_info_t *_part = &cHeader(imap)->part_headers[cHeader(imap)->part_headers.size() - 1]; - bool rfc822_body_subtype = _part->message_sub_type == esp_mail_imap_message_sub_type_rfc822; - - if (rfc822_body_subtype) - { - if (!_part->rfc822_part) - { - // additional rfc822 message header, store it to the rfc822 part header - _part->rfc822_part = true; - _part->rfc822_header = res.part.rfc822_header; - imap->_rfc822_part_count++; - _part->rfc822_msg_Idx = imap->_rfc822_part_count; - } - } - } - - cHeader(imap)->part_headers.push_back(res.part); - cHeader(imap)->message_data_count = cHeader(imap)->part_headers.size(); - - if (res.part.msg_type != esp_mail_msg_type_none || - res.part.attach_type != esp_mail_att_type_none) - { - if (res.part.attach_type == esp_mail_att_type_attachment || - res.part.message_sub_type != esp_mail_imap_message_sub_type_rfc822) - { - if (res.part.attach_type != esp_mail_att_type_none && - cHeader(imap)->multipart_sub_type != esp_mail_imap_multipart_sub_type_alternative) - { - cHeader(imap)->hasAttachment = true; - cHeader(imap)->attachment_count++; - } - } - } - } - else - { - // nonexistent part - // return false to exit the loop without closing the connection - if (closeSession) - imap->closeSession(); - return false; - } - } - - if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) - { - if (cPart(imap) && cPart(imap)->file_open_write) - mbfs->close(mbfs_type imap->_imap_data->storage.type); - } - - if (cPart(imap) && imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text) - cPart(imap)->text[cPart(imap)->textLen] = 0; - } - else - { - - // Response NO - - // Some server responses NO and should exit (false) from MIME feching loop without - // closing the session - if (imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_mime) - return handleIMAPError(imap, errCode, false); - - if (closeSession) - imap->closeSession(); - return false; - } - - return true; -} - -void ESP_Mail_Client::addHeader(MB_String &s, PGM_P name, const char *s_value, int num_value, bool trim, bool isJson) -{ - if (isJson) - { - s += (s.length() > 0) ? esp_mail_str_77 /* ",\"" */ : esp_mail_str_78 /* "{\"" */; - s += name; - - if (strlen(s_value) > 0) - { - s += esp_mail_str_79; /* "\":\"" */ - ; - if (trim) - { - MB_String t = s_value; - t.replaceAll("\"", ""); - s += t; - } - else - s += s_value; - s += esp_mail_str_11; /* "\"" */ - } - else - { - s += esp_mail_str_34 /* ":" */; - appendSpace(s); - s += num_value; - } - } - else - { - if (s.length() > 0) - appendNewline(s); - s += name; - s += esp_mail_str_34 /* ":" */; - appendSpace(s); - if (strlen(s_value) > 0) - s += s_value; - else - s += num_value; - } -} - -void ESP_Mail_Client::saveHeader(IMAPSession *imap, bool json) -{ - if (!imap->_storageReady) - return; - - MB_String headerFilePath; - - prepareFilePath(imap, headerFilePath, true); - - headerFilePath += json ? esp_mail_str_65 /* "/header.json" */ : esp_mail_str_66 /* "/header.txt" */; - - prepareFileList(imap, headerFilePath); - - int sz = mbfs->open(headerFilePath, mbfs_type imap->_imap_data->storage.type, mb_fs_open_mode_write); - if (sz < 0) - { - imap->_responseStatus.errorCode = sz; - imap->_responseStatus.text.clear(); -#if !defined(SILENT_MODE) - if (imap->_debug) - { - esp_mail_debug_print_tag(imap->errorReason().c_str(), esp_mail_debug_tag_type_error, true); - } -#endif - return; - } - - MB_String s; - for (size_t i = 0; i < imap->_headers.size(); i++) - addHeaderItem(s, &imap->_headers[i], json); - - if (json) - s += esp_mail_str_75; /* "]}" */ - - mbfs->print(mbfs_type imap->_imap_data->storage.type, s.c_str()); - - mbfs->close(mbfs_type imap->_imap_data->storage.type); - - imap->_headerSaved = true; -} - -void ESP_Mail_Client::addHeaderItem(MB_String &str, esp_mail_message_header_t *header, bool json) -{ - MB_String s; - if (json) - { - if (str.length() > 0) - str += esp_mail_str_8; /* "," */ - else - str = esp_mail_str_76; /* "{\"Messages\":[" */ - } - - addHeader(s, message_headers[esp_mail_message_header_field_number].text, "", header->message_no, false, json); - addHeader(s, message_headers[esp_mail_message_header_field_uid].text, "", header->message_uid, false, json); - - if (header->accept_language.length() > 0) - addHeader(s, message_headers[esp_mail_message_header_field_accept_language].text, header->accept_language.c_str(), 0, false, json); - - if (header->content_language.length() > 0) - addHeader(s, message_headers[esp_mail_message_header_field_content_language].text, header->content_language.c_str(), 0, false, json); - - addRFC822Headers(s, &header->header_fields, json); - - for (size_t j = 0; j < header->part_headers.size(); j++) - { - if (header->part_headers[j].rfc822_part) - { - MB_String s1; - addRFC822Headers(s1, &header->part_headers[j].rfc822_header, json); - - if (json) - { - s += esp_mail_str_69; /* ",\"RFC822\":" */ - s += s1; - s += esp_mail_str_36; /* "}" */ - } - else - { - s += esp_mail_str_70; /* "\r\n\r\nRFC822:\r\n" */ - s += s1; - } - } - } - - if (header->attachment_count > 0) - { - if (json) - { - s += esp_mail_str_71 /* ",\"Attachments\":{\"Count\":" */; - s += header->attachment_count; - s += esp_mail_str_72; /* ",\"Files\":[" */ - } - else - { - s += esp_mail_str_73; /* "\r\n\r\nAttachments (" */ - s += header->attachment_count; - s += esp_mail_str_74; /* ")\r\n" */ - } - - int index = 0; - for (size_t j = 0; j < header->part_headers.size(); j++) - { - - if (header->part_headers[j].attach_type == esp_mail_att_type_none || header->part_headers[j].rfc822_part) - continue; - - if (json) - { - if (index > 0) - s += esp_mail_str_8; /* "," */ - s += esp_mail_str_67; /* /"{\"Filename\":\"" */ - s += header->part_headers[j].filename; - s += esp_mail_str_11; /* "\"" */ - } - else - { - if (index > 0) - appendNewline(s); - appendNewline(s); - s += esp_mail_str_68; /* /"Index: " */ - s += index + 1; - addHeader(s, message_headers[esp_mail_message_header_field_filename].text, header->part_headers[j].filename.c_str(), 0, false, json); - } - - addHeader(s, message_headers[esp_mail_message_header_field_name].text, header->part_headers[j].name.c_str(), 0, false, json); - addHeader(s, message_headers[esp_mail_message_header_field_size].text, "", header->part_headers[j].attach_data_size, false, json); - addHeader(s, message_headers[esp_mail_message_header_field_mime].text, header->part_headers[j].content_type.c_str(), 0, false, json); - addHeader(s, message_headers[esp_mail_message_header_field_type].text, header->part_headers[j].attach_type == esp_mail_att_type_attachment ? esp_mail_content_disposition_type_t::attachment : esp_mail_content_disposition_type_t::inline_, 0, false, json); - addHeader(s, message_headers[esp_mail_message_header_field_description].text, header->part_headers[j].content_description.c_str(), 0, false, json); - addHeader(s, message_headers[esp_mail_message_header_field_creation_date].text, header->part_headers[j].creation_date.c_str(), 0, false, json); - - if (json) - s += esp_mail_str_36; /* "}" */ - - index++; - } - - if (json) - s += esp_mail_str_75; /* "]}" */ - } - - if (json) - { - s += esp_mail_str_36; /* "}" */ - } - - str += s; -} - -int ESP_Mail_Client::getRFC822HeaderPtr(int index, esp_mail_imap_rfc822_msg_header_item_t *header) -{ - if (index > esp_mail_rfc822_header_field_from && index < esp_mail_rfc822_header_field_maxType) - return toAddr(header->header_items[index]); - return 0; -} - -void ESP_Mail_Client::addRFC822Headers(MB_String &s, esp_mail_imap_rfc822_msg_header_item_t *header, bool json) -{ - for (int i = esp_mail_rfc822_header_field_from; i < esp_mail_rfc822_header_field_maxType; i++) - addRFC822HeaderItem(s, header, i, json); -} - -void ESP_Mail_Client::addRFC822HeaderItem(MB_String &s, esp_mail_imap_rfc822_msg_header_item_t *header, int index, bool json) -{ - int ptr = getRFC822HeaderPtr(index, header); - if (ptr > 0) - addHeader(s, rfc822_headers[index].text, addrTo(ptr)->c_str(), 0, rfc822_headers[index].trim, json); -} - -esp_mail_imap_response_status ESP_Mail_Client::imapResponseStatus(IMAPSession *imap, char *response, PGM_P tag) -{ - imap->_responseStatus.clear(false); - MB_String test; - esp_mail_imap_response_status status = esp_mail_imap_resp_unknown; - esp_mail_imap_response_types type = esp_mail_imap_response_maxType; - - if (strpos(response, imap->prependTag(imap_responses[esp_mail_imap_response_ok].text, tag).c_str(), 0) > -1) - { - status = esp_mail_imap_resp_ok; - type = esp_mail_imap_response_ok; - } - else if (strpos(response, imap->prependTag(imap_responses[esp_mail_imap_response_no].text, tag).c_str(), 0) > -1) - { - status = esp_mail_imap_resp_no; - type = esp_mail_imap_response_no; - } - else if (strpos(response, imap->prependTag(imap_responses[esp_mail_imap_response_bad].text, tag).c_str(), 0) > -1) - { - status = esp_mail_imap_resp_bad; - type = esp_mail_imap_response_bad; - } - - if (status != esp_mail_imap_resp_unknown) - { - test = imap->prependTag(imap_responses[type].text, tag); - - imap->_responseStatus.text = &response[test.length()]; - if (imap->_responseStatus.text[imap->_responseStatus.text.length() - 2] == '\r') - imap->_responseStatus.text[imap->_responseStatus.text.length() - 2] = 0; - - test = imap_responses[type].text; - test.trim(); - imap->_responseStatus.status = test; - imap->_responseStatus.completed = true; - } - return status; -} - -bool ESP_Mail_Client::parseCapabilityResponse(IMAPSession *imap, const char *buf, int &chunkIdx) -{ - if (chunkIdx == 0) - { - MB_String res; - // We add white space to make post token checking to work in all capabilities. - // This will allow us to check "IDLE " and "ID " correctly. - appendSpace(res, false, buf); - - if (strposP(res.c_str(), imap_responses[esp_mail_imap_response_capability_untagged].text, 0) > -1 || strposP(res.c_str(), imap_responses[esp_mail_imap_response_capability].text, 0) > -1) - { - for (int i = esp_mail_auth_capability_plain; i < esp_mail_auth_capability_maxType; i++) - { - if (strposP(res.c_str(), imap_auth_cap_pre_tokens[i].c_str(), 0) > -1) - imap->_auth_capability[i] = true; - } - - for (int i = esp_mail_imap_read_capability_imap4; i < esp_mail_imap_read_capability_maxType; i++) - { - if (strposP(res.c_str(), imap_read_cap_post_tokens[i].c_str(), 0) > -1) - { - imap->_feature_capability[i] = true; - if (i == esp_mail_imap_read_capability_logindisable) - imap->_auth_capability[esp_mail_auth_capability_login] = false; - } - } - - return true; - } - } - - return false; -} - -char *ESP_Mail_Client::getList(char *buf, bool &isList) -{ - if (buf[0] == '(' && buf[1] != ')') - { - if (buf[strlen(buf) - 1] == ')') - buf[strlen(buf) - 1] = 0; - else - isList = true; - - return &buf[1]; - } - else if (isList) - { - if (buf[strlen(buf) - 1] == ')') - { - buf[strlen(buf) - 1] = 0; - isList = false; - } - } - - return buf; -} - -void ESP_Mail_Client::parseFoldersResponse(IMAPSession *imap, char *buf, bool list) -{ - struct esp_mail_folder_info_t fd; - int pos = list ? strposP(buf, imap_responses[esp_mail_imap_response_list].text, 0) : strposP(buf, imap_responses[esp_mail_imap_response_lsub].text, 0); - bool isList = false, delimOk = false; - if (pos != -1) - { - char *p = allocMem(strlen(buf)); - strcpy(p, buf); - char *pp = p; - char *end = p; - int count = 0; - int tkPos = 3; - - while (pp != NULL) - { - // See RFC2047.h - ESP_MAIL_STRSEP(&end, " "); - count++; - - if (count >= tkPos && strlen(pp) > 0) - { - if (count == tkPos && pp[0] == '(' && pp[1] != ')') - fd.attributes = getList(pp, isList); - else if (isList) - { - fd.attributes += ' '; - fd.attributes += getList(pp, isList); - } - else - { - if (pp[strlen(pp) - 1] == '"') - pp[strlen(pp) - 1] = 0; - - const char *ptr = pp[0] == '"' ? &pp[1] : &pp[0]; - - if (!delimOk) - { - delimOk = true; - fd.delimiter = ptr; - } - else - { - if (fd.name.length() > 0) - fd.name += ' '; - fd.name += ptr; - } - } - } - pp = end; - } - - // release memory - freeMem(&p); - - imap->_folders.add(fd); - } -} - -bool ESP_Mail_Client::parseIdleResponse(IMAPSession *imap) -{ - - int chunkBufSize = 0; - - if (!reconnect(imap)) - return false; - - if (imap->client.connected()) - chunkBufSize = imap->client.available(); - else - return false; - - if (chunkBufSize > 0) - { - chunkBufSize = ESP_MAIL_CLIENT_RESPONSE_BUFFER_SIZE; - - char *buf = allocMem(chunkBufSize + 1); - - int octetCount = 0; - - int readLen = 0; - - MB_String ovfBuf; - readResponse(imap, buf, chunkBufSize, readLen, false, octetCount, ovfBuf); - - // If buffer overflown, copy from overflow buffer - if (ovfBuf.length() > 0) - { - // release memory - freeMem(&buf); - buf = allocMem(ovfBuf.length() + 1); - strcpy(buf, ovfBuf.c_str()); - ovfBuf.clear(); - } - - if (readLen > 0) - { - - if (imap->_debug && imap->_debugLevel > esp_mail_debug_level_basic) - esp_mail_debug_print((const char *)buf, true); - - char *tmp = nullptr; - int p1 = -1; - bool exists = false; - - tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_exists].text, 0); - if (tmp) - { - int numMsg = imap->_mbif._msgCount; - imap->_mbif._msgCount = atoi(tmp); - // release memory - freeMem(&tmp); - exists = true; - imap->_mbif._folderChanged |= (int)imap->_mbif._msgCount != numMsg; - if ((int)imap->_mbif._msgCount > numMsg) - { - imap->_mbif._polling_status.type = imap_polling_status_type_new_message; - imap->_mbif._polling_status.messageNum = imap->_mbif._msgCount; - } - goto ex; - } - - tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_expunge].text, 0); - if (tmp) - { - imap->_mbif._polling_status.type = imap_polling_status_type_remove_message; - imap->_mbif._polling_status.messageNum = atoi(tmp); - - if (imap->_mbif._polling_status.messageNum == imap->_mbif._msgCount && imap->_mbif._nextUID > 0) - imap->_mbif._nextUID--; - - // release memory - freeMem(&tmp); - imap->_mbif._folderChanged = true; - goto ex; - } - - tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_recent].text, 0); - if (tmp) - { - imap->_mbif._recentCount = atoi(tmp); - // release memory - freeMem(&tmp); - goto ex; - } - - tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_fetch].text, 0); - if (tmp) - { - imap->_mbif._polling_status.messageNum = atoi(tmp); - // release memory - freeMem(&tmp); - - imap->_mbif._polling_status.argument = buf; - imap->_mbif._polling_status.argument.erase(0, p1 + 8); - imap->_mbif._polling_status.argument.pop_back(); - imap->_mbif._folderChanged = true; - imap->_mbif._polling_status.type = imap_polling_status_type_fetch_message; - goto ex; - } - - ex: - - imap->_mbif._floderChangedState = (imap->_mbif._folderChanged && exists) || imap->_mbif._polling_status.type == imap_polling_status_type_fetch_message; - } - - // release memory - freeMem(&buf); - } - - size_t imap_idle_tmo = imap->_imap_data->limit.imap_idle_timeout; - - if (imap_idle_tmo < 60 * 1000 || imap_idle_tmo > 29 * 60 * 1000) - imap_idle_tmo = 10 * 60 * 1000; - - if (millis() - imap->_mbif._idleTimeMs > imap_idle_tmo) - { - if (imap->mStopListen(true)) - return imap->mListen(true); - return false; - } - - return true; -} - -void ESP_Mail_Client::appendFetchString(MB_String &buf, bool uid) -{ - if (uid) - buf += imap_cmd_post_tokens[esp_mail_imap_command_uid]; - else - joinStringSpace(buf, false, 2, imap_commands[esp_mail_imap_command_flags].text, esp_mail_str_38 /* "(" */); -} - -void ESP_Mail_Client::parseCmdResponse(IMAPSession *imap, char *buf, PGM_P find) -{ - if (imap->_imap_cmd == esp_mail_imap_cmd_get_uid) - imap->_uid_tmp = 0; - - char *tmp = nullptr; - int p1 = strposP(buf, find, 0); - if (p1 != -1) - { - if (imap->_imap_cmd == esp_mail_imap_cmd_get_quota_root || - imap->_imap_cmd == esp_mail_imap_cmd_get_acl || - imap->_imap_cmd == esp_mail_imap_cmd_my_rights) - { - int ofs = imap->_imap_cmd == esp_mail_imap_cmd_get_quota_root ? 0 : 1; - int p2 = strposP(buf, esp_mail_str_2 /* " " */, p1 + strlen_P(find) + ofs); - if (p2 != -1) - { - int len = strlen(buf) - p2 - 1; - tmp = allocMem(len); - strncpy(tmp, buf + p2 + 1, strlen(buf) - p2 - 1); - if (imap->_imap_cmd == esp_mail_imap_cmd_get_quota_root) - { - if (imap->_quota_root_tmp.length() > 0) - imap->_quota_root_tmp += esp_mail_str_8; /* ";" */ - imap->_quota_root_tmp += tmp; - } - else - { - imap->_acl_tmp = tmp; - } - - // release memory - freeMem(&tmp); - } - } - else - { - int len = imap->_imap_cmd == esp_mail_imap_cmd_get_uid ? 20 : strlen(buf) - p1 - strlen_P(find); - int ofs = imap->_imap_cmd == esp_mail_imap_cmd_get_uid || - imap->_imap_cmd == esp_mail_imap_cmd_fetch_sequence_set - ? 1 - : imap->_imap_cmd == esp_mail_imap_cmd_namespace || imap->_imap_cmd == esp_mail_imap_cmd_id ? 0 - : 2; - tmp = allocMem(len); - - strncpy(tmp, buf + p1 + strlen_P(find), strlen(buf) - p1 - strlen_P(find) - ofs); - - esp_mail_imap_msg_num_t msg_num; - - switch ((int)imap->_imap_cmd) - { - case esp_mail_imap_cmd_get_uid: - imap->_uid_tmp = atoi(tmp); - break; - case esp_mail_imap_cmd_get_flags: - imap->_flags_tmp = tmp; - break; - case esp_mail_imap_cmd_get_quota: - imap->_quota_tmp = tmp; - break; - case esp_mail_imap_cmd_id: - imap->_server_id_tmp = tmp; - break; - case esp_mail_imap_cmd_namespace: - imap->_ns_tmp += tmp; - break; - case esp_mail_imap_cmd_fetch_sequence_set: - - msg_num.type = esp_mail_imap_msg_num_type_uid; - msg_num.value = (uint32_t)atoi(tmp); - imap->_imap_msg_num.push_back(msg_num); - - if (imap->_imap_msg_num.size() > imap->_imap_data->limit.fetch) - imap->_imap_msg_num.erase(imap->_imap_msg_num.begin()); - - break; - default: - break; - } - } - - // release memory - freeMem(&tmp); - } -} - -bool ESP_Mail_Client::getFlags(IMAPSession *imap, char *buf, esp_mail_imap_response_types type) -{ - if (strposP(buf, imap_responses[type].text, 0) != -1) - { - char *p = allocMem(strlen(buf)); - strcpy(p, buf); - char *pp = p; - char *end = p; - int count = 0; - bool isList = false; - int tkPos = (type == esp_mail_imap_response_permanent_flags) ? 4 : 3; - - while (pp != NULL) - { - // See RFC2047.h - ESP_MAIL_STRSEP(&end, " "); - count++; - if (count >= tkPos && strlen(pp) > 0) - { - if (type == esp_mail_imap_response_permanent_flags && pp[strlen(pp) - 1] == ']') - pp[strlen(pp) - 1] = 0; - - if (count == tkPos && pp[0] == '(' && pp[1] != ')') - imap->_mbif.addFlag(getList(pp, isList), type == esp_mail_imap_response_permanent_flags); - else if (isList) - imap->_mbif.addFlag(getList(pp, isList), type == esp_mail_imap_response_permanent_flags); - } - pp = end; - } - - // release memory - freeMem(&p); - - return true; - } - - return false; -} - -void ESP_Mail_Client::parseExamineResponse(IMAPSession *imap, char *buf) -{ - char *tmp = NULL; - - tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_exists].text, 0); - if (tmp) - { - imap->_mbif._msgCount = atoi(tmp); - // release memory - freeMem(&tmp); - return; - } - - tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_recent].text, 0); - if (tmp) - { - imap->_mbif._recentCount = atoi(tmp); - // release memory - freeMem(&tmp); - return; - } - - if (imap->_mbif._flags.size() == 0 && getFlags(imap, buf, esp_mail_imap_response_flags)) - return; - - if (imap->_mbif._permanent_flags.size() == 0 && getFlags(imap, buf, esp_mail_imap_response_permanent_flags)) - return; - - if (imap->_mbif._uidValidity == 0) - { - tmp = subStr(buf, imap_responses[esp_mail_imap_response_uidvalidity].text, esp_mail_str_41 /* "]" */, 0, 0); - if (tmp) - { - imap->_mbif._uidValidity = atoi(tmp); - // release memory - freeMem(&tmp); - return; - } - } - - if (imap->_nextUID.length() == 0) - { - tmp = subStr(buf, imap_responses[esp_mail_imap_response_uidnext].text, esp_mail_str_41 /* "]" */, 0, 0); - if (tmp) - { - imap->_nextUID = tmp; - imap->_mbif._nextUID = atoi(tmp); - // release memory - freeMem(&tmp); - return; - } - } - - if (imap->_unseenMsgIndex.length() == 0) - { - tmp = subStr(buf, imap_responses[esp_mail_imap_response_unseen].text, esp_mail_str_41 /* "]" */, 0, 0); - if (tmp) - { - imap->_unseenMsgIndex = tmp; - imap->_mbif._unseenMsgIndex = atoi(tmp); - // release memory - freeMem(&tmp); - return; - } - } - - if (imap->isCondStoreSupported()) - { - tmp = subStr(buf, imap_responses[esp_mail_imap_response_highest_modsec].text, esp_mail_str_41 /* "]" */, 0, 0); - if (tmp) - { - imap->_mbif._highestModSeq = tmp; - // release memory - freeMem(&tmp); - return; - } - - tmp = subStr(buf, imap_responses[esp_mail_imap_response_nomodsec].text, nullptr, 0, 0); - if (tmp) - { - imap->_mbif._nomodsec = true; - // release memory - freeMem(&tmp); - return; - } - } -} - -bool ESP_Mail_Client::handleIMAPError(IMAPSession *imap, int err, bool ret) -{ - if (err < 0) - { - errorStatusCB(imap, nullptr, err, true); - - if (imap->_headers.size() > 0 && cHeader(imap)) - { - if ((imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) && (imap->_imap_data->download.attachment || imap->_imap_data->download.inlineImg)) - { - if (cPart(imap) && cHeader(imap)->part_headers.size() > 0) - cPart(imap)->download_error = imap->errorReason().c_str(); - } - else if (cHeader(imap)) - cHeader(imap)->error_msg = imap->errorReason().c_str(); - - cHeader(imap)->error = true; - } - } - - closeTCPSession(imap); - - imap->_cbData.empty(); - - return ret; -} - -void ESP_Mail_Client::prepareFileList(IMAPSession *imap, MB_String &filePath) -{ -#if defined(MBFS_SD_FS) - if (!mbfs->longNameSupported()) - { - cHeader(imap)->sd_alias_file_count++; - MB_String alias = cHeader(imap)->message_uid; - alias += esp_mail_str_83; /* "_" */ - alias += cHeader(imap)->sd_alias_file_count; - - if (imap->_sdFileList.length() > 0) - { - if (imap->_sdFileList[imap->_sdFileList.length() - 1] == ']') - { - imap->_sdFileList[imap->_sdFileList.length() - 1] = 0; - imap->_sdFileList += esp_mail_str_8; /* "," */ - } - } - imap->_sdFileList += esp_mail_str_80; /* "{\"Renamed\":\"" */ - imap->_sdFileList += alias; - imap->_sdFileList += esp_mail_str_81; /* "\",\"Original\":\"" */ - imap->_sdFileList += filePath; - imap->_sdFileList += esp_mail_str_82; /* "\"}]" */ - // rename the original file - filePath = alias; - } -#endif -} - -bool ESP_Mail_Client::parseAttachmentResponse(IMAPSession *imap, char *buf, esp_mail_imap_response_data &res) -{ - int bufLen = res.readLen; - - if (res.chunkIdx == 0) - { - char *tmp = subStr(buf, esp_mail_str_36 /* "{" */, esp_mail_str_37 /* "}" */, 0); - if (tmp) - { - res.chunkIdx++; - res.octetCount = 0; // CRLF counted from first line - res.octetLength = atoi(tmp); - // release memory - freeMem(&tmp); - cPart(imap)->octetLen = res.octetLength; - cPart(imap)->octetCount = 0; - cHeader(imap)->total_download_size += res.octetLength; - imap->_lastProgress = -1; - -#if defined(ESP_MAIL_OTA_UPDATE_ENABLED) - if (cPart(imap)->is_firmware_file) - { - cPart(imap)->is_firmware_file = Update.begin(cPart(imap)->attach_data_size); - - if (!cPart(imap)->is_firmware_file) - { - imap->_responseStatus.errorCode = IMAP_STATUS_FIRMWARE_UPDATE_INIT_FAILED; - imap->_responseStatus.text.clear(); - } - -#if !defined(SILENT_MODE) - - sendCallback(imap, esp_mail_cb_str_42 /* "Updating firmware..." */, true, false); - - if (!cPart(imap)->is_firmware_file) - { - printDebug(imap, - imap->errorReason().c_str(), - imap->errorReason().c_str(), - esp_mail_debug_tag_type_error, - true, - false); - } - -#endif - } -#endif - - if (!cPart(imap)->file_open_write) - { - - if (imap->_storageReady && cPart(imap)->save_to_file) - { - res.downloadRequest = true; - - res.filePath.clear(); - - res.filePath += imap->_imap_data->storage.saved_path; - res.filePath += esp_mail_str_10; /* "/" */ - res.filePath += cHeader(imap)->message_uid; - res.filePath += esp_mail_str_10; /* "/" */ - res.filePath += cPart(imap)->filename; - - prepareFileList(imap, res.filePath); - - int sz = mbfs->open(res.filePath, mbfs_type imap->_imap_data->storage.type, mb_fs_open_mode_write); - - if (sz < 0) - { - imap->_responseStatus.errorCode = sz; - imap->_responseStatus.text.clear(); -#if !defined(SILENT_MODE) - printDebug(imap, - imap->errorReason().c_str(), - imap->errorReason().c_str(), - esp_mail_debug_tag_type_error, - true, - false); -#endif - } - - cPart(imap)->file_open_write = true; - } - } - } - return true; - } - - yield_impl(); - - if (res.octetLength == 0) - return true; - - if (cPart(imap)->octetCount <= res.octetLength) - { - if (cPart(imap)->octetCount + bufLen > res.octetLength) - { - bufLen = res.octetLength - cPart(imap)->octetCount; - buf[bufLen] = 0; - cPart(imap)->octetCount += bufLen; - } - else - cPart(imap)->octetCount = res.octetCount; - - if (imap->_imap_data->enable.download_status) - { - if (imap->_debug) - downloadReport(imap, 100 * cPart(imap)->octetCount / res.octetLength); - } - - if (cPart(imap)->octetCount > res.octetLength) - return true; - - bool write_error = false, fw_write_error = false; - - if (cPart(imap)->xencoding == esp_mail_msg_xencoding_base64) - { - - size_t olen = 0; - unsigned char *decoded = decodeBase64((const unsigned char *)buf, bufLen, &olen); - - if (decoded) - { - - if (!cPart(imap)->sizeProp) - { - cPart(imap)->attach_data_size += olen; - cHeader(imap)->total_attach_data_size += cPart(imap)->attach_data_size; - } - - sendStreamCB(imap, (void *)decoded, olen, res.chunkIdx, false); - - size_t write = olen; - - if (cPart(imap)->is_firmware_file) - { -#if defined(ESP_MAIL_OTA_UPDATE_ENABLED) - size_t fw_write = Update.write((uint8_t *)decoded, olen); - cPart(imap)->firmware_downloaded_byte += fw_write == olen ? olen : 0; - fw_write_error = fw_write != olen; -#endif - } - - if (cPart(imap)->save_to_file) - { - if (mbfs->ready(mbfs_type imap->_imap_data->storage.type)) - write = mbfs->write(mbfs_type imap->_imap_data->storage.type, (uint8_t *)decoded, olen); - } - - yield_impl(); - // release memory - freeMem(&decoded); - - write_error = write != olen; - } - - if (!reconnect(imap)) - return false; - } - else - { - // binary content - if (!cPart(imap)->sizeProp) - { - cPart(imap)->attach_data_size += bufLen; - cHeader(imap)->total_attach_data_size += cPart(imap)->attach_data_size; - } - - sendStreamCB(imap, (void *)buf, bufLen, res.chunkIdx, false); - - int write = bufLen; - - if (cPart(imap)->is_firmware_file) - { -#if defined(ESP_MAIL_OTA_UPDATE_ENABLED) - int fw_write = Update.write((uint8_t *)buf, bufLen); - cPart(imap)->firmware_downloaded_byte += fw_write == bufLen ? (size_t)bufLen : 0; - fw_write_error = fw_write != bufLen; -#endif - } - - if (cPart(imap)->save_to_file) - { - if (mbfs->ready(mbfs_type imap->_imap_data->storage.type)) - write = mbfs->write(mbfs_type imap->_imap_data->storage.type, (uint8_t *)buf, bufLen); - } - - yield_impl(); - - write_error = write != bufLen; - - if (!reconnect(imap)) - return false; - } - -#if defined(ESP_MAIL_OTA_UPDATE_ENABLED) - if (cPart(imap)->is_firmware_file) - { - bool update_result_ok = !fw_write_error; - - if (!imap->_isFirmwareUpdated && update_result_ok && - (cPart(imap)->firmware_downloaded_byte == (size_t)cPart(imap)->attach_data_size || cPart(imap)->octetCount >= res.octetLength)) - { - update_result_ok = Update.end(cPart(imap)->octetCount >= res.octetLength); - if (update_result_ok) - imap->_isFirmwareUpdated = true; - } - - if (!update_result_ok) - { - cPart(imap)->is_firmware_file = false; - - imap->_responseStatus.errorCode = fw_write_error ? IMAP_STATUS_FIRMWARE_UPDATE_WRITE_FAILED : IMAP_STATUS_FIRMWARE_UPDATE_END_FAILED; - imap->_responseStatus.text.clear(); - -#if !defined(SILENT_MODE) - printDebug(imap, - imap->_responseStatus.text.c_str(), - imap->errorReason().c_str(), - esp_mail_debug_tag_type_error, - !imap->_debug, - false); -#endif - } - } -#endif - - if (write_error || fw_write_error) - return false; - } - - res.chunkIdx++; - return true; -} - -void ESP_Mail_Client::downloadReport(IMAPSession *imap, int progress) -{ - printProgress(progress, imap->_lastProgress); -} - -void ESP_Mail_Client::fetchReport(IMAPSession *imap, int progress, bool download) -{ -#if !defined(SILENT_MODE) - if (imap->_debug && imap->_lastProgress == -1 && strcmp_P(cPart(imap)->filename.c_str(), esp_mail_str_84 /* "message" */) != 0) - esp_mail_debug_print_tag(cPart(imap)->filename.c_str(), esp_mail_debug_tag_type_client, true); - printProgress(progress, imap->_lastProgress); -#endif -} - -void ESP_Mail_Client::searchReport(IMAPSession *imap, int progress) -{ - printProgress(progress, imap->_lastProgress); -} - -struct esp_mail_imap_msg_num_t ESP_Mail_Client::cMSG(IMAPSession *imap) -{ - return imap->_imap_msg_num[cIdx(imap)]; -} - -int ESP_Mail_Client::cIdx(IMAPSession *imap) -{ - return imap->_cMsgIdx; -} - -void ESP_Mail_Client::decodeText(IMAPSession *imap, esp_mail_imap_response_data &res) -{ - int bufLen = res.readLen; - bool rfc822_body_subtype = cPart(imap)->message_sub_type == esp_mail_imap_message_sub_type_rfc822; - if (res.chunkIdx == 0) - { - - imap->_lastProgress = -1; - char *tmp = subStr(res.response, esp_mail_str_36 /* "{" */, esp_mail_str_37 /* "}" */, 0); - if (tmp) - { - res.chunkIdx++; - res.octetCount = 0; - res.octetLength = atoi(tmp); - // release memory - freeMem(&tmp); - cPart(imap)->octetLen = res.octetLength; - cPart(imap)->octetCount = 0; - - bool dlMsg = (rfc822_body_subtype && imap->_imap_data->download.rfc822) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->download.text))); - if (dlMsg) - prepareFilePath(imap, res.filePath, false); - - if (res.filePath.length() == 0) - { - if (!rfc822_body_subtype) - res.filePath += esp_mail_str_84; /* "message" */ - else - joinStringSpace(res.filePath, false, 2, esp_mail_str_85 /* "rfc822" */, esp_mail_str_84 /* "message" */); - } - cPart(imap)->filename = res.filePath; - - if (imap->_storageReady && !cPart(imap)->file_open_write && dlMsg) - { - - prepareFileList(imap, res.filePath); - - int sz = mbfs->open(res.filePath, mbfs_type imap->_imap_data->storage.type, mb_fs_open_mode_write); - if (sz > -1) - { - res.downloadRequest = true; - cPart(imap)->file_open_write = true; - } - else - { - imap->_responseStatus.errorCode = sz; - imap->_responseStatus.text.clear(); -#if !defined(SILENT_MODE) - if (imap->_debug) - esp_mail_debug_print_tag(imap->errorReason().c_str(), esp_mail_debug_tag_type_error, true); -#endif - } - } - - return; - } - else - { -#if !defined(SILENT_MODE) - if (imap->_debug) - esp_mail_debug_print_tag(esp_mail_error_imap_str_12 /* "no centent" */, esp_mail_debug_tag_type_client, false); -#endif - } - } - - yield_impl(); - - if (res.octetLength == 0) - return; - - bool enableDownloads = (imap->_imap_data->download.rfc822 && rfc822_body_subtype) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->download.text))); - - if (imap->_imap_data->download.rfc822 || imap->_imap_data->download.html || imap->_imap_data->download.text || (rfc822_body_subtype && imap->_imap_data->enable.rfc822) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->enable.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->enable.text)))) - { - - if (cPart(imap)->octetCount + bufLen >= res.octetLength) - { - bufLen = res.octetLength - cPart(imap)->octetCount; - cPart(imap)->octetCount += bufLen; - - if (res.octetLength <= res.octetCount && cPart(imap)->xencoding != esp_mail_msg_xencoding_base64 && cPart(imap)->xencoding != esp_mail_msg_xencoding_qp) - bufLen = 0; - - res.response[bufLen] = 0; - } - else - cPart(imap)->octetCount = res.octetCount; - - if (imap->_debug) - fetchReport(imap, 100 * cPart(imap)->octetCount / res.octetLength, enableDownloads); - - if (cPart(imap)->octetCount <= res.octetLength) - { - bool hrdBrk = cPart(imap)->xencoding == esp_mail_msg_xencoding_qp; - hrdBrk &= cPart(imap)->octetCount < res.octetLength; - hrdBrk &= bufLen == 2 && res.response[bufLen - 2] != '\r' && res.response[bufLen - 1] != '\n'; - - // remove soft break for QP - if (bufLen <= QP_ENC_MSG_LEN && res.response[bufLen - 1] == '=' && cPart(imap)->xencoding == esp_mail_msg_xencoding_qp) - { - hrdBrk = false; - res.response[bufLen - 1] = 0; - bufLen--; - } - - size_t olen = 0; - char *decoded = nullptr; - MB_String str; - bool dontDeleteOrModify = false; - - // decode the content based on the transfer decoding - if (cPart(imap)->xencoding == esp_mail_msg_xencoding_base64) - { - decoded = (char *)decodeBase64((const unsigned char *)res.response, bufLen, &olen); - } - else if (cPart(imap)->xencoding == esp_mail_msg_xencoding_qp) - { - decoded = allocMem(bufLen + 10); - decodeQP_UTF8(res.response, decoded); - olen = strlen(decoded); - } - else if (cPart(imap)->xencoding == esp_mail_msg_xencoding_7bit) - { - decoded = decode7Bit_UTF8(res.response); - olen = strlen(decoded); - } - else if (cPart(imap)->xencoding == esp_mail_msg_xencoding_8bit) - { - decoded = decode8Bit_UTF8(res.response); - olen = strlen(decoded); - } - else - { - // binary - dontDeleteOrModify = true; - decoded = res.response; - olen = bufLen; - } - - if (decoded) - { - // charset? apply character decoding to the decoded or nonencoded content - if ((rfc822_body_subtype && imap->_imap_data->enable.rfc822) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->enable.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->enable.text)))) - { - if (imap->_charDecCallback) - { - IMAP_Decoding_Info decoding; - decoding.charset = cPart(imap)->charset.c_str(); - decoding.data = decoded; - decoding.type = IMAP_Decoding_Info::message_part_type_text; - - imap->_charDecCallback(&decoding); - - if (decoding.decodedString.length() > 0) - { - char *buf2 = allocMem(decoding.decodedString.length() + 1); - strcpy(buf2, decoding.decodedString.c_str()); - - if (decoded && !dontDeleteOrModify) - // release memory - freeMem(&decoded); - - decoded = buf2; - olen = strlen(buf2); - } - } - else - { - esp_mail_char_decoding_scheme scheme = getEncodingFromCharset(cPart(imap)->charset.c_str()); - - if (scheme == esp_mail_char_decoding_scheme_iso8859_1) - { - int ilen = olen; - int olen2 = (ilen + 1) * 2; - unsigned char *tmp = allocMem(olen2); - decodeLatin1_UTF8(tmp, &olen2, (unsigned char *)decoded, &ilen); - - if (decoded && !dontDeleteOrModify) - // release memory - freeMem(&decoded); - - olen = olen2; - decoded = (char *)tmp; - } - else if (scheme == esp_mail_char_decoding_scheme_tis_620 || scheme == esp_mail_char_decoding_scheme_iso8859_11 || scheme == esp_mail_char_decoding_scheme_windows_874) - { - char *out = allocMem((olen + 1) * 3); - decodeTIS620_UTF8(out, decoded, olen); - olen = strlen(out); - if (decoded && !dontDeleteOrModify) - // release memory - freeMem(&decoded); - decoded = out; - } - } - - if (cPart(imap)->text.length() < imap->_imap_data->limit.msg_size) - { - - if (cPart(imap)->text.length() + olen < imap->_imap_data->limit.msg_size) - { - cPart(imap)->textLen += olen; - cPart(imap)->text.append(decoded, olen); - if (hrdBrk) - { - appendNewline(cPart(imap)->text); - cPart(imap)->textLen += 2; - } - } - else - { - int d = imap->_imap_data->limit.msg_size - cPart(imap)->text.length(); - cPart(imap)->textLen += d; - if (d > 0) - cPart(imap)->text.append(decoded, d); - - if (hrdBrk) - { - appendNewline(cPart(imap)->text); - cPart(imap)->textLen += 2; - } - } - } - } - - if (res.filePath.length() > 0 && res.downloadRequest) - { - if (mbfs->ready(mbfs_type imap->_imap_data->storage.type)) - { - if (olen > 0) - mbfs->write(mbfs_type imap->_imap_data->storage.type, (uint8_t *)decoded, olen); - if (hrdBrk) - mbfs->write(mbfs_type imap->_imap_data->storage.type, (uint8_t *)"\r\n", 2); - } - } - - sendStreamCB(imap, (void *)decoded, olen, res.chunkIdx, hrdBrk); - - if (decoded && !dontDeleteOrModify) - // release memory - freeMem(&decoded); - } - } - } - - res.chunkIdx++; -} - -void ESP_Mail_Client::sendStreamCB(IMAPSession *imap, void *buf, size_t len, int chunkIndex, bool hrdBrk) -{ - if (imap->_mimeDataStreamCallback && len > 0) - { - MIME_Data_Stream_Info streaminfo; - streaminfo.uid = cHeader(imap)->message_uid; - streaminfo.disposition = cPart(imap)->content_disposition.c_str(); - streaminfo.type = cPart(imap)->content_type.c_str(); - streaminfo.charSet = cPart(imap)->charset.c_str(); - streaminfo.transfer_encoding = cPart(imap)->content_transfer_encoding.c_str(); - streaminfo.cid = cPart(imap)->CID.c_str(); - streaminfo.description = cPart(imap)->content_description.c_str(); - streaminfo.date = cPart(imap)->creation_date.c_str(); - streaminfo.filename = cPart(imap)->filename.c_str(); - streaminfo.size = (cPart(imap)->sizeProp) ? cPart(imap)->attach_data_size : cPart(imap)->octetLen; - streaminfo.name = cPart(imap)->name.c_str(); - streaminfo.octet_size = cPart(imap)->octetLen; - streaminfo.octet_count = cPart(imap)->octetCount; - streaminfo.isFirstData = chunkIndex == 1; - streaminfo.isLastData = !hrdBrk ? cPart(imap)->octetLen == cPart(imap)->octetCount : false; - streaminfo.data_size = len; - streaminfo.data = buf; - streaminfo.flowed = cPart(imap)->plain_flowed; - streaminfo.delsp = cPart(imap)->plain_delsp; - - imap->_mimeDataStreamCallback(streaminfo); - - if (hrdBrk) - { - streaminfo.isFirstData = false; - streaminfo.isLastData = cPart(imap)->octetLen == cPart(imap)->octetCount; - streaminfo.data_size = 2; - streaminfo.data = (void *)"\r\n"; - imap->_mimeDataStreamCallback(streaminfo); - } - } -} - -void ESP_Mail_Client::prepareFilePath(IMAPSession *imap, MB_String &filePath, bool header) -{ - bool rfc822_body_subtype = cPart(imap)->message_sub_type == esp_mail_imap_message_sub_type_rfc822; - MB_String fpath = imap->_imap_data->storage.saved_path; - fpath += esp_mail_str_10; /* "/" */ - fpath += cHeader(imap)->message_uid; - - if (!header) - { - if (!rfc822_body_subtype) - { - fpath += esp_mail_str_86; /* "/msg" */ - if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) - fpath += mimeinfo[esp_mail_file_extension_txt].endsWith; - else if (cPart(imap)->msg_type == esp_mail_msg_type_html) - fpath += mimeinfo[esp_mail_file_extension_htm].endsWith; - } - else - { - fpath += esp_mail_str_87; /* "/rfc822_msg" */ - - if (cPart(imap)->rfc822_msg_Idx > 0) - fpath += cPart(imap)->rfc822_msg_Idx; - - if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) - fpath += mimeinfo[esp_mail_file_extension_txt].endsWith; - else if (cPart(imap)->msg_type == esp_mail_msg_type_html) - fpath += mimeinfo[esp_mail_file_extension_htm].endsWith; - else - // possible rfc822 encapsulated message which cannot fetch its header - fpath += mimeinfo[esp_mail_file_extension_dat].endsWith; - } - } - - filePath = fpath; -} - -void ESP_Mail_Client::sendStorageNotReadyError(IMAPSession *imap, esp_mail_file_storage_type storageType) -{ - -#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) -#if !defined(SILENT_MODE) - if (imap->_debug && (storageType == esp_mail_file_storage_type_flash || storageType == esp_mail_file_storage_type_sd)) - { - if (storageType == esp_mail_file_storage_type_flash) - { - esp_mail_debug_print_tag(esp_mail_error_mem_str_1 /* "flash Storage is not ready." */, esp_mail_debug_tag_type_error, true); -#if defined(MB_ARDUINO_PICO) - esp_mail_debug_print_tag(esp_mail_error_mem_str_10 /* "please make sure that the size of flash filesystem is not 0 in Pico." */, esp_mail_debug_tag_type_error, true); -#endif - } - else if (storageType == esp_mail_file_storage_type_sd) - esp_mail_debug_print_tag(esp_mail_error_mem_str_2 /* "SD Storage is not ready." */, esp_mail_debug_tag_type_error, true); - } -#endif -#endif -} - -IMAPSession::IMAPSession(Client *client) -{ - setClient(client); -} - -IMAPSession::IMAPSession() -{ -} - -IMAPSession::~IMAPSession() -{ - empty(); -} - -bool IMAPSession::closeSession() -{ - _prev_imap_cmd = esp_mail_imap_cmd_sasl_login; - _prev_imap_custom_cmd = esp_mail_imap_cmd_custom; - - if (!connected()) - return false; - - if (_mbif._idleTimeMs > 0) - mStopListen(false); - - if (_loginStatus) - { -#if !defined(ESP8266) - /** - * The strange behavior in ESP8266 SSL client, BearSSLWiFiClientSecure - * The client disposed without memory released after the server close - * the connection due to LOGOUT command, which caused the memory leaks. - */ - if (!MailClient.imapLogout(this)) - return false; -#endif - } - - return MailClient.handleIMAPError(this, 0, true); -} - -bool IMAPSession::connected() -{ - return client.connected(); -} - -bool IMAPSession::connect(Session_Config *session_config, IMAP_Data *imap_data, bool login) -{ - _sessionSSL = false; - _sessionLogin = login; - - if (session_config) - session_config->clearPorts(); - - this->_customCmdResCallback = NULL; - - int ptr = toAddr(*session_config); - session_config->addPtr(&_configPtrList, ptr); - - if (!handleConnection(session_config, imap_data, _sessionSSL)) - return false; - - if (!_sessionLogin) - return true; - - _loginStatus = MailClient.imapAuth(this, _sessionSSL); - - return _loginStatus; -} - -bool IMAPSession::mLogin(MB_StringPtr email, MB_StringPtr password, bool isToken) -{ - if (_loginStatus) - return true; - - if (!MailClient.sessionExisted(this)) - return false; - - _session_cfg->login.email = email; - - _session_cfg->login.accessToken.clear(); - _session_cfg->login.password.clear(); - - if (isToken) - _session_cfg->login.accessToken = password; - else - _session_cfg->login.password = password; - - _loginStatus = MailClient.imapAuth(this, _sessionSSL); - - return _loginStatus; -} - -void IMAPSession::appendIdList(MB_String &list, IMAP_Identification *identification) -{ - - if (identification->name.length() > 0 && identification->name.length() <= 1024) - MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_name].text, identification->name.c_str()); - - if (identification->version.length() > 0 && identification->version.length() <= 1024) - { - if (list.length() > 0) - MailClient.appendSpace(list); - MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_version].text, identification->version.c_str()); - } - - if (identification->os.length() > 0 && identification->os.length() <= 1024) - { - if (list.length() > 0) - MailClient.appendSpace(list); - MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_os].text, identification->os.c_str()); - } - - if (identification->vendor.length() > 0 && identification->vendor.length() <= 1024) - { - if (list.length() > 0) - MailClient.appendSpace(list); - MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_vendor].text, identification->vendor.c_str()); - } - - if (identification->support_url.length() > 0 && identification->support_url.length() <= 1024) - { - if (list.length() > 0) - MailClient.appendSpace(list); - MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_support_url].text, identification->support_url.c_str()); - } - - if (identification->address.length() > 0 && identification->address.length() <= 1024) - { - if (list.length() > 0) - MailClient.appendSpace(list); - MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_address].text, identification->address.c_str()); - } - - if (identification->date.length() > 0 && identification->date.length() <= 1024) - { - if (list.length() > 0) - MailClient.appendSpace(list); - MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_date].text, identification->date.c_str()); - } - - if (identification->command.length() > 0 && identification->command.length() <= 1024) - { - if (list.length() > 0) - MailClient.appendSpace(list); - MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_command].text, identification->command.c_str()); - } - - if (identification->arguments.length() > 0 && identification->arguments.length() <= 1024) - { - if (list.length() > 0) - MailClient.appendSpace(list); - MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_arguments].text, identification->arguments.c_str()); - } - - if (identification->environment.length() > 0 && identification->environment.length() <= 1024) - { - if (list.length() > 0) - MailClient.appendSpace(list); - MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_environment].text, identification->environment.c_str()); - } -} - -bool IMAPSession::id(IMAP_Identification *identification) -{ -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_61 /* "Send client identification..." */, - esp_mail_dbg_str_82 /* "send IMAP command, ID" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - if (!_feature_capability[esp_mail_imap_read_capability_id]) - { -#if !defined(SILENT_MODE) - printDebugNotSupported(); -#endif - return false; - } - - if (!MailClient.reconnect(this)) - return false; - - MB_String cmd, idList; - - appendIdList(idList, identification); - - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_id].text); - - if (idList.length() > 0) - MailClient.appendString(cmd, idList.c_str(), false, false, esp_mail_string_mark_type_round_bracket); - else - { - int bufLen = 50; - char *buf = MailClient.allocMem(bufLen); - snprintf(buf, bufLen, pgm2Str(esp_mail_str_21 /* "(\"name\" \"ESP Mail Client\" \"version\" \"%s\")" */), ESP_MAIL_VERSION); - cmd += buf; - // release memory - MailClient.freeMem(&buf); - } - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_id; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - return true; -} - -String IMAPSession::serverID() -{ - return _server_id_tmp.c_str(); -} - -bool IMAPSession::isAuthenticated() -{ - return _authenticated; -} - -bool IMAPSession::isLoggedIn() -{ - return _loginStatus; -} - -bool IMAPSession::isFirmwareUpdateSuccess() -{ - return _isFirmwareUpdated; -} - -bool IMAPSession::mCustomConnect(Session_Config *session_config, imapResponseCallback callback, MB_StringPtr tag) -{ - this->_customCmdResCallback = callback; - this->_responseStatus.tag = tag; - - bool ssl = false; - if (!handleConnection(session_config, NULL, ssl)) - return false; - - return true; -} - -bool IMAPSession::handleConnection(Session_Config *session_config, IMAP_Data *imap_data, bool &ssl) -{ - - _session_cfg = session_config; - - if (!client.isInitialized()) - return MailClient.handleIMAPError(this, TCP_CLIENT_ERROR_NOT_INITIALIZED, false); - - // Resources are also released if network disconnected. - if (!MailClient.reconnect(this)) - return false; - - // Need to close previous connection first to free resources. - MailClient.closeTCPSession(this); - - _session_cfg = session_config; - _imap_data = imap_data; - - MailClient.setCert(_session_cfg, _session_cfg->certificate.cert_data); - - ssl = false; - if (!connect(ssl)) - { - MailClient.closeTCPSession(this); - return false; - } - - return true; -} - -bool IMAPSession::connect(bool &ssl) -{ - ssl = false; - MB_String buf; - - if (_imap_data) - { - if (_imap_data->fetch.sequence_set.string.length() > 0 || _imap_data->fetch.uid.length() > 0 || _imap_data->fetch.number.length() > 0) - _headerOnly = false; - else - _headerOnly = true; - } - - _totalRead = 0; - _secure = true; - bool secureMode = true; - - client.txBufDivider = 16; // minimum, tx buffer size for ssl data and request command data - client.rxBufDivider = 1; - if (_imap_data) - { - if (!_headerOnly && !_imap_data->firmware_update.attach_filename.length() == 0 && !_imap_data->enable.html && !_imap_data->enable.text && !_imap_data->download.attachment && !_imap_data->download.inlineImg && !_imap_data->download.html && !_imap_data->download.text) - client.rxBufDivider = 16; // minimum rx buffer size for only message header - } - - MailClient.preparePortFunction(_session_cfg, false, _secure, secureMode, ssl); - -#if !defined(SILENT_MODE) - MailClient.printLibInfo(this); -#endif - - MailClient.prepareTime(_session_cfg, this); - - MailClient.setSecure(client, _session_cfg); - - if (!MailClient.beginConnection(_session_cfg, this, secureMode)) - return false; - - // server connected - - client.setTimeout(tcpTimeout); - - // wait for greeting - unsigned long dataMs = millis(); - while (client.connected() && client.available() == 0 && millis() - dataMs < 2000) - { - yield_impl(); - } - - int chunkBufSize = client.available(); - - if (chunkBufSize > 0) - { - char *buf = MailClient.allocMem(chunkBufSize + 1); - client.readBytes(buf, chunkBufSize); - if (_debug && _debugLevel > esp_mail_debug_level_basic && !_customCmdResCallback) - esp_mail_debug_print((const char *)buf, true); - - if (_customCmdResCallback) - { - MailClient.imapResponseStatus(this, buf, esp_mail_str_3 /* "*" */); - _responseStatus.text = buf; - - if (_responseStatus.text[_responseStatus.text.length() - 2] == '\r' && _responseStatus.text[_responseStatus.text.length() - 1] == '\n') - _responseStatus.text[_responseStatus.text.length() - 2] = 0; - - if (_responseStatus.tag.length() == 0) - this->_responseStatus.tag = esp_mail_imap_tag_str; - - _customCmdResCallback(_responseStatus); - } - - // release memory - MailClient.freeMem(&buf); - } - - if (!_customCmdResCallback) - { -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_48 /* "IMAP server connected" */, - esp_mail_dbg_str_33 /* "IMAP server connected" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - } - - return true; -} - -void IMAPSession::debug(int level) -{ - if (level > esp_mail_debug_level_none) - { - if (level > esp_mail_debug_level_basic && level < esp_mail_debug_level_maintainer) - level = esp_mail_debug_level_basic; - _debugLevel = level; - _debug = true; - client.setDebugLevel(level); - } - else - { - _debugLevel = esp_mail_debug_level_none; - _debug = false; - client.setDebugLevel(0); - } -} - -String IMAPSession::errorReason() -{ - return MailClient.errorReason(false, _responseStatus.errorCode, _responseStatus.text.c_str()); -} - -int IMAPSession::errorCode() -{ - return _responseStatus.errorCode; -} - -bool IMAPSession::mSelectFolder(MB_StringPtr folderName, bool readOnly) -{ - if (connected()) - { - if (!openFolder(folderName, readOnly)) - return false; - } - else - { - _currentFolder = folderName; - } - - if (!connected()) - { - _responseStatus.errorCode = IMAP_STATUS_OPEN_MAILBOX_FAILED; - _responseStatus.clear(); - } - - return connected(); -} - -void IMAPSession::setTCPTimeout(unsigned long timeoutSec) -{ - tcpTimeout = timeoutSec; -} - -void IMAPSession::setClient(Client *client) -{ - this->client.setClient(client); -} - -void IMAPSession::setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password) -{ - this->client.setGSMClient(client, modem, pin, apn, user, password); -} - -void IMAPSession::networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB) -{ - this->client.networkConnectionRequestCallback(networkConnectionCB); -} - -void IMAPSession::networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB) -{ - this->client.networkStatusRequestCallback(networkStatusCB); -} - -void IMAPSession::setNetworkStatus(bool status) -{ - this->client.setNetworkStatus(status); - MailClient.networkStatus = status; -} - -void IMAPSession::setSSLBufferSize(int rx, int tx) -{ - this->client.setIOBufferSize(rx, tx); -} - -bool IMAPSession::mOpenFolder(MB_StringPtr folderName, bool readOnly) -{ - if (!connected()) - { - _responseStatus.errorCode = IMAP_STATUS_OPEN_MAILBOX_FAILED; - _responseStatus.clear(); - return false; - } - - if (readOnly) - return openMailbox(folderName, esp_mail_imap_auth_mode::esp_mail_imap_mode_examine, true, false); - else - return openMailbox(folderName, esp_mail_imap_auth_mode::esp_mail_imap_mode_select, true, false); -} - -bool IMAPSession::getFolders(FoldersCollection &folders) -{ - if (!connected()) - return false; - return getMailboxes(folders); -} - -bool IMAPSession::mCloseFolder(bool expunge) -{ - - // no folder opened - if (_currentFolder.length() == 0) - { -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_error_imap_str_11 /* "no mailbox opened" */, - esp_mail_error_imap_str_11 /* "no mailbox opened" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - return false; - } - - return closeMailbox(expunge); -} - -bool IMAPSession::mListen(bool recon) -{ - if (!MailClient.sessionExisted(this)) - return false; - - if (_currentFolder.length() == 0) - { - _mbif._floderChangedState = false; - _mbif._folderChanged = false; - return false; - } - - if (!MailClient.reconnect(this)) - return false; - - if (!connected()) - { - if (!_imap_data || (millis() - _last_server_connect_ms < 2000 && _last_server_connect_ms > 0)) - return false; - - _last_server_connect_ms = millis(); - - bool ssl = false; - - if (!connect(ssl)) - { - MailClient.closeTCPSession(this); - return false; - } - - // re-authenticate after session closed - if (!MailClient.imapAuth(this, ssl)) - { - MailClient.closeTCPSession(this); - return false; - } - - // re-open folder - if (!selectFolder(_currentFolder.c_str())) - return false; - } - - // no IDLE was not supported (should be checked after imapAuth) - if (!_feature_capability[esp_mail_imap_read_capability_idle]) - { -#if !defined(SILENT_MODE) - printDebugNotSupported(); -#endif - } - - if (_mbif._idleTimeMs == 0) - { - _mbif._polling_status.messageNum = 0; - _mbif._polling_status.type = imap_polling_status_type_undefined; - _mbif._polling_status.argument.clear(); - _mbif._recentCount = 0; - _mbif._folderChanged = false; - -#if !defined(SILENT_MODE) - MB_String dbMsg; - - if (!recon) - { - - dbMsg = esp_mail_dbg_str_51; /* "listening to " */ - dbMsg += _currentFolder; - dbMsg += esp_mail_dbg_str_52; /* " folder changes" */ - MailClient.printDebug(this, - esp_mail_cb_str_29 /* "Listening to mailbox changes..." */, - dbMsg.c_str(), - esp_mail_debug_tag_type_client, - true, - false); - } - -#endif - - if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_idle].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_idle; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - -#if !defined(SILENT_MODE) - if (!recon) - { - - dbMsg = esp_mail_str_88 /* "polling established on " */; - dbMsg += MailClient.Time.getDateTimeString(MailClient.Time.getCurrentTimestamp(), "%B %d, %Y %H:%M:%S"); - MailClient.printDebug(this, - esp_mail_cb_str_49 /* "Polling established" */, - dbMsg.c_str(), - esp_mail_debug_tag_type_client, - true, - false); - } - -#endif - - _mbif._idleTimeMs = millis(); - } - else - { - if (_mbif._floderChangedState) - { - _mbif._floderChangedState = false; - _mbif._folderChanged = false; - _mbif._polling_status.messageNum = 0; - _mbif._polling_status.type = imap_polling_status_type_undefined; - _mbif._polling_status.argument.clear(); - _mbif._recentCount = 0; - } - - size_t imap_idle_tmo = _imap_data->limit.imap_idle_timeout; - - if (imap_idle_tmo < 60 * 1000 || imap_idle_tmo > 29 * 60 * 1000) - imap_idle_tmo = 10 * 60 * 1000; - - size_t host_check_interval = _imap_data->limit.imap_idle_host_check_interval; - - if (host_check_interval < 30 * 1000 || host_check_interval > imap_idle_tmo) - host_check_interval = 60 * 1000; - - if (millis() - _last_host_check_ms > host_check_interval && connected()) - { - _last_host_check_ms = millis(); - - IPAddress ip; - - if (client.hostByName(_session_cfg->server.host_name.c_str(), ip) != 1) - { - closeSession(); - _mbif._idleTimeMs = millis(); - return false; - } - } - - return MailClient.parseIdleResponse(this); - } - - return true; -} - -bool IMAPSession::mStopListen(bool recon) -{ - _mbif._idleTimeMs = 0; - _mbif._floderChangedState = false; - _mbif._folderChanged = false; - _mbif._polling_status.messageNum = 0; - _mbif._polling_status.type = imap_polling_status_type_undefined; - _mbif._polling_status.argument.clear(); - _mbif._recentCount = 0; - - if (!connected() || _currentFolder.length() == 0 || !_feature_capability[esp_mail_imap_read_capability_idle]) - return false; - - if (MailClient.imapSend(this, imap_commands[esp_mail_imap_command_done].text, true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_done; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - -#if !defined(SILENT_MODE) - if (!recon) - { - MailClient.printDebug(this, - esp_mail_cb_str_50 /* "Mailbox listening stopped" */, - esp_mail_dbg_str_54 /* "Mailbox listening stopped" */, - esp_mail_debug_tag_type_client, - true, - false); - } -#endif - - return true; -} - -bool IMAPSession::folderChanged() -{ - return _mbif._floderChangedState; -} - -bool IMAPSession::noop() -{ - -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_62 /* "Sending noop..." */, - esp_mail_dbg_str_83 /* "send IMAP command, NOOP" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - - if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_noop].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_noop; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - return true; -} - -void IMAPSession::checkUID() -{ - if (MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_uid].text) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_flags].text) || - MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_body].text) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_peek].text) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_text].text) || - MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_header].text) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_fields].text) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, esp_mail_str_40 /* "[" */) || - MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, esp_mail_str_41 /* "]" */) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_mime].text)) - _imap_data->fetch.uid = esp_mail_str_3; /* "*" */ -} - -void IMAPSession::checkPath() -{ - MB_String path = _imap_data->storage.saved_path; - if (path[0] != '/') - { - path = '/'; - path += _imap_data->storage.saved_path; - path = path.c_str(); - } -} - -bool IMAPSession::headerOnly() -{ - return _headerOnly; -} - -struct esp_mail_imap_msg_list_t IMAPSession::data() -{ - struct esp_mail_imap_msg_list_t ret; - - for (size_t i = 0; i < _headers.size(); i++) - { - -#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) - if (MailClient.getFreeHeap() < ESP_MAIL_MIN_MEM) - continue; -#endif - struct esp_mail_imap_msg_item_t itm; - itm.setRFC822Headers(&_headers[i].header_fields); - itm.UID = _headers[i].message_uid; - itm.msgNo = _headers[i].message_no; - itm.flags = _headers[i].flags.c_str(); - itm.acceptLang = _headers[i].accept_language.c_str(); - itm.contentLang = _headers[i].content_language.c_str(); - itm.hasAttachment = _headers[i].hasAttachment; - itm.fetchError = _headers[i].error_msg.c_str(); - - getMessages(i, itm); - - getRFC822Messages(i, itm); - - ret.msgItems.push_back(itm); - } - - return ret; -} - -SelectedFolderInfo IMAPSession::selectedFolder() -{ - return _mbif; -} - -void IMAPSession::callback(imapStatusCallback imapCallback) -{ - _statusCallback = imapCallback; -} - -void IMAPSession::characterDecodingCallback(imapCharacterDecodingCallback callback) -{ - _charDecCallback = callback; -} - -void IMAPSession::mimeDataStreamCallback(MIMEDataStreamCallback mimeDataStreamCallback) -{ - _mimeDataStreamCallback = mimeDataStreamCallback; -} - -void IMAPSession::setSystemTime(time_t ts, float gmtOffset) -{ - MailClient.Time.setTimestamp(ts, gmtOffset); -} - -void IMAPSession::keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount) -{ - this->client.keepAlive(tcpKeepIdleSeconds, tcpKeepIntervalSeconds, tcpKeepCount); -} - -bool IMAPSession::isKeepAlive() -{ - return this->client.isKeepAlive(); -} - -void IMAPSession::getMessages(uint16_t messageIndex, struct esp_mail_imap_msg_item_t &msg) -{ - msg.text.content = ""; - msg.text.charSet = ""; - msg.text.content_type = ""; - msg.text.transfer_encoding = ""; - msg.html.content = ""; - msg.html.charSet = ""; - msg.html.content_type = ""; - msg.html.transfer_encoding = ""; - - if (messageIndex < _headers.size()) - { - int sz = _headers[messageIndex].part_headers.size(); - if (sz > 0) - { - for (int i = 0; i < sz; i++) - { - if (_headers[messageIndex].part_headers[i].attach_type == esp_mail_att_type_attachment || (!_headers[messageIndex].part_headers[i].rfc822_part && _headers[messageIndex].part_headers[i].message_sub_type != esp_mail_imap_message_sub_type_rfc822)) - { - if (_headers[messageIndex].part_headers[i].attach_type == esp_mail_att_type_none) - { - if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_plain || _headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_enriched) - { - msg.text.content = _headers[messageIndex].part_headers[i].text.c_str(); - msg.text.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); - msg.text.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); - msg.text.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); - } - - if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_html) - { - msg.html.content = _headers[messageIndex].part_headers[i].text.c_str(); - msg.html.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); - msg.html.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); - msg.html.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); - } - } - else - { - struct esp_mail_attachment_info_t att; - att.filename = _headers[messageIndex].part_headers[i].filename.c_str(); - att.mime = _headers[messageIndex].part_headers[i].content_type.c_str(); - att.name = _headers[messageIndex].part_headers[i].name.c_str(); - att.size = _headers[messageIndex].part_headers[i].attach_data_size; - att.description = _headers[messageIndex].part_headers[i].content_description.c_str(); - att.creationDate = _headers[messageIndex].part_headers[i].creation_date.c_str(); - att.type = _headers[messageIndex].part_headers[i].attach_type; - msg.attachments.push_back(att); - } - } - } - } - } -} - -void IMAPSession::getRFC822Messages(uint16_t messageIndex, struct esp_mail_imap_msg_item_t &msg) -{ - if (messageIndex < _headers.size()) - { - int size = _headers[messageIndex].part_headers.size(); - int partIdx = 0; - int cIdx = 0; - IMAP_MSG_Item *_rfc822 = nullptr; - if (size > 0) - { - for (int i = 0; i < size; i++) - { - if (_headers[messageIndex].part_headers[i].message_sub_type == esp_mail_imap_message_sub_type_rfc822 && _headers[messageIndex].part_headers[i].attach_type != esp_mail_att_type_attachment) - { - if (_headers[messageIndex].part_headers[i].rfc822_part) - { - if (partIdx > 0) - msg.rfc822.push_back(*_rfc822); - cIdx = i; - partIdx++; - _rfc822 = new IMAP_MSG_Item(); - _rfc822->setRFC822Headers(&_headers[messageIndex].part_headers[i].rfc822_header); - } - else - { - if (MailClient.multipartMember(_headers[messageIndex].part_headers[cIdx].partNumStr, _headers[messageIndex].part_headers[i].partNumStr)) - { - if (_headers[messageIndex].part_headers[i].attach_type == esp_mail_att_type_none) - { - if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_plain || _headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_enriched) - { - _rfc822->text.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); - _rfc822->text.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); - _rfc822->text.content = _headers[messageIndex].part_headers[i].text.c_str(); - _rfc822->text.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); - } - if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_html) - { - _rfc822->html.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); - _rfc822->html.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); - _rfc822->html.content = _headers[messageIndex].part_headers[i].text.c_str(); - _rfc822->html.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); - } - } - else - { - struct esp_mail_attachment_info_t att; - att.filename = _headers[messageIndex].part_headers[i].filename.c_str(); - att.mime = _headers[messageIndex].part_headers[i].content_type.c_str(); - att.name = _headers[messageIndex].part_headers[i].name.c_str(); - att.size = _headers[messageIndex].part_headers[i].attach_data_size; - att.description = _headers[messageIndex].part_headers[i].content_description.c_str(); - att.creationDate = _headers[messageIndex].part_headers[i].creation_date.c_str(); - att.type = _headers[messageIndex].part_headers[i].attach_type; - _rfc822->attachments.push_back(att); - } - } - } - } - } - - if ((int)msg.rfc822.size() < partIdx && _rfc822 != nullptr) - msg.rfc822.push_back(*_rfc822); - } - } -} - -bool IMAPSession::closeMailbox(bool expunge) -{ -#if !defined(SILENT_MODE) - MB_String dbMsg = esp_mail_dbg_str_32; /* "closing the " */ - dbMsg += _currentFolder; - dbMsg += esp_mail_str_89; /* " folder..." */ - - MailClient.printDebug(this, - esp_mail_cb_str_27 /* "Closing the mailbox folder..." */, - dbMsg.c_str(), - esp_mail_debug_tag_type_client, - true, - false); -#endif - if (!MailClient.reconnect(this)) - return false; - - // If folder was opened in readonly mode, use CLOSE command will not expunge the deleted messages - // Or user intent to expunge the deleted message after close the folder. - if (expunge || _readOnlyMode) - { - - if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_close].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_close; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_CLOSE_MAILBOX_FAILED, false)) - return false; - } - else - { - // Close folder without expunge - if (_feature_capability[esp_mail_imap_read_capability_unselect]) - { - if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_unselect].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_unselect; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_CLOSE_MAILBOX_FAILED, false)) - return false; - } - else - { - // Open non-existing folder - MB_String folder = esp_mail_str_84 /* "message" */; - folder += MailClient.Time.getCurrentTimestamp(); - MB_StringPtr folderPtr; - folderPtr = toStringPtr(folder); - openMailbox(folderPtr, esp_mail_imap_auth_mode::esp_mail_imap_mode_examine, true, true); - } - } - - _currentFolder.clear(); - _mailboxOpened = false; - - return true; -} - -bool IMAPSession::openMailbox(MB_StringPtr folder, esp_mail_imap_auth_mode mode, bool waitResponse, bool unselect) -{ - - if (!MailClient.sessionExisted(this)) - return false; - - MB_String _folder = folder; - - if (!MailClient.reconnect(this)) - return false; - - if (_folder.length() == 0) - return false; - - bool _dbg = _debug; - imapStatusCallback _cb = _statusCallback; - - // The SELECT/EXAMINE command automatically deselects any currently selected mailbox - // before attempting the new selection (RFC3501 p.33) - - // folder should not close for re-selection otherwise the server returned * BAD Command Argument Error. 12 - - if (!unselect) - { - - bool sameFolder = strcmp(_currentFolder.c_str(), _folder.c_str()) == 0; - - // guards 3 seconds to prevent accidently frequently select the same folder with the same mode - if (!_mailboxOpened && sameFolder && millis() - _lastSameFolderOpenMillis < 3000) - { - if ((_readOnlyMode && mode == esp_mail_imap_mode_examine) || (!_readOnlyMode && mode == esp_mail_imap_mode_select)) - return true; - } - - if (!sameFolder) - _currentFolder = folder; - -#if !defined(SILENT_MODE) - MB_String dbMsg = esp_mail_dbg_str_68; /* "selecting the " */ - dbMsg += _currentFolder; - dbMsg += esp_mail_str_89; /* " folder..." */ - - MailClient.printDebug(this, - esp_mail_cb_str_51 /* "Open the mailbox folder..." */, - dbMsg.c_str(), - esp_mail_debug_tag_type_client, - true, - false); -#endif - } - else - { - // Hide the callback and debug info - _debug = false; - _statusCallback = NULL; - _currentFolder = folder; - } - - MB_String cmd; - MailClient.appendSpace(cmd, true, mode == esp_mail_imap_mode_examine ? imap_commands[esp_mail_imap_command_examine].text : imap_commands[esp_mail_imap_command_select].text); - MailClient.appendString(cmd, _currentFolder.c_str(), false, false, esp_mail_string_mark_type_double_quote); - - if (isCondStoreSupported()) - { - MailClient.appendSpace(cmd); - MailClient.appendString(cmd, imap_commands[esp_mail_imap_command_condstore].text, false, false, esp_mail_string_mark_type_round_bracket); - } - - _imap_cmd = mode == esp_mail_imap_mode_examine ? esp_mail_imap_cmd_examine : esp_mail_imap_cmd_select; - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - if (!unselect) - _lastSameFolderOpenMillis = millis(); - - if (waitResponse && !MailClient.handleIMAPResponse(this, IMAP_STATUS_OPEN_MAILBOX_FAILED, false)) - { - if (!unselect) - return false; - } - - if (unselect) - { - _statusCallback = _cb; - _debug = _dbg; - } - - if (mode == esp_mail_imap_mode_examine) - _readOnlyMode = true; - else if (mode == esp_mail_imap_mode_select) - _readOnlyMode = false; - - _mailboxOpened = !unselect; - - return true; -} - -bool IMAPSession::getMailboxes(FoldersCollection &folders) -{ -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_16 /* "Reading the list of mailboxes..." */, - esp_mail_dbg_str_35 /* "send IMAP command, LIST" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - _folders.clear(); - - MB_String cmd; - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_list].text); - MailClient.appendString(cmd, NULL, false, false, esp_mail_string_mark_type_double_quote); - MailClient.prependSpace(cmd, esp_mail_str_3 /* "*" */); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_list; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) - return false; - - folders = _folders; - return true; -} - -bool IMAPSession::mGetSubscribesMailboxes(MB_StringPtr reference, MB_StringPtr mailbox, FoldersCollection &folders) -{ -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_30 /* "Listing the subscribed mailboxes..." */, - esp_mail_dbg_str_56 /* "send IMAP command, LSUB" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - folders.clear(); - - MB_String cmd; - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_lsub].text); - MailClient.appendString(cmd, MB_String(reference).c_str(), false, false, esp_mail_string_mark_type_double_quote); - MailClient.appendSpace(cmd); - MailClient.appendString(cmd, MB_String(mailbox).c_str(), false, false, esp_mail_string_mark_type_double_quote); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - FoldersCollection tmp; - - for (size_t i = 0; i < this->_folders.size(); i++) - tmp.add(this->_folders[i]); - - this->_folders.clear(); - - _imap_cmd = esp_mail_imap_cmd_lsub; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) - return false; - - for (size_t i = 0; i < this->_folders.size(); i++) - folders.add(this->_folders[i]); - - this->_folders.clear(); - - for (size_t i = 0; i < tmp.size(); i++) - this->_folders.add(tmp[i]); - - tmp.clear(); - - return true; -} - -bool IMAPSession::mSubscribe(MB_StringPtr folder) -{ -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_31 /* "Subscribe mailbox..." */, - esp_mail_dbg_str_57 /* "send IMAP command, SUBSCRIBE" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - MB_String cmd; - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_subscribe].text); - MailClient.appendString(cmd, MB_String(folder).c_str(), false, false, esp_mail_string_mark_type_double_quote); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_subscribe; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) - return false; - - return true; -} - -bool IMAPSession::mUnSubscribe(MB_StringPtr folder) -{ -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_32 /* "Unsubscribe mailbox..." */, - esp_mail_dbg_str_58 /* "send IMAP command, UNSUBSCRIBE" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - MB_String cmd; - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_unsubscribe].text); - MailClient.appendString(cmd, MB_String(folder).c_str(), false, false, esp_mail_string_mark_type_double_quote); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_unsubscribe; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) - return false; - - return true; -} - -bool IMAPSession::mFetchSequenceSet() -{ - - MB_String cmd; - if (_imap_data->fetch.sequence_set.UID) - MailClient.appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_fetch].text); - else - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_fetch].text); - - MailClient.appendSpace(cmd, false, _imap_data->fetch.sequence_set.string.c_str()); - MailClient.appendString(cmd, imap_commands[esp_mail_imap_command_uid].text, false, false, esp_mail_string_mark_type_round_bracket); - - addModifier(cmd, esp_mail_imap_command_changedsince, _imap_data->fetch.modsequence); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_msg_num.clear(); - - _imap_cmd = esp_mail_imap_cmd_fetch_sequence_set; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) - return false; - - return true; -} - -MB_String IMAPSession::prependTag(PGM_P cmd, PGM_P tag) -{ - MB_String s = (tag == NULL) ? esp_mail_imap_tag_str : tag; - MailClient.appendSpace(s); - s += cmd; - return s; -} - -bool IMAPSession::checkCapabilities() -{ -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_52 /* "Checking the capability..." */, - esp_mail_dbg_str_76 /* "check the capability" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_capability].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_capability; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_CHECK_CAPABILITIES_FAILED, false)) - return false; - - return true; -} - -bool IMAPSession::mCreateFolder(MB_StringPtr folderName) -{ -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_59 /* "Creating folder..." */, - esp_mail_dbg_str_49 /* "creating folder" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - MB_String cmd; - MailClient.joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_create].text, folderName); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_create; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - return true; -} - -bool IMAPSession::mRenameFolder(MB_StringPtr currentFolderName, MB_StringPtr newFolderName) -{ -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_53 /* "Renaming folder..." */, - esp_mail_dbg_str_55 /* "renaming folder" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - MB_String o = currentFolderName; - MB_String n = newFolderName; - - o.trim(); - n.trim(); - - if (o == n) - return true; - - if (o.length() == 0 || n.length() == 0) - return false; - - MB_String cmd; - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_rename].text); - MailClient.appendString(cmd, o.c_str(), false, false, esp_mail_string_mark_type_double_quote); - MailClient.appendSpace(cmd); - MailClient.appendString(cmd, n.c_str(), false, false, esp_mail_string_mark_type_double_quote); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_rename; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - if (_currentFolder == o) - selectFolder(n.c_str(), false); - - return true; -} - -int IMAPSession::getUID(int msgNum) -{ -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_25 /* "Get UID..." */, - esp_mail_dbg_str_79 /* "get UID" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - int uid = mGetUID(msgNum); - - if (!MailClient.sessionExisted(this)) - return false; - -#if !defined(SILENT_MODE) - MB_String dbMsg = esp_mail_cb_str_54; /* "UID is " */ - dbMsg += uid; - - MailClient.printDebug(this, - dbMsg.c_str(), - dbMsg.c_str(), - esp_mail_debug_tag_type_client, - true, - false); -#endif - return uid; -} - -int IMAPSession::mGetUID(int msgNum) -{ - - if (_currentFolder.length() == 0) - return 0; - - MB_String cmd; - MailClient.joinStringSpace(cmd, true, 3, imap_commands[esp_mail_imap_command_fetch].text, MB_String(msgNum).c_str(), imap_commands[esp_mail_imap_command_uid].text); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return 0; - - _imap_cmd = esp_mail_imap_cmd_get_uid; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return 0; - - return _uid_tmp; -} - -const char *IMAPSession::getFlags(int msgNum) -{ -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_55 /* "Get Flags..." */, - esp_mail_dbg_str_80 /* "get flags" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - - _flags_tmp.clear(); - if (_currentFolder.length() == 0) - return _flags_tmp.c_str(); - - MB_String cmd, cmd2; - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_fetch].text); - MailClient.appendString(cmd2, imap_commands[esp_mail_imap_command_flags].text, false, false, esp_mail_string_mark_type_round_bracket); - MailClient.joinStringSpace(cmd, false, 2, MB_String(msgNum).c_str(), cmd2.c_str()); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return _flags_tmp.c_str(); - - _imap_cmd = esp_mail_imap_cmd_get_flags; - MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false); - - return _flags_tmp.c_str(); -} - -bool IMAPSession::mSendCustomCommand(MB_StringPtr cmd, imapResponseCallback callback, MB_StringPtr tag) -{ - - _customCmdResCallback = callback; - _cmd = cmd; - _cmd.trim(); - - MB_String _tag = cmd; - _tag.trim(); - - MB_String _tag2 = tag; - _tag2.trim(); - - if (_tag2.length() == 0) - { - int p = MailClient.strpos(_tag.c_str(), " ", 0); - if (p > -1) - { - _tag.erase(p, _tag.length() - p); - _tag.trim(); - _responseStatus.tag = _tag; - } - } - else - { - _responseStatus.tag = tag; - _responseStatus.tag.trim(); - if (MailClient.strpos(_cmd.c_str(), _responseStatus.tag.c_str(), 0, false) == -1) - _cmd = prependTag(_cmd.c_str(), _responseStatus.tag.c_str()); - } - - // filter for specific command - if (_cmd.find(imap_cmd_pre_tokens[esp_mail_imap_command_idle].c_str()) != MB_String::npos) - _imap_custom_cmd = esp_mail_imap_cmd_idle; - else if (_cmd.find(imap_cmd_pre_tokens[esp_mail_imap_command_append].c_str()) != MB_String::npos) - _imap_custom_cmd = esp_mail_imap_cmd_append; - else if (_cmd.find(imap_cmd_pre_tokens[esp_mail_imap_command_login].c_str()) != MB_String::npos) - _imap_custom_cmd = esp_mail_imap_cmd_sasl_login; - else if (_cmd.find(imap_cmd_pre_tokens[esp_mail_imap_command_logout].c_str()) != MB_String::npos) - _imap_custom_cmd = esp_mail_imap_cmd_logout; - else - _imap_custom_cmd = esp_mail_imap_cmd_custom; - - if (_prev_imap_custom_cmd != _imap_custom_cmd || _imap_custom_cmd != esp_mail_imap_cmd_idle) - { - if (MailClient.imapSend(this, _cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - { - _prev_imap_custom_cmd = esp_mail_imap_cmd_custom; - return false; - } - } - - _imap_cmd = esp_mail_imap_cmd_custom; - - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - { - _prev_imap_custom_cmd = esp_mail_imap_cmd_custom; - return false; - } - - if (_imap_custom_cmd == esp_mail_imap_cmd_sasl_login) - { - _authenticated = true; - _loginStatus = true; - } - else if (_imap_custom_cmd == esp_mail_imap_cmd_logout) - { - _authenticated = false; - _loginStatus = false; - } - - _prev_imap_custom_cmd = _imap_custom_cmd; - - if (MailClient.strposP(_cmd.c_str(), imap_auth_capabilities[esp_mail_auth_capability_starttls].text, 0, false) == 0) - { - bool verify = false; - - if (_session_cfg) - verify = _session_cfg->certificate.verify; - - if (!client.connectSSL(verify)) - return false; - - // set the secure mode - if (_session_cfg) - { - // We reset the prefer connection mode in case user set it. - _session_cfg->secure.startTLS = false; - _session_cfg->secure.mode = esp_mail_secure_mode_undefined; - } - - _secure = true; - } - - return true; -} - -bool IMAPSession::mSendData(MB_StringPtr data, bool lastData, esp_mail_imap_command cmd) -{ - MB_String _data = data; - if (MailClient.imapSend(this, _data.c_str(), lastData) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - if (lastData) - { - _imap_cmd = cmd; - _cmd.clear(); - - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - } - - return true; -} - -bool IMAPSession::mSendData(uint8_t *data, size_t size, bool lastData, esp_mail_imap_command cmd) -{ - - if (MailClient.imapSend(this, data, size) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - if (lastData) - { - if (MailClient.imapSend(this, pgm2Str(esp_mail_str_42 /* "\r\n" */), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = cmd; - _cmd.clear(); - - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - } - - return true; -} - -bool IMAPSession::mDeleteFolder(MB_StringPtr folderName) -{ -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_56 /* "Deleting folder..." */, - esp_mail_dbg_str_81 /* "delete folder" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - MB_String cmd; - MailClient.joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_delete].text, MB_String(folderName).c_str()); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_delete; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - return true; -} - -bool IMAPSession::isCondStoreSupported() -{ - return _feature_capability[esp_mail_imap_read_capability_condstore]; -} - -bool IMAPSession::isModseqSupported() -{ - return isCondStoreSupported() && !_mbif._nomodsec; -} - -void IMAPSession::addModifier(MB_String &cmd, esp_mail_imap_command_types type, int32_t modsequence) -{ - if (modsequence > -1 && isModseqSupported()) - { - MB_String modifier; - MailClient.joinStringSpace(modifier, false, 2, imap_commands[type].text, MB_String(modsequence).c_str()); - MailClient.appendSpace(cmd); - MailClient.appendString(cmd, modifier.c_str(), false, false, esp_mail_string_mark_type_round_bracket); - } -} - -bool IMAPSession::deleteMsg(MessageList *toDelete, const char *sequenceSet, bool UID, bool expunge, int32_t modsequence) -{ - if ((toDelete && toDelete->_list.size() == 0) || (!toDelete && strlen(sequenceSet) == 0)) - return false; - - if (!selectFolder(_currentFolder.c_str(), false)) - return false; - -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_57 /* "Deleting message(s)..." */, - esp_mail_dbg_str_75 /* "delete message(s)" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - - if (!MailClient.sessionExisted(this)) - return false; - - MB_String cmd; - if (UID || toDelete) - { - MailClient.appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_store].text); - - if (toDelete && toDelete->_list.size() > 0) - MailClient.appendList(cmd, toDelete->_list); - } - else if (!toDelete && strlen(sequenceSet) > 0) - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_store].text); - - if (!toDelete && strlen(sequenceSet) > 0) - cmd += sequenceSet; - - addModifier(cmd, esp_mail_imap_command_unchangedsince, modsequence); - - cmd += imap_cmd_pre_tokens[esp_mail_imap_command_plus_flags]; - MailClient.prependDot(cmd, imap_commands[esp_mail_imap_command_silent].text); - MailClient.appendSpace(cmd); - MailClient.appendString(cmd, esp_mail_str_91 /* "\\Deleted" */, false, false, esp_mail_string_mark_type_round_bracket); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_store; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - if (expunge) - { - if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_expunge].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_expunge; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - } - - return true; -} - -bool IMAPSession::mDeleteMessages(MessageList *toDelete, bool expunge, int32_t modsequence) -{ - if (toDelete->_list.size() > 0) - return deleteMsg(toDelete, "", false, expunge); - return true; -} - -bool IMAPSession::mDeleteMessagesSet(MB_StringPtr sequenceSet, bool UID, bool expunge, int32_t modsequence) -{ - return deleteMsg(nullptr, MB_String(sequenceSet).c_str(), UID, expunge); -} - -bool IMAPSession::copyMsg(MessageList *toCopy, const char *sequenceSet, bool UID, MB_StringPtr dest) -{ -#if !defined(SILENT_MODE) - MB_String dbMsg = esp_mail_dbg_str_48; /* "copying message(s) to " */ - dbMsg += dest; - - MailClient.printDebug(this, - esp_mail_cb_str_58 /* "Copying message(s)..." */, - dbMsg.c_str(), - esp_mail_debug_tag_type_client, - true, - false); -#endif - - if (!MailClient.sessionExisted(this)) - return false; - - if ((toCopy && toCopy->_list.size() == 0) || (!toCopy && strlen(sequenceSet) == 0)) - return false; - - if (!selectFolder(_currentFolder.c_str(), false)) - return false; - - MB_String cmd; - if (UID || toCopy) - { - MailClient.appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_copy].text); - - if (toCopy && toCopy->_list.size() > 0) - MailClient.appendList(cmd, toCopy->_list); - } - else if (!toCopy && strlen(sequenceSet) > 0) - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_copy].text); - - if (!toCopy && strlen(sequenceSet) > 0) - cmd += sequenceSet; - - MailClient.prependSpace(cmd, MB_String(dest).c_str()); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_copy; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - return true; -} - -bool IMAPSession::mCopyMessages(MessageList *toCopy, MB_StringPtr dest) -{ - return copyMsg(toCopy, "", false, dest); -} - -bool IMAPSession::mCopyMessagesSet(MB_StringPtr sequenceSet, bool UID, MB_StringPtr dest) -{ - return copyMsg(nullptr, MB_String(sequenceSet).c_str(), UID, dest); -} - -bool IMAPSession::moveMsg(MessageList *toMove, const char *sequenceSet, bool UID, MB_StringPtr dest) -{ -#if !defined(SILENT_MODE) - MB_String dbMsg = esp_mail_dbg_str_59; /* "moving message(s) to " */ - dbMsg += dest; - - MailClient.printDebug(this, - esp_mail_cb_str_60 /* "Moving message(s)..." */, - dbMsg.c_str(), - esp_mail_debug_tag_type_client, - true, - false); -#endif - - if (!MailClient.sessionExisted(this)) - return false; - - if ((toMove && toMove->_list.size() == 0) || (!toMove && strlen(sequenceSet) == 0)) - return false; - - if (!_feature_capability[esp_mail_imap_read_capability_move]) - { - - bool ret = mCopyMessages(toMove, dest); - - if (ret) - ret = mDeleteMessages(toMove, true); - - return ret; - } - - if (!selectFolder(_currentFolder.c_str(), false)) - return false; - - MB_String cmd; - if (UID || toMove) - { - MailClient.appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_move].text); - if (toMove && toMove->_list.size() > 0) - MailClient.appendList(cmd, toMove->_list); - } - else if (!toMove && strlen(sequenceSet) > 0) - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_move].text); - - if (!toMove && strlen(sequenceSet) > 0) - cmd += sequenceSet; - - MailClient.prependSpace(cmd, MB_String(dest).c_str()); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_move; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - return true; -} - -bool IMAPSession::mMoveMessages(MessageList *toMove, MB_StringPtr dest) -{ - return moveMsg(toMove, "", false, dest); -} - -bool IMAPSession::mMoveMessagesSet(MB_StringPtr sequenceSet, bool UID, MB_StringPtr dest) -{ - return moveMsg(nullptr, MB_String(sequenceSet).c_str(), UID, dest); -} - -bool IMAPSession::mGetSetQuota(MB_StringPtr quotaRoot, IMAP_Quota_Root_Info *data, bool getMode) -{ - -#if !defined(SILENT_MODE) - PGM_P p1 = getMode ? esp_mail_cb_str_33 /* "Get quota root resource usage and limit..." */ : esp_mail_cb_str_34 /* "Set quota root resource usage and limit..." */; - PGM_P p2 = getMode ? esp_mail_dbg_str_60 /* "send IMAP command, GETQUOTA" */ : esp_mail_dbg_str_61 /* "send IMAP command, SETQUOTA" */; - MailClient.printDebug(this, p1, p2, esp_mail_debug_tag_type_client, true, false); -#endif - - if (!_feature_capability[esp_mail_imap_read_capability_quota]) - { -#if !defined(SILENT_MODE) - printDebugNotSupported(); -#endif - return false; - } - - MB_String _quotaRoot = quotaRoot; - - MB_String cmd; - if (getMode) - { - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_getquota].text); - MailClient.appendString(cmd, _quotaRoot.c_str(), false, false, esp_mail_string_mark_type_double_quote); - } - else - { - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_setquota].text); - MailClient.appendString(cmd, _quotaRoot.c_str(), false, false, esp_mail_string_mark_type_double_quote); - MailClient.appendSpace(cmd); - - MB_String cmd2; - MailClient.joinStringSpace(cmd2, false, 2, data->name.c_str(), MB_String((int)data->limit).c_str()); - MailClient.appendString(cmd, cmd2.c_str(), false, false, esp_mail_string_mark_type_round_bracket); - } - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _quota_tmp.clear(); - - _imap_cmd = (getMode) ? esp_mail_imap_cmd_get_quota : esp_mail_imap_cmd_set_quota; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - if (getMode) - { - mParseQuota(_quota_tmp.c_str(), data); - } - - _quota_tmp.clear(); - - return true; -} - -void IMAPSession::mParseQuota(const char *quota, IMAP_Quota_Root_Info *data) -{ - _vectorImpl tokens; - MailClient.splitToken(quota, tokens, " "); - data->quota_root = tokens[0]; - tokens[1].erase(0, 1); - data->name = tokens[1]; - data->usage = atoi(tokens[2].c_str()); - data->limit = atoi(tokens[3].c_str()); -} - -bool IMAPSession::mGetQuotaRoots(MB_StringPtr mailbox, IMAP_Quota_Roots_List *quotaRootsList) -{ -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_35 /* "Get the list of quota roots..." */, - esp_mail_dbg_str_62 /* "send IMAP command, GETQUOTAROOT" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - - if (!MailClient.sessionExisted(this)) - return false; - - if (!_feature_capability[esp_mail_imap_read_capability_quota]) - { -#if !defined(SILENT_MODE) - printDebugNotSupported(); -#endif - return false; - } - - MB_String _mailbox = mailbox; - - MB_String cmd; - MailClient.appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_getquota].text, imap_commands[esp_mail_imap_command_root].text); - MailClient.appendString(cmd, _mailbox.c_str(), false, false, esp_mail_string_mark_type_double_quote); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _quota_root_tmp.clear(); - _quota_tmp.clear(); - - _imap_cmd = esp_mail_imap_cmd_get_quota_root; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - _vectorImpl tokens; - MailClient.splitToken(_quota_root_tmp.c_str(), tokens, ","); - - for (size_t i = 0; i < tokens.size(); i++) - { - _vectorImpl tk; - MailClient.splitToken(tokens[i].c_str(), tk, ":"); - IMAP_Quota_Root_Info data; - if (tk.size() > 1) - mParseQuota(tk[1].c_str(), &data); - else - data.quota_root = tk[0]; - - quotaRootsList->add(data); - } - - _quota_root_tmp.clear(); - _quota_tmp.clear(); - - return true; -} - -bool IMAPSession::mManageACL(MB_StringPtr mailbox, IMAP_Rights_List *acl_list, IMAP_Rights_Info *acl, MB_StringPtr identifier, esp_mail_imap_command type) -{ - -#if !defined(SILENT_MODE) - - PGM_P p1 = NULL; - PGM_P p2 = NULL; - if (type == esp_mail_imap_cmd_get_acl) - { - p1 = esp_mail_cb_str_36; /* "Get the ACL..." */ - p2 = esp_mail_dbg_str_77; /* "get the ACL" */ - } - else if (type == esp_mail_imap_cmd_set_acl) - { - p1 = esp_mail_cb_str_37; /* "Setting the ACL..." */ - p2 = esp_mail_dbg_str_78; /* "set the ACL" */ - } - else if (type == esp_mail_imap_cmd_delete_acl) - { - p1 = esp_mail_cb_str_38; /* "Deleting the ACL..." */ - p2 = esp_mail_dbg_str_72; /* "delete the ACL" */ - } - else if (type == esp_mail_imap_cmd_my_rights) - { - p1 = esp_mail_cb_str_39; /* "Get my ACL..." */ - p2 = esp_mail_dbg_str_23; /* "get my ACL" */ - } - - MailClient.printDebug(this, p1, p2, esp_mail_debug_tag_type_client, true, false); - -#endif - - if (!MailClient.sessionExisted(this)) - return false; - - if (!_feature_capability[esp_mail_imap_read_capability_acl]) - { -#if !defined(SILENT_MODE) - printDebugNotSupported(); -#endif - return false; - } - - MB_String _mailbox = mailbox; - MB_String _identifier = identifier; - - MB_String cmd; - if (type == esp_mail_imap_cmd_get_acl) - { - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_get_acl].text); - MailClient.appendString(cmd, _mailbox.c_str(), false, false, esp_mail_string_mark_type_double_quote); - } - else if (type == esp_mail_imap_cmd_set_acl) - { - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_set_acl].text); - MailClient.appendString(cmd, MB_String(mailbox).c_str(), false, false, esp_mail_string_mark_type_double_quote); - MailClient.appendSpace(cmd); - MailClient.appendString(cmd, acl->identifier.c_str(), false, false, esp_mail_string_mark_type_double_quote); - MailClient.appendSpace(cmd); - MB_String rights; - getRights(rights, acl); - MailClient.appendString(cmd, rights.c_str(), false, false, esp_mail_string_mark_type_double_quote); - } - else if (type == esp_mail_imap_cmd_delete_acl) - { - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_delete_acl].text); - MailClient.appendString(cmd, _mailbox.c_str(), false, false, esp_mail_string_mark_type_double_quote); - MailClient.appendSpace(cmd); - MailClient.appendString(cmd, _identifier.c_str(), false, false, esp_mail_string_mark_type_double_quote); - } - else if (type == esp_mail_imap_cmd_my_rights) - { - MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_myrights].text); - MailClient.appendString(cmd, _mailbox.c_str(), false, false, esp_mail_string_mark_type_double_quote); - } - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _acl_tmp.clear(); - - _imap_cmd = type; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - if (type == esp_mail_imap_cmd_get_acl) - parseACL(_acl_tmp, acl_list); - else if (type == esp_mail_imap_cmd_my_rights) - parseRights(_acl_tmp, acl); - - _acl_tmp.clear(); - - return true; -} - -void IMAPSession::parseACL(MB_String &acl_str, IMAP_Rights_List *right_list) -{ - _vectorImpl tokens; - MailClient.splitToken(acl_str.c_str(), tokens, " "); - - for (size_t i = 0; i < tokens.size(); i += 2) - { - IMAP_Rights_Info info; - info.identifier = tokens[i]; - parseRights(tokens[i + 1], &info); - right_list->add(info); - } -} - -void IMAPSession::parseRights(MB_String &righs_str, IMAP_Rights_Info *info) -{ - for (size_t i = 0; i < righs_str.length(); i++) - { - uint8_t c = righs_str[i] - 97; - if (c >= esp_mail_imap_rights_administer && c < esp_mail_imap_rights_maxType) - info->rights[c] = true; - } -} - -void IMAPSession::getRights(MB_String &righs_str, IMAP_Rights_Info *info) -{ - for (size_t i = esp_mail_imap_rights_administer; i < esp_mail_imap_rights_maxType; i++) - { - if (info->rights[i]) - righs_str += (char)(i + 97); - } -} - -bool IMAPSession::mNamespace(IMAP_Namespaces_List *ns) -{ - -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_40 /* "Get namespace..." */, - esp_mail_dbg_str_67 /* "send IMAP command, NAMESPACE" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - - if (!MailClient.sessionExisted(this)) - return false; - - if (!_feature_capability[esp_mail_imap_read_capability_namespace]) - { -#if !defined(SILENT_MODE) - printDebugNotSupported(); -#endif - return false; - } - - if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_namespace].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _ns_tmp.clear(); - - _imap_cmd = esp_mail_imap_cmd_namespace; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - int cnt = 0; - MB_String personal, other, shared; - - for (size_t i = 0; i < _ns_tmp.length(); i++) - { - if (i > 0 && i < _ns_tmp.length() - 1 && _ns_tmp[i] == ' ' && _ns_tmp[i - 1] != '"' && _ns_tmp[i + 1] != '"') - { - if (cnt == 0) - personal = _ns_tmp.substr(0, i); - else if (cnt == 1) - { - other = _ns_tmp.substr(personal.length() + 1, i - personal.length() - 1); - shared = _ns_tmp.substr(i + 1, _ns_tmp.length() - i - 1); - } - cnt++; - } - } - - if (personal.length() > 4) - parseNamespaces(personal, &(ns->personal_namespaces)); - - if (other.length() > 4) - parseNamespaces(other, &(ns->other_users_namespaces)); - - if (shared.length() > 4) - parseNamespaces(shared, &(ns->shared_namespaces)); - - return true; -} - -bool IMAPSession::mEnable(MB_StringPtr capability) -{ - -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_41 /* "Enable capability..." */, - esp_mail_dbg_str_68 /* "send IMAP command, ENABLE" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - - if (!_feature_capability[esp_mail_imap_read_capability_enable]) - { -#if !defined(SILENT_MODE) - printDebugNotSupported(); -#endif - return false; - } - - MB_String _cap = capability; - - MB_String cmd; - MailClient.joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_enable].text, _cap.c_str()); - - if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - _imap_cmd = esp_mail_imap_cmd_enable; - if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) - return false; - - return true; -} - -void IMAPSession::parseNamespaces(MB_String &ns_str, IMAP_Namespaces *ns) -{ - MB_String tmp = ns_str.substr(2, ns_str.length() - 4); - tmp.replaceAll(")(", " "); - _vectorImpl tokens; - MailClient.splitToken(tmp.c_str(), tokens, " "); - - for (size_t i = 0; i < tokens.size(); i += 2) - { - IMAP_Namespace_Info info; - info.prefix = tokens[i]; - info.delimiter = tokens[i + 1]; - ns->add(info); - } -} - -void IMAPSession::empty() -{ - _nextUID.clear(); - _unseenMsgIndex.clear(); - _flags_tmp.clear(); - _quota_tmp.clear(); - _quota_root_tmp.clear(); - _acl_tmp.clear(); - _ns_tmp.clear(); - _server_id_tmp.clear(); - _sdFileList.clear(); - clearMessageData(); -} - -IMAP_Status IMAPSession::status() -{ - return _cbData; -} - -String IMAPSession::fileList() -{ - return _sdFileList.c_str(); -} - -void IMAPSession::clearMessageData() -{ - for (size_t i = 0; i < _headers.size(); i++) - { - _headers[i].part_headers.clear(); - } - - _headers.clear(); - _imap_msg_num.clear(); - _mbif._searchCount = 0; - _flags_tmp.clear(); - -#if defined(MB_USE_STD_VECTOR) - _folders.clear(); - _mbif._flags.clear(); -#endif -} - -void IMAPSession::printDebugNotSupported() -{ - -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_error_imap_str_13 /* "not supported by IMAP server" */, - esp_mail_error_imap_str_13 /* "not supported by IMAP server" */, - esp_mail_debug_tag_type_error, - true, - false); -#endif -} - -IMAP_Status::IMAP_Status() -{ -} - -IMAP_Status::~IMAP_Status() -{ - empty(); -} - -const char *IMAP_Status::info() -{ - return _info.c_str(); -} - -bool IMAP_Status::success() -{ - return _success; -} - -void IMAP_Status::empty() -{ - _info.clear(); -} - -#endif - + +#ifndef ESP_MAIL_IMAP_H +#define ESP_MAIL_IMAP_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +/** + * Mail Client Arduino Library for Espressif's ESP32 and ESP8266, Raspberry Pi RP2040 Pico, and SAMD21 with u-blox NINA-W102 WiFi/Bluetooth module + * + * Created August 28, 2023 + * + * This library allows Espressif's ESP32, ESP8266, SAMD and RP2040 Pico devices to send and read Email through the SMTP and IMAP servers. + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * 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 "ESP_Mail_Client_Version.h" +#include "ESP_Mail_Client.h" + +#if defined(ENABLE_IMAP) + +#if defined(MB_ARDUINO_PICO) +extern uint8_t _FS_start; +extern uint8_t _FS_end; +#endif + +int ESP_Mail_Client::decodeChar(const char *s) +{ + return 16 * hexval(*(s + 1)) + hexval(*(s + 2)); +} + +void ESP_Mail_Client::decodeQP_UTF8(const char *buf, char *out) +{ + char *tmp = strP(esp_mail_str_47 /* "0123456789ABCDEF" */); + int idx = 0; + while (*buf) + { + if (*buf != '=') + out[idx++] = *buf++; + else if (*(buf + 1) == '\r' && *(buf + 2) == '\n') + buf += 3; + else if (*(buf + 1) == '\n') + buf += 2; + else if (!strchr(tmp, *(buf + 1))) + out[idx++] = *buf++; + else if (!strchr(tmp, *(buf + 2))) + out[idx++] = *buf++; + else + { + out[idx++] = decodeChar(buf); + buf += 3; + } + } + + // release memory + freeMem(&tmp); +} + +char *ESP_Mail_Client::decode7Bit_UTF8(char *buf) +{ + MB_String s; + + // only non NULL and 7-bit ASCII are allowed + + // rfc2045 section 2.7 + + size_t len = buf ? strlen(buf) : 0; + + for (size_t i = 0; i < len; i++) + { + if (buf[i] > 0 && buf[i] < 128 && i < 998) + s.append(1, buf[i]); + } + + // some special chars can't send in 7bit unless encoded as queoted printable string + char *decoded = allocMem(s.length() + 10); + decodeQP_UTF8(s.c_str(), decoded); + s.clear(); + return decoded; +} + +char *ESP_Mail_Client::decode8Bit_UTF8(char *buf) +{ + MB_String s; + + // only non NULL and less than 998 octet length are allowed + + // rfc2045 section 2.8 + + size_t len = buf ? strlen(buf) : 0; + + for (size_t i = 0; i < len; i++) + { + if (buf[i] > 0 && i < 998) + s.append(1, buf[i]); + } + + char *decoded = allocMem(s.length() + 1); + strcpy(decoded, s.c_str()); + s.clear(); + return decoded; +} + +void ESP_Mail_Client::decodeString(IMAPSession *imap, MB_String &str, const char *enc) +{ + + size_t p1 = 0, p2 = 0; + MB_String headerEnc; + + if (strlen(enc) == 0) + { + while (str[p1] == ' ' && p1 < str.length() - 1) + p1++; + + if (str[p1] == '=' && str[p1 + 1] == '?') + { + p2 = str.find('?', p1 + 2); + if (p2 != MB_String::npos) + headerEnc = str.substr(p1 + 2, p2 - p1 - 2); + } + } + else + headerEnc = enc; + + int bufSize = str.length() + 10; + char *buf = allocMem(bufSize); + + // Content Q and B decodings + RFC2047Decoder.decode(mbfs, buf, str.c_str(), bufSize); + + // Char set decoding + esp_mail_char_decoding_scheme scheme = getEncodingFromCharset(headerEnc.c_str()); + if (imap->_charDecCallback) + { + IMAP_Decoding_Info decoding; + decoding.charset = headerEnc.c_str(); + decoding.data = buf; + decoding.type = IMAP_Decoding_Info::message_part_type_header; + + imap->_charDecCallback(&decoding); + + if (decoding.decodedString.length() > 0) + { + char *buf2 = allocMem(decoding.decodedString.length() + 1); + strcpy(buf2, decoding.decodedString.c_str()); + // release memory and point to new buffer + freeMem(&buf); + buf = buf2; + } + } + else if (scheme == esp_mail_char_decoding_scheme_iso8859_1) + { + int len = strlen(buf); + int olen = (len + 1) * 2; + unsigned char *out = allocMem(olen); + decodeLatin1_UTF8(out, &olen, (unsigned char *)buf, &len); + // release memory and point to new buffer + freeMem(&buf); + buf = (char *)out; + } + else if (scheme == esp_mail_char_decoding_scheme_tis_620 || scheme == esp_mail_char_decoding_scheme_iso8859_11 || scheme == esp_mail_char_decoding_scheme_windows_874) + { + size_t len2 = strlen(buf); + char *tmp = allocMem((len2 + 1) * 3); + decodeTIS620_UTF8(tmp, buf, len2); + // release memory and point to new buffer + freeMem(&buf); + buf = tmp; + } + + str = buf; + // release memory + freeMem(&buf); +} + +esp_mail_char_decoding_scheme ESP_Mail_Client::getEncodingFromCharset(const char *enc) +{ + esp_mail_char_decoding_scheme scheme = esp_mail_char_decoding_scheme_default; + + for (int i = esp_mail_char_decoding_utf8; i < esp_mail_char_decoding_maxType; i++) + { + if (strpos(enc, char_decodings[i].text, 0, false) > -1) + scheme = (esp_mail_char_decoding_scheme)i; + } + + return scheme; +} + +int ESP_Mail_Client::encodeUnicode_UTF8(char *out, uint32_t utf) +{ + if (utf <= 0x7F) + { + // Plain ASCII + out[0] = (char)utf; + out[1] = 0; + return 1; + } + else if (utf <= 0x07FF) + { + // 2-byte unicode + out[0] = (char)(((utf >> 6) & 0x1F) | 0xC0); + out[1] = (char)(((utf >> 0) & 0x3F) | 0x80); + out[2] = 0; + return 2; + } + else if (utf <= 0xFFFF) + { + // 3-byte unicode + out[0] = (char)(((utf >> 12) & 0x0F) | 0xE0); + out[1] = (char)(((utf >> 6) & 0x3F) | 0x80); + out[2] = (char)(((utf >> 0) & 0x3F) | 0x80); + out[3] = 0; + return 3; + } + else if (utf <= 0x10FFFF) + { + // 4-byte unicode + out[0] = (char)(((utf >> 18) & 0x07) | 0xF0); + out[1] = (char)(((utf >> 12) & 0x3F) | 0x80); + out[2] = (char)(((utf >> 6) & 0x3F) | 0x80); + out[3] = (char)(((utf >> 0) & 0x3F) | 0x80); + out[4] = 0; + return 4; + } + else + { + // error - use replacement character + out[0] = (char)0xEF; + out[1] = (char)0xBF; + out[2] = (char)0xBD; + out[3] = 0; + return 0; + } +} + +void ESP_Mail_Client::decodeTIS620_UTF8(char *out, const char *in, size_t len) +{ + // output is the 3-byte value UTF-8 + int j = 0; + for (size_t i = 0; i < len; i++) + { + if (in[i] < 0x80) + out[j++] = in[i]; + else if ((in[i] >= 0xa0 && in[i] < 0xdb) || (in[i] > 0xde && in[i] < 0xfc)) + { + int unicode = 0x0e00 + in[i] - 0xa0; + char o[5]; + memset(o, 0, 5); + int r = encodeUnicode_UTF8(o, unicode); + for (int x = 0; x < r; x++) + out[j++] = o[x]; + } + } +} + +int ESP_Mail_Client::decodeLatin1_UTF8(unsigned char *out, int *outlen, const unsigned char *in, int *inlen) +{ + unsigned char *outstart = out; + const unsigned char *base = in; + const unsigned char *processed = in; + unsigned char *outend = out + *outlen; + const unsigned char *inend; + unsigned int c; + int bits; + + inend = in + (*inlen); + while ((in < inend) && (out - outstart + 5 < *outlen)) + { + c = *in++; + + /* assertion: c is a single UTF-4 value */ + if (out >= outend) + break; + if (c < 0x80) + { + *out++ = c; + bits = -6; + } + else + { + *out++ = ((c >> 6) & 0x1F) | 0xC0; + bits = 0; + } + + for (; bits >= 0; bits -= 6) + { + if (out >= outend) + break; + *out++ = ((c >> bits) & 0x3F) | 0x80; + } + processed = (const unsigned char *)in; + } + *outlen = out - outstart; + *inlen = processed - base; + return (0); +} + +bool ESP_Mail_Client::sendFetchCommand(IMAPSession *imap, int msgIndex, esp_mail_imap_command cmdCase) +{ + + MB_String cmd, cmd2, cmd3; + appendHeadersFetchCommand(imap, cmd, msgIndex, false); + + if (cmdCase == esp_mail_imap_cmd_fetch_body_mime) + { + joinStringDot(cmd2, 2, imap_commands[esp_mail_imap_command_header].text, imap_commands[esp_mail_imap_command_fields].text); + appendSpace(cmd2); + joinStringSpace(cmd3, false, 2, message_headers[esp_mail_message_header_field_content_type].text, message_headers[esp_mail_message_header_field_content_transfer_encoding].text); + appendString(cmd2, cmd3.c_str(), false, false, esp_mail_string_mark_type_round_bracket); + } + else if (cmdCase == esp_mail_imap_cmd_fetch_body_text) + cmd2 = cPart(imap)->partNumFetchStr.length() > 0 ? cPart(imap)->partNumFetchStr.c_str() : imap_commands[esp_mail_imap_command_text].text; + else if (cmdCase == esp_mail_imap_cmd_fetch_body_attachment) + cmd2 = cPart(imap)->partNumFetchStr; + + if (cmd2.length() > 0) + appendString(cmd, cmd2.c_str(), false, false, esp_mail_string_mark_type_square_bracket); + + bool allowPartialFetch = (cmdCase == esp_mail_imap_cmd_fetch_body_attachment && cPart(imap)->is_firmware_file) ? false : true; + + if (imap->_mimeDataStreamCallback) + allowPartialFetch = false; + + if (allowPartialFetch) + { + // Apply partial fetch in case download was disabled. + if (!imap->_storageReady && imap->_attDownload && cmdCase == esp_mail_imap_cmd_fetch_body_attachment) + cmd += esp_mail_str_48; /* "<0.0>" */ // This case should not happen because the memory storage was previousely checked. + else if ((!imap->_msgDownload && cmdCase == esp_mail_imap_cmd_fetch_body_text) || (imap->_msgDownload && !imap->_storageReady)) + { + cmd += esp_mail_str_49; /* "<0." */ + cmd += imap->_imap_data->limit.msg_size; + cmd += esp_mail_str_20; /* ">" */ + } + } + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + return true; +} + +bool ESP_Mail_Client::readMail(IMAPSession *imap, bool closeSession) +{ + if (!imap || !sessionExisted(imap)) + return false; + + imap->checkUID(); + imap->checkPath(); + imap->_cbData._success = false; + + if (!imap->connected()) + imap->_mailboxOpened = false; + + imap->_isFirmwareUpdated = false; + + MB_String buf, command, _uid; + + size_t readCount = 0; + imap->_multipart_levels.clear(); + + if (!reconnect(imap)) + return false; + + imap->_msgDownload = imap->_imap_data->download.text || imap->_imap_data->download.html; + imap->_attDownload = imap->_imap_data->download.attachment || imap->_imap_data->download.inlineImg; + + if (!imap->_storageChecked) + { + imap->_storageChecked = true; + imap->_storageReady = imap->_imap_data->download.header || (!imap->_imap_data->fetch.headerOnly && (imap->_msgDownload || imap->_attDownload)) ? mbfs->checkStorageReady(mbfs_type imap->_imap_data->storage.type) : true; + } + + bool readyToDownload = (imap->_msgDownload || imap->_attDownload) && imap->_storageReady; + + if (!imap->_storageReady) + sendStorageNotReadyError(imap, imap->_imap_data->storage.type); + +#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) + + int cmem = MailClient.getFreeHeap(); + + if (cmem < ESP_MAIL_MIN_MEM) + { +#if !defined(SILENT_MODE) + if (imap->_debug && imap->_statusCallback && !imap->_customCmdResCallback) + { + esp_mail_debug_print(); + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_OUT_OF_MEMORY, true); + } +#endif + + goto out; + } +#endif + + if (!imap->connected() && !imap->_loginStatus) + { +#if !defined(SILENT_MODE) + if (imap->_debug && imap->_statusCallback && !imap->_customCmdResCallback) + { + esp_mail_debug_print(); + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_NOT_YET_LOGIN, true); + } +#endif + return false; + } + + // new session + if (!imap->connected()) + { + // authenticate new + + bool ssl = false; + + if (!imap->connect(ssl)) + { + closeTCPSession(imap); + return false; + } + + if (!imapAuth(imap, ssl)) + { + closeTCPSession(imap); + return false; + } + } + else + { + // If time config changed, we will update time + MailClient.prepareTime(imap->_session_cfg, imap); + + // reuse session + for (size_t i = 0; i < imap->_headers.size(); i++) + imap->_headers[i].part_headers.clear(); + imap->_headers.clear(); + + if (imap->_imap_data->fetch.sequence_set.string.length() > 0 || imap->_imap_data->fetch.uid.length() > 0 || imap->_imap_data->fetch.number.length() > 0) + imap->_headerOnly = false; + else + imap->_headerOnly = true; + } + + imap->_rfc822_part_count = 0; + imap->_mbif._availableItems = 0; + imap->_imap_msg_num.clear(); + imap->_uidSearch = false; + imap->_mbif._searchCount = 0; + + if (imap->_currentFolder.length() == 0) + return handleIMAPError(imap, IMAP_STATUS_NO_MAILBOX_FOLDER_OPENED, false); + + if (!imap->_mailboxOpened || (imap->_imap_data->fetch.set_seen && !imap->_headerOnly && imap->_readOnlyMode)) + { + if (!imap->openFolder(imap->_currentFolder.c_str(), imap->_readOnlyMode && !imap->_imap_data->fetch.set_seen)) + return handleIMAPError(imap, IMAP_STATUS_OPEN_MAILBOX_FAILED, false); + } + + if (imap->_headerOnly) + { + if (imap->_imap_data->search.criteria.length() > 0) + { + command = esp_mail_imap_tag_str; + +#if !defined(SILENT_MODE) + printDebug(imap, + esp_mail_cb_str_18 /* "Searching messages..." */, + esp_mail_dbg_str_36 /* "searching messages" */, + esp_mail_debug_tag_type_client, + true, + false); + +#endif + + if (strposP(imap->_imap_data->search.criteria.c_str(), imap_cmd_post_tokens[esp_mail_imap_command_uid].c_str(), 0) != -1) + { + imap->_uidSearch = true; + command += imap_cmd_pre_tokens[esp_mail_imap_command_uid]; + } + + command += imap_cmd_pre_tokens[esp_mail_imap_command_search]; + + imap->_imap_data->search.criteria.trim(); + + MB_String tag; + appendTagSpace(tag); + + // Remove internal used reserved tag + if (strpos(imap->_imap_data->search.criteria.c_str(), tag.c_str(), 0, true) == 0) + imap->_imap_data->search.criteria.erase(0, tag.length()); + + for (size_t i = 0; i < imap->_imap_data->search.criteria.length(); i++) + { + if (imap->_imap_data->search.criteria[i] != ' ' && imap->_imap_data->search.criteria[i] != '\r' && imap->_imap_data->search.criteria[i] != '\n') + buf.append(1, imap->_imap_data->search.criteria[i]); + + if (imap->_imap_data->search.criteria[i] == ' ') + { + + if ((imap->_uidSearch && strcmp(buf.c_str(), imap_commands[esp_mail_imap_command_uid].text) == 0) || (imap->_unseen && buf.find(imap_commands[esp_mail_imap_command_all].text) != MB_String::npos)) + buf.clear(); + + if (strcmp(buf.c_str(), imap_commands[esp_mail_imap_command_search].text) != 0 && buf.length() > 0) + prependSpace(command, buf.c_str()); + + buf.clear(); + } + } + + if (imap->_unseen && strpos(imap->_imap_data->search.criteria.c_str(), imap_cmd_pre_tokens[esp_mail_imap_command_new].c_str(), 0) == -1) + command += imap_cmd_pre_tokens[esp_mail_imap_command_new]; + + if (buf.length() > 0) + prependSpace(command, buf.c_str()); + + if (!imap->isModseqSupported() && strpos(imap->_imap_data->search.criteria.c_str(), imap_cmd_pre_tokens[esp_mail_imap_command_modsec].c_str(), 0, false) != -1) + { + imap->_responseStatus.errorCode = IMAP_STATUS_MODSEQ_WAS_NOT_SUPPORTED; +#if !defined(SILENT_MODE) + + if (imap->_statusCallback) + sendErrorCB(imap, imap->errorReason().c_str(), false, false); + + if (imap->_debug) + esp_mail_debug_print_tag(imap->errorReason().c_str(), esp_mail_debug_tag_type_error, true); + +#endif + return false; + } + + if (imapSend(imap, command.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + command.clear(); + + imap->_imap_cmd = esp_mail_imap_cmd_search; + + if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, closeSession)) + return false; + +#if !defined(SILENT_MODE) + if (imap->_statusCallback) + { + callBackSendNewLine(imap, false); + if (imap->_imap_msg_num.size() > 0) + { + int bufLen = 100; + char *buf = allocMem(bufLen); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_50 /* "Search limit: %d\nFound %d messages\nShow %d messages\n" */), (int)imap->_imap_data->limit.search, imap->_mbif._searchCount, (int)imap->_imap_msg_num.size()); + sendCallback(imap, buf, false, false); + // release memory + freeMem(&buf); + } + else + sendCallback(imap, esp_mail_error_imap_str_9 /* "no messages found for the specified search criteria" */, false, false); + } +#endif + } + else + { +#if !defined(SILENT_MODE) + if (imap->_statusCallback) + sendCallback(imap, esp_mail_error_imap_str_10 /* "no search criteria provided, then fetching the latest message" */, false, false); +#endif + imap->_mbif._availableItems++; + + esp_mail_imap_msg_num_t msg_num; + msg_num.type = esp_mail_imap_msg_num_type_number; + msg_num.value = (uint32_t)imap->_mbif._msgCount; + + imap->_imap_msg_num.push_back(msg_num); + imap->_headerOnly = false; + imap->_imap_data->fetch.number = imap->_mbif._msgCount; + } + } + else + { + + if (imap->_imap_data->fetch.sequence_set.string.length() > 0) + { + imap->_headerOnly = imap->_imap_data->fetch.sequence_set.headerOnly; + imap->mFetchSequenceSet(); + + imap->_mbif._availableItems = imap->_imap_msg_num.size(); + } + else + { + if (imap->_imap_data->fetch.uid.length() > 0) + { + imap->_mbif._availableItems++; + + esp_mail_imap_msg_num_t msg_num; + msg_num.type = esp_mail_imap_msg_num_type_uid; + msg_num.value = (uint32_t)atoi(imap->_imap_data->fetch.uid.c_str()); + + imap->_imap_msg_num.push_back(msg_num); + } + + if (imap->_imap_data->fetch.number.length() > 0) + { + imap->_mbif._availableItems++; + + esp_mail_imap_msg_num_t msg_num; + msg_num.type = esp_mail_imap_msg_num_type_number; + msg_num.value = (uint32_t)atoi(imap->_imap_data->fetch.number.c_str()); + + imap->_imap_msg_num.push_back(msg_num); + } + } + } + + if (imap->_imap_data->fetch.headerOnly) + imap->_headerOnly = true; + + for (size_t i = 0; i < imap->_imap_msg_num.size(); i++) + { + imap->_cMsgIdx = i; + imap->_totalRead++; + +#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) + if (MailClient.getFreeHeap() - (imap->_imap_data->limit.msg_size * (i + 1)) < ESP_MAIL_MIN_MEM) + { + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_OUT_OF_MEMORY, true); + goto out; + } +#endif + +#if !defined(SILENT_MODE) + if (imap->_statusCallback) + { + readCount++; + int bufLen = 100; + PGM_P p = imap->_uidSearch || imap->_imap_msg_num[i].type == esp_mail_imap_msg_num_type_uid ? esp_mail_str_52 /* "Fetch message %d, UID: %d" */ : esp_mail_str_53 /* "Fetch message %d, Number: %d" */; + char *buf = allocMem(bufLen); + snprintf(buf, bufLen, pgm2Str(p), imap->_totalRead, (int)imap->_imap_msg_num[i].value); + sendCallback(imap, buf, true, false); + // release memory + freeMem(&buf); + } + + if (imap->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_37 /* "send IMAP command, FETCH" */, esp_mail_debug_tag_type_client, true); +#endif + MB_String cmd; + appendHeadersFetchCommand(imap, cmd, i, true); + + // We fetch only known RFC822 headers because + // using Fetch RFC822.HEADER reurns all included unused headers + // which required more memory and network bandwidth. + MB_String cmd2; + appendRFC822HeadersFetchCommand(cmd2); + + appendString(cmd, cmd2.c_str(), false, false, esp_mail_string_mark_type_square_bracket); + + imap->addModifier(cmd, esp_mail_imap_command_changedsince, imap->_imap_data->fetch.modsequence); + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + { + if (i < imap->_imap_msg_num.size() - 1) + continue; + return false; + } + + imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_header; + + int err = imap->_headerOnly ? IMAP_STATUS_IMAP_RESPONSE_FAILED : IMAP_STATUS_BAD_COMMAND; + + if (!handleIMAPResponse(imap, err, closeSession)) + { + if (i < imap->_imap_msg_num.size() - 1) + continue; + return false; + } + + if (!cHeader(imap)) + continue; + + if (imap->_imap_msg_num[i].type == esp_mail_imap_msg_num_type_number) + cHeader(imap)->message_uid = imap->mGetUID(cHeader(imap)->message_no); + + cHeader(imap)->flags = imap->getFlags(cHeader(imap)->message_no); + + if (!imap->_headerOnly) + { + imap->_cPartIdx = 0; + + // Reset attachment state if it was set by "multipart/mixed" content type header + cHeader(imap)->hasAttachment = false; + +#if !defined(SILENT_MODE) + if (imap->_debug) + debugPrintNewLine(); +#endif + + // multipart + if (cHeader(imap)->multipart) + { + struct esp_mail_imap_multipart_level_t mlevel; + mlevel.level = 1; + mlevel.fetch_rfc822_header = false; + mlevel.append_body_text = false; + imap->_multipart_levels.push_back(mlevel); + + if (!fetchMultipartBodyHeader(imap, i)) + return false; + } + else + { + // single part + if (imap->_debug) + printBodyPartFechingDubug(imap, "1", false); + + cHeader(imap)->partNumStr.clear(); + if (!sendFetchCommand(imap, i, esp_mail_imap_cmd_fetch_body_mime)) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_mime; + if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, closeSession)) + return false; + } + + if (readyToDownload && imap->_imap_data->storage.saved_path.length() == 0) + imap->_imap_data->storage.saved_path = esp_mail_str_10; /* "/" */ + + if (cHeader(imap)->part_headers.size() > 0) + { + + cHeader(imap)->sd_alias_file_count = 0; + + imap->_sdFileList.clear(); + if (!mbfs->longNameSupported()) + imap->_sdFileList = esp_mail_str_40; /* "[" */ + +#if !defined(SILENT_MODE) + + if (cHeader(imap)->attachment_count > 0 && imap->_statusCallback) + { + int bufLen = 100; + char *buf = allocMem(bufLen); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_54 /* "Attachments (%d)" */), cHeader(imap)->attachment_count); + callBackSendNewLine(imap, false); + sendCallback(imap, buf, false, false); + // release memory + freeMem(&buf); + + int count = 0; + + for (size_t j = 0; j < cHeader(imap)->part_headers.size(); j++) + { + imap->_cPartIdx = j; + if (!cPart(imap)->rfc822_part && cPart(imap)->attach_type != esp_mail_att_type_none) + { + count++; + MB_String str = count; + appendDot(str); + prependSpace(str, cPart(imap)->filename.c_str()); + sendCallback(imap, str.c_str(), false, false); + } + } + } + +#endif + + MB_String s1, s2; + int _idx1 = 0; + for (size_t j = 0; j < cHeader(imap)->part_headers.size(); j++) + { + imap->_cPartIdx = j; + if (cPart(imap)->rfc822_part) + { + s1 = cPart(imap)->partNumStr; + _idx1 = cPart(imap)->rfc822_msg_Idx; + } + else if (s1.length() > 0) + { + if (multipartMember(s1, cPart(imap)->partNumStr)) + { + cPart(imap)->message_sub_type = esp_mail_imap_message_sub_type_rfc822; + cPart(imap)->rfc822_msg_Idx = _idx1; + } + } + + if (cPart(imap)->multipart_sub_type == esp_mail_imap_multipart_sub_type_parallel) + s2 = cPart(imap)->partNumStr; + else if (s2.length() > 0) + { + if (multipartMember(s2, cPart(imap)->partNumStr)) + { + cPart(imap)->attach_type = esp_mail_att_type_attachment; + if (cPart(imap)->filename.length() == 0) + { + if (cPart(imap)->name.length() > 0) + cPart(imap)->filename = cPart(imap)->name; + else + { + char *uid = getRandomUID(); + cPart(imap)->filename = uid; + cPart(imap)->filename += mimeinfo[esp_mail_file_extension_dat].endsWith; + freeMem(&uid); + } + } + } + } + + checkFirmwareFile(imap, cPart(imap)->filename.c_str(), *cPart(imap), true); + } + + int attach_count = 0; + int ccnt = 0; + + for (size_t j = 0; j < cHeader(imap)->part_headers.size(); j++) + { + imap->_cPartIdx = j; + + if (cPart(imap)->rfc822_part || cPart(imap)->multipart_sub_type != esp_mail_imap_multipart_sub_type_none) + continue; + + bool rfc822_body_subtype = cPart(imap)->message_sub_type == esp_mail_imap_message_sub_type_rfc822 && cPart(imap)->attach_type != esp_mail_att_type_attachment; + + if (cPart(imap)->attach_type == esp_mail_att_type_none && (cPart(imap)->msg_type == esp_mail_msg_type_html || cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched)) + { + + bool ret = ((imap->_imap_data->enable.rfc822 || imap->_imap_data->download.rfc822) && rfc822_body_subtype) || (!rfc822_body_subtype && ((imap->_imap_data->enable.text && (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched)) || (imap->_imap_data->enable.html && cPart(imap)->msg_type == esp_mail_msg_type_html) || (cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->download.text))); + if (!ret) + continue; + +#if !defined(SILENT_MODE) + + if ((imap->_imap_data->download.rfc822 && rfc822_body_subtype) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->download.text)))) + { + + if (ccnt == 0 && imap->_statusCallback) + sendCallback(imap, esp_mail_cb_str_43 /* "Downloading messages..." */, true, false); + + if (imap->_debug) + { + debugPrintNewLine(); + if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) + esp_mail_debug_print_tag(esp_mail_dbg_str_74 /* "download plain TEXT message" */, esp_mail_debug_tag_type_client, true); + else if (cPart(imap)->msg_type == esp_mail_msg_type_html) + esp_mail_debug_print_tag(esp_mail_dbg_str_71 /* "download HTML message" */, esp_mail_debug_tag_type_client, true); + } + } + else + { + if (ccnt == 0) + sendCallback(imap, esp_mail_cb_str_28 /* "Reading messages..." */, true, false); + + if (imap->_debug) + { + debugPrintNewLine(); + if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) + esp_mail_debug_print_tag(esp_mail_dbg_str_46 /* "reading plain TEXT message" */, esp_mail_debug_tag_type_client, true); + else if (cPart(imap)->msg_type == esp_mail_msg_type_html) + esp_mail_debug_print_tag(esp_mail_dbg_str_47 /* "reading HTML message" */, esp_mail_debug_tag_type_client, true); + } + } + +#endif + + ccnt++; + + if (!sendFetchCommand(imap, i, esp_mail_imap_cmd_fetch_body_text)) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_text; + if (!handleIMAPResponse(imap, IMAP_STATUS_IMAP_RESPONSE_FAILED, closeSession)) + return false; + } + else if (cPart(imap)->attach_type != esp_mail_att_type_none && (imap->_storageReady || cPart(imap)->is_firmware_file)) + { + + if (cPart(imap)->is_firmware_file || (imap->_imap_data->download.attachment && cPart(imap)->attach_type == esp_mail_att_type_attachment) || (imap->_imap_data->download.inlineImg && cPart(imap)->attach_type == esp_mail_att_type_inline)) + { +#if !defined(SILENT_MODE) + if (cPart(imap)->save_to_file) + { + + if (attach_count == 0 && imap->_statusCallback) + sendCallback(imap, esp_mail_cb_str_19 /* "Downloading attachments..." */, true, false); + + if (imap->_debug) + { + debugPrintNewLine(); + int bufLen = 100; + char *buf = allocMem(bufLen); + snprintf(buf, bufLen, pgm2Str(esp_mail_dbg_str_70 /* "download attachment %d of %d" */), attach_count + 1, (int)cHeader(imap)->attachment_count); + esp_mail_debug_print_tag(buf, esp_mail_debug_tag_type_client, true); + // release memory + freeMem(&buf); + + MB_String filePath = imap->_imap_data->storage.saved_path; + filePath += esp_mail_str_10; /* "/" */ + filePath += cHeader(imap)->message_uid; + filePath += esp_mail_str_10; /* "/" */ + filePath += cPart(imap)->filename; + + esp_mail_debug_print_tag(filePath.c_str(), esp_mail_debug_tag_type_client, true); + } + } +#endif + + attach_count++; + + if (cPart(imap)->octetLen <= (int)imap->_imap_data->limit.attachment_size) + { + + if (imap->_storageReady || cPart(imap)->is_firmware_file) + { + + if ((int)j < (int)cHeader(imap)->part_headers.size() - 1) + if (cHeader(imap)->part_headers[j + 1].octetLen > (int)imap->_imap_data->limit.attachment_size) + cHeader(imap)->downloaded_bytes += cHeader(imap)->part_headers[j + 1].octetLen; + + if (!sendFetchCommand(imap, i, esp_mail_imap_cmd_fetch_body_attachment)) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_attachment; + if (!handleIMAPResponse(imap, IMAP_STATUS_IMAP_RESPONSE_FAILED, closeSession)) + return false; + + yield_impl(); + } + } + else + { + if ((int)j == (int)cHeader(imap)->part_headers.size() - 1) + cHeader(imap)->downloaded_bytes += cPart(imap)->octetLen; + } + } + } + } + } + + if (imap->_storageReady && imap->_imap_data->download.header && !imap->_headerSaved) + { +#if !defined(SILENT_MODE) + if (imap->_statusCallback) + sendCallback(imap, esp_mail_cb_str_21 /* "Saving message header to file..." */, true, false); + else if (imap->_debug) + debugPrintNewLine(); +#endif + + saveHeader(imap, false); + saveHeader(imap, true); + } + + // save files list to file + if (imap->_storageReady && imap->_sdFileList.length() > 0) + { + MB_String filepath = cHeader(imap)->message_uid; + filepath += mimeinfo[esp_mail_file_extension_txt].endsWith; + if (mbfs->open(filepath, mbfs_type imap->_imap_data->storage.type, mb_fs_open_mode_write) > -1) + { + mbfs->print(mbfs_type imap->_imap_data->storage.type, imap->_sdFileList.c_str()); + mbfs->close(mbfs_type imap->_imap_data->storage.type); + } + } + + imap->_cMsgIdx++; + } +#if !defined(SILENT_MODE) + if (imap->_debug) + { + MB_String str = esp_mail_str_55; /* "Free Heap: " */ + str += MailClient.getFreeHeap(); + esp_mail_debug_print_tag(str.c_str(), esp_mail_debug_tag_type_client, true); + } +#endif + } +#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) +out: +#endif + if (readCount < imap->_imap_msg_num.size()) + { + imap->_mbif._availableItems = readCount; + imap->_imap_msg_num.erase(imap->_imap_msg_num.begin() + readCount, imap->_imap_msg_num.end()); + } + + if (closeSession) + { + if (!imap->closeSession()) + return false; + } + else + { +#if !defined(SILENT_MODE) + printDebug(imap, + esp_mail_cb_str_46 /* "Finished reading Email" */, + esp_mail_dbg_str_29 /* "finished reading Email" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + } + + imap->_cbData._success = true; + +#if !defined(SILENT_MODE) + if (imap->_statusCallback) + callBackSendNewLine(imap, true); +#endif + + return true; +} + +void ESP_Mail_Client::appendHeadersFetchCommand(IMAPSession *imap, MB_String &cmd, int index, bool debug) +{ + if (imap->_uidSearch || imap->_imap_msg_num[index].type == esp_mail_imap_msg_num_type_uid) + appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_fetch].text); + else + appendSpace(cmd, true, imap_commands[esp_mail_imap_command_fetch].text); +#if !defined(SILENT_MODE) + if (debug && imap->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_26 /* "fetch message header" */, esp_mail_debug_tag_type_client, true); +#endif + joinStringSpace(cmd, false, 2, MB_String((int)imap->_imap_msg_num[index].value).c_str(), imap_commands[esp_mail_imap_command_body].text); + + if (!imap->_imap_data->fetch.set_seen) + prependDot(cmd, imap_commands[esp_mail_imap_command_peek].text); +} + +void ESP_Mail_Client::appendRFC822HeadersFetchCommand(MB_String &cmd) +{ + joinStringDot(cmd, 2, imap_commands[esp_mail_imap_command_header].text, imap_commands[esp_mail_imap_command_fields].text); + appendSpace(cmd); + + MB_String cmd2; + + for (int i = 0; i < esp_mail_rfc822_header_field_maxType; i++) + appendSpace(cmd2, false, rfc822_headers[i].text); + + joinStringSpace(cmd2, false, 4, message_headers[esp_mail_message_header_field_content_type].text, + message_headers[esp_mail_message_header_field_content_transfer_encoding].text, + message_headers[esp_mail_message_header_field_content_language].text, + message_headers[esp_mail_message_header_field_accept_language].text); + + appendString(cmd, cmd2.c_str(), false, false, esp_mail_string_mark_type_round_bracket); +} + +bool ESP_Mail_Client::getMultipartFechCmd(IMAPSession *imap, int msgIdx, MB_String &partText) +{ + if (imap->_multipart_levels.size() == 0) + return false; + + int cLevel = imap->_multipart_levels.size() - 1; + + cHeader(imap)->partNumStr.clear(); + + appendHeadersFetchCommand(imap, partText, msgIdx, false); + + MB_String cmd1; + for (size_t i = 0; i < imap->_multipart_levels.size(); i++) + { + if (i > 0) + { + cmd1 += esp_mail_str_27; /* "." */ + cHeader(imap)->partNumStr += esp_mail_str_27; /* "." */ + } + + cmd1 += imap->_multipart_levels[i].level; + cHeader(imap)->partNumStr += imap->_multipart_levels[i].level; + } + + if (imap->_multipart_levels[cLevel].fetch_rfc822_header) + { + MB_String cmd2; + appendRFC822HeadersFetchCommand(cmd2); + prependDot(cmd1, cmd2.c_str()); + imap->_multipart_levels[cLevel].append_body_text = true; + } + else + prependDot(cmd1, imap_commands[esp_mail_imap_command_mime].text); + + appendString(partText, cmd1.c_str(), false, false, esp_mail_string_mark_type_square_bracket); + + imap->_multipart_levels[cLevel].fetch_rfc822_header = false; + + return true; +} + +bool ESP_Mail_Client::multipartMember(const MB_String &parent, const MB_String &child) +{ + if (parent.length() > child.length()) + return false; + + for (size_t i = 0; i < parent.length(); i++) + if (parent[i] != child[i]) + return false; + + return true; +} + +bool ESP_Mail_Client::fetchMultipartBodyHeader(IMAPSession *imap, int msgIdx) +{ + bool ret = true; + + if (!connected(imap)) + { + closeTCPSession(imap); + return false; + } + int cLevel = 0; + + // slower than BODYSTRUCTURE parsing but sure + do + { + +#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) + // Prevent stack overflow + if (MailClient.getFreeHeap() < ESP_MAIL_MIN_MEM) + { + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_OUT_OF_MEMORY, true); + break; + } +#endif + + struct esp_mail_message_part_info_t *_cpart = &cHeader(imap)->part_headers[cHeader(imap)->message_data_count - 1]; + bool rfc822_body_subtype = _cpart->message_sub_type == esp_mail_imap_message_sub_type_rfc822 && _cpart->attach_type != esp_mail_att_type_attachment; + + MB_String cmd; + if (!getMultipartFechCmd(imap, msgIdx, cmd)) + return true; + + if (imap->_debug) + printBodyPartFechingDubug(imap, cHeader(imap)->partNumStr.c_str(), imap->_multipart_levels.size() > 1); + + // Try fetching the part and its sub parts hierarchically + // Some sub part may not exist at the current multipart level + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_fetch_body_mime; + ret = handleIMAPResponse(imap, IMAP_STATUS_IMAP_RESPONSE_FAILED, false); + + _cpart = &cHeader(imap)->part_headers[cHeader(imap)->message_data_count - 1]; + rfc822_body_subtype = _cpart->message_sub_type == esp_mail_imap_message_sub_type_rfc822 && _cpart->attach_type != esp_mail_att_type_attachment; + cLevel = imap->_multipart_levels.size() - 1; + + if (ret) + { + if (_cpart->multipart) + { + if (_cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_parallel || _cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_alternative || _cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_related || _cpart->multipart_sub_type == esp_mail_imap_multipart_sub_type_mixed) + { + struct esp_mail_imap_multipart_level_t mlevel; + mlevel.level = 1; + mlevel.fetch_rfc822_header = false; + mlevel.append_body_text = false; + imap->_multipart_levels.push_back(mlevel); + fetchMultipartBodyHeader(imap, msgIdx); + } + else + imap->_multipart_levels[cLevel].level++; + } + else + { + if (rfc822_body_subtype) + { + // Get additional rfc822 message header + imap->_multipart_levels[cLevel].fetch_rfc822_header = true; + fetchMultipartBodyHeader(imap, msgIdx); + } + else + { + if (imap->_multipart_levels[cLevel].append_body_text) + { + // single part rfc822 message body, append TEXT to the body fetch command + prependDot(_cpart->partNumFetchStr, imap_commands[esp_mail_imap_command_text].text); + imap->_multipart_levels[cLevel].append_body_text = false; + } + imap->_multipart_levels[cLevel].level++; + } + } + } + + } while (ret); + + imap->_multipart_levels.pop_back(); + + if (imap->_multipart_levels.size() > 0) + { + cLevel = imap->_multipart_levels.size() - 1; + imap->_multipart_levels[cLevel].level++; + } + + return true; +} + +void ESP_Mail_Client::printBodyPartFechingDubug(IMAPSession *imap, const char *partNum, bool multiLevel) +{ +#if !defined(SILENT_MODE) + MB_String str = multiLevel ? esp_mail_dbg_str_28 /* "fetch body sub part header, " */ : esp_mail_dbg_str_27; /* "fetch body part header, " */ + str += partNum; + esp_mail_debug_print_tag(str.c_str(), esp_mail_debug_tag_type_client, true); +#endif +} + +bool ESP_Mail_Client::imapAuth(IMAPSession *imap, bool &ssl) +{ + + if (!sessionExisted(imap)) + return false; + + imap->_auth_capability[esp_mail_auth_capability_login] = false; + + imap->_session_cfg->int_start_tls = imap->_session_cfg->secure.startTLS; + imap->_session_cfg->int_mode = imap->_session_cfg->secure.mode; + +#if !defined(ESP_MAIL_DISABLE_SSL) +unauthenticate: +#endif + + // capabilities may change after TLS negotiation + if (!imap->checkCapabilities()) + return false; + +#if !defined(ESP_MAIL_DISABLE_SSL) + + if (imap->_session_cfg->int_mode != esp_mail_secure_mode_nonsecure) + { + // start TLS when needed or the server issues + if ((imap->_auth_capability[esp_mail_auth_capability_starttls] || imap->_session_cfg->int_start_tls || imap->_session_cfg->int_mode == esp_mail_secure_mode_ssl_tls) && !ssl) + { +#if !defined(SILENT_MODE) + printDebug(imap, + esp_mail_cb_str_2 /* "Sending STARTTLS command..." */, + esp_mail_dbg_str_1 /* "send command, STARTTLS" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + imapSend(imap, imap->prependTag(imap_commands[esp_mail_imap_command_starttls].text).c_str(), true); + + // rfc2595 section 3.1 + imap->_imap_cmd = esp_mail_imap_cmd_starttls; + if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, false)) + return false; + +#if !defined(SILENT_MODE) + if (imap->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_22 /* "perform SSL/TLS handshake" */, esp_mail_debug_tag_type_client, true); +#endif + + // connect in secure mode + // do TLS handshake + + if (!imap->client.connectSSL(imap->_session_cfg->certificate.verify)) + return handleIMAPError(imap, MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP, false); + + // set the secure mode + imap->_session_cfg->int_start_tls = false; + imap->_session_cfg->int_mode = esp_mail_secure_mode_undefined; + ssl = true; + imap->_secure = true; + + // check the capabilitiy again to prevent the man in the middle attack + goto unauthenticate; + } + } + +#endif + + imap->clearMessageData(); + imap->_mailboxOpened = false; + + bool creds = imap->_session_cfg->login.email.length() > 0 && imap->_session_cfg->login.password.length() > 0; + bool sasl_auth_oauth = imap->_session_cfg->login.accessToken.length() > 0 && imap->_auth_capability[esp_mail_auth_capability_xoauth2]; + bool sasl_login = creds; + bool sasl_auth_plain = imap->_auth_capability[esp_mail_auth_capability_plain] && creds; + + bool supported_sasl = sasl_auth_oauth || sasl_login || sasl_auth_plain; + + if (!supported_sasl) + return handleIMAPError(imap, IMAP_STATUS_NO_SUPPORTED_AUTH, false); + + // rfc4959 + if (supported_sasl) + { +#if !defined(SILENT_MODE) + if (imap->_statusCallback) + sendCallback(imap, esp_mail_cb_str_14 /* "Logging in..." */, true, false); + else if (imap->_debug) + debugPrintNewLine(); +#endif + } + + if (sasl_auth_oauth) + { + + if (!imap->_auth_capability[esp_mail_auth_capability_xoauth2]) + { + handleIMAPError(imap, IMAP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED, false); + return false; + } + +#if !defined(SILENT_MODE) + if (imap->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_45 /* "send IMAP command, AUTH XOAUTH2" */, esp_mail_debug_tag_type_client, true); +#endif + + MB_String cmd; + joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_authenticate].text, imap_commands[esp_mail_imap_command_xoauth2].text); + + if (imap->_auth_capability[esp_mail_auth_capability_sasl_ir]) + { + prependSpace(cmd, getXOAUTH2String(imap->_session_cfg->login.email, imap->_session_cfg->login.accessToken).c_str()); + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + } + else + { + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_sasl_auth_oauth; + if (!handleIMAPResponse(imap, IMAP_STATUS_AUTHENTICATE_FAILED, true)) + return false; + + cmd = getXOAUTH2String(imap->_session_cfg->login.email, imap->_session_cfg->login.accessToken); + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + } + + imap->_imap_cmd = esp_mail_imap_cmd_sasl_auth_oauth; + if (!handleIMAPResponse(imap, IMAP_STATUS_AUTHENTICATE_FAILED, false)) + return false; + } + else if (sasl_auth_plain) + { + +#if !defined(SILENT_MODE) + if (imap->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_44 /* "send IMAP command, AUTHENTICATE PLAIN" */, esp_mail_debug_tag_type_client, true); +#endif + + int len = imap->_session_cfg->login.email.length() + imap->_session_cfg->login.password.length() + 2; + uint8_t *tmp = allocMem(len); + memset(tmp, 0, len); + int p = 1; + memcpy(tmp + p, imap->_session_cfg->login.email.c_str(), imap->_session_cfg->login.email.length()); + p += imap->_session_cfg->login.email.length() + 1; + memcpy(tmp + p, imap->_session_cfg->login.password.c_str(), imap->_session_cfg->login.password.length()); + p += imap->_session_cfg->login.password.length(); + + MB_String cmd; + joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_authenticate].text, imap_commands[esp_mail_imap_command_plain].text); + + if (imap->_auth_capability[esp_mail_auth_capability_sasl_ir]) + { + prependSpace(cmd, encodeBase64Str(tmp, p).c_str()); + // release memory + freeMem(&tmp); + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + } + else + { + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_sasl_auth_plain; + + if (!handleIMAPResponse(imap, IMAP_STATUS_AUTHENTICATE_FAILED, true)) + return false; + + cmd = encodeBase64Str(tmp, p); + // release memory + freeMem(&tmp); + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + } + + imap->_imap_cmd = esp_mail_imap_cmd_sasl_auth_plain; + if (!handleIMAPResponse(imap, IMAP_STATUS_AUTHENTICATE_FAILED, true)) + return false; + } + else if (sasl_login) + { + +#if !defined(SILENT_MODE) + if (imap->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_34 /* "send IMAP command, LOGIN" */, esp_mail_debug_tag_type_client, true); +#endif + MB_String cmd; + joinStringSpace(cmd, true, 3, imap_commands[esp_mail_imap_command_login].text, imap->_session_cfg->login.email.c_str(), imap->_session_cfg->login.password.c_str()); + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_sasl_login; + if (!handleIMAPResponse(imap, IMAP_STATUS_AUTHENTICATE_FAILED, true)) + return false; + } + + // auto capabilities after login? + if (!imap->_feature_capability[esp_mail_imap_read_capability_auto_caps]) + { + if (!imap->checkCapabilities()) + return false; + } + + if (imap->_feature_capability[esp_mail_imap_read_capability_id]) + { + if (!imap->id(&imap->_imap_data->identification)) + return false; + } + + if (supported_sasl) + imap->_authenticated = true; + + return true; +} + +bool ESP_Mail_Client::imapLogout(IMAPSession *imap) +{ + +#if defined(ESP8266) + return false; +#endif + + if (!sessionExisted(imap)) + return false; + +#if !defined(SILENT_MODE) + printDebug(imap, + esp_mail_cb_str_20 /* "Logging out..." */, + esp_mail_dbg_str_38 /* "send IMAP command, LOGOUT" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (imapSend(imap, imap->prependTag(imap_commands[esp_mail_imap_command_logout].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_logout; + if (!handleIMAPResponse(imap, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + imap->_authenticated = false; + +#if !defined(SILENT_MODE) + printDebug(imap, + esp_mail_cb_str_47 /* "Log out completed" */, + esp_mail_dbg_str_31 /* "log out completed" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + return true; +} + +size_t ESP_Mail_Client::imapSend(IMAPSession *imap, PGM_P data, bool newline) +{ + if (!imap || !sessionReady(imap)) + return 0; + + int sent = 0; + + MB_String s = data; + + int toSend = newline ? s.length() + 2 : s.length(); + + if (imap->_debug && imap->_debugLevel > esp_mail_debug_level_maintainer && !imap->_customCmdResCallback) + esp_mail_debug_print(s.c_str(), newline); + + sent = newline ? imap->client.println(s.c_str()) : imap->client.print(s.c_str()); + + if (sent != toSend) + { + errorStatusCB(imap, nullptr, sent, true); + sent = 0; + } + + return sent; +} + +size_t ESP_Mail_Client::imapSend(IMAPSession *imap, int data, bool newline) +{ + MB_String s = data; + return imapSend(imap, s.c_str(), newline); +} + +size_t ESP_Mail_Client::imapSend(IMAPSession *imap, uint8_t *data, size_t size) +{ + if (!imap || !sessionReady(imap)) + return 0; + + int sent = 0; + + sent = imap->client.write(data, size); + + if (sent != (int)size) + { + errorStatusCB(imap, nullptr, sent, true); + sent = 0; + } + + return sent; +} + +bool ESP_Mail_Client::mSetFlag(IMAPSession *imap, MB_StringPtr sequenceSet, MB_StringPtr flag, esp_mail_imap_store_flag_type type, bool closeSession, bool silent, bool UID, int32_t modsequence) +{ + if (!reconnect(imap)) + return false; + + if (!imap->connected()) + { + imap->_mailboxOpened = false; + return false; + } + + if (imap->_currentFolder.length() == 0) + { +#if !defined(SILENT_MODE) + printDebug(imap, + esp_mail_error_imap_str_11 /* "no mailbox opened" */, + esp_mail_error_imap_str_11 /* "no mailbox opened" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + } + else + { + if (imap->_readOnlyMode || !imap->_mailboxOpened) + { + if (!imap->selectFolder(imap->_currentFolder.c_str(), false)) + return false; + } + } + +#if !defined(SILENT_MODE) + PGM_P p1 = NULL; + PGM_P p2 = NULL; + if (type == esp_mail_imap_store_flag_type_set) + { + p1 = esp_mail_cb_str_26; /* "Setting FLAG..." */ + p2 = esp_mail_dbg_str_41; /* "setting FLAG" */ + } + else if (type == esp_mail_imap_store_flag_type_add) + { + p1 = esp_mail_cb_str_24; /* "Adding FLAG..." */ + p2 = esp_mail_dbg_str_42; /* "adding FLAG" */ + } + else + { + p1 = esp_mail_cb_str_23; /* "Removing FLAG..." */ + p2 = esp_mail_dbg_str_43; /* "removing FLAG" */ + } + + printDebug(imap, + p1, + p2, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (!sessionExisted(imap)) + return false; + + MB_String cmd; + if (UID) + appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_store].text); + else + appendSpace(cmd, true, imap_commands[esp_mail_imap_command_store].text); + + cmd += sequenceSet; + + imap->addModifier(cmd, esp_mail_imap_command_unchangedsince, modsequence); + + if (type == esp_mail_imap_store_flag_type_set) + cmd += imap_cmd_pre_tokens[esp_mail_imap_command_flags]; + else if (type == esp_mail_imap_store_flag_type_add) + cmd += imap_cmd_pre_tokens[esp_mail_imap_command_plus_flags]; + else + cmd += imap_cmd_pre_tokens[esp_mail_imap_command_minus_flags]; + + if (silent) + prependDot(cmd, imap_commands[esp_mail_imap_command_silent].text); + + appendSpace(cmd); + appendString(cmd, MB_String(flag).c_str(), false, false, esp_mail_string_mark_type_round_bracket); + + if (imapSend(imap, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + imap->_imap_cmd = esp_mail_imap_cmd_store; + + if (!handleIMAPResponse(imap, IMAP_STATUS_STORE_FAILED, false)) + return false; + + if (closeSession) + imap->closeSession(); + + return true; +} + +int ESP_Mail_Client::parseSearchResponse(IMAPSession *imap, esp_mail_imap_response_data &res, PGM_P tag, const char *key) +{ + int bufLen = res.chunkBufSize; + int ret = -1; + char c = 0; + int idx = 0; + int num = 0; + + size_t tagLen = strlen_P(tag); + MB_String _tag = tag; + + while (imap->client.available() > 0 && idx < bufLen) + { + yield_impl(); + + ret = imap->client.read(); + + if (ret > -1) + { + + if (idx >= bufLen - 1) + return idx; + + c = (char)ret; + + if (c == '\n') + c = ' '; + + res.response[idx++] = c; + + if (res.chunkIdx == 0) + { + // Search response parsing + if (strcmp(res.response, key) == 0) + { + res.chunkIdx++; + return 0; + } + else + { + // Status response parsing + res.imapResp = imapResponseStatus(imap, res.response, esp_mail_imap_tag_str); + + // Exit if error or complete (no messages found) + if (res.imapResp != esp_mail_imap_resp_unknown) + goto end_search; + } + } + else + { + if (c == ' ') + { + imap->_mbif._searchCount++; + if (imap->_imap_data->enable.recent_sort) + { + esp_mail_imap_msg_num_t msg_num; + msg_num.type = imap->_uidSearch ? esp_mail_imap_msg_num_type_uid : esp_mail_imap_msg_num_type_number; + msg_num.value = (uint32_t)atoi(res.response); + + imap->_imap_msg_num.push_back(msg_num); + + if (imap->_imap_msg_num.size() > imap->_imap_data->limit.search) + imap->_imap_msg_num.erase(imap->_imap_msg_num.begin()); + } + else + { + if (imap->_imap_msg_num.size() < imap->_imap_data->limit.search) + { + esp_mail_imap_msg_num_t msg_num; + msg_num.type = imap->_uidSearch ? esp_mail_imap_msg_num_type_uid : esp_mail_imap_msg_num_type_number; + msg_num.value = (uint32_t)atoi(res.response); + + imap->_imap_msg_num.push_back(msg_num); + } + } + + if (imap->_debug) + { + num = (float)(100.0f * imap->_mbif._searchCount / imap->_mbif._msgCount); + if (res.searchCount != num) + { + res.searchCount = num; + searchReport(imap, num); + } + } + + res.chunkIdx++; + return idx; + } + else if (idx >= (int)tagLen) + { + if (strpos(res.response, _tag.c_str(), 0, false) > -1) + { +#if defined(MB_USE_STD_VECTOR) + if (imap->_imap_data->enable.recent_sort) + std::sort(imap->_imap_msg_num.begin(), imap->_imap_msg_num.end(), compareMore); +#else + if (imap->_imap_data->enable.recent_sort) + numDecSort(imap->_imap_msg_num); +#endif + goto end_search; + } + } + } + } + } + + return idx; + +end_search: + + res.endSearch = true; + int read = imap->client.available(); + read = imap->client.readBytes(res.response + idx, read); + return idx + read; +} + +#if !defined(MB_USE_STD_VECTOR) +void ESP_Mail_Client::numDecSort(_vectorImpl &arr) +{ + + struct esp_mail_imap_msg_num_t tmp; + + for (size_t i = 0; i < arr.size(); ++i) + { + for (size_t j = i + 1; j < arr.size(); ++j) + { + if (arr[i].value < arr[j].value) + { + tmp = arr[i]; + arr[i] = arr[j]; + arr[j] = tmp; + } + } + } +} +#endif + +struct esp_mail_message_part_info_t *ESP_Mail_Client::cPart(IMAPSession *imap) +{ + if (cHeader(imap) && imap->_cPartIdx < (int)cHeader(imap)->part_headers.size()) + return &cHeader(imap)->part_headers[imap->_cPartIdx]; + return nullptr; +} + +struct esp_mail_message_header_t *ESP_Mail_Client::cHeader(IMAPSession *imap) +{ + if (cIdx(imap) < (int)imap->_headers.size()) + return &imap->_headers[cIdx(imap)]; + return nullptr; +} + +bool ESP_Mail_Client::parseHeaderField(IMAPSession *imap, const char *buf, PGM_P beginToken, bool caseSensitive, struct esp_mail_message_header_t &header, int &headerState, int state) +{ + if (strcmpP(buf, 0, beginToken, caseSensitive)) + { + headerState = state; + char *tmp = subStr(buf, beginToken, NULL, 0, -1, caseSensitive); + if (tmp) + { + collectHeaderField(imap, tmp, header, headerState); + // release memory + freeMem(&tmp); + return true; + } + } + + return false; +} + +void ESP_Mail_Client::parseHeaderResponse(IMAPSession *imap, esp_mail_imap_response_data &res, bool caseSensitive) +{ + char *tmp = nullptr; + if (res.chunkIdx == 0) + { + MB_String str; + joinStringDot(str, 2, imap_commands[esp_mail_imap_command_header].text, imap_commands[esp_mail_imap_command_fields].text); + + if (!res.isUntaggedResponse && strposP(res.response, str.c_str(), 0, caseSensitive) != -1 && res.response[0] == '*') + res.isUntaggedResponse = true; + + if (res.isUntaggedResponse && res.response[strlen(res.response) - 1] == '}') + res.untaggedRespCompleted = true; + + if (res.isUntaggedResponse && res.header.message_no == 0) + { + tmp = subStr(res.response, imap_responses[esp_mail_imap_response_untagged].text, imap_responses[esp_mail_imap_response_fetch].text, 0); + if (tmp) + { + res.header.message_no = atoi(tmp); + // release memory + freeMem(&tmp); + } + } + + if (res.isUntaggedResponse && res.untaggedRespCompleted) + { + tmp = subStr(res.response, esp_mail_str_36 /* "{" */, esp_mail_str_37 /* "}" */, 0, 0, caseSensitive); + if (tmp) + { + res.octetCount = 2; + res.header.header_data_len = atoi(tmp); + // release memory + freeMem(&tmp); + res.chunkIdx++; + } + } + } + else + { + if (res.octetCount > res.header.header_data_len + 2) + return; + + res.chunkIdx++; + + MB_String field; + + for (int i = esp_mail_rfc822_header_field_from; i < esp_mail_rfc822_header_field_maxType; i++) + { + appendHeaderName(field, rfc822_headers[i].text, true, false, false); + if (parseHeaderField(imap, res.response, field.c_str(), caseSensitive, res.header, res.headerState, i)) + return; + } + + appendHeaderName(field, message_headers[esp_mail_message_header_field_content_transfer_encoding].text, true, true, false); + + if (parseHeaderField(imap, res.response, field.c_str(), caseSensitive, res.header, res.headerState, esp_mail_imap_state_content_transfer_encoding)) + return; + + appendHeaderName(field, message_headers[esp_mail_message_header_field_accept_language].text, true, true, false); + + if (parseHeaderField(imap, res.response, field.c_str(), caseSensitive, res.header, res.headerState, esp_mail_imap_state_accept_language)) + return; + + appendHeaderName(field, message_headers[esp_mail_message_header_field_content_language].text, true, true, false); + + if (parseHeaderField(imap, res.response, field.c_str(), caseSensitive, res.header, res.headerState, esp_mail_imap_state_content_language)) + return; + + MB_String contentTypeName; + appendHeaderName(contentTypeName, message_headers[esp_mail_message_header_field_content_type].text, false, false, false); + if (strcmpP(res.response, 0, contentTypeName.c_str(), caseSensitive)) + { + res.headerState = esp_mail_imap_state_content_type; + tmp = subStr(res.response, contentTypeName.c_str(), esp_mail_str_35 /* ";" */, 0, 0, caseSensitive); + if (tmp) + { + // We set attachment status here as attachment should be included in multipart/mixed message, + // unless no real attachments included which we don't know until fetching the sub part. + if (strpos(tmp, esp_mail_imap_multipart_sub_type_t::mixed, 0, caseSensitive) != -1) + res.header.hasAttachment = true; + + collectHeaderField(imap, res.response, res.header, res.headerState); + // release memory + freeMem(&tmp); + } + } + } +} + +void ESP_Mail_Client::collectHeaderField(IMAPSession *imap, char *buf, struct esp_mail_message_header_t &header, int state) +{ + size_t i = 0; + while (buf[i] == ' ') + { + i++; + if (strlen(buf) <= i) + return; + } + + if (state < esp_mail_rfc822_header_field_maxType) + { + int ptr = getRFC822HeaderPtr(state, &header.header_fields); + if (ptr > 0) + { + *(addrTo(ptr)) += &buf[i]; + } + return; + } + + switch (state) + { + case esp_mail_imap_state_content_type: + header.content_type += &buf[i]; + break; + case esp_mail_imap_state_content_transfer_encoding: + header.content_transfer_encoding += &buf[i]; + break; + case esp_mail_imap_state_accept_language: + header.accept_language += &buf[i]; + break; + case esp_mail_imap_state_content_language: + header.content_language += &buf[i]; + break; + case esp_mail_imap_state_char_set: + header.char_set += &buf[i]; + break; + case esp_mail_imap_state_boundary: + header.boundary += &buf[i]; + break; + default: + break; + } +} + +bool ESP_Mail_Client::getDecodedHeader(IMAPSession *imap, const char *buf, PGM_P beginToken, MB_String &out, bool caseSensitive) +{ + if (getHeader(buf, beginToken, out, caseSensitive)) + { + // decode header text + decodeString(imap, out); + return true; + } + return false; +} + +void ESP_Mail_Client::checkFirmwareFile(IMAPSession *imap, const char *filename, struct esp_mail_message_part_info_t &part, bool defaultSize) +{ + if (strcmp(filename, imap->_imap_data->firmware_update.attach_filename.c_str()) == 0 && part.attach_type == esp_mail_att_type_attachment) + { + part.is_firmware_file = true; + // If no file size prop from Content-Disposition header + if (part.attach_data_size == 0 && defaultSize) + { +#if defined(ESP32) || defined(ESP8266) + int sketchFreeSpace = ESP.getFreeSketchSpace(); + part.attach_data_size = sketchFreeSpace ? sketchFreeSpace : 1024000; +#elif defined(MB_ARDUINO_PICO) + size_t spiffsSize = ((size_t)&_FS_end - (size_t)&_FS_start); + part.attach_data_size = spiffsSize ? spiffsSize / 2 : 1024000; +#endif + } + + if (!imap->_imap_data->firmware_update.save_to_file) + part.save_to_file = false; + } +} + +void ESP_Mail_Client::parsePartHeaderResponse(IMAPSession *imap, esp_mail_imap_response_data &res, bool caseSensitive) +{ + char *tmp = nullptr; + if (res.chunkIdx == 0) + { + tmp = subStr(res.response, imap_responses[esp_mail_imap_response_fetch].text, NULL, 0, -1); + if (tmp) + { + // release memory + freeMem(&tmp); + tmp = subStr(res.response, esp_mail_str_36 /* "{" */, esp_mail_str_37 /* "}" */, 0); + if (tmp) + { + res.chunkIdx++; + res.part.octetLen = atoi(tmp); + res.octetCount = 2; + // release memory + freeMem(&tmp); + } + } + } + else + { + MB_String value, old_value; + bool valueStored = false; + res.chunkIdx++; + + // if all octets read + + if (res.octetCount > res.part.octetLen) + { + + // Is inline attachment without content id or name or filename? + // It is supposed to be the inline message txt content, reset attach type to none + + if (res.part.attach_type == esp_mail_att_type_inline && res.part.CID.length() == 0) + res.part.attach_type = esp_mail_att_type_none; + + // Is attachment file extension missing? + // append extension + + if (res.part.attach_type == esp_mail_att_type_inline || res.part.attach_type == esp_mail_att_type_attachment) + { + if (res.part.filename.length() > 0 && res.part.filename.find('.') == MB_String::npos) + { + MB_String ext; + getExtfromMIME(res.part.content_type.c_str(), ext); + res.part.filename += ext; + } + + checkFirmwareFile(imap, res.part.filename.c_str(), res.part); + } + + return; + } + + // Content header field parse + if (strcmpP(res.response, 0, esp_mail_str_56 /* "content-" */, caseSensitive)) + { + // Content-Type + MB_String contentTypeName; + appendHeaderName(contentTypeName, message_headers[esp_mail_message_header_field_content_type].text, false, false, false); + if (strcmpP(res.response, 0, contentTypeName.c_str(), caseSensitive)) + { + + res.part.cur_content_hdr = esp_mail_message_part_info_t::content_header_field_type; + resetStringPtr(res.part); + + tmp = subStr(res.response, contentTypeName.c_str(), esp_mail_str_35 /* ";" */, 0, 0, caseSensitive); + if (tmp) + { + res.part.content_type = tmp; + // release memory + freeMem(&tmp); + int p1 = strposP(res.part.content_type.c_str(), esp_mail_imap_composite_media_type_t::multipart, 0, caseSensitive); + if (p1 != -1) + { + p1 += strlen(esp_mail_imap_composite_media_type_t::multipart) + 1; + res.part.multipart = true; + // inline or embedded images + if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::related, p1, caseSensitive) != -1) + res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_related; + // multiple text formats e.g. plain, html, enriched + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::alternative, p1, caseSensitive) != -1) + res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_alternative; + // medias + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::parallel, p1, caseSensitive) != -1) + res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_parallel; + // rfc822 encapsulated + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::digest, p1, caseSensitive) != -1) + res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_digest; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::report, p1, caseSensitive) != -1) + res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_report; + // others can be attachments + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::mixed, p1, caseSensitive) != -1) + res.part.multipart_sub_type = esp_mail_imap_multipart_sub_type_mixed; + } + + p1 = strposP(res.part.content_type.c_str(), esp_mail_imap_composite_media_type_t::message, 0, caseSensitive); + if (p1 != -1) + { + p1 += strlen(esp_mail_imap_composite_media_type_t::message) + 1; + if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::rfc822, p1, caseSensitive) != -1) + res.part.message_sub_type = esp_mail_imap_message_sub_type_rfc822; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::Partial, p1, caseSensitive) != -1) + res.part.message_sub_type = esp_mail_imap_message_sub_type_partial; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::External_Body, p1, caseSensitive) != -1) + res.part.message_sub_type = esp_mail_imap_message_sub_type_external_body; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::delivery_status, p1, caseSensitive) != -1) + res.part.message_sub_type = esp_mail_imap_message_sub_type_delivery_status; + } + + p1 = strpos(res.part.content_type.c_str(), esp_mail_imap_descrete_media_type_t::text, 0, caseSensitive); + if (p1 != -1) + { + p1 += strlen(esp_mail_imap_descrete_media_type_t::text) + 1; + if (strpos(res.part.content_type.c_str(), esp_mail_imap_media_text_sub_type_t::plain, p1, caseSensitive) != -1) + res.part.msg_type = esp_mail_msg_type_plain; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_media_text_sub_type_t::enriched, p1, caseSensitive) != -1) + res.part.msg_type = esp_mail_msg_type_enriched; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_media_text_sub_type_t::html, p1, caseSensitive) != -1) + res.part.msg_type = esp_mail_msg_type_html; + else + res.part.msg_type = esp_mail_msg_type_plain; + } + } + } + + // Content-Description + MB_String contentDescrName; + appendHeaderName(contentDescrName, message_headers[esp_mail_message_header_field_content_description].text, false, true, false); + if (getDecodedHeader(imap, res.response, contentDescrName.c_str(), res.part.descr, caseSensitive)) + { + res.part.cur_content_hdr = esp_mail_message_part_info_t::content_header_field_description; + + tmp = subStr(res.response, contentDescrName.c_str(), NULL, 0, -1, caseSensitive); + if (tmp) + { + value = tmp; + // release memory + freeMem(&tmp); + + res.part.stringPtr = toAddr(res.part.content_description); + value.trim(); + if (value.length() == 0) + return; + } + } + + // Content-ID + MB_String contentIdName; + appendHeaderName(contentIdName, message_headers[esp_mail_message_header_field_content_id].text, false, true, false); + if (strcmpP(res.response, 0, contentIdName.c_str(), caseSensitive)) + { + tmp = subStr(res.response, contentIdName.c_str(), NULL, 0, -1, caseSensitive); + if (tmp) + { + res.part.CID = tmp; + // release memory + freeMem(&tmp); + res.part.CID.trim(); + + if (res.part.CID[0] == '<') + res.part.CID.erase(0, 1); + + if (res.part.CID[res.part.CID.length() - 1] == '>') + res.part.CID.erase(res.part.CID.length() - 1, 1); + + // if inline attachment file name was not assigned + if (res.part.attach_type == esp_mail_att_type_inline && res.part.filename.length() == 0) + { + // set filename from content id and append extension later + res.part.filename = res.part.CID; + res.part.name = res.part.filename; + } + } + + res.part.cur_content_hdr = esp_mail_message_part_info_t::content_header_field_id; + resetStringPtr(res.part); + } + + // Content-Disposition + MB_String contentDispositionName; + appendHeaderName(contentDispositionName, message_headers[esp_mail_message_header_field_content_disposition].text, false, true, false); + if (strcmpP(res.response, 0, contentDispositionName.c_str(), caseSensitive)) + { + + res.part.cur_content_hdr = esp_mail_message_part_info_t::content_header_field_disposition; + resetStringPtr(res.part); + + tmp = subStr(res.response, contentDispositionName.c_str(), esp_mail_str_35 /* ";" */, 0, 0, caseSensitive); + if (tmp) + { + // don't count altenative part text and html as embedded contents + if (cHeader(imap)->multipart_sub_type != esp_mail_imap_multipart_sub_type_alternative) + { + res.part.content_disposition = tmp; + if (caseSensitive) + { + if (strcmp(tmp, esp_mail_content_disposition_type_t::attachment) == 0) + res.part.attach_type = esp_mail_att_type_attachment; + else if (strcmp(tmp, esp_mail_content_disposition_type_t::inline_) == 0) + res.part.attach_type = esp_mail_att_type_inline; + } + else + { + if (strcasecmp(tmp, esp_mail_content_disposition_type_t::attachment) == 0) + res.part.attach_type = esp_mail_att_type_attachment; + else if (strcasecmp(tmp, esp_mail_content_disposition_type_t::inline_) == 0) + res.part.attach_type = esp_mail_att_type_inline; + } + } + // release memory + freeMem(&tmp); + } + } + + // Content-Transfer-Encoding + MB_String contentTEName; + appendHeaderName(contentTEName, message_headers[esp_mail_message_header_field_content_transfer_encoding].text, false, true, false); + if (strcmpP(res.response, 0, contentTEName.c_str(), caseSensitive)) + { + // store last text field + + res.part.cur_content_hdr = esp_mail_message_part_info_t::content_header_field_transfer_enc; + resetStringPtr(res.part); + + tmp = subStr(res.response, contentTEName.c_str(), NULL, 0, -1, caseSensitive); + if (tmp) + { + res.part.content_transfer_encoding = tmp; + + if (strcmpP(tmp, 0, esp_mail_transfer_encoding_t::enc_base64)) + res.part.xencoding = esp_mail_msg_xencoding_base64; + else if (strcmpP(tmp, 0, esp_mail_transfer_encoding_t::enc_qp)) + res.part.xencoding = esp_mail_msg_xencoding_qp; + else if (strcmpP(tmp, 0, esp_mail_transfer_encoding_t::enc_7bit)) + res.part.xencoding = esp_mail_msg_xencoding_7bit; + else if (strcmpP(tmp, 0, esp_mail_transfer_encoding_t::enc_8bit)) + res.part.xencoding = esp_mail_msg_xencoding_8bit; + else if (strcmpP(tmp, 0, esp_mail_transfer_encoding_t::enc_binary)) + res.part.xencoding = esp_mail_msg_xencoding_binary; + // release memory + freeMem(&tmp); + } + } + } + else + { + + if (res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_none) + { + + resetStringPtr(res.part); + + MB_String field; + for (int i = esp_mail_rfc822_header_field_from; i < esp_mail_rfc822_header_field_maxType; i++) + { + field = rfc822_headers[i].text; + field += esp_mail_str_34; /* ":" */ + ; + + int ptr = getRFC822HeaderPtr(i, &res.part.rfc822_header); + if (ptr > 0) + { + if (getDecodedHeader(imap, res.response, field.c_str(), *(addrTo(ptr)), caseSensitive)) + return; + } + } + } + } + + // parse content type header sub type properties + if (res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_type) + { + + if (res.part.msg_type == esp_mail_msg_type_plain || res.part.msg_type == esp_mail_msg_type_enriched) + { + MB_String charset; + appendLowerCaseString(charset, message_headers[esp_mail_message_header_field_charset].text, false); + // We have to check for both quotes string or non quote string + if (getPartHeaderProperties(imap, res.response, charset.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.charset = value; + resetStringPtr(res.part); + } + else if (getPartHeaderProperties(imap, res.response, charset.c_str(), esp_mail_str_35 /* ";" */, true, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.charset = value; + resetStringPtr(res.part); + } + + if (strposP(res.response, esp_mail_str_59 /* "format=flowed" */, 0, caseSensitive) > -1 || strposP(res.response, esp_mail_str_58 /* "format=\"flowed\"" */, 0, caseSensitive) > -1) + { + res.part.plain_flowed = true; + resetStringPtr(res.part); + } + + if (strposP(res.response, esp_mail_str_61 /* "delsp=yes" */, 0, caseSensitive) > -1 || strposP(res.response, esp_mail_str_60 /* "delsp=\"yes\"" */, 0, caseSensitive) > -1) + { + res.part.plain_delsp = true; + resetStringPtr(res.part); + } + } + + if (res.part.charset.length() == 0) + { + MB_String charset; + appendLowerCaseString(charset, message_headers[esp_mail_message_header_field_charset].text, false); + // We have to check for both quotes string or non quote string + if (getPartHeaderProperties(imap, res.response, charset.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.charset = value; + resetStringPtr(res.part); + } + else if (getPartHeaderProperties(imap, res.response, charset.c_str(), esp_mail_str_35 /* ";" */, true, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.charset = value; + resetStringPtr(res.part); + } + } + + MB_String name; + appendLowerCaseString(name, message_headers[esp_mail_message_header_field_name].text, false); + // We have to check for both quotes string or non quote string + if (getPartHeaderProperties(imap, res.response, name.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.stringPtr = toAddr(res.part.name); + value.trim(); + if (value.length() == 0) + return; + } + else if (getPartHeaderProperties(imap, res.response, name.c_str(), esp_mail_str_35 /* ";" */, true, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.stringPtr = toAddr(res.part.name); + value.trim(); + if (value.length() == 0) + return; + } + } + + // parse content disposition header sub type properties + if (res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_disposition && res.part.content_disposition.length() > 0) + { + // filename prop + MB_String filename; + appendLowerCaseString(filename, message_headers[esp_mail_message_header_field_filename].text, false); + // We have to check for both quotes string or non quote string + if (getPartHeaderProperties(imap, res.response, filename.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.stringPtr = toAddr(res.part.filename); + value.trim(); + if (value.length() == 0) + return; + } + else if (getPartHeaderProperties(imap, res.response, filename.c_str(), esp_mail_str_35 /* ";" */, true, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.stringPtr = toAddr(res.part.filename); + value.trim(); + if (value.length() == 0) + return; + } + + // size prop + MB_String size; + appendLowerCaseString(size, message_headers[esp_mail_message_header_field_size].text, false); + + if (getPartHeaderProperties(imap, res.response, size.c_str(), esp_mail_str_35 /* ";" */, true, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.attach_data_size = atoi(value.c_str()); + cHeader(imap)->total_attach_data_size += res.part.attach_data_size; + res.part.sizeProp = true; + + if (!valueStored && old_value.length() > 0) + valueStored = storeStringPtr(imap, res.part.stringPtr, old_value, res.response); + resetStringPtr(res.part); + } + + // creation date prop + MB_String creationDate; + appendLowerCaseString(creationDate, message_headers[esp_mail_message_header_field_creation_date].text, false); + + if (getPartHeaderProperties(imap, res.response, creationDate.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.creation_date = value; + if (!valueStored && old_value.length() > 0) + valueStored = storeStringPtr(imap, res.part.stringPtr, old_value, res.response); + resetStringPtr(res.part); + } + + // mod date prop + MB_String modDate; + appendLowerCaseString(modDate, message_headers[esp_mail_message_header_field_modification_date].text, false); + + if (getPartHeaderProperties(imap, res.response, modDate.c_str(), esp_mail_str_11 /* "\"" */, false, value, old_value, res.part.stringEnc, caseSensitive)) + { + res.part.modification_date = value; + if (!valueStored && old_value.length() > 0) + valueStored = storeStringPtr(imap, res.part.stringPtr, old_value, res.response); + resetStringPtr(res.part); + } + } + + if (!valueStored && (res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_description || res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_type || res.part.cur_content_hdr == esp_mail_message_part_info_t::content_header_field_disposition)) + storeStringPtr(imap, res.part.stringPtr, value, res.response); + } +} + +void ESP_Mail_Client::resetStringPtr(struct esp_mail_message_part_info_t &part) +{ + part.stringPtr = 0; + part.stringEnc = esp_mail_char_decoding_scheme_default; +} + +int ESP_Mail_Client::countChar(const char *buf, char find) +{ + if (!buf) + return 0; + + int count = 0; + + for (size_t i = 0; i < strlen(buf); i++) + { + if (buf[i] == find) + count++; + } + + return count; +} + +bool ESP_Mail_Client::storeStringPtr(IMAPSession *imap, uint32_t addr, MB_String &value, const char *buf) +{ + if (addr) + { + MB_String *a = addrTo(addr); + MB_String s = value.length() > 0 ? value : buf; + + // is value string contains double quotes? + // trim it + if (countChar(s.c_str(), '"') == 2) + s.trim(); + + if (s[0] == '"') + s.erase(0, 1); + + if (s[s.length() - 1] == '"') + s.erase(s.length() - 1, 1); + + decodeString(imap, s); + + *a += s; + + return true; + } + + return false; +} + +bool ESP_Mail_Client::getPartHeaderProperties(IMAPSession *imap, const char *buf, PGM_P p, PGM_P e, bool num, MB_String &value, MB_String &old_value, esp_mail_char_decoding_scheme &scheme, bool caseSensitive) +{ + + MB_String str = p; + str += esp_mail_str_7; /* "=" */ + if (!num) + str += esp_mail_str_11; /* "\"" */ + + char *tmp = subStr(buf, str.c_str(), e, 0, 0, caseSensitive); + if (!tmp) + { + str = p; + str += esp_mail_str_7; /* "=" */ + tmp = subStr(buf, str.c_str(), e, 0, 0, caseSensitive); + if (tmp) + { + // other sub headers found? + int p2 = strposP(tmp, esp_mail_str_35 /* ";" */, 0, caseSensitive); + if (p2 > -1) + { + // release memory + freeMem(&tmp); + tmp = subStr(buf, str.c_str(), esp_mail_str_35 /* ";" */, 0, 0, caseSensitive); + } + // release memory in case above condition does not match + freeMem(&tmp); + } + else + { + // Extended notation rfc5987 + str = p; + str += esp_mail_str_3; /* "*" */ + int p2 = strpos(buf, str.c_str(), 0, caseSensitive); + if (p2 > -1) + { + int p3 = strposP(buf, esp_mail_str_3 /* "*" */, p2 + str.length() + 1, caseSensitive); + if (p3 > -1 && p3 < (int)strlen(buf)) + { + MB_String charset; + + p3 += 2; + + int p4 = strpos(buf, "'", p3, caseSensitive); + if (p4 > -1) + { + + scheme = getEncodingFromCharset(buf); + int c1 = p4 + 1; + p4 = strpos(buf, "'", p4 + 1, caseSensitive); + int c2 = p4; + if (c2 > -1) + { + charset.append(buf + c1, c2 - c1); + } + p3 = p4 + 1; + } + + int len = strlen(buf) - p3; + tmp = allocMem(len + 1); + + if (buf[strlen(buf) - 1] == ';') + len--; + + memcpy(tmp, &buf[p3], len); + + if (scheme == esp_mail_char_decoding_scheme_utf_8) + { + char *buf2 = urlDecode(tmp); + // release memory and point to new buffer + freeMem(&tmp); + tmp = buf2; + } + else if (imap->_charDecCallback) + { + IMAP_Decoding_Info decoding; + decoding.charset = charset.c_str(); + decoding.data = tmp; + decoding.type = IMAP_Decoding_Info::message_part_type_header; + + imap->_charDecCallback(&decoding); + + if (decoding.decodedString.length() > 0) + { + char *buf2 = allocMem(decoding.decodedString.length() + 1); + strcpy(buf2, decoding.decodedString.c_str()); + // release memory and point to new buffer + freeMem(&tmp); + tmp = buf2; + } + } + else if (scheme == esp_mail_char_decoding_scheme_iso8859_1) + { + int ilen = strlen(tmp); + int olen = (ilen + 1) * 2; + char *buf2 = allocMem(olen); + decodeLatin1_UTF8((unsigned char *)buf2, &olen, (unsigned char *)tmp, &ilen); + // release memory and point to new buffer + freeMem(&tmp); + tmp = buf2; + } + else if (scheme == esp_mail_char_decoding_scheme_tis_620 || scheme == esp_mail_char_decoding_scheme_iso8859_11 || scheme == esp_mail_char_decoding_scheme_windows_874) + { + int ilen = strlen(tmp); + char *buf2 = allocMem((ilen + 1) * 3); + decodeTIS620_UTF8(buf2, tmp, ilen); + // release memory and point to new buffer + freeMem(&tmp); + tmp = buf2; + } + } + } + } + } + + if (tmp) + { + old_value = value; + value = tmp; + // release memory + freeMem(&tmp); + return true; + } + + return false; +} + +char *ESP_Mail_Client::urlDecode(const char *str) +{ + int d = 0; /* whether or not the string is decoded */ + char *dStr = allocMem(strlen(str) + 1); + char eStr[] = "00"; /* for a hex code */ + + strcpy(dStr, str); + + while (!d) + { + d = 1; + size_t i; /* the counter for the string */ + + for (i = 0; i < strlen(dStr); ++i) + { + + if (dStr[i] == '%') + { + if (dStr[i + 1] == 0) + return dStr; + + if (isxdigit(dStr[i + 1]) && isxdigit(dStr[i + 2])) + { + d = 0; + + /* combine the next to numbers into one */ + eStr[0] = dStr[i + 1]; + eStr[1] = dStr[i + 2]; + + /* convert it to decimal */ + long int x = strtol(eStr, NULL, 16); + + /* remove the hex */ + memmove(&dStr[i + 1], &dStr[i + 3], strlen(&dStr[i + 3]) + 1); + + dStr[i] = x; + } + } + } + } + + return dStr; +} + +bool ESP_Mail_Client::handleIMAPResponse(IMAPSession *imap, int errCode, bool closeSession) +{ + + if (!reconnect(imap)) + return false; + + esp_mail_imap_response_data res(imap->client.available()); + imap->_lastProgress = -1; + + // Flag used for CRLF inclusion in response reading in case 8bit/binary attachment and base64 encoded and binary messages + bool withLineBreak = imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text && (cPart(imap)->xencoding == esp_mail_msg_xencoding_base64 || cPart(imap)->xencoding == esp_mail_msg_xencoding_binary); + withLineBreak |= imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment && cPart(imap)->xencoding != esp_mail_msg_xencoding_base64; + + // custom cmd IDLE?, waiting incoming server response + if (res.chunkBufSize == 0 && imap->_prev_imap_custom_cmd == imap->_imap_custom_cmd && imap->_imap_custom_cmd == esp_mail_imap_cmd_idle) + { + if (!reconnect(imap)) + return false; + + return true; + } + + while (imap->connected() && res.chunkBufSize <= 0) + { + + if (!reconnect(imap, res.dataTime)) + return false; + + if (!connected(imap)) + { +#if defined(ESP32) + if (imap->_imap_cmd == esp_mail_imap_cmd_logout) // suppress the error due to server closes the connection immediately in ESP32 core v2.0.4 + return true; +#endif + if (millis() - imap->_last_network_error_ms > 1000) + { + imap->_last_network_error_ms = millis(); + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, true); + } + + return false; + } + res.chunkBufSize = imap->client.available(); + yield_impl(); + } + + res.dataTime = millis(); + + if (res.chunkBufSize > 0) + { + if (imap->_imap_cmd == esp_mail_imap_cmd_examine) + { + imap->_mbif.clear(); + imap->_nextUID.clear(); + imap->_unseenMsgIndex.clear(); + } + + if (imap->_imap_cmd == esp_mail_imap_cmd_search) + { + imap->_mbif._searchCount = 0; + imap->_imap_msg_num.clear(); + } + + // response buffer + res.chunkBufSize = ESP_MAIL_CLIENT_RESPONSE_BUFFER_SIZE; + res.response = allocMem(res.chunkBufSize + 1); + + if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) + res.lastBuf = allocMem(BASE64_CHUNKED_LEN + 1); + + while (!res.completedResponse) // looking for operation finishing + { + yield_impl(); + + if (imap->_imap_cmd == esp_mail_imap_cmd_append || (imap->_imap_custom_cmd == esp_mail_imap_cmd_append && imap->_imap_cmd == esp_mail_imap_cmd_custom && imap->_customCmdResCallback)) + { + // No waiting time out for APPEND + res.dataTime = millis(); + } + + if (!reconnect(imap, res.dataTime) || !connected(imap)) + { + + if (!connected(imap)) + { + + if (cPart(imap) && cPart(imap)->file_open_write) + mbfs->close(mbfs_type imap->_imap_data->storage.type); + +#if defined(ESP32) + if (imap->_imap_cmd == esp_mail_imap_cmd_logout) // suppress the error due to server closes the connection immediately in ESP32 core v2.0.4 + return true; +#endif + + if (millis() - imap->_last_network_error_ms > 1000) + { + imap->_last_network_error_ms = millis(); + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, true); + } + + return false; + } + return false; + } + + res.chunkBufSize = imap->client.available(); + + if (res.chunkBufSize > 0) + { + res.chunkBufSize = ESP_MAIL_CLIENT_RESPONSE_BUFFER_SIZE; + + if (imap->_imap_cmd == esp_mail_imap_cmd_search) + { + + res.readLen = parseSearchResponse(imap, res, esp_mail_imap_tag_str, imap_responses[esp_mail_imap_response_search].text); + imap->_mbif._availableItems = imap->_imap_msg_num.size(); + + if (imap->_mbif._availableItems == 0) + { + res.imapResp = imapResponseStatus(imap, res.response, esp_mail_imap_tag_str); + + if (res.imapResp != esp_mail_imap_resp_unknown) + res.endSearch = true; + + if (res.imapResp == esp_mail_imap_resp_bad) + { + errorStatusCB(imap, nullptr, IMAP_STATUS_BAD_COMMAND, false); + return false; + } + } + } + else + { + // response read as chunk ended with CRLF or complete buffer size + int o = res.octetCount; + res.readLen = 0; + MB_String ovfBuf; + if (!readResponse(imap, res.response, res.chunkBufSize, res.readLen, withLineBreak, res.octetCount, ovfBuf)) + { + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_READ_TIMEOUT, true); + return false; + } + + // If buffer overflown, copy from overflow buffer + if (ovfBuf.length() > 0) + { + // release memory + freeMem(&res.response); + res.response = allocMem(ovfBuf.length() + 1); + strcpy(res.response, ovfBuf.c_str()); + ovfBuf.clear(); + } + + if (res.readLen == 0 && o != res.octetCount && res.octetCount <= res.octetLength && cPart(imap)->xencoding != esp_mail_msg_xencoding_base64 && cPart(imap)->xencoding != esp_mail_msg_xencoding_binary && cPart(imap)->xencoding != esp_mail_msg_xencoding_qp) + { + strcpy_P(res.response, esp_mail_str_42 /* "\r\n" */); + res.readLen = 2; + } + } + + if (res.readLen) + { + if (imap->_debug && imap->_debugLevel > esp_mail_debug_level_basic && !imap->_customCmdResCallback) + { + if (imap->_imap_cmd != esp_mail_imap_cmd_search && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_text && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_attachment && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_inline) + esp_mail_debug_print((const char *)res.response, true); + } + + if (imap->_imap_cmd != esp_mail_imap_cmd_search || (imap->_imap_cmd == esp_mail_imap_cmd_search && res.endSearch)) + res.imapResp = imapResponseStatus(imap, res.response, esp_mail_imap_tag_str); + + if (res.imapResp != esp_mail_imap_resp_unknown) + { + + // We've got the right response, + // prepare to exit + + res.completedResponse = true; + + if (imap->_debug && imap->_debugLevel > esp_mail_debug_level_basic && !imap->_customCmdResCallback) + { + if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) + esp_mail_debug_print((const char *)res.response, true); + } + + MB_String ovfBuf; + + while (imap->client.available()) + { + + if (!readResponse(imap, res.response, res.chunkBufSize, res.readLen, true, res.octetCount, ovfBuf)) + { + errorStatusCB(imap, nullptr, MAIL_CLIENT_ERROR_READ_TIMEOUT, true); + return false; + } + // If buffer overflown, copy from overflow buffer + if (ovfBuf.length() > 0) + { + // release memory + freeMem(&res.response); + res.response = allocMem(ovfBuf.length() + 1); + strcpy(res.response, ovfBuf.c_str()); + ovfBuf.clear(); + } + + if (res.readLen) + { + if (imap->_debug && imap->_debugLevel > esp_mail_debug_level_basic && !imap->_customCmdResCallback) + { + if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) + esp_mail_debug_print((const char *)res.response, true); + } + } + } + } + else + { + + // No response ever parsed + + if (imap->_imap_cmd == esp_mail_imap_cmd_sasl_auth_plain || imap->_imap_cmd == esp_mail_imap_cmd_sasl_auth_oauth) + { + if (imap->_imap_cmd == esp_mail_imap_cmd_sasl_auth_oauth) + { + if (isOAuthError(res.response, res.readLen, res.chunkIdx, 2)) + res.completedResponse = true; + } + + // In case SASL-IR extension does not support, check for initial zero-length server challenge first "+ " + if (!imap->_auth_capability[esp_mail_auth_capability_sasl_ir] && strcmp(res.response, pgm2Str(esp_mail_str_63 /* "+ " */)) == 0) + { + res.imapResp = esp_mail_imap_resp_ok; + res.completedResponse = true; + } + } + + if (imap->_imap_cmd == esp_mail_imap_cmd_sasl_login || imap->_imap_cmd == esp_mail_imap_cmd_sasl_auth_oauth || imap->_imap_cmd == esp_mail_imap_cmd_sasl_auth_plain) + { + int i = 0; + if (parseCapabilityResponse(imap, res.response, i)) + imap->_feature_capability[esp_mail_imap_read_capability_auto_caps] = true; + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_custom && imap->_customCmdResCallback) + { + + res.imapResp = imapResponseStatus(imap, res.response, imap->_responseStatus.tag.c_str()); + + // get response or custom cmd APPEND or custom cmd IDLE? + if (res.imapResp > esp_mail_imap_resp_unknown || strposP(imap->_cmd.c_str(), imap_commands[esp_mail_imap_command_append].text, 0, false) > -1 || imap->_imap_custom_cmd == esp_mail_imap_cmd_idle) + res.completedResponse = true; + + imap->_responseStatus.text = res.response; + + imap->_customCmdResCallback(imap->_responseStatus); + + if (res.completedResponse) + return true; + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_append) + { + res.imapResp = esp_mail_imap_resp_ok; + res.completedResponse = true; + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_capability) + parseCapabilityResponse(imap, res.response, res.chunkIdx); + else if (imap->_imap_cmd == esp_mail_imap_cmd_list) + parseFoldersResponse(imap, res.response, true); + else if (imap->_imap_cmd == esp_mail_imap_cmd_lsub) + parseFoldersResponse(imap, res.response, false); + else if (imap->_imap_cmd == esp_mail_imap_cmd_select || imap->_imap_cmd == esp_mail_imap_cmd_examine) + parseExamineResponse(imap, res.response); + else if (imap->_imap_cmd == esp_mail_imap_cmd_get_uid) + { + MB_String str; + appendFetchString(str, true); + parseCmdResponse(imap, res.response, str.c_str()); + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_get_flags) + { + MB_String str; + appendFetchString(str, false); + parseCmdResponse(imap, res.response, str.c_str()); + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_get_quota) + parseCmdResponse(imap, res.response, imap_responses[esp_mail_imap_response_quota].text); + else if (imap->_imap_cmd == esp_mail_imap_cmd_id) + parseCmdResponse(imap, res.response, imap_responses[esp_mail_imap_response_id].text); + else if (imap->_imap_cmd == esp_mail_imap_cmd_get_quota_root) + { + parseCmdResponse(imap, res.response, imap_responses[esp_mail_imap_response_quotaroot].text); + imap->_quota_tmp.clear(); + parseCmdResponse(imap, res.response, imap_responses[esp_mail_imap_response_quota].text); + if (imap->_quota_tmp.length() > 0) + { + imap->_quota_root_tmp += (char)':'; + imap->_quota_root_tmp += imap->_quota_tmp; + } + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_get_acl || imap->_imap_cmd == esp_mail_imap_cmd_my_rights) + parseCmdResponse(imap, res.response, imap->_imap_cmd == esp_mail_imap_cmd_get_acl ? imap_responses[esp_mail_imap_response_acl].text : imap_responses[esp_mail_imap_response_myrights].text); + else if (imap->_imap_cmd == esp_mail_imap_cmd_namespace) + parseCmdResponse(imap, res.response, imap_responses[esp_mail_imap_response_namespace].text); + else if (imap->_imap_cmd == esp_mail_imap_cmd_idle) + { + res.completedResponse = res.response[0] == '+'; + res.imapResp = esp_mail_imap_resp_ok; + + imap->_last_host_check_ms = millis(); + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_sequence_set) + { + MB_String str; + appendFetchString(str, true); + parseCmdResponse(imap, res.response, str.c_str()); + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_header) + { + + if (res.headerState == 0 && cMSG(imap).type == esp_mail_imap_msg_num_type_uid) + res.header.message_uid = cMSG(imap).value; + + int _st = res.headerState; + parseHeaderResponse(imap, res, imap->_imap_data->enable.header_case_sensitive); + if (_st == res.headerState && res.headerState > 0 && res.octetCount <= res.header.header_data_len) + collectHeaderField(imap, res.response, res.header, res.headerState); + } + else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_mime) + parsePartHeaderResponse(imap, res, imap->_imap_data->enable.header_case_sensitive); + else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text) + decodeText(imap, res); + else if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) + { + + if (cPart(imap)->xencoding == esp_mail_msg_xencoding_base64) + { + // Multi-line chunked base64 string attachment handle + if (res.octetCount < res.octetLength && res.readLen < BASE64_CHUNKED_LEN) + { + if (strlen(res.lastBuf) > 0) + { + res.buf = allocMem(res.readLen + strlen(res.lastBuf) + 2); + strcpy(res.buf, res.lastBuf); + strcat(res.buf, res.response); + res.readLen = strlen(res.buf); + res.tmo = parseAttachmentResponse(imap, res.buf, res); + // release memory + freeMem(&res.buf); + memset(res.lastBuf, 0, BASE64_CHUNKED_LEN + 1); + if (!res.tmo) + break; + } + else if (res.readLen < BASE64_CHUNKED_LEN + 1) + strcpy(res.lastBuf, res.response); + } + else + { + res.tmo = parseAttachmentResponse(imap, res.response, res); + if (!res.tmo) + break; + } + } + else + res.tmo = parseAttachmentResponse(imap, res.response, res); + } + + res.dataTime = millis(); + } + } + memset(res.response, 0, res.chunkBufSize); + } + } + + if (imap->_imap_cmd == esp_mail_imap_cmd_search) + { + if (imap->_debug && res.searchCount > 0 && res.searchCount < 100) + { + searchReport(imap, 100); + } + } + } + + if ((res.imapResp != esp_mail_imap_resp_ok && imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_header && res.header.header_data_len == 0) || res.imapResp == esp_mail_imap_resp_no) + { + // We don't get any response + + if (res.imapResp == esp_mail_imap_resp_no) + imap->_responseStatus.errorCode = IMAP_STATUS_IMAP_RESPONSE_FAILED; + else if (imap->_imap_data->fetch.modsequence > -1 && imap->isModseqSupported() && res.imapResp == esp_mail_imap_resp_ok && res.header.header_data_len == 0) + imap->_responseStatus.errorCode = IMAP_STATUS_CHANGEDSINC_MODSEQ_TEST_FAILED; + else + imap->_responseStatus.errorCode = IMAP_STATUS_NO_MESSAGE; + +#if !defined(SILENT_MODE) + + if (imap->_statusCallback && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_mime) + sendErrorCB(imap, imap->errorReason().c_str(), false, false); + + if (imap->_debug && imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_mime) + esp_mail_debug_print_tag(imap->errorReason().c_str(), esp_mail_debug_tag_type_error, true); + +#endif + + return false; + } + + // We've got OK or NO responses + + if (res.imapResp == esp_mail_imap_resp_ok) + { + // Response OK + + if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_header) + { + // Headers management + + char *buf = allocMem(res.header.content_type.length() + 1); + strcpy(buf, res.header.content_type.c_str()); + res.header.content_type.clear(); + + MB_String contentTypeName; + appendHeaderName(contentTypeName, message_headers[esp_mail_message_header_field_content_type].text, false, false, false); + + res.buf = subStr(buf, contentTypeName.c_str(), esp_mail_str_35 /* ";" */, 0, 0, false); + if (res.buf) + { + res.headerState = esp_mail_imap_state_content_type; + collectHeaderField(imap, res.buf, res.header, res.headerState); + // release memory + freeMem(&res.buf); + + if (res.header.content_type.length() > 0) + { + int p1 = strposP(res.header.content_type.c_str(), esp_mail_imap_composite_media_type_t::multipart, 0); + if (p1 != -1) + { + p1 += strlen(esp_mail_imap_composite_media_type_t::multipart) + 1; + res.header.multipart = true; + // inline or embedded images + if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::related, p1) != -1) + res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_related; + // multiple text formats e.g. plain, html, enriched + else if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::alternative, p1) != -1) + res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_alternative; + // medias + else if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::parallel, p1) != -1) + res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_parallel; + // rfc822 encapsulated + else if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::digest, p1) != -1) + res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_digest; + else if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::report, p1) != -1) + res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_report; + // others can be attachments + else if (strpos(res.header.content_type.c_str(), esp_mail_imap_multipart_sub_type_t::mixed, p1) != -1) + res.header.multipart_sub_type = esp_mail_imap_multipart_sub_type_mixed; + } + + p1 = strposP(res.header.content_type.c_str(), esp_mail_imap_composite_media_type_t::message, 0); + if (p1 != -1) + { + p1 += strlen(esp_mail_imap_composite_media_type_t::message) + 1; + if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::rfc822, p1) != -1) + { + res.header.rfc822_part = true; + res.header.message_sub_type = esp_mail_imap_message_sub_type_rfc822; + } + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::Partial, p1) != -1) + res.header.message_sub_type = esp_mail_imap_message_sub_type_partial; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::External_Body, p1) != -1) + res.header.message_sub_type = esp_mail_imap_message_sub_type_external_body; + else if (strpos(res.part.content_type.c_str(), esp_mail_imap_message_sub_type_t::delivery_status, p1) != -1) + res.header.message_sub_type = esp_mail_imap_message_sub_type_delivery_status; + } + } + + MB_String charset; + appendLowerCaseString(charset, message_headers[esp_mail_message_header_field_charset].text, false); + charset += esp_mail_str_7; /* "=" */ + + res.buf = subStr(buf, charset.c_str(), NULL, 0, -1, false); + if (res.buf) + { + res.headerState = esp_mail_imap_state_char_set; + collectHeaderField(imap, res.buf, res.header, res.headerState); + // release memory + freeMem(&res.buf); + } + + if (res.header.multipart) + { + if (strcmpP(buf, 0, esp_mail_str_64 /* "boundary=\"" */)) + { + res.buf = subStr(buf, esp_mail_str_64 /* "boundary=\"" */, esp_mail_str_11 /* "\"" */, 0, 0, false); + if (res.buf) + { + res.headerState = esp_mail_imap_state_boundary; + collectHeaderField(imap, res.buf, res.header, res.headerState); + // release memory + freeMem(&res.buf); + } + } + } + } + + // release memory + freeMem(&buf); + + // Decode the headers fields + + for (int i = esp_mail_rfc822_header_field_from; i < esp_mail_rfc822_header_field_maxType; i++) + { + if (i != esp_mail_rfc822_header_field_msg_id && i != esp_mail_rfc822_header_field_flags) + decodeString(imap, res.header.header_fields.header_items[i]); + } + + imap->_headers.push_back(res.header); + } + + if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_mime) + { + // Expect the octet length in the response for the existent part + if (res.part.octetLen > 0) + { + + res.part.partNumStr = cHeader(imap)->partNumStr; + res.part.partNumFetchStr = cHeader(imap)->partNumStr; + if (cHeader(imap)->part_headers.size() > 0) + { + + struct esp_mail_message_part_info_t *_part = &cHeader(imap)->part_headers[cHeader(imap)->part_headers.size() - 1]; + bool rfc822_body_subtype = _part->message_sub_type == esp_mail_imap_message_sub_type_rfc822; + + if (rfc822_body_subtype) + { + if (!_part->rfc822_part) + { + // additional rfc822 message header, store it to the rfc822 part header + _part->rfc822_part = true; + _part->rfc822_header = res.part.rfc822_header; + imap->_rfc822_part_count++; + _part->rfc822_msg_Idx = imap->_rfc822_part_count; + } + } + } + + cHeader(imap)->part_headers.push_back(res.part); + cHeader(imap)->message_data_count = cHeader(imap)->part_headers.size(); + + if (res.part.msg_type != esp_mail_msg_type_none || + res.part.attach_type != esp_mail_att_type_none) + { + if (res.part.attach_type == esp_mail_att_type_attachment || + res.part.message_sub_type != esp_mail_imap_message_sub_type_rfc822) + { + if (res.part.attach_type != esp_mail_att_type_none && + cHeader(imap)->multipart_sub_type != esp_mail_imap_multipart_sub_type_alternative) + { + cHeader(imap)->hasAttachment = true; + cHeader(imap)->attachment_count++; + } + } + } + } + else + { + // nonexistent part + // return false to exit the loop without closing the connection + if (closeSession) + imap->closeSession(); + return false; + } + } + + if (imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) + { + if (cPart(imap) && cPart(imap)->file_open_write) + mbfs->close(mbfs_type imap->_imap_data->storage.type); + } + + if (cPart(imap) && imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_text) + cPart(imap)->text[cPart(imap)->textLen] = 0; + } + else + { + + // Response NO + + // Some server responses NO and should exit (false) from MIME feching loop without + // closing the session + if (imap->_imap_cmd != esp_mail_imap_cmd_fetch_body_mime) + return handleIMAPError(imap, errCode, false); + + if (closeSession) + imap->closeSession(); + return false; + } + + return true; +} + +void ESP_Mail_Client::addHeader(MB_String &s, PGM_P name, const char *s_value, int num_value, bool trim, bool isJson) +{ + if (isJson) + { + s += (s.length() > 0) ? esp_mail_str_77 /* ",\"" */ : esp_mail_str_78 /* "{\"" */; + s += name; + + if (strlen(s_value) > 0) + { + s += esp_mail_str_79; /* "\":\"" */ + ; + if (trim) + { + MB_String t = s_value; + t.replaceAll("\"", ""); + s += t; + } + else + s += s_value; + s += esp_mail_str_11; /* "\"" */ + } + else + { + s += esp_mail_str_34 /* ":" */; + appendSpace(s); + s += num_value; + } + } + else + { + if (s.length() > 0) + appendNewline(s); + s += name; + s += esp_mail_str_34 /* ":" */; + appendSpace(s); + if (strlen(s_value) > 0) + s += s_value; + else + s += num_value; + } +} + +void ESP_Mail_Client::saveHeader(IMAPSession *imap, bool json) +{ + if (!imap->_storageReady) + return; + + MB_String headerFilePath; + + prepareFilePath(imap, headerFilePath, true); + + headerFilePath += json ? esp_mail_str_65 /* "/header.json" */ : esp_mail_str_66 /* "/header.txt" */; + + prepareFileList(imap, headerFilePath); + + int sz = mbfs->open(headerFilePath, mbfs_type imap->_imap_data->storage.type, mb_fs_open_mode_write); + if (sz < 0) + { + imap->_responseStatus.errorCode = sz; + imap->_responseStatus.text.clear(); +#if !defined(SILENT_MODE) + if (imap->_debug) + { + esp_mail_debug_print_tag(imap->errorReason().c_str(), esp_mail_debug_tag_type_error, true); + } +#endif + return; + } + + MB_String s; + for (size_t i = 0; i < imap->_headers.size(); i++) + addHeaderItem(s, &imap->_headers[i], json); + + if (json) + s += esp_mail_str_75; /* "]}" */ + + mbfs->print(mbfs_type imap->_imap_data->storage.type, s.c_str()); + + mbfs->close(mbfs_type imap->_imap_data->storage.type); + + imap->_headerSaved = true; +} + +void ESP_Mail_Client::addHeaderItem(MB_String &str, esp_mail_message_header_t *header, bool json) +{ + MB_String s; + if (json) + { + if (str.length() > 0) + str += esp_mail_str_8; /* "," */ + else + str = esp_mail_str_76; /* "{\"Messages\":[" */ + } + + addHeader(s, message_headers[esp_mail_message_header_field_number].text, "", header->message_no, false, json); + addHeader(s, message_headers[esp_mail_message_header_field_uid].text, "", header->message_uid, false, json); + + if (header->accept_language.length() > 0) + addHeader(s, message_headers[esp_mail_message_header_field_accept_language].text, header->accept_language.c_str(), 0, false, json); + + if (header->content_language.length() > 0) + addHeader(s, message_headers[esp_mail_message_header_field_content_language].text, header->content_language.c_str(), 0, false, json); + + addRFC822Headers(s, &header->header_fields, json); + + for (size_t j = 0; j < header->part_headers.size(); j++) + { + if (header->part_headers[j].rfc822_part) + { + MB_String s1; + addRFC822Headers(s1, &header->part_headers[j].rfc822_header, json); + + if (json) + { + s += esp_mail_str_69; /* ",\"RFC822\":" */ + s += s1; + s += esp_mail_str_36; /* "}" */ + } + else + { + s += esp_mail_str_70; /* "\r\n\r\nRFC822:\r\n" */ + s += s1; + } + } + } + + if (header->attachment_count > 0) + { + if (json) + { + s += esp_mail_str_71 /* ",\"Attachments\":{\"Count\":" */; + s += header->attachment_count; + s += esp_mail_str_72; /* ",\"Files\":[" */ + } + else + { + s += esp_mail_str_73; /* "\r\n\r\nAttachments (" */ + s += header->attachment_count; + s += esp_mail_str_74; /* ")\r\n" */ + } + + int index = 0; + for (size_t j = 0; j < header->part_headers.size(); j++) + { + + if (header->part_headers[j].attach_type == esp_mail_att_type_none || header->part_headers[j].rfc822_part) + continue; + + if (json) + { + if (index > 0) + s += esp_mail_str_8; /* "," */ + s += esp_mail_str_67; /* /"{\"Filename\":\"" */ + s += header->part_headers[j].filename; + s += esp_mail_str_11; /* "\"" */ + } + else + { + if (index > 0) + appendNewline(s); + appendNewline(s); + s += esp_mail_str_68; /* /"Index: " */ + s += index + 1; + addHeader(s, message_headers[esp_mail_message_header_field_filename].text, header->part_headers[j].filename.c_str(), 0, false, json); + } + + addHeader(s, message_headers[esp_mail_message_header_field_name].text, header->part_headers[j].name.c_str(), 0, false, json); + addHeader(s, message_headers[esp_mail_message_header_field_size].text, "", header->part_headers[j].attach_data_size, false, json); + addHeader(s, message_headers[esp_mail_message_header_field_mime].text, header->part_headers[j].content_type.c_str(), 0, false, json); + addHeader(s, message_headers[esp_mail_message_header_field_type].text, header->part_headers[j].attach_type == esp_mail_att_type_attachment ? esp_mail_content_disposition_type_t::attachment : esp_mail_content_disposition_type_t::inline_, 0, false, json); + addHeader(s, message_headers[esp_mail_message_header_field_description].text, header->part_headers[j].content_description.c_str(), 0, false, json); + addHeader(s, message_headers[esp_mail_message_header_field_creation_date].text, header->part_headers[j].creation_date.c_str(), 0, false, json); + + if (json) + s += esp_mail_str_36; /* "}" */ + + index++; + } + + if (json) + s += esp_mail_str_75; /* "]}" */ + } + + if (json) + { + s += esp_mail_str_36; /* "}" */ + } + + str += s; +} + +int ESP_Mail_Client::getRFC822HeaderPtr(int index, esp_mail_imap_rfc822_msg_header_item_t *header) +{ + if (index > esp_mail_rfc822_header_field_from && index < esp_mail_rfc822_header_field_maxType) + return toAddr(header->header_items[index]); + return 0; +} + +void ESP_Mail_Client::addRFC822Headers(MB_String &s, esp_mail_imap_rfc822_msg_header_item_t *header, bool json) +{ + for (int i = esp_mail_rfc822_header_field_from; i < esp_mail_rfc822_header_field_maxType; i++) + addRFC822HeaderItem(s, header, i, json); +} + +void ESP_Mail_Client::addRFC822HeaderItem(MB_String &s, esp_mail_imap_rfc822_msg_header_item_t *header, int index, bool json) +{ + int ptr = getRFC822HeaderPtr(index, header); + if (ptr > 0) + addHeader(s, rfc822_headers[index].text, addrTo(ptr)->c_str(), 0, rfc822_headers[index].trim, json); +} + +esp_mail_imap_response_status ESP_Mail_Client::imapResponseStatus(IMAPSession *imap, char *response, PGM_P tag) +{ + imap->_responseStatus.clear(false); + MB_String test; + esp_mail_imap_response_status status = esp_mail_imap_resp_unknown; + esp_mail_imap_response_types type = esp_mail_imap_response_maxType; + + if (strpos(response, imap->prependTag(imap_responses[esp_mail_imap_response_ok].text, tag).c_str(), 0) > -1) + { + status = esp_mail_imap_resp_ok; + type = esp_mail_imap_response_ok; + } + else if (strpos(response, imap->prependTag(imap_responses[esp_mail_imap_response_no].text, tag).c_str(), 0) > -1) + { + status = esp_mail_imap_resp_no; + type = esp_mail_imap_response_no; + } + else if (strpos(response, imap->prependTag(imap_responses[esp_mail_imap_response_bad].text, tag).c_str(), 0) > -1) + { + status = esp_mail_imap_resp_bad; + type = esp_mail_imap_response_bad; + } + + if (status != esp_mail_imap_resp_unknown) + { + test = imap->prependTag(imap_responses[type].text, tag); + + imap->_responseStatus.text = &response[test.length()]; + if (imap->_responseStatus.text[imap->_responseStatus.text.length() - 2] == '\r') + imap->_responseStatus.text[imap->_responseStatus.text.length() - 2] = 0; + + test = imap_responses[type].text; + test.trim(); + imap->_responseStatus.status = test; + imap->_responseStatus.completed = true; + } + return status; +} + +bool ESP_Mail_Client::parseCapabilityResponse(IMAPSession *imap, const char *buf, int &chunkIdx) +{ + if (chunkIdx == 0) + { + MB_String res; + // We add white space to make post token checking to work in all capabilities. + // This will allow us to check "IDLE " and "ID " correctly. + appendSpace(res, false, buf); + + if (strposP(res.c_str(), imap_responses[esp_mail_imap_response_capability_untagged].text, 0) > -1 || strposP(res.c_str(), imap_responses[esp_mail_imap_response_capability].text, 0) > -1) + { + for (int i = esp_mail_auth_capability_plain; i < esp_mail_auth_capability_maxType; i++) + { + if (strposP(res.c_str(), imap_auth_cap_pre_tokens[i].c_str(), 0) > -1) + imap->_auth_capability[i] = true; + } + + for (int i = esp_mail_imap_read_capability_imap4; i < esp_mail_imap_read_capability_maxType; i++) + { + if (strposP(res.c_str(), imap_read_cap_post_tokens[i].c_str(), 0) > -1) + { + imap->_feature_capability[i] = true; + if (i == esp_mail_imap_read_capability_logindisable) + imap->_auth_capability[esp_mail_auth_capability_login] = false; + } + } + + return true; + } + } + + return false; +} + +char *ESP_Mail_Client::getList(char *buf, bool &isList) +{ + if (buf[0] == '(' && buf[1] != ')') + { + if (buf[strlen(buf) - 1] == ')') + buf[strlen(buf) - 1] = 0; + else + isList = true; + + return &buf[1]; + } + else if (isList) + { + if (buf[strlen(buf) - 1] == ')') + { + buf[strlen(buf) - 1] = 0; + isList = false; + } + } + + return buf; +} + +void ESP_Mail_Client::parseFoldersResponse(IMAPSession *imap, char *buf, bool list) +{ + struct esp_mail_folder_info_t fd; + int pos = list ? strposP(buf, imap_responses[esp_mail_imap_response_list].text, 0) : strposP(buf, imap_responses[esp_mail_imap_response_lsub].text, 0); + bool isList = false, delimOk = false; + if (pos != -1) + { + char *p = allocMem(strlen(buf)); + strcpy(p, buf); + char *pp = p; + char *end = p; + int count = 0; + int tkPos = 3; + + while (pp != NULL) + { + // See RFC2047.h + ESP_MAIL_STRSEP(&end, " "); + count++; + + if (count >= tkPos && strlen(pp) > 0) + { + if (count == tkPos && pp[0] == '(' && pp[1] != ')') + fd.attributes = getList(pp, isList); + else if (isList) + { + fd.attributes += ' '; + fd.attributes += getList(pp, isList); + } + else + { + if (pp[strlen(pp) - 1] == '"') + pp[strlen(pp) - 1] = 0; + + const char *ptr = pp[0] == '"' ? &pp[1] : &pp[0]; + + if (!delimOk) + { + delimOk = true; + fd.delimiter = ptr; + } + else + { + if (fd.name.length() > 0) + fd.name += ' '; + fd.name += ptr; + } + } + } + pp = end; + } + + // release memory + freeMem(&p); + + imap->_folders.add(fd); + } +} + +bool ESP_Mail_Client::parseIdleResponse(IMAPSession *imap) +{ + + int chunkBufSize = 0; + + if (!reconnect(imap)) + return false; + + if (imap->client.connected()) + chunkBufSize = imap->client.available(); + else + return false; + + if (chunkBufSize > 0) + { + chunkBufSize = ESP_MAIL_CLIENT_RESPONSE_BUFFER_SIZE; + + char *buf = allocMem(chunkBufSize + 1); + + int octetCount = 0; + + int readLen = 0; + + MB_String ovfBuf; + readResponse(imap, buf, chunkBufSize, readLen, false, octetCount, ovfBuf); + + // If buffer overflown, copy from overflow buffer + if (ovfBuf.length() > 0) + { + // release memory + freeMem(&buf); + buf = allocMem(ovfBuf.length() + 1); + strcpy(buf, ovfBuf.c_str()); + ovfBuf.clear(); + } + + if (readLen > 0) + { + + if (imap->_debug && imap->_debugLevel > esp_mail_debug_level_basic) + esp_mail_debug_print((const char *)buf, true); + + char *tmp = nullptr; + int p1 = -1; + bool exists = false; + + tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_exists].text, 0); + if (tmp) + { + int numMsg = imap->_mbif._msgCount; + imap->_mbif._msgCount = atoi(tmp); + // release memory + freeMem(&tmp); + exists = true; + imap->_mbif._folderChanged |= (int)imap->_mbif._msgCount != numMsg; + if ((int)imap->_mbif._msgCount > numMsg) + { + imap->_mbif._polling_status.type = imap_polling_status_type_new_message; + imap->_mbif._polling_status.messageNum = imap->_mbif._msgCount; + } + goto ex; + } + + tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_expunge].text, 0); + if (tmp) + { + imap->_mbif._polling_status.type = imap_polling_status_type_remove_message; + imap->_mbif._polling_status.messageNum = atoi(tmp); + + if (imap->_mbif._polling_status.messageNum == imap->_mbif._msgCount && imap->_mbif._nextUID > 0) + imap->_mbif._nextUID--; + + // release memory + freeMem(&tmp); + imap->_mbif._folderChanged = true; + goto ex; + } + + tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_recent].text, 0); + if (tmp) + { + imap->_mbif._recentCount = atoi(tmp); + // release memory + freeMem(&tmp); + goto ex; + } + + tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_fetch].text, 0); + if (tmp) + { + imap->_mbif._polling_status.messageNum = atoi(tmp); + // release memory + freeMem(&tmp); + + imap->_mbif._polling_status.argument = buf; + imap->_mbif._polling_status.argument.erase(0, p1 + 8); + imap->_mbif._polling_status.argument.pop_back(); + imap->_mbif._folderChanged = true; + imap->_mbif._polling_status.type = imap_polling_status_type_fetch_message; + goto ex; + } + + ex: + + imap->_mbif._floderChangedState = (imap->_mbif._folderChanged && exists) || imap->_mbif._polling_status.type == imap_polling_status_type_fetch_message; + } + + // release memory + freeMem(&buf); + } + + size_t imap_idle_tmo = imap->_imap_data->limit.imap_idle_timeout; + + if (imap_idle_tmo < 60 * 1000 || imap_idle_tmo > 29 * 60 * 1000) + imap_idle_tmo = 10 * 60 * 1000; + + if (millis() - imap->_mbif._idleTimeMs > imap_idle_tmo) + { + if (imap->mStopListen(true)) + return imap->mListen(true); + return false; + } + + return true; +} + +void ESP_Mail_Client::appendFetchString(MB_String &buf, bool uid) +{ + if (uid) + buf += imap_cmd_post_tokens[esp_mail_imap_command_uid]; + else + joinStringSpace(buf, false, 2, imap_commands[esp_mail_imap_command_flags].text, esp_mail_str_38 /* "(" */); +} + +void ESP_Mail_Client::parseCmdResponse(IMAPSession *imap, char *buf, PGM_P find) +{ + if (imap->_imap_cmd == esp_mail_imap_cmd_get_uid) + imap->_uid_tmp = 0; + + char *tmp = nullptr; + int p1 = strposP(buf, find, 0); + if (p1 != -1) + { + if (imap->_imap_cmd == esp_mail_imap_cmd_get_quota_root || + imap->_imap_cmd == esp_mail_imap_cmd_get_acl || + imap->_imap_cmd == esp_mail_imap_cmd_my_rights) + { + int ofs = imap->_imap_cmd == esp_mail_imap_cmd_get_quota_root ? 0 : 1; + int p2 = strposP(buf, esp_mail_str_2 /* " " */, p1 + strlen_P(find) + ofs); + if (p2 != -1) + { + int len = strlen(buf) - p2 - 1; + tmp = allocMem(len); + strncpy(tmp, buf + p2 + 1, strlen(buf) - p2 - 1); + if (imap->_imap_cmd == esp_mail_imap_cmd_get_quota_root) + { + if (imap->_quota_root_tmp.length() > 0) + imap->_quota_root_tmp += esp_mail_str_8; /* ";" */ + imap->_quota_root_tmp += tmp; + } + else + { + imap->_acl_tmp = tmp; + } + + // release memory + freeMem(&tmp); + } + } + else + { + int len = imap->_imap_cmd == esp_mail_imap_cmd_get_uid ? 20 : strlen(buf) - p1 - strlen_P(find); + int ofs = imap->_imap_cmd == esp_mail_imap_cmd_get_uid || + imap->_imap_cmd == esp_mail_imap_cmd_fetch_sequence_set + ? 1 + : imap->_imap_cmd == esp_mail_imap_cmd_namespace || imap->_imap_cmd == esp_mail_imap_cmd_id ? 0 + : 2; + tmp = allocMem(len); + + strncpy(tmp, buf + p1 + strlen_P(find), strlen(buf) - p1 - strlen_P(find) - ofs); + + esp_mail_imap_msg_num_t msg_num; + + switch ((int)imap->_imap_cmd) + { + case esp_mail_imap_cmd_get_uid: + imap->_uid_tmp = atoi(tmp); + break; + case esp_mail_imap_cmd_get_flags: + imap->_flags_tmp = tmp; + break; + case esp_mail_imap_cmd_get_quota: + imap->_quota_tmp = tmp; + break; + case esp_mail_imap_cmd_id: + imap->_server_id_tmp = tmp; + break; + case esp_mail_imap_cmd_namespace: + imap->_ns_tmp += tmp; + break; + case esp_mail_imap_cmd_fetch_sequence_set: + + msg_num.type = esp_mail_imap_msg_num_type_uid; + msg_num.value = (uint32_t)atoi(tmp); + imap->_imap_msg_num.push_back(msg_num); + + if (imap->_imap_msg_num.size() > imap->_imap_data->limit.fetch) + imap->_imap_msg_num.erase(imap->_imap_msg_num.begin()); + + break; + default: + break; + } + } + + // release memory + freeMem(&tmp); + } +} + +bool ESP_Mail_Client::getFlags(IMAPSession *imap, char *buf, esp_mail_imap_response_types type) +{ + if (strposP(buf, imap_responses[type].text, 0) != -1) + { + char *p = allocMem(strlen(buf)); + strcpy(p, buf); + char *pp = p; + char *end = p; + int count = 0; + bool isList = false; + int tkPos = (type == esp_mail_imap_response_permanent_flags) ? 4 : 3; + + while (pp != NULL) + { + // See RFC2047.h + ESP_MAIL_STRSEP(&end, " "); + count++; + if (count >= tkPos && strlen(pp) > 0) + { + if (type == esp_mail_imap_response_permanent_flags && pp[strlen(pp) - 1] == ']') + pp[strlen(pp) - 1] = 0; + + if (count == tkPos && pp[0] == '(' && pp[1] != ')') + imap->_mbif.addFlag(getList(pp, isList), type == esp_mail_imap_response_permanent_flags); + else if (isList) + imap->_mbif.addFlag(getList(pp, isList), type == esp_mail_imap_response_permanent_flags); + } + pp = end; + } + + // release memory + freeMem(&p); + + return true; + } + + return false; +} + +void ESP_Mail_Client::parseExamineResponse(IMAPSession *imap, char *buf) +{ + char *tmp = NULL; + + tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_exists].text, 0); + if (tmp) + { + imap->_mbif._msgCount = atoi(tmp); + // release memory + freeMem(&tmp); + return; + } + + tmp = subStr(buf, NULL, imap_responses[esp_mail_imap_response_recent].text, 0); + if (tmp) + { + imap->_mbif._recentCount = atoi(tmp); + // release memory + freeMem(&tmp); + return; + } + + if (imap->_mbif._flags.size() == 0 && getFlags(imap, buf, esp_mail_imap_response_flags)) + return; + + if (imap->_mbif._permanent_flags.size() == 0 && getFlags(imap, buf, esp_mail_imap_response_permanent_flags)) + return; + + if (imap->_mbif._uidValidity == 0) + { + tmp = subStr(buf, imap_responses[esp_mail_imap_response_uidvalidity].text, esp_mail_str_41 /* "]" */, 0, 0); + if (tmp) + { + imap->_mbif._uidValidity = atoi(tmp); + // release memory + freeMem(&tmp); + return; + } + } + + if (imap->_nextUID.length() == 0) + { + tmp = subStr(buf, imap_responses[esp_mail_imap_response_uidnext].text, esp_mail_str_41 /* "]" */, 0, 0); + if (tmp) + { + imap->_nextUID = tmp; + imap->_mbif._nextUID = atoi(tmp); + // release memory + freeMem(&tmp); + return; + } + } + + if (imap->_unseenMsgIndex.length() == 0) + { + tmp = subStr(buf, imap_responses[esp_mail_imap_response_unseen].text, esp_mail_str_41 /* "]" */, 0, 0); + if (tmp) + { + imap->_unseenMsgIndex = tmp; + imap->_mbif._unseenMsgIndex = atoi(tmp); + // release memory + freeMem(&tmp); + return; + } + } + + if (imap->isCondStoreSupported()) + { + tmp = subStr(buf, imap_responses[esp_mail_imap_response_highest_modsec].text, esp_mail_str_41 /* "]" */, 0, 0); + if (tmp) + { + imap->_mbif._highestModSeq = tmp; + // release memory + freeMem(&tmp); + return; + } + + tmp = subStr(buf, imap_responses[esp_mail_imap_response_nomodsec].text, nullptr, 0, 0); + if (tmp) + { + imap->_mbif._nomodsec = true; + // release memory + freeMem(&tmp); + return; + } + } +} + +bool ESP_Mail_Client::handleIMAPError(IMAPSession *imap, int err, bool ret) +{ + if (err < 0) + { + errorStatusCB(imap, nullptr, err, true); + + if (imap->_headers.size() > 0 && cHeader(imap)) + { + if ((imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_attachment || imap->_imap_cmd == esp_mail_imap_cmd_fetch_body_inline) && (imap->_imap_data->download.attachment || imap->_imap_data->download.inlineImg)) + { + if (cPart(imap) && cHeader(imap)->part_headers.size() > 0) + cPart(imap)->download_error = imap->errorReason().c_str(); + } + else if (cHeader(imap)) + cHeader(imap)->error_msg = imap->errorReason().c_str(); + + cHeader(imap)->error = true; + } + } + + closeTCPSession(imap); + + imap->_cbData.empty(); + + return ret; +} + +void ESP_Mail_Client::prepareFileList(IMAPSession *imap, MB_String &filePath) +{ +#if defined(MBFS_SD_FS) + if (!mbfs->longNameSupported()) + { + cHeader(imap)->sd_alias_file_count++; + MB_String alias = cHeader(imap)->message_uid; + alias += esp_mail_str_83; /* "_" */ + alias += cHeader(imap)->sd_alias_file_count; + + if (imap->_sdFileList.length() > 0) + { + if (imap->_sdFileList[imap->_sdFileList.length() - 1] == ']') + { + imap->_sdFileList[imap->_sdFileList.length() - 1] = 0; + imap->_sdFileList += esp_mail_str_8; /* "," */ + } + } + imap->_sdFileList += esp_mail_str_80; /* "{\"Renamed\":\"" */ + imap->_sdFileList += alias; + imap->_sdFileList += esp_mail_str_81; /* "\",\"Original\":\"" */ + imap->_sdFileList += filePath; + imap->_sdFileList += esp_mail_str_82; /* "\"}]" */ + // rename the original file + filePath = alias; + } +#endif +} + +bool ESP_Mail_Client::parseAttachmentResponse(IMAPSession *imap, char *buf, esp_mail_imap_response_data &res) +{ + int bufLen = res.readLen; + + if (res.chunkIdx == 0) + { + char *tmp = subStr(buf, esp_mail_str_36 /* "{" */, esp_mail_str_37 /* "}" */, 0); + if (tmp) + { + res.chunkIdx++; + res.octetCount = 0; // CRLF counted from first line + res.octetLength = atoi(tmp); + // release memory + freeMem(&tmp); + cPart(imap)->octetLen = res.octetLength; + cPart(imap)->octetCount = 0; + cHeader(imap)->total_download_size += res.octetLength; + imap->_lastProgress = -1; + +#if defined(ESP_MAIL_OTA_UPDATE_ENABLED) + if (cPart(imap)->is_firmware_file) + { + cPart(imap)->is_firmware_file = Update.begin(cPart(imap)->attach_data_size); + + if (!cPart(imap)->is_firmware_file) + { + imap->_responseStatus.errorCode = IMAP_STATUS_FIRMWARE_UPDATE_INIT_FAILED; + imap->_responseStatus.text.clear(); + } + +#if !defined(SILENT_MODE) + + sendCallback(imap, esp_mail_cb_str_42 /* "Updating firmware..." */, true, false); + + if (!cPart(imap)->is_firmware_file) + { + printDebug(imap, + imap->errorReason().c_str(), + imap->errorReason().c_str(), + esp_mail_debug_tag_type_error, + true, + false); + } + +#endif + } +#endif + + if (!cPart(imap)->file_open_write) + { + + if (imap->_storageReady && cPart(imap)->save_to_file) + { + res.downloadRequest = true; + + res.filePath.clear(); + + res.filePath += imap->_imap_data->storage.saved_path; + res.filePath += esp_mail_str_10; /* "/" */ + res.filePath += cHeader(imap)->message_uid; + res.filePath += esp_mail_str_10; /* "/" */ + res.filePath += cPart(imap)->filename; + + prepareFileList(imap, res.filePath); + + int sz = mbfs->open(res.filePath, mbfs_type imap->_imap_data->storage.type, mb_fs_open_mode_write); + + if (sz < 0) + { + imap->_responseStatus.errorCode = sz; + imap->_responseStatus.text.clear(); +#if !defined(SILENT_MODE) + printDebug(imap, + imap->errorReason().c_str(), + imap->errorReason().c_str(), + esp_mail_debug_tag_type_error, + true, + false); +#endif + } + + cPart(imap)->file_open_write = true; + } + } + } + return true; + } + + yield_impl(); + + if (res.octetLength == 0) + return true; + + if (cPart(imap)->octetCount <= res.octetLength) + { + if (cPart(imap)->octetCount + bufLen > res.octetLength) + { + bufLen = res.octetLength - cPart(imap)->octetCount; + buf[bufLen] = 0; + cPart(imap)->octetCount += bufLen; + } + else + cPart(imap)->octetCount = res.octetCount; + + if (imap->_imap_data->enable.download_status) + { + if (imap->_debug) + downloadReport(imap, 100 * cPart(imap)->octetCount / res.octetLength); + } + + if (cPart(imap)->octetCount > res.octetLength) + return true; + + bool write_error = false, fw_write_error = false; + + if (cPart(imap)->xencoding == esp_mail_msg_xencoding_base64) + { + + size_t olen = 0; + unsigned char *decoded = decodeBase64((const unsigned char *)buf, bufLen, &olen); + + if (decoded) + { + + if (!cPart(imap)->sizeProp) + { + cPart(imap)->attach_data_size += olen; + cHeader(imap)->total_attach_data_size += cPart(imap)->attach_data_size; + } + + sendStreamCB(imap, (void *)decoded, olen, res.chunkIdx, false); + + size_t write = olen; + + if (cPart(imap)->is_firmware_file) + { +#if defined(ESP_MAIL_OTA_UPDATE_ENABLED) + size_t fw_write = Update.write((uint8_t *)decoded, olen); + cPart(imap)->firmware_downloaded_byte += fw_write == olen ? olen : 0; + fw_write_error = fw_write != olen; +#endif + } + + if (cPart(imap)->save_to_file) + { + if (mbfs->ready(mbfs_type imap->_imap_data->storage.type)) + write = mbfs->write(mbfs_type imap->_imap_data->storage.type, (uint8_t *)decoded, olen); + } + + yield_impl(); + // release memory + freeMem(&decoded); + + write_error = write != olen; + } + + if (!reconnect(imap)) + return false; + } + else + { + // binary content + if (!cPart(imap)->sizeProp) + { + cPart(imap)->attach_data_size += bufLen; + cHeader(imap)->total_attach_data_size += cPart(imap)->attach_data_size; + } + + sendStreamCB(imap, (void *)buf, bufLen, res.chunkIdx, false); + + int write = bufLen; + + if (cPart(imap)->is_firmware_file) + { +#if defined(ESP_MAIL_OTA_UPDATE_ENABLED) + int fw_write = Update.write((uint8_t *)buf, bufLen); + cPart(imap)->firmware_downloaded_byte += fw_write == bufLen ? (size_t)bufLen : 0; + fw_write_error = fw_write != bufLen; +#endif + } + + if (cPart(imap)->save_to_file) + { + if (mbfs->ready(mbfs_type imap->_imap_data->storage.type)) + write = mbfs->write(mbfs_type imap->_imap_data->storage.type, (uint8_t *)buf, bufLen); + } + + yield_impl(); + + write_error = write != bufLen; + + if (!reconnect(imap)) + return false; + } + +#if defined(ESP_MAIL_OTA_UPDATE_ENABLED) + if (cPart(imap)->is_firmware_file) + { + bool update_result_ok = !fw_write_error; + + if (!imap->_isFirmwareUpdated && update_result_ok && + (cPart(imap)->firmware_downloaded_byte == (size_t)cPart(imap)->attach_data_size || cPart(imap)->octetCount >= res.octetLength)) + { + update_result_ok = Update.end(cPart(imap)->octetCount >= res.octetLength); + if (update_result_ok) + imap->_isFirmwareUpdated = true; + } + + if (!update_result_ok) + { + cPart(imap)->is_firmware_file = false; + + imap->_responseStatus.errorCode = fw_write_error ? IMAP_STATUS_FIRMWARE_UPDATE_WRITE_FAILED : IMAP_STATUS_FIRMWARE_UPDATE_END_FAILED; + imap->_responseStatus.text.clear(); + +#if !defined(SILENT_MODE) + printDebug(imap, + imap->_responseStatus.text.c_str(), + imap->errorReason().c_str(), + esp_mail_debug_tag_type_error, + !imap->_debug, + false); +#endif + } + } +#endif + + if (write_error || fw_write_error) + return false; + } + + res.chunkIdx++; + return true; +} + +void ESP_Mail_Client::downloadReport(IMAPSession *imap, int progress) +{ + printProgress(progress, imap->_lastProgress); +} + +void ESP_Mail_Client::fetchReport(IMAPSession *imap, int progress, bool download) +{ +#if !defined(SILENT_MODE) + if (imap->_debug && imap->_lastProgress == -1 && strcmp_P(cPart(imap)->filename.c_str(), esp_mail_str_84 /* "message" */) != 0) + esp_mail_debug_print_tag(cPart(imap)->filename.c_str(), esp_mail_debug_tag_type_client, true); + printProgress(progress, imap->_lastProgress); +#endif +} + +void ESP_Mail_Client::searchReport(IMAPSession *imap, int progress) +{ + printProgress(progress, imap->_lastProgress); +} + +struct esp_mail_imap_msg_num_t ESP_Mail_Client::cMSG(IMAPSession *imap) +{ + return imap->_imap_msg_num[cIdx(imap)]; +} + +int ESP_Mail_Client::cIdx(IMAPSession *imap) +{ + return imap->_cMsgIdx; +} + +void ESP_Mail_Client::decodeText(IMAPSession *imap, esp_mail_imap_response_data &res) +{ + int bufLen = res.readLen; + bool rfc822_body_subtype = cPart(imap)->message_sub_type == esp_mail_imap_message_sub_type_rfc822; + if (res.chunkIdx == 0) + { + + imap->_lastProgress = -1; + char *tmp = subStr(res.response, esp_mail_str_36 /* "{" */, esp_mail_str_37 /* "}" */, 0); + if (tmp) + { + res.chunkIdx++; + res.octetCount = 0; + res.octetLength = atoi(tmp); + // release memory + freeMem(&tmp); + cPart(imap)->octetLen = res.octetLength; + cPart(imap)->octetCount = 0; + + bool dlMsg = (rfc822_body_subtype && imap->_imap_data->download.rfc822) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->download.text))); + if (dlMsg) + prepareFilePath(imap, res.filePath, false); + + if (res.filePath.length() == 0) + { + if (!rfc822_body_subtype) + res.filePath += esp_mail_str_84; /* "message" */ + else + joinStringSpace(res.filePath, false, 2, esp_mail_str_85 /* "rfc822" */, esp_mail_str_84 /* "message" */); + } + cPart(imap)->filename = res.filePath; + + if (imap->_storageReady && !cPart(imap)->file_open_write && dlMsg) + { + + prepareFileList(imap, res.filePath); + + int sz = mbfs->open(res.filePath, mbfs_type imap->_imap_data->storage.type, mb_fs_open_mode_write); + if (sz > -1) + { + res.downloadRequest = true; + cPart(imap)->file_open_write = true; + } + else + { + imap->_responseStatus.errorCode = sz; + imap->_responseStatus.text.clear(); +#if !defined(SILENT_MODE) + if (imap->_debug) + esp_mail_debug_print_tag(imap->errorReason().c_str(), esp_mail_debug_tag_type_error, true); +#endif + } + } + + return; + } + else + { +#if !defined(SILENT_MODE) + if (imap->_debug) + esp_mail_debug_print_tag(esp_mail_error_imap_str_12 /* "no centent" */, esp_mail_debug_tag_type_client, false); +#endif + } + } + + yield_impl(); + + if (res.octetLength == 0) + return; + + bool enableDownloads = (imap->_imap_data->download.rfc822 && rfc822_body_subtype) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->download.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->download.text))); + + if (imap->_imap_data->download.rfc822 || imap->_imap_data->download.html || imap->_imap_data->download.text || (rfc822_body_subtype && imap->_imap_data->enable.rfc822) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->enable.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->enable.text)))) + { + + if (cPart(imap)->octetCount + bufLen >= res.octetLength) + { + bufLen = res.octetLength - cPart(imap)->octetCount; + cPart(imap)->octetCount += bufLen; + + if (res.octetLength <= res.octetCount && cPart(imap)->xencoding != esp_mail_msg_xencoding_base64 && cPart(imap)->xencoding != esp_mail_msg_xencoding_qp) + bufLen = 0; + + res.response[bufLen] = 0; + } + else + cPart(imap)->octetCount = res.octetCount; + + if (imap->_debug) + fetchReport(imap, 100 * cPart(imap)->octetCount / res.octetLength, enableDownloads); + + if (cPart(imap)->octetCount <= res.octetLength) + { + bool hrdBrk = cPart(imap)->xencoding == esp_mail_msg_xencoding_qp; + hrdBrk &= cPart(imap)->octetCount < res.octetLength; + hrdBrk &= bufLen == 2 && res.response[bufLen - 2] != '\r' && res.response[bufLen - 1] != '\n'; + + // remove soft break for QP + if (bufLen <= QP_ENC_MSG_LEN && res.response[bufLen - 1] == '=' && cPart(imap)->xencoding == esp_mail_msg_xencoding_qp) + { + hrdBrk = false; + res.response[bufLen - 1] = 0; + bufLen--; + } + + size_t olen = 0; + char *decoded = nullptr; + MB_String str; + bool dontDeleteOrModify = false; + + // decode the content based on the transfer decoding + if (cPart(imap)->xencoding == esp_mail_msg_xencoding_base64) + { + decoded = (char *)decodeBase64((const unsigned char *)res.response, bufLen, &olen); + } + else if (cPart(imap)->xencoding == esp_mail_msg_xencoding_qp) + { + decoded = allocMem(bufLen + 10); + decodeQP_UTF8(res.response, decoded); + olen = strlen(decoded); + } + else if (cPart(imap)->xencoding == esp_mail_msg_xencoding_7bit) + { + decoded = decode7Bit_UTF8(res.response); + olen = strlen(decoded); + } + else if (cPart(imap)->xencoding == esp_mail_msg_xencoding_8bit) + { + decoded = decode8Bit_UTF8(res.response); + olen = strlen(decoded); + } + else + { + // binary + dontDeleteOrModify = true; + decoded = res.response; + olen = bufLen; + } + + if (decoded) + { + // charset? apply character decoding to the decoded or nonencoded content + if ((rfc822_body_subtype && imap->_imap_data->enable.rfc822) || (!rfc822_body_subtype && ((cPart(imap)->msg_type == esp_mail_msg_type_html && imap->_imap_data->enable.html) || ((cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) && imap->_imap_data->enable.text)))) + { + if (imap->_charDecCallback) + { + IMAP_Decoding_Info decoding; + decoding.charset = cPart(imap)->charset.c_str(); + decoding.data = decoded; + decoding.type = IMAP_Decoding_Info::message_part_type_text; + + imap->_charDecCallback(&decoding); + + if (decoding.decodedString.length() > 0) + { + char *buf2 = allocMem(decoding.decodedString.length() + 1); + strcpy(buf2, decoding.decodedString.c_str()); + + if (decoded && !dontDeleteOrModify) + // release memory + freeMem(&decoded); + + decoded = buf2; + olen = strlen(buf2); + } + } + else + { + esp_mail_char_decoding_scheme scheme = getEncodingFromCharset(cPart(imap)->charset.c_str()); + + if (scheme == esp_mail_char_decoding_scheme_iso8859_1) + { + int ilen = olen; + int olen2 = (ilen + 1) * 2; + unsigned char *tmp = allocMem(olen2); + decodeLatin1_UTF8(tmp, &olen2, (unsigned char *)decoded, &ilen); + + if (decoded && !dontDeleteOrModify) + // release memory + freeMem(&decoded); + + olen = olen2; + decoded = (char *)tmp; + } + else if (scheme == esp_mail_char_decoding_scheme_tis_620 || scheme == esp_mail_char_decoding_scheme_iso8859_11 || scheme == esp_mail_char_decoding_scheme_windows_874) + { + char *out = allocMem((olen + 1) * 3); + decodeTIS620_UTF8(out, decoded, olen); + olen = strlen(out); + if (decoded && !dontDeleteOrModify) + // release memory + freeMem(&decoded); + decoded = out; + } + } + + if (cPart(imap)->text.length() < imap->_imap_data->limit.msg_size) + { + + if (cPart(imap)->text.length() + olen < imap->_imap_data->limit.msg_size) + { + cPart(imap)->textLen += olen; + cPart(imap)->text.append(decoded, olen); + if (hrdBrk) + { + appendNewline(cPart(imap)->text); + cPart(imap)->textLen += 2; + } + } + else + { + int d = imap->_imap_data->limit.msg_size - cPart(imap)->text.length(); + cPart(imap)->textLen += d; + if (d > 0) + cPart(imap)->text.append(decoded, d); + + if (hrdBrk) + { + appendNewline(cPart(imap)->text); + cPart(imap)->textLen += 2; + } + } + } + } + + if (res.filePath.length() > 0 && res.downloadRequest) + { + if (mbfs->ready(mbfs_type imap->_imap_data->storage.type)) + { + if (olen > 0) + mbfs->write(mbfs_type imap->_imap_data->storage.type, (uint8_t *)decoded, olen); + if (hrdBrk) + mbfs->write(mbfs_type imap->_imap_data->storage.type, (uint8_t *)"\r\n", 2); + } + } + + sendStreamCB(imap, (void *)decoded, olen, res.chunkIdx, hrdBrk); + + if (decoded && !dontDeleteOrModify) + // release memory + freeMem(&decoded); + } + } + } + + res.chunkIdx++; +} + +void ESP_Mail_Client::sendStreamCB(IMAPSession *imap, void *buf, size_t len, int chunkIndex, bool hrdBrk) +{ + if (imap->_mimeDataStreamCallback && len > 0) + { + MIME_Data_Stream_Info streaminfo; + streaminfo.uid = cHeader(imap)->message_uid; + streaminfo.disposition = cPart(imap)->content_disposition.c_str(); + streaminfo.type = cPart(imap)->content_type.c_str(); + streaminfo.charSet = cPart(imap)->charset.c_str(); + streaminfo.transfer_encoding = cPart(imap)->content_transfer_encoding.c_str(); + streaminfo.cid = cPart(imap)->CID.c_str(); + streaminfo.description = cPart(imap)->content_description.c_str(); + streaminfo.date = cPart(imap)->creation_date.c_str(); + streaminfo.filename = cPart(imap)->filename.c_str(); + streaminfo.size = (cPart(imap)->sizeProp) ? cPart(imap)->attach_data_size : cPart(imap)->octetLen; + streaminfo.name = cPart(imap)->name.c_str(); + streaminfo.octet_size = cPart(imap)->octetLen; + streaminfo.octet_count = cPart(imap)->octetCount; + streaminfo.isFirstData = chunkIndex == 1; + streaminfo.isLastData = !hrdBrk ? cPart(imap)->octetLen == cPart(imap)->octetCount : false; + streaminfo.data_size = len; + streaminfo.data = buf; + streaminfo.flowed = cPart(imap)->plain_flowed; + streaminfo.delsp = cPart(imap)->plain_delsp; + + imap->_mimeDataStreamCallback(streaminfo); + + if (hrdBrk) + { + streaminfo.isFirstData = false; + streaminfo.isLastData = cPart(imap)->octetLen == cPart(imap)->octetCount; + streaminfo.data_size = 2; + streaminfo.data = (void *)"\r\n"; + imap->_mimeDataStreamCallback(streaminfo); + } + } +} + +void ESP_Mail_Client::prepareFilePath(IMAPSession *imap, MB_String &filePath, bool header) +{ + bool rfc822_body_subtype = cPart(imap)->message_sub_type == esp_mail_imap_message_sub_type_rfc822; + MB_String fpath = imap->_imap_data->storage.saved_path; + fpath += esp_mail_str_10; /* "/" */ + fpath += cHeader(imap)->message_uid; + + if (!header) + { + if (!rfc822_body_subtype) + { + fpath += esp_mail_str_86; /* "/msg" */ + if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) + fpath += mimeinfo[esp_mail_file_extension_txt].endsWith; + else if (cPart(imap)->msg_type == esp_mail_msg_type_html) + fpath += mimeinfo[esp_mail_file_extension_htm].endsWith; + } + else + { + fpath += esp_mail_str_87; /* "/rfc822_msg" */ + + if (cPart(imap)->rfc822_msg_Idx > 0) + fpath += cPart(imap)->rfc822_msg_Idx; + + if (cPart(imap)->msg_type == esp_mail_msg_type_plain || cPart(imap)->msg_type == esp_mail_msg_type_enriched) + fpath += mimeinfo[esp_mail_file_extension_txt].endsWith; + else if (cPart(imap)->msg_type == esp_mail_msg_type_html) + fpath += mimeinfo[esp_mail_file_extension_htm].endsWith; + else + // possible rfc822 encapsulated message which cannot fetch its header + fpath += mimeinfo[esp_mail_file_extension_dat].endsWith; + } + } + + filePath = fpath; +} + +void ESP_Mail_Client::sendStorageNotReadyError(IMAPSession *imap, esp_mail_file_storage_type storageType) +{ + +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) +#if !defined(SILENT_MODE) + if (imap->_debug && (storageType == esp_mail_file_storage_type_flash || storageType == esp_mail_file_storage_type_sd)) + { + if (storageType == esp_mail_file_storage_type_flash) + { + esp_mail_debug_print_tag(esp_mail_error_mem_str_1 /* "flash Storage is not ready." */, esp_mail_debug_tag_type_error, true); +#if defined(MB_ARDUINO_PICO) + esp_mail_debug_print_tag(esp_mail_error_mem_str_10 /* "please make sure that the size of flash filesystem is not 0 in Pico." */, esp_mail_debug_tag_type_error, true); +#endif + } + else if (storageType == esp_mail_file_storage_type_sd) + esp_mail_debug_print_tag(esp_mail_error_mem_str_2 /* "SD Storage is not ready." */, esp_mail_debug_tag_type_error, true); + } +#endif +#endif +} + +IMAPSession::IMAPSession(Client *client) +{ + setClient(client); +} + +IMAPSession::IMAPSession() +{ +} + +IMAPSession::~IMAPSession() +{ + empty(); +} + +bool IMAPSession::closeSession() +{ + _prev_imap_cmd = esp_mail_imap_cmd_sasl_login; + _prev_imap_custom_cmd = esp_mail_imap_cmd_custom; + + if (!connected()) + return false; + + if (_mbif._idleTimeMs > 0) + mStopListen(false); + + if (_loginStatus) + { +#if !defined(ESP8266) + /** + * The strange behavior in ESP8266 SSL client, BearSSLWiFiClientSecure + * The client disposed without memory released after the server close + * the connection due to LOGOUT command, which caused the memory leaks. + */ + if (!MailClient.imapLogout(this)) + return false; +#endif + } + + return MailClient.handleIMAPError(this, 0, true); +} + +bool IMAPSession::connected() +{ + return client.connected(); +} + +bool IMAPSession::connect(Session_Config *session_config, IMAP_Data *imap_data, bool login) +{ + _sessionSSL = false; + _sessionLogin = login; + + if (session_config) + session_config->clearPorts(); + + this->_customCmdResCallback = NULL; + + int ptr = toAddr(*session_config); + session_config->addPtr(&_configPtrList, ptr); + + if (!handleConnection(session_config, imap_data, _sessionSSL)) + return false; + + if (!_sessionLogin) + return true; + + _loginStatus = MailClient.imapAuth(this, _sessionSSL); + + return _loginStatus; +} + +bool IMAPSession::mLogin(MB_StringPtr email, MB_StringPtr password, bool isToken) +{ + if (_loginStatus) + return true; + + if (!MailClient.sessionExisted(this)) + return false; + + _session_cfg->login.email = email; + + _session_cfg->login.accessToken.clear(); + _session_cfg->login.password.clear(); + + if (isToken) + _session_cfg->login.accessToken = password; + else + _session_cfg->login.password = password; + + _loginStatus = MailClient.imapAuth(this, _sessionSSL); + + return _loginStatus; +} + +void IMAPSession::appendIdList(MB_String &list, IMAP_Identification *identification) +{ + + if (identification->name.length() > 0 && identification->name.length() <= 1024) + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_name].text, identification->name.c_str()); + + if (identification->version.length() > 0 && identification->version.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_version].text, identification->version.c_str()); + } + + if (identification->os.length() > 0 && identification->os.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_os].text, identification->os.c_str()); + } + + if (identification->vendor.length() > 0 && identification->vendor.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_vendor].text, identification->vendor.c_str()); + } + + if (identification->support_url.length() > 0 && identification->support_url.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_support_url].text, identification->support_url.c_str()); + } + + if (identification->address.length() > 0 && identification->address.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_address].text, identification->address.c_str()); + } + + if (identification->date.length() > 0 && identification->date.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_date].text, identification->date.c_str()); + } + + if (identification->command.length() > 0 && identification->command.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_command].text, identification->command.c_str()); + } + + if (identification->arguments.length() > 0 && identification->arguments.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_arguments].text, identification->arguments.c_str()); + } + + if (identification->environment.length() > 0 && identification->environment.length() <= 1024) + { + if (list.length() > 0) + MailClient.appendSpace(list); + MailClient.appendImap4KeyValue(list, imap_identification_keys[esp_mail_imap_identification_key_environment].text, identification->environment.c_str()); + } +} + +bool IMAPSession::id(IMAP_Identification *identification) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_61 /* "Send client identification..." */, + esp_mail_dbg_str_82 /* "send IMAP command, ID" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + if (!_feature_capability[esp_mail_imap_read_capability_id]) + { +#if !defined(SILENT_MODE) + printDebugNotSupported(); +#endif + return false; + } + + if (!MailClient.reconnect(this)) + return false; + + MB_String cmd, idList; + + appendIdList(idList, identification); + + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_id].text); + + if (idList.length() > 0) + MailClient.appendString(cmd, idList.c_str(), false, false, esp_mail_string_mark_type_round_bracket); + else + { + int bufLen = 50; + char *buf = MailClient.allocMem(bufLen); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_21 /* "(\"name\" \"ESP Mail Client\" \"version\" \"%s\")" */), ESP_MAIL_VERSION); + cmd += buf; + // release memory + MailClient.freeMem(&buf); + } + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_id; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + return true; +} + +String IMAPSession::serverID() +{ + return _server_id_tmp.c_str(); +} + +bool IMAPSession::isAuthenticated() +{ + return _authenticated; +} + +bool IMAPSession::isLoggedIn() +{ + return _loginStatus; +} + +bool IMAPSession::isFirmwareUpdateSuccess() +{ + return _isFirmwareUpdated; +} + +bool IMAPSession::mCustomConnect(Session_Config *session_config, imapResponseCallback callback, MB_StringPtr tag) +{ + this->_customCmdResCallback = callback; + this->_responseStatus.tag = tag; + + bool ssl = false; + if (!handleConnection(session_config, NULL, ssl)) + return false; + + return true; +} + +bool IMAPSession::handleConnection(Session_Config *session_config, IMAP_Data *imap_data, bool &ssl) +{ + + _session_cfg = session_config; + + if (!client.isInitialized()) + return MailClient.handleIMAPError(this, TCP_CLIENT_ERROR_NOT_INITIALIZED, false); + + // Resources are also released if network disconnected. + if (!MailClient.reconnect(this)) + return false; + + // Need to close previous connection first to free resources. + MailClient.closeTCPSession(this); + + _session_cfg = session_config; + _imap_data = imap_data; + + MailClient.setCert(_session_cfg, _session_cfg->certificate.cert_data); + + ssl = false; + if (!connect(ssl)) + { + MailClient.closeTCPSession(this); + return false; + } + + return true; +} + +bool IMAPSession::connect(bool &ssl) +{ + ssl = false; + MB_String buf; + + if (_imap_data) + { + if (_imap_data->fetch.sequence_set.string.length() > 0 || _imap_data->fetch.uid.length() > 0 || _imap_data->fetch.number.length() > 0) + _headerOnly = false; + else + _headerOnly = true; + } + + _totalRead = 0; + _secure = true; + bool secureMode = true; + + client.txBufDivider = 16; // minimum, tx buffer size for ssl data and request command data + client.rxBufDivider = 1; + if (_imap_data) + { + if (!_headerOnly && !_imap_data->firmware_update.attach_filename.length() == 0 && !_imap_data->enable.html && !_imap_data->enable.text && !_imap_data->download.attachment && !_imap_data->download.inlineImg && !_imap_data->download.html && !_imap_data->download.text) + client.rxBufDivider = 16; // minimum rx buffer size for only message header + } + + MailClient.preparePortFunction(_session_cfg, false, _secure, secureMode, ssl); + +#if !defined(SILENT_MODE) + MailClient.printLibInfo(this); +#endif + + MailClient.prepareTime(_session_cfg, this); + + MailClient.setSecure(client, _session_cfg); + + if (!MailClient.beginConnection(_session_cfg, this, secureMode)) + return false; + + // server connected + + client.setTimeout(tcpTimeout); + + // wait for greeting + unsigned long dataMs = millis(); + while (client.connected() && client.available() == 0 && millis() - dataMs < 2000) + { + yield_impl(); + } + + int chunkBufSize = client.available(); + + if (chunkBufSize > 0) + { + char *buf = MailClient.allocMem(chunkBufSize + 1); + client.readBytes(buf, chunkBufSize); + if (_debug && _debugLevel > esp_mail_debug_level_basic && !_customCmdResCallback) + esp_mail_debug_print((const char *)buf, true); + + if (_customCmdResCallback) + { + MailClient.imapResponseStatus(this, buf, esp_mail_str_3 /* "*" */); + _responseStatus.text = buf; + + if (_responseStatus.text[_responseStatus.text.length() - 2] == '\r' && _responseStatus.text[_responseStatus.text.length() - 1] == '\n') + _responseStatus.text[_responseStatus.text.length() - 2] = 0; + + if (_responseStatus.tag.length() == 0) + this->_responseStatus.tag = esp_mail_imap_tag_str; + + _customCmdResCallback(_responseStatus); + } + + // release memory + MailClient.freeMem(&buf); + } + + if (!_customCmdResCallback) + { +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_48 /* "IMAP server connected" */, + esp_mail_dbg_str_33 /* "IMAP server connected" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + } + + return true; +} + +void IMAPSession::debug(int level) +{ + if (level > esp_mail_debug_level_none) + { + if (level > esp_mail_debug_level_basic && level < esp_mail_debug_level_maintainer) + level = esp_mail_debug_level_basic; + _debugLevel = level; + _debug = true; + client.setDebugLevel(level); + } + else + { + _debugLevel = esp_mail_debug_level_none; + _debug = false; + client.setDebugLevel(0); + } +} + +String IMAPSession::errorReason() +{ + return MailClient.errorReason(false, _responseStatus.errorCode, _responseStatus.text.c_str()); +} + +int IMAPSession::errorCode() +{ + return _responseStatus.errorCode; +} + +bool IMAPSession::mSelectFolder(MB_StringPtr folderName, bool readOnly) +{ + if (connected()) + { + if (!openFolder(folderName, readOnly)) + return false; + } + else + { + _currentFolder = folderName; + } + + if (!connected()) + { + _responseStatus.errorCode = IMAP_STATUS_OPEN_MAILBOX_FAILED; + _responseStatus.clear(); + } + + return connected(); +} + +void IMAPSession::setTCPTimeout(unsigned long timeoutSec) +{ + tcpTimeout = timeoutSec; +} + +void IMAPSession::setClient(Client *client) +{ + this->client.setClient(client); +} + +void IMAPSession::setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password) +{ + this->client.setGSMClient(client, modem, pin, apn, user, password); +} + +void IMAPSession::networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB) +{ + this->client.networkConnectionRequestCallback(networkConnectionCB); +} + +void IMAPSession::networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB) +{ + this->client.networkStatusRequestCallback(networkStatusCB); +} + +void IMAPSession::setNetworkStatus(bool status) +{ + this->client.setNetworkStatus(status); + MailClient.networkStatus = status; +} + +void IMAPSession::setSSLBufferSize(int rx, int tx) +{ + this->client.setIOBufferSize(rx, tx); +} + +bool IMAPSession::mOpenFolder(MB_StringPtr folderName, bool readOnly) +{ + if (!connected()) + { + _responseStatus.errorCode = IMAP_STATUS_OPEN_MAILBOX_FAILED; + _responseStatus.clear(); + return false; + } + + if (readOnly) + return openMailbox(folderName, esp_mail_imap_auth_mode::esp_mail_imap_mode_examine, true, false); + else + return openMailbox(folderName, esp_mail_imap_auth_mode::esp_mail_imap_mode_select, true, false); +} + +bool IMAPSession::getFolders(FoldersCollection &folders) +{ + if (!connected()) + return false; + return getMailboxes(folders); +} + +bool IMAPSession::mCloseFolder(bool expunge) +{ + + // no folder opened + if (_currentFolder.length() == 0) + { +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_error_imap_str_11 /* "no mailbox opened" */, + esp_mail_error_imap_str_11 /* "no mailbox opened" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + return false; + } + + return closeMailbox(expunge); +} + +bool IMAPSession::mListen(bool recon) +{ + if (!MailClient.sessionExisted(this)) + return false; + + if (_currentFolder.length() == 0) + { + _mbif._floderChangedState = false; + _mbif._folderChanged = false; + return false; + } + + if (!MailClient.reconnect(this)) + return false; + + if (!connected()) + { + if (!_imap_data || (millis() - _last_server_connect_ms < 2000 && _last_server_connect_ms > 0)) + return false; + + _last_server_connect_ms = millis(); + + bool ssl = false; + + if (!connect(ssl)) + { + MailClient.closeTCPSession(this); + return false; + } + + // re-authenticate after session closed + if (!MailClient.imapAuth(this, ssl)) + { + MailClient.closeTCPSession(this); + return false; + } + + // re-open folder + if (!selectFolder(_currentFolder.c_str())) + return false; + } + + // no IDLE was not supported (should be checked after imapAuth) + if (!_feature_capability[esp_mail_imap_read_capability_idle]) + { +#if !defined(SILENT_MODE) + printDebugNotSupported(); +#endif + } + + if (_mbif._idleTimeMs == 0) + { + _mbif._polling_status.messageNum = 0; + _mbif._polling_status.type = imap_polling_status_type_undefined; + _mbif._polling_status.argument.clear(); + _mbif._recentCount = 0; + _mbif._folderChanged = false; + +#if !defined(SILENT_MODE) + MB_String dbMsg; + + if (!recon) + { + + dbMsg = esp_mail_dbg_str_51; /* "listening to " */ + dbMsg += _currentFolder; + dbMsg += esp_mail_dbg_str_52; /* " folder changes" */ + MailClient.printDebug(this, + esp_mail_cb_str_29 /* "Listening to mailbox changes..." */, + dbMsg.c_str(), + esp_mail_debug_tag_type_client, + true, + false); + } + +#endif + + if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_idle].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_idle; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + +#if !defined(SILENT_MODE) + if (!recon) + { + + dbMsg = esp_mail_str_88 /* "polling established on " */; + dbMsg += MailClient.Time.getDateTimeString(MailClient.Time.getCurrentTimestamp(), "%B %d, %Y %H:%M:%S"); + MailClient.printDebug(this, + esp_mail_cb_str_49 /* "Polling established" */, + dbMsg.c_str(), + esp_mail_debug_tag_type_client, + true, + false); + } + +#endif + + _mbif._idleTimeMs = millis(); + } + else + { + if (_mbif._floderChangedState) + { + _mbif._floderChangedState = false; + _mbif._folderChanged = false; + _mbif._polling_status.messageNum = 0; + _mbif._polling_status.type = imap_polling_status_type_undefined; + _mbif._polling_status.argument.clear(); + _mbif._recentCount = 0; + } + + size_t imap_idle_tmo = _imap_data->limit.imap_idle_timeout; + + if (imap_idle_tmo < 60 * 1000 || imap_idle_tmo > 29 * 60 * 1000) + imap_idle_tmo = 10 * 60 * 1000; + + size_t host_check_interval = _imap_data->limit.imap_idle_host_check_interval; + + if (host_check_interval < 30 * 1000 || host_check_interval > imap_idle_tmo) + host_check_interval = 60 * 1000; + + if (millis() - _last_host_check_ms > host_check_interval && connected()) + { + _last_host_check_ms = millis(); + + IPAddress ip; + + if (client.hostByName(_session_cfg->server.host_name.c_str(), ip) != 1) + { + closeSession(); + _mbif._idleTimeMs = millis(); + return false; + } + } + + return MailClient.parseIdleResponse(this); + } + + return true; +} + +bool IMAPSession::mStopListen(bool recon) +{ + _mbif._idleTimeMs = 0; + _mbif._floderChangedState = false; + _mbif._folderChanged = false; + _mbif._polling_status.messageNum = 0; + _mbif._polling_status.type = imap_polling_status_type_undefined; + _mbif._polling_status.argument.clear(); + _mbif._recentCount = 0; + + if (!connected() || _currentFolder.length() == 0 || !_feature_capability[esp_mail_imap_read_capability_idle]) + return false; + + if (MailClient.imapSend(this, imap_commands[esp_mail_imap_command_done].text, true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_done; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + +#if !defined(SILENT_MODE) + if (!recon) + { + MailClient.printDebug(this, + esp_mail_cb_str_50 /* "Mailbox listening stopped" */, + esp_mail_dbg_str_54 /* "Mailbox listening stopped" */, + esp_mail_debug_tag_type_client, + true, + false); + } +#endif + + return true; +} + +bool IMAPSession::folderChanged() +{ + return _mbif._floderChangedState; +} + +bool IMAPSession::noop() +{ + +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_62 /* "Sending noop..." */, + esp_mail_dbg_str_83 /* "send IMAP command, NOOP" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_noop].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_noop; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + return true; +} + +void IMAPSession::checkUID() +{ + if (MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_uid].text) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_flags].text) || + MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_body].text) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_peek].text) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_text].text) || + MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_header].text) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_fields].text) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, esp_mail_str_40 /* "[" */) || + MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, esp_mail_str_41 /* "]" */) || MailClient.strcmpP(_imap_data->fetch.uid.c_str(), 0, imap_commands[esp_mail_imap_command_mime].text)) + _imap_data->fetch.uid = esp_mail_str_3; /* "*" */ +} + +void IMAPSession::checkPath() +{ + MB_String path = _imap_data->storage.saved_path; + if (path[0] != '/') + { + path = '/'; + path += _imap_data->storage.saved_path; + path = path.c_str(); + } +} + +bool IMAPSession::headerOnly() +{ + return _headerOnly; +} + +struct esp_mail_imap_msg_list_t IMAPSession::data() +{ + struct esp_mail_imap_msg_list_t ret; + + for (size_t i = 0; i < _headers.size(); i++) + { + +#if defined(MB_ARDUINO_ESP) || defined(MB_ARDUINO_PICO) + if (MailClient.getFreeHeap() < ESP_MAIL_MIN_MEM) + continue; +#endif + struct esp_mail_imap_msg_item_t itm; + itm.setRFC822Headers(&_headers[i].header_fields); + itm.UID = _headers[i].message_uid; + itm.msgNo = _headers[i].message_no; + itm.flags = _headers[i].flags.c_str(); + itm.acceptLang = _headers[i].accept_language.c_str(); + itm.contentLang = _headers[i].content_language.c_str(); + itm.hasAttachment = _headers[i].hasAttachment; + itm.fetchError = _headers[i].error_msg.c_str(); + + getMessages(i, itm); + + getRFC822Messages(i, itm); + + ret.msgItems.push_back(itm); + } + + return ret; +} + +SelectedFolderInfo IMAPSession::selectedFolder() +{ + return _mbif; +} + +void IMAPSession::callback(imapStatusCallback imapCallback) +{ + _statusCallback = imapCallback; +} + +void IMAPSession::characterDecodingCallback(imapCharacterDecodingCallback callback) +{ + _charDecCallback = callback; +} + +void IMAPSession::mimeDataStreamCallback(MIMEDataStreamCallback mimeDataStreamCallback) +{ + _mimeDataStreamCallback = mimeDataStreamCallback; +} + +void IMAPSession::setSystemTime(time_t ts, float gmtOffset) +{ + MailClient.Time.setTimestamp(ts, gmtOffset); +} + +void IMAPSession::keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount) +{ + this->client.keepAlive(tcpKeepIdleSeconds, tcpKeepIntervalSeconds, tcpKeepCount); +} + +bool IMAPSession::isKeepAlive() +{ + return this->client.isKeepAlive(); +} + +void IMAPSession::getMessages(uint16_t messageIndex, struct esp_mail_imap_msg_item_t &msg) +{ + msg.text.content = ""; + msg.text.charSet = ""; + msg.text.content_type = ""; + msg.text.transfer_encoding = ""; + msg.html.content = ""; + msg.html.charSet = ""; + msg.html.content_type = ""; + msg.html.transfer_encoding = ""; + + if (messageIndex < _headers.size()) + { + int sz = _headers[messageIndex].part_headers.size(); + if (sz > 0) + { + for (int i = 0; i < sz; i++) + { + if (_headers[messageIndex].part_headers[i].attach_type == esp_mail_att_type_attachment || (!_headers[messageIndex].part_headers[i].rfc822_part && _headers[messageIndex].part_headers[i].message_sub_type != esp_mail_imap_message_sub_type_rfc822)) + { + if (_headers[messageIndex].part_headers[i].attach_type == esp_mail_att_type_none) + { + if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_plain || _headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_enriched) + { + msg.text.content = _headers[messageIndex].part_headers[i].text.c_str(); + msg.text.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); + msg.text.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); + msg.text.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); + } + + if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_html) + { + msg.html.content = _headers[messageIndex].part_headers[i].text.c_str(); + msg.html.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); + msg.html.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); + msg.html.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); + } + } + else + { + struct esp_mail_attachment_info_t att; + att.filename = _headers[messageIndex].part_headers[i].filename.c_str(); + att.mime = _headers[messageIndex].part_headers[i].content_type.c_str(); + att.name = _headers[messageIndex].part_headers[i].name.c_str(); + att.size = _headers[messageIndex].part_headers[i].attach_data_size; + att.description = _headers[messageIndex].part_headers[i].content_description.c_str(); + att.creationDate = _headers[messageIndex].part_headers[i].creation_date.c_str(); + att.type = _headers[messageIndex].part_headers[i].attach_type; + msg.attachments.push_back(att); + } + } + } + } + } +} + +void IMAPSession::getRFC822Messages(uint16_t messageIndex, struct esp_mail_imap_msg_item_t &msg) +{ + if (messageIndex < _headers.size()) + { + int size = _headers[messageIndex].part_headers.size(); + int partIdx = 0; + int cIdx = 0; + IMAP_MSG_Item *_rfc822 = nullptr; + if (size > 0) + { + for (int i = 0; i < size; i++) + { + if (_headers[messageIndex].part_headers[i].message_sub_type == esp_mail_imap_message_sub_type_rfc822 && _headers[messageIndex].part_headers[i].attach_type != esp_mail_att_type_attachment) + { + if (_headers[messageIndex].part_headers[i].rfc822_part) + { + if (partIdx > 0) + msg.rfc822.push_back(*_rfc822); + cIdx = i; + partIdx++; + _rfc822 = new IMAP_MSG_Item(); + _rfc822->setRFC822Headers(&_headers[messageIndex].part_headers[i].rfc822_header); + } + else + { + if (MailClient.multipartMember(_headers[messageIndex].part_headers[cIdx].partNumStr, _headers[messageIndex].part_headers[i].partNumStr)) + { + if (_headers[messageIndex].part_headers[i].attach_type == esp_mail_att_type_none) + { + if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_plain || _headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_enriched) + { + _rfc822->text.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); + _rfc822->text.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); + _rfc822->text.content = _headers[messageIndex].part_headers[i].text.c_str(); + _rfc822->text.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); + } + if (_headers[messageIndex].part_headers[i].msg_type == esp_mail_msg_type_html) + { + _rfc822->html.charSet = _headers[messageIndex].part_headers[i].charset.c_str(); + _rfc822->html.content_type = _headers[messageIndex].part_headers[i].content_type.c_str(); + _rfc822->html.content = _headers[messageIndex].part_headers[i].text.c_str(); + _rfc822->html.transfer_encoding = _headers[messageIndex].part_headers[i].content_transfer_encoding.c_str(); + } + } + else + { + struct esp_mail_attachment_info_t att; + att.filename = _headers[messageIndex].part_headers[i].filename.c_str(); + att.mime = _headers[messageIndex].part_headers[i].content_type.c_str(); + att.name = _headers[messageIndex].part_headers[i].name.c_str(); + att.size = _headers[messageIndex].part_headers[i].attach_data_size; + att.description = _headers[messageIndex].part_headers[i].content_description.c_str(); + att.creationDate = _headers[messageIndex].part_headers[i].creation_date.c_str(); + att.type = _headers[messageIndex].part_headers[i].attach_type; + _rfc822->attachments.push_back(att); + } + } + } + } + } + + if ((int)msg.rfc822.size() < partIdx && _rfc822 != nullptr) + msg.rfc822.push_back(*_rfc822); + } + } +} + +bool IMAPSession::closeMailbox(bool expunge) +{ +#if !defined(SILENT_MODE) + MB_String dbMsg = esp_mail_dbg_str_32; /* "closing the " */ + dbMsg += _currentFolder; + dbMsg += esp_mail_str_89; /* " folder..." */ + + MailClient.printDebug(this, + esp_mail_cb_str_27 /* "Closing the mailbox folder..." */, + dbMsg.c_str(), + esp_mail_debug_tag_type_client, + true, + false); +#endif + if (!MailClient.reconnect(this)) + return false; + + // If folder was opened in readonly mode, use CLOSE command will not expunge the deleted messages + // Or user intent to expunge the deleted message after close the folder. + if (expunge || _readOnlyMode) + { + + if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_close].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_close; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_CLOSE_MAILBOX_FAILED, false)) + return false; + } + else + { + // Close folder without expunge + if (_feature_capability[esp_mail_imap_read_capability_unselect]) + { + if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_unselect].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_unselect; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_CLOSE_MAILBOX_FAILED, false)) + return false; + } + else + { + // Open non-existing folder + MB_String folder = esp_mail_str_84 /* "message" */; + folder += MailClient.Time.getCurrentTimestamp(); + MB_StringPtr folderPtr; + folderPtr = toStringPtr(folder); + openMailbox(folderPtr, esp_mail_imap_auth_mode::esp_mail_imap_mode_examine, true, true); + } + } + + _currentFolder.clear(); + _mailboxOpened = false; + + return true; +} + +bool IMAPSession::openMailbox(MB_StringPtr folder, esp_mail_imap_auth_mode mode, bool waitResponse, bool unselect) +{ + + if (!MailClient.sessionExisted(this)) + return false; + + MB_String _folder = folder; + + if (!MailClient.reconnect(this)) + return false; + + if (_folder.length() == 0) + return false; + + bool _dbg = _debug; + imapStatusCallback _cb = _statusCallback; + + // The SELECT/EXAMINE command automatically deselects any currently selected mailbox + // before attempting the new selection (RFC3501 p.33) + + // folder should not close for re-selection otherwise the server returned * BAD Command Argument Error. 12 + + if (!unselect) + { + + bool sameFolder = strcmp(_currentFolder.c_str(), _folder.c_str()) == 0; + + // guards 3 seconds to prevent accidently frequently select the same folder with the same mode + if (!_mailboxOpened && sameFolder && millis() - _lastSameFolderOpenMillis < 3000) + { + if ((_readOnlyMode && mode == esp_mail_imap_mode_examine) || (!_readOnlyMode && mode == esp_mail_imap_mode_select)) + return true; + } + + if (!sameFolder) + _currentFolder = folder; + +#if !defined(SILENT_MODE) + MB_String dbMsg = esp_mail_dbg_str_68; /* "selecting the " */ + dbMsg += _currentFolder; + dbMsg += esp_mail_str_89; /* " folder..." */ + + MailClient.printDebug(this, + esp_mail_cb_str_51 /* "Open the mailbox folder..." */, + dbMsg.c_str(), + esp_mail_debug_tag_type_client, + true, + false); +#endif + } + else + { + // Hide the callback and debug info + _debug = false; + _statusCallback = NULL; + _currentFolder = folder; + } + + MB_String cmd; + MailClient.appendSpace(cmd, true, mode == esp_mail_imap_mode_examine ? imap_commands[esp_mail_imap_command_examine].text : imap_commands[esp_mail_imap_command_select].text); + MailClient.appendString(cmd, _currentFolder.c_str(), false, false, esp_mail_string_mark_type_double_quote); + + if (isCondStoreSupported()) + { + MailClient.appendSpace(cmd); + MailClient.appendString(cmd, imap_commands[esp_mail_imap_command_condstore].text, false, false, esp_mail_string_mark_type_round_bracket); + } + + _imap_cmd = mode == esp_mail_imap_mode_examine ? esp_mail_imap_cmd_examine : esp_mail_imap_cmd_select; + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + if (!unselect) + _lastSameFolderOpenMillis = millis(); + + if (waitResponse && !MailClient.handleIMAPResponse(this, IMAP_STATUS_OPEN_MAILBOX_FAILED, false)) + { + if (!unselect) + return false; + } + + if (unselect) + { + _statusCallback = _cb; + _debug = _dbg; + } + + if (mode == esp_mail_imap_mode_examine) + _readOnlyMode = true; + else if (mode == esp_mail_imap_mode_select) + _readOnlyMode = false; + + _mailboxOpened = !unselect; + + return true; +} + +bool IMAPSession::getMailboxes(FoldersCollection &folders) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_16 /* "Reading the list of mailboxes..." */, + esp_mail_dbg_str_35 /* "send IMAP command, LIST" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + _folders.clear(); + + MB_String cmd; + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_list].text); + MailClient.appendString(cmd, NULL, false, false, esp_mail_string_mark_type_double_quote); + MailClient.prependSpace(cmd, esp_mail_str_3 /* "*" */); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_list; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) + return false; + + folders = _folders; + return true; +} + +bool IMAPSession::mGetSubscribesMailboxes(MB_StringPtr reference, MB_StringPtr mailbox, FoldersCollection &folders) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_30 /* "Listing the subscribed mailboxes..." */, + esp_mail_dbg_str_56 /* "send IMAP command, LSUB" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + folders.clear(); + + MB_String cmd; + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_lsub].text); + MailClient.appendString(cmd, MB_String(reference).c_str(), false, false, esp_mail_string_mark_type_double_quote); + MailClient.appendSpace(cmd); + MailClient.appendString(cmd, MB_String(mailbox).c_str(), false, false, esp_mail_string_mark_type_double_quote); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + FoldersCollection tmp; + + for (size_t i = 0; i < this->_folders.size(); i++) + tmp.add(this->_folders[i]); + + this->_folders.clear(); + + _imap_cmd = esp_mail_imap_cmd_lsub; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) + return false; + + for (size_t i = 0; i < this->_folders.size(); i++) + folders.add(this->_folders[i]); + + this->_folders.clear(); + + for (size_t i = 0; i < tmp.size(); i++) + this->_folders.add(tmp[i]); + + tmp.clear(); + + return true; +} + +bool IMAPSession::mSubscribe(MB_StringPtr folder) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_31 /* "Subscribe mailbox..." */, + esp_mail_dbg_str_57 /* "send IMAP command, SUBSCRIBE" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + MB_String cmd; + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_subscribe].text); + MailClient.appendString(cmd, MB_String(folder).c_str(), false, false, esp_mail_string_mark_type_double_quote); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_subscribe; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) + return false; + + return true; +} + +bool IMAPSession::mUnSubscribe(MB_StringPtr folder) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_32 /* "Unsubscribe mailbox..." */, + esp_mail_dbg_str_58 /* "send IMAP command, UNSUBSCRIBE" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + MB_String cmd; + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_unsubscribe].text); + MailClient.appendString(cmd, MB_String(folder).c_str(), false, false, esp_mail_string_mark_type_double_quote); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_unsubscribe; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) + return false; + + return true; +} + +bool IMAPSession::mFetchSequenceSet() +{ + + MB_String cmd; + if (_imap_data->fetch.sequence_set.UID) + MailClient.appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_fetch].text); + else + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_fetch].text); + + MailClient.appendSpace(cmd, false, _imap_data->fetch.sequence_set.string.c_str()); + MailClient.appendString(cmd, imap_commands[esp_mail_imap_command_uid].text, false, false, esp_mail_string_mark_type_round_bracket); + + addModifier(cmd, esp_mail_imap_command_changedsince, _imap_data->fetch.modsequence); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_msg_num.clear(); + + _imap_cmd = esp_mail_imap_cmd_fetch_sequence_set; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_LIST_MAILBOXS_FAILED, false)) + return false; + + return true; +} + +MB_String IMAPSession::prependTag(PGM_P cmd, PGM_P tag) +{ + MB_String s = (tag == NULL) ? esp_mail_imap_tag_str : tag; + MailClient.appendSpace(s); + s += cmd; + return s; +} + +bool IMAPSession::checkCapabilities() +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_52 /* "Checking the capability..." */, + esp_mail_dbg_str_76 /* "check the capability" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_capability].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_capability; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_CHECK_CAPABILITIES_FAILED, false)) + return false; + + return true; +} + +bool IMAPSession::mCreateFolder(MB_StringPtr folderName) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_59 /* "Creating folder..." */, + esp_mail_dbg_str_49 /* "creating folder" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + MB_String cmd; + MailClient.joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_create].text, folderName); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_create; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + return true; +} + +bool IMAPSession::mRenameFolder(MB_StringPtr currentFolderName, MB_StringPtr newFolderName) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_53 /* "Renaming folder..." */, + esp_mail_dbg_str_55 /* "renaming folder" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + MB_String o = currentFolderName; + MB_String n = newFolderName; + + o.trim(); + n.trim(); + + if (o == n) + return true; + + if (o.length() == 0 || n.length() == 0) + return false; + + MB_String cmd; + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_rename].text); + MailClient.appendString(cmd, o.c_str(), false, false, esp_mail_string_mark_type_double_quote); + MailClient.appendSpace(cmd); + MailClient.appendString(cmd, n.c_str(), false, false, esp_mail_string_mark_type_double_quote); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_rename; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + if (_currentFolder == o) + selectFolder(n.c_str(), false); + + return true; +} + +int IMAPSession::getUID(int msgNum) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_25 /* "Get UID..." */, + esp_mail_dbg_str_79 /* "get UID" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + int uid = mGetUID(msgNum); + + if (!MailClient.sessionExisted(this)) + return false; + +#if !defined(SILENT_MODE) + MB_String dbMsg = esp_mail_cb_str_54; /* "UID is " */ + dbMsg += uid; + + MailClient.printDebug(this, + dbMsg.c_str(), + dbMsg.c_str(), + esp_mail_debug_tag_type_client, + true, + false); +#endif + return uid; +} + +int IMAPSession::mGetUID(int msgNum) +{ + + if (_currentFolder.length() == 0) + return 0; + + MB_String cmd; + MailClient.joinStringSpace(cmd, true, 3, imap_commands[esp_mail_imap_command_fetch].text, MB_String(msgNum).c_str(), imap_commands[esp_mail_imap_command_uid].text); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return 0; + + _imap_cmd = esp_mail_imap_cmd_get_uid; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return 0; + + return _uid_tmp; +} + +const char *IMAPSession::getFlags(int msgNum) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_55 /* "Get Flags..." */, + esp_mail_dbg_str_80 /* "get flags" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + _flags_tmp.clear(); + if (_currentFolder.length() == 0) + return _flags_tmp.c_str(); + + MB_String cmd, cmd2; + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_fetch].text); + MailClient.appendString(cmd2, imap_commands[esp_mail_imap_command_flags].text, false, false, esp_mail_string_mark_type_round_bracket); + MailClient.joinStringSpace(cmd, false, 2, MB_String(msgNum).c_str(), cmd2.c_str()); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return _flags_tmp.c_str(); + + _imap_cmd = esp_mail_imap_cmd_get_flags; + MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false); + + return _flags_tmp.c_str(); +} + +bool IMAPSession::mSendCustomCommand(MB_StringPtr cmd, imapResponseCallback callback, MB_StringPtr tag) +{ + + _customCmdResCallback = callback; + _cmd = cmd; + _cmd.trim(); + + MB_String _tag = cmd; + _tag.trim(); + + MB_String _tag2 = tag; + _tag2.trim(); + + if (_tag2.length() == 0) + { + int p = MailClient.strpos(_tag.c_str(), " ", 0); + if (p > -1) + { + _tag.erase(p, _tag.length() - p); + _tag.trim(); + _responseStatus.tag = _tag; + } + } + else + { + _responseStatus.tag = tag; + _responseStatus.tag.trim(); + if (MailClient.strpos(_cmd.c_str(), _responseStatus.tag.c_str(), 0, false) == -1) + _cmd = prependTag(_cmd.c_str(), _responseStatus.tag.c_str()); + } + + // filter for specific command + if (_cmd.find(imap_cmd_pre_tokens[esp_mail_imap_command_idle].c_str()) != MB_String::npos) + _imap_custom_cmd = esp_mail_imap_cmd_idle; + else if (_cmd.find(imap_cmd_pre_tokens[esp_mail_imap_command_append].c_str()) != MB_String::npos) + _imap_custom_cmd = esp_mail_imap_cmd_append; + else if (_cmd.find(imap_cmd_pre_tokens[esp_mail_imap_command_login].c_str()) != MB_String::npos) + _imap_custom_cmd = esp_mail_imap_cmd_sasl_login; + else if (_cmd.find(imap_cmd_pre_tokens[esp_mail_imap_command_logout].c_str()) != MB_String::npos) + _imap_custom_cmd = esp_mail_imap_cmd_logout; + else + _imap_custom_cmd = esp_mail_imap_cmd_custom; + + if (_prev_imap_custom_cmd != _imap_custom_cmd || _imap_custom_cmd != esp_mail_imap_cmd_idle) + { + if (MailClient.imapSend(this, _cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + { + _prev_imap_custom_cmd = esp_mail_imap_cmd_custom; + return false; + } + } + + _imap_cmd = esp_mail_imap_cmd_custom; + + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + { + _prev_imap_custom_cmd = esp_mail_imap_cmd_custom; + return false; + } + + if (_imap_custom_cmd == esp_mail_imap_cmd_sasl_login) + { + _authenticated = true; + _loginStatus = true; + } + else if (_imap_custom_cmd == esp_mail_imap_cmd_logout) + { + _authenticated = false; + _loginStatus = false; + } + + _prev_imap_custom_cmd = _imap_custom_cmd; + + if (MailClient.strposP(_cmd.c_str(), imap_auth_capabilities[esp_mail_auth_capability_starttls].text, 0, false) == 0) + { + bool verify = false; + + if (_session_cfg) + verify = _session_cfg->certificate.verify; + + if (!client.connectSSL(verify)) + return false; + + // set the secure mode + if (_session_cfg) + { + // We reset the prefer connection mode in case user set it. + _session_cfg->secure.startTLS = false; + _session_cfg->secure.mode = esp_mail_secure_mode_undefined; + } + + _secure = true; + } + + return true; +} + +bool IMAPSession::mSendData(MB_StringPtr data, bool lastData, esp_mail_imap_command cmd) +{ + MB_String _data = data; + if (MailClient.imapSend(this, _data.c_str(), lastData) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + if (lastData) + { + _imap_cmd = cmd; + _cmd.clear(); + + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + } + + return true; +} + +bool IMAPSession::mSendData(uint8_t *data, size_t size, bool lastData, esp_mail_imap_command cmd) +{ + + if (MailClient.imapSend(this, data, size) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + if (lastData) + { + if (MailClient.imapSend(this, pgm2Str(esp_mail_str_42 /* "\r\n" */), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = cmd; + _cmd.clear(); + + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + } + + return true; +} + +bool IMAPSession::mDeleteFolder(MB_StringPtr folderName) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_56 /* "Deleting folder..." */, + esp_mail_dbg_str_81 /* "delete folder" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + MB_String cmd; + MailClient.joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_delete].text, MB_String(folderName).c_str()); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_delete; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + return true; +} + +bool IMAPSession::isCondStoreSupported() +{ + return _feature_capability[esp_mail_imap_read_capability_condstore]; +} + +bool IMAPSession::isModseqSupported() +{ + return isCondStoreSupported() && !_mbif._nomodsec; +} + +void IMAPSession::addModifier(MB_String &cmd, esp_mail_imap_command_types type, int32_t modsequence) +{ + if (modsequence > -1 && isModseqSupported()) + { + MB_String modifier; + MailClient.joinStringSpace(modifier, false, 2, imap_commands[type].text, MB_String(modsequence).c_str()); + MailClient.appendSpace(cmd); + MailClient.appendString(cmd, modifier.c_str(), false, false, esp_mail_string_mark_type_round_bracket); + } +} + +bool IMAPSession::deleteMsg(MessageList *toDelete, const char *sequenceSet, bool UID, bool expunge, int32_t modsequence) +{ + if ((toDelete && toDelete->_list.size() == 0) || (!toDelete && strlen(sequenceSet) == 0)) + return false; + + if (!selectFolder(_currentFolder.c_str(), false)) + return false; + +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_57 /* "Deleting message(s)..." */, + esp_mail_dbg_str_75 /* "delete message(s)" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (!MailClient.sessionExisted(this)) + return false; + + MB_String cmd; + if (UID || toDelete) + { + MailClient.appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_store].text); + + if (toDelete && toDelete->_list.size() > 0) + MailClient.appendList(cmd, toDelete->_list); + } + else if (!toDelete && strlen(sequenceSet) > 0) + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_store].text); + + if (!toDelete && strlen(sequenceSet) > 0) + cmd += sequenceSet; + + addModifier(cmd, esp_mail_imap_command_unchangedsince, modsequence); + + cmd += imap_cmd_pre_tokens[esp_mail_imap_command_plus_flags]; + MailClient.prependDot(cmd, imap_commands[esp_mail_imap_command_silent].text); + MailClient.appendSpace(cmd); + MailClient.appendString(cmd, esp_mail_str_91 /* "\\Deleted" */, false, false, esp_mail_string_mark_type_round_bracket); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_store; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + if (expunge) + { + if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_expunge].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_expunge; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + } + + return true; +} + +bool IMAPSession::mDeleteMessages(MessageList *toDelete, bool expunge, int32_t modsequence) +{ + if (toDelete->_list.size() > 0) + return deleteMsg(toDelete, "", false, expunge); + return true; +} + +bool IMAPSession::mDeleteMessagesSet(MB_StringPtr sequenceSet, bool UID, bool expunge, int32_t modsequence) +{ + return deleteMsg(nullptr, MB_String(sequenceSet).c_str(), UID, expunge); +} + +bool IMAPSession::copyMsg(MessageList *toCopy, const char *sequenceSet, bool UID, MB_StringPtr dest) +{ +#if !defined(SILENT_MODE) + MB_String dbMsg = esp_mail_dbg_str_48; /* "copying message(s) to " */ + dbMsg += dest; + + MailClient.printDebug(this, + esp_mail_cb_str_58 /* "Copying message(s)..." */, + dbMsg.c_str(), + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (!MailClient.sessionExisted(this)) + return false; + + if ((toCopy && toCopy->_list.size() == 0) || (!toCopy && strlen(sequenceSet) == 0)) + return false; + + if (!selectFolder(_currentFolder.c_str(), false)) + return false; + + MB_String cmd; + if (UID || toCopy) + { + MailClient.appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_copy].text); + + if (toCopy && toCopy->_list.size() > 0) + MailClient.appendList(cmd, toCopy->_list); + } + else if (!toCopy && strlen(sequenceSet) > 0) + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_copy].text); + + if (!toCopy && strlen(sequenceSet) > 0) + cmd += sequenceSet; + + MailClient.prependSpace(cmd, MB_String(dest).c_str()); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_copy; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + return true; +} + +bool IMAPSession::mCopyMessages(MessageList *toCopy, MB_StringPtr dest) +{ + return copyMsg(toCopy, "", false, dest); +} + +bool IMAPSession::mCopyMessagesSet(MB_StringPtr sequenceSet, bool UID, MB_StringPtr dest) +{ + return copyMsg(nullptr, MB_String(sequenceSet).c_str(), UID, dest); +} + +bool IMAPSession::moveMsg(MessageList *toMove, const char *sequenceSet, bool UID, MB_StringPtr dest) +{ +#if !defined(SILENT_MODE) + MB_String dbMsg = esp_mail_dbg_str_59; /* "moving message(s) to " */ + dbMsg += dest; + + MailClient.printDebug(this, + esp_mail_cb_str_60 /* "Moving message(s)..." */, + dbMsg.c_str(), + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (!MailClient.sessionExisted(this)) + return false; + + if ((toMove && toMove->_list.size() == 0) || (!toMove && strlen(sequenceSet) == 0)) + return false; + + if (!_feature_capability[esp_mail_imap_read_capability_move]) + { + + bool ret = mCopyMessages(toMove, dest); + + if (ret) + ret = mDeleteMessages(toMove, true); + + return ret; + } + + if (!selectFolder(_currentFolder.c_str(), false)) + return false; + + MB_String cmd; + if (UID || toMove) + { + MailClient.appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_uid].text, imap_commands[esp_mail_imap_command_move].text); + if (toMove && toMove->_list.size() > 0) + MailClient.appendList(cmd, toMove->_list); + } + else if (!toMove && strlen(sequenceSet) > 0) + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_move].text); + + if (!toMove && strlen(sequenceSet) > 0) + cmd += sequenceSet; + + MailClient.prependSpace(cmd, MB_String(dest).c_str()); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_move; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + return true; +} + +bool IMAPSession::mMoveMessages(MessageList *toMove, MB_StringPtr dest) +{ + return moveMsg(toMove, "", false, dest); +} + +bool IMAPSession::mMoveMessagesSet(MB_StringPtr sequenceSet, bool UID, MB_StringPtr dest) +{ + return moveMsg(nullptr, MB_String(sequenceSet).c_str(), UID, dest); +} + +bool IMAPSession::mGetSetQuota(MB_StringPtr quotaRoot, IMAP_Quota_Root_Info *data, bool getMode) +{ + +#if !defined(SILENT_MODE) + PGM_P p1 = getMode ? esp_mail_cb_str_33 /* "Get quota root resource usage and limit..." */ : esp_mail_cb_str_34 /* "Set quota root resource usage and limit..." */; + PGM_P p2 = getMode ? esp_mail_dbg_str_60 /* "send IMAP command, GETQUOTA" */ : esp_mail_dbg_str_61 /* "send IMAP command, SETQUOTA" */; + MailClient.printDebug(this, p1, p2, esp_mail_debug_tag_type_client, true, false); +#endif + + if (!_feature_capability[esp_mail_imap_read_capability_quota]) + { +#if !defined(SILENT_MODE) + printDebugNotSupported(); +#endif + return false; + } + + MB_String _quotaRoot = quotaRoot; + + MB_String cmd; + if (getMode) + { + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_getquota].text); + MailClient.appendString(cmd, _quotaRoot.c_str(), false, false, esp_mail_string_mark_type_double_quote); + } + else + { + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_setquota].text); + MailClient.appendString(cmd, _quotaRoot.c_str(), false, false, esp_mail_string_mark_type_double_quote); + MailClient.appendSpace(cmd); + + MB_String cmd2; + MailClient.joinStringSpace(cmd2, false, 2, data->name.c_str(), MB_String((int)data->limit).c_str()); + MailClient.appendString(cmd, cmd2.c_str(), false, false, esp_mail_string_mark_type_round_bracket); + } + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _quota_tmp.clear(); + + _imap_cmd = (getMode) ? esp_mail_imap_cmd_get_quota : esp_mail_imap_cmd_set_quota; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + if (getMode) + { + mParseQuota(_quota_tmp.c_str(), data); + } + + _quota_tmp.clear(); + + return true; +} + +void IMAPSession::mParseQuota(const char *quota, IMAP_Quota_Root_Info *data) +{ + _vectorImpl tokens; + MailClient.splitToken(quota, tokens, " "); + data->quota_root = tokens[0]; + tokens[1].erase(0, 1); + data->name = tokens[1]; + data->usage = atoi(tokens[2].c_str()); + data->limit = atoi(tokens[3].c_str()); +} + +bool IMAPSession::mGetQuotaRoots(MB_StringPtr mailbox, IMAP_Quota_Roots_List *quotaRootsList) +{ +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_35 /* "Get the list of quota roots..." */, + esp_mail_dbg_str_62 /* "send IMAP command, GETQUOTAROOT" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (!MailClient.sessionExisted(this)) + return false; + + if (!_feature_capability[esp_mail_imap_read_capability_quota]) + { +#if !defined(SILENT_MODE) + printDebugNotSupported(); +#endif + return false; + } + + MB_String _mailbox = mailbox; + + MB_String cmd; + MailClient.appendSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_getquota].text, imap_commands[esp_mail_imap_command_root].text); + MailClient.appendString(cmd, _mailbox.c_str(), false, false, esp_mail_string_mark_type_double_quote); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _quota_root_tmp.clear(); + _quota_tmp.clear(); + + _imap_cmd = esp_mail_imap_cmd_get_quota_root; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + _vectorImpl tokens; + MailClient.splitToken(_quota_root_tmp.c_str(), tokens, ","); + + for (size_t i = 0; i < tokens.size(); i++) + { + _vectorImpl tk; + MailClient.splitToken(tokens[i].c_str(), tk, ":"); + IMAP_Quota_Root_Info data; + if (tk.size() > 1) + mParseQuota(tk[1].c_str(), &data); + else + data.quota_root = tk[0]; + + quotaRootsList->add(data); + } + + _quota_root_tmp.clear(); + _quota_tmp.clear(); + + return true; +} + +bool IMAPSession::mManageACL(MB_StringPtr mailbox, IMAP_Rights_List *acl_list, IMAP_Rights_Info *acl, MB_StringPtr identifier, esp_mail_imap_command type) +{ + +#if !defined(SILENT_MODE) + + PGM_P p1 = NULL; + PGM_P p2 = NULL; + if (type == esp_mail_imap_cmd_get_acl) + { + p1 = esp_mail_cb_str_36; /* "Get the ACL..." */ + p2 = esp_mail_dbg_str_77; /* "get the ACL" */ + } + else if (type == esp_mail_imap_cmd_set_acl) + { + p1 = esp_mail_cb_str_37; /* "Setting the ACL..." */ + p2 = esp_mail_dbg_str_78; /* "set the ACL" */ + } + else if (type == esp_mail_imap_cmd_delete_acl) + { + p1 = esp_mail_cb_str_38; /* "Deleting the ACL..." */ + p2 = esp_mail_dbg_str_72; /* "delete the ACL" */ + } + else if (type == esp_mail_imap_cmd_my_rights) + { + p1 = esp_mail_cb_str_39; /* "Get my ACL..." */ + p2 = esp_mail_dbg_str_23; /* "get my ACL" */ + } + + MailClient.printDebug(this, p1, p2, esp_mail_debug_tag_type_client, true, false); + +#endif + + if (!MailClient.sessionExisted(this)) + return false; + + if (!_feature_capability[esp_mail_imap_read_capability_acl]) + { +#if !defined(SILENT_MODE) + printDebugNotSupported(); +#endif + return false; + } + + MB_String _mailbox = mailbox; + MB_String _identifier = identifier; + + MB_String cmd; + if (type == esp_mail_imap_cmd_get_acl) + { + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_get_acl].text); + MailClient.appendString(cmd, _mailbox.c_str(), false, false, esp_mail_string_mark_type_double_quote); + } + else if (type == esp_mail_imap_cmd_set_acl) + { + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_set_acl].text); + MailClient.appendString(cmd, MB_String(mailbox).c_str(), false, false, esp_mail_string_mark_type_double_quote); + MailClient.appendSpace(cmd); + MailClient.appendString(cmd, acl->identifier.c_str(), false, false, esp_mail_string_mark_type_double_quote); + MailClient.appendSpace(cmd); + MB_String rights; + getRights(rights, acl); + MailClient.appendString(cmd, rights.c_str(), false, false, esp_mail_string_mark_type_double_quote); + } + else if (type == esp_mail_imap_cmd_delete_acl) + { + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_delete_acl].text); + MailClient.appendString(cmd, _mailbox.c_str(), false, false, esp_mail_string_mark_type_double_quote); + MailClient.appendSpace(cmd); + MailClient.appendString(cmd, _identifier.c_str(), false, false, esp_mail_string_mark_type_double_quote); + } + else if (type == esp_mail_imap_cmd_my_rights) + { + MailClient.appendSpace(cmd, true, imap_commands[esp_mail_imap_command_myrights].text); + MailClient.appendString(cmd, _mailbox.c_str(), false, false, esp_mail_string_mark_type_double_quote); + } + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _acl_tmp.clear(); + + _imap_cmd = type; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + if (type == esp_mail_imap_cmd_get_acl) + parseACL(_acl_tmp, acl_list); + else if (type == esp_mail_imap_cmd_my_rights) + parseRights(_acl_tmp, acl); + + _acl_tmp.clear(); + + return true; +} + +void IMAPSession::parseACL(MB_String &acl_str, IMAP_Rights_List *right_list) +{ + _vectorImpl tokens; + MailClient.splitToken(acl_str.c_str(), tokens, " "); + + for (size_t i = 0; i < tokens.size(); i += 2) + { + IMAP_Rights_Info info; + info.identifier = tokens[i]; + parseRights(tokens[i + 1], &info); + right_list->add(info); + } +} + +void IMAPSession::parseRights(MB_String &righs_str, IMAP_Rights_Info *info) +{ + for (size_t i = 0; i < righs_str.length(); i++) + { + uint8_t c = righs_str[i] - 97; + if (c >= esp_mail_imap_rights_administer && c < esp_mail_imap_rights_maxType) + info->rights[c] = true; + } +} + +void IMAPSession::getRights(MB_String &righs_str, IMAP_Rights_Info *info) +{ + for (size_t i = esp_mail_imap_rights_administer; i < esp_mail_imap_rights_maxType; i++) + { + if (info->rights[i]) + righs_str += (char)(i + 97); + } +} + +bool IMAPSession::mNamespace(IMAP_Namespaces_List *ns) +{ + +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_40 /* "Get namespace..." */, + esp_mail_dbg_str_67 /* "send IMAP command, NAMESPACE" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (!MailClient.sessionExisted(this)) + return false; + + if (!_feature_capability[esp_mail_imap_read_capability_namespace]) + { +#if !defined(SILENT_MODE) + printDebugNotSupported(); +#endif + return false; + } + + if (MailClient.imapSend(this, prependTag(imap_commands[esp_mail_imap_command_namespace].text).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _ns_tmp.clear(); + + _imap_cmd = esp_mail_imap_cmd_namespace; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + int cnt = 0; + MB_String personal, other, shared; + + for (size_t i = 0; i < _ns_tmp.length(); i++) + { + if (i > 0 && i < _ns_tmp.length() - 1 && _ns_tmp[i] == ' ' && _ns_tmp[i - 1] != '"' && _ns_tmp[i + 1] != '"') + { + if (cnt == 0) + personal = _ns_tmp.substr(0, i); + else if (cnt == 1) + { + other = _ns_tmp.substr(personal.length() + 1, i - personal.length() - 1); + shared = _ns_tmp.substr(i + 1, _ns_tmp.length() - i - 1); + } + cnt++; + } + } + + if (personal.length() > 4) + parseNamespaces(personal, &(ns->personal_namespaces)); + + if (other.length() > 4) + parseNamespaces(other, &(ns->other_users_namespaces)); + + if (shared.length() > 4) + parseNamespaces(shared, &(ns->shared_namespaces)); + + return true; +} + +bool IMAPSession::mEnable(MB_StringPtr capability) +{ + +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_41 /* "Enable capability..." */, + esp_mail_dbg_str_68 /* "send IMAP command, ENABLE" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + if (!_feature_capability[esp_mail_imap_read_capability_enable]) + { +#if !defined(SILENT_MODE) + printDebugNotSupported(); +#endif + return false; + } + + MB_String _cap = capability; + + MB_String cmd; + MailClient.joinStringSpace(cmd, true, 2, imap_commands[esp_mail_imap_command_enable].text, _cap.c_str()); + + if (MailClient.imapSend(this, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + _imap_cmd = esp_mail_imap_cmd_enable; + if (!MailClient.handleIMAPResponse(this, IMAP_STATUS_BAD_COMMAND, false)) + return false; + + return true; +} + +void IMAPSession::parseNamespaces(MB_String &ns_str, IMAP_Namespaces *ns) +{ + MB_String tmp = ns_str.substr(2, ns_str.length() - 4); + tmp.replaceAll(")(", " "); + _vectorImpl tokens; + MailClient.splitToken(tmp.c_str(), tokens, " "); + + for (size_t i = 0; i < tokens.size(); i += 2) + { + IMAP_Namespace_Info info; + info.prefix = tokens[i]; + info.delimiter = tokens[i + 1]; + ns->add(info); + } +} + +void IMAPSession::empty() +{ + _nextUID.clear(); + _unseenMsgIndex.clear(); + _flags_tmp.clear(); + _quota_tmp.clear(); + _quota_root_tmp.clear(); + _acl_tmp.clear(); + _ns_tmp.clear(); + _server_id_tmp.clear(); + _sdFileList.clear(); + clearMessageData(); +} + +IMAP_Status IMAPSession::status() +{ + return _cbData; +} + +String IMAPSession::fileList() +{ + return _sdFileList.c_str(); +} + +void IMAPSession::clearMessageData() +{ + for (size_t i = 0; i < _headers.size(); i++) + { + _headers[i].part_headers.clear(); + } + + _headers.clear(); + _imap_msg_num.clear(); + _mbif._searchCount = 0; + _flags_tmp.clear(); + +#if defined(MB_USE_STD_VECTOR) + _folders.clear(); + _mbif._flags.clear(); +#endif +} + +void IMAPSession::printDebugNotSupported() +{ + +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_error_imap_str_13 /* "not supported by IMAP server" */, + esp_mail_error_imap_str_13 /* "not supported by IMAP server" */, + esp_mail_debug_tag_type_error, + true, + false); +#endif +} + +IMAP_Status::IMAP_Status() +{ +} + +IMAP_Status::~IMAP_Status() +{ + empty(); +} + +const char *IMAP_Status::info() +{ + return _info.c_str(); +} + +bool IMAP_Status::success() +{ + return _success; +} + +void IMAP_Status::empty() +{ + _info.clear(); +} + +#endif + #endif /* ESP_MAIL_IMAP_H */ \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_SMTP.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_SMTP.h index 8371e95ca..9ec383187 100644 --- a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_SMTP.h +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_SMTP.h @@ -1,3631 +1,3631 @@ - -#ifndef ESP_MAIL_SMTP_H -#define ESP_MAIL_SMTP_H - -#include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30409) -#error "Mixed versions compilation." -#endif - -/** - * Mail Client Arduino Library for Espressif's ESP32 and ESP8266, Raspberry Pi RP2040 Pico, and SAMD21 with u-blox NINA-W102 WiFi/Bluetooth module - * - * Created August 28, 2023 - * - * This library allows Espressif's ESP32, ESP8266, SAMD and RP2040 Pico devices to send and read Email through the SMTP and IMAP servers. - * - * The MIT License (MIT) - * Copyright (c) 2023 K. Suwatchai (Mobizt) - * - * - * 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 "ESP_Mail_Client_Version.h" -#include "ESP_Mail_Client.h" - -#if defined(ENABLE_SMTP) - -void ESP_Mail_Client::mimeFromFile(const char *name, MB_String &mime) -{ - MB_String ext = name; - size_t p = ext.find_last_of("."); - if (p != MB_String::npos) - { - ext = ext.substr(p, ext.length() - p); - if (ext.length() > 0) - getMIME(ext.c_str(), mime); - } -} - -void ESP_Mail_Client::getMIME(const char *ext, MB_String &mime) -{ - mime.clear(); - for (int i = 0; i < esp_mail_file_extension_maxType; i++) - { - if (strcmp_P(ext, mimeinfo[i].endsWith) == 0) - { - mime = mimeinfo[i].mimeType; - break; - } - } -} - -bool ESP_Mail_Client::smtpAuth(SMTPSession *smtp, bool &ssl) -{ - if (!smtp) - return false; - - smtp->_auth_capability[esp_mail_auth_capability_login] = false; - - smtp->_session_cfg->int_start_tls = smtp->_session_cfg->secure.startTLS; - smtp->_session_cfg->int_mode = smtp->_session_cfg->secure.mode; - -#if !defined(ESP_MAIL_DISABLE_SSL) -initial_stage: -#endif - -// Sending greeting helo response -#if !defined(SILENT_MODE) - printDebug(smtp, - esp_mail_cb_str_3 /* "Sending greeting response..." */, - esp_mail_dbg_str_5 /* "send SMTP command, EHLO" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - - // The Extended HELLO (EHLO) and HELLO (HELO) commands are used to identify Client (ourself) - - // Since we support ESMTP (rfc5321), let server knows by sending EHLO first - - // If server was not support ESMTP (rfc5321) the failure 501, 500, 502, or 550 would be replied. - - // To prevent connection rejection, EHLO/HELO command parameter should be primary host name (domain name) of client system. - // Otherwise client public IP address string (IPv4 or IPv6) can be assign when no host name is available - - MB_String s = smtp_cmd_post_tokens[esp_mail_smtp_command_ehlo]; - appendDomain(s, smtp->_session_cfg->login.user_domain.c_str()); - - if (smtpSend(smtp, s.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - // expected success status code 250 - // expected error status code 500, 501, 504, 421 - if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_greeting, esp_mail_smtp_status_code_250, 0)) - { - -#if !defined(SILENT_MODE) - if (smtp->_debug) - esp_mail_debug_print_tag(esp_mail_dbg_str_17 /* "No ESMTP supported, send SMTP command, HELO" */, esp_mail_debug_tag_type_client, true); -#endif - // In case EHLO (rfc5321) is not acceptable, - // send HELO command (rfc821) instead. - s = smtp_cmd_post_tokens[esp_mail_smtp_command_helo]; - appendDomain(s, smtp->_session_cfg->login.user_domain.c_str()); - - if (!smtpSend(smtp, s.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - // expected success status code 250 - // expected error status code 500, 501, 504, 421 - if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_greeting, esp_mail_smtp_status_code_250, SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED)) - return false; - - smtp->_feature_capability[esp_mail_smtp_send_capability_esmtp] = false; - smtp->_auth_capability[esp_mail_auth_capability_login] = true; - } - else - smtp->_feature_capability[esp_mail_smtp_send_capability_esmtp] = true; - -#if !defined(ESP_MAIL_DISABLE_SSL) - - if (smtp->_session_cfg->int_mode != esp_mail_secure_mode_nonsecure) - { - // start TLS when needed - // rfc3207 - if ((smtp->_auth_capability[esp_mail_auth_capability_starttls] || smtp->_session_cfg->int_start_tls || smtp->_session_cfg->int_mode == esp_mail_secure_mode_ssl_tls) && !ssl) - { -// send starttls command -#if !defined(SILENT_MODE) - printDebug(smtp, - esp_mail_cb_str_2 /* "Sending STARTTLS command..." */, - esp_mail_dbg_str_1 /* "send command, STARTTLS" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - - // expected success status code 250 for complete the request - // some server returns 220 to restart to initial state - - // expected error status code 500, 501, 504, 421 - smtpSend(smtp, smtp_commands[esp_mail_smtp_command_starttls].text, true); - if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_start_tls, esp_mail_smtp_status_code_250, SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED)) - return false; - -#if !defined(SILENT_MODE) - if (smtp->_debug) - esp_mail_debug_print_tag(esp_mail_dbg_str_22 /* "perform SSL/TLS handshake" */, esp_mail_debug_tag_type_client, true); -#endif - - // connect in secure mode - // do TLS handshake - if (!smtp->client.connectSSL(smtp->_session_cfg->certificate.verify)) - return handleSMTPError(smtp, MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP); - - // set the secure mode - smtp->_session_cfg->int_start_tls = false; - smtp->_session_cfg->int_mode = esp_mail_secure_mode_undefined; - ssl = true; - smtp->_secure = true; - - // return to initial stage if the response status is 220. - if (smtp->_responseStatus.statusCode == esp_mail_smtp_status_code_220) - goto initial_stage; - } - } - -#endif - - bool creds = smtp->_session_cfg->login.email.length() > 0 && smtp->_session_cfg->login.password.length() > 0; - bool sasl_auth_oauth = smtp->_session_cfg->login.accessToken.length() > 0 && smtp->_auth_capability[esp_mail_auth_capability_xoauth2]; - bool sasl_login = smtp->_auth_capability[esp_mail_auth_capability_login] && creds; - bool sasl_auth_plain = smtp->_auth_capability[esp_mail_auth_capability_plain] && creds; - - if (sasl_auth_oauth || sasl_login || sasl_auth_plain) - { -#if !defined(SILENT_MODE) - if (smtp->_statusCallback) - sendCB(smtp, esp_mail_cb_str_14 /* "Logging in..." */, true, false); -#endif - - // log in - if (sasl_auth_oauth) - { -#if !defined(SILENT_MODE) - if (smtp->_debug) - esp_mail_debug_print_tag(esp_mail_dbg_str_15 /* "send smtp command, AUTH XOAUTH2" */, esp_mail_debug_tag_type_client, true); -#endif - if (!smtp->_auth_capability[esp_mail_auth_capability_xoauth2]) - return handleSMTPError(smtp, SMTP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED, false); - - MB_String cmd = smtp_cmd_post_tokens[esp_mail_smtp_command_auth]; - cmd += smtp_auth_cap_post_tokens[esp_mail_auth_capability_xoauth2]; - - if (smtpSend(smtp, cmd.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - if (smtpSend(smtp, getXOAUTH2String(smtp->_session_cfg->login.email, smtp->_session_cfg->login.accessToken).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_auth_xoauth2, esp_mail_smtp_status_code_235, SMTP_STATUS_AUTHEN_FAILED)) - return false; - } - else if (sasl_auth_plain) - { -#if !defined(SILENT_MODE) - if (smtp->_debug) - { - esp_mail_debug_print_tag(esp_mail_dbg_str_7 /* "send SMTP command, AUTH PLAIN" */, esp_mail_debug_tag_type_client, true); - esp_mail_debug_print_tag(smtp->_session_cfg->login.email.c_str(), esp_mail_debug_tag_type_client, true); - MB_String mask; - maskString(mask, smtp->_session_cfg->login.password.length()); - esp_mail_debug_print_tag(mask.c_str(), esp_mail_debug_tag_type_client, true); - } -#endif - // rfc4616 - int len = smtp->_session_cfg->login.email.length() + smtp->_session_cfg->login.password.length() + 2; - uint8_t *tmp = allocMem(len); - memset(tmp, 0, len); - int p = 1; - memcpy(tmp + p, smtp->_session_cfg->login.email.c_str(), smtp->_session_cfg->login.email.length()); - p += smtp->_session_cfg->login.email.length() + 1; - memcpy(tmp + p, smtp->_session_cfg->login.password.c_str(), smtp->_session_cfg->login.password.length()); - p += smtp->_session_cfg->login.password.length(); - - MB_String cmd = smtp_cmd_post_tokens[esp_mail_smtp_command_auth]; - cmd += smtp_cmd_post_tokens[esp_mail_smtp_command_plain]; - cmd += encodeBase64Str(tmp, p); - // release memory - freeMem(&tmp); - - if (smtpSend(smtp, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_auth_plain, esp_mail_smtp_status_code_235, SMTP_STATUS_USER_LOGIN_FAILED)) - return false; - } - else if (sasl_login) - { -#if !defined(SILENT_MODE) - if (smtp->_debug) - esp_mail_debug_print_tag(esp_mail_dbg_str_6 /* "send SMTP command, AUTH LOGIN" */, esp_mail_debug_tag_type_client, true); -#endif - MB_String cmd = smtp_cmd_post_tokens[esp_mail_smtp_command_auth]; - cmd += smtp_commands[esp_mail_smtp_command_login].text; - - if (smtpSend(smtp, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - // expected server challenge response - if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_auth_login, esp_mail_smtp_status_code_334, SMTP_STATUS_AUTHEN_FAILED)) - return false; - -#if !defined(SILENT_MODE) - if (smtp->_debug) - esp_mail_debug_print_tag(smtp->_session_cfg->login.email.c_str(), esp_mail_debug_tag_type_client, true); -#endif - if (smtpSend(smtp, encodeBase64Str((const unsigned char *)smtp->_session_cfg->login.email.c_str(), smtp->_session_cfg->login.email.length()).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - // expected server challenge response - if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_login_user, esp_mail_smtp_status_code_334, SMTP_STATUS_USER_LOGIN_FAILED)) - return false; - -#if !defined(SILENT_MODE) - if (smtp->_debug) - { - MB_String mask; - maskString(mask, smtp->_session_cfg->login.password.length()); - esp_mail_debug_print_tag(mask.c_str(), esp_mail_debug_tag_type_client, true); - } -#endif - if (smtpSend(smtp, encodeBase64Str((const unsigned char *)smtp->_session_cfg->login.password.c_str(), smtp->_session_cfg->login.password.length()).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_login_psw, esp_mail_smtp_status_code_235, SMTP_STATUS_PASSWORD_LOGIN_FAILED)) - return false; - } - - smtp->_authenticated = true; - } - - return true; -} - -bool ESP_Mail_Client::addSendingResult(SMTPSession *smtp, SMTP_Message *msg, bool result, bool showResult) -{ - if (!smtp) - return false; - - if (result) - smtp->_sentSuccessCount++; - else - smtp->_sentFailedCount++; - - if (smtp->_session_cfg->sentLogs.filename.length() > 0 && smtp->_session_cfg->sentLogs.storage_type != esp_mail_file_storage_type_none) - saveSendingLogs(smtp, msg, result); - - // Store only tatest result - smtp->sendingResult.clear(); - - SMTP_Result status; - status.completed = result; - status.timestamp = smtp->ts; - status.subject = msg->subject.c_str(); - - if (msg->timestamp.tag.length() && msg->timestamp.format.length()) - status.subject.replaceAll(msg->timestamp.tag, Time.getDateTimeString(Time.getCurrentTimestamp(), msg->timestamp.format.c_str())); - - status.recipients = msg->_rcp[0].email.c_str(); - smtp->sendingResult.add(&status); - - smtp->_cbData._sentSuccess = smtp->_sentSuccessCount; - smtp->_cbData._sentFailed = smtp->_sentFailedCount; - -#if !defined(SILENT_MODE) - if (smtp->_statusCallback) - { - if (showResult) - { - int bufLen = 512; - char *buf = allocMem(bufLen); - time_t ts = (time_t)smtp->ts; - MB_String sep; - for (int i = 0; i < 25; i++) - sep += '-'; - - sendCallback(smtp, sep.c_str(), true, false); - snprintf(buf, bufLen, pgm2Str(esp_mail_str_93 /* "Message sent success: %d" */), smtp->_sentSuccessCount); - sendCallback(smtp, buf, false, false); - snprintf(buf, bufLen, pgm2Str(esp_mail_str_94 /* "Message sent failed: %d" */), smtp->_sentFailedCount); - sendCallback(smtp, buf, false, false); - sendCallback(smtp, sep.c_str(), false, false); - snprintf(buf, bufLen, pgm2Str(esp_mail_str_95 /* "Status: %s" */), result ? pgm2Str(esp_mail_str_98 /* "success" */) : pgm2Str(esp_mail_str_99 /* "failed" */)); - sendCallback(smtp, buf, false, false); - snprintf(buf, bufLen, pgm2Str(esp_mail_str_96 /* "Date/Time: %s" */), Time.getDateTimeString(ts, "%B %d, %Y %H:%M:%S").c_str()); - sendCallback(smtp, buf, false, false); - snprintf(buf, bufLen, pgm2Str(esp_mail_str_97 /* "Recipient: %s" */), msg->_rcp[0].email.c_str()); - sendCallback(smtp, buf, false, false); - snprintf(buf, bufLen, pgm2Str(esp_mail_str_92 /* "Subject: %s" */), msg->subject.c_str()); - sendCallback(smtp, buf, false, false); - freeMem(&buf); - } - } -#endif - - return result; -} - -void ESP_Mail_Client::saveSendingLogs(SMTPSession *smtp, SMTP_Message *msg, bool result) -{ - if (!smtp->_session_cfg || smtp->_session_cfg->sentLogs.filename.length() == 0 || smtp->_session_cfg->sentLogs.storage_type == esp_mail_file_storage_type_none) - return; - - int sz = mbfs->open(smtp->_session_cfg->sentLogs.filename.c_str(), mbfs_type smtp->_session_cfg->sentLogs.storage_type, mb_fs_open_mode_append); - if (sz < 0) - return; - - MB_String cm = esp_mail_str_8; /* "," */ - mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, (int)result); - mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, cm.c_str()); - mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, (int)smtp->ts); - mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, cm.c_str()); - mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, msg->_rcp[0].email.c_str()); - mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, cm.c_str()); - mbfs->println(mbfs_type smtp->_session_cfg->sentLogs.storage_type, msg->subject.c_str()); - mbfs->close(mbfs_type smtp->_session_cfg->sentLogs.storage_type); -} - -bool ESP_Mail_Client::sendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession) -{ - if (!smtp || !sessionExisted(smtp)) - return false; - - smtp->_customCmdResCallback = NULL; - - return mSendMail(smtp, msg, closeSession); -} - -size_t ESP_Mail_Client::numAtt(SMTPSession *smtp, esp_mail_attach_type type, SMTP_Message *msg) -{ - size_t count = 0; - for (size_t i = 0; i < msg->_att.size(); i++) - { - if (msg->_att[i]._int.att_type == type) - count++; - } - return count; -} - -bool ESP_Mail_Client::checkEmail(SMTPSession *smtp, SMTP_Message *msg) -{ - bool validRecipient = false; - - if (!validEmail(msg->sender.email.c_str())) - { - errorStatusCB(smtp, this->imap, SMTP_STATUS_NO_VALID_SENDER_EXISTED, false); - return addSendingResult(smtp, msg, false, true); - } - - for (uint8_t i = 0; i < msg->_rcp.size(); i++) - { - if (validEmail(msg->_rcp[i].email.c_str())) - validRecipient = true; - } - - if (!validRecipient) - { - errorStatusCB(smtp, this->imap, SMTP_STATUS_NO_VALID_RECIPIENTS_EXISTED, false); - return addSendingResult(smtp, msg, false, true); - } - - return true; -} - -bool ESP_Mail_Client::mSendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession) -{ - if (!smtp) - return false; - - smtp->_responseStatus.errorCode = 0; - smtp->_responseStatus.statusCode = 0; - smtp->_responseStatus.text.clear(); - smtp->_cbData._success = false; - bool rfc822MSG = false; - - if (!checkEmail(smtp, msg)) - return false; - - smtp->_chunkedEnable = false; - smtp->_chunkCount = 0; - - if (!smtp->connected() && !smtp->_loginStatus) - { -#if !defined(SILENT_MODE) - if (smtp->_debug && smtp->_statusCallback && !smtp->_customCmdResCallback) - { - esp_mail_debug_print(); - errorStatusCB(smtp, this->imap, MAIL_CLIENT_ERROR_NOT_YET_LOGIN, false); - } -#endif - return false; - } - - // new session - if (!smtp->connected()) - { - bool ssl = false; - - if (!smtp->connect(ssl)) - { - closeTCPSession(smtp); - return addSendingResult(smtp, msg, false, true); - } - - if (!smtpAuth(smtp, ssl)) - { - closeTCPSession(smtp); - return addSendingResult(smtp, msg, false, true); - } - smtp->_sentSuccessCount = 0; - smtp->_sentFailedCount = 0; - smtp->sendingResult.clear(); - } - else - { - // If time config changed, we will update time - MailClient.prepareTime(smtp->_session_cfg, smtp); - // reuse session -#if !defined(SILENT_MODE) - PGM_P p1 = smtp->_sentSuccessCount || smtp->_sentFailedCount ? esp_mail_cb_str_10 /* "Sending next Email..." */ : esp_mail_cb_str_9 /* "Sending Email..." */; - PGM_P p2 = smtp->_sentSuccessCount || smtp->_sentFailedCount ? esp_mail_dbg_str_13 /* "send next Email" */ : esp_mail_dbg_str_3 /* "send Email" */; - - printDebug(smtp, - p1, - p2, - esp_mail_debug_tag_type_client, - true, - false); -#endif - } - -#if !defined(SILENT_MODE) - printDebug(smtp, - esp_mail_cb_str_4 /* "Sending message header..." */, - esp_mail_dbg_str_8 /* "send message header" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - - imap = nullptr; - calDataLen = false; - dataLen = 0; - - return sendContent(smtp, msg, closeSession, rfc822MSG); -} - -bool ESP_Mail_Client::sendContent(SMTPSession *smtp, SMTP_Message *msg, bool closeSession, bool rfc822MSG) -{ - - if (msg->html.content.length() > 0 || strlen(msg->html.nonCopyContent) > 0 || msg->html.blob.size > 0 || msg->html.file.name.length() > 0) - msg->type |= esp_mail_msg_type_html; - - if (msg->text.content.length() > 0 || strlen(msg->text.nonCopyContent) > 0 || msg->text.blob.size > 0 || msg->text.file.name.length() > 0) - msg->type |= esp_mail_msg_type_plain; - - for (size_t i = 0; i < msg->_rfc822.size(); i++) - { - if (msg->_rfc822[i].html.content.length() > 0) - msg->_rfc822[i].type |= esp_mail_msg_type_html; - - if (msg->_rfc822[i].text.content.length() > 0) - msg->_rfc822[i].type |= esp_mail_msg_type_plain; - } - - MB_String buf; - MB_String buf2; - checkUnencodedData(smtp, msg); - - if (msg->priority >= esp_mail_smtp_priority_high && msg->priority <= esp_mail_smtp_priority_low) - { - appendHeaderField(buf2, message_headers[esp_mail_message_header_field_x_priority].text, MB_String(msg->priority).c_str(), false, true); - - PGM_P p = nullptr; - if (msg->priority == esp_mail_smtp_priority_high) - p = esp_mail_str_4; /* "High" */ - else if (msg->priority == esp_mail_smtp_priority_normal) - p = esp_mail_str_5; /* "Normal" */ - else if (msg->priority == esp_mail_smtp_priority_low) - p = esp_mail_str_6; /* "Low" */ - - if (p) - { - appendHeaderField(buf2, message_headers[esp_mail_message_header_field_x_msmail_priority].text, p, false, true); - appendHeaderField(buf2, message_headers[esp_mail_message_header_field_importance].text, p, false, true); - } - } - - // If author and transmitter (sender or agent) are not identical, send both 'From' and 'Sender' headers - if (msg->sender.email.length() > 0 && msg->author.email.length() > 0 && - strcmp(msg->sender.email.c_str(), msg->author.email.c_str()) != 0) - { - appendAddressHeaderField(buf2, msg->author, esp_mail_rfc822_header_field_from, true, false, true); - appendAddressHeaderField(buf2, msg->sender, esp_mail_rfc822_header_field_sender, true, false, true); - } - // If author and transmitter (agent) are identical, send only 'From' header - else if (msg->sender.email.length() > 0) - appendAddressHeaderField(buf2, msg->sender, esp_mail_rfc822_header_field_from, true, false, true); - - if (!imap && smtp) - { - - buf = smtp_cmd_post_tokens[esp_mail_smtp_command_mail]; - buf += smtp_commands[esp_mail_smtp_command_from].text; - - appendString(buf, msg->author.email.length() ? msg->author.email.c_str() : msg->sender.email.c_str(), false, false, esp_mail_string_mark_type_angle_bracket); - - if (msg->text._int.xencoding == esp_mail_msg_xencoding_binary || msg->html._int.xencoding == esp_mail_msg_xencoding_binary) - { - if (smtp->_feature_capability[esp_mail_smtp_send_capability_binary_mime] || (smtp->_feature_capability[esp_mail_smtp_send_capability_chunking] && msg->enable.chunking)) - { - buf += smtp_cmd_pre_tokens[esp_mail_smtp_command_body]; - buf += esp_mail_str_7; /* "=" */ - buf += smtp_send_capabilities[esp_mail_smtp_send_capability_binary_mime].text; - } - } - else if (msg->text._int.xencoding == esp_mail_msg_xencoding_8bit || msg->html._int.xencoding == esp_mail_msg_xencoding_8bit) - { - if (smtp->_feature_capability[esp_mail_smtp_send_capability_8bit_mime]) - { - buf += smtp_cmd_pre_tokens[esp_mail_smtp_command_body]; - buf += esp_mail_str_7; /* "=" */ - buf += smtp_send_capabilities[esp_mail_smtp_send_capability_8bit_mime].text; - } - } - - // expected success status code 250 - // expected failure status code 552, 451, 452 - // expected error status code 500, 501, 421 - if (!altSendData(buf, true, smtp, msg, true, true, esp_mail_smtp_cmd_send_header_sender, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_SENDER_FAILED)) - return false; - } - - // Construct 'To' header fields. - - for (uint8_t i = 0; i < msg->_rcp.size(); i++) - { - appendAddressHeaderField(buf2, msg->_rcp[i], esp_mail_rfc822_header_field_to, i == 0, i > 0, i == msg->_rcp.size() - 1); - if (!imap && smtp) - { - // only address - buf = smtp_cmd_post_tokens[esp_mail_smtp_command_rcpt]; - buf += smtp_commands[esp_mail_smtp_command_to].text; - appendString(buf, msg->_rcp[i].email.c_str(), false, false, esp_mail_string_mark_type_angle_bracket); - - // rfc3461, rfc3464 - if (smtp->_feature_capability[esp_mail_smtp_send_capability_dsn]) - { - if (msg->response.notify != esp_mail_smtp_notify_never) - { - buf += smtp_cmd_pre_tokens[esp_mail_smtp_command_notify]; - buf += esp_mail_str_7; /* "=" */ - - MB_String notify; - - if ((msg->response.notify & esp_mail_smtp_notify_success) == esp_mail_smtp_notify_success) - notify = smtp_commands[esp_mail_smtp_command_success].text; - - if (notify.length()) - notify += esp_mail_str_8; /* "," */ - - if ((msg->response.notify & esp_mail_smtp_notify_failure) == esp_mail_smtp_notify_failure) - notify += smtp_commands[esp_mail_smtp_command_failure].text; - - if (notify.length()) - notify += esp_mail_str_8; /* "," */ - - if ((msg->response.notify & esp_mail_smtp_notify_delay) == esp_mail_smtp_notify_delay) - notify += smtp_commands[esp_mail_smtp_command_delay].text; - - buf += notify; - } - } - - smtp->_canForward = true; - - // expected success status code 250, 251 - // expected failure status code 550, 551, 552, 553, 450, 451, 452 - // expected error status code 500, 501, 503, 421 - if (!altSendData(buf, true, smtp, msg, true, true, esp_mail_smtp_cmd_send_header_recipient, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED)) - return false; - } - } - - // Construct 'Cc' header field. - for (uint8_t i = 0; i < msg->_cc.size(); i++) - { - appendAddressHeaderField(buf2, msg->_cc[i], esp_mail_rfc822_header_field_cc, i == 0, i > 0, i == msg->_cc.size() - 1); - if (!imap) - { - // only address - buf = smtp_cmd_post_tokens[esp_mail_smtp_command_rcpt]; - buf += smtp_commands[esp_mail_smtp_command_to].text; - appendString(buf, msg->_cc[i].email.c_str(), false, false, esp_mail_string_mark_type_angle_bracket); - - smtp->_canForward = true; - - // expected success status code 250, 251 - // expected failure status code 550, 551, 552, 553, 450, 451, 452 - // expected error status code 500, 501, 503, 421 - if (!altSendData(buf, true, smtp, msg, true, true, esp_mail_smtp_cmd_send_header_recipient, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED)) - return false; - } - } - - if (!imap && smtp) - { - for (uint8_t i = 0; i < msg->_bcc.size(); i++) - { - // only address - buf = smtp_cmd_post_tokens[esp_mail_smtp_command_rcpt]; - buf += smtp_commands[esp_mail_smtp_command_to].text; - appendString(buf, msg->_bcc[i].email.c_str(), false, false, esp_mail_string_mark_type_angle_bracket); - - smtp->_canForward = true; - - // expected success status code 250, 251 - // expected failure status code 550, 551, 552, 553, 450, 451, 452 - // expected error status code 500, 501, 503, 421 - if (!altSendData(buf, true, smtp, msg, true, true, esp_mail_smtp_cmd_send_header_recipient, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED)) - return false; - } - -#if !defined(SILENT_MODE) - altSendCallback(smtp, esp_mail_cb_str_5 /* "Sending message body..." */, esp_mail_dbg_str_9 /* "send message body" */, esp_mail_debug_tag_type_client, true, false); -#endif - if (smtp->_feature_capability[esp_mail_smtp_send_capability_chunking] && msg->enable.chunking) - { - smtp->_chunkedEnable = true; - if (!sendBDAT(smtp, msg, buf2.length(), false)) - return false; - } - else - { - // expected success status code 354 - // expected failure status code 451, 554 - // expected error status code 500, 501, 503, 421 - MB_String sdata = smtp_commands[esp_mail_smtp_command_data].text; - if (!altSendData(sdata, true, smtp, msg, true, true, esp_mail_smtp_cmd_send_body, esp_mail_smtp_status_code_354, SMTP_STATUS_SEND_BODY_FAILED)) - return false; - } - } - -#if defined(ENABLE_IMAP) && !defined(SILENT_MODE) - if (imap) - altSendCallback(smtp, esp_mail_cb_str_14 /* "Appending message..." */, esp_mail_dbg_str_69 /* "appending message" */, esp_mail_debug_tag_type_client, true, false); - -#endif - - if (!altSendData(buf2, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - - MB_String s; - appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_subject].text, msg->subject.c_str(), false, true); - - if (msg->timestamp.tag.length() && msg->timestamp.format.length()) - s.replaceAll(msg->timestamp.tag, Time.getDateTimeString(Time.getCurrentTimestamp(), msg->timestamp.format.c_str())); - - // Construct the 'Date' header field. - // The 'Date' header field should be valid and should be included in the message headers to - // prevent the 'spam' or 'junk' message considered by mail server. - - bool dateHdr = false; - MB_String dt; - - uint32_t ts = 0; - - if (smtp) - smtp->ts = ts; - - // Check if valid 'Date' field assigned from custom headers. - if (msg->_hdr.size() > 0) - { - for (uint8_t k = 0; k < msg->_hdr.size(); k++) - { - appendString(s, msg->_hdr[k].c_str(), false, true); - - if (getHeader(msg->_hdr[k].c_str(), rfc822_headers[esp_mail_rfc822_header_field_date].text, dt, false)) - { - ts = Time.getTimestamp(dt.c_str(), true); - dateHdr = ts > ESP_MAIL_CLIENT_VALID_TS; - if (smtp) - smtp->ts = ts; - } - } - } - - // Check if valid 'Date' field assigned from SMTP_Message's date property. - if (!dateHdr && msg->date.length() > 0) - { - dt = msg->date; - ts = Time.getTimestamp(msg->date.c_str(), true); - dateHdr = ts > ESP_MAIL_CLIENT_VALID_TS; - if (smtp) - smtp->ts = ts; - } - - if (dateHdr) - { - // 'Date' header field assigned. - appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_date].text, dt.c_str(), false, true); - } - else - { - // If there is no 'Date' field assigned, get time from system and construct 'Date' header field. - if (smtp) - { - ts = MailClient.Time.getCurrentTimestamp(); - smtp->ts = ts; - } - else if (imap) - { -#if defined(ENABLE_IMAP) - if (calDataLen) - { - ts = MailClient.Time.getCurrentTimestamp(); - imap_ts = ts; - } - else - ts = imap_ts; -#endif - } - - if (ts > ESP_MAIL_CLIENT_VALID_TS) - appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_date].text, Time.getDateTimeString().c_str(), false, true); - } - - if (msg->response.reply_to.length() > 0) - appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_reply_to].text, msg->response.reply_to.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); - - if (msg->response.return_path.length() > 0) - appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_return_path].text, msg->response.return_path.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); - - if (msg->in_reply_to.length() > 0) - appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_in_reply_to].text, msg->in_reply_to.c_str(), false, true); - - if (msg->references.length() > 0) - appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_references].text, msg->references.c_str(), false, true); - - if (msg->comments.length() > 0) - appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_comments].text, msg->comments.c_str(), false, true); - - if (msg->keywords.length() > 0) - appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_keywords].text, msg->keywords.c_str(), false, true); - - if (msg->messageID.length() > 0) - appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_msg_id].text, msg->messageID.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); - - appendHeaderField(s, message_headers[esp_mail_message_header_field_mime_version].text, esp_mail_str_51 /* "1.0" */, false, true); - - if (!sendBDAT(smtp, msg, s.length(), false)) - return false; - - if (!altSendData(s, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - - return sendMSGData(smtp, msg, closeSession, rfc822MSG); -} - -void ESP_Mail_Client::altSendCallback(SMTPSession *smtp, PGM_P cbMsg, PGM_P dbMsg, esp_mail_debug_tag_type type, bool prependCRLF, bool success) -{ -#if !defined(SILENT_MODE) - if (smtp) - printDebug(smtp, cbMsg, dbMsg, type, prependCRLF, success); - else if (imap && !calDataLen) - { -#if defined(ENABLE_IMAP) - printDebug(imap, cbMsg, dbMsg, type, prependCRLF, success); -#endif - } -#endif -} - -bool ESP_Mail_Client::sendMSGData(SMTPSession *smtp, SMTP_Message *msg, bool closeSession, bool rfc822MSG) -{ - MB_String s; - MB_String mixed = getMIMEBoundary(15); - MB_String alt = getMIMEBoundary(15); - - if (numAtt(smtp, esp_mail_att_type_attachment, msg) == 0 && msg->_parallel.size() == 0 && msg->_rfc822.size() == 0) - { - if (msg->type == (esp_mail_msg_type_plain | esp_mail_msg_type_html | esp_mail_msg_type_enriched) || numAtt(smtp, esp_mail_att_type_inline, msg) > 0) - { - if (!sendMSG(smtp, msg, alt)) - return addSendingResult(smtp, msg, false, true); - } - else if (msg->type != esp_mail_msg_type_none) - { - if (!sendPartText(smtp, msg, msg->type, "")) - return addSendingResult(smtp, msg, false, true); - } - } - else - { - s.clear(); - appendMultipartContentType(s, esp_mail_multipart_type_mixed, mixed.c_str()); - appendBoundaryString(s, mixed.c_str(), false, true); - - if (!sendBDAT(smtp, msg, s.length(), false)) - return false; - - if (!altSendData(s, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - - if (!sendMSG(smtp, msg, alt)) - return addSendingResult(smtp, msg, false, true); - - if (!sendBDAT(smtp, msg, 2, false)) - return false; - - MB_String str; - appendNewline(str); - - if (!altSendData(str, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - -#if !defined(SILENT_MODE) - altSendCallback(smtp, esp_mail_cb_str_6 /* "Sending attachments..." */, esp_mail_dbg_str_10 /* "send attachments" */, esp_mail_debug_tag_type_client, true, false); -#endif - if (!sendAttachments(smtp, msg, mixed)) - return addSendingResult(smtp, msg, false, true); - - if (!sendParallelAttachments(smtp, msg, mixed)) - return addSendingResult(smtp, msg, false, true); - - if (!sendRFC822Msg(smtp, msg, mixed, closeSession, msg->_rfc822.size() > 0)) - return addSendingResult(smtp, msg, false, true); - - s.clear(); - appendBoundaryString(s, mixed.c_str(), true, false); - - if (!sendBDAT(smtp, msg, s.length(), false)) - return false; - - if (!altSendData(s, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - } - - if (!rfc822MSG && !imap && smtp) - { -#if !defined(SILENT_MODE) - altSendCallback(smtp, esp_mail_cb_str_11 /* "Finishing the message sending..." */, esp_mail_dbg_str_16 /* "finishing the message sending" */, esp_mail_debug_tag_type_client, true, false); -#endif - if (smtp->_chunkedEnable) - { - - if (!sendBDAT(smtp, msg, 0, true)) - return false; - - // expected success status code 250 - // expected failure status code 451, 554 - // expected error status code 500, 501, 503, 421 - if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_chunk_termination, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_BODY_FAILED)) - return false; - } - else - { - // expected success status code 250 - // expected failure status code 451, 554 - // expected error status code 500, 501, 503, 421 - MB_String str = smtp_commands[esp_mail_smtp_command_terminate].text; - if (!altSendData(str, false, smtp, msg, true, true, esp_mail_smtp_cmd_send_body, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_BODY_FAILED)) - return false; - } - - addSendingResult(smtp, msg, true, !closeSession); - - if (closeSession && smtp) - { - if (!smtp->closeSession()) - return false; - } - } - if (smtp) - smtp->_cbData._success = true; - return true; -} - -bool ESP_Mail_Client::sendRFC822Msg(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, bool closeSession, bool rfc822MSG) -{ - if (msg->_rfc822.size() == 0) - return true; - - MB_String buf; - - for (uint8_t i = 0; i < msg->_rfc822.size(); i++) - { - buf.clear(); - getRFC822PartHeader(smtp, buf, boundary); - - getRFC822MsgEnvelope(smtp, &msg->_rfc822[i], buf); - - if (!sendBDAT(smtp, msg, buf.length(), false)) - return false; - - if (!altSendData(buf, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - - if (!sendMSGData(smtp, &msg->_rfc822[i], closeSession, rfc822MSG)) - return false; - } - - return true; -} - -void ESP_Mail_Client::getRFC822MsgEnvelope(SMTPSession *smtp, SMTP_Message *msg, MB_String &buf) -{ - if (msg->date.length() > 0) - appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_date].text, msg->date.c_str(), false, true); - else - { - time_t now = 0; - if (smtp) - now = MailClient.Time.getCurrentTimestamp(); - else if (imap) - { -#if defined(ENABLE_IMAP) - if (calDataLen) - { - now = MailClient.Time.getCurrentTimestamp(); - imap_ts = now; - } - else - now = imap_ts; -#endif - } - - if (now > ESP_MAIL_CLIENT_VALID_TS) - appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_date].text, Time.getDateTimeString().c_str(), false, true); - } - - // Construct 'From' header field. - if (msg->from.email.length() > 0) - appendAddressHeaderField(buf, msg->from, esp_mail_rfc822_header_field_from, true, false, true); - - // Construct 'Sender' header field. - if (msg->sender.email.length() > 0) - appendAddressHeaderField(buf, msg->sender, esp_mail_rfc822_header_field_sender, true, false, true); - - if (msg->response.reply_to.length() > 0) - appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_reply_to].text, msg->response.reply_to.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); - - if (msg->response.return_path.length() > 0) - appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_return_path].text, msg->response.return_path.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); - - // Construct 'To' header field. - for (uint8_t i = 0; i < msg->_rcp.size(); i++) - appendAddressHeaderField(buf, msg->_rcp[i], esp_mail_rfc822_header_field_to, i == 0, i > 0, i == msg->_rcp.size() - 1); - - for (uint8_t i = 0; i < msg->_cc.size(); i++) - appendAddressHeaderField(buf, msg->_cc[i], esp_mail_rfc822_header_field_cc, i == 0, i > 0, i == msg->_cc.size() - 1); - - for (uint8_t i = 0; i < msg->_bcc.size(); i++) - appendAddressHeaderField(buf, msg->_bcc[i], esp_mail_rfc822_header_field_bcc, i == 0, i > 0, i == msg->_bcc.size() - 1); - - if (msg->subject.length() > 0) - appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_subject].text, msg->subject.c_str(), false, true); - - if (msg->keywords.length() > 0) - appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_keywords].text, msg->keywords.c_str(), false, true); - - if (msg->comments.length() > 0) - appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_comments].text, msg->comments.c_str(), false, true); - - if (msg->in_reply_to.length() > 0) - appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_in_reply_to].text, msg->in_reply_to.c_str(), false, true); - - if (msg->references.length() > 0) - appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_references].text, msg->references.c_str(), false, true); - - if (msg->messageID.length() > 0) - appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_msg_id].text, msg->messageID.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); -} - -void ESP_Mail_Client::appendBoundaryString(MB_String &buf, const char *value, bool endMark, bool newLine) -{ - buf += esp_mail_str_9; /* "--" */ - buf += value; - if (endMark) - buf += esp_mail_str_9; /* "--" */ - if (newLine) - appendNewline(buf); -} - -bool ESP_Mail_Client::sendBDAT(SMTPSession *smtp, SMTP_Message *msg, int len, bool last) -{ - if (!smtp) - return true; - - if (!smtp->_chunkedEnable || !msg->enable.chunking) - return true; - - smtp->_chunkCount++; - - MB_String bdat = smtp_cmd_post_tokens[esp_mail_smtp_command_bdat]; - bdat += len; - if (last) - bdat += smtp_cmd_pre_tokens[esp_mail_smtp_command_last]; - - if (smtpSend(smtp, bdat.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return addSendingResult(smtp, msg, false, true); - - if (!smtp->_feature_capability[esp_mail_smtp_send_capability_pipelining]) - { - // expected success status code 250 - // expected failure status code 451, 554 - // expected error status code 500, 501, 503, 421 - if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_send_body, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_BODY_FAILED)) - return addSendingResult(smtp, msg, false, true); - smtp->_chunkCount = 0; - } - return true; -} - -void ESP_Mail_Client::getXEncoding(esp_mail_msg_xencoding &xencoding, const char *enc) -{ - if (strcmp(enc, Content_Transfer_Encoding::enc_binary) == 0) - xencoding = esp_mail_msg_xencoding_binary; - else if (strcmp(enc, Content_Transfer_Encoding::enc_8bit) == 0) - xencoding = esp_mail_msg_xencoding_8bit; - else if (strcmp(enc, Content_Transfer_Encoding::enc_7bit) == 0) - xencoding = esp_mail_msg_xencoding_7bit; -} - -void ESP_Mail_Client::checkUnencodedData(SMTPSession *smtp, SMTP_Message *msg) -{ - if (msg->type & esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched || msg->type & esp_mail_msg_type_html) - { - if ((msg->type & esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched) > 0 && msg->text.transfer_encoding.length() > 0) - getXEncoding(msg->text._int.xencoding, msg->text.transfer_encoding.c_str()); - - if ((msg->type & esp_mail_msg_type_html) > 0 && msg->html.transfer_encoding.length() > 0) - getXEncoding(msg->html._int.xencoding, msg->html.transfer_encoding.c_str()); - } - - for (size_t i = 0; i < msg->_att.size(); i++) - getXEncoding(msg->_att[i]._int.xencoding, msg->_att[i].descr.transfer_encoding.c_str()); -} - -bool ESP_Mail_Client::altIsCB(SMTPSession *smtp) -{ - bool cb = false; - if (smtp) - cb = smtp->_statusCallback != NULL; - else if (imap && !calDataLen) - { -#if defined(ENABLE_IMAP) - cb = imap->_statusCallback != NULL; -#endif - } - - return cb; -} - -bool ESP_Mail_Client::altIsDebug(SMTPSession *smtp) -{ - bool dbg = false; - if (smtp) - dbg = smtp->_debug; - else if (imap && !calDataLen) - { -#if defined(ENABLE_IMAP) - dbg = imap->_debug; -#endif - } - - return dbg; -} - -bool ESP_Mail_Client::sendBlobAttachment(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att) -{ - bool cb = altIsCB(smtp); - uint32_t addr = altProgressPtr(smtp); - - if (strcmp(att->descr.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0 && strcmp(att->descr.transfer_encoding.c_str(), att->descr.content_encoding.c_str()) != 0) - { - esp_mail_smtp_send_base64_data_info_t data_info; - - data_info.rawPtr = att->blob.data; - data_info.size = att->blob.size; - data_info.flashMem = att->_int.flash_blob; - data_info.filename = att->descr.filename.c_str(); - - if (!sendBase64(smtp, msg, data_info, true, cb)) - return false; - - return true; - } - else - { - if (att->blob.size > 0) - { - if (strcmp(att->descr.content_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) - { - esp_mail_smtp_send_base64_data_info_t data_info; - - data_info.rawPtr = att->blob.data; - data_info.size = att->blob.size; - data_info.flashMem = att->_int.flash_blob; - data_info.filename = att->descr.filename.c_str(); - - if (!sendBase64(smtp, msg, data_info, false, cb)) - return false; - - return true; - } - else - { - - size_t chunkSize = ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE; - size_t writeLen = 0; - uint8_t *buf = allocMem(chunkSize); - while (writeLen < att->blob.size) - { - if (writeLen > att->blob.size - chunkSize) - chunkSize = att->blob.size - writeLen; - - if (!sendBDAT(smtp, msg, chunkSize, false)) - break; - memcpy_P(buf, att->blob.data, chunkSize); - - if (!altSendData(buf, chunkSize, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - break; - - if (smtp->_debug) - uploadReport(att->descr.filename.c_str(), addr, 100 * writeLen / att->blob.size); - - writeLen += chunkSize; - } - - // release memory - freeMem(&buf); - - if (smtp->_debug) - uploadReport(att->descr.filename.c_str(), addr, 100); - - return writeLen >= att->blob.size; - } - } - } - return false; -} - -bool ESP_Mail_Client::sendFile(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att) -{ - bool cb = altIsCB(smtp); - uint32_t addr = altProgressPtr(smtp); - - if (strcmp(att->descr.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0 && strcmp(att->descr.transfer_encoding.c_str(), att->descr.content_encoding.c_str()) != 0) - { - esp_mail_smtp_send_base64_data_info_t data_info; - - data_info.filename = att->descr.filename.c_str(); - data_info.storageType = att->file.storage_type; - - if (!sendBase64(smtp, msg, data_info, true, cb)) - return false; - - return true; - } - else - { - if (mbfs->size(mbfs_type att->file.storage_type) > 0) - { - if (strcmp(att->descr.content_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) - { - esp_mail_smtp_send_base64_data_info_t data_info; - - data_info.filename = att->descr.filename.c_str(); - data_info.storageType = att->file.storage_type; - - if (!sendBase64(smtp, msg, data_info, false, cb)) - return false; - - return true; - } - else - { - int chunkSize = ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE; - int writeLen = 0; - - int fileSize = mbfs->size(mbfs_type att->file.storage_type); - - if (fileSize < chunkSize) - chunkSize = fileSize; - - uint8_t *buf = allocMem(chunkSize); - - while (writeLen < fileSize && mbfs->available(mbfs_type att->file.storage_type)) - { - if (writeLen > fileSize - chunkSize) - chunkSize = fileSize - writeLen; - int readLen = mbfs->read(mbfs_type att->file.storage_type, buf, chunkSize); - if (readLen != chunkSize) - { - errorStatusCB(smtp, this->imap, MB_FS_ERROR_FILE_IO_ERROR, false); - break; - } - - if (!sendBDAT(smtp, msg, chunkSize, false)) - break; - - if (!altSendData(buf, chunkSize, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - break; - - if (smtp->_debug) - uploadReport(att->descr.filename.c_str(), addr, 100 * writeLen / fileSize); - - writeLen += chunkSize; - } - - // release memory - freeMem(&buf); - - if (smtp->_debug) - uploadReport(att->descr.filename.c_str(), addr, 100); - - return writeLen == fileSize; - } - } - return false; - } - return false; -} - -bool ESP_Mail_Client::sendParallelAttachments(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary) -{ - if (msg->_parallel.size() == 0) - return true; - - MB_String parallel = getMIMEBoundary(15); - MB_String buf; - - appendBoundaryString(buf, boundary.c_str(), false, true); - - appendMultipartContentType(buf, esp_mail_multipart_type_parallel, parallel.c_str()); - - if (!sendBDAT(smtp, msg, buf.length(), false)) - return false; - - if (!altSendData(buf, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - - if (!sendAttachments(smtp, msg, parallel, true)) - return addSendingResult(smtp, msg, false, true); - - buf.clear(); - appendBoundaryString(buf, parallel.c_str(), true, false); - - if (!sendBDAT(smtp, msg, buf.length(), false)) - return false; - - if (!altSendData(buf, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - - return true; -} - -bool ESP_Mail_Client::sendAttachments(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, bool parallel) -{ - MB_String s; - MB_String buf; - int cnt = 0; - - SMTP_Attachment *att = nullptr; - - size_t sz = msg->_att.size(); - if (parallel) - sz = msg->_parallel.size(); - - for (size_t i = 0; i < sz; i++) - { - if (parallel) - att = &msg->_parallel[i]; - else - att = &msg->_att[i]; - - if (att->_int.att_type == esp_mail_att_type_attachment) - { -#if !defined(SILENT_MODE) - altSendCallback(smtp, att->descr.filename.c_str(), att->descr.filename.c_str(), esp_mail_debug_tag_type_client, true, false); -#endif - cnt++; - - if (att->file.storage_type == esp_mail_file_storage_type_none) - { - if (!att->blob.data) - continue; - - if (att->blob.size == 0) - continue; - - buf.clear(); - getAttachHeader(buf, boundary, att, att->blob.size, false); - - if (!sendBDAT(smtp, msg, buf.length(), false)) - return false; - - if (!altSendData(buf, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - - if (!sendBlobAttachment(smtp, msg, att)) - return false; - - if (!sendBDAT(smtp, msg, 2, false)) - return false; - - MB_String str; - appendNewline(str); - - if (!altSendData(str, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - } - else - { - if (att->file.storage_type == esp_mail_file_storage_type_sd && !smtp->_sdStorageChecked && !smtp->_sdStorageReady) - { - smtp->_sdStorageChecked = true; - smtp->_sdStorageReady = mbfs->sdReady(); - } - else if (att->file.storage_type == esp_mail_file_storage_type_flash && !smtp->_flashStorageChecked && !smtp->_flashStorageReady) - { - smtp->_flashStorageChecked = true; - smtp->_flashStorageReady = mbfs->flashReady(); - } - - if (!smtp->_flashStorageReady && !smtp->_sdStorageReady) - { - sendStorageNotReadyError(smtp, att->file.storage_type); - continue; - } - - if (openFileRead(smtp, msg, att, buf, boundary, false)) - { - - if (!sendFile(smtp, msg, att)) - return false; - - if (!sendBDAT(smtp, msg, 2, false)) - return false; - - MB_String str; - appendNewline(str); - - if (!altSendData(str, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - } - } - } - } - return true; -} - -void ESP_Mail_Client::altSendStorageErrorCB(SMTPSession *smtp, int err) -{ -#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) - - if (smtp) - { - smtp->_responseStatus.errorCode = err; - smtp->_responseStatus.text.clear(); - -#if !defined(SILENT_MODE) - if (smtp->_statusCallback) - esp_mail_debug_print_tag(esp_mail_error_mem_str_3 /* "file does not exist or can't access" */, esp_mail_debug_tag_type_client, true); - - if (smtp->_debug) - esp_mail_debug_print_tag(smtp->errorReason().c_str(), esp_mail_debug_tag_type_error, true); -#endif - } - else if (imap && !calDataLen) - { -#if defined(ENABLE_IMAP) - - imap->_responseStatus.errorCode = err; - imap->_responseStatus.text.clear(); - -#if !defined(SILENT_MODE) - if (imap->_statusCallback) - esp_mail_debug_print_tag(esp_mail_error_mem_str_3 /* "file does not exist or can't access" */, esp_mail_debug_tag_type_client, true); - - if (imap->_debug) - { - esp_mail_debug_print_tag(smtp->errorReason().c_str(), esp_mail_debug_tag_type_error, true); - } -#endif -#endif - } - -#endif -} - -bool ESP_Mail_Client::openFileRead(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att, MB_String &buf, const MB_String &boundary, bool inlined) -{ - int sz = -1; - MB_String filepath; - - if (att->file.path.length() > 0) - { - if (att->file.path[0] != '/') - filepath = esp_mail_str_10; /* "/" */ - filepath += att->file.path; - } - - sz = mbfs->open(filepath, mbfs_type att->file.storage_type, mb_fs_open_mode_read); - if (sz < 0) - { - - if (strlen(att->descr.filename.c_str()) > 0) - { - filepath.clear(); - if (att->descr.filename[0] != '/') - filepath = esp_mail_str_10; /* "/" */ - filepath += att->descr.filename; - } - - sz = mbfs->open(filepath, mbfs_type att->file.storage_type, mb_fs_open_mode_read); - } - - if (sz < 0) - { - altSendStorageErrorCB(smtp, sz); - } - else - { - - buf.clear(); - - getAttachHeader(buf, boundary, att, sz, inlined); - - if (!sendBDAT(smtp, msg, buf.length(), false)) - return false; - - if (!altSendData(buf, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - - return true; - } - - return false; -} - -bool ESP_Mail_Client::openFileRead2(SMTPSession *smtp, SMTP_Message *msg, const char *path, esp_mail_file_storage_type storageType) -{ - - MB_String filepath; - - if (strlen(path) > 0) - { - if (path[0] != '/') - filepath = esp_mail_str_10; /* "/" */ - filepath += path; - } - - int sz = mbfs->open(filepath, mbfs_type storageType, mb_fs_open_mode_read); - if (sz < 0) - { - altSendStorageErrorCB(smtp, sz); - return false; - } - - return true; -} - -void ESP_Mail_Client::sendStorageNotReadyError(SMTPSession *smtp, esp_mail_file_storage_type storageType) -{ - -#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) - -#if !defined(SILENT_MODE) - if (altIsCB(smtp)) - { - if (storageType == esp_mail_file_storage_type_flash) - { - esp_mail_debug_print_tag(esp_mail_error_mem_str_1 /* "flash Storage is not ready." */, esp_mail_debug_tag_type_error, true); -#if defined(MB_ARDUINO_PICO) - esp_mail_debug_print_tag(esp_mail_error_mem_str_10 /* "please make sure that the size of flash filesystem is not 0 in Pico." */, esp_mail_debug_tag_type_error, true); -#endif - } - else if (storageType == esp_mail_file_storage_type_sd) - esp_mail_debug_print_tag(esp_mail_error_mem_str_2 /* "SD Storage is not ready." */, esp_mail_debug_tag_type_error, true); - } - - if (altIsDebug(smtp)) - { - if (storageType == esp_mail_file_storage_type_flash) - { - esp_mail_debug_print_tag(esp_mail_error_mem_str_1 /* "flash Storage is not ready." */, esp_mail_debug_tag_type_error, true); -#if defined(MB_ARDUINO_PICO) - esp_mail_debug_print_tag(esp_mail_error_mem_str_10 /* "please make sure that the size of flash filesystem is not 0 in Pico." */, esp_mail_debug_tag_type_error, true); -#endif - } - else if (storageType == esp_mail_file_storage_type_sd) - esp_mail_debug_print_tag(esp_mail_error_mem_str_2 /* "SD Storage is not ready." */, esp_mail_debug_tag_type_error, true); - } -#endif - -#endif -} - -bool ESP_Mail_Client::sendInline(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, byte type) -{ - size_t num = numAtt(smtp, esp_mail_att_type_inline, msg) > 0; - -#if !defined(SILENT_MODE) - if (num > 0) - altSendCallback(smtp, esp_mail_cb_str_8 /* "Sending inline data..." */, esp_mail_dbg_str_14 /* "send inline data" */, esp_mail_debug_tag_type_client, true, false); -#endif - MB_String buf; - MB_String related = getMIMEBoundary(15); - int cnt = 0; - SMTP_Attachment *att = nullptr; - - MB_String s; - - appendBoundaryString(s, boundary.c_str(), false, true); - - appendMultipartContentType(s, esp_mail_multipart_type_related, related.c_str()); - - if (!sendBDAT(smtp, msg, s.length(), false)) - return false; - - if (!altSendData(s, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - - if (!sendPartText(smtp, msg, type, related.c_str())) - return false; - -#if !defined(SILENT_MODE) - bool cb = altIsCB(smtp); - - if (cb && numAtt(smtp, esp_mail_att_type_inline, msg) > 0) - esp_mail_debug_print(); -#endif - - if (num > 0) - { - for (uint8_t i = 0; i < msg->_att.size(); i++) - { - att = &msg->_att[i]; - if (att->_int.att_type == esp_mail_att_type_inline) - { -#if !defined(SILENT_MODE) - altSendCallback(smtp, att->descr.filename.c_str(), att->descr.filename.c_str(), esp_mail_debug_tag_type_client, true, false); -#endif - cnt++; - - if (att->file.storage_type == esp_mail_file_storage_type_none) - { - if (!att->blob.data) - continue; - - if (att->blob.size == 0) - continue; -#if !defined(SILENT_MODE) - altSendCallback(smtp, att->descr.filename.c_str(), att->descr.filename.c_str(), esp_mail_debug_tag_type_client, true, false); -#endif - buf.clear(); - getAttachHeader(buf, related, att, att->blob.size, true); - - if (!sendBDAT(smtp, msg, buf.length(), false)) - return false; - - if (!altSendData(buf, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - - if (!sendBlobAttachment(smtp, msg, att)) - return false; - - if (!sendBDAT(smtp, msg, 2, false)) - return false; - - MB_String str; - appendNewline(str); - - if (!altSendData(str, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - } - else - { - - if (att->file.storage_type == esp_mail_file_storage_type_sd && !smtp->_sdStorageChecked && !smtp->_sdStorageReady) - { - smtp->_sdStorageChecked = true; - smtp->_sdStorageReady = mbfs->sdReady(); - } - else if (att->file.storage_type == esp_mail_file_storage_type_flash && !smtp->_flashStorageChecked && !smtp->_flashStorageReady) - { - smtp->_flashStorageChecked = true; - smtp->_flashStorageReady = mbfs->flashReady(); - } - - if (!smtp->_flashStorageReady && !smtp->_sdStorageReady) - { - sendStorageNotReadyError(smtp, att->file.storage_type); - continue; - } - - if (openFileRead(smtp, msg, att, buf, related, true)) - { - if (!sendFile(smtp, msg, att)) - return false; - - if (!sendBDAT(smtp, msg, 2, false)) - return false; - - MB_String str; - appendNewline(str); - - if (!altSendData(str, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - } - } - } - } - } - - appendNewline(s); - - appendBoundaryString(s, related.c_str(), true, true); - - if (!sendBDAT(smtp, msg, s.length(), false)) - return false; - - if (!altSendData(s, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - - return true; -} - -size_t ESP_Mail_Client::smtpSend(SMTPSession *smtp, PGM_P data, bool newline) -{ - if (!smtp || !sessionReady(smtp)) - return 0; - - int sent = 0; - - MB_String s = data; - - int toSend = newline ? s.length() + 2 : s.length(); - -#if !defined(SILENT_MODE) - if (!smtp->_customCmdResCallback && smtp->_debugLevel > esp_mail_debug_level_maintainer) - esp_mail_debug_print(s.c_str(), newline); -#endif - - sent = newline ? smtp->client.println(s.c_str()) : smtp->client.print(s.c_str()); - - if (sent != toSend) - { - errorStatusCB(smtp, this->imap, sent, false); - sent = 0; - } - - return sent; -} - -size_t ESP_Mail_Client::smtpSend(SMTPSession *smtp, int data, bool newline) -{ - MB_String s = data; - return smtpSend(smtp, s.c_str(), newline); -} - -size_t ESP_Mail_Client::smtpSend(SMTPSession *smtp, uint8_t *data, size_t size) -{ - if (!smtp || !sessionReady(smtp)) - return 0; - - size_t sent = smtp->client.write(data, size); - - if (sent != size) - { - errorStatusCB(smtp, this->imap, sent, false); - sent = 0; - } - - return sent; -} - -bool ESP_Mail_Client::handleSMTPError(SMTPSession *smtp, int err, bool ret) -{ - - if (err < 0) - errorStatusCB(smtp, this->imap, err, false); - - if (smtp) - { - closeTCPSession(smtp); - } - else if (imap && !calDataLen) - { -#if defined(ENABLE_IMAP) - if (imap->connected()) - closeTCPSession(imap); -#endif - } - - return ret; -} - -bool ESP_Mail_Client::sendPartText(SMTPSession *smtp, SMTP_Message *msg, uint8_t type, const char *boundary) -{ - MB_String header; - - if (strlen(boundary) > 0) - appendBoundaryString(header, boundary, false, true); - - if (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) - { - if (msg->text.content_type.length() > 0) - { - appendHeaderField(header, message_headers[esp_mail_message_header_field_content_type].text, msg->text.content_type.c_str(), false, false); - - bool firstProp = true; - - if (msg->text.charSet.length() > 0) - appendHeaderProp(header, message_headers[esp_mail_message_header_field_charset].text, msg->text.charSet.c_str(), firstProp, true, true, false); - - if (msg->text.flowed) - { - appendHeaderProp(header, message_headers[esp_mail_message_header_field_format].text, "flowed", firstProp, true, true, false); - appendHeaderProp(header, message_headers[esp_mail_message_header_field_delsp].text, "no", firstProp, true, true, false); - } - - if (msg->text.embed.enable) - { - appendHeaderProp(header, message_headers[esp_mail_message_header_field_name].text, esp_mail_str_13 /* "msg.txt" */, firstProp, false, true, false); - char *uid = getRandomUID(); - msg->text._int.cid = uid; - // release memory - freeMem(&uid); - } - - appendNewline(header); - } - - if (msg->text.transfer_encoding.length() > 0) - appendHeaderField(header, message_headers[esp_mail_message_header_field_content_transfer_encoding].text, msg->text.transfer_encoding.c_str(), false, true); - } - else if (type == esp_mail_msg_type_html) - { - if (msg->text.content_type.length() > 0) - { - appendHeaderField(header, message_headers[esp_mail_message_header_field_content_type].text, msg->html.content_type.c_str(), false, false); - bool firstProp = true; - - if (msg->html.charSet.length() > 0) - appendHeaderProp(header, message_headers[esp_mail_message_header_field_charset].text, msg->html.charSet.c_str(), firstProp, true, true, false); - - if (msg->html.embed.enable) - { - appendHeaderProp(header, message_headers[esp_mail_message_header_field_name].text, esp_mail_str_14 /* "msg.html" */, firstProp, true, true, false); - char *uid = getRandomUID(); - msg->html._int.cid = uid; - // release memory - freeMem(&uid); - } - - appendNewline(header); - } - - if (msg->html.transfer_encoding.length() > 0) - appendHeaderField(header, message_headers[esp_mail_message_header_field_content_transfer_encoding].text, msg->html.transfer_encoding.c_str(), false, true); - } - - if ((type == esp_mail_msg_type_html && msg->html.embed.enable) || ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) && msg->text.embed.enable)) - { - - if ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) && msg->text.embed.enable) - appendEmbedMessage(header, msg->text, false); - else if (type == esp_mail_msg_type_html && msg->html.embed.enable) - appendEmbedMessage(header, msg->html, true); - } - - appendNewline(header); - - bool rawBlob = (msg->text.blob.size > 0 && (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched)) || (msg->html.blob.size > 0 && type == esp_mail_msg_type_html); - bool rawFile = (msg->text.file.name.length() > 0 && (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched)) || (msg->html.file.name.length() > 0 && type == esp_mail_msg_type_html); - bool rawContent = ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) && msg->text.content.length() > 0) || (type == esp_mail_msg_type_html && msg->html.content.length() > 0); - bool nonCopyContent = ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) && strlen(msg->text.nonCopyContent) > 0) || (type == esp_mail_msg_type_html && strlen(msg->html.nonCopyContent) > 0); - - if (rawBlob || rawFile || nonCopyContent) - { - if (!sendBDAT(smtp, msg, header.length(), false)) - return false; - - if (!altSendData(header, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - - header.clear(); - - if (rawBlob || nonCopyContent) - { - if (!sendBlobBody(smtp, msg, type)) - return false; - } - else if (rawFile) - { - if (!sendFileBody(smtp, msg, type)) - return false; - } - } - else if (rawContent) - encodingText(smtp, msg, type, header); - - appendNewline(header); - - if (strlen(boundary) > 0) - appendNewline(header); - - if (!sendBDAT(smtp, msg, header.length(), false)) - return false; - - if (!altSendData(header, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - - return true; -} - -bool ESP_Mail_Client::sendBlobBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type) -{ - - bool cb = altIsCB(smtp); - uint32_t addr = altProgressPtr(smtp); - - if (msg->text.blob.size == 0 && msg->html.blob.size == 0 && strlen(msg->text.nonCopyContent) == 0 && strlen(msg->html.nonCopyContent) == 0) - return true; - - bool ret = true; - int bufLen = 512; - size_t pos = 0; - - const uint8_t *raw = NULL; - int len = 0; - bool base64 = false; - - if ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched)) - { - if (strlen(msg->text.nonCopyContent) > 0) - { - raw = (const uint8_t *)msg->text.nonCopyContent; - len = strlen(msg->text.nonCopyContent); - } - else - { - raw = msg->text.blob.data; - len = msg->text.blob.size; - } - base64 = msg->text.transfer_encoding.length() > 0 && strcmp(msg->text.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0; - } - else if (type == esp_mail_msg_type_html) - { - if (strlen(msg->html.nonCopyContent) > 0) - { - raw = (const uint8_t *)msg->html.nonCopyContent; - len = strlen(msg->html.nonCopyContent); - } - else - { - raw = msg->html.blob.data; - len = msg->html.blob.size; - } - base64 = msg->html.transfer_encoding.length() > 0 && strcmp(msg->html.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0; - } - - if (base64) - { - MB_String s1 = esp_mail_str_15; /* "flash content message" */ - - esp_mail_smtp_send_base64_data_info_t data_info; - - data_info.flashMem = true; - data_info.filename = s1.c_str(); - data_info.rawPtr = raw; - data_info.size = len; - - return sendBase64(smtp, msg, data_info, true, cb); - } - - int available = len; - int sz = len; - uint8_t *buf = allocMem(bufLen + 1); - while (available) - { - if (available > bufLen) - available = bufLen; - - memcpy_P(buf, raw + pos, available); - - if (!sendBDAT(smtp, msg, available, false)) - { - ret = false; - break; - } - - if (!altSendData(buf, available, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - { - ret = false; - break; - } - - pos += available; - len -= available; - available = len; - - if (smtp->_debug) - { - MB_String s1 = esp_mail_str_15; /* "flash content message" */ - uploadReport(s1.c_str(), addr, 100 * pos / sz); - } - } - - // release memory - freeMem(&buf); - - return ret; -} - -bool ESP_Mail_Client::sendFileBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type) -{ - bool cb = altIsCB(smtp); - uint32_t addr = altProgressPtr(smtp); - - if (msg->text.file.name.length() == 0 && msg->html.file.name.length() == 0) - return true; - - bool ret = true; - int chunkSize = ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE; - int writeLen = 0; - - if (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) - { - - if (!openFileRead2(smtp, msg, msg->text.file.name.c_str(), msg->text.file.type)) - return false; - - if (msg->text.transfer_encoding.length() > 0) - { - if (strcmp(msg->text.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) - { - MB_String s1 = esp_mail_str_16; /* "file content message" */ - - esp_mail_smtp_send_base64_data_info_t data_info; - - data_info.filename = s1.c_str(); - data_info.storageType = msg->text.file.type; - - return sendBase64(smtp, msg, data_info, true, cb); - } - } - - int fileSize = mbfs->size(mbfs_type msg->text.file.type); - - if (fileSize > 0) - { - - if (fileSize < chunkSize) - chunkSize = fileSize; - - uint8_t *buf = allocMem(chunkSize); - - while (writeLen < fileSize && mbfs->available(mbfs_type msg->text.file.type)) - { - if (writeLen > fileSize - chunkSize) - chunkSize = fileSize - writeLen; - int readLen = mbfs->read(mbfs_type msg->text.file.type, buf, chunkSize); - - if (readLen != chunkSize) - { - errorStatusCB(smtp, this->imap, MB_FS_ERROR_FILE_IO_ERROR, false); - break; - } - - if (!sendBDAT(smtp, msg, chunkSize, false)) - { - ret = false; - break; - } - - if (!altSendData(buf, chunkSize, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - { - ret = false; - break; - } - - if (smtp->_debug) - uploadReport(pgm2Str(esp_mail_str_16 /* "file content message" */), addr, 100 * writeLen / fileSize); - - writeLen += chunkSize; - } - - // release memory - freeMem(&buf); - - if (smtp->_debug) - uploadReport(pgm2Str(esp_mail_str_16 /* "file content message" */), addr, 100); - - return ret && writeLen == fileSize; - } - } - else if (type == esp_mail_message_type::esp_mail_msg_type_html) - { - - if (!openFileRead2(smtp, msg, msg->html.file.name.c_str(), msg->html.file.type)) - return false; - - if (msg->html.transfer_encoding.length() > 0) - { - if (strcmp(msg->html.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) - { - MB_String s1 = esp_mail_str_16; /* "file content message" */ - - esp_mail_smtp_send_base64_data_info_t data_info; - - data_info.filename = s1.c_str(); - data_info.storageType = msg->html.file.type; - - return sendBase64(smtp, msg, data_info, true, cb); - } - } - - int fileSize = mbfs->size(mbfs_type msg->html.file.type); - - if (fileSize > 0) - { - - if (fileSize < chunkSize) - chunkSize = fileSize; - - uint8_t *buf = allocMem(chunkSize); - - while (writeLen < fileSize && mbfs->available(mbfs_type msg->html.file.type)) - { - if (writeLen > fileSize - chunkSize) - chunkSize = fileSize - writeLen; - int readLen = mbfs->read(mbfs_type msg->html.file.type, buf, chunkSize); - - if (readLen != chunkSize) - { - errorStatusCB(smtp, this->imap, MB_FS_ERROR_FILE_IO_ERROR, false); - break; - } - - if (!sendBDAT(smtp, msg, chunkSize, false)) - { - ret = false; - break; - } - - if (!altSendData(buf, chunkSize, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - { - ret = false; - break; - } - - if (cb) - uploadReport(pgm2Str(esp_mail_str_16 /* "file content message" */), addr, 100 * writeLen / fileSize); - - writeLen += chunkSize; - } - - // release memory - freeMem(&buf); - - if (cb) - uploadReport(pgm2Str(esp_mail_str_16 /* "file content message" */), addr, 100); - - return ret && writeLen == fileSize; - } - } - - return false; -} - -void ESP_Mail_Client::encodingText(SMTPSession *smtp, SMTP_Message *msg, uint8_t type, MB_String &content) -{ - if (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) - { - MB_String s = msg->text.content; - - if (msg->text.flowed) - formatFlowedText(s); - - if (msg->text.transfer_encoding.length() > 0) - { - if (strcmp(msg->text.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) - content += encodeBase64Str((const unsigned char *)s.c_str(), s.length()); - else if (strcmp(msg->text.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_qp) == 0) - { - char *out = allocMem(s.length() * 3 + 1); - encodeQP(s.c_str(), out); - content += out; - - // release memory - freeMem(&out); - } - else - content += s; - } - else - content += s; - } - else if (type == esp_mail_message_type::esp_mail_msg_type_html) - { - MB_String s = msg->html.content; - MB_String fnd, rep; - SMTP_Attachment *att = nullptr; - for (uint8_t i = 0; i < msg->_att.size(); i++) - { - att = &msg->_att[i]; - if (att->_int.att_type == esp_mail_att_type_inline) - { - MB_String filename(att->descr.filename); - - size_t found = filename.find_last_of("/\\"); - if (found != MB_String::npos) - filename = filename.substr(found + 1); - - appendString(fnd, filename.c_str(), false, false, esp_mail_string_mark_type_double_quote); - - MB_String cid = esp_mail_str_17; /* "cid:" */ - cid += att->descr.content_id.length() > 0 ? att->descr.content_id : att->_int.cid; - - appendString(rep, cid.c_str(), false, false, esp_mail_string_mark_type_double_quote); - - s.replaceAll(fnd, rep); - } - } - - if (msg->html.transfer_encoding.length() > 0) - { - if (strcmp(msg->html.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) - content += encodeBase64Str((const unsigned char *)s.c_str(), s.length()); - else if (strcmp(msg->html.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_qp) == 0) - { - char *out = allocMem(msg->html.content.length() * 3 + 1); - encodeQP(msg->html.content.c_str(), out); - content += out; - - // release memory - freeMem(&out); - } - else - content += s; - } - else - content += s; - s.clear(); - } - - if (msg->timestamp.tag.length() && msg->timestamp.format.length()) - content.replaceAll(msg->timestamp.tag, Time.getDateTimeString(Time.getCurrentTimestamp(), msg->timestamp.format.c_str())); -} - -void ESP_Mail_Client::encodeQP(const char *buf, char *out) -{ - int n = 0, p = 0, pos = 0; - for (n = 0; *buf; buf++) - { - if (n >= 73 && *buf != 10 && *buf != 13) - { - p = sprintf(out + pos, "=\r\n"); - pos += p; - n = 0; - } - - if (*buf == 10 || *buf == 13) - { - out[pos++] = *buf; - n = 0; - } - else if (*buf < 32 || *buf == 61 || *buf > 126) - { - p = sprintf(out + pos, "=%02X", (unsigned char)*buf); - n += p; - pos += p; - } - else if (*buf != 32 || (*(buf + 1) != 10 && *(buf + 1) != 13)) - { - out[pos++] = *buf; - n++; - } - else - { - p = sprintf(out + pos, "=20"); - n += p; - pos += p; - } - } -} - -/** Add the soft line break to the long text line (rfc 3676) - * and add Format=flowed parameter in the plain text content-type header. - * We use the existing white space as a part of this soft line break - * and set delSp="no" parameter to the header. - * - * Some servers are not rfc 3676 compliant. - * This causes the text lines are wrapped instead of joined. - * - * Some mail clients trim the space before the line break - * which makes the soft line break cannot be seen. - */ -void ESP_Mail_Client::formatFlowedText(MB_String &content) -{ - int count = 0; - MB_String qms; - int j = 0; - _vectorImpl tokens; - char *stk = strP(esp_mail_str_18); /* "\r\n" */ - char *qm = strP(esp_mail_str_20); /* ">" */ - splitToken(content.c_str(), tokens, stk); - content.clear(); - for (size_t i = 0; i < tokens.size(); i++) - { - if (tokens[i].length() > 0) - { - j = 0; - qms.clear(); - while (tokens[i][j] == qm[0]) - { - qms += qm; - j++; - } - softBreak(tokens[i], qms.c_str()); - if (count > 0) - content += stk; - content += tokens[i]; - } - else if (count > 0) - content += stk; - count++; - } - - // release memory - freeMem(&stk); - freeMem(&qm); - tokens.clear(); -} - -void ESP_Mail_Client::softBreak(MB_String &content, const char *quoteMarks) -{ - size_t len = 0; - char *stk = strP(esp_mail_str_2); /* " " */ - _vectorImpl tokens; - splitToken(content.c_str(), tokens, stk); - content.clear(); - for (size_t i = 0; i < tokens.size(); i++) - { - if (tokens[i].length() > 0) - { - if (len + tokens[i].length() + 3 > FLOWED_TEXT_LEN) - { - /* insert soft crlf */ - content += stk; - appendNewline(content); - - /* insert quote marks */ - if (strlen(quoteMarks) > 0) - content += quoteMarks; - content += tokens[i]; - len = tokens[i].length(); - } - else - { - if (len > 0) - { - content += stk; - len += strlen(stk); - } - content += tokens[i]; - len += tokens[i].length(); - } - } - } - - // release memory - freeMem(&stk); - tokens.clear(); -} - -bool ESP_Mail_Client::altSendData(MB_String &s, bool newLine, SMTPSession *smtp, SMTP_Message *msg, bool addSendResult, bool getResponse, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode) -{ - if (!imap && smtp) - { - if (smtpSend(smtp, s.c_str(), newLine) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - { - if (addSendResult) - return addSendingResult(smtp, msg, false, true); - else - return false; - } - - if (getResponse) - { - if (!handleSMTPResponse(smtp, cmd, statusCode, errCode)) - { - if (addSendResult) - return addSendingResult(smtp, msg, false, true); - else - return false; - } - } - } - else if (imap) - { -#if defined(ENABLE_IMAP) - if (newLine) - appendNewline(s); - MB_StringPtr data = toStringPtr(s); - - if (calDataLen) - dataLen += s.length(); - else - return imap->mSendData(data, false, esp_mail_imap_cmd_append); -#endif - } - - return true; -} - -bool ESP_Mail_Client::altSendData(uint8_t *data, size_t size, SMTPSession *smtp, SMTP_Message *msg, bool addSendResult, bool getResponse, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode) -{ - if (!imap && smtp) - { - if (smtpSend(smtp, data, size) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - { - if (addSendResult) - return addSendingResult(smtp, msg, false, true); - else - return false; - } - - if (getResponse) - { - if (!handleSMTPResponse(smtp, cmd, statusCode, errCode)) - { - if (addSendResult) - return addSendingResult(smtp, msg, false, true); - else - return false; - } - } - } - else if (imap) - { -#if defined(ENABLE_IMAP) - - if (calDataLen) - dataLen += size; - else - return imap->mSendData(data, size, false, esp_mail_imap_cmd_append); -#endif - } - - return true; -} - -bool ESP_Mail_Client::sendMSG(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary) -{ - MB_String s; - - if (numAtt(smtp, esp_mail_att_type_inline, msg) > 0) - { - appendMultipartContentType(s, esp_mail_multipart_type_alternative, boundary.c_str()); - - if (!sendBDAT(smtp, msg, s.length(), false)) - return false; - - if (!altSendData(s, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - - if (msg->type == esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched || msg->type == esp_mail_msg_type_html) - { - if (!sendInline(smtp, msg, boundary, msg->type)) - return false; - } - else if (msg->type == (esp_mail_msg_type_html | esp_mail_msg_type_enriched | esp_mail_msg_type_plain)) - { - if (!sendPartText(smtp, msg, esp_mail_msg_type_plain, boundary.c_str())) - return false; - if (!sendInline(smtp, msg, boundary, esp_mail_msg_type_html)) - return false; - } - - appendBoundaryString(s, boundary.c_str(), true, true); - - if (!sendBDAT(smtp, msg, s.length(), false)) - return false; - - if (!altSendData(s, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - } - else - { - if (msg->type == esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched || msg->type == esp_mail_msg_type_html) - { - if (!sendPartText(smtp, msg, msg->type, "")) - return false; - } - else if (msg->type == (esp_mail_msg_type_html | esp_mail_msg_type_enriched | esp_mail_msg_type_plain)) - { - appendMultipartContentType(s, esp_mail_multipart_type_alternative, boundary.c_str()); - - if (!sendBDAT(smtp, msg, s.length(), false)) - return false; - - if (!altSendData(s, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - - if (!sendPartText(smtp, msg, esp_mail_msg_type_plain, boundary.c_str())) - return false; - - if (!sendPartText(smtp, msg, esp_mail_msg_type_html, boundary.c_str())) - return false; - - s.clear(); - appendBoundaryString(s, boundary.c_str(), true, false); - - if (!sendBDAT(smtp, msg, s.length(), false)) - return false; - - if (!altSendData(s, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - return false; - } - } - return true; -} - -void ESP_Mail_Client::getAttachHeader(MB_String &header, const MB_String &boundary, SMTP_Attachment *attach, size_t size, bool isInline) -{ - appendBoundaryString(header, boundary.c_str(), false, true); - - appendHeaderName(header, message_headers[esp_mail_message_header_field_content_type].text); - - if (attach->descr.mime.length() == 0) - { - MB_String mime; - mimeFromFile(attach->descr.filename.c_str(), mime); - if (mime.length() > 0) - appendString(header, mime.c_str(), false, false); - else - appendString(header, mimeinfo[esp_mail_file_extension_binary].mimeType, false, false); - } - else - appendString(header, attach->descr.mime.c_str(), false, false); - - MB_String filename = attach->descr.filename; - - size_t found = filename.find_last_of("/\\"); - if (found != MB_String::npos) - filename = filename.substr(found + 1); - - bool firstProp = true; - - appendHeaderProp(header, message_headers[esp_mail_message_header_field_name].text, filename.c_str(), firstProp, false, true, true); - - if (isInline || (!isInline && !attach->_int.parallel)) - { - appendHeaderName(header, message_headers[esp_mail_message_header_field_content_disposition].text); - appendString(header, isInline ? esp_mail_content_disposition_type_t::inline_ : esp_mail_content_disposition_type_t::attachment, false, false); - - firstProp = true; - appendHeaderProp(header, message_headers[esp_mail_message_header_field_filename].text, filename.c_str(), firstProp, true, true, false); - appendHeaderProp(header, message_headers[esp_mail_message_header_field_size].text, MB_String((int)size).c_str(), firstProp, true, false, true); - } - - if (isInline) - { - - appendHeaderField(header, message_headers[esp_mail_message_header_field_content_location].text, filename.c_str(), false, true); - - appendHeaderName(header, message_headers[esp_mail_message_header_field_content_id].text); - if (attach->descr.content_id.length() > 0) - appendString(header, attach->descr.content_id.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); - else - appendString(header, attach->_int.cid.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); - } - - if (attach->descr.transfer_encoding.length() > 0) - appendHeaderField(header, message_headers[esp_mail_message_header_field_content_transfer_encoding].text, attach->descr.transfer_encoding.c_str(), false, true); - - if (attach->descr.description.length() > 0) - appendHeaderField(header, message_headers[esp_mail_message_header_field_content_description].text, attach->descr.description.c_str(), false, true); - - appendNewline(header); -} - -void ESP_Mail_Client::getRFC822PartHeader(SMTPSession *smtp, MB_String &header, const MB_String &boundary) -{ - appendBoundaryString(header, boundary.c_str(), false, true); - - appendHeaderName(header, message_headers[esp_mail_message_header_field_content_type].text); - appendString(header, esp_mail_str_22 /* "message/rfc822" */, false, true); - - appendHeaderName(header, message_headers[esp_mail_message_header_field_content_disposition].text); - appendString(header, esp_mail_content_disposition_type_t::attachment, false, true); - appendNewline(header); -} - -uint32_t ESP_Mail_Client::altProgressPtr(SMTPSession *smtp) -{ - uint32_t addr = 0; - if (smtp) - { - smtp->_lastProgress = -1; - addr = toAddr(smtp->_lastProgress); - } - else if (imap && !calDataLen) - { -#if defined(ENABLE_IMAP) - imap->_lastProgress = -1; - addr = toAddr(imap->_lastProgress); -#endif - } - - return addr; -} - -void ESP_Mail_Client::parseAuthCapability(SMTPSession *smtp, char *buf) -{ - if (!smtp) - return; - - if (strposP(buf, smtp_cmd_post_tokens[esp_mail_smtp_command_auth].c_str(), 0) > -1) - { - for (int i = esp_mail_auth_capability_plain; i < esp_mail_auth_capability_maxType; i++) - { - if (strposP(buf, smtp_auth_cap_pre_tokens[i].c_str(), 0) > -1) - { - smtp->_auth_capability[i] = true; - // Don't exit the loop - // and continue checking for all auth types - } - } - } - else if (strposP(buf, smtp_auth_capabilities[esp_mail_auth_capability_starttls].text, 0) > -1) - { - smtp->_auth_capability[esp_mail_auth_capability_starttls] = true; - return; - } - - for (int i = esp_mail_smtp_send_capability_binary_mime; i < esp_mail_smtp_send_capability_maxType; i++) - { - if (strposP(buf, smtp_send_cap_pre_tokens[i].c_str(), 0) > -1) - { - smtp->_feature_capability[i] = true; - return; - } - } -} - -bool ESP_Mail_Client::handleSMTPResponse(SMTPSession *smtp, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode) -{ - if (!smtp) - return false; - - smtp->_smtp_cmd = cmd; - - if (!reconnect(smtp)) - return false; - - bool ret = false; - char *response = nullptr; - int readLen = 0; - long dataTime = millis(); - int chunkBufSize = 0; - MB_String s, r, err; - int chunkIndex = 0; - int count = 0; - bool completedResponse = false; - smtp->_responseStatus.errorCode = 0; - smtp->_responseStatus.statusCode = 0; - smtp->_responseStatus.text.clear(); - uint8_t minResLen = 5; - struct esp_mail_smtp_response_status_t status; - - bool canForward = smtp->_canForward; - smtp->_canForward = false; - - status.id = smtp->_commandID; - - chunkBufSize = smtp->client.available(); - - while (smtp->connected() && chunkBufSize <= 0) - { - if (!reconnect(smtp, dataTime)) - return false; - if (!connected(smtp)) - { - if (cmd != esp_mail_smtp_cmd_logout) - errorStatusCB(smtp, this->imap, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, false); - - return false; - } - chunkBufSize = smtp->client.available(); - yield_impl(); - } - - dataTime = millis(); - - if (chunkBufSize > 1) - { - while (!completedResponse) - { - yield_impl(); - - if (!reconnect(smtp, dataTime)) - return false; - - if (!connected(smtp)) - { - if (cmd != esp_mail_smtp_cmd_logout) - errorStatusCB(smtp, this->imap, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, false); - return false; - } - - chunkBufSize = smtp->client.available(); - - if (chunkBufSize <= 0) - break; - - if (chunkBufSize > 0) - { - - chunkBufSize = ESP_MAIL_CLIENT_RESPONSE_BUFFER_SIZE; - response = allocMem(chunkBufSize + 1); - - read_line: - - MB_String ovfBuf; - if (!readResponse(smtp, response, chunkBufSize, readLen, false, count, ovfBuf)) - { - closeTCPSession(smtp); - errorStatusCB(smtp, this->imap, MAIL_CLIENT_ERROR_READ_TIMEOUT, false); - return false; - } - - // If buffer overflown, copy from overflow buffer - if (ovfBuf.length() > 0) - { - // release memory - freeMem(&response); - response = allocMem(ovfBuf.length() + 1); - strcpy(response, ovfBuf.c_str()); - ovfBuf.clear(); - } - - if (readLen) - { - if (smtp->_smtp_cmd != esp_mail_smtp_command::esp_mail_smtp_cmd_initial_state) - { - // sometimes server sent multiple lines response - // sometimes rx buffer is not ready for a while - - if (strlen(response) < minResLen) - { - r += response; - chunkBufSize = 0; - while (chunkBufSize == 0) - { - yield_impl(); - if (!reconnect(smtp, dataTime)) - return false; - chunkBufSize = smtp->client.available(); - } - } - else - { - if (r.length() > 0) - { - r += response; - memset(response, 0, chunkBufSize); - strcpy(response, r.c_str()); - } -#if !defined(SILENT_MODE) - if (!smtp->_customCmdResCallback && smtp->_debugLevel > esp_mail_debug_level_basic) - esp_mail_debug_print((const char *)response, true); -#endif - } - - if (smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_greeting) - parseAuthCapability(smtp, response); - } - - getResponseStatus(response, statusCode, 0, status); - - // No response code from greeting? - // Assumed multi-line greeting responses. - - if (status.statusCode == 0 && smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_initial_state) - { - -#if !defined(SILENT_MODE) - if (smtp->_debug && !smtp->_customCmdResCallback) - esp_mail_debug_print_tag(response, esp_mail_debug_tag_type_server, true); -#endif - - memset(response, 0, chunkBufSize + 1); - - // read again until we get the response code - goto read_line; - } - - // get the status code again for unexpected return code - if (smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_start_tls || status.statusCode == 0) - getResponseStatus(response, esp_mail_smtp_status_code_0, 0, status); - - smtp->_responseStatus = status; - - if ((status.statusCode > 0 && status.statusCode == statusCode) || - (smtp->_smtp_cmd == esp_mail_smtp_cmd_start_tls && status.statusCode == esp_mail_smtp_status_code_220) || - (canForward && statusCode == esp_mail_smtp_status_code_250 && status.statusCode == esp_mail_smtp_status_code_251) - - ) - { - ret = true; - } - - if (strlen(response) >= minResLen) - { -#if !defined(SILENT_MODE) - if (smtp->_debug) - { - if (!smtp->_customCmdResCallback) - { - appendDebugTag(s, esp_mail_debug_tag_type_server, true); - if (smtp->_responseStatus.statusCode != esp_mail_smtp_status_code_334) - s += response; - else - { - // base64 encoded server challenge message - size_t olen = 0; - char *decoded = (char *)decodeBase64((const unsigned char *)status.text.c_str(), status.text.length(), &olen); - if (decoded && olen > 0) - { - s.append(decoded, olen); - err = decoded; - } - - // release memory - freeMem(&decoded); - } - esp_mail_debug_print(s.c_str(), true); - } - } - -#endif - r.clear(); - } - - if (smtp->_customCmdResCallback && (smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_initial_state || smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_custom)) - { - struct esp_mail_smtp_response_status_t res = status; - res.text = response; - smtp->_customCmdResCallback(res); - } - - completedResponse = smtp->_responseStatus.statusCode > 0 && status.text.length() > minResLen; - - if (smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_auth_xoauth2 && smtp->_responseStatus.statusCode == esp_mail_smtp_status_code_334) - { - if (isOAuthError(response, readLen, chunkIndex, 4)) - { - smtp->_responseStatus.text = err; - smtp->_responseStatus.errorCode = SMTP_STATUS_XOAUTH2_AUTH_FAILED; - ret = false; - } - } - - chunkIndex++; - - if (smtp->_chunkedEnable && smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_chunk_termination) - completedResponse = smtp->_chunkCount == chunkIndex; - } - - // release memory - freeMem(&response); - } - } - - if (!ret && !smtp->_customCmdResCallback) - handleSMTPError(smtp, errCode, false); - } - - return ret; -} - -void ESP_Mail_Client::getResponseStatus(const char *buf, esp_mail_smtp_status_code statusCode, int beginPos, struct esp_mail_smtp_response_status_t &status) -{ - if (statusCode > esp_mail_smtp_status_code_0) - { - int codeLength = 3; - int textLength = strlen(buf) - codeLength - 1; - - if ((int)strlen(buf) > codeLength && (buf[codeLength] == ' ' || buf[codeLength] == '-') && textLength > 0) - { - char *tmp = nullptr; - tmp = allocMem(codeLength + 1); - memcpy(tmp, &buf[0], codeLength); - - int code = atoi(tmp); - - // release memory - freeMem(&tmp); - - if (buf[codeLength] == ' ') - status.statusCode = code; - - int i = codeLength + 1; - - // We will collect the status text starting from status code 334 and 4xx - // The status text of 334 will be used for debugging display of the base64 server challenge - if (code == esp_mail_smtp_status_code_334 || code >= esp_mail_smtp_status_code_421) - { - // find the next sp - while (i < (int)strlen(buf) && buf[i] != ' ') - i++; - - // if sp found, set index to the next pos, otherwise set index to num length + 1 - i = (i < (int)strlen(buf) - 1) ? i + 1 : codeLength + 1; - - tmp = allocMem(textLength + 1); - memcpy(tmp, &buf[i], strlen(buf) - i - 1); - status.text += tmp; - // release memory - freeMem(&tmp); - } - } - } -} - -void ESP_Mail_Client::uploadReport(const char *filename, uint32_t pgAddr, int progress) -{ - if (pgAddr == 0) - return; - - int *lastProgress = addrTo(pgAddr); - - printProgress(progress, *lastProgress); -} - -MB_String ESP_Mail_Client::getMIMEBoundary(size_t len) -{ - MB_String tmp = boundary_table; - char *buf = allocMem(len); - if (len) - { - --len; - buf[0] = tmp[0]; - buf[1] = tmp[1]; - for (size_t n = 2; n < len; n++) - { - int key = rand() % (int)(tmp.length() - 1); - buf[n] = tmp[key]; - } - buf[len] = '\0'; - } - MB_String s = buf; - // release memory - freeMem(&buf); - return s; -} - -int ESP_Mail_Client::chunkAvailable(SMTPSession *smtp, esp_mail_smtp_send_base64_data_info_t &data_info) -{ - if (!data_info.rawPtr) - { - int fileSize = mbfs->size(mbfs_type data_info.storageType); - if (!fileSize) - { - errorStatusCB(smtp, this->imap, MB_FS_ERROR_FILE_IO_ERROR, false); - return -1; - } - - return mbfs->available(mbfs_type data_info.storageType); - } - - return data_info.size - data_info.dataIndex; -} - -int ESP_Mail_Client::getChunk(SMTPSession *smtp, esp_mail_smtp_send_base64_data_info_t &data_info, unsigned char *rawChunk, bool base64) -{ - int available = chunkAvailable(smtp, data_info); - - if (available <= 0) - return available; - - size_t size = base64 ? 3 : 4; - - if (data_info.dataIndex + size > data_info.size) - size = data_info.size - data_info.dataIndex; - - if (!data_info.rawPtr) - { - - int readLen = mbfs->read(mbfs_type data_info.storageType, rawChunk, size); - - if (readLen >= 0) - data_info.dataIndex += readLen; - - return readLen; - } - - if (data_info.flashMem) - memcpy_P(rawChunk, data_info.rawPtr + data_info.dataIndex, size); - else - memcpy(rawChunk, data_info.rawPtr + data_info.dataIndex, size); - - data_info.dataIndex += size; - - return size; -} - -void ESP_Mail_Client::closeChunk(esp_mail_smtp_send_base64_data_info_t &data_info) -{ - if (!data_info.rawPtr) - { - mbfs->close(mbfs_type data_info.storageType); - } -} - -bool ESP_Mail_Client::sendBase64(SMTPSession *smtp, SMTP_Message *msg, esp_mail_smtp_send_base64_data_info_t &data_info, bool base64, bool report) -{ - int size = chunkAvailable(smtp, data_info); - - if (size <= 0) - return false; - - data_info.size = size; - - bool ret = false; - - uint32_t addr = altProgressPtr(smtp); - - size_t chunkSize = (BASE64_CHUNKED_LEN * UPLOAD_CHUNKS_NUM) + (2 * UPLOAD_CHUNKS_NUM); - int bufIndex = 0; - bool dataReady = false; - int encodedCount = 0; - int read = 0; - - if (!base64) - { - if (data_info.size < chunkSize) - chunkSize = data_info.size; - } - - uint8_t *buf = allocMem(chunkSize); - memset(buf, 0, chunkSize); - - uint8_t *rawChunk = allocMem(base64 ? 3 : 4); - - if (report) - uploadReport(data_info.filename, addr, data_info.dataIndex / data_info.size); - - int min = base64 ? 3 : 1; - - while (chunkAvailable(smtp, data_info)) - { - - if (chunkAvailable(smtp, data_info) >= min) - { - - read = getChunk(smtp, data_info, rawChunk, base64); - - if (!read) - goto ex; - - getBuffer(base64, buf, rawChunk, encodedCount, bufIndex, dataReady, read, chunkSize); - - if (dataReady) - { - - if (!sendBDAT(smtp, msg, base64 ? bufIndex : bufIndex + 1, false)) - goto ex; - - if (!altSendData(buf, base64 ? bufIndex : bufIndex + 1, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - goto ex; - - memset(buf, 0, chunkSize); - bufIndex = 0; - } - - if (report) - uploadReport(data_info.filename, addr, 100 * data_info.dataIndex / data_info.size); - } - else if (base64) - { - read = getChunk(smtp, data_info, rawChunk, base64); - if (!read) - goto ex; - } - } - - closeChunk(data_info); - - if (base64) - { - if (bufIndex > 0) - { - if (!sendBDAT(smtp, msg, bufIndex, false)) - goto ex; - - if (!altSendData(buf, bufIndex, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - goto ex; - } - - if (read) - { - memset(buf, 0, chunkSize); - bufIndex = 0; - buf[bufIndex++] = b64_index_table[rawChunk[0] >> 2]; - if (read == 1) - { - buf[bufIndex++] = b64_index_table[(rawChunk[0] & 0x03) << 4]; - buf[bufIndex++] = '='; - } - else - { - buf[bufIndex++] = b64_index_table[((rawChunk[0] & 0x03) << 4) | (rawChunk[1] >> 4)]; - buf[bufIndex++] = b64_index_table[(rawChunk[1] & 0x0f) << 2]; - } - buf[bufIndex++] = '='; - - if (!sendBDAT(smtp, msg, bufIndex, false)) - goto ex; - - if (!altSendData(buf, bufIndex, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) - goto ex; - } - } - - ret = true; - - if (report) - uploadReport(data_info.filename, addr, 100); - -ex: - // release memory - freeMem(&buf); - freeMem(&rawChunk); - - if (!ret) - closeChunk(data_info); - - return ret; -} - -void ESP_Mail_Client::getBuffer(bool base64, uint8_t *out, uint8_t *in, int &encodedCount, int &bufIndex, bool &dataReady, int &size, size_t chunkSize) -{ - if (base64) - { - size = 0; - out[bufIndex++] = b64_index_table[in[0] >> 2]; - out[bufIndex++] = b64_index_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; - out[bufIndex++] = b64_index_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; - out[bufIndex++] = b64_index_table[in[2] & 0x3f]; - - encodedCount += 4; - - if (encodedCount == BASE64_CHUNKED_LEN) - { - if (bufIndex + 1 < (int)chunkSize) - { - out[bufIndex++] = 0x0d; - out[bufIndex++] = 0x0a; - } - encodedCount = 0; - } - - dataReady = bufIndex >= (int)chunkSize - 4; - } - else - { - memcpy(out + bufIndex, in, size); - bufIndex += size; - - if (bufIndex + 1 == BASE64_CHUNKED_LEN) - { - if (bufIndex + 2 < (int)chunkSize) - { - out[bufIndex++] = 0x0d; - out[bufIndex++] = 0x0a; - } - } - - dataReady = bufIndex + 1 >= (int)chunkSize - size; - } -} - -MB_FS *ESP_Mail_Client::getMBFS() -{ - return mbfs; -} - -SMTPSession::SMTPSession(Client *client) -{ - setClient(client); -} - -SMTPSession::SMTPSession() -{ -} - -SMTPSession::~SMTPSession() -{ - closeSession(); -} - -bool SMTPSession::connect(Session_Config *session_config, bool login) -{ - _sessionSSL = false; - _sessionLogin = login; - - if (session_config) - session_config->clearPorts(); - - this->_customCmdResCallback = NULL; - - int ptr = toAddr(*session_config); - session_config->addPtr(&_configPtrList, ptr); - - if (!handleConnection(session_config, _sessionSSL)) - return false; - - if (!_sessionLogin) - return true; - - _loginStatus = MailClient.smtpAuth(this, _sessionSSL); - - return _loginStatus; -} - -bool SMTPSession::mLogin(MB_StringPtr email, MB_StringPtr password, bool isToken) -{ - if (_loginStatus) - return true; - - if (!MailClient.sessionExisted(this)) - return false; - - _session_cfg->login.email = email; - - _session_cfg->login.accessToken.clear(); - _session_cfg->login.password.clear(); - - if (isToken) - _session_cfg->login.accessToken = password; - else - _session_cfg->login.password = password; - - _loginStatus = MailClient.smtpAuth(this, _sessionSSL); - - return _loginStatus; -} - -bool SMTPSession::isAuthenticated() -{ - return _authenticated; -} - -bool SMTPSession::isLoggedIn() -{ - return _loginStatus; -} - -int SMTPSession::customConnect(Session_Config *session_config, smtpResponseCallback callback, int commandID) -{ - this->_customCmdResCallback = callback; - - if (commandID > -1) - this->_commandID = commandID; - else - this->_commandID++; - - bool ssl = false; - if (!handleConnection(session_config, ssl)) - return -1; - - return this->_responseStatus.statusCode; -} - -bool SMTPSession::handleConnection(Session_Config *session_config, bool &ssl) -{ - _session_cfg = session_config; - - if (!client.isInitialized()) - return MailClient.handleSMTPError(this, TCP_CLIENT_ERROR_NOT_INITIALIZED); - - // Resources are also released if network disconnected. - if (!MailClient.reconnect(this)) - return false; - - // Close previous connection first to free resources. - MailClient.closeTCPSession(this); - - _session_cfg = session_config; - - MailClient.setCert(_session_cfg, _session_cfg->certificate.cert_data); - - ssl = false; - - if (!connect(ssl)) - { - MailClient.closeTCPSession(this); - return false; - } - - return true; -} - -bool SMTPSession::connect(bool &ssl) -{ - if (!MailClient.reconnect(this)) - return false; - - ssl = false; - _secure = true; - bool secureMode = true; - - MB_String s; - - client.rxBufDivider = 16; // minimum rx buffer for smtp status response - client.txBufDivider = 8; // medium tx buffer for faster attachment/inline data transfer - - MailClient.preparePortFunction(_session_cfg, true, _secure, secureMode, ssl); - -#if !defined(SILENT_MODE) - MailClient.printLibInfo(this); -#endif - - MailClient.prepareTime(_session_cfg, this); - - MailClient.setSecure(client, _session_cfg); - - if (!MailClient.beginConnection(_session_cfg, this, secureMode)) - return false; - - // server connected -#if !defined(SILENT_MODE) - if (!_customCmdResCallback) - { - - MailClient.printDebug(this, - esp_mail_dbg_str_4 /* "SMTP server connected" */, - esp_mail_cb_str_12 /* "SMTP server connected, wait for greeting..." */, - esp_mail_debug_tag_type_client, - true, - false); - } -#endif - - client.setTimeout(tcpTimeout); - - // expected success status code 220 for ready to service - // expected failure status code 421 - if (!MailClient.handleSMTPResponse(this, esp_mail_smtp_cmd_initial_state, esp_mail_smtp_status_code_220, SMTP_STATUS_SMTP_GREETING_GET_RESPONSE_FAILED)) - return false; - - return true; -} - -int SMTPSession::mSendCustomCommand(MB_StringPtr cmd, smtpResponseCallback callback, int commandID) -{ - _customCmdResCallback = callback; - - if (commandID > -1) - _commandID = commandID; - else - _commandID++; - - MB_String _cmd = cmd; - - if (MailClient.smtpSend(this, _cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return -1; - - if (!MailClient.handleSMTPResponse(this, esp_mail_smtp_cmd_custom, esp_mail_smtp_status_code_0, SMTP_STATUS_SEND_CUSTOM_COMMAND_FAILED)) - return -1; - - bool tlsCmd = false; - for (int i = esp_mail_auth_capability_plain; i < esp_mail_auth_capability_maxType; i++) - { - if (MailClient.strposP(_cmd.c_str(), smtp_auth_capabilities[i].text, 0) > -1) - { - if (i == esp_mail_auth_capability_starttls) - tlsCmd = true; - else - _waitForAuthenticate = true; - } - } - - if (MailClient.strposP(_cmd.c_str(), smtp_commands[esp_mail_smtp_command_quit].text, 0, false) > -1) - { - _authenticated = false; - _waitForAuthenticate = false; - } - - if (_waitForAuthenticate && _responseStatus.statusCode == esp_mail_smtp_status_code_235) - { - _authenticated = true; - _waitForAuthenticate = false; - _loginStatus = true; - } - - if (tlsCmd) - { - bool verify = false; - - if (_session_cfg) - verify = _session_cfg->certificate.verify; - - if (!client.connectSSL(verify)) - return false; - - // set the secure mode - if (_session_cfg) - { - // We reset the prefer connection mode in case user set it. - _session_cfg->secure.startTLS = false; - _session_cfg->secure.mode = esp_mail_secure_mode_undefined; - } - - _secure = true; - } - - return this->_responseStatus.statusCode; -} - -bool SMTPSession::mSendData(MB_StringPtr data) -{ - - MB_String _data = data; - - if (MailClient.smtpSend(this, _data.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - return true; -} - -bool SMTPSession::mSendData(uint8_t *data, size_t size) -{ - - if (MailClient.smtpSend(this, data, size) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) - return false; - - return true; -} - -void SMTPSession::debug(int level) -{ - if (level > esp_mail_debug_level_none) - { - if (level > esp_mail_debug_level_basic && level < esp_mail_debug_level_maintainer) - level = esp_mail_debug_level_basic; - _debugLevel = level; - _debug = true; - client.setDebugLevel(level); - } - else - { - _debugLevel = esp_mail_debug_level_none; - _debug = false; - client.setDebugLevel(0); - } -} - -String SMTPSession::errorReason() -{ - String s = MailClient.errorReason(true, _responseStatus.errorCode, ""); - return s; -} - -int SMTPSession::statusCode() -{ - return _responseStatus.statusCode; -} - -String SMTPSession::statusMessage() -{ - return _responseStatus.text.c_str(); -} - -int SMTPSession::errorCode() -{ - return _responseStatus.errorCode; -} - -bool SMTPSession::closeSession() -{ - - if (!connected()) - return false; - - _cbData._sentSuccess = _sentSuccessCount; - _cbData._sentFailed = _sentFailedCount; - -#if !defined(SILENT_MODE) - MailClient.printDebug(this, - esp_mail_cb_str_7 /* "Closing the session..." */, - esp_mail_dbg_str_11 /* "terminate the SMTP session" */, - esp_mail_debug_tag_type_client, - true, - false); -#endif - - bool ret = true; - - if (_loginStatus) - { - -/* Sign out */ -#if !defined(ESP8266) - - // QUIT command asks SMTP server to close the TCP session. - // The connection may drop immediately. - - // There is memory leaks bug in ESP8266 BearSSLWiFiClientSecure class when the remote server - // drops the connection. - - ret = MailClient.smtpSend(this, smtp_commands[esp_mail_smtp_command_quit].text, true) > 0; - - // This may return false due to connection drops before get any response. - - // expected success status code 221 - // expected error status code 500 - MailClient.handleSMTPResponse(this, esp_mail_smtp_cmd_logout, esp_mail_smtp_status_code_221, SMTP_STATUS_SEND_BODY_FAILED); - - if (_responseStatus.statusCode == esp_mail_smtp_status_code_500) - return false; -#endif - - if (ret) - { - -#if !defined(SILENT_MODE) - if (_sentSuccessCount > 0) - { - MailClient.printDebug(this, - esp_mail_cb_str_13 /* "Message sent successfully" */, - esp_mail_dbg_str_12 /* "message sent successfully" */, - esp_mail_debug_tag_type_client, - true, - false); - } - - if (_statusCallback) - MailClient.callBackSendNewLine(this, true); -#endif - - _authenticated = false; - _waitForAuthenticate = false; - } - } - -#if !defined(SILENT_MODE) - if (_statusCallback) - sendingResult.clear(); -#endif - - return MailClient.handleSMTPError(this, 0, ret); -} - -bool SMTPSession::connected() -{ - return client.connected(); -} - -void SMTPSession::callback(smtpStatusCallback smtpCallback) -{ - _statusCallback = smtpCallback; -} - -SMTP_Status SMTPSession::status() -{ - return _cbData; -} - -void SMTPSession::setSystemTime(time_t ts, float gmtOffset) -{ - MailClient.Time.setTimestamp(ts, gmtOffset); -} - -void SMTPSession::keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount) -{ - this->client.keepAlive(tcpKeepIdleSeconds, tcpKeepIntervalSeconds, tcpKeepCount); -} - -bool SMTPSession::isKeepAlive() -{ - return this->client.isKeepAlive(); -} - -void SMTPSession::setTCPTimeout(unsigned long timeoutSec) -{ - tcpTimeout = timeoutSec; -} - -void SMTPSession::setClient(Client *client) -{ - this->client.setClient(client); -} - -void SMTPSession::setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password) -{ - this->client.setGSMClient(client, modem, pin, apn, user, password); -} - -void SMTPSession::networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB) -{ - this->client.networkConnectionRequestCallback(networkConnectionCB); -} - -void SMTPSession::networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB) -{ - this->client.networkStatusRequestCallback(networkStatusCB); -} - -void SMTPSession::setNetworkStatus(bool status) -{ - this->client.setNetworkStatus(status); - MailClient.networkStatus = status; -} - -void SMTPSession::setSSLBufferSize(int rx, int tx) -{ - this->client.setIOBufferSize(rx, tx); -} - -SMTP_Status::SMTP_Status() -{ -} - -SMTP_Status::~SMTP_Status() -{ - empty(); -} - -const char *SMTP_Status::info() -{ - return _info.c_str(); -} - -bool SMTP_Status::success() -{ - return _success; -} - -size_t SMTP_Status::completedCount() -{ - return _sentSuccess; -} - -size_t SMTP_Status::failedCount() -{ - return _sentFailed; -} - -void SMTP_Status::empty() -{ - _info.clear(); -} - -#endif - -#endif /* ESP_MAIL_SMTP_H */ + +#ifndef ESP_MAIL_SMTP_H +#define ESP_MAIL_SMTP_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +/** + * Mail Client Arduino Library for Espressif's ESP32 and ESP8266, Raspberry Pi RP2040 Pico, and SAMD21 with u-blox NINA-W102 WiFi/Bluetooth module + * + * Created August 28, 2023 + * + * This library allows Espressif's ESP32, ESP8266, SAMD and RP2040 Pico devices to send and read Email through the SMTP and IMAP servers. + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * 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 "ESP_Mail_Client_Version.h" +#include "ESP_Mail_Client.h" + +#if defined(ENABLE_SMTP) + +void ESP_Mail_Client::mimeFromFile(const char *name, MB_String &mime) +{ + MB_String ext = name; + size_t p = ext.find_last_of("."); + if (p != MB_String::npos) + { + ext = ext.substr(p, ext.length() - p); + if (ext.length() > 0) + getMIME(ext.c_str(), mime); + } +} + +void ESP_Mail_Client::getMIME(const char *ext, MB_String &mime) +{ + mime.clear(); + for (int i = 0; i < esp_mail_file_extension_maxType; i++) + { + if (strcmp_P(ext, mimeinfo[i].endsWith) == 0) + { + mime = mimeinfo[i].mimeType; + break; + } + } +} + +bool ESP_Mail_Client::smtpAuth(SMTPSession *smtp, bool &ssl) +{ + if (!smtp) + return false; + + smtp->_auth_capability[esp_mail_auth_capability_login] = false; + + smtp->_session_cfg->int_start_tls = smtp->_session_cfg->secure.startTLS; + smtp->_session_cfg->int_mode = smtp->_session_cfg->secure.mode; + +#if !defined(ESP_MAIL_DISABLE_SSL) +initial_stage: +#endif + +// Sending greeting helo response +#if !defined(SILENT_MODE) + printDebug(smtp, + esp_mail_cb_str_3 /* "Sending greeting response..." */, + esp_mail_dbg_str_5 /* "send SMTP command, EHLO" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + // The Extended HELLO (EHLO) and HELLO (HELO) commands are used to identify Client (ourself) + + // Since we support ESMTP (rfc5321), let server knows by sending EHLO first + + // If server was not support ESMTP (rfc5321) the failure 501, 500, 502, or 550 would be replied. + + // To prevent connection rejection, EHLO/HELO command parameter should be primary host name (domain name) of client system. + // Otherwise client public IP address string (IPv4 or IPv6) can be assign when no host name is available + + MB_String s = smtp_cmd_post_tokens[esp_mail_smtp_command_ehlo]; + appendDomain(s, smtp->_session_cfg->login.user_domain.c_str()); + + if (smtpSend(smtp, s.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + // expected success status code 250 + // expected error status code 500, 501, 504, 421 + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_greeting, esp_mail_smtp_status_code_250, 0)) + { + +#if !defined(SILENT_MODE) + if (smtp->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_17 /* "No ESMTP supported, send SMTP command, HELO" */, esp_mail_debug_tag_type_client, true); +#endif + // In case EHLO (rfc5321) is not acceptable, + // send HELO command (rfc821) instead. + s = smtp_cmd_post_tokens[esp_mail_smtp_command_helo]; + appendDomain(s, smtp->_session_cfg->login.user_domain.c_str()); + + if (!smtpSend(smtp, s.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + // expected success status code 250 + // expected error status code 500, 501, 504, 421 + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_greeting, esp_mail_smtp_status_code_250, SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED)) + return false; + + smtp->_feature_capability[esp_mail_smtp_send_capability_esmtp] = false; + smtp->_auth_capability[esp_mail_auth_capability_login] = true; + } + else + smtp->_feature_capability[esp_mail_smtp_send_capability_esmtp] = true; + +#if !defined(ESP_MAIL_DISABLE_SSL) + + if (smtp->_session_cfg->int_mode != esp_mail_secure_mode_nonsecure) + { + // start TLS when needed + // rfc3207 + if ((smtp->_auth_capability[esp_mail_auth_capability_starttls] || smtp->_session_cfg->int_start_tls || smtp->_session_cfg->int_mode == esp_mail_secure_mode_ssl_tls) && !ssl) + { +// send starttls command +#if !defined(SILENT_MODE) + printDebug(smtp, + esp_mail_cb_str_2 /* "Sending STARTTLS command..." */, + esp_mail_dbg_str_1 /* "send command, STARTTLS" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + // expected success status code 250 for complete the request + // some server returns 220 to restart to initial state + + // expected error status code 500, 501, 504, 421 + smtpSend(smtp, smtp_commands[esp_mail_smtp_command_starttls].text, true); + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_start_tls, esp_mail_smtp_status_code_250, SMTP_STATUS_SMTP_GREETING_SEND_ACK_FAILED)) + return false; + +#if !defined(SILENT_MODE) + if (smtp->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_22 /* "perform SSL/TLS handshake" */, esp_mail_debug_tag_type_client, true); +#endif + + // connect in secure mode + // do TLS handshake + if (!smtp->client.connectSSL(smtp->_session_cfg->certificate.verify)) + return handleSMTPError(smtp, MAIL_CLIENT_ERROR_SSL_TLS_STRUCTURE_SETUP); + + // set the secure mode + smtp->_session_cfg->int_start_tls = false; + smtp->_session_cfg->int_mode = esp_mail_secure_mode_undefined; + ssl = true; + smtp->_secure = true; + + // return to initial stage if the response status is 220. + if (smtp->_responseStatus.statusCode == esp_mail_smtp_status_code_220) + goto initial_stage; + } + } + +#endif + + bool creds = smtp->_session_cfg->login.email.length() > 0 && smtp->_session_cfg->login.password.length() > 0; + bool sasl_auth_oauth = smtp->_session_cfg->login.accessToken.length() > 0 && smtp->_auth_capability[esp_mail_auth_capability_xoauth2]; + bool sasl_login = smtp->_auth_capability[esp_mail_auth_capability_login] && creds; + bool sasl_auth_plain = smtp->_auth_capability[esp_mail_auth_capability_plain] && creds; + + if (sasl_auth_oauth || sasl_login || sasl_auth_plain) + { +#if !defined(SILENT_MODE) + if (smtp->_statusCallback) + sendCB(smtp, esp_mail_cb_str_14 /* "Logging in..." */, true, false); +#endif + + // log in + if (sasl_auth_oauth) + { +#if !defined(SILENT_MODE) + if (smtp->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_15 /* "send smtp command, AUTH XOAUTH2" */, esp_mail_debug_tag_type_client, true); +#endif + if (!smtp->_auth_capability[esp_mail_auth_capability_xoauth2]) + return handleSMTPError(smtp, SMTP_STATUS_SERVER_OAUTH2_LOGIN_DISABLED, false); + + MB_String cmd = smtp_cmd_post_tokens[esp_mail_smtp_command_auth]; + cmd += smtp_auth_cap_post_tokens[esp_mail_auth_capability_xoauth2]; + + if (smtpSend(smtp, cmd.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + if (smtpSend(smtp, getXOAUTH2String(smtp->_session_cfg->login.email, smtp->_session_cfg->login.accessToken).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_auth_xoauth2, esp_mail_smtp_status_code_235, SMTP_STATUS_AUTHEN_FAILED)) + return false; + } + else if (sasl_auth_plain) + { +#if !defined(SILENT_MODE) + if (smtp->_debug) + { + esp_mail_debug_print_tag(esp_mail_dbg_str_7 /* "send SMTP command, AUTH PLAIN" */, esp_mail_debug_tag_type_client, true); + esp_mail_debug_print_tag(smtp->_session_cfg->login.email.c_str(), esp_mail_debug_tag_type_client, true); + MB_String mask; + maskString(mask, smtp->_session_cfg->login.password.length()); + esp_mail_debug_print_tag(mask.c_str(), esp_mail_debug_tag_type_client, true); + } +#endif + // rfc4616 + int len = smtp->_session_cfg->login.email.length() + smtp->_session_cfg->login.password.length() + 2; + uint8_t *tmp = allocMem(len); + memset(tmp, 0, len); + int p = 1; + memcpy(tmp + p, smtp->_session_cfg->login.email.c_str(), smtp->_session_cfg->login.email.length()); + p += smtp->_session_cfg->login.email.length() + 1; + memcpy(tmp + p, smtp->_session_cfg->login.password.c_str(), smtp->_session_cfg->login.password.length()); + p += smtp->_session_cfg->login.password.length(); + + MB_String cmd = smtp_cmd_post_tokens[esp_mail_smtp_command_auth]; + cmd += smtp_cmd_post_tokens[esp_mail_smtp_command_plain]; + cmd += encodeBase64Str(tmp, p); + // release memory + freeMem(&tmp); + + if (smtpSend(smtp, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_auth_plain, esp_mail_smtp_status_code_235, SMTP_STATUS_USER_LOGIN_FAILED)) + return false; + } + else if (sasl_login) + { +#if !defined(SILENT_MODE) + if (smtp->_debug) + esp_mail_debug_print_tag(esp_mail_dbg_str_6 /* "send SMTP command, AUTH LOGIN" */, esp_mail_debug_tag_type_client, true); +#endif + MB_String cmd = smtp_cmd_post_tokens[esp_mail_smtp_command_auth]; + cmd += smtp_commands[esp_mail_smtp_command_login].text; + + if (smtpSend(smtp, cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + // expected server challenge response + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_auth_login, esp_mail_smtp_status_code_334, SMTP_STATUS_AUTHEN_FAILED)) + return false; + +#if !defined(SILENT_MODE) + if (smtp->_debug) + esp_mail_debug_print_tag(smtp->_session_cfg->login.email.c_str(), esp_mail_debug_tag_type_client, true); +#endif + if (smtpSend(smtp, encodeBase64Str((const unsigned char *)smtp->_session_cfg->login.email.c_str(), smtp->_session_cfg->login.email.length()).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + // expected server challenge response + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_login_user, esp_mail_smtp_status_code_334, SMTP_STATUS_USER_LOGIN_FAILED)) + return false; + +#if !defined(SILENT_MODE) + if (smtp->_debug) + { + MB_String mask; + maskString(mask, smtp->_session_cfg->login.password.length()); + esp_mail_debug_print_tag(mask.c_str(), esp_mail_debug_tag_type_client, true); + } +#endif + if (smtpSend(smtp, encodeBase64Str((const unsigned char *)smtp->_session_cfg->login.password.c_str(), smtp->_session_cfg->login.password.length()).c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_login_psw, esp_mail_smtp_status_code_235, SMTP_STATUS_PASSWORD_LOGIN_FAILED)) + return false; + } + + smtp->_authenticated = true; + } + + return true; +} + +bool ESP_Mail_Client::addSendingResult(SMTPSession *smtp, SMTP_Message *msg, bool result, bool showResult) +{ + if (!smtp) + return false; + + if (result) + smtp->_sentSuccessCount++; + else + smtp->_sentFailedCount++; + + if (smtp->_session_cfg->sentLogs.filename.length() > 0 && smtp->_session_cfg->sentLogs.storage_type != esp_mail_file_storage_type_none) + saveSendingLogs(smtp, msg, result); + + // Store only tatest result + smtp->sendingResult.clear(); + + SMTP_Result status; + status.completed = result; + status.timestamp = smtp->ts; + status.subject = msg->subject.c_str(); + + if (msg->timestamp.tag.length() && msg->timestamp.format.length()) + status.subject.replaceAll(msg->timestamp.tag, Time.getDateTimeString(Time.getCurrentTimestamp(), msg->timestamp.format.c_str())); + + status.recipients = msg->_rcp[0].email.c_str(); + smtp->sendingResult.add(&status); + + smtp->_cbData._sentSuccess = smtp->_sentSuccessCount; + smtp->_cbData._sentFailed = smtp->_sentFailedCount; + +#if !defined(SILENT_MODE) + if (smtp->_statusCallback) + { + if (showResult) + { + int bufLen = 512; + char *buf = allocMem(bufLen); + time_t ts = (time_t)smtp->ts; + MB_String sep; + for (int i = 0; i < 25; i++) + sep += '-'; + + sendCallback(smtp, sep.c_str(), true, false); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_93 /* "Message sent success: %d" */), smtp->_sentSuccessCount); + sendCallback(smtp, buf, false, false); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_94 /* "Message sent failed: %d" */), smtp->_sentFailedCount); + sendCallback(smtp, buf, false, false); + sendCallback(smtp, sep.c_str(), false, false); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_95 /* "Status: %s" */), result ? pgm2Str(esp_mail_str_98 /* "success" */) : pgm2Str(esp_mail_str_99 /* "failed" */)); + sendCallback(smtp, buf, false, false); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_96 /* "Date/Time: %s" */), Time.getDateTimeString(ts, "%B %d, %Y %H:%M:%S").c_str()); + sendCallback(smtp, buf, false, false); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_97 /* "Recipient: %s" */), msg->_rcp[0].email.c_str()); + sendCallback(smtp, buf, false, false); + snprintf(buf, bufLen, pgm2Str(esp_mail_str_92 /* "Subject: %s" */), msg->subject.c_str()); + sendCallback(smtp, buf, false, false); + freeMem(&buf); + } + } +#endif + + return result; +} + +void ESP_Mail_Client::saveSendingLogs(SMTPSession *smtp, SMTP_Message *msg, bool result) +{ + if (!smtp->_session_cfg || smtp->_session_cfg->sentLogs.filename.length() == 0 || smtp->_session_cfg->sentLogs.storage_type == esp_mail_file_storage_type_none) + return; + + int sz = mbfs->open(smtp->_session_cfg->sentLogs.filename.c_str(), mbfs_type smtp->_session_cfg->sentLogs.storage_type, mb_fs_open_mode_append); + if (sz < 0) + return; + + MB_String cm = esp_mail_str_8; /* "," */ + mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, (int)result); + mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, cm.c_str()); + mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, (int)smtp->ts); + mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, cm.c_str()); + mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, msg->_rcp[0].email.c_str()); + mbfs->print(mbfs_type smtp->_session_cfg->sentLogs.storage_type, cm.c_str()); + mbfs->println(mbfs_type smtp->_session_cfg->sentLogs.storage_type, msg->subject.c_str()); + mbfs->close(mbfs_type smtp->_session_cfg->sentLogs.storage_type); +} + +bool ESP_Mail_Client::sendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession) +{ + if (!smtp || !sessionExisted(smtp)) + return false; + + smtp->_customCmdResCallback = NULL; + + return mSendMail(smtp, msg, closeSession); +} + +size_t ESP_Mail_Client::numAtt(SMTPSession *smtp, esp_mail_attach_type type, SMTP_Message *msg) +{ + size_t count = 0; + for (size_t i = 0; i < msg->_att.size(); i++) + { + if (msg->_att[i]._int.att_type == type) + count++; + } + return count; +} + +bool ESP_Mail_Client::checkEmail(SMTPSession *smtp, SMTP_Message *msg) +{ + bool validRecipient = false; + + if (!validEmail(msg->sender.email.c_str())) + { + errorStatusCB(smtp, this->imap, SMTP_STATUS_NO_VALID_SENDER_EXISTED, false); + return addSendingResult(smtp, msg, false, true); + } + + for (uint8_t i = 0; i < msg->_rcp.size(); i++) + { + if (validEmail(msg->_rcp[i].email.c_str())) + validRecipient = true; + } + + if (!validRecipient) + { + errorStatusCB(smtp, this->imap, SMTP_STATUS_NO_VALID_RECIPIENTS_EXISTED, false); + return addSendingResult(smtp, msg, false, true); + } + + return true; +} + +bool ESP_Mail_Client::mSendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession) +{ + if (!smtp) + return false; + + smtp->_responseStatus.errorCode = 0; + smtp->_responseStatus.statusCode = 0; + smtp->_responseStatus.text.clear(); + smtp->_cbData._success = false; + bool rfc822MSG = false; + + if (!checkEmail(smtp, msg)) + return false; + + smtp->_chunkedEnable = false; + smtp->_chunkCount = 0; + + if (!smtp->connected() && !smtp->_loginStatus) + { +#if !defined(SILENT_MODE) + if (smtp->_debug && smtp->_statusCallback && !smtp->_customCmdResCallback) + { + esp_mail_debug_print(); + errorStatusCB(smtp, this->imap, MAIL_CLIENT_ERROR_NOT_YET_LOGIN, false); + } +#endif + return false; + } + + // new session + if (!smtp->connected()) + { + bool ssl = false; + + if (!smtp->connect(ssl)) + { + closeTCPSession(smtp); + return addSendingResult(smtp, msg, false, true); + } + + if (!smtpAuth(smtp, ssl)) + { + closeTCPSession(smtp); + return addSendingResult(smtp, msg, false, true); + } + smtp->_sentSuccessCount = 0; + smtp->_sentFailedCount = 0; + smtp->sendingResult.clear(); + } + else + { + // If time config changed, we will update time + MailClient.prepareTime(smtp->_session_cfg, smtp); + // reuse session +#if !defined(SILENT_MODE) + PGM_P p1 = smtp->_sentSuccessCount || smtp->_sentFailedCount ? esp_mail_cb_str_10 /* "Sending next Email..." */ : esp_mail_cb_str_9 /* "Sending Email..." */; + PGM_P p2 = smtp->_sentSuccessCount || smtp->_sentFailedCount ? esp_mail_dbg_str_13 /* "send next Email" */ : esp_mail_dbg_str_3 /* "send Email" */; + + printDebug(smtp, + p1, + p2, + esp_mail_debug_tag_type_client, + true, + false); +#endif + } + +#if !defined(SILENT_MODE) + printDebug(smtp, + esp_mail_cb_str_4 /* "Sending message header..." */, + esp_mail_dbg_str_8 /* "send message header" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + imap = nullptr; + calDataLen = false; + dataLen = 0; + + return sendContent(smtp, msg, closeSession, rfc822MSG); +} + +bool ESP_Mail_Client::sendContent(SMTPSession *smtp, SMTP_Message *msg, bool closeSession, bool rfc822MSG) +{ + + if (msg->html.content.length() > 0 || strlen(msg->html.nonCopyContent) > 0 || msg->html.blob.size > 0 || msg->html.file.name.length() > 0) + msg->type |= esp_mail_msg_type_html; + + if (msg->text.content.length() > 0 || strlen(msg->text.nonCopyContent) > 0 || msg->text.blob.size > 0 || msg->text.file.name.length() > 0) + msg->type |= esp_mail_msg_type_plain; + + for (size_t i = 0; i < msg->_rfc822.size(); i++) + { + if (msg->_rfc822[i].html.content.length() > 0) + msg->_rfc822[i].type |= esp_mail_msg_type_html; + + if (msg->_rfc822[i].text.content.length() > 0) + msg->_rfc822[i].type |= esp_mail_msg_type_plain; + } + + MB_String buf; + MB_String buf2; + checkUnencodedData(smtp, msg); + + if (msg->priority >= esp_mail_smtp_priority_high && msg->priority <= esp_mail_smtp_priority_low) + { + appendHeaderField(buf2, message_headers[esp_mail_message_header_field_x_priority].text, MB_String(msg->priority).c_str(), false, true); + + PGM_P p = nullptr; + if (msg->priority == esp_mail_smtp_priority_high) + p = esp_mail_str_4; /* "High" */ + else if (msg->priority == esp_mail_smtp_priority_normal) + p = esp_mail_str_5; /* "Normal" */ + else if (msg->priority == esp_mail_smtp_priority_low) + p = esp_mail_str_6; /* "Low" */ + + if (p) + { + appendHeaderField(buf2, message_headers[esp_mail_message_header_field_x_msmail_priority].text, p, false, true); + appendHeaderField(buf2, message_headers[esp_mail_message_header_field_importance].text, p, false, true); + } + } + + // If author and transmitter (sender or agent) are not identical, send both 'From' and 'Sender' headers + if (msg->sender.email.length() > 0 && msg->author.email.length() > 0 && + strcmp(msg->sender.email.c_str(), msg->author.email.c_str()) != 0) + { + appendAddressHeaderField(buf2, msg->author, esp_mail_rfc822_header_field_from, true, false, true); + appendAddressHeaderField(buf2, msg->sender, esp_mail_rfc822_header_field_sender, true, false, true); + } + // If author and transmitter (agent) are identical, send only 'From' header + else if (msg->sender.email.length() > 0) + appendAddressHeaderField(buf2, msg->sender, esp_mail_rfc822_header_field_from, true, false, true); + + if (!imap && smtp) + { + + buf = smtp_cmd_post_tokens[esp_mail_smtp_command_mail]; + buf += smtp_commands[esp_mail_smtp_command_from].text; + + appendString(buf, msg->author.email.length() ? msg->author.email.c_str() : msg->sender.email.c_str(), false, false, esp_mail_string_mark_type_angle_bracket); + + if (msg->text._int.xencoding == esp_mail_msg_xencoding_binary || msg->html._int.xencoding == esp_mail_msg_xencoding_binary) + { + if (smtp->_feature_capability[esp_mail_smtp_send_capability_binary_mime] || (smtp->_feature_capability[esp_mail_smtp_send_capability_chunking] && msg->enable.chunking)) + { + buf += smtp_cmd_pre_tokens[esp_mail_smtp_command_body]; + buf += esp_mail_str_7; /* "=" */ + buf += smtp_send_capabilities[esp_mail_smtp_send_capability_binary_mime].text; + } + } + else if (msg->text._int.xencoding == esp_mail_msg_xencoding_8bit || msg->html._int.xencoding == esp_mail_msg_xencoding_8bit) + { + if (smtp->_feature_capability[esp_mail_smtp_send_capability_8bit_mime]) + { + buf += smtp_cmd_pre_tokens[esp_mail_smtp_command_body]; + buf += esp_mail_str_7; /* "=" */ + buf += smtp_send_capabilities[esp_mail_smtp_send_capability_8bit_mime].text; + } + } + + // expected success status code 250 + // expected failure status code 552, 451, 452 + // expected error status code 500, 501, 421 + if (!altSendData(buf, true, smtp, msg, true, true, esp_mail_smtp_cmd_send_header_sender, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_SENDER_FAILED)) + return false; + } + + // Construct 'To' header fields. + + for (uint8_t i = 0; i < msg->_rcp.size(); i++) + { + appendAddressHeaderField(buf2, msg->_rcp[i], esp_mail_rfc822_header_field_to, i == 0, i > 0, i == msg->_rcp.size() - 1); + if (!imap && smtp) + { + // only address + buf = smtp_cmd_post_tokens[esp_mail_smtp_command_rcpt]; + buf += smtp_commands[esp_mail_smtp_command_to].text; + appendString(buf, msg->_rcp[i].email.c_str(), false, false, esp_mail_string_mark_type_angle_bracket); + + // rfc3461, rfc3464 + if (smtp->_feature_capability[esp_mail_smtp_send_capability_dsn]) + { + if (msg->response.notify != esp_mail_smtp_notify_never) + { + buf += smtp_cmd_pre_tokens[esp_mail_smtp_command_notify]; + buf += esp_mail_str_7; /* "=" */ + + MB_String notify; + + if ((msg->response.notify & esp_mail_smtp_notify_success) == esp_mail_smtp_notify_success) + notify = smtp_commands[esp_mail_smtp_command_success].text; + + if (notify.length()) + notify += esp_mail_str_8; /* "," */ + + if ((msg->response.notify & esp_mail_smtp_notify_failure) == esp_mail_smtp_notify_failure) + notify += smtp_commands[esp_mail_smtp_command_failure].text; + + if (notify.length()) + notify += esp_mail_str_8; /* "," */ + + if ((msg->response.notify & esp_mail_smtp_notify_delay) == esp_mail_smtp_notify_delay) + notify += smtp_commands[esp_mail_smtp_command_delay].text; + + buf += notify; + } + } + + smtp->_canForward = true; + + // expected success status code 250, 251 + // expected failure status code 550, 551, 552, 553, 450, 451, 452 + // expected error status code 500, 501, 503, 421 + if (!altSendData(buf, true, smtp, msg, true, true, esp_mail_smtp_cmd_send_header_recipient, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED)) + return false; + } + } + + // Construct 'Cc' header field. + for (uint8_t i = 0; i < msg->_cc.size(); i++) + { + appendAddressHeaderField(buf2, msg->_cc[i], esp_mail_rfc822_header_field_cc, i == 0, i > 0, i == msg->_cc.size() - 1); + if (!imap) + { + // only address + buf = smtp_cmd_post_tokens[esp_mail_smtp_command_rcpt]; + buf += smtp_commands[esp_mail_smtp_command_to].text; + appendString(buf, msg->_cc[i].email.c_str(), false, false, esp_mail_string_mark_type_angle_bracket); + + smtp->_canForward = true; + + // expected success status code 250, 251 + // expected failure status code 550, 551, 552, 553, 450, 451, 452 + // expected error status code 500, 501, 503, 421 + if (!altSendData(buf, true, smtp, msg, true, true, esp_mail_smtp_cmd_send_header_recipient, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED)) + return false; + } + } + + if (!imap && smtp) + { + for (uint8_t i = 0; i < msg->_bcc.size(); i++) + { + // only address + buf = smtp_cmd_post_tokens[esp_mail_smtp_command_rcpt]; + buf += smtp_commands[esp_mail_smtp_command_to].text; + appendString(buf, msg->_bcc[i].email.c_str(), false, false, esp_mail_string_mark_type_angle_bracket); + + smtp->_canForward = true; + + // expected success status code 250, 251 + // expected failure status code 550, 551, 552, 553, 450, 451, 452 + // expected error status code 500, 501, 503, 421 + if (!altSendData(buf, true, smtp, msg, true, true, esp_mail_smtp_cmd_send_header_recipient, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_HEADER_RECIPIENT_FAILED)) + return false; + } + +#if !defined(SILENT_MODE) + altSendCallback(smtp, esp_mail_cb_str_5 /* "Sending message body..." */, esp_mail_dbg_str_9 /* "send message body" */, esp_mail_debug_tag_type_client, true, false); +#endif + if (smtp->_feature_capability[esp_mail_smtp_send_capability_chunking] && msg->enable.chunking) + { + smtp->_chunkedEnable = true; + if (!sendBDAT(smtp, msg, buf2.length(), false)) + return false; + } + else + { + // expected success status code 354 + // expected failure status code 451, 554 + // expected error status code 500, 501, 503, 421 + MB_String sdata = smtp_commands[esp_mail_smtp_command_data].text; + if (!altSendData(sdata, true, smtp, msg, true, true, esp_mail_smtp_cmd_send_body, esp_mail_smtp_status_code_354, SMTP_STATUS_SEND_BODY_FAILED)) + return false; + } + } + +#if defined(ENABLE_IMAP) && !defined(SILENT_MODE) + if (imap) + altSendCallback(smtp, esp_mail_cb_str_14 /* "Appending message..." */, esp_mail_dbg_str_69 /* "appending message" */, esp_mail_debug_tag_type_client, true, false); + +#endif + + if (!altSendData(buf2, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + MB_String s; + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_subject].text, msg->subject.c_str(), false, true); + + if (msg->timestamp.tag.length() && msg->timestamp.format.length()) + s.replaceAll(msg->timestamp.tag, Time.getDateTimeString(Time.getCurrentTimestamp(), msg->timestamp.format.c_str())); + + // Construct the 'Date' header field. + // The 'Date' header field should be valid and should be included in the message headers to + // prevent the 'spam' or 'junk' message considered by mail server. + + bool dateHdr = false; + MB_String dt; + + uint32_t ts = 0; + + if (smtp) + smtp->ts = ts; + + // Check if valid 'Date' field assigned from custom headers. + if (msg->_hdr.size() > 0) + { + for (uint8_t k = 0; k < msg->_hdr.size(); k++) + { + appendString(s, msg->_hdr[k].c_str(), false, true); + + if (getHeader(msg->_hdr[k].c_str(), rfc822_headers[esp_mail_rfc822_header_field_date].text, dt, false)) + { + ts = Time.getTimestamp(dt.c_str(), true); + dateHdr = ts > ESP_MAIL_CLIENT_VALID_TS; + if (smtp) + smtp->ts = ts; + } + } + } + + // Check if valid 'Date' field assigned from SMTP_Message's date property. + if (!dateHdr && msg->date.length() > 0) + { + dt = msg->date; + ts = Time.getTimestamp(msg->date.c_str(), true); + dateHdr = ts > ESP_MAIL_CLIENT_VALID_TS; + if (smtp) + smtp->ts = ts; + } + + if (dateHdr) + { + // 'Date' header field assigned. + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_date].text, dt.c_str(), false, true); + } + else + { + // If there is no 'Date' field assigned, get time from system and construct 'Date' header field. + if (smtp) + { + ts = MailClient.Time.getCurrentTimestamp(); + smtp->ts = ts; + } + else if (imap) + { +#if defined(ENABLE_IMAP) + if (calDataLen) + { + ts = MailClient.Time.getCurrentTimestamp(); + imap_ts = ts; + } + else + ts = imap_ts; +#endif + } + + if (ts > ESP_MAIL_CLIENT_VALID_TS) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_date].text, Time.getDateTimeString().c_str(), false, true); + } + + if (msg->response.reply_to.length() > 0) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_reply_to].text, msg->response.reply_to.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + + if (msg->response.return_path.length() > 0) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_return_path].text, msg->response.return_path.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + + if (msg->in_reply_to.length() > 0) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_in_reply_to].text, msg->in_reply_to.c_str(), false, true); + + if (msg->references.length() > 0) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_references].text, msg->references.c_str(), false, true); + + if (msg->comments.length() > 0) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_comments].text, msg->comments.c_str(), false, true); + + if (msg->keywords.length() > 0) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_keywords].text, msg->keywords.c_str(), false, true); + + if (msg->messageID.length() > 0) + appendHeaderField(s, rfc822_headers[esp_mail_rfc822_header_field_msg_id].text, msg->messageID.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + + appendHeaderField(s, message_headers[esp_mail_message_header_field_mime_version].text, esp_mail_str_51 /* "1.0" */, false, true); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + return sendMSGData(smtp, msg, closeSession, rfc822MSG); +} + +void ESP_Mail_Client::altSendCallback(SMTPSession *smtp, PGM_P cbMsg, PGM_P dbMsg, esp_mail_debug_tag_type type, bool prependCRLF, bool success) +{ +#if !defined(SILENT_MODE) + if (smtp) + printDebug(smtp, cbMsg, dbMsg, type, prependCRLF, success); + else if (imap && !calDataLen) + { +#if defined(ENABLE_IMAP) + printDebug(imap, cbMsg, dbMsg, type, prependCRLF, success); +#endif + } +#endif +} + +bool ESP_Mail_Client::sendMSGData(SMTPSession *smtp, SMTP_Message *msg, bool closeSession, bool rfc822MSG) +{ + MB_String s; + MB_String mixed = getMIMEBoundary(15); + MB_String alt = getMIMEBoundary(15); + + if (numAtt(smtp, esp_mail_att_type_attachment, msg) == 0 && msg->_parallel.size() == 0 && msg->_rfc822.size() == 0) + { + if (msg->type == (esp_mail_msg_type_plain | esp_mail_msg_type_html | esp_mail_msg_type_enriched) || numAtt(smtp, esp_mail_att_type_inline, msg) > 0) + { + if (!sendMSG(smtp, msg, alt)) + return addSendingResult(smtp, msg, false, true); + } + else if (msg->type != esp_mail_msg_type_none) + { + if (!sendPartText(smtp, msg, msg->type, "")) + return addSendingResult(smtp, msg, false, true); + } + } + else + { + s.clear(); + appendMultipartContentType(s, esp_mail_multipart_type_mixed, mixed.c_str()); + appendBoundaryString(s, mixed.c_str(), false, true); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (!sendMSG(smtp, msg, alt)) + return addSendingResult(smtp, msg, false, true); + + if (!sendBDAT(smtp, msg, 2, false)) + return false; + + MB_String str; + appendNewline(str); + + if (!altSendData(str, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + +#if !defined(SILENT_MODE) + altSendCallback(smtp, esp_mail_cb_str_6 /* "Sending attachments..." */, esp_mail_dbg_str_10 /* "send attachments" */, esp_mail_debug_tag_type_client, true, false); +#endif + if (!sendAttachments(smtp, msg, mixed)) + return addSendingResult(smtp, msg, false, true); + + if (!sendParallelAttachments(smtp, msg, mixed)) + return addSendingResult(smtp, msg, false, true); + + if (!sendRFC822Msg(smtp, msg, mixed, closeSession, msg->_rfc822.size() > 0)) + return addSendingResult(smtp, msg, false, true); + + s.clear(); + appendBoundaryString(s, mixed.c_str(), true, false); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + } + + if (!rfc822MSG && !imap && smtp) + { +#if !defined(SILENT_MODE) + altSendCallback(smtp, esp_mail_cb_str_11 /* "Finishing the message sending..." */, esp_mail_dbg_str_16 /* "finishing the message sending" */, esp_mail_debug_tag_type_client, true, false); +#endif + if (smtp->_chunkedEnable) + { + + if (!sendBDAT(smtp, msg, 0, true)) + return false; + + // expected success status code 250 + // expected failure status code 451, 554 + // expected error status code 500, 501, 503, 421 + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_chunk_termination, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_BODY_FAILED)) + return false; + } + else + { + // expected success status code 250 + // expected failure status code 451, 554 + // expected error status code 500, 501, 503, 421 + MB_String str = smtp_commands[esp_mail_smtp_command_terminate].text; + if (!altSendData(str, false, smtp, msg, true, true, esp_mail_smtp_cmd_send_body, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_BODY_FAILED)) + return false; + } + + addSendingResult(smtp, msg, true, !closeSession); + + if (closeSession && smtp) + { + if (!smtp->closeSession()) + return false; + } + } + if (smtp) + smtp->_cbData._success = true; + return true; +} + +bool ESP_Mail_Client::sendRFC822Msg(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, bool closeSession, bool rfc822MSG) +{ + if (msg->_rfc822.size() == 0) + return true; + + MB_String buf; + + for (uint8_t i = 0; i < msg->_rfc822.size(); i++) + { + buf.clear(); + getRFC822PartHeader(smtp, buf, boundary); + + getRFC822MsgEnvelope(smtp, &msg->_rfc822[i], buf); + + if (!sendBDAT(smtp, msg, buf.length(), false)) + return false; + + if (!altSendData(buf, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (!sendMSGData(smtp, &msg->_rfc822[i], closeSession, rfc822MSG)) + return false; + } + + return true; +} + +void ESP_Mail_Client::getRFC822MsgEnvelope(SMTPSession *smtp, SMTP_Message *msg, MB_String &buf) +{ + if (msg->date.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_date].text, msg->date.c_str(), false, true); + else + { + time_t now = 0; + if (smtp) + now = MailClient.Time.getCurrentTimestamp(); + else if (imap) + { +#if defined(ENABLE_IMAP) + if (calDataLen) + { + now = MailClient.Time.getCurrentTimestamp(); + imap_ts = now; + } + else + now = imap_ts; +#endif + } + + if (now > ESP_MAIL_CLIENT_VALID_TS) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_date].text, Time.getDateTimeString().c_str(), false, true); + } + + // Construct 'From' header field. + if (msg->from.email.length() > 0) + appendAddressHeaderField(buf, msg->from, esp_mail_rfc822_header_field_from, true, false, true); + + // Construct 'Sender' header field. + if (msg->sender.email.length() > 0) + appendAddressHeaderField(buf, msg->sender, esp_mail_rfc822_header_field_sender, true, false, true); + + if (msg->response.reply_to.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_reply_to].text, msg->response.reply_to.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + + if (msg->response.return_path.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_return_path].text, msg->response.return_path.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + + // Construct 'To' header field. + for (uint8_t i = 0; i < msg->_rcp.size(); i++) + appendAddressHeaderField(buf, msg->_rcp[i], esp_mail_rfc822_header_field_to, i == 0, i > 0, i == msg->_rcp.size() - 1); + + for (uint8_t i = 0; i < msg->_cc.size(); i++) + appendAddressHeaderField(buf, msg->_cc[i], esp_mail_rfc822_header_field_cc, i == 0, i > 0, i == msg->_cc.size() - 1); + + for (uint8_t i = 0; i < msg->_bcc.size(); i++) + appendAddressHeaderField(buf, msg->_bcc[i], esp_mail_rfc822_header_field_bcc, i == 0, i > 0, i == msg->_bcc.size() - 1); + + if (msg->subject.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_subject].text, msg->subject.c_str(), false, true); + + if (msg->keywords.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_keywords].text, msg->keywords.c_str(), false, true); + + if (msg->comments.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_comments].text, msg->comments.c_str(), false, true); + + if (msg->in_reply_to.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_in_reply_to].text, msg->in_reply_to.c_str(), false, true); + + if (msg->references.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_references].text, msg->references.c_str(), false, true); + + if (msg->messageID.length() > 0) + appendHeaderField(buf, rfc822_headers[esp_mail_rfc822_header_field_msg_id].text, msg->messageID.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); +} + +void ESP_Mail_Client::appendBoundaryString(MB_String &buf, const char *value, bool endMark, bool newLine) +{ + buf += esp_mail_str_9; /* "--" */ + buf += value; + if (endMark) + buf += esp_mail_str_9; /* "--" */ + if (newLine) + appendNewline(buf); +} + +bool ESP_Mail_Client::sendBDAT(SMTPSession *smtp, SMTP_Message *msg, int len, bool last) +{ + if (!smtp) + return true; + + if (!smtp->_chunkedEnable || !msg->enable.chunking) + return true; + + smtp->_chunkCount++; + + MB_String bdat = smtp_cmd_post_tokens[esp_mail_smtp_command_bdat]; + bdat += len; + if (last) + bdat += smtp_cmd_pre_tokens[esp_mail_smtp_command_last]; + + if (smtpSend(smtp, bdat.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return addSendingResult(smtp, msg, false, true); + + if (!smtp->_feature_capability[esp_mail_smtp_send_capability_pipelining]) + { + // expected success status code 250 + // expected failure status code 451, 554 + // expected error status code 500, 501, 503, 421 + if (!handleSMTPResponse(smtp, esp_mail_smtp_cmd_send_body, esp_mail_smtp_status_code_250, SMTP_STATUS_SEND_BODY_FAILED)) + return addSendingResult(smtp, msg, false, true); + smtp->_chunkCount = 0; + } + return true; +} + +void ESP_Mail_Client::getXEncoding(esp_mail_msg_xencoding &xencoding, const char *enc) +{ + if (strcmp(enc, Content_Transfer_Encoding::enc_binary) == 0) + xencoding = esp_mail_msg_xencoding_binary; + else if (strcmp(enc, Content_Transfer_Encoding::enc_8bit) == 0) + xencoding = esp_mail_msg_xencoding_8bit; + else if (strcmp(enc, Content_Transfer_Encoding::enc_7bit) == 0) + xencoding = esp_mail_msg_xencoding_7bit; +} + +void ESP_Mail_Client::checkUnencodedData(SMTPSession *smtp, SMTP_Message *msg) +{ + if (msg->type & esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched || msg->type & esp_mail_msg_type_html) + { + if ((msg->type & esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched) > 0 && msg->text.transfer_encoding.length() > 0) + getXEncoding(msg->text._int.xencoding, msg->text.transfer_encoding.c_str()); + + if ((msg->type & esp_mail_msg_type_html) > 0 && msg->html.transfer_encoding.length() > 0) + getXEncoding(msg->html._int.xencoding, msg->html.transfer_encoding.c_str()); + } + + for (size_t i = 0; i < msg->_att.size(); i++) + getXEncoding(msg->_att[i]._int.xencoding, msg->_att[i].descr.transfer_encoding.c_str()); +} + +bool ESP_Mail_Client::altIsCB(SMTPSession *smtp) +{ + bool cb = false; + if (smtp) + cb = smtp->_statusCallback != NULL; + else if (imap && !calDataLen) + { +#if defined(ENABLE_IMAP) + cb = imap->_statusCallback != NULL; +#endif + } + + return cb; +} + +bool ESP_Mail_Client::altIsDebug(SMTPSession *smtp) +{ + bool dbg = false; + if (smtp) + dbg = smtp->_debug; + else if (imap && !calDataLen) + { +#if defined(ENABLE_IMAP) + dbg = imap->_debug; +#endif + } + + return dbg; +} + +bool ESP_Mail_Client::sendBlobAttachment(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att) +{ + bool cb = altIsCB(smtp); + uint32_t addr = altProgressPtr(smtp); + + if (strcmp(att->descr.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0 && strcmp(att->descr.transfer_encoding.c_str(), att->descr.content_encoding.c_str()) != 0) + { + esp_mail_smtp_send_base64_data_info_t data_info; + + data_info.rawPtr = att->blob.data; + data_info.size = att->blob.size; + data_info.flashMem = att->_int.flash_blob; + data_info.filename = att->descr.filename.c_str(); + + if (!sendBase64(smtp, msg, data_info, true, cb)) + return false; + + return true; + } + else + { + if (att->blob.size > 0) + { + if (strcmp(att->descr.content_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) + { + esp_mail_smtp_send_base64_data_info_t data_info; + + data_info.rawPtr = att->blob.data; + data_info.size = att->blob.size; + data_info.flashMem = att->_int.flash_blob; + data_info.filename = att->descr.filename.c_str(); + + if (!sendBase64(smtp, msg, data_info, false, cb)) + return false; + + return true; + } + else + { + + size_t chunkSize = ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE; + size_t writeLen = 0; + uint8_t *buf = allocMem(chunkSize); + while (writeLen < att->blob.size) + { + if (writeLen > att->blob.size - chunkSize) + chunkSize = att->blob.size - writeLen; + + if (!sendBDAT(smtp, msg, chunkSize, false)) + break; + memcpy_P(buf, att->blob.data, chunkSize); + + if (!altSendData(buf, chunkSize, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + break; + + if (smtp->_debug) + uploadReport(att->descr.filename.c_str(), addr, 100 * writeLen / att->blob.size); + + writeLen += chunkSize; + } + + // release memory + freeMem(&buf); + + if (smtp->_debug) + uploadReport(att->descr.filename.c_str(), addr, 100); + + return writeLen >= att->blob.size; + } + } + } + return false; +} + +bool ESP_Mail_Client::sendFile(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att) +{ + bool cb = altIsCB(smtp); + uint32_t addr = altProgressPtr(smtp); + + if (strcmp(att->descr.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0 && strcmp(att->descr.transfer_encoding.c_str(), att->descr.content_encoding.c_str()) != 0) + { + esp_mail_smtp_send_base64_data_info_t data_info; + + data_info.filename = att->descr.filename.c_str(); + data_info.storageType = att->file.storage_type; + + if (!sendBase64(smtp, msg, data_info, true, cb)) + return false; + + return true; + } + else + { + if (mbfs->size(mbfs_type att->file.storage_type) > 0) + { + if (strcmp(att->descr.content_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) + { + esp_mail_smtp_send_base64_data_info_t data_info; + + data_info.filename = att->descr.filename.c_str(); + data_info.storageType = att->file.storage_type; + + if (!sendBase64(smtp, msg, data_info, false, cb)) + return false; + + return true; + } + else + { + int chunkSize = ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE; + int writeLen = 0; + + int fileSize = mbfs->size(mbfs_type att->file.storage_type); + + if (fileSize < chunkSize) + chunkSize = fileSize; + + uint8_t *buf = allocMem(chunkSize); + + while (writeLen < fileSize && mbfs->available(mbfs_type att->file.storage_type)) + { + if (writeLen > fileSize - chunkSize) + chunkSize = fileSize - writeLen; + int readLen = mbfs->read(mbfs_type att->file.storage_type, buf, chunkSize); + if (readLen != chunkSize) + { + errorStatusCB(smtp, this->imap, MB_FS_ERROR_FILE_IO_ERROR, false); + break; + } + + if (!sendBDAT(smtp, msg, chunkSize, false)) + break; + + if (!altSendData(buf, chunkSize, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + break; + + if (smtp->_debug) + uploadReport(att->descr.filename.c_str(), addr, 100 * writeLen / fileSize); + + writeLen += chunkSize; + } + + // release memory + freeMem(&buf); + + if (smtp->_debug) + uploadReport(att->descr.filename.c_str(), addr, 100); + + return writeLen == fileSize; + } + } + return false; + } + return false; +} + +bool ESP_Mail_Client::sendParallelAttachments(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary) +{ + if (msg->_parallel.size() == 0) + return true; + + MB_String parallel = getMIMEBoundary(15); + MB_String buf; + + appendBoundaryString(buf, boundary.c_str(), false, true); + + appendMultipartContentType(buf, esp_mail_multipart_type_parallel, parallel.c_str()); + + if (!sendBDAT(smtp, msg, buf.length(), false)) + return false; + + if (!altSendData(buf, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (!sendAttachments(smtp, msg, parallel, true)) + return addSendingResult(smtp, msg, false, true); + + buf.clear(); + appendBoundaryString(buf, parallel.c_str(), true, false); + + if (!sendBDAT(smtp, msg, buf.length(), false)) + return false; + + if (!altSendData(buf, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + return true; +} + +bool ESP_Mail_Client::sendAttachments(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, bool parallel) +{ + MB_String s; + MB_String buf; + int cnt = 0; + + SMTP_Attachment *att = nullptr; + + size_t sz = msg->_att.size(); + if (parallel) + sz = msg->_parallel.size(); + + for (size_t i = 0; i < sz; i++) + { + if (parallel) + att = &msg->_parallel[i]; + else + att = &msg->_att[i]; + + if (att->_int.att_type == esp_mail_att_type_attachment) + { +#if !defined(SILENT_MODE) + altSendCallback(smtp, att->descr.filename.c_str(), att->descr.filename.c_str(), esp_mail_debug_tag_type_client, true, false); +#endif + cnt++; + + if (att->file.storage_type == esp_mail_file_storage_type_none) + { + if (!att->blob.data) + continue; + + if (att->blob.size == 0) + continue; + + buf.clear(); + getAttachHeader(buf, boundary, att, att->blob.size, false); + + if (!sendBDAT(smtp, msg, buf.length(), false)) + return false; + + if (!altSendData(buf, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (!sendBlobAttachment(smtp, msg, att)) + return false; + + if (!sendBDAT(smtp, msg, 2, false)) + return false; + + MB_String str; + appendNewline(str); + + if (!altSendData(str, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + } + else + { + if (att->file.storage_type == esp_mail_file_storage_type_sd && !smtp->_sdStorageChecked && !smtp->_sdStorageReady) + { + smtp->_sdStorageChecked = true; + smtp->_sdStorageReady = mbfs->sdReady(); + } + else if (att->file.storage_type == esp_mail_file_storage_type_flash && !smtp->_flashStorageChecked && !smtp->_flashStorageReady) + { + smtp->_flashStorageChecked = true; + smtp->_flashStorageReady = mbfs->flashReady(); + } + + if (!smtp->_flashStorageReady && !smtp->_sdStorageReady) + { + sendStorageNotReadyError(smtp, att->file.storage_type); + continue; + } + + if (openFileRead(smtp, msg, att, buf, boundary, false)) + { + + if (!sendFile(smtp, msg, att)) + return false; + + if (!sendBDAT(smtp, msg, 2, false)) + return false; + + MB_String str; + appendNewline(str); + + if (!altSendData(str, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + } + } + } + } + return true; +} + +void ESP_Mail_Client::altSendStorageErrorCB(SMTPSession *smtp, int err) +{ +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) + + if (smtp) + { + smtp->_responseStatus.errorCode = err; + smtp->_responseStatus.text.clear(); + +#if !defined(SILENT_MODE) + if (smtp->_statusCallback) + esp_mail_debug_print_tag(esp_mail_error_mem_str_3 /* "file does not exist or can't access" */, esp_mail_debug_tag_type_client, true); + + if (smtp->_debug) + esp_mail_debug_print_tag(smtp->errorReason().c_str(), esp_mail_debug_tag_type_error, true); +#endif + } + else if (imap && !calDataLen) + { +#if defined(ENABLE_IMAP) + + imap->_responseStatus.errorCode = err; + imap->_responseStatus.text.clear(); + +#if !defined(SILENT_MODE) + if (imap->_statusCallback) + esp_mail_debug_print_tag(esp_mail_error_mem_str_3 /* "file does not exist or can't access" */, esp_mail_debug_tag_type_client, true); + + if (imap->_debug) + { + esp_mail_debug_print_tag(smtp->errorReason().c_str(), esp_mail_debug_tag_type_error, true); + } +#endif +#endif + } + +#endif +} + +bool ESP_Mail_Client::openFileRead(SMTPSession *smtp, SMTP_Message *msg, SMTP_Attachment *att, MB_String &buf, const MB_String &boundary, bool inlined) +{ + int sz = -1; + MB_String filepath; + + if (att->file.path.length() > 0) + { + if (att->file.path[0] != '/') + filepath = esp_mail_str_10; /* "/" */ + filepath += att->file.path; + } + + sz = mbfs->open(filepath, mbfs_type att->file.storage_type, mb_fs_open_mode_read); + if (sz < 0) + { + + if (strlen(att->descr.filename.c_str()) > 0) + { + filepath.clear(); + if (att->descr.filename[0] != '/') + filepath = esp_mail_str_10; /* "/" */ + filepath += att->descr.filename; + } + + sz = mbfs->open(filepath, mbfs_type att->file.storage_type, mb_fs_open_mode_read); + } + + if (sz < 0) + { + altSendStorageErrorCB(smtp, sz); + } + else + { + + buf.clear(); + + getAttachHeader(buf, boundary, att, sz, inlined); + + if (!sendBDAT(smtp, msg, buf.length(), false)) + return false; + + if (!altSendData(buf, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + return true; + } + + return false; +} + +bool ESP_Mail_Client::openFileRead2(SMTPSession *smtp, SMTP_Message *msg, const char *path, esp_mail_file_storage_type storageType) +{ + + MB_String filepath; + + if (strlen(path) > 0) + { + if (path[0] != '/') + filepath = esp_mail_str_10; /* "/" */ + filepath += path; + } + + int sz = mbfs->open(filepath, mbfs_type storageType, mb_fs_open_mode_read); + if (sz < 0) + { + altSendStorageErrorCB(smtp, sz); + return false; + } + + return true; +} + +void ESP_Mail_Client::sendStorageNotReadyError(SMTPSession *smtp, esp_mail_file_storage_type storageType) +{ + +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) + +#if !defined(SILENT_MODE) + if (altIsCB(smtp)) + { + if (storageType == esp_mail_file_storage_type_flash) + { + esp_mail_debug_print_tag(esp_mail_error_mem_str_1 /* "flash Storage is not ready." */, esp_mail_debug_tag_type_error, true); +#if defined(MB_ARDUINO_PICO) + esp_mail_debug_print_tag(esp_mail_error_mem_str_10 /* "please make sure that the size of flash filesystem is not 0 in Pico." */, esp_mail_debug_tag_type_error, true); +#endif + } + else if (storageType == esp_mail_file_storage_type_sd) + esp_mail_debug_print_tag(esp_mail_error_mem_str_2 /* "SD Storage is not ready." */, esp_mail_debug_tag_type_error, true); + } + + if (altIsDebug(smtp)) + { + if (storageType == esp_mail_file_storage_type_flash) + { + esp_mail_debug_print_tag(esp_mail_error_mem_str_1 /* "flash Storage is not ready." */, esp_mail_debug_tag_type_error, true); +#if defined(MB_ARDUINO_PICO) + esp_mail_debug_print_tag(esp_mail_error_mem_str_10 /* "please make sure that the size of flash filesystem is not 0 in Pico." */, esp_mail_debug_tag_type_error, true); +#endif + } + else if (storageType == esp_mail_file_storage_type_sd) + esp_mail_debug_print_tag(esp_mail_error_mem_str_2 /* "SD Storage is not ready." */, esp_mail_debug_tag_type_error, true); + } +#endif + +#endif +} + +bool ESP_Mail_Client::sendInline(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary, byte type) +{ + size_t num = numAtt(smtp, esp_mail_att_type_inline, msg) > 0; + +#if !defined(SILENT_MODE) + if (num > 0) + altSendCallback(smtp, esp_mail_cb_str_8 /* "Sending inline data..." */, esp_mail_dbg_str_14 /* "send inline data" */, esp_mail_debug_tag_type_client, true, false); +#endif + MB_String buf; + MB_String related = getMIMEBoundary(15); + int cnt = 0; + SMTP_Attachment *att = nullptr; + + MB_String s; + + appendBoundaryString(s, boundary.c_str(), false, true); + + appendMultipartContentType(s, esp_mail_multipart_type_related, related.c_str()); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (!sendPartText(smtp, msg, type, related.c_str())) + return false; + +#if !defined(SILENT_MODE) + bool cb = altIsCB(smtp); + + if (cb && numAtt(smtp, esp_mail_att_type_inline, msg) > 0) + esp_mail_debug_print(); +#endif + + if (num > 0) + { + for (uint8_t i = 0; i < msg->_att.size(); i++) + { + att = &msg->_att[i]; + if (att->_int.att_type == esp_mail_att_type_inline) + { +#if !defined(SILENT_MODE) + altSendCallback(smtp, att->descr.filename.c_str(), att->descr.filename.c_str(), esp_mail_debug_tag_type_client, true, false); +#endif + cnt++; + + if (att->file.storage_type == esp_mail_file_storage_type_none) + { + if (!att->blob.data) + continue; + + if (att->blob.size == 0) + continue; +#if !defined(SILENT_MODE) + altSendCallback(smtp, att->descr.filename.c_str(), att->descr.filename.c_str(), esp_mail_debug_tag_type_client, true, false); +#endif + buf.clear(); + getAttachHeader(buf, related, att, att->blob.size, true); + + if (!sendBDAT(smtp, msg, buf.length(), false)) + return false; + + if (!altSendData(buf, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (!sendBlobAttachment(smtp, msg, att)) + return false; + + if (!sendBDAT(smtp, msg, 2, false)) + return false; + + MB_String str; + appendNewline(str); + + if (!altSendData(str, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + } + else + { + + if (att->file.storage_type == esp_mail_file_storage_type_sd && !smtp->_sdStorageChecked && !smtp->_sdStorageReady) + { + smtp->_sdStorageChecked = true; + smtp->_sdStorageReady = mbfs->sdReady(); + } + else if (att->file.storage_type == esp_mail_file_storage_type_flash && !smtp->_flashStorageChecked && !smtp->_flashStorageReady) + { + smtp->_flashStorageChecked = true; + smtp->_flashStorageReady = mbfs->flashReady(); + } + + if (!smtp->_flashStorageReady && !smtp->_sdStorageReady) + { + sendStorageNotReadyError(smtp, att->file.storage_type); + continue; + } + + if (openFileRead(smtp, msg, att, buf, related, true)) + { + if (!sendFile(smtp, msg, att)) + return false; + + if (!sendBDAT(smtp, msg, 2, false)) + return false; + + MB_String str; + appendNewline(str); + + if (!altSendData(str, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + } + } + } + } + } + + appendNewline(s); + + appendBoundaryString(s, related.c_str(), true, true); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + return true; +} + +size_t ESP_Mail_Client::smtpSend(SMTPSession *smtp, PGM_P data, bool newline) +{ + if (!smtp || !sessionReady(smtp)) + return 0; + + int sent = 0; + + MB_String s = data; + + int toSend = newline ? s.length() + 2 : s.length(); + +#if !defined(SILENT_MODE) + if (!smtp->_customCmdResCallback && smtp->_debugLevel > esp_mail_debug_level_maintainer) + esp_mail_debug_print(s.c_str(), newline); +#endif + + sent = newline ? smtp->client.println(s.c_str()) : smtp->client.print(s.c_str()); + + if (sent != toSend) + { + errorStatusCB(smtp, this->imap, sent, false); + sent = 0; + } + + return sent; +} + +size_t ESP_Mail_Client::smtpSend(SMTPSession *smtp, int data, bool newline) +{ + MB_String s = data; + return smtpSend(smtp, s.c_str(), newline); +} + +size_t ESP_Mail_Client::smtpSend(SMTPSession *smtp, uint8_t *data, size_t size) +{ + if (!smtp || !sessionReady(smtp)) + return 0; + + size_t sent = smtp->client.write(data, size); + + if (sent != size) + { + errorStatusCB(smtp, this->imap, sent, false); + sent = 0; + } + + return sent; +} + +bool ESP_Mail_Client::handleSMTPError(SMTPSession *smtp, int err, bool ret) +{ + + if (err < 0) + errorStatusCB(smtp, this->imap, err, false); + + if (smtp) + { + closeTCPSession(smtp); + } + else if (imap && !calDataLen) + { +#if defined(ENABLE_IMAP) + if (imap->connected()) + closeTCPSession(imap); +#endif + } + + return ret; +} + +bool ESP_Mail_Client::sendPartText(SMTPSession *smtp, SMTP_Message *msg, uint8_t type, const char *boundary) +{ + MB_String header; + + if (strlen(boundary) > 0) + appendBoundaryString(header, boundary, false, true); + + if (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) + { + if (msg->text.content_type.length() > 0) + { + appendHeaderField(header, message_headers[esp_mail_message_header_field_content_type].text, msg->text.content_type.c_str(), false, false); + + bool firstProp = true; + + if (msg->text.charSet.length() > 0) + appendHeaderProp(header, message_headers[esp_mail_message_header_field_charset].text, msg->text.charSet.c_str(), firstProp, true, true, false); + + if (msg->text.flowed) + { + appendHeaderProp(header, message_headers[esp_mail_message_header_field_format].text, "flowed", firstProp, true, true, false); + appendHeaderProp(header, message_headers[esp_mail_message_header_field_delsp].text, "no", firstProp, true, true, false); + } + + if (msg->text.embed.enable) + { + appendHeaderProp(header, message_headers[esp_mail_message_header_field_name].text, esp_mail_str_13 /* "msg.txt" */, firstProp, false, true, false); + char *uid = getRandomUID(); + msg->text._int.cid = uid; + // release memory + freeMem(&uid); + } + + appendNewline(header); + } + + if (msg->text.transfer_encoding.length() > 0) + appendHeaderField(header, message_headers[esp_mail_message_header_field_content_transfer_encoding].text, msg->text.transfer_encoding.c_str(), false, true); + } + else if (type == esp_mail_msg_type_html) + { + if (msg->text.content_type.length() > 0) + { + appendHeaderField(header, message_headers[esp_mail_message_header_field_content_type].text, msg->html.content_type.c_str(), false, false); + bool firstProp = true; + + if (msg->html.charSet.length() > 0) + appendHeaderProp(header, message_headers[esp_mail_message_header_field_charset].text, msg->html.charSet.c_str(), firstProp, true, true, false); + + if (msg->html.embed.enable) + { + appendHeaderProp(header, message_headers[esp_mail_message_header_field_name].text, esp_mail_str_14 /* "msg.html" */, firstProp, true, true, false); + char *uid = getRandomUID(); + msg->html._int.cid = uid; + // release memory + freeMem(&uid); + } + + appendNewline(header); + } + + if (msg->html.transfer_encoding.length() > 0) + appendHeaderField(header, message_headers[esp_mail_message_header_field_content_transfer_encoding].text, msg->html.transfer_encoding.c_str(), false, true); + } + + if ((type == esp_mail_msg_type_html && msg->html.embed.enable) || ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) && msg->text.embed.enable)) + { + + if ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) && msg->text.embed.enable) + appendEmbedMessage(header, msg->text, false); + else if (type == esp_mail_msg_type_html && msg->html.embed.enable) + appendEmbedMessage(header, msg->html, true); + } + + appendNewline(header); + + bool rawBlob = (msg->text.blob.size > 0 && (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched)) || (msg->html.blob.size > 0 && type == esp_mail_msg_type_html); + bool rawFile = (msg->text.file.name.length() > 0 && (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched)) || (msg->html.file.name.length() > 0 && type == esp_mail_msg_type_html); + bool rawContent = ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) && msg->text.content.length() > 0) || (type == esp_mail_msg_type_html && msg->html.content.length() > 0); + bool nonCopyContent = ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) && strlen(msg->text.nonCopyContent) > 0) || (type == esp_mail_msg_type_html && strlen(msg->html.nonCopyContent) > 0); + + if (rawBlob || rawFile || nonCopyContent) + { + if (!sendBDAT(smtp, msg, header.length(), false)) + return false; + + if (!altSendData(header, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + header.clear(); + + if (rawBlob || nonCopyContent) + { + if (!sendBlobBody(smtp, msg, type)) + return false; + } + else if (rawFile) + { + if (!sendFileBody(smtp, msg, type)) + return false; + } + } + else if (rawContent) + encodingText(smtp, msg, type, header); + + appendNewline(header); + + if (strlen(boundary) > 0) + appendNewline(header); + + if (!sendBDAT(smtp, msg, header.length(), false)) + return false; + + if (!altSendData(header, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + return true; +} + +bool ESP_Mail_Client::sendBlobBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type) +{ + + bool cb = altIsCB(smtp); + uint32_t addr = altProgressPtr(smtp); + + if (msg->text.blob.size == 0 && msg->html.blob.size == 0 && strlen(msg->text.nonCopyContent) == 0 && strlen(msg->html.nonCopyContent) == 0) + return true; + + bool ret = true; + int bufLen = 512; + size_t pos = 0; + + const uint8_t *raw = NULL; + int len = 0; + bool base64 = false; + + if ((type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched)) + { + if (strlen(msg->text.nonCopyContent) > 0) + { + raw = (const uint8_t *)msg->text.nonCopyContent; + len = strlen(msg->text.nonCopyContent); + } + else + { + raw = msg->text.blob.data; + len = msg->text.blob.size; + } + base64 = msg->text.transfer_encoding.length() > 0 && strcmp(msg->text.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0; + } + else if (type == esp_mail_msg_type_html) + { + if (strlen(msg->html.nonCopyContent) > 0) + { + raw = (const uint8_t *)msg->html.nonCopyContent; + len = strlen(msg->html.nonCopyContent); + } + else + { + raw = msg->html.blob.data; + len = msg->html.blob.size; + } + base64 = msg->html.transfer_encoding.length() > 0 && strcmp(msg->html.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0; + } + + if (base64) + { + MB_String s1 = esp_mail_str_15; /* "flash content message" */ + + esp_mail_smtp_send_base64_data_info_t data_info; + + data_info.flashMem = true; + data_info.filename = s1.c_str(); + data_info.rawPtr = raw; + data_info.size = len; + + return sendBase64(smtp, msg, data_info, true, cb); + } + + int available = len; + int sz = len; + uint8_t *buf = allocMem(bufLen + 1); + while (available) + { + if (available > bufLen) + available = bufLen; + + memcpy_P(buf, raw + pos, available); + + if (!sendBDAT(smtp, msg, available, false)) + { + ret = false; + break; + } + + if (!altSendData(buf, available, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + { + ret = false; + break; + } + + pos += available; + len -= available; + available = len; + + if (smtp->_debug) + { + MB_String s1 = esp_mail_str_15; /* "flash content message" */ + uploadReport(s1.c_str(), addr, 100 * pos / sz); + } + } + + // release memory + freeMem(&buf); + + return ret; +} + +bool ESP_Mail_Client::sendFileBody(SMTPSession *smtp, SMTP_Message *msg, uint8_t type) +{ + bool cb = altIsCB(smtp); + uint32_t addr = altProgressPtr(smtp); + + if (msg->text.file.name.length() == 0 && msg->html.file.name.length() == 0) + return true; + + bool ret = true; + int chunkSize = ESP_MAIL_CLIENT_STREAM_CHUNK_SIZE; + int writeLen = 0; + + if (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) + { + + if (!openFileRead2(smtp, msg, msg->text.file.name.c_str(), msg->text.file.type)) + return false; + + if (msg->text.transfer_encoding.length() > 0) + { + if (strcmp(msg->text.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) + { + MB_String s1 = esp_mail_str_16; /* "file content message" */ + + esp_mail_smtp_send_base64_data_info_t data_info; + + data_info.filename = s1.c_str(); + data_info.storageType = msg->text.file.type; + + return sendBase64(smtp, msg, data_info, true, cb); + } + } + + int fileSize = mbfs->size(mbfs_type msg->text.file.type); + + if (fileSize > 0) + { + + if (fileSize < chunkSize) + chunkSize = fileSize; + + uint8_t *buf = allocMem(chunkSize); + + while (writeLen < fileSize && mbfs->available(mbfs_type msg->text.file.type)) + { + if (writeLen > fileSize - chunkSize) + chunkSize = fileSize - writeLen; + int readLen = mbfs->read(mbfs_type msg->text.file.type, buf, chunkSize); + + if (readLen != chunkSize) + { + errorStatusCB(smtp, this->imap, MB_FS_ERROR_FILE_IO_ERROR, false); + break; + } + + if (!sendBDAT(smtp, msg, chunkSize, false)) + { + ret = false; + break; + } + + if (!altSendData(buf, chunkSize, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + { + ret = false; + break; + } + + if (smtp->_debug) + uploadReport(pgm2Str(esp_mail_str_16 /* "file content message" */), addr, 100 * writeLen / fileSize); + + writeLen += chunkSize; + } + + // release memory + freeMem(&buf); + + if (smtp->_debug) + uploadReport(pgm2Str(esp_mail_str_16 /* "file content message" */), addr, 100); + + return ret && writeLen == fileSize; + } + } + else if (type == esp_mail_message_type::esp_mail_msg_type_html) + { + + if (!openFileRead2(smtp, msg, msg->html.file.name.c_str(), msg->html.file.type)) + return false; + + if (msg->html.transfer_encoding.length() > 0) + { + if (strcmp(msg->html.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) + { + MB_String s1 = esp_mail_str_16; /* "file content message" */ + + esp_mail_smtp_send_base64_data_info_t data_info; + + data_info.filename = s1.c_str(); + data_info.storageType = msg->html.file.type; + + return sendBase64(smtp, msg, data_info, true, cb); + } + } + + int fileSize = mbfs->size(mbfs_type msg->html.file.type); + + if (fileSize > 0) + { + + if (fileSize < chunkSize) + chunkSize = fileSize; + + uint8_t *buf = allocMem(chunkSize); + + while (writeLen < fileSize && mbfs->available(mbfs_type msg->html.file.type)) + { + if (writeLen > fileSize - chunkSize) + chunkSize = fileSize - writeLen; + int readLen = mbfs->read(mbfs_type msg->html.file.type, buf, chunkSize); + + if (readLen != chunkSize) + { + errorStatusCB(smtp, this->imap, MB_FS_ERROR_FILE_IO_ERROR, false); + break; + } + + if (!sendBDAT(smtp, msg, chunkSize, false)) + { + ret = false; + break; + } + + if (!altSendData(buf, chunkSize, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + { + ret = false; + break; + } + + if (cb) + uploadReport(pgm2Str(esp_mail_str_16 /* "file content message" */), addr, 100 * writeLen / fileSize); + + writeLen += chunkSize; + } + + // release memory + freeMem(&buf); + + if (cb) + uploadReport(pgm2Str(esp_mail_str_16 /* "file content message" */), addr, 100); + + return ret && writeLen == fileSize; + } + } + + return false; +} + +void ESP_Mail_Client::encodingText(SMTPSession *smtp, SMTP_Message *msg, uint8_t type, MB_String &content) +{ + if (type == esp_mail_msg_type_plain || type == esp_mail_msg_type_enriched) + { + MB_String s = msg->text.content; + + if (msg->text.flowed) + formatFlowedText(s); + + if (msg->text.transfer_encoding.length() > 0) + { + if (strcmp(msg->text.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) + content += encodeBase64Str((const unsigned char *)s.c_str(), s.length()); + else if (strcmp(msg->text.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_qp) == 0) + { + char *out = allocMem(s.length() * 3 + 1); + encodeQP(s.c_str(), out); + content += out; + + // release memory + freeMem(&out); + } + else + content += s; + } + else + content += s; + } + else if (type == esp_mail_message_type::esp_mail_msg_type_html) + { + MB_String s = msg->html.content; + MB_String fnd, rep; + SMTP_Attachment *att = nullptr; + for (uint8_t i = 0; i < msg->_att.size(); i++) + { + att = &msg->_att[i]; + if (att->_int.att_type == esp_mail_att_type_inline) + { + MB_String filename(att->descr.filename); + + size_t found = filename.find_last_of("/\\"); + if (found != MB_String::npos) + filename = filename.substr(found + 1); + + appendString(fnd, filename.c_str(), false, false, esp_mail_string_mark_type_double_quote); + + MB_String cid = esp_mail_str_17; /* "cid:" */ + cid += att->descr.content_id.length() > 0 ? att->descr.content_id : att->_int.cid; + + appendString(rep, cid.c_str(), false, false, esp_mail_string_mark_type_double_quote); + + s.replaceAll(fnd, rep); + } + } + + if (msg->html.transfer_encoding.length() > 0) + { + if (strcmp(msg->html.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_base64) == 0) + content += encodeBase64Str((const unsigned char *)s.c_str(), s.length()); + else if (strcmp(msg->html.transfer_encoding.c_str(), Content_Transfer_Encoding::enc_qp) == 0) + { + char *out = allocMem(msg->html.content.length() * 3 + 1); + encodeQP(msg->html.content.c_str(), out); + content += out; + + // release memory + freeMem(&out); + } + else + content += s; + } + else + content += s; + s.clear(); + } + + if (msg->timestamp.tag.length() && msg->timestamp.format.length()) + content.replaceAll(msg->timestamp.tag, Time.getDateTimeString(Time.getCurrentTimestamp(), msg->timestamp.format.c_str())); +} + +void ESP_Mail_Client::encodeQP(const char *buf, char *out) +{ + int n = 0, p = 0, pos = 0; + for (n = 0; *buf; buf++) + { + if (n >= 73 && *buf != 10 && *buf != 13) + { + p = sprintf(out + pos, "=\r\n"); + pos += p; + n = 0; + } + + if (*buf == 10 || *buf == 13) + { + out[pos++] = *buf; + n = 0; + } + else if (*buf < 32 || *buf == 61 || *buf > 126) + { + p = sprintf(out + pos, "=%02X", (unsigned char)*buf); + n += p; + pos += p; + } + else if (*buf != 32 || (*(buf + 1) != 10 && *(buf + 1) != 13)) + { + out[pos++] = *buf; + n++; + } + else + { + p = sprintf(out + pos, "=20"); + n += p; + pos += p; + } + } +} + +/** Add the soft line break to the long text line (rfc 3676) + * and add Format=flowed parameter in the plain text content-type header. + * We use the existing white space as a part of this soft line break + * and set delSp="no" parameter to the header. + * + * Some servers are not rfc 3676 compliant. + * This causes the text lines are wrapped instead of joined. + * + * Some mail clients trim the space before the line break + * which makes the soft line break cannot be seen. + */ +void ESP_Mail_Client::formatFlowedText(MB_String &content) +{ + int count = 0; + MB_String qms; + int j = 0; + _vectorImpl tokens; + char *stk = strP(esp_mail_str_18); /* "\r\n" */ + char *qm = strP(esp_mail_str_20); /* ">" */ + splitToken(content.c_str(), tokens, stk); + content.clear(); + for (size_t i = 0; i < tokens.size(); i++) + { + if (tokens[i].length() > 0) + { + j = 0; + qms.clear(); + while (tokens[i][j] == qm[0]) + { + qms += qm; + j++; + } + softBreak(tokens[i], qms.c_str()); + if (count > 0) + content += stk; + content += tokens[i]; + } + else if (count > 0) + content += stk; + count++; + } + + // release memory + freeMem(&stk); + freeMem(&qm); + tokens.clear(); +} + +void ESP_Mail_Client::softBreak(MB_String &content, const char *quoteMarks) +{ + size_t len = 0; + char *stk = strP(esp_mail_str_2); /* " " */ + _vectorImpl tokens; + splitToken(content.c_str(), tokens, stk); + content.clear(); + for (size_t i = 0; i < tokens.size(); i++) + { + if (tokens[i].length() > 0) + { + if (len + tokens[i].length() + 3 > FLOWED_TEXT_LEN) + { + /* insert soft crlf */ + content += stk; + appendNewline(content); + + /* insert quote marks */ + if (strlen(quoteMarks) > 0) + content += quoteMarks; + content += tokens[i]; + len = tokens[i].length(); + } + else + { + if (len > 0) + { + content += stk; + len += strlen(stk); + } + content += tokens[i]; + len += tokens[i].length(); + } + } + } + + // release memory + freeMem(&stk); + tokens.clear(); +} + +bool ESP_Mail_Client::altSendData(MB_String &s, bool newLine, SMTPSession *smtp, SMTP_Message *msg, bool addSendResult, bool getResponse, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode) +{ + if (!imap && smtp) + { + if (smtpSend(smtp, s.c_str(), newLine) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + { + if (addSendResult) + return addSendingResult(smtp, msg, false, true); + else + return false; + } + + if (getResponse) + { + if (!handleSMTPResponse(smtp, cmd, statusCode, errCode)) + { + if (addSendResult) + return addSendingResult(smtp, msg, false, true); + else + return false; + } + } + } + else if (imap) + { +#if defined(ENABLE_IMAP) + if (newLine) + appendNewline(s); + MB_StringPtr data = toStringPtr(s); + + if (calDataLen) + dataLen += s.length(); + else + return imap->mSendData(data, false, esp_mail_imap_cmd_append); +#endif + } + + return true; +} + +bool ESP_Mail_Client::altSendData(uint8_t *data, size_t size, SMTPSession *smtp, SMTP_Message *msg, bool addSendResult, bool getResponse, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode) +{ + if (!imap && smtp) + { + if (smtpSend(smtp, data, size) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + { + if (addSendResult) + return addSendingResult(smtp, msg, false, true); + else + return false; + } + + if (getResponse) + { + if (!handleSMTPResponse(smtp, cmd, statusCode, errCode)) + { + if (addSendResult) + return addSendingResult(smtp, msg, false, true); + else + return false; + } + } + } + else if (imap) + { +#if defined(ENABLE_IMAP) + + if (calDataLen) + dataLen += size; + else + return imap->mSendData(data, size, false, esp_mail_imap_cmd_append); +#endif + } + + return true; +} + +bool ESP_Mail_Client::sendMSG(SMTPSession *smtp, SMTP_Message *msg, const MB_String &boundary) +{ + MB_String s; + + if (numAtt(smtp, esp_mail_att_type_inline, msg) > 0) + { + appendMultipartContentType(s, esp_mail_multipart_type_alternative, boundary.c_str()); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (msg->type == esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched || msg->type == esp_mail_msg_type_html) + { + if (!sendInline(smtp, msg, boundary, msg->type)) + return false; + } + else if (msg->type == (esp_mail_msg_type_html | esp_mail_msg_type_enriched | esp_mail_msg_type_plain)) + { + if (!sendPartText(smtp, msg, esp_mail_msg_type_plain, boundary.c_str())) + return false; + if (!sendInline(smtp, msg, boundary, esp_mail_msg_type_html)) + return false; + } + + appendBoundaryString(s, boundary.c_str(), true, true); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + } + else + { + if (msg->type == esp_mail_msg_type_plain || msg->type == esp_mail_msg_type_enriched || msg->type == esp_mail_msg_type_html) + { + if (!sendPartText(smtp, msg, msg->type, "")) + return false; + } + else if (msg->type == (esp_mail_msg_type_html | esp_mail_msg_type_enriched | esp_mail_msg_type_plain)) + { + appendMultipartContentType(s, esp_mail_multipart_type_alternative, boundary.c_str()); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + + if (!sendPartText(smtp, msg, esp_mail_msg_type_plain, boundary.c_str())) + return false; + + if (!sendPartText(smtp, msg, esp_mail_msg_type_html, boundary.c_str())) + return false; + + s.clear(); + appendBoundaryString(s, boundary.c_str(), true, false); + + if (!sendBDAT(smtp, msg, s.length(), false)) + return false; + + if (!altSendData(s, false, smtp, msg, true, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + return false; + } + } + return true; +} + +void ESP_Mail_Client::getAttachHeader(MB_String &header, const MB_String &boundary, SMTP_Attachment *attach, size_t size, bool isInline) +{ + appendBoundaryString(header, boundary.c_str(), false, true); + + appendHeaderName(header, message_headers[esp_mail_message_header_field_content_type].text); + + if (attach->descr.mime.length() == 0) + { + MB_String mime; + mimeFromFile(attach->descr.filename.c_str(), mime); + if (mime.length() > 0) + appendString(header, mime.c_str(), false, false); + else + appendString(header, mimeinfo[esp_mail_file_extension_binary].mimeType, false, false); + } + else + appendString(header, attach->descr.mime.c_str(), false, false); + + MB_String filename = attach->descr.filename; + + size_t found = filename.find_last_of("/\\"); + if (found != MB_String::npos) + filename = filename.substr(found + 1); + + bool firstProp = true; + + appendHeaderProp(header, message_headers[esp_mail_message_header_field_name].text, filename.c_str(), firstProp, false, true, true); + + if (isInline || (!isInline && !attach->_int.parallel)) + { + appendHeaderName(header, message_headers[esp_mail_message_header_field_content_disposition].text); + appendString(header, isInline ? esp_mail_content_disposition_type_t::inline_ : esp_mail_content_disposition_type_t::attachment, false, false); + + firstProp = true; + appendHeaderProp(header, message_headers[esp_mail_message_header_field_filename].text, filename.c_str(), firstProp, true, true, false); + appendHeaderProp(header, message_headers[esp_mail_message_header_field_size].text, MB_String((int)size).c_str(), firstProp, true, false, true); + } + + if (isInline) + { + + appendHeaderField(header, message_headers[esp_mail_message_header_field_content_location].text, filename.c_str(), false, true); + + appendHeaderName(header, message_headers[esp_mail_message_header_field_content_id].text); + if (attach->descr.content_id.length() > 0) + appendString(header, attach->descr.content_id.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + else + appendString(header, attach->_int.cid.c_str(), false, true, esp_mail_string_mark_type_angle_bracket); + } + + if (attach->descr.transfer_encoding.length() > 0) + appendHeaderField(header, message_headers[esp_mail_message_header_field_content_transfer_encoding].text, attach->descr.transfer_encoding.c_str(), false, true); + + if (attach->descr.description.length() > 0) + appendHeaderField(header, message_headers[esp_mail_message_header_field_content_description].text, attach->descr.description.c_str(), false, true); + + appendNewline(header); +} + +void ESP_Mail_Client::getRFC822PartHeader(SMTPSession *smtp, MB_String &header, const MB_String &boundary) +{ + appendBoundaryString(header, boundary.c_str(), false, true); + + appendHeaderName(header, message_headers[esp_mail_message_header_field_content_type].text); + appendString(header, esp_mail_str_22 /* "message/rfc822" */, false, true); + + appendHeaderName(header, message_headers[esp_mail_message_header_field_content_disposition].text); + appendString(header, esp_mail_content_disposition_type_t::attachment, false, true); + appendNewline(header); +} + +uint32_t ESP_Mail_Client::altProgressPtr(SMTPSession *smtp) +{ + uint32_t addr = 0; + if (smtp) + { + smtp->_lastProgress = -1; + addr = toAddr(smtp->_lastProgress); + } + else if (imap && !calDataLen) + { +#if defined(ENABLE_IMAP) + imap->_lastProgress = -1; + addr = toAddr(imap->_lastProgress); +#endif + } + + return addr; +} + +void ESP_Mail_Client::parseAuthCapability(SMTPSession *smtp, char *buf) +{ + if (!smtp) + return; + + if (strposP(buf, smtp_cmd_post_tokens[esp_mail_smtp_command_auth].c_str(), 0) > -1) + { + for (int i = esp_mail_auth_capability_plain; i < esp_mail_auth_capability_maxType; i++) + { + if (strposP(buf, smtp_auth_cap_pre_tokens[i].c_str(), 0) > -1) + { + smtp->_auth_capability[i] = true; + // Don't exit the loop + // and continue checking for all auth types + } + } + } + else if (strposP(buf, smtp_auth_capabilities[esp_mail_auth_capability_starttls].text, 0) > -1) + { + smtp->_auth_capability[esp_mail_auth_capability_starttls] = true; + return; + } + + for (int i = esp_mail_smtp_send_capability_binary_mime; i < esp_mail_smtp_send_capability_maxType; i++) + { + if (strposP(buf, smtp_send_cap_pre_tokens[i].c_str(), 0) > -1) + { + smtp->_feature_capability[i] = true; + return; + } + } +} + +bool ESP_Mail_Client::handleSMTPResponse(SMTPSession *smtp, esp_mail_smtp_command cmd, esp_mail_smtp_status_code statusCode, int errCode) +{ + if (!smtp) + return false; + + smtp->_smtp_cmd = cmd; + + if (!reconnect(smtp)) + return false; + + bool ret = false; + char *response = nullptr; + int readLen = 0; + long dataTime = millis(); + int chunkBufSize = 0; + MB_String s, r, err; + int chunkIndex = 0; + int count = 0; + bool completedResponse = false; + smtp->_responseStatus.errorCode = 0; + smtp->_responseStatus.statusCode = 0; + smtp->_responseStatus.text.clear(); + uint8_t minResLen = 5; + struct esp_mail_smtp_response_status_t status; + + bool canForward = smtp->_canForward; + smtp->_canForward = false; + + status.id = smtp->_commandID; + + chunkBufSize = smtp->client.available(); + + while (smtp->connected() && chunkBufSize <= 0) + { + if (!reconnect(smtp, dataTime)) + return false; + if (!connected(smtp)) + { + if (cmd != esp_mail_smtp_cmd_logout) + errorStatusCB(smtp, this->imap, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, false); + + return false; + } + chunkBufSize = smtp->client.available(); + yield_impl(); + } + + dataTime = millis(); + + if (chunkBufSize > 1) + { + while (!completedResponse) + { + yield_impl(); + + if (!reconnect(smtp, dataTime)) + return false; + + if (!connected(smtp)) + { + if (cmd != esp_mail_smtp_cmd_logout) + errorStatusCB(smtp, this->imap, MAIL_CLIENT_ERROR_CONNECTION_CLOSED, false); + return false; + } + + chunkBufSize = smtp->client.available(); + + if (chunkBufSize <= 0) + break; + + if (chunkBufSize > 0) + { + + chunkBufSize = ESP_MAIL_CLIENT_RESPONSE_BUFFER_SIZE; + response = allocMem(chunkBufSize + 1); + + read_line: + + MB_String ovfBuf; + if (!readResponse(smtp, response, chunkBufSize, readLen, false, count, ovfBuf)) + { + closeTCPSession(smtp); + errorStatusCB(smtp, this->imap, MAIL_CLIENT_ERROR_READ_TIMEOUT, false); + return false; + } + + // If buffer overflown, copy from overflow buffer + if (ovfBuf.length() > 0) + { + // release memory + freeMem(&response); + response = allocMem(ovfBuf.length() + 1); + strcpy(response, ovfBuf.c_str()); + ovfBuf.clear(); + } + + if (readLen) + { + if (smtp->_smtp_cmd != esp_mail_smtp_command::esp_mail_smtp_cmd_initial_state) + { + // sometimes server sent multiple lines response + // sometimes rx buffer is not ready for a while + + if (strlen(response) < minResLen) + { + r += response; + chunkBufSize = 0; + while (chunkBufSize == 0) + { + yield_impl(); + if (!reconnect(smtp, dataTime)) + return false; + chunkBufSize = smtp->client.available(); + } + } + else + { + if (r.length() > 0) + { + r += response; + memset(response, 0, chunkBufSize); + strcpy(response, r.c_str()); + } +#if !defined(SILENT_MODE) + if (!smtp->_customCmdResCallback && smtp->_debugLevel > esp_mail_debug_level_basic) + esp_mail_debug_print((const char *)response, true); +#endif + } + + if (smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_greeting) + parseAuthCapability(smtp, response); + } + + getResponseStatus(response, statusCode, 0, status); + + // No response code from greeting? + // Assumed multi-line greeting responses. + + if (status.statusCode == 0 && smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_initial_state) + { + +#if !defined(SILENT_MODE) + if (smtp->_debug && !smtp->_customCmdResCallback) + esp_mail_debug_print_tag(response, esp_mail_debug_tag_type_server, true); +#endif + + memset(response, 0, chunkBufSize + 1); + + // read again until we get the response code + goto read_line; + } + + // get the status code again for unexpected return code + if (smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_start_tls || status.statusCode == 0) + getResponseStatus(response, esp_mail_smtp_status_code_0, 0, status); + + smtp->_responseStatus = status; + + if ((status.statusCode > 0 && status.statusCode == statusCode) || + (smtp->_smtp_cmd == esp_mail_smtp_cmd_start_tls && status.statusCode == esp_mail_smtp_status_code_220) || + (canForward && statusCode == esp_mail_smtp_status_code_250 && status.statusCode == esp_mail_smtp_status_code_251) + + ) + { + ret = true; + } + + if (strlen(response) >= minResLen) + { +#if !defined(SILENT_MODE) + if (smtp->_debug) + { + if (!smtp->_customCmdResCallback) + { + appendDebugTag(s, esp_mail_debug_tag_type_server, true); + if (smtp->_responseStatus.statusCode != esp_mail_smtp_status_code_334) + s += response; + else + { + // base64 encoded server challenge message + size_t olen = 0; + char *decoded = (char *)decodeBase64((const unsigned char *)status.text.c_str(), status.text.length(), &olen); + if (decoded && olen > 0) + { + s.append(decoded, olen); + err = decoded; + } + + // release memory + freeMem(&decoded); + } + esp_mail_debug_print(s.c_str(), true); + } + } + +#endif + r.clear(); + } + + if (smtp->_customCmdResCallback && (smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_initial_state || smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_custom)) + { + struct esp_mail_smtp_response_status_t res = status; + res.text = response; + smtp->_customCmdResCallback(res); + } + + completedResponse = smtp->_responseStatus.statusCode > 0 && status.text.length() > minResLen; + + if (smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_auth_xoauth2 && smtp->_responseStatus.statusCode == esp_mail_smtp_status_code_334) + { + if (isOAuthError(response, readLen, chunkIndex, 4)) + { + smtp->_responseStatus.text = err; + smtp->_responseStatus.errorCode = SMTP_STATUS_XOAUTH2_AUTH_FAILED; + ret = false; + } + } + + chunkIndex++; + + if (smtp->_chunkedEnable && smtp->_smtp_cmd == esp_mail_smtp_command::esp_mail_smtp_cmd_chunk_termination) + completedResponse = smtp->_chunkCount == chunkIndex; + } + + // release memory + freeMem(&response); + } + } + + if (!ret && !smtp->_customCmdResCallback) + handleSMTPError(smtp, errCode, false); + } + + return ret; +} + +void ESP_Mail_Client::getResponseStatus(const char *buf, esp_mail_smtp_status_code statusCode, int beginPos, struct esp_mail_smtp_response_status_t &status) +{ + if (statusCode > esp_mail_smtp_status_code_0) + { + int codeLength = 3; + int textLength = strlen(buf) - codeLength - 1; + + if ((int)strlen(buf) > codeLength && (buf[codeLength] == ' ' || buf[codeLength] == '-') && textLength > 0) + { + char *tmp = nullptr; + tmp = allocMem(codeLength + 1); + memcpy(tmp, &buf[0], codeLength); + + int code = atoi(tmp); + + // release memory + freeMem(&tmp); + + if (buf[codeLength] == ' ') + status.statusCode = code; + + int i = codeLength + 1; + + // We will collect the status text starting from status code 334 and 4xx + // The status text of 334 will be used for debugging display of the base64 server challenge + if (code == esp_mail_smtp_status_code_334 || code >= esp_mail_smtp_status_code_421) + { + // find the next sp + while (i < (int)strlen(buf) && buf[i] != ' ') + i++; + + // if sp found, set index to the next pos, otherwise set index to num length + 1 + i = (i < (int)strlen(buf) - 1) ? i + 1 : codeLength + 1; + + tmp = allocMem(textLength + 1); + memcpy(tmp, &buf[i], strlen(buf) - i - 1); + status.text += tmp; + // release memory + freeMem(&tmp); + } + } + } +} + +void ESP_Mail_Client::uploadReport(const char *filename, uint32_t pgAddr, int progress) +{ + if (pgAddr == 0) + return; + + int *lastProgress = addrTo(pgAddr); + + printProgress(progress, *lastProgress); +} + +MB_String ESP_Mail_Client::getMIMEBoundary(size_t len) +{ + MB_String tmp = boundary_table; + char *buf = allocMem(len); + if (len) + { + --len; + buf[0] = tmp[0]; + buf[1] = tmp[1]; + for (size_t n = 2; n < len; n++) + { + int key = rand() % (int)(tmp.length() - 1); + buf[n] = tmp[key]; + } + buf[len] = '\0'; + } + MB_String s = buf; + // release memory + freeMem(&buf); + return s; +} + +int ESP_Mail_Client::chunkAvailable(SMTPSession *smtp, esp_mail_smtp_send_base64_data_info_t &data_info) +{ + if (!data_info.rawPtr) + { + int fileSize = mbfs->size(mbfs_type data_info.storageType); + if (!fileSize) + { + errorStatusCB(smtp, this->imap, MB_FS_ERROR_FILE_IO_ERROR, false); + return -1; + } + + return mbfs->available(mbfs_type data_info.storageType); + } + + return data_info.size - data_info.dataIndex; +} + +int ESP_Mail_Client::getChunk(SMTPSession *smtp, esp_mail_smtp_send_base64_data_info_t &data_info, unsigned char *rawChunk, bool base64) +{ + int available = chunkAvailable(smtp, data_info); + + if (available <= 0) + return available; + + size_t size = base64 ? 3 : 4; + + if (data_info.dataIndex + size > data_info.size) + size = data_info.size - data_info.dataIndex; + + if (!data_info.rawPtr) + { + + int readLen = mbfs->read(mbfs_type data_info.storageType, rawChunk, size); + + if (readLen >= 0) + data_info.dataIndex += readLen; + + return readLen; + } + + if (data_info.flashMem) + memcpy_P(rawChunk, data_info.rawPtr + data_info.dataIndex, size); + else + memcpy(rawChunk, data_info.rawPtr + data_info.dataIndex, size); + + data_info.dataIndex += size; + + return size; +} + +void ESP_Mail_Client::closeChunk(esp_mail_smtp_send_base64_data_info_t &data_info) +{ + if (!data_info.rawPtr) + { + mbfs->close(mbfs_type data_info.storageType); + } +} + +bool ESP_Mail_Client::sendBase64(SMTPSession *smtp, SMTP_Message *msg, esp_mail_smtp_send_base64_data_info_t &data_info, bool base64, bool report) +{ + int size = chunkAvailable(smtp, data_info); + + if (size <= 0) + return false; + + data_info.size = size; + + bool ret = false; + + uint32_t addr = altProgressPtr(smtp); + + size_t chunkSize = (BASE64_CHUNKED_LEN * UPLOAD_CHUNKS_NUM) + (2 * UPLOAD_CHUNKS_NUM); + int bufIndex = 0; + bool dataReady = false; + int encodedCount = 0; + int read = 0; + + if (!base64) + { + if (data_info.size < chunkSize) + chunkSize = data_info.size; + } + + uint8_t *buf = allocMem(chunkSize); + memset(buf, 0, chunkSize); + + uint8_t *rawChunk = allocMem(base64 ? 3 : 4); + + if (report) + uploadReport(data_info.filename, addr, data_info.dataIndex / data_info.size); + + int min = base64 ? 3 : 1; + + while (chunkAvailable(smtp, data_info)) + { + + if (chunkAvailable(smtp, data_info) >= min) + { + + read = getChunk(smtp, data_info, rawChunk, base64); + + if (!read) + goto ex; + + getBuffer(base64, buf, rawChunk, encodedCount, bufIndex, dataReady, read, chunkSize); + + if (dataReady) + { + + if (!sendBDAT(smtp, msg, base64 ? bufIndex : bufIndex + 1, false)) + goto ex; + + if (!altSendData(buf, base64 ? bufIndex : bufIndex + 1, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + goto ex; + + memset(buf, 0, chunkSize); + bufIndex = 0; + } + + if (report) + uploadReport(data_info.filename, addr, 100 * data_info.dataIndex / data_info.size); + } + else if (base64) + { + read = getChunk(smtp, data_info, rawChunk, base64); + if (!read) + goto ex; + } + } + + closeChunk(data_info); + + if (base64) + { + if (bufIndex > 0) + { + if (!sendBDAT(smtp, msg, bufIndex, false)) + goto ex; + + if (!altSendData(buf, bufIndex, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + goto ex; + } + + if (read) + { + memset(buf, 0, chunkSize); + bufIndex = 0; + buf[bufIndex++] = b64_index_table[rawChunk[0] >> 2]; + if (read == 1) + { + buf[bufIndex++] = b64_index_table[(rawChunk[0] & 0x03) << 4]; + buf[bufIndex++] = '='; + } + else + { + buf[bufIndex++] = b64_index_table[((rawChunk[0] & 0x03) << 4) | (rawChunk[1] >> 4)]; + buf[bufIndex++] = b64_index_table[(rawChunk[1] & 0x0f) << 2]; + } + buf[bufIndex++] = '='; + + if (!sendBDAT(smtp, msg, bufIndex, false)) + goto ex; + + if (!altSendData(buf, bufIndex, smtp, msg, false, false, esp_mail_smtp_cmd_undefined, esp_mail_smtp_status_code_0, SMTP_STATUS_UNDEFINED)) + goto ex; + } + } + + ret = true; + + if (report) + uploadReport(data_info.filename, addr, 100); + +ex: + // release memory + freeMem(&buf); + freeMem(&rawChunk); + + if (!ret) + closeChunk(data_info); + + return ret; +} + +void ESP_Mail_Client::getBuffer(bool base64, uint8_t *out, uint8_t *in, int &encodedCount, int &bufIndex, bool &dataReady, int &size, size_t chunkSize) +{ + if (base64) + { + size = 0; + out[bufIndex++] = b64_index_table[in[0] >> 2]; + out[bufIndex++] = b64_index_table[((in[0] & 0x03) << 4) | (in[1] >> 4)]; + out[bufIndex++] = b64_index_table[((in[1] & 0x0f) << 2) | (in[2] >> 6)]; + out[bufIndex++] = b64_index_table[in[2] & 0x3f]; + + encodedCount += 4; + + if (encodedCount == BASE64_CHUNKED_LEN) + { + if (bufIndex + 1 < (int)chunkSize) + { + out[bufIndex++] = 0x0d; + out[bufIndex++] = 0x0a; + } + encodedCount = 0; + } + + dataReady = bufIndex >= (int)chunkSize - 4; + } + else + { + memcpy(out + bufIndex, in, size); + bufIndex += size; + + if (bufIndex + 1 == BASE64_CHUNKED_LEN) + { + if (bufIndex + 2 < (int)chunkSize) + { + out[bufIndex++] = 0x0d; + out[bufIndex++] = 0x0a; + } + } + + dataReady = bufIndex + 1 >= (int)chunkSize - size; + } +} + +MB_FS *ESP_Mail_Client::getMBFS() +{ + return mbfs; +} + +SMTPSession::SMTPSession(Client *client) +{ + setClient(client); +} + +SMTPSession::SMTPSession() +{ +} + +SMTPSession::~SMTPSession() +{ + closeSession(); +} + +bool SMTPSession::connect(Session_Config *session_config, bool login) +{ + _sessionSSL = false; + _sessionLogin = login; + + if (session_config) + session_config->clearPorts(); + + this->_customCmdResCallback = NULL; + + int ptr = toAddr(*session_config); + session_config->addPtr(&_configPtrList, ptr); + + if (!handleConnection(session_config, _sessionSSL)) + return false; + + if (!_sessionLogin) + return true; + + _loginStatus = MailClient.smtpAuth(this, _sessionSSL); + + return _loginStatus; +} + +bool SMTPSession::mLogin(MB_StringPtr email, MB_StringPtr password, bool isToken) +{ + if (_loginStatus) + return true; + + if (!MailClient.sessionExisted(this)) + return false; + + _session_cfg->login.email = email; + + _session_cfg->login.accessToken.clear(); + _session_cfg->login.password.clear(); + + if (isToken) + _session_cfg->login.accessToken = password; + else + _session_cfg->login.password = password; + + _loginStatus = MailClient.smtpAuth(this, _sessionSSL); + + return _loginStatus; +} + +bool SMTPSession::isAuthenticated() +{ + return _authenticated; +} + +bool SMTPSession::isLoggedIn() +{ + return _loginStatus; +} + +int SMTPSession::customConnect(Session_Config *session_config, smtpResponseCallback callback, int commandID) +{ + this->_customCmdResCallback = callback; + + if (commandID > -1) + this->_commandID = commandID; + else + this->_commandID++; + + bool ssl = false; + if (!handleConnection(session_config, ssl)) + return -1; + + return this->_responseStatus.statusCode; +} + +bool SMTPSession::handleConnection(Session_Config *session_config, bool &ssl) +{ + _session_cfg = session_config; + + if (!client.isInitialized()) + return MailClient.handleSMTPError(this, TCP_CLIENT_ERROR_NOT_INITIALIZED); + + // Resources are also released if network disconnected. + if (!MailClient.reconnect(this)) + return false; + + // Close previous connection first to free resources. + MailClient.closeTCPSession(this); + + _session_cfg = session_config; + + MailClient.setCert(_session_cfg, _session_cfg->certificate.cert_data); + + ssl = false; + + if (!connect(ssl)) + { + MailClient.closeTCPSession(this); + return false; + } + + return true; +} + +bool SMTPSession::connect(bool &ssl) +{ + if (!MailClient.reconnect(this)) + return false; + + ssl = false; + _secure = true; + bool secureMode = true; + + MB_String s; + + client.rxBufDivider = 16; // minimum rx buffer for smtp status response + client.txBufDivider = 8; // medium tx buffer for faster attachment/inline data transfer + + MailClient.preparePortFunction(_session_cfg, true, _secure, secureMode, ssl); + +#if !defined(SILENT_MODE) + MailClient.printLibInfo(this); +#endif + + MailClient.prepareTime(_session_cfg, this); + + MailClient.setSecure(client, _session_cfg); + + if (!MailClient.beginConnection(_session_cfg, this, secureMode)) + return false; + + // server connected +#if !defined(SILENT_MODE) + if (!_customCmdResCallback) + { + + MailClient.printDebug(this, + esp_mail_dbg_str_4 /* "SMTP server connected" */, + esp_mail_cb_str_12 /* "SMTP server connected, wait for greeting..." */, + esp_mail_debug_tag_type_client, + true, + false); + } +#endif + + client.setTimeout(tcpTimeout); + + // expected success status code 220 for ready to service + // expected failure status code 421 + if (!MailClient.handleSMTPResponse(this, esp_mail_smtp_cmd_initial_state, esp_mail_smtp_status_code_220, SMTP_STATUS_SMTP_GREETING_GET_RESPONSE_FAILED)) + return false; + + return true; +} + +int SMTPSession::mSendCustomCommand(MB_StringPtr cmd, smtpResponseCallback callback, int commandID) +{ + _customCmdResCallback = callback; + + if (commandID > -1) + _commandID = commandID; + else + _commandID++; + + MB_String _cmd = cmd; + + if (MailClient.smtpSend(this, _cmd.c_str(), true) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return -1; + + if (!MailClient.handleSMTPResponse(this, esp_mail_smtp_cmd_custom, esp_mail_smtp_status_code_0, SMTP_STATUS_SEND_CUSTOM_COMMAND_FAILED)) + return -1; + + bool tlsCmd = false; + for (int i = esp_mail_auth_capability_plain; i < esp_mail_auth_capability_maxType; i++) + { + if (MailClient.strposP(_cmd.c_str(), smtp_auth_capabilities[i].text, 0) > -1) + { + if (i == esp_mail_auth_capability_starttls) + tlsCmd = true; + else + _waitForAuthenticate = true; + } + } + + if (MailClient.strposP(_cmd.c_str(), smtp_commands[esp_mail_smtp_command_quit].text, 0, false) > -1) + { + _authenticated = false; + _waitForAuthenticate = false; + } + + if (_waitForAuthenticate && _responseStatus.statusCode == esp_mail_smtp_status_code_235) + { + _authenticated = true; + _waitForAuthenticate = false; + _loginStatus = true; + } + + if (tlsCmd) + { + bool verify = false; + + if (_session_cfg) + verify = _session_cfg->certificate.verify; + + if (!client.connectSSL(verify)) + return false; + + // set the secure mode + if (_session_cfg) + { + // We reset the prefer connection mode in case user set it. + _session_cfg->secure.startTLS = false; + _session_cfg->secure.mode = esp_mail_secure_mode_undefined; + } + + _secure = true; + } + + return this->_responseStatus.statusCode; +} + +bool SMTPSession::mSendData(MB_StringPtr data) +{ + + MB_String _data = data; + + if (MailClient.smtpSend(this, _data.c_str(), false) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + return true; +} + +bool SMTPSession::mSendData(uint8_t *data, size_t size) +{ + + if (MailClient.smtpSend(this, data, size) == ESP_MAIL_CLIENT_TRANSFER_DATA_FAILED) + return false; + + return true; +} + +void SMTPSession::debug(int level) +{ + if (level > esp_mail_debug_level_none) + { + if (level > esp_mail_debug_level_basic && level < esp_mail_debug_level_maintainer) + level = esp_mail_debug_level_basic; + _debugLevel = level; + _debug = true; + client.setDebugLevel(level); + } + else + { + _debugLevel = esp_mail_debug_level_none; + _debug = false; + client.setDebugLevel(0); + } +} + +String SMTPSession::errorReason() +{ + String s = MailClient.errorReason(true, _responseStatus.errorCode, ""); + return s; +} + +int SMTPSession::statusCode() +{ + return _responseStatus.statusCode; +} + +String SMTPSession::statusMessage() +{ + return _responseStatus.text.c_str(); +} + +int SMTPSession::errorCode() +{ + return _responseStatus.errorCode; +} + +bool SMTPSession::closeSession() +{ + + if (!connected()) + return false; + + _cbData._sentSuccess = _sentSuccessCount; + _cbData._sentFailed = _sentFailedCount; + +#if !defined(SILENT_MODE) + MailClient.printDebug(this, + esp_mail_cb_str_7 /* "Closing the session..." */, + esp_mail_dbg_str_11 /* "terminate the SMTP session" */, + esp_mail_debug_tag_type_client, + true, + false); +#endif + + bool ret = true; + + if (_loginStatus) + { + +/* Sign out */ +#if !defined(ESP8266) + + // QUIT command asks SMTP server to close the TCP session. + // The connection may drop immediately. + + // There is memory leaks bug in ESP8266 BearSSLWiFiClientSecure class when the remote server + // drops the connection. + + ret = MailClient.smtpSend(this, smtp_commands[esp_mail_smtp_command_quit].text, true) > 0; + + // This may return false due to connection drops before get any response. + + // expected success status code 221 + // expected error status code 500 + MailClient.handleSMTPResponse(this, esp_mail_smtp_cmd_logout, esp_mail_smtp_status_code_221, SMTP_STATUS_SEND_BODY_FAILED); + + if (_responseStatus.statusCode == esp_mail_smtp_status_code_500) + return false; +#endif + + if (ret) + { + +#if !defined(SILENT_MODE) + if (_sentSuccessCount > 0) + { + MailClient.printDebug(this, + esp_mail_cb_str_13 /* "Message sent successfully" */, + esp_mail_dbg_str_12 /* "message sent successfully" */, + esp_mail_debug_tag_type_client, + true, + false); + } + + if (_statusCallback) + MailClient.callBackSendNewLine(this, true); +#endif + + _authenticated = false; + _waitForAuthenticate = false; + } + } + +#if !defined(SILENT_MODE) + if (_statusCallback) + sendingResult.clear(); +#endif + + return MailClient.handleSMTPError(this, 0, ret); +} + +bool SMTPSession::connected() +{ + return client.connected(); +} + +void SMTPSession::callback(smtpStatusCallback smtpCallback) +{ + _statusCallback = smtpCallback; +} + +SMTP_Status SMTPSession::status() +{ + return _cbData; +} + +void SMTPSession::setSystemTime(time_t ts, float gmtOffset) +{ + MailClient.Time.setTimestamp(ts, gmtOffset); +} + +void SMTPSession::keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount) +{ + this->client.keepAlive(tcpKeepIdleSeconds, tcpKeepIntervalSeconds, tcpKeepCount); +} + +bool SMTPSession::isKeepAlive() +{ + return this->client.isKeepAlive(); +} + +void SMTPSession::setTCPTimeout(unsigned long timeoutSec) +{ + tcpTimeout = timeoutSec; +} + +void SMTPSession::setClient(Client *client) +{ + this->client.setClient(client); +} + +void SMTPSession::setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password) +{ + this->client.setGSMClient(client, modem, pin, apn, user, password); +} + +void SMTPSession::networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB) +{ + this->client.networkConnectionRequestCallback(networkConnectionCB); +} + +void SMTPSession::networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB) +{ + this->client.networkStatusRequestCallback(networkStatusCB); +} + +void SMTPSession::setNetworkStatus(bool status) +{ + this->client.setNetworkStatus(status); + MailClient.networkStatus = status; +} + +void SMTPSession::setSSLBufferSize(int rx, int tx) +{ + this->client.setIOBufferSize(rx, tx); +} + +SMTP_Status::SMTP_Status() +{ +} + +SMTP_Status::~SMTP_Status() +{ + empty(); +} + +const char *SMTP_Status::info() +{ + return _info.c_str(); +} + +bool SMTP_Status::success() +{ + return _success; +} + +size_t SMTP_Status::completedCount() +{ + return _sentSuccess; +} + +size_t SMTP_Status::failedCount() +{ + return _sentFailed; +} + +void SMTP_Status::empty() +{ + _info.clear(); +} + +#endif + +#endif /* ESP_MAIL_SMTP_H */ diff --git a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_TCPClient.h b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_TCPClient.h index 1656a64f0..a3e1c43bd 100644 --- a/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_TCPClient.h +++ b/lib/libesp32/ESP-Mail-Client/src/ESP_Mail_TCPClient.h @@ -1,1094 +1,1094 @@ -/** - * - * The Network Upgradable Arduino Secure TCP Client Class, ESP_Mail_TCPClient.h v1.0.1 - * - * Created August 27, 2023 - * - * The MIT License (MIT) - * Copyright (c) 2023 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person returning 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 ESP_MAIL_TCPCLIENT_H -#define ESP_MAIL_TCPCLIENT_H - -#include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30409) -#error "Mixed versions compilation." -#endif - -#pragma GCC diagnostic ignored "-Wunused-variable" -#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" - -#include "ESP_Mail_Const.h" - -#if defined(ESP32) && (defined(ENABLE_SMTP) || defined(ENABLE_IMAP)) -#include "IPAddress.h" -#include "lwip/sockets.h" -#endif - -#if defined(ESP32) - -#include "ESP8266WiFi.h" -#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) -#define WIFI_HAS_HOST_BY_NAME -#endif -#include "extras/WiFiClientImpl.h" -#define BASE_WIFICLIENT WiFiClientImpl - -#elif defined(ESP_MAIL_WIFI_IS_AVAILABLE) -#include "WiFiClient.h" -#define BASE_WIFICLIENT WiFiClient -#endif - -#include "SSLClient/ESP_SSLClient.h" - -class ESP_Mail_TCPClient -{ -public: - ESP_Mail_TCPClient() - { -#if !defined(ESP_MAIL_DISABLE_SSL) - _tcp_client = new ESP_SSLClient(); -#endif - } - - ~ESP_Mail_TCPClient() - { - clear(); -#if !defined(ESP_MAIL_DISABLE_SSL) - if (_tcp_client) - delete _tcp_client; - _tcp_client = nullptr; -#endif - } - - /** - * Set the client. - * @param client The Client interface. - */ - void setClient(Client *client) - { - clear(); - _basic_client = client; - _client_type = esp_mail_client_type_external_basic_client; - } - - /** Assign TinyGsm Clients. - * - * @param client The pointer to TinyGsmClient. - * @param modem The pointer to TinyGsm modem object. Modem should be initialized and/or set mode before transfering data - * @param pin The SIM pin. - * @param apn The GPRS APN (Access Point Name). - * @param user The GPRS user. - * @param password The GPRS password. - */ - void setGSMClient(Client *client, void *modem = nullptr, const char *pin = nullptr, const char *apn = nullptr, const char *user = nullptr, const char *password = nullptr) - { -#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) - _pin = pin; - _apn = apn; - _user = user; - _password = password; - _modem = modem; - _client_type = esp_mail_client_type_external_gsm_client; - _basic_client = client; -#endif - } - - /** - * Set Root CA certificate to verify. - * @param caCert The certificate. - */ - void setCACert(const char *caCert) - { -#if !defined(ESP_MAIL_DISABLE_SSL) - if (caCert) - { - if (_x509) - delete _x509; - - _x509 = new X509List(caCert); - _tcp_client->setTrustAnchors(_x509); - - setCertType(esp_mail_cert_type_data); - setTA(true); - } - else - { - setCertType(esp_mail_cert_type_none); - setInSecure(); - } -#endif - } - - /** - * Set Root CA certificate to verify. - * @param certFile The certificate file path. - * @param storageType The storage type mb_fs_mem_storage_type_flash or mb_fs_mem_storage_type_sd. - * @return true when certificate loaded successfully. - */ - bool setCertFile(const char *certFile, mb_fs_mem_storage_type storageType) - { -#if !defined(ESP_MAIL_DISABLE_SSL) - if (!_mbfs) - return false; - - if (_clock_ready && strlen(certFile) > 0) - { - MB_String filename = certFile; - if (filename.length() > 0) - { - if (filename[0] != '/') - filename.prepend('/'); - } - - int len = _mbfs->open(filename, storageType, mb_fs_open_mode_read); - if (len > -1) - { - uint8_t *der = (uint8_t *)_mbfs->newP(len); - if (_mbfs->available(storageType)) - _mbfs->read(storageType, der, len); - _mbfs->close(storageType); - - if (_x509) - delete _x509; - - _x509 = new X509List(der, len); - _tcp_client->setTrustAnchors(_x509); - setTA(true); - _mbfs->delP(&der); - - setCertType(esp_mail_cert_type_file); - } - } -#endif - - return getCertType() == esp_mail_cert_type_file; - } - - /** - * Set TCP connection time out in seconds. - * @param timeoutSec The time out in seconds. - */ - void setTimeout(uint32_t timeoutSec) - { - _tcp_client->setTimeout(timeoutSec * 1000); - } - - /** Set the BearSSL IO buffer size. - * - * @param rx The BearSSL receive buffer size in bytes. - * @param tx The BearSSL trasmit buffer size in bytes. - */ - void setIOBufferSize(int rx, int tx) - { - _rx_size = rx; - _tx_size = tx; - } - - /** - * Get the ethernet link status. - * @return true for link up or false for link down. - */ - bool ethLinkUp() - { - bool ret = false; - -#if !defined(ESP_MAIL_DISABLE_NATIVE_ETHERNET) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) - -#if defined(ESP_MAIL_ETH_IS_AVAILABLE) - -#if defined(ESP32) - if (validIP(ETH.localIP())) - { - ETH.linkUp(); - ret = true; - } -#elif defined(ESP8266) - -#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) - if (!_session_config) - return false; -#endif - -#if defined(ESP8266) && defined(ESP8266_CORE_SDK_V3_X_X) - -#if defined(INC_ENC28J60_LWIP) - if (_session_config->spi_ethernet_module.enc28j60) - { - ret = _session_config->spi_ethernet_module.enc28j60->status() == WL_CONNECTED; - goto ex; - } -#endif -#if defined(INC_W5100_LWIP) - if (_session_config->spi_ethernet_module.w5100) - { - ret = _session_config->spi_ethernet_module.w5100->status() == WL_CONNECTED; - goto ex; - } -#endif -#if defined(INC_W5500_LWIP) - if (_session_config->spi_ethernet_module.w5500) - { - ret = _session_config->spi_ethernet_module.w5500->status() == WL_CONNECTED; - goto ex; - } -#endif -#elif defined(MB_ARDUINO_PICO) - -#endif - - return ret; - -#if defined(INC_ENC28J60_LWIP) || defined(INC_W5100_LWIP) || defined(INC_W5500_LWIP) - ex: -#endif - // workaround for ESP8266 Ethernet - delayMicroseconds(0); -#endif - -#endif - -#endif - - return ret; - } - - /** - * Checking for valid IP. - * @return true for valid. - */ - bool validIP(IPAddress ip) - { - char buf[16]; - sprintf(buf, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); - return strcmp(buf, "0.0.0.0") != 0; - } - - /** - * Ethernet DNS workaround. - */ - void ethDNSWorkAround() - { - -#if !defined(ESP_MAIL_DISABLE_NATIVE_ETHERNET) && (defined(ENABLE_SMTP) || defined(ENABLE_IMAP)) - if (!_session_config) - return; - -#if defined(ESP8266_CORE_SDK_V3_X_X) - -#if defined(INC_ENC28J60_LWIP) - if (_session_config->spi_ethernet_module.enc28j60) - goto ex; -#endif -#if defined(INC_W5100_LWIP) - if (_session_config->spi_ethernet_module.w5100) - goto ex; -#endif -#if defined(INC_W5500_LWIP) - if (_session_config->spi_ethernet_module.w5500) - goto ex; -#endif - -#elif defined(MB_ARDUINO_PICO) - -#endif - - return; - -#if defined(INC_ENC28J60_LWIP) || defined(INC_W5100_LWIP) || defined(INC_W5500_LWIP) - ex: -#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) - BASE_WIFICLIENT client; - client.connect(_session_config->server.host_name.c_str(), _session_config->server.port); - client.stop(); -#endif -#endif - -#endif - } - - /** - * Get the network status. - * @return true for connected or false for not connected. - */ - bool networkReady() - { - - // We will not invoke the network status request when device has built-in WiFi or Ethernet and it is connected. - if (_client_type == esp_mail_client_type_external_gsm_client) - { - _network_status = gprsConnected(); - if (!_network_status) - gprsConnect(); - } - else if (WiFI_CONNECTED || ethLinkUp()) - _network_status = true; - else if (_client_type == esp_mail_client_type_external_basic_client) - { - if (!_network_status_cb) - _last_error = 1; - else - _network_status_cb(); - } - - return _network_status; - } - - /** - * Reconnect the network. - */ - void networkReconnect() - { - - if (_client_type == esp_mail_client_type_external_basic_client) - { -#if defined(ESP_MAIL_HAS_WIFI_DISCONNECT) - // We can reconnect WiFi when device connected via built-in WiFi that supports reconnect - if (WiFI_CONNECTED) - { - WiFi.reconnect(); - return; - } - -#endif - - if (_network_connection_cb) - _network_connection_cb(); - } - else if (_client_type == esp_mail_client_type_external_gsm_client) - { - gprsDisconnect(); - gprsConnect(); - } - else if (_client_type == esp_mail_client_type_internal_basic_client) - { - -#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) -#if defined(ESP32) || defined(ESP8266) - WiFi.reconnect(); -#else - if (_wifi_multi && _wifi_multi->credentials.size()) - _wifi_multi->reconnect(); -#endif -#endif - } - } - - /** - * Disconnect the network. - */ - void networkDisconnect() {} - - /** - * Get the Client type. - * @return The esp_mail_client_type enum value. - */ - esp_mail_client_type type() { return _client_type; } - - /** - * Get the Client initialization status. - * @return The initialization status. - */ - bool isInitialized() - { - bool rdy = true; -#if !defined(ESP_MAIL_WIFI_IS_AVAILABLE) - if (_client_type == esp_mail_client_type_external_basic_client && - (!_network_connection_cb || !_network_status_cb)) - rdy = false; - else if (_client_type != esp_mail_client_type_external_basic_client || - _client_type != esp_mail_client_type_external_gsm_client) - rdy = false; -#else - // assume external client is WiFiClient and network status request callback is not required - // when device was connected to network using on board WiFi - if (_client_type == esp_mail_client_type_external_basic_client && - (!_network_connection_cb || (!_network_status_cb && !WiFI_CONNECTED && !ethLinkUp()))) - { - rdy = false; - } - -#endif - - if (!rdy) - { -#if !defined(SILENT_MODE) && (defined(ENABLE_SMTP) || defined(ENABLE_IMAP)) - if (_debug_level > 0) - { - if (!_network_connection_cb) - esp_mail_debug_print_tag(esp_mail_error_client_str_2 /* "network connection callback is required" */, esp_mail_debug_tag_type_error, true); - if (!WiFI_CONNECTED && !ethLinkUp()) - { - if (!_network_status_cb) - esp_mail_debug_print_tag(esp_mail_error_client_str_3 /* "network connection status callback is required" */, esp_mail_debug_tag_type_error, true); - } - } -#endif - } - - return rdy; - } - - /** - * Set Root CA certificate to verify. - * @param name The host name. - * @param ip The ip address result. - * @return 1 for success or 0 for failed. - */ - int hostByName(const char *name, IPAddress &ip) - { -#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) - return WiFiHelper::hostByName(name, ip); -#else - return 1; -#endif - } - - /** - * Store the host name and port. - * @param host The host name to connect. - * @param port The port to connect. - * @return true. - */ - bool begin(const char *host, uint16_t port) - { - _host = host; - _port = port; -#if !defined(ESP_MAIL_DISABLE_SSL) - _tcp_client->setBufferSizes(_rx_size >= _minRXTXBufSize && _rx_size <= _maxRXBufSize ? _rx_size : _maxRXBufSize / rxBufDivider, - _tx_size >= _minRXTXBufSize && _tx_size <= _maxTXBufSize ? _tx_size : _maxTXBufSize / txBufDivider); -#endif - _last_error = 0; - return true; - } - - /** - * Start TCP connection using stored host name and port. - * @param secure The secure mode option. - * @param verify The Root CA certificate verification option. - * @return true for success or false for error. - */ - - bool connect(bool secured, bool verify) - { - bool ret = false; - -#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) - _last_error = 0; - -#if !defined(ESP_MAIL_DISABLE_SSL) - _tcp_client->enableSSL(secured); - setSecure(secured); - setVerify(verify); -#endif - - if (connected()) - { - flush(); - return true; - } - - if (!_basic_client) - { - if (_client_type == esp_mail_client_type_external_basic_client) - { - _last_error = 1; - return false; - } - else if (_client_type != esp_mail_client_type_external_gsm_client) - { -// Device has no built-in WiFi, external client required. -#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) - _basic_client = new BASE_WIFICLIENT(); - _client_type = esp_mail_client_type_internal_basic_client; -#else - _last_error = 1; - return false; -#endif - } - } - -#if defined(ESP_MAIL_DISABLE_SSL) - _tcp_client = _basic_client; -#else - _tcp_client->setClient(_basic_client); -#endif - - if (!_tcp_client->connect(_host.c_str(), _port)) - return false; - -#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) && (defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO)) - if (_client_type == esp_mail_client_type_internal_basic_client) - reinterpret_cast(_basic_client)->setNoDelay(true); -#endif - - // For TCP keepalive should work in ESP8266 core > 3.1.2. - // https://github.com/esp8266/Arduino/pull/8940 - - // Not currently supported by WiFiClientSecure in Arduino Pico core - - if (_client_type == esp_mail_client_type_internal_basic_client) - { - if (isKeepAliveSet()) - { -#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) - -#if defined(ESP8266) - if (_tcpKeepIdleSeconds == 0 || _tcpKeepIntervalSeconds == 0 || _tcpKeepCount == 0) - reinterpret_cast(_basic_client)->disableKeepAlive(); - else - reinterpret_cast(_basic_client)->keepAlive(_tcpKeepIdleSeconds, _tcpKeepIntervalSeconds, _tcpKeepCount); - -#elif defined(ESP32) - - if (_tcpKeepIdleSeconds == 0 || _tcpKeepIntervalSeconds == 0 || _tcpKeepCount == 0) - { - _tcpKeepIdleSeconds = 0; - _tcpKeepIntervalSeconds = 0; - _tcpKeepCount = 0; - } - - bool success = setOption(TCP_KEEPIDLE, &_tcpKeepIdleSeconds) > -1 && - setOption(TCP_KEEPINTVL, &_tcpKeepIntervalSeconds) > -1 && - setOption(TCP_KEEPCNT, &_tcpKeepCount) > -1; - if (!success) - _isKeepAlive = false; -#endif - -#endif - } - } - - ret = connected(); - if (!ret) - stop(); -#endif - return ret; - } - - /** - * Upgrade the current connection by setting up the SSL and perform the SSL handshake. - * - * @param verify The Root CA certificate verification option - * @return operating result. - */ - - bool connectSSL(bool verify) - { -#if !defined(ESP_MAIL_DISABLE_SSL) - _tcp_client->setDebugLevel(2); - - bool ret = _tcp_client->connected(); - - if (ret) - { - setVerify(verify); - ret = _tcp_client->connectSSL(_host.c_str(), _port); - if (ret) - _secured = true; - } - - if (!ret) - stop(); - - return ret; -#endif - return false; - } - - /** - * Stop TCP connection. - */ - void stop() - { - if (_tcp_client) - _tcp_client->stop(); - } - - /** - * Get the TCP connection status. - * @return true for connected or false for not connected. - */ - bool connected() { return _tcp_client && _tcp_client->connected(); }; - - /** - * The TCP data write function. - * @param data The data to write. - * @param len The length of data to write. - * @return The size of data that was successfully written or 0 for error. - */ - int write(uint8_t *data, int len) - { - if (!_tcp_client) - return TCP_CLIENT_ERROR_NOT_INITIALIZED; - - if (!data) - return TCP_CLIENT_ERROR_SEND_DATA_FAILED; - - if (len == 0) - return TCP_CLIENT_ERROR_SEND_DATA_FAILED; - - if (!networkReady()) - return TCP_CLIENT_ERROR_NOT_CONNECTED; - - if (!connect(isSecure(), isVerify())) - return TCP_CLIENT_ERROR_CONNECTION_REFUSED; - - int toSend = _chunkSize; - int sent = 0; - while (sent < len) - { - if (sent + toSend > len) - toSend = len - sent; - - if ((int)_tcp_client->write(data + sent, toSend) != toSend) - return TCP_CLIENT_ERROR_SEND_DATA_FAILED; - - sent += toSend; - } - - return len; - } - - /** - * The TCP data send function. - * @param data The data to send. - * @return The size of data that was successfully sent or 0 for error. - */ - int send(const char *data) { return write((uint8_t *)data, strlen(data)); } - - /** - * The TCP data print function. - * @param data The data to print. - * @return The size of data that was successfully print or 0 for error. - */ - int print(const char *data) { return send(data); } - - /** - * The TCP data print function. - * @param data The data to print. - * @return The size of data that was successfully print or 0 for error. - */ - int print(int data) - { - char buf[64]; - memset(buf, 0, 64); - sprintf(buf, (const char *)FPSTR("%d"), data); - int ret = send(buf); - return ret; - } - - /** - * The TCP data print with new line function. - * @param data The data to print. - * @return The size of data that was successfully print or 0 for error. - */ - int println(const char *data) - { - int len = send(data); - if (len < 0) - return len; - int sz = send((const char *)FPSTR("\r\n")); - if (sz < 0) - return sz; - return len + sz; - } - - /** - * The TCP data print with new line function. - * @param data The data to print. - * @return The size of data that was successfully print or 0 for error. - */ - int println(int data) - { - char buf[64]; - memset(buf, 0, 64); - sprintf(buf, (const char *)FPSTR("%d\r\n"), data); - int ret = send(buf); - return ret; - } - - /** - * Get available data size to read. - * @return The avaiable data size. - */ - int available() - { - if (!_basic_client) - return TCP_CLIENT_ERROR_NOT_INITIALIZED; - - return _tcp_client->available(); - } - - /** - * The TCP data read function. - * @return The read value or -1 for error. - */ - int read() - { - if (!_basic_client) - return TCP_CLIENT_ERROR_NOT_INITIALIZED; - - return _tcp_client->read(); - } - - /** - * The TCP data read function. - * @param buf The data buffer. - * @param len The length of data that read. - * @return The size of data that was successfully read or negative value for error. - */ - int readBytes(uint8_t *buf, int len) - { - if (!_basic_client) - return TCP_CLIENT_ERROR_NOT_INITIALIZED; - - return _tcp_client->read(buf, len); - } - - /** - * The TCP data read function. - * @param buf The data buffer. - * @param len The length of data that read. - * @return The size of data that was successfully read or negative value for error. - */ - int readBytes(char *buf, int len) - { - return readBytes((uint8_t *)buf, len); - } - - /** - * Wait for all receive buffer data read. - */ - void flush() - { - if (_tcp_client) - _tcp_client->flush(); - } - - /** - * Set the network connection request callback. - * @param networkConnectionCB The callback function that handles the network connection. - */ - void networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB) - { - _network_connection_cb = networkConnectionCB; - } - - /** - * Set the network status request callback. - * @param networkStatusCB The callback function that calls the setNetworkStatus function to set the network status. - */ - void networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB) - { - _network_status_cb = networkStatusCB; - } - - /** - * Set the network status which should call in side the networkStatusRequestCallback function. - * @param status The status of network. - */ - void setNetworkStatus(bool status) - { - _network_status = status; - } - - void setMBFS(MB_FS *mbfs) { _mbfs = mbfs; } - -#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) - void setSession(Session_Config *session_config) - { - _session_config = session_config; - } -#endif - - void setClockReady(bool rdy) - { - _clock_ready = rdy; - } - - void setCertType(esp_mail_cert_type type) { _cert_type = type; } - - esp_mail_cert_type getCertType() { return _cert_type; } - - void setDebugLevel(int debug) { _debug_level = debug; } - - unsigned long tcpTimeout() - { - if (_tcp_client) - return 1000 * _tcp_client->getTimeout(); - return 0; - } - - void disconnect(){}; - - void keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount) - { - _tcpKeepIdleSeconds = tcpKeepIdleSeconds; - _tcpKeepIntervalSeconds = tcpKeepIntervalSeconds; - _tcpKeepCount = tcpKeepCount; - _isKeepAlive = tcpKeepIdleSeconds > 0 && tcpKeepIntervalSeconds > 0 && tcpKeepCount > 0; - } - - bool isKeepAliveSet() { return _tcpKeepIdleSeconds > -1 && _tcpKeepIntervalSeconds > -1 && _tcpKeepCount > -1; }; - - bool isKeepAlive() { return _isKeepAlive; }; - - void clear() - { -#if !defined(ESP_MAIL_DISABLE_SSL) - if (_basic_client && _client_type == esp_mail_client_type_internal_basic_client) - { -#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) - delete (BASE_WIFICLIENT *)_basic_client; -#else - delete _basic_client; -#endif - _basic_client = nullptr; - } -#else - _basic_client = nullptr; -#endif - _client_type = esp_mail_client_type_undefined; - } - - void setWiFi(esp_mail_wifi_credentials_t *wifi) { _wifi_multi = wifi; } - - bool gprsConnect() - { -#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) - TinyGsm *gsmModem = (TinyGsm *)_modem; - if (gsmModem) - { - // Unlock your SIM card with a PIN if needed - if (_pin.length() && gsmModem->getSimStatus() != 3) - gsmModem->simUnlock(_pin.c_str()); - -#if defined(TINY_GSM_MODEM_XBEE) - // The XBee must run the gprsConnect function BEFORE waiting for network! - gsmModem->gprsConnect(_apn.c_str(), _user.c_str(), _password.c_str()); -#endif - -#if !defined(SILENT_MODE) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) - if (_debug_level > 0 && _last_error == 0) - esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR("Waiting for network..."), esp_mail_debug_tag_type_info, false); -#endif - if (!gsmModem->waitForNetwork()) - { -#if !defined(SILENT_MODE) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) - if (_debug_level > 0 && _last_error == 0) - esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR(" fail"), esp_mail_debug_tag_type_info, true, false); -#endif - _last_error = 1; - _network_status = false; - return false; - } - -#if !defined(SILENT_MODE) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) - if (_debug_level > 0 && _last_error == 0) - esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR(" success"), esp_mail_debug_tag_type_info, true, false); -#endif - - if (gsmModem->isNetworkConnected()) - { -#if !defined(SILENT_MODE) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) - if (_debug_level > 0 && _last_error == 0) - { - esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR("Connecting to "), esp_mail_debug_tag_type_info, false); - esp_mail_debug_print_tag(_apn.c_str(), esp_mail_debug_tag_type_info, false, false); - } -#endif - _network_status = gsmModem->gprsConnect(_apn.c_str(), _user.c_str(), _password.c_str()) && - gsmModem->isGprsConnected(); - -#if !defined(SILENT_MODE) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) - if (_debug_level > 0 && _last_error == 0) - { - if (_network_status) - esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR(" success"), esp_mail_debug_tag_type_info, true, false); - else - esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR(" fail"), esp_mail_debug_tag_type_info, true, false); - } -#endif - } - - if (!_network_status) - _last_error = 1; - - return _network_status; - } - -#endif - return false; - } - - bool gprsConnected() - { -#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) - TinyGsm *gsmModem = (TinyGsm *)_modem; - _network_status = gsmModem && gsmModem->isGprsConnected(); -#endif - return _network_status; - } - - bool gprsDisconnect() - { -#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) - TinyGsm *gsmModem = (TinyGsm *)_modem; - _network_status = gsmModem && gsmModem->gprsDisconnect(); -#endif - return !_network_status; - } - - bool gprsGetTime(int &year, int &month, int &day, int &hour, int &min, int &sec, float &timezone) - { -#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) && defined(TINY_GSM_MODEM_HAS_TIME) - - if (!gprsConnected()) - return 0; - - TinyGsm *gsmModem = (TinyGsm *)_modem; - year = 0; - month = 0; - day = 0; - hour = 0; - min = 0; - sec = 0; - timezone = 0; - for (int8_t i = 5; i; i--) - { - if (gsmModem->getNetworkTime(&year, &month, &day, &hour, &min, &sec, &timezone)) - { - return true; - } - } -#endif - return false; - } - - int setOption(int option, int *value) - { -#if defined(ESP32) && defined(ESP_MAIL_WIFI_IS_AVAILABLE) - // Actually we wish to use setSocketOption directly but it is ambiguous in old ESP32 core v1.0.x.; - // Use setOption instead for old core support. - return reinterpret_cast(_basic_client)->setOption(option, value); -#endif - return 0; - } - - void setTA(bool hasTA) - { - _has_ta = hasTA; - } - - void setSecure(bool secure) - { - _secured = secure; - } - - void setInSecure() - { -#if !defined(ESP_MAIL_DISABLE_SSL) - _use_insecure = true; - setTA(false); -#endif - } - - void setVerify(bool verify) - { -#if !defined(ESP_MAIL_DISABLE_SSL) - if (_has_ta) - _use_insecure = !verify; - - if (_use_insecure) - _tcp_client->setInsecure(); -#endif - } - - bool isSecure() - { - return _secured; - } - - bool isVerify() - { - return !_use_insecure; - } - - int rxBufDivider = 16; - int txBufDivider = 32; - -private: - // lwIP TCP Keepalive idle in seconds. - int _tcpKeepIdleSeconds = -1; - // lwIP TCP Keepalive interval in seconds. - int _tcpKeepIntervalSeconds = -1; - // lwIP TCP Keepalive count. - int _tcpKeepCount = -1; - bool _isKeepAlive = false; - - uint16_t _bsslRxSize = 1024; - uint16_t _bsslTxSize = 1024; - const int _maxRXBufSize = 16384; // SSL full supported 16 kB - const int _maxTXBufSize = 16384; - const int _minRXTXBufSize = 512; -#if defined(ESP_MAIL_DISABLE_SSL) - Client *_tcp_client = nullptr; -#else - ESP_SSLClient *_tcp_client = nullptr; - X509List *_x509 = nullptr; -#endif - - MB_String _host; - uint16_t _port = 443; - - MB_FS *_mbfs = nullptr; - Client *_basic_client = nullptr; - esp_mail_wifi_credentials_t *_wifi_multi = nullptr; -#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) - Session_Config *_session_config = nullptr; -#endif - NetworkConnectionRequestCallback _network_connection_cb = NULL; - NetworkStatusRequestCallback _network_status_cb = NULL; -#if defined(ESP_MAIL_HAS_WIFIMULTI) - WiFiMulti *_multi = nullptr; -#endif -#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) - MB_String _pin, _apn, _user, _password; - void *_modem = nullptr; -#endif - - bool _has_ta = false; - bool _secured = false; - bool _use_insecure = false; - int _debug_level = 0; - int _chunkSize = 1024; - bool _clock_ready = false; - int _last_error = 0; - volatile bool _network_status = false; - int _rx_size = -1, _tx_size = -1; - - esp_mail_cert_type _cert_type = esp_mail_cert_type_undefined; - esp_mail_client_type _client_type = esp_mail_client_type_undefined; -}; - +/** + * + * The Network Upgradable Arduino Secure TCP Client Class, ESP_Mail_TCPClient.h v1.0.1 + * + * Created August 27, 2023 + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person returning 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 ESP_MAIL_TCPCLIENT_H +#define ESP_MAIL_TCPCLIENT_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +#pragma GCC diagnostic ignored "-Wunused-variable" +#pragma GCC diagnostic ignored "-Wdelete-non-virtual-dtor" + +#include "ESP_Mail_Const.h" + +#if defined(ESP32) && (defined(ENABLE_SMTP) || defined(ENABLE_IMAP)) +#include "IPAddress.h" +#include "lwip/sockets.h" +#endif + +#if defined(ESP32) + +#include "ESP8266WiFi.h" +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) +#define WIFI_HAS_HOST_BY_NAME +#endif +#include "extras/WiFiClientImpl.h" +#define BASE_WIFICLIENT WiFiClientImpl + +#elif defined(ESP_MAIL_WIFI_IS_AVAILABLE) +#include "WiFiClient.h" +#define BASE_WIFICLIENT WiFiClient +#endif + +#include "SSLClient/ESP_SSLClient.h" + +class ESP_Mail_TCPClient +{ +public: + ESP_Mail_TCPClient() + { +#if !defined(ESP_MAIL_DISABLE_SSL) + _tcp_client = new ESP_SSLClient(); +#endif + } + + ~ESP_Mail_TCPClient() + { + clear(); +#if !defined(ESP_MAIL_DISABLE_SSL) + if (_tcp_client) + delete _tcp_client; + _tcp_client = nullptr; +#endif + } + + /** + * Set the client. + * @param client The Client interface. + */ + void setClient(Client *client) + { + clear(); + _basic_client = client; + _client_type = esp_mail_client_type_external_basic_client; + } + + /** Assign TinyGsm Clients. + * + * @param client The pointer to TinyGsmClient. + * @param modem The pointer to TinyGsm modem object. Modem should be initialized and/or set mode before transfering data + * @param pin The SIM pin. + * @param apn The GPRS APN (Access Point Name). + * @param user The GPRS user. + * @param password The GPRS password. + */ + void setGSMClient(Client *client, void *modem = nullptr, const char *pin = nullptr, const char *apn = nullptr, const char *user = nullptr, const char *password = nullptr) + { +#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) + _pin = pin; + _apn = apn; + _user = user; + _password = password; + _modem = modem; + _client_type = esp_mail_client_type_external_gsm_client; + _basic_client = client; +#endif + } + + /** + * Set Root CA certificate to verify. + * @param caCert The certificate. + */ + void setCACert(const char *caCert) + { +#if !defined(ESP_MAIL_DISABLE_SSL) + if (caCert) + { + if (_x509) + delete _x509; + + _x509 = new X509List(caCert); + _tcp_client->setTrustAnchors(_x509); + + setCertType(esp_mail_cert_type_data); + setTA(true); + } + else + { + setCertType(esp_mail_cert_type_none); + setInSecure(); + } +#endif + } + + /** + * Set Root CA certificate to verify. + * @param certFile The certificate file path. + * @param storageType The storage type mb_fs_mem_storage_type_flash or mb_fs_mem_storage_type_sd. + * @return true when certificate loaded successfully. + */ + bool setCertFile(const char *certFile, mb_fs_mem_storage_type storageType) + { +#if !defined(ESP_MAIL_DISABLE_SSL) + if (!_mbfs) + return false; + + if (_clock_ready && strlen(certFile) > 0) + { + MB_String filename = certFile; + if (filename.length() > 0) + { + if (filename[0] != '/') + filename.prepend('/'); + } + + int len = _mbfs->open(filename, storageType, mb_fs_open_mode_read); + if (len > -1) + { + uint8_t *der = (uint8_t *)_mbfs->newP(len); + if (_mbfs->available(storageType)) + _mbfs->read(storageType, der, len); + _mbfs->close(storageType); + + if (_x509) + delete _x509; + + _x509 = new X509List(der, len); + _tcp_client->setTrustAnchors(_x509); + setTA(true); + _mbfs->delP(&der); + + setCertType(esp_mail_cert_type_file); + } + } +#endif + + return getCertType() == esp_mail_cert_type_file; + } + + /** + * Set TCP connection time out in seconds. + * @param timeoutSec The time out in seconds. + */ + void setTimeout(uint32_t timeoutSec) + { + _tcp_client->setTimeout(timeoutSec * 1000); + } + + /** Set the BearSSL IO buffer size. + * + * @param rx The BearSSL receive buffer size in bytes. + * @param tx The BearSSL trasmit buffer size in bytes. + */ + void setIOBufferSize(int rx, int tx) + { + _rx_size = rx; + _tx_size = tx; + } + + /** + * Get the ethernet link status. + * @return true for link up or false for link down. + */ + bool ethLinkUp() + { + bool ret = false; + +#if !defined(ESP_MAIL_DISABLE_NATIVE_ETHERNET) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) + +#if defined(ESP_MAIL_ETH_IS_AVAILABLE) + +#if defined(ESP32) + if (validIP(ETH.localIP())) + { + ETH.linkUp(); + ret = true; + } +#elif defined(ESP8266) + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + if (!_session_config) + return false; +#endif + +#if defined(ESP8266) && defined(ESP8266_CORE_SDK_V3_X_X) + +#if defined(INC_ENC28J60_LWIP) + if (_session_config->spi_ethernet_module.enc28j60) + { + ret = _session_config->spi_ethernet_module.enc28j60->status() == WL_CONNECTED; + goto ex; + } +#endif +#if defined(INC_W5100_LWIP) + if (_session_config->spi_ethernet_module.w5100) + { + ret = _session_config->spi_ethernet_module.w5100->status() == WL_CONNECTED; + goto ex; + } +#endif +#if defined(INC_W5500_LWIP) + if (_session_config->spi_ethernet_module.w5500) + { + ret = _session_config->spi_ethernet_module.w5500->status() == WL_CONNECTED; + goto ex; + } +#endif +#elif defined(MB_ARDUINO_PICO) + +#endif + + return ret; + +#if defined(INC_ENC28J60_LWIP) || defined(INC_W5100_LWIP) || defined(INC_W5500_LWIP) + ex: +#endif + // workaround for ESP8266 Ethernet + delayMicroseconds(0); +#endif + +#endif + +#endif + + return ret; + } + + /** + * Checking for valid IP. + * @return true for valid. + */ + bool validIP(IPAddress ip) + { + char buf[16]; + sprintf(buf, "%u.%u.%u.%u", ip[0], ip[1], ip[2], ip[3]); + return strcmp(buf, "0.0.0.0") != 0; + } + + /** + * Ethernet DNS workaround. + */ + void ethDNSWorkAround() + { + +#if !defined(ESP_MAIL_DISABLE_NATIVE_ETHERNET) && (defined(ENABLE_SMTP) || defined(ENABLE_IMAP)) + if (!_session_config) + return; + +#if defined(ESP8266_CORE_SDK_V3_X_X) + +#if defined(INC_ENC28J60_LWIP) + if (_session_config->spi_ethernet_module.enc28j60) + goto ex; +#endif +#if defined(INC_W5100_LWIP) + if (_session_config->spi_ethernet_module.w5100) + goto ex; +#endif +#if defined(INC_W5500_LWIP) + if (_session_config->spi_ethernet_module.w5500) + goto ex; +#endif + +#elif defined(MB_ARDUINO_PICO) + +#endif + + return; + +#if defined(INC_ENC28J60_LWIP) || defined(INC_W5100_LWIP) || defined(INC_W5500_LWIP) + ex: +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) + BASE_WIFICLIENT client; + client.connect(_session_config->server.host_name.c_str(), _session_config->server.port); + client.stop(); +#endif +#endif + +#endif + } + + /** + * Get the network status. + * @return true for connected or false for not connected. + */ + bool networkReady() + { + + // We will not invoke the network status request when device has built-in WiFi or Ethernet and it is connected. + if (_client_type == esp_mail_client_type_external_gsm_client) + { + _network_status = gprsConnected(); + if (!_network_status) + gprsConnect(); + } + else if (WiFI_CONNECTED || ethLinkUp()) + _network_status = true; + else if (_client_type == esp_mail_client_type_external_basic_client) + { + if (!_network_status_cb) + _last_error = 1; + else + _network_status_cb(); + } + + return _network_status; + } + + /** + * Reconnect the network. + */ + void networkReconnect() + { + + if (_client_type == esp_mail_client_type_external_basic_client) + { +#if defined(ESP_MAIL_HAS_WIFI_DISCONNECT) + // We can reconnect WiFi when device connected via built-in WiFi that supports reconnect + if (WiFI_CONNECTED) + { + WiFi.reconnect(); + return; + } + +#endif + + if (_network_connection_cb) + _network_connection_cb(); + } + else if (_client_type == esp_mail_client_type_external_gsm_client) + { + gprsDisconnect(); + gprsConnect(); + } + else if (_client_type == esp_mail_client_type_internal_basic_client) + { + +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) +#if defined(ESP32) || defined(ESP8266) + WiFi.reconnect(); +#else + if (_wifi_multi && _wifi_multi->credentials.size()) + _wifi_multi->reconnect(); +#endif +#endif + } + } + + /** + * Disconnect the network. + */ + void networkDisconnect() {} + + /** + * Get the Client type. + * @return The esp_mail_client_type enum value. + */ + esp_mail_client_type type() { return _client_type; } + + /** + * Get the Client initialization status. + * @return The initialization status. + */ + bool isInitialized() + { + bool rdy = true; +#if !defined(ESP_MAIL_WIFI_IS_AVAILABLE) + if (_client_type == esp_mail_client_type_external_basic_client && + (!_network_connection_cb || !_network_status_cb)) + rdy = false; + else if (_client_type != esp_mail_client_type_external_basic_client || + _client_type != esp_mail_client_type_external_gsm_client) + rdy = false; +#else + // assume external client is WiFiClient and network status request callback is not required + // when device was connected to network using on board WiFi + if (_client_type == esp_mail_client_type_external_basic_client && + (!_network_connection_cb || (!_network_status_cb && !WiFI_CONNECTED && !ethLinkUp()))) + { + rdy = false; + } + +#endif + + if (!rdy) + { +#if !defined(SILENT_MODE) && (defined(ENABLE_SMTP) || defined(ENABLE_IMAP)) + if (_debug_level > 0) + { + if (!_network_connection_cb) + esp_mail_debug_print_tag(esp_mail_error_client_str_2 /* "network connection callback is required" */, esp_mail_debug_tag_type_error, true); + if (!WiFI_CONNECTED && !ethLinkUp()) + { + if (!_network_status_cb) + esp_mail_debug_print_tag(esp_mail_error_client_str_3 /* "network connection status callback is required" */, esp_mail_debug_tag_type_error, true); + } + } +#endif + } + + return rdy; + } + + /** + * Set Root CA certificate to verify. + * @param name The host name. + * @param ip The ip address result. + * @return 1 for success or 0 for failed. + */ + int hostByName(const char *name, IPAddress &ip) + { +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) + return WiFiHelper::hostByName(name, ip); +#else + return 1; +#endif + } + + /** + * Store the host name and port. + * @param host The host name to connect. + * @param port The port to connect. + * @return true. + */ + bool begin(const char *host, uint16_t port) + { + _host = host; + _port = port; +#if !defined(ESP_MAIL_DISABLE_SSL) + _tcp_client->setBufferSizes(_rx_size >= _minRXTXBufSize && _rx_size <= _maxRXBufSize ? _rx_size : _maxRXBufSize / rxBufDivider, + _tx_size >= _minRXTXBufSize && _tx_size <= _maxTXBufSize ? _tx_size : _maxTXBufSize / txBufDivider); +#endif + _last_error = 0; + return true; + } + + /** + * Start TCP connection using stored host name and port. + * @param secure The secure mode option. + * @param verify The Root CA certificate verification option. + * @return true for success or false for error. + */ + + bool connect(bool secured, bool verify) + { + bool ret = false; + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + _last_error = 0; + +#if !defined(ESP_MAIL_DISABLE_SSL) + _tcp_client->enableSSL(secured); + setSecure(secured); + setVerify(verify); +#endif + + if (connected()) + { + flush(); + return true; + } + + if (!_basic_client) + { + if (_client_type == esp_mail_client_type_external_basic_client) + { + _last_error = 1; + return false; + } + else if (_client_type != esp_mail_client_type_external_gsm_client) + { +// Device has no built-in WiFi, external client required. +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) + _basic_client = new BASE_WIFICLIENT(); + _client_type = esp_mail_client_type_internal_basic_client; +#else + _last_error = 1; + return false; +#endif + } + } + +#if defined(ESP_MAIL_DISABLE_SSL) + _tcp_client = _basic_client; +#else + _tcp_client->setClient(_basic_client); +#endif + + if (!_tcp_client->connect(_host.c_str(), _port)) + return false; + +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) && (defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO)) + if (_client_type == esp_mail_client_type_internal_basic_client) + reinterpret_cast(_basic_client)->setNoDelay(true); +#endif + + // For TCP keepalive should work in ESP8266 core > 3.1.2. + // https://github.com/esp8266/Arduino/pull/8940 + + // Not currently supported by WiFiClientSecure in Arduino Pico core + + if (_client_type == esp_mail_client_type_internal_basic_client) + { + if (isKeepAliveSet()) + { +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) + +#if defined(ESP8266) + if (_tcpKeepIdleSeconds == 0 || _tcpKeepIntervalSeconds == 0 || _tcpKeepCount == 0) + reinterpret_cast(_basic_client)->disableKeepAlive(); + else + reinterpret_cast(_basic_client)->keepAlive(_tcpKeepIdleSeconds, _tcpKeepIntervalSeconds, _tcpKeepCount); + +#elif defined(ESP32) + + if (_tcpKeepIdleSeconds == 0 || _tcpKeepIntervalSeconds == 0 || _tcpKeepCount == 0) + { + _tcpKeepIdleSeconds = 0; + _tcpKeepIntervalSeconds = 0; + _tcpKeepCount = 0; + } + + bool success = setOption(TCP_KEEPIDLE, &_tcpKeepIdleSeconds) > -1 && + setOption(TCP_KEEPINTVL, &_tcpKeepIntervalSeconds) > -1 && + setOption(TCP_KEEPCNT, &_tcpKeepCount) > -1; + if (!success) + _isKeepAlive = false; +#endif + +#endif + } + } + + ret = connected(); + if (!ret) + stop(); +#endif + return ret; + } + + /** + * Upgrade the current connection by setting up the SSL and perform the SSL handshake. + * + * @param verify The Root CA certificate verification option + * @return operating result. + */ + + bool connectSSL(bool verify) + { +#if !defined(ESP_MAIL_DISABLE_SSL) + _tcp_client->setDebugLevel(2); + + bool ret = _tcp_client->connected(); + + if (ret) + { + setVerify(verify); + ret = _tcp_client->connectSSL(_host.c_str(), _port); + if (ret) + _secured = true; + } + + if (!ret) + stop(); + + return ret; +#endif + return false; + } + + /** + * Stop TCP connection. + */ + void stop() + { + if (_tcp_client) + _tcp_client->stop(); + } + + /** + * Get the TCP connection status. + * @return true for connected or false for not connected. + */ + bool connected() { return _tcp_client && _tcp_client->connected(); }; + + /** + * The TCP data write function. + * @param data The data to write. + * @param len The length of data to write. + * @return The size of data that was successfully written or 0 for error. + */ + int write(uint8_t *data, int len) + { + if (!_tcp_client) + return TCP_CLIENT_ERROR_NOT_INITIALIZED; + + if (!data) + return TCP_CLIENT_ERROR_SEND_DATA_FAILED; + + if (len == 0) + return TCP_CLIENT_ERROR_SEND_DATA_FAILED; + + if (!networkReady()) + return TCP_CLIENT_ERROR_NOT_CONNECTED; + + if (!connect(isSecure(), isVerify())) + return TCP_CLIENT_ERROR_CONNECTION_REFUSED; + + int toSend = _chunkSize; + int sent = 0; + while (sent < len) + { + if (sent + toSend > len) + toSend = len - sent; + + if ((int)_tcp_client->write(data + sent, toSend) != toSend) + return TCP_CLIENT_ERROR_SEND_DATA_FAILED; + + sent += toSend; + } + + return len; + } + + /** + * The TCP data send function. + * @param data The data to send. + * @return The size of data that was successfully sent or 0 for error. + */ + int send(const char *data) { return write((uint8_t *)data, strlen(data)); } + + /** + * The TCP data print function. + * @param data The data to print. + * @return The size of data that was successfully print or 0 for error. + */ + int print(const char *data) { return send(data); } + + /** + * The TCP data print function. + * @param data The data to print. + * @return The size of data that was successfully print or 0 for error. + */ + int print(int data) + { + char buf[64]; + memset(buf, 0, 64); + sprintf(buf, (const char *)FPSTR("%d"), data); + int ret = send(buf); + return ret; + } + + /** + * The TCP data print with new line function. + * @param data The data to print. + * @return The size of data that was successfully print or 0 for error. + */ + int println(const char *data) + { + int len = send(data); + if (len < 0) + return len; + int sz = send((const char *)FPSTR("\r\n")); + if (sz < 0) + return sz; + return len + sz; + } + + /** + * The TCP data print with new line function. + * @param data The data to print. + * @return The size of data that was successfully print or 0 for error. + */ + int println(int data) + { + char buf[64]; + memset(buf, 0, 64); + sprintf(buf, (const char *)FPSTR("%d\r\n"), data); + int ret = send(buf); + return ret; + } + + /** + * Get available data size to read. + * @return The avaiable data size. + */ + int available() + { + if (!_basic_client) + return TCP_CLIENT_ERROR_NOT_INITIALIZED; + + return _tcp_client->available(); + } + + /** + * The TCP data read function. + * @return The read value or -1 for error. + */ + int read() + { + if (!_basic_client) + return TCP_CLIENT_ERROR_NOT_INITIALIZED; + + return _tcp_client->read(); + } + + /** + * The TCP data read function. + * @param buf The data buffer. + * @param len The length of data that read. + * @return The size of data that was successfully read or negative value for error. + */ + int readBytes(uint8_t *buf, int len) + { + if (!_basic_client) + return TCP_CLIENT_ERROR_NOT_INITIALIZED; + + return _tcp_client->read(buf, len); + } + + /** + * The TCP data read function. + * @param buf The data buffer. + * @param len The length of data that read. + * @return The size of data that was successfully read or negative value for error. + */ + int readBytes(char *buf, int len) + { + return readBytes((uint8_t *)buf, len); + } + + /** + * Wait for all receive buffer data read. + */ + void flush() + { + if (_tcp_client) + _tcp_client->flush(); + } + + /** + * Set the network connection request callback. + * @param networkConnectionCB The callback function that handles the network connection. + */ + void networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB) + { + _network_connection_cb = networkConnectionCB; + } + + /** + * Set the network status request callback. + * @param networkStatusCB The callback function that calls the setNetworkStatus function to set the network status. + */ + void networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB) + { + _network_status_cb = networkStatusCB; + } + + /** + * Set the network status which should call in side the networkStatusRequestCallback function. + * @param status The status of network. + */ + void setNetworkStatus(bool status) + { + _network_status = status; + } + + void setMBFS(MB_FS *mbfs) { _mbfs = mbfs; } + +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + void setSession(Session_Config *session_config) + { + _session_config = session_config; + } +#endif + + void setClockReady(bool rdy) + { + _clock_ready = rdy; + } + + void setCertType(esp_mail_cert_type type) { _cert_type = type; } + + esp_mail_cert_type getCertType() { return _cert_type; } + + void setDebugLevel(int debug) { _debug_level = debug; } + + unsigned long tcpTimeout() + { + if (_tcp_client) + return 1000 * _tcp_client->getTimeout(); + return 0; + } + + void disconnect(){}; + + void keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount) + { + _tcpKeepIdleSeconds = tcpKeepIdleSeconds; + _tcpKeepIntervalSeconds = tcpKeepIntervalSeconds; + _tcpKeepCount = tcpKeepCount; + _isKeepAlive = tcpKeepIdleSeconds > 0 && tcpKeepIntervalSeconds > 0 && tcpKeepCount > 0; + } + + bool isKeepAliveSet() { return _tcpKeepIdleSeconds > -1 && _tcpKeepIntervalSeconds > -1 && _tcpKeepCount > -1; }; + + bool isKeepAlive() { return _isKeepAlive; }; + + void clear() + { +#if !defined(ESP_MAIL_DISABLE_SSL) + if (_basic_client && _client_type == esp_mail_client_type_internal_basic_client) + { +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) + delete (BASE_WIFICLIENT *)_basic_client; +#else + delete _basic_client; +#endif + _basic_client = nullptr; + } +#else + _basic_client = nullptr; +#endif + _client_type = esp_mail_client_type_undefined; + } + + void setWiFi(esp_mail_wifi_credentials_t *wifi) { _wifi_multi = wifi; } + + bool gprsConnect() + { +#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) + TinyGsm *gsmModem = (TinyGsm *)_modem; + if (gsmModem) + { + // Unlock your SIM card with a PIN if needed + if (_pin.length() && gsmModem->getSimStatus() != 3) + gsmModem->simUnlock(_pin.c_str()); + +#if defined(TINY_GSM_MODEM_XBEE) + // The XBee must run the gprsConnect function BEFORE waiting for network! + gsmModem->gprsConnect(_apn.c_str(), _user.c_str(), _password.c_str()); +#endif + +#if !defined(SILENT_MODE) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) + if (_debug_level > 0 && _last_error == 0) + esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR("Waiting for network..."), esp_mail_debug_tag_type_info, false); +#endif + if (!gsmModem->waitForNetwork()) + { +#if !defined(SILENT_MODE) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) + if (_debug_level > 0 && _last_error == 0) + esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR(" fail"), esp_mail_debug_tag_type_info, true, false); +#endif + _last_error = 1; + _network_status = false; + return false; + } + +#if !defined(SILENT_MODE) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) + if (_debug_level > 0 && _last_error == 0) + esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR(" success"), esp_mail_debug_tag_type_info, true, false); +#endif + + if (gsmModem->isNetworkConnected()) + { +#if !defined(SILENT_MODE) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) + if (_debug_level > 0 && _last_error == 0) + { + esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR("Connecting to "), esp_mail_debug_tag_type_info, false); + esp_mail_debug_print_tag(_apn.c_str(), esp_mail_debug_tag_type_info, false, false); + } +#endif + _network_status = gsmModem->gprsConnect(_apn.c_str(), _user.c_str(), _password.c_str()) && + gsmModem->isGprsConnected(); + +#if !defined(SILENT_MODE) && (defined(ENABLE_IMAP) || defined(ENABLE_SMTP)) + if (_debug_level > 0 && _last_error == 0) + { + if (_network_status) + esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR(" success"), esp_mail_debug_tag_type_info, true, false); + else + esp_mail_debug_print_tag((const char *)MBSTRING_FLASH_MCR(" fail"), esp_mail_debug_tag_type_info, true, false); + } +#endif + } + + if (!_network_status) + _last_error = 1; + + return _network_status; + } + +#endif + return false; + } + + bool gprsConnected() + { +#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) + TinyGsm *gsmModem = (TinyGsm *)_modem; + _network_status = gsmModem && gsmModem->isGprsConnected(); +#endif + return _network_status; + } + + bool gprsDisconnect() + { +#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) + TinyGsm *gsmModem = (TinyGsm *)_modem; + _network_status = gsmModem && gsmModem->gprsDisconnect(); +#endif + return !_network_status; + } + + bool gprsGetTime(int &year, int &month, int &day, int &hour, int &min, int &sec, float &timezone) + { +#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) && defined(TINY_GSM_MODEM_HAS_TIME) + + if (!gprsConnected()) + return 0; + + TinyGsm *gsmModem = (TinyGsm *)_modem; + year = 0; + month = 0; + day = 0; + hour = 0; + min = 0; + sec = 0; + timezone = 0; + for (int8_t i = 5; i; i--) + { + if (gsmModem->getNetworkTime(&year, &month, &day, &hour, &min, &sec, &timezone)) + { + return true; + } + } +#endif + return false; + } + + int setOption(int option, int *value) + { +#if defined(ESP32) && defined(ESP_MAIL_WIFI_IS_AVAILABLE) + // Actually we wish to use setSocketOption directly but it is ambiguous in old ESP32 core v1.0.x.; + // Use setOption instead for old core support. + return reinterpret_cast(_basic_client)->setOption(option, value); +#endif + return 0; + } + + void setTA(bool hasTA) + { + _has_ta = hasTA; + } + + void setSecure(bool secure) + { + _secured = secure; + } + + void setInSecure() + { +#if !defined(ESP_MAIL_DISABLE_SSL) + _use_insecure = true; + setTA(false); +#endif + } + + void setVerify(bool verify) + { +#if !defined(ESP_MAIL_DISABLE_SSL) + if (_has_ta) + _use_insecure = !verify; + + if (_use_insecure) + _tcp_client->setInsecure(); +#endif + } + + bool isSecure() + { + return _secured; + } + + bool isVerify() + { + return !_use_insecure; + } + + int rxBufDivider = 16; + int txBufDivider = 32; + +private: + // lwIP TCP Keepalive idle in seconds. + int _tcpKeepIdleSeconds = -1; + // lwIP TCP Keepalive interval in seconds. + int _tcpKeepIntervalSeconds = -1; + // lwIP TCP Keepalive count. + int _tcpKeepCount = -1; + bool _isKeepAlive = false; + + uint16_t _bsslRxSize = 1024; + uint16_t _bsslTxSize = 1024; + const int _maxRXBufSize = 16384; // SSL full supported 16 kB + const int _maxTXBufSize = 16384; + const int _minRXTXBufSize = 512; +#if defined(ESP_MAIL_DISABLE_SSL) + Client *_tcp_client = nullptr; +#else + ESP_SSLClient *_tcp_client = nullptr; + X509List *_x509 = nullptr; +#endif + + MB_String _host; + uint16_t _port = 443; + + MB_FS *_mbfs = nullptr; + Client *_basic_client = nullptr; + esp_mail_wifi_credentials_t *_wifi_multi = nullptr; +#if defined(ENABLE_SMTP) || defined(ENABLE_IMAP) + Session_Config *_session_config = nullptr; +#endif + NetworkConnectionRequestCallback _network_connection_cb = NULL; + NetworkStatusRequestCallback _network_status_cb = NULL; +#if defined(ESP_MAIL_HAS_WIFIMULTI) + WiFiMulti *_multi = nullptr; +#endif +#if defined(ESP_MAIL_GSM_MODEM_IS_AVAILABLE) + MB_String _pin, _apn, _user, _password; + void *_modem = nullptr; +#endif + + bool _has_ta = false; + bool _secured = false; + bool _use_insecure = false; + int _debug_level = 0; + int _chunkSize = 1024; + bool _clock_ready = false; + int _last_error = 0; + volatile bool _network_status = false; + int _rx_size = -1, _tx_size = -1; + + esp_mail_cert_type _cert_type = esp_mail_cert_type_undefined; + esp_mail_client_type _client_type = esp_mail_client_type_undefined; +}; + #endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/HeapStat.h b/lib/libesp32/ESP-Mail-Client/src/HeapStat.h index c6ed4e865..7ea591612 100644 --- a/lib/libesp32/ESP-Mail-Client/src/HeapStat.h +++ b/lib/libesp32/ESP-Mail-Client/src/HeapStat.h @@ -1,146 +1,146 @@ -/** Memory usage info for debugging purpose - -#include "HeapStat.h" - -HeapStat heapInfo; - -void setup() -{ - Serial.begin(115200); -} - -void loop() -{ - // Other codes here - - // Collect memory info - heapInfo.collect(); - - // Print memory info - heapInfo.print(); - -} - -*/ - -#ifndef HEAP_STAT_H -#define HEAP_STAT_H - -#if defined(ESP8266) || defined(ESP32) -#ifndef MB_ARDUINO_ESP -#define MB_ARDUINO_ESP -#endif -#endif - -#if defined(ARDUINO_ARCH_RP2040) - -#if defined(ARDUINO_NANO_RP2040_CONNECT) -#ifndef MB_ARDUINO_NANO_RP2040_CONNECT -#define MB_ARDUINO_NANO_RP2040_CONNECT -#endif -#else -#ifndef MB_ARDUINO_PICO -#define MB_ARDUINO_PICO -#endif -#endif - -#endif - -#include "ESP_Mail_Client.h" - -class HeapStat -{ -private: - int current_heap = 0; - int first_round_heap = 0; - int min_heap = 0; - int max_heap = 0; - int diff_heap_from_first_round = 0; - int diff_heap_from_current_round = 0; - int _count = 0; - - int getFreeHeap() - { -#if defined(MB_ARDUINO_ESP) - return ESP.getFreeHeap(); -#elif defined(MB_ARDUINO_PICO) - return rp2040.getFreeHeap(); -#else - return 0; -#endif - } - -public: - HeapStat() {} - ~HeapStat() {} - - void reset() - { - current_heap = 0; - first_round_heap = 0; - min_heap = 0; - max_heap = 0; - diff_heap_from_first_round = 0; - diff_heap_from_current_round = 0; - _count = 0; - } - - void collect() - { - _count++; - - if (max_heap < getFreeHeap()) - max_heap = getFreeHeap(); - - if (min_heap == 0 || min_heap > getFreeHeap()) - min_heap = getFreeHeap(); - - if (first_round_heap == 0) - first_round_heap = getFreeHeap(); - - if (current_heap > 0) - { - diff_heap_from_first_round = getFreeHeap() - first_round_heap; - diff_heap_from_current_round = getFreeHeap() - current_heap; - } - - current_heap = getFreeHeap(); - } - - int current() - { - return current_heap; - } - - int min() - { - return min_heap; - } - - int max() - { - return max_heap; - } - - int diff1() - { - return diff_heap_from_first_round; - } - - int diffN() - { - return diff_heap_from_current_round; - } - - int count() - { - return _count; - } - - void print() - { - MailClient.printf("#### Heap Info\n#### Current: %d, Min: %d, Max: %d, Diff_1: %d, Diff_%d: %d\n", current(), min(), max(), diff1(), count(), diffN()); - } -}; - +/** Memory usage info for debugging purpose + +#include "HeapStat.h" + +HeapStat heapInfo; + +void setup() +{ + Serial.begin(115200); +} + +void loop() +{ + // Other codes here + + // Collect memory info + heapInfo.collect(); + + // Print memory info + heapInfo.print(); + +} + +*/ + +#ifndef HEAP_STAT_H +#define HEAP_STAT_H + +#if defined(ESP8266) || defined(ESP32) +#ifndef MB_ARDUINO_ESP +#define MB_ARDUINO_ESP +#endif +#endif + +#if defined(ARDUINO_ARCH_RP2040) + +#if defined(ARDUINO_NANO_RP2040_CONNECT) +#ifndef MB_ARDUINO_NANO_RP2040_CONNECT +#define MB_ARDUINO_NANO_RP2040_CONNECT +#endif +#else +#ifndef MB_ARDUINO_PICO +#define MB_ARDUINO_PICO +#endif +#endif + +#endif + +#include "ESP_Mail_Client.h" + +class HeapStat +{ +private: + int current_heap = 0; + int first_round_heap = 0; + int min_heap = 0; + int max_heap = 0; + int diff_heap_from_first_round = 0; + int diff_heap_from_current_round = 0; + int _count = 0; + + int getFreeHeap() + { +#if defined(MB_ARDUINO_ESP) + return ESP.getFreeHeap(); +#elif defined(MB_ARDUINO_PICO) + return rp2040.getFreeHeap(); +#else + return 0; +#endif + } + +public: + HeapStat() {} + ~HeapStat() {} + + void reset() + { + current_heap = 0; + first_round_heap = 0; + min_heap = 0; + max_heap = 0; + diff_heap_from_first_round = 0; + diff_heap_from_current_round = 0; + _count = 0; + } + + void collect() + { + _count++; + + if (max_heap < getFreeHeap()) + max_heap = getFreeHeap(); + + if (min_heap == 0 || min_heap > getFreeHeap()) + min_heap = getFreeHeap(); + + if (first_round_heap == 0) + first_round_heap = getFreeHeap(); + + if (current_heap > 0) + { + diff_heap_from_first_round = getFreeHeap() - first_round_heap; + diff_heap_from_current_round = getFreeHeap() - current_heap; + } + + current_heap = getFreeHeap(); + } + + int current() + { + return current_heap; + } + + int min() + { + return min_heap; + } + + int max() + { + return max_heap; + } + + int diff1() + { + return diff_heap_from_first_round; + } + + int diffN() + { + return diff_heap_from_current_round; + } + + int count() + { + return _count; + } + + void print() + { + MailClient.printf("#### Heap Info\n#### Current: %d, Min: %d, Max: %d, Diff_1: %d, Diff_%d: %d\n", current(), min(), max(), diff1(), count(), diffN()); + } +}; + #endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/README.md b/lib/libesp32/ESP-Mail-Client/src/README.md index 8fe315876..6d6933a3b 100644 --- a/lib/libesp32/ESP-Mail-Client/src/README.md +++ b/lib/libesp32/ESP-Mail-Client/src/README.md @@ -1,3416 +1,3416 @@ -# ESP Mail Client Arduino Library - - -The description of the available functions in the current reease are shown below. - - -## Global functions - - -#### Sending Email through the SMTP server. - -param **`smtp`** The pointer to SMTP session object which holds the data and the TCP client. - -param **`msg`** The pointer to SMTP_Message class which contains the header, body, and attachments. - -param **`closeSession`** The option to Close the SMTP session after sent. - -return **`boolean`** The boolean value indicates the success of operation. - -```cpp -bool sendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession = true); -``` - - - -#### Append message to the mailbox - -param **`imap`** The pointer to IMAP sesssion object which holds the data and the TCP client. - -param **`msg`** The pointer to SMTP_Message class which contains the header, body, and attachments. - -param **`lastAppend`** The last message to append (optional). In case MULTIAPPEND extension - -is supported, set this to false will append messages in single APPEND command. - -param **`flags`** The flags to set to this message. - - param **`dateTime`** The date/time to set to this message (optional). - -return **`boolean`** The boolean value indicates the success of operation. - -```cpp -bool appendMessage(IMAPSession *imap, SMTP_Message *msg, T flags = ""); -``` - - -#### Reading Email through IMAP server. - -param **`imap`** The pointer to IMAP sesssion object which holds the data and the TCP client. - -param **`closeSession`** The option to close the IMAP session after fetching or searching the Email. - -return **`boolean`** The boolean value indicates the success of operation. - -```cpp -bool readMail(IMAPSession *imap, bool closeSession = true); -``` - - - - - -#### Set the argument to the Flags for the specified message. - -param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. - -param **`msgUID`** The UID of the message. - -param **`flags`** The flag list to set. - -param **`closeSession`** The option to close the IMAP session after set flag. - -param **`silent`** The option to ignore the response. - -param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. - -return **`boolean`** The boolean value indicates the success of operation. - -The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. - -```cpp -bool setFlag(IMAPSession *imap, int msgUID, flags, bool closeSession, bool silent = false, int32_t modsequence = -1); -``` - - - - - -#### Set the argument to the Flags for the specified message. - -param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. - -param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or -message sequence number or ranges of UID or sequence number. - -param **`UID`** The option for sequenceSet whether it is UID or message sequence number. - -param **`flags`** The flag list to set. - -param **`closeSession`** The option to close the IMAP session after set flag. - -param **`silent`** The option to ignore the response. - -param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. - -return **`boolean`** The boolean value indicates the success of operation. - -The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. - -```cpp -bool setFlag(IMAPSession *imap, sequenceSet, bool UID, flags, bool closeSession, bool silent = false, int32_t modsequence = -1); -``` - - - - - -#### Add the argument to the Flags for the specified message. - -param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. - -param **`msgUID`** The UID of the message. - -param **`flags`** The flag list to add. - -param **`closeSession`** The option to close the IMAP session after add flag. - -param **`silent`** The option to ignore the response. - -param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. - -return **`boolean`** The boolean value indicates the success of operation. - -The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. - -```cpp -bool addFlag(IMAPSession *imap, int msgUID, flags, bool closeSession, int32_t modsequence = -1); -``` - - - - - -#### Add the argument to the Flags for the specified message. - -param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. - -param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or -message sequence number or ranges of UID or sequence number. - -param **`UID`** The option for sequenceSet whether it is UID or message sequence number. - -param **`flags`** The flag list to add. - -param **`closeSession`** The option to close the IMAP session after set flag. - -param **`silent`** The option to ignore the response. - -param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. - -return **`boolean`** The boolean value indicates the success of operation. - -The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. - -```cpp -bool addFlag(IMAPSession *imap, sequenceSet, bool UID, flags, bool closeSession, bool silent = false, int32_t modsequence = -1); -``` - - - - - -#### Remove the argument from the Flags for the specified message. - -param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. - -param **`msgUID`** The UID of the message that flags to be removed. - -param **`flags`** The flag list to remove. - -param **`closeSession`** The option to close the IMAP session after remove flag. - -param **`silent`** The option to ignore the response. - -param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. - -return **`boolean`** The boolean value indicates the success of operation. - -The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. - -```cpp -bool removeFlag(IMAPSession *imap, int msgUID, flags, bool closeSession, int32_t modsequence = -1); -``` - - - - - -#### Remove the argument from the Flags for the specified message. - -param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. - -param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or -message sequence number or ranges of UID or sequence number. - -param **`UID`** The option for sequenceSet whether it is UID or message sequence number. - -param **`flags`** The flag list to remove. - -param **`closeSession`** The option to close the IMAP session after set flag. - -param **`silent`** The option to ignore the response. - -param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. - -return **`boolean`** The boolean value indicates the success of operation. - -The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. - -```cpp -bool removeFlag(IMAPSession *imap, sequenceSet, bool UID, flags, bool closeSession, bool silent = false, int32_t modsequence = -1); -``` - - - - - - -#### Reconnect WiFi or network if lost connection. - -param **`reconnect`** The boolean to set/unset WiFi AP reconnection. - -```cpp -void networkReconnect(bool reconnect); -``` - - - - -#### Initiate SD card with SPI port configuration. - -param **`ss`** The SPI Chip/Slave Select pin. - -param **`sck`** The SPI Clock pin. - -param **`miso`** The SPI MISO pin. - -param **`mosi`** The SPI MOSI pin. - -aram **`frequency`** The SPI frequency. - -return **`boolean`** The boolean value indicates the success of operation. - -```cpp -bool sdBegin(int8_t ss = -1, int8_t sck = -1, int8_t miso = -1, int8_t mosi = -1, uint32_t frequency = 4000000); -``` - - - - - -#### Initiate SD card with SD FS configurations (ESP8266 only). - -param **`ss`** SPI Chip/Slave Select pin. - -param **`sdFSConfig`** The pointer to SDFSConfig object (ESP8266 only). - -return **`boolean`** type status indicates the success of the operation. - -```cpp - bool sdBegin(SDFSConfig *sdFSConfig); -``` - - - - - -#### Initiate SD card with chip select and SPI configuration (ESP32 only). - -param **`ss`** The SPI Chip/Slave Select pin. - -param **`spiConfig`** The pointer to SPIClass object for SPI configuartion. - -param **`frequency`** The SPI frequency. - -return **`boolean`** The boolean value indicates the success of operation. - -```cpp -bool sdBegin(int8_t ss, SPIClass *spiConfig = nullptr, uint32_t frequency = 4000000); -``` - - - - - -#### Initiate SD card with SdFat SPI and pins configurations (with SdFat included only). - -param **`sdFatSPIConfig`** The pointer to SdSpiConfig object for SdFat SPI configuration. - -param **`ss`** The SPI Chip/Slave Select pin. - -param **`sck`** The SPI Clock pin. - -param **`miso`** The SPI MISO pin. - -param **`mosi`** The SPI MOSI pin. - -return **`boolean`** The boolean value indicates the success of operation. - -```cpp - bool sdBegin(SdSpiConfig *sdFatSPIConfig, int8_t ss = -1, int8_t sck = -1, int8_t miso = -1, int8_t mosi = -1); -``` - - - - - -#### Initiate SD card with SdFat SDIO configuration (with SdFat included only). - -param **`sdFatSDIOConfig`** The pointer to SdioConfig object for SdFat SDIO configuration. - -return **`boolean`** The boolean value indicates the success of operation. - -```cpp - bool sdBegin(SdioConfig *sdFatSDIOConfig); -``` - - - - -#### Initialize the SD_MMC card (ESP32 only). - -param **`mountpoint`** The mounting point. - -param **`mode1bit`** Allow 1 bit data line (SPI mode). - -param **`format_if_mount_failed`** Format SD_MMC card if mount failed. - -return **`Boolean`** type status indicates the success of the operation. - -```cpp -bool sdMMCBegin(const char *mountpoint = "/sdcard", bool mode1bit = false, bool format_if_mount_failed = false); -``` - - - - -#### Get free Heap memory. - -return **`int`** Free memory amount in byte. - -```cpp -int getFreeHeap(); -``` - - - - - -## IMAPSession class functions - - -The following functions are available from the IMAP Session class. - -This class used for controlling IMAP transports and retrieving the data from the IMAP server. - - - - -#### Set the tcp timeout. - -param **`timeoutSec`** The tcp timeout in seconds. - -```cpp -void setTCPTimeout(unsigned long timeoutSec); -``` - - - -#### Assign custom Client from Arduino Clients. - -param **`client`** The pointer to Arduino Client derived class e.g. WiFiClient, WiFiClientSecure, EthernetClient or GSMClient. - -```cpp -void setClient(Client *client); -``` - - -#### Assign TinyGsm Clients. - -param **`client`** The pointer to TinyGsmClient. - -param **`modem`** The pointer to TinyGsm modem object. Modem should be initialized and/or set mode before transfering data. - -param **`pin`** The SIM pin. - -param **`apn`** The GPRS APN (Access Point Name). - -param **`user`** The GPRS user. - -param **`password`** The GPRS password. - -```cpp -void setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password); -``` - - -#### Assign the callback function to handle the network connection for custom Client. - -param **`networkConnectionCB`** The function that handles the network connection. - -```cpp -void networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB); -``` - - - -#### Assign the callback function to handle the network connection status acknowledgement. - -param **`networkStatusCB`** The function that handle the network connection status acknowledgement. - -```cpp -void networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB); -``` - - - -#### Set the network status acknowledgement. - -param **`status`** The network status. - -```cpp -void setNetworkStatus(bool status); -``` - - - -#### Set the BearSSL IO buffer size. - -param **`rx`** The BearSSL receive buffer size in bytes. - -param **`tx`** The BearSSL trasmit buffer size in bytes. - -```cpp -void setSSLBufferSize(int rx = -1, int tx = -1); -``` - - - -#### Set system time with timestamp. - -param **`ts`** timestamp in seconds from midnight Jan 1, 1970. - -param **`gmtOffset`** The GMT offset. - -This function allows the internal time setting by timestamp i.e. timestamp from external RTC. - -```cpp -void setSystemTime(time_t ts, float gmtOffset = 0); -``` - - - -#### Begin the IMAP server connection. - -param **`session_config`** The pointer to Session_Config structured data that keeps the server and log in details. - -param **`imap_data`** The pointer to IMAP_Data structured data that keeps the operation options. - -param **`login`** The bool option for login after server connection. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool connect(Session_Config *session_config, IMAP_Data *imap_data, bool login = true); -``` - - - -#### Login to IMAP server using Email and password. - -param **`email`** The IMAP server account email. - -param **`password`** The IMAP server account password. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bbool loginWithPassword( email, password); -``` - - - -#### Login to IMAP server using Email and access token. - -param **`email`** The IMAP server account email. - -param **`token`** The Access token to log in. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bbool loginWithAccessToken( email, token); -``` - - -#### Send the client identification to the server - -param **`identification`** The pointer to IMAP_Identification structured data that keeps - -the key properties e.g., name, version, os, os_version, vendor, support_url, address, - -date, command, arguments, and environment. - -```cpp -bool id(IMAP_Identification *identification); -``` - - -#### Return the server ID returns from ID command. - -return **`The server ID string.`** - -```cpp -String serverID(); -``` - - -#### Return the SASL authentication status. - -return **`boolean`** The boolean value indicates SASL authentication status. - -```cpp -bool isAuthenticated(); -``` - - -#### Return the log in status. - -return **`boolean`** The boolean value indicates log in status. - -```cpp -bool isLoggedIn(); -``` - - -#### Return firmware update result when attachment filename matches. - -return **`boolean`** The boolean value indicates the firmware update status. - -```cpp -bool isFirmwareUpdateSuccess(); -``` - - -#### Close the IMAP session. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool closeSession(); -``` - - -#### Setup TCP KeepAlive for internal TCP client. - -param **`tcpKeepIdleSeconds`** lwIP TCP Keepalive idle in seconds. - -param **`tcpKeepIntervalSeconds`** lwIP TCP Keepalive interval in seconds. - -param **`tcpKeepCount`** lwIP TCP Keepalive count. - -For the TCP (KeepAlive) options, see [this doc](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/lwip.html#tcp-options). - -If value of one of these parameters is zero, the TCP KeepAlive will be disabled. - -You can check the server connecting status, by exexuting `.connected()` which will return true when connection to the server is still alive. - -```cpp -void keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount); -``` - - - -#### Get TCP KeepAlive status. - -return **`Boolean`** status of TCP Keepalive. - -```cpp -bool isKeepAlive(); -``` - - - -#### Get TCP connection status. - -return **`boolean`** The boolean value indicates the connection status. - -```cpp -bool connected(); -``` - - - - - - -#### Set to enable the debug. - -param **`level`** The level to enable the debug message - -level = 0, no debugging - -level = 1, basic level debugging - -```cpp -void debug(int level); -``` - - - - - -#### Get the list of all the mailbox folders since the TCP session was opened and user was authenticated. - -param **`folders`** The FoldersCollection class that contains the collection of the -FolderInfo structured data. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool getFolders(FoldersCollection &folders); -``` - - - - - -#### Select or open the mailbox folder to search or fetch the message inside. - -param **`folderName`** The known mailbox folder name. The default name is INBOX. - -param **`readOnly`** The option to open the mailbox for read only. Set this option to false when you wish -to modify the Flags using the setFlag, addFlag and removeFlag functions. - -return **`boolean`** The boolean value which indicates the success of operation. - -note: the function will exit immediately and return true if the time since previous success folder selection (open) with the same readOnly mode, is less than 5 seconds. - -```cpp -bool selectFolder( folderName, bool readOnly = true); -``` - - - - - -#### Open the mailbox folder to read or search the mesages. - -param **`folderName`** The name of known mailbox folder to be opened. - -param **`readOnly`** The option to open the mailbox for reading only. Set this option to false when you wish -to modify the flags using the setFlag, addFlag and removeFlag functions. - -return **`boolean`** The boolean value which indicates the success of operation. - -note: the function will exit immediately and return true if the time since previous success folder selection (open) with the same readOnly mode, is less than 5 seconds. - -```cpp -bool openFolder( folderName, bool readOnly = true); -``` - - - - - -#### Close the mailbox folder that was opened. - -param **`expunge`** The option to allow emty the deleted flag set messages in case folder was open with editable mode. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool closeFolder(bool expunge = false); -``` - - - - - - -#### Create folder. - -param **`folderName`** The name of folder to create. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool createFolder( folderName); -``` - - - - - -#### Get subscribes mailboxes. - -param **`reference`** The reference name. - -param **`mailbox`** The mailbox name with possible wildcards. - -param **`folders`** The return FoldersCollection that contains the folder info e.g., name, attribute and delimiter. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool getSubscribesMailboxes( reference, mailbox, FoldersCollection &folders); -``` - - - - -#### Subscribe mailbox. - -param **`folderName`** The name of folder to subscribe. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool subscribe( folderName) -``` - - - - -#### Unsubscribe mailbox. - -param **`folderName`** The name of folder to unsubscribe. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool unSubscribe( folderName) -``` - - - - - -#### Rename folder. - -param **`currentFolderName`** The name of folder to create. - -param **`newFolderName`** The new name of folder to create. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool renameFolder( currentFolderName, newFolderName); -``` - - - -#### Delete folder. - -param **`folderName`** The name of folder to delete.. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool deleteFolder( folderName); -``` - - - - - - -#### Get UID number in selected or opened mailbox. - -param **`msgNum`** The message number or order in the total message numbers. - -return **`boolean`** The boolean value which indicates the success of operation. - -Returns 0 when fail to get UID. - -```cpp -int getUID(int msgNum); -``` - - - - - - - -#### Get message flags in selected or opened mailbox. - -param **`msgNum`** The message number or order in the total message numbers. - -return **`string`** Message flags in selected or opened mailbox. - -empty string when fail to get flags. - -```cpp -const char *getFlags(int msgNum); -``` - - - - - - -#### Send the custom IMAP command and get the result via callback. - -param **`cmd`** The command string. - -param **`callback`** The function that accepts IMAP_Response as parameter. - -param **`tag`** The tag string to pass to the callback function. - -return **`boolean`** The boolean value which indicates the success of operation. - -imap.connect and imap.selectFolder or imap.openFolder are needed to call once prior to call this function. - -```cpp -bool sendCustomCommand( cmd, imapResponseCallback callback, tag); -``` - - - - - -#### Send the custom IMAP command data string. - -param **`data`** The string data. - -param **`lastData`** The flag represents the last data to send (optional). - -return **`boolean`** The boolean value which indicates the success of operation. - -Should be used after calling sendCustomCommand("APPEND xxxxxx"); - -```cpp -bool sendCustomData(T data, bool lastData = false); -``` - - - - - -#### Send the custom IMAP command data. - -param **`data`** The byte data. - -param **`size`** The data size. - -param **`lastData`** The flag represents the last data to send (optional). - -return **`boolean`** The boolean value which indicates the success of operation. - -Should be used after calling ssendCustomCommand("APPEND xxxxxx"); - -```cpp -bool sendCustomData(uint8_t *data, size_t size, bool lastData = false); -``` - - - - -#### Begin the IMAP server connection without authentication. - -param **`session_config`** The pointer to Session_Config structured data that keeps the server and log in details. - -param **`callback`** The callback function that accepts IMAP_Response as parameter. - -param **`tag`** The tag that pass to the callback function. - -return **`The boolean`** value indicates the success of operation. - -```cpp -bool customConnect(Session_Config *session_config, imapResponseCallback callback, tag); -``` - - - - -#### Copy the messages to the defined mailbox folder. - -param **`toCopy`** The pointer to the MessageList class that contains the list of messages to copy. - -param **`dest`** The destination folder that the messages to copy to. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool copyMessages(MessageList *toCopy, dest); -``` - - - - - -#### Copy the messages to the defined mailbox folder. - -param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or -message sequence number or ranges of UID or sequence number. - -param **`UID`** The option for sequenceSet whether it is UID or message sequence number. - -param **`dest`** The destination folder that the messages to copy to. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool copyMessages( sequenceSet, bool UID, dest); -``` - - - - - - -#### Move the messages to the defined mailbox folder. - -param **`toMove`** The pointer to the MessageList class that contains the list of messages to move. - -param **`dest`** The destination folder that the messages to move to. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool moveMessages(MessageList *toMove, dest); -``` - - - - - -#### Move the messages to the defined mailbox folder. - -param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or -message sequence number or ranges of UID or sequence number. - -param **`UID`** The option for sequenceSet whether it is UID or message sequence number. - -param **`dest`** The destination folder that the messages to move to. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool moveMessages( sequenceSet, bool UID, dest); -``` - - - - - - -#### Delete the messages in the opened mailbox folder. - -param **`toDelete`** The pointer to the MessageList class that contains the list of messages to delete. - -param **`expunge`** The boolean option to expunge all messages. - -param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. - -return **`boolean`** The boolean value indicates the success of operation. - -The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. - -```cpp -bool deleteMessages(MessageList *toDelete, bool expunge = false, int32_t modsequence = -1); -``` - - - - - - -#### Delete the messages in the opened mailbox folder. - -param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or -message sequence number or ranges of UID or sequence number. - -param **`UID`** The option for sequenceSet whether it is UID or message sequence number. - -param **`expunge`** The boolean option to expunge all messages. - -param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. - -return **`boolean`** The boolean value indicates the success of operation. - -The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. - -```cpp -bool deleteMessages( sequenceSet, bool UID, bool expunge = false, int32_t modsequence = -1); -``` - - - - - - -#### Get the quota root's resource usage and limits. - -param **`quotaRoot`** The quota root to get. - -param **`info`** The pointer to `IMAP_Quota_Root_Info` that contains quota root's resource name, usage and limit. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool getQuota( quotaRoot, IMAP_Quota_Root_Info *info); -``` - - - - - -#### Set the quota root's resource usage and limits. - -param **`quotaRoot`** The quota root to set. - -param **`data`** The pointer to `IMAP_Quota_Root_Info` that contains quota root's resource name, usage and limit. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool setQuota( quotaRoot, IMAP_Quota_Root_Info *data); -``` - - - - - -#### Get the list of quota roots for the named mailbox. - -param **`mailbox`** The mailbox name. - -param **`quotaRootsList`** The pointer to `IMAP_Quota_Roots_List` that contains the list of `IMAP_Quota_Root_Info`. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool getQuotaRoot( mailbox, IMAP_Quota_Roots_List *quotaRootsList); -``` - - - - - -#### Get the ACLs for a mailbox. - -param **`mailbox`** The mailbox name. - -param **`aclList`** The pointer to the returning `IMAP_Rights_List` object. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool getACL( mailbox, IMAP_Rights_List *aclList); -``` - - - - - - -#### Get the ACLs for a mailbox. - -param **`mailbox`** The mailbox name. - -param **`acl`** The pointer to the acl IMAP_Rights_Info to set. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool setACL( mailbox, IMAP_Rights_Info *acl); -``` - - - - - - -#### Delete the ACLs set for identifier on mailbox. - -param **`mailbox`** The mailbox name. - -param **`identifier`** The identifier (user) to remove the rights. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool deleteACL( mailbox, identifier); -``` - - - - - -#### Show my ACLs for a mailbox. - -param **`mailbox`** The mailbox name. - -param **`acl`** The pointer to the returning `IMAP_Rights_Info` object. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool myRights( mailbox, IMAP_Rights_Info *acl); -``` - - - - - -#### Returns IMAP namespaces. - -param **`mailbox`** The mailbox name. - -param **`ns`** The pointer to the returning `IMAP_Namespaces_List` object. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool getNamespace(IMAP_Namespaces_List *ns); -``` - - - - - - -#### Enable IMAP capability. - -param **`capability`** The mailbox name. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool enable( capability); -``` - - - - - -#### Listen for the selected or open mailbox for updates. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool listen(); -``` - - - - - - -#### Stop listen for the mailbox for updates. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool stopListen(); -``` - - - - - - - -#### Check for the selected or open mailbox updates. - -return **`boolean`** The boolean value which indicates the changes status of mailbox. - -```cpp -bool folderChanged(); -``` - - - - - - -#### Assign the callback function that returns the operating status when fetching or reading the Email. - -param **`imapCallback`** The function that accepts the `imapStatusCallback` as parameter. - -```cpp -void callback(imapStatusCallback imapCallback); -``` - - - - -#### Assign the callback function to decode the string based on the character set. - -param **`callback`** The function that accepts the pointer to `IMAP_Decoding_Info` as parameter. - -```cpp -void characterDecodingCallback(imapCharacterDecodingCallback callback); -``` - - - -#### Assign the callback function that returns the MIME data stream from fetching or reading the Email. - -param **`mimeDataStreamCallback`** The function that accepts the `MIME_Stream_Info` as parameter. - -```cpp -void mimeDataStreamCallback(MIMEDataStreamCallback mimeDataStreamCallback); -``` - - - - - -#### Determine if no message body contained in the search result and only the message header is available. - -```cpp -bool headerOnly(); -``` - - - - - -#### Get the message list from search or fetch the Emails - -return **`The IMAP_MSG_List structured`** data which contains the text and html contents, -attachments, inline images, embedded rfc822 messages details for each message. - -```cpp -IMAP_MSG_List data(); -``` - - - - -#### Get the details of the selected or opned mailbox folder - -return **`The SelectedFolderInfo class`** instance which contains the info about flags, total messages, next UID, -earch count and the available messages count. - -```cpp -SelectedFolderInfo selectedFolder(); -``` - - - - - -#### Get the error details when readingg the Emails. - -return **`String`** The string of error details. - -```cpp -String errorReason(); -``` - - -#### Get the operating status error code. - -return **`int`** The value of operating status error code. - -The negative value indicated error. - -See src/ESP_Mail_Error.h and extras/MB_FS.h - -```cpp -int errorCode(); -``` - - - -#### Clear all the cache data stored in the IMAP session object. - -```cpp -void empty(); -``` - - - -#### Get the status of message fetching and searching. - -return **`IMAP_Status`** The IMAP_Status object contains the fetching and searching statuses. - -```cpp -IMAP_Status status(); -``` - - - -#### Get the JSON string of file name list of files that stored in SD card. - -return **`The JSON string`** of filenames. - -note This will available only when standard SD library was used and file storage is SD. - -```cpp -String fileList(); -``` - - -## SMTPSession class functions - - -The following functions are available from the SMTP Session class. - -This class is similar to the IMAP session class, used for controlling SMTP transports -and retrieving the data from the SMTP server. - - - - -#### Set the tcp timeout. - -param **`timeoutSec`** The tcp timeout in seconds. - -```cpp -void setTCPTimeout(unsigned long timeoutSec); -``` - - - -#### Assign custom Client from Arduino Clients. - -param **`client`** The pointer to Arduino Client derived class e.g. WiFiClient, WiFiClientSecure, EthernetClient or GSMClient. - -```cpp -void setClient(Client *client); -``` - - -#### Assign TinyGsm Clients. - -param **`client`** The pointer to TinyGsmClient. - -param **`modem`** The pointer to TinyGsm modem object. Modem should be initialized and/or set mode before transfering data. - -param **`pin`** The SIM pin. - -param **`apn`** The GPRS APN (Access Point Name). - -param **`user`** The GPRS user. - -param **`password`** The GPRS password. - -```cpp -void setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password); -``` - - - -#### Assign the callback function to handle the network connection for custom Client. - -param **`networkConnectionCB`** The function that handles the network connection. - -```cpp -void networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB); -``` - - -#### Assign the callback function to handle the network connection status acknowledgement. - -param **`networkStatusCB`** The function that handle the network connection status acknowledgement. - -```cpp -void networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB); -``` - - - -#### Set the network status acknowledgement. - -param **`status`** The network status. - -```cpp -void setNetworkStatus(bool status); -``` - - - -#### Set the BearSSL IO buffer size. - -param **`rx`** The BearSSL receive buffer size in bytes. - -param **`tx`** The BearSSL trasmit buffer size in bytes. - -```cpp -void setSSLBufferSize(int rx = -1, int tx = -1); -``` - - - -#### Set system time with timestamp. - -param **`ts`** timestamp in seconds from midnight Jan 1, 1970. - -param **`gmtOffset`** The GMT offset. - -This function allows the internal time setting by timestamp i.e. timestamp from external RTC. - -```cpp -void setSystemTime(time_t ts, float gmtOffset = 0); -``` - - - -#### Begin the SMTP server connection. - -param **`session_config`** The pointer to Session_Config structured data that keeps the server and log in details. - -param **`login`** The bool option for login after server connection. - -return **`boolean`** The boolean value indicates the success of operation. - -```cpp -bool connect(Session_Config *session_config, bool login = true); -``` - - - -#### Login to SMTP server using Email and password. - -param **`email`** The SMTP server account email. - -param **`password`** The SMTP server account password. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool loginWithPassword( email, password); -``` - - - -#### Login to SMTP server using Email and access token. - -param **`email`** The SMTP server account email. - -param **`token`** The Access token to log in. - -return **`boolean`** The boolean value which indicates the success of operation. - -```cpp -bool loginWithAccessToken( email, token); -``` - - -#### Return the SASL authentication status. - -return **`boolean`** The boolean value indicates SASL authentication status. - -```cpp -bool isAuthenticated(); -``` - - - -#### Return the log in status. - -return **`boolean`** The boolean value indicates log in status. - -```cpp -bool isLoggedIn(); -``` - - -#### Close the SMTP session. - -```cpp -bool closeSession(); -``` - - - -#### Setup TCP KeepAlive for internal TCP client. - -param **`tcpKeepIdleSeconds`** lwIP TCP Keepalive idle in seconds. - -param **`tcpKeepIntervalSeconds`** lwIP TCP Keepalive interval in seconds. - -param **`tcpKeepCount`** lwIP TCP Keepalive count. - -For the TCP (KeepAlive) options, see [this doc](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/lwip.html#tcp-options). - -If value of one of these parameters is zero, the TCP KeepAlive will be disabled. - -You can check the server connecting status, by exexuting `.connected()` which will return true when connection to the server is still alive. - -```cpp -void keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount); -``` - - - -#### Get TCP KeepAlive status. - -return **`Boolean`** status of TCP Keepalive. - -```cpp -bool isKeepAlive(); -``` - - - -#### Get TCP connection status. - -return **`boolean`** The boolean value indicates the connection status. - -```cpp -bool connected(); -``` - - - - -#### Begin the SMTP server connection without authentication. - -param **`session_config`** The pointer to Session_Config structured data that keeps the server and log in details. - -param **`callback`** The callback function that accepts the SMTP_Response as parameter. - -param **`commandID`** The command identifier number that will pass to the callback. - -return **`The int`** value of response code. - -If commandID was not set or set to -1, the command identifier will be auto increased started from zero. - -```cpp -int customConnect(Session_Config *session_config, smtpResponseCallback callback, int commandID = -1); -``` - - - - - - -#### Send the custom SMTP command and get the result via callback. - -param **`cmd`** The command string. - -param **`callback`** The function that accepts the SMTP_Response as parameter. - -return **`boolean`** The boolean value which indicates the success of operation. - -smtp.connect or smtp.customConnect is needed to call once prior to call this function. - -```cpp -bool sendCustomCommand( cmd, smtpResponseCallback callback); -``` - - - - - -#### Send the custom SMTP command data string. - -param **`data`** The string data. - -return **`The boolean`** value which indicates the success of operation. - -Should be used after calling sendCustomCommand("DATA"); - -```cpp -bool sendCustomData( data); -``` - - - - -#### Send the custom SMTP command data. - -param **`data`** The byte data. - -param **`size`** The data size. - -return **`The boolean`** value which indicates the success of operation. - -Should be used after calling sendCustomCommand("DATA"); - -```cpp -bool sendCustomData(uint8_t *data, size_t size); -``` - - - - - -#### Set to enable the debug. - -param **`level`** The level to enable the debug message - -level = 0, no debugging - -level = 1, basic level debugging - -```cpp -void debug(int level); -``` - - - - - -#### Get the error details when sending the Email - -return **`String`** The string of error details. - -```cpp -String errorReason(); -``` - - -#### Get the operating status error code. - -return **`int`** The value of operating status error code. - -The negative value indicated error. - -See src/ESP_Mail_Error.h and extras/MB_FS.h - -```cpp -int errorCode(); -``` - - - -#### Get the SMTP server response status code. - -return **`int`** The value of SMTP server response status code. - -See RFC 5321 standard's documentation. - -```cpp -int statusCode(); -``` - - - -#### Get the SMTP server response status message. - -return **`String`** The value of SMTP server response status message. - -```cpp -String statusMessage(); -``` - - - -#### Set the Email sending status callback function. - -param **`smtpCallback`** The callback function that accept the `smtpStatusCallback` param. - -```cpp -void callback(smtpStatusCallback smtpCallback); -``` - - -#### Get the status of message fetching and searching. - -return **`SMTP_Status`** The SMTP_Status object contains the sending status. - -```cpp -SMTP_Status status(); -``` - -## SMTP_Message class functions - - -The following functions are available from the SMTP Message class. - -This class is used for storing the message data including headers, body and attachments -which will be processed with the SMTP session class. - - - - -#### To reset the SMTP_Attachment item data - -param **`att`** The SMTP_Attachment class that stores the info about attachment - -This function was used for clear the internal data of attachment item to be ready for reuse. - -```cpp -void resetAttachItem(SMTP_Attachment &att); -``` - - - -#### To clear all data in SMTP_Message class included headers, bodies and attachments - -```cpp -void clear(); -``` - - - - -#### To clear all the inline images in SMTP_Message class. - -```cpp -void clearInlineimages(); -``` - - - - - -#### To clear all the attachments. - -```cpp -void clearAttachments(); -``` - - - - - -#### To clear all rfc822 message attachment. - -```cpp -void clearRFC822Messages(); -``` - - - - - -#### To clear the primary recipient mailboxes. - -```cpp -void clearRecipients(); -``` - - - - - -#### To clear the Carbon-copy recipient mailboxes. - -```cpp -void clearCc(); -``` - - - - - -#### To clear the Blind-carbon-copy recipient mailboxes. - -```cpp -void clearBcc(); -``` - - -#### To clear the custom message headers. - -```cpp -void clearHeader(); -``` - - - - -#### To add attachment to the message. - -param **`att`** The SMTP_Attachment data item - -```cpp -void addAttachment(SMTP_Attachment &att); -``` - - - - - -#### To add parallel attachment to the message. - -param **`att`** The SMTP_Attachment data item - -```cpp -void addParallelAttachment(SMTP_Attachment &att); -``` - - - - - -#### To add inline image to the message. - -param **`att`** The SMTP_Attachment data item - -```cpp -void addInlineImage(SMTP_Attachment &att); -``` - - - - - -#### To add rfc822 message to the message. - -param **`msg`** The RFC822_Message class object - -```cpp -void addMessage(SMTP_Message &msg); -``` - - - - - -#### To add the primary recipient mailbox to the message. - -param **`name`** The name of primary recipient - -param **`email`** The Email address of primary recipient - -```cpp -void addRecipient( name, email); -``` - - - - - -#### To add Carbon-copy recipient mailbox. - -param **`email`** The Email address of secondary recipient - -```cpp -void addCc( email); -``` - - - - - -#### To add Blind-carbon-copy recipient mailbox. - -param **`email`** The Email address of the tertiary recipient - -```cpp -void addBcc( email); -``` - - - - - -#### To add the custom header to the message. - -param **`hdr`** The header name and value - -```cpp -void addHeader( hdr); -``` - - - - -##### [properties] The message author config - -This property has the sub properties - -###### [const char*] name - The sender name. - -###### [const char*] email - The sender Email address. - -```cpp -esp_mail_email_info_t sender; -``` - - -##### [properties] The topic of message - -```cpp -const char *subject; -``` - - -##### [properties] The message type - -```cpp -byte type; -``` - - -##### [properties] The PLAIN text message - -This property has the sub properties - -###### [esp_mail_smtp_embed_message_body_t] embed - The option to embed this message content as a file. - -###### [const char*] content - The PLAIN text content of the message. - -###### [esp_mail_blob_message_content_t] blob - The blob that contins PLAIN text content of the message. - -###### [esp_mail_file_message_content_t] file - The file that contins PLAIN text content of the message. - -###### [const char*] charSet - The character transcoding of the PLAIN text content of the message. - -###### [const char*] content_type - The content type of message. - -###### [const char*] transfer_encoding - The option to encode the content for data transfer. - -###### [boolean] flowed - The option to send the PLAIN text with wrapping. - -```cpp -esp_mail_plain_body_t text; -``` - - -##### [properties] The HTML text message - -This propery has the sub properties - -###### [const char*] content - The HTML content of the message. - -###### [esp_mail_blob_message_content_t] blob - The blob that contins HTML content of the message. - -###### [esp_mail_file_message_content_t] file - The file that contins HTML content of the message. - -###### [const char*] charSet - The character transcoding of the HTML content of the message. - -###### [const char*] content_type - The content type of message. - -###### [const char*] transfer_encoding - The option to encode the content for data transfer. - -```cpp -esp_mail_html_body_t html; -``` - - -##### [properties] The response config - -This propery has the sub properties - -###### [const char*] reply_to - The author Email address to reply. - -###### [const char*] return_path - The sender Email address to return the message. - -###### [int] notify - The Delivery Status Notifications enumeration e.g. - -esp_mail_smtp_notify_never = 0, - -esp_mail_smtp_notify_success = 1, - -esp_mail_smtp_notify_failure = 2, and - -esp_mail_smtp_notify_delay = 4 - -```cpp -esp_mail_smtp_msg_response_t response; -``` - - -##### [properties] The priority of the message - -This property has the enumeration values - -esp_mail_smtp_priority_high = 1, - -esp_mail_smtp_priority_normal = 3, - -esp_mail_smtp_priority_low = 5 - -```cpp -esp_mail_smtp_priority priority; -``` - - -##### [properties] The enable options - -This propery has the sub property - -###### [boolean] chunking - enable chunk data sending for large message. - -```cpp -esp_mail_smtp_enable_option_t enable; -``` - - -##### [properties] The message from config - -This property has the sub properties - -###### [const char*] name - The messsage author name. - -###### [const char*] email - The message author Email address. - -```cpp -esp_mail_email_info_t from; -``` - - -##### [properties] The message identifier - -```cpp -const char *ID; -``` - -##### [properties] The keywords or phrases, separated by commas - -```cpp -const char *keywords; -``` - - -##### [properties] The comments about message - -```cpp -const char *comments; -``` - - -##### [properties] The date of message - -```cpp -const char *date; -``` - - -##### [properties] The return recipient of the message - -```cpp -const char *return_path; -``` - - - -##### [properties] The field that contains the parent's message ID of the message to which this one is a reply - -```cpp -const char *in_reply_to; -``` - - - -##### [properties] The field that contains the parent's references (if any) and followed by the parent's message ID (if any) of the message to which this one is a reply - -```cpp -const char *references; -``` - - -## IMAP_Status class functions - - -The following functions are available from the IMAP Status class. - -This class is used as the callback parameter for retrieving the status while reading the Email. - - - - -#### Get the information of each process in the reading operation. - -return **`string`** The info for each process - -```cpp -const char *info(); -``` - - - - -#### Get the status of completion. - -return **`boolean`** The bool value indicates that all reading processes are finished - -```cpp -bool success(); -``` - - - - - -#### To clear all data store in this class. - -```cpp -void empty(); -``` - - - - - - -## SMTP_Status class functions - - -The following functions are available from the SMTP Status class. - -This class is used as the callback parameter for retrieving the status while sending the Email. - - - - -#### Get the information of each process in the sending operation. - -return **`string`** The info for each process - -```cpp -const char *info(); -``` - - - - -#### Get the status of completion. - -return **`boolean`** The bool value indicates that all sending processes are finished - -```cpp -bool success(); -``` - - - - - -#### To clear all data store in this class. - -```cpp -void empty(); -``` - - - - -#### Get the number of complete sending message. - -return **`number`** The number of message that was sent - -```cpp -size_t completedCount(); -``` - - - - - -#### Get the number of failed sending message. - -return **`number`** The number of message that was not sent - -```cpp -size_t failedCount(); -``` - - - - -## SendingResult class functions - - -The following functions are available from the SendingResult class. - -This class is used for retrieving the info about the result of sending the messages. - - - - -#### Get the information of a message sending status. - -param **`index`** The index number of a message sending status - -return **`SMTP_Result`** The SMTP_Result type data that provides these properties - -##### [bool] completed - The status of the message - -#### [MB_String] recipients - The primary recipient mailbox of the message - -#### [MB_String] subject - The topic of the message - -#### [time_t] timesstamp - The timestamp of the message - -```cpp -SMTP_Result getItem(size_t index); -``` - - - - - -#### Get the amount of the result data. - -return **`number`** The number of result item - -```cpp -size_t size(); -``` - - - - -## SMTP_Response type data - -The following properties are available from the SMTP_Response data type. - -This data type obtains the response from sending custom SMTP commands. - - -#### [Properties] The command identifier - -```cpp -int id; -``` - -#### [Properties] The response text - -```cpp -MB_String text; -``` - - -#### [Properties] The response code - -```cpp -int respCode; -``` - - - - -## FoldersCollection class functions - - -The following functions are available from the FoldersCollection class. - -This class is used for retrieving the info about the mailbox folders which available to read or serach -in the user Email mailbox. - - - - -#### Get the information of a folder in a folder collection. - -param **`index`** The index number of folders - -return **`esp_mail_folder_info_item_t`** The esp_mail_folder_info_item_t structured data that provides these properties - -#### [MB_String] name - The name of folder - -#### [MB_String] attributes - The attributes of folder - -#### [MB_String] delimiter - The delimeter of folder - -```cpp -esp_mail_folder_info_item_t info(size_t index); -``` - - - - - -#### Get the number of folders in the collection. - -return **`number`** The number of folder in the collection - -```cpp -size_t size(); -``` - - - - - - -## SelectedFolderInfo class functions - - -The following functions are available from the SelectedFolderInfo class. - -This class is used for retrieving the info about the sselected or opened mailbox folder. - - - - -#### Get the numbers of flags in the user Email mailbox. - -return **`number`** The numbers of flags - -```cpp -size_t flagCount(); -``` - - - - - -#### Get the numbers of messages in this mailbox. - -return **`number`** The numbers of messages in the selected mailbox folder - -```cpp -size_t msgCount(); -``` - - - - - - -#### Get the numbers of messages in this mailbox that recent flag was set. - -return **`number`** The numbers of messages in the selected mailbox folder that recent flag was set - -```cpp -size_t recentCount(); -``` - - - - - - -#### Get the order of message in number of message in this mailbox that reoved. - -return **`IMAP_Polling_Status`** The data that holds the polling status. - -The IMAP_Polling_Status has the properties e.g. type, messageNum, and argument. - -The type property is the type of status e.g.imap_polling_status_type_undefined, imap_polling_status_type_new_message, -imap_polling_status_type_remove_message, and imap_polling_status_type_fetch_message. - -The messageNum property is message number or order from the total number of message that added, fetched or deleted. - -The argument property is the argument of commands e.g. FETCH - -```cpp -struct IMAP_Polling_Status pollingStatus(); -``` - - - - - - - - -#### Get the predicted next message UID in the sselected folder. - -return **`number`** The number represents the next message UID number - -```cpp -size_t nextUID(); -``` - - - - - - - -#### Get the numbers of messages from search result based on the search criteria. - -return **`number`** The total number of messsages from search - -```cpp -size_t searchCount(); -``` - - - - - -#### Get the numbers of messages to be stored in the ressult. - -return **`number`** The number of messsage stored from search - -```cpp -size_t availableMessages(); -``` - - - - - -#### Get the flag argument at the specified index. - -return **`index`** The index of flag in the flags list - -return **`String`** The argument of selected flag - -```cpp -String flag(size_t index); -``` - - - - -## Session_Config type data - - -The following properties are available from the Session_Config data type. - -This data type is used for storing the session info about the server and login credentials. - - -#### [Properties] The server config - -This property has the sub properties - -##### [MB_String] host_name - The hostName of the server. - -##### [uint16_t] port - The port on the server to connect to. - -```cpp -esp_mail_sesson_sever_config_t server; -``` - - -#### [Properties] The log in config - -This property has the sub properties - -##### [MB_String] email - The user Email address to log in. - -##### [consst char *] password - The user password to log in. - -##### [consst char *] accessToken - The OAuth2.0 access token to log in. - -##### [consst char *] user_domain - The host name or public IP of client system. - -```cpp -esp_mail_sesson_login_config_t login; -``` - - -#### [Properties] The secure config - -This property has the sub properties - -##### [bool] startTLS - The option to send the command to start the TLS connection. - -```cpp -esp_mail_sesson_secure_config_t secure; -``` - - -#### [Properties] The ports and protocols config - -This property has the sub properties - -##### [port_function *] list - The list (aray) of port_function. - -##### [size_t] size - The size of array. - -```cpp -esp_mail_ports_functions ports_functions; -``` - - - - -#### [Properties] The certificate config - -##### [const char *] cert_data - The certificate data (base64 data). - -##### [const char *] cert_file - The certificate file (DER format). - -##### [esp_mail_file_storage_type] cert_file_storage_type - The storage type. - -##### [bool] verify - The cerificate verification option. - -```cpp -esp_mail_sesson_cert_config_t certificate; -``` - - - -#### [Properties] SPI Ethernet Module config for ESP8266 - -##### [ENC28J60lwIP *] enc28j60 - The ENC28J60 Ethernet module lwip interfac. - -##### [Wiznet5100lwIP *] w5100 - The W5100 Ethernet module lwip interfac. - -##### [Wiznet5500lwIP *] w5500 - The W5500 Ethernet module lwip interfac. - -```cpp -esp_mail_spi_ethernet_module_t spi_ethernet_module; -``` - - - -#### [Properties] The callback function for WiFi connection - -```cpp -NetworkConnectionHandler network_connection_handler; -``` - - - - -## port_function type data - -#### [Properties] The port number - -```cpp -uint16_t port; -``` - -#### [Properties] The protocol - -The port protocol e.g. esp_mail_protocol_plain_text, esp_mail_protocol_ssl and esp_mail_protocol_tls. - -```cpp -esp_mail_protocol protocol; -``` - - - - -## IMAP_Data type data - - -The following properties are available from the IMAP_Data data type. - -This data type is used for storing the IMAP transport and operating options to -control and store the operation result e.g. the messahe contents from search and fetch. - - - - -#### [Properties] The config for fetching - -This property has the sub properties - -##### [MB_String] uid - The UID of message to fetch. - -##### [MB_String] number - The message sequence number to fetch. - -##### [esp_mail_imap_sequence_set_t] sequence_set - The sequence set options. - -##### [MB_String] set_seen - Set the message flag as seen. - -```cpp -esp_mail_imap_fetch_config_t fetch; -``` - - -#### [Properties] The config for IMAP sequence set fetching - -This property has the sub properties - -##### [MB_String] string - The sequence set string i.g., unique identifier (UID) -or message sequence number or ranges of UID or sequence number. - -##### [bool] UID - The option for sequenceSet whether it is UID or message sequence number. - -##### [bool] headerOnly - The option for header only fetching. - -```cpp -esp_mail_imap_sequence_set_t fetch; -``` - - -#### [Properties] The config for search - -This property has the sub properties - -##### [MB_String] criteria - The search criteria. - -##### [boolean] unseen_msg - The option to search the unseen message. - -```cpp -esp_mail_imap_search_config_t search; -``` - - -#### [Properties] The config about the limits - -This property has the sub properties - -##### [size_t] search - The maximum messages from the search result. - -##### [size_t] fetch - The maximum messages from the sequence set fetching result. - -##### [size_t] msg_size - The maximum size of the memory buffer to store the message content. - -This is only limit for data to be stored in the IMAPSession. - -##### [size_t] attachment_size - The maximum size of each attachment to download. - -The IMAP idle (polling) timeout in ms (1 min to 29 min). Default is 10 min. - -##### [size_t] imap_idle_timeout - The IMAP idle timeout in ms. - -The IMAP idle (polling) host check interval in ms (30 sec to imap_idle_timeout) -for internet availability checking to ensure the connection is active. - -Default is 1 min. - -##### [size_t] imap_idle_host_check_interval - The IMAP idle host check interval in ms. - - -```cpp -esp_mail_imap_limit_config_t limit; -``` - - - -#### [Properties] The config to enable the features - -This property has the sub properties - -##### [boolean] text - To store the PLAIN text of the message in the IMAPSession. - -##### [boolean] html - To store the HTML of the message in the IMAPSession. - -##### [boolean] rfc822 - To store the rfc822 messages in the IMAPSession. - -##### [boolean] download_status - To enable the download status via the serial port. - -##### [boolean] recent_sort - To sort the message UID of the search result in descending order. - -##### [boolean] header_case_sesitive - To allow case sesitive in header parsing. - -```cpp -esp_mail_imap_enable_config_t enable; -``` - - - -#### [Properties] The config about downloads - -This property has the sub properties - -##### [boolean] text - To download the PLAIN text content of the message. - -##### [boolean] html - To download the HTML content of the message. - -##### [boolean] attachment - To download the attachments of the message. - -##### [boolean] inlineImg - To download the inline image of the message. - -##### [boolean] rfc822 - To download the rfc822 mesages in the message. - -##### [boolean] header - To download the message header. - -```cpp -esp_mail_imap_download_config_t download; -``` - - - -#### [Properties] The config about the storage and path to save the downloaded file. - -This property has the sub properties - -##### [const char*] saved_path - The path to save the downloaded file. - -##### [esp_mail_file_storage_type] type - The type of file storages enumeration e.g. - -esp_mail_file_storage_type_none = 0, - -esp_mail_file_storage_type_flash = 1, and - -esp_mail_file_storage_type_sd = 2 - -```cpp -esp_mail_imap_storage_config_t storage; -``` - - -#### [Properties] The config about firmware updates and downloads for ESP32, ESP8266 and Raspberry Pi Pico. - -This property has the sub properties - -##### [string] attach_filename - Update firmware using message attachments if one of its filename matches. - -##### [bool] save_to_file - Save firmware file option. - -```cpp -esp_mail_imap_firmware_config_t firmware_update; -``` - - - -## esp_mail_smtp_embed_message_body_t structured data - - -The following properties are available from the IMAP_Data data type. - -This data type is used for storing the IMAP transport and operating options to -control and store the operation result e.g. the messahe contents from search and fetch. - - - - -##### [Properties] Enable to send this message body as file - -```cpp -bool enable; -``` - - -##### [Properties] The name of embedded file - -```cpp -const char* enable; -``` - - -##### [Properties] The embedded type enumeration - -esp_mail_smtp_embed_message_type_attachment = 0 - -sp_mail_smtp_embed_message_type_inline = 1 - -```cpp -esp_mail_smtp_embed_message_type type; -``` - -## esp_mail_blob_message_content_t structured data - - -The following properties are available from the esp_mail_blob_message_content_t data type. - -This data type is used for storing the blob info of message body. - - - -##### [Properties] The array of content in flash memory. - -```cpp -const uint8_t * data; -``` - - -##### [Properties] The array size in bytes. - -```cpp -size_t size; -``` - - - - - -## esp_mail_file_message_content_t structured data - - -The following properties are available from the esp_mail_file_message_content_t data type. - -This data type is used for storing the file info of message body. - - -##### [Properties] The file path include its name. - -```cpp -const char *name; -``` - - -##### [Properties] The type of file storages. - -```cpp -esp_mail_file_storage_type type; -``` - - - - - -## IMAP_MSG_Item type data - - -The following properties are available from the IMAP_MSG_Item data type. - -This data type is used for message item info and its contents from search and fetch. - - - - -#### [Properties] The message number - -```cpp -int msgNo; -``` - - -#### [Properties] The message UID - -```cpp -int UID; -``` - - -#### [Properties] The message identifier - -```cpp -const char *ID; -``` - - - -#### [Properties] The language(s) for auto-responses - -```cpp -const char *acceptLang; -``` - - - -#### [Properties] The language of message content - -```cpp -const char *contentLang; -``` - - - -#### [Properties] The mailbox of message author - -```cpp -const char *from; -``` - - -#### [Properties] The charset of the mailbox of message author (deprecate) - -```cpp -const char *fromCharset; -``` - - -#### [Properties] The primary recipient mailbox - -```cpp -const char *to; -``` - - -#### [Properties] The charset of the primary recipient mailbox (deprecate) - -```cpp -const char *toCharset; -``` - - -#### [Properties] The Carbon-copy recipient mailboxes - -```cpp -const char *cc; -``` - - -#### [Properties] The charset of the Carbon-copy recipient mailbox header (deprecate) - -```cpp -const char *ccCharset; -``` - -#### [Properties] The message date and time - -```cpp -const char *date; -``` - -#### [Properties] The topic of message - -```cpp -const char *subject; -``` - -#### [Properties] The topic of message charset (deprecate) - -```cpp -const char *subjectCharset; -``` - -#### [Properties] The PLAIN text content of the message - -```cpp -esp_mail_plain_body_t text; -``` - -#### [Properties] The HTML content of the message - -```cpp -esp_mail_html_body_t html; -``` - -#### [Properties] The sender Email - -```cpp -const char *sender; -``` - - -#### [Properties] The charset of the sender Email (obsoleted) - -```cpp -const char *senderCharset; -``` - - -#### [Properties] The keywords or phrases, separated by commas - -```cpp -const char *keyword; -``` - -#### [Properties] The comments about message - -```cpp -const char *comments; -``` - - -#### [Properties] The return recipient of the message - -```cpp -const char *return_path; -``` - - -#### [Properties] The Email address to reply - -```cpp -const char *reply_to; -``` - - -#### [Properties] The field that contains the parent's message ID of the message to which this one is a reply - -```cpp -const char *in_reply_to; -``` - - -#### [Properties] The field that contains the parent's references (if any) and followed by the parent's message ID (if any) of the message to which this one is a reply - -```cpp -const char *references; -``` - - -#### [Properties] The Blind carbon-copy recipients - -```cpp -const char *bcc; -``` - -#### [Properties] The charset of the Blind carbon-copy recipient mailbox header (obsoleted) - -```cpp -const char *bccCharset; -``` - - -#### [Properties] The error description from fetching the message - -```cpp -const char *fetchError; -``` - - -#### [Properties] The info about the attachments in the message - -```cpp -std::vector attachments; -``` - -#### [Properties] The info about the rfc822 messages included in the message - -```cpp -std::vector rfc822; -``` - - - - -## IMAP_Response type data - -The following properties are available from the IMAP_Response data type. - -This data type obtains the response from sending custom IMAP commands. - - -#### [Properties] The status tag - -```cpp -MB_String tag; -``` - -#### [Properties] The status text - -```cpp -MB_String text; -``` - - -#### [Properties] The completion of response - -```cpp -bool completed; -``` - - - - - - -## MIME_Data_Stream_Info type data - -The following properties are available from the MIME_Data_Stream_Info data type. - -This data type obtains the IMAP multipart body or MIME stream data via the callback function. - - -#### [Properties] The message UID - -```cpp -uint32_t uid; -``` - -#### [Properties] The content type of the message part - -```cpp -const char *type; -``` - -#### [Properties] The content disposition of the message part - -```cpp -const char *disposition; -``` - - -#### [Properties] The content character set of the message part - -```cpp -const char *charSet; -``` - - -#### [Properties] The text content flowed format parameter of the message part - -```cpp -bool flowed; -``` - - -#### [Properties] The text content format DelSp parameter of the message part - -```cpp -bool delsp; -``` - - -#### [Properties] The content transfer encoding of the message part - -```cpp -const char *transfer_encoding; -``` - - -#### [Properties] The content ID of the inline attachment type message part - -```cpp -const char *cid; -``` - - -#### [Properties] The content description of the message part - -```cpp -const char *description; -``` - -#### [Properties] The file name of the attachment type message part - -```cpp -const char *filename; -``` - - -#### [Properties] The name of the attachment type message part - -```cpp -const char *name; -``` - - -#### [Properties] The creation date of the message part - -```cpp -const char *date; -``` - -#### [Properties] The size of the attachment (unencoded) type message part - -```cpp -size_t size; -``` - - -#### [Properties] The total octet of the message part - -```cpp -size_t octet_size; -``` - -#### [Properties] The current octet count of the message part that currently parses - -```cpp -int octet_count; -``` - -#### [Properties] The size of content (unencoded) of message part - -```cpp -size_t data_size; -``` - - -#### [Properties] The data buffer of message part that currently parses - -```cpp -void *data; -``` - - -#### [Properties] The flag that states the first chunk data of message part that currently parses - -```cpp -bool isFirstData; -``` - -#### [Properties] The flag that states the final chunk data of message part that currently parses - -```cpp -bool isLastData; -``` - - - - -## IMAP_Decoding_Info type data - -The following properties are available from the IMAP_Decoding_Info data type. - -This data type obtains the IMAP header and text (plain and html) strings to be decoded via the callback function based on its character set. - - -#### [Properties] The character set of the string to decode - -```cpp -const char *charset; -``` - -#### [Properties] The string to decode - -```cpp -const char *data; -``` - - -#### [Properties] The type of data that currently processed - -0 or IMAP_Decoding_Info::message_part_type_header - -1 or IMAP_Decoding_Info::message_part_type_text - -```cpp -message_part_type type; -``` - - - - - -## Search Criteria - -Search crieria is used for searching the mailbox for messages that match -the given searching criteria. - -Searching criteria consist of one or more search keys. When multiple keys are -specified, the result is the intersection (AND function) of all the messages -that match those keys. - -Example: - - **`DELETED FROM "SMITH" SINCE 1-Feb-1994`** refers -to all deleted messages from Smith that were placed in the mailbox since -February 1, 1994. - -A search key can also be a parenthesized list of one or more search keys -(e.g., for use with the OR and NOT keys). - -**`SINCE 10-Feb-2019`** will search all messages that received since 10 Feb 2019 - -**`UID SEARCH ALL`** will seach all message which will return the message UID -that can be use later for fetch one or more messages. - - -The following keywords can be used for the search criteria. - - -**ALL** - All messages in the mailbox; the default initial key for ANDing. - -**ANSWERED** - Messages with the \Answered flag set. - -**BCC** - Messages that contain the specified string in the envelope structure's BCC field. - -**BEFORE** - Messages whose internal date (disregarding time and timezone) is earlier than the specified date. - -**BODY** - Messages that contain the specified string in the body of the message. - -**CC** - Messages that contain the specified string in the envelope structure's CC field. - -**DELETED** - Messages with the \Deleted flag set. - -**DRAFT** - Messages with the \Draft flag set. - -**FLAGGED** - Messages with the \Flagged flag set. - -**FROM** - Messages that contain the specified string in the envelope structure's FROM field. - -**HEADER** - Messages that have a header with the specified field-name (as defined in [RFC-2822]) - -and that contains the specified string in the text of the header (what comes after the colon). - -If the string to search is zero-length, this matches all messages that have a header line with - -the specified field-name regardless of the contents. - -**KEYWORD** - Messages with the specified keyword flag set. - -**LARGER** - Messages with an (RFC-2822) size larger than the specified number of octets. - -**NEW** - Messages that have the \Recent flag set but not the \Seen flag. - -This is functionally equivalent to **"(RECENT UNSEEN)"**. - -**NOT** - Messages that do not match the specified search key. - -**OLD** - Messages that do not have the \Recent flag set. This is functionally equivalent to - -**"NOT RECENT"** (as opposed to **"NOT NEW"**). - -**ON** - Messages whose internal date (disregarding time and timezone) is within the specified date. - -**OR** - Messages that match either search key. - -**RECENT** - Messages that have the \Recent flag set. - -**SEEN** - Messages that have the \Seen flag set. - -**SENTBEFORE** - Messages whose (RFC-2822) Date: header (disregarding time and timezone) is earlier than the specified date. - -**SENTON** - Messages whose (RFC-2822) Date: header (disregarding time and timezone) is within the specified date. - -**SENTSINCE** - Messages whose (RFC-2822) Date: header (disregarding time and timezone) is within or later than the specified date. - -**SINCE** - Messages whose internal date (disregarding time and timezone) is within or later than the specified date. - -**SMALLER** - Messages with an (RFC-2822) size smaller than the specified number of octets. - -**SUBJECT** - Messages that contain the specified string in the envelope structure's SUBJECT field. - -**TEXT** - Messages that contain the specified string in the header or body of the message. - -**TO** - Messages that contain the specified string in the envelope structure's TO field. - -**UID** - Messages with unique identifiers corresponding to the specified unique identifier set. - -Sequence set ranges are permitted. - -**UNANSWERED** - Messages that do not have the \Answered flag set. - -**UNDELETED** - Messages that do not have the \Deleted flag set. - -**UNDRAFT** - Messages that do not have the \Draft flag set. - -**UNFLAGGED** - Messages that do not have the \Flagged flag set. - -**UNKEYWORD** - Messages that do not have the specified keyword flag set. - -**UNSEEN** - Messages that do not have the \Seen flag set. - - - - - - - - - -## MailClient.Time functions - - -The helper function to set and get the system time. - - - - - -#### Set the system time from the NTP server. - -param **`gmtOffset`** The GMT time offset in hour. - -param **`daylightOffset`** The Daylight time offset in hour. - -return **`boolean`** The status indicates the success of operation. - -This requires internet connection - -```cpp -bool setClock(float gmtOffset, float daylightOffset); -``` - - - - - -#### Get the timestamp from the year, month, date, hour, minute, and second provided. - -param **`year`** The year. - -param **`mon`** The months from 1 to 12. - -param **`date`** The dates. - -param **`hour`** The hours. - -param **`mins`** The minutes. - -param **`sec`** The seconds. - -return **`time_t`** The value of timestamp. - -```cpp -time_t getTimestamp(int year, int mon, int date, int hour, int mins, int sec); -``` - - - - -#### Get the timestamp from the time string. - -param **`gmt`** Return GMT time. - -return **`timestamp`** of time string. - -```cpp -time_t getTimestamp(const char* timeString, bool gmt = false); -``` - - - - - - -#### Get the current timestamp. - -return **`uint64_t`** The value of current timestamp. - -```cpp -uint64_t getCurrentTimestamp(); -``` - - - - - - -#### Get the current date time string that valid for Email - -return **`String`** The current date time string. - -```cpp -String getDateTimeString(); -``` - - - - - - -## License - -The MIT License (MIT) - -Copyright (c) 2023 K. Suwatchai (Mobizt) - - -Permission is hereby granted, free of charge, to any person returning 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. - +# ESP Mail Client Arduino Library + + +The description of the available functions in the current reease are shown below. + + +## Global functions + + +#### Sending Email through the SMTP server. + +param **`smtp`** The pointer to SMTP session object which holds the data and the TCP client. + +param **`msg`** The pointer to SMTP_Message class which contains the header, body, and attachments. + +param **`closeSession`** The option to Close the SMTP session after sent. + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp +bool sendMail(SMTPSession *smtp, SMTP_Message *msg, bool closeSession = true); +``` + + + +#### Append message to the mailbox + +param **`imap`** The pointer to IMAP sesssion object which holds the data and the TCP client. + +param **`msg`** The pointer to SMTP_Message class which contains the header, body, and attachments. + +param **`lastAppend`** The last message to append (optional). In case MULTIAPPEND extension + +is supported, set this to false will append messages in single APPEND command. + +param **`flags`** The flags to set to this message. + + param **`dateTime`** The date/time to set to this message (optional). + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp +bool appendMessage(IMAPSession *imap, SMTP_Message *msg, T flags = ""); +``` + + +#### Reading Email through IMAP server. + +param **`imap`** The pointer to IMAP sesssion object which holds the data and the TCP client. + +param **`closeSession`** The option to close the IMAP session after fetching or searching the Email. + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp +bool readMail(IMAPSession *imap, bool closeSession = true); +``` + + + + + +#### Set the argument to the Flags for the specified message. + +param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. + +param **`msgUID`** The UID of the message. + +param **`flags`** The flag list to set. + +param **`closeSession`** The option to close the IMAP session after set flag. + +param **`silent`** The option to ignore the response. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool setFlag(IMAPSession *imap, int msgUID, flags, bool closeSession, bool silent = false, int32_t modsequence = -1); +``` + + + + + +#### Set the argument to the Flags for the specified message. + +param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. + +param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or +message sequence number or ranges of UID or sequence number. + +param **`UID`** The option for sequenceSet whether it is UID or message sequence number. + +param **`flags`** The flag list to set. + +param **`closeSession`** The option to close the IMAP session after set flag. + +param **`silent`** The option to ignore the response. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool setFlag(IMAPSession *imap, sequenceSet, bool UID, flags, bool closeSession, bool silent = false, int32_t modsequence = -1); +``` + + + + + +#### Add the argument to the Flags for the specified message. + +param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. + +param **`msgUID`** The UID of the message. + +param **`flags`** The flag list to add. + +param **`closeSession`** The option to close the IMAP session after add flag. + +param **`silent`** The option to ignore the response. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool addFlag(IMAPSession *imap, int msgUID, flags, bool closeSession, int32_t modsequence = -1); +``` + + + + + +#### Add the argument to the Flags for the specified message. + +param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. + +param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or +message sequence number or ranges of UID or sequence number. + +param **`UID`** The option for sequenceSet whether it is UID or message sequence number. + +param **`flags`** The flag list to add. + +param **`closeSession`** The option to close the IMAP session after set flag. + +param **`silent`** The option to ignore the response. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool addFlag(IMAPSession *imap, sequenceSet, bool UID, flags, bool closeSession, bool silent = false, int32_t modsequence = -1); +``` + + + + + +#### Remove the argument from the Flags for the specified message. + +param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. + +param **`msgUID`** The UID of the message that flags to be removed. + +param **`flags`** The flag list to remove. + +param **`closeSession`** The option to close the IMAP session after remove flag. + +param **`silent`** The option to ignore the response. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool removeFlag(IMAPSession *imap, int msgUID, flags, bool closeSession, int32_t modsequence = -1); +``` + + + + + +#### Remove the argument from the Flags for the specified message. + +param **`imap`** The pointer to IMAP session object which holds the data and the TCP client. + +param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or +message sequence number or ranges of UID or sequence number. + +param **`UID`** The option for sequenceSet whether it is UID or message sequence number. + +param **`flags`** The flag list to remove. + +param **`closeSession`** The option to close the IMAP session after set flag. + +param **`silent`** The option to ignore the response. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool removeFlag(IMAPSession *imap, sequenceSet, bool UID, flags, bool closeSession, bool silent = false, int32_t modsequence = -1); +``` + + + + + + +#### Reconnect WiFi or network if lost connection. + +param **`reconnect`** The boolean to set/unset WiFi AP reconnection. + +```cpp +void networkReconnect(bool reconnect); +``` + + + + +#### Initiate SD card with SPI port configuration. + +param **`ss`** The SPI Chip/Slave Select pin. + +param **`sck`** The SPI Clock pin. + +param **`miso`** The SPI MISO pin. + +param **`mosi`** The SPI MOSI pin. + +aram **`frequency`** The SPI frequency. + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp +bool sdBegin(int8_t ss = -1, int8_t sck = -1, int8_t miso = -1, int8_t mosi = -1, uint32_t frequency = 4000000); +``` + + + + + +#### Initiate SD card with SD FS configurations (ESP8266 only). + +param **`ss`** SPI Chip/Slave Select pin. + +param **`sdFSConfig`** The pointer to SDFSConfig object (ESP8266 only). + +return **`boolean`** type status indicates the success of the operation. + +```cpp + bool sdBegin(SDFSConfig *sdFSConfig); +``` + + + + + +#### Initiate SD card with chip select and SPI configuration (ESP32 only). + +param **`ss`** The SPI Chip/Slave Select pin. + +param **`spiConfig`** The pointer to SPIClass object for SPI configuartion. + +param **`frequency`** The SPI frequency. + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp +bool sdBegin(int8_t ss, SPIClass *spiConfig = nullptr, uint32_t frequency = 4000000); +``` + + + + + +#### Initiate SD card with SdFat SPI and pins configurations (with SdFat included only). + +param **`sdFatSPIConfig`** The pointer to SdSpiConfig object for SdFat SPI configuration. + +param **`ss`** The SPI Chip/Slave Select pin. + +param **`sck`** The SPI Clock pin. + +param **`miso`** The SPI MISO pin. + +param **`mosi`** The SPI MOSI pin. + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp + bool sdBegin(SdSpiConfig *sdFatSPIConfig, int8_t ss = -1, int8_t sck = -1, int8_t miso = -1, int8_t mosi = -1); +``` + + + + + +#### Initiate SD card with SdFat SDIO configuration (with SdFat included only). + +param **`sdFatSDIOConfig`** The pointer to SdioConfig object for SdFat SDIO configuration. + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp + bool sdBegin(SdioConfig *sdFatSDIOConfig); +``` + + + + +#### Initialize the SD_MMC card (ESP32 only). + +param **`mountpoint`** The mounting point. + +param **`mode1bit`** Allow 1 bit data line (SPI mode). + +param **`format_if_mount_failed`** Format SD_MMC card if mount failed. + +return **`Boolean`** type status indicates the success of the operation. + +```cpp +bool sdMMCBegin(const char *mountpoint = "/sdcard", bool mode1bit = false, bool format_if_mount_failed = false); +``` + + + + +#### Get free Heap memory. + +return **`int`** Free memory amount in byte. + +```cpp +int getFreeHeap(); +``` + + + + + +## IMAPSession class functions + + +The following functions are available from the IMAP Session class. + +This class used for controlling IMAP transports and retrieving the data from the IMAP server. + + + + +#### Set the tcp timeout. + +param **`timeoutSec`** The tcp timeout in seconds. + +```cpp +void setTCPTimeout(unsigned long timeoutSec); +``` + + + +#### Assign custom Client from Arduino Clients. + +param **`client`** The pointer to Arduino Client derived class e.g. WiFiClient, WiFiClientSecure, EthernetClient or GSMClient. + +```cpp +void setClient(Client *client); +``` + + +#### Assign TinyGsm Clients. + +param **`client`** The pointer to TinyGsmClient. + +param **`modem`** The pointer to TinyGsm modem object. Modem should be initialized and/or set mode before transfering data. + +param **`pin`** The SIM pin. + +param **`apn`** The GPRS APN (Access Point Name). + +param **`user`** The GPRS user. + +param **`password`** The GPRS password. + +```cpp +void setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password); +``` + + +#### Assign the callback function to handle the network connection for custom Client. + +param **`networkConnectionCB`** The function that handles the network connection. + +```cpp +void networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB); +``` + + + +#### Assign the callback function to handle the network connection status acknowledgement. + +param **`networkStatusCB`** The function that handle the network connection status acknowledgement. + +```cpp +void networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB); +``` + + + +#### Set the network status acknowledgement. + +param **`status`** The network status. + +```cpp +void setNetworkStatus(bool status); +``` + + + +#### Set the BearSSL IO buffer size. + +param **`rx`** The BearSSL receive buffer size in bytes. + +param **`tx`** The BearSSL trasmit buffer size in bytes. + +```cpp +void setSSLBufferSize(int rx = -1, int tx = -1); +``` + + + +#### Set system time with timestamp. + +param **`ts`** timestamp in seconds from midnight Jan 1, 1970. + +param **`gmtOffset`** The GMT offset. + +This function allows the internal time setting by timestamp i.e. timestamp from external RTC. + +```cpp +void setSystemTime(time_t ts, float gmtOffset = 0); +``` + + + +#### Begin the IMAP server connection. + +param **`session_config`** The pointer to Session_Config structured data that keeps the server and log in details. + +param **`imap_data`** The pointer to IMAP_Data structured data that keeps the operation options. + +param **`login`** The bool option for login after server connection. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool connect(Session_Config *session_config, IMAP_Data *imap_data, bool login = true); +``` + + + +#### Login to IMAP server using Email and password. + +param **`email`** The IMAP server account email. + +param **`password`** The IMAP server account password. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bbool loginWithPassword( email, password); +``` + + + +#### Login to IMAP server using Email and access token. + +param **`email`** The IMAP server account email. + +param **`token`** The Access token to log in. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bbool loginWithAccessToken( email, token); +``` + + +#### Send the client identification to the server + +param **`identification`** The pointer to IMAP_Identification structured data that keeps + +the key properties e.g., name, version, os, os_version, vendor, support_url, address, + +date, command, arguments, and environment. + +```cpp +bool id(IMAP_Identification *identification); +``` + + +#### Return the server ID returns from ID command. + +return **`The server ID string.`** + +```cpp +String serverID(); +``` + + +#### Return the SASL authentication status. + +return **`boolean`** The boolean value indicates SASL authentication status. + +```cpp +bool isAuthenticated(); +``` + + +#### Return the log in status. + +return **`boolean`** The boolean value indicates log in status. + +```cpp +bool isLoggedIn(); +``` + + +#### Return firmware update result when attachment filename matches. + +return **`boolean`** The boolean value indicates the firmware update status. + +```cpp +bool isFirmwareUpdateSuccess(); +``` + + +#### Close the IMAP session. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool closeSession(); +``` + + +#### Setup TCP KeepAlive for internal TCP client. + +param **`tcpKeepIdleSeconds`** lwIP TCP Keepalive idle in seconds. + +param **`tcpKeepIntervalSeconds`** lwIP TCP Keepalive interval in seconds. + +param **`tcpKeepCount`** lwIP TCP Keepalive count. + +For the TCP (KeepAlive) options, see [this doc](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/lwip.html#tcp-options). + +If value of one of these parameters is zero, the TCP KeepAlive will be disabled. + +You can check the server connecting status, by exexuting `.connected()` which will return true when connection to the server is still alive. + +```cpp +void keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount); +``` + + + +#### Get TCP KeepAlive status. + +return **`Boolean`** status of TCP Keepalive. + +```cpp +bool isKeepAlive(); +``` + + + +#### Get TCP connection status. + +return **`boolean`** The boolean value indicates the connection status. + +```cpp +bool connected(); +``` + + + + + + +#### Set to enable the debug. + +param **`level`** The level to enable the debug message + +level = 0, no debugging + +level = 1, basic level debugging + +```cpp +void debug(int level); +``` + + + + + +#### Get the list of all the mailbox folders since the TCP session was opened and user was authenticated. + +param **`folders`** The FoldersCollection class that contains the collection of the +FolderInfo structured data. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool getFolders(FoldersCollection &folders); +``` + + + + + +#### Select or open the mailbox folder to search or fetch the message inside. + +param **`folderName`** The known mailbox folder name. The default name is INBOX. + +param **`readOnly`** The option to open the mailbox for read only. Set this option to false when you wish +to modify the Flags using the setFlag, addFlag and removeFlag functions. + +return **`boolean`** The boolean value which indicates the success of operation. + +note: the function will exit immediately and return true if the time since previous success folder selection (open) with the same readOnly mode, is less than 5 seconds. + +```cpp +bool selectFolder( folderName, bool readOnly = true); +``` + + + + + +#### Open the mailbox folder to read or search the mesages. + +param **`folderName`** The name of known mailbox folder to be opened. + +param **`readOnly`** The option to open the mailbox for reading only. Set this option to false when you wish +to modify the flags using the setFlag, addFlag and removeFlag functions. + +return **`boolean`** The boolean value which indicates the success of operation. + +note: the function will exit immediately and return true if the time since previous success folder selection (open) with the same readOnly mode, is less than 5 seconds. + +```cpp +bool openFolder( folderName, bool readOnly = true); +``` + + + + + +#### Close the mailbox folder that was opened. + +param **`expunge`** The option to allow emty the deleted flag set messages in case folder was open with editable mode. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool closeFolder(bool expunge = false); +``` + + + + + + +#### Create folder. + +param **`folderName`** The name of folder to create. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool createFolder( folderName); +``` + + + + + +#### Get subscribes mailboxes. + +param **`reference`** The reference name. + +param **`mailbox`** The mailbox name with possible wildcards. + +param **`folders`** The return FoldersCollection that contains the folder info e.g., name, attribute and delimiter. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool getSubscribesMailboxes( reference, mailbox, FoldersCollection &folders); +``` + + + + +#### Subscribe mailbox. + +param **`folderName`** The name of folder to subscribe. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool subscribe( folderName) +``` + + + + +#### Unsubscribe mailbox. + +param **`folderName`** The name of folder to unsubscribe. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool unSubscribe( folderName) +``` + + + + + +#### Rename folder. + +param **`currentFolderName`** The name of folder to create. + +param **`newFolderName`** The new name of folder to create. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool renameFolder( currentFolderName, newFolderName); +``` + + + +#### Delete folder. + +param **`folderName`** The name of folder to delete.. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool deleteFolder( folderName); +``` + + + + + + +#### Get UID number in selected or opened mailbox. + +param **`msgNum`** The message number or order in the total message numbers. + +return **`boolean`** The boolean value which indicates the success of operation. + +Returns 0 when fail to get UID. + +```cpp +int getUID(int msgNum); +``` + + + + + + + +#### Get message flags in selected or opened mailbox. + +param **`msgNum`** The message number or order in the total message numbers. + +return **`string`** Message flags in selected or opened mailbox. + +empty string when fail to get flags. + +```cpp +const char *getFlags(int msgNum); +``` + + + + + + +#### Send the custom IMAP command and get the result via callback. + +param **`cmd`** The command string. + +param **`callback`** The function that accepts IMAP_Response as parameter. + +param **`tag`** The tag string to pass to the callback function. + +return **`boolean`** The boolean value which indicates the success of operation. + +imap.connect and imap.selectFolder or imap.openFolder are needed to call once prior to call this function. + +```cpp +bool sendCustomCommand( cmd, imapResponseCallback callback, tag); +``` + + + + + +#### Send the custom IMAP command data string. + +param **`data`** The string data. + +param **`lastData`** The flag represents the last data to send (optional). + +return **`boolean`** The boolean value which indicates the success of operation. + +Should be used after calling sendCustomCommand("APPEND xxxxxx"); + +```cpp +bool sendCustomData(T data, bool lastData = false); +``` + + + + + +#### Send the custom IMAP command data. + +param **`data`** The byte data. + +param **`size`** The data size. + +param **`lastData`** The flag represents the last data to send (optional). + +return **`boolean`** The boolean value which indicates the success of operation. + +Should be used after calling ssendCustomCommand("APPEND xxxxxx"); + +```cpp +bool sendCustomData(uint8_t *data, size_t size, bool lastData = false); +``` + + + + +#### Begin the IMAP server connection without authentication. + +param **`session_config`** The pointer to Session_Config structured data that keeps the server and log in details. + +param **`callback`** The callback function that accepts IMAP_Response as parameter. + +param **`tag`** The tag that pass to the callback function. + +return **`The boolean`** value indicates the success of operation. + +```cpp +bool customConnect(Session_Config *session_config, imapResponseCallback callback, tag); +``` + + + + +#### Copy the messages to the defined mailbox folder. + +param **`toCopy`** The pointer to the MessageList class that contains the list of messages to copy. + +param **`dest`** The destination folder that the messages to copy to. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool copyMessages(MessageList *toCopy, dest); +``` + + + + + +#### Copy the messages to the defined mailbox folder. + +param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or +message sequence number or ranges of UID or sequence number. + +param **`UID`** The option for sequenceSet whether it is UID or message sequence number. + +param **`dest`** The destination folder that the messages to copy to. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool copyMessages( sequenceSet, bool UID, dest); +``` + + + + + + +#### Move the messages to the defined mailbox folder. + +param **`toMove`** The pointer to the MessageList class that contains the list of messages to move. + +param **`dest`** The destination folder that the messages to move to. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool moveMessages(MessageList *toMove, dest); +``` + + + + + +#### Move the messages to the defined mailbox folder. + +param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or +message sequence number or ranges of UID or sequence number. + +param **`UID`** The option for sequenceSet whether it is UID or message sequence number. + +param **`dest`** The destination folder that the messages to move to. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool moveMessages( sequenceSet, bool UID, dest); +``` + + + + + + +#### Delete the messages in the opened mailbox folder. + +param **`toDelete`** The pointer to the MessageList class that contains the list of messages to delete. + +param **`expunge`** The boolean option to expunge all messages. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool deleteMessages(MessageList *toDelete, bool expunge = false, int32_t modsequence = -1); +``` + + + + + + +#### Delete the messages in the opened mailbox folder. + +param **`sequenceSet`** The sequence set string i.g., unique identifier (UID) or +message sequence number or ranges of UID or sequence number. + +param **`UID`** The option for sequenceSet whether it is UID or message sequence number. + +param **`expunge`** The boolean option to expunge all messages. + +param **`modsequence`** The int32_t option for UNCHANGESINCE conditional test. + +return **`boolean`** The boolean value indicates the success of operation. + +The modsequence value can be used only if IMAP server supports Conditional STORE extension and the selected mailbox supports modsequences. + +```cpp +bool deleteMessages( sequenceSet, bool UID, bool expunge = false, int32_t modsequence = -1); +``` + + + + + + +#### Get the quota root's resource usage and limits. + +param **`quotaRoot`** The quota root to get. + +param **`info`** The pointer to `IMAP_Quota_Root_Info` that contains quota root's resource name, usage and limit. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool getQuota( quotaRoot, IMAP_Quota_Root_Info *info); +``` + + + + + +#### Set the quota root's resource usage and limits. + +param **`quotaRoot`** The quota root to set. + +param **`data`** The pointer to `IMAP_Quota_Root_Info` that contains quota root's resource name, usage and limit. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool setQuota( quotaRoot, IMAP_Quota_Root_Info *data); +``` + + + + + +#### Get the list of quota roots for the named mailbox. + +param **`mailbox`** The mailbox name. + +param **`quotaRootsList`** The pointer to `IMAP_Quota_Roots_List` that contains the list of `IMAP_Quota_Root_Info`. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool getQuotaRoot( mailbox, IMAP_Quota_Roots_List *quotaRootsList); +``` + + + + + +#### Get the ACLs for a mailbox. + +param **`mailbox`** The mailbox name. + +param **`aclList`** The pointer to the returning `IMAP_Rights_List` object. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool getACL( mailbox, IMAP_Rights_List *aclList); +``` + + + + + + +#### Get the ACLs for a mailbox. + +param **`mailbox`** The mailbox name. + +param **`acl`** The pointer to the acl IMAP_Rights_Info to set. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool setACL( mailbox, IMAP_Rights_Info *acl); +``` + + + + + + +#### Delete the ACLs set for identifier on mailbox. + +param **`mailbox`** The mailbox name. + +param **`identifier`** The identifier (user) to remove the rights. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool deleteACL( mailbox, identifier); +``` + + + + + +#### Show my ACLs for a mailbox. + +param **`mailbox`** The mailbox name. + +param **`acl`** The pointer to the returning `IMAP_Rights_Info` object. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool myRights( mailbox, IMAP_Rights_Info *acl); +``` + + + + + +#### Returns IMAP namespaces. + +param **`mailbox`** The mailbox name. + +param **`ns`** The pointer to the returning `IMAP_Namespaces_List` object. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool getNamespace(IMAP_Namespaces_List *ns); +``` + + + + + + +#### Enable IMAP capability. + +param **`capability`** The mailbox name. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool enable( capability); +``` + + + + + +#### Listen for the selected or open mailbox for updates. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool listen(); +``` + + + + + + +#### Stop listen for the mailbox for updates. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool stopListen(); +``` + + + + + + + +#### Check for the selected or open mailbox updates. + +return **`boolean`** The boolean value which indicates the changes status of mailbox. + +```cpp +bool folderChanged(); +``` + + + + + + +#### Assign the callback function that returns the operating status when fetching or reading the Email. + +param **`imapCallback`** The function that accepts the `imapStatusCallback` as parameter. + +```cpp +void callback(imapStatusCallback imapCallback); +``` + + + + +#### Assign the callback function to decode the string based on the character set. + +param **`callback`** The function that accepts the pointer to `IMAP_Decoding_Info` as parameter. + +```cpp +void characterDecodingCallback(imapCharacterDecodingCallback callback); +``` + + + +#### Assign the callback function that returns the MIME data stream from fetching or reading the Email. + +param **`mimeDataStreamCallback`** The function that accepts the `MIME_Stream_Info` as parameter. + +```cpp +void mimeDataStreamCallback(MIMEDataStreamCallback mimeDataStreamCallback); +``` + + + + + +#### Determine if no message body contained in the search result and only the message header is available. + +```cpp +bool headerOnly(); +``` + + + + + +#### Get the message list from search or fetch the Emails + +return **`The IMAP_MSG_List structured`** data which contains the text and html contents, +attachments, inline images, embedded rfc822 messages details for each message. + +```cpp +IMAP_MSG_List data(); +``` + + + + +#### Get the details of the selected or opned mailbox folder + +return **`The SelectedFolderInfo class`** instance which contains the info about flags, total messages, next UID, +earch count and the available messages count. + +```cpp +SelectedFolderInfo selectedFolder(); +``` + + + + + +#### Get the error details when readingg the Emails. + +return **`String`** The string of error details. + +```cpp +String errorReason(); +``` + + +#### Get the operating status error code. + +return **`int`** The value of operating status error code. + +The negative value indicated error. + +See src/ESP_Mail_Error.h and extras/MB_FS.h + +```cpp +int errorCode(); +``` + + + +#### Clear all the cache data stored in the IMAP session object. + +```cpp +void empty(); +``` + + + +#### Get the status of message fetching and searching. + +return **`IMAP_Status`** The IMAP_Status object contains the fetching and searching statuses. + +```cpp +IMAP_Status status(); +``` + + + +#### Get the JSON string of file name list of files that stored in SD card. + +return **`The JSON string`** of filenames. + +note This will available only when standard SD library was used and file storage is SD. + +```cpp +String fileList(); +``` + + +## SMTPSession class functions + + +The following functions are available from the SMTP Session class. + +This class is similar to the IMAP session class, used for controlling SMTP transports +and retrieving the data from the SMTP server. + + + + +#### Set the tcp timeout. + +param **`timeoutSec`** The tcp timeout in seconds. + +```cpp +void setTCPTimeout(unsigned long timeoutSec); +``` + + + +#### Assign custom Client from Arduino Clients. + +param **`client`** The pointer to Arduino Client derived class e.g. WiFiClient, WiFiClientSecure, EthernetClient or GSMClient. + +```cpp +void setClient(Client *client); +``` + + +#### Assign TinyGsm Clients. + +param **`client`** The pointer to TinyGsmClient. + +param **`modem`** The pointer to TinyGsm modem object. Modem should be initialized and/or set mode before transfering data. + +param **`pin`** The SIM pin. + +param **`apn`** The GPRS APN (Access Point Name). + +param **`user`** The GPRS user. + +param **`password`** The GPRS password. + +```cpp +void setGSMClient(Client *client, void *modem, const char *pin, const char *apn, const char *user, const char *password); +``` + + + +#### Assign the callback function to handle the network connection for custom Client. + +param **`networkConnectionCB`** The function that handles the network connection. + +```cpp +void networkConnectionRequestCallback(NetworkConnectionRequestCallback networkConnectionCB); +``` + + +#### Assign the callback function to handle the network connection status acknowledgement. + +param **`networkStatusCB`** The function that handle the network connection status acknowledgement. + +```cpp +void networkStatusRequestCallback(NetworkStatusRequestCallback networkStatusCB); +``` + + + +#### Set the network status acknowledgement. + +param **`status`** The network status. + +```cpp +void setNetworkStatus(bool status); +``` + + + +#### Set the BearSSL IO buffer size. + +param **`rx`** The BearSSL receive buffer size in bytes. + +param **`tx`** The BearSSL trasmit buffer size in bytes. + +```cpp +void setSSLBufferSize(int rx = -1, int tx = -1); +``` + + + +#### Set system time with timestamp. + +param **`ts`** timestamp in seconds from midnight Jan 1, 1970. + +param **`gmtOffset`** The GMT offset. + +This function allows the internal time setting by timestamp i.e. timestamp from external RTC. + +```cpp +void setSystemTime(time_t ts, float gmtOffset = 0); +``` + + + +#### Begin the SMTP server connection. + +param **`session_config`** The pointer to Session_Config structured data that keeps the server and log in details. + +param **`login`** The bool option for login after server connection. + +return **`boolean`** The boolean value indicates the success of operation. + +```cpp +bool connect(Session_Config *session_config, bool login = true); +``` + + + +#### Login to SMTP server using Email and password. + +param **`email`** The SMTP server account email. + +param **`password`** The SMTP server account password. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool loginWithPassword( email, password); +``` + + + +#### Login to SMTP server using Email and access token. + +param **`email`** The SMTP server account email. + +param **`token`** The Access token to log in. + +return **`boolean`** The boolean value which indicates the success of operation. + +```cpp +bool loginWithAccessToken( email, token); +``` + + +#### Return the SASL authentication status. + +return **`boolean`** The boolean value indicates SASL authentication status. + +```cpp +bool isAuthenticated(); +``` + + + +#### Return the log in status. + +return **`boolean`** The boolean value indicates log in status. + +```cpp +bool isLoggedIn(); +``` + + +#### Close the SMTP session. + +```cpp +bool closeSession(); +``` + + + +#### Setup TCP KeepAlive for internal TCP client. + +param **`tcpKeepIdleSeconds`** lwIP TCP Keepalive idle in seconds. + +param **`tcpKeepIntervalSeconds`** lwIP TCP Keepalive interval in seconds. + +param **`tcpKeepCount`** lwIP TCP Keepalive count. + +For the TCP (KeepAlive) options, see [this doc](https://docs.espressif.com/projects/esp-idf/en/latest/esp32/api-guides/lwip.html#tcp-options). + +If value of one of these parameters is zero, the TCP KeepAlive will be disabled. + +You can check the server connecting status, by exexuting `.connected()` which will return true when connection to the server is still alive. + +```cpp +void keepAlive(int tcpKeepIdleSeconds, int tcpKeepIntervalSeconds, int tcpKeepCount); +``` + + + +#### Get TCP KeepAlive status. + +return **`Boolean`** status of TCP Keepalive. + +```cpp +bool isKeepAlive(); +``` + + + +#### Get TCP connection status. + +return **`boolean`** The boolean value indicates the connection status. + +```cpp +bool connected(); +``` + + + + +#### Begin the SMTP server connection without authentication. + +param **`session_config`** The pointer to Session_Config structured data that keeps the server and log in details. + +param **`callback`** The callback function that accepts the SMTP_Response as parameter. + +param **`commandID`** The command identifier number that will pass to the callback. + +return **`The int`** value of response code. + +If commandID was not set or set to -1, the command identifier will be auto increased started from zero. + +```cpp +int customConnect(Session_Config *session_config, smtpResponseCallback callback, int commandID = -1); +``` + + + + + + +#### Send the custom SMTP command and get the result via callback. + +param **`cmd`** The command string. + +param **`callback`** The function that accepts the SMTP_Response as parameter. + +return **`boolean`** The boolean value which indicates the success of operation. + +smtp.connect or smtp.customConnect is needed to call once prior to call this function. + +```cpp +bool sendCustomCommand( cmd, smtpResponseCallback callback); +``` + + + + + +#### Send the custom SMTP command data string. + +param **`data`** The string data. + +return **`The boolean`** value which indicates the success of operation. + +Should be used after calling sendCustomCommand("DATA"); + +```cpp +bool sendCustomData( data); +``` + + + + +#### Send the custom SMTP command data. + +param **`data`** The byte data. + +param **`size`** The data size. + +return **`The boolean`** value which indicates the success of operation. + +Should be used after calling sendCustomCommand("DATA"); + +```cpp +bool sendCustomData(uint8_t *data, size_t size); +``` + + + + + +#### Set to enable the debug. + +param **`level`** The level to enable the debug message + +level = 0, no debugging + +level = 1, basic level debugging + +```cpp +void debug(int level); +``` + + + + + +#### Get the error details when sending the Email + +return **`String`** The string of error details. + +```cpp +String errorReason(); +``` + + +#### Get the operating status error code. + +return **`int`** The value of operating status error code. + +The negative value indicated error. + +See src/ESP_Mail_Error.h and extras/MB_FS.h + +```cpp +int errorCode(); +``` + + + +#### Get the SMTP server response status code. + +return **`int`** The value of SMTP server response status code. + +See RFC 5321 standard's documentation. + +```cpp +int statusCode(); +``` + + + +#### Get the SMTP server response status message. + +return **`String`** The value of SMTP server response status message. + +```cpp +String statusMessage(); +``` + + + +#### Set the Email sending status callback function. + +param **`smtpCallback`** The callback function that accept the `smtpStatusCallback` param. + +```cpp +void callback(smtpStatusCallback smtpCallback); +``` + + +#### Get the status of message fetching and searching. + +return **`SMTP_Status`** The SMTP_Status object contains the sending status. + +```cpp +SMTP_Status status(); +``` + +## SMTP_Message class functions + + +The following functions are available from the SMTP Message class. + +This class is used for storing the message data including headers, body and attachments +which will be processed with the SMTP session class. + + + + +#### To reset the SMTP_Attachment item data + +param **`att`** The SMTP_Attachment class that stores the info about attachment + +This function was used for clear the internal data of attachment item to be ready for reuse. + +```cpp +void resetAttachItem(SMTP_Attachment &att); +``` + + + +#### To clear all data in SMTP_Message class included headers, bodies and attachments + +```cpp +void clear(); +``` + + + + +#### To clear all the inline images in SMTP_Message class. + +```cpp +void clearInlineimages(); +``` + + + + + +#### To clear all the attachments. + +```cpp +void clearAttachments(); +``` + + + + + +#### To clear all rfc822 message attachment. + +```cpp +void clearRFC822Messages(); +``` + + + + + +#### To clear the primary recipient mailboxes. + +```cpp +void clearRecipients(); +``` + + + + + +#### To clear the Carbon-copy recipient mailboxes. + +```cpp +void clearCc(); +``` + + + + + +#### To clear the Blind-carbon-copy recipient mailboxes. + +```cpp +void clearBcc(); +``` + + +#### To clear the custom message headers. + +```cpp +void clearHeader(); +``` + + + + +#### To add attachment to the message. + +param **`att`** The SMTP_Attachment data item + +```cpp +void addAttachment(SMTP_Attachment &att); +``` + + + + + +#### To add parallel attachment to the message. + +param **`att`** The SMTP_Attachment data item + +```cpp +void addParallelAttachment(SMTP_Attachment &att); +``` + + + + + +#### To add inline image to the message. + +param **`att`** The SMTP_Attachment data item + +```cpp +void addInlineImage(SMTP_Attachment &att); +``` + + + + + +#### To add rfc822 message to the message. + +param **`msg`** The RFC822_Message class object + +```cpp +void addMessage(SMTP_Message &msg); +``` + + + + + +#### To add the primary recipient mailbox to the message. + +param **`name`** The name of primary recipient + +param **`email`** The Email address of primary recipient + +```cpp +void addRecipient( name, email); +``` + + + + + +#### To add Carbon-copy recipient mailbox. + +param **`email`** The Email address of secondary recipient + +```cpp +void addCc( email); +``` + + + + + +#### To add Blind-carbon-copy recipient mailbox. + +param **`email`** The Email address of the tertiary recipient + +```cpp +void addBcc( email); +``` + + + + + +#### To add the custom header to the message. + +param **`hdr`** The header name and value + +```cpp +void addHeader( hdr); +``` + + + + +##### [properties] The message author config + +This property has the sub properties + +###### [const char*] name - The sender name. + +###### [const char*] email - The sender Email address. + +```cpp +esp_mail_email_info_t sender; +``` + + +##### [properties] The topic of message + +```cpp +const char *subject; +``` + + +##### [properties] The message type + +```cpp +byte type; +``` + + +##### [properties] The PLAIN text message + +This property has the sub properties + +###### [esp_mail_smtp_embed_message_body_t] embed - The option to embed this message content as a file. + +###### [const char*] content - The PLAIN text content of the message. + +###### [esp_mail_blob_message_content_t] blob - The blob that contins PLAIN text content of the message. + +###### [esp_mail_file_message_content_t] file - The file that contins PLAIN text content of the message. + +###### [const char*] charSet - The character transcoding of the PLAIN text content of the message. + +###### [const char*] content_type - The content type of message. + +###### [const char*] transfer_encoding - The option to encode the content for data transfer. + +###### [boolean] flowed - The option to send the PLAIN text with wrapping. + +```cpp +esp_mail_plain_body_t text; +``` + + +##### [properties] The HTML text message + +This propery has the sub properties + +###### [const char*] content - The HTML content of the message. + +###### [esp_mail_blob_message_content_t] blob - The blob that contins HTML content of the message. + +###### [esp_mail_file_message_content_t] file - The file that contins HTML content of the message. + +###### [const char*] charSet - The character transcoding of the HTML content of the message. + +###### [const char*] content_type - The content type of message. + +###### [const char*] transfer_encoding - The option to encode the content for data transfer. + +```cpp +esp_mail_html_body_t html; +``` + + +##### [properties] The response config + +This propery has the sub properties + +###### [const char*] reply_to - The author Email address to reply. + +###### [const char*] return_path - The sender Email address to return the message. + +###### [int] notify - The Delivery Status Notifications enumeration e.g. + +esp_mail_smtp_notify_never = 0, + +esp_mail_smtp_notify_success = 1, + +esp_mail_smtp_notify_failure = 2, and + +esp_mail_smtp_notify_delay = 4 + +```cpp +esp_mail_smtp_msg_response_t response; +``` + + +##### [properties] The priority of the message + +This property has the enumeration values + +esp_mail_smtp_priority_high = 1, + +esp_mail_smtp_priority_normal = 3, + +esp_mail_smtp_priority_low = 5 + +```cpp +esp_mail_smtp_priority priority; +``` + + +##### [properties] The enable options + +This propery has the sub property + +###### [boolean] chunking - enable chunk data sending for large message. + +```cpp +esp_mail_smtp_enable_option_t enable; +``` + + +##### [properties] The message from config + +This property has the sub properties + +###### [const char*] name - The messsage author name. + +###### [const char*] email - The message author Email address. + +```cpp +esp_mail_email_info_t from; +``` + + +##### [properties] The message identifier + +```cpp +const char *ID; +``` + +##### [properties] The keywords or phrases, separated by commas + +```cpp +const char *keywords; +``` + + +##### [properties] The comments about message + +```cpp +const char *comments; +``` + + +##### [properties] The date of message + +```cpp +const char *date; +``` + + +##### [properties] The return recipient of the message + +```cpp +const char *return_path; +``` + + + +##### [properties] The field that contains the parent's message ID of the message to which this one is a reply + +```cpp +const char *in_reply_to; +``` + + + +##### [properties] The field that contains the parent's references (if any) and followed by the parent's message ID (if any) of the message to which this one is a reply + +```cpp +const char *references; +``` + + +## IMAP_Status class functions + + +The following functions are available from the IMAP Status class. + +This class is used as the callback parameter for retrieving the status while reading the Email. + + + + +#### Get the information of each process in the reading operation. + +return **`string`** The info for each process + +```cpp +const char *info(); +``` + + + + +#### Get the status of completion. + +return **`boolean`** The bool value indicates that all reading processes are finished + +```cpp +bool success(); +``` + + + + + +#### To clear all data store in this class. + +```cpp +void empty(); +``` + + + + + + +## SMTP_Status class functions + + +The following functions are available from the SMTP Status class. + +This class is used as the callback parameter for retrieving the status while sending the Email. + + + + +#### Get the information of each process in the sending operation. + +return **`string`** The info for each process + +```cpp +const char *info(); +``` + + + + +#### Get the status of completion. + +return **`boolean`** The bool value indicates that all sending processes are finished + +```cpp +bool success(); +``` + + + + + +#### To clear all data store in this class. + +```cpp +void empty(); +``` + + + + +#### Get the number of complete sending message. + +return **`number`** The number of message that was sent + +```cpp +size_t completedCount(); +``` + + + + + +#### Get the number of failed sending message. + +return **`number`** The number of message that was not sent + +```cpp +size_t failedCount(); +``` + + + + +## SendingResult class functions + + +The following functions are available from the SendingResult class. + +This class is used for retrieving the info about the result of sending the messages. + + + + +#### Get the information of a message sending status. + +param **`index`** The index number of a message sending status + +return **`SMTP_Result`** The SMTP_Result type data that provides these properties + +##### [bool] completed - The status of the message + +#### [MB_String] recipients - The primary recipient mailbox of the message + +#### [MB_String] subject - The topic of the message + +#### [time_t] timesstamp - The timestamp of the message + +```cpp +SMTP_Result getItem(size_t index); +``` + + + + + +#### Get the amount of the result data. + +return **`number`** The number of result item + +```cpp +size_t size(); +``` + + + + +## SMTP_Response type data + +The following properties are available from the SMTP_Response data type. + +This data type obtains the response from sending custom SMTP commands. + + +#### [Properties] The command identifier + +```cpp +int id; +``` + +#### [Properties] The response text + +```cpp +MB_String text; +``` + + +#### [Properties] The response code + +```cpp +int respCode; +``` + + + + +## FoldersCollection class functions + + +The following functions are available from the FoldersCollection class. + +This class is used for retrieving the info about the mailbox folders which available to read or serach +in the user Email mailbox. + + + + +#### Get the information of a folder in a folder collection. + +param **`index`** The index number of folders + +return **`esp_mail_folder_info_item_t`** The esp_mail_folder_info_item_t structured data that provides these properties + +#### [MB_String] name - The name of folder + +#### [MB_String] attributes - The attributes of folder + +#### [MB_String] delimiter - The delimeter of folder + +```cpp +esp_mail_folder_info_item_t info(size_t index); +``` + + + + + +#### Get the number of folders in the collection. + +return **`number`** The number of folder in the collection + +```cpp +size_t size(); +``` + + + + + + +## SelectedFolderInfo class functions + + +The following functions are available from the SelectedFolderInfo class. + +This class is used for retrieving the info about the sselected or opened mailbox folder. + + + + +#### Get the numbers of flags in the user Email mailbox. + +return **`number`** The numbers of flags + +```cpp +size_t flagCount(); +``` + + + + + +#### Get the numbers of messages in this mailbox. + +return **`number`** The numbers of messages in the selected mailbox folder + +```cpp +size_t msgCount(); +``` + + + + + + +#### Get the numbers of messages in this mailbox that recent flag was set. + +return **`number`** The numbers of messages in the selected mailbox folder that recent flag was set + +```cpp +size_t recentCount(); +``` + + + + + + +#### Get the order of message in number of message in this mailbox that reoved. + +return **`IMAP_Polling_Status`** The data that holds the polling status. + +The IMAP_Polling_Status has the properties e.g. type, messageNum, and argument. + +The type property is the type of status e.g.imap_polling_status_type_undefined, imap_polling_status_type_new_message, +imap_polling_status_type_remove_message, and imap_polling_status_type_fetch_message. + +The messageNum property is message number or order from the total number of message that added, fetched or deleted. + +The argument property is the argument of commands e.g. FETCH + +```cpp +struct IMAP_Polling_Status pollingStatus(); +``` + + + + + + + + +#### Get the predicted next message UID in the sselected folder. + +return **`number`** The number represents the next message UID number + +```cpp +size_t nextUID(); +``` + + + + + + + +#### Get the numbers of messages from search result based on the search criteria. + +return **`number`** The total number of messsages from search + +```cpp +size_t searchCount(); +``` + + + + + +#### Get the numbers of messages to be stored in the ressult. + +return **`number`** The number of messsage stored from search + +```cpp +size_t availableMessages(); +``` + + + + + +#### Get the flag argument at the specified index. + +return **`index`** The index of flag in the flags list + +return **`String`** The argument of selected flag + +```cpp +String flag(size_t index); +``` + + + + +## Session_Config type data + + +The following properties are available from the Session_Config data type. + +This data type is used for storing the session info about the server and login credentials. + + +#### [Properties] The server config + +This property has the sub properties + +##### [MB_String] host_name - The hostName of the server. + +##### [uint16_t] port - The port on the server to connect to. + +```cpp +esp_mail_sesson_sever_config_t server; +``` + + +#### [Properties] The log in config + +This property has the sub properties + +##### [MB_String] email - The user Email address to log in. + +##### [consst char *] password - The user password to log in. + +##### [consst char *] accessToken - The OAuth2.0 access token to log in. + +##### [consst char *] user_domain - The host name or public IP of client system. + +```cpp +esp_mail_sesson_login_config_t login; +``` + + +#### [Properties] The secure config + +This property has the sub properties + +##### [bool] startTLS - The option to send the command to start the TLS connection. + +```cpp +esp_mail_sesson_secure_config_t secure; +``` + + +#### [Properties] The ports and protocols config + +This property has the sub properties + +##### [port_function *] list - The list (aray) of port_function. + +##### [size_t] size - The size of array. + +```cpp +esp_mail_ports_functions ports_functions; +``` + + + + +#### [Properties] The certificate config + +##### [const char *] cert_data - The certificate data (base64 data). + +##### [const char *] cert_file - The certificate file (DER format). + +##### [esp_mail_file_storage_type] cert_file_storage_type - The storage type. + +##### [bool] verify - The cerificate verification option. + +```cpp +esp_mail_sesson_cert_config_t certificate; +``` + + + +#### [Properties] SPI Ethernet Module config for ESP8266 + +##### [ENC28J60lwIP *] enc28j60 - The ENC28J60 Ethernet module lwip interfac. + +##### [Wiznet5100lwIP *] w5100 - The W5100 Ethernet module lwip interfac. + +##### [Wiznet5500lwIP *] w5500 - The W5500 Ethernet module lwip interfac. + +```cpp +esp_mail_spi_ethernet_module_t spi_ethernet_module; +``` + + + +#### [Properties] The callback function for WiFi connection + +```cpp +NetworkConnectionHandler network_connection_handler; +``` + + + + +## port_function type data + +#### [Properties] The port number + +```cpp +uint16_t port; +``` + +#### [Properties] The protocol + +The port protocol e.g. esp_mail_protocol_plain_text, esp_mail_protocol_ssl and esp_mail_protocol_tls. + +```cpp +esp_mail_protocol protocol; +``` + + + + +## IMAP_Data type data + + +The following properties are available from the IMAP_Data data type. + +This data type is used for storing the IMAP transport and operating options to +control and store the operation result e.g. the messahe contents from search and fetch. + + + + +#### [Properties] The config for fetching + +This property has the sub properties + +##### [MB_String] uid - The UID of message to fetch. + +##### [MB_String] number - The message sequence number to fetch. + +##### [esp_mail_imap_sequence_set_t] sequence_set - The sequence set options. + +##### [MB_String] set_seen - Set the message flag as seen. + +```cpp +esp_mail_imap_fetch_config_t fetch; +``` + + +#### [Properties] The config for IMAP sequence set fetching + +This property has the sub properties + +##### [MB_String] string - The sequence set string i.g., unique identifier (UID) +or message sequence number or ranges of UID or sequence number. + +##### [bool] UID - The option for sequenceSet whether it is UID or message sequence number. + +##### [bool] headerOnly - The option for header only fetching. + +```cpp +esp_mail_imap_sequence_set_t fetch; +``` + + +#### [Properties] The config for search + +This property has the sub properties + +##### [MB_String] criteria - The search criteria. + +##### [boolean] unseen_msg - The option to search the unseen message. + +```cpp +esp_mail_imap_search_config_t search; +``` + + +#### [Properties] The config about the limits + +This property has the sub properties + +##### [size_t] search - The maximum messages from the search result. + +##### [size_t] fetch - The maximum messages from the sequence set fetching result. + +##### [size_t] msg_size - The maximum size of the memory buffer to store the message content. + +This is only limit for data to be stored in the IMAPSession. + +##### [size_t] attachment_size - The maximum size of each attachment to download. + +The IMAP idle (polling) timeout in ms (1 min to 29 min). Default is 10 min. + +##### [size_t] imap_idle_timeout - The IMAP idle timeout in ms. + +The IMAP idle (polling) host check interval in ms (30 sec to imap_idle_timeout) +for internet availability checking to ensure the connection is active. + +Default is 1 min. + +##### [size_t] imap_idle_host_check_interval - The IMAP idle host check interval in ms. + + +```cpp +esp_mail_imap_limit_config_t limit; +``` + + + +#### [Properties] The config to enable the features + +This property has the sub properties + +##### [boolean] text - To store the PLAIN text of the message in the IMAPSession. + +##### [boolean] html - To store the HTML of the message in the IMAPSession. + +##### [boolean] rfc822 - To store the rfc822 messages in the IMAPSession. + +##### [boolean] download_status - To enable the download status via the serial port. + +##### [boolean] recent_sort - To sort the message UID of the search result in descending order. + +##### [boolean] header_case_sesitive - To allow case sesitive in header parsing. + +```cpp +esp_mail_imap_enable_config_t enable; +``` + + + +#### [Properties] The config about downloads + +This property has the sub properties + +##### [boolean] text - To download the PLAIN text content of the message. + +##### [boolean] html - To download the HTML content of the message. + +##### [boolean] attachment - To download the attachments of the message. + +##### [boolean] inlineImg - To download the inline image of the message. + +##### [boolean] rfc822 - To download the rfc822 mesages in the message. + +##### [boolean] header - To download the message header. + +```cpp +esp_mail_imap_download_config_t download; +``` + + + +#### [Properties] The config about the storage and path to save the downloaded file. + +This property has the sub properties + +##### [const char*] saved_path - The path to save the downloaded file. + +##### [esp_mail_file_storage_type] type - The type of file storages enumeration e.g. + +esp_mail_file_storage_type_none = 0, + +esp_mail_file_storage_type_flash = 1, and + +esp_mail_file_storage_type_sd = 2 + +```cpp +esp_mail_imap_storage_config_t storage; +``` + + +#### [Properties] The config about firmware updates and downloads for ESP32, ESP8266 and Raspberry Pi Pico. + +This property has the sub properties + +##### [string] attach_filename - Update firmware using message attachments if one of its filename matches. + +##### [bool] save_to_file - Save firmware file option. + +```cpp +esp_mail_imap_firmware_config_t firmware_update; +``` + + + +## esp_mail_smtp_embed_message_body_t structured data + + +The following properties are available from the IMAP_Data data type. + +This data type is used for storing the IMAP transport and operating options to +control and store the operation result e.g. the messahe contents from search and fetch. + + + + +##### [Properties] Enable to send this message body as file + +```cpp +bool enable; +``` + + +##### [Properties] The name of embedded file + +```cpp +const char* enable; +``` + + +##### [Properties] The embedded type enumeration + +esp_mail_smtp_embed_message_type_attachment = 0 + +sp_mail_smtp_embed_message_type_inline = 1 + +```cpp +esp_mail_smtp_embed_message_type type; +``` + +## esp_mail_blob_message_content_t structured data + + +The following properties are available from the esp_mail_blob_message_content_t data type. + +This data type is used for storing the blob info of message body. + + + +##### [Properties] The array of content in flash memory. + +```cpp +const uint8_t * data; +``` + + +##### [Properties] The array size in bytes. + +```cpp +size_t size; +``` + + + + + +## esp_mail_file_message_content_t structured data + + +The following properties are available from the esp_mail_file_message_content_t data type. + +This data type is used for storing the file info of message body. + + +##### [Properties] The file path include its name. + +```cpp +const char *name; +``` + + +##### [Properties] The type of file storages. + +```cpp +esp_mail_file_storage_type type; +``` + + + + + +## IMAP_MSG_Item type data + + +The following properties are available from the IMAP_MSG_Item data type. + +This data type is used for message item info and its contents from search and fetch. + + + + +#### [Properties] The message number + +```cpp +int msgNo; +``` + + +#### [Properties] The message UID + +```cpp +int UID; +``` + + +#### [Properties] The message identifier + +```cpp +const char *ID; +``` + + + +#### [Properties] The language(s) for auto-responses + +```cpp +const char *acceptLang; +``` + + + +#### [Properties] The language of message content + +```cpp +const char *contentLang; +``` + + + +#### [Properties] The mailbox of message author + +```cpp +const char *from; +``` + + +#### [Properties] The charset of the mailbox of message author (deprecate) + +```cpp +const char *fromCharset; +``` + + +#### [Properties] The primary recipient mailbox + +```cpp +const char *to; +``` + + +#### [Properties] The charset of the primary recipient mailbox (deprecate) + +```cpp +const char *toCharset; +``` + + +#### [Properties] The Carbon-copy recipient mailboxes + +```cpp +const char *cc; +``` + + +#### [Properties] The charset of the Carbon-copy recipient mailbox header (deprecate) + +```cpp +const char *ccCharset; +``` + +#### [Properties] The message date and time + +```cpp +const char *date; +``` + +#### [Properties] The topic of message + +```cpp +const char *subject; +``` + +#### [Properties] The topic of message charset (deprecate) + +```cpp +const char *subjectCharset; +``` + +#### [Properties] The PLAIN text content of the message + +```cpp +esp_mail_plain_body_t text; +``` + +#### [Properties] The HTML content of the message + +```cpp +esp_mail_html_body_t html; +``` + +#### [Properties] The sender Email + +```cpp +const char *sender; +``` + + +#### [Properties] The charset of the sender Email (obsoleted) + +```cpp +const char *senderCharset; +``` + + +#### [Properties] The keywords or phrases, separated by commas + +```cpp +const char *keyword; +``` + +#### [Properties] The comments about message + +```cpp +const char *comments; +``` + + +#### [Properties] The return recipient of the message + +```cpp +const char *return_path; +``` + + +#### [Properties] The Email address to reply + +```cpp +const char *reply_to; +``` + + +#### [Properties] The field that contains the parent's message ID of the message to which this one is a reply + +```cpp +const char *in_reply_to; +``` + + +#### [Properties] The field that contains the parent's references (if any) and followed by the parent's message ID (if any) of the message to which this one is a reply + +```cpp +const char *references; +``` + + +#### [Properties] The Blind carbon-copy recipients + +```cpp +const char *bcc; +``` + +#### [Properties] The charset of the Blind carbon-copy recipient mailbox header (obsoleted) + +```cpp +const char *bccCharset; +``` + + +#### [Properties] The error description from fetching the message + +```cpp +const char *fetchError; +``` + + +#### [Properties] The info about the attachments in the message + +```cpp +std::vector attachments; +``` + +#### [Properties] The info about the rfc822 messages included in the message + +```cpp +std::vector rfc822; +``` + + + + +## IMAP_Response type data + +The following properties are available from the IMAP_Response data type. + +This data type obtains the response from sending custom IMAP commands. + + +#### [Properties] The status tag + +```cpp +MB_String tag; +``` + +#### [Properties] The status text + +```cpp +MB_String text; +``` + + +#### [Properties] The completion of response + +```cpp +bool completed; +``` + + + + + + +## MIME_Data_Stream_Info type data + +The following properties are available from the MIME_Data_Stream_Info data type. + +This data type obtains the IMAP multipart body or MIME stream data via the callback function. + + +#### [Properties] The message UID + +```cpp +uint32_t uid; +``` + +#### [Properties] The content type of the message part + +```cpp +const char *type; +``` + +#### [Properties] The content disposition of the message part + +```cpp +const char *disposition; +``` + + +#### [Properties] The content character set of the message part + +```cpp +const char *charSet; +``` + + +#### [Properties] The text content flowed format parameter of the message part + +```cpp +bool flowed; +``` + + +#### [Properties] The text content format DelSp parameter of the message part + +```cpp +bool delsp; +``` + + +#### [Properties] The content transfer encoding of the message part + +```cpp +const char *transfer_encoding; +``` + + +#### [Properties] The content ID of the inline attachment type message part + +```cpp +const char *cid; +``` + + +#### [Properties] The content description of the message part + +```cpp +const char *description; +``` + +#### [Properties] The file name of the attachment type message part + +```cpp +const char *filename; +``` + + +#### [Properties] The name of the attachment type message part + +```cpp +const char *name; +``` + + +#### [Properties] The creation date of the message part + +```cpp +const char *date; +``` + +#### [Properties] The size of the attachment (unencoded) type message part + +```cpp +size_t size; +``` + + +#### [Properties] The total octet of the message part + +```cpp +size_t octet_size; +``` + +#### [Properties] The current octet count of the message part that currently parses + +```cpp +int octet_count; +``` + +#### [Properties] The size of content (unencoded) of message part + +```cpp +size_t data_size; +``` + + +#### [Properties] The data buffer of message part that currently parses + +```cpp +void *data; +``` + + +#### [Properties] The flag that states the first chunk data of message part that currently parses + +```cpp +bool isFirstData; +``` + +#### [Properties] The flag that states the final chunk data of message part that currently parses + +```cpp +bool isLastData; +``` + + + + +## IMAP_Decoding_Info type data + +The following properties are available from the IMAP_Decoding_Info data type. + +This data type obtains the IMAP header and text (plain and html) strings to be decoded via the callback function based on its character set. + + +#### [Properties] The character set of the string to decode + +```cpp +const char *charset; +``` + +#### [Properties] The string to decode + +```cpp +const char *data; +``` + + +#### [Properties] The type of data that currently processed + +0 or IMAP_Decoding_Info::message_part_type_header + +1 or IMAP_Decoding_Info::message_part_type_text + +```cpp +message_part_type type; +``` + + + + + +## Search Criteria + +Search crieria is used for searching the mailbox for messages that match +the given searching criteria. + +Searching criteria consist of one or more search keys. When multiple keys are +specified, the result is the intersection (AND function) of all the messages +that match those keys. + +Example: + + **`DELETED FROM "SMITH" SINCE 1-Feb-1994`** refers +to all deleted messages from Smith that were placed in the mailbox since +February 1, 1994. + +A search key can also be a parenthesized list of one or more search keys +(e.g., for use with the OR and NOT keys). + +**`SINCE 10-Feb-2019`** will search all messages that received since 10 Feb 2019 + +**`UID SEARCH ALL`** will seach all message which will return the message UID +that can be use later for fetch one or more messages. + + +The following keywords can be used for the search criteria. + + +**ALL** - All messages in the mailbox; the default initial key for ANDing. + +**ANSWERED** - Messages with the \Answered flag set. + +**BCC** - Messages that contain the specified string in the envelope structure's BCC field. + +**BEFORE** - Messages whose internal date (disregarding time and timezone) is earlier than the specified date. + +**BODY** - Messages that contain the specified string in the body of the message. + +**CC** - Messages that contain the specified string in the envelope structure's CC field. + +**DELETED** - Messages with the \Deleted flag set. + +**DRAFT** - Messages with the \Draft flag set. + +**FLAGGED** - Messages with the \Flagged flag set. + +**FROM** - Messages that contain the specified string in the envelope structure's FROM field. + +**HEADER** - Messages that have a header with the specified field-name (as defined in [RFC-2822]) + +and that contains the specified string in the text of the header (what comes after the colon). + +If the string to search is zero-length, this matches all messages that have a header line with + +the specified field-name regardless of the contents. + +**KEYWORD** - Messages with the specified keyword flag set. + +**LARGER** - Messages with an (RFC-2822) size larger than the specified number of octets. + +**NEW** - Messages that have the \Recent flag set but not the \Seen flag. + +This is functionally equivalent to **"(RECENT UNSEEN)"**. + +**NOT** - Messages that do not match the specified search key. + +**OLD** - Messages that do not have the \Recent flag set. This is functionally equivalent to + +**"NOT RECENT"** (as opposed to **"NOT NEW"**). + +**ON** - Messages whose internal date (disregarding time and timezone) is within the specified date. + +**OR** - Messages that match either search key. + +**RECENT** - Messages that have the \Recent flag set. + +**SEEN** - Messages that have the \Seen flag set. + +**SENTBEFORE** - Messages whose (RFC-2822) Date: header (disregarding time and timezone) is earlier than the specified date. + +**SENTON** - Messages whose (RFC-2822) Date: header (disregarding time and timezone) is within the specified date. + +**SENTSINCE** - Messages whose (RFC-2822) Date: header (disregarding time and timezone) is within or later than the specified date. + +**SINCE** - Messages whose internal date (disregarding time and timezone) is within or later than the specified date. + +**SMALLER** - Messages with an (RFC-2822) size smaller than the specified number of octets. + +**SUBJECT** - Messages that contain the specified string in the envelope structure's SUBJECT field. + +**TEXT** - Messages that contain the specified string in the header or body of the message. + +**TO** - Messages that contain the specified string in the envelope structure's TO field. + +**UID** - Messages with unique identifiers corresponding to the specified unique identifier set. + +Sequence set ranges are permitted. + +**UNANSWERED** - Messages that do not have the \Answered flag set. + +**UNDELETED** - Messages that do not have the \Deleted flag set. + +**UNDRAFT** - Messages that do not have the \Draft flag set. + +**UNFLAGGED** - Messages that do not have the \Flagged flag set. + +**UNKEYWORD** - Messages that do not have the specified keyword flag set. + +**UNSEEN** - Messages that do not have the \Seen flag set. + + + + + + + + + +## MailClient.Time functions + + +The helper function to set and get the system time. + + + + + +#### Set the system time from the NTP server. + +param **`gmtOffset`** The GMT time offset in hour. + +param **`daylightOffset`** The Daylight time offset in hour. + +return **`boolean`** The status indicates the success of operation. + +This requires internet connection + +```cpp +bool setClock(float gmtOffset, float daylightOffset); +``` + + + + + +#### Get the timestamp from the year, month, date, hour, minute, and second provided. + +param **`year`** The year. + +param **`mon`** The months from 1 to 12. + +param **`date`** The dates. + +param **`hour`** The hours. + +param **`mins`** The minutes. + +param **`sec`** The seconds. + +return **`time_t`** The value of timestamp. + +```cpp +time_t getTimestamp(int year, int mon, int date, int hour, int mins, int sec); +``` + + + + +#### Get the timestamp from the time string. + +param **`gmt`** Return GMT time. + +return **`timestamp`** of time string. + +```cpp +time_t getTimestamp(const char* timeString, bool gmt = false); +``` + + + + + + +#### Get the current timestamp. + +return **`uint64_t`** The value of current timestamp. + +```cpp +uint64_t getCurrentTimestamp(); +``` + + + + + + +#### Get the current date time string that valid for Email + +return **`String`** The current date time string. + +```cpp +String getDateTimeString(); +``` + + + + + + +## License + +The MIT License (MIT) + +Copyright (c) 2023 K. Suwatchai (Mobizt) + + +Permission is hereby granted, free of charge, to any person returning 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/lib/libesp32/ESP-Mail-Client/src/SSLClient/Custom_ESP_SSLClient_FS.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/Custom_ESP_SSLClient_FS.h index 1f28bdb0c..c9687adf8 100644 --- a/lib/libesp32/ESP-Mail-Client/src/SSLClient/Custom_ESP_SSLClient_FS.h +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/Custom_ESP_SSLClient_FS.h @@ -1,23 +1,23 @@ - -#ifndef CUSTOM_ESP_SSLCLIENT_FS_H -#define CUSTOM_ESP_SSLCLIENT_FS_H - -#include "../ESP_Mail_FS.h" - -#if defined(ESP_MAIL_DISABLE_SSL) -#undef USE_LIB_SSL_ENGINE -#undef USE_EMBED_SSL_ENGINE -#endif - -#if defined(ESP_MAIL_USE_PSRAM) -#if !defined(ESP_SSLCLIENT_USE_PSRAM) -#define ESP_SSLCLIENT_USE_PSRAM -#endif -#else -#undef ESP_SSLCLIENT_USE_PSRAM -#endif - -#undef ESP_SSLCLIENT_ENABLE_DEBUG -#undef ESP_SSLCLIENT_ENABLE_SSL_ERROR_STRING - -#endif + +#ifndef CUSTOM_ESP_SSLCLIENT_FS_H +#define CUSTOM_ESP_SSLCLIENT_FS_H + +#include "../ESP_Mail_FS.h" + +#if defined(ESP_MAIL_DISABLE_SSL) +#undef USE_LIB_SSL_ENGINE +#undef USE_EMBED_SSL_ENGINE +#endif + +#if defined(ESP_MAIL_USE_PSRAM) +#if !defined(ESP_SSLCLIENT_USE_PSRAM) +#define ESP_SSLCLIENT_USE_PSRAM +#endif +#else +#undef ESP_SSLCLIENT_USE_PSRAM +#endif + +#undef ESP_SSLCLIENT_ENABLE_DEBUG +#undef ESP_SSLCLIENT_ENABLE_SSL_ERROR_STRING + +#endif diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient.h index a77b08080..a32f27004 100644 --- a/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient.h +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient.h @@ -1,79 +1,79 @@ -/** - * - * The ESP SSL Client Class, ESP_SSLClient.h v2.1.6 - * - * Created August 27, 2023 - * - * The MIT License (MIT) - * Copyright (c) 2023 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person returning 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 ESP_SSLCLIENT_H -#define ESP_SSLCLIENT_H - -#include "ESP_SSLClient_FS.h" - -#ifndef SSLCLIENT_CONNECTION_UPGRADABLE -#define SSLCLIENT_CONNECTION_UPGRADABLE -#endif -#include "ESP_SSLClient_Const.h" -#if defined(USE_EMBED_SSL_ENGINE) || defined(USE_LIB_SSL_ENGINE) -#include "client/BSSL_TCP_Client.h" -class ESP_SSLClient : public BSSL_TCP_Client -{ -public: - ESP_SSLClient(){}; - ~ESP_SSLClient(){}; -}; - -class ESP_SSLClient2 : public BSSL_TCP_Client -{ -public: - ESP_SSLClient2(Client &client, bool enableSSL = true) : _base_client(client) - { - setClient(&_base_client, enableSSL); - }; - ~ESP_SSLClient2(){}; - -private: - Client &_base_client; -}; - -#else -class ESP_SSLClient -{ -public: - ESP_SSLClient(){}; - ~ESP_SSLClient(){}; -}; - -class ESP_SSLClient2 -{ -public: - ESP_SSLClient2(Client &client, bool enableSSL = true) : _base_client(client){}; - ~ESP_SSLClient2(){}; - -private: - Client &_base_client; -}; -#endif - -#endif +/** + * + * The ESP SSL Client Class, ESP_SSLClient.h v2.1.6 + * + * Created August 27, 2023 + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person returning 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 ESP_SSLCLIENT_H +#define ESP_SSLCLIENT_H + +#include "ESP_SSLClient_FS.h" + +#ifndef SSLCLIENT_CONNECTION_UPGRADABLE +#define SSLCLIENT_CONNECTION_UPGRADABLE +#endif +#include "ESP_SSLClient_Const.h" +#if defined(USE_EMBED_SSL_ENGINE) || defined(USE_LIB_SSL_ENGINE) +#include "client/BSSL_TCP_Client.h" +class ESP_SSLClient : public BSSL_TCP_Client +{ +public: + ESP_SSLClient(){}; + ~ESP_SSLClient(){}; +}; + +class ESP_SSLClient2 : public BSSL_TCP_Client +{ +public: + ESP_SSLClient2(Client &client, bool enableSSL = true) : _base_client(client) + { + setClient(&_base_client, enableSSL); + }; + ~ESP_SSLClient2(){}; + +private: + Client &_base_client; +}; + +#else +class ESP_SSLClient +{ +public: + ESP_SSLClient(){}; + ~ESP_SSLClient(){}; +}; + +class ESP_SSLClient2 +{ +public: + ESP_SSLClient2(Client &client, bool enableSSL = true) : _base_client(client){}; + ~ESP_SSLClient2(){}; + +private: + Client &_base_client; +}; +#endif + +#endif diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient_Const.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient_Const.h index 290e702ba..a2eecc128 100644 --- a/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient_Const.h +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/ESP_SSLClient_Const.h @@ -1,138 +1,138 @@ -#ifndef ESP_SSLCLIENT_CONST_H -#define ESP_SSLCLIENT_CONST_H - -#pragma GCC diagnostic ignored "-Wunused-function" -#pragma GCC diagnostic ignored "-Wvla" - -#include "ESP_SSLClient_FS.h" - -#include -#include - -#if defined(__AVR__) -#undef USE_LIB_SSL_ENGINE -#undef USE_EMBED_SSL_ENGINE -#error "Not support AVR architecture" -#endif - -#define ESP_SSLCLIENT_VALID_TIMESTAMP 1690979919 - -#ifndef SSLCLIENT_CONNECTION_UPGRADABLE -#define SSLCLIENT_CONNECTION_UPGRADABLE -#endif - -#ifdef ESP_SSLCLIENT_ENABLE_DEBUG -#if !defined(ESP_SSLCLIENT_DEBUG_PORT) -#define ESP_SSLCLIENT_DEBUG_PORT Serial -#endif -#define ESP_SSLCLIENT_DEBUG_PRINT ESP_SSLCLIENT_DEBUG_PORT.print -#else -#define ESP_SSLCLIENT_DEBUG_PRINT(...) -#endif - -#if !defined(FPSTR) -#define FPSTR -#endif - -#if defined(USE_EMBED_SSL_ENGINE) || defined(USE_LIB_SSL_ENGINE) - -enum esp_ssl_client_debug_level -{ - esp_ssl_debug_none = 0, - esp_ssl_debug_error = 1, - esp_ssl_debug_warn = 2, - esp_ssl_debug_info = 3, - esp_ssl_debug_dump = 4 -}; - -enum esp_ssl_client_error_types -{ - esp_ssl_ok, - esp_ssl_connection_fail, - esp_ssl_write_error, - esp_ssl_read_error, - esp_ssl_out_of_memory, - esp_ssl_internal_error -}; - -#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) - -static void esp_ssl_debug_print_prefix(const char *func_name, int level) -{ - ESP_SSLCLIENT_DEBUG_PRINT(PSTR("> ")); - // print the debug level - switch (level) - { - case esp_ssl_debug_info: - ESP_SSLCLIENT_DEBUG_PRINT(PSTR("INFO.")); - break; - case esp_ssl_debug_warn: - ESP_SSLCLIENT_DEBUG_PRINT(PSTR("WARN.")); - break; - case esp_ssl_debug_error: - ESP_SSLCLIENT_DEBUG_PRINT(PSTR("ERROR.")); - break; - default: - break; - } - - // print the function name - ESP_SSLCLIENT_DEBUG_PRINT(PSTR("")); - ESP_SSLCLIENT_DEBUG_PRINT(func_name); - ESP_SSLCLIENT_DEBUG_PRINT(PSTR(": ")); -} - -static void esp_ssl_debug_print(PGM_P msg, int debug_level, int level, const char *func_name) -{ - if (debug_level >= level) - { - esp_ssl_debug_print_prefix(func_name, level); - ESP_SSLCLIENT_DEBUG_PRINT(msg); - ESP_SSLCLIENT_DEBUG_PRINT("\r\n"); - } -} - -#endif - -static uint8_t htoi(unsigned char c) -{ - if (c >= '0' && c <= '9') - return c - '0'; - else if (c >= 'A' && c <= 'F') - return 10 + c - 'A'; - else if (c >= 'a' && c <= 'f') - return 10 + c - 'a'; - else - return 255; -} - -// Helper function which aborts a TLS handshake by sending TLS -// ClientAbort and ClientClose messages. -static bool send_abort(Client *probe, bool supportsLen) -{ - // If we're still connected, send the appropriate notice that - // we're aborting the handshake per RFCs. - static const uint8_t clientAbort_P[] PROGMEM = { - 0x15 /*alert*/, 0x03, 0x03 /*TLS 1.2*/, 0x00, 0x02, - 1, 90 /* warning: user_cancelled */ - }; - static const uint8_t clientClose_P[] PROGMEM = { - 0x15 /*alert*/, 0x03, 0x03 /*TLS 1.2*/, 0x00, 0x02, - 1, 0 /* warning: close_notify */ - }; - if (probe->connected()) - { - uint8_t msg[sizeof(clientAbort_P)]; - memcpy_P(msg, clientAbort_P, sizeof(clientAbort_P)); - probe->write(msg, sizeof(clientAbort_P)); - memcpy_P(msg, clientClose_P, sizeof(clientClose_P)); - probe->write(msg, sizeof(clientClose_P)); - } - return supportsLen; -} - -const uint16_t _secure_ports[26] = {443 /* HTTPS */, 465 /* SMTP */, 563 /* NNTP */, 636 /* LDAPS */, 695 /* IEEE-MMS-SSL */, 832 /* NETCONF */, 853 /* DNS */, 989 /* FTPS */, 990 /* FTPS */, 992 /* Telnet */, 993 /* IMAP */, 995 /* POP3 */, 4116 /* Smartcard */, 4843 /* OPC */, 5061 /* SIP */, 5085 /* LLIP */, 5349 /* NAT */, 5671 /* AMQP */, 5986 /* WinRM-HTTPS */, 6513 /* NETCONF */, 6514 /* Syslog */, 6515 /* Elipse RPC */, 6619 /* OFTP */, 8243 /* Apache Synapse */, 8403 /* GxFWD */, 8883 /* MQTT */}; - -#endif - +#ifndef ESP_SSLCLIENT_CONST_H +#define ESP_SSLCLIENT_CONST_H + +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wvla" + +#include "ESP_SSLClient_FS.h" + +#include +#include + +#if defined(__AVR__) +#undef USE_LIB_SSL_ENGINE +#undef USE_EMBED_SSL_ENGINE +#error "Not support AVR architecture" +#endif + +#define ESP_SSLCLIENT_VALID_TIMESTAMP 1690979919 + +#ifndef SSLCLIENT_CONNECTION_UPGRADABLE +#define SSLCLIENT_CONNECTION_UPGRADABLE +#endif + +#ifdef ESP_SSLCLIENT_ENABLE_DEBUG +#if !defined(ESP_SSLCLIENT_DEBUG_PORT) +#define ESP_SSLCLIENT_DEBUG_PORT Serial +#endif +#define ESP_SSLCLIENT_DEBUG_PRINT ESP_SSLCLIENT_DEBUG_PORT.print +#else +#define ESP_SSLCLIENT_DEBUG_PRINT(...) +#endif + +#if !defined(FPSTR) +#define FPSTR +#endif + +#if defined(USE_EMBED_SSL_ENGINE) || defined(USE_LIB_SSL_ENGINE) + +enum esp_ssl_client_debug_level +{ + esp_ssl_debug_none = 0, + esp_ssl_debug_error = 1, + esp_ssl_debug_warn = 2, + esp_ssl_debug_info = 3, + esp_ssl_debug_dump = 4 +}; + +enum esp_ssl_client_error_types +{ + esp_ssl_ok, + esp_ssl_connection_fail, + esp_ssl_write_error, + esp_ssl_read_error, + esp_ssl_out_of_memory, + esp_ssl_internal_error +}; + +#if defined(ESP_SSLCLIENT_ENABLE_DEBUG) + +static void esp_ssl_debug_print_prefix(const char *func_name, int level) +{ + ESP_SSLCLIENT_DEBUG_PRINT(PSTR("> ")); + // print the debug level + switch (level) + { + case esp_ssl_debug_info: + ESP_SSLCLIENT_DEBUG_PRINT(PSTR("INFO.")); + break; + case esp_ssl_debug_warn: + ESP_SSLCLIENT_DEBUG_PRINT(PSTR("WARN.")); + break; + case esp_ssl_debug_error: + ESP_SSLCLIENT_DEBUG_PRINT(PSTR("ERROR.")); + break; + default: + break; + } + + // print the function name + ESP_SSLCLIENT_DEBUG_PRINT(PSTR("")); + ESP_SSLCLIENT_DEBUG_PRINT(func_name); + ESP_SSLCLIENT_DEBUG_PRINT(PSTR(": ")); +} + +static void esp_ssl_debug_print(PGM_P msg, int debug_level, int level, const char *func_name) +{ + if (debug_level >= level) + { + esp_ssl_debug_print_prefix(func_name, level); + ESP_SSLCLIENT_DEBUG_PRINT(msg); + ESP_SSLCLIENT_DEBUG_PRINT("\r\n"); + } +} + +#endif + +static uint8_t htoi(unsigned char c) +{ + if (c >= '0' && c <= '9') + return c - '0'; + else if (c >= 'A' && c <= 'F') + return 10 + c - 'A'; + else if (c >= 'a' && c <= 'f') + return 10 + c - 'a'; + else + return 255; +} + +// Helper function which aborts a TLS handshake by sending TLS +// ClientAbort and ClientClose messages. +static bool send_abort(Client *probe, bool supportsLen) +{ + // If we're still connected, send the appropriate notice that + // we're aborting the handshake per RFCs. + static const uint8_t clientAbort_P[] PROGMEM = { + 0x15 /*alert*/, 0x03, 0x03 /*TLS 1.2*/, 0x00, 0x02, + 1, 90 /* warning: user_cancelled */ + }; + static const uint8_t clientClose_P[] PROGMEM = { + 0x15 /*alert*/, 0x03, 0x03 /*TLS 1.2*/, 0x00, 0x02, + 1, 0 /* warning: close_notify */ + }; + if (probe->connected()) + { + uint8_t msg[sizeof(clientAbort_P)]; + memcpy_P(msg, clientAbort_P, sizeof(clientAbort_P)); + probe->write(msg, sizeof(clientAbort_P)); + memcpy_P(msg, clientClose_P, sizeof(clientClose_P)); + probe->write(msg, sizeof(clientClose_P)); + } + return supportsLen; +} + +const uint16_t _secure_ports[26] = {443 /* HTTPS */, 465 /* SMTP */, 563 /* NNTP */, 636 /* LDAPS */, 695 /* IEEE-MMS-SSL */, 832 /* NETCONF */, 853 /* DNS */, 989 /* FTPS */, 990 /* FTPS */, 992 /* Telnet */, 993 /* IMAP */, 995 /* POP3 */, 4116 /* Smartcard */, 4843 /* OPC */, 5061 /* SIP */, 5085 /* LLIP */, 5349 /* NAT */, 5671 /* AMQP */, 5986 /* WinRM-HTTPS */, 6513 /* NETCONF */, 6514 /* Syslog */, 6515 /* Elipse RPC */, 6619 /* OFTP */, 8243 /* Apache Synapse */, 8403 /* GxFWD */, 8883 /* MQTT */}; + +#endif + #endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_Helper.cpp b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_Helper.cpp index 3d4d62684..dae864105 100644 --- a/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_Helper.cpp +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_Helper.cpp @@ -1,1053 +1,1053 @@ -/* - WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries - - Mostly compatible with Arduino WiFi shield library and standard - WiFiClient/ServerSecure (except for certificate handling). - - Copyright (c) 2018 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 -*/ -#ifndef BSSL_HELPER_CPP -#define BSSL_HELPER_CPP - -#pragma GCC diagnostic ignored "-Wunused-function" -#pragma GCC diagnostic ignored "-Wvla" - -#include -#include "../ESP_SSLClient_FS.h" -#include "../ESP_SSLClient_Const.h" -#if defined(USE_LIB_SSL_ENGINE) - -#include "BSSL_Helper.h" -#include -#include -#include "../bssl/bearssl.h" -#include -#include -#if defined __has_include -#if __has_include() -#include -#endif -#endif - -namespace key_bssl -{ - // Code here is pulled from brssl sources, with the copyright and license - // shown below. I've rewritten things using C++ semantics and removed - // custom VEC_* calls (std::vector to the rescue) and adjusted things to - // allow for long-running operation (i.e. some memory issues when DERs - // passed into the decoders). Bugs are most likely my fault. - - // Original (c) message follows: - /* - Copyright (c) 2016 Thomas Pornin - - 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. - */ - - class private_key - { - public: - int key_type; /* BR_KEYTYPE_RSA or BR_KEYTYPE_EC */ - union - { - br_rsa_private_key rsa; - br_ec_private_key ec; - } key; - }; - - class public_key - { - public: - int key_type; /* BR_KEYTYPE_RSA or BR_KEYTYPE_EC */ - union - { - br_rsa_public_key rsa; - br_ec_public_key ec; - } key; - }; - - class pem_object - { - public: - char *name; - unsigned char *data; - size_t data_len; - }; - - // Forward definitions - void free_ta_contents(br_x509_trust_anchor *ta); - void free_public_key(public_key *pk); - void free_private_key(private_key *sk); - bool looks_like_DER(const unsigned char *buf, size_t len); - pem_object *decode_pem(const void *src, size_t len, size_t *num); - void free_pem_object_contents(pem_object *po); - char *strdupImpl(const char *s); - - // Used as callback multiple places to append a string to a vector - static void byte_vector_append(void *ctx, const void *buff, size_t len) - { - std::vector *vec = static_cast *>(ctx); - vec->reserve(vec->size() + len); // Allocate extra space all at once - for (size_t i = 0; i < len; i++) - { - vec->push_back(((uint8_t *)buff)[i]); - } - } - - static bool certificate_to_trust_anchor_inner(br_x509_trust_anchor *ta, const br_x509_certificate *xc) - { - std::unique_ptr dc(new br_x509_decoder_context_libmail); // auto-delete on exit - std::vector vdn; - br_x509_pkey *pk; - - // Clear everything in the Trust Anchor - memset(ta, 0, sizeof(*ta)); - - br_x509_decoder_init_libmail(dc.get(), byte_vector_append, (void *)&vdn); - br_x509_decoder_push_libmail(dc.get(), xc->data, xc->data_len); - pk = br_x509_decoder_get_pkey(dc.get()); - if (pk == nullptr) - { - return false; // No key present, something broken in the cert! - } - - // Copy the raw certificate data - ta->dn.data = (uint8_t *)malloc(vdn.size()); - if (!ta->dn.data) - { - return false; // OOM, but nothing yet allocated - } - memcpy(ta->dn.data, &vdn[0], vdn.size()); - ta->dn.len = vdn.size(); - ta->flags = 0; - if (br_x509_decoder_isCA(dc.get())) - { - ta->flags |= BR_X509_TA_CA; - } - - // Extract the public key - switch (pk->key_type) - { - case BR_KEYTYPE_RSA: - ta->pkey.key_type = BR_KEYTYPE_RSA; - ta->pkey.key.rsa.n = (uint8_t *)malloc(pk->key.rsa.nlen); - ta->pkey.key.rsa.e = (uint8_t *)malloc(pk->key.rsa.elen); - if ((ta->pkey.key.rsa.n == nullptr) || (ta->pkey.key.rsa.e == nullptr)) - { - free_ta_contents(ta); // OOM, so clean up - return false; - } - memcpy(ta->pkey.key.rsa.n, pk->key.rsa.n, pk->key.rsa.nlen); - ta->pkey.key.rsa.nlen = pk->key.rsa.nlen; - memcpy(ta->pkey.key.rsa.e, pk->key.rsa.e, pk->key.rsa.elen); - ta->pkey.key.rsa.elen = pk->key.rsa.elen; - return true; - case BR_KEYTYPE_EC: - ta->pkey.key_type = BR_KEYTYPE_EC; - ta->pkey.key.ec.curve = pk->key.ec.curve; - ta->pkey.key.ec.q = (uint8_t *)malloc(pk->key.ec.qlen); - if (ta->pkey.key.ec.q == nullptr) - { - free_ta_contents(ta); // OOM, so clean up - return false; - } - memcpy(ta->pkey.key.ec.q, pk->key.ec.q, pk->key.ec.qlen); - ta->pkey.key.ec.qlen = pk->key.ec.qlen; - return true; - default: - free_ta_contents(ta); // Unknown key type - return false; - } - - // Should never get here, if so there was an unknown error - return false; - } - - br_x509_trust_anchor *certificate_to_trust_anchor(const br_x509_certificate *xc) - { - br_x509_trust_anchor *ta = (br_x509_trust_anchor *)malloc(sizeof(br_x509_trust_anchor)); - if (!ta) - { - return nullptr; - } - - if (!certificate_to_trust_anchor_inner(ta, xc)) - { - free(ta); - return nullptr; - } - return ta; - } - - void free_ta_contents(br_x509_trust_anchor *ta) - { - if (ta) - { - free(ta->dn.data); - if (ta->pkey.key_type == BR_KEYTYPE_RSA) - { - free(ta->pkey.key.rsa.n); - free(ta->pkey.key.rsa.e); - } - else if (ta->pkey.key_type == BR_KEYTYPE_EC) - { - free(ta->pkey.key.ec.q); - } - memset(ta, 0, sizeof(*ta)); - } - } - - // Checks if a bitstream looks like a valid DER(binary) encoding. - // Basically tries to verify the length of all included segments - // matches the length of the input buffer. Does not actually - // validate any contents. - bool looks_like_DER(const unsigned char *buff, size_t len) - { - if (len < 2) - { - return false; - } - if (pgm_read_byte(buff++) != 0x30) - { - return false; - } - int fb = pgm_read_byte(buff++); - len -= 2; - if (fb < 0x80) - { - return (size_t)fb == len; - } - else if (fb == 0x80) - { - return false; - } - else - { - fb -= 0x80; - if (len < (size_t)fb + 2) - { - return false; - } - len -= (size_t)fb; - size_t dlen = 0; - while (fb-- > 0) - { - if (dlen > (len >> 8)) - { - return false; - } - dlen = (dlen << 8) + (size_t)pgm_read_byte(buff++); - } - return dlen == len; - } - } - - void free_pem_object_contents(pem_object *po) - { - if (po) - { - free(po->name); - free(po->data); - po->name = nullptr; - po->data = nullptr; - } - } - - char *strdupImpl(const char *s) - { - size_t slen = strlen(s); - char *result = (char *)malloc(slen + 1); - if (!result) - return NULL; - memcpy(result, s, slen + 1); - return result; - } - - // Converts a PEM (~=base64) source into a set of DER-encoded binary blobs. - // Each blob is named by the ---- BEGIN xxx ---- field, and multiple - // blobs may be returned. - pem_object *decode_pem(const void *src, size_t len, size_t *num) - { - std::vector pem_list; - std::unique_ptr pc(new br_pem_decoder_context); // auto-delete on exit - if (!pc.get()) - { - return nullptr; - } - pem_object po, *pos; - const unsigned char *buff; - std::vector bv; - - *num = 0; - br_pem_decoder_init(pc.get()); - buff = (const unsigned char *)src; - po.name = nullptr; - po.data = nullptr; - po.data_len = 0; - bool inobj = false; - bool extra_nl = true; - - while (len > 0) - { - size_t tlen; - - tlen = br_pem_decoder_push(pc.get(), buff, len); - buff += tlen; - len -= tlen; - switch (br_pem_decoder_event(pc.get())) - { - case BR_PEM_BEGIN_OBJ: - po.name = strdupImpl(br_pem_decoder_name(pc.get())); - br_pem_decoder_setdest(pc.get(), byte_vector_append, &bv); - inobj = true; - break; - - case BR_PEM_END_OBJ: - if (inobj) - { - // Stick data into the vector - po.data = (uint8_t *)malloc(bv.size()); - if (po.data) - { - memcpy(po.data, &bv[0], bv.size()); - po.data_len = bv.size(); - pem_list.push_back(po); - } - // Clean up state for next blob processing - bv.clear(); - po.name = nullptr; - po.data = nullptr; - po.data_len = 0; - inobj = false; - } - break; - - case BR_PEM_ERROR: - free(po.name); - for (size_t i = 0; i < pem_list.size(); i++) - { - free_pem_object_contents(&pem_list[i]); - } - return nullptr; - - default: - // Do nothing here, the parser is still working on things - break; - } - - if (len == 0 && extra_nl) - { - extra_nl = false; - buff = (const unsigned char *)"\n"; - len = 1; - } - } - - if (inobj) - { - free(po.name); - for (size_t i = 0; i < pem_list.size(); i++) - { - free_pem_object_contents(&pem_list[i]); - } - return nullptr; - } - - pos = (pem_object *)malloc((1 + pem_list.size()) * sizeof(*pos)); - if (pos) - { - *num = pem_list.size(); - pem_list.push_back(po); // Null-terminate list - memcpy(pos, &pem_list[0], pem_list.size() * sizeof(*pos)); - } - return pos; - } - - // Parse out DER or PEM encoded certificates from a binary buffer, - // potentially stored in PROGMEM. - br_x509_certificate *read_certificates(const char *buff, size_t len, size_t *num) - { - std::vector cert_list; - pem_object *pos; - size_t u, num_pos; - br_x509_certificate *xcs; - br_x509_certificate dummy; - - *num = 0; - - if (looks_like_DER((const unsigned char *)buff, len)) - { - xcs = (br_x509_certificate *)malloc(2 * sizeof(*xcs)); - if (!xcs) - { - return nullptr; - } - xcs[0].data = (uint8_t *)malloc(len); - if (!xcs[0].data) - { - free(xcs); - return nullptr; - } - memcpy_P(xcs[0].data, buff, len); - xcs[0].data_len = len; - xcs[1].data = nullptr; - xcs[1].data_len = 0; - *num = 1; - return xcs; - } - - pos = decode_pem(buff, len, &num_pos); - if (!pos) - { - return nullptr; - } - for (u = 0; u < num_pos; u++) - { - if (!strcmp_P(pos[u].name, PSTR("CERTIFICATE")) || !strcmp_P(pos[u].name, PSTR("X509 CERTIFICATE"))) - { - br_x509_certificate xc; - xc.data = pos[u].data; - xc.data_len = pos[u].data_len; - pos[u].data = nullptr; // Don't free the data we moved to the xc vector! - cert_list.push_back(xc); - } - } - for (u = 0; u < num_pos; u++) - { - free_pem_object_contents(&pos[u]); - } - free(pos); - - if (cert_list.size() == 0) - { - return nullptr; - } - *num = cert_list.size(); - dummy.data = nullptr; - dummy.data_len = 0; - cert_list.push_back(dummy); - xcs = (br_x509_certificate *)malloc(cert_list.size() * sizeof(*xcs)); - if (!xcs) - { - for (size_t i = 0; i < cert_list.size(); i++) - { - free(cert_list[i].data); // Clean up any captured data blobs - } - return nullptr; - } - memcpy(xcs, &cert_list[0], cert_list.size() * sizeof(br_x509_certificate)); - // XCS now has [].data pointing to the previously allocated blobs, so don't - // want to free anything in cert_list[]. - return xcs; - } - - void free_certificates(br_x509_certificate *certs, size_t num) - { - if (certs) - { - for (size_t u = 0; u < num; u++) - { - free(certs[u].data); - } - free(certs); - } - } - - static public_key *decode_public_key(const unsigned char *buff, size_t len) - { - std::unique_ptr dc(new br_pkey_decoder_context); // auto-delete on exit - if (!dc.get()) - { - return nullptr; - } - - public_key *pk = nullptr; - // https://github.com/yglukhov/bearssl_pkey_decoder - br_pkey_decoder_init(dc.get()); - br_pkey_decoder_push(dc.get(), buff, len); - int err = br_pkey_decoder_last_error(dc.get()); - if (err != 0) - { - return nullptr; - } - - const br_rsa_public_key *rk = nullptr; - const br_ec_public_key *ek = nullptr; - switch (br_pkey_decoder_key_type(dc.get())) - { - case BR_KEYTYPE_RSA: - rk = br_pkey_decoder_get_rsa(dc.get()); - pk = (public_key *)malloc(sizeof *pk); - if (!pk) - { - return nullptr; - } - pk->key_type = BR_KEYTYPE_RSA; - pk->key.rsa.n = (uint8_t *)malloc(rk->nlen); - pk->key.rsa.e = (uint8_t *)malloc(rk->elen); - if (!pk->key.rsa.n || !pk->key.rsa.e) - { - free(pk->key.rsa.n); - free(pk->key.rsa.e); - free(pk); - return nullptr; - } - memcpy(pk->key.rsa.n, rk->n, rk->nlen); - pk->key.rsa.nlen = rk->nlen; - memcpy(pk->key.rsa.e, rk->e, rk->elen); - pk->key.rsa.elen = rk->elen; - return pk; - - case BR_KEYTYPE_EC: - ek = br_pkey_decoder_get_ec(dc.get()); - pk = (public_key *)malloc(sizeof *pk); - if (!pk) - { - return nullptr; - } - pk->key_type = BR_KEYTYPE_EC; - pk->key.ec.q = (uint8_t *)malloc(ek->qlen); - if (!pk->key.ec.q) - { - free(pk); - return nullptr; - } - memcpy(pk->key.ec.q, ek->q, ek->qlen); - pk->key.ec.qlen = ek->qlen; - pk->key.ec.curve = ek->curve; - return pk; - - default: - return nullptr; - } - } - - void free_public_key(public_key *pk) - { - if (pk) - { - if (pk->key_type == BR_KEYTYPE_RSA) - { - free(pk->key.rsa.n); - free(pk->key.rsa.e); - } - else if (pk->key_type == BR_KEYTYPE_EC) - { - free(pk->key.ec.q); - } - free(pk); - } - } - - static private_key *decode_private_key(const unsigned char *buff, size_t len) - { - std::unique_ptr dc(new br_skey_decoder_context); // auto-delete on exit - if (!dc.get()) - { - return nullptr; - } - - private_key *sk = nullptr; - - br_skey_decoder_init(dc.get()); - br_skey_decoder_push(dc.get(), buff, len); - int err = br_skey_decoder_last_error(dc.get()); - if (err != 0) - { - return nullptr; - } - - const br_rsa_private_key *rk = nullptr; - const br_ec_private_key *ek = nullptr; - switch (br_skey_decoder_key_type(dc.get())) - { - case BR_KEYTYPE_RSA: - rk = br_skey_decoder_get_rsa(dc.get()); - sk = (private_key *)malloc(sizeof *sk); - if (!sk) - { - return nullptr; - } - sk->key_type = BR_KEYTYPE_RSA; - sk->key.rsa.p = (uint8_t *)malloc(rk->plen); - sk->key.rsa.q = (uint8_t *)malloc(rk->qlen); - sk->key.rsa.dp = (uint8_t *)malloc(rk->dplen); - sk->key.rsa.dq = (uint8_t *)malloc(rk->dqlen); - sk->key.rsa.iq = (uint8_t *)malloc(rk->iqlen); - if (!sk->key.rsa.p || !sk->key.rsa.q || !sk->key.rsa.dp || !sk->key.rsa.dq || !sk->key.rsa.iq) - { - free_private_key(sk); - return nullptr; - } - sk->key.rsa.n_bitlen = rk->n_bitlen; - memcpy(sk->key.rsa.p, rk->p, rk->plen); - sk->key.rsa.plen = rk->plen; - memcpy(sk->key.rsa.q, rk->q, rk->qlen); - sk->key.rsa.qlen = rk->qlen; - memcpy(sk->key.rsa.dp, rk->dp, rk->dplen); - sk->key.rsa.dplen = rk->dplen; - memcpy(sk->key.rsa.dq, rk->dq, rk->dqlen); - sk->key.rsa.dqlen = rk->dqlen; - memcpy(sk->key.rsa.iq, rk->iq, rk->iqlen); - sk->key.rsa.iqlen = rk->iqlen; - return sk; - - case BR_KEYTYPE_EC: - ek = br_skey_decoder_get_ec(dc.get()); - sk = (private_key *)malloc(sizeof *sk); - if (!sk) - { - return nullptr; - } - sk->key_type = BR_KEYTYPE_EC; - sk->key.ec.curve = ek->curve; - sk->key.ec.x = (uint8_t *)malloc(ek->xlen); - if (!sk->key.ec.x) - { - free_private_key(sk); - return nullptr; - } - memcpy(sk->key.ec.x, ek->x, ek->xlen); - sk->key.ec.xlen = ek->xlen; - return sk; - - default: - return nullptr; - } - } - - void free_private_key(private_key *sk) - { - if (sk) - { - switch (sk->key_type) - { - case BR_KEYTYPE_RSA: - free(sk->key.rsa.p); - free(sk->key.rsa.q); - free(sk->key.rsa.dp); - free(sk->key.rsa.dq); - free(sk->key.rsa.iq); - break; - case BR_KEYTYPE_EC: - free(sk->key.ec.x); - break; - default: - // Could be an uninitted key, no sub elements to free - break; - } - free(sk); - } - } - - void free_pem_object(pem_object *pos) - { - if (pos != nullptr) - { - for (size_t u = 0; pos[u].name; u++) - { - free_pem_object_contents(&pos[u]); - } - free(pos); - } - } - - private_key *read_private_key(const char *buff, size_t len) - { - private_key *sk = nullptr; - pem_object *pos = nullptr; - - if (looks_like_DER((const unsigned char *)buff, len)) - { - sk = decode_private_key((const unsigned char *)buff, len); - return sk; - } - - size_t num; - pos = decode_pem(buff, len, &num); - if (pos == nullptr) - { - return nullptr; // PEM decode error - } - for (size_t u = 0; pos[u].name; u++) - { - const char *name = pos[u].name; - if (!strcmp_P(name, PSTR("RSA PRIVATE KEY")) || !strcmp_P(name, PSTR("EC PRIVATE KEY")) || !strcmp_P(name, PSTR("PRIVATE KEY"))) - { - sk = decode_private_key(pos[u].data, pos[u].data_len); - free_pem_object(pos); - return sk; - } - } - // If we hit here, no match - free_pem_object(pos); - return nullptr; - } - - public_key *read_public_key(const char *buff, size_t len) - { - public_key *pk = nullptr; - pem_object *pos = nullptr; - - if (looks_like_DER((const unsigned char *)buff, len)) - { - pk = decode_public_key((const unsigned char *)buff, len); - return pk; - } - size_t num; - pos = decode_pem(buff, len, &num); - if (pos == nullptr) - { - return nullptr; // PEM decode error - } - for (size_t u = 0; pos[u].name; u++) - { - const char *name = pos[u].name; - if (!strcmp_P(name, PSTR("RSA PUBLIC KEY")) || !strcmp_P(name, PSTR("EC PUBLIC KEY")) || !strcmp_P(name, PSTR("PUBLIC KEY"))) - { - pk = decode_public_key(pos[u].data, pos[u].data_len); - free_pem_object(pos); - return pk; - } - } - - // We hit here == no key found - free_pem_object(pos); - return pk; - } - - static uint8_t *loadStream(Stream &stream, size_t size) - { - uint8_t *dest = (uint8_t *)malloc(size); - if (!dest) - { - return nullptr; // OOM error - } - if (size != stream.readBytes(dest, size)) - { - free(dest); // Error during read - return nullptr; - } - return dest; - } -}; - -namespace bssl -{ - - // ----- Public Key ----- - - PublicKey::PublicKey() - { - _key = nullptr; - } - - PublicKey::PublicKey(const char *pemKey) - { - _key = nullptr; - parse(pemKey); - } - - PublicKey::PublicKey(const uint8_t *derKey, size_t derLen) - { - _key = nullptr; - parse(derKey, derLen); - } - - PublicKey::PublicKey(Stream &stream, size_t size) - { - _key = nullptr; - auto buff = key_bssl::loadStream(stream, size); - if (buff) - { - parse(buff, size); - free(buff); - } - } - - PublicKey::~PublicKey() - { - if (_key) - { - key_bssl::free_public_key(_key); - } - } - - bool PublicKey::parse(const char *pemKey) - { - return parse((const uint8_t *)pemKey, strlen_P(pemKey)); - } - - bool PublicKey::parse(const uint8_t *derKey, size_t derLen) - { - if (_key) - { - key_bssl::free_public_key(_key); - _key = nullptr; - } - _key = key_bssl::read_public_key((const char *)derKey, derLen); - return _key ? true : false; - } - - bool PublicKey::isRSA() const - { - if (!_key || _key->key_type != BR_KEYTYPE_RSA) - { - return false; - } - return true; - } - - bool PublicKey::isEC() const - { - if (!_key || _key->key_type != BR_KEYTYPE_EC) - { - return false; - } - return true; - } - - const br_rsa_public_key *PublicKey::getRSA() const - { - if (!_key || _key->key_type != BR_KEYTYPE_RSA) - { - return nullptr; - } - return &_key->key.rsa; - } - - const br_ec_public_key *PublicKey::getEC() const - { - if (!_key || _key->key_type != BR_KEYTYPE_EC) - { - return nullptr; - } - return &_key->key.ec; - } - - // ----- Private Key ----- - - PrivateKey::PrivateKey() - { - _key = nullptr; - } - - PrivateKey::PrivateKey(const char *pemKey) - { - _key = nullptr; - parse(pemKey); - } - - PrivateKey::PrivateKey(const uint8_t *derKey, size_t derLen) - { - _key = nullptr; - parse(derKey, derLen); - } - - PrivateKey::PrivateKey(Stream &stream, size_t size) - { - _key = nullptr; - auto buff = key_bssl::loadStream(stream, size); - if (buff) - { - parse(buff, size); - free(buff); - } - } - - PrivateKey::~PrivateKey() - { - if (_key) - { - key_bssl::free_private_key(_key); - } - } - - bool PrivateKey::parse(const char *pemKey) - { - return parse((const uint8_t *)pemKey, strlen_P(pemKey)); - } - - bool PrivateKey::parse(const uint8_t *derKey, size_t derLen) - { - if (_key) - { - key_bssl::free_private_key(_key); - _key = nullptr; - } - _key = key_bssl::read_private_key((const char *)derKey, derLen); - return _key ? true : false; - } - - bool PrivateKey::isRSA() const - { - if (!_key || _key->key_type != BR_KEYTYPE_RSA) - { - return false; - } - return true; - } - - bool PrivateKey::isEC() const - { - if (!_key || _key->key_type != BR_KEYTYPE_EC) - { - return false; - } - return true; - } - - const br_rsa_private_key *PrivateKey::getRSA() const - { - if (!_key || _key->key_type != BR_KEYTYPE_RSA) - { - return nullptr; - } - return &_key->key.rsa; - } - - const br_ec_private_key *PrivateKey::getEC() const - { - if (!_key || _key->key_type != BR_KEYTYPE_EC) - { - return nullptr; - } - return &_key->key.ec; - } - - // ----- Certificate Lists ----- - - X509List::X509List() - { - _count = 0; - _cert = nullptr; - _ta = nullptr; - } - - X509List::X509List(const char *pemCert) - { - _count = 0; - _cert = nullptr; - _ta = nullptr; - append(pemCert); - } - - X509List::X509List(const uint8_t *derCert, size_t derLen) - { - _count = 0; - _cert = nullptr; - _ta = nullptr; - append(derCert, derLen); - } - - X509List::X509List(Stream &stream, size_t size) - { - _count = 0; - _cert = nullptr; - _ta = nullptr; - auto buff = key_bssl::loadStream(stream, size); - if (buff) - { - append(buff, size); - free(buff); - } - } - - X509List::~X509List() - { - key_bssl::free_certificates(_cert, _count); // also frees cert - for (size_t i = 0; i < _count; i++) - { - key_bssl::free_ta_contents(&_ta[i]); - } - free(_ta); - } - - bool X509List::append(const char *pemCert) - { - return append((const uint8_t *)pemCert, strlen_P(pemCert)); - } - - bool X509List::append(const uint8_t *derCert, size_t derLen) - { - size_t numCerts; - br_x509_certificate *newCerts = key_bssl::read_certificates((const char *)derCert, derLen, &numCerts); - if (!newCerts) - { - return false; - } - - // Add in the certificates - br_x509_certificate *saveCert = _cert; - _cert = (br_x509_certificate *)realloc(_cert, (numCerts + _count) * sizeof(br_x509_certificate)); - if (!_cert) - { - free(newCerts); - _cert = saveCert; - return false; - } - memcpy(&_cert[_count], newCerts, numCerts * sizeof(br_x509_certificate)); - free(newCerts); - - // Build TAs for each certificate - br_x509_trust_anchor *saveTa = _ta; - _ta = (br_x509_trust_anchor *)realloc(_ta, (numCerts + _count) * sizeof(br_x509_trust_anchor)); - if (!_ta) - { - _ta = saveTa; - return false; - } - for (size_t i = 0; i < numCerts; i++) - { - br_x509_trust_anchor *newTa = key_bssl::certificate_to_trust_anchor(&_cert[_count + i]); - if (newTa) - { - _ta[_count + i] = *newTa; - free(newTa); - } - else - { - return false; // OOM - } - } - _count += numCerts; - - return true; - } - -}; - -#endif - +/* + WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries + - Mostly compatible with Arduino WiFi shield library and standard + WiFiClient/ServerSecure (except for certificate handling). + + Copyright (c) 2018 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 +*/ +#ifndef BSSL_HELPER_CPP +#define BSSL_HELPER_CPP + +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wvla" + +#include +#include "../ESP_SSLClient_FS.h" +#include "../ESP_SSLClient_Const.h" +#if defined(USE_LIB_SSL_ENGINE) + +#include "BSSL_Helper.h" +#include +#include +#include "../bssl/bearssl.h" +#include +#include +#if defined __has_include +#if __has_include() +#include +#endif +#endif + +namespace key_bssl +{ + // Code here is pulled from brssl sources, with the copyright and license + // shown below. I've rewritten things using C++ semantics and removed + // custom VEC_* calls (std::vector to the rescue) and adjusted things to + // allow for long-running operation (i.e. some memory issues when DERs + // passed into the decoders). Bugs are most likely my fault. + + // Original (c) message follows: + /* + Copyright (c) 2016 Thomas Pornin + + 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. + */ + + class private_key + { + public: + int key_type; /* BR_KEYTYPE_RSA or BR_KEYTYPE_EC */ + union + { + br_rsa_private_key rsa; + br_ec_private_key ec; + } key; + }; + + class public_key + { + public: + int key_type; /* BR_KEYTYPE_RSA or BR_KEYTYPE_EC */ + union + { + br_rsa_public_key rsa; + br_ec_public_key ec; + } key; + }; + + class pem_object + { + public: + char *name; + unsigned char *data; + size_t data_len; + }; + + // Forward definitions + void free_ta_contents(br_x509_trust_anchor *ta); + void free_public_key(public_key *pk); + void free_private_key(private_key *sk); + bool looks_like_DER(const unsigned char *buf, size_t len); + pem_object *decode_pem(const void *src, size_t len, size_t *num); + void free_pem_object_contents(pem_object *po); + char *strdupImpl(const char *s); + + // Used as callback multiple places to append a string to a vector + static void byte_vector_append(void *ctx, const void *buff, size_t len) + { + std::vector *vec = static_cast *>(ctx); + vec->reserve(vec->size() + len); // Allocate extra space all at once + for (size_t i = 0; i < len; i++) + { + vec->push_back(((uint8_t *)buff)[i]); + } + } + + static bool certificate_to_trust_anchor_inner(br_x509_trust_anchor *ta, const br_x509_certificate *xc) + { + std::unique_ptr dc(new br_x509_decoder_context_libmail); // auto-delete on exit + std::vector vdn; + br_x509_pkey *pk; + + // Clear everything in the Trust Anchor + memset(ta, 0, sizeof(*ta)); + + br_x509_decoder_init_libmail(dc.get(), byte_vector_append, (void *)&vdn); + br_x509_decoder_push_libmail(dc.get(), xc->data, xc->data_len); + pk = br_x509_decoder_get_pkey(dc.get()); + if (pk == nullptr) + { + return false; // No key present, something broken in the cert! + } + + // Copy the raw certificate data + ta->dn.data = (uint8_t *)malloc(vdn.size()); + if (!ta->dn.data) + { + return false; // OOM, but nothing yet allocated + } + memcpy(ta->dn.data, &vdn[0], vdn.size()); + ta->dn.len = vdn.size(); + ta->flags = 0; + if (br_x509_decoder_isCA(dc.get())) + { + ta->flags |= BR_X509_TA_CA; + } + + // Extract the public key + switch (pk->key_type) + { + case BR_KEYTYPE_RSA: + ta->pkey.key_type = BR_KEYTYPE_RSA; + ta->pkey.key.rsa.n = (uint8_t *)malloc(pk->key.rsa.nlen); + ta->pkey.key.rsa.e = (uint8_t *)malloc(pk->key.rsa.elen); + if ((ta->pkey.key.rsa.n == nullptr) || (ta->pkey.key.rsa.e == nullptr)) + { + free_ta_contents(ta); // OOM, so clean up + return false; + } + memcpy(ta->pkey.key.rsa.n, pk->key.rsa.n, pk->key.rsa.nlen); + ta->pkey.key.rsa.nlen = pk->key.rsa.nlen; + memcpy(ta->pkey.key.rsa.e, pk->key.rsa.e, pk->key.rsa.elen); + ta->pkey.key.rsa.elen = pk->key.rsa.elen; + return true; + case BR_KEYTYPE_EC: + ta->pkey.key_type = BR_KEYTYPE_EC; + ta->pkey.key.ec.curve = pk->key.ec.curve; + ta->pkey.key.ec.q = (uint8_t *)malloc(pk->key.ec.qlen); + if (ta->pkey.key.ec.q == nullptr) + { + free_ta_contents(ta); // OOM, so clean up + return false; + } + memcpy(ta->pkey.key.ec.q, pk->key.ec.q, pk->key.ec.qlen); + ta->pkey.key.ec.qlen = pk->key.ec.qlen; + return true; + default: + free_ta_contents(ta); // Unknown key type + return false; + } + + // Should never get here, if so there was an unknown error + return false; + } + + br_x509_trust_anchor *certificate_to_trust_anchor(const br_x509_certificate *xc) + { + br_x509_trust_anchor *ta = (br_x509_trust_anchor *)malloc(sizeof(br_x509_trust_anchor)); + if (!ta) + { + return nullptr; + } + + if (!certificate_to_trust_anchor_inner(ta, xc)) + { + free(ta); + return nullptr; + } + return ta; + } + + void free_ta_contents(br_x509_trust_anchor *ta) + { + if (ta) + { + free(ta->dn.data); + if (ta->pkey.key_type == BR_KEYTYPE_RSA) + { + free(ta->pkey.key.rsa.n); + free(ta->pkey.key.rsa.e); + } + else if (ta->pkey.key_type == BR_KEYTYPE_EC) + { + free(ta->pkey.key.ec.q); + } + memset(ta, 0, sizeof(*ta)); + } + } + + // Checks if a bitstream looks like a valid DER(binary) encoding. + // Basically tries to verify the length of all included segments + // matches the length of the input buffer. Does not actually + // validate any contents. + bool looks_like_DER(const unsigned char *buff, size_t len) + { + if (len < 2) + { + return false; + } + if (pgm_read_byte(buff++) != 0x30) + { + return false; + } + int fb = pgm_read_byte(buff++); + len -= 2; + if (fb < 0x80) + { + return (size_t)fb == len; + } + else if (fb == 0x80) + { + return false; + } + else + { + fb -= 0x80; + if (len < (size_t)fb + 2) + { + return false; + } + len -= (size_t)fb; + size_t dlen = 0; + while (fb-- > 0) + { + if (dlen > (len >> 8)) + { + return false; + } + dlen = (dlen << 8) + (size_t)pgm_read_byte(buff++); + } + return dlen == len; + } + } + + void free_pem_object_contents(pem_object *po) + { + if (po) + { + free(po->name); + free(po->data); + po->name = nullptr; + po->data = nullptr; + } + } + + char *strdupImpl(const char *s) + { + size_t slen = strlen(s); + char *result = (char *)malloc(slen + 1); + if (!result) + return NULL; + memcpy(result, s, slen + 1); + return result; + } + + // Converts a PEM (~=base64) source into a set of DER-encoded binary blobs. + // Each blob is named by the ---- BEGIN xxx ---- field, and multiple + // blobs may be returned. + pem_object *decode_pem(const void *src, size_t len, size_t *num) + { + std::vector pem_list; + std::unique_ptr pc(new br_pem_decoder_context); // auto-delete on exit + if (!pc.get()) + { + return nullptr; + } + pem_object po, *pos; + const unsigned char *buff; + std::vector bv; + + *num = 0; + br_pem_decoder_init(pc.get()); + buff = (const unsigned char *)src; + po.name = nullptr; + po.data = nullptr; + po.data_len = 0; + bool inobj = false; + bool extra_nl = true; + + while (len > 0) + { + size_t tlen; + + tlen = br_pem_decoder_push(pc.get(), buff, len); + buff += tlen; + len -= tlen; + switch (br_pem_decoder_event(pc.get())) + { + case BR_PEM_BEGIN_OBJ: + po.name = strdupImpl(br_pem_decoder_name(pc.get())); + br_pem_decoder_setdest(pc.get(), byte_vector_append, &bv); + inobj = true; + break; + + case BR_PEM_END_OBJ: + if (inobj) + { + // Stick data into the vector + po.data = (uint8_t *)malloc(bv.size()); + if (po.data) + { + memcpy(po.data, &bv[0], bv.size()); + po.data_len = bv.size(); + pem_list.push_back(po); + } + // Clean up state for next blob processing + bv.clear(); + po.name = nullptr; + po.data = nullptr; + po.data_len = 0; + inobj = false; + } + break; + + case BR_PEM_ERROR: + free(po.name); + for (size_t i = 0; i < pem_list.size(); i++) + { + free_pem_object_contents(&pem_list[i]); + } + return nullptr; + + default: + // Do nothing here, the parser is still working on things + break; + } + + if (len == 0 && extra_nl) + { + extra_nl = false; + buff = (const unsigned char *)"\n"; + len = 1; + } + } + + if (inobj) + { + free(po.name); + for (size_t i = 0; i < pem_list.size(); i++) + { + free_pem_object_contents(&pem_list[i]); + } + return nullptr; + } + + pos = (pem_object *)malloc((1 + pem_list.size()) * sizeof(*pos)); + if (pos) + { + *num = pem_list.size(); + pem_list.push_back(po); // Null-terminate list + memcpy(pos, &pem_list[0], pem_list.size() * sizeof(*pos)); + } + return pos; + } + + // Parse out DER or PEM encoded certificates from a binary buffer, + // potentially stored in PROGMEM. + br_x509_certificate *read_certificates(const char *buff, size_t len, size_t *num) + { + std::vector cert_list; + pem_object *pos; + size_t u, num_pos; + br_x509_certificate *xcs; + br_x509_certificate dummy; + + *num = 0; + + if (looks_like_DER((const unsigned char *)buff, len)) + { + xcs = (br_x509_certificate *)malloc(2 * sizeof(*xcs)); + if (!xcs) + { + return nullptr; + } + xcs[0].data = (uint8_t *)malloc(len); + if (!xcs[0].data) + { + free(xcs); + return nullptr; + } + memcpy_P(xcs[0].data, buff, len); + xcs[0].data_len = len; + xcs[1].data = nullptr; + xcs[1].data_len = 0; + *num = 1; + return xcs; + } + + pos = decode_pem(buff, len, &num_pos); + if (!pos) + { + return nullptr; + } + for (u = 0; u < num_pos; u++) + { + if (!strcmp_P(pos[u].name, PSTR("CERTIFICATE")) || !strcmp_P(pos[u].name, PSTR("X509 CERTIFICATE"))) + { + br_x509_certificate xc; + xc.data = pos[u].data; + xc.data_len = pos[u].data_len; + pos[u].data = nullptr; // Don't free the data we moved to the xc vector! + cert_list.push_back(xc); + } + } + for (u = 0; u < num_pos; u++) + { + free_pem_object_contents(&pos[u]); + } + free(pos); + + if (cert_list.size() == 0) + { + return nullptr; + } + *num = cert_list.size(); + dummy.data = nullptr; + dummy.data_len = 0; + cert_list.push_back(dummy); + xcs = (br_x509_certificate *)malloc(cert_list.size() * sizeof(*xcs)); + if (!xcs) + { + for (size_t i = 0; i < cert_list.size(); i++) + { + free(cert_list[i].data); // Clean up any captured data blobs + } + return nullptr; + } + memcpy(xcs, &cert_list[0], cert_list.size() * sizeof(br_x509_certificate)); + // XCS now has [].data pointing to the previously allocated blobs, so don't + // want to free anything in cert_list[]. + return xcs; + } + + void free_certificates(br_x509_certificate *certs, size_t num) + { + if (certs) + { + for (size_t u = 0; u < num; u++) + { + free(certs[u].data); + } + free(certs); + } + } + + static public_key *decode_public_key(const unsigned char *buff, size_t len) + { + std::unique_ptr dc(new br_pkey_decoder_context); // auto-delete on exit + if (!dc.get()) + { + return nullptr; + } + + public_key *pk = nullptr; + // https://github.com/yglukhov/bearssl_pkey_decoder + br_pkey_decoder_init(dc.get()); + br_pkey_decoder_push(dc.get(), buff, len); + int err = br_pkey_decoder_last_error(dc.get()); + if (err != 0) + { + return nullptr; + } + + const br_rsa_public_key *rk = nullptr; + const br_ec_public_key *ek = nullptr; + switch (br_pkey_decoder_key_type(dc.get())) + { + case BR_KEYTYPE_RSA: + rk = br_pkey_decoder_get_rsa(dc.get()); + pk = (public_key *)malloc(sizeof *pk); + if (!pk) + { + return nullptr; + } + pk->key_type = BR_KEYTYPE_RSA; + pk->key.rsa.n = (uint8_t *)malloc(rk->nlen); + pk->key.rsa.e = (uint8_t *)malloc(rk->elen); + if (!pk->key.rsa.n || !pk->key.rsa.e) + { + free(pk->key.rsa.n); + free(pk->key.rsa.e); + free(pk); + return nullptr; + } + memcpy(pk->key.rsa.n, rk->n, rk->nlen); + pk->key.rsa.nlen = rk->nlen; + memcpy(pk->key.rsa.e, rk->e, rk->elen); + pk->key.rsa.elen = rk->elen; + return pk; + + case BR_KEYTYPE_EC: + ek = br_pkey_decoder_get_ec(dc.get()); + pk = (public_key *)malloc(sizeof *pk); + if (!pk) + { + return nullptr; + } + pk->key_type = BR_KEYTYPE_EC; + pk->key.ec.q = (uint8_t *)malloc(ek->qlen); + if (!pk->key.ec.q) + { + free(pk); + return nullptr; + } + memcpy(pk->key.ec.q, ek->q, ek->qlen); + pk->key.ec.qlen = ek->qlen; + pk->key.ec.curve = ek->curve; + return pk; + + default: + return nullptr; + } + } + + void free_public_key(public_key *pk) + { + if (pk) + { + if (pk->key_type == BR_KEYTYPE_RSA) + { + free(pk->key.rsa.n); + free(pk->key.rsa.e); + } + else if (pk->key_type == BR_KEYTYPE_EC) + { + free(pk->key.ec.q); + } + free(pk); + } + } + + static private_key *decode_private_key(const unsigned char *buff, size_t len) + { + std::unique_ptr dc(new br_skey_decoder_context); // auto-delete on exit + if (!dc.get()) + { + return nullptr; + } + + private_key *sk = nullptr; + + br_skey_decoder_init(dc.get()); + br_skey_decoder_push(dc.get(), buff, len); + int err = br_skey_decoder_last_error(dc.get()); + if (err != 0) + { + return nullptr; + } + + const br_rsa_private_key *rk = nullptr; + const br_ec_private_key *ek = nullptr; + switch (br_skey_decoder_key_type(dc.get())) + { + case BR_KEYTYPE_RSA: + rk = br_skey_decoder_get_rsa(dc.get()); + sk = (private_key *)malloc(sizeof *sk); + if (!sk) + { + return nullptr; + } + sk->key_type = BR_KEYTYPE_RSA; + sk->key.rsa.p = (uint8_t *)malloc(rk->plen); + sk->key.rsa.q = (uint8_t *)malloc(rk->qlen); + sk->key.rsa.dp = (uint8_t *)malloc(rk->dplen); + sk->key.rsa.dq = (uint8_t *)malloc(rk->dqlen); + sk->key.rsa.iq = (uint8_t *)malloc(rk->iqlen); + if (!sk->key.rsa.p || !sk->key.rsa.q || !sk->key.rsa.dp || !sk->key.rsa.dq || !sk->key.rsa.iq) + { + free_private_key(sk); + return nullptr; + } + sk->key.rsa.n_bitlen = rk->n_bitlen; + memcpy(sk->key.rsa.p, rk->p, rk->plen); + sk->key.rsa.plen = rk->plen; + memcpy(sk->key.rsa.q, rk->q, rk->qlen); + sk->key.rsa.qlen = rk->qlen; + memcpy(sk->key.rsa.dp, rk->dp, rk->dplen); + sk->key.rsa.dplen = rk->dplen; + memcpy(sk->key.rsa.dq, rk->dq, rk->dqlen); + sk->key.rsa.dqlen = rk->dqlen; + memcpy(sk->key.rsa.iq, rk->iq, rk->iqlen); + sk->key.rsa.iqlen = rk->iqlen; + return sk; + + case BR_KEYTYPE_EC: + ek = br_skey_decoder_get_ec(dc.get()); + sk = (private_key *)malloc(sizeof *sk); + if (!sk) + { + return nullptr; + } + sk->key_type = BR_KEYTYPE_EC; + sk->key.ec.curve = ek->curve; + sk->key.ec.x = (uint8_t *)malloc(ek->xlen); + if (!sk->key.ec.x) + { + free_private_key(sk); + return nullptr; + } + memcpy(sk->key.ec.x, ek->x, ek->xlen); + sk->key.ec.xlen = ek->xlen; + return sk; + + default: + return nullptr; + } + } + + void free_private_key(private_key *sk) + { + if (sk) + { + switch (sk->key_type) + { + case BR_KEYTYPE_RSA: + free(sk->key.rsa.p); + free(sk->key.rsa.q); + free(sk->key.rsa.dp); + free(sk->key.rsa.dq); + free(sk->key.rsa.iq); + break; + case BR_KEYTYPE_EC: + free(sk->key.ec.x); + break; + default: + // Could be an uninitted key, no sub elements to free + break; + } + free(sk); + } + } + + void free_pem_object(pem_object *pos) + { + if (pos != nullptr) + { + for (size_t u = 0; pos[u].name; u++) + { + free_pem_object_contents(&pos[u]); + } + free(pos); + } + } + + private_key *read_private_key(const char *buff, size_t len) + { + private_key *sk = nullptr; + pem_object *pos = nullptr; + + if (looks_like_DER((const unsigned char *)buff, len)) + { + sk = decode_private_key((const unsigned char *)buff, len); + return sk; + } + + size_t num; + pos = decode_pem(buff, len, &num); + if (pos == nullptr) + { + return nullptr; // PEM decode error + } + for (size_t u = 0; pos[u].name; u++) + { + const char *name = pos[u].name; + if (!strcmp_P(name, PSTR("RSA PRIVATE KEY")) || !strcmp_P(name, PSTR("EC PRIVATE KEY")) || !strcmp_P(name, PSTR("PRIVATE KEY"))) + { + sk = decode_private_key(pos[u].data, pos[u].data_len); + free_pem_object(pos); + return sk; + } + } + // If we hit here, no match + free_pem_object(pos); + return nullptr; + } + + public_key *read_public_key(const char *buff, size_t len) + { + public_key *pk = nullptr; + pem_object *pos = nullptr; + + if (looks_like_DER((const unsigned char *)buff, len)) + { + pk = decode_public_key((const unsigned char *)buff, len); + return pk; + } + size_t num; + pos = decode_pem(buff, len, &num); + if (pos == nullptr) + { + return nullptr; // PEM decode error + } + for (size_t u = 0; pos[u].name; u++) + { + const char *name = pos[u].name; + if (!strcmp_P(name, PSTR("RSA PUBLIC KEY")) || !strcmp_P(name, PSTR("EC PUBLIC KEY")) || !strcmp_P(name, PSTR("PUBLIC KEY"))) + { + pk = decode_public_key(pos[u].data, pos[u].data_len); + free_pem_object(pos); + return pk; + } + } + + // We hit here == no key found + free_pem_object(pos); + return pk; + } + + static uint8_t *loadStream(Stream &stream, size_t size) + { + uint8_t *dest = (uint8_t *)malloc(size); + if (!dest) + { + return nullptr; // OOM error + } + if (size != stream.readBytes(dest, size)) + { + free(dest); // Error during read + return nullptr; + } + return dest; + } +}; + +namespace bssl +{ + + // ----- Public Key ----- + + PublicKey::PublicKey() + { + _key = nullptr; + } + + PublicKey::PublicKey(const char *pemKey) + { + _key = nullptr; + parse(pemKey); + } + + PublicKey::PublicKey(const uint8_t *derKey, size_t derLen) + { + _key = nullptr; + parse(derKey, derLen); + } + + PublicKey::PublicKey(Stream &stream, size_t size) + { + _key = nullptr; + auto buff = key_bssl::loadStream(stream, size); + if (buff) + { + parse(buff, size); + free(buff); + } + } + + PublicKey::~PublicKey() + { + if (_key) + { + key_bssl::free_public_key(_key); + } + } + + bool PublicKey::parse(const char *pemKey) + { + return parse((const uint8_t *)pemKey, strlen_P(pemKey)); + } + + bool PublicKey::parse(const uint8_t *derKey, size_t derLen) + { + if (_key) + { + key_bssl::free_public_key(_key); + _key = nullptr; + } + _key = key_bssl::read_public_key((const char *)derKey, derLen); + return _key ? true : false; + } + + bool PublicKey::isRSA() const + { + if (!_key || _key->key_type != BR_KEYTYPE_RSA) + { + return false; + } + return true; + } + + bool PublicKey::isEC() const + { + if (!_key || _key->key_type != BR_KEYTYPE_EC) + { + return false; + } + return true; + } + + const br_rsa_public_key *PublicKey::getRSA() const + { + if (!_key || _key->key_type != BR_KEYTYPE_RSA) + { + return nullptr; + } + return &_key->key.rsa; + } + + const br_ec_public_key *PublicKey::getEC() const + { + if (!_key || _key->key_type != BR_KEYTYPE_EC) + { + return nullptr; + } + return &_key->key.ec; + } + + // ----- Private Key ----- + + PrivateKey::PrivateKey() + { + _key = nullptr; + } + + PrivateKey::PrivateKey(const char *pemKey) + { + _key = nullptr; + parse(pemKey); + } + + PrivateKey::PrivateKey(const uint8_t *derKey, size_t derLen) + { + _key = nullptr; + parse(derKey, derLen); + } + + PrivateKey::PrivateKey(Stream &stream, size_t size) + { + _key = nullptr; + auto buff = key_bssl::loadStream(stream, size); + if (buff) + { + parse(buff, size); + free(buff); + } + } + + PrivateKey::~PrivateKey() + { + if (_key) + { + key_bssl::free_private_key(_key); + } + } + + bool PrivateKey::parse(const char *pemKey) + { + return parse((const uint8_t *)pemKey, strlen_P(pemKey)); + } + + bool PrivateKey::parse(const uint8_t *derKey, size_t derLen) + { + if (_key) + { + key_bssl::free_private_key(_key); + _key = nullptr; + } + _key = key_bssl::read_private_key((const char *)derKey, derLen); + return _key ? true : false; + } + + bool PrivateKey::isRSA() const + { + if (!_key || _key->key_type != BR_KEYTYPE_RSA) + { + return false; + } + return true; + } + + bool PrivateKey::isEC() const + { + if (!_key || _key->key_type != BR_KEYTYPE_EC) + { + return false; + } + return true; + } + + const br_rsa_private_key *PrivateKey::getRSA() const + { + if (!_key || _key->key_type != BR_KEYTYPE_RSA) + { + return nullptr; + } + return &_key->key.rsa; + } + + const br_ec_private_key *PrivateKey::getEC() const + { + if (!_key || _key->key_type != BR_KEYTYPE_EC) + { + return nullptr; + } + return &_key->key.ec; + } + + // ----- Certificate Lists ----- + + X509List::X509List() + { + _count = 0; + _cert = nullptr; + _ta = nullptr; + } + + X509List::X509List(const char *pemCert) + { + _count = 0; + _cert = nullptr; + _ta = nullptr; + append(pemCert); + } + + X509List::X509List(const uint8_t *derCert, size_t derLen) + { + _count = 0; + _cert = nullptr; + _ta = nullptr; + append(derCert, derLen); + } + + X509List::X509List(Stream &stream, size_t size) + { + _count = 0; + _cert = nullptr; + _ta = nullptr; + auto buff = key_bssl::loadStream(stream, size); + if (buff) + { + append(buff, size); + free(buff); + } + } + + X509List::~X509List() + { + key_bssl::free_certificates(_cert, _count); // also frees cert + for (size_t i = 0; i < _count; i++) + { + key_bssl::free_ta_contents(&_ta[i]); + } + free(_ta); + } + + bool X509List::append(const char *pemCert) + { + return append((const uint8_t *)pemCert, strlen_P(pemCert)); + } + + bool X509List::append(const uint8_t *derCert, size_t derLen) + { + size_t numCerts; + br_x509_certificate *newCerts = key_bssl::read_certificates((const char *)derCert, derLen, &numCerts); + if (!newCerts) + { + return false; + } + + // Add in the certificates + br_x509_certificate *saveCert = _cert; + _cert = (br_x509_certificate *)realloc(_cert, (numCerts + _count) * sizeof(br_x509_certificate)); + if (!_cert) + { + free(newCerts); + _cert = saveCert; + return false; + } + memcpy(&_cert[_count], newCerts, numCerts * sizeof(br_x509_certificate)); + free(newCerts); + + // Build TAs for each certificate + br_x509_trust_anchor *saveTa = _ta; + _ta = (br_x509_trust_anchor *)realloc(_ta, (numCerts + _count) * sizeof(br_x509_trust_anchor)); + if (!_ta) + { + _ta = saveTa; + return false; + } + for (size_t i = 0; i < numCerts; i++) + { + br_x509_trust_anchor *newTa = key_bssl::certificate_to_trust_anchor(&_cert[_count + i]); + if (newTa) + { + _ta[_count + i] = *newTa; + free(newTa); + } + else + { + return false; // OOM + } + } + _count += numCerts; + + return true; + } + +}; + +#endif + #endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_Helper.h b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_Helper.h index ca7ff0c1f..ef3d1461c 100644 --- a/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_Helper.h +++ b/lib/libesp32/ESP-Mail-Client/src/SSLClient/client/BSSL_Helper.h @@ -1,447 +1,447 @@ - -/* - WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries - - Mostly compatible with Arduino WiFi shield library and standard - WiFiClient/ServerSecure (except for certificate handling). - - Copyright (c) 2018 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 -*/ -#ifndef BSSL_HELPER_H -#define BSSL_HELPER_H - -#pragma GCC diagnostic ignored "-Wunused-function" -#pragma GCC diagnostic ignored "-Wvla" - -#include -#include "../ESP_SSLClient_FS.h" -#include "../ESP_SSLClient_Const.h" - -#if defined(USE_EMBED_SSL_ENGINE) - -#if defined(ESP8266) - -#ifdef __GNUC__ -#if __GNUC__ > 4 || __GNUC__ == 10 -#if defined(ARDUINO_ESP8266_GIT_VER) -#if ARDUINO_ESP8266_GIT_VER > 0 -#define ESP8266_CORE_SDK_V3_X_X -#endif -#endif -#endif -#endif - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#else - -#include -#include -#include -#include - -#endif - -#elif defined(USE_LIB_SSL_ENGINE) - -#include "../bssl/bearssl.h" - -#endif - -#if defined(USE_LIB_SSL_ENGINE) || defined(USE_EMBED_SSL_ENGINE) -// Cache for a TLS session with a server -// Use with BearSSL::WiFiClientSecure::setSession -// to accelerate the TLS handshake -class BearSSL_Session -{ - friend class BSSL_SSL_Client; - -public: - BearSSL_Session() - { - memset(&_session, 0, sizeof(_session)); - } - - br_ssl_session_parameters *getSession() - { - return &_session; - } - -private: - // The actual BearSSL session information - br_ssl_session_parameters _session; -}; - -static const uint16_t suites_P[] PROGMEM = { -#ifndef BEARSSL_SSL_BASIC - BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, - BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, - BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, - BR_TLS_RSA_WITH_AES_128_GCM_SHA256, - BR_TLS_RSA_WITH_AES_256_GCM_SHA384, - BR_TLS_RSA_WITH_AES_128_CCM, - BR_TLS_RSA_WITH_AES_256_CCM, - BR_TLS_RSA_WITH_AES_128_CCM_8, - BR_TLS_RSA_WITH_AES_256_CCM_8, -#endif - BR_TLS_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_RSA_WITH_AES_256_CBC_SHA256, - BR_TLS_RSA_WITH_AES_128_CBC_SHA, - BR_TLS_RSA_WITH_AES_256_CBC_SHA, -#ifndef BEARSSL_SSL_BASIC - BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, - BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA -#endif -}; - -// For apps which want to use less secure but faster ciphers, only -static const uint16_t faster_suites_P[] PROGMEM = { - BR_TLS_RSA_WITH_AES_256_CBC_SHA256, - BR_TLS_RSA_WITH_AES_128_CBC_SHA256, - BR_TLS_RSA_WITH_AES_256_CBC_SHA, - BR_TLS_RSA_WITH_AES_128_CBC_SHA}; - -// Internal opaque structures, not needed by user applications -namespace key_bssl -{ - class public_key; - class private_key; -}; - -namespace bssl -{ - - // Holds either a single public RSA or EC key for use when BearSSL wants a pubkey. - // Copies all associated data so no need to keep input PEM/DER keys. - // All inputs can be either in RAM or PROGMEM. - class PublicKey - { - public: - PublicKey(); - PublicKey(const char *pemKey); - PublicKey(const uint8_t *derKey, size_t derLen); - PublicKey(Stream &stream, size_t size); - PublicKey(Stream &stream) : PublicKey(stream, stream.available()){}; - ~PublicKey(); - - bool parse(const char *pemKey); - bool parse(const uint8_t *derKey, size_t derLen); - - // Accessors for internal use, not needed by apps - bool isRSA() const; - bool isEC() const; - const br_rsa_public_key *getRSA() const; - const br_ec_public_key *getEC() const; - - // Disable the copy constructor, we're pointer based - PublicKey(const PublicKey &that) = delete; - PublicKey &operator=(const PublicKey &that) = delete; - - private: - key_bssl::public_key *_key; - }; - - // Holds either a single private RSA or EC key for use when BearSSL wants a secretkey. - // Copies all associated data so no need to keep input PEM/DER keys. - // All inputs can be either in RAM or PROGMEM. - class PrivateKey - { - public: - PrivateKey(); - PrivateKey(const char *pemKey); - PrivateKey(const uint8_t *derKey, size_t derLen); - PrivateKey(Stream &stream, size_t size); - PrivateKey(Stream &stream) : PrivateKey(stream, stream.available()){}; - ~PrivateKey(); - - bool parse(const char *pemKey); - bool parse(const uint8_t *derKey, size_t derLen); - - // Accessors for internal use, not needed by apps - bool isRSA() const; - bool isEC() const; - const br_rsa_private_key *getRSA() const; - const br_ec_private_key *getEC() const; - - // Disable the copy constructor, we're pointer based - PrivateKey(const PrivateKey &that) = delete; - PrivateKey &operator=(const PrivateKey &that) = delete; - - private: - key_bssl::private_key *_key; - }; - - // Holds one or more X.509 certificates and associated trust anchors for - // use whenever BearSSL needs a cert or TA. May want to have multiple - // certs for things like a series of trusted CAs (but check the CertStore class - // for a more memory efficient way). - // Copies all associated data so no need to keep input PEM/DER certs. - // All inputs can be either in RAM or PROGMEM. - class X509List - { - public: - X509List(); - X509List(const char *pemCert); - X509List(const uint8_t *derCert, size_t derLen); - X509List(Stream &stream, size_t size); - X509List(Stream &stream) : X509List(stream, stream.available()){}; - ~X509List(); - - bool append(const char *pemCert); - bool append(const uint8_t *derCert, size_t derLen); - - // Accessors - size_t getCount() const - { - return _count; - } - const br_x509_certificate *getX509Certs() const - { - return _cert; - } - const br_x509_trust_anchor *getTrustAnchors() const - { - return _ta; - } - - // Disable the copy constructor, we're pointer based - X509List(const X509List &that) = delete; - X509List &operator=(const X509List &that) = delete; - - private: - size_t _count; - br_x509_certificate *_cert; - br_x509_trust_anchor *_ta; - }; - - extern "C" - { - - // Install hashes into the SSL engine - static void br_ssl_client_install_hashes(br_ssl_engine_context *eng) - { - br_ssl_engine_set_hash(eng, br_md5_ID, &br_md5_vtable); - br_ssl_engine_set_hash(eng, br_sha1_ID, &br_sha1_vtable); - br_ssl_engine_set_hash(eng, br_sha224_ID, &br_sha224_vtable); - br_ssl_engine_set_hash(eng, br_sha256_ID, &br_sha256_vtable); - br_ssl_engine_set_hash(eng, br_sha384_ID, &br_sha384_vtable); - br_ssl_engine_set_hash(eng, br_sha512_ID, &br_sha512_vtable); - } - - static void br_x509_minimal_install_hashes(br_x509_minimal_context *x509) - { - br_x509_minimal_set_hash(x509, br_md5_ID, &br_md5_vtable); - br_x509_minimal_set_hash(x509, br_sha1_ID, &br_sha1_vtable); - br_x509_minimal_set_hash(x509, br_sha224_ID, &br_sha224_vtable); - br_x509_minimal_set_hash(x509, br_sha256_ID, &br_sha256_vtable); - br_x509_minimal_set_hash(x509, br_sha384_ID, &br_sha384_vtable); - br_x509_minimal_set_hash(x509, br_sha512_ID, &br_sha512_vtable); - } - - // Default initializion for our SSL clients - static void br_ssl_client_base_init(br_ssl_client_context *cc, const uint16_t *cipher_list, int cipher_cnt) - { - uint16_t suites[cipher_cnt]; - memcpy_P(suites, cipher_list, cipher_cnt * sizeof(cipher_list[0])); - br_ssl_client_zero(cc); - br_ssl_engine_add_flags(&cc->eng, BR_OPT_NO_RENEGOTIATION); // forbid SSL renegotiation, as we free the Private Key after handshake - br_ssl_engine_set_versions(&cc->eng, BR_TLS10, BR_TLS12); - br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); - br_ssl_client_set_default_rsapub(cc); - br_ssl_engine_set_default_rsavrfy(&cc->eng); -#ifndef BEARSSL_SSL_BASIC - br_ssl_engine_set_default_ecdsa(&cc->eng); -#endif - br_ssl_client_install_hashes(&cc->eng); - br_ssl_engine_set_prf10(&cc->eng, &br_tls10_prf); - br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); - br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf); - br_ssl_engine_set_default_aes_cbc(&cc->eng); -#ifndef BEARSSL_SSL_BASIC - br_ssl_engine_set_default_aes_gcm(&cc->eng); - br_ssl_engine_set_default_aes_ccm(&cc->eng); - br_ssl_engine_set_default_des_cbc(&cc->eng); - br_ssl_engine_set_default_chapol(&cc->eng); -#endif - } - - // BearSSL doesn't define a true insecure decoder, so we make one ourselves - // from the simple parser. It generates the issuer and subject hashes and - // the SHA1 fingerprint, only one (or none!) of which will be used to - // "verify" the certificate. - - // Private x509 decoder state - struct br_x509_insecure_context - { - const br_x509_class *vtable; - bool done_cert; - const uint8_t *match_fingerprint; - br_sha1_context sha1_cert; - bool allow_self_signed; - br_sha256_context sha256_subject; - br_sha256_context sha256_issuer; - br_x509_decoder_context_libmail ctx; - }; - - // Callback for the x509_minimal subject DN - static void insecure_subject_dn_append(void *ctx, const void *buf, size_t len) - { - br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; - br_sha256_update(&xc->sha256_subject, buf, len); - } - - // Callback for the x509_minimal issuer DN - static void insecure_issuer_dn_append(void *ctx, const void *buf, size_t len) - { - br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; - br_sha256_update(&xc->sha256_issuer, buf, len); - } - - // Callback for each certificate present in the chain (but only operates - // on the first one by design). - static void insecure_start_cert(const br_x509_class **ctx, uint32_t length) - { - (void)ctx; - (void)length; - } - - // Callback for each byte stream in the chain. Only process first cert. - static void insecure_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) - { - br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; - // Don't process anything but the first certificate in the chain - if (!xc->done_cert) - { - br_sha1_update(&xc->sha1_cert, buf, len); - br_x509_decoder_push_libmail(&xc->ctx, (const void *)buf, len); - } - } - // Callback on the first byte of any certificate - static void insecure_start_chain(const br_x509_class **ctx, const char *server_name) - { - br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; -#if defined(USE_EMBED_SSL_ENGINE) - br_x509_decoder_init_libmail(&xc->ctx, insecure_subject_dn_append, xc, insecure_issuer_dn_append, xc); -#elif defined(ESP32) || defined(USE_LIB_SSL_ENGINE) - br_x509_decoder_init_libmail(&xc->ctx, insecure_subject_dn_append, xc); -#endif - xc->done_cert = false; - br_sha1_init(&xc->sha1_cert); - br_sha256_init(&xc->sha256_subject); - br_sha256_init(&xc->sha256_issuer); - (void)server_name; - } - - // Callback on individual cert end. - static void insecure_end_cert(const br_x509_class **ctx) - { - br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; - xc->done_cert = true; - } - - // Callback when complete chain has been parsed. - // Return 0 on validation success, !0 on validation error - static unsigned insecure_end_chain(const br_x509_class **ctx) - { - const br_x509_insecure_context *xc = (const br_x509_insecure_context *)ctx; - if (!xc->done_cert) - { - // BSSL_BSSL_SSL_Client_DEBUG_PRINTF("insecure_end_chain: No cert seen\n"); - return 1; // error - } - - // Handle SHA1 fingerprint matching - char res[20]; - br_sha1_out(&xc->sha1_cert, res); - if (xc->match_fingerprint && memcmp(res, xc->match_fingerprint, sizeof(res))) - { - - return BR_ERR_X509_NOT_TRUSTED; - } - - // Handle self-signer certificate acceptance - char res_issuer[32]; - char res_subject[32]; - br_sha256_out(&xc->sha256_issuer, res_issuer); - br_sha256_out(&xc->sha256_subject, res_subject); - if (xc->allow_self_signed && memcmp(res_subject, res_issuer, sizeof(res_issuer))) - { - // BSSL_BSSL_SSL_Client_DEBUG_PRINTF("insecure_end_chain: Didn't get self-signed cert\n"); - return BR_ERR_X509_NOT_TRUSTED; - } - - // Default (no validation at all) or no errors in prior checks = success. - return 0; - } - - // Return the public key from the validator (set by x509_minimal) - static const br_x509_pkey *insecure_get_pkey(const br_x509_class *const *ctx, unsigned *usages) - { - const br_x509_insecure_context *xc = (const br_x509_insecure_context *)ctx; - if (usages != nullptr) - { - *usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN; // I said we were insecure! - } - return &xc->ctx.pkey; - } - } - -}; -#endif - + +/* + WiFiClientBearSSL- SSL client/server for esp8266 using BearSSL libraries + - Mostly compatible with Arduino WiFi shield library and standard + WiFiClient/ServerSecure (except for certificate handling). + + Copyright (c) 2018 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 +*/ +#ifndef BSSL_HELPER_H +#define BSSL_HELPER_H + +#pragma GCC diagnostic ignored "-Wunused-function" +#pragma GCC diagnostic ignored "-Wvla" + +#include +#include "../ESP_SSLClient_FS.h" +#include "../ESP_SSLClient_Const.h" + +#if defined(USE_EMBED_SSL_ENGINE) + +#if defined(ESP8266) + +#ifdef __GNUC__ +#if __GNUC__ > 4 || __GNUC__ == 10 +#if defined(ARDUINO_ESP8266_GIT_VER) +#if ARDUINO_ESP8266_GIT_VER > 0 +#define ESP8266_CORE_SDK_V3_X_X +#endif +#endif +#endif +#endif + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#else + +#include +#include +#include +#include + +#endif + +#elif defined(USE_LIB_SSL_ENGINE) + +#include "../bssl/bearssl.h" + +#endif + +#if defined(USE_LIB_SSL_ENGINE) || defined(USE_EMBED_SSL_ENGINE) +// Cache for a TLS session with a server +// Use with BearSSL::WiFiClientSecure::setSession +// to accelerate the TLS handshake +class BearSSL_Session +{ + friend class BSSL_SSL_Client; + +public: + BearSSL_Session() + { + memset(&_session, 0, sizeof(_session)); + } + + br_ssl_session_parameters *getSession() + { + return &_session; + } + +private: + // The actual BearSSL session information + br_ssl_session_parameters _session; +}; + +static const uint16_t suites_P[] PROGMEM = { +#ifndef BEARSSL_SSL_BASIC + BR_TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, + BR_TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, + BR_TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, + BR_TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256, + BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384, + BR_TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDH_RSA_WITH_AES_128_CBC_SHA, + BR_TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA, + BR_TLS_ECDH_RSA_WITH_AES_256_CBC_SHA, + BR_TLS_RSA_WITH_AES_128_GCM_SHA256, + BR_TLS_RSA_WITH_AES_256_GCM_SHA384, + BR_TLS_RSA_WITH_AES_128_CCM, + BR_TLS_RSA_WITH_AES_256_CCM, + BR_TLS_RSA_WITH_AES_128_CCM_8, + BR_TLS_RSA_WITH_AES_256_CCM_8, +#endif + BR_TLS_RSA_WITH_AES_128_CBC_SHA256, + BR_TLS_RSA_WITH_AES_256_CBC_SHA256, + BR_TLS_RSA_WITH_AES_128_CBC_SHA, + BR_TLS_RSA_WITH_AES_256_CBC_SHA, +#ifndef BEARSSL_SSL_BASIC + BR_TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA, + BR_TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA, + BR_TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA, + BR_TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA, + BR_TLS_RSA_WITH_3DES_EDE_CBC_SHA +#endif +}; + +// For apps which want to use less secure but faster ciphers, only +static const uint16_t faster_suites_P[] PROGMEM = { + BR_TLS_RSA_WITH_AES_256_CBC_SHA256, + BR_TLS_RSA_WITH_AES_128_CBC_SHA256, + BR_TLS_RSA_WITH_AES_256_CBC_SHA, + BR_TLS_RSA_WITH_AES_128_CBC_SHA}; + +// Internal opaque structures, not needed by user applications +namespace key_bssl +{ + class public_key; + class private_key; +}; + +namespace bssl +{ + + // Holds either a single public RSA or EC key for use when BearSSL wants a pubkey. + // Copies all associated data so no need to keep input PEM/DER keys. + // All inputs can be either in RAM or PROGMEM. + class PublicKey + { + public: + PublicKey(); + PublicKey(const char *pemKey); + PublicKey(const uint8_t *derKey, size_t derLen); + PublicKey(Stream &stream, size_t size); + PublicKey(Stream &stream) : PublicKey(stream, stream.available()){}; + ~PublicKey(); + + bool parse(const char *pemKey); + bool parse(const uint8_t *derKey, size_t derLen); + + // Accessors for internal use, not needed by apps + bool isRSA() const; + bool isEC() const; + const br_rsa_public_key *getRSA() const; + const br_ec_public_key *getEC() const; + + // Disable the copy constructor, we're pointer based + PublicKey(const PublicKey &that) = delete; + PublicKey &operator=(const PublicKey &that) = delete; + + private: + key_bssl::public_key *_key; + }; + + // Holds either a single private RSA or EC key for use when BearSSL wants a secretkey. + // Copies all associated data so no need to keep input PEM/DER keys. + // All inputs can be either in RAM or PROGMEM. + class PrivateKey + { + public: + PrivateKey(); + PrivateKey(const char *pemKey); + PrivateKey(const uint8_t *derKey, size_t derLen); + PrivateKey(Stream &stream, size_t size); + PrivateKey(Stream &stream) : PrivateKey(stream, stream.available()){}; + ~PrivateKey(); + + bool parse(const char *pemKey); + bool parse(const uint8_t *derKey, size_t derLen); + + // Accessors for internal use, not needed by apps + bool isRSA() const; + bool isEC() const; + const br_rsa_private_key *getRSA() const; + const br_ec_private_key *getEC() const; + + // Disable the copy constructor, we're pointer based + PrivateKey(const PrivateKey &that) = delete; + PrivateKey &operator=(const PrivateKey &that) = delete; + + private: + key_bssl::private_key *_key; + }; + + // Holds one or more X.509 certificates and associated trust anchors for + // use whenever BearSSL needs a cert or TA. May want to have multiple + // certs for things like a series of trusted CAs (but check the CertStore class + // for a more memory efficient way). + // Copies all associated data so no need to keep input PEM/DER certs. + // All inputs can be either in RAM or PROGMEM. + class X509List + { + public: + X509List(); + X509List(const char *pemCert); + X509List(const uint8_t *derCert, size_t derLen); + X509List(Stream &stream, size_t size); + X509List(Stream &stream) : X509List(stream, stream.available()){}; + ~X509List(); + + bool append(const char *pemCert); + bool append(const uint8_t *derCert, size_t derLen); + + // Accessors + size_t getCount() const + { + return _count; + } + const br_x509_certificate *getX509Certs() const + { + return _cert; + } + const br_x509_trust_anchor *getTrustAnchors() const + { + return _ta; + } + + // Disable the copy constructor, we're pointer based + X509List(const X509List &that) = delete; + X509List &operator=(const X509List &that) = delete; + + private: + size_t _count; + br_x509_certificate *_cert; + br_x509_trust_anchor *_ta; + }; + + extern "C" + { + + // Install hashes into the SSL engine + static void br_ssl_client_install_hashes(br_ssl_engine_context *eng) + { + br_ssl_engine_set_hash(eng, br_md5_ID, &br_md5_vtable); + br_ssl_engine_set_hash(eng, br_sha1_ID, &br_sha1_vtable); + br_ssl_engine_set_hash(eng, br_sha224_ID, &br_sha224_vtable); + br_ssl_engine_set_hash(eng, br_sha256_ID, &br_sha256_vtable); + br_ssl_engine_set_hash(eng, br_sha384_ID, &br_sha384_vtable); + br_ssl_engine_set_hash(eng, br_sha512_ID, &br_sha512_vtable); + } + + static void br_x509_minimal_install_hashes(br_x509_minimal_context *x509) + { + br_x509_minimal_set_hash(x509, br_md5_ID, &br_md5_vtable); + br_x509_minimal_set_hash(x509, br_sha1_ID, &br_sha1_vtable); + br_x509_minimal_set_hash(x509, br_sha224_ID, &br_sha224_vtable); + br_x509_minimal_set_hash(x509, br_sha256_ID, &br_sha256_vtable); + br_x509_minimal_set_hash(x509, br_sha384_ID, &br_sha384_vtable); + br_x509_minimal_set_hash(x509, br_sha512_ID, &br_sha512_vtable); + } + + // Default initializion for our SSL clients + static void br_ssl_client_base_init(br_ssl_client_context *cc, const uint16_t *cipher_list, int cipher_cnt) + { + uint16_t suites[cipher_cnt]; + memcpy_P(suites, cipher_list, cipher_cnt * sizeof(cipher_list[0])); + br_ssl_client_zero(cc); + br_ssl_engine_add_flags(&cc->eng, BR_OPT_NO_RENEGOTIATION); // forbid SSL renegotiation, as we free the Private Key after handshake + br_ssl_engine_set_versions(&cc->eng, BR_TLS10, BR_TLS12); + br_ssl_engine_set_suites(&cc->eng, suites, (sizeof suites) / (sizeof suites[0])); + br_ssl_client_set_default_rsapub(cc); + br_ssl_engine_set_default_rsavrfy(&cc->eng); +#ifndef BEARSSL_SSL_BASIC + br_ssl_engine_set_default_ecdsa(&cc->eng); +#endif + br_ssl_client_install_hashes(&cc->eng); + br_ssl_engine_set_prf10(&cc->eng, &br_tls10_prf); + br_ssl_engine_set_prf_sha256(&cc->eng, &br_tls12_sha256_prf); + br_ssl_engine_set_prf_sha384(&cc->eng, &br_tls12_sha384_prf); + br_ssl_engine_set_default_aes_cbc(&cc->eng); +#ifndef BEARSSL_SSL_BASIC + br_ssl_engine_set_default_aes_gcm(&cc->eng); + br_ssl_engine_set_default_aes_ccm(&cc->eng); + br_ssl_engine_set_default_des_cbc(&cc->eng); + br_ssl_engine_set_default_chapol(&cc->eng); +#endif + } + + // BearSSL doesn't define a true insecure decoder, so we make one ourselves + // from the simple parser. It generates the issuer and subject hashes and + // the SHA1 fingerprint, only one (or none!) of which will be used to + // "verify" the certificate. + + // Private x509 decoder state + struct br_x509_insecure_context + { + const br_x509_class *vtable; + bool done_cert; + const uint8_t *match_fingerprint; + br_sha1_context sha1_cert; + bool allow_self_signed; + br_sha256_context sha256_subject; + br_sha256_context sha256_issuer; + br_x509_decoder_context_libmail ctx; + }; + + // Callback for the x509_minimal subject DN + static void insecure_subject_dn_append(void *ctx, const void *buf, size_t len) + { + br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; + br_sha256_update(&xc->sha256_subject, buf, len); + } + + // Callback for the x509_minimal issuer DN + static void insecure_issuer_dn_append(void *ctx, const void *buf, size_t len) + { + br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; + br_sha256_update(&xc->sha256_issuer, buf, len); + } + + // Callback for each certificate present in the chain (but only operates + // on the first one by design). + static void insecure_start_cert(const br_x509_class **ctx, uint32_t length) + { + (void)ctx; + (void)length; + } + + // Callback for each byte stream in the chain. Only process first cert. + static void insecure_append(const br_x509_class **ctx, const unsigned char *buf, size_t len) + { + br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; + // Don't process anything but the first certificate in the chain + if (!xc->done_cert) + { + br_sha1_update(&xc->sha1_cert, buf, len); + br_x509_decoder_push_libmail(&xc->ctx, (const void *)buf, len); + } + } + // Callback on the first byte of any certificate + static void insecure_start_chain(const br_x509_class **ctx, const char *server_name) + { + br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; +#if defined(USE_EMBED_SSL_ENGINE) + br_x509_decoder_init_libmail(&xc->ctx, insecure_subject_dn_append, xc, insecure_issuer_dn_append, xc); +#elif defined(ESP32) || defined(USE_LIB_SSL_ENGINE) + br_x509_decoder_init_libmail(&xc->ctx, insecure_subject_dn_append, xc); +#endif + xc->done_cert = false; + br_sha1_init(&xc->sha1_cert); + br_sha256_init(&xc->sha256_subject); + br_sha256_init(&xc->sha256_issuer); + (void)server_name; + } + + // Callback on individual cert end. + static void insecure_end_cert(const br_x509_class **ctx) + { + br_x509_insecure_context *xc = (br_x509_insecure_context *)ctx; + xc->done_cert = true; + } + + // Callback when complete chain has been parsed. + // Return 0 on validation success, !0 on validation error + static unsigned insecure_end_chain(const br_x509_class **ctx) + { + const br_x509_insecure_context *xc = (const br_x509_insecure_context *)ctx; + if (!xc->done_cert) + { + // BSSL_BSSL_SSL_Client_DEBUG_PRINTF("insecure_end_chain: No cert seen\n"); + return 1; // error + } + + // Handle SHA1 fingerprint matching + char res[20]; + br_sha1_out(&xc->sha1_cert, res); + if (xc->match_fingerprint && memcmp(res, xc->match_fingerprint, sizeof(res))) + { + + return BR_ERR_X509_NOT_TRUSTED; + } + + // Handle self-signer certificate acceptance + char res_issuer[32]; + char res_subject[32]; + br_sha256_out(&xc->sha256_issuer, res_issuer); + br_sha256_out(&xc->sha256_subject, res_subject); + if (xc->allow_self_signed && memcmp(res_subject, res_issuer, sizeof(res_issuer))) + { + // BSSL_BSSL_SSL_Client_DEBUG_PRINTF("insecure_end_chain: Didn't get self-signed cert\n"); + return BR_ERR_X509_NOT_TRUSTED; + } + + // Default (no validation at all) or no errors in prior checks = success. + return 0; + } + + // Return the public key from the validator (set by x509_minimal) + static const br_x509_pkey *insecure_get_pkey(const br_x509_class *const *ctx, unsigned *usages) + { + const br_x509_insecure_context *xc = (const br_x509_insecure_context *)ctx; + if (usages != nullptr) + { + *usages = BR_KEYTYPE_KEYX | BR_KEYTYPE_SIGN; // I said we were insecure! + } + return &xc->ctx.pkey; + } + } + +}; +#endif + #endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/Build_Options.h b/lib/libesp32/ESP-Mail-Client/src/extras/Build_Options.h index a2251f896..d90111389 100644 --- a/lib/libesp32/ESP-Mail-Client/src/extras/Build_Options.h +++ b/lib/libesp32/ESP-Mail-Client/src/extras/Build_Options.h @@ -1,52 +1,52 @@ -#ifndef BUILD_OPTIONS_H -#define BUILD_OPTIONS_H - -#if defined(DISABLE_ALL_OPTIONS) -#undef ENABLE_NTP_TIME -#undef ENABLE_ERROR_STRING -#undef ENABLE_IMAP -#undef ENABLE_SMTP -#undef ESP_MAIL_USE_PSRAM -#undef ESP_MAIL_DEFAULT_SD_FS -#undef ESP_MAIL_CARD_TYPE_SD -#undef ESP_MAIL_CARD_TYPE_SD_MMC -#undef ESP_MAIL_DEFAULT_FLASH_FS -#undef ESP_MAIL_DEFAULT_DEBUG_PORT -#endif - -#if defined(DISABLE_NTP_TIME) -#undef ENABLE_NTP_TIME -#endif - -#if defined(DISABLE_ERROR_STRING) -#undef ENABLE_ERROR_STRING -#endif - -#if defined(DISABLE_IMAP) -#undef ENABLE_IMAP -#endif - -#if defined(DISABLE_SMTP) -#undef ENABLE_SMTP -#endif - -#if defined(DISABLE_PSRAM) -#undef ESP_MAIL_USE_PSRAM -#endif - -#if defined(DISABLE_SD) -#undef ESP_MAIL_DEFAULT_SD_FS -#undef ESP_MAIL_CARD_TYPE_SD_MMC -#undef ESP_MAIL_DEFAULT_FLASH_FS -#endif - -#if defined(DISABLE_FLASH) -#undef ESP_MAIL_DEFAULT_FLASH_FS -#undef ESP_MAIL_FORMAT_FLASH_IF_MOUNT_FAILED -#endif - -#if defined(ESP_MAIL_DEFAULT_DEBUG_PORT) -#undef ESP_MAIL_DEFAULT_DEBUG_PORT -#endif - +#ifndef BUILD_OPTIONS_H +#define BUILD_OPTIONS_H + +#if defined(DISABLE_ALL_OPTIONS) +#undef ENABLE_NTP_TIME +#undef ENABLE_ERROR_STRING +#undef ENABLE_IMAP +#undef ENABLE_SMTP +#undef ESP_MAIL_USE_PSRAM +#undef ESP_MAIL_DEFAULT_SD_FS +#undef ESP_MAIL_CARD_TYPE_SD +#undef ESP_MAIL_CARD_TYPE_SD_MMC +#undef ESP_MAIL_DEFAULT_FLASH_FS +#undef ESP_MAIL_DEFAULT_DEBUG_PORT +#endif + +#if defined(DISABLE_NTP_TIME) +#undef ENABLE_NTP_TIME +#endif + +#if defined(DISABLE_ERROR_STRING) +#undef ENABLE_ERROR_STRING +#endif + +#if defined(DISABLE_IMAP) +#undef ENABLE_IMAP +#endif + +#if defined(DISABLE_SMTP) +#undef ENABLE_SMTP +#endif + +#if defined(DISABLE_PSRAM) +#undef ESP_MAIL_USE_PSRAM +#endif + +#if defined(DISABLE_SD) +#undef ESP_MAIL_DEFAULT_SD_FS +#undef ESP_MAIL_CARD_TYPE_SD_MMC +#undef ESP_MAIL_DEFAULT_FLASH_FS +#endif + +#if defined(DISABLE_FLASH) +#undef ESP_MAIL_DEFAULT_FLASH_FS +#undef ESP_MAIL_FORMAT_FLASH_IF_MOUNT_FAILED +#endif + +#if defined(ESP_MAIL_DEFAULT_DEBUG_PORT) +#undef ESP_MAIL_DEFAULT_DEBUG_PORT +#endif + #endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/ESP8266_Supports.h b/lib/libesp32/ESP-Mail-Client/src/extras/ESP8266_Supports.h index 5604690c6..db68d01e6 100644 --- a/lib/libesp32/ESP-Mail-Client/src/extras/ESP8266_Supports.h +++ b/lib/libesp32/ESP-Mail-Client/src/extras/ESP8266_Supports.h @@ -1,52 +1,52 @@ -#ifndef ESP8266_SUPPORTS_H -#define ESP8266_SUPPORTS_H -#include -#include "MB_MCU.h" -#if defined(ESP8266) || defined(MB_ARDUINO_PICO) - -#include - -//__GNUC__ -//__GNUC_MINOR__ -//__GNUC_PATCHLEVEL__ - -#ifdef __GNUC__ -#if __GNUC__ > 4 || __GNUC__ == 10 -#if defined(ARDUINO_ESP8266_GIT_VER) -#if ARDUINO_ESP8266_GIT_VER > 0 -#define ESP8266_CORE_SDK_V3_X_X -#endif -#endif -#endif -#endif - -#if defined __has_include - -#if __has_include() -#include -#endif - -#if __has_include()&& defined(ENABLE_ESP8266_ENC28J60_ETH) -#define INC_ENC28J60_LWIP -#include -#endif - -#if __has_include() && defined(ENABLE_ESP8266_W5100_ETH) -#define INC_W5100_LWIP -#include -#endif - -#if __has_include()&& defined(ENABLE_ESP8266_W5500_ETH) -#define INC_W5500_LWIP -#include -#endif - -#if defined(MB_ARDUINO_PICO) - -#endif - -#endif - -#endif - +#ifndef ESP8266_SUPPORTS_H +#define ESP8266_SUPPORTS_H +#include +#include "MB_MCU.h" +#if defined(ESP8266) || defined(MB_ARDUINO_PICO) + +#include + +//__GNUC__ +//__GNUC_MINOR__ +//__GNUC_PATCHLEVEL__ + +#ifdef __GNUC__ +#if __GNUC__ > 4 || __GNUC__ == 10 +#if defined(ARDUINO_ESP8266_GIT_VER) +#if ARDUINO_ESP8266_GIT_VER > 0 +#define ESP8266_CORE_SDK_V3_X_X +#endif +#endif +#endif +#endif + +#if defined __has_include + +#if __has_include() +#include +#endif + +#if __has_include()&& defined(ENABLE_ESP8266_ENC28J60_ETH) +#define INC_ENC28J60_LWIP +#include +#endif + +#if __has_include() && defined(ENABLE_ESP8266_W5100_ETH) +#define INC_W5100_LWIP +#include +#endif + +#if __has_include()&& defined(ENABLE_ESP8266_W5500_ETH) +#define INC_W5500_LWIP +#include +#endif + +#if defined(MB_ARDUINO_PICO) + +#endif + +#endif + +#endif + #endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS.h b/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS.h index caed959a9..886350962 100644 --- a/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS.h +++ b/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS.h @@ -1,353 +1,353 @@ -/** - * The MB_FS, filesystems wrapper class v1.0.16 - * - * This wrapper class is for SD and Flash filesystems interface which supports SdFat (//https://github.com/greiman/SdFat) - * - * Created June 14, 2023 - * - * The MIT License (MIT) - * Copyright (c) 2023 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person returning 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 MBFS_CLASS_H -#define MBFS_CLASS_H - -#include -#include -#include "MB_FS_Interfaces.h" -#include MB_STRING_INCLUDE_CLASS - - -#define MB_FS_ERROR_FILE_IO_ERROR -300 -#define MB_FS_ERROR_FILE_NOT_FOUND -301 -#define MB_FS_ERROR_FLASH_STORAGE_IS_NOT_READY -302 -#define MB_FS_ERROR_SD_STORAGE_IS_NOT_READY -303 -#define MB_FS_ERROR_FILE_STILL_OPENED -304 - - -#define mbfs_file_type mb_fs_mem_storage_type -#define mbfs_flash mb_fs_mem_storage_type_flash -#define mbfs_sd mb_fs_mem_storage_type_sd -#define mbfs_undefined mb_fs_mem_storage_type_undefined - -#define mbfs_type (mbfs_file_type) - -typedef enum -{ - mb_fs_mem_storage_type_undefined, - mb_fs_mem_storage_type_flash, - mb_fs_mem_storage_type_sd -} mb_fs_mem_storage_type; - -typedef enum -{ - mb_fs_open_mode_undefined = -1, - mb_fs_open_mode_read = 0, - mb_fs_open_mode_write, - mb_fs_open_mode_append -} mb_fs_open_mode; - -extern FS *ufsp; - -class MB_FS { - -public: - MB_FS() {} - ~MB_FS() {} - - - bool sdBegin(int ss = -1, int sck = -1, int miso = -1, int mosi = -1, uint32_t frequency = 4000000) { - mfsp = ufsp; - return true; - } - - bool sdSPIBegin(int ss, SPIClass *spiConfig, uint32_t frequency) { - mfsp = ufsp; - return true; - } - - // Check the mounting status of Flash storage. - bool flashReady() { - return true; - } - - // Check the mounting status of SD storage. - bool sdReady() { - return true; - } - - // Check the mounting status of Flash or SD storage with mb_fs_mem_storage_type. - bool checkStorageReady(mbfs_file_type type) { - return true; - } - - int open(const MB_String &filename, mbfs_file_type type, mb_fs_open_mode mode) { - char fmode[8]; - switch (mode) { - case mb_fs_open_mode_read: - strcpy(fmode, "r"); - break; - case mb_fs_open_mode_write: - strcpy(fmode, "w"); - break; - case mb_fs_open_mode_append: - strcpy(fmode, "a"); - break; - } - flash_file = filename; - mfsp = ufsp; - mb_File = mfsp->open(filename.c_str(), fmode); - //Serial.printf(">>> 1 %s, %s, %d ", filename.c_str(), fmode, mb_File); - return mb_File; - } - - bool ready(mbfs_file_type type) { - return true; - } - - int size(mbfs_file_type type) { - return mb_File.size(); - } - - // Check if file is ready to read/write. - int available(mbfs_file_type type) { - return mb_File.available(); - } - - // Read byte array. Return the number of bytes that completed read or negative value for error. - int read(mbfs_file_type type, uint8_t *buf, size_t len) { - return mb_File.read(buf, len); - } - - // Print char array. Return the number of bytes that completed write or negative value for error. - int print(mbfs_file_type type, const char *str) { - return mb_File.print(str); - } - - // Print char array with new line. Return the number of bytes that completed write or negative value for error. - int println(mbfs_file_type type, const char *str) { - return mb_File.print(str); - } - - // Print integer. Return the number of bytes that completed write or negative value for error. - int print(mbfs_file_type type, int v) { - return mb_File.print(v); - } - - // Print integer with newline. Return the number of bytes that completed write or negative value for error. - int println(mbfs_file_type type, int v) { - return mb_File.print(v); - } - - int print(mbfs_file_type type, unsigned int v) { - return mb_File.print(v); - } - - // Print integer with newline. Return the number of bytes that completed write or negative value for error. - int println(mbfs_file_type type, unsigned int v) { - return mb_File.print(v); - } - - // Write byte array. Return the number of bytes that completed write or negative value for error. - int write(mbfs_file_type type, uint8_t *buf, size_t len) { - return mb_File.write(buf, len); - } - - // Close file. - void close(mbfs_file_type type) { - mb_File.close(); - } - - // Check file existence. - bool existed(const MB_String &filename, mbfs_file_type type) { - return mfsp->exists(filename.c_str()); - } - - // Seek to position in file. - bool seek(mbfs_file_type type, int pos) { - return mb_File.seek(pos); - } - - // Read byte. Return the 1 for completed read or negative value for error. - int read(mbfs_file_type type) { - return mb_File.read(); - } - - // Write byte. Return the 1 for completed write or negative value for error. - int write(mbfs_file_type type, uint8_t v) { - return mb_File.write(v); - } - - bool remove(const MB_String &filename, mbfs_file_type type) { - return mfsp->remove(filename.c_str()); - } - - fs::File &getFlashFile() { - return mb_File; - } - - // Get name of opened file. - const char *name(mbfs_file_type type) { - return flash_file.c_str(); - } - - // Calculate CRC16 of byte array. - uint16_t calCRC(const char *buf) { - uint8_t x; - uint16_t crc = 0xFFFF; - - int length = (int)strlen(buf); - - while (length--) { - x = crc >> 8 ^ *buf++; - x ^= x >> 4; - crc = (crc << 8) ^ ((uint16_t)(x << 12)) ^ ((uint16_t)(x << 5)) ^ ((uint16_t)x); - } - return crc; - } - - // Free reserved memory at pointer. - void delP(void *ptr) { - void **p = (void **)ptr; - if (*p) { - free(*p); - *p = 0; - } - } - - // Allocate memory - void *newP(size_t len, bool clear = true) { - void *p; - size_t newLen = getReservedLen(len); -#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) - - if (ESP.getPsramSize() > 0) - p = (void *)ps_malloc(newLen); - else - p = (void *)malloc(newLen); - - if (!p) - return NULL; - -#else - -#if defined(ESP8266_USE_EXTERNAL_HEAP) - ESP.setExternalHeap(); -#endif - - p = (void *)malloc(newLen); - bool nn = p ? true : false; - -#if defined(ESP8266_USE_EXTERNAL_HEAP) - ESP.resetHeap(); -#endif - - if (!nn) - return NULL; - -#endif - if (clear) - memset(p, 0, newLen); - return p; - } - - size_t getReservedLen(size_t len) { - int blen = len + 1; - - int newlen = (blen / 4) * 4; - - if (newlen < blen) - newlen += 4; - - return (size_t)newlen; - } - - void createDirs(MB_String dirs, mbfs_file_type type) { - if (!longNameSupported()) - return; - - MB_String dir; - int count = 0; - int lastPos = 0; - for (size_t i = 0; i < dirs.length(); i++) { - dir.append(1, dirs[i]); - count++; - if (dirs[i] == '/' && i > 0) { - if (dir.length() > 0) - { - - lastPos = dir.length() - 1; - -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash) - MBFS_FLASH_FS.mkdir(dir.substr(0, dir.length() - 1).c_str()); -#endif - -#if defined(MBFS_SD_FS) - if (type == mbfs_sd) - MBFS_SD_FS.mkdir(dir.substr(0, dir.length() - 1).c_str()); -#endif - } - count = 0; - } - } - - if (count > 0) - { - if (dir.find('.', lastPos) == MB_String::npos) - { -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash) - MBFS_FLASH_FS.mkdir(dir.c_str()); -#endif - -#if defined(MBFS_SD_FS) - if (type == mbfs_sd) - MBFS_SD_FS.mkdir(dir.c_str()); -#endif - } - } - - dir.clear(); - } - - bool longNameSupported() { - -#if defined(MBFS_SDFAT_ENABLED) || defined(MBFS_FLASH_FS) - return true; -#endif - -#if defined(MBFS_SD_FS) && (defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO)) - return true; -#endif - - return false; - } - -private: - uint16_t flash_filename_crc = 0; - MB_String flash_file, sd_file; - FS *mfsp; - File mb_File; - -}; - -#endif +/** + * The MB_FS, filesystems wrapper class v1.0.16 + * + * This wrapper class is for SD and Flash filesystems interface which supports SdFat (//https://github.com/greiman/SdFat) + * + * Created June 14, 2023 + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person returning 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 MBFS_CLASS_H +#define MBFS_CLASS_H + +#include +#include +#include "MB_FS_Interfaces.h" +#include MB_STRING_INCLUDE_CLASS + + +#define MB_FS_ERROR_FILE_IO_ERROR -300 +#define MB_FS_ERROR_FILE_NOT_FOUND -301 +#define MB_FS_ERROR_FLASH_STORAGE_IS_NOT_READY -302 +#define MB_FS_ERROR_SD_STORAGE_IS_NOT_READY -303 +#define MB_FS_ERROR_FILE_STILL_OPENED -304 + + +#define mbfs_file_type mb_fs_mem_storage_type +#define mbfs_flash mb_fs_mem_storage_type_flash +#define mbfs_sd mb_fs_mem_storage_type_sd +#define mbfs_undefined mb_fs_mem_storage_type_undefined + +#define mbfs_type (mbfs_file_type) + +typedef enum +{ + mb_fs_mem_storage_type_undefined, + mb_fs_mem_storage_type_flash, + mb_fs_mem_storage_type_sd +} mb_fs_mem_storage_type; + +typedef enum +{ + mb_fs_open_mode_undefined = -1, + mb_fs_open_mode_read = 0, + mb_fs_open_mode_write, + mb_fs_open_mode_append +} mb_fs_open_mode; + +extern FS *ufsp; + +class MB_FS { + +public: + MB_FS() {} + ~MB_FS() {} + + + bool sdBegin(int ss = -1, int sck = -1, int miso = -1, int mosi = -1, uint32_t frequency = 4000000) { + mfsp = ufsp; + return true; + } + + bool sdSPIBegin(int ss, SPIClass *spiConfig, uint32_t frequency) { + mfsp = ufsp; + return true; + } + + // Check the mounting status of Flash storage. + bool flashReady() { + return true; + } + + // Check the mounting status of SD storage. + bool sdReady() { + return true; + } + + // Check the mounting status of Flash or SD storage with mb_fs_mem_storage_type. + bool checkStorageReady(mbfs_file_type type) { + return true; + } + + int open(const MB_String &filename, mbfs_file_type type, mb_fs_open_mode mode) { + char fmode[8]; + switch (mode) { + case mb_fs_open_mode_read: + strcpy(fmode, "r"); + break; + case mb_fs_open_mode_write: + strcpy(fmode, "w"); + break; + case mb_fs_open_mode_append: + strcpy(fmode, "a"); + break; + } + flash_file = filename; + mfsp = ufsp; + mb_File = mfsp->open(filename.c_str(), fmode); + //Serial.printf(">>> 1 %s, %s, %d ", filename.c_str(), fmode, mb_File); + return mb_File; + } + + bool ready(mbfs_file_type type) { + return true; + } + + int size(mbfs_file_type type) { + return mb_File.size(); + } + + // Check if file is ready to read/write. + int available(mbfs_file_type type) { + return mb_File.available(); + } + + // Read byte array. Return the number of bytes that completed read or negative value for error. + int read(mbfs_file_type type, uint8_t *buf, size_t len) { + return mb_File.read(buf, len); + } + + // Print char array. Return the number of bytes that completed write or negative value for error. + int print(mbfs_file_type type, const char *str) { + return mb_File.print(str); + } + + // Print char array with new line. Return the number of bytes that completed write or negative value for error. + int println(mbfs_file_type type, const char *str) { + return mb_File.print(str); + } + + // Print integer. Return the number of bytes that completed write or negative value for error. + int print(mbfs_file_type type, int v) { + return mb_File.print(v); + } + + // Print integer with newline. Return the number of bytes that completed write or negative value for error. + int println(mbfs_file_type type, int v) { + return mb_File.print(v); + } + + int print(mbfs_file_type type, unsigned int v) { + return mb_File.print(v); + } + + // Print integer with newline. Return the number of bytes that completed write or negative value for error. + int println(mbfs_file_type type, unsigned int v) { + return mb_File.print(v); + } + + // Write byte array. Return the number of bytes that completed write or negative value for error. + int write(mbfs_file_type type, uint8_t *buf, size_t len) { + return mb_File.write(buf, len); + } + + // Close file. + void close(mbfs_file_type type) { + mb_File.close(); + } + + // Check file existence. + bool existed(const MB_String &filename, mbfs_file_type type) { + return mfsp->exists(filename.c_str()); + } + + // Seek to position in file. + bool seek(mbfs_file_type type, int pos) { + return mb_File.seek(pos); + } + + // Read byte. Return the 1 for completed read or negative value for error. + int read(mbfs_file_type type) { + return mb_File.read(); + } + + // Write byte. Return the 1 for completed write or negative value for error. + int write(mbfs_file_type type, uint8_t v) { + return mb_File.write(v); + } + + bool remove(const MB_String &filename, mbfs_file_type type) { + return mfsp->remove(filename.c_str()); + } + + fs::File &getFlashFile() { + return mb_File; + } + + // Get name of opened file. + const char *name(mbfs_file_type type) { + return flash_file.c_str(); + } + + // Calculate CRC16 of byte array. + uint16_t calCRC(const char *buf) { + uint8_t x; + uint16_t crc = 0xFFFF; + + int length = (int)strlen(buf); + + while (length--) { + x = crc >> 8 ^ *buf++; + x ^= x >> 4; + crc = (crc << 8) ^ ((uint16_t)(x << 12)) ^ ((uint16_t)(x << 5)) ^ ((uint16_t)x); + } + return crc; + } + + // Free reserved memory at pointer. + void delP(void *ptr) { + void **p = (void **)ptr; + if (*p) { + free(*p); + *p = 0; + } + } + + // Allocate memory + void *newP(size_t len, bool clear = true) { + void *p; + size_t newLen = getReservedLen(len); +#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) + + if (ESP.getPsramSize() > 0) + p = (void *)ps_malloc(newLen); + else + p = (void *)malloc(newLen); + + if (!p) + return NULL; + +#else + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + ESP.setExternalHeap(); +#endif + + p = (void *)malloc(newLen); + bool nn = p ? true : false; + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + ESP.resetHeap(); +#endif + + if (!nn) + return NULL; + +#endif + if (clear) + memset(p, 0, newLen); + return p; + } + + size_t getReservedLen(size_t len) { + int blen = len + 1; + + int newlen = (blen / 4) * 4; + + if (newlen < blen) + newlen += 4; + + return (size_t)newlen; + } + + void createDirs(MB_String dirs, mbfs_file_type type) { + if (!longNameSupported()) + return; + + MB_String dir; + int count = 0; + int lastPos = 0; + for (size_t i = 0; i < dirs.length(); i++) { + dir.append(1, dirs[i]); + count++; + if (dirs[i] == '/' && i > 0) { + if (dir.length() > 0) + { + + lastPos = dir.length() - 1; + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash) + MBFS_FLASH_FS.mkdir(dir.substr(0, dir.length() - 1).c_str()); +#endif + +#if defined(MBFS_SD_FS) + if (type == mbfs_sd) + MBFS_SD_FS.mkdir(dir.substr(0, dir.length() - 1).c_str()); +#endif + } + count = 0; + } + } + + if (count > 0) + { + if (dir.find('.', lastPos) == MB_String::npos) + { +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash) + MBFS_FLASH_FS.mkdir(dir.c_str()); +#endif + +#if defined(MBFS_SD_FS) + if (type == mbfs_sd) + MBFS_SD_FS.mkdir(dir.c_str()); +#endif + } + } + + dir.clear(); + } + + bool longNameSupported() { + +#if defined(MBFS_SDFAT_ENABLED) || defined(MBFS_FLASH_FS) + return true; +#endif + +#if defined(MBFS_SD_FS) && (defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO)) + return true; +#endif + + return false; + } + +private: + uint16_t flash_filename_crc = 0; + MB_String flash_file, sd_file; + FS *mfsp; + File mb_File; + +}; + +#endif diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS_Interfaces.h b/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS_Interfaces.h index 9bdc1e75d..2d9a8bace 100644 --- a/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS_Interfaces.h +++ b/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS_Interfaces.h @@ -1,94 +1,94 @@ -#pragma once - -/* Convert specific definitions to MB_FS definitions */ -#ifndef MB_FS_INTERFACES_H -#define MB_FS_INTERFACES_H - -#include - -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wdeprecated-declarations" - -// include definitions file -#include "./ESP_Mail_FS.h" - -// 1. ESP_MAIL_DEFAULT_FLASH_FS -> MBFS_FLASH_FS -#if defined ESP_MAIL_DEFAULT_FLASH_FS -#define MBFS_FLASH_FS ESP_MAIL_DEFAULT_FLASH_FS -#endif - -// 2. ESP_MAIL_DEFAULT_SD_FS -> MBFS_SD_FS -#if defined ESP_MAIL_DEFAULT_SD_FS -#define MBFS_SD_FS ESP_MAIL_DEFAULT_SD_FS -#endif - -// 3. ESP_MAIL_CARD_TYPE_SD -> MBFS_CARD_TYPE_SD -#if defined(ESP_MAIL_CARD_TYPE_SD) -#define MBFS_CARD_TYPE_SD /* */ ESP_MAIL_CARD_TYPE_SD -#endif - -// 4. ESP_MAIL_CARD_TYPE_SD_MMC -> MBFS_CARD_TYPE_SD_MMC -#if defined(ESP_MAIL_CARD_TYPE_SD_MMC) -#define MBFS_CARD_TYPE_SD_MMC /* */ ESP_MAIL_CARD_TYPE_SD_MMC -#endif - -// 5. ESP_MAIL_FORMAT_FLASH_IF_MOUNT_FAILED -> MBFS_FORMAT_FLASH -#if defined(ESP_MAIL_FORMAT_FLASH_IF_MOUNT_FAILED) -#define MBFS_FORMAT_FLASH /* */ ESP_MAIL_FORMAT_FLASH_IF_MOUNT_FAILED -#endif - -#if defined(MBFS_SD_FS) || defined(MBFS_FLASH_FS) -#define MBFS_USE_FILE_STORAGE -#endif - -// Only SdFat library from Bill Greiman -#if defined(ESP32) && defined(SD_FAT_VERSION) && defined(SD_FAT_VERSION_STR) && defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) -#define MBFS_ESP32_SDFAT_ENABLED -#ifndef ESP_MAIL_USE_SDFAT -#define ESP_MAIL_USE_SDFAT -#endif -#endif - -// Only SdFat library from Bill Greiman -#if !defined(ESP32) && !defined(ESP8266) && !defined(ARDUINO_ARCH_RP2040) && defined(SD_FAT_VERSION) && defined(SD_FAT_VERSION_STR) && defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) -#define MBFS_SDFAT_ENABLED -#ifndef ESP_MAIL_USE_SDFAT -#define ESP_MAIL_USE_SDFAT -#endif -#endif - -// For MB_String -#if defined(ESP_MAIL_USE_PSRAM) -#define MB_STRING_USE_PSRAM -#endif - -#if defined(MBFS_SD_FS) - -#if !defined(ESP_MAIL_SD_FILE) - -#if defined(MBFS_ESP32_SDFAT_ENABLED) -#define MBFS_SD_FILE SdFile -#else -#if defined(ESP32) || defined(ESP8266) || defined(ARDUINO_ARCH_RP2040) -#define MBFS_SD_FILE fs::File -#else -#define MBFS_SD_FILE File -#endif - -#endif - -#else - -#define MBFS_SD_FILE ESP_MAIL_SD_FILE - -#endif - -#endif - -#ifndef MB_STRING_INCLUDE_CLASS -#define MB_STRING_INCLUDE_CLASS "MB_String.h" -#endif - - - -#endif /* MB_FS_INTERFACES_H */ +#pragma once + +/* Convert specific definitions to MB_FS definitions */ +#ifndef MB_FS_INTERFACES_H +#define MB_FS_INTERFACES_H + +#include + +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" + +// include definitions file +#include "./ESP_Mail_FS.h" + +// 1. ESP_MAIL_DEFAULT_FLASH_FS -> MBFS_FLASH_FS +#if defined ESP_MAIL_DEFAULT_FLASH_FS +#define MBFS_FLASH_FS ESP_MAIL_DEFAULT_FLASH_FS +#endif + +// 2. ESP_MAIL_DEFAULT_SD_FS -> MBFS_SD_FS +#if defined ESP_MAIL_DEFAULT_SD_FS +#define MBFS_SD_FS ESP_MAIL_DEFAULT_SD_FS +#endif + +// 3. ESP_MAIL_CARD_TYPE_SD -> MBFS_CARD_TYPE_SD +#if defined(ESP_MAIL_CARD_TYPE_SD) +#define MBFS_CARD_TYPE_SD /* */ ESP_MAIL_CARD_TYPE_SD +#endif + +// 4. ESP_MAIL_CARD_TYPE_SD_MMC -> MBFS_CARD_TYPE_SD_MMC +#if defined(ESP_MAIL_CARD_TYPE_SD_MMC) +#define MBFS_CARD_TYPE_SD_MMC /* */ ESP_MAIL_CARD_TYPE_SD_MMC +#endif + +// 5. ESP_MAIL_FORMAT_FLASH_IF_MOUNT_FAILED -> MBFS_FORMAT_FLASH +#if defined(ESP_MAIL_FORMAT_FLASH_IF_MOUNT_FAILED) +#define MBFS_FORMAT_FLASH /* */ ESP_MAIL_FORMAT_FLASH_IF_MOUNT_FAILED +#endif + +#if defined(MBFS_SD_FS) || defined(MBFS_FLASH_FS) +#define MBFS_USE_FILE_STORAGE +#endif + +// Only SdFat library from Bill Greiman +#if defined(ESP32) && defined(SD_FAT_VERSION) && defined(SD_FAT_VERSION_STR) && defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) +#define MBFS_ESP32_SDFAT_ENABLED +#ifndef ESP_MAIL_USE_SDFAT +#define ESP_MAIL_USE_SDFAT +#endif +#endif + +// Only SdFat library from Bill Greiman +#if !defined(ESP32) && !defined(ESP8266) && !defined(ARDUINO_ARCH_RP2040) && defined(SD_FAT_VERSION) && defined(SD_FAT_VERSION_STR) && defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) +#define MBFS_SDFAT_ENABLED +#ifndef ESP_MAIL_USE_SDFAT +#define ESP_MAIL_USE_SDFAT +#endif +#endif + +// For MB_String +#if defined(ESP_MAIL_USE_PSRAM) +#define MB_STRING_USE_PSRAM +#endif + +#if defined(MBFS_SD_FS) + +#if !defined(ESP_MAIL_SD_FILE) + +#if defined(MBFS_ESP32_SDFAT_ENABLED) +#define MBFS_SD_FILE SdFile +#else +#if defined(ESP32) || defined(ESP8266) || defined(ARDUINO_ARCH_RP2040) +#define MBFS_SD_FILE fs::File +#else +#define MBFS_SD_FILE File +#endif + +#endif + +#else + +#define MBFS_SD_FILE ESP_MAIL_SD_FILE + +#endif + +#endif + +#ifndef MB_STRING_INCLUDE_CLASS +#define MB_STRING_INCLUDE_CLASS "MB_String.h" +#endif + + + +#endif /* MB_FS_INTERFACES_H */ diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS_org.h b/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS_org.h index 682a3d78e..b49c60c48 100644 --- a/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS_org.h +++ b/lib/libesp32/ESP-Mail-Client/src/extras/MB_FS_org.h @@ -1,1139 +1,1139 @@ -/** - * The MB_FS, filesystems wrapper class v1.0.16 - * - * This wrapper class is for SD and Flash filesystems interface which supports SdFat (//https://github.com/greiman/SdFat) - * - * Created June 14, 2023 - * - * The MIT License (MIT) - * Copyright (c) 2023 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person returning 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. - */ - -#if 0 -#ifndef MBFS_CLASS_H -#define MBFS_CLASS_H - -#include -#include "MB_MCU.h" - -#define FS_NO_GLOBALS -#if defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO) -#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) -#include -#endif -#endif -#include "MB_FS_Interfaces.h" -#include MB_STRING_INCLUDE_CLASS - -#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) -#include "SPI.h" -#endif - -#if defined(ESP32) && __has_include() -#ifdef _LITTLEFS_H_ -#define MB_FS_USE_POSIX_STAT -#include -namespace mb_fs_ns -{ - inline bool exists(const char *mountPoint, const char *filename) - { - MB_String path = mountPoint; - path += filename; - struct stat st; - return stat(path.c_str(), &st) == 0; - } -}; -#endif -#endif - -using namespace mb_string; - -#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) -#include -#endif - -#define MB_FS_ERROR_FILE_IO_ERROR -300 -#define MB_FS_ERROR_FILE_NOT_FOUND -301 -#define MB_FS_ERROR_FLASH_STORAGE_IS_NOT_READY -302 -#define MB_FS_ERROR_SD_STORAGE_IS_NOT_READY -303 -#define MB_FS_ERROR_FILE_STILL_OPENED -304 - -typedef enum -{ - mb_fs_mem_storage_type_undefined, - mb_fs_mem_storage_type_flash, - mb_fs_mem_storage_type_sd -} mb_fs_mem_storage_type; - -typedef enum -{ - mb_fs_open_mode_undefined = -1, - mb_fs_open_mode_read = 0, - mb_fs_open_mode_write, - mb_fs_open_mode_append -} mb_fs_open_mode; - -#define mbfs_file_type mb_fs_mem_storage_type -#define mbfs_flash mb_fs_mem_storage_type_flash -#define mbfs_sd mb_fs_mem_storage_type_sd -#define mbfs_undefined mb_fs_mem_storage_type_undefined - -#define mbfs_type (mbfs_file_type) - -#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) -#if !defined(MBFS_SDFAT_ENABLED) -struct mbfs_sd_config_info_t -{ - int ss = -1; -}; -#endif -#elif defined(ESP32) || defined(MBFS_SDFAT_ENABLED) - -#if defined(ESP32) -struct mbfs_sd_mmc_config_info_t -{ - const char *mountpoint = ""; - bool mode1bit = false; - bool format_if_mount_failed = false; -}; -#endif - -struct mbfs_sd_config_info_t -{ - int ss = -1; - int sck = -1; - int miso = -1; - int mosi = -1; - uint32_t frequency = 4000000; - -#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) - - SdSpiConfig *sdFatSPIConfig = nullptr; - SdioConfig *sdFatSDIOConfig = nullptr; - -#endif - -#if defined(ESP32) - -#if defined(MBFS_SD_FS) - SPIClass *spiConfig = nullptr; -#endif - mbfs_sd_mmc_config_info_t sdMMCConfig; -#endif - -#if defined(MBFS_SDFAT_ENABLED) - SPIClass *spiConfig = nullptr; -#endif -}; - -#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) -struct mbfs_sd_config_info_t -{ - int ss = -1; -#if defined(MBFS_SD_FS) - SDFSConfig *sdFSConfig = nullptr; -#endif -}; -#else -struct mbfs_sd_config_info_t -{ - int ss = -1; -}; -#endif - -class MB_FS -{ - -public: - MB_FS() {} - ~MB_FS() {} - - struct mbfs_sd_config_info_t sd_config; - - // Assign the SD card interfaces with GPIO pins. - bool sdBegin(int ss = -1, int sck = -1, int miso = -1, int mosi = -1, uint32_t frequency = 4000000) - { - if (sd_rdy) - return true; - -#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) - sd_config.ss = ss; -#if defined(ESP32) - sd_config.sck = sck; - sd_config.miso = miso; - sd_config.mosi = mosi; - SPI.begin(sck, miso, mosi, ss); - sd_config.frequency = frequency; - return sdSPIBegin(ss, &SPI, frequency); -#elif defined(ESP8266) || defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) - sd_rdy = MBFS_SD_FS.begin(ss); - return sd_rdy; -#elif defined(MB_ARDUINO_PICO) - SDFSConfig c; - c.setCSPin(ss); - c.setSPISpeed(frequency); - MBFS_SD_FS.setConfig(c); - sd_rdy = MBFS_SD_FS.begin(); - return sd_rdy; -#endif - -#endif - return false; - } - -#if defined(ESP32) && defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) - - // Assign the SD card interfaces with SPIClass object pointer (ESP32 only). - bool sdSPIBegin(int ss, SPIClass *spiConfig, uint32_t frequency) - { - - if (sd_rdy) - return true; - - sd_config.frequency = frequency; - -#if defined(ESP32) - - sd_config.ss = ss; - - if (spiConfig) - sd_config.spiConfig = spiConfig; - else - sd_config.spiConfig = &SPI; - -#if !defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) - if (ss > -1) - sd_rdy = MBFS_SD_FS.begin(ss, *sd_config.spiConfig, frequency); - else - sd_rdy = MBFS_SD_FS.begin(); -#endif - -#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) - - cfg->_int.sd_config.sck = sck; - - if (ss > -1) - sd_rdy = MBFS_SD_FS.begin(ss); - else - sd_rdy = MBFS_SD_FS.begin(SD_CS_PIN); -#endif - - return sd_rdy; - } - -#endif - -#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) - - // Assign the SD card interfaces with SdSpiConfig object pointer and SPI pins assignment. - bool sdFatBegin(SdSpiConfig *sdFatSPIConfig, int ss, int sck, int miso, int mosi) - { - - if (sd_rdy) - return true; - - if (sdFatSPIConfig) - { - sd_config.sdFatSPIConfig = sdFatSPIConfig; - sd_config.spiConfig = &SPI; - sd_config.ss = ss; - -#if defined(ESP32) - if (ss > -1) - sd_config.spiConfig->begin(sck, miso, mosi, ss); -#endif - - sd_rdy = MBFS_SD_FS.begin(*sd_config.sdFatSPIConfig); - return sd_rdy; - } - - return false; - } - - // Assign the SD card interfaces with SdioConfig object pointer. - bool sdFatBegin(SdioConfig *sdFatSDIOConfig) - { - - if (sd_rdy) - return true; - -#if defined(HAS_SDIO_CLASS) // Default is 0 (no SDIO) in SdFatConfig.h - -#if HAS_SDIO_CLASS - - if (sdFatSDIOConfig) - { - sd_config.sdFatSDIOConfig = sdFatSDIOConfig; - - sd_rdy = MBFS_SD_FS.begin(*sd_config.sdFatSDIOConfig); - return sd_rdy; - } -#endif - -#endif - - return false; - } -#endif - -#if (defined(ESP8266) || defined(MB_ARDUINO_PICO)) && defined(MBFS_SD_FS) - // Assign the SD card interfaces with SDFSConfig object pointer (ESP8266 and Pico only). - bool sdFatBegin(SDFSConfig *sdFSConfig) - { - - if (sd_rdy) - return true; - - if (sdFSConfig) - { - sd_config.sdFSConfig = sdFSConfig; - SDFS.setConfig(*sd_config.sdFSConfig); - sd_rdy = SDFS.begin(); - return sd_rdy; - } - - return false; - } -#endif - - // Assign the SD_MMC card interfaces (ESP32 only). - bool sdMMCBegin(const char *mountpoint, bool mode1bit, bool format_if_mount_failed) - { - - if (sd_rdy) - return true; - -#if defined(ESP32) -#if defined(MBFS_CARD_TYPE_SD_MMC) - - sd_config.sdMMCConfig.mountpoint = mountpoint; - sd_config.sdMMCConfig.mode1bit = mode1bit; - sd_config.sdMMCConfig.format_if_mount_failed = format_if_mount_failed; - - sd_rdy = MBFS_SD_FS.begin(mountpoint, mode1bit, format_if_mount_failed); - return sd_rdy; -#endif -#endif - return false; - } - - // Check the mounting status of Flash storage. - bool flashReady() - { -#if defined MBFS_FLASH_FS - - if (flash_rdy) - return true; - -#if defined(ESP32) - -#if defined(MBFS_FORMAT_FLASH) - flash_rdy = MBFS_FLASH_FS.begin(true); -#else - flash_rdy = MBFS_FLASH_FS.begin(); -#endif - -#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) - flash_rdy = MBFS_FLASH_FS.begin(); -#endif - -#endif - - return flash_rdy; - } - - // Check the mounting status of SD storage. - bool sdReady() - { - -#if defined(MBFS_SD_FS) - - if (sd_rdy) - return true; - -#if defined(ESP32) - -#if defined(MBFS_CARD_TYPE_SD) - - if (!sd_config.spiConfig) - { - if (sd_config.ss > -1) - SPI.begin(sd_config.sck, sd_config.miso, sd_config.mosi, sd_config.ss); - sd_config.spiConfig = &SPI; - } - -#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) - - if (!sd_rdy) - { - if (sd_config.sdFatSPIConfig) - sd_rdy = MBFS_SD_FS.begin(*sd_config.sdFatSPIConfig); - else if (sd_config.sdFatSDIOConfig) - sd_rdy = MBFS_SD_FS.begin(*sd_config.sdFatSDIOConfig); - } - -#else - if (!sd_rdy) - sd_rdy = sdSPIBegin(sd_config.ss, sd_config.spiConfig, sd_config.frequency); - -#endif - -#elif defined(MBFS_CARD_TYPE_SD_MMC) - if (!sd_rdy) - sd_rdy = sdMMCBegin(sd_config.sdMMCConfig.mountpoint, sd_config.sdMMCConfig.mode1bit, sd_config.sdMMCConfig.format_if_mount_failed); -#endif - -#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) - if (!sd_rdy) - { - if (sd_config.sdFSConfig) - sd_rdy = sdFatBegin(sd_config.sdFSConfig); - else - sd_rdy = sdBegin(sd_config.ss); - } - -#elif defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) - if (!sd_rdy) - sd_rdy = sdBegin(sd_config.ss); -#endif - -#endif - - return sd_rdy; - } - - // Check the mounting status of Flash or SD storage with mb_fs_mem_storage_type. - bool checkStorageReady(mbfs_file_type type) - { - -#if defined(MBFS_USE_FILE_STORAGE) - if (type == mbfs_flash) - { - if (!flash_rdy) - flashReady(); - return flash_rdy; - } - else if (type == mbfs_sd) - { - if (!sd_rdy) - sdReady(); - return sd_rdy; - } -#endif - - return false; - } - - // Open file for read or write with file name, mb_fs_mem_storage_type and mb_fs_open_mode. - // return size of file (read) or 0 (write) or negative value for error - int open(const MB_String &filename, mbfs_file_type type, mb_fs_open_mode mode) - { - -#if defined(MBFS_USE_FILE_STORAGE) - - if (!checkStorageReady(type)) - { - if (type == mbfs_flash) - return MB_FS_ERROR_FLASH_STORAGE_IS_NOT_READY; - else if (type == mbfs_sd) - return MB_FS_ERROR_SD_STORAGE_IS_NOT_READY; - else - return MB_FS_ERROR_FILE_IO_ERROR; - } - - if (mode == mb_fs_open_mode_read) - { - if (!existed(filename.c_str(), type)) - return MB_FS_ERROR_FILE_NOT_FOUND; - } - - int ret = openFile(filename, type, mode); - - if (ret < 0) - return ret; - - if (ready(type)) - return ret; - -#endif - return MB_FS_ERROR_FILE_IO_ERROR; - } - - // Check if file is already open. - bool ready(mbfs_file_type type) - { -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash && mb_flashFs) - return true; -#endif -#if defined(MBFS_SD_FS) - if (type == mbfs_sd && mb_sdFs) - return true; -#endif - return false; - } - - // Get file for read/write with file name, mb_fs_mem_storage_type and mb_fs_open_mode. - int size(mbfs_file_type type) - { - int size = 0; - -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash && mb_flashFs) - size = mb_flashFs.size(); -#endif -#if defined(MBFS_SD_FS) - if (type == mbfs_sd && mb_sdFs) - size = mb_sdFs.size(); -#endif - return size; - } - - // Check if file is ready to read/write. - int available(mbfs_file_type type) - { - int available = 0; - -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash && mb_flashFs) - available = mb_flashFs.available(); -#endif -#if defined(MBFS_SD_FS) - if (type == mbfs_sd && mb_sdFs) - available = mb_sdFs.available(); -#endif - return available; - } - - // Read byte array. Return the number of bytes that completed read or negative value for error. - int read(mbfs_file_type type, uint8_t *buf, size_t len) - { - int read = 0; -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash && mb_flashFs) - read = mb_flashFs.read(buf, len); -#endif -#if defined(MBFS_SD_FS) - if (type == mbfs_sd && mb_sdFs) - read = mb_sdFs.read(buf, len); -#endif - return read; - } - - // Print char array. Return the number of bytes that completed write or negative value for error. - int print(mbfs_file_type type, const char *str) - { - int write = 0; -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash && mb_flashFs) - write = mb_flashFs.print(str); -#endif -#if defined(MBFS_SD_FS) - - if (type == mbfs_sd && mb_sdFs) - write = mb_sdFs.print(str); -#endif - return write; - } - - // Print char array with new line. Return the number of bytes that completed write or negative value for error. - int println(mbfs_file_type type, const char *str) - { - int write = print(type, str); - if (write == (int)strlen(str)) - write += print(type, (const char *)MBSTRING_FLASH_MCR("\n")); - return write; - } - - // Print integer. Return the number of bytes that completed write or negative value for error. - int print(mbfs_file_type type, int v) - { - int write = 0; -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash && mb_flashFs) - write = mb_flashFs.print(v); -#endif -#if defined(MBFS_SD_FS) - - if (type == mbfs_sd && mb_sdFs) - write = mb_sdFs.print(v); -#endif - return write; - } - - // Print integer with newline. Return the number of bytes that completed write or negative value for error. - int println(mbfs_file_type type, int v) - { - int write = print(type, v); - if (write > 0) - write += print(type, (const char *)MBSTRING_FLASH_MCR("\n")); - return write; - } - - int print(mbfs_file_type type, unsigned int v) - { - int write = 0; -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash && mb_flashFs) - write = mb_flashFs.print(v); -#endif -#if defined(MBFS_SD_FS) - - if (type == mbfs_sd && mb_sdFs) - write = mb_sdFs.print(v); -#endif - return write; - } - - // Print integer with newline. Return the number of bytes that completed write or negative value for error. - int println(mbfs_file_type type, unsigned int v) - { - int write = print(type, v); - if (write > 0) - write += print(type, (const char *)MBSTRING_FLASH_MCR("\n")); - return write; - } - - // Write byte array. Return the number of bytes that completed write or negative value for error. - int write(mbfs_file_type type, uint8_t *buf, size_t len) - { - int write = 0; -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash && mb_flashFs) - write = mb_flashFs.write(buf, len); -#endif -#if defined(MBFS_SD_FS) - - if (type == mbfs_sd && mb_sdFs) - write = mb_sdFs.write(buf, len); -#endif - return write; - } - - // Close file. - void close(mbfs_file_type type) - { - -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash && mb_flashFs && flash_opened) - { - mb_flashFs.close(); - flash_filename_crc = 0; - flash_opened = false; - flash_open_mode = mb_fs_open_mode_undefined; - } -#endif - -#if defined(MBFS_SD_FS) - if (type == mbfs_sd && mb_sdFs && sd_opened) - { - mb_sdFs.close(); - sd_filename_crc = 0; - sd_opened = false; - sd_open_mode = mb_fs_open_mode_undefined; - } -#endif - } - - // Check file existence. - bool existed(const MB_String &filename, mbfs_file_type type) - { - - if (!checkStorageReady(type)) - return false; - -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash) - { - -// The workaround for ESP32 LittleFS when calling vfs_api.cpp open() issue. -// See https://github.com/espressif/arduino-esp32/issues/7615 -#if defined(MB_FS_USE_POSIX_STAT) - return mb_fs_ns::exists("/littlefs", filename.c_str()); -#else - return MBFS_FLASH_FS.exists(filename.c_str()); -#endif - } - -#endif - -#if defined(MBFS_SD_FS) - if (type == mbfs_sd) - { -#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) - MBFS_SD_FILE file; - bool ret = file.open(filename.c_str(), O_RDONLY); - file.close(); - return ret; -#else - return MBFS_SD_FS.exists(filename.c_str()); -#endif - } -#endif - - return false; - } - - // Seek to position in file. - bool seek(mbfs_file_type type, int pos) - { - -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash && mb_flashFs) - return mb_flashFs.seek(pos); -#endif -#if defined(MBFS_SD_FS) - if (type == mbfs_sd && mb_sdFs) - return mb_sdFs.seek(pos); -#endif - - return false; - } - - // Read byte. Return the 1 for completed read or negative value for error. - int read(mbfs_file_type type) - { -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash && mb_flashFs) - return mb_flashFs.read(); -#endif -#if defined(MBFS_SD_FS) - if (type == mbfs_sd && mb_sdFs) - return mb_sdFs.read(); -#endif - return -1; - } - - // Write byte. Return the 1 for completed write or negative value for error. - int write(mbfs_file_type type, uint8_t v) - { -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash && mb_flashFs) - return mb_flashFs.write(v); -#endif -#if defined(MBFS_SD_FS) - if (type == mbfs_sd && mb_sdFs) - return mb_sdFs.write(v); -#endif - return -1; - } - - bool remove(const MB_String &filename, mbfs_file_type type) - { - if (!checkStorageReady(type)) - return false; - -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash && !flashReady()) - return false; -#endif - -#if defined(MBFS_SD_FS) - if (type == mbfs_sd && !sdReady()) - return false; -#endif - - if (!existed(filename, type)) - return true; - -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash) - return MBFS_FLASH_FS.remove(filename.c_str()); -#endif -#if defined(MBFS_SD_FS) - if (type == mbfs_sd) - { -#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) - if (mb_sdFs.open(filename.c_str(), O_RDWR | O_CREAT | O_APPEND)) - { - mb_sdFs.remove(); - mb_sdFs.close(); - return true; - } -#else - return MBFS_SD_FS.remove(filename.c_str()); -#endif - } - -#endif - return false; - } - -// Get the Flash file instance. -#if defined(MBFS_FLASH_FS) - fs::File &getFlashFile() - { - return mb_flashFs; - } -#endif - -// Get the SD file instance. -#if defined(MBFS_SD_FS) - MBFS_SD_FILE &getSDFile() - { - return mb_sdFs; - } -#endif - - // Get name of opened file. - const char *name(mbfs_file_type type) - { -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash && mb_flashFs) - return flash_file.c_str(); -#endif -#if defined(MBFS_SD_FS) - if (type == mbfs_sd && mb_sdFs) - return sd_file.c_str(); -#endif - - return ""; - } - - // Calculate CRC16 of byte array. - uint16_t calCRC(const char *buf) - { - uint8_t x; - uint16_t crc = 0xFFFF; - - int length = (int)strlen(buf); - - while (length--) - { - x = crc >> 8 ^ *buf++; - x ^= x >> 4; - crc = (crc << 8) ^ ((uint16_t)(x << 12)) ^ ((uint16_t)(x << 5)) ^ ((uint16_t)x); - } - return crc; - } - - // Free reserved memory at pointer. - void delP(void *ptr) - { - void **p = (void **)ptr; - if (*p) - { - free(*p); - *p = 0; - } - } - - // Allocate memory - void *newP(size_t len, bool clear = true) - { - void *p; - size_t newLen = getReservedLen(len); -#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) - - if (ESP.getPsramSize() > 0) - p = (void *)ps_malloc(newLen); - else - p = (void *)malloc(newLen); - - if (!p) - return NULL; - -#else - -#if defined(ESP8266_USE_EXTERNAL_HEAP) - ESP.setExternalHeap(); -#endif - - p = (void *)malloc(newLen); - bool nn = p ? true : false; - -#if defined(ESP8266_USE_EXTERNAL_HEAP) - ESP.resetHeap(); -#endif - - if (!nn) - return NULL; - -#endif - if (clear) - memset(p, 0, newLen); - return p; - } - - size_t getReservedLen(size_t len) - { - int blen = len + 1; - - int newlen = (blen / 4) * 4; - - if (newlen < blen) - newlen += 4; - - return (size_t)newlen; - } - - void createDirs(MB_String dirs, mbfs_file_type type) - { - if (!longNameSupported()) - return; - - MB_String dir; - int count = 0; - int lastPos = 0; - for (size_t i = 0; i < dirs.length(); i++) - { - dir.append(1, dirs[i]); - count++; - if (dirs[i] == '/' && i > 0) - { - if (dir.length() > 0) - { - - lastPos = dir.length() - 1; - -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash) - MBFS_FLASH_FS.mkdir(dir.substr(0, dir.length() - 1).c_str()); -#endif - -#if defined(MBFS_SD_FS) - if (type == mbfs_sd) - MBFS_SD_FS.mkdir(dir.substr(0, dir.length() - 1).c_str()); -#endif - } - count = 0; - } - } - - if (count > 0) - { - if (dir.find('.', lastPos) == MB_String::npos) - { -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash) - MBFS_FLASH_FS.mkdir(dir.c_str()); -#endif - -#if defined(MBFS_SD_FS) - if (type == mbfs_sd) - MBFS_SD_FS.mkdir(dir.c_str()); -#endif - } - } - - dir.clear(); - } - - bool longNameSupported() - { - -#if defined(MBFS_SDFAT_ENABLED) || defined(MBFS_FLASH_FS) - return true; -#endif - -#if defined(MBFS_SD_FS) && (defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO)) - return true; -#endif - - return false; - } - -private: - uint16_t flash_filename_crc = 0; - uint16_t sd_filename_crc = 0; - MB_String flash_file, sd_file; - mb_fs_open_mode flash_open_mode = mb_fs_open_mode_undefined; - mb_fs_open_mode sd_open_mode = mb_fs_open_mode_undefined; - bool flash_opened = false; - bool sd_opened = false; - bool sd_rdy = false; - bool flash_rdy = false; - uint16_t loopCount = 0; - -#if defined(MBFS_FLASH_FS) - fs::File mb_flashFs; -#endif -#if defined(MBFS_SD_FS) - MBFS_SD_FILE mb_sdFs; -#endif - - int openFile(const MB_String &filename, mb_fs_mem_storage_type type, mb_fs_open_mode mode) - { - -#if defined(MBFS_FLASH_FS) - if (type == mbfs_flash) - return openFlashFile(filename, mode); -#endif -#if defined(MBFS_SD_FS) - if (type == mbfs_sd) - return openSDFile(filename, mode); -#endif - return MB_FS_ERROR_FILE_IO_ERROR; - } - - int openSDFile(const MB_String &filename, mb_fs_open_mode mode) - { - int ret = MB_FS_ERROR_FILE_IO_ERROR; - -#if defined(MBFS_SD_FS) - - if (mode == mb_fs_open_mode_read || mode == mb_fs_open_mode_write || mode == mb_fs_open_mode_append) - { - uint16_t crc = calCRC(filename.c_str()); - - if (mode == sd_open_mode && flash_filename_crc == crc && sd_opened) // same sd file opened, leave it - return MB_FS_ERROR_FILE_STILL_OPENED; - - if (sd_opened) - close(mbfs_sd); // sd file opened, close it - - flash_filename_crc = crc; - } - -#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) - - if (mode == mb_fs_open_mode_read) - { - if (mb_sdFs.open(filename.c_str(), O_RDONLY)) - { - sd_file = filename; - sd_opened = true; - sd_open_mode = mode; - ret = mb_sdFs.size(); - } - } - else if (mode == mb_fs_open_mode_write || mode == mb_fs_open_mode_append) - { - if (mode == mb_fs_open_mode_write) - remove(filename, mb_fs_mem_storage_type_sd); - - createDirs(filename, mb_fs_mem_storage_type_sd); - if (mb_sdFs.open(filename.c_str(), O_RDWR | O_CREAT | O_APPEND)) - { - sd_file = filename; - sd_opened = true; - sd_open_mode = mode; - ret = 0; - } - } - -#else - - if (mode == mb_fs_open_mode_read) - { -#if defined(ESP32) || defined(ESP8266) - mb_sdFs = MBFS_SD_FS.open(filename.c_str(), FILE_READ); -#else - mb_sdFs = MBFS_SD_FS.open(filename.c_str(), "r"); -#endif - if (mb_sdFs) - { - sd_file = filename; - sd_opened = true; - sd_open_mode = mode; - ret = mb_sdFs.size(); - } - } - else if (mode == mb_fs_open_mode_write || mode == mb_fs_open_mode_append) - { - if (mode == mb_fs_open_mode_write) - remove(filename, mb_fs_mem_storage_type_sd); - - createDirs(filename, mb_fs_mem_storage_type_sd); -#if defined(ESP32) - if (mode == mb_fs_open_mode_write) - mb_sdFs = MBFS_SD_FS.open(filename.c_str(), FILE_WRITE); - else - mb_sdFs = MBFS_SD_FS.open(filename.c_str(), FILE_APPEND); -#elif defined(ESP8266) - mb_sdFs = MBFS_SD_FS.open(filename.c_str(), FILE_WRITE); -#else - if (mode == mb_fs_open_mode_write) - mb_sdFs = MBFS_SD_FS.open(filename.c_str(), "w"); - else - mb_sdFs = MBFS_SD_FS.open(filename.c_str(), "a"); -#endif - - if (mb_sdFs) - { - sd_file = filename; - sd_opened = true; - sd_open_mode = mode; - ret = 0; - } - } -#endif - -#endif - return ret; - } - - int openFlashFile(const MB_String &filename, mb_fs_open_mode mode) - { - int ret = MB_FS_ERROR_FILE_IO_ERROR; - -#if defined(MBFS_FLASH_FS) - - if (mode == mb_fs_open_mode_read || mode == mb_fs_open_mode_write || mode == mb_fs_open_mode_append) - { - uint16_t crc = calCRC(filename.c_str()); - if (mode == flash_open_mode && sd_filename_crc == crc && flash_opened) // same flash file opened, leave it - return MB_FS_ERROR_FILE_STILL_OPENED; - - if (flash_opened) - close(mbfs_flash); // flash file opened, close it - - sd_filename_crc = crc; - } - - if (mode == mb_fs_open_mode_read) - { - mb_flashFs = MBFS_FLASH_FS.open(filename.c_str(), "r"); - if (mb_flashFs) - { - flash_file = filename; - flash_opened = true; - flash_open_mode = mode; - ret = mb_flashFs.size(); - } - } - else if (mode == mb_fs_open_mode_write || mode == mb_fs_open_mode_append) - { - if (mode == mb_fs_open_mode_write) - remove(filename, mb_fs_mem_storage_type_flash); - - createDirs(filename, mb_fs_mem_storage_type_flash); - if (mode == mb_fs_open_mode_write) - mb_flashFs = MBFS_FLASH_FS.open(filename.c_str(), "w"); - else - mb_flashFs = MBFS_FLASH_FS.open(filename.c_str(), "a"); - - if (mb_flashFs) - { - flash_file = filename; - flash_opened = true; - flash_open_mode = mode; - ret = 0; - } - } - -#endif - return ret; - } -}; - -#endif +/** + * The MB_FS, filesystems wrapper class v1.0.16 + * + * This wrapper class is for SD and Flash filesystems interface which supports SdFat (//https://github.com/greiman/SdFat) + * + * Created June 14, 2023 + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person returning 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. + */ + +#if 0 +#ifndef MBFS_CLASS_H +#define MBFS_CLASS_H + +#include +#include "MB_MCU.h" + +#define FS_NO_GLOBALS +#if defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO) +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) +#include +#endif +#endif +#include "MB_FS_Interfaces.h" +#include MB_STRING_INCLUDE_CLASS + +#if defined(MBFS_FLASH_FS) || defined(MBFS_SD_FS) +#include "SPI.h" +#endif + +#if defined(ESP32) && __has_include() +#ifdef _LITTLEFS_H_ +#define MB_FS_USE_POSIX_STAT +#include +namespace mb_fs_ns +{ + inline bool exists(const char *mountPoint, const char *filename) + { + MB_String path = mountPoint; + path += filename; + struct stat st; + return stat(path.c_str(), &st) == 0; + } +}; +#endif +#endif + +using namespace mb_string; + +#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) +#include +#endif + +#define MB_FS_ERROR_FILE_IO_ERROR -300 +#define MB_FS_ERROR_FILE_NOT_FOUND -301 +#define MB_FS_ERROR_FLASH_STORAGE_IS_NOT_READY -302 +#define MB_FS_ERROR_SD_STORAGE_IS_NOT_READY -303 +#define MB_FS_ERROR_FILE_STILL_OPENED -304 + +typedef enum +{ + mb_fs_mem_storage_type_undefined, + mb_fs_mem_storage_type_flash, + mb_fs_mem_storage_type_sd +} mb_fs_mem_storage_type; + +typedef enum +{ + mb_fs_open_mode_undefined = -1, + mb_fs_open_mode_read = 0, + mb_fs_open_mode_write, + mb_fs_open_mode_append +} mb_fs_open_mode; + +#define mbfs_file_type mb_fs_mem_storage_type +#define mbfs_flash mb_fs_mem_storage_type_flash +#define mbfs_sd mb_fs_mem_storage_type_sd +#define mbfs_undefined mb_fs_mem_storage_type_undefined + +#define mbfs_type (mbfs_file_type) + +#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) +#if !defined(MBFS_SDFAT_ENABLED) +struct mbfs_sd_config_info_t +{ + int ss = -1; +}; +#endif +#elif defined(ESP32) || defined(MBFS_SDFAT_ENABLED) + +#if defined(ESP32) +struct mbfs_sd_mmc_config_info_t +{ + const char *mountpoint = ""; + bool mode1bit = false; + bool format_if_mount_failed = false; +}; +#endif + +struct mbfs_sd_config_info_t +{ + int ss = -1; + int sck = -1; + int miso = -1; + int mosi = -1; + uint32_t frequency = 4000000; + +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + + SdSpiConfig *sdFatSPIConfig = nullptr; + SdioConfig *sdFatSDIOConfig = nullptr; + +#endif + +#if defined(ESP32) + +#if defined(MBFS_SD_FS) + SPIClass *spiConfig = nullptr; +#endif + mbfs_sd_mmc_config_info_t sdMMCConfig; +#endif + +#if defined(MBFS_SDFAT_ENABLED) + SPIClass *spiConfig = nullptr; +#endif +}; + +#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) +struct mbfs_sd_config_info_t +{ + int ss = -1; +#if defined(MBFS_SD_FS) + SDFSConfig *sdFSConfig = nullptr; +#endif +}; +#else +struct mbfs_sd_config_info_t +{ + int ss = -1; +}; +#endif + +class MB_FS +{ + +public: + MB_FS() {} + ~MB_FS() {} + + struct mbfs_sd_config_info_t sd_config; + + // Assign the SD card interfaces with GPIO pins. + bool sdBegin(int ss = -1, int sck = -1, int miso = -1, int mosi = -1, uint32_t frequency = 4000000) + { + if (sd_rdy) + return true; + +#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) + sd_config.ss = ss; +#if defined(ESP32) + sd_config.sck = sck; + sd_config.miso = miso; + sd_config.mosi = mosi; + SPI.begin(sck, miso, mosi, ss); + sd_config.frequency = frequency; + return sdSPIBegin(ss, &SPI, frequency); +#elif defined(ESP8266) || defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) + sd_rdy = MBFS_SD_FS.begin(ss); + return sd_rdy; +#elif defined(MB_ARDUINO_PICO) + SDFSConfig c; + c.setCSPin(ss); + c.setSPISpeed(frequency); + MBFS_SD_FS.setConfig(c); + sd_rdy = MBFS_SD_FS.begin(); + return sd_rdy; +#endif + +#endif + return false; + } + +#if defined(ESP32) && defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) + + // Assign the SD card interfaces with SPIClass object pointer (ESP32 only). + bool sdSPIBegin(int ss, SPIClass *spiConfig, uint32_t frequency) + { + + if (sd_rdy) + return true; + + sd_config.frequency = frequency; + +#if defined(ESP32) + + sd_config.ss = ss; + + if (spiConfig) + sd_config.spiConfig = spiConfig; + else + sd_config.spiConfig = &SPI; + +#if !defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + if (ss > -1) + sd_rdy = MBFS_SD_FS.begin(ss, *sd_config.spiConfig, frequency); + else + sd_rdy = MBFS_SD_FS.begin(); +#endif + +#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) + + cfg->_int.sd_config.sck = sck; + + if (ss > -1) + sd_rdy = MBFS_SD_FS.begin(ss); + else + sd_rdy = MBFS_SD_FS.begin(SD_CS_PIN); +#endif + + return sd_rdy; + } + +#endif + +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + + // Assign the SD card interfaces with SdSpiConfig object pointer and SPI pins assignment. + bool sdFatBegin(SdSpiConfig *sdFatSPIConfig, int ss, int sck, int miso, int mosi) + { + + if (sd_rdy) + return true; + + if (sdFatSPIConfig) + { + sd_config.sdFatSPIConfig = sdFatSPIConfig; + sd_config.spiConfig = &SPI; + sd_config.ss = ss; + +#if defined(ESP32) + if (ss > -1) + sd_config.spiConfig->begin(sck, miso, mosi, ss); +#endif + + sd_rdy = MBFS_SD_FS.begin(*sd_config.sdFatSPIConfig); + return sd_rdy; + } + + return false; + } + + // Assign the SD card interfaces with SdioConfig object pointer. + bool sdFatBegin(SdioConfig *sdFatSDIOConfig) + { + + if (sd_rdy) + return true; + +#if defined(HAS_SDIO_CLASS) // Default is 0 (no SDIO) in SdFatConfig.h + +#if HAS_SDIO_CLASS + + if (sdFatSDIOConfig) + { + sd_config.sdFatSDIOConfig = sdFatSDIOConfig; + + sd_rdy = MBFS_SD_FS.begin(*sd_config.sdFatSDIOConfig); + return sd_rdy; + } +#endif + +#endif + + return false; + } +#endif + +#if (defined(ESP8266) || defined(MB_ARDUINO_PICO)) && defined(MBFS_SD_FS) + // Assign the SD card interfaces with SDFSConfig object pointer (ESP8266 and Pico only). + bool sdFatBegin(SDFSConfig *sdFSConfig) + { + + if (sd_rdy) + return true; + + if (sdFSConfig) + { + sd_config.sdFSConfig = sdFSConfig; + SDFS.setConfig(*sd_config.sdFSConfig); + sd_rdy = SDFS.begin(); + return sd_rdy; + } + + return false; + } +#endif + + // Assign the SD_MMC card interfaces (ESP32 only). + bool sdMMCBegin(const char *mountpoint, bool mode1bit, bool format_if_mount_failed) + { + + if (sd_rdy) + return true; + +#if defined(ESP32) +#if defined(MBFS_CARD_TYPE_SD_MMC) + + sd_config.sdMMCConfig.mountpoint = mountpoint; + sd_config.sdMMCConfig.mode1bit = mode1bit; + sd_config.sdMMCConfig.format_if_mount_failed = format_if_mount_failed; + + sd_rdy = MBFS_SD_FS.begin(mountpoint, mode1bit, format_if_mount_failed); + return sd_rdy; +#endif +#endif + return false; + } + + // Check the mounting status of Flash storage. + bool flashReady() + { +#if defined MBFS_FLASH_FS + + if (flash_rdy) + return true; + +#if defined(ESP32) + +#if defined(MBFS_FORMAT_FLASH) + flash_rdy = MBFS_FLASH_FS.begin(true); +#else + flash_rdy = MBFS_FLASH_FS.begin(); +#endif + +#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) + flash_rdy = MBFS_FLASH_FS.begin(); +#endif + +#endif + + return flash_rdy; + } + + // Check the mounting status of SD storage. + bool sdReady() + { + +#if defined(MBFS_SD_FS) + + if (sd_rdy) + return true; + +#if defined(ESP32) + +#if defined(MBFS_CARD_TYPE_SD) + + if (!sd_config.spiConfig) + { + if (sd_config.ss > -1) + SPI.begin(sd_config.sck, sd_config.miso, sd_config.mosi, sd_config.ss); + sd_config.spiConfig = &SPI; + } + +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + + if (!sd_rdy) + { + if (sd_config.sdFatSPIConfig) + sd_rdy = MBFS_SD_FS.begin(*sd_config.sdFatSPIConfig); + else if (sd_config.sdFatSDIOConfig) + sd_rdy = MBFS_SD_FS.begin(*sd_config.sdFatSDIOConfig); + } + +#else + if (!sd_rdy) + sd_rdy = sdSPIBegin(sd_config.ss, sd_config.spiConfig, sd_config.frequency); + +#endif + +#elif defined(MBFS_CARD_TYPE_SD_MMC) + if (!sd_rdy) + sd_rdy = sdMMCBegin(sd_config.sdMMCConfig.mountpoint, sd_config.sdMMCConfig.mode1bit, sd_config.sdMMCConfig.format_if_mount_failed); +#endif + +#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) + if (!sd_rdy) + { + if (sd_config.sdFSConfig) + sd_rdy = sdFatBegin(sd_config.sdFSConfig); + else + sd_rdy = sdBegin(sd_config.ss); + } + +#elif defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) + if (!sd_rdy) + sd_rdy = sdBegin(sd_config.ss); +#endif + +#endif + + return sd_rdy; + } + + // Check the mounting status of Flash or SD storage with mb_fs_mem_storage_type. + bool checkStorageReady(mbfs_file_type type) + { + +#if defined(MBFS_USE_FILE_STORAGE) + if (type == mbfs_flash) + { + if (!flash_rdy) + flashReady(); + return flash_rdy; + } + else if (type == mbfs_sd) + { + if (!sd_rdy) + sdReady(); + return sd_rdy; + } +#endif + + return false; + } + + // Open file for read or write with file name, mb_fs_mem_storage_type and mb_fs_open_mode. + // return size of file (read) or 0 (write) or negative value for error + int open(const MB_String &filename, mbfs_file_type type, mb_fs_open_mode mode) + { + +#if defined(MBFS_USE_FILE_STORAGE) + + if (!checkStorageReady(type)) + { + if (type == mbfs_flash) + return MB_FS_ERROR_FLASH_STORAGE_IS_NOT_READY; + else if (type == mbfs_sd) + return MB_FS_ERROR_SD_STORAGE_IS_NOT_READY; + else + return MB_FS_ERROR_FILE_IO_ERROR; + } + + if (mode == mb_fs_open_mode_read) + { + if (!existed(filename.c_str(), type)) + return MB_FS_ERROR_FILE_NOT_FOUND; + } + + int ret = openFile(filename, type, mode); + + if (ret < 0) + return ret; + + if (ready(type)) + return ret; + +#endif + return MB_FS_ERROR_FILE_IO_ERROR; + } + + // Check if file is already open. + bool ready(mbfs_file_type type) + { +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + return true; +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + return true; +#endif + return false; + } + + // Get file for read/write with file name, mb_fs_mem_storage_type and mb_fs_open_mode. + int size(mbfs_file_type type) + { + int size = 0; + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + size = mb_flashFs.size(); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + size = mb_sdFs.size(); +#endif + return size; + } + + // Check if file is ready to read/write. + int available(mbfs_file_type type) + { + int available = 0; + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + available = mb_flashFs.available(); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + available = mb_sdFs.available(); +#endif + return available; + } + + // Read byte array. Return the number of bytes that completed read or negative value for error. + int read(mbfs_file_type type, uint8_t *buf, size_t len) + { + int read = 0; +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + read = mb_flashFs.read(buf, len); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + read = mb_sdFs.read(buf, len); +#endif + return read; + } + + // Print char array. Return the number of bytes that completed write or negative value for error. + int print(mbfs_file_type type, const char *str) + { + int write = 0; +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + write = mb_flashFs.print(str); +#endif +#if defined(MBFS_SD_FS) + + if (type == mbfs_sd && mb_sdFs) + write = mb_sdFs.print(str); +#endif + return write; + } + + // Print char array with new line. Return the number of bytes that completed write or negative value for error. + int println(mbfs_file_type type, const char *str) + { + int write = print(type, str); + if (write == (int)strlen(str)) + write += print(type, (const char *)MBSTRING_FLASH_MCR("\n")); + return write; + } + + // Print integer. Return the number of bytes that completed write or negative value for error. + int print(mbfs_file_type type, int v) + { + int write = 0; +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + write = mb_flashFs.print(v); +#endif +#if defined(MBFS_SD_FS) + + if (type == mbfs_sd && mb_sdFs) + write = mb_sdFs.print(v); +#endif + return write; + } + + // Print integer with newline. Return the number of bytes that completed write or negative value for error. + int println(mbfs_file_type type, int v) + { + int write = print(type, v); + if (write > 0) + write += print(type, (const char *)MBSTRING_FLASH_MCR("\n")); + return write; + } + + int print(mbfs_file_type type, unsigned int v) + { + int write = 0; +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + write = mb_flashFs.print(v); +#endif +#if defined(MBFS_SD_FS) + + if (type == mbfs_sd && mb_sdFs) + write = mb_sdFs.print(v); +#endif + return write; + } + + // Print integer with newline. Return the number of bytes that completed write or negative value for error. + int println(mbfs_file_type type, unsigned int v) + { + int write = print(type, v); + if (write > 0) + write += print(type, (const char *)MBSTRING_FLASH_MCR("\n")); + return write; + } + + // Write byte array. Return the number of bytes that completed write or negative value for error. + int write(mbfs_file_type type, uint8_t *buf, size_t len) + { + int write = 0; +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + write = mb_flashFs.write(buf, len); +#endif +#if defined(MBFS_SD_FS) + + if (type == mbfs_sd && mb_sdFs) + write = mb_sdFs.write(buf, len); +#endif + return write; + } + + // Close file. + void close(mbfs_file_type type) + { + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs && flash_opened) + { + mb_flashFs.close(); + flash_filename_crc = 0; + flash_opened = false; + flash_open_mode = mb_fs_open_mode_undefined; + } +#endif + +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs && sd_opened) + { + mb_sdFs.close(); + sd_filename_crc = 0; + sd_opened = false; + sd_open_mode = mb_fs_open_mode_undefined; + } +#endif + } + + // Check file existence. + bool existed(const MB_String &filename, mbfs_file_type type) + { + + if (!checkStorageReady(type)) + return false; + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash) + { + +// The workaround for ESP32 LittleFS when calling vfs_api.cpp open() issue. +// See https://github.com/espressif/arduino-esp32/issues/7615 +#if defined(MB_FS_USE_POSIX_STAT) + return mb_fs_ns::exists("/littlefs", filename.c_str()); +#else + return MBFS_FLASH_FS.exists(filename.c_str()); +#endif + } + +#endif + +#if defined(MBFS_SD_FS) + if (type == mbfs_sd) + { +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + MBFS_SD_FILE file; + bool ret = file.open(filename.c_str(), O_RDONLY); + file.close(); + return ret; +#else + return MBFS_SD_FS.exists(filename.c_str()); +#endif + } +#endif + + return false; + } + + // Seek to position in file. + bool seek(mbfs_file_type type, int pos) + { + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + return mb_flashFs.seek(pos); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + return mb_sdFs.seek(pos); +#endif + + return false; + } + + // Read byte. Return the 1 for completed read or negative value for error. + int read(mbfs_file_type type) + { +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + return mb_flashFs.read(); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + return mb_sdFs.read(); +#endif + return -1; + } + + // Write byte. Return the 1 for completed write or negative value for error. + int write(mbfs_file_type type, uint8_t v) + { +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + return mb_flashFs.write(v); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + return mb_sdFs.write(v); +#endif + return -1; + } + + bool remove(const MB_String &filename, mbfs_file_type type) + { + if (!checkStorageReady(type)) + return false; + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && !flashReady()) + return false; +#endif + +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && !sdReady()) + return false; +#endif + + if (!existed(filename, type)) + return true; + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash) + return MBFS_FLASH_FS.remove(filename.c_str()); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd) + { +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + if (mb_sdFs.open(filename.c_str(), O_RDWR | O_CREAT | O_APPEND)) + { + mb_sdFs.remove(); + mb_sdFs.close(); + return true; + } +#else + return MBFS_SD_FS.remove(filename.c_str()); +#endif + } + +#endif + return false; + } + +// Get the Flash file instance. +#if defined(MBFS_FLASH_FS) + fs::File &getFlashFile() + { + return mb_flashFs; + } +#endif + +// Get the SD file instance. +#if defined(MBFS_SD_FS) + MBFS_SD_FILE &getSDFile() + { + return mb_sdFs; + } +#endif + + // Get name of opened file. + const char *name(mbfs_file_type type) + { +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash && mb_flashFs) + return flash_file.c_str(); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd && mb_sdFs) + return sd_file.c_str(); +#endif + + return ""; + } + + // Calculate CRC16 of byte array. + uint16_t calCRC(const char *buf) + { + uint8_t x; + uint16_t crc = 0xFFFF; + + int length = (int)strlen(buf); + + while (length--) + { + x = crc >> 8 ^ *buf++; + x ^= x >> 4; + crc = (crc << 8) ^ ((uint16_t)(x << 12)) ^ ((uint16_t)(x << 5)) ^ ((uint16_t)x); + } + return crc; + } + + // Free reserved memory at pointer. + void delP(void *ptr) + { + void **p = (void **)ptr; + if (*p) + { + free(*p); + *p = 0; + } + } + + // Allocate memory + void *newP(size_t len, bool clear = true) + { + void *p; + size_t newLen = getReservedLen(len); +#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) + + if (ESP.getPsramSize() > 0) + p = (void *)ps_malloc(newLen); + else + p = (void *)malloc(newLen); + + if (!p) + return NULL; + +#else + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + ESP.setExternalHeap(); +#endif + + p = (void *)malloc(newLen); + bool nn = p ? true : false; + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + ESP.resetHeap(); +#endif + + if (!nn) + return NULL; + +#endif + if (clear) + memset(p, 0, newLen); + return p; + } + + size_t getReservedLen(size_t len) + { + int blen = len + 1; + + int newlen = (blen / 4) * 4; + + if (newlen < blen) + newlen += 4; + + return (size_t)newlen; + } + + void createDirs(MB_String dirs, mbfs_file_type type) + { + if (!longNameSupported()) + return; + + MB_String dir; + int count = 0; + int lastPos = 0; + for (size_t i = 0; i < dirs.length(); i++) + { + dir.append(1, dirs[i]); + count++; + if (dirs[i] == '/' && i > 0) + { + if (dir.length() > 0) + { + + lastPos = dir.length() - 1; + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash) + MBFS_FLASH_FS.mkdir(dir.substr(0, dir.length() - 1).c_str()); +#endif + +#if defined(MBFS_SD_FS) + if (type == mbfs_sd) + MBFS_SD_FS.mkdir(dir.substr(0, dir.length() - 1).c_str()); +#endif + } + count = 0; + } + } + + if (count > 0) + { + if (dir.find('.', lastPos) == MB_String::npos) + { +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash) + MBFS_FLASH_FS.mkdir(dir.c_str()); +#endif + +#if defined(MBFS_SD_FS) + if (type == mbfs_sd) + MBFS_SD_FS.mkdir(dir.c_str()); +#endif + } + } + + dir.clear(); + } + + bool longNameSupported() + { + +#if defined(MBFS_SDFAT_ENABLED) || defined(MBFS_FLASH_FS) + return true; +#endif + +#if defined(MBFS_SD_FS) && (defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO)) + return true; +#endif + + return false; + } + +private: + uint16_t flash_filename_crc = 0; + uint16_t sd_filename_crc = 0; + MB_String flash_file, sd_file; + mb_fs_open_mode flash_open_mode = mb_fs_open_mode_undefined; + mb_fs_open_mode sd_open_mode = mb_fs_open_mode_undefined; + bool flash_opened = false; + bool sd_opened = false; + bool sd_rdy = false; + bool flash_rdy = false; + uint16_t loopCount = 0; + +#if defined(MBFS_FLASH_FS) + fs::File mb_flashFs; +#endif +#if defined(MBFS_SD_FS) + MBFS_SD_FILE mb_sdFs; +#endif + + int openFile(const MB_String &filename, mb_fs_mem_storage_type type, mb_fs_open_mode mode) + { + +#if defined(MBFS_FLASH_FS) + if (type == mbfs_flash) + return openFlashFile(filename, mode); +#endif +#if defined(MBFS_SD_FS) + if (type == mbfs_sd) + return openSDFile(filename, mode); +#endif + return MB_FS_ERROR_FILE_IO_ERROR; + } + + int openSDFile(const MB_String &filename, mb_fs_open_mode mode) + { + int ret = MB_FS_ERROR_FILE_IO_ERROR; + +#if defined(MBFS_SD_FS) + + if (mode == mb_fs_open_mode_read || mode == mb_fs_open_mode_write || mode == mb_fs_open_mode_append) + { + uint16_t crc = calCRC(filename.c_str()); + + if (mode == sd_open_mode && flash_filename_crc == crc && sd_opened) // same sd file opened, leave it + return MB_FS_ERROR_FILE_STILL_OPENED; + + if (sd_opened) + close(mbfs_sd); // sd file opened, close it + + flash_filename_crc = crc; + } + +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + + if (mode == mb_fs_open_mode_read) + { + if (mb_sdFs.open(filename.c_str(), O_RDONLY)) + { + sd_file = filename; + sd_opened = true; + sd_open_mode = mode; + ret = mb_sdFs.size(); + } + } + else if (mode == mb_fs_open_mode_write || mode == mb_fs_open_mode_append) + { + if (mode == mb_fs_open_mode_write) + remove(filename, mb_fs_mem_storage_type_sd); + + createDirs(filename, mb_fs_mem_storage_type_sd); + if (mb_sdFs.open(filename.c_str(), O_RDWR | O_CREAT | O_APPEND)) + { + sd_file = filename; + sd_opened = true; + sd_open_mode = mode; + ret = 0; + } + } + +#else + + if (mode == mb_fs_open_mode_read) + { +#if defined(ESP32) || defined(ESP8266) + mb_sdFs = MBFS_SD_FS.open(filename.c_str(), FILE_READ); +#else + mb_sdFs = MBFS_SD_FS.open(filename.c_str(), "r"); +#endif + if (mb_sdFs) + { + sd_file = filename; + sd_opened = true; + sd_open_mode = mode; + ret = mb_sdFs.size(); + } + } + else if (mode == mb_fs_open_mode_write || mode == mb_fs_open_mode_append) + { + if (mode == mb_fs_open_mode_write) + remove(filename, mb_fs_mem_storage_type_sd); + + createDirs(filename, mb_fs_mem_storage_type_sd); +#if defined(ESP32) + if (mode == mb_fs_open_mode_write) + mb_sdFs = MBFS_SD_FS.open(filename.c_str(), FILE_WRITE); + else + mb_sdFs = MBFS_SD_FS.open(filename.c_str(), FILE_APPEND); +#elif defined(ESP8266) + mb_sdFs = MBFS_SD_FS.open(filename.c_str(), FILE_WRITE); +#else + if (mode == mb_fs_open_mode_write) + mb_sdFs = MBFS_SD_FS.open(filename.c_str(), "w"); + else + mb_sdFs = MBFS_SD_FS.open(filename.c_str(), "a"); +#endif + + if (mb_sdFs) + { + sd_file = filename; + sd_opened = true; + sd_open_mode = mode; + ret = 0; + } + } +#endif + +#endif + return ret; + } + + int openFlashFile(const MB_String &filename, mb_fs_open_mode mode) + { + int ret = MB_FS_ERROR_FILE_IO_ERROR; + +#if defined(MBFS_FLASH_FS) + + if (mode == mb_fs_open_mode_read || mode == mb_fs_open_mode_write || mode == mb_fs_open_mode_append) + { + uint16_t crc = calCRC(filename.c_str()); + if (mode == flash_open_mode && sd_filename_crc == crc && flash_opened) // same flash file opened, leave it + return MB_FS_ERROR_FILE_STILL_OPENED; + + if (flash_opened) + close(mbfs_flash); // flash file opened, close it + + sd_filename_crc = crc; + } + + if (mode == mb_fs_open_mode_read) + { + mb_flashFs = MBFS_FLASH_FS.open(filename.c_str(), "r"); + if (mb_flashFs) + { + flash_file = filename; + flash_opened = true; + flash_open_mode = mode; + ret = mb_flashFs.size(); + } + } + else if (mode == mb_fs_open_mode_write || mode == mb_fs_open_mode_append) + { + if (mode == mb_fs_open_mode_write) + remove(filename, mb_fs_mem_storage_type_flash); + + createDirs(filename, mb_fs_mem_storage_type_flash); + if (mode == mb_fs_open_mode_write) + mb_flashFs = MBFS_FLASH_FS.open(filename.c_str(), "w"); + else + mb_flashFs = MBFS_FLASH_FS.open(filename.c_str(), "a"); + + if (mb_flashFs) + { + flash_file = filename; + flash_opened = true; + flash_open_mode = mode; + ret = 0; + } + } + +#endif + return ret; + } +}; + +#endif #endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/MB_MCU.h b/lib/libesp32/ESP-Mail-Client/src/extras/MB_MCU.h index 3009e67bb..b754e0f9f 100644 --- a/lib/libesp32/ESP-Mail-Client/src/extras/MB_MCU.h +++ b/lib/libesp32/ESP-Mail-Client/src/extras/MB_MCU.h @@ -1,67 +1,67 @@ -#pragma once - -#ifndef MB_MCU_H -#define MB_MCU_H - - -#if defined(ESP8266) || defined(ESP32) -#ifndef MB_ARDUINO_ESP -#define MB_ARDUINO_ESP -#endif -#endif - -#if defined(__arm__) -#ifndef MB_ARDUINO_ARM -#define MB_ARDUINO_ARM -#endif -#endif - -// Renesas -#if defined(ARDUINO_PORTENTA_C33) - -#endif - -// Renesas -#if defined(ARDUINO_UNOWIFIR4) - -#endif - -// Renesas -#if defined(ARDUINO_MINIMA) - -#endif - -#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) || defined(ARDUINO_PORTENTA_X8) - -#endif - - -#if defined(ARDUINO_ARCH_SAMD) -#ifndef MB_ARDUINO_ARCH_SAMD -#define MB_ARDUINO_ARCH_SAMD -#endif -#endif - -#if defined(ARDUINO_ARCH_RP2040) - -#if defined(ARDUINO_NANO_RP2040_CONNECT) -#ifndef MB_ARDUINO_NANO_RP2040_CONNECT -#define MB_ARDUINO_NANO_RP2040_CONNECT -#endif -#else -#ifndef MB_ARDUINO_PICO -#define MB_ARDUINO_PICO -#endif -#endif - -#endif - - -#if defined(TEENSYDUINO) -#ifndef MB_ARDUINO_TEENSY -#define MB_ARDUINO_TEENSY -#endif -#endif - - +#pragma once + +#ifndef MB_MCU_H +#define MB_MCU_H + + +#if defined(ESP8266) || defined(ESP32) +#ifndef MB_ARDUINO_ESP +#define MB_ARDUINO_ESP +#endif +#endif + +#if defined(__arm__) +#ifndef MB_ARDUINO_ARM +#define MB_ARDUINO_ARM +#endif +#endif + +// Renesas +#if defined(ARDUINO_PORTENTA_C33) + +#endif + +// Renesas +#if defined(ARDUINO_UNOWIFIR4) + +#endif + +// Renesas +#if defined(ARDUINO_MINIMA) + +#endif + +#if defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) || defined(ARDUINO_PORTENTA_X8) + +#endif + + +#if defined(ARDUINO_ARCH_SAMD) +#ifndef MB_ARDUINO_ARCH_SAMD +#define MB_ARDUINO_ARCH_SAMD +#endif +#endif + +#if defined(ARDUINO_ARCH_RP2040) + +#if defined(ARDUINO_NANO_RP2040_CONNECT) +#ifndef MB_ARDUINO_NANO_RP2040_CONNECT +#define MB_ARDUINO_NANO_RP2040_CONNECT +#endif +#else +#ifndef MB_ARDUINO_PICO +#define MB_ARDUINO_PICO +#endif +#endif + +#endif + + +#if defined(TEENSYDUINO) +#ifndef MB_ARDUINO_TEENSY +#define MB_ARDUINO_TEENSY +#endif +#endif + + #endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/MB_String.h b/lib/libesp32/ESP-Mail-Client/src/extras/MB_String.h index 775ade48d..c5a8c00db 100644 --- a/lib/libesp32/ESP-Mail-Client/src/extras/MB_String.h +++ b/lib/libesp32/ESP-Mail-Client/src/extras/MB_String.h @@ -1,2075 +1,2075 @@ - -/** - * Mobizt's SRAM/PSRAM supported String, version 1.2.9 - * - * Created December 3, 2022 - * - * Changes Log - * - * v1.2.9 - * - substring optimization - * - * v1.2.8 - * - Add support StringSumHelper class in Arduino - * - * v1.2.7 - * - Fix string sub type checking issue - * - * v1.2.6 - * - Update trim() function - * - * v1.2.5 - * - Fixed double string issue and add support long double - * - * v1.2.4 - * - Check PSRAM availability before allocating the memory - * - * v1.2.3 - * - Fixed flash string F and PSTR handle - * - * v1.2.2 - * - Add supports more MCUs. - * - * v1.2.1 - * - Add flash string manipulation functions. - * - * v1.2.0 - * - Add supports bool, integer and float manipulation. - * - * v1.1.2 - * - Fix substring with zero length returns the original string issue. - * - * v1.1.1 - * - Fix possible ESP8266 code exit without resetting the external heap stack - * - * v1.1.0 - * - Add support ESP8266 external virtual RAM (SRAM or PSRAM) - * - * v1.0.1 - * - Add trim function - * - Add version enum - * - * v1.0.0 - * - Initial release - * - * The MIT License (MIT) - * Copyright (c) 2023 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person returning 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 MB_String_H -#define MB_String_H - -#include -#if !defined(__AVR__) -#include -#include -#include -#endif - -#define MB_STRING_MAJOR 1 -#define MB_STRING_MINOR 2 -#define MB_STRING_PATCH 5 - -#if defined(ESP8266) && defined(MMU_EXTERNAL_HEAP) && defined(MB_STRING_USE_PSRAM) -#include -#include -#define ESP8266_USE_EXTERNAL_HEAP -#endif - -#if defined(ESP8266) || defined(ESP32) -#define MBSTRING_FLASH_MCR FPSTR -#elif defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) -#define MBSTRING_FLASH_MCR PSTR -#else -#define MBSTRING_FLASH_MCR(s) (s) -#endif - -class MB_String; - -#define pgm2Str(p) (MB_String().appendP(p).c_str()) -#define num2Str(v, p) (MB_String().appendNum(v, p).c_str()) - -#if defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F4) -#define MB_IS_SAME std::is_same -#define MB_ENABLE_IF std::enable_if -#else -#define MB_IS_SAME is_same -#define MB_ENABLE_IF enable_if -#endif - -namespace mb_string -{ - enum mb_string_sub_type - { - mb_string_sub_type_none, - mb_string_sub_type_bool, - mb_string_sub_type_float, - mb_string_sub_type_double, - mb_string_sub_type_int8, - mb_string_sub_type_uint8, - mb_string_sub_type_int16, - mb_string_sub_type_uint16, - mb_string_sub_type_int32, - mb_string_sub_type_uint32, - mb_string_sub_type_int64, - mb_string_sub_type_uint64, - mb_string_sub_type_cstring, - mb_string_sub_type_chars, - mb_string_sub_type_mb_string, - mb_string_sub_type_arduino_string, - mb_string_sub_type_std_string, - mb_string_sub_type_fptr, - mb_string_sub_type_string_sum_helper - - }; - - typedef struct mb_string_ptr_t - { - - public: - mb_string_ptr_t(uint32_t addr = 0, mb_string_sub_type type = mb_string_sub_type_cstring, int precision = -1, const StringSumHelper *s = nullptr) - { - _addr = addr; - _type = type; - _precision = precision; - _ssh = s; - } - int precision() { return _precision; } - mb_string_sub_type type() { return _type; } - uint32_t address() { return _addr; } - const StringSumHelper *stringsumhelper() { return _ssh; } - - private: - mb_string_sub_type _type = mb_string_sub_type_none; - int _precision = -1; - uint32_t _addr = 0; - const StringSumHelper *_ssh = nullptr; - - } MB_StringPtr; - - template - struct enable_if - { - }; - template - struct enable_if - { - typedef T type; - }; - template - struct is_same - { - static bool const value = false; - }; - template - struct is_same - { - static bool const value = true; - }; - - template - struct is_num_int8 - { - static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; - }; - - template - struct is_num_uint8 - { - static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; - }; - - template - struct is_num_int16 - { - static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; - }; - - template - struct is_num_uint16 - { - static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; - }; - - template - struct is_num_int32 - { - static bool const value = MB_IS_SAME::value || MB_IS_SAME::value || - MB_IS_SAME::value || MB_IS_SAME::value || - MB_IS_SAME::value; - }; - - template - struct is_num_uint32 - { - static bool const value = MB_IS_SAME::value || MB_IS_SAME::value || - MB_IS_SAME::value; - }; - - template - struct is_num_int64 - { - static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; - }; - - template - struct is_num_uint64 - { - static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; - }; - - template - struct is_num_neg_int - { - static bool const value = is_num_int8::value || is_num_int16::value || - is_num_int32::value || is_num_int64::value; - }; - - template - struct is_num_pos_int - { - static bool const value = is_num_uint8::value || is_num_uint16::value || - is_num_uint32::value || is_num_uint64::value; - }; - - template - struct is_num_int - { - static bool const value = is_num_pos_int::value || is_num_neg_int::value; - }; - - template - struct is_num_float - { - static bool const value = MB_IS_SAME::value || MB_IS_SAME::value || MB_IS_SAME::value; - }; - - template - struct is_bool - { - static bool const value = MB_IS_SAME::value; - }; - - template - struct cs_t - { - static bool const value = MB_IS_SAME::value; - }; - - template - struct ccs_t - { - static bool const value = MB_IS_SAME::value; - }; - - template - struct as_t - { - static bool const value = MB_IS_SAME::value; - }; - - template - struct cas_t - { - static bool const value = MB_IS_SAME::value; - }; - - template - struct ss_t - { -#if !defined(__AVR__) - static bool const value = MB_IS_SAME::value; -#else - static bool const value = false; -#endif - }; - - template - struct css_t - { -#if !defined(__AVR__) - static bool const value = MB_IS_SAME::value; -#else - static bool const value = false; -#endif - }; - - template - struct ssh_t - { - static bool const value = MB_IS_SAME::value; - }; - - template - struct fs_t - { - static bool const value = MB_IS_SAME::value; - }; - - template - struct mbs_t - { - static bool const value = MB_IS_SAME::value; - }; - - template - struct cmbs_t - { - static bool const value = MB_IS_SAME::value; - }; - - template - struct pgm_t - { - static bool const value = MB_IS_SAME::value; - }; - - template - struct is_const_chars - { - static bool const value = cs_t::value || ccs_t::value; - }; - - template - struct is_arduino_string - { - static bool const value = as_t::value || cas_t::value; - }; - - template - struct is_std_string - { - static bool const value = ss_t::value || css_t::value; - }; - - template - struct is_mb_string - { - static bool const value = mbs_t::value || cmbs_t::value; - }; - - template - struct is_arduino_string_sum_helper - { - static bool const value = ssh_t::value; - }; - - template - struct is_arduino_flash_string_helper - { - static bool const value = fs_t::value; - }; - - template - struct is_string - { - static bool const value = is_const_chars::value || is_arduino_string::value || - is_arduino_string_sum_helper::value || is_arduino_flash_string_helper::value || - is_std_string::value || is_mb_string::value; - }; - - template - uint32_t toAddr(T &v) { return reinterpret_cast(&v); } - -#if defined(__AVR__) - template - T addrTo(int address) - { - return reinterpret_cast(address); - } -#else - template - auto addrTo(int address) -> typename MB_ENABLE_IF::value, T>::type - { - return reinterpret_cast(address); - } -#endif - - template - auto getSubType(T val) -> typename MB_ENABLE_IF::value || is_num_float::value || MB_IS_SAME::value || is_const_chars::value || is_arduino_flash_string_helper::value || is_arduino_string::value || is_std_string::value || is_mb_string::value || MB_IS_SAME::value, mb_string_sub_type>::type - { - if (is_num_uint64::value) - return mb_string_sub_type_uint64; - else if (is_num_int64::value) - return mb_string_sub_type_int64; - else if (is_num_uint32::value) - return mb_string_sub_type_uint32; - else if (is_num_int32::value) - return mb_string_sub_type_int32; - else if (is_num_uint16::value) - return mb_string_sub_type_uint16; - else if (is_num_int16::value) - return mb_string_sub_type_int16; - else if (is_num_uint8::value) - return mb_string_sub_type_uint8; - else if (is_num_int8::value) - return mb_string_sub_type_int8; - else if (MB_IS_SAME::value) - return mb_string_sub_type_bool; - else if (MB_IS_SAME::value) - return mb_string_sub_type_float; - else if (MB_IS_SAME::value) - return mb_string_sub_type_double; - else if (is_arduino_string::value) - return mb_string_sub_type_arduino_string; - else if (is_std_string::value) - return mb_string_sub_type_std_string; - else if (is_mb_string::value) - return mb_string_sub_type_mb_string; - else if (is_arduino_flash_string_helper::value) - return mb_string_sub_type_fptr; - else if (MB_IS_SAME::value) - return mb_string_sub_type_string_sum_helper; - else if (ccs_t::value) - return mb_string_sub_type_cstring; - else if (cs_t::value) - return mb_string_sub_type_chars; - - return mb_string_sub_type_int8; - } - - template - auto getSubType(T *val) -> typename MB_ENABLE_IF::value || is_num_float::value || MB_IS_SAME::value || is_const_chars::value || is_arduino_flash_string_helper::value || is_arduino_string::value || is_std_string::value || is_mb_string::value || MB_IS_SAME::value, mb_string_sub_type>::type - { - return getSubType(*val); - } - - template - auto toStringPtr(const T &val) -> typename MB_ENABLE_IF::value || is_arduino_string::value || is_mb_string::value, MB_StringPtr>::type - { - return MB_StringPtr(reinterpret_cast(&val), getSubType(val)); - } - - template - auto toStringPtr(const T &val) -> typename MB_ENABLE_IF::value, MB_StringPtr>::type - { -#if defined(ESP8266) - return MB_StringPtr(reinterpret_cast(&val), getSubType(val), -1); - -#else - return MB_StringPtr(reinterpret_cast(&val), getSubType(val), -1, &val); -#endif - } - - template - auto toStringPtr(T val) -> typename MB_ENABLE_IF::value, MB_StringPtr>::type { return MB_StringPtr(reinterpret_cast(val), getSubType(val)); } - - template - auto toStringPtr(T &val) -> typename MB_ENABLE_IF::value, MB_StringPtr>::type { return MB_StringPtr(reinterpret_cast(val), getSubType(val)); } - -#if !defined(__AVR__) - template - auto toStringPtr(T val) -> typename MB_ENABLE_IF::value, MB_StringPtr>::type - { - return MB_StringPtr(); - } -#endif - - template - auto toStringPtr(T val) -> typename MB_ENABLE_IF::value, MB_StringPtr>::type - { - return val; - } - - template - auto toStringPtr(T &val, int precision = -1) -> typename MB_ENABLE_IF::value || is_num_float::value || MB_IS_SAME::value, MB_StringPtr>::type { return MB_StringPtr(reinterpret_cast(&val), getSubType(val), precision); } -} - -using namespace mb_string; - -class MB_String -{ -public: - MB_String() - { -#if defined(ESP8266_USE_EXTERNAL_HEAP) - // reserve default 1 byte external heap to refer to its pointer later - reset(1); -#endif - }; - - ~MB_String() - { - allocate(0, false); - }; - - MB_String(const char *cstr) - { - if (cstr) - copy(cstr, strlen_P(cstr)); - } - - MB_String(const MB_String &value) - { - *this = value; - } - - MB_String(const __FlashStringHelper *str) - { - *this = str; - } - -#if !defined(ESP8266) - MB_String(StringSumHelper rval) - { - *this = rval; - } -#endif - - MB_String(MB_StringPtr value) - { - *this = value; - } - - MB_String(String value) - { - *this = value; - } - - MB_String(bool value) - { - appendNum(value); - } - - MB_String(unsigned char value, unsigned char base = 10) - { - int len = 1 + 8 * sizeof(unsigned char); - reserve(len); - - if (bufLen > 0) - utoa(value, buf, base); - } - - MB_String(int value, unsigned char base = 10) - { - int len = 2 + 8 * sizeof(int); - reserve(len); - - if (bufLen > 0) - { - if (base == 10) - sprintf(buf, (const char *)MBSTRING_FLASH_MCR("%d"), value); - else - itoa(value, buf, base); - } - } - - MB_String(unsigned int value, unsigned char base = 10) - { - int len = 1 + 8 * sizeof(unsigned int); - reserve(len); - - if (bufLen > 0) - utoa(value, buf, base); - } - - MB_String(long value, unsigned char base = 10) - { - int len = 2 + 8 * sizeof(long); - reserve(len); - - if (bufLen > 0) - { - if (base == 10) - sprintf(buf, (const char *)MBSTRING_FLASH_MCR("%ld"), value); - else - ltoa(value, buf, base); - } - } - - MB_String(unsigned long value, unsigned char base = 10) - { - int len = 1 + 8 * sizeof(unsigned long); - reserve(len); - - if (bufLen > 0) - ultoa(value, buf, base); - } - - MB_String(float value, unsigned char decimalPlaces = 2) - { - reserve(33); - if (bufLen > 0) - { - char *v = toFloatStr(value, 0, decimalPlaces); - if (v) - { - strcpy(buf, v); - delP(&v); - } - } - } - - MB_String(double value, unsigned char decimalPlaces = 3) - { - reserve(33); - - if (bufLen > 0) - { - char *v = toFloatStr(value, 1, decimalPlaces); - if (v) - { - strcpy(buf, v); - delP(&v); - } - } - } - - MB_String(long double value, unsigned char decimalPlaces = 3) - { - reserve(65); - if (bufLen > 0) - { - char *v = toFloatStr(value, 2, decimalPlaces); - if (v) - { - strcpy(buf, v); - delP(&v); - } - } - } - -#if !defined(__AVR__) - MB_String &operator=(const std::string &rhs) - { - if (rhs.length() > 0) - copy(rhs.c_str(), rhs.length()); - else - clear(); - - return *this; - } -#endif - MB_String &operator=(const String &rhs) - { - - if (rhs.length() > 0) - copy(rhs.c_str(), rhs.length()); - else - clear(); - - return *this; - } - - MB_String &operator=(const __FlashStringHelper *str) - { - if (str) - appendF(str, true); - - return *this; - } - -#if !defined(ESP8266) - MB_String &operator=(StringSumHelper rval) - { - String temp = rval; - *this = temp; - return *this; - } - - MB_String &operator+=(StringSumHelper rval) - { - String temp = rval; - *this += temp; - return *this; - } -#endif - - MB_String &operator+=(const __FlashStringHelper *str) - { - if (str) - appendF(str); - - return *this; - } - - unsigned char operator==(const MB_String &rhs) const - { - return equals(rhs); - } - - unsigned char operator==(const char *cstr) const - { - return equals(cstr); - } - - unsigned char operator!=(const MB_String &rhs) const - { - return !equals(rhs); - } - - unsigned char operator!=(const char *cstr) const - { - return !equals(cstr); - } -#if !defined(__AVR__) - MB_String &operator+=(const std::string &rhs) - { - concat(rhs.c_str()); - return (*this); - } -#endif - MB_String &operator+=(const String &rhs) - { - concat(rhs.c_str()); - return (*this); - } - - MB_String &operator=(const MB_String &rhs) - { - if (this == &rhs) - return *this; - - if (rhs.length() > 0) - copy(rhs.buf, rhs.length()); - else - clear(); - - return *this; - } - - MB_String &operator+=(const MB_String &rhs) - { - concat(rhs); - return (*this); - } - - MB_String &operator+=(const char *cstr) - { - size_t len = strlen_P(cstr); - size_t slen = length(); - - if (_reserve(slen + len, false)) - { - strcat_P(buf, (PGM_P)cstr); - *(buf + slen + len) = '\0'; - } - - return (*this); - } - - MB_String &operator+=(char cstr) - { - append(1, cstr); - return (*this); - } - - MB_String &operator+=(bool value) - { - appendNum(value); - return (*this); - } - - MB_String &operator=(MB_StringPtr ptr) - { - setPtr(ptr); - return (*this); - } - - MB_String &operator+=(MB_StringPtr ptr) - { - appendPtr(ptr); - return (*this); - } - - template - auto operator=(T value) -> typename MB_ENABLE_IF::value || is_num_float::value || is_bool::value, MB_String &>::type - { - clear(); - appendNum(value); - return (*this); - } - - template - auto operator+=(T value) -> typename MB_ENABLE_IF::value || is_num_float::value || is_bool::value, MB_String &>::type - { - appendNum(value); - return (*this); - } - - MB_String &appendP(PGM_P pgms, bool clear = false) - { - if (clear) - this->clear(); - - char *t = pgmStr(pgms); - if (t) - { - *this += t; - delP(&t); - } - - return (*this); - } - - MB_String &appendF(const __FlashStringHelper *pstr, bool clear = false) - { - if (clear) - this->clear(); - - int len = strlen_P((PGM_P)pstr); - if (len > 0) - { - unsigned int newlen = length() + len; - reserve(newlen); - - if (bufLen > 0) - memcpy_P(buf + length(), (PGM_P)pstr, len + 1); - } - - return (*this); - } - - MB_String &setPtr(MB_StringPtr src) - { - clear(); - appendPtr(src); - return (*this); - }; - - MB_String &appendPtr(MB_StringPtr src) - { - if (src.type() == mb_string_sub_type_fptr) - appendF(addrTo(src.address())); - else if (src.type() == mb_string_sub_type_cstring || src.type() == mb_string_sub_type_chars) - *this += addrTo(src.address()); - else if (src.type() == mb_string_sub_type_arduino_string) - *this += *addrTo(src.address()); - else if (src.type() == mb_string_sub_type_string_sum_helper) -#if !defined(ESP8266) - *this += *src.stringsumhelper(); -#else - *this += *addrTo(src.address()); -#endif -#if !defined(__AVR__) - else if (src.type() == mb_string_sub_type_std_string) - *this += *addrTo(src.address()); -#endif - else if (src.type() == mb_string_sub_type_mb_string) - *this += *addrTo(src.address()); - else if (src.type() == mb_string_sub_type_uint64) - appendNum(*addrTo(src.address())); - else if (src.type() == mb_string_sub_type_int64) - appendNum(*addrTo(src.address())); - else if (src.type() == mb_string_sub_type_uint32) - appendNum(*addrTo(src.address())); - else if (src.type() == mb_string_sub_type_int32) - appendNum(*addrTo(src.address())); - else if (src.type() == mb_string_sub_type_uint16) - appendNum(*addrTo(src.address())); - else if (src.type() == mb_string_sub_type_int16) - appendNum(*addrTo(src.address())); - else if (src.type() == mb_string_sub_type_uint8) - appendNum(*addrTo(src.address())); - else if (src.type() == mb_string_sub_type_int8) - appendNum(*addrTo(src.address())); - else if (src.type() == mb_string_sub_type_bool) - appendNum(*addrTo(src.address())); - else if (src.type() == mb_string_sub_type_float) - appendNum(*addrTo(src.address()), src.precision()); - else if (src.type() == mb_string_sub_type_double) - appendNum(*addrTo(src.address()), src.precision()); - - return (*this); - }; - - template - auto appendNum(T value, int precision = 0) -> typename MB_ENABLE_IF::value || is_bool::value, MB_String &>::type - { - char *s = NULL; - - if (is_bool::value) - s = boolStr(value); - else if (is_num_neg_int::value) - { -#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) - s = int32Str(value); -#else - s = int64Str(value); -#endif - } - else if (is_num_pos_int::value) - { -#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) - s = uint32Str(value); -#else - s = uint64Str(value); -#endif - } - - if (s) - { - *this += s; - delP(&s); - } - - return (*this); - } - - MB_String &appendNum(float value, int precision = 5) - { - if (precision < 0) - precision = 5; - - char *s = toFloatStr(value, 0, precision); - if (s) - { - *this += s; - delP(&s); - } - return (*this); - } - - MB_String &appendNum(double value, int precision = 9) - { - if (precision < 0) - precision = 9; - - char *s = toFloatStr(value, 1, precision); - if (s) - { - *this += s; - delP(&s); - } - return (*this); - } - - MB_String &appendNum(long double value, int precision = 9) - { - if (precision < 0) - precision = 9; - - char *s = toFloatStr(value, 2, precision); - if (s) - { - *this += s; - delP(&s); - } - return (*this); - } - - MB_String &operator=(const char *cstr) - { - if (cstr) - copy(cstr, strlen_P(cstr)); - else - clear(); - - return *this; - } - - MB_String &operator=(char c) - { - clear(); - if (_reserve(1, false)) - { - *(buf) = c; - *(buf + 1) = '\0'; - } - - return *this; - } - - void trim() - { - int p1 = 0, p2 = length() - 1; - while (p1 < (int)length()) - { - if (buf[p1] > 32) - break; - p1++; - } - - while (p2 >= 0) - { - if (buf[p2] > 32) - break; - p2--; - } - - if (p1 == (int)length() && p2 < 0) - { - clear(); - return; - } - - if (p2 >= p1 && p2 >= 0 && p1 < (int)length()) - { - memmove(buf, buf + p1, p2 - p1 + 1); - buf[p2 - p1 + 1] = '\0'; - _reserve(p2 - p1 + 1, true); - } - } - - void append(const char *cstr, size_t n) - { - if (!cstr) - return; - - size_t slen = length(); - - if (n > strlen(cstr)) - n = strlen(cstr); - - if (_reserve(slen + n, false)) - { - memmove(buf + slen, cstr, n); - *(buf + slen + n) = '\0'; - } - } - - void append(size_t n, char c) - { - size_t slen = length(); - - if (_reserve(slen + n, false)) - { - for (size_t i = 0; i < n; i++) - *(buf + slen + i) = c; - *(buf + slen + n) = '\0'; - } - } - - void prepend(char c) - { - size_t slen = length(); - size_t len = 1; - - if (maxLength() < slen + len) - _reserve(slen + len, false); - - memmove(buf + len, buf, slen); - buf[0] = c; - buf[len + slen] = '\0'; - } - - void prepend(const char *cstr) - { - size_t slen = length(); - size_t len = strlen(cstr); - - if (maxLength() < slen + len) - _reserve(slen + len, false); - - memmove(buf + len, buf, slen); - memmove(buf, cstr, len); - buf[len + slen] = '\0'; - } - - const char *c_str() const - { - if (!buf) - return ""; - return (const char *)buf; - } - - char operator[](size_t index) const - { - if (index >= bufLen || !buf) - return 0; - return buf[index]; - } - - char &operator[](size_t index) - { - static char c; - if (index >= bufLen || !buf) - { - c = '\0'; - return c; - } - return buf[index]; - } - - void swap(MB_String &rhs) - { - rhs.clear(); - } - - void shrink_to_fit() - { - size_t slen = length(); - _reserve(slen, true); - } - - void pop_back() - { - if (length() > 0) - { - size_t slen = length(); - if (slen > 0) - buf[slen - 1] = '\0'; - _reserve(slen, true); - } - } - - size_t size() const - { - return length(); - } - - size_t bufferLength() const - { - return bufLen; - } - - size_t find(const MB_String &s, size_t index = 0) const - { - if (!s.buf) - return -1; - return strpos(buf, s.buf, index); - } - - size_t find(const char *s, size_t index = 0) const - { - return strpos(buf, s, index); - } - - size_t find(char c, size_t index = 0) const - { - return strpos(buf, c, index); - } - - size_t rfind(const char *s, size_t index = npos) const - { - return rstrpos(buf, s, index); - } - - size_t rfind(char c, size_t index = npos) const - { - return rstrpos(buf, c, index); - } - - void erase(size_t index = 0, size_t len = npos) - { - - if (!buf || index >= length()) - return; - - if (index + len > length() || len == npos) - len = length() - index; - - int rightLen = length() - index - len; - - memmove(buf + index, buf + index + len, rightLen); - - buf[index + rightLen] = '\0'; - - _reserve(length(), true); - } - - size_t length() const - { - if (!buf) - return 0; - return strlen(buf); - } - - MB_String substr(size_t offset, size_t len = npos) const - { - MB_String out; - substr(out, offset, len); - return out; - } - - void substr(MB_String &out, size_t offset, size_t len = npos) const - { - if (len > 0 && length() > 0 && offset < length()) - { - if (len > length() - offset) - len = length() - offset; - out.copy(buf + offset, len); - } - } - - void clear() - { -#if defined(ESP8266_USE_EXTERNAL_HEAP) - reset(1); -#else - allocate(0, false); -#endif - } - -#if defined(ESP8266_USE_EXTERNAL_HEAP) - void reset(size_t len) - { - if (len == 0) - len = 4; - ESP.setExternalHeap(); - if (buf) - buf = (char *)realloc(buf, len); - else - buf = (char *)malloc(len); - ESP.resetHeap(); - - if (buf) - { - bufLen = len; - memset(buf, 0, len); - } - } -#endif - - void resize(size_t len) - { - if (_reserve(len, true)) - buf[len] = '\0'; - } - - MB_String &replace(size_t pos, size_t len, const char *replace) - { - size_t repLen = strlen(replace); - - if (length() > 0 && length() > pos && repLen > 0) - { - if (pos + len > length()) - len = length() - pos; - - if (repLen > len) - { - size_t rightLen = length() - pos - len; - - if (maxLength() < length() + repLen - len) - _reserve(length() + repLen - len, false); - - memmove(buf + pos + repLen, buf + pos + len, rightLen); - buf[pos + repLen + rightLen] = '\0'; - } - - memmove(buf + pos, replace, repLen); - } - - return *this; - } - - MB_String &replace(size_t pos, size_t len, const MB_String &replace) - { - return this->replace(pos, len, replace.c_str()); - } - - MB_String &insert(size_t pos, size_t n, char c) - { - size_t slen = length(); - - size_t rightLen = slen - pos; - - if (maxLength() < slen + n) - _reserve(slen + n, false); - - if (maxLength() >= slen + n) - { - memmove(buf + pos + n, buf + pos, rightLen); - - for (size_t i = 0; i < n; i++) - *(buf + pos + i) = c; - - buf[pos + n + rightLen] = '\0'; - } - - return *this; - } - - MB_String &insert(size_t pos, const char *cstr) - { - size_t insLen = strlen(cstr); - - if (length() > 0 && length() > pos && insLen > 0) - { - - size_t rightLen = length() - pos; - - if (maxLength() < length() + insLen) - _reserve(length() + insLen, false); - - memmove(buf + pos + insLen, buf + pos, rightLen); - buf[pos + insLen + rightLen] = '\0'; - memmove(buf + pos, cstr, insLen); - } - - return *this; - } - - MB_String &insert(size_t pos, const MB_String &str) - { - return insert(pos, str.c_str()); - } - - MB_String &insert(size_t pos, char c) - { - char temp[2]{c, '\0'}; - return insert(pos, temp); - } - - size_t find_first_of(const char *cstr, size_t pos = 0) const - { - if (!cstr) - return -1; - - return strpos(buf, cstr, pos); - } - - size_t find_first_of(const MB_String &str, size_t pos = 0) const - { - if (length() == 0 || pos >= length()) - return -1; - - return find_first_of(str.buf, pos); - } - - size_t find_first_not_of(const char *cstr, size_t pos = 0) const - { - if (length() == 0 || pos >= length()) - return -1; - - int size = strcspn(buf + pos, cstr); - if (size == 0) - { - while (size == 0 && pos < length()) - { - size = strcspn(buf + pos, cstr); - pos++; - } - - if (pos > 0) - pos--; - } - - return pos; - } - - size_t find_first_not_of(const MB_String &str, size_t pos = 0) const - { - if (length() == 0 || pos >= length() || str.length() == 0) - return -1; - - return find_first_not_of(str.buf, pos); - } - - size_t find_last_of(const char *cstr, size_t pos = npos) const - { - if (!cstr) - return -1; - - return rstrpos(buf, cstr, pos); - } - - size_t find_last_of(const MB_String &str, size_t pos = npos) const - { - if (str.length() == 0) - return -1; - - return find_last_of(str.buf, pos); - } - - size_t find_last_not_of(const char *cstr, size_t pos = npos) const - { - if (length() == 0) - return -1; - - if (pos >= length()) - pos = length() - 1; - - int p = length() - 1; - int size = strcspn(buf + p, cstr); - if (size == 0) - { - while (size == 0 && p > 0) - { - size = strcspn(buf + p, cstr); - p--; - } - p++; - } - - return p; - } - - size_t find_last_not_of(const MB_String &str, size_t pos = npos) const - { - if (str.length() == 0) - return -1; - - return find_last_not_of(str.buf, pos); - } - - MB_String & replaceAll(const char *find, const char *replace) - { - if (length() == 0) - return *this;; - - int i, cnt = 0; - int repLen = strlen(replace); - int findLen = strlen(find); - - MB_String temp = buf; - char *s = temp.buf; - clear(); - - for (i = 0; s[i] != '\0'; i++) - { - if (strstr(&s[i], find) == &s[i]) - { - cnt++; - i += findLen - 1; - } - } - - if (_reserve(i + cnt * (repLen - findLen) + 1, false)) - { - i = 0; - while (*s) - { - if (strstr(s, find) == s) - { - strcpy(&buf[i], replace); - i += repLen; - s += findLen; - } - else - buf[i++] = *s++; - } - - buf[i] = '\0'; - } - - temp.clear(); - - return *this; - } - - void replaceAll(const MB_String &find, const MB_String &replace) - { - replaceAll(find.c_str(), replace.c_str()); - } - - bool empty() const - { - return length() == 0; - } - - void reserve(size_t len) - { - if (_reserve(len, false)) - buf[len] = '\0'; - } - - static const size_t npos = -1; - -private: -#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) - - char *int32Str(signed long value) - { - char *t = (char *)newP(64); - sprintf(t, (const char *)MBSTRING_FLASH_MCR("%ld"), value); - return t; - } - - char *uint32Str(unsigned long value) - { - char *t = (char *)newP(64); - sprintf(t, (const char *)MBSTRING_FLASH_MCR("%lu"), value); - return t; - } - -#endif - - char *int64Str(signed long long value) - { - char *t = (char *)newP(64); - sprintf(t, (const char *)MBSTRING_FLASH_MCR("%lld"), value); - return t; - } - - char *uint64Str(unsigned long long value) - { - char *t = (char *)newP(64); - sprintf(t, (const char *)MBSTRING_FLASH_MCR("%llu"), value); - return t; - } - - char *boolStr(bool value) - { - char *t = (char *)newP(8); - value ? strcpy(t, (const char *)MBSTRING_FLASH_MCR("true")) : strcpy(t, (const char *)MBSTRING_FLASH_MCR("false")); - return t; - } - - char *toFloatStr(long double value, int type, int precision) - { - int width = type == 0 ? 32 : 64; - - char *t = (char *)newP(width); - - if (t) - { - MB_String fmt = MBSTRING_FLASH_MCR("%."); - fmt += precision; - if (type == 2) - fmt += MBSTRING_FLASH_MCR("L"); - fmt += MBSTRING_FLASH_MCR("f"); - sprintf(t, fmt.c_str(), value); - trim(t); - } - - return t; - } - - char *nullStr() - { - char *t = (char *)newP(6); - strcpy(t, (const char *)MBSTRING_FLASH_MCR("null")); - return t; - } - - char *pgmStr(PGM_P p) - { - char *t = (char *)newP(strlen_P(p)); - strcpy_P(t, p); - return t; - } - - void trim(char *s) - { - if (!s) - return; - size_t i = strlen(s) - 1; - while (s[i] == '0' && i > 0) - { - if (s[i - 1] == '.') - { - i--; - break; - } - if (s[i - 1] != '0') - break; - i--; - } - if (i < strlen(s) - 1) - s[i] = '\0'; - } - - void *newP(size_t len) - { - void *p; - size_t newLen = getReservedLen(len); -#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) - if (ESP.getPsramSize() > 0) - p = (void *)ps_malloc(newLen); - else - p = (void *)malloc(newLen); - if (!p) - return NULL; - -#else - -#if defined(ESP8266_USE_EXTERNAL_HEAP) - ESP.setExternalHeap(); -#endif - - p = (void *)malloc(newLen); - bool nn = p ? true : false; - -#if defined(ESP8266_USE_EXTERNAL_HEAP) - ESP.resetHeap(); -#endif - - if (!nn) - return NULL; - -#endif - memset(p, 0, newLen); - return p; - } - - void delP(void *ptr) - { - void **p = (void **)ptr; - if (*p) - { - free(*p); - *p = 0; - } - } - - size_t getReservedLen(size_t len) - { - int blen = len + 1; - - int newlen = (blen / 4) * 4; - - if (newlen < blen) - newlen += 4; - - return (size_t)newlen; - } - - size_t maxLength() const - { - if (bufferLength() == 0) - return 0; - return bufferLength() - 1; - } - - void concat(const MB_String &s) - { - if (s.length() == 0) - return; - - if (&s == this) - { - size_t slen = length(); - - if (2 * slen > maxLength()) - { - if (!_reserve(2 * slen, false)) - return; - } - - memmove(buf + slen, buf, slen); - buf[2 * slen] = '\0'; - } - else - { - concat(s.buf, s.length()); - } - } - - void concat(const char *cstr, size_t len) - { - if (!cstr) - return; - - size_t slen = length(); - - if (slen + len > maxLength()) - { - if (!_reserve(slen + len, false)) - return; - } - - memmove(buf + slen, cstr, len); - buf[slen + len] = '\0'; - } - - void concat(const char *cstr) - { - if (!cstr) - return; - - concat(cstr, strlen(cstr)); - } - - void move(MB_String &rhs) - { - if (buf) - { - if (bufLen >= rhs.bufLen) - { - strcpy(buf, rhs.buf); - bufLen = rhs.bufLen; - rhs.bufLen = 0; - return; - } - else - { - free(buf); - } - } - buf = rhs.buf; - bufLen = rhs.bufLen; - rhs.buf = NULL; - } - - void allocate(size_t len, bool shrink) - { - - if (len == 0) - { - if (buf) - free(buf); - buf = NULL; - bufLen = 0; - return; - } - - if (len > bufLen || shrink) - { - -#if defined(ESP8266_USE_EXTERNAL_HEAP) - ESP.setExternalHeap(); -#endif - - if (shrink || (bufLen > 0 && buf)) - { - int slen = length(); - -#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) - if (ESP.getPsramSize() > 0) - buf = (char *)ps_realloc(buf, len); - else - buf = (char *)realloc(buf, len); -#else - buf = (char *)realloc(buf, len); -#endif - if (buf) - { - buf[slen] = '\0'; - bufLen = len; - } - } - else - { -#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) - if (ESP.getPsramSize() > 0) - buf = (char *)ps_malloc(len); - else - buf = (char *)malloc(len); -#else - buf = (char *)malloc(len); -#endif - if (buf) - { - buf[0] = '\0'; - bufLen = len; - } - } - -#if defined(ESP8266_USE_EXTERNAL_HEAP) - ESP.resetHeap(); -#endif - } - } - - MB_String ©(const char *cstr, size_t length) - { - - if (!_reserve(length, false)) - { - clear(); - return *this; - } - - memcpy_P(buf, (PGM_P)cstr, length); - buf[length] = '\0'; - - return *this; - } - - bool _reserve(size_t len, bool shrink) - { - - size_t newlen = getReservedLen(len); - if (shrink) - allocate(newlen, true); - else if (newlen > bufLen) - allocate(newlen, false); - - return newlen <= bufLen; - } - - int strpos(const char *haystack, const char *needle, int offset) const - { - if (!haystack || !needle) - return -1; - - int hlen = strlen(haystack); - int nlen = strlen(needle); - - if (hlen == 0 || nlen == 0) - return -1; - - int hidx = offset, nidx = 0; - while ((*(haystack + hidx) != '\0') && (*(needle + nidx) != '\0') && hidx < hlen) - { - if (*(needle + nidx) != *(haystack + hidx)) - { - hidx++; - nidx = 0; - } - else - { - nidx++; - hidx++; - if (nidx == nlen) - return hidx - nidx; - } - } - - return -1; - } - - int strpos(const char *haystack, char needle, int offset) const - { - if (!haystack || needle == 0) - return -1; - - int hlen = strlen(haystack); - - if (hlen == 0) - return -1; - - int hidx = offset; - while ((*(haystack + hidx) != '\0') && hidx < hlen) - { - if (needle == *(haystack + hidx)) - return hidx; - hidx++; - } - - return -1; - } - - int rstrpos(const char *haystack, const char *needle, int offset /* start search from this offset to the left string */) const - { - if (!haystack || !needle) - return -1; - - int hlen = strlen(haystack); - int nlen = strlen(needle); - - if (hlen == 0 || nlen == 0) - return -1; - - int hidx = offset; - - if (hidx >= hlen || (size_t)offset == npos) - hidx = hlen - 1; - - int nidx = nlen - 1; - - while (hidx >= 0) - { - if (*(needle + nidx) != *(haystack + hidx)) - { - hidx--; - nidx = nlen - 1; - } - else - { - if (nidx == 0) - return hidx + nidx; - nidx--; - hidx--; - } - } - - return -1; - } - - int rstrpos(const char *haystack, char needle, int offset /* start search from this offset to the left char */) const - { - if (!haystack || needle == 0) - return -1; - - int hlen = strlen(haystack); - - if (hlen == 0) - return -1; - - int hidx = offset; - - if (hidx >= hlen || (size_t)offset == npos) - hidx = hlen - 1; - - while (hidx >= 0) - { - if (needle == *(haystack + hidx)) - return hidx; - hidx--; - } - - return -1; - } - - int compareTo(const MB_String &s) const - { - if (!buf || !s.buf) - { - if (s.buf && s.length() > 0) - return 0 - *(unsigned char *)s.buf; - if (buf && length() > 0) - return *(unsigned char *)buf; - return 0; - } - return strcmp(buf, s.buf); - } - - unsigned char equals(const MB_String &s2) const - { - return (length() == s2.length() && compareTo(s2) == 0); - } - - unsigned char equals(const char *cstr) const - { - if (length() == 0) - return (cstr == NULL || *cstr == 0); - if (cstr == NULL) - return buf[0] == 0; - return strcmp(buf, cstr) == 0; - } - - char *ultoa(unsigned long value, char *str, int radix) - { - const char *format = NULL; - - switch (radix) - { - case 8: - format = "%o"; - break; - case 10: - format = "%ul"; - break; - case 16: - format = "%x"; - break; - } - - if (format == NULL) - return str; - - int size = sprintf(str, format, value); - return &str[size]; - } - -#if (!defined(ESP32) && !defined(ESP8266) && !defined(ARDUINO_ARCH_STM32) && !defined(ARDUINO_ARCH_SAMD)) || defined(ARDUINO_NANO_RP2040_CONNECT) - char *ltoa(long value, char *str, int radix) - { - const char *format = NULL; - - switch (radix) - { - case 8: - format = "%o"; - break; - case 10: - format = "%l"; - break; - case 16: - format = "%x"; - break; - } - - if (format == NULL) - return str; - - int size = sprintf(str, format, value); - return &str[size]; - } - - char *utoa(unsigned int value, char *str, int radix) - { - const char *format = NULL; - - switch (radix) - { - case 8: - format = "%o"; - break; - case 10: - format = "%u"; - break; - case 16: - format = "%x"; - break; - } - - if (format == NULL) - return str; - - int size = sprintf(str, format, value); - return &str[size]; - } - - char *itoa(int value, char *str, int radix) - { - const char *format = NULL; - - switch (radix) - { - case 8: - format = "%o"; - break; - case 10: - format = "%d"; - break; - case 16: - format = "%x"; - break; - } - - if (format == NULL) - return str; - - int size = sprintf(str, format, value); - return &str[size]; - } -#endif - - char *buf = NULL; - size_t bufLen = 0; -}; - -inline MB_String operator+(const MB_String &lhs, const MB_String &rhs) -{ - MB_String res; - res.reserve(lhs.length() + rhs.length()); - res += lhs; - res += rhs; - return res; -} - -#if !defined(__AVR__) - -inline MB_String operator+(MB_String &&lhs, const MB_String &rhs) -{ - lhs += rhs; - return std::move(lhs); -} - -inline MB_String operator+(MB_String &lhs, MB_String &&rhs) -{ - lhs += rhs; - return std::move(lhs); -} - -inline MB_String operator+(MB_String &lhs, char rhs) -{ - lhs += rhs; - return std::move(lhs); -} - -inline MB_String operator+(char lhs, MB_String &rhs) -{ - rhs.insert(0, lhs); - return rhs; -} - -inline MB_String operator+(MB_String &&lhs, char rhs) -{ - return std::move(lhs.insert(0, rhs)); -} - -#endif - + +/** + * Mobizt's SRAM/PSRAM supported String, version 1.2.9 + * + * Created December 3, 2022 + * + * Changes Log + * + * v1.2.9 + * - substring optimization + * + * v1.2.8 + * - Add support StringSumHelper class in Arduino + * + * v1.2.7 + * - Fix string sub type checking issue + * + * v1.2.6 + * - Update trim() function + * + * v1.2.5 + * - Fixed double string issue and add support long double + * + * v1.2.4 + * - Check PSRAM availability before allocating the memory + * + * v1.2.3 + * - Fixed flash string F and PSTR handle + * + * v1.2.2 + * - Add supports more MCUs. + * + * v1.2.1 + * - Add flash string manipulation functions. + * + * v1.2.0 + * - Add supports bool, integer and float manipulation. + * + * v1.1.2 + * - Fix substring with zero length returns the original string issue. + * + * v1.1.1 + * - Fix possible ESP8266 code exit without resetting the external heap stack + * + * v1.1.0 + * - Add support ESP8266 external virtual RAM (SRAM or PSRAM) + * + * v1.0.1 + * - Add trim function + * - Add version enum + * + * v1.0.0 + * - Initial release + * + * The MIT License (MIT) + * Copyright (c) 2023 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person returning 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 MB_String_H +#define MB_String_H + +#include +#if !defined(__AVR__) +#include +#include +#include +#endif + +#define MB_STRING_MAJOR 1 +#define MB_STRING_MINOR 2 +#define MB_STRING_PATCH 5 + +#if defined(ESP8266) && defined(MMU_EXTERNAL_HEAP) && defined(MB_STRING_USE_PSRAM) +#include +#include +#define ESP8266_USE_EXTERNAL_HEAP +#endif + +#if defined(ESP8266) || defined(ESP32) +#define MBSTRING_FLASH_MCR FPSTR +#elif defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) +#define MBSTRING_FLASH_MCR PSTR +#else +#define MBSTRING_FLASH_MCR(s) (s) +#endif + +class MB_String; + +#define pgm2Str(p) (MB_String().appendP(p).c_str()) +#define num2Str(v, p) (MB_String().appendNum(v, p).c_str()) + +#if defined(ARDUINO_ARCH_STM32) || defined(ARDUINO_ARCH_STM32F1) || defined(ARDUINO_ARCH_STM32F4) +#define MB_IS_SAME std::is_same +#define MB_ENABLE_IF std::enable_if +#else +#define MB_IS_SAME is_same +#define MB_ENABLE_IF enable_if +#endif + +namespace mb_string +{ + enum mb_string_sub_type + { + mb_string_sub_type_none, + mb_string_sub_type_bool, + mb_string_sub_type_float, + mb_string_sub_type_double, + mb_string_sub_type_int8, + mb_string_sub_type_uint8, + mb_string_sub_type_int16, + mb_string_sub_type_uint16, + mb_string_sub_type_int32, + mb_string_sub_type_uint32, + mb_string_sub_type_int64, + mb_string_sub_type_uint64, + mb_string_sub_type_cstring, + mb_string_sub_type_chars, + mb_string_sub_type_mb_string, + mb_string_sub_type_arduino_string, + mb_string_sub_type_std_string, + mb_string_sub_type_fptr, + mb_string_sub_type_string_sum_helper + + }; + + typedef struct mb_string_ptr_t + { + + public: + mb_string_ptr_t(uint32_t addr = 0, mb_string_sub_type type = mb_string_sub_type_cstring, int precision = -1, const StringSumHelper *s = nullptr) + { + _addr = addr; + _type = type; + _precision = precision; + _ssh = s; + } + int precision() { return _precision; } + mb_string_sub_type type() { return _type; } + uint32_t address() { return _addr; } + const StringSumHelper *stringsumhelper() { return _ssh; } + + private: + mb_string_sub_type _type = mb_string_sub_type_none; + int _precision = -1; + uint32_t _addr = 0; + const StringSumHelper *_ssh = nullptr; + + } MB_StringPtr; + + template + struct enable_if + { + }; + template + struct enable_if + { + typedef T type; + }; + template + struct is_same + { + static bool const value = false; + }; + template + struct is_same + { + static bool const value = true; + }; + + template + struct is_num_int8 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; + }; + + template + struct is_num_uint8 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; + }; + + template + struct is_num_int16 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; + }; + + template + struct is_num_uint16 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; + }; + + template + struct is_num_int32 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value || + MB_IS_SAME::value || MB_IS_SAME::value || + MB_IS_SAME::value; + }; + + template + struct is_num_uint32 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value || + MB_IS_SAME::value; + }; + + template + struct is_num_int64 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; + }; + + template + struct is_num_uint64 + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value; + }; + + template + struct is_num_neg_int + { + static bool const value = is_num_int8::value || is_num_int16::value || + is_num_int32::value || is_num_int64::value; + }; + + template + struct is_num_pos_int + { + static bool const value = is_num_uint8::value || is_num_uint16::value || + is_num_uint32::value || is_num_uint64::value; + }; + + template + struct is_num_int + { + static bool const value = is_num_pos_int::value || is_num_neg_int::value; + }; + + template + struct is_num_float + { + static bool const value = MB_IS_SAME::value || MB_IS_SAME::value || MB_IS_SAME::value; + }; + + template + struct is_bool + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct cs_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct ccs_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct as_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct cas_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct ss_t + { +#if !defined(__AVR__) + static bool const value = MB_IS_SAME::value; +#else + static bool const value = false; +#endif + }; + + template + struct css_t + { +#if !defined(__AVR__) + static bool const value = MB_IS_SAME::value; +#else + static bool const value = false; +#endif + }; + + template + struct ssh_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct fs_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct mbs_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct cmbs_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct pgm_t + { + static bool const value = MB_IS_SAME::value; + }; + + template + struct is_const_chars + { + static bool const value = cs_t::value || ccs_t::value; + }; + + template + struct is_arduino_string + { + static bool const value = as_t::value || cas_t::value; + }; + + template + struct is_std_string + { + static bool const value = ss_t::value || css_t::value; + }; + + template + struct is_mb_string + { + static bool const value = mbs_t::value || cmbs_t::value; + }; + + template + struct is_arduino_string_sum_helper + { + static bool const value = ssh_t::value; + }; + + template + struct is_arduino_flash_string_helper + { + static bool const value = fs_t::value; + }; + + template + struct is_string + { + static bool const value = is_const_chars::value || is_arduino_string::value || + is_arduino_string_sum_helper::value || is_arduino_flash_string_helper::value || + is_std_string::value || is_mb_string::value; + }; + + template + uint32_t toAddr(T &v) { return reinterpret_cast(&v); } + +#if defined(__AVR__) + template + T addrTo(int address) + { + return reinterpret_cast(address); + } +#else + template + auto addrTo(int address) -> typename MB_ENABLE_IF::value, T>::type + { + return reinterpret_cast(address); + } +#endif + + template + auto getSubType(T val) -> typename MB_ENABLE_IF::value || is_num_float::value || MB_IS_SAME::value || is_const_chars::value || is_arduino_flash_string_helper::value || is_arduino_string::value || is_std_string::value || is_mb_string::value || MB_IS_SAME::value, mb_string_sub_type>::type + { + if (is_num_uint64::value) + return mb_string_sub_type_uint64; + else if (is_num_int64::value) + return mb_string_sub_type_int64; + else if (is_num_uint32::value) + return mb_string_sub_type_uint32; + else if (is_num_int32::value) + return mb_string_sub_type_int32; + else if (is_num_uint16::value) + return mb_string_sub_type_uint16; + else if (is_num_int16::value) + return mb_string_sub_type_int16; + else if (is_num_uint8::value) + return mb_string_sub_type_uint8; + else if (is_num_int8::value) + return mb_string_sub_type_int8; + else if (MB_IS_SAME::value) + return mb_string_sub_type_bool; + else if (MB_IS_SAME::value) + return mb_string_sub_type_float; + else if (MB_IS_SAME::value) + return mb_string_sub_type_double; + else if (is_arduino_string::value) + return mb_string_sub_type_arduino_string; + else if (is_std_string::value) + return mb_string_sub_type_std_string; + else if (is_mb_string::value) + return mb_string_sub_type_mb_string; + else if (is_arduino_flash_string_helper::value) + return mb_string_sub_type_fptr; + else if (MB_IS_SAME::value) + return mb_string_sub_type_string_sum_helper; + else if (ccs_t::value) + return mb_string_sub_type_cstring; + else if (cs_t::value) + return mb_string_sub_type_chars; + + return mb_string_sub_type_int8; + } + + template + auto getSubType(T *val) -> typename MB_ENABLE_IF::value || is_num_float::value || MB_IS_SAME::value || is_const_chars::value || is_arduino_flash_string_helper::value || is_arduino_string::value || is_std_string::value || is_mb_string::value || MB_IS_SAME::value, mb_string_sub_type>::type + { + return getSubType(*val); + } + + template + auto toStringPtr(const T &val) -> typename MB_ENABLE_IF::value || is_arduino_string::value || is_mb_string::value, MB_StringPtr>::type + { + return MB_StringPtr(reinterpret_cast(&val), getSubType(val)); + } + + template + auto toStringPtr(const T &val) -> typename MB_ENABLE_IF::value, MB_StringPtr>::type + { +#if defined(ESP8266) + return MB_StringPtr(reinterpret_cast(&val), getSubType(val), -1); + +#else + return MB_StringPtr(reinterpret_cast(&val), getSubType(val), -1, &val); +#endif + } + + template + auto toStringPtr(T val) -> typename MB_ENABLE_IF::value, MB_StringPtr>::type { return MB_StringPtr(reinterpret_cast(val), getSubType(val)); } + + template + auto toStringPtr(T &val) -> typename MB_ENABLE_IF::value, MB_StringPtr>::type { return MB_StringPtr(reinterpret_cast(val), getSubType(val)); } + +#if !defined(__AVR__) + template + auto toStringPtr(T val) -> typename MB_ENABLE_IF::value, MB_StringPtr>::type + { + return MB_StringPtr(); + } +#endif + + template + auto toStringPtr(T val) -> typename MB_ENABLE_IF::value, MB_StringPtr>::type + { + return val; + } + + template + auto toStringPtr(T &val, int precision = -1) -> typename MB_ENABLE_IF::value || is_num_float::value || MB_IS_SAME::value, MB_StringPtr>::type { return MB_StringPtr(reinterpret_cast(&val), getSubType(val), precision); } +} + +using namespace mb_string; + +class MB_String +{ +public: + MB_String() + { +#if defined(ESP8266_USE_EXTERNAL_HEAP) + // reserve default 1 byte external heap to refer to its pointer later + reset(1); +#endif + }; + + ~MB_String() + { + allocate(0, false); + }; + + MB_String(const char *cstr) + { + if (cstr) + copy(cstr, strlen_P(cstr)); + } + + MB_String(const MB_String &value) + { + *this = value; + } + + MB_String(const __FlashStringHelper *str) + { + *this = str; + } + +#if !defined(ESP8266) + MB_String(StringSumHelper rval) + { + *this = rval; + } +#endif + + MB_String(MB_StringPtr value) + { + *this = value; + } + + MB_String(String value) + { + *this = value; + } + + MB_String(bool value) + { + appendNum(value); + } + + MB_String(unsigned char value, unsigned char base = 10) + { + int len = 1 + 8 * sizeof(unsigned char); + reserve(len); + + if (bufLen > 0) + utoa(value, buf, base); + } + + MB_String(int value, unsigned char base = 10) + { + int len = 2 + 8 * sizeof(int); + reserve(len); + + if (bufLen > 0) + { + if (base == 10) + sprintf(buf, (const char *)MBSTRING_FLASH_MCR("%d"), value); + else + itoa(value, buf, base); + } + } + + MB_String(unsigned int value, unsigned char base = 10) + { + int len = 1 + 8 * sizeof(unsigned int); + reserve(len); + + if (bufLen > 0) + utoa(value, buf, base); + } + + MB_String(long value, unsigned char base = 10) + { + int len = 2 + 8 * sizeof(long); + reserve(len); + + if (bufLen > 0) + { + if (base == 10) + sprintf(buf, (const char *)MBSTRING_FLASH_MCR("%ld"), value); + else + ltoa(value, buf, base); + } + } + + MB_String(unsigned long value, unsigned char base = 10) + { + int len = 1 + 8 * sizeof(unsigned long); + reserve(len); + + if (bufLen > 0) + ultoa(value, buf, base); + } + + MB_String(float value, unsigned char decimalPlaces = 2) + { + reserve(33); + if (bufLen > 0) + { + char *v = toFloatStr(value, 0, decimalPlaces); + if (v) + { + strcpy(buf, v); + delP(&v); + } + } + } + + MB_String(double value, unsigned char decimalPlaces = 3) + { + reserve(33); + + if (bufLen > 0) + { + char *v = toFloatStr(value, 1, decimalPlaces); + if (v) + { + strcpy(buf, v); + delP(&v); + } + } + } + + MB_String(long double value, unsigned char decimalPlaces = 3) + { + reserve(65); + if (bufLen > 0) + { + char *v = toFloatStr(value, 2, decimalPlaces); + if (v) + { + strcpy(buf, v); + delP(&v); + } + } + } + +#if !defined(__AVR__) + MB_String &operator=(const std::string &rhs) + { + if (rhs.length() > 0) + copy(rhs.c_str(), rhs.length()); + else + clear(); + + return *this; + } +#endif + MB_String &operator=(const String &rhs) + { + + if (rhs.length() > 0) + copy(rhs.c_str(), rhs.length()); + else + clear(); + + return *this; + } + + MB_String &operator=(const __FlashStringHelper *str) + { + if (str) + appendF(str, true); + + return *this; + } + +#if !defined(ESP8266) + MB_String &operator=(StringSumHelper rval) + { + String temp = rval; + *this = temp; + return *this; + } + + MB_String &operator+=(StringSumHelper rval) + { + String temp = rval; + *this += temp; + return *this; + } +#endif + + MB_String &operator+=(const __FlashStringHelper *str) + { + if (str) + appendF(str); + + return *this; + } + + unsigned char operator==(const MB_String &rhs) const + { + return equals(rhs); + } + + unsigned char operator==(const char *cstr) const + { + return equals(cstr); + } + + unsigned char operator!=(const MB_String &rhs) const + { + return !equals(rhs); + } + + unsigned char operator!=(const char *cstr) const + { + return !equals(cstr); + } +#if !defined(__AVR__) + MB_String &operator+=(const std::string &rhs) + { + concat(rhs.c_str()); + return (*this); + } +#endif + MB_String &operator+=(const String &rhs) + { + concat(rhs.c_str()); + return (*this); + } + + MB_String &operator=(const MB_String &rhs) + { + if (this == &rhs) + return *this; + + if (rhs.length() > 0) + copy(rhs.buf, rhs.length()); + else + clear(); + + return *this; + } + + MB_String &operator+=(const MB_String &rhs) + { + concat(rhs); + return (*this); + } + + MB_String &operator+=(const char *cstr) + { + size_t len = strlen_P(cstr); + size_t slen = length(); + + if (_reserve(slen + len, false)) + { + strcat_P(buf, (PGM_P)cstr); + *(buf + slen + len) = '\0'; + } + + return (*this); + } + + MB_String &operator+=(char cstr) + { + append(1, cstr); + return (*this); + } + + MB_String &operator+=(bool value) + { + appendNum(value); + return (*this); + } + + MB_String &operator=(MB_StringPtr ptr) + { + setPtr(ptr); + return (*this); + } + + MB_String &operator+=(MB_StringPtr ptr) + { + appendPtr(ptr); + return (*this); + } + + template + auto operator=(T value) -> typename MB_ENABLE_IF::value || is_num_float::value || is_bool::value, MB_String &>::type + { + clear(); + appendNum(value); + return (*this); + } + + template + auto operator+=(T value) -> typename MB_ENABLE_IF::value || is_num_float::value || is_bool::value, MB_String &>::type + { + appendNum(value); + return (*this); + } + + MB_String &appendP(PGM_P pgms, bool clear = false) + { + if (clear) + this->clear(); + + char *t = pgmStr(pgms); + if (t) + { + *this += t; + delP(&t); + } + + return (*this); + } + + MB_String &appendF(const __FlashStringHelper *pstr, bool clear = false) + { + if (clear) + this->clear(); + + int len = strlen_P((PGM_P)pstr); + if (len > 0) + { + unsigned int newlen = length() + len; + reserve(newlen); + + if (bufLen > 0) + memcpy_P(buf + length(), (PGM_P)pstr, len + 1); + } + + return (*this); + } + + MB_String &setPtr(MB_StringPtr src) + { + clear(); + appendPtr(src); + return (*this); + }; + + MB_String &appendPtr(MB_StringPtr src) + { + if (src.type() == mb_string_sub_type_fptr) + appendF(addrTo(src.address())); + else if (src.type() == mb_string_sub_type_cstring || src.type() == mb_string_sub_type_chars) + *this += addrTo(src.address()); + else if (src.type() == mb_string_sub_type_arduino_string) + *this += *addrTo(src.address()); + else if (src.type() == mb_string_sub_type_string_sum_helper) +#if !defined(ESP8266) + *this += *src.stringsumhelper(); +#else + *this += *addrTo(src.address()); +#endif +#if !defined(__AVR__) + else if (src.type() == mb_string_sub_type_std_string) + *this += *addrTo(src.address()); +#endif + else if (src.type() == mb_string_sub_type_mb_string) + *this += *addrTo(src.address()); + else if (src.type() == mb_string_sub_type_uint64) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_int64) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_uint32) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_int32) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_uint16) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_int16) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_uint8) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_int8) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_bool) + appendNum(*addrTo(src.address())); + else if (src.type() == mb_string_sub_type_float) + appendNum(*addrTo(src.address()), src.precision()); + else if (src.type() == mb_string_sub_type_double) + appendNum(*addrTo(src.address()), src.precision()); + + return (*this); + }; + + template + auto appendNum(T value, int precision = 0) -> typename MB_ENABLE_IF::value || is_bool::value, MB_String &>::type + { + char *s = NULL; + + if (is_bool::value) + s = boolStr(value); + else if (is_num_neg_int::value) + { +#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) + s = int32Str(value); +#else + s = int64Str(value); +#endif + } + else if (is_num_pos_int::value) + { +#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) + s = uint32Str(value); +#else + s = uint64Str(value); +#endif + } + + if (s) + { + *this += s; + delP(&s); + } + + return (*this); + } + + MB_String &appendNum(float value, int precision = 5) + { + if (precision < 0) + precision = 5; + + char *s = toFloatStr(value, 0, precision); + if (s) + { + *this += s; + delP(&s); + } + return (*this); + } + + MB_String &appendNum(double value, int precision = 9) + { + if (precision < 0) + precision = 9; + + char *s = toFloatStr(value, 1, precision); + if (s) + { + *this += s; + delP(&s); + } + return (*this); + } + + MB_String &appendNum(long double value, int precision = 9) + { + if (precision < 0) + precision = 9; + + char *s = toFloatStr(value, 2, precision); + if (s) + { + *this += s; + delP(&s); + } + return (*this); + } + + MB_String &operator=(const char *cstr) + { + if (cstr) + copy(cstr, strlen_P(cstr)); + else + clear(); + + return *this; + } + + MB_String &operator=(char c) + { + clear(); + if (_reserve(1, false)) + { + *(buf) = c; + *(buf + 1) = '\0'; + } + + return *this; + } + + void trim() + { + int p1 = 0, p2 = length() - 1; + while (p1 < (int)length()) + { + if (buf[p1] > 32) + break; + p1++; + } + + while (p2 >= 0) + { + if (buf[p2] > 32) + break; + p2--; + } + + if (p1 == (int)length() && p2 < 0) + { + clear(); + return; + } + + if (p2 >= p1 && p2 >= 0 && p1 < (int)length()) + { + memmove(buf, buf + p1, p2 - p1 + 1); + buf[p2 - p1 + 1] = '\0'; + _reserve(p2 - p1 + 1, true); + } + } + + void append(const char *cstr, size_t n) + { + if (!cstr) + return; + + size_t slen = length(); + + if (n > strlen(cstr)) + n = strlen(cstr); + + if (_reserve(slen + n, false)) + { + memmove(buf + slen, cstr, n); + *(buf + slen + n) = '\0'; + } + } + + void append(size_t n, char c) + { + size_t slen = length(); + + if (_reserve(slen + n, false)) + { + for (size_t i = 0; i < n; i++) + *(buf + slen + i) = c; + *(buf + slen + n) = '\0'; + } + } + + void prepend(char c) + { + size_t slen = length(); + size_t len = 1; + + if (maxLength() < slen + len) + _reserve(slen + len, false); + + memmove(buf + len, buf, slen); + buf[0] = c; + buf[len + slen] = '\0'; + } + + void prepend(const char *cstr) + { + size_t slen = length(); + size_t len = strlen(cstr); + + if (maxLength() < slen + len) + _reserve(slen + len, false); + + memmove(buf + len, buf, slen); + memmove(buf, cstr, len); + buf[len + slen] = '\0'; + } + + const char *c_str() const + { + if (!buf) + return ""; + return (const char *)buf; + } + + char operator[](size_t index) const + { + if (index >= bufLen || !buf) + return 0; + return buf[index]; + } + + char &operator[](size_t index) + { + static char c; + if (index >= bufLen || !buf) + { + c = '\0'; + return c; + } + return buf[index]; + } + + void swap(MB_String &rhs) + { + rhs.clear(); + } + + void shrink_to_fit() + { + size_t slen = length(); + _reserve(slen, true); + } + + void pop_back() + { + if (length() > 0) + { + size_t slen = length(); + if (slen > 0) + buf[slen - 1] = '\0'; + _reserve(slen, true); + } + } + + size_t size() const + { + return length(); + } + + size_t bufferLength() const + { + return bufLen; + } + + size_t find(const MB_String &s, size_t index = 0) const + { + if (!s.buf) + return -1; + return strpos(buf, s.buf, index); + } + + size_t find(const char *s, size_t index = 0) const + { + return strpos(buf, s, index); + } + + size_t find(char c, size_t index = 0) const + { + return strpos(buf, c, index); + } + + size_t rfind(const char *s, size_t index = npos) const + { + return rstrpos(buf, s, index); + } + + size_t rfind(char c, size_t index = npos) const + { + return rstrpos(buf, c, index); + } + + void erase(size_t index = 0, size_t len = npos) + { + + if (!buf || index >= length()) + return; + + if (index + len > length() || len == npos) + len = length() - index; + + int rightLen = length() - index - len; + + memmove(buf + index, buf + index + len, rightLen); + + buf[index + rightLen] = '\0'; + + _reserve(length(), true); + } + + size_t length() const + { + if (!buf) + return 0; + return strlen(buf); + } + + MB_String substr(size_t offset, size_t len = npos) const + { + MB_String out; + substr(out, offset, len); + return out; + } + + void substr(MB_String &out, size_t offset, size_t len = npos) const + { + if (len > 0 && length() > 0 && offset < length()) + { + if (len > length() - offset) + len = length() - offset; + out.copy(buf + offset, len); + } + } + + void clear() + { +#if defined(ESP8266_USE_EXTERNAL_HEAP) + reset(1); +#else + allocate(0, false); +#endif + } + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + void reset(size_t len) + { + if (len == 0) + len = 4; + ESP.setExternalHeap(); + if (buf) + buf = (char *)realloc(buf, len); + else + buf = (char *)malloc(len); + ESP.resetHeap(); + + if (buf) + { + bufLen = len; + memset(buf, 0, len); + } + } +#endif + + void resize(size_t len) + { + if (_reserve(len, true)) + buf[len] = '\0'; + } + + MB_String &replace(size_t pos, size_t len, const char *replace) + { + size_t repLen = strlen(replace); + + if (length() > 0 && length() > pos && repLen > 0) + { + if (pos + len > length()) + len = length() - pos; + + if (repLen > len) + { + size_t rightLen = length() - pos - len; + + if (maxLength() < length() + repLen - len) + _reserve(length() + repLen - len, false); + + memmove(buf + pos + repLen, buf + pos + len, rightLen); + buf[pos + repLen + rightLen] = '\0'; + } + + memmove(buf + pos, replace, repLen); + } + + return *this; + } + + MB_String &replace(size_t pos, size_t len, const MB_String &replace) + { + return this->replace(pos, len, replace.c_str()); + } + + MB_String &insert(size_t pos, size_t n, char c) + { + size_t slen = length(); + + size_t rightLen = slen - pos; + + if (maxLength() < slen + n) + _reserve(slen + n, false); + + if (maxLength() >= slen + n) + { + memmove(buf + pos + n, buf + pos, rightLen); + + for (size_t i = 0; i < n; i++) + *(buf + pos + i) = c; + + buf[pos + n + rightLen] = '\0'; + } + + return *this; + } + + MB_String &insert(size_t pos, const char *cstr) + { + size_t insLen = strlen(cstr); + + if (length() > 0 && length() > pos && insLen > 0) + { + + size_t rightLen = length() - pos; + + if (maxLength() < length() + insLen) + _reserve(length() + insLen, false); + + memmove(buf + pos + insLen, buf + pos, rightLen); + buf[pos + insLen + rightLen] = '\0'; + memmove(buf + pos, cstr, insLen); + } + + return *this; + } + + MB_String &insert(size_t pos, const MB_String &str) + { + return insert(pos, str.c_str()); + } + + MB_String &insert(size_t pos, char c) + { + char temp[2]{c, '\0'}; + return insert(pos, temp); + } + + size_t find_first_of(const char *cstr, size_t pos = 0) const + { + if (!cstr) + return -1; + + return strpos(buf, cstr, pos); + } + + size_t find_first_of(const MB_String &str, size_t pos = 0) const + { + if (length() == 0 || pos >= length()) + return -1; + + return find_first_of(str.buf, pos); + } + + size_t find_first_not_of(const char *cstr, size_t pos = 0) const + { + if (length() == 0 || pos >= length()) + return -1; + + int size = strcspn(buf + pos, cstr); + if (size == 0) + { + while (size == 0 && pos < length()) + { + size = strcspn(buf + pos, cstr); + pos++; + } + + if (pos > 0) + pos--; + } + + return pos; + } + + size_t find_first_not_of(const MB_String &str, size_t pos = 0) const + { + if (length() == 0 || pos >= length() || str.length() == 0) + return -1; + + return find_first_not_of(str.buf, pos); + } + + size_t find_last_of(const char *cstr, size_t pos = npos) const + { + if (!cstr) + return -1; + + return rstrpos(buf, cstr, pos); + } + + size_t find_last_of(const MB_String &str, size_t pos = npos) const + { + if (str.length() == 0) + return -1; + + return find_last_of(str.buf, pos); + } + + size_t find_last_not_of(const char *cstr, size_t pos = npos) const + { + if (length() == 0) + return -1; + + if (pos >= length()) + pos = length() - 1; + + int p = length() - 1; + int size = strcspn(buf + p, cstr); + if (size == 0) + { + while (size == 0 && p > 0) + { + size = strcspn(buf + p, cstr); + p--; + } + p++; + } + + return p; + } + + size_t find_last_not_of(const MB_String &str, size_t pos = npos) const + { + if (str.length() == 0) + return -1; + + return find_last_not_of(str.buf, pos); + } + + MB_String & replaceAll(const char *find, const char *replace) + { + if (length() == 0) + return *this;; + + int i, cnt = 0; + int repLen = strlen(replace); + int findLen = strlen(find); + + MB_String temp = buf; + char *s = temp.buf; + clear(); + + for (i = 0; s[i] != '\0'; i++) + { + if (strstr(&s[i], find) == &s[i]) + { + cnt++; + i += findLen - 1; + } + } + + if (_reserve(i + cnt * (repLen - findLen) + 1, false)) + { + i = 0; + while (*s) + { + if (strstr(s, find) == s) + { + strcpy(&buf[i], replace); + i += repLen; + s += findLen; + } + else + buf[i++] = *s++; + } + + buf[i] = '\0'; + } + + temp.clear(); + + return *this; + } + + void replaceAll(const MB_String &find, const MB_String &replace) + { + replaceAll(find.c_str(), replace.c_str()); + } + + bool empty() const + { + return length() == 0; + } + + void reserve(size_t len) + { + if (_reserve(len, false)) + buf[len] = '\0'; + } + + static const size_t npos = -1; + +private: +#if defined(ARDUINO_ARCH_SAMD) || defined(__AVR_ATmega4809__) || defined(ARDUINO_NANO_RP2040_CONNECT) + + char *int32Str(signed long value) + { + char *t = (char *)newP(64); + sprintf(t, (const char *)MBSTRING_FLASH_MCR("%ld"), value); + return t; + } + + char *uint32Str(unsigned long value) + { + char *t = (char *)newP(64); + sprintf(t, (const char *)MBSTRING_FLASH_MCR("%lu"), value); + return t; + } + +#endif + + char *int64Str(signed long long value) + { + char *t = (char *)newP(64); + sprintf(t, (const char *)MBSTRING_FLASH_MCR("%lld"), value); + return t; + } + + char *uint64Str(unsigned long long value) + { + char *t = (char *)newP(64); + sprintf(t, (const char *)MBSTRING_FLASH_MCR("%llu"), value); + return t; + } + + char *boolStr(bool value) + { + char *t = (char *)newP(8); + value ? strcpy(t, (const char *)MBSTRING_FLASH_MCR("true")) : strcpy(t, (const char *)MBSTRING_FLASH_MCR("false")); + return t; + } + + char *toFloatStr(long double value, int type, int precision) + { + int width = type == 0 ? 32 : 64; + + char *t = (char *)newP(width); + + if (t) + { + MB_String fmt = MBSTRING_FLASH_MCR("%."); + fmt += precision; + if (type == 2) + fmt += MBSTRING_FLASH_MCR("L"); + fmt += MBSTRING_FLASH_MCR("f"); + sprintf(t, fmt.c_str(), value); + trim(t); + } + + return t; + } + + char *nullStr() + { + char *t = (char *)newP(6); + strcpy(t, (const char *)MBSTRING_FLASH_MCR("null")); + return t; + } + + char *pgmStr(PGM_P p) + { + char *t = (char *)newP(strlen_P(p)); + strcpy_P(t, p); + return t; + } + + void trim(char *s) + { + if (!s) + return; + size_t i = strlen(s) - 1; + while (s[i] == '0' && i > 0) + { + if (s[i - 1] == '.') + { + i--; + break; + } + if (s[i - 1] != '0') + break; + i--; + } + if (i < strlen(s) - 1) + s[i] = '\0'; + } + + void *newP(size_t len) + { + void *p; + size_t newLen = getReservedLen(len); +#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) + if (ESP.getPsramSize() > 0) + p = (void *)ps_malloc(newLen); + else + p = (void *)malloc(newLen); + if (!p) + return NULL; + +#else + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + ESP.setExternalHeap(); +#endif + + p = (void *)malloc(newLen); + bool nn = p ? true : false; + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + ESP.resetHeap(); +#endif + + if (!nn) + return NULL; + +#endif + memset(p, 0, newLen); + return p; + } + + void delP(void *ptr) + { + void **p = (void **)ptr; + if (*p) + { + free(*p); + *p = 0; + } + } + + size_t getReservedLen(size_t len) + { + int blen = len + 1; + + int newlen = (blen / 4) * 4; + + if (newlen < blen) + newlen += 4; + + return (size_t)newlen; + } + + size_t maxLength() const + { + if (bufferLength() == 0) + return 0; + return bufferLength() - 1; + } + + void concat(const MB_String &s) + { + if (s.length() == 0) + return; + + if (&s == this) + { + size_t slen = length(); + + if (2 * slen > maxLength()) + { + if (!_reserve(2 * slen, false)) + return; + } + + memmove(buf + slen, buf, slen); + buf[2 * slen] = '\0'; + } + else + { + concat(s.buf, s.length()); + } + } + + void concat(const char *cstr, size_t len) + { + if (!cstr) + return; + + size_t slen = length(); + + if (slen + len > maxLength()) + { + if (!_reserve(slen + len, false)) + return; + } + + memmove(buf + slen, cstr, len); + buf[slen + len] = '\0'; + } + + void concat(const char *cstr) + { + if (!cstr) + return; + + concat(cstr, strlen(cstr)); + } + + void move(MB_String &rhs) + { + if (buf) + { + if (bufLen >= rhs.bufLen) + { + strcpy(buf, rhs.buf); + bufLen = rhs.bufLen; + rhs.bufLen = 0; + return; + } + else + { + free(buf); + } + } + buf = rhs.buf; + bufLen = rhs.bufLen; + rhs.buf = NULL; + } + + void allocate(size_t len, bool shrink) + { + + if (len == 0) + { + if (buf) + free(buf); + buf = NULL; + bufLen = 0; + return; + } + + if (len > bufLen || shrink) + { + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + ESP.setExternalHeap(); +#endif + + if (shrink || (bufLen > 0 && buf)) + { + int slen = length(); + +#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) + if (ESP.getPsramSize() > 0) + buf = (char *)ps_realloc(buf, len); + else + buf = (char *)realloc(buf, len); +#else + buf = (char *)realloc(buf, len); +#endif + if (buf) + { + buf[slen] = '\0'; + bufLen = len; + } + } + else + { +#if defined(BOARD_HAS_PSRAM) && defined(MB_STRING_USE_PSRAM) + if (ESP.getPsramSize() > 0) + buf = (char *)ps_malloc(len); + else + buf = (char *)malloc(len); +#else + buf = (char *)malloc(len); +#endif + if (buf) + { + buf[0] = '\0'; + bufLen = len; + } + } + +#if defined(ESP8266_USE_EXTERNAL_HEAP) + ESP.resetHeap(); +#endif + } + } + + MB_String ©(const char *cstr, size_t length) + { + + if (!_reserve(length, false)) + { + clear(); + return *this; + } + + memcpy_P(buf, (PGM_P)cstr, length); + buf[length] = '\0'; + + return *this; + } + + bool _reserve(size_t len, bool shrink) + { + + size_t newlen = getReservedLen(len); + if (shrink) + allocate(newlen, true); + else if (newlen > bufLen) + allocate(newlen, false); + + return newlen <= bufLen; + } + + int strpos(const char *haystack, const char *needle, int offset) const + { + if (!haystack || !needle) + return -1; + + int hlen = strlen(haystack); + int nlen = strlen(needle); + + if (hlen == 0 || nlen == 0) + return -1; + + int hidx = offset, nidx = 0; + while ((*(haystack + hidx) != '\0') && (*(needle + nidx) != '\0') && hidx < hlen) + { + if (*(needle + nidx) != *(haystack + hidx)) + { + hidx++; + nidx = 0; + } + else + { + nidx++; + hidx++; + if (nidx == nlen) + return hidx - nidx; + } + } + + return -1; + } + + int strpos(const char *haystack, char needle, int offset) const + { + if (!haystack || needle == 0) + return -1; + + int hlen = strlen(haystack); + + if (hlen == 0) + return -1; + + int hidx = offset; + while ((*(haystack + hidx) != '\0') && hidx < hlen) + { + if (needle == *(haystack + hidx)) + return hidx; + hidx++; + } + + return -1; + } + + int rstrpos(const char *haystack, const char *needle, int offset /* start search from this offset to the left string */) const + { + if (!haystack || !needle) + return -1; + + int hlen = strlen(haystack); + int nlen = strlen(needle); + + if (hlen == 0 || nlen == 0) + return -1; + + int hidx = offset; + + if (hidx >= hlen || (size_t)offset == npos) + hidx = hlen - 1; + + int nidx = nlen - 1; + + while (hidx >= 0) + { + if (*(needle + nidx) != *(haystack + hidx)) + { + hidx--; + nidx = nlen - 1; + } + else + { + if (nidx == 0) + return hidx + nidx; + nidx--; + hidx--; + } + } + + return -1; + } + + int rstrpos(const char *haystack, char needle, int offset /* start search from this offset to the left char */) const + { + if (!haystack || needle == 0) + return -1; + + int hlen = strlen(haystack); + + if (hlen == 0) + return -1; + + int hidx = offset; + + if (hidx >= hlen || (size_t)offset == npos) + hidx = hlen - 1; + + while (hidx >= 0) + { + if (needle == *(haystack + hidx)) + return hidx; + hidx--; + } + + return -1; + } + + int compareTo(const MB_String &s) const + { + if (!buf || !s.buf) + { + if (s.buf && s.length() > 0) + return 0 - *(unsigned char *)s.buf; + if (buf && length() > 0) + return *(unsigned char *)buf; + return 0; + } + return strcmp(buf, s.buf); + } + + unsigned char equals(const MB_String &s2) const + { + return (length() == s2.length() && compareTo(s2) == 0); + } + + unsigned char equals(const char *cstr) const + { + if (length() == 0) + return (cstr == NULL || *cstr == 0); + if (cstr == NULL) + return buf[0] == 0; + return strcmp(buf, cstr) == 0; + } + + char *ultoa(unsigned long value, char *str, int radix) + { + const char *format = NULL; + + switch (radix) + { + case 8: + format = "%o"; + break; + case 10: + format = "%ul"; + break; + case 16: + format = "%x"; + break; + } + + if (format == NULL) + return str; + + int size = sprintf(str, format, value); + return &str[size]; + } + +#if (!defined(ESP32) && !defined(ESP8266) && !defined(ARDUINO_ARCH_STM32) && !defined(ARDUINO_ARCH_SAMD)) || defined(ARDUINO_NANO_RP2040_CONNECT) + char *ltoa(long value, char *str, int radix) + { + const char *format = NULL; + + switch (radix) + { + case 8: + format = "%o"; + break; + case 10: + format = "%l"; + break; + case 16: + format = "%x"; + break; + } + + if (format == NULL) + return str; + + int size = sprintf(str, format, value); + return &str[size]; + } + + char *utoa(unsigned int value, char *str, int radix) + { + const char *format = NULL; + + switch (radix) + { + case 8: + format = "%o"; + break; + case 10: + format = "%u"; + break; + case 16: + format = "%x"; + break; + } + + if (format == NULL) + return str; + + int size = sprintf(str, format, value); + return &str[size]; + } + + char *itoa(int value, char *str, int radix) + { + const char *format = NULL; + + switch (radix) + { + case 8: + format = "%o"; + break; + case 10: + format = "%d"; + break; + case 16: + format = "%x"; + break; + } + + if (format == NULL) + return str; + + int size = sprintf(str, format, value); + return &str[size]; + } +#endif + + char *buf = NULL; + size_t bufLen = 0; +}; + +inline MB_String operator+(const MB_String &lhs, const MB_String &rhs) +{ + MB_String res; + res.reserve(lhs.length() + rhs.length()); + res += lhs; + res += rhs; + return res; +} + +#if !defined(__AVR__) + +inline MB_String operator+(MB_String &&lhs, const MB_String &rhs) +{ + lhs += rhs; + return std::move(lhs); +} + +inline MB_String operator+(MB_String &lhs, MB_String &&rhs) +{ + lhs += rhs; + return std::move(lhs); +} + +inline MB_String operator+(MB_String &lhs, char rhs) +{ + lhs += rhs; + return std::move(lhs); +} + +inline MB_String operator+(char lhs, MB_String &rhs) +{ + rhs.insert(0, lhs); + return rhs; +} + +inline MB_String operator+(MB_String &&lhs, char rhs) +{ + return std::move(lhs.insert(0, rhs)); +} + +#endif + #endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/MB_Time.h b/lib/libesp32/ESP-Mail-Client/src/extras/MB_Time.h index 73d84ac2b..491c671b6 100644 --- a/lib/libesp32/ESP-Mail-Client/src/extras/MB_Time.h +++ b/lib/libesp32/ESP-Mail-Client/src/extras/MB_Time.h @@ -1,435 +1,435 @@ -#ifndef MB_Time_H -#define MB_Time_H - -#include "ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30409) -#error "Mixed versions compilation." -#endif - -/* - * Time helper class v1.0.7 - * - * Created August 28, 2023 - * - * Do not remove or modify this file as it required for AVR, ARM, SAMD devices and external client to work. - * - * The MIT License (MIT) - * Copyright (c) 2022 K. Suwatchai (Mobizt) - * - * - * Permission is hereby granted, free of charge, to any person returning 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 "Networks_Provider.h" - -#define ESP_TIME_DEFAULT_TS 1577836800 -#define ESP_TIME_NON_TS -1000 - -#include -#include - -#if defined(ESP32) && !defined(ESP_ARDUINO_VERSION) /* ESP32 core < v2.0.x */ -#include -#else -#include -#endif - -#if defined(ESP_MAIL_USE_PSRAM) -#define MB_STRING_USE_PSRAM -#endif - -#include "MB_String.h" -#include "MB_MCU.h" - -#if defined(ESP8266) -#include "user_interface.h" -#endif - -#if defined(__AVR__) || defined(MB_ARDUINO_TEENSY) -#define MB_TIME_PGM_ATTR -#else -#define MB_TIME_PGM_ATTR PROGMEM -#endif - -#if !defined(MB_ARDUINO_ESP) -static const char *mb_months[12] MB_TIME_PGM_ATTR = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; -#endif - -enum base_time_type_t -{ - base_time_type_undefined = -1, - base_time_type_unset = 0, - base_time_type_auto = 1, - base_time_type_user = 2 -}; - -class MB_Time -{ -public: - MB_Time() - { - } - - ~MB_Time() - { - clear(); - } - - void clear() - { -#if defined(ENABLE_NTP_TIME) - if (_sv1.length()) - { - _sv1.clear(); - _sv2.clear(); - _sv3.clear(); - } -#endif - } - - void readNTPTime(unsigned long waitMs, bool debugProgress) - { - if (!timeReady()) - { - if (WiFI_CONNECTED) - { - -#if defined(ENABLE_NTP_TIME) -#if (defined(ESP32) || defined(ESP8266)) - configTime(_gmt_offset * 3600, _daylight_offset * 60, _sv1.c_str(), _sv2.c_str(), _sv3.c_str()); -#elif defined(ARDUINO_RASPBERRY_PI_PICO_W) - NTP.begin(_sv1.c_str(), _sv2.c_str()); - NTP.waitSet(); -#endif -#endif - unsigned long ms = millis(); - -#if !defined(SILENT_MODE) - unsigned long pgms = 0; -#endif - do - { -#if defined(ESP_MAIL_HAS_WIFI_TIME) - _base_ts = WiFi.getTime() > ESP_TIME_DEFAULT_TS ? WiFi.getTime() : _base_ts; -#elif defined(ENABLE_NTP_TIME) - _base_ts = time(nullptr) > ESP_TIME_DEFAULT_TS ? time(nullptr) : _base_ts; -#else - break; -#endif - -#if !defined(SILENT_MODE) - if (debugProgress && millis() - pgms > 50) - { - pgms = millis(); - esp_mail_debug_print(".", false); - } -#endif - - yield_impl(); - } while (millis() - ms < waitMs && _base_ts < ESP_TIME_DEFAULT_TS); -#if !defined(SILENT_MODE) - if (debugProgress) - esp_mail_debug_print("", true); -#endif - } - } - } - - int setTimestamp(time_t ts, float gmtOffset) - { - _gmt_offset = gmtOffset; - _base_time_type = ts > ESP_TIME_DEFAULT_TS ? base_time_type_user : base_time_type_unset; -#if defined(MB_ARDUINO_ESP) - struct timeval tm; // sec, us - tm.tv_sec = ts; - tm.tv_usec = 0; - return settimeofday((const struct timeval *)&tm, 0); -#else - _ts_offset = ts - millis() / 1000; - return 1; -#endif - } - - /** Get the timestamp from the year, month, date, hour, minute, - * and second provided. - * - * @param year The year. - * @param mon The month from 1 to 12. - * @param date The dates. - * @param hour The hours. - * @param mins The minutes. - * @param sec The seconds. - * @return time_t The value of timestamp. - */ - time_t getTimestamp(int year, int mon, int date, int hour, int mins, int sec) - { - struct tm timeinfo; - timeinfo.tm_year = year - 1900; - timeinfo.tm_mon = mon - 1; - timeinfo.tm_mday = date; - timeinfo.tm_hour = hour; - timeinfo.tm_min = mins; - timeinfo.tm_sec = sec; - time_t ts = mktime(&timeinfo); - return ts; - } - - /** Get the timestamp from the RFC 2822 time string. - * e.g. Mon, 02 May 2022 00:30:00 +0000 or 02 May 2022 00:30:00 +0000 - * - * @param gmt Return the GMT time. - * @return timestamp of time string. - */ - time_t getTimestamp(const char *timeString, bool gmt = false) - { -#if defined(MB_ARDUINO_ESP) - struct tm timeinfo; - - if (strstr(timeString, ",") != NULL) - strptime(timeString, "%a, %d %b %Y %H:%M:%S %z", &timeinfo); - else - strptime(timeString, "%d %b %Y %H:%M:%S %z", &timeinfo); - - time_t ts = mktime(&timeinfo); - return ts; - -#else - - time_t ts = 0; - _vectorImpl tk; - MB_String s1 = timeString; - - splitToken(s1, tk, ' '); - int day = 0, mon = 0, year = 0, hr = 0, mins = 0, sec = 0, tz_h = 0, tz_m = 0; - - int tkindex = tk.size() == 5 ? -1 : 0; // No week days? - - // some response may include (UTC) and (ICT) - if (tk.size() >= 5) - { - day = atoi(tk[tkindex + 1].c_str()); - for (size_t i = 0; i < 12; i++) - { - if (strcmp_P(mb_months[i], tk[tkindex + 2].c_str()) == 0) - mon = i; - } - - // RFC 822 year to RFC 2822 - if (tk[tkindex + 3].length() == 2) - tk[tkindex + 3].prepend("20"); - - year = atoi(tk[tkindex + 3].c_str()); - - _vectorImpl tk2; - splitToken(tk[tkindex + 4], tk2, ':'); - if (tk2.size() == 3) - { - hr = atoi(tk2[0].c_str()); - mins = atoi(tk2[1].c_str()); - sec = atoi(tk2[2].c_str()); - } - - ts = getTimestamp(year, mon + 1, day, hr, mins, sec); - - if (tk[tkindex + 5].length() == 5 && gmt) - { - char tmp[6]; - memset(tmp, 0, 6); - strncpy(tmp, tk[tkindex + 5].c_str() + 1, 2); - tz_h = atoi(tmp); - - memset(tmp, 0, 6); - strncpy(tmp, tk[tkindex + 5].c_str() + 3, 2); - tz_m = atoi(tmp); - - time_t tz = tz_h * 60 * 60 + tz_m * 60; - if (tk[tkindex + 5][0] == '+') - ts -= tz; // remove time zone offset - else - ts += tz; - } - } - return ts; -#endif - } - - /** Get the current timestamp. - * - * @return uint64_t The value of current timestamp. - */ - uint64_t getCurrentTimestamp() - { - getBaseTime(); - return _base_ts; - } - - /** Get the current rfc822 date time string that valid for Email. - * @return String The current date time string. - */ - String getDateTimeString() - { - getBaseTime(); - - char tbuf[40]; - strftime(tbuf, 40, "%a, %d %b %Y %H:%M:%S %z", &_time_info); - MB_String tStr = tbuf, tzStr; - - int p = _gmt_offset < 0 ? -1 : 1; - float dif = (p * (_gmt_offset * 10 - (int)_gmt_offset * 10)) * 60.0 / 10; - tzStr = (_gmt_offset < 0) ? '-' : '+'; - - if ((int)_gmt_offset < 10) - tzStr += 0; - - tzStr += (int)_gmt_offset; - - if (dif < 10) - tzStr += 0; - - tzStr += (int)dif; - - // replace for valid timezone - tStr.replaceAll("+0000", tzStr); - return tStr.c_str(); - } - - String getDateTimeString(time_t ts, const char *format) - { - char tbuf[100]; - strftime(tbuf, 100, format, localtime(&ts)); - return tbuf; - } - - void begin(float gmtOffset, float daylightOffset, const char *servers) - { - if (timeReady() && _base_time_type == base_time_type_undefined) - _base_time_type = base_time_type_auto; - else if (_base_time_type == base_time_type_undefined) - _base_time_type = base_time_type_unset; - -#if defined(ENABLE_NTP_TIME) && (defined(ESP32) || defined(ESP8266) || defined(ARDUINO_RASPBERRY_PI_PICO_W)) - - _vectorImpl tk; - MB_String sv = servers; - - clear(); - - splitToken(sv, tk, ','); - - if (tk.size() > 0) - _sv1 = tk[0]; - if (tk.size() > 1) - _sv2 = tk[1]; - if (tk.size() > 2) - _sv3 = tk[2]; - -#endif - - if ((gmtOffset > ESP_TIME_NON_TS && _gmt_offset != gmtOffset) || (daylightOffset > ESP_TIME_NON_TS && _daylight_offset != daylightOffset)) - { - // Reset system timestamp when config changed - _base_ts = 0; - if (gmtOffset > ESP_TIME_NON_TS) - _gmt_offset = gmtOffset; - if (daylightOffset > ESP_TIME_NON_TS) - _daylight_offset = daylightOffset; - - if (_base_time_type == base_time_type_unset) - setTimestamp(millis(), _gmt_offset); - } - } - - /** get the clock ready state - */ - bool timeReady() - { - getBaseTime(); - return _time_ready; - } - -private: - time_t _base_ts = 0; - struct tm _time_info; - float _gmt_offset = ESP_TIME_NON_TS; - float _daylight_offset = ESP_TIME_NON_TS; - void splitToken(MB_String &str, _vectorImpl &tk, char delim) - { - size_t current, previous = 0; - current = str.find(delim, previous); - MB_String s; - while (current != MB_String::npos) - { - - s = str.substr(previous, current - previous); - s.trim(); - - if (s.length() > 0) - tk.push_back(s); - previous = current + 1; - current = str.find(delim, previous); - } - - s = str.substr(previous, current - previous); - - s.trim(); - - if (s.length() > 0) - tk.push_back(s); - - s.clear(); - } - - // 9Safe) Get base timestamp - void getBaseTime() - { - -#if defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO) - - if (_base_ts < time(nullptr) && time(nullptr) > ESP_TIME_DEFAULT_TS) - _base_ts = time(nullptr); - -#if defined(ESP32) - getLocalTime(&_time_info); -#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) - localtime_r(&_base_ts, &_time_info); -#endif - -#elif defined(ESP_MAIL_HAS_WIFI_TIME) - if (WiFI_CONNECTED) - _base_ts = WiFi.getTime() > ESP_TIME_DEFAULT_TS ? WiFi.getTime() : _base_ts; -#else - _base_ts = _ts_offset + millis() / 1000; -#endif - - _time_ready = _base_ts > ESP_TIME_DEFAULT_TS; - if (_time_ready) - _ts_offset = _base_ts - millis() / 1000; - } - -#if defined(ENABLE_NTP_TIME) - // in ESP8266 these NTP sever strings should be existed during configuring time. - MB_String _sv1, _sv2, _sv3; -#endif - - uint32_t _ts_offset = 0; - bool _time_ready = false; - base_time_type_t _base_time_type = base_time_type_undefined; -}; - -#endif // MB_Time_H +#ifndef MB_Time_H +#define MB_Time_H + +#include "ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +/* + * Time helper class v1.0.7 + * + * Created August 28, 2023 + * + * Do not remove or modify this file as it required for AVR, ARM, SAMD devices and external client to work. + * + * The MIT License (MIT) + * Copyright (c) 2022 K. Suwatchai (Mobizt) + * + * + * Permission is hereby granted, free of charge, to any person returning 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 "Networks_Provider.h" + +#define ESP_TIME_DEFAULT_TS 1577836800 +#define ESP_TIME_NON_TS -1000 + +#include +#include + +#if defined(ESP32) && !defined(ESP_ARDUINO_VERSION) /* ESP32 core < v2.0.x */ +#include +#else +#include +#endif + +#if defined(ESP_MAIL_USE_PSRAM) +#define MB_STRING_USE_PSRAM +#endif + +#include "MB_String.h" +#include "MB_MCU.h" + +#if defined(ESP8266) +#include "user_interface.h" +#endif + +#if defined(__AVR__) || defined(MB_ARDUINO_TEENSY) +#define MB_TIME_PGM_ATTR +#else +#define MB_TIME_PGM_ATTR PROGMEM +#endif + +#if !defined(MB_ARDUINO_ESP) +static const char *mb_months[12] MB_TIME_PGM_ATTR = {"Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; +#endif + +enum base_time_type_t +{ + base_time_type_undefined = -1, + base_time_type_unset = 0, + base_time_type_auto = 1, + base_time_type_user = 2 +}; + +class MB_Time +{ +public: + MB_Time() + { + } + + ~MB_Time() + { + clear(); + } + + void clear() + { +#if defined(ENABLE_NTP_TIME) + if (_sv1.length()) + { + _sv1.clear(); + _sv2.clear(); + _sv3.clear(); + } +#endif + } + + void readNTPTime(unsigned long waitMs, bool debugProgress) + { + if (!timeReady()) + { + if (WiFI_CONNECTED) + { + +#if defined(ENABLE_NTP_TIME) +#if (defined(ESP32) || defined(ESP8266)) + configTime(_gmt_offset * 3600, _daylight_offset * 60, _sv1.c_str(), _sv2.c_str(), _sv3.c_str()); +#elif defined(ARDUINO_RASPBERRY_PI_PICO_W) + NTP.begin(_sv1.c_str(), _sv2.c_str()); + NTP.waitSet(); +#endif +#endif + unsigned long ms = millis(); + +#if !defined(SILENT_MODE) + unsigned long pgms = 0; +#endif + do + { +#if defined(ESP_MAIL_HAS_WIFI_TIME) + _base_ts = WiFi.getTime() > ESP_TIME_DEFAULT_TS ? WiFi.getTime() : _base_ts; +#elif defined(ENABLE_NTP_TIME) + _base_ts = time(nullptr) > ESP_TIME_DEFAULT_TS ? time(nullptr) : _base_ts; +#else + break; +#endif + +#if !defined(SILENT_MODE) + if (debugProgress && millis() - pgms > 50) + { + pgms = millis(); + esp_mail_debug_print(".", false); + } +#endif + + yield_impl(); + } while (millis() - ms < waitMs && _base_ts < ESP_TIME_DEFAULT_TS); +#if !defined(SILENT_MODE) + if (debugProgress) + esp_mail_debug_print("", true); +#endif + } + } + } + + int setTimestamp(time_t ts, float gmtOffset) + { + _gmt_offset = gmtOffset; + _base_time_type = ts > ESP_TIME_DEFAULT_TS ? base_time_type_user : base_time_type_unset; +#if defined(MB_ARDUINO_ESP) + struct timeval tm; // sec, us + tm.tv_sec = ts; + tm.tv_usec = 0; + return settimeofday((const struct timeval *)&tm, 0); +#else + _ts_offset = ts - millis() / 1000; + return 1; +#endif + } + + /** Get the timestamp from the year, month, date, hour, minute, + * and second provided. + * + * @param year The year. + * @param mon The month from 1 to 12. + * @param date The dates. + * @param hour The hours. + * @param mins The minutes. + * @param sec The seconds. + * @return time_t The value of timestamp. + */ + time_t getTimestamp(int year, int mon, int date, int hour, int mins, int sec) + { + struct tm timeinfo; + timeinfo.tm_year = year - 1900; + timeinfo.tm_mon = mon - 1; + timeinfo.tm_mday = date; + timeinfo.tm_hour = hour; + timeinfo.tm_min = mins; + timeinfo.tm_sec = sec; + time_t ts = mktime(&timeinfo); + return ts; + } + + /** Get the timestamp from the RFC 2822 time string. + * e.g. Mon, 02 May 2022 00:30:00 +0000 or 02 May 2022 00:30:00 +0000 + * + * @param gmt Return the GMT time. + * @return timestamp of time string. + */ + time_t getTimestamp(const char *timeString, bool gmt = false) + { +#if defined(MB_ARDUINO_ESP) + struct tm timeinfo; + + if (strstr(timeString, ",") != NULL) + strptime(timeString, "%a, %d %b %Y %H:%M:%S %z", &timeinfo); + else + strptime(timeString, "%d %b %Y %H:%M:%S %z", &timeinfo); + + time_t ts = mktime(&timeinfo); + return ts; + +#else + + time_t ts = 0; + _vectorImpl tk; + MB_String s1 = timeString; + + splitToken(s1, tk, ' '); + int day = 0, mon = 0, year = 0, hr = 0, mins = 0, sec = 0, tz_h = 0, tz_m = 0; + + int tkindex = tk.size() == 5 ? -1 : 0; // No week days? + + // some response may include (UTC) and (ICT) + if (tk.size() >= 5) + { + day = atoi(tk[tkindex + 1].c_str()); + for (size_t i = 0; i < 12; i++) + { + if (strcmp_P(mb_months[i], tk[tkindex + 2].c_str()) == 0) + mon = i; + } + + // RFC 822 year to RFC 2822 + if (tk[tkindex + 3].length() == 2) + tk[tkindex + 3].prepend("20"); + + year = atoi(tk[tkindex + 3].c_str()); + + _vectorImpl tk2; + splitToken(tk[tkindex + 4], tk2, ':'); + if (tk2.size() == 3) + { + hr = atoi(tk2[0].c_str()); + mins = atoi(tk2[1].c_str()); + sec = atoi(tk2[2].c_str()); + } + + ts = getTimestamp(year, mon + 1, day, hr, mins, sec); + + if (tk[tkindex + 5].length() == 5 && gmt) + { + char tmp[6]; + memset(tmp, 0, 6); + strncpy(tmp, tk[tkindex + 5].c_str() + 1, 2); + tz_h = atoi(tmp); + + memset(tmp, 0, 6); + strncpy(tmp, tk[tkindex + 5].c_str() + 3, 2); + tz_m = atoi(tmp); + + time_t tz = tz_h * 60 * 60 + tz_m * 60; + if (tk[tkindex + 5][0] == '+') + ts -= tz; // remove time zone offset + else + ts += tz; + } + } + return ts; +#endif + } + + /** Get the current timestamp. + * + * @return uint64_t The value of current timestamp. + */ + uint64_t getCurrentTimestamp() + { + getBaseTime(); + return _base_ts; + } + + /** Get the current rfc822 date time string that valid for Email. + * @return String The current date time string. + */ + String getDateTimeString() + { + getBaseTime(); + + char tbuf[40]; + strftime(tbuf, 40, "%a, %d %b %Y %H:%M:%S %z", &_time_info); + MB_String tStr = tbuf, tzStr; + + int p = _gmt_offset < 0 ? -1 : 1; + float dif = (p * (_gmt_offset * 10 - (int)_gmt_offset * 10)) * 60.0 / 10; + tzStr = (_gmt_offset < 0) ? '-' : '+'; + + if ((int)_gmt_offset < 10) + tzStr += 0; + + tzStr += (int)_gmt_offset; + + if (dif < 10) + tzStr += 0; + + tzStr += (int)dif; + + // replace for valid timezone + tStr.replaceAll("+0000", tzStr); + return tStr.c_str(); + } + + String getDateTimeString(time_t ts, const char *format) + { + char tbuf[100]; + strftime(tbuf, 100, format, localtime(&ts)); + return tbuf; + } + + void begin(float gmtOffset, float daylightOffset, const char *servers) + { + if (timeReady() && _base_time_type == base_time_type_undefined) + _base_time_type = base_time_type_auto; + else if (_base_time_type == base_time_type_undefined) + _base_time_type = base_time_type_unset; + +#if defined(ENABLE_NTP_TIME) && (defined(ESP32) || defined(ESP8266) || defined(ARDUINO_RASPBERRY_PI_PICO_W)) + + _vectorImpl tk; + MB_String sv = servers; + + clear(); + + splitToken(sv, tk, ','); + + if (tk.size() > 0) + _sv1 = tk[0]; + if (tk.size() > 1) + _sv2 = tk[1]; + if (tk.size() > 2) + _sv3 = tk[2]; + +#endif + + if ((gmtOffset > ESP_TIME_NON_TS && _gmt_offset != gmtOffset) || (daylightOffset > ESP_TIME_NON_TS && _daylight_offset != daylightOffset)) + { + // Reset system timestamp when config changed + _base_ts = 0; + if (gmtOffset > ESP_TIME_NON_TS) + _gmt_offset = gmtOffset; + if (daylightOffset > ESP_TIME_NON_TS) + _daylight_offset = daylightOffset; + + if (_base_time_type == base_time_type_unset) + setTimestamp(millis(), _gmt_offset); + } + } + + /** get the clock ready state + */ + bool timeReady() + { + getBaseTime(); + return _time_ready; + } + +private: + time_t _base_ts = 0; + struct tm _time_info; + float _gmt_offset = ESP_TIME_NON_TS; + float _daylight_offset = ESP_TIME_NON_TS; + void splitToken(MB_String &str, _vectorImpl &tk, char delim) + { + size_t current, previous = 0; + current = str.find(delim, previous); + MB_String s; + while (current != MB_String::npos) + { + + s = str.substr(previous, current - previous); + s.trim(); + + if (s.length() > 0) + tk.push_back(s); + previous = current + 1; + current = str.find(delim, previous); + } + + s = str.substr(previous, current - previous); + + s.trim(); + + if (s.length() > 0) + tk.push_back(s); + + s.clear(); + } + + // 9Safe) Get base timestamp + void getBaseTime() + { + +#if defined(ESP32) || defined(ESP8266) || defined(MB_ARDUINO_PICO) + + if (_base_ts < time(nullptr) && time(nullptr) > ESP_TIME_DEFAULT_TS) + _base_ts = time(nullptr); + +#if defined(ESP32) + getLocalTime(&_time_info); +#elif defined(ESP8266) || defined(MB_ARDUINO_PICO) + localtime_r(&_base_ts, &_time_info); +#endif + +#elif defined(ESP_MAIL_HAS_WIFI_TIME) + if (WiFI_CONNECTED) + _base_ts = WiFi.getTime() > ESP_TIME_DEFAULT_TS ? WiFi.getTime() : _base_ts; +#else + _base_ts = _ts_offset + millis() / 1000; +#endif + + _time_ready = _base_ts > ESP_TIME_DEFAULT_TS; + if (_time_ready) + _ts_offset = _base_ts - millis() / 1000; + } + +#if defined(ENABLE_NTP_TIME) + // in ESP8266 these NTP sever strings should be existed during configuring time. + MB_String _sv1, _sv2, _sv3; +#endif + + uint32_t _ts_offset = 0; + bool _time_ready = false; + base_time_type_t _base_time_type = base_time_type_undefined; +}; + +#endif // MB_Time_H diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/Networks_Provider.h b/lib/libesp32/ESP-Mail-Client/src/extras/Networks_Provider.h index a891eb1bf..a5a7154e8 100644 --- a/lib/libesp32/ESP-Mail-Client/src/extras/Networks_Provider.h +++ b/lib/libesp32/ESP-Mail-Client/src/extras/Networks_Provider.h @@ -1,131 +1,131 @@ -#ifndef ESP_MAIL_NETWORKS_PROVIDER_H -#define ESP_MAIL_NETWORKS_PROVIDER_H - -#include "../ESP_Mail_FS.h" - -#include "../ESP_Mail_Client_Version.h" -#if !VALID_VERSION_CHECK(30409) -#error "Mixed versions compilation." -#endif - -#if __has_include() -#include -#endif - -#include "ESP8266_Supports.h" - -// Renesas devices -#if defined(ARDUINO_UNOWIFIR4) || defined(ARDUINO_MINIMA) || defined(ARDUINO_PORTENTA_C33) -#define ESP_MAIL_STRSEP strsepImpl -#define ESP_MAIL_USE_STRSEP_IMPL -#else -#define ESP_MAIL_STRSEP strsep -#endif - -#if defined(ESP32) || defined(ESP8266) || defined(ARDUINO_RASPBERRY_PI_PICO_W) || \ - defined(ARDUINO_UNOWIFIR4) || defined(ARDUINO_PORTENTA_C33) || \ - defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) || \ - __has_include() ||__has_include() - -#if !defined(ESP_MAIL_DISABLE_ONBOARD_WIFI) - -#define ESP_MAIL_WIFI_IS_AVAILABLE - -#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) -#include -#elif defined(ESP8266) -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#elif __has_include() -#include -#endif - -#if !defined(ARDUINO_RASPBERRY_PI_PICO_W) && \ - !defined(MB_ARDUINO_ARCH_SAMD) && \ - !defined(MB_ARDUINO_MBED_PORTENTA) && \ - !defined(ARDUINO_UNOWIFIR4) && \ - !defined(ARDUINO_PORTENTA_C33) && \ - !defined(ARDUINO_NANO_RP2040_CONNECT) -#define ESP_MAIL_HAS_WIFI_DISCONNECT -#endif - -#if defined(ARDUINO_PORTENTA_C33) -#define CONST_STRING_CAST char * // C33 WiFi library SSID is char array -#else -#define CONST_STRING_CAST const char * -#endif - -// WiFiS3 getTime is currently return 0 (not implemented) -#if __has_include() || __has_include() -#define ESP_MAIL_HAS_WIFI_TIME -#endif - -#if defined(MB_ARDUINO_PICO) && __has_include() -#define ESP_MAIL_HAS_WIFIMULTI -#endif - -#endif - -#endif - -#if !defined(ESP_MAIL_DISABLE_NATIVE_ETHERNET) - -#if defined(ESP32) && defined(CONFIG_ETH_ENABLED) -#include -#define ESP_MAIL_ETH_IS_AVAILABLE -#elif defined(ESP8266) && defined(ESP8266_CORE_SDK_V3_X_X) -#if defined(INC_ENC28J60_LWIP) || defined(INC_W5100_LWIP) || defined(INC_W5500_LWIP) -#define ESP_MAIL_ETH_IS_AVAILABLE -#endif -#endif - -#endif - -#if defined(TINY_GSM_MODEM_SIM800) || \ - defined(TINY_GSM_MODEM_SIM808) || \ - defined(TINY_GSM_MODEM_SIM868) || \ - defined(TINY_GSM_MODEM_SIM900) || \ - defined(TINY_GSM_MODEM_SIM7000) || \ - defined(TINY_GSM_MODEM_SIM7000) || \ - defined(TINY_GSM_MODEM_SIM7000SSL) || \ - defined(TINY_GSM_MODEM_SIM7070) || \ - defined(TINY_GSM_MODEM_SIM7080) || \ - defined(TINY_GSM_MODEM_SIM7090) || \ - defined(TINY_GSM_MODEM_SIM5320) || \ - defined(TINY_GSM_MODEM_SIM5360) || \ - defined(TINY_GSM_MODEM_SIM5300) || \ - defined(TINY_GSM_MODEM_SIM7100) || \ - defined(TINY_GSM_MODEM_SIM7600) || \ - defined(TINY_GSM_MODEM_SIM7800) || \ - defined(TINY_GSM_MODEM_SIM7500) || \ - defined(TINY_GSM_MODEM_UBLOX) || \ - defined(TINY_GSM_MODEM_SARAR4) || \ - defined(TINY_GSM_MODEM_M95) || \ - defined(TINY_GSM_MODEM_BG96) || \ - defined(TINY_GSM_MODEM_A6) || \ - defined(TINY_GSM_MODEM_A7) || \ - defined(TINY_GSM_MODEM_M590) || \ - defined(TINY_GSM_MODEM_MC60) || \ - defined(TINY_GSM_MODEM_MC60E) || \ - defined(TINY_GSM_MODEM_XBEE) || \ - defined(TINY_GSM_MODEM_SEQUANS_MONARCH) -#define ESP_MAIL_TINYGSM_IS_AVAILABLE -#endif - -#if defined(ESP_MAIL_TINYGSM_IS_AVAILABLE) && __has_include() -#include -#define ESP_MAIL_GSM_MODEM_IS_AVAILABLE -#endif - -#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) -#define WiFI_CONNECTED (WiFi.status() == WL_CONNECTED) -#else -#define WiFI_CONNECTED false -#endif - -#endif +#ifndef ESP_MAIL_NETWORKS_PROVIDER_H +#define ESP_MAIL_NETWORKS_PROVIDER_H + +#include "../ESP_Mail_FS.h" + +#include "../ESP_Mail_Client_Version.h" +#if !VALID_VERSION_CHECK(30409) +#error "Mixed versions compilation." +#endif + +#if __has_include() +#include +#endif + +#include "ESP8266_Supports.h" + +// Renesas devices +#if defined(ARDUINO_UNOWIFIR4) || defined(ARDUINO_MINIMA) || defined(ARDUINO_PORTENTA_C33) +#define ESP_MAIL_STRSEP strsepImpl +#define ESP_MAIL_USE_STRSEP_IMPL +#else +#define ESP_MAIL_STRSEP strsep +#endif + +#if defined(ESP32) || defined(ESP8266) || defined(ARDUINO_RASPBERRY_PI_PICO_W) || \ + defined(ARDUINO_UNOWIFIR4) || defined(ARDUINO_PORTENTA_C33) || \ + defined(ARDUINO_PORTENTA_H7_M7) || defined(ARDUINO_PORTENTA_H7_M4) || \ + __has_include() ||__has_include() + +#if !defined(ESP_MAIL_DISABLE_ONBOARD_WIFI) + +#define ESP_MAIL_WIFI_IS_AVAILABLE + +#if defined(ESP32) || defined(ARDUINO_RASPBERRY_PI_PICO_W) +#include +#elif defined(ESP8266) +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#elif __has_include() +#include +#endif + +#if !defined(ARDUINO_RASPBERRY_PI_PICO_W) && \ + !defined(MB_ARDUINO_ARCH_SAMD) && \ + !defined(MB_ARDUINO_MBED_PORTENTA) && \ + !defined(ARDUINO_UNOWIFIR4) && \ + !defined(ARDUINO_PORTENTA_C33) && \ + !defined(ARDUINO_NANO_RP2040_CONNECT) +#define ESP_MAIL_HAS_WIFI_DISCONNECT +#endif + +#if defined(ARDUINO_PORTENTA_C33) +#define CONST_STRING_CAST char * // C33 WiFi library SSID is char array +#else +#define CONST_STRING_CAST const char * +#endif + +// WiFiS3 getTime is currently return 0 (not implemented) +#if __has_include() || __has_include() +#define ESP_MAIL_HAS_WIFI_TIME +#endif + +#if defined(MB_ARDUINO_PICO) && __has_include() +#define ESP_MAIL_HAS_WIFIMULTI +#endif + +#endif + +#endif + +#if !defined(ESP_MAIL_DISABLE_NATIVE_ETHERNET) + +#if defined(ESP32) && defined(CONFIG_ETH_ENABLED) +#include +#define ESP_MAIL_ETH_IS_AVAILABLE +#elif defined(ESP8266) && defined(ESP8266_CORE_SDK_V3_X_X) +#if defined(INC_ENC28J60_LWIP) || defined(INC_W5100_LWIP) || defined(INC_W5500_LWIP) +#define ESP_MAIL_ETH_IS_AVAILABLE +#endif +#endif + +#endif + +#if defined(TINY_GSM_MODEM_SIM800) || \ + defined(TINY_GSM_MODEM_SIM808) || \ + defined(TINY_GSM_MODEM_SIM868) || \ + defined(TINY_GSM_MODEM_SIM900) || \ + defined(TINY_GSM_MODEM_SIM7000) || \ + defined(TINY_GSM_MODEM_SIM7000) || \ + defined(TINY_GSM_MODEM_SIM7000SSL) || \ + defined(TINY_GSM_MODEM_SIM7070) || \ + defined(TINY_GSM_MODEM_SIM7080) || \ + defined(TINY_GSM_MODEM_SIM7090) || \ + defined(TINY_GSM_MODEM_SIM5320) || \ + defined(TINY_GSM_MODEM_SIM5360) || \ + defined(TINY_GSM_MODEM_SIM5300) || \ + defined(TINY_GSM_MODEM_SIM7100) || \ + defined(TINY_GSM_MODEM_SIM7600) || \ + defined(TINY_GSM_MODEM_SIM7800) || \ + defined(TINY_GSM_MODEM_SIM7500) || \ + defined(TINY_GSM_MODEM_UBLOX) || \ + defined(TINY_GSM_MODEM_SARAR4) || \ + defined(TINY_GSM_MODEM_M95) || \ + defined(TINY_GSM_MODEM_BG96) || \ + defined(TINY_GSM_MODEM_A6) || \ + defined(TINY_GSM_MODEM_A7) || \ + defined(TINY_GSM_MODEM_M590) || \ + defined(TINY_GSM_MODEM_MC60) || \ + defined(TINY_GSM_MODEM_MC60E) || \ + defined(TINY_GSM_MODEM_XBEE) || \ + defined(TINY_GSM_MODEM_SEQUANS_MONARCH) +#define ESP_MAIL_TINYGSM_IS_AVAILABLE +#endif + +#if defined(ESP_MAIL_TINYGSM_IS_AVAILABLE) && __has_include() +#include +#define ESP_MAIL_GSM_MODEM_IS_AVAILABLE +#endif + +#if defined(ESP_MAIL_WIFI_IS_AVAILABLE) +#define WiFI_CONNECTED (WiFi.status() == WL_CONNECTED) +#else +#define WiFI_CONNECTED false +#endif + +#endif diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/SDHelper.h b/lib/libesp32/ESP-Mail-Client/src/extras/SDHelper.h index 48490c473..2d4715e16 100644 --- a/lib/libesp32/ESP-Mail-Client/src/extras/SDHelper.h +++ b/lib/libesp32/ESP-Mail-Client/src/extras/SDHelper.h @@ -1,163 +1,163 @@ -#pragma once - -#ifndef SD_HELPER_H_ -#define SD_HELPER_H_ - -#include -#include - -// If SD Card used for storage, assign SD card type and FS used in src/ESP_Mail_FS.h and -// change the config for that card interfaces in this file (src/extras/SDHelper.h) - -#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) - -#if defined(ESP32) - -#define SPI_CS_PIN 13 -#define SPI_SCK_PIN 14 -#define SPI_MISO_PIN 2 -#define SPI_MOSI_PIN 15 -#define SPI_CLOCK_IN_MHz 16 - -// #define SPI_CS_PIN 5 -// #define SPI_SCK_PIN 18 -// #define SPI_MISO_PIN 19 -// #define SPI_MOSI_PIN 23 -// #define SPI_CLOCK_IN_MHz 4 // may work on lower clock rate - -#elif defined(ESP8266) -#define SPI_CS_PIN 15 -#elif defined(MB_ARDUINO_PICO) -// Use SPI 1's SS (GPIO 13) port as CS for SPI -#define SPI_CS_PIN PIN_SPI1_SS -#elif defined(MB_ARDUINO_ARCH_SAMD) || defined(MB_ARDUINO_NANO_RP2040_CONNECT) || defined(MB_ARDUINO_TEENSY) - -#define SPI_CS_PIN 4 - -#if defined(MBFS_SDFAT_ENABLED) -#define SPI_SCK_PIN -1 -#define SPI_MISO_PIN -1 -#define SPI_MOSI_PIN -1 -#define SPI_CLOCK_IN_MHz 4 // works on lower clock rate -#endif - -#endif - -// if SdFat library installed and ESP_Mail_FS.h was set to use it (for ESP32 only) -#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) - -// https://github.com/greiman/SdFat -SdSpiConfig sdFatSPIConfig(SPI_CS_PIN, DEDICATED_SPI, SD_SCK_MHZ(SPI_CLOCK_IN_MHz)); - -#elif defined(ESP32) // if ESP32 and no SdFat library installed - -SPIClass spi; - -#elif defined(ESP8266) - -SDFSConfig sdFSConfig(SPI_CS_PIN, SPI_HALF_SPEED); - -#elif defined(MB_ARDUINO_PICO) - -/** Use Pico SPI 1 for SPI - * MISO GPIO 12 - * MOSI GPIO 15 - * SCK GPIO 14 - * SS GPIO 13 - */ -SDFSConfig sdFSConfig(SPI_CS_PIN, SPI_HALF_SPEED, SPI1); - -#endif - -#endif - -bool SD_Card_Mounting() -{ - -#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) - -#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) - - Serial.print("\nMounting SD Card... "); - - if (!MailClient.sdBegin(&sdFatSPIConfig, SPI_CS_PIN, SPI_SCK_PIN, SPI_MISO_PIN, SPI_MOSI_PIN)) // pointer to SdSpiConfig, SS, SCK,MISO, MOSI - { - Serial.println("failed\n"); - return false; - } - else - { - Serial.println("success\n"); - return true; - } - -#elif defined(ESP32) // if ESP32 and no SdFat library installed - - Serial.print("\nMounting SD Card... "); - - spi.begin(SPI_SCK_PIN, SPI_MISO_PIN, SPI_MOSI_PIN, SPI_CS_PIN); // SPI pins config -> SCK,MISO, MOSI, SS - if (!MailClient.sdBegin(SPI_CS_PIN, &spi)) // SS, pointer to SPIClass <- SPIClass object should defined as static or global - { - Serial.println("failed\n"); - return false; - } - else - { - Serial.println("success\n"); - return true; - } -#elif defined(ESP8266) - - Serial.print("\nMounting SD Card... "); - - if (!MailClient.sdBegin(SPI_CS_PIN)) // or Firebase.sdBegin(&sdFSConfig) - { - Serial.println("failed\n"); - return false; - } - else - { - Serial.println("success\n"); - return true; - } - -#elif defined(MB_ARDUINO_PICO) - - Serial.print("\nMounting SD Card... "); - - if (!MailClient.sdBegin(&sdFSConfig)) // We begin with the SDFSConfig to use SPI 1 port - { - Serial.println("failed\n"); - return false; - } - else - { - Serial.println("success\n"); - return true; - } - -#endif - -#endif - -#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD_MMC) - - Serial.print("\nMounting SD_MMC Card... "); - - if (!MailClient.sdMMCBegin("/sdcard", false, true)) - { - Serial.println("failed\n"); - return false; - } - else - { - Serial.println("success\n"); - return true; - } -#endif - - Serial.println("\nSD filesystem was not setup yet."); - return false; -} - -#endif +#pragma once + +#ifndef SD_HELPER_H_ +#define SD_HELPER_H_ + +#include +#include + +// If SD Card used for storage, assign SD card type and FS used in src/ESP_Mail_FS.h and +// change the config for that card interfaces in this file (src/extras/SDHelper.h) + +#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) + +#if defined(ESP32) + +#define SPI_CS_PIN 13 +#define SPI_SCK_PIN 14 +#define SPI_MISO_PIN 2 +#define SPI_MOSI_PIN 15 +#define SPI_CLOCK_IN_MHz 16 + +// #define SPI_CS_PIN 5 +// #define SPI_SCK_PIN 18 +// #define SPI_MISO_PIN 19 +// #define SPI_MOSI_PIN 23 +// #define SPI_CLOCK_IN_MHz 4 // may work on lower clock rate + +#elif defined(ESP8266) +#define SPI_CS_PIN 15 +#elif defined(MB_ARDUINO_PICO) +// Use SPI 1's SS (GPIO 13) port as CS for SPI +#define SPI_CS_PIN PIN_SPI1_SS +#elif defined(MB_ARDUINO_ARCH_SAMD) || defined(MB_ARDUINO_NANO_RP2040_CONNECT) || defined(MB_ARDUINO_TEENSY) + +#define SPI_CS_PIN 4 + +#if defined(MBFS_SDFAT_ENABLED) +#define SPI_SCK_PIN -1 +#define SPI_MISO_PIN -1 +#define SPI_MOSI_PIN -1 +#define SPI_CLOCK_IN_MHz 4 // works on lower clock rate +#endif + +#endif + +// if SdFat library installed and ESP_Mail_FS.h was set to use it (for ESP32 only) +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + +// https://github.com/greiman/SdFat +SdSpiConfig sdFatSPIConfig(SPI_CS_PIN, DEDICATED_SPI, SD_SCK_MHZ(SPI_CLOCK_IN_MHz)); + +#elif defined(ESP32) // if ESP32 and no SdFat library installed + +SPIClass spi; + +#elif defined(ESP8266) + +SDFSConfig sdFSConfig(SPI_CS_PIN, SPI_HALF_SPEED); + +#elif defined(MB_ARDUINO_PICO) + +/** Use Pico SPI 1 for SPI + * MISO GPIO 12 + * MOSI GPIO 15 + * SCK GPIO 14 + * SS GPIO 13 + */ +SDFSConfig sdFSConfig(SPI_CS_PIN, SPI_HALF_SPEED, SPI1); + +#endif + +#endif + +bool SD_Card_Mounting() +{ + +#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD) + +#if defined(MBFS_ESP32_SDFAT_ENABLED) || defined(MBFS_SDFAT_ENABLED) + + Serial.print("\nMounting SD Card... "); + + if (!MailClient.sdBegin(&sdFatSPIConfig, SPI_CS_PIN, SPI_SCK_PIN, SPI_MISO_PIN, SPI_MOSI_PIN)) // pointer to SdSpiConfig, SS, SCK,MISO, MOSI + { + Serial.println("failed\n"); + return false; + } + else + { + Serial.println("success\n"); + return true; + } + +#elif defined(ESP32) // if ESP32 and no SdFat library installed + + Serial.print("\nMounting SD Card... "); + + spi.begin(SPI_SCK_PIN, SPI_MISO_PIN, SPI_MOSI_PIN, SPI_CS_PIN); // SPI pins config -> SCK,MISO, MOSI, SS + if (!MailClient.sdBegin(SPI_CS_PIN, &spi)) // SS, pointer to SPIClass <- SPIClass object should defined as static or global + { + Serial.println("failed\n"); + return false; + } + else + { + Serial.println("success\n"); + return true; + } +#elif defined(ESP8266) + + Serial.print("\nMounting SD Card... "); + + if (!MailClient.sdBegin(SPI_CS_PIN)) // or Firebase.sdBegin(&sdFSConfig) + { + Serial.println("failed\n"); + return false; + } + else + { + Serial.println("success\n"); + return true; + } + +#elif defined(MB_ARDUINO_PICO) + + Serial.print("\nMounting SD Card... "); + + if (!MailClient.sdBegin(&sdFSConfig)) // We begin with the SDFSConfig to use SPI 1 port + { + Serial.println("failed\n"); + return false; + } + else + { + Serial.println("success\n"); + return true; + } + +#endif + +#endif + +#if defined(MBFS_SD_FS) && defined(MBFS_CARD_TYPE_SD_MMC) + + Serial.print("\nMounting SD_MMC Card... "); + + if (!MailClient.sdMMCBegin("/sdcard", false, true)) + { + Serial.println("failed\n"); + return false; + } + else + { + Serial.println("success\n"); + return true; + } +#endif + + Serial.println("\nSD filesystem was not setup yet."); + return false; +} + +#endif diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/mb_print/mb_print.c b/lib/libesp32/ESP-Mail-Client/src/extras/mb_print/mb_print.c index 1a595f4fc..1aa8ac6b0 100644 --- a/lib/libesp32/ESP-Mail-Client/src/extras/mb_print/mb_print.c +++ b/lib/libesp32/ESP-Mail-Client/src/extras/mb_print/mb_print.c @@ -1,1048 +1,1048 @@ -/////////////////////////////////////////////////////////////////////////////// -// \author (c) Marco Paland (info@paland.com) -// 2014-2019, PALANDesign Hannover, Germany -// -// \license The MIT License (MIT) -// -// 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. -// -// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on -// embedded systems with a very limited resources. These routines are thread -// safe and reentrant! -// Use this instead of the bloated standard/newlib printf cause these use -// malloc for printf (and may not be thread safe). -// -/////////////////////////////////////////////////////////////////////////////// - -#ifndef MB_PRINT_C -#define MB_PRINT_C - -#include -#include - -#include "mb_print.h" - -// define this globally (e.g. gcc -DMB_PRINT_INCLUDE_CONFIG_H ...) to include the -// printf_config.h header file -// default: undefined -#ifdef MB_PRINT_INCLUDE_CONFIG_H -#include "printf_config.h" -#endif - -// 'ntoa' conversion buffer size, this must be big enough to hold one converted -// numeric number including padded zeros (dynamically created on stack) -// default: 32 byte -#ifndef MB_PRINT_NTOA_BUFFER_SIZE -#define MB_PRINT_NTOA_BUFFER_SIZE 32U -#endif - -// 'ftoa' conversion buffer size, this must be big enough to hold one converted -// float number including padded zeros (dynamically created on stack) -// default: 32 byte -#ifndef MB_PRINT_FTOA_BUFFER_SIZE -#define MB_PRINT_FTOA_BUFFER_SIZE 32U -#endif - -// support for the floating point type (%f) -// default: activated -#ifndef MB_PRINT_DISABLE_SUPPORT_FLOAT -#define MB_PRINT_SUPPORT_FLOAT -#endif - -// support for exponential floating point notation (%e/%g) -// default: activated -#ifndef MB_PRINT_DISABLE_SUPPORT_EXPONENTIAL -#define MB_PRINT_SUPPORT_EXPONENTIAL -#endif - -// define the default floating point precision -// default: 6 digits -#ifndef MB_PRINT_DEFAULT_FLOAT_PRECISION -#define MB_PRINT_DEFAULT_FLOAT_PRECISION 6U -#endif - -// define the largest float suitable to print with %f -// default: 1e9 -#ifndef MB_PRINT_MAX_FLOAT -#define MB_PRINT_MAX_FLOAT 1e9 -#endif - -// support for the long long types (%llu or %p) -// default: activated -#ifndef MB_PRINT_DISABLE_SUPPORT_LONG_LONG -#define MB_PRINT_SUPPORT_LONG_LONG -#endif - -// support for the ptrdiff_t type (%t) -// ptrdiff_t is normally defined in as long or long long type -// default: activated -#ifndef MB_PRINT_DISABLE_SUPPORT_PTRDIFF_T -#define MB_PRINT_SUPPORT_PTRDIFF_T -#endif - -/////////////////////////////////////////////////////////////////////////////// - -// internal flag definitions -#define MB_PRINT_FLAGS_ZEROPAD (1U << 0U) -#define MB_PRINT_FLAGS_LEFT (1U << 1U) -#define MB_PRINT_FLAGS_PLUS (1U << 2U) -#define MB_PRINT_FLAGS_SPACE (1U << 3U) -#define MB_PRINT_FLAGS_HASH (1U << 4U) -#define MB_PRINT_FLAGS_UPPERCASE (1U << 5U) -#define MB_PRINT_FLAGS_CHAR (1U << 6U) -#define MB_PRINT_FLAGS_SHORT (1U << 7U) -#define MB_PRINT_FLAGS_LONG (1U << 8U) -#define MB_PRINT_FLAGS_LONG_LONG (1U << 9U) -#define MB_PRINT_FLAGS_PRECISION (1U << 10U) -#define MB_PRINT_FLAGS_ADAPT_EXP (1U << 11U) - -// import float.h for DBL_MAX -#if defined(MB_PRINT_SUPPORT_FLOAT) -#include -#endif - -// output function type -typedef void (*mb_print_out_fn_type)(char character, void *buffer, size_t idx, size_t maxlen); - -// wrapper (used as buffer) for output function type -typedef struct -{ - void (*fct)(char character, void *arg); - void *arg; -} mb_print_out_fn_wrap_type; - -// internal buffer output -static inline void mb_print_out_buffer(char character, void *buffer, size_t idx, size_t maxlen) -{ - if (idx < maxlen) - { - ((char *)buffer)[idx] = character; - } -} - -// internal null output -static inline void mb_print_out_null(char character, void *buffer, size_t idx, size_t maxlen) -{ - (void)character; - (void)buffer; - (void)idx; - (void)maxlen; -} - -// internal _putchar wrapper -static inline void mb_print_out_char(char character, void *buffer, size_t idx, size_t maxlen) -{ - (void)buffer; - (void)idx; - (void)maxlen; - if (character) - { - mb_print_putchar(character); - } -} - -// internal output function wrapper -static inline void mb_print_out_fn(char character, void *buffer, size_t idx, size_t maxlen) -{ - (void)idx; - (void)maxlen; - if (character) - { - // buffer is the output fct pointer - ((mb_print_out_fn_wrap_type *)buffer)->fct(character, ((mb_print_out_fn_wrap_type *)buffer)->arg); - } -} - -// internal secure strlen -// \return The length of the string (excluding the terminating 0) limited by 'maxsize' -static inline unsigned int mb_print_strlen(const char *str, size_t maxsize) -{ - const char *s; - for (s = str; *s && maxsize--; ++s) - ; - return (unsigned int)(s - str); -} - -// internal test if char is a digit (0-9) -// \return true if char is a digit -static inline bool mb_print_is_digit(char ch) -{ - return (ch >= '0') && (ch <= '9'); -} - -// internal ASCII string to unsigned int conversion -static unsigned int mb_print_atoi(const char **str) -{ - unsigned int i = 0U; - while (mb_print_is_digit(**str)) - { - i = i * 10U + (unsigned int)(*((*str)++) - '0'); - } - return i; -} - -// output the specified string in reverse, taking care of any zero-padding -static size_t mb_print_out_rev(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, const char *buf, size_t len, unsigned int width, unsigned int flags) -{ - const size_t start_idx = idx; - - // pad spaces up to given width - if (!(flags & MB_PRINT_FLAGS_LEFT) && !(flags & MB_PRINT_FLAGS_ZEROPAD)) - { - for (size_t i = len; i < width; i++) - { - out(' ', buffer, idx++, maxlen); - } - } - - // reverse string - while (len) - { - out(buf[--len], buffer, idx++, maxlen); - } - - // append pad spaces up to given width - if (flags & MB_PRINT_FLAGS_LEFT) - { - while (idx - start_idx < width) - { - out(' ', buffer, idx++, maxlen); - } - } - - return idx; -} - -// internal itoa format -static size_t mb_print_itoa_format(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, char *buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) -{ - // pad leading zeros - if (!(flags & MB_PRINT_FLAGS_LEFT)) - { - if (width && (flags & MB_PRINT_FLAGS_ZEROPAD) && (negative || (flags & (MB_PRINT_FLAGS_PLUS | MB_PRINT_FLAGS_SPACE)))) - { - width--; - } - while ((len < prec) && (len < MB_PRINT_NTOA_BUFFER_SIZE)) - { - buf[len++] = '0'; - } - while ((flags & MB_PRINT_FLAGS_ZEROPAD) && (len < width) && (len < MB_PRINT_NTOA_BUFFER_SIZE)) - { - buf[len++] = '0'; - } - } - - // handle hash - if (flags & MB_PRINT_FLAGS_HASH) - { - if (!(flags & MB_PRINT_FLAGS_PRECISION) && len && ((len == prec) || (len == width))) - { - len--; - if (len && (base == 16U)) - { - len--; - } - } - if ((base == 16U) && !(flags & MB_PRINT_FLAGS_UPPERCASE) && (len < MB_PRINT_NTOA_BUFFER_SIZE)) - { - buf[len++] = 'x'; - } - else if ((base == 16U) && (flags & MB_PRINT_FLAGS_UPPERCASE) && (len < MB_PRINT_NTOA_BUFFER_SIZE)) - { - buf[len++] = 'X'; - } - else if ((base == 2U) && (len < MB_PRINT_NTOA_BUFFER_SIZE)) - { - buf[len++] = 'b'; - } - if (len < MB_PRINT_NTOA_BUFFER_SIZE) - { - buf[len++] = '0'; - } - } - - if (len < MB_PRINT_NTOA_BUFFER_SIZE) - { - if (negative) - { - buf[len++] = '-'; - } - else if (flags & MB_PRINT_FLAGS_PLUS) - { - buf[len++] = '+'; // ignore the space if the '+' exists - } - else if (flags & MB_PRINT_FLAGS_SPACE) - { - buf[len++] = ' '; - } - } - - return mb_print_out_rev(out, buffer, idx, maxlen, buf, len, width, flags); -} - -// internal itoa for 'long' type -static size_t mb_print_itoa_long(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) -{ - char buf[MB_PRINT_NTOA_BUFFER_SIZE]; - size_t len = 0U; - - // no hash for 0 values - if (!value) - { - flags &= ~MB_PRINT_FLAGS_HASH; - } - - // write if precision != 0 and value is != 0 - if (!(flags & MB_PRINT_FLAGS_PRECISION) || value) - { - do - { - const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & MB_PRINT_FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; - value /= base; - } while (value && (len < MB_PRINT_NTOA_BUFFER_SIZE)); - } - - return mb_print_itoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); -} - -// internal itoa for 'long long' type -#if defined(MB_PRINT_SUPPORT_LONG_LONG) -static size_t mb_print_itoa_long_long(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) -{ - char buf[MB_PRINT_NTOA_BUFFER_SIZE]; - size_t len = 0U; - - // no hash for 0 values - if (!value) - { - flags &= ~MB_PRINT_FLAGS_HASH; - } - - // write if precision != 0 and value is != 0 - if (!(flags & MB_PRINT_FLAGS_PRECISION) || value) - { - do - { - const char digit = (char)(value % base); - buf[len++] = digit < 10 ? '0' + digit : (flags & MB_PRINT_FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; - value /= base; - } while (value && (len < MB_PRINT_NTOA_BUFFER_SIZE)); - } - - return mb_print_itoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); -} -#endif // MB_PRINT_SUPPORT_LONG_LONG - -#if defined(MB_PRINT_SUPPORT_FLOAT) - -#if defined(MB_PRINT_SUPPORT_EXPONENTIAL) -// forward declaration so that mb_print_ftoa can switch to exp notation for values > MB_PRINT_MAX_FLOAT -static size_t mb_print_ftoa_exp(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags); -#endif - -// internal ftoa for fixed decimal floating point -static size_t mb_print_ftoa(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) -{ - char buf[MB_PRINT_FTOA_BUFFER_SIZE]; - size_t len = 0U; - double diff = 0.0; - - // powers of 10 - static const double pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}; - - // test for special values - if (value != value) - return mb_print_out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); - if (value < -DBL_MAX) - return mb_print_out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); - if (value > DBL_MAX) - return mb_print_out_rev(out, buffer, idx, maxlen, (flags & MB_PRINT_FLAGS_PLUS) ? "fni+" : "fni", (flags & MB_PRINT_FLAGS_PLUS) ? 4U : 3U, width, flags); - - // test for very large values - // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad - if ((value > MB_PRINT_MAX_FLOAT) || (value < -MB_PRINT_MAX_FLOAT)) - { -#if defined(MB_PRINT_SUPPORT_EXPONENTIAL) - return mb_print_ftoa_exp(out, buffer, idx, maxlen, value, prec, width, flags); -#else - return 0U; -#endif - } - - // test for negative - bool negative = false; - if (value < 0) - { - negative = true; - value = 0 - value; - } - - // set default precision, if not set explicitly - if (!(flags & MB_PRINT_FLAGS_PRECISION)) - { - prec = MB_PRINT_DEFAULT_FLOAT_PRECISION; - } - // limit precision to 9, cause a prec >= 10 can lead to overflow errors - while ((len < MB_PRINT_FTOA_BUFFER_SIZE) && (prec > 9U)) - { - buf[len++] = '0'; - prec--; - } - - int whole = (int)value; - double tmp = (value - whole) * pow10[prec]; - unsigned long frac = (unsigned long)tmp; - diff = tmp - frac; - - if (diff > 0.5) - { - ++frac; - // handle rollover, e.g. case 0.99 with prec 1 is 1.0 - if (frac >= pow10[prec]) - { - frac = 0; - ++whole; - } - } - else if (diff < 0.5) - { - } - else if ((frac == 0U) || (frac & 1U)) - { - // if halfway, round up if odd OR if last digit is 0 - ++frac; - } - - if (prec == 0U) - { - diff = value - (double)whole; - if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) - { - // exactly 0.5 and ODD, then round up - // 1.5 -> 2, but 2.5 -> 2 - ++whole; - } - } - else - { - unsigned int count = prec; - // now do fractional part, as an unsigned number - while (len < MB_PRINT_FTOA_BUFFER_SIZE) - { - --count; - buf[len++] = (char)(48U + (frac % 10U)); - if (!(frac /= 10U)) - { - break; - } - } - // add extra 0s - while ((len < MB_PRINT_FTOA_BUFFER_SIZE) && (count-- > 0U)) - { - buf[len++] = '0'; - } - if (len < MB_PRINT_FTOA_BUFFER_SIZE) - { - // add decimal - buf[len++] = '.'; - } - } - - // do whole part, number is reversed - while (len < MB_PRINT_FTOA_BUFFER_SIZE) - { - buf[len++] = (char)(48 + (whole % 10)); - if (!(whole /= 10)) - { - break; - } - } - - // pad leading zeros - if (!(flags & MB_PRINT_FLAGS_LEFT) && (flags & MB_PRINT_FLAGS_ZEROPAD)) - { - if (width && (negative || (flags & (MB_PRINT_FLAGS_PLUS | MB_PRINT_FLAGS_SPACE)))) - { - width--; - } - while ((len < width) && (len < MB_PRINT_FTOA_BUFFER_SIZE)) - { - buf[len++] = '0'; - } - } - - if (len < MB_PRINT_FTOA_BUFFER_SIZE) - { - if (negative) - { - buf[len++] = '-'; - } - else if (flags & MB_PRINT_FLAGS_PLUS) - { - buf[len++] = '+'; // ignore the space if the '+' exists - } - else if (flags & MB_PRINT_FLAGS_SPACE) - { - buf[len++] = ' '; - } - } - - return mb_print_out_rev(out, buffer, idx, maxlen, buf, len, width, flags); -} - -#if defined(MB_PRINT_SUPPORT_EXPONENTIAL) -// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse -static size_t mb_print_ftoa_exp(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) -{ - // check for NaN and special values - if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) - { - return mb_print_ftoa(out, buffer, idx, maxlen, value, prec, width, flags); - } - - // determine the sign - const bool negative = value < 0; - if (negative) - { - value = -value; - } - - // default precision - if (!(flags & MB_PRINT_FLAGS_PRECISION)) - { - prec = MB_PRINT_DEFAULT_FLOAT_PRECISION; - } - - // determine the decimal exponent - // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) - union - { - uint64_t U; - double F; - } conv; - - conv.F = value; - int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 - conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2) - // now approximate log10 from the log2 integer part and an expansion of ln around 1.5 - int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168); - // now we want to compute 10^expval but we want to be sure it won't overflow - exp2 = (int)(expval * 3.321928094887362 + 0.5); - const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; - const double z2 = z * z; - conv.U = (uint64_t)(exp2 + 1023) << 52U; - // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex - conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); - // correct for rounding errors - if (value < conv.F) - { - expval--; - conv.F /= 10; - } - - // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters - unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; - - // in "%g" mode, "prec" is the number of *significant figures* not decimals - if (flags & MB_PRINT_FLAGS_ADAPT_EXP) - { - // do we want to fall-back to "%f" mode? - if ((value >= 1e-4) && (value < 1e6)) - { - if ((int)prec > expval) - { - prec = (unsigned)((int)prec - expval - 1); - } - else - { - prec = 0; - } - flags |= MB_PRINT_FLAGS_PRECISION; // make sure mb_print_ftoa respects precision - // no characters in exponent - minwidth = 0U; - expval = 0; - } - else - { - // we use one sigfig for the whole part - if ((prec > 0) && (flags & MB_PRINT_FLAGS_PRECISION)) - { - --prec; - } - } - } - - // will everything fit? - unsigned int fwidth = width; - if (width > minwidth) - { - // we didn't fall-back so subtract the characters required for the exponent - fwidth -= minwidth; - } - else - { - // not enough characters, so go back to default sizing - fwidth = 0U; - } - if ((flags & MB_PRINT_FLAGS_LEFT) && minwidth) - { - // if we're padding on the right, DON'T pad the floating part - fwidth = 0U; - } - - // rescale the float value - if (expval) - { - value /= conv.F; - } - - // output the floating part - const size_t start_idx = idx; - idx = mb_print_ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~MB_PRINT_FLAGS_ADAPT_EXP); - - // output the exponent part - if (minwidth) - { - // output the exponential symbol - out((flags & MB_PRINT_FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); - // output the exponent value - idx = mb_print_itoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth - 1, MB_PRINT_FLAGS_ZEROPAD | MB_PRINT_FLAGS_PLUS); - // might need to right-pad spaces - if (flags & MB_PRINT_FLAGS_LEFT) - { - while (idx - start_idx < width) - out(' ', buffer, idx++, maxlen); - } - } - return idx; -} -#endif // MB_PRINT_SUPPORT_EXPONENTIAL -#endif // MB_PRINT_SUPPORT_FLOAT - -// internal vsnprintf -static int mb_print_vsnprintf_int(mb_print_out_fn_type out, char *buffer, const size_t maxlen, const char *format, va_list va) -{ - unsigned int flags, width, precision, n; - size_t idx = 0U; - - if (!buffer) - { - // use null output function - out = mb_print_out_null; - } - - while (*format) - { - // format specifier? %[flags][width][.precision][length] - if (*format != '%') - { - // no - out(*format, buffer, idx++, maxlen); - format++; - continue; - } - else - { - // yes, evaluate it - format++; - } - - // evaluate flags - flags = 0U; - do - { - switch (*format) - { - case '0': - flags |= MB_PRINT_FLAGS_ZEROPAD; - format++; - n = 1U; - break; - case '-': - flags |= MB_PRINT_FLAGS_LEFT; - format++; - n = 1U; - break; - case '+': - flags |= MB_PRINT_FLAGS_PLUS; - format++; - n = 1U; - break; - case ' ': - flags |= MB_PRINT_FLAGS_SPACE; - format++; - n = 1U; - break; - case '#': - flags |= MB_PRINT_FLAGS_HASH; - format++; - n = 1U; - break; - default: - n = 0U; - break; - } - } while (n); - - // evaluate width field - width = 0U; - if (mb_print_is_digit(*format)) - { - width = mb_print_atoi(&format); - } - else if (*format == '*') - { - const int w = va_arg(va, int); - if (w < 0) - { - flags |= MB_PRINT_FLAGS_LEFT; // reverse padding - width = (unsigned int)-w; - } - else - { - width = (unsigned int)w; - } - format++; - } - - // evaluate precision field - precision = 0U; - if (*format == '.') - { - flags |= MB_PRINT_FLAGS_PRECISION; - format++; - if (mb_print_is_digit(*format)) - { - precision = mb_print_atoi(&format); - } - else if (*format == '*') - { - const int prec = (int)va_arg(va, int); - precision = prec > 0 ? (unsigned int)prec : 0U; - format++; - } - } - - // evaluate length field - switch (*format) - { - case 'l': - flags |= MB_PRINT_FLAGS_LONG; - format++; - if (*format == 'l') - { - flags |= MB_PRINT_FLAGS_LONG_LONG; - format++; - } - break; - case 'h': - flags |= MB_PRINT_FLAGS_SHORT; - format++; - if (*format == 'h') - { - flags |= MB_PRINT_FLAGS_CHAR; - format++; - } - break; -#if defined(MB_PRINT_SUPPORT_PTRDIFF_T) - case 't': - flags |= (sizeof(ptrdiff_t) == sizeof(long) ? MB_PRINT_FLAGS_LONG : MB_PRINT_FLAGS_LONG_LONG); - format++; - break; -#endif - case 'j': - flags |= (sizeof(intmax_t) == sizeof(long) ? MB_PRINT_FLAGS_LONG : MB_PRINT_FLAGS_LONG_LONG); - format++; - break; - case 'z': - flags |= (sizeof(size_t) == sizeof(long) ? MB_PRINT_FLAGS_LONG : MB_PRINT_FLAGS_LONG_LONG); - format++; - break; - default: - break; - } - - // evaluate specifier - switch (*format) - { - case 'd': - case 'i': - case 'u': - case 'x': - case 'X': - case 'o': - case 'b': - { - // set the base - unsigned int base; - if (*format == 'x' || *format == 'X') - { - base = 16U; - } - else if (*format == 'o') - { - base = 8U; - } - else if (*format == 'b') - { - base = 2U; - } - else - { - base = 10U; - flags &= ~MB_PRINT_FLAGS_HASH; // no hash for dec format - } - // uppercase - if (*format == 'X') - { - flags |= MB_PRINT_FLAGS_UPPERCASE; - } - - // no plus or space flag for u, x, X, o, b - if ((*format != 'i') && (*format != 'd')) - { - flags &= ~(MB_PRINT_FLAGS_PLUS | MB_PRINT_FLAGS_SPACE); - } - - // ignore '0' flag when precision is given - if (flags & MB_PRINT_FLAGS_PRECISION) - { - flags &= ~MB_PRINT_FLAGS_ZEROPAD; - } - - // convert the integer - if ((*format == 'i') || (*format == 'd')) - { - // signed - if (flags & MB_PRINT_FLAGS_LONG_LONG) - { -#if defined(MB_PRINT_SUPPORT_LONG_LONG) - const long long value = va_arg(va, long long); - idx = mb_print_itoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); -#endif - } - else if (flags & MB_PRINT_FLAGS_LONG) - { - const long value = va_arg(va, long); - idx = mb_print_itoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); - } - else - { - const int value = (flags & MB_PRINT_FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & MB_PRINT_FLAGS_SHORT) ? (short int)va_arg(va, int) - : va_arg(va, int); - idx = mb_print_itoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); - } - } - else - { - // unsigned - if (flags & MB_PRINT_FLAGS_LONG_LONG) - { -#if defined(MB_PRINT_SUPPORT_LONG_LONG) - idx = mb_print_itoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); -#endif - } - else if (flags & MB_PRINT_FLAGS_LONG) - { - idx = mb_print_itoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); - } - else - { - const unsigned int value = (flags & MB_PRINT_FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & MB_PRINT_FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) - : va_arg(va, unsigned int); - idx = mb_print_itoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); - } - } - format++; - break; - } -#if defined(MB_PRINT_SUPPORT_FLOAT) - case 'f': - case 'F': - if (*format == 'F') - flags |= MB_PRINT_FLAGS_UPPERCASE; - idx = mb_print_ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); - format++; - break; -#if defined(MB_PRINT_SUPPORT_EXPONENTIAL) - case 'e': - case 'E': - case 'g': - case 'G': - if ((*format == 'g') || (*format == 'G')) - flags |= MB_PRINT_FLAGS_ADAPT_EXP; - if ((*format == 'E') || (*format == 'G')) - flags |= MB_PRINT_FLAGS_UPPERCASE; - idx = mb_print_ftoa_exp(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); - format++; - break; -#endif // MB_PRINT_SUPPORT_EXPONENTIAL -#endif // MB_PRINT_SUPPORT_FLOAT - case 'c': - { - unsigned int l = 1U; - // pre padding - if (!(flags & MB_PRINT_FLAGS_LEFT)) - { - while (l++ < width) - { - out(' ', buffer, idx++, maxlen); - } - } - // char output - out((char)va_arg(va, int), buffer, idx++, maxlen); - // post padding - if (flags & MB_PRINT_FLAGS_LEFT) - { - while (l++ < width) - { - out(' ', buffer, idx++, maxlen); - } - } - format++; - break; - } - - case 's': - { - const char *p = va_arg(va, char *); - unsigned int l = mb_print_strlen(p, precision ? precision : (size_t)-1); - // pre padding - if (flags & MB_PRINT_FLAGS_PRECISION) - { - l = (l < precision ? l : precision); - } - if (!(flags & MB_PRINT_FLAGS_LEFT)) - { - while (l++ < width) - { - out(' ', buffer, idx++, maxlen); - } - } - // string output - while ((*p != 0) && (!(flags & MB_PRINT_FLAGS_PRECISION) || precision--)) - { - out(*(p++), buffer, idx++, maxlen); - } - // post padding - if (flags & MB_PRINT_FLAGS_LEFT) - { - while (l++ < width) - { - out(' ', buffer, idx++, maxlen); - } - } - format++; - break; - } - - case 'p': - { - width = sizeof(void *) * 2U; - flags |= MB_PRINT_FLAGS_ZEROPAD | MB_PRINT_FLAGS_UPPERCASE; -#if defined(MB_PRINT_SUPPORT_LONG_LONG) - const bool is_ll = sizeof(uintptr_t) == sizeof(long long); - if (is_ll) - { - idx = mb_print_itoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void *), false, 16U, precision, width, flags); - } - else - { -#endif - idx = mb_print_itoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void *)), false, 16U, precision, width, flags); -#if defined(MB_PRINT_SUPPORT_LONG_LONG) - } -#endif - format++; - break; - } - - case '%': - out('%', buffer, idx++, maxlen); - format++; - break; - - default: - out(*format, buffer, idx++, maxlen); - format++; - break; - } - } - - // termination - out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); - - // return written chars without terminating \0 - return (int)idx; -} - -/////////////////////////////////////////////////////////////////////////////// - -int mb_print_printf(const char *format, ...) -{ - va_list va; - va_start(va, format); - char buffer[1]; - const int ret = mb_print_vsnprintf_int(mb_print_out_char, buffer, (size_t)-1, format, va); - va_end(va); - return ret; -} - -int mb_print_sprintf(char *buffer, const char *format, ...) -{ - va_list va; - va_start(va, format); - const int ret = mb_print_vsnprintf_int(mb_print_out_buffer, buffer, (size_t)-1, format, va); - va_end(va); - return ret; -} - -int mb_print_snprintf_(char *buffer, size_t count, const char *format, ...) -{ - va_list va; - va_start(va, format); - const int ret = mb_print_vsnprintf_int(mb_print_out_buffer, buffer, count, format, va); - va_end(va); - return ret; -} - -int mb_print_vprintf(const char *format, va_list va) -{ - char buffer[1]; - return mb_print_vsnprintf_int(mb_print_out_char, buffer, (size_t)-1, format, va); -} - -int mb_print_vsnprintf_(char *buffer, size_t count, const char *format, va_list va) -{ - return mb_print_vsnprintf_int(mb_print_out_buffer, buffer, count, format, va); -} - -int mb_print_fnprintf(void (*out)(char character, void *arg), void *arg, const char *format, ...) -{ - va_list va; - va_start(va, format); - const mb_print_out_fn_wrap_type out_fct_wrap = {out, arg}; - const int ret = mb_print_vsnprintf_int(mb_print_out_fn, (char *)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va); - va_end(va); - return ret; -} - +/////////////////////////////////////////////////////////////////////////////// +// \author (c) Marco Paland (info@paland.com) +// 2014-2019, PALANDesign Hannover, Germany +// +// \license The MIT License (MIT) +// +// 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. +// +// \brief Tiny printf, sprintf and (v)snprintf implementation, optimized for speed on +// embedded systems with a very limited resources. These routines are thread +// safe and reentrant! +// Use this instead of the bloated standard/newlib printf cause these use +// malloc for printf (and may not be thread safe). +// +/////////////////////////////////////////////////////////////////////////////// + +#ifndef MB_PRINT_C +#define MB_PRINT_C + +#include +#include + +#include "mb_print.h" + +// define this globally (e.g. gcc -DMB_PRINT_INCLUDE_CONFIG_H ...) to include the +// printf_config.h header file +// default: undefined +#ifdef MB_PRINT_INCLUDE_CONFIG_H +#include "printf_config.h" +#endif + +// 'ntoa' conversion buffer size, this must be big enough to hold one converted +// numeric number including padded zeros (dynamically created on stack) +// default: 32 byte +#ifndef MB_PRINT_NTOA_BUFFER_SIZE +#define MB_PRINT_NTOA_BUFFER_SIZE 32U +#endif + +// 'ftoa' conversion buffer size, this must be big enough to hold one converted +// float number including padded zeros (dynamically created on stack) +// default: 32 byte +#ifndef MB_PRINT_FTOA_BUFFER_SIZE +#define MB_PRINT_FTOA_BUFFER_SIZE 32U +#endif + +// support for the floating point type (%f) +// default: activated +#ifndef MB_PRINT_DISABLE_SUPPORT_FLOAT +#define MB_PRINT_SUPPORT_FLOAT +#endif + +// support for exponential floating point notation (%e/%g) +// default: activated +#ifndef MB_PRINT_DISABLE_SUPPORT_EXPONENTIAL +#define MB_PRINT_SUPPORT_EXPONENTIAL +#endif + +// define the default floating point precision +// default: 6 digits +#ifndef MB_PRINT_DEFAULT_FLOAT_PRECISION +#define MB_PRINT_DEFAULT_FLOAT_PRECISION 6U +#endif + +// define the largest float suitable to print with %f +// default: 1e9 +#ifndef MB_PRINT_MAX_FLOAT +#define MB_PRINT_MAX_FLOAT 1e9 +#endif + +// support for the long long types (%llu or %p) +// default: activated +#ifndef MB_PRINT_DISABLE_SUPPORT_LONG_LONG +#define MB_PRINT_SUPPORT_LONG_LONG +#endif + +// support for the ptrdiff_t type (%t) +// ptrdiff_t is normally defined in as long or long long type +// default: activated +#ifndef MB_PRINT_DISABLE_SUPPORT_PTRDIFF_T +#define MB_PRINT_SUPPORT_PTRDIFF_T +#endif + +/////////////////////////////////////////////////////////////////////////////// + +// internal flag definitions +#define MB_PRINT_FLAGS_ZEROPAD (1U << 0U) +#define MB_PRINT_FLAGS_LEFT (1U << 1U) +#define MB_PRINT_FLAGS_PLUS (1U << 2U) +#define MB_PRINT_FLAGS_SPACE (1U << 3U) +#define MB_PRINT_FLAGS_HASH (1U << 4U) +#define MB_PRINT_FLAGS_UPPERCASE (1U << 5U) +#define MB_PRINT_FLAGS_CHAR (1U << 6U) +#define MB_PRINT_FLAGS_SHORT (1U << 7U) +#define MB_PRINT_FLAGS_LONG (1U << 8U) +#define MB_PRINT_FLAGS_LONG_LONG (1U << 9U) +#define MB_PRINT_FLAGS_PRECISION (1U << 10U) +#define MB_PRINT_FLAGS_ADAPT_EXP (1U << 11U) + +// import float.h for DBL_MAX +#if defined(MB_PRINT_SUPPORT_FLOAT) +#include +#endif + +// output function type +typedef void (*mb_print_out_fn_type)(char character, void *buffer, size_t idx, size_t maxlen); + +// wrapper (used as buffer) for output function type +typedef struct +{ + void (*fct)(char character, void *arg); + void *arg; +} mb_print_out_fn_wrap_type; + +// internal buffer output +static inline void mb_print_out_buffer(char character, void *buffer, size_t idx, size_t maxlen) +{ + if (idx < maxlen) + { + ((char *)buffer)[idx] = character; + } +} + +// internal null output +static inline void mb_print_out_null(char character, void *buffer, size_t idx, size_t maxlen) +{ + (void)character; + (void)buffer; + (void)idx; + (void)maxlen; +} + +// internal _putchar wrapper +static inline void mb_print_out_char(char character, void *buffer, size_t idx, size_t maxlen) +{ + (void)buffer; + (void)idx; + (void)maxlen; + if (character) + { + mb_print_putchar(character); + } +} + +// internal output function wrapper +static inline void mb_print_out_fn(char character, void *buffer, size_t idx, size_t maxlen) +{ + (void)idx; + (void)maxlen; + if (character) + { + // buffer is the output fct pointer + ((mb_print_out_fn_wrap_type *)buffer)->fct(character, ((mb_print_out_fn_wrap_type *)buffer)->arg); + } +} + +// internal secure strlen +// \return The length of the string (excluding the terminating 0) limited by 'maxsize' +static inline unsigned int mb_print_strlen(const char *str, size_t maxsize) +{ + const char *s; + for (s = str; *s && maxsize--; ++s) + ; + return (unsigned int)(s - str); +} + +// internal test if char is a digit (0-9) +// \return true if char is a digit +static inline bool mb_print_is_digit(char ch) +{ + return (ch >= '0') && (ch <= '9'); +} + +// internal ASCII string to unsigned int conversion +static unsigned int mb_print_atoi(const char **str) +{ + unsigned int i = 0U; + while (mb_print_is_digit(**str)) + { + i = i * 10U + (unsigned int)(*((*str)++) - '0'); + } + return i; +} + +// output the specified string in reverse, taking care of any zero-padding +static size_t mb_print_out_rev(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, const char *buf, size_t len, unsigned int width, unsigned int flags) +{ + const size_t start_idx = idx; + + // pad spaces up to given width + if (!(flags & MB_PRINT_FLAGS_LEFT) && !(flags & MB_PRINT_FLAGS_ZEROPAD)) + { + for (size_t i = len; i < width; i++) + { + out(' ', buffer, idx++, maxlen); + } + } + + // reverse string + while (len) + { + out(buf[--len], buffer, idx++, maxlen); + } + + // append pad spaces up to given width + if (flags & MB_PRINT_FLAGS_LEFT) + { + while (idx - start_idx < width) + { + out(' ', buffer, idx++, maxlen); + } + } + + return idx; +} + +// internal itoa format +static size_t mb_print_itoa_format(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, char *buf, size_t len, bool negative, unsigned int base, unsigned int prec, unsigned int width, unsigned int flags) +{ + // pad leading zeros + if (!(flags & MB_PRINT_FLAGS_LEFT)) + { + if (width && (flags & MB_PRINT_FLAGS_ZEROPAD) && (negative || (flags & (MB_PRINT_FLAGS_PLUS | MB_PRINT_FLAGS_SPACE)))) + { + width--; + } + while ((len < prec) && (len < MB_PRINT_NTOA_BUFFER_SIZE)) + { + buf[len++] = '0'; + } + while ((flags & MB_PRINT_FLAGS_ZEROPAD) && (len < width) && (len < MB_PRINT_NTOA_BUFFER_SIZE)) + { + buf[len++] = '0'; + } + } + + // handle hash + if (flags & MB_PRINT_FLAGS_HASH) + { + if (!(flags & MB_PRINT_FLAGS_PRECISION) && len && ((len == prec) || (len == width))) + { + len--; + if (len && (base == 16U)) + { + len--; + } + } + if ((base == 16U) && !(flags & MB_PRINT_FLAGS_UPPERCASE) && (len < MB_PRINT_NTOA_BUFFER_SIZE)) + { + buf[len++] = 'x'; + } + else if ((base == 16U) && (flags & MB_PRINT_FLAGS_UPPERCASE) && (len < MB_PRINT_NTOA_BUFFER_SIZE)) + { + buf[len++] = 'X'; + } + else if ((base == 2U) && (len < MB_PRINT_NTOA_BUFFER_SIZE)) + { + buf[len++] = 'b'; + } + if (len < MB_PRINT_NTOA_BUFFER_SIZE) + { + buf[len++] = '0'; + } + } + + if (len < MB_PRINT_NTOA_BUFFER_SIZE) + { + if (negative) + { + buf[len++] = '-'; + } + else if (flags & MB_PRINT_FLAGS_PLUS) + { + buf[len++] = '+'; // ignore the space if the '+' exists + } + else if (flags & MB_PRINT_FLAGS_SPACE) + { + buf[len++] = ' '; + } + } + + return mb_print_out_rev(out, buffer, idx, maxlen, buf, len, width, flags); +} + +// internal itoa for 'long' type +static size_t mb_print_itoa_long(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, unsigned long value, bool negative, unsigned long base, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[MB_PRINT_NTOA_BUFFER_SIZE]; + size_t len = 0U; + + // no hash for 0 values + if (!value) + { + flags &= ~MB_PRINT_FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & MB_PRINT_FLAGS_PRECISION) || value) + { + do + { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & MB_PRINT_FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } while (value && (len < MB_PRINT_NTOA_BUFFER_SIZE)); + } + + return mb_print_itoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +} + +// internal itoa for 'long long' type +#if defined(MB_PRINT_SUPPORT_LONG_LONG) +static size_t mb_print_itoa_long_long(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, unsigned long long value, bool negative, unsigned long long base, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[MB_PRINT_NTOA_BUFFER_SIZE]; + size_t len = 0U; + + // no hash for 0 values + if (!value) + { + flags &= ~MB_PRINT_FLAGS_HASH; + } + + // write if precision != 0 and value is != 0 + if (!(flags & MB_PRINT_FLAGS_PRECISION) || value) + { + do + { + const char digit = (char)(value % base); + buf[len++] = digit < 10 ? '0' + digit : (flags & MB_PRINT_FLAGS_UPPERCASE ? 'A' : 'a') + digit - 10; + value /= base; + } while (value && (len < MB_PRINT_NTOA_BUFFER_SIZE)); + } + + return mb_print_itoa_format(out, buffer, idx, maxlen, buf, len, negative, (unsigned int)base, prec, width, flags); +} +#endif // MB_PRINT_SUPPORT_LONG_LONG + +#if defined(MB_PRINT_SUPPORT_FLOAT) + +#if defined(MB_PRINT_SUPPORT_EXPONENTIAL) +// forward declaration so that mb_print_ftoa can switch to exp notation for values > MB_PRINT_MAX_FLOAT +static size_t mb_print_ftoa_exp(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags); +#endif + +// internal ftoa for fixed decimal floating point +static size_t mb_print_ftoa(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) +{ + char buf[MB_PRINT_FTOA_BUFFER_SIZE]; + size_t len = 0U; + double diff = 0.0; + + // powers of 10 + static const double pow10[] = {1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000}; + + // test for special values + if (value != value) + return mb_print_out_rev(out, buffer, idx, maxlen, "nan", 3, width, flags); + if (value < -DBL_MAX) + return mb_print_out_rev(out, buffer, idx, maxlen, "fni-", 4, width, flags); + if (value > DBL_MAX) + return mb_print_out_rev(out, buffer, idx, maxlen, (flags & MB_PRINT_FLAGS_PLUS) ? "fni+" : "fni", (flags & MB_PRINT_FLAGS_PLUS) ? 4U : 3U, width, flags); + + // test for very large values + // standard printf behavior is to print EVERY whole number digit -- which could be 100s of characters overflowing your buffers == bad + if ((value > MB_PRINT_MAX_FLOAT) || (value < -MB_PRINT_MAX_FLOAT)) + { +#if defined(MB_PRINT_SUPPORT_EXPONENTIAL) + return mb_print_ftoa_exp(out, buffer, idx, maxlen, value, prec, width, flags); +#else + return 0U; +#endif + } + + // test for negative + bool negative = false; + if (value < 0) + { + negative = true; + value = 0 - value; + } + + // set default precision, if not set explicitly + if (!(flags & MB_PRINT_FLAGS_PRECISION)) + { + prec = MB_PRINT_DEFAULT_FLOAT_PRECISION; + } + // limit precision to 9, cause a prec >= 10 can lead to overflow errors + while ((len < MB_PRINT_FTOA_BUFFER_SIZE) && (prec > 9U)) + { + buf[len++] = '0'; + prec--; + } + + int whole = (int)value; + double tmp = (value - whole) * pow10[prec]; + unsigned long frac = (unsigned long)tmp; + diff = tmp - frac; + + if (diff > 0.5) + { + ++frac; + // handle rollover, e.g. case 0.99 with prec 1 is 1.0 + if (frac >= pow10[prec]) + { + frac = 0; + ++whole; + } + } + else if (diff < 0.5) + { + } + else if ((frac == 0U) || (frac & 1U)) + { + // if halfway, round up if odd OR if last digit is 0 + ++frac; + } + + if (prec == 0U) + { + diff = value - (double)whole; + if ((!(diff < 0.5) || (diff > 0.5)) && (whole & 1)) + { + // exactly 0.5 and ODD, then round up + // 1.5 -> 2, but 2.5 -> 2 + ++whole; + } + } + else + { + unsigned int count = prec; + // now do fractional part, as an unsigned number + while (len < MB_PRINT_FTOA_BUFFER_SIZE) + { + --count; + buf[len++] = (char)(48U + (frac % 10U)); + if (!(frac /= 10U)) + { + break; + } + } + // add extra 0s + while ((len < MB_PRINT_FTOA_BUFFER_SIZE) && (count-- > 0U)) + { + buf[len++] = '0'; + } + if (len < MB_PRINT_FTOA_BUFFER_SIZE) + { + // add decimal + buf[len++] = '.'; + } + } + + // do whole part, number is reversed + while (len < MB_PRINT_FTOA_BUFFER_SIZE) + { + buf[len++] = (char)(48 + (whole % 10)); + if (!(whole /= 10)) + { + break; + } + } + + // pad leading zeros + if (!(flags & MB_PRINT_FLAGS_LEFT) && (flags & MB_PRINT_FLAGS_ZEROPAD)) + { + if (width && (negative || (flags & (MB_PRINT_FLAGS_PLUS | MB_PRINT_FLAGS_SPACE)))) + { + width--; + } + while ((len < width) && (len < MB_PRINT_FTOA_BUFFER_SIZE)) + { + buf[len++] = '0'; + } + } + + if (len < MB_PRINT_FTOA_BUFFER_SIZE) + { + if (negative) + { + buf[len++] = '-'; + } + else if (flags & MB_PRINT_FLAGS_PLUS) + { + buf[len++] = '+'; // ignore the space if the '+' exists + } + else if (flags & MB_PRINT_FLAGS_SPACE) + { + buf[len++] = ' '; + } + } + + return mb_print_out_rev(out, buffer, idx, maxlen, buf, len, width, flags); +} + +#if defined(MB_PRINT_SUPPORT_EXPONENTIAL) +// internal ftoa variant for exponential floating-point type, contributed by Martijn Jasperse +static size_t mb_print_ftoa_exp(mb_print_out_fn_type out, char *buffer, size_t idx, size_t maxlen, double value, unsigned int prec, unsigned int width, unsigned int flags) +{ + // check for NaN and special values + if ((value != value) || (value > DBL_MAX) || (value < -DBL_MAX)) + { + return mb_print_ftoa(out, buffer, idx, maxlen, value, prec, width, flags); + } + + // determine the sign + const bool negative = value < 0; + if (negative) + { + value = -value; + } + + // default precision + if (!(flags & MB_PRINT_FLAGS_PRECISION)) + { + prec = MB_PRINT_DEFAULT_FLOAT_PRECISION; + } + + // determine the decimal exponent + // based on the algorithm by David Gay (https://www.ampl.com/netlib/fp/dtoa.c) + union + { + uint64_t U; + double F; + } conv; + + conv.F = value; + int exp2 = (int)((conv.U >> 52U) & 0x07FFU) - 1023; // effectively log2 + conv.U = (conv.U & ((1ULL << 52U) - 1U)) | (1023ULL << 52U); // drop the exponent so conv.F is now in [1,2) + // now approximate log10 from the log2 integer part and an expansion of ln around 1.5 + int expval = (int)(0.1760912590558 + exp2 * 0.301029995663981 + (conv.F - 1.5) * 0.289529654602168); + // now we want to compute 10^expval but we want to be sure it won't overflow + exp2 = (int)(expval * 3.321928094887362 + 0.5); + const double z = expval * 2.302585092994046 - exp2 * 0.6931471805599453; + const double z2 = z * z; + conv.U = (uint64_t)(exp2 + 1023) << 52U; + // compute exp(z) using continued fractions, see https://en.wikipedia.org/wiki/Exponential_function#Continued_fractions_for_ex + conv.F *= 1 + 2 * z / (2 - z + (z2 / (6 + (z2 / (10 + z2 / 14))))); + // correct for rounding errors + if (value < conv.F) + { + expval--; + conv.F /= 10; + } + + // the exponent format is "%+03d" and largest value is "307", so set aside 4-5 characters + unsigned int minwidth = ((expval < 100) && (expval > -100)) ? 4U : 5U; + + // in "%g" mode, "prec" is the number of *significant figures* not decimals + if (flags & MB_PRINT_FLAGS_ADAPT_EXP) + { + // do we want to fall-back to "%f" mode? + if ((value >= 1e-4) && (value < 1e6)) + { + if ((int)prec > expval) + { + prec = (unsigned)((int)prec - expval - 1); + } + else + { + prec = 0; + } + flags |= MB_PRINT_FLAGS_PRECISION; // make sure mb_print_ftoa respects precision + // no characters in exponent + minwidth = 0U; + expval = 0; + } + else + { + // we use one sigfig for the whole part + if ((prec > 0) && (flags & MB_PRINT_FLAGS_PRECISION)) + { + --prec; + } + } + } + + // will everything fit? + unsigned int fwidth = width; + if (width > minwidth) + { + // we didn't fall-back so subtract the characters required for the exponent + fwidth -= minwidth; + } + else + { + // not enough characters, so go back to default sizing + fwidth = 0U; + } + if ((flags & MB_PRINT_FLAGS_LEFT) && minwidth) + { + // if we're padding on the right, DON'T pad the floating part + fwidth = 0U; + } + + // rescale the float value + if (expval) + { + value /= conv.F; + } + + // output the floating part + const size_t start_idx = idx; + idx = mb_print_ftoa(out, buffer, idx, maxlen, negative ? -value : value, prec, fwidth, flags & ~MB_PRINT_FLAGS_ADAPT_EXP); + + // output the exponent part + if (minwidth) + { + // output the exponential symbol + out((flags & MB_PRINT_FLAGS_UPPERCASE) ? 'E' : 'e', buffer, idx++, maxlen); + // output the exponent value + idx = mb_print_itoa_long(out, buffer, idx, maxlen, (expval < 0) ? -expval : expval, expval < 0, 10, 0, minwidth - 1, MB_PRINT_FLAGS_ZEROPAD | MB_PRINT_FLAGS_PLUS); + // might need to right-pad spaces + if (flags & MB_PRINT_FLAGS_LEFT) + { + while (idx - start_idx < width) + out(' ', buffer, idx++, maxlen); + } + } + return idx; +} +#endif // MB_PRINT_SUPPORT_EXPONENTIAL +#endif // MB_PRINT_SUPPORT_FLOAT + +// internal vsnprintf +static int mb_print_vsnprintf_int(mb_print_out_fn_type out, char *buffer, const size_t maxlen, const char *format, va_list va) +{ + unsigned int flags, width, precision, n; + size_t idx = 0U; + + if (!buffer) + { + // use null output function + out = mb_print_out_null; + } + + while (*format) + { + // format specifier? %[flags][width][.precision][length] + if (*format != '%') + { + // no + out(*format, buffer, idx++, maxlen); + format++; + continue; + } + else + { + // yes, evaluate it + format++; + } + + // evaluate flags + flags = 0U; + do + { + switch (*format) + { + case '0': + flags |= MB_PRINT_FLAGS_ZEROPAD; + format++; + n = 1U; + break; + case '-': + flags |= MB_PRINT_FLAGS_LEFT; + format++; + n = 1U; + break; + case '+': + flags |= MB_PRINT_FLAGS_PLUS; + format++; + n = 1U; + break; + case ' ': + flags |= MB_PRINT_FLAGS_SPACE; + format++; + n = 1U; + break; + case '#': + flags |= MB_PRINT_FLAGS_HASH; + format++; + n = 1U; + break; + default: + n = 0U; + break; + } + } while (n); + + // evaluate width field + width = 0U; + if (mb_print_is_digit(*format)) + { + width = mb_print_atoi(&format); + } + else if (*format == '*') + { + const int w = va_arg(va, int); + if (w < 0) + { + flags |= MB_PRINT_FLAGS_LEFT; // reverse padding + width = (unsigned int)-w; + } + else + { + width = (unsigned int)w; + } + format++; + } + + // evaluate precision field + precision = 0U; + if (*format == '.') + { + flags |= MB_PRINT_FLAGS_PRECISION; + format++; + if (mb_print_is_digit(*format)) + { + precision = mb_print_atoi(&format); + } + else if (*format == '*') + { + const int prec = (int)va_arg(va, int); + precision = prec > 0 ? (unsigned int)prec : 0U; + format++; + } + } + + // evaluate length field + switch (*format) + { + case 'l': + flags |= MB_PRINT_FLAGS_LONG; + format++; + if (*format == 'l') + { + flags |= MB_PRINT_FLAGS_LONG_LONG; + format++; + } + break; + case 'h': + flags |= MB_PRINT_FLAGS_SHORT; + format++; + if (*format == 'h') + { + flags |= MB_PRINT_FLAGS_CHAR; + format++; + } + break; +#if defined(MB_PRINT_SUPPORT_PTRDIFF_T) + case 't': + flags |= (sizeof(ptrdiff_t) == sizeof(long) ? MB_PRINT_FLAGS_LONG : MB_PRINT_FLAGS_LONG_LONG); + format++; + break; +#endif + case 'j': + flags |= (sizeof(intmax_t) == sizeof(long) ? MB_PRINT_FLAGS_LONG : MB_PRINT_FLAGS_LONG_LONG); + format++; + break; + case 'z': + flags |= (sizeof(size_t) == sizeof(long) ? MB_PRINT_FLAGS_LONG : MB_PRINT_FLAGS_LONG_LONG); + format++; + break; + default: + break; + } + + // evaluate specifier + switch (*format) + { + case 'd': + case 'i': + case 'u': + case 'x': + case 'X': + case 'o': + case 'b': + { + // set the base + unsigned int base; + if (*format == 'x' || *format == 'X') + { + base = 16U; + } + else if (*format == 'o') + { + base = 8U; + } + else if (*format == 'b') + { + base = 2U; + } + else + { + base = 10U; + flags &= ~MB_PRINT_FLAGS_HASH; // no hash for dec format + } + // uppercase + if (*format == 'X') + { + flags |= MB_PRINT_FLAGS_UPPERCASE; + } + + // no plus or space flag for u, x, X, o, b + if ((*format != 'i') && (*format != 'd')) + { + flags &= ~(MB_PRINT_FLAGS_PLUS | MB_PRINT_FLAGS_SPACE); + } + + // ignore '0' flag when precision is given + if (flags & MB_PRINT_FLAGS_PRECISION) + { + flags &= ~MB_PRINT_FLAGS_ZEROPAD; + } + + // convert the integer + if ((*format == 'i') || (*format == 'd')) + { + // signed + if (flags & MB_PRINT_FLAGS_LONG_LONG) + { +#if defined(MB_PRINT_SUPPORT_LONG_LONG) + const long long value = va_arg(va, long long); + idx = mb_print_itoa_long_long(out, buffer, idx, maxlen, (unsigned long long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); +#endif + } + else if (flags & MB_PRINT_FLAGS_LONG) + { + const long value = va_arg(va, long); + idx = mb_print_itoa_long(out, buffer, idx, maxlen, (unsigned long)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + else + { + const int value = (flags & MB_PRINT_FLAGS_CHAR) ? (char)va_arg(va, int) : (flags & MB_PRINT_FLAGS_SHORT) ? (short int)va_arg(va, int) + : va_arg(va, int); + idx = mb_print_itoa_long(out, buffer, idx, maxlen, (unsigned int)(value > 0 ? value : 0 - value), value < 0, base, precision, width, flags); + } + } + else + { + // unsigned + if (flags & MB_PRINT_FLAGS_LONG_LONG) + { +#if defined(MB_PRINT_SUPPORT_LONG_LONG) + idx = mb_print_itoa_long_long(out, buffer, idx, maxlen, va_arg(va, unsigned long long), false, base, precision, width, flags); +#endif + } + else if (flags & MB_PRINT_FLAGS_LONG) + { + idx = mb_print_itoa_long(out, buffer, idx, maxlen, va_arg(va, unsigned long), false, base, precision, width, flags); + } + else + { + const unsigned int value = (flags & MB_PRINT_FLAGS_CHAR) ? (unsigned char)va_arg(va, unsigned int) : (flags & MB_PRINT_FLAGS_SHORT) ? (unsigned short int)va_arg(va, unsigned int) + : va_arg(va, unsigned int); + idx = mb_print_itoa_long(out, buffer, idx, maxlen, value, false, base, precision, width, flags); + } + } + format++; + break; + } +#if defined(MB_PRINT_SUPPORT_FLOAT) + case 'f': + case 'F': + if (*format == 'F') + flags |= MB_PRINT_FLAGS_UPPERCASE; + idx = mb_print_ftoa(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); + format++; + break; +#if defined(MB_PRINT_SUPPORT_EXPONENTIAL) + case 'e': + case 'E': + case 'g': + case 'G': + if ((*format == 'g') || (*format == 'G')) + flags |= MB_PRINT_FLAGS_ADAPT_EXP; + if ((*format == 'E') || (*format == 'G')) + flags |= MB_PRINT_FLAGS_UPPERCASE; + idx = mb_print_ftoa_exp(out, buffer, idx, maxlen, va_arg(va, double), precision, width, flags); + format++; + break; +#endif // MB_PRINT_SUPPORT_EXPONENTIAL +#endif // MB_PRINT_SUPPORT_FLOAT + case 'c': + { + unsigned int l = 1U; + // pre padding + if (!(flags & MB_PRINT_FLAGS_LEFT)) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + // char output + out((char)va_arg(va, int), buffer, idx++, maxlen); + // post padding + if (flags & MB_PRINT_FLAGS_LEFT) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 's': + { + const char *p = va_arg(va, char *); + unsigned int l = mb_print_strlen(p, precision ? precision : (size_t)-1); + // pre padding + if (flags & MB_PRINT_FLAGS_PRECISION) + { + l = (l < precision ? l : precision); + } + if (!(flags & MB_PRINT_FLAGS_LEFT)) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + // string output + while ((*p != 0) && (!(flags & MB_PRINT_FLAGS_PRECISION) || precision--)) + { + out(*(p++), buffer, idx++, maxlen); + } + // post padding + if (flags & MB_PRINT_FLAGS_LEFT) + { + while (l++ < width) + { + out(' ', buffer, idx++, maxlen); + } + } + format++; + break; + } + + case 'p': + { + width = sizeof(void *) * 2U; + flags |= MB_PRINT_FLAGS_ZEROPAD | MB_PRINT_FLAGS_UPPERCASE; +#if defined(MB_PRINT_SUPPORT_LONG_LONG) + const bool is_ll = sizeof(uintptr_t) == sizeof(long long); + if (is_ll) + { + idx = mb_print_itoa_long_long(out, buffer, idx, maxlen, (uintptr_t)va_arg(va, void *), false, 16U, precision, width, flags); + } + else + { +#endif + idx = mb_print_itoa_long(out, buffer, idx, maxlen, (unsigned long)((uintptr_t)va_arg(va, void *)), false, 16U, precision, width, flags); +#if defined(MB_PRINT_SUPPORT_LONG_LONG) + } +#endif + format++; + break; + } + + case '%': + out('%', buffer, idx++, maxlen); + format++; + break; + + default: + out(*format, buffer, idx++, maxlen); + format++; + break; + } + } + + // termination + out((char)0, buffer, idx < maxlen ? idx : maxlen - 1U, maxlen); + + // return written chars without terminating \0 + return (int)idx; +} + +/////////////////////////////////////////////////////////////////////////////// + +int mb_print_printf(const char *format, ...) +{ + va_list va; + va_start(va, format); + char buffer[1]; + const int ret = mb_print_vsnprintf_int(mb_print_out_char, buffer, (size_t)-1, format, va); + va_end(va); + return ret; +} + +int mb_print_sprintf(char *buffer, const char *format, ...) +{ + va_list va; + va_start(va, format); + const int ret = mb_print_vsnprintf_int(mb_print_out_buffer, buffer, (size_t)-1, format, va); + va_end(va); + return ret; +} + +int mb_print_snprintf_(char *buffer, size_t count, const char *format, ...) +{ + va_list va; + va_start(va, format); + const int ret = mb_print_vsnprintf_int(mb_print_out_buffer, buffer, count, format, va); + va_end(va); + return ret; +} + +int mb_print_vprintf(const char *format, va_list va) +{ + char buffer[1]; + return mb_print_vsnprintf_int(mb_print_out_char, buffer, (size_t)-1, format, va); +} + +int mb_print_vsnprintf_(char *buffer, size_t count, const char *format, va_list va) +{ + return mb_print_vsnprintf_int(mb_print_out_buffer, buffer, count, format, va); +} + +int mb_print_fnprintf(void (*out)(char character, void *arg), void *arg, const char *format, ...) +{ + va_list va; + va_start(va, format); + const mb_print_out_fn_wrap_type out_fct_wrap = {out, arg}; + const int ret = mb_print_vsnprintf_int(mb_print_out_fn, (char *)(uintptr_t)&out_fct_wrap, (size_t)-1, format, va); + va_end(va); + return ret; +} + #endif \ No newline at end of file diff --git a/lib/libesp32/ESP-Mail-Client/src/extras/mb_print/mb_print.h b/lib/libesp32/ESP-Mail-Client/src/extras/mb_print/mb_print.h index 5ec3727bd..79ab67b9f 100644 --- a/lib/libesp32/ESP-Mail-Client/src/extras/mb_print/mb_print.h +++ b/lib/libesp32/ESP-Mail-Client/src/extras/mb_print/mb_print.h @@ -1,108 +1,108 @@ -/////////////////////////////////////////////////////////////////////////////// -// \author (c) Marco Paland (info@paland.com) -// 2014-2019, PALANDesign Hannover, Germany -// -// \license The MIT License (MIT) -// -// 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. -// -// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on -// embedded systems with a very limited resources. -// Use this instead of bloated standard/newlib printf. -// These routines are thread safe and reentrant. -// -/////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#ifndef _PRINTF_H_ -#define _PRINTF_H_ - -#include -#include - -#ifdef __cplusplus -extern "C" -{ -#endif - - /** - * Output a character to a custom device like UART, used by the printf() function - * This function is declared here only. You have to write your custom implementation somewhere - * \param character Character to output - */ - void mb_print_putchar(char character) __attribute__((used)); - - /** - * Tiny printf implementation - * You have to implement _putchar if you use printf() - * To avoid conflicts with the regular printf() API it is overridden by macro defines - * and internal underscore-appended functions like printf_() are used - * \param format A string that specifies the format of the output - * \return The number of characters that are written into the array, not counting the terminating null character - */ - int mb_print_printf(const char *format, ...) __attribute__((used)); - - /** - * Tiny sprintf implementation - * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD! - * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output! - * \param format A string that specifies the format of the output - * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character - */ - int mb_print_sprintf(char *buffer, const char *format, ...) __attribute__((used)); - - /** - * Tiny snprintf/vsnprintf implementation - * \param buffer A pointer to the buffer where to store the formatted string - * \param count The maximum number of characters to store in the buffer, including a terminating null character - * \param format A string that specifies the format of the output - * \param va A value identifying a variable arguments list - * \return The number of characters that COULD have been written into the buffer, not counting the terminating - * null character. A value equal or larger than count indicates truncation. Only when the returned value - * is non-negative and less than count, the string has been completely written. - */ -#define mb_print_snprintf mb_print_snprintf_ -#define mb_print_vsnprintf mb_print_vsnprintf_ - int mb_print_snprintf_(char *buffer, size_t count, const char *format, ...) __attribute__((used)); - int mb_print_vsnprintf_(char *buffer, size_t count, const char *format, va_list va) __attribute__((used)); - - /** - * Tiny vprintf implementation - * \param format A string that specifies the format of the output - * \param va A value identifying a variable arguments list - * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character - */ - int mb_print_vprintf(const char *format, va_list va) __attribute__((used)); - - /** - * printf with output function - * You may use this as dynamic alternative to printf() with its fixed _putchar() output - * \param out An output function which takes one character and an argument pointer - * \param arg An argument pointer for user data passed to output function - * \param format A string that specifies the format of the output - * \return The number of characters that are sent to the output function, not counting the terminating null character - */ - int mb_print_fnprintf(void (*out)(char character, void *arg), void *arg, const char *format, ...) __attribute__((used)); - -#ifdef __cplusplus -} -#endif - +/////////////////////////////////////////////////////////////////////////////// +// \author (c) Marco Paland (info@paland.com) +// 2014-2019, PALANDesign Hannover, Germany +// +// \license The MIT License (MIT) +// +// 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. +// +// \brief Tiny printf, sprintf and snprintf implementation, optimized for speed on +// embedded systems with a very limited resources. +// Use this instead of bloated standard/newlib printf. +// These routines are thread safe and reentrant. +// +/////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#ifndef _PRINTF_H_ +#define _PRINTF_H_ + +#include +#include + +#ifdef __cplusplus +extern "C" +{ +#endif + + /** + * Output a character to a custom device like UART, used by the printf() function + * This function is declared here only. You have to write your custom implementation somewhere + * \param character Character to output + */ + void mb_print_putchar(char character) __attribute__((used)); + + /** + * Tiny printf implementation + * You have to implement _putchar if you use printf() + * To avoid conflicts with the regular printf() API it is overridden by macro defines + * and internal underscore-appended functions like printf_() are used + * \param format A string that specifies the format of the output + * \return The number of characters that are written into the array, not counting the terminating null character + */ + int mb_print_printf(const char *format, ...) __attribute__((used)); + + /** + * Tiny sprintf implementation + * Due to security reasons (buffer overflow) YOU SHOULD CONSIDER USING (V)SNPRINTF INSTEAD! + * \param buffer A pointer to the buffer where to store the formatted string. MUST be big enough to store the output! + * \param format A string that specifies the format of the output + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + */ + int mb_print_sprintf(char *buffer, const char *format, ...) __attribute__((used)); + + /** + * Tiny snprintf/vsnprintf implementation + * \param buffer A pointer to the buffer where to store the formatted string + * \param count The maximum number of characters to store in the buffer, including a terminating null character + * \param format A string that specifies the format of the output + * \param va A value identifying a variable arguments list + * \return The number of characters that COULD have been written into the buffer, not counting the terminating + * null character. A value equal or larger than count indicates truncation. Only when the returned value + * is non-negative and less than count, the string has been completely written. + */ +#define mb_print_snprintf mb_print_snprintf_ +#define mb_print_vsnprintf mb_print_vsnprintf_ + int mb_print_snprintf_(char *buffer, size_t count, const char *format, ...) __attribute__((used)); + int mb_print_vsnprintf_(char *buffer, size_t count, const char *format, va_list va) __attribute__((used)); + + /** + * Tiny vprintf implementation + * \param format A string that specifies the format of the output + * \param va A value identifying a variable arguments list + * \return The number of characters that are WRITTEN into the buffer, not counting the terminating null character + */ + int mb_print_vprintf(const char *format, va_list va) __attribute__((used)); + + /** + * printf with output function + * You may use this as dynamic alternative to printf() with its fixed _putchar() output + * \param out An output function which takes one character and an argument pointer + * \param arg An argument pointer for user data passed to output function + * \param format A string that specifies the format of the output + * \return The number of characters that are sent to the output function, not counting the terminating null character + */ + int mb_print_fnprintf(void (*out)(char character, void *arg), void *arg, const char *format, ...) __attribute__((used)); + +#ifdef __cplusplus +} +#endif + #endif // _PRINTF_H_ \ No newline at end of file diff --git a/lib/libesp32/berry/default/berry.c b/lib/libesp32/berry/default/berry.c index c9fab69fe..694c42849 100644 --- a/lib/libesp32/berry/default/berry.c +++ b/lib/libesp32/berry/default/berry.c @@ -1,424 +1,424 @@ -/******************************************************************** -** Copyright (c) 2018-2020 Guan Wenliang -** This file is part of the Berry default interpreter. -** skiars@qq.com, https://github.com/Skiars/berry -** See Copyright Notice in the LICENSE file or at -** https://github.com/Skiars/berry/blob/master/LICENSE -********************************************************************/ -#ifndef TASMOTA // only when compiling stand-along - -#include "berry.h" -#include "be_repl.h" -#include "be_vm.h" -#include -#include -#include - -#include "be_mapping.h" - -/* using GNU/readline library */ -#if defined(USE_READLINE_LIB) - #include - #include -#endif - -/* detect operating system name */ -#if defined(__linux) - #define OS_NAME "Linux" -#elif defined(__unix) - #define OS_NAME "Unix" -#elif defined(__APPLE__) - #define OS_NAME "Darwin" -#elif defined(_WIN32) - #define OS_NAME "Windows" -#else - #define OS_NAME "Unknown OS" -#endif - -/* detect compiler name and version */ -#if defined(__clang__) - #define COMPILER "clang " __clang_version__ -#elif defined(__GNUC__) - #define COMPILER "GCC " __VERSION__ -#elif defined(_MSC_VER) - #define COMPILER "MSVC" -#elif defined(__CC_ARM) - #define COMPILER "ARMCC" -#elif defined(__ICCARM__) - #define COMPILER "IAR" -#else - #define COMPILER "Unknown Compiler" -#endif - -#if BE_DEBUG -#define FULL_VERSION "Berry " BERRY_VERSION " (debug)" -#else -#define FULL_VERSION "Berry " BERRY_VERSION -#endif - -/* prompt message when REPL is loaded */ -#define repl_prelude \ - FULL_VERSION " (build in " __DATE__ ", " __TIME__ ")\n" \ - "[" COMPILER "] on " OS_NAME " (default)\n" \ - -#if defined(_WIN32) -#define PATH_SEPARATOR ";" -#else -#define PATH_SEPARATOR ":" -#endif - - -/* command help information */ -#define help_information \ - "Usage: berry [options] [script [args]]\n" \ - "Avilable options are:\n" \ - " -i enter interactive mode after executing 'file'\n" \ - " -l all variables in 'file' are parsed as local\n" \ - " -e load 'script' source string and execute\n" \ - " -m custom module search path(s) separated by '" PATH_SEPARATOR "'\n"\ - " -c compile script 'file' to bytecode file\n" \ - " -o save bytecode to 'file'\n" \ - " -g force named globals in VM\n" \ - " -s force Berry compiler in strict mode\n" \ - " -v show version information\n" \ - " -h show help information\n\n" \ - "For more information, please see:\n" \ - " .\n" - -#define array_count(a) (sizeof(a) / sizeof((a)[0])) - -#define arg_i (1 << 0) -#define arg_c (1 << 1) -#define arg_o (1 << 2) -#define arg_l (1 << 3) -#define arg_h (1 << 4) -#define arg_v (1 << 5) -#define arg_e (1 << 6) -#define arg_g (1 << 7) -#define arg_s (1 << 8) -#define arg_err (1 << 9) -#define arg_m (1 << 10) - -struct arg_opts { - int idx; - const char *pattern; - const char *optarg; - const char *errarg; - const char *src; - const char *dst; - const char *modulepath; - const char *execute; -}; - -/* check if the character is a letter */ -static int is_letter(int ch) -{ - return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); -} - -/* matching options - * pattern: pattern string, the set of vaild options - * ch: option character to be matched - * */ -static const char* match_opt(const char *pattern, int ch) -{ - int c = '\0'; - if (pattern) { - while ((c = *pattern) != '\0' && c != ch) { - c = *(++pattern); - while (c != '\0' && !is_letter(c)) { - c = *(++pattern); /* skip characters that are not letters */ - } - } - } - return c == ch ? pattern : NULL; -} - -/* read an option from the arguments - * opt: option match state - * argc: the number of arguments - * argv: the arguments list - * */ -static int arg_getopt(struct arg_opts *opt, int argc, char *argv[]) -{ - if (opt->idx < argc) { - char *arg = argv[opt->idx]; - if (arg[0] == '-' && strlen(arg) == 2) { - const char *res = match_opt(opt->pattern, arg[1]); - /* the '?' indicates an optional argument after the option */ - if (++opt->idx < argc && res != NULL - && res[1] == '?' && *argv[opt->idx] != '-') { - opt->optarg = argv[opt->idx++]; /* save the argument */ - return *res; - } - opt->optarg = NULL; - opt->errarg = arg; - return res != NULL ? *res : '?'; - } - } - return 0; -} - -/* portable readline function package */ -static char* get_line(const char *prompt) -{ -#if defined(USE_READLINE_LIB) - char *line = readline(prompt); - if (line && strlen(line)) { - add_history(line); - } - return line; -#else - static char buffer[1000]; - fputs(prompt, stdout); - fflush(stdout); - if (be_readstring(buffer, sizeof(buffer))) { - buffer[strlen(buffer) - 1] = '\0'; - return buffer; - } - return NULL; -#endif -} - -static void free_line(char *ptr) -{ -#if defined(USE_READLINE_LIB) - free(ptr); -#else - (void)ptr; -#endif -} - -static int handle_result(bvm *vm, int res) -{ - switch (res) { - case BE_OK: /* everything is OK */ - return 0; - case BE_EXCEPTION: /* uncatched exception */ - be_dumpexcept(vm); - return 1; - case BE_EXIT: /* return exit code */ - return be_toindex(vm, -1); - case BE_IO_ERROR: - be_writestring("error: "); - be_writestring(be_tostring(vm, -1)); - be_writenewline(); - return -2; - case BE_MALLOC_FAIL: - be_writestring("error: memory allocation failed.\n"); - return -1; - default: /* unkonw result */ - return 2; - } -} - -/* execute a script source or file and output a result or error */ -static int doscript(bvm *vm, const char *name, int args) -{ - int res = be_loadmode(vm, name, args & arg_l); - if (res == BE_OK) { /* parsing succeeded */ - res = be_pcall(vm, 0); /* execute */ - } - return handle_result(vm, res); -} - -/* load a Berry script string or file and execute - * args: the enabled options mask - * */ -static int load_script(bvm *vm, int argc, char *argv[], int args, const char * script) -{ - int res = 0; - int repl_mode = args & arg_i || (args == 0 && argc == 0); - if (repl_mode) { /* enter the REPL mode after executing the script file */ - be_writestring(repl_prelude); - } - /* compile script file */ - if (script) { - res = be_loadstring(vm, script); - if (res == BE_OK) { /* parsing succeeded */ - res = be_pcall(vm, 0); /* execute */ - } - res = handle_result(vm, res); - } - if (res == BE_OK && argc > 0) { /* check file path or source string argument */ - res = doscript(vm, argv[0], args); - } - if (res == BE_OK && repl_mode) { /* enter the REPL mode */ - res = be_repl(vm, get_line, free_line); - if (res == -BE_MALLOC_FAIL) { - be_writestring("error: memory allocation failed.\n"); - } - } - return res; -} - -/* compile the source code to a bytecode file */ -static int build_file(bvm *vm, const char *dst, const char *src, int args) -{ - int res = be_loadmode(vm, src, args & arg_l); /* compile script file */ - if (res == BE_OK) { - if (!dst) dst = "a.out"; /* the default output file name */ - res = be_savecode(vm, dst); /* save bytecode file */ - } - return handle_result(vm, res); -} - -static int parse_arg(struct arg_opts *opt, int argc, char *argv[]) -{ - int ch, args = 0; - opt->idx = 1; - while ((ch = arg_getopt(opt, argc, argv)) != '\0') { - switch (ch) { - case 'h': args |= arg_h; break; - case 'v': args |= arg_v; break; - case 'i': args |= arg_i; break; - case 'l': args |= arg_l; break; - case 'g': args |= arg_g; break; - case 's': args |= arg_s; break; - case 'e': - args |= arg_e; - opt->execute = opt->optarg; - break; - case 'm': - args |= arg_m; - opt->modulepath = opt->optarg; - break; - case '?': return args | arg_err; - case 'c': - args |= arg_c; - opt->src = opt->optarg; - break; - case 'o': - args |= arg_o; - opt->dst = opt->optarg; - break; - default: - break; - } - } - return args; -} - -static void push_args(bvm *vm, int argc, char *argv[]) -{ - be_newobject(vm, "list"); - while (argc--) { - be_pushstring(vm, *argv++); - be_data_push(vm, -2); - be_pop(vm, 1); - } - be_pop(vm, 1); - be_setglobal(vm, "_argv"); - be_pop(vm, 1); -} - -#if defined(_WIN32) -#define BERRY_ROOT "\\Windows\\system32" -static const char *module_paths[] = { - BERRY_ROOT "\\berry\\packages", -}; -#else -#define BERRY_ROOT "/usr/local" -static const char *module_paths[] = { - BERRY_ROOT "/lib/berry/packages", -}; -#endif - -static void berry_paths(bvm * vm) -{ - size_t i; - for (i = 0; i < array_count(module_paths); ++i) { - be_module_path_set(vm, module_paths[i]); - } -} - -static void berry_custom_paths(bvm *vm, const char *modulepath) -{ - const char delim[] = PATH_SEPARATOR; - char *copy = malloc(strlen(modulepath) + 1); - strcpy(copy, modulepath); - char *ptr = strtok(copy, delim); - - while (ptr != NULL) { - be_module_path_set(vm, ptr); - ptr = strtok(NULL, delim); - } - free(copy); -} - -/* - * command format: berry [options] [script [args]] - * command options: - * -i: enter interactive mode after executing 'script' - * -b: load code from bytecode file - * -e: load 'script' source and execute - * -m: specify custom module search path(s) - * command format: berry options - * command options: - * -v: show version information - * -h: show help information - * command format: berry option file [option file] - * command options: - * -c: compile script file to bytecode file - * -o: set the output file name - * */ -static int analysis_args(bvm *vm, int argc, char *argv[]) -{ - int args = 0; - struct arg_opts opt = { 0 }; - opt.pattern = "m?vhile?gsc?o?"; - args = parse_arg(&opt, argc, argv); - argc -= opt.idx; - argv += opt.idx; - if (args & arg_err) { - be_writestring(be_pushfstring(vm, - "error: missing argument to '%s'\n", opt.errarg)); - be_pop(vm, 1); - return -1; - } - - if (args & arg_m) { - berry_custom_paths(vm, opt.modulepath); - args &= ~arg_m; - } - else { - // use default module paths - berry_paths(vm); - } - - if (args & arg_g) { - comp_set_named_gbl(vm); /* forced named global in VM code */ - args &= ~arg_g; /* clear the flag for this option not to interfere with other options */ - } - if (args & arg_s) { - comp_set_strict(vm); /* compiler in strict mode */ - args &= ~arg_s; - } - if (args & arg_v) { - be_writestring(FULL_VERSION "\n"); - } - if (args & arg_h) { - be_writestring(help_information); - } - push_args(vm, argc, argv); - if (args & (arg_c | arg_o)) { - if (!opt.src && argc > 0) { - opt.src = *argv; - } - return build_file(vm, opt.dst, opt.src, args); - } - return load_script(vm, argc, argv, args, opt.execute); -} - - -int main(int argc, char *argv[]) -{ - int res; - bvm *vm = be_vm_new(); /* create a virtual machine instance */ - be_set_ctype_func_handler(vm, be_call_ctype_func); - res = analysis_args(vm, argc, argv); - be_vm_delete(vm); /* free all objects and vm */ - return res; -} - -#endif // COMPILE_BERRY_LIB +/******************************************************************** +** Copyright (c) 2018-2020 Guan Wenliang +** This file is part of the Berry default interpreter. +** skiars@qq.com, https://github.com/Skiars/berry +** See Copyright Notice in the LICENSE file or at +** https://github.com/Skiars/berry/blob/master/LICENSE +********************************************************************/ +#ifndef TASMOTA // only when compiling stand-along + +#include "berry.h" +#include "be_repl.h" +#include "be_vm.h" +#include +#include +#include + +#include "be_mapping.h" + +/* using GNU/readline library */ +#if defined(USE_READLINE_LIB) + #include + #include +#endif + +/* detect operating system name */ +#if defined(__linux) + #define OS_NAME "Linux" +#elif defined(__unix) + #define OS_NAME "Unix" +#elif defined(__APPLE__) + #define OS_NAME "Darwin" +#elif defined(_WIN32) + #define OS_NAME "Windows" +#else + #define OS_NAME "Unknown OS" +#endif + +/* detect compiler name and version */ +#if defined(__clang__) + #define COMPILER "clang " __clang_version__ +#elif defined(__GNUC__) + #define COMPILER "GCC " __VERSION__ +#elif defined(_MSC_VER) + #define COMPILER "MSVC" +#elif defined(__CC_ARM) + #define COMPILER "ARMCC" +#elif defined(__ICCARM__) + #define COMPILER "IAR" +#else + #define COMPILER "Unknown Compiler" +#endif + +#if BE_DEBUG +#define FULL_VERSION "Berry " BERRY_VERSION " (debug)" +#else +#define FULL_VERSION "Berry " BERRY_VERSION +#endif + +/* prompt message when REPL is loaded */ +#define repl_prelude \ + FULL_VERSION " (build in " __DATE__ ", " __TIME__ ")\n" \ + "[" COMPILER "] on " OS_NAME " (default)\n" \ + +#if defined(_WIN32) +#define PATH_SEPARATOR ";" +#else +#define PATH_SEPARATOR ":" +#endif + + +/* command help information */ +#define help_information \ + "Usage: berry [options] [script [args]]\n" \ + "Avilable options are:\n" \ + " -i enter interactive mode after executing 'file'\n" \ + " -l all variables in 'file' are parsed as local\n" \ + " -e load 'script' source string and execute\n" \ + " -m custom module search path(s) separated by '" PATH_SEPARATOR "'\n"\ + " -c compile script 'file' to bytecode file\n" \ + " -o save bytecode to 'file'\n" \ + " -g force named globals in VM\n" \ + " -s force Berry compiler in strict mode\n" \ + " -v show version information\n" \ + " -h show help information\n\n" \ + "For more information, please see:\n" \ + " .\n" + +#define array_count(a) (sizeof(a) / sizeof((a)[0])) + +#define arg_i (1 << 0) +#define arg_c (1 << 1) +#define arg_o (1 << 2) +#define arg_l (1 << 3) +#define arg_h (1 << 4) +#define arg_v (1 << 5) +#define arg_e (1 << 6) +#define arg_g (1 << 7) +#define arg_s (1 << 8) +#define arg_err (1 << 9) +#define arg_m (1 << 10) + +struct arg_opts { + int idx; + const char *pattern; + const char *optarg; + const char *errarg; + const char *src; + const char *dst; + const char *modulepath; + const char *execute; +}; + +/* check if the character is a letter */ +static int is_letter(int ch) +{ + return (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'); +} + +/* matching options + * pattern: pattern string, the set of vaild options + * ch: option character to be matched + * */ +static const char* match_opt(const char *pattern, int ch) +{ + int c = '\0'; + if (pattern) { + while ((c = *pattern) != '\0' && c != ch) { + c = *(++pattern); + while (c != '\0' && !is_letter(c)) { + c = *(++pattern); /* skip characters that are not letters */ + } + } + } + return c == ch ? pattern : NULL; +} + +/* read an option from the arguments + * opt: option match state + * argc: the number of arguments + * argv: the arguments list + * */ +static int arg_getopt(struct arg_opts *opt, int argc, char *argv[]) +{ + if (opt->idx < argc) { + char *arg = argv[opt->idx]; + if (arg[0] == '-' && strlen(arg) == 2) { + const char *res = match_opt(opt->pattern, arg[1]); + /* the '?' indicates an optional argument after the option */ + if (++opt->idx < argc && res != NULL + && res[1] == '?' && *argv[opt->idx] != '-') { + opt->optarg = argv[opt->idx++]; /* save the argument */ + return *res; + } + opt->optarg = NULL; + opt->errarg = arg; + return res != NULL ? *res : '?'; + } + } + return 0; +} + +/* portable readline function package */ +static char* get_line(const char *prompt) +{ +#if defined(USE_READLINE_LIB) + char *line = readline(prompt); + if (line && strlen(line)) { + add_history(line); + } + return line; +#else + static char buffer[1000]; + fputs(prompt, stdout); + fflush(stdout); + if (be_readstring(buffer, sizeof(buffer))) { + buffer[strlen(buffer) - 1] = '\0'; + return buffer; + } + return NULL; +#endif +} + +static void free_line(char *ptr) +{ +#if defined(USE_READLINE_LIB) + free(ptr); +#else + (void)ptr; +#endif +} + +static int handle_result(bvm *vm, int res) +{ + switch (res) { + case BE_OK: /* everything is OK */ + return 0; + case BE_EXCEPTION: /* uncatched exception */ + be_dumpexcept(vm); + return 1; + case BE_EXIT: /* return exit code */ + return be_toindex(vm, -1); + case BE_IO_ERROR: + be_writestring("error: "); + be_writestring(be_tostring(vm, -1)); + be_writenewline(); + return -2; + case BE_MALLOC_FAIL: + be_writestring("error: memory allocation failed.\n"); + return -1; + default: /* unkonw result */ + return 2; + } +} + +/* execute a script source or file and output a result or error */ +static int doscript(bvm *vm, const char *name, int args) +{ + int res = be_loadmode(vm, name, args & arg_l); + if (res == BE_OK) { /* parsing succeeded */ + res = be_pcall(vm, 0); /* execute */ + } + return handle_result(vm, res); +} + +/* load a Berry script string or file and execute + * args: the enabled options mask + * */ +static int load_script(bvm *vm, int argc, char *argv[], int args, const char * script) +{ + int res = 0; + int repl_mode = args & arg_i || (args == 0 && argc == 0); + if (repl_mode) { /* enter the REPL mode after executing the script file */ + be_writestring(repl_prelude); + } + /* compile script file */ + if (script) { + res = be_loadstring(vm, script); + if (res == BE_OK) { /* parsing succeeded */ + res = be_pcall(vm, 0); /* execute */ + } + res = handle_result(vm, res); + } + if (res == BE_OK && argc > 0) { /* check file path or source string argument */ + res = doscript(vm, argv[0], args); + } + if (res == BE_OK && repl_mode) { /* enter the REPL mode */ + res = be_repl(vm, get_line, free_line); + if (res == -BE_MALLOC_FAIL) { + be_writestring("error: memory allocation failed.\n"); + } + } + return res; +} + +/* compile the source code to a bytecode file */ +static int build_file(bvm *vm, const char *dst, const char *src, int args) +{ + int res = be_loadmode(vm, src, args & arg_l); /* compile script file */ + if (res == BE_OK) { + if (!dst) dst = "a.out"; /* the default output file name */ + res = be_savecode(vm, dst); /* save bytecode file */ + } + return handle_result(vm, res); +} + +static int parse_arg(struct arg_opts *opt, int argc, char *argv[]) +{ + int ch, args = 0; + opt->idx = 1; + while ((ch = arg_getopt(opt, argc, argv)) != '\0') { + switch (ch) { + case 'h': args |= arg_h; break; + case 'v': args |= arg_v; break; + case 'i': args |= arg_i; break; + case 'l': args |= arg_l; break; + case 'g': args |= arg_g; break; + case 's': args |= arg_s; break; + case 'e': + args |= arg_e; + opt->execute = opt->optarg; + break; + case 'm': + args |= arg_m; + opt->modulepath = opt->optarg; + break; + case '?': return args | arg_err; + case 'c': + args |= arg_c; + opt->src = opt->optarg; + break; + case 'o': + args |= arg_o; + opt->dst = opt->optarg; + break; + default: + break; + } + } + return args; +} + +static void push_args(bvm *vm, int argc, char *argv[]) +{ + be_newobject(vm, "list"); + while (argc--) { + be_pushstring(vm, *argv++); + be_data_push(vm, -2); + be_pop(vm, 1); + } + be_pop(vm, 1); + be_setglobal(vm, "_argv"); + be_pop(vm, 1); +} + +#if defined(_WIN32) +#define BERRY_ROOT "\\Windows\\system32" +static const char *module_paths[] = { + BERRY_ROOT "\\berry\\packages", +}; +#else +#define BERRY_ROOT "/usr/local" +static const char *module_paths[] = { + BERRY_ROOT "/lib/berry/packages", +}; +#endif + +static void berry_paths(bvm * vm) +{ + size_t i; + for (i = 0; i < array_count(module_paths); ++i) { + be_module_path_set(vm, module_paths[i]); + } +} + +static void berry_custom_paths(bvm *vm, const char *modulepath) +{ + const char delim[] = PATH_SEPARATOR; + char *copy = malloc(strlen(modulepath) + 1); + strcpy(copy, modulepath); + char *ptr = strtok(copy, delim); + + while (ptr != NULL) { + be_module_path_set(vm, ptr); + ptr = strtok(NULL, delim); + } + free(copy); +} + +/* + * command format: berry [options] [script [args]] + * command options: + * -i: enter interactive mode after executing 'script' + * -b: load code from bytecode file + * -e: load 'script' source and execute + * -m: specify custom module search path(s) + * command format: berry options + * command options: + * -v: show version information + * -h: show help information + * command format: berry option file [option file] + * command options: + * -c: compile script file to bytecode file + * -o: set the output file name + * */ +static int analysis_args(bvm *vm, int argc, char *argv[]) +{ + int args = 0; + struct arg_opts opt = { 0 }; + opt.pattern = "m?vhile?gsc?o?"; + args = parse_arg(&opt, argc, argv); + argc -= opt.idx; + argv += opt.idx; + if (args & arg_err) { + be_writestring(be_pushfstring(vm, + "error: missing argument to '%s'\n", opt.errarg)); + be_pop(vm, 1); + return -1; + } + + if (args & arg_m) { + berry_custom_paths(vm, opt.modulepath); + args &= ~arg_m; + } + else { + // use default module paths + berry_paths(vm); + } + + if (args & arg_g) { + comp_set_named_gbl(vm); /* forced named global in VM code */ + args &= ~arg_g; /* clear the flag for this option not to interfere with other options */ + } + if (args & arg_s) { + comp_set_strict(vm); /* compiler in strict mode */ + args &= ~arg_s; + } + if (args & arg_v) { + be_writestring(FULL_VERSION "\n"); + } + if (args & arg_h) { + be_writestring(help_information); + } + push_args(vm, argc, argv); + if (args & (arg_c | arg_o)) { + if (!opt.src && argc > 0) { + opt.src = *argv; + } + return build_file(vm, opt.dst, opt.src, args); + } + return load_script(vm, argc, argv, args, opt.execute); +} + + +int main(int argc, char *argv[]) +{ + int res; + bvm *vm = be_vm_new(); /* create a virtual machine instance */ + be_set_ctype_func_handler(vm, be_call_ctype_func); + res = analysis_args(vm, argc, argv); + be_vm_delete(vm); /* free all objects and vm */ + return res; +} + +#endif // COMPILE_BERRY_LIB diff --git a/lib/libesp32/berry/tests/relop.be b/lib/libesp32/berry/tests/relop.be index a9a9805f1..8fd856a32 100644 --- a/lib/libesp32/berry/tests/relop.be +++ b/lib/libesp32/berry/tests/relop.be @@ -1,40 +1,40 @@ -def assert_true(status) - assert(status == true, 'assert(true) failed!') -end - -def assert_false(status) - assert(status == false, 'assert(false) failed!') -end - -assert_true(0 == 0) -assert_false(0 != 0) -assert_true(0 != 1) -assert_false(0 == 1) - - -assert_true(0.0 == 0) -assert_false(0.0 != 0) -assert_true(0.0 != 1.0) -assert_false(0.0 == 1.0) - -assert_true(nil == nil) -assert_false(nil != nil) -assert_true(true != nil) -assert_false(true == nil) -assert_true(nil != false) -assert_false(nil == false) - -assert_true(list == list) -assert_false(list == map) - -assert_true([] == []) -assert_true([true] == [true]) -assert_true([[]] == [[]]) -assert_false([[]] != [[]]) -assert_false([0] == []) -assert_false([] != []) -assert_true([] != nil) -assert_false([] == nil) - -assert_true({} != nil) -assert_false({} == nil) +def assert_true(status) + assert(status == true, 'assert(true) failed!') +end + +def assert_false(status) + assert(status == false, 'assert(false) failed!') +end + +assert_true(0 == 0) +assert_false(0 != 0) +assert_true(0 != 1) +assert_false(0 == 1) + + +assert_true(0.0 == 0) +assert_false(0.0 != 0) +assert_true(0.0 != 1.0) +assert_false(0.0 == 1.0) + +assert_true(nil == nil) +assert_false(nil != nil) +assert_true(true != nil) +assert_false(true == nil) +assert_true(nil != false) +assert_false(nil == false) + +assert_true(list == list) +assert_false(list == map) + +assert_true([] == []) +assert_true([true] == [true]) +assert_true([[]] == [[]]) +assert_false([[]] != [[]]) +assert_false([0] == []) +assert_false([] != []) +assert_true([] != nil) +assert_false([] == nil) + +assert_true({} != nil) +assert_false({} == nil) diff --git a/lib/libesp32/berry/tools/grammar/berry.bytecode b/lib/libesp32/berry/tools/grammar/berry.bytecode index 6b90c2a1d..afe8f10c4 100755 --- a/lib/libesp32/berry/tools/grammar/berry.bytecode +++ b/lib/libesp32/berry/tools/grammar/berry.bytecode @@ -1,92 +1,92 @@ -------------------------------------------------------------------------------- --- the Berry's bytecode file structure (version 1) --- --- description --- --- a double dash ('--') start a line comment. --- a: b means that the entity 'a' is realized by the 'b' structure. --- a: b c 'b' and 'c' are arranged in a compact order (one byte alignment). --- [a] means that structure 'a' can be repeated 0 to any times. --- [a](b) means that structure 'a' can be repeated 'b' times. --- a | b means that the entity can be implemented by structure 'a' or 'b'. --- N a number indicates the byte count of the field (eg. 'a: 1'). --- .N means the number of bits in the field (eg. 'a: .1'). --- only the first entity is a file entity (the root). -------------------------------------------------------------------------------- - -bytecode_file: -- little endian - header - global_desc - main_function - -header: 8 - magic_number: 3 -- 0xbecdfe (berry code file) - version: 1 -- 0x03 update with file structure definition - integer_size: .1 - float_size: .1 - -- reserved space - -main_function -> function - -global_desc: - builtin_count: 4 - global_count: 4 -- excluding builtins - global_name -> [ - string - ](global_count) - -function: - information: - function_name: - string - source: - string - argc: 1 -- arguments count - nstack: 1 -- number of stack size by this function - varg: 1 - extra: 1 -- extra data - bytecode: - code_size: 4 - code_array -> [ -- bytecode array - instruction: 4 - ](code_size) - constant_table: - constant_count: 4 - [constant_value](constant_count) - proto_table: - proto_count: 4 - [function](proto_count) - upval_table: - upval_count: 1 - upvals: [ - instack: 1 - index: 1 - ](upval_count) - debug_info: - -- reserved - -constant_value: - type: 1 -- type of value - integer | float | string | class - -string: - string_size: 2 - byte_array: string_size - -class: - class_name: - string - member_count: 4 -- number of member variables - method_count: 4 -- number of method - method_table: [ - string -- method name - function | nil -- method function body or nil (static member) if the first byte is null (which would be an empty func name) - ](method_count) - member_index_table -> [ - string -- member name - ](member_count) - -nil: 1 -boolean: 1 -integer: 4 | 8 -float: 4 | 8 +------------------------------------------------------------------------------- +-- the Berry's bytecode file structure (version 1) +-- +-- description +-- +-- a double dash ('--') start a line comment. +-- a: b means that the entity 'a' is realized by the 'b' structure. +-- a: b c 'b' and 'c' are arranged in a compact order (one byte alignment). +-- [a] means that structure 'a' can be repeated 0 to any times. +-- [a](b) means that structure 'a' can be repeated 'b' times. +-- a | b means that the entity can be implemented by structure 'a' or 'b'. +-- N a number indicates the byte count of the field (eg. 'a: 1'). +-- .N means the number of bits in the field (eg. 'a: .1'). +-- only the first entity is a file entity (the root). +------------------------------------------------------------------------------- + +bytecode_file: -- little endian + header + global_desc + main_function + +header: 8 + magic_number: 3 -- 0xbecdfe (berry code file) + version: 1 -- 0x03 update with file structure definition + integer_size: .1 + float_size: .1 + -- reserved space + +main_function -> function + +global_desc: + builtin_count: 4 + global_count: 4 -- excluding builtins + global_name -> [ + string + ](global_count) + +function: + information: + function_name: + string + source: + string + argc: 1 -- arguments count + nstack: 1 -- number of stack size by this function + varg: 1 + extra: 1 -- extra data + bytecode: + code_size: 4 + code_array -> [ -- bytecode array + instruction: 4 + ](code_size) + constant_table: + constant_count: 4 + [constant_value](constant_count) + proto_table: + proto_count: 4 + [function](proto_count) + upval_table: + upval_count: 1 + upvals: [ + instack: 1 + index: 1 + ](upval_count) + debug_info: + -- reserved + +constant_value: + type: 1 -- type of value + integer | float | string | class + +string: + string_size: 2 + byte_array: string_size + +class: + class_name: + string + member_count: 4 -- number of member variables + method_count: 4 -- number of method + method_table: [ + string -- method name + function | nil -- method function body or nil (static member) if the first byte is null (which would be an empty func name) + ](method_count) + member_index_table -> [ + string -- member name + ](member_count) + +nil: 1 +boolean: 1 +integer: 4 | 8 +float: 4 | 8 diff --git a/lib/libesp32/berry/tools/grammar/const_obj.ebnf b/lib/libesp32/berry/tools/grammar/const_obj.ebnf index 6c38a4262..aede116e6 100755 --- a/lib/libesp32/berry/tools/grammar/const_obj.ebnf +++ b/lib/libesp32/berry/tools/grammar/const_obj.ebnf @@ -1,11 +1,11 @@ -block = type name ['(' {attributes} ')'] '{' {data_fields} '}'; -type = 'map' | 'class' | 'module' | 'vartab'; - -attributes = name ':' name [',']; -data_fields = data_name ',' data_value [':' depend_macro] '\n'; - -(* regular expression *) -name = [_a-zA-Z]\w*; -data_name = [\._a-zA-Z]\w*; -data_value = [\w\()]+; -depend_macro = [_a-zA-Z]\w*; +block = type name ['(' {attributes} ')'] '{' {data_fields} '}'; +type = 'map' | 'class' | 'module' | 'vartab'; + +attributes = name ':' name [',']; +data_fields = data_name ',' data_value [':' depend_macro] '\n'; + +(* regular expression *) +name = [_a-zA-Z]\w*; +data_name = [\._a-zA-Z]\w*; +data_value = [\w\()]+; +depend_macro = [_a-zA-Z]\w*; diff --git a/lib/libesp32/berry/tools/plugins/Notepad++/TasmotaBerry-udl.xml b/lib/libesp32/berry/tools/plugins/Notepad++/TasmotaBerry-udl.xml index c535c6d09..bed93ba9e 100644 --- a/lib/libesp32/berry/tools/plugins/Notepad++/TasmotaBerry-udl.xml +++ b/lib/libesp32/berry/tools/plugins/Notepad++/TasmotaBerry-udl.xml @@ -1,64 +1,64 @@ - - - - - - - - 00# 01 02 03#- 04-# - - 0x - A B C D E F a b c d e f - - - - .. - - ! ~ * / % + - << >> & ^ | .. < <= > >= == != && || ? ( ) { } [ ] . , : = += -= *= /= %= &= |= ^= <<= >>= - - - - - if do while for def - else elif - end - - - - if elif else while for def end class break continue return true false nil var do import as try except raise static - nil boolean integer real string function class instance module list map range global file math bytes persist - assert print input super type classname classof number int real str bool module size compile issubclass is instance call open - file.write file.read file.readbytes file.readline file.seek file.tell file.size file.close list.tostring list.push list.pop list.insert list.item list.setitem list.size list.resize list.clear list.iter list.keys list.concat list.reverse list.copy map.tostring map.insert map.remove map.item map.setitem map.insert map.contains nap.find map.size map.iter map.keys range.tostring range.iter range.lower range.upper range.incr range.setrange string.count string.split string.find string.hex string.byte string.char string.toupper string.tolower string.tr string.replace string.escape string.format math.pi math.nan math.imin math.imax math.floor math.ceil math.abs math.rand math.srand math.isnan math.sqrt math.cos math.tan math.asin math.acos math.atan math.atan2 math.deg math.rad math.sinh math.cosh math.tanh bytes.size bytes.resize bytes.clear bytes.reverse bytes.copy bytes.ismapped bytes.get bytes.geti bytes.set bytes.seti bytes.add bytes.getfloat bytes.setfloat bytes.getbits bytes.setbits bytes.setbytes bytes.tostring bytes.tohex bytes.fromhex bytes.asstring bytes.tob64 bytes.fromb64 global.contains global.id global.setmember json.load json.dump introspect.members introspect.get introspect.set introspect.name introspect.ismethod introspect.module introspect.setmodule introspect.topr os.getcmd os.chdir os.mkdir os.remove os.listdir os.system os.exit os.path.isdir os.path.isfile os.path.exists os.path.split os.path.splitext persist.save persist.find - - - - - 00" 01\ 02" 03' 04\ 05' 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + 00# 01 02 03#- 04-# + + 0x + A B C D E F a b c d e f + + + + .. + - ! ~ * / % + - << >> & ^ | .. < <= > >= == != && || ? ( ) { } [ ] . , : = += -= *= /= %= &= |= ^= <<= >>= + + + + + if do while for def + else elif + end + + + + if elif else while for def end class break continue return true false nil var do import as try except raise static + nil boolean integer real string function class instance module list map range global file math bytes persist + assert print input super type classname classof number int real str bool module size compile issubclass is instance call open + file.write file.read file.readbytes file.readline file.seek file.tell file.size file.close list.tostring list.push list.pop list.insert list.item list.setitem list.size list.resize list.clear list.iter list.keys list.concat list.reverse list.copy map.tostring map.insert map.remove map.item map.setitem map.insert map.contains nap.find map.size map.iter map.keys range.tostring range.iter range.lower range.upper range.incr range.setrange string.count string.split string.find string.hex string.byte string.char string.toupper string.tolower string.tr string.replace string.escape string.format math.pi math.nan math.imin math.imax math.floor math.ceil math.abs math.rand math.srand math.isnan math.sqrt math.cos math.tan math.asin math.acos math.atan math.atan2 math.deg math.rad math.sinh math.cosh math.tanh bytes.size bytes.resize bytes.clear bytes.reverse bytes.copy bytes.ismapped bytes.get bytes.geti bytes.set bytes.seti bytes.add bytes.getfloat bytes.setfloat bytes.getbits bytes.setbits bytes.setbytes bytes.tostring bytes.tohex bytes.fromhex bytes.asstring bytes.tob64 bytes.fromb64 global.contains global.id global.setmember json.load json.dump introspect.members introspect.get introspect.set introspect.name introspect.ismethod introspect.module introspect.setmodule introspect.topr os.getcmd os.chdir os.mkdir os.remove os.listdir os.system os.exit os.path.isdir os.path.isfile os.path.exists os.path.split os.path.splitext persist.save persist.find + + + + + 00" 01\ 02" 03' 04\ 05' 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/lib/libesp32/rtsp/CRtspSession.cpp b/lib/libesp32/rtsp/CRtspSession.cpp index 79e210d1e..075364c58 100755 --- a/lib/libesp32/rtsp/CRtspSession.cpp +++ b/lib/libesp32/rtsp/CRtspSession.cpp @@ -1,420 +1,420 @@ -#include "CRtspSession.h" -#include -#include -#include - -CRtspSession::CRtspSession(SOCKET aRtspClient, CStreamer * aStreamer) : m_RtspClient(aRtspClient),m_Streamer(aStreamer) -{ -// printf("Creating RTSP session\n"); - Init(); - - m_RtspSessionID = getRandom(); // create a session ID - m_RtspSessionID |= 0x80000000; - m_StreamID = -1; - m_ClientRTPPort = 0; - m_ClientRTCPPort = 0; - m_TcpTransport = false; - m_streaming = false; - m_stopped = false; -}; - -CRtspSession::~CRtspSession() -{ - closesocket(m_RtspClient); -}; - -void CRtspSession::Init() -{ - m_RtspCmdType = RTSP_UNKNOWN; - memset(m_URLPreSuffix, 0x00, sizeof(m_URLPreSuffix)); - memset(m_URLSuffix, 0x00, sizeof(m_URLSuffix)); - memset(m_CSeq, 0x00, sizeof(m_CSeq)); - memset(m_URLHostPort, 0x00, sizeof(m_URLHostPort)); - m_ContentLength = 0; -}; - -bool CRtspSession::ParseRtspRequest(char const * aRequest, unsigned aRequestSize) -{ - // char CmdName[RTSP_PARAM_STRING_MAX]; - //char CurRequest[RTSP_BUFFER_SIZE]; // Note: we assume single threaded, this large buf we keep off of the tiny stack - unsigned CurRequestSize; - - Init(); - CurRequestSize = aRequestSize; - memcpy(CurRequest,aRequest,aRequestSize); - - // check whether the request contains information about the RTP/RTCP UDP client ports (SETUP command) - char * ClientPortPtr; - char * TmpPtr; - char CP[128]; //static char CP[1024]; - char * pCP; - int Length; - - - ClientPortPtr = strstr(CurRequest,"client_port"); - if (ClientPortPtr != nullptr) - { - TmpPtr = strstr(ClientPortPtr,"\r\n"); - if (TmpPtr != nullptr) - { - TmpPtr[0] = 0x00; - Length = strlen(ClientPortPtr); - if (Length > 128) - { - Length = 128; - } - strncpy(CP,ClientPortPtr, Length); - pCP = strstr(CP,"="); - if (pCP != nullptr) - { - pCP++; - strcpy(CP,pCP); - pCP = strstr(CP,"-"); - if (pCP != nullptr) - { - pCP[0] = 0x00; - m_ClientRTPPort = atoi(CP); - m_ClientRTCPPort = m_ClientRTPPort + 1; - }; - }; - }; - }; - - // Read everything up to the first space as the command name - bool parseSucceeded = false; - unsigned i; - for (i = 0; i < sizeof(CmdName)-1 && i < CurRequestSize; ++i) - { - char c = CurRequest[i]; - if (c == ' ' || c == '\t') - { - parseSucceeded = true; - break; - } - CmdName[i] = c; - } - CmdName[i] = '\0'; - if (!parseSucceeded) { -// printf("failed to parse RTSP\n"); - return false; - } - -// printf("RTSP received %s\n", CmdName); - - // find out the command type - if (strstr(CmdName,"OPTIONS") != nullptr) m_RtspCmdType = RTSP_OPTIONS; else - if (strstr(CmdName,"DESCRIBE") != nullptr) m_RtspCmdType = RTSP_DESCRIBE; else - if (strstr(CmdName,"SETUP") != nullptr) m_RtspCmdType = RTSP_SETUP; else - if (strstr(CmdName,"PLAY") != nullptr) m_RtspCmdType = RTSP_PLAY; else - if (strstr(CmdName,"TEARDOWN") != nullptr) m_RtspCmdType = RTSP_TEARDOWN; - - // check whether the request contains transport information (UDP or TCP) - if (m_RtspCmdType == RTSP_SETUP) - { - TmpPtr = strstr(CurRequest,"RTP/AVP/TCP"); - if (TmpPtr != nullptr) m_TcpTransport = true; else m_TcpTransport = false; - }; - - // Skip over the prefix of any "rtsp://" or "rtsp:/" URL that follows: - unsigned j = i+1; - while (j < CurRequestSize && (CurRequest[j] == ' ' || CurRequest[j] == '\t')) ++j; // skip over any additional white space - for (; (int)j < (int)(CurRequestSize-8); ++j) - { - if ((CurRequest[j] == 'r' || CurRequest[j] == 'R') && - (CurRequest[j+1] == 't' || CurRequest[j+1] == 'T') && - (CurRequest[j+2] == 's' || CurRequest[j+2] == 'S') && - (CurRequest[j+3] == 'p' || CurRequest[j+3] == 'P') && - CurRequest[j+4] == ':' && CurRequest[j+5] == '/') - { - j += 6; - if (CurRequest[j] == '/') - { // This is a "rtsp://" URL; skip over the host:port part that follows: - ++j; - unsigned uidx = 0; - while (j < CurRequestSize && CurRequest[j] != '/' && CurRequest[j] != ' ' && uidx < sizeof(m_URLHostPort) - 1) - { // extract the host:port part of the URL here - m_URLHostPort[uidx] = CurRequest[j]; - uidx++; - ++j; - }; - } - else --j; - i = j; - break; - } - } - - // Look for the URL suffix (before the following "RTSP/"): - parseSucceeded = false; - for (unsigned k = i+1; (int)k < (int)(CurRequestSize-5); ++k) - { - if (CurRequest[k] == 'R' && CurRequest[k+1] == 'T' && - CurRequest[k+2] == 'S' && CurRequest[k+3] == 'P' && - CurRequest[k+4] == '/') - { - while (--k >= i && CurRequest[k] == ' ') {} - unsigned k1 = k; - while (k1 > i && CurRequest[k1] != '/') --k1; - if (k - k1 + 1 > sizeof(m_URLSuffix)) return false; - unsigned n = 0, k2 = k1+1; - - while (k2 <= k) m_URLSuffix[n++] = CurRequest[k2++]; - m_URLSuffix[n] = '\0'; - - if (k1 - i > sizeof(m_URLPreSuffix)) return false; - n = 0; k2 = i + 1; - while (k2 <= k1 - 1) m_URLPreSuffix[n++] = CurRequest[k2++]; - m_URLPreSuffix[n] = '\0'; - i = k + 7; - parseSucceeded = true; - break; - } - } - if (!parseSucceeded) return false; - - // Look for "CSeq:", skip whitespace, then read everything up to the next \r or \n as 'CSeq': - parseSucceeded = false; - for (j = i; (int)j < (int)(CurRequestSize-5); ++j) - { - if (CurRequest[j] == 'C' && CurRequest[j+1] == 'S' && - CurRequest[j+2] == 'e' && CurRequest[j+3] == 'q' && - CurRequest[j+4] == ':') - { - j += 5; - while (j < CurRequestSize && (CurRequest[j] == ' ' || CurRequest[j] == '\t')) ++j; - unsigned n; - for (n = 0; n < sizeof(m_CSeq)-1 && j < CurRequestSize; ++n,++j) - { - char c = CurRequest[j]; - if (c == '\r' || c == '\n') - { - parseSucceeded = true; - break; - } - m_CSeq[n] = c; - } - m_CSeq[n] = '\0'; - break; - } - } - if (!parseSucceeded) return false; - - // Also: Look for "Content-Length:" (optional) - for (j = i; (int)j < (int)(CurRequestSize-15); ++j) - { - if (CurRequest[j] == 'C' && CurRequest[j+1] == 'o' && - CurRequest[j+2] == 'n' && CurRequest[j+3] == 't' && - CurRequest[j+4] == 'e' && CurRequest[j+5] == 'n' && - CurRequest[j+6] == 't' && CurRequest[j+7] == '-' && - (CurRequest[j+8] == 'L' || CurRequest[j+8] == 'l') && - CurRequest[j+9] == 'e' && CurRequest[j+10] == 'n' && - CurRequest[j+11] == 'g' && CurRequest[j+12] == 't' && - CurRequest[j+13] == 'h' && CurRequest[j+14] == ':') - { - j += 15; - while (j < CurRequestSize && (CurRequest[j] == ' ' || CurRequest[j] == '\t')) ++j; - unsigned num; - if (sscanf(&CurRequest[j], "%u", &num) == 1) m_ContentLength = num; - } - } - return true; -}; - -RTSP_CMD_TYPES CRtspSession::Handle_RtspRequest(char const * aRequest, unsigned aRequestSize) -{ - if (ParseRtspRequest(aRequest,aRequestSize)) - { - switch (m_RtspCmdType) - { - case RTSP_OPTIONS: { Handle_RtspOPTION(); break; }; - case RTSP_DESCRIBE: { Handle_RtspDESCRIBE(); break; }; - case RTSP_SETUP: { Handle_RtspSETUP(); break; }; - case RTSP_PLAY: { Handle_RtspPLAY(); break; }; - default: {}; - }; - }; - return m_RtspCmdType; -}; - -void CRtspSession::Handle_RtspOPTION() -{ - //static char Response[1024]; // Note: we assume single threaded, this large buf we keep off of the tiny stack - - snprintf(Response,sizeof(Response), - "RTSP/1.0 200 OK\r\nCSeq: %s\r\n" - "Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE\r\n\r\n",m_CSeq); - - socketsend(m_RtspClient,Response,strlen(Response)); -} - -void CRtspSession::Handle_RtspDESCRIBE() -{ - //static char Response[1024]; // Note: we assume single threaded, this large buf we keep off of the tiny stack - char SDPBuf[128]; //static char SDPBuf[1024]; - char URLBuf[128]; //static char URLBuf[1024]; - - // check whether we know a stream with the URL which is requested - m_StreamID = -1; // invalid URL - if ((strcmp(m_URLPreSuffix,"mjpeg") == 0) && (strcmp(m_URLSuffix,"1") == 0)) m_StreamID = 0; else - if ((strcmp(m_URLPreSuffix,"mjpeg") == 0) && (strcmp(m_URLSuffix,"2") == 0)) m_StreamID = 1; - if (m_StreamID == -1) - { // Stream not available - snprintf(Response,sizeof(Response), - "RTSP/1.0 404 Stream Not Found\r\nCSeq: %s\r\n%s\r\n", - m_CSeq, - DateHeader()); - - socketsend(m_RtspClient,Response,strlen(Response)); - return; - }; - - // simulate DESCRIBE server response - // static char OBuf[256]; - char * ColonPtr; - strcpy(OBuf,m_URLHostPort); - ColonPtr = strstr(OBuf,":"); - if (ColonPtr != nullptr) ColonPtr[0] = 0x00; - - snprintf(SDPBuf,sizeof(SDPBuf), - "v=0\r\n" - "o=- %d 1 IN IP4 %s\r\n" - "s=\r\n" - "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session - "m=video 0 RTP/AVP 26\r\n" // currently we just handle UDP sessions - // "a=x-dimensions: 640,480\r\n" - "c=IN IP4 0.0.0.0\r\n", - rand(), - OBuf); - char StreamName[64]; - switch (m_StreamID) - { - case 0: strcpy(StreamName,"mjpeg/1"); break; - case 1: strcpy(StreamName,"mjpeg/2"); break; - }; - snprintf(URLBuf,sizeof(URLBuf), - "rtsp://%s/%s", - m_URLHostPort, - StreamName); - snprintf(Response,sizeof(Response), - "RTSP/1.0 200 OK\r\nCSeq: %s\r\n" - "%s\r\n" - "Content-Base: %s/\r\n" - "Content-Type: application/sdp\r\n" - "Content-Length: %d\r\n\r\n" - "%s", - m_CSeq, - DateHeader(), - URLBuf, - (int) strlen(SDPBuf), - SDPBuf); - - socketsend(m_RtspClient,Response,strlen(Response)); -} - -void CRtspSession::Handle_RtspSETUP() -{ - //static char Response[1024]; - //static char Transport[255]; - - // init RTP streamer transport type (UDP or TCP) and ports for UDP transport - m_Streamer->InitTransport(m_ClientRTPPort,m_ClientRTCPPort,m_TcpTransport); - - // simulate SETUP server response - if (m_TcpTransport) - snprintf(Transport,sizeof(Transport),"RTP/AVP/TCP;unicast;interleaved=0-1"); - else - snprintf(Transport,sizeof(Transport), - "RTP/AVP;unicast;destination=127.0.0.1;source=127.0.0.1;client_port=%i-%i;server_port=%i-%i", - m_ClientRTPPort, - m_ClientRTCPPort, - m_Streamer->GetRtpServerPort(), - m_Streamer->GetRtcpServerPort()); - snprintf(Response,sizeof(Response), - "RTSP/1.0 200 OK\r\nCSeq: %s\r\n" - "%s\r\n" - "Transport: %s\r\n" - "Session: %i\r\n\r\n", - m_CSeq, - DateHeader(), - Transport, - m_RtspSessionID); - - socketsend(m_RtspClient,Response,strlen(Response)); -} - -void CRtspSession::Handle_RtspPLAY() -{ - //static char Response[1024]; - - // simulate SETUP server response - snprintf(Response,sizeof(Response), - "RTSP/1.0 200 OK\r\nCSeq: %s\r\n" - "%s\r\n" - "Range: npt=0.000-\r\n" - "Session: %i\r\n" - "RTP-Info: url=rtsp://127.0.0.1:8554/mjpeg/1/track1\r\n\r\n", - m_CSeq, - DateHeader(), - m_RtspSessionID); - - socketsend(m_RtspClient,Response,strlen(Response)); -} - -char const * CRtspSession::DateHeader() -{ - //static char buf[200]; - time_t tt = time(NULL); - strftime(session_buf, sizeof(session_buf), "Date: %a, %b %d %Y %H:%M:%S GMT", gmtime(&tt)); - return session_buf; -} - -int CRtspSession::GetStreamID() -{ - return m_StreamID; -}; - - - -/** - Read from our socket, parsing commands as possible. - */ -bool CRtspSession::handleRequests(uint32_t readTimeoutMs) -{ - if(m_stopped) - return false; // Already closed down - - //char RecvBuf[RTSP_BUFFER_SIZE]; // Note: we assume single threaded, this large buf we keep off of the tiny stack - - memset(RecvBuf,0x00,sizeof(RecvBuf)); - int res = socketread(m_RtspClient,RecvBuf,sizeof(RecvBuf), readTimeoutMs); - if(res > 0) { - // we filter away everything which seems not to be an RTSP command: O-ption, D-escribe, S-etup, P-lay, T-eardown - if ((RecvBuf[0] == 'O') || (RecvBuf[0] == 'D') || (RecvBuf[0] == 'S') || (RecvBuf[0] == 'P') || (RecvBuf[0] == 'T')) - { - RTSP_CMD_TYPES C = Handle_RtspRequest(RecvBuf,res); - if (C == RTSP_PLAY) - m_streaming = true; - else if (C == RTSP_TEARDOWN) - m_stopped = true; - } - return true; - } - else if(res == 0) { -// printf("client closed socket, exiting\n"); - m_stopped = true; - return true; - } - else { - // Timeout on read - - return false; - } -} - -void CRtspSession::broadcastCurrentFrame(uint32_t curMsec) { - // Send a frame - if (m_streaming && !m_stopped) { - // printf("serving a frame\n"); - m_Streamer->streamImage(curMsec); - } -} +#include "CRtspSession.h" +#include +#include +#include + +CRtspSession::CRtspSession(SOCKET aRtspClient, CStreamer * aStreamer) : m_RtspClient(aRtspClient),m_Streamer(aStreamer) +{ +// printf("Creating RTSP session\n"); + Init(); + + m_RtspSessionID = getRandom(); // create a session ID + m_RtspSessionID |= 0x80000000; + m_StreamID = -1; + m_ClientRTPPort = 0; + m_ClientRTCPPort = 0; + m_TcpTransport = false; + m_streaming = false; + m_stopped = false; +}; + +CRtspSession::~CRtspSession() +{ + closesocket(m_RtspClient); +}; + +void CRtspSession::Init() +{ + m_RtspCmdType = RTSP_UNKNOWN; + memset(m_URLPreSuffix, 0x00, sizeof(m_URLPreSuffix)); + memset(m_URLSuffix, 0x00, sizeof(m_URLSuffix)); + memset(m_CSeq, 0x00, sizeof(m_CSeq)); + memset(m_URLHostPort, 0x00, sizeof(m_URLHostPort)); + m_ContentLength = 0; +}; + +bool CRtspSession::ParseRtspRequest(char const * aRequest, unsigned aRequestSize) +{ + // char CmdName[RTSP_PARAM_STRING_MAX]; + //char CurRequest[RTSP_BUFFER_SIZE]; // Note: we assume single threaded, this large buf we keep off of the tiny stack + unsigned CurRequestSize; + + Init(); + CurRequestSize = aRequestSize; + memcpy(CurRequest,aRequest,aRequestSize); + + // check whether the request contains information about the RTP/RTCP UDP client ports (SETUP command) + char * ClientPortPtr; + char * TmpPtr; + char CP[128]; //static char CP[1024]; + char * pCP; + int Length; + + + ClientPortPtr = strstr(CurRequest,"client_port"); + if (ClientPortPtr != nullptr) + { + TmpPtr = strstr(ClientPortPtr,"\r\n"); + if (TmpPtr != nullptr) + { + TmpPtr[0] = 0x00; + Length = strlen(ClientPortPtr); + if (Length > 128) + { + Length = 128; + } + strncpy(CP,ClientPortPtr, Length); + pCP = strstr(CP,"="); + if (pCP != nullptr) + { + pCP++; + strcpy(CP,pCP); + pCP = strstr(CP,"-"); + if (pCP != nullptr) + { + pCP[0] = 0x00; + m_ClientRTPPort = atoi(CP); + m_ClientRTCPPort = m_ClientRTPPort + 1; + }; + }; + }; + }; + + // Read everything up to the first space as the command name + bool parseSucceeded = false; + unsigned i; + for (i = 0; i < sizeof(CmdName)-1 && i < CurRequestSize; ++i) + { + char c = CurRequest[i]; + if (c == ' ' || c == '\t') + { + parseSucceeded = true; + break; + } + CmdName[i] = c; + } + CmdName[i] = '\0'; + if (!parseSucceeded) { +// printf("failed to parse RTSP\n"); + return false; + } + +// printf("RTSP received %s\n", CmdName); + + // find out the command type + if (strstr(CmdName,"OPTIONS") != nullptr) m_RtspCmdType = RTSP_OPTIONS; else + if (strstr(CmdName,"DESCRIBE") != nullptr) m_RtspCmdType = RTSP_DESCRIBE; else + if (strstr(CmdName,"SETUP") != nullptr) m_RtspCmdType = RTSP_SETUP; else + if (strstr(CmdName,"PLAY") != nullptr) m_RtspCmdType = RTSP_PLAY; else + if (strstr(CmdName,"TEARDOWN") != nullptr) m_RtspCmdType = RTSP_TEARDOWN; + + // check whether the request contains transport information (UDP or TCP) + if (m_RtspCmdType == RTSP_SETUP) + { + TmpPtr = strstr(CurRequest,"RTP/AVP/TCP"); + if (TmpPtr != nullptr) m_TcpTransport = true; else m_TcpTransport = false; + }; + + // Skip over the prefix of any "rtsp://" or "rtsp:/" URL that follows: + unsigned j = i+1; + while (j < CurRequestSize && (CurRequest[j] == ' ' || CurRequest[j] == '\t')) ++j; // skip over any additional white space + for (; (int)j < (int)(CurRequestSize-8); ++j) + { + if ((CurRequest[j] == 'r' || CurRequest[j] == 'R') && + (CurRequest[j+1] == 't' || CurRequest[j+1] == 'T') && + (CurRequest[j+2] == 's' || CurRequest[j+2] == 'S') && + (CurRequest[j+3] == 'p' || CurRequest[j+3] == 'P') && + CurRequest[j+4] == ':' && CurRequest[j+5] == '/') + { + j += 6; + if (CurRequest[j] == '/') + { // This is a "rtsp://" URL; skip over the host:port part that follows: + ++j; + unsigned uidx = 0; + while (j < CurRequestSize && CurRequest[j] != '/' && CurRequest[j] != ' ' && uidx < sizeof(m_URLHostPort) - 1) + { // extract the host:port part of the URL here + m_URLHostPort[uidx] = CurRequest[j]; + uidx++; + ++j; + }; + } + else --j; + i = j; + break; + } + } + + // Look for the URL suffix (before the following "RTSP/"): + parseSucceeded = false; + for (unsigned k = i+1; (int)k < (int)(CurRequestSize-5); ++k) + { + if (CurRequest[k] == 'R' && CurRequest[k+1] == 'T' && + CurRequest[k+2] == 'S' && CurRequest[k+3] == 'P' && + CurRequest[k+4] == '/') + { + while (--k >= i && CurRequest[k] == ' ') {} + unsigned k1 = k; + while (k1 > i && CurRequest[k1] != '/') --k1; + if (k - k1 + 1 > sizeof(m_URLSuffix)) return false; + unsigned n = 0, k2 = k1+1; + + while (k2 <= k) m_URLSuffix[n++] = CurRequest[k2++]; + m_URLSuffix[n] = '\0'; + + if (k1 - i > sizeof(m_URLPreSuffix)) return false; + n = 0; k2 = i + 1; + while (k2 <= k1 - 1) m_URLPreSuffix[n++] = CurRequest[k2++]; + m_URLPreSuffix[n] = '\0'; + i = k + 7; + parseSucceeded = true; + break; + } + } + if (!parseSucceeded) return false; + + // Look for "CSeq:", skip whitespace, then read everything up to the next \r or \n as 'CSeq': + parseSucceeded = false; + for (j = i; (int)j < (int)(CurRequestSize-5); ++j) + { + if (CurRequest[j] == 'C' && CurRequest[j+1] == 'S' && + CurRequest[j+2] == 'e' && CurRequest[j+3] == 'q' && + CurRequest[j+4] == ':') + { + j += 5; + while (j < CurRequestSize && (CurRequest[j] == ' ' || CurRequest[j] == '\t')) ++j; + unsigned n; + for (n = 0; n < sizeof(m_CSeq)-1 && j < CurRequestSize; ++n,++j) + { + char c = CurRequest[j]; + if (c == '\r' || c == '\n') + { + parseSucceeded = true; + break; + } + m_CSeq[n] = c; + } + m_CSeq[n] = '\0'; + break; + } + } + if (!parseSucceeded) return false; + + // Also: Look for "Content-Length:" (optional) + for (j = i; (int)j < (int)(CurRequestSize-15); ++j) + { + if (CurRequest[j] == 'C' && CurRequest[j+1] == 'o' && + CurRequest[j+2] == 'n' && CurRequest[j+3] == 't' && + CurRequest[j+4] == 'e' && CurRequest[j+5] == 'n' && + CurRequest[j+6] == 't' && CurRequest[j+7] == '-' && + (CurRequest[j+8] == 'L' || CurRequest[j+8] == 'l') && + CurRequest[j+9] == 'e' && CurRequest[j+10] == 'n' && + CurRequest[j+11] == 'g' && CurRequest[j+12] == 't' && + CurRequest[j+13] == 'h' && CurRequest[j+14] == ':') + { + j += 15; + while (j < CurRequestSize && (CurRequest[j] == ' ' || CurRequest[j] == '\t')) ++j; + unsigned num; + if (sscanf(&CurRequest[j], "%u", &num) == 1) m_ContentLength = num; + } + } + return true; +}; + +RTSP_CMD_TYPES CRtspSession::Handle_RtspRequest(char const * aRequest, unsigned aRequestSize) +{ + if (ParseRtspRequest(aRequest,aRequestSize)) + { + switch (m_RtspCmdType) + { + case RTSP_OPTIONS: { Handle_RtspOPTION(); break; }; + case RTSP_DESCRIBE: { Handle_RtspDESCRIBE(); break; }; + case RTSP_SETUP: { Handle_RtspSETUP(); break; }; + case RTSP_PLAY: { Handle_RtspPLAY(); break; }; + default: {}; + }; + }; + return m_RtspCmdType; +}; + +void CRtspSession::Handle_RtspOPTION() +{ + //static char Response[1024]; // Note: we assume single threaded, this large buf we keep off of the tiny stack + + snprintf(Response,sizeof(Response), + "RTSP/1.0 200 OK\r\nCSeq: %s\r\n" + "Public: DESCRIBE, SETUP, TEARDOWN, PLAY, PAUSE\r\n\r\n",m_CSeq); + + socketsend(m_RtspClient,Response,strlen(Response)); +} + +void CRtspSession::Handle_RtspDESCRIBE() +{ + //static char Response[1024]; // Note: we assume single threaded, this large buf we keep off of the tiny stack + char SDPBuf[128]; //static char SDPBuf[1024]; + char URLBuf[128]; //static char URLBuf[1024]; + + // check whether we know a stream with the URL which is requested + m_StreamID = -1; // invalid URL + if ((strcmp(m_URLPreSuffix,"mjpeg") == 0) && (strcmp(m_URLSuffix,"1") == 0)) m_StreamID = 0; else + if ((strcmp(m_URLPreSuffix,"mjpeg") == 0) && (strcmp(m_URLSuffix,"2") == 0)) m_StreamID = 1; + if (m_StreamID == -1) + { // Stream not available + snprintf(Response,sizeof(Response), + "RTSP/1.0 404 Stream Not Found\r\nCSeq: %s\r\n%s\r\n", + m_CSeq, + DateHeader()); + + socketsend(m_RtspClient,Response,strlen(Response)); + return; + }; + + // simulate DESCRIBE server response + // static char OBuf[256]; + char * ColonPtr; + strcpy(OBuf,m_URLHostPort); + ColonPtr = strstr(OBuf,":"); + if (ColonPtr != nullptr) ColonPtr[0] = 0x00; + + snprintf(SDPBuf,sizeof(SDPBuf), + "v=0\r\n" + "o=- %d 1 IN IP4 %s\r\n" + "s=\r\n" + "t=0 0\r\n" // start / stop - 0 -> unbounded and permanent session + "m=video 0 RTP/AVP 26\r\n" // currently we just handle UDP sessions + // "a=x-dimensions: 640,480\r\n" + "c=IN IP4 0.0.0.0\r\n", + rand(), + OBuf); + char StreamName[64]; + switch (m_StreamID) + { + case 0: strcpy(StreamName,"mjpeg/1"); break; + case 1: strcpy(StreamName,"mjpeg/2"); break; + }; + snprintf(URLBuf,sizeof(URLBuf), + "rtsp://%s/%s", + m_URLHostPort, + StreamName); + snprintf(Response,sizeof(Response), + "RTSP/1.0 200 OK\r\nCSeq: %s\r\n" + "%s\r\n" + "Content-Base: %s/\r\n" + "Content-Type: application/sdp\r\n" + "Content-Length: %d\r\n\r\n" + "%s", + m_CSeq, + DateHeader(), + URLBuf, + (int) strlen(SDPBuf), + SDPBuf); + + socketsend(m_RtspClient,Response,strlen(Response)); +} + +void CRtspSession::Handle_RtspSETUP() +{ + //static char Response[1024]; + //static char Transport[255]; + + // init RTP streamer transport type (UDP or TCP) and ports for UDP transport + m_Streamer->InitTransport(m_ClientRTPPort,m_ClientRTCPPort,m_TcpTransport); + + // simulate SETUP server response + if (m_TcpTransport) + snprintf(Transport,sizeof(Transport),"RTP/AVP/TCP;unicast;interleaved=0-1"); + else + snprintf(Transport,sizeof(Transport), + "RTP/AVP;unicast;destination=127.0.0.1;source=127.0.0.1;client_port=%i-%i;server_port=%i-%i", + m_ClientRTPPort, + m_ClientRTCPPort, + m_Streamer->GetRtpServerPort(), + m_Streamer->GetRtcpServerPort()); + snprintf(Response,sizeof(Response), + "RTSP/1.0 200 OK\r\nCSeq: %s\r\n" + "%s\r\n" + "Transport: %s\r\n" + "Session: %i\r\n\r\n", + m_CSeq, + DateHeader(), + Transport, + m_RtspSessionID); + + socketsend(m_RtspClient,Response,strlen(Response)); +} + +void CRtspSession::Handle_RtspPLAY() +{ + //static char Response[1024]; + + // simulate SETUP server response + snprintf(Response,sizeof(Response), + "RTSP/1.0 200 OK\r\nCSeq: %s\r\n" + "%s\r\n" + "Range: npt=0.000-\r\n" + "Session: %i\r\n" + "RTP-Info: url=rtsp://127.0.0.1:8554/mjpeg/1/track1\r\n\r\n", + m_CSeq, + DateHeader(), + m_RtspSessionID); + + socketsend(m_RtspClient,Response,strlen(Response)); +} + +char const * CRtspSession::DateHeader() +{ + //static char buf[200]; + time_t tt = time(NULL); + strftime(session_buf, sizeof(session_buf), "Date: %a, %b %d %Y %H:%M:%S GMT", gmtime(&tt)); + return session_buf; +} + +int CRtspSession::GetStreamID() +{ + return m_StreamID; +}; + + + +/** + Read from our socket, parsing commands as possible. + */ +bool CRtspSession::handleRequests(uint32_t readTimeoutMs) +{ + if(m_stopped) + return false; // Already closed down + + //char RecvBuf[RTSP_BUFFER_SIZE]; // Note: we assume single threaded, this large buf we keep off of the tiny stack + + memset(RecvBuf,0x00,sizeof(RecvBuf)); + int res = socketread(m_RtspClient,RecvBuf,sizeof(RecvBuf), readTimeoutMs); + if(res > 0) { + // we filter away everything which seems not to be an RTSP command: O-ption, D-escribe, S-etup, P-lay, T-eardown + if ((RecvBuf[0] == 'O') || (RecvBuf[0] == 'D') || (RecvBuf[0] == 'S') || (RecvBuf[0] == 'P') || (RecvBuf[0] == 'T')) + { + RTSP_CMD_TYPES C = Handle_RtspRequest(RecvBuf,res); + if (C == RTSP_PLAY) + m_streaming = true; + else if (C == RTSP_TEARDOWN) + m_stopped = true; + } + return true; + } + else if(res == 0) { +// printf("client closed socket, exiting\n"); + m_stopped = true; + return true; + } + else { + // Timeout on read + + return false; + } +} + +void CRtspSession::broadcastCurrentFrame(uint32_t curMsec) { + // Send a frame + if (m_streaming && !m_stopped) { + // printf("serving a frame\n"); + m_Streamer->streamImage(curMsec); + } +} diff --git a/lib/libesp32/rtsp/CRtspSession.h b/lib/libesp32/rtsp/CRtspSession.h index 79700bd60..949a15293 100755 --- a/lib/libesp32/rtsp/CRtspSession.h +++ b/lib/libesp32/rtsp/CRtspSession.h @@ -1,80 +1,80 @@ -#pragma once - -#include "CStreamer.h" -#include "platglue.h" - -// supported command types -enum RTSP_CMD_TYPES -{ - RTSP_OPTIONS, - RTSP_DESCRIBE, - RTSP_SETUP, - RTSP_PLAY, - RTSP_TEARDOWN, - RTSP_UNKNOWN -}; - -#define RTSP_BUFFER_SIZE 10000 // for incoming requests, and outgoing responses -#define RTSP_PARAM_STRING_MAX 200 -#define MAX_HOSTNAME_LEN 256 - -class CRtspSession -{ -public: - CRtspSession(SOCKET aRtspClient, CStreamer * aStreamer); - ~CRtspSession(); - - RTSP_CMD_TYPES Handle_RtspRequest(char const * aRequest, unsigned aRequestSize); - int GetStreamID(); - - /** - Read from our socket, parsing commands as possible. - - return false if the read timed out - */ - bool handleRequests(uint32_t readTimeoutMs); - - /** - broadcast a current frame - */ - void broadcastCurrentFrame(uint32_t curMsec); - - bool m_streaming; - bool m_stopped; - -private: - void Init(); - bool ParseRtspRequest(char const * aRequest, unsigned aRequestSize); - char const * DateHeader(); - - // RTSP request command handlers - void Handle_RtspOPTION(); - void Handle_RtspDESCRIBE(); - void Handle_RtspSETUP(); - void Handle_RtspPLAY(); - - // global session state parameters - int m_RtspSessionID; - SOCKET m_RtspClient; // RTSP socket of that session - int m_StreamID; // number of simulated stream of that session - IPPORT m_ClientRTPPort; // client port for UDP based RTP transport - IPPORT m_ClientRTCPPort; // client port for UDP based RTCP transport - bool m_TcpTransport; // if Tcp based streaming was activated - CStreamer * m_Streamer; // the UDP or TCP streamer of that session - - // parameters of the last received RTSP request - - RTSP_CMD_TYPES m_RtspCmdType; // command type (if any) of the current request - char m_URLPreSuffix[RTSP_PARAM_STRING_MAX]; // stream name pre suffix - char m_URLSuffix[RTSP_PARAM_STRING_MAX]; // stream name suffix - char m_CSeq[RTSP_PARAM_STRING_MAX]; // RTSP command sequence number - char m_URLHostPort[MAX_HOSTNAME_LEN]; // host:port part of the URL - unsigned m_ContentLength; // SDP string size - char CurRequest[RTSP_BUFFER_SIZE]; - char RecvBuf[RTSP_BUFFER_SIZE]; - char session_buf[128]; - char CmdName[RTSP_PARAM_STRING_MAX]; - char Transport[255]; - char Response[1024]; - char OBuf[256]; -}; +#pragma once + +#include "CStreamer.h" +#include "platglue.h" + +// supported command types +enum RTSP_CMD_TYPES +{ + RTSP_OPTIONS, + RTSP_DESCRIBE, + RTSP_SETUP, + RTSP_PLAY, + RTSP_TEARDOWN, + RTSP_UNKNOWN +}; + +#define RTSP_BUFFER_SIZE 10000 // for incoming requests, and outgoing responses +#define RTSP_PARAM_STRING_MAX 200 +#define MAX_HOSTNAME_LEN 256 + +class CRtspSession +{ +public: + CRtspSession(SOCKET aRtspClient, CStreamer * aStreamer); + ~CRtspSession(); + + RTSP_CMD_TYPES Handle_RtspRequest(char const * aRequest, unsigned aRequestSize); + int GetStreamID(); + + /** + Read from our socket, parsing commands as possible. + + return false if the read timed out + */ + bool handleRequests(uint32_t readTimeoutMs); + + /** + broadcast a current frame + */ + void broadcastCurrentFrame(uint32_t curMsec); + + bool m_streaming; + bool m_stopped; + +private: + void Init(); + bool ParseRtspRequest(char const * aRequest, unsigned aRequestSize); + char const * DateHeader(); + + // RTSP request command handlers + void Handle_RtspOPTION(); + void Handle_RtspDESCRIBE(); + void Handle_RtspSETUP(); + void Handle_RtspPLAY(); + + // global session state parameters + int m_RtspSessionID; + SOCKET m_RtspClient; // RTSP socket of that session + int m_StreamID; // number of simulated stream of that session + IPPORT m_ClientRTPPort; // client port for UDP based RTP transport + IPPORT m_ClientRTCPPort; // client port for UDP based RTCP transport + bool m_TcpTransport; // if Tcp based streaming was activated + CStreamer * m_Streamer; // the UDP or TCP streamer of that session + + // parameters of the last received RTSP request + + RTSP_CMD_TYPES m_RtspCmdType; // command type (if any) of the current request + char m_URLPreSuffix[RTSP_PARAM_STRING_MAX]; // stream name pre suffix + char m_URLSuffix[RTSP_PARAM_STRING_MAX]; // stream name suffix + char m_CSeq[RTSP_PARAM_STRING_MAX]; // RTSP command sequence number + char m_URLHostPort[MAX_HOSTNAME_LEN]; // host:port part of the URL + unsigned m_ContentLength; // SDP string size + char CurRequest[RTSP_BUFFER_SIZE]; + char RecvBuf[RTSP_BUFFER_SIZE]; + char session_buf[128]; + char CmdName[RTSP_PARAM_STRING_MAX]; + char Transport[255]; + char Response[1024]; + char OBuf[256]; +}; diff --git a/lib/libesp32/rtsp/CStreamer.cpp b/lib/libesp32/rtsp/CStreamer.cpp index a9f638de9..d730926a7 100755 --- a/lib/libesp32/rtsp/CStreamer.cpp +++ b/lib/libesp32/rtsp/CStreamer.cpp @@ -1,350 +1,350 @@ -#include "CStreamer.h" - -#include - -//#define STREAM_DEBUG - -CStreamer::CStreamer(SOCKET aClient, u_short width, u_short height) : m_Client(aClient) -{ -// printf("Creating TSP streamer\n"); - m_RtpServerPort = 0; - m_RtcpServerPort = 0; - m_RtpClientPort = 0; - m_RtcpClientPort = 0; - - m_SequenceNumber = 0; - m_Timestamp = 0; - m_SendIdx = 0; - m_TCPTransport = false; - - m_RtpSocket = NULLSOCKET; - m_RtcpSocket = NULLSOCKET; - - m_width = width; - m_height = height; - m_prevMsec = 0; -}; - -CStreamer::~CStreamer() -{ - udpsocketclose(m_RtpSocket); - udpsocketclose(m_RtcpSocket); -}; - -int CStreamer::SendRtpPacket(unsigned const char * jpeg, int jpegLen, int fragmentOffset, BufPtr quant0tbl, BufPtr quant1tbl) -{ -#define KRtpHeaderSize 12 // size of the RTP header -#define KJpegHeaderSize 8 // size of the special JPEG payload header - -#define MAX_FRAGMENT_SIZE 1100 // FIXME, pick more carefully - int fragmentLen = MAX_FRAGMENT_SIZE; - if(fragmentLen + fragmentOffset > jpegLen) // Shrink last fragment if needed - fragmentLen = jpegLen - fragmentOffset; - - bool isLastFragment = (fragmentOffset + fragmentLen) == jpegLen; - - // Do we have custom quant tables? If so include them per RFC - - bool includeQuantTbl = quant0tbl && quant1tbl && fragmentOffset == 0; - uint8_t q = includeQuantTbl ? 128 : 0x5e; - - //static char RtpBuf[2048]; // Note: we assume single threaded, this large buf we keep off of the tiny stack - int RtpPacketSize = fragmentLen + KRtpHeaderSize + KJpegHeaderSize + (includeQuantTbl ? (4 + 64 * 2) : 0); - - memset(RtpBuf,0x00,sizeof(RtpBuf)); - // Prepare the first 4 byte of the packet. This is the Rtp over Rtsp header in case of TCP based transport - RtpBuf[0] = '$'; // magic number - RtpBuf[1] = 0; // number of multiplexed subchannel on RTPS connection - here the RTP channel - RtpBuf[2] = (RtpPacketSize & 0x0000FF00) >> 8; - RtpBuf[3] = (RtpPacketSize & 0x000000FF); - // Prepare the 12 byte RTP header - RtpBuf[4] = 0x80; // RTP version - RtpBuf[5] = 0x1a | (isLastFragment ? 0x80 : 0x00); // JPEG payload (26) and marker bit - RtpBuf[7] = m_SequenceNumber & 0x0FF; // each packet is counted with a sequence counter - RtpBuf[6] = m_SequenceNumber >> 8; - RtpBuf[8] = (m_Timestamp & 0xFF000000) >> 24; // each image gets a timestamp - RtpBuf[9] = (m_Timestamp & 0x00FF0000) >> 16; - RtpBuf[10] = (m_Timestamp & 0x0000FF00) >> 8; - RtpBuf[11] = (m_Timestamp & 0x000000FF); - RtpBuf[12] = 0x13; // 4 byte SSRC (sychronization source identifier) - RtpBuf[13] = 0xf9; // we just an arbitrary number here to keep it simple - RtpBuf[14] = 0x7e; - RtpBuf[15] = 0x67; - - // Prepare the 8 byte payload JPEG header - RtpBuf[16] = 0x00; // type specific - RtpBuf[17] = (fragmentOffset & 0x00FF0000) >> 16; // 3 byte fragmentation offset for fragmented images - RtpBuf[18] = (fragmentOffset & 0x0000FF00) >> 8; - RtpBuf[19] = (fragmentOffset & 0x000000FF); - - /* These sampling factors indicate that the chrominance components of - type 0 video is downsampled horizontally by 2 (often called 4:2:2) - while the chrominance components of type 1 video are downsampled both - horizontally and vertically by 2 (often called 4:2:0). */ - RtpBuf[20] = 0x00; // type (fixme might be wrong for camera data) https://tools.ietf.org/html/rfc2435 - RtpBuf[21] = q; // quality scale factor was 0x5e - RtpBuf[22] = m_width / 8; // width / 8 - RtpBuf[23] = m_height / 8; // height / 8 - - int headerLen = 24; // Inlcuding jpeg header but not qant table header - if(includeQuantTbl) { // we need a quant header - but only in first packet of the frame - //printf("inserting quanttbl\n"); - RtpBuf[24] = 0; // MBZ - RtpBuf[25] = 0; // 8 bit precision - RtpBuf[26] = 0; // MSB of lentgh - - int numQantBytes = 64; // Two 64 byte tables - RtpBuf[27] = 2 * numQantBytes; // LSB of length - - headerLen += 4; - - memcpy(RtpBuf + headerLen, quant0tbl, numQantBytes); - headerLen += numQantBytes; - - memcpy(RtpBuf + headerLen, quant1tbl, numQantBytes); - headerLen += numQantBytes; - } - // printf("Sending timestamp %d, seq %d, fragoff %d, fraglen %d, jpegLen %d\n", m_Timestamp, m_SequenceNumber, fragmentOffset, fragmentLen, jpegLen); - - // append the JPEG scan data to the RTP buffer - memcpy(RtpBuf + headerLen,jpeg + fragmentOffset, fragmentLen); - fragmentOffset += fragmentLen; - - m_SequenceNumber++; // prepare the packet counter for the next packet - - IPADDRESS otherip; - IPPORT otherport; - socketpeeraddr(m_Client, &otherip, &otherport); - - // RTP marker bit must be set on last fragment - if (m_TCPTransport) // RTP over RTSP - we send the buffer + 4 byte additional header - socketsend(m_Client,RtpBuf,RtpPacketSize + 4); - else // UDP - we send just the buffer by skipping the 4 byte RTP over RTSP header - udpsocketsend(m_RtpSocket,&RtpBuf[4],RtpPacketSize, otherip, m_RtpClientPort); - - return isLastFragment ? 0 : fragmentOffset; -}; - -void CStreamer::InitTransport(u_short aRtpPort, u_short aRtcpPort, bool TCP) -{ - m_RtpClientPort = aRtpPort; - m_RtcpClientPort = aRtcpPort; - m_TCPTransport = TCP; - - if (!m_TCPTransport) - { // allocate port pairs for RTP/RTCP ports in UDP transport mode - for (u_short P = 6970; P < 0xFFFE; P += 2) - { - m_RtpSocket = udpsocketcreate(P); - if (m_RtpSocket) - { // Rtp socket was bound successfully. Lets try to bind the consecutive Rtsp socket - m_RtcpSocket = udpsocketcreate(P + 1); - if (m_RtcpSocket) - { - m_RtpServerPort = P; - m_RtcpServerPort = P+1; - break; - } - else - { - udpsocketclose(m_RtpSocket); - udpsocketclose(m_RtcpSocket); - }; - } - }; - }; -}; - -u_short CStreamer::GetRtpServerPort() -{ - return m_RtpServerPort; -}; - -u_short CStreamer::GetRtcpServerPort() -{ - return m_RtcpServerPort; -}; - -void CStreamer::streamFrame(unsigned const char *data, uint32_t dataLen, uint32_t curMsec) -{ - if(m_prevMsec == 0) // first frame init our timestamp - m_prevMsec = curMsec; - - // compute deltat (being careful to handle clock rollover with a little lie) - uint32_t deltams = (curMsec >= m_prevMsec) ? curMsec - m_prevMsec : 100; - m_prevMsec = curMsec; - - // locate quant tables if possible - BufPtr qtable0, qtable1; - - if (!decodeJPEGfile(&data, &dataLen, &qtable0, &qtable1)) { -#ifdef STREAM_DEBUG - printf("can't decode jpeg data\n"); -#endif - return; - } - - int offset = 0; - do { - offset = SendRtpPacket(data, dataLen, offset, qtable0, qtable1); - } while(offset != 0); - - // Increment ONLY after a full frame - uint32_t units = 90000; // Hz per RFC 2435 - m_Timestamp += (units * deltams / 1000); // fixed timestamp increment for a frame rate of 25fps - - m_SendIdx++; - if (m_SendIdx > 1) m_SendIdx = 0; - -#ifdef STREAM_DEBUG - printf("frame sent\n"); -#endif -}; - -#include - -// search for a particular JPEG marker, moves *start to just after that marker -// This function fixes up the provided start ptr to point to the -// actual JPEG stream data and returns the number of bytes skipped -// APP0 e0 -// DQT db -// DQT db -// DHT c4 -// DHT c4 -// DHT c4 -// DHT c4 -// SOF0 c0 baseline (not progressive) 3 color 0x01 Y, 0x21 2h1v, 0x00 tbl0 -// - 0x02 Cb, 0x11 1h1v, 0x01 tbl1 - 0x03 Cr, 0x11 1h1v, 0x01 tbl1 -// therefore 4:2:2, with two separate quant tables (0 and 1) -// SOS da -// EOI d9 (no need to strip data after this RFC says client will discard) -bool findJPEGheader(BufPtr *start, uint32_t *len, uint8_t marker) { - // per https://en.wikipedia.org/wiki/JPEG_File_Interchange_Format - unsigned const char *bytes = *start; - - // kinda skanky, will break if unlucky and the headers inxlucde 0xffda - // might fall off array if jpeg is invalid - // FIXME - return false instead - while(bytes - *start < *len) { - uint8_t framing = *bytes++; // better be 0xff - if(framing != 0xff) { -// printf("malformed jpeg, framing=%x\n", framing); - return false; - } - uint8_t typecode = *bytes++; - if(typecode == marker) { - unsigned skipped = bytes - *start; - //printf("found marker 0x%x, skipped %d\n", marker, skipped); - - *start = bytes; - - // shrink len for the bytes we just skipped - *len -= skipped; - - return true; - } - else { - // not the section we were looking for, skip the entire section - switch(typecode) { - case 0xd8: // start of image - { - break; // no data to skip - } - case 0xe0: // app0 - case 0xdb: // dqt - case 0xc4: // dht - case 0xc0: // sof0 - case 0xda: // sos - { - // standard format section with 2 bytes for len. skip that many bytes - uint32_t len = bytes[0] * 256 + bytes[1]; - //printf("skipping section 0x%x, %d bytes\n", typecode, len); - bytes += len; - break; - } - default: -// printf("unexpected jpeg typecode 0x%x\n", typecode); - break; - } - } - } - -// printf("failed to find jpeg marker 0x%x", marker); - return false; -} - -// the scan data uses byte stuffing to guarantee anything that starts with 0xff -// followed by something not zero, is a new section. Look for that marker and return the ptr -// pointing there -void skipScanBytes(BufPtr *start) { - BufPtr bytes = *start; - - while(true) { // FIXME, check against length - while(*bytes++ != 0xff); - if(*bytes++ != 0) { - *start = bytes - 2; // back up to the 0xff marker we just found - return; - } - } -} -void nextJpegBlock(BufPtr *bytes) { - uint32_t len = (*bytes)[0] * 256 + (*bytes)[1]; - //printf("going to next jpeg block %d bytes\n", len); - *bytes += len; -} - -// When JPEG is stored as a file it is wrapped in a container -// This function fixes up the provided start ptr to point to the -// actual JPEG stream data and returns the number of bytes skipped -bool decodeJPEGfile(BufPtr *start, uint32_t *len, BufPtr *qtable0, BufPtr *qtable1) { - // per https://en.wikipedia.org/wiki/JPEG_File_Interchange_Format - unsigned const char *bytes = *start; - - if(!findJPEGheader(&bytes, len, 0xd8)) // better at least look like a jpeg file - return false; // FAILED! - - // Look for quant tables if they are present - *qtable0 = NULL; - *qtable1 = NULL; - BufPtr quantstart = *start; - uint32_t quantlen = *len; - if(!findJPEGheader(&quantstart, &quantlen, 0xdb)) { -// printf("error can't find quant table 0\n"); - } - else { - // printf("found quant table %x\n", quantstart[2]); - - *qtable0 = quantstart + 3; // 3 bytes of header skipped - nextJpegBlock(&quantstart); - if(!findJPEGheader(&quantstart, &quantlen, 0xdb)) { -// printf("error can't find quant table 1\n"); - } - else { - // printf("found quant table %x\n", quantstart[2]); - } - *qtable1 = quantstart + 3; - nextJpegBlock(&quantstart); - } - - if(!findJPEGheader(start, len, 0xda)) - return false; // FAILED! - - // Skip the header bytes of the SOS marker FIXME why doesn't this work? - uint32_t soslen = (*start)[0] * 256 + (*start)[1]; - *start += soslen; - *len -= soslen; - - // start scanning the data portion of the scan to find the end marker - BufPtr endmarkerptr = *start; - uint32_t endlen = *len; - - skipScanBytes(&endmarkerptr); - if(!findJPEGheader(&endmarkerptr, &endlen, 0xd9)) - return false; // FAILED! - - // endlen must now be the # of bytes between the start of our scan and - // the end marker, tell the caller to ignore bytes afterwards - *len = endmarkerptr - *start; - - return true; -} +#include "CStreamer.h" + +#include + +//#define STREAM_DEBUG + +CStreamer::CStreamer(SOCKET aClient, u_short width, u_short height) : m_Client(aClient) +{ +// printf("Creating TSP streamer\n"); + m_RtpServerPort = 0; + m_RtcpServerPort = 0; + m_RtpClientPort = 0; + m_RtcpClientPort = 0; + + m_SequenceNumber = 0; + m_Timestamp = 0; + m_SendIdx = 0; + m_TCPTransport = false; + + m_RtpSocket = NULLSOCKET; + m_RtcpSocket = NULLSOCKET; + + m_width = width; + m_height = height; + m_prevMsec = 0; +}; + +CStreamer::~CStreamer() +{ + udpsocketclose(m_RtpSocket); + udpsocketclose(m_RtcpSocket); +}; + +int CStreamer::SendRtpPacket(unsigned const char * jpeg, int jpegLen, int fragmentOffset, BufPtr quant0tbl, BufPtr quant1tbl) +{ +#define KRtpHeaderSize 12 // size of the RTP header +#define KJpegHeaderSize 8 // size of the special JPEG payload header + +#define MAX_FRAGMENT_SIZE 1100 // FIXME, pick more carefully + int fragmentLen = MAX_FRAGMENT_SIZE; + if(fragmentLen + fragmentOffset > jpegLen) // Shrink last fragment if needed + fragmentLen = jpegLen - fragmentOffset; + + bool isLastFragment = (fragmentOffset + fragmentLen) == jpegLen; + + // Do we have custom quant tables? If so include them per RFC + + bool includeQuantTbl = quant0tbl && quant1tbl && fragmentOffset == 0; + uint8_t q = includeQuantTbl ? 128 : 0x5e; + + //static char RtpBuf[2048]; // Note: we assume single threaded, this large buf we keep off of the tiny stack + int RtpPacketSize = fragmentLen + KRtpHeaderSize + KJpegHeaderSize + (includeQuantTbl ? (4 + 64 * 2) : 0); + + memset(RtpBuf,0x00,sizeof(RtpBuf)); + // Prepare the first 4 byte of the packet. This is the Rtp over Rtsp header in case of TCP based transport + RtpBuf[0] = '$'; // magic number + RtpBuf[1] = 0; // number of multiplexed subchannel on RTPS connection - here the RTP channel + RtpBuf[2] = (RtpPacketSize & 0x0000FF00) >> 8; + RtpBuf[3] = (RtpPacketSize & 0x000000FF); + // Prepare the 12 byte RTP header + RtpBuf[4] = 0x80; // RTP version + RtpBuf[5] = 0x1a | (isLastFragment ? 0x80 : 0x00); // JPEG payload (26) and marker bit + RtpBuf[7] = m_SequenceNumber & 0x0FF; // each packet is counted with a sequence counter + RtpBuf[6] = m_SequenceNumber >> 8; + RtpBuf[8] = (m_Timestamp & 0xFF000000) >> 24; // each image gets a timestamp + RtpBuf[9] = (m_Timestamp & 0x00FF0000) >> 16; + RtpBuf[10] = (m_Timestamp & 0x0000FF00) >> 8; + RtpBuf[11] = (m_Timestamp & 0x000000FF); + RtpBuf[12] = 0x13; // 4 byte SSRC (sychronization source identifier) + RtpBuf[13] = 0xf9; // we just an arbitrary number here to keep it simple + RtpBuf[14] = 0x7e; + RtpBuf[15] = 0x67; + + // Prepare the 8 byte payload JPEG header + RtpBuf[16] = 0x00; // type specific + RtpBuf[17] = (fragmentOffset & 0x00FF0000) >> 16; // 3 byte fragmentation offset for fragmented images + RtpBuf[18] = (fragmentOffset & 0x0000FF00) >> 8; + RtpBuf[19] = (fragmentOffset & 0x000000FF); + + /* These sampling factors indicate that the chrominance components of + type 0 video is downsampled horizontally by 2 (often called 4:2:2) + while the chrominance components of type 1 video are downsampled both + horizontally and vertically by 2 (often called 4:2:0). */ + RtpBuf[20] = 0x00; // type (fixme might be wrong for camera data) https://tools.ietf.org/html/rfc2435 + RtpBuf[21] = q; // quality scale factor was 0x5e + RtpBuf[22] = m_width / 8; // width / 8 + RtpBuf[23] = m_height / 8; // height / 8 + + int headerLen = 24; // Inlcuding jpeg header but not qant table header + if(includeQuantTbl) { // we need a quant header - but only in first packet of the frame + //printf("inserting quanttbl\n"); + RtpBuf[24] = 0; // MBZ + RtpBuf[25] = 0; // 8 bit precision + RtpBuf[26] = 0; // MSB of lentgh + + int numQantBytes = 64; // Two 64 byte tables + RtpBuf[27] = 2 * numQantBytes; // LSB of length + + headerLen += 4; + + memcpy(RtpBuf + headerLen, quant0tbl, numQantBytes); + headerLen += numQantBytes; + + memcpy(RtpBuf + headerLen, quant1tbl, numQantBytes); + headerLen += numQantBytes; + } + // printf("Sending timestamp %d, seq %d, fragoff %d, fraglen %d, jpegLen %d\n", m_Timestamp, m_SequenceNumber, fragmentOffset, fragmentLen, jpegLen); + + // append the JPEG scan data to the RTP buffer + memcpy(RtpBuf + headerLen,jpeg + fragmentOffset, fragmentLen); + fragmentOffset += fragmentLen; + + m_SequenceNumber++; // prepare the packet counter for the next packet + + IPADDRESS otherip; + IPPORT otherport; + socketpeeraddr(m_Client, &otherip, &otherport); + + // RTP marker bit must be set on last fragment + if (m_TCPTransport) // RTP over RTSP - we send the buffer + 4 byte additional header + socketsend(m_Client,RtpBuf,RtpPacketSize + 4); + else // UDP - we send just the buffer by skipping the 4 byte RTP over RTSP header + udpsocketsend(m_RtpSocket,&RtpBuf[4],RtpPacketSize, otherip, m_RtpClientPort); + + return isLastFragment ? 0 : fragmentOffset; +}; + +void CStreamer::InitTransport(u_short aRtpPort, u_short aRtcpPort, bool TCP) +{ + m_RtpClientPort = aRtpPort; + m_RtcpClientPort = aRtcpPort; + m_TCPTransport = TCP; + + if (!m_TCPTransport) + { // allocate port pairs for RTP/RTCP ports in UDP transport mode + for (u_short P = 6970; P < 0xFFFE; P += 2) + { + m_RtpSocket = udpsocketcreate(P); + if (m_RtpSocket) + { // Rtp socket was bound successfully. Lets try to bind the consecutive Rtsp socket + m_RtcpSocket = udpsocketcreate(P + 1); + if (m_RtcpSocket) + { + m_RtpServerPort = P; + m_RtcpServerPort = P+1; + break; + } + else + { + udpsocketclose(m_RtpSocket); + udpsocketclose(m_RtcpSocket); + }; + } + }; + }; +}; + +u_short CStreamer::GetRtpServerPort() +{ + return m_RtpServerPort; +}; + +u_short CStreamer::GetRtcpServerPort() +{ + return m_RtcpServerPort; +}; + +void CStreamer::streamFrame(unsigned const char *data, uint32_t dataLen, uint32_t curMsec) +{ + if(m_prevMsec == 0) // first frame init our timestamp + m_prevMsec = curMsec; + + // compute deltat (being careful to handle clock rollover with a little lie) + uint32_t deltams = (curMsec >= m_prevMsec) ? curMsec - m_prevMsec : 100; + m_prevMsec = curMsec; + + // locate quant tables if possible + BufPtr qtable0, qtable1; + + if (!decodeJPEGfile(&data, &dataLen, &qtable0, &qtable1)) { +#ifdef STREAM_DEBUG + printf("can't decode jpeg data\n"); +#endif + return; + } + + int offset = 0; + do { + offset = SendRtpPacket(data, dataLen, offset, qtable0, qtable1); + } while(offset != 0); + + // Increment ONLY after a full frame + uint32_t units = 90000; // Hz per RFC 2435 + m_Timestamp += (units * deltams / 1000); // fixed timestamp increment for a frame rate of 25fps + + m_SendIdx++; + if (m_SendIdx > 1) m_SendIdx = 0; + +#ifdef STREAM_DEBUG + printf("frame sent\n"); +#endif +}; + +#include + +// search for a particular JPEG marker, moves *start to just after that marker +// This function fixes up the provided start ptr to point to the +// actual JPEG stream data and returns the number of bytes skipped +// APP0 e0 +// DQT db +// DQT db +// DHT c4 +// DHT c4 +// DHT c4 +// DHT c4 +// SOF0 c0 baseline (not progressive) 3 color 0x01 Y, 0x21 2h1v, 0x00 tbl0 +// - 0x02 Cb, 0x11 1h1v, 0x01 tbl1 - 0x03 Cr, 0x11 1h1v, 0x01 tbl1 +// therefore 4:2:2, with two separate quant tables (0 and 1) +// SOS da +// EOI d9 (no need to strip data after this RFC says client will discard) +bool findJPEGheader(BufPtr *start, uint32_t *len, uint8_t marker) { + // per https://en.wikipedia.org/wiki/JPEG_File_Interchange_Format + unsigned const char *bytes = *start; + + // kinda skanky, will break if unlucky and the headers inxlucde 0xffda + // might fall off array if jpeg is invalid + // FIXME - return false instead + while(bytes - *start < *len) { + uint8_t framing = *bytes++; // better be 0xff + if(framing != 0xff) { +// printf("malformed jpeg, framing=%x\n", framing); + return false; + } + uint8_t typecode = *bytes++; + if(typecode == marker) { + unsigned skipped = bytes - *start; + //printf("found marker 0x%x, skipped %d\n", marker, skipped); + + *start = bytes; + + // shrink len for the bytes we just skipped + *len -= skipped; + + return true; + } + else { + // not the section we were looking for, skip the entire section + switch(typecode) { + case 0xd8: // start of image + { + break; // no data to skip + } + case 0xe0: // app0 + case 0xdb: // dqt + case 0xc4: // dht + case 0xc0: // sof0 + case 0xda: // sos + { + // standard format section with 2 bytes for len. skip that many bytes + uint32_t len = bytes[0] * 256 + bytes[1]; + //printf("skipping section 0x%x, %d bytes\n", typecode, len); + bytes += len; + break; + } + default: +// printf("unexpected jpeg typecode 0x%x\n", typecode); + break; + } + } + } + +// printf("failed to find jpeg marker 0x%x", marker); + return false; +} + +// the scan data uses byte stuffing to guarantee anything that starts with 0xff +// followed by something not zero, is a new section. Look for that marker and return the ptr +// pointing there +void skipScanBytes(BufPtr *start) { + BufPtr bytes = *start; + + while(true) { // FIXME, check against length + while(*bytes++ != 0xff); + if(*bytes++ != 0) { + *start = bytes - 2; // back up to the 0xff marker we just found + return; + } + } +} +void nextJpegBlock(BufPtr *bytes) { + uint32_t len = (*bytes)[0] * 256 + (*bytes)[1]; + //printf("going to next jpeg block %d bytes\n", len); + *bytes += len; +} + +// When JPEG is stored as a file it is wrapped in a container +// This function fixes up the provided start ptr to point to the +// actual JPEG stream data and returns the number of bytes skipped +bool decodeJPEGfile(BufPtr *start, uint32_t *len, BufPtr *qtable0, BufPtr *qtable1) { + // per https://en.wikipedia.org/wiki/JPEG_File_Interchange_Format + unsigned const char *bytes = *start; + + if(!findJPEGheader(&bytes, len, 0xd8)) // better at least look like a jpeg file + return false; // FAILED! + + // Look for quant tables if they are present + *qtable0 = NULL; + *qtable1 = NULL; + BufPtr quantstart = *start; + uint32_t quantlen = *len; + if(!findJPEGheader(&quantstart, &quantlen, 0xdb)) { +// printf("error can't find quant table 0\n"); + } + else { + // printf("found quant table %x\n", quantstart[2]); + + *qtable0 = quantstart + 3; // 3 bytes of header skipped + nextJpegBlock(&quantstart); + if(!findJPEGheader(&quantstart, &quantlen, 0xdb)) { +// printf("error can't find quant table 1\n"); + } + else { + // printf("found quant table %x\n", quantstart[2]); + } + *qtable1 = quantstart + 3; + nextJpegBlock(&quantstart); + } + + if(!findJPEGheader(start, len, 0xda)) + return false; // FAILED! + + // Skip the header bytes of the SOS marker FIXME why doesn't this work? + uint32_t soslen = (*start)[0] * 256 + (*start)[1]; + *start += soslen; + *len -= soslen; + + // start scanning the data portion of the scan to find the end marker + BufPtr endmarkerptr = *start; + uint32_t endlen = *len; + + skipScanBytes(&endmarkerptr); + if(!findJPEGheader(&endmarkerptr, &endlen, 0xd9)) + return false; // FAILED! + + // endlen must now be the # of bytes between the start of our scan and + // the end marker, tell the caller to ignore bytes afterwards + *len = endmarkerptr - *start; + + return true; +} diff --git a/lib/libesp32/rtsp/CStreamer.h b/lib/libesp32/rtsp/CStreamer.h index 58a9983e2..36b249610 100755 --- a/lib/libesp32/rtsp/CStreamer.h +++ b/lib/libesp32/rtsp/CStreamer.h @@ -1,57 +1,57 @@ -#pragma once - -#include "platglue.h" - -typedef unsigned const char *BufPtr; - -class CStreamer -{ -public: - CStreamer(SOCKET aClient, u_short width, u_short height); - virtual ~CStreamer(); - - void InitTransport(u_short aRtpPort, u_short aRtcpPort, bool TCP); - u_short GetRtpServerPort(); - u_short GetRtcpServerPort(); - - virtual void streamImage(uint32_t curMsec) = 0; // send a new image to the client -protected: - - void streamFrame(unsigned const char *data, uint32_t dataLen, uint32_t curMsec); - -private: - int SendRtpPacket(unsigned const char *jpeg, int jpegLen, int fragmentOffset, BufPtr quant0tbl = NULL, BufPtr quant1tbl = NULL);// returns new fragmentOffset or 0 if finished with frame - - UDPSOCKET m_RtpSocket; // RTP socket for streaming RTP packets to client - UDPSOCKET m_RtcpSocket; // RTCP socket for sending/receiving RTCP packages - - uint16_t m_RtpClientPort; // RTP receiver port on client (in host byte order!) - uint16_t m_RtcpClientPort; // RTCP receiver port on client (in host byte order!) - IPPORT m_RtpServerPort; // RTP sender port on server - IPPORT m_RtcpServerPort; // RTCP sender port on server - - u_short m_SequenceNumber; - uint32_t m_Timestamp; - int m_SendIdx; - bool m_TCPTransport; - SOCKET m_Client; - uint32_t m_prevMsec; - - u_short m_width; // image data info - u_short m_height; - char RtpBuf[2048]; -}; - - - -// When JPEG is stored as a file it is wrapped in a container -// This function fixes up the provided start ptr to point to the -// actual JPEG stream data and returns the number of bytes skipped -// returns true if the file seems to be valid jpeg -// If quant tables can be found they will be stored in qtable0/1 -bool decodeJPEGfile(BufPtr *start, uint32_t *len, BufPtr *qtable0, BufPtr *qtable1); -bool findJPEGheader(BufPtr *start, uint32_t *len, uint8_t marker); - -// Given a jpeg ptr pointing to a pair of length bytes, advance the pointer to -// the next 0xff marker byte -void nextJpegBlock(BufPtr *start); +#pragma once + +#include "platglue.h" + +typedef unsigned const char *BufPtr; + +class CStreamer +{ +public: + CStreamer(SOCKET aClient, u_short width, u_short height); + virtual ~CStreamer(); + + void InitTransport(u_short aRtpPort, u_short aRtcpPort, bool TCP); + u_short GetRtpServerPort(); + u_short GetRtcpServerPort(); + + virtual void streamImage(uint32_t curMsec) = 0; // send a new image to the client +protected: + + void streamFrame(unsigned const char *data, uint32_t dataLen, uint32_t curMsec); + +private: + int SendRtpPacket(unsigned const char *jpeg, int jpegLen, int fragmentOffset, BufPtr quant0tbl = NULL, BufPtr quant1tbl = NULL);// returns new fragmentOffset or 0 if finished with frame + + UDPSOCKET m_RtpSocket; // RTP socket for streaming RTP packets to client + UDPSOCKET m_RtcpSocket; // RTCP socket for sending/receiving RTCP packages + + uint16_t m_RtpClientPort; // RTP receiver port on client (in host byte order!) + uint16_t m_RtcpClientPort; // RTCP receiver port on client (in host byte order!) + IPPORT m_RtpServerPort; // RTP sender port on server + IPPORT m_RtcpServerPort; // RTCP sender port on server + + u_short m_SequenceNumber; + uint32_t m_Timestamp; + int m_SendIdx; + bool m_TCPTransport; + SOCKET m_Client; + uint32_t m_prevMsec; + + u_short m_width; // image data info + u_short m_height; + char RtpBuf[2048]; +}; + + + +// When JPEG is stored as a file it is wrapped in a container +// This function fixes up the provided start ptr to point to the +// actual JPEG stream data and returns the number of bytes skipped +// returns true if the file seems to be valid jpeg +// If quant tables can be found they will be stored in qtable0/1 +bool decodeJPEGfile(BufPtr *start, uint32_t *len, BufPtr *qtable0, BufPtr *qtable1); +bool findJPEGheader(BufPtr *start, uint32_t *len, uint8_t marker); + +// Given a jpeg ptr pointing to a pair of length bytes, advance the pointer to +// the next 0xff marker byte +void nextJpegBlock(BufPtr *start); diff --git a/lib/libesp32/rtsp/JPEGSamples.cpp b/lib/libesp32/rtsp/JPEGSamples.cpp index 12def78e2..ffa75a8ea 100755 --- a/lib/libesp32/rtsp/JPEGSamples.cpp +++ b/lib/libesp32/rtsp/JPEGSamples.cpp @@ -1,3327 +1,3327 @@ -#include "JPEGSamples.h" - -#ifdef INCLUDE_SIMDATA -// APP0 e0 -// DQT db -// DQT db -// DHT c4 -// DHT c4 -// DHT c4 -// DHT c4 -// SOF0 c0 baseline (not progressive) 3 color 0x01 Y, 0x21 2h1v, 0x00 tbl0 -// - 0x02 Cb, 0x11 1h1v, 0x01 tbl1 - 0x03 Cr, 0x11 1h1v, 0x01 tbl1 -// therefore 4:2:2, with two separate quant tables (0 and 1) -// SOS da -// EOI d9 (no need to strip data after this RFC says client will discard) -unsigned const char capture_jpg[] = { - 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, - 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, - 0x00, 0x0f, 0x0a, 0x0b, 0x0d, 0x0b, 0x09, 0x0f, 0x0d, 0x0c, 0x0d, 0x11, - 0x10, 0x0f, 0x12, 0x17, 0x26, 0x18, 0x17, 0x15, 0x15, 0x17, 0x2e, 0x21, - 0x23, 0x1b, 0x26, 0x36, 0x30, 0x39, 0x38, 0x35, 0x30, 0x35, 0x34, 0x3c, - 0x44, 0x56, 0x49, 0x3c, 0x40, 0x52, 0x41, 0x34, 0x35, 0x4b, 0x66, 0x4c, - 0x52, 0x59, 0x5c, 0x61, 0x62, 0x61, 0x3a, 0x48, 0x6a, 0x71, 0x69, 0x5e, - 0x71, 0x56, 0x5f, 0x61, 0x5d, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x10, 0x11, - 0x11, 0x17, 0x14, 0x17, 0x2c, 0x18, 0x18, 0x2c, 0x5d, 0x3e, 0x35, 0x3e, - 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, - 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, - 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, - 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, - 0x5d, 0x5d, 0xff, 0xc4, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, - 0xc4, 0x00, 0xb5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, - 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, - 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, - 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, - 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, - 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, - 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, - 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, - 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, - 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, - 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, - 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, - 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, - 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, - 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa, 0xff, 0xc4, 0x00, 0x1f, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, - 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, - 0xc4, 0x00, 0xb5, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, - 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, - 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, - 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, - 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, - 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, - 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, - 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, - 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, - 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, - 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, - 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, - 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, - 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, - 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, - 0xf9, 0xfa, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x02, 0x58, 0x03, 0x20, 0x03, - 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, - 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xc7, - 0x10, 0xd3, 0xa3, 0x84, 0xaf, 0x34, 0xda, 0x08, 0x9a, 0xe3, 0x1b, 0x46, - 0x29, 0xc9, 0xf7, 0xc5, 0x4f, 0x40, 0x34, 0xd3, 0xa5, 0x3a, 0x84, 0x20, - 0xa5, 0xa6, 0x20, 0xa2, 0x81, 0x85, 0x14, 0x08, 0x28, 0xa0, 0x62, 0xd1, - 0x40, 0x05, 0x14, 0x00, 0x94, 0x50, 0x01, 0x45, 0x03, 0x0a, 0x28, 0x10, - 0x52, 0x50, 0x01, 0x49, 0x40, 0xc2, 0x8a, 0x00, 0x29, 0x28, 0x01, 0x28, - 0xa0, 0x02, 0x92, 0x80, 0x12, 0x8a, 0x00, 0x4a, 0x4a, 0x00, 0x29, 0x28, - 0x01, 0x29, 0x28, 0x01, 0x28, 0xa0, 0x04, 0xa4, 0xa0, 0x02, 0x92, 0x80, - 0x12, 0x92, 0x80, 0x12, 0x8a, 0x60, 0x25, 0x25, 0x02, 0x12, 0x92, 0x80, - 0x12, 0x8a, 0x00, 0x4a, 0x4a, 0x40, 0x14, 0x50, 0x02, 0x52, 0x53, 0x10, - 0x94, 0x94, 0x08, 0x4a, 0x28, 0x10, 0x94, 0x94, 0x00, 0x52, 0x50, 0x02, - 0x52, 0x50, 0x02, 0x51, 0x40, 0x09, 0x49, 0x40, 0x09, 0x4f, 0x4e, 0x94, - 0x08, 0x75, 0x15, 0x42, 0x12, 0x8a, 0x42, 0x12, 0x92, 0x98, 0x09, 0x45, - 0x00, 0x14, 0x94, 0x08, 0x28, 0xa4, 0x02, 0x52, 0x53, 0x10, 0x52, 0x52, - 0x00, 0xa4, 0xa0, 0x90, 0x13, 0x2d, 0x4a, 0xb2, 0x27, 0xa8, 0xa9, 0x67, - 0x51, 0x76, 0x06, 0xdd, 0x06, 0x7d, 0xe9, 0xd4, 0x90, 0xcd, 0x28, 0x4e, - 0x56, 0xa5, 0xa1, 0x08, 0x29, 0x69, 0x88, 0x28, 0xa0, 0x02, 0x8a, 0x00, - 0x28, 0xa0, 0x61, 0x4b, 0x40, 0x09, 0x4b, 0x40, 0x84, 0xa2, 0x81, 0x85, - 0x14, 0x00, 0x51, 0x40, 0xc2, 0x92, 0x81, 0x05, 0x14, 0x00, 0x94, 0x50, - 0x01, 0x49, 0x40, 0x05, 0x25, 0x03, 0x0a, 0x4a, 0x00, 0x29, 0x28, 0x01, - 0x29, 0x28, 0x00, 0xa4, 0xa0, 0x04, 0xa2, 0x80, 0x12, 0x92, 0x81, 0x09, - 0x45, 0x03, 0x12, 0x92, 0x80, 0x12, 0x8a, 0x00, 0x4a, 0x4a, 0x62, 0x12, - 0x92, 0x90, 0x09, 0x49, 0x40, 0x09, 0x49, 0x40, 0x05, 0x25, 0x02, 0x12, - 0x8a, 0x60, 0x25, 0x25, 0x00, 0x14, 0x94, 0x08, 0x29, 0xb4, 0x00, 0x52, - 0x50, 0x21, 0x29, 0x28, 0x00, 0xa4, 0xa0, 0x04, 0xa2, 0x98, 0x86, 0xd1, - 0x48, 0x04, 0xa7, 0xa5, 0x00, 0x3a, 0x90, 0xd5, 0x12, 0x25, 0x25, 0x00, - 0x14, 0x50, 0x02, 0x51, 0x40, 0x84, 0xa4, 0xa0, 0x02, 0x8a, 0x00, 0x4a, - 0x29, 0x08, 0x29, 0x28, 0x01, 0x29, 0x29, 0x88, 0xcb, 0xf3, 0x4d, 0x28, - 0x90, 0xd2, 0xb1, 0xd4, 0x6d, 0xe8, 0xf2, 0x6f, 0xb6, 0xdb, 0xe9, 0x93, - 0xfa, 0xd5, 0xda, 0xce, 0x23, 0x65, 0xeb, 0x43, 0x94, 0xab, 0x14, 0xd0, - 0x98, 0xb4, 0x53, 0x24, 0x28, 0xa0, 0x05, 0xa2, 0x80, 0x0a, 0x28, 0x18, - 0x51, 0x40, 0x05, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, 0x00, 0x51, 0x40, - 0x09, 0x45, 0x00, 0x14, 0x94, 0x0c, 0x28, 0xa0, 0x02, 0x92, 0x80, 0x0a, - 0x4a, 0x00, 0x29, 0x28, 0x00, 0xa4, 0xa0, 0x04, 0xa2, 0x80, 0x12, 0x8a, - 0x00, 0x4a, 0x4a, 0x00, 0x4a, 0x4a, 0x00, 0x4a, 0x28, 0x01, 0x29, 0x28, - 0x10, 0x94, 0x50, 0x31, 0x29, 0x28, 0x10, 0x94, 0x94, 0x0c, 0x4a, 0x4a, - 0x62, 0x12, 0x92, 0x80, 0x12, 0x92, 0x80, 0x0a, 0x4a, 0x04, 0x14, 0x94, - 0x00, 0x53, 0x68, 0x10, 0x52, 0x50, 0x02, 0x51, 0x40, 0x86, 0xd1, 0x40, - 0x09, 0x49, 0x4c, 0x04, 0xa2, 0x80, 0x12, 0x92, 0x81, 0x09, 0x4f, 0x4a, - 0x40, 0x3a, 0x9b, 0x56, 0x48, 0x52, 0x50, 0x01, 0x45, 0x20, 0x0a, 0x29, - 0x08, 0x4a, 0x4a, 0x60, 0x25, 0x14, 0x80, 0x4a, 0x29, 0x92, 0x14, 0x94, - 0x80, 0x4a, 0x29, 0x8c, 0xc4, 0xcd, 0x28, 0xe9, 0x53, 0x63, 0xa4, 0xd7, - 0xd0, 0x5f, 0xe7, 0x91, 0x7f, 0xd9, 0xfe, 0xb5, 0xad, 0x59, 0xc4, 0xa9, - 0x97, 0x2c, 0xcf, 0x6a, 0xb9, 0x4d, 0x12, 0x14, 0xb5, 0x42, 0x0a, 0x28, - 0x00, 0xa2, 0x80, 0x16, 0x8a, 0x00, 0x28, 0xa0, 0x41, 0x45, 0x00, 0x14, - 0x50, 0x30, 0xa4, 0xa0, 0x02, 0x8a, 0x00, 0x28, 0xa0, 0x02, 0x92, 0x81, - 0x85, 0x14, 0x00, 0x94, 0x50, 0x01, 0x49, 0x40, 0x05, 0x25, 0x00, 0x14, - 0x94, 0x00, 0x52, 0x50, 0x02, 0x52, 0x50, 0x01, 0x49, 0x40, 0x09, 0x49, - 0x40, 0x09, 0x49, 0x40, 0x05, 0x25, 0x00, 0x25, 0x14, 0x00, 0x94, 0x94, - 0x00, 0x94, 0x94, 0x00, 0x94, 0x94, 0xc4, 0x25, 0x25, 0x20, 0x12, 0x92, - 0x80, 0x12, 0x92, 0x80, 0x0a, 0x29, 0x80, 0x94, 0x94, 0x08, 0x29, 0x29, - 0x08, 0x6d, 0x15, 0x40, 0x25, 0x25, 0x21, 0x09, 0x45, 0x20, 0x12, 0x92, - 0x81, 0x09, 0x49, 0x4c, 0x02, 0x9c, 0x94, 0x00, 0xfa, 0x69, 0xaa, 0x24, - 0x4a, 0x4a, 0x00, 0x29, 0x68, 0x01, 0x28, 0xa4, 0x21, 0x28, 0xa6, 0x02, - 0x52, 0x52, 0x00, 0xa2, 0x81, 0x09, 0x45, 0x31, 0x09, 0x4d, 0x35, 0x43, - 0x30, 0xa9, 0xea, 0x6a, 0x2c, 0x74, 0x9a, 0x3a, 0x3b, 0xe2, 0xf6, 0x25, - 0xfe, 0xf3, 0x62, 0xb7, 0xab, 0x3e, 0xa3, 0x96, 0xc4, 0xf6, 0x87, 0xe7, - 0xad, 0x01, 0x42, 0x10, 0xb4, 0x55, 0x08, 0x5a, 0x28, 0x10, 0x51, 0x40, - 0x0b, 0x49, 0x40, 0xc5, 0xa2, 0x98, 0x05, 0x14, 0x80, 0x29, 0x28, 0x00, - 0xa2, 0x80, 0x0a, 0x28, 0x00, 0xa2, 0x80, 0x0a, 0x4a, 0x06, 0x14, 0x50, - 0x02, 0x51, 0x40, 0x05, 0x25, 0x00, 0x14, 0x94, 0x00, 0x52, 0x50, 0x01, - 0x49, 0x40, 0x09, 0x45, 0x00, 0x25, 0x25, 0x00, 0x25, 0x25, 0x00, 0x14, - 0x94, 0x00, 0x94, 0x94, 0x00, 0x94, 0x50, 0x02, 0x52, 0x50, 0x21, 0x29, - 0x28, 0x01, 0x29, 0xb4, 0x00, 0x52, 0x50, 0x21, 0x29, 0x28, 0x01, 0x29, - 0x29, 0x80, 0x94, 0x52, 0x00, 0xa4, 0xa6, 0x21, 0x29, 0x28, 0x01, 0x29, - 0x28, 0x00, 0xa4, 0x34, 0x08, 0x4a, 0x4a, 0x04, 0x25, 0x14, 0x00, 0xda, - 0x28, 0x01, 0x29, 0xcb, 0x40, 0x0f, 0xa4, 0xab, 0x20, 0x4a, 0x4a, 0x00, - 0x28, 0xa0, 0x04, 0xa2, 0x81, 0x09, 0x45, 0x21, 0x85, 0x25, 0x02, 0x12, - 0x8a, 0x00, 0x4a, 0x4a, 0x42, 0x0a, 0x29, 0x81, 0x81, 0x4e, 0x14, 0x8e, - 0xa2, 0xcd, 0x9b, 0xf9, 0x77, 0x51, 0xbf, 0xa1, 0xae, 0xa3, 0xf8, 0x54, - 0xfa, 0x81, 0x51, 0xf6, 0x87, 0xd0, 0x92, 0x0e, 0x25, 0x15, 0xa4, 0xbd, - 0x29, 0x75, 0x10, 0xb4, 0xb5, 0x42, 0x0a, 0x28, 0x10, 0xb4, 0x50, 0x01, - 0x45, 0x03, 0x0a, 0x29, 0x80, 0xb4, 0x94, 0x80, 0x29, 0x68, 0x01, 0x28, - 0xa0, 0x02, 0x8a, 0x00, 0x29, 0x29, 0x80, 0xb4, 0x94, 0x86, 0x14, 0x50, - 0x02, 0x52, 0xd0, 0x02, 0x52, 0x50, 0x01, 0x45, 0x00, 0x14, 0x94, 0x00, - 0x94, 0x94, 0x00, 0x52, 0x50, 0x02, 0x52, 0x50, 0x01, 0x49, 0x40, 0x09, - 0x49, 0x40, 0x09, 0x49, 0x40, 0x09, 0x49, 0x40, 0x09, 0x45, 0x00, 0x25, - 0x25, 0x02, 0x12, 0x92, 0x98, 0x09, 0x49, 0x48, 0x42, 0x52, 0x50, 0x02, - 0x52, 0x50, 0x02, 0x52, 0x53, 0x00, 0xa2, 0x81, 0x09, 0x49, 0x40, 0x09, - 0x49, 0x40, 0x09, 0x45, 0x00, 0x36, 0x8a, 0x64, 0x89, 0x49, 0x48, 0x62, - 0x51, 0x45, 0xc4, 0x25, 0x2a, 0x50, 0x03, 0xe8, 0xaa, 0x24, 0x4a, 0x28, - 0x10, 0x94, 0x50, 0x02, 0x51, 0x40, 0x86, 0xd1, 0x48, 0x61, 0x49, 0x45, - 0xc4, 0x25, 0x14, 0xc0, 0x4a, 0x29, 0x00, 0x94, 0xb4, 0x08, 0xe7, 0xe9, - 0xc0, 0xd0, 0xce, 0x91, 0xd9, 0xae, 0xbe, 0x36, 0xdf, 0x0a, 0x9f, 0xc3, - 0xf4, 0xac, 0xdf, 0xc4, 0x57, 0xd9, 0x1c, 0x3a, 0xd6, 0x9c, 0x7c, 0xad, - 0x1d, 0x44, 0x3e, 0x8a, 0xa1, 0x0b, 0x45, 0x00, 0x14, 0xb4, 0x08, 0x28, - 0xa0, 0x61, 0x45, 0x00, 0x14, 0xb4, 0x00, 0x94, 0x50, 0x02, 0xd2, 0x50, - 0x01, 0x45, 0x00, 0x14, 0x94, 0x00, 0x51, 0x40, 0x05, 0x14, 0x0c, 0x4a, - 0x28, 0x00, 0xa2, 0x80, 0x12, 0x8a, 0x00, 0x4a, 0x28, 0x01, 0x28, 0xa0, - 0x04, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x02, 0x92, 0x80, 0x12, 0x92, 0x80, - 0x12, 0x92, 0x80, 0x12, 0x92, 0x80, 0x0a, 0x4a, 0x00, 0x6d, 0x14, 0x00, - 0x94, 0x94, 0x08, 0x4a, 0x4a, 0x04, 0x25, 0x36, 0x80, 0x12, 0x92, 0x80, - 0x0a, 0x4a, 0x00, 0x4a, 0x28, 0x01, 0x29, 0x28, 0x10, 0x94, 0x94, 0x0c, - 0x29, 0x28, 0x10, 0x94, 0x94, 0x08, 0x4a, 0x29, 0x88, 0x4a, 0x43, 0x40, - 0x09, 0x4e, 0x5a, 0x60, 0x3e, 0x8a, 0x76, 0x24, 0x6d, 0x14, 0x00, 0x52, - 0x50, 0x21, 0x28, 0xa0, 0x42, 0x52, 0x1a, 0x2c, 0x30, 0xa2, 0x80, 0x12, - 0x92, 0x98, 0x82, 0x92, 0xa4, 0x41, 0x49, 0x4c, 0x66, 0x05, 0x14, 0x1d, - 0x03, 0x96, 0xba, 0x9d, 0x29, 0xf7, 0xe9, 0xab, 0xeb, 0xb9, 0xab, 0x29, - 0xbd, 0x51, 0x7f, 0x64, 0xb3, 0xda, 0xb4, 0xa0, 0x39, 0x4a, 0x1e, 0xe4, - 0x92, 0xd2, 0xd5, 0x08, 0x5a, 0x28, 0x10, 0x51, 0x40, 0x0b, 0x45, 0x00, - 0x14, 0x50, 0x30, 0xa2, 0x80, 0x0a, 0x28, 0x00, 0xa2, 0x80, 0x0a, 0x4a, - 0x00, 0x28, 0xa0, 0x05, 0xa4, 0xa0, 0x61, 0x45, 0x02, 0x0a, 0x4a, 0x06, - 0x14, 0x50, 0x02, 0x51, 0x40, 0x05, 0x25, 0x00, 0x14, 0x94, 0x00, 0x94, - 0x94, 0x00, 0x52, 0x50, 0x02, 0x52, 0x50, 0x02, 0x52, 0x50, 0x02, 0x52, - 0x50, 0x02, 0x52, 0x50, 0x02, 0x52, 0x50, 0x02, 0x52, 0x50, 0x21, 0x28, - 0xa0, 0x62, 0x53, 0x68, 0x10, 0x94, 0x94, 0x08, 0x4a, 0x4a, 0x06, 0x25, - 0x25, 0x02, 0x12, 0x8a, 0x00, 0x4a, 0x28, 0x10, 0x94, 0x94, 0x00, 0x94, - 0x53, 0x10, 0x94, 0x94, 0x0c, 0x4a, 0x4a, 0x09, 0x12, 0x92, 0x98, 0x05, - 0x2a, 0xf5, 0xa0, 0x07, 0xd1, 0x4c, 0x91, 0x28, 0xa0, 0x42, 0x52, 0x50, - 0x01, 0x45, 0x00, 0x25, 0x36, 0x80, 0x0a, 0x29, 0x88, 0x4a, 0x29, 0x08, - 0x43, 0x45, 0x20, 0x1b, 0x45, 0x00, 0x73, 0xf4, 0x50, 0x74, 0x8e, 0x53, - 0x5d, 0x0f, 0x87, 0xdf, 0x74, 0x0c, 0x87, 0xb0, 0xcf, 0xeb, 0x59, 0x54, - 0x45, 0xa3, 0x4f, 0xb5, 0x5e, 0xb4, 0x3f, 0x2d, 0x53, 0x24, 0xb3, 0x4b, - 0x4c, 0x41, 0x45, 0x00, 0x2d, 0x14, 0x08, 0x28, 0xa0, 0x02, 0x96, 0x81, - 0x85, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, 0x00, 0x52, 0x50, 0x30, 0xa2, - 0x81, 0x05, 0x14, 0x0c, 0x29, 0x28, 0x01, 0x69, 0x28, 0x00, 0xa4, 0xa0, - 0x02, 0x8a, 0x00, 0x4a, 0x28, 0x01, 0x28, 0xa0, 0x04, 0xa2, 0x80, 0x12, - 0x92, 0x80, 0x12, 0x92, 0x80, 0x12, 0x92, 0x80, 0x12, 0x92, 0x80, 0x12, - 0x92, 0x80, 0x12, 0x92, 0x80, 0x12, 0x92, 0x80, 0x0a, 0x6d, 0x00, 0x25, - 0x25, 0x02, 0x12, 0x92, 0x80, 0x1b, 0x45, 0x02, 0x12, 0x92, 0x98, 0x09, - 0x49, 0x40, 0x05, 0x25, 0x02, 0x12, 0x92, 0x80, 0x0a, 0x4a, 0x42, 0x10, - 0xd2, 0x53, 0x01, 0x29, 0x28, 0x00, 0xa6, 0xd0, 0x20, 0xa5, 0x1d, 0x69, - 0x80, 0xfa, 0x29, 0x92, 0x25, 0x25, 0x31, 0x05, 0x25, 0x00, 0x25, 0x14, - 0x00, 0x94, 0x50, 0x21, 0x28, 0xa4, 0x02, 0x51, 0x4c, 0x04, 0xa4, 0xa4, - 0x01, 0x45, 0x22, 0x4e, 0x76, 0x92, 0x9d, 0xb5, 0x3a, 0x87, 0x0a, 0xd9, - 0xf0, 0xec, 0x9f, 0xe9, 0x32, 0x2f, 0xf7, 0xb6, 0x8f, 0xd6, 0xb2, 0xa8, - 0x5c, 0x0d, 0xda, 0xb5, 0x66, 0x79, 0xc5, 0x36, 0x4a, 0x2e, 0xd2, 0xd3, - 0x10, 0xb4, 0x94, 0x08, 0x5a, 0x5a, 0x00, 0x4a, 0x28, 0x18, 0xb4, 0x53, - 0x00, 0xa2, 0x90, 0x05, 0x14, 0xc0, 0x28, 0xa4, 0x01, 0x45, 0x03, 0x0a, - 0x28, 0x10, 0x51, 0x40, 0xc2, 0x92, 0x81, 0x05, 0x14, 0x0c, 0x29, 0x28, - 0x00, 0xa2, 0x80, 0x0a, 0x4a, 0x00, 0x29, 0x28, 0x00, 0xa4, 0xa0, 0x04, - 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, - 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, - 0xa4, 0xa0, 0x42, 0x52, 0x50, 0x02, 0x53, 0x69, 0x88, 0x4a, 0x4a, 0x40, - 0x25, 0x25, 0x00, 0x14, 0x53, 0x10, 0x94, 0x94, 0x00, 0x94, 0x94, 0x80, - 0x4a, 0x4a, 0x62, 0x0a, 0x6d, 0x02, 0x12, 0x92, 0x98, 0x05, 0x2a, 0xd2, - 0x02, 0x4a, 0x4a, 0xa2, 0x44, 0xa4, 0xa0, 0x41, 0x49, 0x4c, 0x02, 0x92, - 0x81, 0x89, 0x45, 0x21, 0x09, 0x45, 0x32, 0x44, 0xa4, 0xa0, 0x02, 0x8a, - 0x40, 0x25, 0x14, 0x86, 0x73, 0x94, 0xb4, 0x23, 0xa0, 0x4c, 0xd6, 0x86, - 0x8a, 0xf8, 0xd4, 0x61, 0xff, 0x00, 0x7c, 0x54, 0x54, 0xd8, 0xd2, 0x9e, - 0xe7, 0x51, 0xe9, 0x53, 0xda, 0xff, 0x00, 0xac, 0xa5, 0xba, 0x20, 0xd0, - 0x14, 0xb5, 0x42, 0x16, 0x8a, 0x04, 0x2d, 0x14, 0x0c, 0x28, 0xa0, 0x02, - 0x8a, 0x00, 0x5a, 0x28, 0x00, 0xa2, 0x80, 0x0a, 0x28, 0x18, 0x51, 0x40, - 0x05, 0x14, 0xc0, 0x28, 0xa4, 0x02, 0x52, 0xd0, 0x02, 0x51, 0x40, 0x05, - 0x14, 0x00, 0x52, 0x50, 0x01, 0x49, 0x40, 0x05, 0x14, 0x00, 0x94, 0x94, - 0x00, 0x94, 0x94, 0x00, 0x53, 0x68, 0x00, 0xa4, 0xa0, 0x06, 0xd2, 0x50, - 0x02, 0x52, 0x50, 0x02, 0x52, 0x50, 0x02, 0x52, 0x50, 0x02, 0x52, 0x50, - 0x02, 0x52, 0x50, 0x02, 0x53, 0x68, 0x01, 0x29, 0x28, 0x10, 0x94, 0x94, - 0x08, 0x6d, 0x25, 0x30, 0x0a, 0x29, 0x00, 0x94, 0x94, 0x08, 0x4a, 0x4a, - 0x60, 0x25, 0x14, 0x84, 0x36, 0x8a, 0x00, 0x4a, 0x4a, 0x62, 0x12, 0x94, - 0x52, 0x02, 0x4a, 0x4a, 0xb2, 0x44, 0xa2, 0x98, 0x84, 0xa2, 0x90, 0x09, - 0x49, 0x40, 0x09, 0x45, 0x02, 0x12, 0x8a, 0x04, 0x25, 0x14, 0x00, 0x94, - 0x94, 0x00, 0x51, 0x49, 0x01, 0xcd, 0x52, 0xd3, 0xb1, 0xd4, 0x15, 0x62, - 0xc9, 0xfc, 0xbb, 0x84, 0x7f, 0xee, 0xf3, 0x51, 0x3d, 0x8a, 0x8e, 0xe7, - 0x62, 0x3e, 0xe2, 0x7f, 0xba, 0x3f, 0x95, 0x4b, 0x0f, 0x12, 0x0a, 0x95, - 0xf0, 0x93, 0xd4, 0xd2, 0x5e, 0x94, 0xea, 0xa1, 0x0b, 0x45, 0x00, 0x14, - 0x50, 0x21, 0x68, 0xa0, 0x02, 0x8a, 0x06, 0x14, 0x53, 0x00, 0xa2, 0x90, - 0x05, 0x2d, 0x00, 0x25, 0x14, 0x00, 0x51, 0x40, 0xc5, 0xa2, 0x80, 0x12, - 0x8a, 0x00, 0x28, 0xa0, 0x02, 0x8a, 0x00, 0x29, 0x28, 0x00, 0xa2, 0x80, - 0x12, 0x92, 0x80, 0x0a, 0x4a, 0x00, 0x4a, 0x28, 0x01, 0x29, 0x28, 0x01, - 0x29, 0x28, 0x01, 0x29, 0x28, 0x01, 0xb4, 0x94, 0x00, 0x94, 0x94, 0x00, - 0x94, 0x94, 0x00, 0x94, 0x94, 0x00, 0x94, 0x94, 0x08, 0x6d, 0x25, 0x00, - 0x25, 0x25, 0x00, 0x36, 0x92, 0x81, 0x09, 0x49, 0x40, 0x09, 0x45, 0x00, - 0x14, 0x94, 0x00, 0x94, 0x94, 0x08, 0x4a, 0x4a, 0x00, 0x4a, 0x4a, 0x04, - 0x25, 0x25, 0x31, 0x05, 0x14, 0x01, 0x25, 0x25, 0x31, 0x09, 0x45, 0x31, - 0x09, 0x45, 0x00, 0x25, 0x14, 0x12, 0x25, 0x25, 0x00, 0x14, 0x94, 0xc0, - 0x4a, 0x29, 0x08, 0x4a, 0x4a, 0x00, 0x29, 0x28, 0x03, 0x9c, 0xa2, 0xa4, - 0xea, 0x0a, 0x50, 0xdc, 0x7e, 0x14, 0xa5, 0xb0, 0xe2, 0x76, 0xb6, 0xef, - 0xe6, 0xdb, 0xab, 0x7e, 0x1f, 0xa0, 0xa9, 0x97, 0xae, 0x6a, 0x21, 0xf0, - 0x83, 0xdc, 0xd3, 0x8f, 0xee, 0xd4, 0x95, 0x68, 0x90, 0xa2, 0x80, 0x16, - 0x8a, 0x00, 0x28, 0xa0, 0x02, 0x96, 0x80, 0x0a, 0x28, 0x00, 0xa2, 0x81, - 0x85, 0x2d, 0x02, 0x12, 0x8a, 0x06, 0x14, 0x50, 0x01, 0x45, 0x00, 0x14, - 0x50, 0x01, 0x45, 0x00, 0x14, 0x50, 0x01, 0x49, 0x40, 0x05, 0x14, 0x00, - 0x94, 0x50, 0x01, 0x49, 0x40, 0x09, 0x49, 0x40, 0x09, 0x49, 0x40, 0x09, - 0x49, 0x40, 0x09, 0x49, 0x40, 0x09, 0x4d, 0xa0, 0x04, 0xa4, 0xa0, 0x04, - 0xa4, 0xa0, 0x06, 0xd2, 0x50, 0x02, 0x52, 0x50, 0x21, 0x29, 0x28, 0x01, - 0xb4, 0x50, 0x03, 0x69, 0x28, 0x01, 0x29, 0x28, 0x10, 0x94, 0x94, 0x00, - 0x52, 0x50, 0x21, 0x29, 0x28, 0x01, 0x29, 0x28, 0x10, 0x94, 0x94, 0x00, - 0x86, 0x92, 0x98, 0x09, 0x45, 0x02, 0x24, 0xa2, 0xa8, 0x91, 0x28, 0xa0, - 0x42, 0x51, 0x40, 0x09, 0x45, 0x00, 0x25, 0x25, 0x31, 0x09, 0x45, 0x21, - 0x09, 0x45, 0x03, 0x12, 0x8a, 0x62, 0x12, 0x8a, 0x00, 0xe6, 0x8d, 0x2e, - 0x78, 0xa9, 0x3a, 0x80, 0x51, 0x40, 0x2d, 0xce, 0xb7, 0x44, 0x7f, 0x33, - 0x4c, 0x1f, 0xef, 0xb5, 0x5e, 0xed, 0x59, 0x53, 0xd8, 0x72, 0xf8, 0x8d, - 0x2b, 0x7e, 0x52, 0xa5, 0xab, 0x44, 0x8b, 0x4b, 0x40, 0x05, 0x14, 0x00, - 0xb4, 0x94, 0x00, 0xb4, 0x50, 0x01, 0x45, 0x00, 0x14, 0x50, 0x02, 0xd1, - 0x40, 0xc2, 0x8a, 0x00, 0x28, 0xa0, 0x02, 0x8a, 0x00, 0x28, 0xa0, 0x02, - 0x8a, 0x00, 0x28, 0xa0, 0x02, 0x8a, 0x00, 0x29, 0x28, 0x01, 0x28, 0xa0, - 0x04, 0xa2, 0x80, 0x12, 0x92, 0x80, 0x12, 0x92, 0x80, 0x12, 0x92, 0x80, - 0x12, 0x92, 0x80, 0x1b, 0x49, 0x40, 0x09, 0x49, 0x40, 0x09, 0x49, 0x40, - 0x0d, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa6, 0xd0, 0x02, 0x52, 0x50, - 0x21, 0x29, 0x28, 0x10, 0xda, 0x4a, 0x00, 0x29, 0x28, 0x01, 0x29, 0x28, - 0x10, 0x94, 0x94, 0x00, 0x94, 0x94, 0x00, 0x94, 0x94, 0xc4, 0x25, 0x25, - 0x02, 0x12, 0x8a, 0x40, 0x49, 0x45, 0x50, 0x84, 0xa4, 0xa6, 0x48, 0x52, - 0x53, 0x00, 0xa4, 0xa4, 0x01, 0x49, 0x40, 0x82, 0x92, 0x81, 0x09, 0x45, - 0x21, 0x89, 0x45, 0x31, 0x09, 0x45, 0x20, 0x39, 0xaa, 0x5e, 0x94, 0xec, - 0x75, 0x0a, 0x29, 0x31, 0x4a, 0xc0, 0x74, 0x7e, 0x19, 0x7c, 0xc3, 0x24, - 0x7f, 0xdd, 0x19, 0xff, 0x00, 0xc7, 0xab, 0x66, 0xb3, 0xa7, 0xd8, 0xa9, - 0xee, 0x5d, 0xb3, 0x6f, 0x92, 0xad, 0x55, 0x22, 0x18, 0xb4, 0x50, 0x01, - 0x4b, 0x40, 0x82, 0x8a, 0x06, 0x14, 0x53, 0x00, 0xa2, 0x90, 0x0b, 0x45, - 0x00, 0x14, 0x50, 0x30, 0xa5, 0xa0, 0x02, 0x8a, 0x00, 0x28, 0xa0, 0x02, - 0x8a, 0x00, 0x28, 0xa0, 0x02, 0x8a, 0x00, 0x28, 0xa0, 0x04, 0xa2, 0x80, - 0x12, 0x8a, 0x00, 0x29, 0x28, 0x01, 0x29, 0x28, 0x00, 0xa4, 0xa0, 0x06, - 0xd2, 0x50, 0x02, 0x52, 0x50, 0x02, 0x53, 0x68, 0x01, 0x29, 0x28, 0x01, - 0x29, 0xb4, 0x00, 0x94, 0x94, 0x00, 0x94, 0xda, 0x00, 0x29, 0xb4, 0x08, - 0x4a, 0x69, 0xa0, 0x04, 0xa4, 0xa0, 0x42, 0x52, 0x50, 0x02, 0x52, 0x50, - 0x02, 0x51, 0x40, 0x0d, 0xa4, 0xa6, 0x21, 0x29, 0x29, 0x00, 0x94, 0x94, - 0xc4, 0x06, 0x9b, 0x40, 0x09, 0x45, 0x02, 0x1f, 0x45, 0x32, 0x44, 0xa2, - 0x98, 0x05, 0x25, 0x00, 0x14, 0x50, 0x21, 0x29, 0x29, 0x80, 0x94, 0x50, - 0x21, 0x28, 0xa0, 0x02, 0x92, 0x90, 0x84, 0xa2, 0x98, 0x1c, 0xd5, 0x25, - 0x23, 0xa8, 0x70, 0xe9, 0x4b, 0x48, 0x0d, 0x9f, 0x0e, 0x49, 0xfe, 0x99, - 0x27, 0xfb, 0x5b, 0x57, 0xf5, 0xae, 0x88, 0x56, 0x50, 0xea, 0x54, 0xcb, - 0x56, 0x47, 0x9c, 0x55, 0xda, 0xa4, 0x4b, 0x16, 0x8a, 0x62, 0x16, 0x8a, - 0x00, 0x28, 0xa0, 0x02, 0x96, 0x98, 0x05, 0x14, 0x86, 0x14, 0x50, 0x21, - 0x68, 0xa0, 0x61, 0x45, 0x00, 0x2d, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, - 0x00, 0x51, 0x40, 0x05, 0x14, 0x00, 0x51, 0x40, 0x09, 0x45, 0x00, 0x14, - 0x94, 0x00, 0x52, 0x50, 0x02, 0x51, 0x40, 0x09, 0x49, 0x40, 0x09, 0x49, - 0x40, 0x0d, 0xa4, 0xa0, 0x04, 0xa6, 0xd0, 0x02, 0x52, 0x50, 0x02, 0x53, - 0x68, 0x01, 0x29, 0xb4, 0x00, 0x94, 0x94, 0x00, 0x94, 0x94, 0x00, 0xda, - 0x4a, 0x04, 0x25, 0x25, 0x00, 0x25, 0x25, 0x00, 0x25, 0x25, 0x02, 0x1b, - 0x45, 0x00, 0x25, 0x36, 0x81, 0x05, 0x21, 0xa0, 0x06, 0xd1, 0x40, 0x86, - 0xd2, 0x50, 0x02, 0x52, 0x50, 0x04, 0x9d, 0xa9, 0x2a, 0x90, 0x98, 0x52, - 0x53, 0x24, 0x28, 0xa0, 0x41, 0x49, 0x40, 0xc2, 0x8a, 0x04, 0x25, 0x25, - 0x30, 0x12, 0x92, 0x90, 0x85, 0xa4, 0xa4, 0x02, 0x51, 0x48, 0x0e, 0x62, - 0x96, 0xad, 0x9d, 0x21, 0x4a, 0x33, 0xde, 0x96, 0x80, 0x68, 0x68, 0x8f, - 0xb3, 0x53, 0x83, 0xde, 0x41, 0x5d, 0x68, 0xac, 0x97, 0xc4, 0x54, 0xb6, - 0x44, 0xf6, 0xa7, 0x12, 0xd6, 0x88, 0xe9, 0x54, 0x48, 0x52, 0xd0, 0x20, - 0xa2, 0x80, 0x16, 0x8a, 0x00, 0x28, 0xa6, 0x01, 0x4b, 0x48, 0x02, 0x8a, - 0x06, 0x14, 0xb4, 0x00, 0x51, 0x40, 0x05, 0x2d, 0x00, 0x14, 0x50, 0x01, - 0x45, 0x00, 0x14, 0x50, 0x01, 0x4b, 0x40, 0x09, 0x45, 0x00, 0x14, 0x94, - 0x00, 0x52, 0x52, 0x00, 0xa4, 0xa6, 0x02, 0x51, 0x40, 0x09, 0x49, 0x40, - 0x09, 0x49, 0x40, 0x0d, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x06, 0xd2, 0x50, - 0x03, 0x69, 0x28, 0x01, 0x0d, 0x36, 0x80, 0x12, 0x9b, 0x40, 0x09, 0x49, - 0x40, 0x09, 0x4d, 0xa0, 0x42, 0x52, 0x50, 0x02, 0x52, 0x1a, 0x00, 0x4a, - 0x6d, 0x00, 0x25, 0x14, 0x08, 0x6d, 0x25, 0x00, 0x25, 0x14, 0xc4, 0x36, - 0x92, 0x90, 0x84, 0xa4, 0xa6, 0x21, 0x29, 0x29, 0x00, 0xf1, 0x45, 0x31, - 0x05, 0x25, 0x31, 0x05, 0x25, 0x50, 0x85, 0xa4, 0xa4, 0x30, 0xa4, 0xa4, - 0x21, 0x28, 0xaa, 0x01, 0x29, 0x29, 0x12, 0x14, 0x52, 0xb8, 0xc4, 0xa4, - 0xa6, 0x17, 0x39, 0xaa, 0x4a, 0x47, 0x48, 0x52, 0x8a, 0x56, 0x02, 0x7b, - 0x39, 0x3c, 0xab, 0xa8, 0xe4, 0xfe, 0xef, 0x3f, 0xa5, 0x76, 0xeb, 0xf7, - 0x13, 0xfd, 0xd1, 0xfc, 0xab, 0x3f, 0xb6, 0x5c, 0xbe, 0x12, 0x48, 0xb8, - 0x90, 0x56, 0x9a, 0xf4, 0xaa, 0xea, 0x40, 0xb4, 0xb4, 0xc4, 0x14, 0xb4, - 0xc0, 0x28, 0xa4, 0x01, 0x45, 0x00, 0x2d, 0x14, 0x0c, 0x28, 0xa0, 0x42, - 0xd1, 0x40, 0xc2, 0x8a, 0x00, 0x29, 0x68, 0x00, 0xa2, 0x80, 0x0a, 0x5a, - 0x00, 0x28, 0xa0, 0x02, 0x8a, 0x00, 0x28, 0xa0, 0x04, 0xa2, 0x80, 0x0a, - 0x4a, 0x00, 0x29, 0x28, 0x01, 0x28, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa4, - 0xa0, 0x04, 0xa6, 0xd0, 0x02, 0x52, 0x50, 0x03, 0x69, 0x28, 0x01, 0xb4, - 0x94, 0x00, 0xda, 0x4a, 0x00, 0x6d, 0x25, 0x00, 0x25, 0x36, 0x80, 0x12, - 0x92, 0x81, 0x0d, 0xa2, 0x80, 0x1b, 0x49, 0x40, 0x0d, 0xa4, 0xa0, 0x04, - 0xa2, 0x81, 0x0d, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x91, - 0x29, 0xb4, 0xc0, 0x4a, 0x4a, 0x40, 0x3b, 0xb5, 0x2d, 0x32, 0x44, 0xa2, - 0x81, 0x05, 0x2d, 0x50, 0x84, 0xa2, 0x90, 0x09, 0x49, 0x4c, 0x05, 0xa4, - 0xa6, 0x21, 0x29, 0x29, 0x00, 0x52, 0x54, 0x80, 0x51, 0x40, 0x8e, 0x6f, - 0x63, 0x51, 0xe5, 0x9a, 0xd5, 0x9d, 0x43, 0x71, 0x8a, 0x75, 0x64, 0x03, - 0x4f, 0xdd, 0x3c, 0xf6, 0xae, 0xea, 0xd9, 0xfc, 0xcb, 0x65, 0x6f, 0xc3, - 0xf4, 0x15, 0x1f, 0x6c, 0xbb, 0xfb, 0xa4, 0xc3, 0xad, 0x6a, 0x27, 0xdd, - 0xaa, 0x7b, 0x90, 0x3a, 0x9d, 0x4c, 0x41, 0x45, 0x20, 0x0a, 0x29, 0x80, - 0xb4, 0x50, 0x01, 0x45, 0x20, 0x0a, 0x5a, 0x06, 0x14, 0x50, 0x02, 0xd1, - 0x40, 0x05, 0x14, 0x00, 0xb4, 0x50, 0x01, 0x45, 0x00, 0x14, 0x50, 0x02, - 0xd1, 0x40, 0x05, 0x14, 0x00, 0x51, 0x40, 0x09, 0x49, 0x40, 0x05, 0x25, - 0x00, 0x25, 0x14, 0x00, 0x94, 0x94, 0x00, 0x94, 0x94, 0x80, 0x4a, 0x4a, - 0x60, 0x36, 0x92, 0x80, 0x1b, 0x49, 0x40, 0x0d, 0xa6, 0xd0, 0x02, 0x53, - 0x68, 0x01, 0x29, 0xb4, 0x00, 0x94, 0x94, 0x00, 0x94, 0xda, 0x00, 0x69, - 0xa4, 0x34, 0x08, 0x4a, 0x69, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, - 0x42, 0x52, 0x50, 0x02, 0x52, 0x50, 0x21, 0x29, 0x28, 0x01, 0x29, 0xb4, - 0xc0, 0x43, 0x49, 0x48, 0x07, 0x0a, 0x29, 0x92, 0x25, 0x2d, 0x31, 0x05, - 0x25, 0x31, 0x0b, 0x49, 0x40, 0x05, 0x14, 0x84, 0x25, 0x14, 0xc4, 0x25, - 0x25, 0x00, 0x14, 0x94, 0x08, 0x29, 0x31, 0x48, 0x66, 0x16, 0xf1, 0xdc, - 0x53, 0xc4, 0x8b, 0xf8, 0x55, 0x33, 0xa4, 0x3e, 0x43, 0x4d, 0xd8, 0xb4, - 0xae, 0x03, 0x4c, 0x60, 0xd7, 0x55, 0xa2, 0x36, 0xed, 0x34, 0x7f, 0xbe, - 0xd5, 0x9b, 0xf8, 0x91, 0x4b, 0xe1, 0x2f, 0x76, 0xad, 0x38, 0x0f, 0xc9, - 0x4d, 0xee, 0x49, 0x2d, 0x2d, 0x02, 0x0a, 0x29, 0x80, 0xb4, 0x52, 0x00, - 0xa2, 0x98, 0x05, 0x2d, 0x00, 0x14, 0xb4, 0x0c, 0x4a, 0x5a, 0x40, 0x14, - 0x50, 0x02, 0xd1, 0x40, 0x05, 0x2d, 0x00, 0x14, 0x50, 0x01, 0x4b, 0x40, - 0x05, 0x14, 0x00, 0x51, 0x40, 0x05, 0x25, 0x00, 0x14, 0x94, 0x00, 0x51, - 0x40, 0x09, 0x49, 0x40, 0x09, 0x49, 0x40, 0x05, 0x25, 0x00, 0x36, 0x92, - 0x90, 0x09, 0x4d, 0xa6, 0x03, 0x69, 0x28, 0x01, 0xb4, 0xd3, 0x40, 0x0d, - 0xa6, 0xd0, 0x02, 0x52, 0x50, 0x03, 0x69, 0x28, 0x01, 0x29, 0xb4, 0x00, - 0xd3, 0x4d, 0xa0, 0x04, 0xa4, 0xa0, 0x42, 0x53, 0x68, 0x00, 0xa4, 0xa0, - 0x04, 0xa6, 0xd0, 0x21, 0x29, 0x28, 0x01, 0x29, 0x28, 0x01, 0x29, 0x28, - 0x24, 0x4a, 0x4a, 0x00, 0x51, 0x4b, 0x4c, 0x42, 0x51, 0x4c, 0x41, 0x45, - 0x00, 0x2d, 0x25, 0x04, 0x89, 0x45, 0x30, 0x0a, 0x4a, 0x04, 0x25, 0x14, - 0x00, 0x94, 0x51, 0x70, 0x12, 0x8a, 0x04, 0x73, 0xa4, 0xd2, 0x66, 0x9d, - 0x8e, 0xa0, 0xcd, 0x2e, 0xef, 0x7a, 0x90, 0x1f, 0x9a, 0xe8, 0xbc, 0x37, - 0x26, 0x60, 0x74, 0xcf, 0x40, 0x4f, 0xfe, 0x3d, 0x59, 0x4b, 0xa1, 0x6b, - 0x63, 0x62, 0xaf, 0x59, 0x9c, 0xa5, 0x5c, 0x88, 0x2c, 0xd2, 0xd3, 0x10, - 0x51, 0x48, 0x05, 0xa2, 0x80, 0x0a, 0x5a, 0x06, 0x14, 0x50, 0x20, 0xa5, - 0xa0, 0x61, 0x45, 0x00, 0x2d, 0x14, 0x00, 0x51, 0x40, 0x0b, 0x45, 0x00, - 0x14, 0xb4, 0x00, 0x51, 0x40, 0x05, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, - 0x00, 0x94, 0x52, 0x00, 0xa4, 0xa6, 0x01, 0x49, 0x48, 0x02, 0x92, 0x80, - 0x12, 0x92, 0x98, 0x09, 0x4d, 0xa0, 0x04, 0xa6, 0xd0, 0x02, 0x53, 0x4d, - 0x20, 0x1a, 0x69, 0xb4, 0xc0, 0x61, 0xa4, 0xa0, 0x06, 0xd3, 0x68, 0x01, - 0x29, 0xb4, 0x80, 0x6d, 0x36, 0x80, 0x12, 0x92, 0x80, 0x1b, 0x45, 0x30, - 0x12, 0x92, 0x80, 0x12, 0x92, 0x81, 0x09, 0x4d, 0xa4, 0x02, 0x52, 0x53, - 0x01, 0x29, 0x28, 0x24, 0x6d, 0x25, 0x00, 0x25, 0x25, 0x02, 0x0a, 0x75, - 0x02, 0x12, 0x8a, 0x60, 0x14, 0x50, 0x21, 0x68, 0xa6, 0x21, 0x28, 0xa6, - 0x02, 0x51, 0x40, 0x84, 0xa2, 0x90, 0x84, 0xa2, 0x80, 0x12, 0x8a, 0x62, - 0x39, 0xb6, 0xa6, 0xd5, 0x33, 0xa8, 0x5a, 0x5c, 0xd6, 0x7a, 0x85, 0xc7, - 0x56, 0xcf, 0x86, 0x24, 0xff, 0x00, 0x4a, 0x91, 0x7d, 0x42, 0x8f, 0xd6, - 0xa2, 0x65, 0x44, 0xe9, 0x2a, 0xdd, 0x97, 0x71, 0x57, 0x32, 0x11, 0x76, - 0x8a, 0x00, 0x29, 0x68, 0x00, 0xa2, 0x90, 0x05, 0x2d, 0x03, 0x0a, 0x5a, - 0x00, 0x28, 0xa0, 0x02, 0x96, 0x80, 0x0a, 0x28, 0x01, 0x68, 0xa0, 0x05, - 0xa2, 0x80, 0x0a, 0x5a, 0x00, 0x4a, 0x5a, 0x00, 0x28, 0xa0, 0x02, 0x8a, - 0x06, 0x14, 0x94, 0x00, 0x52, 0x50, 0x01, 0x45, 0x20, 0x12, 0x8a, 0x00, - 0x4a, 0x28, 0x10, 0x94, 0x94, 0x00, 0x94, 0xda, 0x00, 0x4a, 0x6d, 0x30, - 0x12, 0x9a, 0x68, 0x01, 0x86, 0x9a, 0x68, 0x01, 0xa6, 0x9b, 0x40, 0x0d, - 0x34, 0xda, 0x90, 0x1b, 0x4d, 0xa0, 0x06, 0xd3, 0x68, 0x01, 0x29, 0x28, - 0x00, 0xa6, 0xd3, 0x01, 0x29, 0x28, 0x01, 0x28, 0xdb, 0x40, 0x06, 0xda, - 0x4d, 0xb4, 0x08, 0x42, 0x2a, 0x33, 0x4c, 0x43, 0x68, 0xa4, 0x02, 0x52, - 0x53, 0x10, 0x94, 0xda, 0x00, 0x51, 0x4b, 0x40, 0x84, 0xa2, 0x82, 0x42, - 0x8a, 0xa0, 0x16, 0x8a, 0x62, 0x0a, 0x4a, 0x04, 0x14, 0x50, 0x02, 0x51, - 0x48, 0x04, 0xa2, 0x98, 0x84, 0xa2, 0x81, 0x1c, 0xd9, 0xa6, 0xd6, 0x96, - 0xb1, 0xd2, 0x14, 0x56, 0x4d, 0x8c, 0x5a, 0xd2, 0xd0, 0x5f, 0x6e, 0xad, - 0x07, 0xbb, 0x8a, 0x8a, 0x9a, 0xa2, 0xa0, 0x75, 0xc3, 0xa5, 0x58, 0xb4, - 0x3f, 0xbc, 0xaa, 0x96, 0xc4, 0xa3, 0x43, 0xb5, 0x14, 0x21, 0x0b, 0x45, - 0x00, 0x14, 0x50, 0x31, 0x68, 0xa4, 0x20, 0xa5, 0xa0, 0x61, 0x45, 0x00, - 0x2d, 0x14, 0x00, 0xb4, 0x50, 0x02, 0xd1, 0x40, 0x05, 0x2d, 0x00, 0x14, - 0x50, 0x01, 0x4b, 0x40, 0x09, 0x45, 0x00, 0x14, 0x50, 0x30, 0xa2, 0x80, - 0x0a, 0x4a, 0x40, 0x14, 0x94, 0x00, 0x52, 0x50, 0x20, 0xa4, 0xa0, 0x62, - 0x52, 0x50, 0x20, 0xa4, 0xa0, 0x06, 0xd2, 0x50, 0x03, 0x69, 0xa6, 0x98, - 0x0c, 0x34, 0xce, 0xf8, 0xf5, 0xa0, 0x08, 0x16, 0x5d, 0xc7, 0x14, 0xea, - 0x4c, 0x06, 0xd3, 0x69, 0x00, 0xda, 0x6d, 0x00, 0x36, 0x9b, 0x40, 0x09, - 0xba, 0x96, 0x80, 0x0c, 0x66, 0x93, 0x14, 0xc0, 0x4a, 0x6e, 0x68, 0x10, - 0x99, 0xa3, 0x75, 0x2b, 0x80, 0xdd, 0xe2, 0x93, 0x7d, 0x3b, 0x80, 0xc3, - 0x20, 0xa4, 0x6a, 0x2e, 0x21, 0x94, 0x50, 0x31, 0x28, 0xa6, 0x21, 0xb4, - 0x94, 0x08, 0x4a, 0x5a, 0x04, 0x14, 0x53, 0x10, 0x52, 0xd2, 0x10, 0x51, - 0x54, 0x48, 0x51, 0x40, 0x09, 0x45, 0x30, 0x12, 0x96, 0xa4, 0x04, 0xa4, - 0xa6, 0x20, 0xa4, 0xa1, 0x01, 0xce, 0x37, 0x5e, 0x29, 0xb8, 0xad, 0xeb, - 0x7c, 0x4c, 0xe9, 0x12, 0x96, 0xb0, 0x00, 0xab, 0x36, 0x12, 0x79, 0x57, - 0x90, 0xc9, 0xfd, 0xd3, 0x9f, 0xd2, 0xa6, 0x7b, 0x15, 0x0d, 0xce, 0xe1, - 0x7e, 0xe2, 0x7f, 0xba, 0x3f, 0x95, 0x4d, 0x07, 0x12, 0x8a, 0x7f, 0x60, - 0x9e, 0xa6, 0x90, 0xe9, 0x4b, 0x42, 0x10, 0x51, 0x40, 0x0b, 0x45, 0x00, - 0x14, 0x50, 0x31, 0x68, 0xa4, 0x01, 0x4b, 0x40, 0x05, 0x2d, 0x00, 0x14, - 0x50, 0x02, 0xd1, 0x40, 0x0b, 0x45, 0x00, 0x14, 0x50, 0x02, 0xd1, 0x40, - 0x05, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, 0x0c, 0x4a, 0x29, 0x00, 0x94, - 0x50, 0x01, 0x4d, 0xa0, 0x02, 0x8a, 0x04, 0x25, 0x25, 0x00, 0x25, 0x25, - 0x30, 0x0a, 0x69, 0xa0, 0x06, 0xd3, 0x71, 0x9a, 0x00, 0x5f, 0x28, 0xfa, - 0x54, 0x32, 0xdb, 0x4a, 0x4a, 0xed, 0x1d, 0x29, 0xa0, 0x21, 0x5b, 0x09, - 0x95, 0xf7, 0x71, 0xf9, 0xd4, 0x8d, 0x1e, 0x3a, 0xd2, 0x60, 0x42, 0xd5, - 0x19, 0xa4, 0x02, 0x1a, 0x6d, 0x48, 0x0c, 0x34, 0xc3, 0x4c, 0x08, 0x9d, - 0xb1, 0x53, 0x7f, 0x0d, 0x00, 0x34, 0x1a, 0x5c, 0xd3, 0x01, 0x8e, 0xf8, - 0x15, 0x4c, 0xde, 0x0d, 0xf8, 0xe9, 0x45, 0x84, 0x3f, 0xcd, 0xa8, 0xfc, - 0xef, 0x9f, 0x19, 0xa4, 0x21, 0xcc, 0x78, 0xa8, 0x43, 0xf3, 0xcd, 0x21, - 0x11, 0xca, 0x70, 0xe1, 0xbd, 0x2a, 0xef, 0xf0, 0x0f, 0xa5, 0x30, 0x19, - 0x45, 0x31, 0x89, 0x49, 0x4c, 0x02, 0x92, 0x81, 0x0d, 0xa2, 0x81, 0x0b, - 0x45, 0x32, 0x45, 0xa2, 0x98, 0x05, 0x2d, 0x21, 0x09, 0x4b, 0x4c, 0x42, - 0x51, 0x40, 0x84, 0xa2, 0x80, 0x0a, 0x4a, 0x00, 0x4a, 0x29, 0x81, 0xce, - 0x51, 0xb4, 0xd5, 0xb6, 0x74, 0x86, 0xda, 0x36, 0xd6, 0x63, 0x48, 0x00, - 0xa3, 0xee, 0xe4, 0x8f, 0x4a, 0x96, 0x38, 0xee, 0x77, 0x96, 0xcc, 0x1e, - 0xdd, 0x48, 0x3e, 0xdf, 0xa0, 0xa9, 0x97, 0x86, 0x14, 0xd7, 0xc0, 0x4b, - 0xf8, 0x8d, 0x44, 0xfb, 0xb4, 0xea, 0x48, 0x42, 0xd1, 0x4c, 0x02, 0x8a, - 0x00, 0x29, 0x68, 0x00, 0xa2, 0x90, 0xc5, 0xa2, 0x80, 0x0a, 0x28, 0x01, - 0x68, 0xa0, 0x05, 0xa2, 0x80, 0x16, 0x8a, 0x00, 0x29, 0x68, 0x00, 0xa2, - 0x80, 0x0a, 0x28, 0x18, 0x51, 0x40, 0x05, 0x14, 0x80, 0x29, 0x28, 0x00, - 0xa4, 0xa0, 0x02, 0x92, 0x90, 0x05, 0x25, 0x31, 0x05, 0x25, 0x00, 0x25, - 0x25, 0x00, 0x25, 0x25, 0x30, 0x1b, 0x42, 0x7d, 0xf1, 0x40, 0x17, 0x14, - 0xe0, 0x53, 0x5e, 0x5a, 0x00, 0xa9, 0x2c, 0x84, 0xd5, 0x66, 0xa0, 0x08, - 0x1e, 0xa3, 0xa4, 0x02, 0x53, 0x49, 0xa4, 0x04, 0x66, 0x9a, 0x68, 0x02, - 0x19, 0x7a, 0x54, 0x90, 0xbe, 0x62, 0xa1, 0x80, 0x77, 0xa1, 0xce, 0x05, - 0x50, 0x15, 0x5a, 0x5d, 0xdc, 0x54, 0x12, 0x28, 0x54, 0x26, 0x80, 0x14, - 0xfc, 0xe9, 0xc5, 0x34, 0x45, 0xce, 0x6a, 0x09, 0x15, 0x81, 0xc8, 0xa4, - 0xef, 0x40, 0x81, 0x86, 0xe5, 0x23, 0xbd, 0x4e, 0xad, 0x8e, 0x0d, 0x03, - 0x48, 0x43, 0x49, 0x54, 0x30, 0xa2, 0x81, 0x09, 0x49, 0x40, 0x09, 0x49, - 0x40, 0x82, 0x96, 0x99, 0x2c, 0x29, 0x6a, 0x84, 0x14, 0xb4, 0xc4, 0x14, - 0x50, 0x20, 0xa4, 0xa0, 0x41, 0x45, 0x03, 0x12, 0x8a, 0x42, 0x12, 0x8c, - 0xd1, 0xb8, 0x18, 0x0b, 0xef, 0x4e, 0xa0, 0xee, 0x12, 0x99, 0x83, 0x48, - 0x04, 0xa4, 0xaa, 0xe8, 0x66, 0xb7, 0x3b, 0x3d, 0x0e, 0x4f, 0x37, 0x4b, - 0x53, 0xfe, 0xdb, 0x55, 0xea, 0x54, 0xd7, 0xb8, 0x29, 0x7c, 0x46, 0x9c, - 0x07, 0xe4, 0xa9, 0x2a, 0x50, 0x82, 0x96, 0x98, 0x05, 0x2d, 0x00, 0x14, - 0x50, 0x01, 0x4b, 0x48, 0x61, 0x45, 0x00, 0x14, 0xb4, 0xc0, 0x28, 0xa4, - 0x03, 0xa8, 0xa0, 0x02, 0x8a, 0x00, 0x5a, 0x28, 0x00, 0xa2, 0x80, 0x0a, - 0x28, 0x01, 0x69, 0x29, 0x00, 0x51, 0x4c, 0x61, 0x49, 0x40, 0x05, 0x25, - 0x20, 0x0a, 0x28, 0x01, 0x28, 0xa0, 0x04, 0xa2, 0x80, 0x1b, 0x49, 0x40, - 0x84, 0xa6, 0x93, 0x4c, 0x05, 0x48, 0x99, 0xea, 0x65, 0x80, 0x2d, 0x00, - 0x29, 0xa8, 0x9a, 0x80, 0x2b, 0xbd, 0x42, 0x68, 0x02, 0x09, 0x2a, 0x23, - 0x48, 0x06, 0xd3, 0x0d, 0x48, 0x0d, 0xa6, 0x1a, 0x60, 0x43, 0x2f, 0x4a, - 0x4b, 0x57, 0xea, 0x3d, 0x28, 0x60, 0x4a, 0x4d, 0x38, 0xfc, 0xeb, 0x54, - 0x06, 0x63, 0x26, 0xd6, 0xa9, 0x67, 0x1e, 0x64, 0x25, 0x47, 0x71, 0x43, - 0xdc, 0x43, 0x2d, 0xd0, 0xc7, 0x16, 0xd6, 0x39, 0xe4, 0x9a, 0x5f, 0x30, - 0x54, 0x00, 0xc3, 0x32, 0xd3, 0x37, 0xb3, 0x74, 0xa0, 0x40, 0x1d, 0xd1, - 0xd7, 0x7f, 0x4c, 0xd5, 0xae, 0xb4, 0x0c, 0x43, 0x49, 0x54, 0x01, 0x45, - 0x02, 0x12, 0x92, 0x90, 0x84, 0xa4, 0xaa, 0x01, 0x28, 0xcd, 0x04, 0x8b, - 0x9a, 0x75, 0x32, 0x42, 0x96, 0xa8, 0x02, 0x8a, 0x42, 0x0a, 0x4a, 0x04, - 0x14, 0x53, 0x00, 0xa2, 0x81, 0x09, 0x45, 0x20, 0x39, 0xfc, 0xd2, 0x83, - 0x49, 0x9d, 0xd1, 0x1d, 0x9a, 0x61, 0xeb, 0x49, 0x14, 0x34, 0x9a, 0x07, - 0x4a, 0xb4, 0x62, 0xce, 0xa3, 0xc2, 0xf2, 0xee, 0xb5, 0x68, 0xff, 0x00, - 0xbb, 0x96, 0xff, 0x00, 0xc7, 0xab, 0x66, 0xa6, 0x97, 0xc2, 0x13, 0xf8, - 0x8b, 0xd6, 0x87, 0x29, 0x56, 0x29, 0x21, 0x31, 0x68, 0xa6, 0x01, 0x4b, - 0x40, 0x05, 0x14, 0x0c, 0x28, 0xa0, 0x05, 0xa2, 0x80, 0x0a, 0x28, 0x01, - 0x69, 0x69, 0x00, 0x52, 0xd0, 0x01, 0x4b, 0x40, 0x05, 0x14, 0x00, 0x51, - 0x40, 0x0b, 0x45, 0x20, 0x0a, 0x28, 0x18, 0x52, 0x53, 0x00, 0xa4, 0xa0, - 0x61, 0x45, 0x20, 0x0a, 0x28, 0x10, 0x94, 0x94, 0x00, 0x94, 0x94, 0x00, - 0x94, 0x94, 0x08, 0x4a, 0x86, 0x5a, 0x68, 0x0b, 0x96, 0xaf, 0xbe, 0x2a, - 0x94, 0xd1, 0x10, 0x23, 0x6a, 0x85, 0xa8, 0x02, 0x07, 0xa8, 0x1a, 0x80, - 0x20, 0x97, 0xa5, 0x40, 0x4d, 0x4b, 0x01, 0x84, 0xd3, 0x73, 0x48, 0x63, - 0x69, 0xa4, 0xd0, 0x04, 0x0e, 0xd5, 0x52, 0xda, 0x5d, 0xb3, 0xed, 0xcf, - 0x5e, 0x29, 0xbd, 0x80, 0xb8, 0xd2, 0x2f, 0x72, 0x2a, 0x2f, 0xb7, 0x43, - 0x1f, 0xde, 0x6a, 0x40, 0x67, 0xdd, 0xea, 0x11, 0x6e, 0xf9, 0x7f, 0x95, - 0x3a, 0xd6, 0xfa, 0x39, 0x46, 0xd2, 0x7e, 0x61, 0x4a, 0x57, 0x11, 0x66, - 0x47, 0xfd, 0xd9, 0xe7, 0x1c, 0x53, 0x3c, 0xa1, 0x8c, 0xd2, 0xb8, 0x86, - 0x05, 0x19, 0xe9, 0x52, 0x6d, 0x2b, 0xcd, 0x51, 0x23, 0x2e, 0x33, 0xe5, - 0xd3, 0xe0, 0x98, 0x3a, 0x66, 0xa5, 0x8d, 0x13, 0x75, 0xa6, 0xd5, 0xad, - 0x86, 0x14, 0x50, 0x02, 0x52, 0x1a, 0x04, 0x26, 0x69, 0xb9, 0xa1, 0x08, - 0x4c, 0xd2, 0xd5, 0x5c, 0x41, 0x9a, 0x5c, 0xd0, 0x48, 0xb9, 0xa5, 0xa6, - 0x21, 0x68, 0xa6, 0x20, 0xa2, 0x98, 0x05, 0x14, 0x00, 0x94, 0x52, 0x24, - 0x28, 0xa0, 0x67, 0x39, 0xd6, 0x9d, 0xf3, 0x55, 0x58, 0xe9, 0x1f, 0xb4, - 0xf7, 0xa3, 0x61, 0x35, 0x08, 0xab, 0x89, 0xe5, 0xe0, 0xd3, 0x31, 0x83, - 0x55, 0x62, 0x4d, 0xdf, 0x0a, 0x3f, 0xfa, 0x4c, 0xc9, 0xea, 0xa3, 0xff, - 0x00, 0x42, 0xae, 0x92, 0x95, 0x25, 0xba, 0x09, 0x96, 0xec, 0xcd, 0x5c, - 0xa9, 0x00, 0xa2, 0x98, 0x82, 0x8a, 0x00, 0x29, 0x68, 0x18, 0x51, 0x48, - 0x02, 0x96, 0x80, 0x0a, 0x5a, 0x00, 0x5a, 0x29, 0x80, 0x52, 0xd2, 0x00, - 0xa5, 0xa0, 0x02, 0x8a, 0x00, 0x28, 0xa0, 0x05, 0xa2, 0x81, 0x85, 0x14, - 0x80, 0x29, 0x28, 0x00, 0xa2, 0x81, 0x89, 0x45, 0x02, 0x0a, 0x4a, 0x40, - 0x14, 0x94, 0x00, 0x53, 0x69, 0x80, 0x94, 0x94, 0x00, 0xda, 0x86, 0x6e, - 0x94, 0x08, 0x7d, 0x8c, 0x98, 0x97, 0x6f, 0xaf, 0x15, 0xa1, 0x4d, 0x03, - 0x23, 0x6a, 0x85, 0xa9, 0x81, 0x5d, 0xea, 0x07, 0xa4, 0x04, 0x32, 0x74, - 0xaa, 0x84, 0xd4, 0x81, 0x19, 0x6a, 0x89, 0xee, 0x23, 0x5e, 0xae, 0x3f, - 0x3a, 0x91, 0x95, 0xa4, 0xd4, 0xa0, 0x4e, 0xad, 0x55, 0x24, 0xd6, 0x93, - 0xf8, 0x56, 0xab, 0x95, 0xb1, 0x14, 0xe5, 0xd5, 0xe4, 0x6f, 0xba, 0xa0, - 0x55, 0x46, 0xbb, 0x90, 0xb6, 0x7a, 0x53, 0x51, 0x01, 0x8d, 0x3c, 0x8d, - 0xd5, 0xcd, 0x46, 0x49, 0xa6, 0x02, 0x52, 0x86, 0x2a, 0x73, 0x45, 0x80, - 0xd3, 0x4b, 0xcf, 0x3a, 0x06, 0x07, 0xef, 0x55, 0xe5, 0x62, 0x63, 0xac, - 0xb6, 0x18, 0x80, 0xe0, 0xd4, 0xbe, 0x68, 0xc5, 0x16, 0x64, 0x91, 0x33, - 0x13, 0x50, 0xdb, 0x9c, 0x4a, 0x57, 0xf1, 0xaa, 0xe8, 0x4a, 0x2f, 0x25, - 0x21, 0xa1, 0x6c, 0x31, 0x28, 0xa2, 0xc0, 0x25, 0x25, 0x30, 0x1a, 0x4d, - 0x37, 0x34, 0x80, 0x4c, 0xd1, 0x9a, 0x64, 0x8b, 0x46, 0x6a, 0x84, 0x00, - 0xd3, 0xb3, 0x4c, 0x07, 0x66, 0x96, 0x82, 0x45, 0xa2, 0x98, 0x82, 0x92, - 0x81, 0x05, 0x14, 0x00, 0x51, 0x45, 0x80, 0xe7, 0x3a, 0x51, 0xbc, 0x8a, - 0xa6, 0xce, 0x91, 0xde, 0x69, 0xa6, 0x99, 0x18, 0xd2, 0x40, 0x33, 0x71, - 0xa3, 0x34, 0x80, 0xd5, 0xf0, 0xe4, 0x9b, 0x35, 0x58, 0x47, 0xf7, 0x98, - 0x0a, 0xec, 0x3b, 0x52, 0xa7, 0xf1, 0x30, 0xa9, 0xd0, 0xb1, 0x6a, 0x7e, - 0x7a, 0xbd, 0x47, 0x50, 0x0a, 0x29, 0x88, 0x5a, 0x29, 0x00, 0x51, 0x40, - 0x05, 0x2d, 0x21, 0x85, 0x2d, 0x00, 0x14, 0xb4, 0x00, 0x52, 0xd0, 0x02, - 0xd1, 0x40, 0x05, 0x14, 0x00, 0x52, 0xd0, 0x01, 0x45, 0x00, 0x2d, 0x25, - 0x20, 0x16, 0x8a, 0x06, 0x14, 0x94, 0x00, 0x52, 0x50, 0x30, 0xa2, 0x90, - 0x09, 0x45, 0x00, 0x14, 0x94, 0xc0, 0x4a, 0x4a, 0x04, 0x25, 0x36, 0x80, - 0x1b, 0x9a, 0x86, 0x63, 0xf2, 0xd3, 0x11, 0x02, 0x3e, 0xc7, 0x07, 0xd2, - 0xb6, 0x50, 0xee, 0x40, 0x68, 0xea, 0x03, 0x5a, 0xa0, 0x6a, 0x60, 0x40, - 0xf5, 0x5d, 0xea, 0x40, 0x8d, 0xfa, 0x56, 0x73, 0xb7, 0x3d, 0x69, 0x01, - 0x85, 0xab, 0xea, 0x5c, 0x6c, 0x85, 0xfe, 0xb5, 0x90, 0x65, 0x76, 0xea, - 0xd5, 0x62, 0x43, 0x73, 0x49, 0x9a, 0x43, 0x0a, 0x4c, 0xd0, 0x02, 0xd2, - 0x50, 0x20, 0xa2, 0x80, 0x00, 0x7d, 0xeb, 0x5a, 0xca, 0xe8, 0x3a, 0x6c, - 0xfe, 0x2c, 0xd4, 0x4c, 0x65, 0xce, 0xd5, 0x2a, 0xc4, 0x2a, 0x6e, 0x48, - 0xbe, 0x58, 0xaa, 0x73, 0x83, 0x1c, 0xc8, 0xfd, 0xb3, 0xcd, 0x52, 0xd8, - 0x0b, 0x4a, 0xc7, 0x14, 0x67, 0x34, 0x90, 0xc3, 0x34, 0x55, 0x5c, 0x04, - 0x34, 0x94, 0x84, 0x21, 0xa8, 0xe8, 0x01, 0x33, 0x4b, 0x54, 0x21, 0x29, - 0x73, 0x4c, 0x40, 0x29, 0xf4, 0x5c, 0x91, 0xc2, 0x9d, 0x4c, 0x42, 0xd1, - 0x4c, 0x90, 0xa2, 0x90, 0x05, 0x25, 0x50, 0x05, 0x25, 0x24, 0x23, 0x9c, - 0xcd, 0x25, 0x5a, 0x48, 0xea, 0x41, 0x49, 0x48, 0x02, 0x96, 0x86, 0x80, - 0xb7, 0xa5, 0xbf, 0x97, 0xa8, 0xc0, 0xde, 0x8d, 0x9f, 0xd0, 0xd7, 0x74, - 0xbc, 0xc6, 0x87, 0xd5, 0x47, 0xf2, 0xa8, 0x87, 0xf1, 0x02, 0x7b, 0x12, - 0xc1, 0xfe, 0xb0, 0x56, 0x88, 0xe9, 0x47, 0x50, 0x0a, 0x5a, 0x04, 0x14, - 0x50, 0x01, 0x45, 0x00, 0x14, 0xb4, 0x0c, 0x29, 0x68, 0x00, 0xa5, 0xa4, - 0x02, 0xd1, 0x40, 0x0b, 0x45, 0x00, 0x14, 0x50, 0x01, 0x45, 0x00, 0x14, - 0xb4, 0x00, 0x51, 0x40, 0xc2, 0x8a, 0x00, 0x29, 0x29, 0x0c, 0x29, 0x29, - 0x00, 0x51, 0x40, 0x05, 0x25, 0x00, 0x14, 0x94, 0x00, 0x94, 0x99, 0xa6, - 0x21, 0xa4, 0xd4, 0x65, 0xe9, 0x01, 0x13, 0x4a, 0x05, 0x40, 0xf2, 0xe6, - 0x98, 0x10, 0x96, 0xad, 0x5d, 0x3a, 0x6d, 0xf1, 0x6d, 0xcf, 0x23, 0x9a, - 0x43, 0x2c, 0xb5, 0x40, 0xd5, 0x44, 0x90, 0xbd, 0x56, 0x92, 0x80, 0x21, - 0x93, 0xee, 0xd7, 0x35, 0xaa, 0xdc, 0xb4, 0x28, 0x48, 0x26, 0x9c, 0x50, - 0x33, 0x9c, 0x63, 0x97, 0x24, 0xd0, 0x0d, 0x30, 0x16, 0x8a, 0x90, 0x0a, - 0x29, 0x80, 0x52, 0x52, 0x10, 0x51, 0x40, 0xc2, 0x9c, 0xad, 0xb4, 0xe4, - 0x50, 0xc0, 0xd9, 0xb4, 0xbb, 0x59, 0xd3, 0x07, 0xef, 0xd5, 0xd5, 0x6e, - 0x2b, 0x9c, 0x07, 0x8e, 0x45, 0x24, 0x91, 0x6e, 0x5a, 0xd1, 0x09, 0x82, - 0x47, 0xf2, 0xf2, 0x69, 0x7c, 0xae, 0x3e, 0xf5, 0x52, 0x11, 0x17, 0x7a, - 0x28, 0x18, 0x52, 0x52, 0x10, 0xda, 0x61, 0xa4, 0x02, 0x51, 0x4c, 0x42, - 0x52, 0xd5, 0x80, 0x53, 0xb3, 0x45, 0x89, 0x1c, 0x29, 0xc2, 0x82, 0x07, - 0x51, 0x54, 0x20, 0xa2, 0x81, 0x85, 0x14, 0x08, 0x28, 0xa4, 0x07, 0x33, - 0x4b, 0x4d, 0x9d, 0x22, 0xf6, 0xa6, 0xd3, 0x01, 0x73, 0x4b, 0xda, 0x90, - 0x0e, 0x56, 0xda, 0x77, 0x0e, 0xd9, 0xfe, 0x55, 0xe8, 0x16, 0xe7, 0x75, - 0xba, 0x1f, 0x61, 0xfc, 0x85, 0x4a, 0xfe, 0x20, 0x3f, 0x84, 0x99, 0x3e, - 0xf0, 0xad, 0x15, 0xfb, 0xb4, 0xde, 0xe0, 0x3a, 0x8a, 0x62, 0x0a, 0x5a, - 0x40, 0x14, 0x50, 0x01, 0x45, 0x03, 0x0a, 0x5a, 0x40, 0x14, 0xb4, 0x00, - 0x52, 0xd0, 0x01, 0x45, 0x00, 0x2d, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, - 0x0c, 0x4a, 0x29, 0x0c, 0x33, 0x49, 0x9a, 0x40, 0x19, 0xa3, 0x34, 0x86, - 0x14, 0x94, 0xc0, 0x29, 0x68, 0x00, 0xa4, 0xa4, 0x21, 0x29, 0x29, 0x80, - 0x99, 0xa6, 0x3b, 0x60, 0x53, 0x11, 0x55, 0xee, 0x2a, 0xbb, 0x4d, 0xef, - 0x52, 0x02, 0x67, 0x34, 0xc3, 0x4c, 0x64, 0x64, 0xd5, 0xbd, 0x36, 0x6d, - 0xb7, 0x20, 0x7f, 0x7a, 0xa5, 0x94, 0x6c, 0xf6, 0xa8, 0x5e, 0xb4, 0x33, - 0x2b, 0xb5, 0x57, 0x92, 0x80, 0x21, 0x6a, 0xe4, 0xf5, 0xcf, 0xf5, 0x67, - 0xf1, 0xaa, 0x80, 0xa4, 0x60, 0x9a, 0x4a, 0x43, 0x1e, 0x0d, 0x2d, 0x20, - 0x0a, 0x4a, 0x77, 0x00, 0xa2, 0x90, 0x84, 0xcd, 0x1b, 0xa8, 0x18, 0xdc, - 0xd1, 0x9a, 0x00, 0xb3, 0x63, 0x29, 0x49, 0xc7, 0xbd, 0x6b, 0xa4, 0xbc, - 0x72, 0x6b, 0x26, 0x03, 0xd6, 0xee, 0x21, 0xc6, 0xf3, 0x50, 0x49, 0x7c, - 0xe7, 0xa3, 0xe2, 0x9c, 0x22, 0x04, 0x4b, 0x34, 0xb2, 0x7f, 0xcb, 0x43, - 0x53, 0x45, 0x33, 0x35, 0xbc, 0x8a, 0x4f, 0xcc, 0x06, 0x73, 0xf8, 0xd5, - 0xc8, 0x0b, 0x29, 0xf7, 0x29, 0xd5, 0x02, 0x0c, 0xd2, 0x50, 0x02, 0x52, - 0x55, 0x12, 0x36, 0x92, 0x98, 0x05, 0x2d, 0x31, 0x05, 0x2d, 0x02, 0x16, - 0x9c, 0x29, 0xa2, 0x47, 0x52, 0xd5, 0x08, 0x28, 0xa4, 0x26, 0x14, 0x50, - 0x02, 0x51, 0x40, 0x1c, 0xd5, 0x2d, 0x51, 0xd0, 0x26, 0x33, 0x45, 0x26, - 0x86, 0x14, 0xa2, 0x86, 0x80, 0x5f, 0xe1, 0x35, 0xdb, 0xe8, 0xb2, 0xf9, - 0xba, 0x72, 0x9f, 0xf6, 0x8d, 0x45, 0xbd, 0xe4, 0x3f, 0xb0, 0x68, 0x56, - 0x8c, 0x47, 0x2b, 0x55, 0x3d, 0xc9, 0x43, 0xe8, 0xa4, 0x01, 0x45, 0x00, - 0x14, 0xb4, 0x00, 0x51, 0x48, 0x61, 0x4b, 0x40, 0x05, 0x14, 0xc0, 0x5a, - 0x29, 0x00, 0x52, 0xd0, 0x02, 0x52, 0xd0, 0x01, 0x49, 0x40, 0x09, 0xb8, - 0x51, 0x9a, 0x91, 0x8d, 0x2d, 0x50, 0x4f, 0x78, 0x90, 0xae, 0x58, 0xd0, - 0x33, 0x3e, 0x1d, 0x7a, 0x39, 0x6e, 0x96, 0x20, 0x38, 0x26, 0xb5, 0x83, - 0x64, 0x56, 0x6f, 0x49, 0x58, 0xd3, 0x97, 0x41, 0x73, 0x4b, 0x4c, 0x90, - 0xa2, 0xa8, 0x41, 0x45, 0x00, 0x14, 0x94, 0x00, 0x99, 0xa6, 0xe6, 0x98, - 0x86, 0x16, 0xe6, 0xa2, 0x94, 0x6f, 0x18, 0xcd, 0x51, 0x25, 0x71, 0x0a, - 0x8f, 0x7a, 0x43, 0x12, 0x7a, 0x52, 0x01, 0x70, 0x29, 0xaf, 0xd2, 0x80, - 0x29, 0xb9, 0xe6, 0x9a, 0x18, 0xab, 0x66, 0xa6, 0x45, 0xa3, 0xa3, 0xb7, - 0x93, 0xcd, 0x84, 0x30, 0xfa, 0x52, 0xbd, 0x38, 0x6c, 0x4b, 0x2b, 0x49, - 0x55, 0xde, 0xa8, 0x44, 0x0d, 0x5c, 0xb6, 0xbc, 0x3e, 0x56, 0xff, 0x00, - 0x77, 0x34, 0xe0, 0x29, 0x1c, 0xf5, 0x14, 0xc6, 0x02, 0x9f, 0x52, 0x01, - 0x9a, 0x6e, 0x68, 0xb0, 0x5c, 0x4c, 0xd1, 0x9a, 0x00, 0x4a, 0x28, 0x01, - 0x28, 0xa6, 0x03, 0x93, 0xad, 0x4b, 0x96, 0x3d, 0xcd, 0x45, 0x86, 0x2a, - 0xf1, 0x56, 0xfe, 0x5d, 0xb5, 0xa4, 0x44, 0xc5, 0xf2, 0xb2, 0x99, 0x53, - 0x51, 0xfc, 0xf1, 0xe7, 0x06, 0xa6, 0xc0, 0x5c, 0x8a, 0x46, 0xdb, 0xd6, - 0xa4, 0xf3, 0x4d, 0x65, 0x62, 0x85, 0xf3, 0x4d, 0x2f, 0x9d, 0x48, 0x9b, - 0x0f, 0x59, 0x77, 0x53, 0xab, 0x44, 0x48, 0x53, 0x6a, 0xac, 0x48, 0x52, - 0xd0, 0x48, 0x94, 0xb4, 0x08, 0x5a, 0x70, 0xaa, 0x01, 0x69, 0x68, 0x10, - 0x51, 0x40, 0x82, 0x8a, 0x2c, 0x01, 0x45, 0x2b, 0x01, 0xcd, 0xd1, 0x5a, - 0x9b, 0x80, 0xa2, 0xa5, 0x8c, 0x28, 0x15, 0x1b, 0x80, 0xbd, 0x2b, 0xac, - 0xf0, 0xc4, 0x9b, 0xac, 0xca, 0x67, 0xa6, 0x4f, 0xeb, 0x53, 0x27, 0xaa, - 0x29, 0x6c, 0xcd, 0xba, 0xbd, 0x6a, 0x72, 0x95, 0xa4, 0xc9, 0x44, 0xf4, - 0x54, 0x80, 0x51, 0x40, 0x05, 0x14, 0x00, 0x51, 0x4c, 0x61, 0x45, 0x20, - 0x16, 0x8a, 0x40, 0x2d, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, 0x00, 0x52, - 0x77, 0x14, 0x03, 0x39, 0x3b, 0xfd, 0x4e, 0xe1, 0x2e, 0xb0, 0x8d, 0xc5, - 0x4b, 0x6d, 0xaf, 0x4e, 0x06, 0x1d, 0x73, 0x45, 0x58, 0xea, 0x6d, 0x05, - 0x78, 0x84, 0x9a, 0xe4, 0xbd, 0xb0, 0x2b, 0x36, 0xee, 0xf6, 0x4b, 0xaf, - 0xbf, 0x51, 0xb1, 0x4a, 0x28, 0x86, 0x13, 0xb2, 0x5d, 0xcb, 0x5d, 0xac, - 0x2f, 0x98, 0x54, 0xfb, 0x0f, 0xe5, 0x58, 0xcb, 0xe2, 0x2e, 0x5f, 0x09, - 0x20, 0x34, 0xec, 0xd6, 0x86, 0x02, 0xd1, 0x54, 0x01, 0x9a, 0x5c, 0xd2, - 0x01, 0x29, 0x29, 0x88, 0x08, 0x6c, 0x64, 0x03, 0x50, 0x92, 0xdf, 0xdd, - 0x3f, 0x95, 0x5a, 0x57, 0x11, 0x13, 0x6e, 0x5e, 0xa0, 0xd3, 0x4c, 0x94, - 0x3d, 0x04, 0x44, 0x5f, 0x9a, 0x4d, 0xd5, 0x37, 0x01, 0xbb, 0xe9, 0xac, - 0x68, 0x02, 0x8c, 0xbe, 0x67, 0x9a, 0x36, 0xe7, 0x15, 0x2c, 0x4a, 0x58, - 0x80, 0x70, 0x3e, 0xb5, 0x12, 0xdc, 0xd1, 0x6c, 0x6b, 0x69, 0x72, 0x71, - 0xb2, 0xae, 0xb1, 0xaa, 0x81, 0x12, 0x2a, 0xc9, 0x55, 0xde, 0xa8, 0x92, - 0xbb, 0xd7, 0x39, 0xe2, 0x01, 0xf2, 0x4b, 0xfe, 0xed, 0x54, 0x37, 0x14, - 0x8e, 0x68, 0xf5, 0xa4, 0xaa, 0x63, 0x14, 0x51, 0x52, 0x02, 0x52, 0xd0, - 0x02, 0x51, 0x40, 0x09, 0x45, 0x20, 0x0a, 0x29, 0x88, 0x96, 0x24, 0x35, - 0x3e, 0xca, 0x45, 0x8f, 0x8a, 0x20, 0x5f, 0xe6, 0xa9, 0xdd, 0x03, 0x0c, - 0x52, 0x4c, 0x2c, 0x1b, 0x4e, 0x29, 0xdb, 0x32, 0x39, 0xa2, 0xe1, 0x61, - 0xea, 0x30, 0x29, 0x6b, 0x31, 0x87, 0x34, 0xef, 0x2d, 0xaa, 0xc9, 0xb9, - 0x2c, 0x71, 0x6d, 0x39, 0xcd, 0x48, 0x4d, 0x34, 0x66, 0xc4, 0xcd, 0x25, - 0x32, 0x44, 0xa3, 0x34, 0xc4, 0x2d, 0x2d, 0x02, 0x17, 0x34, 0xea, 0x62, - 0x16, 0x8e, 0xf4, 0xc0, 0x5a, 0x29, 0x08, 0x28, 0xa0, 0x02, 0x8a, 0x62, - 0x39, 0xaa, 0x29, 0xb6, 0x75, 0x0b, 0x49, 0x52, 0x01, 0x49, 0x40, 0x85, - 0xae, 0x8b, 0xc2, 0x72, 0x7e, 0xf6, 0x54, 0xff, 0x00, 0x64, 0x7f, 0xe8, - 0x55, 0x9d, 0x44, 0x5c, 0x4e, 0x98, 0x55, 0xbb, 0x3a, 0xd2, 0x64, 0x22, - 0xdd, 0x14, 0x80, 0x28, 0xa0, 0x02, 0x8a, 0x06, 0x14, 0x53, 0x00, 0xa2, - 0x90, 0x05, 0x14, 0x80, 0x5a, 0x5a, 0x00, 0x29, 0x28, 0x00, 0xa4, 0xa0, - 0x06, 0x3b, 0xed, 0x15, 0x0f, 0xda, 0x14, 0x9a, 0x68, 0x4c, 0xe4, 0x35, - 0x1e, 0x2f, 0x0f, 0xd2, 0xab, 0x99, 0x82, 0x74, 0xc5, 0x2a, 0xdf, 0x11, - 0xbd, 0x2f, 0x84, 0x84, 0xc9, 0xba, 0x9b, 0xe6, 0x56, 0x46, 0x82, 0xac, - 0xa6, 0xb6, 0xac, 0x35, 0xb6, 0x8a, 0x3f, 0x2d, 0x86, 0xee, 0xb5, 0x0e, - 0x1d, 0x4a, 0xf2, 0x3a, 0x44, 0x6d, 0xc8, 0x18, 0x77, 0x15, 0x20, 0xa1, - 0x6a, 0x62, 0xd0, 0xb4, 0x66, 0xac, 0x42, 0x66, 0x8c, 0xd2, 0x10, 0x99, - 0xa6, 0x34, 0x9b, 0x46, 0x6a, 0x80, 0xb1, 0x63, 0xa8, 0xc4, 0x99, 0x0e, - 0x2a, 0xd7, 0xf6, 0x9d, 0xa9, 0xf5, 0xfc, 0xa8, 0x8e, 0x83, 0xf6, 0x77, - 0x2a, 0xea, 0x77, 0xb0, 0xb5, 0xa9, 0x54, 0x07, 0x2c, 0x08, 0xac, 0x33, - 0x29, 0xab, 0x9b, 0xd0, 0x98, 0xc6, 0xc3, 0x7c, 0xea, 0x97, 0x20, 0xd6, - 0x25, 0xd8, 0x4d, 0xcb, 0xeb, 0x51, 0x99, 0x45, 0x3d, 0x45, 0x61, 0x86, - 0x5e, 0x78, 0x14, 0x9b, 0x9c, 0xd2, 0x19, 0x34, 0x12, 0x34, 0x52, 0xab, - 0x1a, 0xd9, 0xce, 0x56, 0xaa, 0x3b, 0x93, 0x22, 0x07, 0xa8, 0x1e, 0xb4, - 0x66, 0x65, 0x69, 0x2b, 0x07, 0x5d, 0x19, 0x8d, 0xfd, 0xc5, 0x38, 0x6e, - 0x29, 0x1c, 0xab, 0x7d, 0xe3, 0xf5, 0xa4, 0xaa, 0x6c, 0x61, 0x4b, 0x48, - 0x02, 0x92, 0x92, 0x01, 0x28, 0xa0, 0x03, 0x06, 0x9f, 0xe5, 0x9a, 0x02, - 0xc3, 0xc4, 0x0d, 0x52, 0x2d, 0xb1, 0xa5, 0x71, 0xd8, 0xb5, 0x14, 0x07, - 0x1d, 0x31, 0x53, 0x08, 0x6b, 0x2e, 0x63, 0x41, 0x7c, 0xa1, 0x4e, 0xc0, - 0xa0, 0x01, 0x7e, 0x6e, 0x94, 0xfd, 0x95, 0x46, 0x6e, 0x43, 0xbc, 0xaa, - 0x5d, 0xa2, 0xa8, 0x9b, 0x8b, 0xd2, 0x97, 0x34, 0xc4, 0x2e, 0x69, 0x09, - 0xa0, 0x43, 0x77, 0x51, 0xba, 0x82, 0x43, 0x75, 0x19, 0xa6, 0x01, 0x9a, - 0x5c, 0xd0, 0x21, 0xd4, 0xa2, 0xa8, 0x43, 0xa9, 0x68, 0x10, 0x52, 0xd2, - 0x10, 0x51, 0x4c, 0x02, 0x8a, 0x04, 0x73, 0x74, 0xb4, 0xce, 0xa1, 0x28, - 0x15, 0x00, 0x21, 0xa2, 0x80, 0x1d, 0x5a, 0xde, 0x1b, 0x7d, 0x9a, 0x9a, - 0x2f, 0xf7, 0x99, 0x47, 0xf3, 0xa8, 0xa9, 0xb1, 0x70, 0x3b, 0x05, 0xe9, - 0x56, 0xad, 0x0f, 0xcf, 0x5a, 0x3d, 0x88, 0x45, 0xda, 0x28, 0x10, 0x51, - 0x40, 0x05, 0x14, 0x0c, 0x28, 0xa0, 0x04, 0xa5, 0xa4, 0x01, 0x45, 0x00, - 0x14, 0x50, 0x01, 0x45, 0x00, 0x14, 0x94, 0x01, 0x5e, 0xe7, 0xa5, 0x63, - 0x35, 0xfc, 0x62, 0xe3, 0xca, 0x63, 0x86, 0xe2, 0xae, 0xda, 0x5c, 0x5d, - 0x4c, 0x5b, 0xb7, 0xdc, 0x72, 0x6a, 0x91, 0xe6, 0xb3, 0x99, 0xb4, 0x40, - 0x29, 0xc7, 0x43, 0x4d, 0xef, 0xc5, 0x09, 0x14, 0xc7, 0x04, 0x35, 0xa9, - 0xa3, 0x5a, 0xf9, 0x97, 0x49, 0xe6, 0x27, 0xcb, 0x9a, 0x99, 0xc6, 0xc5, - 0xa3, 0xa9, 0x4e, 0x14, 0x0a, 0x7e, 0x6b, 0x34, 0x64, 0x2e, 0xea, 0x4d, - 0xd5, 0x40, 0x26, 0xfa, 0x69, 0x90, 0x54, 0x8c, 0x61, 0x9c, 0x7a, 0xd4, - 0x12, 0xdc, 0xae, 0xd2, 0x28, 0xb8, 0x72, 0x95, 0xa2, 0x6d, 0xd2, 0x71, - 0x57, 0x92, 0x16, 0x04, 0x1a, 0x39, 0x8e, 0x8d, 0x91, 0x16, 0xa0, 0xdc, - 0xa2, 0x7a, 0x55, 0x3a, 0xa9, 0x19, 0xb1, 0xa4, 0x53, 0xe3, 0xe6, 0x91, - 0x23, 0xcc, 0x23, 0x34, 0x9e, 0x58, 0xa4, 0x48, 0xbb, 0x69, 0x69, 0x0c, - 0x46, 0xe9, 0x5a, 0x36, 0x72, 0xf9, 0x90, 0xfb, 0x8a, 0x64, 0xb1, 0xcf, - 0x55, 0xda, 0xb6, 0x33, 0x2b, 0xcb, 0xd2, 0xb1, 0x35, 0x7c, 0x15, 0xc7, - 0xa9, 0xa1, 0x09, 0x9c, 0xbb, 0xa7, 0xcc, 0xdf, 0x5a, 0x8f, 0x63, 0x7a, - 0x1a, 0x60, 0x37, 0x14, 0xec, 0x50, 0x01, 0xb0, 0xd3, 0xc4, 0x06, 0x80, - 0xb1, 0x22, 0xdb, 0x7d, 0x6a, 0x55, 0xb4, 0xa9, 0xe6, 0x34, 0xe5, 0x26, - 0x4b, 0x2a, 0x99, 0x6d, 0x36, 0xd6, 0x6e, 0x65, 0xf2, 0x8f, 0x10, 0x20, - 0xa7, 0x61, 0x16, 0x8d, 0x58, 0xf4, 0x43, 0x1a, 0x50, 0xb4, 0x6f, 0xcf, - 0x34, 0xd4, 0x0c, 0xb9, 0x84, 0xcd, 0x15, 0xa5, 0x88, 0x6c, 0x4b, 0x63, - 0xf3, 0x35, 0x59, 0xcd, 0x21, 0x09, 0x9a, 0x4d, 0xd4, 0xac, 0x21, 0x37, - 0x53, 0x0c, 0xa0, 0x77, 0xa0, 0x08, 0xda, 0xed, 0x45, 0x40, 0xf7, 0xde, - 0x82, 0xa9, 0x21, 0x91, 0x1b, 0xc7, 0xff, 0x00, 0x26, 0x99, 0xf6, 0xd7, - 0xef, 0xcd, 0x16, 0x02, 0x41, 0x7c, 0x6a, 0x41, 0x7a, 0x3d, 0xa9, 0x59, - 0x8a, 0xc4, 0x8b, 0x74, 0xbe, 0xf5, 0x2a, 0xcc, 0x3d, 0x69, 0x85, 0x87, - 0x89, 0x85, 0x48, 0x24, 0x14, 0xc8, 0xb0, 0xfd, 0xd4, 0xbb, 0xa8, 0x24, - 0x5c, 0xd2, 0xd3, 0x10, 0xb4, 0xb4, 0x08, 0x28, 0xa2, 0xe2, 0x39, 0xba, - 0x2b, 0x43, 0xa4, 0x28, 0xa9, 0x18, 0x51, 0x48, 0x02, 0xae, 0x69, 0x4f, - 0xe5, 0xea, 0x30, 0x37, 0xfb, 0x55, 0x35, 0x2d, 0xca, 0x5c, 0x37, 0x3b, - 0xa4, 0xfb, 0xab, 0xfe, 0xe8, 0xab, 0x10, 0x1c, 0x48, 0x28, 0xfb, 0x24, - 0x1a, 0x03, 0xa5, 0x25, 0x31, 0x0b, 0x45, 0x00, 0x14, 0x50, 0x01, 0x45, - 0x00, 0x25, 0x14, 0x0c, 0x28, 0xa4, 0x01, 0x45, 0x00, 0x14, 0x50, 0x01, - 0x4d, 0x26, 0x80, 0x2b, 0xdc, 0xb7, 0xc9, 0x58, 0x37, 0x9a, 0x6c, 0x57, - 0x13, 0x79, 0x85, 0x99, 0x5a, 0xb5, 0x8c, 0xac, 0x4d, 0xb5, 0xb9, 0x91, - 0x76, 0x9e, 0x41, 0xd9, 0x55, 0xc5, 0x63, 0x50, 0xe8, 0xa7, 0xa9, 0xb9, - 0x6d, 0x6a, 0xbf, 0x67, 0xe9, 0x4e, 0x8b, 0x4a, 0x0c, 0xc4, 0x88, 0xbf, - 0x4a, 0x28, 0x31, 0x4d, 0x59, 0xdc, 0x9f, 0xfb, 0x2e, 0x4f, 0xe1, 0x8c, - 0xd4, 0xf6, 0x96, 0x52, 0xc1, 0x26, 0xe6, 0x4c, 0x57, 0x5d, 0x54, 0xb9, - 0x48, 0x8c, 0xcb, 0x7e, 0x60, 0x1d, 0xe9, 0xa6, 0xe5, 0x47, 0x7a, 0xf3, - 0xcd, 0x08, 0xda, 0xf5, 0x45, 0x42, 0xda, 0x87, 0xa5, 0x45, 0xcb, 0x50, - 0x22, 0x6b, 0xe7, 0x3d, 0x2a, 0x26, 0xba, 0x90, 0xf7, 0xa5, 0x73, 0x4e, - 0x51, 0x86, 0x42, 0x7b, 0xd3, 0x73, 0x41, 0x64, 0xb6, 0xd2, 0xf9, 0x72, - 0x83, 0x5b, 0x30, 0xcd, 0xd2, 0x92, 0x5a, 0x8d, 0xec, 0x51, 0xd4, 0x64, - 0x12, 0x5d, 0x65, 0x7d, 0x05, 0x41, 0x5b, 0xcc, 0xc5, 0x85, 0x3e, 0x2f, - 0xbd, 0x50, 0x41, 0x39, 0xa6, 0xd2, 0x24, 0x4a, 0x6d, 0x00, 0x21, 0xe9, - 0x4e, 0xb1, 0x9f, 0x65, 0xca, 0xc7, 0xfd, 0xf3, 0x8a, 0x60, 0x69, 0x35, - 0x57, 0x7a, 0xd6, 0xe6, 0x45, 0x5b, 0x96, 0xfd, 0xdb, 0x57, 0x2b, 0x37, - 0x9d, 0x23, 0x9d, 0xc4, 0x9c, 0x1a, 0x77, 0xd0, 0x12, 0xbb, 0x20, 0xf2, - 0x39, 0xa3, 0xc8, 0xac, 0xf9, 0x8d, 0x94, 0x05, 0xfb, 0x28, 0x3d, 0x56, - 0x9c, 0xb6, 0x23, 0xfb, 0xb4, 0xb9, 0xc7, 0xc8, 0x4a, 0xb6, 0x3e, 0xc2, - 0xa4, 0x16, 0xa8, 0x2a, 0x79, 0xca, 0xe5, 0x1e, 0x12, 0x35, 0xec, 0x29, - 0x0c, 0xa8, 0xb4, 0x25, 0x71, 0x68, 0x88, 0x8d, 0xc5, 0x30, 0xcc, 0x4d, - 0x68, 0xa0, 0x64, 0xe6, 0x30, 0xb1, 0xa4, 0xad, 0x2c, 0x67, 0x71, 0x92, - 0xfd, 0xda, 0x91, 0x69, 0x88, 0x09, 0xa6, 0xee, 0xa4, 0x05, 0x63, 0x75, - 0xb3, 0x3b, 0x45, 0x11, 0x5e, 0xb6, 0xff, 0x00, 0x98, 0x71, 0xf5, 0xa2, - 0xc3, 0x26, 0x6b, 0xd1, 0x51, 0x35, 0xe3, 0x76, 0xe2, 0x8b, 0x01, 0x0b, - 0x5c, 0x31, 0xef, 0x51, 0x34, 0xb9, 0xef, 0x40, 0x86, 0x79, 0x94, 0xdd, - 0xe6, 0x81, 0x8d, 0xc9, 0xa2, 0x81, 0x0b, 0xb6, 0x9e, 0x05, 0x00, 0x38, - 0x1c, 0x54, 0x9e, 0x69, 0xa0, 0x05, 0xf3, 0x4d, 0x3c, 0x5c, 0x38, 0xa3, - 0x70, 0x24, 0x17, 0x4d, 0xde, 0xa4, 0x5b, 0xca, 0x56, 0x11, 0x62, 0x3b, - 0x9d, 0xd5, 0x30, 0x9a, 0x92, 0x64, 0x34, 0x4a, 0x0d, 0x3e, 0xa9, 0x33, - 0x30, 0xa5, 0xaa, 0xb0, 0x1c, 0xe5, 0x25, 0x07, 0x48, 0x1e, 0x94, 0x52, - 0x01, 0x68, 0xa6, 0x80, 0x4a, 0x92, 0x16, 0xdb, 0x26, 0xef, 0xad, 0x4c, - 0xf6, 0x2a, 0x1b, 0x9e, 0x81, 0x6d, 0xcc, 0x11, 0x9f, 0xf6, 0x47, 0xf2, - 0xab, 0x2b, 0xf7, 0x85, 0x28, 0xfc, 0x24, 0xbd, 0xcd, 0x05, 0xe9, 0x4b, - 0x54, 0x01, 0x45, 0x00, 0x14, 0x50, 0x01, 0x45, 0x20, 0x12, 0x92, 0x80, - 0x0a, 0x28, 0x00, 0xa2, 0x80, 0x0a, 0x4c, 0xd0, 0x03, 0x77, 0x54, 0x53, - 0x49, 0xf2, 0x1c, 0x51, 0x70, 0x28, 0xcb, 0x21, 0x6a, 0xac, 0xcc, 0x69, - 0x5c, 0x66, 0x76, 0xa1, 0x6d, 0xf6, 0x84, 0xe3, 0xef, 0x0a, 0xc4, 0x62, - 0x62, 0x72, 0xad, 0x43, 0xd5, 0x15, 0x07, 0x66, 0x6c, 0x69, 0xba, 0x9a, - 0x30, 0x11, 0x3f, 0x5a, 0xf4, 0x0d, 0x2a, 0xd6, 0x34, 0x87, 0x77, 0x1c, - 0xd7, 0x34, 0x74, 0x95, 0x8d, 0xaa, 0xec, 0x5f, 0x70, 0x31, 0x59, 0xb7, - 0x5b, 0x6b, 0xb9, 0xb3, 0x96, 0xc7, 0x29, 0xa8, 0x36, 0xd9, 0xf8, 0xe9, - 0x55, 0xb7, 0x66, 0xb9, 0xaa, 0xee, 0x76, 0x53, 0xd8, 0x33, 0x4d, 0xcd, - 0x73, 0x9b, 0x09, 0x9a, 0x68, 0x6d, 0xdd, 0x29, 0x00, 0xfa, 0x75, 0x00, - 0x2a, 0xf5, 0xad, 0xeb, 0x44, 0xfd, 0xde, 0xfe, 0xd5, 0xa4, 0x5e, 0xa5, - 0x74, 0x32, 0xae, 0xbf, 0xd6, 0x53, 0x33, 0x5a, 0xcb, 0x73, 0x19, 0x8e, - 0xa7, 0x45, 0xf7, 0xaa, 0x0c, 0xcb, 0x06, 0x9b, 0x4d, 0x90, 0x25, 0x26, - 0x2a, 0x46, 0x21, 0xaa, 0x53, 0x31, 0x8e, 0x40, 0xc3, 0xa8, 0xaa, 0x03, - 0x6d, 0x24, 0xf3, 0x21, 0x0d, 0x55, 0x6e, 0xa6, 0xd8, 0x2a, 0xa2, 0xf4, - 0x33, 0xea, 0x66, 0x4d, 0x2c, 0x92, 0xf1, 0x9a, 0xad, 0xe4, 0x0a, 0xce, - 0x4c, 0xdd, 0x21, 0x86, 0xdc, 0x7a, 0xd2, 0xf9, 0x28, 0x3d, 0x2a, 0x2e, - 0xcb, 0xb0, 0x9b, 0xa3, 0x5a, 0x61, 0xb8, 0x41, 0xde, 0xad, 0x45, 0x92, - 0xdd, 0x88, 0x5a, 0xe7, 0xda, 0xa2, 0x33, 0x31, 0xef, 0x5a, 0xf2, 0x18, - 0xba, 0x83, 0x0b, 0x13, 0x4d, 0xad, 0x0c, 0x84, 0xa5, 0xa0, 0x02, 0x8a, - 0x04, 0x32, 0x4e, 0x94, 0x2b, 0x71, 0x43, 0x10, 0x85, 0xaa, 0xbd, 0xc4, - 0x85, 0x71, 0x40, 0xc4, 0xb7, 0x45, 0x9b, 0xef, 0x54, 0xc6, 0x38, 0x17, - 0xf8, 0x69, 0x5c, 0x0a, 0x9e, 0xb8, 0xa6, 0x91, 0x4c, 0x63, 0x0a, 0xd3, - 0x76, 0x50, 0x20, 0xd9, 0x4a, 0x23, 0xa0, 0x63, 0xb1, 0x4b, 0x40, 0x82, - 0x8a, 0x00, 0x4c, 0xd2, 0x6e, 0xa0, 0x62, 0x6e, 0xa7, 0x86, 0xa4, 0x20, - 0x2f, 0x49, 0xba, 0x98, 0x16, 0xad, 0x5a, 0xae, 0x21, 0xac, 0xc4, 0xcb, - 0x31, 0x9a, 0x98, 0x56, 0x88, 0xcc, 0x5a, 0x5a, 0x64, 0x9c, 0xef, 0x7a, - 0x4a, 0xd2, 0xc6, 0xe2, 0xd1, 0x52, 0x31, 0x40, 0x34, 0x63, 0x07, 0x91, - 0x49, 0x08, 0x6d, 0x3b, 0xb1, 0xa2, 0x43, 0x8e, 0xe7, 0x7b, 0xa3, 0xbf, - 0x9b, 0x60, 0xa7, 0xfd, 0xa3, 0xfd, 0x2b, 0x47, 0x1c, 0x54, 0x53, 0xf8, - 0x47, 0x3f, 0x88, 0xb9, 0x1f, 0xdd, 0xa5, 0xa6, 0x89, 0x16, 0x8a, 0x60, - 0x14, 0x53, 0x18, 0x52, 0x52, 0x01, 0x28, 0xa4, 0x02, 0x51, 0x9a, 0x00, - 0x4d, 0xd4, 0xc3, 0x28, 0x1d, 0xe8, 0x60, 0x42, 0xf7, 0x68, 0x3b, 0xd4, - 0x26, 0xf2, 0xb2, 0x6c, 0x9e, 0x62, 0x13, 0x7c, 0x7d, 0x29, 0xbf, 0x68, - 0x2c, 0x32, 0x2a, 0x05, 0x71, 0x14, 0x96, 0xed, 0x46, 0xd3, 0x53, 0x71, - 0x31, 0x8c, 0x17, 0xf8, 0xb1, 0x5c, 0xe6, 0xaa, 0x8a, 0x2e, 0x8e, 0xde, - 0x98, 0x15, 0xa5, 0x36, 0x54, 0x6f, 0x72, 0x9a, 0x65, 0x4f, 0x15, 0xd8, - 0x5b, 0x5e, 0xea, 0x10, 0xdb, 0x02, 0x8f, 0x95, 0xad, 0x69, 0xa8, 0xb9, - 0xea, 0x74, 0x49, 0xfb, 0xa3, 0x2e, 0x35, 0x8d, 0x40, 0x8e, 0x49, 0xab, - 0x50, 0xcc, 0xef, 0x0f, 0xcc, 0xd9, 0xae, 0xba, 0xd0, 0x51, 0xd8, 0xc9, - 0x19, 0xba, 0x91, 0xc3, 0x8c, 0xf7, 0xa8, 0x63, 0xe9, 0x5e, 0x7d, 0x63, - 0xae, 0x97, 0xc2, 0x3a, 0x8a, 0xc4, 0xd0, 0x43, 0x50, 0x6d, 0x60, 0xdc, - 0x53, 0xb0, 0x89, 0x79, 0xa7, 0x0a, 0x7c, 0xa3, 0xb8, 0xe5, 0xeb, 0x5d, - 0x25, 0xa4, 0x32, 0x1b, 0x4f, 0x96, 0x9c, 0x7e, 0x20, 0xe7, 0xb2, 0x33, - 0xb5, 0x0b, 0x57, 0x5c, 0xb1, 0xe2, 0xb3, 0xb7, 0x1a, 0xda, 0xaa, 0x31, - 0x52, 0xe6, 0x1e, 0x24, 0xa9, 0x62, 0x3c, 0xd6, 0x20, 0xd1, 0x68, 0xf4, - 0xa6, 0xe4, 0x53, 0x20, 0x61, 0x75, 0xa6, 0x19, 0x94, 0x54, 0x95, 0x62, - 0x17, 0x9e, 0xab, 0x4a, 0xdb, 0xb9, 0x35, 0x45, 0x58, 0x9a, 0x0d, 0x43, - 0x62, 0x18, 0xf1, 0xd3, 0x9c, 0xd4, 0x72, 0x4f, 0xbc, 0xe4, 0x9a, 0x5b, - 0x0b, 0x94, 0x81, 0xa7, 0x02, 0xa2, 0x6b, 0xa1, 0x4d, 0x42, 0xe0, 0xe6, - 0x91, 0x13, 0x5c, 0x9e, 0xd5, 0x0b, 0x4a, 0xc7, 0xbd, 0x6d, 0xc8, 0x8c, - 0x5d, 0x46, 0x44, 0x4e, 0x4d, 0x15, 0x66, 0x62, 0x51, 0x40, 0x05, 0x25, - 0x00, 0x25, 0x2d, 0x00, 0x25, 0x25, 0x02, 0x18, 0xe7, 0x8a, 0x62, 0xfd, - 0xda, 0x42, 0x10, 0x9a, 0x82, 0x7f, 0xb9, 0x54, 0x03, 0x2d, 0xdb, 0x14, - 0xf2, 0xcb, 0xeb, 0x52, 0x8a, 0x2b, 0xb3, 0x73, 0xc5, 0x1e, 0x65, 0x0c, - 0x57, 0x17, 0xcc, 0xa3, 0x70, 0xa0, 0x63, 0xa9, 0x68, 0x10, 0x62, 0x8c, - 0x50, 0x02, 0x52, 0x71, 0x40, 0x0d, 0x6a, 0x6d, 0x30, 0x16, 0x8a, 0x00, - 0x4c, 0xd1, 0x9a, 0x40, 0x59, 0xb7, 0x35, 0x75, 0x0d, 0x48, 0x99, 0x65, - 0x0f, 0x15, 0x30, 0x35, 0x48, 0xcd, 0x8e, 0xcd, 0x2e, 0x68, 0x20, 0xe7, - 0xa8, 0x35, 0xa9, 0xd2, 0x14, 0xf5, 0xa8, 0x60, 0x5a, 0x18, 0x0b, 0x51, - 0x4b, 0x8c, 0x54, 0xc4, 0x08, 0x71, 0x4b, 0x8e, 0xd4, 0xc0, 0xec, 0xfc, - 0x2c, 0xfb, 0xb4, 0xfd, 0xbe, 0x9b, 0x8f, 0xeb, 0x5b, 0xe8, 0x32, 0xb5, - 0x9d, 0x2d, 0x8b, 0xa9, 0xb9, 0x62, 0x25, 0xf9, 0x69, 0xd8, 0xad, 0x0c, - 0xc4, 0xa2, 0x80, 0x0a, 0x28, 0x18, 0xda, 0x42, 0x68, 0x01, 0xa5, 0xc7, - 0xad, 0x46, 0x65, 0x51, 0xde, 0xa6, 0xe0, 0x46, 0xd7, 0x48, 0x3b, 0xd4, - 0x7f, 0x6c, 0x07, 0xa5, 0x4d, 0xca, 0xb1, 0x04, 0x97, 0x2c, 0xc3, 0x1d, - 0x2a, 0x21, 0xb8, 0xf5, 0xac, 0xe5, 0x23, 0x2b, 0x83, 0x42, 0x0d, 0x1e, - 0x4a, 0xe2, 0xa2, 0xe4, 0x86, 0xd5, 0xc6, 0x29, 0xca, 0x10, 0x0e, 0xc2, - 0xa5, 0x8c, 0x6b, 0xdd, 0x43, 0x10, 0xe5, 0xaa, 0xa4, 0xda, 0xcc, 0x2b, - 0xc2, 0x02, 0xc7, 0xe9, 0x57, 0x18, 0x5c, 0x46, 0x75, 0xc5, 0xed, 0xc4, - 0xfd, 0x3e, 0x51, 0xed, 0x54, 0x58, 0x36, 0x7e, 0x6a, 0xdb, 0x92, 0xc6, - 0xf0, 0x56, 0x45, 0x73, 0x2a, 0xd7, 0x61, 0xa2, 0xcf, 0xe6, 0xd9, 0x0f, - 0xa9, 0xa7, 0xb3, 0x45, 0xef, 0x11, 0x93, 0x7c, 0xca, 0x6a, 0xc5, 0x97, - 0xfa, 0xb3, 0x5d, 0x95, 0xb6, 0x33, 0x89, 0x99, 0xe2, 0x21, 0x85, 0x8c, - 0xff, 0x00, 0xb4, 0x7f, 0xf4, 0x1a, 0xa9, 0x67, 0x3f, 0x99, 0xf2, 0x9e, - 0xb5, 0xc5, 0x5d, 0x68, 0x99, 0xd1, 0x41, 0xe9, 0x62, 0xde, 0x29, 0x71, - 0x5c, 0xe6, 0xc2, 0xe2, 0x8a, 0x00, 0xb7, 0x07, 0x94, 0x63, 0xe4, 0x73, - 0x50, 0xcc, 0xa1, 0x9f, 0xe5, 0xad, 0x96, 0x91, 0x30, 0x5f, 0x10, 0xc1, - 0x19, 0xae, 0xaf, 0x45, 0x90, 0x7d, 0x93, 0x04, 0xfa, 0xd6, 0x5d, 0x4a, - 0x9e, 0xc5, 0x7d, 0x69, 0x81, 0x85, 0xb9, 0xed, 0x5c, 0xe9, 0x1f, 0x31, - 0xae, 0x8a, 0x9b, 0x19, 0xd2, 0x42, 0x62, 0x9c, 0x38, 0xae, 0x63, 0x71, - 0xe6, 0x53, 0x8e, 0xb5, 0x1b, 0x4b, 0x4c, 0x08, 0xda, 0x5f, 0x7a, 0x89, - 0xa5, 0xf5, 0x34, 0xf9, 0x40, 0x85, 0xee, 0x14, 0x0e, 0xb5, 0x52, 0x5b, - 0xcc, 0x74, 0xad, 0x3d, 0x99, 0x0e, 0xa5, 0x86, 0xf9, 0xef, 0xd7, 0xa1, - 0xa4, 0xf3, 0x19, 0xba, 0x9a, 0xd2, 0x31, 0x31, 0x73, 0xb8, 0x75, 0xa3, - 0x15, 0x56, 0x33, 0x12, 0x92, 0x80, 0x12, 0x8a, 0x00, 0x4a, 0x29, 0x00, - 0x94, 0x50, 0x02, 0x62, 0x99, 0x23, 0x6c, 0x5c, 0x9a, 0x00, 0x8d, 0x27, - 0x0c, 0x71, 0x52, 0x1a, 0x9e, 0xa0, 0x31, 0x87, 0x14, 0x46, 0xbb, 0x85, - 0x50, 0x88, 0x5a, 0xa2, 0x97, 0xee, 0xd3, 0xb0, 0x11, 0x27, 0x5a, 0x47, - 0x5c, 0x49, 0x40, 0x0d, 0x2b, 0xcd, 0x34, 0xad, 0x00, 0x25, 0x14, 0x86, - 0x14, 0xbb, 0xcd, 0x00, 0x3f, 0x79, 0xa4, 0xdc, 0x68, 0xb0, 0x82, 0x8a, - 0x00, 0x4a, 0x28, 0x01, 0x28, 0xa0, 0x02, 0x81, 0x40, 0x16, 0x60, 0xab, - 0x91, 0xd2, 0x02, 0xc2, 0x1a, 0x94, 0x1a, 0x66, 0x6c, 0x93, 0x34, 0xb4, - 0x12, 0x73, 0xf4, 0x55, 0x9b, 0x8a, 0x06, 0x4d, 0x48, 0x8a, 0x43, 0x50, - 0x05, 0x81, 0x19, 0xa5, 0xfb, 0x39, 0xf4, 0xfd, 0x2a, 0x40, 0x51, 0x68, - 0xcc, 0x71, 0xe5, 0xb7, 0xfd, 0xf3, 0x56, 0xd3, 0x49, 0xb8, 0x93, 0xee, - 0xc7, 0x81, 0x5a, 0x72, 0xf7, 0x11, 0xd0, 0x68, 0x56, 0xb2, 0xd9, 0xab, - 0x09, 0x40, 0x00, 0xfb, 0xfb, 0xd6, 0xe4, 0x2c, 0x37, 0x62, 0xb1, 0xb7, - 0x29, 0x4d, 0xdc, 0xd0, 0x81, 0x72, 0x28, 0x74, 0xa7, 0x12, 0x59, 0x1e, - 0xda, 0x6d, 0x30, 0x1b, 0x49, 0x4c, 0x0a, 0xd7, 0x53, 0xf9, 0x29, 0xba, - 0xb3, 0x9f, 0x53, 0x3d, 0x85, 0x4c, 0xf4, 0x45, 0xc1, 0x5c, 0xae, 0xf7, - 0xf2, 0x1e, 0xf5, 0x11, 0xb8, 0x73, 0xde, 0xb1, 0xb9, 0xb2, 0x89, 0x13, - 0x3b, 0x1e, 0xf4, 0xd1, 0x76, 0xf0, 0xfb, 0xd3, 0xb5, 0xd1, 0x13, 0x1c, - 0xba, 0xba, 0x7f, 0x12, 0x55, 0xd8, 0xae, 0xbc, 0xc8, 0xf7, 0x20, 0x15, - 0x9f, 0x2e, 0xa6, 0x1c, 0xa5, 0x49, 0x35, 0xa4, 0x47, 0xda, 0x62, 0x39, - 0xa8, 0x5f, 0x5c, 0x6f, 0xe1, 0x86, 0xaa, 0x54, 0x83, 0x94, 0x81, 0xb5, - 0x7b, 0xa6, 0xfb, 0xaa, 0x17, 0xf1, 0xa8, 0x1e, 0xee, 0xf2, 0x6f, 0xf9, - 0x6a, 0x6b, 0x58, 0x53, 0x8f, 0x50, 0xe4, 0x64, 0x62, 0xda, 0x59, 0x1b, - 0x2e, 0x33, 0x53, 0x7d, 0x9c, 0xf1, 0xb4, 0x55, 0x5d, 0x5c, 0xd3, 0x93, - 0x42, 0x58, 0x93, 0xd6, 0x96, 0xe1, 0x7f, 0x77, 0x53, 0xcd, 0xa9, 0xa7, - 0x2d, 0x91, 0x89, 0x30, 0x09, 0x21, 0x18, 0xad, 0xed, 0x12, 0xec, 0xac, - 0x5b, 0x47, 0x6f, 0xf1, 0xaa, 0x62, 0x5b, 0x16, 0x3c, 0xd0, 0xd1, 0x90, - 0x5a, 0xae, 0xe9, 0xa7, 0xf7, 0x67, 0x15, 0xd5, 0x57, 0xe1, 0x25, 0x10, - 0xeb, 0x10, 0x79, 0xb0, 0x73, 0xda, 0xa8, 0x5b, 0x5b, 0x79, 0x6d, 0x5c, - 0x55, 0x76, 0xb1, 0xad, 0x12, 0x69, 0x25, 0x58, 0xbe, 0xf5, 0x31, 0x2e, - 0x91, 0xa4, 0x0b, 0x9e, 0xbe, 0xd5, 0x8f, 0x26, 0x97, 0x2f, 0x9f, 0x5b, - 0x17, 0x15, 0x72, 0x29, 0x7c, 0xba, 0x94, 0x50, 0xe5, 0x87, 0x34, 0xf1, - 0x16, 0x0d, 0x5d, 0xc8, 0x1f, 0x80, 0x2a, 0x54, 0xb8, 0xf2, 0xc7, 0x07, - 0x15, 0x20, 0x43, 0x35, 0xce, 0xfe, 0xa7, 0x35, 0x58, 0x9a, 0x72, 0x63, - 0x5a, 0x0c, 0x32, 0x01, 0x51, 0xb4, 0xc2, 0x9a, 0x8d, 0xc7, 0xcd, 0x62, - 0x33, 0x3e, 0x7b, 0x54, 0x4d, 0x31, 0xad, 0x55, 0x33, 0x17, 0x54, 0x89, - 0xa4, 0x3e, 0xb5, 0x19, 0x35, 0xa2, 0x89, 0x93, 0x91, 0x0b, 0x1a, 0x87, - 0x6e, 0xe7, 0xa6, 0x22, 0x6a, 0x70, 0x15, 0x20, 0x3b, 0x14, 0x62, 0xa8, - 0x03, 0x61, 0xa6, 0x62, 0x9b, 0x40, 0x25, 0x18, 0xa8, 0x01, 0x76, 0x1a, - 0x6e, 0xda, 0x2c, 0x01, 0xb6, 0x97, 0x6d, 0x20, 0x0c, 0x55, 0x5b, 0xe1, - 0xfb, 0xa3, 0x4d, 0x6e, 0x26, 0x67, 0x03, 0xf3, 0x0a, 0xb8, 0x67, 0x18, - 0x14, 0x9a, 0x18, 0x79, 0xdb, 0xfb, 0x56, 0xbe, 0x9d, 0x68, 0x02, 0x92, - 0xfc, 0xd0, 0x22, 0x79, 0xac, 0x23, 0x6c, 0xf1, 0x59, 0x57, 0x5a, 0x54, - 0xa3, 0x98, 0xfa, 0x55, 0xa7, 0xdc, 0xcc, 0xa0, 0xd6, 0xb2, 0xc6, 0xdf, - 0x32, 0xd3, 0x58, 0x53, 0xb1, 0x57, 0x19, 0x46, 0x29, 0x58, 0xa1, 0x92, - 0x27, 0xa5, 0x45, 0x40, 0x05, 0x15, 0x23, 0x1d, 0x45, 0x02, 0x0a, 0x29, - 0x80, 0xb4, 0xa3, 0x14, 0x80, 0x09, 0xe2, 0x9b, 0x40, 0x05, 0x2d, 0x00, - 0x4f, 0x05, 0x5b, 0x4a, 0x56, 0x11, 0x32, 0x9a, 0x98, 0x1a, 0x09, 0x1e, - 0x0d, 0x3f, 0x34, 0xc9, 0x32, 0xc5, 0xbe, 0xee, 0x8a, 0x7f, 0x0a, 0x9a, - 0x3d, 0x3e, 0x57, 0xe9, 0x1b, 0x7e, 0x55, 0xb1, 0xa1, 0x7a, 0x2d, 0x0a, - 0xe5, 0xbf, 0xe5, 0x98, 0xfc, 0x4d, 0x5e, 0x8b, 0xc3, 0x6d, 0xff, 0x00, - 0x2d, 0x24, 0xc7, 0xe4, 0x69, 0x0a, 0xe5, 0xd8, 0xb4, 0x0b, 0x65, 0xea, - 0xc4, 0xfe, 0x15, 0x72, 0x2d, 0x26, 0xd6, 0x3e, 0x91, 0x0a, 0x9e, 0x61, - 0x97, 0x62, 0xb6, 0x89, 0x3f, 0x80, 0x0a, 0xb2, 0x15, 0x00, 0xed, 0x51, - 0x70, 0xb0, 0xc2, 0x15, 0x8d, 0x2a, 0x42, 0xa0, 0xe6, 0x86, 0xc6, 0x8b, - 0xf6, 0xdd, 0x6a, 0x76, 0x5a, 0x51, 0x19, 0x13, 0xa7, 0x15, 0x55, 0xea, - 0x84, 0x32, 0x9a, 0xdf, 0x76, 0x80, 0x33, 0x2e, 0xfe, 0x65, 0x35, 0x90, - 0xdc, 0x1a, 0x55, 0x36, 0x34, 0xa4, 0x25, 0x15, 0x81, 0xb3, 0x62, 0x54, - 0x6c, 0xa0, 0xd6, 0x88, 0xcd, 0x90, 0xb4, 0x00, 0xfa, 0xd4, 0x5f, 0x67, - 0xbb, 0x1f, 0xea, 0xe5, 0x6c, 0x7d, 0x6a, 0xf4, 0xea, 0x40, 0x0b, 0x4b, - 0x8d, 0xf9, 0x90, 0x7e, 0xb5, 0x37, 0x90, 0x07, 0x50, 0x2a, 0x64, 0x52, - 0x06, 0x01, 0x50, 0x9c, 0x53, 0x22, 0x7c, 0xb8, 0x15, 0x3d, 0x2e, 0x52, - 0x65, 0xc5, 0x15, 0x25, 0x67, 0x73, 0x42, 0xb9, 0xf9, 0x24, 0xa5, 0x97, - 0xe7, 0x89, 0x87, 0xad, 0x1d, 0x41, 0xec, 0x64, 0x4d, 0x06, 0xf9, 0x73, - 0xd6, 0xb4, 0xf4, 0x48, 0x17, 0xcc, 0x2a, 0x6b, 0x49, 0xcf, 0x42, 0x63, - 0x13, 0x7d, 0x74, 0x24, 0x97, 0x90, 0xd8, 0xab, 0x96, 0xda, 0x52, 0x5a, - 0x7f, 0x1e, 0x6b, 0x7f, 0x6b, 0xcd, 0x1b, 0x18, 0x14, 0xb5, 0x3d, 0x85, - 0x76, 0xad, 0x50, 0x48, 0xeb, 0x0a, 0x86, 0xf0, 0x21, 0xb9, 0xb5, 0xf3, - 0x31, 0xed, 0x51, 0x45, 0x63, 0x87, 0x07, 0x9a, 0x97, 0x2d, 0x07, 0x15, - 0xa9, 0xa2, 0x30, 0x00, 0xa7, 0x64, 0x56, 0x45, 0x89, 0xe6, 0x62, 0x90, - 0xcb, 0x4c, 0x08, 0xda, 0x5f, 0x7a, 0x88, 0xcb, 0x5a, 0x28, 0xdc, 0x87, - 0x3b, 0x0c, 0x32, 0x55, 0x71, 0x2b, 0x33, 0x11, 0x5b, 0x2a, 0x66, 0x4e, - 0xa0, 0xa6, 0xa2, 0x7e, 0x95, 0xa2, 0x46, 0x77, 0x0e, 0xd4, 0xd3, 0x48, - 0x08, 0xcd, 0x30, 0xd5, 0x6c, 0x22, 0xbc, 0x8d, 0xe9, 0x4b, 0x1d, 0x43, - 0x1a, 0x26, 0x02, 0xa4, 0x55, 0xa1, 0x03, 0x2c, 0x2d, 0xb1, 0x63, 0xc0, - 0xab, 0x70, 0xe9, 0xa5, 0xba, 0xd3, 0x62, 0x2e, 0x47, 0xa7, 0x44, 0xbd, - 0xab, 0x3b, 0x53, 0xb6, 0xdb, 0x36, 0x54, 0x7f, 0x9c, 0x55, 0x45, 0x92, - 0x54, 0x4b, 0x66, 0x6e, 0x82, 0xad, 0xc1, 0xa7, 0x16, 0x3f, 0x30, 0xa8, - 0x2c, 0xbf, 0x0e, 0x99, 0x12, 0x8f, 0x99, 0x45, 0x67, 0x6a, 0x90, 0x2c, - 0x53, 0xf0, 0x38, 0xc0, 0xa6, 0x49, 0x40, 0xe0, 0x77, 0xa6, 0x19, 0x14, - 0x56, 0x05, 0x91, 0x35, 0xc0, 0xed, 0x55, 0xa6, 0x9b, 0xcc, 0x18, 0x22, - 0x98, 0x58, 0x80, 0xaa, 0xfa, 0x50, 0x2a, 0xc4, 0x68, 0xe9, 0x96, 0x62, - 0x59, 0x33, 0xda, 0xb7, 0x02, 0x15, 0x14, 0x21, 0x31, 0xd9, 0x22, 0x93, - 0x23, 0xd2, 0x8b, 0x10, 0x35, 0x91, 0x58, 0x55, 0x77, 0xb7, 0x4e, 0xe8, - 0x29, 0x05, 0x8a, 0x72, 0xe9, 0xf0, 0xb7, 0x6c, 0x1a, 0xab, 0x2e, 0x9b, - 0x93, 0xf2, 0x1a, 0xab, 0xf7, 0x0d, 0x86, 0xa6, 0x9b, 0x37, 0x4c, 0x52, - 0x36, 0x89, 0x26, 0x33, 0x9a, 0xad, 0x02, 0xe5, 0x39, 0x74, 0xf9, 0xa3, - 0xed, 0x9a, 0xa8, 0x46, 0x38, 0xa1, 0xd8, 0xa4, 0xc2, 0x96, 0xa4, 0x61, - 0x4b, 0x40, 0x05, 0x14, 0x80, 0x29, 0x68, 0x10, 0x94, 0xb4, 0x01, 0x2c, - 0x55, 0x6d, 0x05, 0x00, 0x4e, 0x12, 0x9f, 0x82, 0x3b, 0x50, 0x48, 0xe0, - 0x69, 0xf9, 0xa4, 0x23, 0xa8, 0x8a, 0xd6, 0x24, 0xfb, 0xb0, 0xaf, 0xe5, - 0x56, 0x15, 0x1b, 0xb7, 0x15, 0x77, 0x2a, 0xc3, 0xf6, 0x1f, 0xe2, 0x6a, - 0x77, 0xca, 0x2a, 0x6e, 0x50, 0xbb, 0x80, 0xa5, 0xf3, 0x28, 0x01, 0x3c, - 0xc6, 0xa4, 0xcd, 0x21, 0x8f, 0x8f, 0xef, 0x55, 0xc5, 0xcd, 0x20, 0x2c, - 0x47, 0xf2, 0x9a, 0x95, 0xa4, 0xf7, 0xa0, 0x08, 0x5e, 0x74, 0x1d, 0x5a, - 0xa9, 0xbc, 0xb9, 0x7e, 0x3a, 0x55, 0x08, 0x78, 0xe6, 0x91, 0xba, 0x53, - 0x40, 0x67, 0x4e, 0x39, 0x22, 0xb1, 0xa7, 0xe3, 0x35, 0x53, 0xd8, 0xba, - 0x65, 0x4f, 0x30, 0xf3, 0xcd, 0x20, 0x91, 0x8e, 0x79, 0xac, 0xac, 0x5b, - 0x91, 0x07, 0xda, 0x1c, 0xb1, 0xe6, 0xad, 0xa6, 0xe2, 0xa3, 0x9a, 0x87, - 0xa0, 0x22, 0x5c, 0x62, 0xac, 0x47, 0xc2, 0x52, 0x18, 0xbb, 0xaa, 0xb3, - 0x55, 0x81, 0x0c, 0xdf, 0x70, 0xd5, 0x68, 0xb8, 0x93, 0xf1, 0xaa, 0xe8, - 0x4a, 0xf8, 0x8d, 0x18, 0x46, 0x6a, 0x56, 0x5e, 0x2b, 0x9d, 0x1a, 0xb2, - 0xb4, 0xe2, 0x84, 0x39, 0x5a, 0x63, 0xe8, 0x55, 0x54, 0xcb, 0x9e, 0xbd, - 0x6a, 0xed, 0xac, 0x7b, 0x24, 0xc8, 0xa1, 0xb2, 0xba, 0x1a, 0xf0, 0x4f, - 0x2a, 0xae, 0x03, 0x9a, 0x73, 0xcc, 0xcd, 0xf7, 0x9c, 0x9a, 0xd1, 0x33, - 0x3b, 0x15, 0x9b, 0x14, 0xda, 0x86, 0x5a, 0x13, 0x34, 0xd2, 0xe0, 0x52, - 0x48, 0x06, 0x99, 0x85, 0x47, 0xe7, 0x56, 0x8a, 0x99, 0x9b, 0xa8, 0x34, - 0xc8, 0xde, 0xb4, 0xcc, 0x9a, 0xd1, 0x53, 0x46, 0x4e, 0x6c, 0x29, 0x2b, - 0x4b, 0x12, 0x25, 0x41, 0xd2, 0x5a, 0xa1, 0x12, 0x1a, 0x8e, 0xa4, 0x61, - 0x4c, 0x34, 0x01, 0x19, 0xa8, 0x65, 0x38, 0x14, 0xc4, 0x44, 0x16, 0xa4, - 0x44, 0xe6, 0xa4, 0x65, 0xc8, 0xa2, 0x26, 0xb4, 0xad, 0x2c, 0xc7, 0xf1, - 0xd4, 0x81, 0xa2, 0x91, 0x2c, 0x7d, 0x05, 0x3f, 0xb5, 0x31, 0x08, 0x2a, - 0x39, 0xa0, 0x59, 0x3e, 0xf0, 0xa1, 0x08, 0x45, 0x89, 0x13, 0xa2, 0xd4, - 0x9d, 0xa9, 0x0c, 0x55, 0xac, 0x2f, 0x12, 0x39, 0x8f, 0xcb, 0x23, 0xd7, - 0xfa, 0x55, 0x44, 0x4c, 0xe7, 0xcc, 0xa4, 0xf5, 0xa8, 0xcb, 0x66, 0xa2, - 0xc6, 0x82, 0x66, 0x93, 0xbd, 0x20, 0x1a, 0x4d, 0x0b, 0xd6, 0x98, 0x8d, - 0xed, 0x24, 0x6c, 0x8b, 0x35, 0xac, 0x1e, 0x84, 0x43, 0x17, 0x83, 0x4d, - 0xf2, 0xc1, 0xa6, 0x21, 0xa6, 0x1f, 0x43, 0x49, 0xe5, 0x37, 0xd6, 0x91, - 0x23, 0xbc, 0x8c, 0x8e, 0x95, 0x1b, 0x42, 0x16, 0x84, 0x03, 0x37, 0x62, - 0xa2, 0x79, 0xf8, 0xe6, 0x81, 0x99, 0x9a, 0x84, 0xf8, 0xe8, 0x6b, 0x0e, - 0x6e, 0x64, 0xcd, 0x31, 0xa1, 0x94, 0xa2, 0x82, 0xc7, 0x51, 0x41, 0x21, - 0x45, 0x31, 0x8b, 0x8a, 0x31, 0x48, 0x44, 0x89, 0x03, 0xbf, 0x41, 0x56, - 0xe2, 0xd3, 0xff, 0x00, 0xbc, 0x68, 0x25, 0x96, 0xd2, 0xd2, 0x30, 0xbd, - 0x2a, 0x74, 0x86, 0x35, 0xfe, 0x11, 0x48, 0x90, 0x64, 0xe6, 0x8e, 0x94, - 0xc4, 0x47, 0x8c, 0xd3, 0x84, 0x74, 0x86, 0x76, 0x1b, 0xa8, 0xc9, 0xf5, - 0xa0, 0xd4, 0x5a, 0x31, 0x48, 0x07, 0x88, 0xd8, 0xf6, 0xa9, 0x16, 0xdd, - 0xcd, 0x30, 0x24, 0x16, 0x9f, 0xde, 0x6a, 0x7f, 0x95, 0x02, 0x7d, 0xe2, - 0x28, 0x01, 0x0c, 0xf6, 0xd1, 0xf4, 0x1f, 0xa5, 0x30, 0xea, 0x3f, 0xdd, - 0x8e, 0x8b, 0x01, 0x19, 0xbd, 0xb8, 0x6e, 0x9c, 0x54, 0x12, 0x35, 0xcb, - 0x7f, 0x1d, 0x55, 0x90, 0x08, 0x90, 0x48, 0xdf, 0x78, 0xd5, 0xa5, 0x4c, - 0x52, 0x02, 0x55, 0xe2, 0xa5, 0x1c, 0xd0, 0x05, 0x0b, 0x94, 0xf9, 0xab, - 0x16, 0xfe, 0x2f, 0xdd, 0x33, 0x55, 0x30, 0x83, 0x33, 0xd1, 0x73, 0x4f, - 0xf2, 0x30, 0xbd, 0xf3, 0x58, 0xdc, 0xd8, 0xab, 0xe4, 0xb0, 0x6e, 0x6a, - 0xdd, 0xb1, 0xc8, 0xc1, 0xed, 0x4a, 0x48, 0x22, 0x49, 0x3f, 0x4e, 0x3b, - 0xd4, 0xe3, 0xee, 0x54, 0xb1, 0x8a, 0x9c, 0xd3, 0xa4, 0x87, 0x8c, 0xd3, - 0x4c, 0x19, 0x46, 0x61, 0x9a, 0xaa, 0x99, 0xf3, 0x2a, 0xfa, 0x02, 0x34, - 0x60, 0x3d, 0x2a, 0xc6, 0x6b, 0x13, 0x46, 0x41, 0x24, 0x6c, 0xfd, 0x05, - 0x3d, 0x2d, 0x8f, 0x7a, 0x4c, 0x11, 0x20, 0xb6, 0x45, 0xa7, 0x84, 0x0b, - 0x40, 0xc7, 0x6e, 0xc5, 0x34, 0xc9, 0x56, 0xa2, 0x27, 0x24, 0x30, 0xcb, - 0x4c, 0xf3, 0x0d, 0x6a, 0xa9, 0x99, 0x3a, 0x83, 0x79, 0x3d, 0xe8, 0x22, - 0xad, 0x44, 0xca, 0xe3, 0x29, 0xb5, 0x68, 0x90, 0xa5, 0xa0, 0x61, 0x45, - 0x20, 0x0a, 0xaf, 0xff, 0x00, 0x2d, 0xa9, 0x8c, 0x93, 0x14, 0xcc, 0x73, - 0x50, 0x01, 0xb6, 0x9a, 0x56, 0x8b, 0x81, 0x14, 0x9f, 0x28, 0xa8, 0x02, - 0x17, 0x6c, 0xd5, 0x08, 0x9a, 0x1b, 0x76, 0x90, 0xf4, 0xab, 0x70, 0xd8, - 0x3e, 0xf1, 0x52, 0x33, 0x4a, 0x1b, 0x60, 0x95, 0x61, 0x78, 0x34, 0x84, - 0x4f, 0x8c, 0x8a, 0x5c, 0x53, 0x00, 0xc5, 0x14, 0x80, 0x61, 0x14, 0x62, - 0x90, 0x0b, 0x59, 0x1a, 0xfd, 0xa9, 0xb9, 0x48, 0xb1, 0xd9, 0x8f, 0xf2, - 0xab, 0x83, 0xb1, 0x32, 0x31, 0x9a, 0xc2, 0x28, 0xa1, 0xf9, 0x8e, 0x5a, - 0xb3, 0x5e, 0xd7, 0x93, 0x83, 0x51, 0x72, 0xc6, 0x7d, 0x9d, 0x87, 0x4a, - 0x6e, 0xc7, 0x14, 0x05, 0xc3, 0x69, 0xee, 0x28, 0x14, 0x86, 0x6f, 0xe9, - 0xcf, 0xfb, 0xac, 0x55, 0xe0, 0xd4, 0xd1, 0x0c, 0x78, 0x6a, 0x76, 0xea, - 0x64, 0x86, 0xea, 0x43, 0x2e, 0x29, 0x0c, 0x3e, 0xd1, 0x50, 0xbc, 0xc5, - 0xa8, 0x10, 0xcd, 0xa6, 0xab, 0xcf, 0xc5, 0x00, 0x64, 0x6a, 0x1c, 0xf1, - 0x54, 0x7c, 0xba, 0x2e, 0x68, 0x90, 0x9e, 0x55, 0x37, 0xcb, 0x22, 0x80, - 0xb0, 0x98, 0x34, 0xf1, 0x1b, 0x1e, 0x94, 0x08, 0x7a, 0xdb, 0x48, 0xdd, - 0xaa, 0xc2, 0x69, 0xec, 0x7a, 0x9a, 0xa2, 0x2e, 0x4e, 0x9a, 0x72, 0xf7, - 0xa9, 0xd2, 0xd6, 0x34, 0xfe, 0x1a, 0x9b, 0x88, 0x97, 0x66, 0x29, 0x76, - 0xd0, 0x21, 0xd4, 0x50, 0x20, 0xa4, 0xc5, 0x00, 0x20, 0x14, 0xf0, 0x28, - 0x03, 0xb1, 0x5b, 0x67, 0xff, 0x00, 0x26, 0xa5, 0x16, 0x9e, 0xad, 0x41, - 0xa8, 0xef, 0x2e, 0x04, 0xfb, 0xc4, 0x1a, 0x69, 0xb9, 0xb6, 0x8f, 0xa0, - 0xfd, 0x28, 0x18, 0xc3, 0xa8, 0xff, 0x00, 0x71, 0x2a, 0x23, 0x7b, 0x70, - 0xdd, 0x38, 0xa3, 0x94, 0x06, 0x7f, 0xa4, 0x3f, 0x56, 0x34, 0xa2, 0xd8, - 0x9e, 0xa6, 0x98, 0x12, 0xad, 0xb2, 0xd4, 0xab, 0x02, 0xff, 0x00, 0x76, - 0x80, 0x24, 0x11, 0xd4, 0x4c, 0x3f, 0x79, 0x40, 0x12, 0x85, 0xe2, 0x97, - 0xcb, 0x34, 0x00, 0xf1, 0x15, 0x3f, 0x6e, 0x28, 0x02, 0xac, 0xe3, 0x71, - 0xac, 0x0d, 0x53, 0x70, 0x2c, 0x81, 0x4e, 0x18, 0x7a, 0x56, 0x9b, 0x89, - 0x14, 0xe0, 0x42, 0x3a, 0x8a, 0x9f, 0x8a, 0xe6, 0x92, 0x3a, 0x11, 0x0c, - 0xcc, 0x3a, 0x54, 0x70, 0xfc, 0x87, 0x9a, 0x4c, 0x48, 0x25, 0x6c, 0xb5, - 0x4e, 0x25, 0xf9, 0x40, 0xc5, 0x12, 0x2d, 0x12, 0xad, 0x49, 0xf3, 0x15, - 0xa5, 0x70, 0x21, 0xfb, 0x23, 0x37, 0xb5, 0x2a, 0x69, 0xc8, 0xa7, 0x27, - 0x93, 0x4f, 0x98, 0x14, 0x49, 0xc5, 0xbc, 0x6b, 0xda, 0x9d, 0xb5, 0x45, - 0x49, 0x41, 0xb8, 0x0a, 0x6e, 0xfa, 0xb5, 0x02, 0x39, 0xc4, 0xdd, 0x49, - 0x9a, 0xd1, 0x40, 0xc9, 0xd4, 0x1b, 0x4c, 0xad, 0x6c, 0x67, 0x70, 0xa4, - 0xa6, 0x01, 0x4a, 0x4d, 0x48, 0xc8, 0xe9, 0xb4, 0xc4, 0x34, 0x9a, 0x7a, - 0xf3, 0x48, 0x64, 0xde, 0x53, 0x7a, 0x53, 0x5a, 0x36, 0x03, 0xa5, 0x48, - 0x11, 0x66, 0xa0, 0x6f, 0xf5, 0xb4, 0xc0, 0x92, 0x9a, 0x6a, 0x46, 0x3d, - 0x69, 0x0d, 0x08, 0x08, 0x7c, 0x97, 0x9d, 0xba, 0x71, 0x56, 0xe3, 0xb1, - 0xe3, 0x9a, 0xa6, 0xc0, 0xb7, 0x6f, 0x6e, 0xb0, 0xf4, 0x15, 0x6b, 0x15, - 0x00, 0x3b, 0x14, 0x95, 0x42, 0x26, 0x46, 0xe2, 0x97, 0x75, 0x48, 0xc6, - 0x97, 0xa6, 0xef, 0xa0, 0x04, 0xdf, 0x4e, 0x06, 0x80, 0x0c, 0xd6, 0x76, - 0xaf, 0x26, 0xc8, 0x01, 0x1e, 0xf5, 0x48, 0x96, 0x60, 0xc8, 0xed, 0x25, - 0x20, 0x84, 0x9a, 0x82, 0x8b, 0x09, 0x67, 0xbc, 0x72, 0x0d, 0x59, 0x4d, - 0x35, 0x3a, 0xbd, 0x17, 0x01, 0xb7, 0x56, 0x91, 0x0b, 0x77, 0xc0, 0x19, - 0xc7, 0x15, 0xcd, 0x79, 0x4c, 0x1c, 0xf1, 0xdc, 0xd5, 0x74, 0x25, 0x6e, - 0x6a, 0xd8, 0xb6, 0xd5, 0xad, 0x28, 0xdf, 0x75, 0x24, 0x36, 0x49, 0x4f, - 0x0d, 0x54, 0x40, 0xd6, 0x7a, 0x88, 0xe6, 0x90, 0x08, 0xab, 0x52, 0xaa, - 0xd2, 0x01, 0x64, 0xe0, 0x56, 0x6d, 0xdc, 0xc1, 0x01, 0x26, 0x80, 0x31, - 0x66, 0x9c, 0x49, 0x25, 0x34, 0x73, 0x52, 0xcd, 0x90, 0xb4, 0x99, 0xa2, - 0xc0, 0xc7, 0x62, 0xa4, 0x49, 0x36, 0xf4, 0xa9, 0xdc, 0x56, 0x2c, 0xc7, - 0x77, 0x8e, 0xd5, 0x66, 0x3b, 0x85, 0x7a, 0x35, 0x25, 0xc4, 0x96, 0x93, - 0x35, 0xa1, 0x02, 0x6e, 0x14, 0x9b, 0xa8, 0x24, 0x5a, 0x28, 0x00, 0xc9, - 0x1d, 0xa9, 0x54, 0xe7, 0xb5, 0x02, 0x25, 0xc5, 0x19, 0xc5, 0x02, 0x3a, - 0x83, 0x77, 0x70, 0xdd, 0x38, 0xa6, 0xfe, 0xfd, 0xfa, 0xb9, 0xa6, 0x6e, - 0x28, 0xb7, 0xcf, 0x5a, 0x91, 0x6d, 0x94, 0x52, 0x02, 0x65, 0x84, 0x7a, - 0x53, 0x84, 0x74, 0x08, 0x77, 0x97, 0x4b, 0x85, 0xfe, 0xf5, 0x03, 0x0f, - 0x36, 0x35, 0xa4, 0xfb, 0x48, 0xec, 0x28, 0x00, 0xf3, 0x9c, 0xf6, 0xc5, - 0x39, 0x23, 0x24, 0xe4, 0xd0, 0x05, 0x90, 0x38, 0xa4, 0xa0, 0x03, 0x35, - 0x0c, 0x92, 0xd3, 0x11, 0x09, 0xa8, 0x9e, 0x14, 0x6e, 0xa2, 0x98, 0x15, - 0xa5, 0xb4, 0x5c, 0x70, 0x2b, 0x3e, 0xe2, 0xd4, 0xaf, 0x4a, 0x24, 0x69, - 0x06, 0x57, 0xfb, 0x3e, 0xe3, 0x52, 0xad, 0x9d, 0x73, 0xb3, 0x72, 0x45, - 0xb5, 0x5a, 0x78, 0x85, 0x45, 0x48, 0x0f, 0xc0, 0x14, 0x6e, 0x14, 0xec, - 0x31, 0x4b, 0x54, 0x7b, 0xeb, 0x45, 0x03, 0x27, 0x31, 0xbb, 0x8d, 0x27, - 0x35, 0xa2, 0x81, 0x9f, 0x38, 0x51, 0x56, 0x48, 0x51, 0x55, 0x61, 0x08, - 0x69, 0xb4, 0x00, 0x86, 0x9b, 0x9a, 0x40, 0x47, 0xe6, 0x8a, 0x63, 0x4c, - 0x2b, 0x3b, 0x94, 0x46, 0xd3, 0x0a, 0x8f, 0xce, 0x1e, 0xb4, 0x5c, 0x00, - 0x48, 0x1a, 0xb5, 0x6d, 0xa3, 0x53, 0x8a, 0xce, 0x52, 0x2a, 0x31, 0x3a, - 0x6b, 0xbd, 0x35, 0x52, 0x34, 0x2b, 0x8e, 0x14, 0x93, 0x59, 0x3a, 0x90, - 0x48, 0x2d, 0xc9, 0x26, 0xaa, 0x0e, 0xe9, 0x12, 0xce, 0x73, 0xcc, 0xf3, - 0x24, 0x24, 0x74, 0xa6, 0xb9, 0xf9, 0xa9, 0xdc, 0x76, 0x26, 0x19, 0x22, - 0x94, 0xc7, 0xc5, 0x4a, 0x60, 0x3a, 0x3c, 0x53, 0xe0, 0x29, 0x2b, 0x9f, - 0x6a, 0x04, 0x5c, 0x50, 0x07, 0x4a, 0x90, 0x55, 0x00, 0xb9, 0xc5, 0x2f, - 0x9a, 0x28, 0x01, 0x0c, 0xb5, 0x19, 0x91, 0x8d, 0x00, 0x27, 0x98, 0xde, - 0xb5, 0x34, 0x79, 0x22, 0x90, 0xc9, 0x31, 0x4d, 0xa0, 0x42, 0x35, 0x3e, - 0x3a, 0x40, 0x3f, 0x15, 0x4b, 0x52, 0x8c, 0x3a, 0xaa, 0x9f, 0xf3, 0xc5, - 0x5a, 0x21, 0x95, 0x3e, 0xc0, 0x31, 0xd6, 0xa5, 0x4b, 0x55, 0x5a, 0x86, - 0xcb, 0x25, 0x1b, 0x57, 0xa5, 0x31, 0xde, 0xa4, 0x0c, 0x9b, 0xc9, 0x82, - 0x9f, 0xbd, 0x54, 0x0b, 0x03, 0xd2, 0xac, 0x09, 0xed, 0x31, 0xe6, 0x63, - 0xd6, 0xb4, 0x56, 0x3a, 0x98, 0xb0, 0x63, 0xfa, 0x75, 0xa2, 0xb5, 0x33, - 0x12, 0xa2, 0x90, 0xf1, 0xc5, 0x24, 0x03, 0xa1, 0x27, 0x6e, 0x0f, 0x5a, - 0xb0, 0x38, 0x14, 0x86, 0x57, 0xb8, 0x7d, 0xdf, 0x2d, 0x65, 0xdf, 0x63, - 0xcb, 0xda, 0x68, 0x1a, 0x32, 0x9a, 0x2a, 0x45, 0x14, 0x8b, 0x1f, 0x49, - 0x8e, 0x68, 0x28, 0x90, 0x0e, 0x29, 0x6a, 0x09, 0x03, 0x42, 0xcb, 0xb1, - 0xb3, 0x4e, 0xc2, 0xb9, 0x60, 0x5d, 0xb9, 0xa7, 0x89, 0x19, 0xba, 0xb5, - 0x55, 0x88, 0x14, 0xff, 0x00, 0xbf, 0x4e, 0x8c, 0x65, 0xaa, 0xac, 0x49, - 0x6d, 0x13, 0x8a, 0x7f, 0x14, 0x99, 0x21, 0x8a, 0x31, 0x40, 0x0b, 0x51, - 0x3d, 0x16, 0x03, 0xb4, 0x09, 0x4f, 0x09, 0x41, 0xb0, 0xec, 0x01, 0xde, - 0x93, 0xcc, 0x8c, 0x50, 0x02, 0x1b, 0x81, 0xd9, 0x69, 0xbe, 0x73, 0x9e, - 0x82, 0x80, 0x1a, 0x7c, 0xe3, 0xde, 0xb9, 0xfb, 0x9d, 0x53, 0xca, 0xb8, - 0x2a, 0xd2, 0x55, 0x72, 0xfb, 0xa2, 0x4f, 0xde, 0xb1, 0xa7, 0xa7, 0xde, - 0xdb, 0xdc, 0x60, 0x6f, 0x15, 0xae, 0x91, 0x2d, 0x62, 0xa5, 0xd0, 0xb9, - 0x44, 0x94, 0x01, 0x4e, 0xad, 0x09, 0x17, 0x35, 0x1b, 0x1a, 0x04, 0x42, - 0xcf, 0x51, 0xd3, 0x00, 0xa2, 0x81, 0x8c, 0x35, 0x04, 0xb1, 0xe6, 0x98, - 0xd1, 0x5b, 0x6f, 0xb5, 0x1b, 0x4d, 0x65, 0xca, 0x6d, 0xcc, 0x34, 0x8a, - 0x84, 0xb9, 0xdf, 0x8a, 0xb5, 0x4c, 0x8f, 0x68, 0x32, 0xe5, 0xca, 0xa1, - 0xc5, 0x16, 0xfb, 0xb6, 0xf3, 0x56, 0xe3, 0x62, 0x39, 0xae, 0x4a, 0x6a, - 0x3a, 0x64, 0x85, 0x14, 0xc0, 0x28, 0xa0, 0x41, 0x45, 0x50, 0x08, 0x4d, - 0x30, 0x9a, 0x43, 0x23, 0x67, 0xc5, 0x20, 0xff, 0x00, 0x55, 0x4e, 0xc0, - 0x67, 0xaa, 0x33, 0xb9, 0xe6, 0xa0, 0x96, 0x62, 0xa7, 0x07, 0xad, 0x4c, - 0xa1, 0xd4, 0xab, 0x90, 0x99, 0x58, 0xf7, 0xa8, 0xdd, 0xda, 0xb9, 0xc0, - 0x96, 0xd2, 0x6f, 0x9f, 0x69, 0xef, 0x5b, 0x30, 0xce, 0xf1, 0x91, 0xcd, - 0x46, 0xe5, 0xa6, 0x69, 0x5c, 0xeb, 0xf7, 0xed, 0x6d, 0xb3, 0x78, 0x03, - 0x6e, 0xda, 0xe7, 0xb5, 0x3b, 0xcb, 0x89, 0xf8, 0x92, 0x53, 0x8f, 0x4a, - 0xb8, 0xab, 0x0f, 0xcc, 0x5b, 0x1c, 0x2a, 0x7c, 0xd5, 0x25, 0xcc, 0xa9, - 0xb7, 0xe5, 0xa8, 0x4d, 0x89, 0x8f, 0xfb, 0x7a, 0x05, 0xe0, 0x54, 0x2f, - 0x7c, 0xc6, 0x9a, 0x89, 0x44, 0x6d, 0x23, 0x95, 0xeb, 0x5a, 0x3a, 0x6c, - 0x65, 0x13, 0x9e, 0xf5, 0x6c, 0x92, 0xed, 0x2e, 0x69, 0x90, 0x3d, 0x95, - 0xb1, 0x40, 0x8c, 0xd3, 0x18, 0x86, 0x9e, 0xb1, 0x66, 0x91, 0x42, 0xf9, - 0x27, 0x35, 0x32, 0xa6, 0x05, 0x04, 0x92, 0xaa, 0xd4, 0x72, 0x75, 0xa0, - 0x44, 0x75, 0x22, 0xd2, 0x01, 0xf5, 0x4b, 0x50, 0xfe, 0x1f, 0xad, 0x51, - 0x24, 0x4b, 0x2f, 0xcb, 0xcd, 0x46, 0xf3, 0xe3, 0xf8, 0xab, 0x3b, 0x14, - 0x56, 0x6b, 0xd4, 0x15, 0x4e, 0x7b, 0xa6, 0x7f, 0xbb, 0x42, 0x02, 0x9b, - 0x2e, 0x4e, 0x69, 0x0e, 0x05, 0x3b, 0x95, 0x62, 0x1d, 0xce, 0x1f, 0x2a, - 0x71, 0x57, 0x62, 0xbe, 0x9c, 0x0f, 0x98, 0xe6, 0x95, 0xae, 0x04, 0xff, - 0x00, 0x6e, 0x24, 0x7c, 0xc9, 0x47, 0xdb, 0x2a, 0x85, 0xca, 0x39, 0x6f, - 0x13, 0xb8, 0xa9, 0x96, 0xea, 0x13, 0x4b, 0x51, 0x72, 0x92, 0x09, 0xa1, - 0xfe, 0xf5, 0x0d, 0x3c, 0x67, 0xf8, 0xa8, 0xe6, 0x17, 0x29, 0x56, 0x7b, - 0xa8, 0xd7, 0xa1, 0xcd, 0x65, 0xcc, 0xc6, 0x47, 0xa0, 0x69, 0x11, 0x62, - 0x9b, 0x81, 0x4a, 0xe5, 0x87, 0x14, 0xdd, 0xf8, 0xa4, 0x21, 0x86, 0x4a, - 0x4d, 0xc6, 0xae, 0xc2, 0xb8, 0xf1, 0x27, 0xa8, 0xa9, 0x01, 0x8d, 0xbd, - 0x28, 0x13, 0x1e, 0x23, 0xf4, 0x34, 0xe1, 0x01, 0xf5, 0xa7, 0x72, 0x09, - 0x92, 0x2a, 0xbb, 0x1a, 0x71, 0xd6, 0x99, 0x2c, 0x7d, 0x2d, 0x04, 0x0b, - 0x46, 0x28, 0x00, 0xc5, 0x26, 0xda, 0x00, 0xea, 0xbc, 0xe7, 0xec, 0x29, - 0x7f, 0x78, 0xdd, 0xe9, 0x9b, 0x8f, 0x10, 0x16, 0xea, 0x6a, 0x41, 0x6d, - 0x48, 0x43, 0xc4, 0x20, 0x54, 0x98, 0xc5, 0x00, 0x57, 0xbc, 0x97, 0xc9, - 0x81, 0x9a, 0xbc, 0xd6, 0xea, 0x76, 0x92, 0xe5, 0x89, 0xf5, 0x23, 0xaf, - 0xb9, 0xae, 0x85, 0xfc, 0x33, 0x35, 0xf1, 0x89, 0x6d, 0x75, 0x25, 0xbc, - 0xbb, 0x90, 0xe2, 0xbb, 0xad, 0x13, 0x56, 0x4b, 0x98, 0x42, 0xb1, 0xf9, - 0xab, 0xcf, 0xa9, 0xa4, 0xae, 0x77, 0x7c, 0x51, 0x36, 0x41, 0xa7, 0x66, - 0xb6, 0x47, 0x38, 0xb5, 0x1c, 0x87, 0x8a, 0xa4, 0x26, 0x56, 0xcd, 0x46, - 0x25, 0x56, 0x3c, 0x1a, 0x00, 0x7e, 0x69, 0x73, 0x4c, 0x00, 0xd3, 0x68, - 0x01, 0x36, 0x8a, 0x6b, 0x2d, 0x34, 0x04, 0x0e, 0xb5, 0x46, 0x51, 0x89, - 0x81, 0xad, 0x09, 0xea, 0x2c, 0x91, 0xef, 0x5a, 0x21, 0x18, 0x8e, 0x93, - 0x1a, 0x1e, 0x6a, 0x23, 0x40, 0x82, 0x8a, 0x06, 0x21, 0x35, 0x19, 0x93, - 0x14, 0x80, 0x4f, 0x32, 0x9a, 0xd2, 0xe0, 0x53, 0x03, 0x36, 0x6b, 0xf7, - 0x17, 0x7b, 0x41, 0x3b, 0x6b, 0x49, 0x3e, 0x61, 0x53, 0x3d, 0x19, 0x4b, - 0x61, 0x66, 0x0a, 0x22, 0xf7, 0xc5, 0x44, 0x0f, 0x6a, 0xb4, 0x4a, 0x1b, - 0x6a, 0xc1, 0x9c, 0xe0, 0x56, 0x7e, 0xa0, 0x37, 0xdc, 0x7e, 0x02, 0x9f, - 0x46, 0x4b, 0xd5, 0x95, 0xc4, 0x75, 0x15, 0xc7, 0x0b, 0x5c, 0x69, 0x96, - 0x43, 0x01, 0xc4, 0x9b, 0xab, 0x4a, 0x1b, 0x82, 0x13, 0x15, 0x56, 0xbb, - 0x2d, 0x12, 0x5c, 0x6a, 0x1f, 0xbb, 0xc6, 0x3a, 0x56, 0x64, 0xb7, 0x26, - 0x43, 0x55, 0xcb, 0x61, 0xf3, 0x13, 0x09, 0x36, 0xae, 0x0d, 0x3b, 0xe5, - 0x7e, 0x6b, 0x3d, 0x88, 0x1e, 0x29, 0x0d, 0x17, 0x34, 0x52, 0x27, 0xb7, - 0x5f, 0x33, 0x02, 0xb6, 0x93, 0x85, 0x14, 0x5f, 0x51, 0x31, 0xf4, 0xe8, - 0x86, 0xe6, 0xab, 0x24, 0xb2, 0x29, 0xc2, 0x98, 0x88, 0xd8, 0x7c, 0xd4, - 0xe5, 0xa4, 0x34, 0x4e, 0xa4, 0x52, 0xee, 0x5f, 0x51, 0x4a, 0xe0, 0x2e, - 0xf5, 0xf5, 0xa8, 0x1f, 0x93, 0x4c, 0x42, 0x0a, 0x75, 0x30, 0x1c, 0x0d, - 0x67, 0x6a, 0x93, 0xf9, 0x45, 0x3e, 0xbf, 0xd2, 0x98, 0x8a, 0x5f, 0x68, - 0x69, 0x3e, 0xe8, 0xc5, 0x54, 0xba, 0xdc, 0x5b, 0x04, 0xd4, 0x21, 0x90, - 0x84, 0xa4, 0x69, 0x11, 0x6a, 0x0d, 0x36, 0x2b, 0xb4, 0x99, 0xa6, 0x53, - 0x0b, 0x0f, 0x5a, 0x90, 0x50, 0x30, 0xa2, 0x98, 0x09, 0x45, 0x2b, 0x92, - 0x14, 0xd6, 0x22, 0x90, 0xc8, 0xc9, 0x15, 0x19, 0x92, 0x98, 0x11, 0x3c, - 0xc0, 0x54, 0x2d, 0x71, 0xe9, 0x55, 0xca, 0x4d, 0xc8, 0x8c, 0xac, 0x68, - 0xdf, 0x54, 0x48, 0xe0, 0xd5, 0x25, 0x20, 0x16, 0x97, 0x14, 0x0c, 0x70, - 0xc8, 0xe9, 0x52, 0x2c, 0xf2, 0x0e, 0xf4, 0x84, 0x4a, 0x2e, 0xdf, 0xbd, - 0x4c, 0x97, 0x39, 0xea, 0x48, 0xa0, 0x4e, 0x25, 0xb8, 0x5f, 0x23, 0xef, - 0x66, 0xac, 0x0a, 0x68, 0xc9, 0xa1, 0x77, 0x01, 0x46, 0x68, 0x24, 0x4c, - 0xd3, 0x77, 0x53, 0x03, 0xb3, 0x0a, 0x05, 0x3c, 0x53, 0x66, 0xe4, 0x80, - 0xd2, 0xd0, 0x21, 0x0d, 0x47, 0xbf, 0x9a, 0x43, 0x1b, 0x73, 0x17, 0x98, - 0x84, 0x11, 0x95, 0x35, 0xc3, 0xeb, 0xda, 0x4b, 0x5a, 0xbf, 0x99, 0x18, - 0xf9, 0x0d, 0x74, 0xd1, 0x77, 0x56, 0x31, 0x97, 0xbb, 0x23, 0x0c, 0xe4, - 0x1a, 0xbb, 0xa6, 0xde, 0x1b, 0x7b, 0xa5, 0x62, 0x78, 0xae, 0x7a, 0xd1, - 0xd0, 0xeb, 0xa4, 0xf5, 0x3b, 0xfb, 0x1b, 0xe4, 0xb9, 0xb7, 0x56, 0x07, - 0x9a, 0xb2, 0xb2, 0x66, 0xb1, 0xa7, 0xb1, 0x32, 0xdc, 0x94, 0x1a, 0x64, - 0xc7, 0x8a, 0xd5, 0x10, 0x51, 0xb9, 0x93, 0xcb, 0x89, 0x9b, 0xd2, 0xa9, - 0x69, 0x88, 0x7c, 0xc9, 0x1c, 0x9e, 0xbd, 0x3f, 0x3a, 0x72, 0xf8, 0x42, - 0x26, 0x86, 0x69, 0x77, 0x50, 0x02, 0x6e, 0xa3, 0x34, 0x0c, 0x5c, 0xd2, - 0x66, 0x80, 0x13, 0x15, 0x46, 0xed, 0x30, 0x73, 0x57, 0x12, 0x47, 0xb2, - 0x7c, 0xbf, 0x85, 0x44, 0xa2, 0x8e, 0x82, 0x11, 0xf8, 0xaa, 0xcf, 0x32, - 0x03, 0xf7, 0x85, 0x50, 0xc3, 0xce, 0x04, 0x71, 0x4c, 0x32, 0x35, 0x4a, - 0x01, 0xbb, 0xe9, 0x3a, 0xd2, 0x65, 0x12, 0xad, 0x05, 0x44, 0x9c, 0x1a, - 0x23, 0x2b, 0x03, 0x33, 0xae, 0x74, 0xb9, 0x03, 0xef, 0x8f, 0x9a, 0xd2, - 0xb5, 0x80, 0x98, 0x79, 0xa7, 0x57, 0x5b, 0x34, 0x28, 0x6c, 0x54, 0xbb, - 0x3f, 0xbf, 0x09, 0xe9, 0x4b, 0xb5, 0xb1, 0xef, 0x4c, 0x3a, 0x0f, 0xb4, - 0x84, 0xae, 0xe6, 0x38, 0xe6, 0xa3, 0xb9, 0xd3, 0x9d, 0xfe, 0x74, 0xab, - 0x4d, 0x6c, 0x4b, 0x32, 0x9f, 0x7c, 0x47, 0x0e, 0x2a, 0xb4, 0xd2, 0x8a, - 0xc1, 0xc2, 0xcc, 0xad, 0xc6, 0x27, 0xcd, 0x56, 0xe0, 0x1c, 0x50, 0x31, - 0x97, 0x08, 0x76, 0x1e, 0x2a, 0x90, 0x1c, 0xd6, 0xf2, 0x8e, 0x82, 0x45, - 0xc9, 0xe3, 0x7f, 0x28, 0x30, 0x1c, 0x0e, 0xb5, 0x02, 0x3e, 0x2b, 0x07, - 0xb0, 0xc7, 0xfd, 0xa3, 0xb5, 0x3b, 0xcf, 0x3e, 0x95, 0x9d, 0x80, 0xbd, - 0x67, 0x20, 0x4c, 0x39, 0xad, 0x34, 0xba, 0x0d, 0xd3, 0x15, 0x8f, 0x53, - 0x5d, 0xc9, 0x7c, 0xcf, 0xa5, 0x39, 0x2e, 0x36, 0x75, 0xc5, 0x69, 0x71, - 0x58, 0x71, 0xd4, 0x23, 0x15, 0x0b, 0x6b, 0x11, 0xad, 0x51, 0x03, 0x3f, - 0xb6, 0xa2, 0xfe, 0xf5, 0x30, 0xeb, 0x91, 0xfa, 0xd1, 0x66, 0x05, 0x59, - 0xbc, 0x43, 0xfd, 0xca, 0xaa, 0xda, 0xec, 0xc7, 0xb9, 0xad, 0x39, 0x45, - 0x72, 0x4b, 0x5d, 0x4e, 0x79, 0xe4, 0xda, 0xcf, 0x5d, 0x1d, 0xb6, 0xe3, - 0x18, 0xcd, 0x62, 0xfe, 0x22, 0x8b, 0x21, 0x31, 0x4b, 0x8a, 0xd1, 0x12, - 0x57, 0x96, 0x53, 0x1f, 0xf0, 0xd7, 0x3d, 0x7b, 0xaa, 0xf9, 0xf2, 0xe3, - 0x67, 0x4a, 0xa9, 0x2d, 0x02, 0x3b, 0x96, 0x2d, 0xef, 0x20, 0x23, 0xae, - 0x2a, 0xb5, 0xec, 0xea, 0x65, 0xf9, 0x6b, 0x9e, 0x37, 0x35, 0x65, 0x36, - 0x76, 0x6a, 0x4d, 0xbe, 0xb5, 0x4c, 0x61, 0x8a, 0x4a, 0x43, 0x01, 0x52, - 0x50, 0x21, 0x69, 0x2a, 0x84, 0x34, 0x9a, 0x63, 0x49, 0x49, 0x81, 0x1f, - 0x9b, 0x50, 0xbc, 0xe2, 0x9d, 0x89, 0x64, 0x2d, 0x71, 0xe9, 0x51, 0x19, - 0x09, 0xab, 0xb1, 0x17, 0x19, 0x9a, 0x4a, 0xa0, 0x16, 0x8a, 0x00, 0x5a, - 0x76, 0x69, 0x00, 0xf0, 0xd4, 0xf5, 0x6a, 0x06, 0x48, 0x0d, 0x3a, 0xa0, - 0x02, 0x9a, 0x5c, 0x0a, 0x60, 0x33, 0xed, 0x2c, 0xa7, 0x83, 0x57, 0x6d, - 0x35, 0x20, 0x4e, 0xd9, 0x68, 0x62, 0x34, 0x70, 0x24, 0x5c, 0x83, 0xc5, - 0x41, 0xb4, 0xa1, 0xe3, 0x8a, 0xa5, 0xa9, 0x90, 0x07, 0x97, 0xd6, 0x9d, - 0xf3, 0x37, 0x7a, 0x62, 0x3b, 0xbd, 0xd4, 0x66, 0x83, 0x52, 0x78, 0xf6, - 0xe2, 0xa5, 0xf9, 0x29, 0x01, 0x04, 0xec, 0x16, 0xaa, 0x97, 0xa6, 0xc4, - 0x89, 0x62, 0x93, 0xb1, 0xa8, 0x6f, 0x6d, 0x52, 0x68, 0xf6, 0xb0, 0xc8, - 0x34, 0x42, 0x56, 0x62, 0xa8, 0xae, 0x8e, 0x13, 0x57, 0xb0, 0x6b, 0x3b, - 0x9e, 0x73, 0xb4, 0xf4, 0xac, 0xec, 0x60, 0xd6, 0xd5, 0x57, 0x50, 0xa4, - 0xf4, 0x34, 0xf4, 0xed, 0x51, 0xad, 0x48, 0x19, 0xe2, 0xbb, 0x4d, 0x3a, - 0xee, 0x39, 0xed, 0xc3, 0x67, 0x9a, 0xe1, 0xf8, 0x19, 0xd0, 0xf5, 0x57, - 0x2d, 0x89, 0x69, 0x25, 0x7e, 0x2b, 0x74, 0x64, 0x66, 0xea, 0x32, 0x7e, - 0xe0, 0x8f, 0x5c, 0xd3, 0xac, 0x76, 0xa4, 0x1b, 0x47, 0xa9, 0x34, 0x48, - 0x6b, 0x62, 0x6d, 0xe2, 0x8c, 0xd0, 0x20, 0xa5, 0xcd, 0x00, 0x2e, 0x69, - 0x69, 0x80, 0xea, 0xaf, 0x74, 0xb9, 0x02, 0x9a, 0x25, 0x92, 0xec, 0xcc, - 0x55, 0x53, 0x18, 0x26, 0xa9, 0x6c, 0x2e, 0xa6, 0x6e, 0xa3, 0x79, 0xe5, - 0xa3, 0x2a, 0xe7, 0x76, 0x2b, 0x9a, 0x92, 0x69, 0x59, 0xfe, 0x62, 0x6b, - 0x6b, 0x59, 0x0a, 0x25, 0xeb, 0x09, 0x78, 0xc1, 0x35, 0xaf, 0x01, 0xdf, - 0xc5, 0x73, 0x6c, 0xcd, 0x65, 0xa8, 0xe7, 0xb6, 0x6e, 0xab, 0xd2, 0x9d, - 0x1c, 0x47, 0xbd, 0x6d, 0x52, 0xd6, 0xb9, 0x10, 0xec, 0x3e, 0x40, 0x91, - 0xaf, 0x26, 0xab, 0x24, 0xeb, 0xbb, 0xad, 0x60, 0x59, 0xa3, 0x03, 0x2c, - 0x8b, 0x52, 0x49, 0x19, 0xd9, 0xf2, 0x55, 0x41, 0xdc, 0x97, 0xa1, 0x94, - 0x96, 0xb2, 0xfd, 0xb3, 0xf7, 0xcb, 0xde, 0xb4, 0x3e, 0xc9, 0xc5, 0x6f, - 0xcb, 0xa8, 0x93, 0xd0, 0x6b, 0x47, 0xb6, 0x9d, 0x11, 0xf5, 0xac, 0xe4, - 0xac, 0x51, 0x05, 0xdd, 0xb4, 0x2c, 0xa4, 0xb2, 0xd7, 0x35, 0x79, 0xa7, - 0x49, 0xbb, 0x74, 0x63, 0x8a, 0x49, 0xdc, 0x56, 0xb1, 0x57, 0x98, 0xc6, - 0x3b, 0xd5, 0xdb, 0x4f, 0xf5, 0x64, 0xb5, 0x44, 0x95, 0x86, 0xb5, 0x3a, - 0x64, 0xb2, 0xb7, 0x7b, 0x0f, 0xba, 0x32, 0x6b, 0x09, 0xf4, 0x99, 0x11, - 0x1e, 0x60, 0x03, 0x46, 0xb9, 0xef, 0xef, 0x5a, 0xa9, 0xde, 0x16, 0x33, - 0x51, 0xe5, 0x98, 0x0f, 0x96, 0x33, 0x55, 0x0d, 0xba, 0x93, 0x58, 0x6c, - 0x6b, 0x2d, 0xc6, 0xfd, 0x95, 0x73, 0x47, 0xc8, 0x9d, 0x05, 0x65, 0x76, - 0xc4, 0x46, 0xd3, 0x0a, 0x44, 0xb9, 0xd9, 0x4e, 0xc6, 0xd1, 0x76, 0x1f, - 0xf6, 0xf9, 0x7a, 0x06, 0x34, 0xdf, 0xb4, 0xcd, 0xfd, 0xe3, 0x56, 0xa2, - 0x4b, 0x91, 0x19, 0x79, 0x18, 0xfd, 0xf3, 0x40, 0xb5, 0x91, 0xf9, 0xe2, - 0xaf, 0x44, 0x66, 0x3b, 0xec, 0x4f, 0xed, 0x47, 0xd8, 0xcf, 0xad, 0x1c, - 0xc1, 0x60, 0xfb, 0x18, 0x1d, 0x5e, 0x9d, 0xf6, 0x78, 0x97, 0xa9, 0xa3, - 0x98, 0x2c, 0x44, 0x24, 0x58, 0xa5, 0xca, 0x56, 0x9d, 0xa6, 0xbf, 0x24, - 0x43, 0x6f, 0xde, 0xc5, 0x65, 0x38, 0x5c, 0xb8, 0xb3, 0x4a, 0x0f, 0x11, - 0xab, 0x7f, 0xac, 0x5c, 0x56, 0x94, 0x3a, 0x9c, 0x32, 0xf4, 0xa9, 0xd6, - 0x23, 0x71, 0x25, 0x96, 0xea, 0x2f, 0x25, 0xb0, 0x6b, 0x8e, 0x91, 0x01, - 0x95, 0xbe, 0xa7, 0xf9, 0xd6, 0xbc, 0xde, 0xe8, 0xa1, 0x1d, 0x45, 0x10, - 0x8a, 0x5f, 0x28, 0x0a, 0xc2, 0xe6, 0xf6, 0x0c, 0x51, 0x4c, 0x43, 0x0d, - 0x36, 0x82, 0x40, 0x53, 0xf3, 0x8a, 0x60, 0x21, 0x7a, 0x89, 0xe5, 0xc5, - 0x3d, 0xc9, 0x2b, 0xbd, 0xc0, 0x15, 0x0b, 0x5c, 0x1e, 0xd5, 0x7c, 0xa4, - 0x36, 0x44, 0x5c, 0xb7, 0x5a, 0x65, 0x59, 0x21, 0x45, 0x00, 0x25, 0x2d, - 0x00, 0x14, 0xb4, 0x00, 0xb4, 0xb4, 0x80, 0x29, 0x45, 0x00, 0x3c, 0x35, - 0x3f, 0x77, 0x15, 0x36, 0x19, 0x13, 0x4d, 0xe9, 0x51, 0x97, 0x26, 0xaa, - 0xc2, 0x1b, 0x4b, 0x4c, 0x0b, 0xb6, 0x97, 0xcd, 0x0b, 0x7f, 0xb3, 0x5a, - 0x1f, 0x6d, 0x8d, 0x86, 0x6b, 0x3b, 0x59, 0x8a, 0x48, 0x95, 0x24, 0x57, - 0xfb, 0xa6, 0x94, 0xd5, 0x19, 0x9d, 0xa6, 0x4d, 0x49, 0x1c, 0x4e, 0xc7, - 0xa5, 0x51, 0xa1, 0x68, 0x46, 0x40, 0xa4, 0x67, 0x0b, 0x41, 0x37, 0x28, - 0xcc, 0xe5, 0x8d, 0x34, 0x35, 0x0c, 0xa4, 0x47, 0x3c, 0xfe, 0x50, 0x18, - 0xa5, 0x49, 0xa4, 0x75, 0xeb, 0x53, 0xd4, 0x2f, 0x72, 0xad, 0xf4, 0x0b, - 0x73, 0x19, 0x47, 0x5a, 0xe4, 0x75, 0x1b, 0x19, 0x6d, 0x1c, 0xef, 0x5c, - 0x2f, 0xad, 0x75, 0x47, 0xde, 0x8d, 0x8c, 0xbe, 0x19, 0x14, 0xc5, 0x68, - 0x58, 0xdf, 0xcb, 0x6e, 0xc3, 0x0d, 0xc5, 0x72, 0xce, 0x3a, 0x1d, 0x11, - 0x67, 0x61, 0xa7, 0xcf, 0xf6, 0x88, 0xb7, 0x54, 0xf3, 0x4e, 0x8b, 0x16, - 0x59, 0xc0, 0xf4, 0xc9, 0xa9, 0xa7, 0xa8, 0xa5, 0xb9, 0x8d, 0xa9, 0xdf, - 0x05, 0x65, 0xf2, 0xb0, 0xf4, 0x1d, 0x43, 0xec, 0xd0, 0x6e, 0xc7, 0xcc, - 0x6b, 0xa1, 0x53, 0xe6, 0x69, 0x13, 0x7b, 0x13, 0xe9, 0x53, 0x49, 0x72, - 0xa6, 0x47, 0xcf, 0x5f, 0x5f, 0x7a, 0xd0, 0x35, 0x8b, 0x5e, 0xf3, 0x28, - 0x29, 0x69, 0x88, 0x5a, 0x7d, 0x30, 0x1c, 0x29, 0xb3, 0x0f, 0x96, 0x9a, - 0x25, 0x8f, 0x87, 0xfd, 0x4f, 0xe3, 0x50, 0xa4, 0x79, 0x62, 0x29, 0xad, - 0x83, 0xa9, 0x4b, 0x54, 0xd1, 0xd6, 0x54, 0xca, 0x8e, 0x7d, 0xab, 0x99, - 0x6b, 0x53, 0x14, 0xa5, 0x66, 0xf9, 0x3d, 0xeb, 0xa7, 0xe2, 0x89, 0x92, - 0xde, 0xc5, 0x59, 0x18, 0x45, 0x2e, 0x15, 0xb3, 0x5a, 0xd6, 0xcf, 0xc8, - 0x39, 0xae, 0x4a, 0x9b, 0x9d, 0x10, 0xd8, 0xd8, 0xb7, 0x6d, 0xc0, 0x54, - 0xcd, 0x18, 0x23, 0x8e, 0xb4, 0x26, 0x4b, 0xd0, 0xcd, 0xb9, 0xb7, 0x79, - 0x32, 0x8e, 0x6a, 0x18, 0xec, 0xbc, 0xbe, 0xe6, 0xa9, 0xae, 0x84, 0xfb, - 0x42, 0xe5, 0xbe, 0x52, 0xb4, 0x61, 0x62, 0xc3, 0x9a, 0x9d, 0x8b, 0xdc, - 0xbf, 0x6b, 0x66, 0x27, 0x93, 0xa5, 0x68, 0x7f, 0x63, 0x2e, 0x2b, 0x68, - 0x4c, 0x86, 0xac, 0x43, 0x26, 0x8e, 0x8b, 0xc9, 0xac, 0xfb, 0xb8, 0x12, - 0x25, 0xe2, 0x94, 0xdd, 0xc0, 0xc1, 0xd5, 0x3c, 0xc6, 0x5d, 0xb1, 0xe6, - 0x9b, 0x0c, 0x6f, 0xe5, 0x61, 0x85, 0x27, 0x6b, 0x15, 0x72, 0x9e, 0xa3, - 0x69, 0x19, 0x8f, 0x20, 0x60, 0xd6, 0x68, 0x27, 0xa2, 0xd6, 0x72, 0xd5, - 0x04, 0x74, 0x67, 0x45, 0x63, 0x3e, 0x6d, 0xf1, 0x54, 0xe7, 0xd4, 0x4a, - 0xdb, 0x49, 0x6d, 0xb3, 0x3b, 0xb2, 0x3a, 0xd4, 0xc3, 0xe1, 0x2d, 0xbd, - 0x4a, 0xd1, 0x9d, 0xe9, 0x4d, 0x64, 0xc5, 0x65, 0x71, 0x32, 0x19, 0x98, - 0x2a, 0x1a, 0xa0, 0x5b, 0x71, 0xaa, 0x8a, 0x04, 0x26, 0xd3, 0x46, 0xca, - 0xb2, 0xc5, 0x58, 0xfb, 0x9a, 0x75, 0x51, 0x98, 0x99, 0xc5, 0x2f, 0xda, - 0x1b, 0xb5, 0x2b, 0x01, 0x0b, 0x5c, 0xb8, 0x3f, 0x78, 0xd3, 0x4d, 0xc3, - 0xfa, 0xd1, 0xca, 0x17, 0x13, 0xcd, 0x73, 0xde, 0x98, 0x4d, 0x30, 0x15, - 0x73, 0x56, 0x6d, 0xe1, 0xf5, 0xa8, 0x94, 0x8a, 0x8a, 0x2f, 0xc5, 0x6f, - 0x57, 0x63, 0x01, 0x6b, 0x16, 0xcd, 0xed, 0x61, 0xec, 0xff, 0x00, 0x2e, - 0x2a, 0x8b, 0x8e, 0x69, 0xdc, 0x04, 0x14, 0x1a, 0x45, 0x0d, 0xa4, 0xc5, - 0x04, 0x89, 0x4d, 0x38, 0xaa, 0x11, 0x1b, 0x48, 0x05, 0x42, 0xf7, 0x1e, - 0x95, 0x4a, 0x06, 0x7c, 0xc5, 0x67, 0x9d, 0x8d, 0x45, 0x92, 0x7a, 0xd6, - 0xbc, 0xb6, 0x33, 0xe6, 0x13, 0x14, 0x62, 0x81, 0x5c, 0x5c, 0x52, 0xe2, - 0x81, 0x0b, 0xb6, 0x93, 0xcb, 0xa0, 0x43, 0x48, 0xc5, 0x36, 0x99, 0x41, - 0x4b, 0x48, 0x62, 0xd1, 0x48, 0x05, 0xa5, 0xa0, 0x07, 0x53, 0xbf, 0x86, - 0xa7, 0xa8, 0x15, 0xcf, 0x5a, 0x4a, 0xb0, 0x16, 0x8a, 0x00, 0x5a, 0x33, - 0x40, 0x16, 0x2d, 0x66, 0x68, 0xdc, 0x62, 0xad, 0x49, 0x78, 0x4d, 0x47, - 0x50, 0x68, 0xf5, 0x05, 0x0a, 0x3b, 0x54, 0xc1, 0xeb, 0x42, 0x04, 0x72, - 0x3f, 0x89, 0xc5, 0x55, 0x96, 0x44, 0xfe, 0x1e, 0x69, 0xdc, 0x45, 0x39, - 0x32, 0x4d, 0x25, 0x4b, 0x2d, 0x10, 0x5d, 0x28, 0x92, 0x32, 0x0d, 0x54, - 0xd3, 0x66, 0x90, 0x48, 0x63, 0xcf, 0xc8, 0x3f, 0xc6, 0x94, 0xb6, 0x08, - 0xee, 0x68, 0x3e, 0x0d, 0x32, 0xe2, 0xde, 0x3b, 0xab, 0x46, 0x89, 0xc7, - 0x5e, 0x2b, 0x4a, 0x6e, 0xd2, 0x46, 0x75, 0x15, 0xd1, 0xc2, 0x4d, 0x1f, - 0x95, 0x33, 0x27, 0xbf, 0xf5, 0xa6, 0xf4, 0xab, 0xab, 0xf1, 0x1a, 0x41, - 0xe8, 0x6c, 0xe8, 0x9a, 0x83, 0x47, 0xbd, 0x59, 0x8e, 0x31, 0xfd, 0x69, - 0x75, 0x6b, 0xa6, 0x97, 0x1b, 0x5b, 0xe4, 0x15, 0x95, 0x05, 0x6b, 0x97, - 0x3d, 0x4a, 0xf6, 0xfc, 0xbc, 0x31, 0xe3, 0xef, 0x39, 0xfe, 0x55, 0x73, - 0x52, 0x18, 0xb6, 0x80, 0x0f, 0xf3, 0xf2, 0xd6, 0xf4, 0x7e, 0x23, 0x29, - 0xad, 0x8d, 0x6d, 0x3f, 0x10, 0xc2, 0x16, 0xaf, 0x75, 0xae, 0x4e, 0xa6, - 0xac, 0x75, 0x2d, 0x32, 0x47, 0x0a, 0x5a, 0xa0, 0x0a, 0x59, 0x06, 0x63, - 0x34, 0xd0, 0x98, 0x42, 0x71, 0x1d, 0x47, 0x1b, 0x62, 0x71, 0x48, 0x7d, - 0x4d, 0x20, 0x16, 0x44, 0xed, 0x8a, 0xc7, 0xd5, 0xb4, 0xb4, 0x9d, 0x48, - 0xc5, 0x69, 0x46, 0x66, 0x35, 0x22, 0x71, 0x17, 0xba, 0x7c, 0xd6, 0x32, - 0x9d, 0xc3, 0xe5, 0xcf, 0x06, 0xac, 0x5a, 0xb9, 0xe0, 0x0e, 0xb4, 0x57, - 0x86, 0xb7, 0x46, 0xd4, 0x65, 0x74, 0x6f, 0x58, 0xb9, 0x23, 0x91, 0xcd, - 0x68, 0xa0, 0x27, 0xb5, 0x64, 0x8a, 0x90, 0x92, 0x26, 0x3a, 0xd5, 0x59, - 0x2b, 0x56, 0x71, 0xdb, 0x52, 0xdd, 0x94, 0x51, 0xec, 0xc9, 0x1c, 0xd4, - 0xf9, 0x02, 0xb2, 0x4c, 0xea, 0x2f, 0x69, 0xd7, 0x3b, 0x24, 0x15, 0xb6, - 0x2e, 0x57, 0x6e, 0x69, 0xc7, 0x70, 0x91, 0x4a, 0xee, 0xf3, 0x8e, 0x2b, - 0x0a, 0xf2, 0x46, 0x6e, 0xb5, 0x4c, 0x84, 0x53, 0x62, 0xa3, 0x92, 0x2b, - 0x3a, 0xeb, 0x55, 0xda, 0xbb, 0x51, 0x7a, 0xd6, 0x5a, 0x96, 0x66, 0xdc, - 0xdc, 0x3b, 0x2f, 0x27, 0xad, 0x53, 0x4e, 0xb4, 0x3d, 0x80, 0xd5, 0xb1, - 0x93, 0x1c, 0x54, 0x17, 0x89, 0x89, 0xcd, 0x3a, 0x7d, 0x86, 0xc7, 0x5a, - 0x21, 0x7e, 0x05, 0x17, 0x3b, 0xa3, 0x3b, 0x58, 0x73, 0x47, 0x28, 0x9b, - 0xd4, 0xce, 0x9f, 0x27, 0x35, 0x5d, 0x0e, 0x1a, 0x97, 0x42, 0xe2, 0x8b, - 0x1c, 0x1a, 0x8f, 0xbd, 0x49, 0xa5, 0x87, 0x37, 0x02, 0xa2, 0x35, 0xa1, - 0x83, 0x23, 0xa4, 0xa6, 0x03, 0x59, 0x73, 0x4e, 0x8e, 0x02, 0xd4, 0x9b, - 0xb0, 0xd2, 0x27, 0x5b, 0x4a, 0x90, 0x5a, 0x8f, 0x4a, 0xcf, 0x98, 0xd9, - 0x53, 0x24, 0x10, 0x01, 0x53, 0x44, 0x80, 0x1a, 0xca, 0x4c, 0xd1, 0x46, - 0xc5, 0x92, 0x46, 0x06, 0xda, 0x6e, 0xea, 0x10, 0x0b, 0x9a, 0x63, 0x0a, - 0x2e, 0x04, 0x74, 0x94, 0xc4, 0x34, 0xb5, 0x37, 0x24, 0xd5, 0x58, 0x86, - 0xc3, 0xca, 0x95, 0xba, 0x0a, 0x4f, 0xb0, 0x4c, 0xdd, 0x6b, 0x64, 0xac, - 0x60, 0xe6, 0x3c, 0x69, 0x3f, 0xde, 0x6a, 0x91, 0x74, 0xb8, 0xc7, 0xff, - 0x00, 0xaa, 0x9f, 0x31, 0x06, 0x76, 0xa7, 0x6e, 0x90, 0xb0, 0xd9, 0xfe, - 0x78, 0xaa, 0x20, 0x55, 0x30, 0x42, 0xed, 0xa5, 0xc5, 0x48, 0xc5, 0xc5, - 0x14, 0x00, 0x52, 0x8f, 0x9a, 0x80, 0x1d, 0xe4, 0x16, 0xa8, 0xa4, 0x5f, - 0x2f, 0x83, 0x45, 0xc0, 0x8a, 0x96, 0x82, 0x85, 0xa2, 0xa4, 0x05, 0xa5, - 0xa0, 0x62, 0xd3, 0xfb, 0x50, 0x22, 0xb1, 0xeb, 0x45, 0x50, 0x05, 0x14, - 0x00, 0xb4, 0x50, 0x04, 0xa9, 0x52, 0x54, 0x81, 0xea, 0xbb, 0x98, 0xd2, - 0x3b, 0x32, 0x2e, 0x4b, 0x56, 0xe9, 0x19, 0x36, 0x73, 0x97, 0x17, 0x57, - 0x37, 0x52, 0xb2, 0xa4, 0x8d, 0x81, 0x56, 0xf4, 0xab, 0x82, 0xc4, 0xc6, - 0x6b, 0x2a, 0xbe, 0x46, 0xb1, 0x7a, 0x1a, 0x4c, 0xb5, 0x0b, 0x53, 0x24, - 0x82, 0x5e, 0x54, 0xd5, 0x0b, 0x47, 0xf2, 0xee, 0x19, 0x5f, 0xa9, 0xa4, - 0xfe, 0x11, 0xad, 0xcd, 0x38, 0xc6, 0xee, 0x0d, 0x53, 0xd4, 0x2f, 0x06, - 0x9e, 0x57, 0x3f, 0x36, 0x7d, 0x2a, 0xa9, 0xea, 0x44, 0x8e, 0x71, 0x22, - 0x17, 0xd7, 0x2e, 0xc7, 0xb7, 0xf8, 0xd5, 0x4b, 0xbb, 0x57, 0xb7, 0x71, - 0xbf, 0xa7, 0x6a, 0xab, 0xf3, 0x19, 0x46, 0x7c, 0xb2, 0xe5, 0x35, 0xbc, - 0x31, 0x62, 0x97, 0x53, 0x91, 0x2f, 0xdd, 0xe3, 0x3f, 0x9d, 0x4d, 0xe2, - 0x3b, 0x14, 0xb4, 0xb8, 0x55, 0x87, 0xee, 0x37, 0x1f, 0xf8, 0xed, 0x3c, - 0x33, 0xbf, 0x32, 0x37, 0xa8, 0xf9, 0x64, 0x8a, 0xf6, 0x69, 0x9b, 0xa4, - 0x20, 0x7d, 0xcc, 0x35, 0x6a, 0xc9, 0x0a, 0xca, 0x10, 0x32, 0xe7, 0x15, - 0x2b, 0x70, 0x6c, 0x97, 0xee, 0xd4, 0xd1, 0xcb, 0x59, 0x34, 0x59, 0x65, - 0x5f, 0x34, 0xfe, 0xb4, 0x08, 0x76, 0x30, 0x29, 0x54, 0x8c, 0x53, 0x01, - 0x9e, 0x60, 0x53, 0xcd, 0x47, 0x25, 0xe2, 0xe3, 0x02, 0x98, 0x98, 0xd4, - 0x97, 0x34, 0x15, 0x24, 0xd2, 0x63, 0x45, 0xcb, 0x36, 0x21, 0xf1, 0x53, - 0xdc, 0x76, 0xa5, 0x00, 0x91, 0x42, 0xea, 0xc1, 0x2e, 0xd0, 0xab, 0x2e, - 0x73, 0x54, 0x63, 0xf0, 0xfd, 0xba, 0x3f, 0xdd, 0xad, 0xbd, 0xa3, 0xb1, - 0x0a, 0x36, 0x66, 0xd5, 0xa6, 0x9d, 0x04, 0x71, 0x70, 0x29, 0xbb, 0xe2, - 0x53, 0x8e, 0x95, 0x9f, 0x4b, 0x95, 0xd4, 0x8e, 0x50, 0x25, 0xaa, 0xb2, - 0x44, 0x2a, 0x65, 0x23, 0x68, 0x53, 0x08, 0x38, 0x24, 0x54, 0xad, 0x4a, - 0x24, 0x48, 0x96, 0xd1, 0x87, 0x99, 0x5a, 0xe9, 0x32, 0xf9, 0x75, 0x44, - 0xbd, 0x8c, 0xfb, 0xb3, 0xcf, 0x06, 0xab, 0xdd, 0x0f, 0xdd, 0x55, 0xb3, - 0x38, 0xa2, 0x84, 0xa3, 0x28, 0x71, 0x58, 0x12, 0xdb, 0xc8, 0xb2, 0x12, - 0xeb, 0x8e, 0x6a, 0x6d, 0x72, 0x9e, 0xe5, 0x49, 0x79, 0x35, 0x25, 0xb5, - 0xa4, 0x92, 0xfc, 0xca, 0x38, 0xa6, 0x97, 0x42, 0x8b, 0x50, 0xc4, 0xca, - 0xe2, 0xac, 0x98, 0xd5, 0x99, 0x77, 0x52, 0x94, 0x79, 0x47, 0xb8, 0xd9, - 0x8c, 0x56, 0xec, 0x3c, 0xa3, 0x96, 0xaa, 0x93, 0xb9, 0x91, 0xf2, 0xdc, - 0x9a, 0x96, 0x38, 0xab, 0x95, 0x24, 0x4a, 0xa6, 0xfc, 0x1a, 0x46, 0x82, - 0x83, 0x4e, 0x5e, 0xb4, 0x8a, 0x62, 0xc9, 0x51, 0x35, 0x68, 0x8e, 0x71, - 0x94, 0x50, 0x00, 0x2b, 0x46, 0x10, 0x0a, 0x66, 0xb1, 0xa8, 0x6f, 0x48, - 0x97, 0x6d, 0x18, 0xac, 0xae, 0x6c, 0x2e, 0x28, 0xc5, 0x50, 0x0e, 0xa3, - 0xa5, 0x48, 0x09, 0xbe, 0xa3, 0x69, 0xb1, 0x4d, 0x44, 0x86, 0xc8, 0x8c, - 0xd4, 0x0d, 0xcd, 0x5b, 0xa8, 0x98, 0xca, 0x64, 0xc9, 0x6e, 0x4f, 0xde, - 0xab, 0x09, 0x14, 0x6b, 0x4f, 0x63, 0x2b, 0x92, 0x79, 0xa8, 0xbd, 0xe9, - 0xad, 0x77, 0x12, 0xf7, 0xa9, 0x11, 0x09, 0xd4, 0xa2, 0xa8, 0x1f, 0x54, - 0xfe, 0xe8, 0xa7, 0xca, 0x33, 0x3e, 0xe6, 0x73, 0x70, 0x7e, 0x61, 0x50, - 0x62, 0xac, 0x81, 0x69, 0xb9, 0x14, 0x0c, 0x42, 0xf4, 0xdc, 0xd0, 0x51, - 0x22, 0xad, 0x49, 0x18, 0xa4, 0x4b, 0x2c, 0xc6, 0x2a, 0xa5, 0xe7, 0xfa, - 0xca, 0x71, 0x02, 0xad, 0x2d, 0x05, 0x85, 0x2d, 0x00, 0x14, 0xea, 0x00, - 0x5a, 0x7f, 0x6a, 0x40, 0x57, 0x6e, 0xb4, 0xda, 0x60, 0x2d, 0x14, 0x00, - 0x52, 0xd0, 0x03, 0xd0, 0xd4, 0xb5, 0x36, 0x03, 0xd6, 0x96, 0x33, 0x4d, - 0xba, 0x83, 0x30, 0xb7, 0x35, 0xd5, 0x0d, 0xcc, 0x26, 0x61, 0x5b, 0xd9, - 0xdc, 0x43, 0x23, 0xe1, 0x33, 0x93, 0xfd, 0x6a, 0xc5, 0x9d, 0xab, 0xc0, - 0xe5, 0xde, 0xa2, 0x71, 0xde, 0xc6, 0x8a, 0xc6, 0x87, 0x55, 0xaa, 0xcc, - 0x39, 0xa8, 0xe8, 0x04, 0x4f, 0xd2, 0xb3, 0xee, 0xad, 0xb7, 0x1d, 0xca, - 0x76, 0xb5, 0x24, 0x36, 0x11, 0xcf, 0x73, 0x0a, 0xe3, 0xad, 0x52, 0x9a, - 0xc2, 0x7b, 0xf9, 0xf7, 0xcc, 0xdf, 0x81, 0xe6, 0x9c, 0x6d, 0x11, 0x3d, - 0x5d, 0xcb, 0x49, 0x65, 0xe5, 0x11, 0x84, 0xa9, 0xee, 0x6c, 0xa3, 0xbb, - 0xb5, 0x68, 0xf6, 0xf3, 0x8e, 0x31, 0x45, 0xac, 0xee, 0x71, 0x56, 0xde, - 0xe6, 0x7d, 0x82, 0xcb, 0xa6, 0xb3, 0x20, 0x49, 0x39, 0xe0, 0x1c, 0x7b, - 0xd5, 0xe7, 0xb0, 0x9e, 0xfe, 0x3c, 0xb2, 0x73, 0x9e, 0x0d, 0x6d, 0x4e, - 0x3c, 0x8e, 0xe7, 0x4c, 0xa5, 0xce, 0xae, 0x5c, 0xb0, 0xd0, 0xcc, 0x2a, - 0x77, 0x1a, 0x9d, 0xe0, 0x58, 0x97, 0x00, 0x54, 0xb4, 0x51, 0x51, 0xa3, - 0xe6, 0x8c, 0x01, 0x58, 0xb3, 0x51, 0x7c, 0xc5, 0x5e, 0xf4, 0xf1, 0x78, - 0xa3, 0xbd, 0x40, 0xc8, 0xe4, 0xd4, 0x07, 0x6a, 0x87, 0xed, 0xaf, 0xda, - 0x82, 0xd4, 0x48, 0xcb, 0xb3, 0x77, 0xa4, 0x5e, 0x0d, 0x30, 0x91, 0x6a, - 0xdd, 0xbe, 0x71, 0x57, 0x29, 0x32, 0x47, 0x23, 0xec, 0x39, 0xa9, 0x65, - 0x9d, 0x5d, 0x28, 0x8e, 0xe2, 0x63, 0xb4, 0xd6, 0xf3, 0x24, 0xc5, 0x68, - 0xc9, 0x69, 0xbf, 0xee, 0xd5, 0xd3, 0x7a, 0x93, 0x3d, 0x08, 0xc5, 0xb4, - 0xe8, 0x31, 0x54, 0xe4, 0xd3, 0xdf, 0x3b, 0x98, 0xd6, 0x96, 0x26, 0xe4, - 0x43, 0x03, 0x8a, 0x8a, 0x5a, 0xe6, 0x96, 0xe7, 0x74, 0x36, 0x22, 0x8f, - 0xef, 0xd4, 0x93, 0x0c, 0x2d, 0x38, 0x1c, 0xf3, 0x24, 0xd3, 0xff, 0x00, - 0xd6, 0x8a, 0xd4, 0x92, 0x2f, 0x97, 0x81, 0x5a, 0x47, 0x73, 0x2a, 0x9b, - 0x15, 0x4a, 0xb1, 0x93, 0xa5, 0x3e, 0xe6, 0x3d, 0xd1, 0x62, 0xaa, 0x7a, - 0x31, 0x47, 0x54, 0x51, 0xf2, 0x29, 0x24, 0xb6, 0x57, 0x4c, 0x62, 0xb3, - 0xbd, 0x99, 0x6d, 0x68, 0x73, 0x3a, 0xbd, 0x83, 0x5b, 0x49, 0x95, 0xfb, - 0xb4, 0xb6, 0x17, 0x2f, 0x6f, 0x0f, 0x09, 0xf9, 0x8a, 0xd5, 0xae, 0xa4, - 0xa7, 0x74, 0x34, 0x5c, 0x3b, 0x31, 0xc2, 0xf5, 0xa1, 0xc4, 0x95, 0x33, - 0x91, 0x51, 0x56, 0x21, 0xf2, 0xf9, 0xcd, 0x48, 0x23, 0xae, 0x76, 0xcd, - 0xa2, 0x41, 0x72, 0x06, 0xde, 0x2a, 0x89, 0x43, 0x4d, 0x31, 0x8c, 0xc6, - 0x29, 0xea, 0x2a, 0x81, 0xec, 0x12, 0x54, 0x4d, 0x5a, 0x18, 0x0d, 0xa2, - 0x80, 0x0a, 0xb7, 0x64, 0xdc, 0xed, 0xac, 0xe6, 0x8d, 0x69, 0x6e, 0x5d, - 0xa5, 0xc5, 0x60, 0x74, 0x87, 0x14, 0xd2, 0xc2, 0x98, 0x88, 0x5e, 0x75, - 0x5a, 0xad, 0x25, 0xf2, 0x76, 0xaa, 0x50, 0x6c, 0xce, 0x53, 0x48, 0x83, - 0xed, 0x8c, 0xc6, 0x83, 0x2d, 0x6c, 0x95, 0x8e, 0x77, 0x2b, 0x8a, 0x26, - 0xa9, 0xd6, 0xf7, 0x6f, 0x6a, 0x76, 0x24, 0x1b, 0x50, 0x7e, 0xd5, 0x11, - 0xb9, 0x91, 0xbf, 0x8a, 0x8b, 0x12, 0x33, 0xcc, 0x6f, 0x5a, 0x43, 0xcd, - 0x16, 0xd4, 0x57, 0x12, 0x8a, 0x62, 0x1a, 0x6a, 0x32, 0xe0, 0x50, 0x55, - 0x88, 0xcb, 0xd2, 0x50, 0x50, 0xa0, 0x54, 0xa1, 0x28, 0x19, 0x2e, 0x38, - 0xa7, 0x45, 0xd2, 0x91, 0x04, 0xcb, 0xc5, 0x51, 0x9c, 0xfe, 0xf2, 0x92, - 0x19, 0x1e, 0x05, 0x36, 0xa8, 0xa0, 0xa2, 0x80, 0x1d, 0x45, 0x20, 0x1d, - 0x4e, 0x1d, 0x28, 0x02, 0x06, 0xeb, 0x49, 0x4c, 0x04, 0xa5, 0xa0, 0x02, - 0x8a, 0x00, 0x70, 0xa9, 0xc5, 0x20, 0x3d, 0x79, 0xa6, 0x1d, 0x8d, 0x47, - 0xf6, 0x94, 0x6e, 0xa6, 0xb5, 0xb9, 0x9d, 0x89, 0x92, 0x68, 0x94, 0x67, - 0x22, 0xa1, 0x94, 0x7d, 0xa0, 0xfc, 0xa6, 0xaa, 0xe4, 0x58, 0x0c, 0x5b, - 0x56, 0xa9, 0x4c, 0x30, 0x69, 0x74, 0x1a, 0xdc, 0x80, 0xf3, 0x51, 0xb5, - 0x64, 0x6a, 0x45, 0x27, 0x4a, 0x6d, 0xb9, 0xf9, 0xa8, 0x03, 0x77, 0x4e, - 0xb7, 0x8e, 0x53, 0xf3, 0x01, 0x5a, 0x8b, 0xa5, 0xc1, 0xfd, 0xda, 0xda, - 0x9c, 0x8e, 0x7a, 0x91, 0x25, 0x1a, 0x74, 0x03, 0xf8, 0x45, 0x29, 0x86, - 0x34, 0xe8, 0xb5, 0xb1, 0x05, 0x59, 0xeb, 0x1e, 0xfb, 0xe4, 0x42, 0x69, - 0x33, 0x44, 0x54, 0xb7, 0x46, 0xb9, 0xce, 0xd1, 0xd2, 0xaa, 0x5e, 0x41, - 0x73, 0x1f, 0xdd, 0xce, 0x2b, 0x9d, 0x2e, 0x63, 0x7b, 0xd9, 0x94, 0x32, - 0xe7, 0xad, 0x39, 0x54, 0x9a, 0xca, 0xc6, 0xd7, 0x25, 0x11, 0xd4, 0xd1, - 0xc0, 0x7f, 0xbb, 0xfa, 0x55, 0x72, 0xdc, 0xcf, 0x98, 0x90, 0x43, 0xed, - 0x47, 0xd9, 0xfd, 0x69, 0xda, 0xc2, 0xb8, 0xd1, 0xfb, 0xa9, 0x05, 0x5e, - 0x53, 0x95, 0x15, 0x12, 0x29, 0x6c, 0x0d, 0xd2, 0xb3, 0xa5, 0xb9, 0x64, - 0x3d, 0x69, 0xa4, 0x06, 0x8e, 0x81, 0x3f, 0x99, 0x38, 0xfa, 0xd7, 0x5b, - 0x00, 0xe9, 0x51, 0x0d, 0xc2, 0xa2, 0x26, 0x93, 0xee, 0x1a, 0xcb, 0xbd, - 0x6f, 0x90, 0xd7, 0x52, 0x39, 0xce, 0x65, 0x66, 0xfd, 0xe3, 0x66, 0xa4, - 0x33, 0xe4, 0x57, 0x3c, 0xd7, 0xbc, 0x76, 0x46, 0x76, 0x44, 0x31, 0xc9, - 0xfb, 0xce, 0xb5, 0x35, 0xc5, 0xc2, 0x08, 0xba, 0xd2, 0x5b, 0x91, 0x2d, - 0x48, 0x2c, 0xef, 0x57, 0xcf, 0x00, 0x57, 0x5d, 0x01, 0xcc, 0x40, 0xd1, - 0x1f, 0x88, 0x89, 0xad, 0x08, 0x65, 0x7e, 0x6a, 0xbb, 0xf3, 0x57, 0x21, - 0x45, 0x0c, 0xd9, 0x49, 0xb2, 0xb3, 0x19, 0x97, 0x75, 0xb0, 0xc8, 0x55, - 0xb1, 0xd2, 0xa9, 0xbf, 0x94, 0xa9, 0xb4, 0x0a, 0x2f, 0xa8, 0xed, 0xa1, - 0x93, 0x0c, 0x91, 0xac, 0xc7, 0x91, 0xd6, 0xa7, 0x69, 0xa2, 0x3d, 0xea, - 0x5e, 0xe6, 0xaa, 0x24, 0x6d, 0x71, 0x1f, 0xad, 0x40, 0xf7, 0x04, 0xfd, - 0xda, 0x8f, 0x53, 0x44, 0x88, 0xc2, 0x16, 0xeb, 0x4b, 0xe5, 0x52, 0xb9, - 0xa5, 0x83, 0xc8, 0x14, 0x92, 0x44, 0x02, 0xf4, 0xaa, 0xbe, 0xa4, 0x49, - 0x68, 0x51, 0x93, 0xad, 0x42, 0xd5, 0xd0, 0x72, 0x0c, 0xa2, 0x80, 0x12, - 0xa6, 0xb7, 0x7d, 0x8d, 0x9a, 0x52, 0xd8, 0xa8, 0xee, 0x69, 0xf9, 0xa9, - 0x8e, 0xa2, 0xa2, 0x92, 0xed, 0x57, 0xb8, 0xae, 0x54, 0x8e, 0xa7, 0x2b, - 0x14, 0xe4, 0xd4, 0x7d, 0x2a, 0xac, 0x97, 0x6e, 0xdf, 0xfe, 0xba, 0xe8, - 0x8c, 0x4c, 0x1d, 0x42, 0x22, 0xcc, 0xdd, 0x4d, 0x1b, 0x6a, 0xcc, 0x5b, - 0x1c, 0x05, 0x2d, 0x04, 0x0b, 0x4e, 0xa0, 0x05, 0xa2, 0x81, 0x0b, 0x49, - 0x40, 0x08, 0x5c, 0x0a, 0x88, 0xcd, 0xe9, 0x41, 0x64, 0x65, 0xc9, 0xa6, - 0xd3, 0x28, 0x29, 0xc2, 0x80, 0x24, 0x15, 0x2a, 0x54, 0x88, 0x7b, 0x74, - 0xa5, 0x8b, 0xa5, 0x04, 0x93, 0x76, 0xaa, 0x13, 0x7d, 0xfa, 0x60, 0xb7, - 0x19, 0xda, 0x9b, 0x41, 0x61, 0x4b, 0x40, 0x0b, 0x45, 0x20, 0x14, 0x53, - 0xc7, 0x4a, 0x40, 0x42, 0xdd, 0x69, 0xb5, 0x42, 0x0a, 0x28, 0x18, 0x51, - 0x40, 0x0e, 0x4e, 0xb5, 0x3d, 0x26, 0x07, 0x71, 0x2e, 0xa0, 0x55, 0x38, - 0xeb, 0x4b, 0xa6, 0xdc, 0xb4, 0xb3, 0xfc, 0xc7, 0xa9, 0xad, 0x27, 0x1b, - 0x22, 0xd4, 0x74, 0xb9, 0xa3, 0x77, 0xfe, 0xa4, 0x7e, 0x35, 0xa5, 0xa6, - 0x27, 0xfa, 0x20, 0xfa, 0x9a, 0x97, 0xd0, 0xe7, 0xee, 0x4d, 0x22, 0xd6, - 0x6d, 0xd0, 0xc5, 0x6e, 0xc9, 0x45, 0x16, 0x6c, 0x53, 0x37, 0x57, 0x33, - 0x36, 0x18, 0xc6, 0xa0, 0x47, 0xc4, 0x94, 0x08, 0xd8, 0xd3, 0x2e, 0xb1, - 0x28, 0xe6, 0xba, 0x78, 0x5b, 0x2a, 0x29, 0xd3, 0x7e, 0xf0, 0xa6, 0x58, - 0xa8, 0xe4, 0x5a, 0xee, 0x47, 0x39, 0x4a, 0x65, 0xac, 0x7d, 0x46, 0x3d, - 0xd1, 0x30, 0xa9, 0x6c, 0xa4, 0x59, 0xf0, 0xfd, 0xb0, 0x8c, 0x90, 0xd5, - 0xa3, 0x7b, 0xa6, 0xa4, 0xc3, 0x28, 0x30, 0x6b, 0x9a, 0x8c, 0xb5, 0x66, - 0x95, 0xba, 0x18, 0xf7, 0x9a, 0x01, 0x65, 0xca, 0x28, 0xcd, 0x54, 0x8f, - 0x44, 0x3d, 0x1c, 0x73, 0x5a, 0x4b, 0xb8, 0xa3, 0x2e, 0x86, 0x8d, 0x97, - 0x86, 0xd3, 0xef, 0x4d, 0xfc, 0xab, 0x62, 0x2d, 0x3a, 0xda, 0x25, 0xc0, - 0x88, 0x56, 0x7c, 0xc3, 0x63, 0x7f, 0xb3, 0x6d, 0xf7, 0x67, 0x60, 0xae, - 0x5f, 0x56, 0x0d, 0x1c, 0x99, 0x5a, 0xdf, 0xe2, 0x46, 0x71, 0xdc, 0xcb, - 0x67, 0x2d, 0x57, 0x2d, 0x9f, 0xe4, 0xae, 0x29, 0x9d, 0xab, 0x62, 0x7a, - 0xc9, 0xba, 0x8c, 0x99, 0x78, 0xa6, 0xb6, 0x27, 0xa9, 0x67, 0x4a, 0xcd, - 0xbc, 0xc1, 0xab, 0xb5, 0xb0, 0xb8, 0x59, 0x50, 0x73, 0xcd, 0x60, 0xb4, - 0x66, 0xb3, 0x57, 0x45, 0x99, 0xa4, 0x54, 0x43, 0x9a, 0xc8, 0xba, 0x6d, - 0xd1, 0xb6, 0x2b, 0xb5, 0x6c, 0x71, 0x9c, 0xb3, 0xfc, 0xb2, 0x1a, 0x53, - 0x90, 0xb5, 0x9c, 0xb7, 0x3a, 0xa3, 0x0d, 0x08, 0xb0, 0xc7, 0xa5, 0x4d, - 0xfd, 0x98, 0xd3, 0x2f, 0xce, 0x69, 0x0a, 0x5a, 0x0f, 0x83, 0x4c, 0x30, - 0xb8, 0xc5, 0x74, 0x56, 0xd7, 0x0c, 0xb1, 0x05, 0x22, 0x8e, 0xb7, 0x25, - 0xbb, 0xa1, 0x7a, 0xd1, 0xb6, 0x94, 0x99, 0x21, 0x8a, 0x31, 0x52, 0x07, - 0x3f, 0xa8, 0x2e, 0x2f, 0x3f, 0x2a, 0xcd, 0x92, 0xe0, 0xac, 0xbb, 0x68, - 0x9e, 0xe5, 0xc3, 0x53, 0x24, 0xdb, 0xb3, 0x48, 0x48, 0xcd, 0x3c, 0x5b, - 0x9f, 0x7a, 0x87, 0x23, 0x65, 0x01, 0xeb, 0x6b, 0x52, 0xac, 0x20, 0x54, - 0x36, 0x6a, 0x87, 0xed, 0x02, 0x93, 0x15, 0x23, 0x12, 0x98, 0xfd, 0x28, - 0x44, 0xb3, 0x32, 0x51, 0xcd, 0x40, 0x6b, 0xb0, 0xe2, 0x19, 0x49, 0x40, - 0x05, 0x19, 0xc5, 0x00, 0x36, 0x49, 0x9f, 0xd6, 0xab, 0x92, 0x49, 0xa1, - 0x21, 0xdc, 0x4a, 0x5a, 0x04, 0x2e, 0x69, 0xea, 0x68, 0x11, 0x28, 0x02, - 0x97, 0x6d, 0x06, 0x62, 0xe2, 0x8c, 0x50, 0x20, 0xa4, 0x2c, 0x05, 0x03, - 0x22, 0x69, 0x7d, 0x2a, 0x32, 0xc6, 0x8b, 0x1a, 0x58, 0x4a, 0x6d, 0x03, - 0x0a, 0x28, 0x00, 0xa5, 0xa0, 0x42, 0xe6, 0xa7, 0x8e, 0x89, 0x20, 0x24, - 0x6e, 0x94, 0xf8, 0xba, 0x52, 0x44, 0x92, 0xb7, 0x4a, 0xce, 0x7e, 0xb4, - 0xd0, 0x96, 0xe3, 0x7b, 0x51, 0x41, 0xa0, 0x51, 0x48, 0x05, 0xa2, 0x90, - 0x0b, 0x4f, 0x14, 0x01, 0x13, 0x53, 0x6a, 0x84, 0x18, 0xa4, 0xa0, 0x62, - 0x52, 0xd0, 0x03, 0xd3, 0xad, 0x4d, 0x4a, 0xc0, 0x75, 0xdf, 0xd9, 0xf3, - 0x34, 0x98, 0xda, 0x7e, 0xb5, 0x72, 0xce, 0xc5, 0xed, 0xc8, 0x2d, 0x5d, - 0x75, 0xec, 0xcb, 0x53, 0xf7, 0x4b, 0x77, 0x2f, 0xfb, 0xb1, 0x5b, 0x9a, - 0x68, 0xff, 0x00, 0x45, 0x1f, 0x53, 0x5c, 0xd6, 0x7a, 0x1c, 0xfd, 0x19, - 0x3b, 0xad, 0x66, 0xde, 0x27, 0x15, 0xd0, 0x66, 0x8c, 0x59, 0xdb, 0x63, - 0x73, 0x55, 0x9a, 0xe9, 0x47, 0xad, 0x73, 0x4c, 0xe9, 0x89, 0x03, 0xde, - 0x31, 0xe9, 0x50, 0x79, 0x8e, 0x4d, 0x67, 0x72, 0xf9, 0x4b, 0x76, 0x72, - 0x95, 0x95, 0x73, 0x5d, 0xce, 0x97, 0x37, 0x99, 0x00, 0xa2, 0x2f, 0xdf, - 0x26, 0xa2, 0xf7, 0x4d, 0x41, 0xd2, 0x9a, 0xfd, 0x2b, 0xd1, 0x47, 0x13, - 0x29, 0xcc, 0x2b, 0x1f, 0x50, 0x6d, 0xbd, 0x2a, 0x64, 0x5c, 0x4b, 0x5a, - 0x73, 0x10, 0x77, 0x81, 0x5a, 0xf1, 0x4a, 0x64, 0xea, 0x2b, 0x92, 0x2a, - 0xda, 0x9b, 0x4c, 0x96, 0xa0, 0x6e, 0x26, 0x15, 0xb6, 0xe8, 0xc9, 0x5a, - 0xe3, 0xa3, 0xb8, 0x8e, 0x53, 0x85, 0x6a, 0x96, 0xb2, 0x34, 0x10, 0xb0, - 0x02, 0xb9, 0x5b, 0xd2, 0x24, 0x95, 0xab, 0x68, 0xe9, 0x13, 0x3f, 0xb4, - 0x56, 0x8f, 0x4a, 0xf3, 0x89, 0x38, 0x34, 0x87, 0x4d, 0x9a, 0x16, 0xe3, - 0x9a, 0x8d, 0x1a, 0x36, 0x52, 0xb0, 0xbf, 0x65, 0xb8, 0x23, 0x85, 0xfd, - 0x6a, 0xbc, 0x96, 0x72, 0xa3, 0x72, 0xb5, 0x1c, 0xa6, 0x8a, 0x48, 0x8f, - 0x69, 0x5f, 0x6a, 0xbf, 0x69, 0x7a, 0x61, 0x20, 0xe6, 0xb9, 0xe4, 0x8d, - 0xfa, 0x13, 0x49, 0xac, 0xee, 0x97, 0x61, 0xe7, 0x35, 0x15, 0xc5, 0xe9, - 0x09, 0xc7, 0x7a, 0xd9, 0x76, 0x39, 0xec, 0x65, 0xce, 0xdb, 0x9c, 0x10, - 0x28, 0x67, 0xf9, 0x31, 0x8a, 0x3a, 0x9d, 0x9a, 0x24, 0x3a, 0xdf, 0x99, - 0x16, 0xb6, 0x55, 0xc6, 0x05, 0x2e, 0xa7, 0x3d, 0x46, 0x48, 0xbb, 0x69, - 0xfc, 0x0a, 0x66, 0x43, 0x8c, 0x98, 0x15, 0x4c, 0xea, 0x6a, 0x1b, 0x15, - 0x0d, 0x14, 0x84, 0xfe, 0xd3, 0x5a, 0x3f, 0xb4, 0xd6, 0xb3, 0x2b, 0x94, - 0xcd, 0xbd, 0xb8, 0x12, 0xb6, 0x45, 0x67, 0x34, 0x79, 0x6c, 0xd3, 0x9c, - 0x8b, 0xa7, 0x1b, 0x07, 0x96, 0x3d, 0x29, 0xe1, 0x31, 0x59, 0x23, 0x5b, - 0x8c, 0x6c, 0x0a, 0x8c, 0xb5, 0x50, 0x26, 0x44, 0x65, 0xa6, 0x79, 0x82, - 0xa5, 0x22, 0x80, 0x4a, 0xb4, 0x17, 0x14, 0x09, 0x94, 0x27, 0xfb, 0xd5, - 0x58, 0xd7, 0x59, 0xc4, 0xc6, 0x1a, 0x6d, 0x30, 0x12, 0x8a, 0x00, 0x6b, - 0x0c, 0xd4, 0x24, 0x73, 0x4c, 0x42, 0x51, 0x48, 0x61, 0x4b, 0x40, 0x0b, - 0x9a, 0x91, 0x25, 0xf5, 0xa0, 0x56, 0x25, 0x0e, 0x0d, 0x35, 0xa5, 0x02, - 0x91, 0x3c, 0xa4, 0x2d, 0x36, 0x6a, 0x3c, 0x93, 0x4c, 0xa1, 0x69, 0xd8, - 0xa0, 0x62, 0x53, 0x28, 0x00, 0xa2, 0x80, 0x16, 0x96, 0x80, 0x0a, 0x9e, - 0x3a, 0x1b, 0x11, 0x23, 0x0e, 0x2a, 0x58, 0xbe, 0xed, 0x22, 0x47, 0xc9, - 0xc2, 0x56, 0x6b, 0xd3, 0x04, 0x03, 0xa5, 0x25, 0x05, 0x8b, 0x45, 0x20, - 0x0a, 0x29, 0x80, 0xb4, 0xe1, 0xd2, 0x90, 0x11, 0x37, 0x5a, 0x41, 0x4c, - 0x05, 0x34, 0xda, 0x00, 0x28, 0xa0, 0x07, 0xa7, 0x5a, 0x9a, 0xa4, 0x0f, - 0x56, 0x86, 0x1e, 0x7a, 0x52, 0xcb, 0x6f, 0x9e, 0xd5, 0xd6, 0xb5, 0x24, - 0xc8, 0xd4, 0xa2, 0x6d, 0xbc, 0x56, 0xd6, 0x93, 0x36, 0x62, 0x0b, 0x58, - 0xd5, 0xbd, 0xd0, 0x2d, 0x8d, 0x26, 0xe4, 0x55, 0x1b, 0xa5, 0xad, 0xd1, - 0xce, 0x73, 0x1a, 0xa2, 0xf2, 0x2b, 0x37, 0x15, 0xcb, 0x5b, 0x46, 0x75, - 0xd2, 0x7a, 0x06, 0xca, 0x5d, 0xb5, 0x8d, 0xcd, 0x19, 0x32, 0xa9, 0xae, - 0xa7, 0xc3, 0xf7, 0x1c, 0xed, 0x34, 0x9e, 0xe2, 0x7b, 0x1d, 0x32, 0x1e, - 0x29, 0x4f, 0x4a, 0xf4, 0xa2, 0xce, 0x09, 0x14, 0xe7, 0x35, 0x10, 0xb1, - 0x8d, 0xf9, 0x96, 0x94, 0x98, 0x22, 0xd2, 0xb4, 0x71, 0xae, 0x16, 0x84, - 0x90, 0x6e, 0xac, 0x8d, 0x11, 0x36, 0xe1, 0x50, 0x4d, 0xf3, 0x1a, 0xa8, - 0x10, 0xca, 0xd6, 0x3a, 0x7f, 0x93, 0x2c, 0x8e, 0xdc, 0x86, 0xe9, 0xf9, - 0xd5, 0x89, 0x54, 0xd5, 0x79, 0x95, 0xcc, 0x56, 0x2f, 0xf2, 0x90, 0x6a, - 0x8a, 0x5a, 0x82, 0xfc, 0x8e, 0xf5, 0x9d, 0xf4, 0x2b, 0xa9, 0xa4, 0x1a, - 0x38, 0x63, 0xe2, 0xb3, 0x7c, 0xed, 0xd3, 0x7a, 0x54, 0xfd, 0x92, 0x96, - 0xe5, 0x95, 0x95, 0x14, 0x7c, 0xcd, 0x54, 0x6f, 0x35, 0x28, 0x11, 0x4f, - 0xcd, 0x50, 0x8a, 0xb1, 0xcf, 0xdc, 0x6a, 0x42, 0x69, 0x38, 0x1c, 0x55, - 0x2b, 0x8d, 0x45, 0xa3, 0x3f, 0x2d, 0x43, 0x57, 0x67, 0x46, 0xc8, 0x8e, - 0x1b, 0xff, 0x00, 0x32, 0xee, 0x33, 0x20, 0xc7, 0x35, 0xaa, 0xf7, 0x31, - 0xca, 0x8a, 0x01, 0xa9, 0xbd, 0x98, 0xa2, 0x89, 0xe2, 0xb6, 0x59, 0x06, - 0x6a, 0x3b, 0xb8, 0x96, 0x15, 0xe3, 0xad, 0x74, 0x50, 0xf7, 0xcc, 0xaa, - 0xcf, 0x94, 0xa8, 0x27, 0x68, 0xfd, 0x69, 0x46, 0xaa, 0x54, 0xf3, 0x5d, - 0x72, 0xc3, 0xf5, 0x30, 0x55, 0xae, 0x5d, 0x8f, 0x53, 0x52, 0x82, 0x9d, - 0xfd, 0xa3, 0x9e, 0x95, 0xe7, 0x48, 0xec, 0xe4, 0x18, 0xd7, 0x6e, 0xd5, - 0x5c, 0xe4, 0x9a, 0x8b, 0x94, 0x90, 0x98, 0xa7, 0x8a, 0x96, 0x50, 0xc9, - 0x2a, 0x2c, 0xd0, 0x03, 0x09, 0xe6, 0x97, 0x76, 0x05, 0x20, 0x2b, 0x48, - 0xd5, 0x59, 0xa4, 0xa2, 0xc5, 0x22, 0x17, 0x9a, 0xab, 0xbc, 0xfe, 0xf5, - 0x51, 0x89, 0x2e, 0x44, 0x2d, 0x73, 0x8a, 0x8d, 0xaf, 0x49, 0xab, 0xf6, - 0x66, 0x5c, 0xe1, 0x14, 0x9b, 0xcd, 0x48, 0x6b, 0x43, 0x31, 0x86, 0x99, - 0x40, 0x09, 0x45, 0x00, 0x25, 0x42, 0xdd, 0x69, 0x88, 0x6d, 0x14, 0x0c, - 0x4a, 0x76, 0x29, 0x00, 0x52, 0x50, 0x02, 0x6e, 0x34, 0x94, 0xc4, 0x14, - 0xb4, 0x86, 0x3c, 0x51, 0x40, 0x05, 0x47, 0x40, 0x05, 0x2d, 0x36, 0x01, - 0x4e, 0xa4, 0x01, 0x53, 0xc5, 0xd2, 0x86, 0x22, 0x46, 0xe9, 0x53, 0x47, - 0xd2, 0x91, 0x01, 0x3f, 0xdc, 0xac, 0xc6, 0xaa, 0xe8, 0x08, 0x55, 0xa7, - 0x52, 0x34, 0x0c, 0x51, 0x8a, 0x00, 0x28, 0xa4, 0x01, 0x4e, 0x14, 0x01, - 0x0b, 0x75, 0xa0, 0x53, 0x10, 0xb4, 0x94, 0x00, 0x52, 0x50, 0x03, 0x96, - 0xa6, 0xa9, 0x63, 0x3d, 0xa6, 0xda, 0x0a, 0x7d, 0xca, 0x0c, 0x57, 0x6d, - 0x24, 0x63, 0x36, 0x61, 0x5f, 0x2f, 0x06, 0x9f, 0xa4, 0x9d, 0xac, 0x3e, - 0xb5, 0x85, 0x72, 0xe0, 0x6e, 0xff, 0x00, 0x0d, 0x53, 0xb9, 0xe9, 0x5a, - 0x47, 0x63, 0x03, 0x9a, 0xd5, 0x97, 0xe5, 0x35, 0x92, 0x05, 0x61, 0x58, - 0xea, 0xa4, 0x4a, 0x07, 0x14, 0x6d, 0xac, 0x6e, 0x6c, 0x58, 0x89, 0x2b, - 0x42, 0xc9, 0x8c, 0x2c, 0x0d, 0x48, 0x8e, 0x8a, 0xd6, 0xf5, 0xd8, 0x63, - 0x15, 0x6a, 0x49, 0x5f, 0x67, 0x35, 0xd7, 0x44, 0xe4, 0xa8, 0x88, 0xa3, - 0xe7, 0x9a, 0x94, 0xa1, 0x61, 0x5a, 0x90, 0x2a, 0xc7, 0x4b, 0xe5, 0x1a, - 0x00, 0xb1, 0x18, 0xe2, 0xab, 0x5e, 0x48, 0x10, 0xf5, 0xa9, 0xe8, 0x3e, - 0xa4, 0xe6, 0x40, 0x91, 0x02, 0x6a, 0x8c, 0xb3, 0xb3, 0xf0, 0x2a, 0x53, - 0xd0, 0x2d, 0xa8, 0xc4, 0x88, 0x9a, 0x71, 0x01, 0x28, 0x28, 0xad, 0x71, - 0x20, 0x11, 0x92, 0x4f, 0x15, 0xce, 0x5d, 0xeb, 0x1b, 0x64, 0x29, 0x6e, - 0xb9, 0x6f, 0x5e, 0x69, 0xda, 0xe8, 0x16, 0xe4, 0x3e, 0x75, 0xd4, 0xa3, - 0xe6, 0x7d, 0xbf, 0x4a, 0xcf, 0x9a, 0x36, 0x2f, 0x86, 0xf9, 0xab, 0x16, - 0xf4, 0x3a, 0x61, 0xb8, 0xe8, 0xe0, 0xa7, 0xb5, 0xaa, 0x3f, 0x51, 0x5c, - 0xfc, 0xc7, 0x43, 0x44, 0x2f, 0x60, 0x3f, 0x87, 0x8a, 0xaa, 0xd0, 0xcb, - 0x09, 0xc8, 0xab, 0xbd, 0xcc, 0xb6, 0x2c, 0x45, 0xad, 0xcd, 0x0a, 0xe3, - 0x15, 0x32, 0xea, 0x9e, 0x67, 0x2f, 0xf3, 0x7e, 0x15, 0xbe, 0x1f, 0xdd, - 0x67, 0x3e, 0x23, 0xde, 0x1e, 0x2f, 0x15, 0xbb, 0x55, 0x1b, 0xac, 0xc9, - 0x27, 0x02, 0xbd, 0x27, 0x56, 0xd1, 0x39, 0x29, 0xd1, 0x7c, 0xe4, 0xb6, - 0xf1, 0x95, 0x15, 0xa1, 0x08, 0xe2, 0xbc, 0x26, 0xee, 0xcf, 0x63, 0xa1, - 0x3e, 0xda, 0x6e, 0x70, 0x6a, 0xcc, 0xc8, 0x9d, 0xe9, 0x9b, 0x8d, 0x4b, - 0x65, 0x20, 0xce, 0x7a, 0xd2, 0x56, 0x77, 0x2a, 0xc4, 0x52, 0x4c, 0xa9, - 0x54, 0x9e, 0xf7, 0xde, 0xa9, 0x08, 0xa9, 0x2d, 0xd7, 0xbd, 0x55, 0x92, - 0xe8, 0x76, 0x35, 0xa2, 0x44, 0x39, 0x95, 0xda, 0xe0, 0xd4, 0x65, 0x8d, - 0x6c, 0x62, 0xdd, 0xc6, 0xd2, 0x53, 0xd8, 0x44, 0xb1, 0x1c, 0x35, 0x5b, - 0xed, 0x48, 0x06, 0x1a, 0x61, 0xa0, 0x06, 0xd1, 0x40, 0x05, 0x34, 0x8c, - 0xd0, 0x98, 0x06, 0xce, 0x2a, 0x13, 0x4c, 0x42, 0x53, 0xc5, 0x21, 0x85, - 0x34, 0xd0, 0x03, 0x69, 0x76, 0xd3, 0x01, 0xd8, 0xa5, 0xc5, 0x4d, 0xc0, - 0x5a, 0x4a, 0x2e, 0x01, 0x51, 0x9a, 0x60, 0x14, 0xe1, 0x40, 0x0b, 0x49, - 0x40, 0x21, 0x45, 0x5a, 0x4f, 0xbb, 0x43, 0x01, 0xc6, 0xa6, 0x5a, 0x46, - 0x42, 0x5c, 0x7d, 0xca, 0xcb, 0x3d, 0x69, 0x95, 0x11, 0xc9, 0x4b, 0x41, - 0x63, 0xe9, 0xc2, 0x90, 0x08, 0xd4, 0xca, 0x60, 0x14, 0xea, 0x40, 0x44, - 0xdd, 0x69, 0x29, 0x88, 0x5a, 0x5a, 0x00, 0x43, 0x4d, 0xa0, 0x07, 0xad, - 0x4b, 0x48, 0x67, 0xb7, 0x5a, 0xbe, 0x56, 0xa6, 0x95, 0x32, 0xb5, 0xdf, - 0x48, 0xe5, 0x9e, 0xe6, 0x05, 0xf2, 0xf5, 0xa8, 0x6c, 0xfe, 0x59, 0x45, - 0x73, 0xe2, 0x0d, 0xe0, 0x6f, 0xaf, 0x31, 0xd5, 0x4b, 0xa2, 0x00, 0xeb, - 0x4e, 0x1b, 0x18, 0xbd, 0xce, 0x57, 0x55, 0x9f, 0xcc, 0x7d, 0x8b, 0x8a, - 0xa8, 0x13, 0x8a, 0xe7, 0xab, 0xbd, 0x8e, 0xba, 0x6b, 0x41, 0xe1, 0x69, - 0xe1, 0x6b, 0x13, 0x42, 0x78, 0xd6, 0xb4, 0x21, 0xd9, 0x8c, 0x1a, 0x48, - 0x4c, 0xe8, 0x34, 0xf1, 0x0e, 0x06, 0xdc, 0x66, 0xa5, 0xd4, 0x1f, 0x11, - 0x7e, 0x75, 0xdb, 0x40, 0xe2, 0xaa, 0x25, 0x9a, 0xe6, 0x3e, 0x7a, 0xf5, - 0xa7, 0xca, 0xf8, 0x38, 0x15, 0x51, 0xd8, 0x19, 0x24, 0x3e, 0xf5, 0x2e, - 0xe1, 0x4e, 0x22, 0x64, 0x12, 0x5d, 0xaa, 0x1e, 0x39, 0xac, 0x6b, 0xb8, - 0xe6, 0x9e, 0xe0, 0x49, 0x9f, 0x97, 0xd2, 0xa8, 0x16, 0xe5, 0xed, 0xcc, - 0xca, 0x01, 0xa9, 0x62, 0x41, 0x58, 0x24, 0x5b, 0x1f, 0x2b, 0x88, 0xd6, - 0xb2, 0xef, 0x6e, 0xf0, 0x33, 0x9e, 0x2b, 0x5b, 0x12, 0x61, 0xde, 0xde, - 0x3d, 0xc2, 0xec, 0x07, 0x09, 0x54, 0xbe, 0x44, 0xe8, 0x2b, 0x29, 0xcb, - 0x4b, 0x1b, 0xc2, 0x02, 0xf9, 0x84, 0xd2, 0x6c, 0xe7, 0x26, 0xb9, 0x9b, - 0x3b, 0x23, 0x0b, 0x12, 0x62, 0x93, 0x15, 0x98, 0x0e, 0x02, 0x92, 0x48, - 0xb3, 0x40, 0x14, 0xe5, 0xb2, 0x57, 0xed, 0x51, 0xa6, 0x9f, 0xb5, 0x86, - 0x0d, 0x5a, 0x9d, 0x8c, 0xdc, 0x0b, 0x69, 0x66, 0x3a, 0x9a, 0x77, 0xd9, - 0xd5, 0x7a, 0x01, 0x57, 0xcf, 0x70, 0xb5, 0x88, 0x98, 0x73, 0x52, 0xc6, - 0xd8, 0xac, 0xca, 0x25, 0x2f, 0xc5, 0x46, 0x69, 0x89, 0x22, 0x36, 0x34, - 0xcd, 0xe2, 0xb2, 0x65, 0x91, 0xbc, 0xc0, 0x55, 0x29, 0x2f, 0x87, 0xaf, - 0xeb, 0x4e, 0x31, 0x0b, 0xd8, 0xcd, 0x9a, 0xfb, 0x7d, 0x55, 0x7b, 0x86, - 0x35, 0xd1, 0x18, 0x9c, 0xf2, 0x99, 0x11, 0x62, 0x69, 0xb5, 0x64, 0x06, - 0x29, 0x69, 0xd8, 0x04, 0xa5, 0xa0, 0x05, 0x1d, 0x6a, 0xe2, 0x1c, 0xad, - 0x20, 0x03, 0x4d, 0x34, 0x00, 0xca, 0x4a, 0x00, 0x4a, 0x5a, 0x40, 0x3a, - 0xaa, 0xbf, 0xde, 0xa6, 0x21, 0x2a, 0x41, 0x40, 0xc7, 0x53, 0x48, 0xa0, - 0x04, 0xdb, 0x4b, 0x48, 0x05, 0xa4, 0xa0, 0x02, 0x8a, 0x00, 0x6d, 0x30, - 0xd3, 0x00, 0xa7, 0x2d, 0x00, 0x3f, 0x14, 0xca, 0x00, 0x72, 0x75, 0xab, - 0x29, 0x40, 0x31, 0x5a, 0xa7, 0x4a, 0x46, 0x63, 0x2e, 0x7e, 0xe5, 0x66, - 0x9a, 0x63, 0x88, 0xe5, 0xa5, 0xa0, 0xb1, 0x69, 0x73, 0x45, 0x80, 0x09, - 0xa6, 0xd2, 0x01, 0x69, 0xd4, 0x01, 0x13, 0x75, 0xa2, 0x98, 0x83, 0x14, - 0x0a, 0x40, 0x3a, 0x9a, 0x45, 0x30, 0x05, 0xeb, 0x52, 0xd2, 0xea, 0x33, - 0xdb, 0x2c, 0x4f, 0xc9, 0x56, 0xa4, 0x6f, 0x96, 0xbb, 0x68, 0xec, 0x73, - 0x54, 0x31, 0x75, 0x05, 0xe6, 0xb3, 0x51, 0xc4, 0x72, 0xf2, 0x6b, 0x3c, - 0x41, 0xac, 0x0d, 0x5f, 0xed, 0x28, 0xd2, 0x2a, 0xc5, 0xbf, 0xd4, 0x1a, - 0x5c, 0xaa, 0x71, 0x58, 0xc6, 0x5a, 0x0f, 0x93, 0x53, 0x37, 0xcb, 0xcb, - 0x6e, 0x34, 0xed, 0xb5, 0xce, 0xce, 0x81, 0xca, 0x29, 0xf8, 0xe6, 0xa4, - 0x09, 0x10, 0x54, 0xeb, 0xc5, 0x30, 0x2c, 0x43, 0x76, 0xd1, 0x9a, 0xd0, - 0x17, 0xde, 0x76, 0xd4, 0x7a, 0xd2, 0x2f, 0x94, 0xca, 0x71, 0xb9, 0xa3, - 0x04, 0x83, 0xaa, 0x1f, 0xc2, 0x95, 0xfe, 0x76, 0xe9, 0x5d, 0x31, 0x77, - 0x39, 0xd9, 0x3a, 0x82, 0x16, 0xab, 0xb8, 0x91, 0xab, 0x48, 0xad, 0x09, - 0x6c, 0x8f, 0xec, 0xe4, 0x9f, 0x7a, 0x5b, 0xe7, 0xfb, 0x34, 0x1c, 0x2f, - 0x5a, 0x69, 0x5c, 0x2e, 0x36, 0xc5, 0x5e, 0x71, 0x92, 0x31, 0x56, 0xe5, - 0xdb, 0x6f, 0x1f, 0xbd, 0x44, 0x51, 0x52, 0x76, 0x31, 0xaf, 0x75, 0x24, - 0x5c, 0x96, 0xae, 0x76, 0xee, 0xf5, 0xe7, 0x7e, 0x7a, 0x54, 0xc9, 0xd8, - 0xd2, 0x9c, 0x46, 0x2a, 0xc8, 0xe2, 0x90, 0x44, 0x01, 0xf9, 0x8e, 0x2b, - 0x9f, 0x73, 0xb9, 0x35, 0x12, 0xa7, 0xdb, 0xa3, 0x0f, 0x8a, 0xb4, 0xb7, - 0xb6, 0xe0, 0x72, 0x6b, 0x3b, 0x3b, 0x8e, 0x75, 0x2f, 0xb1, 0x2a, 0xdd, - 0x40, 0xdf, 0xfe, 0xaa, 0x78, 0x68, 0x8f, 0x43, 0x45, 0xcc, 0x47, 0x6d, - 0x1d, 0x54, 0xd3, 0x6a, 0x59, 0xa2, 0x61, 0x4e, 0x51, 0x52, 0x50, 0xfd, - 0xb4, 0x85, 0x29, 0x5c, 0x76, 0x23, 0x68, 0xaa, 0x22, 0x31, 0x4c, 0x44, - 0x6f, 0x20, 0x51, 0x50, 0x35, 0xc7, 0xa1, 0xa4, 0x05, 0x69, 0x6f, 0x42, - 0xf5, 0x35, 0x46, 0x6d, 0x48, 0x0e, 0x95, 0xa2, 0xa7, 0x72, 0x5c, 0x8a, - 0x32, 0xdf, 0xc8, 0xf5, 0x5c, 0xb9, 0x6e, 0xb5, 0xb2, 0x85, 0x8e, 0x76, - 0xee, 0x32, 0x8a, 0x62, 0x0a, 0x5a, 0x76, 0x00, 0xa2, 0x80, 0x16, 0x8a, - 0x40, 0x15, 0x3c, 0x2d, 0x4c, 0x09, 0xa9, 0xa6, 0x90, 0x88, 0xcd, 0x36, - 0x80, 0x0a, 0x4a, 0x06, 0x3a, 0xa1, 0x93, 0xad, 0x08, 0x4c, 0x65, 0x48, - 0xb4, 0x0c, 0x5a, 0x28, 0x18, 0xb4, 0x94, 0x00, 0x94, 0x50, 0x20, 0xa4, - 0xa0, 0x02, 0xa3, 0x34, 0x20, 0x0a, 0x70, 0xa0, 0x07, 0xd3, 0x4d, 0x00, - 0x2a, 0x55, 0x84, 0xa0, 0x07, 0x35, 0x4e, 0x9d, 0x29, 0x19, 0x90, 0xdd, - 0xfd, 0xca, 0xa1, 0x4c, 0x71, 0x1c, 0xb4, 0xe1, 0x41, 0x62, 0xe2, 0x96, - 0x8b, 0x88, 0x69, 0xa4, 0xa4, 0x31, 0xd4, 0xb4, 0x80, 0x8d, 0xba, 0xd2, - 0x8a, 0x62, 0x0c, 0x52, 0x62, 0x98, 0x0b, 0x45, 0x00, 0x20, 0xeb, 0x52, - 0x8a, 0x43, 0x3d, 0x8b, 0x4b, 0x97, 0x30, 0xd5, 0x9b, 0x89, 0x0f, 0x15, - 0xd5, 0x87, 0xf8, 0x4c, 0x2a, 0x7c, 0x45, 0x2b, 0xce, 0x63, 0x15, 0xcf, - 0xde, 0x47, 0x33, 0xb8, 0x11, 0xf1, 0xcd, 0x69, 0x25, 0x74, 0x34, 0xec, - 0x46, 0x15, 0xc7, 0x12, 0x75, 0xa3, 0x8a, 0xe2, 0x6a, 0xc6, 0xf7, 0x1a, - 0x69, 0x2b, 0x36, 0x50, 0xe5, 0x34, 0xec, 0x54, 0x6c, 0x31, 0xe2, 0x9e, - 0xb4, 0x0c, 0x95, 0x45, 0x38, 0x64, 0x3d, 0x59, 0x24, 0xe2, 0xe0, 0x83, - 0xcd, 0x69, 0x5a, 0xdf, 0x0c, 0xfc, 0xc7, 0x34, 0xf9, 0xac, 0x44, 0xa3, - 0x73, 0x66, 0x27, 0x49, 0x17, 0x2b, 0x8a, 0x73, 0x2e, 0x6b, 0xae, 0x9c, - 0xee, 0x72, 0x38, 0xd9, 0x80, 0x50, 0x29, 0xb2, 0xc0, 0x92, 0xfd, 0xf1, - 0x9a, 0xbb, 0xd8, 0x42, 0x34, 0x91, 0x40, 0x9d, 0x40, 0x15, 0xce, 0x6b, - 0x3a, 0xc1, 0x20, 0xac, 0x1d, 0x6a, 0x63, 0xa6, 0xac, 0xab, 0x5d, 0x98, - 0x3e, 0x49, 0x90, 0xee, 0x91, 0x89, 0x3e, 0xf4, 0xfd, 0xb1, 0xc6, 0x33, - 0xd2, 0xb9, 0xa7, 0x3b, 0xb3, 0xb1, 0x14, 0xef, 0xb5, 0x58, 0xe1, 0x52, - 0x17, 0x93, 0x58, 0x77, 0x5a, 0x9c, 0xd3, 0xe4, 0x74, 0x53, 0xe8, 0x68, - 0x48, 0x4d, 0x95, 0x50, 0xd3, 0x5f, 0xef, 0x55, 0x22, 0x6e, 0xc4, 0x12, - 0xb2, 0xf4, 0x63, 0x52, 0xa5, 0xec, 0xc8, 0x78, 0x73, 0x53, 0xc9, 0x73, - 0x4e, 0x62, 0xca, 0xeb, 0x13, 0x63, 0xff, 0x00, 0xaf, 0x4f, 0x5d, 0x62, - 0x4c, 0xfc, 0xc4, 0x9a, 0xcd, 0xd2, 0x29, 0x4e, 0xc5, 0x88, 0x35, 0x8e, - 0x79, 0xad, 0xcb, 0x5b, 0x85, 0x95, 0x6b, 0x9a, 0x4b, 0x95, 0x9d, 0x31, - 0xd5, 0x16, 0x29, 0xac, 0xc0, 0x53, 0x02, 0xbc, 0xd7, 0x28, 0xbd, 0xeb, - 0x3a, 0x7b, 0xe1, 0x54, 0x91, 0x06, 0x7c, 0xf7, 0xea, 0x3b, 0xd6, 0x7c, - 0xb7, 0xec, 0xdd, 0x2b, 0x65, 0x13, 0x27, 0x32, 0xb3, 0x4a, 0xcd, 0xd4, - 0xd4, 0x79, 0xad, 0x4c, 0x6e, 0x14, 0x50, 0x01, 0x4b, 0x48, 0x04, 0xa5, - 0xa6, 0x01, 0x45, 0x30, 0x1d, 0x8a, 0x7a, 0xad, 0x20, 0x1d, 0x22, 0x60, - 0x54, 0x4a, 0x70, 0x68, 0x02, 0xca, 0x3e, 0x69, 0xc6, 0x81, 0x0c, 0x22, - 0x99, 0x48, 0x63, 0x68, 0xa0, 0x02, 0xa3, 0x7e, 0xb4, 0xc4, 0x32, 0x9e, - 0xb4, 0x86, 0x3a, 0x8a, 0x00, 0x28, 0xa0, 0x04, 0xa2, 0x90, 0x05, 0x14, - 0x00, 0x94, 0xc3, 0x4c, 0x04, 0xa7, 0x0a, 0x00, 0x75, 0x36, 0x80, 0x1c, - 0xb5, 0x3a, 0xd0, 0x0c, 0x52, 0x7e, 0x6a, 0xb2, 0x94, 0x8c, 0xca, 0xf7, - 0x67, 0x8a, 0xa5, 0x54, 0x38, 0x8f, 0x4a, 0x78, 0xa4, 0x58, 0x51, 0x83, - 0x45, 0x84, 0x34, 0xd1, 0x49, 0x8c, 0x29, 0xc2, 0x90, 0x11, 0xb7, 0x5a, - 0x51, 0x54, 0x21, 0xd4, 0x94, 0x08, 0x69, 0xa6, 0xe6, 0x81, 0x8a, 0x2a, - 0x5a, 0x06, 0x7a, 0xbe, 0x91, 0x27, 0xcb, 0x8a, 0xd6, 0x6d, 0xac, 0x05, - 0x5d, 0x09, 0x59, 0x11, 0x38, 0x5e, 0x45, 0x79, 0xb0, 0xdc, 0x76, 0xaa, - 0x93, 0x98, 0xe0, 0x84, 0x91, 0x8a, 0xeb, 0x5a, 0x9c, 0xf3, 0xec, 0x62, - 0xca, 0x09, 0x3b, 0x9a, 0xa3, 0xe2, 0xb9, 0x2a, 0x6e, 0x75, 0x43, 0x61, - 0xac, 0xde, 0xd4, 0xcc, 0x9f, 0x4a, 0xc8, 0xa1, 0xd1, 0xc5, 0x33, 0x74, - 0x5a, 0x9d, 0x20, 0x97, 0xb8, 0x1f, 0x9d, 0x3e, 0x41, 0x73, 0x93, 0x79, - 0x34, 0xf5, 0xb7, 0x3e, 0xb4, 0xb9, 0x47, 0xcc, 0x4b, 0xe5, 0x15, 0x14, - 0x8b, 0x1e, 0x69, 0xd8, 0x57, 0x14, 0xc4, 0x69, 0x9b, 0x48, 0xa2, 0xc5, - 0x73, 0x17, 0x20, 0xbc, 0x92, 0x3c, 0x56, 0x95, 0xbe, 0xa6, 0x3b, 0x9f, - 0xce, 0xa5, 0x7b, 0xa4, 0xc9, 0x5c, 0xb1, 0xfd, 0xa7, 0x15, 0x41, 0x73, - 0xad, 0xc5, 0x0c, 0x44, 0x81, 0xcd, 0x6c, 0xa6, 0x63, 0xec, 0xce, 0x66, - 0xe6, 0xfa, 0xe2, 0xed, 0xc9, 0x76, 0xe3, 0xd2, 0xa0, 0xc6, 0x2a, 0x2a, - 0x54, 0xb9, 0xd3, 0x1a, 0x76, 0x17, 0x9a, 0x82, 0xee, 0x27, 0x78, 0x48, - 0x5a, 0xc1, 0x3d, 0x4d, 0x24, 0xb4, 0x30, 0xe7, 0xd3, 0x27, 0xea, 0x71, - 0x55, 0x5e, 0xc6, 0x55, 0xfe, 0x1a, 0xe8, 0x52, 0xb9, 0x85, 0x86, 0x79, - 0x2e, 0x3b, 0x53, 0x1e, 0x26, 0xf4, 0xa6, 0x84, 0x45, 0xe5, 0xb0, 0xed, - 0x4d, 0xc1, 0xa2, 0xc3, 0x12, 0x9c, 0x05, 0x48, 0x17, 0x2d, 0x2c, 0xa4, - 0x99, 0xba, 0x1c, 0x57, 0x4f, 0x67, 0x6f, 0xe4, 0xa7, 0x5a, 0xe5, 0xa8, - 0xee, 0xce, 0xc8, 0x2b, 0x22, 0x59, 0x6e, 0x16, 0x31, 0xcd, 0x66, 0x4f, - 0xa9, 0x73, 0xc5, 0x25, 0x11, 0x36, 0x64, 0xdc, 0x5f, 0x77, 0xc9, 0xaa, - 0x32, 0x5e, 0x3b, 0x74, 0x3c, 0x57, 0x4a, 0x89, 0x84, 0xa6, 0x56, 0x24, - 0x93, 0xcd, 0x25, 0x59, 0x98, 0x51, 0x40, 0x09, 0x45, 0x30, 0x16, 0x8a, - 0x90, 0x0a, 0x5a, 0x00, 0x4a, 0x5a, 0x60, 0x48, 0x2a, 0x45, 0xa4, 0x03, - 0xa4, 0xfb, 0xb5, 0x57, 0x1c, 0xd0, 0x04, 0xb1, 0xe4, 0x1a, 0xb0, 0x0d, - 0x00, 0xc0, 0x8a, 0x89, 0x85, 0x02, 0x19, 0x45, 0x03, 0x12, 0x9a, 0xd4, - 0x08, 0x8a, 0x9e, 0xb4, 0xc6, 0x3a, 0x8a, 0x40, 0x14, 0x52, 0x01, 0x28, - 0xa2, 0xc0, 0x25, 0x2d, 0x00, 0x25, 0x25, 0x50, 0x06, 0x29, 0x69, 0x00, - 0xb8, 0xa4, 0xc5, 0x20, 0x01, 0x52, 0x07, 0xa5, 0x60, 0x63, 0xb7, 0xf3, - 0x56, 0x11, 0xc5, 0x04, 0x15, 0xee, 0xdb, 0x9a, 0xad, 0x54, 0x34, 0x28, - 0x38, 0xa9, 0x63, 0xe4, 0x50, 0x50, 0xea, 0x33, 0x83, 0x40, 0x86, 0x4a, - 0x72, 0xd4, 0xca, 0x43, 0x16, 0x9d, 0x48, 0x06, 0x37, 0x5a, 0x51, 0x54, - 0x21, 0x69, 0xa4, 0xd0, 0x03, 0x69, 0x28, 0x18, 0xe1, 0x52, 0x0e, 0x95, - 0x20, 0x7a, 0x3d, 0x94, 0x84, 0x36, 0x06, 0x6b, 0x7a, 0x31, 0x95, 0x19, - 0x6a, 0xa4, 0x8d, 0x79, 0x92, 0x2b, 0xcf, 0x2e, 0x24, 0xfb, 0xd8, 0x15, - 0x91, 0x79, 0x7d, 0x18, 0xcb, 0x1e, 0x47, 0xa2, 0xf5, 0xae, 0xa8, 0xec, - 0x71, 0x4f, 0xe2, 0x33, 0xbe, 0xd6, 0x6e, 0xe6, 0x08, 0xb9, 0xdb, 0x57, - 0xa3, 0xb4, 0x5e, 0xec, 0x6b, 0x07, 0xab, 0x36, 0xd9, 0x12, 0x3c, 0x30, - 0xa2, 0xf4, 0xaa, 0x98, 0x06, 0x4f, 0x6a, 0x52, 0xd8, 0x11, 0x6b, 0xed, - 0x51, 0x01, 0x8c, 0xd3, 0x0d, 0xc6, 0x7a, 0x54, 0xdc, 0x2c, 0x09, 0x37, - 0xcd, 0xcd, 0x4f, 0xf6, 0xa4, 0x5a, 0x45, 0x10, 0xbe, 0xa4, 0xbb, 0xb6, - 0xf1, 0xf9, 0xd3, 0xe3, 0xbe, 0x43, 0xc5, 0x29, 0x68, 0x09, 0x13, 0x79, - 0xd9, 0xa6, 0xef, 0x35, 0x3c, 0xc5, 0x72, 0x86, 0xfa, 0x4c, 0x9a, 0x9b, - 0x97, 0x60, 0xa6, 0x34, 0x7e, 0xd4, 0x93, 0x18, 0xdf, 0x2e, 0x97, 0xcb, - 0xa8, 0x6c, 0xb0, 0xd9, 0x4a, 0x40, 0xef, 0x48, 0x64, 0x05, 0xa3, 0xa5, - 0xf2, 0x15, 0x85, 0x5a, 0xd0, 0x96, 0x91, 0x1f, 0xd8, 0x22, 0x6e, 0xd4, - 0xd6, 0xd1, 0xe0, 0x6e, 0xab, 0x5b, 0x29, 0xd8, 0xc6, 0x51, 0x2a, 0xdc, - 0xe8, 0xf1, 0xed, 0x1b, 0x06, 0xdf, 0xa5, 0x67, 0xbe, 0x90, 0xe3, 0xbe, - 0x6a, 0x9d, 0x52, 0x54, 0x0a, 0x8f, 0xa6, 0xcd, 0x9f, 0xbb, 0x56, 0xec, - 0xb4, 0x67, 0x2d, 0x99, 0x78, 0x15, 0x95, 0x49, 0x9a, 0xd3, 0x89, 0xb5, - 0x14, 0x31, 0xdb, 0x2d, 0x54, 0xb9, 0xd4, 0x82, 0xf0, 0xa6, 0xb0, 0x8a, - 0x36, 0x6c, 0xc7, 0xb9, 0xbe, 0xc9, 0xf9, 0x8e, 0x6b, 0x3e, 0x4b, 0xa7, - 0x6e, 0x95, 0xd3, 0x18, 0x9c, 0xf3, 0x65, 0x66, 0x39, 0xeb, 0x49, 0x5b, - 0x10, 0x14, 0x94, 0x84, 0x25, 0x2d, 0x21, 0x85, 0x15, 0x42, 0x0a, 0x2a, - 0x46, 0x2d, 0x14, 0x80, 0x28, 0xaa, 0x02, 0x55, 0xa7, 0xe6, 0xa4, 0x43, - 0xdb, 0x95, 0xa8, 0x01, 0xc5, 0x31, 0x8b, 0x9a, 0x96, 0x3c, 0xd0, 0x04, - 0xc3, 0x9a, 0x64, 0x8b, 0x48, 0x92, 0x03, 0x49, 0x40, 0xc4, 0xa4, 0xa0, - 0x08, 0xda, 0x94, 0x53, 0x63, 0x43, 0xb3, 0x45, 0x20, 0x12, 0x8a, 0x00, - 0x5a, 0x4a, 0x04, 0x14, 0x53, 0x00, 0xa2, 0x86, 0x01, 0x45, 0x20, 0x16, - 0x8a, 0x00, 0x43, 0x4c, 0xa6, 0x01, 0x9a, 0x70, 0x90, 0x8a, 0x56, 0x01, - 0x33, 0x9a, 0x5c, 0x53, 0x01, 0xad, 0x53, 0x45, 0xf7, 0x29, 0x00, 0xfa, - 0x88, 0xd1, 0x70, 0x1b, 0xde, 0x92, 0x90, 0xc5, 0xa7, 0x0a, 0x00, 0x63, - 0x75, 0xa3, 0x34, 0xc4, 0x2d, 0x46, 0x68, 0x00, 0xa2, 0x81, 0x8e, 0x15, - 0x20, 0xa0, 0x0f, 0x5b, 0xfb, 0x32, 0xda, 0x29, 0x6e, 0x33, 0x54, 0x26, - 0xd4, 0x8a, 0xb6, 0x31, 0x9f, 0xc6, 0xba, 0xa6, 0xb9, 0x4c, 0x29, 0xbe, - 0x66, 0x67, 0xdc, 0x5d, 0xca, 0xcd, 0xc1, 0xaa, 0x8f, 0x6e, 0xb2, 0xf3, - 0x23, 0x56, 0x77, 0xd0, 0xd1, 0x8f, 0xb6, 0x78, 0xe0, 0x3c, 0x55, 0x9f, - 0xb5, 0xfa, 0x66, 0xa5, 0x09, 0x95, 0x6e, 0xaf, 0xcf, 0x4e, 0xbf, 0x5a, - 0x84, 0x5d, 0xbe, 0x3a, 0x7e, 0xb4, 0xdd, 0x31, 0x29, 0x11, 0x1b, 0x96, - 0xce, 0x49, 0x35, 0x13, 0x6a, 0x72, 0x29, 0xc2, 0x8f, 0xd6, 0x9f, 0xb2, - 0x2b, 0x98, 0x85, 0xb5, 0x09, 0xbe, 0x95, 0x19, 0xbb, 0x9c, 0xff, 0x00, - 0xcb, 0x43, 0x53, 0x6b, 0x0e, 0xe3, 0x3c, 0xc7, 0xcf, 0xdf, 0x35, 0xa1, - 0xa3, 0x2c, 0x92, 0xdd, 0x0f, 0x98, 0xe2, 0xb3, 0xad, 0xb1, 0xad, 0x2d, - 0xce, 0x94, 0x27, 0x02, 0x97, 0x6d, 0x73, 0x16, 0x3b, 0x65, 0x38, 0x44, - 0x4f, 0x41, 0x40, 0xcb, 0x31, 0xe9, 0xf2, 0x3f, 0x6a, 0x8e, 0xea, 0xd8, - 0xdb, 0xfd, 0xea, 0xdb, 0x94, 0xcf, 0x9f, 0x52, 0xb5, 0x15, 0xce, 0x6e, - 0x36, 0x99, 0x27, 0x4a, 0x10, 0x99, 0x44, 0xdb, 0x1d, 0xd5, 0x69, 0x14, - 0xd5, 0x30, 0x48, 0x99, 0x45, 0x48, 0x2a, 0x2e, 0x55, 0x86, 0x91, 0x9a, - 0x61, 0x8c, 0x7a, 0x51, 0x70, 0xb1, 0x1f, 0x94, 0xa2, 0xa0, 0xb8, 0xb8, - 0x8e, 0x04, 0xcd, 0x35, 0xa8, 0x6c, 0x62, 0x5e, 0xea, 0x06, 0x4c, 0xf3, - 0xc7, 0xb5, 0x64, 0xcd, 0x75, 0xe9, 0x5d, 0x11, 0x89, 0x8b, 0x65, 0x46, - 0x62, 0xd4, 0x95, 0xa1, 0x90, 0x86, 0x92, 0x98, 0x05, 0x25, 0x02, 0x0a, - 0x5c, 0x52, 0x18, 0xb8, 0xa4, 0xa6, 0x80, 0x4a, 0x5a, 0x00, 0x29, 0x68, - 0x01, 0x29, 0x69, 0x00, 0xf1, 0x4f, 0x14, 0x80, 0x97, 0xf8, 0x69, 0x82, - 0x2a, 0x04, 0x4a, 0x23, 0x02, 0x9d, 0x8a, 0x04, 0x37, 0xa1, 0xa9, 0x78, - 0x65, 0xa0, 0x0a, 0xae, 0xb8, 0xa8, 0xe8, 0x01, 0x29, 0x28, 0x18, 0xd3, - 0x49, 0x4c, 0x62, 0xd2, 0xd2, 0x10, 0x51, 0x40, 0x05, 0x14, 0xc0, 0x28, - 0xa4, 0x02, 0x51, 0x40, 0x06, 0x28, 0xa0, 0x61, 0x4b, 0x40, 0x82, 0xa3, - 0xa0, 0x04, 0xa2, 0x81, 0x8e, 0x5a, 0x75, 0x31, 0x0d, 0x6a, 0x96, 0x1f, - 0xbb, 0x48, 0x07, 0xf6, 0xa8, 0xa8, 0x01, 0x86, 0x8a, 0x06, 0x2d, 0x3a, - 0x90, 0x0c, 0x6a, 0x41, 0x4e, 0xc0, 0x49, 0xfc, 0x35, 0x0d, 0x02, 0x12, - 0x9d, 0x40, 0xc5, 0xa9, 0x29, 0x30, 0x3d, 0x37, 0x53, 0xbb, 0x77, 0x3b, - 0x73, 0x59, 0xbb, 0x47, 0x2e, 0x6b, 0xa6, 0xb6, 0xb2, 0xb1, 0x8d, 0x3f, - 0x76, 0x37, 0x2b, 0xb4, 0x9f, 0x3e, 0x4f, 0xdd, 0x15, 0x14, 0x7e, 0x7c, - 0xc7, 0x8f, 0xbb, 0xef, 0x55, 0xca, 0x47, 0x30, 0xa2, 0xd1, 0xde, 0x40, - 0x37, 0x6d, 0xfa, 0x55, 0xcf, 0xb3, 0x72, 0x06, 0x49, 0xfc, 0x2a, 0x89, - 0xb9, 0x05, 0xc5, 0xb0, 0x3c, 0x2f, 0x5a, 0x86, 0xe1, 0x56, 0xde, 0x23, - 0xf2, 0xd6, 0x84, 0xdc, 0xa0, 0xd7, 0x1b, 0x07, 0xff, 0x00, 0x5e, 0xa9, - 0xb1, 0xc9, 0x35, 0x93, 0x36, 0x48, 0x51, 0x49, 0x59, 0x58, 0xd0, 0x3e, - 0x83, 0x9a, 0xeb, 0x34, 0x1b, 0x2f, 0x22, 0x0d, 0xe4, 0x7c, 0xc6, 0xb9, - 0x6b, 0xbe, 0x87, 0x45, 0x25, 0xa5, 0xcd, 0x4d, 0x94, 0x6d, 0xac, 0x4a, - 0x16, 0xb4, 0x34, 0x98, 0x95, 0xe4, 0x62, 0xc0, 0x71, 0x8a, 0x40, 0xf6, - 0x34, 0x65, 0xb8, 0x8a, 0xdc, 0xe0, 0x57, 0x3d, 0xac, 0x5c, 0x19, 0xfe, - 0xed, 0x75, 0xde, 0xc7, 0x34, 0x62, 0xee, 0x53, 0x55, 0x38, 0xa7, 0xd7, - 0x19, 0xd8, 0x14, 0xda, 0x00, 0x6e, 0x29, 0xd4, 0x0c, 0x5a, 0x75, 0x21, - 0x85, 0x21, 0x38, 0xa0, 0x0c, 0xdb, 0xeb, 0xf1, 0x0a, 0xfc, 0xbc, 0x9a, - 0xe7, 0xee, 0xaf, 0x0b, 0xb6, 0x5f, 0x9a, 0xde, 0x28, 0xc5, 0xc8, 0xcc, - 0x96, 0xe0, 0xbd, 0x42, 0x2b, 0x74, 0x62, 0xc7, 0x52, 0x53, 0x01, 0x29, - 0xb4, 0x00, 0x94, 0x54, 0x80, 0x66, 0x9d, 0x9a, 0x04, 0x26, 0x69, 0x33, - 0x54, 0x30, 0xa5, 0xa4, 0x01, 0x45, 0x00, 0x14, 0x52, 0x01, 0xeb, 0x52, - 0x0a, 0x00, 0x91, 0x4d, 0x4b, 0x40, 0x83, 0x34, 0xb4, 0x08, 0x6b, 0x53, - 0x51, 0xf1, 0x40, 0x09, 0x27, 0x35, 0x01, 0xa1, 0x00, 0xdc, 0xd2, 0x50, - 0x50, 0x94, 0xa0, 0x50, 0x01, 0x45, 0x32, 0x42, 0x8a, 0x43, 0x0a, 0x33, - 0x40, 0x09, 0x9a, 0x37, 0x50, 0x02, 0x6e, 0xa5, 0xdf, 0x40, 0x09, 0xbe, - 0x8d, 0xd4, 0x00, 0x6e, 0xa7, 0xee, 0xe2, 0x80, 0x19, 0x9a, 0x69, 0xa0, - 0x04, 0xa2, 0x98, 0xc7, 0x2d, 0x3a, 0x90, 0x86, 0xb5, 0x4b, 0x09, 0xf9, - 0x68, 0x01, 0x69, 0x94, 0x30, 0x18, 0x68, 0xa0, 0x62, 0xd2, 0xd4, 0x80, - 0xd7, 0xa6, 0x8a, 0xa0, 0x24, 0x6f, 0xb9, 0x51, 0x50, 0x20, 0xa5, 0x14, - 0x0c, 0x5c, 0xd3, 0xe9, 0x01, 0xe8, 0xd2, 0x21, 0x63, 0xbd, 0xeb, 0x36, - 0xe2, 0x4f, 0x35, 0xbc, 0xb5, 0xfb, 0xbd, 0xeb, 0xaa, 0x3a, 0xbe, 0x63, - 0x9e, 0x5d, 0x84, 0x58, 0x8b, 0x9f, 0x25, 0x39, 0x53, 0xe9, 0x57, 0x45, - 0xa8, 0x8c, 0x04, 0x40, 0x72, 0x6b, 0x43, 0x33, 0x46, 0x1b, 0x3f, 0x22, - 0x0d, 0xc5, 0x23, 0xdd, 0xeb, 0x9a, 0x72, 0x42, 0xb1, 0x23, 0x49, 0xe6, - 0xe3, 0xda, 0x9a, 0x64, 0xb3, 0x35, 0xbc, 0xbd, 0xfb, 0x98, 0xb6, 0x41, - 0xaa, 0x17, 0x3f, 0xbc, 0x72, 0x48, 0xe3, 0xde, 0xa9, 0x05, 0x8c, 0xab, - 0x80, 0xac, 0xdc, 0x0e, 0x95, 0x0e, 0xca, 0xc6, 0x7b, 0x9b, 0xc4, 0x29, - 0xb5, 0x9b, 0x28, 0xbb, 0xa4, 0xda, 0xfd, 0xa6, 0xf1, 0x01, 0x1f, 0x28, - 0x35, 0xda, 0x5b, 0xc6, 0x12, 0x25, 0x51, 0xd0, 0x0a, 0xe0, 0xa9, 0xac, - 0x8e, 0xd8, 0xfc, 0x24, 0x84, 0x55, 0x7b, 0x89, 0x04, 0x29, 0xb8, 0xd1, - 0x15, 0x72, 0x5b, 0x28, 0xc9, 0xa9, 0xa2, 0x0c, 0xd4, 0x71, 0xf8, 0x94, - 0x40, 0xd8, 0x59, 0x76, 0xd5, 0x3a, 0x4c, 0x14, 0x91, 0x66, 0xd7, 0x53, - 0xfb, 0x74, 0xb5, 0x68, 0x8a, 0x8e, 0x62, 0xb9, 0x6c, 0x36, 0x98, 0x45, - 0x22, 0x82, 0x9b, 0x40, 0x08, 0x69, 0x05, 0x16, 0x01, 0xd4, 0x54, 0x14, - 0x26, 0x6b, 0x33, 0x51, 0xd4, 0x3c, 0xa1, 0xb5, 0x7a, 0xd6, 0x90, 0x8d, - 0xc9, 0x93, 0x39, 0xbb, 0x9b, 0xa2, 0xce, 0x49, 0x35, 0x42, 0x47, 0xdd, - 0x5d, 0x56, 0x39, 0xe4, 0x45, 0x4e, 0x15, 0x64, 0x8b, 0x49, 0x40, 0x05, - 0x34, 0xd4, 0x80, 0xda, 0x4a, 0x04, 0x82, 0x96, 0x9d, 0xc6, 0x14, 0x52, - 0x01, 0x68, 0xa4, 0x01, 0x4b, 0x4c, 0x02, 0x8a, 0x40, 0x2a, 0xd4, 0x82, - 0x80, 0x24, 0x5e, 0xb5, 0x2d, 0x02, 0x0a, 0x5a, 0x00, 0x4a, 0x89, 0xc6, - 0x39, 0xa0, 0x06, 0xe6, 0x9a, 0xd4, 0x0c, 0x65, 0x14, 0x08, 0x6d, 0x3c, - 0x30, 0xc5, 0x00, 0x30, 0x9a, 0x6e, 0x69, 0xee, 0x02, 0xe6, 0x93, 0x34, - 0x86, 0x26, 0x68, 0xcd, 0x00, 0x25, 0x14, 0x00, 0x51, 0x40, 0x09, 0x4b, - 0x4c, 0x05, 0xa6, 0xd0, 0x02, 0xd1, 0x8a, 0x40, 0x2e, 0x29, 0x31, 0x40, - 0x87, 0x2d, 0x3a, 0x80, 0x1a, 0xd5, 0x24, 0x3d, 0x0d, 0x00, 0x38, 0xd4, - 0x74, 0x00, 0xda, 0x29, 0x0c, 0x51, 0x4b, 0x40, 0x0d, 0x7a, 0x6d, 0x30, - 0x15, 0x8f, 0x14, 0xda, 0x00, 0x4a, 0x78, 0x14, 0x00, 0xec, 0x53, 0xa8, - 0x03, 0xd0, 0xf5, 0x19, 0x73, 0xfb, 0xb4, 0xea, 0x6a, 0x88, 0x4d, 0x9f, - 0xc3, 0xf3, 0x1a, 0xe9, 0x8a, 0x39, 0x59, 0xa5, 0xa7, 0xd8, 0x98, 0x17, - 0x7e, 0xee, 0x7e, 0xb5, 0xa1, 0x04, 0x0a, 0xff, 0x00, 0xbd, 0x9a, 0x46, - 0x03, 0xda, 0xb4, 0x44, 0x49, 0x99, 0x17, 0xd7, 0xe1, 0x2e, 0x30, 0x9f, - 0xbc, 0x51, 0xfd, 0xea, 0x8d, 0xee, 0x6e, 0x6e, 0xe3, 0x2a, 0x91, 0x44, - 0xa3, 0xd7, 0x75, 0x5c, 0xb4, 0x90, 0x2d, 0x8a, 0xc5, 0x67, 0xf3, 0x02, - 0x34, 0xbc, 0x54, 0x37, 0xce, 0x04, 0x7b, 0x43, 0x9d, 0xd5, 0x3d, 0x47, - 0xb9, 0x9b, 0x48, 0x71, 0x58, 0xbd, 0xcd, 0xc8, 0xd8, 0xd3, 0x7e, 0x95, - 0x0c, 0xa8, 0x9d, 0x5f, 0x87, 0xec, 0xfc, 0x98, 0x3c, 0xc3, 0xf7, 0x8f, - 0xf8, 0xd6, 0xe4, 0x75, 0xe6, 0xee, 0x76, 0xb1, 0x4d, 0x64, 0xeb, 0xdf, - 0xf1, 0xe2, 0xdf, 0x8d, 0x6f, 0x47, 0xe2, 0x39, 0xea, 0xfc, 0x27, 0x2f, - 0x2f, 0x4a, 0xce, 0x97, 0xad, 0x7a, 0x12, 0xd8, 0xe7, 0x8b, 0x36, 0xfc, - 0x31, 0x20, 0x87, 0x7f, 0xd3, 0xfa, 0xd6, 0xe9, 0xbe, 0x5a, 0xf2, 0xf9, - 0x7d, 0xe6, 0x7a, 0x12, 0x64, 0x7f, 0xda, 0x0b, 0x47, 0xdb, 0x47, 0xbd, - 0x57, 0x29, 0x37, 0x1b, 0xf6, 0xcf, 0x63, 0x4d, 0xfb, 0x67, 0xb1, 0xaa, - 0x51, 0x23, 0x98, 0x0d, 0xef, 0xfb, 0x26, 0xa3, 0x5b, 0xd2, 0x7f, 0x86, - 0x93, 0x88, 0xe2, 0xcb, 0x70, 0xc8, 0x5d, 0x6a, 0x6a, 0xc4, 0xd8, 0xce, - 0xd5, 0x2f, 0x84, 0x11, 0xe0, 0x7d, 0xea, 0xe5, 0xee, 0x67, 0xdc, 0xd9, - 0x35, 0xd1, 0x04, 0x60, 0xe4, 0x51, 0x27, 0x3d, 0x69, 0x2b, 0x63, 0x21, - 0x48, 0xe6, 0x8a, 0x00, 0x43, 0x49, 0x40, 0x05, 0x34, 0xd0, 0x03, 0x68, - 0xa4, 0x02, 0xd2, 0x55, 0x00, 0x51, 0x48, 0x05, 0xa2, 0x80, 0x0a, 0x5a, - 0x40, 0x14, 0x50, 0x02, 0xad, 0x48, 0x28, 0x01, 0xea, 0x6a, 0x5a, 0x00, - 0x5a, 0x28, 0x10, 0x53, 0x5b, 0xee, 0x1a, 0x04, 0x57, 0xcf, 0x34, 0x53, - 0x18, 0xda, 0x29, 0x00, 0xc3, 0x4d, 0xa0, 0x04, 0xa2, 0x98, 0x0b, 0x49, - 0x48, 0x61, 0x45, 0x30, 0x16, 0x8c, 0x52, 0x10, 0xb8, 0xa5, 0xc5, 0x00, - 0x32, 0x9e, 0x28, 0x01, 0x68, 0xc5, 0x03, 0x11, 0x69, 0x28, 0x10, 0x66, - 0x92, 0x98, 0x0a, 0xb4, 0xea, 0x43, 0x1a, 0x69, 0xd1, 0x1a, 0x00, 0x71, - 0xa6, 0xd0, 0x21, 0xb4, 0x50, 0x31, 0x68, 0xa0, 0x00, 0xd2, 0x50, 0x03, - 0x69, 0x31, 0x40, 0x05, 0x48, 0x28, 0x00, 0xdd, 0x49, 0x9a, 0x00, 0xef, - 0x91, 0x77, 0x39, 0x79, 0x2a, 0xd6, 0x9d, 0x6d, 0xe6, 0xcf, 0xba, 0x55, - 0x62, 0x05, 0x75, 0x1c, 0x86, 0xc7, 0x91, 0xe6, 0x61, 0x56, 0x11, 0xff, - 0x00, 0x02, 0x38, 0xa6, 0x6b, 0x17, 0xf2, 0x59, 0x59, 0xf9, 0x42, 0x28, - 0xc6, 0x78, 0xf9, 0x4d, 0x74, 0xc1, 0x6a, 0x61, 0x2d, 0x8e, 0x49, 0xb0, - 0x5c, 0x9f, 0x53, 0x57, 0x62, 0xb9, 0x8a, 0x35, 0xc0, 0xdd, 0x9a, 0xc2, - 0x6e, 0xf2, 0x36, 0x5b, 0x11, 0x49, 0x38, 0x1f, 0xc0, 0x33, 0x59, 0xb7, - 0x2f, 0xe6, 0x1c, 0x95, 0xc5, 0x52, 0x63, 0x48, 0xaf, 0x8a, 0x8d, 0xab, - 0x37, 0xa9, 0xa8, 0xcc, 0x55, 0xcd, 0x26, 0xd7, 0xed, 0x37, 0xa8, 0x31, - 0xf2, 0xe6, 0xb9, 0xaa, 0xbb, 0x44, 0xde, 0x92, 0xd4, 0xed, 0x63, 0x5d, - 0xb1, 0xa8, 0x1e, 0x95, 0x2a, 0xd7, 0x11, 0xb8, 0xe3, 0x59, 0x7a, 0xda, - 0xee, 0xb3, 0x61, 0xf5, 0xad, 0xa8, 0xfc, 0x46, 0x15, 0x76, 0x39, 0x79, - 0xc6, 0x06, 0x2b, 0x3a, 0x41, 0xf3, 0x57, 0x7c, 0x96, 0x87, 0x3c, 0x0d, - 0xdf, 0x0e, 0xdb, 0x16, 0x47, 0x7e, 0xd8, 0xfe, 0xb5, 0xa8, 0xf6, 0xb5, - 0xe7, 0xf5, 0x3b, 0x64, 0x33, 0xec, 0xc3, 0xd2, 0x9c, 0xb6, 0xf5, 0x7b, - 0x88, 0x9c, 0x5a, 0x67, 0xff, 0x00, 0xd5, 0x4b, 0xf6, 0x51, 0x53, 0x66, - 0x3d, 0x06, 0x9b, 0x74, 0xa4, 0xf2, 0x12, 0xa5, 0xb2, 0x92, 0x24, 0x55, - 0x0b, 0x55, 0xef, 0x6e, 0x56, 0xde, 0x12, 0xc6, 0xa2, 0x2a, 0xec, 0xa9, - 0x1c, 0x9d, 0xed, 0xd1, 0x9a, 0x42, 0xed, 0x59, 0xec, 0x77, 0x57, 0x5c, - 0x4e, 0x71, 0x29, 0x45, 0x36, 0x48, 0xfc, 0x71, 0x51, 0xd3, 0xb8, 0x09, - 0x45, 0x48, 0x0a, 0x72, 0x6a, 0x33, 0x4e, 0xe0, 0x36, 0x8a, 0x00, 0x7d, - 0x36, 0x8b, 0x80, 0x62, 0x8a, 0x2e, 0x02, 0x53, 0xa8, 0x00, 0xa5, 0x14, - 0x80, 0x29, 0x0d, 0x00, 0x02, 0xa5, 0x14, 0x00, 0xb5, 0x32, 0xf4, 0xa0, - 0x05, 0xa2, 0x81, 0x0b, 0x47, 0x6a, 0x04, 0x54, 0x3f, 0x7a, 0x8a, 0x60, - 0x25, 0x14, 0xae, 0x31, 0x86, 0x81, 0x40, 0x08, 0x69, 0x29, 0x8c, 0x5a, - 0x28, 0x10, 0x62, 0x9d, 0xb6, 0x90, 0x06, 0x29, 0x68, 0xb8, 0x0b, 0x49, - 0x40, 0x82, 0x8d, 0xb4, 0x0c, 0x5c, 0x52, 0xe2, 0x80, 0x13, 0x6d, 0x30, - 0x8a, 0x62, 0x0d, 0xb4, 0xb8, 0xa4, 0x30, 0xa2, 0x80, 0x18, 0xd5, 0x24, - 0x3d, 0xe8, 0x00, 0x6a, 0x6d, 0x00, 0x21, 0xa2, 0x81, 0x85, 0x2d, 0x2b, - 0x80, 0xec, 0x66, 0x82, 0x29, 0x88, 0x6e, 0x28, 0x34, 0x98, 0xc4, 0xa4, - 0xcd, 0x30, 0x12, 0x94, 0x0a, 0x00, 0xf4, 0x36, 0xf9, 0xa4, 0x11, 0xd6, - 0xbd, 0xa5, 0xce, 0xd0, 0x23, 0x49, 0x30, 0x7d, 0xab, 0xa9, 0xe8, 0xce, - 0x4d, 0xd0, 0xeb, 0xbb, 0xbf, 0x22, 0x13, 0x23, 0x34, 0x8d, 0x8f, 0xee, - 0xd7, 0x29, 0xa9, 0xdd, 0x34, 0xad, 0xe6, 0x7c, 0xdb, 0x7f, 0xdd, 0xae, - 0xa5, 0x1d, 0x0c, 0xba, 0x94, 0x7c, 0xf7, 0x28, 0x5b, 0x9c, 0x7b, 0xd4, - 0xb6, 0xf9, 0x61, 0x97, 0xe0, 0x57, 0x31, 0xb9, 0x5b, 0x69, 0x9e, 0x6e, - 0x1b, 0x8a, 0x99, 0xb9, 0xc0, 0xa7, 0xf6, 0x82, 0xe3, 0x1b, 0xa5, 0x40, - 0x6a, 0x64, 0x52, 0x0c, 0x13, 0xd2, 0xba, 0xaf, 0x0e, 0x69, 0xed, 0x1c, - 0x5b, 0xf6, 0xfc, 0xdf, 0xfd, 0x7a, 0xe5, 0xad, 0xd8, 0xea, 0xa5, 0xa6, - 0xa7, 0x44, 0xba, 0x7c, 0xed, 0xda, 0xa7, 0x5d, 0x2e, 0x4f, 0xef, 0x52, - 0xf6, 0x44, 0x7b, 0x54, 0x3b, 0xfb, 0x35, 0xbf, 0xbd, 0x55, 0x35, 0x0d, - 0x1c, 0xc9, 0x6e, 0x46, 0xe3, 0x5b, 0x52, 0xa6, 0x94, 0x8c, 0x6a, 0xd5, - 0xf7, 0x4e, 0x5a, 0xe3, 0x43, 0xbb, 0x24, 0xfc, 0xa2, 0xab, 0x2f, 0x86, - 0x6e, 0x5f, 0xa9, 0x02, 0xbb, 0x27, 0x63, 0x08, 0x4c, 0xe8, 0x34, 0x7d, - 0x0d, 0xad, 0xad, 0xf6, 0x75, 0xeb, 0x5a, 0x23, 0x49, 0x26, 0xb8, 0x94, - 0x0e, 0xa9, 0x55, 0x24, 0x1a, 0x38, 0xa9, 0x97, 0x4b, 0x51, 0x4e, 0xc4, - 0x73, 0x8f, 0x36, 0x91, 0xc4, 0xb9, 0xae, 0x73, 0x51, 0xbc, 0x54, 0x27, - 0x6d, 0x2e, 0x5d, 0x07, 0x19, 0xea, 0x62, 0xdc, 0xea, 0xcf, 0x9d, 0xa8, - 0xbf, 0xad, 0x5d, 0xb3, 0x9b, 0xcc, 0x5a, 0xe2, 0xa9, 0xb9, 0xdf, 0x4f, - 0x62, 0xce, 0xec, 0x57, 0x35, 0xac, 0x5e, 0x99, 0xa5, 0xda, 0x3a, 0x0a, - 0xba, 0x68, 0xce, 0xa3, 0x31, 0x1c, 0x92, 0x69, 0x36, 0xf1, 0x5b, 0x18, - 0x8e, 0x0b, 0x45, 0x3d, 0xc4, 0x1d, 0xaa, 0x3a, 0x06, 0x1c, 0xd2, 0x73, - 0x45, 0x80, 0x4e, 0x69, 0x3a, 0xd0, 0x03, 0x69, 0x3b, 0xd3, 0x60, 0x3e, - 0x8c, 0x52, 0xb0, 0x05, 0x36, 0x8b, 0x00, 0x94, 0xb4, 0x80, 0x29, 0x69, - 0x80, 0xb4, 0x52, 0x01, 0x29, 0xe2, 0x80, 0x1e, 0x2a, 0x45, 0xcd, 0x02, - 0x1d, 0x45, 0x30, 0x16, 0x95, 0x7a, 0xd2, 0xb8, 0x8a, 0xce, 0x39, 0xa6, - 0x53, 0x60, 0x86, 0xd2, 0xd2, 0x28, 0x43, 0x41, 0xa6, 0x21, 0x29, 0xb4, - 0x80, 0x50, 0x29, 0xe1, 0x68, 0x01, 0xdd, 0x29, 0x28, 0x00, 0xc5, 0x18, - 0xa0, 0x03, 0x14, 0x98, 0xa0, 0x02, 0x8a, 0x00, 0x5c, 0xd2, 0xe6, 0x8b, - 0x08, 0x33, 0x48, 0x68, 0x18, 0x94, 0x94, 0x00, 0x51, 0x40, 0x0d, 0x34, - 0xf8, 0x7a, 0x9a, 0x06, 0x07, 0xad, 0x21, 0xa0, 0x44, 0x7d, 0xe8, 0xa0, - 0x62, 0xe6, 0x9d, 0x48, 0x07, 0x52, 0x66, 0x98, 0x0d, 0x26, 0x92, 0x80, - 0x12, 0x97, 0x14, 0x08, 0x5a, 0x28, 0x19, 0xe9, 0xd1, 0xd9, 0xb7, 0xde, - 0x28, 0x0f, 0xd6, 0xae, 0xd9, 0xda, 0xc0, 0x9f, 0xbe, 0x95, 0x9c, 0x7b, - 0x01, 0x5d, 0xdb, 0x9c, 0x43, 0x9e, 0x0f, 0x3e, 0x5d, 0xd1, 0x6d, 0xf2, - 0xff, 0x00, 0xda, 0x35, 0x9b, 0x7f, 0x1b, 0xc9, 0x27, 0x97, 0x80, 0x56, - 0xb4, 0xba, 0x23, 0xd4, 0xa7, 0x75, 0x02, 0x24, 0x3b, 0x16, 0x35, 0x19, - 0xac, 0x5b, 0xa9, 0x76, 0x2f, 0x93, 0x19, 0xc0, 0x35, 0x25, 0xc7, 0x72, - 0x58, 0x53, 0xc8, 0x83, 0x27, 0xa9, 0xfd, 0x69, 0xf0, 0x41, 0x9e, 0x58, - 0xd6, 0x45, 0xb1, 0x97, 0x71, 0xac, 0x69, 0x85, 0xa8, 0xec, 0x2c, 0x65, - 0xbd, 0x9c, 0x47, 0x1a, 0xf2, 0x6a, 0xa7, 0xdc, 0x21, 0xa9, 0xd8, 0xe9, - 0x9e, 0x0e, 0x85, 0x42, 0xbd, 0xd7, 0x27, 0xd3, 0x02, 0xba, 0x7b, 0x7b, - 0x68, 0xad, 0x93, 0x6c, 0x49, 0x81, 0x5c, 0xb3, 0x95, 0xcd, 0xa3, 0x72, - 0x5a, 0x2a, 0x0a, 0xe4, 0x41, 0x45, 0x3b, 0xd8, 0xc7, 0x96, 0xfa, 0x0c, - 0x31, 0x21, 0xfe, 0x11, 0x48, 0xb6, 0xf1, 0x2f, 0x44, 0x15, 0xa7, 0xb4, - 0xb9, 0x1e, 0xce, 0xc3, 0xf0, 0x3d, 0x29, 0x6a, 0x79, 0x8a, 0xe4, 0x0a, - 0x46, 0xe0, 0x55, 0x27, 0x70, 0xb5, 0x8c, 0x2f, 0x10, 0x5d, 0xb4, 0x36, - 0xdb, 0x14, 0xfc, 0xcd, 0x91, 0x5c, 0x1d, 0xfd, 0xce, 0xd2, 0xc1, 0x7a, - 0x93, 0x4e, 0x7b, 0x17, 0x4b, 0x72, 0x8c, 0x7f, 0x31, 0xc9, 0xad, 0xad, - 0x35, 0xf8, 0xc5, 0x70, 0x54, 0x3d, 0x18, 0x12, 0x6a, 0x77, 0x5e, 0x45, - 0xb9, 0xc7, 0xde, 0xed, 0x5c, 0xa4, 0xaf, 0xb9, 0xcd, 0x6d, 0x4f, 0x63, - 0x9a, 0x7b, 0x91, 0xe2, 0x9d, 0x5a, 0x12, 0x2d, 0x06, 0x90, 0x11, 0x66, - 0x9b, 0x4c, 0x02, 0x8a, 0x00, 0x29, 0xb4, 0x80, 0x63, 0x52, 0x03, 0x54, - 0x04, 0x94, 0x52, 0x00, 0xa6, 0xd0, 0x02, 0x51, 0x48, 0x02, 0x96, 0xa8, - 0x05, 0xa2, 0xa5, 0x80, 0x94, 0xf5, 0xa0, 0x07, 0x53, 0xd2, 0x81, 0x12, - 0x51, 0x40, 0x05, 0x20, 0x6f, 0x9a, 0x98, 0x11, 0xce, 0x3e, 0x7a, 0x8a, - 0x81, 0x09, 0x40, 0xa4, 0x50, 0x53, 0x68, 0x10, 0x94, 0xa0, 0x50, 0x04, - 0x80, 0x53, 0xc0, 0xa0, 0x03, 0x14, 0x98, 0xa0, 0x02, 0x9b, 0x9a, 0x00, - 0x4c, 0xd2, 0x66, 0x80, 0x0a, 0x28, 0x18, 0x52, 0x66, 0x98, 0x83, 0x34, - 0x66, 0x90, 0x06, 0x69, 0x33, 0x40, 0x82, 0x8a, 0x06, 0x07, 0x9a, 0x74, - 0x5d, 0x68, 0x01, 0xa4, 0xf3, 0x49, 0x40, 0xc4, 0xa4, 0xa0, 0x02, 0x97, - 0x34, 0x00, 0xbb, 0xa9, 0x28, 0x00, 0xa2, 0x80, 0x16, 0x96, 0x80, 0x12, - 0x8a, 0x00, 0xf5, 0xe8, 0xa1, 0x69, 0xa7, 0x01, 0x72, 0xeb, 0xdf, 0x70, - 0xa9, 0x6e, 0xe7, 0x2a, 0xbe, 0x47, 0x96, 0x23, 0xcf, 0xf7, 0x2b, 0xd0, - 0x5d, 0xd1, 0xe7, 0xb2, 0x85, 0xd4, 0x90, 0xc7, 0x16, 0xc4, 0x67, 0x24, - 0xfa, 0xad, 0x51, 0xff, 0x00, 0x52, 0x85, 0xb7, 0xe2, 0x82, 0x8c, 0xc9, - 0xae, 0x36, 0x83, 0x21, 0x6c, 0x91, 0x54, 0xec, 0xa3, 0xf3, 0xe7, 0xde, - 0x7a, 0x2f, 0xaf, 0xd6, 0xa2, 0x6f, 0x42, 0xa2, 0x5b, 0x65, 0xde, 0xde, - 0xc2, 0x9a, 0xd2, 0x34, 0x7f, 0x76, 0x80, 0x29, 0xca, 0xcd, 0x2b, 0x7b, - 0xe2, 0xbb, 0xef, 0x09, 0xe9, 0x8b, 0x6d, 0x6b, 0xe7, 0x32, 0xfc, 0xed, - 0x91, 0xfa, 0xd7, 0x3d, 0x67, 0xd0, 0xe9, 0xa6, 0xb4, 0x3a, 0x1a, 0x2b, - 0x22, 0xc2, 0x8a, 0x00, 0x33, 0x45, 0x04, 0x44, 0x28, 0xa0, 0xb0, 0xa2, - 0x80, 0x0a, 0x3a, 0xd3, 0x89, 0x95, 0x43, 0x90, 0xf1, 0x9c, 0xfe, 0x40, - 0xc8, 0xea, 0x39, 0x1f, 0x95, 0x70, 0x6c, 0x4b, 0xc9, 0x93, 0xcd, 0x6d, - 0x5f, 0x64, 0x56, 0x18, 0x9a, 0x2a, 0xd2, 0xb3, 0xf9, 0x6b, 0xcf, 0x91, - 0xdc, 0x8c, 0xfd, 0x5e, 0xe3, 0xcc, 0x97, 0x06, 0xb2, 0x47, 0xde, 0xae, - 0xa5, 0xb1, 0xc8, 0xc7, 0x77, 0xa2, 0xa8, 0x42, 0xd2, 0x37, 0x4a, 0x90, - 0x22, 0xa6, 0xd3, 0x18, 0x51, 0x40, 0x0b, 0x4d, 0xa4, 0xc4, 0x34, 0xd3, - 0x68, 0x01, 0x69, 0x68, 0x18, 0x66, 0x92, 0x90, 0x05, 0x14, 0xc4, 0x14, - 0x50, 0x31, 0x69, 0x29, 0x00, 0x53, 0xd6, 0x98, 0x87, 0xd3, 0xd6, 0x80, - 0x24, 0xa2, 0x81, 0x08, 0xd5, 0x1e, 0x79, 0xa0, 0x68, 0x7c, 0xa3, 0x85, - 0xaa, 0xef, 0x40, 0x84, 0xcd, 0x25, 0x03, 0x16, 0x9a, 0x69, 0x00, 0x0a, - 0x78, 0xa6, 0x03, 0xa9, 0xe0, 0xd2, 0x01, 0x09, 0xa6, 0x96, 0xa0, 0x42, - 0x53, 0x73, 0x40, 0xc4, 0xcd, 0x26, 0x69, 0x80, 0x99, 0xa2, 0x90, 0x05, - 0x25, 0x00, 0x14, 0xb4, 0x00, 0x51, 0x4c, 0x02, 0x8a, 0x00, 0x5a, 0x50, - 0x71, 0x48, 0x04, 0xa4, 0xa1, 0x00, 0x94, 0x53, 0x01, 0x28, 0xa4, 0x31, - 0x71, 0x4b, 0x40, 0x84, 0xa2, 0x80, 0x16, 0x92, 0x81, 0x8b, 0x45, 0x00, - 0x7b, 0x21, 0x95, 0x6d, 0x6d, 0x4f, 0xef, 0xdb, 0x71, 0xfe, 0xe8, 0xcd, - 0x67, 0x89, 0x36, 0xee, 0x90, 0xa0, 0x63, 0xfe, 0xd0, 0xae, 0xd5, 0xb1, - 0xc2, 0xf7, 0x18, 0x21, 0xf3, 0xff, 0x00, 0x78, 0xff, 0x00, 0x28, 0xac, - 0xdd, 0x4a, 0x68, 0xc1, 0xf2, 0xd7, 0xa7, 0x7a, 0xd1, 0x77, 0x24, 0xe7, - 0xa6, 0x79, 0x2e, 0xa6, 0x58, 0xd4, 0x63, 0xb5, 0x6c, 0xac, 0x5e, 0x45, - 0xb8, 0x8d, 0x7f, 0x8b, 0x9a, 0xc1, 0xeb, 0x23, 0x7d, 0x90, 0xad, 0xf2, - 0xad, 0x51, 0x99, 0xb9, 0xab, 0xe8, 0x40, 0x96, 0x89, 0xe6, 0x5c, 0x2a, - 0xfa, 0xff, 0x00, 0x85, 0x7a, 0xa5, 0xa2, 0x85, 0xb6, 0x8f, 0x1f, 0xdd, - 0x15, 0xc5, 0x53, 0xe3, 0x3b, 0x23, 0xa4, 0x09, 0xa8, 0xa0, 0x02, 0x8a, - 0x68, 0x97, 0x23, 0x9f, 0xd5, 0x35, 0x19, 0x61, 0xb8, 0x3b, 0x1f, 0x8d, - 0xa2, 0xa1, 0xb7, 0xd7, 0xca, 0x47, 0xfb, 0xce, 0xbe, 0xb5, 0xa5, 0x58, - 0x76, 0x22, 0x9b, 0xb9, 0xb7, 0x65, 0x7c, 0x97, 0x5d, 0x2a, 0xdd, 0x63, - 0x12, 0xa6, 0xec, 0x14, 0x55, 0xd8, 0x8e, 0x70, 0xa8, 0xa6, 0x97, 0x65, - 0x52, 0x44, 0x5c, 0xe0, 0xfc, 0x65, 0x37, 0x9d, 0x8e, 0x7b, 0x7f, 0x4a, - 0xe5, 0x54, 0x73, 0x46, 0x21, 0x9d, 0x18, 0x75, 0xa1, 0x76, 0xde, 0x12, - 0x71, 0x5a, 0x1b, 0x76, 0x47, 0xbb, 0xd2, 0xb8, 0xba, 0x9d, 0x4f, 0x63, - 0x9c, 0xb9, 0x25, 0xe4, 0x63, 0xf8, 0x54, 0x41, 0x71, 0x5d, 0x27, 0x30, - 0xe3, 0x49, 0x8a, 0x60, 0x39, 0x54, 0x9a, 0x64, 0xa3, 0x14, 0x80, 0x84, - 0xd2, 0x50, 0x00, 0x45, 0x25, 0x30, 0x12, 0x92, 0x80, 0x0a, 0x6e, 0x28, - 0x01, 0x71, 0x4b, 0x49, 0x80, 0x94, 0x94, 0xc0, 0x4a, 0x28, 0x00, 0xa2, - 0x80, 0x16, 0x8a, 0x40, 0x25, 0x48, 0xb4, 0x00, 0xfa, 0x7a, 0xd0, 0x22, - 0x5e, 0xd4, 0x84, 0xd0, 0x22, 0x07, 0x7a, 0x8b, 0x75, 0x03, 0x24, 0x32, - 0x7c, 0xb5, 0x1e, 0x6a, 0x80, 0x28, 0xa4, 0x20, 0xa4, 0x34, 0x86, 0x28, - 0xa7, 0x50, 0x31, 0x73, 0x46, 0x4d, 0x02, 0x12, 0x93, 0x34, 0x0c, 0x6e, - 0xea, 0x4a, 0x04, 0x25, 0x2d, 0x00, 0x25, 0x2d, 0x00, 0x14, 0x50, 0x01, - 0x45, 0x03, 0x0a, 0x28, 0xb8, 0x82, 0x8a, 0x00, 0x28, 0xa0, 0x02, 0x8a, - 0x00, 0x31, 0x45, 0x03, 0x12, 0x8a, 0x40, 0x19, 0xa2, 0x98, 0x0b, 0x8a, - 0x28, 0x00, 0x34, 0xda, 0x40, 0x2d, 0x3a, 0x98, 0x1e, 0x96, 0x24, 0x59, - 0x64, 0xc8, 0x00, 0x53, 0xb2, 0xd7, 0x12, 0x88, 0xb2, 0xc5, 0x6b, 0xae, - 0xe7, 0x1d, 0x8b, 0xd7, 0xf2, 0xc1, 0x67, 0x60, 0x71, 0x0f, 0xcf, 0x8f, - 0xa7, 0xa5, 0x72, 0x3a, 0x8b, 0x95, 0x89, 0xd8, 0x9f, 0xbd, 0x9c, 0x7f, - 0x3a, 0xe9, 0xda, 0x3a, 0x99, 0xad, 0x58, 0xed, 0x12, 0xcf, 0x6e, 0x6e, - 0x25, 0xcf, 0xe3, 0xf5, 0xab, 0xf8, 0xdc, 0xfb, 0x9b, 0xb5, 0x72, 0x47, - 0xb9, 0xb4, 0xf7, 0xb1, 0x5e, 0x73, 0x54, 0x1f, 0xad, 0x6a, 0x4a, 0x35, - 0x34, 0x5d, 0x26, 0xe6, 0x6b, 0x85, 0x75, 0x4c, 0x00, 0x7e, 0x95, 0xe8, - 0x56, 0xea, 0xc9, 0x0a, 0x86, 0xeb, 0x8a, 0xe4, 0x94, 0x57, 0x35, 0xcd, - 0xa5, 0x2f, 0x76, 0xc4, 0xb4, 0x52, 0x64, 0xab, 0xb0, 0xa2, 0xae, 0x2e, - 0xc4, 0x33, 0x3a, 0x6d, 0x26, 0x39, 0x5f, 0x24, 0x0a, 0x60, 0xd1, 0x21, - 0xf4, 0x5a, 0xd9, 0xd4, 0x44, 0xab, 0x96, 0xed, 0x6c, 0xa3, 0xb6, 0xfb, - 0xa2, 0xac, 0xd7, 0x39, 0xa8, 0x51, 0x4a, 0xe0, 0xe2, 0x15, 0x95, 0xaf, - 0x5e, 0x0b, 0x5b, 0x5e, 0x3e, 0xf1, 0xcd, 0x6b, 0x4f, 0x52, 0x5a, 0x3c, - 0xff, 0x00, 0x58, 0x94, 0xcd, 0xd7, 0xde, 0xaa, 0xd9, 0xc1, 0xe6, 0x3d, - 0x72, 0xd7, 0x91, 0xdf, 0x41, 0x58, 0xd8, 0x8a, 0x0d, 0xa3, 0x1d, 0xaa, - 0x3d, 0x43, 0xf7, 0x76, 0x52, 0x63, 0xd2, 0xb1, 0x86, 0xe5, 0xcf, 0x63, - 0x98, 0xea, 0xc7, 0xeb, 0x46, 0x2b, 0xa4, 0xe7, 0x1d, 0xe5, 0x9a, 0xb1, - 0x1c, 0x23, 0x14, 0x00, 0x93, 0x62, 0x35, 0xcd, 0x67, 0x31, 0xdc, 0x68, - 0x10, 0xca, 0x28, 0x18, 0xec, 0x52, 0x53, 0x01, 0xb4, 0xde, 0xf4, 0x00, - 0xb4, 0x50, 0x02, 0x52, 0x66, 0x80, 0x12, 0x92, 0x90, 0x09, 0x45, 0x3b, - 0x00, 0xb4, 0x52, 0x00, 0xa5, 0xa0, 0x02, 0x9c, 0xb4, 0x00, 0xfa, 0x5d, - 0xf4, 0x08, 0x53, 0x25, 0x44, 0x58, 0xd0, 0x31, 0xa4, 0xd3, 0x68, 0x10, - 0xea, 0x28, 0x18, 0xb4, 0x50, 0x20, 0xa3, 0x19, 0xa0, 0x03, 0x14, 0xb4, - 0x0c, 0x28, 0xcd, 0x02, 0x1a, 0x4d, 0x36, 0x80, 0x0a, 0x5a, 0x00, 0x28, - 0xa0, 0x61, 0x45, 0x00, 0x2d, 0x25, 0x02, 0x0a, 0x28, 0x00, 0xa5, 0xa0, - 0x04, 0xa2, 0x80, 0x0a, 0x28, 0x18, 0x51, 0x40, 0x0b, 0x49, 0x40, 0x84, - 0xa3, 0x14, 0x0c, 0x5c, 0x52, 0xe2, 0x90, 0x0b, 0x4d, 0xcd, 0x00, 0x18, - 0xa5, 0xa6, 0x01, 0x4b, 0x48, 0x0f, 0x44, 0xf2, 0x64, 0xd9, 0xc7, 0x5a, - 0xe9, 0x34, 0x5b, 0x3f, 0xb3, 0x43, 0xbc, 0xc4, 0xa1, 0xbd, 0x6b, 0xb3, - 0x94, 0xe3, 0x7b, 0x18, 0x3a, 0xf5, 0xf1, 0xba, 0xbf, 0x11, 0x3b, 0x7c, - 0x91, 0xe0, 0xe3, 0x3c, 0x77, 0x15, 0xce, 0xed, 0x3a, 0xa6, 0xa4, 0xb1, - 0xff, 0x00, 0xcb, 0x35, 0xc6, 0x7f, 0x51, 0x5b, 0xd5, 0x76, 0x22, 0x8a, - 0x37, 0x24, 0x5d, 0x91, 0xac, 0x2b, 0xe9, 0xcf, 0xe5, 0x50, 0xc9, 0xf2, - 0x8c, 0x56, 0x51, 0x2a, 0xe5, 0x19, 0x89, 0x26, 0xb4, 0xb4, 0x2d, 0x14, - 0xdf, 0x4f, 0x97, 0xfb, 0x83, 0xad, 0x4d, 0x49, 0x58, 0xb8, 0x23, 0xb9, - 0xb6, 0xb6, 0x8e, 0xda, 0x30, 0xb1, 0x8c, 0x54, 0xd5, 0xcb, 0x73, 0x5b, - 0x20, 0xa2, 0x91, 0xa8, 0x51, 0x4c, 0xc6, 0xde, 0xf0, 0x51, 0x48, 0xa6, - 0x14, 0x50, 0x48, 0x51, 0x4d, 0x0a, 0x4c, 0x09, 0xc7, 0x5a, 0xe1, 0x7c, - 0x47, 0x7e, 0x25, 0xb8, 0x66, 0x63, 0xf2, 0xa5, 0x6d, 0x0d, 0x9b, 0x17, - 0xda, 0x39, 0x67, 0x90, 0xca, 0xd9, 0x35, 0xa3, 0xa6, 0xc7, 0x83, 0x93, - 0xd6, 0xbc, 0xfa, 0x8e, 0xe7, 0xa3, 0x4c, 0xd2, 0xaa, 0x9a, 0xaf, 0xfc, - 0x78, 0xc9, 0xfe, 0xed, 0x10, 0xdc, 0x55, 0x36, 0x30, 0x12, 0x1c, 0xf5, - 0xf5, 0xa9, 0x44, 0x38, 0xed, 0x5d, 0x27, 0x28, 0xae, 0x94, 0xcd, 0xdb, - 0x68, 0x02, 0x9d, 0xc4, 0x9b, 0xb8, 0xaa, 0xf5, 0x43, 0x10, 0xd1, 0x48, - 0x63, 0xa9, 0x28, 0x10, 0xda, 0x4a, 0x06, 0x25, 0x36, 0x81, 0x09, 0x49, - 0x40, 0x09, 0x45, 0x03, 0x0a, 0x28, 0x00, 0xa2, 0x80, 0x16, 0x8a, 0x00, - 0x29, 0x73, 0x40, 0x06, 0x68, 0xcd, 0x00, 0x19, 0xa4, 0xcd, 0x20, 0x1b, - 0x45, 0x00, 0x3a, 0x96, 0x98, 0x05, 0x14, 0x84, 0x2d, 0x14, 0xc0, 0x5a, - 0x4a, 0x40, 0x14, 0x94, 0x00, 0x94, 0x50, 0xc0, 0x28, 0xa0, 0x05, 0xa2, - 0x85, 0xa0, 0x09, 0x45, 0x31, 0x85, 0x14, 0x84, 0x2d, 0x25, 0x03, 0x16, - 0x92, 0x81, 0x05, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, 0x0c, 0x28, 0xa0, - 0x42, 0xe2, 0x97, 0x14, 0x00, 0x62, 0x8a, 0x06, 0x25, 0x18, 0xa4, 0x01, - 0x4b, 0x40, 0x09, 0x49, 0x4c, 0x0f, 0x5d, 0xd3, 0x20, 0xdf, 0x74, 0x1b, - 0x83, 0x8a, 0xb7, 0xe2, 0x09, 0xe7, 0x8a, 0xcc, 0xc7, 0x13, 0xfc, 0xe4, - 0x11, 0x5e, 0x85, 0x1b, 0x4e, 0x57, 0x3c, 0xf9, 0xbb, 0x1c, 0x66, 0xa9, - 0x17, 0xd9, 0xed, 0x0a, 0xc4, 0x4e, 0xe9, 0x37, 0x67, 0xb7, 0xbd, 0x5c, - 0xd1, 0xad, 0x92, 0xda, 0xd8, 0xc9, 0x8d, 0xce, 0x7f, 0xc6, 0xa6, 0xa6, - 0xeb, 0xcc, 0xda, 0x1b, 0x32, 0xc6, 0x3b, 0xd5, 0x59, 0xcd, 0x04, 0x0d, - 0xb3, 0xb4, 0xfb, 0x5c, 0xe1, 0x7b, 0x1a, 0xef, 0xac, 0xad, 0x92, 0xd6, - 0x00, 0x88, 0x31, 0x5c, 0x95, 0x25, 0x79, 0x58, 0xe9, 0x8a, 0xb4, 0x6e, - 0x58, 0xa2, 0x95, 0x8c, 0x79, 0xb5, 0x0a, 0x46, 0x6d, 0xbd, 0x68, 0x51, - 0xb9, 0xb3, 0x95, 0x88, 0xd6, 0x75, 0x67, 0xda, 0x2a, 0x5a, 0x97, 0xd8, - 0x22, 0x14, 0x50, 0x50, 0x51, 0x54, 0x61, 0xd4, 0x28, 0xa6, 0xc4, 0x51, - 0xd5, 0xe7, 0x30, 0xd9, 0x3e, 0xdf, 0xbc, 0x47, 0x15, 0xe6, 0x9a, 0xbc, - 0xcc, 0xf2, 0xb0, 0xec, 0x4f, 0xf3, 0xad, 0x5c, 0x5a, 0xa6, 0x55, 0x2d, - 0x66, 0x56, 0xb6, 0x8f, 0x27, 0x15, 0xbb, 0x6d, 0x1e, 0xd5, 0xaf, 0x36, - 0x47, 0xa6, 0x4f, 0x55, 0xaf, 0xd3, 0x7d, 0xbb, 0x0f, 0x6a, 0xa8, 0x6e, - 0x44, 0xf6, 0x32, 0x02, 0xe3, 0x8a, 0x5c, 0x56, 0xec, 0xe6, 0x17, 0x65, - 0x50, 0xba, 0x3c, 0xd5, 0x22, 0x4a, 0x4f, 0x4d, 0xa1, 0x94, 0x21, 0xa0, - 0x52, 0x63, 0x1d, 0x4d, 0x34, 0xc4, 0x30, 0x9a, 0x6d, 0x03, 0x12, 0x9b, - 0x4c, 0x02, 0x8a, 0x40, 0x14, 0x50, 0x02, 0x51, 0x4c, 0x02, 0x8a, 0x40, - 0x2d, 0x14, 0x80, 0x28, 0xa0, 0x41, 0x49, 0x4c, 0x61, 0x49, 0x48, 0x02, - 0x8a, 0x60, 0x2d, 0x3a, 0x80, 0x0a, 0x54, 0xeb, 0x43, 0x10, 0xa6, 0x92, - 0x90, 0x0b, 0x45, 0x17, 0x18, 0xda, 0x4a, 0x04, 0x28, 0xe6, 0x96, 0x9b, - 0x01, 0x08, 0xa2, 0x90, 0x05, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, 0x00, - 0x52, 0x50, 0x02, 0xd2, 0x50, 0x01, 0x4b, 0x40, 0x05, 0x25, 0x00, 0x14, - 0x50, 0x01, 0x4b, 0x40, 0xc5, 0x14, 0xa6, 0x90, 0x09, 0x45, 0x0c, 0x04, - 0xcd, 0x2d, 0x00, 0x25, 0x26, 0x69, 0x80, 0x94, 0x50, 0x07, 0xff, 0xd9, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xca, 0x0c, 0x57, 0x6d, 0x24, 0x63, 0x36, 0x61, 0x5f, 0x2f, 0x06, 0x9f, - 0xa4, 0x9d, 0xac, 0x3e, 0xb5, 0x85, 0x72, 0xe0, 0x6e, 0xff, 0x00, 0x0d, - 0x53, 0xb9, 0xe9, 0x5a, 0x47, 0x63, 0x03, 0x9a, 0xd5, 0x97, 0xe5, 0x35, - 0x92, 0x05, 0x61, 0x58, 0xea, 0xa4, 0x4a, 0x07, 0x14, 0x6d, 0xac, 0x6e, - 0x6c, 0x58, 0x89, 0x2b, 0x42, 0xc9, 0x8c, 0x2c, 0x0d, 0x48, 0x8e, 0x8a, - 0xd6, 0xf5, 0xd8, 0x63, 0x15, 0x6a, 0x49, 0x5f, 0x67, 0x35, 0xd7, 0x44, - 0xe4, 0xa8, 0x88, 0xa3, 0xe7, 0x9a, 0x94, 0xa1, 0x61, 0x5a, 0x90, 0x2a, - 0xc7, 0x4b, 0xe5, 0x1a, 0x00, 0xb1, 0x18, 0xe2, 0xab, 0x5e, 0x48, 0x10, - 0xf5, 0xa9, 0xe8, 0x3e, 0xa4, 0xe6, 0x40, 0x91, 0x02, 0x6a, 0x8c, 0xb3, - 0xb3, 0xf0, 0x2a, 0x53, 0xd0, 0x2d, 0xa8, 0xc4, 0x88, 0x9a, 0x71, 0x01, - 0x28, 0x28, 0xad, 0x71, 0x20, 0x11, 0x92, 0x4f, 0x15, 0xce, 0x5d, 0xeb, - 0x1b, 0x64, 0x29, 0x6e, 0xb9, 0x6f, 0x5e, 0x69, 0xda, 0xe8, 0x16, 0xe4, - 0x3e, 0x75, 0xd4, 0xa3, 0xe6, 0x7d, 0xbf, 0x4a, 0xcf, 0x9a, 0x36, 0x2f, - 0x86, 0xf9, 0xab, 0x16, 0xf4, 0x3a, 0x61, 0xb8, 0xe8, 0xe0, 0xa7, 0xb5, - 0xaa, 0x3f, 0x51, 0x5c, 0xfc, 0xc7, 0x43, 0x44, 0x2f, 0x60, 0x3f, 0x87, - 0x8a, 0xaa, 0xd0, 0xcb, 0x09, 0xc8, 0xab, 0xbd, 0xcc, 0xb6, 0x2c, 0x45, - 0xad, 0xcd, 0x0a, 0xe3, 0x15, 0x32, 0xea, 0x9e, 0x67, 0x2f, 0xf3, 0x7e, - 0x15, 0xbe, 0x1f, 0xdd, 0x67, 0x3e, 0x23, 0xde, 0x1e, 0x2f, 0x15, 0xbb, - 0x55, 0x1b, 0xac, 0xc9, 0x27, 0x02, 0xbd, 0x27, 0x56, 0xd1, 0x39, 0x29, - 0xd1, 0x7c, 0xe4, 0xb6, 0xf1, 0x95, 0x15, 0xa1, 0x08, 0xe2, 0xbc, 0x26, - 0xee, 0xcf, 0x63, 0xa1, 0x3e, 0xda, 0x6e, 0x70, 0x6a, 0xcc, 0xc8, 0x9d, - 0xe9, 0x9b, 0x8d, 0x4b, 0x65, 0x20, 0xce, 0x7a, 0xd2, 0x56, 0x77, 0x2a, - 0xc4, 0x52, 0x4c, 0xa9, 0x54, 0x9e, 0xf7, 0xde, 0xa9, 0x08, 0xa9, 0x2d, - 0xd7, 0xbd, 0x55, 0x92, 0xe8, 0x76, 0x35, 0xa2, 0x44, 0x39, 0x95, 0xda, - 0xe0, 0xd4, 0x65, 0x8d, 0x6c, 0x62, 0xdd, 0xc6, 0xd2, 0x53, 0xd8, 0x44, - 0xb1, 0x1c, 0x35, 0x5b, 0xed, 0x48, 0x06, 0x1a, 0x61, 0xa0, 0x06, 0xd1, - 0x40, 0x05, 0x34, 0x8c, 0xd0, 0x98, 0x06, 0xce, 0x2a, 0x13, 0x4c, 0x42, - 0x53, 0xc5, 0x21, 0x85, 0x34, 0xd0, 0x03, 0x69, 0x76, 0xd3, 0x01, 0xd8, - 0xa5, 0xc5, 0x4d, 0xc0, 0x5a, 0x4a, 0x2e, 0x01, 0x51, 0x9a, 0x60, 0x14, - 0xe1, 0x40, 0x0b, 0x49, 0x40, 0x21, 0x45, 0x5a, 0x4f, 0xbb, 0x43, 0x01, - 0xc6, 0xa6, 0x5a, 0x46, 0x42, 0x5c, 0x7d, 0xca, 0xcb, 0x3d, 0x69, 0x95, - 0x11, 0xc9, 0x4b, 0x41, 0x63, 0xe9, 0xc2, 0x90, 0x08, 0xd4, 0xca, 0x60, - 0x14, 0xea, 0x40, 0x44, 0xdd, 0x69, 0x29, 0x88, 0x5a, 0x5a, 0x00, 0x43, - 0x4d, 0xa0, 0x07, 0xad, 0x4b, 0x48, 0x67, 0xb7, 0x5a, 0xbe, 0x56, 0xa6, - 0x95, 0x32, 0xb5, 0xdf, 0x48, 0xe5, 0x9e, 0xe6, 0x05, 0xf2, 0xf5, 0xa8, - 0x6c, 0xfe, 0x59, 0x45, 0x73, 0xe2, 0x0d, 0xe0, 0x6f, 0xaf, 0x31, 0xd5, - 0x4b, 0xa2, 0x00, 0xeb, 0x4e, 0x1b, 0x18, 0xbd, 0xce, 0x57, 0x55, 0x9f, - 0xcc, 0x7d, 0x8b, 0x8a, 0xa8, 0x13, 0x8a, 0xe7, 0xab, 0xbd, 0x8e, 0xba, - 0x6b, 0x41, 0xe1, 0x69, 0xe1, 0x6b, 0x13, 0x42, 0x78, 0xd6, 0xb4, 0x21, - 0xd9, 0x8c, 0x1a, 0x48, 0x4c, 0xe8, 0x34, 0xf1, 0x0e, 0x06, 0xdc, 0x66, - 0xa5, 0xd4, 0x1f, 0x11, 0x7e, 0x75, 0xdb, 0x40, 0xe2, 0xaa, 0x25, 0x9a, - 0xe6, 0x3e, 0x7a, 0xf5, 0xa7, 0xca, 0xf8, 0x38, 0x15, 0x51, 0xd8, 0x19, - 0x24, 0x3e, 0xf5, 0x2e, 0xe1, 0x4e, 0x22, 0x64, 0x12, 0x5d, 0xaa, 0x1e, - 0x39, 0xac, 0x6b, 0xb8, 0xe6, 0x9e, 0xe0, 0x49, 0x9f, 0x97, 0xd2, 0xa8, - 0x16, 0xe5, 0xed, 0xcc, 0xca, 0x01, 0xa9, 0x62, 0x41, 0x58, 0x24, 0x5b, - 0x1f, 0x2b, 0x88, 0xd6, 0xb2, 0xef, 0x6e, 0xf0, 0x33, 0x9e, 0x2b, 0x5b, - 0x12, 0x61, 0xde, 0xde, 0x3d, 0xc2, 0xec, 0x07, 0x09, 0x54, 0xbe, 0x44, - 0xe8, 0x2b, 0x29, 0xcb, 0x4b, 0x1b, 0xc2, 0x02, 0xf9, 0x84, 0xd2, 0x6c, - 0xe7, 0x26, 0xb9, 0x9b, 0x3b, 0x23, 0x0b, 0x12, 0x62, 0x93, 0x15, 0x98, - 0x0e, 0x02, 0x92, 0x48, 0xb3, 0x40, 0x14, 0xe5, 0xb2, 0x57, 0xed, 0x51, - 0xa6, 0x9f, 0xb5, 0x86, 0x0d, 0x5a, 0x9d, 0x8c, 0xdc, 0x0b, 0x69, 0x66, - 0x3a, 0x9a, 0x77, 0xd9, 0xd5, 0x7a, 0x01, 0x57, 0xcf, 0x70, 0xb5, 0x88, - 0x98, 0x73, 0x52, 0xc6, 0xd8, 0xac, 0xca, 0x25, 0x2f, 0xc5, 0x46, 0x69, - 0x89, 0x22, 0x36, 0x34, 0xcd, 0xe2, 0xb2, 0x65, 0x91, 0xbc, 0xc0, 0x55, - 0x29, 0x2f, 0x87, 0xaf, 0xeb, 0x4e, 0x31, 0x0b, 0xd8, 0xcd, 0x9a, 0xfb, - 0x7d, 0x55, 0x7b, 0x86, 0x35, 0xd1, 0x18, 0x9c, 0xf2, 0x99, 0x11, 0x62, - 0x69, 0xb5, 0x64, 0x06, 0x29, 0x69, 0xd8, 0x04, 0xa5, 0xa0, 0x05, 0x1d, - 0x6a, 0xe2, 0x1c, 0xad, 0x20, 0x03, 0x4d, 0x34, 0x00, 0xca, 0x4a, 0x00, - 0x4a, 0x5a, 0x40, 0x3a, 0xaa, 0xbf, 0xde, 0xa6, 0x21, 0x2a, 0x41, 0x40, - 0xc7, 0x53, 0x48, 0xa0, 0x04, 0xdb, 0x4b, 0x48, 0x05, 0xa4, 0xa0, 0x02, - 0x8a, 0x00, 0x6d, 0x30, 0xd3, 0x00, 0xa7, 0x2d, 0x00, 0x3f, 0x14, 0xca, - 0x00, 0x72, 0x75, 0xab, 0x29, 0x40, 0x31, 0x5a, 0xa7, 0x4a, 0x46, 0x63, - 0x2e, 0x7e, 0xe5, 0x66, 0x9a, 0x63, 0x88, 0xe5, 0xa5, 0xa0, 0xb1, 0x69, - 0x73, 0x45, 0x80, 0x09, 0xa6, 0xd2, 0x01, 0x69, 0xd4, 0x01, 0x13, 0x75, - 0xa2, 0x98, 0x83, 0x14, 0x0a, 0x40, 0x3a, 0x9a, 0x45, 0x30, 0x05, 0xeb, - 0x52, 0xd2, 0xea, 0x33, 0xdb, 0x2c, 0x4f, 0xc9, 0x56, 0xa4, 0x6f, 0x96, - 0xbb, 0x68, 0xec, 0x73, 0x54, 0x31, 0x75, 0x05 -}; -unsigned int capture_jpg_len = 24800; - - -unsigned const char octo_jpg[] = { - 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, - 0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, - 0x00, 0x11, 0x0b, 0x0c, 0x0f, 0x0c, 0x0a, 0x11, 0x0f, 0x0e, 0x0f, 0x13, - 0x12, 0x11, 0x14, 0x19, 0x2a, 0x1b, 0x19, 0x17, 0x17, 0x19, 0x33, 0x24, - 0x26, 0x1e, 0x2a, 0x3c, 0x35, 0x3f, 0x3e, 0x3b, 0x35, 0x3a, 0x39, 0x43, - 0x4b, 0x60, 0x51, 0x43, 0x47, 0x5a, 0x48, 0x39, 0x3a, 0x53, 0x71, 0x54, - 0x5a, 0x63, 0x66, 0x6b, 0x6c, 0x6b, 0x40, 0x50, 0x76, 0x7e, 0x74, 0x68, - 0x7d, 0x60, 0x69, 0x6b, 0x67, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x12, 0x13, - 0x13, 0x19, 0x16, 0x19, 0x31, 0x1b, 0x1b, 0x31, 0x67, 0x45, 0x3a, 0x45, - 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, - 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, - 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, - 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, - 0x67, 0x67, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x01, 0xe0, 0x02, 0x80, 0x03, - 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00, - 0x1f, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x10, 0x00, - 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, - 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, - 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, - 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, - 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, - 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, - 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, - 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, - 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, - 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, - 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, - 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, - 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, - 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, - 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x00, - 0x1f, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, - 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, - 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x11, 0x00, - 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, - 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, - 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, - 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, - 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, - 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, - 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, - 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, - 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, - 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, - 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, - 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, - 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, - 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, - 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x00, - 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xef, - 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, - 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, - 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, - 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa4, 0xa5, 0xa0, - 0x02, 0x8a, 0x4a, 0x5a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, - 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, - 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, - 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, - 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa4, 0xa5, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x92, 0x96, - 0xab, 0xdd, 0x4e, 0x96, 0xb6, 0xd2, 0xcc, 0xe7, 0x09, 0x1a, 0x96, 0x3f, - 0x80, 0xa0, 0x09, 0x8b, 0x28, 0xea, 0xc0, 0x7e, 0x34, 0x07, 0x53, 0xd1, - 0x81, 0xfc, 0x6b, 0xc8, 0xaf, 0x6f, 0xe7, 0xbd, 0xbb, 0x96, 0x69, 0x25, - 0x7c, 0xbb, 0x13, 0x80, 0xc7, 0x00, 0x54, 0x71, 0xdd, 0x4f, 0x19, 0xf9, - 0x27, 0x95, 0x48, 0xfe, 0xeb, 0x1a, 0x00, 0xf6, 0x2a, 0x2b, 0xcb, 0x6d, - 0x7c, 0x4b, 0xaa, 0xda, 0x91, 0xb2, 0xed, 0xdd, 0x47, 0xf0, 0xc9, 0xf3, - 0x56, 0xdd, 0x87, 0x8f, 0x5c, 0x61, 0x6f, 0xad, 0x81, 0x1f, 0xdf, 0x88, - 0xff, 0x00, 0x43, 0x40, 0x1d, 0xbd, 0x15, 0x99, 0xa7, 0xeb, 0xda, 0x7e, - 0xa1, 0x81, 0x05, 0xc2, 0xee, 0x3f, 0xc0, 0xdc, 0x1a, 0xd3, 0x1d, 0x28, - 0x01, 0x68, 0xa4, 0xa2, 0x80, 0x16, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x29, 0x28, 0x01, 0x69, 0x28, 0xcd, 0x21, 0x3c, 0xf3, - 0xd2, 0x80, 0x16, 0x8a, 0xca, 0xd4, 0x7c, 0x45, 0xa7, 0x69, 0xc0, 0xf9, - 0xd3, 0x86, 0x71, 0xfc, 0x09, 0xc9, 0xae, 0x6e, 0xfb, 0xc7, 0x93, 0x3e, - 0x56, 0xca, 0xdd, 0x50, 0x76, 0x79, 0x39, 0xfd, 0x28, 0x03, 0xb9, 0xa4, - 0x2e, 0xa3, 0xab, 0x01, 0xf8, 0xd7, 0x96, 0x5d, 0x78, 0x8b, 0x55, 0xba, - 0x24, 0xbd, 0xe4, 0x8b, 0xec, 0x9f, 0x28, 0xfd, 0x2a, 0x8b, 0xdc, 0xcf, - 0x26, 0x4b, 0xcf, 0x23, 0x7d, 0x5c, 0xd0, 0x07, 0xb0, 0x87, 0x53, 0xd1, - 0x81, 0xfc, 0x69, 0x6b, 0xc9, 0xb4, 0x9d, 0x46, 0x5b, 0x1d, 0x42, 0x19, - 0xbc, 0xd6, 0xda, 0x8c, 0x0b, 0x02, 0xc7, 0x91, 0xde, 0xbd, 0x5a, 0x36, - 0x57, 0x45, 0x74, 0x39, 0x56, 0x00, 0x83, 0xed, 0x40, 0x12, 0x51, 0x45, - 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, - 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, - 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, - 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, - 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, - 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, - 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, - 0x14, 0x00, 0x57, 0x3b, 0xe3, 0x8b, 0xcf, 0xb3, 0x68, 0x4d, 0x18, 0x3f, - 0x34, 0xec, 0x13, 0xf0, 0xea, 0x7f, 0x95, 0x74, 0x55, 0xc2, 0x7c, 0x44, - 0xb8, 0xdf, 0x77, 0x6d, 0x00, 0x3c, 0x22, 0x17, 0x23, 0xdc, 0x9c, 0x7f, - 0x4a, 0x00, 0xe4, 0xa8, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x5c, - 0xed, 0x3b, 0x81, 0x23, 0xdc, 0x75, 0xfc, 0xeb, 0x6f, 0x4a, 0xf1, 0x5e, - 0xa1, 0xa7, 0xe1, 0x1d, 0xfe, 0xd1, 0x10, 0xe8, 0x92, 0x76, 0xfa, 0x1e, - 0xb5, 0x86, 0x28, 0xa0, 0x0f, 0x4d, 0xd2, 0x7c, 0x4f, 0x61, 0xa9, 0xe1, - 0x44, 0x9e, 0x4c, 0xa7, 0xfe, 0x59, 0xc8, 0x70, 0x7f, 0x0f, 0x5a, 0xda, - 0x06, 0xbc, 0x64, 0x70, 0x72, 0x38, 0x3e, 0xbf, 0xfd, 0x7f, 0x5a, 0xde, - 0xd1, 0xfc, 0x5b, 0x79, 0x60, 0x56, 0x2b, 0x82, 0x6e, 0x60, 0xe9, 0x86, - 0x3f, 0x3a, 0x8f, 0x63, 0xfe, 0x7f, 0x0a, 0x00, 0xf4, 0x8a, 0x2a, 0x86, - 0x99, 0xaa, 0xda, 0x6a, 0x91, 0x6f, 0xb6, 0x94, 0x37, 0x19, 0x28, 0x78, - 0x65, 0x3f, 0x4a, 0xba, 0x58, 0x28, 0xe4, 0x81, 0xf5, 0xa0, 0x07, 0x51, - 0x54, 0x6e, 0x75, 0x8d, 0x3e, 0xd7, 0x26, 0x6b, 0xb8, 0x57, 0x1d, 0xb7, - 0x64, 0xd6, 0x65, 0xc7, 0x8c, 0xf4, 0xa8, 0x41, 0xd9, 0x24, 0x92, 0x9f, - 0xf6, 0x13, 0xaf, 0xe7, 0x40, 0x1d, 0x0d, 0x15, 0xc6, 0xcb, 0xe3, 0xd8, - 0x97, 0x88, 0x6c, 0x9d, 0x87, 0x6d, 0xee, 0x07, 0xe8, 0x05, 0x53, 0x93, - 0xc7, 0x97, 0xcd, 0xfe, 0xae, 0xda, 0x05, 0xfa, 0x92, 0x4f, 0xf3, 0xa0, - 0x0e, 0xfa, 0x8a, 0xf3, 0x87, 0xf1, 0xae, 0xaa, 0xd9, 0xc3, 0x44, 0xa3, - 0xd0, 0x20, 0xa8, 0xdb, 0xc5, 0xfa, 0xc3, 0x1f, 0xf8, 0xf9, 0x51, 0xf4, - 0x45, 0xa0, 0x0f, 0x4b, 0xa2, 0xbc, 0xc4, 0xf8, 0xb3, 0x58, 0x3f, 0xf2, - 0xf6, 0x7f, 0xef, 0x81, 0xfe, 0x14, 0x0f, 0x16, 0x6b, 0x03, 0xfe, 0x5e, - 0xcf, 0xfd, 0xf0, 0x3f, 0xc2, 0x80, 0x3d, 0x3a, 0x8a, 0xf3, 0x35, 0xf1, - 0x7e, 0xb0, 0xbf, 0xf2, 0xf2, 0x0f, 0xd5, 0x07, 0xf8, 0x54, 0xe9, 0xe3, - 0x6d, 0x55, 0x7e, 0xf3, 0x42, 0xff, 0x00, 0xef, 0x27, 0xf8, 0x50, 0x07, - 0xa2, 0xd1, 0x5c, 0x14, 0x7e, 0x3d, 0xbc, 0x18, 0xf3, 0x2d, 0xa1, 0x71, - 0xdf, 0x04, 0x83, 0x56, 0xed, 0xfc, 0x7f, 0x0f, 0xfc, 0xb6, 0xb3, 0x95, - 0x7d, 0xd1, 0xf7, 0x7f, 0x3a, 0x00, 0xec, 0xa8, 0xac, 0x0b, 0x7f, 0x18, - 0xe9, 0x32, 0xe0, 0x34, 0xaf, 0x11, 0x3d, 0x9d, 0x3f, 0xc2, 0xb4, 0xed, - 0xb5, 0x6b, 0x1b, 0xac, 0x79, 0x37, 0x51, 0x39, 0x3d, 0x83, 0x50, 0x05, - 0xcc, 0xd2, 0x1a, 0xce, 0xd5, 0x75, 0xab, 0x3d, 0x2a, 0x1d, 0xd7, 0x12, - 0xfc, 0xc7, 0xa2, 0x29, 0xcb, 0x1a, 0xe1, 0xb5, 0x8f, 0x15, 0x5e, 0xea, - 0x5b, 0xa3, 0x8d, 0x8c, 0x10, 0x1c, 0xfc, 0x88, 0x70, 0x4f, 0xd4, 0xd0, - 0x07, 0x5b, 0xab, 0xf8, 0xae, 0xc3, 0x4d, 0xdc, 0x88, 0xc6, 0xe2, 0x61, - 0xd5, 0x23, 0x39, 0x03, 0xea, 0x6b, 0x8e, 0xd5, 0x7c, 0x4f, 0xa8, 0x6a, - 0x7f, 0x29, 0x94, 0xc1, 0x11, 0xfe, 0x08, 0xce, 0x3f, 0x33, 0x59, 0x1f, - 0xe7, 0xfc, 0xfa, 0xd2, 0x50, 0x02, 0x9e, 0xb9, 0xff, 0x00, 0xeb, 0xd2, - 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x1d, 0x47, 0xad, 0x7a, 0x67, - 0x84, 0x2f, 0x0d, 0xde, 0x83, 0x0e, 0xe3, 0x96, 0x8b, 0x28, 0xdf, 0x87, - 0x4a, 0xf3, 0x3a, 0xed, 0x7e, 0x1d, 0xdc, 0x66, 0x3b, 0xb8, 0x33, 0xc0, - 0x21, 0xc5, 0x00, 0x76, 0x74, 0x52, 0x52, 0xd0, 0x01, 0x45, 0x14, 0x50, - 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, - 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, - 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, - 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, - 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, - 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, - 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x5e, 0x6d, 0xe3, - 0x89, 0x3c, 0xcf, 0x11, 0xc8, 0xbf, 0xdc, 0x45, 0x5f, 0xd3, 0x3f, 0xd6, - 0xbd, 0x26, 0xbc, 0xbf, 0xc5, 0xc7, 0x3e, 0x26, 0xbc, 0xf6, 0x2b, 0xff, - 0x00, 0xa0, 0x8a, 0x00, 0xc7, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, - 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa3, 0xfa, 0xf5, 0xa2, 0x8a, 0x00, 0x96, - 0xde, 0xe6, 0x6b, 0x59, 0x44, 0xb0, 0x48, 0xd1, 0xc8, 0x3b, 0xa9, 0xc5, - 0x4b, 0x75, 0xaa, 0x5e, 0xdd, 0x93, 0xe7, 0x5c, 0xca, 0xd9, 0xed, 0xbb, - 0x15, 0x56, 0x8a, 0x00, 0x3b, 0xe7, 0xbf, 0xbd, 0x2d, 0x25, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0xb4, 0x98, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, - 0x00, 0x28, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x0b, 0x42, 0xf0, - 0x72, 0x32, 0x3b, 0xe4, 0x1c, 0x52, 0x51, 0x40, 0x0e, 0x67, 0x77, 0x39, - 0x76, 0x66, 0x61, 0xc0, 0x24, 0xe7, 0x02, 0x92, 0x92, 0x8a, 0x00, 0x28, - 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x2b, - 0xa5, 0xf0, 0x0c, 0xa5, 0x35, 0xd9, 0x23, 0xec, 0xf0, 0x91, 0xf9, 0x11, - 0xfe, 0x15, 0xcd, 0x56, 0xf7, 0x81, 0xff, 0x00, 0xe4, 0x64, 0x88, 0x7f, - 0xb0, 0xdf, 0xca, 0x80, 0x3d, 0x24, 0x7a, 0xd2, 0xd2, 0x0a, 0x5a, 0x00, - 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, - 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, - 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, - 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, - 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, - 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, - 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, - 0x2b, 0xcc, 0xbc, 0x67, 0x1e, 0xcf, 0x12, 0xdc, 0x13, 0xfc, 0x61, 0x48, - 0xff, 0x00, 0xbe, 0x45, 0x7a, 0x6d, 0x79, 0xf7, 0xc4, 0x08, 0x3c, 0xbd, - 0x5e, 0x19, 0x40, 0xe2, 0x58, 0x87, 0x3e, 0xe3, 0x20, 0xfe, 0x98, 0xa0, - 0x0e, 0x62, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0xba, 0x1f, 0x02, 0xa6, 0xef, 0x10, - 0x06, 0xfe, 0xe4, 0x4c, 0xc7, 0xf9, 0x7f, 0x5a, 0xe7, 0xba, 0x57, 0x5d, - 0xf0, 0xf2, 0xdf, 0x75, 0xd5, 0xd4, 0xe4, 0x70, 0xa8, 0x10, 0x1f, 0xaf, - 0xff, 0x00, 0xaa, 0x80, 0x3b, 0x91, 0x4b, 0x49, 0x4b, 0x40, 0x05, 0x14, - 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, - 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, - 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, - 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, - 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, - 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, - 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x72, - 0xfe, 0x3d, 0xb3, 0xf3, 0xf4, 0xa4, 0xb8, 0x51, 0xf3, 0x40, 0xfc, 0xfd, - 0x0f, 0x1f, 0xcf, 0x15, 0xd3, 0xd7, 0x17, 0xe3, 0x2f, 0x10, 0x8d, 0xaf, - 0xa6, 0xdb, 0x61, 0x89, 0xe2, 0x67, 0xea, 0x07, 0xb0, 0xa0, 0x0e, 0x32, - 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, - 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, - 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, - 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, - 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, - 0x8a, 0x28, 0xa0, 0x03, 0xb5, 0x77, 0x7e, 0x01, 0x9a, 0xd8, 0x69, 0xf2, - 0xc4, 0x8f, 0xfe, 0x90, 0x5c, 0xb3, 0xa9, 0xf4, 0xed, 0x8a, 0xe1, 0x2a, - 0x6b, 0x4b, 0xb9, 0x6c, 0x6e, 0x12, 0x78, 0x1c, 0xa3, 0xa1, 0xc8, 0x23, - 0xf9, 0x50, 0x07, 0xb0, 0xd2, 0xd6, 0x56, 0x83, 0xac, 0xc7, 0xac, 0x59, - 0x09, 0x57, 0x0b, 0x2a, 0xf1, 0x22, 0x67, 0xa1, 0xff, 0x00, 0x0a, 0xd4, - 0xa0, 0x05, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, - 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, - 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, - 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, - 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, - 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, - 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa4, 0xa5, - 0xaa, 0xf7, 0x57, 0x31, 0xda, 0xdb, 0x49, 0x3c, 0x87, 0x09, 0x1a, 0x96, - 0x26, 0x80, 0x31, 0xbc, 0x5b, 0xae, 0x8d, 0x2a, 0xcf, 0xc9, 0x85, 0x87, - 0xda, 0x66, 0x18, 0x51, 0x9f, 0xba, 0x3d, 0x6b, 0xce, 0x8e, 0x59, 0x8b, - 0x12, 0x49, 0x27, 0x39, 0x35, 0x67, 0x55, 0xbf, 0x93, 0x53, 0xd4, 0x65, - 0xb9, 0x94, 0x93, 0xb8, 0x9d, 0xa3, 0xfb, 0xa3, 0xb0, 0xaa, 0xb4, 0x00, - 0x94, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, - 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, - 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, - 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, - 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, - 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x5f, 0xd1, 0x75, 0x49, - 0x74, 0x9b, 0xf4, 0xb8, 0x8f, 0x25, 0x73, 0x89, 0x13, 0x3f, 0x79, 0x6b, - 0xd4, 0xad, 0x2e, 0x62, 0xbb, 0xb7, 0x8e, 0x78, 0x5b, 0x74, 0x72, 0x0c, - 0xa9, 0xaf, 0x1f, 0xfe, 0x67, 0xa5, 0x75, 0xbe, 0x04, 0xd5, 0xcc, 0x72, - 0xb6, 0x9d, 0x33, 0x1d, 0x8f, 0xf3, 0x43, 0x9e, 0xc7, 0xd2, 0x80, 0x3b, - 0x9a, 0x5a, 0x6d, 0x3a, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, - 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, - 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, - 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, - 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, - 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, - 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x10, 0xf4, 0xae, - 0x3f, 0xc7, 0xda, 0x91, 0x8e, 0x18, 0xec, 0x22, 0x3f, 0x7f, 0xe7, 0x93, - 0x1e, 0x9d, 0x87, 0xf9, 0xf6, 0xae, 0xbc, 0x9e, 0x39, 0xaf, 0x29, 0xd7, - 0x6f, 0x8e, 0xa3, 0xab, 0xdc, 0x4f, 0x9f, 0x94, 0xb1, 0x09, 0xfe, 0xe8, - 0xa0, 0x0a, 0x14, 0x94, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, - 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, - 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, - 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, - 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, - 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, - 0x51, 0x40, 0x05, 0x4b, 0x6d, 0x71, 0x25, 0xad, 0xc4, 0x73, 0xc4, 0x70, - 0xf1, 0x9d, 0xc2, 0xa2, 0xa2, 0x80, 0x3d, 0x77, 0x4f, 0xbb, 0x5b, 0xeb, - 0x38, 0x6e, 0x23, 0xe9, 0x22, 0xe7, 0xe9, 0xea, 0x3f, 0x03, 0x56, 0xeb, - 0x92, 0xf8, 0x7f, 0x7a, 0x65, 0xb0, 0x9a, 0xd1, 0xce, 0x5a, 0x17, 0xdc, - 0xbf, 0x43, 0xff, 0x00, 0xd7, 0xae, 0xb6, 0x80, 0x0a, 0x28, 0xa2, 0x80, - 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, - 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, - 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, - 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, - 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, - 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x4a, 0x5a, 0x4a, - 0x00, 0xcf, 0xd7, 0xae, 0xbe, 0xc7, 0xa3, 0x5d, 0xcc, 0x3a, 0xac, 0x64, - 0x2f, 0xd4, 0xf0, 0x3f, 0x5a, 0xf2, 0x93, 0xc8, 0xe6, 0xbd, 0x0b, 0xc7, - 0x53, 0x18, 0xf4, 0x1f, 0x2c, 0x1c, 0x79, 0x92, 0xa8, 0xc7, 0xb0, 0xc9, - 0xfe, 0x82, 0xbc, 0xf2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, - 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa5, 0xfe, 0x42, 0x80, 0x12, - 0x8a, 0x72, 0xa3, 0x39, 0xc2, 0x2b, 0x31, 0xf4, 0x00, 0xd5, 0x98, 0xf4, - 0xcb, 0xd9, 0x31, 0x8b, 0x77, 0x00, 0xfa, 0x8c, 0x7f, 0x3a, 0x34, 0x1d, - 0x99, 0x52, 0x8a, 0xd2, 0x1a, 0x15, 0xf9, 0xff, 0x00, 0x96, 0x4a, 0x3f, - 0xe0, 0x42, 0x97, 0xfb, 0x06, 0xf7, 0xfb, 0x8b, 0xff, 0x00, 0x7d, 0x0a, - 0x57, 0x41, 0xca, 0xcc, 0xca, 0x2b, 0x48, 0xe8, 0x57, 0xf9, 0xff, 0x00, - 0x54, 0xbf, 0xf7, 0xd0, 0xa6, 0x36, 0x8b, 0x7c, 0xa3, 0x98, 0x33, 0xf4, - 0x61, 0x45, 0xd0, 0x72, 0xb2, 0x85, 0x15, 0x6d, 0xb4, 0xbb, 0xd5, 0xeb, - 0x6f, 0x27, 0xe4, 0x2a, 0x23, 0x67, 0x70, 0xbd, 0x6d, 0xe5, 0xcf, 0xfb, - 0x86, 0x8b, 0xa0, 0xb3, 0x21, 0xa2, 0x9e, 0xd0, 0xc8, 0xa7, 0xe6, 0x8d, - 0xd7, 0xea, 0xa4, 0x52, 0x15, 0x3d, 0xd4, 0xfe, 0x46, 0x8b, 0x85, 0x98, - 0xda, 0x29, 0xdb, 0x4f, 0x70, 0x7f, 0x2a, 0x36, 0x9e, 0xc0, 0xfe, 0x54, - 0xee, 0x16, 0x1b, 0x45, 0x3b, 0x69, 0xf4, 0x3f, 0x95, 0x39, 0x61, 0x9a, - 0x4f, 0xb9, 0x13, 0xb7, 0xfb, 0xaa, 0x4d, 0x2b, 0x85, 0x99, 0x1d, 0x15, - 0x3a, 0xd9, 0x5d, 0x3f, 0x0b, 0x6f, 0x2f, 0xfd, 0xf1, 0x8f, 0xe7, 0x52, - 0x8d, 0x2a, 0xf8, 0xf4, 0xb6, 0x7f, 0xd2, 0x8b, 0xa0, 0xb3, 0x29, 0xd1, - 0x5a, 0x0b, 0xa1, 0xdf, 0x30, 0xcf, 0x93, 0x8f, 0xab, 0x01, 0x4e, 0x1a, - 0x0d, 0xf7, 0x78, 0x97, 0xfe, 0xfa, 0x14, 0x5d, 0x07, 0x2b, 0x33, 0x68, - 0xad, 0x3f, 0xec, 0x0b, 0xdc, 0x7d, 0xd4, 0xff, 0x00, 0xbe, 0x85, 0x27, - 0xf6, 0x15, 0xf8, 0x07, 0xf7, 0x4a, 0x7e, 0x8c, 0x28, 0xba, 0x0e, 0x56, - 0x66, 0xd1, 0x56, 0xa5, 0xd3, 0x6f, 0x22, 0x53, 0xbe, 0xde, 0x4c, 0x7a, - 0x85, 0xc8, 0xfd, 0x2a, 0xb3, 0x29, 0x53, 0x86, 0x52, 0x3d, 0x88, 0x34, - 0xee, 0x2b, 0x31, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, - 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0xe8, 0x7c, 0x0f, 0x73, 0xe4, - 0x6b, 0xeb, 0x19, 0x3c, 0x4c, 0x85, 0x7f, 0xaf, 0xf4, 0xaf, 0x46, 0xcd, - 0x79, 0x36, 0x89, 0x37, 0xd9, 0xf5, 0xcb, 0x39, 0x73, 0x8f, 0xdf, 0x28, - 0x27, 0xd8, 0x9c, 0x1f, 0xd0, 0xd7, 0xac, 0x0a, 0x00, 0x75, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x1c, 0x87, 0xc4, 0x56, 0xff, 0x00, 0x43, 0xb4, 0x5f, 0x59, 0x09, - 0xfd, 0x2b, 0x86, 0xae, 0xdb, 0xe2, 0x2f, 0xfa, 0x8b, 0x3f, 0xf7, 0x9b, - 0xf9, 0x0a, 0xe2, 0x68, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, - 0x00, 0xa5, 0xa4, 0xab, 0x3a, 0x7d, 0x84, 0x97, 0xf3, 0x88, 0xe3, 0xe0, - 0x0f, 0xbc, 0xc7, 0xa2, 0x8f, 0xf3, 0xd2, 0x93, 0xd0, 0x06, 0x5b, 0x5a, - 0xcd, 0x77, 0x27, 0x97, 0x0a, 0x16, 0x35, 0xd0, 0xd8, 0x78, 0x6e, 0x31, - 0x83, 0x36, 0x66, 0x6f, 0xee, 0x8e, 0x17, 0x35, 0xb5, 0xa5, 0xe9, 0x51, - 0x5a, 0xc2, 0xa1, 0x57, 0x0a, 0x7a, 0xf1, 0xcb, 0x7b, 0x9a, 0xd2, 0x00, - 0x2f, 0x0b, 0xc0, 0x1d, 0xab, 0x39, 0x4e, 0xfb, 0x1b, 0x46, 0x09, 0x6e, - 0x67, 0xdb, 0xe9, 0x8b, 0x12, 0xed, 0x45, 0x48, 0xc7, 0xa0, 0x15, 0x38, - 0xb2, 0x5e, 0xee, 0xc6, 0xac, 0xd2, 0x8a, 0x8b, 0x9a, 0x58, 0xaf, 0xf6, - 0x28, 0xbf, 0xda, 0xfc, 0xe9, 0x0d, 0x94, 0x5f, 0xed, 0x7e, 0x75, 0x66, - 0x8a, 0x00, 0xad, 0xf6, 0x28, 0xfd, 0x5a, 0x90, 0xd8, 0xaf, 0x67, 0x35, - 0x6a, 0x8a, 0x00, 0xa6, 0x6c, 0x7d, 0x1f, 0xf4, 0xa6, 0x9b, 0x27, 0xec, - 0xe2, 0xaf, 0x1a, 0x05, 0x00, 0x50, 0x36, 0x52, 0x76, 0xdb, 0x4d, 0xfb, - 0x14, 0x9f, 0xdd, 0x53, 0x5a, 0x26, 0x81, 0x45, 0xc2, 0xc8, 0xcd, 0x36, - 0x2f, 0xde, 0x25, 0xfc, 0x85, 0x02, 0xc5, 0xfb, 0x44, 0xbf, 0x90, 0xad, - 0x2a, 0x4a, 0x2e, 0x16, 0x46, 0x78, 0xb3, 0x93, 0xd1, 0x45, 0x38, 0x59, - 0x49, 0xdc, 0x81, 0x57, 0xa9, 0x68, 0xb8, 0x14, 0x45, 0x93, 0xf7, 0x71, - 0xf9, 0x53, 0x85, 0x88, 0xee, 0xff, 0x00, 0xa5, 0x5c, 0xa2, 0x8b, 0x81, - 0x50, 0x59, 0x27, 0x76, 0x26, 0x9e, 0x2c, 0xa2, 0xef, 0xbb, 0xf3, 0xab, - 0x14, 0x50, 0x05, 0x7f, 0xb1, 0xc3, 0xe8, 0x69, 0x3e, 0xc5, 0x17, 0x6d, - 0xdf, 0x9d, 0x59, 0xa2, 0x80, 0x2a, 0x9b, 0x25, 0xfe, 0x17, 0x35, 0x56, - 0xe7, 0x4a, 0x49, 0x94, 0x89, 0x22, 0x49, 0x41, 0xf5, 0x15, 0xa8, 0x68, - 0x14, 0x5c, 0x2c, 0x71, 0x97, 0xfe, 0x1a, 0xc1, 0x66, 0xb7, 0x62, 0xad, - 0xff, 0x00, 0x3c, 0xdb, 0xfa, 0x1a, 0xc1, 0x96, 0x29, 0x21, 0x90, 0xa4, - 0x8a, 0x55, 0x97, 0xb1, 0xaf, 0x4f, 0x74, 0x57, 0x18, 0x71, 0x9f, 0xc3, - 0xa5, 0x62, 0xeb, 0x3a, 0x2c, 0x77, 0x71, 0x1e, 0x06, 0xe1, 0xf7, 0x5f, - 0xd0, 0xfb, 0xfb, 0x55, 0xa9, 0x99, 0xca, 0x1d, 0x8e, 0x1e, 0x8a, 0x96, - 0xe6, 0xda, 0x5b, 0x59, 0xda, 0x29, 0x57, 0x6b, 0x2f, 0x7f, 0x5f, 0x7a, - 0x8a, 0xb5, 0x31, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x1c, - 0x8e, 0x63, 0x75, 0x71, 0xd5, 0x08, 0x6f, 0xca, 0xbd, 0x8d, 0x79, 0x03, - 0xe9, 0x5e, 0x34, 0x7a, 0x1a, 0xf6, 0x54, 0xfb, 0x8b, 0xf4, 0x14, 0x00, - 0xfa, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, - 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, - 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, - 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, - 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, - 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, - 0x0a, 0x28, 0xa2, 0x80, 0x39, 0x0f, 0x88, 0xa3, 0xfd, 0x0e, 0xd1, 0xbd, - 0x24, 0x61, 0xfa, 0x57, 0x0d, 0x5d, 0xf7, 0xc4, 0x28, 0xf3, 0xa3, 0xc3, - 0x27, 0xf7, 0x66, 0x03, 0xf3, 0x06, 0xb8, 0x1a, 0x00, 0x28, 0xa2, 0x8a, - 0x00, 0x28, 0xa2, 0x96, 0x80, 0x1f, 0x6d, 0x04, 0x97, 0x33, 0xa4, 0x31, - 0x02, 0x59, 0x8e, 0x3f, 0xfd, 0x75, 0xde, 0x68, 0xfa, 0x5c, 0x76, 0x76, - 0xca, 0xa1, 0x78, 0xea, 0x49, 0xee, 0x7d, 0x6b, 0x23, 0xc2, 0x5a, 0x66, - 0x50, 0xdc, 0xc8, 0xbf, 0x78, 0xe1, 0x7e, 0x9f, 0xfe, 0xba, 0xea, 0x80, - 0x00, 0x60, 0x74, 0x15, 0x94, 0xdd, 0xdd, 0x8d, 0xa1, 0x1b, 0x2b, 0xb1, - 0x47, 0x41, 0x9a, 0x28, 0x14, 0x1f, 0x5a, 0x83, 0x40, 0x35, 0x34, 0x56, - 0xc5, 0xf9, 0x63, 0x80, 0x69, 0xd6, 0xd0, 0xe7, 0xe7, 0x61, 0xf4, 0xab, - 0x55, 0x71, 0x8f, 0x73, 0x29, 0x4f, 0xa2, 0x21, 0x5b, 0x58, 0xc0, 0xc6, - 0x09, 0xf7, 0xcd, 0x35, 0xed, 0x06, 0x3e, 0x53, 0x83, 0x4d, 0xb8, 0xbf, - 0xb6, 0xb7, 0x38, 0x96, 0x55, 0x56, 0xf4, 0xce, 0x4d, 0x16, 0xda, 0x85, - 0xb5, 0xc9, 0xc4, 0x33, 0x23, 0x1f, 0x4c, 0xf3, 0x57, 0x64, 0x4d, 0xe5, - 0xb9, 0x5d, 0xd1, 0x91, 0x88, 0x65, 0xc1, 0xa0, 0x55, 0xe9, 0x62, 0x12, - 0x29, 0x07, 0xaf, 0x63, 0x54, 0x4a, 0xec, 0x62, 0xa7, 0xa8, 0xac, 0xe5, - 0x1b, 0x1a, 0x42, 0x57, 0x0a, 0x28, 0xa2, 0xa4, 0xb0, 0xa2, 0x8a, 0x28, - 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, - 0x00, 0xa3, 0xbf, 0x4c, 0xd1, 0x56, 0x2d, 0x61, 0xe3, 0x7b, 0x7a, 0xf0, - 0x29, 0xa5, 0x76, 0x26, 0xec, 0xae, 0x24, 0x56, 0xc5, 0x80, 0x2e, 0x70, - 0x2a, 0x51, 0x6b, 0x1f, 0x7c, 0x9f, 0xc6, 0x96, 0x69, 0xe2, 0x81, 0x37, - 0x4d, 0x22, 0xa2, 0xfb, 0x9a, 0xae, 0x9a, 0xbd, 0x93, 0xb6, 0xd1, 0x3a, - 0x03, 0xef, 0xc5, 0x6a, 0x92, 0x46, 0x37, 0x93, 0x25, 0x7b, 0x51, 0x82, - 0x50, 0xe3, 0xda, 0xab, 0x32, 0x94, 0x38, 0x61, 0x83, 0x5a, 0x0a, 0xc1, - 0x97, 0x20, 0x82, 0x3d, 0x45, 0x32, 0x68, 0x84, 0x8a, 0x78, 0xe7, 0xb5, - 0x4c, 0xa3, 0xd8, 0x71, 0x9b, 0x5b, 0x94, 0x68, 0x23, 0x23, 0x04, 0x64, - 0x1e, 0xa2, 0x82, 0x36, 0x9c, 0x1e, 0xbd, 0xe8, 0x15, 0x99, 0xb1, 0x83, - 0xe2, 0x0d, 0x1d, 0x6e, 0xa0, 0x2d, 0x18, 0x02, 0x41, 0xca, 0x9e, 0xdf, - 0x43, 0xed, 0x5c, 0x5b, 0x29, 0x46, 0x2a, 0xc0, 0x82, 0x0e, 0x08, 0x3d, - 0x73, 0x5e, 0xa2, 0xc0, 0x30, 0x21, 0x80, 0xc1, 0x15, 0xc4, 0xf8, 0xab, - 0x4e, 0x36, 0xf7, 0x2b, 0x70, 0x06, 0x12, 0x43, 0xb5, 0xf1, 0xd8, 0xff, - 0x00, 0xf5, 0xc5, 0x69, 0x09, 0x74, 0x33, 0x9c, 0x7a, 0x98, 0x54, 0x52, - 0xd2, 0x56, 0x86, 0x21, 0x45, 0x14, 0x50, 0x02, 0x80, 0x4f, 0x4a, 0xf6, - 0x44, 0xfb, 0xa3, 0xe8, 0x2b, 0xc7, 0xad, 0x97, 0xcc, 0xba, 0x86, 0x3f, - 0xef, 0x48, 0xab, 0xf9, 0x90, 0x2b, 0xd8, 0x87, 0x41, 0xf4, 0xa0, 0x07, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x52, 0x52, 0xd2, 0x1e, 0x94, 0x01, 0x83, 0xe3, 0x68, 0x7c, 0xdf, 0x0e, - 0x4c, 0x47, 0x58, 0xd9, 0x5b, 0xf5, 0xc7, 0xf5, 0xaf, 0x36, 0xaf, 0x58, - 0xd6, 0xa0, 0xfb, 0x4e, 0x8d, 0x77, 0x0f, 0x76, 0x89, 0xb1, 0xf5, 0xc6, - 0x6b, 0xca, 0x39, 0xe9, 0xde, 0x80, 0x12, 0x8a, 0x28, 0xa0, 0x02, 0xa4, - 0x82, 0x36, 0x9a, 0x74, 0x88, 0x73, 0xbd, 0x82, 0xfe, 0x75, 0x1d, 0x68, - 0xf8, 0x7a, 0x21, 0x2e, 0xb5, 0x6c, 0xac, 0x38, 0xde, 0x49, 0xfc, 0x29, - 0x31, 0xad, 0xce, 0xee, 0xc6, 0x01, 0x6d, 0x6b, 0x1c, 0x4a, 0x31, 0x80, - 0x3f, 0x95, 0x58, 0xa6, 0x8e, 0x82, 0x9d, 0x58, 0x1d, 0x21, 0x42, 0x29, - 0x77, 0x0b, 0xdc, 0x9a, 0x2a, 0x6b, 0x41, 0x99, 0xb3, 0xe8, 0x29, 0xad, - 0x58, 0xa4, 0xec, 0x8b, 0x6a, 0x02, 0xae, 0x07, 0x6a, 0xca, 0xd6, 0x2f, - 0xe5, 0x8d, 0x96, 0xda, 0xd0, 0x33, 0x4e, 0xe3, 0x27, 0x03, 0x3b, 0x47, - 0xad, 0x6a, 0xbb, 0x05, 0x52, 0x7d, 0x2b, 0x9d, 0xd2, 0x35, 0x08, 0x9b, - 0x53, 0xb8, 0x79, 0x9c, 0x29, 0x94, 0xfc, 0x84, 0xfa, 0x64, 0xf1, 0x5a, - 0xbe, 0xc6, 0x30, 0x4d, 0xea, 0x64, 0x5d, 0x5b, 0x4f, 0x6e, 0xe0, 0xdc, - 0x23, 0xa1, 0x63, 0xd4, 0x8c, 0xfe, 0xb5, 0x0a, 0xb1, 0x53, 0xb8, 0x1c, - 0x30, 0x3d, 0x73, 0x5d, 0x27, 0x89, 0x2e, 0xa0, 0x6b, 0x2f, 0x29, 0x4a, - 0xbc, 0x85, 0x81, 0x18, 0xed, 0xef, 0x5c, 0xdf, 0x7f, 0xaf, 0x35, 0x93, - 0x56, 0x67, 0x5d, 0x37, 0xcc, 0xb5, 0x47, 0x4f, 0xa0, 0xea, 0x86, 0xe5, - 0x7c, 0x89, 0x8e, 0x65, 0x5e, 0x41, 0xf5, 0x15, 0x7a, 0xf1, 0x0e, 0xe0, - 0xeb, 0x5c, 0x85, 0xa4, 0xe6, 0xda, 0xea, 0x29, 0x54, 0xe3, 0x6b, 0x0c, - 0xfb, 0x8e, 0xf5, 0xda, 0x4d, 0x89, 0x2d, 0xf7, 0x0e, 0xe3, 0x22, 0xae, - 0xf7, 0x46, 0x13, 0x8f, 0x2c, 0xae, 0x8a, 0x60, 0xf1, 0x45, 0x02, 0x8a, - 0xcc, 0xb0, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, - 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x01, 0x63, 0x4f, 0x31, 0xd5, 0x7d, 0x4d, - 0x58, 0xbd, 0xbb, 0x8e, 0xc2, 0xd1, 0xa5, 0x7e, 0x8b, 0xc0, 0x1e, 0xb4, - 0xcb, 0x35, 0xcc, 0xa4, 0xfa, 0x56, 0x2f, 0x89, 0xee, 0x0b, 0xdc, 0xa5, - 0xb8, 0x3f, 0x2a, 0x8c, 0x91, 0xea, 0x4d, 0x5c, 0x74, 0x57, 0x33, 0x6b, - 0x9a, 0x56, 0x28, 0x4c, 0xd7, 0x7a, 0x8b, 0xbc, 0xed, 0x1b, 0xc8, 0x07, - 0x65, 0x07, 0x02, 0xaa, 0x63, 0x07, 0x07, 0x8c, 0x57, 0x53, 0xa4, 0x6a, - 0x16, 0x8b, 0x61, 0x1a, 0x19, 0x12, 0x36, 0x51, 0x86, 0x0c, 0x79, 0xae, - 0x7b, 0x50, 0x96, 0x39, 0xef, 0xe5, 0x92, 0x21, 0x84, 0x27, 0x8a, 0x4d, - 0x1b, 0x41, 0xbb, 0xf2, 0xd8, 0xb7, 0xa3, 0xea, 0xaf, 0x6b, 0x38, 0x8e, - 0x56, 0x2d, 0x0b, 0x1c, 0x7d, 0x3f, 0xfa, 0xd5, 0xd6, 0x2b, 0x06, 0x50, - 0x41, 0xc8, 0x3c, 0x83, 0x5c, 0x06, 0x3f, 0x3a, 0xeb, 0xb4, 0x1b, 0x93, - 0x71, 0xa6, 0xa1, 0x6e, 0x59, 0x3e, 0x53, 0xf8, 0x55, 0x45, 0xf4, 0x66, - 0x75, 0xa0, 0x96, 0xa8, 0x9e, 0xf1, 0x30, 0xe1, 0x87, 0x43, 0x50, 0x0a, - 0xbb, 0x76, 0xbb, 0xa1, 0x3e, 0xd5, 0x4a, 0xa6, 0x4a, 0xcc, 0x50, 0x77, - 0x40, 0x79, 0xac, 0xdd, 0x7e, 0xcc, 0x5d, 0xe9, 0x93, 0x0c, 0x65, 0x95, - 0x77, 0x0f, 0xa8, 0xad, 0x23, 0x4d, 0x74, 0x0e, 0x85, 0x58, 0x64, 0x10, - 0x45, 0x4a, 0xdc, 0xb7, 0xb1, 0xe5, 0xd8, 0x23, 0x83, 0xd4, 0x75, 0xa4, - 0xa9, 0x2e, 0x57, 0x65, 0xcc, 0xab, 0xfd, 0xd7, 0x22, 0xa3, 0xae, 0x83, - 0x94, 0x29, 0x69, 0x29, 0x7d, 0x28, 0x02, 0xe6, 0x8b, 0x1f, 0x9b, 0xad, - 0xd9, 0x20, 0x1c, 0x79, 0xe8, 0x4f, 0xd3, 0x22, 0xbd, 0x64, 0x57, 0x98, - 0xf8, 0x42, 0x2f, 0x37, 0xc4, 0x76, 0xb9, 0x1f, 0x74, 0x96, 0xfc, 0x94, - 0x8f, 0xeb, 0x5e, 0x9c, 0x28, 0x01, 0xd4, 0x51, 0x45, 0x00, 0x14, 0x51, - 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, - 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, - 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, - 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x49, 0x40, 0x0b, 0x45, - 0x25, 0x14, 0x00, 0xb4, 0x52, 0x66, 0x8a, 0x00, 0x5a, 0x29, 0x28, 0xa0, - 0x05, 0xa2, 0x92, 0x90, 0xba, 0x8e, 0xac, 0x07, 0xe3, 0x40, 0x0b, 0x45, - 0x37, 0xcc, 0x4f, 0xef, 0x2f, 0xe7, 0x49, 0xe7, 0x46, 0x3a, 0xc8, 0x83, - 0xfe, 0x04, 0x28, 0x02, 0x4a, 0x2a, 0x2f, 0x3e, 0x2f, 0xf9, 0xea, 0x9f, - 0xf7, 0xd0, 0xa3, 0xcf, 0x8b, 0xfe, 0x7a, 0xa7, 0xfd, 0xf4, 0x28, 0x01, - 0xec, 0xa1, 0x94, 0x82, 0x32, 0x08, 0xc1, 0xaf, 0x23, 0xd5, 0x2d, 0x8d, - 0x9e, 0xa5, 0x71, 0x01, 0xff, 0x00, 0x96, 0x72, 0x10, 0x3e, 0x99, 0xe2, - 0xbd, 0x68, 0x4b, 0x19, 0xe8, 0xeb, 0xf9, 0xd7, 0x01, 0xe3, 0xcb, 0x41, - 0x16, 0xaa, 0x97, 0x0b, 0x8d, 0xb3, 0xa7, 0x38, 0x3d, 0xc5, 0x00, 0x73, - 0x54, 0x52, 0xd2, 0x50, 0x01, 0x5a, 0xbe, 0x17, 0x3f, 0xf1, 0x3c, 0xb7, - 0xcf, 0xfb, 0x5f, 0xc8, 0xd6, 0x55, 0x68, 0x68, 0x12, 0x79, 0x7a, 0xd5, - 0xa9, 0x3d, 0xdf, 0x1f, 0x9e, 0x45, 0x27, 0xb0, 0xd6, 0xe7, 0xa2, 0x63, - 0x8a, 0x28, 0xcd, 0x15, 0x81, 0xd2, 0x15, 0x3d, 0x97, 0xdf, 0x6f, 0xa5, - 0x40, 0x6a, 0x6b, 0x46, 0xc4, 0xa4, 0x7a, 0x8a, 0x71, 0xdc, 0x99, 0xec, - 0x4d, 0x76, 0x71, 0x69, 0x29, 0x1d, 0x42, 0x13, 0xfa, 0x57, 0x08, 0x3b, - 0x1f, 0xc6, 0xbb, 0xe9, 0x57, 0x7c, 0x4c, 0x9f, 0xde, 0x04, 0x57, 0x0b, - 0x22, 0x18, 0xe4, 0x68, 0xc8, 0xe5, 0x49, 0x1f, 0x95, 0x5c, 0xc7, 0x43, - 0xa8, 0xca, 0x29, 0x68, 0xa8, 0x3a, 0x44, 0x27, 0x1c, 0xd7, 0x6d, 0x6c, - 0xd9, 0xd3, 0x63, 0x27, 0xa9, 0x41, 0x5c, 0x5a, 0x23, 0x49, 0x22, 0xa2, - 0xff, 0x00, 0x19, 0xc5, 0x76, 0xe5, 0x04, 0x56, 0x41, 0x07, 0x45, 0x50, - 0x2a, 0xa2, 0x73, 0x57, 0xdd, 0x15, 0x05, 0x14, 0x0a, 0x2a, 0x06, 0x14, - 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, - 0x51, 0x45, 0x00, 0x58, 0xb2, 0xea, 0xf5, 0xcc, 0x6b, 0xc4, 0x9d, 0x5a, - 0x6c, 0xfb, 0x63, 0xf2, 0xae, 0x9a, 0xcd, 0xb1, 0x21, 0x1e, 0xb5, 0xcf, - 0x78, 0x8e, 0x23, 0x1e, 0xa6, 0x5f, 0x1c, 0x48, 0xb9, 0xfd, 0x2a, 0xfe, - 0xc9, 0x30, 0xd2, 0x66, 0x5d, 0x2f, 0xf5, 0xa4, 0x1d, 0x29, 0x6a, 0x0e, - 0xa0, 0xae, 0x8f, 0xc2, 0xcd, 0xfe, 0x8f, 0x30, 0xec, 0x18, 0x57, 0x36, - 0x6b, 0xa9, 0xf0, 0xcc, 0x3b, 0x34, 0xf6, 0x90, 0x8c, 0x19, 0x1b, 0x35, - 0x70, 0xdc, 0xc2, 0xb3, 0xf7, 0x4d, 0x49, 0xff, 0x00, 0xd4, 0xb7, 0xd2, - 0xa8, 0x0e, 0x82, 0xae, 0xdc, 0xb6, 0xd8, 0x5a, 0xa9, 0x0a, 0x27, 0xb9, - 0x95, 0x3d, 0x82, 0x94, 0x75, 0x14, 0x94, 0x13, 0x80, 0x4f, 0xa5, 0x42, - 0x34, 0x3c, 0xca, 0xff, 0x00, 0x9b, 0xfb, 0x83, 0xff, 0x00, 0x4d, 0x1b, - 0xf9, 0xd4, 0x15, 0x25, 0xc3, 0x17, 0xb8, 0x91, 0xbf, 0xbc, 0xc4, 0xfe, - 0xb5, 0x1d, 0x74, 0x2d, 0x8e, 0x67, 0xb8, 0x52, 0xf3, 0x8e, 0x3a, 0xd2, - 0x51, 0xf4, 0xa0, 0x47, 0x4f, 0xf0, 0xfe, 0x0f, 0x33, 0x58, 0x9a, 0x6c, - 0x7c, 0xb1, 0x45, 0x81, 0xf8, 0x9f, 0xfe, 0xb1, 0xaf, 0x40, 0xae, 0x4f, - 0xc0, 0x16, 0xe2, 0x2d, 0x3e, 0xe2, 0xe5, 0x88, 0x1e, 0x74, 0x81, 0x57, - 0x27, 0xb0, 0xff, 0x00, 0xf5, 0xd7, 0x52, 0x65, 0x8c, 0x75, 0x91, 0x47, - 0xfc, 0x08, 0x50, 0x04, 0x94, 0x54, 0x5e, 0x7c, 0x5f, 0xf3, 0xd5, 0x3f, - 0xef, 0xa1, 0x47, 0x9f, 0x17, 0xfc, 0xf5, 0x4f, 0xfb, 0xe8, 0x50, 0x04, - 0xb4, 0x54, 0x42, 0x68, 0x8f, 0x49, 0x13, 0xfe, 0xfa, 0x14, 0xef, 0x31, - 0x3f, 0xbc, 0xbf, 0x9d, 0x00, 0x3e, 0x8a, 0x68, 0x75, 0x3d, 0x18, 0x1f, - 0xc6, 0x96, 0x80, 0x16, 0x8a, 0x4a, 0x28, 0x01, 0x68, 0xa4, 0xa2, 0x80, - 0x16, 0x8a, 0x4a, 0x28, 0x01, 0x68, 0xa4, 0xa2, 0x80, 0x16, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x04, 0xcd, 0x55, 0xb8, 0xd4, 0x2d, 0x2d, - 0x4f, 0xef, 0xae, 0x62, 0x88, 0xfa, 0x33, 0x81, 0x56, 0x4d, 0x67, 0x7f, - 0x61, 0xe9, 0xcd, 0x33, 0xcc, 0xd6, 0x91, 0x3c, 0x92, 0x31, 0x66, 0x67, - 0x19, 0xc9, 0x3e, 0xc6, 0x80, 0x20, 0x7f, 0x14, 0xe9, 0x6a, 0xdb, 0x52, - 0x66, 0x95, 0xbd, 0x23, 0x42, 0xd4, 0x87, 0x5f, 0x96, 0x4f, 0xf8, 0xf7, - 0xd2, 0xef, 0x24, 0xf7, 0x64, 0xdb, 0xfc, 0xeb, 0x56, 0x28, 0x22, 0x88, - 0x62, 0x38, 0x96, 0x31, 0xe8, 0x14, 0x0a, 0x93, 0x14, 0x01, 0x89, 0xf6, - 0xfd, 0x72, 0x4f, 0xf5, 0x7a, 0x64, 0x51, 0xe7, 0xa1, 0x92, 0x51, 0xfd, - 0x29, 0x42, 0xf8, 0x86, 0x51, 0xcb, 0xda, 0x43, 0x9f, 0x40, 0x4e, 0x2b, - 0x6e, 0x8c, 0xf7, 0xa0, 0x0c, 0x51, 0xa7, 0xeb, 0x2f, 0xfe, 0xb3, 0x54, - 0x44, 0xff, 0x00, 0x72, 0x21, 0x41, 0xd0, 0xef, 0x24, 0x1f, 0xbe, 0xd6, - 0x2e, 0x4f, 0xfb, 0x80, 0x2d, 0x6d, 0x64, 0x51, 0x9a, 0x00, 0xc3, 0x1e, - 0x19, 0x53, 0xf7, 0xf5, 0x1b, 0xe7, 0xfa, 0xcb, 0x47, 0xfc, 0x22, 0x96, - 0x47, 0xef, 0xcd, 0x74, 0xff, 0x00, 0x59, 0x4d, 0x6e, 0x12, 0x3b, 0xd4, - 0x32, 0x5d, 0x43, 0x17, 0xfa, 0xc9, 0xa3, 0x4f, 0xf7, 0x9c, 0x0a, 0x00, - 0xca, 0x1e, 0x13, 0xd3, 0x57, 0xa8, 0x98, 0xfd, 0x65, 0x34, 0xa3, 0xc2, - 0x9a, 0x5f, 0x78, 0x5c, 0xfd, 0x64, 0x35, 0x6a, 0x4d, 0x73, 0x4c, 0x87, - 0xef, 0xdf, 0xc1, 0xf8, 0x38, 0x3f, 0xca, 0xab, 0xb7, 0x8a, 0x74, 0xa1, - 0x90, 0xb7, 0x0c, 0xe7, 0xd1, 0x23, 0x63, 0xfd, 0x28, 0x01, 0x3f, 0xe1, - 0x14, 0xd2, 0xbf, 0xe7, 0x83, 0x7f, 0xdf, 0x66, 0x93, 0xfe, 0x11, 0x5d, - 0x2b, 0xfe, 0x78, 0xb7, 0xfd, 0xfc, 0x34, 0x7f, 0xc2, 0x51, 0x6a, 0xdf, - 0xea, 0xad, 0xaf, 0x25, 0xff, 0x00, 0x72, 0x03, 0x47, 0xfc, 0x24, 0x13, - 0x3f, 0xfa, 0xad, 0x1f, 0x51, 0x6f, 0x76, 0x8c, 0x2f, 0xf5, 0xa0, 0x00, - 0xf8, 0x4f, 0x4b, 0xff, 0x00, 0x9e, 0x52, 0x0f, 0xa4, 0x86, 0xb3, 0x35, - 0xbf, 0x0a, 0xda, 0x2e, 0x97, 0x34, 0x96, 0xbe, 0x67, 0x9d, 0x1a, 0x97, - 0x5c, 0xb9, 0x6f, 0xaf, 0xe7, 0x5a, 0x27, 0x58, 0xd5, 0x1c, 0x7e, 0xef, - 0x42, 0x9c, 0xff, 0x00, 0xbf, 0x3a, 0xad, 0x0f, 0xa8, 0xeb, 0x4e, 0x08, - 0x1a, 0x22, 0x80, 0x78, 0x3b, 0xee, 0x41, 0xfe, 0x42, 0x80, 0x3c, 0xd0, - 0x13, 0xde, 0x8a, 0xd0, 0xd6, 0xf4, 0xfb, 0x8d, 0x3e, 0xf4, 0xfd, 0xa2, - 0x01, 0x08, 0x94, 0x97, 0x45, 0x0c, 0x0a, 0xe3, 0xd3, 0x35, 0x9f, 0x40, - 0x05, 0x49, 0x6f, 0x2f, 0x93, 0x71, 0x1c, 0xa0, 0xe3, 0xcb, 0x65, 0x61, - 0xf8, 0x1a, 0x8e, 0x8e, 0x7b, 0x50, 0x07, 0xa8, 0xc4, 0xe2, 0x58, 0x92, - 0x45, 0xe4, 0x30, 0xc8, 0x3e, 0xd4, 0xfa, 0xc7, 0xf0, 0xb5, 0xea, 0xdd, - 0xe8, 0xf1, 0xa9, 0x39, 0x92, 0x1f, 0xdd, 0x91, 0xec, 0x39, 0x1f, 0xa5, - 0x6c, 0x56, 0x0f, 0x46, 0x74, 0xa7, 0x74, 0x14, 0xb1, 0x39, 0x59, 0x54, - 0xf6, 0xce, 0x29, 0x33, 0x41, 0xa4, 0x86, 0xf5, 0x34, 0x73, 0x9f, 0xce, - 0xb9, 0x8f, 0x10, 0xd8, 0x34, 0x37, 0x06, 0xe1, 0x01, 0xd9, 0x27, 0xde, - 0xc7, 0xf0, 0x9c, 0xf5, 0xae, 0x86, 0xda, 0x6d, 0xcb, 0xb5, 0xbe, 0xf0, - 0xa9, 0x24, 0x8d, 0x25, 0x42, 0x92, 0x00, 0xca, 0xc3, 0x04, 0x1a, 0xd9, - 0xda, 0x48, 0xc2, 0x32, 0x70, 0x91, 0xc1, 0x76, 0xcd, 0x2d, 0x74, 0x37, - 0x3e, 0x1a, 0x46, 0x25, 0xad, 0xe6, 0xd8, 0x3f, 0xba, 0x57, 0x22, 0x8b, - 0x6f, 0x0c, 0xa2, 0xb6, 0xeb, 0x89, 0xb7, 0x8f, 0xee, 0xa8, 0xda, 0x2b, - 0x3e, 0x56, 0x74, 0xfb, 0x68, 0xd8, 0xab, 0xe1, 0xdd, 0x3d, 0xa6, 0xb9, - 0x17, 0x2e, 0xb8, 0x8d, 0x3e, 0xee, 0x7b, 0x9a, 0xe8, 0x2f, 0x1f, 0xe5, - 0x0a, 0x3b, 0xd3, 0xd1, 0x12, 0xde, 0x10, 0xa8, 0x02, 0xa2, 0x8c, 0x00, - 0x06, 0x2a, 0x9b, 0xb9, 0x91, 0xcb, 0x1f, 0xc2, 0xa9, 0xfb, 0xaa, 0xc6, - 0x29, 0xb9, 0xca, 0xe2, 0x01, 0x45, 0x14, 0x56, 0x46, 0x81, 0x45, 0x14, - 0x66, 0x98, 0x06, 0x68, 0xa8, 0x6e, 0x2e, 0xa1, 0xb7, 0xff, 0x00, 0x5a, - 0xe0, 0x1f, 0x4e, 0xf4, 0x41, 0x75, 0x0d, 0xc0, 0xcc, 0x4e, 0x1c, 0xf7, - 0x1e, 0x94, 0x0e, 0xc4, 0xd4, 0x51, 0x45, 0x02, 0x0a, 0x28, 0xa2, 0x80, - 0x1d, 0x0b, 0x14, 0x94, 0x37, 0xbe, 0x29, 0x9a, 0xed, 0x81, 0xbd, 0xb3, - 0xdd, 0x18, 0xfd, 0xe4, 0x7c, 0xaf, 0xbd, 0x2e, 0x3d, 0x2a, 0xe5, 0xb4, - 0xbb, 0xd3, 0x69, 0xea, 0x2a, 0xe3, 0xd8, 0xce, 0x57, 0x4f, 0x99, 0x1c, - 0x29, 0xc8, 0x24, 0x1e, 0x08, 0xeb, 0xed, 0x45, 0x75, 0x9a, 0x86, 0x87, - 0x0d, 0xdb, 0x79, 0x8a, 0xc6, 0x29, 0x0f, 0x52, 0x06, 0x41, 0xfc, 0x2a, - 0x82, 0x78, 0x62, 0x4d, 0xd8, 0x92, 0xe1, 0x76, 0xe7, 0xf8, 0x57, 0x9a, - 0x1c, 0x59, 0xb4, 0x6b, 0x45, 0xad, 0x4c, 0x9b, 0x3b, 0x59, 0x2f, 0x2e, - 0x56, 0x28, 0xc6, 0x77, 0x1e, 0x4f, 0xf7, 0x45, 0x76, 0xb6, 0xf1, 0x2d, - 0xbc, 0x0b, 0x12, 0x8f, 0x95, 0x06, 0x05, 0x43, 0x63, 0xa7, 0xc3, 0x63, - 0x1e, 0xd8, 0x97, 0x9e, 0xec, 0x7a, 0x9a, 0xb0, 0xee, 0x11, 0x37, 0x31, - 0xc0, 0x15, 0x51, 0x56, 0x30, 0xa9, 0x3e, 0x76, 0x41, 0x78, 0xfc, 0x84, - 0x1f, 0x5a, 0xad, 0x43, 0xb9, 0x77, 0x2c, 0x7b, 0xd2, 0x0e, 0x95, 0x9b, - 0x77, 0x65, 0xc5, 0x59, 0x0b, 0x55, 0xf5, 0x09, 0xbc, 0x8b, 0x09, 0xa5, - 0xce, 0x36, 0xa1, 0x3f, 0xa1, 0xab, 0x15, 0x87, 0xe2, 0xfb, 0xbf, 0xb3, - 0xe9, 0x0d, 0x10, 0x3f, 0x3c, 0xec, 0x17, 0x1e, 0xc3, 0xad, 0x09, 0x5d, - 0x8d, 0xe8, 0x8e, 0x20, 0x9c, 0x9f, 0x6c, 0xd2, 0x52, 0x9a, 0x4a, 0xdc, - 0xe6, 0x0a, 0x50, 0x0b, 0x10, 0x17, 0x96, 0x3d, 0x07, 0xad, 0x25, 0x69, - 0x78, 0x7e, 0xca, 0xe6, 0xef, 0x52, 0x49, 0x2d, 0x6d, 0xc4, 0xed, 0x01, - 0x0e, 0xca, 0xed, 0x81, 0x40, 0x1d, 0x8d, 0x87, 0x84, 0x6c, 0x92, 0xce, - 0x21, 0x37, 0x9d, 0xe6, 0x6c, 0xcb, 0xe2, 0x42, 0x06, 0x7e, 0x95, 0x68, - 0x78, 0x4f, 0x4b, 0xef, 0x1c, 0xa7, 0xeb, 0x21, 0xa6, 0xff, 0x00, 0x68, - 0xeb, 0x83, 0xef, 0x68, 0xe8, 0x7f, 0xdd, 0xb9, 0x14, 0xa7, 0x57, 0xd5, - 0x97, 0xef, 0xe8, 0x32, 0xff, 0x00, 0xc0, 0x2e, 0x15, 0xbf, 0xa5, 0x00, - 0x3b, 0xfe, 0x11, 0x4d, 0x2b, 0xfe, 0x78, 0x31, 0xff, 0x00, 0xb6, 0x86, - 0x8f, 0xf8, 0x45, 0x34, 0xaf, 0xf9, 0xe0, 0xdf, 0xf7, 0xd9, 0xa6, 0x8d, - 0x7a, 0xe5, 0x07, 0xef, 0x34, 0x4d, 0x40, 0x1f, 0xf6, 0x14, 0x37, 0xf5, - 0xa3, 0xfe, 0x12, 0x48, 0x54, 0x7e, 0xfa, 0xca, 0xfe, 0x2f, 0xf7, 0xa0, - 0x3c, 0x7e, 0x54, 0x00, 0xa7, 0xc2, 0x9a, 0x5f, 0xfc, 0xf1, 0x7f, 0xc2, - 0x43, 0x41, 0xf0, 0x9e, 0x98, 0x7a, 0x24, 0xa3, 0xe9, 0x29, 0xa5, 0x5f, - 0x14, 0xe9, 0x7f, 0xc7, 0x2c, 0x91, 0xff, 0x00, 0xbd, 0x13, 0x0f, 0xe9, - 0x53, 0xc5, 0xaf, 0xe9, 0x52, 0x0f, 0x96, 0xfe, 0x1f, 0xf8, 0x13, 0x63, - 0xf9, 0xd0, 0x05, 0x5f, 0xf8, 0x44, 0xec, 0x47, 0xdd, 0x96, 0xe5, 0x7e, - 0x92, 0x9a, 0x3f, 0xe1, 0x17, 0x8d, 0x7f, 0xd5, 0xdf, 0xde, 0xa7, 0xd2, - 0x5a, 0xd4, 0x8e, 0xf6, 0xde, 0x61, 0x98, 0xe7, 0x89, 0xff, 0x00, 0xdd, - 0x70, 0x6a, 0x70, 0xc0, 0xf4, 0x34, 0x01, 0x8a, 0x34, 0x0b, 0x88, 0xff, - 0x00, 0xd4, 0xea, 0xf7, 0x8b, 0xfe, 0xf1, 0x0d, 0x4b, 0xfd, 0x99, 0xac, - 0x20, 0xf9, 0x35, 0x7d, 0xc7, 0xfd, 0xb8, 0x85, 0x6d, 0x51, 0x91, 0x40, - 0x18, 0x9e, 0x57, 0x88, 0x22, 0xfb, 0xb7, 0x16, 0x92, 0x8e, 0xd9, 0x52, - 0x29, 0x05, 0xde, 0xbf, 0x11, 0x1e, 0x65, 0x84, 0x12, 0x8f, 0x54, 0x93, - 0x15, 0xb9, 0x46, 0x05, 0x00, 0x62, 0x7f, 0x6e, 0xdd, 0xc7, 0xff, 0x00, - 0x1f, 0x1a, 0x45, 0xca, 0x8f, 0x54, 0xc3, 0x52, 0x8f, 0x14, 0xe9, 0xca, - 0x76, 0xcc, 0xd2, 0xdb, 0xb7, 0xf7, 0x65, 0x88, 0xad, 0x6d, 0x53, 0x1e, - 0x34, 0x71, 0x86, 0x50, 0x41, 0xec, 0x45, 0x00, 0x55, 0xb7, 0xd6, 0x2c, - 0x2e, 0x3f, 0xd4, 0xde, 0x42, 0xc7, 0xd3, 0x78, 0x15, 0x70, 0x10, 0x7d, - 0xea, 0x84, 0xda, 0x16, 0x9b, 0x71, 0xcc, 0x96, 0x71, 0x67, 0xd5, 0x57, - 0x15, 0x79, 0x10, 0x46, 0x81, 0x54, 0x60, 0x01, 0x80, 0x28, 0x01, 0xf4, - 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, - 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x25, 0x19, 0xe2, 0x96, 0xb2, - 0xaf, 0x64, 0xd5, 0x9a, 0xe5, 0xa3, 0xb3, 0x8a, 0xd9, 0x22, 0x03, 0xfd, - 0x6c, 0xac, 0x49, 0x3f, 0x80, 0xa0, 0x0d, 0x4a, 0x82, 0x7b, 0xcb, 0x7b, - 0x75, 0xcc, 0xd3, 0xc7, 0x18, 0xff, 0x00, 0x69, 0x80, 0xac, 0x93, 0xa2, - 0x5f, 0x5d, 0x73, 0x7d, 0xaa, 0xcc, 0x41, 0x3c, 0xa4, 0x00, 0x20, 0xa9, - 0xad, 0xfc, 0x35, 0xa6, 0x42, 0x77, 0x1b, 0x7f, 0x35, 0x87, 0xf1, 0x4a, - 0xc5, 0xcf, 0xeb, 0x40, 0x09, 0x27, 0x89, 0xb4, 0xd5, 0x6d, 0xb1, 0xc9, - 0x24, 0xed, 0xe9, 0x12, 0x16, 0xa6, 0x8d, 0x6a, 0xf2, 0x60, 0x4d, 0xae, - 0x95, 0x70, 0xe0, 0xf4, 0x32, 0x10, 0x82, 0xb5, 0x62, 0xb7, 0x8a, 0x11, - 0x88, 0xe3, 0x44, 0x1f, 0xec, 0xae, 0x2a, 0x5c, 0x7a, 0xd0, 0x06, 0x11, - 0x6f, 0x11, 0x5c, 0x7d, 0xd8, 0xed, 0x2d, 0x81, 0xfe, 0xf1, 0x2e, 0x45, - 0x20, 0xd2, 0x75, 0x69, 0xb1, 0xf6, 0x8d, 0x65, 0xd4, 0x77, 0x11, 0x46, - 0x17, 0xf5, 0xad, 0xec, 0x51, 0x8a, 0x00, 0xc4, 0x5f, 0x0d, 0x40, 0xff, - 0x00, 0xf1, 0xf1, 0x77, 0x79, 0x3f, 0xfb, 0xf2, 0x91, 0xfc, 0xaa, 0x64, - 0xf0, 0xd6, 0x96, 0x9c, 0x9b, 0x45, 0x73, 0xea, 0xe4, 0x9a, 0xd5, 0xa2, - 0x80, 0x29, 0xc7, 0xa5, 0x58, 0xc5, 0xfe, 0xae, 0xd2, 0x10, 0x7f, 0xdc, - 0x15, 0x61, 0x20, 0x89, 0x3e, 0xec, 0x68, 0xbf, 0x45, 0x02, 0xa4, 0xa2, - 0x80, 0x13, 0x1e, 0x9c, 0x52, 0xe2, 0x8a, 0x5a, 0x00, 0x4c, 0x71, 0x46, - 0x29, 0x68, 0xa0, 0x0c, 0x7f, 0x10, 0xe9, 0x0b, 0xab, 0xe9, 0xcd, 0x16, - 0x00, 0x95, 0x3e, 0x68, 0xdb, 0xd0, 0x8f, 0xf1, 0xaf, 0x32, 0x96, 0x27, - 0x86, 0x56, 0x8a, 0x55, 0x2a, 0xea, 0xdb, 0x4a, 0x9e, 0xa0, 0xd7, 0xb2, - 0x62, 0xb9, 0x4f, 0x17, 0xf8, 0x77, 0xed, 0x8a, 0x6f, 0xed, 0x14, 0x7d, - 0xa1, 0x07, 0xef, 0x14, 0x0f, 0xbe, 0x3f, 0xc6, 0x80, 0x38, 0x3a, 0x29, - 0x7a, 0x1c, 0x1e, 0x29, 0x28, 0x03, 0x5b, 0xc3, 0x5a, 0x90, 0xd3, 0xf5, - 0x10, 0x24, 0x38, 0x86, 0x6f, 0x91, 0x8f, 0xa7, 0xbd, 0x77, 0xbd, 0x46, - 0x45, 0x79, 0x6f, 0xf4, 0xae, 0xbf, 0xc3, 0x1a, 0xe0, 0x9d, 0x16, 0xca, - 0xe5, 0xb1, 0x22, 0x8c, 0x46, 0xc7, 0xa3, 0x0f, 0x4f, 0xad, 0x67, 0x38, - 0xf5, 0x35, 0x84, 0xba, 0x33, 0xa4, 0xa3, 0x14, 0x0f, 0xff, 0x00, 0x5f, - 0xb5, 0x15, 0x99, 0xa8, 0x0c, 0xa9, 0xc8, 0x3c, 0xd5, 0xa8, 0xae, 0x94, - 0x8c, 0x3f, 0x07, 0xd6, 0xaa, 0xd1, 0x8a, 0x69, 0xb4, 0x4c, 0xa2, 0x99, - 0xa0, 0x1d, 0x4f, 0x71, 0x4d, 0x79, 0x91, 0x06, 0x73, 0x93, 0x54, 0x68, - 0xc5, 0x57, 0x3b, 0x27, 0xd9, 0x8f, 0x9a, 0x66, 0x95, 0xb1, 0xd0, 0x76, - 0xa6, 0x0a, 0x28, 0xc5, 0x43, 0xd4, 0xb4, 0xac, 0x14, 0x51, 0x45, 0x03, - 0x0c, 0xd1, 0x46, 0x29, 0x33, 0x40, 0x1c, 0xee, 0xab, 0xbf, 0xed, 0xf2, - 0x19, 0x3b, 0x9e, 0x29, 0xfa, 0x28, 0x7f, 0xb7, 0x8d, 0x99, 0xdb, 0x86, - 0xdd, 0xfe, 0x7e, 0xb5, 0xb7, 0x3d, 0xb4, 0x53, 0x8c, 0x4a, 0x81, 0x8d, - 0x10, 0xc1, 0x15, 0xba, 0xe2, 0x34, 0x0a, 0x3d, 0xa8, 0x2f, 0x9b, 0x4b, - 0x12, 0xd1, 0x49, 0x4b, 0x41, 0x21, 0x45, 0x14, 0x50, 0x20, 0xa1, 0x49, - 0x46, 0xdc, 0x0f, 0x34, 0x51, 0x8a, 0x00, 0xb7, 0x15, 0xca, 0x30, 0xf9, - 0xb8, 0x35, 0x36, 0xf4, 0x3d, 0xc5, 0x67, 0x51, 0xcd, 0x5f, 0x3b, 0x33, - 0x74, 0xd1, 0x79, 0xe7, 0x44, 0x19, 0xce, 0x4f, 0xb5, 0x54, 0x96, 0x63, - 0x29, 0xe7, 0x81, 0xe9, 0x4c, 0xc5, 0x14, 0x9c, 0x9b, 0x1c, 0x60, 0x90, - 0x62, 0x8a, 0x28, 0xc7, 0x07, 0xda, 0xa4, 0xb0, 0xae, 0x13, 0xc5, 0x77, - 0xc2, 0xf3, 0x54, 0x28, 0x8d, 0xba, 0x38, 0x3e, 0x41, 0xf5, 0xef, 0x5d, - 0x27, 0x88, 0xb5, 0x65, 0xd3, 0x6d, 0x0a, 0x46, 0x41, 0xb8, 0x94, 0x6d, - 0x50, 0x3b, 0x7b, 0xd7, 0x06, 0x49, 0x27, 0x24, 0xe5, 0x8f, 0x53, 0xeb, - 0x5a, 0x41, 0x75, 0x32, 0x9c, 0xba, 0x09, 0x45, 0x14, 0x64, 0x63, 0x39, - 0xe2, 0xb4, 0x32, 0x14, 0x02, 0xc4, 0x2a, 0x82, 0x49, 0xe9, 0x5e, 0x97, - 0xe1, 0x6d, 0x24, 0x69, 0x7a, 0x5a, 0x87, 0x50, 0x27, 0x9b, 0xe7, 0x93, - 0x8e, 0x87, 0xb0, 0xae, 0x7b, 0xc1, 0x9a, 0x07, 0xda, 0x25, 0x5d, 0x42, - 0xe5, 0x7f, 0x74, 0x87, 0x31, 0x03, 0xfc, 0x47, 0xd7, 0xe9, 0x5d, 0xd8, - 0x14, 0x00, 0xb4, 0x62, 0x96, 0x8a, 0x00, 0x4c, 0x51, 0x8c, 0xd2, 0xd1, - 0x40, 0x11, 0xbc, 0x68, 0xff, 0x00, 0x79, 0x14, 0xfd, 0x57, 0x35, 0x04, - 0x9a, 0x75, 0x9c, 0xbf, 0xeb, 0x2d, 0x60, 0x6f, 0xac, 0x62, 0xad, 0x51, - 0x40, 0x19, 0x6f, 0xe1, 0xdd, 0x2e, 0x43, 0x93, 0x65, 0x10, 0xff, 0x00, - 0x74, 0x62, 0xa1, 0x6f, 0x0c, 0x59, 0x81, 0x98, 0x65, 0xb9, 0xb7, 0x3e, - 0xb1, 0xcc, 0x7f, 0xad, 0x6d, 0x51, 0x40, 0x18, 0x47, 0x43, 0xd4, 0x62, - 0xc1, 0xb6, 0xd6, 0x67, 0x00, 0x76, 0x95, 0x43, 0x51, 0xe5, 0xf8, 0x86, - 0xdf, 0xa4, 0xb6, 0x97, 0x20, 0x7f, 0x78, 0x6d, 0x26, 0xb7, 0x68, 0xc5, - 0x00, 0x62, 0x9d, 0x5b, 0x52, 0x87, 0x1f, 0x68, 0xd2, 0x24, 0xc7, 0xac, - 0x2e, 0x1a, 0x95, 0x7c, 0x51, 0x62, 0x1b, 0x6c, 0xeb, 0x3d, 0xbb, 0x7a, - 0x4b, 0x19, 0x15, 0xb3, 0x8a, 0x63, 0xc4, 0x92, 0x0c, 0x3a, 0x2b, 0x0f, - 0x42, 0x33, 0x40, 0x15, 0xed, 0xb5, 0x3b, 0x3b, 0xac, 0x79, 0x17, 0x51, - 0x39, 0x3d, 0x83, 0x0c, 0xfe, 0x55, 0x6c, 0x1c, 0x8c, 0xd6, 0x6d, 0xce, - 0x81, 0xa6, 0x5d, 0x64, 0xbd, 0xa4, 0x61, 0xbf, 0xbc, 0x83, 0x69, 0xfc, - 0xc5, 0x55, 0xff, 0x00, 0x84, 0x7a, 0x58, 0x0e, 0x6c, 0x75, 0x3b, 0xa8, - 0x4f, 0xf7, 0x5c, 0xef, 0x1f, 0xad, 0x00, 0x6e, 0x66, 0x8a, 0xc5, 0x8c, - 0xeb, 0xb6, 0xf2, 0x22, 0xc8, 0xb6, 0xd7, 0x69, 0xbb, 0x0c, 0xc0, 0xec, - 0x60, 0x3e, 0x9d, 0x2b, 0x64, 0x74, 0xa0, 0x07, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x52, 0x63, 0x1d, 0x29, 0x68, 0xa0, 0x04, 0xc5, - 0x14, 0xb4, 0x50, 0x02, 0x52, 0xd1, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, - 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, - 0x14, 0x51, 0x45, 0x00, 0x14, 0x98, 0xa5, 0xa2, 0x80, 0x39, 0x2f, 0x13, - 0xf8, 0x57, 0xed, 0x5b, 0xae, 0xec, 0x15, 0x56, 0x7e, 0xaf, 0x1f, 0x40, - 0xdf, 0x4a, 0xe1, 0xa4, 0x46, 0x8a, 0x46, 0x49, 0x15, 0x91, 0xd7, 0xaa, - 0xb0, 0xe4, 0x57, 0xb2, 0xe2, 0xb1, 0x35, 0xdf, 0x0d, 0xda, 0xea, 0xe0, - 0xbe, 0x3c, 0xab, 0x81, 0xca, 0xc8, 0xbd, 0xfe, 0xbe, 0xb4, 0x01, 0xe6, - 0x9e, 0xd4, 0x02, 0x54, 0x86, 0x52, 0x54, 0x8e, 0x84, 0x76, 0xfa, 0x55, - 0xfd, 0x5b, 0x45, 0xbc, 0xd2, 0x65, 0x22, 0xe2, 0x3f, 0xdd, 0x9f, 0xbb, - 0x20, 0xe5, 0x4f, 0xf8, 0x56, 0x7e, 0x3f, 0x2f, 0x7a, 0x00, 0xeb, 0x74, - 0x2f, 0x13, 0xab, 0x85, 0xb7, 0xbf, 0x6d, 0xad, 0x8c, 0x2c, 0xbe, 0xbe, - 0xc6, 0xba, 0x75, 0x60, 0xea, 0x19, 0x48, 0x60, 0x7b, 0x83, 0x5e, 0x59, - 0xdb, 0x18, 0xc8, 0xad, 0x1d, 0x33, 0x5c, 0xbb, 0xd3, 0x4e, 0xd8, 0xdf, - 0xcc, 0x8f, 0xbc, 0x6d, 0xcf, 0xe5, 0x59, 0xb8, 0x2e, 0x86, 0x91, 0x9d, - 0xb7, 0x3d, 0x0a, 0x8a, 0xc4, 0xd3, 0xfc, 0x53, 0x65, 0x75, 0x85, 0x98, - 0x9b, 0x79, 0x0f, 0x66, 0xe4, 0x7e, 0x75, 0xb4, 0x8e, 0xb2, 0x20, 0x64, - 0x60, 0xca, 0x7b, 0xa9, 0xcd, 0x66, 0xd3, 0x46, 0xa9, 0xa6, 0x2d, 0x14, - 0x76, 0xa3, 0x34, 0x0c, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, - 0x33, 0x58, 0xed, 0x3c, 0xb6, 0x1a, 0xa3, 0x19, 0x4b, 0x18, 0xdc, 0xf0, - 0x7b, 0x56, 0xc6, 0x2a, 0x1b, 0x8b, 0x68, 0xee, 0x63, 0x29, 0x2a, 0xe4, - 0x76, 0x3e, 0x94, 0x0d, 0x12, 0x46, 0xeb, 0x22, 0x86, 0x46, 0x04, 0x1f, - 0x4a, 0x49, 0x24, 0x8e, 0x24, 0xdd, 0x23, 0x05, 0x51, 0xef, 0x59, 0x67, - 0x48, 0x9e, 0x33, 0xfe, 0x8f, 0x39, 0x03, 0xd3, 0x38, 0xa5, 0x5d, 0x22, - 0x59, 0x1f, 0x75, 0xc4, 0xfb, 0x87, 0xfb, 0x3c, 0xd0, 0x3b, 0x21, 0x2d, - 0x26, 0x9a, 0xfb, 0x52, 0x32, 0xab, 0x32, 0xc2, 0xbd, 0x79, 0xe3, 0xda, - 0xb5, 0xea, 0x38, 0x60, 0x8e, 0x08, 0xc2, 0x46, 0xa1, 0x40, 0xa9, 0x33, - 0x40, 0x98, 0x51, 0x45, 0x19, 0xa0, 0x41, 0x45, 0x14, 0x66, 0x80, 0x0a, - 0x28, 0xa3, 0x34, 0x00, 0x51, 0x9a, 0x4e, 0x95, 0x15, 0xc5, 0xd4, 0x16, - 0x91, 0xef, 0xb8, 0x95, 0x23, 0x5e, 0xdb, 0x8e, 0x33, 0x40, 0x12, 0xf6, - 0xfe, 0x55, 0x9f, 0xac, 0xeb, 0x30, 0x69, 0x71, 0x12, 0xc4, 0x3c, 0xe7, - 0xee, 0x46, 0x3f, 0x99, 0xac, 0x6d, 0x53, 0xc5, 0xc3, 0x0d, 0x1e, 0x9e, - 0x87, 0x3f, 0xf3, 0xd5, 0x87, 0x4f, 0xa0, 0xae, 0x62, 0x69, 0x64, 0x9e, - 0x43, 0x24, 0xae, 0xce, 0xec, 0x72, 0x49, 0xe6, 0xad, 0x43, 0xb9, 0x9c, - 0xa6, 0xba, 0x12, 0x5e, 0xde, 0x4d, 0x7d, 0x72, 0xf3, 0xce, 0xfb, 0x9d, - 0x8f, 0xe5, 0x50, 0x51, 0x4f, 0x8a, 0x29, 0x27, 0x90, 0x47, 0x12, 0x33, - 0xc8, 0xc7, 0x01, 0x54, 0x64, 0xd6, 0xa6, 0x23, 0x2b, 0xa1, 0xf0, 0xcf, - 0x86, 0x64, 0xd4, 0xa4, 0x5b, 0x8b, 0xa5, 0x29, 0x6a, 0xa7, 0x20, 0x63, - 0x05, 0xcf, 0xa5, 0x69, 0xf8, 0x7f, 0xc1, 0xa5, 0x59, 0x6e, 0x35, 0x30, - 0x09, 0x1c, 0x88, 0x07, 0x4f, 0xc6, 0xbb, 0x14, 0x45, 0x55, 0x0a, 0xa0, - 0x28, 0x03, 0x00, 0x0e, 0xd4, 0x00, 0x91, 0x46, 0x91, 0x22, 0xa4, 0x6a, - 0x15, 0x14, 0x60, 0x28, 0x1d, 0x29, 0xf4, 0x62, 0x96, 0x80, 0x0a, 0x28, - 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, - 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x4a, 0x5a, 0x28, 0x01, 0x28, - 0xa5, 0xa2, 0x80, 0x13, 0x1e, 0xf4, 0x52, 0xd1, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x09, 0x46, 0x6a, 0x1b, 0xb9, 0x8d, 0xbd, - 0xa4, 0xb2, 0x85, 0xde, 0x63, 0x42, 0xc1, 0x47, 0x7c, 0x57, 0x9b, 0xdd, - 0xf8, 0xaf, 0x54, 0xb9, 0x72, 0xcb, 0x39, 0x85, 0x4f, 0xf0, 0x27, 0x6f, - 0xad, 0x00, 0x7a, 0x75, 0x15, 0xe5, 0x71, 0xf8, 0x8f, 0x56, 0x8c, 0xe7, - 0xed, 0xb2, 0xe3, 0xdf, 0x9a, 0xd9, 0xd3, 0x7c, 0x63, 0xa8, 0xaf, 0xfa, - 0xfb, 0x6f, 0xb4, 0xc6, 0xbf, 0x79, 0x91, 0x48, 0x61, 0x40, 0x1d, 0xe5, - 0x15, 0x95, 0xa5, 0x6b, 0xd6, 0x5a, 0xaa, 0xfe, 0xe2, 0x4c, 0x49, 0x8e, - 0x63, 0x6e, 0x0d, 0x69, 0xe6, 0x80, 0x1d, 0x49, 0x4b, 0x45, 0x00, 0x43, - 0x34, 0x11, 0xcd, 0x1b, 0x47, 0x22, 0x2b, 0xa3, 0x7d, 0xe5, 0x61, 0x90, - 0x7e, 0xb5, 0xcc, 0xea, 0xbe, 0x08, 0xb7, 0x9f, 0x32, 0x58, 0x3f, 0x91, - 0x27, 0xf7, 0x1b, 0x95, 0x3f, 0xe1, 0x5d, 0x5d, 0x18, 0xa0, 0x0f, 0x28, - 0xd4, 0x74, 0x3b, 0xfd, 0x34, 0x9f, 0xb4, 0xdb, 0xb8, 0x5e, 0xce, 0x9f, - 0x32, 0x9f, 0xc4, 0x74, 0xac, 0xfe, 0x9e, 0xbf, 0x88, 0xaf, 0x66, 0x65, - 0x0c, 0xa4, 0x10, 0x08, 0x3d, 0x8f, 0x4a, 0xc8, 0xbe, 0xf0, 0xc6, 0x97, - 0x7d, 0x92, 0xf6, 0xe1, 0x1f, 0xfb, 0xf1, 0xf0, 0x68, 0x03, 0xcc, 0x6a, - 0x6b, 0x5b, 0xcb, 0x8b, 0x47, 0xdd, 0x6f, 0x3c, 0x91, 0x1f, 0xf6, 0x5b, - 0x83, 0xf8, 0x57, 0x4f, 0x7b, 0xe0, 0x39, 0x54, 0x93, 0x65, 0x72, 0xae, - 0x0f, 0xf0, 0xca, 0x30, 0x47, 0xe3, 0x58, 0xd7, 0x7e, 0x1a, 0xd5, 0x6d, - 0x32, 0x5a, 0xd5, 0x9d, 0x47, 0x74, 0xe6, 0x80, 0x2c, 0x5b, 0xf8, 0xb6, - 0xfe, 0x2c, 0x09, 0x44, 0x73, 0x28, 0xfe, 0xf2, 0xed, 0xad, 0x2b, 0x7f, - 0x19, 0x40, 0x40, 0xfb, 0x45, 0xb4, 0x88, 0x7d, 0x54, 0xe4, 0x57, 0x29, - 0x24, 0x52, 0xc4, 0xdb, 0x64, 0x8e, 0x44, 0x3e, 0x8c, 0xa6, 0xa3, 0xe3, - 0xb7, 0x5a, 0x9e, 0x54, 0x52, 0x9b, 0x47, 0x7d, 0x17, 0x89, 0x74, 0xb9, - 0x7f, 0xe5, 0xb9, 0x43, 0xe8, 0xc8, 0xd5, 0x6a, 0x3d, 0x56, 0xc2, 0x4f, - 0xb9, 0x79, 0x01, 0xfa, 0xc8, 0x05, 0x79, 0xbf, 0xb5, 0x02, 0x97, 0x22, - 0x2b, 0xda, 0x33, 0xd4, 0x56, 0x68, 0xdb, 0xee, 0xc8, 0x87, 0xe8, 0x69, - 0xe0, 0x83, 0xd0, 0x8f, 0xce, 0xbc, 0xb0, 0x1d, 0xbd, 0x09, 0x1f, 0x43, - 0x4f, 0x17, 0x13, 0xaf, 0x49, 0xa4, 0x1f, 0xf0, 0x23, 0x4b, 0x90, 0x7e, - 0xd0, 0xf5, 0x0a, 0x2b, 0xcc, 0xc5, 0xf5, 0xd2, 0xf4, 0xb9, 0x9b, 0xfe, - 0xfb, 0x34, 0xe1, 0xa9, 0x5e, 0x0e, 0x97, 0x32, 0xff, 0x00, 0xdf, 0x46, - 0x97, 0x20, 0x7b, 0x43, 0xd2, 0xa8, 0xaf, 0x35, 0xfe, 0xd3, 0xbe, 0xff, - 0x00, 0x9f, 0xa9, 0x7f, 0xef, 0xaa, 0x5f, 0xed, 0x4b, 0xef, 0xf9, 0xfb, - 0x9b, 0xfe, 0xfa, 0xa3, 0x90, 0x3d, 0xa1, 0xe9, 0x34, 0x95, 0xe6, 0xdf, - 0xda, 0x77, 0xc7, 0xad, 0xd4, 0xbf, 0xf7, 0xd5, 0x21, 0xd4, 0x2f, 0x0f, - 0xfc, 0xbd, 0x4b, 0xff, 0x00, 0x7d, 0x1a, 0x39, 0x03, 0xda, 0x1e, 0x97, - 0xf8, 0xd2, 0x12, 0x07, 0x52, 0x3f, 0x3a, 0xf3, 0x33, 0x7b, 0x72, 0xdf, - 0x7a, 0xe2, 0x6f, 0xfb, 0xec, 0xd3, 0x1a, 0xe2, 0x76, 0xeb, 0x3c, 0x87, - 0xea, 0xc6, 0x8f, 0x66, 0x1e, 0xd0, 0xf4, 0xd6, 0x92, 0x35, 0x1c, 0xba, - 0x81, 0xea, 0x5b, 0x15, 0x5e, 0x4d, 0x4e, 0xca, 0x31, 0xf3, 0xdd, 0xc2, - 0x3d, 0xb7, 0x82, 0x6b, 0xcd, 0xc9, 0x2c, 0x72, 0xc4, 0x9f, 0xa9, 0xa2, - 0x9f, 0x20, 0x7b, 0x43, 0xbe, 0x9b, 0xc4, 0xba, 0x64, 0x5d, 0x2e, 0x37, - 0x1f, 0x44, 0x53, 0x59, 0xf7, 0x1e, 0x32, 0x81, 0x78, 0xb7, 0xb7, 0x91, - 0xcf, 0xab, 0x9d, 0xa2, 0xb9, 0x1f, 0xc7, 0x8a, 0x06, 0x73, 0xf2, 0xfe, - 0x60, 0x53, 0xe4, 0x44, 0xb9, 0xb3, 0x66, 0xeb, 0xc5, 0x7a, 0x84, 0xe0, - 0x88, 0xd9, 0x20, 0x1d, 0xb6, 0x0e, 0x7f, 0x5c, 0xd6, 0x4c, 0xd3, 0x4b, - 0x3b, 0x97, 0x9a, 0x46, 0x77, 0x3d, 0x59, 0x8e, 0x4d, 0x4d, 0x6d, 0xa6, - 0x5f, 0x5d, 0x36, 0x21, 0xb5, 0x95, 0xfd, 0xf6, 0x56, 0xbd, 0xaf, 0x82, - 0xb5, 0x39, 0xf0, 0x65, 0xf2, 0xe0, 0x1d, 0xf7, 0x1c, 0xd5, 0x59, 0x22, - 0x6e, 0xd9, 0xcf, 0x7e, 0xb4, 0xf8, 0x62, 0x92, 0x77, 0x54, 0x85, 0x1a, - 0x47, 0x27, 0x01, 0x51, 0x72, 0x4d, 0x77, 0x76, 0x3e, 0x06, 0xb1, 0x87, - 0x0d, 0x75, 0x23, 0xdc, 0x37, 0xf7, 0x73, 0xb5, 0x7f, 0x4a, 0xdf, 0xb4, - 0xb0, 0xb6, 0xb2, 0x4d, 0xb6, 0xf0, 0x24, 0x43, 0xfd, 0x91, 0xcd, 0x31, - 0x1c, 0x3e, 0x95, 0xe0, 0xab, 0xcb, 0xa2, 0xb2, 0x5e, 0x1f, 0xb3, 0x47, - 0xdd, 0x7a, 0xb1, 0xff, 0x00, 0x0a, 0xec, 0x74, 0xbd, 0x16, 0xcb, 0x4a, - 0x4c, 0x5b, 0x44, 0x03, 0x63, 0x97, 0x3c, 0xb1, 0xfc, 0x6b, 0x44, 0x0a, - 0x31, 0x40, 0x08, 0x07, 0xe9, 0x4e, 0xa4, 0xa5, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, - 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x06, 0x90, 0x0a, 0x90, 0x79, 0x15, 0xc8, - 0xeb, 0xde, 0x0f, 0x4b, 0x89, 0x9a, 0xe3, 0x4f, 0x61, 0x1c, 0x8f, 0xc9, - 0x88, 0xf0, 0x1b, 0xe9, 0xe9, 0x5d, 0x79, 0xaa, 0x13, 0x4d, 0x8b, 0xd5, - 0x1f, 0xc2, 0xbd, 0x69, 0xa5, 0x72, 0x64, 0xec, 0x8f, 0x2e, 0xbc, 0xb2, - 0xb9, 0xb1, 0x98, 0xc3, 0x75, 0x0b, 0x42, 0xc3, 0x8e, 0x47, 0x5f, 0xa1, - 0xe9, 0x56, 0xf4, 0xad, 0x6a, 0x7d, 0x2d, 0x5d, 0x63, 0x8d, 0x24, 0x49, - 0x39, 0x2a, 0xf5, 0xe9, 0x77, 0x96, 0x56, 0xf7, 0xf0, 0x18, 0xae, 0x22, - 0x57, 0x42, 0x3a, 0x11, 0xc8, 0xae, 0x07, 0xc4, 0x7e, 0x19, 0x97, 0x4a, - 0x3e, 0x7d, 0xbe, 0x65, 0xb6, 0x39, 0xfa, 0xa7, 0xb1, 0xff, 0x00, 0x1a, - 0x13, 0xb0, 0xda, 0xb9, 0x47, 0x4e, 0xb2, 0xba, 0xd4, 0xef, 0x26, 0x96, - 0xd0, 0xac, 0x72, 0x26, 0x18, 0x90, 0xd8, 0xc6, 0x6b, 0xab, 0xd0, 0x7c, - 0x47, 0x27, 0xda, 0x7f, 0xb3, 0xb5, 0x5f, 0xdd, 0xdc, 0x8f, 0x95, 0x1c, - 0xff, 0x00, 0x17, 0xa0, 0x3e, 0xfe, 0xf5, 0xc6, 0x58, 0xdf, 0xcf, 0xa7, - 0xcf, 0xe6, 0xdb, 0xb6, 0x1b, 0x18, 0x20, 0xf2, 0x0f, 0xe1, 0x4f, 0x96, - 0x5b, 0xad, 0x5e, 0xf9, 0xa4, 0x08, 0x5e, 0x66, 0x00, 0x81, 0x18, 0xe8, - 0x05, 0x1a, 0x58, 0x5a, 0xa6, 0x7a, 0xde, 0x68, 0xae, 0x67, 0xc2, 0x9a, - 0xcc, 0x97, 0x51, 0x9b, 0x1b, 0xc0, 0xcb, 0x73, 0x0a, 0x8c, 0x6e, 0xea, - 0xcb, 0xfe, 0x35, 0xd3, 0x52, 0x28, 0x5a, 0x28, 0xa2, 0x80, 0x0a, 0x4c, - 0x52, 0xd1, 0x40, 0x09, 0x46, 0x29, 0x68, 0xa0, 0x08, 0x25, 0xb6, 0x86, - 0x61, 0x89, 0x61, 0x47, 0x1e, 0x8c, 0xa0, 0xd5, 0x0b, 0x8f, 0x0e, 0x69, - 0x77, 0x1c, 0x3d, 0x94, 0x63, 0x3f, 0xdd, 0xf9, 0x7f, 0x95, 0x6a, 0xd2, - 0x1a, 0x00, 0xe6, 0x67, 0xf0, 0x46, 0x96, 0xc0, 0xb2, 0x99, 0xa1, 0x1f, - 0xec, 0xbf, 0x03, 0xf3, 0x15, 0xc5, 0x6b, 0x42, 0xc2, 0xca, 0xe7, 0xc8, - 0xb0, 0x9e, 0x4b, 0x80, 0xa7, 0xe6, 0x72, 0x00, 0x03, 0xd8, 0x57, 0x43, - 0xe3, 0x4f, 0x10, 0xc9, 0x2c, 0xad, 0xa7, 0x5a, 0x49, 0xb6, 0x35, 0x38, - 0x99, 0xd4, 0xf2, 0x7d, 0xab, 0x8e, 0x5b, 0x74, 0x03, 0x04, 0x93, 0x40, - 0x0c, 0xfb, 0x4f, 0xaa, 0xfe, 0xb4, 0xbf, 0x69, 0x1f, 0xdd, 0x35, 0x28, - 0x86, 0x31, 0xfc, 0x22, 0x9c, 0x11, 0x47, 0xf0, 0x8f, 0xca, 0x80, 0x21, - 0xfb, 0x50, 0xfe, 0xe9, 0xa3, 0xed, 0x23, 0xfb, 0xa6, 0xa6, 0xda, 0xa3, - 0xb0, 0xa5, 0xc0, 0xf4, 0x14, 0x01, 0x0f, 0xda, 0x47, 0xf7, 0x1a, 0x93, - 0xed, 0x23, 0xfb, 0x8d, 0x53, 0xe3, 0xd8, 0x51, 0x81, 0xe9, 0x40, 0x10, - 0xfd, 0xa1, 0x7f, 0xba, 0x69, 0x3e, 0xd2, 0x3f, 0xba, 0x6a, 0x7c, 0x0f, - 0x4a, 0x69, 0x55, 0x3d, 0x54, 0x7e, 0x54, 0x01, 0x0f, 0xda, 0x47, 0xf7, - 0x7f, 0x5a, 0x3e, 0xd4, 0x3f, 0xbb, 0x52, 0x98, 0xd0, 0xf5, 0x51, 0x51, - 0xb5, 0xaa, 0x9f, 0xba, 0x48, 0xa0, 0x09, 0xec, 0xa5, 0xb6, 0x92, 0xe5, - 0x16, 0xee, 0x47, 0x8a, 0x12, 0x70, 0x5d, 0x46, 0x48, 0xae, 0xde, 0xcb, - 0xc1, 0x7a, 0x6c, 0xf0, 0xc7, 0x32, 0xdd, 0xcd, 0x3a, 0xb8, 0x0c, 0x19, - 0x08, 0x00, 0x8a, 0xf3, 0xc7, 0x85, 0xd3, 0xb6, 0x47, 0xb5, 0x6f, 0xf8, - 0x5b, 0xc4, 0x72, 0x68, 0xb7, 0x22, 0x29, 0x99, 0x9a, 0xce, 0x43, 0xf3, - 0xae, 0x7e, 0xe1, 0xfe, 0xf0, 0xfe, 0xa2, 0x80, 0x3b, 0x78, 0x3c, 0x23, - 0xa4, 0x43, 0xcf, 0xd9, 0x77, 0x9f, 0x57, 0x62, 0x6b, 0x46, 0x1d, 0x2e, - 0xca, 0xdf, 0xfd, 0x4d, 0xac, 0x4b, 0xf4, 0x5a, 0xb1, 0x14, 0x89, 0x2c, - 0x6b, 0x24, 0x6c, 0x19, 0x18, 0x64, 0x11, 0xd0, 0x8a, 0x7d, 0x00, 0x22, - 0xa8, 0x51, 0x80, 0x00, 0xfa, 0x0a, 0x5a, 0x29, 0x68, 0x01, 0x31, 0x45, - 0x2d, 0x14, 0x00, 0x94, 0xb4, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, - 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, - 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, - 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, - 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, - 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, - 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, - 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x08, 0x7a, 0x56, 0x3c, 0x8c, - 0x4c, 0x8c, 0x4f, 0x5c, 0xd6, 0xc1, 0xa8, 0x5a, 0xd6, 0x26, 0x7d, 0xc5, - 0x79, 0xaa, 0x8c, 0x92, 0x33, 0x9c, 0x5c, 0xb6, 0x1d, 0x09, 0x2d, 0x0a, - 0x93, 0xd7, 0x14, 0xb2, 0x46, 0xb2, 0xc6, 0xc8, 0xea, 0x19, 0x58, 0x60, - 0x83, 0xde, 0x9c, 0x00, 0x50, 0x00, 0xe9, 0x4b, 0x52, 0x5a, 0x3c, 0xcf, - 0xc5, 0x3a, 0x1b, 0x69, 0x17, 0xbe, 0x64, 0x40, 0x9b, 0x69, 0x8f, 0xc8, - 0x7f, 0xbb, 0xea, 0x2a, 0xa6, 0x89, 0xa8, 0x0d, 0x36, 0xfd, 0x67, 0x65, - 0x2d, 0x19, 0x05, 0x5b, 0x1d, 0x79, 0xef, 0x5e, 0x93, 0xab, 0xe9, 0xf1, - 0xea, 0x76, 0x12, 0x5b, 0x4a, 0x06, 0x18, 0x7c, 0xa7, 0xd1, 0xbb, 0x57, - 0x95, 0xdd, 0x5b, 0xc9, 0x69, 0x73, 0x24, 0x13, 0xa9, 0x59, 0x11, 0x8a, - 0x91, 0xee, 0x3a, 0x7e, 0x14, 0x2d, 0x01, 0xab, 0xa3, 0x5f, 0x58, 0xd6, - 0x62, 0x7d, 0x5a, 0xde, 0xee, 0xc0, 0x9f, 0x32, 0x21, 0xf3, 0x31, 0x04, - 0x64, 0xfd, 0x2b, 0xbb, 0xd1, 0xb5, 0x38, 0xb5, 0x6b, 0x04, 0xb8, 0x8c, - 0xe1, 0x8f, 0x0e, 0x99, 0xe5, 0x5b, 0xb8, 0xaf, 0x2f, 0xd3, 0xe3, 0x86, - 0x5b, 0xe8, 0x63, 0x9c, 0xe2, 0x26, 0x60, 0x1a, 0xba, 0xab, 0x9b, 0x7f, - 0xf8, 0x47, 0x08, 0xbf, 0xb0, 0x2c, 0x23, 0x04, 0x2c, 0xd0, 0xb3, 0x7c, - 0xae, 0x3e, 0xa6, 0xaa, 0xcd, 0xea, 0x4d, 0xd4, 0x74, 0x3b, 0x6a, 0x5a, - 0xce, 0xd2, 0x75, 0x6b, 0x6d, 0x56, 0xdc, 0x4b, 0x6d, 0x26, 0x71, 0xf7, - 0x90, 0xfd, 0xe5, 0x3e, 0xe2, 0xb4, 0x07, 0x4a, 0x92, 0xc5, 0xa2, 0x92, - 0x96, 0x80, 0x0a, 0x28, 0xa4, 0xa0, 0x05, 0xac, 0x5f, 0x14, 0xea, 0xbf, - 0xd9, 0x5a, 0x53, 0x32, 0x36, 0x26, 0x94, 0xec, 0x8c, 0x7b, 0x9e, 0xff, - 0x00, 0x85, 0x6c, 0x1f, 0x4a, 0xf3, 0xcf, 0x1d, 0xde, 0x9b, 0x8d, 0x64, - 0x40, 0xa7, 0xe4, 0xb7, 0x4c, 0x1f, 0xa9, 0xeb, 0x40, 0x1c, 0xf3, 0x12, - 0x49, 0x24, 0xe4, 0x93, 0x92, 0x69, 0x28, 0xa4, 0xa0, 0x02, 0x96, 0x92, - 0x8a, 0x00, 0x5a, 0x29, 0x28, 0xa0, 0x05, 0xa2, 0x8f, 0x6f, 0xca, 0x8f, - 0x5e, 0x3a, 0x50, 0x01, 0x49, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0xb5, 0x14, 0xb0, 0xee, 0x19, 0x5f, 0xbc, 0x3f, 0x5a, 0x92, 0x8a, 0x00, - 0xec, 0x7e, 0x1f, 0x6b, 0x26, 0x58, 0x5f, 0x4d, 0x98, 0xfc, 0xf1, 0x8d, - 0xd1, 0x7b, 0x8e, 0xe2, 0xbb, 0x61, 0xd0, 0x57, 0x90, 0x69, 0x57, 0x6d, - 0xa6, 0xeb, 0x16, 0xf7, 0x6b, 0xc0, 0x57, 0x01, 0xc7, 0xb1, 0xeb, 0x5e, - 0xba, 0xac, 0x19, 0x43, 0x29, 0xc8, 0x23, 0x22, 0x80, 0x1f, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x02, 0x51, 0x4b, - 0x45, 0x00, 0x25, 0x2d, 0x14, 0x50, 0x02, 0x57, 0x1d, 0xe3, 0x9d, 0x1b, - 0xcc, 0x4f, 0xed, 0x28, 0x57, 0xe6, 0x41, 0xb6, 0x50, 0x07, 0x51, 0xeb, - 0x5d, 0x95, 0x42, 0xf1, 0xac, 0xa8, 0xc8, 0xea, 0x19, 0x58, 0x10, 0x41, - 0x19, 0x04, 0x1e, 0xa2, 0x80, 0x3c, 0x77, 0xa1, 0xab, 0x12, 0x5e, 0xdc, - 0x4b, 0x6e, 0xb0, 0x49, 0x3b, 0xb4, 0x4b, 0xd1, 0x49, 0xad, 0x4f, 0x13, - 0xe8, 0x0f, 0xa4, 0x5d, 0x19, 0x62, 0x52, 0x6d, 0x64, 0x3f, 0x2b, 0x0f, - 0xe1, 0x3e, 0x86, 0xb0, 0xe8, 0x15, 0x8d, 0xdd, 0x17, 0x47, 0xd4, 0x5a, - 0x15, 0xbf, 0xb3, 0xb8, 0x58, 0x5c, 0xe7, 0x6f, 0x24, 0x6e, 0xf6, 0x35, - 0xb1, 0x69, 0xe3, 0x49, 0x6d, 0x65, 0x36, 0xfa, 0xad, 0xb9, 0x59, 0x10, - 0xe0, 0xba, 0x7f, 0x85, 0x73, 0x7a, 0x6e, 0xb7, 0x77, 0xa7, 0x21, 0x8e, - 0x16, 0x47, 0x8b, 0x39, 0xd9, 0x20, 0xc8, 0xcf, 0xaf, 0x5a, 0xab, 0x79, - 0x75, 0x2d, 0xed, 0xd3, 0xcf, 0x31, 0x05, 0xdb, 0xd3, 0xb7, 0xd2, 0xa9, - 0xda, 0xc2, 0x57, 0xbe, 0xa7, 0xa5, 0xdb, 0x78, 0x8f, 0x4b, 0xb9, 0x1f, - 0x25, 0xe4, 0x60, 0xfa, 0x31, 0xc5, 0x5d, 0x17, 0xd6, 0xcc, 0x32, 0x2e, - 0x23, 0x23, 0xfd, 0xe1, 0x5c, 0x6e, 0x99, 0x6f, 0xa2, 0x4d, 0xa7, 0x26, - 0xf3, 0x08, 0x7d, 0xa3, 0xcc, 0x2e, 0xdb, 0x58, 0x1e, 0xe7, 0x26, 0xb9, - 0x8b, 0xb5, 0x89, 0x2e, 0xa5, 0x5b, 0x76, 0x2d, 0x08, 0x63, 0xb0, 0xfa, - 0x8a, 0x1a, 0xb2, 0x05, 0x2b, 0xb3, 0xd5, 0x65, 0xd5, 0xac, 0x21, 0x1f, - 0xbc, 0xbc, 0x85, 0x7e, 0xae, 0x2b, 0x32, 0xef, 0xc6, 0x3a, 0x5d, 0xb0, - 0x3b, 0x65, 0x69, 0x4f, 0x40, 0x23, 0x15, 0xcf, 0xe8, 0x96, 0x3a, 0x44, - 0xba, 0x6a, 0x3c, 0xcd, 0x1b, 0xcc, 0x47, 0xef, 0x3c, 0xc6, 0xc1, 0x53, - 0xfd, 0x2b, 0x07, 0x53, 0x8e, 0xde, 0x3b, 0xf9, 0x92, 0xd1, 0xf7, 0x40, - 0x0f, 0xca, 0x41, 0xcf, 0xe5, 0xed, 0xcd, 0x26, 0x81, 0x4a, 0xee, 0xc7, - 0x4d, 0x7f, 0xe2, 0x8d, 0x56, 0xea, 0xca, 0x49, 0xec, 0xad, 0x44, 0x16, - 0xe0, 0x1f, 0xde, 0x39, 0xf9, 0xab, 0x92, 0x96, 0x69, 0x2e, 0x64, 0x69, - 0xa6, 0x73, 0x24, 0x8f, 0xcb, 0x33, 0x75, 0x26, 0xaf, 0xcd, 0xae, 0xca, - 0x74, 0x36, 0xd3, 0xde, 0x24, 0x2b, 0x80, 0xa1, 0xc1, 0xc1, 0xc6, 0x7d, - 0x2b, 0x34, 0x70, 0x00, 0xa1, 0xd8, 0x6a, 0xfd, 0x42, 0x8a, 0x28, 0xfc, - 0x69, 0x0c, 0x50, 0x09, 0x38, 0x03, 0x27, 0x38, 0x03, 0xde, 0x9d, 0x24, - 0x4f, 0x0c, 0x85, 0x25, 0x46, 0x47, 0x5e, 0x08, 0x61, 0x82, 0x2b, 0xa2, - 0xf0, 0x3e, 0x98, 0xb7, 0x9a, 0x83, 0xdc, 0xc8, 0x01, 0x48, 0x30, 0x54, - 0x1f, 0xef, 0x1f, 0xfe, 0xb0, 0x35, 0x9f, 0xe2, 0xaf, 0xf9, 0x18, 0xaf, - 0x07, 0xfb, 0x74, 0x01, 0x95, 0x45, 0x14, 0x50, 0x06, 0xf7, 0x83, 0x2d, - 0xa2, 0xb9, 0xd7, 0x00, 0x99, 0x12, 0x45, 0x58, 0xc9, 0xc3, 0x0c, 0x8c, - 0xd6, 0x87, 0x8f, 0xac, 0xe0, 0x83, 0xec, 0xd3, 0x45, 0x12, 0xc6, 0xce, - 0x4a, 0xb6, 0xd1, 0x8c, 0xd5, 0x3f, 0x01, 0x7f, 0xc8, 0x78, 0xff, 0x00, - 0xd7, 0x26, 0xad, 0x3f, 0x88, 0x9f, 0xea, 0xac, 0xff, 0x00, 0xde, 0x6f, - 0xe4, 0x28, 0x03, 0x8a, 0xa2, 0x96, 0x92, 0x80, 0x0a, 0x71, 0x52, 0xa7, - 0x0c, 0x08, 0x3e, 0x84, 0x74, 0xa1, 0x3f, 0xd6, 0x2f, 0xfb, 0xc2, 0xba, - 0xff, 0x00, 0x1c, 0xe9, 0x0a, 0x89, 0x1e, 0xa5, 0x0a, 0x81, 0xd1, 0x25, - 0x03, 0xf4, 0x3f, 0xd3, 0xf2, 0xa0, 0x0e, 0x3e, 0x92, 0x8f, 0xc3, 0x1e, - 0xd4, 0x50, 0x00, 0x40, 0x65, 0x22, 0xbd, 0x67, 0x45, 0x97, 0xce, 0xd2, - 0x2d, 0x24, 0x3d, 0xe2, 0x51, 0xf9, 0x71, 0x5e, 0x4e, 0x7a, 0x7e, 0x15, - 0xe9, 0xfe, 0x14, 0x6d, 0xde, 0x1d, 0xb4, 0xf6, 0x52, 0x3f, 0x53, 0x40, - 0x1b, 0x14, 0x52, 0x52, 0xd0, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, - 0x50, 0x04, 0x17, 0x16, 0xf1, 0x5c, 0xc0, 0xf1, 0x4c, 0x81, 0xe3, 0x71, - 0x86, 0x56, 0xe9, 0x5c, 0x06, 0xbf, 0xe1, 0x49, 0xf4, 0xf2, 0xd7, 0x16, - 0x80, 0xcd, 0x6d, 0xe8, 0x07, 0xcd, 0x1f, 0xe1, 0xdc, 0x7d, 0x2b, 0xd1, - 0xa9, 0xa4, 0x03, 0xc1, 0x1f, 0x5a, 0x00, 0xf1, 0xae, 0x9f, 0x85, 0x15, - 0xe9, 0x3a, 0xb7, 0x85, 0x6c, 0x35, 0x22, 0x64, 0x11, 0x98, 0x66, 0x3f, - 0xc6, 0x9f, 0xd4, 0x57, 0x2f, 0x7f, 0xe0, 0xad, 0x46, 0xdc, 0x93, 0x6f, - 0xb2, 0xe2, 0x3e, 0xa3, 0x07, 0x04, 0x7e, 0x06, 0x80, 0x39, 0xda, 0x2a, - 0xe4, 0xda, 0x55, 0xf4, 0x07, 0x12, 0xda, 0xcc, 0x3d, 0x72, 0x95, 0x55, - 0xa2, 0x90, 0x75, 0x89, 0xc7, 0xe0, 0x68, 0x01, 0x28, 0xa7, 0x08, 0xdf, - 0xb2, 0x39, 0xff, 0x00, 0x80, 0x9a, 0x92, 0x3b, 0x2b, 0x99, 0x7f, 0xd5, - 0xdb, 0xca, 0xc7, 0xd9, 0x4d, 0x00, 0x56, 0x9b, 0xee, 0x1f, 0xa8, 0xa7, - 0x76, 0x15, 0xa2, 0x3c, 0x37, 0xaa, 0xcd, 0x13, 0x32, 0xda, 0x48, 0xa0, - 0x72, 0x77, 0x71, 0xc5, 0x67, 0x90, 0x41, 0xda, 0x7a, 0x8e, 0xb4, 0x00, - 0x94, 0x51, 0x41, 0xa0, 0x0f, 0x47, 0xf0, 0x35, 0xb8, 0x87, 0x40, 0x56, - 0xc6, 0x0c, 0xb2, 0x33, 0x9f, 0xd0, 0x7f, 0x4a, 0xe3, 0x7c, 0x55, 0xff, - 0x00, 0x23, 0x15, 0xe7, 0xfb, 0xff, 0x00, 0xd2, 0xbb, 0xcf, 0x0b, 0x00, - 0x3c, 0x39, 0x67, 0x8f, 0xee, 0x1f, 0xe6, 0x6b, 0x83, 0xf1, 0x57, 0xfc, - 0x8c, 0x57, 0x9f, 0xef, 0xff, 0x00, 0x4a, 0x00, 0xca, 0xa2, 0x8a, 0x28, - 0x03, 0xa2, 0xf0, 0x17, 0xfc, 0x87, 0xcf, 0xfd, 0x72, 0x6a, 0xd3, 0xf8, - 0x8b, 0xfe, 0xaa, 0xcb, 0xfd, 0xe6, 0xfe, 0x42, 0xb3, 0x3c, 0x05, 0xff, - 0x00, 0x21, 0xe3, 0xff, 0x00, 0x5c, 0x9a, 0xb4, 0xbe, 0x22, 0xff, 0x00, - 0xab, 0xb3, 0xfa, 0xb7, 0xf2, 0x14, 0x01, 0xc5, 0xd1, 0x45, 0x14, 0x00, - 0xa9, 0xf7, 0xc7, 0xfb, 0xc2, 0xbd, 0x53, 0x5c, 0xb7, 0x17, 0x5a, 0x15, - 0xc4, 0x24, 0x67, 0x31, 0x64, 0x7e, 0x03, 0x3f, 0xd2, 0xbc, 0xad, 0x3f, - 0xd6, 0x2f, 0xfb, 0xc2, 0xbd, 0x7e, 0x60, 0x1a, 0xd1, 0xc1, 0xe8, 0x63, - 0x23, 0xf4, 0xa0, 0x0f, 0x20, 0x1c, 0x8a, 0x4a, 0x73, 0x8c, 0x48, 0xe3, - 0xd1, 0x88, 0xfd, 0x69, 0xb4, 0x00, 0x76, 0xaf, 0x4e, 0xf0, 0x8f, 0xfc, - 0x8b, 0x76, 0xbf, 0xee, 0x9f, 0xe6, 0x6b, 0xcc, 0x7b, 0x57, 0xa7, 0x78, - 0x47, 0xfe, 0x45, 0xbb, 0x5f, 0xf7, 0x4f, 0xf3, 0x34, 0x01, 0xb5, 0x45, - 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, - 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, - 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, - 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, - 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, - 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, - 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, - 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, - 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x49, - 0x4b, 0x45, 0x00, 0x14, 0x98, 0xa5, 0xa2, 0x80, 0x1a, 0x46, 0x47, 0x22, - 0x9a, 0x62, 0x8c, 0xf5, 0x8d, 0x4f, 0xe0, 0x2a, 0x4a, 0x28, 0x02, 0x21, - 0x0c, 0x63, 0xa4, 0x6a, 0x3f, 0xe0, 0x22, 0x9e, 0x14, 0x0e, 0x80, 0x52, - 0xd2, 0xd0, 0x04, 0x17, 0x5f, 0xf1, 0xe9, 0x37, 0xfb, 0x87, 0xf9, 0x57, - 0x90, 0x37, 0xde, 0x3f, 0x53, 0x5e, 0xbf, 0x75, 0xff, 0x00, 0x1e, 0x93, - 0x7f, 0xb8, 0x7f, 0x95, 0x79, 0x03, 0xfd, 0xe3, 0xf5, 0x34, 0x00, 0xda, - 0x0d, 0x14, 0x1a, 0x00, 0xf5, 0x2f, 0x0b, 0xff, 0x00, 0xc8, 0xbb, 0x65, - 0xfe, 0xe7, 0xf5, 0x35, 0xc1, 0x78, 0xab, 0xfe, 0x46, 0x2b, 0xcf, 0xf7, - 0xff, 0x00, 0xa5, 0x77, 0xbe, 0x17, 0xff, 0x00, 0x91, 0x76, 0xcb, 0xfd, - 0xcf, 0xea, 0x6b, 0x82, 0xf1, 0x57, 0xfc, 0x8c, 0x57, 0x9f, 0xef, 0xff, - 0x00, 0x4a, 0x00, 0xca, 0xa2, 0x8a, 0x28, 0x03, 0xa2, 0xf0, 0x17, 0xfc, - 0x87, 0x8f, 0xfd, 0x72, 0x6a, 0xd2, 0xf8, 0x8b, 0xfe, 0xae, 0xcf, 0xea, - 0xdf, 0xc8, 0x56, 0x6f, 0x80, 0xbf, 0xe4, 0x3c, 0x7f, 0xeb, 0x93, 0x56, - 0x97, 0xc4, 0x5f, 0xf5, 0x76, 0x7f, 0x56, 0xfe, 0x42, 0x80, 0x38, 0xba, - 0x28, 0xa2, 0x80, 0x15, 0x3f, 0xd6, 0x2f, 0xfb, 0xc2, 0xbd, 0x86, 0x4f, - 0xf8, 0xf6, 0x6f, 0xf7, 0x0f, 0xf2, 0xaf, 0x1e, 0x4f, 0xf5, 0x8b, 0xfe, - 0xf0, 0xaf, 0x61, 0x93, 0xfe, 0x3d, 0x9b, 0xfd, 0xc3, 0xfc, 0xa8, 0x03, - 0xc8, 0x25, 0xff, 0x00, 0x5d, 0x27, 0xfb, 0xcd, 0xfc, 0xe9, 0x94, 0xf9, - 0xbf, 0xd7, 0x49, 0xfe, 0xf3, 0x7f, 0x3a, 0x65, 0x00, 0x1d, 0xab, 0xd3, - 0xbc, 0x23, 0xff, 0x00, 0x22, 0xdd, 0xaf, 0xfb, 0xa7, 0xf9, 0x9a, 0xf3, - 0x1e, 0xd5, 0xe9, 0xde, 0x11, 0xff, 0x00, 0x91, 0x6e, 0xd7, 0xfd, 0xd3, - 0xfc, 0xcd, 0x00, 0x6d, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, - 0x51, 0x49, 0x4b, 0x40, 0x05, 0x14, 0x94, 0x50, 0x04, 0x37, 0x5f, 0xf1, - 0xe9, 0x37, 0xfb, 0x87, 0xf9, 0x57, 0x90, 0x3f, 0xde, 0x3f, 0x53, 0x5e, - 0xbf, 0x77, 0xff, 0x00, 0x1e, 0xb3, 0x7f, 0xb8, 0xdf, 0xca, 0xbc, 0x81, - 0xfe, 0xf1, 0xfa, 0x9a, 0x00, 0x6d, 0x06, 0x8a, 0x28, 0x03, 0xd4, 0xbc, - 0x2f, 0xff, 0x00, 0x22, 0xf5, 0x9f, 0xfb, 0x9f, 0xd4, 0xd7, 0x05, 0xe2, - 0xaf, 0xf9, 0x18, 0xaf, 0x3f, 0xdf, 0xfe, 0x95, 0xdc, 0xf8, 0x6a, 0xe2, - 0x34, 0xf0, 0xfd, 0x98, 0x2d, 0xc8, 0x4f, 0xea, 0x6b, 0x85, 0xf1, 0x43, - 0x07, 0xf1, 0x0d, 0xd9, 0x1d, 0x0b, 0xd1, 0x61, 0x5d, 0x19, 0x74, 0x0e, - 0xb4, 0x51, 0x40, 0xce, 0x8f, 0xc0, 0x5f, 0xf2, 0x1e, 0x3f, 0xf5, 0xc9, - 0xab, 0x4b, 0xe2, 0x2f, 0xfa, 0xbb, 0x2f, 0xf7, 0x9b, 0xf9, 0x0a, 0xca, - 0xf0, 0x4c, 0xa2, 0x2d, 0x6c, 0xb1, 0x19, 0xfd, 0xd3, 0x55, 0xff, 0x00, - 0x1f, 0x4e, 0x27, 0x8e, 0xd3, 0x00, 0x8c, 0x33, 0x7f, 0x21, 0x4e, 0xce, - 0xd7, 0x17, 0x32, 0xbd, 0x8e, 0x42, 0x8a, 0x28, 0xa4, 0x31, 0x53, 0xfd, - 0x62, 0xff, 0x00, 0xbc, 0x2b, 0xd8, 0x64, 0xff, 0x00, 0x8f, 0x66, 0xff, - 0x00, 0x70, 0xff, 0x00, 0x2a, 0xf1, 0xf4, 0xfb, 0xe3, 0xea, 0x3f, 0x9d, - 0x7a, 0xcb, 0x5d, 0xc4, 0x6d, 0xd8, 0x64, 0x8f, 0x90, 0xff, 0x00, 0x2a, - 0x2d, 0x71, 0x36, 0x96, 0xe7, 0x93, 0xcd, 0xfe, 0xba, 0x4f, 0xf7, 0x9b, - 0xf9, 0xd3, 0x29, 0xf2, 0xf3, 0x34, 0x9f, 0xef, 0x1f, 0xe7, 0x4c, 0xa0, - 0x61, 0xda, 0xbd, 0x3f, 0xc2, 0x3f, 0xf2, 0x2e, 0x5a, 0xff, 0x00, 0xba, - 0x7f, 0x99, 0xaf, 0x30, 0xed, 0x5e, 0x9f, 0xe1, 0x1f, 0xf9, 0x17, 0x2d, - 0x7f, 0xdd, 0x3f, 0xcc, 0xd0, 0x06, 0xc5, 0x2d, 0x25, 0x14, 0x00, 0xb4, - 0x52, 0x52, 0xd0, 0x01, 0x45, 0x25, 0x2d, 0x00, 0x14, 0x51, 0x45, 0x00, - 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, - 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, - 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, - 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, - 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, - 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, - 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, - 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x49, 0x40, - 0x05, 0x14, 0xc7, 0x95, 0x50, 0x7c, 0xcc, 0x05, 0x56, 0x92, 0xf9, 0x47, - 0x11, 0x8c, 0xfb, 0xd3, 0x49, 0xb2, 0x5c, 0x92, 0x2e, 0x1a, 0x6b, 0x48, - 0xa9, 0xf7, 0x98, 0x0a, 0xcd, 0x92, 0xea, 0x57, 0xfe, 0x2d, 0xbf, 0x4a, - 0x88, 0xe4, 0xf7, 0x27, 0xeb, 0x56, 0xa9, 0xb3, 0x37, 0x59, 0x74, 0x34, - 0x5e, 0xf6, 0x25, 0xe0, 0x1d, 0xc7, 0xda, 0xa1, 0x6b, 0xf3, 0xfc, 0x2b, - 0x8a, 0xa9, 0x45, 0x52, 0x82, 0x33, 0x75, 0x64, 0x3e, 0xea, 0xf2, 0x56, - 0xb5, 0x97, 0xa0, 0xf9, 0x0f, 0xf2, 0xaf, 0x30, 0x6f, 0xbc, 0x79, 0xee, - 0x6b, 0xd1, 0xee, 0x7f, 0xe3, 0xde, 0x5f, 0xf7, 0x4d, 0x79, 0xbb, 0x75, - 0x3f, 0x5a, 0x99, 0xa4, 0x8d, 0x29, 0x49, 0xbd, 0xc4, 0xa2, 0x8a, 0x2b, - 0x33, 0x63, 0xbf, 0xd0, 0x7f, 0xe4, 0x0b, 0x6b, 0x9f, 0xee, 0x7f, 0xec, - 0xc6, 0xb9, 0x0f, 0x10, 0x7f, 0xc8, 0x6e, 0xe7, 0xfd, 0xfa, 0xeb, 0xf4, - 0x2f, 0xf9, 0x02, 0xda, 0xff, 0x00, 0xb9, 0xfd, 0x4d, 0x72, 0x3e, 0x20, - 0xff, 0x00, 0x90, 0xd5, 0xd7, 0xfb, 0xf5, 0xac, 0xbe, 0x13, 0x0a, 0x7f, - 0x13, 0x33, 0xa8, 0xa2, 0x8e, 0xf5, 0x91, 0xb9, 0xb5, 0xe1, 0x1f, 0xf9, - 0x0b, 0xff, 0x00, 0xdb, 0x36, 0xab, 0xde, 0x34, 0xfb, 0x96, 0xdf, 0x56, - 0xfe, 0x42, 0xa8, 0xf8, 0x47, 0xfe, 0x42, 0xff, 0x00, 0xf6, 0xcd, 0xaa, - 0xf7, 0x8d, 0x3e, 0xed, 0xb7, 0xd5, 0xbf, 0x90, 0xad, 0x17, 0xc2, 0x62, - 0xfe, 0x33, 0x97, 0xa2, 0x8a, 0x2b, 0x33, 0x61, 0xc9, 0xf7, 0x87, 0xd4, - 0x57, 0xa4, 0x1f, 0xf5, 0x07, 0xfd, 0xc3, 0xfc, 0xab, 0xcd, 0xd7, 0xef, - 0x0f, 0xa8, 0xaf, 0x48, 0x3f, 0xea, 0x1b, 0xfd, 0xc3, 0xfc, 0xab, 0x58, - 0x18, 0xd5, 0xe8, 0x79, 0xc4, 0x9f, 0xeb, 0x5f, 0xfd, 0xe3, 0xfc, 0xe9, - 0x94, 0xf9, 0x3f, 0xd6, 0xbf, 0xfb, 0xc7, 0xf9, 0xd3, 0x2b, 0x36, 0x6a, - 0xb6, 0x0a, 0xef, 0xfc, 0x33, 0x34, 0x89, 0xa1, 0xdb, 0x85, 0x62, 0x00, - 0x07, 0x8f, 0xc4, 0xd7, 0x01, 0x5d, 0xe7, 0x87, 0x3f, 0xe4, 0x0b, 0x6f, - 0xf4, 0x3f, 0xcc, 0xd5, 0x41, 0x5d, 0x99, 0xd5, 0x6d, 0x2d, 0x0d, 0xa4, - 0xbd, 0x94, 0x01, 0x9c, 0x1a, 0x91, 0x6f, 0xc7, 0xf1, 0x29, 0xaa, 0x63, - 0xa5, 0x15, 0xa7, 0x22, 0x66, 0x3e, 0xd2, 0x48, 0xd2, 0x4b, 0xa8, 0x9f, - 0xf8, 0xb1, 0xf5, 0xa9, 0x43, 0x02, 0x32, 0x08, 0x35, 0x91, 0xfc, 0xe9, - 0x43, 0x32, 0x9c, 0xab, 0x10, 0x7d, 0x73, 0x52, 0xe9, 0xf6, 0x2d, 0x56, - 0x7d, 0x4d, 0x8a, 0x2b, 0x32, 0x3b, 0xc9, 0x54, 0xf2, 0x43, 0x0f, 0x71, - 0x56, 0xa3, 0xbd, 0x8d, 0xf8, 0x3f, 0x29, 0xa8, 0x71, 0x68, 0xd1, 0x54, - 0x8b, 0x2c, 0xd2, 0xd3, 0x15, 0x83, 0x0c, 0x83, 0x9a, 0x75, 0x49, 0xa0, - 0xb4, 0x52, 0x52, 0xd0, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, - 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, - 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, - 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, - 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, - 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, - 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, - 0x01, 0x45, 0x14, 0x50, 0x01, 0x49, 0x9a, 0x33, 0x55, 0x6e, 0x6e, 0x84, - 0x43, 0x6a, 0x9c, 0xb1, 0xfd, 0x28, 0x4a, 0xe2, 0x6d, 0x25, 0xa9, 0x3c, - 0x92, 0xac, 0x63, 0x2c, 0x71, 0x54, 0xa5, 0xbd, 0x66, 0x38, 0x8f, 0x81, - 0x55, 0xdd, 0xda, 0x43, 0x97, 0x39, 0xa4, 0xad, 0x94, 0x12, 0xdc, 0xe7, - 0x95, 0x46, 0xf6, 0x06, 0x25, 0xcf, 0xcc, 0x49, 0xa2, 0x8a, 0x2a, 0xcc, - 0xb7, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa4, 0x66, 0x0a, 0xa5, 0x89, - 0x00, 0x0e, 0xb9, 0x3d, 0x28, 0x02, 0xae, 0xa9, 0x3a, 0xdb, 0x69, 0xb3, - 0xca, 0xe7, 0x18, 0x5e, 0x2b, 0xcf, 0x7a, 0xf2, 0x7b, 0xd6, 0xdf, 0x89, - 0x75, 0x95, 0xbe, 0x93, 0xec, 0xd6, 0xed, 0x98, 0x11, 0xb9, 0x6f, 0xef, - 0x9a, 0xc3, 0xef, 0x58, 0xcd, 0xdd, 0x9d, 0x34, 0xa3, 0x64, 0x14, 0x7a, - 0xd1, 0x57, 0x34, 0x8b, 0x17, 0xbf, 0xd4, 0x23, 0x85, 0x46, 0x57, 0x70, - 0x2d, 0xec, 0xb5, 0x2b, 0x53, 0x46, 0xec, 0xae, 0x76, 0xfa, 0x42, 0x18, - 0xf4, 0xab, 0x64, 0x23, 0x04, 0x46, 0x0f, 0xe7, 0xcd, 0x71, 0xbe, 0x20, - 0xff, 0x00, 0x90, 0xd5, 0xd7, 0xfb, 0xf5, 0xde, 0x05, 0x0a, 0x00, 0x1f, - 0x74, 0x0c, 0x0a, 0xe0, 0xfc, 0x41, 0xff, 0x00, 0x21, 0xab, 0xaf, 0xf7, - 0xeb, 0x49, 0xec, 0x61, 0x49, 0xde, 0x4c, 0xce, 0xa2, 0x8a, 0x2b, 0x23, - 0xa0, 0xda, 0xf0, 0x8f, 0xfc, 0x85, 0xbf, 0xed, 0x99, 0xab, 0xde, 0x34, - 0xfb, 0xb6, 0xdf, 0x56, 0xfe, 0x42, 0xa8, 0xf8, 0x4b, 0xfe, 0x42, 0xff, - 0x00, 0xf6, 0xcc, 0xd5, 0xdf, 0x1a, 0x7d, 0xdb, 0x5f, 0xab, 0x7f, 0x2a, - 0xd1, 0x7c, 0x26, 0x2f, 0xe3, 0x39, 0x8a, 0x28, 0xa2, 0xb3, 0x36, 0x1c, - 0xbf, 0x78, 0x7e, 0x15, 0xe9, 0x40, 0x66, 0x3c, 0x7b, 0x62, 0xbc, 0xd5, - 0x7e, 0xf8, 0xfa, 0x8a, 0xf4, 0xa5, 0xfb, 0xa2, 0xb5, 0xa6, 0x61, 0x5b, - 0xa1, 0xe7, 0x17, 0x48, 0x63, 0xba, 0x95, 0x08, 0xc1, 0x57, 0x35, 0x15, - 0x6d, 0xf8, 0xaa, 0xc0, 0xdb, 0x6a, 0x1f, 0x68, 0x51, 0xfb, 0xa9, 0xb9, - 0x27, 0xd1, 0xab, 0x17, 0xf9, 0xfa, 0x56, 0x6d, 0x59, 0x9b, 0x45, 0xdd, - 0x21, 0x2b, 0xaf, 0xf0, 0x7d, 0xe0, 0x96, 0xc6, 0x4b, 0x66, 0x38, 0x78, - 0x9b, 0x23, 0xfd, 0xd3, 0x5c, 0x85, 0x5b, 0xd3, 0x2f, 0xdf, 0x4e, 0xbc, - 0x49, 0xd3, 0xa0, 0xe1, 0xd7, 0xb1, 0x53, 0xd6, 0x9c, 0x5d, 0x99, 0x33, - 0x8f, 0x32, 0xb1, 0xe8, 0x63, 0x90, 0x33, 0xde, 0x8a, 0x82, 0xd2, 0xea, - 0x1b, 0xcb, 0x75, 0x9a, 0x17, 0x0c, 0x84, 0x77, 0x3c, 0x83, 0xef, 0x53, - 0xd6, 0xe7, 0x26, 0xdb, 0x85, 0x14, 0x51, 0x40, 0x05, 0x06, 0x8a, 0x28, - 0x10, 0xe8, 0xe5, 0x78, 0xc8, 0x2a, 0x48, 0xab, 0x50, 0xdf, 0x03, 0xf2, - 0xc8, 0x31, 0xee, 0x2a, 0x9d, 0x15, 0x2e, 0x29, 0x97, 0x19, 0xb8, 0x9a, - 0xea, 0xc1, 0x86, 0x41, 0xc8, 0xa7, 0x56, 0x54, 0x33, 0x49, 0x11, 0xe0, - 0xf1, 0xe9, 0x5a, 0x10, 0x4c, 0xb2, 0xae, 0x54, 0xfe, 0x15, 0x94, 0xa3, - 0x63, 0xa2, 0x13, 0x52, 0x26, 0xa2, 0x92, 0x96, 0xa4, 0xd0, 0x28, 0xa2, - 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, - 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, - 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, - 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, - 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, - 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, - 0x8a, 0x00, 0x28, 0xa2, 0x92, 0x80, 0x20, 0xb9, 0x9b, 0xc9, 0x8c, 0x9f, - 0xe2, 0x3d, 0x2b, 0x34, 0x92, 0x58, 0xb1, 0xe4, 0x9e, 0xb5, 0x62, 0xfd, - 0xb3, 0x36, 0xde, 0xc0, 0x55, 0x7a, 0xda, 0x0a, 0xca, 0xe7, 0x2d, 0x49, - 0x5d, 0xd8, 0x28, 0xa2, 0x8a, 0xb3, 0x30, 0xa2, 0x8a, 0x28, 0x00, 0xa2, - 0x8a, 0x28, 0x03, 0x37, 0x59, 0xd6, 0x62, 0xd2, 0x91, 0x41, 0x53, 0x24, - 0xcf, 0xf7, 0x56, 0xb9, 0x3d, 0x43, 0x5a, 0xbb, 0xd4, 0x32, 0xb2, 0x49, - 0xb2, 0x3e, 0xd1, 0xa7, 0x03, 0xf1, 0xf5, 0xae, 0x97, 0x5e, 0xd0, 0x8e, - 0xa9, 0x22, 0xcb, 0x1c, 0x81, 0x24, 0x55, 0xdb, 0xf3, 0x56, 0x23, 0x78, - 0x62, 0xe9, 0x4f, 0xcd, 0x24, 0x63, 0xf0, 0xac, 0xe4, 0xa4, 0xde, 0x86, - 0xd0, 0x71, 0x4b, 0x53, 0x1b, 0xf0, 0xc5, 0x27, 0x6a, 0xdd, 0x4f, 0x0c, - 0x39, 0x3f, 0xbc, 0x9d, 0x40, 0xf6, 0x19, 0xab, 0xb6, 0xfe, 0x1f, 0xb4, - 0x84, 0x82, 0xfb, 0xa5, 0x23, 0xb3, 0x74, 0xa1, 0x52, 0x93, 0x34, 0x75, - 0x22, 0x8e, 0x7e, 0xc3, 0x4f, 0x9f, 0x50, 0x90, 0x24, 0x11, 0x92, 0x3b, - 0xb9, 0xe8, 0x05, 0x76, 0xba, 0x3e, 0x95, 0x16, 0x95, 0x6d, 0xe5, 0xa6, - 0x1a, 0x56, 0xfb, 0xef, 0x8e, 0x4d, 0x49, 0x6e, 0xe9, 0x12, 0x84, 0x11, - 0xaa, 0x28, 0xe8, 0x54, 0x62, 0xad, 0x03, 0xb8, 0x64, 0x1e, 0xb5, 0x6a, - 0x1c, 0xa6, 0x33, 0xa8, 0xe4, 0x29, 0xe9, 0x5c, 0x0e, 0xbe, 0x73, 0xad, - 0xdc, 0xe3, 0xfb, 0xf5, 0xde, 0x3b, 0x2c, 0x68, 0x5e, 0x43, 0xb5, 0x14, - 0x65, 0x8f, 0xa0, 0xaf, 0x39, 0xbd, 0x9f, 0xed, 0x57, 0x92, 0xcf, 0x8e, - 0x24, 0x72, 0xc3, 0xf1, 0xa8, 0xa8, 0x55, 0x1d, 0xc8, 0x68, 0xa2, 0x96, - 0xb2, 0x3a, 0x0d, 0xcf, 0x07, 0xa1, 0x3a, 0xab, 0xb7, 0x65, 0x4a, 0xb9, - 0xe3, 0x45, 0x26, 0x2b, 0x66, 0x1d, 0x32, 0xc3, 0xf4, 0xa9, 0x3c, 0x1f, - 0x64, 0xd1, 0xdb, 0x49, 0x72, 0xc3, 0x06, 0x53, 0xf2, 0xfd, 0x2a, 0xef, - 0x89, 0x2c, 0xcd, 0xee, 0x95, 0x26, 0xc0, 0x0c, 0x91, 0x7c, 0xeb, 0xef, - 0xc7, 0x23, 0xf2, 0xad, 0x52, 0xf7, 0x4e, 0x77, 0x25, 0xce, 0x70, 0xb4, - 0x52, 0xd2, 0x56, 0x47, 0x40, 0xa0, 0xe1, 0x81, 0xf4, 0xaf, 0x4a, 0x89, - 0x83, 0x44, 0x8c, 0x3a, 0x11, 0x9a, 0xf3, 0x4a, 0xef, 0x3c, 0x3f, 0x74, - 0x2e, 0xf4, 0x98, 0x9b, 0x39, 0x74, 0x1b, 0x5b, 0xd8, 0xd6, 0x94, 0xcc, - 0x6b, 0x2d, 0x0b, 0x57, 0x96, 0x90, 0xde, 0xdb, 0x34, 0x13, 0x28, 0x65, - 0x6f, 0xcc, 0x1f, 0x5a, 0xe2, 0xf5, 0x4d, 0x12, 0xe3, 0x4e, 0x76, 0x24, - 0x19, 0x21, 0x3d, 0x1d, 0x46, 0x7f, 0x3a, 0xee, 0xf3, 0x51, 0x4d, 0x2a, - 0x80, 0x53, 0x86, 0xf5, 0x07, 0xa5, 0x68, 0xe1, 0xcc, 0x65, 0x19, 0xb8, - 0x9e, 0x71, 0x45, 0x75, 0xf7, 0x7a, 0x2d, 0x9d, 0xd3, 0x16, 0xf2, 0xfc, - 0xb6, 0x3f, 0xdd, 0xe2, 0xb3, 0xe4, 0xf0, 0xc1, 0xff, 0x00, 0x96, 0x53, - 0xff, 0x00, 0xdf, 0x42, 0xa1, 0xd2, 0x92, 0x36, 0x55, 0x53, 0x32, 0x2c, - 0xb5, 0x0b, 0x8d, 0x3e, 0x4d, 0xf6, 0xf2, 0x94, 0x24, 0xe7, 0x1d, 0x41, - 0xfc, 0x2b, 0xac, 0xd0, 0xf5, 0xd5, 0xd4, 0xd8, 0xc3, 0x2a, 0x2c, 0x77, - 0x00, 0x64, 0x63, 0xa3, 0x56, 0x21, 0xf0, 0xcd, 0xc1, 0x38, 0x59, 0x50, - 0xd6, 0xb6, 0x85, 0xa0, 0x36, 0x9f, 0x71, 0xf6, 0x89, 0x9c, 0x34, 0x80, - 0x61, 0x54, 0x76, 0xa2, 0x2a, 0x49, 0x93, 0x37, 0x06, 0x8d, 0xd1, 0xd2, - 0x96, 0x8a, 0x2b, 0x43, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, - 0x00, 0xa7, 0x43, 0x2b, 0x44, 0xe1, 0x87, 0xe3, 0x4d, 0xa2, 0x86, 0xae, - 0x09, 0xd9, 0xdc, 0xd7, 0x47, 0x0e, 0xa1, 0x87, 0x43, 0x4f, 0xaa, 0x9a, - 0x7b, 0x13, 0x11, 0x53, 0xd8, 0xd5, 0xba, 0xe7, 0x6a, 0xce, 0xc7, 0x64, - 0x5d, 0xd5, 0xc2, 0x8a, 0x28, 0xa4, 0x50, 0x51, 0x45, 0x14, 0x00, 0x51, - 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, - 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, - 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, - 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, - 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, - 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x52, 0x52, 0xd1, 0x40, 0x19, - 0xd7, 0xe8, 0x44, 0xa1, 0xbb, 0x1a, 0xad, 0x5a, 0x77, 0x11, 0x09, 0x63, - 0x2b, 0xdf, 0xb5, 0x66, 0x32, 0xb2, 0x36, 0xd7, 0x18, 0x22, 0xb6, 0x83, - 0xba, 0xb1, 0xcb, 0x52, 0x36, 0x77, 0x0a, 0x28, 0xa2, 0xac, 0xcc, 0x28, - 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x29, 0x19, 0x43, 0x8c, 0x11, - 0x4b, 0x45, 0x30, 0x29, 0xca, 0x85, 0x1b, 0x1d, 0xa9, 0x95, 0x6a, 0x75, - 0xdd, 0x19, 0xf5, 0x02, 0xaa, 0x8f, 0x7a, 0xd1, 0x3b, 0x80, 0xb4, 0xe5, - 0xb8, 0x5b, 0x74, 0x2f, 0x23, 0x62, 0x30, 0x32, 0x49, 0xa6, 0xd5, 0x4d, - 0x52, 0x09, 0x2e, 0x2c, 0x25, 0x8a, 0x1f, 0xbe, 0x47, 0x03, 0xd6, 0x89, - 0x6c, 0x0b, 0x73, 0x17, 0x5a, 0xf1, 0x13, 0xdf, 0x2b, 0x43, 0x6e, 0x3c, - 0xb8, 0x0f, 0x7e, 0xee, 0x3d, 0xfd, 0x2b, 0x14, 0xfd, 0x38, 0xa9, 0x5a, - 0xd2, 0xe1, 0x5b, 0x06, 0xde, 0x5c, 0xfb, 0x29, 0xa9, 0xe0, 0xd1, 0xef, - 0x67, 0x23, 0x10, 0xb0, 0x07, 0xfb, 0xdc, 0x57, 0x1d, 0xa4, 0xd9, 0xd6, - 0xb9, 0x62, 0x8a, 0x55, 0xa7, 0xa2, 0x68, 0xf2, 0x6a, 0x73, 0x86, 0x6f, - 0x96, 0xdd, 0x4e, 0x5d, 0xcf, 0x7f, 0x61, 0x5a, 0x36, 0x5e, 0x1b, 0x8e, - 0x3c, 0x3d, 0xcb, 0xef, 0x3f, 0xdd, 0x5e, 0x9f, 0x8d, 0x6e, 0x41, 0xb6, - 0x0d, 0xab, 0x1a, 0x85, 0x51, 0xc6, 0x07, 0x40, 0x2b, 0x48, 0xd2, 0x7b, - 0xb2, 0x27, 0x55, 0x5a, 0xc8, 0xb7, 0x12, 0x24, 0x51, 0x2c, 0x71, 0x8c, - 0x2a, 0x8c, 0x01, 0xe8, 0x29, 0xe7, 0x91, 0xcd, 0x20, 0x21, 0x86, 0x47, - 0xa5, 0x2d, 0x59, 0xce, 0x72, 0x1e, 0x20, 0xd0, 0x5a, 0xdd, 0xda, 0xea, - 0xd9, 0x73, 0x13, 0x1c, 0xba, 0x0f, 0xe0, 0x3f, 0xe1, 0x58, 0x15, 0xe8, - 0x73, 0xc9, 0xb8, 0x94, 0x1d, 0x07, 0x51, 0x58, 0xf7, 0xfa, 0x15, 0xbd, - 0xd1, 0x2f, 0x17, 0xee, 0x64, 0x3d, 0x48, 0x1c, 0x1a, 0x99, 0x53, 0xbe, - 0xa8, 0xde, 0x15, 0x6d, 0xa3, 0x39, 0x4a, 0xbd, 0xa4, 0x6a, 0xb3, 0x69, - 0x73, 0x6f, 0x8c, 0x6e, 0x8d, 0x87, 0xcc, 0x84, 0xe3, 0x77, 0xbf, 0xd6, - 0xa4, 0xb8, 0xd0, 0xaf, 0x20, 0x24, 0x84, 0x12, 0x8e, 0xc5, 0x6a, 0xa2, - 0xd8, 0xdd, 0x33, 0x6d, 0x5b, 0x79, 0x09, 0xee, 0x76, 0xd6, 0x5c, 0xb2, - 0x46, 0xad, 0xc5, 0xa3, 0xb7, 0x83, 0x52, 0x86, 0xfa, 0xd8, 0x4b, 0x6e, - 0x4e, 0xd3, 0xc1, 0x07, 0xaa, 0xd2, 0xd6, 0x6e, 0x81, 0x63, 0x2d, 0x9d, - 0xab, 0x79, 0xc3, 0x6b, 0x48, 0xdb, 0xb6, 0xff, 0x00, 0x76, 0xb4, 0xeb, - 0xaa, 0x1b, 0x6a, 0x72, 0x49, 0x24, 0xf4, 0x12, 0x94, 0x02, 0xcc, 0x00, - 0xeb, 0xda, 0x8a, 0x9a, 0xd9, 0x3a, 0xb1, 0xaa, 0xbd, 0x84, 0x49, 0x1c, - 0x4a, 0x83, 0xa7, 0x35, 0x20, 0xa0, 0x51, 0x59, 0xde, 0xe0, 0x14, 0x51, - 0x45, 0x20, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, - 0xa9, 0x20, 0x84, 0xcc, 0xe0, 0x01, 0xc7, 0x73, 0x43, 0x76, 0x1a, 0x4d, - 0xbb, 0x22, 0xdd, 0x8a, 0x95, 0x8b, 0x71, 0xfe, 0x23, 0x56, 0xe9, 0xaa, - 0xa1, 0x40, 0x03, 0xa0, 0xa7, 0x57, 0x3b, 0x77, 0x67, 0x64, 0x55, 0x95, - 0x82, 0x8a, 0x28, 0xa4, 0x30, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, - 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, - 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, - 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, - 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, - 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, - 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x01, 0x0d, 0x41, 0x71, - 0x6e, 0xb3, 0x0f, 0x46, 0xec, 0x6a, 0x7a, 0x28, 0xd8, 0x4d, 0x27, 0xb9, - 0x93, 0x2c, 0x2d, 0x13, 0x61, 0xf8, 0x1e, 0xbe, 0xb4, 0xca, 0xd6, 0x64, - 0x57, 0x18, 0x60, 0x08, 0xaa, 0xb2, 0xd8, 0xf7, 0x88, 0xe3, 0xd8, 0xd6, - 0xb1, 0x9a, 0xea, 0x61, 0x2a, 0x4d, 0x6a, 0x8a, 0x74, 0x53, 0x9e, 0x37, - 0x8c, 0x9d, 0xca, 0x45, 0x34, 0x56, 0x97, 0x31, 0xb3, 0x5b, 0x85, 0x14, - 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x0d, 0x7f, 0xba, 0x7e, 0x95, 0x4b, - 0xb9, 0xab, 0xad, 0xf7, 0x4f, 0xd0, 0xd5, 0x2a, 0xd2, 0x20, 0x2d, 0x25, - 0x2d, 0x15, 0x40, 0x5a, 0x45, 0xdd, 0x00, 0x1e, 0xa2, 0xaa, 0x91, 0x82, - 0x47, 0xbd, 0x5b, 0x8b, 0xfd, 0x52, 0xd5, 0x59, 0x06, 0x25, 0x6f, 0xad, - 0x4c, 0x77, 0x01, 0x28, 0xa2, 0x8a, 0xa0, 0x2c, 0x5b, 0x1c, 0xc7, 0x8e, - 0xe2, 0xa4, 0x73, 0xb5, 0x09, 0xf6, 0xa8, 0x6d, 0x8e, 0x37, 0x0a, 0x7d, - 0xc1, 0xc4, 0x47, 0xde, 0xb3, 0x6b, 0x50, 0x2a, 0x9e, 0xb9, 0xf5, 0xa5, - 0xa4, 0xa5, 0xab, 0x00, 0xab, 0x30, 0x2e, 0x23, 0xcf, 0x72, 0x2a, 0xb5, - 0x5c, 0x51, 0x84, 0xc7, 0xa0, 0xa5, 0x20, 0x29, 0x9e, 0x49, 0xfa, 0xd1, - 0x41, 0xea, 0x7e, 0xb4, 0x55, 0x20, 0x0a, 0xb5, 0x6f, 0xfe, 0xa8, 0x55, - 0x5a, 0xb3, 0x07, 0xfa, 0xa1, 0x53, 0x2d, 0x80, 0x96, 0x8a, 0x28, 0xac, - 0xc0, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x29, 0x3e, 0x95, - 0x2c, 0x76, 0xf2, 0x48, 0x78, 0x04, 0x0f, 0x53, 0x57, 0x21, 0xb3, 0x44, - 0x39, 0x7f, 0x99, 0xaa, 0x5c, 0x92, 0x2e, 0x34, 0xdb, 0x2a, 0xc3, 0x6c, - 0xf2, 0x9c, 0xf4, 0x5f, 0x5a, 0xd0, 0x8e, 0x35, 0x8d, 0x70, 0xa3, 0x14, - 0xe0, 0x29, 0x6b, 0x27, 0x26, 0xce, 0x88, 0xc1, 0x44, 0x5a, 0x28, 0xa2, - 0xa4, 0xb0, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, - 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, - 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, - 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, - 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, - 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, - 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, - 0x28, 0x01, 0x28, 0xa5, 0xa2, 0x80, 0x18, 0x54, 0x30, 0xc1, 0x19, 0xa8, - 0x64, 0xb3, 0x8d, 0xfe, 0xee, 0x54, 0xfb, 0x55, 0x8a, 0x29, 0xdd, 0xa1, - 0x38, 0xa7, 0xb9, 0x9d, 0x25, 0x94, 0x8b, 0x9d, 0xbc, 0x8a, 0x85, 0xa3, - 0x75, 0xfb, 0xca, 0x41, 0xfa, 0x56, 0xb9, 0xa4, 0x20, 0x1e, 0xbc, 0xfe, - 0x15, 0x4a, 0x6c, 0xcd, 0xd2, 0x4c, 0xc7, 0xa2, 0xb4, 0xda, 0xda, 0x27, - 0xea, 0x83, 0xf0, 0xa8, 0x9a, 0xc1, 0x0f, 0x46, 0x22, 0xaf, 0xda, 0x23, - 0x37, 0x49, 0xad, 0x8c, 0xf6, 0xfb, 0xa7, 0xe9, 0x54, 0xeb, 0x59, 0xec, - 0x24, 0xda, 0x76, 0xb0, 0x39, 0x15, 0x41, 0xb4, 0xfb, 0x94, 0xc9, 0xf2, - 0x89, 0xfa, 0x10, 0x6b, 0x48, 0xcd, 0x10, 0xe1, 0x24, 0x41, 0x45, 0x3c, - 0xc3, 0x2a, 0xf0, 0xd1, 0xb0, 0xfc, 0x29, 0x84, 0x11, 0xd4, 0x62, 0xb4, - 0xba, 0xee, 0x4d, 0x99, 0x6e, 0x2f, 0xf5, 0x4b, 0xf4, 0xaa, 0xd3, 0x7f, - 0xad, 0x6a, 0xb3, 0x17, 0xfa, 0xa1, 0x55, 0xa6, 0x3f, 0xbe, 0x6f, 0xad, - 0x4c, 0x5e, 0xa0, 0x36, 0x8a, 0x28, 0xab, 0x02, 0x5b, 0x5f, 0xbc, 0x7e, - 0x94, 0xfb, 0xaf, 0xb8, 0x3e, 0xb4, 0xcb, 0x5f, 0xbc, 0x7e, 0x94, 0xfb, - 0xaf, 0xb8, 0x3f, 0xde, 0xa8, 0xea, 0x05, 0x7a, 0x28, 0xa2, 0xac, 0x02, - 0xae, 0xf6, 0x1f, 0x4a, 0xa3, 0x9a, 0xba, 0x39, 0x51, 0xf4, 0xa8, 0x90, - 0x14, 0xdb, 0xef, 0x1f, 0xad, 0x14, 0x87, 0xef, 0x1f, 0xad, 0x28, 0x56, - 0x3d, 0x14, 0x9f, 0xc0, 0xd5, 0x5d, 0x06, 0xa2, 0x55, 0xa8, 0x3f, 0xd4, - 0x8a, 0x85, 0x6d, 0x67, 0x7f, 0xbb, 0x0b, 0xfd, 0x71, 0x57, 0xed, 0xec, - 0xa6, 0x11, 0x80, 0xca, 0x17, 0xea, 0x6a, 0x25, 0x25, 0x61, 0xa8, 0xb7, - 0xd0, 0x8e, 0x8a, 0xb6, 0xb6, 0x0d, 0xd5, 0x9c, 0x7e, 0x02, 0xa5, 0x5b, - 0x28, 0x87, 0x52, 0x58, 0xd6, 0x5c, 0xe8, 0xb5, 0x4e, 0x4c, 0xcf, 0x3c, - 0x53, 0xd2, 0x19, 0x24, 0xfb, 0xaa, 0x7f, 0x1a, 0xd1, 0x58, 0x23, 0x4e, - 0x42, 0x01, 0x52, 0x54, 0xba, 0x85, 0xaa, 0x3d, 0xca, 0x09, 0x62, 0xe7, - 0xef, 0xb0, 0x1f, 0x4a, 0xb3, 0x1d, 0xac, 0x71, 0xf4, 0x19, 0x3e, 0xf5, - 0x38, 0xa2, 0xa5, 0xc9, 0xb3, 0x45, 0x08, 0xa0, 0x14, 0x51, 0x4b, 0x52, - 0x58, 0x94, 0xb4, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, - 0x40, 0x05, 0x14, 0x51, 0x40, 0x09, 0x45, 0x2d, 0x14, 0x00, 0x94, 0x52, - 0xd1, 0x40, 0x09, 0x45, 0x2d, 0x14, 0x00, 0x86, 0x9a, 0x63, 0x56, 0xea, - 0xa0, 0xd3, 0xa8, 0xa0, 0x56, 0x23, 0x30, 0xc6, 0x47, 0xdc, 0x1f, 0x95, - 0x46, 0xf6, 0x36, 0xef, 0xc9, 0x8c, 0x55, 0x9a, 0x4a, 0x77, 0x61, 0xca, - 0x8a, 0x87, 0x4d, 0xb6, 0x3f, 0xc0, 0x7f, 0x3a, 0x69, 0xd2, 0xed, 0xcf, - 0xf0, 0x91, 0xf8, 0xd5, 0xda, 0x29, 0xf3, 0x3e, 0xe2, 0xe4, 0x89, 0x4d, - 0x34, 0xd8, 0x50, 0xe4, 0x6e, 0xfc, 0xe9, 0x5f, 0x4e, 0x86, 0x41, 0x83, - 0xbb, 0xf3, 0xab, 0x74, 0x51, 0xcc, 0xc3, 0x92, 0x25, 0x0f, 0xec, 0x98, - 0x3f, 0xdb, 0xfc, 0xe9, 0xc3, 0x4b, 0xb7, 0x1f, 0xc2, 0x4f, 0xd4, 0xd5, - 0xda, 0x28, 0xe7, 0x97, 0x70, 0xe4, 0x89, 0x54, 0x69, 0xd6, 0xe3, 0xfe, - 0x59, 0xe7, 0xf1, 0xa9, 0x05, 0xbc, 0x43, 0xf8, 0x07, 0xe5, 0x53, 0x51, - 0x4b, 0x99, 0x87, 0x2a, 0x22, 0x10, 0x44, 0x3a, 0x46, 0xbf, 0x95, 0x3c, - 0x28, 0x1d, 0x00, 0x14, 0xea, 0x29, 0x6a, 0x3b, 0x20, 0xa2, 0x96, 0x8a, - 0x06, 0x25, 0x14, 0xb4, 0x50, 0x02, 0x51, 0x4b, 0x45, 0x00, 0x25, 0x2d, - 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, - 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, - 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, - 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, - 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x07, 0xff, 0xd9 -}; -unsigned int octo_jpg_len = 14817; - -#endif +#include "JPEGSamples.h" + +#ifdef INCLUDE_SIMDATA +// APP0 e0 +// DQT db +// DQT db +// DHT c4 +// DHT c4 +// DHT c4 +// DHT c4 +// SOF0 c0 baseline (not progressive) 3 color 0x01 Y, 0x21 2h1v, 0x00 tbl0 +// - 0x02 Cb, 0x11 1h1v, 0x01 tbl1 - 0x03 Cr, 0x11 1h1v, 0x01 tbl1 +// therefore 4:2:2, with two separate quant tables (0 and 1) +// SOS da +// EOI d9 (no need to strip data after this RFC says client will discard) +unsigned const char capture_jpg[] = { + 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, + 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, + 0x00, 0x0f, 0x0a, 0x0b, 0x0d, 0x0b, 0x09, 0x0f, 0x0d, 0x0c, 0x0d, 0x11, + 0x10, 0x0f, 0x12, 0x17, 0x26, 0x18, 0x17, 0x15, 0x15, 0x17, 0x2e, 0x21, + 0x23, 0x1b, 0x26, 0x36, 0x30, 0x39, 0x38, 0x35, 0x30, 0x35, 0x34, 0x3c, + 0x44, 0x56, 0x49, 0x3c, 0x40, 0x52, 0x41, 0x34, 0x35, 0x4b, 0x66, 0x4c, + 0x52, 0x59, 0x5c, 0x61, 0x62, 0x61, 0x3a, 0x48, 0x6a, 0x71, 0x69, 0x5e, + 0x71, 0x56, 0x5f, 0x61, 0x5d, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x10, 0x11, + 0x11, 0x17, 0x14, 0x17, 0x2c, 0x18, 0x18, 0x2c, 0x5d, 0x3e, 0x35, 0x3e, + 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, + 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, + 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, + 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, 0x5d, + 0x5d, 0x5d, 0xff, 0xc4, 0x00, 0x1f, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, + 0xc4, 0x00, 0xb5, 0x10, 0x00, 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, + 0x05, 0x05, 0x04, 0x04, 0x00, 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, + 0x04, 0x11, 0x05, 0x12, 0x21, 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, + 0x22, 0x71, 0x14, 0x32, 0x81, 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, + 0x15, 0x52, 0xd1, 0xf0, 0x24, 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, + 0x17, 0x18, 0x19, 0x1a, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, + 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, + 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, + 0x7a, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, + 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, + 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, + 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, + 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, + 0xe7, 0xe8, 0xe9, 0xea, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa, 0xff, 0xc4, 0x00, 0x1f, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, + 0xc4, 0x00, 0xb5, 0x11, 0x00, 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, + 0x07, 0x05, 0x04, 0x04, 0x00, 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, + 0x11, 0x04, 0x05, 0x21, 0x31, 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, + 0x13, 0x22, 0x32, 0x81, 0x08, 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, + 0x23, 0x33, 0x52, 0xf0, 0x15, 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, + 0xe1, 0x25, 0xf1, 0x17, 0x18, 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, + 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, + 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, + 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, + 0x79, 0x7a, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, + 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, + 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, + 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, + 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, + 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, + 0xf9, 0xfa, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x02, 0x58, 0x03, 0x20, 0x03, + 0x01, 0x21, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xda, 0x00, + 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xc7, + 0x10, 0xd3, 0xa3, 0x84, 0xaf, 0x34, 0xda, 0x08, 0x9a, 0xe3, 0x1b, 0x46, + 0x29, 0xc9, 0xf7, 0xc5, 0x4f, 0x40, 0x34, 0xd3, 0xa5, 0x3a, 0x84, 0x20, + 0xa5, 0xa6, 0x20, 0xa2, 0x81, 0x85, 0x14, 0x08, 0x28, 0xa0, 0x62, 0xd1, + 0x40, 0x05, 0x14, 0x00, 0x94, 0x50, 0x01, 0x45, 0x03, 0x0a, 0x28, 0x10, + 0x52, 0x50, 0x01, 0x49, 0x40, 0xc2, 0x8a, 0x00, 0x29, 0x28, 0x01, 0x28, + 0xa0, 0x02, 0x92, 0x80, 0x12, 0x8a, 0x00, 0x4a, 0x4a, 0x00, 0x29, 0x28, + 0x01, 0x29, 0x28, 0x01, 0x28, 0xa0, 0x04, 0xa4, 0xa0, 0x02, 0x92, 0x80, + 0x12, 0x92, 0x80, 0x12, 0x8a, 0x60, 0x25, 0x25, 0x02, 0x12, 0x92, 0x80, + 0x12, 0x8a, 0x00, 0x4a, 0x4a, 0x40, 0x14, 0x50, 0x02, 0x52, 0x53, 0x10, + 0x94, 0x94, 0x08, 0x4a, 0x28, 0x10, 0x94, 0x94, 0x00, 0x52, 0x50, 0x02, + 0x52, 0x50, 0x02, 0x51, 0x40, 0x09, 0x49, 0x40, 0x09, 0x4f, 0x4e, 0x94, + 0x08, 0x75, 0x15, 0x42, 0x12, 0x8a, 0x42, 0x12, 0x92, 0x98, 0x09, 0x45, + 0x00, 0x14, 0x94, 0x08, 0x28, 0xa4, 0x02, 0x52, 0x53, 0x10, 0x52, 0x52, + 0x00, 0xa4, 0xa0, 0x90, 0x13, 0x2d, 0x4a, 0xb2, 0x27, 0xa8, 0xa9, 0x67, + 0x51, 0x76, 0x06, 0xdd, 0x06, 0x7d, 0xe9, 0xd4, 0x90, 0xcd, 0x28, 0x4e, + 0x56, 0xa5, 0xa1, 0x08, 0x29, 0x69, 0x88, 0x28, 0xa0, 0x02, 0x8a, 0x00, + 0x28, 0xa0, 0x61, 0x4b, 0x40, 0x09, 0x4b, 0x40, 0x84, 0xa2, 0x81, 0x85, + 0x14, 0x00, 0x51, 0x40, 0xc2, 0x92, 0x81, 0x05, 0x14, 0x00, 0x94, 0x50, + 0x01, 0x49, 0x40, 0x05, 0x25, 0x03, 0x0a, 0x4a, 0x00, 0x29, 0x28, 0x01, + 0x29, 0x28, 0x00, 0xa4, 0xa0, 0x04, 0xa2, 0x80, 0x12, 0x92, 0x81, 0x09, + 0x45, 0x03, 0x12, 0x92, 0x80, 0x12, 0x8a, 0x00, 0x4a, 0x4a, 0x62, 0x12, + 0x92, 0x90, 0x09, 0x49, 0x40, 0x09, 0x49, 0x40, 0x05, 0x25, 0x02, 0x12, + 0x8a, 0x60, 0x25, 0x25, 0x00, 0x14, 0x94, 0x08, 0x29, 0xb4, 0x00, 0x52, + 0x50, 0x21, 0x29, 0x28, 0x00, 0xa4, 0xa0, 0x04, 0xa2, 0x98, 0x86, 0xd1, + 0x48, 0x04, 0xa7, 0xa5, 0x00, 0x3a, 0x90, 0xd5, 0x12, 0x25, 0x25, 0x00, + 0x14, 0x50, 0x02, 0x51, 0x40, 0x84, 0xa4, 0xa0, 0x02, 0x8a, 0x00, 0x4a, + 0x29, 0x08, 0x29, 0x28, 0x01, 0x29, 0x29, 0x88, 0xcb, 0xf3, 0x4d, 0x28, + 0x90, 0xd2, 0xb1, 0xd4, 0x6d, 0xe8, 0xf2, 0x6f, 0xb6, 0xdb, 0xe9, 0x93, + 0xfa, 0xd5, 0xda, 0xce, 0x23, 0x65, 0xeb, 0x43, 0x94, 0xab, 0x14, 0xd0, + 0x98, 0xb4, 0x53, 0x24, 0x28, 0xa0, 0x05, 0xa2, 0x80, 0x0a, 0x28, 0x18, + 0x51, 0x40, 0x05, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, 0x00, 0x51, 0x40, + 0x09, 0x45, 0x00, 0x14, 0x94, 0x0c, 0x28, 0xa0, 0x02, 0x92, 0x80, 0x0a, + 0x4a, 0x00, 0x29, 0x28, 0x00, 0xa4, 0xa0, 0x04, 0xa2, 0x80, 0x12, 0x8a, + 0x00, 0x4a, 0x4a, 0x00, 0x4a, 0x4a, 0x00, 0x4a, 0x28, 0x01, 0x29, 0x28, + 0x10, 0x94, 0x50, 0x31, 0x29, 0x28, 0x10, 0x94, 0x94, 0x0c, 0x4a, 0x4a, + 0x62, 0x12, 0x92, 0x80, 0x12, 0x92, 0x80, 0x0a, 0x4a, 0x04, 0x14, 0x94, + 0x00, 0x53, 0x68, 0x10, 0x52, 0x50, 0x02, 0x51, 0x40, 0x86, 0xd1, 0x40, + 0x09, 0x49, 0x4c, 0x04, 0xa2, 0x80, 0x12, 0x92, 0x81, 0x09, 0x4f, 0x4a, + 0x40, 0x3a, 0x9b, 0x56, 0x48, 0x52, 0x50, 0x01, 0x45, 0x20, 0x0a, 0x29, + 0x08, 0x4a, 0x4a, 0x60, 0x25, 0x14, 0x80, 0x4a, 0x29, 0x92, 0x14, 0x94, + 0x80, 0x4a, 0x29, 0x8c, 0xc4, 0xcd, 0x28, 0xe9, 0x53, 0x63, 0xa4, 0xd7, + 0xd0, 0x5f, 0xe7, 0x91, 0x7f, 0xd9, 0xfe, 0xb5, 0xad, 0x59, 0xc4, 0xa9, + 0x97, 0x2c, 0xcf, 0x6a, 0xb9, 0x4d, 0x12, 0x14, 0xb5, 0x42, 0x0a, 0x28, + 0x00, 0xa2, 0x80, 0x16, 0x8a, 0x00, 0x28, 0xa0, 0x41, 0x45, 0x00, 0x14, + 0x50, 0x30, 0xa4, 0xa0, 0x02, 0x8a, 0x00, 0x28, 0xa0, 0x02, 0x92, 0x81, + 0x85, 0x14, 0x00, 0x94, 0x50, 0x01, 0x49, 0x40, 0x05, 0x25, 0x00, 0x14, + 0x94, 0x00, 0x52, 0x50, 0x02, 0x52, 0x50, 0x01, 0x49, 0x40, 0x09, 0x49, + 0x40, 0x09, 0x49, 0x40, 0x05, 0x25, 0x00, 0x25, 0x14, 0x00, 0x94, 0x94, + 0x00, 0x94, 0x94, 0x00, 0x94, 0x94, 0xc4, 0x25, 0x25, 0x20, 0x12, 0x92, + 0x80, 0x12, 0x92, 0x80, 0x0a, 0x29, 0x80, 0x94, 0x94, 0x08, 0x29, 0x29, + 0x08, 0x6d, 0x15, 0x40, 0x25, 0x25, 0x21, 0x09, 0x45, 0x20, 0x12, 0x92, + 0x81, 0x09, 0x49, 0x4c, 0x02, 0x9c, 0x94, 0x00, 0xfa, 0x69, 0xaa, 0x24, + 0x4a, 0x4a, 0x00, 0x29, 0x68, 0x01, 0x28, 0xa4, 0x21, 0x28, 0xa6, 0x02, + 0x52, 0x52, 0x00, 0xa2, 0x81, 0x09, 0x45, 0x31, 0x09, 0x4d, 0x35, 0x43, + 0x30, 0xa9, 0xea, 0x6a, 0x2c, 0x74, 0x9a, 0x3a, 0x3b, 0xe2, 0xf6, 0x25, + 0xfe, 0xf3, 0x62, 0xb7, 0xab, 0x3e, 0xa3, 0x96, 0xc4, 0xf6, 0x87, 0xe7, + 0xad, 0x01, 0x42, 0x10, 0xb4, 0x55, 0x08, 0x5a, 0x28, 0x10, 0x51, 0x40, + 0x0b, 0x49, 0x40, 0xc5, 0xa2, 0x98, 0x05, 0x14, 0x80, 0x29, 0x28, 0x00, + 0xa2, 0x80, 0x0a, 0x28, 0x00, 0xa2, 0x80, 0x0a, 0x4a, 0x06, 0x14, 0x50, + 0x02, 0x51, 0x40, 0x05, 0x25, 0x00, 0x14, 0x94, 0x00, 0x52, 0x50, 0x01, + 0x49, 0x40, 0x09, 0x45, 0x00, 0x25, 0x25, 0x00, 0x25, 0x25, 0x00, 0x14, + 0x94, 0x00, 0x94, 0x94, 0x00, 0x94, 0x50, 0x02, 0x52, 0x50, 0x21, 0x29, + 0x28, 0x01, 0x29, 0xb4, 0x00, 0x52, 0x50, 0x21, 0x29, 0x28, 0x01, 0x29, + 0x29, 0x80, 0x94, 0x52, 0x00, 0xa4, 0xa6, 0x21, 0x29, 0x28, 0x01, 0x29, + 0x28, 0x00, 0xa4, 0x34, 0x08, 0x4a, 0x4a, 0x04, 0x25, 0x14, 0x00, 0xda, + 0x28, 0x01, 0x29, 0xcb, 0x40, 0x0f, 0xa4, 0xab, 0x20, 0x4a, 0x4a, 0x00, + 0x28, 0xa0, 0x04, 0xa2, 0x81, 0x09, 0x45, 0x21, 0x85, 0x25, 0x02, 0x12, + 0x8a, 0x00, 0x4a, 0x4a, 0x42, 0x0a, 0x29, 0x81, 0x81, 0x4e, 0x14, 0x8e, + 0xa2, 0xcd, 0x9b, 0xf9, 0x77, 0x51, 0xbf, 0xa1, 0xae, 0xa3, 0xf8, 0x54, + 0xfa, 0x81, 0x51, 0xf6, 0x87, 0xd0, 0x92, 0x0e, 0x25, 0x15, 0xa4, 0xbd, + 0x29, 0x75, 0x10, 0xb4, 0xb5, 0x42, 0x0a, 0x28, 0x10, 0xb4, 0x50, 0x01, + 0x45, 0x03, 0x0a, 0x29, 0x80, 0xb4, 0x94, 0x80, 0x29, 0x68, 0x01, 0x28, + 0xa0, 0x02, 0x8a, 0x00, 0x29, 0x29, 0x80, 0xb4, 0x94, 0x86, 0x14, 0x50, + 0x02, 0x52, 0xd0, 0x02, 0x52, 0x50, 0x01, 0x45, 0x00, 0x14, 0x94, 0x00, + 0x94, 0x94, 0x00, 0x52, 0x50, 0x02, 0x52, 0x50, 0x01, 0x49, 0x40, 0x09, + 0x49, 0x40, 0x09, 0x49, 0x40, 0x09, 0x49, 0x40, 0x09, 0x45, 0x00, 0x25, + 0x25, 0x02, 0x12, 0x92, 0x98, 0x09, 0x49, 0x48, 0x42, 0x52, 0x50, 0x02, + 0x52, 0x50, 0x02, 0x52, 0x53, 0x00, 0xa2, 0x81, 0x09, 0x49, 0x40, 0x09, + 0x49, 0x40, 0x09, 0x45, 0x00, 0x36, 0x8a, 0x64, 0x89, 0x49, 0x48, 0x62, + 0x51, 0x45, 0xc4, 0x25, 0x2a, 0x50, 0x03, 0xe8, 0xaa, 0x24, 0x4a, 0x28, + 0x10, 0x94, 0x50, 0x02, 0x51, 0x40, 0x86, 0xd1, 0x48, 0x61, 0x49, 0x45, + 0xc4, 0x25, 0x14, 0xc0, 0x4a, 0x29, 0x00, 0x94, 0xb4, 0x08, 0xe7, 0xe9, + 0xc0, 0xd0, 0xce, 0x91, 0xd9, 0xae, 0xbe, 0x36, 0xdf, 0x0a, 0x9f, 0xc3, + 0xf4, 0xac, 0xdf, 0xc4, 0x57, 0xd9, 0x1c, 0x3a, 0xd6, 0x9c, 0x7c, 0xad, + 0x1d, 0x44, 0x3e, 0x8a, 0xa1, 0x0b, 0x45, 0x00, 0x14, 0xb4, 0x08, 0x28, + 0xa0, 0x61, 0x45, 0x00, 0x14, 0xb4, 0x00, 0x94, 0x50, 0x02, 0xd2, 0x50, + 0x01, 0x45, 0x00, 0x14, 0x94, 0x00, 0x51, 0x40, 0x05, 0x14, 0x0c, 0x4a, + 0x28, 0x00, 0xa2, 0x80, 0x12, 0x8a, 0x00, 0x4a, 0x28, 0x01, 0x28, 0xa0, + 0x04, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x02, 0x92, 0x80, 0x12, 0x92, 0x80, + 0x12, 0x92, 0x80, 0x12, 0x92, 0x80, 0x0a, 0x4a, 0x00, 0x6d, 0x14, 0x00, + 0x94, 0x94, 0x08, 0x4a, 0x4a, 0x04, 0x25, 0x36, 0x80, 0x12, 0x92, 0x80, + 0x0a, 0x4a, 0x00, 0x4a, 0x28, 0x01, 0x29, 0x28, 0x10, 0x94, 0x94, 0x0c, + 0x29, 0x28, 0x10, 0x94, 0x94, 0x08, 0x4a, 0x29, 0x88, 0x4a, 0x43, 0x40, + 0x09, 0x4e, 0x5a, 0x60, 0x3e, 0x8a, 0x76, 0x24, 0x6d, 0x14, 0x00, 0x52, + 0x50, 0x21, 0x28, 0xa0, 0x42, 0x52, 0x1a, 0x2c, 0x30, 0xa2, 0x80, 0x12, + 0x92, 0x98, 0x82, 0x92, 0xa4, 0x41, 0x49, 0x4c, 0x66, 0x05, 0x14, 0x1d, + 0x03, 0x96, 0xba, 0x9d, 0x29, 0xf7, 0xe9, 0xab, 0xeb, 0xb9, 0xab, 0x29, + 0xbd, 0x51, 0x7f, 0x64, 0xb3, 0xda, 0xb4, 0xa0, 0x39, 0x4a, 0x1e, 0xe4, + 0x92, 0xd2, 0xd5, 0x08, 0x5a, 0x28, 0x10, 0x51, 0x40, 0x0b, 0x45, 0x00, + 0x14, 0x50, 0x30, 0xa2, 0x80, 0x0a, 0x28, 0x00, 0xa2, 0x80, 0x0a, 0x4a, + 0x00, 0x28, 0xa0, 0x05, 0xa4, 0xa0, 0x61, 0x45, 0x02, 0x0a, 0x4a, 0x06, + 0x14, 0x50, 0x02, 0x51, 0x40, 0x05, 0x25, 0x00, 0x14, 0x94, 0x00, 0x94, + 0x94, 0x00, 0x52, 0x50, 0x02, 0x52, 0x50, 0x02, 0x52, 0x50, 0x02, 0x52, + 0x50, 0x02, 0x52, 0x50, 0x02, 0x52, 0x50, 0x02, 0x52, 0x50, 0x21, 0x28, + 0xa0, 0x62, 0x53, 0x68, 0x10, 0x94, 0x94, 0x08, 0x4a, 0x4a, 0x06, 0x25, + 0x25, 0x02, 0x12, 0x8a, 0x00, 0x4a, 0x28, 0x10, 0x94, 0x94, 0x00, 0x94, + 0x53, 0x10, 0x94, 0x94, 0x0c, 0x4a, 0x4a, 0x09, 0x12, 0x92, 0x98, 0x05, + 0x2a, 0xf5, 0xa0, 0x07, 0xd1, 0x4c, 0x91, 0x28, 0xa0, 0x42, 0x52, 0x50, + 0x01, 0x45, 0x00, 0x25, 0x36, 0x80, 0x0a, 0x29, 0x88, 0x4a, 0x29, 0x08, + 0x43, 0x45, 0x20, 0x1b, 0x45, 0x00, 0x73, 0xf4, 0x50, 0x74, 0x8e, 0x53, + 0x5d, 0x0f, 0x87, 0xdf, 0x74, 0x0c, 0x87, 0xb0, 0xcf, 0xeb, 0x59, 0x54, + 0x45, 0xa3, 0x4f, 0xb5, 0x5e, 0xb4, 0x3f, 0x2d, 0x53, 0x24, 0xb3, 0x4b, + 0x4c, 0x41, 0x45, 0x00, 0x2d, 0x14, 0x08, 0x28, 0xa0, 0x02, 0x96, 0x81, + 0x85, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, 0x00, 0x52, 0x50, 0x30, 0xa2, + 0x81, 0x05, 0x14, 0x0c, 0x29, 0x28, 0x01, 0x69, 0x28, 0x00, 0xa4, 0xa0, + 0x02, 0x8a, 0x00, 0x4a, 0x28, 0x01, 0x28, 0xa0, 0x04, 0xa2, 0x80, 0x12, + 0x92, 0x80, 0x12, 0x92, 0x80, 0x12, 0x92, 0x80, 0x12, 0x92, 0x80, 0x12, + 0x92, 0x80, 0x12, 0x92, 0x80, 0x12, 0x92, 0x80, 0x0a, 0x6d, 0x00, 0x25, + 0x25, 0x02, 0x12, 0x92, 0x80, 0x1b, 0x45, 0x02, 0x12, 0x92, 0x98, 0x09, + 0x49, 0x40, 0x05, 0x25, 0x02, 0x12, 0x92, 0x80, 0x0a, 0x4a, 0x42, 0x10, + 0xd2, 0x53, 0x01, 0x29, 0x28, 0x00, 0xa6, 0xd0, 0x20, 0xa5, 0x1d, 0x69, + 0x80, 0xfa, 0x29, 0x92, 0x25, 0x25, 0x31, 0x05, 0x25, 0x00, 0x25, 0x14, + 0x00, 0x94, 0x50, 0x21, 0x28, 0xa4, 0x02, 0x51, 0x4c, 0x04, 0xa4, 0xa4, + 0x01, 0x45, 0x22, 0x4e, 0x76, 0x92, 0x9d, 0xb5, 0x3a, 0x87, 0x0a, 0xd9, + 0xf0, 0xec, 0x9f, 0xe9, 0x32, 0x2f, 0xf7, 0xb6, 0x8f, 0xd6, 0xb2, 0xa8, + 0x5c, 0x0d, 0xda, 0xb5, 0x66, 0x79, 0xc5, 0x36, 0x4a, 0x2e, 0xd2, 0xd3, + 0x10, 0xb4, 0x94, 0x08, 0x5a, 0x5a, 0x00, 0x4a, 0x28, 0x18, 0xb4, 0x53, + 0x00, 0xa2, 0x90, 0x05, 0x14, 0xc0, 0x28, 0xa4, 0x01, 0x45, 0x03, 0x0a, + 0x28, 0x10, 0x51, 0x40, 0xc2, 0x92, 0x81, 0x05, 0x14, 0x0c, 0x29, 0x28, + 0x00, 0xa2, 0x80, 0x0a, 0x4a, 0x00, 0x29, 0x28, 0x00, 0xa4, 0xa0, 0x04, + 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, + 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, + 0xa4, 0xa0, 0x42, 0x52, 0x50, 0x02, 0x53, 0x69, 0x88, 0x4a, 0x4a, 0x40, + 0x25, 0x25, 0x00, 0x14, 0x53, 0x10, 0x94, 0x94, 0x00, 0x94, 0x94, 0x80, + 0x4a, 0x4a, 0x62, 0x0a, 0x6d, 0x02, 0x12, 0x92, 0x98, 0x05, 0x2a, 0xd2, + 0x02, 0x4a, 0x4a, 0xa2, 0x44, 0xa4, 0xa0, 0x41, 0x49, 0x4c, 0x02, 0x92, + 0x81, 0x89, 0x45, 0x21, 0x09, 0x45, 0x32, 0x44, 0xa4, 0xa0, 0x02, 0x8a, + 0x40, 0x25, 0x14, 0x86, 0x73, 0x94, 0xb4, 0x23, 0xa0, 0x4c, 0xd6, 0x86, + 0x8a, 0xf8, 0xd4, 0x61, 0xff, 0x00, 0x7c, 0x54, 0x54, 0xd8, 0xd2, 0x9e, + 0xe7, 0x51, 0xe9, 0x53, 0xda, 0xff, 0x00, 0xac, 0xa5, 0xba, 0x20, 0xd0, + 0x14, 0xb5, 0x42, 0x16, 0x8a, 0x04, 0x2d, 0x14, 0x0c, 0x28, 0xa0, 0x02, + 0x8a, 0x00, 0x5a, 0x28, 0x00, 0xa2, 0x80, 0x0a, 0x28, 0x18, 0x51, 0x40, + 0x05, 0x14, 0xc0, 0x28, 0xa4, 0x02, 0x52, 0xd0, 0x02, 0x51, 0x40, 0x05, + 0x14, 0x00, 0x52, 0x50, 0x01, 0x49, 0x40, 0x05, 0x14, 0x00, 0x94, 0x94, + 0x00, 0x94, 0x94, 0x00, 0x53, 0x68, 0x00, 0xa4, 0xa0, 0x06, 0xd2, 0x50, + 0x02, 0x52, 0x50, 0x02, 0x52, 0x50, 0x02, 0x52, 0x50, 0x02, 0x52, 0x50, + 0x02, 0x52, 0x50, 0x02, 0x53, 0x68, 0x01, 0x29, 0x28, 0x10, 0x94, 0x94, + 0x08, 0x6d, 0x25, 0x30, 0x0a, 0x29, 0x00, 0x94, 0x94, 0x08, 0x4a, 0x4a, + 0x60, 0x25, 0x14, 0x84, 0x36, 0x8a, 0x00, 0x4a, 0x4a, 0x62, 0x12, 0x94, + 0x52, 0x02, 0x4a, 0x4a, 0xb2, 0x44, 0xa2, 0x98, 0x84, 0xa2, 0x90, 0x09, + 0x49, 0x40, 0x09, 0x45, 0x02, 0x12, 0x8a, 0x04, 0x25, 0x14, 0x00, 0x94, + 0x94, 0x00, 0x51, 0x49, 0x01, 0xcd, 0x52, 0xd3, 0xb1, 0xd4, 0x15, 0x62, + 0xc9, 0xfc, 0xbb, 0x84, 0x7f, 0xee, 0xf3, 0x51, 0x3d, 0x8a, 0x8e, 0xe7, + 0x62, 0x3e, 0xe2, 0x7f, 0xba, 0x3f, 0x95, 0x4b, 0x0f, 0x12, 0x0a, 0x95, + 0xf0, 0x93, 0xd4, 0xd2, 0x5e, 0x94, 0xea, 0xa1, 0x0b, 0x45, 0x00, 0x14, + 0x50, 0x21, 0x68, 0xa0, 0x02, 0x8a, 0x06, 0x14, 0x53, 0x00, 0xa2, 0x90, + 0x05, 0x2d, 0x00, 0x25, 0x14, 0x00, 0x51, 0x40, 0xc5, 0xa2, 0x80, 0x12, + 0x8a, 0x00, 0x28, 0xa0, 0x02, 0x8a, 0x00, 0x29, 0x28, 0x00, 0xa2, 0x80, + 0x12, 0x92, 0x80, 0x0a, 0x4a, 0x00, 0x4a, 0x28, 0x01, 0x29, 0x28, 0x01, + 0x29, 0x28, 0x01, 0x29, 0x28, 0x01, 0xb4, 0x94, 0x00, 0x94, 0x94, 0x00, + 0x94, 0x94, 0x00, 0x94, 0x94, 0x00, 0x94, 0x94, 0x08, 0x6d, 0x25, 0x00, + 0x25, 0x25, 0x00, 0x36, 0x92, 0x81, 0x09, 0x49, 0x40, 0x09, 0x45, 0x00, + 0x14, 0x94, 0x00, 0x94, 0x94, 0x08, 0x4a, 0x4a, 0x00, 0x4a, 0x4a, 0x04, + 0x25, 0x25, 0x31, 0x05, 0x14, 0x01, 0x25, 0x25, 0x31, 0x09, 0x45, 0x31, + 0x09, 0x45, 0x00, 0x25, 0x14, 0x12, 0x25, 0x25, 0x00, 0x14, 0x94, 0xc0, + 0x4a, 0x29, 0x08, 0x4a, 0x4a, 0x00, 0x29, 0x28, 0x03, 0x9c, 0xa2, 0xa4, + 0xea, 0x0a, 0x50, 0xdc, 0x7e, 0x14, 0xa5, 0xb0, 0xe2, 0x76, 0xb6, 0xef, + 0xe6, 0xdb, 0xab, 0x7e, 0x1f, 0xa0, 0xa9, 0x97, 0xae, 0x6a, 0x21, 0xf0, + 0x83, 0xdc, 0xd3, 0x8f, 0xee, 0xd4, 0x95, 0x68, 0x90, 0xa2, 0x80, 0x16, + 0x8a, 0x00, 0x28, 0xa0, 0x02, 0x96, 0x80, 0x0a, 0x28, 0x00, 0xa2, 0x81, + 0x85, 0x2d, 0x02, 0x12, 0x8a, 0x06, 0x14, 0x50, 0x01, 0x45, 0x00, 0x14, + 0x50, 0x01, 0x45, 0x00, 0x14, 0x50, 0x01, 0x49, 0x40, 0x05, 0x14, 0x00, + 0x94, 0x50, 0x01, 0x49, 0x40, 0x09, 0x49, 0x40, 0x09, 0x49, 0x40, 0x09, + 0x49, 0x40, 0x09, 0x49, 0x40, 0x09, 0x4d, 0xa0, 0x04, 0xa4, 0xa0, 0x04, + 0xa4, 0xa0, 0x06, 0xd2, 0x50, 0x02, 0x52, 0x50, 0x21, 0x29, 0x28, 0x01, + 0xb4, 0x50, 0x03, 0x69, 0x28, 0x01, 0x29, 0x28, 0x10, 0x94, 0x94, 0x00, + 0x52, 0x50, 0x21, 0x29, 0x28, 0x01, 0x29, 0x28, 0x10, 0x94, 0x94, 0x00, + 0x86, 0x92, 0x98, 0x09, 0x45, 0x02, 0x24, 0xa2, 0xa8, 0x91, 0x28, 0xa0, + 0x42, 0x51, 0x40, 0x09, 0x45, 0x00, 0x25, 0x25, 0x31, 0x09, 0x45, 0x21, + 0x09, 0x45, 0x03, 0x12, 0x8a, 0x62, 0x12, 0x8a, 0x00, 0xe6, 0x8d, 0x2e, + 0x78, 0xa9, 0x3a, 0x80, 0x51, 0x40, 0x2d, 0xce, 0xb7, 0x44, 0x7f, 0x33, + 0x4c, 0x1f, 0xef, 0xb5, 0x5e, 0xed, 0x59, 0x53, 0xd8, 0x72, 0xf8, 0x8d, + 0x2b, 0x7e, 0x52, 0xa5, 0xab, 0x44, 0x8b, 0x4b, 0x40, 0x05, 0x14, 0x00, + 0xb4, 0x94, 0x00, 0xb4, 0x50, 0x01, 0x45, 0x00, 0x14, 0x50, 0x02, 0xd1, + 0x40, 0xc2, 0x8a, 0x00, 0x28, 0xa0, 0x02, 0x8a, 0x00, 0x28, 0xa0, 0x02, + 0x8a, 0x00, 0x28, 0xa0, 0x02, 0x8a, 0x00, 0x29, 0x28, 0x01, 0x28, 0xa0, + 0x04, 0xa2, 0x80, 0x12, 0x92, 0x80, 0x12, 0x92, 0x80, 0x12, 0x92, 0x80, + 0x12, 0x92, 0x80, 0x1b, 0x49, 0x40, 0x09, 0x49, 0x40, 0x09, 0x49, 0x40, + 0x0d, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa6, 0xd0, 0x02, 0x52, 0x50, + 0x21, 0x29, 0x28, 0x10, 0xda, 0x4a, 0x00, 0x29, 0x28, 0x01, 0x29, 0x28, + 0x10, 0x94, 0x94, 0x00, 0x94, 0x94, 0x00, 0x94, 0x94, 0xc4, 0x25, 0x25, + 0x02, 0x12, 0x8a, 0x40, 0x49, 0x45, 0x50, 0x84, 0xa4, 0xa6, 0x48, 0x52, + 0x53, 0x00, 0xa4, 0xa4, 0x01, 0x49, 0x40, 0x82, 0x92, 0x81, 0x09, 0x45, + 0x21, 0x89, 0x45, 0x31, 0x09, 0x45, 0x20, 0x39, 0xaa, 0x5e, 0x94, 0xec, + 0x75, 0x0a, 0x29, 0x31, 0x4a, 0xc0, 0x74, 0x7e, 0x19, 0x7c, 0xc3, 0x24, + 0x7f, 0xdd, 0x19, 0xff, 0x00, 0xc7, 0xab, 0x66, 0xb3, 0xa7, 0xd8, 0xa9, + 0xee, 0x5d, 0xb3, 0x6f, 0x92, 0xad, 0x55, 0x22, 0x18, 0xb4, 0x50, 0x01, + 0x4b, 0x40, 0x82, 0x8a, 0x06, 0x14, 0x53, 0x00, 0xa2, 0x90, 0x0b, 0x45, + 0x00, 0x14, 0x50, 0x30, 0xa5, 0xa0, 0x02, 0x8a, 0x00, 0x28, 0xa0, 0x02, + 0x8a, 0x00, 0x28, 0xa0, 0x02, 0x8a, 0x00, 0x28, 0xa0, 0x04, 0xa2, 0x80, + 0x12, 0x8a, 0x00, 0x29, 0x28, 0x01, 0x29, 0x28, 0x00, 0xa4, 0xa0, 0x06, + 0xd2, 0x50, 0x02, 0x52, 0x50, 0x02, 0x53, 0x68, 0x01, 0x29, 0x28, 0x01, + 0x29, 0xb4, 0x00, 0x94, 0x94, 0x00, 0x94, 0xda, 0x00, 0x29, 0xb4, 0x08, + 0x4a, 0x69, 0xa0, 0x04, 0xa4, 0xa0, 0x42, 0x52, 0x50, 0x02, 0x52, 0x50, + 0x02, 0x51, 0x40, 0x0d, 0xa4, 0xa6, 0x21, 0x29, 0x29, 0x00, 0x94, 0x94, + 0xc4, 0x06, 0x9b, 0x40, 0x09, 0x45, 0x02, 0x1f, 0x45, 0x32, 0x44, 0xa2, + 0x98, 0x05, 0x25, 0x00, 0x14, 0x50, 0x21, 0x29, 0x29, 0x80, 0x94, 0x50, + 0x21, 0x28, 0xa0, 0x02, 0x92, 0x90, 0x84, 0xa2, 0x98, 0x1c, 0xd5, 0x25, + 0x23, 0xa8, 0x70, 0xe9, 0x4b, 0x48, 0x0d, 0x9f, 0x0e, 0x49, 0xfe, 0x99, + 0x27, 0xfb, 0x5b, 0x57, 0xf5, 0xae, 0x88, 0x56, 0x50, 0xea, 0x54, 0xcb, + 0x56, 0x47, 0x9c, 0x55, 0xda, 0xa4, 0x4b, 0x16, 0x8a, 0x62, 0x16, 0x8a, + 0x00, 0x28, 0xa0, 0x02, 0x96, 0x98, 0x05, 0x14, 0x86, 0x14, 0x50, 0x21, + 0x68, 0xa0, 0x61, 0x45, 0x00, 0x2d, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, + 0x00, 0x51, 0x40, 0x05, 0x14, 0x00, 0x51, 0x40, 0x09, 0x45, 0x00, 0x14, + 0x94, 0x00, 0x52, 0x50, 0x02, 0x51, 0x40, 0x09, 0x49, 0x40, 0x09, 0x49, + 0x40, 0x0d, 0xa4, 0xa0, 0x04, 0xa6, 0xd0, 0x02, 0x52, 0x50, 0x02, 0x53, + 0x68, 0x01, 0x29, 0xb4, 0x00, 0x94, 0x94, 0x00, 0x94, 0x94, 0x00, 0xda, + 0x4a, 0x04, 0x25, 0x25, 0x00, 0x25, 0x25, 0x00, 0x25, 0x25, 0x02, 0x1b, + 0x45, 0x00, 0x25, 0x36, 0x81, 0x05, 0x21, 0xa0, 0x06, 0xd1, 0x40, 0x86, + 0xd2, 0x50, 0x02, 0x52, 0x50, 0x04, 0x9d, 0xa9, 0x2a, 0x90, 0x98, 0x52, + 0x53, 0x24, 0x28, 0xa0, 0x41, 0x49, 0x40, 0xc2, 0x8a, 0x04, 0x25, 0x25, + 0x30, 0x12, 0x92, 0x90, 0x85, 0xa4, 0xa4, 0x02, 0x51, 0x48, 0x0e, 0x62, + 0x96, 0xad, 0x9d, 0x21, 0x4a, 0x33, 0xde, 0x96, 0x80, 0x68, 0x68, 0x8f, + 0xb3, 0x53, 0x83, 0xde, 0x41, 0x5d, 0x68, 0xac, 0x97, 0xc4, 0x54, 0xb6, + 0x44, 0xf6, 0xa7, 0x12, 0xd6, 0x88, 0xe9, 0x54, 0x48, 0x52, 0xd0, 0x20, + 0xa2, 0x80, 0x16, 0x8a, 0x00, 0x28, 0xa6, 0x01, 0x4b, 0x48, 0x02, 0x8a, + 0x06, 0x14, 0xb4, 0x00, 0x51, 0x40, 0x05, 0x2d, 0x00, 0x14, 0x50, 0x01, + 0x45, 0x00, 0x14, 0x50, 0x01, 0x4b, 0x40, 0x09, 0x45, 0x00, 0x14, 0x94, + 0x00, 0x52, 0x52, 0x00, 0xa4, 0xa6, 0x02, 0x51, 0x40, 0x09, 0x49, 0x40, + 0x09, 0x49, 0x40, 0x0d, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x06, 0xd2, 0x50, + 0x03, 0x69, 0x28, 0x01, 0x0d, 0x36, 0x80, 0x12, 0x9b, 0x40, 0x09, 0x49, + 0x40, 0x09, 0x4d, 0xa0, 0x42, 0x52, 0x50, 0x02, 0x52, 0x1a, 0x00, 0x4a, + 0x6d, 0x00, 0x25, 0x14, 0x08, 0x6d, 0x25, 0x00, 0x25, 0x14, 0xc4, 0x36, + 0x92, 0x90, 0x84, 0xa4, 0xa6, 0x21, 0x29, 0x29, 0x00, 0xf1, 0x45, 0x31, + 0x05, 0x25, 0x31, 0x05, 0x25, 0x50, 0x85, 0xa4, 0xa4, 0x30, 0xa4, 0xa4, + 0x21, 0x28, 0xaa, 0x01, 0x29, 0x29, 0x12, 0x14, 0x52, 0xb8, 0xc4, 0xa4, + 0xa6, 0x17, 0x39, 0xaa, 0x4a, 0x47, 0x48, 0x52, 0x8a, 0x56, 0x02, 0x7b, + 0x39, 0x3c, 0xab, 0xa8, 0xe4, 0xfe, 0xef, 0x3f, 0xa5, 0x76, 0xeb, 0xf7, + 0x13, 0xfd, 0xd1, 0xfc, 0xab, 0x3f, 0xb6, 0x5c, 0xbe, 0x12, 0x48, 0xb8, + 0x90, 0x56, 0x9a, 0xf4, 0xaa, 0xea, 0x40, 0xb4, 0xb4, 0xc4, 0x14, 0xb4, + 0xc0, 0x28, 0xa4, 0x01, 0x45, 0x00, 0x2d, 0x14, 0x0c, 0x28, 0xa0, 0x42, + 0xd1, 0x40, 0xc2, 0x8a, 0x00, 0x29, 0x68, 0x00, 0xa2, 0x80, 0x0a, 0x5a, + 0x00, 0x28, 0xa0, 0x02, 0x8a, 0x00, 0x28, 0xa0, 0x04, 0xa2, 0x80, 0x0a, + 0x4a, 0x00, 0x29, 0x28, 0x01, 0x28, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa4, + 0xa0, 0x04, 0xa6, 0xd0, 0x02, 0x52, 0x50, 0x03, 0x69, 0x28, 0x01, 0xb4, + 0x94, 0x00, 0xda, 0x4a, 0x00, 0x6d, 0x25, 0x00, 0x25, 0x36, 0x80, 0x12, + 0x92, 0x81, 0x0d, 0xa2, 0x80, 0x1b, 0x49, 0x40, 0x0d, 0xa4, 0xa0, 0x04, + 0xa2, 0x81, 0x0d, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, 0x91, + 0x29, 0xb4, 0xc0, 0x4a, 0x4a, 0x40, 0x3b, 0xb5, 0x2d, 0x32, 0x44, 0xa2, + 0x81, 0x05, 0x2d, 0x50, 0x84, 0xa2, 0x90, 0x09, 0x49, 0x4c, 0x05, 0xa4, + 0xa6, 0x21, 0x29, 0x29, 0x00, 0x52, 0x54, 0x80, 0x51, 0x40, 0x8e, 0x6f, + 0x63, 0x51, 0xe5, 0x9a, 0xd5, 0x9d, 0x43, 0x71, 0x8a, 0x75, 0x64, 0x03, + 0x4f, 0xdd, 0x3c, 0xf6, 0xae, 0xea, 0xd9, 0xfc, 0xcb, 0x65, 0x6f, 0xc3, + 0xf4, 0x15, 0x1f, 0x6c, 0xbb, 0xfb, 0xa4, 0xc3, 0xad, 0x6a, 0x27, 0xdd, + 0xaa, 0x7b, 0x90, 0x3a, 0x9d, 0x4c, 0x41, 0x45, 0x20, 0x0a, 0x29, 0x80, + 0xb4, 0x50, 0x01, 0x45, 0x20, 0x0a, 0x5a, 0x06, 0x14, 0x50, 0x02, 0xd1, + 0x40, 0x05, 0x14, 0x00, 0xb4, 0x50, 0x01, 0x45, 0x00, 0x14, 0x50, 0x02, + 0xd1, 0x40, 0x05, 0x14, 0x00, 0x51, 0x40, 0x09, 0x49, 0x40, 0x05, 0x25, + 0x00, 0x25, 0x14, 0x00, 0x94, 0x94, 0x00, 0x94, 0x94, 0x80, 0x4a, 0x4a, + 0x60, 0x36, 0x92, 0x80, 0x1b, 0x49, 0x40, 0x0d, 0xa6, 0xd0, 0x02, 0x53, + 0x68, 0x01, 0x29, 0xb4, 0x00, 0x94, 0x94, 0x00, 0x94, 0xda, 0x00, 0x69, + 0xa4, 0x34, 0x08, 0x4a, 0x69, 0xa0, 0x04, 0xa4, 0xa0, 0x04, 0xa4, 0xa0, + 0x42, 0x52, 0x50, 0x02, 0x52, 0x50, 0x21, 0x29, 0x28, 0x01, 0x29, 0xb4, + 0xc0, 0x43, 0x49, 0x48, 0x07, 0x0a, 0x29, 0x92, 0x25, 0x2d, 0x31, 0x05, + 0x25, 0x31, 0x0b, 0x49, 0x40, 0x05, 0x14, 0x84, 0x25, 0x14, 0xc4, 0x25, + 0x25, 0x00, 0x14, 0x94, 0x08, 0x29, 0x31, 0x48, 0x66, 0x16, 0xf1, 0xdc, + 0x53, 0xc4, 0x8b, 0xf8, 0x55, 0x33, 0xa4, 0x3e, 0x43, 0x4d, 0xd8, 0xb4, + 0xae, 0x03, 0x4c, 0x60, 0xd7, 0x55, 0xa2, 0x36, 0xed, 0x34, 0x7f, 0xbe, + 0xd5, 0x9b, 0xf8, 0x91, 0x4b, 0xe1, 0x2f, 0x76, 0xad, 0x38, 0x0f, 0xc9, + 0x4d, 0xee, 0x49, 0x2d, 0x2d, 0x02, 0x0a, 0x29, 0x80, 0xb4, 0x52, 0x00, + 0xa2, 0x98, 0x05, 0x2d, 0x00, 0x14, 0xb4, 0x0c, 0x4a, 0x5a, 0x40, 0x14, + 0x50, 0x02, 0xd1, 0x40, 0x05, 0x2d, 0x00, 0x14, 0x50, 0x01, 0x4b, 0x40, + 0x05, 0x14, 0x00, 0x51, 0x40, 0x05, 0x25, 0x00, 0x14, 0x94, 0x00, 0x51, + 0x40, 0x09, 0x49, 0x40, 0x09, 0x49, 0x40, 0x05, 0x25, 0x00, 0x36, 0x92, + 0x90, 0x09, 0x4d, 0xa6, 0x03, 0x69, 0x28, 0x01, 0xb4, 0xd3, 0x40, 0x0d, + 0xa6, 0xd0, 0x02, 0x52, 0x50, 0x03, 0x69, 0x28, 0x01, 0x29, 0xb4, 0x00, + 0xd3, 0x4d, 0xa0, 0x04, 0xa4, 0xa0, 0x42, 0x53, 0x68, 0x00, 0xa4, 0xa0, + 0x04, 0xa6, 0xd0, 0x21, 0x29, 0x28, 0x01, 0x29, 0x28, 0x01, 0x29, 0x28, + 0x24, 0x4a, 0x4a, 0x00, 0x51, 0x4b, 0x4c, 0x42, 0x51, 0x4c, 0x41, 0x45, + 0x00, 0x2d, 0x25, 0x04, 0x89, 0x45, 0x30, 0x0a, 0x4a, 0x04, 0x25, 0x14, + 0x00, 0x94, 0x51, 0x70, 0x12, 0x8a, 0x04, 0x73, 0xa4, 0xd2, 0x66, 0x9d, + 0x8e, 0xa0, 0xcd, 0x2e, 0xef, 0x7a, 0x90, 0x1f, 0x9a, 0xe8, 0xbc, 0x37, + 0x26, 0x60, 0x74, 0xcf, 0x40, 0x4f, 0xfe, 0x3d, 0x59, 0x4b, 0xa1, 0x6b, + 0x63, 0x62, 0xaf, 0x59, 0x9c, 0xa5, 0x5c, 0x88, 0x2c, 0xd2, 0xd3, 0x10, + 0x51, 0x48, 0x05, 0xa2, 0x80, 0x0a, 0x5a, 0x06, 0x14, 0x50, 0x20, 0xa5, + 0xa0, 0x61, 0x45, 0x00, 0x2d, 0x14, 0x00, 0x51, 0x40, 0x0b, 0x45, 0x00, + 0x14, 0xb4, 0x00, 0x51, 0x40, 0x05, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, + 0x00, 0x94, 0x52, 0x00, 0xa4, 0xa6, 0x01, 0x49, 0x48, 0x02, 0x92, 0x80, + 0x12, 0x92, 0x98, 0x09, 0x4d, 0xa0, 0x04, 0xa6, 0xd0, 0x02, 0x53, 0x4d, + 0x20, 0x1a, 0x69, 0xb4, 0xc0, 0x61, 0xa4, 0xa0, 0x06, 0xd3, 0x68, 0x01, + 0x29, 0xb4, 0x80, 0x6d, 0x36, 0x80, 0x12, 0x92, 0x80, 0x1b, 0x45, 0x30, + 0x12, 0x92, 0x80, 0x12, 0x92, 0x81, 0x09, 0x4d, 0xa4, 0x02, 0x52, 0x53, + 0x01, 0x29, 0x28, 0x24, 0x6d, 0x25, 0x00, 0x25, 0x25, 0x02, 0x0a, 0x75, + 0x02, 0x12, 0x8a, 0x60, 0x14, 0x50, 0x21, 0x68, 0xa6, 0x21, 0x28, 0xa6, + 0x02, 0x51, 0x40, 0x84, 0xa2, 0x90, 0x84, 0xa2, 0x80, 0x12, 0x8a, 0x62, + 0x39, 0xb6, 0xa6, 0xd5, 0x33, 0xa8, 0x5a, 0x5c, 0xd6, 0x7a, 0x85, 0xc7, + 0x56, 0xcf, 0x86, 0x24, 0xff, 0x00, 0x4a, 0x91, 0x7d, 0x42, 0x8f, 0xd6, + 0xa2, 0x65, 0x44, 0xe9, 0x2a, 0xdd, 0x97, 0x71, 0x57, 0x32, 0x11, 0x76, + 0x8a, 0x00, 0x29, 0x68, 0x00, 0xa2, 0x90, 0x05, 0x2d, 0x03, 0x0a, 0x5a, + 0x00, 0x28, 0xa0, 0x02, 0x96, 0x80, 0x0a, 0x28, 0x01, 0x68, 0xa0, 0x05, + 0xa2, 0x80, 0x0a, 0x5a, 0x00, 0x4a, 0x5a, 0x00, 0x28, 0xa0, 0x02, 0x8a, + 0x06, 0x14, 0x94, 0x00, 0x52, 0x50, 0x01, 0x45, 0x20, 0x12, 0x8a, 0x00, + 0x4a, 0x28, 0x10, 0x94, 0x94, 0x00, 0x94, 0xda, 0x00, 0x4a, 0x6d, 0x30, + 0x12, 0x9a, 0x68, 0x01, 0x86, 0x9a, 0x68, 0x01, 0xa6, 0x9b, 0x40, 0x0d, + 0x34, 0xda, 0x90, 0x1b, 0x4d, 0xa0, 0x06, 0xd3, 0x68, 0x01, 0x29, 0x28, + 0x00, 0xa6, 0xd3, 0x01, 0x29, 0x28, 0x01, 0x28, 0xdb, 0x40, 0x06, 0xda, + 0x4d, 0xb4, 0x08, 0x42, 0x2a, 0x33, 0x4c, 0x43, 0x68, 0xa4, 0x02, 0x52, + 0x53, 0x10, 0x94, 0xda, 0x00, 0x51, 0x4b, 0x40, 0x84, 0xa2, 0x82, 0x42, + 0x8a, 0xa0, 0x16, 0x8a, 0x62, 0x0a, 0x4a, 0x04, 0x14, 0x50, 0x02, 0x51, + 0x48, 0x04, 0xa2, 0x98, 0x84, 0xa2, 0x81, 0x1c, 0xd9, 0xa6, 0xd6, 0x96, + 0xb1, 0xd2, 0x14, 0x56, 0x4d, 0x8c, 0x5a, 0xd2, 0xd0, 0x5f, 0x6e, 0xad, + 0x07, 0xbb, 0x8a, 0x8a, 0x9a, 0xa2, 0xa0, 0x75, 0xc3, 0xa5, 0x58, 0xb4, + 0x3f, 0xbc, 0xaa, 0x96, 0xc4, 0xa3, 0x43, 0xb5, 0x14, 0x21, 0x0b, 0x45, + 0x00, 0x14, 0x50, 0x31, 0x68, 0xa4, 0x20, 0xa5, 0xa0, 0x61, 0x45, 0x00, + 0x2d, 0x14, 0x00, 0xb4, 0x50, 0x02, 0xd1, 0x40, 0x05, 0x2d, 0x00, 0x14, + 0x50, 0x01, 0x4b, 0x40, 0x09, 0x45, 0x00, 0x14, 0x50, 0x30, 0xa2, 0x80, + 0x0a, 0x4a, 0x40, 0x14, 0x94, 0x00, 0x52, 0x50, 0x20, 0xa4, 0xa0, 0x62, + 0x52, 0x50, 0x20, 0xa4, 0xa0, 0x06, 0xd2, 0x50, 0x03, 0x69, 0xa6, 0x98, + 0x0c, 0x34, 0xce, 0xf8, 0xf5, 0xa0, 0x08, 0x16, 0x5d, 0xc7, 0x14, 0xea, + 0x4c, 0x06, 0xd3, 0x69, 0x00, 0xda, 0x6d, 0x00, 0x36, 0x9b, 0x40, 0x09, + 0xba, 0x96, 0x80, 0x0c, 0x66, 0x93, 0x14, 0xc0, 0x4a, 0x6e, 0x68, 0x10, + 0x99, 0xa3, 0x75, 0x2b, 0x80, 0xdd, 0xe2, 0x93, 0x7d, 0x3b, 0x80, 0xc3, + 0x20, 0xa4, 0x6a, 0x2e, 0x21, 0x94, 0x50, 0x31, 0x28, 0xa6, 0x21, 0xb4, + 0x94, 0x08, 0x4a, 0x5a, 0x04, 0x14, 0x53, 0x10, 0x52, 0xd2, 0x10, 0x51, + 0x54, 0x48, 0x51, 0x40, 0x09, 0x45, 0x30, 0x12, 0x96, 0xa4, 0x04, 0xa4, + 0xa6, 0x20, 0xa4, 0xa1, 0x01, 0xce, 0x37, 0x5e, 0x29, 0xb8, 0xad, 0xeb, + 0x7c, 0x4c, 0xe9, 0x12, 0x96, 0xb0, 0x00, 0xab, 0x36, 0x12, 0x79, 0x57, + 0x90, 0xc9, 0xfd, 0xd3, 0x9f, 0xd2, 0xa6, 0x7b, 0x15, 0x0d, 0xce, 0xe1, + 0x7e, 0xe2, 0x7f, 0xba, 0x3f, 0x95, 0x4d, 0x07, 0x12, 0x8a, 0x7f, 0x60, + 0x9e, 0xa6, 0x90, 0xe9, 0x4b, 0x42, 0x10, 0x51, 0x40, 0x0b, 0x45, 0x00, + 0x14, 0x50, 0x31, 0x68, 0xa4, 0x01, 0x4b, 0x40, 0x05, 0x2d, 0x00, 0x14, + 0x50, 0x02, 0xd1, 0x40, 0x0b, 0x45, 0x00, 0x14, 0x50, 0x02, 0xd1, 0x40, + 0x05, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, 0x0c, 0x4a, 0x29, 0x00, 0x94, + 0x50, 0x01, 0x4d, 0xa0, 0x02, 0x8a, 0x04, 0x25, 0x25, 0x00, 0x25, 0x25, + 0x30, 0x0a, 0x69, 0xa0, 0x06, 0xd3, 0x71, 0x9a, 0x00, 0x5f, 0x28, 0xfa, + 0x54, 0x32, 0xdb, 0x4a, 0x4a, 0xed, 0x1d, 0x29, 0xa0, 0x21, 0x5b, 0x09, + 0x95, 0xf7, 0x71, 0xf9, 0xd4, 0x8d, 0x1e, 0x3a, 0xd2, 0x60, 0x42, 0xd5, + 0x19, 0xa4, 0x02, 0x1a, 0x6d, 0x48, 0x0c, 0x34, 0xc3, 0x4c, 0x08, 0x9d, + 0xb1, 0x53, 0x7f, 0x0d, 0x00, 0x34, 0x1a, 0x5c, 0xd3, 0x01, 0x8e, 0xf8, + 0x15, 0x4c, 0xde, 0x0d, 0xf8, 0xe9, 0x45, 0x84, 0x3f, 0xcd, 0xa8, 0xfc, + 0xef, 0x9f, 0x19, 0xa4, 0x21, 0xcc, 0x78, 0xa8, 0x43, 0xf3, 0xcd, 0x21, + 0x11, 0xca, 0x70, 0xe1, 0xbd, 0x2a, 0xef, 0xf0, 0x0f, 0xa5, 0x30, 0x19, + 0x45, 0x31, 0x89, 0x49, 0x4c, 0x02, 0x92, 0x81, 0x0d, 0xa2, 0x81, 0x0b, + 0x45, 0x32, 0x45, 0xa2, 0x98, 0x05, 0x2d, 0x21, 0x09, 0x4b, 0x4c, 0x42, + 0x51, 0x40, 0x84, 0xa2, 0x80, 0x0a, 0x4a, 0x00, 0x4a, 0x29, 0x81, 0xce, + 0x51, 0xb4, 0xd5, 0xb6, 0x74, 0x86, 0xda, 0x36, 0xd6, 0x63, 0x48, 0x00, + 0xa3, 0xee, 0xe4, 0x8f, 0x4a, 0x96, 0x38, 0xee, 0x77, 0x96, 0xcc, 0x1e, + 0xdd, 0x48, 0x3e, 0xdf, 0xa0, 0xa9, 0x97, 0x86, 0x14, 0xd7, 0xc0, 0x4b, + 0xf8, 0x8d, 0x44, 0xfb, 0xb4, 0xea, 0x48, 0x42, 0xd1, 0x4c, 0x02, 0x8a, + 0x00, 0x29, 0x68, 0x00, 0xa2, 0x90, 0xc5, 0xa2, 0x80, 0x0a, 0x28, 0x01, + 0x68, 0xa0, 0x05, 0xa2, 0x80, 0x16, 0x8a, 0x00, 0x29, 0x68, 0x00, 0xa2, + 0x80, 0x0a, 0x28, 0x18, 0x51, 0x40, 0x05, 0x14, 0x80, 0x29, 0x28, 0x00, + 0xa4, 0xa0, 0x02, 0x92, 0x90, 0x05, 0x25, 0x31, 0x05, 0x25, 0x00, 0x25, + 0x25, 0x00, 0x25, 0x25, 0x30, 0x1b, 0x42, 0x7d, 0xf1, 0x40, 0x17, 0x14, + 0xe0, 0x53, 0x5e, 0x5a, 0x00, 0xa9, 0x2c, 0x84, 0xd5, 0x66, 0xa0, 0x08, + 0x1e, 0xa3, 0xa4, 0x02, 0x53, 0x49, 0xa4, 0x04, 0x66, 0x9a, 0x68, 0x02, + 0x19, 0x7a, 0x54, 0x90, 0xbe, 0x62, 0xa1, 0x80, 0x77, 0xa1, 0xce, 0x05, + 0x50, 0x15, 0x5a, 0x5d, 0xdc, 0x54, 0x12, 0x28, 0x54, 0x26, 0x80, 0x14, + 0xfc, 0xe9, 0xc5, 0x34, 0x45, 0xce, 0x6a, 0x09, 0x15, 0x81, 0xc8, 0xa4, + 0xef, 0x40, 0x81, 0x86, 0xe5, 0x23, 0xbd, 0x4e, 0xad, 0x8e, 0x0d, 0x03, + 0x48, 0x43, 0x49, 0x54, 0x30, 0xa2, 0x81, 0x09, 0x49, 0x40, 0x09, 0x49, + 0x40, 0x82, 0x96, 0x99, 0x2c, 0x29, 0x6a, 0x84, 0x14, 0xb4, 0xc4, 0x14, + 0x50, 0x20, 0xa4, 0xa0, 0x41, 0x45, 0x03, 0x12, 0x8a, 0x42, 0x12, 0x8c, + 0xd1, 0xb8, 0x18, 0x0b, 0xef, 0x4e, 0xa0, 0xee, 0x12, 0x99, 0x83, 0x48, + 0x04, 0xa4, 0xaa, 0xe8, 0x66, 0xb7, 0x3b, 0x3d, 0x0e, 0x4f, 0x37, 0x4b, + 0x53, 0xfe, 0xdb, 0x55, 0xea, 0x54, 0xd7, 0xb8, 0x29, 0x7c, 0x46, 0x9c, + 0x07, 0xe4, 0xa9, 0x2a, 0x50, 0x82, 0x96, 0x98, 0x05, 0x2d, 0x00, 0x14, + 0x50, 0x01, 0x4b, 0x48, 0x61, 0x45, 0x00, 0x14, 0xb4, 0xc0, 0x28, 0xa4, + 0x03, 0xa8, 0xa0, 0x02, 0x8a, 0x00, 0x5a, 0x28, 0x00, 0xa2, 0x80, 0x0a, + 0x28, 0x01, 0x69, 0x29, 0x00, 0x51, 0x4c, 0x61, 0x49, 0x40, 0x05, 0x25, + 0x20, 0x0a, 0x28, 0x01, 0x28, 0xa0, 0x04, 0xa2, 0x80, 0x1b, 0x49, 0x40, + 0x84, 0xa6, 0x93, 0x4c, 0x05, 0x48, 0x99, 0xea, 0x65, 0x80, 0x2d, 0x00, + 0x29, 0xa8, 0x9a, 0x80, 0x2b, 0xbd, 0x42, 0x68, 0x02, 0x09, 0x2a, 0x23, + 0x48, 0x06, 0xd3, 0x0d, 0x48, 0x0d, 0xa6, 0x1a, 0x60, 0x43, 0x2f, 0x4a, + 0x4b, 0x57, 0xea, 0x3d, 0x28, 0x60, 0x4a, 0x4d, 0x38, 0xfc, 0xeb, 0x54, + 0x06, 0x63, 0x26, 0xd6, 0xa9, 0x67, 0x1e, 0x64, 0x25, 0x47, 0x71, 0x43, + 0xdc, 0x43, 0x2d, 0xd0, 0xc7, 0x16, 0xd6, 0x39, 0xe4, 0x9a, 0x5f, 0x30, + 0x54, 0x00, 0xc3, 0x32, 0xd3, 0x37, 0xb3, 0x74, 0xa0, 0x40, 0x1d, 0xd1, + 0xd7, 0x7f, 0x4c, 0xd5, 0xae, 0xb4, 0x0c, 0x43, 0x49, 0x54, 0x01, 0x45, + 0x02, 0x12, 0x92, 0x90, 0x84, 0xa4, 0xaa, 0x01, 0x28, 0xcd, 0x04, 0x8b, + 0x9a, 0x75, 0x32, 0x42, 0x96, 0xa8, 0x02, 0x8a, 0x42, 0x0a, 0x4a, 0x04, + 0x14, 0x53, 0x00, 0xa2, 0x81, 0x09, 0x45, 0x20, 0x39, 0xfc, 0xd2, 0x83, + 0x49, 0x9d, 0xd1, 0x1d, 0x9a, 0x61, 0xeb, 0x49, 0x14, 0x34, 0x9a, 0x07, + 0x4a, 0xb4, 0x62, 0xce, 0xa3, 0xc2, 0xf2, 0xee, 0xb5, 0x68, 0xff, 0x00, + 0xbb, 0x96, 0xff, 0x00, 0xc7, 0xab, 0x66, 0xa6, 0x97, 0xc2, 0x13, 0xf8, + 0x8b, 0xd6, 0x87, 0x29, 0x56, 0x29, 0x21, 0x31, 0x68, 0xa6, 0x01, 0x4b, + 0x40, 0x05, 0x14, 0x0c, 0x28, 0xa0, 0x05, 0xa2, 0x80, 0x0a, 0x28, 0x01, + 0x69, 0x69, 0x00, 0x52, 0xd0, 0x01, 0x4b, 0x40, 0x05, 0x14, 0x00, 0x51, + 0x40, 0x0b, 0x45, 0x20, 0x0a, 0x28, 0x18, 0x52, 0x53, 0x00, 0xa4, 0xa0, + 0x61, 0x45, 0x20, 0x0a, 0x28, 0x10, 0x94, 0x94, 0x00, 0x94, 0x94, 0x00, + 0x94, 0x94, 0x08, 0x4a, 0x86, 0x5a, 0x68, 0x0b, 0x96, 0xaf, 0xbe, 0x2a, + 0x94, 0xd1, 0x10, 0x23, 0x6a, 0x85, 0xa8, 0x02, 0x07, 0xa8, 0x1a, 0x80, + 0x20, 0x97, 0xa5, 0x40, 0x4d, 0x4b, 0x01, 0x84, 0xd3, 0x73, 0x48, 0x63, + 0x69, 0xa4, 0xd0, 0x04, 0x0e, 0xd5, 0x52, 0xda, 0x5d, 0xb3, 0xed, 0xcf, + 0x5e, 0x29, 0xbd, 0x80, 0xb8, 0xd2, 0x2f, 0x72, 0x2a, 0x2f, 0xb7, 0x43, + 0x1f, 0xde, 0x6a, 0x40, 0x67, 0xdd, 0xea, 0x11, 0x6e, 0xf9, 0x7f, 0x95, + 0x3a, 0xd6, 0xfa, 0x39, 0x46, 0xd2, 0x7e, 0x61, 0x4a, 0x57, 0x11, 0x66, + 0x47, 0xfd, 0xd9, 0xe7, 0x1c, 0x53, 0x3c, 0xa1, 0x8c, 0xd2, 0xb8, 0x86, + 0x05, 0x19, 0xe9, 0x52, 0x6d, 0x2b, 0xcd, 0x51, 0x23, 0x2e, 0x33, 0xe5, + 0xd3, 0xe0, 0x98, 0x3a, 0x66, 0xa5, 0x8d, 0x13, 0x75, 0xa6, 0xd5, 0xad, + 0x86, 0x14, 0x50, 0x02, 0x52, 0x1a, 0x04, 0x26, 0x69, 0xb9, 0xa1, 0x08, + 0x4c, 0xd2, 0xd5, 0x5c, 0x41, 0x9a, 0x5c, 0xd0, 0x48, 0xb9, 0xa5, 0xa6, + 0x21, 0x68, 0xa6, 0x20, 0xa2, 0x98, 0x05, 0x14, 0x00, 0x94, 0x52, 0x24, + 0x28, 0xa0, 0x67, 0x39, 0xd6, 0x9d, 0xf3, 0x55, 0x58, 0xe9, 0x1f, 0xb4, + 0xf7, 0xa3, 0x61, 0x35, 0x08, 0xab, 0x89, 0xe5, 0xe0, 0xd3, 0x31, 0x83, + 0x55, 0x62, 0x4d, 0xdf, 0x0a, 0x3f, 0xfa, 0x4c, 0xc9, 0xea, 0xa3, 0xff, + 0x00, 0x42, 0xae, 0x92, 0x95, 0x25, 0xba, 0x09, 0x96, 0xec, 0xcd, 0x5c, + 0xa9, 0x00, 0xa2, 0x98, 0x82, 0x8a, 0x00, 0x29, 0x68, 0x18, 0x51, 0x48, + 0x02, 0x96, 0x80, 0x0a, 0x5a, 0x00, 0x5a, 0x29, 0x80, 0x52, 0xd2, 0x00, + 0xa5, 0xa0, 0x02, 0x8a, 0x00, 0x28, 0xa0, 0x05, 0xa2, 0x81, 0x85, 0x14, + 0x80, 0x29, 0x28, 0x00, 0xa2, 0x81, 0x89, 0x45, 0x02, 0x0a, 0x4a, 0x40, + 0x14, 0x94, 0x00, 0x53, 0x69, 0x80, 0x94, 0x94, 0x00, 0xda, 0x86, 0x6e, + 0x94, 0x08, 0x7d, 0x8c, 0x98, 0x97, 0x6f, 0xaf, 0x15, 0xa1, 0x4d, 0x03, + 0x23, 0x6a, 0x85, 0xa9, 0x81, 0x5d, 0xea, 0x07, 0xa4, 0x04, 0x32, 0x74, + 0xaa, 0x84, 0xd4, 0x81, 0x19, 0x6a, 0x89, 0xee, 0x23, 0x5e, 0xae, 0x3f, + 0x3a, 0x91, 0x95, 0xa4, 0xd4, 0xa0, 0x4e, 0xad, 0x55, 0x24, 0xd6, 0x93, + 0xf8, 0x56, 0xab, 0x95, 0xb1, 0x14, 0xe5, 0xd5, 0xe4, 0x6f, 0xba, 0xa0, + 0x55, 0x46, 0xbb, 0x90, 0xb6, 0x7a, 0x53, 0x51, 0x01, 0x8d, 0x3c, 0x8d, + 0xd5, 0xcd, 0x46, 0x49, 0xa6, 0x02, 0x52, 0x86, 0x2a, 0x73, 0x45, 0x80, + 0xd3, 0x4b, 0xcf, 0x3a, 0x06, 0x07, 0xef, 0x55, 0xe5, 0x62, 0x63, 0xac, + 0xb6, 0x18, 0x80, 0xe0, 0xd4, 0xbe, 0x68, 0xc5, 0x16, 0x64, 0x91, 0x33, + 0x13, 0x50, 0xdb, 0x9c, 0x4a, 0x57, 0xf1, 0xaa, 0xe8, 0x4a, 0x2f, 0x25, + 0x21, 0xa1, 0x6c, 0x31, 0x28, 0xa2, 0xc0, 0x25, 0x25, 0x30, 0x1a, 0x4d, + 0x37, 0x34, 0x80, 0x4c, 0xd1, 0x9a, 0x64, 0x8b, 0x46, 0x6a, 0x84, 0x00, + 0xd3, 0xb3, 0x4c, 0x07, 0x66, 0x96, 0x82, 0x45, 0xa2, 0x98, 0x82, 0x92, + 0x81, 0x05, 0x14, 0x00, 0x51, 0x45, 0x80, 0xe7, 0x3a, 0x51, 0xbc, 0x8a, + 0xa6, 0xce, 0x91, 0xde, 0x69, 0xa6, 0x99, 0x18, 0xd2, 0x40, 0x33, 0x71, + 0xa3, 0x34, 0x80, 0xd5, 0xf0, 0xe4, 0x9b, 0x35, 0x58, 0x47, 0xf7, 0x98, + 0x0a, 0xec, 0x3b, 0x52, 0xa7, 0xf1, 0x30, 0xa9, 0xd0, 0xb1, 0x6a, 0x7e, + 0x7a, 0xbd, 0x47, 0x50, 0x0a, 0x29, 0x88, 0x5a, 0x29, 0x00, 0x51, 0x40, + 0x05, 0x2d, 0x21, 0x85, 0x2d, 0x00, 0x14, 0xb4, 0x00, 0x52, 0xd0, 0x02, + 0xd1, 0x40, 0x05, 0x14, 0x00, 0x52, 0xd0, 0x01, 0x45, 0x00, 0x2d, 0x25, + 0x20, 0x16, 0x8a, 0x06, 0x14, 0x94, 0x00, 0x52, 0x50, 0x30, 0xa2, 0x90, + 0x09, 0x45, 0x00, 0x14, 0x94, 0xc0, 0x4a, 0x4a, 0x04, 0x25, 0x36, 0x80, + 0x1b, 0x9a, 0x86, 0x63, 0xf2, 0xd3, 0x11, 0x02, 0x3e, 0xc7, 0x07, 0xd2, + 0xb6, 0x50, 0xee, 0x40, 0x68, 0xea, 0x03, 0x5a, 0xa0, 0x6a, 0x60, 0x40, + 0xf5, 0x5d, 0xea, 0x40, 0x8d, 0xfa, 0x56, 0x73, 0xb7, 0x3d, 0x69, 0x01, + 0x85, 0xab, 0xea, 0x5c, 0x6c, 0x85, 0xfe, 0xb5, 0x90, 0x65, 0x76, 0xea, + 0xd5, 0x62, 0x43, 0x73, 0x49, 0x9a, 0x43, 0x0a, 0x4c, 0xd0, 0x02, 0xd2, + 0x50, 0x20, 0xa2, 0x80, 0x00, 0x7d, 0xeb, 0x5a, 0xca, 0xe8, 0x3a, 0x6c, + 0xfe, 0x2c, 0xd4, 0x4c, 0x65, 0xce, 0xd5, 0x2a, 0xc4, 0x2a, 0x6e, 0x48, + 0xbe, 0x58, 0xaa, 0x73, 0x83, 0x1c, 0xc8, 0xfd, 0xb3, 0xcd, 0x52, 0xd8, + 0x0b, 0x4a, 0xc7, 0x14, 0x67, 0x34, 0x90, 0xc3, 0x34, 0x55, 0x5c, 0x04, + 0x34, 0x94, 0x84, 0x21, 0xa8, 0xe8, 0x01, 0x33, 0x4b, 0x54, 0x21, 0x29, + 0x73, 0x4c, 0x40, 0x29, 0xf4, 0x5c, 0x91, 0xc2, 0x9d, 0x4c, 0x42, 0xd1, + 0x4c, 0x90, 0xa2, 0x90, 0x05, 0x25, 0x50, 0x05, 0x25, 0x24, 0x23, 0x9c, + 0xcd, 0x25, 0x5a, 0x48, 0xea, 0x41, 0x49, 0x48, 0x02, 0x96, 0x86, 0x80, + 0xb7, 0xa5, 0xbf, 0x97, 0xa8, 0xc0, 0xde, 0x8d, 0x9f, 0xd0, 0xd7, 0x74, + 0xbc, 0xc6, 0x87, 0xd5, 0x47, 0xf2, 0xa8, 0x87, 0xf1, 0x02, 0x7b, 0x12, + 0xc1, 0xfe, 0xb0, 0x56, 0x88, 0xe9, 0x47, 0x50, 0x0a, 0x5a, 0x04, 0x14, + 0x50, 0x01, 0x45, 0x00, 0x14, 0xb4, 0x0c, 0x29, 0x68, 0x00, 0xa5, 0xa4, + 0x02, 0xd1, 0x40, 0x0b, 0x45, 0x00, 0x14, 0x50, 0x01, 0x45, 0x00, 0x14, + 0xb4, 0x00, 0x51, 0x40, 0xc2, 0x8a, 0x00, 0x29, 0x29, 0x0c, 0x29, 0x29, + 0x00, 0x51, 0x40, 0x05, 0x25, 0x00, 0x14, 0x94, 0x00, 0x94, 0x99, 0xa6, + 0x21, 0xa4, 0xd4, 0x65, 0xe9, 0x01, 0x13, 0x4a, 0x05, 0x40, 0xf2, 0xe6, + 0x98, 0x10, 0x96, 0xad, 0x5d, 0x3a, 0x6d, 0xf1, 0x6d, 0xcf, 0x23, 0x9a, + 0x43, 0x2c, 0xb5, 0x40, 0xd5, 0x44, 0x90, 0xbd, 0x56, 0x92, 0x80, 0x21, + 0x93, 0xee, 0xd7, 0x35, 0xaa, 0xdc, 0xb4, 0x28, 0x48, 0x26, 0x9c, 0x50, + 0x33, 0x9c, 0x63, 0x97, 0x24, 0xd0, 0x0d, 0x30, 0x16, 0x8a, 0x90, 0x0a, + 0x29, 0x80, 0x52, 0x52, 0x10, 0x51, 0x40, 0xc2, 0x9c, 0xad, 0xb4, 0xe4, + 0x50, 0xc0, 0xd9, 0xb4, 0xbb, 0x59, 0xd3, 0x07, 0xef, 0xd5, 0xd5, 0x6e, + 0x2b, 0x9c, 0x07, 0x8e, 0x45, 0x24, 0x91, 0x6e, 0x5a, 0xd1, 0x09, 0x82, + 0x47, 0xf2, 0xf2, 0x69, 0x7c, 0xae, 0x3e, 0xf5, 0x52, 0x11, 0x17, 0x7a, + 0x28, 0x18, 0x52, 0x52, 0x10, 0xda, 0x61, 0xa4, 0x02, 0x51, 0x4c, 0x42, + 0x52, 0xd5, 0x80, 0x53, 0xb3, 0x45, 0x89, 0x1c, 0x29, 0xc2, 0x82, 0x07, + 0x51, 0x54, 0x20, 0xa2, 0x81, 0x85, 0x14, 0x08, 0x28, 0xa4, 0x07, 0x33, + 0x4b, 0x4d, 0x9d, 0x22, 0xf6, 0xa6, 0xd3, 0x01, 0x73, 0x4b, 0xda, 0x90, + 0x0e, 0x56, 0xda, 0x77, 0x0e, 0xd9, 0xfe, 0x55, 0xe8, 0x16, 0xe7, 0x75, + 0xba, 0x1f, 0x61, 0xfc, 0x85, 0x4a, 0xfe, 0x20, 0x3f, 0x84, 0x99, 0x3e, + 0xf0, 0xad, 0x15, 0xfb, 0xb4, 0xde, 0xe0, 0x3a, 0x8a, 0x62, 0x0a, 0x5a, + 0x40, 0x14, 0x50, 0x01, 0x45, 0x03, 0x0a, 0x5a, 0x40, 0x14, 0xb4, 0x00, + 0x52, 0xd0, 0x01, 0x45, 0x00, 0x2d, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, + 0x0c, 0x4a, 0x29, 0x0c, 0x33, 0x49, 0x9a, 0x40, 0x19, 0xa3, 0x34, 0x86, + 0x14, 0x94, 0xc0, 0x29, 0x68, 0x00, 0xa4, 0xa4, 0x21, 0x29, 0x29, 0x80, + 0x99, 0xa6, 0x3b, 0x60, 0x53, 0x11, 0x55, 0xee, 0x2a, 0xbb, 0x4d, 0xef, + 0x52, 0x02, 0x67, 0x34, 0xc3, 0x4c, 0x64, 0x64, 0xd5, 0xbd, 0x36, 0x6d, + 0xb7, 0x20, 0x7f, 0x7a, 0xa5, 0x94, 0x6c, 0xf6, 0xa8, 0x5e, 0xb4, 0x33, + 0x2b, 0xb5, 0x57, 0x92, 0x80, 0x21, 0x6a, 0xe4, 0xf5, 0xcf, 0xf5, 0x67, + 0xf1, 0xaa, 0x80, 0xa4, 0x60, 0x9a, 0x4a, 0x43, 0x1e, 0x0d, 0x2d, 0x20, + 0x0a, 0x4a, 0x77, 0x00, 0xa2, 0x90, 0x84, 0xcd, 0x1b, 0xa8, 0x18, 0xdc, + 0xd1, 0x9a, 0x00, 0xb3, 0x63, 0x29, 0x49, 0xc7, 0xbd, 0x6b, 0xa4, 0xbc, + 0x72, 0x6b, 0x26, 0x03, 0xd6, 0xee, 0x21, 0xc6, 0xf3, 0x50, 0x49, 0x7c, + 0xe7, 0xa3, 0xe2, 0x9c, 0x22, 0x04, 0x4b, 0x34, 0xb2, 0x7f, 0xcb, 0x43, + 0x53, 0x45, 0x33, 0x35, 0xbc, 0x8a, 0x4f, 0xcc, 0x06, 0x73, 0xf8, 0xd5, + 0xc8, 0x0b, 0x29, 0xf7, 0x29, 0xd5, 0x02, 0x0c, 0xd2, 0x50, 0x02, 0x52, + 0x55, 0x12, 0x36, 0x92, 0x98, 0x05, 0x2d, 0x31, 0x05, 0x2d, 0x02, 0x16, + 0x9c, 0x29, 0xa2, 0x47, 0x52, 0xd5, 0x08, 0x28, 0xa4, 0x26, 0x14, 0x50, + 0x02, 0x51, 0x40, 0x1c, 0xd5, 0x2d, 0x51, 0xd0, 0x26, 0x33, 0x45, 0x26, + 0x86, 0x14, 0xa2, 0x86, 0x80, 0x5f, 0xe1, 0x35, 0xdb, 0xe8, 0xb2, 0xf9, + 0xba, 0x72, 0x9f, 0xf6, 0x8d, 0x45, 0xbd, 0xe4, 0x3f, 0xb0, 0x68, 0x56, + 0x8c, 0x47, 0x2b, 0x55, 0x3d, 0xc9, 0x43, 0xe8, 0xa4, 0x01, 0x45, 0x00, + 0x14, 0xb4, 0x00, 0x51, 0x48, 0x61, 0x4b, 0x40, 0x05, 0x14, 0xc0, 0x5a, + 0x29, 0x00, 0x52, 0xd0, 0x02, 0x52, 0xd0, 0x01, 0x49, 0x40, 0x09, 0xb8, + 0x51, 0x9a, 0x91, 0x8d, 0x2d, 0x50, 0x4f, 0x78, 0x90, 0xae, 0x58, 0xd0, + 0x33, 0x3e, 0x1d, 0x7a, 0x39, 0x6e, 0x96, 0x20, 0x38, 0x26, 0xb5, 0x83, + 0x64, 0x56, 0x6f, 0x49, 0x58, 0xd3, 0x97, 0x41, 0x73, 0x4b, 0x4c, 0x90, + 0xa2, 0xa8, 0x41, 0x45, 0x00, 0x14, 0x94, 0x00, 0x99, 0xa6, 0xe6, 0x98, + 0x86, 0x16, 0xe6, 0xa2, 0x94, 0x6f, 0x18, 0xcd, 0x51, 0x25, 0x71, 0x0a, + 0x8f, 0x7a, 0x43, 0x12, 0x7a, 0x52, 0x01, 0x70, 0x29, 0xaf, 0xd2, 0x80, + 0x29, 0xb9, 0xe6, 0x9a, 0x18, 0xab, 0x66, 0xa6, 0x45, 0xa3, 0xa3, 0xb7, + 0x93, 0xcd, 0x84, 0x30, 0xfa, 0x52, 0xbd, 0x38, 0x6c, 0x4b, 0x2b, 0x49, + 0x55, 0xde, 0xa8, 0x44, 0x0d, 0x5c, 0xb6, 0xbc, 0x3e, 0x56, 0xff, 0x00, + 0x77, 0x34, 0xe0, 0x29, 0x1c, 0xf5, 0x14, 0xc6, 0x02, 0x9f, 0x52, 0x01, + 0x9a, 0x6e, 0x68, 0xb0, 0x5c, 0x4c, 0xd1, 0x9a, 0x00, 0x4a, 0x28, 0x01, + 0x28, 0xa6, 0x03, 0x93, 0xad, 0x4b, 0x96, 0x3d, 0xcd, 0x45, 0x86, 0x2a, + 0xf1, 0x56, 0xfe, 0x5d, 0xb5, 0xa4, 0x44, 0xc5, 0xf2, 0xb2, 0x99, 0x53, + 0x51, 0xfc, 0xf1, 0xe7, 0x06, 0xa6, 0xc0, 0x5c, 0x8a, 0x46, 0xdb, 0xd6, + 0xa4, 0xf3, 0x4d, 0x65, 0x62, 0x85, 0xf3, 0x4d, 0x2f, 0x9d, 0x48, 0x9b, + 0x0f, 0x59, 0x77, 0x53, 0xab, 0x44, 0x48, 0x53, 0x6a, 0xac, 0x48, 0x52, + 0xd0, 0x48, 0x94, 0xb4, 0x08, 0x5a, 0x70, 0xaa, 0x01, 0x69, 0x68, 0x10, + 0x51, 0x40, 0x82, 0x8a, 0x2c, 0x01, 0x45, 0x2b, 0x01, 0xcd, 0xd1, 0x5a, + 0x9b, 0x80, 0xa2, 0xa5, 0x8c, 0x28, 0x15, 0x1b, 0x80, 0xbd, 0x2b, 0xac, + 0xf0, 0xc4, 0x9b, 0xac, 0xca, 0x67, 0xa6, 0x4f, 0xeb, 0x53, 0x27, 0xaa, + 0x29, 0x6c, 0xcd, 0xba, 0xbd, 0x6a, 0x72, 0x95, 0xa4, 0xc9, 0x44, 0xf4, + 0x54, 0x80, 0x51, 0x40, 0x05, 0x14, 0x00, 0x51, 0x4c, 0x61, 0x45, 0x20, + 0x16, 0x8a, 0x40, 0x2d, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, 0x00, 0x52, + 0x77, 0x14, 0x03, 0x39, 0x3b, 0xfd, 0x4e, 0xe1, 0x2e, 0xb0, 0x8d, 0xc5, + 0x4b, 0x6d, 0xaf, 0x4e, 0x06, 0x1d, 0x73, 0x45, 0x58, 0xea, 0x6d, 0x05, + 0x78, 0x84, 0x9a, 0xe4, 0xbd, 0xb0, 0x2b, 0x36, 0xee, 0xf6, 0x4b, 0xaf, + 0xbf, 0x51, 0xb1, 0x4a, 0x28, 0x86, 0x13, 0xb2, 0x5d, 0xcb, 0x5d, 0xac, + 0x2f, 0x98, 0x54, 0xfb, 0x0f, 0xe5, 0x58, 0xcb, 0xe2, 0x2e, 0x5f, 0x09, + 0x20, 0x34, 0xec, 0xd6, 0x86, 0x02, 0xd1, 0x54, 0x01, 0x9a, 0x5c, 0xd2, + 0x01, 0x29, 0x29, 0x88, 0x08, 0x6c, 0x64, 0x03, 0x50, 0x92, 0xdf, 0xdd, + 0x3f, 0x95, 0x5a, 0x57, 0x11, 0x13, 0x6e, 0x5e, 0xa0, 0xd3, 0x4c, 0x94, + 0x3d, 0x04, 0x44, 0x5f, 0x9a, 0x4d, 0xd5, 0x37, 0x01, 0xbb, 0xe9, 0xac, + 0x68, 0x02, 0x8c, 0xbe, 0x67, 0x9a, 0x36, 0xe7, 0x15, 0x2c, 0x4a, 0x58, + 0x80, 0x70, 0x3e, 0xb5, 0x12, 0xdc, 0xd1, 0x6c, 0x6b, 0x69, 0x72, 0x71, + 0xb2, 0xae, 0xb1, 0xaa, 0x81, 0x12, 0x2a, 0xc9, 0x55, 0xde, 0xa8, 0x92, + 0xbb, 0xd7, 0x39, 0xe2, 0x01, 0xf2, 0x4b, 0xfe, 0xed, 0x54, 0x37, 0x14, + 0x8e, 0x68, 0xf5, 0xa4, 0xaa, 0x63, 0x14, 0x51, 0x52, 0x02, 0x52, 0xd0, + 0x02, 0x51, 0x40, 0x09, 0x45, 0x20, 0x0a, 0x29, 0x88, 0x96, 0x24, 0x35, + 0x3e, 0xca, 0x45, 0x8f, 0x8a, 0x20, 0x5f, 0xe6, 0xa9, 0xdd, 0x03, 0x0c, + 0x52, 0x4c, 0x2c, 0x1b, 0x4e, 0x29, 0xdb, 0x32, 0x39, 0xa2, 0xe1, 0x61, + 0xea, 0x30, 0x29, 0x6b, 0x31, 0x87, 0x34, 0xef, 0x2d, 0xaa, 0xc9, 0xb9, + 0x2c, 0x71, 0x6d, 0x39, 0xcd, 0x48, 0x4d, 0x34, 0x66, 0xc4, 0xcd, 0x25, + 0x32, 0x44, 0xa3, 0x34, 0xc4, 0x2d, 0x2d, 0x02, 0x17, 0x34, 0xea, 0x62, + 0x16, 0x8e, 0xf4, 0xc0, 0x5a, 0x29, 0x08, 0x28, 0xa0, 0x02, 0x8a, 0x62, + 0x39, 0xaa, 0x29, 0xb6, 0x75, 0x0b, 0x49, 0x52, 0x01, 0x49, 0x40, 0x85, + 0xae, 0x8b, 0xc2, 0x72, 0x7e, 0xf6, 0x54, 0xff, 0x00, 0x64, 0x7f, 0xe8, + 0x55, 0x9d, 0x44, 0x5c, 0x4e, 0x98, 0x55, 0xbb, 0x3a, 0xd2, 0x64, 0x22, + 0xdd, 0x14, 0x80, 0x28, 0xa0, 0x02, 0x8a, 0x06, 0x14, 0x53, 0x00, 0xa2, + 0x90, 0x05, 0x14, 0x80, 0x5a, 0x5a, 0x00, 0x29, 0x28, 0x00, 0xa4, 0xa0, + 0x06, 0x3b, 0xed, 0x15, 0x0f, 0xda, 0x14, 0x9a, 0x68, 0x4c, 0xe4, 0x35, + 0x1e, 0x2f, 0x0f, 0xd2, 0xab, 0x99, 0x82, 0x74, 0xc5, 0x2a, 0xdf, 0x11, + 0xbd, 0x2f, 0x84, 0x84, 0xc9, 0xba, 0x9b, 0xe6, 0x56, 0x46, 0x82, 0xac, + 0xa6, 0xb6, 0xac, 0x35, 0xb6, 0x8a, 0x3f, 0x2d, 0x86, 0xee, 0xb5, 0x0e, + 0x1d, 0x4a, 0xf2, 0x3a, 0x44, 0x6d, 0xc8, 0x18, 0x77, 0x15, 0x20, 0xa1, + 0x6a, 0x62, 0xd0, 0xb4, 0x66, 0xac, 0x42, 0x66, 0x8c, 0xd2, 0x10, 0x99, + 0xa6, 0x34, 0x9b, 0x46, 0x6a, 0x80, 0xb1, 0x63, 0xa8, 0xc4, 0x99, 0x0e, + 0x2a, 0xd7, 0xf6, 0x9d, 0xa9, 0xf5, 0xfc, 0xa8, 0x8e, 0x83, 0xf6, 0x77, + 0x2a, 0xea, 0x77, 0xb0, 0xb5, 0xa9, 0x54, 0x07, 0x2c, 0x08, 0xac, 0x33, + 0x29, 0xab, 0x9b, 0xd0, 0x98, 0xc6, 0xc3, 0x7c, 0xea, 0x97, 0x20, 0xd6, + 0x25, 0xd8, 0x4d, 0xcb, 0xeb, 0x51, 0x99, 0x45, 0x3d, 0x45, 0x61, 0x86, + 0x5e, 0x78, 0x14, 0x9b, 0x9c, 0xd2, 0x19, 0x34, 0x12, 0x34, 0x52, 0xab, + 0x1a, 0xd9, 0xce, 0x56, 0xaa, 0x3b, 0x93, 0x22, 0x07, 0xa8, 0x1e, 0xb4, + 0x66, 0x65, 0x69, 0x2b, 0x07, 0x5d, 0x19, 0x8d, 0xfd, 0xc5, 0x38, 0x6e, + 0x29, 0x1c, 0xab, 0x7d, 0xe3, 0xf5, 0xa4, 0xaa, 0x6c, 0x61, 0x4b, 0x48, + 0x02, 0x92, 0x92, 0x01, 0x28, 0xa0, 0x03, 0x06, 0x9f, 0xe5, 0x9a, 0x02, + 0xc3, 0xc4, 0x0d, 0x52, 0x2d, 0xb1, 0xa5, 0x71, 0xd8, 0xb5, 0x14, 0x07, + 0x1d, 0x31, 0x53, 0x08, 0x6b, 0x2e, 0x63, 0x41, 0x7c, 0xa1, 0x4e, 0xc0, + 0xa0, 0x01, 0x7e, 0x6e, 0x94, 0xfd, 0x95, 0x46, 0x6e, 0x43, 0xbc, 0xaa, + 0x5d, 0xa2, 0xa8, 0x9b, 0x8b, 0xd2, 0x97, 0x34, 0xc4, 0x2e, 0x69, 0x09, + 0xa0, 0x43, 0x77, 0x51, 0xba, 0x82, 0x43, 0x75, 0x19, 0xa6, 0x01, 0x9a, + 0x5c, 0xd0, 0x21, 0xd4, 0xa2, 0xa8, 0x43, 0xa9, 0x68, 0x10, 0x52, 0xd2, + 0x10, 0x51, 0x4c, 0x02, 0x8a, 0x04, 0x73, 0x74, 0xb4, 0xce, 0xa1, 0x28, + 0x15, 0x00, 0x21, 0xa2, 0x80, 0x1d, 0x5a, 0xde, 0x1b, 0x7d, 0x9a, 0x9a, + 0x2f, 0xf7, 0x99, 0x47, 0xf3, 0xa8, 0xa9, 0xb1, 0x70, 0x3b, 0x05, 0xe9, + 0x56, 0xad, 0x0f, 0xcf, 0x5a, 0x3d, 0x88, 0x45, 0xda, 0x28, 0x10, 0x51, + 0x40, 0x05, 0x14, 0x0c, 0x28, 0xa0, 0x04, 0xa5, 0xa4, 0x01, 0x45, 0x00, + 0x14, 0x50, 0x01, 0x45, 0x00, 0x14, 0x94, 0x01, 0x5e, 0xe7, 0xa5, 0x63, + 0x35, 0xfc, 0x62, 0xe3, 0xca, 0x63, 0x86, 0xe2, 0xae, 0xda, 0x5c, 0x5d, + 0x4c, 0x5b, 0xb7, 0xdc, 0x72, 0x6a, 0x91, 0xe6, 0xb3, 0x99, 0xb4, 0x40, + 0x29, 0xc7, 0x43, 0x4d, 0xef, 0xc5, 0x09, 0x14, 0xc7, 0x04, 0x35, 0xa9, + 0xa3, 0x5a, 0xf9, 0x97, 0x49, 0xe6, 0x27, 0xcb, 0x9a, 0x99, 0xc6, 0xc5, + 0xa3, 0xa9, 0x4e, 0x14, 0x0a, 0x7e, 0x6b, 0x34, 0x64, 0x2e, 0xea, 0x4d, + 0xd5, 0x40, 0x26, 0xfa, 0x69, 0x90, 0x54, 0x8c, 0x61, 0x9c, 0x7a, 0xd4, + 0x12, 0xdc, 0xae, 0xd2, 0x28, 0xb8, 0x72, 0x95, 0xa2, 0x6d, 0xd2, 0x71, + 0x57, 0x92, 0x16, 0x04, 0x1a, 0x39, 0x8e, 0x8d, 0x91, 0x16, 0xa0, 0xdc, + 0xa2, 0x7a, 0x55, 0x3a, 0xa9, 0x19, 0xb1, 0xa4, 0x53, 0xe3, 0xe6, 0x91, + 0x23, 0xcc, 0x23, 0x34, 0x9e, 0x58, 0xa4, 0x48, 0xbb, 0x69, 0x69, 0x0c, + 0x46, 0xe9, 0x5a, 0x36, 0x72, 0xf9, 0x90, 0xfb, 0x8a, 0x64, 0xb1, 0xcf, + 0x55, 0xda, 0xb6, 0x33, 0x2b, 0xcb, 0xd2, 0xb1, 0x35, 0x7c, 0x15, 0xc7, + 0xa9, 0xa1, 0x09, 0x9c, 0xbb, 0xa7, 0xcc, 0xdf, 0x5a, 0x8f, 0x63, 0x7a, + 0x1a, 0x60, 0x37, 0x14, 0xec, 0x50, 0x01, 0xb0, 0xd3, 0xc4, 0x06, 0x80, + 0xb1, 0x22, 0xdb, 0x7d, 0x6a, 0x55, 0xb4, 0xa9, 0xe6, 0x34, 0xe5, 0x26, + 0x4b, 0x2a, 0x99, 0x6d, 0x36, 0xd6, 0x6e, 0x65, 0xf2, 0x8f, 0x10, 0x20, + 0xa7, 0x61, 0x16, 0x8d, 0x58, 0xf4, 0x43, 0x1a, 0x50, 0xb4, 0x6f, 0xcf, + 0x34, 0xd4, 0x0c, 0xb9, 0x84, 0xcd, 0x15, 0xa5, 0x88, 0x6c, 0x4b, 0x63, + 0xf3, 0x35, 0x59, 0xcd, 0x21, 0x09, 0x9a, 0x4d, 0xd4, 0xac, 0x21, 0x37, + 0x53, 0x0c, 0xa0, 0x77, 0xa0, 0x08, 0xda, 0xed, 0x45, 0x40, 0xf7, 0xde, + 0x82, 0xa9, 0x21, 0x91, 0x1b, 0xc7, 0xff, 0x00, 0x26, 0x99, 0xf6, 0xd7, + 0xef, 0xcd, 0x16, 0x02, 0x41, 0x7c, 0x6a, 0x41, 0x7a, 0x3d, 0xa9, 0x59, + 0x8a, 0xc4, 0x8b, 0x74, 0xbe, 0xf5, 0x2a, 0xcc, 0x3d, 0x69, 0x85, 0x87, + 0x89, 0x85, 0x48, 0x24, 0x14, 0xc8, 0xb0, 0xfd, 0xd4, 0xbb, 0xa8, 0x24, + 0x5c, 0xd2, 0xd3, 0x10, 0xb4, 0xb4, 0x08, 0x28, 0xa2, 0xe2, 0x39, 0xba, + 0x2b, 0x43, 0xa4, 0x28, 0xa9, 0x18, 0x51, 0x48, 0x02, 0xae, 0x69, 0x4f, + 0xe5, 0xea, 0x30, 0x37, 0xfb, 0x55, 0x35, 0x2d, 0xca, 0x5c, 0x37, 0x3b, + 0xa4, 0xfb, 0xab, 0xfe, 0xe8, 0xab, 0x10, 0x1c, 0x48, 0x28, 0xfb, 0x24, + 0x1a, 0x03, 0xa5, 0x25, 0x31, 0x0b, 0x45, 0x00, 0x14, 0x50, 0x01, 0x45, + 0x00, 0x25, 0x14, 0x0c, 0x28, 0xa4, 0x01, 0x45, 0x00, 0x14, 0x50, 0x01, + 0x4d, 0x26, 0x80, 0x2b, 0xdc, 0xb7, 0xc9, 0x58, 0x37, 0x9a, 0x6c, 0x57, + 0x13, 0x79, 0x85, 0x99, 0x5a, 0xb5, 0x8c, 0xac, 0x4d, 0xb5, 0xb9, 0x91, + 0x76, 0x9e, 0x41, 0xd9, 0x55, 0xc5, 0x63, 0x50, 0xe8, 0xa7, 0xa9, 0xb9, + 0x6d, 0x6a, 0xbf, 0x67, 0xe9, 0x4e, 0x8b, 0x4a, 0x0c, 0xc4, 0x88, 0xbf, + 0x4a, 0x28, 0x31, 0x4d, 0x59, 0xdc, 0x9f, 0xfb, 0x2e, 0x4f, 0xe1, 0x8c, + 0xd4, 0xf6, 0x96, 0x52, 0xc1, 0x26, 0xe6, 0x4c, 0x57, 0x5d, 0x54, 0xb9, + 0x48, 0x8c, 0xcb, 0x7e, 0x60, 0x1d, 0xe9, 0xa6, 0xe5, 0x47, 0x7a, 0xf3, + 0xcd, 0x08, 0xda, 0xf5, 0x45, 0x42, 0xda, 0x87, 0xa5, 0x45, 0xcb, 0x50, + 0x22, 0x6b, 0xe7, 0x3d, 0x2a, 0x26, 0xba, 0x90, 0xf7, 0xa5, 0x73, 0x4e, + 0x51, 0x86, 0x42, 0x7b, 0xd3, 0x73, 0x41, 0x64, 0xb6, 0xd2, 0xf9, 0x72, + 0x83, 0x5b, 0x30, 0xcd, 0xd2, 0x92, 0x5a, 0x8d, 0xec, 0x51, 0xd4, 0x64, + 0x12, 0x5d, 0x65, 0x7d, 0x05, 0x41, 0x5b, 0xcc, 0xc5, 0x85, 0x3e, 0x2f, + 0xbd, 0x50, 0x41, 0x39, 0xa6, 0xd2, 0x24, 0x4a, 0x6d, 0x00, 0x21, 0xe9, + 0x4e, 0xb1, 0x9f, 0x65, 0xca, 0xc7, 0xfd, 0xf3, 0x8a, 0x60, 0x69, 0x35, + 0x57, 0x7a, 0xd6, 0xe6, 0x45, 0x5b, 0x96, 0xfd, 0xdb, 0x57, 0x2b, 0x37, + 0x9d, 0x23, 0x9d, 0xc4, 0x9c, 0x1a, 0x77, 0xd0, 0x12, 0xbb, 0x20, 0xf2, + 0x39, 0xa3, 0xc8, 0xac, 0xf9, 0x8d, 0x94, 0x05, 0xfb, 0x28, 0x3d, 0x56, + 0x9c, 0xb6, 0x23, 0xfb, 0xb4, 0xb9, 0xc7, 0xc8, 0x4a, 0xb6, 0x3e, 0xc2, + 0xa4, 0x16, 0xa8, 0x2a, 0x79, 0xca, 0xe5, 0x1e, 0x12, 0x35, 0xec, 0x29, + 0x0c, 0xa8, 0xb4, 0x25, 0x71, 0x68, 0x88, 0x8d, 0xc5, 0x30, 0xcc, 0x4d, + 0x68, 0xa0, 0x64, 0xe6, 0x30, 0xb1, 0xa4, 0xad, 0x2c, 0x67, 0x71, 0x92, + 0xfd, 0xda, 0x91, 0x69, 0x88, 0x09, 0xa6, 0xee, 0xa4, 0x05, 0x63, 0x75, + 0xb3, 0x3b, 0x45, 0x11, 0x5e, 0xb6, 0xff, 0x00, 0x98, 0x71, 0xf5, 0xa2, + 0xc3, 0x26, 0x6b, 0xd1, 0x51, 0x35, 0xe3, 0x76, 0xe2, 0x8b, 0x01, 0x0b, + 0x5c, 0x31, 0xef, 0x51, 0x34, 0xb9, 0xef, 0x40, 0x86, 0x79, 0x94, 0xdd, + 0xe6, 0x81, 0x8d, 0xc9, 0xa2, 0x81, 0x0b, 0xb6, 0x9e, 0x05, 0x00, 0x38, + 0x1c, 0x54, 0x9e, 0x69, 0xa0, 0x05, 0xf3, 0x4d, 0x3c, 0x5c, 0x38, 0xa3, + 0x70, 0x24, 0x17, 0x4d, 0xde, 0xa4, 0x5b, 0xca, 0x56, 0x11, 0x62, 0x3b, + 0x9d, 0xd5, 0x30, 0x9a, 0x92, 0x64, 0x34, 0x4a, 0x0d, 0x3e, 0xa9, 0x33, + 0x30, 0xa5, 0xaa, 0xb0, 0x1c, 0xe5, 0x25, 0x07, 0x48, 0x1e, 0x94, 0x52, + 0x01, 0x68, 0xa6, 0x80, 0x4a, 0x92, 0x16, 0xdb, 0x26, 0xef, 0xad, 0x4c, + 0xf6, 0x2a, 0x1b, 0x9e, 0x81, 0x6d, 0xcc, 0x11, 0x9f, 0xf6, 0x47, 0xf2, + 0xab, 0x2b, 0xf7, 0x85, 0x28, 0xfc, 0x24, 0xbd, 0xcd, 0x05, 0xe9, 0x4b, + 0x54, 0x01, 0x45, 0x00, 0x14, 0x50, 0x01, 0x45, 0x20, 0x12, 0x92, 0x80, + 0x0a, 0x28, 0x00, 0xa2, 0x80, 0x0a, 0x4c, 0xd0, 0x03, 0x77, 0x54, 0x53, + 0x49, 0xf2, 0x1c, 0x51, 0x70, 0x28, 0xcb, 0x21, 0x6a, 0xac, 0xcc, 0x69, + 0x5c, 0x66, 0x76, 0xa1, 0x6d, 0xf6, 0x84, 0xe3, 0xef, 0x0a, 0xc4, 0x62, + 0x62, 0x72, 0xad, 0x43, 0xd5, 0x15, 0x07, 0x66, 0x6c, 0x69, 0xba, 0x9a, + 0x30, 0x11, 0x3f, 0x5a, 0xf4, 0x0d, 0x2a, 0xd6, 0x34, 0x87, 0x77, 0x1c, + 0xd7, 0x34, 0x74, 0x95, 0x8d, 0xaa, 0xec, 0x5f, 0x70, 0x31, 0x59, 0xb7, + 0x5b, 0x6b, 0xb9, 0xb3, 0x96, 0xc7, 0x29, 0xa8, 0x36, 0xd9, 0xf8, 0xe9, + 0x55, 0xb7, 0x66, 0xb9, 0xaa, 0xee, 0x76, 0x53, 0xd8, 0x33, 0x4d, 0xcd, + 0x73, 0x9b, 0x09, 0x9a, 0x68, 0x6d, 0xdd, 0x29, 0x00, 0xfa, 0x75, 0x00, + 0x2a, 0xf5, 0xad, 0xeb, 0x44, 0xfd, 0xde, 0xfe, 0xd5, 0xa4, 0x5e, 0xa5, + 0x74, 0x32, 0xae, 0xbf, 0xd6, 0x53, 0x33, 0x5a, 0xcb, 0x73, 0x19, 0x8e, + 0xa7, 0x45, 0xf7, 0xaa, 0x0c, 0xcb, 0x06, 0x9b, 0x4d, 0x90, 0x25, 0x26, + 0x2a, 0x46, 0x21, 0xaa, 0x53, 0x31, 0x8e, 0x40, 0xc3, 0xa8, 0xaa, 0x03, + 0x6d, 0x24, 0xf3, 0x21, 0x0d, 0x55, 0x6e, 0xa6, 0xd8, 0x2a, 0xa2, 0xf4, + 0x33, 0xea, 0x66, 0x4d, 0x2c, 0x92, 0xf1, 0x9a, 0xad, 0xe4, 0x0a, 0xce, + 0x4c, 0xdd, 0x21, 0x86, 0xdc, 0x7a, 0xd2, 0xf9, 0x28, 0x3d, 0x2a, 0x2e, + 0xcb, 0xb0, 0x9b, 0xa3, 0x5a, 0x61, 0xb8, 0x41, 0xde, 0xad, 0x45, 0x92, + 0xdd, 0x88, 0x5a, 0xe7, 0xda, 0xa2, 0x33, 0x31, 0xef, 0x5a, 0xf2, 0x18, + 0xba, 0x83, 0x0b, 0x13, 0x4d, 0xad, 0x0c, 0x84, 0xa5, 0xa0, 0x02, 0x8a, + 0x04, 0x32, 0x4e, 0x94, 0x2b, 0x71, 0x43, 0x10, 0x85, 0xaa, 0xbd, 0xc4, + 0x85, 0x71, 0x40, 0xc4, 0xb7, 0x45, 0x9b, 0xef, 0x54, 0xc6, 0x38, 0x17, + 0xf8, 0x69, 0x5c, 0x0a, 0x9e, 0xb8, 0xa6, 0x91, 0x4c, 0x63, 0x0a, 0xd3, + 0x76, 0x50, 0x20, 0xd9, 0x4a, 0x23, 0xa0, 0x63, 0xb1, 0x4b, 0x40, 0x82, + 0x8a, 0x00, 0x4c, 0xd2, 0x6e, 0xa0, 0x62, 0x6e, 0xa7, 0x86, 0xa4, 0x20, + 0x2f, 0x49, 0xba, 0x98, 0x16, 0xad, 0x5a, 0xae, 0x21, 0xac, 0xc4, 0xcb, + 0x31, 0x9a, 0x98, 0x56, 0x88, 0xcc, 0x5a, 0x5a, 0x64, 0x9c, 0xef, 0x7a, + 0x4a, 0xd2, 0xc6, 0xe2, 0xd1, 0x52, 0x31, 0x40, 0x34, 0x63, 0x07, 0x91, + 0x49, 0x08, 0x6d, 0x3b, 0xb1, 0xa2, 0x43, 0x8e, 0xe7, 0x7b, 0xa3, 0xbf, + 0x9b, 0x60, 0xa7, 0xfd, 0xa3, 0xfd, 0x2b, 0x47, 0x1c, 0x54, 0x53, 0xf8, + 0x47, 0x3f, 0x88, 0xb9, 0x1f, 0xdd, 0xa5, 0xa6, 0x89, 0x16, 0x8a, 0x60, + 0x14, 0x53, 0x18, 0x52, 0x52, 0x01, 0x28, 0xa4, 0x02, 0x51, 0x9a, 0x00, + 0x4d, 0xd4, 0xc3, 0x28, 0x1d, 0xe8, 0x60, 0x42, 0xf7, 0x68, 0x3b, 0xd4, + 0x26, 0xf2, 0xb2, 0x6c, 0x9e, 0x62, 0x13, 0x7c, 0x7d, 0x29, 0xbf, 0x68, + 0x2c, 0x32, 0x2a, 0x05, 0x71, 0x14, 0x96, 0xed, 0x46, 0xd3, 0x53, 0x71, + 0x31, 0x8c, 0x17, 0xf8, 0xb1, 0x5c, 0xe6, 0xaa, 0x8a, 0x2e, 0x8e, 0xde, + 0x98, 0x15, 0xa5, 0x36, 0x54, 0x6f, 0x72, 0x9a, 0x65, 0x4f, 0x15, 0xd8, + 0x5b, 0x5e, 0xea, 0x10, 0xdb, 0x02, 0x8f, 0x95, 0xad, 0x69, 0xa8, 0xb9, + 0xea, 0x74, 0x49, 0xfb, 0xa3, 0x2e, 0x35, 0x8d, 0x40, 0x8e, 0x49, 0xab, + 0x50, 0xcc, 0xef, 0x0f, 0xcc, 0xd9, 0xae, 0xba, 0xd0, 0x51, 0xd8, 0xc9, + 0x19, 0xba, 0x91, 0xc3, 0x8c, 0xf7, 0xa8, 0x63, 0xe9, 0x5e, 0x7d, 0x63, + 0xae, 0x97, 0xc2, 0x3a, 0x8a, 0xc4, 0xd0, 0x43, 0x50, 0x6d, 0x60, 0xdc, + 0x53, 0xb0, 0x89, 0x79, 0xa7, 0x0a, 0x7c, 0xa3, 0xb8, 0xe5, 0xeb, 0x5d, + 0x25, 0xa4, 0x32, 0x1b, 0x4f, 0x96, 0x9c, 0x7e, 0x20, 0xe7, 0xb2, 0x33, + 0xb5, 0x0b, 0x57, 0x5c, 0xb1, 0xe2, 0xb3, 0xb7, 0x1a, 0xda, 0xaa, 0x31, + 0x52, 0xe6, 0x1e, 0x24, 0xa9, 0x62, 0x3c, 0xd6, 0x20, 0xd1, 0x68, 0xf4, + 0xa6, 0xe4, 0x53, 0x20, 0x61, 0x75, 0xa6, 0x19, 0x94, 0x54, 0x95, 0x62, + 0x17, 0x9e, 0xab, 0x4a, 0xdb, 0xb9, 0x35, 0x45, 0x58, 0x9a, 0x0d, 0x43, + 0x62, 0x18, 0xf1, 0xd3, 0x9c, 0xd4, 0x72, 0x4f, 0xbc, 0xe4, 0x9a, 0x5b, + 0x0b, 0x94, 0x81, 0xa7, 0x02, 0xa2, 0x6b, 0xa1, 0x4d, 0x42, 0xe0, 0xe6, + 0x91, 0x13, 0x5c, 0x9e, 0xd5, 0x0b, 0x4a, 0xc7, 0xbd, 0x6d, 0xc8, 0x8c, + 0x5d, 0x46, 0x44, 0x4e, 0x4d, 0x15, 0x66, 0x62, 0x51, 0x40, 0x05, 0x25, + 0x00, 0x25, 0x2d, 0x00, 0x25, 0x25, 0x02, 0x18, 0xe7, 0x8a, 0x62, 0xfd, + 0xda, 0x42, 0x10, 0x9a, 0x82, 0x7f, 0xb9, 0x54, 0x03, 0x2d, 0xdb, 0x14, + 0xf2, 0xcb, 0xeb, 0x52, 0x8a, 0x2b, 0xb3, 0x73, 0xc5, 0x1e, 0x65, 0x0c, + 0x57, 0x17, 0xcc, 0xa3, 0x70, 0xa0, 0x63, 0xa9, 0x68, 0x10, 0x62, 0x8c, + 0x50, 0x02, 0x52, 0x71, 0x40, 0x0d, 0x6a, 0x6d, 0x30, 0x16, 0x8a, 0x00, + 0x4c, 0xd1, 0x9a, 0x40, 0x59, 0xb7, 0x35, 0x75, 0x0d, 0x48, 0x99, 0x65, + 0x0f, 0x15, 0x30, 0x35, 0x48, 0xcd, 0x8e, 0xcd, 0x2e, 0x68, 0x20, 0xe7, + 0xa8, 0x35, 0xa9, 0xd2, 0x14, 0xf5, 0xa8, 0x60, 0x5a, 0x18, 0x0b, 0x51, + 0x4b, 0x8c, 0x54, 0xc4, 0x08, 0x71, 0x4b, 0x8e, 0xd4, 0xc0, 0xec, 0xfc, + 0x2c, 0xfb, 0xb4, 0xfd, 0xbe, 0x9b, 0x8f, 0xeb, 0x5b, 0xe8, 0x32, 0xb5, + 0x9d, 0x2d, 0x8b, 0xa9, 0xb9, 0x62, 0x25, 0xf9, 0x69, 0xd8, 0xad, 0x0c, + 0xc4, 0xa2, 0x80, 0x0a, 0x28, 0x18, 0xda, 0x42, 0x68, 0x01, 0xa5, 0xc7, + 0xad, 0x46, 0x65, 0x51, 0xde, 0xa6, 0xe0, 0x46, 0xd7, 0x48, 0x3b, 0xd4, + 0x7f, 0x6c, 0x07, 0xa5, 0x4d, 0xca, 0xb1, 0x04, 0x97, 0x2c, 0xc3, 0x1d, + 0x2a, 0x21, 0xb8, 0xf5, 0xac, 0xe5, 0x23, 0x2b, 0x83, 0x42, 0x0d, 0x1e, + 0x4a, 0xe2, 0xa2, 0xe4, 0x86, 0xd5, 0xc6, 0x29, 0xca, 0x10, 0x0e, 0xc2, + 0xa5, 0x8c, 0x6b, 0xdd, 0x43, 0x10, 0xe5, 0xaa, 0xa4, 0xda, 0xcc, 0x2b, + 0xc2, 0x02, 0xc7, 0xe9, 0x57, 0x18, 0x5c, 0x46, 0x75, 0xc5, 0xed, 0xc4, + 0xfd, 0x3e, 0x51, 0xed, 0x54, 0x58, 0x36, 0x7e, 0x6a, 0xdb, 0x92, 0xc6, + 0xf0, 0x56, 0x45, 0x73, 0x2a, 0xd7, 0x61, 0xa2, 0xcf, 0xe6, 0xd9, 0x0f, + 0xa9, 0xa7, 0xb3, 0x45, 0xef, 0x11, 0x93, 0x7c, 0xca, 0x6a, 0xc5, 0x97, + 0xfa, 0xb3, 0x5d, 0x95, 0xb6, 0x33, 0x89, 0x99, 0xe2, 0x21, 0x85, 0x8c, + 0xff, 0x00, 0xb4, 0x7f, 0xf4, 0x1a, 0xa9, 0x67, 0x3f, 0x99, 0xf2, 0x9e, + 0xb5, 0xc5, 0x5d, 0x68, 0x99, 0xd1, 0x41, 0xe9, 0x62, 0xde, 0x29, 0x71, + 0x5c, 0xe6, 0xc2, 0xe2, 0x8a, 0x00, 0xb7, 0x07, 0x94, 0x63, 0xe4, 0x73, + 0x50, 0xcc, 0xa1, 0x9f, 0xe5, 0xad, 0x96, 0x91, 0x30, 0x5f, 0x10, 0xc1, + 0x19, 0xae, 0xaf, 0x45, 0x90, 0x7d, 0x93, 0x04, 0xfa, 0xd6, 0x5d, 0x4a, + 0x9e, 0xc5, 0x7d, 0x69, 0x81, 0x85, 0xb9, 0xed, 0x5c, 0xe9, 0x1f, 0x31, + 0xae, 0x8a, 0x9b, 0x19, 0xd2, 0x42, 0x62, 0x9c, 0x38, 0xae, 0x63, 0x71, + 0xe6, 0x53, 0x8e, 0xb5, 0x1b, 0x4b, 0x4c, 0x08, 0xda, 0x5f, 0x7a, 0x89, + 0xa5, 0xf5, 0x34, 0xf9, 0x40, 0x85, 0xee, 0x14, 0x0e, 0xb5, 0x52, 0x5b, + 0xcc, 0x74, 0xad, 0x3d, 0x99, 0x0e, 0xa5, 0x86, 0xf9, 0xef, 0xd7, 0xa1, + 0xa4, 0xf3, 0x19, 0xba, 0x9a, 0xd2, 0x31, 0x31, 0x73, 0xb8, 0x75, 0xa3, + 0x15, 0x56, 0x33, 0x12, 0x92, 0x80, 0x12, 0x8a, 0x00, 0x4a, 0x29, 0x00, + 0x94, 0x50, 0x02, 0x62, 0x99, 0x23, 0x6c, 0x5c, 0x9a, 0x00, 0x8d, 0x27, + 0x0c, 0x71, 0x52, 0x1a, 0x9e, 0xa0, 0x31, 0x87, 0x14, 0x46, 0xbb, 0x85, + 0x50, 0x88, 0x5a, 0xa2, 0x97, 0xee, 0xd3, 0xb0, 0x11, 0x27, 0x5a, 0x47, + 0x5c, 0x49, 0x40, 0x0d, 0x2b, 0xcd, 0x34, 0xad, 0x00, 0x25, 0x14, 0x86, + 0x14, 0xbb, 0xcd, 0x00, 0x3f, 0x79, 0xa4, 0xdc, 0x68, 0xb0, 0x82, 0x8a, + 0x00, 0x4a, 0x28, 0x01, 0x28, 0xa0, 0x02, 0x81, 0x40, 0x16, 0x60, 0xab, + 0x91, 0xd2, 0x02, 0xc2, 0x1a, 0x94, 0x1a, 0x66, 0x6c, 0x93, 0x34, 0xb4, + 0x12, 0x73, 0xf4, 0x55, 0x9b, 0x8a, 0x06, 0x4d, 0x48, 0x8a, 0x43, 0x50, + 0x05, 0x81, 0x19, 0xa5, 0xfb, 0x39, 0xf4, 0xfd, 0x2a, 0x40, 0x51, 0x68, + 0xcc, 0x71, 0xe5, 0xb7, 0xfd, 0xf3, 0x56, 0xd3, 0x49, 0xb8, 0x93, 0xee, + 0xc7, 0x81, 0x5a, 0x72, 0xf7, 0x11, 0xd0, 0x68, 0x56, 0xb2, 0xd9, 0xab, + 0x09, 0x40, 0x00, 0xfb, 0xfb, 0xd6, 0xe4, 0x2c, 0x37, 0x62, 0xb1, 0xb7, + 0x29, 0x4d, 0xdc, 0xd0, 0x81, 0x72, 0x28, 0x74, 0xa7, 0x12, 0x59, 0x1e, + 0xda, 0x6d, 0x30, 0x1b, 0x49, 0x4c, 0x0a, 0xd7, 0x53, 0xf9, 0x29, 0xba, + 0xb3, 0x9f, 0x53, 0x3d, 0x85, 0x4c, 0xf4, 0x45, 0xc1, 0x5c, 0xae, 0xf7, + 0xf2, 0x1e, 0xf5, 0x11, 0xb8, 0x73, 0xde, 0xb1, 0xb9, 0xb2, 0x89, 0x13, + 0x3b, 0x1e, 0xf4, 0xd1, 0x76, 0xf0, 0xfb, 0xd3, 0xb5, 0xd1, 0x13, 0x1c, + 0xba, 0xba, 0x7f, 0x12, 0x55, 0xd8, 0xae, 0xbc, 0xc8, 0xf7, 0x20, 0x15, + 0x9f, 0x2e, 0xa6, 0x1c, 0xa5, 0x49, 0x35, 0xa4, 0x47, 0xda, 0x62, 0x39, + 0xa8, 0x5f, 0x5c, 0x6f, 0xe1, 0x86, 0xaa, 0x54, 0x83, 0x94, 0x81, 0xb5, + 0x7b, 0xa6, 0xfb, 0xaa, 0x17, 0xf1, 0xa8, 0x1e, 0xee, 0xf2, 0x6f, 0xf9, + 0x6a, 0x6b, 0x58, 0x53, 0x8f, 0x50, 0xe4, 0x64, 0x62, 0xda, 0x59, 0x1b, + 0x2e, 0x33, 0x53, 0x7d, 0x9c, 0xf1, 0xb4, 0x55, 0x5d, 0x5c, 0xd3, 0x93, + 0x42, 0x58, 0x93, 0xd6, 0x96, 0xe1, 0x7f, 0x77, 0x53, 0xcd, 0xa9, 0xa7, + 0x2d, 0x91, 0x89, 0x30, 0x09, 0x21, 0x18, 0xad, 0xed, 0x12, 0xec, 0xac, + 0x5b, 0x47, 0x6f, 0xf1, 0xaa, 0x62, 0x5b, 0x16, 0x3c, 0xd0, 0xd1, 0x90, + 0x5a, 0xae, 0xe9, 0xa7, 0xf7, 0x67, 0x15, 0xd5, 0x57, 0xe1, 0x25, 0x10, + 0xeb, 0x10, 0x79, 0xb0, 0x73, 0xda, 0xa8, 0x5b, 0x5b, 0x79, 0x6d, 0x5c, + 0x55, 0x76, 0xb1, 0xad, 0x12, 0x69, 0x25, 0x58, 0xbe, 0xf5, 0x31, 0x2e, + 0x91, 0xa4, 0x0b, 0x9e, 0xbe, 0xd5, 0x8f, 0x26, 0x97, 0x2f, 0x9f, 0x5b, + 0x17, 0x15, 0x72, 0x29, 0x7c, 0xba, 0x94, 0x50, 0xe5, 0x87, 0x34, 0xf1, + 0x16, 0x0d, 0x5d, 0xc8, 0x1f, 0x80, 0x2a, 0x54, 0xb8, 0xf2, 0xc7, 0x07, + 0x15, 0x20, 0x43, 0x35, 0xce, 0xfe, 0xa7, 0x35, 0x58, 0x9a, 0x72, 0x63, + 0x5a, 0x0c, 0x32, 0x01, 0x51, 0xb4, 0xc2, 0x9a, 0x8d, 0xc7, 0xcd, 0x62, + 0x33, 0x3e, 0x7b, 0x54, 0x4d, 0x31, 0xad, 0x55, 0x33, 0x17, 0x54, 0x89, + 0xa4, 0x3e, 0xb5, 0x19, 0x35, 0xa2, 0x89, 0x93, 0x91, 0x0b, 0x1a, 0x87, + 0x6e, 0xe7, 0xa6, 0x22, 0x6a, 0x70, 0x15, 0x20, 0x3b, 0x14, 0x62, 0xa8, + 0x03, 0x61, 0xa6, 0x62, 0x9b, 0x40, 0x25, 0x18, 0xa8, 0x01, 0x76, 0x1a, + 0x6e, 0xda, 0x2c, 0x01, 0xb6, 0x97, 0x6d, 0x20, 0x0c, 0x55, 0x5b, 0xe1, + 0xfb, 0xa3, 0x4d, 0x6e, 0x26, 0x67, 0x03, 0xf3, 0x0a, 0xb8, 0x67, 0x18, + 0x14, 0x9a, 0x18, 0x79, 0xdb, 0xfb, 0x56, 0xbe, 0x9d, 0x68, 0x02, 0x92, + 0xfc, 0xd0, 0x22, 0x79, 0xac, 0x23, 0x6c, 0xf1, 0x59, 0x57, 0x5a, 0x54, + 0xa3, 0x98, 0xfa, 0x55, 0xa7, 0xdc, 0xcc, 0xa0, 0xd6, 0xb2, 0xc6, 0xdf, + 0x32, 0xd3, 0x58, 0x53, 0xb1, 0x57, 0x19, 0x46, 0x29, 0x58, 0xa1, 0x92, + 0x27, 0xa5, 0x45, 0x40, 0x05, 0x15, 0x23, 0x1d, 0x45, 0x02, 0x0a, 0x29, + 0x80, 0xb4, 0xa3, 0x14, 0x80, 0x09, 0xe2, 0x9b, 0x40, 0x05, 0x2d, 0x00, + 0x4f, 0x05, 0x5b, 0x4a, 0x56, 0x11, 0x32, 0x9a, 0x98, 0x1a, 0x09, 0x1e, + 0x0d, 0x3f, 0x34, 0xc9, 0x32, 0xc5, 0xbe, 0xee, 0x8a, 0x7f, 0x0a, 0x9a, + 0x3d, 0x3e, 0x57, 0xe9, 0x1b, 0x7e, 0x55, 0xb1, 0xa1, 0x7a, 0x2d, 0x0a, + 0xe5, 0xbf, 0xe5, 0x98, 0xfc, 0x4d, 0x5e, 0x8b, 0xc3, 0x6d, 0xff, 0x00, + 0x2d, 0x24, 0xc7, 0xe4, 0x69, 0x0a, 0xe5, 0xd8, 0xb4, 0x0b, 0x65, 0xea, + 0xc4, 0xfe, 0x15, 0x72, 0x2d, 0x26, 0xd6, 0x3e, 0x91, 0x0a, 0x9e, 0x61, + 0x97, 0x62, 0xb6, 0x89, 0x3f, 0x80, 0x0a, 0xb2, 0x15, 0x00, 0xed, 0x51, + 0x70, 0xb0, 0xc2, 0x15, 0x8d, 0x2a, 0x42, 0xa0, 0xe6, 0x86, 0xc6, 0x8b, + 0xf6, 0xdd, 0x6a, 0x76, 0x5a, 0x51, 0x19, 0x13, 0xa7, 0x15, 0x55, 0xea, + 0x84, 0x32, 0x9a, 0xdf, 0x76, 0x80, 0x33, 0x2e, 0xfe, 0x65, 0x35, 0x90, + 0xdc, 0x1a, 0x55, 0x36, 0x34, 0xa4, 0x25, 0x15, 0x81, 0xb3, 0x62, 0x54, + 0x6c, 0xa0, 0xd6, 0x88, 0xcd, 0x90, 0xb4, 0x00, 0xfa, 0xd4, 0x5f, 0x67, + 0xbb, 0x1f, 0xea, 0xe5, 0x6c, 0x7d, 0x6a, 0xf4, 0xea, 0x40, 0x0b, 0x4b, + 0x8d, 0xf9, 0x90, 0x7e, 0xb5, 0x37, 0x90, 0x07, 0x50, 0x2a, 0x64, 0x52, + 0x06, 0x01, 0x50, 0x9c, 0x53, 0x22, 0x7c, 0xb8, 0x15, 0x3d, 0x2e, 0x52, + 0x65, 0xc5, 0x15, 0x25, 0x67, 0x73, 0x42, 0xb9, 0xf9, 0x24, 0xa5, 0x97, + 0xe7, 0x89, 0x87, 0xad, 0x1d, 0x41, 0xec, 0x64, 0x4d, 0x06, 0xf9, 0x73, + 0xd6, 0xb4, 0xf4, 0x48, 0x17, 0xcc, 0x2a, 0x6b, 0x49, 0xcf, 0x42, 0x63, + 0x13, 0x7d, 0x74, 0x24, 0x97, 0x90, 0xd8, 0xab, 0x96, 0xda, 0x52, 0x5a, + 0x7f, 0x1e, 0x6b, 0x7f, 0x6b, 0xcd, 0x1b, 0x18, 0x14, 0xb5, 0x3d, 0x85, + 0x76, 0xad, 0x50, 0x48, 0xeb, 0x0a, 0x86, 0xf0, 0x21, 0xb9, 0xb5, 0xf3, + 0x31, 0xed, 0x51, 0x45, 0x63, 0x87, 0x07, 0x9a, 0x97, 0x2d, 0x07, 0x15, + 0xa9, 0xa2, 0x30, 0x00, 0xa7, 0x64, 0x56, 0x45, 0x89, 0xe6, 0x62, 0x90, + 0xcb, 0x4c, 0x08, 0xda, 0x5f, 0x7a, 0x88, 0xcb, 0x5a, 0x28, 0xdc, 0x87, + 0x3b, 0x0c, 0x32, 0x55, 0x71, 0x2b, 0x33, 0x11, 0x5b, 0x2a, 0x66, 0x4e, + 0xa0, 0xa6, 0xa2, 0x7e, 0x95, 0xa2, 0x46, 0x77, 0x0e, 0xd4, 0xd3, 0x48, + 0x08, 0xcd, 0x30, 0xd5, 0x6c, 0x22, 0xbc, 0x8d, 0xe9, 0x4b, 0x1d, 0x43, + 0x1a, 0x26, 0x02, 0xa4, 0x55, 0xa1, 0x03, 0x2c, 0x2d, 0xb1, 0x63, 0xc0, + 0xab, 0x70, 0xe9, 0xa5, 0xba, 0xd3, 0x62, 0x2e, 0x47, 0xa7, 0x44, 0xbd, + 0xab, 0x3b, 0x53, 0xb6, 0xdb, 0x36, 0x54, 0x7f, 0x9c, 0x55, 0x45, 0x92, + 0x54, 0x4b, 0x66, 0x6e, 0x82, 0xad, 0xc1, 0xa7, 0x16, 0x3f, 0x30, 0xa8, + 0x2c, 0xbf, 0x0e, 0x99, 0x12, 0x8f, 0x99, 0x45, 0x67, 0x6a, 0x90, 0x2c, + 0x53, 0xf0, 0x38, 0xc0, 0xa6, 0x49, 0x40, 0xe0, 0x77, 0xa6, 0x19, 0x14, + 0x56, 0x05, 0x91, 0x35, 0xc0, 0xed, 0x55, 0xa6, 0x9b, 0xcc, 0x18, 0x22, + 0x98, 0x58, 0x80, 0xaa, 0xfa, 0x50, 0x2a, 0xc4, 0x68, 0xe9, 0x96, 0x62, + 0x59, 0x33, 0xda, 0xb7, 0x02, 0x15, 0x14, 0x21, 0x31, 0xd9, 0x22, 0x93, + 0x23, 0xd2, 0x8b, 0x10, 0x35, 0x91, 0x58, 0x55, 0x77, 0xb7, 0x4e, 0xe8, + 0x29, 0x05, 0x8a, 0x72, 0xe9, 0xf0, 0xb7, 0x6c, 0x1a, 0xab, 0x2e, 0x9b, + 0x93, 0xf2, 0x1a, 0xab, 0xf7, 0x0d, 0x86, 0xa6, 0x9b, 0x37, 0x4c, 0x52, + 0x36, 0x89, 0x26, 0x33, 0x9a, 0xad, 0x02, 0xe5, 0x39, 0x74, 0xf9, 0xa3, + 0xed, 0x9a, 0xa8, 0x46, 0x38, 0xa1, 0xd8, 0xa4, 0xc2, 0x96, 0xa4, 0x61, + 0x4b, 0x40, 0x05, 0x14, 0x80, 0x29, 0x68, 0x10, 0x94, 0xb4, 0x01, 0x2c, + 0x55, 0x6d, 0x05, 0x00, 0x4e, 0x12, 0x9f, 0x82, 0x3b, 0x50, 0x48, 0xe0, + 0x69, 0xf9, 0xa4, 0x23, 0xa8, 0x8a, 0xd6, 0x24, 0xfb, 0xb0, 0xaf, 0xe5, + 0x56, 0x15, 0x1b, 0xb7, 0x15, 0x77, 0x2a, 0xc3, 0xf6, 0x1f, 0xe2, 0x6a, + 0x77, 0xca, 0x2a, 0x6e, 0x50, 0xbb, 0x80, 0xa5, 0xf3, 0x28, 0x01, 0x3c, + 0xc6, 0xa4, 0xcd, 0x21, 0x8f, 0x8f, 0xef, 0x55, 0xc5, 0xcd, 0x20, 0x2c, + 0x47, 0xf2, 0x9a, 0x95, 0xa4, 0xf7, 0xa0, 0x08, 0x5e, 0x74, 0x1d, 0x5a, + 0xa9, 0xbc, 0xb9, 0x7e, 0x3a, 0x55, 0x08, 0x78, 0xe6, 0x91, 0xba, 0x53, + 0x40, 0x67, 0x4e, 0x39, 0x22, 0xb1, 0xa7, 0xe3, 0x35, 0x53, 0xd8, 0xba, + 0x65, 0x4f, 0x30, 0xf3, 0xcd, 0x20, 0x91, 0x8e, 0x79, 0xac, 0xac, 0x5b, + 0x91, 0x07, 0xda, 0x1c, 0xb1, 0xe6, 0xad, 0xa6, 0xe2, 0xa3, 0x9a, 0x87, + 0xa0, 0x22, 0x5c, 0x62, 0xac, 0x47, 0xc2, 0x52, 0x18, 0xbb, 0xaa, 0xb3, + 0x55, 0x81, 0x0c, 0xdf, 0x70, 0xd5, 0x68, 0xb8, 0x93, 0xf1, 0xaa, 0xe8, + 0x4a, 0xf8, 0x8d, 0x18, 0x46, 0x6a, 0x56, 0x5e, 0x2b, 0x9d, 0x1a, 0xb2, + 0xb4, 0xe2, 0x84, 0x39, 0x5a, 0x63, 0xe8, 0x55, 0x54, 0xcb, 0x9e, 0xbd, + 0x6a, 0xed, 0xac, 0x7b, 0x24, 0xc8, 0xa1, 0xb2, 0xba, 0x1a, 0xf0, 0x4f, + 0x2a, 0xae, 0x03, 0x9a, 0x73, 0xcc, 0xcd, 0xf7, 0x9c, 0x9a, 0xd1, 0x33, + 0x3b, 0x15, 0x9b, 0x14, 0xda, 0x86, 0x5a, 0x13, 0x34, 0xd2, 0xe0, 0x52, + 0x48, 0x06, 0x99, 0x85, 0x47, 0xe7, 0x56, 0x8a, 0x99, 0x9b, 0xa8, 0x34, + 0xc8, 0xde, 0xb4, 0xcc, 0x9a, 0xd1, 0x53, 0x46, 0x4e, 0x6c, 0x29, 0x2b, + 0x4b, 0x12, 0x25, 0x41, 0xd2, 0x5a, 0xa1, 0x12, 0x1a, 0x8e, 0xa4, 0x61, + 0x4c, 0x34, 0x01, 0x19, 0xa8, 0x65, 0x38, 0x14, 0xc4, 0x44, 0x16, 0xa4, + 0x44, 0xe6, 0xa4, 0x65, 0xc8, 0xa2, 0x26, 0xb4, 0xad, 0x2c, 0xc7, 0xf1, + 0xd4, 0x81, 0xa2, 0x91, 0x2c, 0x7d, 0x05, 0x3f, 0xb5, 0x31, 0x08, 0x2a, + 0x39, 0xa0, 0x59, 0x3e, 0xf0, 0xa1, 0x08, 0x45, 0x89, 0x13, 0xa2, 0xd4, + 0x9d, 0xa9, 0x0c, 0x55, 0xac, 0x2f, 0x12, 0x39, 0x8f, 0xcb, 0x23, 0xd7, + 0xfa, 0x55, 0x44, 0x4c, 0xe7, 0xcc, 0xa4, 0xf5, 0xa8, 0xcb, 0x66, 0xa2, + 0xc6, 0x82, 0x66, 0x93, 0xbd, 0x20, 0x1a, 0x4d, 0x0b, 0xd6, 0x98, 0x8d, + 0xed, 0x24, 0x6c, 0x8b, 0x35, 0xac, 0x1e, 0x84, 0x43, 0x17, 0x83, 0x4d, + 0xf2, 0xc1, 0xa6, 0x21, 0xa6, 0x1f, 0x43, 0x49, 0xe5, 0x37, 0xd6, 0x91, + 0x23, 0xbc, 0x8c, 0x8e, 0x95, 0x1b, 0x42, 0x16, 0x84, 0x03, 0x37, 0x62, + 0xa2, 0x79, 0xf8, 0xe6, 0x81, 0x99, 0x9a, 0x84, 0xf8, 0xe8, 0x6b, 0x0e, + 0x6e, 0x64, 0xcd, 0x31, 0xa1, 0x94, 0xa2, 0x82, 0xc7, 0x51, 0x41, 0x21, + 0x45, 0x31, 0x8b, 0x8a, 0x31, 0x48, 0x44, 0x89, 0x03, 0xbf, 0x41, 0x56, + 0xe2, 0xd3, 0xff, 0x00, 0xbc, 0x68, 0x25, 0x96, 0xd2, 0xd2, 0x30, 0xbd, + 0x2a, 0x74, 0x86, 0x35, 0xfe, 0x11, 0x48, 0x90, 0x64, 0xe6, 0x8e, 0x94, + 0xc4, 0x47, 0x8c, 0xd3, 0x84, 0x74, 0x86, 0x76, 0x1b, 0xa8, 0xc9, 0xf5, + 0xa0, 0xd4, 0x5a, 0x31, 0x48, 0x07, 0x88, 0xd8, 0xf6, 0xa9, 0x16, 0xdd, + 0xcd, 0x30, 0x24, 0x16, 0x9f, 0xde, 0x6a, 0x7f, 0x95, 0x02, 0x7d, 0xe2, + 0x28, 0x01, 0x0c, 0xf6, 0xd1, 0xf4, 0x1f, 0xa5, 0x30, 0xea, 0x3f, 0xdd, + 0x8e, 0x8b, 0x01, 0x19, 0xbd, 0xb8, 0x6e, 0x9c, 0x54, 0x12, 0x35, 0xcb, + 0x7f, 0x1d, 0x55, 0x90, 0x08, 0x90, 0x48, 0xdf, 0x78, 0xd5, 0xa5, 0x4c, + 0x52, 0x02, 0x55, 0xe2, 0xa5, 0x1c, 0xd0, 0x05, 0x0b, 0x94, 0xf9, 0xab, + 0x16, 0xfe, 0x2f, 0xdd, 0x33, 0x55, 0x30, 0x83, 0x33, 0xd1, 0x73, 0x4f, + 0xf2, 0x30, 0xbd, 0xf3, 0x58, 0xdc, 0xd8, 0xab, 0xe4, 0xb0, 0x6e, 0x6a, + 0xdd, 0xb1, 0xc8, 0xc1, 0xed, 0x4a, 0x48, 0x22, 0x49, 0x3f, 0x4e, 0x3b, + 0xd4, 0xe3, 0xee, 0x54, 0xb1, 0x8a, 0x9c, 0xd3, 0xa4, 0x87, 0x8c, 0xd3, + 0x4c, 0x19, 0x46, 0x61, 0x9a, 0xaa, 0x99, 0xf3, 0x2a, 0xfa, 0x02, 0x34, + 0x60, 0x3d, 0x2a, 0xc6, 0x6b, 0x13, 0x46, 0x41, 0x24, 0x6c, 0xfd, 0x05, + 0x3d, 0x2d, 0x8f, 0x7a, 0x4c, 0x11, 0x20, 0xb6, 0x45, 0xa7, 0x84, 0x0b, + 0x40, 0xc7, 0x6e, 0xc5, 0x34, 0xc9, 0x56, 0xa2, 0x27, 0x24, 0x30, 0xcb, + 0x4c, 0xf3, 0x0d, 0x6a, 0xa9, 0x99, 0x3a, 0x83, 0x79, 0x3d, 0xe8, 0x22, + 0xad, 0x44, 0xca, 0xe3, 0x29, 0xb5, 0x68, 0x90, 0xa5, 0xa0, 0x61, 0x45, + 0x20, 0x0a, 0xaf, 0xff, 0x00, 0x2d, 0xa9, 0x8c, 0x93, 0x14, 0xcc, 0x73, + 0x50, 0x01, 0xb6, 0x9a, 0x56, 0x8b, 0x81, 0x14, 0x9f, 0x28, 0xa8, 0x02, + 0x17, 0x6c, 0xd5, 0x08, 0x9a, 0x1b, 0x76, 0x90, 0xf4, 0xab, 0x70, 0xd8, + 0x3e, 0xf1, 0x52, 0x33, 0x4a, 0x1b, 0x60, 0x95, 0x61, 0x78, 0x34, 0x84, + 0x4f, 0x8c, 0x8a, 0x5c, 0x53, 0x00, 0xc5, 0x14, 0x80, 0x61, 0x14, 0x62, + 0x90, 0x0b, 0x59, 0x1a, 0xfd, 0xa9, 0xb9, 0x48, 0xb1, 0xd9, 0x8f, 0xf2, + 0xab, 0x83, 0xb1, 0x32, 0x31, 0x9a, 0xc2, 0x28, 0xa1, 0xf9, 0x8e, 0x5a, + 0xb3, 0x5e, 0xd7, 0x93, 0x83, 0x51, 0x72, 0xc6, 0x7d, 0x9d, 0x87, 0x4a, + 0x6e, 0xc7, 0x14, 0x05, 0xc3, 0x69, 0xee, 0x28, 0x14, 0x86, 0x6f, 0xe9, + 0xcf, 0xfb, 0xac, 0x55, 0xe0, 0xd4, 0xd1, 0x0c, 0x78, 0x6a, 0x76, 0xea, + 0x64, 0x86, 0xea, 0x43, 0x2e, 0x29, 0x0c, 0x3e, 0xd1, 0x50, 0xbc, 0xc5, + 0xa8, 0x10, 0xcd, 0xa6, 0xab, 0xcf, 0xc5, 0x00, 0x64, 0x6a, 0x1c, 0xf1, + 0x54, 0x7c, 0xba, 0x2e, 0x68, 0x90, 0x9e, 0x55, 0x37, 0xcb, 0x22, 0x80, + 0xb0, 0x98, 0x34, 0xf1, 0x1b, 0x1e, 0x94, 0x08, 0x7a, 0xdb, 0x48, 0xdd, + 0xaa, 0xc2, 0x69, 0xec, 0x7a, 0x9a, 0xa2, 0x2e, 0x4e, 0x9a, 0x72, 0xf7, + 0xa9, 0xd2, 0xd6, 0x34, 0xfe, 0x1a, 0x9b, 0x88, 0x97, 0x66, 0x29, 0x76, + 0xd0, 0x21, 0xd4, 0x50, 0x20, 0xa4, 0xc5, 0x00, 0x20, 0x14, 0xf0, 0x28, + 0x03, 0xb1, 0x5b, 0x67, 0xff, 0x00, 0x26, 0xa5, 0x16, 0x9e, 0xad, 0x41, + 0xa8, 0xef, 0x2e, 0x04, 0xfb, 0xc4, 0x1a, 0x69, 0xb9, 0xb6, 0x8f, 0xa0, + 0xfd, 0x28, 0x18, 0xc3, 0xa8, 0xff, 0x00, 0x71, 0x2a, 0x23, 0x7b, 0x70, + 0xdd, 0x38, 0xa3, 0x94, 0x06, 0x7f, 0xa4, 0x3f, 0x56, 0x34, 0xa2, 0xd8, + 0x9e, 0xa6, 0x98, 0x12, 0xad, 0xb2, 0xd4, 0xab, 0x02, 0xff, 0x00, 0x76, + 0x80, 0x24, 0x11, 0xd4, 0x4c, 0x3f, 0x79, 0x40, 0x12, 0x85, 0xe2, 0x97, + 0xcb, 0x34, 0x00, 0xf1, 0x15, 0x3f, 0x6e, 0x28, 0x02, 0xac, 0xe3, 0x71, + 0xac, 0x0d, 0x53, 0x70, 0x2c, 0x81, 0x4e, 0x18, 0x7a, 0x56, 0x9b, 0x89, + 0x14, 0xe0, 0x42, 0x3a, 0x8a, 0x9f, 0x8a, 0xe6, 0x92, 0x3a, 0x11, 0x0c, + 0xcc, 0x3a, 0x54, 0x70, 0xfc, 0x87, 0x9a, 0x4c, 0x48, 0x25, 0x6c, 0xb5, + 0x4e, 0x25, 0xf9, 0x40, 0xc5, 0x12, 0x2d, 0x12, 0xad, 0x49, 0xf3, 0x15, + 0xa5, 0x70, 0x21, 0xfb, 0x23, 0x37, 0xb5, 0x2a, 0x69, 0xc8, 0xa7, 0x27, + 0x93, 0x4f, 0x98, 0x14, 0x49, 0xc5, 0xbc, 0x6b, 0xda, 0x9d, 0xb5, 0x45, + 0x49, 0x41, 0xb8, 0x0a, 0x6e, 0xfa, 0xb5, 0x02, 0x39, 0xc4, 0xdd, 0x49, + 0x9a, 0xd1, 0x40, 0xc9, 0xd4, 0x1b, 0x4c, 0xad, 0x6c, 0x67, 0x70, 0xa4, + 0xa6, 0x01, 0x4a, 0x4d, 0x48, 0xc8, 0xe9, 0xb4, 0xc4, 0x34, 0x9a, 0x7a, + 0xf3, 0x48, 0x64, 0xde, 0x53, 0x7a, 0x53, 0x5a, 0x36, 0x03, 0xa5, 0x48, + 0x11, 0x66, 0xa0, 0x6f, 0xf5, 0xb4, 0xc0, 0x92, 0x9a, 0x6a, 0x46, 0x3d, + 0x69, 0x0d, 0x08, 0x08, 0x7c, 0x97, 0x9d, 0xba, 0x71, 0x56, 0xe3, 0xb1, + 0xe3, 0x9a, 0xa6, 0xc0, 0xb7, 0x6f, 0x6e, 0xb0, 0xf4, 0x15, 0x6b, 0x15, + 0x00, 0x3b, 0x14, 0x95, 0x42, 0x26, 0x46, 0xe2, 0x97, 0x75, 0x48, 0xc6, + 0x97, 0xa6, 0xef, 0xa0, 0x04, 0xdf, 0x4e, 0x06, 0x80, 0x0c, 0xd6, 0x76, + 0xaf, 0x26, 0xc8, 0x01, 0x1e, 0xf5, 0x48, 0x96, 0x60, 0xc8, 0xed, 0x25, + 0x20, 0x84, 0x9a, 0x82, 0x8b, 0x09, 0x67, 0xbc, 0x72, 0x0d, 0x59, 0x4d, + 0x35, 0x3a, 0xbd, 0x17, 0x01, 0xb7, 0x56, 0x91, 0x0b, 0x77, 0xc0, 0x19, + 0xc7, 0x15, 0xcd, 0x79, 0x4c, 0x1c, 0xf1, 0xdc, 0xd5, 0x74, 0x25, 0x6e, + 0x6a, 0xd8, 0xb6, 0xd5, 0xad, 0x28, 0xdf, 0x75, 0x24, 0x36, 0x49, 0x4f, + 0x0d, 0x54, 0x40, 0xd6, 0x7a, 0x88, 0xe6, 0x90, 0x08, 0xab, 0x52, 0xaa, + 0xd2, 0x01, 0x64, 0xe0, 0x56, 0x6d, 0xdc, 0xc1, 0x01, 0x26, 0x80, 0x31, + 0x66, 0x9c, 0x49, 0x25, 0x34, 0x73, 0x52, 0xcd, 0x90, 0xb4, 0x99, 0xa2, + 0xc0, 0xc7, 0x62, 0xa4, 0x49, 0x36, 0xf4, 0xa9, 0xdc, 0x56, 0x2c, 0xc7, + 0x77, 0x8e, 0xd5, 0x66, 0x3b, 0x85, 0x7a, 0x35, 0x25, 0xc4, 0x96, 0x93, + 0x35, 0xa1, 0x02, 0x6e, 0x14, 0x9b, 0xa8, 0x24, 0x5a, 0x28, 0x00, 0xc9, + 0x1d, 0xa9, 0x54, 0xe7, 0xb5, 0x02, 0x25, 0xc5, 0x19, 0xc5, 0x02, 0x3a, + 0x83, 0x77, 0x70, 0xdd, 0x38, 0xa6, 0xfe, 0xfd, 0xfa, 0xb9, 0xa6, 0x6e, + 0x28, 0xb7, 0xcf, 0x5a, 0x91, 0x6d, 0x94, 0x52, 0x02, 0x65, 0x84, 0x7a, + 0x53, 0x84, 0x74, 0x08, 0x77, 0x97, 0x4b, 0x85, 0xfe, 0xf5, 0x03, 0x0f, + 0x36, 0x35, 0xa4, 0xfb, 0x48, 0xec, 0x28, 0x00, 0xf3, 0x9c, 0xf6, 0xc5, + 0x39, 0x23, 0x24, 0xe4, 0xd0, 0x05, 0x90, 0x38, 0xa4, 0xa0, 0x03, 0x35, + 0x0c, 0x92, 0xd3, 0x11, 0x09, 0xa8, 0x9e, 0x14, 0x6e, 0xa2, 0x98, 0x15, + 0xa5, 0xb4, 0x5c, 0x70, 0x2b, 0x3e, 0xe2, 0xd4, 0xaf, 0x4a, 0x24, 0x69, + 0x06, 0x57, 0xfb, 0x3e, 0xe3, 0x52, 0xad, 0x9d, 0x73, 0xb3, 0x72, 0x45, + 0xb5, 0x5a, 0x78, 0x85, 0x45, 0x48, 0x0f, 0xc0, 0x14, 0x6e, 0x14, 0xec, + 0x31, 0x4b, 0x54, 0x7b, 0xeb, 0x45, 0x03, 0x27, 0x31, 0xbb, 0x8d, 0x27, + 0x35, 0xa2, 0x81, 0x9f, 0x38, 0x51, 0x56, 0x48, 0x51, 0x55, 0x61, 0x08, + 0x69, 0xb4, 0x00, 0x86, 0x9b, 0x9a, 0x40, 0x47, 0xe6, 0x8a, 0x63, 0x4c, + 0x2b, 0x3b, 0x94, 0x46, 0xd3, 0x0a, 0x8f, 0xce, 0x1e, 0xb4, 0x5c, 0x00, + 0x48, 0x1a, 0xb5, 0x6d, 0xa3, 0x53, 0x8a, 0xce, 0x52, 0x2a, 0x31, 0x3a, + 0x6b, 0xbd, 0x35, 0x52, 0x34, 0x2b, 0x8e, 0x14, 0x93, 0x59, 0x3a, 0x90, + 0x48, 0x2d, 0xc9, 0x26, 0xaa, 0x0e, 0xe9, 0x12, 0xce, 0x73, 0xcc, 0xf3, + 0x24, 0x24, 0x74, 0xa6, 0xb9, 0xf9, 0xa9, 0xdc, 0x76, 0x26, 0x19, 0x22, + 0x94, 0xc7, 0xc5, 0x4a, 0x60, 0x3a, 0x3c, 0x53, 0xe0, 0x29, 0x2b, 0x9f, + 0x6a, 0x04, 0x5c, 0x50, 0x07, 0x4a, 0x90, 0x55, 0x00, 0xb9, 0xc5, 0x2f, + 0x9a, 0x28, 0x01, 0x0c, 0xb5, 0x19, 0x91, 0x8d, 0x00, 0x27, 0x98, 0xde, + 0xb5, 0x34, 0x79, 0x22, 0x90, 0xc9, 0x31, 0x4d, 0xa0, 0x42, 0x35, 0x3e, + 0x3a, 0x40, 0x3f, 0x15, 0x4b, 0x52, 0x8c, 0x3a, 0xaa, 0x9f, 0xf3, 0xc5, + 0x5a, 0x21, 0x95, 0x3e, 0xc0, 0x31, 0xd6, 0xa5, 0x4b, 0x55, 0x5a, 0x86, + 0xcb, 0x25, 0x1b, 0x57, 0xa5, 0x31, 0xde, 0xa4, 0x0c, 0x9b, 0xc9, 0x82, + 0x9f, 0xbd, 0x54, 0x0b, 0x03, 0xd2, 0xac, 0x09, 0xed, 0x31, 0xe6, 0x63, + 0xd6, 0xb4, 0x56, 0x3a, 0x98, 0xb0, 0x63, 0xfa, 0x75, 0xa2, 0xb5, 0x33, + 0x12, 0xa2, 0x90, 0xf1, 0xc5, 0x24, 0x03, 0xa1, 0x27, 0x6e, 0x0f, 0x5a, + 0xb0, 0x38, 0x14, 0x86, 0x57, 0xb8, 0x7d, 0xdf, 0x2d, 0x65, 0xdf, 0x63, + 0xcb, 0xda, 0x68, 0x1a, 0x32, 0x9a, 0x2a, 0x45, 0x14, 0x8b, 0x1f, 0x49, + 0x8e, 0x68, 0x28, 0x90, 0x0e, 0x29, 0x6a, 0x09, 0x03, 0x42, 0xcb, 0xb1, + 0xb3, 0x4e, 0xc2, 0xb9, 0x60, 0x5d, 0xb9, 0xa7, 0x89, 0x19, 0xba, 0xb5, + 0x55, 0x88, 0x14, 0xff, 0x00, 0xbf, 0x4e, 0x8c, 0x65, 0xaa, 0xac, 0x49, + 0x6d, 0x13, 0x8a, 0x7f, 0x14, 0x99, 0x21, 0x8a, 0x31, 0x40, 0x0b, 0x51, + 0x3d, 0x16, 0x03, 0xb4, 0x09, 0x4f, 0x09, 0x41, 0xb0, 0xec, 0x01, 0xde, + 0x93, 0xcc, 0x8c, 0x50, 0x02, 0x1b, 0x81, 0xd9, 0x69, 0xbe, 0x73, 0x9e, + 0x82, 0x80, 0x1a, 0x7c, 0xe3, 0xde, 0xb9, 0xfb, 0x9d, 0x53, 0xca, 0xb8, + 0x2a, 0xd2, 0x55, 0x72, 0xfb, 0xa2, 0x4f, 0xde, 0xb1, 0xa7, 0xa7, 0xde, + 0xdb, 0xdc, 0x60, 0x6f, 0x15, 0xae, 0x91, 0x2d, 0x62, 0xa5, 0xd0, 0xb9, + 0x44, 0x94, 0x01, 0x4e, 0xad, 0x09, 0x17, 0x35, 0x1b, 0x1a, 0x04, 0x42, + 0xcf, 0x51, 0xd3, 0x00, 0xa2, 0x81, 0x8c, 0x35, 0x04, 0xb1, 0xe6, 0x98, + 0xd1, 0x5b, 0x6f, 0xb5, 0x1b, 0x4d, 0x65, 0xca, 0x6d, 0xcc, 0x34, 0x8a, + 0x84, 0xb9, 0xdf, 0x8a, 0xb5, 0x4c, 0x8f, 0x68, 0x32, 0xe5, 0xca, 0xa1, + 0xc5, 0x16, 0xfb, 0xb6, 0xf3, 0x56, 0xe3, 0x62, 0x39, 0xae, 0x4a, 0x6a, + 0x3a, 0x64, 0x85, 0x14, 0xc0, 0x28, 0xa0, 0x41, 0x45, 0x50, 0x08, 0x4d, + 0x30, 0x9a, 0x43, 0x23, 0x67, 0xc5, 0x20, 0xff, 0x00, 0x55, 0x4e, 0xc0, + 0x67, 0xaa, 0x33, 0xb9, 0xe6, 0xa0, 0x96, 0x62, 0xa7, 0x07, 0xad, 0x4c, + 0xa1, 0xd4, 0xab, 0x90, 0x99, 0x58, 0xf7, 0xa8, 0xdd, 0xda, 0xb9, 0xc0, + 0x96, 0xd2, 0x6f, 0x9f, 0x69, 0xef, 0x5b, 0x30, 0xce, 0xf1, 0x91, 0xcd, + 0x46, 0xe5, 0xa6, 0x69, 0x5c, 0xeb, 0xf7, 0xed, 0x6d, 0xb3, 0x78, 0x03, + 0x6e, 0xda, 0xe7, 0xb5, 0x3b, 0xcb, 0x89, 0xf8, 0x92, 0x53, 0x8f, 0x4a, + 0xb8, 0xab, 0x0f, 0xcc, 0x5b, 0x1c, 0x2a, 0x7c, 0xd5, 0x25, 0xcc, 0xa9, + 0xb7, 0xe5, 0xa8, 0x4d, 0x89, 0x8f, 0xfb, 0x7a, 0x05, 0xe0, 0x54, 0x2f, + 0x7c, 0xc6, 0x9a, 0x89, 0x44, 0x6d, 0x23, 0x95, 0xeb, 0x5a, 0x3a, 0x6c, + 0x65, 0x13, 0x9e, 0xf5, 0x6c, 0x92, 0xed, 0x2e, 0x69, 0x90, 0x3d, 0x95, + 0xb1, 0x40, 0x8c, 0xd3, 0x18, 0x86, 0x9e, 0xb1, 0x66, 0x91, 0x42, 0xf9, + 0x27, 0x35, 0x32, 0xa6, 0x05, 0x04, 0x92, 0xaa, 0xd4, 0x72, 0x75, 0xa0, + 0x44, 0x75, 0x22, 0xd2, 0x01, 0xf5, 0x4b, 0x50, 0xfe, 0x1f, 0xad, 0x51, + 0x24, 0x4b, 0x2f, 0xcb, 0xcd, 0x46, 0xf3, 0xe3, 0xf8, 0xab, 0x3b, 0x14, + 0x56, 0x6b, 0xd4, 0x15, 0x4e, 0x7b, 0xa6, 0x7f, 0xbb, 0x42, 0x02, 0x9b, + 0x2e, 0x4e, 0x69, 0x0e, 0x05, 0x3b, 0x95, 0x62, 0x1d, 0xce, 0x1f, 0x2a, + 0x71, 0x57, 0x62, 0xbe, 0x9c, 0x0f, 0x98, 0xe6, 0x95, 0xae, 0x04, 0xff, + 0x00, 0x6e, 0x24, 0x7c, 0xc9, 0x47, 0xdb, 0x2a, 0x85, 0xca, 0x39, 0x6f, + 0x13, 0xb8, 0xa9, 0x96, 0xea, 0x13, 0x4b, 0x51, 0x72, 0x92, 0x09, 0xa1, + 0xfe, 0xf5, 0x0d, 0x3c, 0x67, 0xf8, 0xa8, 0xe6, 0x17, 0x29, 0x56, 0x7b, + 0xa8, 0xd7, 0xa1, 0xcd, 0x65, 0xcc, 0xc6, 0x47, 0xa0, 0x69, 0x11, 0x62, + 0x9b, 0x81, 0x4a, 0xe5, 0x87, 0x14, 0xdd, 0xf8, 0xa4, 0x21, 0x86, 0x4a, + 0x4d, 0xc6, 0xae, 0xc2, 0xb8, 0xf1, 0x27, 0xa8, 0xa9, 0x01, 0x8d, 0xbd, + 0x28, 0x13, 0x1e, 0x23, 0xf4, 0x34, 0xe1, 0x01, 0xf5, 0xa7, 0x72, 0x09, + 0x92, 0x2a, 0xbb, 0x1a, 0x71, 0xd6, 0x99, 0x2c, 0x7d, 0x2d, 0x04, 0x0b, + 0x46, 0x28, 0x00, 0xc5, 0x26, 0xda, 0x00, 0xea, 0xbc, 0xe7, 0xec, 0x29, + 0x7f, 0x78, 0xdd, 0xe9, 0x9b, 0x8f, 0x10, 0x16, 0xea, 0x6a, 0x41, 0x6d, + 0x48, 0x43, 0xc4, 0x20, 0x54, 0x98, 0xc5, 0x00, 0x57, 0xbc, 0x97, 0xc9, + 0x81, 0x9a, 0xbc, 0xd6, 0xea, 0x76, 0x92, 0xe5, 0x89, 0xf5, 0x23, 0xaf, + 0xb9, 0xae, 0x85, 0xfc, 0x33, 0x35, 0xf1, 0x89, 0x6d, 0x75, 0x25, 0xbc, + 0xbb, 0x90, 0xe2, 0xbb, 0xad, 0x13, 0x56, 0x4b, 0x98, 0x42, 0xb1, 0xf9, + 0xab, 0xcf, 0xa9, 0xa4, 0xae, 0x77, 0x7c, 0x51, 0x36, 0x41, 0xa7, 0x66, + 0xb6, 0x47, 0x38, 0xb5, 0x1c, 0x87, 0x8a, 0xa4, 0x26, 0x56, 0xcd, 0x46, + 0x25, 0x56, 0x3c, 0x1a, 0x00, 0x7e, 0x69, 0x73, 0x4c, 0x00, 0xd3, 0x68, + 0x01, 0x36, 0x8a, 0x6b, 0x2d, 0x34, 0x04, 0x0e, 0xb5, 0x46, 0x51, 0x89, + 0x81, 0xad, 0x09, 0xea, 0x2c, 0x91, 0xef, 0x5a, 0x21, 0x18, 0x8e, 0x93, + 0x1a, 0x1e, 0x6a, 0x23, 0x40, 0x82, 0x8a, 0x06, 0x21, 0x35, 0x19, 0x93, + 0x14, 0x80, 0x4f, 0x32, 0x9a, 0xd2, 0xe0, 0x53, 0x03, 0x36, 0x6b, 0xf7, + 0x17, 0x7b, 0x41, 0x3b, 0x6b, 0x49, 0x3e, 0x61, 0x53, 0x3d, 0x19, 0x4b, + 0x61, 0x66, 0x0a, 0x22, 0xf7, 0xc5, 0x44, 0x0f, 0x6a, 0xb4, 0x4a, 0x1b, + 0x6a, 0xc1, 0x9c, 0xe0, 0x56, 0x7e, 0xa0, 0x37, 0xdc, 0x7e, 0x02, 0x9f, + 0x46, 0x4b, 0xd5, 0x95, 0xc4, 0x75, 0x15, 0xc7, 0x0b, 0x5c, 0x69, 0x96, + 0x43, 0x01, 0xc4, 0x9b, 0xab, 0x4a, 0x1b, 0x82, 0x13, 0x15, 0x56, 0xbb, + 0x2d, 0x12, 0x5c, 0x6a, 0x1f, 0xbb, 0xc6, 0x3a, 0x56, 0x64, 0xb7, 0x26, + 0x43, 0x55, 0xcb, 0x61, 0xf3, 0x13, 0x09, 0x36, 0xae, 0x0d, 0x3b, 0xe5, + 0x7e, 0x6b, 0x3d, 0x88, 0x1e, 0x29, 0x0d, 0x17, 0x34, 0x52, 0x27, 0xb7, + 0x5f, 0x33, 0x02, 0xb6, 0x93, 0x85, 0x14, 0x5f, 0x51, 0x31, 0xf4, 0xe8, + 0x86, 0xe6, 0xab, 0x24, 0xb2, 0x29, 0xc2, 0x98, 0x88, 0xd8, 0x7c, 0xd4, + 0xe5, 0xa4, 0x34, 0x4e, 0xa4, 0x52, 0xee, 0x5f, 0x51, 0x4a, 0xe0, 0x2e, + 0xf5, 0xf5, 0xa8, 0x1f, 0x93, 0x4c, 0x42, 0x0a, 0x75, 0x30, 0x1c, 0x0d, + 0x67, 0x6a, 0x93, 0xf9, 0x45, 0x3e, 0xbf, 0xd2, 0x98, 0x8a, 0x5f, 0x68, + 0x69, 0x3e, 0xe8, 0xc5, 0x54, 0xba, 0xdc, 0x5b, 0x04, 0xd4, 0x21, 0x90, + 0x84, 0xa4, 0x69, 0x11, 0x6a, 0x0d, 0x36, 0x2b, 0xb4, 0x99, 0xa6, 0x53, + 0x0b, 0x0f, 0x5a, 0x90, 0x50, 0x30, 0xa2, 0x98, 0x09, 0x45, 0x2b, 0x92, + 0x14, 0xd6, 0x22, 0x90, 0xc8, 0xc9, 0x15, 0x19, 0x92, 0x98, 0x11, 0x3c, + 0xc0, 0x54, 0x2d, 0x71, 0xe9, 0x55, 0xca, 0x4d, 0xc8, 0x8c, 0xac, 0x68, + 0xdf, 0x54, 0x48, 0xe0, 0xd5, 0x25, 0x20, 0x16, 0x97, 0x14, 0x0c, 0x70, + 0xc8, 0xe9, 0x52, 0x2c, 0xf2, 0x0e, 0xf4, 0x84, 0x4a, 0x2e, 0xdf, 0xbd, + 0x4c, 0x97, 0x39, 0xea, 0x48, 0xa0, 0x4e, 0x25, 0xb8, 0x5f, 0x23, 0xef, + 0x66, 0xac, 0x0a, 0x68, 0xc9, 0xa1, 0x77, 0x01, 0x46, 0x68, 0x24, 0x4c, + 0xd3, 0x77, 0x53, 0x03, 0xb3, 0x0a, 0x05, 0x3c, 0x53, 0x66, 0xe4, 0x80, + 0xd2, 0xd0, 0x21, 0x0d, 0x47, 0xbf, 0x9a, 0x43, 0x1b, 0x73, 0x17, 0x98, + 0x84, 0x11, 0x95, 0x35, 0xc3, 0xeb, 0xda, 0x4b, 0x5a, 0xbf, 0x99, 0x18, + 0xf9, 0x0d, 0x74, 0xd1, 0x77, 0x56, 0x31, 0x97, 0xbb, 0x23, 0x0c, 0xe4, + 0x1a, 0xbb, 0xa6, 0xde, 0x1b, 0x7b, 0xa5, 0x62, 0x78, 0xae, 0x7a, 0xd1, + 0xd0, 0xeb, 0xa4, 0xf5, 0x3b, 0xfb, 0x1b, 0xe4, 0xb9, 0xb7, 0x56, 0x07, + 0x9a, 0xb2, 0xb2, 0x66, 0xb1, 0xa7, 0xb1, 0x32, 0xdc, 0x94, 0x1a, 0x64, + 0xc7, 0x8a, 0xd5, 0x10, 0x51, 0xb9, 0x93, 0xcb, 0x89, 0x9b, 0xd2, 0xa9, + 0x69, 0x88, 0x7c, 0xc9, 0x1c, 0x9e, 0xbd, 0x3f, 0x3a, 0x72, 0xf8, 0x42, + 0x26, 0x86, 0x69, 0x77, 0x50, 0x02, 0x6e, 0xa3, 0x34, 0x0c, 0x5c, 0xd2, + 0x66, 0x80, 0x13, 0x15, 0x46, 0xed, 0x30, 0x73, 0x57, 0x12, 0x47, 0xb2, + 0x7c, 0xbf, 0x85, 0x44, 0xa2, 0x8e, 0x82, 0x11, 0xf8, 0xaa, 0xcf, 0x32, + 0x03, 0xf7, 0x85, 0x50, 0xc3, 0xce, 0x04, 0x71, 0x4c, 0x32, 0x35, 0x4a, + 0x01, 0xbb, 0xe9, 0x3a, 0xd2, 0x65, 0x12, 0xad, 0x05, 0x44, 0x9c, 0x1a, + 0x23, 0x2b, 0x03, 0x33, 0xae, 0x74, 0xb9, 0x03, 0xef, 0x8f, 0x9a, 0xd2, + 0xb5, 0x80, 0x98, 0x79, 0xa7, 0x57, 0x5b, 0x34, 0x28, 0x6c, 0x54, 0xbb, + 0x3f, 0xbf, 0x09, 0xe9, 0x4b, 0xb5, 0xb1, 0xef, 0x4c, 0x3a, 0x0f, 0xb4, + 0x84, 0xae, 0xe6, 0x38, 0xe6, 0xa3, 0xb9, 0xd3, 0x9d, 0xfe, 0x74, 0xab, + 0x4d, 0x6c, 0x4b, 0x32, 0x9f, 0x7c, 0x47, 0x0e, 0x2a, 0xb4, 0xd2, 0x8a, + 0xc1, 0xc2, 0xcc, 0xad, 0xc6, 0x27, 0xcd, 0x56, 0xe0, 0x1c, 0x50, 0x31, + 0x97, 0x08, 0x76, 0x1e, 0x2a, 0x90, 0x1c, 0xd6, 0xf2, 0x8e, 0x82, 0x45, + 0xc9, 0xe3, 0x7f, 0x28, 0x30, 0x1c, 0x0e, 0xb5, 0x02, 0x3e, 0x2b, 0x07, + 0xb0, 0xc7, 0xfd, 0xa3, 0xb5, 0x3b, 0xcf, 0x3e, 0x95, 0x9d, 0x80, 0xbd, + 0x67, 0x20, 0x4c, 0x39, 0xad, 0x34, 0xba, 0x0d, 0xd3, 0x15, 0x8f, 0x53, + 0x5d, 0xc9, 0x7c, 0xcf, 0xa5, 0x39, 0x2e, 0x36, 0x75, 0xc5, 0x69, 0x71, + 0x58, 0x71, 0xd4, 0x23, 0x15, 0x0b, 0x6b, 0x11, 0xad, 0x51, 0x03, 0x3f, + 0xb6, 0xa2, 0xfe, 0xf5, 0x30, 0xeb, 0x91, 0xfa, 0xd1, 0x66, 0x05, 0x59, + 0xbc, 0x43, 0xfd, 0xca, 0xaa, 0xda, 0xec, 0xc7, 0xb9, 0xad, 0x39, 0x45, + 0x72, 0x4b, 0x5d, 0x4e, 0x79, 0xe4, 0xda, 0xcf, 0x5d, 0x1d, 0xb6, 0xe3, + 0x18, 0xcd, 0x62, 0xfe, 0x22, 0x8b, 0x21, 0x31, 0x4b, 0x8a, 0xd1, 0x12, + 0x57, 0x96, 0x53, 0x1f, 0xf0, 0xd7, 0x3d, 0x7b, 0xaa, 0xf9, 0xf2, 0xe3, + 0x67, 0x4a, 0xa9, 0x2d, 0x02, 0x3b, 0x96, 0x2d, 0xef, 0x20, 0x23, 0xae, + 0x2a, 0xb5, 0xec, 0xea, 0x65, 0xf9, 0x6b, 0x9e, 0x37, 0x35, 0x65, 0x36, + 0x76, 0x6a, 0x4d, 0xbe, 0xb5, 0x4c, 0x61, 0x8a, 0x4a, 0x43, 0x01, 0x52, + 0x50, 0x21, 0x69, 0x2a, 0x84, 0x34, 0x9a, 0x63, 0x49, 0x49, 0x81, 0x1f, + 0x9b, 0x50, 0xbc, 0xe2, 0x9d, 0x89, 0x64, 0x2d, 0x71, 0xe9, 0x51, 0x19, + 0x09, 0xab, 0xb1, 0x17, 0x19, 0x9a, 0x4a, 0xa0, 0x16, 0x8a, 0x00, 0x5a, + 0x76, 0x69, 0x00, 0xf0, 0xd4, 0xf5, 0x6a, 0x06, 0x48, 0x0d, 0x3a, 0xa0, + 0x02, 0x9a, 0x5c, 0x0a, 0x60, 0x33, 0xed, 0x2c, 0xa7, 0x83, 0x57, 0x6d, + 0x35, 0x20, 0x4e, 0xd9, 0x68, 0x62, 0x34, 0x70, 0x24, 0x5c, 0x83, 0xc5, + 0x41, 0xb4, 0xa1, 0xe3, 0x8a, 0xa5, 0xa9, 0x90, 0x07, 0x97, 0xd6, 0x9d, + 0xf3, 0x37, 0x7a, 0x62, 0x3b, 0xbd, 0xd4, 0x66, 0x83, 0x52, 0x78, 0xf6, + 0xe2, 0xa5, 0xf9, 0x29, 0x01, 0x04, 0xec, 0x16, 0xaa, 0x97, 0xa6, 0xc4, + 0x89, 0x62, 0x93, 0xb1, 0xa8, 0x6f, 0x6d, 0x52, 0x68, 0xf6, 0xb0, 0xc8, + 0x34, 0x42, 0x56, 0x62, 0xa8, 0xae, 0x8e, 0x13, 0x57, 0xb0, 0x6b, 0x3b, + 0x9e, 0x73, 0xb4, 0xf4, 0xac, 0xec, 0x60, 0xd6, 0xd5, 0x57, 0x50, 0xa4, + 0xf4, 0x34, 0xf4, 0xed, 0x51, 0xad, 0x48, 0x19, 0xe2, 0xbb, 0x4d, 0x3a, + 0xee, 0x39, 0xed, 0xc3, 0x67, 0x9a, 0xe1, 0xf8, 0x19, 0xd0, 0xf5, 0x57, + 0x2d, 0x89, 0x69, 0x25, 0x7e, 0x2b, 0x74, 0x64, 0x66, 0xea, 0x32, 0x7e, + 0xe0, 0x8f, 0x5c, 0xd3, 0xac, 0x76, 0xa4, 0x1b, 0x47, 0xa9, 0x34, 0x48, + 0x6b, 0x62, 0x6d, 0xe2, 0x8c, 0xd0, 0x20, 0xa5, 0xcd, 0x00, 0x2e, 0x69, + 0x69, 0x80, 0xea, 0xaf, 0x74, 0xb9, 0x02, 0x9a, 0x25, 0x92, 0xec, 0xcc, + 0x55, 0x53, 0x18, 0x26, 0xa9, 0x6c, 0x2e, 0xa6, 0x6e, 0xa3, 0x79, 0xe5, + 0xa3, 0x2a, 0xe7, 0x76, 0x2b, 0x9a, 0x92, 0x69, 0x59, 0xfe, 0x62, 0x6b, + 0x6b, 0x59, 0x0a, 0x25, 0xeb, 0x09, 0x78, 0xc1, 0x35, 0xaf, 0x01, 0xdf, + 0xc5, 0x73, 0x6c, 0xcd, 0x65, 0xa8, 0xe7, 0xb6, 0x6e, 0xab, 0xd2, 0x9d, + 0x1c, 0x47, 0xbd, 0x6d, 0x52, 0xd6, 0xb9, 0x10, 0xec, 0x3e, 0x40, 0x91, + 0xaf, 0x26, 0xab, 0x24, 0xeb, 0xbb, 0xad, 0x60, 0x59, 0xa3, 0x03, 0x2c, + 0x8b, 0x52, 0x49, 0x19, 0xd9, 0xf2, 0x55, 0x41, 0xdc, 0x97, 0xa1, 0x94, + 0x96, 0xb2, 0xfd, 0xb3, 0xf7, 0xcb, 0xde, 0xb4, 0x3e, 0xc9, 0xc5, 0x6f, + 0xcb, 0xa8, 0x93, 0xd0, 0x6b, 0x47, 0xb6, 0x9d, 0x11, 0xf5, 0xac, 0xe4, + 0xac, 0x51, 0x05, 0xdd, 0xb4, 0x2c, 0xa4, 0xb2, 0xd7, 0x35, 0x79, 0xa7, + 0x49, 0xbb, 0x74, 0x63, 0x8a, 0x49, 0xdc, 0x56, 0xb1, 0x57, 0x98, 0xc6, + 0x3b, 0xd5, 0xdb, 0x4f, 0xf5, 0x64, 0xb5, 0x44, 0x95, 0x86, 0xb5, 0x3a, + 0x64, 0xb2, 0xb7, 0x7b, 0x0f, 0xba, 0x32, 0x6b, 0x09, 0xf4, 0x99, 0x11, + 0x1e, 0x60, 0x03, 0x46, 0xb9, 0xef, 0xef, 0x5a, 0xa9, 0xde, 0x16, 0x33, + 0x51, 0xe5, 0x98, 0x0f, 0x96, 0x33, 0x55, 0x0d, 0xba, 0x93, 0x58, 0x6c, + 0x6b, 0x2d, 0xc6, 0xfd, 0x95, 0x73, 0x47, 0xc8, 0x9d, 0x05, 0x65, 0x76, + 0xc4, 0x46, 0xd3, 0x0a, 0x44, 0xb9, 0xd9, 0x4e, 0xc6, 0xd1, 0x76, 0x1f, + 0xf6, 0xf9, 0x7a, 0x06, 0x34, 0xdf, 0xb4, 0xcd, 0xfd, 0xe3, 0x56, 0xa2, + 0x4b, 0x91, 0x19, 0x79, 0x18, 0xfd, 0xf3, 0x40, 0xb5, 0x91, 0xf9, 0xe2, + 0xaf, 0x44, 0x66, 0x3b, 0xec, 0x4f, 0xed, 0x47, 0xd8, 0xcf, 0xad, 0x1c, + 0xc1, 0x60, 0xfb, 0x18, 0x1d, 0x5e, 0x9d, 0xf6, 0x78, 0x97, 0xa9, 0xa3, + 0x98, 0x2c, 0x44, 0x24, 0x58, 0xa5, 0xca, 0x56, 0x9d, 0xa6, 0xbf, 0x24, + 0x43, 0x6f, 0xde, 0xc5, 0x65, 0x38, 0x5c, 0xb8, 0xb3, 0x4a, 0x0f, 0x11, + 0xab, 0x7f, 0xac, 0x5c, 0x56, 0x94, 0x3a, 0x9c, 0x32, 0xf4, 0xa9, 0xd6, + 0x23, 0x71, 0x25, 0x96, 0xea, 0x2f, 0x25, 0xb0, 0x6b, 0x8e, 0x91, 0x01, + 0x95, 0xbe, 0xa7, 0xf9, 0xd6, 0xbc, 0xde, 0xe8, 0xa1, 0x1d, 0x45, 0x10, + 0x8a, 0x5f, 0x28, 0x0a, 0xc2, 0xe6, 0xf6, 0x0c, 0x51, 0x4c, 0x43, 0x0d, + 0x36, 0x82, 0x40, 0x53, 0xf3, 0x8a, 0x60, 0x21, 0x7a, 0x89, 0xe5, 0xc5, + 0x3d, 0xc9, 0x2b, 0xbd, 0xc0, 0x15, 0x0b, 0x5c, 0x1e, 0xd5, 0x7c, 0xa4, + 0x36, 0x44, 0x5c, 0xb7, 0x5a, 0x65, 0x59, 0x21, 0x45, 0x00, 0x25, 0x2d, + 0x00, 0x14, 0xb4, 0x00, 0xb4, 0xb4, 0x80, 0x29, 0x45, 0x00, 0x3c, 0x35, + 0x3f, 0x77, 0x15, 0x36, 0x19, 0x13, 0x4d, 0xe9, 0x51, 0x97, 0x26, 0xaa, + 0xc2, 0x1b, 0x4b, 0x4c, 0x0b, 0xb6, 0x97, 0xcd, 0x0b, 0x7f, 0xb3, 0x5a, + 0x1f, 0x6d, 0x8d, 0x86, 0x6b, 0x3b, 0x59, 0x8a, 0x48, 0x95, 0x24, 0x57, + 0xfb, 0xa6, 0x94, 0xd5, 0x19, 0x9d, 0xa6, 0x4d, 0x49, 0x1c, 0x4e, 0xc7, + 0xa5, 0x51, 0xa1, 0x68, 0x46, 0x40, 0xa4, 0x67, 0x0b, 0x41, 0x37, 0x28, + 0xcc, 0xe5, 0x8d, 0x34, 0x35, 0x0c, 0xa4, 0x47, 0x3c, 0xfe, 0x50, 0x18, + 0xa5, 0x49, 0xa4, 0x75, 0xeb, 0x53, 0xd4, 0x2f, 0x72, 0xad, 0xf4, 0x0b, + 0x73, 0x19, 0x47, 0x5a, 0xe4, 0x75, 0x1b, 0x19, 0x6d, 0x1c, 0xef, 0x5c, + 0x2f, 0xad, 0x75, 0x47, 0xde, 0x8d, 0x8c, 0xbe, 0x19, 0x14, 0xc5, 0x68, + 0x58, 0xdf, 0xcb, 0x6e, 0xc3, 0x0d, 0xc5, 0x72, 0xce, 0x3a, 0x1d, 0x11, + 0x67, 0x61, 0xa7, 0xcf, 0xf6, 0x88, 0xb7, 0x54, 0xf3, 0x4e, 0x8b, 0x16, + 0x59, 0xc0, 0xf4, 0xc9, 0xa9, 0xa7, 0xa8, 0xa5, 0xb9, 0x8d, 0xa9, 0xdf, + 0x05, 0x65, 0xf2, 0xb0, 0xf4, 0x1d, 0x43, 0xec, 0xd0, 0x6e, 0xc7, 0xcc, + 0x6b, 0xa1, 0x53, 0xe6, 0x69, 0x13, 0x7b, 0x13, 0xe9, 0x53, 0x49, 0x72, + 0xa6, 0x47, 0xcf, 0x5f, 0x5f, 0x7a, 0xd0, 0x35, 0x8b, 0x5e, 0xf3, 0x28, + 0x29, 0x69, 0x88, 0x5a, 0x7d, 0x30, 0x1c, 0x29, 0xb3, 0x0f, 0x96, 0x9a, + 0x25, 0x8f, 0x87, 0xfd, 0x4f, 0xe3, 0x50, 0xa4, 0x79, 0x62, 0x29, 0xad, + 0x83, 0xa9, 0x4b, 0x54, 0xd1, 0xd6, 0x54, 0xca, 0x8e, 0x7d, 0xab, 0x99, + 0x6b, 0x53, 0x14, 0xa5, 0x66, 0xf9, 0x3d, 0xeb, 0xa7, 0xe2, 0x89, 0x92, + 0xde, 0xc5, 0x59, 0x18, 0x45, 0x2e, 0x15, 0xb3, 0x5a, 0xd6, 0xcf, 0xc8, + 0x39, 0xae, 0x4a, 0x9b, 0x9d, 0x10, 0xd8, 0xd8, 0xb7, 0x6d, 0xc0, 0x54, + 0xcd, 0x18, 0x23, 0x8e, 0xb4, 0x26, 0x4b, 0xd0, 0xcd, 0xb9, 0xb7, 0x79, + 0x32, 0x8e, 0x6a, 0x18, 0xec, 0xbc, 0xbe, 0xe6, 0xa9, 0xae, 0x84, 0xfb, + 0x42, 0xe5, 0xbe, 0x52, 0xb4, 0x61, 0x62, 0xc3, 0x9a, 0x9d, 0x8b, 0xdc, + 0xbf, 0x6b, 0x66, 0x27, 0x93, 0xa5, 0x68, 0x7f, 0x63, 0x2e, 0x2b, 0x68, + 0x4c, 0x86, 0xac, 0x43, 0x26, 0x8e, 0x8b, 0xc9, 0xac, 0xfb, 0xb8, 0x12, + 0x25, 0xe2, 0x94, 0xdd, 0xc0, 0xc1, 0xd5, 0x3c, 0xc6, 0x5d, 0xb1, 0xe6, + 0x9b, 0x0c, 0x6f, 0xe5, 0x61, 0x85, 0x27, 0x6b, 0x15, 0x72, 0x9e, 0xa3, + 0x69, 0x19, 0x8f, 0x20, 0x60, 0xd6, 0x68, 0x27, 0xa2, 0xd6, 0x72, 0xd5, + 0x04, 0x74, 0x67, 0x45, 0x63, 0x3e, 0x6d, 0xf1, 0x54, 0xe7, 0xd4, 0x4a, + 0xdb, 0x49, 0x6d, 0xb3, 0x3b, 0xb2, 0x3a, 0xd4, 0xc3, 0xe1, 0x2d, 0xbd, + 0x4a, 0xd1, 0x9d, 0xe9, 0x4d, 0x64, 0xc5, 0x65, 0x71, 0x32, 0x19, 0x98, + 0x2a, 0x1a, 0xa0, 0x5b, 0x71, 0xaa, 0x8a, 0x04, 0x26, 0xd3, 0x46, 0xca, + 0xb2, 0xc5, 0x58, 0xfb, 0x9a, 0x75, 0x51, 0x98, 0x99, 0xc5, 0x2f, 0xda, + 0x1b, 0xb5, 0x2b, 0x01, 0x0b, 0x5c, 0xb8, 0x3f, 0x78, 0xd3, 0x4d, 0xc3, + 0xfa, 0xd1, 0xca, 0x17, 0x13, 0xcd, 0x73, 0xde, 0x98, 0x4d, 0x30, 0x15, + 0x73, 0x56, 0x6d, 0xe1, 0xf5, 0xa8, 0x94, 0x8a, 0x8a, 0x2f, 0xc5, 0x6f, + 0x57, 0x63, 0x01, 0x6b, 0x16, 0xcd, 0xed, 0x61, 0xec, 0xff, 0x00, 0x2e, + 0x2a, 0x8b, 0x8e, 0x69, 0xdc, 0x04, 0x14, 0x1a, 0x45, 0x0d, 0xa4, 0xc5, + 0x04, 0x89, 0x4d, 0x38, 0xaa, 0x11, 0x1b, 0x48, 0x05, 0x42, 0xf7, 0x1e, + 0x95, 0x4a, 0x06, 0x7c, 0xc5, 0x67, 0x9d, 0x8d, 0x45, 0x92, 0x7a, 0xd6, + 0xbc, 0xb6, 0x33, 0xe6, 0x13, 0x14, 0x62, 0x81, 0x5c, 0x5c, 0x52, 0xe2, + 0x81, 0x0b, 0xb6, 0x93, 0xcb, 0xa0, 0x43, 0x48, 0xc5, 0x36, 0x99, 0x41, + 0x4b, 0x48, 0x62, 0xd1, 0x48, 0x05, 0xa5, 0xa0, 0x07, 0x53, 0xbf, 0x86, + 0xa7, 0xa8, 0x15, 0xcf, 0x5a, 0x4a, 0xb0, 0x16, 0x8a, 0x00, 0x5a, 0x33, + 0x40, 0x16, 0x2d, 0x66, 0x68, 0xdc, 0x62, 0xad, 0x49, 0x78, 0x4d, 0x47, + 0x50, 0x68, 0xf5, 0x05, 0x0a, 0x3b, 0x54, 0xc1, 0xeb, 0x42, 0x04, 0x72, + 0x3f, 0x89, 0xc5, 0x55, 0x96, 0x44, 0xfe, 0x1e, 0x69, 0xdc, 0x45, 0x39, + 0x32, 0x4d, 0x25, 0x4b, 0x2d, 0x10, 0x5d, 0x28, 0x92, 0x32, 0x0d, 0x54, + 0xd3, 0x66, 0x90, 0x48, 0x63, 0xcf, 0xc8, 0x3f, 0xc6, 0x94, 0xb6, 0x08, + 0xee, 0x68, 0x3e, 0x0d, 0x32, 0xe2, 0xde, 0x3b, 0xab, 0x46, 0x89, 0xc7, + 0x5e, 0x2b, 0x4a, 0x6e, 0xd2, 0x46, 0x75, 0x15, 0xd1, 0xc2, 0x4d, 0x1f, + 0x95, 0x33, 0x27, 0xbf, 0xf5, 0xa6, 0xf4, 0xab, 0xab, 0xf1, 0x1a, 0x41, + 0xe8, 0x6c, 0xe8, 0x9a, 0x83, 0x47, 0xbd, 0x59, 0x8e, 0x31, 0xfd, 0x69, + 0x75, 0x6b, 0xa6, 0x97, 0x1b, 0x5b, 0xe4, 0x15, 0x95, 0x05, 0x6b, 0x97, + 0x3d, 0x4a, 0xf6, 0xfc, 0xbc, 0x31, 0xe3, 0xef, 0x39, 0xfe, 0x55, 0x73, + 0x52, 0x18, 0xb6, 0x80, 0x0f, 0xf3, 0xf2, 0xd6, 0xf4, 0x7e, 0x23, 0x29, + 0xad, 0x8d, 0x6d, 0x3f, 0x10, 0xc2, 0x16, 0xaf, 0x75, 0xae, 0x4e, 0xa6, + 0xac, 0x75, 0x2d, 0x32, 0x47, 0x0a, 0x5a, 0xa0, 0x0a, 0x59, 0x06, 0x63, + 0x34, 0xd0, 0x98, 0x42, 0x71, 0x1d, 0x47, 0x1b, 0x62, 0x71, 0x48, 0x7d, + 0x4d, 0x20, 0x16, 0x44, 0xed, 0x8a, 0xc7, 0xd5, 0xb4, 0xb4, 0x9d, 0x48, + 0xc5, 0x69, 0x46, 0x66, 0x35, 0x22, 0x71, 0x17, 0xba, 0x7c, 0xd6, 0x32, + 0x9d, 0xc3, 0xe5, 0xcf, 0x06, 0xac, 0x5a, 0xb9, 0xe0, 0x0e, 0xb4, 0x57, + 0x86, 0xb7, 0x46, 0xd4, 0x65, 0x74, 0x6f, 0x58, 0xb9, 0x23, 0x91, 0xcd, + 0x68, 0xa0, 0x27, 0xb5, 0x64, 0x8a, 0x90, 0x92, 0x26, 0x3a, 0xd5, 0x59, + 0x2b, 0x56, 0x71, 0xdb, 0x52, 0xdd, 0x94, 0x51, 0xec, 0xc9, 0x1c, 0xd4, + 0xf9, 0x02, 0xb2, 0x4c, 0xea, 0x2f, 0x69, 0xd7, 0x3b, 0x24, 0x15, 0xb6, + 0x2e, 0x57, 0x6e, 0x69, 0xc7, 0x70, 0x91, 0x4a, 0xee, 0xf3, 0x8e, 0x2b, + 0x0a, 0xf2, 0x46, 0x6e, 0xb5, 0x4c, 0x84, 0x53, 0x62, 0xa3, 0x92, 0x2b, + 0x3a, 0xeb, 0x55, 0xda, 0xbb, 0x51, 0x7a, 0xd6, 0x5a, 0x96, 0x66, 0xdc, + 0xdc, 0x3b, 0x2f, 0x27, 0xad, 0x53, 0x4e, 0xb4, 0x3d, 0x80, 0xd5, 0xb1, + 0x93, 0x1c, 0x54, 0x17, 0x89, 0x89, 0xcd, 0x3a, 0x7d, 0x86, 0xc7, 0x5a, + 0x21, 0x7e, 0x05, 0x17, 0x3b, 0xa3, 0x3b, 0x58, 0x73, 0x47, 0x28, 0x9b, + 0xd4, 0xce, 0x9f, 0x27, 0x35, 0x5d, 0x0e, 0x1a, 0x97, 0x42, 0xe2, 0x8b, + 0x1c, 0x1a, 0x8f, 0xbd, 0x49, 0xa5, 0x87, 0x37, 0x02, 0xa2, 0x35, 0xa1, + 0x83, 0x23, 0xa4, 0xa6, 0x03, 0x59, 0x73, 0x4e, 0x8e, 0x02, 0xd4, 0x9b, + 0xb0, 0xd2, 0x27, 0x5b, 0x4a, 0x90, 0x5a, 0x8f, 0x4a, 0xcf, 0x98, 0xd9, + 0x53, 0x24, 0x10, 0x01, 0x53, 0x44, 0x80, 0x1a, 0xca, 0x4c, 0xd1, 0x46, + 0xc5, 0x92, 0x46, 0x06, 0xda, 0x6e, 0xea, 0x10, 0x0b, 0x9a, 0x63, 0x0a, + 0x2e, 0x04, 0x74, 0x94, 0xc4, 0x34, 0xb5, 0x37, 0x24, 0xd5, 0x58, 0x86, + 0xc3, 0xca, 0x95, 0xba, 0x0a, 0x4f, 0xb0, 0x4c, 0xdd, 0x6b, 0x64, 0xac, + 0x60, 0xe6, 0x3c, 0x69, 0x3f, 0xde, 0x6a, 0x91, 0x74, 0xb8, 0xc7, 0xff, + 0x00, 0xaa, 0x9f, 0x31, 0x06, 0x76, 0xa7, 0x6e, 0x90, 0xb0, 0xd9, 0xfe, + 0x78, 0xaa, 0x20, 0x55, 0x30, 0x42, 0xed, 0xa5, 0xc5, 0x48, 0xc5, 0xc5, + 0x14, 0x00, 0x52, 0x8f, 0x9a, 0x80, 0x1d, 0xe4, 0x16, 0xa8, 0xa4, 0x5f, + 0x2f, 0x83, 0x45, 0xc0, 0x8a, 0x96, 0x82, 0x85, 0xa2, 0xa4, 0x05, 0xa5, + 0xa0, 0x62, 0xd3, 0xfb, 0x50, 0x22, 0xb1, 0xeb, 0x45, 0x50, 0x05, 0x14, + 0x00, 0xb4, 0x50, 0x04, 0xa9, 0x52, 0x54, 0x81, 0xea, 0xbb, 0x98, 0xd2, + 0x3b, 0x32, 0x2e, 0x4b, 0x56, 0xe9, 0x19, 0x36, 0x73, 0x97, 0x17, 0x57, + 0x37, 0x52, 0xb2, 0xa4, 0x8d, 0x81, 0x56, 0xf4, 0xab, 0x82, 0xc4, 0xc6, + 0x6b, 0x2a, 0xbe, 0x46, 0xb1, 0x7a, 0x1a, 0x4c, 0xb5, 0x0b, 0x53, 0x24, + 0x82, 0x5e, 0x54, 0xd5, 0x0b, 0x47, 0xf2, 0xee, 0x19, 0x5f, 0xa9, 0xa4, + 0xfe, 0x11, 0xad, 0xcd, 0x38, 0xc6, 0xee, 0x0d, 0x53, 0xd4, 0x2f, 0x06, + 0x9e, 0x57, 0x3f, 0x36, 0x7d, 0x2a, 0xa9, 0xea, 0x44, 0x8e, 0x71, 0x22, + 0x17, 0xd7, 0x2e, 0xc7, 0xb7, 0xf8, 0xd5, 0x4b, 0xbb, 0x57, 0xb7, 0x71, + 0xbf, 0xa7, 0x6a, 0xab, 0xf3, 0x19, 0x46, 0x7c, 0xb2, 0xe5, 0x35, 0xbc, + 0x31, 0x62, 0x97, 0x53, 0x91, 0x2f, 0xdd, 0xe3, 0x3f, 0x9d, 0x4d, 0xe2, + 0x3b, 0x14, 0xb4, 0xb8, 0x55, 0x87, 0xee, 0x37, 0x1f, 0xf8, 0xed, 0x3c, + 0x33, 0xbf, 0x32, 0x37, 0xa8, 0xf9, 0x64, 0x8a, 0xf6, 0x69, 0x9b, 0xa4, + 0x20, 0x7d, 0xcc, 0x35, 0x6a, 0xc9, 0x0a, 0xca, 0x10, 0x32, 0xe7, 0x15, + 0x2b, 0x70, 0x6c, 0x97, 0xee, 0xd4, 0xd1, 0xcb, 0x59, 0x34, 0x59, 0x65, + 0x5f, 0x34, 0xfe, 0xb4, 0x08, 0x76, 0x30, 0x29, 0x54, 0x8c, 0x53, 0x01, + 0x9e, 0x60, 0x53, 0xcd, 0x47, 0x25, 0xe2, 0xe3, 0x02, 0x98, 0x98, 0xd4, + 0x97, 0x34, 0x15, 0x24, 0xd2, 0x63, 0x45, 0xcb, 0x36, 0x21, 0xf1, 0x53, + 0xdc, 0x76, 0xa5, 0x00, 0x91, 0x42, 0xea, 0xc1, 0x2e, 0xd0, 0xab, 0x2e, + 0x73, 0x54, 0x63, 0xf0, 0xfd, 0xba, 0x3f, 0xdd, 0xad, 0xbd, 0xa3, 0xb1, + 0x0a, 0x36, 0x66, 0xd5, 0xa6, 0x9d, 0x04, 0x71, 0x70, 0x29, 0xbb, 0xe2, + 0x53, 0x8e, 0x95, 0x9f, 0x4b, 0x95, 0xd4, 0x8e, 0x50, 0x25, 0xaa, 0xb2, + 0x44, 0x2a, 0x65, 0x23, 0x68, 0x53, 0x08, 0x38, 0x24, 0x54, 0xad, 0x4a, + 0x24, 0x48, 0x96, 0xd1, 0x87, 0x99, 0x5a, 0xe9, 0x32, 0xf9, 0x75, 0x44, + 0xbd, 0x8c, 0xfb, 0xb3, 0xcf, 0x06, 0xab, 0xdd, 0x0f, 0xdd, 0x55, 0xb3, + 0x38, 0xa2, 0x84, 0xa3, 0x28, 0x71, 0x58, 0x12, 0xdb, 0xc8, 0xb2, 0x12, + 0xeb, 0x8e, 0x6a, 0x6d, 0x72, 0x9e, 0xe5, 0x49, 0x79, 0x35, 0x25, 0xb5, + 0xa4, 0x92, 0xfc, 0xca, 0x38, 0xa6, 0x97, 0x42, 0x8b, 0x50, 0xc4, 0xca, + 0xe2, 0xac, 0x98, 0xd5, 0x99, 0x77, 0x52, 0x94, 0x79, 0x47, 0xb8, 0xd9, + 0x8c, 0x56, 0xec, 0x3c, 0xa3, 0x96, 0xaa, 0x93, 0xb9, 0x91, 0xf2, 0xdc, + 0x9a, 0x96, 0x38, 0xab, 0x95, 0x24, 0x4a, 0xa6, 0xfc, 0x1a, 0x46, 0x82, + 0x83, 0x4e, 0x5e, 0xb4, 0x8a, 0x62, 0xc9, 0x51, 0x35, 0x68, 0x8e, 0x71, + 0x94, 0x50, 0x00, 0x2b, 0x46, 0x10, 0x0a, 0x66, 0xb1, 0xa8, 0x6f, 0x48, + 0x97, 0x6d, 0x18, 0xac, 0xae, 0x6c, 0x2e, 0x28, 0xc5, 0x50, 0x0e, 0xa3, + 0xa5, 0x48, 0x09, 0xbe, 0xa3, 0x69, 0xb1, 0x4d, 0x44, 0x86, 0xc8, 0x8c, + 0xd4, 0x0d, 0xcd, 0x5b, 0xa8, 0x98, 0xca, 0x64, 0xc9, 0x6e, 0x4f, 0xde, + 0xab, 0x09, 0x14, 0x6b, 0x4f, 0x63, 0x2b, 0x92, 0x79, 0xa8, 0xbd, 0xe9, + 0xad, 0x77, 0x12, 0xf7, 0xa9, 0x11, 0x09, 0xd4, 0xa2, 0xa8, 0x1f, 0x54, + 0xfe, 0xe8, 0xa7, 0xca, 0x33, 0x3e, 0xe6, 0x73, 0x70, 0x7e, 0x61, 0x50, + 0x62, 0xac, 0x81, 0x69, 0xb9, 0x14, 0x0c, 0x42, 0xf4, 0xdc, 0xd0, 0x51, + 0x22, 0xad, 0x49, 0x18, 0xa4, 0x4b, 0x2c, 0xc6, 0x2a, 0xa5, 0xe7, 0xfa, + 0xca, 0x71, 0x02, 0xad, 0x2d, 0x05, 0x85, 0x2d, 0x00, 0x14, 0xea, 0x00, + 0x5a, 0x7f, 0x6a, 0x40, 0x57, 0x6e, 0xb4, 0xda, 0x60, 0x2d, 0x14, 0x00, + 0x52, 0xd0, 0x03, 0xd0, 0xd4, 0xb5, 0x36, 0x03, 0xd6, 0x96, 0x33, 0x4d, + 0xba, 0x83, 0x30, 0xb7, 0x35, 0xd5, 0x0d, 0xcc, 0x26, 0x61, 0x5b, 0xd9, + 0xdc, 0x43, 0x23, 0xe1, 0x33, 0x93, 0xfd, 0x6a, 0xc5, 0x9d, 0xab, 0xc0, + 0xe5, 0xde, 0xa2, 0x71, 0xde, 0xc6, 0x8a, 0xc6, 0x87, 0x55, 0xaa, 0xcc, + 0x39, 0xa8, 0xe8, 0x04, 0x4f, 0xd2, 0xb3, 0xee, 0xad, 0xb7, 0x1d, 0xca, + 0x76, 0xb5, 0x24, 0x36, 0x11, 0xcf, 0x73, 0x0a, 0xe3, 0xad, 0x52, 0x9a, + 0xc2, 0x7b, 0xf9, 0xf7, 0xcc, 0xdf, 0x81, 0xe6, 0x9c, 0x6d, 0x11, 0x3d, + 0x5d, 0xcb, 0x49, 0x65, 0xe5, 0x11, 0x84, 0xa9, 0xee, 0x6c, 0xa3, 0xbb, + 0xb5, 0x68, 0xf6, 0xf3, 0x8e, 0x31, 0x45, 0xac, 0xee, 0x71, 0x56, 0xde, + 0xe6, 0x7d, 0x82, 0xcb, 0xa6, 0xb3, 0x20, 0x49, 0x39, 0xe0, 0x1c, 0x7b, + 0xd5, 0xe7, 0xb0, 0x9e, 0xfe, 0x3c, 0xb2, 0x73, 0x9e, 0x0d, 0x6d, 0x4e, + 0x3c, 0x8e, 0xe7, 0x4c, 0xa5, 0xce, 0xae, 0x5c, 0xb0, 0xd0, 0xcc, 0x2a, + 0x77, 0x1a, 0x9d, 0xe0, 0x58, 0x97, 0x00, 0x54, 0xb4, 0x51, 0x51, 0xa3, + 0xe6, 0x8c, 0x01, 0x58, 0xb3, 0x51, 0x7c, 0xc5, 0x5e, 0xf4, 0xf1, 0x78, + 0xa3, 0xbd, 0x40, 0xc8, 0xe4, 0xd4, 0x07, 0x6a, 0x87, 0xed, 0xaf, 0xda, + 0x82, 0xd4, 0x48, 0xcb, 0xb3, 0x77, 0xa4, 0x5e, 0x0d, 0x30, 0x91, 0x6a, + 0xdd, 0xbe, 0x71, 0x57, 0x29, 0x32, 0x47, 0x23, 0xec, 0x39, 0xa9, 0x65, + 0x9d, 0x5d, 0x28, 0x8e, 0xe2, 0x63, 0xb4, 0xd6, 0xf3, 0x24, 0xc5, 0x68, + 0xc9, 0x69, 0xbf, 0xee, 0xd5, 0xd3, 0x7a, 0x93, 0x3d, 0x08, 0xc5, 0xb4, + 0xe8, 0x31, 0x54, 0xe4, 0xd3, 0xdf, 0x3b, 0x98, 0xd6, 0x96, 0x26, 0xe4, + 0x43, 0x03, 0x8a, 0x8a, 0x5a, 0xe6, 0x96, 0xe7, 0x74, 0x36, 0x22, 0x8f, + 0xef, 0xd4, 0x93, 0x0c, 0x2d, 0x38, 0x1c, 0xf3, 0x24, 0xd3, 0xff, 0x00, + 0xd6, 0x8a, 0xd4, 0x92, 0x2f, 0x97, 0x81, 0x5a, 0x47, 0x73, 0x2a, 0x9b, + 0x15, 0x4a, 0xb1, 0x93, 0xa5, 0x3e, 0xe6, 0x3d, 0xd1, 0x62, 0xaa, 0x7a, + 0x31, 0x47, 0x54, 0x51, 0xf2, 0x29, 0x24, 0xb6, 0x57, 0x4c, 0x62, 0xb3, + 0xbd, 0x99, 0x6d, 0x68, 0x73, 0x3a, 0xbd, 0x83, 0x5b, 0x49, 0x95, 0xfb, + 0xb4, 0xb6, 0x17, 0x2f, 0x6f, 0x0f, 0x09, 0xf9, 0x8a, 0xd5, 0xae, 0xa4, + 0xa7, 0x74, 0x34, 0x5c, 0x3b, 0x31, 0xc2, 0xf5, 0xa1, 0xc4, 0x95, 0x33, + 0x91, 0x51, 0x56, 0x21, 0xf2, 0xf9, 0xcd, 0x48, 0x23, 0xae, 0x76, 0xcd, + 0xa2, 0x41, 0x72, 0x06, 0xde, 0x2a, 0x89, 0x43, 0x4d, 0x31, 0x8c, 0xc6, + 0x29, 0xea, 0x2a, 0x81, 0xec, 0x12, 0x54, 0x4d, 0x5a, 0x18, 0x0d, 0xa2, + 0x80, 0x0a, 0xb7, 0x64, 0xdc, 0xed, 0xac, 0xe6, 0x8d, 0x69, 0x6e, 0x5d, + 0xa5, 0xc5, 0x60, 0x74, 0x87, 0x14, 0xd2, 0xc2, 0x98, 0x88, 0x5e, 0x75, + 0x5a, 0xad, 0x25, 0xf2, 0x76, 0xaa, 0x50, 0x6c, 0xce, 0x53, 0x48, 0x83, + 0xed, 0x8c, 0xc6, 0x83, 0x2d, 0x6c, 0x95, 0x8e, 0x77, 0x2b, 0x8a, 0x26, + 0xa9, 0xd6, 0xf7, 0x6f, 0x6a, 0x76, 0x24, 0x1b, 0x50, 0x7e, 0xd5, 0x11, + 0xb9, 0x91, 0xbf, 0x8a, 0x8b, 0x12, 0x33, 0xcc, 0x6f, 0x5a, 0x43, 0xcd, + 0x16, 0xd4, 0x57, 0x12, 0x8a, 0x62, 0x1a, 0x6a, 0x32, 0xe0, 0x50, 0x55, + 0x88, 0xcb, 0xd2, 0x50, 0x50, 0xa0, 0x54, 0xa1, 0x28, 0x19, 0x2e, 0x38, + 0xa7, 0x45, 0xd2, 0x91, 0x04, 0xcb, 0xc5, 0x51, 0x9c, 0xfe, 0xf2, 0x92, + 0x19, 0x1e, 0x05, 0x36, 0xa8, 0xa0, 0xa2, 0x80, 0x1d, 0x45, 0x20, 0x1d, + 0x4e, 0x1d, 0x28, 0x02, 0x06, 0xeb, 0x49, 0x4c, 0x04, 0xa5, 0xa0, 0x02, + 0x8a, 0x00, 0x70, 0xa9, 0xc5, 0x20, 0x3d, 0x79, 0xa6, 0x1d, 0x8d, 0x47, + 0xf6, 0x94, 0x6e, 0xa6, 0xb5, 0xb9, 0x9d, 0x89, 0x92, 0x68, 0x94, 0x67, + 0x22, 0xa1, 0x94, 0x7d, 0xa0, 0xfc, 0xa6, 0xaa, 0xe4, 0x58, 0x0c, 0x5b, + 0x56, 0xa9, 0x4c, 0x30, 0x69, 0x74, 0x1a, 0xdc, 0x80, 0xf3, 0x51, 0xb5, + 0x64, 0x6a, 0x45, 0x27, 0x4a, 0x6d, 0xb9, 0xf9, 0xa8, 0x03, 0x77, 0x4e, + 0xb7, 0x8e, 0x53, 0xf3, 0x01, 0x5a, 0x8b, 0xa5, 0xc1, 0xfd, 0xda, 0xda, + 0x9c, 0x8e, 0x7a, 0x91, 0x25, 0x1a, 0x74, 0x03, 0xf8, 0x45, 0x29, 0x86, + 0x34, 0xe8, 0xb5, 0xb1, 0x05, 0x59, 0xeb, 0x1e, 0xfb, 0xe4, 0x42, 0x69, + 0x33, 0x44, 0x54, 0xb7, 0x46, 0xb9, 0xce, 0xd1, 0xd2, 0xaa, 0x5e, 0x41, + 0x73, 0x1f, 0xdd, 0xce, 0x2b, 0x9d, 0x2e, 0x63, 0x7b, 0xd9, 0x94, 0x32, + 0xe7, 0xad, 0x39, 0x54, 0x9a, 0xca, 0xc6, 0xd7, 0x25, 0x11, 0xd4, 0xd1, + 0xc0, 0x7f, 0xbb, 0xfa, 0x55, 0x72, 0xdc, 0xcf, 0x98, 0x90, 0x43, 0xed, + 0x47, 0xd9, 0xfd, 0x69, 0xda, 0xc2, 0xb8, 0xd1, 0xfb, 0xa9, 0x05, 0x5e, + 0x53, 0x95, 0x15, 0x12, 0x29, 0x6c, 0x0d, 0xd2, 0xb3, 0xa5, 0xb9, 0x64, + 0x3d, 0x69, 0xa4, 0x06, 0x8e, 0x81, 0x3f, 0x99, 0x38, 0xfa, 0xd7, 0x5b, + 0x00, 0xe9, 0x51, 0x0d, 0xc2, 0xa2, 0x26, 0x93, 0xee, 0x1a, 0xcb, 0xbd, + 0x6f, 0x90, 0xd7, 0x52, 0x39, 0xce, 0x65, 0x66, 0xfd, 0xe3, 0x66, 0xa4, + 0x33, 0xe4, 0x57, 0x3c, 0xd7, 0xbc, 0x76, 0x46, 0x76, 0x44, 0x31, 0xc9, + 0xfb, 0xce, 0xb5, 0x35, 0xc5, 0xc2, 0x08, 0xba, 0xd2, 0x5b, 0x91, 0x2d, + 0x48, 0x2c, 0xef, 0x57, 0xcf, 0x00, 0x57, 0x5d, 0x01, 0xcc, 0x40, 0xd1, + 0x1f, 0x88, 0x89, 0xad, 0x08, 0x65, 0x7e, 0x6a, 0xbb, 0xf3, 0x57, 0x21, + 0x45, 0x0c, 0xd9, 0x49, 0xb2, 0xb3, 0x19, 0x97, 0x75, 0xb0, 0xc8, 0x55, + 0xb1, 0xd2, 0xa9, 0xbf, 0x94, 0xa9, 0xb4, 0x0a, 0x2f, 0xa8, 0xed, 0xa1, + 0x93, 0x0c, 0x91, 0xac, 0xc7, 0x91, 0xd6, 0xa7, 0x69, 0xa2, 0x3d, 0xea, + 0x5e, 0xe6, 0xaa, 0x24, 0x6d, 0x71, 0x1f, 0xad, 0x40, 0xf7, 0x04, 0xfd, + 0xda, 0x8f, 0x53, 0x44, 0x88, 0xc2, 0x16, 0xeb, 0x4b, 0xe5, 0x52, 0xb9, + 0xa5, 0x83, 0xc8, 0x14, 0x92, 0x44, 0x02, 0xf4, 0xaa, 0xbe, 0xa4, 0x49, + 0x68, 0x51, 0x93, 0xad, 0x42, 0xd5, 0xd0, 0x72, 0x0c, 0xa2, 0x80, 0x12, + 0xa6, 0xb7, 0x7d, 0x8d, 0x9a, 0x52, 0xd8, 0xa8, 0xee, 0x69, 0xf9, 0xa9, + 0x8e, 0xa2, 0xa2, 0x92, 0xed, 0x57, 0xb8, 0xae, 0x54, 0x8e, 0xa7, 0x2b, + 0x14, 0xe4, 0xd4, 0x7d, 0x2a, 0xac, 0x97, 0x6e, 0xdf, 0xfe, 0xba, 0xe8, + 0x8c, 0x4c, 0x1d, 0x42, 0x22, 0xcc, 0xdd, 0x4d, 0x1b, 0x6a, 0xcc, 0x5b, + 0x1c, 0x05, 0x2d, 0x04, 0x0b, 0x4e, 0xa0, 0x05, 0xa2, 0x81, 0x0b, 0x49, + 0x40, 0x08, 0x5c, 0x0a, 0x88, 0xcd, 0xe9, 0x41, 0x64, 0x65, 0xc9, 0xa6, + 0xd3, 0x28, 0x29, 0xc2, 0x80, 0x24, 0x15, 0x2a, 0x54, 0x88, 0x7b, 0x74, + 0xa5, 0x8b, 0xa5, 0x04, 0x93, 0x76, 0xaa, 0x13, 0x7d, 0xfa, 0x60, 0xb7, + 0x19, 0xda, 0x9b, 0x41, 0x61, 0x4b, 0x40, 0x0b, 0x45, 0x20, 0x14, 0x53, + 0xc7, 0x4a, 0x40, 0x42, 0xdd, 0x69, 0xb5, 0x42, 0x0a, 0x28, 0x18, 0x51, + 0x40, 0x0e, 0x4e, 0xb5, 0x3d, 0x26, 0x07, 0x71, 0x2e, 0xa0, 0x55, 0x38, + 0xeb, 0x4b, 0xa6, 0xdc, 0xb4, 0xb3, 0xfc, 0xc7, 0xa9, 0xad, 0x27, 0x1b, + 0x22, 0xd4, 0x74, 0xb9, 0xa3, 0x77, 0xfe, 0xa4, 0x7e, 0x35, 0xa5, 0xa6, + 0x27, 0xfa, 0x20, 0xfa, 0x9a, 0x97, 0xd0, 0xe7, 0xee, 0x4d, 0x22, 0xd6, + 0x6d, 0xd0, 0xc5, 0x6e, 0xc9, 0x45, 0x16, 0x6c, 0x53, 0x37, 0x57, 0x33, + 0x36, 0x18, 0xc6, 0xa0, 0x47, 0xc4, 0x94, 0x08, 0xd8, 0xd3, 0x2e, 0xb1, + 0x28, 0xe6, 0xba, 0x78, 0x5b, 0x2a, 0x29, 0xd3, 0x7e, 0xf0, 0xa6, 0x58, + 0xa8, 0xe4, 0x5a, 0xee, 0x47, 0x39, 0x4a, 0x65, 0xac, 0x7d, 0x46, 0x3d, + 0xd1, 0x30, 0xa9, 0x6c, 0xa4, 0x59, 0xf0, 0xfd, 0xb0, 0x8c, 0x90, 0xd5, + 0xa3, 0x7b, 0xa6, 0xa4, 0xc3, 0x28, 0x30, 0x6b, 0x9a, 0x8c, 0xb5, 0x66, + 0x95, 0xba, 0x18, 0xf7, 0x9a, 0x01, 0x65, 0xca, 0x28, 0xcd, 0x54, 0x8f, + 0x44, 0x3d, 0x1c, 0x73, 0x5a, 0x4b, 0xb8, 0xa3, 0x2e, 0x86, 0x8d, 0x97, + 0x86, 0xd3, 0xef, 0x4d, 0xfc, 0xab, 0x62, 0x2d, 0x3a, 0xda, 0x25, 0xc0, + 0x88, 0x56, 0x7c, 0xc3, 0x63, 0x7f, 0xb3, 0x6d, 0xf7, 0x67, 0x60, 0xae, + 0x5f, 0x56, 0x0d, 0x1c, 0x99, 0x5a, 0xdf, 0xe2, 0x46, 0x71, 0xdc, 0xcb, + 0x67, 0x2d, 0x57, 0x2d, 0x9f, 0xe4, 0xae, 0x29, 0x9d, 0xab, 0x62, 0x7a, + 0xc9, 0xba, 0x8c, 0x99, 0x78, 0xa6, 0xb6, 0x27, 0xa9, 0x67, 0x4a, 0xcd, + 0xbc, 0xc1, 0xab, 0xb5, 0xb0, 0xb8, 0x59, 0x50, 0x73, 0xcd, 0x60, 0xb4, + 0x66, 0xb3, 0x57, 0x45, 0x99, 0xa4, 0x54, 0x43, 0x9a, 0xc8, 0xba, 0x6d, + 0xd1, 0xb6, 0x2b, 0xb5, 0x6c, 0x71, 0x9c, 0xb3, 0xfc, 0xb2, 0x1a, 0x53, + 0x90, 0xb5, 0x9c, 0xb7, 0x3a, 0xa3, 0x0d, 0x08, 0xb0, 0xc7, 0xa5, 0x4d, + 0xfd, 0x98, 0xd3, 0x2f, 0xce, 0x69, 0x0a, 0x5a, 0x0f, 0x83, 0x4c, 0x30, + 0xb8, 0xc5, 0x74, 0x56, 0xd7, 0x0c, 0xb1, 0x05, 0x22, 0x8e, 0xb7, 0x25, + 0xbb, 0xa1, 0x7a, 0xd1, 0xb6, 0x94, 0x99, 0x21, 0x8a, 0x31, 0x52, 0x07, + 0x3f, 0xa8, 0x2e, 0x2f, 0x3f, 0x2a, 0xcd, 0x92, 0xe0, 0xac, 0xbb, 0x68, + 0x9e, 0xe5, 0xc3, 0x53, 0x24, 0xdb, 0xb3, 0x48, 0x48, 0xcd, 0x3c, 0x5b, + 0x9f, 0x7a, 0x87, 0x23, 0x65, 0x01, 0xeb, 0x6b, 0x52, 0xac, 0x20, 0x54, + 0x36, 0x6a, 0x87, 0xed, 0x02, 0x93, 0x15, 0x23, 0x12, 0x98, 0xfd, 0x28, + 0x44, 0xb3, 0x32, 0x51, 0xcd, 0x40, 0x6b, 0xb0, 0xe2, 0x19, 0x49, 0x40, + 0x05, 0x19, 0xc5, 0x00, 0x36, 0x49, 0x9f, 0xd6, 0xab, 0x92, 0x49, 0xa1, + 0x21, 0xdc, 0x4a, 0x5a, 0x04, 0x2e, 0x69, 0xea, 0x68, 0x11, 0x28, 0x02, + 0x97, 0x6d, 0x06, 0x62, 0xe2, 0x8c, 0x50, 0x20, 0xa4, 0x2c, 0x05, 0x03, + 0x22, 0x69, 0x7d, 0x2a, 0x32, 0xc6, 0x8b, 0x1a, 0x58, 0x4a, 0x6d, 0x03, + 0x0a, 0x28, 0x00, 0xa5, 0xa0, 0x42, 0xe6, 0xa7, 0x8e, 0x89, 0x20, 0x24, + 0x6e, 0x94, 0xf8, 0xba, 0x52, 0x44, 0x92, 0xb7, 0x4a, 0xce, 0x7e, 0xb4, + 0xd0, 0x96, 0xe3, 0x7b, 0x51, 0x41, 0xa0, 0x51, 0x48, 0x05, 0xa2, 0x90, + 0x0b, 0x4f, 0x14, 0x01, 0x13, 0x53, 0x6a, 0x84, 0x18, 0xa4, 0xa0, 0x62, + 0x52, 0xd0, 0x03, 0xd3, 0xad, 0x4d, 0x4a, 0xc0, 0x75, 0xdf, 0xd9, 0xf3, + 0x34, 0x98, 0xda, 0x7e, 0xb5, 0x72, 0xce, 0xc5, 0xed, 0xc8, 0x2d, 0x5d, + 0x75, 0xec, 0xcb, 0x53, 0xf7, 0x4b, 0x77, 0x2f, 0xfb, 0xb1, 0x5b, 0x9a, + 0x68, 0xff, 0x00, 0x45, 0x1f, 0x53, 0x5c, 0xd6, 0x7a, 0x1c, 0xfd, 0x19, + 0x3b, 0xad, 0x66, 0xde, 0x27, 0x15, 0xd0, 0x66, 0x8c, 0x59, 0xdb, 0x63, + 0x73, 0x55, 0x9a, 0xe9, 0x47, 0xad, 0x73, 0x4c, 0xe9, 0x89, 0x03, 0xde, + 0x31, 0xe9, 0x50, 0x79, 0x8e, 0x4d, 0x67, 0x72, 0xf9, 0x4b, 0x76, 0x72, + 0x95, 0x95, 0x73, 0x5d, 0xce, 0x97, 0x37, 0x99, 0x00, 0xa2, 0x2f, 0xdf, + 0x26, 0xa2, 0xf7, 0x4d, 0x41, 0xd2, 0x9a, 0xfd, 0x2b, 0xd1, 0x47, 0x13, + 0x29, 0xcc, 0x2b, 0x1f, 0x50, 0x6d, 0xbd, 0x2a, 0x64, 0x5c, 0x4b, 0x5a, + 0x73, 0x10, 0x77, 0x81, 0x5a, 0xf1, 0x4a, 0x64, 0xea, 0x2b, 0x92, 0x2a, + 0xda, 0x9b, 0x4c, 0x96, 0xa0, 0x6e, 0x26, 0x15, 0xb6, 0xe8, 0xc9, 0x5a, + 0xe3, 0xa3, 0xb8, 0x8e, 0x53, 0x85, 0x6a, 0x96, 0xb2, 0x34, 0x10, 0xb0, + 0x02, 0xb9, 0x5b, 0xd2, 0x24, 0x95, 0xab, 0x68, 0xe9, 0x13, 0x3f, 0xb4, + 0x56, 0x8f, 0x4a, 0xf3, 0x89, 0x38, 0x34, 0x87, 0x4d, 0x9a, 0x16, 0xe3, + 0x9a, 0x8d, 0x1a, 0x36, 0x52, 0xb0, 0xbf, 0x65, 0xb8, 0x23, 0x85, 0xfd, + 0x6a, 0xbc, 0x96, 0x72, 0xa3, 0x72, 0xb5, 0x1c, 0xa6, 0x8a, 0x48, 0x8f, + 0x69, 0x5f, 0x6a, 0xbf, 0x69, 0x7a, 0x61, 0x20, 0xe6, 0xb9, 0xe4, 0x8d, + 0xfa, 0x13, 0x49, 0xac, 0xee, 0x97, 0x61, 0xe7, 0x35, 0x15, 0xc5, 0xe9, + 0x09, 0xc7, 0x7a, 0xd9, 0x76, 0x39, 0xec, 0x65, 0xce, 0xdb, 0x9c, 0x10, + 0x28, 0x67, 0xf9, 0x31, 0x8a, 0x3a, 0x9d, 0x9a, 0x24, 0x3a, 0xdf, 0x99, + 0x16, 0xb6, 0x55, 0xc6, 0x05, 0x2e, 0xa7, 0x3d, 0x46, 0x48, 0xbb, 0x69, + 0xfc, 0x0a, 0x66, 0x43, 0x8c, 0x98, 0x15, 0x4c, 0xea, 0x6a, 0x1b, 0x15, + 0x0d, 0x14, 0x84, 0xfe, 0xd3, 0x5a, 0x3f, 0xb4, 0xd6, 0xb3, 0x2b, 0x94, + 0xcd, 0xbd, 0xb8, 0x12, 0xb6, 0x45, 0x67, 0x34, 0x79, 0x6c, 0xd3, 0x9c, + 0x8b, 0xa7, 0x1b, 0x07, 0x96, 0x3d, 0x29, 0xe1, 0x31, 0x59, 0x23, 0x5b, + 0x8c, 0x6c, 0x0a, 0x8c, 0xb5, 0x50, 0x26, 0x44, 0x65, 0xa6, 0x79, 0x82, + 0xa5, 0x22, 0x80, 0x4a, 0xb4, 0x17, 0x14, 0x09, 0x94, 0x27, 0xfb, 0xd5, + 0x58, 0xd7, 0x59, 0xc4, 0xc6, 0x1a, 0x6d, 0x30, 0x12, 0x8a, 0x00, 0x6b, + 0x0c, 0xd4, 0x24, 0x73, 0x4c, 0x42, 0x51, 0x48, 0x61, 0x4b, 0x40, 0x0b, + 0x9a, 0x91, 0x25, 0xf5, 0xa0, 0x56, 0x25, 0x0e, 0x0d, 0x35, 0xa5, 0x02, + 0x91, 0x3c, 0xa4, 0x2d, 0x36, 0x6a, 0x3c, 0x93, 0x4c, 0xa1, 0x69, 0xd8, + 0xa0, 0x62, 0x53, 0x28, 0x00, 0xa2, 0x80, 0x16, 0x96, 0x80, 0x0a, 0x9e, + 0x3a, 0x1b, 0x11, 0x23, 0x0e, 0x2a, 0x58, 0xbe, 0xed, 0x22, 0x47, 0xc9, + 0xc2, 0x56, 0x6b, 0xd3, 0x04, 0x03, 0xa5, 0x25, 0x05, 0x8b, 0x45, 0x20, + 0x0a, 0x29, 0x80, 0xb4, 0xe1, 0xd2, 0x90, 0x11, 0x37, 0x5a, 0x41, 0x4c, + 0x05, 0x34, 0xda, 0x00, 0x28, 0xa0, 0x07, 0xa7, 0x5a, 0x9a, 0xa4, 0x0f, + 0x56, 0x86, 0x1e, 0x7a, 0x52, 0xcb, 0x6f, 0x9e, 0xd5, 0xd6, 0xb5, 0x24, + 0xc8, 0xd4, 0xa2, 0x6d, 0xbc, 0x56, 0xd6, 0x93, 0x36, 0x62, 0x0b, 0x58, + 0xd5, 0xbd, 0xd0, 0x2d, 0x8d, 0x26, 0xe4, 0x55, 0x1b, 0xa5, 0xad, 0xd1, + 0xce, 0x73, 0x1a, 0xa2, 0xf2, 0x2b, 0x37, 0x15, 0xcb, 0x5b, 0x46, 0x75, + 0xd2, 0x7a, 0x06, 0xca, 0x5d, 0xb5, 0x8d, 0xcd, 0x19, 0x32, 0xa9, 0xae, + 0xa7, 0xc3, 0xf7, 0x1c, 0xed, 0x34, 0x9e, 0xe2, 0x7b, 0x1d, 0x32, 0x1e, + 0x29, 0x4f, 0x4a, 0xf4, 0xa2, 0xce, 0x09, 0x14, 0xe7, 0x35, 0x10, 0xb1, + 0x8d, 0xf9, 0x96, 0x94, 0x98, 0x22, 0xd2, 0xb4, 0x71, 0xae, 0x16, 0x84, + 0x90, 0x6e, 0xac, 0x8d, 0x11, 0x36, 0xe1, 0x50, 0x4d, 0xf3, 0x1a, 0xa8, + 0x10, 0xca, 0xd6, 0x3a, 0x7f, 0x93, 0x2c, 0x8e, 0xdc, 0x86, 0xe9, 0xf9, + 0xd5, 0x89, 0x54, 0xd5, 0x79, 0x95, 0xcc, 0x56, 0x2f, 0xf2, 0x90, 0x6a, + 0x8a, 0x5a, 0x82, 0xfc, 0x8e, 0xf5, 0x9d, 0xf4, 0x2b, 0xa9, 0xa4, 0x1a, + 0x38, 0x63, 0xe2, 0xb3, 0x7c, 0xed, 0xd3, 0x7a, 0x54, 0xfd, 0x92, 0x96, + 0xe5, 0x95, 0x95, 0x14, 0x7c, 0xcd, 0x54, 0x6f, 0x35, 0x28, 0x11, 0x4f, + 0xcd, 0x50, 0x8a, 0xb1, 0xcf, 0xdc, 0x6a, 0x42, 0x69, 0x38, 0x1c, 0x55, + 0x2b, 0x8d, 0x45, 0xa3, 0x3f, 0x2d, 0x43, 0x57, 0x67, 0x46, 0xc8, 0x8e, + 0x1b, 0xff, 0x00, 0x32, 0xee, 0x33, 0x20, 0xc7, 0x35, 0xaa, 0xf7, 0x31, + 0xca, 0x8a, 0x01, 0xa9, 0xbd, 0x98, 0xa2, 0x89, 0xe2, 0xb6, 0x59, 0x06, + 0x6a, 0x3b, 0xb8, 0x96, 0x15, 0xe3, 0xad, 0x74, 0x50, 0xf7, 0xcc, 0xaa, + 0xcf, 0x94, 0xa8, 0x27, 0x68, 0xfd, 0x69, 0x46, 0xaa, 0x54, 0xf3, 0x5d, + 0x72, 0xc3, 0xf5, 0x30, 0x55, 0xae, 0x5d, 0x8f, 0x53, 0x52, 0x82, 0x9d, + 0xfd, 0xa3, 0x9e, 0x95, 0xe7, 0x48, 0xec, 0xe4, 0x18, 0xd7, 0x6e, 0xd5, + 0x5c, 0xe4, 0x9a, 0x8b, 0x94, 0x90, 0x98, 0xa7, 0x8a, 0x96, 0x50, 0xc9, + 0x2a, 0x2c, 0xd0, 0x03, 0x09, 0xe6, 0x97, 0x76, 0x05, 0x20, 0x2b, 0x48, + 0xd5, 0x59, 0xa4, 0xa2, 0xc5, 0x22, 0x17, 0x9a, 0xab, 0xbc, 0xfe, 0xf5, + 0x51, 0x89, 0x2e, 0x44, 0x2d, 0x73, 0x8a, 0x8d, 0xaf, 0x49, 0xab, 0xf6, + 0x66, 0x5c, 0xe1, 0x14, 0x9b, 0xcd, 0x48, 0x6b, 0x43, 0x31, 0x86, 0x99, + 0x40, 0x09, 0x45, 0x00, 0x25, 0x42, 0xdd, 0x69, 0x88, 0x6d, 0x14, 0x0c, + 0x4a, 0x76, 0x29, 0x00, 0x52, 0x50, 0x02, 0x6e, 0x34, 0x94, 0xc4, 0x14, + 0xb4, 0x86, 0x3c, 0x51, 0x40, 0x05, 0x47, 0x40, 0x05, 0x2d, 0x36, 0x01, + 0x4e, 0xa4, 0x01, 0x53, 0xc5, 0xd2, 0x86, 0x22, 0x46, 0xe9, 0x53, 0x47, + 0xd2, 0x91, 0x01, 0x3f, 0xdc, 0xac, 0xc6, 0xaa, 0xe8, 0x08, 0x55, 0xa7, + 0x52, 0x34, 0x0c, 0x51, 0x8a, 0x00, 0x28, 0xa4, 0x01, 0x4e, 0x14, 0x01, + 0x0b, 0x75, 0xa0, 0x53, 0x10, 0xb4, 0x94, 0x00, 0x52, 0x50, 0x03, 0x96, + 0xa6, 0xa9, 0x63, 0x3d, 0xa6, 0xda, 0x0a, 0x7d, 0xca, 0x0c, 0x57, 0x6d, + 0x24, 0x63, 0x36, 0x61, 0x5f, 0x2f, 0x06, 0x9f, 0xa4, 0x9d, 0xac, 0x3e, + 0xb5, 0x85, 0x72, 0xe0, 0x6e, 0xff, 0x00, 0x0d, 0x53, 0xb9, 0xe9, 0x5a, + 0x47, 0x63, 0x03, 0x9a, 0xd5, 0x97, 0xe5, 0x35, 0x92, 0x05, 0x61, 0x58, + 0xea, 0xa4, 0x4a, 0x07, 0x14, 0x6d, 0xac, 0x6e, 0x6c, 0x58, 0x89, 0x2b, + 0x42, 0xc9, 0x8c, 0x2c, 0x0d, 0x48, 0x8e, 0x8a, 0xd6, 0xf5, 0xd8, 0x63, + 0x15, 0x6a, 0x49, 0x5f, 0x67, 0x35, 0xd7, 0x44, 0xe4, 0xa8, 0x88, 0xa3, + 0xe7, 0x9a, 0x94, 0xa1, 0x61, 0x5a, 0x90, 0x2a, 0xc7, 0x4b, 0xe5, 0x1a, + 0x00, 0xb1, 0x18, 0xe2, 0xab, 0x5e, 0x48, 0x10, 0xf5, 0xa9, 0xe8, 0x3e, + 0xa4, 0xe6, 0x40, 0x91, 0x02, 0x6a, 0x8c, 0xb3, 0xb3, 0xf0, 0x2a, 0x53, + 0xd0, 0x2d, 0xa8, 0xc4, 0x88, 0x9a, 0x71, 0x01, 0x28, 0x28, 0xad, 0x71, + 0x20, 0x11, 0x92, 0x4f, 0x15, 0xce, 0x5d, 0xeb, 0x1b, 0x64, 0x29, 0x6e, + 0xb9, 0x6f, 0x5e, 0x69, 0xda, 0xe8, 0x16, 0xe4, 0x3e, 0x75, 0xd4, 0xa3, + 0xe6, 0x7d, 0xbf, 0x4a, 0xcf, 0x9a, 0x36, 0x2f, 0x86, 0xf9, 0xab, 0x16, + 0xf4, 0x3a, 0x61, 0xb8, 0xe8, 0xe0, 0xa7, 0xb5, 0xaa, 0x3f, 0x51, 0x5c, + 0xfc, 0xc7, 0x43, 0x44, 0x2f, 0x60, 0x3f, 0x87, 0x8a, 0xaa, 0xd0, 0xcb, + 0x09, 0xc8, 0xab, 0xbd, 0xcc, 0xb6, 0x2c, 0x45, 0xad, 0xcd, 0x0a, 0xe3, + 0x15, 0x32, 0xea, 0x9e, 0x67, 0x2f, 0xf3, 0x7e, 0x15, 0xbe, 0x1f, 0xdd, + 0x67, 0x3e, 0x23, 0xde, 0x1e, 0x2f, 0x15, 0xbb, 0x55, 0x1b, 0xac, 0xc9, + 0x27, 0x02, 0xbd, 0x27, 0x56, 0xd1, 0x39, 0x29, 0xd1, 0x7c, 0xe4, 0xb6, + 0xf1, 0x95, 0x15, 0xa1, 0x08, 0xe2, 0xbc, 0x26, 0xee, 0xcf, 0x63, 0xa1, + 0x3e, 0xda, 0x6e, 0x70, 0x6a, 0xcc, 0xc8, 0x9d, 0xe9, 0x9b, 0x8d, 0x4b, + 0x65, 0x20, 0xce, 0x7a, 0xd2, 0x56, 0x77, 0x2a, 0xc4, 0x52, 0x4c, 0xa9, + 0x54, 0x9e, 0xf7, 0xde, 0xa9, 0x08, 0xa9, 0x2d, 0xd7, 0xbd, 0x55, 0x92, + 0xe8, 0x76, 0x35, 0xa2, 0x44, 0x39, 0x95, 0xda, 0xe0, 0xd4, 0x65, 0x8d, + 0x6c, 0x62, 0xdd, 0xc6, 0xd2, 0x53, 0xd8, 0x44, 0xb1, 0x1c, 0x35, 0x5b, + 0xed, 0x48, 0x06, 0x1a, 0x61, 0xa0, 0x06, 0xd1, 0x40, 0x05, 0x34, 0x8c, + 0xd0, 0x98, 0x06, 0xce, 0x2a, 0x13, 0x4c, 0x42, 0x53, 0xc5, 0x21, 0x85, + 0x34, 0xd0, 0x03, 0x69, 0x76, 0xd3, 0x01, 0xd8, 0xa5, 0xc5, 0x4d, 0xc0, + 0x5a, 0x4a, 0x2e, 0x01, 0x51, 0x9a, 0x60, 0x14, 0xe1, 0x40, 0x0b, 0x49, + 0x40, 0x21, 0x45, 0x5a, 0x4f, 0xbb, 0x43, 0x01, 0xc6, 0xa6, 0x5a, 0x46, + 0x42, 0x5c, 0x7d, 0xca, 0xcb, 0x3d, 0x69, 0x95, 0x11, 0xc9, 0x4b, 0x41, + 0x63, 0xe9, 0xc2, 0x90, 0x08, 0xd4, 0xca, 0x60, 0x14, 0xea, 0x40, 0x44, + 0xdd, 0x69, 0x29, 0x88, 0x5a, 0x5a, 0x00, 0x43, 0x4d, 0xa0, 0x07, 0xad, + 0x4b, 0x48, 0x67, 0xb7, 0x5a, 0xbe, 0x56, 0xa6, 0x95, 0x32, 0xb5, 0xdf, + 0x48, 0xe5, 0x9e, 0xe6, 0x05, 0xf2, 0xf5, 0xa8, 0x6c, 0xfe, 0x59, 0x45, + 0x73, 0xe2, 0x0d, 0xe0, 0x6f, 0xaf, 0x31, 0xd5, 0x4b, 0xa2, 0x00, 0xeb, + 0x4e, 0x1b, 0x18, 0xbd, 0xce, 0x57, 0x55, 0x9f, 0xcc, 0x7d, 0x8b, 0x8a, + 0xa8, 0x13, 0x8a, 0xe7, 0xab, 0xbd, 0x8e, 0xba, 0x6b, 0x41, 0xe1, 0x69, + 0xe1, 0x6b, 0x13, 0x42, 0x78, 0xd6, 0xb4, 0x21, 0xd9, 0x8c, 0x1a, 0x48, + 0x4c, 0xe8, 0x34, 0xf1, 0x0e, 0x06, 0xdc, 0x66, 0xa5, 0xd4, 0x1f, 0x11, + 0x7e, 0x75, 0xdb, 0x40, 0xe2, 0xaa, 0x25, 0x9a, 0xe6, 0x3e, 0x7a, 0xf5, + 0xa7, 0xca, 0xf8, 0x38, 0x15, 0x51, 0xd8, 0x19, 0x24, 0x3e, 0xf5, 0x2e, + 0xe1, 0x4e, 0x22, 0x64, 0x12, 0x5d, 0xaa, 0x1e, 0x39, 0xac, 0x6b, 0xb8, + 0xe6, 0x9e, 0xe0, 0x49, 0x9f, 0x97, 0xd2, 0xa8, 0x16, 0xe5, 0xed, 0xcc, + 0xca, 0x01, 0xa9, 0x62, 0x41, 0x58, 0x24, 0x5b, 0x1f, 0x2b, 0x88, 0xd6, + 0xb2, 0xef, 0x6e, 0xf0, 0x33, 0x9e, 0x2b, 0x5b, 0x12, 0x61, 0xde, 0xde, + 0x3d, 0xc2, 0xec, 0x07, 0x09, 0x54, 0xbe, 0x44, 0xe8, 0x2b, 0x29, 0xcb, + 0x4b, 0x1b, 0xc2, 0x02, 0xf9, 0x84, 0xd2, 0x6c, 0xe7, 0x26, 0xb9, 0x9b, + 0x3b, 0x23, 0x0b, 0x12, 0x62, 0x93, 0x15, 0x98, 0x0e, 0x02, 0x92, 0x48, + 0xb3, 0x40, 0x14, 0xe5, 0xb2, 0x57, 0xed, 0x51, 0xa6, 0x9f, 0xb5, 0x86, + 0x0d, 0x5a, 0x9d, 0x8c, 0xdc, 0x0b, 0x69, 0x66, 0x3a, 0x9a, 0x77, 0xd9, + 0xd5, 0x7a, 0x01, 0x57, 0xcf, 0x70, 0xb5, 0x88, 0x98, 0x73, 0x52, 0xc6, + 0xd8, 0xac, 0xca, 0x25, 0x2f, 0xc5, 0x46, 0x69, 0x89, 0x22, 0x36, 0x34, + 0xcd, 0xe2, 0xb2, 0x65, 0x91, 0xbc, 0xc0, 0x55, 0x29, 0x2f, 0x87, 0xaf, + 0xeb, 0x4e, 0x31, 0x0b, 0xd8, 0xcd, 0x9a, 0xfb, 0x7d, 0x55, 0x7b, 0x86, + 0x35, 0xd1, 0x18, 0x9c, 0xf2, 0x99, 0x11, 0x62, 0x69, 0xb5, 0x64, 0x06, + 0x29, 0x69, 0xd8, 0x04, 0xa5, 0xa0, 0x05, 0x1d, 0x6a, 0xe2, 0x1c, 0xad, + 0x20, 0x03, 0x4d, 0x34, 0x00, 0xca, 0x4a, 0x00, 0x4a, 0x5a, 0x40, 0x3a, + 0xaa, 0xbf, 0xde, 0xa6, 0x21, 0x2a, 0x41, 0x40, 0xc7, 0x53, 0x48, 0xa0, + 0x04, 0xdb, 0x4b, 0x48, 0x05, 0xa4, 0xa0, 0x02, 0x8a, 0x00, 0x6d, 0x30, + 0xd3, 0x00, 0xa7, 0x2d, 0x00, 0x3f, 0x14, 0xca, 0x00, 0x72, 0x75, 0xab, + 0x29, 0x40, 0x31, 0x5a, 0xa7, 0x4a, 0x46, 0x63, 0x2e, 0x7e, 0xe5, 0x66, + 0x9a, 0x63, 0x88, 0xe5, 0xa5, 0xa0, 0xb1, 0x69, 0x73, 0x45, 0x80, 0x09, + 0xa6, 0xd2, 0x01, 0x69, 0xd4, 0x01, 0x13, 0x75, 0xa2, 0x98, 0x83, 0x14, + 0x0a, 0x40, 0x3a, 0x9a, 0x45, 0x30, 0x05, 0xeb, 0x52, 0xd2, 0xea, 0x33, + 0xdb, 0x2c, 0x4f, 0xc9, 0x56, 0xa4, 0x6f, 0x96, 0xbb, 0x68, 0xec, 0x73, + 0x54, 0x31, 0x75, 0x05, 0xe6, 0xb3, 0x51, 0xc4, 0x72, 0xf2, 0x6b, 0x3c, + 0x41, 0xac, 0x0d, 0x5f, 0xed, 0x28, 0xd2, 0x2a, 0xc5, 0xbf, 0xd4, 0x1a, + 0x5c, 0xaa, 0x71, 0x58, 0xc6, 0x5a, 0x0f, 0x93, 0x53, 0x37, 0xcb, 0xcb, + 0x6e, 0x34, 0xed, 0xb5, 0xce, 0xce, 0x81, 0xca, 0x29, 0xf8, 0xe6, 0xa4, + 0x09, 0x10, 0x54, 0xeb, 0xc5, 0x30, 0x2c, 0x43, 0x76, 0xd1, 0x9a, 0xd0, + 0x17, 0xde, 0x76, 0xd4, 0x7a, 0xd2, 0x2f, 0x94, 0xca, 0x71, 0xb9, 0xa3, + 0x04, 0x83, 0xaa, 0x1f, 0xc2, 0x95, 0xfe, 0x76, 0xe9, 0x5d, 0x31, 0x77, + 0x39, 0xd9, 0x3a, 0x82, 0x16, 0xab, 0xb8, 0x91, 0xab, 0x48, 0xad, 0x09, + 0x6c, 0x8f, 0xec, 0xe4, 0x9f, 0x7a, 0x5b, 0xe7, 0xfb, 0x34, 0x1c, 0x2f, + 0x5a, 0x69, 0x5c, 0x2e, 0x36, 0xc5, 0x5e, 0x71, 0x92, 0x31, 0x56, 0xe5, + 0xdb, 0x6f, 0x1f, 0xbd, 0x44, 0x51, 0x52, 0x76, 0x31, 0xaf, 0x75, 0x24, + 0x5c, 0x96, 0xae, 0x76, 0xee, 0xf5, 0xe7, 0x7e, 0x7a, 0x54, 0xc9, 0xd8, + 0xd2, 0x9c, 0x46, 0x2a, 0xc8, 0xe2, 0x90, 0x44, 0x01, 0xf9, 0x8e, 0x2b, + 0x9f, 0x73, 0xb9, 0x35, 0x12, 0xa7, 0xdb, 0xa3, 0x0f, 0x8a, 0xb4, 0xb7, + 0xb6, 0xe0, 0x72, 0x6b, 0x3b, 0x3b, 0x8e, 0x75, 0x2f, 0xb1, 0x2a, 0xdd, + 0x40, 0xdf, 0xfe, 0xaa, 0x78, 0x68, 0x8f, 0x43, 0x45, 0xcc, 0x47, 0x6d, + 0x1d, 0x54, 0xd3, 0x6a, 0x59, 0xa2, 0x61, 0x4e, 0x51, 0x52, 0x50, 0xfd, + 0xb4, 0x85, 0x29, 0x5c, 0x76, 0x23, 0x68, 0xaa, 0x22, 0x31, 0x4c, 0x44, + 0x6f, 0x20, 0x51, 0x50, 0x35, 0xc7, 0xa1, 0xa4, 0x05, 0x69, 0x6f, 0x42, + 0xf5, 0x35, 0x46, 0x6d, 0x48, 0x0e, 0x95, 0xa2, 0xa7, 0x72, 0x5c, 0x8a, + 0x32, 0xdf, 0xc8, 0xf5, 0x5c, 0xb9, 0x6e, 0xb5, 0xb2, 0x85, 0x8e, 0x76, + 0xee, 0x32, 0x8a, 0x62, 0x0a, 0x5a, 0x76, 0x00, 0xa2, 0x80, 0x16, 0x8a, + 0x40, 0x15, 0x3c, 0x2d, 0x4c, 0x09, 0xa9, 0xa6, 0x90, 0x88, 0xcd, 0x36, + 0x80, 0x0a, 0x4a, 0x06, 0x3a, 0xa1, 0x93, 0xad, 0x08, 0x4c, 0x65, 0x48, + 0xb4, 0x0c, 0x5a, 0x28, 0x18, 0xb4, 0x94, 0x00, 0x94, 0x50, 0x20, 0xa4, + 0xa0, 0x02, 0xa3, 0x34, 0x20, 0x0a, 0x70, 0xa0, 0x07, 0xd3, 0x4d, 0x00, + 0x2a, 0x55, 0x84, 0xa0, 0x07, 0x35, 0x4e, 0x9d, 0x29, 0x19, 0x90, 0xdd, + 0xfd, 0xca, 0xa1, 0x4c, 0x71, 0x1c, 0xb4, 0xe1, 0x41, 0x62, 0xe2, 0x96, + 0x8b, 0x88, 0x69, 0xa4, 0xa4, 0x31, 0xd4, 0xb4, 0x80, 0x8d, 0xba, 0xd2, + 0x8a, 0x62, 0x0c, 0x52, 0x62, 0x98, 0x0b, 0x45, 0x00, 0x20, 0xeb, 0x52, + 0x8a, 0x43, 0x3d, 0x8b, 0x4b, 0x97, 0x30, 0xd5, 0x9b, 0x89, 0x0f, 0x15, + 0xd5, 0x87, 0xf8, 0x4c, 0x2a, 0x7c, 0x45, 0x2b, 0xce, 0x63, 0x15, 0xcf, + 0xde, 0x47, 0x33, 0xb8, 0x11, 0xf1, 0xcd, 0x69, 0x25, 0x74, 0x34, 0xec, + 0x46, 0x15, 0xc7, 0x12, 0x75, 0xa3, 0x8a, 0xe2, 0x6a, 0xc6, 0xf7, 0x1a, + 0x69, 0x2b, 0x36, 0x50, 0xe5, 0x34, 0xec, 0x54, 0x6c, 0x31, 0xe2, 0x9e, + 0xb4, 0x0c, 0x95, 0x45, 0x38, 0x64, 0x3d, 0x59, 0x24, 0xe2, 0xe0, 0x83, + 0xcd, 0x69, 0x5a, 0xdf, 0x0c, 0xfc, 0xc7, 0x34, 0xf9, 0xac, 0x44, 0xa3, + 0x73, 0x66, 0x27, 0x49, 0x17, 0x2b, 0x8a, 0x73, 0x2e, 0x6b, 0xae, 0x9c, + 0xee, 0x72, 0x38, 0xd9, 0x80, 0x50, 0x29, 0xb2, 0xc0, 0x92, 0xfd, 0xf1, + 0x9a, 0xbb, 0xd8, 0x42, 0x34, 0x91, 0x40, 0x9d, 0x40, 0x15, 0xce, 0x6b, + 0x3a, 0xc1, 0x20, 0xac, 0x1d, 0x6a, 0x63, 0xa6, 0xac, 0xab, 0x5d, 0x98, + 0x3e, 0x49, 0x90, 0xee, 0x91, 0x89, 0x3e, 0xf4, 0xfd, 0xb1, 0xc6, 0x33, + 0xd2, 0xb9, 0xa7, 0x3b, 0xb3, 0xb1, 0x14, 0xef, 0xb5, 0x58, 0xe1, 0x52, + 0x17, 0x93, 0x58, 0x77, 0x5a, 0x9c, 0xd3, 0xe4, 0x74, 0x53, 0xe8, 0x68, + 0x48, 0x4d, 0x95, 0x50, 0xd3, 0x5f, 0xef, 0x55, 0x22, 0x6e, 0xc4, 0x12, + 0xb2, 0xf4, 0x63, 0x52, 0xa5, 0xec, 0xc8, 0x78, 0x73, 0x53, 0xc9, 0x73, + 0x4e, 0x62, 0xca, 0xeb, 0x13, 0x63, 0xff, 0x00, 0xaf, 0x4f, 0x5d, 0x62, + 0x4c, 0xfc, 0xc4, 0x9a, 0xcd, 0xd2, 0x29, 0x4e, 0xc5, 0x88, 0x35, 0x8e, + 0x79, 0xad, 0xcb, 0x5b, 0x85, 0x95, 0x6b, 0x9a, 0x4b, 0x95, 0x9d, 0x31, + 0xd5, 0x16, 0x29, 0xac, 0xc0, 0x53, 0x02, 0xbc, 0xd7, 0x28, 0xbd, 0xeb, + 0x3a, 0x7b, 0xe1, 0x54, 0x91, 0x06, 0x7c, 0xf7, 0xea, 0x3b, 0xd6, 0x7c, + 0xb7, 0xec, 0xdd, 0x2b, 0x65, 0x13, 0x27, 0x32, 0xb3, 0x4a, 0xcd, 0xd4, + 0xd4, 0x79, 0xad, 0x4c, 0x6e, 0x14, 0x50, 0x01, 0x4b, 0x48, 0x04, 0xa5, + 0xa6, 0x01, 0x45, 0x30, 0x1d, 0x8a, 0x7a, 0xad, 0x20, 0x1d, 0x22, 0x60, + 0x54, 0x4a, 0x70, 0x68, 0x02, 0xca, 0x3e, 0x69, 0xc6, 0x81, 0x0c, 0x22, + 0x99, 0x48, 0x63, 0x68, 0xa0, 0x02, 0xa3, 0x7e, 0xb4, 0xc4, 0x32, 0x9e, + 0xb4, 0x86, 0x3a, 0x8a, 0x00, 0x28, 0xa0, 0x04, 0xa2, 0x90, 0x05, 0x14, + 0x00, 0x94, 0xc3, 0x4c, 0x04, 0xa7, 0x0a, 0x00, 0x75, 0x36, 0x80, 0x1c, + 0xb5, 0x3a, 0xd0, 0x0c, 0x52, 0x7e, 0x6a, 0xb2, 0x94, 0x8c, 0xca, 0xf7, + 0x67, 0x8a, 0xa5, 0x54, 0x38, 0x8f, 0x4a, 0x78, 0xa4, 0x58, 0x51, 0x83, + 0x45, 0x84, 0x34, 0xd1, 0x49, 0x8c, 0x29, 0xc2, 0x90, 0x11, 0xb7, 0x5a, + 0x51, 0x54, 0x21, 0xd4, 0x94, 0x08, 0x69, 0xa6, 0xe6, 0x81, 0x8a, 0x2a, + 0x5a, 0x06, 0x7a, 0xbe, 0x91, 0x27, 0xcb, 0x8a, 0xd6, 0x6d, 0xac, 0x05, + 0x5d, 0x09, 0x59, 0x11, 0x38, 0x5e, 0x45, 0x79, 0xb0, 0xdc, 0x76, 0xaa, + 0x93, 0x98, 0xe0, 0x84, 0x91, 0x8a, 0xeb, 0x5a, 0x9c, 0xf3, 0xec, 0x62, + 0xca, 0x09, 0x3b, 0x9a, 0xa3, 0xe2, 0xb9, 0x2a, 0x6e, 0x75, 0x43, 0x61, + 0xac, 0xde, 0xd4, 0xcc, 0x9f, 0x4a, 0xc8, 0xa1, 0xd1, 0xc5, 0x33, 0x74, + 0x5a, 0x9d, 0x20, 0x97, 0xb8, 0x1f, 0x9d, 0x3e, 0x41, 0x73, 0x93, 0x79, + 0x34, 0xf5, 0xb7, 0x3e, 0xb4, 0xb9, 0x47, 0xcc, 0x4b, 0xe5, 0x15, 0x14, + 0x8b, 0x1e, 0x69, 0xd8, 0x57, 0x14, 0xc4, 0x69, 0x9b, 0x48, 0xa2, 0xc5, + 0x73, 0x17, 0x20, 0xbc, 0x92, 0x3c, 0x56, 0x95, 0xbe, 0xa6, 0x3b, 0x9f, + 0xce, 0xa5, 0x7b, 0xa4, 0xc9, 0x5c, 0xb1, 0xfd, 0xa7, 0x15, 0x41, 0x73, + 0xad, 0xc5, 0x0c, 0x44, 0x81, 0xcd, 0x6c, 0xa6, 0x63, 0xec, 0xce, 0x66, + 0xe6, 0xfa, 0xe2, 0xed, 0xc9, 0x76, 0xe3, 0xd2, 0xa0, 0xc6, 0x2a, 0x2a, + 0x54, 0xb9, 0xd3, 0x1a, 0x76, 0x17, 0x9a, 0x82, 0xee, 0x27, 0x78, 0x48, + 0x5a, 0xc1, 0x3d, 0x4d, 0x24, 0xb4, 0x30, 0xe7, 0xd3, 0x27, 0xea, 0x71, + 0x55, 0x5e, 0xc6, 0x55, 0xfe, 0x1a, 0xe8, 0x52, 0xb9, 0x85, 0x86, 0x79, + 0x2e, 0x3b, 0x53, 0x1e, 0x26, 0xf4, 0xa6, 0x84, 0x45, 0xe5, 0xb0, 0xed, + 0x4d, 0xc1, 0xa2, 0xc3, 0x12, 0x9c, 0x05, 0x48, 0x17, 0x2d, 0x2c, 0xa4, + 0x99, 0xba, 0x1c, 0x57, 0x4f, 0x67, 0x6f, 0xe4, 0xa7, 0x5a, 0xe5, 0xa8, + 0xee, 0xce, 0xc8, 0x2b, 0x22, 0x59, 0x6e, 0x16, 0x31, 0xcd, 0x66, 0x4f, + 0xa9, 0x73, 0xc5, 0x25, 0x11, 0x36, 0x64, 0xdc, 0x5f, 0x77, 0xc9, 0xaa, + 0x32, 0x5e, 0x3b, 0x74, 0x3c, 0x57, 0x4a, 0x89, 0x84, 0xa6, 0x56, 0x24, + 0x93, 0xcd, 0x25, 0x59, 0x98, 0x51, 0x40, 0x09, 0x45, 0x30, 0x16, 0x8a, + 0x90, 0x0a, 0x5a, 0x00, 0x4a, 0x5a, 0x60, 0x48, 0x2a, 0x45, 0xa4, 0x03, + 0xa4, 0xfb, 0xb5, 0x57, 0x1c, 0xd0, 0x04, 0xb1, 0xe4, 0x1a, 0xb0, 0x0d, + 0x00, 0xc0, 0x8a, 0x89, 0x85, 0x02, 0x19, 0x45, 0x03, 0x12, 0x9a, 0xd4, + 0x08, 0x8a, 0x9e, 0xb4, 0xc6, 0x3a, 0x8a, 0x40, 0x14, 0x52, 0x01, 0x28, + 0xa2, 0xc0, 0x25, 0x2d, 0x00, 0x25, 0x25, 0x50, 0x06, 0x29, 0x69, 0x00, + 0xb8, 0xa4, 0xc5, 0x20, 0x01, 0x52, 0x07, 0xa5, 0x60, 0x63, 0xb7, 0xf3, + 0x56, 0x11, 0xc5, 0x04, 0x15, 0xee, 0xdb, 0x9a, 0xad, 0x54, 0x34, 0x28, + 0x38, 0xa9, 0x63, 0xe4, 0x50, 0x50, 0xea, 0x33, 0x83, 0x40, 0x86, 0x4a, + 0x72, 0xd4, 0xca, 0x43, 0x16, 0x9d, 0x48, 0x06, 0x37, 0x5a, 0x51, 0x54, + 0x21, 0x69, 0xa4, 0xd0, 0x03, 0x69, 0x28, 0x18, 0xe1, 0x52, 0x0e, 0x95, + 0x20, 0x7a, 0x3d, 0x94, 0x84, 0x36, 0x06, 0x6b, 0x7a, 0x31, 0x95, 0x19, + 0x6a, 0xa4, 0x8d, 0x79, 0x92, 0x2b, 0xcf, 0x2e, 0x24, 0xfb, 0xd8, 0x15, + 0x91, 0x79, 0x7d, 0x18, 0xcb, 0x1e, 0x47, 0xa2, 0xf5, 0xae, 0xa8, 0xec, + 0x71, 0x4f, 0xe2, 0x33, 0xbe, 0xd6, 0x6e, 0xe6, 0x08, 0xb9, 0xdb, 0x57, + 0xa3, 0xb4, 0x5e, 0xec, 0x6b, 0x07, 0xab, 0x36, 0xd9, 0x12, 0x3c, 0x30, + 0xa2, 0xf4, 0xaa, 0x98, 0x06, 0x4f, 0x6a, 0x52, 0xd8, 0x11, 0x6b, 0xed, + 0x51, 0x01, 0x8c, 0xd3, 0x0d, 0xc6, 0x7a, 0x54, 0xdc, 0x2c, 0x09, 0x37, + 0xcd, 0xcd, 0x4f, 0xf6, 0xa4, 0x5a, 0x45, 0x10, 0xbe, 0xa4, 0xbb, 0xb6, + 0xf1, 0xf9, 0xd3, 0xe3, 0xbe, 0x43, 0xc5, 0x29, 0x68, 0x09, 0x13, 0x79, + 0xd9, 0xa6, 0xef, 0x35, 0x3c, 0xc5, 0x72, 0x86, 0xfa, 0x4c, 0x9a, 0x9b, + 0x97, 0x60, 0xa6, 0x34, 0x7e, 0xd4, 0x93, 0x18, 0xdf, 0x2e, 0x97, 0xcb, + 0xa8, 0x6c, 0xb0, 0xd9, 0x4a, 0x40, 0xef, 0x48, 0x64, 0x05, 0xa3, 0xa5, + 0xf2, 0x15, 0x85, 0x5a, 0xd0, 0x96, 0x91, 0x1f, 0xd8, 0x22, 0x6e, 0xd4, + 0xd6, 0xd1, 0xe0, 0x6e, 0xab, 0x5b, 0x29, 0xd8, 0xc6, 0x51, 0x2a, 0xdc, + 0xe8, 0xf1, 0xed, 0x1b, 0x06, 0xdf, 0xa5, 0x67, 0xbe, 0x90, 0xe3, 0xbe, + 0x6a, 0x9d, 0x52, 0x54, 0x0a, 0x8f, 0xa6, 0xcd, 0x9f, 0xbb, 0x56, 0xec, + 0xb4, 0x67, 0x2d, 0x99, 0x78, 0x15, 0x95, 0x49, 0x9a, 0xd3, 0x89, 0xb5, + 0x14, 0x31, 0xdb, 0x2d, 0x54, 0xb9, 0xd4, 0x82, 0xf0, 0xa6, 0xb0, 0x8a, + 0x36, 0x6c, 0xc7, 0xb9, 0xbe, 0xc9, 0xf9, 0x8e, 0x6b, 0x3e, 0x4b, 0xa7, + 0x6e, 0x95, 0xd3, 0x18, 0x9c, 0xf3, 0x65, 0x66, 0x39, 0xeb, 0x49, 0x5b, + 0x10, 0x14, 0x94, 0x84, 0x25, 0x2d, 0x21, 0x85, 0x15, 0x42, 0x0a, 0x2a, + 0x46, 0x2d, 0x14, 0x80, 0x28, 0xaa, 0x02, 0x55, 0xa7, 0xe6, 0xa4, 0x43, + 0xdb, 0x95, 0xa8, 0x01, 0xc5, 0x31, 0x8b, 0x9a, 0x96, 0x3c, 0xd0, 0x04, + 0xc3, 0x9a, 0x64, 0x8b, 0x48, 0x92, 0x03, 0x49, 0x40, 0xc4, 0xa4, 0xa0, + 0x08, 0xda, 0x94, 0x53, 0x63, 0x43, 0xb3, 0x45, 0x20, 0x12, 0x8a, 0x00, + 0x5a, 0x4a, 0x04, 0x14, 0x53, 0x00, 0xa2, 0x86, 0x01, 0x45, 0x20, 0x16, + 0x8a, 0x00, 0x43, 0x4c, 0xa6, 0x01, 0x9a, 0x70, 0x90, 0x8a, 0x56, 0x01, + 0x33, 0x9a, 0x5c, 0x53, 0x01, 0xad, 0x53, 0x45, 0xf7, 0x29, 0x00, 0xfa, + 0x88, 0xd1, 0x70, 0x1b, 0xde, 0x92, 0x90, 0xc5, 0xa7, 0x0a, 0x00, 0x63, + 0x75, 0xa3, 0x34, 0xc4, 0x2d, 0x46, 0x68, 0x00, 0xa2, 0x81, 0x8e, 0x15, + 0x20, 0xa0, 0x0f, 0x5b, 0xfb, 0x32, 0xda, 0x29, 0x6e, 0x33, 0x54, 0x26, + 0xd4, 0x8a, 0xb6, 0x31, 0x9f, 0xc6, 0xba, 0xa6, 0xb9, 0x4c, 0x29, 0xbe, + 0x66, 0x67, 0xdc, 0x5d, 0xca, 0xcd, 0xc1, 0xaa, 0x8f, 0x6e, 0xb2, 0xf3, + 0x23, 0x56, 0x77, 0xd0, 0xd1, 0x8f, 0xb6, 0x78, 0xe0, 0x3c, 0x55, 0x9f, + 0xb5, 0xfa, 0x66, 0xa5, 0x09, 0x95, 0x6e, 0xaf, 0xcf, 0x4e, 0xbf, 0x5a, + 0x84, 0x5d, 0xbe, 0x3a, 0x7e, 0xb4, 0xdd, 0x31, 0x29, 0x11, 0x1b, 0x96, + 0xce, 0x49, 0x35, 0x13, 0x6a, 0x72, 0x29, 0xc2, 0x8f, 0xd6, 0x9f, 0xb2, + 0x2b, 0x98, 0x85, 0xb5, 0x09, 0xbe, 0x95, 0x19, 0xbb, 0x9c, 0xff, 0x00, + 0xcb, 0x43, 0x53, 0x6b, 0x0e, 0xe3, 0x3c, 0xc7, 0xcf, 0xdf, 0x35, 0xa1, + 0xa3, 0x2c, 0x92, 0xdd, 0x0f, 0x98, 0xe2, 0xb3, 0xad, 0xb1, 0xad, 0x2d, + 0xce, 0x94, 0x27, 0x02, 0x97, 0x6d, 0x73, 0x16, 0x3b, 0x65, 0x38, 0x44, + 0x4f, 0x41, 0x40, 0xcb, 0x31, 0xe9, 0xf2, 0x3f, 0x6a, 0x8e, 0xea, 0xd8, + 0xdb, 0xfd, 0xea, 0xdb, 0x94, 0xcf, 0x9f, 0x52, 0xb5, 0x15, 0xce, 0x6e, + 0x36, 0x99, 0x27, 0x4a, 0x10, 0x99, 0x44, 0xdb, 0x1d, 0xd5, 0x69, 0x14, + 0xd5, 0x30, 0x48, 0x99, 0x45, 0x48, 0x2a, 0x2e, 0x55, 0x86, 0x91, 0x9a, + 0x61, 0x8c, 0x7a, 0x51, 0x70, 0xb1, 0x1f, 0x94, 0xa2, 0xa0, 0xb8, 0xb8, + 0x8e, 0x04, 0xcd, 0x35, 0xa8, 0x6c, 0x62, 0x5e, 0xea, 0x06, 0x4c, 0xf3, + 0xc7, 0xb5, 0x64, 0xcd, 0x75, 0xe9, 0x5d, 0x11, 0x89, 0x8b, 0x65, 0x46, + 0x62, 0xd4, 0x95, 0xa1, 0x90, 0x86, 0x92, 0x98, 0x05, 0x25, 0x02, 0x0a, + 0x5c, 0x52, 0x18, 0xb8, 0xa4, 0xa6, 0x80, 0x4a, 0x5a, 0x00, 0x29, 0x68, + 0x01, 0x29, 0x69, 0x00, 0xf1, 0x4f, 0x14, 0x80, 0x97, 0xf8, 0x69, 0x82, + 0x2a, 0x04, 0x4a, 0x23, 0x02, 0x9d, 0x8a, 0x04, 0x37, 0xa1, 0xa9, 0x78, + 0x65, 0xa0, 0x0a, 0xae, 0xb8, 0xa8, 0xe8, 0x01, 0x29, 0x28, 0x18, 0xd3, + 0x49, 0x4c, 0x62, 0xd2, 0xd2, 0x10, 0x51, 0x40, 0x05, 0x14, 0xc0, 0x28, + 0xa4, 0x02, 0x51, 0x40, 0x06, 0x28, 0xa0, 0x61, 0x4b, 0x40, 0x82, 0xa3, + 0xa0, 0x04, 0xa2, 0x81, 0x8e, 0x5a, 0x75, 0x31, 0x0d, 0x6a, 0x96, 0x1f, + 0xbb, 0x48, 0x07, 0xf6, 0xa8, 0xa8, 0x01, 0x86, 0x8a, 0x06, 0x2d, 0x3a, + 0x90, 0x0c, 0x6a, 0x41, 0x4e, 0xc0, 0x49, 0xfc, 0x35, 0x0d, 0x02, 0x12, + 0x9d, 0x40, 0xc5, 0xa9, 0x29, 0x30, 0x3d, 0x37, 0x53, 0xbb, 0x77, 0x3b, + 0x73, 0x59, 0xbb, 0x47, 0x2e, 0x6b, 0xa6, 0xb6, 0xb2, 0xb1, 0x8d, 0x3f, + 0x76, 0x37, 0x2b, 0xb4, 0x9f, 0x3e, 0x4f, 0xdd, 0x15, 0x14, 0x7e, 0x7c, + 0xc7, 0x8f, 0xbb, 0xef, 0x55, 0xca, 0x47, 0x30, 0xa2, 0xd1, 0xde, 0x40, + 0x37, 0x6d, 0xfa, 0x55, 0xcf, 0xb3, 0x72, 0x06, 0x49, 0xfc, 0x2a, 0x89, + 0xb9, 0x05, 0xc5, 0xb0, 0x3c, 0x2f, 0x5a, 0x86, 0xe1, 0x56, 0xde, 0x23, + 0xf2, 0xd6, 0x84, 0xdc, 0xa0, 0xd7, 0x1b, 0x07, 0xff, 0x00, 0x5e, 0xa9, + 0xb1, 0xc9, 0x35, 0x93, 0x36, 0x48, 0x51, 0x49, 0x59, 0x58, 0xd0, 0x3e, + 0x83, 0x9a, 0xeb, 0x34, 0x1b, 0x2f, 0x22, 0x0d, 0xe4, 0x7c, 0xc6, 0xb9, + 0x6b, 0xbe, 0x87, 0x45, 0x25, 0xa5, 0xcd, 0x4d, 0x94, 0x6d, 0xac, 0x4a, + 0x16, 0xb4, 0x34, 0x98, 0x95, 0xe4, 0x62, 0xc0, 0x71, 0x8a, 0x40, 0xf6, + 0x34, 0x65, 0xb8, 0x8a, 0xdc, 0xe0, 0x57, 0x3d, 0xac, 0x5c, 0x19, 0xfe, + 0xed, 0x75, 0xde, 0xc7, 0x34, 0x62, 0xee, 0x53, 0x55, 0x38, 0xa7, 0xd7, + 0x19, 0xd8, 0x14, 0xda, 0x00, 0x6e, 0x29, 0xd4, 0x0c, 0x5a, 0x75, 0x21, + 0x85, 0x21, 0x38, 0xa0, 0x0c, 0xdb, 0xeb, 0xf1, 0x0a, 0xfc, 0xbc, 0x9a, + 0xe7, 0xee, 0xaf, 0x0b, 0xb6, 0x5f, 0x9a, 0xde, 0x28, 0xc5, 0xc8, 0xcc, + 0x96, 0xe0, 0xbd, 0x42, 0x2b, 0x74, 0x62, 0xc7, 0x52, 0x53, 0x01, 0x29, + 0xb4, 0x00, 0x94, 0x54, 0x80, 0x66, 0x9d, 0x9a, 0x04, 0x26, 0x69, 0x33, + 0x54, 0x30, 0xa5, 0xa4, 0x01, 0x45, 0x00, 0x14, 0x52, 0x01, 0xeb, 0x52, + 0x0a, 0x00, 0x91, 0x4d, 0x4b, 0x40, 0x83, 0x34, 0xb4, 0x08, 0x6b, 0x53, + 0x51, 0xf1, 0x40, 0x09, 0x27, 0x35, 0x01, 0xa1, 0x00, 0xdc, 0xd2, 0x50, + 0x50, 0x94, 0xa0, 0x50, 0x01, 0x45, 0x32, 0x42, 0x8a, 0x43, 0x0a, 0x33, + 0x40, 0x09, 0x9a, 0x37, 0x50, 0x02, 0x6e, 0xa5, 0xdf, 0x40, 0x09, 0xbe, + 0x8d, 0xd4, 0x00, 0x6e, 0xa7, 0xee, 0xe2, 0x80, 0x19, 0x9a, 0x69, 0xa0, + 0x04, 0xa2, 0x98, 0xc7, 0x2d, 0x3a, 0x90, 0x86, 0xb5, 0x4b, 0x09, 0xf9, + 0x68, 0x01, 0x69, 0x94, 0x30, 0x18, 0x68, 0xa0, 0x62, 0xd2, 0xd4, 0x80, + 0xd7, 0xa6, 0x8a, 0xa0, 0x24, 0x6f, 0xb9, 0x51, 0x50, 0x20, 0xa5, 0x14, + 0x0c, 0x5c, 0xd3, 0xe9, 0x01, 0xe8, 0xd2, 0x21, 0x63, 0xbd, 0xeb, 0x36, + 0xe2, 0x4f, 0x35, 0xbc, 0xb5, 0xfb, 0xbd, 0xeb, 0xaa, 0x3a, 0xbe, 0x63, + 0x9e, 0x5d, 0x84, 0x58, 0x8b, 0x9f, 0x25, 0x39, 0x53, 0xe9, 0x57, 0x45, + 0xa8, 0x8c, 0x04, 0x40, 0x72, 0x6b, 0x43, 0x33, 0x46, 0x1b, 0x3f, 0x22, + 0x0d, 0xc5, 0x23, 0xdd, 0xeb, 0x9a, 0x72, 0x42, 0xb1, 0x23, 0x49, 0xe6, + 0xe3, 0xda, 0x9a, 0x64, 0xb3, 0x35, 0xbc, 0xbd, 0xfb, 0x98, 0xb6, 0x41, + 0xaa, 0x17, 0x3f, 0xbc, 0x72, 0x48, 0xe3, 0xde, 0xa9, 0x05, 0x8c, 0xab, + 0x80, 0xac, 0xdc, 0x0e, 0x95, 0x0e, 0xca, 0xc6, 0x7b, 0x9b, 0xc4, 0x29, + 0xb5, 0x9b, 0x28, 0xbb, 0xa4, 0xda, 0xfd, 0xa6, 0xf1, 0x01, 0x1f, 0x28, + 0x35, 0xda, 0x5b, 0xc6, 0x12, 0x25, 0x51, 0xd0, 0x0a, 0xe0, 0xa9, 0xac, + 0x8e, 0xd8, 0xfc, 0x24, 0x84, 0x55, 0x7b, 0x89, 0x04, 0x29, 0xb8, 0xd1, + 0x15, 0x72, 0x5b, 0x28, 0xc9, 0xa9, 0xa2, 0x0c, 0xd4, 0x71, 0xf8, 0x94, + 0x40, 0xd8, 0x59, 0x76, 0xd5, 0x3a, 0x4c, 0x14, 0x91, 0x66, 0xd7, 0x53, + 0xfb, 0x74, 0xb5, 0x68, 0x8a, 0x8e, 0x62, 0xb9, 0x6c, 0x36, 0x98, 0x45, + 0x22, 0x82, 0x9b, 0x40, 0x08, 0x69, 0x05, 0x16, 0x01, 0xd4, 0x54, 0x14, + 0x26, 0x6b, 0x33, 0x51, 0xd4, 0x3c, 0xa1, 0xb5, 0x7a, 0xd6, 0x90, 0x8d, + 0xc9, 0x93, 0x39, 0xbb, 0x9b, 0xa2, 0xce, 0x49, 0x35, 0x42, 0x47, 0xdd, + 0x5d, 0x56, 0x39, 0xe4, 0x45, 0x4e, 0x15, 0x64, 0x8b, 0x49, 0x40, 0x05, + 0x34, 0xd4, 0x80, 0xda, 0x4a, 0x04, 0x82, 0x96, 0x9d, 0xc6, 0x14, 0x52, + 0x01, 0x68, 0xa4, 0x01, 0x4b, 0x4c, 0x02, 0x8a, 0x40, 0x2a, 0xd4, 0x82, + 0x80, 0x24, 0x5e, 0xb5, 0x2d, 0x02, 0x0a, 0x5a, 0x00, 0x4a, 0x89, 0xc6, + 0x39, 0xa0, 0x06, 0xe6, 0x9a, 0xd4, 0x0c, 0x65, 0x14, 0x08, 0x6d, 0x3c, + 0x30, 0xc5, 0x00, 0x30, 0x9a, 0x6e, 0x69, 0xee, 0x02, 0xe6, 0x93, 0x34, + 0x86, 0x26, 0x68, 0xcd, 0x00, 0x25, 0x14, 0x00, 0x51, 0x40, 0x09, 0x4b, + 0x4c, 0x05, 0xa6, 0xd0, 0x02, 0xd1, 0x8a, 0x40, 0x2e, 0x29, 0x31, 0x40, + 0x87, 0x2d, 0x3a, 0x80, 0x1a, 0xd5, 0x24, 0x3d, 0x0d, 0x00, 0x38, 0xd4, + 0x74, 0x00, 0xda, 0x29, 0x0c, 0x51, 0x4b, 0x40, 0x0d, 0x7a, 0x6d, 0x30, + 0x15, 0x8f, 0x14, 0xda, 0x00, 0x4a, 0x78, 0x14, 0x00, 0xec, 0x53, 0xa8, + 0x03, 0xd0, 0xf5, 0x19, 0x73, 0xfb, 0xb4, 0xea, 0x6a, 0x88, 0x4d, 0x9f, + 0xc3, 0xf3, 0x1a, 0xe9, 0x8a, 0x39, 0x59, 0xa5, 0xa7, 0xd8, 0x98, 0x17, + 0x7e, 0xee, 0x7e, 0xb5, 0xa1, 0x04, 0x0a, 0xff, 0x00, 0xbd, 0x9a, 0x46, + 0x03, 0xda, 0xb4, 0x44, 0x49, 0x99, 0x17, 0xd7, 0xe1, 0x2e, 0x30, 0x9f, + 0xbc, 0x51, 0xfd, 0xea, 0x8d, 0xee, 0x6e, 0x6e, 0xe3, 0x2a, 0x91, 0x44, + 0xa3, 0xd7, 0x75, 0x5c, 0xb4, 0x90, 0x2d, 0x8a, 0xc5, 0x67, 0xf3, 0x02, + 0x34, 0xbc, 0x54, 0x37, 0xce, 0x04, 0x7b, 0x43, 0x9d, 0xd5, 0x3d, 0x47, + 0xb9, 0x9b, 0x48, 0x71, 0x58, 0xbd, 0xcd, 0xc8, 0xd8, 0xd3, 0x7e, 0x95, + 0x0c, 0xa8, 0x9d, 0x5f, 0x87, 0xec, 0xfc, 0x98, 0x3c, 0xc3, 0xf7, 0x8f, + 0xf8, 0xd6, 0xe4, 0x75, 0xe6, 0xee, 0x76, 0xb1, 0x4d, 0x64, 0xeb, 0xdf, + 0xf1, 0xe2, 0xdf, 0x8d, 0x6f, 0x47, 0xe2, 0x39, 0xea, 0xfc, 0x27, 0x2f, + 0x2f, 0x4a, 0xce, 0x97, 0xad, 0x7a, 0x12, 0xd8, 0xe7, 0x8b, 0x36, 0xfc, + 0x31, 0x20, 0x87, 0x7f, 0xd3, 0xfa, 0xd6, 0xe9, 0xbe, 0x5a, 0xf2, 0xf9, + 0x7d, 0xe6, 0x7a, 0x12, 0x64, 0x7f, 0xda, 0x0b, 0x47, 0xdb, 0x47, 0xbd, + 0x57, 0x29, 0x37, 0x1b, 0xf6, 0xcf, 0x63, 0x4d, 0xfb, 0x67, 0xb1, 0xaa, + 0x51, 0x23, 0x98, 0x0d, 0xef, 0xfb, 0x26, 0xa3, 0x5b, 0xd2, 0x7f, 0x86, + 0x93, 0x88, 0xe2, 0xcb, 0x70, 0xc8, 0x5d, 0x6a, 0x6a, 0xc4, 0xd8, 0xce, + 0xd5, 0x2f, 0x84, 0x11, 0xe0, 0x7d, 0xea, 0xe5, 0xee, 0x67, 0xdc, 0xd9, + 0x35, 0xd1, 0x04, 0x60, 0xe4, 0x51, 0x27, 0x3d, 0x69, 0x2b, 0x63, 0x21, + 0x48, 0xe6, 0x8a, 0x00, 0x43, 0x49, 0x40, 0x05, 0x34, 0xd0, 0x03, 0x68, + 0xa4, 0x02, 0xd2, 0x55, 0x00, 0x51, 0x48, 0x05, 0xa2, 0x80, 0x0a, 0x5a, + 0x40, 0x14, 0x50, 0x02, 0xad, 0x48, 0x28, 0x01, 0xea, 0x6a, 0x5a, 0x00, + 0x5a, 0x28, 0x10, 0x53, 0x5b, 0xee, 0x1a, 0x04, 0x57, 0xcf, 0x34, 0x53, + 0x18, 0xda, 0x29, 0x00, 0xc3, 0x4d, 0xa0, 0x04, 0xa2, 0x98, 0x0b, 0x49, + 0x48, 0x61, 0x45, 0x30, 0x16, 0x8c, 0x52, 0x10, 0xb8, 0xa5, 0xc5, 0x00, + 0x32, 0x9e, 0x28, 0x01, 0x68, 0xc5, 0x03, 0x11, 0x69, 0x28, 0x10, 0x66, + 0x92, 0x98, 0x0a, 0xb4, 0xea, 0x43, 0x1a, 0x69, 0xd1, 0x1a, 0x00, 0x71, + 0xa6, 0xd0, 0x21, 0xb4, 0x50, 0x31, 0x68, 0xa0, 0x00, 0xd2, 0x50, 0x03, + 0x69, 0x31, 0x40, 0x05, 0x48, 0x28, 0x00, 0xdd, 0x49, 0x9a, 0x00, 0xef, + 0x91, 0x77, 0x39, 0x79, 0x2a, 0xd6, 0x9d, 0x6d, 0xe6, 0xcf, 0xba, 0x55, + 0x62, 0x05, 0x75, 0x1c, 0x86, 0xc7, 0x91, 0xe6, 0x61, 0x56, 0x11, 0xff, + 0x00, 0x02, 0x38, 0xa6, 0x6b, 0x17, 0xf2, 0x59, 0x59, 0xf9, 0x42, 0x28, + 0xc6, 0x78, 0xf9, 0x4d, 0x74, 0xc1, 0x6a, 0x61, 0x2d, 0x8e, 0x49, 0xb0, + 0x5c, 0x9f, 0x53, 0x57, 0x62, 0xb9, 0x8a, 0x35, 0xc0, 0xdd, 0x9a, 0xc2, + 0x6e, 0xf2, 0x36, 0x5b, 0x11, 0x49, 0x38, 0x1f, 0xc0, 0x33, 0x59, 0xb7, + 0x2f, 0xe6, 0x1c, 0x95, 0xc5, 0x52, 0x63, 0x48, 0xaf, 0x8a, 0x8d, 0xab, + 0x37, 0xa9, 0xa8, 0xcc, 0x55, 0xcd, 0x26, 0xd7, 0xed, 0x37, 0xa8, 0x31, + 0xf2, 0xe6, 0xb9, 0xaa, 0xbb, 0x44, 0xde, 0x92, 0xd4, 0xed, 0x63, 0x5d, + 0xb1, 0xa8, 0x1e, 0x95, 0x2a, 0xd7, 0x11, 0xb8, 0xe3, 0x59, 0x7a, 0xda, + 0xee, 0xb3, 0x61, 0xf5, 0xad, 0xa8, 0xfc, 0x46, 0x15, 0x76, 0x39, 0x79, + 0xc6, 0x06, 0x2b, 0x3a, 0x41, 0xf3, 0x57, 0x7c, 0x96, 0x87, 0x3c, 0x0d, + 0xdf, 0x0e, 0xdb, 0x16, 0x47, 0x7e, 0xd8, 0xfe, 0xb5, 0xa8, 0xf6, 0xb5, + 0xe7, 0xf5, 0x3b, 0x64, 0x33, 0xec, 0xc3, 0xd2, 0x9c, 0xb6, 0xf5, 0x7b, + 0x88, 0x9c, 0x5a, 0x67, 0xff, 0x00, 0xd5, 0x4b, 0xf6, 0x51, 0x53, 0x66, + 0x3d, 0x06, 0x9b, 0x74, 0xa4, 0xf2, 0x12, 0xa5, 0xb2, 0x92, 0x24, 0x55, + 0x0b, 0x55, 0xef, 0x6e, 0x56, 0xde, 0x12, 0xc6, 0xa2, 0x2a, 0xec, 0xa9, + 0x1c, 0x9d, 0xed, 0xd1, 0x9a, 0x42, 0xed, 0x59, 0xec, 0x77, 0x57, 0x5c, + 0x4e, 0x71, 0x29, 0x45, 0x36, 0x48, 0xfc, 0x71, 0x51, 0xd3, 0xb8, 0x09, + 0x45, 0x48, 0x0a, 0x72, 0x6a, 0x33, 0x4e, 0xe0, 0x36, 0x8a, 0x00, 0x7d, + 0x36, 0x8b, 0x80, 0x62, 0x8a, 0x2e, 0x02, 0x53, 0xa8, 0x00, 0xa5, 0x14, + 0x80, 0x29, 0x0d, 0x00, 0x02, 0xa5, 0x14, 0x00, 0xb5, 0x32, 0xf4, 0xa0, + 0x05, 0xa2, 0x81, 0x0b, 0x47, 0x6a, 0x04, 0x54, 0x3f, 0x7a, 0x8a, 0x60, + 0x25, 0x14, 0xae, 0x31, 0x86, 0x81, 0x40, 0x08, 0x69, 0x29, 0x8c, 0x5a, + 0x28, 0x10, 0x62, 0x9d, 0xb6, 0x90, 0x06, 0x29, 0x68, 0xb8, 0x0b, 0x49, + 0x40, 0x82, 0x8d, 0xb4, 0x0c, 0x5c, 0x52, 0xe2, 0x80, 0x13, 0x6d, 0x30, + 0x8a, 0x62, 0x0d, 0xb4, 0xb8, 0xa4, 0x30, 0xa2, 0x80, 0x18, 0xd5, 0x24, + 0x3d, 0xe8, 0x00, 0x6a, 0x6d, 0x00, 0x21, 0xa2, 0x81, 0x85, 0x2d, 0x2b, + 0x80, 0xec, 0x66, 0x82, 0x29, 0x88, 0x6e, 0x28, 0x34, 0x98, 0xc4, 0xa4, + 0xcd, 0x30, 0x12, 0x94, 0x0a, 0x00, 0xf4, 0x36, 0xf9, 0xa4, 0x11, 0xd6, + 0xbd, 0xa5, 0xce, 0xd0, 0x23, 0x49, 0x30, 0x7d, 0xab, 0xa9, 0xe8, 0xce, + 0x4d, 0xd0, 0xeb, 0xbb, 0xbf, 0x22, 0x13, 0x23, 0x34, 0x8d, 0x8f, 0xee, + 0xd7, 0x29, 0xa9, 0xdd, 0x34, 0xad, 0xe6, 0x7c, 0xdb, 0x7f, 0xdd, 0xae, + 0xa5, 0x1d, 0x0c, 0xba, 0x94, 0x7c, 0xf7, 0x28, 0x5b, 0x9c, 0x7b, 0xd4, + 0xb6, 0xf9, 0x61, 0x97, 0xe0, 0x57, 0x31, 0xb9, 0x5b, 0x69, 0x9e, 0x6e, + 0x1b, 0x8a, 0x99, 0xb9, 0xc0, 0xa7, 0xf6, 0x82, 0xe3, 0x1b, 0xa5, 0x40, + 0x6a, 0x64, 0x52, 0x0c, 0x13, 0xd2, 0xba, 0xaf, 0x0e, 0x69, 0xed, 0x1c, + 0x5b, 0xf6, 0xfc, 0xdf, 0xfd, 0x7a, 0xe5, 0xad, 0xd8, 0xea, 0xa5, 0xa6, + 0xa7, 0x44, 0xba, 0x7c, 0xed, 0xda, 0xa7, 0x5d, 0x2e, 0x4f, 0xef, 0x52, + 0xf6, 0x44, 0x7b, 0x54, 0x3b, 0xfb, 0x35, 0xbf, 0xbd, 0x55, 0x35, 0x0d, + 0x1c, 0xc9, 0x6e, 0x46, 0xe3, 0x5b, 0x52, 0xa6, 0x94, 0x8c, 0x6a, 0xd5, + 0xf7, 0x4e, 0x5a, 0xe3, 0x43, 0xbb, 0x24, 0xfc, 0xa2, 0xab, 0x2f, 0x86, + 0x6e, 0x5f, 0xa9, 0x02, 0xbb, 0x27, 0x63, 0x08, 0x4c, 0xe8, 0x34, 0x7d, + 0x0d, 0xad, 0xad, 0xf6, 0x75, 0xeb, 0x5a, 0x23, 0x49, 0x26, 0xb8, 0x94, + 0x0e, 0xa9, 0x55, 0x24, 0x1a, 0x38, 0xa9, 0x97, 0x4b, 0x51, 0x4e, 0xc4, + 0x73, 0x8f, 0x36, 0x91, 0xc4, 0xb9, 0xae, 0x73, 0x51, 0xbc, 0x54, 0x27, + 0x6d, 0x2e, 0x5d, 0x07, 0x19, 0xea, 0x62, 0xdc, 0xea, 0xcf, 0x9d, 0xa8, + 0xbf, 0xad, 0x5d, 0xb3, 0x9b, 0xcc, 0x5a, 0xe2, 0xa9, 0xb9, 0xdf, 0x4f, + 0x62, 0xce, 0xec, 0x57, 0x35, 0xac, 0x5e, 0x99, 0xa5, 0xda, 0x3a, 0x0a, + 0xba, 0x68, 0xce, 0xa3, 0x31, 0x1c, 0x92, 0x69, 0x36, 0xf1, 0x5b, 0x18, + 0x8e, 0x0b, 0x45, 0x3d, 0xc4, 0x1d, 0xaa, 0x3a, 0x06, 0x1c, 0xd2, 0x73, + 0x45, 0x80, 0x4e, 0x69, 0x3a, 0xd0, 0x03, 0x69, 0x3b, 0xd3, 0x60, 0x3e, + 0x8c, 0x52, 0xb0, 0x05, 0x36, 0x8b, 0x00, 0x94, 0xb4, 0x80, 0x29, 0x69, + 0x80, 0xb4, 0x52, 0x01, 0x29, 0xe2, 0x80, 0x1e, 0x2a, 0x45, 0xcd, 0x02, + 0x1d, 0x45, 0x30, 0x16, 0x95, 0x7a, 0xd2, 0xb8, 0x8a, 0xce, 0x39, 0xa6, + 0x53, 0x60, 0x86, 0xd2, 0xd2, 0x28, 0x43, 0x41, 0xa6, 0x21, 0x29, 0xb4, + 0x80, 0x50, 0x29, 0xe1, 0x68, 0x01, 0xdd, 0x29, 0x28, 0x00, 0xc5, 0x18, + 0xa0, 0x03, 0x14, 0x98, 0xa0, 0x02, 0x8a, 0x00, 0x5c, 0xd2, 0xe6, 0x8b, + 0x08, 0x33, 0x48, 0x68, 0x18, 0x94, 0x94, 0x00, 0x51, 0x40, 0x0d, 0x34, + 0xf8, 0x7a, 0x9a, 0x06, 0x07, 0xad, 0x21, 0xa0, 0x44, 0x7d, 0xe8, 0xa0, + 0x62, 0xe6, 0x9d, 0x48, 0x07, 0x52, 0x66, 0x98, 0x0d, 0x26, 0x92, 0x80, + 0x12, 0x97, 0x14, 0x08, 0x5a, 0x28, 0x19, 0xe9, 0xd1, 0xd9, 0xb7, 0xde, + 0x28, 0x0f, 0xd6, 0xae, 0xd9, 0xda, 0xc0, 0x9f, 0xbe, 0x95, 0x9c, 0x7b, + 0x01, 0x5d, 0xdb, 0x9c, 0x43, 0x9e, 0x0f, 0x3e, 0x5d, 0xd1, 0x6d, 0xf2, + 0xff, 0x00, 0xda, 0x35, 0x9b, 0x7f, 0x1b, 0xc9, 0x27, 0x97, 0x80, 0x56, + 0xb4, 0xba, 0x23, 0xd4, 0xa7, 0x75, 0x02, 0x24, 0x3b, 0x16, 0x35, 0x19, + 0xac, 0x5b, 0xa9, 0x76, 0x2f, 0x93, 0x19, 0xc0, 0x35, 0x25, 0xc7, 0x72, + 0x58, 0x53, 0xc8, 0x83, 0x27, 0xa9, 0xfd, 0x69, 0xf0, 0x41, 0x9e, 0x58, + 0xd6, 0x45, 0xb1, 0x97, 0x71, 0xac, 0x69, 0x85, 0xa8, 0xec, 0x2c, 0x65, + 0xbd, 0x9c, 0x47, 0x1a, 0xf2, 0x6a, 0xa7, 0xdc, 0x21, 0xa9, 0xd8, 0xe9, + 0x9e, 0x0e, 0x85, 0x42, 0xbd, 0xd7, 0x27, 0xd3, 0x02, 0xba, 0x7b, 0x7b, + 0x68, 0xad, 0x93, 0x6c, 0x49, 0x81, 0x5c, 0xb3, 0x95, 0xcd, 0xa3, 0x72, + 0x5a, 0x2a, 0x0a, 0xe4, 0x41, 0x45, 0x3b, 0xd8, 0xc7, 0x96, 0xfa, 0x0c, + 0x31, 0x21, 0xfe, 0x11, 0x48, 0xb6, 0xf1, 0x2f, 0x44, 0x15, 0xa7, 0xb4, + 0xb9, 0x1e, 0xce, 0xc3, 0xf0, 0x3d, 0x29, 0x6a, 0x79, 0x8a, 0xe4, 0x0a, + 0x46, 0xe0, 0x55, 0x27, 0x70, 0xb5, 0x8c, 0x2f, 0x10, 0x5d, 0xb4, 0x36, + 0xdb, 0x14, 0xfc, 0xcd, 0x91, 0x5c, 0x1d, 0xfd, 0xce, 0xd2, 0xc1, 0x7a, + 0x93, 0x4e, 0x7b, 0x17, 0x4b, 0x72, 0x8c, 0x7f, 0x31, 0xc9, 0xad, 0xad, + 0x35, 0xf8, 0xc5, 0x70, 0x54, 0x3d, 0x18, 0x12, 0x6a, 0x77, 0x5e, 0x45, + 0xb9, 0xc7, 0xde, 0xed, 0x5c, 0xa4, 0xaf, 0xb9, 0xcd, 0x6d, 0x4f, 0x63, + 0x9a, 0x7b, 0x91, 0xe2, 0x9d, 0x5a, 0x12, 0x2d, 0x06, 0x90, 0x11, 0x66, + 0x9b, 0x4c, 0x02, 0x8a, 0x00, 0x29, 0xb4, 0x80, 0x63, 0x52, 0x03, 0x54, + 0x04, 0x94, 0x52, 0x00, 0xa6, 0xd0, 0x02, 0x51, 0x48, 0x02, 0x96, 0xa8, + 0x05, 0xa2, 0xa5, 0x80, 0x94, 0xf5, 0xa0, 0x07, 0x53, 0xd2, 0x81, 0x12, + 0x51, 0x40, 0x05, 0x20, 0x6f, 0x9a, 0x98, 0x11, 0xce, 0x3e, 0x7a, 0x8a, + 0x81, 0x09, 0x40, 0xa4, 0x50, 0x53, 0x68, 0x10, 0x94, 0xa0, 0x50, 0x04, + 0x80, 0x53, 0xc0, 0xa0, 0x03, 0x14, 0x98, 0xa0, 0x02, 0x9b, 0x9a, 0x00, + 0x4c, 0xd2, 0x66, 0x80, 0x0a, 0x28, 0x18, 0x52, 0x66, 0x98, 0x83, 0x34, + 0x66, 0x90, 0x06, 0x69, 0x33, 0x40, 0x82, 0x8a, 0x06, 0x07, 0x9a, 0x74, + 0x5d, 0x68, 0x01, 0xa4, 0xf3, 0x49, 0x40, 0xc4, 0xa4, 0xa0, 0x02, 0x97, + 0x34, 0x00, 0xbb, 0xa9, 0x28, 0x00, 0xa2, 0x80, 0x16, 0x96, 0x80, 0x12, + 0x8a, 0x00, 0xf5, 0xe8, 0xa1, 0x69, 0xa7, 0x01, 0x72, 0xeb, 0xdf, 0x70, + 0xa9, 0x6e, 0xe7, 0x2a, 0xbe, 0x47, 0x96, 0x23, 0xcf, 0xf7, 0x2b, 0xd0, + 0x5d, 0xd1, 0xe7, 0xb2, 0x85, 0xd4, 0x90, 0xc7, 0x16, 0xc4, 0x67, 0x24, + 0xfa, 0xad, 0x51, 0xff, 0x00, 0x52, 0x85, 0xb7, 0xe2, 0x82, 0x8c, 0xc9, + 0xae, 0x36, 0x83, 0x21, 0x6c, 0x91, 0x54, 0xec, 0xa3, 0xf3, 0xe7, 0xde, + 0x7a, 0x2f, 0xaf, 0xd6, 0xa2, 0x6f, 0x42, 0xa2, 0x5b, 0x65, 0xde, 0xde, + 0xc2, 0x9a, 0xd2, 0x34, 0x7f, 0x76, 0x80, 0x29, 0xca, 0xcd, 0x2b, 0x7b, + 0xe2, 0xbb, 0xef, 0x09, 0xe9, 0x8b, 0x6d, 0x6b, 0xe7, 0x32, 0xfc, 0xed, + 0x91, 0xfa, 0xd7, 0x3d, 0x67, 0xd0, 0xe9, 0xa6, 0xb4, 0x3a, 0x1a, 0x2b, + 0x22, 0xc2, 0x8a, 0x00, 0x33, 0x45, 0x04, 0x44, 0x28, 0xa0, 0xb0, 0xa2, + 0x80, 0x0a, 0x3a, 0xd3, 0x89, 0x95, 0x43, 0x90, 0xf1, 0x9c, 0xfe, 0x40, + 0xc8, 0xea, 0x39, 0x1f, 0x95, 0x70, 0x6c, 0x4b, 0xc9, 0x93, 0xcd, 0x6d, + 0x5f, 0x64, 0x56, 0x18, 0x9a, 0x2a, 0xd2, 0xb3, 0xf9, 0x6b, 0xcf, 0x91, + 0xdc, 0x8c, 0xfd, 0x5e, 0xe3, 0xcc, 0x97, 0x06, 0xb2, 0x47, 0xde, 0xae, + 0xa5, 0xb1, 0xc8, 0xc7, 0x77, 0xa2, 0xa8, 0x42, 0xd2, 0x37, 0x4a, 0x90, + 0x22, 0xa6, 0xd3, 0x18, 0x51, 0x40, 0x0b, 0x4d, 0xa4, 0xc4, 0x34, 0xd3, + 0x68, 0x01, 0x69, 0x68, 0x18, 0x66, 0x92, 0x90, 0x05, 0x14, 0xc4, 0x14, + 0x50, 0x31, 0x69, 0x29, 0x00, 0x53, 0xd6, 0x98, 0x87, 0xd3, 0xd6, 0x80, + 0x24, 0xa2, 0x81, 0x08, 0xd5, 0x1e, 0x79, 0xa0, 0x68, 0x7c, 0xa3, 0x85, + 0xaa, 0xef, 0x40, 0x84, 0xcd, 0x25, 0x03, 0x16, 0x9a, 0x69, 0x00, 0x0a, + 0x78, 0xa6, 0x03, 0xa9, 0xe0, 0xd2, 0x01, 0x09, 0xa6, 0x96, 0xa0, 0x42, + 0x53, 0x73, 0x40, 0xc4, 0xcd, 0x26, 0x69, 0x80, 0x99, 0xa2, 0x90, 0x05, + 0x25, 0x00, 0x14, 0xb4, 0x00, 0x51, 0x4c, 0x02, 0x8a, 0x00, 0x5a, 0x50, + 0x71, 0x48, 0x04, 0xa4, 0xa1, 0x00, 0x94, 0x53, 0x01, 0x28, 0xa4, 0x31, + 0x71, 0x4b, 0x40, 0x84, 0xa2, 0x80, 0x16, 0x92, 0x81, 0x8b, 0x45, 0x00, + 0x7b, 0x21, 0x95, 0x6d, 0x6d, 0x4f, 0xef, 0xdb, 0x71, 0xfe, 0xe8, 0xcd, + 0x67, 0x89, 0x36, 0xee, 0x90, 0xa0, 0x63, 0xfe, 0xd0, 0xae, 0xd5, 0xb1, + 0xc2, 0xf7, 0x18, 0x21, 0xf3, 0xff, 0x00, 0x78, 0xff, 0x00, 0x28, 0xac, + 0xdd, 0x4a, 0x68, 0xc1, 0xf2, 0xd7, 0xa7, 0x7a, 0xd1, 0x77, 0x24, 0xe7, + 0xa6, 0x79, 0x2e, 0xa6, 0x58, 0xd4, 0x63, 0xb5, 0x6c, 0xac, 0x5e, 0x45, + 0xb8, 0x8d, 0x7f, 0x8b, 0x9a, 0xc1, 0xeb, 0x23, 0x7d, 0x90, 0xad, 0xf2, + 0xad, 0x51, 0x99, 0xb9, 0xab, 0xe8, 0x40, 0x96, 0x89, 0xe6, 0x5c, 0x2a, + 0xfa, 0xff, 0x00, 0x85, 0x7a, 0xa5, 0xa2, 0x85, 0xb6, 0x8f, 0x1f, 0xdd, + 0x15, 0xc5, 0x53, 0xe3, 0x3b, 0x23, 0xa4, 0x09, 0xa8, 0xa0, 0x02, 0x8a, + 0x68, 0x97, 0x23, 0x9f, 0xd5, 0x35, 0x19, 0x61, 0xb8, 0x3b, 0x1f, 0x8d, + 0xa2, 0xa1, 0xb7, 0xd7, 0xca, 0x47, 0xfb, 0xce, 0xbe, 0xb5, 0xa5, 0x58, + 0x76, 0x22, 0x9b, 0xb9, 0xb7, 0x65, 0x7c, 0x97, 0x5d, 0x2a, 0xdd, 0x63, + 0x12, 0xa6, 0xec, 0x14, 0x55, 0xd8, 0x8e, 0x70, 0xa8, 0xa6, 0x97, 0x65, + 0x52, 0x44, 0x5c, 0xe0, 0xfc, 0x65, 0x37, 0x9d, 0x8e, 0x7b, 0x7f, 0x4a, + 0xe5, 0x54, 0x73, 0x46, 0x21, 0x9d, 0x18, 0x75, 0xa1, 0x76, 0xde, 0x12, + 0x71, 0x5a, 0x1b, 0x76, 0x47, 0xbb, 0xd2, 0xb8, 0xba, 0x9d, 0x4f, 0x63, + 0x9c, 0xb9, 0x25, 0xe4, 0x63, 0xf8, 0x54, 0x41, 0x71, 0x5d, 0x27, 0x30, + 0xe3, 0x49, 0x8a, 0x60, 0x39, 0x54, 0x9a, 0x64, 0xa3, 0x14, 0x80, 0x84, + 0xd2, 0x50, 0x00, 0x45, 0x25, 0x30, 0x12, 0x92, 0x80, 0x0a, 0x6e, 0x28, + 0x01, 0x71, 0x4b, 0x49, 0x80, 0x94, 0x94, 0xc0, 0x4a, 0x28, 0x00, 0xa2, + 0x80, 0x16, 0x8a, 0x40, 0x25, 0x48, 0xb4, 0x00, 0xfa, 0x7a, 0xd0, 0x22, + 0x5e, 0xd4, 0x84, 0xd0, 0x22, 0x07, 0x7a, 0x8b, 0x75, 0x03, 0x24, 0x32, + 0x7c, 0xb5, 0x1e, 0x6a, 0x80, 0x28, 0xa4, 0x20, 0xa4, 0x34, 0x86, 0x28, + 0xa7, 0x50, 0x31, 0x73, 0x46, 0x4d, 0x02, 0x12, 0x93, 0x34, 0x0c, 0x6e, + 0xea, 0x4a, 0x04, 0x25, 0x2d, 0x00, 0x25, 0x2d, 0x00, 0x14, 0x50, 0x01, + 0x45, 0x03, 0x0a, 0x28, 0xb8, 0x82, 0x8a, 0x00, 0x28, 0xa0, 0x02, 0x8a, + 0x00, 0x31, 0x45, 0x03, 0x12, 0x8a, 0x40, 0x19, 0xa2, 0x98, 0x0b, 0x8a, + 0x28, 0x00, 0x34, 0xda, 0x40, 0x2d, 0x3a, 0x98, 0x1e, 0x96, 0x24, 0x59, + 0x64, 0xc8, 0x00, 0x53, 0xb2, 0xd7, 0x12, 0x88, 0xb2, 0xc5, 0x6b, 0xae, + 0xe7, 0x1d, 0x8b, 0xd7, 0xf2, 0xc1, 0x67, 0x60, 0x71, 0x0f, 0xcf, 0x8f, + 0xa7, 0xa5, 0x72, 0x3a, 0x8b, 0x95, 0x89, 0xd8, 0x9f, 0xbd, 0x9c, 0x7f, + 0x3a, 0xe9, 0xda, 0x3a, 0x99, 0xad, 0x58, 0xed, 0x12, 0xcf, 0x6e, 0x6e, + 0x25, 0xcf, 0xe3, 0xf5, 0xab, 0xf8, 0xdc, 0xfb, 0x9b, 0xb5, 0x72, 0x47, + 0xb9, 0xb4, 0xf7, 0xb1, 0x5e, 0x73, 0x54, 0x1f, 0xad, 0x6a, 0x4a, 0x35, + 0x34, 0x5d, 0x26, 0xe6, 0x6b, 0x85, 0x75, 0x4c, 0x00, 0x7e, 0x95, 0xe8, + 0x56, 0xea, 0xc9, 0x0a, 0x86, 0xeb, 0x8a, 0xe4, 0x94, 0x57, 0x35, 0xcd, + 0xa5, 0x2f, 0x76, 0xc4, 0xb4, 0x52, 0x64, 0xab, 0xb0, 0xa2, 0xae, 0x2e, + 0xc4, 0x33, 0x3a, 0x6d, 0x26, 0x39, 0x5f, 0x24, 0x0a, 0x60, 0xd1, 0x21, + 0xf4, 0x5a, 0xd9, 0xd4, 0x44, 0xab, 0x96, 0xed, 0x6c, 0xa3, 0xb6, 0xfb, + 0xa2, 0xac, 0xd7, 0x39, 0xa8, 0x51, 0x4a, 0xe0, 0xe2, 0x15, 0x95, 0xaf, + 0x5e, 0x0b, 0x5b, 0x5e, 0x3e, 0xf1, 0xcd, 0x6b, 0x4f, 0x52, 0x5a, 0x3c, + 0xff, 0x00, 0x58, 0x94, 0xcd, 0xd7, 0xde, 0xaa, 0xd9, 0xc1, 0xe6, 0x3d, + 0x72, 0xd7, 0x91, 0xdf, 0x41, 0x58, 0xd8, 0x8a, 0x0d, 0xa3, 0x1d, 0xaa, + 0x3d, 0x43, 0xf7, 0x76, 0x52, 0x63, 0xd2, 0xb1, 0x86, 0xe5, 0xcf, 0x63, + 0x98, 0xea, 0xc7, 0xeb, 0x46, 0x2b, 0xa4, 0xe7, 0x1d, 0xe5, 0x9a, 0xb1, + 0x1c, 0x23, 0x14, 0x00, 0x93, 0x62, 0x35, 0xcd, 0x67, 0x31, 0xdc, 0x68, + 0x10, 0xca, 0x28, 0x18, 0xec, 0x52, 0x53, 0x01, 0xb4, 0xde, 0xf4, 0x00, + 0xb4, 0x50, 0x02, 0x52, 0x66, 0x80, 0x12, 0x92, 0x90, 0x09, 0x45, 0x3b, + 0x00, 0xb4, 0x52, 0x00, 0xa5, 0xa0, 0x02, 0x9c, 0xb4, 0x00, 0xfa, 0x5d, + 0xf4, 0x08, 0x53, 0x25, 0x44, 0x58, 0xd0, 0x31, 0xa4, 0xd3, 0x68, 0x10, + 0xea, 0x28, 0x18, 0xb4, 0x50, 0x20, 0xa3, 0x19, 0xa0, 0x03, 0x14, 0xb4, + 0x0c, 0x28, 0xcd, 0x02, 0x1a, 0x4d, 0x36, 0x80, 0x0a, 0x5a, 0x00, 0x28, + 0xa0, 0x61, 0x45, 0x00, 0x2d, 0x25, 0x02, 0x0a, 0x28, 0x00, 0xa5, 0xa0, + 0x04, 0xa2, 0x80, 0x0a, 0x28, 0x18, 0x51, 0x40, 0x0b, 0x49, 0x40, 0x84, + 0xa3, 0x14, 0x0c, 0x5c, 0x52, 0xe2, 0x90, 0x0b, 0x4d, 0xcd, 0x00, 0x18, + 0xa5, 0xa6, 0x01, 0x4b, 0x48, 0x0f, 0x44, 0xf2, 0x64, 0xd9, 0xc7, 0x5a, + 0xe9, 0x34, 0x5b, 0x3f, 0xb3, 0x43, 0xbc, 0xc4, 0xa1, 0xbd, 0x6b, 0xb3, + 0x94, 0xe3, 0x7b, 0x18, 0x3a, 0xf5, 0xf1, 0xba, 0xbf, 0x11, 0x3b, 0x7c, + 0x91, 0xe0, 0xe3, 0x3c, 0x77, 0x15, 0xce, 0xed, 0x3a, 0xa6, 0xa4, 0xb1, + 0xff, 0x00, 0xcb, 0x35, 0xc6, 0x7f, 0x51, 0x5b, 0xd5, 0x76, 0x22, 0x8a, + 0x37, 0x24, 0x5d, 0x91, 0xac, 0x2b, 0xe9, 0xcf, 0xe5, 0x50, 0xc9, 0xf2, + 0x8c, 0x56, 0x51, 0x2a, 0xe5, 0x19, 0x89, 0x26, 0xb4, 0xb4, 0x2d, 0x14, + 0xdf, 0x4f, 0x97, 0xfb, 0x83, 0xad, 0x4d, 0x49, 0x58, 0xb8, 0x23, 0xb9, + 0xb6, 0xb6, 0x8e, 0xda, 0x30, 0xb1, 0x8c, 0x54, 0xd5, 0xcb, 0x73, 0x5b, + 0x20, 0xa2, 0x91, 0xa8, 0x51, 0x4c, 0xc6, 0xde, 0xf0, 0x51, 0x48, 0xa6, + 0x14, 0x50, 0x48, 0x51, 0x4d, 0x0a, 0x4c, 0x09, 0xc7, 0x5a, 0xe1, 0x7c, + 0x47, 0x7e, 0x25, 0xb8, 0x66, 0x63, 0xf2, 0xa5, 0x6d, 0x0d, 0x9b, 0x17, + 0xda, 0x39, 0x67, 0x90, 0xca, 0xd9, 0x35, 0xa3, 0xa6, 0xc7, 0x83, 0x93, + 0xd6, 0xbc, 0xfa, 0x8e, 0xe7, 0xa3, 0x4c, 0xd2, 0xaa, 0x9a, 0xaf, 0xfc, + 0x78, 0xc9, 0xfe, 0xed, 0x10, 0xdc, 0x55, 0x36, 0x30, 0x12, 0x1c, 0xf5, + 0xf5, 0xa9, 0x44, 0x38, 0xed, 0x5d, 0x27, 0x28, 0xae, 0x94, 0xcd, 0xdb, + 0x68, 0x02, 0x9d, 0xc4, 0x9b, 0xb8, 0xaa, 0xf5, 0x43, 0x10, 0xd1, 0x48, + 0x63, 0xa9, 0x28, 0x10, 0xda, 0x4a, 0x06, 0x25, 0x36, 0x81, 0x09, 0x49, + 0x40, 0x09, 0x45, 0x03, 0x0a, 0x28, 0x00, 0xa2, 0x80, 0x16, 0x8a, 0x00, + 0x29, 0x73, 0x40, 0x06, 0x68, 0xcd, 0x00, 0x19, 0xa4, 0xcd, 0x20, 0x1b, + 0x45, 0x00, 0x3a, 0x96, 0x98, 0x05, 0x14, 0x84, 0x2d, 0x14, 0xc0, 0x5a, + 0x4a, 0x40, 0x14, 0x94, 0x00, 0x94, 0x50, 0xc0, 0x28, 0xa0, 0x05, 0xa2, + 0x85, 0xa0, 0x09, 0x45, 0x31, 0x85, 0x14, 0x84, 0x2d, 0x25, 0x03, 0x16, + 0x92, 0x81, 0x05, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, 0x0c, 0x28, 0xa0, + 0x42, 0xe2, 0x97, 0x14, 0x00, 0x62, 0x8a, 0x06, 0x25, 0x18, 0xa4, 0x01, + 0x4b, 0x40, 0x09, 0x49, 0x4c, 0x0f, 0x5d, 0xd3, 0x20, 0xdf, 0x74, 0x1b, + 0x83, 0x8a, 0xb7, 0xe2, 0x09, 0xe7, 0x8a, 0xcc, 0xc7, 0x13, 0xfc, 0xe4, + 0x11, 0x5e, 0x85, 0x1b, 0x4e, 0x57, 0x3c, 0xf9, 0xbb, 0x1c, 0x66, 0xa9, + 0x17, 0xd9, 0xed, 0x0a, 0xc4, 0x4e, 0xe9, 0x37, 0x67, 0xb7, 0xbd, 0x5c, + 0xd1, 0xad, 0x92, 0xda, 0xd8, 0xc9, 0x8d, 0xce, 0x7f, 0xc6, 0xa6, 0xa6, + 0xeb, 0xcc, 0xda, 0x1b, 0x32, 0xc6, 0x3b, 0xd5, 0x59, 0xcd, 0x04, 0x0d, + 0xb3, 0xb4, 0xfb, 0x5c, 0xe1, 0x7b, 0x1a, 0xef, 0xac, 0xad, 0x92, 0xd6, + 0x00, 0x88, 0x31, 0x5c, 0x95, 0x25, 0x79, 0x58, 0xe9, 0x8a, 0xb4, 0x6e, + 0x58, 0xa2, 0x95, 0x8c, 0x79, 0xb5, 0x0a, 0x46, 0x6d, 0xbd, 0x68, 0x51, + 0xb9, 0xb3, 0x95, 0x88, 0xd6, 0x75, 0x67, 0xda, 0x2a, 0x5a, 0x97, 0xd8, + 0x22, 0x14, 0x50, 0x50, 0x51, 0x54, 0x61, 0xd4, 0x28, 0xa6, 0xc4, 0x51, + 0xd5, 0xe7, 0x30, 0xd9, 0x3e, 0xdf, 0xbc, 0x47, 0x15, 0xe6, 0x9a, 0xbc, + 0xcc, 0xf2, 0xb0, 0xec, 0x4f, 0xf3, 0xad, 0x5c, 0x5a, 0xa6, 0x55, 0x2d, + 0x66, 0x56, 0xb6, 0x8f, 0x27, 0x15, 0xbb, 0x6d, 0x1e, 0xd5, 0xaf, 0x36, + 0x47, 0xa6, 0x4f, 0x55, 0xaf, 0xd3, 0x7d, 0xbb, 0x0f, 0x6a, 0xa8, 0x6e, + 0x44, 0xf6, 0x32, 0x02, 0xe3, 0x8a, 0x5c, 0x56, 0xec, 0xe6, 0x17, 0x65, + 0x50, 0xba, 0x3c, 0xd5, 0x22, 0x4a, 0x4f, 0x4d, 0xa1, 0x94, 0x21, 0xa0, + 0x52, 0x63, 0x1d, 0x4d, 0x34, 0xc4, 0x30, 0x9a, 0x6d, 0x03, 0x12, 0x9b, + 0x4c, 0x02, 0x8a, 0x40, 0x14, 0x50, 0x02, 0x51, 0x4c, 0x02, 0x8a, 0x40, + 0x2d, 0x14, 0x80, 0x28, 0xa0, 0x41, 0x49, 0x4c, 0x61, 0x49, 0x48, 0x02, + 0x8a, 0x60, 0x2d, 0x3a, 0x80, 0x0a, 0x54, 0xeb, 0x43, 0x10, 0xa6, 0x92, + 0x90, 0x0b, 0x45, 0x17, 0x18, 0xda, 0x4a, 0x04, 0x28, 0xe6, 0x96, 0x9b, + 0x01, 0x08, 0xa2, 0x90, 0x05, 0x14, 0x00, 0x51, 0x40, 0x05, 0x14, 0x00, + 0x52, 0x50, 0x02, 0xd2, 0x50, 0x01, 0x4b, 0x40, 0x05, 0x25, 0x00, 0x14, + 0x50, 0x01, 0x4b, 0x40, 0xc5, 0x14, 0xa6, 0x90, 0x09, 0x45, 0x0c, 0x04, + 0xcd, 0x2d, 0x00, 0x25, 0x26, 0x69, 0x80, 0x94, 0x50, 0x07, 0xff, 0xd9, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xca, 0x0c, 0x57, 0x6d, 0x24, 0x63, 0x36, 0x61, 0x5f, 0x2f, 0x06, 0x9f, + 0xa4, 0x9d, 0xac, 0x3e, 0xb5, 0x85, 0x72, 0xe0, 0x6e, 0xff, 0x00, 0x0d, + 0x53, 0xb9, 0xe9, 0x5a, 0x47, 0x63, 0x03, 0x9a, 0xd5, 0x97, 0xe5, 0x35, + 0x92, 0x05, 0x61, 0x58, 0xea, 0xa4, 0x4a, 0x07, 0x14, 0x6d, 0xac, 0x6e, + 0x6c, 0x58, 0x89, 0x2b, 0x42, 0xc9, 0x8c, 0x2c, 0x0d, 0x48, 0x8e, 0x8a, + 0xd6, 0xf5, 0xd8, 0x63, 0x15, 0x6a, 0x49, 0x5f, 0x67, 0x35, 0xd7, 0x44, + 0xe4, 0xa8, 0x88, 0xa3, 0xe7, 0x9a, 0x94, 0xa1, 0x61, 0x5a, 0x90, 0x2a, + 0xc7, 0x4b, 0xe5, 0x1a, 0x00, 0xb1, 0x18, 0xe2, 0xab, 0x5e, 0x48, 0x10, + 0xf5, 0xa9, 0xe8, 0x3e, 0xa4, 0xe6, 0x40, 0x91, 0x02, 0x6a, 0x8c, 0xb3, + 0xb3, 0xf0, 0x2a, 0x53, 0xd0, 0x2d, 0xa8, 0xc4, 0x88, 0x9a, 0x71, 0x01, + 0x28, 0x28, 0xad, 0x71, 0x20, 0x11, 0x92, 0x4f, 0x15, 0xce, 0x5d, 0xeb, + 0x1b, 0x64, 0x29, 0x6e, 0xb9, 0x6f, 0x5e, 0x69, 0xda, 0xe8, 0x16, 0xe4, + 0x3e, 0x75, 0xd4, 0xa3, 0xe6, 0x7d, 0xbf, 0x4a, 0xcf, 0x9a, 0x36, 0x2f, + 0x86, 0xf9, 0xab, 0x16, 0xf4, 0x3a, 0x61, 0xb8, 0xe8, 0xe0, 0xa7, 0xb5, + 0xaa, 0x3f, 0x51, 0x5c, 0xfc, 0xc7, 0x43, 0x44, 0x2f, 0x60, 0x3f, 0x87, + 0x8a, 0xaa, 0xd0, 0xcb, 0x09, 0xc8, 0xab, 0xbd, 0xcc, 0xb6, 0x2c, 0x45, + 0xad, 0xcd, 0x0a, 0xe3, 0x15, 0x32, 0xea, 0x9e, 0x67, 0x2f, 0xf3, 0x7e, + 0x15, 0xbe, 0x1f, 0xdd, 0x67, 0x3e, 0x23, 0xde, 0x1e, 0x2f, 0x15, 0xbb, + 0x55, 0x1b, 0xac, 0xc9, 0x27, 0x02, 0xbd, 0x27, 0x56, 0xd1, 0x39, 0x29, + 0xd1, 0x7c, 0xe4, 0xb6, 0xf1, 0x95, 0x15, 0xa1, 0x08, 0xe2, 0xbc, 0x26, + 0xee, 0xcf, 0x63, 0xa1, 0x3e, 0xda, 0x6e, 0x70, 0x6a, 0xcc, 0xc8, 0x9d, + 0xe9, 0x9b, 0x8d, 0x4b, 0x65, 0x20, 0xce, 0x7a, 0xd2, 0x56, 0x77, 0x2a, + 0xc4, 0x52, 0x4c, 0xa9, 0x54, 0x9e, 0xf7, 0xde, 0xa9, 0x08, 0xa9, 0x2d, + 0xd7, 0xbd, 0x55, 0x92, 0xe8, 0x76, 0x35, 0xa2, 0x44, 0x39, 0x95, 0xda, + 0xe0, 0xd4, 0x65, 0x8d, 0x6c, 0x62, 0xdd, 0xc6, 0xd2, 0x53, 0xd8, 0x44, + 0xb1, 0x1c, 0x35, 0x5b, 0xed, 0x48, 0x06, 0x1a, 0x61, 0xa0, 0x06, 0xd1, + 0x40, 0x05, 0x34, 0x8c, 0xd0, 0x98, 0x06, 0xce, 0x2a, 0x13, 0x4c, 0x42, + 0x53, 0xc5, 0x21, 0x85, 0x34, 0xd0, 0x03, 0x69, 0x76, 0xd3, 0x01, 0xd8, + 0xa5, 0xc5, 0x4d, 0xc0, 0x5a, 0x4a, 0x2e, 0x01, 0x51, 0x9a, 0x60, 0x14, + 0xe1, 0x40, 0x0b, 0x49, 0x40, 0x21, 0x45, 0x5a, 0x4f, 0xbb, 0x43, 0x01, + 0xc6, 0xa6, 0x5a, 0x46, 0x42, 0x5c, 0x7d, 0xca, 0xcb, 0x3d, 0x69, 0x95, + 0x11, 0xc9, 0x4b, 0x41, 0x63, 0xe9, 0xc2, 0x90, 0x08, 0xd4, 0xca, 0x60, + 0x14, 0xea, 0x40, 0x44, 0xdd, 0x69, 0x29, 0x88, 0x5a, 0x5a, 0x00, 0x43, + 0x4d, 0xa0, 0x07, 0xad, 0x4b, 0x48, 0x67, 0xb7, 0x5a, 0xbe, 0x56, 0xa6, + 0x95, 0x32, 0xb5, 0xdf, 0x48, 0xe5, 0x9e, 0xe6, 0x05, 0xf2, 0xf5, 0xa8, + 0x6c, 0xfe, 0x59, 0x45, 0x73, 0xe2, 0x0d, 0xe0, 0x6f, 0xaf, 0x31, 0xd5, + 0x4b, 0xa2, 0x00, 0xeb, 0x4e, 0x1b, 0x18, 0xbd, 0xce, 0x57, 0x55, 0x9f, + 0xcc, 0x7d, 0x8b, 0x8a, 0xa8, 0x13, 0x8a, 0xe7, 0xab, 0xbd, 0x8e, 0xba, + 0x6b, 0x41, 0xe1, 0x69, 0xe1, 0x6b, 0x13, 0x42, 0x78, 0xd6, 0xb4, 0x21, + 0xd9, 0x8c, 0x1a, 0x48, 0x4c, 0xe8, 0x34, 0xf1, 0x0e, 0x06, 0xdc, 0x66, + 0xa5, 0xd4, 0x1f, 0x11, 0x7e, 0x75, 0xdb, 0x40, 0xe2, 0xaa, 0x25, 0x9a, + 0xe6, 0x3e, 0x7a, 0xf5, 0xa7, 0xca, 0xf8, 0x38, 0x15, 0x51, 0xd8, 0x19, + 0x24, 0x3e, 0xf5, 0x2e, 0xe1, 0x4e, 0x22, 0x64, 0x12, 0x5d, 0xaa, 0x1e, + 0x39, 0xac, 0x6b, 0xb8, 0xe6, 0x9e, 0xe0, 0x49, 0x9f, 0x97, 0xd2, 0xa8, + 0x16, 0xe5, 0xed, 0xcc, 0xca, 0x01, 0xa9, 0x62, 0x41, 0x58, 0x24, 0x5b, + 0x1f, 0x2b, 0x88, 0xd6, 0xb2, 0xef, 0x6e, 0xf0, 0x33, 0x9e, 0x2b, 0x5b, + 0x12, 0x61, 0xde, 0xde, 0x3d, 0xc2, 0xec, 0x07, 0x09, 0x54, 0xbe, 0x44, + 0xe8, 0x2b, 0x29, 0xcb, 0x4b, 0x1b, 0xc2, 0x02, 0xf9, 0x84, 0xd2, 0x6c, + 0xe7, 0x26, 0xb9, 0x9b, 0x3b, 0x23, 0x0b, 0x12, 0x62, 0x93, 0x15, 0x98, + 0x0e, 0x02, 0x92, 0x48, 0xb3, 0x40, 0x14, 0xe5, 0xb2, 0x57, 0xed, 0x51, + 0xa6, 0x9f, 0xb5, 0x86, 0x0d, 0x5a, 0x9d, 0x8c, 0xdc, 0x0b, 0x69, 0x66, + 0x3a, 0x9a, 0x77, 0xd9, 0xd5, 0x7a, 0x01, 0x57, 0xcf, 0x70, 0xb5, 0x88, + 0x98, 0x73, 0x52, 0xc6, 0xd8, 0xac, 0xca, 0x25, 0x2f, 0xc5, 0x46, 0x69, + 0x89, 0x22, 0x36, 0x34, 0xcd, 0xe2, 0xb2, 0x65, 0x91, 0xbc, 0xc0, 0x55, + 0x29, 0x2f, 0x87, 0xaf, 0xeb, 0x4e, 0x31, 0x0b, 0xd8, 0xcd, 0x9a, 0xfb, + 0x7d, 0x55, 0x7b, 0x86, 0x35, 0xd1, 0x18, 0x9c, 0xf2, 0x99, 0x11, 0x62, + 0x69, 0xb5, 0x64, 0x06, 0x29, 0x69, 0xd8, 0x04, 0xa5, 0xa0, 0x05, 0x1d, + 0x6a, 0xe2, 0x1c, 0xad, 0x20, 0x03, 0x4d, 0x34, 0x00, 0xca, 0x4a, 0x00, + 0x4a, 0x5a, 0x40, 0x3a, 0xaa, 0xbf, 0xde, 0xa6, 0x21, 0x2a, 0x41, 0x40, + 0xc7, 0x53, 0x48, 0xa0, 0x04, 0xdb, 0x4b, 0x48, 0x05, 0xa4, 0xa0, 0x02, + 0x8a, 0x00, 0x6d, 0x30, 0xd3, 0x00, 0xa7, 0x2d, 0x00, 0x3f, 0x14, 0xca, + 0x00, 0x72, 0x75, 0xab, 0x29, 0x40, 0x31, 0x5a, 0xa7, 0x4a, 0x46, 0x63, + 0x2e, 0x7e, 0xe5, 0x66, 0x9a, 0x63, 0x88, 0xe5, 0xa5, 0xa0, 0xb1, 0x69, + 0x73, 0x45, 0x80, 0x09, 0xa6, 0xd2, 0x01, 0x69, 0xd4, 0x01, 0x13, 0x75, + 0xa2, 0x98, 0x83, 0x14, 0x0a, 0x40, 0x3a, 0x9a, 0x45, 0x30, 0x05, 0xeb, + 0x52, 0xd2, 0xea, 0x33, 0xdb, 0x2c, 0x4f, 0xc9, 0x56, 0xa4, 0x6f, 0x96, + 0xbb, 0x68, 0xec, 0x73, 0x54, 0x31, 0x75, 0x05 +}; +unsigned int capture_jpg_len = 24800; + + +unsigned const char octo_jpg[] = { + 0xff, 0xd8, 0xff, 0xe0, 0x00, 0x10, 0x4a, 0x46, 0x49, 0x46, 0x00, 0x01, + 0x01, 0x01, 0x00, 0x48, 0x00, 0x48, 0x00, 0x00, 0xff, 0xdb, 0x00, 0x43, + 0x00, 0x11, 0x0b, 0x0c, 0x0f, 0x0c, 0x0a, 0x11, 0x0f, 0x0e, 0x0f, 0x13, + 0x12, 0x11, 0x14, 0x19, 0x2a, 0x1b, 0x19, 0x17, 0x17, 0x19, 0x33, 0x24, + 0x26, 0x1e, 0x2a, 0x3c, 0x35, 0x3f, 0x3e, 0x3b, 0x35, 0x3a, 0x39, 0x43, + 0x4b, 0x60, 0x51, 0x43, 0x47, 0x5a, 0x48, 0x39, 0x3a, 0x53, 0x71, 0x54, + 0x5a, 0x63, 0x66, 0x6b, 0x6c, 0x6b, 0x40, 0x50, 0x76, 0x7e, 0x74, 0x68, + 0x7d, 0x60, 0x69, 0x6b, 0x67, 0xff, 0xdb, 0x00, 0x43, 0x01, 0x12, 0x13, + 0x13, 0x19, 0x16, 0x19, 0x31, 0x1b, 0x1b, 0x31, 0x67, 0x45, 0x3a, 0x45, + 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, + 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, + 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, + 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, 0x67, + 0x67, 0x67, 0xff, 0xc0, 0x00, 0x11, 0x08, 0x01, 0xe0, 0x02, 0x80, 0x03, + 0x01, 0x22, 0x00, 0x02, 0x11, 0x01, 0x03, 0x11, 0x01, 0xff, 0xc4, 0x00, + 0x1f, 0x00, 0x00, 0x01, 0x05, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x10, 0x00, + 0x02, 0x01, 0x03, 0x03, 0x02, 0x04, 0x03, 0x05, 0x05, 0x04, 0x04, 0x00, + 0x00, 0x01, 0x7d, 0x01, 0x02, 0x03, 0x00, 0x04, 0x11, 0x05, 0x12, 0x21, + 0x31, 0x41, 0x06, 0x13, 0x51, 0x61, 0x07, 0x22, 0x71, 0x14, 0x32, 0x81, + 0x91, 0xa1, 0x08, 0x23, 0x42, 0xb1, 0xc1, 0x15, 0x52, 0xd1, 0xf0, 0x24, + 0x33, 0x62, 0x72, 0x82, 0x09, 0x0a, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x25, + 0x26, 0x27, 0x28, 0x29, 0x2a, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, + 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, 0x56, + 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6a, + 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x83, 0x84, 0x85, 0x86, + 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, + 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, 0xb2, 0xb3, + 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, + 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, 0xd8, 0xd9, + 0xda, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, 0xf1, + 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xc4, 0x00, + 0x1f, 0x01, 0x00, 0x03, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, + 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0xff, 0xc4, 0x00, 0xb5, 0x11, 0x00, + 0x02, 0x01, 0x02, 0x04, 0x04, 0x03, 0x04, 0x07, 0x05, 0x04, 0x04, 0x00, + 0x01, 0x02, 0x77, 0x00, 0x01, 0x02, 0x03, 0x11, 0x04, 0x05, 0x21, 0x31, + 0x06, 0x12, 0x41, 0x51, 0x07, 0x61, 0x71, 0x13, 0x22, 0x32, 0x81, 0x08, + 0x14, 0x42, 0x91, 0xa1, 0xb1, 0xc1, 0x09, 0x23, 0x33, 0x52, 0xf0, 0x15, + 0x62, 0x72, 0xd1, 0x0a, 0x16, 0x24, 0x34, 0xe1, 0x25, 0xf1, 0x17, 0x18, + 0x19, 0x1a, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x35, 0x36, 0x37, 0x38, 0x39, + 0x3a, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4a, 0x53, 0x54, 0x55, + 0x56, 0x57, 0x58, 0x59, 0x5a, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, + 0x6a, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7a, 0x82, 0x83, 0x84, + 0x85, 0x86, 0x87, 0x88, 0x89, 0x8a, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, + 0x98, 0x99, 0x9a, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xa8, 0xa9, 0xaa, + 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7, 0xb8, 0xb9, 0xba, 0xc2, 0xc3, 0xc4, + 0xc5, 0xc6, 0xc7, 0xc8, 0xc9, 0xca, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7, + 0xd8, 0xd9, 0xda, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7, 0xe8, 0xe9, 0xea, + 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7, 0xf8, 0xf9, 0xfa, 0xff, 0xda, 0x00, + 0x0c, 0x03, 0x01, 0x00, 0x02, 0x11, 0x03, 0x11, 0x00, 0x3f, 0x00, 0xef, + 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, + 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, + 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, + 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa4, 0xa5, 0xa0, + 0x02, 0x8a, 0x4a, 0x5a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, + 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, + 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, + 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, + 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa4, 0xa5, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x92, 0x96, + 0xab, 0xdd, 0x4e, 0x96, 0xb6, 0xd2, 0xcc, 0xe7, 0x09, 0x1a, 0x96, 0x3f, + 0x80, 0xa0, 0x09, 0x8b, 0x28, 0xea, 0xc0, 0x7e, 0x34, 0x07, 0x53, 0xd1, + 0x81, 0xfc, 0x6b, 0xc8, 0xaf, 0x6f, 0xe7, 0xbd, 0xbb, 0x96, 0x69, 0x25, + 0x7c, 0xbb, 0x13, 0x80, 0xc7, 0x00, 0x54, 0x71, 0xdd, 0x4f, 0x19, 0xf9, + 0x27, 0x95, 0x48, 0xfe, 0xeb, 0x1a, 0x00, 0xf6, 0x2a, 0x2b, 0xcb, 0x6d, + 0x7c, 0x4b, 0xaa, 0xda, 0x91, 0xb2, 0xed, 0xdd, 0x47, 0xf0, 0xc9, 0xf3, + 0x56, 0xdd, 0x87, 0x8f, 0x5c, 0x61, 0x6f, 0xad, 0x81, 0x1f, 0xdf, 0x88, + 0xff, 0x00, 0x43, 0x40, 0x1d, 0xbd, 0x15, 0x99, 0xa7, 0xeb, 0xda, 0x7e, + 0xa1, 0x81, 0x05, 0xc2, 0xee, 0x3f, 0xc0, 0xdc, 0x1a, 0xd3, 0x1d, 0x28, + 0x01, 0x68, 0xa4, 0xa2, 0x80, 0x16, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x29, 0x28, 0x01, 0x69, 0x28, 0xcd, 0x21, 0x3c, 0xf3, + 0xd2, 0x80, 0x16, 0x8a, 0xca, 0xd4, 0x7c, 0x45, 0xa7, 0x69, 0xc0, 0xf9, + 0xd3, 0x86, 0x71, 0xfc, 0x09, 0xc9, 0xae, 0x6e, 0xfb, 0xc7, 0x93, 0x3e, + 0x56, 0xca, 0xdd, 0x50, 0x76, 0x79, 0x39, 0xfd, 0x28, 0x03, 0xb9, 0xa4, + 0x2e, 0xa3, 0xab, 0x01, 0xf8, 0xd7, 0x96, 0x5d, 0x78, 0x8b, 0x55, 0xba, + 0x24, 0xbd, 0xe4, 0x8b, 0xec, 0x9f, 0x28, 0xfd, 0x2a, 0x8b, 0xdc, 0xcf, + 0x26, 0x4b, 0xcf, 0x23, 0x7d, 0x5c, 0xd0, 0x07, 0xb0, 0x87, 0x53, 0xd1, + 0x81, 0xfc, 0x69, 0x6b, 0xc9, 0xb4, 0x9d, 0x46, 0x5b, 0x1d, 0x42, 0x19, + 0xbc, 0xd6, 0xda, 0x8c, 0x0b, 0x02, 0xc7, 0x91, 0xde, 0xbd, 0x5a, 0x36, + 0x57, 0x45, 0x74, 0x39, 0x56, 0x00, 0x83, 0xed, 0x40, 0x12, 0x51, 0x45, + 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, + 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, + 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, + 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, + 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, + 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, + 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, + 0x14, 0x00, 0x57, 0x3b, 0xe3, 0x8b, 0xcf, 0xb3, 0x68, 0x4d, 0x18, 0x3f, + 0x34, 0xec, 0x13, 0xf0, 0xea, 0x7f, 0x95, 0x74, 0x55, 0xc2, 0x7c, 0x44, + 0xb8, 0xdf, 0x77, 0x6d, 0x00, 0x3c, 0x22, 0x17, 0x23, 0xdc, 0x9c, 0x7f, + 0x4a, 0x00, 0xe4, 0xa8, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x5c, + 0xed, 0x3b, 0x81, 0x23, 0xdc, 0x75, 0xfc, 0xeb, 0x6f, 0x4a, 0xf1, 0x5e, + 0xa1, 0xa7, 0xe1, 0x1d, 0xfe, 0xd1, 0x10, 0xe8, 0x92, 0x76, 0xfa, 0x1e, + 0xb5, 0x86, 0x28, 0xa0, 0x0f, 0x4d, 0xd2, 0x7c, 0x4f, 0x61, 0xa9, 0xe1, + 0x44, 0x9e, 0x4c, 0xa7, 0xfe, 0x59, 0xc8, 0x70, 0x7f, 0x0f, 0x5a, 0xda, + 0x06, 0xbc, 0x64, 0x70, 0x72, 0x38, 0x3e, 0xbf, 0xfd, 0x7f, 0x5a, 0xde, + 0xd1, 0xfc, 0x5b, 0x79, 0x60, 0x56, 0x2b, 0x82, 0x6e, 0x60, 0xe9, 0x86, + 0x3f, 0x3a, 0x8f, 0x63, 0xfe, 0x7f, 0x0a, 0x00, 0xf4, 0x8a, 0x2a, 0x86, + 0x99, 0xaa, 0xda, 0x6a, 0x91, 0x6f, 0xb6, 0x94, 0x37, 0x19, 0x28, 0x78, + 0x65, 0x3f, 0x4a, 0xba, 0x58, 0x28, 0xe4, 0x81, 0xf5, 0xa0, 0x07, 0x51, + 0x54, 0x6e, 0x75, 0x8d, 0x3e, 0xd7, 0x26, 0x6b, 0xb8, 0x57, 0x1d, 0xb7, + 0x64, 0xd6, 0x65, 0xc7, 0x8c, 0xf4, 0xa8, 0x41, 0xd9, 0x24, 0x92, 0x9f, + 0xf6, 0x13, 0xaf, 0xe7, 0x40, 0x1d, 0x0d, 0x15, 0xc6, 0xcb, 0xe3, 0xd8, + 0x97, 0x88, 0x6c, 0x9d, 0x87, 0x6d, 0xee, 0x07, 0xe8, 0x05, 0x53, 0x93, + 0xc7, 0x97, 0xcd, 0xfe, 0xae, 0xda, 0x05, 0xfa, 0x92, 0x4f, 0xf3, 0xa0, + 0x0e, 0xfa, 0x8a, 0xf3, 0x87, 0xf1, 0xae, 0xaa, 0xd9, 0xc3, 0x44, 0xa3, + 0xd0, 0x20, 0xa8, 0xdb, 0xc5, 0xfa, 0xc3, 0x1f, 0xf8, 0xf9, 0x51, 0xf4, + 0x45, 0xa0, 0x0f, 0x4b, 0xa2, 0xbc, 0xc4, 0xf8, 0xb3, 0x58, 0x3f, 0xf2, + 0xf6, 0x7f, 0xef, 0x81, 0xfe, 0x14, 0x0f, 0x16, 0x6b, 0x03, 0xfe, 0x5e, + 0xcf, 0xfd, 0xf0, 0x3f, 0xc2, 0x80, 0x3d, 0x3a, 0x8a, 0xf3, 0x35, 0xf1, + 0x7e, 0xb0, 0xbf, 0xf2, 0xf2, 0x0f, 0xd5, 0x07, 0xf8, 0x54, 0xe9, 0xe3, + 0x6d, 0x55, 0x7e, 0xf3, 0x42, 0xff, 0x00, 0xef, 0x27, 0xf8, 0x50, 0x07, + 0xa2, 0xd1, 0x5c, 0x14, 0x7e, 0x3d, 0xbc, 0x18, 0xf3, 0x2d, 0xa1, 0x71, + 0xdf, 0x04, 0x83, 0x56, 0xed, 0xfc, 0x7f, 0x0f, 0xfc, 0xb6, 0xb3, 0x95, + 0x7d, 0xd1, 0xf7, 0x7f, 0x3a, 0x00, 0xec, 0xa8, 0xac, 0x0b, 0x7f, 0x18, + 0xe9, 0x32, 0xe0, 0x34, 0xaf, 0x11, 0x3d, 0x9d, 0x3f, 0xc2, 0xb4, 0xed, + 0xb5, 0x6b, 0x1b, 0xac, 0x79, 0x37, 0x51, 0x39, 0x3d, 0x83, 0x50, 0x05, + 0xcc, 0xd2, 0x1a, 0xce, 0xd5, 0x75, 0xab, 0x3d, 0x2a, 0x1d, 0xd7, 0x12, + 0xfc, 0xc7, 0xa2, 0x29, 0xcb, 0x1a, 0xe1, 0xb5, 0x8f, 0x15, 0x5e, 0xea, + 0x5b, 0xa3, 0x8d, 0x8c, 0x10, 0x1c, 0xfc, 0x88, 0x70, 0x4f, 0xd4, 0xd0, + 0x07, 0x5b, 0xab, 0xf8, 0xae, 0xc3, 0x4d, 0xdc, 0x88, 0xc6, 0xe2, 0x61, + 0xd5, 0x23, 0x39, 0x03, 0xea, 0x6b, 0x8e, 0xd5, 0x7c, 0x4f, 0xa8, 0x6a, + 0x7f, 0x29, 0x94, 0xc1, 0x11, 0xfe, 0x08, 0xce, 0x3f, 0x33, 0x59, 0x1f, + 0xe7, 0xfc, 0xfa, 0xd2, 0x50, 0x02, 0x9e, 0xb9, 0xff, 0x00, 0xeb, 0xd2, + 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x1d, 0x47, 0xad, 0x7a, 0x67, + 0x84, 0x2f, 0x0d, 0xde, 0x83, 0x0e, 0xe3, 0x96, 0x8b, 0x28, 0xdf, 0x87, + 0x4a, 0xf3, 0x3a, 0xed, 0x7e, 0x1d, 0xdc, 0x66, 0x3b, 0xb8, 0x33, 0xc0, + 0x21, 0xc5, 0x00, 0x76, 0x74, 0x52, 0x52, 0xd0, 0x01, 0x45, 0x14, 0x50, + 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, + 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, + 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, + 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, + 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, + 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, + 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x5e, 0x6d, 0xe3, + 0x89, 0x3c, 0xcf, 0x11, 0xc8, 0xbf, 0xdc, 0x45, 0x5f, 0xd3, 0x3f, 0xd6, + 0xbd, 0x26, 0xbc, 0xbf, 0xc5, 0xc7, 0x3e, 0x26, 0xbc, 0xf6, 0x2b, 0xff, + 0x00, 0xa0, 0x8a, 0x00, 0xc7, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, + 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa3, 0xfa, 0xf5, 0xa2, 0x8a, 0x00, 0x96, + 0xde, 0xe6, 0x6b, 0x59, 0x44, 0xb0, 0x48, 0xd1, 0xc8, 0x3b, 0xa9, 0xc5, + 0x4b, 0x75, 0xaa, 0x5e, 0xdd, 0x93, 0xe7, 0x5c, 0xca, 0xd9, 0xed, 0xbb, + 0x15, 0x56, 0x8a, 0x00, 0x3b, 0xe7, 0xbf, 0xbd, 0x2d, 0x25, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0xb4, 0x98, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, + 0x00, 0x28, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x0b, 0x42, 0xf0, + 0x72, 0x32, 0x3b, 0xe4, 0x1c, 0x52, 0x51, 0x40, 0x0e, 0x67, 0x77, 0x39, + 0x76, 0x66, 0x61, 0xc0, 0x24, 0xe7, 0x02, 0x92, 0x92, 0x8a, 0x00, 0x28, + 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x2b, + 0xa5, 0xf0, 0x0c, 0xa5, 0x35, 0xd9, 0x23, 0xec, 0xf0, 0x91, 0xf9, 0x11, + 0xfe, 0x15, 0xcd, 0x56, 0xf7, 0x81, 0xff, 0x00, 0xe4, 0x64, 0x88, 0x7f, + 0xb0, 0xdf, 0xca, 0x80, 0x3d, 0x24, 0x7a, 0xd2, 0xd2, 0x0a, 0x5a, 0x00, + 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, + 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, + 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, + 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, + 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, + 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, + 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, + 0x2b, 0xcc, 0xbc, 0x67, 0x1e, 0xcf, 0x12, 0xdc, 0x13, 0xfc, 0x61, 0x48, + 0xff, 0x00, 0xbe, 0x45, 0x7a, 0x6d, 0x79, 0xf7, 0xc4, 0x08, 0x3c, 0xbd, + 0x5e, 0x19, 0x40, 0xe2, 0x58, 0x87, 0x3e, 0xe3, 0x20, 0xfe, 0x98, 0xa0, + 0x0e, 0x62, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0xba, 0x1f, 0x02, 0xa6, 0xef, 0x10, + 0x06, 0xfe, 0xe4, 0x4c, 0xc7, 0xf9, 0x7f, 0x5a, 0xe7, 0xba, 0x57, 0x5d, + 0xf0, 0xf2, 0xdf, 0x75, 0xd5, 0xd4, 0xe4, 0x70, 0xa8, 0x10, 0x1f, 0xaf, + 0xff, 0x00, 0xaa, 0x80, 0x3b, 0x91, 0x4b, 0x49, 0x4b, 0x40, 0x05, 0x14, + 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, + 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, + 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, + 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, + 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, + 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, + 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x72, + 0xfe, 0x3d, 0xb3, 0xf3, 0xf4, 0xa4, 0xb8, 0x51, 0xf3, 0x40, 0xfc, 0xfd, + 0x0f, 0x1f, 0xcf, 0x15, 0xd3, 0xd7, 0x17, 0xe3, 0x2f, 0x10, 0x8d, 0xaf, + 0xa6, 0xdb, 0x61, 0x89, 0xe2, 0x67, 0xea, 0x07, 0xb0, 0xa0, 0x0e, 0x32, + 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, + 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, + 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, + 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, + 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, + 0x8a, 0x28, 0xa0, 0x03, 0xb5, 0x77, 0x7e, 0x01, 0x9a, 0xd8, 0x69, 0xf2, + 0xc4, 0x8f, 0xfe, 0x90, 0x5c, 0xb3, 0xa9, 0xf4, 0xed, 0x8a, 0xe1, 0x2a, + 0x6b, 0x4b, 0xb9, 0x6c, 0x6e, 0x12, 0x78, 0x1c, 0xa3, 0xa1, 0xc8, 0x23, + 0xf9, 0x50, 0x07, 0xb0, 0xd2, 0xd6, 0x56, 0x83, 0xac, 0xc7, 0xac, 0x59, + 0x09, 0x57, 0x0b, 0x2a, 0xf1, 0x22, 0x67, 0xa1, 0xff, 0x00, 0x0a, 0xd4, + 0xa0, 0x05, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, + 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, + 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, + 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, + 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, + 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, + 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa4, 0xa5, + 0xaa, 0xf7, 0x57, 0x31, 0xda, 0xdb, 0x49, 0x3c, 0x87, 0x09, 0x1a, 0x96, + 0x26, 0x80, 0x31, 0xbc, 0x5b, 0xae, 0x8d, 0x2a, 0xcf, 0xc9, 0x85, 0x87, + 0xda, 0x66, 0x18, 0x51, 0x9f, 0xba, 0x3d, 0x6b, 0xce, 0x8e, 0x59, 0x8b, + 0x12, 0x49, 0x27, 0x39, 0x35, 0x67, 0x55, 0xbf, 0x93, 0x53, 0xd4, 0x65, + 0xb9, 0x94, 0x93, 0xb8, 0x9d, 0xa3, 0xfb, 0xa3, 0xb0, 0xaa, 0xb4, 0x00, + 0x94, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, + 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, + 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, + 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, + 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, + 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x5f, 0xd1, 0x75, 0x49, + 0x74, 0x9b, 0xf4, 0xb8, 0x8f, 0x25, 0x73, 0x89, 0x13, 0x3f, 0x79, 0x6b, + 0xd4, 0xad, 0x2e, 0x62, 0xbb, 0xb7, 0x8e, 0x78, 0x5b, 0x74, 0x72, 0x0c, + 0xa9, 0xaf, 0x1f, 0xfe, 0x67, 0xa5, 0x75, 0xbe, 0x04, 0xd5, 0xcc, 0x72, + 0xb6, 0x9d, 0x33, 0x1d, 0x8f, 0xf3, 0x43, 0x9e, 0xc7, 0xd2, 0x80, 0x3b, + 0x9a, 0x5a, 0x6d, 0x3a, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, + 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, + 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, + 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, + 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, + 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, + 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x10, 0xf4, 0xae, + 0x3f, 0xc7, 0xda, 0x91, 0x8e, 0x18, 0xec, 0x22, 0x3f, 0x7f, 0xe7, 0x93, + 0x1e, 0x9d, 0x87, 0xf9, 0xf6, 0xae, 0xbc, 0x9e, 0x39, 0xaf, 0x29, 0xd7, + 0x6f, 0x8e, 0xa3, 0xab, 0xdc, 0x4f, 0x9f, 0x94, 0xb1, 0x09, 0xfe, 0xe8, + 0xa0, 0x0a, 0x14, 0x94, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, + 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, + 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, + 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, + 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, + 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, + 0x51, 0x40, 0x05, 0x4b, 0x6d, 0x71, 0x25, 0xad, 0xc4, 0x73, 0xc4, 0x70, + 0xf1, 0x9d, 0xc2, 0xa2, 0xa2, 0x80, 0x3d, 0x77, 0x4f, 0xbb, 0x5b, 0xeb, + 0x38, 0x6e, 0x23, 0xe9, 0x22, 0xe7, 0xe9, 0xea, 0x3f, 0x03, 0x56, 0xeb, + 0x92, 0xf8, 0x7f, 0x7a, 0x65, 0xb0, 0x9a, 0xd1, 0xce, 0x5a, 0x17, 0xdc, + 0xbf, 0x43, 0xff, 0x00, 0xd7, 0xae, 0xb6, 0x80, 0x0a, 0x28, 0xa2, 0x80, + 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, + 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, + 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, + 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, + 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, + 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x4a, 0x5a, 0x4a, + 0x00, 0xcf, 0xd7, 0xae, 0xbe, 0xc7, 0xa3, 0x5d, 0xcc, 0x3a, 0xac, 0x64, + 0x2f, 0xd4, 0xf0, 0x3f, 0x5a, 0xf2, 0x93, 0xc8, 0xe6, 0xbd, 0x0b, 0xc7, + 0x53, 0x18, 0xf4, 0x1f, 0x2c, 0x1c, 0x79, 0x92, 0xa8, 0xc7, 0xb0, 0xc9, + 0xfe, 0x82, 0xbc, 0xf2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, + 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa5, 0xfe, 0x42, 0x80, 0x12, + 0x8a, 0x72, 0xa3, 0x39, 0xc2, 0x2b, 0x31, 0xf4, 0x00, 0xd5, 0x98, 0xf4, + 0xcb, 0xd9, 0x31, 0x8b, 0x77, 0x00, 0xfa, 0x8c, 0x7f, 0x3a, 0x34, 0x1d, + 0x99, 0x52, 0x8a, 0xd2, 0x1a, 0x15, 0xf9, 0xff, 0x00, 0x96, 0x4a, 0x3f, + 0xe0, 0x42, 0x97, 0xfb, 0x06, 0xf7, 0xfb, 0x8b, 0xff, 0x00, 0x7d, 0x0a, + 0x57, 0x41, 0xca, 0xcc, 0xca, 0x2b, 0x48, 0xe8, 0x57, 0xf9, 0xff, 0x00, + 0x54, 0xbf, 0xf7, 0xd0, 0xa6, 0x36, 0x8b, 0x7c, 0xa3, 0x98, 0x33, 0xf4, + 0x61, 0x45, 0xd0, 0x72, 0xb2, 0x85, 0x15, 0x6d, 0xb4, 0xbb, 0xd5, 0xeb, + 0x6f, 0x27, 0xe4, 0x2a, 0x23, 0x67, 0x70, 0xbd, 0x6d, 0xe5, 0xcf, 0xfb, + 0x86, 0x8b, 0xa0, 0xb3, 0x21, 0xa2, 0x9e, 0xd0, 0xc8, 0xa7, 0xe6, 0x8d, + 0xd7, 0xea, 0xa4, 0x52, 0x15, 0x3d, 0xd4, 0xfe, 0x46, 0x8b, 0x85, 0x98, + 0xda, 0x29, 0xdb, 0x4f, 0x70, 0x7f, 0x2a, 0x36, 0x9e, 0xc0, 0xfe, 0x54, + 0xee, 0x16, 0x1b, 0x45, 0x3b, 0x69, 0xf4, 0x3f, 0x95, 0x39, 0x61, 0x9a, + 0x4f, 0xb9, 0x13, 0xb7, 0xfb, 0xaa, 0x4d, 0x2b, 0x85, 0x99, 0x1d, 0x15, + 0x3a, 0xd9, 0x5d, 0x3f, 0x0b, 0x6f, 0x2f, 0xfd, 0xf1, 0x8f, 0xe7, 0x52, + 0x8d, 0x2a, 0xf8, 0xf4, 0xb6, 0x7f, 0xd2, 0x8b, 0xa0, 0xb3, 0x29, 0xd1, + 0x5a, 0x0b, 0xa1, 0xdf, 0x30, 0xcf, 0x93, 0x8f, 0xab, 0x01, 0x4e, 0x1a, + 0x0d, 0xf7, 0x78, 0x97, 0xfe, 0xfa, 0x14, 0x5d, 0x07, 0x2b, 0x33, 0x68, + 0xad, 0x3f, 0xec, 0x0b, 0xdc, 0x7d, 0xd4, 0xff, 0x00, 0xbe, 0x85, 0x27, + 0xf6, 0x15, 0xf8, 0x07, 0xf7, 0x4a, 0x7e, 0x8c, 0x28, 0xba, 0x0e, 0x56, + 0x66, 0xd1, 0x56, 0xa5, 0xd3, 0x6f, 0x22, 0x53, 0xbe, 0xde, 0x4c, 0x7a, + 0x85, 0xc8, 0xfd, 0x2a, 0xb3, 0x29, 0x53, 0x86, 0x52, 0x3d, 0x88, 0x34, + 0xee, 0x2b, 0x31, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, + 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0xe8, 0x7c, 0x0f, 0x73, 0xe4, + 0x6b, 0xeb, 0x19, 0x3c, 0x4c, 0x85, 0x7f, 0xaf, 0xf4, 0xaf, 0x46, 0xcd, + 0x79, 0x36, 0x89, 0x37, 0xd9, 0xf5, 0xcb, 0x39, 0x73, 0x8f, 0xdf, 0x28, + 0x27, 0xd8, 0x9c, 0x1f, 0xd0, 0xd7, 0xac, 0x0a, 0x00, 0x75, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x1c, 0x87, 0xc4, 0x56, 0xff, 0x00, 0x43, 0xb4, 0x5f, 0x59, 0x09, + 0xfd, 0x2b, 0x86, 0xae, 0xdb, 0xe2, 0x2f, 0xfa, 0x8b, 0x3f, 0xf7, 0x9b, + 0xf9, 0x0a, 0xe2, 0x68, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, + 0x00, 0xa5, 0xa4, 0xab, 0x3a, 0x7d, 0x84, 0x97, 0xf3, 0x88, 0xe3, 0xe0, + 0x0f, 0xbc, 0xc7, 0xa2, 0x8f, 0xf3, 0xd2, 0x93, 0xd0, 0x06, 0x5b, 0x5a, + 0xcd, 0x77, 0x27, 0x97, 0x0a, 0x16, 0x35, 0xd0, 0xd8, 0x78, 0x6e, 0x31, + 0x83, 0x36, 0x66, 0x6f, 0xee, 0x8e, 0x17, 0x35, 0xb5, 0xa5, 0xe9, 0x51, + 0x5a, 0xc2, 0xa1, 0x57, 0x0a, 0x7a, 0xf1, 0xcb, 0x7b, 0x9a, 0xd2, 0x00, + 0x2f, 0x0b, 0xc0, 0x1d, 0xab, 0x39, 0x4e, 0xfb, 0x1b, 0x46, 0x09, 0x6e, + 0x67, 0xdb, 0xe9, 0x8b, 0x12, 0xed, 0x45, 0x48, 0xc7, 0xa0, 0x15, 0x38, + 0xb2, 0x5e, 0xee, 0xc6, 0xac, 0xd2, 0x8a, 0x8b, 0x9a, 0x58, 0xaf, 0xf6, + 0x28, 0xbf, 0xda, 0xfc, 0xe9, 0x0d, 0x94, 0x5f, 0xed, 0x7e, 0x75, 0x66, + 0x8a, 0x00, 0xad, 0xf6, 0x28, 0xfd, 0x5a, 0x90, 0xd8, 0xaf, 0x67, 0x35, + 0x6a, 0x8a, 0x00, 0xa6, 0x6c, 0x7d, 0x1f, 0xf4, 0xa6, 0x9b, 0x27, 0xec, + 0xe2, 0xaf, 0x1a, 0x05, 0x00, 0x50, 0x36, 0x52, 0x76, 0xdb, 0x4d, 0xfb, + 0x14, 0x9f, 0xdd, 0x53, 0x5a, 0x26, 0x81, 0x45, 0xc2, 0xc8, 0xcd, 0x36, + 0x2f, 0xde, 0x25, 0xfc, 0x85, 0x02, 0xc5, 0xfb, 0x44, 0xbf, 0x90, 0xad, + 0x2a, 0x4a, 0x2e, 0x16, 0x46, 0x78, 0xb3, 0x93, 0xd1, 0x45, 0x38, 0x59, + 0x49, 0xdc, 0x81, 0x57, 0xa9, 0x68, 0xb8, 0x14, 0x45, 0x93, 0xf7, 0x71, + 0xf9, 0x53, 0x85, 0x88, 0xee, 0xff, 0x00, 0xa5, 0x5c, 0xa2, 0x8b, 0x81, + 0x50, 0x59, 0x27, 0x76, 0x26, 0x9e, 0x2c, 0xa2, 0xef, 0xbb, 0xf3, 0xab, + 0x14, 0x50, 0x05, 0x7f, 0xb1, 0xc3, 0xe8, 0x69, 0x3e, 0xc5, 0x17, 0x6d, + 0xdf, 0x9d, 0x59, 0xa2, 0x80, 0x2a, 0x9b, 0x25, 0xfe, 0x17, 0x35, 0x56, + 0xe7, 0x4a, 0x49, 0x94, 0x89, 0x22, 0x49, 0x41, 0xf5, 0x15, 0xa8, 0x68, + 0x14, 0x5c, 0x2c, 0x71, 0x97, 0xfe, 0x1a, 0xc1, 0x66, 0xb7, 0x62, 0xad, + 0xff, 0x00, 0x3c, 0xdb, 0xfa, 0x1a, 0xc1, 0x96, 0x29, 0x21, 0x90, 0xa4, + 0x8a, 0x55, 0x97, 0xb1, 0xaf, 0x4f, 0x74, 0x57, 0x18, 0x71, 0x9f, 0xc3, + 0xa5, 0x62, 0xeb, 0x3a, 0x2c, 0x77, 0x71, 0x1e, 0x06, 0xe1, 0xf7, 0x5f, + 0xd0, 0xfb, 0xfb, 0x55, 0xa9, 0x99, 0xca, 0x1d, 0x8e, 0x1e, 0x8a, 0x96, + 0xe6, 0xda, 0x5b, 0x59, 0xda, 0x29, 0x57, 0x6b, 0x2f, 0x7f, 0x5f, 0x7a, + 0x8a, 0xb5, 0x31, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x1c, + 0x8e, 0x63, 0x75, 0x71, 0xd5, 0x08, 0x6f, 0xca, 0xbd, 0x8d, 0x79, 0x03, + 0xe9, 0x5e, 0x34, 0x7a, 0x1a, 0xf6, 0x54, 0xfb, 0x8b, 0xf4, 0x14, 0x00, + 0xfa, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, + 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, + 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, + 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, + 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, + 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, + 0x0a, 0x28, 0xa2, 0x80, 0x39, 0x0f, 0x88, 0xa3, 0xfd, 0x0e, 0xd1, 0xbd, + 0x24, 0x61, 0xfa, 0x57, 0x0d, 0x5d, 0xf7, 0xc4, 0x28, 0xf3, 0xa3, 0xc3, + 0x27, 0xf7, 0x66, 0x03, 0xf3, 0x06, 0xb8, 0x1a, 0x00, 0x28, 0xa2, 0x8a, + 0x00, 0x28, 0xa2, 0x96, 0x80, 0x1f, 0x6d, 0x04, 0x97, 0x33, 0xa4, 0x31, + 0x02, 0x59, 0x8e, 0x3f, 0xfd, 0x75, 0xde, 0x68, 0xfa, 0x5c, 0x76, 0x76, + 0xca, 0xa1, 0x78, 0xea, 0x49, 0xee, 0x7d, 0x6b, 0x23, 0xc2, 0x5a, 0x66, + 0x50, 0xdc, 0xc8, 0xbf, 0x78, 0xe1, 0x7e, 0x9f, 0xfe, 0xba, 0xea, 0x80, + 0x00, 0x60, 0x74, 0x15, 0x94, 0xdd, 0xdd, 0x8d, 0xa1, 0x1b, 0x2b, 0xb1, + 0x47, 0x41, 0x9a, 0x28, 0x14, 0x1f, 0x5a, 0x83, 0x40, 0x35, 0x34, 0x56, + 0xc5, 0xf9, 0x63, 0x80, 0x69, 0xd6, 0xd0, 0xe7, 0xe7, 0x61, 0xf4, 0xab, + 0x55, 0x71, 0x8f, 0x73, 0x29, 0x4f, 0xa2, 0x21, 0x5b, 0x58, 0xc0, 0xc6, + 0x09, 0xf7, 0xcd, 0x35, 0xed, 0x06, 0x3e, 0x53, 0x83, 0x4d, 0xb8, 0xbf, + 0xb6, 0xb7, 0x38, 0x96, 0x55, 0x56, 0xf4, 0xce, 0x4d, 0x16, 0xda, 0x85, + 0xb5, 0xc9, 0xc4, 0x33, 0x23, 0x1f, 0x4c, 0xf3, 0x57, 0x64, 0x4d, 0xe5, + 0xb9, 0x5d, 0xd1, 0x91, 0x88, 0x65, 0xc1, 0xa0, 0x55, 0xe9, 0x62, 0x12, + 0x29, 0x07, 0xaf, 0x63, 0x54, 0x4a, 0xec, 0x62, 0xa7, 0xa8, 0xac, 0xe5, + 0x1b, 0x1a, 0x42, 0x57, 0x0a, 0x28, 0xa2, 0xa4, 0xb0, 0xa2, 0x8a, 0x28, + 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, + 0x00, 0xa3, 0xbf, 0x4c, 0xd1, 0x56, 0x2d, 0x61, 0xe3, 0x7b, 0x7a, 0xf0, + 0x29, 0xa5, 0x76, 0x26, 0xec, 0xae, 0x24, 0x56, 0xc5, 0x80, 0x2e, 0x70, + 0x2a, 0x51, 0x6b, 0x1f, 0x7c, 0x9f, 0xc6, 0x96, 0x69, 0xe2, 0x81, 0x37, + 0x4d, 0x22, 0xa2, 0xfb, 0x9a, 0xae, 0x9a, 0xbd, 0x93, 0xb6, 0xd1, 0x3a, + 0x03, 0xef, 0xc5, 0x6a, 0x92, 0x46, 0x37, 0x93, 0x25, 0x7b, 0x51, 0x82, + 0x50, 0xe3, 0xda, 0xab, 0x32, 0x94, 0x38, 0x61, 0x83, 0x5a, 0x0a, 0xc1, + 0x97, 0x20, 0x82, 0x3d, 0x45, 0x32, 0x68, 0x84, 0x8a, 0x78, 0xe7, 0xb5, + 0x4c, 0xa3, 0xd8, 0x71, 0x9b, 0x5b, 0x94, 0x68, 0x23, 0x23, 0x04, 0x64, + 0x1e, 0xa2, 0x82, 0x36, 0x9c, 0x1e, 0xbd, 0xe8, 0x15, 0x99, 0xb1, 0x83, + 0xe2, 0x0d, 0x1d, 0x6e, 0xa0, 0x2d, 0x18, 0x02, 0x41, 0xca, 0x9e, 0xdf, + 0x43, 0xed, 0x5c, 0x5b, 0x29, 0x46, 0x2a, 0xc0, 0x82, 0x0e, 0x08, 0x3d, + 0x73, 0x5e, 0xa2, 0xc0, 0x30, 0x21, 0x80, 0xc1, 0x15, 0xc4, 0xf8, 0xab, + 0x4e, 0x36, 0xf7, 0x2b, 0x70, 0x06, 0x12, 0x43, 0xb5, 0xf1, 0xd8, 0xff, + 0x00, 0xf5, 0xc5, 0x69, 0x09, 0x74, 0x33, 0x9c, 0x7a, 0x98, 0x54, 0x52, + 0xd2, 0x56, 0x86, 0x21, 0x45, 0x14, 0x50, 0x02, 0x80, 0x4f, 0x4a, 0xf6, + 0x44, 0xfb, 0xa3, 0xe8, 0x2b, 0xc7, 0xad, 0x97, 0xcc, 0xba, 0x86, 0x3f, + 0xef, 0x48, 0xab, 0xf9, 0x90, 0x2b, 0xd8, 0x87, 0x41, 0xf4, 0xa0, 0x07, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x52, 0x52, 0xd2, 0x1e, 0x94, 0x01, 0x83, 0xe3, 0x68, 0x7c, 0xdf, 0x0e, + 0x4c, 0x47, 0x58, 0xd9, 0x5b, 0xf5, 0xc7, 0xf5, 0xaf, 0x36, 0xaf, 0x58, + 0xd6, 0xa0, 0xfb, 0x4e, 0x8d, 0x77, 0x0f, 0x76, 0x89, 0xb1, 0xf5, 0xc6, + 0x6b, 0xca, 0x39, 0xe9, 0xde, 0x80, 0x12, 0x8a, 0x28, 0xa0, 0x02, 0xa4, + 0x82, 0x36, 0x9a, 0x74, 0x88, 0x73, 0xbd, 0x82, 0xfe, 0x75, 0x1d, 0x68, + 0xf8, 0x7a, 0x21, 0x2e, 0xb5, 0x6c, 0xac, 0x38, 0xde, 0x49, 0xfc, 0x29, + 0x31, 0xad, 0xce, 0xee, 0xc6, 0x01, 0x6d, 0x6b, 0x1c, 0x4a, 0x31, 0x80, + 0x3f, 0x95, 0x58, 0xa6, 0x8e, 0x82, 0x9d, 0x58, 0x1d, 0x21, 0x42, 0x29, + 0x77, 0x0b, 0xdc, 0x9a, 0x2a, 0x6b, 0x41, 0x99, 0xb3, 0xe8, 0x29, 0xad, + 0x58, 0xa4, 0xec, 0x8b, 0x6a, 0x02, 0xae, 0x07, 0x6a, 0xca, 0xd6, 0x2f, + 0xe5, 0x8d, 0x96, 0xda, 0xd0, 0x33, 0x4e, 0xe3, 0x27, 0x03, 0x3b, 0x47, + 0xad, 0x6a, 0xbb, 0x05, 0x52, 0x7d, 0x2b, 0x9d, 0xd2, 0x35, 0x08, 0x9b, + 0x53, 0xb8, 0x79, 0x9c, 0x29, 0x94, 0xfc, 0x84, 0xfa, 0x64, 0xf1, 0x5a, + 0xbe, 0xc6, 0x30, 0x4d, 0xea, 0x64, 0x5d, 0x5b, 0x4f, 0x6e, 0xe0, 0xdc, + 0x23, 0xa1, 0x63, 0xd4, 0x8c, 0xfe, 0xb5, 0x0a, 0xb1, 0x53, 0xb8, 0x1c, + 0x30, 0x3d, 0x73, 0x5d, 0x27, 0x89, 0x2e, 0xa0, 0x6b, 0x2f, 0x29, 0x4a, + 0xbc, 0x85, 0x81, 0x18, 0xed, 0xef, 0x5c, 0xdf, 0x7f, 0xaf, 0x35, 0x93, + 0x56, 0x67, 0x5d, 0x37, 0xcc, 0xb5, 0x47, 0x4f, 0xa0, 0xea, 0x86, 0xe5, + 0x7c, 0x89, 0x8e, 0x65, 0x5e, 0x41, 0xf5, 0x15, 0x7a, 0xf1, 0x0e, 0xe0, + 0xeb, 0x5c, 0x85, 0xa4, 0xe6, 0xda, 0xea, 0x29, 0x54, 0xe3, 0x6b, 0x0c, + 0xfb, 0x8e, 0xf5, 0xda, 0x4d, 0x89, 0x2d, 0xf7, 0x0e, 0xe3, 0x22, 0xae, + 0xf7, 0x46, 0x13, 0x8f, 0x2c, 0xae, 0x8a, 0x60, 0xf1, 0x45, 0x02, 0x8a, + 0xcc, 0xb0, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, + 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x01, 0x63, 0x4f, 0x31, 0xd5, 0x7d, 0x4d, + 0x58, 0xbd, 0xbb, 0x8e, 0xc2, 0xd1, 0xa5, 0x7e, 0x8b, 0xc0, 0x1e, 0xb4, + 0xcb, 0x35, 0xcc, 0xa4, 0xfa, 0x56, 0x2f, 0x89, 0xee, 0x0b, 0xdc, 0xa5, + 0xb8, 0x3f, 0x2a, 0x8c, 0x91, 0xea, 0x4d, 0x5c, 0x74, 0x57, 0x33, 0x6b, + 0x9a, 0x56, 0x28, 0x4c, 0xd7, 0x7a, 0x8b, 0xbc, 0xed, 0x1b, 0xc8, 0x07, + 0x65, 0x07, 0x02, 0xaa, 0x63, 0x07, 0x07, 0x8c, 0x57, 0x53, 0xa4, 0x6a, + 0x16, 0x8b, 0x61, 0x1a, 0x19, 0x12, 0x36, 0x51, 0x86, 0x0c, 0x79, 0xae, + 0x7b, 0x50, 0x96, 0x39, 0xef, 0xe5, 0x92, 0x21, 0x84, 0x27, 0x8a, 0x4d, + 0x1b, 0x41, 0xbb, 0xf2, 0xd8, 0xb7, 0xa3, 0xea, 0xaf, 0x6b, 0x38, 0x8e, + 0x56, 0x2d, 0x0b, 0x1c, 0x7d, 0x3f, 0xfa, 0xd5, 0xd6, 0x2b, 0x06, 0x50, + 0x41, 0xc8, 0x3c, 0x83, 0x5c, 0x06, 0x3f, 0x3a, 0xeb, 0xb4, 0x1b, 0x93, + 0x71, 0xa6, 0xa1, 0x6e, 0x59, 0x3e, 0x53, 0xf8, 0x55, 0x45, 0xf4, 0x66, + 0x75, 0xa0, 0x96, 0xa8, 0x9e, 0xf1, 0x30, 0xe1, 0x87, 0x43, 0x50, 0x0a, + 0xbb, 0x76, 0xbb, 0xa1, 0x3e, 0xd5, 0x4a, 0xa6, 0x4a, 0xcc, 0x50, 0x77, + 0x40, 0x79, 0xac, 0xdd, 0x7e, 0xcc, 0x5d, 0xe9, 0x93, 0x0c, 0x65, 0x95, + 0x77, 0x0f, 0xa8, 0xad, 0x23, 0x4d, 0x74, 0x0e, 0x85, 0x58, 0x64, 0x10, + 0x45, 0x4a, 0xdc, 0xb7, 0xb1, 0xe5, 0xd8, 0x23, 0x83, 0xd4, 0x75, 0xa4, + 0xa9, 0x2e, 0x57, 0x65, 0xcc, 0xab, 0xfd, 0xd7, 0x22, 0xa3, 0xae, 0x83, + 0x94, 0x29, 0x69, 0x29, 0x7d, 0x28, 0x02, 0xe6, 0x8b, 0x1f, 0x9b, 0xad, + 0xd9, 0x20, 0x1c, 0x79, 0xe8, 0x4f, 0xd3, 0x22, 0xbd, 0x64, 0x57, 0x98, + 0xf8, 0x42, 0x2f, 0x37, 0xc4, 0x76, 0xb9, 0x1f, 0x74, 0x96, 0xfc, 0x94, + 0x8f, 0xeb, 0x5e, 0x9c, 0x28, 0x01, 0xd4, 0x51, 0x45, 0x00, 0x14, 0x51, + 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, + 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, + 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, + 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x49, 0x40, 0x0b, 0x45, + 0x25, 0x14, 0x00, 0xb4, 0x52, 0x66, 0x8a, 0x00, 0x5a, 0x29, 0x28, 0xa0, + 0x05, 0xa2, 0x92, 0x90, 0xba, 0x8e, 0xac, 0x07, 0xe3, 0x40, 0x0b, 0x45, + 0x37, 0xcc, 0x4f, 0xef, 0x2f, 0xe7, 0x49, 0xe7, 0x46, 0x3a, 0xc8, 0x83, + 0xfe, 0x04, 0x28, 0x02, 0x4a, 0x2a, 0x2f, 0x3e, 0x2f, 0xf9, 0xea, 0x9f, + 0xf7, 0xd0, 0xa3, 0xcf, 0x8b, 0xfe, 0x7a, 0xa7, 0xfd, 0xf4, 0x28, 0x01, + 0xec, 0xa1, 0x94, 0x82, 0x32, 0x08, 0xc1, 0xaf, 0x23, 0xd5, 0x2d, 0x8d, + 0x9e, 0xa5, 0x71, 0x01, 0xff, 0x00, 0x96, 0x72, 0x10, 0x3e, 0x99, 0xe2, + 0xbd, 0x68, 0x4b, 0x19, 0xe8, 0xeb, 0xf9, 0xd7, 0x01, 0xe3, 0xcb, 0x41, + 0x16, 0xaa, 0x97, 0x0b, 0x8d, 0xb3, 0xa7, 0x38, 0x3d, 0xc5, 0x00, 0x73, + 0x54, 0x52, 0xd2, 0x50, 0x01, 0x5a, 0xbe, 0x17, 0x3f, 0xf1, 0x3c, 0xb7, + 0xcf, 0xfb, 0x5f, 0xc8, 0xd6, 0x55, 0x68, 0x68, 0x12, 0x79, 0x7a, 0xd5, + 0xa9, 0x3d, 0xdf, 0x1f, 0x9e, 0x45, 0x27, 0xb0, 0xd6, 0xe7, 0xa2, 0x63, + 0x8a, 0x28, 0xcd, 0x15, 0x81, 0xd2, 0x15, 0x3d, 0x97, 0xdf, 0x6f, 0xa5, + 0x40, 0x6a, 0x6b, 0x46, 0xc4, 0xa4, 0x7a, 0x8a, 0x71, 0xdc, 0x99, 0xec, + 0x4d, 0x76, 0x71, 0x69, 0x29, 0x1d, 0x42, 0x13, 0xfa, 0x57, 0x08, 0x3b, + 0x1f, 0xc6, 0xbb, 0xe9, 0x57, 0x7c, 0x4c, 0x9f, 0xde, 0x04, 0x57, 0x0b, + 0x22, 0x18, 0xe4, 0x68, 0xc8, 0xe5, 0x49, 0x1f, 0x95, 0x5c, 0xc7, 0x43, + 0xa8, 0xca, 0x29, 0x68, 0xa8, 0x3a, 0x44, 0x27, 0x1c, 0xd7, 0x6d, 0x6c, + 0xd9, 0xd3, 0x63, 0x27, 0xa9, 0x41, 0x5c, 0x5a, 0x23, 0x49, 0x22, 0xa2, + 0xff, 0x00, 0x19, 0xc5, 0x76, 0xe5, 0x04, 0x56, 0x41, 0x07, 0x45, 0x50, + 0x2a, 0xa2, 0x73, 0x57, 0xdd, 0x15, 0x05, 0x14, 0x0a, 0x2a, 0x06, 0x14, + 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, + 0x51, 0x45, 0x00, 0x58, 0xb2, 0xea, 0xf5, 0xcc, 0x6b, 0xc4, 0x9d, 0x5a, + 0x6c, 0xfb, 0x63, 0xf2, 0xae, 0x9a, 0xcd, 0xb1, 0x21, 0x1e, 0xb5, 0xcf, + 0x78, 0x8e, 0x23, 0x1e, 0xa6, 0x5f, 0x1c, 0x48, 0xb9, 0xfd, 0x2a, 0xfe, + 0xc9, 0x30, 0xd2, 0x66, 0x5d, 0x2f, 0xf5, 0xa4, 0x1d, 0x29, 0x6a, 0x0e, + 0xa0, 0xae, 0x8f, 0xc2, 0xcd, 0xfe, 0x8f, 0x30, 0xec, 0x18, 0x57, 0x36, + 0x6b, 0xa9, 0xf0, 0xcc, 0x3b, 0x34, 0xf6, 0x90, 0x8c, 0x19, 0x1b, 0x35, + 0x70, 0xdc, 0xc2, 0xb3, 0xf7, 0x4d, 0x49, 0xff, 0x00, 0xd4, 0xb7, 0xd2, + 0xa8, 0x0e, 0x82, 0xae, 0xdc, 0xb6, 0xd8, 0x5a, 0xa9, 0x0a, 0x27, 0xb9, + 0x95, 0x3d, 0x82, 0x94, 0x75, 0x14, 0x94, 0x13, 0x80, 0x4f, 0xa5, 0x42, + 0x34, 0x3c, 0xca, 0xff, 0x00, 0x9b, 0xfb, 0x83, 0xff, 0x00, 0x4d, 0x1b, + 0xf9, 0xd4, 0x15, 0x25, 0xc3, 0x17, 0xb8, 0x91, 0xbf, 0xbc, 0xc4, 0xfe, + 0xb5, 0x1d, 0x74, 0x2d, 0x8e, 0x67, 0xb8, 0x52, 0xf3, 0x8e, 0x3a, 0xd2, + 0x51, 0xf4, 0xa0, 0x47, 0x4f, 0xf0, 0xfe, 0x0f, 0x33, 0x58, 0x9a, 0x6c, + 0x7c, 0xb1, 0x45, 0x81, 0xf8, 0x9f, 0xfe, 0xb1, 0xaf, 0x40, 0xae, 0x4f, + 0xc0, 0x16, 0xe2, 0x2d, 0x3e, 0xe2, 0xe5, 0x88, 0x1e, 0x74, 0x81, 0x57, + 0x27, 0xb0, 0xff, 0x00, 0xf5, 0xd7, 0x52, 0x65, 0x8c, 0x75, 0x91, 0x47, + 0xfc, 0x08, 0x50, 0x04, 0x94, 0x54, 0x5e, 0x7c, 0x5f, 0xf3, 0xd5, 0x3f, + 0xef, 0xa1, 0x47, 0x9f, 0x17, 0xfc, 0xf5, 0x4f, 0xfb, 0xe8, 0x50, 0x04, + 0xb4, 0x54, 0x42, 0x68, 0x8f, 0x49, 0x13, 0xfe, 0xfa, 0x14, 0xef, 0x31, + 0x3f, 0xbc, 0xbf, 0x9d, 0x00, 0x3e, 0x8a, 0x68, 0x75, 0x3d, 0x18, 0x1f, + 0xc6, 0x96, 0x80, 0x16, 0x8a, 0x4a, 0x28, 0x01, 0x68, 0xa4, 0xa2, 0x80, + 0x16, 0x8a, 0x4a, 0x28, 0x01, 0x68, 0xa4, 0xa2, 0x80, 0x16, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x04, 0xcd, 0x55, 0xb8, 0xd4, 0x2d, 0x2d, + 0x4f, 0xef, 0xae, 0x62, 0x88, 0xfa, 0x33, 0x81, 0x56, 0x4d, 0x67, 0x7f, + 0x61, 0xe9, 0xcd, 0x33, 0xcc, 0xd6, 0x91, 0x3c, 0x92, 0x31, 0x66, 0x67, + 0x19, 0xc9, 0x3e, 0xc6, 0x80, 0x20, 0x7f, 0x14, 0xe9, 0x6a, 0xdb, 0x52, + 0x66, 0x95, 0xbd, 0x23, 0x42, 0xd4, 0x87, 0x5f, 0x96, 0x4f, 0xf8, 0xf7, + 0xd2, 0xef, 0x24, 0xf7, 0x64, 0xdb, 0xfc, 0xeb, 0x56, 0x28, 0x22, 0x88, + 0x62, 0x38, 0x96, 0x31, 0xe8, 0x14, 0x0a, 0x93, 0x14, 0x01, 0x89, 0xf6, + 0xfd, 0x72, 0x4f, 0xf5, 0x7a, 0x64, 0x51, 0xe7, 0xa1, 0x92, 0x51, 0xfd, + 0x29, 0x42, 0xf8, 0x86, 0x51, 0xcb, 0xda, 0x43, 0x9f, 0x40, 0x4e, 0x2b, + 0x6e, 0x8c, 0xf7, 0xa0, 0x0c, 0x51, 0xa7, 0xeb, 0x2f, 0xfe, 0xb3, 0x54, + 0x44, 0xff, 0x00, 0x72, 0x21, 0x41, 0xd0, 0xef, 0x24, 0x1f, 0xbe, 0xd6, + 0x2e, 0x4f, 0xfb, 0x80, 0x2d, 0x6d, 0x64, 0x51, 0x9a, 0x00, 0xc3, 0x1e, + 0x19, 0x53, 0xf7, 0xf5, 0x1b, 0xe7, 0xfa, 0xcb, 0x47, 0xfc, 0x22, 0x96, + 0x47, 0xef, 0xcd, 0x74, 0xff, 0x00, 0x59, 0x4d, 0x6e, 0x12, 0x3b, 0xd4, + 0x32, 0x5d, 0x43, 0x17, 0xfa, 0xc9, 0xa3, 0x4f, 0xf7, 0x9c, 0x0a, 0x00, + 0xca, 0x1e, 0x13, 0xd3, 0x57, 0xa8, 0x98, 0xfd, 0x65, 0x34, 0xa3, 0xc2, + 0x9a, 0x5f, 0x78, 0x5c, 0xfd, 0x64, 0x35, 0x6a, 0x4d, 0x73, 0x4c, 0x87, + 0xef, 0xdf, 0xc1, 0xf8, 0x38, 0x3f, 0xca, 0xab, 0xb7, 0x8a, 0x74, 0xa1, + 0x90, 0xb7, 0x0c, 0xe7, 0xd1, 0x23, 0x63, 0xfd, 0x28, 0x01, 0x3f, 0xe1, + 0x14, 0xd2, 0xbf, 0xe7, 0x83, 0x7f, 0xdf, 0x66, 0x93, 0xfe, 0x11, 0x5d, + 0x2b, 0xfe, 0x78, 0xb7, 0xfd, 0xfc, 0x34, 0x7f, 0xc2, 0x51, 0x6a, 0xdf, + 0xea, 0xad, 0xaf, 0x25, 0xff, 0x00, 0x72, 0x03, 0x47, 0xfc, 0x24, 0x13, + 0x3f, 0xfa, 0xad, 0x1f, 0x51, 0x6f, 0x76, 0x8c, 0x2f, 0xf5, 0xa0, 0x00, + 0xf8, 0x4f, 0x4b, 0xff, 0x00, 0x9e, 0x52, 0x0f, 0xa4, 0x86, 0xb3, 0x35, + 0xbf, 0x0a, 0xda, 0x2e, 0x97, 0x34, 0x96, 0xbe, 0x67, 0x9d, 0x1a, 0x97, + 0x5c, 0xb9, 0x6f, 0xaf, 0xe7, 0x5a, 0x27, 0x58, 0xd5, 0x1c, 0x7e, 0xef, + 0x42, 0x9c, 0xff, 0x00, 0xbf, 0x3a, 0xad, 0x0f, 0xa8, 0xeb, 0x4e, 0x08, + 0x1a, 0x22, 0x80, 0x78, 0x3b, 0xee, 0x41, 0xfe, 0x42, 0x80, 0x3c, 0xd0, + 0x13, 0xde, 0x8a, 0xd0, 0xd6, 0xf4, 0xfb, 0x8d, 0x3e, 0xf4, 0xfd, 0xa2, + 0x01, 0x08, 0x94, 0x97, 0x45, 0x0c, 0x0a, 0xe3, 0xd3, 0x35, 0x9f, 0x40, + 0x05, 0x49, 0x6f, 0x2f, 0x93, 0x71, 0x1c, 0xa0, 0xe3, 0xcb, 0x65, 0x61, + 0xf8, 0x1a, 0x8e, 0x8e, 0x7b, 0x50, 0x07, 0xa8, 0xc4, 0xe2, 0x58, 0x92, + 0x45, 0xe4, 0x30, 0xc8, 0x3e, 0xd4, 0xfa, 0xc7, 0xf0, 0xb5, 0xea, 0xdd, + 0xe8, 0xf1, 0xa9, 0x39, 0x92, 0x1f, 0xdd, 0x91, 0xec, 0x39, 0x1f, 0xa5, + 0x6c, 0x56, 0x0f, 0x46, 0x74, 0xa7, 0x74, 0x14, 0xb1, 0x39, 0x59, 0x54, + 0xf6, 0xce, 0x29, 0x33, 0x41, 0xa4, 0x86, 0xf5, 0x34, 0x73, 0x9f, 0xce, + 0xb9, 0x8f, 0x10, 0xd8, 0x34, 0x37, 0x06, 0xe1, 0x01, 0xd9, 0x27, 0xde, + 0xc7, 0xf0, 0x9c, 0xf5, 0xae, 0x86, 0xda, 0x6d, 0xcb, 0xb5, 0xbe, 0xf0, + 0xa9, 0x24, 0x8d, 0x25, 0x42, 0x92, 0x00, 0xca, 0xc3, 0x04, 0x1a, 0xd9, + 0xda, 0x48, 0xc2, 0x32, 0x70, 0x91, 0xc1, 0x76, 0xcd, 0x2d, 0x74, 0x37, + 0x3e, 0x1a, 0x46, 0x25, 0xad, 0xe6, 0xd8, 0x3f, 0xba, 0x57, 0x22, 0x8b, + 0x6f, 0x0c, 0xa2, 0xb6, 0xeb, 0x89, 0xb7, 0x8f, 0xee, 0xa8, 0xda, 0x2b, + 0x3e, 0x56, 0x74, 0xfb, 0x68, 0xd8, 0xab, 0xe1, 0xdd, 0x3d, 0xa6, 0xb9, + 0x17, 0x2e, 0xb8, 0x8d, 0x3e, 0xee, 0x7b, 0x9a, 0xe8, 0x2f, 0x1f, 0xe5, + 0x0a, 0x3b, 0xd3, 0xd1, 0x12, 0xde, 0x10, 0xa8, 0x02, 0xa2, 0x8c, 0x00, + 0x06, 0x2a, 0x9b, 0xb9, 0x91, 0xcb, 0x1f, 0xc2, 0xa9, 0xfb, 0xaa, 0xc6, + 0x29, 0xb9, 0xca, 0xe2, 0x01, 0x45, 0x14, 0x56, 0x46, 0x81, 0x45, 0x14, + 0x66, 0x98, 0x06, 0x68, 0xa8, 0x6e, 0x2e, 0xa1, 0xb7, 0xff, 0x00, 0x5a, + 0xe0, 0x1f, 0x4e, 0xf4, 0x41, 0x75, 0x0d, 0xc0, 0xcc, 0x4e, 0x1c, 0xf7, + 0x1e, 0x94, 0x0e, 0xc4, 0xd4, 0x51, 0x45, 0x02, 0x0a, 0x28, 0xa2, 0x80, + 0x1d, 0x0b, 0x14, 0x94, 0x37, 0xbe, 0x29, 0x9a, 0xed, 0x81, 0xbd, 0xb3, + 0xdd, 0x18, 0xfd, 0xe4, 0x7c, 0xaf, 0xbd, 0x2e, 0x3d, 0x2a, 0xe5, 0xb4, + 0xbb, 0xd3, 0x69, 0xea, 0x2a, 0xe3, 0xd8, 0xce, 0x57, 0x4f, 0x99, 0x1c, + 0x29, 0xc8, 0x24, 0x1e, 0x08, 0xeb, 0xed, 0x45, 0x75, 0x9a, 0x86, 0x87, + 0x0d, 0xdb, 0x79, 0x8a, 0xc6, 0x29, 0x0f, 0x52, 0x06, 0x41, 0xfc, 0x2a, + 0x82, 0x78, 0x62, 0x4d, 0xd8, 0x92, 0xe1, 0x76, 0xe7, 0xf8, 0x57, 0x9a, + 0x1c, 0x59, 0xb4, 0x6b, 0x45, 0xad, 0x4c, 0x9b, 0x3b, 0x59, 0x2f, 0x2e, + 0x56, 0x28, 0xc6, 0x77, 0x1e, 0x4f, 0xf7, 0x45, 0x76, 0xb6, 0xf1, 0x2d, + 0xbc, 0x0b, 0x12, 0x8f, 0x95, 0x06, 0x05, 0x43, 0x63, 0xa7, 0xc3, 0x63, + 0x1e, 0xd8, 0x97, 0x9e, 0xec, 0x7a, 0x9a, 0xb0, 0xee, 0x11, 0x37, 0x31, + 0xc0, 0x15, 0x51, 0x56, 0x30, 0xa9, 0x3e, 0x76, 0x41, 0x78, 0xfc, 0x84, + 0x1f, 0x5a, 0xad, 0x43, 0xb9, 0x77, 0x2c, 0x7b, 0xd2, 0x0e, 0x95, 0x9b, + 0x77, 0x65, 0xc5, 0x59, 0x0b, 0x55, 0xf5, 0x09, 0xbc, 0x8b, 0x09, 0xa5, + 0xce, 0x36, 0xa1, 0x3f, 0xa1, 0xab, 0x15, 0x87, 0xe2, 0xfb, 0xbf, 0xb3, + 0xe9, 0x0d, 0x10, 0x3f, 0x3c, 0xec, 0x17, 0x1e, 0xc3, 0xad, 0x09, 0x5d, + 0x8d, 0xe8, 0x8e, 0x20, 0x9c, 0x9f, 0x6c, 0xd2, 0x52, 0x9a, 0x4a, 0xdc, + 0xe6, 0x0a, 0x50, 0x0b, 0x10, 0x17, 0x96, 0x3d, 0x07, 0xad, 0x25, 0x69, + 0x78, 0x7e, 0xca, 0xe6, 0xef, 0x52, 0x49, 0x2d, 0x6d, 0xc4, 0xed, 0x01, + 0x0e, 0xca, 0xed, 0x81, 0x40, 0x1d, 0x8d, 0x87, 0x84, 0x6c, 0x92, 0xce, + 0x21, 0x37, 0x9d, 0xe6, 0x6c, 0xcb, 0xe2, 0x42, 0x06, 0x7e, 0x95, 0x68, + 0x78, 0x4f, 0x4b, 0xef, 0x1c, 0xa7, 0xeb, 0x21, 0xa6, 0xff, 0x00, 0x68, + 0xeb, 0x83, 0xef, 0x68, 0xe8, 0x7f, 0xdd, 0xb9, 0x14, 0xa7, 0x57, 0xd5, + 0x97, 0xef, 0xe8, 0x32, 0xff, 0x00, 0xc0, 0x2e, 0x15, 0xbf, 0xa5, 0x00, + 0x3b, 0xfe, 0x11, 0x4d, 0x2b, 0xfe, 0x78, 0x31, 0xff, 0x00, 0xb6, 0x86, + 0x8f, 0xf8, 0x45, 0x34, 0xaf, 0xf9, 0xe0, 0xdf, 0xf7, 0xd9, 0xa6, 0x8d, + 0x7a, 0xe5, 0x07, 0xef, 0x34, 0x4d, 0x40, 0x1f, 0xf6, 0x14, 0x37, 0xf5, + 0xa3, 0xfe, 0x12, 0x48, 0x54, 0x7e, 0xfa, 0xca, 0xfe, 0x2f, 0xf7, 0xa0, + 0x3c, 0x7e, 0x54, 0x00, 0xa7, 0xc2, 0x9a, 0x5f, 0xfc, 0xf1, 0x7f, 0xc2, + 0x43, 0x41, 0xf0, 0x9e, 0x98, 0x7a, 0x24, 0xa3, 0xe9, 0x29, 0xa5, 0x5f, + 0x14, 0xe9, 0x7f, 0xc7, 0x2c, 0x91, 0xff, 0x00, 0xbd, 0x13, 0x0f, 0xe9, + 0x53, 0xc5, 0xaf, 0xe9, 0x52, 0x0f, 0x96, 0xfe, 0x1f, 0xf8, 0x13, 0x63, + 0xf9, 0xd0, 0x05, 0x5f, 0xf8, 0x44, 0xec, 0x47, 0xdd, 0x96, 0xe5, 0x7e, + 0x92, 0x9a, 0x3f, 0xe1, 0x17, 0x8d, 0x7f, 0xd5, 0xdf, 0xde, 0xa7, 0xd2, + 0x5a, 0xd4, 0x8e, 0xf6, 0xde, 0x61, 0x98, 0xe7, 0x89, 0xff, 0x00, 0xdd, + 0x70, 0x6a, 0x70, 0xc0, 0xf4, 0x34, 0x01, 0x8a, 0x34, 0x0b, 0x88, 0xff, + 0x00, 0xd4, 0xea, 0xf7, 0x8b, 0xfe, 0xf1, 0x0d, 0x4b, 0xfd, 0x99, 0xac, + 0x20, 0xf9, 0x35, 0x7d, 0xc7, 0xfd, 0xb8, 0x85, 0x6d, 0x51, 0x91, 0x40, + 0x18, 0x9e, 0x57, 0x88, 0x22, 0xfb, 0xb7, 0x16, 0x92, 0x8e, 0xd9, 0x52, + 0x29, 0x05, 0xde, 0xbf, 0x11, 0x1e, 0x65, 0x84, 0x12, 0x8f, 0x54, 0x93, + 0x15, 0xb9, 0x46, 0x05, 0x00, 0x62, 0x7f, 0x6e, 0xdd, 0xc7, 0xff, 0x00, + 0x1f, 0x1a, 0x45, 0xca, 0x8f, 0x54, 0xc3, 0x52, 0x8f, 0x14, 0xe9, 0xca, + 0x76, 0xcc, 0xd2, 0xdb, 0xb7, 0xf7, 0x65, 0x88, 0xad, 0x6d, 0x53, 0x1e, + 0x34, 0x71, 0x86, 0x50, 0x41, 0xec, 0x45, 0x00, 0x55, 0xb7, 0xd6, 0x2c, + 0x2e, 0x3f, 0xd4, 0xde, 0x42, 0xc7, 0xd3, 0x78, 0x15, 0x70, 0x10, 0x7d, + 0xea, 0x84, 0xda, 0x16, 0x9b, 0x71, 0xcc, 0x96, 0x71, 0x67, 0xd5, 0x57, + 0x15, 0x79, 0x10, 0x46, 0x81, 0x54, 0x60, 0x01, 0x80, 0x28, 0x01, 0xf4, + 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, + 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x25, 0x19, 0xe2, 0x96, 0xb2, + 0xaf, 0x64, 0xd5, 0x9a, 0xe5, 0xa3, 0xb3, 0x8a, 0xd9, 0x22, 0x03, 0xfd, + 0x6c, 0xac, 0x49, 0x3f, 0x80, 0xa0, 0x0d, 0x4a, 0x82, 0x7b, 0xcb, 0x7b, + 0x75, 0xcc, 0xd3, 0xc7, 0x18, 0xff, 0x00, 0x69, 0x80, 0xac, 0x93, 0xa2, + 0x5f, 0x5d, 0x73, 0x7d, 0xaa, 0xcc, 0x41, 0x3c, 0xa4, 0x00, 0x20, 0xa9, + 0xad, 0xfc, 0x35, 0xa6, 0x42, 0x77, 0x1b, 0x7f, 0x35, 0x87, 0xf1, 0x4a, + 0xc5, 0xcf, 0xeb, 0x40, 0x09, 0x27, 0x89, 0xb4, 0xd5, 0x6d, 0xb1, 0xc9, + 0x24, 0xed, 0xe9, 0x12, 0x16, 0xa6, 0x8d, 0x6a, 0xf2, 0x60, 0x4d, 0xae, + 0x95, 0x70, 0xe0, 0xf4, 0x32, 0x10, 0x82, 0xb5, 0x62, 0xb7, 0x8a, 0x11, + 0x88, 0xe3, 0x44, 0x1f, 0xec, 0xae, 0x2a, 0x5c, 0x7a, 0xd0, 0x06, 0x11, + 0x6f, 0x11, 0x5c, 0x7d, 0xd8, 0xed, 0x2d, 0x81, 0xfe, 0xf1, 0x2e, 0x45, + 0x20, 0xd2, 0x75, 0x69, 0xb1, 0xf6, 0x8d, 0x65, 0xd4, 0x77, 0x11, 0x46, + 0x17, 0xf5, 0xad, 0xec, 0x51, 0x8a, 0x00, 0xc4, 0x5f, 0x0d, 0x40, 0xff, + 0x00, 0xf1, 0xf1, 0x77, 0x79, 0x3f, 0xfb, 0xf2, 0x91, 0xfc, 0xaa, 0x64, + 0xf0, 0xd6, 0x96, 0x9c, 0x9b, 0x45, 0x73, 0xea, 0xe4, 0x9a, 0xd5, 0xa2, + 0x80, 0x29, 0xc7, 0xa5, 0x58, 0xc5, 0xfe, 0xae, 0xd2, 0x10, 0x7f, 0xdc, + 0x15, 0x61, 0x20, 0x89, 0x3e, 0xec, 0x68, 0xbf, 0x45, 0x02, 0xa4, 0xa2, + 0x80, 0x13, 0x1e, 0x9c, 0x52, 0xe2, 0x8a, 0x5a, 0x00, 0x4c, 0x71, 0x46, + 0x29, 0x68, 0xa0, 0x0c, 0x7f, 0x10, 0xe9, 0x0b, 0xab, 0xe9, 0xcd, 0x16, + 0x00, 0x95, 0x3e, 0x68, 0xdb, 0xd0, 0x8f, 0xf1, 0xaf, 0x32, 0x96, 0x27, + 0x86, 0x56, 0x8a, 0x55, 0x2a, 0xea, 0xdb, 0x4a, 0x9e, 0xa0, 0xd7, 0xb2, + 0x62, 0xb9, 0x4f, 0x17, 0xf8, 0x77, 0xed, 0x8a, 0x6f, 0xed, 0x14, 0x7d, + 0xa1, 0x07, 0xef, 0x14, 0x0f, 0xbe, 0x3f, 0xc6, 0x80, 0x38, 0x3a, 0x29, + 0x7a, 0x1c, 0x1e, 0x29, 0x28, 0x03, 0x5b, 0xc3, 0x5a, 0x90, 0xd3, 0xf5, + 0x10, 0x24, 0x38, 0x86, 0x6f, 0x91, 0x8f, 0xa7, 0xbd, 0x77, 0xbd, 0x46, + 0x45, 0x79, 0x6f, 0xf4, 0xae, 0xbf, 0xc3, 0x1a, 0xe0, 0x9d, 0x16, 0xca, + 0xe5, 0xb1, 0x22, 0x8c, 0x46, 0xc7, 0xa3, 0x0f, 0x4f, 0xad, 0x67, 0x38, + 0xf5, 0x35, 0x84, 0xba, 0x33, 0xa4, 0xa3, 0x14, 0x0f, 0xff, 0x00, 0x5f, + 0xb5, 0x15, 0x99, 0xa8, 0x0c, 0xa9, 0xc8, 0x3c, 0xd5, 0xa8, 0xae, 0x94, + 0x8c, 0x3f, 0x07, 0xd6, 0xaa, 0xd1, 0x8a, 0x69, 0xb4, 0x4c, 0xa2, 0x99, + 0xa0, 0x1d, 0x4f, 0x71, 0x4d, 0x79, 0x91, 0x06, 0x73, 0x93, 0x54, 0x68, + 0xc5, 0x57, 0x3b, 0x27, 0xd9, 0x8f, 0x9a, 0x66, 0x95, 0xb1, 0xd0, 0x76, + 0xa6, 0x0a, 0x28, 0xc5, 0x43, 0xd4, 0xb4, 0xac, 0x14, 0x51, 0x45, 0x03, + 0x0c, 0xd1, 0x46, 0x29, 0x33, 0x40, 0x1c, 0xee, 0xab, 0xbf, 0xed, 0xf2, + 0x19, 0x3b, 0x9e, 0x29, 0xfa, 0x28, 0x7f, 0xb7, 0x8d, 0x99, 0xdb, 0x86, + 0xdd, 0xfe, 0x7e, 0xb5, 0xb7, 0x3d, 0xb4, 0x53, 0x8c, 0x4a, 0x81, 0x8d, + 0x10, 0xc1, 0x15, 0xba, 0xe2, 0x34, 0x0a, 0x3d, 0xa8, 0x2f, 0x9b, 0x4b, + 0x12, 0xd1, 0x49, 0x4b, 0x41, 0x21, 0x45, 0x14, 0x50, 0x20, 0xa1, 0x49, + 0x46, 0xdc, 0x0f, 0x34, 0x51, 0x8a, 0x00, 0xb7, 0x15, 0xca, 0x30, 0xf9, + 0xb8, 0x35, 0x36, 0xf4, 0x3d, 0xc5, 0x67, 0x51, 0xcd, 0x5f, 0x3b, 0x33, + 0x74, 0xd1, 0x79, 0xe7, 0x44, 0x19, 0xce, 0x4f, 0xb5, 0x54, 0x96, 0x63, + 0x29, 0xe7, 0x81, 0xe9, 0x4c, 0xc5, 0x14, 0x9c, 0x9b, 0x1c, 0x60, 0x90, + 0x62, 0x8a, 0x28, 0xc7, 0x07, 0xda, 0xa4, 0xb0, 0xae, 0x13, 0xc5, 0x77, + 0xc2, 0xf3, 0x54, 0x28, 0x8d, 0xba, 0x38, 0x3e, 0x41, 0xf5, 0xef, 0x5d, + 0x27, 0x88, 0xb5, 0x65, 0xd3, 0x6d, 0x0a, 0x46, 0x41, 0xb8, 0x94, 0x6d, + 0x50, 0x3b, 0x7b, 0xd7, 0x06, 0x49, 0x27, 0x24, 0xe5, 0x8f, 0x53, 0xeb, + 0x5a, 0x41, 0x75, 0x32, 0x9c, 0xba, 0x09, 0x45, 0x14, 0x64, 0x63, 0x39, + 0xe2, 0xb4, 0x32, 0x14, 0x02, 0xc4, 0x2a, 0x82, 0x49, 0xe9, 0x5e, 0x97, + 0xe1, 0x6d, 0x24, 0x69, 0x7a, 0x5a, 0x87, 0x50, 0x27, 0x9b, 0xe7, 0x93, + 0x8e, 0x87, 0xb0, 0xae, 0x7b, 0xc1, 0x9a, 0x07, 0xda, 0x25, 0x5d, 0x42, + 0xe5, 0x7f, 0x74, 0x87, 0x31, 0x03, 0xfc, 0x47, 0xd7, 0xe9, 0x5d, 0xd8, + 0x14, 0x00, 0xb4, 0x62, 0x96, 0x8a, 0x00, 0x4c, 0x51, 0x8c, 0xd2, 0xd1, + 0x40, 0x11, 0xbc, 0x68, 0xff, 0x00, 0x79, 0x14, 0xfd, 0x57, 0x35, 0x04, + 0x9a, 0x75, 0x9c, 0xbf, 0xeb, 0x2d, 0x60, 0x6f, 0xac, 0x62, 0xad, 0x51, + 0x40, 0x19, 0x6f, 0xe1, 0xdd, 0x2e, 0x43, 0x93, 0x65, 0x10, 0xff, 0x00, + 0x74, 0x62, 0xa1, 0x6f, 0x0c, 0x59, 0x81, 0x98, 0x65, 0xb9, 0xb7, 0x3e, + 0xb1, 0xcc, 0x7f, 0xad, 0x6d, 0x51, 0x40, 0x18, 0x47, 0x43, 0xd4, 0x62, + 0xc1, 0xb6, 0xd6, 0x67, 0x00, 0x76, 0x95, 0x43, 0x51, 0xe5, 0xf8, 0x86, + 0xdf, 0xa4, 0xb6, 0x97, 0x20, 0x7f, 0x78, 0x6d, 0x26, 0xb7, 0x68, 0xc5, + 0x00, 0x62, 0x9d, 0x5b, 0x52, 0x87, 0x1f, 0x68, 0xd2, 0x24, 0xc7, 0xac, + 0x2e, 0x1a, 0x95, 0x7c, 0x51, 0x62, 0x1b, 0x6c, 0xeb, 0x3d, 0xbb, 0x7a, + 0x4b, 0x19, 0x15, 0xb3, 0x8a, 0x63, 0xc4, 0x92, 0x0c, 0x3a, 0x2b, 0x0f, + 0x42, 0x33, 0x40, 0x15, 0xed, 0xb5, 0x3b, 0x3b, 0xac, 0x79, 0x17, 0x51, + 0x39, 0x3d, 0x83, 0x0c, 0xfe, 0x55, 0x6c, 0x1c, 0x8c, 0xd6, 0x6d, 0xce, + 0x81, 0xa6, 0x5d, 0x64, 0xbd, 0xa4, 0x61, 0xbf, 0xbc, 0x83, 0x69, 0xfc, + 0xc5, 0x55, 0xff, 0x00, 0x84, 0x7a, 0x58, 0x0e, 0x6c, 0x75, 0x3b, 0xa8, + 0x4f, 0xf7, 0x5c, 0xef, 0x1f, 0xad, 0x00, 0x6e, 0x66, 0x8a, 0xc5, 0x8c, + 0xeb, 0xb6, 0xf2, 0x22, 0xc8, 0xb6, 0xd7, 0x69, 0xbb, 0x0c, 0xc0, 0xec, + 0x60, 0x3e, 0x9d, 0x2b, 0x64, 0x74, 0xa0, 0x07, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x52, 0x63, 0x1d, 0x29, 0x68, 0xa0, 0x04, 0xc5, + 0x14, 0xb4, 0x50, 0x02, 0x52, 0xd1, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, + 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, + 0x14, 0x51, 0x45, 0x00, 0x14, 0x98, 0xa5, 0xa2, 0x80, 0x39, 0x2f, 0x13, + 0xf8, 0x57, 0xed, 0x5b, 0xae, 0xec, 0x15, 0x56, 0x7e, 0xaf, 0x1f, 0x40, + 0xdf, 0x4a, 0xe1, 0xa4, 0x46, 0x8a, 0x46, 0x49, 0x15, 0x91, 0xd7, 0xaa, + 0xb0, 0xe4, 0x57, 0xb2, 0xe2, 0xb1, 0x35, 0xdf, 0x0d, 0xda, 0xea, 0xe0, + 0xbe, 0x3c, 0xab, 0x81, 0xca, 0xc8, 0xbd, 0xfe, 0xbe, 0xb4, 0x01, 0xe6, + 0x9e, 0xd4, 0x02, 0x54, 0x86, 0x52, 0x54, 0x8e, 0x84, 0x76, 0xfa, 0x55, + 0xfd, 0x5b, 0x45, 0xbc, 0xd2, 0x65, 0x22, 0xe2, 0x3f, 0xdd, 0x9f, 0xbb, + 0x20, 0xe5, 0x4f, 0xf8, 0x56, 0x7e, 0x3f, 0x2f, 0x7a, 0x00, 0xeb, 0x74, + 0x2f, 0x13, 0xab, 0x85, 0xb7, 0xbf, 0x6d, 0xad, 0x8c, 0x2c, 0xbe, 0xbe, + 0xc6, 0xba, 0x75, 0x60, 0xea, 0x19, 0x48, 0x60, 0x7b, 0x83, 0x5e, 0x59, + 0xdb, 0x18, 0xc8, 0xad, 0x1d, 0x33, 0x5c, 0xbb, 0xd3, 0x4e, 0xd8, 0xdf, + 0xcc, 0x8f, 0xbc, 0x6d, 0xcf, 0xe5, 0x59, 0xb8, 0x2e, 0x86, 0x91, 0x9d, + 0xb7, 0x3d, 0x0a, 0x8a, 0xc4, 0xd3, 0xfc, 0x53, 0x65, 0x75, 0x85, 0x98, + 0x9b, 0x79, 0x0f, 0x66, 0xe4, 0x7e, 0x75, 0xb4, 0x8e, 0xb2, 0x20, 0x64, + 0x60, 0xca, 0x7b, 0xa9, 0xcd, 0x66, 0xd3, 0x46, 0xa9, 0xa6, 0x2d, 0x14, + 0x76, 0xa3, 0x34, 0x0c, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, + 0x33, 0x58, 0xed, 0x3c, 0xb6, 0x1a, 0xa3, 0x19, 0x4b, 0x18, 0xdc, 0xf0, + 0x7b, 0x56, 0xc6, 0x2a, 0x1b, 0x8b, 0x68, 0xee, 0x63, 0x29, 0x2a, 0xe4, + 0x76, 0x3e, 0x94, 0x0d, 0x12, 0x46, 0xeb, 0x22, 0x86, 0x46, 0x04, 0x1f, + 0x4a, 0x49, 0x24, 0x8e, 0x24, 0xdd, 0x23, 0x05, 0x51, 0xef, 0x59, 0x67, + 0x48, 0x9e, 0x33, 0xfe, 0x8f, 0x39, 0x03, 0xd3, 0x38, 0xa5, 0x5d, 0x22, + 0x59, 0x1f, 0x75, 0xc4, 0xfb, 0x87, 0xfb, 0x3c, 0xd0, 0x3b, 0x21, 0x2d, + 0x26, 0x9a, 0xfb, 0x52, 0x32, 0xab, 0x32, 0xc2, 0xbd, 0x79, 0xe3, 0xda, + 0xb5, 0xea, 0x38, 0x60, 0x8e, 0x08, 0xc2, 0x46, 0xa1, 0x40, 0xa9, 0x33, + 0x40, 0x98, 0x51, 0x45, 0x19, 0xa0, 0x41, 0x45, 0x14, 0x66, 0x80, 0x0a, + 0x28, 0xa3, 0x34, 0x00, 0x51, 0x9a, 0x4e, 0x95, 0x15, 0xc5, 0xd4, 0x16, + 0x91, 0xef, 0xb8, 0x95, 0x23, 0x5e, 0xdb, 0x8e, 0x33, 0x40, 0x12, 0xf6, + 0xfe, 0x55, 0x9f, 0xac, 0xeb, 0x30, 0x69, 0x71, 0x12, 0xc4, 0x3c, 0xe7, + 0xee, 0x46, 0x3f, 0x99, 0xac, 0x6d, 0x53, 0xc5, 0xc3, 0x0d, 0x1e, 0x9e, + 0x87, 0x3f, 0xf3, 0xd5, 0x87, 0x4f, 0xa0, 0xae, 0x62, 0x69, 0x64, 0x9e, + 0x43, 0x24, 0xae, 0xce, 0xec, 0x72, 0x49, 0xe6, 0xad, 0x43, 0xb9, 0x9c, + 0xa6, 0xba, 0x12, 0x5e, 0xde, 0x4d, 0x7d, 0x72, 0xf3, 0xce, 0xfb, 0x9d, + 0x8f, 0xe5, 0x50, 0x51, 0x4f, 0x8a, 0x29, 0x27, 0x90, 0x47, 0x12, 0x33, + 0xc8, 0xc7, 0x01, 0x54, 0x64, 0xd6, 0xa6, 0x23, 0x2b, 0xa1, 0xf0, 0xcf, + 0x86, 0x64, 0xd4, 0xa4, 0x5b, 0x8b, 0xa5, 0x29, 0x6a, 0xa7, 0x20, 0x63, + 0x05, 0xcf, 0xa5, 0x69, 0xf8, 0x7f, 0xc1, 0xa5, 0x59, 0x6e, 0x35, 0x30, + 0x09, 0x1c, 0x88, 0x07, 0x4f, 0xc6, 0xbb, 0x14, 0x45, 0x55, 0x0a, 0xa0, + 0x28, 0x03, 0x00, 0x0e, 0xd4, 0x00, 0x91, 0x46, 0x91, 0x22, 0xa4, 0x6a, + 0x15, 0x14, 0x60, 0x28, 0x1d, 0x29, 0xf4, 0x62, 0x96, 0x80, 0x0a, 0x28, + 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, + 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x4a, 0x5a, 0x28, 0x01, 0x28, + 0xa5, 0xa2, 0x80, 0x13, 0x1e, 0xf4, 0x52, 0xd1, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x09, 0x46, 0x6a, 0x1b, 0xb9, 0x8d, 0xbd, + 0xa4, 0xb2, 0x85, 0xde, 0x63, 0x42, 0xc1, 0x47, 0x7c, 0x57, 0x9b, 0xdd, + 0xf8, 0xaf, 0x54, 0xb9, 0x72, 0xcb, 0x39, 0x85, 0x4f, 0xf0, 0x27, 0x6f, + 0xad, 0x00, 0x7a, 0x75, 0x15, 0xe5, 0x71, 0xf8, 0x8f, 0x56, 0x8c, 0xe7, + 0xed, 0xb2, 0xe3, 0xdf, 0x9a, 0xd9, 0xd3, 0x7c, 0x63, 0xa8, 0xaf, 0xfa, + 0xfb, 0x6f, 0xb4, 0xc6, 0xbf, 0x79, 0x91, 0x48, 0x61, 0x40, 0x1d, 0xe5, + 0x15, 0x95, 0xa5, 0x6b, 0xd6, 0x5a, 0xaa, 0xfe, 0xe2, 0x4c, 0x49, 0x8e, + 0x63, 0x6e, 0x0d, 0x69, 0xe6, 0x80, 0x1d, 0x49, 0x4b, 0x45, 0x00, 0x43, + 0x34, 0x11, 0xcd, 0x1b, 0x47, 0x22, 0x2b, 0xa3, 0x7d, 0xe5, 0x61, 0x90, + 0x7e, 0xb5, 0xcc, 0xea, 0xbe, 0x08, 0xb7, 0x9f, 0x32, 0x58, 0x3f, 0x91, + 0x27, 0xf7, 0x1b, 0x95, 0x3f, 0xe1, 0x5d, 0x5d, 0x18, 0xa0, 0x0f, 0x28, + 0xd4, 0x74, 0x3b, 0xfd, 0x34, 0x9f, 0xb4, 0xdb, 0xb8, 0x5e, 0xce, 0x9f, + 0x32, 0x9f, 0xc4, 0x74, 0xac, 0xfe, 0x9e, 0xbf, 0x88, 0xaf, 0x66, 0x65, + 0x0c, 0xa4, 0x10, 0x08, 0x3d, 0x8f, 0x4a, 0xc8, 0xbe, 0xf0, 0xc6, 0x97, + 0x7d, 0x92, 0xf6, 0xe1, 0x1f, 0xfb, 0xf1, 0xf0, 0x68, 0x03, 0xcc, 0x6a, + 0x6b, 0x5b, 0xcb, 0x8b, 0x47, 0xdd, 0x6f, 0x3c, 0x91, 0x1f, 0xf6, 0x5b, + 0x83, 0xf8, 0x57, 0x4f, 0x7b, 0xe0, 0x39, 0x54, 0x93, 0x65, 0x72, 0xae, + 0x0f, 0xf0, 0xca, 0x30, 0x47, 0xe3, 0x58, 0xd7, 0x7e, 0x1a, 0xd5, 0x6d, + 0x32, 0x5a, 0xd5, 0x9d, 0x47, 0x74, 0xe6, 0x80, 0x2c, 0x5b, 0xf8, 0xb6, + 0xfe, 0x2c, 0x09, 0x44, 0x73, 0x28, 0xfe, 0xf2, 0xed, 0xad, 0x2b, 0x7f, + 0x19, 0x40, 0x40, 0xfb, 0x45, 0xb4, 0x88, 0x7d, 0x54, 0xe4, 0x57, 0x29, + 0x24, 0x52, 0xc4, 0xdb, 0x64, 0x8e, 0x44, 0x3e, 0x8c, 0xa6, 0xa3, 0xe3, + 0xb7, 0x5a, 0x9e, 0x54, 0x52, 0x9b, 0x47, 0x7d, 0x17, 0x89, 0x74, 0xb9, + 0x7f, 0xe5, 0xb9, 0x43, 0xe8, 0xc8, 0xd5, 0x6a, 0x3d, 0x56, 0xc2, 0x4f, + 0xb9, 0x79, 0x01, 0xfa, 0xc8, 0x05, 0x79, 0xbf, 0xb5, 0x02, 0x97, 0x22, + 0x2b, 0xda, 0x33, 0xd4, 0x56, 0x68, 0xdb, 0xee, 0xc8, 0x87, 0xe8, 0x69, + 0xe0, 0x83, 0xd0, 0x8f, 0xce, 0xbc, 0xb0, 0x1d, 0xbd, 0x09, 0x1f, 0x43, + 0x4f, 0x17, 0x13, 0xaf, 0x49, 0xa4, 0x1f, 0xf0, 0x23, 0x4b, 0x90, 0x7e, + 0xd0, 0xf5, 0x0a, 0x2b, 0xcc, 0xc5, 0xf5, 0xd2, 0xf4, 0xb9, 0x9b, 0xfe, + 0xfb, 0x34, 0xe1, 0xa9, 0x5e, 0x0e, 0x97, 0x32, 0xff, 0x00, 0xdf, 0x46, + 0x97, 0x20, 0x7b, 0x43, 0xd2, 0xa8, 0xaf, 0x35, 0xfe, 0xd3, 0xbe, 0xff, + 0x00, 0x9f, 0xa9, 0x7f, 0xef, 0xaa, 0x5f, 0xed, 0x4b, 0xef, 0xf9, 0xfb, + 0x9b, 0xfe, 0xfa, 0xa3, 0x90, 0x3d, 0xa1, 0xe9, 0x34, 0x95, 0xe6, 0xdf, + 0xda, 0x77, 0xc7, 0xad, 0xd4, 0xbf, 0xf7, 0xd5, 0x21, 0xd4, 0x2f, 0x0f, + 0xfc, 0xbd, 0x4b, 0xff, 0x00, 0x7d, 0x1a, 0x39, 0x03, 0xda, 0x1e, 0x97, + 0xf8, 0xd2, 0x12, 0x07, 0x52, 0x3f, 0x3a, 0xf3, 0x33, 0x7b, 0x72, 0xdf, + 0x7a, 0xe2, 0x6f, 0xfb, 0xec, 0xd3, 0x1a, 0xe2, 0x76, 0xeb, 0x3c, 0x87, + 0xea, 0xc6, 0x8f, 0x66, 0x1e, 0xd0, 0xf4, 0xd6, 0x92, 0x35, 0x1c, 0xba, + 0x81, 0xea, 0x5b, 0x15, 0x5e, 0x4d, 0x4e, 0xca, 0x31, 0xf3, 0xdd, 0xc2, + 0x3d, 0xb7, 0x82, 0x6b, 0xcd, 0xc9, 0x2c, 0x72, 0xc4, 0x9f, 0xa9, 0xa2, + 0x9f, 0x20, 0x7b, 0x43, 0xbe, 0x9b, 0xc4, 0xba, 0x64, 0x5d, 0x2e, 0x37, + 0x1f, 0x44, 0x53, 0x59, 0xf7, 0x1e, 0x32, 0x81, 0x78, 0xb7, 0xb7, 0x91, + 0xcf, 0xab, 0x9d, 0xa2, 0xb9, 0x1f, 0xc7, 0x8a, 0x06, 0x73, 0xf2, 0xfe, + 0x60, 0x53, 0xe4, 0x44, 0xb9, 0xb3, 0x66, 0xeb, 0xc5, 0x7a, 0x84, 0xe0, + 0x88, 0xd9, 0x20, 0x1d, 0xb6, 0x0e, 0x7f, 0x5c, 0xd6, 0x4c, 0xd3, 0x4b, + 0x3b, 0x97, 0x9a, 0x46, 0x77, 0x3d, 0x59, 0x8e, 0x4d, 0x4d, 0x6d, 0xa6, + 0x5f, 0x5d, 0x36, 0x21, 0xb5, 0x95, 0xfd, 0xf6, 0x56, 0xbd, 0xaf, 0x82, + 0xb5, 0x39, 0xf0, 0x65, 0xf2, 0xe0, 0x1d, 0xf7, 0x1c, 0xd5, 0x59, 0x22, + 0x6e, 0xd9, 0xcf, 0x7e, 0xb4, 0xf8, 0x62, 0x92, 0x77, 0x54, 0x85, 0x1a, + 0x47, 0x27, 0x01, 0x51, 0x72, 0x4d, 0x77, 0x76, 0x3e, 0x06, 0xb1, 0x87, + 0x0d, 0x75, 0x23, 0xdc, 0x37, 0xf7, 0x73, 0xb5, 0x7f, 0x4a, 0xdf, 0xb4, + 0xb0, 0xb6, 0xb2, 0x4d, 0xb6, 0xf0, 0x24, 0x43, 0xfd, 0x91, 0xcd, 0x31, + 0x1c, 0x3e, 0x95, 0xe0, 0xab, 0xcb, 0xa2, 0xb2, 0x5e, 0x1f, 0xb3, 0x47, + 0xdd, 0x7a, 0xb1, 0xff, 0x00, 0x0a, 0xec, 0x74, 0xbd, 0x16, 0xcb, 0x4a, + 0x4c, 0x5b, 0x44, 0x03, 0x63, 0x97, 0x3c, 0xb1, 0xfc, 0x6b, 0x44, 0x0a, + 0x31, 0x40, 0x08, 0x07, 0xe9, 0x4e, 0xa4, 0xa5, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x02, 0x8a, 0x28, + 0xa0, 0x02, 0x8a, 0x28, 0xa0, 0x06, 0x90, 0x0a, 0x90, 0x79, 0x15, 0xc8, + 0xeb, 0xde, 0x0f, 0x4b, 0x89, 0x9a, 0xe3, 0x4f, 0x61, 0x1c, 0x8f, 0xc9, + 0x88, 0xf0, 0x1b, 0xe9, 0xe9, 0x5d, 0x79, 0xaa, 0x13, 0x4d, 0x8b, 0xd5, + 0x1f, 0xc2, 0xbd, 0x69, 0xa5, 0x72, 0x64, 0xec, 0x8f, 0x2e, 0xbc, 0xb2, + 0xb9, 0xb1, 0x98, 0xc3, 0x75, 0x0b, 0x42, 0xc3, 0x8e, 0x47, 0x5f, 0xa1, + 0xe9, 0x56, 0xf4, 0xad, 0x6a, 0x7d, 0x2d, 0x5d, 0x63, 0x8d, 0x24, 0x49, + 0x39, 0x2a, 0xf5, 0xe9, 0x77, 0x96, 0x56, 0xf7, 0xf0, 0x18, 0xae, 0x22, + 0x57, 0x42, 0x3a, 0x11, 0xc8, 0xae, 0x07, 0xc4, 0x7e, 0x19, 0x97, 0x4a, + 0x3e, 0x7d, 0xbe, 0x65, 0xb6, 0x39, 0xfa, 0xa7, 0xb1, 0xff, 0x00, 0x1a, + 0x13, 0xb0, 0xda, 0xb9, 0x47, 0x4e, 0xb2, 0xba, 0xd4, 0xef, 0x26, 0x96, + 0xd0, 0xac, 0x72, 0x26, 0x18, 0x90, 0xd8, 0xc6, 0x6b, 0xab, 0xd0, 0x7c, + 0x47, 0x27, 0xda, 0x7f, 0xb3, 0xb5, 0x5f, 0xdd, 0xdc, 0x8f, 0x95, 0x1c, + 0xff, 0x00, 0x17, 0xa0, 0x3e, 0xfe, 0xf5, 0xc6, 0x58, 0xdf, 0xcf, 0xa7, + 0xcf, 0xe6, 0xdb, 0xb6, 0x1b, 0x18, 0x20, 0xf2, 0x0f, 0xe1, 0x4f, 0x96, + 0x5b, 0xad, 0x5e, 0xf9, 0xa4, 0x08, 0x5e, 0x66, 0x00, 0x81, 0x18, 0xe8, + 0x05, 0x1a, 0x58, 0x5a, 0xa6, 0x7a, 0xde, 0x68, 0xae, 0x67, 0xc2, 0x9a, + 0xcc, 0x97, 0x51, 0x9b, 0x1b, 0xc0, 0xcb, 0x73, 0x0a, 0x8c, 0x6e, 0xea, + 0xcb, 0xfe, 0x35, 0xd3, 0x52, 0x28, 0x5a, 0x28, 0xa2, 0x80, 0x0a, 0x4c, + 0x52, 0xd1, 0x40, 0x09, 0x46, 0x29, 0x68, 0xa0, 0x08, 0x25, 0xb6, 0x86, + 0x61, 0x89, 0x61, 0x47, 0x1e, 0x8c, 0xa0, 0xd5, 0x0b, 0x8f, 0x0e, 0x69, + 0x77, 0x1c, 0x3d, 0x94, 0x63, 0x3f, 0xdd, 0xf9, 0x7f, 0x95, 0x6a, 0xd2, + 0x1a, 0x00, 0xe6, 0x67, 0xf0, 0x46, 0x96, 0xc0, 0xb2, 0x99, 0xa1, 0x1f, + 0xec, 0xbf, 0x03, 0xf3, 0x15, 0xc5, 0x6b, 0x42, 0xc2, 0xca, 0xe7, 0xc8, + 0xb0, 0x9e, 0x4b, 0x80, 0xa7, 0xe6, 0x72, 0x00, 0x03, 0xd8, 0x57, 0x43, + 0xe3, 0x4f, 0x10, 0xc9, 0x2c, 0xad, 0xa7, 0x5a, 0x49, 0xb6, 0x35, 0x38, + 0x99, 0xd4, 0xf2, 0x7d, 0xab, 0x8e, 0x5b, 0x74, 0x03, 0x04, 0x93, 0x40, + 0x0c, 0xfb, 0x4f, 0xaa, 0xfe, 0xb4, 0xbf, 0x69, 0x1f, 0xdd, 0x35, 0x28, + 0x86, 0x31, 0xfc, 0x22, 0x9c, 0x11, 0x47, 0xf0, 0x8f, 0xca, 0x80, 0x21, + 0xfb, 0x50, 0xfe, 0xe9, 0xa3, 0xed, 0x23, 0xfb, 0xa6, 0xa6, 0xda, 0xa3, + 0xb0, 0xa5, 0xc0, 0xf4, 0x14, 0x01, 0x0f, 0xda, 0x47, 0xf7, 0x1a, 0x93, + 0xed, 0x23, 0xfb, 0x8d, 0x53, 0xe3, 0xd8, 0x51, 0x81, 0xe9, 0x40, 0x10, + 0xfd, 0xa1, 0x7f, 0xba, 0x69, 0x3e, 0xd2, 0x3f, 0xba, 0x6a, 0x7c, 0x0f, + 0x4a, 0x69, 0x55, 0x3d, 0x54, 0x7e, 0x54, 0x01, 0x0f, 0xda, 0x47, 0xf7, + 0x7f, 0x5a, 0x3e, 0xd4, 0x3f, 0xbb, 0x52, 0x98, 0xd0, 0xf5, 0x51, 0x51, + 0xb5, 0xaa, 0x9f, 0xba, 0x48, 0xa0, 0x09, 0xec, 0xa5, 0xb6, 0x92, 0xe5, + 0x16, 0xee, 0x47, 0x8a, 0x12, 0x70, 0x5d, 0x46, 0x48, 0xae, 0xde, 0xcb, + 0xc1, 0x7a, 0x6c, 0xf0, 0xc7, 0x32, 0xdd, 0xcd, 0x3a, 0xb8, 0x0c, 0x19, + 0x08, 0x00, 0x8a, 0xf3, 0xc7, 0x85, 0xd3, 0xb6, 0x47, 0xb5, 0x6f, 0xf8, + 0x5b, 0xc4, 0x72, 0x68, 0xb7, 0x22, 0x29, 0x99, 0x9a, 0xce, 0x43, 0xf3, + 0xae, 0x7e, 0xe1, 0xfe, 0xf0, 0xfe, 0xa2, 0x80, 0x3b, 0x78, 0x3c, 0x23, + 0xa4, 0x43, 0xcf, 0xd9, 0x77, 0x9f, 0x57, 0x62, 0x6b, 0x46, 0x1d, 0x2e, + 0xca, 0xdf, 0xfd, 0x4d, 0xac, 0x4b, 0xf4, 0x5a, 0xb1, 0x14, 0x89, 0x2c, + 0x6b, 0x24, 0x6c, 0x19, 0x18, 0x64, 0x11, 0xd0, 0x8a, 0x7d, 0x00, 0x22, + 0xa8, 0x51, 0x80, 0x00, 0xfa, 0x0a, 0x5a, 0x29, 0x68, 0x01, 0x31, 0x45, + 0x2d, 0x14, 0x00, 0x94, 0xb4, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, + 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, + 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, + 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, + 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, + 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, + 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, + 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x08, 0x7a, 0x56, 0x3c, 0x8c, + 0x4c, 0x8c, 0x4f, 0x5c, 0xd6, 0xc1, 0xa8, 0x5a, 0xd6, 0x26, 0x7d, 0xc5, + 0x79, 0xaa, 0x8c, 0x92, 0x33, 0x9c, 0x5c, 0xb6, 0x1d, 0x09, 0x2d, 0x0a, + 0x93, 0xd7, 0x14, 0xb2, 0x46, 0xb2, 0xc6, 0xc8, 0xea, 0x19, 0x58, 0x60, + 0x83, 0xde, 0x9c, 0x00, 0x50, 0x00, 0xe9, 0x4b, 0x52, 0x5a, 0x3c, 0xcf, + 0xc5, 0x3a, 0x1b, 0x69, 0x17, 0xbe, 0x64, 0x40, 0x9b, 0x69, 0x8f, 0xc8, + 0x7f, 0xbb, 0xea, 0x2a, 0xa6, 0x89, 0xa8, 0x0d, 0x36, 0xfd, 0x67, 0x65, + 0x2d, 0x19, 0x05, 0x5b, 0x1d, 0x79, 0xef, 0x5e, 0x93, 0xab, 0xe9, 0xf1, + 0xea, 0x76, 0x12, 0x5b, 0x4a, 0x06, 0x18, 0x7c, 0xa7, 0xd1, 0xbb, 0x57, + 0x95, 0xdd, 0x5b, 0xc9, 0x69, 0x73, 0x24, 0x13, 0xa9, 0x59, 0x11, 0x8a, + 0x91, 0xee, 0x3a, 0x7e, 0x14, 0x2d, 0x01, 0xab, 0xa3, 0x5f, 0x58, 0xd6, + 0x62, 0x7d, 0x5a, 0xde, 0xee, 0xc0, 0x9f, 0x32, 0x21, 0xf3, 0x31, 0x04, + 0x64, 0xfd, 0x2b, 0xbb, 0xd1, 0xb5, 0x38, 0xb5, 0x6b, 0x04, 0xb8, 0x8c, + 0xe1, 0x8f, 0x0e, 0x99, 0xe5, 0x5b, 0xb8, 0xaf, 0x2f, 0xd3, 0xe3, 0x86, + 0x5b, 0xe8, 0x63, 0x9c, 0xe2, 0x26, 0x60, 0x1a, 0xba, 0xab, 0x9b, 0x7f, + 0xf8, 0x47, 0x08, 0xbf, 0xb0, 0x2c, 0x23, 0x04, 0x2c, 0xd0, 0xb3, 0x7c, + 0xae, 0x3e, 0xa6, 0xaa, 0xcd, 0xea, 0x4d, 0xd4, 0x74, 0x3b, 0x6a, 0x5a, + 0xce, 0xd2, 0x75, 0x6b, 0x6d, 0x56, 0xdc, 0x4b, 0x6d, 0x26, 0x71, 0xf7, + 0x90, 0xfd, 0xe5, 0x3e, 0xe2, 0xb4, 0x07, 0x4a, 0x92, 0xc5, 0xa2, 0x92, + 0x96, 0x80, 0x0a, 0x28, 0xa4, 0xa0, 0x05, 0xac, 0x5f, 0x14, 0xea, 0xbf, + 0xd9, 0x5a, 0x53, 0x32, 0x36, 0x26, 0x94, 0xec, 0x8c, 0x7b, 0x9e, 0xff, + 0x00, 0x85, 0x6c, 0x1f, 0x4a, 0xf3, 0xcf, 0x1d, 0xde, 0x9b, 0x8d, 0x64, + 0x40, 0xa7, 0xe4, 0xb7, 0x4c, 0x1f, 0xa9, 0xeb, 0x40, 0x1c, 0xf3, 0x12, + 0x49, 0x24, 0xe4, 0x93, 0x92, 0x69, 0x28, 0xa4, 0xa0, 0x02, 0x96, 0x92, + 0x8a, 0x00, 0x5a, 0x29, 0x28, 0xa0, 0x05, 0xa2, 0x8f, 0x6f, 0xca, 0x8f, + 0x5e, 0x3a, 0x50, 0x01, 0x49, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0xb5, 0x14, 0xb0, 0xee, 0x19, 0x5f, 0xbc, 0x3f, 0x5a, 0x92, 0x8a, 0x00, + 0xec, 0x7e, 0x1f, 0x6b, 0x26, 0x58, 0x5f, 0x4d, 0x98, 0xfc, 0xf1, 0x8d, + 0xd1, 0x7b, 0x8e, 0xe2, 0xbb, 0x61, 0xd0, 0x57, 0x90, 0x69, 0x57, 0x6d, + 0xa6, 0xeb, 0x16, 0xf7, 0x6b, 0xc0, 0x57, 0x01, 0xc7, 0xb1, 0xeb, 0x5e, + 0xba, 0xac, 0x19, 0x43, 0x29, 0xc8, 0x23, 0x22, 0x80, 0x1f, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x02, 0x51, 0x4b, + 0x45, 0x00, 0x25, 0x2d, 0x14, 0x50, 0x02, 0x57, 0x1d, 0xe3, 0x9d, 0x1b, + 0xcc, 0x4f, 0xed, 0x28, 0x57, 0xe6, 0x41, 0xb6, 0x50, 0x07, 0x51, 0xeb, + 0x5d, 0x95, 0x42, 0xf1, 0xac, 0xa8, 0xc8, 0xea, 0x19, 0x58, 0x10, 0x41, + 0x19, 0x04, 0x1e, 0xa2, 0x80, 0x3c, 0x77, 0xa1, 0xab, 0x12, 0x5e, 0xdc, + 0x4b, 0x6e, 0xb0, 0x49, 0x3b, 0xb4, 0x4b, 0xd1, 0x49, 0xad, 0x4f, 0x13, + 0xe8, 0x0f, 0xa4, 0x5d, 0x19, 0x62, 0x52, 0x6d, 0x64, 0x3f, 0x2b, 0x0f, + 0xe1, 0x3e, 0x86, 0xb0, 0xe8, 0x15, 0x8d, 0xdd, 0x17, 0x47, 0xd4, 0x5a, + 0x15, 0xbf, 0xb3, 0xb8, 0x58, 0x5c, 0xe7, 0x6f, 0x24, 0x6e, 0xf6, 0x35, + 0xb1, 0x69, 0xe3, 0x49, 0x6d, 0x65, 0x36, 0xfa, 0xad, 0xb9, 0x59, 0x10, + 0xe0, 0xba, 0x7f, 0x85, 0x73, 0x7a, 0x6e, 0xb7, 0x77, 0xa7, 0x21, 0x8e, + 0x16, 0x47, 0x8b, 0x39, 0xd9, 0x20, 0xc8, 0xcf, 0xaf, 0x5a, 0xab, 0x79, + 0x75, 0x2d, 0xed, 0xd3, 0xcf, 0x31, 0x05, 0xdb, 0xd3, 0xb7, 0xd2, 0xa9, + 0xda, 0xc2, 0x57, 0xbe, 0xa7, 0xa5, 0xdb, 0x78, 0x8f, 0x4b, 0xb9, 0x1f, + 0x25, 0xe4, 0x60, 0xfa, 0x31, 0xc5, 0x5d, 0x17, 0xd6, 0xcc, 0x32, 0x2e, + 0x23, 0x23, 0xfd, 0xe1, 0x5c, 0x6e, 0x99, 0x6f, 0xa2, 0x4d, 0xa7, 0x26, + 0xf3, 0x08, 0x7d, 0xa3, 0xcc, 0x2e, 0xdb, 0x58, 0x1e, 0xe7, 0x26, 0xb9, + 0x8b, 0xb5, 0x89, 0x2e, 0xa5, 0x5b, 0x76, 0x2d, 0x08, 0x63, 0xb0, 0xfa, + 0x8a, 0x1a, 0xb2, 0x05, 0x2b, 0xb3, 0xd5, 0x65, 0xd5, 0xac, 0x21, 0x1f, + 0xbc, 0xbc, 0x85, 0x7e, 0xae, 0x2b, 0x32, 0xef, 0xc6, 0x3a, 0x5d, 0xb0, + 0x3b, 0x65, 0x69, 0x4f, 0x40, 0x23, 0x15, 0xcf, 0xe8, 0x96, 0x3a, 0x44, + 0xba, 0x6a, 0x3c, 0xcd, 0x1b, 0xcc, 0x47, 0xef, 0x3c, 0xc6, 0xc1, 0x53, + 0xfd, 0x2b, 0x07, 0x53, 0x8e, 0xde, 0x3b, 0xf9, 0x92, 0xd1, 0xf7, 0x40, + 0x0f, 0xca, 0x41, 0xcf, 0xe5, 0xed, 0xcd, 0x26, 0x81, 0x4a, 0xee, 0xc7, + 0x4d, 0x7f, 0xe2, 0x8d, 0x56, 0xea, 0xca, 0x49, 0xec, 0xad, 0x44, 0x16, + 0xe0, 0x1f, 0xde, 0x39, 0xf9, 0xab, 0x92, 0x96, 0x69, 0x2e, 0x64, 0x69, + 0xa6, 0x73, 0x24, 0x8f, 0xcb, 0x33, 0x75, 0x26, 0xaf, 0xcd, 0xae, 0xca, + 0x74, 0x36, 0xd3, 0xde, 0x24, 0x2b, 0x80, 0xa1, 0xc1, 0xc1, 0xc6, 0x7d, + 0x2b, 0x34, 0x70, 0x00, 0xa1, 0xd8, 0x6a, 0xfd, 0x42, 0x8a, 0x28, 0xfc, + 0x69, 0x0c, 0x50, 0x09, 0x38, 0x03, 0x27, 0x38, 0x03, 0xde, 0x9d, 0x24, + 0x4f, 0x0c, 0x85, 0x25, 0x46, 0x47, 0x5e, 0x08, 0x61, 0x82, 0x2b, 0xa2, + 0xf0, 0x3e, 0x98, 0xb7, 0x9a, 0x83, 0xdc, 0xc8, 0x01, 0x48, 0x30, 0x54, + 0x1f, 0xef, 0x1f, 0xfe, 0xb0, 0x35, 0x9f, 0xe2, 0xaf, 0xf9, 0x18, 0xaf, + 0x07, 0xfb, 0x74, 0x01, 0x95, 0x45, 0x14, 0x50, 0x06, 0xf7, 0x83, 0x2d, + 0xa2, 0xb9, 0xd7, 0x00, 0x99, 0x12, 0x45, 0x58, 0xc9, 0xc3, 0x0c, 0x8c, + 0xd6, 0x87, 0x8f, 0xac, 0xe0, 0x83, 0xec, 0xd3, 0x45, 0x12, 0xc6, 0xce, + 0x4a, 0xb6, 0xd1, 0x8c, 0xd5, 0x3f, 0x01, 0x7f, 0xc8, 0x78, 0xff, 0x00, + 0xd7, 0x26, 0xad, 0x3f, 0x88, 0x9f, 0xea, 0xac, 0xff, 0x00, 0xde, 0x6f, + 0xe4, 0x28, 0x03, 0x8a, 0xa2, 0x96, 0x92, 0x80, 0x0a, 0x71, 0x52, 0xa7, + 0x0c, 0x08, 0x3e, 0x84, 0x74, 0xa1, 0x3f, 0xd6, 0x2f, 0xfb, 0xc2, 0xba, + 0xff, 0x00, 0x1c, 0xe9, 0x0a, 0x89, 0x1e, 0xa5, 0x0a, 0x81, 0xd1, 0x25, + 0x03, 0xf4, 0x3f, 0xd3, 0xf2, 0xa0, 0x0e, 0x3e, 0x92, 0x8f, 0xc3, 0x1e, + 0xd4, 0x50, 0x00, 0x40, 0x65, 0x22, 0xbd, 0x67, 0x45, 0x97, 0xce, 0xd2, + 0x2d, 0x24, 0x3d, 0xe2, 0x51, 0xf9, 0x71, 0x5e, 0x4e, 0x7a, 0x7e, 0x15, + 0xe9, 0xfe, 0x14, 0x6d, 0xde, 0x1d, 0xb4, 0xf6, 0x52, 0x3f, 0x53, 0x40, + 0x1b, 0x14, 0x52, 0x52, 0xd0, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, + 0x50, 0x04, 0x17, 0x16, 0xf1, 0x5c, 0xc0, 0xf1, 0x4c, 0x81, 0xe3, 0x71, + 0x86, 0x56, 0xe9, 0x5c, 0x06, 0xbf, 0xe1, 0x49, 0xf4, 0xf2, 0xd7, 0x16, + 0x80, 0xcd, 0x6d, 0xe8, 0x07, 0xcd, 0x1f, 0xe1, 0xdc, 0x7d, 0x2b, 0xd1, + 0xa9, 0xa4, 0x03, 0xc1, 0x1f, 0x5a, 0x00, 0xf1, 0xae, 0x9f, 0x85, 0x15, + 0xe9, 0x3a, 0xb7, 0x85, 0x6c, 0x35, 0x22, 0x64, 0x11, 0x98, 0x66, 0x3f, + 0xc6, 0x9f, 0xd4, 0x57, 0x2f, 0x7f, 0xe0, 0xad, 0x46, 0xdc, 0x93, 0x6f, + 0xb2, 0xe2, 0x3e, 0xa3, 0x07, 0x04, 0x7e, 0x06, 0x80, 0x39, 0xda, 0x2a, + 0xe4, 0xda, 0x55, 0xf4, 0x07, 0x12, 0xda, 0xcc, 0x3d, 0x72, 0x95, 0x55, + 0xa2, 0x90, 0x75, 0x89, 0xc7, 0xe0, 0x68, 0x01, 0x28, 0xa7, 0x08, 0xdf, + 0xb2, 0x39, 0xff, 0x00, 0x80, 0x9a, 0x92, 0x3b, 0x2b, 0x99, 0x7f, 0xd5, + 0xdb, 0xca, 0xc7, 0xd9, 0x4d, 0x00, 0x56, 0x9b, 0xee, 0x1f, 0xa8, 0xa7, + 0x76, 0x15, 0xa2, 0x3c, 0x37, 0xaa, 0xcd, 0x13, 0x32, 0xda, 0x48, 0xa0, + 0x72, 0x77, 0x71, 0xc5, 0x67, 0x90, 0x41, 0xda, 0x7a, 0x8e, 0xb4, 0x00, + 0x94, 0x51, 0x41, 0xa0, 0x0f, 0x47, 0xf0, 0x35, 0xb8, 0x87, 0x40, 0x56, + 0xc6, 0x0c, 0xb2, 0x33, 0x9f, 0xd0, 0x7f, 0x4a, 0xe3, 0x7c, 0x55, 0xff, + 0x00, 0x23, 0x15, 0xe7, 0xfb, 0xff, 0x00, 0xd2, 0xbb, 0xcf, 0x0b, 0x00, + 0x3c, 0x39, 0x67, 0x8f, 0xee, 0x1f, 0xe6, 0x6b, 0x83, 0xf1, 0x57, 0xfc, + 0x8c, 0x57, 0x9f, 0xef, 0xff, 0x00, 0x4a, 0x00, 0xca, 0xa2, 0x8a, 0x28, + 0x03, 0xa2, 0xf0, 0x17, 0xfc, 0x87, 0xcf, 0xfd, 0x72, 0x6a, 0xd3, 0xf8, + 0x8b, 0xfe, 0xaa, 0xcb, 0xfd, 0xe6, 0xfe, 0x42, 0xb3, 0x3c, 0x05, 0xff, + 0x00, 0x21, 0xe3, 0xff, 0x00, 0x5c, 0x9a, 0xb4, 0xbe, 0x22, 0xff, 0x00, + 0xab, 0xb3, 0xfa, 0xb7, 0xf2, 0x14, 0x01, 0xc5, 0xd1, 0x45, 0x14, 0x00, + 0xa9, 0xf7, 0xc7, 0xfb, 0xc2, 0xbd, 0x53, 0x5c, 0xb7, 0x17, 0x5a, 0x15, + 0xc4, 0x24, 0x67, 0x31, 0x64, 0x7e, 0x03, 0x3f, 0xd2, 0xbc, 0xad, 0x3f, + 0xd6, 0x2f, 0xfb, 0xc2, 0xbd, 0x7e, 0x60, 0x1a, 0xd1, 0xc1, 0xe8, 0x63, + 0x23, 0xf4, 0xa0, 0x0f, 0x20, 0x1c, 0x8a, 0x4a, 0x73, 0x8c, 0x48, 0xe3, + 0xd1, 0x88, 0xfd, 0x69, 0xb4, 0x00, 0x76, 0xaf, 0x4e, 0xf0, 0x8f, 0xfc, + 0x8b, 0x76, 0xbf, 0xee, 0x9f, 0xe6, 0x6b, 0xcc, 0x7b, 0x57, 0xa7, 0x78, + 0x47, 0xfe, 0x45, 0xbb, 0x5f, 0xf7, 0x4f, 0xf3, 0x34, 0x01, 0xb5, 0x45, + 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, + 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, + 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, + 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, + 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, + 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, + 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, + 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, + 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x49, + 0x4b, 0x45, 0x00, 0x14, 0x98, 0xa5, 0xa2, 0x80, 0x1a, 0x46, 0x47, 0x22, + 0x9a, 0x62, 0x8c, 0xf5, 0x8d, 0x4f, 0xe0, 0x2a, 0x4a, 0x28, 0x02, 0x21, + 0x0c, 0x63, 0xa4, 0x6a, 0x3f, 0xe0, 0x22, 0x9e, 0x14, 0x0e, 0x80, 0x52, + 0xd2, 0xd0, 0x04, 0x17, 0x5f, 0xf1, 0xe9, 0x37, 0xfb, 0x87, 0xf9, 0x57, + 0x90, 0x37, 0xde, 0x3f, 0x53, 0x5e, 0xbf, 0x75, 0xff, 0x00, 0x1e, 0x93, + 0x7f, 0xb8, 0x7f, 0x95, 0x79, 0x03, 0xfd, 0xe3, 0xf5, 0x34, 0x00, 0xda, + 0x0d, 0x14, 0x1a, 0x00, 0xf5, 0x2f, 0x0b, 0xff, 0x00, 0xc8, 0xbb, 0x65, + 0xfe, 0xe7, 0xf5, 0x35, 0xc1, 0x78, 0xab, 0xfe, 0x46, 0x2b, 0xcf, 0xf7, + 0xff, 0x00, 0xa5, 0x77, 0xbe, 0x17, 0xff, 0x00, 0x91, 0x76, 0xcb, 0xfd, + 0xcf, 0xea, 0x6b, 0x82, 0xf1, 0x57, 0xfc, 0x8c, 0x57, 0x9f, 0xef, 0xff, + 0x00, 0x4a, 0x00, 0xca, 0xa2, 0x8a, 0x28, 0x03, 0xa2, 0xf0, 0x17, 0xfc, + 0x87, 0x8f, 0xfd, 0x72, 0x6a, 0xd2, 0xf8, 0x8b, 0xfe, 0xae, 0xcf, 0xea, + 0xdf, 0xc8, 0x56, 0x6f, 0x80, 0xbf, 0xe4, 0x3c, 0x7f, 0xeb, 0x93, 0x56, + 0x97, 0xc4, 0x5f, 0xf5, 0x76, 0x7f, 0x56, 0xfe, 0x42, 0x80, 0x38, 0xba, + 0x28, 0xa2, 0x80, 0x15, 0x3f, 0xd6, 0x2f, 0xfb, 0xc2, 0xbd, 0x86, 0x4f, + 0xf8, 0xf6, 0x6f, 0xf7, 0x0f, 0xf2, 0xaf, 0x1e, 0x4f, 0xf5, 0x8b, 0xfe, + 0xf0, 0xaf, 0x61, 0x93, 0xfe, 0x3d, 0x9b, 0xfd, 0xc3, 0xfc, 0xa8, 0x03, + 0xc8, 0x25, 0xff, 0x00, 0x5d, 0x27, 0xfb, 0xcd, 0xfc, 0xe9, 0x94, 0xf9, + 0xbf, 0xd7, 0x49, 0xfe, 0xf3, 0x7f, 0x3a, 0x65, 0x00, 0x1d, 0xab, 0xd3, + 0xbc, 0x23, 0xff, 0x00, 0x22, 0xdd, 0xaf, 0xfb, 0xa7, 0xf9, 0x9a, 0xf3, + 0x1e, 0xd5, 0xe9, 0xde, 0x11, 0xff, 0x00, 0x91, 0x6e, 0xd7, 0xfd, 0xd3, + 0xfc, 0xcd, 0x00, 0x6d, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, + 0x51, 0x49, 0x4b, 0x40, 0x05, 0x14, 0x94, 0x50, 0x04, 0x37, 0x5f, 0xf1, + 0xe9, 0x37, 0xfb, 0x87, 0xf9, 0x57, 0x90, 0x3f, 0xde, 0x3f, 0x53, 0x5e, + 0xbf, 0x77, 0xff, 0x00, 0x1e, 0xb3, 0x7f, 0xb8, 0xdf, 0xca, 0xbc, 0x81, + 0xfe, 0xf1, 0xfa, 0x9a, 0x00, 0x6d, 0x06, 0x8a, 0x28, 0x03, 0xd4, 0xbc, + 0x2f, 0xff, 0x00, 0x22, 0xf5, 0x9f, 0xfb, 0x9f, 0xd4, 0xd7, 0x05, 0xe2, + 0xaf, 0xf9, 0x18, 0xaf, 0x3f, 0xdf, 0xfe, 0x95, 0xdc, 0xf8, 0x6a, 0xe2, + 0x34, 0xf0, 0xfd, 0x98, 0x2d, 0xc8, 0x4f, 0xea, 0x6b, 0x85, 0xf1, 0x43, + 0x07, 0xf1, 0x0d, 0xd9, 0x1d, 0x0b, 0xd1, 0x61, 0x5d, 0x19, 0x74, 0x0e, + 0xb4, 0x51, 0x40, 0xce, 0x8f, 0xc0, 0x5f, 0xf2, 0x1e, 0x3f, 0xf5, 0xc9, + 0xab, 0x4b, 0xe2, 0x2f, 0xfa, 0xbb, 0x2f, 0xf7, 0x9b, 0xf9, 0x0a, 0xca, + 0xf0, 0x4c, 0xa2, 0x2d, 0x6c, 0xb1, 0x19, 0xfd, 0xd3, 0x55, 0xff, 0x00, + 0x1f, 0x4e, 0x27, 0x8e, 0xd3, 0x00, 0x8c, 0x33, 0x7f, 0x21, 0x4e, 0xce, + 0xd7, 0x17, 0x32, 0xbd, 0x8e, 0x42, 0x8a, 0x28, 0xa4, 0x31, 0x53, 0xfd, + 0x62, 0xff, 0x00, 0xbc, 0x2b, 0xd8, 0x64, 0xff, 0x00, 0x8f, 0x66, 0xff, + 0x00, 0x70, 0xff, 0x00, 0x2a, 0xf1, 0xf4, 0xfb, 0xe3, 0xea, 0x3f, 0x9d, + 0x7a, 0xcb, 0x5d, 0xc4, 0x6d, 0xd8, 0x64, 0x8f, 0x90, 0xff, 0x00, 0x2a, + 0x2d, 0x71, 0x36, 0x96, 0xe7, 0x93, 0xcd, 0xfe, 0xba, 0x4f, 0xf7, 0x9b, + 0xf9, 0xd3, 0x29, 0xf2, 0xf3, 0x34, 0x9f, 0xef, 0x1f, 0xe7, 0x4c, 0xa0, + 0x61, 0xda, 0xbd, 0x3f, 0xc2, 0x3f, 0xf2, 0x2e, 0x5a, 0xff, 0x00, 0xba, + 0x7f, 0x99, 0xaf, 0x30, 0xed, 0x5e, 0x9f, 0xe1, 0x1f, 0xf9, 0x17, 0x2d, + 0x7f, 0xdd, 0x3f, 0xcc, 0xd0, 0x06, 0xc5, 0x2d, 0x25, 0x14, 0x00, 0xb4, + 0x52, 0x52, 0xd0, 0x01, 0x45, 0x25, 0x2d, 0x00, 0x14, 0x51, 0x45, 0x00, + 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, + 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, + 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, + 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, + 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, + 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, + 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, + 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x45, 0x00, 0x14, 0x51, 0x49, 0x40, + 0x05, 0x14, 0xc7, 0x95, 0x50, 0x7c, 0xcc, 0x05, 0x56, 0x92, 0xf9, 0x47, + 0x11, 0x8c, 0xfb, 0xd3, 0x49, 0xb2, 0x5c, 0x92, 0x2e, 0x1a, 0x6b, 0x48, + 0xa9, 0xf7, 0x98, 0x0a, 0xcd, 0x92, 0xea, 0x57, 0xfe, 0x2d, 0xbf, 0x4a, + 0x88, 0xe4, 0xf7, 0x27, 0xeb, 0x56, 0xa9, 0xb3, 0x37, 0x59, 0x74, 0x34, + 0x5e, 0xf6, 0x25, 0xe0, 0x1d, 0xc7, 0xda, 0xa1, 0x6b, 0xf3, 0xfc, 0x2b, + 0x8a, 0xa9, 0x45, 0x52, 0x82, 0x33, 0x75, 0x64, 0x3e, 0xea, 0xf2, 0x56, + 0xb5, 0x97, 0xa0, 0xf9, 0x0f, 0xf2, 0xaf, 0x30, 0x6f, 0xbc, 0x79, 0xee, + 0x6b, 0xd1, 0xee, 0x7f, 0xe3, 0xde, 0x5f, 0xf7, 0x4d, 0x79, 0xbb, 0x75, + 0x3f, 0x5a, 0x99, 0xa4, 0x8d, 0x29, 0x49, 0xbd, 0xc4, 0xa2, 0x8a, 0x2b, + 0x33, 0x63, 0xbf, 0xd0, 0x7f, 0xe4, 0x0b, 0x6b, 0x9f, 0xee, 0x7f, 0xec, + 0xc6, 0xb9, 0x0f, 0x10, 0x7f, 0xc8, 0x6e, 0xe7, 0xfd, 0xfa, 0xeb, 0xf4, + 0x2f, 0xf9, 0x02, 0xda, 0xff, 0x00, 0xb9, 0xfd, 0x4d, 0x72, 0x3e, 0x20, + 0xff, 0x00, 0x90, 0xd5, 0xd7, 0xfb, 0xf5, 0xac, 0xbe, 0x13, 0x0a, 0x7f, + 0x13, 0x33, 0xa8, 0xa2, 0x8e, 0xf5, 0x91, 0xb9, 0xb5, 0xe1, 0x1f, 0xf9, + 0x0b, 0xff, 0x00, 0xdb, 0x36, 0xab, 0xde, 0x34, 0xfb, 0x96, 0xdf, 0x56, + 0xfe, 0x42, 0xa8, 0xf8, 0x47, 0xfe, 0x42, 0xff, 0x00, 0xf6, 0xcd, 0xaa, + 0xf7, 0x8d, 0x3e, 0xed, 0xb7, 0xd5, 0xbf, 0x90, 0xad, 0x17, 0xc2, 0x62, + 0xfe, 0x33, 0x97, 0xa2, 0x8a, 0x2b, 0x33, 0x61, 0xc9, 0xf7, 0x87, 0xd4, + 0x57, 0xa4, 0x1f, 0xf5, 0x07, 0xfd, 0xc3, 0xfc, 0xab, 0xcd, 0xd7, 0xef, + 0x0f, 0xa8, 0xaf, 0x48, 0x3f, 0xea, 0x1b, 0xfd, 0xc3, 0xfc, 0xab, 0x58, + 0x18, 0xd5, 0xe8, 0x79, 0xc4, 0x9f, 0xeb, 0x5f, 0xfd, 0xe3, 0xfc, 0xe9, + 0x94, 0xf9, 0x3f, 0xd6, 0xbf, 0xfb, 0xc7, 0xf9, 0xd3, 0x2b, 0x36, 0x6a, + 0xb6, 0x0a, 0xef, 0xfc, 0x33, 0x34, 0x89, 0xa1, 0xdb, 0x85, 0x62, 0x00, + 0x07, 0x8f, 0xc4, 0xd7, 0x01, 0x5d, 0xe7, 0x87, 0x3f, 0xe4, 0x0b, 0x6f, + 0xf4, 0x3f, 0xcc, 0xd5, 0x41, 0x5d, 0x99, 0xd5, 0x6d, 0x2d, 0x0d, 0xa4, + 0xbd, 0x94, 0x01, 0x9c, 0x1a, 0x91, 0x6f, 0xc7, 0xf1, 0x29, 0xaa, 0x63, + 0xa5, 0x15, 0xa7, 0x22, 0x66, 0x3e, 0xd2, 0x48, 0xd2, 0x4b, 0xa8, 0x9f, + 0xf8, 0xb1, 0xf5, 0xa9, 0x43, 0x02, 0x32, 0x08, 0x35, 0x91, 0xfc, 0xe9, + 0x43, 0x32, 0x9c, 0xab, 0x10, 0x7d, 0x73, 0x52, 0xe9, 0xf6, 0x2d, 0x56, + 0x7d, 0x4d, 0x8a, 0x2b, 0x32, 0x3b, 0xc9, 0x54, 0xf2, 0x43, 0x0f, 0x71, + 0x56, 0xa3, 0xbd, 0x8d, 0xf8, 0x3f, 0x29, 0xa8, 0x71, 0x68, 0xd1, 0x54, + 0x8b, 0x2c, 0xd2, 0xd3, 0x15, 0x83, 0x0c, 0x83, 0x9a, 0x75, 0x49, 0xa0, + 0xb4, 0x52, 0x52, 0xd0, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, + 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, + 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, + 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, + 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, + 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, + 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, + 0x01, 0x45, 0x14, 0x50, 0x01, 0x49, 0x9a, 0x33, 0x55, 0x6e, 0x6e, 0x84, + 0x43, 0x6a, 0x9c, 0xb1, 0xfd, 0x28, 0x4a, 0xe2, 0x6d, 0x25, 0xa9, 0x3c, + 0x92, 0xac, 0x63, 0x2c, 0x71, 0x54, 0xa5, 0xbd, 0x66, 0x38, 0x8f, 0x81, + 0x55, 0xdd, 0xda, 0x43, 0x97, 0x39, 0xa4, 0xad, 0x94, 0x12, 0xdc, 0xe7, + 0x95, 0x46, 0xf6, 0x06, 0x25, 0xcf, 0xcc, 0x49, 0xa2, 0x8a, 0x2a, 0xcc, + 0xb7, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa4, 0x66, 0x0a, 0xa5, 0x89, + 0x00, 0x0e, 0xb9, 0x3d, 0x28, 0x02, 0xae, 0xa9, 0x3a, 0xdb, 0x69, 0xb3, + 0xca, 0xe7, 0x18, 0x5e, 0x2b, 0xcf, 0x7a, 0xf2, 0x7b, 0xd6, 0xdf, 0x89, + 0x75, 0x95, 0xbe, 0x93, 0xec, 0xd6, 0xed, 0x98, 0x11, 0xb9, 0x6f, 0xef, + 0x9a, 0xc3, 0xef, 0x58, 0xcd, 0xdd, 0x9d, 0x34, 0xa3, 0x64, 0x14, 0x7a, + 0xd1, 0x57, 0x34, 0x8b, 0x17, 0xbf, 0xd4, 0x23, 0x85, 0x46, 0x57, 0x70, + 0x2d, 0xec, 0xb5, 0x2b, 0x53, 0x46, 0xec, 0xae, 0x76, 0xfa, 0x42, 0x18, + 0xf4, 0xab, 0x64, 0x23, 0x04, 0x46, 0x0f, 0xe7, 0xcd, 0x71, 0xbe, 0x20, + 0xff, 0x00, 0x90, 0xd5, 0xd7, 0xfb, 0xf5, 0xde, 0x05, 0x0a, 0x00, 0x1f, + 0x74, 0x0c, 0x0a, 0xe0, 0xfc, 0x41, 0xff, 0x00, 0x21, 0xab, 0xaf, 0xf7, + 0xeb, 0x49, 0xec, 0x61, 0x49, 0xde, 0x4c, 0xce, 0xa2, 0x8a, 0x2b, 0x23, + 0xa0, 0xda, 0xf0, 0x8f, 0xfc, 0x85, 0xbf, 0xed, 0x99, 0xab, 0xde, 0x34, + 0xfb, 0xb6, 0xdf, 0x56, 0xfe, 0x42, 0xa8, 0xf8, 0x4b, 0xfe, 0x42, 0xff, + 0x00, 0xf6, 0xcc, 0xd5, 0xdf, 0x1a, 0x7d, 0xdb, 0x5f, 0xab, 0x7f, 0x2a, + 0xd1, 0x7c, 0x26, 0x2f, 0xe3, 0x39, 0x8a, 0x28, 0xa2, 0xb3, 0x36, 0x1c, + 0xbf, 0x78, 0x7e, 0x15, 0xe9, 0x40, 0x66, 0x3c, 0x7b, 0x62, 0xbc, 0xd5, + 0x7e, 0xf8, 0xfa, 0x8a, 0xf4, 0xa5, 0xfb, 0xa2, 0xb5, 0xa6, 0x61, 0x5b, + 0xa1, 0xe7, 0x17, 0x48, 0x63, 0xba, 0x95, 0x08, 0xc1, 0x57, 0x35, 0x15, + 0x6d, 0xf8, 0xaa, 0xc0, 0xdb, 0x6a, 0x1f, 0x68, 0x51, 0xfb, 0xa9, 0xb9, + 0x27, 0xd1, 0xab, 0x17, 0xf9, 0xfa, 0x56, 0x6d, 0x59, 0x9b, 0x45, 0xdd, + 0x21, 0x2b, 0xaf, 0xf0, 0x7d, 0xe0, 0x96, 0xc6, 0x4b, 0x66, 0x38, 0x78, + 0x9b, 0x23, 0xfd, 0xd3, 0x5c, 0x85, 0x5b, 0xd3, 0x2f, 0xdf, 0x4e, 0xbc, + 0x49, 0xd3, 0xa0, 0xe1, 0xd7, 0xb1, 0x53, 0xd6, 0x9c, 0x5d, 0x99, 0x33, + 0x8f, 0x32, 0xb1, 0xe8, 0x63, 0x90, 0x33, 0xde, 0x8a, 0x82, 0xd2, 0xea, + 0x1b, 0xcb, 0x75, 0x9a, 0x17, 0x0c, 0x84, 0x77, 0x3c, 0x83, 0xef, 0x53, + 0xd6, 0xe7, 0x26, 0xdb, 0x85, 0x14, 0x51, 0x40, 0x05, 0x06, 0x8a, 0x28, + 0x10, 0xe8, 0xe5, 0x78, 0xc8, 0x2a, 0x48, 0xab, 0x50, 0xdf, 0x03, 0xf2, + 0xc8, 0x31, 0xee, 0x2a, 0x9d, 0x15, 0x2e, 0x29, 0x97, 0x19, 0xb8, 0x9a, + 0xea, 0xc1, 0x86, 0x41, 0xc8, 0xa7, 0x56, 0x54, 0x33, 0x49, 0x11, 0xe0, + 0xf1, 0xe9, 0x5a, 0x10, 0x4c, 0xb2, 0xae, 0x54, 0xfe, 0x15, 0x94, 0xa3, + 0x63, 0xa2, 0x13, 0x52, 0x26, 0xa2, 0x92, 0x96, 0xa4, 0xd0, 0x28, 0xa2, + 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, + 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, + 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, + 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, + 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, + 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, + 0x8a, 0x00, 0x28, 0xa2, 0x92, 0x80, 0x20, 0xb9, 0x9b, 0xc9, 0x8c, 0x9f, + 0xe2, 0x3d, 0x2b, 0x34, 0x92, 0x58, 0xb1, 0xe4, 0x9e, 0xb5, 0x62, 0xfd, + 0xb3, 0x36, 0xde, 0xc0, 0x55, 0x7a, 0xda, 0x0a, 0xca, 0xe7, 0x2d, 0x49, + 0x5d, 0xd8, 0x28, 0xa2, 0x8a, 0xb3, 0x30, 0xa2, 0x8a, 0x28, 0x00, 0xa2, + 0x8a, 0x28, 0x03, 0x37, 0x59, 0xd6, 0x62, 0xd2, 0x91, 0x41, 0x53, 0x24, + 0xcf, 0xf7, 0x56, 0xb9, 0x3d, 0x43, 0x5a, 0xbb, 0xd4, 0x32, 0xb2, 0x49, + 0xb2, 0x3e, 0xd1, 0xa7, 0x03, 0xf1, 0xf5, 0xae, 0x97, 0x5e, 0xd0, 0x8e, + 0xa9, 0x22, 0xcb, 0x1c, 0x81, 0x24, 0x55, 0xdb, 0xf3, 0x56, 0x23, 0x78, + 0x62, 0xe9, 0x4f, 0xcd, 0x24, 0x63, 0xf0, 0xac, 0xe4, 0xa4, 0xde, 0x86, + 0xd0, 0x71, 0x4b, 0x53, 0x1b, 0xf0, 0xc5, 0x27, 0x6a, 0xdd, 0x4f, 0x0c, + 0x39, 0x3f, 0xbc, 0x9d, 0x40, 0xf6, 0x19, 0xab, 0xb6, 0xfe, 0x1f, 0xb4, + 0x84, 0x82, 0xfb, 0xa5, 0x23, 0xb3, 0x74, 0xa1, 0x52, 0x93, 0x34, 0x75, + 0x22, 0x8e, 0x7e, 0xc3, 0x4f, 0x9f, 0x50, 0x90, 0x24, 0x11, 0x92, 0x3b, + 0xb9, 0xe8, 0x05, 0x76, 0xba, 0x3e, 0x95, 0x16, 0x95, 0x6d, 0xe5, 0xa6, + 0x1a, 0x56, 0xfb, 0xef, 0x8e, 0x4d, 0x49, 0x6e, 0xe9, 0x12, 0x84, 0x11, + 0xaa, 0x28, 0xe8, 0x54, 0x62, 0xad, 0x03, 0xb8, 0x64, 0x1e, 0xb5, 0x6a, + 0x1c, 0xa6, 0x33, 0xa8, 0xe4, 0x29, 0xe9, 0x5c, 0x0e, 0xbe, 0x73, 0xad, + 0xdc, 0xe3, 0xfb, 0xf5, 0xde, 0x3b, 0x2c, 0x68, 0x5e, 0x43, 0xb5, 0x14, + 0x65, 0x8f, 0xa0, 0xaf, 0x39, 0xbd, 0x9f, 0xed, 0x57, 0x92, 0xcf, 0x8e, + 0x24, 0x72, 0xc3, 0xf1, 0xa8, 0xa8, 0x55, 0x1d, 0xc8, 0x68, 0xa2, 0x96, + 0xb2, 0x3a, 0x0d, 0xcf, 0x07, 0xa1, 0x3a, 0xab, 0xb7, 0x65, 0x4a, 0xb9, + 0xe3, 0x45, 0x26, 0x2b, 0x66, 0x1d, 0x32, 0xc3, 0xf4, 0xa9, 0x3c, 0x1f, + 0x64, 0xd1, 0xdb, 0x49, 0x72, 0xc3, 0x06, 0x53, 0xf2, 0xfd, 0x2a, 0xef, + 0x89, 0x2c, 0xcd, 0xee, 0x95, 0x26, 0xc0, 0x0c, 0x91, 0x7c, 0xeb, 0xef, + 0xc7, 0x23, 0xf2, 0xad, 0x52, 0xf7, 0x4e, 0x77, 0x25, 0xce, 0x70, 0xb4, + 0x52, 0xd2, 0x56, 0x47, 0x40, 0xa0, 0xe1, 0x81, 0xf4, 0xaf, 0x4a, 0x89, + 0x83, 0x44, 0x8c, 0x3a, 0x11, 0x9a, 0xf3, 0x4a, 0xef, 0x3c, 0x3f, 0x74, + 0x2e, 0xf4, 0x98, 0x9b, 0x39, 0x74, 0x1b, 0x5b, 0xd8, 0xd6, 0x94, 0xcc, + 0x6b, 0x2d, 0x0b, 0x57, 0x96, 0x90, 0xde, 0xdb, 0x34, 0x13, 0x28, 0x65, + 0x6f, 0xcc, 0x1f, 0x5a, 0xe2, 0xf5, 0x4d, 0x12, 0xe3, 0x4e, 0x76, 0x24, + 0x19, 0x21, 0x3d, 0x1d, 0x46, 0x7f, 0x3a, 0xee, 0xf3, 0x51, 0x4d, 0x2a, + 0x80, 0x53, 0x86, 0xf5, 0x07, 0xa5, 0x68, 0xe1, 0xcc, 0x65, 0x19, 0xb8, + 0x9e, 0x71, 0x45, 0x75, 0xf7, 0x7a, 0x2d, 0x9d, 0xd3, 0x16, 0xf2, 0xfc, + 0xb6, 0x3f, 0xdd, 0xe2, 0xb3, 0xe4, 0xf0, 0xc1, 0xff, 0x00, 0x96, 0x53, + 0xff, 0x00, 0xdf, 0x42, 0xa1, 0xd2, 0x92, 0x36, 0x55, 0x53, 0x32, 0x2c, + 0xb5, 0x0b, 0x8d, 0x3e, 0x4d, 0xf6, 0xf2, 0x94, 0x24, 0xe7, 0x1d, 0x41, + 0xfc, 0x2b, 0xac, 0xd0, 0xf5, 0xd5, 0xd4, 0xd8, 0xc3, 0x2a, 0x2c, 0x77, + 0x00, 0x64, 0x63, 0xa3, 0x56, 0x21, 0xf0, 0xcd, 0xc1, 0x38, 0x59, 0x50, + 0xd6, 0xb6, 0x85, 0xa0, 0x36, 0x9f, 0x71, 0xf6, 0x89, 0x9c, 0x34, 0x80, + 0x61, 0x54, 0x76, 0xa2, 0x2a, 0x49, 0x93, 0x37, 0x06, 0x8d, 0xd1, 0xd2, + 0x96, 0x8a, 0x2b, 0x43, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, + 0x00, 0xa7, 0x43, 0x2b, 0x44, 0xe1, 0x87, 0xe3, 0x4d, 0xa2, 0x86, 0xae, + 0x09, 0xd9, 0xdc, 0xd7, 0x47, 0x0e, 0xa1, 0x87, 0x43, 0x4f, 0xaa, 0x9a, + 0x7b, 0x13, 0x11, 0x53, 0xd8, 0xd5, 0xba, 0xe7, 0x6a, 0xce, 0xc7, 0x64, + 0x5d, 0xd5, 0xc2, 0x8a, 0x28, 0xa4, 0x50, 0x51, 0x45, 0x14, 0x00, 0x51, + 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, + 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, + 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, + 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, + 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x51, + 0x45, 0x14, 0x00, 0x51, 0x45, 0x14, 0x00, 0x52, 0x52, 0xd1, 0x40, 0x19, + 0xd7, 0xe8, 0x44, 0xa1, 0xbb, 0x1a, 0xad, 0x5a, 0x77, 0x11, 0x09, 0x63, + 0x2b, 0xdf, 0xb5, 0x66, 0x32, 0xb2, 0x36, 0xd7, 0x18, 0x22, 0xb6, 0x83, + 0xba, 0xb1, 0xcb, 0x52, 0x36, 0x77, 0x0a, 0x28, 0xa2, 0xac, 0xcc, 0x28, + 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x29, 0x19, 0x43, 0x8c, 0x11, + 0x4b, 0x45, 0x30, 0x29, 0xca, 0x85, 0x1b, 0x1d, 0xa9, 0x95, 0x6a, 0x75, + 0xdd, 0x19, 0xf5, 0x02, 0xaa, 0x8f, 0x7a, 0xd1, 0x3b, 0x80, 0xb4, 0xe5, + 0xb8, 0x5b, 0x74, 0x2f, 0x23, 0x62, 0x30, 0x32, 0x49, 0xa6, 0xd5, 0x4d, + 0x52, 0x09, 0x2e, 0x2c, 0x25, 0x8a, 0x1f, 0xbe, 0x47, 0x03, 0xd6, 0x89, + 0x6c, 0x0b, 0x73, 0x17, 0x5a, 0xf1, 0x13, 0xdf, 0x2b, 0x43, 0x6e, 0x3c, + 0xb8, 0x0f, 0x7e, 0xee, 0x3d, 0xfd, 0x2b, 0x14, 0xfd, 0x38, 0xa9, 0x5a, + 0xd2, 0xe1, 0x5b, 0x06, 0xde, 0x5c, 0xfb, 0x29, 0xa9, 0xe0, 0xd1, 0xef, + 0x67, 0x23, 0x10, 0xb0, 0x07, 0xfb, 0xdc, 0x57, 0x1d, 0xa4, 0xd9, 0xd6, + 0xb9, 0x62, 0x8a, 0x55, 0xa7, 0xa2, 0x68, 0xf2, 0x6a, 0x73, 0x86, 0x6f, + 0x96, 0xdd, 0x4e, 0x5d, 0xcf, 0x7f, 0x61, 0x5a, 0x36, 0x5e, 0x1b, 0x8e, + 0x3c, 0x3d, 0xcb, 0xef, 0x3f, 0xdd, 0x5e, 0x9f, 0x8d, 0x6e, 0x41, 0xb6, + 0x0d, 0xab, 0x1a, 0x85, 0x51, 0xc6, 0x07, 0x40, 0x2b, 0x48, 0xd2, 0x7b, + 0xb2, 0x27, 0x55, 0x5a, 0xc8, 0xb7, 0x12, 0x24, 0x51, 0x2c, 0x71, 0x8c, + 0x2a, 0x8c, 0x01, 0xe8, 0x29, 0xe7, 0x91, 0xcd, 0x20, 0x21, 0x86, 0x47, + 0xa5, 0x2d, 0x59, 0xce, 0x72, 0x1e, 0x20, 0xd0, 0x5a, 0xdd, 0xda, 0xea, + 0xd9, 0x73, 0x13, 0x1c, 0xba, 0x0f, 0xe0, 0x3f, 0xe1, 0x58, 0x15, 0xe8, + 0x73, 0xc9, 0xb8, 0x94, 0x1d, 0x07, 0x51, 0x58, 0xf7, 0xfa, 0x15, 0xbd, + 0xd1, 0x2f, 0x17, 0xee, 0x64, 0x3d, 0x48, 0x1c, 0x1a, 0x99, 0x53, 0xbe, + 0xa8, 0xde, 0x15, 0x6d, 0xa3, 0x39, 0x4a, 0xbd, 0xa4, 0x6a, 0xb3, 0x69, + 0x73, 0x6f, 0x8c, 0x6e, 0x8d, 0x87, 0xcc, 0x84, 0xe3, 0x77, 0xbf, 0xd6, + 0xa4, 0xb8, 0xd0, 0xaf, 0x20, 0x24, 0x84, 0x12, 0x8e, 0xc5, 0x6a, 0xa2, + 0xd8, 0xdd, 0x33, 0x6d, 0x5b, 0x79, 0x09, 0xee, 0x76, 0xd6, 0x5c, 0xb2, + 0x46, 0xad, 0xc5, 0xa3, 0xb7, 0x83, 0x52, 0x86, 0xfa, 0xd8, 0x4b, 0x6e, + 0x4e, 0xd3, 0xc1, 0x07, 0xaa, 0xd2, 0xd6, 0x6e, 0x81, 0x63, 0x2d, 0x9d, + 0xab, 0x79, 0xc3, 0x6b, 0x48, 0xdb, 0xb6, 0xff, 0x00, 0x76, 0xb4, 0xeb, + 0xaa, 0x1b, 0x6a, 0x72, 0x49, 0x24, 0xf4, 0x12, 0x94, 0x02, 0xcc, 0x00, + 0xeb, 0xda, 0x8a, 0x9a, 0xd9, 0x3a, 0xb1, 0xaa, 0xbd, 0x84, 0x49, 0x1c, + 0x4a, 0x83, 0xa7, 0x35, 0x20, 0xa0, 0x51, 0x59, 0xde, 0xe0, 0x14, 0x51, + 0x45, 0x20, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, 0xa2, 0x80, 0x0a, 0x28, + 0xa9, 0x20, 0x84, 0xcc, 0xe0, 0x01, 0xc7, 0x73, 0x43, 0x76, 0x1a, 0x4d, + 0xbb, 0x22, 0xdd, 0x8a, 0x95, 0x8b, 0x71, 0xfe, 0x23, 0x56, 0xe9, 0xaa, + 0xa1, 0x40, 0x03, 0xa0, 0xa7, 0x57, 0x3b, 0x77, 0x67, 0x64, 0x55, 0x95, + 0x82, 0x8a, 0x28, 0xa4, 0x30, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, + 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, + 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, + 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, + 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, + 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, + 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x01, 0x0d, 0x41, 0x71, + 0x6e, 0xb3, 0x0f, 0x46, 0xec, 0x6a, 0x7a, 0x28, 0xd8, 0x4d, 0x27, 0xb9, + 0x93, 0x2c, 0x2d, 0x13, 0x61, 0xf8, 0x1e, 0xbe, 0xb4, 0xca, 0xd6, 0x64, + 0x57, 0x18, 0x60, 0x08, 0xaa, 0xb2, 0xd8, 0xf7, 0x88, 0xe3, 0xd8, 0xd6, + 0xb1, 0x9a, 0xea, 0x61, 0x2a, 0x4d, 0x6a, 0x8a, 0x74, 0x53, 0x9e, 0x37, + 0x8c, 0x9d, 0xca, 0x45, 0x34, 0x56, 0x97, 0x31, 0xb3, 0x5b, 0x85, 0x14, + 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x0d, 0x7f, 0xba, 0x7e, 0x95, 0x4b, + 0xb9, 0xab, 0xad, 0xf7, 0x4f, 0xd0, 0xd5, 0x2a, 0xd2, 0x20, 0x2d, 0x25, + 0x2d, 0x15, 0x40, 0x5a, 0x45, 0xdd, 0x00, 0x1e, 0xa2, 0xaa, 0x91, 0x82, + 0x47, 0xbd, 0x5b, 0x8b, 0xfd, 0x52, 0xd5, 0x59, 0x06, 0x25, 0x6f, 0xad, + 0x4c, 0x77, 0x01, 0x28, 0xa2, 0x8a, 0xa0, 0x2c, 0x5b, 0x1c, 0xc7, 0x8e, + 0xe2, 0xa4, 0x73, 0xb5, 0x09, 0xf6, 0xa8, 0x6d, 0x8e, 0x37, 0x0a, 0x7d, + 0xc1, 0xc4, 0x47, 0xde, 0xb3, 0x6b, 0x50, 0x2a, 0x9e, 0xb9, 0xf5, 0xa5, + 0xa4, 0xa5, 0xab, 0x00, 0xab, 0x30, 0x2e, 0x23, 0xcf, 0x72, 0x2a, 0xb5, + 0x5c, 0x51, 0x84, 0xc7, 0xa0, 0xa5, 0x20, 0x29, 0x9e, 0x49, 0xfa, 0xd1, + 0x41, 0xea, 0x7e, 0xb4, 0x55, 0x20, 0x0a, 0xb5, 0x6f, 0xfe, 0xa8, 0x55, + 0x5a, 0xb3, 0x07, 0xfa, 0xa1, 0x53, 0x2d, 0x80, 0x96, 0x8a, 0x28, 0xac, + 0xc0, 0x28, 0xa2, 0x8a, 0x00, 0x28, 0xa2, 0x8a, 0x00, 0x29, 0x3e, 0x95, + 0x2c, 0x76, 0xf2, 0x48, 0x78, 0x04, 0x0f, 0x53, 0x57, 0x21, 0xb3, 0x44, + 0x39, 0x7f, 0x99, 0xaa, 0x5c, 0x92, 0x2e, 0x34, 0xdb, 0x2a, 0xc3, 0x6c, + 0xf2, 0x9c, 0xf4, 0x5f, 0x5a, 0xd0, 0x8e, 0x35, 0x8d, 0x70, 0xa3, 0x14, + 0xe0, 0x29, 0x6b, 0x27, 0x26, 0xce, 0x88, 0xc1, 0x44, 0x5a, 0x28, 0xa2, + 0xa4, 0xb0, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, + 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, + 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, + 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, + 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, + 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, + 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, 0x28, 0x00, 0xa2, 0x8a, + 0x28, 0x01, 0x28, 0xa5, 0xa2, 0x80, 0x18, 0x54, 0x30, 0xc1, 0x19, 0xa8, + 0x64, 0xb3, 0x8d, 0xfe, 0xee, 0x54, 0xfb, 0x55, 0x8a, 0x29, 0xdd, 0xa1, + 0x38, 0xa7, 0xb9, 0x9d, 0x25, 0x94, 0x8b, 0x9d, 0xbc, 0x8a, 0x85, 0xa3, + 0x75, 0xfb, 0xca, 0x41, 0xfa, 0x56, 0xb9, 0xa4, 0x20, 0x1e, 0xbc, 0xfe, + 0x15, 0x4a, 0x6c, 0xcd, 0xd2, 0x4c, 0xc7, 0xa2, 0xb4, 0xda, 0xda, 0x27, + 0xea, 0x83, 0xf0, 0xa8, 0x9a, 0xc1, 0x0f, 0x46, 0x22, 0xaf, 0xda, 0x23, + 0x37, 0x49, 0xad, 0x8c, 0xf6, 0xfb, 0xa7, 0xe9, 0x54, 0xeb, 0x59, 0xec, + 0x24, 0xda, 0x76, 0xb0, 0x39, 0x15, 0x41, 0xb4, 0xfb, 0x94, 0xc9, 0xf2, + 0x89, 0xfa, 0x10, 0x6b, 0x48, 0xcd, 0x10, 0xe1, 0x24, 0x41, 0x45, 0x3c, + 0xc3, 0x2a, 0xf0, 0xd1, 0xb0, 0xfc, 0x29, 0x84, 0x11, 0xd4, 0x62, 0xb4, + 0xba, 0xee, 0x4d, 0x99, 0x6e, 0x2f, 0xf5, 0x4b, 0xf4, 0xaa, 0xd3, 0x7f, + 0xad, 0x6a, 0xb3, 0x17, 0xfa, 0xa1, 0x55, 0xa6, 0x3f, 0xbe, 0x6f, 0xad, + 0x4c, 0x5e, 0xa0, 0x36, 0x8a, 0x28, 0xab, 0x02, 0x5b, 0x5f, 0xbc, 0x7e, + 0x94, 0xfb, 0xaf, 0xb8, 0x3e, 0xb4, 0xcb, 0x5f, 0xbc, 0x7e, 0x94, 0xfb, + 0xaf, 0xb8, 0x3f, 0xde, 0xa8, 0xea, 0x05, 0x7a, 0x28, 0xa2, 0xac, 0x02, + 0xae, 0xf6, 0x1f, 0x4a, 0xa3, 0x9a, 0xba, 0x39, 0x51, 0xf4, 0xa8, 0x90, + 0x14, 0xdb, 0xef, 0x1f, 0xad, 0x14, 0x87, 0xef, 0x1f, 0xad, 0x28, 0x56, + 0x3d, 0x14, 0x9f, 0xc0, 0xd5, 0x5d, 0x06, 0xa2, 0x55, 0xa8, 0x3f, 0xd4, + 0x8a, 0x85, 0x6d, 0x67, 0x7f, 0xbb, 0x0b, 0xfd, 0x71, 0x57, 0xed, 0xec, + 0xa6, 0x11, 0x80, 0xca, 0x17, 0xea, 0x6a, 0x25, 0x25, 0x61, 0xa8, 0xb7, + 0xd0, 0x8e, 0x8a, 0xb6, 0xb6, 0x0d, 0xd5, 0x9c, 0x7e, 0x02, 0xa5, 0x5b, + 0x28, 0x87, 0x52, 0x58, 0xd6, 0x5c, 0xe8, 0xb5, 0x4e, 0x4c, 0xcf, 0x3c, + 0x53, 0xd2, 0x19, 0x24, 0xfb, 0xaa, 0x7f, 0x1a, 0xd1, 0x58, 0x23, 0x4e, + 0x42, 0x01, 0x52, 0x54, 0xba, 0x85, 0xaa, 0x3d, 0xca, 0x09, 0x62, 0xe7, + 0xef, 0xb0, 0x1f, 0x4a, 0xb3, 0x1d, 0xac, 0x71, 0xf4, 0x19, 0x3e, 0xf5, + 0x38, 0xa2, 0xa5, 0xc9, 0xb3, 0x45, 0x08, 0xa0, 0x14, 0x51, 0x4b, 0x52, + 0x58, 0x94, 0xb4, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, 0x40, 0x05, 0x14, 0x51, + 0x40, 0x05, 0x14, 0x51, 0x40, 0x09, 0x45, 0x2d, 0x14, 0x00, 0x94, 0x52, + 0xd1, 0x40, 0x09, 0x45, 0x2d, 0x14, 0x00, 0x86, 0x9a, 0x63, 0x56, 0xea, + 0xa0, 0xd3, 0xa8, 0xa0, 0x56, 0x23, 0x30, 0xc6, 0x47, 0xdc, 0x1f, 0x95, + 0x46, 0xf6, 0x36, 0xef, 0xc9, 0x8c, 0x55, 0x9a, 0x4a, 0x77, 0x61, 0xca, + 0x8a, 0x87, 0x4d, 0xb6, 0x3f, 0xc0, 0x7f, 0x3a, 0x69, 0xd2, 0xed, 0xcf, + 0xf0, 0x91, 0xf8, 0xd5, 0xda, 0x29, 0xf3, 0x3e, 0xe2, 0xe4, 0x89, 0x4d, + 0x34, 0xd8, 0x50, 0xe4, 0x6e, 0xfc, 0xe9, 0x5f, 0x4e, 0x86, 0x41, 0x83, + 0xbb, 0xf3, 0xab, 0x74, 0x51, 0xcc, 0xc3, 0x92, 0x25, 0x0f, 0xec, 0x98, + 0x3f, 0xdb, 0xfc, 0xe9, 0xc3, 0x4b, 0xb7, 0x1f, 0xc2, 0x4f, 0xd4, 0xd5, + 0xda, 0x28, 0xe7, 0x97, 0x70, 0xe4, 0x89, 0x54, 0x69, 0xd6, 0xe3, 0xfe, + 0x59, 0xe7, 0xf1, 0xa9, 0x05, 0xbc, 0x43, 0xf8, 0x07, 0xe5, 0x53, 0x51, + 0x4b, 0x99, 0x87, 0x2a, 0x22, 0x10, 0x44, 0x3a, 0x46, 0xbf, 0x95, 0x3c, + 0x28, 0x1d, 0x00, 0x14, 0xea, 0x29, 0x6a, 0x3b, 0x20, 0xa2, 0x96, 0x8a, + 0x06, 0x25, 0x14, 0xb4, 0x50, 0x02, 0x51, 0x4b, 0x45, 0x00, 0x25, 0x2d, + 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, + 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, + 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, + 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x01, 0x45, + 0x14, 0x50, 0x01, 0x45, 0x14, 0x50, 0x07, 0xff, 0xd9 +}; +unsigned int octo_jpg_len = 14817; + +#endif diff --git a/lib/libesp32/rtsp/JPEGSamples.h b/lib/libesp32/rtsp/JPEGSamples.h index 038b19f7f..be44a57e3 100755 --- a/lib/libesp32/rtsp/JPEGSamples.h +++ b/lib/libesp32/rtsp/JPEGSamples.h @@ -1,11 +1,11 @@ -#pragma once - -#ifndef ARDUINO_ARCH_ESP32 -#define INCLUDE_SIMDATA -#endif - -#ifdef INCLUDE_SIMDATA -extern unsigned const char capture_jpg[]; -extern unsigned const char octo_jpg[]; -extern unsigned int octo_jpg_len, capture_jpg_len; -#endif +#pragma once + +#ifndef ARDUINO_ARCH_ESP32 +#define INCLUDE_SIMDATA +#endif + +#ifdef INCLUDE_SIMDATA +extern unsigned const char capture_jpg[]; +extern unsigned const char octo_jpg[]; +extern unsigned int octo_jpg_len, capture_jpg_len; +#endif diff --git a/lib/libesp32/rtsp/OV2640.cpp b/lib/libesp32/rtsp/OV2640.cpp index f8abe39f9..49177742a 100755 --- a/lib/libesp32/rtsp/OV2640.cpp +++ b/lib/libesp32/rtsp/OV2640.cpp @@ -1,193 +1,193 @@ -#include "OV2640.h" - -#define TAG "OV2640" - -// definitions appropriate for the ESP32-CAM devboard (and most clones) -camera_config_t esp32cam_config{ - - .pin_pwdn = -1, // FIXME: on the TTGO T-Journal I think this is GPIO 0 - .pin_reset = 15, - - .pin_xclk = 27, - - .pin_sscb_sda = 25, - .pin_sscb_scl = 23, - - .pin_d7 = 19, - .pin_d6 = 36, - .pin_d5 = 18, - .pin_d4 = 39, - .pin_d3 = 5, - .pin_d2 = 34, - .pin_d1 = 35, - .pin_d0 = 17, - .pin_vsync = 22, - .pin_href = 26, - .pin_pclk = 21, - .xclk_freq_hz = 20000000, - .ledc_timer = LEDC_TIMER_0, - .ledc_channel = LEDC_CHANNEL_0, - .pixel_format = PIXFORMAT_JPEG, - // .frame_size = FRAMESIZE_UXGA, // needs 234K of framebuffer space - // .frame_size = FRAMESIZE_SXGA, // needs 160K for framebuffer - // .frame_size = FRAMESIZE_XGA, // needs 96K or even smaller FRAMESIZE_SVGA - can work if using only 1 fb - .frame_size = FRAMESIZE_SVGA, - .jpeg_quality = 12, //0-63 lower numbers are higher quality - .fb_count = 2 // if more than one i2s runs in continous mode. Use only with jpeg -}; - -camera_config_t esp32cam_aithinker_config{ - - .pin_pwdn = 32, - .pin_reset = -1, - - .pin_xclk = 0, - - .pin_sscb_sda = 26, - .pin_sscb_scl = 27, - - // Note: LED GPIO is apparently 4 not sure where that goes - // per https://github.com/donny681/ESP32_CAMERA_QR/blob/e4ef44549876457cd841f33a0892c82a71f35358/main/led.c - .pin_d7 = 35, - .pin_d6 = 34, - .pin_d5 = 39, - .pin_d4 = 36, - .pin_d3 = 21, - .pin_d2 = 19, - .pin_d1 = 18, - .pin_d0 = 5, - .pin_vsync = 25, - .pin_href = 23, - .pin_pclk = 22, - .xclk_freq_hz = 20000000, - .ledc_timer = LEDC_TIMER_1, - .ledc_channel = LEDC_CHANNEL_1, - .pixel_format = PIXFORMAT_JPEG, - // .frame_size = FRAMESIZE_UXGA, // needs 234K of framebuffer space - // .frame_size = FRAMESIZE_SXGA, // needs 160K for framebuffer - // .frame_size = FRAMESIZE_XGA, // needs 96K or even smaller FRAMESIZE_SVGA - can work if using only 1 fb - .frame_size = FRAMESIZE_SVGA, - .jpeg_quality = 12, //0-63 lower numbers are higher quality - .fb_count = 2 // if more than one i2s runs in continous mode. Use only with jpeg -}; - -camera_config_t esp32cam_ttgo_t_config{ - - .pin_pwdn = 26, - .pin_reset = -1, - - .pin_xclk = 32, - - .pin_sscb_sda = 13, - .pin_sscb_scl = 12, - - .pin_d7 = 39, - .pin_d6 = 36, - .pin_d5 = 23, - .pin_d4 = 18, - .pin_d3 = 15, - .pin_d2 = 4, - .pin_d1 = 14, - .pin_d0 = 5, - .pin_vsync = 27, - .pin_href = 25, - .pin_pclk = 19, - .xclk_freq_hz = 20000000, - .ledc_timer = LEDC_TIMER_0, - .ledc_channel = LEDC_CHANNEL_0, - .pixel_format = PIXFORMAT_JPEG, - .frame_size = FRAMESIZE_SVGA, - .jpeg_quality = 12, //0-63 lower numbers are higher quality - .fb_count = 2 // if more than one i2s runs in continous mode. Use only with jpeg -}; - -void OV2640::run(void) -{ - if (fb) - //return the frame buffer back to the driver for reuse - esp_camera_fb_return(fb); - - fb = esp_camera_fb_get(); -} - -void OV2640::runIfNeeded(void) -{ - if (!fb) - run(); -} - -int OV2640::getWidth(void) -{ - runIfNeeded(); - return fb->width; -} - -int OV2640::getHeight(void) -{ - runIfNeeded(); - return fb->height; -} - -size_t OV2640::getSize(void) -{ - runIfNeeded(); - if (!fb) - return 0; // FIXME - this shouldn't be possible but apparently the new cam board returns null sometimes? - return fb->len; -} - -uint8_t *OV2640::getfb(void) -{ - runIfNeeded(); - if (!fb) - return NULL; // FIXME - this shouldn't be possible but apparently the new cam board returns null sometimes? - - return fb->buf; -} - -framesize_t OV2640::getFrameSize(void) -{ - return _cam_config.frame_size; -} - -void OV2640::setFrameSize(framesize_t size) -{ - _cam_config.frame_size = size; -} - -pixformat_t OV2640::getPixelFormat(void) -{ - return _cam_config.pixel_format; -} - -void OV2640::setPixelFormat(pixformat_t format) -{ - switch (format) - { - case PIXFORMAT_RGB565: - case PIXFORMAT_YUV422: - case PIXFORMAT_GRAYSCALE: - case PIXFORMAT_JPEG: - _cam_config.pixel_format = format; - break; - default: - _cam_config.pixel_format = PIXFORMAT_GRAYSCALE; - break; - } -} - -esp_err_t OV2640::init(camera_config_t config) -{ - memset(&_cam_config, 0, sizeof(_cam_config)); - memcpy(&_cam_config, &config, sizeof(config)); - - esp_err_t err = esp_camera_init(&_cam_config); - if (err != ESP_OK) - { -// printf("Camera probe failed with error 0x%x", err); - return err; - } - // ESP_ERROR_CHECK(gpio_install_isr_service(0)); - - return ESP_OK; -} +#include "OV2640.h" + +#define TAG "OV2640" + +// definitions appropriate for the ESP32-CAM devboard (and most clones) +camera_config_t esp32cam_config{ + + .pin_pwdn = -1, // FIXME: on the TTGO T-Journal I think this is GPIO 0 + .pin_reset = 15, + + .pin_xclk = 27, + + .pin_sscb_sda = 25, + .pin_sscb_scl = 23, + + .pin_d7 = 19, + .pin_d6 = 36, + .pin_d5 = 18, + .pin_d4 = 39, + .pin_d3 = 5, + .pin_d2 = 34, + .pin_d1 = 35, + .pin_d0 = 17, + .pin_vsync = 22, + .pin_href = 26, + .pin_pclk = 21, + .xclk_freq_hz = 20000000, + .ledc_timer = LEDC_TIMER_0, + .ledc_channel = LEDC_CHANNEL_0, + .pixel_format = PIXFORMAT_JPEG, + // .frame_size = FRAMESIZE_UXGA, // needs 234K of framebuffer space + // .frame_size = FRAMESIZE_SXGA, // needs 160K for framebuffer + // .frame_size = FRAMESIZE_XGA, // needs 96K or even smaller FRAMESIZE_SVGA - can work if using only 1 fb + .frame_size = FRAMESIZE_SVGA, + .jpeg_quality = 12, //0-63 lower numbers are higher quality + .fb_count = 2 // if more than one i2s runs in continous mode. Use only with jpeg +}; + +camera_config_t esp32cam_aithinker_config{ + + .pin_pwdn = 32, + .pin_reset = -1, + + .pin_xclk = 0, + + .pin_sscb_sda = 26, + .pin_sscb_scl = 27, + + // Note: LED GPIO is apparently 4 not sure where that goes + // per https://github.com/donny681/ESP32_CAMERA_QR/blob/e4ef44549876457cd841f33a0892c82a71f35358/main/led.c + .pin_d7 = 35, + .pin_d6 = 34, + .pin_d5 = 39, + .pin_d4 = 36, + .pin_d3 = 21, + .pin_d2 = 19, + .pin_d1 = 18, + .pin_d0 = 5, + .pin_vsync = 25, + .pin_href = 23, + .pin_pclk = 22, + .xclk_freq_hz = 20000000, + .ledc_timer = LEDC_TIMER_1, + .ledc_channel = LEDC_CHANNEL_1, + .pixel_format = PIXFORMAT_JPEG, + // .frame_size = FRAMESIZE_UXGA, // needs 234K of framebuffer space + // .frame_size = FRAMESIZE_SXGA, // needs 160K for framebuffer + // .frame_size = FRAMESIZE_XGA, // needs 96K or even smaller FRAMESIZE_SVGA - can work if using only 1 fb + .frame_size = FRAMESIZE_SVGA, + .jpeg_quality = 12, //0-63 lower numbers are higher quality + .fb_count = 2 // if more than one i2s runs in continous mode. Use only with jpeg +}; + +camera_config_t esp32cam_ttgo_t_config{ + + .pin_pwdn = 26, + .pin_reset = -1, + + .pin_xclk = 32, + + .pin_sscb_sda = 13, + .pin_sscb_scl = 12, + + .pin_d7 = 39, + .pin_d6 = 36, + .pin_d5 = 23, + .pin_d4 = 18, + .pin_d3 = 15, + .pin_d2 = 4, + .pin_d1 = 14, + .pin_d0 = 5, + .pin_vsync = 27, + .pin_href = 25, + .pin_pclk = 19, + .xclk_freq_hz = 20000000, + .ledc_timer = LEDC_TIMER_0, + .ledc_channel = LEDC_CHANNEL_0, + .pixel_format = PIXFORMAT_JPEG, + .frame_size = FRAMESIZE_SVGA, + .jpeg_quality = 12, //0-63 lower numbers are higher quality + .fb_count = 2 // if more than one i2s runs in continous mode. Use only with jpeg +}; + +void OV2640::run(void) +{ + if (fb) + //return the frame buffer back to the driver for reuse + esp_camera_fb_return(fb); + + fb = esp_camera_fb_get(); +} + +void OV2640::runIfNeeded(void) +{ + if (!fb) + run(); +} + +int OV2640::getWidth(void) +{ + runIfNeeded(); + return fb->width; +} + +int OV2640::getHeight(void) +{ + runIfNeeded(); + return fb->height; +} + +size_t OV2640::getSize(void) +{ + runIfNeeded(); + if (!fb) + return 0; // FIXME - this shouldn't be possible but apparently the new cam board returns null sometimes? + return fb->len; +} + +uint8_t *OV2640::getfb(void) +{ + runIfNeeded(); + if (!fb) + return NULL; // FIXME - this shouldn't be possible but apparently the new cam board returns null sometimes? + + return fb->buf; +} + +framesize_t OV2640::getFrameSize(void) +{ + return _cam_config.frame_size; +} + +void OV2640::setFrameSize(framesize_t size) +{ + _cam_config.frame_size = size; +} + +pixformat_t OV2640::getPixelFormat(void) +{ + return _cam_config.pixel_format; +} + +void OV2640::setPixelFormat(pixformat_t format) +{ + switch (format) + { + case PIXFORMAT_RGB565: + case PIXFORMAT_YUV422: + case PIXFORMAT_GRAYSCALE: + case PIXFORMAT_JPEG: + _cam_config.pixel_format = format; + break; + default: + _cam_config.pixel_format = PIXFORMAT_GRAYSCALE; + break; + } +} + +esp_err_t OV2640::init(camera_config_t config) +{ + memset(&_cam_config, 0, sizeof(_cam_config)); + memcpy(&_cam_config, &config, sizeof(config)); + + esp_err_t err = esp_camera_init(&_cam_config); + if (err != ESP_OK) + { +// printf("Camera probe failed with error 0x%x", err); + return err; + } + // ESP_ERROR_CHECK(gpio_install_isr_service(0)); + + return ESP_OK; +} diff --git a/lib/libesp32/rtsp/OV2640.h b/lib/libesp32/rtsp/OV2640.h index 9c69cc930..b9b5706c5 100755 --- a/lib/libesp32/rtsp/OV2640.h +++ b/lib/libesp32/rtsp/OV2640.h @@ -1,43 +1,43 @@ -#ifndef OV2640_H_ -#define OV2640_H_ - -#include -#include -#include -#include "esp_log.h" -#include "esp_attr.h" -#include "esp_camera.h" - -extern camera_config_t esp32cam_config, esp32cam_aithinker_config, esp32cam_ttgo_t_config; - -class OV2640 -{ -public: - OV2640(){ - fb = NULL; - }; - ~OV2640(){ - }; - esp_err_t init(camera_config_t config); - void run(void); - size_t getSize(void); - uint8_t *getfb(void); - int getWidth(void); - int getHeight(void); - framesize_t getFrameSize(void); - pixformat_t getPixelFormat(void); - - void setFrameSize(framesize_t size); - void setPixelFormat(pixformat_t format); - -private: - void runIfNeeded(); // grab a frame if we don't already have one - - // camera_framesize_t _frame_size; - // camera_pixelformat_t _pixel_format; - camera_config_t _cam_config; - - camera_fb_t *fb; -}; - -#endif //OV2640_H_ +#ifndef OV2640_H_ +#define OV2640_H_ + +#include +#include +#include +#include "esp_log.h" +#include "esp_attr.h" +#include "esp_camera.h" + +extern camera_config_t esp32cam_config, esp32cam_aithinker_config, esp32cam_ttgo_t_config; + +class OV2640 +{ +public: + OV2640(){ + fb = NULL; + }; + ~OV2640(){ + }; + esp_err_t init(camera_config_t config); + void run(void); + size_t getSize(void); + uint8_t *getfb(void); + int getWidth(void); + int getHeight(void); + framesize_t getFrameSize(void); + pixformat_t getPixelFormat(void); + + void setFrameSize(framesize_t size); + void setPixelFormat(pixformat_t format); + +private: + void runIfNeeded(); // grab a frame if we don't already have one + + // camera_framesize_t _frame_size; + // camera_pixelformat_t _pixel_format; + camera_config_t _cam_config; + + camera_fb_t *fb; +}; + +#endif //OV2640_H_ diff --git a/lib/libesp32_lvgl/LVGL_assets/fonts/DSEG7/DSEG-LICENSE.txt b/lib/libesp32_lvgl/LVGL_assets/fonts/DSEG7/DSEG-LICENSE.txt index ad4c0bf52..a6c8ffd30 100755 --- a/lib/libesp32_lvgl/LVGL_assets/fonts/DSEG7/DSEG-LICENSE.txt +++ b/lib/libesp32_lvgl/LVGL_assets/fonts/DSEG7/DSEG-LICENSE.txt @@ -1,95 +1,95 @@ -Copyright (c) 2017, keshikan (http://www.keshikan.net), -with Reserved Font Name "DSEG". - - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. +Copyright (c) 2017, keshikan (http://www.keshikan.net), +with Reserved Font Name "DSEG". + + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/lib/libesp32_lvgl/LVGL_assets/fonts/pixel_perfect/Berkelium (GEOS)/FreeLicense.txt b/lib/libesp32_lvgl/LVGL_assets/fonts/pixel_perfect/Berkelium (GEOS)/FreeLicense.txt index e48a09bba..09450f24f 100755 --- a/lib/libesp32_lvgl/LVGL_assets/fonts/pixel_perfect/Berkelium (GEOS)/FreeLicense.txt +++ b/lib/libesp32_lvgl/LVGL_assets/fonts/pixel_perfect/Berkelium (GEOS)/FreeLicense.txt @@ -1,20 +1,20 @@ -KREATIVE SOFTWARE RELAY FONTS FREE USE LICENSE -version 1.2f - -Permission is hereby granted, free of charge, to any person or entity (the "User") obtaining a copy of the included font files (the "Software") produced by Kreative Software, to utilize, display, embed, or redistribute the Software, subject to the following conditions: - -1. The User may not sell copies of the Software for a fee. - -1a. The User may give away copies of the Software free of charge provided this license and any documentation is included verbatim and credit is given to Kreative Korporation or Kreative Software. - -2. The User may not modify, reverse-engineer, or create any derivative works of the Software. - -3. Any Software carrying the following font names or variations thereof is not covered by this license and may not be used under the terms of this license: Jewel Hill, Miss Diode n Friends, This is Beckie's font! - -3a. Any Software carrying a font name ending with the string "Pro CE" is not covered by this license and may not be used under the terms of this license. - -4. This license becomes null and void if any of the above conditions are not met. - -5. Kreative Software reserves the right to change this license at any time without notice. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE SOFTWARE OR FROM OTHER DEALINGS IN THE SOFTWARE. +KREATIVE SOFTWARE RELAY FONTS FREE USE LICENSE +version 1.2f + +Permission is hereby granted, free of charge, to any person or entity (the "User") obtaining a copy of the included font files (the "Software") produced by Kreative Software, to utilize, display, embed, or redistribute the Software, subject to the following conditions: + +1. The User may not sell copies of the Software for a fee. + +1a. The User may give away copies of the Software free of charge provided this license and any documentation is included verbatim and credit is given to Kreative Korporation or Kreative Software. + +2. The User may not modify, reverse-engineer, or create any derivative works of the Software. + +3. Any Software carrying the following font names or variations thereof is not covered by this license and may not be used under the terms of this license: Jewel Hill, Miss Diode n Friends, This is Beckie's font! + +3a. Any Software carrying a font name ending with the string "Pro CE" is not covered by this license and may not be used under the terms of this license. + +4. This license becomes null and void if any of the above conditions are not met. + +5. Kreative Software reserves the right to change this license at any time without notice. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE SOFTWARE OR FROM OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/libesp32_lvgl/LVGL_assets/fonts/pixel_perfect/PrintChar (Apple II Font)/FreeLicense.txt b/lib/libesp32_lvgl/LVGL_assets/fonts/pixel_perfect/PrintChar (Apple II Font)/FreeLicense.txt index e48a09bba..09450f24f 100644 --- a/lib/libesp32_lvgl/LVGL_assets/fonts/pixel_perfect/PrintChar (Apple II Font)/FreeLicense.txt +++ b/lib/libesp32_lvgl/LVGL_assets/fonts/pixel_perfect/PrintChar (Apple II Font)/FreeLicense.txt @@ -1,20 +1,20 @@ -KREATIVE SOFTWARE RELAY FONTS FREE USE LICENSE -version 1.2f - -Permission is hereby granted, free of charge, to any person or entity (the "User") obtaining a copy of the included font files (the "Software") produced by Kreative Software, to utilize, display, embed, or redistribute the Software, subject to the following conditions: - -1. The User may not sell copies of the Software for a fee. - -1a. The User may give away copies of the Software free of charge provided this license and any documentation is included verbatim and credit is given to Kreative Korporation or Kreative Software. - -2. The User may not modify, reverse-engineer, or create any derivative works of the Software. - -3. Any Software carrying the following font names or variations thereof is not covered by this license and may not be used under the terms of this license: Jewel Hill, Miss Diode n Friends, This is Beckie's font! - -3a. Any Software carrying a font name ending with the string "Pro CE" is not covered by this license and may not be used under the terms of this license. - -4. This license becomes null and void if any of the above conditions are not met. - -5. Kreative Software reserves the right to change this license at any time without notice. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE SOFTWARE OR FROM OTHER DEALINGS IN THE SOFTWARE. +KREATIVE SOFTWARE RELAY FONTS FREE USE LICENSE +version 1.2f + +Permission is hereby granted, free of charge, to any person or entity (the "User") obtaining a copy of the included font files (the "Software") produced by Kreative Software, to utilize, display, embed, or redistribute the Software, subject to the following conditions: + +1. The User may not sell copies of the Software for a fee. + +1a. The User may give away copies of the Software free of charge provided this license and any documentation is included verbatim and credit is given to Kreative Korporation or Kreative Software. + +2. The User may not modify, reverse-engineer, or create any derivative works of the Software. + +3. Any Software carrying the following font names or variations thereof is not covered by this license and may not be used under the terms of this license: Jewel Hill, Miss Diode n Friends, This is Beckie's font! + +3a. Any Software carrying a font name ending with the string "Pro CE" is not covered by this license and may not be used under the terms of this license. + +4. This license becomes null and void if any of the above conditions are not met. + +5. Kreative Software reserves the right to change this license at any time without notice. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE SOFTWARE OR FROM OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/libesp32_lvgl/LVGL_assets/fonts/pixel_perfect/Shaston (GSOS)/FreeLicense.txt b/lib/libesp32_lvgl/LVGL_assets/fonts/pixel_perfect/Shaston (GSOS)/FreeLicense.txt index e48a09bba..09450f24f 100644 --- a/lib/libesp32_lvgl/LVGL_assets/fonts/pixel_perfect/Shaston (GSOS)/FreeLicense.txt +++ b/lib/libesp32_lvgl/LVGL_assets/fonts/pixel_perfect/Shaston (GSOS)/FreeLicense.txt @@ -1,20 +1,20 @@ -KREATIVE SOFTWARE RELAY FONTS FREE USE LICENSE -version 1.2f - -Permission is hereby granted, free of charge, to any person or entity (the "User") obtaining a copy of the included font files (the "Software") produced by Kreative Software, to utilize, display, embed, or redistribute the Software, subject to the following conditions: - -1. The User may not sell copies of the Software for a fee. - -1a. The User may give away copies of the Software free of charge provided this license and any documentation is included verbatim and credit is given to Kreative Korporation or Kreative Software. - -2. The User may not modify, reverse-engineer, or create any derivative works of the Software. - -3. Any Software carrying the following font names or variations thereof is not covered by this license and may not be used under the terms of this license: Jewel Hill, Miss Diode n Friends, This is Beckie's font! - -3a. Any Software carrying a font name ending with the string "Pro CE" is not covered by this license and may not be used under the terms of this license. - -4. This license becomes null and void if any of the above conditions are not met. - -5. Kreative Software reserves the right to change this license at any time without notice. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE SOFTWARE OR FROM OTHER DEALINGS IN THE SOFTWARE. +KREATIVE SOFTWARE RELAY FONTS FREE USE LICENSE +version 1.2f + +Permission is hereby granted, free of charge, to any person or entity (the "User") obtaining a copy of the included font files (the "Software") produced by Kreative Software, to utilize, display, embed, or redistribute the Software, subject to the following conditions: + +1. The User may not sell copies of the Software for a fee. + +1a. The User may give away copies of the Software free of charge provided this license and any documentation is included verbatim and credit is given to Kreative Korporation or Kreative Software. + +2. The User may not modify, reverse-engineer, or create any derivative works of the Software. + +3. Any Software carrying the following font names or variations thereof is not covered by this license and may not be used under the terms of this license: Jewel Hill, Miss Diode n Friends, This is Beckie's font! + +3a. Any Software carrying a font name ending with the string "Pro CE" is not covered by this license and may not be used under the terms of this license. + +4. This license becomes null and void if any of the above conditions are not met. + +5. Kreative Software reserves the right to change this license at any time without notice. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF THE USE OR INABILITY TO USE THE SOFTWARE OR FROM OTHER DEALINGS IN THE SOFTWARE. diff --git a/lib/libesp32_lvgl/LVGL_assets/fonts/roboto/ttf/OFL.txt b/lib/libesp32_lvgl/LVGL_assets/fonts/roboto/ttf/OFL.txt index a417551aa..9c48e05a2 100644 --- a/lib/libesp32_lvgl/LVGL_assets/fonts/roboto/ttf/OFL.txt +++ b/lib/libesp32_lvgl/LVGL_assets/fonts/roboto/ttf/OFL.txt @@ -1,93 +1,93 @@ -Copyright 2011 The Roboto Project Authors (https://github.com/googlefonts/roboto-classic) - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -https://openfontlicense.org - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. +Copyright 2011 The Roboto Project Authors (https://github.com/googlefonts/roboto-classic) + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +https://openfontlicense.org + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/lib/libesp32_lvgl/freetype/ChangeLog b/lib/libesp32_lvgl/freetype/ChangeLog index ca58f007a..c9d45451a 100644 --- a/lib/libesp32_lvgl/freetype/ChangeLog +++ b/lib/libesp32_lvgl/freetype/ChangeLog @@ -2041,11 +2041,11 @@ 2022-12-20 Alexei Podtelezhnikov - [psaux] Delay the upem validity assertion. - - Fixes #1194. - - * src/psaux/psft.c (cf2_getUnitsPerEm): Remove the upem assert. + [psaux] Delay the upem validity assertion. + + Fixes #1194. + + * src/psaux/psft.c (cf2_getUnitsPerEm): Remove the upem assert. (cf2_checkTransform): Assert the upem validity after checking the scale. 2022-12-14 David Vanderson @@ -2422,10 +2422,10 @@ 2022-10-03 Alexei Podtelezhnikov - * src/cache/ftccmap.c (FTC_CMapCache_Lookup): Avoid `FT_Set_Charmap`. - - Set charmap aggressively without all validations of `FT_Set_Charmap` - because we take it from the available array and only temporarily. + * src/cache/ftccmap.c (FTC_CMapCache_Lookup): Avoid `FT_Set_Charmap`. + + Set charmap aggressively without all validations of `FT_Set_Charmap` + because we take it from the available array and only temporarily. Even CMap Format 14 will gracefully return 0. 2022-10-03 Alexei Podtelezhnikov @@ -2509,13 +2509,13 @@ 2022-09-22 Alexei Podtelezhnikov - [base] Discard and recreate bitmaps for copying and converting. - - Reusing target bitmaps for copying and converting is permitted. It is, - however, pointless to preserve their content before overwriting. Free- - malloc might be faster than realloc. - - * src/base/ftbitmap.c (FT_Bitmap_Copy, FT_Bitmap_Convert): Free + [base] Discard and recreate bitmaps for copying and converting. + + Reusing target bitmaps for copying and converting is permitted. It is, + however, pointless to preserve their content before overwriting. Free- + malloc might be faster than realloc. + + * src/base/ftbitmap.c (FT_Bitmap_Copy, FT_Bitmap_Convert): Free an old buffer and create a new one. 2022-09-16 Dominik Röttsches @@ -3112,8 +3112,8 @@ 2022-06-16 Alexei Podtelezhnikov - [truetype/GX] Clean up advance adjustment (Brrr). - + [truetype/GX] Clean up advance adjustment (Brrr). + * src/truetype/ttgload.c (load_truetype_glyph): Remove remaining code. 2022-06-16 Ben Wagner @@ -3846,22 +3846,22 @@ 2022-02-09 Alexei Podtelezhnikov - [pshinter] Clear reused mask. - - In PS hinter, memory allocations persist until the module is done. - Therefore, we have to clear reused masks. - + [pshinter] Clear reused mask. + + In PS hinter, memory allocations persist until the module is done. + Therefore, we have to clear reused masks. + * src/pshinter/pshrec.c (ps_mask_table_alloc): Clear reused mask. 2022-02-09 Alexei Podtelezhnikov - [pshinter] Use unsigned indices. - - This reduces casting and eliminates some checks. - - * src/pshinter/pshrec.c (ps_mask_test_bit, ps_mask_table_merge, - ps_dimension_add_t1stem, ps_hints_t1stem3): Updated. - (ps_dimension_add_counter): Updated, unnecessary checks removed. + [pshinter] Use unsigned indices. + + This reduces casting and eliminates some checks. + + * src/pshinter/pshrec.c (ps_mask_test_bit, ps_mask_table_merge, + ps_dimension_add_t1stem, ps_hints_t1stem3): Updated. + (ps_dimension_add_counter): Updated, unnecessary checks removed. 2022-02-08 Alexei Podtelezhnikov @@ -3878,12 +3878,12 @@ 2022-02-08 Alexei Podtelezhnikov - [pshinter] Revise the hint table handling. - - * src/pshinter/pshrec.c (ps_hint_table_ensure): Remove redundant size - check; avoid array zeroing because it is fully initialized when used. - (ps_hint_table_alloc): Fix off-by-one comparison and remove another - zeroing of the array elements. + [pshinter] Revise the hint table handling. + + * src/pshinter/pshrec.c (ps_hint_table_ensure): Remove redundant size + check; avoid array zeroing because it is fully initialized when used. + (ps_hint_table_alloc): Fix off-by-one comparison and remove another + zeroing of the array elements. 2022-02-06 Werner Lemberg @@ -3933,10 +3933,10 @@ 2022-01-31 Alexei Podtelezhnikov - [cache] Partially revert 9870b6c07e2c. - - Fix crashes reported by Werner. - + [cache] Partially revert 9870b6c07e2c. + + Fix crashes reported by Werner. + * src/cache/ftcmru.c (FTC_MruList_New): Use `FT_ALLOC` again. 2022-01-31 Werner Lemberg @@ -4251,9 +4251,9 @@ 2022-01-20 Alexei Podtelezhnikov - [pshinter] Avoid unnecessary zeroing. - - * src/pshinter/pshalgo.c (psh_hint_table_init,psh_glyph_init, + [pshinter] Avoid unnecessary zeroing. + + * src/pshinter/pshalgo.c (psh_hint_table_init,psh_glyph_init, psh_glyph_interpolate_normal_points): Use FT_QNEW_ARRAY. 2022-01-20 Alexei Podtelezhnikov diff --git a/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_bind.cpp b/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_bind.cpp index 5c2a1f671..aff049ac6 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_bind.cpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_bind.cpp @@ -1,153 +1,153 @@ - -#include "lv_gltf_data_internal.hpp" - -#if LV_USE_GLTF -#include "../../../drivers/opengles/lv_opengles_private.h" - -#include - -#include -#include -#include - -#include "lv_gltf_bind.h" - -static uint32_t bind_count = 0; - -void lv_gltf_bind_set(lv_gltf_bind_t * bind, uint8_t channel, float data) -{ - LV_ASSERT_NULL(bind); - LV_ASSERT(channel < LV_GLTF_BIND_MAX_CHANNELS); - - if(data != bind->data[channel]) { - bind->data[channel] = data; - bind->dirty = true; - } -} - -float lv_gltf_bind_get(lv_gltf_bind_t * bind, uint8_t channel) -{ - LV_ASSERT_NULL(bind); - LV_ASSERT(channel < LV_GLTF_BIND_MAX_CHANNELS); - return bind->data[channel]; -} - -void lv_gltf_bind_bind_clean(lv_gltf_bind_t * bind) -{ - bind->dirty = false; -} - -lv_gltf_bind_t * add_by_node(lv_gltf_model_t * gltf_data, fastgltf::Node * node, lv_gltf_bind_prop_t which_prop, - uint32_t data_mask, - lv_gltf_bind_dir_t dir) -{ - if(node == nullptr) { - return nullptr; - } - - lv_gltf_bind_t new_bind; - new_bind.id = bind_count++; - new_bind.prop = which_prop; - new_bind.data_mask = data_mask; - new_bind.data[0] = new_bind.data[1] = new_bind.data[2] = which_prop == LV_GLTF_BIND_PROP_SCALE ? 1.f : 0.f; - new_bind.dir = dir; - new_bind.dirty = true; - new_bind.next_bind = nullptr; - - // Check if an bind already exists for this node - if(gltf_data->node_binds.find(node) != gltf_data->node_binds.end()) { - // Get the existing bind - lv_gltf_bind_t * existingbind = gltf_data->node_binds[node]; - - // Traverse to the end of the linked list of binds - while(existingbind->next_bind != nullptr) - existingbind = existingbind->next_bind; - - lv_array_push_back(&gltf_data->binds, &new_bind); - existingbind->next_bind = (lv_gltf_bind_t *)lv_array_at(&gltf_data->binds, lv_array_size(&gltf_data->binds) - 1); - return existingbind->next_bind; - } - else { - // No existing bind, insert the new one - lv_array_push_back(&gltf_data->binds, &new_bind); - gltf_data->node_binds[node] = (lv_gltf_bind_t *)lv_array_at(&gltf_data->binds, lv_array_size(&gltf_data->binds) - 1); - return gltf_data->node_binds[node]; - } - return nullptr; -} - -lv_gltf_bind_t * lv_gltf_bind_add_by_index(lv_gltf_model_t * data, size_t index, lv_gltf_bind_prop_t which_prop, - uint32_t data_mask, - lv_gltf_bind_dir_t dir) -{ - lv_gltf_data_node_t * node = lv_gltf_data_node_get_by_index(data, index); - if(!node) { - return nullptr; - } - - return add_by_node(data, node->node, which_prop, data_mask, dir); -} - -lv_gltf_bind_t * lv_gltf_bind_add_by_ip(lv_gltf_model_t * data, const char * ip, lv_gltf_bind_prop_t which_prop, - uint32_t data_mask, - lv_gltf_bind_dir_t dir) -{ - lv_gltf_data_node_t * node = lv_gltf_data_node_get_by_ip(data, ip); - if(!node) { - return nullptr; - } - return add_by_node(data, node->node, which_prop, data_mask, dir); -} - -lv_gltf_bind_t * lv_gltf_bind_add_by_path(lv_gltf_model_t * data, const char * path, lv_gltf_bind_prop_t which_prop, - uint32_t data_mask, lv_gltf_bind_dir_t dir) -{ - lv_gltf_data_node_t * node = lv_gltf_data_node_get_by_path(data, path); - - if(!node) { - return nullptr; - } - - return add_by_node(data, node->node, which_prop, data_mask, dir); -} - -lv_result_t lv_gltf_bind_remove(lv_gltf_model_t * gltf_data, lv_gltf_bind_t * bind_to_remove) -{ - for(auto pair : gltf_data->node_binds) { - lv_gltf_bind_t * currentbind = pair.second; - lv_gltf_bind_t * previousbind = nullptr; - - while(currentbind != nullptr) { - if(currentbind->id == bind_to_remove->id) { - // Found the bind to remove - if(previousbind != nullptr) { - // Link the previous bind to the next one - previousbind->next_bind = currentbind->next_bind; - } - else { - gltf_data->node_binds[pair.first] = currentbind->next_bind; - } - - for(uint32_t i = 0; i < lv_array_size(&gltf_data->binds); ++i) { - const lv_gltf_bind_t * current_entry = (const lv_gltf_bind_t *)lv_array_at(&gltf_data->binds, i); - if(current_entry->id == bind_to_remove->id) { - lv_array_remove(&gltf_data->binds, i); - } - } - return LV_RESULT_OK; - } - previousbind = currentbind; - if(currentbind != nullptr) { - if(currentbind->next_bind != nullptr) { - currentbind = currentbind->next_bind; - } - else { - currentbind = nullptr; - } - } - } - } - return LV_RESULT_INVALID; -} - -#endif /*LV_USE_GLTF*/ + +#include "lv_gltf_data_internal.hpp" + +#if LV_USE_GLTF +#include "../../../drivers/opengles/lv_opengles_private.h" + +#include + +#include +#include +#include + +#include "lv_gltf_bind.h" + +static uint32_t bind_count = 0; + +void lv_gltf_bind_set(lv_gltf_bind_t * bind, uint8_t channel, float data) +{ + LV_ASSERT_NULL(bind); + LV_ASSERT(channel < LV_GLTF_BIND_MAX_CHANNELS); + + if(data != bind->data[channel]) { + bind->data[channel] = data; + bind->dirty = true; + } +} + +float lv_gltf_bind_get(lv_gltf_bind_t * bind, uint8_t channel) +{ + LV_ASSERT_NULL(bind); + LV_ASSERT(channel < LV_GLTF_BIND_MAX_CHANNELS); + return bind->data[channel]; +} + +void lv_gltf_bind_bind_clean(lv_gltf_bind_t * bind) +{ + bind->dirty = false; +} + +lv_gltf_bind_t * add_by_node(lv_gltf_model_t * gltf_data, fastgltf::Node * node, lv_gltf_bind_prop_t which_prop, + uint32_t data_mask, + lv_gltf_bind_dir_t dir) +{ + if(node == nullptr) { + return nullptr; + } + + lv_gltf_bind_t new_bind; + new_bind.id = bind_count++; + new_bind.prop = which_prop; + new_bind.data_mask = data_mask; + new_bind.data[0] = new_bind.data[1] = new_bind.data[2] = which_prop == LV_GLTF_BIND_PROP_SCALE ? 1.f : 0.f; + new_bind.dir = dir; + new_bind.dirty = true; + new_bind.next_bind = nullptr; + + // Check if an bind already exists for this node + if(gltf_data->node_binds.find(node) != gltf_data->node_binds.end()) { + // Get the existing bind + lv_gltf_bind_t * existingbind = gltf_data->node_binds[node]; + + // Traverse to the end of the linked list of binds + while(existingbind->next_bind != nullptr) + existingbind = existingbind->next_bind; + + lv_array_push_back(&gltf_data->binds, &new_bind); + existingbind->next_bind = (lv_gltf_bind_t *)lv_array_at(&gltf_data->binds, lv_array_size(&gltf_data->binds) - 1); + return existingbind->next_bind; + } + else { + // No existing bind, insert the new one + lv_array_push_back(&gltf_data->binds, &new_bind); + gltf_data->node_binds[node] = (lv_gltf_bind_t *)lv_array_at(&gltf_data->binds, lv_array_size(&gltf_data->binds) - 1); + return gltf_data->node_binds[node]; + } + return nullptr; +} + +lv_gltf_bind_t * lv_gltf_bind_add_by_index(lv_gltf_model_t * data, size_t index, lv_gltf_bind_prop_t which_prop, + uint32_t data_mask, + lv_gltf_bind_dir_t dir) +{ + lv_gltf_data_node_t * node = lv_gltf_data_node_get_by_index(data, index); + if(!node) { + return nullptr; + } + + return add_by_node(data, node->node, which_prop, data_mask, dir); +} + +lv_gltf_bind_t * lv_gltf_bind_add_by_ip(lv_gltf_model_t * data, const char * ip, lv_gltf_bind_prop_t which_prop, + uint32_t data_mask, + lv_gltf_bind_dir_t dir) +{ + lv_gltf_data_node_t * node = lv_gltf_data_node_get_by_ip(data, ip); + if(!node) { + return nullptr; + } + return add_by_node(data, node->node, which_prop, data_mask, dir); +} + +lv_gltf_bind_t * lv_gltf_bind_add_by_path(lv_gltf_model_t * data, const char * path, lv_gltf_bind_prop_t which_prop, + uint32_t data_mask, lv_gltf_bind_dir_t dir) +{ + lv_gltf_data_node_t * node = lv_gltf_data_node_get_by_path(data, path); + + if(!node) { + return nullptr; + } + + return add_by_node(data, node->node, which_prop, data_mask, dir); +} + +lv_result_t lv_gltf_bind_remove(lv_gltf_model_t * gltf_data, lv_gltf_bind_t * bind_to_remove) +{ + for(auto pair : gltf_data->node_binds) { + lv_gltf_bind_t * currentbind = pair.second; + lv_gltf_bind_t * previousbind = nullptr; + + while(currentbind != nullptr) { + if(currentbind->id == bind_to_remove->id) { + // Found the bind to remove + if(previousbind != nullptr) { + // Link the previous bind to the next one + previousbind->next_bind = currentbind->next_bind; + } + else { + gltf_data->node_binds[pair.first] = currentbind->next_bind; + } + + for(uint32_t i = 0; i < lv_array_size(&gltf_data->binds); ++i) { + const lv_gltf_bind_t * current_entry = (const lv_gltf_bind_t *)lv_array_at(&gltf_data->binds, i); + if(current_entry->id == bind_to_remove->id) { + lv_array_remove(&gltf_data->binds, i); + } + } + return LV_RESULT_OK; + } + previousbind = currentbind; + if(currentbind != nullptr) { + if(currentbind->next_bind != nullptr) { + currentbind = currentbind->next_bind; + } + else { + currentbind = nullptr; + } + } + } + } + return LV_RESULT_INVALID; +} + +#endif /*LV_USE_GLTF*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_bind.h b/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_bind.h index 1210fbf74..f893c8d5d 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_bind.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_bind.h @@ -1,106 +1,106 @@ -#ifndef LV_GLTF_BIND_H -#define LV_GLTF_BIND_H - -#include "lv_gltf_model.h" - -#if LV_USE_GLTF - -#ifdef __cplusplus -extern "C" { -#endif - -typedef enum { - LV_GLTF_BIND_PROP_VISIBILITY, - LV_GLTF_BIND_PROP_POSITION, - LV_GLTF_BIND_PROP_ROTATION, - LV_GLTF_BIND_PROP_SCALE, - LV_GLTF_BIND_PROP_BASE_COLOR, - LV_GLTF_BIND_PROP_ALPHA_FACTOR, - LV_GLTF_BIND_PROP_EMIS_COLOR, - LV_GLTF_BIND_PROP_WORLD_POSITION -} lv_gltf_bind_prop_t; - -#define LV_GLTF_BIND_MAX_CHANNELS 4 -#define LV_GLTF_BIND_CHANNEL_0 (0x01) -#define LV_GLTF_BIND_CHANNEL_1 (0x02) -#define LV_GLTF_BIND_CHANNEL_2 (0x04) -#define LV_GLTF_BIND_CHANNEL_3 (0x08) - -typedef enum { LV_GLTF_BIND_DIR_READ, LV_GLTF_BIND_DIR_WRITE } lv_gltf_bind_dir_t; - -struct _lv_gltf_bind { - struct _lv_gltf_bind * next_bind; - lv_gltf_bind_prop_t prop; - lv_gltf_bind_dir_t dir; - uint32_t id; - uint32_t data_mask; - float data[LV_GLTF_BIND_MAX_CHANNELS]; - bool dirty; -}; - -typedef struct _lv_gltf_bind lv_gltf_bind_t; - -void lv_gltf_bind_set(lv_gltf_bind_t * bind, uint8_t channel, float data); -float lv_gltf_bind_get(lv_gltf_bind_t * bind, uint8_t channel); - -/** - * @brief Reset the dirty flag for a given bind. - * - * @param bind Pointer to the lv_gltf_bind_t to reset the dirty flag for. - */ -void lv_gltf_bind_bind_clean(lv_gltf_bind_t * bind); - -/** - * @brief Add an bind to a GLTF data object by node index. - * - * @param gltf_data Pointer to the lv_gltf_data_t object to which the bind will be added. - * @param nodeIndex The index of the node to bind. - * @param which_prop The property to bind. - * @param data_mask A mask indicating which data fields to bind. - * @return Pointer to the newly created lv_gltf_bind_t object, or NULL if the operation failed. - */ -lv_gltf_bind_t * lv_gltf_bind_add_by_index(lv_gltf_model_t * data, size_t index, lv_gltf_bind_prop_t which_prop, - uint32_t data_mask, - lv_gltf_bind_dir_t dir); - -/** - * @brief Add an bind to a GLTF data object by node IP address. - * - * @param gltf_data Pointer to the lv_gltf_data_t object to which the bind will be added. - * @param nodeIp The IP address of the node to bind. - * @param which_prop The property to bind. - * @param data_mask A mask indicating which data fields to bind. - * @return Pointer to the newly created lv_gltf_bind_t object, or NULL if the operation failed. - */ -lv_gltf_bind_t * lv_gltf_bind_add_by_ip(lv_gltf_model_t * data, const char * node_ip, lv_gltf_bind_prop_t which_prop, - uint32_t data_mask, lv_gltf_bind_dir_t dir); - -/** - * @brief Add an bind to a GLTF data object by node ID. - * - * @param gltf_data Pointer to the lv_gltf_data_t object to which the bind will be added. - * @param nodeId The ID of the node to bind. - * @param which_prop The property to bind. - * @param data_mask A mask indicating which data fields to bind. - * @return Pointer to the newly created lv_gltf_bind_t object, or NULL if the operation failed. - */ -lv_gltf_bind_t * lv_gltf_bind_add_by_path(lv_gltf_model_t * data, const char * path, lv_gltf_bind_prop_t which_prop, - uint32_t data_mask, lv_gltf_bind_dir_t dir); - -/** - * @brief Remove an bind from a GLTF data object. - * - * @param gltf_data Pointer to the lv_gltf_data_t object from which the bind will be removed. - * @param bind The bind to be removed. - * @param which_prop The property to bind. - * @param data_mask A mask indicating which data fields to bind. - * @return True on success, False on failure. - */ -lv_result_t lv_gltf_bind_remove(lv_gltf_model_t * _data, lv_gltf_bind_t * bind); - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_USE_GLTF*/ -#endif /*LV_GLTF_BIND_H*/ +#ifndef LV_GLTF_BIND_H +#define LV_GLTF_BIND_H + +#include "lv_gltf_model.h" + +#if LV_USE_GLTF + +#ifdef __cplusplus +extern "C" { +#endif + +typedef enum { + LV_GLTF_BIND_PROP_VISIBILITY, + LV_GLTF_BIND_PROP_POSITION, + LV_GLTF_BIND_PROP_ROTATION, + LV_GLTF_BIND_PROP_SCALE, + LV_GLTF_BIND_PROP_BASE_COLOR, + LV_GLTF_BIND_PROP_ALPHA_FACTOR, + LV_GLTF_BIND_PROP_EMIS_COLOR, + LV_GLTF_BIND_PROP_WORLD_POSITION +} lv_gltf_bind_prop_t; + +#define LV_GLTF_BIND_MAX_CHANNELS 4 +#define LV_GLTF_BIND_CHANNEL_0 (0x01) +#define LV_GLTF_BIND_CHANNEL_1 (0x02) +#define LV_GLTF_BIND_CHANNEL_2 (0x04) +#define LV_GLTF_BIND_CHANNEL_3 (0x08) + +typedef enum { LV_GLTF_BIND_DIR_READ, LV_GLTF_BIND_DIR_WRITE } lv_gltf_bind_dir_t; + +struct _lv_gltf_bind { + struct _lv_gltf_bind * next_bind; + lv_gltf_bind_prop_t prop; + lv_gltf_bind_dir_t dir; + uint32_t id; + uint32_t data_mask; + float data[LV_GLTF_BIND_MAX_CHANNELS]; + bool dirty; +}; + +typedef struct _lv_gltf_bind lv_gltf_bind_t; + +void lv_gltf_bind_set(lv_gltf_bind_t * bind, uint8_t channel, float data); +float lv_gltf_bind_get(lv_gltf_bind_t * bind, uint8_t channel); + +/** + * @brief Reset the dirty flag for a given bind. + * + * @param bind Pointer to the lv_gltf_bind_t to reset the dirty flag for. + */ +void lv_gltf_bind_bind_clean(lv_gltf_bind_t * bind); + +/** + * @brief Add an bind to a GLTF data object by node index. + * + * @param gltf_data Pointer to the lv_gltf_data_t object to which the bind will be added. + * @param nodeIndex The index of the node to bind. + * @param which_prop The property to bind. + * @param data_mask A mask indicating which data fields to bind. + * @return Pointer to the newly created lv_gltf_bind_t object, or NULL if the operation failed. + */ +lv_gltf_bind_t * lv_gltf_bind_add_by_index(lv_gltf_model_t * data, size_t index, lv_gltf_bind_prop_t which_prop, + uint32_t data_mask, + lv_gltf_bind_dir_t dir); + +/** + * @brief Add an bind to a GLTF data object by node IP address. + * + * @param gltf_data Pointer to the lv_gltf_data_t object to which the bind will be added. + * @param nodeIp The IP address of the node to bind. + * @param which_prop The property to bind. + * @param data_mask A mask indicating which data fields to bind. + * @return Pointer to the newly created lv_gltf_bind_t object, or NULL if the operation failed. + */ +lv_gltf_bind_t * lv_gltf_bind_add_by_ip(lv_gltf_model_t * data, const char * node_ip, lv_gltf_bind_prop_t which_prop, + uint32_t data_mask, lv_gltf_bind_dir_t dir); + +/** + * @brief Add an bind to a GLTF data object by node ID. + * + * @param gltf_data Pointer to the lv_gltf_data_t object to which the bind will be added. + * @param nodeId The ID of the node to bind. + * @param which_prop The property to bind. + * @param data_mask A mask indicating which data fields to bind. + * @return Pointer to the newly created lv_gltf_bind_t object, or NULL if the operation failed. + */ +lv_gltf_bind_t * lv_gltf_bind_add_by_path(lv_gltf_model_t * data, const char * path, lv_gltf_bind_prop_t which_prop, + uint32_t data_mask, lv_gltf_bind_dir_t dir); + +/** + * @brief Remove an bind from a GLTF data object. + * + * @param gltf_data Pointer to the lv_gltf_data_t object from which the bind will be removed. + * @param bind The bind to be removed. + * @param which_prop The property to bind. + * @param data_mask A mask indicating which data fields to bind. + * @return True on success, False on failure. + */ +lv_result_t lv_gltf_bind_remove(lv_gltf_model_t * _data, lv_gltf_bind_t * bind); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_USE_GLTF*/ +#endif /*LV_GLTF_BIND_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_data_internal.h b/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_data_internal.h index f8615a232..6e1b80878 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_data_internal.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_data_internal.h @@ -1,252 +1,252 @@ -#ifndef LV_GLTFDATA_PRIVATE_H -#define LV_GLTFDATA_PRIVATE_H - -#include "../../../lv_conf_internal.h" -#if LV_USE_GLTF -#include "../../../drivers/opengles/opengl_shader/lv_opengl_shader_internal.h" -#include "../../../draw/lv_image_dsc.h" -#include "../../../misc/lv_types.h" - -typedef struct { - GLuint count; - GLuint instanceCount; - GLuint firstIndex; - GLint baseVertex; - GLuint baseInstance; -} IndirectDrawCommand; - -typedef struct { - IndirectDrawCommand draw; - GLenum primitiveType; - GLenum indexType; - GLuint vertexArray; - - GLuint vertexBuffer; - GLuint indexBuffer; - - GLuint materialUniformsIndex; - GLuint albedoTexture; - GLuint emissiveTexture; - GLuint metalRoughTexture; - GLuint occlusionTexture; - GLuint normalTexture; - GLuint diffuseTransmissionTexture; - GLuint diffuseTransmissionColorTexture; - GLuint transmissionTexture; - GLuint transmissionTexcoordIndex; - - GLint baseColorTexcoordIndex; - GLint emissiveTexcoordIndex; - - GLint metallicRoughnessTexcoordIndex; - GLint occlusionTexcoordIndex; - GLint normalTexcoordIndex; - GLint diffuseTransmissionTexcoordIndex; - GLint diffuseTransmissionColorTexcoordIndex; - - GLint clearcoatTexture; - GLint clearcoatRoughnessTexture; - GLint clearcoatNormalTexture; - GLint clearcoatTexcoordIndex; - GLint clearcoatRoughnessTexcoordIndex; - GLint clearcoatNormalTexcoordIndex; - - GLuint thicknessTexture; - GLint thicknessTexcoordIndex; - - GLuint diffuseTexture; - GLint diffuseTexcoordIndex; - - GLuint specularGlossinessTexture; - GLint specularGlossinessTexcoordIndex; - -} lv_gltf_primitive_t; - -typedef struct { - GLint camera; - GLint view_projection_matrix; - GLint model_matrix; - GLint view_matrix; - GLint projection_matrix; - - GLint env_intensity; - GLint env_diffuse_sampler; - GLint env_specular_sampler; - GLint env_sheen_sampler; - GLint env_ggx_lut_sampler; - GLint env_charlie_lut_sampler; - GLint env_mip_count; - - GLint exposure; - GLint roughness_factor; - - GLint base_color_factor; - GLint base_color_sampler; - GLint base_color_uv_set; - GLint base_color_uv_transform; - - GLint emissive_factor; - GLint emissive_sampler; - GLint emissive_uv_set; - GLint emissive_uv_transform; - GLint emissive_strength; - - GLint metallic_factor; - GLint metallic_roughness_sampler; - GLint metallic_roughness_uv_set; - GLint metallic_roughness_uv_transform; - - GLint occlusion_strength; - GLint occlusion_sampler; - GLint occlusion_uv_set; - GLint occlusion_uv_transform; - - GLint normal_scale; - GLint normal_sampler; - GLint normal_uv_set; - GLint normal_uv_transform; - - GLint clearcoat_factor; - GLint clearcoat_roughness_factor; - GLint clearcoat_sampler; - GLint clearcoat_uv_set; - GLint clearcoat_uv_transform; - GLint clearcoat_roughness_sampler; - GLint clearcoat_roughness_uv_set; - GLint clearcoat_roughness_uv_transform; - GLint clearcoat_normal_scale; - GLint clearcoat_normal_sampler; - GLint clearcoat_normal_uv_set; - GLint clearcoat_normal_uv_transform; - - GLint thickness; - GLint thickness_sampler; - GLint thickness_uv_set; - GLint thickness_uv_transform; - - GLint diffuse_transmission_sampler; - GLint diffuse_transmission_uv_set; - GLint diffuse_transmission_uv_transform; - - GLint diffuse_transmission_color_sampler; - GLint diffuse_transmission_color_uv_set; - GLint diffuse_transmission_color_uv_transform; - - GLint sheen_color_factor; - GLint sheen_roughness_factor; - - GLint specular_color_factor; - GLint specular_factor; - - GLint diffuse_transmission_color_factor; - GLint diffuse_transmission_factor; - - GLint ior; - GLint alpha_cutoff; - - GLint dispersion; - GLint screen_size; - GLint transmission_factor; - GLint transmission_sampler; - GLint transmission_uv_set; - GLint transmission_uv_transform; - GLint transmission_framebuffer_sampler; - GLint transmission_framebuffer_size; - - GLint attenuation_distance; - GLint attenuation_color; - - GLint joints_sampler; - - GLint diffuse_factor; - GLint glossiness_factor; - - GLint diffuse_sampler; - GLint diffuse_uv_set; - GLint diffuse_uv_transform; - GLint specular_glossiness_sampler; - GLint specular_glossiness_uv_set; - GLint specular_glossiness_uv_transform; - -} lv_gltf_uniform_locations_t; - -lv_gltf_uniform_locations_t lv_gltf_uniform_locations_create(GLuint program); - -typedef struct { - GLuint program; - uint32_t bg_program; - uint32_t vert; - uint32_t frag; -} lv_gltf_shaderset_t; - -typedef struct { - lv_gltf_uniform_locations_t uniforms; - lv_gltf_shaderset_t shaderset; -} lv_gltf_compiled_shader_t; - -void lv_gltf_store_compiled_shader(lv_gltf_model_t * data, size_t identifier, lv_gltf_compiled_shader_t * shader); -lv_gltf_compiled_shader_t * lv_gltf_get_compiled_shader(lv_gltf_model_t * data, size_t identifier); - -/** - * @brief Load the gltf file at the specified filepath - * - * @param gltf_path The gltf filename - * @param ret_data Pointer to the data container that will be populated. - * @param shaders Pointer to the shader cache object this file uses. - */ -lv_gltf_model_t * -lv_gltf_data_load_from_file(const char * file_path, - lv_opengl_shader_manager_t * shader_manager); - -/** - * @brief Load the gltf file encoded within the supplied byte array - * - * @param gltf_path The gltf filename - * @param gltf_data_size if gltf_path is instead a byte array, pass the size of that array in through this variable (or 0 if it's a file path). - * @param ret_data Pointer to the data container that will be populated. - * @param shaders Pointer to the shader cache object this file uses. - */ - -lv_gltf_model_t * -lv_gltf_data_load_from_bytes(const uint8_t * data, size_t data_size, - lv_opengl_shader_manager_t * shader_manager); - - -/** - * @brief Retrieve the radius of the GLTF data object. - * - * @param D Pointer to the lv_gltf_data_t object from which to get the radius. - * @return The radius of the GLTF data object. - */ -double lv_gltf_data_get_radius(lv_gltf_model_t * D); - - -/** - * @brief Destroy a GLTF data object and free associated resources. - * - * @param _data Pointer to the lv_gltf_data_t object to be destroyed. - */ -void lv_gltf_data_destroy(lv_gltf_model_t * _data); - -/** - * @brief Copy the bounds information from one GLTF data object to another. - * - * @param to Pointer to the destination lv_gltf_data_t object. - * @param from Pointer to the source lv_gltf_data_t object. - */ -void lv_gltf_data_copy_bounds_info(lv_gltf_model_t * to, lv_gltf_model_t * from); - -/** - * @brief Swap the red and blue channels in a pixel buffer. - * - * @param pixel_buffer Pointer to the pixel buffer containing the image data. - * @param byte_total_count The total number of bytes in the pixel buffer. - * @param has_alpha Flag indicating whether the pixel buffer includes an alpha channel. - */ -void lv_gltf_data_rgb_to_bgr(uint8_t * pixel_buffer, - size_t byte_total_count, - bool has_alpha); - - -#endif /*LV_USE_GLTF*/ -#endif /* LV_GLTFDATA_PRIVATE_H */ +#ifndef LV_GLTFDATA_PRIVATE_H +#define LV_GLTFDATA_PRIVATE_H + +#include "../../../lv_conf_internal.h" +#if LV_USE_GLTF +#include "../../../drivers/opengles/opengl_shader/lv_opengl_shader_internal.h" +#include "../../../draw/lv_image_dsc.h" +#include "../../../misc/lv_types.h" + +typedef struct { + GLuint count; + GLuint instanceCount; + GLuint firstIndex; + GLint baseVertex; + GLuint baseInstance; +} IndirectDrawCommand; + +typedef struct { + IndirectDrawCommand draw; + GLenum primitiveType; + GLenum indexType; + GLuint vertexArray; + + GLuint vertexBuffer; + GLuint indexBuffer; + + GLuint materialUniformsIndex; + GLuint albedoTexture; + GLuint emissiveTexture; + GLuint metalRoughTexture; + GLuint occlusionTexture; + GLuint normalTexture; + GLuint diffuseTransmissionTexture; + GLuint diffuseTransmissionColorTexture; + GLuint transmissionTexture; + GLuint transmissionTexcoordIndex; + + GLint baseColorTexcoordIndex; + GLint emissiveTexcoordIndex; + + GLint metallicRoughnessTexcoordIndex; + GLint occlusionTexcoordIndex; + GLint normalTexcoordIndex; + GLint diffuseTransmissionTexcoordIndex; + GLint diffuseTransmissionColorTexcoordIndex; + + GLint clearcoatTexture; + GLint clearcoatRoughnessTexture; + GLint clearcoatNormalTexture; + GLint clearcoatTexcoordIndex; + GLint clearcoatRoughnessTexcoordIndex; + GLint clearcoatNormalTexcoordIndex; + + GLuint thicknessTexture; + GLint thicknessTexcoordIndex; + + GLuint diffuseTexture; + GLint diffuseTexcoordIndex; + + GLuint specularGlossinessTexture; + GLint specularGlossinessTexcoordIndex; + +} lv_gltf_primitive_t; + +typedef struct { + GLint camera; + GLint view_projection_matrix; + GLint model_matrix; + GLint view_matrix; + GLint projection_matrix; + + GLint env_intensity; + GLint env_diffuse_sampler; + GLint env_specular_sampler; + GLint env_sheen_sampler; + GLint env_ggx_lut_sampler; + GLint env_charlie_lut_sampler; + GLint env_mip_count; + + GLint exposure; + GLint roughness_factor; + + GLint base_color_factor; + GLint base_color_sampler; + GLint base_color_uv_set; + GLint base_color_uv_transform; + + GLint emissive_factor; + GLint emissive_sampler; + GLint emissive_uv_set; + GLint emissive_uv_transform; + GLint emissive_strength; + + GLint metallic_factor; + GLint metallic_roughness_sampler; + GLint metallic_roughness_uv_set; + GLint metallic_roughness_uv_transform; + + GLint occlusion_strength; + GLint occlusion_sampler; + GLint occlusion_uv_set; + GLint occlusion_uv_transform; + + GLint normal_scale; + GLint normal_sampler; + GLint normal_uv_set; + GLint normal_uv_transform; + + GLint clearcoat_factor; + GLint clearcoat_roughness_factor; + GLint clearcoat_sampler; + GLint clearcoat_uv_set; + GLint clearcoat_uv_transform; + GLint clearcoat_roughness_sampler; + GLint clearcoat_roughness_uv_set; + GLint clearcoat_roughness_uv_transform; + GLint clearcoat_normal_scale; + GLint clearcoat_normal_sampler; + GLint clearcoat_normal_uv_set; + GLint clearcoat_normal_uv_transform; + + GLint thickness; + GLint thickness_sampler; + GLint thickness_uv_set; + GLint thickness_uv_transform; + + GLint diffuse_transmission_sampler; + GLint diffuse_transmission_uv_set; + GLint diffuse_transmission_uv_transform; + + GLint diffuse_transmission_color_sampler; + GLint diffuse_transmission_color_uv_set; + GLint diffuse_transmission_color_uv_transform; + + GLint sheen_color_factor; + GLint sheen_roughness_factor; + + GLint specular_color_factor; + GLint specular_factor; + + GLint diffuse_transmission_color_factor; + GLint diffuse_transmission_factor; + + GLint ior; + GLint alpha_cutoff; + + GLint dispersion; + GLint screen_size; + GLint transmission_factor; + GLint transmission_sampler; + GLint transmission_uv_set; + GLint transmission_uv_transform; + GLint transmission_framebuffer_sampler; + GLint transmission_framebuffer_size; + + GLint attenuation_distance; + GLint attenuation_color; + + GLint joints_sampler; + + GLint diffuse_factor; + GLint glossiness_factor; + + GLint diffuse_sampler; + GLint diffuse_uv_set; + GLint diffuse_uv_transform; + GLint specular_glossiness_sampler; + GLint specular_glossiness_uv_set; + GLint specular_glossiness_uv_transform; + +} lv_gltf_uniform_locations_t; + +lv_gltf_uniform_locations_t lv_gltf_uniform_locations_create(GLuint program); + +typedef struct { + GLuint program; + uint32_t bg_program; + uint32_t vert; + uint32_t frag; +} lv_gltf_shaderset_t; + +typedef struct { + lv_gltf_uniform_locations_t uniforms; + lv_gltf_shaderset_t shaderset; +} lv_gltf_compiled_shader_t; + +void lv_gltf_store_compiled_shader(lv_gltf_model_t * data, size_t identifier, lv_gltf_compiled_shader_t * shader); +lv_gltf_compiled_shader_t * lv_gltf_get_compiled_shader(lv_gltf_model_t * data, size_t identifier); + +/** + * @brief Load the gltf file at the specified filepath + * + * @param gltf_path The gltf filename + * @param ret_data Pointer to the data container that will be populated. + * @param shaders Pointer to the shader cache object this file uses. + */ +lv_gltf_model_t * +lv_gltf_data_load_from_file(const char * file_path, + lv_opengl_shader_manager_t * shader_manager); + +/** + * @brief Load the gltf file encoded within the supplied byte array + * + * @param gltf_path The gltf filename + * @param gltf_data_size if gltf_path is instead a byte array, pass the size of that array in through this variable (or 0 if it's a file path). + * @param ret_data Pointer to the data container that will be populated. + * @param shaders Pointer to the shader cache object this file uses. + */ + +lv_gltf_model_t * +lv_gltf_data_load_from_bytes(const uint8_t * data, size_t data_size, + lv_opengl_shader_manager_t * shader_manager); + + +/** + * @brief Retrieve the radius of the GLTF data object. + * + * @param D Pointer to the lv_gltf_data_t object from which to get the radius. + * @return The radius of the GLTF data object. + */ +double lv_gltf_data_get_radius(lv_gltf_model_t * D); + + +/** + * @brief Destroy a GLTF data object and free associated resources. + * + * @param _data Pointer to the lv_gltf_data_t object to be destroyed. + */ +void lv_gltf_data_destroy(lv_gltf_model_t * _data); + +/** + * @brief Copy the bounds information from one GLTF data object to another. + * + * @param to Pointer to the destination lv_gltf_data_t object. + * @param from Pointer to the source lv_gltf_data_t object. + */ +void lv_gltf_data_copy_bounds_info(lv_gltf_model_t * to, lv_gltf_model_t * from); + +/** + * @brief Swap the red and blue channels in a pixel buffer. + * + * @param pixel_buffer Pointer to the pixel buffer containing the image data. + * @param byte_total_count The total number of bytes in the pixel buffer. + * @param has_alpha Flag indicating whether the pixel buffer includes an alpha channel. + */ +void lv_gltf_data_rgb_to_bgr(uint8_t * pixel_buffer, + size_t byte_total_count, + bool has_alpha); + + +#endif /*LV_USE_GLTF*/ +#endif /* LV_GLTFDATA_PRIVATE_H */ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_data_internal.hpp b/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_data_internal.hpp index c254aafd4..c33e5fe89 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_data_internal.hpp +++ b/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_data_internal.hpp @@ -1,373 +1,373 @@ -#ifndef LV_GLTFDATA_HPP -#define LV_GLTFDATA_HPP - -#include "../../../lv_conf_internal.h" - -#if LV_USE_GLTF - -#include -#include "lv_gltf_data_internal.h" -#include "lv_gltf_bind.h" - -#include "../../../misc/lv_array.h" -#include "../../../drivers/opengles/lv_opengles_private.h" - -#ifdef __cplusplus - -#include -#include -#include -#include - -// Vector of int32_t's -using UintVector = std::vector; -// Vector of int32_t's -using IntVector = std::vector; -// Vector of int64_t's -using LongVector = std::vector; -// Pointer to fastgltf::Node -using NodePtr = fastgltf::Node *; -// A standard 4x4 transform matrix -using Transform = fastgltf::math::fmat4x4; -// Pair of Node pointer and int32_t -using NodeIndexPair = std::pair; -// Pair of float and Node/Index pair -using NodeIndexDistancePair = std::pair; -// Vector of NodeIndexPair -using NodePairVector = std::vector; -// Vector of NodeIndexDistancePair -using NodeDistanceVector = std::vector; -// Map of uint32_t to NodePairVector -using MaterialIndexMap = std::map; -// Map of Node Pointers to Transforms -using NodeTransformMap = std::map; -// Map of Nodes by string (name) -using StringNodeMap = std::map; -// Map of Nodes by string (name) -using NodeIntMap = std::map; -// Map of Nodes by string (name) -using NodeVector = std::vector; -// Map of Node Index to Map of Prim Index to CenterXYZ+RadiusW Vec4 -using NodePrimCenterMap = std::map >; -// Map of Overrides by Node -using NodeOverrideMap = std::map; -// Map of Overrides by Node -using OverrideVector = std::vector; - -typedef struct { - GLuint drawsBuffer; - std::vector primitives; -} lv_gltf_mesh_data_t; - -typedef struct { - const char *ip; - const char *path; - fastgltf::Node *node; -} lv_gltf_data_node_t; - - -struct _lv_gltf_model_t { - const char *filename; - fastgltf::Asset asset; - lv_array_t nodes; - NodeVector node_by_light_index; - NodeTransformMap node_transform_cache; - MaterialIndexMap opaque_nodes_by_material_index; - MaterialIndexMap blended_nodes_by_material_index; - NodeOverrideMap node_binds; - lv_array_t binds; - std::vector validated_skins; - std::vector skin_tex; - NodePrimCenterMap local_mesh_to_center_points_by_primitive; - lv_gltf_t* viewer; - - std::vector meshes; - std::vector textures; - lv_array_t compiled_shaders; - std::map > channel_set_cache; - fastgltf::math::fmat4x4 view_mat; - fastgltf::math::fvec3 view_pos; - fastgltf::math::fvec3 vertex_max; - fastgltf::math::fvec3 vertex_min; - fastgltf::math::fvec3 vertex_cen; - - lv_timer_t* animation_update_timer; - - size_t current_animation; - size_t last_material_index; - - uint32_t last_camera_index; - int32_t last_anim_num; - - float bound_radius; - - uint32_t current_animation_max_time; - uint32_t local_timestamp; - uint32_t last_tick; - uint32_t camera; - - bool is_animation_enabled; - bool last_pass_was_transmission; - bool last_frame_was_antialiased; - bool last_frame_no_motion; - bool _last_frame_no_motion; - struct _lv_gltf_model_t *linked_view_source; -}; - -/** - * @brief Retrieve a specific texture from the GLTF model data. - * - * @param data Pointer to the lv_gltf_data_t object containing the model data. - * @param index The index of the texture to retrieve. - * @return Pointer to the texture object. - */ -GLuint lv_gltf_data_get_texture(lv_gltf_model_t *data, size_t index); - - -/** - * @brief Retrieve the minimum bounds (X/Y/Z) of the model from the GLTF data. - * - * @param data Pointer to the lv_gltf_data_t object containing the model data. - * @return Pointer to a 3-element float array representing the minimum bounds. - */ -fastgltf::math::fvec3 lv_gltf_data_get_bounds_min(const lv_gltf_model_t *data); - -/** - * @brief Retrieve the maximum bounds (X/Y/Z) of the model from the GLTF data. - * - * @param D Pointer to the lv_gltf_data_t object containing the model data. - * @return Pointer to a 3-element float array representing the maximum bounds. - */ -fastgltf::math::fvec3 lv_gltf_data_get_bounds_max(const lv_gltf_model_t *data); - -/** - * @brief Retrieve the center coordinates of the GLTF data object. - * - * @param D Pointer to the lv_gltf_data_t object from which to get the center. - * @return Pointer to an array containing the center coordinates (x, y, z). - */ -fastgltf::math::fvec3 lv_gltf_data_get_center(const lv_gltf_model_t *data); - -/** - * @brief Retrieve the filename of the GLTF model. - * - * @param D Pointer to the lv_gltf_data_t object containing the model data. - * @return Pointer to a constant character string representing the filename. - */ -const char *lv_gltf_get_filename(const lv_gltf_model_t *data); - -/** - * @brief Check if the centerpoint cache contains a specific entry. - * - * @param data Pointer to the lv_gltf_data_t object containing the model data. - * @param index The index of the entry to check. - * @param element The specific parameter to check within the cache. - * @return True if the cache contains the entry, false otherwise. - */ -bool lv_gltf_data_centerpoint_cache_contains(lv_gltf_model_t *data, size_t index, int32_t element); - -/** - * @brief Retrieve a specific primitive from a mesh. - * - * @param M Pointer to the MeshData structure containing the mesh data. - * @param I The index of the primitive to retrieve. - * @return Pointer to the primitive data. - */ -lv_gltf_primitive_t *lv_gltf_data_get_primitive_from_mesh(lv_gltf_mesh_data_t *M, size_t I); - -/** - * @brief Retrieve the asset associated with the GLTF model data. - * - * @param D Pointer to the lv_gltf_data_t object containing the model data. - * @return Pointer to the asset data. - */ -fastgltf::Asset *lv_gltf_data_get_asset(lv_gltf_model_t *data); - -/** - * @brief Retrieve mesh data for a specific index from the GLTF model data. - * - * @param D Pointer to the lv_gltf_data_t object containing the model data. - * @param I The index of the mesh data to retrieve. - * @return Pointer to the MeshData structure containing the mesh data. - */ -lv_gltf_mesh_data_t *lv_gltf_data_get_mesh(lv_gltf_model_t *data, size_t index); - -/** - * @brief Retrieve the skin texture index for a specific entry in the GLTF model data. - * - * @param data Pointer to the lv_gltf_data_t object containing the model data. - * @param index The index of the entry for which to retrieve the skin texture index. - * @return The skin texture index. - */ -GLuint lv_gltf_data_get_skin_texture_at(lv_gltf_model_t *data, size_t index); - -/** - * @brief Check if the validated skins contain a specific entry. - * - * @param data Pointer to the lv_gltf_data_t object containing the model data. - * @param index The index of the skin to check. - * @return True if the validated skins contain the entry, false otherwise. - */ -bool lv_gltf_data_validated_skins_contains(lv_gltf_model_t *data, size_t index); - -/** - * @brief Validate a specific skin in the GLTF model data. - * - * @param data Pointer to the lv_gltf_data_t object containing the model data. - * @param index The index of the skin to validate. - */ -void lv_gltf_data_validate_skin(lv_gltf_model_t *data, size_t index); - -/** - * @brief Add an opaque node primitive to the GLTF model data. - * - * @param D Pointer to the lv_gltf_data_t object containing the model data. - * @param I The index of the primitive to add. - * @param N Pointer to the NodePtr representing the node to add. - * @param P The specific parameter associated with the primitive. - */ -void lv_gltf_data_add_opaque_node_primitive(lv_gltf_model_t *data, size_t index, fastgltf::Node *node, size_t primitive_index); - -/** - * @brief Add a blended node primitive to the GLTF model data. - * - * @param D Pointer to the lv_gltf_data_t object containing the model data. - * @param I The index of the primitive to add. - * @param N Pointer to the NodePtr representing the node to add. - * @param P The specific parameter associated with the primitive. - */ -void lv_gltf_data_add_blended_node_primitive(lv_gltf_model_t *data, size_t mesh_index, fastgltf::Node *node, - size_t primitive_index); - -/** - * @brief Set the cached transformation matrix for a specific node in the GLTF model data. - * - * @param D Pointer to the lv_gltf_data_t object containing the model data. - * @param N Pointer to the NodePtr representing the node for which to set the transformation. - * @param M The transformation matrix to cache. - */ -void lv_gltf_data_set_cached_transform(lv_gltf_model_t* data, fastgltf::Node* node, fastgltf::math::fmat4x4 M); - -/** - * @brief Clear the transformation cache for the GLTF model data. - * - * @param D Pointer to the lv_gltf_data_t object containing the model data. - */ -void lv_gltf_data_clear_transform_cache(lv_gltf_model_t* data); - -/** - * @brief Retrieve the cached transformation matrix for a specific node in the GLTF model data. - * - * @param D Pointer to the lv_gltf_data_t object containing the model data. - * @param N Pointer to the NodePtr representing the node for which to retrieve the transformation. - * @return The cached transformation matrix. - */ -fastgltf::math::fmat4x4 lv_gltf_data_get_cached_transform(lv_gltf_model_t* data, fastgltf::Node* node); - -/** - * @brief Check if a cached transformation matrix exists for a given node. - * - * @param D Pointer to the lv_gltf_data_t object containing the model data. - * @param N Pointer to the NodePtr representing the node for which to retrieve the transformation. - * @return true if a cache item exists, false otherwise - int32_t*/ -bool lv_gltf_data_has_cached_transform(lv_gltf_model_t* data, fastgltf::Node* node); - -/** - * @brief Check if the transformation cache is empty. - * - * @param D Pointer to the lv_gltf_data_t object containing the model data. - * @return True if the transformation cache is empty, false otherwise. - */ -bool lv_gltf_data_transform_cache_is_empty(lv_gltf_model_t* data); - -/** - * @brief Retrieve the size of the skins in the GLTF model data. - * - * @param D Pointer to the lv_gltf_data_t object containing the model data. - * @return The size of the skins. - */ -size_t lv_gltf_data_get_skins_size(lv_gltf_model_t *data); - -/** - * @brief Retrieve a specific skin from the GLTF model data. - * - * @param D Pointer to the lv_gltf_data_t object containing the model data. - * @param I The index of the skin to retrieve. - * @return The skin index. - */ -size_t lv_gltf_data_get_skin(lv_gltf_model_t *data, size_t index); - -/** - * @brief Ingest and discover defines for a specific node and primitive in the GLTF model data. - * - * @param data_obj Pointer to the lv_gltf_data_t object containing the model data. - * @param node Pointer to the node for which to ingest defines. - * @param prim Pointer to the primitive for which to ingest defines. - */ -void lv_gltf_data_injest_discover_defines(lv_gltf_model_t *data, fastgltf::Node *node, fastgltf::Primitive *prim); - -/** - * @brief Retrieve the center point of a specific mesh element from the GLTF model data. - * - * @param gltf_data Pointer to the lv_gltf_data_t object containing the model data. - * @param matrix The transformation matrix to apply when calculating the center point. - * @param meshIndex The index of the mesh from which to retrieve the center point. - * @param elem The specific element index within the mesh. - * @return The center point as a fastgltf::math::fvec3 structure. - */ -fastgltf::math::fvec3 lv_gltf_data_get_centerpoint(lv_gltf_model_t *gltf_data, fastgltf::math::fmat4x4 matrix, size_t mesh_index, - int32_t elem); - - -lv_gltf_mesh_data_t *lv_gltf_get_new_meshdata(lv_gltf_model_t *_data); - -lv_gltf_model_t *lv_gltf_data_create_internal(const char *gltf_path, fastgltf::Asset); - -lv_gltf_model_t *lv_gltf_data_load_internal(const void *data_source, size_t data_size, lv_opengl_shader_manager_t *shaders); - -/*void set_node_at_path(lv_gltf_data_t *data, const std::string &path,*/ -/* fastgltf::Node *node);*/ -/*void set_node_at_ip(lv_gltf_data_t *data, const std::string &ip,*/ -/* fastgltf::Node *node);*/ -/*void set_node_index(lv_gltf_data_t *data, size_t index, fastgltf::Node *node);*/ - -fastgltf::math::fvec4 lv_gltf_get_primitive_centerpoint(lv_gltf_model_t *data, fastgltf::Mesh &mesh, uint32_t prim_num); - -fastgltf::math::fvec3 get_cached_centerpoint(lv_gltf_model_t *data, size_t index, int32_t element, - fastgltf::math::fmat4x4 matrix); - -void lv_gltf_data_destroy_textures(lv_gltf_model_t *data); -GLuint lv_gltf_data_create_texture(lv_gltf_model_t *data); -void lv_gltf_data_nodes_init(lv_gltf_model_t *data, size_t size); -void lv_gltf_data_node_init(lv_gltf_data_node_t * node, fastgltf::Node * fastgltf_node, const char * path, const char * ip); -void lv_gltf_data_node_add(lv_gltf_model_t *data, const lv_gltf_data_node_t *data_node); -void lv_gltf_data_node_delete(lv_gltf_data_node_t *node); - -/** - * @brief Retrieve the pixel data for a specific texture in a GLTF model. - * - * @param pixels Pointer to the memory where the pixel data will be stored. - * @param data_obj Pointer to the lv_gltf_data_t object containing the model data. - * @param model_texture_index The index of the texture in the model. - * @param mipmapnum The mipmap level to retrieve pixel data for. - * @param width The width of the texture. - * @param height The height of the texture. - * @param has_alpha Flag indicating whether the texture includes an alpha channel. - * @return True if the pixel data was successfully retrieved, false otherwise. - */ -bool lv_gltf_data_get_texture_pixels(void *pixels, lv_gltf_model_t *data_obj, uint32_t model_texture_index, uint32_t mipmapnum, - uint32_t width, uint32_t height, bool has_alpha); - -lv_gltf_data_node_t *lv_gltf_data_node_get_by_index(lv_gltf_model_t *data, size_t index); -lv_gltf_data_node_t *lv_gltf_data_node_get_by_ip(lv_gltf_model_t *data, const char *ip); -lv_gltf_data_node_t *lv_gltf_data_node_get_by_path(lv_gltf_model_t *data, const char *path); -uint32_t lv_gltf_data_get_animation_total_time(lv_gltf_model_t *data, uint32_t index); -std::vector *lv_gltf_data_animation_get_channel_set(std::size_t anim_num, lv_gltf_model_t *data, fastgltf::Node &node); -void lv_gltf_data_animation_matrix_apply(float timestamp, std::size_t anim_num, lv_gltf_model_t *gltf_data, fastgltf::Node &node, - fastgltf::math::fmat4x4 &matrix); - -#endif - -#endif /*LV_USE_GLTF*/ -#endif /*LV_GLTFVIEW_H*/ +#ifndef LV_GLTFDATA_HPP +#define LV_GLTFDATA_HPP + +#include "../../../lv_conf_internal.h" + +#if LV_USE_GLTF + +#include +#include "lv_gltf_data_internal.h" +#include "lv_gltf_bind.h" + +#include "../../../misc/lv_array.h" +#include "../../../drivers/opengles/lv_opengles_private.h" + +#ifdef __cplusplus + +#include +#include +#include +#include + +// Vector of int32_t's +using UintVector = std::vector; +// Vector of int32_t's +using IntVector = std::vector; +// Vector of int64_t's +using LongVector = std::vector; +// Pointer to fastgltf::Node +using NodePtr = fastgltf::Node *; +// A standard 4x4 transform matrix +using Transform = fastgltf::math::fmat4x4; +// Pair of Node pointer and int32_t +using NodeIndexPair = std::pair; +// Pair of float and Node/Index pair +using NodeIndexDistancePair = std::pair; +// Vector of NodeIndexPair +using NodePairVector = std::vector; +// Vector of NodeIndexDistancePair +using NodeDistanceVector = std::vector; +// Map of uint32_t to NodePairVector +using MaterialIndexMap = std::map; +// Map of Node Pointers to Transforms +using NodeTransformMap = std::map; +// Map of Nodes by string (name) +using StringNodeMap = std::map; +// Map of Nodes by string (name) +using NodeIntMap = std::map; +// Map of Nodes by string (name) +using NodeVector = std::vector; +// Map of Node Index to Map of Prim Index to CenterXYZ+RadiusW Vec4 +using NodePrimCenterMap = std::map >; +// Map of Overrides by Node +using NodeOverrideMap = std::map; +// Map of Overrides by Node +using OverrideVector = std::vector; + +typedef struct { + GLuint drawsBuffer; + std::vector primitives; +} lv_gltf_mesh_data_t; + +typedef struct { + const char *ip; + const char *path; + fastgltf::Node *node; +} lv_gltf_data_node_t; + + +struct _lv_gltf_model_t { + const char *filename; + fastgltf::Asset asset; + lv_array_t nodes; + NodeVector node_by_light_index; + NodeTransformMap node_transform_cache; + MaterialIndexMap opaque_nodes_by_material_index; + MaterialIndexMap blended_nodes_by_material_index; + NodeOverrideMap node_binds; + lv_array_t binds; + std::vector validated_skins; + std::vector skin_tex; + NodePrimCenterMap local_mesh_to_center_points_by_primitive; + lv_gltf_t* viewer; + + std::vector meshes; + std::vector textures; + lv_array_t compiled_shaders; + std::map > channel_set_cache; + fastgltf::math::fmat4x4 view_mat; + fastgltf::math::fvec3 view_pos; + fastgltf::math::fvec3 vertex_max; + fastgltf::math::fvec3 vertex_min; + fastgltf::math::fvec3 vertex_cen; + + lv_timer_t* animation_update_timer; + + size_t current_animation; + size_t last_material_index; + + uint32_t last_camera_index; + int32_t last_anim_num; + + float bound_radius; + + uint32_t current_animation_max_time; + uint32_t local_timestamp; + uint32_t last_tick; + uint32_t camera; + + bool is_animation_enabled; + bool last_pass_was_transmission; + bool last_frame_was_antialiased; + bool last_frame_no_motion; + bool _last_frame_no_motion; + struct _lv_gltf_model_t *linked_view_source; +}; + +/** + * @brief Retrieve a specific texture from the GLTF model data. + * + * @param data Pointer to the lv_gltf_data_t object containing the model data. + * @param index The index of the texture to retrieve. + * @return Pointer to the texture object. + */ +GLuint lv_gltf_data_get_texture(lv_gltf_model_t *data, size_t index); + + +/** + * @brief Retrieve the minimum bounds (X/Y/Z) of the model from the GLTF data. + * + * @param data Pointer to the lv_gltf_data_t object containing the model data. + * @return Pointer to a 3-element float array representing the minimum bounds. + */ +fastgltf::math::fvec3 lv_gltf_data_get_bounds_min(const lv_gltf_model_t *data); + +/** + * @brief Retrieve the maximum bounds (X/Y/Z) of the model from the GLTF data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @return Pointer to a 3-element float array representing the maximum bounds. + */ +fastgltf::math::fvec3 lv_gltf_data_get_bounds_max(const lv_gltf_model_t *data); + +/** + * @brief Retrieve the center coordinates of the GLTF data object. + * + * @param D Pointer to the lv_gltf_data_t object from which to get the center. + * @return Pointer to an array containing the center coordinates (x, y, z). + */ +fastgltf::math::fvec3 lv_gltf_data_get_center(const lv_gltf_model_t *data); + +/** + * @brief Retrieve the filename of the GLTF model. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @return Pointer to a constant character string representing the filename. + */ +const char *lv_gltf_get_filename(const lv_gltf_model_t *data); + +/** + * @brief Check if the centerpoint cache contains a specific entry. + * + * @param data Pointer to the lv_gltf_data_t object containing the model data. + * @param index The index of the entry to check. + * @param element The specific parameter to check within the cache. + * @return True if the cache contains the entry, false otherwise. + */ +bool lv_gltf_data_centerpoint_cache_contains(lv_gltf_model_t *data, size_t index, int32_t element); + +/** + * @brief Retrieve a specific primitive from a mesh. + * + * @param M Pointer to the MeshData structure containing the mesh data. + * @param I The index of the primitive to retrieve. + * @return Pointer to the primitive data. + */ +lv_gltf_primitive_t *lv_gltf_data_get_primitive_from_mesh(lv_gltf_mesh_data_t *M, size_t I); + +/** + * @brief Retrieve the asset associated with the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @return Pointer to the asset data. + */ +fastgltf::Asset *lv_gltf_data_get_asset(lv_gltf_model_t *data); + +/** + * @brief Retrieve mesh data for a specific index from the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @param I The index of the mesh data to retrieve. + * @return Pointer to the MeshData structure containing the mesh data. + */ +lv_gltf_mesh_data_t *lv_gltf_data_get_mesh(lv_gltf_model_t *data, size_t index); + +/** + * @brief Retrieve the skin texture index for a specific entry in the GLTF model data. + * + * @param data Pointer to the lv_gltf_data_t object containing the model data. + * @param index The index of the entry for which to retrieve the skin texture index. + * @return The skin texture index. + */ +GLuint lv_gltf_data_get_skin_texture_at(lv_gltf_model_t *data, size_t index); + +/** + * @brief Check if the validated skins contain a specific entry. + * + * @param data Pointer to the lv_gltf_data_t object containing the model data. + * @param index The index of the skin to check. + * @return True if the validated skins contain the entry, false otherwise. + */ +bool lv_gltf_data_validated_skins_contains(lv_gltf_model_t *data, size_t index); + +/** + * @brief Validate a specific skin in the GLTF model data. + * + * @param data Pointer to the lv_gltf_data_t object containing the model data. + * @param index The index of the skin to validate. + */ +void lv_gltf_data_validate_skin(lv_gltf_model_t *data, size_t index); + +/** + * @brief Add an opaque node primitive to the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @param I The index of the primitive to add. + * @param N Pointer to the NodePtr representing the node to add. + * @param P The specific parameter associated with the primitive. + */ +void lv_gltf_data_add_opaque_node_primitive(lv_gltf_model_t *data, size_t index, fastgltf::Node *node, size_t primitive_index); + +/** + * @brief Add a blended node primitive to the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @param I The index of the primitive to add. + * @param N Pointer to the NodePtr representing the node to add. + * @param P The specific parameter associated with the primitive. + */ +void lv_gltf_data_add_blended_node_primitive(lv_gltf_model_t *data, size_t mesh_index, fastgltf::Node *node, + size_t primitive_index); + +/** + * @brief Set the cached transformation matrix for a specific node in the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @param N Pointer to the NodePtr representing the node for which to set the transformation. + * @param M The transformation matrix to cache. + */ +void lv_gltf_data_set_cached_transform(lv_gltf_model_t* data, fastgltf::Node* node, fastgltf::math::fmat4x4 M); + +/** + * @brief Clear the transformation cache for the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + */ +void lv_gltf_data_clear_transform_cache(lv_gltf_model_t* data); + +/** + * @brief Retrieve the cached transformation matrix for a specific node in the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @param N Pointer to the NodePtr representing the node for which to retrieve the transformation. + * @return The cached transformation matrix. + */ +fastgltf::math::fmat4x4 lv_gltf_data_get_cached_transform(lv_gltf_model_t* data, fastgltf::Node* node); + +/** + * @brief Check if a cached transformation matrix exists for a given node. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @param N Pointer to the NodePtr representing the node for which to retrieve the transformation. + * @return true if a cache item exists, false otherwise + int32_t*/ +bool lv_gltf_data_has_cached_transform(lv_gltf_model_t* data, fastgltf::Node* node); + +/** + * @brief Check if the transformation cache is empty. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @return True if the transformation cache is empty, false otherwise. + */ +bool lv_gltf_data_transform_cache_is_empty(lv_gltf_model_t* data); + +/** + * @brief Retrieve the size of the skins in the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @return The size of the skins. + */ +size_t lv_gltf_data_get_skins_size(lv_gltf_model_t *data); + +/** + * @brief Retrieve a specific skin from the GLTF model data. + * + * @param D Pointer to the lv_gltf_data_t object containing the model data. + * @param I The index of the skin to retrieve. + * @return The skin index. + */ +size_t lv_gltf_data_get_skin(lv_gltf_model_t *data, size_t index); + +/** + * @brief Ingest and discover defines for a specific node and primitive in the GLTF model data. + * + * @param data_obj Pointer to the lv_gltf_data_t object containing the model data. + * @param node Pointer to the node for which to ingest defines. + * @param prim Pointer to the primitive for which to ingest defines. + */ +void lv_gltf_data_injest_discover_defines(lv_gltf_model_t *data, fastgltf::Node *node, fastgltf::Primitive *prim); + +/** + * @brief Retrieve the center point of a specific mesh element from the GLTF model data. + * + * @param gltf_data Pointer to the lv_gltf_data_t object containing the model data. + * @param matrix The transformation matrix to apply when calculating the center point. + * @param meshIndex The index of the mesh from which to retrieve the center point. + * @param elem The specific element index within the mesh. + * @return The center point as a fastgltf::math::fvec3 structure. + */ +fastgltf::math::fvec3 lv_gltf_data_get_centerpoint(lv_gltf_model_t *gltf_data, fastgltf::math::fmat4x4 matrix, size_t mesh_index, + int32_t elem); + + +lv_gltf_mesh_data_t *lv_gltf_get_new_meshdata(lv_gltf_model_t *_data); + +lv_gltf_model_t *lv_gltf_data_create_internal(const char *gltf_path, fastgltf::Asset); + +lv_gltf_model_t *lv_gltf_data_load_internal(const void *data_source, size_t data_size, lv_opengl_shader_manager_t *shaders); + +/*void set_node_at_path(lv_gltf_data_t *data, const std::string &path,*/ +/* fastgltf::Node *node);*/ +/*void set_node_at_ip(lv_gltf_data_t *data, const std::string &ip,*/ +/* fastgltf::Node *node);*/ +/*void set_node_index(lv_gltf_data_t *data, size_t index, fastgltf::Node *node);*/ + +fastgltf::math::fvec4 lv_gltf_get_primitive_centerpoint(lv_gltf_model_t *data, fastgltf::Mesh &mesh, uint32_t prim_num); + +fastgltf::math::fvec3 get_cached_centerpoint(lv_gltf_model_t *data, size_t index, int32_t element, + fastgltf::math::fmat4x4 matrix); + +void lv_gltf_data_destroy_textures(lv_gltf_model_t *data); +GLuint lv_gltf_data_create_texture(lv_gltf_model_t *data); +void lv_gltf_data_nodes_init(lv_gltf_model_t *data, size_t size); +void lv_gltf_data_node_init(lv_gltf_data_node_t * node, fastgltf::Node * fastgltf_node, const char * path, const char * ip); +void lv_gltf_data_node_add(lv_gltf_model_t *data, const lv_gltf_data_node_t *data_node); +void lv_gltf_data_node_delete(lv_gltf_data_node_t *node); + +/** + * @brief Retrieve the pixel data for a specific texture in a GLTF model. + * + * @param pixels Pointer to the memory where the pixel data will be stored. + * @param data_obj Pointer to the lv_gltf_data_t object containing the model data. + * @param model_texture_index The index of the texture in the model. + * @param mipmapnum The mipmap level to retrieve pixel data for. + * @param width The width of the texture. + * @param height The height of the texture. + * @param has_alpha Flag indicating whether the texture includes an alpha channel. + * @return True if the pixel data was successfully retrieved, false otherwise. + */ +bool lv_gltf_data_get_texture_pixels(void *pixels, lv_gltf_model_t *data_obj, uint32_t model_texture_index, uint32_t mipmapnum, + uint32_t width, uint32_t height, bool has_alpha); + +lv_gltf_data_node_t *lv_gltf_data_node_get_by_index(lv_gltf_model_t *data, size_t index); +lv_gltf_data_node_t *lv_gltf_data_node_get_by_ip(lv_gltf_model_t *data, const char *ip); +lv_gltf_data_node_t *lv_gltf_data_node_get_by_path(lv_gltf_model_t *data, const char *path); +uint32_t lv_gltf_data_get_animation_total_time(lv_gltf_model_t *data, uint32_t index); +std::vector *lv_gltf_data_animation_get_channel_set(std::size_t anim_num, lv_gltf_model_t *data, fastgltf::Node &node); +void lv_gltf_data_animation_matrix_apply(float timestamp, std::size_t anim_num, lv_gltf_model_t *gltf_data, fastgltf::Node &node, + fastgltf::math::fmat4x4 &matrix); + +#endif + +#endif /*LV_USE_GLTF*/ +#endif /*LV_GLTFVIEW_H*/ diff --git a/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_model.h b/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_model.h index 600cd93d9..c57d92fe1 100644 --- a/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_model.h +++ b/lib/libesp32_lvgl/lvgl/src/libs/gltf/gltf_data/lv_gltf_model.h @@ -1,135 +1,135 @@ -#ifndef LV_GLTF_MODEL_H -#define LV_GLTF_MODEL_H - -#include "../../../lv_conf_internal.h" -#if LV_USE_GLTF - -#include "../../../misc/lv_types.h" - -#ifdef __cplusplus -extern "C" { -#endif -/** - * @brief Get the number of images in the glTF model - * - * Images in glTF are used as sources for textures and can be stored either as external files - * or embedded as base64-encoded model within the glTF file. - * - * @param model Pointer to the glTF model data structure - * @return Number of images in the model - */ -size_t lv_gltf_model_get_image_count(const lv_gltf_model_t * model); - -/** - * @brief Get the number of textures in the glTF model - * - * Textures define how images are sampled and applied to materials. Each texture references - * an image and may specify sampling parameters like filtering and wrapping modes. - * - * @param model Pointer to the glTF model data structure - * @return Number of textures in the model - */ -size_t lv_gltf_model_get_texture_count(const lv_gltf_model_t * model); - -/** - * @brief Get the number of materials in the glTF model - * - * Materials define the visual appearance of mesh primitives, including properties like - * base color, metallic/roughness values, normal maps, and other surface characteristics. - * - * @param model Pointer to the glTF model data structure - * @return Number of materials in the model - */ -size_t lv_gltf_model_get_material_count(const lv_gltf_model_t * model); - -/** - * @brief Get the number of cameras in the glTF model - * - * Cameras define viewpoints within the 3D scene and can be either perspective or - * orthographic. They are typically attached to nodes in the scene graph. - * - * @param model Pointer to the glTF model data structure - * @return Number of cameras in the model - */ -size_t lv_gltf_model_get_camera_count(const lv_gltf_model_t * model); - -/** - * @brief Get the number of nodes in the glTF model - * - * Nodes form the scene graph hierarchy and can contain transformations, meshes, cameras, - * or other nodes as children. They define the spatial relationships between objects in the scene. - * - * @param model Pointer to the glTF model data structure - * @return Number of nodes in the model - */ -size_t lv_gltf_model_get_node_count(const lv_gltf_model_t * model); - -/** - * @brief Get the number of meshes in the glTF model - * - * Meshes contain the geometric model for 3D objects, including vertex positions, normals, - * texture coordinates, and indices. Each mesh can have multiple primitives with different materials. - * - * @param model Pointer to the glTF model data structure - * @return Number of meshes in the model - */ -size_t lv_gltf_model_get_mesh_count(const lv_gltf_model_t * model); - -/** - * @brief Get the number of scenes in the glTF model - * - * Scenes define the root nodes of the scene graph. A glTF file can contain multiple scenes, - * though typically only one is designated as the default scene to be displayed. - * - * @param model Pointer to the glTF model data structure - * @return Number of scenes in the model - */ -size_t lv_gltf_model_get_scene_count(const lv_gltf_model_t * model); - -/** - * @brief Get the number of animations in the glTF model - * - * Animations define keyframe-based motion for nodes in the scene, including transformations - * like translation, rotation, and scaling over time. - * - * @param model Pointer to the glTF model data structure - * @return Number of animations in the model - */ -size_t lv_gltf_model_get_animation_count(const lv_gltf_model_t * model); - -/** - * @brief Select and start playing an animation - * - * @param model Pointer to the glTF model structure - * @param index Animation number to start playing - * @return LV_RESULT_OK if the animation was started else LV_RESULT_INVALID - */ -lv_result_t lv_gltf_model_play_animation(lv_gltf_model_t * model, size_t index); - -/** - * @brief Pause the current animation - * - * @param model Pointer to the glTF model structure - */ -void lv_gltf_model_pause_animation(lv_gltf_model_t * model); - -/** - * @brief Check if an animation is currently being played - * - * @param model Pointer to the glTF model structure - */ -bool lv_gltf_model_is_animation_paused(lv_gltf_model_t * model); - -/** - * @brief Get the current selected animation. To see if it's playing see `lv_gltf_model_is_animation_paused` - * - * @param model Pointer to the glTF model structure - */ -size_t lv_gltf_model_get_animation(lv_gltf_model_t * model); - -#ifdef __cplusplus -} /*extern "C"*/ -#endif - -#endif /*LV_USE_GLTF*/ -#endif /*LV_GLTF_MODEL_H*/ +#ifndef LV_GLTF_MODEL_H +#define LV_GLTF_MODEL_H + +#include "../../../lv_conf_internal.h" +#if LV_USE_GLTF + +#include "../../../misc/lv_types.h" + +#ifdef __cplusplus +extern "C" { +#endif +/** + * @brief Get the number of images in the glTF model + * + * Images in glTF are used as sources for textures and can be stored either as external files + * or embedded as base64-encoded model within the glTF file. + * + * @param model Pointer to the glTF model data structure + * @return Number of images in the model + */ +size_t lv_gltf_model_get_image_count(const lv_gltf_model_t * model); + +/** + * @brief Get the number of textures in the glTF model + * + * Textures define how images are sampled and applied to materials. Each texture references + * an image and may specify sampling parameters like filtering and wrapping modes. + * + * @param model Pointer to the glTF model data structure + * @return Number of textures in the model + */ +size_t lv_gltf_model_get_texture_count(const lv_gltf_model_t * model); + +/** + * @brief Get the number of materials in the glTF model + * + * Materials define the visual appearance of mesh primitives, including properties like + * base color, metallic/roughness values, normal maps, and other surface characteristics. + * + * @param model Pointer to the glTF model data structure + * @return Number of materials in the model + */ +size_t lv_gltf_model_get_material_count(const lv_gltf_model_t * model); + +/** + * @brief Get the number of cameras in the glTF model + * + * Cameras define viewpoints within the 3D scene and can be either perspective or + * orthographic. They are typically attached to nodes in the scene graph. + * + * @param model Pointer to the glTF model data structure + * @return Number of cameras in the model + */ +size_t lv_gltf_model_get_camera_count(const lv_gltf_model_t * model); + +/** + * @brief Get the number of nodes in the glTF model + * + * Nodes form the scene graph hierarchy and can contain transformations, meshes, cameras, + * or other nodes as children. They define the spatial relationships between objects in the scene. + * + * @param model Pointer to the glTF model data structure + * @return Number of nodes in the model + */ +size_t lv_gltf_model_get_node_count(const lv_gltf_model_t * model); + +/** + * @brief Get the number of meshes in the glTF model + * + * Meshes contain the geometric model for 3D objects, including vertex positions, normals, + * texture coordinates, and indices. Each mesh can have multiple primitives with different materials. + * + * @param model Pointer to the glTF model data structure + * @return Number of meshes in the model + */ +size_t lv_gltf_model_get_mesh_count(const lv_gltf_model_t * model); + +/** + * @brief Get the number of scenes in the glTF model + * + * Scenes define the root nodes of the scene graph. A glTF file can contain multiple scenes, + * though typically only one is designated as the default scene to be displayed. + * + * @param model Pointer to the glTF model data structure + * @return Number of scenes in the model + */ +size_t lv_gltf_model_get_scene_count(const lv_gltf_model_t * model); + +/** + * @brief Get the number of animations in the glTF model + * + * Animations define keyframe-based motion for nodes in the scene, including transformations + * like translation, rotation, and scaling over time. + * + * @param model Pointer to the glTF model data structure + * @return Number of animations in the model + */ +size_t lv_gltf_model_get_animation_count(const lv_gltf_model_t * model); + +/** + * @brief Select and start playing an animation + * + * @param model Pointer to the glTF model structure + * @param index Animation number to start playing + * @return LV_RESULT_OK if the animation was started else LV_RESULT_INVALID + */ +lv_result_t lv_gltf_model_play_animation(lv_gltf_model_t * model, size_t index); + +/** + * @brief Pause the current animation + * + * @param model Pointer to the glTF model structure + */ +void lv_gltf_model_pause_animation(lv_gltf_model_t * model); + +/** + * @brief Check if an animation is currently being played + * + * @param model Pointer to the glTF model structure + */ +bool lv_gltf_model_is_animation_paused(lv_gltf_model_t * model); + +/** + * @brief Get the current selected animation. To see if it's playing see `lv_gltf_model_is_animation_paused` + * + * @param model Pointer to the glTF model structure + */ +size_t lv_gltf_model_get_animation(lv_gltf_model_t * model); + +#ifdef __cplusplus +} /*extern "C"*/ +#endif + +#endif /*LV_USE_GLTF*/ +#endif /*LV_GLTF_MODEL_H*/ diff --git a/lib/libesp32_ml/tf_lite_esp32/src/tensorflow/lite/micro/kernels/split_v.cc b/lib/libesp32_ml/tf_lite_esp32/src/tensorflow/lite/micro/kernels/split_v.cc index d0002d57c..86d3fbe8e 100644 --- a/lib/libesp32_ml/tf_lite_esp32/src/tensorflow/lite/micro/kernels/split_v.cc +++ b/lib/libesp32_ml/tf_lite_esp32/src/tensorflow/lite/micro/kernels/split_v.cc @@ -1,130 +1,130 @@ -/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. -==============================================================================*/ - -#include "tensorflow/lite/c/builtin_op_data.h" -#include "tensorflow/lite/c/common.h" -#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" -#include "tensorflow/lite/kernels/kernel_util.h" -#include "tensorflow/lite/kernels/op_macros.h" -#include "tensorflow/lite/micro/kernels/kernel_util.h" -#include "tensorflow/lite/micro/micro_log.h" - -namespace tflite { -namespace ops { -namespace micro { -namespace split_v { - -template -TfLiteStatus SplitImpl(TfLiteContext* context, TfLiteNode* node, - const TfLiteEvalTensor* input, int axis_value) { - const TfLiteIntArray* input_dims = input->dims; - const TfLiteEvalTensor* output0 = - tflite::micro::GetEvalOutput(context, node, 0); - - const int split_dimensions = input_dims->size; - - TFLITE_DCHECK_LT(axis_value, split_dimensions); - TFLITE_DCHECK_EQ(output0->dims->size, split_dimensions); - - int64_t split_size = 0; - const int output_count = NumOutputs(node); - for (int i = 0; i < output_count; i++) { - split_size += - tflite::micro::GetEvalOutput(context, node, i)->dims->data[axis_value]; - } - TFLITE_DCHECK_EQ(split_size, input_dims->data[axis_value]); - int64_t outer_size = 1; - for (int i = 0; i < axis_value; ++i) { - outer_size *= input_dims->data[i]; - } - - int64_t base_inner_size = 1; - for (int i = axis_value + 1; i < split_dimensions; ++i) { - base_inner_size *= input_dims->data[i]; - } - - const T* input_ptr = tflite::micro::GetTensorData(input); - for (int k = 0; k < outer_size; ++k) { - for (int i = 0; i < output_count; ++i) { - TfLiteEvalTensor* output_tensor = - tflite::micro::GetEvalOutput(context, node, i); - T* output_data = tflite::micro::GetTensorData(output_tensor); - const int copy_size = - output_tensor->dims->data[axis_value] * base_inner_size; - T* output_ptr = output_data + k * copy_size; - for (int j = 0; j < copy_size; ++j) output_ptr[j] = input_ptr[j]; - input_ptr += copy_size; - } - } - - return kTfLiteOk; -} - -TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { - TF_LITE_ENSURE_EQ(context, NumInputs(node), 3); - - MicroContext* micro_context = GetMicroContext(context); - // Dynamic output tensors are needed if axis tensor is not constant. - // But Micro doesn't support dynamic memory allocation, so we only support - // constant axis tensor for now. - TfLiteTensor* axis = micro_context->AllocateTempInputTensor(node, 2); - TF_LITE_ENSURE_MSG(context, IsConstantTensor(axis), - "Non constant axis tensor not supported"); - micro_context->DeallocateTempTfLiteTensor(axis); - return kTfLiteOk; -} - -TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { - const TfLiteEvalTensor* input = tflite::micro::GetEvalInput(context, node, 0); - const TfLiteEvalTensor* axis = tflite::micro::GetEvalInput(context, node, 2); - - int axis_value = tflite::micro::GetTensorData(axis)[0]; - if (axis_value < 0) { - axis_value += input->dims->size; - } - - TF_LITE_ENSURE(context, axis_value >= 0); - TF_LITE_ENSURE(context, axis_value < input->dims->size); - - switch (input->type) { - case kTfLiteFloat32: { - return SplitImpl(context, node, input, axis_value); - } - case kTfLiteInt8: { - return SplitImpl(context, node, input, axis_value); - } - case kTfLiteInt16: { - return SplitImpl(context, node, input, axis_value); - } - case kTfLiteInt32: { - return SplitImpl(context, node, input, axis_value); - } - default: - MicroPrintf("Type %s currently not supported.", - TfLiteTypeGetName(input->type)); - return kTfLiteError; - } - return kTfLiteOk; -} - -} // namespace split_v - -TfLiteRegistration Register_SPLIT_V() { - return tflite::micro::RegisterOp(nullptr, split_v::Prepare, split_v::Eval); -} - -} // namespace micro -} // namespace ops -} // namespace tflite +/* Copyright 2018 The TensorFlow Authors. All Rights Reserved. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +==============================================================================*/ + +#include "tensorflow/lite/c/builtin_op_data.h" +#include "tensorflow/lite/c/common.h" +#include "tensorflow/lite/kernels/internal/tensor_ctypes.h" +#include "tensorflow/lite/kernels/kernel_util.h" +#include "tensorflow/lite/kernels/op_macros.h" +#include "tensorflow/lite/micro/kernels/kernel_util.h" +#include "tensorflow/lite/micro/micro_log.h" + +namespace tflite { +namespace ops { +namespace micro { +namespace split_v { + +template +TfLiteStatus SplitImpl(TfLiteContext* context, TfLiteNode* node, + const TfLiteEvalTensor* input, int axis_value) { + const TfLiteIntArray* input_dims = input->dims; + const TfLiteEvalTensor* output0 = + tflite::micro::GetEvalOutput(context, node, 0); + + const int split_dimensions = input_dims->size; + + TFLITE_DCHECK_LT(axis_value, split_dimensions); + TFLITE_DCHECK_EQ(output0->dims->size, split_dimensions); + + int64_t split_size = 0; + const int output_count = NumOutputs(node); + for (int i = 0; i < output_count; i++) { + split_size += + tflite::micro::GetEvalOutput(context, node, i)->dims->data[axis_value]; + } + TFLITE_DCHECK_EQ(split_size, input_dims->data[axis_value]); + int64_t outer_size = 1; + for (int i = 0; i < axis_value; ++i) { + outer_size *= input_dims->data[i]; + } + + int64_t base_inner_size = 1; + for (int i = axis_value + 1; i < split_dimensions; ++i) { + base_inner_size *= input_dims->data[i]; + } + + const T* input_ptr = tflite::micro::GetTensorData(input); + for (int k = 0; k < outer_size; ++k) { + for (int i = 0; i < output_count; ++i) { + TfLiteEvalTensor* output_tensor = + tflite::micro::GetEvalOutput(context, node, i); + T* output_data = tflite::micro::GetTensorData(output_tensor); + const int copy_size = + output_tensor->dims->data[axis_value] * base_inner_size; + T* output_ptr = output_data + k * copy_size; + for (int j = 0; j < copy_size; ++j) output_ptr[j] = input_ptr[j]; + input_ptr += copy_size; + } + } + + return kTfLiteOk; +} + +TfLiteStatus Prepare(TfLiteContext* context, TfLiteNode* node) { + TF_LITE_ENSURE_EQ(context, NumInputs(node), 3); + + MicroContext* micro_context = GetMicroContext(context); + // Dynamic output tensors are needed if axis tensor is not constant. + // But Micro doesn't support dynamic memory allocation, so we only support + // constant axis tensor for now. + TfLiteTensor* axis = micro_context->AllocateTempInputTensor(node, 2); + TF_LITE_ENSURE_MSG(context, IsConstantTensor(axis), + "Non constant axis tensor not supported"); + micro_context->DeallocateTempTfLiteTensor(axis); + return kTfLiteOk; +} + +TfLiteStatus Eval(TfLiteContext* context, TfLiteNode* node) { + const TfLiteEvalTensor* input = tflite::micro::GetEvalInput(context, node, 0); + const TfLiteEvalTensor* axis = tflite::micro::GetEvalInput(context, node, 2); + + int axis_value = tflite::micro::GetTensorData(axis)[0]; + if (axis_value < 0) { + axis_value += input->dims->size; + } + + TF_LITE_ENSURE(context, axis_value >= 0); + TF_LITE_ENSURE(context, axis_value < input->dims->size); + + switch (input->type) { + case kTfLiteFloat32: { + return SplitImpl(context, node, input, axis_value); + } + case kTfLiteInt8: { + return SplitImpl(context, node, input, axis_value); + } + case kTfLiteInt16: { + return SplitImpl(context, node, input, axis_value); + } + case kTfLiteInt32: { + return SplitImpl(context, node, input, axis_value); + } + default: + MicroPrintf("Type %s currently not supported.", + TfLiteTypeGetName(input->type)); + return kTfLiteError; + } + return kTfLiteOk; +} + +} // namespace split_v + +TfLiteRegistration Register_SPLIT_V() { + return tflite::micro::RegisterOp(nullptr, split_v::Prepare, split_v::Eval); +} + +} // namespace micro +} // namespace ops +} // namespace tflite diff --git a/pio-tools/gzip-firmware.py b/pio-tools/gzip-firmware.py index 6dc5e6c7c..3be48d5c3 100644 --- a/pio-tools/gzip-firmware.py +++ b/pio-tools/gzip-firmware.py @@ -1,78 +1,78 @@ -Import("env") - -import pathlib -import shutil -import tasmotapiolib -import gzip -from colorama import Fore, Back, Style - -def map_gzip(source, target, env): - # create string with location and file names based on variant - map_file = pathlib.Path(tasmotapiolib.get_final_map_path(env)) - - if map_file.is_file(): - gzip_file = map_file.with_suffix(".map.gz") - - # check if new target map files exist and remove if necessary - if gzip_file.is_file(): - gzip_file.unlink() - - # write gzip map file - with map_file.open("rb") as fp: - with gzip.open(str(gzip_file), "wb", compresslevel=9) as f: - shutil.copyfileobj(fp, f) - - # remove map file - if map_file.is_file(): - map_file.unlink() - - -if not tasmotapiolib.is_env_set(tasmotapiolib.DISABLE_MAP_GZ, env): - silent_action = env.Action([map_gzip]) - silent_action.strfunction = lambda target, source, env: '' # hack to silence scons command output - env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", silent_action) - -if tasmotapiolib.is_env_set(tasmotapiolib.ENABLE_ESP32_GZ, env) or env["PIOPLATFORM"] != "espressif32": - import time - - gzip_level = int(env['ENV'].get('GZIP_LEVEL', 10)) - - def bin_gzip(source, target, env): - # create string with location and file names based on variant - bin_file = pathlib.Path(tasmotapiolib.get_final_bin_path(env)) - gzip_file = bin_file.with_suffix(".bin.gz") - - # check if new target files exist and remove if necessary - if gzip_file.is_file(): - gzip_file.unlink() - - # write gzip firmware file - with bin_file.open("rb") as fp: - with gzip_file.open("wb") as f: - time_start = time.time() - gz = tasmotapiolib.compress(fp.read(), gzip_level) - time_delta = time.time() - time_start - f.write(gz) - - ORG_FIRMWARE_SIZE = bin_file.stat().st_size - GZ_FIRMWARE_SIZE = gzip_file.stat().st_size - - print() - if ORG_FIRMWARE_SIZE > 995326 and env["PIOPLATFORM"] != "espressif32": - print(Fore.RED + "!!! Tasmota firmware size is too big with {} bytes. Max size is 995326 bytes !!! ".format( - ORG_FIRMWARE_SIZE - ) - ) - else: - print(Fore.GREEN + "Compression reduced firmware size to {:.0f}% (was {} bytes, now {} bytes, took {:.3f} seconds)".format( - (GZ_FIRMWARE_SIZE / ORG_FIRMWARE_SIZE) * 100, - ORG_FIRMWARE_SIZE, - GZ_FIRMWARE_SIZE, - time_delta, - ) - ) - - if not tasmotapiolib.is_env_set(tasmotapiolib.DISABLE_BIN_GZ, env): - silent_action = env.Action([bin_gzip]) - silent_action.strfunction = lambda target, source, env: '' # hack to silence scons command output - env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", silent_action) +Import("env") + +import pathlib +import shutil +import tasmotapiolib +import gzip +from colorama import Fore, Back, Style + +def map_gzip(source, target, env): + # create string with location and file names based on variant + map_file = pathlib.Path(tasmotapiolib.get_final_map_path(env)) + + if map_file.is_file(): + gzip_file = map_file.with_suffix(".map.gz") + + # check if new target map files exist and remove if necessary + if gzip_file.is_file(): + gzip_file.unlink() + + # write gzip map file + with map_file.open("rb") as fp: + with gzip.open(str(gzip_file), "wb", compresslevel=9) as f: + shutil.copyfileobj(fp, f) + + # remove map file + if map_file.is_file(): + map_file.unlink() + + +if not tasmotapiolib.is_env_set(tasmotapiolib.DISABLE_MAP_GZ, env): + silent_action = env.Action([map_gzip]) + silent_action.strfunction = lambda target, source, env: '' # hack to silence scons command output + env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", silent_action) + +if tasmotapiolib.is_env_set(tasmotapiolib.ENABLE_ESP32_GZ, env) or env["PIOPLATFORM"] != "espressif32": + import time + + gzip_level = int(env['ENV'].get('GZIP_LEVEL', 10)) + + def bin_gzip(source, target, env): + # create string with location and file names based on variant + bin_file = pathlib.Path(tasmotapiolib.get_final_bin_path(env)) + gzip_file = bin_file.with_suffix(".bin.gz") + + # check if new target files exist and remove if necessary + if gzip_file.is_file(): + gzip_file.unlink() + + # write gzip firmware file + with bin_file.open("rb") as fp: + with gzip_file.open("wb") as f: + time_start = time.time() + gz = tasmotapiolib.compress(fp.read(), gzip_level) + time_delta = time.time() - time_start + f.write(gz) + + ORG_FIRMWARE_SIZE = bin_file.stat().st_size + GZ_FIRMWARE_SIZE = gzip_file.stat().st_size + + print() + if ORG_FIRMWARE_SIZE > 995326 and env["PIOPLATFORM"] != "espressif32": + print(Fore.RED + "!!! Tasmota firmware size is too big with {} bytes. Max size is 995326 bytes !!! ".format( + ORG_FIRMWARE_SIZE + ) + ) + else: + print(Fore.GREEN + "Compression reduced firmware size to {:.0f}% (was {} bytes, now {} bytes, took {:.3f} seconds)".format( + (GZ_FIRMWARE_SIZE / ORG_FIRMWARE_SIZE) * 100, + ORG_FIRMWARE_SIZE, + GZ_FIRMWARE_SIZE, + time_delta, + ) + ) + + if not tasmotapiolib.is_env_set(tasmotapiolib.DISABLE_BIN_GZ, env): + silent_action = env.Action([bin_gzip]) + silent_action.strfunction = lambda target, source, env: '' # hack to silence scons command output + env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", silent_action) diff --git a/pio-tools/name-firmware.py b/pio-tools/name-firmware.py index 3c00b9dc1..63490f515 100644 --- a/pio-tools/name-firmware.py +++ b/pio-tools/name-firmware.py @@ -1,53 +1,53 @@ -Import("env") - -import os -import shutil -import pathlib -import tasmotapiolib -from os.path import join -from colorama import Fore, Back, Style - - -def bin_map_copy(source, target, env): - firsttarget = pathlib.Path(target[0].path) - - # get locations and file names based on variant - map_file = os.path.normpath(str(tasmotapiolib.get_final_map_path(env))) - bin_file = os.path.normpath(str(tasmotapiolib.get_final_bin_path(env))) - one_bin_file = bin_file - firmware_name = env.subst("$BUILD_DIR/${PROGNAME}.bin") - if env["PIOPLATFORM"] == "espressif32": - if("safeboot" in firmware_name): - SAFEBOOT_SIZE = firsttarget.stat().st_size - if SAFEBOOT_SIZE > 851967: - print(Fore.RED + "!!! Tasmota safeboot size is too big with {} bytes. Max size is 851967 bytes !!! ".format( - SAFEBOOT_SIZE - ) - ) - if("safeboot" not in firmware_name): - factory_tmp = pathlib.Path(firsttarget).with_suffix("") - factory = os.path.normpath(str(factory_tmp.with_suffix(factory_tmp.suffix + ".factory.bin"))) - one_bin_tmp = pathlib.Path(bin_file).with_suffix("") - one_bin_file = os.path.normpath(str(one_bin_tmp.with_suffix(one_bin_tmp.suffix + ".factory.bin"))) - - # check if new target files exist and remove if necessary - for f in [map_file, bin_file, one_bin_file]: - f_path = pathlib.Path(f) - if f_path.is_file(): - f_path.unlink() - - # copy firmware.bin and map to final destination - shutil.copy(str(firsttarget), bin_file) - if env["PIOPLATFORM"] == "espressif32": - # the map file is needed later for firmware-metrics.py - shutil.copy(os.path.normpath(str(tasmotapiolib.get_source_map_path(env))), map_file) - if("safeboot" not in firmware_name): - shutil.copy(factory, one_bin_file) - else: - map_firm = os.path.normpath(join(env.subst("$BUILD_DIR"), "firmware.map")) - shutil.copy(os.path.normpath(str(tasmotapiolib.get_source_map_path(env))), map_firm) - shutil.move(os.path.normpath(str(tasmotapiolib.get_source_map_path(env))), map_file) - -silent_action = env.Action(bin_map_copy) -silent_action.strfunction = lambda target, source, env: '' # hack to silence scons command output -env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", silent_action) +Import("env") + +import os +import shutil +import pathlib +import tasmotapiolib +from os.path import join +from colorama import Fore, Back, Style + + +def bin_map_copy(source, target, env): + firsttarget = pathlib.Path(target[0].path) + + # get locations and file names based on variant + map_file = os.path.normpath(str(tasmotapiolib.get_final_map_path(env))) + bin_file = os.path.normpath(str(tasmotapiolib.get_final_bin_path(env))) + one_bin_file = bin_file + firmware_name = env.subst("$BUILD_DIR/${PROGNAME}.bin") + if env["PIOPLATFORM"] == "espressif32": + if("safeboot" in firmware_name): + SAFEBOOT_SIZE = firsttarget.stat().st_size + if SAFEBOOT_SIZE > 851967: + print(Fore.RED + "!!! Tasmota safeboot size is too big with {} bytes. Max size is 851967 bytes !!! ".format( + SAFEBOOT_SIZE + ) + ) + if("safeboot" not in firmware_name): + factory_tmp = pathlib.Path(firsttarget).with_suffix("") + factory = os.path.normpath(str(factory_tmp.with_suffix(factory_tmp.suffix + ".factory.bin"))) + one_bin_tmp = pathlib.Path(bin_file).with_suffix("") + one_bin_file = os.path.normpath(str(one_bin_tmp.with_suffix(one_bin_tmp.suffix + ".factory.bin"))) + + # check if new target files exist and remove if necessary + for f in [map_file, bin_file, one_bin_file]: + f_path = pathlib.Path(f) + if f_path.is_file(): + f_path.unlink() + + # copy firmware.bin and map to final destination + shutil.copy(str(firsttarget), bin_file) + if env["PIOPLATFORM"] == "espressif32": + # the map file is needed later for firmware-metrics.py + shutil.copy(os.path.normpath(str(tasmotapiolib.get_source_map_path(env))), map_file) + if("safeboot" not in firmware_name): + shutil.copy(factory, one_bin_file) + else: + map_firm = os.path.normpath(join(env.subst("$BUILD_DIR"), "firmware.map")) + shutil.copy(os.path.normpath(str(tasmotapiolib.get_source_map_path(env))), map_firm) + shutil.move(os.path.normpath(str(tasmotapiolib.get_source_map_path(env))), map_file) + +silent_action = env.Action(bin_map_copy) +silent_action.strfunction = lambda target, source, env: '' # hack to silence scons command output +env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", silent_action) diff --git a/pio-tools/override_copy.py b/pio-tools/override_copy.py index 96d6c520c..237fe480f 100644 --- a/pio-tools/override_copy.py +++ b/pio-tools/override_copy.py @@ -1,46 +1,46 @@ -Import('env') - - -import os -import pathlib -import shutil -from colorama import Fore, Back, Style - -# Ensure the variants directory is correctly formatted based on the OS -# This is necessary to avoid issues with path handling in different environments -variants_dir = env.BoardConfig().get("build.variants_dir", "") -if variants_dir: - if os.name == "nt": - variants_dir = variants_dir.replace("/", "\\") - env.BoardConfig().update("build.variants_dir", variants_dir) - else: - variants_dir = variants_dir.replace("\\", "/") - env.BoardConfig().update("build.variants_dir", variants_dir) - -project_dir = os.path.normpath(env["PROJECT_DIR"]) -if " " in project_dir: - print(Fore.RED + "*** Whitespace(s) in project path, unexpected issues/errors can happen ***") - -# copy tasmota/user_config_override_sample.h to tasmota/user_config_override.h -uc_override = pathlib.Path(os.path.normpath("tasmota/user_config_override.h")) -uc_override_sample = pathlib.Path(os.path.normpath("tasmota/user_config_override_sample.h")) -if uc_override.is_file(): - print(Fore.GREEN + "*** use provided user_config_override.h as planned ***") -else: - shutil.copy(str(uc_override_sample), str(uc_override)) - -# copy platformio_override_sample.ini to platformio_override.ini -pio_override = pathlib.Path(os.path.normpath("platformio_override.ini")) -pio_override_sample = pathlib.Path(os.path.normpath("platformio_override_sample.ini")) -if pio_override.is_file(): - print(Fore.GREEN + "*** use provided platformio_override.ini as planned ***") -else: - shutil.copy(str(pio_override_sample), str(pio_override)) - -# copy platformio_tasmota_cenv_sample.ini to platformio_tasmota_cenv.ini -pio_cenv = pathlib.Path(os.path.normpath("platformio_tasmota_cenv.ini")) -pio_cenv_sample = pathlib.Path(os.path.normpath("platformio_tasmota_cenv_sample.ini")) -if pio_cenv.is_file(): - print(Fore.GREEN + "*** use provided platformio_tasmota_cenv.ini as planned ***") -else: - shutil.copy(str(pio_cenv_sample), str(pio_cenv)) +Import('env') + + +import os +import pathlib +import shutil +from colorama import Fore, Back, Style + +# Ensure the variants directory is correctly formatted based on the OS +# This is necessary to avoid issues with path handling in different environments +variants_dir = env.BoardConfig().get("build.variants_dir", "") +if variants_dir: + if os.name == "nt": + variants_dir = variants_dir.replace("/", "\\") + env.BoardConfig().update("build.variants_dir", variants_dir) + else: + variants_dir = variants_dir.replace("\\", "/") + env.BoardConfig().update("build.variants_dir", variants_dir) + +project_dir = os.path.normpath(env["PROJECT_DIR"]) +if " " in project_dir: + print(Fore.RED + "*** Whitespace(s) in project path, unexpected issues/errors can happen ***") + +# copy tasmota/user_config_override_sample.h to tasmota/user_config_override.h +uc_override = pathlib.Path(os.path.normpath("tasmota/user_config_override.h")) +uc_override_sample = pathlib.Path(os.path.normpath("tasmota/user_config_override_sample.h")) +if uc_override.is_file(): + print(Fore.GREEN + "*** use provided user_config_override.h as planned ***") +else: + shutil.copy(str(uc_override_sample), str(uc_override)) + +# copy platformio_override_sample.ini to platformio_override.ini +pio_override = pathlib.Path(os.path.normpath("platformio_override.ini")) +pio_override_sample = pathlib.Path(os.path.normpath("platformio_override_sample.ini")) +if pio_override.is_file(): + print(Fore.GREEN + "*** use provided platformio_override.ini as planned ***") +else: + shutil.copy(str(pio_override_sample), str(pio_override)) + +# copy platformio_tasmota_cenv_sample.ini to platformio_tasmota_cenv.ini +pio_cenv = pathlib.Path(os.path.normpath("platformio_tasmota_cenv.ini")) +pio_cenv_sample = pathlib.Path(os.path.normpath("platformio_tasmota_cenv_sample.ini")) +if pio_cenv.is_file(): + print(Fore.GREEN + "*** use provided platformio_tasmota_cenv.ini as planned ***") +else: + shutil.copy(str(pio_cenv_sample), str(pio_cenv)) diff --git a/platformio.ini b/platformio.ini index 098c96f96..012cee3d9 100644 --- a/platformio.ini +++ b/platformio.ini @@ -1,147 +1,147 @@ -; PlatformIO Project Configuration File -; -; Build options: build flags, source filter, extra scripting -; Upload options: custom port, speed and extra flags -; Library options: dependencies, extra library storages -; -; Please visit documentation for the other options and examples -; http://docs.platformio.org/en/stable/projectconf.html -; -; ********************************************************************* -; *** Selection of Tasmota build variant is done with VSC -; *** alternatively can be done in: platformio_override.ini -; *** See example: platformio_override_sample.ini -; ********************************************************************* - -[platformio] -description = Provide ESP8266 / ESP32 based devices with Web, MQTT and OTA firmware -src_dir = tasmota -lib_dir = lib/default -boards_dir = boards -build_cache_dir = .cache -extra_configs = platformio_tasmota32.ini - platformio_tasmota_env.ini - platformio_tasmota_env32.ini - platformio_override.ini - platformio_tasmota_cenv.ini - -[common] -platform = ${core.platform} -platform_packages = ${core.platform_packages} -framework = arduino -board = esp8266_1M -board_build.filesystem = littlefs -board_build.littlefs_version = 2.0 -board_build.variants_dir = variants/tasmota -custom_unpack_dir = unpacked_littlefs -build_unflags = ${core.build_unflags} -build_flags = ${core.build_flags} -monitor_speed = 115200 -monitor_echo = yes -; *** Upload Serial reset method for Wemos and NodeMCU -upload_resetmethod = nodemcu -check_skip_packages = yes -extra_scripts = ${esp_defaults.extra_scripts} -lib_archive = no -lib_ldf_mode = chain -lib_compat_mode = strict -shared_libdeps_dir = lib -lib_extra_dirs = - lib/lib_basic - lib/lib_i2c - lib/lib_display - lib/lib_ssl - lib/lib_audio - lib/lib_rf - lib/lib_div - -[tasmota] -; Uncomment if you do NOT want gzipped map file(s) -;disable_map_gz = 1 -; Uncomment and specify a folder where to place the map file(s) (default set to folder build_output) -;map_dir = /tmp/map_files/ -; Uncomment if you do NOT want additionally gzipped firmware file(s) at all -;disable_bin_gz = 1 -; Uncomment if you want additionally gzipped esp32x firmware file(s) -;enable_esp32_gz = 1 -; Uncomment and specify a folder where to place the firmware file(s) (default set to folder build_output) -;bin_dir = /tmp/bin_files/ -; Global build flags (used for all env) can be overridden in "platformio_override.ini" -build_unflags = -build_flags = - -[scripts_defaults] -extra_scripts = pre:pio-tools/pre_source_dir.py - pre:pio-tools/set_partition_table.py - pre:pio-tools/override_copy.py - pre:pio-tools/compress-html.py - pre:pio-tools/port-vsc.py - post:pio-tools/strip-flags.py - -[esp_defaults] -extra_scripts = post:pio-tools/name-firmware.py - post:pio-tools/gzip-firmware.py - post:pio-tools/metrics-firmware.py - pre:pio-tools/custom_target.py -; post:pio-tools/obj-dump.py - ${scripts_defaults.extra_scripts} -; *** remove undesired all warnings -build_unflags = ${tasmota.build_unflags} - -Wall -; -mtarget-align - -Wdeprecated-declarations -build_flags = ${tasmota.build_flags} - -DCORE_DEBUG_LEVEL=0 - -Wl,-Map,firmware.map - -Wno-deprecated-declarations -; -mno-target-align - -mtarget-align - -free - -fipa-pta - -Wreturn-type - -DTASMOTA ; flag indicating that we are compiling Tasmota -; ********************************************************************* -; *** Use custom settings from file user_config_override.h - -DUSE_CONFIG_OVERRIDE -; ********************************************************************* - -[esp82xx_defaults] -extra_scripts = ${esp_defaults.extra_scripts} -build_flags = ${esp_defaults.build_flags} - -DNDEBUG - -DFP_IN_IROM - -DBEARSSL_SSL_BASIC - ; NONOSDK22x_190703 = 2.2.2-dev(38a443e) - -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703 - -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH - ; -DPIO_FRAMEWORK_ARDUINO_LWIP2_IPV6_HIGHER_BANDWIDTH -DUSE_IPV6 ; enables IPv6 - ; VTABLES in Flash - -DVTABLES_IN_FLASH - ; remove the 4-bytes alignment for PSTR() - -DPSTR_ALIGN=1 - ; restrict to minimal mime-types - -DMIMETYPE_MINIMAL - ; uncomment the following to enable TLS with 4096 RSA certificates - ;-DUSE_4K_RSA -lib_ignore = ESP8266Audio - ESP8266SAM - ESP8266LLMNR - ESP8266NetBIOS - ESP8266SSDP - ESP8266WiFiMesh - GDBStub - ESP8266HTTPUpdateServer - SPISlave - Hash -; Disable next if you want to use ArduinoOTA in Tasmota (default disabled) - ArduinoOTA - -[core] -; *** Esp8266 Tasmota modified Arduino core based on core 2.7.4. Added Backport for PWM selection -platform = https://github.com/tasmota/platform-espressif8266/releases/download/2026.01.00/platform-espressif8266.zip -platform_packages = -build_unflags = ${esp_defaults.build_unflags} -build_flags = ${esp82xx_defaults.build_flags} -; *** Use ONE of the two PWM variants. Tasmota default is Locked PWM - ;-DWAVEFORM_LOCKED_PHASE - -DWAVEFORM_LOCKED_PWM +; PlatformIO Project Configuration File +; +; Build options: build flags, source filter, extra scripting +; Upload options: custom port, speed and extra flags +; Library options: dependencies, extra library storages +; +; Please visit documentation for the other options and examples +; http://docs.platformio.org/en/stable/projectconf.html +; +; ********************************************************************* +; *** Selection of Tasmota build variant is done with VSC +; *** alternatively can be done in: platformio_override.ini +; *** See example: platformio_override_sample.ini +; ********************************************************************* + +[platformio] +description = Provide ESP8266 / ESP32 based devices with Web, MQTT and OTA firmware +src_dir = tasmota +lib_dir = lib/default +boards_dir = boards +build_cache_dir = .cache +extra_configs = platformio_tasmota32.ini + platformio_tasmota_env.ini + platformio_tasmota_env32.ini + platformio_override.ini + platformio_tasmota_cenv.ini + +[common] +platform = ${core.platform} +platform_packages = ${core.platform_packages} +framework = arduino +board = esp8266_1M +board_build.filesystem = littlefs +board_build.littlefs_version = 2.0 +board_build.variants_dir = variants/tasmota +custom_unpack_dir = unpacked_littlefs +build_unflags = ${core.build_unflags} +build_flags = ${core.build_flags} +monitor_speed = 115200 +monitor_echo = yes +; *** Upload Serial reset method for Wemos and NodeMCU +upload_resetmethod = nodemcu +check_skip_packages = yes +extra_scripts = ${esp_defaults.extra_scripts} +lib_archive = no +lib_ldf_mode = chain +lib_compat_mode = strict +shared_libdeps_dir = lib +lib_extra_dirs = + lib/lib_basic + lib/lib_i2c + lib/lib_display + lib/lib_ssl + lib/lib_audio + lib/lib_rf + lib/lib_div + +[tasmota] +; Uncomment if you do NOT want gzipped map file(s) +;disable_map_gz = 1 +; Uncomment and specify a folder where to place the map file(s) (default set to folder build_output) +;map_dir = /tmp/map_files/ +; Uncomment if you do NOT want additionally gzipped firmware file(s) at all +;disable_bin_gz = 1 +; Uncomment if you want additionally gzipped esp32x firmware file(s) +;enable_esp32_gz = 1 +; Uncomment and specify a folder where to place the firmware file(s) (default set to folder build_output) +;bin_dir = /tmp/bin_files/ +; Global build flags (used for all env) can be overridden in "platformio_override.ini" +build_unflags = +build_flags = + +[scripts_defaults] +extra_scripts = pre:pio-tools/pre_source_dir.py + pre:pio-tools/set_partition_table.py + pre:pio-tools/override_copy.py + pre:pio-tools/compress-html.py + pre:pio-tools/port-vsc.py + post:pio-tools/strip-flags.py + +[esp_defaults] +extra_scripts = post:pio-tools/name-firmware.py + post:pio-tools/gzip-firmware.py + post:pio-tools/metrics-firmware.py + pre:pio-tools/custom_target.py +; post:pio-tools/obj-dump.py + ${scripts_defaults.extra_scripts} +; *** remove undesired all warnings +build_unflags = ${tasmota.build_unflags} + -Wall +; -mtarget-align + -Wdeprecated-declarations +build_flags = ${tasmota.build_flags} + -DCORE_DEBUG_LEVEL=0 + -Wl,-Map,firmware.map + -Wno-deprecated-declarations +; -mno-target-align + -mtarget-align + -free + -fipa-pta + -Wreturn-type + -DTASMOTA ; flag indicating that we are compiling Tasmota +; ********************************************************************* +; *** Use custom settings from file user_config_override.h + -DUSE_CONFIG_OVERRIDE +; ********************************************************************* + +[esp82xx_defaults] +extra_scripts = ${esp_defaults.extra_scripts} +build_flags = ${esp_defaults.build_flags} + -DNDEBUG + -DFP_IN_IROM + -DBEARSSL_SSL_BASIC + ; NONOSDK22x_190703 = 2.2.2-dev(38a443e) + -DPIO_FRAMEWORK_ARDUINO_ESPRESSIF_SDK22x_190703 + -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH_LOW_FLASH + ; -DPIO_FRAMEWORK_ARDUINO_LWIP2_IPV6_HIGHER_BANDWIDTH -DUSE_IPV6 ; enables IPv6 + ; VTABLES in Flash + -DVTABLES_IN_FLASH + ; remove the 4-bytes alignment for PSTR() + -DPSTR_ALIGN=1 + ; restrict to minimal mime-types + -DMIMETYPE_MINIMAL + ; uncomment the following to enable TLS with 4096 RSA certificates + ;-DUSE_4K_RSA +lib_ignore = ESP8266Audio + ESP8266SAM + ESP8266LLMNR + ESP8266NetBIOS + ESP8266SSDP + ESP8266WiFiMesh + GDBStub + ESP8266HTTPUpdateServer + SPISlave + Hash +; Disable next if you want to use ArduinoOTA in Tasmota (default disabled) + ArduinoOTA + +[core] +; *** Esp8266 Tasmota modified Arduino core based on core 2.7.4. Added Backport for PWM selection +platform = https://github.com/tasmota/platform-espressif8266/releases/download/2026.01.00/platform-espressif8266.zip +platform_packages = +build_unflags = ${esp_defaults.build_unflags} +build_flags = ${esp82xx_defaults.build_flags} +; *** Use ONE of the two PWM variants. Tasmota default is Locked PWM + ;-DWAVEFORM_LOCKED_PHASE + -DWAVEFORM_LOCKED_PWM diff --git a/platformio_override_sample.ini b/platformio_override_sample.ini index b66752e40..3bd027ac6 100644 --- a/platformio_override_sample.ini +++ b/platformio_override_sample.ini @@ -1,133 +1,133 @@ -; *** Example PlatformIO Project Configuration Override File *** -; *** Changes done here override settings in platformio.ini *** -; -; ***************************************************************** -; *** to activate rename this file to platformio_override.ini *** -; ***************************************************************** -; -; Please visit documentation for the options and examples -; http://docs.platformio.org/en/stable/projectconf.html - -[platformio] -; For best Gitpod performance remove the ";" in the next line. Needed Platformio files are cached and installed at first run -;core_dir = .platformio -; For unrelated compile errors with Windows it can help to shorten Platformio project path -;workspace_dir = c:\.pio -;extra_configs = platformio_tasmota_user_env.ini - -; *** Build/upload environment -default_envs = -; *** Uncomment the line(s) below to select version(s) - tasmota -; tasmota-debug -; tasmota-minimal -; tasmota-lite -; tasmota-knx -; tasmota-sensors -; tasmota-display -; tasmota-zbbridge -; tasmota-ir -; tasmota32 -; tasmota32solo1 -; tasmota32s2 -; tasmota32s2cdc -; tasmota32s3 -; tasmota32c2 -; tasmota32c3 -; tasmota32c6 -; tasmota32-zbbrdgpro -; tasmota32-bluetooth -; tasmota32-webcam -; tasmota32-knx -; tasmota32-lvgl -; tasmota32-ir -; tasmota32-nspanel -; tasmota32c3ser -; tasmota32c6ser -; tasmota32s3ser - -[tasmota] -; *** Global build / unbuild compile time flags for ALL Tasmota / Tasmota32 [env] -;build_unflags = -;build_flags = - -[env] -;build_unflags = ${common.build_unflags} -; -Wswitch-unreachable -;build_flags = ${common.build_flags} -; -DF_CRYSTAL=26000000 -; -Wno-switch-unreachable -; *** Optional Debug messages -; -DDEBUG_TASMOTA_CORE -; -DDEBUG_TASMOTA_DRIVER -; -DDEBUG_TASMOTA_SENSOR -; Build variant 1MB = 1MB firmware no filesystem (default) -;board = ${common.board} -; Build variant 2MB = 1MB firmware, 1MB filesystem (most Shelly devices) -;board = esp8266_2M1M -; Build variant 4MB = 1MB firmware, 1MB OTA, 2MB filesystem (WEMOS D1 Mini, NodeMCU, Sonoff POW) -;board = esp8266_4M2M -;board_build.f_cpu = 160000000L -;board_build.f_flash = 40000000L -; *** Define serial port used for erasing/flashing/terminal -;upload_port = COM4 -;monitor_port = COM4 -lib_extra_dirs = ${library.lib_extra_dirs} - - -[env:tasmota32_base] -; *** Uncomment next lines ";" to enable development Tasmota Arduino version ESP32 -;platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152 - -;platform_packages = framework-arduinoespressif32 @ -;build_unflags = ${esp32_defaults.build_unflags} -;build_flags = ${esp32_defaults.build_flags} -;board = esp32 -;board_build.f_cpu = 240000000L -;board_build.f_flash = 40000000L -;board_build.flash_mode = qio -;board_build.flash_size = 8MB -;board_upload.maximum_size = 8388608 -;board_upload.arduino.flash_extra_images = -;board_build.partitions = partitions/esp32_partition_app2944k_fs2M.csv -; *** Serial port used for erasing/flashing the ESP32 -;upload_port = COM4 -;monitor_port = COM4 -;upload_speed = 115200 -monitor_speed = 115200 -;upload_resetmethod = ${common.upload_resetmethod} -lib_extra_dirs = ${library.lib_extra_dirs} -; *** ESP32 lib. ALWAYS needed for ESP32 !!! - lib/libesp32 -; *** comment the following line if you dont use LVGL in a Tasmota32 build. Reduces compile time - lib/libesp32_lvgl -; *** uncomment the following line if you use Bluetooth or Apple Homekit in a Tasmota32 build. Reduces compile time - lib/libesp32_div -; *** uncomment the following line if you use Epaper driver epidy in your Tasmota32 build. Reduces compile time -; lib/libesp32_eink - - -[library] -shared_libdeps_dir = lib -; *** Library disable / enable for variant Tasmota(32). Disable reduces compile time -; *** !!! Disabling needed libs will generate compile errors !!! -; *** The resulting firmware will NOT be different if you leave all libs enabled -; *** Disabling by putting a ";" in front of the lib name -; *** If you dont know what it is all about, do not change -lib_extra_dirs = -; *** Only disabled for Tasmota minimal and Tasmota light. For all other variants needed! - lib/lib_basic -; **** I2C devices. Most sensors. Disable only if you dont have ANY I2C device enabled - lib/lib_i2c -; *** Displays. Disable if you dont have any Display activated - lib/lib_display -; *** Bear SSL and base64. Disable if you dont have SSL or TLS activated - lib/lib_ssl -; *** Audio needs a lot of time to compile. Mostly not used functions. Recommended to disable - lib/lib_audio -; *** RF 433 stuff (not RF Bridge). Recommended to disable - lib/lib_rf -; *** Mostly not used functions. Recommended to disable - lib/lib_div - - +; *** Example PlatformIO Project Configuration Override File *** +; *** Changes done here override settings in platformio.ini *** +; +; ***************************************************************** +; *** to activate rename this file to platformio_override.ini *** +; ***************************************************************** +; +; Please visit documentation for the options and examples +; http://docs.platformio.org/en/stable/projectconf.html + +[platformio] +; For best Gitpod performance remove the ";" in the next line. Needed Platformio files are cached and installed at first run +;core_dir = .platformio +; For unrelated compile errors with Windows it can help to shorten Platformio project path +;workspace_dir = c:\.pio +;extra_configs = platformio_tasmota_user_env.ini + +; *** Build/upload environment +default_envs = +; *** Uncomment the line(s) below to select version(s) + tasmota +; tasmota-debug +; tasmota-minimal +; tasmota-lite +; tasmota-knx +; tasmota-sensors +; tasmota-display +; tasmota-zbbridge +; tasmota-ir +; tasmota32 +; tasmota32solo1 +; tasmota32s2 +; tasmota32s2cdc +; tasmota32s3 +; tasmota32c2 +; tasmota32c3 +; tasmota32c6 +; tasmota32-zbbrdgpro +; tasmota32-bluetooth +; tasmota32-webcam +; tasmota32-knx +; tasmota32-lvgl +; tasmota32-ir +; tasmota32-nspanel +; tasmota32c3ser +; tasmota32c6ser +; tasmota32s3ser + +[tasmota] +; *** Global build / unbuild compile time flags for ALL Tasmota / Tasmota32 [env] +;build_unflags = +;build_flags = + +[env] +;build_unflags = ${common.build_unflags} +; -Wswitch-unreachable +;build_flags = ${common.build_flags} +; -DF_CRYSTAL=26000000 +; -Wno-switch-unreachable +; *** Optional Debug messages +; -DDEBUG_TASMOTA_CORE +; -DDEBUG_TASMOTA_DRIVER +; -DDEBUG_TASMOTA_SENSOR +; Build variant 1MB = 1MB firmware no filesystem (default) +;board = ${common.board} +; Build variant 2MB = 1MB firmware, 1MB filesystem (most Shelly devices) +;board = esp8266_2M1M +; Build variant 4MB = 1MB firmware, 1MB OTA, 2MB filesystem (WEMOS D1 Mini, NodeMCU, Sonoff POW) +;board = esp8266_4M2M +;board_build.f_cpu = 160000000L +;board_build.f_flash = 40000000L +; *** Define serial port used for erasing/flashing/terminal +;upload_port = COM4 +;monitor_port = COM4 +lib_extra_dirs = ${library.lib_extra_dirs} + + +[env:tasmota32_base] +; *** Uncomment next lines ";" to enable development Tasmota Arduino version ESP32 +;platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152 + +;platform_packages = framework-arduinoespressif32 @ +;build_unflags = ${esp32_defaults.build_unflags} +;build_flags = ${esp32_defaults.build_flags} +;board = esp32 +;board_build.f_cpu = 240000000L +;board_build.f_flash = 40000000L +;board_build.flash_mode = qio +;board_build.flash_size = 8MB +;board_upload.maximum_size = 8388608 +;board_upload.arduino.flash_extra_images = +;board_build.partitions = partitions/esp32_partition_app2944k_fs2M.csv +; *** Serial port used for erasing/flashing the ESP32 +;upload_port = COM4 +;monitor_port = COM4 +;upload_speed = 115200 +monitor_speed = 115200 +;upload_resetmethod = ${common.upload_resetmethod} +lib_extra_dirs = ${library.lib_extra_dirs} +; *** ESP32 lib. ALWAYS needed for ESP32 !!! + lib/libesp32 +; *** comment the following line if you dont use LVGL in a Tasmota32 build. Reduces compile time + lib/libesp32_lvgl +; *** uncomment the following line if you use Bluetooth or Apple Homekit in a Tasmota32 build. Reduces compile time + lib/libesp32_div +; *** uncomment the following line if you use Epaper driver epidy in your Tasmota32 build. Reduces compile time +; lib/libesp32_eink + + +[library] +shared_libdeps_dir = lib +; *** Library disable / enable for variant Tasmota(32). Disable reduces compile time +; *** !!! Disabling needed libs will generate compile errors !!! +; *** The resulting firmware will NOT be different if you leave all libs enabled +; *** Disabling by putting a ";" in front of the lib name +; *** If you dont know what it is all about, do not change +lib_extra_dirs = +; *** Only disabled for Tasmota minimal and Tasmota light. For all other variants needed! + lib/lib_basic +; **** I2C devices. Most sensors. Disable only if you dont have ANY I2C device enabled + lib/lib_i2c +; *** Displays. Disable if you dont have any Display activated + lib/lib_display +; *** Bear SSL and base64. Disable if you dont have SSL or TLS activated + lib/lib_ssl +; *** Audio needs a lot of time to compile. Mostly not used functions. Recommended to disable + lib/lib_audio +; *** RF 433 stuff (not RF Bridge). Recommended to disable + lib/lib_rf +; *** Mostly not used functions. Recommended to disable + lib/lib_div + + diff --git a/platformio_tasmota32.ini b/platformio_tasmota32.ini index 1b3383837..3db1aca6c 100644 --- a/platformio_tasmota32.ini +++ b/platformio_tasmota32.ini @@ -1,105 +1,105 @@ -; *** ESP32 Tasmota version *** - -[esp32_defaults] -build_unflags = ${esp_defaults.build_unflags} - -mtarget-align - -Wswitch-unreachable - -Wstringop-overflow - -Wincompatible-pointer-types - -Wnonnull-compare - -fexceptions - -Wpointer-arith -build_flags = ${esp_defaults.build_flags} - ; comment next line to disable IPv6 support - -DUSE_IPV6 - -mno-target-align - -Wno-switch-unreachable - -Wno-stringop-overflow - -fno-exceptions - -ffunction-sections - -fdata-sections - -Wl,--gc-sections - -DBUFFER_LENGTH=128 - -DHTTP_UPLOAD_BUFLEN=2048 - -DMQTT_MAX_PACKET_SIZE=1200 - -Duint32=uint32_t - -Duint16=uint16_t - -Duint8=uint8_t - -Dsint8_t=int8_t - -Dsint32_t=int32_t - -Dsint16_t=int16_t - -Dmemcpy_P=memcpy - -Dmemcmp_P=memcmp - -DUSE_SHA_ROM - ;for TLS we can afford compiling for 4K RSA keys - -DUSE_4K_RSA - -I$PROJECT_DIR/include - -include "sdkconfig.h" - -include "esp32x_fixes.h" - ; wrappers for the crash-recorder - -Wl,--wrap=panicHandler -Wl,--wrap=xt_unhandled_exception - -Wl,--wrap=_Z11analogWritehi ; `analogWrite(unsigned char, int)` use the Tasmota version of analogWrite for deeper integration and phase control - -Wl,--wrap=ledcReadFreq ; `uint32_t ledcReadFreq(uint8_t chan)` - -Wl,--wrap=delay ; void delay(uint32_t ms) -lib_ignore = - HTTPUpdateServer - USB - NetBIOS - Preferences - ArduinoOTA -extra_scripts = pre:pio-tools/add_c_flags.py - pre:pio-tools/solidify-from-url.py - pre:pio-tools/gen-berry-structures.py - post:pio-tools/post_esp32.py - ${esp_defaults.extra_scripts} -monitor_filters = esp32_exception_decoder - -[safeboot_flags] -lib_ignore = ${esp32_defaults.lib_ignore} - ESPmDNS - LinkedList - LittleFS - ESP Mail Client - IRremoteESP8266 - NeoPixelBus - OneWire - EEPROM - EEPROM 24C128_256_521 - MFRC522 - JPEGDEC - universal display Library - ESP8266Audio - ESP8266SAM - FFat - SD - SD_MMC - UdpListener - esp_wireguard_tasmota - IniFile - Berry - Berry mapping to C - Berry Tasmota mapping - Berry int64 implementation for 32 bits architecture - Berry Matter protocol implementation - Berry animation library for WS2812 leds - Micro-RTSP - re1.5 - DHT sensor library - ccronexpr -custom_component_remove = - espressif/network_provisioning - espressif/esp_modem - espressif/esp-dsp - espressif/esp32-camera - espressif/mdns - espressif/esp_jpg - espressif/fb_gfx - espressif/cmake_utilities - -[core32] -platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.02.30/platform-espressif32.zip -platform_packages = -build_unflags = ${esp32_defaults.build_unflags} -build_flags = ${esp32_defaults.build_flags} - - +; *** ESP32 Tasmota version *** + +[esp32_defaults] +build_unflags = ${esp_defaults.build_unflags} + -mtarget-align + -Wswitch-unreachable + -Wstringop-overflow + -Wincompatible-pointer-types + -Wnonnull-compare + -fexceptions + -Wpointer-arith +build_flags = ${esp_defaults.build_flags} + ; comment next line to disable IPv6 support + -DUSE_IPV6 + -mno-target-align + -Wno-switch-unreachable + -Wno-stringop-overflow + -fno-exceptions + -ffunction-sections + -fdata-sections + -Wl,--gc-sections + -DBUFFER_LENGTH=128 + -DHTTP_UPLOAD_BUFLEN=2048 + -DMQTT_MAX_PACKET_SIZE=1200 + -Duint32=uint32_t + -Duint16=uint16_t + -Duint8=uint8_t + -Dsint8_t=int8_t + -Dsint32_t=int32_t + -Dsint16_t=int16_t + -Dmemcpy_P=memcpy + -Dmemcmp_P=memcmp + -DUSE_SHA_ROM + ;for TLS we can afford compiling for 4K RSA keys + -DUSE_4K_RSA + -I$PROJECT_DIR/include + -include "sdkconfig.h" + -include "esp32x_fixes.h" + ; wrappers for the crash-recorder + -Wl,--wrap=panicHandler -Wl,--wrap=xt_unhandled_exception + -Wl,--wrap=_Z11analogWritehi ; `analogWrite(unsigned char, int)` use the Tasmota version of analogWrite for deeper integration and phase control + -Wl,--wrap=ledcReadFreq ; `uint32_t ledcReadFreq(uint8_t chan)` + -Wl,--wrap=delay ; void delay(uint32_t ms) +lib_ignore = + HTTPUpdateServer + USB + NetBIOS + Preferences + ArduinoOTA +extra_scripts = pre:pio-tools/add_c_flags.py + pre:pio-tools/solidify-from-url.py + pre:pio-tools/gen-berry-structures.py + post:pio-tools/post_esp32.py + ${esp_defaults.extra_scripts} +monitor_filters = esp32_exception_decoder + +[safeboot_flags] +lib_ignore = ${esp32_defaults.lib_ignore} + ESPmDNS + LinkedList + LittleFS + ESP Mail Client + IRremoteESP8266 + NeoPixelBus + OneWire + EEPROM + EEPROM 24C128_256_521 + MFRC522 + JPEGDEC + universal display Library + ESP8266Audio + ESP8266SAM + FFat + SD + SD_MMC + UdpListener + esp_wireguard_tasmota + IniFile + Berry + Berry mapping to C + Berry Tasmota mapping + Berry int64 implementation for 32 bits architecture + Berry Matter protocol implementation + Berry animation library for WS2812 leds + Micro-RTSP + re1.5 + DHT sensor library + ccronexpr +custom_component_remove = + espressif/network_provisioning + espressif/esp_modem + espressif/esp-dsp + espressif/esp32-camera + espressif/mdns + espressif/esp_jpg + espressif/fb_gfx + espressif/cmake_utilities + +[core32] +platform = https://github.com/tasmota/platform-espressif32/releases/download/2026.02.30/platform-espressif32.zip +platform_packages = +build_unflags = ${esp32_defaults.build_unflags} +build_flags = ${esp32_defaults.build_flags} + + diff --git a/platformio_tasmota_env.ini b/platformio_tasmota_env.ini index 287a475fa..c8bb3514d 100644 --- a/platformio_tasmota_env.ini +++ b/platformio_tasmota_env.ini @@ -1,146 +1,146 @@ -[env] -platform = ${common.platform} -platform_packages = ${common.platform_packages} -framework = ${common.framework} -board = ${common.board} -board_build.filesystem = ${common.board_build.filesystem} -build_unflags = ${common.build_unflags} -build_flags = ${esp82xx_defaults.build_flags} -monitor_speed = ${common.monitor_speed} -monitor_echo = ${common.monitor_echo} -upload_resetmethod = ${common.upload_resetmethod} -extra_scripts = ${esp_defaults.extra_scripts} -lib_ldf_mode = ${common.lib_ldf_mode} -lib_compat_mode = ${common.lib_compat_mode} -lib_extra_dirs = ${common.lib_extra_dirs} -lib_ignore = ${esp82xx_defaults.lib_ignore} -; Add files to Filesystem for all env (global). Remove no files entry and add a line with the file to include -custom_files_upload = no_files - -[env:tasmota] -build_flags = ${env.build_flags} -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota.bin.gz"' - -[env:tasmota-4M] -board = esp8266_4M2M -build_flags = ${env.build_flags} - -DCODE_IMAGE_STR='"tasmota-4M"' - -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-4M.bin.gz"' - -[env:tasmota-minimal] -build_flags = ${env.build_flags} -DFIRMWARE_MINIMAL -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-minimal.bin.gz"' -lib_extra_dirs = - -[env:tasmota-lite] -build_flags = ${env.build_flags} -DFIRMWARE_LITE -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-lite.bin.gz"' -lib_extra_dirs = - -[env:tasmota-knx] -build_flags = ${env.build_flags} -DFIRMWARE_KNX_NO_EMULATION -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-knx.bin.gz"' -lib_extra_dirs = lib/lib_basic, lib/lib_div - -[env:tasmota-sensors] -build_flags = ${env.build_flags} -DFIRMWARE_SENSORS -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-sensors.bin.gz"' -lib_extra_dirs = lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div - -[env:tasmota-display] -build_flags = ${env.build_flags} -DFIRMWARE_DISPLAYS -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-display.bin.gz"' -lib_extra_dirs = lib/lib_basic, lib/lib_display - -[env:tasmota-ir] -build_flags = ${env.build_flags} -DFIRMWARE_IR -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-ir.bin.gz"' -lib_extra_dirs = lib/lib_basic - -[env:tasmota-zbbridge] -build_flags = ${env.build_flags} -DFIRMWARE_ZBBRIDGE -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-zbbridge.bin.gz"' -board = esp8266_zbbridge -lib_extra_dirs = lib/lib_basic, lib/lib_ssl, lib/lib_div - -[env:tasmota-zigbee] -build_flags = ${env.build_flags} - -DUSE_ZIGBEE - -DUSE_CCLOADER - -DCODE_IMAGE_STR='"zigbee"' - -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-zigbee.bin.gz"' -board = esp8266_4M2M -board_build.f_cpu = 160000000L - -[env:tasmota-AD] -build_flags = ${env.build_flags} -DMY_LANGUAGE=ca_AD -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmot-AD.bin.gz"' - -[env:tasmota-AF] -build_flags = ${env.build_flags} -DMY_LANGUAGE=af_AF -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-AF.bin.gz"' - -[env:tasmota-BG] -build_flags = ${env.build_flags} -DMY_LANGUAGE=bg_BG -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-BG.bin.gz"' - -[env:tasmota-BR] -build_flags = ${env.build_flags} -DMY_LANGUAGE=pt_BR -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-BR.bin.gz"' - -[env:tasmota-CN] -build_flags = ${env.build_flags} -DMY_LANGUAGE=zh_CN -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-CN.bin.gz"' - -[env:tasmota-CZ] -build_flags = ${env.build_flags} -DMY_LANGUAGE=cs_CZ -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-CZ.bin.gz"' - -[env:tasmota-DE] -build_flags = ${env.build_flags} -DMY_LANGUAGE=de_DE -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-DE.bin.gz"' - -[env:tasmota-ES] -build_flags = ${env.build_flags} -DMY_LANGUAGE=es_ES -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-ES.bin.gz"' - -[env:tasmota-FR] -build_flags = ${env.build_flags} -DMY_LANGUAGE=fr_FR -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-FR.bin.gz"' - -[env:tasmota-FY] -build_flags = ${env.build_flags} -DMY_LANGUAGE=fy_NL -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-FY.bin.gz"' - -[env:tasmota-GR] -build_flags = ${env.build_flags} -DMY_LANGUAGE=el_GR -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-GR.bin.gz"' - -[env:tasmota-HE] -build_flags = ${env.build_flags} -DMY_LANGUAGE=he_HE -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-HE.bin.gz"' - -[env:tasmota-HU] -build_flags = ${env.build_flags} -DMY_LANGUAGE=hu_HU -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-HU.bin.gz"' - -[env:tasmota-IT] -build_flags = ${env.build_flags} -DMY_LANGUAGE=it_IT -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-IT.bin.gz"' - -[env:tasmota-KO] -build_flags = ${env.build_flags} -DMY_LANGUAGE=ko_KO -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-KO.bin.gz"' - -[env:tasmota-LT] -build_flags = ${env.build_flags} -DMY_LANGUAGE=lt_LT -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-LT.bin.gz"' - -[env:tasmota-NL] -build_flags = ${env.build_flags} -DMY_LANGUAGE=nl_NL -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-NL.bin.gz"' - -[env:tasmota-PL] -build_flags = ${env.build_flags} -DMY_LANGUAGE=pl_PL -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-PL.bin.gz"' - -[env:tasmota-PT] -build_flags = ${env.build_flags} -DMY_LANGUAGE=pt_PT -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-PT.bin.gz"' - -[env:tasmota-RO] -build_flags = ${env.build_flags} -DMY_LANGUAGE=ro_RO -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-RO.bin.gz"' - -[env:tasmota-RU] -build_flags = ${env.build_flags} -DMY_LANGUAGE=ru_RU -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-RU.bin.gz"' - -[env:tasmota-SE] -build_flags = ${env.build_flags} -DMY_LANGUAGE=sv_SE -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-SE.bin.gz"' - -[env:tasmota-SK] -build_flags = ${env.build_flags} -DMY_LANGUAGE=sk_SK -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-SK.bin.gz"' - -[env:tasmota-TR] -build_flags = ${env.build_flags} -DMY_LANGUAGE=tr_TR -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-TR.bin.gz"' - -[env:tasmota-TW] -build_flags = ${env.build_flags} -DMY_LANGUAGE=zh_TW -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-TW.bin.gz"' - -[env:tasmota-UK] -build_flags = ${env.build_flags} -DMY_LANGUAGE=uk_UA -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-UK.bin.gz"' - -[env:tasmota-VN] -build_flags = ${env.build_flags} -DMY_LANGUAGE=vi_VN -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-VN.bin.gz"' +[env] +platform = ${common.platform} +platform_packages = ${common.platform_packages} +framework = ${common.framework} +board = ${common.board} +board_build.filesystem = ${common.board_build.filesystem} +build_unflags = ${common.build_unflags} +build_flags = ${esp82xx_defaults.build_flags} +monitor_speed = ${common.monitor_speed} +monitor_echo = ${common.monitor_echo} +upload_resetmethod = ${common.upload_resetmethod} +extra_scripts = ${esp_defaults.extra_scripts} +lib_ldf_mode = ${common.lib_ldf_mode} +lib_compat_mode = ${common.lib_compat_mode} +lib_extra_dirs = ${common.lib_extra_dirs} +lib_ignore = ${esp82xx_defaults.lib_ignore} +; Add files to Filesystem for all env (global). Remove no files entry and add a line with the file to include +custom_files_upload = no_files + +[env:tasmota] +build_flags = ${env.build_flags} -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota.bin.gz"' + +[env:tasmota-4M] +board = esp8266_4M2M +build_flags = ${env.build_flags} + -DCODE_IMAGE_STR='"tasmota-4M"' + -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-4M.bin.gz"' + +[env:tasmota-minimal] +build_flags = ${env.build_flags} -DFIRMWARE_MINIMAL -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-minimal.bin.gz"' +lib_extra_dirs = + +[env:tasmota-lite] +build_flags = ${env.build_flags} -DFIRMWARE_LITE -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-lite.bin.gz"' +lib_extra_dirs = + +[env:tasmota-knx] +build_flags = ${env.build_flags} -DFIRMWARE_KNX_NO_EMULATION -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-knx.bin.gz"' +lib_extra_dirs = lib/lib_basic, lib/lib_div + +[env:tasmota-sensors] +build_flags = ${env.build_flags} -DFIRMWARE_SENSORS -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-sensors.bin.gz"' +lib_extra_dirs = lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div + +[env:tasmota-display] +build_flags = ${env.build_flags} -DFIRMWARE_DISPLAYS -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-display.bin.gz"' +lib_extra_dirs = lib/lib_basic, lib/lib_display + +[env:tasmota-ir] +build_flags = ${env.build_flags} -DFIRMWARE_IR -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-ir.bin.gz"' +lib_extra_dirs = lib/lib_basic + +[env:tasmota-zbbridge] +build_flags = ${env.build_flags} -DFIRMWARE_ZBBRIDGE -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-zbbridge.bin.gz"' +board = esp8266_zbbridge +lib_extra_dirs = lib/lib_basic, lib/lib_ssl, lib/lib_div + +[env:tasmota-zigbee] +build_flags = ${env.build_flags} + -DUSE_ZIGBEE + -DUSE_CCLOADER + -DCODE_IMAGE_STR='"zigbee"' + -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-zigbee.bin.gz"' +board = esp8266_4M2M +board_build.f_cpu = 160000000L + +[env:tasmota-AD] +build_flags = ${env.build_flags} -DMY_LANGUAGE=ca_AD -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmot-AD.bin.gz"' + +[env:tasmota-AF] +build_flags = ${env.build_flags} -DMY_LANGUAGE=af_AF -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-AF.bin.gz"' + +[env:tasmota-BG] +build_flags = ${env.build_flags} -DMY_LANGUAGE=bg_BG -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-BG.bin.gz"' + +[env:tasmota-BR] +build_flags = ${env.build_flags} -DMY_LANGUAGE=pt_BR -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-BR.bin.gz"' + +[env:tasmota-CN] +build_flags = ${env.build_flags} -DMY_LANGUAGE=zh_CN -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-CN.bin.gz"' + +[env:tasmota-CZ] +build_flags = ${env.build_flags} -DMY_LANGUAGE=cs_CZ -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-CZ.bin.gz"' + +[env:tasmota-DE] +build_flags = ${env.build_flags} -DMY_LANGUAGE=de_DE -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-DE.bin.gz"' + +[env:tasmota-ES] +build_flags = ${env.build_flags} -DMY_LANGUAGE=es_ES -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-ES.bin.gz"' + +[env:tasmota-FR] +build_flags = ${env.build_flags} -DMY_LANGUAGE=fr_FR -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-FR.bin.gz"' + +[env:tasmota-FY] +build_flags = ${env.build_flags} -DMY_LANGUAGE=fy_NL -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-FY.bin.gz"' + +[env:tasmota-GR] +build_flags = ${env.build_flags} -DMY_LANGUAGE=el_GR -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-GR.bin.gz"' + +[env:tasmota-HE] +build_flags = ${env.build_flags} -DMY_LANGUAGE=he_HE -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-HE.bin.gz"' + +[env:tasmota-HU] +build_flags = ${env.build_flags} -DMY_LANGUAGE=hu_HU -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-HU.bin.gz"' + +[env:tasmota-IT] +build_flags = ${env.build_flags} -DMY_LANGUAGE=it_IT -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-IT.bin.gz"' + +[env:tasmota-KO] +build_flags = ${env.build_flags} -DMY_LANGUAGE=ko_KO -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-KO.bin.gz"' + +[env:tasmota-LT] +build_flags = ${env.build_flags} -DMY_LANGUAGE=lt_LT -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-LT.bin.gz"' + +[env:tasmota-NL] +build_flags = ${env.build_flags} -DMY_LANGUAGE=nl_NL -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-NL.bin.gz"' + +[env:tasmota-PL] +build_flags = ${env.build_flags} -DMY_LANGUAGE=pl_PL -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-PL.bin.gz"' + +[env:tasmota-PT] +build_flags = ${env.build_flags} -DMY_LANGUAGE=pt_PT -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-PT.bin.gz"' + +[env:tasmota-RO] +build_flags = ${env.build_flags} -DMY_LANGUAGE=ro_RO -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-RO.bin.gz"' + +[env:tasmota-RU] +build_flags = ${env.build_flags} -DMY_LANGUAGE=ru_RU -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-RU.bin.gz"' + +[env:tasmota-SE] +build_flags = ${env.build_flags} -DMY_LANGUAGE=sv_SE -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-SE.bin.gz"' + +[env:tasmota-SK] +build_flags = ${env.build_flags} -DMY_LANGUAGE=sk_SK -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-SK.bin.gz"' + +[env:tasmota-TR] +build_flags = ${env.build_flags} -DMY_LANGUAGE=tr_TR -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-TR.bin.gz"' + +[env:tasmota-TW] +build_flags = ${env.build_flags} -DMY_LANGUAGE=zh_TW -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-TW.bin.gz"' + +[env:tasmota-UK] +build_flags = ${env.build_flags} -DMY_LANGUAGE=uk_UA -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-UK.bin.gz"' + +[env:tasmota-VN] +build_flags = ${env.build_flags} -DMY_LANGUAGE=vi_VN -DOTA_URL='"http://ota.tasmota.com/tasmota/release/tasmota-VN.bin.gz"' diff --git a/platformio_tasmota_env32.ini b/platformio_tasmota_env32.ini index 9c38037a3..e0090aab5 100644 --- a/platformio_tasmota_env32.ini +++ b/platformio_tasmota_env32.ini @@ -1,555 +1,555 @@ -[env:tasmota32_base] -framework = ${common.framework} -platform = ${core32.platform} -platform_packages = ${core32.platform_packages} -board_build.filesystem = ${common.board_build.filesystem} -custom_unpack_dir = ${common.custom_unpack_dir} -board_build.variants_dir = ${common.board_build.variants_dir} -board = esp32 -monitor_speed = ${common.monitor_speed} -monitor_echo = ${common.monitor_echo} -upload_resetmethod = ${common.upload_resetmethod} -check_skip_packages = ${common.check_skip_packages} -extra_scripts = ${esp32_defaults.extra_scripts} -monitor_filters = ${esp32_defaults.monitor_filters} -build_unflags = ${core32.build_unflags} -build_flags = ${core32.build_flags} -lib_ldf_mode = ${common.lib_ldf_mode} -lib_compat_mode = ${common.lib_compat_mode} -lib_extra_dirs = ${common.lib_extra_dirs} - lib/libesp32 - lib/libesp32_lvgl -lib_ignore = ${esp32_defaults.lib_ignore} -; Add files to Filesystem for all env (global). Remove no files entry and add a line with the file to include -; Example for adding the Partition Manager -; custom_files_upload = -; tasmota/berry/modules/Partition_Manager.tapp -custom_files_upload = no_files - -[env:tasmota32-safeboot] -extends = env:tasmota32_base -board = esp32-solo1 -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} -custom_sdkconfig = '# CONFIG_BT_ENABLED is not set' - CONFIG_BT_DISABLED=y - '# CONFIG_BT_NIMBLE_ENABLED is no set' - CONFIG_BT_NIMBLE_DISABLED=y -custom_component_remove = ${safeboot_flags.custom_component_remove} - -[env:tasmota32solo1-safeboot] -extends = env:tasmota32_base -board = esp32-solo1 -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32solo1-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} -custom_sdkconfig = '# CONFIG_BT_ENABLED is not set' - CONFIG_BT_DISABLED=y - '# CONFIG_BT_NIMBLE_ENABLED is no set' - CONFIG_BT_NIMBLE_DISABLED=y -custom_component_remove = ${safeboot_flags.custom_component_remove} - -[env:tasmota32s2-safeboot] -extends = env:tasmota32_base -board = esp32s2 -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s2-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} - -[env:tasmota32s2cdc-safeboot] -extends = env:tasmota32_base -board = esp32s2cdc -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s2cdc-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} - -[env:tasmota32c2-safeboot] -extends = env:tasmota32_base -board = esp32c2 -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c2-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} - -[env:tasmota32c3-safeboot] -extends = env:tasmota32_base -board = esp32c3 -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c3-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} - -[env:tasmota32c3ser-safeboot] -extends = env:tasmota32_base -board = esp32c3ser -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c3ser-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} - -[env:tasmota32s3-safeboot] -extends = env:tasmota32_base -board = esp32s3-qio_qspi -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s3-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} - -[env:tasmota32c5-safeboot] -platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152 -extends = env:tasmota32_base -board = esp32c5 -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c5-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} -custom_sdkconfig = - '# CONFIG_BT_ENABLED is not set' - '# CONFIG_BT_NIMBLE_ENABLED is not set' - '# CONFIG_BT_CONTROLLER_ENABLED is not set' - CONFIG_BT_CONTROLLER_DISABLED=y - '# CONFIG_LWIP_IP_FORWARD is not set' - '# CONFIG_LWIP_IPV4_NAPT is not set' - '# CONFIG_LWIP_IPV4_NAPT_PORTMAP is not set' - '# CONFIG_LWIP_PPP_SUPPORT is not set' - '# CONFIG_ETH_ENABLED is not set' - '# CONFIG_ETH_USE_SPI_ETHERNET is not set' - '# CONFIG_ETH_TRANSMIT_MUTEX is not set' - '# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set' - '# CONFIG_ETH_SPI_ETHERNET_W5500 is not set' - '# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set' -custom_component_remove = ${safeboot_flags.custom_component_remove} - -[env:tasmota32c5ser-safeboot] -platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152 -extends = env:tasmota32_base -board = esp32c5ser -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c5ser-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} -custom_sdkconfig = - '# CONFIG_BT_ENABLED is not set' - '# CONFIG_BT_NIMBLE_ENABLED is not set' - '# CONFIG_BT_CONTROLLER_ENABLED is not set' - CONFIG_BT_CONTROLLER_DISABLED=y - '# CONFIG_LWIP_IP_FORWARD is not set' - '# CONFIG_LWIP_IPV4_NAPT is not set' - '# CONFIG_LWIP_IPV4_NAPT_PORTMAP is not set' - '# CONFIG_LWIP_PPP_SUPPORT is not set' - '# CONFIG_ETH_ENABLED is not set' - '# CONFIG_ETH_USE_SPI_ETHERNET is not set' - '# CONFIG_ETH_TRANSMIT_MUTEX is not set' - '# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set' - '# CONFIG_ETH_SPI_ETHERNET_W5500 is not set' - '# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set' -custom_component_remove = ${safeboot_flags.custom_component_remove} - -[env:tasmota32c6-safeboot] -extends = env:tasmota32_base -board = esp32c6 -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c6-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} -custom_sdkconfig = - '# CONFIG_BT_ENABLED is not set' - '# CONFIG_BT_NIMBLE_ENABLED is not set' - '# CONFIG_BT_CONTROLLER_ENABLED is not set' - CONFIG_BT_CONTROLLER_DISABLED=y - '# CONFIG_LWIP_IP_FORWARD is not set' - '# CONFIG_LWIP_IPV4_NAPT is not set' - '# CONFIG_LWIP_IPV4_NAPT_PORTMAP is not set' - '# CONFIG_LWIP_PPP_SUPPORT is not set' -custom_component_remove = ${safeboot_flags.custom_component_remove} - -[env:tasmota32c6ser-safeboot] -extends = env:tasmota32_base -board = esp32c6ser -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c6ser-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} -custom_sdkconfig = - '# CONFIG_BT_ENABLED is not set' - '# CONFIG_BT_NIMBLE_ENABLED is not set' - '# CONFIG_BT_CONTROLLER_ENABLED is not set' - CONFIG_BT_CONTROLLER_DISABLED=y - '# CONFIG_LWIP_IP_FORWARD is not set' - '# CONFIG_LWIP_IPV4_NAPT is not set' - '# CONFIG_LWIP_IPV4_NAPT_PORTMAP is not set' - '# CONFIG_LWIP_PPP_SUPPORT is not set' -custom_component_remove = ${safeboot_flags.custom_component_remove} - -[env:tasmota32s3ser-safeboot] -extends = env:tasmota32_base -board = esp32s3ser-qio_qspi -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s3ser-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} - -[env:tasmota32p4-safeboot] -extends = env:tasmota32_base -board = esp32p4 -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32p4-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} - -[env:tasmota32p4r3-safeboot] -platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152 -extends = env:tasmota32_base -board = esp32p4r3 -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32p4r3-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} - -[env:tasmota32p4ser-safeboot] -extends = env:tasmota32_base -board = esp32p4ser -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32p4ser-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} - -[env:tasmota32p4r3ser-safeboot] -platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152 -extends = env:tasmota32_base -board = esp32p4r3ser -board_build.app_partition_name = safeboot -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_SAFEBOOT - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32p4r3ser-safeboot.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 -lib_ignore = ${safeboot_flags.lib_ignore} - -[env:tasmota32] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_TASMOTA32 - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32.bin"' - -[env:tasmota32solo1] -extends = env:tasmota32_base -board = esp32-solo1 -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_TASMOTA32 - -DCODE_IMAGE_STR='"solo1"' - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32solo1.bin"' -lib_ignore = ${env:tasmota32_base.lib_ignore} - Micro-RTSP - epdiy - -[env:tasmota32s2] -extends = env:tasmota32_base -board = esp32s2 -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_TASMOTA32 - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s2.bin"' -lib_ignore = ${env:tasmota32_base.lib_ignore} - esp-nimble-cpp - Micro-RTSP - epdiy - -[env:tasmota32s2cdc] -extends = env:tasmota32_base -board = esp32s2cdc -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_TASMOTA32 - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s2cdc.bin"' -lib_ignore = ${env:tasmota32_base.lib_ignore} - esp-nimble-cpp - Micro-RTSP - epdiy - -[env:tasmota32c2] -extends = env:tasmota32_base -board = esp32c2 -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_TASMOTA32 - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c2.bin"' -lib_ignore = ${env:tasmota32_base.lib_ignore} - Micro-RTSP - -[env:tasmota32c3] -extends = env:tasmota32_base -board = esp32c3 -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_TASMOTA32 - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c3.bin"' -lib_ignore = ${env:tasmota32_base.lib_ignore} - Micro-RTSP -[env:tasmota32c5] -platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152 -extends = env:tasmota32_base -board = esp32c5 -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_TASMOTA32 - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c5.bin"' -lib_ignore = ${env:tasmota32_base.lib_ignore} - Micro-RTSP -[env:tasmota32c6] -extends = env:tasmota32_base -board = esp32c6 -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_TASMOTA32 - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c6.bin"' -lib_ignore = ${env:tasmota32_base.lib_ignore} - Micro-RTSP - -[env:tasmota32p4] -extends = env:tasmota32_base -board = esp32p4 -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_TASMOTA32 - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32p4.bin"' -lib_ignore = ${env:tasmota32_base.lib_ignore} - Micro-RTSP - -[env:tasmota32p4r3] -platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152 -extends = env:tasmota32_base -board = esp32p4r3 -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_TASMOTA32 - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32p4r3.bin"' -lib_ignore = ${env:tasmota32_base.lib_ignore} - Micro-RTSP - -[env:tasmota32s3] -extends = env:tasmota32_base -board = esp32s3-qio_qspi -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_TASMOTA32 - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s3.bin"' -lib_ignore = ${env:tasmota32_base.lib_ignore} - Micro-RTSP - epdiy - -[env:tasmota32-webcam] -extends = env:tasmota32_base -board = esp32-fix -board_build.f_cpu = 240000000L -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_WEBCAM - -DCAMERA_MODEL_AI_THINKER - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-webcam.bin"' -lib_extra_dirs = lib/lib_ssl, lib/libesp32 - -[env:tasmota32-bluetooth] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_BLUETOOTH - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-bluetooth.bin"' -lib_extra_dirs = lib/libesp32, lib/libesp32_div, lib/lib_basic, lib/lib_i2c, lib/lib_ssl -lib_ignore = ${env:tasmota32_base.lib_ignore} - Micro-RTSP - -[env:tasmota32-display] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_DISPLAYS - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-display.bin"' -lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_display, lib/lib_ssl -lib_ignore = ${env:tasmota32_base.lib_ignore} - Micro-RTSP - -[env:tasmota32-lvgl] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_LVGL - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-lvgl.bin"' -board_build.f_cpu = 240000000L -lib_extra_dirs = lib/libesp32, lib/libesp32_lvgl, lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div, lib/lib_ssl, lib/lib_display -lib_ignore = ${env:tasmota32_base.lib_ignore} - Micro-RTSP - -[env:tasmota32-ir] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_IR - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-ir.bin"' -lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_ssl -lib_ignore = ${env:tasmota32_base.lib_ignore} - Micro-RTSP - -[env:tasmota32-zbbrdgpro] -extends = env:tasmota32_base -board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv -build_flags = ${env:tasmota32_base.build_flags} - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-zbbrdgpro.bin"' - -DFIRMWARE_ZBBRDGPRO -custom_files_upload = ${env:tasmota32_base.custom_files_upload} - tools/fw_SonoffZigbeeBridgePro_cc2652/Sonoff_ZBPro.autoconf - tasmota/berry/zigbee/cc2652_flasher.be - tasmota/berry/zigbee/intelhex.be - tasmota/berry/zigbee/sonoff_zb_pro_flasher.be - tools/fw_SonoffZigbeeBridgePro_cc2652/SonoffZBPro_coord_20220219.hex -custom_sdkconfig = CONFIG_D0WD_PSRAM_CLK_IO=5 - CONFIG_D0WD_PSRAM_CS_IO=18 -custom_component_remove = espressif/esp-dsp - espressif/esp_modem - espressif/esp32-camera - espressif/mdns -lib_extra_dirs = lib/lib_basic, lib/lib_ssl, lib/libesp32 -lib_ignore = ${env:tasmota32_base.lib_ignore} - Micro-RTSP - IRremoteESP8266 - TasmotaModbus - ESP Mail Client - JPEGDEC - -[env:tasmota32-nspanel] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} - -DFIRMWARE_NSPANEL - -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-nspanel.bin"' -custom_sdkconfig = CONFIG_D0WD_PSRAM_CLK_IO=5 - CONFIG_D0WD_PSRAM_CS_IO=18 - -[env:tasmota32-AD] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=ca_AD -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-AD.bin"' - -[env:tasmota32-AF] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=af_AF -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-AF.bin"' - -[env:tasmota32-BG] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=bg_BG -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-BG.bin"' - -[env:tasmota32-BR] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=pt_BR -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-BR.bin"' - -[env:tasmota32-CN] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=zh_CN -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-CN.bin"' - -[env:tasmota32-CZ] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=cs_CZ -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-CZ.bin"' - -[env:tasmota32-DE] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=de_DE -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-DE.bin"' - -[env:tasmota32-ES] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=es_ES -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-ES.bin"' - -[env:tasmota32-FR] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=fr_FR -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-FR.bin"' - -[env:tasmota32-FY] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=fy_NL -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-FY.bin"' - -[env:tasmota32-GR] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=el_GR -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-GR.bin"' - -[env:tasmota32-HE] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=he_HE -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-HE.bin"' - -[env:tasmota32-HU] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=hu_HU -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-HU.bin"' - -[env:tasmota32-IT] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=it_IT -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-IT.bin"' - -[env:tasmota32-KO] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=ko_KO -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-KO.bin"' - -[env:tasmota32-LT] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=lt_LT -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-LT.bin"' - -[env:tasmota32-NL] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=nl_NL -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-NL.bin"' - -[env:tasmota32-PL] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=pl_PL -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-PL.bin"' - -[env:tasmota32-PT] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=pt_PT -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-PT.bin"' - -[env:tasmota32-RO] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=ro_RO -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-RO.bin"' - -[env:tasmota32-RU] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=ru_RU -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-RU.bin"' - -[env:tasmota32-SE] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=sv_SE -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-SE.bin"' - -[env:tasmota32-SK] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=sk_SK -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-SK.bin"' - -[env:tasmota32-TR] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=tr_TR -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-TR.bin"' - -[env:tasmota32-TW] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=zh_TW -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-TW.bin"' - -[env:tasmota32-UK] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=uk_UA -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-UK.bin"' - -[env:tasmota32-VN] -extends = env:tasmota32_base -build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=vi_VN -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-VN.bin"' +[env:tasmota32_base] +framework = ${common.framework} +platform = ${core32.platform} +platform_packages = ${core32.platform_packages} +board_build.filesystem = ${common.board_build.filesystem} +custom_unpack_dir = ${common.custom_unpack_dir} +board_build.variants_dir = ${common.board_build.variants_dir} +board = esp32 +monitor_speed = ${common.monitor_speed} +monitor_echo = ${common.monitor_echo} +upload_resetmethod = ${common.upload_resetmethod} +check_skip_packages = ${common.check_skip_packages} +extra_scripts = ${esp32_defaults.extra_scripts} +monitor_filters = ${esp32_defaults.monitor_filters} +build_unflags = ${core32.build_unflags} +build_flags = ${core32.build_flags} +lib_ldf_mode = ${common.lib_ldf_mode} +lib_compat_mode = ${common.lib_compat_mode} +lib_extra_dirs = ${common.lib_extra_dirs} + lib/libesp32 + lib/libesp32_lvgl +lib_ignore = ${esp32_defaults.lib_ignore} +; Add files to Filesystem for all env (global). Remove no files entry and add a line with the file to include +; Example for adding the Partition Manager +; custom_files_upload = +; tasmota/berry/modules/Partition_Manager.tapp +custom_files_upload = no_files + +[env:tasmota32-safeboot] +extends = env:tasmota32_base +board = esp32-solo1 +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} +custom_sdkconfig = '# CONFIG_BT_ENABLED is not set' + CONFIG_BT_DISABLED=y + '# CONFIG_BT_NIMBLE_ENABLED is no set' + CONFIG_BT_NIMBLE_DISABLED=y +custom_component_remove = ${safeboot_flags.custom_component_remove} + +[env:tasmota32solo1-safeboot] +extends = env:tasmota32_base +board = esp32-solo1 +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32solo1-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} +custom_sdkconfig = '# CONFIG_BT_ENABLED is not set' + CONFIG_BT_DISABLED=y + '# CONFIG_BT_NIMBLE_ENABLED is no set' + CONFIG_BT_NIMBLE_DISABLED=y +custom_component_remove = ${safeboot_flags.custom_component_remove} + +[env:tasmota32s2-safeboot] +extends = env:tasmota32_base +board = esp32s2 +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s2-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32s2cdc-safeboot] +extends = env:tasmota32_base +board = esp32s2cdc +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s2cdc-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32c2-safeboot] +extends = env:tasmota32_base +board = esp32c2 +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c2-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32c3-safeboot] +extends = env:tasmota32_base +board = esp32c3 +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c3-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32c3ser-safeboot] +extends = env:tasmota32_base +board = esp32c3ser +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c3ser-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32s3-safeboot] +extends = env:tasmota32_base +board = esp32s3-qio_qspi +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s3-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32c5-safeboot] +platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152 +extends = env:tasmota32_base +board = esp32c5 +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c5-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} +custom_sdkconfig = + '# CONFIG_BT_ENABLED is not set' + '# CONFIG_BT_NIMBLE_ENABLED is not set' + '# CONFIG_BT_CONTROLLER_ENABLED is not set' + CONFIG_BT_CONTROLLER_DISABLED=y + '# CONFIG_LWIP_IP_FORWARD is not set' + '# CONFIG_LWIP_IPV4_NAPT is not set' + '# CONFIG_LWIP_IPV4_NAPT_PORTMAP is not set' + '# CONFIG_LWIP_PPP_SUPPORT is not set' + '# CONFIG_ETH_ENABLED is not set' + '# CONFIG_ETH_USE_SPI_ETHERNET is not set' + '# CONFIG_ETH_TRANSMIT_MUTEX is not set' + '# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set' + '# CONFIG_ETH_SPI_ETHERNET_W5500 is not set' + '# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set' +custom_component_remove = ${safeboot_flags.custom_component_remove} + +[env:tasmota32c5ser-safeboot] +platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152 +extends = env:tasmota32_base +board = esp32c5ser +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c5ser-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} +custom_sdkconfig = + '# CONFIG_BT_ENABLED is not set' + '# CONFIG_BT_NIMBLE_ENABLED is not set' + '# CONFIG_BT_CONTROLLER_ENABLED is not set' + CONFIG_BT_CONTROLLER_DISABLED=y + '# CONFIG_LWIP_IP_FORWARD is not set' + '# CONFIG_LWIP_IPV4_NAPT is not set' + '# CONFIG_LWIP_IPV4_NAPT_PORTMAP is not set' + '# CONFIG_LWIP_PPP_SUPPORT is not set' + '# CONFIG_ETH_ENABLED is not set' + '# CONFIG_ETH_USE_SPI_ETHERNET is not set' + '# CONFIG_ETH_TRANSMIT_MUTEX is not set' + '# CONFIG_ETH_SPI_ETHERNET_DM9051 is not set' + '# CONFIG_ETH_SPI_ETHERNET_W5500 is not set' + '# CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL is not set' +custom_component_remove = ${safeboot_flags.custom_component_remove} + +[env:tasmota32c6-safeboot] +extends = env:tasmota32_base +board = esp32c6 +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c6-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} +custom_sdkconfig = + '# CONFIG_BT_ENABLED is not set' + '# CONFIG_BT_NIMBLE_ENABLED is not set' + '# CONFIG_BT_CONTROLLER_ENABLED is not set' + CONFIG_BT_CONTROLLER_DISABLED=y + '# CONFIG_LWIP_IP_FORWARD is not set' + '# CONFIG_LWIP_IPV4_NAPT is not set' + '# CONFIG_LWIP_IPV4_NAPT_PORTMAP is not set' + '# CONFIG_LWIP_PPP_SUPPORT is not set' +custom_component_remove = ${safeboot_flags.custom_component_remove} + +[env:tasmota32c6ser-safeboot] +extends = env:tasmota32_base +board = esp32c6ser +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c6ser-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} +custom_sdkconfig = + '# CONFIG_BT_ENABLED is not set' + '# CONFIG_BT_NIMBLE_ENABLED is not set' + '# CONFIG_BT_CONTROLLER_ENABLED is not set' + CONFIG_BT_CONTROLLER_DISABLED=y + '# CONFIG_LWIP_IP_FORWARD is not set' + '# CONFIG_LWIP_IPV4_NAPT is not set' + '# CONFIG_LWIP_IPV4_NAPT_PORTMAP is not set' + '# CONFIG_LWIP_PPP_SUPPORT is not set' +custom_component_remove = ${safeboot_flags.custom_component_remove} + +[env:tasmota32s3ser-safeboot] +extends = env:tasmota32_base +board = esp32s3ser-qio_qspi +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s3ser-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32p4-safeboot] +extends = env:tasmota32_base +board = esp32p4 +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32p4-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32p4r3-safeboot] +platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152 +extends = env:tasmota32_base +board = esp32p4r3 +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32p4r3-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32p4ser-safeboot] +extends = env:tasmota32_base +board = esp32p4ser +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32p4ser-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32p4r3ser-safeboot] +platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152 +extends = env:tasmota32_base +board = esp32p4r3ser +board_build.app_partition_name = safeboot +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_SAFEBOOT + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32p4r3ser-safeboot.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 +lib_ignore = ${safeboot_flags.lib_ignore} + +[env:tasmota32] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_TASMOTA32 + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32.bin"' + +[env:tasmota32solo1] +extends = env:tasmota32_base +board = esp32-solo1 +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_TASMOTA32 + -DCODE_IMAGE_STR='"solo1"' + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32solo1.bin"' +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP + epdiy + +[env:tasmota32s2] +extends = env:tasmota32_base +board = esp32s2 +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_TASMOTA32 + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s2.bin"' +lib_ignore = ${env:tasmota32_base.lib_ignore} + esp-nimble-cpp + Micro-RTSP + epdiy + +[env:tasmota32s2cdc] +extends = env:tasmota32_base +board = esp32s2cdc +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_TASMOTA32 + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s2cdc.bin"' +lib_ignore = ${env:tasmota32_base.lib_ignore} + esp-nimble-cpp + Micro-RTSP + epdiy + +[env:tasmota32c2] +extends = env:tasmota32_base +board = esp32c2 +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_TASMOTA32 + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c2.bin"' +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP + +[env:tasmota32c3] +extends = env:tasmota32_base +board = esp32c3 +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_TASMOTA32 + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c3.bin"' +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP +[env:tasmota32c5] +platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152 +extends = env:tasmota32_base +board = esp32c5 +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_TASMOTA32 + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c5.bin"' +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP +[env:tasmota32c6] +extends = env:tasmota32_base +board = esp32c6 +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_TASMOTA32 + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32c6.bin"' +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP + +[env:tasmota32p4] +extends = env:tasmota32_base +board = esp32p4 +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_TASMOTA32 + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32p4.bin"' +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP + +[env:tasmota32p4r3] +platform = https://github.com/Jason2866/platform-espressif32.git#Arduino/IDF55_gcc152 +extends = env:tasmota32_base +board = esp32p4r3 +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_TASMOTA32 + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32p4r3.bin"' +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP + +[env:tasmota32s3] +extends = env:tasmota32_base +board = esp32s3-qio_qspi +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_TASMOTA32 + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32s3.bin"' +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP + epdiy + +[env:tasmota32-webcam] +extends = env:tasmota32_base +board = esp32-fix +board_build.f_cpu = 240000000L +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_WEBCAM + -DCAMERA_MODEL_AI_THINKER + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-webcam.bin"' +lib_extra_dirs = lib/lib_ssl, lib/libesp32 + +[env:tasmota32-bluetooth] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_BLUETOOTH + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-bluetooth.bin"' +lib_extra_dirs = lib/libesp32, lib/libesp32_div, lib/lib_basic, lib/lib_i2c, lib/lib_ssl +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP + +[env:tasmota32-display] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_DISPLAYS + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-display.bin"' +lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_display, lib/lib_ssl +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP + +[env:tasmota32-lvgl] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_LVGL + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-lvgl.bin"' +board_build.f_cpu = 240000000L +lib_extra_dirs = lib/libesp32, lib/libesp32_lvgl, lib/lib_basic, lib/lib_i2c, lib/lib_rf, lib/lib_div, lib/lib_ssl, lib/lib_display +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP + +[env:tasmota32-ir] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_IR + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-ir.bin"' +lib_extra_dirs = lib/libesp32, lib/lib_basic, lib/lib_ssl +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP + +[env:tasmota32-zbbrdgpro] +extends = env:tasmota32_base +board_build.partitions = partitions/esp32_partition_app1856k_fs1344k.csv +build_flags = ${env:tasmota32_base.build_flags} + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-zbbrdgpro.bin"' + -DFIRMWARE_ZBBRDGPRO +custom_files_upload = ${env:tasmota32_base.custom_files_upload} + tools/fw_SonoffZigbeeBridgePro_cc2652/Sonoff_ZBPro.autoconf + tasmota/berry/zigbee/cc2652_flasher.be + tasmota/berry/zigbee/intelhex.be + tasmota/berry/zigbee/sonoff_zb_pro_flasher.be + tools/fw_SonoffZigbeeBridgePro_cc2652/SonoffZBPro_coord_20220219.hex +custom_sdkconfig = CONFIG_D0WD_PSRAM_CLK_IO=5 + CONFIG_D0WD_PSRAM_CS_IO=18 +custom_component_remove = espressif/esp-dsp + espressif/esp_modem + espressif/esp32-camera + espressif/mdns +lib_extra_dirs = lib/lib_basic, lib/lib_ssl, lib/libesp32 +lib_ignore = ${env:tasmota32_base.lib_ignore} + Micro-RTSP + IRremoteESP8266 + TasmotaModbus + ESP Mail Client + JPEGDEC + +[env:tasmota32-nspanel] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} + -DFIRMWARE_NSPANEL + -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-nspanel.bin"' +custom_sdkconfig = CONFIG_D0WD_PSRAM_CLK_IO=5 + CONFIG_D0WD_PSRAM_CS_IO=18 + +[env:tasmota32-AD] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=ca_AD -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-AD.bin"' + +[env:tasmota32-AF] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=af_AF -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-AF.bin"' + +[env:tasmota32-BG] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=bg_BG -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-BG.bin"' + +[env:tasmota32-BR] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=pt_BR -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-BR.bin"' + +[env:tasmota32-CN] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=zh_CN -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-CN.bin"' + +[env:tasmota32-CZ] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=cs_CZ -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-CZ.bin"' + +[env:tasmota32-DE] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=de_DE -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-DE.bin"' + +[env:tasmota32-ES] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=es_ES -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-ES.bin"' + +[env:tasmota32-FR] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=fr_FR -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-FR.bin"' + +[env:tasmota32-FY] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=fy_NL -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-FY.bin"' + +[env:tasmota32-GR] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=el_GR -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-GR.bin"' + +[env:tasmota32-HE] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=he_HE -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-HE.bin"' + +[env:tasmota32-HU] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=hu_HU -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-HU.bin"' + +[env:tasmota32-IT] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=it_IT -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-IT.bin"' + +[env:tasmota32-KO] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=ko_KO -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-KO.bin"' + +[env:tasmota32-LT] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=lt_LT -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-LT.bin"' + +[env:tasmota32-NL] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=nl_NL -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-NL.bin"' + +[env:tasmota32-PL] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=pl_PL -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-PL.bin"' + +[env:tasmota32-PT] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=pt_PT -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-PT.bin"' + +[env:tasmota32-RO] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=ro_RO -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-RO.bin"' + +[env:tasmota32-RU] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=ru_RU -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-RU.bin"' + +[env:tasmota32-SE] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=sv_SE -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-SE.bin"' + +[env:tasmota32-SK] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=sk_SK -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-SK.bin"' + +[env:tasmota32-TR] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=tr_TR -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-TR.bin"' + +[env:tasmota32-TW] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=zh_TW -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-TW.bin"' + +[env:tasmota32-UK] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=uk_UA -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-UK.bin"' + +[env:tasmota32-VN] +extends = env:tasmota32_base +build_flags = ${env:tasmota32_base.build_flags} -DMY_LANGUAGE=vi_VN -DFIRMWARE_TASMOTA32 -DOTA_URL='"http://ota.tasmota.com/tasmota32/release/tasmota32-VN.bin"' diff --git a/tasmota/displaydesc/M5Stack_Dial_display.ini b/tasmota/displaydesc/M5Stack_Dial_display.ini index 4178b75a5..e9f9bf4c6 100644 --- a/tasmota/displaydesc/M5Stack_Dial_display.ini +++ b/tasmota/displaydesc/M5Stack_Dial_display.ini @@ -1,81 +1,81 @@ -:H,GC9A01,240,240,16,SPI,2,7,6,5,4,9,8,-1,40 -:S,2,1,0,1,80,80 -:I -EF,0 -EB,1,14 -FE,0 -EF,0 -EB,1,14 -84,1,40 -85,1,FF -86,1,FF -87,1,FF -88,1,0A -89,1,21 -8A,1,00 -8B,1,80 -8C,1,01 -8D,1,01 -8E,1,FF -8F,1,FF -B6,2,00,20 -3A,1,05 -90,4,08,08,08,08 -BD,1,06 -BC,1,00 -FF,3,60,01,04 -C3,1,13 -C4,1,13 -C9,1,22 -BE,1,11 -E1,2,10,0E -DF,3,21,0c,02 -F0,6,45,09,08,08,26,2A -F1,6,43,70,72,36,37,6F -F2,6,45,09,08,08,26,2A -F3,6,43,70,72,36,37,6F -ED,2,1B,0B -AE,1,77 -CD,1,63 -70,9,07,07,04,0E,0F,09,07,08,03 -E8,1,34 -62,0C,18,0D,71,ED,70,70,18,0F,71,EF,70,70 -63,0C,18,11,71,F1,70,70,18,13,71,F3,70,70 -64,7,28,29,F1,01,F1,00,07 -66,0A,3C,00,CD,67,45,45,10,00,00,00 -67,0A,00,3C,00,00,00,01,54,10,32,98 -74,7,10,85,80,00,00,4E,00 -98,2,3e,07 -35,0 -21,0 -11,80 -29,14 -:o,28 -:O,29 -:A,2A,2B,2C,01 -:R,36 -:0,C8,00,00,00 -:1,A8,00,00,00 -:2,08,00,00,00 -:3,68,00,00,00 -:D,51 -:r,2 -:UTI,FT3267,I1,38,-1,-1 -RD A8 -CP 11 -RTF -RD A3 -CP 64 -RTF -RT -:UTT -RDM 00 16 -MV 2 1 -RT -:UTX -MV 3 2 -RT -:UTY -MV 5 2 -RT +:H,GC9A01,240,240,16,SPI,2,7,6,5,4,9,8,-1,40 +:S,2,1,0,1,80,80 +:I +EF,0 +EB,1,14 +FE,0 +EF,0 +EB,1,14 +84,1,40 +85,1,FF +86,1,FF +87,1,FF +88,1,0A +89,1,21 +8A,1,00 +8B,1,80 +8C,1,01 +8D,1,01 +8E,1,FF +8F,1,FF +B6,2,00,20 +3A,1,05 +90,4,08,08,08,08 +BD,1,06 +BC,1,00 +FF,3,60,01,04 +C3,1,13 +C4,1,13 +C9,1,22 +BE,1,11 +E1,2,10,0E +DF,3,21,0c,02 +F0,6,45,09,08,08,26,2A +F1,6,43,70,72,36,37,6F +F2,6,45,09,08,08,26,2A +F3,6,43,70,72,36,37,6F +ED,2,1B,0B +AE,1,77 +CD,1,63 +70,9,07,07,04,0E,0F,09,07,08,03 +E8,1,34 +62,0C,18,0D,71,ED,70,70,18,0F,71,EF,70,70 +63,0C,18,11,71,F1,70,70,18,13,71,F3,70,70 +64,7,28,29,F1,01,F1,00,07 +66,0A,3C,00,CD,67,45,45,10,00,00,00 +67,0A,00,3C,00,00,00,01,54,10,32,98 +74,7,10,85,80,00,00,4E,00 +98,2,3e,07 +35,0 +21,0 +11,80 +29,14 +:o,28 +:O,29 +:A,2A,2B,2C,01 +:R,36 +:0,C8,00,00,00 +:1,A8,00,00,00 +:2,08,00,00,00 +:3,68,00,00,00 +:D,51 +:r,2 +:UTI,FT3267,I1,38,-1,-1 +RD A8 +CP 11 +RTF +RD A3 +CP 64 +RTF +RT +:UTT +RDM 00 16 +MV 2 1 +RT +:UTX +MV 3 2 +RT +:UTY +MV 5 2 +RT # \ No newline at end of file diff --git a/tasmota/include/tasmota_template.h b/tasmota/include/tasmota_template.h index ab602d36f..0f4b491d9 100644 --- a/tasmota/include/tasmota_template.h +++ b/tasmota/include/tasmota_template.h @@ -1,3741 +1,3741 @@ -/* - tasmota_template.h - template settings for Tasmota - - Copyright (C) 2021 Theo Arends - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef _TASMOTA_TEMPLATE_H_ -#define _TASMOTA_TEMPLATE_H_ - -// User selectable GPIO functionality -// ATTENTION: Only add at the end of this list just before GPIO_SENSOR_END -// Then add the same name(s) in a nice location in array kGpioNiceList -enum UserSelectablePins { - GPIO_NONE, // Not used - GPIO_KEY1, GPIO_KEY1_NP, GPIO_KEY1_INV, GPIO_KEY1_INV_NP, // 4 x Button - GPIO_SWT1, GPIO_SWT1_NP, // 8 x User connected external switches - GPIO_REL1, GPIO_REL1_INV, // 8 x Relays - GPIO_LED1, GPIO_LED1_INV, // 4 x Leds - GPIO_CNTR1, GPIO_CNTR1_NP, // 4 x Counter - GPIO_PWM1, GPIO_PWM1_INV, // 5 x PWM - GPIO_BUZZER, GPIO_BUZZER_INV, // Buzzer - GPIO_LEDLNK, GPIO_LEDLNK_INV, // Link led - GPIO_I2C_SCL, GPIO_I2C_SDA, // Software I2C - GPIO_SPI_MISO, GPIO_SPI_MOSI, GPIO_SPI_CLK, GPIO_SPI_CS, GPIO_SPI_DC, // Hardware SPI - GPIO_SSPI_MISO, GPIO_SSPI_MOSI, GPIO_SSPI_SCLK, GPIO_SSPI_CS, GPIO_SSPI_DC, // Software SPI - GPIO_BACKLIGHT, // Display backlight control - GPIO_OLED_RESET, // OLED Display Reset - GPIO_IRSEND, GPIO_IRRECV, // IR interface - GPIO_RFSEND, GPIO_RFRECV, // RF interface - GPIO_DHT11, GPIO_DHT22, GPIO_SI7021, GPIO_DHT11_OUT, // DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 - GPIO_DSB, GPIO_DSB_OUT, // DS18B20 or DS18S20 - GPIO_WS2812, // WS2812 Led string - GPIO_MHZ_TXD, GPIO_MHZ_RXD, // MH-Z19 Serial interface - GPIO_PZEM0XX_TX, GPIO_PZEM004_RX, GPIO_PZEM016_RX, GPIO_PZEM017_RX, // PZEM Serial Modbus interface - GPIO_SAIR_TX, GPIO_SAIR_RX, // SenseAir Serial interface - GPIO_PMS5003_TX, GPIO_PMS5003_RX, // Plantower PMS5003 Serial interface - GPIO_SDS0X1_TX, GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface - GPIO_SBR_TX, GPIO_SBR_RX, // Serial Bridge Serial interface - GPIO_SR04_TRIG, GPIO_SR04_ECHO, // SR04 interface - GPIO_SDM120_TX, GPIO_SDM120_RX, // SDM120 Serial interface - GPIO_SDM630_TX, GPIO_SDM630_RX, // SDM630 Serial interface - GPIO_TM1638CLK, GPIO_TM1638DIO, GPIO_TM1638STB, // TM1638 interface - GPIO_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player - GPIO_HX711_SCK, GPIO_HX711_DAT, // HX711 Load Cell interface - GPIO_TX2X_TXD_BLACK, // TX20/TX23 Transmission Pin - GPIO_TUYA_TX, GPIO_TUYA_RX, // Tuya Serial interface - GPIO_MGC3130_XFER, GPIO_MGC3130_RESET, // MGC3130 interface - GPIO_RF_SENSOR, // Rf receiver with sensor decoding - GPIO_AZ_TXD, GPIO_AZ_RXD, // AZ-Instrument 7798 Serial interface - GPIO_MAX31855CS, GPIO_MAX31855CLK, GPIO_MAX31855DO, // MAX31855 Serial interface - GPIO_NRG_SEL, GPIO_NRG_SEL_INV, GPIO_NRG_CF1, GPIO_HLW_CF, GPIO_HJL_CF, // HLW8012/HJL-01/BL0937 energy monitoring - GPIO_MCP39F5_TX, GPIO_MCP39F5_RX, GPIO_MCP39F5_RST, // MCP39F501 Energy monitoring (Shelly2) - GPIO_PN532_TXD, GPIO_PN532_RXD, // PN532 NFC Serial interface - GPIO_SM16716_CLK, GPIO_SM16716_DAT, GPIO_SM16716_SEL, // SM16716 SELECT - GPIO_DI, GPIO_DCKI, // my92x1 PWM controller - GPIO_CSE7766_TX, GPIO_CSE7766_RX, // CSE7766 Serial interface (S31 and Pow R2) - GPIO_ARIRFRCV, GPIO_ARIRFSEL, // Arilux RF Receive input - GPIO_TXD, GPIO_RXD, // Serial interface - GPIO_ROT1A, GPIO_ROT1B, // Rotary switch - GPIO_ADC_JOY, // Analog joystick - GPIO_SSPI_MAX31865_CS1, // MAX31865 Chip Select - GPIO_HRE_CLOCK, GPIO_HRE_DATA, // HR-E Water Meter - GPIO_ADE7953_IRQ, // ADE7953 IRQ - GPIO_SOLAXX1_TX, GPIO_SOLAXX1_RX, // Solax Inverter Serial interface - GPIO_ZIGBEE_TX, GPIO_ZIGBEE_RX, // Zigbee Serial interface - GPIO_RDM6300_RX, // RDM6300 RX - GPIO_IBEACON_TX, GPIO_IBEACON_RX, // HM17 IBEACON Serial interface - GPIO_A4988_DIR, GPIO_A4988_STP, GPIO_A4988_ENA, GPIO_A4988_MS1, // A4988 interface - GPIO_OUTPUT_HI, GPIO_OUTPUT_LO, // Fixed output state - GPIO_DDS2382_TX, GPIO_DDS2382_RX, // DDS2382 Serial interface - GPIO_DDSU666_TX, GPIO_DDSU666_RX, // DDSU666 Serial interface - GPIO_SM2135_CLK, GPIO_SM2135_DAT, // SM2135 PWM controller - GPIO_DEEPSLEEP, // Kill switch for deepsleep - GPIO_EXS_ENABLE, // EXS MCU Enable - GPIO_TASMOTACLIENT_TXD, GPIO_TASMOTACLIENT_RXD, // Client Serial interface - GPIO_TASMOTACLIENT_RST, GPIO_TASMOTACLIENT_RST_INV, // Client Reset - GPIO_HPMA_RX, GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface - GPIO_GPS_RX, GPIO_GPS_TX, // GPS Serial interface - GPIO_HM10_RX, GPIO_HM10_TX, // HM10-BLE-Mijia-bridge Serial interface - GPIO_LE01MR_RX, GPIO_LE01MR_TX, // F&F LE-01MR energy meter - GPIO_CC1101_GDO0, GPIO_CC1101_GDO2, // CC1101 Serial interface - GPIO_HRXL_RX, // Data from MaxBotix HRXL sonar range sensor - GPIO_ELECTRIQ_MOODL_TX, // ElectriQ iQ-wifiMOODL Serial TX - GPIO_AS3935, // Franklin Lightning Sensor - GPIO_ADC_INPUT, // Analog input - GPIO_ADC_TEMP, // Analog Thermistor - GPIO_ADC_LIGHT, // Analog Light sensor - GPIO_ADC_BUTTON, GPIO_ADC_BUTTON_INV, // Analog Button - GPIO_ADC_RANGE, // Analog Range - GPIO_ADC_CT_POWER, // ANalog Current -#ifdef ESP32 - GPIO_WEBCAM_PWDN, GPIO_WEBCAM_RESET, GPIO_WEBCAM_XCLK, // Webcam - GPIO_WEBCAM_SIOD, GPIO_WEBCAM_SIOC, // Webcam I2C - GPIO_WEBCAM_DATA, - GPIO_WEBCAM_VSYNC, GPIO_WEBCAM_HREF, GPIO_WEBCAM_PCLK, - GPIO_WEBCAM_PSCLK, - GPIO_WEBCAM_HSD, - GPIO_WEBCAM_PSRCS, -#endif - GPIO_BOILER_OT_RX, GPIO_BOILER_OT_TX, // OpenTherm Boiler TX pin - GPIO_WINDMETER_SPEED, // WindMeter speed counter pin - GPIO_KEY1_TC, // Touch pin as button - GPIO_BL0940_RX, // BL0940 serial interface - GPIO_TCP_TX, GPIO_TCP_RX, // TCP to serial bridge -#ifdef ESP32 - GPIO_ETH_PHY_POWER, GPIO_ETH_PHY_MDC, GPIO_ETH_PHY_MDIO, // Ethernet -#endif - GPIO_TELEINFO_RX, // Teleinfo telemetry data receive pin - GPIO_TELEINFO_ENABLE, // Teleinfo Enable Receive Pin - GPIO_LMT01, // LMT01 input counting pin - GPIO_IEM3000_TX, GPIO_IEM3000_RX, // IEM3000 Serial interface - GPIO_ZIGBEE_RST, // Zigbee reset - GPIO_DYP_RX, - GPIO_MIEL_HVAC_TX, GPIO_MIEL_HVAC_RX, // Mitsubishi Electric HVAC - GPIO_WE517_TX, GPIO_WE517_RX, // ORNO WE517 Serial interface - GPIO_AS608_TX, GPIO_AS608_RX, // Serial interface AS608 / R503 - GPIO_SHELLY_DIMMER_BOOT0, GPIO_SHELLY_DIMMER_RST_INV, - GPIO_RC522_RST, // RC522 reset - GPIO_P9813_CLK, GPIO_P9813_DAT, // P9813 Clock and Data - GPIO_OPTION_A, // Specific device options to be served in code - GPIO_FTC532, // FTC532 touch ctrlr serial input - GPIO_RC522_CS, - GPIO_NRF24_CS, GPIO_NRF24_DC, - GPIO_ILI9341_CS, GPIO_ILI9341_DC, - GPIO_ILI9488_CS, - GPIO_EPAPER29_CS, - GPIO_EPAPER42_CS, - GPIO_SSD1351_CS, - GPIO_RA8876_CS, - GPIO_ST7789_CS, GPIO_ST7789_DC, - GPIO_SSD1331_CS, GPIO_SSD1331_DC, - GPIO_SDCARD_CS, - GPIO_ROT1A_NP, GPIO_ROT1B_NP, // Rotary switch - GPIO_ADC_PH, // Analog PH Sensor - GPIO_BS814_CLK, GPIO_BS814_DAT, // Holtek BS814A2 touch ctrlr - GPIO_WIEGAND_D0, GPIO_WIEGAND_D1, // Wiegand Data lines - GPIO_NEOPOOL_TX, GPIO_NEOPOOL_RX, // Sugar Valley RS485 interface - GPIO_SDM72_TX, GPIO_SDM72_RX, // SDM72 Serial interface - GPIO_TM1637CLK, GPIO_TM1637DIO, // TM1637 interface - GPIO_PROJECTOR_CTRL_TX, GPIO_PROJECTOR_CTRL_RX, // LCD/DLP Projector Serial Control - GPIO_SSD1351_DC, - GPIO_XPT2046_CS, // XPT2046 SPI Chip Select - GPIO_CSE7761_TX, GPIO_CSE7761_RX, // CSE7761 Serial interface (Dual R3) - GPIO_VL53LXX_XSHUT1, // VL53LXX_XSHUT (the max number of sensors is VL53LXX_MAX_SENSORS)- Used when connecting multiple VL53LXX - GPIO_MAX7219CLK, GPIO_MAX7219DIN, GPIO_MAX7219CS, // MAX7219 interface - GPIO_TFMINIPLUS_TX, GPIO_TFMINIPLUS_RX, // TFmini Plus ToF sensor - GPIO_ZEROCROSS, -#ifdef ESP32 - GPIO_HALLEFFECT, - GPIO_EPD_DATA, // Base connection EPD driver -#endif - GPIO_INPUT, -#ifdef ESP32 - GPIO_KEY1_PD, GPIO_KEY1_INV_PD, GPIO_SWT1_PD, -#endif - GPIO_I2S_DOUT, GPIO_I2S_BCLK, GPIO_I2S_WS, GPIO_I2S_DIN, - GPIO_I2S_BCLK_IN, GPIO_I2S_WS_IN, // Spare since 20240603 - GPIO_INTERRUPT, - GPIO_MCP2515_CS, // MCP2515 Chip Select - GPIO_HRG15_TX, GPIO_HRG15_RX, // Hydreon RG-15 rain sensor serial interface - GPIO_VINDRIKTNING_RX, // IKEA VINDRIKTNING Serial interface - GPIO_BL0939_RX, // BL0939 Serial interface (Dual R3 v2) - GPIO_BL0942_RX, // BL0942 Serial interface - GPIO_HM330X_SET, // HM330X SET pin (sleep when low) - GPIO_HEARTBEAT, GPIO_HEARTBEAT_INV, - GPIO_SHIFT595_SRCLK, GPIO_SHIFT595_RCLK, GPIO_SHIFT595_OE, GPIO_SHIFT595_SER, // 74x595 Shift register - GPIO_SOLAXX1_RTS, // Solax Inverter Serial interface - GPIO_OPTION_E, // Emulated module - GPIO_SDM230_TX, GPIO_SDM230_RX, // SDM230 Serial interface - GPIO_ADC_MQ, // Analog MQ Sensor - GPIO_CM11_TXD, GPIO_CM11_RXD, // CM11 Serial interface - GPIO_BL6523_TX, GPIO_BL6523_RX, // BL6523 based Watt meter Serial interface - GPIO_ADE7880_IRQ, // ADE7880 IRQ - GPIO_RESET, // Generic reset - GPIO_MS01, // Sonoff MS01 Moisture Sensor 1wire interface - GPIO_SDIO_CMD, GPIO_SDIO_CLK, GPIO_SDIO_D0, GPIO_SDIO_D1, GPIO_SDIO_D2, GPIO_SDIO_D3, // SD Card SDIO interface, including 1-bit and 4-bit modes - GPIO_FLOWRATEMETER_IN, // Flowrate Meter - GPIO_BP5758D_CLK, GPIO_BP5758D_DAT, // BP5758D PWM controller - GPIO_SM2335_CLK, GPIO_SM2335_DAT, // SM2335 PWM controller - GPIO_MP3_DFR562_BUSY, // RB-DFR-562, DFPlayer Mini MP3 Player busy flag - GPIO_TM1621_CS, GPIO_TM1621_WR, GPIO_TM1621_RD, GPIO_TM1621_DAT, // Sonoff POWR3xxD and THR3xxD LCD display - GPIO_REL1_BI, GPIO_REL1_BI_INV, // 8 x Relays bistable - GPIO_I2S_MCLK, - GPIO_MBR_TX, GPIO_MBR_RX, // Modbus Bridge Serial interface - GPIO_ADE7953_RST, // ADE7953 Reset - GPIO_NRG_MBS_TX, GPIO_NRG_MBS_RX, // Generic Energy Modbus device - GPIO_ADE7953_CS, // ADE7953 SPI Chip Select - GPIO_DALI_RX, GPIO_DALI_TX, // DALI - GPIO_BP1658CJ_CLK, GPIO_BP1658CJ_DAT,// BP1658CJ - GPIO_DINGTIAN_CLK, GPIO_DINGTIAN_SDI, GPIO_DINGTIAN_Q7, GPIO_DINGTIAN_PL, GPIO_DINGTIAN_RCK, // Dingtian relay board - 595's & 165's pins - GPIO_LD2410_TX, GPIO_LD2410_RX, // HLK-LD2410 - GPIO_MBR_TX_ENA, GPIO_NRG_MBS_TX_ENA, // Modbus Bridge Serial Transmit Enable - GPIO_ME007_TRIG, GPIO_ME007_RX, // ME007 Serial/Trigger interface - GPIO_TUYAMCUBR_TX, GPIO_TUYAMCUBR_RX, // TuyaMCU Bridge - GPIO_BIOPDU_PZEM0XX_TX, GPIO_BIOPDU_PZEM016_RX, GPIO_BIOPDU_BIT, // Biomine BioPDU 625x12 - GPIO_MCP23XXX_INT, GPIO_MCP23SXX_CS, // MCP23xxx Int and SPI Chip select - GPIO_PCF8574_INT, // PCF8574 interrupt - GPIO_LOX_O2_RX, // LOX-O2 RX - GPIO_GM861_TX, GPIO_GM861_RX, // GM861 Serial interface - GPIO_DINGTIAN_OE, // New version of Dingtian relay board where PL is not shared with OE - GPIO_HDMI_CEC, // Support for HDMI CEC - GPIO_HC8_RXD, // HC8 Serial interface - GPIO_I2S_DAC, // Audio DAC support for ESP32 and ESP32S2 - GPIO_MAGIC_SWITCH, // MagicSwitch as in Sonoff BasicR4 - GPIO_PIPSOLAR_TX, GPIO_PIPSOLAR_RX, // pipsolar inverter - GPIO_LORA_CS, GPIO_LORA_RST, GPIO_LORA_BUSY, GPIO_LORA_DI0, GPIO_LORA_DI1, GPIO_LORA_DI2, GPIO_LORA_DI3, GPIO_LORA_DI4, GPIO_LORA_DI5, // LoRa SPI - GPIO_TS_SPI_CS, GPIO_TS_RST, GPIO_TS_IRQ, // SPI for Universal Touch Screen - GPIO_RN2XX3_TX, GPIO_RN2XX3_RX, GPIO_RN2XX3_RST, // RN2XX3 LoRaWan node Serial interface - GPIO_TCP_TX_EN, // TCP to serial bridge, EN pin - GPIO_ASR650X_TX, GPIO_ASR650X_RX, // ASR650X LoRaWan node Serial interface - GPIO_WOOLIIS_RX, // Wooliis Battery capacity monitor Serial RX - GPIO_ADC_VOLTAGE, GPIO_ADC_CURRENT, // Analog Voltage and Current - GPIO_BL0906_RX, // BL0906 Serial interface - GPIO_DALI_RX_INV, GPIO_DALI_TX_INV, // DALI - GPIO_LD2410S_TX, GPIO_LD2410S_RX, // HLK-LD2410S - GPIO_I2C_SER_TX, GPIO_I2C_SER_RX, // I2C via Serial using SC18IM704 protocol (xdrv74) - GPIO_TM1640CLK, GPIO_TM1640DIN, // TM1640 (16 x seven-segment LED controler) - GPIO_TWAI_TX, GPIO_TWAI_RX, GPIO_TWAI_BO, GPIO_TWAI_CLK, // ESP32 TWAI serial interface - GPIO_C8_CO2_5K_TX, GPIO_C8_CO2_5K_RX, // C8-CO2-5K CO2 Sensor - GPIO_V9240_TX, GPIO_V9240_RX, // V9240 serial interface - GPIO_LD2402_TX, GPIO_LD2402_RX, // HLK-LD2402 -#ifdef ESP32 - GPIO_HSDIO_CMD, GPIO_HSDIO_CLK, GPIO_HSDIO_RST, GPIO_HSDIO_D0, GPIO_HSDIO_D1, GPIO_HSDIO_D2, GPIO_HSDIO_D3, // Hosted MCU SDIO interface, including 1-bit and 4-bit modes -#endif - GPIO_VID6608_F, GPIO_VID6608_CW, // VID6608 - GPIO_MKSKYBLU_TX, GPIO_MKSKYBLU_RX, // MakeSkyBlue solar charge controller - GPIO_SENSOR_END }; - -// Error as warning to rethink GPIO usage with max 2045 -static_assert(GPIO_SENSOR_END < 2000, "Too many UserSelectablePins"); - -enum ProgramSelectablePins { - GPIO_FIX_START = 2046, - GPIO_USER, // User configurable needs to be 2047 - GPIO_MAX }; - -#define MAX_OPTIONS_A 9 // Increase if more bits are used from GpioOptionABits - -typedef union { // Restricted by MISRA-C Rule 18.4 but so useful... - uint32_t data; // Allow bit manipulation using SetOption - struct { // GPIO Option_A1 .. Option_A32 - uint32_t pwm1_input : 1; // bit 0 (v9.2.0.1) - Option_A1 - (Light) Change PWM1 to input on power off and no fade running (1) - uint32_t dummy_energy : 1; // bit 1 (v9.3.1.2) - Option_A2 - (Energy) Enable dummy values - uint32_t udisplay_driver : 1; // bit 2 (v9.3.1.2) - Option_A3 - (Display) Universal display driver - uint32_t enable_ccloader : 1; // bit 3 (v9.4.0.5) - Option_A4 - (Zigbee) Enable CCLoader using Zigbee Rx/Tx/Rst Gpios - uint32_t rotary_mi_desk : 1; // bit 4 (v9.5.0.5) - Option_A5 - (Rotary) Enable Mi Desk emulation - uint32_t linkind_support : 1; // bit 5 (v10.1.0.4) - Option_A6 - (Light) LinkInd support - uint32_t shelly_pro : 1; // bit 6 (v12.2.0.1) - Option_A7 - (Device) Shelly Pro - uint32_t ifan04_h : 1; // bit 7 (v14.1.0.4) - Option_A8 - (Device) Sonoff ifan04-H - uint32_t berry_energy : 1; // bit 8 (v14.2.0.4) - Option_A9 - (Energy) Enable Berry energy driver - uint32_t spare09 : 1; // bit 9 - uint32_t spare10 : 1; // bit 10 - uint32_t spare11 : 1; // bit 11 - uint32_t spare12 : 1; // bit 12 - uint32_t spare13 : 1; // bit 13 - uint32_t spare14 : 1; // bit 14 - uint32_t spare15 : 1; // bit 15 - uint32_t spare16 : 1; // bit 16 - uint32_t spare17 : 1; // bit 17 - uint32_t spare18 : 1; // bit 18 - uint32_t spare19 : 1; // bit 19 - uint32_t spare20 : 1; // bit 20 - uint32_t spare21 : 1; // bit 21 - uint32_t spare22 : 1; // bit 22 - uint32_t spare23 : 1; // bit 23 - uint32_t spare24 : 1; // bit 24 - uint32_t spare25 : 1; // bit 25 - uint32_t spare26 : 1; // bit 26 - uint32_t spare27 : 1; // bit 27 - uint32_t spare28 : 1; // bit 28 - uint32_t spare29 : 1; // bit 29 - uint32_t spare30 : 1; // bit 30 - uint32_t spare31 : 1; // bit 31 - }; -} GpioOptionABits; - -#ifdef ESP32 -enum SupportedEmulationModules { - SONOFF_BASIC, SONOFF_RF, SONOFF_SV, SONOFF_TH, SONOFF_DUAL, SONOFF_POW, SONOFF_4CH, SONOFF_S2X, SLAMPHER, SONOFF_TOUCH, - SONOFF_LED, CH1, CH4, MOTOR, ELECTRODRAGON, EXS_RELAY, WION, WEMOS_DUMMY, SONOFF_DEV, H801, - SONOFF_SC, SONOFF_BN, SONOFF_4CHPRO, HUAFAN_SS, SONOFF_BRIDGE, SONOFF_B1, AILIGHT, SONOFF_T11, SONOFF_T12, SONOFF_T13, - SUPLA1, WITTY, YUNSHAN, MAGICHOME, LUANIHVIO, KMC_70011, ARILUX_LC01, ARILUX_LC11, SONOFF_DUAL_R2, ARILUX_LC06, - SONOFF_S31, ZENGGE_ZF_WF017, SONOFF_POW_R2, SONOFF_IFAN02, BLITZWOLF_BWSHP, SHELLY1, SHELLY2, PHILIPS, NEO_COOLCAM, ESP_SWITCH, - OBI, TECKIN, APLIC_WDP303075, TUYA_DIMMER, GOSUND, ARMTRONIX_DIMMERS, SK03_TUYA, PS_16_DZ, TECKIN_US, MANZOKU_EU_4, - OBI2, YTF_IR_BRIDGE, DIGOO, KA10, ZX2820, MI_DESK_LAMP, SP10, WAGA, SYF05, SONOFF_L1, - SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1, SONOFF_ZB_BRIDGE, - MAXMODULE_EMULATION }; - -#define MAX_OPTIONS_E 1 // Increase if more emulated modules are supported from kModuleEmulationList - -const uint8_t kModuleEmulationList[] PROGMEM = { - PWM_DIMMER // (v10.1.0.4) - Option_E1 - (Light) USE_PWM_DIMMER support -}; -#endif // ESP32 - -// Text in webpage Module Parameters and commands GPIOS and GPIO -const char kSensorNames[] PROGMEM = - D_SENSOR_NONE "|" - D_SENSOR_BUTTON "|" D_SENSOR_BUTTON "_n|" D_SENSOR_BUTTON "_i|" D_SENSOR_BUTTON "_in|" - D_SENSOR_SWITCH "|" D_SENSOR_SWITCH "_n|" - D_SENSOR_RELAY "|" D_SENSOR_RELAY "_i|" - D_SENSOR_LED "|" D_SENSOR_LED "_i|" - D_SENSOR_COUNTER "|" D_SENSOR_COUNTER "_n|" - D_SENSOR_PWM "|" D_SENSOR_PWM "_i|" - D_SENSOR_BUZZER "|" D_SENSOR_BUZZER "_i|" - D_SENSOR_LED_LINK "|" D_SENSOR_LED_LINK "_i|" - D_SENSOR_I2C_SCL "|" D_SENSOR_I2C_SDA "|" - D_SENSOR_SPI_MISO "|" D_SENSOR_SPI_MOSI "|" D_SENSOR_SPI_CLK "|" D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" - D_SENSOR_SSPI_MISO "|" D_SENSOR_SSPI_MOSI "|" D_SENSOR_SSPI_SCLK "|" D_SENSOR_SSPI_CS "|" D_SENSOR_SSPI_DC "|" - D_SENSOR_BACKLIGHT "|" D_SENSOR_DISP_RESET "|" - D_SENSOR_IRSEND "|" D_SENSOR_IRRECV "|" - D_SENSOR_RFSEND "|" D_SENSOR_RFRECV "|" - D_SENSOR_DHT11 "|" D_SENSOR_AM2301 "|" D_SENSOR_SI7021 "|" D_SENSOR_DHT11 "_o|" - D_SENSOR_DS18X20 "|" D_SENSOR_DS18X20 "_o|" - D_SENSOR_WS2812 "|" - D_SENSOR_MHZ_TX "|" D_SENSOR_MHZ_RX "|" - D_SENSOR_PZEM0XX_TX "|" D_SENSOR_PZEM004_RX "|" D_SENSOR_PZEM016_RX "|" D_SENSOR_PZEM017_RX "|" - D_SENSOR_SAIR_TX "|" D_SENSOR_SAIR_RX "|" - D_SENSOR_PMS5003_TX "|" D_SENSOR_PMS5003_RX "|" - D_SENSOR_SDS0X1_TX "|" D_SENSOR_SDS0X1_RX "|" - D_SENSOR_SBR_TX "|" D_SENSOR_SBR_RX "|" - D_SENSOR_SR04_TRIG "|" D_SENSOR_SR04_ECHO "|" - D_SENSOR_SDM120_TX "|" D_SENSOR_SDM120_RX "|" - D_SENSOR_SDM630_TX "|" D_SENSOR_SDM630_RX "|" - D_SENSOR_TM1638_CLK "|" D_SENSOR_TM1638_DIO "|" D_SENSOR_TM1638_STB "|" - D_SENSOR_DFR562 "|" - D_SENSOR_HX711_SCK "|" D_SENSOR_HX711_DAT "|" - D_SENSOR_TX2X_TX "|" - D_SENSOR_TUYA_TX "|" D_SENSOR_TUYA_RX "|" - D_SENSOR_MGC3130_XFER "|" D_SENSOR_MGC3130_RESET "|" - D_SENSOR_RF_SENSOR "|" - D_SENSOR_AZ_TX "|" D_SENSOR_AZ_RX "|" - D_SENSOR_MAX31855_CS "|" D_SENSOR_MAX31855_CLK "|" D_SENSOR_MAX31855_DO "|" - D_SENSOR_NRG_SEL "|" D_SENSOR_NRG_SEL "_i|" D_SENSOR_NRG_CF1 "|" D_SENSOR_HLW_CF "|" D_SENSOR_HJL_CF "|" - D_SENSOR_MCP39F5_TX "|" D_SENSOR_MCP39F5_RX "|" D_SENSOR_MCP39F5_RST "|" - D_SENSOR_PN532_TX "|" D_SENSOR_PN532_RX "|" - D_SENSOR_SM16716_CLK "|" D_SENSOR_SM16716_DAT "|" D_SENSOR_SM16716_POWER "|" - D_SENSOR_MY92X1_DI "|" D_SENSOR_MY92X1_DCKI "|" - D_SENSOR_CSE7766_TX "|" D_SENSOR_CSE7766_RX "|" - D_SENSOR_ARIRFRCV "|" D_SENSOR_ARIRFSEL "|" - D_SENSOR_TXD "|" D_SENSOR_RXD "|" - D_SENSOR_ROTARY " A|" D_SENSOR_ROTARY " B|" - D_SENSOR_ADC_JOYSTICK "|" - D_SENSOR_MAX31865_CS "|" - D_SENSOR_HRE_CLOCK "|" D_SENSOR_HRE_DATA "|" - D_SENSOR_ADE7953_IRQ "|" - D_SENSOR_SOLAXX1_TX "|" D_SENSOR_SOLAXX1_RX "|" - D_SENSOR_ZIGBEE_TXD "|" D_SENSOR_ZIGBEE_RXD "|" - D_SENSOR_RDM6300_RX "|" - D_SENSOR_IBEACON_TX "|" D_SENSOR_IBEACON_RX "|" - D_SENSOR_A4988_DIR "|" D_SENSOR_A4988_STP "|" D_SENSOR_A4988_ENA "|" D_SENSOR_A4988_MS1 "|" - D_SENSOR_OUTPUT_HI "|" D_SENSOR_OUTPUT_LO "|" - D_SENSOR_DDS2382_TX "|" D_SENSOR_DDS2382_RX "|" - D_SENSOR_DDSU666_TX "|" D_SENSOR_DDSU666_RX "|" - D_SENSOR_SM2135_CLK "|" D_SENSOR_SM2135_DAT "|" - D_SENSOR_DEEPSLEEP "|" D_SENSOR_EXS_ENABLE "|" - D_SENSOR_CLIENT_TX "|" D_SENSOR_CLIENT_RX "|" D_SENSOR_CLIENT_RESET "|" D_SENSOR_CLIENT_RESET "_i|" - D_SENSOR_HPMA_RX "|" D_SENSOR_HPMA_TX "|" - D_SENSOR_GPS_RX "|" D_SENSOR_GPS_TX "|" - D_SENSOR_HM10_RX "|" D_SENSOR_HM10_TX "|" - D_SENSOR_LE01MR_RX "|" D_SENSOR_LE01MR_TX "|" - D_SENSOR_CC1101_GDO0 "|" D_SENSOR_CC1101_GDO2 "|" - D_SENSOR_HRXL_RX "|" - D_SENSOR_ELECTRIQ_MOODL "|" - D_SENSOR_AS3935 "|" - D_SENSOR_ADC_INPUT "|" - D_SENSOR_ADC_TEMP "|" - D_SENSOR_ADC_LIGHT "|" - D_SENSOR_ADC_BUTTON "|" D_SENSOR_ADC_BUTTON "_i|" - D_SENSOR_ADC_RANGE "|" - D_SENSOR_ADC_CT_POWER "|" -#ifdef ESP32 - D_GPIO_WEBCAM_PWDN "|" D_GPIO_WEBCAM_RESET "|" D_GPIO_WEBCAM_XCLK "|" - D_GPIO_WEBCAM_SIOD "|" D_GPIO_WEBCAM_SIOC "|" - D_GPIO_WEBCAM_DATA "|" - D_GPIO_WEBCAM_VSYNC "|" D_GPIO_WEBCAM_HREF "|" D_GPIO_WEBCAM_PCLK "|" - D_GPIO_WEBCAM_PSCLK "|" - D_GPIO_WEBCAM_HSD "|" - D_GPIO_WEBCAM_PSRCS "|" -#endif - D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" - D_SENSOR_WINDMETER_SPEED "|" D_SENSOR_BUTTON "_tc|" - D_SENSOR_BL0940_RX "|" - D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" -#ifdef ESP32 - D_SENSOR_ETH_PHY_POWER "|" D_SENSOR_ETH_PHY_MDC "|" D_SENSOR_ETH_PHY_MDIO "|" -#endif - D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE "|" - D_SENSOR_LMT01_PULSE "|" - D_SENSOR_IEM3000_TX "|" D_SENSOR_IEM3000_RX "|" - D_SENSOR_ZIGBEE_RST "|" - D_SENSOR_DYP_RX "|" - D_SENSOR_MIEL_HVAC_TX "|" D_SENSOR_MIEL_HVAC_RX "|" - D_SENSOR_WE517_TX "|" D_SENSOR_WE517_RX "|" - D_SENSOR_AS608_TX "|" D_SENSOR_AS608_RX "|" - D_SENSOR_SHELLY_DIMMER_BOOT0 "|" D_SENSOR_SHELLY_DIMMER_RST_INV "|" - D_SENSOR_RC522_RST "|" - D_SENSOR_P9813_CLK "|" D_SENSOR_P9813_DAT "|" - D_SENSOR_OPTION " A|" - D_SENSOR_FTC532 "|" - D_SENSOR_RC522_CS "|" - D_SENSOR_NRF24_CS "|" D_SENSOR_NRF24_DC "|" - D_SENSOR_ILI9341_CS "|" D_SENSOR_ILI9341_DC "|" - D_SENSOR_ILI9488_CS "|" - D_SENSOR_EPAPER29_CS "|" - D_SENSOR_EPAPER42_CS "|" - D_SENSOR_SSD1351_CS "|" - D_SENSOR_RA8876_CS "|" - D_SENSOR_ST7789_CS "|" D_SENSOR_ST7789_DC "|" - D_SENSOR_SSD1331_CS "|" D_SENSOR_SSD1331_DC "|" - D_SENSOR_SDCARD_CS "|" - D_SENSOR_ROTARY " A_n|" D_SENSOR_ROTARY " B_n|" - D_SENSOR_ADC_PH "|" - D_SENSOR_BS814_CLK "|" D_SENSOR_BS814_DAT "|" - D_SENSOR_WIEGAND_D0 "|" D_SENSOR_WIEGAND_D1 "|" - D_SENSOR_NEOPOOL_TX "|" D_SENSOR_NEOPOOL_RX "|" - D_SENSOR_SDM72_TX "|" D_SENSOR_SDM72_RX "|" - D_SENSOR_TM1637_CLK "|" D_SENSOR_TM1637_DIO "|" - D_SENSOR_PROJECTOR_CTRL_TX "|" D_SENSOR_PROJECTOR_CTRL_RX "|" - D_SENSOR_SSD1351_DC "|" - D_SENSOR_XPT2046_CS "|" - D_SENSOR_CSE7761_TX "|" D_SENSOR_CSE7761_RX "|" - D_SENSOR_VL53LXX_XSHUT "|" - D_SENSOR_MAX7219_CLK "|" D_SENSOR_MAX7219_DIN "|" D_SENSOR_MAX7219_CS "|" - D_SENSOR_TFMINIPLUS_TX "|" D_SENSOR_TFMINIPLUS_RX "|" - D_SENSOR_ZEROCROSS "|" -#ifdef ESP32 - D_SENSOR_HALLEFFECT "|" - D_SENSOR_EPD_DATA "|" -#endif - D_SENSOR_INPUT "|" -#ifdef ESP32 - D_SENSOR_BUTTON "_d|" D_SENSOR_BUTTON "_id|" D_SENSOR_SWITCH "_d|" -#endif - D_SENSOR_I2S_DOUT "|" D_SENSOR_I2S_BCLK "|" D_SENSOR_I2S_WS "|" D_SENSOR_I2S_DIN "|" - D_SENSOR_I2S_BCLK_IN "|" D_SENSOR_I2S_WS_IN "|" - D_SENSOR_INTERRUPT "|" - D_SENSOR_MCP2515_CS "|" - D_SENSOR_HRG15_TX "|" D_SENSOR_HRG15_RX "|" - D_SENSOR_VINDRIKTNING_RX "|" - D_SENSOR_BL0939_RX "|" - D_SENSOR_BL0942_RX "|" - D_SENSOR_HM330X_SET "|" - D_SENSOR_HEARTBEAT "|" D_SENSOR_HEARTBEAT "_i|" - D_GPIO_SHIFT595_SRCLK "|" D_GPIO_SHIFT595_RCLK "|" D_GPIO_SHIFT595_OE "|" D_GPIO_SHIFT595_SER "|" - D_SENSOR_SOLAXX1_RTS "|" - D_SENSOR_OPTION " E|" - D_SENSOR_SDM230_TX "|" D_SENSOR_SDM230_RX "|" - D_SENSOR_ADC_MQ "|" - D_SENSOR_CM11_TX "|" D_SENSOR_CM11_RX "|" - D_SENSOR_BL6523_TX "|" D_SENSOR_BL6523_RX "|" - D_SENSOR_ADE7880_IRQ "|" - D_SENSOR_RESET "|" - D_SENSOR_MS01 "|" - D_SENSOR_SDIO_CMD "|" D_SENSOR_SDIO_CLK "|" D_SENSOR_SDIO_D0 "|" D_SENSOR_SDIO_D1 "|" D_SENSOR_SDIO_D2 "|" D_SENSOR_SDIO_D3 "|" - D_SENSOR_FLOWRATEMETER "|" - D_SENSOR_BP5758D_CLK "|" D_SENSOR_BP5758D_DAT "|" - D_SENSOR_SM2335_CLK "|" D_SENSOR_SM2335_DAT "|" - D_SENSOR_DFR562_BUSY "|" - D_GPIO_TM1621_CS "|" D_GPIO_TM1621_WR "|" D_GPIO_TM1621_RD "|" D_GPIO_TM1621_DAT "|" - D_SENSOR_RELAY "_b|" D_SENSOR_RELAY "_bi|" - D_SENSOR_I2S_MCLK "|" - D_SENSOR_MBR_TX "|" D_SENSOR_MBR_RX "|" - D_SENSOR_ADE7953_RST "|" - D_SENSOR_NRG_MBS_TX "|" D_SENSOR_NRG_MBS_RX "|" - D_SENSOR_ADE7953_CS "|" - D_SENSOR_DALI_RX "|" D_SENSOR_DALI_TX "|" - D_SENSOR_BP1658CJ_CLK "|" D_SENSOR_BP1658CJ_DAT "|" - D_GPIO_DINGTIAN_CLK "|" D_GPIO_DINGTIAN_SDI "|" D_GPIO_DINGTIAN_Q7 "|" D_GPIO_DINGTIAN_PL "|" D_GPIO_DINGTIAN_RCK "|" - D_SENSOR_LD2410_TX "|" D_SENSOR_LD2410_RX "|" - D_SENSOR_MBR_TX_ENA "|" D_SENSOR_NRG_MBS_TX_ENA "|" - D_SENSOR_ME007_TRIG "|" D_SENSOR_ME007_RX "|" - D_SENSOR_TUYAMCUBR_TX "|" D_SENSOR_TUYAMCUBR_RX "|" - D_SENSOR_BIOPDU_PZEM0XX_TX "|" D_SENSOR_BIOPDU_PZEM016_RX "|" D_SENSOR_BIOPDU_BIT "|" - D_SENSOR_MCP23XXX_INT "|" D_SENSOR_MCP23SXX_CS "|" - D_SENSOR_PCF8574_INT "|" - D_SENSOR_LOX_O2_RX "|" - D_SENSOR_GM861_TX "|" D_SENSOR_GM861_RX "|" - D_GPIO_DINGTIAN_OE "|" - D_SENSOR_HDMI_CEC "|" - D_SENSOR_HC8_RX "|" - D_SENSOR_I2S_DAC "|" - D_GPIO_MAGIC_SWITCH "|" - D_SENSOR_PIPSOLAR_TX "|" D_SENSOR_PIPSOLAR_RX "|" - D_GPIO_LORA_CS "|" D_GPIO_LORA_RST "|" D_GPIO_LORA_BUSY "|" D_GPIO_LORA_DI "0|" D_GPIO_LORA_DI "1|" D_GPIO_LORA_DI "2|" D_GPIO_LORA_DI "3|" D_GPIO_LORA_DI "4|" D_GPIO_LORA_DI "5|" - D_GPIO_TS_SPI_CS "|" D_GPIO_TS_RST "|" D_GPIO_TS_IRQ "|" - D_GPIO_RN2XX3_TX "|" D_GPIO_RN2XX3_RX "|" D_GPIO_RN2XX3_RST "|" - D_SENSOR_TCP_TXD_EN "|" - D_GPIO_ASR650X_TX "|" D_GPIO_ASR650X_RX "|" - D_SENSOR_WOOLIIS_RX "|" - D_SENSOR_ADC_VOLTAGE "|" D_SENSOR_ADC_CURRENT "|" - D_SENSOR_BL0906_RX "|" - D_SENSOR_DALI_RX "_i|" D_SENSOR_DALI_TX "_i|" - D_SENSOR_LD2410S_TX "|" D_SENSOR_LD2410S_RX "|" - D_SENSOR_I2C_SER_TX "|" D_SENSOR_I2C_SER_RX "|" - D_SENSOR_TM1640_CLK "|" D_SENSOR_TM1640_DIN "|" - D_SENSOR_TWAI_TX "|" D_SENSOR_TWAI_RX "|" D_SENSOR_TWAI_BO "|" D_SENSOR_TWAI_CLK "|" - D_SENSOR_C8_CO2_5K_TX "|" D_SENSOR_C8_CO2_5K_RX "|" - D_SENSOR_V9240_TX "|" D_SENSOR_V9240_RX "|" - D_SENSOR_LD2402_TX "|" D_SENSOR_LD2402_RX "|" -#ifdef ESP32 - D_SENSOR_HSDIO_CMD "|" D_SENSOR_HSDIO_CLK "|" D_SENSOR_HSDIO_RST "|" D_SENSOR_HSDIO_D0 "|" D_SENSOR_HSDIO_D1 "|" D_SENSOR_HSDIO_D2 "|" D_SENSOR_HSDIO_D3 "|" -#endif - D_VID6608_F "|" D_VID6608_CW "|" - D_SENSOR_MKSKYBLU_TX "|" D_SENSOR_MKSKYBLU_RX "|" -; - -const char kSensorNamesFixed[] PROGMEM = - D_SENSOR_USER; - -// Max number of GPIOs -#define MAX_I2C 1 // Display no index if one bus -#ifdef USE_I2C_BUS2 -#undef MAX_I2C -#define MAX_I2C 2 -#endif -#define MAX_MAX31855S 6 -#define MAX_MAX31865S 6 -#define MAX_MCP23XXX 6 -#define MAX_FLOWRATEMETER 2 -#define MAX_A4988_MSS 3 -#define MAX_WEBCAM_DATA 8 -#define MAX_WEBCAM_HSD 3 -#define MAX_SM2135_DAT 10 -#define MAX_SM2335_DAT 16 -#define MAX_DSB 4 -#define MAX_BP1658CJ_DAT 16 -#define MAX_DINGTIAN_SHIFT 4 -#define MAX_MAGIC_SWITCH_MODES 2 -#define MAX_BL0906_RX 6 // Model number of phases, 2 (EM2), 6 (EM6) -#define MAX_BL0942_RX 8 // Baudrates 1/5 (4800), 2/6 (9600), 3/7 (19200), 4/8 (38400), Support Positive values only 1..4, Support also negative values 5..8 -#define MAX_CSE7761 2 // Model 1/2 (DUALR3), 2/2 (POWCT) -#define MAX_TWAI SOC_TWAI_CONTROLLER_NUM -#define MAX_GPS_RX 3 // Baudrates 1 (9600), 2 (19200), 3 (38400) -#ifdef ESP32 -#define MAX_MKSKYBLU_IF 8 // MakeSkyBlue solar charger: ESP32-NRG supports up to 8 phases -#else -#define MAX_MKSKYBLU_IF 3 // MakeSkyBlue solar charger: ESP82xx-NRG supports up to 3 phases -#endif - -const uint16_t kGpioNiceList[] PROGMEM = { - GPIO_NONE, // Not used - AGPIO(GPIO_OPTION_A) + AGMAX(MAX_OPTIONS_A), // Device specific options -#ifdef ESP32 - AGPIO(GPIO_OPTION_E) + AGMAX(MAX_OPTIONS_E), // Device module emulation -#endif - AGPIO(GPIO_KEY1) + AGMAX(MAX_KEYS), // Buttons - AGPIO(GPIO_KEY1_NP) + AGMAX(MAX_KEYS), -#ifdef ESP32 - AGPIO(GPIO_KEY1_PD) + AGMAX(MAX_KEYS), -#endif - AGPIO(GPIO_KEY1_INV) + AGMAX(MAX_KEYS), - AGPIO(GPIO_KEY1_INV_NP) + AGMAX(MAX_KEYS), -#ifdef ESP32 - AGPIO(GPIO_KEY1_INV_PD) + AGMAX(MAX_KEYS), -#if defined(SOC_TOUCH_VERSION_1) || defined(SOC_TOUCH_VERSION_2) - AGPIO(GPIO_KEY1_TC) + AGMAX(MAX_KEYS), // Touch button -#endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2 -#endif - AGPIO(GPIO_SWT1) + AGMAX(MAX_SWITCHES), // User connected external switches - AGPIO(GPIO_SWT1_NP) + AGMAX(MAX_SWITCHES), -#ifdef ESP32 - AGPIO(GPIO_SWT1_PD) + AGMAX(MAX_SWITCHES), -#endif -#ifdef ROTARY_V1 - AGPIO(GPIO_ROT1A) + AGMAX(MAX_ROTARIES), // Rotary A Pin - AGPIO(GPIO_ROT1B) + AGMAX(MAX_ROTARIES), // Rotary B Pin - AGPIO(GPIO_ROT1A_NP) + AGMAX(MAX_ROTARIES), // Rotary A Pin No Pullup - AGPIO(GPIO_ROT1B_NP) + AGMAX(MAX_ROTARIES), // Rotary B Pin No Pullup -#endif - AGPIO(GPIO_REL1) + AGMAX(MAX_RELAYS), // Relays - AGPIO(GPIO_REL1_INV) + AGMAX(MAX_RELAYS), - AGPIO(GPIO_REL1_BI) + AGMAX(MAX_RELAYS), // Bistable (Latching) two coil relays - AGPIO(GPIO_REL1_BI_INV) + AGMAX(MAX_RELAYS), - AGPIO(GPIO_LED1) + AGMAX(MAX_LEDS), // Leds - AGPIO(GPIO_LED1_INV) + AGMAX(MAX_LEDS), -#ifdef USE_COUNTER - AGPIO(GPIO_CNTR1) + AGMAX(MAX_COUNTERS), // Counters - AGPIO(GPIO_CNTR1_NP) + AGMAX(MAX_COUNTERS), -#endif - AGPIO(GPIO_PWM1) + AGMAX(MAX_PWMS), // RGB Red or C Cold White - AGPIO(GPIO_PWM1_INV) + AGMAX(MAX_PWMS), // or extended PWM for ESP32 -#ifdef USE_BUZZER - AGPIO(GPIO_BUZZER), // Buzzer - AGPIO(GPIO_BUZZER_INV), // Inverted buzzer -#endif - AGPIO(GPIO_LEDLNK), // Link led - AGPIO(GPIO_LEDLNK_INV), // Inverted link led -#ifdef USE_BERRY - AGPIO(GPIO_INPUT) + AGMAX(MAX_SWITCHES), // Pure digital input to be read via Berry - AGPIO(GPIO_INTERRUPT) + AGMAX(MAX_SWITCHES), // Interrupt pins to be catched by Berry -#endif - AGPIO(GPIO_OUTPUT_HI), // Fixed output high - AGPIO(GPIO_OUTPUT_LO), // Fixed output low - AGPIO(GPIO_HEARTBEAT), // Every second pulsed high - AGPIO(GPIO_HEARTBEAT_INV), // Every second pulsed low - AGPIO(GPIO_RESET), // Generic reset -#ifdef USE_FTC532 - AGPIO(GPIO_FTC532), // FTC532 touch input -#endif -#ifdef USE_BS814A2 - AGPIO(GPIO_BS814_CLK), // Holtek BS814A2 touch ctrlr - AGPIO(GPIO_BS814_DAT), -#endif - -/*-------------------------------------------------------------------------------------------*\ - * Protocol specifics -\*-------------------------------------------------------------------------------------------*/ - -#ifdef USE_I2C - AGPIO(GPIO_I2C_SCL) + AGMAX(MAX_I2C), // I2C SCL - AGPIO(GPIO_I2C_SDA) + AGMAX(MAX_I2C), // I2C SDA -#ifdef USE_PCF8574 - AGPIO(GPIO_PCF8574_INT), // PCF8574 Interrupt -#endif // USE_PCF8574 -#ifdef USE_I2C_SERIAL - AGPIO(GPIO_I2C_SER_TX) + AGMAX(MAX_I2C), // I2C via Serial TX - AGPIO(GPIO_I2C_SER_RX) + AGMAX(MAX_I2C), // I2C via Serial RX -#endif // USE_I2C_SERIAL -#endif - -#if defined(USE_I2S_AUDIO) || defined (USE_I2S) - AGPIO(GPIO_I2S_MCLK) + AGMAX(MAX_I2S), // I2S master clock - AGPIO(GPIO_I2S_BCLK) + AGMAX(MAX_I2S), // I2S bit clock - AGPIO(GPIO_I2S_DOUT) + AGMAX(MAX_I2S), // I2S Out Data - AGPIO(GPIO_I2S_DAC) + AGMAX(2), // I2S DAC Output - AGPIO(GPIO_I2S_WS) + AGMAX(MAX_I2S), // I2S word select - AGPIO(GPIO_I2S_DIN) + AGMAX(MAX_I2S), // I2S IN Data -#endif - -#ifdef USE_SPI - AGPIO(GPIO_SPI_MISO) + AGMAX(MAX_SPI), // SPI MISO - AGPIO(GPIO_SPI_MOSI) + AGMAX(MAX_SPI), // SPI MOSI - AGPIO(GPIO_SPI_CLK) + AGMAX(MAX_SPI), // SPI Clk - AGPIO(GPIO_SPI_CS) + AGMAX(MAX_SPI), // SPI Chip Select - AGPIO(GPIO_SPI_DC) + AGMAX(MAX_SPI), // SPI Data Direction -#ifdef USE_NRF24 - AGPIO(GPIO_NRF24_CS), - AGPIO(GPIO_NRF24_DC), -#endif -#ifdef USE_RC522 - AGPIO(GPIO_RC522_CS), // RC522 Rfid Chip Select - AGPIO(GPIO_RC522_RST), // RC522 Rfid Reset -#endif -#ifdef USE_SDCARD - AGPIO(GPIO_SDCARD_CS) + AGMAX(MAX_SPI), // SDCard in SPI mode -#endif // USE_SDCARD -#if defined(USE_MCP2515) || defined(USE_CANSNIFFER) - AGPIO(GPIO_MCP2515_CS), -#endif // USE_MCP2515 -#ifdef USE_MCP23XXX_DRV - AGPIO(GPIO_MCP23SXX_CS) + AGMAX(MAX_MCP23XXX), -#endif // USE_MCP23XXX_DRV -#ifdef USE_SPI_LORA - AGPIO(GPIO_LORA_CS), - AGPIO(GPIO_LORA_RST), - AGPIO(GPIO_LORA_BUSY), - AGPIO(GPIO_LORA_DI0), - AGPIO(GPIO_LORA_DI1), - AGPIO(GPIO_LORA_DI2), - AGPIO(GPIO_LORA_DI3), - AGPIO(GPIO_LORA_DI4), - AGPIO(GPIO_LORA_DI5), -#endif // USE_SPI_LORA -#endif // USE_SPI - -#if defined(USE_SDCARD) && defined(ESP32) - AGPIO(GPIO_SDIO_CMD), // SDCard in SDIO mode - AGPIO(GPIO_SDIO_CLK), - AGPIO(GPIO_SDIO_D0), - AGPIO(GPIO_SDIO_D1), // (opt) if in 4-bit mode, DAT1-3 are needed - AGPIO(GPIO_SDIO_D2), - AGPIO(GPIO_SDIO_D3), -#endif // USE_SDCARD - - AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Client Output - AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Client Input - AGPIO(GPIO_SSPI_SCLK), // Software SPI Serial Clock - AGPIO(GPIO_SSPI_CS), // Software SPI Chip Select - AGPIO(GPIO_SSPI_DC), // Software SPI Data or Command - -#if defined(USE_DISPLAY) || defined(USE_LVGL) -#ifdef USE_UNIVERSAL_TOUCH - AGPIO(GPIO_TS_SPI_CS), // Touch CS - AGPIO(GPIO_TS_RST), // Touch Reset - AGPIO(GPIO_TS_IRQ), // Touch IRQ -#endif // USE_UNIVERSAL_TOUCH -// REMOVED -// #ifdef USE_DISPLAY_ILI9341 -// AGPIO(GPIO_ILI9341_CS), -// AGPIO(GPIO_ILI9341_DC), -// #endif // USE_DISPLAY_ILI9341 - -#ifdef USE_XPT2046 - AGPIO(GPIO_XPT2046_CS), // XPT2046 SPI Chip Select -#endif - -#ifdef USE_DISPLAY_ILI9488 - AGPIO(GPIO_ILI9488_CS), -#endif // USE_DISPLAY_ILI9488 -#ifdef USE_DISPLAY_EPAPER_29 - AGPIO(GPIO_EPAPER29_CS), -#endif // USE_DISPLAY_EPAPER_29 -#ifdef USE_DISPLAY_EPAPER_42 - AGPIO(GPIO_EPAPER42_CS), -#endif // USE_DISPLAY_EPAPER_42 -// REMOVED -// #ifdef USE_DISPLAY_SSD1351 -// AGPIO(GPIO_SSD1351_CS), -// AGPIO(GPIO_SSD1351_DC), -// #endif // USE_DISPLAY_SSD1351 -#ifdef USE_DISPLAY_RA8876 - AGPIO(GPIO_RA8876_CS), -#endif // USE_DISPLAY_RA8876 -// REMOVED -// #ifdef USE_DISPLAY_ST7789 -// AGPIO(GPIO_ST7789_CS), -// AGPIO(GPIO_ST7789_DC), -// #endif // USE_DISPLAY_ST7789 -// REMOVED -// #ifdef USE_DISPLAY_SSD1331 -// AGPIO(GPIO_SSD1331_CS), -// AGPIO(GPIO_SSD1331_DC), -// #endif // USE_DISPLAY_SSD1331 -#ifdef USE_DISPLAY_MAX7219_MATRIX - #undef USE_DISPLAY_MAX7219 - #undef USE_DISPLAY_TM1637 - AGPIO(GPIO_MAX7219CLK), - AGPIO(GPIO_MAX7219DIN), - AGPIO(GPIO_MAX7219CS), -#endif // USE_DISPLAY_MAX7219_MATRIX -#ifdef USE_DISPLAY_MAX7219 - AGPIO(GPIO_MAX7219CLK), - AGPIO(GPIO_MAX7219DIN), - AGPIO(GPIO_MAX7219CS), -#endif // USE_DISPLAY_MAX7219 -#ifdef USE_DISPLAY_TM1637 - AGPIO(GPIO_TM1637CLK), - AGPIO(GPIO_TM1637DIO), - AGPIO(GPIO_TM1638CLK), - AGPIO(GPIO_TM1638DIO), - AGPIO(GPIO_TM1638STB), -#endif // USE_DISPLAY_TM1637 -#ifdef USE_DISPLAY_TM1640 - AGPIO(GPIO_TM1640CLK), - AGPIO(GPIO_TM1640DIN), -#endif // USE_DISPLAY_TM1640 - AGPIO(GPIO_BACKLIGHT), // Display backlight control - AGPIO(GPIO_OLED_RESET), // OLED Display Reset -#ifdef ESP32 - AGPIO(GPIO_EPD_DATA), // Base connection EPD driver -#endif -#endif // USE_DISPLAY - -#ifdef USE_DISPLAY_TM1621_SONOFF -// Initial support outside display driver - AGPIO(GPIO_TM1621_CS), - AGPIO(GPIO_TM1621_WR), - AGPIO(GPIO_TM1621_RD), - AGPIO(GPIO_TM1621_DAT), -#endif // USE_DISPLAY_TM1621_SONOFF - -#ifdef USE_MAX31865 - AGPIO(GPIO_SSPI_MAX31865_CS1) + AGMAX(MAX_MAX31865S), -#endif - -#ifdef USE_MCP23XXX_DRV - AGPIO(GPIO_MCP23XXX_INT) + AGMAX(MAX_MCP23XXX), -#endif - -#ifdef USE_HDMI_CEC - AGPIO(GPIO_HDMI_CEC), // HDMI CEC bus -#endif - - AGPIO(GPIO_TXD), // Serial interface - AGPIO(GPIO_RXD), // Serial interface - -/*-------------------------------------------------------------------------------------------*\ - * Single wire sensors -\*-------------------------------------------------------------------------------------------*/ - -#ifdef USE_DHT - AGPIO(GPIO_DHT11), // DHT11 - AGPIO(GPIO_DHT22), // DHT21, DHT22, AM2301, AM2302, AM2321 - AGPIO(GPIO_SI7021), // iTead SI7021 - AGPIO(GPIO_MS01), // Sonoff MS01 - AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 -#endif -#ifdef USE_DS18x20 - AGPIO(GPIO_DSB) + AGMAX(MAX_DSB), // Single wire DS18B20 or DS18S20 - AGPIO(GPIO_DSB_OUT) + AGMAX(MAX_DSB), // Pseudo Single wire DS18B20 or DS18S20 -#endif // USE_DS18x20 -#ifdef USE_LMT01 - AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO -#endif - -/*-------------------------------------------------------------------------------------------*\ - * Light -\*-------------------------------------------------------------------------------------------*/ - -#ifdef USE_LIGHT -#ifdef USE_WS2812 -#if (USE_WS2812_HARDWARE == NEO_HW_P9813) - AGPIO(GPIO_P9813_CLK), // P9813 CLOCK - AGPIO(GPIO_P9813_DAT), // P9813 DATA -#else - AGPIO(GPIO_WS2812) + AGMAX(MAX_RMT), // WS2812 Led string, using RMT on ESP32 -#endif // NEO_HW_P9813 -#endif -#ifdef USE_ARILUX_RF - AGPIO(GPIO_ARIRFRCV), // AriLux RF Receive input - AGPIO(GPIO_ARIRFSEL), // Arilux RF Receive input selected -#endif -#ifdef USE_MY92X1 - AGPIO(GPIO_DI), // my92x1 PWM input - AGPIO(GPIO_DCKI), // my92x1 CLK input -#endif // USE_MY92X1 -#ifdef USE_SM16716 - AGPIO(GPIO_SM16716_CLK), // SM16716 CLOCK - AGPIO(GPIO_SM16716_DAT), // SM16716 DATA - AGPIO(GPIO_SM16716_SEL), // SM16716 SELECT -#endif // USE_SM16716 -#ifdef USE_SM2135 - AGPIO(GPIO_SM2135_CLK), // SM2135 CLOCK - AGPIO(GPIO_SM2135_DAT) + AGMAX(MAX_SM2135_DAT), // SM2135 DATA -#endif // USE_SM2135 -#ifdef USE_SM2335 - AGPIO(GPIO_SM2335_CLK), // SM2335 CLOCK - AGPIO(GPIO_SM2335_DAT) + AGMAX(MAX_SM2335_DAT), // SM2335 DATA -#endif // USE_SM2335 -#ifdef USE_BP1658CJ - AGPIO(GPIO_BP1658CJ_CLK), // BP1658CJ CLOCK - AGPIO(GPIO_BP1658CJ_DAT) + AGMAX(MAX_BP1658CJ_DAT), // BP1658CJ DATA -#endif // USE_BP1658CJ -#ifdef USE_BP5758D - AGPIO(GPIO_BP5758D_CLK), // BP5758D CLOCK - AGPIO(GPIO_BP5758D_DAT), // BP5758D DATA -#endif // USE_BP5758D -#ifdef USE_TUYA_MCU - AGPIO(GPIO_TUYA_TX), // Tuya Serial interface - AGPIO(GPIO_TUYA_RX), // Tuya Serial interface -#endif -#ifdef USE_EXS_DIMMER - AGPIO(GPIO_EXS_ENABLE), // EXS MCU Enable -#endif -#ifdef USE_ELECTRIQ_MOODL - AGPIO(GPIO_ELECTRIQ_MOODL_TX), -#endif -#ifdef USE_SHELLY_DIMMER - AGPIO(GPIO_SHELLY_DIMMER_BOOT0), - AGPIO(GPIO_SHELLY_DIMMER_RST_INV), -#endif -#endif // USE_LIGHT - -#ifdef USE_DALI - AGPIO(GPIO_DALI_TX), // DALI TX - AGPIO(GPIO_DALI_TX_INV), // DALI TX inverted - AGPIO(GPIO_DALI_RX), // DALI RX - AGPIO(GPIO_DALI_RX_INV), // DALI RX inverted -#endif // USE_DALI - -/*-------------------------------------------------------------------------------------------*\ - * Transmission sensors -\*-------------------------------------------------------------------------------------------*/ - -#if defined(USE_IR_REMOTE) || defined(USE_IR_REMOTE_FULL) - AGPIO(GPIO_IRSEND) + AGMAX(MAX_IRSEND), // IR remote -#if defined(USE_IR_RECEIVE) || defined(USE_IR_REMOTE_FULL) - AGPIO(GPIO_IRRECV), // IR receiver -#endif -#endif -#ifdef USE_RC_SWITCH - AGPIO(GPIO_RFSEND), // RF transmitter - AGPIO(GPIO_RFRECV), // RF receiver -#endif -#ifdef USE_RF_SENSOR - AGPIO(GPIO_RF_SENSOR), // Rf receiver with sensor decoding -#endif -#ifdef USE_SR04 - AGPIO(GPIO_SR04_TRIG) + AGMAX(MAX_SR04), // SR04 Tri/TXgger pin - AGPIO(GPIO_SR04_ECHO) + AGMAX(MAX_SR04), // SR04 Ech/RXo pin -#endif -#ifdef USE_ME007 - AGPIO(GPIO_ME007_TRIG), // ME007 Trigger pin (xsns_23_me007.ino) - AGPIO(GPIO_ME007_RX), // ME007 Rx pin (xsns_23_me007.ino) -#endif -#ifdef USE_TM1638 - AGPIO(GPIO_TM1638CLK), // TM1638 Clock - AGPIO(GPIO_TM1638DIO), // TM1638 Data I/O - AGPIO(GPIO_TM1638STB), // TM1638 Strobe -#endif -#ifdef USE_HX711 - AGPIO(GPIO_HX711_SCK), // HX711 Load Cell clock - AGPIO(GPIO_HX711_DAT), // HX711 Load Cell data -#endif -#ifdef USE_TFMINIPLUS - AGPIO(GPIO_TFMINIPLUS_TX), // TFmini Plus TX pin - AGPIO(GPIO_TFMINIPLUS_RX), // TFmini Plus RX pin -#endif - -/*-------------------------------------------------------------------------------------------*\ - * Energy sensors -\*-------------------------------------------------------------------------------------------*/ - -#ifdef USE_ENERGY_SENSOR -#ifdef USE_HLW8012 - AGPIO(GPIO_NRG_SEL), // HLW8012/HLJ-01 Sel output (1 = Voltage) - AGPIO(GPIO_NRG_SEL_INV), // HLW8012/HLJ-01 Sel output (0 = Voltage) - AGPIO(GPIO_NRG_CF1), // HLW8012/HLJ-01 CF1 voltage / current - AGPIO(GPIO_HLW_CF), // HLW8012 CF power - AGPIO(GPIO_HJL_CF), // HJL-01/BL0937 CF power -#endif -#if defined(USE_I2C) && defined(USE_ADE7880) - AGPIO(GPIO_ADE7880_IRQ) + AGMAX(2), // ADE7880 IRQ - (1 = IRQ1, 2 = IRQ2) -#endif -#ifdef USE_ADE7953 -#if defined(USE_I2C) || defined(USE_SPI) - AGPIO(GPIO_ADE7953_IRQ) + AGMAX(6), // ADE7953 IRQ - (1 = Shelly 2.5, 2 = Shelly EM, 3 = Shelly Plus 2PM, 4 = Shelly Pro 1PM, 5 = Shelly Pro 2PM, 6 = Shelly Pro 4PM) - AGPIO(GPIO_ADE7953_RST), // ADE7953 Reset -#ifdef USE_SPI - AGPIO(GPIO_ADE7953_CS) + AGMAX(2), // ADE7953 SPI Chip Select (1 = CS1 (1PM, 2PM), 2 = CS2 (2PM)) -#endif // USE_SPI -#endif // USE_I2C or USE_SPI -#endif // USE_ADE7953 -#ifdef USE_CSE7761 - AGPIO(GPIO_CSE7761_TX), // CSE7761 Serial interface (Dual R3) - AGPIO(GPIO_CSE7761_RX) + AGMAX(MAX_CSE7761), // CSE7761 Serial interface (1 = Dual R3, 2 = POWCT) -#endif -#ifdef USE_CSE7766 - AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2) - AGPIO(GPIO_CSE7766_RX), // CSE7766 Serial interface (S31 and Pow R2) -#endif -#ifdef USE_MCP39F501 - AGPIO(GPIO_MCP39F5_TX), // MCP39F501 Serial interface (Shelly2) - AGPIO(GPIO_MCP39F5_RX), // MCP39F501 Serial interface (Shelly2) - AGPIO(GPIO_MCP39F5_RST), // MCP39F501 Reset (Shelly2) -#endif - AGPIO(GPIO_NRG_MBS_TX_ENA), // Generic Energy Modbus Transmit Enable -#if defined(USE_PZEM004T) || defined(USE_PZEM_AC) || defined(USE_PZEM_DC) - AGPIO(GPIO_PZEM0XX_TX), // PZEM0XX Serial interface -#endif -#ifdef USE_PZEM004T - AGPIO(GPIO_PZEM004_RX), // PZEM004T Serial interface -#endif -#ifdef USE_PZEM_AC - AGPIO(GPIO_PZEM016_RX), // PZEM-014,016 Serial Modbus interface -#endif -#ifdef USE_PZEM_DC - AGPIO(GPIO_PZEM017_RX), // PZEM-003,017 Serial Modbus interface -#endif -#ifdef USE_MODBUS_ENERGY - AGPIO(GPIO_NRG_MBS_TX), // Generic Energy Modbus device - AGPIO(GPIO_NRG_MBS_RX), -#endif -#ifdef USE_SDM120 - AGPIO(GPIO_SDM120_TX), // SDM120 Serial interface - AGPIO(GPIO_SDM120_RX), // SDM120 Serial interface -#endif -#ifdef USE_SDM630 - AGPIO(GPIO_SDM630_TX), // SDM630 Serial interface - AGPIO(GPIO_SDM630_RX), // SDM630 Serial interface -#endif -#ifdef USE_DDS2382 - AGPIO(GPIO_DDS2382_TX), // DDS2382 Serial interface - AGPIO(GPIO_DDS2382_RX), // DDS2382 Serial interface -#endif -#ifdef USE_DDSU666 - AGPIO(GPIO_DDSU666_TX), // DDSU666 Serial interface - AGPIO(GPIO_DDSU666_RX), // DDSU666 Serial interface -#endif // USE_DDSU666 -#ifdef USE_SOLAX_X1 - AGPIO(GPIO_SOLAXX1_TX), // Solax Inverter tx pin - AGPIO(GPIO_SOLAXX1_RX), // Solax Inverter rx pin - AGPIO(GPIO_SOLAXX1_RTS), // Solax Inverter RTS pin -#endif // USE_SOLAX_X1 -#ifdef USE_LE01MR - AGPIO(GPIO_LE01MR_TX), // F7F LE-01MR energy meter tx pin - AGPIO(GPIO_LE01MR_RX), // F7F LE-01MR energy meter rx pin -#endif // USE_LE01MR -#ifdef ESP32 -#ifdef USE_BL0906 - AGPIO(GPIO_BL0906_RX) + AGMAX(MAX_BL0906_RX), // BL0906 Serial interface (Athom EM6) -#endif // USE_BL0906 -#endif // ESP32 -#if defined(USE_BL0940) || defined(USE_BL09XX) - AGPIO(GPIO_BL0939_RX), // BL0939 Serial interface (Dual R3 v2) - AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface - AGPIO(GPIO_BL0942_RX) + AGMAX(MAX_BL0942_RX), // BL0942 Serial interface -#endif -#ifdef USE_IEM3000 - AGPIO(GPIO_IEM3000_TX), // IEM3000 Serial interface - AGPIO(GPIO_IEM3000_RX), // IEM3000 Serial interface -#endif -#ifdef USE_WE517 - AGPIO(GPIO_WE517_TX), // WE517 Serial interface - AGPIO(GPIO_WE517_RX), // WE517 Serial interface -#endif -#ifdef USE_SDM72 - AGPIO(GPIO_SDM72_TX), // SDM72 Serial interface - AGPIO(GPIO_SDM72_RX), // SDM72 Serial interface -#endif - AGPIO(GPIO_ZEROCROSS), -#ifdef USE_SDM230 - AGPIO(GPIO_SDM230_TX), // SDM230 Serial interface - AGPIO(GPIO_SDM230_RX), // SDM230 Serial interface -#endif -#ifdef USE_BL6523 - AGPIO(GPIO_BL6523_TX), // BL6523 based Watt meter Serial interface - AGPIO(GPIO_BL6523_RX), // BL6523 based Watt meter Serial interface -#endif -#ifdef USE_V9240 - AGPIO(GPIO_V9240_TX), // Serial V9240 interface - AGPIO(GPIO_V9240_RX), // Serial V9240 interface -#endif -#ifdef USE_MAKE_SKY_BLUE - AGPIO(GPIO_MKSKYBLU_TX) + AGMAX(MAX_MKSKYBLU_IF), - AGPIO(GPIO_MKSKYBLU_RX) + AGMAX(MAX_MKSKYBLU_IF), -#endif -#endif // USE_ENERGY_SENSOR - -/*-------------------------------------------------------------------------------------------*\ - * Serial sensors -\*-------------------------------------------------------------------------------------------*/ - -#ifdef USE_SERIAL_BRIDGE - AGPIO(GPIO_SBR_TX), // Serial Bridge Serial interface - AGPIO(GPIO_SBR_RX), // Serial Bridge Serial interface -#endif -#ifdef USE_MODBUS_BRIDGE - AGPIO(GPIO_MBR_TX_ENA), // Modbus Bridge Serial interface - AGPIO(GPIO_MBR_TX), // Modbus Bridge Serial interface - AGPIO(GPIO_MBR_RX), // Modbus Bridge Serial interface -#endif -#ifdef USE_TCP_BRIDGE - AGPIO(GPIO_TCP_TX), // TCP Serial bridge - AGPIO(GPIO_TCP_RX), // TCP Serial bridge - AGPIO(GPIO_TCP_TX_EN), // TCP Serial bridge EN -#endif -#ifdef USE_ZIGBEE - AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface - AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface - AGPIO(GPIO_ZIGBEE_RST) + AGMAX(2), // Zigbee reset, pin 1 is reset, pin 2 is bootloader mode -#endif -#ifdef USE_MHZ19 - AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface - AGPIO(GPIO_MHZ_RXD), // MH-Z19 Serial interface -#endif -#ifdef USE_HC8 - AGPIO(GPIO_HC8_RXD), // HC8 Serial interface -#endif -#ifdef USE_SENSEAIR - AGPIO(GPIO_SAIR_TX), // SenseAir Serial interface - AGPIO(GPIO_SAIR_RX), // SenseAir Serial interface -#endif -#ifdef USE_NOVA_SDS - AGPIO(GPIO_SDS0X1_TX), // Nova Fitness SDS011 Serial interface - AGPIO(GPIO_SDS0X1_RX), // Nova Fitness SDS011 Serial interface -#endif -#ifdef USE_HPMA - AGPIO(GPIO_HPMA_TX), // Honeywell HPMA115S0 Serial interface - AGPIO(GPIO_HPMA_RX), // Honeywell HPMA115S0 Serial interface -#endif -#ifdef USE_PMS5003 - AGPIO(GPIO_PMS5003_TX), // Plantower PMS5003 Serial interface - AGPIO(GPIO_PMS5003_RX), // Plantower PMS5003 Serial interface -#endif -#ifdef USE_VINDRIKTNING - AGPIO(GPIO_VINDRIKTNING_RX), // Ikea Vindriktning -#endif -#ifdef USE_HM330X - AGPIO(GPIO_HM330X_SET), // HM330X Sleep pin (active low) -#endif -#if defined(USE_TX20_WIND_SENSOR) || defined(USE_TX23_WIND_SENSOR) || defined(USE_WS2300_WIND_SENSOR) - AGPIO(GPIO_TX2X_TXD_BLACK), // TX20/TX23 Transmission Pin -#endif -#ifdef USE_WINDMETER - AGPIO(GPIO_WINDMETER_SPEED), -#endif -#ifdef USE_MP3_PLAYER - AGPIO(GPIO_MP3_DFR562), // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface - AGPIO(GPIO_MP3_DFR562_BUSY), // RB-DFR-562, DFPlayer Mini MP3 Player optional Busy flag - #endif -#ifdef USE_AZ7798 - AGPIO(GPIO_AZ_TXD), // AZ-Instrument 7798 CO2 datalogger Serial interface - AGPIO(GPIO_AZ_RXD), // AZ-Instrument 7798 CO2 datalogger Serial interface -#endif -#ifdef USE_PN532_HSU - AGPIO(GPIO_PN532_TXD), // PN532 HSU Tx - AGPIO(GPIO_PN532_RXD), // PN532 HSU Rx -#endif -#ifdef USE_TASMOTA_CLIENT - AGPIO(GPIO_TASMOTACLIENT_TXD), // Tasmota Client TX - AGPIO(GPIO_TASMOTACLIENT_RXD), // Tasmota Client RX - AGPIO(GPIO_TASMOTACLIENT_RST), // Tasmota Client Reset - AGPIO(GPIO_TASMOTACLIENT_RST_INV), // Tasmota Client Reset Inverted -#endif -#ifdef USE_RDM6300 - AGPIO(GPIO_RDM6300_RX), -#endif -#ifdef USE_IBEACON - AGPIO(GPIO_IBEACON_TX), - AGPIO(GPIO_IBEACON_RX), -#endif -#ifdef USE_GPS - AGPIO(GPIO_GPS_TX), // GPS serial interface - AGPIO(GPIO_GPS_RX) + AGMAX(MAX_GPS_RX), // GPS serial interface -#endif -#ifdef USE_HM10 - AGPIO(GPIO_HM10_TX), // HM10 serial interface - AGPIO(GPIO_HM10_RX), // HM10 serial interface -#endif -#ifdef USE_OPENTHERM - AGPIO(GPIO_BOILER_OT_TX), - AGPIO(GPIO_BOILER_OT_RX), -#endif -#ifdef USE_AS608 - AGPIO(GPIO_AS608_TX), - AGPIO(GPIO_AS608_RX), -#endif -#ifdef USE_GM861 - AGPIO(GPIO_GM861_TX), - AGPIO(GPIO_GM861_RX), -#endif -#ifdef USE_HRG15 - AGPIO(GPIO_HRG15_TX), - AGPIO(GPIO_HRG15_RX), -#endif -#ifdef USE_CM110x - AGPIO(GPIO_CM11_TXD), // CM110x Serial interface - AGPIO(GPIO_CM11_RXD), // CM110x Serial interface -#endif -#ifdef USE_LD2402 - AGPIO(GPIO_LD2402_TX), // HLK-LD2402 Serial interface - AGPIO(GPIO_LD2402_RX), // HLK-LD2402 Serial interface -#endif -#ifdef USE_LD2410 - AGPIO(GPIO_LD2410_TX), // HLK-LD2410 Serial interface - AGPIO(GPIO_LD2410_RX), // HLK-LD2410 Serial interface -#endif -#ifdef USE_LD2410S - AGPIO(GPIO_LD2410S_TX), // HLK-LD2410S Serial interface - AGPIO(GPIO_LD2410S_RX), // HLK-LD2410S Serial interface -#endif -#ifdef USE_LOX_O2 - AGPIO(GPIO_LOX_O2_RX), // LuminOx Oxygen Sensor LOX-O2 Serial interface -#endif -#ifdef USE_LORAWAN_RN2XX3 - AGPIO(GPIO_RN2XX3_TX), - AGPIO(GPIO_RN2XX3_RX), - AGPIO(GPIO_RN2XX3_RST), // RN2XX3 LoRaWan node Serial interface -#endif -#ifdef USE_LORAWAN_ASR650X - AGPIO(GPIO_ASR650X_TX), - AGPIO(GPIO_ASR650X_RX), // ASR650X LoRaWan node Serial interface -#endif -#ifdef USE_WOOLIIS - AGPIO(GPIO_WOOLIIS_RX), // Wooliis Battery capacity monitor Serial interface -#endif -#ifdef USE_C8_CO2_5K - AGPIO(GPIO_C8_CO2_5K_TX), // SC8-CO2-5K Serial interface - AGPIO(GPIO_C8_CO2_5K_RX), // SC8-CO2-5K Serial interface -#endif - -#ifdef ESP32 -#ifdef USE_ESP32_TWAI -#if SOC_TWAI_SUPPORTED - AGPIO(GPIO_TWAI_TX) + AGMAX(MAX_TWAI), // ESP32 TWAI serial interface - AGPIO(GPIO_TWAI_RX) + AGMAX(MAX_TWAI), - AGPIO(GPIO_TWAI_BO) + AGMAX(MAX_TWAI), - AGPIO(GPIO_TWAI_CLK) + AGMAX(MAX_TWAI), -#endif -#endif -#endif - -/*-------------------------------------------------------------------------------------------*\ - * Other sensors -\*-------------------------------------------------------------------------------------------*/ - -#ifdef USE_MGC3130 - AGPIO(GPIO_MGC3130_XFER), - AGPIO(GPIO_MGC3130_RESET), -#endif -#ifdef USE_MAX31855 - AGPIO(GPIO_MAX31855CS) + AGMAX(MAX_MAX31855S), // MAX31855 Serial interface - AGPIO(GPIO_MAX31855CLK), // MAX31855 Serial interface - AGPIO(GPIO_MAX31855DO), // MAX31855 Serial interface -#endif -#ifdef USE_HRE - AGPIO(GPIO_HRE_CLOCK), - AGPIO(GPIO_HRE_DATA), -#endif -#ifdef USE_A4988_STEPPER - AGPIO(GPIO_A4988_DIR), // A4988 direction pin - AGPIO(GPIO_A4988_STP), // A4988 step pin - // folowing are not mandatory - AGPIO(GPIO_A4988_ENA), // A4988 enabled pin - AGPIO(GPIO_A4988_MS1) + AGMAX(MAX_A4988_MSS), // A4988 microstep pin1 to pin3 -#endif -#ifdef USE_DEEPSLEEP - AGPIO(GPIO_DEEPSLEEP), -#endif -#ifdef USE_KEELOQ - AGPIO(GPIO_CC1101_GDO0), // CC1101 pin for RX - AGPIO(GPIO_CC1101_GDO2), // CC1101 pin for RX -#endif -#ifdef USE_HRXL - AGPIO(GPIO_HRXL_RX), -#endif -#ifdef USE_DYP - AGPIO(GPIO_DYP_RX), -#endif -#ifdef USE_AS3935 - AGPIO(GPIO_AS3935), // AS3935 IRQ Pin -#endif -#ifdef USE_TELEINFO - AGPIO(GPIO_TELEINFO_RX), - AGPIO(GPIO_TELEINFO_ENABLE), -#endif -#ifdef USE_MIEL_HVAC - AGPIO(GPIO_MIEL_HVAC_TX), // Mitsubishi Electric HVAC TX pin - AGPIO(GPIO_MIEL_HVAC_RX), // Mitsubishi Electric HVAC RX pin -#endif -#ifdef USE_TUYAMCUBR - AGPIO(GPIO_TUYAMCUBR_TX), - AGPIO(GPIO_TUYAMCUBR_RX), -#endif -#ifdef USE_WIEGAND - AGPIO(GPIO_WIEGAND_D0), // Data line D0 of Wiegand devices - AGPIO(GPIO_WIEGAND_D1), // Data line D1 of Wiegand devices -#endif -#ifdef USE_NEOPOOL - AGPIO(GPIO_NEOPOOL_TX), // Sugar Valley RS485 Interface - AGPIO(GPIO_NEOPOOL_RX), // Sugar Valley RS485 Interface -#endif -#ifdef USE_PROJECTOR_CTRL - AGPIO(GPIO_PROJECTOR_CTRL_TX), // LCD/DLP Projector Serial Control - AGPIO(GPIO_PROJECTOR_CTRL_RX), // LCD/DLP Projector Serial Control -#endif -#if defined(USE_VL53L0X) or defined (USE_VL53L1X) - AGPIO(GPIO_VL53LXX_XSHUT1) + AGMAX(VL53LXX_MAX_SENSORS), // When using multiple VL53LXX. -#endif -#ifdef USE_FLOWRATEMETER - AGPIO(GPIO_FLOWRATEMETER_IN) + AGMAX(MAX_FLOWRATEMETER), // Flow meter Pin -#endif - -#ifdef USE_SHIFT595 - AGPIO(GPIO_SHIFT595_SRCLK), // 74x595 shift register - AGPIO(GPIO_SHIFT595_RCLK), - AGPIO(GPIO_SHIFT595_OE), - AGPIO(GPIO_SHIFT595_SER), -#endif - -#if defined (ESP32) && defined(USE_DINGTIAN_RELAY) - AGPIO(GPIO_DINGTIAN_CLK) + AGMAX(MAX_DINGTIAN_SHIFT), // Dingtian Relay board - 8,16,24 or 32 relays & inputs - AGPIO(GPIO_DINGTIAN_SDI), - AGPIO(GPIO_DINGTIAN_Q7), - AGPIO(GPIO_DINGTIAN_PL), - AGPIO(GPIO_DINGTIAN_OE), - AGPIO(GPIO_DINGTIAN_RCK), -#endif - -#ifdef USE_MAGIC_SWITCH - AGPIO(GPIO_MAGIC_SWITCH) + AGMAX(MAX_MAGIC_SWITCH_MODES), -#endif - -#ifdef USE_PIPSOLAR - AGPIO(GPIO_PIPSOLAR_TX), // pipsolar inverter Serial interface - AGPIO(GPIO_PIPSOLAR_RX), // pipsolar inverter Serial interface -#endif - -/*-------------------------------------------------------------------------------------------*\ - * ESP32 specifics -\*-------------------------------------------------------------------------------------------*/ - -#ifdef ESP32 -#if CONFIG_IDF_TARGET_ESP32 - AGPIO(GPIO_HALLEFFECT) + AGMAX(2), // Hall effect sensor connected to GPIO36 and 39 -#endif // CONFIG_IDF_TARGET_ESP32 -#ifdef USE_WEBCAM - AGPIO(GPIO_WEBCAM_PWDN), - AGPIO(GPIO_WEBCAM_RESET), - AGPIO(GPIO_WEBCAM_XCLK), - AGPIO(GPIO_WEBCAM_SIOD), - AGPIO(GPIO_WEBCAM_SIOC), - AGPIO(GPIO_WEBCAM_DATA) + AGMAX(MAX_WEBCAM_DATA), - AGPIO(GPIO_WEBCAM_VSYNC), - AGPIO(GPIO_WEBCAM_HREF), - AGPIO(GPIO_WEBCAM_PCLK), - AGPIO(GPIO_WEBCAM_PSCLK), - AGPIO(GPIO_WEBCAM_HSD) + AGMAX(MAX_WEBCAM_HSD), - AGPIO(GPIO_WEBCAM_PSRCS), -#endif // USE_WEBCAM -#ifdef USE_ETHERNET - AGPIO(GPIO_ETH_PHY_POWER), - AGPIO(GPIO_ETH_PHY_MDC) + AGMAX(MAX_SPI), - AGPIO(GPIO_ETH_PHY_MDIO), // Ethernet -#endif // USE_ETHERNET -#ifdef USE_BIOPDU - AGPIO(GPIO_BIOPDU_PZEM0XX_TX), // Biomine BioPDU pins - AGPIO(GPIO_BIOPDU_PZEM016_RX), - AGPIO(GPIO_BIOPDU_BIT) + AGMAX(3), -#endif -#ifdef CONFIG_ESP_WIFI_REMOTE_ENABLED - AGPIO(GPIO_HSDIO_CMD), // Hosted MCU SDIO interface, including 1-bit and 4-bit modes - AGPIO(GPIO_HSDIO_CLK), - AGPIO(GPIO_HSDIO_RST), - AGPIO(GPIO_HSDIO_D0), - AGPIO(GPIO_HSDIO_D1), - AGPIO(GPIO_HSDIO_D2), - AGPIO(GPIO_HSDIO_D3), -#endif // CONFIG_ESP_WIFI_REMOTE_ENABLED - -/*-------------------------------------------------------------------------------------------*\ - * ESP32 multiple Analog / Digital converter inputs -\*-------------------------------------------------------------------------------------------*/ - - AGPIO(GPIO_ADC_INPUT) + AGMAX(MAX_ADCS), // Analog inputs - AGPIO(GPIO_ADC_TEMP) + AGMAX(MAX_ADCS), // Thermistor - AGPIO(GPIO_ADC_LIGHT) + AGMAX(MAX_ADCS), // Light sensor - AGPIO(GPIO_ADC_BUTTON) + AGMAX(MAX_KEYS), // Button - AGPIO(GPIO_ADC_BUTTON_INV) + AGMAX(MAX_KEYS), - AGPIO(GPIO_ADC_RANGE) + AGMAX(MAX_ADCS), // Range - AGPIO(GPIO_ADC_CT_POWER) + AGMAX(MAX_ADCS), // Current - AGPIO(GPIO_ADC_JOY) + AGMAX(MAX_ADCS), // Joystick - AGPIO(GPIO_ADC_PH) + AGMAX(MAX_ADCS), // Analog PH Sensor - AGPIO(GPIO_ADC_MQ) + AGMAX(MAX_ADCS), // Analog MQ Sensor - AGPIO(GPIO_ADC_VOLTAGE) + AGMAX(MAX_ADCS), // Voltage - AGPIO(GPIO_ADC_CURRENT) + AGMAX(MAX_ADCS), // Current -#endif // ESP32 - - -#ifdef USE_VID6608 - AGPIO(GPIO_VID6608_F) + AGMAX(4), // VID6608 step interface (max 4 motors) - AGPIO(GPIO_VID6608_CW) + AGMAX(4), // VID6608 direction interface (max 4 motors) -#endif - -}; - -/*-------------------------------------------------------------------------------------------*\ - * ESP8266 single Analog / Digital converter input -\*-------------------------------------------------------------------------------------------*/ - -#ifdef ESP8266 -const uint16_t kAdcNiceList[] PROGMEM = { - GPIO_NONE, // Not used - AGPIO(GPIO_ADC_INPUT), // Analog inputs - AGPIO(GPIO_ADC_TEMP), // Thermistor - AGPIO(GPIO_ADC_LIGHT), // Light sensor - AGPIO(GPIO_ADC_BUTTON) + AGMAX(MAX_KEYS), // Button - AGPIO(GPIO_ADC_BUTTON_INV) + AGMAX(MAX_KEYS), - AGPIO(GPIO_ADC_RANGE), // Range - AGPIO(GPIO_ADC_CT_POWER), // Current - AGPIO(GPIO_ADC_JOY), // Joystick - AGPIO(GPIO_ADC_PH), // Analog PH Sensor - AGPIO(GPIO_ADC_MQ), // Analog MQ Sensor - AGPIO(GPIO_ADC_VOLTAGE), // Voltage - AGPIO(GPIO_ADC_CURRENT), // Current -}; -#endif // ESP8266 - -/*********************************************************************************************\ - * ATTENTION: No user changeable features beyond this point - do not add templates !!! -\*********************************************************************************************/ - -#define GPIO_ANY 32 // Any GPIO - -#ifdef ESP8266 - -#define MAX_GPI8_PIN 17 // Number of supported GPIO (0..16) -#define FLASH_PINS 6 // Number of flash chip pins - -#define MAX_GPIO_PIN 18 // Number of supported GPIO (0..16 + ADC0) -#define ADC0_PIN 17 // Pin number of ADC0 -#define MIN_FLASH_PINS 4 // Number of flash chip pins unusable for configuration (GPIO6, 7, 8 and 11) -#define MAX_USER_PINS 14 // MAX_GPIO_PIN - MIN_FLASH_PINS -#define WEMOS_MODULE 17 // Wemos module - -const char PINS_WEMOS[] PROGMEM = "D3TXD4RXD2D1flashcFLFLolD6D7D5D8D0A0"; - -typedef struct MYIO8 { - uint8_t io[MAX_GPI8_PIN]; -} myio8; // 17 bytes - -typedef struct MYCFGIO8285 { - uint8_t io[MAX_GPI8_PIN - MIN_FLASH_PINS]; -} mycfgio8285; // 13 bytes - -typedef struct MYTMPLT8285 { - mycfgio8285 gp; - uint8_t flag; -} mytmplt8285; // 14 bytes - -typedef struct MYCFGIO8266 { - uint8_t io[MAX_GPI8_PIN - FLASH_PINS]; -} mycfgio8266; // 11 bytes - -typedef struct MYTMPLT8266 { - mycfgio8266 gp; - uint8_t flag; -} mytmplt8266; // 12 bytes - -#endif // ESP8266 - -#ifdef ESP32 -#if CONFIG_IDF_TARGET_ESP32C2 - -/* **************************************** - * ESP32C2 - * ****************************************/ -#define MAX_GPIO_PIN 21 // Number of supported GPIO -#define MIN_FLASH_PINS 0 // Number of flash chip pins unusable for configuration (GPIO11 to 17) -#define MAX_USER_PINS 21 // MAX_GPIO_PIN - MIN_FLASH_PINS -#define WEMOS_MODULE 0 // Wemos module - -// 0 1 2 3 4 5 6 7 8 91011121314151617181920 -const char PINS_WEMOS[] PROGMEM = "AOAOAOAOAOIOIOIOIOIOIOFLFLFLFLFLFLFLIORXTX"; - -#elif CONFIG_IDF_TARGET_ESP32C3 - -/* **************************************** - * ESP32C3 - * ****************************************/ -#define MAX_GPIO_PIN 22 // Number of supported GPIO -#define MIN_FLASH_PINS 0 // Number of flash chip pins unusable for configuration (GPIO11 to 17) -#define MAX_USER_PINS 22 // MAX_GPIO_PIN - MIN_FLASH_PINS -#define WEMOS_MODULE 0 // Wemos module - -// 0 1 2 3 4 5 6 7 8 9101112131415161718192021 -const char PINS_WEMOS[] PROGMEM = "AOAOAOAOAOAOIOIOIOIOIOFLFLFLFLFLFLFLIOIORXTX"; - -#elif CONFIG_IDF_TARGET_ESP32C5 // ESP32-C5 -/* **************************************** - * ESP32C5 - * ****************************************/ -#define MAX_GPIO_PIN 29 // Number of supported GPIO -#define MIN_FLASH_PINS 0 // Number of flash chip pins unusable for configuration (GPIO16-22 SPI0/1) -#define MAX_USER_PINS 29 // MAX_GPIO_PIN - MIN_FLASH_PINS -#define WEMOS_MODULE 0 // Wemos module - -// 0 1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829 -const char PINS_WEMOS[] PROGMEM = "IOAOAOAOAOAOAOIOIOIOIOIOIOIOFLFLFLFLFLFLFLIOIOIOIOIOIOIOIOIO"; - -#elif CONFIG_IDF_TARGET_ESP32C6 - -/* **************************************** - * ESP32C6 - * ****************************************/ -#define MAX_GPIO_PIN 31 // Number of supported GPIO -#define MIN_FLASH_PINS 0 // Number of flash chip pins unusable for configuration (GPIO24 to 30) -#define MAX_USER_PINS 31 // MAX_GPIO_PIN - MIN_FLASH_PINS -#define WEMOS_MODULE 0 // Wemos module - -// 0 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930 -const char PINS_WEMOS[] PROGMEM = "AOAOAOAOAOAOAOIOIOIOIOIOIOIOIOIOTXRXIOIOIOIOIOIOFLFLFLFLFLFLFL"; - -#elif CONFIG_IDF_TARGET_ESP32S2 - -/* **************************************** - * ESP32S2 - * ****************************************/ -#define MAX_GPIO_PIN 47 // Number of supported GPIO -#define MIN_FLASH_PINS 11 // Number of flash chip pins unusable for configuration (22-25 don't exist, 26-32 for SPI) -#define MAX_USER_PINS 36 // MAX_GPIO_PIN - MIN_FLASH_PINS -#define WEMOS_MODULE 0 // Wemos module - -// 0 1 2 3 4 5 6 7 8 910111213141516171819202122232425262728293031323334353637383940414243444546 -const char PINS_WEMOS[] PROGMEM = "IOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOIO--------FLFLFLFLFLFLFLIOIOIOIOIOIOIOIOIOIOIOIOIOI "; - -#elif CONFIG_IDF_TARGET_ESP32S3 -/* **************************************** - * ESP32S3 - * GPIOs 0..21 + 33..48 - * - 22..25 are not used - * - 26..32 are used for SPI Flash - * - 33..37 are used by PSRAM - * ****************************************/ -#define MAX_GPIO_PIN 49 // Number of supported GPIO, 0..48 -#define MIN_FLASH_PINS 11 // Number of flash chip pins unusable for configuration (22-25 don't exist, 26-32 for SPI) -#define MAX_USER_PINS 38 // MAX_GPIO_PIN - MIN_FLASH_PINS -#define WEMOS_MODULE 0 // Wemos module - -// 0 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445464748 -const char PINS_WEMOS[] PROGMEM = "IOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOIO--------FLFLFLFLFLFLFLIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIO"; - -#elif CONFIG_IDF_TARGET_ESP32P4 -/* **************************************** - * ESP32P4 - * GPIOs 0..54 - * - 34..38 strapping pins - * ****************************************/ -#define MAX_GPIO_PIN 55 // Number of supported GPIO, 0..55 -#define MIN_FLASH_PINS 00 // Number of flash chip pins unusable for configuration (22-25 don't exist, 26-32 for SPI) -#define MAX_USER_PINS 55 // MAX_GPIO_PIN - MIN_FLASH_PINS -#define WEMOS_MODULE 0 // Wemos module - -// 0 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 -const char PINS_WEMOS[] PROGMEM = "IOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOAOAOAOAOAOAOAOAOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOAOAOAOAOAOAO"; - -#else // not CONFIG_IDF_TARGET_ESP32C2/C3/C6 nor CONFIG_IDF_TARGET_ESP32S2 - ESP32 - -/* **************************************** - * ESP32 - including Pico - * - * The initial template was 0-5 9-10 12-39 - * New template covers 0-27 32-39 - * However to maintain backwards compatibility, the following mapping occures - * Template GPIO | Phyiscal GPIO - * 28 | 6 - * 29 | 7 - * 30 | 8 - * 31 | 11 - * ****************************************/ -// Conversion table -#define ESP32_TEMPLATE_TO_PHY \ - 0, 1, 2, 3, 4, 5, \ - 9, 10, \ - 12, 13, 14, 15, 16, 17, 18, 19, \ - 20, 21, 22, 23, 24, 25, 26, 27, \ - 6, 7, 8, 11, /* 28-31 */ \ - 32, 33, 34, 35, 36, 37, 38, 39 - -#define MAX_GPIO_PIN 40 // Number of supported GPIO -#define MIN_FLASH_PINS 4 // Number of flash chip pins unusable for configuration (GPIO6, 7, 8 and 11) -#define MAX_USER_PINS 36 // MAX_GPIO_PIN - MIN_FLASH_PINS -#define WEMOS_MODULE 0 // Wemos module - -// 0 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839 -const char PINS_WEMOS[] PROGMEM = "IOTXIORXIOIOFLFLFLFLFLFLIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIO--------AOAOIAIAIAIAIAIA"; - -#endif // ESP32/S2/C2/C3/C6/P4 selection -#endif // ESP32 - -/********************************************************************************************\ - * !!! Changes in below type sizes impact Settings layout - Add fill bytes in Settings !!! -\********************************************************************************************/ - -typedef struct MYIO { - uint16_t io[MAX_GPIO_PIN]; -} myio; // ESP8266: 18*2 = 36 bytes / ESP32: 40*2 = 80 bytes / ESP32-C3: 22*2 = 44 bytes / ESP32-S2: 47*2 = 94 bytes / ESP32-S3: 49*2 = 98 bytes - -typedef struct MYCFGIO { - uint16_t io[MAX_USER_PINS]; -} mycfgio; // ESP8266: 14*2 = 28 bytes / ESP32: 36*2 = 72 bytes / ESP32-C3: 22*2 = 44 bytes / ESP32-S2: 36*2 = 72 bytes / ESP32-S3: 33*2 = 66 bytes - -#define GPIO_FLAG_USED 0 // Currently no flags used - -typedef union { - uint16_t data; - struct { - uint16_t spare00 : 1; - uint16_t spare01 : 1; - uint16_t spare02 : 1; - uint16_t spare03 : 1; - uint16_t spare04 : 1; - uint16_t spare05 : 1; - uint16_t spare06 : 1; - uint16_t spare07 : 1; - uint16_t spare08 : 1; - uint16_t spare09 : 1; - uint16_t spare10 : 1; - uint16_t spare11 : 1; - uint16_t spare12 : 1; - uint16_t spare13 : 1; - uint16_t spare14 : 1; - uint16_t spare15 : 1; - }; -} gpio_flag; // 2 bytes - -typedef struct MYTMPLT { - mycfgio gp; // 28 / 72 / 44 / 72 bytes - gpio_flag flag; // 2 bytes -} mytmplt; // 30 / 74 / 46 / 74 bytes - -//******************************************************************************************** - -#ifdef ESP8266 -#include "include/tasmota_template_legacy.h" - -/********************************************************************************************\ - * ESP8266 Module Templates -\********************************************************************************************/ - -#define USER_MODULE 255 - -// Supported ESP8266 hardware modules -enum SupportedModulesESP8266 { - SONOFF_BASIC, SONOFF_RF, SONOFF_SV, SONOFF_TH, SONOFF_DUAL, SONOFF_POW, SONOFF_4CH, SONOFF_S2X, SLAMPHER, SONOFF_TOUCH, - SONOFF_LED, CH1, CH4, MOTOR, ELECTRODRAGON, EXS_RELAY, WION, WEMOS, SONOFF_DEV, H801, - SONOFF_SC, SONOFF_BN, SONOFF_4CHPRO, HUAFAN_SS, SONOFF_BRIDGE, SONOFF_B1, AILIGHT, SONOFF_T11, SONOFF_T12, SONOFF_T13, - SUPLA1, WITTY, YUNSHAN, MAGICHOME, LUANIHVIO, KMC_70011, ARILUX_LC01, ARILUX_LC11, SONOFF_DUAL_R2, ARILUX_LC06, - SONOFF_S31, ZENGGE_ZF_WF017, SONOFF_POW_R2, SONOFF_IFAN02, BLITZWOLF_BWSHP, SHELLY1, SHELLY2, PHILIPS, NEO_COOLCAM, ESP_SWITCH, - OBI, TECKIN, APLIC_WDP303075, TUYA_DIMMER, GOSUND, ARMTRONIX_DIMMERS, SK03_TUYA, PS_16_DZ, TECKIN_US, MANZOKU_EU_4, - OBI2, YTF_IR_BRIDGE, DIGOO, KA10, ZX2820, MI_DESK_LAMP, SP10, WAGA, SYF05, SONOFF_L1, - SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1, SONOFF_ZB_BRIDGE, - MAXMODULE }; - -const char kModuleNames[] PROGMEM = - "Sonoff Basic|Sonoff RF|Sonoff SV|Sonoff TH|Sonoff Dual|Sonoff Pow|Sonoff 4CH|Sonoff S2X|Slampher|Sonoff Touch|" - "Sonoff LED|1 Channel|4 Channel|Motor C/AC|ElectroDragon|EXS Relay(s)|WiOn|Generic|Sonoff Dev|H801|" - "Sonoff SC|Sonoff BN-SZ|Sonoff 4CH Pro|Huafan SS|Sonoff Bridge|Sonoff B1|AiLight|Sonoff T1 1CH|Sonoff T1 2CH|Sonoff T1 3CH|" - "Supla Espablo|Witty Cloud|Yunshan Relay|MagicHome|Luani HVIO|KMC 70011|Arilux LC01|Arilux LC11|Sonoff Dual R2|Arilux LC06|" - "Sonoff S31|Zengge WF017|Sonoff Pow R2|Sonoff iFan02|BlitzWolf SHP|Shelly 1|Shelly 2|Xiaomi Philips|Neo Coolcam|ESP Switch|" - "OBI Socket|Teckin|AplicWDP303075|Tuya MCU|Gosund SP1 v23|ARMTR Dimmer|SK03 Outdoor|PS-16-DZ|Teckin US|Manzoku strip|" - "OBI Socket 2|YTF IR Bridge|Digoo DG-SP202|KA10|Luminea ZX2820|Mi Desk Lamp|SP10|WAGA CHCZ02MB|SYF05|Sonoff L1|" - "Sonoff iFan03|EXS Dimmer|PWM Dimmer|Sonoff D1|Sonoff ZbBridge" - ; - -const uint8_t kModuleNiceList[] PROGMEM = { - SONOFF_BASIC, // Sonoff Relay Devices - SONOFF_RF, - SONOFF_TH, - SONOFF_DUAL, - SONOFF_DUAL_R2, - SONOFF_POW, - SONOFF_POW_R2, - SONOFF_4CH, - SONOFF_4CHPRO, - SONOFF_S31, // Sonoff Socket Relay Devices with Energy Monitoring - SONOFF_S2X, // Sonoff Socket Relay Devices - SONOFF_TOUCH, // Sonoff Switch Devices - SONOFF_T11, - SONOFF_T12, - SONOFF_T13, -#ifdef USE_SONOFF_D1 - SONOFF_D1, // Sonoff D1 -#endif - SONOFF_LED, // Sonoff Light Devices - SONOFF_BN, -#ifdef USE_SONOFF_L1 - SONOFF_L1, -#endif - SONOFF_B1, // Sonoff Light Bulbs - SLAMPHER, -#ifdef USE_SONOFF_SC - SONOFF_SC, // Sonoff Environmemtal Sensor -#endif -#ifdef USE_SONOFF_IFAN - SONOFF_IFAN02, // Sonoff Fan - SONOFF_IFAN03, -#endif -#ifdef USE_SONOFF_RF - SONOFF_BRIDGE, // Sonoff Bridge -#endif -#ifdef USE_ZIGBEE_EZSP - SONOFF_ZB_BRIDGE, -#endif - SONOFF_SV, // Sonoff Development Devices - SONOFF_DEV, - CH1, // Relay Devices - CH4, - MOTOR, - ELECTRODRAGON, - EXS_RELAY, - SUPLA1, - LUANIHVIO, - YUNSHAN, - WION, - SHELLY1, - SHELLY2, - BLITZWOLF_BWSHP, // Socket Relay Devices with Energy Monitoring - TECKIN, - TECKIN_US, - APLIC_WDP303075, - GOSUND, - ZX2820, - SK03_TUYA, - DIGOO, - KA10, - SP10, - WAGA, - NEO_COOLCAM, // Socket Relay Devices - OBI, - OBI2, - MANZOKU_EU_4, - ESP_SWITCH, // Switch Devices -#ifdef USE_TUYA_MCU - TUYA_DIMMER, // Dimmer Devices -#endif -#ifdef USE_ARMTRONIX_DIMMERS - ARMTRONIX_DIMMERS, -#endif -#ifdef USE_PS_16_DZ - PS_16_DZ, -#endif -#ifdef USE_EXS_DIMMER - EXS_DIMMER, -#endif -#ifdef USE_PWM_DIMMER - PWM_DIMMER, -#endif - H801, // Light Devices - MAGICHOME, - ARILUX_LC01, - ARILUX_LC06, - ARILUX_LC11, - ZENGGE_ZF_WF017, - HUAFAN_SS, -#ifdef ROTARY_V1 - MI_DESK_LAMP, -#endif - KMC_70011, - AILIGHT, // Light Bulbs - PHILIPS, - SYF05, - YTF_IR_BRIDGE, - WITTY, // Development Devices - WEMOS -}; - -enum SupportedTemplates8285 { - TMP_SONOFF_BASIC, TMP_SONOFF_SV, TMP_SONOFF_DUAL, TMP_SONOFF_POW, TMP_SONOFF_LED, TMP_ELECTRODRAGON, - TMP_EXS_RELAY, TMP_WION, TMP_SONOFF_DEV, TMP_H801, TMP_SONOFF_SC, TMP_SONOFF_BN, TMP_HUAFAN_SS, TMP_SONOFF_BRIDGE, - TMP_SONOFF_B1, TMP_AILIGHT, TMP_SONOFF_T11, TMP_SUPLA1, TMP_WITTY, TMP_YUNSHAN, TMP_MAGICHOME, - TMP_LUANIHVIO, TMP_KMC_70011, TMP_ARILUX_LC01, TMP_ARILUX_LC11, TMP_ARILUX_LC06, TMP_ZENGGE_ZF_WF017, - TMP_SONOFF_POW_R2, TMP_BLITZWOLF_BWSHP, TMP_SHELLY1, TMP_SHELLY2, TMP_PHILIPS, TMP_NEO_COOLCAM, TMP_ESP_SWITCH, TMP_OBI, - TMP_TECKIN, TMP_APLIC_WDP303075, TMP_TUYA_DIMMER, TMP_GOSUND, TMP_ARMTRONIX_DIMMERS, TMP_SK03_TUYA, TMP_PS_16_DZ, - TMP_TECKIN_US, TMP_MANZOKU_EU_4, TMP_OBI2, TMP_YTF_IR_BRIDGE, TMP_DIGOO, TMP_KA10, TMP_ZX2820, TMP_MI_DESK_LAMP, TMP_SP10, - TMP_WAGA, TMP_SYF05, TMP_EXS_DIMMER, TMP_PWM_DIMMER, TMP_SONOFF_ZB_BRIDGE, - TMP_MAXMODULE_8285 }; - -enum SupportedTemplates8266 { - TMP_WEMOS = TMP_MAXMODULE_8285, TMP_SONOFF_4CH, TMP_SONOFF_T12, TMP_SONOFF_T13, TMP_SONOFF_DUAL_R2, TMP_SONOFF_IFAN03, - TMP_MAXMODULE_8266 }; - -const uint8_t kModuleTemplateList[MAXMODULE] PROGMEM = { - TMP_SONOFF_BASIC, - TMP_SONOFF_BASIC, // SONOFF_RF - TMP_SONOFF_SV, - TMP_SONOFF_BASIC, // SONOFF_TH - TMP_SONOFF_DUAL, - TMP_SONOFF_POW, - TMP_SONOFF_4CH, - TMP_SONOFF_BASIC, // SONOFF_S2X - TMP_SONOFF_BASIC, // SLAMPHER - TMP_SONOFF_T11, // SONOFF_TOUCH - TMP_SONOFF_LED, - TMP_SONOFF_BASIC, // CH1 - TMP_SONOFF_DUAL, // CH4 - TMP_SONOFF_BASIC, // MOTOR - TMP_ELECTRODRAGON, - TMP_EXS_RELAY, - TMP_WION, - TMP_WEMOS, - TMP_SONOFF_DEV, - TMP_H801, - TMP_SONOFF_SC, - TMP_SONOFF_BN, - TMP_SONOFF_4CH, // SONOFF_4CHPRO - TMP_HUAFAN_SS, - TMP_SONOFF_BRIDGE, - TMP_SONOFF_B1, - TMP_AILIGHT, - TMP_SONOFF_T11, - TMP_SONOFF_T12, - TMP_SONOFF_T13, - TMP_SUPLA1, - TMP_WITTY, - TMP_YUNSHAN, - TMP_MAGICHOME, - TMP_LUANIHVIO, - TMP_KMC_70011, - TMP_ARILUX_LC01, - TMP_ARILUX_LC11, - TMP_SONOFF_DUAL_R2, - TMP_ARILUX_LC06, - TMP_SONOFF_POW_R2, // SONOFF_S31 - TMP_ZENGGE_ZF_WF017, - TMP_SONOFF_POW_R2, - TMP_SONOFF_4CH, // SONOFF_IFAN02 - TMP_BLITZWOLF_BWSHP, - TMP_SHELLY1, - TMP_SHELLY2, - TMP_PHILIPS, - TMP_NEO_COOLCAM, - TMP_ESP_SWITCH, - TMP_OBI, - TMP_TECKIN, - TMP_APLIC_WDP303075, - TMP_TUYA_DIMMER, - TMP_GOSUND, - TMP_ARMTRONIX_DIMMERS, - TMP_SK03_TUYA, - TMP_PS_16_DZ, - TMP_TECKIN_US, - TMP_MANZOKU_EU_4, - TMP_OBI2, - TMP_YTF_IR_BRIDGE, - TMP_DIGOO, - TMP_KA10, - TMP_ZX2820, - TMP_MI_DESK_LAMP, - TMP_SP10, - TMP_WAGA, - TMP_SYF05, - TMP_SONOFF_DUAL, // SONOFF_L1 - TMP_SONOFF_IFAN03, - TMP_EXS_DIMMER, - TMP_PWM_DIMMER, - TMP_SONOFF_DUAL, // SONOFF_D1 - TMP_SONOFF_ZB_BRIDGE, - }; - -/*********************************************************************************************\ - * Templates with 12 usable pins (ESP8266) -\*********************************************************************************************/ - -const mytmplt8266 kModules8266[TMP_MAXMODULE_8285] PROGMEM = { - { // SONOFF_BASIC - Sonoff Basic (ESP8266) - GPI8_KEY1, // GPIO00 Button - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - GPI8_USER, // GPIO02 Only available on newer Sonoff Basic R2 V1 - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - GPI8_USER, // GPIO04 Optional sensor - 0, // GPIO05 - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On) - GPI8_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off) - Link and Power status - GPI8_USER, // GPIO14 Optional sensor - 0, // GPIO15 - 0, // GPIO16 - 0 // ADC0 Analog input - }, - { // SONOFF_SV - Sonoff SV (ESP8266) - GPI8_KEY1, // GPIO00 Button - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - 0, - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - GPI8_USER, // GPIO04 Optional sensor - GPI8_USER, // GPIO05 Optional sensor - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On) - GPI8_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off) - Link and Power status - GPI8_USER, // GPIO14 Optional sensor - 0, 0, - GPI8_USER // ADC0 Analog input - }, - { // SONOFF_DUAL - Sonoff Dual (ESP8266) - GPI8_USER, // GPIO00 Pad - GPI8_TXD, // GPIO01 Relay control - 0, - GPI8_RXD, // GPIO03 Relay control - GPI8_USER, // GPIO04 Optional sensor - 0, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - 0, - GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status - GPI8_USER, // GPIO14 Optional sensor - 0, 0, 0 - }, - { // SONOFF_POW - Sonoff Pow (ESP8266 - HLW8012) - GPI8_KEY1, // GPIO00 Button - 0, 0, 0, 0, - GPI8_NRG_SEL, // GPIO05 HLW8012 Sel output (1 = Voltage) - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On) - GPI8_NRG_CF1, // GPIO13 HLW8012 CF1 voltage / current - GPI8_HLW_CF, // GPIO14 HLW8012 CF power - GPI8_LED1, // GPIO15 Blue Led (0 = On, 1 = Off) - Link and Power status - 0, 0 - }, - { // SONOFF_LED - Sonoff LED (ESP8266) - GPI8_KEY1, // GPIO00 Button - 0, 0, 0, - GPI8_USER, // GPIO04 Optional sensor (PWM3 Green) - GPI8_USER, // GPIO05 Optional sensor (PWM2 Red) - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_PWM1, // GPIO12 Cold light (PWM0 Cold) - GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status - GPI8_PWM2, // GPIO14 Warm light (PWM1 Warm) - GPI8_USER, // GPIO15 Optional sensor (PWM4 Blue) - 0, 0 - }, - { // ELECTRODRAGON - ElectroDragon IoT Relay Board (ESP8266) - GPI8_KEY2, // GPIO00 Button 2 - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - GPI8_KEY1, // GPIO02 Button 1 - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - GPI8_USER, // GPIO04 Optional sensor - GPI8_USER, // GPIO05 Optional sensor - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_REL2, // GPIO12 Red Led and Relay 2 (0 = Off, 1 = On) - GPI8_REL1, // GPIO13 Red Led and Relay 1 (0 = Off, 1 = On) - GPI8_USER, // GPIO14 Optional sensor - GPI8_USER, // GPIO15 Optional sensor - GPI8_LED1, // GPIO16 Green/Blue Led (1 = On, 0 = Off) - Link and Power status - GPI8_USER // ADC0 A0 Analog input - }, - { // EXS_RELAY - ES-Store Latching relay(s) (ESP8266) - // https://ex-store.de/ESP8266-WiFi-Relay-V31 - // V3.1 Module Pin 1 VCC 3V3, Module Pin 6 GND - // https://ex-store.de/2-Kanal-WiFi-WLan-Relay-V5-Blackline-fuer-Unterputzmontage - GPI8_USER, // GPIO00 V3.1 Module Pin 8 - V5.0 Module Pin 4 - GPI8_USER, // GPIO01 UART0_TXD V3.1 Module Pin 2 - V5.0 Module Pin 3 - GPI8_USER, // GPIO02 V3.1 Module Pin 7 - GPI8_USER, // GPIO03 UART0_RXD V3.1 Module Pin 3 - GPI8_USER, // GPIO04 V3.1 Module Pin 10 - V5.0 Module Pin 2 - GPI8_USER, // GPIO05 V3.1 Module Pin 9 - V5.0 Module Pin 1 - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_REL1, // GPIO12 Relay1 ( 1 = Off) - GPI8_REL2, // GPIO13 Relay1 ( 1 = On) - GPI8_USER, // GPIO14 V3.1 Module Pin 5 - V5.0 GPI8_REL3_INV Relay2 ( 1 = Off) - GPI8_LED1, // GPIO15 V5.0 LED1 - Link and Power status - GPI8_USER, // GPIO16 V3.1 Module Pin 4 - V5.0 GPI8_REL4_INV Relay2 ( 1 = On) - 0 - }, - { // WION - Indoor Tap (ESP8266) - // https://www.amazon.com/gp/product/B00ZYLUBJU/ref=s9_acsd_al_bw_c_x_3_w - GPI8_USER, // GPIO00 Optional sensor (pm clock) - 0, - GPI8_LED1, // GPIO02 Green Led (1 = On, 0 = Off) - Link and Power status - 0, 0, 0, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_USER, // GPIO12 Optional sensor (pm data) - GPI8_KEY1, // GPIO13 Button - 0, - GPI8_REL1, // GPIO15 Relay (0 = Off, 1 = On) - 0, 0 - }, - { // SONOFF_DEV - Sonoff Dev (ESP8266) - GPI8_KEY1, // GPIO00 E-FW Button - GPI8_USER, // GPIO01 TX Serial RXD and Optional sensor - 0, // GPIO02 - GPI8_USER, // GPIO03 RX Serial TXD and Optional sensor - GPI8_USER, // GPIO04 Optional sensor - GPI8_USER, // GPIO05 Optional sensor - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_USER, // GPIO12 - GPI8_USER, // GPIO13 BLUE LED - GPI8_USER, // GPIO14 Optional sensor - 0, // GPIO15 - 0, // GPIO16 - GPI8_USER // ADC0 A0 Analog input - }, - { // H801 - Lixada H801 Wifi (ESP8266) - GPI8_USER, // GPIO00 E-FW Button - GPI8_LED1, // GPIO01 Green LED - Link and Power status - GPI8_USER, // GPIO02 TX and Optional sensor - Pin next to TX on the PCB - GPI8_USER, // GPIO03 RX and Optional sensor - Pin next to GND on the PCB - GPI8_PWM5, // GPIO04 W2 - PWM5 - GPI8_LED2_INV, // GPIO05 Red LED - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_PWM3, // GPIO12 Blue - GPI8_PWM2, // GPIO13 Green - GPI8_PWM4, // GPIO14 W1 - PWM4 - GPI8_PWM1, // GPIO15 Red - 0, 0 - }, - { // SONOFF_SC - onoff SC (ESP8266) - GPI8_KEY1, // GPIO00 Button - GPI8_TXD, // GPIO01 RXD to ATMEGA328P - GPI8_USER, // GPIO02 Optional sensor - GPI8_RXD, // GPIO03 TXD to ATMEGA328P - 0, 0, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - 0, - GPI8_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off) - Link and Power status - 0, 0, 0, 0 - }, - { // SONOFF_BN - Sonoff BN-SZ01 Ceiling led (ESP8285) - 0, 0, 0, 0, 0, 0, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_PWM1, // GPIO12 Light - GPI8_LED1_INV, // GPIO13 Red Led (0 = On, 1 = Off) - Link and Power status - 0, 0, 0, 0 - }, - { // HUAFAN_SS - Hua Fan Smart Socket (ESP8266) - like Sonoff Pow - GPI8_LEDLNK_INV, // GPIO00 Blue Led (0 = On, 1 = Off) - Link status - 0, 0, - GPI8_LED1_INV, // GPIO03 Red Led (0 = On, 1 = Off) - Power status - GPI8_KEY1, // GPIO04 Button - GPI8_REL1_INV, // GPIO05 Relay (0 = On, 1 = Off) - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_NRG_CF1, // GPIO12 HLW8012 CF1 voltage / current - GPI8_NRG_SEL, // GPIO13 HLW8012 Sel output (1 = Voltage) - GPI8_HLW_CF, // GPIO14 HLW8012 CF power - 0, 0, 0 - }, - { // SONOFF_BRIDGE - Sonoff RF Bridge 433 (ESP8285) - GPI8_KEY1, // GPIO00 Button - GPI8_TXD, // GPIO01 RF bridge control - GPI8_USER, // GPIO02 Optional sensor - GPI8_RXD, // GPIO03 RF bridge control - GPI8_USER, // GPIO04 Optional sensor - GPI8_USER, // GPIO05 Optional sensor - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_USER, // GPIO12 Optional sensor - GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status - GPI8_USER, // GPIO14 Optional sensor - 0, 0, 0 - }, - { // SONOFF_B1 - Sonoff B1 (ESP8285 - my9231) - GPI8_KEY1, // GPIO00 Pad - GPI8_USER, // GPIO01 Serial RXD and Optional sensor pad - GPI8_USER, // GPIO02 Optional sensor SDA pad - GPI8_USER, // GPIO03 Serial TXD and Optional sensor pad - 0, 0, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_DI, // GPIO12 my9231 DI - 0, - GPI8_DCKI, // GPIO14 my9231 DCKI - 0, 0, 0 - }, - { // AILIGHT - Ai-Thinker RGBW led (ESP8266 - my9291) - GPI8_KEY1, // GPIO00 Pad - GPI8_USER, // GPIO01 Serial RXD and Optional sensor pad - GPI8_USER, // GPIO02 Optional sensor SDA pad - GPI8_USER, // GPIO03 Serial TXD and Optional sensor pad - 0, 0, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - 0, - GPI8_DI, // GPIO13 my9291 DI - 0, - GPI8_DCKI, // GPIO15 my9291 DCKI - 0, 0 - }, - { // SONOFF_T11 - Sonoff T1 1CH (ESP8285) - GPI8_KEY1, // GPIO00 Button 1 - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - GPI8_USER, // GPIO02 Optional Sensor (J3 Pin 5) - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - 0, 0, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_REL1, // GPIO12 Blue Led and Relay 1 (0 = Off, 1 = On) - GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status - 0, 0, 0, 0 - }, - { // SUPLA1 - Supla Espablo (ESP8266) - // http://www.wykop.pl/ramka/3325399/diy-supla-do-puszki-instalacyjnej-podtynkowej-supla-org/ - 0, // GPIO00 Flash jumper - GPI8_USER, // GPIO01 Serial RXD and Optional sensor -#ifdef USE_DS18x20 - GPI8_DSB, // GPIO02 DS18B20 sensor -#else - GPI8_USER, // GPIO02 Optional sensor -#endif - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - GPI8_KEY1, // GPIO04 Button 1 - GPI8_REL1, // GPIO05 Relay 1 (0 = Off, 1 = On) - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_USER, // GPIO12 Optional sensor - GPI8_REL2, // GPIO13 Relay 2 (0 = Off, 1 = On) - GPI8_USER, // GPIO14 Optional sensor - 0, - GPI8_LED1, // GPIO16 Led (1 = On, 0 = Off) - Link and Power status - GPI8_USER // ADC0 A0 Analog input - }, - { // WITTY - Witty Cloud Dev Board (ESP8266) - // https://www.aliexpress.com/item/ESP8266-serial-WIFI-Witty-cloud-Development-Board-ESP-12F-module-MINI-nodemcu/32643464555.html - GPI8_USER, // GPIO00 D3 flash push button on interface board - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - GPI8_LED1_INV, // GPIO02 D4 Blue Led (0 = On, 1 = Off) on ESP-12F - Link and Power status - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - GPI8_KEY1, // GPIO04 D2 push button on ESP-12F board - GPI8_USER, // GPIO05 D1 optional sensor - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_PWM2, // GPIO12 D6 RGB LED Green - GPI8_PWM3, // GPIO13 D7 RGB LED Blue - GPI8_USER, // GPIO14 D5 optional sensor - GPI8_PWM1, // GPIO15 D8 RGB LED Red - GPI8_USER, // GPIO16 D0 optional sensor - GPI8_USER // ADC0 A0 Light sensor / Requires USE_ADC_VCC in user_config.h to be disabled - }, - { // YUNSHAN - Yunshan Wifi Relay (ESP8266) - // https://www.ebay.com/p/Esp8266-220v-10a-Network-Relay-WiFi-Module/1369583381 - // Schematics and Info https://ucexperiment.wordpress.com/2016/12/18/yunshan-esp8266-250v-15a-acdc-network-wifi-relay-module/ - 0, // GPIO00 Flash jumper - Module Pin 8 - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - Module Pin 2 - GPI8_LED1_INV, // GPIO02 Blue Led (0 = On, 1 = Off) on ESP-12F - Module Pin 7 - Link and Power status - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - Module Pin 3 - GPI8_REL1, // GPIO04 Red Led and Relay (0 = Off, 1 = On) - Module Pin 10 - GPI8_KEY1, // GPIO05 Blue Led and OptoCoupler input - Module Pin 9 - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - 0, 0, 0, 0, 0, 0 - }, - { // MAGICHOME - Magic Home (aka Flux-light) (ESP8266) and Arilux LC10 (ESP8285) - // https://www.aliexpress.com/item/Magic-Home-Mini-RGB-RGBW-Wifi-Controller-For-Led-Strip-Panel-light-Timing-Function-16million-colors/32686853650.html - 0, - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - GPI8_LED1_INV, // GPIO02 Blue onboard LED - Link and Power status - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - GPI8_ARIRFRCV, // GPIO04 IR or RF receiver (optional) (Arilux LC10) - GPI8_PWM2, // GPIO05 RGB LED Green - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_PWM3, // GPIO12 RGB LED Blue - GPI8_USER, // GPIO13 RGBW LED White (optional - set to PWM4 for Cold White or Warm White as used on Arilux LC10) - GPI8_PWM1, // GPIO14 RGB LED Red - GPI8_ARIRFSEL, // GPIO15 RF receiver control (Arilux LC10) - 0, 0 - }, - { // LUANIHVIO - ESP8266_HVIO - // https://luani.de/projekte/esp8266-hvio/ - 0, // GPIO00 Flash jumper - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - GPI8_USER, // GPIO02 Optional sensor / I2C SDA pad - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - GPI8_REL1, // GPIO04 Relay 1 (0 = Off, 1 = On) - GPI8_REL2, // GPIO05 Relay 2 (0 = Off, 1 = On) - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_SWT1, // GPIO12 External input 1 (0 = On, 1 = Off) - GPI8_SWT2, // GPIO13 External input 2 (0 = On, 1 = Off) - GPI8_USER, // GPIO14 Optional sensor / I2C SCL pad - GPI8_LED1, // GPIO15 Led (1 = On, 0 = Off) - Link and Power status - 0, - GPI8_USER // ADC0 A0 Analog input - }, - { // KMC_70011 - KMC 70011 - // https://www.amazon.com/KMC-Timing-Monitoring-Network-125V-240V/dp/B06XRX2GTQ - GPI8_KEY1, // GPIO00 Button - 0, 0, 0, - GPI8_HLW_CF, // GPIO04 HLW8012 CF power - GPI8_NRG_CF1, // GPIO05 HLW8012 CF1 voltage / current - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_NRG_SEL, // GPIO12 HLW8012 SEL (1 = Voltage) - GPI8_LED1_INV, // GPIO13 Green Led - Link and Power status - GPI8_REL1, // GPIO14 Relay - 0, 0, 0 - }, - { // ARILUX_LC01 - Arilux AL-LC01 (ESP8285) - // https://www.banggood.com/nl/ARILUX-AL-LC01-Super-Mini-LED-WIFI-Smart-RGB-Controller-For-RGB-LED-Strip-Light-DC-9-12V-p-1058603.html - // (PwmFrequency 1111Hz) - GPI8_KEY1, // GPIO00 Optional Button - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - GPI8_ARIRFSEL, // GPIO02 RF receiver control - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - GPI8_ARIRFRCV, // GPIO04 IR or RF receiver (optional) - GPI8_PWM1, // GPIO05 RGB LED Red - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_PWM2, // GPIO12 RGB LED Green - GPI8_PWM3, // GPIO13 RGB LED Blue - GPI8_USER, // GPIO14 RGBW LED White (optional - set to PWM4 for Cold White or Warm White) - 0, 0, 0 - }, - { // ARILUX_LC11 - Arilux AL-LC11 (ESP8266) - // https://www.banggood.com/nl/ARILUX-AL-LC11-Super-Mini-LED-WIFI-APP-Controller-RF-Remote-Control-For-RGBWW-LED-Strip-DC9-28V-p-1085112.html - // (PwmFrequency 540Hz) - GPI8_KEY1, // GPIO00 Optional Button - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - GPI8_ARIRFSEL, // GPIO02 RF receiver control - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - GPI8_PWM2, // GPIO04 RGB LED Green - GPI8_PWM1, // GPIO05 RGB LED Red - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_PWM5, // GPIO12 RGBCW LED Warm - GPI8_PWM4, // GPIO13 RGBW LED Cold - GPI8_PWM3, // GPIO14 RGB LED Blue - GPI8_ARIRFRCV, // GPIO15 RF receiver input - 0, 0 - }, - { // ARILUX_LC06 - Arilux AL-LC06 (ESP8285) - // https://www.banggood.com/ARILUX-AL-LC06-LED-WIFI-Smartphone-Controller-Romote-5-Channels-DC12-24V-For-RGBWW-Strip-light-p-1061476.html - GPI8_KEY1, // GPIO00 Optional Button - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - GPI8_USER, // GPIO02 Empty pad - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - GPI8_USER, // GPIO04 W2 - PWM5 - 0, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_PWM2, // GPIO12 RGB LED Green - GPI8_PWM3, // GPIO13 RGB LED Blue - GPI8_PWM1, // GPIO14 RGB LED Red - GPI8_USER, // GPIO15 RGBW LED White - 0, 0 - }, - { // ZENGGE_ZF_WF017 - Zenggee ZJ-WF017-A (ESP12S)) - // https://www.ebay.com/p/Smartphone-Android-IOS-WiFi-Music-Controller-for-RGB-5050-3528-LED-Strip-Light/534446632?_trksid=p2047675.l2644 - GPI8_KEY1, // GPIO00 Optional Button - 0, - GPI8_USER, // GPIO02 Empty pad - 0, - GPI8_USER, // GPIO04 W2 - PWM5 - 0, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_PWM2, // GPIO12 RGB LED Green - GPI8_PWM1, // GPIO13 RGB LED Red - GPI8_PWM3, // GPIO14 RGB LED Blue - 0, 0, 0 - }, - { // SONOFF_POW_R2 - Sonoff Pow R2 (ESP8285 - CSE7766) - GPI8_KEY1, // GPIO00 Button - GPI8_CSE7766_TX, // GPIO01 Serial RXD 4800 baud 8E1 CSE7766 energy sensor - 0, - GPI8_CSE7766_RX, // GPIO03 Serial TXD - 0, 0, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On) - GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status - 0, 0, 0, 0 - }, - { // BLITZWOLF_BWSHP - BlitzWolf BW-SHP2 and BW-SHP6 (ESP8285 - BL0937 or HJL-01 Energy Monitoring) - // https://www.banggood.com/BlitzWolf-BW-SHP2-Smart-WIFI-Socket-EU-Plug-220V-16A-Work-with-Amazon-Alexa-Google-Assistant-p-1292899.html - // https://www.amazon.de/Steckdose-Homecube-intelligente-Verbrauchsanzeige-funktioniert/dp/B076Q2LKHG/ref=sr_1_fkmr0_1 - // https://www.amazon.de/Intelligente-Stromverbrauch-Fernsteurung-Schaltbare-Energieklasse/dp/B076WZQS4S/ref=sr_1_1 - // https://www.aliexpress.com/store/product/BlitzWolf-BW-SHP6-EU-Plug-Metering-Version-WIFI-Smart-Socket-220V-240V-10A-Work-with-Amazon/1965360_32945504669.html - GPI8_LED1_INV, // GPIO00 Red Led (1 = On, 0 = Off) - Power status - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - GPI8_LEDLNK_INV, // GPIO02 Blue Led (1 = On, 0 = Off) - Link status - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - 0, - GPI8_HJL_CF, // GPIO05 BL0937 or HJL-01 CF power - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_NRG_SEL_INV, // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage) - GPI8_KEY1, // GPIO13 Button - GPI8_NRG_CF1, // GPIO14 BL0937 or HJL-01 CF1 current / voltage - GPI8_REL1, // GPIO15 Relay (0 = Off, 1 = On) - 0, 0 - }, - { // SHELLY1 - Shelly1 Open Source (ESP8266 - 2MB) - https://shelly.cloud/shelly1-open-source/ - GPI8_USER, // GPIO00 - Can be changed to GPI8_USER, only if Shelly is powered with 12V DC - GPI8_USER, // GPIO01 Serial RXD - Can be changed to GPI8_USER, only if Shelly is powered with 12V DC - 0, - GPI8_USER, // GPIO03 Serial TXD - Can be changed to GPI8_USER, only if Shelly is powered with 12V DC - GPI8_REL1, // GPIO04 Relay (0 = Off, 1 = On) - GPI8_SWT1_NP, // GPIO05 SW pin - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - 0, 0, 0, 0, 0, 0 - }, - { // SHELLY2 - Shelly2 (ESP8266 - 2MB) - https://shelly.cloud/shelly2/ - 0, - GPI8_MCP39F5_TX, // GPIO01 MCP39F501 Serial input - 0, - GPI8_MCP39F5_RX, // GPIO03 MCP39F501 Serial output - GPI8_REL1, // GPIO04 - GPI8_REL2, // GPIO05 - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_SWT1, // GPIO12 - 0, - GPI8_SWT2, // GPIO14 - GPI8_MCP39F5_RST, // GPIO15 MCP39F501 Reset - 0, - 0 - }, - { // PHILIPS - Xiaomi Philips bulb (ESP8266) - 0, 0, 0, 0, 0, 0, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_PWM2, // GPIO12 cold/warm light - 0, 0, - GPI8_PWM1, // GPIO15 light intensity - 0, 0 - }, - { // NEO_COOLCAM - Neo Coolcam (ESP8266) - // https://www.banggood.com/NEO-COOLCAM-WiFi-Mini-Smart-Plug-APP-Remote-Control-Timing-Smart-Socket-EU-Plug-p-1288562.html?cur_warehouse=CN - 0, 0, 0, 0, - GPI8_LED1_INV, // GPIO04 Red Led (0 = On, 1 = Off) - Link and Power status - 0, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On) - GPI8_KEY1, // GPIO13 Button - 0, 0, 0, 0 - }, - { // ESP_SWITCH - Michael Haustein 4 channel wall switch (ESP07 = ESP8266) - // Use rules for further actions like - rule on power1#state do publish cmnd/other_device/power %value% endon - GPI8_KEY2, // GPIO00 Button 2 - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - GPI8_REL3_INV, // GPIO02 Yellow Led 3 (0 = On, 1 = Off) - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - GPI8_KEY1, // GPIO04 Button 1 - GPI8_REL2_INV, // GPIO05 Red Led 2 (0 = On, 1 = Off) - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_REL4_INV, // GPIO12 Blue Led 4 (0 = On, 1 = Off) - GPI8_KEY4, // GPIO13 Button 4 - GPI8_KEY3, // GPIO14 Button 3 - GPI8_LED1, // GPIO15 Optional sensor - GPI8_REL1_INV, // GPIO16 Green Led 1 (0 = On, 1 = Off) - 0 - }, - { // OBI - OBI socket (ESP8266) - https://www.obi.de/hausfunksteuerung/wifi-stecker-schuko/p/2291706 - GPI8_USER, // GPIO00 - GPI8_USER, // GPIO01 Serial RXD - 0, - GPI8_USER, // GPIO03 Serial TXD - GPI8_LED1, // GPIO04 Blue LED - Link and Power status - GPI8_REL1, // GPIO05 (Relay OFF, but used as Relay Switch) - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_LED3, // GPIO12 (Relay ON, but set to LOW, so we can switch with GPIO05) - GPI8_USER, // GPIO13 - GPI8_KEY1, // GPIO14 Button - 0, - GPI8_USER, // GPIO16 - GPI8_USER // ADC0 A0 Analog input - }, - { // TECKIN - https://www.amazon.de/gp/product/B07D5V139R - 0, - GPI8_KEY1, // GPIO01 Serial TXD and Button - 0, - GPI8_LED1_INV, // GPIO03 Serial RXD and Red Led (0 = On, 1 = Off) - Power status - GPI8_HJL_CF, // GPIO04 BL0937 or HJL-01 CF power - GPI8_NRG_CF1, // GPIO05 BL0937 or HJL-01 CF1 current / voltage - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_NRG_SEL_INV, // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage) - GPI8_LEDLNK_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link status - GPI8_REL1, // GPIO14 Relay (0 = Off, 1 = On) - 0, 0, 0 - }, - { // APLIC_WDP303075 - Aplic WDP 303075 (ESP8285 - HLW8012 Energy Monitoring) - // https://www.amazon.de/dp/B07CNWVNJ2 - 0, 0, 0, - GPI8_KEY1, // GPIO03 Button - GPI8_HLW_CF, // GPIO04 HLW8012 CF power - GPI8_NRG_CF1, // GPIO05 HLW8012 CF1 current / voltage - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_NRG_SEL_INV, // GPIO12 HLW8012 CF Sel output (0 = Voltage) - GPI8_LED1_INV, // GPIO13 LED (0 = On, 1 = Off) - Link and Power status - GPI8_REL1, // GPIO14 Relay SRU 5VDC SDA (0 = Off, 1 = On ) - 0, 0, 0 - }, - { // TUYA_DIMMER - Tuya MCU device (ESP8266 w/ separate MCU) - // https://www.amazon.com/gp/product/B07CTNSZZ8/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1 - GPI8_USER, // Virtual Button (controlled by MCU) - GPI8_USER, // GPIO01 MCU serial control - GPI8_USER, - GPI8_USER, // GPIO03 MCU serial control - GPI8_USER, - GPI8_USER, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_USER, - GPI8_USER, - GPI8_USER, // GPIO14 Green Led - GPI8_USER, - GPI8_USER, - 0 - }, - { // GOSUND - https://www.amazon.de/gp/product/B0777BWS1P - 0, - GPI8_LEDLNK_INV, // GPIO01 Serial RXD and LED1 (blue) inv - Link status - 0, - GPI8_KEY1, // GPIO03 Serial TXD and Button - GPI8_HJL_CF, // GPIO04 BL0937 or HJL-01 CF power - GPI8_NRG_CF1, // GPIO05 BL0937 or HJL-01 CF1 current / voltage - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_NRG_SEL_INV, // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage) - GPI8_LED1_INV, // GPIO13 LED2 (red) inv - Power status - GPI8_REL1, // GPIO14 Relay (0 = Off, 1 = On) - 0, 0, 0 - }, - { // ARMTRONIX_DIMMERS - ARMTRONIX Dimmer, one or two channel (ESP8266 w/ separate MCU dimmer) - // https://www.tindie.com/products/Armtronix/wifi-ac-dimmer-two-triac-board/ - // https://www.tindie.com/products/Armtronix/wifi-ac-dimmer-esp8266-one-triac-board-alexaecho/ - GPI8_USER, - GPI8_TXD, // GPIO01 MCU serial control - GPI8_USER, - GPI8_RXD, // GPIO03 MCU serial control - GPI8_USER, - GPI8_USER, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_USER, - GPI8_USER, - GPI8_USER, - GPI8_USER, - GPI8_USER, - 0 - }, - { // SK03_TUYA - Outdoor smart plug with power monitoring HLW8012 chip - https://www.amazon.com/gp/product/B07CG7MBPV - GPI8_KEY1, // GPIO00 Button - 0, 0, 0, - GPI8_HLW_CF, // GPIO04 HLW8012 CF power - GPI8_NRG_CF1, // GPIO05 HLW8012 CF1 current / voltage - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_NRG_SEL_INV, // GPIO12 HLW8012 CF Sel output (0 = Voltage) - GPI8_LED1_INV, // GPIO13 Red Led (0 = On, 1 = Off) - Power status - GPI8_LEDLNK_INV, // GPIO14 Blue Led (0 = On, 1 = Off) - Link status - GPI8_REL1, // GPIO15 Relay (0 = Off, 1 = On) - 0, 0 - }, - { // PS_16_DZ - PS-16-DZ Dimmer (ESP8266 w/ separate Nuvoton MCU dimmer) - // https://www.aliexpress.com/item/SM-Smart-WIFI-Wall-Dimmer-Light-Switch-US-Ewelink-APP-Remote-Control-Wi-Fi-Wirele-Work/32871151902.html - GPI8_USER, - GPI8_TXD, // GPIO01 MCU serial control - GPI8_USER, - GPI8_RXD, // GPIO03 MCU serial control - GPI8_USER, - GPI8_USER, - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_USER, - GPI8_LED1, // GPIO13 WiFi LED - Link and Power status - GPI8_USER, - GPI8_USER, - GPI8_USER, - 0 - }, - { // TECKIN_US - Teckin SP20 US with Energy Monitoring - // https://www.amazon.com/Outlet-Compatible-Monitoring-Function-Required/dp/B079Q5W22B - // https://www.amazon.com/Outlet-ZOOZEE-Monitoring-Function-Compatible/dp/B07J2LR5KN - GPI8_LED1_INV, // GPIO00 Red Led (1 = On, 0 = Off) - Power status - 0, - GPI8_LEDLNK_INV, // GPIO02 Blue Led (1 = On, 0 = Off) - Link status - 0, - GPI8_REL1, // GPIO04 Relay (0 = Off, 1 = On) - GPI8_HJL_CF, // GPIO05 BL0937 or HJL-01 CF power - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_NRG_SEL_INV, // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage) - GPI8_KEY1, // GPIO13 Button - GPI8_NRG_CF1, // GPIO14 BL0937 or HJL-01 CF1 current / voltage - 0, 0, 0 - }, - { // MANZOKU_EU_4 - "MANZOKU" labeled power strip, EU version - // https://www.amazon.de/Steckdosenleiste-AOFO-Mehrfachsteckdose-Überspannungsschutz-Sprachsteuerung/dp/B07GBSD11P/ - // https://www.amazon.de/Steckdosenleiste-Geekbes-USB-Anschluss-Kompatibel-gesteuert/dp/B078W23BW9/ - 0, // GPIO00 - 0, // GPIO01 Serial RXD - 0, - GPI8_KEY1, // GPIO03 Serial TXD + Button - GPI8_REL2, // GPIO04 Relay 2 - GPI8_REL1, // GPIO05 Relay 1 - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_REL3, // GPIO12 Relay 3 - GPI8_REL4, // GPIO13 Relay 4 - GPI8_USER, // GPIO14 - 0, - GPI8_USER, // GPIO16 - 0 - }, - { // OBI2 - OBI socket (ESP8266) - https://www.obi.de/hausfunksteuerung/wifi-stecker-schuko-2-stueck-weiss/p/4077673 - 0, // GPIO00 - 0, // GPIO01 Serial RXD - 0, - 0, // GPIO03 Serial TXD - GPI8_REL1, // GPIO04 Relay 1 - GPI8_KEY1, // GPIO05 Button - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_LEDLNK_INV, // GPIO12 Green LED - Link status - GPI8_LED1, // GPIO13 Red LED - Power status - 0, 0, 0, 0 - }, - { // YTF_IR_BRIDGE - https://www.aliexpress.com/item/Tuya-universal-Smart-IR-Hub-remote-control-Voice-Control-AC-TV-Work-With-Alexa-Google-Home/32951202513.html - GPI8_USER, // GPIO00 - GPI8_USER, // GPIO01 Serial RXD - GPI8_USER, // GPIO02 - GPI8_USER, // GPIO03 Serial TXD - GPI8_LED1_INV, // GPIO04 Blue Led - Link status - GPI8_IRRECV, // GPIO05 IR Receiver - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - 0, // GPIO12 - GPI8_KEY1, // GPIO13 Button - GPI8_IRSEND, // GPIO14 IR Transmitter - 0, 0, 0 - }, - { // DIGOO - Digoo DG-SP202 - // https://www.banggood.com/DIGOO-DG-SP202-Dual-EU-Plug-Smart-WIFI-Socket-Individual-Controllable-Energy-Monitor-Remote-Control-Timing-Smart-Home-Outlet-let-p-1375323.html - GPI8_KEY1, // GPIO00 Button1 - 0, // GPIO01 Serial RXD - 0, // GPIO02 - 0, // GPIO03 Serial TXD - GPI8_HJL_CF, // GPIO04 BL0937 or HJL-01 CF power - GPI8_NRG_CF1, // GPIO05 BL0937 or HJL-01 CF1 current / voltage - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_NRG_SEL_INV, // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage) - GPI8_LED1, // GPIO13 Blue Leds - Link Status - GPI8_REL2, // GPIO14 Relay2 (0 = Off, 1 = On) and Red Led - GPI8_REL1, // GPIO15 Relay1 (0 = Off, 1 = On) and Red Led - GPI8_KEY2_NP, // GPIO16 Button2, externally pulled up - 0 - }, - { // KA10 - SMANERGY KA10 (ESP8285 - BL0937 Energy Monitoring) - https://www.amazon.es/dp/B07MBTCH2Y - 0, // GPIO00 - GPI8_LEDLNK_INV, // GPIO01 Blue LED - Link status - 0, // GPIO02 - GPI8_KEY1, // GPIO03 Button - GPI8_HJL_CF, // GPIO04 BL0937 CF power - GPI8_NRG_CF1, // GPIO05 BL0937 CF1 voltage / current - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_NRG_SEL_INV, // GPIO12 BL0937 Sel output (1 = Voltage) - GPI8_LED1, // GPIO13 Red LED - Power status - GPI8_REL1, // GPIO14 Relay 1 - 0, 0, 0 - }, - { // ZX2820 - GPI8_KEY1, // GPIO00 Button - 0, 0, 0, - GPI8_HLW_CF, // GPIO04 HLW8012 CF power - GPI8_NRG_CF1, // GPIO05 HLW8012 CF1 voltage / current - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_NRG_SEL_INV, // GPIO12 HLW8012 SEL (0 = Voltage) - GPI8_LED1_INV, // GPIO13 Green Led - Link and Power status - GPI8_REL1, // GPIO14 Relay - 0, 0, 0 - }, - { // MI_DESK_LAMP - Mi LED Desk Lamp - https://www.mi.com/global/smartlamp/ - 0, 0, - GPI8_KEY1, // GPIO02 Button - 0, - GPI8_PWM1, // GPIO04 Cold White - GPI8_PWM2, // GPIO05 Warm White - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_ROT1A, // GPIO12 Rotary switch A pin - GPI8_ROT1B, // GPIO13 Rotary switch B pin - 0, 0, 0, 0 - }, - { // SP10 - Tuya SP10 (BL0937 Energy Monitoring) - // https://www.aliexpress.com/item/Smart-Mini-WiFi-Plug-Outlet-Switch-Work-With-ForEcho-Alexa-Google-Home-Remote-EU-Smart-Socket/32963670423.html - 0, // GPIO00 - GPI8_PWM1, // GPIO01 Nightlight - 0, // GPIO02 - GPI8_KEY1, // GPIO03 Button - GPI8_HJL_CF, // GPIO04 BL0937 CF power - GPI8_NRG_CF1, // GPIO05 BL0937 CF1 voltage / current - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_NRG_SEL_INV, // GPIO12 BL0937 Sel output (1 = Voltage) - GPI8_LED1, // GPIO13 Blue LED - Link status - GPI8_REL1, // GPIO14 Relay and red LED - 0, 0, 0 - }, - { // WAGA - WAGA life CHCZ02MB (HJL-01 Energy Monitoring) - // https://www.ebay.com/itm/332595697006 - GPI8_LED1_INV, // GPIO00 Red LED - 0, // GPIO01 Serial RXD - 0, // GPIO02 - GPI8_NRG_SEL_INV, // GPIO03 HJL-01 Sel output (1 = Voltage) - 0, // GPIO04 - GPI8_HJL_CF, // GPIO05 HJL-01 CF power - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_REL1, // GPIO12 Relay - GPI8_KEY1, // GPIO13 Button - GPI8_NRG_CF1, // GPIO14 HJL-01 CF1 voltage / current - GPI8_LEDLNK_INV, // GPIO15 Blue LED - Link status - 0, 0 - }, - { // SYF05 - Sunyesmart SYF05 (a.k.a. Fcmila) = TYWE3S + SM16726 - // Also works with Merkury 904 RGBW Bulbs with 13 set to GPI8_SM16716_SEL - // https://www.flipkart.com/fc-mila-bxav-xs-ad-smart-bulb/p/itmf85zgs45fzr7n - // https://docs.tuya.com/en/hardware/WiFi-module/wifi-e3s-module.html - // http://www.datasheet-pdf.com/PDF/SM16716-Datasheet-Sunmoon-932771 - GPI8_USER, // GPIO00 N.C. - 0, // GPIO01 Serial RXD - GPI8_USER, // GPIO02 N.C. - 0, // GPIO03 Serial TXD - GPI8_SM16716_CLK, // GPIO04 SM16716 Clock - GPI8_PWM1, // GPIO05 White - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_USER, // GPIO12 Alt. White on some devices - GPI8_USER, // GPIO13 SM16716 Enable on some devices - GPI8_SM16716_DAT, // GPIO14 SM16716 Data - 0, // GPIO15 wired to GND - GPI8_USER, // GPIO16 N.C. - GPI8_USER // ADC0 A0 Analog input - }, - { // EXS_DIMMER - EX-Store WiFi Dimmer v4, two channel (ESP8266 w/ separate MCU dimmer) - // https://ex-store.de/2-Kanal-RS232-WiFi-WLan-Dimmer-Modul-V4-fuer-Unterputzmontage-230V-3A - // https://ex-store.de/2-Kanal-RS232-WiFi-WLan-Dimmer-Modul-V4-fuer-Unterputzmontage-230V-3A-ESP8266-V12-Stift-und-Buchsenleisten - 0, - GPI8_TXD, // GPIO01 MCU serial control - GPI8_LEDLNK, // GPIO02 LED Link - GPI8_RXD, // GPIO03 MCU serial control - GPI8_USER, // GPIO04 - GPI8_USER, // GPIO05 - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_USER, // GPIO12 - GPI8_EXS_ENABLE, // GPIO13 EXS MCU Enable - GPI8_USER, // GPIO14 - 0, // GPIO15 - 0, 0 - }, - { // PWM_DIMMER - Support for Martin Jerry/acenx/Tessan/NTONPOWER SD0x PWM - // dimmer switches. The brightness of the load for these dimmers is - // controlled by a PWM GPIO pin. There are typically power, up & down - // buttons and 4 LED's. Examples are: - // https://www.amazon.com/dp/B07FXYSVR1 - // https://www.amazon.com/dp/B07V26Q3VD - // https://www.amazon.com/dp/B07K67D43J - // https://www.amazon.com/dp/B07TTGFWFM - GPI8_KEY3, // GPIO00 Up button - GPI8_KEY2, // GPIO01 Down button - 0, // GPIO02 - GPI8_LED4_INV, // GPIO03 Level 5 LED - GPI8_LEDLNK_INV, // GPIO04 LED Link - GPI8_LED3_INV, // GPIO05 Level 4 LED - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_LED2_INV, // GPIO12 Level 3 LED - GPI8_PWM1, // GPIO13 Dimmer PWM - GPI8_LED1_INV, // GPIO12 Level 2 LED - GPI8_KEY1_INV, // GPIO15 Power button - GPI8_REL1_INV, // GPIO16 Power relay/Level 1 LED - 0 - }, - { // SONOFF_ZB_BRIDGE - Sonoff Zigbee Bridge (ESP8266) - GPI8_LED1_INV, // GPIO00 Green Led (0 = On, 1 = Off) - Traffic between ESP and EFR - GPI8_ZIGBEE_TX, // GPIO01 Zigbee Serial control - 0, // GPIO02 - GPI8_ZIGBEE_RX, // GPIO03 Zigbee Serial control - GPI8_ZIGBEE_RST, // GPIO04 Zigbee Reset - 0, // GPIO05 EFR32 Bootloader mode (drive Low for Gecko Bootloader, inactive or high for Zigbee EmberZNet) - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_I2C_SDA, // GPIO12 I2C SDA - connected to 512KB EEPROM - GPI8_LEDLNK_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link status - GPI8_I2C_SCL, // GPIO14 I2C SCL - connected to 512KB EEPROM - 0, // GPIO15 connected to IO15 pad, also used for logging - GPI8_KEY1, // GPIO16 Button - 0 - } -}; - -/*********************************************************************************************\ - * Templates with 14 usable pins (ESP8285) -\*********************************************************************************************/ - -const mytmplt8285 kModules8285[TMP_MAXMODULE_8266 - TMP_WEMOS] PROGMEM = { - { // WEMOS - Any ESP8266/ESP8285 device like WeMos and NodeMCU hardware (ESP8266) - GPI8_USER, // GPIO00 D3 Wemos Button Shield - GPI8_USER, // GPIO01 TX Serial RXD - GPI8_USER, // GPIO02 D4 Wemos DHT Shield - GPI8_USER, // GPIO03 RX Serial TXD and Optional sensor - GPI8_USER, // GPIO04 D2 Wemos I2C SDA - GPI8_USER, // GPIO05 D1 Wemos I2C SCL / Wemos Relay Shield (0 = Off, 1 = On) / Wemos WS2812B RGB led Shield - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - GPI8_USER, // GPIO09 (SD_DATA2 Flash QIO or ESP8285) - GPI8_USER, // GPIO10 (SD_DATA3 Flash QIO or ESP8285) - // GPIO11 (SD_CMD Flash) - GPI8_USER, // GPIO12 D6 - GPI8_USER, // GPIO13 D7 - GPI8_USER, // GPIO14 D5 - GPI8_USER, // GPIO15 D8 - GPI8_USER, // GPIO16 D0 Wemos Wake - GPI8_USER // ADC0 A0 Analog input - }, - { // SONOFF_4CH - Sonoff 4CH (ESP8285) - GPI8_KEY1, // GPIO00 Button 1 - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - GPI8_USER, // GPIO02 Optional sensor - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - GPI8_REL3, // GPIO04 Sonoff 4CH Red Led and Relay 3 (0 = Off, 1 = On) - GPI8_REL2, // GPIO05 Sonoff 4CH Red Led and Relay 2 (0 = Off, 1 = On) - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - GPI8_KEY2, // GPIO09 Button 2 - GPI8_KEY3, // GPIO10 Button 3 - // GPIO11 (SD_CMD Flash) - GPI8_REL1, // GPIO12 Red Led and Relay 1 (0 = Off, 1 = On) - Link and Power status - GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - GPI8_KEY4, // GPIO14 Button 4 - GPI8_REL4, // GPIO15 Red Led and Relay 4 (0 = Off, 1 = On) - 0, 0 - }, - { // SONOFF_T12 - Sonoff T1 2CH (ESP8285) - GPI8_KEY1, // GPIO00 Button 1 - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - GPI8_USER, // GPIO02 Optional Sensor (J3 Pin 5) - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - 0, - GPI8_REL2, // GPIO05 Blue Led and Relay 2 (0 = Off, 1 = On) - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - GPI8_KEY2, // GPIO09 Button 2 - 0, // GPIO10 - // GPIO11 (SD_CMD Flash) - GPI8_REL1, // GPIO12 Blue Led and Relay 1 (0 = Off, 1 = On) - GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status - 0, 0, 0, 0 - }, - { // SONOFF_T13 - Sonoff T1 3CH (ESP8285) - GPI8_KEY1, // GPIO00 Button 1 - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - GPI8_USER, // GPIO02 Optional Sensor (J3 Pin 5) - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - GPI8_REL3, // GPIO04 Blue Led and Relay 3 (0 = Off, 1 = On) - GPI8_REL2, // GPIO05 Blue Led and Relay 2 (0 = Off, 1 = On) - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - GPI8_KEY2, // GPIO09 Button 2 - GPI8_KEY3, // GPIO10 Button 3 - // GPIO11 (SD_CMD Flash) - GPI8_REL1, // GPIO12 Blue Led and Relay 1 (0 = Off, 1 = On) - GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status - 0, 0, 0, 0 - }, - { // SONOFF_DUAL_R2 - Sonoff Dual R2 (ESP8285) - GPI8_USER, // GPIO00 Button 0 on header (0 = On, 1 = Off) - GPI8_USER, // GPIO01 Serial RXD and Optional sensor - 0, - GPI8_USER, // GPIO03 Serial TXD and Optional sensor - 0, - GPI8_REL2, // GPIO05 Relay 2 (0 = Off, 1 = On) - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - GPI8_USER, // GPIO09 Button 1 on header (0 = On, 1 = Off) - GPI8_KEY1, // GPIO10 Button on casing - // GPIO11 (SD_CMD Flash) - GPI8_REL1, // GPIO12 Relay 1 (0 = Off, 1 = On) - GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status - 0, 0, 0, 0 - }, - { // SONOFF_IFAN03 - Sonoff iFan03 (ESP8285) - GPI8_KEY1, // GPIO00 WIFI_KEY0 Button 1 - GPI8_TXD, // GPIO01 ESP_TXD Serial RXD connection to P0.5 of RF microcontroller - 0, // GPIO02 ESP_LOG - GPI8_RXD, // GPIO03 ESP_RXD Serial TXD connection to P0.4 of RF microcontroller - 0, // GPIO04 DEBUG_RX - 0, // GPIO05 DEBUG_TX - // GPIO06 (SD_CLK Flash) - // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) - // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) - GPI8_REL1_INV, // GPIO09 WIFI_O0 Relay 1 (0 = Off, 1 = On) controlling the light - GPI8_BUZZER_INV, // GPIO10 WIFI_O4 Buzzer (0 = Off, 1 = On) - // GPIO11 (SD_CMD Flash) - GPI8_REL3, // GPIO12 WIFI_O2 Relay 3 (0 = Off, 1 = On) controlling the fan - GPI8_LED1_INV, // GPIO13 WIFI_CHK Blue Led on PCA (0 = On, 1 = Off) - Link and Power status - GPI8_REL2, // GPIO14 WIFI_O1 Relay 2 (0 = Off, 1 = On) controlling the fan - GPI8_REL4, // GPIO15 WIFI_O3 Relay 4 (0 = Off, 1 = On) controlling the fan - 0, 0 - } -}; - -#endif // ESP8266 - -#ifdef ESP32 -#if CONFIG_IDF_TARGET_ESP32C2 -/********************************************************************************************\ - * ESP32-C2 Module templates -\********************************************************************************************/ - -#define USER_MODULE 255 - -// Supported hardware modules -enum SupportedModulesESP32C2 { - WEMOS, // not really correct, a placeholder for now - MAXMODULE }; - -// Default module settings -const uint8_t kModuleNiceList[] PROGMEM = { - WEMOS, -}; - -// !!! Update this list in the same order as kModuleNiceList !!! -const char kModuleNames[] PROGMEM = - "ESP32C2|" - ; - -// !!! Update this list in the same order as SupportedModulesESP32C2 !!! -const mytmplt kModules[] PROGMEM = { - { // Generic ESP32C2 device - AGPIO(GPIO_USER), // 0 IO GPIO0, ADC1_CH0, RTC - AGPIO(GPIO_USER), // 1 IO GPIO1, ADC1_CH1, RTC - AGPIO(GPIO_USER), // 2 IO GPIO2, ADC1_CH2, RTC - AGPIO(GPIO_USER), // 3 IO GPIO3, ADC1_CH3, RTC - AGPIO(GPIO_USER), // 4 IO GPIO4, ADC1_CH4, RTC - AGPIO(GPIO_USER), // 5 IO GPIO5, RTC - AGPIO(GPIO_USER), // 6 IO GPIO6, - AGPIO(GPIO_USER), // 7 IO GPIO7, - AGPIO(GPIO_USER), // 8 IO GPIO8, Strapping - AGPIO(GPIO_USER), // 9 IO GPIO9, Strapping - AGPIO(GPIO_USER), // 10 IO GPIO10 - 0, // 11 IO GPIO11, output power supply for flash - 0, // 12 IO GPIO12, SPIHD - Free if flash DIO/DOUT - 0, // 13 IO GPIO13, SPIWP - Free if flash DIO/DOUT - 0, // 14 IO GPIO14, SPICS0 - 0, // 15 IO GPIO15, SPICLK - 0, // 16 IO GPIO16, SPID - 0, // 17 IO GPIO17, SPIQ - AGPIO(GPIO_USER), // 18 IO GPIO18, - AGPIO(GPIO_USER), // 19 IO RXD0 GPIO19, U0RXD - AGPIO(GPIO_USER), // 20 IO TXD0 GPIO20, U0TXD - 0 // Flag - }, -}; - -/*********************************************************************************************\ - Known templates -\*********************************************************************************************/ - -#elif CONFIG_IDF_TARGET_ESP32C3 -/********************************************************************************************\ - * ESP32-C3 Module templates -\********************************************************************************************/ - -#define USER_MODULE 255 - -// Supported hardware modules -enum SupportedModulesESP32C3 { - WEMOS, - MAXMODULE }; - -// Default module settings -const uint8_t kModuleNiceList[] PROGMEM = { - WEMOS, -}; - -// !!! Update this list in the same order as kModuleNiceList !!! -const char kModuleNames[] PROGMEM = - "ESP32C3|" - ; - -// !!! Update this list in the same order as SupportedModulesESP32C3 !!! -const mytmplt kModules[] PROGMEM = { - { // Generic ESP32C3 device - AGPIO(GPIO_USER), // 0 IO GPIO0, ADC1_CH0, XTAL_32K_P - AGPIO(GPIO_USER), // 1 IO GPIO1, ADC1_CH1, XTAL_32K_N - AGPIO(GPIO_USER), // 2 IO GPIO2, ADC1_CH2, FSPIQ - AGPIO(GPIO_USER), // 3 IO GPIO3, ADC1_CH3 - AGPIO(GPIO_USER), // 4 IO GPIO4, ADC1_CH4, FSPIHD, MTMS - AGPIO(GPIO_USER), // 5 IO GPIO5, ADC2_CH0, FSPIWP, MTDI - AGPIO(GPIO_USER), // 6 IO GPIO6, FSPICLK, MTCK - AGPIO(GPIO_USER), // 7 IO GPIO7, FSPID, MTDO - AGPIO(GPIO_USER), // 8 IO GPIO8 - AGPIO(GPIO_USER), // 9 IO GPIO9 - AGPIO(GPIO_USER), // 10 IO GPIO10 - 0, // 11 IO GPIO11, output power supply for flash - 0, // 12 IO GPIO12, SPIHD - Free if flash DIO/DOUT - 0, // 13 IO GPIO13, SPIWP - Free if flash DIO/DOUT - 0, // 14 IO GPIO14, SPICS0 - 0, // 15 IO GPIO15, SPICLK - 0, // 16 IO GPIO16, SPID - 0, // 17 IO GPIO17, SPIQ - AGPIO(GPIO_USER), // 18 IO GPIO18, USB_D - AGPIO(GPIO_USER), // 19 IO GPIO19, USB_D+ - AGPIO(GPIO_USER), // 20 IO RXD0 GPIO20, U0RXD - AGPIO(GPIO_USER), // 21 IO TXD0 GPIO21, U0TXD - 0 // Flag - }, -}; - -/*********************************************************************************************\ - Known templates -\*********************************************************************************************/ - -#elif CONFIG_IDF_TARGET_ESP32C5 -/********************************************************************************************\ - * ESP32-C5 Module templates -\********************************************************************************************/ - -#define USER_MODULE 255 - -// Supported hardware modules -enum SupportedModulesESP32C5 { - WEMOS, - MAXMODULE }; - -// Default module settings -const uint8_t kModuleNiceList[] PROGMEM = { - WEMOS, -}; - -// !!! Update this list in the same order as kModuleNiceList !!! -const char kModuleNames[] PROGMEM = - "ESP32C5|" - ; - -// !!! Update this list in the same order as SupportedModulesESP32C5 !!! -const mytmplt kModules[] PROGMEM = { - { // Generic ESP32C5 device - AGPIO(GPIO_USER), // 0 IO GPIO0 - AGPIO(GPIO_USER), // 1 AO GPIO1, ADC1_CH0 - AGPIO(GPIO_USER), // 2 AO GPIO2, ADC1_CH1 - AGPIO(GPIO_USER), // 3 AO GPIO3, ADC1_CH2 - AGPIO(GPIO_USER), // 4 AO GPIO4, ADC1_CH3 - AGPIO(GPIO_USER), // 5 AO GPIO5, ADC1_CH4 - AGPIO(GPIO_USER), // 6 AO GPIO6, ADC1_CH5 - AGPIO(GPIO_USER), // 7 AO GPIO7, ADC1_CH6 - AGPIO(GPIO_USER), // 8 IO GPIO8 - AGPIO(GPIO_USER), // 9 IO GPIO9 - AGPIO(GPIO_USER), // 10 IO GPIO10 - AGPIO(GPIO_USER), // 11 IO GPIO11 - AGPIO(GPIO_USER), // 12 IO GPIO12 - AGPIO(GPIO_USER), // 13 IO GPIO13 - AGPIO(GPIO_USER), // 14 IO GPIO14 - AGPIO(GPIO_USER), // 15 IO GPIO15 - AGPIO(GPIO_USER), // 16 IO GPIO16 - AGPIO(GPIO_USER), // 17 IO GPIO17 - AGPIO(GPIO_USER), // 18 IO GPIO18 - AGPIO(GPIO_USER), // 19 IO GPIO19 - AGPIO(GPIO_USER), // 20 IO GPIO20 - AGPIO(GPIO_USER), // 21 IO GPIO21 - AGPIO(GPIO_USER), // 22 IO GPIO22 - AGPIO(GPIO_USER), // 23 IO GPIO23 - 0, // 24 FL GPIO24, Flash - 0, // 25 FL GPIO25, Flash - 0, // 26 FL GPIO26, Flash - 0 // Flag - }, -}; - -/*********************************************************************************************\ - Known templates -\*********************************************************************************************/ - -#elif CONFIG_IDF_TARGET_ESP32C6 -/********************************************************************************************\ - * ESP32-C6 Module templates -\********************************************************************************************/ - -#define USER_MODULE 255 - -// Supported hardware modules -enum SupportedModulesESP32C6 { - WEMOS, // not really correct, a placeholder for now - MAXMODULE }; - -// Default module settings -const uint8_t kModuleNiceList[] PROGMEM = { - WEMOS, -}; - -// !!! Update this list in the same order as kModuleNiceList !!! -const char kModuleNames[] PROGMEM = - "ESP32C6|" - ; - -// !!! Update this list in the same order as SupportedModulesESP32C6 !!! -const mytmplt kModules[] PROGMEM = { - { // Generic ESP32C6 device - AGPIO(GPIO_USER), // 0 IO GPIO0, ADC1_CH0, LP_GPIO0 - AGPIO(GPIO_USER), // 1 IO GPIO1, ADC1_CH1, LP_GPIO1 - AGPIO(GPIO_USER), // 2 IO GPIO2, ADC1_CH2, LP_GPIO2 - AGPIO(GPIO_USER), // 3 IO GPIO3, ADC1_CH3, LP_GPIO3 - AGPIO(GPIO_USER), // 4 IO GPIO4, ADC1_CH4, LP_GPIO4, Strapping - AGPIO(GPIO_USER), // 5 IO GPIO5, ADC1_CH5, LP_GPIO5, Strapping - AGPIO(GPIO_USER), // 6 IO GPIO6, ADC1_CH6, LP_GPIO6 - AGPIO(GPIO_USER), // 7 IO GPIO7, LP_GPIO7 - AGPIO(GPIO_USER), // 8 IO GPIO8, Strapping - AGPIO(GPIO_USER), // 9 IO GPIO9, Strapping - AGPIO(GPIO_USER), // 10 IO GPIO10 (QFN40 only) - AGPIO(GPIO_USER), // 11 IO GPIO11 (QFN40 only) - AGPIO(GPIO_USER), // 12 IO GPIO12, USB-JTAG - AGPIO(GPIO_USER), // 13 IO GPIO13, USB-JTAG - AGPIO(GPIO_USER), // 14 IO GPIO14 (QFN32 only) - AGPIO(GPIO_USER), // 15 IO GPIO15, Strapping - AGPIO(GPIO_USER), // 16 IO TXD0 GPIO16, U0TXD - AGPIO(GPIO_USER), // 17 IO RXD0 GPIO17, U0RXD - AGPIO(GPIO_USER), // 18 IO GPIO18, SDIO_CMD - AGPIO(GPIO_USER), // 19 IO GPIO19, SDIO_CLK - AGPIO(GPIO_USER), // 20 IO GPIO20, SDIO_DATA0 - AGPIO(GPIO_USER), // 21 IO GPIO21, SDIO_DATA1 - AGPIO(GPIO_USER), // 22 IO GPIO22, SDIO_DATA2 - AGPIO(GPIO_USER), // 23 IO GPIO23, SDIO_DATA3 - 0, // 24 IO GPIO24, SPICS1, PSRAM - 0, // 25 IO GPIO25, SPIQ - 0, // 26 IO GPIO26, SPIWP - Free if flash DIO/DOUT - 0, // 27 IO GPIO27, SPIVDD - 0, // 28 IO GPIO28, SPIHD - Free if flash DIO/DOUT - 0, // 29 IO GPIO29, SPICLK - 0, // 30 IO GPIO30, SPID - 0 // Flag - }, -}; - -/*********************************************************************************************\ - Known templates -\*********************************************************************************************/ -#elif CONFIG_IDF_TARGET_ESP32P4 -/********************************************************************************************\ - * ESP32-P4 Module templates -\********************************************************************************************/ - -#define USER_MODULE 255 - -#define WT32_ETH01 4 //TODO: Why needed? - -// Supported hardware modules -enum SupportedModulesESP32P4 { - WEMOS, // not really correct, a placeholder for now - MAXMODULE }; - -// Default module settings -const uint8_t kModuleNiceList[] PROGMEM = { - WEMOS, -}; - -// !!! Update this list in the same order as kModuleNiceList !!! -const char kModuleNames[] PROGMEM = - "ESP32P4|" - ; - -// !!! Update this list in the same order as SupportedModulesESP32P4 !!! -const mytmplt kModules[] PROGMEM = { - { // Generic ESP32P4 device - AGPIO(GPIO_USER), // 0 IO GPIO0, LP_GPIO0 - AGPIO(GPIO_USER), // 1 IO GPIO1, LP_GPIO1 - AGPIO(GPIO_USER), // 2 IO GPIO2, TOUCH0, LP_GPIO2 - AGPIO(GPIO_USER), // 3 IO GPIO3, TOUCH1, LP_GPIO3 - AGPIO(GPIO_USER), // 4 IO GPIO4, TOUCH2, LP_GPIO4 - AGPIO(GPIO_USER), // 5 IO GPIO5, TOUCH3, LP_GPIO5 - AGPIO(GPIO_USER), // 6 IO GPIO6, TOUCH4, LP_GPIO6 - AGPIO(GPIO_USER), // 7 IO GPIO7, TOUCH5, LP_GPIO7 - AGPIO(GPIO_USER), // 8 IO GPIO8, TOUCH6, LP_GPIO8 - AGPIO(GPIO_USER), // 9 IO GPIO9, TOUCH7, LP_GPIO9 - AGPIO(GPIO_USER), // 10 IO GPIO10, TOUCH8, LP_GPIO10 - AGPIO(GPIO_USER), // 11 IO GPIO11, TOUCH9, LP_GPIO11 - AGPIO(GPIO_USER), // 12 IO GPIO12, TOUCH10, LP_GPIO12 - AGPIO(GPIO_USER), // 13 IO GPIO13, TOUCH11, LP_GPIO13 - AGPIO(GPIO_USER), // 14 IO GPIO14, TOUCH12, LP_GPIO14, SDIO2_D0 ESPHosted (ESP32C6 GPIO20) - AGPIO(GPIO_USER), // 15 IO GPIO15, TOUCH13, LP_GPIO15, SDIO2_D1 ESPHosted (ESP32C6 GPIO21) - AGPIO(GPIO_USER), // 16 IO GPIO16, ADC1_CH0, SDIO2_D2 ESPHosted (ESP32C6 GPIO22) - AGPIO(GPIO_USER), // 17 IO GPIO17, ADC1_CH1, SDIO2_D3 ESPHosted (ESP32C6 GPIO23) - AGPIO(GPIO_USER), // 18 IO GPIO18, ADC1_CH2, SDIO2_CLK ESPHosted (ESP32C6 GPIO19) - AGPIO(GPIO_USER), // 19 IO GPIO19, ADC1_CH3, SDIO2_CMD ESPHosted (ESP32C6 GPIO18) - AGPIO(GPIO_USER), // 20 IO GPIO20, ADC1_CH4 - AGPIO(GPIO_USER), // 21 IO GPIO21, ADC1_CH5 - AGPIO(GPIO_USER), // 22 IO GPIO22, ADC1_CH6 - AGPIO(GPIO_USER), // 23 IO GPIO23, ADC1_CH7 - AGPIO(GPIO_USER), // 24 IO GPIO24 - AGPIO(GPIO_USER), // 25 IO GPIO25 - AGPIO(GPIO_USER), // 26 IO GPIO26 - AGPIO(GPIO_USER), // 27 IO GPIO27 - AGPIO(GPIO_USER), // 28 IO GPIO28 - AGPIO(GPIO_USER), // 29 IO GPIO29 - AGPIO(GPIO_USER), // 30 IO GPIO30 - AGPIO(GPIO_USER), // 31 IO GPIO31 - AGPIO(GPIO_USER), // 32 IO GPIO32 - AGPIO(GPIO_USER), // 33 IO GPIO33 - AGPIO(GPIO_USER), // 34 IO GPIO34, Strapping pin - AGPIO(GPIO_USER), // 35 IO GPIO35, Strapping pin - AGPIO(GPIO_USER), // 36 IO GPIO36, Strapping pin - AGPIO(GPIO_USER), // 37 IO GPIO37, Strapping pin - AGPIO(GPIO_USER), // 38 IO GPIO38, Strapping pin - AGPIO(GPIO_USER), // 39 IO GPIO39 - AGPIO(GPIO_USER), // 40 IO GPIO40 - AGPIO(GPIO_USER), // 41 IO GPIO41 - AGPIO(GPIO_USER), // 42 IO GPIO42 - AGPIO(GPIO_USER), // 43 IO GPIO43 - AGPIO(GPIO_USER), // 44 IO GPIO44 - AGPIO(GPIO_USER), // 45 IO GPIO45 - AGPIO(GPIO_USER), // 46 IO GPIO46 - AGPIO(GPIO_USER), // 47 IO GPIO47 - AGPIO(GPIO_USER), // 48 IO GPIO48 - AGPIO(GPIO_USER), // 49 IO GPIO49, ADC1_CH8 - AGPIO(GPIO_USER), // 50 IO GPIO50, ADC1_CH9 - AGPIO(GPIO_USER), // 51 IO GPIO51, ADC1_CH10, ANA_CMPR_CH0 reference voltage - AGPIO(GPIO_USER), // 52 IO GPIO52, ADC1_CH11, ANA_CMPR_CH0 input (non-inverting) - AGPIO(GPIO_USER), // 53 IO GPIO53, ADC1_CH12, ANA_CMPR_CH1 reference voltage - AGPIO(GPIO_USER), // 54 IO GPIO54, ADC1_CH13, ANA_CMPR_CH1 input (non-inverting) - 0 // Flag - }, -}; - -/*********************************************************************************************\ - Known templates -\*********************************************************************************************/ - -#elif CONFIG_IDF_TARGET_ESP32S2 -/********************************************************************************************\ - * ESP32-S2 Module templates -\********************************************************************************************/ - -#define USER_MODULE 255 - -// Supported hardware modules -enum SupportedModulesESP32S2 { - WEMOS, - MAXMODULE }; - -// Default module settings -const uint8_t kModuleNiceList[] PROGMEM = { - WEMOS, -}; - -// !!! Update this list in the same order as kModuleNiceList !!! -const char kModuleNames[] PROGMEM = - "ESP32S2|" - ; - -// !!! Update this list in the same order as SupportedModulesESP32S2 !!! -const mytmplt kModules[] PROGMEM = { - { // Generic ESP32C3 device - AGPIO(GPIO_USER), // 0 IO GPIO0, RTC_GPIO0, Strapping - AGPIO(GPIO_USER), // 1 AO GPIO1, ADC1_CH0, RTC_GPIO1 - AGPIO(GPIO_USER), // 2 AO GPIO2, ADC1_CH1, RTC_GPIO2 - AGPIO(GPIO_USER), // 3 AO GPIO3, ADC1_CH2, RTC_GPIO3 - AGPIO(GPIO_USER), // 4 AO GPIO4, ADC1_CH3, RTC_GPIO4 - AGPIO(GPIO_USER), // 5 AO GPIO5, ADC1_CH4, RTC_GPIO5 - AGPIO(GPIO_USER), // 6 AO GPIO6, ADC1_CH5, RTC_GPIO6 - AGPIO(GPIO_USER), // 7 AO GPIO7, ADC1_CH6, RTC_GPIO7 - AGPIO(GPIO_USER), // 8 AO GPIO8, ADC1_CH7, RTC_GPIO8 - AGPIO(GPIO_USER), // 9 AO GPIO9, ADC1_CH8, RTC_GPIO9 - AGPIO(GPIO_USER), // 10 AO GPIO10, ADC1_CH9, RTC_GPIO10 - AGPIO(GPIO_USER), // 11 AO GPIO11, ADC2_CH0, RTC_GPIO11 - AGPIO(GPIO_USER), // 12 AO GPIO12, ADC2_CH1, RTC_GPIO12 - AGPIO(GPIO_USER), // 13 AO GPIO13, ADC2_CH2, RTC_GPIO13 - AGPIO(GPIO_USER), // 14 AO GPIO14, ADC2_CH3, RTC_GPIO14 - AGPIO(GPIO_USER), // 15 AO GPIO15, ADC2_CH4, RTC_GPIO15, XTAL_32K_P - AGPIO(GPIO_USER), // 16 AO GPIO16, ADC2_CH5, RTC_GPIO16, XTAL_32K_N - AGPIO(GPIO_USER), // 17 AO GPIO17, ADC2_CH6, RTC_GPIO17, DAC_1 - AGPIO(GPIO_USER), // 18 AO GPIO18, ADC2_CH7, RTC_GPIO18, DAC_2 - AGPIO(GPIO_USER), // 19 AO GPIO19, ADC2_CH8, RTC_GPIO19 - AGPIO(GPIO_USER), // 20 AO GPIO20, ADC2_CH9, RTC_GPIO20 - AGPIO(GPIO_USER), // 21 IO GPIO21, RTC_GPIO21 - // 22 -- Unused - // 23 -- Unused - // 24 -- Unused - // 25 -- Unused - // 26 FL SPICS1, PSRAM - // 27 FL SPIHD - // 28 FL SPIWP - // 29 FL SPICS0 - // 30 FL SPICLK - // 31 FL SPIQ - // 32 FL SPID - AGPIO(GPIO_USER), // 33 IO GPIO33 - AGPIO(GPIO_USER), // 34 IO GPIO34 - AGPIO(GPIO_USER), // 35 IO GPIO35 - AGPIO(GPIO_USER), // 36 IO GPIO36 - AGPIO(GPIO_USER), // 37 IO GPIO37 - AGPIO(GPIO_USER), // 38 IO GPIO38 - AGPIO(GPIO_USER), // 39 IO GPIO39, JTAG MTCK - AGPIO(GPIO_USER), // 40 IO GPIO40, JTAG MTDO - AGPIO(GPIO_USER), // 41 IO GPIO41, JTAG MTDI - AGPIO(GPIO_USER), // 42 IO GPIO42, JTAG MTMS - AGPIO(GPIO_USER), // 43 IO GPIO43, U0TXD - AGPIO(GPIO_USER), // 44 IO GPIO44, U0RXD - AGPIO(GPIO_USER), // 45 IO GPIO45, Strapping - AGPIO(GPIO_USER), // 46 I GPIO46, Input only, Strapping - 0 // Flag - }, -}; - -/*********************************************************************************************\ - Known templates -\*********************************************************************************************/ - -#elif CONFIG_IDF_TARGET_ESP32S3 -/********************************************************************************************\ - * ESP32-S3 Module templates -\********************************************************************************************/ - -#define USER_MODULE 255 - -// Supported hardware modules -enum SupportedModulesESP32S3 { - WEMOS, - MAXMODULE }; - -// Default module settings -const uint8_t kModuleNiceList[] PROGMEM = { - WEMOS, -}; - -// !!! Update this list in the same order as kModuleNiceList !!! -const char kModuleNames[] PROGMEM = - "ESP32S3|" - ; - -// !!! Update this list in the same order as SupportedModulesESP32S2 !!! -const mytmplt kModules[] PROGMEM = { - { // Generic ESP32C3 device - AGPIO(GPIO_USER), // 0 IO RTC_GPIO0, GPIO0, Strapping - AGPIO(GPIO_USER), // 1 AO RTC_GPIO1, GPIO1, TOUCH1, ADC1_CH0 - AGPIO(GPIO_USER), // 2 AO RTC_GPIO2, GPIO2, TOUCH2, ADC1_CH1 - AGPIO(GPIO_USER), // 3 AO RTC_GPIO3, GPIO3, TOUCH3, ADC1_CH2, Strapping - AGPIO(GPIO_USER), // 4 AO RTC_GPIO4, GPIO4, TOUCH4, ADC1_CH3 - AGPIO(GPIO_USER), // 5 AO RTC_GPIO5, GPIO5, TOUCH5, ADC1_CH4 - AGPIO(GPIO_USER), // 6 AO RTC_GPIO6, GPIO6, TOUCH6, ADC1_CH5 - AGPIO(GPIO_USER), // 7 AO RTC_GPIO7, GPIO7, TOUCH7, ADC1_CH6 - AGPIO(GPIO_USER), // 8 AO RTC_GPIO8, GPIO8, TOUCH8, ADC1_CH7, SUBSPICS1 - AGPIO(GPIO_USER), // 9 AO RTC_GPIO9, GPIO9, TOUCH9, ADC1_CH8, SUBSPIHD, FSPIHD - AGPIO(GPIO_USER), // 10 AO RTC_GPIO10, GPIO10, TOUCH10, ADC1_CH9, FSPIIO4, SUBSPICS0, FSPICS0 - AGPIO(GPIO_USER), // 11 AO RTC_GPIO11, GPIO11, TOUCH11, ADC2_CH0, FSPIIO5, SUBSPID, FSPID - AGPIO(GPIO_USER), // 12 AO RTC_GPIO12, GPIO12, TOUCH12, ADC2_CH1, FSPIIO6, SUBSPICLK, FSPICLK - AGPIO(GPIO_USER), // 13 AO RTC_GPIO13, GPIO13, TOUCH13, ADC2_CH2, FSPIIO7, SUBSPIQ, FSPIQ - AGPIO(GPIO_USER), // 14 AO RTC_GPIO14, GPIO14, TOUCH14, ADC2_CH3, FSPIDQS, SUBSPIWP, FSPIWP - AGPIO(GPIO_USER), // 15 AO RTC_GPIO15, GPIO15, U0RTS, ADC2_CH4, XTAL_32K_P - AGPIO(GPIO_USER), // 16 AO RTC_GPIO16, GPIO16, U0CTS, ADC2_CH5, XTAL_32K_N - AGPIO(GPIO_USER), // 17 AO RTC_GPIO17, GPIO17, U1TXD, ADC2_CH6 - AGPIO(GPIO_USER), // 18 AO RTC_GPIO18, GPIO18, U1RXD, ADC2_CH7, CLK_OUT3 - AGPIO(GPIO_USER), // 19 AO RTC_GPIO19, GPIO19, U1RTS, ADC2_CH8, CLK_OUT2, USB_D­ - AGPIO(GPIO_USER), // 20 AO RTC_GPIO20, GPIO20, U1CTS, ADC2_CH9, CLK_OUT1, USB_D+ - AGPIO(GPIO_USER), // 21 IO RTC_GPIO21, GPIO21 - // 22 -- Unused - // 23 -- Unused - // 24 -- Unused - // 25 -- Unused - // 26 FL SPICS1, GPIO26 - // 27 FL SPIHD, GPIO27 - // 28 FL SPIWP, GPIO28 - // 29 FL SPICS0, GPIO29 - // 30 FL SPICLK, GPIO30 - // 31 FL SPIQ, GPIO31 - // 32 FL SPID, GPIO32 - AGPIO(GPIO_NONE), // 33 IO SPIIO4, GPIO33, FSPIHD, SUBSPIHD - AGPIO(GPIO_NONE), // 34 IO SPIIO5, GPIO34, FSPICS0, SUBSPICS0 - AGPIO(GPIO_NONE), // 35 IO SPIIO6, GPIO35, FSPID, SUBSPID - AGPIO(GPIO_NONE), // 36 IO SPIIO7, GPIO36, FSPICLK, SUBSPICLK - AGPIO(GPIO_NONE), // 37 IO SPIDQS, GPIO37, FSPIQ, SUBSPIQ - AGPIO(GPIO_USER), // 38 IO GPIO38, FSPIWP, SUBSPIWP - AGPIO(GPIO_USER), // 39 IO MTCK, GPIO39, CLK_OUT3, SUBSPICS1 - AGPIO(GPIO_USER), // 40 IO MTDO, GPIO40, CLK_OUT2 - AGPIO(GPIO_USER), // 41 IO MTDI, GPIO41, CLK_OUT1 - AGPIO(GPIO_USER), // 42 IO MTMS, GPIO42 - AGPIO(GPIO_USER), // 43 IO U0TXD, GPIO43, CLK_OUT1 - AGPIO(GPIO_USER), // 44 IO U0RXD, GPIO44, CLK_OUT2 - AGPIO(GPIO_USER), // 45 IO GPIO45, Strapping - AGPIO(GPIO_USER), // 46 IO GPIO46, Strapping - AGPIO(GPIO_USER), // 47 IO SPICLK_P_DIFF, GPIO47, SUBSPICLK_P_DIFF - AGPIO(GPIO_USER), // 48 IO SPICLK_N_DIFF, GPIO48, SUBSPICLK_N_DIFF - 0 // Flag - }, -}; - -/*********************************************************************************************\ - Known templates -\*********************************************************************************************/ - -#else // not CONFIG_IDF_TARGET_ESP32C2/C3/C6 nor CONFIG_IDF_TARGET_ESP32S2 - ESP32 -/********************************************************************************************\ - * ESP32 Module templates -\********************************************************************************************/ - -#define USER_MODULE 255 - -// Supported hardware modules -enum SupportedModulesESP32 { - WEMOS, - ESP32_CAM_AITHINKER, - ODROID_GO, - ESP32_SOLO, - WT32_ETH01, - MAXMODULE }; - -// Default module settings -const uint8_t kModuleNiceList[] PROGMEM = { - WEMOS, -#ifdef USE_WEBCAM - ESP32_CAM_AITHINKER, -#endif // USE_WEBCAM -#ifdef USE_ODROID_GO - ODROID_GO, -#endif // USE_ODROID_GO -#ifdef USE_ESP32_SOLO -// ESP32_SOLO, // To be defined -#endif // USE_ESP32_SOLO -#ifdef USE_WT32_ETH01 - WT32_ETH01, -#endif // USE_WT32_ETH01 -}; - -// !!! Update this list in the same order as kModuleNiceList !!! -const char kModuleNames[] PROGMEM = - "ESP32-DevKit|" -#ifdef USE_WEBCAM - "ESP32-Cam|" -#endif // USE_WEBCAM -#ifdef USE_ODROID_GO - "Odroid Go|" -#endif // USE_ODROID_GO -#ifdef USE_ESP32_SOLO -// "ESP32-Solo|" // To be defined -#endif // USE_ESP32_SOLO -#ifdef USE_WT32_ETH01 - "WT32-Eth01|" -#endif // USE_WT32_ETH01 - ; - -// !!! Update this list in the same order as SupportedModulesESP32 !!! -const mytmplt kModules[] PROGMEM = { - { // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32) - AGPIO(GPIO_USER), // 0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK - AGPIO(GPIO_USER), // 1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 - AGPIO(GPIO_USER), // 2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 - AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD, CLK_OUT2 - AGPIO(GPIO_USER), // 4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER - AGPIO(GPIO_USER), // 5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK - // 6 IO Remapped to 28 - // 7 IO Remapped to 29 - // 8 IO Remapped to 30 - AGPIO(GPIO_USER), // 9 IO GPIO9, Flash D2, U1RXD - AGPIO(GPIO_USER), // 10 IO GPIO10, Flash D3, U1TXD - // 11 IO Remapped to 31 - AGPIO(GPIO_USER), // 12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.) - AGPIO(GPIO_USER), // 13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER - AGPIO(GPIO_USER), // 14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 - AGPIO(GPIO_USER), // 15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.) - AGPIO(GPIO_USER), // 16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT - AGPIO(GPIO_USER), // 17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180 - AGPIO(GPIO_USER), // 18 IO GPIO18, VSPICLK, HS1_DATA7 - AGPIO(GPIO_USER), // 19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0 - 0, // 20 - AGPIO(GPIO_USER), // 21 IO GPIO21, VSPIHD, EMAC_TX_EN - AGPIO(GPIO_USER), // 22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1 - AGPIO(GPIO_USER), // 23 IO GPIO23, VSPID, HS1_STROBE - 0, // 24 - AGPIO(GPIO_USER), // 25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 - AGPIO(GPIO_USER), // 26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 - AGPIO(GPIO_USER), // 27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV - 0, // 6 IO GPIO6, Flash CLK - 0, // 7 IO GPIO7, Flash D0 - 0, // 8 IO GPIO8, Flash D1 - 0, // 11 IO GPIO11, Flash CMD - AGPIO(GPIO_USER), // 32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9 - AGPIO(GPIO_USER), // 33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8 - AGPIO(GPIO_USER), // 34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4 - AGPIO(GPIO_USER), // 35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5 - AGPIO(GPIO_USER), // 36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0 - 0, // 37 NO PULLUP - 0, // 38 NO PULLUP - AGPIO(GPIO_USER), // 39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3 - 0 // Flag - }, - -#ifdef USE_WEBCAM - { // ESP32_CAM_AITHINKER - Any ESP32 device with webcam (ESP32) - AGPIO(GPIO_WEBCAM_XCLK), // 0 (I)O GPIO0, CAM_XCLK - AGPIO(GPIO_USER), // 1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 - AGPIO(GPIO_SPI_MISO), // 2 IO GPIO2, VSPI_MISO - AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD, CLK_OUT2 - AGPIO(GPIO_PWM1), // 4 IO GPIO4, Flashlight - AGPIO(GPIO_WEBCAM_DATA), // 5 IO GPIO5, CAM_DATA1 - // 6 IO Remapped to 28 - // 7 IO Remapped to 29 - // 8 IO Remapped to 30 - AGPIO(GPIO_USER), // 9 IO GPIO9, Flash D2, U1RXD - AGPIO(GPIO_USER), // 10 IO GPIO10, Flash D3, U1TXD - // 11 IO Remapped to 31 - AGPIO(GPIO_USER), // 12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.) - AGPIO(GPIO_SDCARD_CS), // 13 IO GPIO13, VSPI_CS_TFLASH - AGPIO(GPIO_SPI_CLK), // 14 IO GPIO14, VSPI_CLK - AGPIO(GPIO_SPI_MOSI), // 15 (I)O GPIO15, VSPI_MOSI (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.) - AGPIO(GPIO_USER), // 16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT - AGPIO(GPIO_USER), // 17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180 - AGPIO(GPIO_WEBCAM_DATA) +1, // 18 IO GPIO18, CAM_DATA2 - AGPIO(GPIO_WEBCAM_DATA) +2, // 19 IO GPIO19, CAM_DATA3 - 0, // 20 - AGPIO(GPIO_WEBCAM_DATA) +3, // 21 IO GPIO21, CAM_DATA4 - AGPIO(GPIO_WEBCAM_PCLK), // 22 IO LED GPIO22, CAM_PCLK - AGPIO(GPIO_WEBCAM_HREF), // 23 IO GPIO23, CAM_HREF - 0, // 24 - AGPIO(GPIO_WEBCAM_VSYNC), // 25 IO GPIO25, CAM_VSYNC - AGPIO(GPIO_WEBCAM_SIOD), // 26 IO GPIO26, CAM_SIOD - AGPIO(GPIO_WEBCAM_SIOC), // 27 IO GPIO27, CAM_SIOC - 0, // 6 IO GPIO6, Flash CLK - 0, // 7 IO GPIO7, Flash D0 - 0, // 8 IO GPIO8, Flash D1 - 0, // 11 IO GPIO11, Flash CMD - AGPIO(GPIO_WEBCAM_PWDN), // 32 IO GPIO32, CAM_PWDN - AGPIO(GPIO_USER), // 33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8 - AGPIO(GPIO_WEBCAM_DATA) +6, // 34 I NO PULLUP GPIO34, CAM_DATA7 - AGPIO(GPIO_WEBCAM_DATA) +7, // 35 I NO PULLUP GPIO35, CAM_DATA8 - AGPIO(GPIO_WEBCAM_DATA) +4, // 36 I NO PULLUP GPIO36, CAM_DATA5 - 0, // 37 NO PULLUP - 0, // 38 NO PULLUP - AGPIO(GPIO_WEBCAM_DATA) +5, // 39 I NO PULLUP GPIO39, CAM_DATA6 - 0 // Flag - }, -#endif // USE_WEBCAM - -#ifdef USE_ODROID_GO - { // ODROID_GO - (ESP32) - AGPIO(GPIO_KEY1), // 0 (I)O GPIO0, BTN-VOLUME - AGPIO(GPIO_TXD), // 1 IO TXD0 GPIO1, TXD0 - AGPIO(GPIO_LEDLNK), // 2 IO GPIO2, STATUS LED - AGPIO(GPIO_RXD), // 3 IO RXD0 GPIO3, RXD0 - AGPIO(GPIO_USER), // 4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER - AGPIO(GPIO_ILI9341_CS), // 5 IO GPIO5, VSPI_CS0_LCD - // 6 IO Remapped to 28 - // 7 IO Remapped to 29 - // 8 IO Remapped to 30 - 0, // 9 IO GPIO9, Flash D2, U1RXD - 0, // 10 IO GPIO10, Flash D3, U1TXD - // 11 IO Remapped to 31 - AGPIO(GPIO_USER), // 12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.) - AGPIO(GPIO_KEY1) +1, // 13 IO GPIO13, BTN-MENU - AGPIO(GPIO_PWM1), // 14 IO GPIO14, LCD Backlight - AGPIO(GPIO_USER), // 15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.) - AGPIO(GPIO_USER), // 16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT - AGPIO(GPIO_USER), // 17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180 - AGPIO(GPIO_SPI_CLK), // 18 IO GPIO18, VSPI_CLK - AGPIO(GPIO_SPI_MISO), // 19 IO GPIO19, VSPI_MISO - 0, // 20 - AGPIO(GPIO_ILI9341_DC), // 21 IO GPIO21, SPI_DC_LCD - AGPIO(GPIO_SDCARD_CS), // 22 IO LED GPIO22, VSPI_CS1_TFLASH - AGPIO(GPIO_SPI_MOSI), // 23 IO GPIO23, VSPI_MOSI - 0, // 24 - 0, // 25 IO GPIO25, DAC_1 (PAM8304A) - 0, // 26 IO GPIO26, DAC_2 (PAM8304A) - AGPIO(GPIO_KEY1) +2, // 27 IO GPIO27, BTN-SELECT - 0, // 6 IO GPIO6, Flash CLK - 0, // 7 IO GPIO7, Flash D0 - 0, // 8 IO GPIO8, Flash D1 - 0, // 11 IO GPIO11, Flash CMD - AGPIO(GPIO_SWT1) +4, // 32 IO GPIO32, BTN-A - AGPIO(GPIO_SWT1) +5, // 33 IO GPIO33, BTN-B - AGPIO(GPIO_ADC_JOY), // 34 I NO PULLUP GPIO34, JOY-X (LEFT-RIGHT) - AGPIO(GPIO_ADC_JOY) +1, // 35 I NO PULLUP GPIO35, JOY-Y (UP-DOWN) - AGPIO(GPIO_ADC_RANGE) +2, // 36 I NO PULLUP GPIO36, SENSOR_VP (BATTERY CARGER) - 0, // 37 NO PULLUP - 0, // 38 NO PULLUP - AGPIO(GPIO_KEY1) +3, // 39 I NO PULLUP GPIO39, BTN-START - 0 // Flag - }, -#endif // USE_ODROID_GO - -#ifdef USE_ESP32_SOLO -// { // ESP32 Solo (ESP32) - To be defined -// }, -#endif // USE_ESP32_SOLO - -#ifdef USE_WT32_ETH01 - { // WT32_ETH01 - (ESP32) - 0, // 0 (I)O GPIO0, Ethernet EMAC_REF_CLK - AGPIO(GPIO_USER), // 1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 - AGPIO(GPIO_USER), // 2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 - AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD, CLK_OUT2 - AGPIO(GPIO_USER), // 4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER - AGPIO(GPIO_USER), // 5 IO GPIO5, RXD Led green - // 6 IO Remapped to 28 - // 7 IO Remapped to 29 - // 8 IO Remapped to 30 - 0, // 9 IO GPIO9, Flash D2, U1RXD - 0, // 10 IO GPIO10, Flash D3, U1TXD - // 11 IO Remapped to 31 - AGPIO(GPIO_USER), // 12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.) - 0, // 13 IO GPIO13, Ethernet EMAC_RX_ER - AGPIO(GPIO_USER), // 14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 - AGPIO(GPIO_USER), // 15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.) - AGPIO(GPIO_OUTPUT_HI), // 16 IO GPIO16, Ethernet OSC_ENA - AGPIO(GPIO_LEDLNK_INV), // 17 IO GPIO17, Network link led (green) - AGPIO(GPIO_ETH_PHY_MDIO), // 18 IO GPIO18, Ethernet MDIO - 0, // 19 IO GPIO19, Ethernet TXD0 - 0, // 20 - 0, // 21 IO GPIO21, Ethernet EMAC_TX_EN - 0, // 22 IO LED GPIO22, Ethernet EMAC_TXD1 - AGPIO(GPIO_ETH_PHY_MDC), // 23 IO GPIO23, Ethernet MDC - 0, // 24 - 0, // 25 IO GPIO25, Ethernet EMAC_RXD0 - 0, // 26 IO GPIO26, Ethernet EMAC_RXD1 - 0, // 27 IO GPIO27, Ethernet EMAC_RX_DV - 0, // 6 IO GPIO6, Flash CLK - 0, // 7 IO GPIO7, Flash D0 - 0, // 8 IO GPIO8, Flash D1 - 0, // 11 IO GPIO11, Flash CMD - AGPIO(GPIO_USER), // 32 IO GPIO32, CFG - AGPIO(GPIO_USER), // 33 IO GPIO33, 485_EN - 0, // 34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4 - AGPIO(GPIO_USER), // 35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5 - AGPIO(GPIO_USER), // 36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0 - 0, // 37 NO PULLUP - 0, // 38 NO PULLUP - AGPIO(GPIO_USER), // 39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3 - 0 // Flag - }, -#endif // USE_WT32_ETH01 - -}; - -/*********************************************************************************************\ - Known templates - -{"NAME":"AITHINKER CAM","GPIO":[4992,1,1,1,1,5088,1,1,1,1,1,1,1,1,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,1,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} -{"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} -{"NAME":"wESP32","GPIO":[1,1,1,1,1,1,0,0,0,1,1,1,5568,5600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} -{"NAME":"Denky (Teleinfo)","GPIO":[1,1,1,1,5664,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1376,1,1,0,0,0,0,1,5632,1,1,1,0,0,1],"FLAG":0,"BASE":1} - -\*********************************************************************************************/ - -#endif // ESP32/S2/C3 selection -#endif // ESP32 - -#endif // _TASMOTA_TEMPLATE_H_ +/* + tasmota_template.h - template settings for Tasmota + + Copyright (C) 2021 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _TASMOTA_TEMPLATE_H_ +#define _TASMOTA_TEMPLATE_H_ + +// User selectable GPIO functionality +// ATTENTION: Only add at the end of this list just before GPIO_SENSOR_END +// Then add the same name(s) in a nice location in array kGpioNiceList +enum UserSelectablePins { + GPIO_NONE, // Not used + GPIO_KEY1, GPIO_KEY1_NP, GPIO_KEY1_INV, GPIO_KEY1_INV_NP, // 4 x Button + GPIO_SWT1, GPIO_SWT1_NP, // 8 x User connected external switches + GPIO_REL1, GPIO_REL1_INV, // 8 x Relays + GPIO_LED1, GPIO_LED1_INV, // 4 x Leds + GPIO_CNTR1, GPIO_CNTR1_NP, // 4 x Counter + GPIO_PWM1, GPIO_PWM1_INV, // 5 x PWM + GPIO_BUZZER, GPIO_BUZZER_INV, // Buzzer + GPIO_LEDLNK, GPIO_LEDLNK_INV, // Link led + GPIO_I2C_SCL, GPIO_I2C_SDA, // Software I2C + GPIO_SPI_MISO, GPIO_SPI_MOSI, GPIO_SPI_CLK, GPIO_SPI_CS, GPIO_SPI_DC, // Hardware SPI + GPIO_SSPI_MISO, GPIO_SSPI_MOSI, GPIO_SSPI_SCLK, GPIO_SSPI_CS, GPIO_SSPI_DC, // Software SPI + GPIO_BACKLIGHT, // Display backlight control + GPIO_OLED_RESET, // OLED Display Reset + GPIO_IRSEND, GPIO_IRRECV, // IR interface + GPIO_RFSEND, GPIO_RFRECV, // RF interface + GPIO_DHT11, GPIO_DHT22, GPIO_SI7021, GPIO_DHT11_OUT, // DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 + GPIO_DSB, GPIO_DSB_OUT, // DS18B20 or DS18S20 + GPIO_WS2812, // WS2812 Led string + GPIO_MHZ_TXD, GPIO_MHZ_RXD, // MH-Z19 Serial interface + GPIO_PZEM0XX_TX, GPIO_PZEM004_RX, GPIO_PZEM016_RX, GPIO_PZEM017_RX, // PZEM Serial Modbus interface + GPIO_SAIR_TX, GPIO_SAIR_RX, // SenseAir Serial interface + GPIO_PMS5003_TX, GPIO_PMS5003_RX, // Plantower PMS5003 Serial interface + GPIO_SDS0X1_TX, GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface + GPIO_SBR_TX, GPIO_SBR_RX, // Serial Bridge Serial interface + GPIO_SR04_TRIG, GPIO_SR04_ECHO, // SR04 interface + GPIO_SDM120_TX, GPIO_SDM120_RX, // SDM120 Serial interface + GPIO_SDM630_TX, GPIO_SDM630_RX, // SDM630 Serial interface + GPIO_TM1638CLK, GPIO_TM1638DIO, GPIO_TM1638STB, // TM1638 interface + GPIO_MP3_DFR562, // RB-DFR-562, DFPlayer Mini MP3 Player + GPIO_HX711_SCK, GPIO_HX711_DAT, // HX711 Load Cell interface + GPIO_TX2X_TXD_BLACK, // TX20/TX23 Transmission Pin + GPIO_TUYA_TX, GPIO_TUYA_RX, // Tuya Serial interface + GPIO_MGC3130_XFER, GPIO_MGC3130_RESET, // MGC3130 interface + GPIO_RF_SENSOR, // Rf receiver with sensor decoding + GPIO_AZ_TXD, GPIO_AZ_RXD, // AZ-Instrument 7798 Serial interface + GPIO_MAX31855CS, GPIO_MAX31855CLK, GPIO_MAX31855DO, // MAX31855 Serial interface + GPIO_NRG_SEL, GPIO_NRG_SEL_INV, GPIO_NRG_CF1, GPIO_HLW_CF, GPIO_HJL_CF, // HLW8012/HJL-01/BL0937 energy monitoring + GPIO_MCP39F5_TX, GPIO_MCP39F5_RX, GPIO_MCP39F5_RST, // MCP39F501 Energy monitoring (Shelly2) + GPIO_PN532_TXD, GPIO_PN532_RXD, // PN532 NFC Serial interface + GPIO_SM16716_CLK, GPIO_SM16716_DAT, GPIO_SM16716_SEL, // SM16716 SELECT + GPIO_DI, GPIO_DCKI, // my92x1 PWM controller + GPIO_CSE7766_TX, GPIO_CSE7766_RX, // CSE7766 Serial interface (S31 and Pow R2) + GPIO_ARIRFRCV, GPIO_ARIRFSEL, // Arilux RF Receive input + GPIO_TXD, GPIO_RXD, // Serial interface + GPIO_ROT1A, GPIO_ROT1B, // Rotary switch + GPIO_ADC_JOY, // Analog joystick + GPIO_SSPI_MAX31865_CS1, // MAX31865 Chip Select + GPIO_HRE_CLOCK, GPIO_HRE_DATA, // HR-E Water Meter + GPIO_ADE7953_IRQ, // ADE7953 IRQ + GPIO_SOLAXX1_TX, GPIO_SOLAXX1_RX, // Solax Inverter Serial interface + GPIO_ZIGBEE_TX, GPIO_ZIGBEE_RX, // Zigbee Serial interface + GPIO_RDM6300_RX, // RDM6300 RX + GPIO_IBEACON_TX, GPIO_IBEACON_RX, // HM17 IBEACON Serial interface + GPIO_A4988_DIR, GPIO_A4988_STP, GPIO_A4988_ENA, GPIO_A4988_MS1, // A4988 interface + GPIO_OUTPUT_HI, GPIO_OUTPUT_LO, // Fixed output state + GPIO_DDS2382_TX, GPIO_DDS2382_RX, // DDS2382 Serial interface + GPIO_DDSU666_TX, GPIO_DDSU666_RX, // DDSU666 Serial interface + GPIO_SM2135_CLK, GPIO_SM2135_DAT, // SM2135 PWM controller + GPIO_DEEPSLEEP, // Kill switch for deepsleep + GPIO_EXS_ENABLE, // EXS MCU Enable + GPIO_TASMOTACLIENT_TXD, GPIO_TASMOTACLIENT_RXD, // Client Serial interface + GPIO_TASMOTACLIENT_RST, GPIO_TASMOTACLIENT_RST_INV, // Client Reset + GPIO_HPMA_RX, GPIO_HPMA_TX, // Honeywell HPMA115S0 Serial interface + GPIO_GPS_RX, GPIO_GPS_TX, // GPS Serial interface + GPIO_HM10_RX, GPIO_HM10_TX, // HM10-BLE-Mijia-bridge Serial interface + GPIO_LE01MR_RX, GPIO_LE01MR_TX, // F&F LE-01MR energy meter + GPIO_CC1101_GDO0, GPIO_CC1101_GDO2, // CC1101 Serial interface + GPIO_HRXL_RX, // Data from MaxBotix HRXL sonar range sensor + GPIO_ELECTRIQ_MOODL_TX, // ElectriQ iQ-wifiMOODL Serial TX + GPIO_AS3935, // Franklin Lightning Sensor + GPIO_ADC_INPUT, // Analog input + GPIO_ADC_TEMP, // Analog Thermistor + GPIO_ADC_LIGHT, // Analog Light sensor + GPIO_ADC_BUTTON, GPIO_ADC_BUTTON_INV, // Analog Button + GPIO_ADC_RANGE, // Analog Range + GPIO_ADC_CT_POWER, // ANalog Current +#ifdef ESP32 + GPIO_WEBCAM_PWDN, GPIO_WEBCAM_RESET, GPIO_WEBCAM_XCLK, // Webcam + GPIO_WEBCAM_SIOD, GPIO_WEBCAM_SIOC, // Webcam I2C + GPIO_WEBCAM_DATA, + GPIO_WEBCAM_VSYNC, GPIO_WEBCAM_HREF, GPIO_WEBCAM_PCLK, + GPIO_WEBCAM_PSCLK, + GPIO_WEBCAM_HSD, + GPIO_WEBCAM_PSRCS, +#endif + GPIO_BOILER_OT_RX, GPIO_BOILER_OT_TX, // OpenTherm Boiler TX pin + GPIO_WINDMETER_SPEED, // WindMeter speed counter pin + GPIO_KEY1_TC, // Touch pin as button + GPIO_BL0940_RX, // BL0940 serial interface + GPIO_TCP_TX, GPIO_TCP_RX, // TCP to serial bridge +#ifdef ESP32 + GPIO_ETH_PHY_POWER, GPIO_ETH_PHY_MDC, GPIO_ETH_PHY_MDIO, // Ethernet +#endif + GPIO_TELEINFO_RX, // Teleinfo telemetry data receive pin + GPIO_TELEINFO_ENABLE, // Teleinfo Enable Receive Pin + GPIO_LMT01, // LMT01 input counting pin + GPIO_IEM3000_TX, GPIO_IEM3000_RX, // IEM3000 Serial interface + GPIO_ZIGBEE_RST, // Zigbee reset + GPIO_DYP_RX, + GPIO_MIEL_HVAC_TX, GPIO_MIEL_HVAC_RX, // Mitsubishi Electric HVAC + GPIO_WE517_TX, GPIO_WE517_RX, // ORNO WE517 Serial interface + GPIO_AS608_TX, GPIO_AS608_RX, // Serial interface AS608 / R503 + GPIO_SHELLY_DIMMER_BOOT0, GPIO_SHELLY_DIMMER_RST_INV, + GPIO_RC522_RST, // RC522 reset + GPIO_P9813_CLK, GPIO_P9813_DAT, // P9813 Clock and Data + GPIO_OPTION_A, // Specific device options to be served in code + GPIO_FTC532, // FTC532 touch ctrlr serial input + GPIO_RC522_CS, + GPIO_NRF24_CS, GPIO_NRF24_DC, + GPIO_ILI9341_CS, GPIO_ILI9341_DC, + GPIO_ILI9488_CS, + GPIO_EPAPER29_CS, + GPIO_EPAPER42_CS, + GPIO_SSD1351_CS, + GPIO_RA8876_CS, + GPIO_ST7789_CS, GPIO_ST7789_DC, + GPIO_SSD1331_CS, GPIO_SSD1331_DC, + GPIO_SDCARD_CS, + GPIO_ROT1A_NP, GPIO_ROT1B_NP, // Rotary switch + GPIO_ADC_PH, // Analog PH Sensor + GPIO_BS814_CLK, GPIO_BS814_DAT, // Holtek BS814A2 touch ctrlr + GPIO_WIEGAND_D0, GPIO_WIEGAND_D1, // Wiegand Data lines + GPIO_NEOPOOL_TX, GPIO_NEOPOOL_RX, // Sugar Valley RS485 interface + GPIO_SDM72_TX, GPIO_SDM72_RX, // SDM72 Serial interface + GPIO_TM1637CLK, GPIO_TM1637DIO, // TM1637 interface + GPIO_PROJECTOR_CTRL_TX, GPIO_PROJECTOR_CTRL_RX, // LCD/DLP Projector Serial Control + GPIO_SSD1351_DC, + GPIO_XPT2046_CS, // XPT2046 SPI Chip Select + GPIO_CSE7761_TX, GPIO_CSE7761_RX, // CSE7761 Serial interface (Dual R3) + GPIO_VL53LXX_XSHUT1, // VL53LXX_XSHUT (the max number of sensors is VL53LXX_MAX_SENSORS)- Used when connecting multiple VL53LXX + GPIO_MAX7219CLK, GPIO_MAX7219DIN, GPIO_MAX7219CS, // MAX7219 interface + GPIO_TFMINIPLUS_TX, GPIO_TFMINIPLUS_RX, // TFmini Plus ToF sensor + GPIO_ZEROCROSS, +#ifdef ESP32 + GPIO_HALLEFFECT, + GPIO_EPD_DATA, // Base connection EPD driver +#endif + GPIO_INPUT, +#ifdef ESP32 + GPIO_KEY1_PD, GPIO_KEY1_INV_PD, GPIO_SWT1_PD, +#endif + GPIO_I2S_DOUT, GPIO_I2S_BCLK, GPIO_I2S_WS, GPIO_I2S_DIN, + GPIO_I2S_BCLK_IN, GPIO_I2S_WS_IN, // Spare since 20240603 + GPIO_INTERRUPT, + GPIO_MCP2515_CS, // MCP2515 Chip Select + GPIO_HRG15_TX, GPIO_HRG15_RX, // Hydreon RG-15 rain sensor serial interface + GPIO_VINDRIKTNING_RX, // IKEA VINDRIKTNING Serial interface + GPIO_BL0939_RX, // BL0939 Serial interface (Dual R3 v2) + GPIO_BL0942_RX, // BL0942 Serial interface + GPIO_HM330X_SET, // HM330X SET pin (sleep when low) + GPIO_HEARTBEAT, GPIO_HEARTBEAT_INV, + GPIO_SHIFT595_SRCLK, GPIO_SHIFT595_RCLK, GPIO_SHIFT595_OE, GPIO_SHIFT595_SER, // 74x595 Shift register + GPIO_SOLAXX1_RTS, // Solax Inverter Serial interface + GPIO_OPTION_E, // Emulated module + GPIO_SDM230_TX, GPIO_SDM230_RX, // SDM230 Serial interface + GPIO_ADC_MQ, // Analog MQ Sensor + GPIO_CM11_TXD, GPIO_CM11_RXD, // CM11 Serial interface + GPIO_BL6523_TX, GPIO_BL6523_RX, // BL6523 based Watt meter Serial interface + GPIO_ADE7880_IRQ, // ADE7880 IRQ + GPIO_RESET, // Generic reset + GPIO_MS01, // Sonoff MS01 Moisture Sensor 1wire interface + GPIO_SDIO_CMD, GPIO_SDIO_CLK, GPIO_SDIO_D0, GPIO_SDIO_D1, GPIO_SDIO_D2, GPIO_SDIO_D3, // SD Card SDIO interface, including 1-bit and 4-bit modes + GPIO_FLOWRATEMETER_IN, // Flowrate Meter + GPIO_BP5758D_CLK, GPIO_BP5758D_DAT, // BP5758D PWM controller + GPIO_SM2335_CLK, GPIO_SM2335_DAT, // SM2335 PWM controller + GPIO_MP3_DFR562_BUSY, // RB-DFR-562, DFPlayer Mini MP3 Player busy flag + GPIO_TM1621_CS, GPIO_TM1621_WR, GPIO_TM1621_RD, GPIO_TM1621_DAT, // Sonoff POWR3xxD and THR3xxD LCD display + GPIO_REL1_BI, GPIO_REL1_BI_INV, // 8 x Relays bistable + GPIO_I2S_MCLK, + GPIO_MBR_TX, GPIO_MBR_RX, // Modbus Bridge Serial interface + GPIO_ADE7953_RST, // ADE7953 Reset + GPIO_NRG_MBS_TX, GPIO_NRG_MBS_RX, // Generic Energy Modbus device + GPIO_ADE7953_CS, // ADE7953 SPI Chip Select + GPIO_DALI_RX, GPIO_DALI_TX, // DALI + GPIO_BP1658CJ_CLK, GPIO_BP1658CJ_DAT,// BP1658CJ + GPIO_DINGTIAN_CLK, GPIO_DINGTIAN_SDI, GPIO_DINGTIAN_Q7, GPIO_DINGTIAN_PL, GPIO_DINGTIAN_RCK, // Dingtian relay board - 595's & 165's pins + GPIO_LD2410_TX, GPIO_LD2410_RX, // HLK-LD2410 + GPIO_MBR_TX_ENA, GPIO_NRG_MBS_TX_ENA, // Modbus Bridge Serial Transmit Enable + GPIO_ME007_TRIG, GPIO_ME007_RX, // ME007 Serial/Trigger interface + GPIO_TUYAMCUBR_TX, GPIO_TUYAMCUBR_RX, // TuyaMCU Bridge + GPIO_BIOPDU_PZEM0XX_TX, GPIO_BIOPDU_PZEM016_RX, GPIO_BIOPDU_BIT, // Biomine BioPDU 625x12 + GPIO_MCP23XXX_INT, GPIO_MCP23SXX_CS, // MCP23xxx Int and SPI Chip select + GPIO_PCF8574_INT, // PCF8574 interrupt + GPIO_LOX_O2_RX, // LOX-O2 RX + GPIO_GM861_TX, GPIO_GM861_RX, // GM861 Serial interface + GPIO_DINGTIAN_OE, // New version of Dingtian relay board where PL is not shared with OE + GPIO_HDMI_CEC, // Support for HDMI CEC + GPIO_HC8_RXD, // HC8 Serial interface + GPIO_I2S_DAC, // Audio DAC support for ESP32 and ESP32S2 + GPIO_MAGIC_SWITCH, // MagicSwitch as in Sonoff BasicR4 + GPIO_PIPSOLAR_TX, GPIO_PIPSOLAR_RX, // pipsolar inverter + GPIO_LORA_CS, GPIO_LORA_RST, GPIO_LORA_BUSY, GPIO_LORA_DI0, GPIO_LORA_DI1, GPIO_LORA_DI2, GPIO_LORA_DI3, GPIO_LORA_DI4, GPIO_LORA_DI5, // LoRa SPI + GPIO_TS_SPI_CS, GPIO_TS_RST, GPIO_TS_IRQ, // SPI for Universal Touch Screen + GPIO_RN2XX3_TX, GPIO_RN2XX3_RX, GPIO_RN2XX3_RST, // RN2XX3 LoRaWan node Serial interface + GPIO_TCP_TX_EN, // TCP to serial bridge, EN pin + GPIO_ASR650X_TX, GPIO_ASR650X_RX, // ASR650X LoRaWan node Serial interface + GPIO_WOOLIIS_RX, // Wooliis Battery capacity monitor Serial RX + GPIO_ADC_VOLTAGE, GPIO_ADC_CURRENT, // Analog Voltage and Current + GPIO_BL0906_RX, // BL0906 Serial interface + GPIO_DALI_RX_INV, GPIO_DALI_TX_INV, // DALI + GPIO_LD2410S_TX, GPIO_LD2410S_RX, // HLK-LD2410S + GPIO_I2C_SER_TX, GPIO_I2C_SER_RX, // I2C via Serial using SC18IM704 protocol (xdrv74) + GPIO_TM1640CLK, GPIO_TM1640DIN, // TM1640 (16 x seven-segment LED controler) + GPIO_TWAI_TX, GPIO_TWAI_RX, GPIO_TWAI_BO, GPIO_TWAI_CLK, // ESP32 TWAI serial interface + GPIO_C8_CO2_5K_TX, GPIO_C8_CO2_5K_RX, // C8-CO2-5K CO2 Sensor + GPIO_V9240_TX, GPIO_V9240_RX, // V9240 serial interface + GPIO_LD2402_TX, GPIO_LD2402_RX, // HLK-LD2402 +#ifdef ESP32 + GPIO_HSDIO_CMD, GPIO_HSDIO_CLK, GPIO_HSDIO_RST, GPIO_HSDIO_D0, GPIO_HSDIO_D1, GPIO_HSDIO_D2, GPIO_HSDIO_D3, // Hosted MCU SDIO interface, including 1-bit and 4-bit modes +#endif + GPIO_VID6608_F, GPIO_VID6608_CW, // VID6608 + GPIO_MKSKYBLU_TX, GPIO_MKSKYBLU_RX, // MakeSkyBlue solar charge controller + GPIO_SENSOR_END }; + +// Error as warning to rethink GPIO usage with max 2045 +static_assert(GPIO_SENSOR_END < 2000, "Too many UserSelectablePins"); + +enum ProgramSelectablePins { + GPIO_FIX_START = 2046, + GPIO_USER, // User configurable needs to be 2047 + GPIO_MAX }; + +#define MAX_OPTIONS_A 9 // Increase if more bits are used from GpioOptionABits + +typedef union { // Restricted by MISRA-C Rule 18.4 but so useful... + uint32_t data; // Allow bit manipulation using SetOption + struct { // GPIO Option_A1 .. Option_A32 + uint32_t pwm1_input : 1; // bit 0 (v9.2.0.1) - Option_A1 - (Light) Change PWM1 to input on power off and no fade running (1) + uint32_t dummy_energy : 1; // bit 1 (v9.3.1.2) - Option_A2 - (Energy) Enable dummy values + uint32_t udisplay_driver : 1; // bit 2 (v9.3.1.2) - Option_A3 - (Display) Universal display driver + uint32_t enable_ccloader : 1; // bit 3 (v9.4.0.5) - Option_A4 - (Zigbee) Enable CCLoader using Zigbee Rx/Tx/Rst Gpios + uint32_t rotary_mi_desk : 1; // bit 4 (v9.5.0.5) - Option_A5 - (Rotary) Enable Mi Desk emulation + uint32_t linkind_support : 1; // bit 5 (v10.1.0.4) - Option_A6 - (Light) LinkInd support + uint32_t shelly_pro : 1; // bit 6 (v12.2.0.1) - Option_A7 - (Device) Shelly Pro + uint32_t ifan04_h : 1; // bit 7 (v14.1.0.4) - Option_A8 - (Device) Sonoff ifan04-H + uint32_t berry_energy : 1; // bit 8 (v14.2.0.4) - Option_A9 - (Energy) Enable Berry energy driver + uint32_t spare09 : 1; // bit 9 + uint32_t spare10 : 1; // bit 10 + uint32_t spare11 : 1; // bit 11 + uint32_t spare12 : 1; // bit 12 + uint32_t spare13 : 1; // bit 13 + uint32_t spare14 : 1; // bit 14 + uint32_t spare15 : 1; // bit 15 + uint32_t spare16 : 1; // bit 16 + uint32_t spare17 : 1; // bit 17 + uint32_t spare18 : 1; // bit 18 + uint32_t spare19 : 1; // bit 19 + uint32_t spare20 : 1; // bit 20 + uint32_t spare21 : 1; // bit 21 + uint32_t spare22 : 1; // bit 22 + uint32_t spare23 : 1; // bit 23 + uint32_t spare24 : 1; // bit 24 + uint32_t spare25 : 1; // bit 25 + uint32_t spare26 : 1; // bit 26 + uint32_t spare27 : 1; // bit 27 + uint32_t spare28 : 1; // bit 28 + uint32_t spare29 : 1; // bit 29 + uint32_t spare30 : 1; // bit 30 + uint32_t spare31 : 1; // bit 31 + }; +} GpioOptionABits; + +#ifdef ESP32 +enum SupportedEmulationModules { + SONOFF_BASIC, SONOFF_RF, SONOFF_SV, SONOFF_TH, SONOFF_DUAL, SONOFF_POW, SONOFF_4CH, SONOFF_S2X, SLAMPHER, SONOFF_TOUCH, + SONOFF_LED, CH1, CH4, MOTOR, ELECTRODRAGON, EXS_RELAY, WION, WEMOS_DUMMY, SONOFF_DEV, H801, + SONOFF_SC, SONOFF_BN, SONOFF_4CHPRO, HUAFAN_SS, SONOFF_BRIDGE, SONOFF_B1, AILIGHT, SONOFF_T11, SONOFF_T12, SONOFF_T13, + SUPLA1, WITTY, YUNSHAN, MAGICHOME, LUANIHVIO, KMC_70011, ARILUX_LC01, ARILUX_LC11, SONOFF_DUAL_R2, ARILUX_LC06, + SONOFF_S31, ZENGGE_ZF_WF017, SONOFF_POW_R2, SONOFF_IFAN02, BLITZWOLF_BWSHP, SHELLY1, SHELLY2, PHILIPS, NEO_COOLCAM, ESP_SWITCH, + OBI, TECKIN, APLIC_WDP303075, TUYA_DIMMER, GOSUND, ARMTRONIX_DIMMERS, SK03_TUYA, PS_16_DZ, TECKIN_US, MANZOKU_EU_4, + OBI2, YTF_IR_BRIDGE, DIGOO, KA10, ZX2820, MI_DESK_LAMP, SP10, WAGA, SYF05, SONOFF_L1, + SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1, SONOFF_ZB_BRIDGE, + MAXMODULE_EMULATION }; + +#define MAX_OPTIONS_E 1 // Increase if more emulated modules are supported from kModuleEmulationList + +const uint8_t kModuleEmulationList[] PROGMEM = { + PWM_DIMMER // (v10.1.0.4) - Option_E1 - (Light) USE_PWM_DIMMER support +}; +#endif // ESP32 + +// Text in webpage Module Parameters and commands GPIOS and GPIO +const char kSensorNames[] PROGMEM = + D_SENSOR_NONE "|" + D_SENSOR_BUTTON "|" D_SENSOR_BUTTON "_n|" D_SENSOR_BUTTON "_i|" D_SENSOR_BUTTON "_in|" + D_SENSOR_SWITCH "|" D_SENSOR_SWITCH "_n|" + D_SENSOR_RELAY "|" D_SENSOR_RELAY "_i|" + D_SENSOR_LED "|" D_SENSOR_LED "_i|" + D_SENSOR_COUNTER "|" D_SENSOR_COUNTER "_n|" + D_SENSOR_PWM "|" D_SENSOR_PWM "_i|" + D_SENSOR_BUZZER "|" D_SENSOR_BUZZER "_i|" + D_SENSOR_LED_LINK "|" D_SENSOR_LED_LINK "_i|" + D_SENSOR_I2C_SCL "|" D_SENSOR_I2C_SDA "|" + D_SENSOR_SPI_MISO "|" D_SENSOR_SPI_MOSI "|" D_SENSOR_SPI_CLK "|" D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" + D_SENSOR_SSPI_MISO "|" D_SENSOR_SSPI_MOSI "|" D_SENSOR_SSPI_SCLK "|" D_SENSOR_SSPI_CS "|" D_SENSOR_SSPI_DC "|" + D_SENSOR_BACKLIGHT "|" D_SENSOR_DISP_RESET "|" + D_SENSOR_IRSEND "|" D_SENSOR_IRRECV "|" + D_SENSOR_RFSEND "|" D_SENSOR_RFRECV "|" + D_SENSOR_DHT11 "|" D_SENSOR_AM2301 "|" D_SENSOR_SI7021 "|" D_SENSOR_DHT11 "_o|" + D_SENSOR_DS18X20 "|" D_SENSOR_DS18X20 "_o|" + D_SENSOR_WS2812 "|" + D_SENSOR_MHZ_TX "|" D_SENSOR_MHZ_RX "|" + D_SENSOR_PZEM0XX_TX "|" D_SENSOR_PZEM004_RX "|" D_SENSOR_PZEM016_RX "|" D_SENSOR_PZEM017_RX "|" + D_SENSOR_SAIR_TX "|" D_SENSOR_SAIR_RX "|" + D_SENSOR_PMS5003_TX "|" D_SENSOR_PMS5003_RX "|" + D_SENSOR_SDS0X1_TX "|" D_SENSOR_SDS0X1_RX "|" + D_SENSOR_SBR_TX "|" D_SENSOR_SBR_RX "|" + D_SENSOR_SR04_TRIG "|" D_SENSOR_SR04_ECHO "|" + D_SENSOR_SDM120_TX "|" D_SENSOR_SDM120_RX "|" + D_SENSOR_SDM630_TX "|" D_SENSOR_SDM630_RX "|" + D_SENSOR_TM1638_CLK "|" D_SENSOR_TM1638_DIO "|" D_SENSOR_TM1638_STB "|" + D_SENSOR_DFR562 "|" + D_SENSOR_HX711_SCK "|" D_SENSOR_HX711_DAT "|" + D_SENSOR_TX2X_TX "|" + D_SENSOR_TUYA_TX "|" D_SENSOR_TUYA_RX "|" + D_SENSOR_MGC3130_XFER "|" D_SENSOR_MGC3130_RESET "|" + D_SENSOR_RF_SENSOR "|" + D_SENSOR_AZ_TX "|" D_SENSOR_AZ_RX "|" + D_SENSOR_MAX31855_CS "|" D_SENSOR_MAX31855_CLK "|" D_SENSOR_MAX31855_DO "|" + D_SENSOR_NRG_SEL "|" D_SENSOR_NRG_SEL "_i|" D_SENSOR_NRG_CF1 "|" D_SENSOR_HLW_CF "|" D_SENSOR_HJL_CF "|" + D_SENSOR_MCP39F5_TX "|" D_SENSOR_MCP39F5_RX "|" D_SENSOR_MCP39F5_RST "|" + D_SENSOR_PN532_TX "|" D_SENSOR_PN532_RX "|" + D_SENSOR_SM16716_CLK "|" D_SENSOR_SM16716_DAT "|" D_SENSOR_SM16716_POWER "|" + D_SENSOR_MY92X1_DI "|" D_SENSOR_MY92X1_DCKI "|" + D_SENSOR_CSE7766_TX "|" D_SENSOR_CSE7766_RX "|" + D_SENSOR_ARIRFRCV "|" D_SENSOR_ARIRFSEL "|" + D_SENSOR_TXD "|" D_SENSOR_RXD "|" + D_SENSOR_ROTARY " A|" D_SENSOR_ROTARY " B|" + D_SENSOR_ADC_JOYSTICK "|" + D_SENSOR_MAX31865_CS "|" + D_SENSOR_HRE_CLOCK "|" D_SENSOR_HRE_DATA "|" + D_SENSOR_ADE7953_IRQ "|" + D_SENSOR_SOLAXX1_TX "|" D_SENSOR_SOLAXX1_RX "|" + D_SENSOR_ZIGBEE_TXD "|" D_SENSOR_ZIGBEE_RXD "|" + D_SENSOR_RDM6300_RX "|" + D_SENSOR_IBEACON_TX "|" D_SENSOR_IBEACON_RX "|" + D_SENSOR_A4988_DIR "|" D_SENSOR_A4988_STP "|" D_SENSOR_A4988_ENA "|" D_SENSOR_A4988_MS1 "|" + D_SENSOR_OUTPUT_HI "|" D_SENSOR_OUTPUT_LO "|" + D_SENSOR_DDS2382_TX "|" D_SENSOR_DDS2382_RX "|" + D_SENSOR_DDSU666_TX "|" D_SENSOR_DDSU666_RX "|" + D_SENSOR_SM2135_CLK "|" D_SENSOR_SM2135_DAT "|" + D_SENSOR_DEEPSLEEP "|" D_SENSOR_EXS_ENABLE "|" + D_SENSOR_CLIENT_TX "|" D_SENSOR_CLIENT_RX "|" D_SENSOR_CLIENT_RESET "|" D_SENSOR_CLIENT_RESET "_i|" + D_SENSOR_HPMA_RX "|" D_SENSOR_HPMA_TX "|" + D_SENSOR_GPS_RX "|" D_SENSOR_GPS_TX "|" + D_SENSOR_HM10_RX "|" D_SENSOR_HM10_TX "|" + D_SENSOR_LE01MR_RX "|" D_SENSOR_LE01MR_TX "|" + D_SENSOR_CC1101_GDO0 "|" D_SENSOR_CC1101_GDO2 "|" + D_SENSOR_HRXL_RX "|" + D_SENSOR_ELECTRIQ_MOODL "|" + D_SENSOR_AS3935 "|" + D_SENSOR_ADC_INPUT "|" + D_SENSOR_ADC_TEMP "|" + D_SENSOR_ADC_LIGHT "|" + D_SENSOR_ADC_BUTTON "|" D_SENSOR_ADC_BUTTON "_i|" + D_SENSOR_ADC_RANGE "|" + D_SENSOR_ADC_CT_POWER "|" +#ifdef ESP32 + D_GPIO_WEBCAM_PWDN "|" D_GPIO_WEBCAM_RESET "|" D_GPIO_WEBCAM_XCLK "|" + D_GPIO_WEBCAM_SIOD "|" D_GPIO_WEBCAM_SIOC "|" + D_GPIO_WEBCAM_DATA "|" + D_GPIO_WEBCAM_VSYNC "|" D_GPIO_WEBCAM_HREF "|" D_GPIO_WEBCAM_PCLK "|" + D_GPIO_WEBCAM_PSCLK "|" + D_GPIO_WEBCAM_HSD "|" + D_GPIO_WEBCAM_PSRCS "|" +#endif + D_SENSOR_BOILER_OT_RX "|" D_SENSOR_BOILER_OT_TX "|" + D_SENSOR_WINDMETER_SPEED "|" D_SENSOR_BUTTON "_tc|" + D_SENSOR_BL0940_RX "|" + D_SENSOR_TCP_TXD "|" D_SENSOR_TCP_RXD "|" +#ifdef ESP32 + D_SENSOR_ETH_PHY_POWER "|" D_SENSOR_ETH_PHY_MDC "|" D_SENSOR_ETH_PHY_MDIO "|" +#endif + D_SENSOR_TELEINFO_RX "|" D_SENSOR_TELEINFO_ENABLE "|" + D_SENSOR_LMT01_PULSE "|" + D_SENSOR_IEM3000_TX "|" D_SENSOR_IEM3000_RX "|" + D_SENSOR_ZIGBEE_RST "|" + D_SENSOR_DYP_RX "|" + D_SENSOR_MIEL_HVAC_TX "|" D_SENSOR_MIEL_HVAC_RX "|" + D_SENSOR_WE517_TX "|" D_SENSOR_WE517_RX "|" + D_SENSOR_AS608_TX "|" D_SENSOR_AS608_RX "|" + D_SENSOR_SHELLY_DIMMER_BOOT0 "|" D_SENSOR_SHELLY_DIMMER_RST_INV "|" + D_SENSOR_RC522_RST "|" + D_SENSOR_P9813_CLK "|" D_SENSOR_P9813_DAT "|" + D_SENSOR_OPTION " A|" + D_SENSOR_FTC532 "|" + D_SENSOR_RC522_CS "|" + D_SENSOR_NRF24_CS "|" D_SENSOR_NRF24_DC "|" + D_SENSOR_ILI9341_CS "|" D_SENSOR_ILI9341_DC "|" + D_SENSOR_ILI9488_CS "|" + D_SENSOR_EPAPER29_CS "|" + D_SENSOR_EPAPER42_CS "|" + D_SENSOR_SSD1351_CS "|" + D_SENSOR_RA8876_CS "|" + D_SENSOR_ST7789_CS "|" D_SENSOR_ST7789_DC "|" + D_SENSOR_SSD1331_CS "|" D_SENSOR_SSD1331_DC "|" + D_SENSOR_SDCARD_CS "|" + D_SENSOR_ROTARY " A_n|" D_SENSOR_ROTARY " B_n|" + D_SENSOR_ADC_PH "|" + D_SENSOR_BS814_CLK "|" D_SENSOR_BS814_DAT "|" + D_SENSOR_WIEGAND_D0 "|" D_SENSOR_WIEGAND_D1 "|" + D_SENSOR_NEOPOOL_TX "|" D_SENSOR_NEOPOOL_RX "|" + D_SENSOR_SDM72_TX "|" D_SENSOR_SDM72_RX "|" + D_SENSOR_TM1637_CLK "|" D_SENSOR_TM1637_DIO "|" + D_SENSOR_PROJECTOR_CTRL_TX "|" D_SENSOR_PROJECTOR_CTRL_RX "|" + D_SENSOR_SSD1351_DC "|" + D_SENSOR_XPT2046_CS "|" + D_SENSOR_CSE7761_TX "|" D_SENSOR_CSE7761_RX "|" + D_SENSOR_VL53LXX_XSHUT "|" + D_SENSOR_MAX7219_CLK "|" D_SENSOR_MAX7219_DIN "|" D_SENSOR_MAX7219_CS "|" + D_SENSOR_TFMINIPLUS_TX "|" D_SENSOR_TFMINIPLUS_RX "|" + D_SENSOR_ZEROCROSS "|" +#ifdef ESP32 + D_SENSOR_HALLEFFECT "|" + D_SENSOR_EPD_DATA "|" +#endif + D_SENSOR_INPUT "|" +#ifdef ESP32 + D_SENSOR_BUTTON "_d|" D_SENSOR_BUTTON "_id|" D_SENSOR_SWITCH "_d|" +#endif + D_SENSOR_I2S_DOUT "|" D_SENSOR_I2S_BCLK "|" D_SENSOR_I2S_WS "|" D_SENSOR_I2S_DIN "|" + D_SENSOR_I2S_BCLK_IN "|" D_SENSOR_I2S_WS_IN "|" + D_SENSOR_INTERRUPT "|" + D_SENSOR_MCP2515_CS "|" + D_SENSOR_HRG15_TX "|" D_SENSOR_HRG15_RX "|" + D_SENSOR_VINDRIKTNING_RX "|" + D_SENSOR_BL0939_RX "|" + D_SENSOR_BL0942_RX "|" + D_SENSOR_HM330X_SET "|" + D_SENSOR_HEARTBEAT "|" D_SENSOR_HEARTBEAT "_i|" + D_GPIO_SHIFT595_SRCLK "|" D_GPIO_SHIFT595_RCLK "|" D_GPIO_SHIFT595_OE "|" D_GPIO_SHIFT595_SER "|" + D_SENSOR_SOLAXX1_RTS "|" + D_SENSOR_OPTION " E|" + D_SENSOR_SDM230_TX "|" D_SENSOR_SDM230_RX "|" + D_SENSOR_ADC_MQ "|" + D_SENSOR_CM11_TX "|" D_SENSOR_CM11_RX "|" + D_SENSOR_BL6523_TX "|" D_SENSOR_BL6523_RX "|" + D_SENSOR_ADE7880_IRQ "|" + D_SENSOR_RESET "|" + D_SENSOR_MS01 "|" + D_SENSOR_SDIO_CMD "|" D_SENSOR_SDIO_CLK "|" D_SENSOR_SDIO_D0 "|" D_SENSOR_SDIO_D1 "|" D_SENSOR_SDIO_D2 "|" D_SENSOR_SDIO_D3 "|" + D_SENSOR_FLOWRATEMETER "|" + D_SENSOR_BP5758D_CLK "|" D_SENSOR_BP5758D_DAT "|" + D_SENSOR_SM2335_CLK "|" D_SENSOR_SM2335_DAT "|" + D_SENSOR_DFR562_BUSY "|" + D_GPIO_TM1621_CS "|" D_GPIO_TM1621_WR "|" D_GPIO_TM1621_RD "|" D_GPIO_TM1621_DAT "|" + D_SENSOR_RELAY "_b|" D_SENSOR_RELAY "_bi|" + D_SENSOR_I2S_MCLK "|" + D_SENSOR_MBR_TX "|" D_SENSOR_MBR_RX "|" + D_SENSOR_ADE7953_RST "|" + D_SENSOR_NRG_MBS_TX "|" D_SENSOR_NRG_MBS_RX "|" + D_SENSOR_ADE7953_CS "|" + D_SENSOR_DALI_RX "|" D_SENSOR_DALI_TX "|" + D_SENSOR_BP1658CJ_CLK "|" D_SENSOR_BP1658CJ_DAT "|" + D_GPIO_DINGTIAN_CLK "|" D_GPIO_DINGTIAN_SDI "|" D_GPIO_DINGTIAN_Q7 "|" D_GPIO_DINGTIAN_PL "|" D_GPIO_DINGTIAN_RCK "|" + D_SENSOR_LD2410_TX "|" D_SENSOR_LD2410_RX "|" + D_SENSOR_MBR_TX_ENA "|" D_SENSOR_NRG_MBS_TX_ENA "|" + D_SENSOR_ME007_TRIG "|" D_SENSOR_ME007_RX "|" + D_SENSOR_TUYAMCUBR_TX "|" D_SENSOR_TUYAMCUBR_RX "|" + D_SENSOR_BIOPDU_PZEM0XX_TX "|" D_SENSOR_BIOPDU_PZEM016_RX "|" D_SENSOR_BIOPDU_BIT "|" + D_SENSOR_MCP23XXX_INT "|" D_SENSOR_MCP23SXX_CS "|" + D_SENSOR_PCF8574_INT "|" + D_SENSOR_LOX_O2_RX "|" + D_SENSOR_GM861_TX "|" D_SENSOR_GM861_RX "|" + D_GPIO_DINGTIAN_OE "|" + D_SENSOR_HDMI_CEC "|" + D_SENSOR_HC8_RX "|" + D_SENSOR_I2S_DAC "|" + D_GPIO_MAGIC_SWITCH "|" + D_SENSOR_PIPSOLAR_TX "|" D_SENSOR_PIPSOLAR_RX "|" + D_GPIO_LORA_CS "|" D_GPIO_LORA_RST "|" D_GPIO_LORA_BUSY "|" D_GPIO_LORA_DI "0|" D_GPIO_LORA_DI "1|" D_GPIO_LORA_DI "2|" D_GPIO_LORA_DI "3|" D_GPIO_LORA_DI "4|" D_GPIO_LORA_DI "5|" + D_GPIO_TS_SPI_CS "|" D_GPIO_TS_RST "|" D_GPIO_TS_IRQ "|" + D_GPIO_RN2XX3_TX "|" D_GPIO_RN2XX3_RX "|" D_GPIO_RN2XX3_RST "|" + D_SENSOR_TCP_TXD_EN "|" + D_GPIO_ASR650X_TX "|" D_GPIO_ASR650X_RX "|" + D_SENSOR_WOOLIIS_RX "|" + D_SENSOR_ADC_VOLTAGE "|" D_SENSOR_ADC_CURRENT "|" + D_SENSOR_BL0906_RX "|" + D_SENSOR_DALI_RX "_i|" D_SENSOR_DALI_TX "_i|" + D_SENSOR_LD2410S_TX "|" D_SENSOR_LD2410S_RX "|" + D_SENSOR_I2C_SER_TX "|" D_SENSOR_I2C_SER_RX "|" + D_SENSOR_TM1640_CLK "|" D_SENSOR_TM1640_DIN "|" + D_SENSOR_TWAI_TX "|" D_SENSOR_TWAI_RX "|" D_SENSOR_TWAI_BO "|" D_SENSOR_TWAI_CLK "|" + D_SENSOR_C8_CO2_5K_TX "|" D_SENSOR_C8_CO2_5K_RX "|" + D_SENSOR_V9240_TX "|" D_SENSOR_V9240_RX "|" + D_SENSOR_LD2402_TX "|" D_SENSOR_LD2402_RX "|" +#ifdef ESP32 + D_SENSOR_HSDIO_CMD "|" D_SENSOR_HSDIO_CLK "|" D_SENSOR_HSDIO_RST "|" D_SENSOR_HSDIO_D0 "|" D_SENSOR_HSDIO_D1 "|" D_SENSOR_HSDIO_D2 "|" D_SENSOR_HSDIO_D3 "|" +#endif + D_VID6608_F "|" D_VID6608_CW "|" + D_SENSOR_MKSKYBLU_TX "|" D_SENSOR_MKSKYBLU_RX "|" +; + +const char kSensorNamesFixed[] PROGMEM = + D_SENSOR_USER; + +// Max number of GPIOs +#define MAX_I2C 1 // Display no index if one bus +#ifdef USE_I2C_BUS2 +#undef MAX_I2C +#define MAX_I2C 2 +#endif +#define MAX_MAX31855S 6 +#define MAX_MAX31865S 6 +#define MAX_MCP23XXX 6 +#define MAX_FLOWRATEMETER 2 +#define MAX_A4988_MSS 3 +#define MAX_WEBCAM_DATA 8 +#define MAX_WEBCAM_HSD 3 +#define MAX_SM2135_DAT 10 +#define MAX_SM2335_DAT 16 +#define MAX_DSB 4 +#define MAX_BP1658CJ_DAT 16 +#define MAX_DINGTIAN_SHIFT 4 +#define MAX_MAGIC_SWITCH_MODES 2 +#define MAX_BL0906_RX 6 // Model number of phases, 2 (EM2), 6 (EM6) +#define MAX_BL0942_RX 8 // Baudrates 1/5 (4800), 2/6 (9600), 3/7 (19200), 4/8 (38400), Support Positive values only 1..4, Support also negative values 5..8 +#define MAX_CSE7761 2 // Model 1/2 (DUALR3), 2/2 (POWCT) +#define MAX_TWAI SOC_TWAI_CONTROLLER_NUM +#define MAX_GPS_RX 3 // Baudrates 1 (9600), 2 (19200), 3 (38400) +#ifdef ESP32 +#define MAX_MKSKYBLU_IF 8 // MakeSkyBlue solar charger: ESP32-NRG supports up to 8 phases +#else +#define MAX_MKSKYBLU_IF 3 // MakeSkyBlue solar charger: ESP82xx-NRG supports up to 3 phases +#endif + +const uint16_t kGpioNiceList[] PROGMEM = { + GPIO_NONE, // Not used + AGPIO(GPIO_OPTION_A) + AGMAX(MAX_OPTIONS_A), // Device specific options +#ifdef ESP32 + AGPIO(GPIO_OPTION_E) + AGMAX(MAX_OPTIONS_E), // Device module emulation +#endif + AGPIO(GPIO_KEY1) + AGMAX(MAX_KEYS), // Buttons + AGPIO(GPIO_KEY1_NP) + AGMAX(MAX_KEYS), +#ifdef ESP32 + AGPIO(GPIO_KEY1_PD) + AGMAX(MAX_KEYS), +#endif + AGPIO(GPIO_KEY1_INV) + AGMAX(MAX_KEYS), + AGPIO(GPIO_KEY1_INV_NP) + AGMAX(MAX_KEYS), +#ifdef ESP32 + AGPIO(GPIO_KEY1_INV_PD) + AGMAX(MAX_KEYS), +#if defined(SOC_TOUCH_VERSION_1) || defined(SOC_TOUCH_VERSION_2) + AGPIO(GPIO_KEY1_TC) + AGMAX(MAX_KEYS), // Touch button +#endif // ESP32 SOC_TOUCH_VERSION_1 or SOC_TOUCH_VERSION_2 +#endif + AGPIO(GPIO_SWT1) + AGMAX(MAX_SWITCHES), // User connected external switches + AGPIO(GPIO_SWT1_NP) + AGMAX(MAX_SWITCHES), +#ifdef ESP32 + AGPIO(GPIO_SWT1_PD) + AGMAX(MAX_SWITCHES), +#endif +#ifdef ROTARY_V1 + AGPIO(GPIO_ROT1A) + AGMAX(MAX_ROTARIES), // Rotary A Pin + AGPIO(GPIO_ROT1B) + AGMAX(MAX_ROTARIES), // Rotary B Pin + AGPIO(GPIO_ROT1A_NP) + AGMAX(MAX_ROTARIES), // Rotary A Pin No Pullup + AGPIO(GPIO_ROT1B_NP) + AGMAX(MAX_ROTARIES), // Rotary B Pin No Pullup +#endif + AGPIO(GPIO_REL1) + AGMAX(MAX_RELAYS), // Relays + AGPIO(GPIO_REL1_INV) + AGMAX(MAX_RELAYS), + AGPIO(GPIO_REL1_BI) + AGMAX(MAX_RELAYS), // Bistable (Latching) two coil relays + AGPIO(GPIO_REL1_BI_INV) + AGMAX(MAX_RELAYS), + AGPIO(GPIO_LED1) + AGMAX(MAX_LEDS), // Leds + AGPIO(GPIO_LED1_INV) + AGMAX(MAX_LEDS), +#ifdef USE_COUNTER + AGPIO(GPIO_CNTR1) + AGMAX(MAX_COUNTERS), // Counters + AGPIO(GPIO_CNTR1_NP) + AGMAX(MAX_COUNTERS), +#endif + AGPIO(GPIO_PWM1) + AGMAX(MAX_PWMS), // RGB Red or C Cold White + AGPIO(GPIO_PWM1_INV) + AGMAX(MAX_PWMS), // or extended PWM for ESP32 +#ifdef USE_BUZZER + AGPIO(GPIO_BUZZER), // Buzzer + AGPIO(GPIO_BUZZER_INV), // Inverted buzzer +#endif + AGPIO(GPIO_LEDLNK), // Link led + AGPIO(GPIO_LEDLNK_INV), // Inverted link led +#ifdef USE_BERRY + AGPIO(GPIO_INPUT) + AGMAX(MAX_SWITCHES), // Pure digital input to be read via Berry + AGPIO(GPIO_INTERRUPT) + AGMAX(MAX_SWITCHES), // Interrupt pins to be catched by Berry +#endif + AGPIO(GPIO_OUTPUT_HI), // Fixed output high + AGPIO(GPIO_OUTPUT_LO), // Fixed output low + AGPIO(GPIO_HEARTBEAT), // Every second pulsed high + AGPIO(GPIO_HEARTBEAT_INV), // Every second pulsed low + AGPIO(GPIO_RESET), // Generic reset +#ifdef USE_FTC532 + AGPIO(GPIO_FTC532), // FTC532 touch input +#endif +#ifdef USE_BS814A2 + AGPIO(GPIO_BS814_CLK), // Holtek BS814A2 touch ctrlr + AGPIO(GPIO_BS814_DAT), +#endif + +/*-------------------------------------------------------------------------------------------*\ + * Protocol specifics +\*-------------------------------------------------------------------------------------------*/ + +#ifdef USE_I2C + AGPIO(GPIO_I2C_SCL) + AGMAX(MAX_I2C), // I2C SCL + AGPIO(GPIO_I2C_SDA) + AGMAX(MAX_I2C), // I2C SDA +#ifdef USE_PCF8574 + AGPIO(GPIO_PCF8574_INT), // PCF8574 Interrupt +#endif // USE_PCF8574 +#ifdef USE_I2C_SERIAL + AGPIO(GPIO_I2C_SER_TX) + AGMAX(MAX_I2C), // I2C via Serial TX + AGPIO(GPIO_I2C_SER_RX) + AGMAX(MAX_I2C), // I2C via Serial RX +#endif // USE_I2C_SERIAL +#endif + +#if defined(USE_I2S_AUDIO) || defined (USE_I2S) + AGPIO(GPIO_I2S_MCLK) + AGMAX(MAX_I2S), // I2S master clock + AGPIO(GPIO_I2S_BCLK) + AGMAX(MAX_I2S), // I2S bit clock + AGPIO(GPIO_I2S_DOUT) + AGMAX(MAX_I2S), // I2S Out Data + AGPIO(GPIO_I2S_DAC) + AGMAX(2), // I2S DAC Output + AGPIO(GPIO_I2S_WS) + AGMAX(MAX_I2S), // I2S word select + AGPIO(GPIO_I2S_DIN) + AGMAX(MAX_I2S), // I2S IN Data +#endif + +#ifdef USE_SPI + AGPIO(GPIO_SPI_MISO) + AGMAX(MAX_SPI), // SPI MISO + AGPIO(GPIO_SPI_MOSI) + AGMAX(MAX_SPI), // SPI MOSI + AGPIO(GPIO_SPI_CLK) + AGMAX(MAX_SPI), // SPI Clk + AGPIO(GPIO_SPI_CS) + AGMAX(MAX_SPI), // SPI Chip Select + AGPIO(GPIO_SPI_DC) + AGMAX(MAX_SPI), // SPI Data Direction +#ifdef USE_NRF24 + AGPIO(GPIO_NRF24_CS), + AGPIO(GPIO_NRF24_DC), +#endif +#ifdef USE_RC522 + AGPIO(GPIO_RC522_CS), // RC522 Rfid Chip Select + AGPIO(GPIO_RC522_RST), // RC522 Rfid Reset +#endif +#ifdef USE_SDCARD + AGPIO(GPIO_SDCARD_CS) + AGMAX(MAX_SPI), // SDCard in SPI mode +#endif // USE_SDCARD +#if defined(USE_MCP2515) || defined(USE_CANSNIFFER) + AGPIO(GPIO_MCP2515_CS), +#endif // USE_MCP2515 +#ifdef USE_MCP23XXX_DRV + AGPIO(GPIO_MCP23SXX_CS) + AGMAX(MAX_MCP23XXX), +#endif // USE_MCP23XXX_DRV +#ifdef USE_SPI_LORA + AGPIO(GPIO_LORA_CS), + AGPIO(GPIO_LORA_RST), + AGPIO(GPIO_LORA_BUSY), + AGPIO(GPIO_LORA_DI0), + AGPIO(GPIO_LORA_DI1), + AGPIO(GPIO_LORA_DI2), + AGPIO(GPIO_LORA_DI3), + AGPIO(GPIO_LORA_DI4), + AGPIO(GPIO_LORA_DI5), +#endif // USE_SPI_LORA +#endif // USE_SPI + +#if defined(USE_SDCARD) && defined(ESP32) + AGPIO(GPIO_SDIO_CMD), // SDCard in SDIO mode + AGPIO(GPIO_SDIO_CLK), + AGPIO(GPIO_SDIO_D0), + AGPIO(GPIO_SDIO_D1), // (opt) if in 4-bit mode, DAT1-3 are needed + AGPIO(GPIO_SDIO_D2), + AGPIO(GPIO_SDIO_D3), +#endif // USE_SDCARD + + AGPIO(GPIO_SSPI_MISO), // Software SPI Master Input Client Output + AGPIO(GPIO_SSPI_MOSI), // Software SPI Master Output Client Input + AGPIO(GPIO_SSPI_SCLK), // Software SPI Serial Clock + AGPIO(GPIO_SSPI_CS), // Software SPI Chip Select + AGPIO(GPIO_SSPI_DC), // Software SPI Data or Command + +#if defined(USE_DISPLAY) || defined(USE_LVGL) +#ifdef USE_UNIVERSAL_TOUCH + AGPIO(GPIO_TS_SPI_CS), // Touch CS + AGPIO(GPIO_TS_RST), // Touch Reset + AGPIO(GPIO_TS_IRQ), // Touch IRQ +#endif // USE_UNIVERSAL_TOUCH +// REMOVED +// #ifdef USE_DISPLAY_ILI9341 +// AGPIO(GPIO_ILI9341_CS), +// AGPIO(GPIO_ILI9341_DC), +// #endif // USE_DISPLAY_ILI9341 + +#ifdef USE_XPT2046 + AGPIO(GPIO_XPT2046_CS), // XPT2046 SPI Chip Select +#endif + +#ifdef USE_DISPLAY_ILI9488 + AGPIO(GPIO_ILI9488_CS), +#endif // USE_DISPLAY_ILI9488 +#ifdef USE_DISPLAY_EPAPER_29 + AGPIO(GPIO_EPAPER29_CS), +#endif // USE_DISPLAY_EPAPER_29 +#ifdef USE_DISPLAY_EPAPER_42 + AGPIO(GPIO_EPAPER42_CS), +#endif // USE_DISPLAY_EPAPER_42 +// REMOVED +// #ifdef USE_DISPLAY_SSD1351 +// AGPIO(GPIO_SSD1351_CS), +// AGPIO(GPIO_SSD1351_DC), +// #endif // USE_DISPLAY_SSD1351 +#ifdef USE_DISPLAY_RA8876 + AGPIO(GPIO_RA8876_CS), +#endif // USE_DISPLAY_RA8876 +// REMOVED +// #ifdef USE_DISPLAY_ST7789 +// AGPIO(GPIO_ST7789_CS), +// AGPIO(GPIO_ST7789_DC), +// #endif // USE_DISPLAY_ST7789 +// REMOVED +// #ifdef USE_DISPLAY_SSD1331 +// AGPIO(GPIO_SSD1331_CS), +// AGPIO(GPIO_SSD1331_DC), +// #endif // USE_DISPLAY_SSD1331 +#ifdef USE_DISPLAY_MAX7219_MATRIX + #undef USE_DISPLAY_MAX7219 + #undef USE_DISPLAY_TM1637 + AGPIO(GPIO_MAX7219CLK), + AGPIO(GPIO_MAX7219DIN), + AGPIO(GPIO_MAX7219CS), +#endif // USE_DISPLAY_MAX7219_MATRIX +#ifdef USE_DISPLAY_MAX7219 + AGPIO(GPIO_MAX7219CLK), + AGPIO(GPIO_MAX7219DIN), + AGPIO(GPIO_MAX7219CS), +#endif // USE_DISPLAY_MAX7219 +#ifdef USE_DISPLAY_TM1637 + AGPIO(GPIO_TM1637CLK), + AGPIO(GPIO_TM1637DIO), + AGPIO(GPIO_TM1638CLK), + AGPIO(GPIO_TM1638DIO), + AGPIO(GPIO_TM1638STB), +#endif // USE_DISPLAY_TM1637 +#ifdef USE_DISPLAY_TM1640 + AGPIO(GPIO_TM1640CLK), + AGPIO(GPIO_TM1640DIN), +#endif // USE_DISPLAY_TM1640 + AGPIO(GPIO_BACKLIGHT), // Display backlight control + AGPIO(GPIO_OLED_RESET), // OLED Display Reset +#ifdef ESP32 + AGPIO(GPIO_EPD_DATA), // Base connection EPD driver +#endif +#endif // USE_DISPLAY + +#ifdef USE_DISPLAY_TM1621_SONOFF +// Initial support outside display driver + AGPIO(GPIO_TM1621_CS), + AGPIO(GPIO_TM1621_WR), + AGPIO(GPIO_TM1621_RD), + AGPIO(GPIO_TM1621_DAT), +#endif // USE_DISPLAY_TM1621_SONOFF + +#ifdef USE_MAX31865 + AGPIO(GPIO_SSPI_MAX31865_CS1) + AGMAX(MAX_MAX31865S), +#endif + +#ifdef USE_MCP23XXX_DRV + AGPIO(GPIO_MCP23XXX_INT) + AGMAX(MAX_MCP23XXX), +#endif + +#ifdef USE_HDMI_CEC + AGPIO(GPIO_HDMI_CEC), // HDMI CEC bus +#endif + + AGPIO(GPIO_TXD), // Serial interface + AGPIO(GPIO_RXD), // Serial interface + +/*-------------------------------------------------------------------------------------------*\ + * Single wire sensors +\*-------------------------------------------------------------------------------------------*/ + +#ifdef USE_DHT + AGPIO(GPIO_DHT11), // DHT11 + AGPIO(GPIO_DHT22), // DHT21, DHT22, AM2301, AM2302, AM2321 + AGPIO(GPIO_SI7021), // iTead SI7021 + AGPIO(GPIO_MS01), // Sonoff MS01 + AGPIO(GPIO_DHT11_OUT), // Pseudo Single wire DHT11, DHT21, DHT22, AM2301, AM2302, AM2321 +#endif +#ifdef USE_DS18x20 + AGPIO(GPIO_DSB) + AGMAX(MAX_DSB), // Single wire DS18B20 or DS18S20 + AGPIO(GPIO_DSB_OUT) + AGMAX(MAX_DSB), // Pseudo Single wire DS18B20 or DS18S20 +#endif // USE_DS18x20 +#ifdef USE_LMT01 + AGPIO(GPIO_LMT01), // LMT01, count pulses on GPIO +#endif + +/*-------------------------------------------------------------------------------------------*\ + * Light +\*-------------------------------------------------------------------------------------------*/ + +#ifdef USE_LIGHT +#ifdef USE_WS2812 +#if (USE_WS2812_HARDWARE == NEO_HW_P9813) + AGPIO(GPIO_P9813_CLK), // P9813 CLOCK + AGPIO(GPIO_P9813_DAT), // P9813 DATA +#else + AGPIO(GPIO_WS2812) + AGMAX(MAX_RMT), // WS2812 Led string, using RMT on ESP32 +#endif // NEO_HW_P9813 +#endif +#ifdef USE_ARILUX_RF + AGPIO(GPIO_ARIRFRCV), // AriLux RF Receive input + AGPIO(GPIO_ARIRFSEL), // Arilux RF Receive input selected +#endif +#ifdef USE_MY92X1 + AGPIO(GPIO_DI), // my92x1 PWM input + AGPIO(GPIO_DCKI), // my92x1 CLK input +#endif // USE_MY92X1 +#ifdef USE_SM16716 + AGPIO(GPIO_SM16716_CLK), // SM16716 CLOCK + AGPIO(GPIO_SM16716_DAT), // SM16716 DATA + AGPIO(GPIO_SM16716_SEL), // SM16716 SELECT +#endif // USE_SM16716 +#ifdef USE_SM2135 + AGPIO(GPIO_SM2135_CLK), // SM2135 CLOCK + AGPIO(GPIO_SM2135_DAT) + AGMAX(MAX_SM2135_DAT), // SM2135 DATA +#endif // USE_SM2135 +#ifdef USE_SM2335 + AGPIO(GPIO_SM2335_CLK), // SM2335 CLOCK + AGPIO(GPIO_SM2335_DAT) + AGMAX(MAX_SM2335_DAT), // SM2335 DATA +#endif // USE_SM2335 +#ifdef USE_BP1658CJ + AGPIO(GPIO_BP1658CJ_CLK), // BP1658CJ CLOCK + AGPIO(GPIO_BP1658CJ_DAT) + AGMAX(MAX_BP1658CJ_DAT), // BP1658CJ DATA +#endif // USE_BP1658CJ +#ifdef USE_BP5758D + AGPIO(GPIO_BP5758D_CLK), // BP5758D CLOCK + AGPIO(GPIO_BP5758D_DAT), // BP5758D DATA +#endif // USE_BP5758D +#ifdef USE_TUYA_MCU + AGPIO(GPIO_TUYA_TX), // Tuya Serial interface + AGPIO(GPIO_TUYA_RX), // Tuya Serial interface +#endif +#ifdef USE_EXS_DIMMER + AGPIO(GPIO_EXS_ENABLE), // EXS MCU Enable +#endif +#ifdef USE_ELECTRIQ_MOODL + AGPIO(GPIO_ELECTRIQ_MOODL_TX), +#endif +#ifdef USE_SHELLY_DIMMER + AGPIO(GPIO_SHELLY_DIMMER_BOOT0), + AGPIO(GPIO_SHELLY_DIMMER_RST_INV), +#endif +#endif // USE_LIGHT + +#ifdef USE_DALI + AGPIO(GPIO_DALI_TX), // DALI TX + AGPIO(GPIO_DALI_TX_INV), // DALI TX inverted + AGPIO(GPIO_DALI_RX), // DALI RX + AGPIO(GPIO_DALI_RX_INV), // DALI RX inverted +#endif // USE_DALI + +/*-------------------------------------------------------------------------------------------*\ + * Transmission sensors +\*-------------------------------------------------------------------------------------------*/ + +#if defined(USE_IR_REMOTE) || defined(USE_IR_REMOTE_FULL) + AGPIO(GPIO_IRSEND) + AGMAX(MAX_IRSEND), // IR remote +#if defined(USE_IR_RECEIVE) || defined(USE_IR_REMOTE_FULL) + AGPIO(GPIO_IRRECV), // IR receiver +#endif +#endif +#ifdef USE_RC_SWITCH + AGPIO(GPIO_RFSEND), // RF transmitter + AGPIO(GPIO_RFRECV), // RF receiver +#endif +#ifdef USE_RF_SENSOR + AGPIO(GPIO_RF_SENSOR), // Rf receiver with sensor decoding +#endif +#ifdef USE_SR04 + AGPIO(GPIO_SR04_TRIG) + AGMAX(MAX_SR04), // SR04 Tri/TXgger pin + AGPIO(GPIO_SR04_ECHO) + AGMAX(MAX_SR04), // SR04 Ech/RXo pin +#endif +#ifdef USE_ME007 + AGPIO(GPIO_ME007_TRIG), // ME007 Trigger pin (xsns_23_me007.ino) + AGPIO(GPIO_ME007_RX), // ME007 Rx pin (xsns_23_me007.ino) +#endif +#ifdef USE_TM1638 + AGPIO(GPIO_TM1638CLK), // TM1638 Clock + AGPIO(GPIO_TM1638DIO), // TM1638 Data I/O + AGPIO(GPIO_TM1638STB), // TM1638 Strobe +#endif +#ifdef USE_HX711 + AGPIO(GPIO_HX711_SCK), // HX711 Load Cell clock + AGPIO(GPIO_HX711_DAT), // HX711 Load Cell data +#endif +#ifdef USE_TFMINIPLUS + AGPIO(GPIO_TFMINIPLUS_TX), // TFmini Plus TX pin + AGPIO(GPIO_TFMINIPLUS_RX), // TFmini Plus RX pin +#endif + +/*-------------------------------------------------------------------------------------------*\ + * Energy sensors +\*-------------------------------------------------------------------------------------------*/ + +#ifdef USE_ENERGY_SENSOR +#ifdef USE_HLW8012 + AGPIO(GPIO_NRG_SEL), // HLW8012/HLJ-01 Sel output (1 = Voltage) + AGPIO(GPIO_NRG_SEL_INV), // HLW8012/HLJ-01 Sel output (0 = Voltage) + AGPIO(GPIO_NRG_CF1), // HLW8012/HLJ-01 CF1 voltage / current + AGPIO(GPIO_HLW_CF), // HLW8012 CF power + AGPIO(GPIO_HJL_CF), // HJL-01/BL0937 CF power +#endif +#if defined(USE_I2C) && defined(USE_ADE7880) + AGPIO(GPIO_ADE7880_IRQ) + AGMAX(2), // ADE7880 IRQ - (1 = IRQ1, 2 = IRQ2) +#endif +#ifdef USE_ADE7953 +#if defined(USE_I2C) || defined(USE_SPI) + AGPIO(GPIO_ADE7953_IRQ) + AGMAX(6), // ADE7953 IRQ - (1 = Shelly 2.5, 2 = Shelly EM, 3 = Shelly Plus 2PM, 4 = Shelly Pro 1PM, 5 = Shelly Pro 2PM, 6 = Shelly Pro 4PM) + AGPIO(GPIO_ADE7953_RST), // ADE7953 Reset +#ifdef USE_SPI + AGPIO(GPIO_ADE7953_CS) + AGMAX(2), // ADE7953 SPI Chip Select (1 = CS1 (1PM, 2PM), 2 = CS2 (2PM)) +#endif // USE_SPI +#endif // USE_I2C or USE_SPI +#endif // USE_ADE7953 +#ifdef USE_CSE7761 + AGPIO(GPIO_CSE7761_TX), // CSE7761 Serial interface (Dual R3) + AGPIO(GPIO_CSE7761_RX) + AGMAX(MAX_CSE7761), // CSE7761 Serial interface (1 = Dual R3, 2 = POWCT) +#endif +#ifdef USE_CSE7766 + AGPIO(GPIO_CSE7766_TX), // CSE7766 Serial interface (S31 and Pow R2) + AGPIO(GPIO_CSE7766_RX), // CSE7766 Serial interface (S31 and Pow R2) +#endif +#ifdef USE_MCP39F501 + AGPIO(GPIO_MCP39F5_TX), // MCP39F501 Serial interface (Shelly2) + AGPIO(GPIO_MCP39F5_RX), // MCP39F501 Serial interface (Shelly2) + AGPIO(GPIO_MCP39F5_RST), // MCP39F501 Reset (Shelly2) +#endif + AGPIO(GPIO_NRG_MBS_TX_ENA), // Generic Energy Modbus Transmit Enable +#if defined(USE_PZEM004T) || defined(USE_PZEM_AC) || defined(USE_PZEM_DC) + AGPIO(GPIO_PZEM0XX_TX), // PZEM0XX Serial interface +#endif +#ifdef USE_PZEM004T + AGPIO(GPIO_PZEM004_RX), // PZEM004T Serial interface +#endif +#ifdef USE_PZEM_AC + AGPIO(GPIO_PZEM016_RX), // PZEM-014,016 Serial Modbus interface +#endif +#ifdef USE_PZEM_DC + AGPIO(GPIO_PZEM017_RX), // PZEM-003,017 Serial Modbus interface +#endif +#ifdef USE_MODBUS_ENERGY + AGPIO(GPIO_NRG_MBS_TX), // Generic Energy Modbus device + AGPIO(GPIO_NRG_MBS_RX), +#endif +#ifdef USE_SDM120 + AGPIO(GPIO_SDM120_TX), // SDM120 Serial interface + AGPIO(GPIO_SDM120_RX), // SDM120 Serial interface +#endif +#ifdef USE_SDM630 + AGPIO(GPIO_SDM630_TX), // SDM630 Serial interface + AGPIO(GPIO_SDM630_RX), // SDM630 Serial interface +#endif +#ifdef USE_DDS2382 + AGPIO(GPIO_DDS2382_TX), // DDS2382 Serial interface + AGPIO(GPIO_DDS2382_RX), // DDS2382 Serial interface +#endif +#ifdef USE_DDSU666 + AGPIO(GPIO_DDSU666_TX), // DDSU666 Serial interface + AGPIO(GPIO_DDSU666_RX), // DDSU666 Serial interface +#endif // USE_DDSU666 +#ifdef USE_SOLAX_X1 + AGPIO(GPIO_SOLAXX1_TX), // Solax Inverter tx pin + AGPIO(GPIO_SOLAXX1_RX), // Solax Inverter rx pin + AGPIO(GPIO_SOLAXX1_RTS), // Solax Inverter RTS pin +#endif // USE_SOLAX_X1 +#ifdef USE_LE01MR + AGPIO(GPIO_LE01MR_TX), // F7F LE-01MR energy meter tx pin + AGPIO(GPIO_LE01MR_RX), // F7F LE-01MR energy meter rx pin +#endif // USE_LE01MR +#ifdef ESP32 +#ifdef USE_BL0906 + AGPIO(GPIO_BL0906_RX) + AGMAX(MAX_BL0906_RX), // BL0906 Serial interface (Athom EM6) +#endif // USE_BL0906 +#endif // ESP32 +#if defined(USE_BL0940) || defined(USE_BL09XX) + AGPIO(GPIO_BL0939_RX), // BL0939 Serial interface (Dual R3 v2) + AGPIO(GPIO_BL0940_RX), // BL0940 Serial interface + AGPIO(GPIO_BL0942_RX) + AGMAX(MAX_BL0942_RX), // BL0942 Serial interface +#endif +#ifdef USE_IEM3000 + AGPIO(GPIO_IEM3000_TX), // IEM3000 Serial interface + AGPIO(GPIO_IEM3000_RX), // IEM3000 Serial interface +#endif +#ifdef USE_WE517 + AGPIO(GPIO_WE517_TX), // WE517 Serial interface + AGPIO(GPIO_WE517_RX), // WE517 Serial interface +#endif +#ifdef USE_SDM72 + AGPIO(GPIO_SDM72_TX), // SDM72 Serial interface + AGPIO(GPIO_SDM72_RX), // SDM72 Serial interface +#endif + AGPIO(GPIO_ZEROCROSS), +#ifdef USE_SDM230 + AGPIO(GPIO_SDM230_TX), // SDM230 Serial interface + AGPIO(GPIO_SDM230_RX), // SDM230 Serial interface +#endif +#ifdef USE_BL6523 + AGPIO(GPIO_BL6523_TX), // BL6523 based Watt meter Serial interface + AGPIO(GPIO_BL6523_RX), // BL6523 based Watt meter Serial interface +#endif +#ifdef USE_V9240 + AGPIO(GPIO_V9240_TX), // Serial V9240 interface + AGPIO(GPIO_V9240_RX), // Serial V9240 interface +#endif +#ifdef USE_MAKE_SKY_BLUE + AGPIO(GPIO_MKSKYBLU_TX) + AGMAX(MAX_MKSKYBLU_IF), + AGPIO(GPIO_MKSKYBLU_RX) + AGMAX(MAX_MKSKYBLU_IF), +#endif +#endif // USE_ENERGY_SENSOR + +/*-------------------------------------------------------------------------------------------*\ + * Serial sensors +\*-------------------------------------------------------------------------------------------*/ + +#ifdef USE_SERIAL_BRIDGE + AGPIO(GPIO_SBR_TX), // Serial Bridge Serial interface + AGPIO(GPIO_SBR_RX), // Serial Bridge Serial interface +#endif +#ifdef USE_MODBUS_BRIDGE + AGPIO(GPIO_MBR_TX_ENA), // Modbus Bridge Serial interface + AGPIO(GPIO_MBR_TX), // Modbus Bridge Serial interface + AGPIO(GPIO_MBR_RX), // Modbus Bridge Serial interface +#endif +#ifdef USE_TCP_BRIDGE + AGPIO(GPIO_TCP_TX), // TCP Serial bridge + AGPIO(GPIO_TCP_RX), // TCP Serial bridge + AGPIO(GPIO_TCP_TX_EN), // TCP Serial bridge EN +#endif +#ifdef USE_ZIGBEE + AGPIO(GPIO_ZIGBEE_TX), // Zigbee Serial interface + AGPIO(GPIO_ZIGBEE_RX), // Zigbee Serial interface + AGPIO(GPIO_ZIGBEE_RST) + AGMAX(2), // Zigbee reset, pin 1 is reset, pin 2 is bootloader mode +#endif +#ifdef USE_MHZ19 + AGPIO(GPIO_MHZ_TXD), // MH-Z19 Serial interface + AGPIO(GPIO_MHZ_RXD), // MH-Z19 Serial interface +#endif +#ifdef USE_HC8 + AGPIO(GPIO_HC8_RXD), // HC8 Serial interface +#endif +#ifdef USE_SENSEAIR + AGPIO(GPIO_SAIR_TX), // SenseAir Serial interface + AGPIO(GPIO_SAIR_RX), // SenseAir Serial interface +#endif +#ifdef USE_NOVA_SDS + AGPIO(GPIO_SDS0X1_TX), // Nova Fitness SDS011 Serial interface + AGPIO(GPIO_SDS0X1_RX), // Nova Fitness SDS011 Serial interface +#endif +#ifdef USE_HPMA + AGPIO(GPIO_HPMA_TX), // Honeywell HPMA115S0 Serial interface + AGPIO(GPIO_HPMA_RX), // Honeywell HPMA115S0 Serial interface +#endif +#ifdef USE_PMS5003 + AGPIO(GPIO_PMS5003_TX), // Plantower PMS5003 Serial interface + AGPIO(GPIO_PMS5003_RX), // Plantower PMS5003 Serial interface +#endif +#ifdef USE_VINDRIKTNING + AGPIO(GPIO_VINDRIKTNING_RX), // Ikea Vindriktning +#endif +#ifdef USE_HM330X + AGPIO(GPIO_HM330X_SET), // HM330X Sleep pin (active low) +#endif +#if defined(USE_TX20_WIND_SENSOR) || defined(USE_TX23_WIND_SENSOR) || defined(USE_WS2300_WIND_SENSOR) + AGPIO(GPIO_TX2X_TXD_BLACK), // TX20/TX23 Transmission Pin +#endif +#ifdef USE_WINDMETER + AGPIO(GPIO_WINDMETER_SPEED), +#endif +#ifdef USE_MP3_PLAYER + AGPIO(GPIO_MP3_DFR562), // RB-DFR-562, DFPlayer Mini MP3 Player Serial interface + AGPIO(GPIO_MP3_DFR562_BUSY), // RB-DFR-562, DFPlayer Mini MP3 Player optional Busy flag + #endif +#ifdef USE_AZ7798 + AGPIO(GPIO_AZ_TXD), // AZ-Instrument 7798 CO2 datalogger Serial interface + AGPIO(GPIO_AZ_RXD), // AZ-Instrument 7798 CO2 datalogger Serial interface +#endif +#ifdef USE_PN532_HSU + AGPIO(GPIO_PN532_TXD), // PN532 HSU Tx + AGPIO(GPIO_PN532_RXD), // PN532 HSU Rx +#endif +#ifdef USE_TASMOTA_CLIENT + AGPIO(GPIO_TASMOTACLIENT_TXD), // Tasmota Client TX + AGPIO(GPIO_TASMOTACLIENT_RXD), // Tasmota Client RX + AGPIO(GPIO_TASMOTACLIENT_RST), // Tasmota Client Reset + AGPIO(GPIO_TASMOTACLIENT_RST_INV), // Tasmota Client Reset Inverted +#endif +#ifdef USE_RDM6300 + AGPIO(GPIO_RDM6300_RX), +#endif +#ifdef USE_IBEACON + AGPIO(GPIO_IBEACON_TX), + AGPIO(GPIO_IBEACON_RX), +#endif +#ifdef USE_GPS + AGPIO(GPIO_GPS_TX), // GPS serial interface + AGPIO(GPIO_GPS_RX) + AGMAX(MAX_GPS_RX), // GPS serial interface +#endif +#ifdef USE_HM10 + AGPIO(GPIO_HM10_TX), // HM10 serial interface + AGPIO(GPIO_HM10_RX), // HM10 serial interface +#endif +#ifdef USE_OPENTHERM + AGPIO(GPIO_BOILER_OT_TX), + AGPIO(GPIO_BOILER_OT_RX), +#endif +#ifdef USE_AS608 + AGPIO(GPIO_AS608_TX), + AGPIO(GPIO_AS608_RX), +#endif +#ifdef USE_GM861 + AGPIO(GPIO_GM861_TX), + AGPIO(GPIO_GM861_RX), +#endif +#ifdef USE_HRG15 + AGPIO(GPIO_HRG15_TX), + AGPIO(GPIO_HRG15_RX), +#endif +#ifdef USE_CM110x + AGPIO(GPIO_CM11_TXD), // CM110x Serial interface + AGPIO(GPIO_CM11_RXD), // CM110x Serial interface +#endif +#ifdef USE_LD2402 + AGPIO(GPIO_LD2402_TX), // HLK-LD2402 Serial interface + AGPIO(GPIO_LD2402_RX), // HLK-LD2402 Serial interface +#endif +#ifdef USE_LD2410 + AGPIO(GPIO_LD2410_TX), // HLK-LD2410 Serial interface + AGPIO(GPIO_LD2410_RX), // HLK-LD2410 Serial interface +#endif +#ifdef USE_LD2410S + AGPIO(GPIO_LD2410S_TX), // HLK-LD2410S Serial interface + AGPIO(GPIO_LD2410S_RX), // HLK-LD2410S Serial interface +#endif +#ifdef USE_LOX_O2 + AGPIO(GPIO_LOX_O2_RX), // LuminOx Oxygen Sensor LOX-O2 Serial interface +#endif +#ifdef USE_LORAWAN_RN2XX3 + AGPIO(GPIO_RN2XX3_TX), + AGPIO(GPIO_RN2XX3_RX), + AGPIO(GPIO_RN2XX3_RST), // RN2XX3 LoRaWan node Serial interface +#endif +#ifdef USE_LORAWAN_ASR650X + AGPIO(GPIO_ASR650X_TX), + AGPIO(GPIO_ASR650X_RX), // ASR650X LoRaWan node Serial interface +#endif +#ifdef USE_WOOLIIS + AGPIO(GPIO_WOOLIIS_RX), // Wooliis Battery capacity monitor Serial interface +#endif +#ifdef USE_C8_CO2_5K + AGPIO(GPIO_C8_CO2_5K_TX), // SC8-CO2-5K Serial interface + AGPIO(GPIO_C8_CO2_5K_RX), // SC8-CO2-5K Serial interface +#endif + +#ifdef ESP32 +#ifdef USE_ESP32_TWAI +#if SOC_TWAI_SUPPORTED + AGPIO(GPIO_TWAI_TX) + AGMAX(MAX_TWAI), // ESP32 TWAI serial interface + AGPIO(GPIO_TWAI_RX) + AGMAX(MAX_TWAI), + AGPIO(GPIO_TWAI_BO) + AGMAX(MAX_TWAI), + AGPIO(GPIO_TWAI_CLK) + AGMAX(MAX_TWAI), +#endif +#endif +#endif + +/*-------------------------------------------------------------------------------------------*\ + * Other sensors +\*-------------------------------------------------------------------------------------------*/ + +#ifdef USE_MGC3130 + AGPIO(GPIO_MGC3130_XFER), + AGPIO(GPIO_MGC3130_RESET), +#endif +#ifdef USE_MAX31855 + AGPIO(GPIO_MAX31855CS) + AGMAX(MAX_MAX31855S), // MAX31855 Serial interface + AGPIO(GPIO_MAX31855CLK), // MAX31855 Serial interface + AGPIO(GPIO_MAX31855DO), // MAX31855 Serial interface +#endif +#ifdef USE_HRE + AGPIO(GPIO_HRE_CLOCK), + AGPIO(GPIO_HRE_DATA), +#endif +#ifdef USE_A4988_STEPPER + AGPIO(GPIO_A4988_DIR), // A4988 direction pin + AGPIO(GPIO_A4988_STP), // A4988 step pin + // folowing are not mandatory + AGPIO(GPIO_A4988_ENA), // A4988 enabled pin + AGPIO(GPIO_A4988_MS1) + AGMAX(MAX_A4988_MSS), // A4988 microstep pin1 to pin3 +#endif +#ifdef USE_DEEPSLEEP + AGPIO(GPIO_DEEPSLEEP), +#endif +#ifdef USE_KEELOQ + AGPIO(GPIO_CC1101_GDO0), // CC1101 pin for RX + AGPIO(GPIO_CC1101_GDO2), // CC1101 pin for RX +#endif +#ifdef USE_HRXL + AGPIO(GPIO_HRXL_RX), +#endif +#ifdef USE_DYP + AGPIO(GPIO_DYP_RX), +#endif +#ifdef USE_AS3935 + AGPIO(GPIO_AS3935), // AS3935 IRQ Pin +#endif +#ifdef USE_TELEINFO + AGPIO(GPIO_TELEINFO_RX), + AGPIO(GPIO_TELEINFO_ENABLE), +#endif +#ifdef USE_MIEL_HVAC + AGPIO(GPIO_MIEL_HVAC_TX), // Mitsubishi Electric HVAC TX pin + AGPIO(GPIO_MIEL_HVAC_RX), // Mitsubishi Electric HVAC RX pin +#endif +#ifdef USE_TUYAMCUBR + AGPIO(GPIO_TUYAMCUBR_TX), + AGPIO(GPIO_TUYAMCUBR_RX), +#endif +#ifdef USE_WIEGAND + AGPIO(GPIO_WIEGAND_D0), // Data line D0 of Wiegand devices + AGPIO(GPIO_WIEGAND_D1), // Data line D1 of Wiegand devices +#endif +#ifdef USE_NEOPOOL + AGPIO(GPIO_NEOPOOL_TX), // Sugar Valley RS485 Interface + AGPIO(GPIO_NEOPOOL_RX), // Sugar Valley RS485 Interface +#endif +#ifdef USE_PROJECTOR_CTRL + AGPIO(GPIO_PROJECTOR_CTRL_TX), // LCD/DLP Projector Serial Control + AGPIO(GPIO_PROJECTOR_CTRL_RX), // LCD/DLP Projector Serial Control +#endif +#if defined(USE_VL53L0X) or defined (USE_VL53L1X) + AGPIO(GPIO_VL53LXX_XSHUT1) + AGMAX(VL53LXX_MAX_SENSORS), // When using multiple VL53LXX. +#endif +#ifdef USE_FLOWRATEMETER + AGPIO(GPIO_FLOWRATEMETER_IN) + AGMAX(MAX_FLOWRATEMETER), // Flow meter Pin +#endif + +#ifdef USE_SHIFT595 + AGPIO(GPIO_SHIFT595_SRCLK), // 74x595 shift register + AGPIO(GPIO_SHIFT595_RCLK), + AGPIO(GPIO_SHIFT595_OE), + AGPIO(GPIO_SHIFT595_SER), +#endif + +#if defined (ESP32) && defined(USE_DINGTIAN_RELAY) + AGPIO(GPIO_DINGTIAN_CLK) + AGMAX(MAX_DINGTIAN_SHIFT), // Dingtian Relay board - 8,16,24 or 32 relays & inputs + AGPIO(GPIO_DINGTIAN_SDI), + AGPIO(GPIO_DINGTIAN_Q7), + AGPIO(GPIO_DINGTIAN_PL), + AGPIO(GPIO_DINGTIAN_OE), + AGPIO(GPIO_DINGTIAN_RCK), +#endif + +#ifdef USE_MAGIC_SWITCH + AGPIO(GPIO_MAGIC_SWITCH) + AGMAX(MAX_MAGIC_SWITCH_MODES), +#endif + +#ifdef USE_PIPSOLAR + AGPIO(GPIO_PIPSOLAR_TX), // pipsolar inverter Serial interface + AGPIO(GPIO_PIPSOLAR_RX), // pipsolar inverter Serial interface +#endif + +/*-------------------------------------------------------------------------------------------*\ + * ESP32 specifics +\*-------------------------------------------------------------------------------------------*/ + +#ifdef ESP32 +#if CONFIG_IDF_TARGET_ESP32 + AGPIO(GPIO_HALLEFFECT) + AGMAX(2), // Hall effect sensor connected to GPIO36 and 39 +#endif // CONFIG_IDF_TARGET_ESP32 +#ifdef USE_WEBCAM + AGPIO(GPIO_WEBCAM_PWDN), + AGPIO(GPIO_WEBCAM_RESET), + AGPIO(GPIO_WEBCAM_XCLK), + AGPIO(GPIO_WEBCAM_SIOD), + AGPIO(GPIO_WEBCAM_SIOC), + AGPIO(GPIO_WEBCAM_DATA) + AGMAX(MAX_WEBCAM_DATA), + AGPIO(GPIO_WEBCAM_VSYNC), + AGPIO(GPIO_WEBCAM_HREF), + AGPIO(GPIO_WEBCAM_PCLK), + AGPIO(GPIO_WEBCAM_PSCLK), + AGPIO(GPIO_WEBCAM_HSD) + AGMAX(MAX_WEBCAM_HSD), + AGPIO(GPIO_WEBCAM_PSRCS), +#endif // USE_WEBCAM +#ifdef USE_ETHERNET + AGPIO(GPIO_ETH_PHY_POWER), + AGPIO(GPIO_ETH_PHY_MDC) + AGMAX(MAX_SPI), + AGPIO(GPIO_ETH_PHY_MDIO), // Ethernet +#endif // USE_ETHERNET +#ifdef USE_BIOPDU + AGPIO(GPIO_BIOPDU_PZEM0XX_TX), // Biomine BioPDU pins + AGPIO(GPIO_BIOPDU_PZEM016_RX), + AGPIO(GPIO_BIOPDU_BIT) + AGMAX(3), +#endif +#ifdef CONFIG_ESP_WIFI_REMOTE_ENABLED + AGPIO(GPIO_HSDIO_CMD), // Hosted MCU SDIO interface, including 1-bit and 4-bit modes + AGPIO(GPIO_HSDIO_CLK), + AGPIO(GPIO_HSDIO_RST), + AGPIO(GPIO_HSDIO_D0), + AGPIO(GPIO_HSDIO_D1), + AGPIO(GPIO_HSDIO_D2), + AGPIO(GPIO_HSDIO_D3), +#endif // CONFIG_ESP_WIFI_REMOTE_ENABLED + +/*-------------------------------------------------------------------------------------------*\ + * ESP32 multiple Analog / Digital converter inputs +\*-------------------------------------------------------------------------------------------*/ + + AGPIO(GPIO_ADC_INPUT) + AGMAX(MAX_ADCS), // Analog inputs + AGPIO(GPIO_ADC_TEMP) + AGMAX(MAX_ADCS), // Thermistor + AGPIO(GPIO_ADC_LIGHT) + AGMAX(MAX_ADCS), // Light sensor + AGPIO(GPIO_ADC_BUTTON) + AGMAX(MAX_KEYS), // Button + AGPIO(GPIO_ADC_BUTTON_INV) + AGMAX(MAX_KEYS), + AGPIO(GPIO_ADC_RANGE) + AGMAX(MAX_ADCS), // Range + AGPIO(GPIO_ADC_CT_POWER) + AGMAX(MAX_ADCS), // Current + AGPIO(GPIO_ADC_JOY) + AGMAX(MAX_ADCS), // Joystick + AGPIO(GPIO_ADC_PH) + AGMAX(MAX_ADCS), // Analog PH Sensor + AGPIO(GPIO_ADC_MQ) + AGMAX(MAX_ADCS), // Analog MQ Sensor + AGPIO(GPIO_ADC_VOLTAGE) + AGMAX(MAX_ADCS), // Voltage + AGPIO(GPIO_ADC_CURRENT) + AGMAX(MAX_ADCS), // Current +#endif // ESP32 + + +#ifdef USE_VID6608 + AGPIO(GPIO_VID6608_F) + AGMAX(4), // VID6608 step interface (max 4 motors) + AGPIO(GPIO_VID6608_CW) + AGMAX(4), // VID6608 direction interface (max 4 motors) +#endif + +}; + +/*-------------------------------------------------------------------------------------------*\ + * ESP8266 single Analog / Digital converter input +\*-------------------------------------------------------------------------------------------*/ + +#ifdef ESP8266 +const uint16_t kAdcNiceList[] PROGMEM = { + GPIO_NONE, // Not used + AGPIO(GPIO_ADC_INPUT), // Analog inputs + AGPIO(GPIO_ADC_TEMP), // Thermistor + AGPIO(GPIO_ADC_LIGHT), // Light sensor + AGPIO(GPIO_ADC_BUTTON) + AGMAX(MAX_KEYS), // Button + AGPIO(GPIO_ADC_BUTTON_INV) + AGMAX(MAX_KEYS), + AGPIO(GPIO_ADC_RANGE), // Range + AGPIO(GPIO_ADC_CT_POWER), // Current + AGPIO(GPIO_ADC_JOY), // Joystick + AGPIO(GPIO_ADC_PH), // Analog PH Sensor + AGPIO(GPIO_ADC_MQ), // Analog MQ Sensor + AGPIO(GPIO_ADC_VOLTAGE), // Voltage + AGPIO(GPIO_ADC_CURRENT), // Current +}; +#endif // ESP8266 + +/*********************************************************************************************\ + * ATTENTION: No user changeable features beyond this point - do not add templates !!! +\*********************************************************************************************/ + +#define GPIO_ANY 32 // Any GPIO + +#ifdef ESP8266 + +#define MAX_GPI8_PIN 17 // Number of supported GPIO (0..16) +#define FLASH_PINS 6 // Number of flash chip pins + +#define MAX_GPIO_PIN 18 // Number of supported GPIO (0..16 + ADC0) +#define ADC0_PIN 17 // Pin number of ADC0 +#define MIN_FLASH_PINS 4 // Number of flash chip pins unusable for configuration (GPIO6, 7, 8 and 11) +#define MAX_USER_PINS 14 // MAX_GPIO_PIN - MIN_FLASH_PINS +#define WEMOS_MODULE 17 // Wemos module + +const char PINS_WEMOS[] PROGMEM = "D3TXD4RXD2D1flashcFLFLolD6D7D5D8D0A0"; + +typedef struct MYIO8 { + uint8_t io[MAX_GPI8_PIN]; +} myio8; // 17 bytes + +typedef struct MYCFGIO8285 { + uint8_t io[MAX_GPI8_PIN - MIN_FLASH_PINS]; +} mycfgio8285; // 13 bytes + +typedef struct MYTMPLT8285 { + mycfgio8285 gp; + uint8_t flag; +} mytmplt8285; // 14 bytes + +typedef struct MYCFGIO8266 { + uint8_t io[MAX_GPI8_PIN - FLASH_PINS]; +} mycfgio8266; // 11 bytes + +typedef struct MYTMPLT8266 { + mycfgio8266 gp; + uint8_t flag; +} mytmplt8266; // 12 bytes + +#endif // ESP8266 + +#ifdef ESP32 +#if CONFIG_IDF_TARGET_ESP32C2 + +/* **************************************** + * ESP32C2 + * ****************************************/ +#define MAX_GPIO_PIN 21 // Number of supported GPIO +#define MIN_FLASH_PINS 0 // Number of flash chip pins unusable for configuration (GPIO11 to 17) +#define MAX_USER_PINS 21 // MAX_GPIO_PIN - MIN_FLASH_PINS +#define WEMOS_MODULE 0 // Wemos module + +// 0 1 2 3 4 5 6 7 8 91011121314151617181920 +const char PINS_WEMOS[] PROGMEM = "AOAOAOAOAOIOIOIOIOIOIOFLFLFLFLFLFLFLIORXTX"; + +#elif CONFIG_IDF_TARGET_ESP32C3 + +/* **************************************** + * ESP32C3 + * ****************************************/ +#define MAX_GPIO_PIN 22 // Number of supported GPIO +#define MIN_FLASH_PINS 0 // Number of flash chip pins unusable for configuration (GPIO11 to 17) +#define MAX_USER_PINS 22 // MAX_GPIO_PIN - MIN_FLASH_PINS +#define WEMOS_MODULE 0 // Wemos module + +// 0 1 2 3 4 5 6 7 8 9101112131415161718192021 +const char PINS_WEMOS[] PROGMEM = "AOAOAOAOAOAOIOIOIOIOIOFLFLFLFLFLFLFLIOIORXTX"; + +#elif CONFIG_IDF_TARGET_ESP32C5 // ESP32-C5 +/* **************************************** + * ESP32C5 + * ****************************************/ +#define MAX_GPIO_PIN 29 // Number of supported GPIO +#define MIN_FLASH_PINS 0 // Number of flash chip pins unusable for configuration (GPIO16-22 SPI0/1) +#define MAX_USER_PINS 29 // MAX_GPIO_PIN - MIN_FLASH_PINS +#define WEMOS_MODULE 0 // Wemos module + +// 0 1 2 3 4 5 6 7 8 91011121314151617181920212223242526272829 +const char PINS_WEMOS[] PROGMEM = "IOAOAOAOAOAOAOIOIOIOIOIOIOIOFLFLFLFLFLFLFLIOIOIOIOIOIOIOIOIO"; + +#elif CONFIG_IDF_TARGET_ESP32C6 + +/* **************************************** + * ESP32C6 + * ****************************************/ +#define MAX_GPIO_PIN 31 // Number of supported GPIO +#define MIN_FLASH_PINS 0 // Number of flash chip pins unusable for configuration (GPIO24 to 30) +#define MAX_USER_PINS 31 // MAX_GPIO_PIN - MIN_FLASH_PINS +#define WEMOS_MODULE 0 // Wemos module + +// 0 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930 +const char PINS_WEMOS[] PROGMEM = "AOAOAOAOAOAOAOIOIOIOIOIOIOIOIOIOTXRXIOIOIOIOIOIOFLFLFLFLFLFLFL"; + +#elif CONFIG_IDF_TARGET_ESP32S2 + +/* **************************************** + * ESP32S2 + * ****************************************/ +#define MAX_GPIO_PIN 47 // Number of supported GPIO +#define MIN_FLASH_PINS 11 // Number of flash chip pins unusable for configuration (22-25 don't exist, 26-32 for SPI) +#define MAX_USER_PINS 36 // MAX_GPIO_PIN - MIN_FLASH_PINS +#define WEMOS_MODULE 0 // Wemos module + +// 0 1 2 3 4 5 6 7 8 910111213141516171819202122232425262728293031323334353637383940414243444546 +const char PINS_WEMOS[] PROGMEM = "IOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOIO--------FLFLFLFLFLFLFLIOIOIOIOIOIOIOIOIOIOIOIOIOI "; + +#elif CONFIG_IDF_TARGET_ESP32S3 +/* **************************************** + * ESP32S3 + * GPIOs 0..21 + 33..48 + * - 22..25 are not used + * - 26..32 are used for SPI Flash + * - 33..37 are used by PSRAM + * ****************************************/ +#define MAX_GPIO_PIN 49 // Number of supported GPIO, 0..48 +#define MIN_FLASH_PINS 11 // Number of flash chip pins unusable for configuration (22-25 don't exist, 26-32 for SPI) +#define MAX_USER_PINS 38 // MAX_GPIO_PIN - MIN_FLASH_PINS +#define WEMOS_MODULE 0 // Wemos module + +// 0 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445464748 +const char PINS_WEMOS[] PROGMEM = "IOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOAOIO--------FLFLFLFLFLFLFLIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIO"; + +#elif CONFIG_IDF_TARGET_ESP32P4 +/* **************************************** + * ESP32P4 + * GPIOs 0..54 + * - 34..38 strapping pins + * ****************************************/ +#define MAX_GPIO_PIN 55 // Number of supported GPIO, 0..55 +#define MIN_FLASH_PINS 00 // Number of flash chip pins unusable for configuration (22-25 don't exist, 26-32 for SPI) +#define MAX_USER_PINS 55 // MAX_GPIO_PIN - MIN_FLASH_PINS +#define WEMOS_MODULE 0 // Wemos module + +// 0 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354 +const char PINS_WEMOS[] PROGMEM = "IOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOAOAOAOAOAOAOAOAOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOAOAOAOAOAOAO"; + +#else // not CONFIG_IDF_TARGET_ESP32C2/C3/C6 nor CONFIG_IDF_TARGET_ESP32S2 - ESP32 + +/* **************************************** + * ESP32 - including Pico + * + * The initial template was 0-5 9-10 12-39 + * New template covers 0-27 32-39 + * However to maintain backwards compatibility, the following mapping occures + * Template GPIO | Phyiscal GPIO + * 28 | 6 + * 29 | 7 + * 30 | 8 + * 31 | 11 + * ****************************************/ +// Conversion table +#define ESP32_TEMPLATE_TO_PHY \ + 0, 1, 2, 3, 4, 5, \ + 9, 10, \ + 12, 13, 14, 15, 16, 17, 18, 19, \ + 20, 21, 22, 23, 24, 25, 26, 27, \ + 6, 7, 8, 11, /* 28-31 */ \ + 32, 33, 34, 35, 36, 37, 38, 39 + +#define MAX_GPIO_PIN 40 // Number of supported GPIO +#define MIN_FLASH_PINS 4 // Number of flash chip pins unusable for configuration (GPIO6, 7, 8 and 11) +#define MAX_USER_PINS 36 // MAX_GPIO_PIN - MIN_FLASH_PINS +#define WEMOS_MODULE 0 // Wemos module + +// 0 1 2 3 4 5 6 7 8 9101112131415161718192021222324252627282930313233343536373839 +const char PINS_WEMOS[] PROGMEM = "IOTXIORXIOIOFLFLFLFLFLFLIOIOIOIOIOIOIOIOIOIOIOIOIOIOIOIO--------AOAOIAIAIAIAIAIA"; + +#endif // ESP32/S2/C2/C3/C6/P4 selection +#endif // ESP32 + +/********************************************************************************************\ + * !!! Changes in below type sizes impact Settings layout - Add fill bytes in Settings !!! +\********************************************************************************************/ + +typedef struct MYIO { + uint16_t io[MAX_GPIO_PIN]; +} myio; // ESP8266: 18*2 = 36 bytes / ESP32: 40*2 = 80 bytes / ESP32-C3: 22*2 = 44 bytes / ESP32-S2: 47*2 = 94 bytes / ESP32-S3: 49*2 = 98 bytes + +typedef struct MYCFGIO { + uint16_t io[MAX_USER_PINS]; +} mycfgio; // ESP8266: 14*2 = 28 bytes / ESP32: 36*2 = 72 bytes / ESP32-C3: 22*2 = 44 bytes / ESP32-S2: 36*2 = 72 bytes / ESP32-S3: 33*2 = 66 bytes + +#define GPIO_FLAG_USED 0 // Currently no flags used + +typedef union { + uint16_t data; + struct { + uint16_t spare00 : 1; + uint16_t spare01 : 1; + uint16_t spare02 : 1; + uint16_t spare03 : 1; + uint16_t spare04 : 1; + uint16_t spare05 : 1; + uint16_t spare06 : 1; + uint16_t spare07 : 1; + uint16_t spare08 : 1; + uint16_t spare09 : 1; + uint16_t spare10 : 1; + uint16_t spare11 : 1; + uint16_t spare12 : 1; + uint16_t spare13 : 1; + uint16_t spare14 : 1; + uint16_t spare15 : 1; + }; +} gpio_flag; // 2 bytes + +typedef struct MYTMPLT { + mycfgio gp; // 28 / 72 / 44 / 72 bytes + gpio_flag flag; // 2 bytes +} mytmplt; // 30 / 74 / 46 / 74 bytes + +//******************************************************************************************** + +#ifdef ESP8266 +#include "include/tasmota_template_legacy.h" + +/********************************************************************************************\ + * ESP8266 Module Templates +\********************************************************************************************/ + +#define USER_MODULE 255 + +// Supported ESP8266 hardware modules +enum SupportedModulesESP8266 { + SONOFF_BASIC, SONOFF_RF, SONOFF_SV, SONOFF_TH, SONOFF_DUAL, SONOFF_POW, SONOFF_4CH, SONOFF_S2X, SLAMPHER, SONOFF_TOUCH, + SONOFF_LED, CH1, CH4, MOTOR, ELECTRODRAGON, EXS_RELAY, WION, WEMOS, SONOFF_DEV, H801, + SONOFF_SC, SONOFF_BN, SONOFF_4CHPRO, HUAFAN_SS, SONOFF_BRIDGE, SONOFF_B1, AILIGHT, SONOFF_T11, SONOFF_T12, SONOFF_T13, + SUPLA1, WITTY, YUNSHAN, MAGICHOME, LUANIHVIO, KMC_70011, ARILUX_LC01, ARILUX_LC11, SONOFF_DUAL_R2, ARILUX_LC06, + SONOFF_S31, ZENGGE_ZF_WF017, SONOFF_POW_R2, SONOFF_IFAN02, BLITZWOLF_BWSHP, SHELLY1, SHELLY2, PHILIPS, NEO_COOLCAM, ESP_SWITCH, + OBI, TECKIN, APLIC_WDP303075, TUYA_DIMMER, GOSUND, ARMTRONIX_DIMMERS, SK03_TUYA, PS_16_DZ, TECKIN_US, MANZOKU_EU_4, + OBI2, YTF_IR_BRIDGE, DIGOO, KA10, ZX2820, MI_DESK_LAMP, SP10, WAGA, SYF05, SONOFF_L1, + SONOFF_IFAN03, EXS_DIMMER, PWM_DIMMER, SONOFF_D1, SONOFF_ZB_BRIDGE, + MAXMODULE }; + +const char kModuleNames[] PROGMEM = + "Sonoff Basic|Sonoff RF|Sonoff SV|Sonoff TH|Sonoff Dual|Sonoff Pow|Sonoff 4CH|Sonoff S2X|Slampher|Sonoff Touch|" + "Sonoff LED|1 Channel|4 Channel|Motor C/AC|ElectroDragon|EXS Relay(s)|WiOn|Generic|Sonoff Dev|H801|" + "Sonoff SC|Sonoff BN-SZ|Sonoff 4CH Pro|Huafan SS|Sonoff Bridge|Sonoff B1|AiLight|Sonoff T1 1CH|Sonoff T1 2CH|Sonoff T1 3CH|" + "Supla Espablo|Witty Cloud|Yunshan Relay|MagicHome|Luani HVIO|KMC 70011|Arilux LC01|Arilux LC11|Sonoff Dual R2|Arilux LC06|" + "Sonoff S31|Zengge WF017|Sonoff Pow R2|Sonoff iFan02|BlitzWolf SHP|Shelly 1|Shelly 2|Xiaomi Philips|Neo Coolcam|ESP Switch|" + "OBI Socket|Teckin|AplicWDP303075|Tuya MCU|Gosund SP1 v23|ARMTR Dimmer|SK03 Outdoor|PS-16-DZ|Teckin US|Manzoku strip|" + "OBI Socket 2|YTF IR Bridge|Digoo DG-SP202|KA10|Luminea ZX2820|Mi Desk Lamp|SP10|WAGA CHCZ02MB|SYF05|Sonoff L1|" + "Sonoff iFan03|EXS Dimmer|PWM Dimmer|Sonoff D1|Sonoff ZbBridge" + ; + +const uint8_t kModuleNiceList[] PROGMEM = { + SONOFF_BASIC, // Sonoff Relay Devices + SONOFF_RF, + SONOFF_TH, + SONOFF_DUAL, + SONOFF_DUAL_R2, + SONOFF_POW, + SONOFF_POW_R2, + SONOFF_4CH, + SONOFF_4CHPRO, + SONOFF_S31, // Sonoff Socket Relay Devices with Energy Monitoring + SONOFF_S2X, // Sonoff Socket Relay Devices + SONOFF_TOUCH, // Sonoff Switch Devices + SONOFF_T11, + SONOFF_T12, + SONOFF_T13, +#ifdef USE_SONOFF_D1 + SONOFF_D1, // Sonoff D1 +#endif + SONOFF_LED, // Sonoff Light Devices + SONOFF_BN, +#ifdef USE_SONOFF_L1 + SONOFF_L1, +#endif + SONOFF_B1, // Sonoff Light Bulbs + SLAMPHER, +#ifdef USE_SONOFF_SC + SONOFF_SC, // Sonoff Environmemtal Sensor +#endif +#ifdef USE_SONOFF_IFAN + SONOFF_IFAN02, // Sonoff Fan + SONOFF_IFAN03, +#endif +#ifdef USE_SONOFF_RF + SONOFF_BRIDGE, // Sonoff Bridge +#endif +#ifdef USE_ZIGBEE_EZSP + SONOFF_ZB_BRIDGE, +#endif + SONOFF_SV, // Sonoff Development Devices + SONOFF_DEV, + CH1, // Relay Devices + CH4, + MOTOR, + ELECTRODRAGON, + EXS_RELAY, + SUPLA1, + LUANIHVIO, + YUNSHAN, + WION, + SHELLY1, + SHELLY2, + BLITZWOLF_BWSHP, // Socket Relay Devices with Energy Monitoring + TECKIN, + TECKIN_US, + APLIC_WDP303075, + GOSUND, + ZX2820, + SK03_TUYA, + DIGOO, + KA10, + SP10, + WAGA, + NEO_COOLCAM, // Socket Relay Devices + OBI, + OBI2, + MANZOKU_EU_4, + ESP_SWITCH, // Switch Devices +#ifdef USE_TUYA_MCU + TUYA_DIMMER, // Dimmer Devices +#endif +#ifdef USE_ARMTRONIX_DIMMERS + ARMTRONIX_DIMMERS, +#endif +#ifdef USE_PS_16_DZ + PS_16_DZ, +#endif +#ifdef USE_EXS_DIMMER + EXS_DIMMER, +#endif +#ifdef USE_PWM_DIMMER + PWM_DIMMER, +#endif + H801, // Light Devices + MAGICHOME, + ARILUX_LC01, + ARILUX_LC06, + ARILUX_LC11, + ZENGGE_ZF_WF017, + HUAFAN_SS, +#ifdef ROTARY_V1 + MI_DESK_LAMP, +#endif + KMC_70011, + AILIGHT, // Light Bulbs + PHILIPS, + SYF05, + YTF_IR_BRIDGE, + WITTY, // Development Devices + WEMOS +}; + +enum SupportedTemplates8285 { + TMP_SONOFF_BASIC, TMP_SONOFF_SV, TMP_SONOFF_DUAL, TMP_SONOFF_POW, TMP_SONOFF_LED, TMP_ELECTRODRAGON, + TMP_EXS_RELAY, TMP_WION, TMP_SONOFF_DEV, TMP_H801, TMP_SONOFF_SC, TMP_SONOFF_BN, TMP_HUAFAN_SS, TMP_SONOFF_BRIDGE, + TMP_SONOFF_B1, TMP_AILIGHT, TMP_SONOFF_T11, TMP_SUPLA1, TMP_WITTY, TMP_YUNSHAN, TMP_MAGICHOME, + TMP_LUANIHVIO, TMP_KMC_70011, TMP_ARILUX_LC01, TMP_ARILUX_LC11, TMP_ARILUX_LC06, TMP_ZENGGE_ZF_WF017, + TMP_SONOFF_POW_R2, TMP_BLITZWOLF_BWSHP, TMP_SHELLY1, TMP_SHELLY2, TMP_PHILIPS, TMP_NEO_COOLCAM, TMP_ESP_SWITCH, TMP_OBI, + TMP_TECKIN, TMP_APLIC_WDP303075, TMP_TUYA_DIMMER, TMP_GOSUND, TMP_ARMTRONIX_DIMMERS, TMP_SK03_TUYA, TMP_PS_16_DZ, + TMP_TECKIN_US, TMP_MANZOKU_EU_4, TMP_OBI2, TMP_YTF_IR_BRIDGE, TMP_DIGOO, TMP_KA10, TMP_ZX2820, TMP_MI_DESK_LAMP, TMP_SP10, + TMP_WAGA, TMP_SYF05, TMP_EXS_DIMMER, TMP_PWM_DIMMER, TMP_SONOFF_ZB_BRIDGE, + TMP_MAXMODULE_8285 }; + +enum SupportedTemplates8266 { + TMP_WEMOS = TMP_MAXMODULE_8285, TMP_SONOFF_4CH, TMP_SONOFF_T12, TMP_SONOFF_T13, TMP_SONOFF_DUAL_R2, TMP_SONOFF_IFAN03, + TMP_MAXMODULE_8266 }; + +const uint8_t kModuleTemplateList[MAXMODULE] PROGMEM = { + TMP_SONOFF_BASIC, + TMP_SONOFF_BASIC, // SONOFF_RF + TMP_SONOFF_SV, + TMP_SONOFF_BASIC, // SONOFF_TH + TMP_SONOFF_DUAL, + TMP_SONOFF_POW, + TMP_SONOFF_4CH, + TMP_SONOFF_BASIC, // SONOFF_S2X + TMP_SONOFF_BASIC, // SLAMPHER + TMP_SONOFF_T11, // SONOFF_TOUCH + TMP_SONOFF_LED, + TMP_SONOFF_BASIC, // CH1 + TMP_SONOFF_DUAL, // CH4 + TMP_SONOFF_BASIC, // MOTOR + TMP_ELECTRODRAGON, + TMP_EXS_RELAY, + TMP_WION, + TMP_WEMOS, + TMP_SONOFF_DEV, + TMP_H801, + TMP_SONOFF_SC, + TMP_SONOFF_BN, + TMP_SONOFF_4CH, // SONOFF_4CHPRO + TMP_HUAFAN_SS, + TMP_SONOFF_BRIDGE, + TMP_SONOFF_B1, + TMP_AILIGHT, + TMP_SONOFF_T11, + TMP_SONOFF_T12, + TMP_SONOFF_T13, + TMP_SUPLA1, + TMP_WITTY, + TMP_YUNSHAN, + TMP_MAGICHOME, + TMP_LUANIHVIO, + TMP_KMC_70011, + TMP_ARILUX_LC01, + TMP_ARILUX_LC11, + TMP_SONOFF_DUAL_R2, + TMP_ARILUX_LC06, + TMP_SONOFF_POW_R2, // SONOFF_S31 + TMP_ZENGGE_ZF_WF017, + TMP_SONOFF_POW_R2, + TMP_SONOFF_4CH, // SONOFF_IFAN02 + TMP_BLITZWOLF_BWSHP, + TMP_SHELLY1, + TMP_SHELLY2, + TMP_PHILIPS, + TMP_NEO_COOLCAM, + TMP_ESP_SWITCH, + TMP_OBI, + TMP_TECKIN, + TMP_APLIC_WDP303075, + TMP_TUYA_DIMMER, + TMP_GOSUND, + TMP_ARMTRONIX_DIMMERS, + TMP_SK03_TUYA, + TMP_PS_16_DZ, + TMP_TECKIN_US, + TMP_MANZOKU_EU_4, + TMP_OBI2, + TMP_YTF_IR_BRIDGE, + TMP_DIGOO, + TMP_KA10, + TMP_ZX2820, + TMP_MI_DESK_LAMP, + TMP_SP10, + TMP_WAGA, + TMP_SYF05, + TMP_SONOFF_DUAL, // SONOFF_L1 + TMP_SONOFF_IFAN03, + TMP_EXS_DIMMER, + TMP_PWM_DIMMER, + TMP_SONOFF_DUAL, // SONOFF_D1 + TMP_SONOFF_ZB_BRIDGE, + }; + +/*********************************************************************************************\ + * Templates with 12 usable pins (ESP8266) +\*********************************************************************************************/ + +const mytmplt8266 kModules8266[TMP_MAXMODULE_8285] PROGMEM = { + { // SONOFF_BASIC - Sonoff Basic (ESP8266) + GPI8_KEY1, // GPIO00 Button + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + GPI8_USER, // GPIO02 Only available on newer Sonoff Basic R2 V1 + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + GPI8_USER, // GPIO04 Optional sensor + 0, // GPIO05 + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On) + GPI8_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off) - Link and Power status + GPI8_USER, // GPIO14 Optional sensor + 0, // GPIO15 + 0, // GPIO16 + 0 // ADC0 Analog input + }, + { // SONOFF_SV - Sonoff SV (ESP8266) + GPI8_KEY1, // GPIO00 Button + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + 0, + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + GPI8_USER, // GPIO04 Optional sensor + GPI8_USER, // GPIO05 Optional sensor + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On) + GPI8_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off) - Link and Power status + GPI8_USER, // GPIO14 Optional sensor + 0, 0, + GPI8_USER // ADC0 Analog input + }, + { // SONOFF_DUAL - Sonoff Dual (ESP8266) + GPI8_USER, // GPIO00 Pad + GPI8_TXD, // GPIO01 Relay control + 0, + GPI8_RXD, // GPIO03 Relay control + GPI8_USER, // GPIO04 Optional sensor + 0, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + 0, + GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status + GPI8_USER, // GPIO14 Optional sensor + 0, 0, 0 + }, + { // SONOFF_POW - Sonoff Pow (ESP8266 - HLW8012) + GPI8_KEY1, // GPIO00 Button + 0, 0, 0, 0, + GPI8_NRG_SEL, // GPIO05 HLW8012 Sel output (1 = Voltage) + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On) + GPI8_NRG_CF1, // GPIO13 HLW8012 CF1 voltage / current + GPI8_HLW_CF, // GPIO14 HLW8012 CF power + GPI8_LED1, // GPIO15 Blue Led (0 = On, 1 = Off) - Link and Power status + 0, 0 + }, + { // SONOFF_LED - Sonoff LED (ESP8266) + GPI8_KEY1, // GPIO00 Button + 0, 0, 0, + GPI8_USER, // GPIO04 Optional sensor (PWM3 Green) + GPI8_USER, // GPIO05 Optional sensor (PWM2 Red) + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_PWM1, // GPIO12 Cold light (PWM0 Cold) + GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status + GPI8_PWM2, // GPIO14 Warm light (PWM1 Warm) + GPI8_USER, // GPIO15 Optional sensor (PWM4 Blue) + 0, 0 + }, + { // ELECTRODRAGON - ElectroDragon IoT Relay Board (ESP8266) + GPI8_KEY2, // GPIO00 Button 2 + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + GPI8_KEY1, // GPIO02 Button 1 + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + GPI8_USER, // GPIO04 Optional sensor + GPI8_USER, // GPIO05 Optional sensor + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_REL2, // GPIO12 Red Led and Relay 2 (0 = Off, 1 = On) + GPI8_REL1, // GPIO13 Red Led and Relay 1 (0 = Off, 1 = On) + GPI8_USER, // GPIO14 Optional sensor + GPI8_USER, // GPIO15 Optional sensor + GPI8_LED1, // GPIO16 Green/Blue Led (1 = On, 0 = Off) - Link and Power status + GPI8_USER // ADC0 A0 Analog input + }, + { // EXS_RELAY - ES-Store Latching relay(s) (ESP8266) + // https://ex-store.de/ESP8266-WiFi-Relay-V31 + // V3.1 Module Pin 1 VCC 3V3, Module Pin 6 GND + // https://ex-store.de/2-Kanal-WiFi-WLan-Relay-V5-Blackline-fuer-Unterputzmontage + GPI8_USER, // GPIO00 V3.1 Module Pin 8 - V5.0 Module Pin 4 + GPI8_USER, // GPIO01 UART0_TXD V3.1 Module Pin 2 - V5.0 Module Pin 3 + GPI8_USER, // GPIO02 V3.1 Module Pin 7 + GPI8_USER, // GPIO03 UART0_RXD V3.1 Module Pin 3 + GPI8_USER, // GPIO04 V3.1 Module Pin 10 - V5.0 Module Pin 2 + GPI8_USER, // GPIO05 V3.1 Module Pin 9 - V5.0 Module Pin 1 + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_REL1, // GPIO12 Relay1 ( 1 = Off) + GPI8_REL2, // GPIO13 Relay1 ( 1 = On) + GPI8_USER, // GPIO14 V3.1 Module Pin 5 - V5.0 GPI8_REL3_INV Relay2 ( 1 = Off) + GPI8_LED1, // GPIO15 V5.0 LED1 - Link and Power status + GPI8_USER, // GPIO16 V3.1 Module Pin 4 - V5.0 GPI8_REL4_INV Relay2 ( 1 = On) + 0 + }, + { // WION - Indoor Tap (ESP8266) + // https://www.amazon.com/gp/product/B00ZYLUBJU/ref=s9_acsd_al_bw_c_x_3_w + GPI8_USER, // GPIO00 Optional sensor (pm clock) + 0, + GPI8_LED1, // GPIO02 Green Led (1 = On, 0 = Off) - Link and Power status + 0, 0, 0, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_USER, // GPIO12 Optional sensor (pm data) + GPI8_KEY1, // GPIO13 Button + 0, + GPI8_REL1, // GPIO15 Relay (0 = Off, 1 = On) + 0, 0 + }, + { // SONOFF_DEV - Sonoff Dev (ESP8266) + GPI8_KEY1, // GPIO00 E-FW Button + GPI8_USER, // GPIO01 TX Serial RXD and Optional sensor + 0, // GPIO02 + GPI8_USER, // GPIO03 RX Serial TXD and Optional sensor + GPI8_USER, // GPIO04 Optional sensor + GPI8_USER, // GPIO05 Optional sensor + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_USER, // GPIO12 + GPI8_USER, // GPIO13 BLUE LED + GPI8_USER, // GPIO14 Optional sensor + 0, // GPIO15 + 0, // GPIO16 + GPI8_USER // ADC0 A0 Analog input + }, + { // H801 - Lixada H801 Wifi (ESP8266) + GPI8_USER, // GPIO00 E-FW Button + GPI8_LED1, // GPIO01 Green LED - Link and Power status + GPI8_USER, // GPIO02 TX and Optional sensor - Pin next to TX on the PCB + GPI8_USER, // GPIO03 RX and Optional sensor - Pin next to GND on the PCB + GPI8_PWM5, // GPIO04 W2 - PWM5 + GPI8_LED2_INV, // GPIO05 Red LED + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_PWM3, // GPIO12 Blue + GPI8_PWM2, // GPIO13 Green + GPI8_PWM4, // GPIO14 W1 - PWM4 + GPI8_PWM1, // GPIO15 Red + 0, 0 + }, + { // SONOFF_SC - onoff SC (ESP8266) + GPI8_KEY1, // GPIO00 Button + GPI8_TXD, // GPIO01 RXD to ATMEGA328P + GPI8_USER, // GPIO02 Optional sensor + GPI8_RXD, // GPIO03 TXD to ATMEGA328P + 0, 0, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + 0, + GPI8_LED1_INV, // GPIO13 Green Led (0 = On, 1 = Off) - Link and Power status + 0, 0, 0, 0 + }, + { // SONOFF_BN - Sonoff BN-SZ01 Ceiling led (ESP8285) + 0, 0, 0, 0, 0, 0, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_PWM1, // GPIO12 Light + GPI8_LED1_INV, // GPIO13 Red Led (0 = On, 1 = Off) - Link and Power status + 0, 0, 0, 0 + }, + { // HUAFAN_SS - Hua Fan Smart Socket (ESP8266) - like Sonoff Pow + GPI8_LEDLNK_INV, // GPIO00 Blue Led (0 = On, 1 = Off) - Link status + 0, 0, + GPI8_LED1_INV, // GPIO03 Red Led (0 = On, 1 = Off) - Power status + GPI8_KEY1, // GPIO04 Button + GPI8_REL1_INV, // GPIO05 Relay (0 = On, 1 = Off) + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_NRG_CF1, // GPIO12 HLW8012 CF1 voltage / current + GPI8_NRG_SEL, // GPIO13 HLW8012 Sel output (1 = Voltage) + GPI8_HLW_CF, // GPIO14 HLW8012 CF power + 0, 0, 0 + }, + { // SONOFF_BRIDGE - Sonoff RF Bridge 433 (ESP8285) + GPI8_KEY1, // GPIO00 Button + GPI8_TXD, // GPIO01 RF bridge control + GPI8_USER, // GPIO02 Optional sensor + GPI8_RXD, // GPIO03 RF bridge control + GPI8_USER, // GPIO04 Optional sensor + GPI8_USER, // GPIO05 Optional sensor + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_USER, // GPIO12 Optional sensor + GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status + GPI8_USER, // GPIO14 Optional sensor + 0, 0, 0 + }, + { // SONOFF_B1 - Sonoff B1 (ESP8285 - my9231) + GPI8_KEY1, // GPIO00 Pad + GPI8_USER, // GPIO01 Serial RXD and Optional sensor pad + GPI8_USER, // GPIO02 Optional sensor SDA pad + GPI8_USER, // GPIO03 Serial TXD and Optional sensor pad + 0, 0, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_DI, // GPIO12 my9231 DI + 0, + GPI8_DCKI, // GPIO14 my9231 DCKI + 0, 0, 0 + }, + { // AILIGHT - Ai-Thinker RGBW led (ESP8266 - my9291) + GPI8_KEY1, // GPIO00 Pad + GPI8_USER, // GPIO01 Serial RXD and Optional sensor pad + GPI8_USER, // GPIO02 Optional sensor SDA pad + GPI8_USER, // GPIO03 Serial TXD and Optional sensor pad + 0, 0, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + 0, + GPI8_DI, // GPIO13 my9291 DI + 0, + GPI8_DCKI, // GPIO15 my9291 DCKI + 0, 0 + }, + { // SONOFF_T11 - Sonoff T1 1CH (ESP8285) + GPI8_KEY1, // GPIO00 Button 1 + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + GPI8_USER, // GPIO02 Optional Sensor (J3 Pin 5) + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + 0, 0, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_REL1, // GPIO12 Blue Led and Relay 1 (0 = Off, 1 = On) + GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status + 0, 0, 0, 0 + }, + { // SUPLA1 - Supla Espablo (ESP8266) + // http://www.wykop.pl/ramka/3325399/diy-supla-do-puszki-instalacyjnej-podtynkowej-supla-org/ + 0, // GPIO00 Flash jumper + GPI8_USER, // GPIO01 Serial RXD and Optional sensor +#ifdef USE_DS18x20 + GPI8_DSB, // GPIO02 DS18B20 sensor +#else + GPI8_USER, // GPIO02 Optional sensor +#endif + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + GPI8_KEY1, // GPIO04 Button 1 + GPI8_REL1, // GPIO05 Relay 1 (0 = Off, 1 = On) + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_USER, // GPIO12 Optional sensor + GPI8_REL2, // GPIO13 Relay 2 (0 = Off, 1 = On) + GPI8_USER, // GPIO14 Optional sensor + 0, + GPI8_LED1, // GPIO16 Led (1 = On, 0 = Off) - Link and Power status + GPI8_USER // ADC0 A0 Analog input + }, + { // WITTY - Witty Cloud Dev Board (ESP8266) + // https://www.aliexpress.com/item/ESP8266-serial-WIFI-Witty-cloud-Development-Board-ESP-12F-module-MINI-nodemcu/32643464555.html + GPI8_USER, // GPIO00 D3 flash push button on interface board + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + GPI8_LED1_INV, // GPIO02 D4 Blue Led (0 = On, 1 = Off) on ESP-12F - Link and Power status + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + GPI8_KEY1, // GPIO04 D2 push button on ESP-12F board + GPI8_USER, // GPIO05 D1 optional sensor + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_PWM2, // GPIO12 D6 RGB LED Green + GPI8_PWM3, // GPIO13 D7 RGB LED Blue + GPI8_USER, // GPIO14 D5 optional sensor + GPI8_PWM1, // GPIO15 D8 RGB LED Red + GPI8_USER, // GPIO16 D0 optional sensor + GPI8_USER // ADC0 A0 Light sensor / Requires USE_ADC_VCC in user_config.h to be disabled + }, + { // YUNSHAN - Yunshan Wifi Relay (ESP8266) + // https://www.ebay.com/p/Esp8266-220v-10a-Network-Relay-WiFi-Module/1369583381 + // Schematics and Info https://ucexperiment.wordpress.com/2016/12/18/yunshan-esp8266-250v-15a-acdc-network-wifi-relay-module/ + 0, // GPIO00 Flash jumper - Module Pin 8 + GPI8_USER, // GPIO01 Serial RXD and Optional sensor - Module Pin 2 + GPI8_LED1_INV, // GPIO02 Blue Led (0 = On, 1 = Off) on ESP-12F - Module Pin 7 - Link and Power status + GPI8_USER, // GPIO03 Serial TXD and Optional sensor - Module Pin 3 + GPI8_REL1, // GPIO04 Red Led and Relay (0 = Off, 1 = On) - Module Pin 10 + GPI8_KEY1, // GPIO05 Blue Led and OptoCoupler input - Module Pin 9 + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + 0, 0, 0, 0, 0, 0 + }, + { // MAGICHOME - Magic Home (aka Flux-light) (ESP8266) and Arilux LC10 (ESP8285) + // https://www.aliexpress.com/item/Magic-Home-Mini-RGB-RGBW-Wifi-Controller-For-Led-Strip-Panel-light-Timing-Function-16million-colors/32686853650.html + 0, + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + GPI8_LED1_INV, // GPIO02 Blue onboard LED - Link and Power status + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + GPI8_ARIRFRCV, // GPIO04 IR or RF receiver (optional) (Arilux LC10) + GPI8_PWM2, // GPIO05 RGB LED Green + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_PWM3, // GPIO12 RGB LED Blue + GPI8_USER, // GPIO13 RGBW LED White (optional - set to PWM4 for Cold White or Warm White as used on Arilux LC10) + GPI8_PWM1, // GPIO14 RGB LED Red + GPI8_ARIRFSEL, // GPIO15 RF receiver control (Arilux LC10) + 0, 0 + }, + { // LUANIHVIO - ESP8266_HVIO + // https://luani.de/projekte/esp8266-hvio/ + 0, // GPIO00 Flash jumper + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + GPI8_USER, // GPIO02 Optional sensor / I2C SDA pad + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + GPI8_REL1, // GPIO04 Relay 1 (0 = Off, 1 = On) + GPI8_REL2, // GPIO05 Relay 2 (0 = Off, 1 = On) + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_SWT1, // GPIO12 External input 1 (0 = On, 1 = Off) + GPI8_SWT2, // GPIO13 External input 2 (0 = On, 1 = Off) + GPI8_USER, // GPIO14 Optional sensor / I2C SCL pad + GPI8_LED1, // GPIO15 Led (1 = On, 0 = Off) - Link and Power status + 0, + GPI8_USER // ADC0 A0 Analog input + }, + { // KMC_70011 - KMC 70011 + // https://www.amazon.com/KMC-Timing-Monitoring-Network-125V-240V/dp/B06XRX2GTQ + GPI8_KEY1, // GPIO00 Button + 0, 0, 0, + GPI8_HLW_CF, // GPIO04 HLW8012 CF power + GPI8_NRG_CF1, // GPIO05 HLW8012 CF1 voltage / current + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_NRG_SEL, // GPIO12 HLW8012 SEL (1 = Voltage) + GPI8_LED1_INV, // GPIO13 Green Led - Link and Power status + GPI8_REL1, // GPIO14 Relay + 0, 0, 0 + }, + { // ARILUX_LC01 - Arilux AL-LC01 (ESP8285) + // https://www.banggood.com/nl/ARILUX-AL-LC01-Super-Mini-LED-WIFI-Smart-RGB-Controller-For-RGB-LED-Strip-Light-DC-9-12V-p-1058603.html + // (PwmFrequency 1111Hz) + GPI8_KEY1, // GPIO00 Optional Button + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + GPI8_ARIRFSEL, // GPIO02 RF receiver control + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + GPI8_ARIRFRCV, // GPIO04 IR or RF receiver (optional) + GPI8_PWM1, // GPIO05 RGB LED Red + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_PWM2, // GPIO12 RGB LED Green + GPI8_PWM3, // GPIO13 RGB LED Blue + GPI8_USER, // GPIO14 RGBW LED White (optional - set to PWM4 for Cold White or Warm White) + 0, 0, 0 + }, + { // ARILUX_LC11 - Arilux AL-LC11 (ESP8266) + // https://www.banggood.com/nl/ARILUX-AL-LC11-Super-Mini-LED-WIFI-APP-Controller-RF-Remote-Control-For-RGBWW-LED-Strip-DC9-28V-p-1085112.html + // (PwmFrequency 540Hz) + GPI8_KEY1, // GPIO00 Optional Button + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + GPI8_ARIRFSEL, // GPIO02 RF receiver control + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + GPI8_PWM2, // GPIO04 RGB LED Green + GPI8_PWM1, // GPIO05 RGB LED Red + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_PWM5, // GPIO12 RGBCW LED Warm + GPI8_PWM4, // GPIO13 RGBW LED Cold + GPI8_PWM3, // GPIO14 RGB LED Blue + GPI8_ARIRFRCV, // GPIO15 RF receiver input + 0, 0 + }, + { // ARILUX_LC06 - Arilux AL-LC06 (ESP8285) + // https://www.banggood.com/ARILUX-AL-LC06-LED-WIFI-Smartphone-Controller-Romote-5-Channels-DC12-24V-For-RGBWW-Strip-light-p-1061476.html + GPI8_KEY1, // GPIO00 Optional Button + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + GPI8_USER, // GPIO02 Empty pad + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + GPI8_USER, // GPIO04 W2 - PWM5 + 0, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_PWM2, // GPIO12 RGB LED Green + GPI8_PWM3, // GPIO13 RGB LED Blue + GPI8_PWM1, // GPIO14 RGB LED Red + GPI8_USER, // GPIO15 RGBW LED White + 0, 0 + }, + { // ZENGGE_ZF_WF017 - Zenggee ZJ-WF017-A (ESP12S)) + // https://www.ebay.com/p/Smartphone-Android-IOS-WiFi-Music-Controller-for-RGB-5050-3528-LED-Strip-Light/534446632?_trksid=p2047675.l2644 + GPI8_KEY1, // GPIO00 Optional Button + 0, + GPI8_USER, // GPIO02 Empty pad + 0, + GPI8_USER, // GPIO04 W2 - PWM5 + 0, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_PWM2, // GPIO12 RGB LED Green + GPI8_PWM1, // GPIO13 RGB LED Red + GPI8_PWM3, // GPIO14 RGB LED Blue + 0, 0, 0 + }, + { // SONOFF_POW_R2 - Sonoff Pow R2 (ESP8285 - CSE7766) + GPI8_KEY1, // GPIO00 Button + GPI8_CSE7766_TX, // GPIO01 Serial RXD 4800 baud 8E1 CSE7766 energy sensor + 0, + GPI8_CSE7766_RX, // GPIO03 Serial TXD + 0, 0, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On) + GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status + 0, 0, 0, 0 + }, + { // BLITZWOLF_BWSHP - BlitzWolf BW-SHP2 and BW-SHP6 (ESP8285 - BL0937 or HJL-01 Energy Monitoring) + // https://www.banggood.com/BlitzWolf-BW-SHP2-Smart-WIFI-Socket-EU-Plug-220V-16A-Work-with-Amazon-Alexa-Google-Assistant-p-1292899.html + // https://www.amazon.de/Steckdose-Homecube-intelligente-Verbrauchsanzeige-funktioniert/dp/B076Q2LKHG/ref=sr_1_fkmr0_1 + // https://www.amazon.de/Intelligente-Stromverbrauch-Fernsteurung-Schaltbare-Energieklasse/dp/B076WZQS4S/ref=sr_1_1 + // https://www.aliexpress.com/store/product/BlitzWolf-BW-SHP6-EU-Plug-Metering-Version-WIFI-Smart-Socket-220V-240V-10A-Work-with-Amazon/1965360_32945504669.html + GPI8_LED1_INV, // GPIO00 Red Led (1 = On, 0 = Off) - Power status + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + GPI8_LEDLNK_INV, // GPIO02 Blue Led (1 = On, 0 = Off) - Link status + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + 0, + GPI8_HJL_CF, // GPIO05 BL0937 or HJL-01 CF power + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_NRG_SEL_INV, // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage) + GPI8_KEY1, // GPIO13 Button + GPI8_NRG_CF1, // GPIO14 BL0937 or HJL-01 CF1 current / voltage + GPI8_REL1, // GPIO15 Relay (0 = Off, 1 = On) + 0, 0 + }, + { // SHELLY1 - Shelly1 Open Source (ESP8266 - 2MB) - https://shelly.cloud/shelly1-open-source/ + GPI8_USER, // GPIO00 - Can be changed to GPI8_USER, only if Shelly is powered with 12V DC + GPI8_USER, // GPIO01 Serial RXD - Can be changed to GPI8_USER, only if Shelly is powered with 12V DC + 0, + GPI8_USER, // GPIO03 Serial TXD - Can be changed to GPI8_USER, only if Shelly is powered with 12V DC + GPI8_REL1, // GPIO04 Relay (0 = Off, 1 = On) + GPI8_SWT1_NP, // GPIO05 SW pin + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + 0, 0, 0, 0, 0, 0 + }, + { // SHELLY2 - Shelly2 (ESP8266 - 2MB) - https://shelly.cloud/shelly2/ + 0, + GPI8_MCP39F5_TX, // GPIO01 MCP39F501 Serial input + 0, + GPI8_MCP39F5_RX, // GPIO03 MCP39F501 Serial output + GPI8_REL1, // GPIO04 + GPI8_REL2, // GPIO05 + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_SWT1, // GPIO12 + 0, + GPI8_SWT2, // GPIO14 + GPI8_MCP39F5_RST, // GPIO15 MCP39F501 Reset + 0, + 0 + }, + { // PHILIPS - Xiaomi Philips bulb (ESP8266) + 0, 0, 0, 0, 0, 0, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_PWM2, // GPIO12 cold/warm light + 0, 0, + GPI8_PWM1, // GPIO15 light intensity + 0, 0 + }, + { // NEO_COOLCAM - Neo Coolcam (ESP8266) + // https://www.banggood.com/NEO-COOLCAM-WiFi-Mini-Smart-Plug-APP-Remote-Control-Timing-Smart-Socket-EU-Plug-p-1288562.html?cur_warehouse=CN + 0, 0, 0, 0, + GPI8_LED1_INV, // GPIO04 Red Led (0 = On, 1 = Off) - Link and Power status + 0, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_REL1, // GPIO12 Red Led and Relay (0 = Off, 1 = On) + GPI8_KEY1, // GPIO13 Button + 0, 0, 0, 0 + }, + { // ESP_SWITCH - Michael Haustein 4 channel wall switch (ESP07 = ESP8266) + // Use rules for further actions like - rule on power1#state do publish cmnd/other_device/power %value% endon + GPI8_KEY2, // GPIO00 Button 2 + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + GPI8_REL3_INV, // GPIO02 Yellow Led 3 (0 = On, 1 = Off) + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + GPI8_KEY1, // GPIO04 Button 1 + GPI8_REL2_INV, // GPIO05 Red Led 2 (0 = On, 1 = Off) + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_REL4_INV, // GPIO12 Blue Led 4 (0 = On, 1 = Off) + GPI8_KEY4, // GPIO13 Button 4 + GPI8_KEY3, // GPIO14 Button 3 + GPI8_LED1, // GPIO15 Optional sensor + GPI8_REL1_INV, // GPIO16 Green Led 1 (0 = On, 1 = Off) + 0 + }, + { // OBI - OBI socket (ESP8266) - https://www.obi.de/hausfunksteuerung/wifi-stecker-schuko/p/2291706 + GPI8_USER, // GPIO00 + GPI8_USER, // GPIO01 Serial RXD + 0, + GPI8_USER, // GPIO03 Serial TXD + GPI8_LED1, // GPIO04 Blue LED - Link and Power status + GPI8_REL1, // GPIO05 (Relay OFF, but used as Relay Switch) + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_LED3, // GPIO12 (Relay ON, but set to LOW, so we can switch with GPIO05) + GPI8_USER, // GPIO13 + GPI8_KEY1, // GPIO14 Button + 0, + GPI8_USER, // GPIO16 + GPI8_USER // ADC0 A0 Analog input + }, + { // TECKIN - https://www.amazon.de/gp/product/B07D5V139R + 0, + GPI8_KEY1, // GPIO01 Serial TXD and Button + 0, + GPI8_LED1_INV, // GPIO03 Serial RXD and Red Led (0 = On, 1 = Off) - Power status + GPI8_HJL_CF, // GPIO04 BL0937 or HJL-01 CF power + GPI8_NRG_CF1, // GPIO05 BL0937 or HJL-01 CF1 current / voltage + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_NRG_SEL_INV, // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage) + GPI8_LEDLNK_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link status + GPI8_REL1, // GPIO14 Relay (0 = Off, 1 = On) + 0, 0, 0 + }, + { // APLIC_WDP303075 - Aplic WDP 303075 (ESP8285 - HLW8012 Energy Monitoring) + // https://www.amazon.de/dp/B07CNWVNJ2 + 0, 0, 0, + GPI8_KEY1, // GPIO03 Button + GPI8_HLW_CF, // GPIO04 HLW8012 CF power + GPI8_NRG_CF1, // GPIO05 HLW8012 CF1 current / voltage + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_NRG_SEL_INV, // GPIO12 HLW8012 CF Sel output (0 = Voltage) + GPI8_LED1_INV, // GPIO13 LED (0 = On, 1 = Off) - Link and Power status + GPI8_REL1, // GPIO14 Relay SRU 5VDC SDA (0 = Off, 1 = On ) + 0, 0, 0 + }, + { // TUYA_DIMMER - Tuya MCU device (ESP8266 w/ separate MCU) + // https://www.amazon.com/gp/product/B07CTNSZZ8/ref=oh_aui_detailpage_o00_s00?ie=UTF8&psc=1 + GPI8_USER, // Virtual Button (controlled by MCU) + GPI8_USER, // GPIO01 MCU serial control + GPI8_USER, + GPI8_USER, // GPIO03 MCU serial control + GPI8_USER, + GPI8_USER, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_USER, + GPI8_USER, + GPI8_USER, // GPIO14 Green Led + GPI8_USER, + GPI8_USER, + 0 + }, + { // GOSUND - https://www.amazon.de/gp/product/B0777BWS1P + 0, + GPI8_LEDLNK_INV, // GPIO01 Serial RXD and LED1 (blue) inv - Link status + 0, + GPI8_KEY1, // GPIO03 Serial TXD and Button + GPI8_HJL_CF, // GPIO04 BL0937 or HJL-01 CF power + GPI8_NRG_CF1, // GPIO05 BL0937 or HJL-01 CF1 current / voltage + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_NRG_SEL_INV, // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage) + GPI8_LED1_INV, // GPIO13 LED2 (red) inv - Power status + GPI8_REL1, // GPIO14 Relay (0 = Off, 1 = On) + 0, 0, 0 + }, + { // ARMTRONIX_DIMMERS - ARMTRONIX Dimmer, one or two channel (ESP8266 w/ separate MCU dimmer) + // https://www.tindie.com/products/Armtronix/wifi-ac-dimmer-two-triac-board/ + // https://www.tindie.com/products/Armtronix/wifi-ac-dimmer-esp8266-one-triac-board-alexaecho/ + GPI8_USER, + GPI8_TXD, // GPIO01 MCU serial control + GPI8_USER, + GPI8_RXD, // GPIO03 MCU serial control + GPI8_USER, + GPI8_USER, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_USER, + GPI8_USER, + GPI8_USER, + GPI8_USER, + GPI8_USER, + 0 + }, + { // SK03_TUYA - Outdoor smart plug with power monitoring HLW8012 chip - https://www.amazon.com/gp/product/B07CG7MBPV + GPI8_KEY1, // GPIO00 Button + 0, 0, 0, + GPI8_HLW_CF, // GPIO04 HLW8012 CF power + GPI8_NRG_CF1, // GPIO05 HLW8012 CF1 current / voltage + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_NRG_SEL_INV, // GPIO12 HLW8012 CF Sel output (0 = Voltage) + GPI8_LED1_INV, // GPIO13 Red Led (0 = On, 1 = Off) - Power status + GPI8_LEDLNK_INV, // GPIO14 Blue Led (0 = On, 1 = Off) - Link status + GPI8_REL1, // GPIO15 Relay (0 = Off, 1 = On) + 0, 0 + }, + { // PS_16_DZ - PS-16-DZ Dimmer (ESP8266 w/ separate Nuvoton MCU dimmer) + // https://www.aliexpress.com/item/SM-Smart-WIFI-Wall-Dimmer-Light-Switch-US-Ewelink-APP-Remote-Control-Wi-Fi-Wirele-Work/32871151902.html + GPI8_USER, + GPI8_TXD, // GPIO01 MCU serial control + GPI8_USER, + GPI8_RXD, // GPIO03 MCU serial control + GPI8_USER, + GPI8_USER, + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_USER, + GPI8_LED1, // GPIO13 WiFi LED - Link and Power status + GPI8_USER, + GPI8_USER, + GPI8_USER, + 0 + }, + { // TECKIN_US - Teckin SP20 US with Energy Monitoring + // https://www.amazon.com/Outlet-Compatible-Monitoring-Function-Required/dp/B079Q5W22B + // https://www.amazon.com/Outlet-ZOOZEE-Monitoring-Function-Compatible/dp/B07J2LR5KN + GPI8_LED1_INV, // GPIO00 Red Led (1 = On, 0 = Off) - Power status + 0, + GPI8_LEDLNK_INV, // GPIO02 Blue Led (1 = On, 0 = Off) - Link status + 0, + GPI8_REL1, // GPIO04 Relay (0 = Off, 1 = On) + GPI8_HJL_CF, // GPIO05 BL0937 or HJL-01 CF power + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_NRG_SEL_INV, // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage) + GPI8_KEY1, // GPIO13 Button + GPI8_NRG_CF1, // GPIO14 BL0937 or HJL-01 CF1 current / voltage + 0, 0, 0 + }, + { // MANZOKU_EU_4 - "MANZOKU" labeled power strip, EU version + // https://www.amazon.de/Steckdosenleiste-AOFO-Mehrfachsteckdose-Überspannungsschutz-Sprachsteuerung/dp/B07GBSD11P/ + // https://www.amazon.de/Steckdosenleiste-Geekbes-USB-Anschluss-Kompatibel-gesteuert/dp/B078W23BW9/ + 0, // GPIO00 + 0, // GPIO01 Serial RXD + 0, + GPI8_KEY1, // GPIO03 Serial TXD + Button + GPI8_REL2, // GPIO04 Relay 2 + GPI8_REL1, // GPIO05 Relay 1 + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_REL3, // GPIO12 Relay 3 + GPI8_REL4, // GPIO13 Relay 4 + GPI8_USER, // GPIO14 + 0, + GPI8_USER, // GPIO16 + 0 + }, + { // OBI2 - OBI socket (ESP8266) - https://www.obi.de/hausfunksteuerung/wifi-stecker-schuko-2-stueck-weiss/p/4077673 + 0, // GPIO00 + 0, // GPIO01 Serial RXD + 0, + 0, // GPIO03 Serial TXD + GPI8_REL1, // GPIO04 Relay 1 + GPI8_KEY1, // GPIO05 Button + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_LEDLNK_INV, // GPIO12 Green LED - Link status + GPI8_LED1, // GPIO13 Red LED - Power status + 0, 0, 0, 0 + }, + { // YTF_IR_BRIDGE - https://www.aliexpress.com/item/Tuya-universal-Smart-IR-Hub-remote-control-Voice-Control-AC-TV-Work-With-Alexa-Google-Home/32951202513.html + GPI8_USER, // GPIO00 + GPI8_USER, // GPIO01 Serial RXD + GPI8_USER, // GPIO02 + GPI8_USER, // GPIO03 Serial TXD + GPI8_LED1_INV, // GPIO04 Blue Led - Link status + GPI8_IRRECV, // GPIO05 IR Receiver + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + 0, // GPIO12 + GPI8_KEY1, // GPIO13 Button + GPI8_IRSEND, // GPIO14 IR Transmitter + 0, 0, 0 + }, + { // DIGOO - Digoo DG-SP202 + // https://www.banggood.com/DIGOO-DG-SP202-Dual-EU-Plug-Smart-WIFI-Socket-Individual-Controllable-Energy-Monitor-Remote-Control-Timing-Smart-Home-Outlet-let-p-1375323.html + GPI8_KEY1, // GPIO00 Button1 + 0, // GPIO01 Serial RXD + 0, // GPIO02 + 0, // GPIO03 Serial TXD + GPI8_HJL_CF, // GPIO04 BL0937 or HJL-01 CF power + GPI8_NRG_CF1, // GPIO05 BL0937 or HJL-01 CF1 current / voltage + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_NRG_SEL_INV, // GPIO12 BL0937 or HJL-01 Sel output (0 = Voltage) + GPI8_LED1, // GPIO13 Blue Leds - Link Status + GPI8_REL2, // GPIO14 Relay2 (0 = Off, 1 = On) and Red Led + GPI8_REL1, // GPIO15 Relay1 (0 = Off, 1 = On) and Red Led + GPI8_KEY2_NP, // GPIO16 Button2, externally pulled up + 0 + }, + { // KA10 - SMANERGY KA10 (ESP8285 - BL0937 Energy Monitoring) - https://www.amazon.es/dp/B07MBTCH2Y + 0, // GPIO00 + GPI8_LEDLNK_INV, // GPIO01 Blue LED - Link status + 0, // GPIO02 + GPI8_KEY1, // GPIO03 Button + GPI8_HJL_CF, // GPIO04 BL0937 CF power + GPI8_NRG_CF1, // GPIO05 BL0937 CF1 voltage / current + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_NRG_SEL_INV, // GPIO12 BL0937 Sel output (1 = Voltage) + GPI8_LED1, // GPIO13 Red LED - Power status + GPI8_REL1, // GPIO14 Relay 1 + 0, 0, 0 + }, + { // ZX2820 + GPI8_KEY1, // GPIO00 Button + 0, 0, 0, + GPI8_HLW_CF, // GPIO04 HLW8012 CF power + GPI8_NRG_CF1, // GPIO05 HLW8012 CF1 voltage / current + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_NRG_SEL_INV, // GPIO12 HLW8012 SEL (0 = Voltage) + GPI8_LED1_INV, // GPIO13 Green Led - Link and Power status + GPI8_REL1, // GPIO14 Relay + 0, 0, 0 + }, + { // MI_DESK_LAMP - Mi LED Desk Lamp - https://www.mi.com/global/smartlamp/ + 0, 0, + GPI8_KEY1, // GPIO02 Button + 0, + GPI8_PWM1, // GPIO04 Cold White + GPI8_PWM2, // GPIO05 Warm White + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_ROT1A, // GPIO12 Rotary switch A pin + GPI8_ROT1B, // GPIO13 Rotary switch B pin + 0, 0, 0, 0 + }, + { // SP10 - Tuya SP10 (BL0937 Energy Monitoring) + // https://www.aliexpress.com/item/Smart-Mini-WiFi-Plug-Outlet-Switch-Work-With-ForEcho-Alexa-Google-Home-Remote-EU-Smart-Socket/32963670423.html + 0, // GPIO00 + GPI8_PWM1, // GPIO01 Nightlight + 0, // GPIO02 + GPI8_KEY1, // GPIO03 Button + GPI8_HJL_CF, // GPIO04 BL0937 CF power + GPI8_NRG_CF1, // GPIO05 BL0937 CF1 voltage / current + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_NRG_SEL_INV, // GPIO12 BL0937 Sel output (1 = Voltage) + GPI8_LED1, // GPIO13 Blue LED - Link status + GPI8_REL1, // GPIO14 Relay and red LED + 0, 0, 0 + }, + { // WAGA - WAGA life CHCZ02MB (HJL-01 Energy Monitoring) + // https://www.ebay.com/itm/332595697006 + GPI8_LED1_INV, // GPIO00 Red LED + 0, // GPIO01 Serial RXD + 0, // GPIO02 + GPI8_NRG_SEL_INV, // GPIO03 HJL-01 Sel output (1 = Voltage) + 0, // GPIO04 + GPI8_HJL_CF, // GPIO05 HJL-01 CF power + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_REL1, // GPIO12 Relay + GPI8_KEY1, // GPIO13 Button + GPI8_NRG_CF1, // GPIO14 HJL-01 CF1 voltage / current + GPI8_LEDLNK_INV, // GPIO15 Blue LED - Link status + 0, 0 + }, + { // SYF05 - Sunyesmart SYF05 (a.k.a. Fcmila) = TYWE3S + SM16726 + // Also works with Merkury 904 RGBW Bulbs with 13 set to GPI8_SM16716_SEL + // https://www.flipkart.com/fc-mila-bxav-xs-ad-smart-bulb/p/itmf85zgs45fzr7n + // https://docs.tuya.com/en/hardware/WiFi-module/wifi-e3s-module.html + // http://www.datasheet-pdf.com/PDF/SM16716-Datasheet-Sunmoon-932771 + GPI8_USER, // GPIO00 N.C. + 0, // GPIO01 Serial RXD + GPI8_USER, // GPIO02 N.C. + 0, // GPIO03 Serial TXD + GPI8_SM16716_CLK, // GPIO04 SM16716 Clock + GPI8_PWM1, // GPIO05 White + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_USER, // GPIO12 Alt. White on some devices + GPI8_USER, // GPIO13 SM16716 Enable on some devices + GPI8_SM16716_DAT, // GPIO14 SM16716 Data + 0, // GPIO15 wired to GND + GPI8_USER, // GPIO16 N.C. + GPI8_USER // ADC0 A0 Analog input + }, + { // EXS_DIMMER - EX-Store WiFi Dimmer v4, two channel (ESP8266 w/ separate MCU dimmer) + // https://ex-store.de/2-Kanal-RS232-WiFi-WLan-Dimmer-Modul-V4-fuer-Unterputzmontage-230V-3A + // https://ex-store.de/2-Kanal-RS232-WiFi-WLan-Dimmer-Modul-V4-fuer-Unterputzmontage-230V-3A-ESP8266-V12-Stift-und-Buchsenleisten + 0, + GPI8_TXD, // GPIO01 MCU serial control + GPI8_LEDLNK, // GPIO02 LED Link + GPI8_RXD, // GPIO03 MCU serial control + GPI8_USER, // GPIO04 + GPI8_USER, // GPIO05 + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_USER, // GPIO12 + GPI8_EXS_ENABLE, // GPIO13 EXS MCU Enable + GPI8_USER, // GPIO14 + 0, // GPIO15 + 0, 0 + }, + { // PWM_DIMMER - Support for Martin Jerry/acenx/Tessan/NTONPOWER SD0x PWM + // dimmer switches. The brightness of the load for these dimmers is + // controlled by a PWM GPIO pin. There are typically power, up & down + // buttons and 4 LED's. Examples are: + // https://www.amazon.com/dp/B07FXYSVR1 + // https://www.amazon.com/dp/B07V26Q3VD + // https://www.amazon.com/dp/B07K67D43J + // https://www.amazon.com/dp/B07TTGFWFM + GPI8_KEY3, // GPIO00 Up button + GPI8_KEY2, // GPIO01 Down button + 0, // GPIO02 + GPI8_LED4_INV, // GPIO03 Level 5 LED + GPI8_LEDLNK_INV, // GPIO04 LED Link + GPI8_LED3_INV, // GPIO05 Level 4 LED + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_LED2_INV, // GPIO12 Level 3 LED + GPI8_PWM1, // GPIO13 Dimmer PWM + GPI8_LED1_INV, // GPIO12 Level 2 LED + GPI8_KEY1_INV, // GPIO15 Power button + GPI8_REL1_INV, // GPIO16 Power relay/Level 1 LED + 0 + }, + { // SONOFF_ZB_BRIDGE - Sonoff Zigbee Bridge (ESP8266) + GPI8_LED1_INV, // GPIO00 Green Led (0 = On, 1 = Off) - Traffic between ESP and EFR + GPI8_ZIGBEE_TX, // GPIO01 Zigbee Serial control + 0, // GPIO02 + GPI8_ZIGBEE_RX, // GPIO03 Zigbee Serial control + GPI8_ZIGBEE_RST, // GPIO04 Zigbee Reset + 0, // GPIO05 EFR32 Bootloader mode (drive Low for Gecko Bootloader, inactive or high for Zigbee EmberZNet) + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_I2C_SDA, // GPIO12 I2C SDA - connected to 512KB EEPROM + GPI8_LEDLNK_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link status + GPI8_I2C_SCL, // GPIO14 I2C SCL - connected to 512KB EEPROM + 0, // GPIO15 connected to IO15 pad, also used for logging + GPI8_KEY1, // GPIO16 Button + 0 + } +}; + +/*********************************************************************************************\ + * Templates with 14 usable pins (ESP8285) +\*********************************************************************************************/ + +const mytmplt8285 kModules8285[TMP_MAXMODULE_8266 - TMP_WEMOS] PROGMEM = { + { // WEMOS - Any ESP8266/ESP8285 device like WeMos and NodeMCU hardware (ESP8266) + GPI8_USER, // GPIO00 D3 Wemos Button Shield + GPI8_USER, // GPIO01 TX Serial RXD + GPI8_USER, // GPIO02 D4 Wemos DHT Shield + GPI8_USER, // GPIO03 RX Serial TXD and Optional sensor + GPI8_USER, // GPIO04 D2 Wemos I2C SDA + GPI8_USER, // GPIO05 D1 Wemos I2C SCL / Wemos Relay Shield (0 = Off, 1 = On) / Wemos WS2812B RGB led Shield + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + GPI8_USER, // GPIO09 (SD_DATA2 Flash QIO or ESP8285) + GPI8_USER, // GPIO10 (SD_DATA3 Flash QIO or ESP8285) + // GPIO11 (SD_CMD Flash) + GPI8_USER, // GPIO12 D6 + GPI8_USER, // GPIO13 D7 + GPI8_USER, // GPIO14 D5 + GPI8_USER, // GPIO15 D8 + GPI8_USER, // GPIO16 D0 Wemos Wake + GPI8_USER // ADC0 A0 Analog input + }, + { // SONOFF_4CH - Sonoff 4CH (ESP8285) + GPI8_KEY1, // GPIO00 Button 1 + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + GPI8_USER, // GPIO02 Optional sensor + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + GPI8_REL3, // GPIO04 Sonoff 4CH Red Led and Relay 3 (0 = Off, 1 = On) + GPI8_REL2, // GPIO05 Sonoff 4CH Red Led and Relay 2 (0 = Off, 1 = On) + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + GPI8_KEY2, // GPIO09 Button 2 + GPI8_KEY3, // GPIO10 Button 3 + // GPIO11 (SD_CMD Flash) + GPI8_REL1, // GPIO12 Red Led and Relay 1 (0 = Off, 1 = On) - Link and Power status + GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) + GPI8_KEY4, // GPIO14 Button 4 + GPI8_REL4, // GPIO15 Red Led and Relay 4 (0 = Off, 1 = On) + 0, 0 + }, + { // SONOFF_T12 - Sonoff T1 2CH (ESP8285) + GPI8_KEY1, // GPIO00 Button 1 + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + GPI8_USER, // GPIO02 Optional Sensor (J3 Pin 5) + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + 0, + GPI8_REL2, // GPIO05 Blue Led and Relay 2 (0 = Off, 1 = On) + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + GPI8_KEY2, // GPIO09 Button 2 + 0, // GPIO10 + // GPIO11 (SD_CMD Flash) + GPI8_REL1, // GPIO12 Blue Led and Relay 1 (0 = Off, 1 = On) + GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status + 0, 0, 0, 0 + }, + { // SONOFF_T13 - Sonoff T1 3CH (ESP8285) + GPI8_KEY1, // GPIO00 Button 1 + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + GPI8_USER, // GPIO02 Optional Sensor (J3 Pin 5) + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + GPI8_REL3, // GPIO04 Blue Led and Relay 3 (0 = Off, 1 = On) + GPI8_REL2, // GPIO05 Blue Led and Relay 2 (0 = Off, 1 = On) + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + GPI8_KEY2, // GPIO09 Button 2 + GPI8_KEY3, // GPIO10 Button 3 + // GPIO11 (SD_CMD Flash) + GPI8_REL1, // GPIO12 Blue Led and Relay 1 (0 = Off, 1 = On) + GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status + 0, 0, 0, 0 + }, + { // SONOFF_DUAL_R2 - Sonoff Dual R2 (ESP8285) + GPI8_USER, // GPIO00 Button 0 on header (0 = On, 1 = Off) + GPI8_USER, // GPIO01 Serial RXD and Optional sensor + 0, + GPI8_USER, // GPIO03 Serial TXD and Optional sensor + 0, + GPI8_REL2, // GPIO05 Relay 2 (0 = Off, 1 = On) + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + GPI8_USER, // GPIO09 Button 1 on header (0 = On, 1 = Off) + GPI8_KEY1, // GPIO10 Button on casing + // GPIO11 (SD_CMD Flash) + GPI8_REL1, // GPIO12 Relay 1 (0 = Off, 1 = On) + GPI8_LED1_INV, // GPIO13 Blue Led (0 = On, 1 = Off) - Link and Power status + 0, 0, 0, 0 + }, + { // SONOFF_IFAN03 - Sonoff iFan03 (ESP8285) + GPI8_KEY1, // GPIO00 WIFI_KEY0 Button 1 + GPI8_TXD, // GPIO01 ESP_TXD Serial RXD connection to P0.5 of RF microcontroller + 0, // GPIO02 ESP_LOG + GPI8_RXD, // GPIO03 ESP_RXD Serial TXD connection to P0.4 of RF microcontroller + 0, // GPIO04 DEBUG_RX + 0, // GPIO05 DEBUG_TX + // GPIO06 (SD_CLK Flash) + // GPIO07 (SD_DATA0 Flash QIO/DIO/DOUT) + // GPIO08 (SD_DATA1 Flash QIO/DIO/DOUT) + GPI8_REL1_INV, // GPIO09 WIFI_O0 Relay 1 (0 = Off, 1 = On) controlling the light + GPI8_BUZZER_INV, // GPIO10 WIFI_O4 Buzzer (0 = Off, 1 = On) + // GPIO11 (SD_CMD Flash) + GPI8_REL3, // GPIO12 WIFI_O2 Relay 3 (0 = Off, 1 = On) controlling the fan + GPI8_LED1_INV, // GPIO13 WIFI_CHK Blue Led on PCA (0 = On, 1 = Off) - Link and Power status + GPI8_REL2, // GPIO14 WIFI_O1 Relay 2 (0 = Off, 1 = On) controlling the fan + GPI8_REL4, // GPIO15 WIFI_O3 Relay 4 (0 = Off, 1 = On) controlling the fan + 0, 0 + } +}; + +#endif // ESP8266 + +#ifdef ESP32 +#if CONFIG_IDF_TARGET_ESP32C2 +/********************************************************************************************\ + * ESP32-C2 Module templates +\********************************************************************************************/ + +#define USER_MODULE 255 + +// Supported hardware modules +enum SupportedModulesESP32C2 { + WEMOS, // not really correct, a placeholder for now + MAXMODULE }; + +// Default module settings +const uint8_t kModuleNiceList[] PROGMEM = { + WEMOS, +}; + +// !!! Update this list in the same order as kModuleNiceList !!! +const char kModuleNames[] PROGMEM = + "ESP32C2|" + ; + +// !!! Update this list in the same order as SupportedModulesESP32C2 !!! +const mytmplt kModules[] PROGMEM = { + { // Generic ESP32C2 device + AGPIO(GPIO_USER), // 0 IO GPIO0, ADC1_CH0, RTC + AGPIO(GPIO_USER), // 1 IO GPIO1, ADC1_CH1, RTC + AGPIO(GPIO_USER), // 2 IO GPIO2, ADC1_CH2, RTC + AGPIO(GPIO_USER), // 3 IO GPIO3, ADC1_CH3, RTC + AGPIO(GPIO_USER), // 4 IO GPIO4, ADC1_CH4, RTC + AGPIO(GPIO_USER), // 5 IO GPIO5, RTC + AGPIO(GPIO_USER), // 6 IO GPIO6, + AGPIO(GPIO_USER), // 7 IO GPIO7, + AGPIO(GPIO_USER), // 8 IO GPIO8, Strapping + AGPIO(GPIO_USER), // 9 IO GPIO9, Strapping + AGPIO(GPIO_USER), // 10 IO GPIO10 + 0, // 11 IO GPIO11, output power supply for flash + 0, // 12 IO GPIO12, SPIHD - Free if flash DIO/DOUT + 0, // 13 IO GPIO13, SPIWP - Free if flash DIO/DOUT + 0, // 14 IO GPIO14, SPICS0 + 0, // 15 IO GPIO15, SPICLK + 0, // 16 IO GPIO16, SPID + 0, // 17 IO GPIO17, SPIQ + AGPIO(GPIO_USER), // 18 IO GPIO18, + AGPIO(GPIO_USER), // 19 IO RXD0 GPIO19, U0RXD + AGPIO(GPIO_USER), // 20 IO TXD0 GPIO20, U0TXD + 0 // Flag + }, +}; + +/*********************************************************************************************\ + Known templates +\*********************************************************************************************/ + +#elif CONFIG_IDF_TARGET_ESP32C3 +/********************************************************************************************\ + * ESP32-C3 Module templates +\********************************************************************************************/ + +#define USER_MODULE 255 + +// Supported hardware modules +enum SupportedModulesESP32C3 { + WEMOS, + MAXMODULE }; + +// Default module settings +const uint8_t kModuleNiceList[] PROGMEM = { + WEMOS, +}; + +// !!! Update this list in the same order as kModuleNiceList !!! +const char kModuleNames[] PROGMEM = + "ESP32C3|" + ; + +// !!! Update this list in the same order as SupportedModulesESP32C3 !!! +const mytmplt kModules[] PROGMEM = { + { // Generic ESP32C3 device + AGPIO(GPIO_USER), // 0 IO GPIO0, ADC1_CH0, XTAL_32K_P + AGPIO(GPIO_USER), // 1 IO GPIO1, ADC1_CH1, XTAL_32K_N + AGPIO(GPIO_USER), // 2 IO GPIO2, ADC1_CH2, FSPIQ + AGPIO(GPIO_USER), // 3 IO GPIO3, ADC1_CH3 + AGPIO(GPIO_USER), // 4 IO GPIO4, ADC1_CH4, FSPIHD, MTMS + AGPIO(GPIO_USER), // 5 IO GPIO5, ADC2_CH0, FSPIWP, MTDI + AGPIO(GPIO_USER), // 6 IO GPIO6, FSPICLK, MTCK + AGPIO(GPIO_USER), // 7 IO GPIO7, FSPID, MTDO + AGPIO(GPIO_USER), // 8 IO GPIO8 + AGPIO(GPIO_USER), // 9 IO GPIO9 + AGPIO(GPIO_USER), // 10 IO GPIO10 + 0, // 11 IO GPIO11, output power supply for flash + 0, // 12 IO GPIO12, SPIHD - Free if flash DIO/DOUT + 0, // 13 IO GPIO13, SPIWP - Free if flash DIO/DOUT + 0, // 14 IO GPIO14, SPICS0 + 0, // 15 IO GPIO15, SPICLK + 0, // 16 IO GPIO16, SPID + 0, // 17 IO GPIO17, SPIQ + AGPIO(GPIO_USER), // 18 IO GPIO18, USB_D + AGPIO(GPIO_USER), // 19 IO GPIO19, USB_D+ + AGPIO(GPIO_USER), // 20 IO RXD0 GPIO20, U0RXD + AGPIO(GPIO_USER), // 21 IO TXD0 GPIO21, U0TXD + 0 // Flag + }, +}; + +/*********************************************************************************************\ + Known templates +\*********************************************************************************************/ + +#elif CONFIG_IDF_TARGET_ESP32C5 +/********************************************************************************************\ + * ESP32-C5 Module templates +\********************************************************************************************/ + +#define USER_MODULE 255 + +// Supported hardware modules +enum SupportedModulesESP32C5 { + WEMOS, + MAXMODULE }; + +// Default module settings +const uint8_t kModuleNiceList[] PROGMEM = { + WEMOS, +}; + +// !!! Update this list in the same order as kModuleNiceList !!! +const char kModuleNames[] PROGMEM = + "ESP32C5|" + ; + +// !!! Update this list in the same order as SupportedModulesESP32C5 !!! +const mytmplt kModules[] PROGMEM = { + { // Generic ESP32C5 device + AGPIO(GPIO_USER), // 0 IO GPIO0 + AGPIO(GPIO_USER), // 1 AO GPIO1, ADC1_CH0 + AGPIO(GPIO_USER), // 2 AO GPIO2, ADC1_CH1 + AGPIO(GPIO_USER), // 3 AO GPIO3, ADC1_CH2 + AGPIO(GPIO_USER), // 4 AO GPIO4, ADC1_CH3 + AGPIO(GPIO_USER), // 5 AO GPIO5, ADC1_CH4 + AGPIO(GPIO_USER), // 6 AO GPIO6, ADC1_CH5 + AGPIO(GPIO_USER), // 7 AO GPIO7, ADC1_CH6 + AGPIO(GPIO_USER), // 8 IO GPIO8 + AGPIO(GPIO_USER), // 9 IO GPIO9 + AGPIO(GPIO_USER), // 10 IO GPIO10 + AGPIO(GPIO_USER), // 11 IO GPIO11 + AGPIO(GPIO_USER), // 12 IO GPIO12 + AGPIO(GPIO_USER), // 13 IO GPIO13 + AGPIO(GPIO_USER), // 14 IO GPIO14 + AGPIO(GPIO_USER), // 15 IO GPIO15 + AGPIO(GPIO_USER), // 16 IO GPIO16 + AGPIO(GPIO_USER), // 17 IO GPIO17 + AGPIO(GPIO_USER), // 18 IO GPIO18 + AGPIO(GPIO_USER), // 19 IO GPIO19 + AGPIO(GPIO_USER), // 20 IO GPIO20 + AGPIO(GPIO_USER), // 21 IO GPIO21 + AGPIO(GPIO_USER), // 22 IO GPIO22 + AGPIO(GPIO_USER), // 23 IO GPIO23 + 0, // 24 FL GPIO24, Flash + 0, // 25 FL GPIO25, Flash + 0, // 26 FL GPIO26, Flash + 0 // Flag + }, +}; + +/*********************************************************************************************\ + Known templates +\*********************************************************************************************/ + +#elif CONFIG_IDF_TARGET_ESP32C6 +/********************************************************************************************\ + * ESP32-C6 Module templates +\********************************************************************************************/ + +#define USER_MODULE 255 + +// Supported hardware modules +enum SupportedModulesESP32C6 { + WEMOS, // not really correct, a placeholder for now + MAXMODULE }; + +// Default module settings +const uint8_t kModuleNiceList[] PROGMEM = { + WEMOS, +}; + +// !!! Update this list in the same order as kModuleNiceList !!! +const char kModuleNames[] PROGMEM = + "ESP32C6|" + ; + +// !!! Update this list in the same order as SupportedModulesESP32C6 !!! +const mytmplt kModules[] PROGMEM = { + { // Generic ESP32C6 device + AGPIO(GPIO_USER), // 0 IO GPIO0, ADC1_CH0, LP_GPIO0 + AGPIO(GPIO_USER), // 1 IO GPIO1, ADC1_CH1, LP_GPIO1 + AGPIO(GPIO_USER), // 2 IO GPIO2, ADC1_CH2, LP_GPIO2 + AGPIO(GPIO_USER), // 3 IO GPIO3, ADC1_CH3, LP_GPIO3 + AGPIO(GPIO_USER), // 4 IO GPIO4, ADC1_CH4, LP_GPIO4, Strapping + AGPIO(GPIO_USER), // 5 IO GPIO5, ADC1_CH5, LP_GPIO5, Strapping + AGPIO(GPIO_USER), // 6 IO GPIO6, ADC1_CH6, LP_GPIO6 + AGPIO(GPIO_USER), // 7 IO GPIO7, LP_GPIO7 + AGPIO(GPIO_USER), // 8 IO GPIO8, Strapping + AGPIO(GPIO_USER), // 9 IO GPIO9, Strapping + AGPIO(GPIO_USER), // 10 IO GPIO10 (QFN40 only) + AGPIO(GPIO_USER), // 11 IO GPIO11 (QFN40 only) + AGPIO(GPIO_USER), // 12 IO GPIO12, USB-JTAG + AGPIO(GPIO_USER), // 13 IO GPIO13, USB-JTAG + AGPIO(GPIO_USER), // 14 IO GPIO14 (QFN32 only) + AGPIO(GPIO_USER), // 15 IO GPIO15, Strapping + AGPIO(GPIO_USER), // 16 IO TXD0 GPIO16, U0TXD + AGPIO(GPIO_USER), // 17 IO RXD0 GPIO17, U0RXD + AGPIO(GPIO_USER), // 18 IO GPIO18, SDIO_CMD + AGPIO(GPIO_USER), // 19 IO GPIO19, SDIO_CLK + AGPIO(GPIO_USER), // 20 IO GPIO20, SDIO_DATA0 + AGPIO(GPIO_USER), // 21 IO GPIO21, SDIO_DATA1 + AGPIO(GPIO_USER), // 22 IO GPIO22, SDIO_DATA2 + AGPIO(GPIO_USER), // 23 IO GPIO23, SDIO_DATA3 + 0, // 24 IO GPIO24, SPICS1, PSRAM + 0, // 25 IO GPIO25, SPIQ + 0, // 26 IO GPIO26, SPIWP - Free if flash DIO/DOUT + 0, // 27 IO GPIO27, SPIVDD + 0, // 28 IO GPIO28, SPIHD - Free if flash DIO/DOUT + 0, // 29 IO GPIO29, SPICLK + 0, // 30 IO GPIO30, SPID + 0 // Flag + }, +}; + +/*********************************************************************************************\ + Known templates +\*********************************************************************************************/ +#elif CONFIG_IDF_TARGET_ESP32P4 +/********************************************************************************************\ + * ESP32-P4 Module templates +\********************************************************************************************/ + +#define USER_MODULE 255 + +#define WT32_ETH01 4 //TODO: Why needed? + +// Supported hardware modules +enum SupportedModulesESP32P4 { + WEMOS, // not really correct, a placeholder for now + MAXMODULE }; + +// Default module settings +const uint8_t kModuleNiceList[] PROGMEM = { + WEMOS, +}; + +// !!! Update this list in the same order as kModuleNiceList !!! +const char kModuleNames[] PROGMEM = + "ESP32P4|" + ; + +// !!! Update this list in the same order as SupportedModulesESP32P4 !!! +const mytmplt kModules[] PROGMEM = { + { // Generic ESP32P4 device + AGPIO(GPIO_USER), // 0 IO GPIO0, LP_GPIO0 + AGPIO(GPIO_USER), // 1 IO GPIO1, LP_GPIO1 + AGPIO(GPIO_USER), // 2 IO GPIO2, TOUCH0, LP_GPIO2 + AGPIO(GPIO_USER), // 3 IO GPIO3, TOUCH1, LP_GPIO3 + AGPIO(GPIO_USER), // 4 IO GPIO4, TOUCH2, LP_GPIO4 + AGPIO(GPIO_USER), // 5 IO GPIO5, TOUCH3, LP_GPIO5 + AGPIO(GPIO_USER), // 6 IO GPIO6, TOUCH4, LP_GPIO6 + AGPIO(GPIO_USER), // 7 IO GPIO7, TOUCH5, LP_GPIO7 + AGPIO(GPIO_USER), // 8 IO GPIO8, TOUCH6, LP_GPIO8 + AGPIO(GPIO_USER), // 9 IO GPIO9, TOUCH7, LP_GPIO9 + AGPIO(GPIO_USER), // 10 IO GPIO10, TOUCH8, LP_GPIO10 + AGPIO(GPIO_USER), // 11 IO GPIO11, TOUCH9, LP_GPIO11 + AGPIO(GPIO_USER), // 12 IO GPIO12, TOUCH10, LP_GPIO12 + AGPIO(GPIO_USER), // 13 IO GPIO13, TOUCH11, LP_GPIO13 + AGPIO(GPIO_USER), // 14 IO GPIO14, TOUCH12, LP_GPIO14, SDIO2_D0 ESPHosted (ESP32C6 GPIO20) + AGPIO(GPIO_USER), // 15 IO GPIO15, TOUCH13, LP_GPIO15, SDIO2_D1 ESPHosted (ESP32C6 GPIO21) + AGPIO(GPIO_USER), // 16 IO GPIO16, ADC1_CH0, SDIO2_D2 ESPHosted (ESP32C6 GPIO22) + AGPIO(GPIO_USER), // 17 IO GPIO17, ADC1_CH1, SDIO2_D3 ESPHosted (ESP32C6 GPIO23) + AGPIO(GPIO_USER), // 18 IO GPIO18, ADC1_CH2, SDIO2_CLK ESPHosted (ESP32C6 GPIO19) + AGPIO(GPIO_USER), // 19 IO GPIO19, ADC1_CH3, SDIO2_CMD ESPHosted (ESP32C6 GPIO18) + AGPIO(GPIO_USER), // 20 IO GPIO20, ADC1_CH4 + AGPIO(GPIO_USER), // 21 IO GPIO21, ADC1_CH5 + AGPIO(GPIO_USER), // 22 IO GPIO22, ADC1_CH6 + AGPIO(GPIO_USER), // 23 IO GPIO23, ADC1_CH7 + AGPIO(GPIO_USER), // 24 IO GPIO24 + AGPIO(GPIO_USER), // 25 IO GPIO25 + AGPIO(GPIO_USER), // 26 IO GPIO26 + AGPIO(GPIO_USER), // 27 IO GPIO27 + AGPIO(GPIO_USER), // 28 IO GPIO28 + AGPIO(GPIO_USER), // 29 IO GPIO29 + AGPIO(GPIO_USER), // 30 IO GPIO30 + AGPIO(GPIO_USER), // 31 IO GPIO31 + AGPIO(GPIO_USER), // 32 IO GPIO32 + AGPIO(GPIO_USER), // 33 IO GPIO33 + AGPIO(GPIO_USER), // 34 IO GPIO34, Strapping pin + AGPIO(GPIO_USER), // 35 IO GPIO35, Strapping pin + AGPIO(GPIO_USER), // 36 IO GPIO36, Strapping pin + AGPIO(GPIO_USER), // 37 IO GPIO37, Strapping pin + AGPIO(GPIO_USER), // 38 IO GPIO38, Strapping pin + AGPIO(GPIO_USER), // 39 IO GPIO39 + AGPIO(GPIO_USER), // 40 IO GPIO40 + AGPIO(GPIO_USER), // 41 IO GPIO41 + AGPIO(GPIO_USER), // 42 IO GPIO42 + AGPIO(GPIO_USER), // 43 IO GPIO43 + AGPIO(GPIO_USER), // 44 IO GPIO44 + AGPIO(GPIO_USER), // 45 IO GPIO45 + AGPIO(GPIO_USER), // 46 IO GPIO46 + AGPIO(GPIO_USER), // 47 IO GPIO47 + AGPIO(GPIO_USER), // 48 IO GPIO48 + AGPIO(GPIO_USER), // 49 IO GPIO49, ADC1_CH8 + AGPIO(GPIO_USER), // 50 IO GPIO50, ADC1_CH9 + AGPIO(GPIO_USER), // 51 IO GPIO51, ADC1_CH10, ANA_CMPR_CH0 reference voltage + AGPIO(GPIO_USER), // 52 IO GPIO52, ADC1_CH11, ANA_CMPR_CH0 input (non-inverting) + AGPIO(GPIO_USER), // 53 IO GPIO53, ADC1_CH12, ANA_CMPR_CH1 reference voltage + AGPIO(GPIO_USER), // 54 IO GPIO54, ADC1_CH13, ANA_CMPR_CH1 input (non-inverting) + 0 // Flag + }, +}; + +/*********************************************************************************************\ + Known templates +\*********************************************************************************************/ + +#elif CONFIG_IDF_TARGET_ESP32S2 +/********************************************************************************************\ + * ESP32-S2 Module templates +\********************************************************************************************/ + +#define USER_MODULE 255 + +// Supported hardware modules +enum SupportedModulesESP32S2 { + WEMOS, + MAXMODULE }; + +// Default module settings +const uint8_t kModuleNiceList[] PROGMEM = { + WEMOS, +}; + +// !!! Update this list in the same order as kModuleNiceList !!! +const char kModuleNames[] PROGMEM = + "ESP32S2|" + ; + +// !!! Update this list in the same order as SupportedModulesESP32S2 !!! +const mytmplt kModules[] PROGMEM = { + { // Generic ESP32C3 device + AGPIO(GPIO_USER), // 0 IO GPIO0, RTC_GPIO0, Strapping + AGPIO(GPIO_USER), // 1 AO GPIO1, ADC1_CH0, RTC_GPIO1 + AGPIO(GPIO_USER), // 2 AO GPIO2, ADC1_CH1, RTC_GPIO2 + AGPIO(GPIO_USER), // 3 AO GPIO3, ADC1_CH2, RTC_GPIO3 + AGPIO(GPIO_USER), // 4 AO GPIO4, ADC1_CH3, RTC_GPIO4 + AGPIO(GPIO_USER), // 5 AO GPIO5, ADC1_CH4, RTC_GPIO5 + AGPIO(GPIO_USER), // 6 AO GPIO6, ADC1_CH5, RTC_GPIO6 + AGPIO(GPIO_USER), // 7 AO GPIO7, ADC1_CH6, RTC_GPIO7 + AGPIO(GPIO_USER), // 8 AO GPIO8, ADC1_CH7, RTC_GPIO8 + AGPIO(GPIO_USER), // 9 AO GPIO9, ADC1_CH8, RTC_GPIO9 + AGPIO(GPIO_USER), // 10 AO GPIO10, ADC1_CH9, RTC_GPIO10 + AGPIO(GPIO_USER), // 11 AO GPIO11, ADC2_CH0, RTC_GPIO11 + AGPIO(GPIO_USER), // 12 AO GPIO12, ADC2_CH1, RTC_GPIO12 + AGPIO(GPIO_USER), // 13 AO GPIO13, ADC2_CH2, RTC_GPIO13 + AGPIO(GPIO_USER), // 14 AO GPIO14, ADC2_CH3, RTC_GPIO14 + AGPIO(GPIO_USER), // 15 AO GPIO15, ADC2_CH4, RTC_GPIO15, XTAL_32K_P + AGPIO(GPIO_USER), // 16 AO GPIO16, ADC2_CH5, RTC_GPIO16, XTAL_32K_N + AGPIO(GPIO_USER), // 17 AO GPIO17, ADC2_CH6, RTC_GPIO17, DAC_1 + AGPIO(GPIO_USER), // 18 AO GPIO18, ADC2_CH7, RTC_GPIO18, DAC_2 + AGPIO(GPIO_USER), // 19 AO GPIO19, ADC2_CH8, RTC_GPIO19 + AGPIO(GPIO_USER), // 20 AO GPIO20, ADC2_CH9, RTC_GPIO20 + AGPIO(GPIO_USER), // 21 IO GPIO21, RTC_GPIO21 + // 22 -- Unused + // 23 -- Unused + // 24 -- Unused + // 25 -- Unused + // 26 FL SPICS1, PSRAM + // 27 FL SPIHD + // 28 FL SPIWP + // 29 FL SPICS0 + // 30 FL SPICLK + // 31 FL SPIQ + // 32 FL SPID + AGPIO(GPIO_USER), // 33 IO GPIO33 + AGPIO(GPIO_USER), // 34 IO GPIO34 + AGPIO(GPIO_USER), // 35 IO GPIO35 + AGPIO(GPIO_USER), // 36 IO GPIO36 + AGPIO(GPIO_USER), // 37 IO GPIO37 + AGPIO(GPIO_USER), // 38 IO GPIO38 + AGPIO(GPIO_USER), // 39 IO GPIO39, JTAG MTCK + AGPIO(GPIO_USER), // 40 IO GPIO40, JTAG MTDO + AGPIO(GPIO_USER), // 41 IO GPIO41, JTAG MTDI + AGPIO(GPIO_USER), // 42 IO GPIO42, JTAG MTMS + AGPIO(GPIO_USER), // 43 IO GPIO43, U0TXD + AGPIO(GPIO_USER), // 44 IO GPIO44, U0RXD + AGPIO(GPIO_USER), // 45 IO GPIO45, Strapping + AGPIO(GPIO_USER), // 46 I GPIO46, Input only, Strapping + 0 // Flag + }, +}; + +/*********************************************************************************************\ + Known templates +\*********************************************************************************************/ + +#elif CONFIG_IDF_TARGET_ESP32S3 +/********************************************************************************************\ + * ESP32-S3 Module templates +\********************************************************************************************/ + +#define USER_MODULE 255 + +// Supported hardware modules +enum SupportedModulesESP32S3 { + WEMOS, + MAXMODULE }; + +// Default module settings +const uint8_t kModuleNiceList[] PROGMEM = { + WEMOS, +}; + +// !!! Update this list in the same order as kModuleNiceList !!! +const char kModuleNames[] PROGMEM = + "ESP32S3|" + ; + +// !!! Update this list in the same order as SupportedModulesESP32S2 !!! +const mytmplt kModules[] PROGMEM = { + { // Generic ESP32C3 device + AGPIO(GPIO_USER), // 0 IO RTC_GPIO0, GPIO0, Strapping + AGPIO(GPIO_USER), // 1 AO RTC_GPIO1, GPIO1, TOUCH1, ADC1_CH0 + AGPIO(GPIO_USER), // 2 AO RTC_GPIO2, GPIO2, TOUCH2, ADC1_CH1 + AGPIO(GPIO_USER), // 3 AO RTC_GPIO3, GPIO3, TOUCH3, ADC1_CH2, Strapping + AGPIO(GPIO_USER), // 4 AO RTC_GPIO4, GPIO4, TOUCH4, ADC1_CH3 + AGPIO(GPIO_USER), // 5 AO RTC_GPIO5, GPIO5, TOUCH5, ADC1_CH4 + AGPIO(GPIO_USER), // 6 AO RTC_GPIO6, GPIO6, TOUCH6, ADC1_CH5 + AGPIO(GPIO_USER), // 7 AO RTC_GPIO7, GPIO7, TOUCH7, ADC1_CH6 + AGPIO(GPIO_USER), // 8 AO RTC_GPIO8, GPIO8, TOUCH8, ADC1_CH7, SUBSPICS1 + AGPIO(GPIO_USER), // 9 AO RTC_GPIO9, GPIO9, TOUCH9, ADC1_CH8, SUBSPIHD, FSPIHD + AGPIO(GPIO_USER), // 10 AO RTC_GPIO10, GPIO10, TOUCH10, ADC1_CH9, FSPIIO4, SUBSPICS0, FSPICS0 + AGPIO(GPIO_USER), // 11 AO RTC_GPIO11, GPIO11, TOUCH11, ADC2_CH0, FSPIIO5, SUBSPID, FSPID + AGPIO(GPIO_USER), // 12 AO RTC_GPIO12, GPIO12, TOUCH12, ADC2_CH1, FSPIIO6, SUBSPICLK, FSPICLK + AGPIO(GPIO_USER), // 13 AO RTC_GPIO13, GPIO13, TOUCH13, ADC2_CH2, FSPIIO7, SUBSPIQ, FSPIQ + AGPIO(GPIO_USER), // 14 AO RTC_GPIO14, GPIO14, TOUCH14, ADC2_CH3, FSPIDQS, SUBSPIWP, FSPIWP + AGPIO(GPIO_USER), // 15 AO RTC_GPIO15, GPIO15, U0RTS, ADC2_CH4, XTAL_32K_P + AGPIO(GPIO_USER), // 16 AO RTC_GPIO16, GPIO16, U0CTS, ADC2_CH5, XTAL_32K_N + AGPIO(GPIO_USER), // 17 AO RTC_GPIO17, GPIO17, U1TXD, ADC2_CH6 + AGPIO(GPIO_USER), // 18 AO RTC_GPIO18, GPIO18, U1RXD, ADC2_CH7, CLK_OUT3 + AGPIO(GPIO_USER), // 19 AO RTC_GPIO19, GPIO19, U1RTS, ADC2_CH8, CLK_OUT2, USB_D­ + AGPIO(GPIO_USER), // 20 AO RTC_GPIO20, GPIO20, U1CTS, ADC2_CH9, CLK_OUT1, USB_D+ + AGPIO(GPIO_USER), // 21 IO RTC_GPIO21, GPIO21 + // 22 -- Unused + // 23 -- Unused + // 24 -- Unused + // 25 -- Unused + // 26 FL SPICS1, GPIO26 + // 27 FL SPIHD, GPIO27 + // 28 FL SPIWP, GPIO28 + // 29 FL SPICS0, GPIO29 + // 30 FL SPICLK, GPIO30 + // 31 FL SPIQ, GPIO31 + // 32 FL SPID, GPIO32 + AGPIO(GPIO_NONE), // 33 IO SPIIO4, GPIO33, FSPIHD, SUBSPIHD + AGPIO(GPIO_NONE), // 34 IO SPIIO5, GPIO34, FSPICS0, SUBSPICS0 + AGPIO(GPIO_NONE), // 35 IO SPIIO6, GPIO35, FSPID, SUBSPID + AGPIO(GPIO_NONE), // 36 IO SPIIO7, GPIO36, FSPICLK, SUBSPICLK + AGPIO(GPIO_NONE), // 37 IO SPIDQS, GPIO37, FSPIQ, SUBSPIQ + AGPIO(GPIO_USER), // 38 IO GPIO38, FSPIWP, SUBSPIWP + AGPIO(GPIO_USER), // 39 IO MTCK, GPIO39, CLK_OUT3, SUBSPICS1 + AGPIO(GPIO_USER), // 40 IO MTDO, GPIO40, CLK_OUT2 + AGPIO(GPIO_USER), // 41 IO MTDI, GPIO41, CLK_OUT1 + AGPIO(GPIO_USER), // 42 IO MTMS, GPIO42 + AGPIO(GPIO_USER), // 43 IO U0TXD, GPIO43, CLK_OUT1 + AGPIO(GPIO_USER), // 44 IO U0RXD, GPIO44, CLK_OUT2 + AGPIO(GPIO_USER), // 45 IO GPIO45, Strapping + AGPIO(GPIO_USER), // 46 IO GPIO46, Strapping + AGPIO(GPIO_USER), // 47 IO SPICLK_P_DIFF, GPIO47, SUBSPICLK_P_DIFF + AGPIO(GPIO_USER), // 48 IO SPICLK_N_DIFF, GPIO48, SUBSPICLK_N_DIFF + 0 // Flag + }, +}; + +/*********************************************************************************************\ + Known templates +\*********************************************************************************************/ + +#else // not CONFIG_IDF_TARGET_ESP32C2/C3/C6 nor CONFIG_IDF_TARGET_ESP32S2 - ESP32 +/********************************************************************************************\ + * ESP32 Module templates +\********************************************************************************************/ + +#define USER_MODULE 255 + +// Supported hardware modules +enum SupportedModulesESP32 { + WEMOS, + ESP32_CAM_AITHINKER, + ODROID_GO, + ESP32_SOLO, + WT32_ETH01, + MAXMODULE }; + +// Default module settings +const uint8_t kModuleNiceList[] PROGMEM = { + WEMOS, +#ifdef USE_WEBCAM + ESP32_CAM_AITHINKER, +#endif // USE_WEBCAM +#ifdef USE_ODROID_GO + ODROID_GO, +#endif // USE_ODROID_GO +#ifdef USE_ESP32_SOLO +// ESP32_SOLO, // To be defined +#endif // USE_ESP32_SOLO +#ifdef USE_WT32_ETH01 + WT32_ETH01, +#endif // USE_WT32_ETH01 +}; + +// !!! Update this list in the same order as kModuleNiceList !!! +const char kModuleNames[] PROGMEM = + "ESP32-DevKit|" +#ifdef USE_WEBCAM + "ESP32-Cam|" +#endif // USE_WEBCAM +#ifdef USE_ODROID_GO + "Odroid Go|" +#endif // USE_ODROID_GO +#ifdef USE_ESP32_SOLO +// "ESP32-Solo|" // To be defined +#endif // USE_ESP32_SOLO +#ifdef USE_WT32_ETH01 + "WT32-Eth01|" +#endif // USE_WT32_ETH01 + ; + +// !!! Update this list in the same order as SupportedModulesESP32 !!! +const mytmplt kModules[] PROGMEM = { + { // WEMOS - Espressif ESP32-DevKitC - Any ESP32 device like WeMos and NodeMCU hardware (ESP32) + AGPIO(GPIO_USER), // 0 (I)O GPIO0, ADC2_CH1, TOUCH1, RTC_GPIO11, CLK_OUT1, EMAC_TX_CLK + AGPIO(GPIO_USER), // 1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 + AGPIO(GPIO_USER), // 2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 + AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD, CLK_OUT2 + AGPIO(GPIO_USER), // 4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER + AGPIO(GPIO_USER), // 5 IO GPIO5, VSPICS0, HS1_DATA6, EMAC_RX_CLK + // 6 IO Remapped to 28 + // 7 IO Remapped to 29 + // 8 IO Remapped to 30 + AGPIO(GPIO_USER), // 9 IO GPIO9, Flash D2, U1RXD + AGPIO(GPIO_USER), // 10 IO GPIO10, Flash D3, U1TXD + // 11 IO Remapped to 31 + AGPIO(GPIO_USER), // 12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.) + AGPIO(GPIO_USER), // 13 IO GPIO13, ADC2_CH4, TOUCH4, RTC_GPIO14, MTCK, HSPID, HS2_DATA3, SD_DATA3, EMAC_RX_ER + AGPIO(GPIO_USER), // 14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 + AGPIO(GPIO_USER), // 15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.) + AGPIO(GPIO_USER), // 16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT + AGPIO(GPIO_USER), // 17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180 + AGPIO(GPIO_USER), // 18 IO GPIO18, VSPICLK, HS1_DATA7 + AGPIO(GPIO_USER), // 19 IO GPIO19, VSPIQ, U0CTS, EMAC_TXD0 + 0, // 20 + AGPIO(GPIO_USER), // 21 IO GPIO21, VSPIHD, EMAC_TX_EN + AGPIO(GPIO_USER), // 22 IO LED GPIO22, VSPIWP, U0RTS, EMAC_TXD1 + AGPIO(GPIO_USER), // 23 IO GPIO23, VSPID, HS1_STROBE + 0, // 24 + AGPIO(GPIO_USER), // 25 IO GPIO25, DAC_1, ADC2_CH8, RTC_GPIO6, EMAC_RXD0 + AGPIO(GPIO_USER), // 26 IO GPIO26, DAC_2, ADC2_CH9, RTC_GPIO7, EMAC_RXD1 + AGPIO(GPIO_USER), // 27 IO GPIO27, ADC2_CH7, TOUCH7, RTC_GPIO17, EMAC_RX_DV + 0, // 6 IO GPIO6, Flash CLK + 0, // 7 IO GPIO7, Flash D0 + 0, // 8 IO GPIO8, Flash D1 + 0, // 11 IO GPIO11, Flash CMD + AGPIO(GPIO_USER), // 32 IO GPIO32, XTAL_32K_P (32.768 kHz crystal oscillator input), ADC1_CH4, TOUCH9, RTC_GPIO9 + AGPIO(GPIO_USER), // 33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8 + AGPIO(GPIO_USER), // 34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4 + AGPIO(GPIO_USER), // 35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5 + AGPIO(GPIO_USER), // 36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0 + 0, // 37 NO PULLUP + 0, // 38 NO PULLUP + AGPIO(GPIO_USER), // 39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3 + 0 // Flag + }, + +#ifdef USE_WEBCAM + { // ESP32_CAM_AITHINKER - Any ESP32 device with webcam (ESP32) + AGPIO(GPIO_WEBCAM_XCLK), // 0 (I)O GPIO0, CAM_XCLK + AGPIO(GPIO_USER), // 1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 + AGPIO(GPIO_SPI_MISO), // 2 IO GPIO2, VSPI_MISO + AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD, CLK_OUT2 + AGPIO(GPIO_PWM1), // 4 IO GPIO4, Flashlight + AGPIO(GPIO_WEBCAM_DATA), // 5 IO GPIO5, CAM_DATA1 + // 6 IO Remapped to 28 + // 7 IO Remapped to 29 + // 8 IO Remapped to 30 + AGPIO(GPIO_USER), // 9 IO GPIO9, Flash D2, U1RXD + AGPIO(GPIO_USER), // 10 IO GPIO10, Flash D3, U1TXD + // 11 IO Remapped to 31 + AGPIO(GPIO_USER), // 12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.) + AGPIO(GPIO_SDCARD_CS), // 13 IO GPIO13, VSPI_CS_TFLASH + AGPIO(GPIO_SPI_CLK), // 14 IO GPIO14, VSPI_CLK + AGPIO(GPIO_SPI_MOSI), // 15 (I)O GPIO15, VSPI_MOSI (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.) + AGPIO(GPIO_USER), // 16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT + AGPIO(GPIO_USER), // 17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180 + AGPIO(GPIO_WEBCAM_DATA) +1, // 18 IO GPIO18, CAM_DATA2 + AGPIO(GPIO_WEBCAM_DATA) +2, // 19 IO GPIO19, CAM_DATA3 + 0, // 20 + AGPIO(GPIO_WEBCAM_DATA) +3, // 21 IO GPIO21, CAM_DATA4 + AGPIO(GPIO_WEBCAM_PCLK), // 22 IO LED GPIO22, CAM_PCLK + AGPIO(GPIO_WEBCAM_HREF), // 23 IO GPIO23, CAM_HREF + 0, // 24 + AGPIO(GPIO_WEBCAM_VSYNC), // 25 IO GPIO25, CAM_VSYNC + AGPIO(GPIO_WEBCAM_SIOD), // 26 IO GPIO26, CAM_SIOD + AGPIO(GPIO_WEBCAM_SIOC), // 27 IO GPIO27, CAM_SIOC + 0, // 6 IO GPIO6, Flash CLK + 0, // 7 IO GPIO7, Flash D0 + 0, // 8 IO GPIO8, Flash D1 + 0, // 11 IO GPIO11, Flash CMD + AGPIO(GPIO_WEBCAM_PWDN), // 32 IO GPIO32, CAM_PWDN + AGPIO(GPIO_USER), // 33 IO GPIO33, XTAL_32K_N (32.768 kHz crystal oscillator output), ADC1_CH5, TOUCH8, RTC_GPIO8 + AGPIO(GPIO_WEBCAM_DATA) +6, // 34 I NO PULLUP GPIO34, CAM_DATA7 + AGPIO(GPIO_WEBCAM_DATA) +7, // 35 I NO PULLUP GPIO35, CAM_DATA8 + AGPIO(GPIO_WEBCAM_DATA) +4, // 36 I NO PULLUP GPIO36, CAM_DATA5 + 0, // 37 NO PULLUP + 0, // 38 NO PULLUP + AGPIO(GPIO_WEBCAM_DATA) +5, // 39 I NO PULLUP GPIO39, CAM_DATA6 + 0 // Flag + }, +#endif // USE_WEBCAM + +#ifdef USE_ODROID_GO + { // ODROID_GO - (ESP32) + AGPIO(GPIO_KEY1), // 0 (I)O GPIO0, BTN-VOLUME + AGPIO(GPIO_TXD), // 1 IO TXD0 GPIO1, TXD0 + AGPIO(GPIO_LEDLNK), // 2 IO GPIO2, STATUS LED + AGPIO(GPIO_RXD), // 3 IO RXD0 GPIO3, RXD0 + AGPIO(GPIO_USER), // 4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER + AGPIO(GPIO_ILI9341_CS), // 5 IO GPIO5, VSPI_CS0_LCD + // 6 IO Remapped to 28 + // 7 IO Remapped to 29 + // 8 IO Remapped to 30 + 0, // 9 IO GPIO9, Flash D2, U1RXD + 0, // 10 IO GPIO10, Flash D3, U1TXD + // 11 IO Remapped to 31 + AGPIO(GPIO_USER), // 12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.) + AGPIO(GPIO_KEY1) +1, // 13 IO GPIO13, BTN-MENU + AGPIO(GPIO_PWM1), // 14 IO GPIO14, LCD Backlight + AGPIO(GPIO_USER), // 15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.) + AGPIO(GPIO_USER), // 16 IO GPIO16, HS1_DATA4, U2RXD, EMAC_CLK_OUT + AGPIO(GPIO_USER), // 17 IO GPIO17, HS1_DATA5, U2TXD, EMAC_CLK_OUT_180 + AGPIO(GPIO_SPI_CLK), // 18 IO GPIO18, VSPI_CLK + AGPIO(GPIO_SPI_MISO), // 19 IO GPIO19, VSPI_MISO + 0, // 20 + AGPIO(GPIO_ILI9341_DC), // 21 IO GPIO21, SPI_DC_LCD + AGPIO(GPIO_SDCARD_CS), // 22 IO LED GPIO22, VSPI_CS1_TFLASH + AGPIO(GPIO_SPI_MOSI), // 23 IO GPIO23, VSPI_MOSI + 0, // 24 + 0, // 25 IO GPIO25, DAC_1 (PAM8304A) + 0, // 26 IO GPIO26, DAC_2 (PAM8304A) + AGPIO(GPIO_KEY1) +2, // 27 IO GPIO27, BTN-SELECT + 0, // 6 IO GPIO6, Flash CLK + 0, // 7 IO GPIO7, Flash D0 + 0, // 8 IO GPIO8, Flash D1 + 0, // 11 IO GPIO11, Flash CMD + AGPIO(GPIO_SWT1) +4, // 32 IO GPIO32, BTN-A + AGPIO(GPIO_SWT1) +5, // 33 IO GPIO33, BTN-B + AGPIO(GPIO_ADC_JOY), // 34 I NO PULLUP GPIO34, JOY-X (LEFT-RIGHT) + AGPIO(GPIO_ADC_JOY) +1, // 35 I NO PULLUP GPIO35, JOY-Y (UP-DOWN) + AGPIO(GPIO_ADC_RANGE) +2, // 36 I NO PULLUP GPIO36, SENSOR_VP (BATTERY CARGER) + 0, // 37 NO PULLUP + 0, // 38 NO PULLUP + AGPIO(GPIO_KEY1) +3, // 39 I NO PULLUP GPIO39, BTN-START + 0 // Flag + }, +#endif // USE_ODROID_GO + +#ifdef USE_ESP32_SOLO +// { // ESP32 Solo (ESP32) - To be defined +// }, +#endif // USE_ESP32_SOLO + +#ifdef USE_WT32_ETH01 + { // WT32_ETH01 - (ESP32) + 0, // 0 (I)O GPIO0, Ethernet EMAC_REF_CLK + AGPIO(GPIO_USER), // 1 IO TXD0 GPIO1, U0TXD, CLK_OUT3, EMAC_RXD2 + AGPIO(GPIO_USER), // 2 IO GPIO2, ADC2_CH2, TOUCH2, RTC_GPIO12, HSPIWP, HS2_DATA0, SD_DATA0 + AGPIO(GPIO_USER), // 3 IO RXD0 GPIO3, U0RXD, CLK_OUT2 + AGPIO(GPIO_USER), // 4 IO GPIO4, ADC2_CH0, TOUCH0, RTC_GPIO10, HSPIHD, HS2_DATA1, SD_DATA1, EMAC_TX_ER + AGPIO(GPIO_USER), // 5 IO GPIO5, RXD Led green + // 6 IO Remapped to 28 + // 7 IO Remapped to 29 + // 8 IO Remapped to 30 + 0, // 9 IO GPIO9, Flash D2, U1RXD + 0, // 10 IO GPIO10, Flash D3, U1TXD + // 11 IO Remapped to 31 + AGPIO(GPIO_USER), // 12 (I)O GPIO12, ADC2_CH5, TOUCH5, RTC_GPIO15, MTDI, HSPIQ, HS2_DATA2, SD_DATA2, EMAC_TXD3 (If driven High, flash voltage (VDD_SDIO) is 1.8V not default 3.3V. Has internal pull-down, so unconnected = Low = 3.3V. May prevent flashing and/or booting if 3.3V flash is connected and pulled high. See ESP32 datasheet for more details.) + 0, // 13 IO GPIO13, Ethernet EMAC_RX_ER + AGPIO(GPIO_USER), // 14 IO GPIO14, ADC2_CH6, TOUCH6, RTC_GPIO16, MTMS, HSPICLK, HS2_CLK, SD_CLK, EMAC_TXD2 + AGPIO(GPIO_USER), // 15 (I)O GPIO15, ADC2_CH3, TOUCH3, MTDO, HSPICS0, RTC_GPIO13, HS2_CMD, SD_CMD, EMAC_RXD3 (If driven Low, silences boot messages from normal boot. Has internal pull-up, so unconnected = High = normal output.) + AGPIO(GPIO_OUTPUT_HI), // 16 IO GPIO16, Ethernet OSC_ENA + AGPIO(GPIO_LEDLNK_INV), // 17 IO GPIO17, Network link led (green) + AGPIO(GPIO_ETH_PHY_MDIO), // 18 IO GPIO18, Ethernet MDIO + 0, // 19 IO GPIO19, Ethernet TXD0 + 0, // 20 + 0, // 21 IO GPIO21, Ethernet EMAC_TX_EN + 0, // 22 IO LED GPIO22, Ethernet EMAC_TXD1 + AGPIO(GPIO_ETH_PHY_MDC), // 23 IO GPIO23, Ethernet MDC + 0, // 24 + 0, // 25 IO GPIO25, Ethernet EMAC_RXD0 + 0, // 26 IO GPIO26, Ethernet EMAC_RXD1 + 0, // 27 IO GPIO27, Ethernet EMAC_RX_DV + 0, // 6 IO GPIO6, Flash CLK + 0, // 7 IO GPIO7, Flash D0 + 0, // 8 IO GPIO8, Flash D1 + 0, // 11 IO GPIO11, Flash CMD + AGPIO(GPIO_USER), // 32 IO GPIO32, CFG + AGPIO(GPIO_USER), // 33 IO GPIO33, 485_EN + 0, // 34 I NO PULLUP GPIO34, ADC1_CH6, RTC_GPIO4 + AGPIO(GPIO_USER), // 35 I NO PULLUP GPIO35, ADC1_CH7, RTC_GPIO5 + AGPIO(GPIO_USER), // 36 I NO PULLUP GPIO36, SENSOR_VP, ADC_H, ADC1_CH0, RTC_GPIO0 + 0, // 37 NO PULLUP + 0, // 38 NO PULLUP + AGPIO(GPIO_USER), // 39 I NO PULLUP GPIO39, SENSOR_VN, ADC1_CH3, ADC_H, RTC_GPIO3 + 0 // Flag + }, +#endif // USE_WT32_ETH01 + +}; + +/*********************************************************************************************\ + Known templates + +{"NAME":"AITHINKER CAM","GPIO":[4992,1,1,1,1,5088,1,1,1,1,1,1,1,1,5089,5090,0,5091,5184,5152,0,5120,5024,5056,0,0,0,0,4928,1,5094,5095,5092,0,0,5093],"FLAG":0,"BASE":1} +{"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} +{"NAME":"wESP32","GPIO":[1,1,1,1,1,1,0,0,0,1,1,1,5568,5600,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} +{"NAME":"Denky (Teleinfo)","GPIO":[1,1,1,1,5664,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,0,1376,1,1,0,0,0,0,1,5632,1,1,1,0,0,1],"FLAG":0,"BASE":1} + +\*********************************************************************************************/ + +#endif // ESP32/S2/C3 selection +#endif // ESP32 + +#endif // _TASMOTA_TEMPLATE_H_ diff --git a/tasmota/include/tasmota_version.h b/tasmota/include/tasmota_version.h index 61ff8aa87..9238d3e2a 100644 --- a/tasmota/include/tasmota_version.h +++ b/tasmota/include/tasmota_version.h @@ -1,27 +1,27 @@ -/* - tasmota_version.h - Version header file for Tasmota - - Copyright (C) 2021 Theo Arends - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef _TASMOTA_VERSION_H_ -#define _TASMOTA_VERSION_H_ - -#define TASMOTA_SHA_SHORT // Filled by Github sed - -const uint32_t TASMOTA_VERSION = 0x0F020005; // 15.2.0.5 - -#endif // _TASMOTA_VERSION_H_ +/* + tasmota_version.h - Version header file for Tasmota + + Copyright (C) 2021 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _TASMOTA_VERSION_H_ +#define _TASMOTA_VERSION_H_ + +#define TASMOTA_SHA_SHORT // Filled by Github sed + +const uint32_t TASMOTA_VERSION = 0x0F020005; // 15.2.0.5 + +#endif // _TASMOTA_VERSION_H_ diff --git a/tasmota/language/af_AF.h b/tasmota/language/af_AF.h index 3b563e783..f5aaad3cf 100644 --- a/tasmota/language/af_AF.h +++ b/tasmota/language/af_AF.h @@ -1,1342 +1,1342 @@ -/* - af_AF.h - localization for Afrikaans - Afrikaans for Tasmota - - Copyright (C) 2021 Christiaan Heerze - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifndef _LANGUAGE_AF_AF_H_ -#define _LANGUAGE_AF_AF_H_ - -/*************************** ATTENTION *******************************\ - * - * Due to memory constraints only UTF-8 is supported. - * To save code space keep text as short as possible. - * Time and Date provided by SDK can not be localized (yet). - * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. - * Use online command Prefix to translate cmnd, stat and tele. - * - * Updated until v9.3.1.1 -\*********************************************************************/ - -//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) -// https://www.science.co.il/language/Locale-codes.php -#define LANGUAGE_LCID 1078 -// HTML (ISO 639-1) Language Code -#define D_HTML_LANGUAGE "af" - -// "2017-03-07T11:08:02" - ISO8601:2004 -#define D_YEAR_MONTH_SEPARATOR "-" -#define D_MONTH_DAY_SEPARATOR "-" -#define D_DATE_TIME_SEPARATOR "T" -#define D_HOUR_MINUTE_SEPARATOR ":" -#define D_MINUTE_SECOND_SEPARATOR ":" - -#define D_DAY3LIST "SonMaaDinWoeDonVryDonSat" -#define D_MONTH3LIST "JanFebMaaAprMeiJunJulAugSepOktNovDes" - -// Non JSON decimal separator -#define D_DECIMAL_SEPARATOR "." - -// Common -#define D_ABSOLUTE_HUMIDITY "Abs Humidity" -#define D_ADDRESS "Address" -#define D_ADMIN "Admin" -#define D_AIR_QUALITY "Luggehalte" -#define D_AP "AP" // Access Point -#define D_AS "as" -#define D_AT "at" -#define D_AUTO "AUTO" -#define D_AUTO_UPDATE "Auto Update" -#define D_BATT "Batt" // Short for Battery -#define D_BATTERY "Battery" -#define D_BATTERY_CHARGE "Lading" // Battery charge in % -#define D_BLINK "Flits" -#define D_BLINKOFF "FlitsAf" -#define D_BOOT_COUNT "Opstarttelling" -#define D_BRIGHTLIGHT "Helder" -#define D_BSSID "BSSId" -#define D_BUTTON "Knoppie" -#define D_BY "deur" // Written by me -#define D_BYTES "Bytes" -#define D_CELSIUS "Celsius" -#define D_CHANNEL "Kanaal" -#define D_CO2 "Koolstofdioksied" -#define D_CODE "kode" // Button code -#define D_COLDLIGHT "Koud" -#define D_COLOR "Color" -#define D_COMMAND "Bevel" -#define D_CONNECTED "Gekoppel" -#define D_CORS_DOMAIN "CORS Domain" -#define D_COUNT "Telling" -#define D_COUNTER "Opnemer" -#define D_CT_POWER "CT Power" -#define D_CURRENT "Stroom" // As in Voltage and Current -#define D_CURRENT_NEUTRAL "Current Neutral" -#define D_DARKLIGHT "Donker" -#define D_DATA "Data" -#define D_DEBUG "Ontfout" -#define D_DEWPOINT "Dou punt" -#define D_DISABLED "Gedeaktiveer" -#define D_DISCONNECTED "Disconnected" -#define D_DISTANCE "Afstand" -#define D_DNS_SERVER "DNS" -#define D_DO "Opgeloste suurstof" -#define D_DONE "Klaar" -#define D_DST_TIME "DST" -#define D_EC "EC" -#define D_ECO2 "eCO₂" -#define D_EMULATION "Emulasie" -#define D_ENABLED "Geaktiveer" -#define D_ERASE "Vee uit" -#define D_ERROR "Fout" -#define D_FAHRENHEIT "Fahrenheit" -#define D_FAILED "Misluk " -#define D_FALLBACK "Terugval" -#define D_FALLBACK_TOPIC "Terugval onderwerp" -#define D_FALSE "Onwaar" -#define D_FILE "Lêer" -#define D_FILE_SYSTEM_SIZE "File System Size" -#define D_FLOW_RATE "Vloeitempo" -#define D_FRAGMENTATION "frag." // Lower case abbreviated version of fragmentation used in "memory fragmentation" -#define D_FRAME_RATE "Frame rate" -#define D_FREE_MEMORY "Vrye geheue" -#define D_FREQUENCY "Frekwensie" -#define D_GAS "Gas" -#define D_GATEWAY "Gateway" -#define D_GROUP "Groep" -#define D_HALL_EFFECT "Hall Effect" -#define D_HEATINDEX "Heat index" -#define D_HOST "Gasheer" -#define D_HOSTNAME "Gasheername" -#define D_HUMIDITY "Humiditeit" -#define D_ILLUMINANCE "Verligting" -#define D_IMMEDIATE "onmiddellik" // Button immediate -#define D_INDEX "Indeks" -#define D_INFO "Inligting" -#define D_INFRARED "Infrarooi" -#define D_INITIALIZED "Geïnisialiseer" -#define D_IP_ADDRESS "IP-adresse" -#define D_LIGHT "Lig" -#define D_LQI "LQI" // Zigbee Link Quality Index -#define D_LWT "LWT" -#define D_MODULE "Module" -#define D_MOISTURE "Vog" -#define D_MQ "MQ" -#define D_MQTT "MQTT" -#define D_MULTI_PRESS "multi-press" -#define D_NOISE "Geraas" -#define D_NONE "Geen" -#define D_NOX "NOx" -#define D_O2 "Suurstof" -#define D_OFF "Uit" -#define D_OFFLINE "Vanlyn" -#define D_OK "Ok" -#define D_ON "aan" -#define D_ONLINE "Aanlyn" -#define D_ORP "ORP" -#define D_PARTITION "Partition" // As in flash and firmware partition -#define D_PASSWORD "Wagwoord" -#define D_PH "pH" -#define D_PORT "Poort" -#define D_POWER_FACTOR "Krag faktor" -#define D_POWERUSAGE "Krag" -#define D_POWERUSAGE_ACTIVE "Regte krag" -#define D_POWERUSAGE_ACTIVE_TOTAL "Active Power Total" -#define D_POWERUSAGE_APPARENT "Oënskynlike krag" -#define D_POWERUSAGE_REACTIVE "reaktiewe krag" -#define D_PRESSURE "Druk" -#define D_PRESSUREATSEALEVEL "Druk op seevlak" -#define D_PROGRAM_FLASH_SIZE "Program Flash Grootte" -#define D_PROGRAM_SIZE "Program Grootte" -#define D_PROJECT "Projek" -#define D_PSR_FREE_MEMORY "PS-RAM vrye geheue" -#define D_PSR_MAX_MEMORY "PS-RAM geheue" -#define D_RAIN "Reën" -#define D_RANGE "Gebied" -#define D_RECEIVED "Ontvang" -#define D_RESTART "Herbegin" -#define D_RESTART_REASON "Herlaai rede" -#define D_RESTARTING "Herbegin" -#define D_RETAINED "behou" -#define D_RULE "Reël" -#define D_SAVE "Stoor" -#define D_SENSOR "Sensor" -#define D_SOC "Laai kondisie" -#define D_SOH "Laai vermoeë" -#define D_SSID "SSId" -#define D_START "Begin" -#define D_STD_TIME "STD" -#define D_STOP "Stop" -#define D_SUBNET_MASK "Subnet Masker" -#define D_SUBSCRIBE_TO "Teken in op" -#define D_SUCCESSFUL "Suksesvol" -#define D_SUNRISE "Sonsopkoms" -#define D_SUNSET "Sononder" -#define D_TEMPERATURE "Temperatuur" -#define D_TIME_OF_DAY "Tyd" -#define D_TO "naar" -#define D_TOGGLE "Verwissel" -#define D_TOPIC "Onderwerp" -#define D_TOTAL_USAGE "Totale gebruik" -#define D_TRANSMIT "Stuur" -#define D_TRUE "Waar" -#define D_TVOC "TVOC" -#define D_TWILIGHT_ASTRONOMICAL "Astronomical" -#define D_TWILIGHT_CIVIL "Civil" -#define D_TWILIGHT_NAUTICAL "Nautical" -#define D_UNSUBSCRIBE_FROM "Teken uit van" -#define D_UPLOAD "Laai op" -#define D_UPTIME "Uptyd" -#define D_USED "used" -#define D_USER "Gebruiker" -#define D_UTC_TIME "UTC" -#define D_UV_INDEX "UV Indeks" -#define D_UV_INDEX_1 "Laag" -#define D_UV_INDEX_2 "Middel" -#define D_UV_INDEX_3 "Hoog" -#define D_UV_INDEX_4 "Gevaarlik" -#define D_UV_INDEX_5 "1ste/2de graad sonbrand" -#define D_UV_INDEX_6 "3e graad sonbrand" -#define D_UV_INDEX_7 "Buite bereik" // Out of Range -#define D_UV_LEVEL "UV Level" -#define D_UV_POWER "UV krag" -#define D_VERSION "Weergawe" -#define D_VOC "VOC" -#define D_VOLTAGE "Spanning" -#define D_VOLUME "Volume" -#define D_WARMLIGHT "Warm" -#define D_WATER_DEPTH "Water diepte" -#define D_WEB_SERVER "Webbediener" -#define D_WEIGHT "Gewig" - -// tasmota.ino -#define D_WARNING_MINIMAL_VERSION "WAARSKUWING Hierdie weergawe ondersteun nie aanhoudende instellings nie" -#define D_LEVEL_10 "level 1-0" -#define D_LEVEL_01 "level 0-1" -#define D_SERIAL_LOGGING_DISABLED "Syslog-logging is uitgeskakel" -#define D_SYSLOG_LOGGING_REENABLED "Syslog-logging is weer geaktiveer" - -#define D_SET_BAUDRATE_TO "Stem Baudrate op" -#define D_RECEIVED_TOPIC "Ontvang onderwerp" -#define D_DATA_SIZE "Data grootte" -#define D_ANALOG_INPUT "Analoog" - -// support.ino -#define D_OSWATCH "osWatch" -#define D_BLOCKED_LOOP "Geblokkeerde lus" -#define D_WPS_FAILED_WITH_STATUS "WPSconfig kon nie status kry nie" -#define D_ACTIVE_FOR_3_MINUTES "3 minute aktief" -#define D_FAILED_TO_START "kon nie begin nie" -#define D_PATCH_ISSUE_2186 "Patch issue 2186" -#define D_CONNECTING_TO_AP "Koppel tans aan AP" -#define D_IN_MODE "in mode" -#define D_CONNECT_FAILED_NO_IP_ADDRESS "Kon nie verbind nie omdat geen IP-adres ontvang is nie" -#define D_CONNECT_FAILED_AP_NOT_REACHED "Kon nie verbind nie, aangesien toegang nie bereik kan word nie" -#define D_CONNECT_FAILED_WRONG_PASSWORD "Kon nie verbind nie" -#define D_CONNECT_FAILED_AP_TIMEOUT "Kon nie verbinding maak met AP-time-out nie" -#define D_ATTEMPTING_CONNECTION "Attempting connection..." -#define D_CHECKING_CONNECTION "Probeer tans verbinding ..." -#define D_QUERY_DONE "Navraag gedoen. MQTT-dienste gevind" -#define D_MQTT_SERVICE_FOUND "MQTT-diens gevind op" -#define D_FOUND_AT "gevind op" -#define D_SYSLOG_HOST_NOT_FOUND "Syslog Host nie gevind nie" - -// settings.ino -#define D_SAVED_TO_FLASH_AT "Gestoor in die flash op" -#define D_LOADED_FROM_FLASH_AT "Uit flash gelaai by" -#define D_USE_DEFAULTS "Gebruik standaardinstellings" -#define D_ERASED_SECTOR "Uitgewis sektor" - -// xdrv_02_webserver.ino -#define D_NOSCRIPT "Skakel JavaScript aan om Tasmota te gebruik" -#define D_SAFEBOOT "SAFEBOOT" -#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware
gradeer asseblief op" -#define D_WEBSERVER_ACTIVE_ON "Webbediener aktief op" -#define D_WITH_IP_ADDRESS "met IP-adres" -#define D_WEBSERVER_STOPPED "Webbediener gestop" -#define D_FILE_NOT_FOUND "Lêer nie gevind nie" -#define D_REDIRECTED "Herlei na captive portal" -#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "WiFi manager stel AccessPoint in en hou Station" -#define D_WIFIMANAGER_SET_ACCESSPOINT "WiFi manager het AccessPoint ingestel" -#define D_TRYING_TO_CONNECT "Probeer om toestel aan netwerk te koppel" - -#define D_RESTART_IN "Begin weer binne" -#define D_SECONDS "sekondes" -#define D_DEVICE_WILL_RESTART "Toestel sal binne 'n paar sekondes weer begin" -#define D_BUTTON_TOGGLE "Wissel" -#define D_CONFIGURATION "Konfigurasie" -#define D_INFORMATION "Inligting" -#define D_FIRMWARE_UPGRADE "Firmware-opgradering" -#define D_MANAGEMENT "Tools" -#define D_GPIO_VIEWER "GPIO Viewer" -#define D_CONSOLE "Konsole" -#define D_CONFIRM_RESTART "Bevestig weer te begin" - -#define D_CONFIGURE_MODULE "Module" -#define D_CONFIGURE_WIFI "WiFi" -#define D_CONFIGURE_MQTT "MQTT" -#define D_CONFIGURE_DOMOTICZ "Domoticz" -#define D_CONFIGURE_LOGGING "Logging" -#define D_CONFIGURE_OTHER "Ander" -#define D_CONFIRM_RESET_CONFIGURATION "Bevestig die herstel van die konfigurasie" -#define D_RESET_CONFIGURATION "Stel terug" -#define D_BACKUP_CONFIGURATION "Rugsteun" -#define D_RESTORE_CONFIGURATION "Herstel" -#define D_START_RESTORE "Start restore" -#define D_MAIN_MENU "Hoofkieslys" - -#define D_MODULE_PARAMETERS "Moduleparameters" -#define D_MODULE_TYPE "Module tipe" -#define D_PULLUP_ENABLE "Geen knoppie/skakelaar optrek" -#define D_ADC "ADC" -#define D_GPIO "GPIO" -#define D_SERIAL_IN "Serial in" -#define D_SERIAL_OUT "Serial uit" - -#define D_WIFI_PARAMETERS "WiFi parameters" -#define D_SCAN_FOR_WIFI_NETWORKS "Soek vir WiFi netwerke" -#define D_SCAN_DONE "Skandering gedoen" -#define D_NO_NETWORKS_FOUND "Geen netwerke gevind nie" -#define D_REFRESH_TO_SCAN_AGAIN "Verfris om weer te skandeer" -#define D_DUPLICATE_ACCESSPOINT "Duplikaat AccessPoint" -#define D_SKIPPING_LOW_QUALITY "Slaan oor as gevolg van lae gehalte" -#define D_MODE "Mode" -#define D_RSSI "RSSI" -#define D_WEP "WEP" -#define D_WPA_PSK "WPA PSK" -#define D_WPA2_PSK "WPA2 PSK" -#define D_AP1_SSID "WiFi Network" -#define D_AP1_SSID_HELP "Type or Select your WiFi Network" -#define D_AP2_SSID "WiFi Network 2" -#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" -#define D_AP_PASSWORD "WiFi Wagwoord" -#define D_AP_PASSWORD_HELP "Enter your WiFi Password" -#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" -#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" -#define D_SHOW_MORE_OPTIONS "More Options" -#define D_CHECK_CREDENTIALS "Please, check your credentials" -#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" -#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" -#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" - -#define D_MQTT_PARAMETERS "MQTT-parameters" -#define D_CLIENT "Kliënt" -#define D_FULL_TOPIC "Volledige onderwerp" - -#define D_LOGGING_PARAMETERS "Logging parameters" -#define D_SERIAL_LOG_LEVEL "Serial log level" -#define D_MQTT_LOG_LEVEL "Mqtt log level" -#define D_WEB_LOG_LEVEL "Web log level" -#define D_SYS_LOG_LEVEL "Syslog level" -#define D_MORE_DEBUG "More debug" -#define D_SYSLOG_HOST "Syslog host" -#define D_SYSLOG_PORT "Syslog port" -#define D_TELEMETRY_PERIOD "Telemetry period" - -#define D_OTHER_PARAMETERS "Ander parameters" -#define D_TEMPLATE "Sjabloon" -#define D_ACTIVATE "Aktiveer" -#define D_DEVICE_NAME "Toestel naam" -#define D_WEB_ADMIN_PASSWORD "Webadministrateurwagwoord" -#define D_MQTT_ENABLE "MQTT inskakel" -#define D_MQTT_TLS_ENABLE "MQTT TLS" -#define D_HTTP_API "HTTP API" -#define D_HTTP_API_ENABLE "HTTP API inskakel" -#define D_FRIENDLY_NAME "Vriendelike naam" -#define D_BELKIN_WEMO "Belkin WeMo" -#define D_HUE_BRIDGE "Hue Bridge" -#define D_SINGLE_DEVICE "enkele toestel" -#define D_MULTI_DEVICE "multi toestel" - -#define D_CONFIGURE_TEMPLATE "sjabloon" -#define D_TEMPLATE_PARAMETERS "Sjabloon parameters" -#define D_TEMPLATE_NAME "Naam" -#define D_BASE_TYPE "Gebaseer op" -#define D_TEMPLATE_FLAGS "Opsies" - -#define D_SAVE_CONFIGURATION "Stoor konfigurasie" -#define D_CONFIGURATION_SAVED "Konfigurasie gestoor" -#define D_CONFIGURATION_RESET "Konfigurasie terugstel" - -#define D_PROGRAM_VERSION "Programweergawe" -#define D_BUILD_DATE_AND_TIME "Bou datum en tyd" -#define D_CORE_AND_SDK_VERSION "Core/SDK weergawe" -#define D_HOSTED_MCU "Hosted MCU" -#define D_FLASH_WRITE_COUNT "Flash skryf tel" -#define D_MAC_ADDRESS "MAC adress" -#define D_MQTT_HOST "MQTT gasheer" -#define D_MQTT_PORT "MQTT poort" -#define D_MQTT_CLIENT "MQTT kliënt" -#define D_MQTT_USER "MQTT gebruiker" -#define D_MQTT_TOPIC "MQTT onderwerp" -#define D_MQTT_GROUP_TOPIC "MQTT groeponderwerp" -#define D_MQTT_FULL_TOPIC "MQTT volledige onderwerp" -#define D_MQTT_NO_RETAIN "MQTT geen behoud" -#define D_MDNS_DISCOVERY "mDNS ontdekking" -#define D_MDNS_ADVERTISE "mDNS adverteer" -#define D_ESP_CHIP_ID "ESP Chip Id" -#define D_FLASH_CHIP_ID "Flash Chip Id" -#define D_FLASH_CHIP_SIZE "Flash Size" -#define D_FREE_PROGRAM_SPACE "Vrye program grootte" - -#define D_UPGRADE_BY_WEBSERVER "Per webbediener" -#define D_OTA_URL "OTA Url" -#define D_START_UPGRADE "Begin opgradering" -#define D_UPGRADE_BY_FILE_UPLOAD "Volgens lêeroplaai" -#define D_UPLOAD_FACTORY "Switching to safeboot partition" -#define D_UPLOAD_STARTED "Oplaai begin" -#define D_UPGRADE_STARTED "Opgradering is begin" -#define D_UPLOAD_DONE "Oplaai gedoen" -#define D_UPLOAD_TRANSFER "Laai oordrag op" -#define D_TRANSFER_STARTED "Oordrag is begin" -#define D_UPLOAD_ERR_1 "Geen lêer is gekies nie" -#define D_UPLOAD_ERR_2 "Nie genoeg plek nie" -#define D_UPLOAD_ERR_3 "Ongeldige lêerhandtekening" -#define D_UPLOAD_ERR_4 "Programgrootte is groter as geheue" -#define D_UPLOAD_ERR_5 "Laai buffer verkeerd op" -#define D_UPLOAD_ERR_6 "Kon nie oplaai nie. Aktiveer logging 3" -#define D_UPLOAD_ERR_7 "Oplaai afgebreek" -#define D_UPLOAD_ERR_8 "Lêer ongeldig" -#define D_UPLOAD_ERR_9 "Lêer is te groot" -#define D_UPLOAD_ERR_10 "Kon nie RF-skyfie inisieer nie" -#define D_UPLOAD_ERR_11 "Kon nie RF-skyfie uitvee nie" -#define D_UPLOAD_ERR_12 "Kon nie na RF-skyfie skryf nie" -#define D_UPLOAD_ERR_13 "Kon nie RF-firmware dekodeer nie" -#define D_UPLOAD_ERR_14 "Nie versoenbaar nie" -#define D_UPLOAD_ERROR_CODE "Laai foutkode op" - -#define D_ENTER_COMMAND "Voer die opdrag in" -#define D_ENABLE_WEBLOG_FOR_RESPONSE "Skakel weblog 2 aan as antwoord verwag word" -#define D_NEED_USER_AND_PASSWORD "Benodig user=&password=" - -// xdrv_01_mqtt.ino -#define D_FINGERPRINT "Verifieer TLS-vingerafdruk ..." -#define D_TLS_CONNECT_FAILED_TO "TLS Connect kon nie" -#define D_RETRY_IN "Probeer weer" -#define D_VERIFIED "Geverifieer met behulp van vingerafdruk" -#define D_INSECURE "Onveilige verbinding weens ongeldige vingerafdruk" -#define D_CONNECT_FAILED_TO "Kon nie verbind nie" - -// xplg_wemohue.ino -#define D_MULTICAST_DISABLED "Multicast gedeaktiveer" -#define D_MULTICAST_REJOINED "Multicast (weer) aangesluit" -#define D_MULTICAST_JOIN_FAILED "Multicast aansluiting het misluk" -#define D_FAILED_TO_SEND_RESPONSE "Kon nie antwoord stuur nie" - -#define D_WEMO "WeMo" -#define D_WEMO_BASIC_EVENT "WeMo basiese event" -#define D_WEMO_EVENT_SERVICE "WeMo geleentheids service" -#define D_WEMO_META_SERVICE "WeMo meta service" -#define D_WEMO_SETUP "WeMo opstelling" -#define D_RESPONSE_SENT "Antwoord gestuur" - -#define D_HUE "Hue" -#define D_HUE_BRIDGE_SETUP "Hue opstelling" -#define D_HUE_API_NOT_IMPLEMENTED "Hue API nie geïmplementeer nie" -#define D_HUE_API "Hue API" -#define D_HUE_POST_ARGS "Hue POST args" -#define D_3_RESPONSE_PACKETS_SENT "3 antwoordpakkies gestuur" - -// xdrv_07_domoticz.ino -#define D_DOMOTICZ_PARAMETERS "Domoticz parameters" -#define D_DOMOTICZ_IDX "Idx" -#define D_DOMOTICZ_KEY_IDX "Key idx" -#define D_DOMOTICZ_SWITCH_IDX "Switch idx" -#define D_DOMOTICZ_KEY "Key" -#define D_DOMOTICZ_SWITCH "Switch" -#define D_DOMOTICZ_SENSOR_IDX "Sensor idx" - #define D_DOMOTICZ_TEMP "Temp" - #define D_DOMOTICZ_TEMP_HUM "Temp,Hum" - #define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Hum,Baro" - #define D_DOMOTICZ_POWER_ENERGY "Krag, Energie" - #define D_DOMOTICZ_ILLUMINANCE "Beligting" - #define D_DOMOTICZ_COUNT "Telling/PM1" - #define D_DOMOTICZ_VOLTAGE "Spanning/PM2.5" - #define D_DOMOTICZ_CURRENT "Stroom/PM10" - #define D_DOMOTICZ_AIRQUALITY "Lug kwaliteit" - #define D_DOMOTICZ_P1_SMART_METER "P1SmartMeter" -#define D_DOMOTICZ_UPDATE_TIMER "Dateer tydopdatering op" - -// xdrv_09_timers.ino -#define D_CONFIGURE_TIMER "Timer" -#define D_TIMER_PARAMETERS "Timer-parameters" -#define D_TIMER_ENABLE "Aktiveer timers" -#define D_TIMER_ARM "Aktiveer" -#define D_TIMER_DAYS "Dae" -#define D_TIMER_REPEAT "Herhaal" -#define D_TIMER_OUTPUT "Uitset" -#define D_TIMER_ACTION "Aksie" - -// xdrv_10_knx.ino -#define D_CONFIGURE_KNX "KNX" -#define D_KNX_PARAMETERS "KNX-parameters" -#define D_KNX_GENERAL_CONFIG "Algemene" -#define D_KNX_PHYSICAL_ADDRESS "Fisiese adres" -#define D_KNX_PHYSICAL_ADDRESS_NOTE "( Moet uniek wees in die KNX-netwerk )" -#define D_KNX_ENABLE "Aktiveer KNX" -#define D_KNX_GROUP_ADDRESS_TO_WRITE "Data om na groepadresse te stuur" -#define D_ADD "Voeg by" -#define D_DELETE "Vee uit" -#define D_REPLY "Antwoord" -#define D_KNX_GROUP_ADDRESS_TO_READ "Groepadresse om data van te ontvang" -#define D_RECEIVED_FROM "Ontvang van" -#define D_KNX_COMMAND_WRITE "Skryf" -#define D_KNX_COMMAND_READ "Lees" -#define D_KNX_COMMAND_OTHER "Ander" -#define D_SENT_TO "gestuur na" -#define D_KNX_WARNING "Die groepadres ( 0 / 0 / 0 ) is gereserveer en kan nie gebruik word nie." -#define D_KNX_ENHANCEMENT "Kommunikasieverbetering" -#define D_KNX_TX_SLOT "KNX TX" -#define D_KNX_RX_SLOT "KNX RX" -#define D_KNX_TX_SCENE "KNX SCENE TX" -#define D_KNX_RX_SCENE "KNX SCENE RX" - -// xdrv_23_zigbee -#define D_ZIGBEE_PERMITJOIN_ACTIVE "Toestelle wat toegelaat word om aan te sluit" -#define D_ZIGBEE_MAPPING_TITLE "Tasmota Zigbee-kartering" -#define D_ZIGBEE_NOT_STARTED "Zigbee het nie begin nie" -#define D_ZIGBEE_MAPPING_IN_PROGRESS_SEC "Kartering aan die gang (% d s. Oor)" -#define D_ZIGBEE_MAPPING_NOT_PRESENT "Geen kartering nie" -#define D_ZIGBEE_MAP_REFRESH "Zigbee kartering Refresh" -#define D_ZIGBEE_MAP "Zigbee-kaart" -#define D_ZIGBEE_PERMITJOIN "Zigbee Permit sluit aan" -#define D_ZIGBEE_GENERATE_KEY "genereer ewekansige Zigbee-netwerksleutel" -#define D_ZIGBEE_UNKNOWN_DEVICE "Onbekende toestel" -#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Onbekende kenmerk" -#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint" -#define D_ZIGBEE_INVALID_PARAM "Ongeldige parameter" -#define D_ZIGBEE_MISSING_PARAM "Ontbrekende parameters" -#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Onbekende kenmerknaam (geïgnoreer): %s" -#define D_ZIGBEE_TOO_MANY_CLUSTERS "Nie meer as een groep-ID per opdrag nie" -#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints" -#define D_ZIGBEE_WRONG_DELIMITER "Verkeerde afbakening vir payload" -#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Onherkenbare zigbee-opdrag: %s" -#define D_ZIGBEE_TOO_MANY_COMMANDS "Slegs 1 opdrag toegelaat (%d)" -#define D_ZIGBEE_NO_ATTRIBUTE "Geen kenmerk in die lys nie" -#define D_ZIGBEE_UNSUPPORTED_ATTRIBUTE_TYPE "Nie-ondersteunde kenmerktipe" -#define D_ZIGBEE_JSON_REQUIRED "Config benodig JSON-voorwerpe" -#define D_ZIGBEE_RESET_1_OR_2 "1 of 2 om te herstel" -#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM gevind by adres" -#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Ewekansige Zigbee parameters, kyk asseblief met 'ZbConfig'" - -// xdrv_89_dali.ino -#define D_SENSOR_DALI_RX "Dali RX" -#define D_SENSOR_DALI_TX "Dali TX" -#define D_CONFIGURE_DALI "Config DALI" - -// xdrv_03_energy.ino -#define D_ENERGY_TODAY "Energie Vandag" -#define D_ENERGY_YESTERDAY "Energie Gister" -#define D_ENERGY_TOTAL "Energie Totaal" - +/* + af_AF.h - localization for Afrikaans - Afrikaans for Tasmota + + Copyright (C) 2021 Christiaan Heerze + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifndef _LANGUAGE_AF_AF_H_ +#define _LANGUAGE_AF_AF_H_ + +/*************************** ATTENTION *******************************\ + * + * Due to memory constraints only UTF-8 is supported. + * To save code space keep text as short as possible. + * Time and Date provided by SDK can not be localized (yet). + * Use online command StateText to translate ON, OFF, HOLD and TOGGLE. + * Use online command Prefix to translate cmnd, stat and tele. + * + * Updated until v9.3.1.1 +\*********************************************************************/ + +//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) +// https://www.science.co.il/language/Locale-codes.php +#define LANGUAGE_LCID 1078 +// HTML (ISO 639-1) Language Code +#define D_HTML_LANGUAGE "af" + +// "2017-03-07T11:08:02" - ISO8601:2004 +#define D_YEAR_MONTH_SEPARATOR "-" +#define D_MONTH_DAY_SEPARATOR "-" +#define D_DATE_TIME_SEPARATOR "T" +#define D_HOUR_MINUTE_SEPARATOR ":" +#define D_MINUTE_SECOND_SEPARATOR ":" + +#define D_DAY3LIST "SonMaaDinWoeDonVryDonSat" +#define D_MONTH3LIST "JanFebMaaAprMeiJunJulAugSepOktNovDes" + +// Non JSON decimal separator +#define D_DECIMAL_SEPARATOR "." + +// Common +#define D_ABSOLUTE_HUMIDITY "Abs Humidity" +#define D_ADDRESS "Address" +#define D_ADMIN "Admin" +#define D_AIR_QUALITY "Luggehalte" +#define D_AP "AP" // Access Point +#define D_AS "as" +#define D_AT "at" +#define D_AUTO "AUTO" +#define D_AUTO_UPDATE "Auto Update" +#define D_BATT "Batt" // Short for Battery +#define D_BATTERY "Battery" +#define D_BATTERY_CHARGE "Lading" // Battery charge in % +#define D_BLINK "Flits" +#define D_BLINKOFF "FlitsAf" +#define D_BOOT_COUNT "Opstarttelling" +#define D_BRIGHTLIGHT "Helder" +#define D_BSSID "BSSId" +#define D_BUTTON "Knoppie" +#define D_BY "deur" // Written by me +#define D_BYTES "Bytes" +#define D_CELSIUS "Celsius" +#define D_CHANNEL "Kanaal" +#define D_CO2 "Koolstofdioksied" +#define D_CODE "kode" // Button code +#define D_COLDLIGHT "Koud" +#define D_COLOR "Color" +#define D_COMMAND "Bevel" +#define D_CONNECTED "Gekoppel" +#define D_CORS_DOMAIN "CORS Domain" +#define D_COUNT "Telling" +#define D_COUNTER "Opnemer" +#define D_CT_POWER "CT Power" +#define D_CURRENT "Stroom" // As in Voltage and Current +#define D_CURRENT_NEUTRAL "Current Neutral" +#define D_DARKLIGHT "Donker" +#define D_DATA "Data" +#define D_DEBUG "Ontfout" +#define D_DEWPOINT "Dou punt" +#define D_DISABLED "Gedeaktiveer" +#define D_DISCONNECTED "Disconnected" +#define D_DISTANCE "Afstand" +#define D_DNS_SERVER "DNS" +#define D_DO "Opgeloste suurstof" +#define D_DONE "Klaar" +#define D_DST_TIME "DST" +#define D_EC "EC" +#define D_ECO2 "eCO₂" +#define D_EMULATION "Emulasie" +#define D_ENABLED "Geaktiveer" +#define D_ERASE "Vee uit" +#define D_ERROR "Fout" +#define D_FAHRENHEIT "Fahrenheit" +#define D_FAILED "Misluk " +#define D_FALLBACK "Terugval" +#define D_FALLBACK_TOPIC "Terugval onderwerp" +#define D_FALSE "Onwaar" +#define D_FILE "Lêer" +#define D_FILE_SYSTEM_SIZE "File System Size" +#define D_FLOW_RATE "Vloeitempo" +#define D_FRAGMENTATION "frag." // Lower case abbreviated version of fragmentation used in "memory fragmentation" +#define D_FRAME_RATE "Frame rate" +#define D_FREE_MEMORY "Vrye geheue" +#define D_FREQUENCY "Frekwensie" +#define D_GAS "Gas" +#define D_GATEWAY "Gateway" +#define D_GROUP "Groep" +#define D_HALL_EFFECT "Hall Effect" +#define D_HEATINDEX "Heat index" +#define D_HOST "Gasheer" +#define D_HOSTNAME "Gasheername" +#define D_HUMIDITY "Humiditeit" +#define D_ILLUMINANCE "Verligting" +#define D_IMMEDIATE "onmiddellik" // Button immediate +#define D_INDEX "Indeks" +#define D_INFO "Inligting" +#define D_INFRARED "Infrarooi" +#define D_INITIALIZED "Geïnisialiseer" +#define D_IP_ADDRESS "IP-adresse" +#define D_LIGHT "Lig" +#define D_LQI "LQI" // Zigbee Link Quality Index +#define D_LWT "LWT" +#define D_MODULE "Module" +#define D_MOISTURE "Vog" +#define D_MQ "MQ" +#define D_MQTT "MQTT" +#define D_MULTI_PRESS "multi-press" +#define D_NOISE "Geraas" +#define D_NONE "Geen" +#define D_NOX "NOx" +#define D_O2 "Suurstof" +#define D_OFF "Uit" +#define D_OFFLINE "Vanlyn" +#define D_OK "Ok" +#define D_ON "aan" +#define D_ONLINE "Aanlyn" +#define D_ORP "ORP" +#define D_PARTITION "Partition" // As in flash and firmware partition +#define D_PASSWORD "Wagwoord" +#define D_PH "pH" +#define D_PORT "Poort" +#define D_POWER_FACTOR "Krag faktor" +#define D_POWERUSAGE "Krag" +#define D_POWERUSAGE_ACTIVE "Regte krag" +#define D_POWERUSAGE_ACTIVE_TOTAL "Active Power Total" +#define D_POWERUSAGE_APPARENT "Oënskynlike krag" +#define D_POWERUSAGE_REACTIVE "reaktiewe krag" +#define D_PRESSURE "Druk" +#define D_PRESSUREATSEALEVEL "Druk op seevlak" +#define D_PROGRAM_FLASH_SIZE "Program Flash Grootte" +#define D_PROGRAM_SIZE "Program Grootte" +#define D_PROJECT "Projek" +#define D_PSR_FREE_MEMORY "PS-RAM vrye geheue" +#define D_PSR_MAX_MEMORY "PS-RAM geheue" +#define D_RAIN "Reën" +#define D_RANGE "Gebied" +#define D_RECEIVED "Ontvang" +#define D_RESTART "Herbegin" +#define D_RESTART_REASON "Herlaai rede" +#define D_RESTARTING "Herbegin" +#define D_RETAINED "behou" +#define D_RULE "Reël" +#define D_SAVE "Stoor" +#define D_SENSOR "Sensor" +#define D_SOC "Laai kondisie" +#define D_SOH "Laai vermoeë" +#define D_SSID "SSId" +#define D_START "Begin" +#define D_STD_TIME "STD" +#define D_STOP "Stop" +#define D_SUBNET_MASK "Subnet Masker" +#define D_SUBSCRIBE_TO "Teken in op" +#define D_SUCCESSFUL "Suksesvol" +#define D_SUNRISE "Sonsopkoms" +#define D_SUNSET "Sononder" +#define D_TEMPERATURE "Temperatuur" +#define D_TIME_OF_DAY "Tyd" +#define D_TO "naar" +#define D_TOGGLE "Verwissel" +#define D_TOPIC "Onderwerp" +#define D_TOTAL_USAGE "Totale gebruik" +#define D_TRANSMIT "Stuur" +#define D_TRUE "Waar" +#define D_TVOC "TVOC" +#define D_TWILIGHT_ASTRONOMICAL "Astronomical" +#define D_TWILIGHT_CIVIL "Civil" +#define D_TWILIGHT_NAUTICAL "Nautical" +#define D_UNSUBSCRIBE_FROM "Teken uit van" +#define D_UPLOAD "Laai op" +#define D_UPTIME "Uptyd" +#define D_USED "used" +#define D_USER "Gebruiker" +#define D_UTC_TIME "UTC" +#define D_UV_INDEX "UV Indeks" +#define D_UV_INDEX_1 "Laag" +#define D_UV_INDEX_2 "Middel" +#define D_UV_INDEX_3 "Hoog" +#define D_UV_INDEX_4 "Gevaarlik" +#define D_UV_INDEX_5 "1ste/2de graad sonbrand" +#define D_UV_INDEX_6 "3e graad sonbrand" +#define D_UV_INDEX_7 "Buite bereik" // Out of Range +#define D_UV_LEVEL "UV Level" +#define D_UV_POWER "UV krag" +#define D_VERSION "Weergawe" +#define D_VOC "VOC" +#define D_VOLTAGE "Spanning" +#define D_VOLUME "Volume" +#define D_WARMLIGHT "Warm" +#define D_WATER_DEPTH "Water diepte" +#define D_WEB_SERVER "Webbediener" +#define D_WEIGHT "Gewig" + +// tasmota.ino +#define D_WARNING_MINIMAL_VERSION "WAARSKUWING Hierdie weergawe ondersteun nie aanhoudende instellings nie" +#define D_LEVEL_10 "level 1-0" +#define D_LEVEL_01 "level 0-1" +#define D_SERIAL_LOGGING_DISABLED "Syslog-logging is uitgeskakel" +#define D_SYSLOG_LOGGING_REENABLED "Syslog-logging is weer geaktiveer" + +#define D_SET_BAUDRATE_TO "Stem Baudrate op" +#define D_RECEIVED_TOPIC "Ontvang onderwerp" +#define D_DATA_SIZE "Data grootte" +#define D_ANALOG_INPUT "Analoog" + +// support.ino +#define D_OSWATCH "osWatch" +#define D_BLOCKED_LOOP "Geblokkeerde lus" +#define D_WPS_FAILED_WITH_STATUS "WPSconfig kon nie status kry nie" +#define D_ACTIVE_FOR_3_MINUTES "3 minute aktief" +#define D_FAILED_TO_START "kon nie begin nie" +#define D_PATCH_ISSUE_2186 "Patch issue 2186" +#define D_CONNECTING_TO_AP "Koppel tans aan AP" +#define D_IN_MODE "in mode" +#define D_CONNECT_FAILED_NO_IP_ADDRESS "Kon nie verbind nie omdat geen IP-adres ontvang is nie" +#define D_CONNECT_FAILED_AP_NOT_REACHED "Kon nie verbind nie, aangesien toegang nie bereik kan word nie" +#define D_CONNECT_FAILED_WRONG_PASSWORD "Kon nie verbind nie" +#define D_CONNECT_FAILED_AP_TIMEOUT "Kon nie verbinding maak met AP-time-out nie" +#define D_ATTEMPTING_CONNECTION "Attempting connection..." +#define D_CHECKING_CONNECTION "Probeer tans verbinding ..." +#define D_QUERY_DONE "Navraag gedoen. MQTT-dienste gevind" +#define D_MQTT_SERVICE_FOUND "MQTT-diens gevind op" +#define D_FOUND_AT "gevind op" +#define D_SYSLOG_HOST_NOT_FOUND "Syslog Host nie gevind nie" + +// settings.ino +#define D_SAVED_TO_FLASH_AT "Gestoor in die flash op" +#define D_LOADED_FROM_FLASH_AT "Uit flash gelaai by" +#define D_USE_DEFAULTS "Gebruik standaardinstellings" +#define D_ERASED_SECTOR "Uitgewis sektor" + +// xdrv_02_webserver.ino +#define D_NOSCRIPT "Skakel JavaScript aan om Tasmota te gebruik" +#define D_SAFEBOOT "SAFEBOOT" +#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMAL firmware
gradeer asseblief op" +#define D_WEBSERVER_ACTIVE_ON "Webbediener aktief op" +#define D_WITH_IP_ADDRESS "met IP-adres" +#define D_WEBSERVER_STOPPED "Webbediener gestop" +#define D_FILE_NOT_FOUND "Lêer nie gevind nie" +#define D_REDIRECTED "Herlei na captive portal" +#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "WiFi manager stel AccessPoint in en hou Station" +#define D_WIFIMANAGER_SET_ACCESSPOINT "WiFi manager het AccessPoint ingestel" +#define D_TRYING_TO_CONNECT "Probeer om toestel aan netwerk te koppel" + +#define D_RESTART_IN "Begin weer binne" +#define D_SECONDS "sekondes" +#define D_DEVICE_WILL_RESTART "Toestel sal binne 'n paar sekondes weer begin" +#define D_BUTTON_TOGGLE "Wissel" +#define D_CONFIGURATION "Konfigurasie" +#define D_INFORMATION "Inligting" +#define D_FIRMWARE_UPGRADE "Firmware-opgradering" +#define D_MANAGEMENT "Tools" +#define D_GPIO_VIEWER "GPIO Viewer" +#define D_CONSOLE "Konsole" +#define D_CONFIRM_RESTART "Bevestig weer te begin" + +#define D_CONFIGURE_MODULE "Module" +#define D_CONFIGURE_WIFI "WiFi" +#define D_CONFIGURE_MQTT "MQTT" +#define D_CONFIGURE_DOMOTICZ "Domoticz" +#define D_CONFIGURE_LOGGING "Logging" +#define D_CONFIGURE_OTHER "Ander" +#define D_CONFIRM_RESET_CONFIGURATION "Bevestig die herstel van die konfigurasie" +#define D_RESET_CONFIGURATION "Stel terug" +#define D_BACKUP_CONFIGURATION "Rugsteun" +#define D_RESTORE_CONFIGURATION "Herstel" +#define D_START_RESTORE "Start restore" +#define D_MAIN_MENU "Hoofkieslys" + +#define D_MODULE_PARAMETERS "Moduleparameters" +#define D_MODULE_TYPE "Module tipe" +#define D_PULLUP_ENABLE "Geen knoppie/skakelaar optrek" +#define D_ADC "ADC" +#define D_GPIO "GPIO" +#define D_SERIAL_IN "Serial in" +#define D_SERIAL_OUT "Serial uit" + +#define D_WIFI_PARAMETERS "WiFi parameters" +#define D_SCAN_FOR_WIFI_NETWORKS "Soek vir WiFi netwerke" +#define D_SCAN_DONE "Skandering gedoen" +#define D_NO_NETWORKS_FOUND "Geen netwerke gevind nie" +#define D_REFRESH_TO_SCAN_AGAIN "Verfris om weer te skandeer" +#define D_DUPLICATE_ACCESSPOINT "Duplikaat AccessPoint" +#define D_SKIPPING_LOW_QUALITY "Slaan oor as gevolg van lae gehalte" +#define D_MODE "Mode" +#define D_RSSI "RSSI" +#define D_WEP "WEP" +#define D_WPA_PSK "WPA PSK" +#define D_WPA2_PSK "WPA2 PSK" +#define D_AP1_SSID "WiFi Network" +#define D_AP1_SSID_HELP "Type or Select your WiFi Network" +#define D_AP2_SSID "WiFi Network 2" +#define D_AP2_SSID_HELP "Type your Alternative WiFi Network" +#define D_AP_PASSWORD "WiFi Wagwoord" +#define D_AP_PASSWORD_HELP "Enter your WiFi Password" +#define D_SELECT_YOUR_WIFI_NETWORK "Select your WiFi Network" +#define D_SHOW_MORE_WIFI_NETWORKS "Scan for all WiFi Networks" +#define D_SHOW_MORE_OPTIONS "More Options" +#define D_CHECK_CREDENTIALS "Please, check your credentials" +#define D_SUCCESSFUL_WIFI_CONNECTION "Successful WiFi Connection" +#define D_NOW_YOU_CAN_CLOSE_THIS_WINDOW "Now you can close this window" +#define D_REDIRECTING_TO_NEW_IP "Redirecting to new device's IP address" + +#define D_MQTT_PARAMETERS "MQTT-parameters" +#define D_CLIENT "Kliënt" +#define D_FULL_TOPIC "Volledige onderwerp" + +#define D_LOGGING_PARAMETERS "Logging parameters" +#define D_SERIAL_LOG_LEVEL "Serial log level" +#define D_MQTT_LOG_LEVEL "Mqtt log level" +#define D_WEB_LOG_LEVEL "Web log level" +#define D_SYS_LOG_LEVEL "Syslog level" +#define D_MORE_DEBUG "More debug" +#define D_SYSLOG_HOST "Syslog host" +#define D_SYSLOG_PORT "Syslog port" +#define D_TELEMETRY_PERIOD "Telemetry period" + +#define D_OTHER_PARAMETERS "Ander parameters" +#define D_TEMPLATE "Sjabloon" +#define D_ACTIVATE "Aktiveer" +#define D_DEVICE_NAME "Toestel naam" +#define D_WEB_ADMIN_PASSWORD "Webadministrateurwagwoord" +#define D_MQTT_ENABLE "MQTT inskakel" +#define D_MQTT_TLS_ENABLE "MQTT TLS" +#define D_HTTP_API "HTTP API" +#define D_HTTP_API_ENABLE "HTTP API inskakel" +#define D_FRIENDLY_NAME "Vriendelike naam" +#define D_BELKIN_WEMO "Belkin WeMo" +#define D_HUE_BRIDGE "Hue Bridge" +#define D_SINGLE_DEVICE "enkele toestel" +#define D_MULTI_DEVICE "multi toestel" + +#define D_CONFIGURE_TEMPLATE "sjabloon" +#define D_TEMPLATE_PARAMETERS "Sjabloon parameters" +#define D_TEMPLATE_NAME "Naam" +#define D_BASE_TYPE "Gebaseer op" +#define D_TEMPLATE_FLAGS "Opsies" + +#define D_SAVE_CONFIGURATION "Stoor konfigurasie" +#define D_CONFIGURATION_SAVED "Konfigurasie gestoor" +#define D_CONFIGURATION_RESET "Konfigurasie terugstel" + +#define D_PROGRAM_VERSION "Programweergawe" +#define D_BUILD_DATE_AND_TIME "Bou datum en tyd" +#define D_CORE_AND_SDK_VERSION "Core/SDK weergawe" +#define D_HOSTED_MCU "Hosted MCU" +#define D_FLASH_WRITE_COUNT "Flash skryf tel" +#define D_MAC_ADDRESS "MAC adress" +#define D_MQTT_HOST "MQTT gasheer" +#define D_MQTT_PORT "MQTT poort" +#define D_MQTT_CLIENT "MQTT kliënt" +#define D_MQTT_USER "MQTT gebruiker" +#define D_MQTT_TOPIC "MQTT onderwerp" +#define D_MQTT_GROUP_TOPIC "MQTT groeponderwerp" +#define D_MQTT_FULL_TOPIC "MQTT volledige onderwerp" +#define D_MQTT_NO_RETAIN "MQTT geen behoud" +#define D_MDNS_DISCOVERY "mDNS ontdekking" +#define D_MDNS_ADVERTISE "mDNS adverteer" +#define D_ESP_CHIP_ID "ESP Chip Id" +#define D_FLASH_CHIP_ID "Flash Chip Id" +#define D_FLASH_CHIP_SIZE "Flash Size" +#define D_FREE_PROGRAM_SPACE "Vrye program grootte" + +#define D_UPGRADE_BY_WEBSERVER "Per webbediener" +#define D_OTA_URL "OTA Url" +#define D_START_UPGRADE "Begin opgradering" +#define D_UPGRADE_BY_FILE_UPLOAD "Volgens lêeroplaai" +#define D_UPLOAD_FACTORY "Switching to safeboot partition" +#define D_UPLOAD_STARTED "Oplaai begin" +#define D_UPGRADE_STARTED "Opgradering is begin" +#define D_UPLOAD_DONE "Oplaai gedoen" +#define D_UPLOAD_TRANSFER "Laai oordrag op" +#define D_TRANSFER_STARTED "Oordrag is begin" +#define D_UPLOAD_ERR_1 "Geen lêer is gekies nie" +#define D_UPLOAD_ERR_2 "Nie genoeg plek nie" +#define D_UPLOAD_ERR_3 "Ongeldige lêerhandtekening" +#define D_UPLOAD_ERR_4 "Programgrootte is groter as geheue" +#define D_UPLOAD_ERR_5 "Laai buffer verkeerd op" +#define D_UPLOAD_ERR_6 "Kon nie oplaai nie. Aktiveer logging 3" +#define D_UPLOAD_ERR_7 "Oplaai afgebreek" +#define D_UPLOAD_ERR_8 "Lêer ongeldig" +#define D_UPLOAD_ERR_9 "Lêer is te groot" +#define D_UPLOAD_ERR_10 "Kon nie RF-skyfie inisieer nie" +#define D_UPLOAD_ERR_11 "Kon nie RF-skyfie uitvee nie" +#define D_UPLOAD_ERR_12 "Kon nie na RF-skyfie skryf nie" +#define D_UPLOAD_ERR_13 "Kon nie RF-firmware dekodeer nie" +#define D_UPLOAD_ERR_14 "Nie versoenbaar nie" +#define D_UPLOAD_ERROR_CODE "Laai foutkode op" + +#define D_ENTER_COMMAND "Voer die opdrag in" +#define D_ENABLE_WEBLOG_FOR_RESPONSE "Skakel weblog 2 aan as antwoord verwag word" +#define D_NEED_USER_AND_PASSWORD "Benodig user=&password=" + +// xdrv_01_mqtt.ino +#define D_FINGERPRINT "Verifieer TLS-vingerafdruk ..." +#define D_TLS_CONNECT_FAILED_TO "TLS Connect kon nie" +#define D_RETRY_IN "Probeer weer" +#define D_VERIFIED "Geverifieer met behulp van vingerafdruk" +#define D_INSECURE "Onveilige verbinding weens ongeldige vingerafdruk" +#define D_CONNECT_FAILED_TO "Kon nie verbind nie" + +// xplg_wemohue.ino +#define D_MULTICAST_DISABLED "Multicast gedeaktiveer" +#define D_MULTICAST_REJOINED "Multicast (weer) aangesluit" +#define D_MULTICAST_JOIN_FAILED "Multicast aansluiting het misluk" +#define D_FAILED_TO_SEND_RESPONSE "Kon nie antwoord stuur nie" + +#define D_WEMO "WeMo" +#define D_WEMO_BASIC_EVENT "WeMo basiese event" +#define D_WEMO_EVENT_SERVICE "WeMo geleentheids service" +#define D_WEMO_META_SERVICE "WeMo meta service" +#define D_WEMO_SETUP "WeMo opstelling" +#define D_RESPONSE_SENT "Antwoord gestuur" + +#define D_HUE "Hue" +#define D_HUE_BRIDGE_SETUP "Hue opstelling" +#define D_HUE_API_NOT_IMPLEMENTED "Hue API nie geïmplementeer nie" +#define D_HUE_API "Hue API" +#define D_HUE_POST_ARGS "Hue POST args" +#define D_3_RESPONSE_PACKETS_SENT "3 antwoordpakkies gestuur" + +// xdrv_07_domoticz.ino +#define D_DOMOTICZ_PARAMETERS "Domoticz parameters" +#define D_DOMOTICZ_IDX "Idx" +#define D_DOMOTICZ_KEY_IDX "Key idx" +#define D_DOMOTICZ_SWITCH_IDX "Switch idx" +#define D_DOMOTICZ_KEY "Key" +#define D_DOMOTICZ_SWITCH "Switch" +#define D_DOMOTICZ_SENSOR_IDX "Sensor idx" + #define D_DOMOTICZ_TEMP "Temp" + #define D_DOMOTICZ_TEMP_HUM "Temp,Hum" + #define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Hum,Baro" + #define D_DOMOTICZ_POWER_ENERGY "Krag, Energie" + #define D_DOMOTICZ_ILLUMINANCE "Beligting" + #define D_DOMOTICZ_COUNT "Telling/PM1" + #define D_DOMOTICZ_VOLTAGE "Spanning/PM2.5" + #define D_DOMOTICZ_CURRENT "Stroom/PM10" + #define D_DOMOTICZ_AIRQUALITY "Lug kwaliteit" + #define D_DOMOTICZ_P1_SMART_METER "P1SmartMeter" +#define D_DOMOTICZ_UPDATE_TIMER "Dateer tydopdatering op" + +// xdrv_09_timers.ino +#define D_CONFIGURE_TIMER "Timer" +#define D_TIMER_PARAMETERS "Timer-parameters" +#define D_TIMER_ENABLE "Aktiveer timers" +#define D_TIMER_ARM "Aktiveer" +#define D_TIMER_DAYS "Dae" +#define D_TIMER_REPEAT "Herhaal" +#define D_TIMER_OUTPUT "Uitset" +#define D_TIMER_ACTION "Aksie" + +// xdrv_10_knx.ino +#define D_CONFIGURE_KNX "KNX" +#define D_KNX_PARAMETERS "KNX-parameters" +#define D_KNX_GENERAL_CONFIG "Algemene" +#define D_KNX_PHYSICAL_ADDRESS "Fisiese adres" +#define D_KNX_PHYSICAL_ADDRESS_NOTE "( Moet uniek wees in die KNX-netwerk )" +#define D_KNX_ENABLE "Aktiveer KNX" +#define D_KNX_GROUP_ADDRESS_TO_WRITE "Data om na groepadresse te stuur" +#define D_ADD "Voeg by" +#define D_DELETE "Vee uit" +#define D_REPLY "Antwoord" +#define D_KNX_GROUP_ADDRESS_TO_READ "Groepadresse om data van te ontvang" +#define D_RECEIVED_FROM "Ontvang van" +#define D_KNX_COMMAND_WRITE "Skryf" +#define D_KNX_COMMAND_READ "Lees" +#define D_KNX_COMMAND_OTHER "Ander" +#define D_SENT_TO "gestuur na" +#define D_KNX_WARNING "Die groepadres ( 0 / 0 / 0 ) is gereserveer en kan nie gebruik word nie." +#define D_KNX_ENHANCEMENT "Kommunikasieverbetering" +#define D_KNX_TX_SLOT "KNX TX" +#define D_KNX_RX_SLOT "KNX RX" +#define D_KNX_TX_SCENE "KNX SCENE TX" +#define D_KNX_RX_SCENE "KNX SCENE RX" + +// xdrv_23_zigbee +#define D_ZIGBEE_PERMITJOIN_ACTIVE "Toestelle wat toegelaat word om aan te sluit" +#define D_ZIGBEE_MAPPING_TITLE "Tasmota Zigbee-kartering" +#define D_ZIGBEE_NOT_STARTED "Zigbee het nie begin nie" +#define D_ZIGBEE_MAPPING_IN_PROGRESS_SEC "Kartering aan die gang (% d s. Oor)" +#define D_ZIGBEE_MAPPING_NOT_PRESENT "Geen kartering nie" +#define D_ZIGBEE_MAP_REFRESH "Zigbee kartering Refresh" +#define D_ZIGBEE_MAP "Zigbee-kaart" +#define D_ZIGBEE_PERMITJOIN "Zigbee Permit sluit aan" +#define D_ZIGBEE_GENERATE_KEY "genereer ewekansige Zigbee-netwerksleutel" +#define D_ZIGBEE_UNKNOWN_DEVICE "Onbekende toestel" +#define D_ZIGBEE_UNKNOWN_ATTRIBUTE "Onbekende kenmerk" +#define D_ZIGBEE_UNKNOWN_ENDPOINT "Unknown endpoint" +#define D_ZIGBEE_INVALID_PARAM "Ongeldige parameter" +#define D_ZIGBEE_MISSING_PARAM "Ontbrekende parameters" +#define D_ZIGBEE_UNKNWON_ATTRIBUTE "Onbekende kenmerknaam (geïgnoreer): %s" +#define D_ZIGBEE_TOO_MANY_CLUSTERS "Nie meer as een groep-ID per opdrag nie" +#define D_ZIGBEE_CONFLICTING_ENDPOINTS "Conflicting destination endpoints" +#define D_ZIGBEE_WRONG_DELIMITER "Verkeerde afbakening vir payload" +#define D_ZIGBEE_UNRECOGNIZED_COMMAND "Onherkenbare zigbee-opdrag: %s" +#define D_ZIGBEE_TOO_MANY_COMMANDS "Slegs 1 opdrag toegelaat (%d)" +#define D_ZIGBEE_NO_ATTRIBUTE "Geen kenmerk in die lys nie" +#define D_ZIGBEE_UNSUPPORTED_ATTRIBUTE_TYPE "Nie-ondersteunde kenmerktipe" +#define D_ZIGBEE_JSON_REQUIRED "Config benodig JSON-voorwerpe" +#define D_ZIGBEE_RESET_1_OR_2 "1 of 2 om te herstel" +#define D_ZIGBEE_EEPROM_FOUND_AT_ADDRESS "ZBBridge EEPROM gevind by adres" +#define D_ZIGBEE_RANDOMIZING_ZBCONFIG "Ewekansige Zigbee parameters, kyk asseblief met 'ZbConfig'" + +// xdrv_89_dali.ino +#define D_SENSOR_DALI_RX "Dali RX" +#define D_SENSOR_DALI_TX "Dali TX" +#define D_CONFIGURE_DALI "Config DALI" + +// xdrv_03_energy.ino +#define D_ENERGY_TODAY "Energie Vandag" +#define D_ENERGY_YESTERDAY "Energie Gister" +#define D_ENERGY_TOTAL "Energie Totaal" + // xdrv_92_vid6608.ino #define D_VID6608_F "VID6608 F" #define D_VID6608_CW "VID6608 CW" -// xsns_100_ina3221.ino -#define D_UNIT_CHARGE "Ah" -#define D_CHARGE "Charge" -#define D_ENERGY "Energy" - -// xdrv_27_shutter.ino -#define D_OPEN "Maak oop" -#define D_CLOSE "Maak toe" -#define D_DOMOTICZ_SHUTTER "Luik" - -// xdrv_28_pcf8574.ino -#define D_CONFIGURE_PCF8574 "PCF8574" -#define D_PCF8574_PARAMETERS "PCF8574 parameters" -#define D_INVERT_PORTS "Keer poorte om" -#define D_DEVICE "Toestel" -#define D_DEVICE_INPUT "Invoer" -#define D_DEVICE_OUTPUT "Uitvoer" - -// xdrv_39_thermostat.ino, xdrv_85_esp32_ble_eq3_trv.ino -#define D_THERMOSTAT "Thermostat" -#define D_THERMOSTAT_SET_POINT "Set Point Temperature" -#define D_THERMOSTAT_SENSOR "Current Temperature" -#define D_THERMOSTAT_GRADIENT "Gradient Temperature" -#define D_THERMOSTAT_DUTY_CYCLE "Duty cycle" -#define D_THERMOSTAT_VALVE_POSITION "Valve Position" -#define D_THERMOSTAT_CYCLE_TIME "Cycle time" -#define D_THERMOSTAT_PI_AUTOTUNE "PI Auto tuning" -#define D_THERMOSTAT_CONTROL_METHOD "Control method" -#define D_THERMOSTAT_RAMP_UP "Ramp up" -#define D_THERMOSTAT_PI "PI" -#define D_THERMOSTAT_AUTOTUNE "Autotune" -#define D_THERMOSTAT_RAMP_UP_HYBRID "Ramp up (Hybrid)" -#define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" -#define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" - -// xdrv_79_esp32_ble.ino -#define D_CONFIGURE_BLE "BLE" -#define D_BLE_PARAMETERS "Bluetooth Settings" -#define D_BLE_ENABLE "Enable Bluetooth" -#define D_BLE_ACTIVESCAN "Enable Active Scan(*)" -#define D_BLE_DEVICES "Devices Seen" -#define D_BLE_REMARK "items marked (*) are not stored in config" - -// xsns_05_ds18b20.ino -#define D_SENSOR_BUSY "Sensor besig" -#define D_SENSOR_CRC_ERROR "Sensor CRC fout" -#define D_SENSORS_FOUND "Sensors gevind" - -// xsns_06_dht.ino -#define D_TIMEOUT_WAITING_FOR "Tyduitstyd wag vir" -#define D_START_SIGNAL_LOW "begin sein laag" -#define D_START_SIGNAL_HIGH "begin sein hoog" -#define D_PULSE "pols" -#define D_CHECKSUM_FAILURE "Checksum het misluk" - -// xsns_07_sht1x.ino -#define D_SENSOR_DID_NOT_ACK_COMMAND "Sensor het nie ACK opdrag" -#define D_SHT1X_FOUND "SHT1X gevind" - -// xsns_18_pms5003.ino -#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter -#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter -#define D_PARTICALS_BEYOND "Deeltjies" - -// xsns_27_apds9960.ino -#define D_GESTURE "Gebaar" -#define D_COLOR_RED "Rooi" -#define D_COLOR_GREEN "Groen" -#define D_COLOR_BLUE "Blou" -#define D_CCT "CCT" -#define D_PROXIMITY "Nabyheid" - -// xsns_32_mpu6050.ino -#define D_AX_AXIS "Accel. X-Axis" -#define D_AY_AXIS "Accel. Y-Axis" -#define D_AZ_AXIS "Accel. Z-Axis" -#define D_GX_AXIS "Gyro X-Axis" -#define D_GY_AXIS "Gyro Y-Axis" -#define D_GZ_AXIS "Gyro Z-Axis" - -// xsns_33_QMC5883L.ino -#define D_MX "Induction X-Axis" -#define D_MY "Induction Y-Axis" -#define D_MZ "Induction Z-Axis" -#define D_MAGNETICFLD "Magnetic Induction" - -// xsns_34_hx711.ino -#define D_HX_CAL_REMOVE "Verwyder gewig" -#define D_HX_CAL_REFERENCE "Laai verwysingsgewig" -#define D_HX_CAL_DONE "Gekalibreer" -#define D_HX_CAL_FAIL "Kon nie kalibreer nie" -#define D_RESET_HX711 "Stel die skaal terug" -#define D_CONFIGURE_HX711 "skaal" -#define D_HX711_PARAMETERS "Skaal parameters" -#define D_ITEM_WEIGHT "Gewig van die item" -#define D_REFERENCE_WEIGHT "Verwysingsgewig" -#define D_CALIBRATE "Kalibreer" -#define D_CALIBRATION "Kalibrasie" - -//xsns_35_tx20.ino -#define D_TX20_WIND_DIRECTION "Windrigting" -#define D_TX20_WIND_SPEED "Wind spoed" -#define D_TX20_WIND_SPEED_MIN "Wind spoed Min" -#define D_TX20_WIND_SPEED_MAX "Wind spoed Max" -#define D_TX20_NORTH "N" -#define D_TX20_EAST "O" -#define D_TX20_SOUTH "S" -#define D_TX20_WEST "W" - -// xsns_53_sml.ino -#define D_TPWRIN "Totaal-In" -#define D_TPWRIN0 "Totaal-In T0" -#define D_TPWRIN1 "Totaal-In T1" -#define D_TPWROUT "Totaal-Uit" -#define D_TPWRCURR "Stroom-In/Uit" -#define D_TPWRCURR1 "Stroom-In p1" -#define D_TPWRCURR2 "Stroom-In p2" -#define D_TPWRCURR3 "Stroom-In p3" -#define D_Strom_L1 "Stroom L1" -#define D_Strom_L2 "Stroom L2" -#define D_Strom_L3 "Stroom L3" -#define D_Spannung_L1 "Spanning L1" -#define D_Spannung_L2 "Spanning L2" -#define D_Spannung_L3 "Spanning L3" -#define D_METERNR "Meter nommmer" -#define D_METERSID "Service ID" -#define D_GasIN "Teller" // Gas-Verbrauch -#define D_H2oIN "Teller" // H2o-Verbrauch -#define D_StL1L2L3 "Stroom L1+L2+L3" -#define D_SpL1L2L3 "Spanning L1+L2+L3/3" - -// xsns_86_tfminiplus.ino -#define D_SIGNALSTRENGTH "Signal Strength" -#define D_CHIPTEMPERATURE "Chip Temperature" - -// xsns_60_GPS -#define D_LATITUDE "Latitude" -#define D_LONGITUDE "Longitude" -#define D_HORIZONTAL_ACCURACY "Horizontal Accuracy" -#define D_ALTITUDE "Altitude" -#define D_VERTICAL_ACCURACY "Vertical Accuracy" -#define D_SPEED "Speed" -#define D_SPEED_ACCURACY "Speed Accuracy" -#define D_HEADING "Heading" -#define D_HEADING_ACCURACY "Heading Accuracy" -#define D_SAT_FIX "Satellite Fix" - #define D_SAT_FIX_NO_FIX "None" - #define D_SAT_FIX_DEAD_RECK "Dead reckoning" - #define D_SAT_FIX_2D "2D" - #define D_SAT_FIX_3D "3D" - #define D_SAT_FIX_GPS_DEAD "GPS and dead reckoning" - #define D_SAT_FIX_TIME "Time only fix" - -// tasmota_template.h - keep them as short as possible to be able to fit them in GUI drop down box -#define D_SENSOR_NONE "Geen" -#define D_SENSOR_USER "Gebruiker" -#define D_SENSOR_OPTION "Opsie" -#define D_SENSOR_DHT11 "DHT11" -#define D_SENSOR_AM2301 "AM2301" -#define D_SENSOR_SI7021 "SI7021" -#define D_SENSOR_MS01 "MS01" -#define D_SENSOR_DS18X20 "DS18x20" -#define D_SENSOR_I2C_SCL "I2C SCL" -#define D_SENSOR_I2C_SDA "I2C SDA" -#define D_SENSOR_I2C_SER_TX "I2C Ser TX" -#define D_SENSOR_I2C_SER_RX "I2C Ser RX" -#define D_SENSOR_I2S_MCLK "I2S MCLK" -#define D_SENSOR_I2S_BCLK "I2S BCLK" -#define D_SENSOR_I2S_WS_IN "I2S BCLK IN" -#define D_SENSOR_I2S_WS "I2S WS" -#define D_SENSOR_I2S_BCLK_IN "I2S WS IN" -#define D_SENSOR_I2S_DIN "I2S DIN" -#define D_SENSOR_I2S_DOUT "I2S DOUT" -#define D_SENSOR_I2S_DAC "I2S DAC" -#define D_SENSOR_HDMI_CEC "HDMI CEC" -#define D_SENSOR_WS2812 "WS2812" -#define D_SENSOR_DFR562 "MP3 Speler" -#define D_SENSOR_DFR562_BUSY "MP3 Bezet" -#define D_SENSOR_IRSEND "IRstuurder" -#define D_SENSOR_SWITCH "SKakelaar" // Suffix "1" -#define D_SENSOR_BUTTON "Knoppie" // Suffix "1" -#define D_SENSOR_RELAY "Relais" // Suffix "1i" -#define D_SENSOR_LED "Led" // Suffix "1i" -#define D_SENSOR_LED_LINK "LedLink" // Suffix "i" -#define D_SENSOR_PWM "PWM" // Suffix "1" -#define D_SENSOR_COUNTER "Teller" // Suffix "1" -#define D_SENSOR_INTERRUPT "Interrupt" -#define D_SENSOR_INPUT "Input" -#define D_SENSOR_IRRECV "IRontvanger" -#define D_SENSOR_MHZ_RX "MHZ Rx" -#define D_SENSOR_MHZ_TX "MHZ Tx" -#define D_SENSOR_HC8_RX "HC8 Rx" -#define D_SENSOR_PZEM004_RX "PZEM004 Rx" -#define D_SENSOR_PZEM016_RX "PZEM016 Rx" -#define D_SENSOR_PZEM017_RX "PZEM017 Rx" -#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" -#define D_SENSOR_SAIR_RX "SAir Rx" -#define D_SENSOR_SAIR_TX "SAir Tx" -#define D_SENSOR_SPI_CS "SPI CS" -#define D_SENSOR_SPI_DC "SPI DC" -#define D_SENSOR_SPI_MISO "SPI MISO" -#define D_SENSOR_SPI_MOSI "SPI MOSI" -#define D_SENSOR_SPI_CLK "SPI CLK" -#define D_SENSOR_SDIO_CMD "SDIO CMD" -#define D_GPIO_TS_SPI_CS "TS SPI CS" -#define D_GPIO_TS_RST "TS RST" -#define D_GPIO_TS_IRQ "TS IRQ" -#define D_SENSOR_SDIO_CMD "SDIO CMD" -#define D_SENSOR_SDIO_CLK "SDIO CLK" -#define D_SENSOR_SDIO_D0 "SDIO D0" -#define D_SENSOR_SDIO_D1 "SDIO D1" -#define D_SENSOR_SDIO_D2 "SDIO D2" -#define D_SENSOR_SDIO_D3 "SDIO D3" -#define D_SENSOR_HSDIO_CMD "HSDIO CMD" -#define D_SENSOR_HSDIO_CLK "HSDIO CLK" -#define D_SENSOR_HSDIO_RST "HSDIO RST" -#define D_SENSOR_HSDIO_D0 "HSDIO D0" -#define D_SENSOR_HSDIO_D1 "HSDIO D1" -#define D_SENSOR_HSDIO_D2 "HSDIO D2" -#define D_SENSOR_HSDIO_D3 "HSDIO D3" -#define D_SENSOR_BACKLIGHT "Backlight" -#define D_SENSOR_PMS5003_TX "PMS5003 Tx" -#define D_SENSOR_PMS5003_RX "PMS5003 Rx" -#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" -#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" -#define D_SENSOR_HPMA_RX "HPMA Rx" -#define D_SENSOR_HPMA_TX "HPMA Tx" -#define D_SENSOR_SBR_RX "SerBr Rx" -#define D_SENSOR_SBR_TX "SerBr Tx" -#define D_SENSOR_MBR_TX "ModBr Tx" -#define D_SENSOR_MBR_RX "ModBr Rx" -#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" -#define D_SENSOR_SR04_TRIG "SR04 Tri/TX" -#define D_SENSOR_SR04_ECHO "SR04 Ech/RX" -#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" -#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" -#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" -#define D_SENSOR_SDM72_TX "SDM72 Tx" -#define D_SENSOR_SDM72_RX "SDM72 Rx" -#define D_SENSOR_SDM120_TX "SDMx20 Tx" -#define D_SENSOR_SDM120_RX "SDMx20 Rx" -#define D_SENSOR_SDM230_TX "SDM230 Tx" -#define D_SENSOR_SDM230_RX "SDM230 Rx" -#define D_SENSOR_SDM630_TX "SDM630 Tx" -#define D_SENSOR_SDM630_RX "SDM630 Rx" -#define D_SENSOR_WE517_TX "WE517 Tx" -#define D_SENSOR_WE517_RX "WE517 Rx" -#define D_SENSOR_LD2402_TX "LD2402 Tx" -#define D_SENSOR_LD2402_RX "LD2402 Rx" -#define D_SENSOR_LD2410_TX "LD2410 Tx" -#define D_SENSOR_LD2410_RX "LD2410 Rx" -#define D_SENSOR_LD2410S_TX "LD2410S Tx" -#define D_SENSOR_LD2410S_RX "LD2410S Rx" -#define D_GPIO_TM1621_CS "TM1621 CS" -#define D_GPIO_TM1621_WR "TM1621 WR" -#define D_GPIO_TM1621_RD "TM1621 RD" -#define D_GPIO_TM1621_DAT "TM1621 DAT" -#define D_SENSOR_TM1637_CLK "TM1637 CLK" -#define D_SENSOR_TM1637_DIO "TM1637 DIO" -#define D_SENSOR_TM1638_CLK "TM1638 CLK" -#define D_SENSOR_TM1638_DIO "TM1638 DIO" -#define D_SENSOR_TM1638_STB "TM1638 STB" -#define D_SENSOR_TM1640_CLK "TM1640 CLK" -#define D_SENSOR_TM1640_DIN "TM1640 DIN" -#define D_SENSOR_MAX7219_DIN "MAX7219 DIN" -#define D_SENSOR_MAX7219_CS "MAX7219 CS" -#define D_SENSOR_MAX7219_CLK "MAX7219 CLK" -#define D_SENSOR_HX711_SCK "HX711 SCK" -#define D_SENSOR_HX711_DAT "HX711 DAT" -#define D_SENSOR_FTC532 "FTC532" -#define D_SENSOR_BS814_CLK "BS814 CLK" -#define D_SENSOR_BS814_DAT "BS814 DAT" -#define D_SENSOR_TX2X_TX "TX2x" -#define D_SENSOR_RFSEND "RFstuurder" -#define D_SENSOR_RFRECV "RFontvanger" -#define D_SENSOR_TUYA_TX "Tuya Tx" -#define D_SENSOR_TUYA_RX "Tuya Rx" -#define D_SENSOR_MGC3130_XFER "MGC3130 Xfr" -#define D_SENSOR_MGC3130_RESET "MGC3130 Rst" -#define D_SENSOR_SSPI_MISO "SSPI MISO" -#define D_SENSOR_SSPI_MOSI "SSPI MOSI" -#define D_SENSOR_SSPI_SCLK "SSPI SCLK" -#define D_SENSOR_SSPI_CS "SSPI CS" -#define D_SENSOR_SSPI_DC "SSPI DC" -#define D_SENSOR_RF_SENSOR "RF Sensor" -#define D_SENSOR_AZ_RX "AZ Rx" -#define D_SENSOR_AZ_TX "AZ Tx" -#define D_SENSOR_MAX31855_CS "MX31855 CS" -#define D_SENSOR_MAX31855_CLK "MX31855 CLK" -#define D_SENSOR_MAX31855_DO "MX31855 DO" -#define D_SENSOR_MAX31865_CS "MX31865 CS" -#define D_GPIO_RN2XX3_TX "RN2XX3 Tx" -#define D_GPIO_RN2XX3_RX "RN2XX3 Rx" -#define D_GPIO_RN2XX3_RST "RN2XX3 Rst" -#define D_GPIO_ASR650X_TX "ASR650x Tx" -#define D_GPIO_ASR650X_RX "ASR650x Rx" -#define D_GPIO_LORA_CS "LoRa CS" -#define D_GPIO_LORA_RST "LoRa Rst" -#define D_GPIO_LORA_BUSY "LoRa Busy" -#define D_GPIO_LORA_DI "LoRa DIO" // Suffix "0","1","2" -#define D_SENSOR_NRG_SEL "HLWBL SEL" // Suffix "i" -#define D_SENSOR_NRG_CF1 "HLWBL CF1" -#define D_SENSOR_HLW_CF "HLW8012 CF" -#define D_SENSOR_HJL_CF "BL0937 CF" -#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx" -#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx" -#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" -#define D_SENSOR_CSE7761_TX "CSE7761 Tx" -#define D_SENSOR_CSE7761_RX "CSE7761 Rx" -#define D_SENSOR_CSE7766_TX "CSE7766 Tx" -#define D_SENSOR_CSE7766_RX "CSE7766 Rx" -#define D_SENSOR_BL0906_RX "BL0906 Rx" -#define D_SENSOR_BL0939_RX "BL0939 Rx" -#define D_SENSOR_BL0942_RX "BL0942 Rx" -#define D_SENSOR_HM330X_SET "HM330X SET" -#define D_SENSOR_PN532_TX "PN532 Tx" -#define D_SENSOR_PN532_RX "PN532 Rx" -#define D_SENSOR_SM16716_CLK "SM16716 CLK" -#define D_SENSOR_SM16716_DAT "SM16716 DAT" -#define D_SENSOR_SM16716_POWER "SM16716 PWR" -#define D_SENSOR_P9813_CLK "P9813 Clk" -#define D_SENSOR_P9813_DAT "P9813 Dat" -#define D_SENSOR_MY92X1_DI "MY92x1 DI" -#define D_SENSOR_MY92X1_DCKI "MY92x1 DCKI" -#define D_SENSOR_ARIRFRCV "ALux IrRcv" -#define D_SENSOR_ARIRFSEL "ALux IrSel" -#define D_SENSOR_TXD "Serial Tx" -#define D_SENSOR_RXD "Serial Rx" -#define D_SENSOR_ROTARY "Draai" // Suffix "1A" -#define D_SENSOR_HRE_CLOCK "HRE Klok" -#define D_SENSOR_HRE_DATA "HRE Data" -#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ" -#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ" -#define D_SENSOR_ADE7953_RST "ADE7953 RST" -#define D_SENSOR_ADE7953_CS "ADE7953 CS" -#define D_SENSOR_BUZZER "Gonser" -#define D_SENSOR_DISP_RESET "Display Rst" -#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" -#define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" -#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" -#define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" -#define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" -#define D_SENSOR_SOLAXX1_RTS "SolaxX1 RTS" -#define D_SENSOR_IBEACON_TX "iBeacon TX" -#define D_SENSOR_IBEACON_RX "iBeacon RX" -#define D_SENSOR_RDM6300_RX "RDM6300 RX" -#define D_SENSOR_CC1101_CS "CC1101 CS" -#define D_SENSOR_A4988_DIR "A4988 DIR" -#define D_SENSOR_A4988_STP "A4988 STP" -#define D_SENSOR_A4988_ENA "A4988 ENA" -#define D_SENSOR_A4988_MS1 "A4988 MS1" -#define D_SENSOR_OUTPUT_HI "Output Hi" -#define D_SENSOR_OUTPUT_LO "Output Lo" -#define D_SENSOR_AS608_TX "AS608 Tx" -#define D_SENSOR_AS608_RX "AS608 Rx" -#define D_SENSOR_GM861_TX "GM861 Tx" -#define D_SENSOR_GM861_RX "GM861 Rx" -#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" -#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" -#define D_SENSOR_DDSU666_TX "DDSU666 Tx" -#define D_SENSOR_DDSU666_RX "DDSU666 Rx" -#define D_SENSOR_SM2135_CLK "SM2135 Clk" -#define D_SENSOR_SM2135_DAT "SM2135 Dat" -#define D_SENSOR_SM2335_CLK "SM2335 Clk" -#define D_SENSOR_SM2335_DAT "SM2335 Dat" -#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk" -#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat" -#define D_SENSOR_BP5758D_CLK "BP5758D Clk" -#define D_SENSOR_BP5758D_DAT "BP5758D Dat" -#define D_SENSOR_DEEPSLEEP "Diep slaap" -#define D_SENSOR_EXS_ENABLE "EXS Inskakel" -#define D_SENSOR_CLIENT_TX "Client TX" -#define D_SENSOR_CLIENT_RX "Client RX" -#define D_SENSOR_CLIENT_RESET "Client RST" -#define D_SENSOR_GPS_RX "GPS RX" -#define D_SENSOR_GPS_TX "GPS TX" -#define D_SENSOR_HM10_RX "HM10 RX" -#define D_SENSOR_HM10_TX "HM10 TX" -#define D_SENSOR_LE01MR_RX "LE-01MR Rx" -#define D_SENSOR_LE01MR_TX "LE-01MR Tx" -#define D_SENSOR_BL0940_RX "BL0940 Rx" -#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" -#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" -#define D_SENSOR_HRXL_RX "HRXL Rx" -#define D_SENSOR_DYP_RX "DYP Rx" -#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" -#define D_SENSOR_AS3935 "AS3935" -#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" -#define D_SENSOR_TELEINFO_RX "TInfo Rx" -#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" -#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" -#define D_SENSOR_ADC_INPUT "ADC Insette" -#define D_SENSOR_ADC_TEMP "ADC Temperatuur" -#define D_SENSOR_ADC_LIGHT "ADC Lig" -#define D_SENSOR_ADC_BUTTON "ADC Knoppie" -#define D_SENSOR_ADC_RANGE "ADC Reekse" -#define D_SENSOR_ADC_CT_POWER "ADC CT Power" -#define D_SENSOR_ADC_JOYSTICK "ADC Joystick" -#define D_SENSOR_ADC_PH "ADC pH" -#define D_SENSOR_ADC_MQ "ADC MQ" -#define D_SENSOR_ADC_VOLTAGE "ADC Voltage" -#define D_SENSOR_ADC_CURRENT "ADC Current" -#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" -#define D_GPIO_WEBCAM_RESET "CAM_RESET" -#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" -#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" -#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" -#define D_GPIO_WEBCAM_DATA "CAM_DATA" -#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" -#define D_GPIO_WEBCAM_HREF "CAM_HREF" -#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" -#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" -#define D_GPIO_WEBCAM_HSD "CAM_HSD" -#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" -#define D_SENSOR_ETH_PHY_POWER "ETH POWER" -#define D_SENSOR_ETH_PHY_MDC "ETH MDC" -#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" -#define D_SENSOR_TCP_TXD "TCP Tx" -#define D_SENSOR_TCP_TXD_EN "TCP Tx En" -#define D_SENSOR_TCP_RXD "TCP Rx" -#define D_SENSOR_IEM3000_TX "iEM3000 TX" -#define D_SENSOR_IEM3000_RX "iEM3000 RX" -#define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" -#define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" -#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" -#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" -#define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" -#define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Herstel" -#define D_SENSOR_RC522_RST "RC522 Herstel" -#define D_SENSOR_RC522_CS "RC522 CS" -#define D_SENSOR_NRF24_CS "NRF24 CS" -#define D_SENSOR_NRF24_DC "NRF24 DC" -#define D_SENSOR_XPT2046_CS "XPT2046 CS" -#define D_SENSOR_ILI9341_CS "ILI9341 CS" -#define D_SENSOR_ILI9341_DC "ILI9341 DC" -#define D_SENSOR_ILI9488_CS "ILI9488 CS" -#define D_SENSOR_EPAPER29_CS "EPaper29 CS" -#define D_SENSOR_EPAPER42_CS "EPaper42 CS" -#define D_SENSOR_SSD1351_CS "SSD1351 CS" -#define D_SENSOR_SSD1351_DC "SSD1351 DC" -#define D_SENSOR_RA8876_CS "RA8876 CS" -#define D_SENSOR_ST7789_CS "ST7789 CS" -#define D_SENSOR_ST7789_DC "ST7789 DC" -#define D_SENSOR_SSD1331_CS "SSD1331 CS" -#define D_SENSOR_SSD1331_DC "SSD1331 DC" -#define D_SENSOR_SDCARD_CS "SDCard CS" -#define D_SENSOR_WIEGAND_D0 "Wiegand D0" -#define D_SENSOR_WIEGAND_D1 "Wiegand D1" -#define D_SENSOR_NEOPOOL_TX "NeoPool Tx" -#define D_SENSOR_NEOPOOL_RX "NeoPool Rx" -#define D_SENSOR_VL53LXX_XSHUT "VL53LXX XSHUT" -#define D_SENSOR_TFMINIPLUS_TX "TFmini+ TX" -#define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" -#define D_SENSOR_ZEROCROSS "ZC Pulse" -#define D_SENSOR_HALLEFFECT "HallEffect" -#define D_SENSOR_EPD_DATA "EPD Data" -#define D_SENSOR_PCF8574_INT "PCF8574 Int" -#define D_SENSOR_MCP23XXX_INT "MCP23xxx Int" -#define D_SENSOR_MCP23SXX_CS "MCP23Sxx CS" -#define D_SENSOR_MCP2515_CS "MCP2515 CS" -#define D_SENSOR_HRG15_RX "HRG15 Rx" -#define D_SENSOR_HRG15_TX "HRG15 Tx" -#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" -#define D_SENSOR_BL6523_TX "BL6523 Tx" -#define D_SENSOR_BL6523_RX "BL6523 Rx" -#define D_SENSOR_HEARTBEAT "Heartbeat" -#define D_SENSOR_RESET "Reset" -#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" -#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" -#define D_GPIO_SHIFT595_OE "74x595 OE" -#define D_GPIO_SHIFT595_SER "74x595 SER" -#define D_GPIO_DINGTIAN_CLK "Dingtian CLK" -#define D_GPIO_DINGTIAN_SDI "Dingtian SDI" -#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7" -#define D_GPIO_DINGTIAN_PL "Dingtian PL" -#define D_GPIO_DINGTIAN_OE "Dingtian OE" -#define D_GPIO_DINGTIAN_RCK "Dingtian RCK" -#define D_SENSOR_CM11_TX "CM110x TX" -#define D_SENSOR_CM11_RX "CM110x RX" -#define D_SENSOR_FLOWRATEMETER "Flowrate" -#define D_SENSOR_ME007_TRIG "ME007 Tri" -#define D_SENSOR_ME007_RX "ME007 Rx" -#define D_SENSOR_TUYAMCUBR_TX "TuyaMCUBr Tx" -#define D_SENSOR_TUYAMCUBR_RX "TuyaMCUBr Rx" -#define D_SENSOR_TWAI_TX "TWAI Tx" -#define D_SENSOR_TWAI_RX "TWAI Rx" -#define D_SENSOR_TWAI_BO "TWAI BusOff" -#define D_SENSOR_TWAI_CLK "TWAI ClkOut" -#define D_SENSOR_BIOPDU_PZEM0XX_TX "BioPDU PZEM0XX Tx" -#define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" -#define D_SENSOR_BIOPDU_BIT "BioPDU Bit" -#define D_SENSOR_LOX_O2_RX "LoxO2 RX" -#define D_GPIO_MAGIC_SWITCH "MagicSwitch" -#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" -#define D_SENSOR_C8_CO2_5K_RX "C8-CO2-5K Rx" -#define D_SENSOR_C8_CO2_5K_TX "C8-CO2-5K Tx" -#define D_SENSOR_MKSKYBLU_TX "MkSkyBlu Tx" -#define D_SENSOR_MKSKYBLU_RX "MkSkyBlu Rx" - -// Units -#define D_UNIT_AMPERE "A" -#define D_UNIT_CELSIUS "C" -#define D_UNIT_CENTIMETER "cm" -#define D_UNIT_DEGREE "°" -#define D_UNIT_FAHRENHEIT "F" -#define D_UNIT_FPS "FPS" -#define D_UNIT_HERTZ "Hz" -#define D_UNIT_HOUR "h" -#define D_UNIT_GALLONS "gal" -#define D_UNIT_GALLONS_PER_MIN "g/m" -#define D_UNIT_GRAM_PER_CUBIC_METER "g/m³" -#define D_UNIT_INCH_MERCURY "inHg" -#define D_UNIT_INCREMENTS "inc" -#define D_UNIT_KELVIN "K" -#define D_UNIT_KILOMETER "km" -#define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" -#define D_UNIT_KILOOHM "kΩ" -#define D_UNIT_KILOWATTHOUR "kWh" -#define D_UNIT_LITERS "L" -#define D_UNIT_LITERS_PER_MIN "L/m" -#define D_UNIT_LUX "lx" -#define D_UNIT_METER "m" -#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³" -#define D_UNIT_MICROMETER "µm" -#define D_UNIT_MICROSECOND "µs" -#define D_UNIT_MICROSIEMENS_PER_CM "µS/cm" -#define D_UNIT_MICROTESLA "µT" -#define D_UNIT_MILLIAMPERE "mA" -#define D_UNIT_MILLILITERS "ml" -#define D_UNIT_MILLIMETER "mm" -#define D_UNIT_MILLIMETER_MERCURY "mmHg" -#define D_UNIT_MILLISECOND "ms" -#define D_UNIT_MILLIVOLT "mV" -#define D_UNIT_MINUTE "Min" -#define D_UNIT_PARTS_PER_BILLION "ppb" -#define D_UNIT_PARTS_PER_DECILITER "ppd" -#define D_UNIT_PARTS_PER_MILLION "ppm" -#define D_UNIT_MILIGRAMS_PER_LITER "mg/L" -#define D_UNIT_PERCENT "%%" -#define D_UNIT_PRESSURE "hPa" -#define D_UNIT_SECOND "sec" -#define D_UNIT_SECTORS "sectors" -#define D_UNIT_VA "VA" -#define D_UNIT_VAR "var" -#define D_UNIT_VOLT "V" -#define D_UNIT_WATT "W" -#define D_UNIT_WATTHOUR "Wh" -#define D_UNIT_WATT_METER_QUADRAT "W/m²" -#define D_UNIT_LITER_PER_MINUTE "l/min" -#define D_UNIT_CUBICMETER_PER_HOUR "m³/h" -#define D_UNIT_CUBIC_METER "m³" - -#define D_NEW_ADDRESS "Setting address to" -#define D_OUT_OF_RANGE "Out of Range" -#define D_SENSOR_DETECTED "detected" - -//SDM220, SDM120, SDM72, LE01MR, SDM230 -#define D_EXPORT_POWER "Uitvoer krag" -#define D_IMPORT_POWER "Invoer krag" -#define D_PHASE_ANGLE "Fasehoek" -#define D_IMPORT_ACTIVE "Invoer aktief" -#define D_EXPORT_ACTIVE "Uitvoer aktief" -#define D_IMPORT_REACTIVE "Import reaktief" -#define D_EXPORT_REACTIVE "Uitvoer reaktief" -#define D_TOTAL_REACTIVE "Totaal reaktief" -#define D_UNIT_KWARH "kvarh" -#define D_UNIT_ANGLE "Deg" -#define D_TOTAL_ACTIVE "Totaal aktief" -#define D_RESETTABLE_TOTAL_ACTIVE "Totaal aktief (RST)" - -//SOLAXX1 -#define D_PV1_VOLTAGE "PV1 Spanning" -#define D_PV1_CURRENT "PV1 Stroom" -#define D_PV1_POWER "PV1 Krag" -#define D_PV2_VOLTAGE "PV2 Spanning" -#define D_PV2_CURRENT "PV2 Stroom" -#define D_PV2_POWER "PV2 Krag" -#define D_SOLAR_POWER "Sonkrag" -#define D_INVERTER_POWER "Omskakelaarkrag" -#define D_STATUS "Status" -#define D_SOLAX_MODE_0 "Wag" -#define D_SOLAX_MODE_1 "Nagaan" -#define D_SOLAX_MODE_2 "Werk" -#define D_SOLAX_MODE_3 "Mislukking" -#define D_SOLAX_MODE_4 "Permanent Failure" // to be translated -#define D_SOLAX_MODE_5 "Software Update" // to be translated -#define D_SOLAX_MODE_6 "Selftest" // to be translated -#define D_SOLAX_ERROR_0 "Geen foutkode nie" -#define D_SOLAX_ERROR_1 "Netspanning verlies fout" -#define D_SOLAX_ERROR_2 "Netspanning spanning fout" -#define D_SOLAX_ERROR_3 "Netspanning frekwensie fout" -#define D_SOLAX_ERROR_4 "Pv stroom fout" -#define D_SOLAX_ERROR_5 "Isolasiefout" -#define D_SOLAX_ERROR_6 "Storing by oormatige temperatuur" -#define D_SOLAX_ERROR_7 "Waaierstoring" -#define D_SOLAX_ERROR_8 "Ander toestelfout" - -//xdrv_10_scripter.ino -#define D_CONFIGURE_SCRIPT "Wysig skrif" -#define D_SCRIPT "wysig skrif" -#define D_SDCARD_UPLOAD "lêer oplaai" -#define D_UFSDIR "ufs vouer" -#define D_UPL_DONE "Klaar" -#define D_SCRIPT_CHARS_LEFT "karakters oor" -#define D_SCRIPT_CHARS_NO_MORE "nie meer karakters nie" -#define D_SCRIPT_DOWNLOAD "Aflaai" -#define D_SCRIPT_ENABLE "skrip inskakel" -#define D_SCRIPT_UPLOAD "Laai op" -#define D_SCRIPT_UPLOAD_FILES "Laai lêers op" - -//xdrv_50_filesystem.ino -#define D_MANAGE_FILE_SYSTEM "Bestuur lêerstelsel" -#define D_FS_SIZE "Grootte" -#define D_FS_FREE "Vry" -#define D_NEW_FILE "newfile.txt" -#define D_CREATE_NEW_FILE "Create and edit new file" -#define D_EDIT_FILE "Edit File" -#define D_CONFIRM_FILE_DEL "Confirm file deletion" -#define D_SHOW_HIDDEN_FILES "Show hidden files" - -//xsns_67_as3935.ino -#define D_AS3935_GAIN "versterking:" -#define D_AS3935_ENERGY "energie:" -#define D_AS3935_DISTANCE "afstand:" -#define D_AS3935_DISTURBER "steur:" -#define D_AS3935_VRMS "µVrms:" -#define D_AS3935_APRX "aprx.:" -#define D_AS3935_AWAY "weg" -#define D_AS3935_LIGHT "weerlig" -#define D_AS3935_OUT "weerlig buite bereik" -#define D_AS3935_NOT "afstand nie bepaal nie" -#define D_AS3935_ABOVE "weerlig oorhoofse" -#define D_AS3935_NOISE "geraas bespeur" -#define D_AS3935_DISTDET "steuring bespeur" -#define D_AS3935_INTNOEV "Onderbreek met geen geleentheid nie!" -#define D_AS3935_FLICKER "IRQ Pin flikker!" -#define D_AS3935_POWEROFF "Skakel af" -#define D_AS3935_NOMESS "luister..." -#define D_AS3935_ON "Aan" -#define D_AS3935_OFF "Uit" -#define D_AS3935_INDOORS "Binnenshuis" -#define D_AS3935_OUTDOORS "Buite" -#define D_AS3935_CAL_FAIL "kalibrasie het misluk" -#define D_AS3935_CAL_OK "kalibrasie ingestel op:" - -//xsns_68_opentherm.ino -#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" -#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" - -// xnrg_15_teleinfo Denky (Teleinfo) -#define D_CONTRACT "Kontrak" -#define D_POWER_LOAD "Kraglading" -#define D_CURRENT_TARIFF "Stroom tarief" -#define D_TARIFF "Tarief" -#define D_OVERLOAD "ADPS" -#define D_MAX_POWER "Max krag" -#define D_MAX_CURRENT "Max stroom" - -// xsns_79_as608.ino -#define D_FP_ENROLL_PLACEFINGER "Plaas vinger" -#define D_FP_ENROLL_REMOVEFINGER "Verwyder vinger" -#define D_FP_ENROLL_PLACESAMEFINGER "Plaas dieselfde vinger weer" -#define D_FP_ENROLL_RETRY "Fout, probeer dus weer" -#define D_FP_ENROLL_RESTART "Begin oor" -#define D_FP_ENROLL_ERROR "Fout" -#define D_FP_ENROLL_RESET "Stel terug" -#define D_FP_ENROLL_ACTIVE "Aktief" -#define D_FP_ENROLL_INACTIVE "Onaktief" -// Indexed by Adafruit_Fingerprint.h defines -#define D_FP_PACKETRECIEVEERR "Komms-fout" // 0x01 Error when receiving data package -#define D_FP_NOFINGER "Geen vinger op die sensor nie" // 0x02 No finger on the sensor -#define D_FP_IMAGEFAIL "Beeldfout" // 0x03 Failed to enroll the finger -#define D_FP_IMAGEMESS "Beeld te deurmekaar" // 0x06 Failed to generate character file due to overly disorderly fingerprint image -#define D_FP_FEATUREFAIL "Vingerafdruk te klein" // 0x07 Failed to generate character file due to the lack of character point or small fingerprint image -#define D_FP_NOMATCH "Nie opgewasse" // 0x08 Finger doesn't match -#define D_FP_NOTFOUND "Kon nie 'n ekwivalent vind nie" // 0x09 Failed to find matching finger -#define D_FP_ENROLLMISMATCH "Vingerafdruk stem nie ooreen nie" // 0x0A Failed to combine the character files -#define D_FP_BADLOCATION "Slegte ligging" // 0x0B Addressed PageID is beyond the finger library -#define D_FP_DBRANGEFAIL "DB-reeksfout" // 0x0C Error when reading template from library or invalid template -#define D_FP_UPLOADFEATUREFAIL "Fout by die oplaai van funksie" // 0x0D Error when uploading template -#define D_FP_PACKETRESPONSEFAIL "Fout van pakketrespons" // 0x0E Module failed to receive the following data packages -#define D_FP_UPLOADFAIL "Oplaaifout" // 0x0F Error when uploading image -#define D_FP_DELETEFAIL "Vee fout" // 0x10 Failed to delete the template -#define D_FP_DBCLEARFAIL "DB leegfout" // 0x11 Failed to clear finger library -#define D_FP_PASSFAIL "Wagwoordfout" // 0x13 Find whether the fingerprint passed or failed -#define D_FP_INVALIDIMAGE "Prent ongeldig" // 0x15 Failed to generate image because of lac of valid primary image -#define D_FP_FLASHERR "Flash skryffout" // 0x18 Error when writing flash -#define D_FP_INVALIDREG "Ongeldige nommer" // 0x1A Invalid register number -#define D_FP_ADDRCODE "Adres kode" // 0x20 Address code -#define D_FP_PASSVERIFY "Wagwoord geverifieer" // 0x21 Verify the fingerprint passed -#define D_FP_UNKNOWNERROR "Fout" // Any other error - -// xsns_90_hrg15.ino -#define D_HRG_VALID "Valid" -#define D_HRG_ACTIVE "Active" -#define D_HRG_EVENT "Event" -#define D_HRG_TOTAL "Total" -#define D_HRG_FLOWRATE "Flow Rate" - -// xsns_96_flowratemeter.ino -#define D_FLOWRATEMETER_NAME "Flowrate" -#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today" -#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today" - -// xsns_83_neopool.ino -#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names -#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife" -#define D_NEOPOOL_MACH_AQUASCENIC "Aquascenic" -#define D_NEOPOOL_MACH_OXILIFE "Oxilife" -#define D_NEOPOOL_MACH_BIONET "Bionet" -#define D_NEOPOOL_MACH_HIDRONISER "Hidroniser" -#define D_NEOPOOL_MACH_UVSCENIC "UVScenic" -#define D_NEOPOOL_MACH_STATION "Station" -#define D_NEOPOOL_MACH_BRILIX "Brilix" -#define D_NEOPOOL_MACH_GENERIC "Generic" -#define D_NEOPOOL_MACH_BAYROL "Bayrol" -#define D_NEOPOOL_MACH_HAY "Hay" -#define D_NEOPOOL_FILTRATION_MANUAL "Handmatig" // Filtration modes -#define D_NEOPOOL_FILTRATION_AUTO "Outomaties" -#define D_NEOPOOL_FILTRATION_HEATING "Verhitting" -#define D_NEOPOOL_FILTRATION_SMART "Slim" -#define D_NEOPOOL_FILTRATION_INTELLIGENT "Intelligent" -#define D_NEOPOOL_FILTRATION_BACKWASH "Terugspoel" -#define D_NEOPOOL_FILTRATION_NONE "" // Filtration speed level -#define D_NEOPOOL_FILTRATION_SLOW "stadig" -#define D_NEOPOOL_FILTRATION_MEDIUM "medium" -#define D_NEOPOOL_FILTRATION_FAST "vinnig" -#define D_NEOPOOL_TYPE "Tipe" // Sensor & relais names -#define D_NEOPOOL_REDOX "Redoks" -#define D_NEOPOOL_CHLORINE "Chloor" -#define D_NEOPOOL_CONDUCTIVITY "Geleidingsvermoë" -#define D_NEOPOOL_IONIZATION "Ionisering" -#define D_NEOPOOL_HYDROLYSIS "Hidrolise" -#define D_NEOPOOL_RELAY "Relais" -#define D_NEOPOOL_RELAY_FILTRATION "Filtrasie" // Relay assignment -#define D_NEOPOOL_RELAY_LIGHT "Lig" -#define D_NEOPOOL_RELAY_PH_ACID "Suurpomp" -#define D_NEOPOOL_RELAY_PH_BASE "Basispump" -#define D_NEOPOOL_RELAY_RX "Redoksvlak" -#define D_NEOPOOL_RELAY_CL "Chloorpomp" -#define D_NEOPOOL_RELAY_CD "Geleidingsvermoë" -#define D_NEOPOOL_RELAY_HEATING "Verhitting" -#define D_NEOPOOL_RELAY_UV "UV" -#define D_NEOPOOL_RELAY_VALVE "Valve" -#define D_NEOPOOL_RELAY_AUX "Aux" -#define D_NEOPOOL_TIME "Tyd" -#define D_NEOPOOL_FILT_MODE "Filtrasie" -#define D_NEOPOOL_CELL_RUNTIME "Cell runtime" -#define D_NEOPOOL_POLARIZATION "Pol" // Sensor status -#define D_NEOPOOL_PR_OFF "PrOff" -#define D_NEOPOOL_SETPOINT_OK "Oké" -#define D_NEOPOOL_COVER "Voorblad" -#define D_NEOPOOL_SHOCK "Skok" -#define D_NEOPOOL_STATUS_ON "ON" -#define D_NEOPOOL_STATUS_OFF "OFF" -#define D_NEOPOOL_STATUS_WAIT "WAIT" -#define D_NEOPOOL_STATUS_TANK "TANK" -#define D_NEOPOOL_STATUS_FLOW "Flow" -#define D_NEOPOOL_LOW "Laag" -#define D_NEOPOOL_FLOW1 "FL1" -#define D_NEOPOOL_FLOW2 "FL2" -#define D_NEOPOOL_PH_HIGH "te hoog" // ph Alarms -#define D_NEOPOOL_PH_LOW "te laag" -#define D_NEOPOOL_PUMP_TIME_EXCEEDED "pomptyd oorskry" - -// xsns_106_gdk101.ino -#define D_AVG_RAD_DOSE "Gemiddelde Stralingsdosis" -#define D_UNIT_US_H "µSv/h" - -// ixrv92_pipsolar.ino -#define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" -#define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" - -// xsns_102_ld2410.ino -#define D_MOVING_DISTANCE "Moving Distance" -#define D_STATIC_DISTANCE "Static Distance" -#define D_DETECT_DISTANCE "Detect Distance" -#define D_MOVING_ENERGY_T "Moving target" -#define D_STATIC_ENERGY_T "Static target" -#define D_LD2410_PIN_STATE "Output pin state" -#define D_LD2410_LIGHT "Light sensor" - -// xsns_115_wooliis.ino -#define D_IMPORT "Import" -#define D_EXPORT "Export" -#define D_CHARGING "Charging" -#define D_CAPACITY "Capacity" - -// xnrg_25_v9240.ino -#define D_SENSOR_V9240_TX "V9240 TX" -#define D_SENSOR_V9240_RX "V9240 RX" - -#endif // _LANGUAGE_AF_AF_H_ +// xsns_100_ina3221.ino +#define D_UNIT_CHARGE "Ah" +#define D_CHARGE "Charge" +#define D_ENERGY "Energy" + +// xdrv_27_shutter.ino +#define D_OPEN "Maak oop" +#define D_CLOSE "Maak toe" +#define D_DOMOTICZ_SHUTTER "Luik" + +// xdrv_28_pcf8574.ino +#define D_CONFIGURE_PCF8574 "PCF8574" +#define D_PCF8574_PARAMETERS "PCF8574 parameters" +#define D_INVERT_PORTS "Keer poorte om" +#define D_DEVICE "Toestel" +#define D_DEVICE_INPUT "Invoer" +#define D_DEVICE_OUTPUT "Uitvoer" + +// xdrv_39_thermostat.ino, xdrv_85_esp32_ble_eq3_trv.ino +#define D_THERMOSTAT "Thermostat" +#define D_THERMOSTAT_SET_POINT "Set Point Temperature" +#define D_THERMOSTAT_SENSOR "Current Temperature" +#define D_THERMOSTAT_GRADIENT "Gradient Temperature" +#define D_THERMOSTAT_DUTY_CYCLE "Duty cycle" +#define D_THERMOSTAT_VALVE_POSITION "Valve Position" +#define D_THERMOSTAT_CYCLE_TIME "Cycle time" +#define D_THERMOSTAT_PI_AUTOTUNE "PI Auto tuning" +#define D_THERMOSTAT_CONTROL_METHOD "Control method" +#define D_THERMOSTAT_RAMP_UP "Ramp up" +#define D_THERMOSTAT_PI "PI" +#define D_THERMOSTAT_AUTOTUNE "Autotune" +#define D_THERMOSTAT_RAMP_UP_HYBRID "Ramp up (Hybrid)" +#define D_THERMOSTAT_PI_HYBRID "PI (Hybrid)" +#define D_THERMOSTAT_AUTOTUNE_HYBRID "Autotune (Hybrid)" + +// xdrv_79_esp32_ble.ino +#define D_CONFIGURE_BLE "BLE" +#define D_BLE_PARAMETERS "Bluetooth Settings" +#define D_BLE_ENABLE "Enable Bluetooth" +#define D_BLE_ACTIVESCAN "Enable Active Scan(*)" +#define D_BLE_DEVICES "Devices Seen" +#define D_BLE_REMARK "items marked (*) are not stored in config" + +// xsns_05_ds18b20.ino +#define D_SENSOR_BUSY "Sensor besig" +#define D_SENSOR_CRC_ERROR "Sensor CRC fout" +#define D_SENSORS_FOUND "Sensors gevind" + +// xsns_06_dht.ino +#define D_TIMEOUT_WAITING_FOR "Tyduitstyd wag vir" +#define D_START_SIGNAL_LOW "begin sein laag" +#define D_START_SIGNAL_HIGH "begin sein hoog" +#define D_PULSE "pols" +#define D_CHECKSUM_FAILURE "Checksum het misluk" + +// xsns_07_sht1x.ino +#define D_SENSOR_DID_NOT_ACK_COMMAND "Sensor het nie ACK opdrag" +#define D_SHT1X_FOUND "SHT1X gevind" + +// xsns_18_pms5003.ino +#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter +#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter +#define D_PARTICALS_BEYOND "Deeltjies" + +// xsns_27_apds9960.ino +#define D_GESTURE "Gebaar" +#define D_COLOR_RED "Rooi" +#define D_COLOR_GREEN "Groen" +#define D_COLOR_BLUE "Blou" +#define D_CCT "CCT" +#define D_PROXIMITY "Nabyheid" + +// xsns_32_mpu6050.ino +#define D_AX_AXIS "Accel. X-Axis" +#define D_AY_AXIS "Accel. Y-Axis" +#define D_AZ_AXIS "Accel. Z-Axis" +#define D_GX_AXIS "Gyro X-Axis" +#define D_GY_AXIS "Gyro Y-Axis" +#define D_GZ_AXIS "Gyro Z-Axis" + +// xsns_33_QMC5883L.ino +#define D_MX "Induction X-Axis" +#define D_MY "Induction Y-Axis" +#define D_MZ "Induction Z-Axis" +#define D_MAGNETICFLD "Magnetic Induction" + +// xsns_34_hx711.ino +#define D_HX_CAL_REMOVE "Verwyder gewig" +#define D_HX_CAL_REFERENCE "Laai verwysingsgewig" +#define D_HX_CAL_DONE "Gekalibreer" +#define D_HX_CAL_FAIL "Kon nie kalibreer nie" +#define D_RESET_HX711 "Stel die skaal terug" +#define D_CONFIGURE_HX711 "skaal" +#define D_HX711_PARAMETERS "Skaal parameters" +#define D_ITEM_WEIGHT "Gewig van die item" +#define D_REFERENCE_WEIGHT "Verwysingsgewig" +#define D_CALIBRATE "Kalibreer" +#define D_CALIBRATION "Kalibrasie" + +//xsns_35_tx20.ino +#define D_TX20_WIND_DIRECTION "Windrigting" +#define D_TX20_WIND_SPEED "Wind spoed" +#define D_TX20_WIND_SPEED_MIN "Wind spoed Min" +#define D_TX20_WIND_SPEED_MAX "Wind spoed Max" +#define D_TX20_NORTH "N" +#define D_TX20_EAST "O" +#define D_TX20_SOUTH "S" +#define D_TX20_WEST "W" + +// xsns_53_sml.ino +#define D_TPWRIN "Totaal-In" +#define D_TPWRIN0 "Totaal-In T0" +#define D_TPWRIN1 "Totaal-In T1" +#define D_TPWROUT "Totaal-Uit" +#define D_TPWRCURR "Stroom-In/Uit" +#define D_TPWRCURR1 "Stroom-In p1" +#define D_TPWRCURR2 "Stroom-In p2" +#define D_TPWRCURR3 "Stroom-In p3" +#define D_Strom_L1 "Stroom L1" +#define D_Strom_L2 "Stroom L2" +#define D_Strom_L3 "Stroom L3" +#define D_Spannung_L1 "Spanning L1" +#define D_Spannung_L2 "Spanning L2" +#define D_Spannung_L3 "Spanning L3" +#define D_METERNR "Meter nommmer" +#define D_METERSID "Service ID" +#define D_GasIN "Teller" // Gas-Verbrauch +#define D_H2oIN "Teller" // H2o-Verbrauch +#define D_StL1L2L3 "Stroom L1+L2+L3" +#define D_SpL1L2L3 "Spanning L1+L2+L3/3" + +// xsns_86_tfminiplus.ino +#define D_SIGNALSTRENGTH "Signal Strength" +#define D_CHIPTEMPERATURE "Chip Temperature" + +// xsns_60_GPS +#define D_LATITUDE "Latitude" +#define D_LONGITUDE "Longitude" +#define D_HORIZONTAL_ACCURACY "Horizontal Accuracy" +#define D_ALTITUDE "Altitude" +#define D_VERTICAL_ACCURACY "Vertical Accuracy" +#define D_SPEED "Speed" +#define D_SPEED_ACCURACY "Speed Accuracy" +#define D_HEADING "Heading" +#define D_HEADING_ACCURACY "Heading Accuracy" +#define D_SAT_FIX "Satellite Fix" + #define D_SAT_FIX_NO_FIX "None" + #define D_SAT_FIX_DEAD_RECK "Dead reckoning" + #define D_SAT_FIX_2D "2D" + #define D_SAT_FIX_3D "3D" + #define D_SAT_FIX_GPS_DEAD "GPS and dead reckoning" + #define D_SAT_FIX_TIME "Time only fix" + +// tasmota_template.h - keep them as short as possible to be able to fit them in GUI drop down box +#define D_SENSOR_NONE "Geen" +#define D_SENSOR_USER "Gebruiker" +#define D_SENSOR_OPTION "Opsie" +#define D_SENSOR_DHT11 "DHT11" +#define D_SENSOR_AM2301 "AM2301" +#define D_SENSOR_SI7021 "SI7021" +#define D_SENSOR_MS01 "MS01" +#define D_SENSOR_DS18X20 "DS18x20" +#define D_SENSOR_I2C_SCL "I2C SCL" +#define D_SENSOR_I2C_SDA "I2C SDA" +#define D_SENSOR_I2C_SER_TX "I2C Ser TX" +#define D_SENSOR_I2C_SER_RX "I2C Ser RX" +#define D_SENSOR_I2S_MCLK "I2S MCLK" +#define D_SENSOR_I2S_BCLK "I2S BCLK" +#define D_SENSOR_I2S_WS_IN "I2S BCLK IN" +#define D_SENSOR_I2S_WS "I2S WS" +#define D_SENSOR_I2S_BCLK_IN "I2S WS IN" +#define D_SENSOR_I2S_DIN "I2S DIN" +#define D_SENSOR_I2S_DOUT "I2S DOUT" +#define D_SENSOR_I2S_DAC "I2S DAC" +#define D_SENSOR_HDMI_CEC "HDMI CEC" +#define D_SENSOR_WS2812 "WS2812" +#define D_SENSOR_DFR562 "MP3 Speler" +#define D_SENSOR_DFR562_BUSY "MP3 Bezet" +#define D_SENSOR_IRSEND "IRstuurder" +#define D_SENSOR_SWITCH "SKakelaar" // Suffix "1" +#define D_SENSOR_BUTTON "Knoppie" // Suffix "1" +#define D_SENSOR_RELAY "Relais" // Suffix "1i" +#define D_SENSOR_LED "Led" // Suffix "1i" +#define D_SENSOR_LED_LINK "LedLink" // Suffix "i" +#define D_SENSOR_PWM "PWM" // Suffix "1" +#define D_SENSOR_COUNTER "Teller" // Suffix "1" +#define D_SENSOR_INTERRUPT "Interrupt" +#define D_SENSOR_INPUT "Input" +#define D_SENSOR_IRRECV "IRontvanger" +#define D_SENSOR_MHZ_RX "MHZ Rx" +#define D_SENSOR_MHZ_TX "MHZ Tx" +#define D_SENSOR_HC8_RX "HC8 Rx" +#define D_SENSOR_PZEM004_RX "PZEM004 Rx" +#define D_SENSOR_PZEM016_RX "PZEM016 Rx" +#define D_SENSOR_PZEM017_RX "PZEM017 Rx" +#define D_SENSOR_PZEM0XX_TX "PZEM0XX Tx" +#define D_SENSOR_SAIR_RX "SAir Rx" +#define D_SENSOR_SAIR_TX "SAir Tx" +#define D_SENSOR_SPI_CS "SPI CS" +#define D_SENSOR_SPI_DC "SPI DC" +#define D_SENSOR_SPI_MISO "SPI MISO" +#define D_SENSOR_SPI_MOSI "SPI MOSI" +#define D_SENSOR_SPI_CLK "SPI CLK" +#define D_SENSOR_SDIO_CMD "SDIO CMD" +#define D_GPIO_TS_SPI_CS "TS SPI CS" +#define D_GPIO_TS_RST "TS RST" +#define D_GPIO_TS_IRQ "TS IRQ" +#define D_SENSOR_SDIO_CMD "SDIO CMD" +#define D_SENSOR_SDIO_CLK "SDIO CLK" +#define D_SENSOR_SDIO_D0 "SDIO D0" +#define D_SENSOR_SDIO_D1 "SDIO D1" +#define D_SENSOR_SDIO_D2 "SDIO D2" +#define D_SENSOR_SDIO_D3 "SDIO D3" +#define D_SENSOR_HSDIO_CMD "HSDIO CMD" +#define D_SENSOR_HSDIO_CLK "HSDIO CLK" +#define D_SENSOR_HSDIO_RST "HSDIO RST" +#define D_SENSOR_HSDIO_D0 "HSDIO D0" +#define D_SENSOR_HSDIO_D1 "HSDIO D1" +#define D_SENSOR_HSDIO_D2 "HSDIO D2" +#define D_SENSOR_HSDIO_D3 "HSDIO D3" +#define D_SENSOR_BACKLIGHT "Backlight" +#define D_SENSOR_PMS5003_TX "PMS5003 Tx" +#define D_SENSOR_PMS5003_RX "PMS5003 Rx" +#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx" +#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx" +#define D_SENSOR_HPMA_RX "HPMA Rx" +#define D_SENSOR_HPMA_TX "HPMA Tx" +#define D_SENSOR_SBR_RX "SerBr Rx" +#define D_SENSOR_SBR_TX "SerBr Tx" +#define D_SENSOR_MBR_TX "ModBr Tx" +#define D_SENSOR_MBR_RX "ModBr Rx" +#define D_SENSOR_MBR_TX_ENA "ModBr Tx Ena" +#define D_SENSOR_SR04_TRIG "SR04 Tri/TX" +#define D_SENSOR_SR04_ECHO "SR04 Ech/RX" +#define D_SENSOR_NRG_MBS_TX "NrgMbs Tx" +#define D_SENSOR_NRG_MBS_RX "NrgMbs Rx" +#define D_SENSOR_NRG_MBS_TX_ENA "NrgMbs Tx Ena" +#define D_SENSOR_SDM72_TX "SDM72 Tx" +#define D_SENSOR_SDM72_RX "SDM72 Rx" +#define D_SENSOR_SDM120_TX "SDMx20 Tx" +#define D_SENSOR_SDM120_RX "SDMx20 Rx" +#define D_SENSOR_SDM230_TX "SDM230 Tx" +#define D_SENSOR_SDM230_RX "SDM230 Rx" +#define D_SENSOR_SDM630_TX "SDM630 Tx" +#define D_SENSOR_SDM630_RX "SDM630 Rx" +#define D_SENSOR_WE517_TX "WE517 Tx" +#define D_SENSOR_WE517_RX "WE517 Rx" +#define D_SENSOR_LD2402_TX "LD2402 Tx" +#define D_SENSOR_LD2402_RX "LD2402 Rx" +#define D_SENSOR_LD2410_TX "LD2410 Tx" +#define D_SENSOR_LD2410_RX "LD2410 Rx" +#define D_SENSOR_LD2410S_TX "LD2410S Tx" +#define D_SENSOR_LD2410S_RX "LD2410S Rx" +#define D_GPIO_TM1621_CS "TM1621 CS" +#define D_GPIO_TM1621_WR "TM1621 WR" +#define D_GPIO_TM1621_RD "TM1621 RD" +#define D_GPIO_TM1621_DAT "TM1621 DAT" +#define D_SENSOR_TM1637_CLK "TM1637 CLK" +#define D_SENSOR_TM1637_DIO "TM1637 DIO" +#define D_SENSOR_TM1638_CLK "TM1638 CLK" +#define D_SENSOR_TM1638_DIO "TM1638 DIO" +#define D_SENSOR_TM1638_STB "TM1638 STB" +#define D_SENSOR_TM1640_CLK "TM1640 CLK" +#define D_SENSOR_TM1640_DIN "TM1640 DIN" +#define D_SENSOR_MAX7219_DIN "MAX7219 DIN" +#define D_SENSOR_MAX7219_CS "MAX7219 CS" +#define D_SENSOR_MAX7219_CLK "MAX7219 CLK" +#define D_SENSOR_HX711_SCK "HX711 SCK" +#define D_SENSOR_HX711_DAT "HX711 DAT" +#define D_SENSOR_FTC532 "FTC532" +#define D_SENSOR_BS814_CLK "BS814 CLK" +#define D_SENSOR_BS814_DAT "BS814 DAT" +#define D_SENSOR_TX2X_TX "TX2x" +#define D_SENSOR_RFSEND "RFstuurder" +#define D_SENSOR_RFRECV "RFontvanger" +#define D_SENSOR_TUYA_TX "Tuya Tx" +#define D_SENSOR_TUYA_RX "Tuya Rx" +#define D_SENSOR_MGC3130_XFER "MGC3130 Xfr" +#define D_SENSOR_MGC3130_RESET "MGC3130 Rst" +#define D_SENSOR_SSPI_MISO "SSPI MISO" +#define D_SENSOR_SSPI_MOSI "SSPI MOSI" +#define D_SENSOR_SSPI_SCLK "SSPI SCLK" +#define D_SENSOR_SSPI_CS "SSPI CS" +#define D_SENSOR_SSPI_DC "SSPI DC" +#define D_SENSOR_RF_SENSOR "RF Sensor" +#define D_SENSOR_AZ_RX "AZ Rx" +#define D_SENSOR_AZ_TX "AZ Tx" +#define D_SENSOR_MAX31855_CS "MX31855 CS" +#define D_SENSOR_MAX31855_CLK "MX31855 CLK" +#define D_SENSOR_MAX31855_DO "MX31855 DO" +#define D_SENSOR_MAX31865_CS "MX31865 CS" +#define D_GPIO_RN2XX3_TX "RN2XX3 Tx" +#define D_GPIO_RN2XX3_RX "RN2XX3 Rx" +#define D_GPIO_RN2XX3_RST "RN2XX3 Rst" +#define D_GPIO_ASR650X_TX "ASR650x Tx" +#define D_GPIO_ASR650X_RX "ASR650x Rx" +#define D_GPIO_LORA_CS "LoRa CS" +#define D_GPIO_LORA_RST "LoRa Rst" +#define D_GPIO_LORA_BUSY "LoRa Busy" +#define D_GPIO_LORA_DI "LoRa DIO" // Suffix "0","1","2" +#define D_SENSOR_NRG_SEL "HLWBL SEL" // Suffix "i" +#define D_SENSOR_NRG_CF1 "HLWBL CF1" +#define D_SENSOR_HLW_CF "HLW8012 CF" +#define D_SENSOR_HJL_CF "BL0937 CF" +#define D_SENSOR_MCP39F5_TX "MCP39F5 Tx" +#define D_SENSOR_MCP39F5_RX "MCP39F5 Rx" +#define D_SENSOR_MCP39F5_RST "MCP39F5 Rst" +#define D_SENSOR_CSE7761_TX "CSE7761 Tx" +#define D_SENSOR_CSE7761_RX "CSE7761 Rx" +#define D_SENSOR_CSE7766_TX "CSE7766 Tx" +#define D_SENSOR_CSE7766_RX "CSE7766 Rx" +#define D_SENSOR_BL0906_RX "BL0906 Rx" +#define D_SENSOR_BL0939_RX "BL0939 Rx" +#define D_SENSOR_BL0942_RX "BL0942 Rx" +#define D_SENSOR_HM330X_SET "HM330X SET" +#define D_SENSOR_PN532_TX "PN532 Tx" +#define D_SENSOR_PN532_RX "PN532 Rx" +#define D_SENSOR_SM16716_CLK "SM16716 CLK" +#define D_SENSOR_SM16716_DAT "SM16716 DAT" +#define D_SENSOR_SM16716_POWER "SM16716 PWR" +#define D_SENSOR_P9813_CLK "P9813 Clk" +#define D_SENSOR_P9813_DAT "P9813 Dat" +#define D_SENSOR_MY92X1_DI "MY92x1 DI" +#define D_SENSOR_MY92X1_DCKI "MY92x1 DCKI" +#define D_SENSOR_ARIRFRCV "ALux IrRcv" +#define D_SENSOR_ARIRFSEL "ALux IrSel" +#define D_SENSOR_TXD "Serial Tx" +#define D_SENSOR_RXD "Serial Rx" +#define D_SENSOR_ROTARY "Draai" // Suffix "1A" +#define D_SENSOR_HRE_CLOCK "HRE Klok" +#define D_SENSOR_HRE_DATA "HRE Data" +#define D_SENSOR_ADE7880_IRQ "ADE7880 IRQ" +#define D_SENSOR_ADE7953_IRQ "ADE7953 IRQ" +#define D_SENSOR_ADE7953_RST "ADE7953 RST" +#define D_SENSOR_ADE7953_CS "ADE7953 CS" +#define D_SENSOR_BUZZER "Gonser" +#define D_SENSOR_DISP_RESET "Display Rst" +#define D_SENSOR_ZIGBEE_TXD "Zigbee Tx" +#define D_SENSOR_ZIGBEE_RXD "Zigbee Rx" +#define D_SENSOR_ZIGBEE_RST "Zigbee Rst" +#define D_SENSOR_SOLAXX1_TX "SolaxX1 Tx" +#define D_SENSOR_SOLAXX1_RX "SolaxX1 Rx" +#define D_SENSOR_SOLAXX1_RTS "SolaxX1 RTS" +#define D_SENSOR_IBEACON_TX "iBeacon TX" +#define D_SENSOR_IBEACON_RX "iBeacon RX" +#define D_SENSOR_RDM6300_RX "RDM6300 RX" +#define D_SENSOR_CC1101_CS "CC1101 CS" +#define D_SENSOR_A4988_DIR "A4988 DIR" +#define D_SENSOR_A4988_STP "A4988 STP" +#define D_SENSOR_A4988_ENA "A4988 ENA" +#define D_SENSOR_A4988_MS1 "A4988 MS1" +#define D_SENSOR_OUTPUT_HI "Output Hi" +#define D_SENSOR_OUTPUT_LO "Output Lo" +#define D_SENSOR_AS608_TX "AS608 Tx" +#define D_SENSOR_AS608_RX "AS608 Rx" +#define D_SENSOR_GM861_TX "GM861 Tx" +#define D_SENSOR_GM861_RX "GM861 Rx" +#define D_SENSOR_DDS2382_TX "DDS238-2 Tx" +#define D_SENSOR_DDS2382_RX "DDS238-2 Rx" +#define D_SENSOR_DDSU666_TX "DDSU666 Tx" +#define D_SENSOR_DDSU666_RX "DDSU666 Rx" +#define D_SENSOR_SM2135_CLK "SM2135 Clk" +#define D_SENSOR_SM2135_DAT "SM2135 Dat" +#define D_SENSOR_SM2335_CLK "SM2335 Clk" +#define D_SENSOR_SM2335_DAT "SM2335 Dat" +#define D_SENSOR_BP1658CJ_CLK "BP1658CJ Clk" +#define D_SENSOR_BP1658CJ_DAT "BP1658CJ Dat" +#define D_SENSOR_BP5758D_CLK "BP5758D Clk" +#define D_SENSOR_BP5758D_DAT "BP5758D Dat" +#define D_SENSOR_DEEPSLEEP "Diep slaap" +#define D_SENSOR_EXS_ENABLE "EXS Inskakel" +#define D_SENSOR_CLIENT_TX "Client TX" +#define D_SENSOR_CLIENT_RX "Client RX" +#define D_SENSOR_CLIENT_RESET "Client RST" +#define D_SENSOR_GPS_RX "GPS RX" +#define D_SENSOR_GPS_TX "GPS TX" +#define D_SENSOR_HM10_RX "HM10 RX" +#define D_SENSOR_HM10_TX "HM10 TX" +#define D_SENSOR_LE01MR_RX "LE-01MR Rx" +#define D_SENSOR_LE01MR_TX "LE-01MR Tx" +#define D_SENSOR_BL0940_RX "BL0940 Rx" +#define D_SENSOR_CC1101_GDO0 "CC1101 GDO0" +#define D_SENSOR_CC1101_GDO2 "CC1101 GDO2" +#define D_SENSOR_HRXL_RX "HRXL Rx" +#define D_SENSOR_DYP_RX "DYP Rx" +#define D_SENSOR_ELECTRIQ_MOODL "MOODL Tx" +#define D_SENSOR_AS3935 "AS3935" +#define D_SENSOR_WINDMETER_SPEED "WindMeter Spd" +#define D_SENSOR_TELEINFO_RX "TInfo Rx" +#define D_SENSOR_TELEINFO_ENABLE "TInfo EN" +#define D_SENSOR_LMT01_PULSE "LMT01 Pulse" +#define D_SENSOR_ADC_INPUT "ADC Insette" +#define D_SENSOR_ADC_TEMP "ADC Temperatuur" +#define D_SENSOR_ADC_LIGHT "ADC Lig" +#define D_SENSOR_ADC_BUTTON "ADC Knoppie" +#define D_SENSOR_ADC_RANGE "ADC Reekse" +#define D_SENSOR_ADC_CT_POWER "ADC CT Power" +#define D_SENSOR_ADC_JOYSTICK "ADC Joystick" +#define D_SENSOR_ADC_PH "ADC pH" +#define D_SENSOR_ADC_MQ "ADC MQ" +#define D_SENSOR_ADC_VOLTAGE "ADC Voltage" +#define D_SENSOR_ADC_CURRENT "ADC Current" +#define D_GPIO_WEBCAM_PWDN "CAM_PWDN" +#define D_GPIO_WEBCAM_RESET "CAM_RESET" +#define D_GPIO_WEBCAM_XCLK "CAM_XCLK" +#define D_GPIO_WEBCAM_SIOD "CAM_SIOD" +#define D_GPIO_WEBCAM_SIOC "CAM_SIOC" +#define D_GPIO_WEBCAM_DATA "CAM_DATA" +#define D_GPIO_WEBCAM_VSYNC "CAM_VSYNC" +#define D_GPIO_WEBCAM_HREF "CAM_HREF" +#define D_GPIO_WEBCAM_PCLK "CAM_PCLK" +#define D_GPIO_WEBCAM_PSCLK "CAM_PSCLK" +#define D_GPIO_WEBCAM_HSD "CAM_HSD" +#define D_GPIO_WEBCAM_PSRCS "CAM_PSRCS" +#define D_SENSOR_ETH_PHY_POWER "ETH POWER" +#define D_SENSOR_ETH_PHY_MDC "ETH MDC" +#define D_SENSOR_ETH_PHY_MDIO "ETH MDIO" +#define D_SENSOR_TCP_TXD "TCP Tx" +#define D_SENSOR_TCP_TXD_EN "TCP Tx En" +#define D_SENSOR_TCP_RXD "TCP Rx" +#define D_SENSOR_IEM3000_TX "iEM3000 TX" +#define D_SENSOR_IEM3000_RX "iEM3000 RX" +#define D_SENSOR_MIEL_HVAC_TX "MiEl HVAC Tx" +#define D_SENSOR_MIEL_HVAC_RX "MiEl HVAC Rx" +#define D_SENSOR_PROJECTOR_CTRL_TX "DLP Tx" +#define D_SENSOR_PROJECTOR_CTRL_RX "DLP Rx" +#define D_SENSOR_SHELLY_DIMMER_BOOT0 "SHD Boot 0" +#define D_SENSOR_SHELLY_DIMMER_RST_INV "SHD Herstel" +#define D_SENSOR_RC522_RST "RC522 Herstel" +#define D_SENSOR_RC522_CS "RC522 CS" +#define D_SENSOR_NRF24_CS "NRF24 CS" +#define D_SENSOR_NRF24_DC "NRF24 DC" +#define D_SENSOR_XPT2046_CS "XPT2046 CS" +#define D_SENSOR_ILI9341_CS "ILI9341 CS" +#define D_SENSOR_ILI9341_DC "ILI9341 DC" +#define D_SENSOR_ILI9488_CS "ILI9488 CS" +#define D_SENSOR_EPAPER29_CS "EPaper29 CS" +#define D_SENSOR_EPAPER42_CS "EPaper42 CS" +#define D_SENSOR_SSD1351_CS "SSD1351 CS" +#define D_SENSOR_SSD1351_DC "SSD1351 DC" +#define D_SENSOR_RA8876_CS "RA8876 CS" +#define D_SENSOR_ST7789_CS "ST7789 CS" +#define D_SENSOR_ST7789_DC "ST7789 DC" +#define D_SENSOR_SSD1331_CS "SSD1331 CS" +#define D_SENSOR_SSD1331_DC "SSD1331 DC" +#define D_SENSOR_SDCARD_CS "SDCard CS" +#define D_SENSOR_WIEGAND_D0 "Wiegand D0" +#define D_SENSOR_WIEGAND_D1 "Wiegand D1" +#define D_SENSOR_NEOPOOL_TX "NeoPool Tx" +#define D_SENSOR_NEOPOOL_RX "NeoPool Rx" +#define D_SENSOR_VL53LXX_XSHUT "VL53LXX XSHUT" +#define D_SENSOR_TFMINIPLUS_TX "TFmini+ TX" +#define D_SENSOR_TFMINIPLUS_RX "TFmini+ RX" +#define D_SENSOR_ZEROCROSS "ZC Pulse" +#define D_SENSOR_HALLEFFECT "HallEffect" +#define D_SENSOR_EPD_DATA "EPD Data" +#define D_SENSOR_PCF8574_INT "PCF8574 Int" +#define D_SENSOR_MCP23XXX_INT "MCP23xxx Int" +#define D_SENSOR_MCP23SXX_CS "MCP23Sxx CS" +#define D_SENSOR_MCP2515_CS "MCP2515 CS" +#define D_SENSOR_HRG15_RX "HRG15 Rx" +#define D_SENSOR_HRG15_TX "HRG15 Tx" +#define D_SENSOR_VINDRIKTNING_RX "VINDRIKTNING" +#define D_SENSOR_BL6523_TX "BL6523 Tx" +#define D_SENSOR_BL6523_RX "BL6523 Rx" +#define D_SENSOR_HEARTBEAT "Heartbeat" +#define D_SENSOR_RESET "Reset" +#define D_GPIO_SHIFT595_SRCLK "74x595 SRCLK" +#define D_GPIO_SHIFT595_RCLK "74x595 RCLK" +#define D_GPIO_SHIFT595_OE "74x595 OE" +#define D_GPIO_SHIFT595_SER "74x595 SER" +#define D_GPIO_DINGTIAN_CLK "Dingtian CLK" +#define D_GPIO_DINGTIAN_SDI "Dingtian SDI" +#define D_GPIO_DINGTIAN_Q7 "Dingtian Q7" +#define D_GPIO_DINGTIAN_PL "Dingtian PL" +#define D_GPIO_DINGTIAN_OE "Dingtian OE" +#define D_GPIO_DINGTIAN_RCK "Dingtian RCK" +#define D_SENSOR_CM11_TX "CM110x TX" +#define D_SENSOR_CM11_RX "CM110x RX" +#define D_SENSOR_FLOWRATEMETER "Flowrate" +#define D_SENSOR_ME007_TRIG "ME007 Tri" +#define D_SENSOR_ME007_RX "ME007 Rx" +#define D_SENSOR_TUYAMCUBR_TX "TuyaMCUBr Tx" +#define D_SENSOR_TUYAMCUBR_RX "TuyaMCUBr Rx" +#define D_SENSOR_TWAI_TX "TWAI Tx" +#define D_SENSOR_TWAI_RX "TWAI Rx" +#define D_SENSOR_TWAI_BO "TWAI BusOff" +#define D_SENSOR_TWAI_CLK "TWAI ClkOut" +#define D_SENSOR_BIOPDU_PZEM0XX_TX "BioPDU PZEM0XX Tx" +#define D_SENSOR_BIOPDU_PZEM016_RX "BioPDU PZEM016 Rx" +#define D_SENSOR_BIOPDU_BIT "BioPDU Bit" +#define D_SENSOR_LOX_O2_RX "LoxO2 RX" +#define D_GPIO_MAGIC_SWITCH "MagicSwitch" +#define D_SENSOR_WOOLIIS_RX "Wooliis Rx" +#define D_SENSOR_C8_CO2_5K_RX "C8-CO2-5K Rx" +#define D_SENSOR_C8_CO2_5K_TX "C8-CO2-5K Tx" +#define D_SENSOR_MKSKYBLU_TX "MkSkyBlu Tx" +#define D_SENSOR_MKSKYBLU_RX "MkSkyBlu Rx" + +// Units +#define D_UNIT_AMPERE "A" +#define D_UNIT_CELSIUS "C" +#define D_UNIT_CENTIMETER "cm" +#define D_UNIT_DEGREE "°" +#define D_UNIT_FAHRENHEIT "F" +#define D_UNIT_FPS "FPS" +#define D_UNIT_HERTZ "Hz" +#define D_UNIT_HOUR "h" +#define D_UNIT_GALLONS "gal" +#define D_UNIT_GALLONS_PER_MIN "g/m" +#define D_UNIT_GRAM_PER_CUBIC_METER "g/m³" +#define D_UNIT_INCH_MERCURY "inHg" +#define D_UNIT_INCREMENTS "inc" +#define D_UNIT_KELVIN "K" +#define D_UNIT_KILOMETER "km" +#define D_UNIT_KILOGRAM "kg" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" +#define D_UNIT_KILOOHM "kΩ" +#define D_UNIT_KILOWATTHOUR "kWh" +#define D_UNIT_LITERS "L" +#define D_UNIT_LITERS_PER_MIN "L/m" +#define D_UNIT_LUX "lx" +#define D_UNIT_METER "m" +#define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m³" +#define D_UNIT_MICROMETER "µm" +#define D_UNIT_MICROSECOND "µs" +#define D_UNIT_MICROSIEMENS_PER_CM "µS/cm" +#define D_UNIT_MICROTESLA "µT" +#define D_UNIT_MILLIAMPERE "mA" +#define D_UNIT_MILLILITERS "ml" +#define D_UNIT_MILLIMETER "mm" +#define D_UNIT_MILLIMETER_MERCURY "mmHg" +#define D_UNIT_MILLISECOND "ms" +#define D_UNIT_MILLIVOLT "mV" +#define D_UNIT_MINUTE "Min" +#define D_UNIT_PARTS_PER_BILLION "ppb" +#define D_UNIT_PARTS_PER_DECILITER "ppd" +#define D_UNIT_PARTS_PER_MILLION "ppm" +#define D_UNIT_MILIGRAMS_PER_LITER "mg/L" +#define D_UNIT_PERCENT "%%" +#define D_UNIT_PRESSURE "hPa" +#define D_UNIT_SECOND "sec" +#define D_UNIT_SECTORS "sectors" +#define D_UNIT_VA "VA" +#define D_UNIT_VAR "var" +#define D_UNIT_VOLT "V" +#define D_UNIT_WATT "W" +#define D_UNIT_WATTHOUR "Wh" +#define D_UNIT_WATT_METER_QUADRAT "W/m²" +#define D_UNIT_LITER_PER_MINUTE "l/min" +#define D_UNIT_CUBICMETER_PER_HOUR "m³/h" +#define D_UNIT_CUBIC_METER "m³" + +#define D_NEW_ADDRESS "Setting address to" +#define D_OUT_OF_RANGE "Out of Range" +#define D_SENSOR_DETECTED "detected" + +//SDM220, SDM120, SDM72, LE01MR, SDM230 +#define D_EXPORT_POWER "Uitvoer krag" +#define D_IMPORT_POWER "Invoer krag" +#define D_PHASE_ANGLE "Fasehoek" +#define D_IMPORT_ACTIVE "Invoer aktief" +#define D_EXPORT_ACTIVE "Uitvoer aktief" +#define D_IMPORT_REACTIVE "Import reaktief" +#define D_EXPORT_REACTIVE "Uitvoer reaktief" +#define D_TOTAL_REACTIVE "Totaal reaktief" +#define D_UNIT_KWARH "kvarh" +#define D_UNIT_ANGLE "Deg" +#define D_TOTAL_ACTIVE "Totaal aktief" +#define D_RESETTABLE_TOTAL_ACTIVE "Totaal aktief (RST)" + +//SOLAXX1 +#define D_PV1_VOLTAGE "PV1 Spanning" +#define D_PV1_CURRENT "PV1 Stroom" +#define D_PV1_POWER "PV1 Krag" +#define D_PV2_VOLTAGE "PV2 Spanning" +#define D_PV2_CURRENT "PV2 Stroom" +#define D_PV2_POWER "PV2 Krag" +#define D_SOLAR_POWER "Sonkrag" +#define D_INVERTER_POWER "Omskakelaarkrag" +#define D_STATUS "Status" +#define D_SOLAX_MODE_0 "Wag" +#define D_SOLAX_MODE_1 "Nagaan" +#define D_SOLAX_MODE_2 "Werk" +#define D_SOLAX_MODE_3 "Mislukking" +#define D_SOLAX_MODE_4 "Permanent Failure" // to be translated +#define D_SOLAX_MODE_5 "Software Update" // to be translated +#define D_SOLAX_MODE_6 "Selftest" // to be translated +#define D_SOLAX_ERROR_0 "Geen foutkode nie" +#define D_SOLAX_ERROR_1 "Netspanning verlies fout" +#define D_SOLAX_ERROR_2 "Netspanning spanning fout" +#define D_SOLAX_ERROR_3 "Netspanning frekwensie fout" +#define D_SOLAX_ERROR_4 "Pv stroom fout" +#define D_SOLAX_ERROR_5 "Isolasiefout" +#define D_SOLAX_ERROR_6 "Storing by oormatige temperatuur" +#define D_SOLAX_ERROR_7 "Waaierstoring" +#define D_SOLAX_ERROR_8 "Ander toestelfout" + +//xdrv_10_scripter.ino +#define D_CONFIGURE_SCRIPT "Wysig skrif" +#define D_SCRIPT "wysig skrif" +#define D_SDCARD_UPLOAD "lêer oplaai" +#define D_UFSDIR "ufs vouer" +#define D_UPL_DONE "Klaar" +#define D_SCRIPT_CHARS_LEFT "karakters oor" +#define D_SCRIPT_CHARS_NO_MORE "nie meer karakters nie" +#define D_SCRIPT_DOWNLOAD "Aflaai" +#define D_SCRIPT_ENABLE "skrip inskakel" +#define D_SCRIPT_UPLOAD "Laai op" +#define D_SCRIPT_UPLOAD_FILES "Laai lêers op" + +//xdrv_50_filesystem.ino +#define D_MANAGE_FILE_SYSTEM "Bestuur lêerstelsel" +#define D_FS_SIZE "Grootte" +#define D_FS_FREE "Vry" +#define D_NEW_FILE "newfile.txt" +#define D_CREATE_NEW_FILE "Create and edit new file" +#define D_EDIT_FILE "Edit File" +#define D_CONFIRM_FILE_DEL "Confirm file deletion" +#define D_SHOW_HIDDEN_FILES "Show hidden files" + +//xsns_67_as3935.ino +#define D_AS3935_GAIN "versterking:" +#define D_AS3935_ENERGY "energie:" +#define D_AS3935_DISTANCE "afstand:" +#define D_AS3935_DISTURBER "steur:" +#define D_AS3935_VRMS "µVrms:" +#define D_AS3935_APRX "aprx.:" +#define D_AS3935_AWAY "weg" +#define D_AS3935_LIGHT "weerlig" +#define D_AS3935_OUT "weerlig buite bereik" +#define D_AS3935_NOT "afstand nie bepaal nie" +#define D_AS3935_ABOVE "weerlig oorhoofse" +#define D_AS3935_NOISE "geraas bespeur" +#define D_AS3935_DISTDET "steuring bespeur" +#define D_AS3935_INTNOEV "Onderbreek met geen geleentheid nie!" +#define D_AS3935_FLICKER "IRQ Pin flikker!" +#define D_AS3935_POWEROFF "Skakel af" +#define D_AS3935_NOMESS "luister..." +#define D_AS3935_ON "Aan" +#define D_AS3935_OFF "Uit" +#define D_AS3935_INDOORS "Binnenshuis" +#define D_AS3935_OUTDOORS "Buite" +#define D_AS3935_CAL_FAIL "kalibrasie het misluk" +#define D_AS3935_CAL_OK "kalibrasie ingestel op:" + +//xsns_68_opentherm.ino +#define D_SENSOR_BOILER_OT_RX "OpenTherm RX" +#define D_SENSOR_BOILER_OT_TX "OpenTherm TX" + +// xnrg_15_teleinfo Denky (Teleinfo) +#define D_CONTRACT "Kontrak" +#define D_POWER_LOAD "Kraglading" +#define D_CURRENT_TARIFF "Stroom tarief" +#define D_TARIFF "Tarief" +#define D_OVERLOAD "ADPS" +#define D_MAX_POWER "Max krag" +#define D_MAX_CURRENT "Max stroom" + +// xsns_79_as608.ino +#define D_FP_ENROLL_PLACEFINGER "Plaas vinger" +#define D_FP_ENROLL_REMOVEFINGER "Verwyder vinger" +#define D_FP_ENROLL_PLACESAMEFINGER "Plaas dieselfde vinger weer" +#define D_FP_ENROLL_RETRY "Fout, probeer dus weer" +#define D_FP_ENROLL_RESTART "Begin oor" +#define D_FP_ENROLL_ERROR "Fout" +#define D_FP_ENROLL_RESET "Stel terug" +#define D_FP_ENROLL_ACTIVE "Aktief" +#define D_FP_ENROLL_INACTIVE "Onaktief" +// Indexed by Adafruit_Fingerprint.h defines +#define D_FP_PACKETRECIEVEERR "Komms-fout" // 0x01 Error when receiving data package +#define D_FP_NOFINGER "Geen vinger op die sensor nie" // 0x02 No finger on the sensor +#define D_FP_IMAGEFAIL "Beeldfout" // 0x03 Failed to enroll the finger +#define D_FP_IMAGEMESS "Beeld te deurmekaar" // 0x06 Failed to generate character file due to overly disorderly fingerprint image +#define D_FP_FEATUREFAIL "Vingerafdruk te klein" // 0x07 Failed to generate character file due to the lack of character point or small fingerprint image +#define D_FP_NOMATCH "Nie opgewasse" // 0x08 Finger doesn't match +#define D_FP_NOTFOUND "Kon nie 'n ekwivalent vind nie" // 0x09 Failed to find matching finger +#define D_FP_ENROLLMISMATCH "Vingerafdruk stem nie ooreen nie" // 0x0A Failed to combine the character files +#define D_FP_BADLOCATION "Slegte ligging" // 0x0B Addressed PageID is beyond the finger library +#define D_FP_DBRANGEFAIL "DB-reeksfout" // 0x0C Error when reading template from library or invalid template +#define D_FP_UPLOADFEATUREFAIL "Fout by die oplaai van funksie" // 0x0D Error when uploading template +#define D_FP_PACKETRESPONSEFAIL "Fout van pakketrespons" // 0x0E Module failed to receive the following data packages +#define D_FP_UPLOADFAIL "Oplaaifout" // 0x0F Error when uploading image +#define D_FP_DELETEFAIL "Vee fout" // 0x10 Failed to delete the template +#define D_FP_DBCLEARFAIL "DB leegfout" // 0x11 Failed to clear finger library +#define D_FP_PASSFAIL "Wagwoordfout" // 0x13 Find whether the fingerprint passed or failed +#define D_FP_INVALIDIMAGE "Prent ongeldig" // 0x15 Failed to generate image because of lac of valid primary image +#define D_FP_FLASHERR "Flash skryffout" // 0x18 Error when writing flash +#define D_FP_INVALIDREG "Ongeldige nommer" // 0x1A Invalid register number +#define D_FP_ADDRCODE "Adres kode" // 0x20 Address code +#define D_FP_PASSVERIFY "Wagwoord geverifieer" // 0x21 Verify the fingerprint passed +#define D_FP_UNKNOWNERROR "Fout" // Any other error + +// xsns_90_hrg15.ino +#define D_HRG_VALID "Valid" +#define D_HRG_ACTIVE "Active" +#define D_HRG_EVENT "Event" +#define D_HRG_TOTAL "Total" +#define D_HRG_FLOWRATE "Flow Rate" + +// xsns_96_flowratemeter.ino +#define D_FLOWRATEMETER_NAME "Flowrate" +#define D_FLOWRATEMETER_AMOUNT_TODAY "Amount Today" +#define D_FLOWRATEMETER_DURATION_TODAY "Duration Today" + +// xsns_83_neopool.ino +#define D_NEOPOOL_MACH_NONE "NeoPool" // Machine names +#define D_NEOPOOL_MACH_HIDROLIFE "Hidrolife" +#define D_NEOPOOL_MACH_AQUASCENIC "Aquascenic" +#define D_NEOPOOL_MACH_OXILIFE "Oxilife" +#define D_NEOPOOL_MACH_BIONET "Bionet" +#define D_NEOPOOL_MACH_HIDRONISER "Hidroniser" +#define D_NEOPOOL_MACH_UVSCENIC "UVScenic" +#define D_NEOPOOL_MACH_STATION "Station" +#define D_NEOPOOL_MACH_BRILIX "Brilix" +#define D_NEOPOOL_MACH_GENERIC "Generic" +#define D_NEOPOOL_MACH_BAYROL "Bayrol" +#define D_NEOPOOL_MACH_HAY "Hay" +#define D_NEOPOOL_FILTRATION_MANUAL "Handmatig" // Filtration modes +#define D_NEOPOOL_FILTRATION_AUTO "Outomaties" +#define D_NEOPOOL_FILTRATION_HEATING "Verhitting" +#define D_NEOPOOL_FILTRATION_SMART "Slim" +#define D_NEOPOOL_FILTRATION_INTELLIGENT "Intelligent" +#define D_NEOPOOL_FILTRATION_BACKWASH "Terugspoel" +#define D_NEOPOOL_FILTRATION_NONE "" // Filtration speed level +#define D_NEOPOOL_FILTRATION_SLOW "stadig" +#define D_NEOPOOL_FILTRATION_MEDIUM "medium" +#define D_NEOPOOL_FILTRATION_FAST "vinnig" +#define D_NEOPOOL_TYPE "Tipe" // Sensor & relais names +#define D_NEOPOOL_REDOX "Redoks" +#define D_NEOPOOL_CHLORINE "Chloor" +#define D_NEOPOOL_CONDUCTIVITY "Geleidingsvermoë" +#define D_NEOPOOL_IONIZATION "Ionisering" +#define D_NEOPOOL_HYDROLYSIS "Hidrolise" +#define D_NEOPOOL_RELAY "Relais" +#define D_NEOPOOL_RELAY_FILTRATION "Filtrasie" // Relay assignment +#define D_NEOPOOL_RELAY_LIGHT "Lig" +#define D_NEOPOOL_RELAY_PH_ACID "Suurpomp" +#define D_NEOPOOL_RELAY_PH_BASE "Basispump" +#define D_NEOPOOL_RELAY_RX "Redoksvlak" +#define D_NEOPOOL_RELAY_CL "Chloorpomp" +#define D_NEOPOOL_RELAY_CD "Geleidingsvermoë" +#define D_NEOPOOL_RELAY_HEATING "Verhitting" +#define D_NEOPOOL_RELAY_UV "UV" +#define D_NEOPOOL_RELAY_VALVE "Valve" +#define D_NEOPOOL_RELAY_AUX "Aux" +#define D_NEOPOOL_TIME "Tyd" +#define D_NEOPOOL_FILT_MODE "Filtrasie" +#define D_NEOPOOL_CELL_RUNTIME "Cell runtime" +#define D_NEOPOOL_POLARIZATION "Pol" // Sensor status +#define D_NEOPOOL_PR_OFF "PrOff" +#define D_NEOPOOL_SETPOINT_OK "Oké" +#define D_NEOPOOL_COVER "Voorblad" +#define D_NEOPOOL_SHOCK "Skok" +#define D_NEOPOOL_STATUS_ON "ON" +#define D_NEOPOOL_STATUS_OFF "OFF" +#define D_NEOPOOL_STATUS_WAIT "WAIT" +#define D_NEOPOOL_STATUS_TANK "TANK" +#define D_NEOPOOL_STATUS_FLOW "Flow" +#define D_NEOPOOL_LOW "Laag" +#define D_NEOPOOL_FLOW1 "FL1" +#define D_NEOPOOL_FLOW2 "FL2" +#define D_NEOPOOL_PH_HIGH "te hoog" // ph Alarms +#define D_NEOPOOL_PH_LOW "te laag" +#define D_NEOPOOL_PUMP_TIME_EXCEEDED "pomptyd oorskry" + +// xsns_106_gdk101.ino +#define D_AVG_RAD_DOSE "Gemiddelde Stralingsdosis" +#define D_UNIT_US_H "µSv/h" + +// ixrv92_pipsolar.ino +#define D_SENSOR_PIPSOLAR_TX "Pipsolar TX" +#define D_SENSOR_PIPSOLAR_RX "Pipsolar RX" + +// xsns_102_ld2410.ino +#define D_MOVING_DISTANCE "Moving Distance" +#define D_STATIC_DISTANCE "Static Distance" +#define D_DETECT_DISTANCE "Detect Distance" +#define D_MOVING_ENERGY_T "Moving target" +#define D_STATIC_ENERGY_T "Static target" +#define D_LD2410_PIN_STATE "Output pin state" +#define D_LD2410_LIGHT "Light sensor" + +// xsns_115_wooliis.ino +#define D_IMPORT "Import" +#define D_EXPORT "Export" +#define D_CHARGING "Charging" +#define D_CAPACITY "Capacity" + +// xnrg_25_v9240.ino +#define D_SENSOR_V9240_TX "V9240 TX" +#define D_SENSOR_V9240_RX "V9240 RX" + +#endif // _LANGUAGE_AF_AF_H_ diff --git a/tasmota/tasmota_xdrv_driver/xdrv_68_zerocrossDimmer.ino b/tasmota/tasmota_xdrv_driver/xdrv_68_zerocrossDimmer.ino index da7fc794e..5d9189972 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_68_zerocrossDimmer.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_68_zerocrossDimmer.ino @@ -1,327 +1,327 @@ -/* - xdrv_68_zerocrossdimmer.ino - Zero-Cross Dimmer support for Tasmota - - Copyright (C) 2023 Stefan Bode - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifdef USE_AC_ZERO_CROSS_DIMMER -/*********************************************************************************************\ - * Zero-Cross AC Dimmer PMM 1..xx use -\*********************************************************************************************/ - -#define XDRV_68 68 - -static const uint8_t TRIGGER_PERIOD = 75; - -#define ZCDIMMERSET_SHOW 1 -//#define ZC_DEBUG 1 - -struct AC_ZERO_CROSS_DIMMER { - uint32_t cycle_time_us; // Time (in micros()) of last ZC signal - uint32_t crossed_zero_at; // Time (in micros()) of last ZC signal - bool timer_iterrupt_started = false; // verification of the interrupt running - bool dimmer_in_use = false; // Check if interrupt has to be run. Is stopped if all lights off - bool fallingEdgeDimmer = false; // Work as a fallwing edge dimmer - bool triggered[MAX_PWMS]; - uint32_t enable_time_us[MAX_PWMS]; // Time since last ZC pulse to enable gate pin. 0 means no disable. - uint32_t disable_time_us[MAX_PWMS]; // 99% of cycle time - uint32_t lastlight[MAX_PWMS]; // Store the light value. Set 1 if controlled through ZCDimmerSet - uint16_t detailpower[MAX_PWMS]; // replaces dimmer and light controll 0..10000. required savedata 0. - uint32_t accurracy[MAX_PWMS]; // offset of the time to fire the triac and the real time when it fired - uint32_t intr_counter = 0; // counter internally on interrerupt calls - uint32_t missed_zero_cross; // count up all missed Zero-cross events. - uint8_t actual_tigger_Period = TRIGGER_PERIOD; // copy of tigger period to change during runtime -} ac_zero_cross_dimmer; - - -#ifdef ESP32 - static hw_timer_t *dimmer_timer = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) -#endif - -#define D_PRFX_ZCDIMMER "ZCDimmer" -#define D_CMND_DIMMERSET "Set" // Set percent as float value for dimmer -#define D_CMND_GATEENABLE "GateTime" // Override the GATE ON time DEBUG PURPOSE - -const char kZCDimmerCommands[] PROGMEM = D_PRFX_ZCDIMMER "|" D_CMND_DIMMERSET "|" D_CMND_GATEENABLE; - -void (* const ZCDimmerCommand[])(void) PROGMEM = { - &CmndZCDimmerSet//,&CmndZCGateEnableTime - }; - -extern "C" void IRAM_ATTR ACDimmerZeroCross(uint32_t time) { - ac_zero_cross_dimmer.dimmer_in_use = false; - ac_zero_cross_dimmer.cycle_time_us = time - ac_zero_cross_dimmer.crossed_zero_at; - ac_zero_cross_dimmer.crossed_zero_at = time; - for (uint8_t i=0; i < MAX_PWMS; i++) { - if (Pin(GPIO_PWM1, i) == -1) continue; - digitalWrite(Pin(GPIO_PWM1, i), LOW ^ ac_zero_cross_dimmer.fallingEdgeDimmer); - ac_zero_cross_dimmer.dimmer_in_use |= ac_zero_cross_dimmer.lastlight[i] > 0; - ac_zero_cross_dimmer.triggered[i] = false; - } -} - -void ACDimmerInit() -{ - for (uint8_t i = 0 ; i < 5; i++) { - ac_zero_cross_dimmer.detailpower[i] = Settings->zcdimmerset[i]; - ac_zero_cross_dimmer.fallingEdgeDimmer = Settings->flag6.zcfallingedge; - } -} - -extern "C" void IRAM_ATTR ACDimmerTimer_intr() { - - uint32_t time_since_zc = micros() - ac_zero_cross_dimmer.crossed_zero_at; - // If no ZC signal received yet. - if (ac_zero_cross_dimmer.crossed_zero_at == 0) return; - -#ifdef ZC_DEBUG - ac_zero_cross_dimmer.intr_counter++; - // Check for missed Zero-Cross event. Single failure will correct - if (time_since_zc > 10100) { - ac_zero_cross_dimmer.crossed_zero_at += ac_zero_cross_dimmer.cycle_time_us; - ac_zero_cross_dimmer.missed_zero_cross++; - time_since_zc += ac_zero_cross_dimmer.cycle_time_us; - } -#endif - ac_zero_cross_dimmer.actual_tigger_Period = TRIGGER_PERIOD; - for (uint8_t i = 0 ; i < MAX_PWMS; i++ ) { - if (Pin(GPIO_PWM1, i) == -1) continue; - - if (time_since_zc + TRIGGER_PERIOD + 30 >= ac_zero_cross_dimmer.enable_time_us[i]){ - // Very close to the fire event. Loop the last µseconds to wait. -#ifdef ESP8266 - // on ESP8266 we can change dynamically the trigger interval. - ac_zero_cross_dimmer.actual_tigger_Period = tmin(ac_zero_cross_dimmer.actual_tigger_Period*2,ac_zero_cross_dimmer.enable_time_us[i] - time_since_zc); -#endif -#ifdef ESP32 - while (time_since_zc < ac_zero_cross_dimmer.enable_time_us[i]) { - time_since_zc = micros() - ac_zero_cross_dimmer.crossed_zero_at; - } -#endif - if (time_since_zc+5 >= ac_zero_cross_dimmer.enable_time_us[i] && !ac_zero_cross_dimmer.triggered[i] ) { - digitalWrite(Pin(GPIO_PWM1, i), HIGH ^ ac_zero_cross_dimmer.fallingEdgeDimmer ); - ac_zero_cross_dimmer.triggered[i] = true; - ac_zero_cross_dimmer.accurracy[i] = time_since_zc-ac_zero_cross_dimmer.enable_time_us[i]; - } - if (time_since_zc >= ac_zero_cross_dimmer.disable_time_us[i]) { - digitalWrite(Pin(GPIO_PWM1, i), LOW ^ ac_zero_cross_dimmer.fallingEdgeDimmer ); - } - } - } -} - -#ifdef ESP8266 -extern "C" uint32_t IRAM_ATTR ACDimmerTimer_intr_ESP8266() { - ACDimmerTimer_intr(); - return ac_zero_cross_dimmer.actual_tigger_Period * 80; -} -#endif // ESP8266 - -void ACDimmerInterruptDisable(bool disable) -{ - AddLog(LOG_LEVEL_INFO, PSTR("ZCD: Zero-CrossDimmer enabled: %d"),!disable); - ac_zero_cross_dimmer.timer_iterrupt_started = !disable; - if (disable) { - //stop the interrupt -#ifdef ESP32 - if (dimmer_timer != nullptr) { -#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) - timerStop(dimmer_timer); -#else // ESP_ARDUINO_VERSION_MAJOR >= 3 - timerAlarmDisable(dimmer_timer); -#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 - } -#endif - } else { - for (uint8_t i = 0 ; i < MAX_PWMS; i++) { - if (Pin(GPIO_PWM1, i) != -1) { - pinMode(Pin(GPIO_PWM1, i), OUTPUT); - AddLog(LOG_LEVEL_INFO, PSTR("ZCD: Zero-CrossDimmer Pin %d set"),Pin(GPIO_PWM1, i)); - } - } -#ifdef ESP32 -#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) - if (dimmer_timer == nullptr) { - dimmer_timer = timerBegin(1000000); // 1 MHz - timerAttachInterrupt(dimmer_timer, &ACDimmerTimer_intr); - // For ESP32, we can't use dynamic interval calculation because the timerX functions - // are not callable from ISR (placed in flash storage). - // Here we just use an interrupt firing every 75 µs. - timerAlarm(dimmer_timer, TRIGGER_PERIOD, true, 0); - } - timerStart(dimmer_timer); -#else // ESP_ARDUINO_VERSION_MAJOR >= 3 - if (dimmer_timer == nullptr) { - // 80 Divider -> 1 count=1µs - dimmer_timer = timerBegin(0, 80, true); - timerAttachInterrupt(dimmer_timer, &ACDimmerTimer_intr, true); - // For ESP32, we can't use dynamic interval calculation because the timerX functions - // are not callable from ISR (placed in flash storage). - // Here we just use an interrupt firing every 75 µs. - timerAlarmWrite(dimmer_timer, TRIGGER_PERIOD , true); - } - timerAlarmEnable(dimmer_timer); -#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 -#endif - } -} - -void ACDimmerControllTrigger(void) { -#ifdef ESP32 - if (ac_zero_cross_dimmer.timer_iterrupt_started != ac_zero_cross_dimmer.dimmer_in_use) { - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ZCD: ZeroEnable %d --> %d ... change..."),ac_zero_cross_dimmer.timer_iterrupt_started, ac_zero_cross_dimmer.dimmer_in_use); - ACDimmerInterruptDisable(!ac_zero_cross_dimmer.dimmer_in_use); - } -#endif - for (uint8_t i = 0; i < MAX_PWMS; i++){ - if (Pin(GPIO_PWM1, i) == -1) continue; - ac_zero_cross_dimmer.disable_time_us[i] = (ac_zero_cross_dimmer.cycle_time_us * 99) / 100; - if (ac_zero_cross_dimmer.detailpower[i]){ - ac_zero_cross_dimmer.lastlight[i] = changeUIntScale(ac_zero_cross_dimmer.detailpower[i]/10, 0, 1000, 0, 1023); - } else { - ac_zero_cross_dimmer.lastlight[i] = Light.fade_running ? Light.fade_cur_10[i] : Light.fade_start_10[i]; - } - ac_zero_cross_dimmer.enable_time_us[i] = (ac_zero_cross_dimmer.cycle_time_us * (1023 - ac_zero_cross_power(ac_zero_cross_dimmer.lastlight[i]))) / 1023; - if (ac_zero_cross_dimmer.enable_time_us[i] > ac_zero_cross_dimmer.disable_time_us[i]) { - // do not set HIGH near to the zero cross - ac_zero_cross_dimmer.enable_time_us[i] = 99999; - } -#ifdef ESP32 - if (ac_zero_cross_dimmer.detailpower[i]){ - float state = (float)(1 - (ac_zero_cross_dimmer.detailpower[i]/10000.0)); - //state = std::acos(1 - (2 * state)) / 3.14159 * ac_zero_cross_dimmer.cycle_time_us; - state = std::acos(1 - (2 * state)) / 3.14159 * ac_zero_cross_dimmer.cycle_time_us; - //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ZCD: Float2: %*_f"),0,&state); - ac_zero_cross_dimmer.enable_time_us[i] = (uint32_t)state; - } -#endif - - } - -} - -void ACDimmerLogging(void) -{ - bool alarmEnabled = false; - uint32_t timercounter = ac_zero_cross_dimmer.intr_counter; - -#ifdef ESP32 - if (dimmer_timer != nullptr) { -#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) - alarmEnabled = true; // we assume it's started, there is no API to check whether it's running - timercounter = (uint32_t)timerRead(dimmer_timer); -#else // ESP_ARDUINO_VERSION_MAJOR >= 3 - alarmEnabled = timerAlarmEnabled(dimmer_timer); - timercounter = (uint32_t)timerRead(dimmer_timer); -#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 - } -#endif - - AddLog(LOG_LEVEL_DEBUG, PSTR("ZCD: ZeroEnable %d -> %d, Alarm %d, intr: %ld, cycle time: %ld µs, missed zc %ld"), - ac_zero_cross_dimmer.dimmer_in_use, ac_zero_cross_dimmer.timer_iterrupt_started, alarmEnabled, timercounter, - ac_zero_cross_dimmer.cycle_time_us, ac_zero_cross_dimmer.missed_zero_cross - ); - for (uint8_t i = 0; i < MAX_PWMS; i++){ - if (Pin(GPIO_PWM1, i) == -1) continue; - - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ZCD: PWM[%d] en: %ld µs, dis: %ld µs, fade: %d, cur: %d, end: %d, lastlight: %d, acc: %ld"), - i+1, ac_zero_cross_dimmer.enable_time_us[i], ac_zero_cross_dimmer.disable_time_us[i], - Light.fade_cur_10[i], Light.fade_start_10[i], Light.fade_end_10[i], ac_zero_cross_dimmer.lastlight[i], - ac_zero_cross_dimmer.accurracy[i] - ); - if (ac_zero_cross_dimmer.accurracy[i]) ac_zero_cross_dimmer.accurracy[i]=0; - } -} - -#ifdef USE_WEBSERVER -#ifdef ZCDIMMERSET_SHOW -void ACDimmerShow(void) -{ - char c_ZCDimmerSetBuffer[8]; - for (uint8_t i = 0; i < MAX_PWMS; i++){ - if (Pin(GPIO_PWM1, i) == -1) continue; - if (ac_zero_cross_dimmer.detailpower[i]){ - dtostrfd(ac_zero_cross_dimmer.detailpower[i]/100.0, 2, c_ZCDimmerSetBuffer); - WSContentSend_PD(PSTR("{s}ZCDimmer%d{m}%s %%{e}"), i+1, c_ZCDimmerSetBuffer); - } - } -} -#endif // ZCDIMMERSET_SHOW -#endif // USE_WEBSERVER - -/*********************************************************************************************\ - * Commands -\*********************************************************************************************/ - -void CmndZCDimmerSet(void) -{ - if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_PWMS)) { - if (XdrvMailbox.data_len > 0) { - Settings->zcdimmerset[XdrvMailbox.index-1] = ac_zero_cross_dimmer.detailpower[XdrvMailbox.index-1] = (uint16_t)(100 * CharToFloat(XdrvMailbox.data)); - } - ResponseCmndIdxFloat((float)(ac_zero_cross_dimmer.detailpower[XdrvMailbox.index-1]) / 100, 2); - } -} - -/*********************************************************************************************\ - * Interface -\*********************************************************************************************/ - -bool Xdrv68(uint32_t function) -{ - bool result = false; - if (Settings->flag4.zerocross_dimmer) { - switch (function) { - case FUNC_INIT: - ACDimmerInit(); -#ifdef ESP32 - //ACDimmerInterruptDisable(false); -#endif -#ifdef ESP8266 - setTimer1Callback(&ACDimmerTimer_intr_ESP8266); -#endif - break; - case FUNC_EVERY_SECOND: - ACDimmerLogging(); - break; - case FUNC_EVERY_100_MSECOND: - ACDimmerControllTrigger(); - break; - case FUNC_INTERRUPT_STOP: - ACDimmerInterruptDisable(true); - break; - case FUNC_INTERRUPT_START: - ACDimmerInterruptDisable(false); - break; - case FUNC_COMMAND: - result = DecodeCommand(kZCDimmerCommands, ZCDimmerCommand); - break; -#ifdef USE_WEBSERVER -#ifdef ZCDIMMERSET_SHOW - case FUNC_WEB_SENSOR: - ACDimmerShow(); - break; -#endif // ZCDIMMERSET_SHOW -#endif // USE_WEBSERVER - case FUNC_ACTIVE: - result = true; - break; - } - } - return result; -} - -#endif // USE_AC_ZERO_CROSS_DIMMER +/* + xdrv_68_zerocrossdimmer.ino - Zero-Cross Dimmer support for Tasmota + + Copyright (C) 2023 Stefan Bode + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef USE_AC_ZERO_CROSS_DIMMER +/*********************************************************************************************\ + * Zero-Cross AC Dimmer PMM 1..xx use +\*********************************************************************************************/ + +#define XDRV_68 68 + +static const uint8_t TRIGGER_PERIOD = 75; + +#define ZCDIMMERSET_SHOW 1 +//#define ZC_DEBUG 1 + +struct AC_ZERO_CROSS_DIMMER { + uint32_t cycle_time_us; // Time (in micros()) of last ZC signal + uint32_t crossed_zero_at; // Time (in micros()) of last ZC signal + bool timer_iterrupt_started = false; // verification of the interrupt running + bool dimmer_in_use = false; // Check if interrupt has to be run. Is stopped if all lights off + bool fallingEdgeDimmer = false; // Work as a fallwing edge dimmer + bool triggered[MAX_PWMS]; + uint32_t enable_time_us[MAX_PWMS]; // Time since last ZC pulse to enable gate pin. 0 means no disable. + uint32_t disable_time_us[MAX_PWMS]; // 99% of cycle time + uint32_t lastlight[MAX_PWMS]; // Store the light value. Set 1 if controlled through ZCDimmerSet + uint16_t detailpower[MAX_PWMS]; // replaces dimmer and light controll 0..10000. required savedata 0. + uint32_t accurracy[MAX_PWMS]; // offset of the time to fire the triac and the real time when it fired + uint32_t intr_counter = 0; // counter internally on interrerupt calls + uint32_t missed_zero_cross; // count up all missed Zero-cross events. + uint8_t actual_tigger_Period = TRIGGER_PERIOD; // copy of tigger period to change during runtime +} ac_zero_cross_dimmer; + + +#ifdef ESP32 + static hw_timer_t *dimmer_timer = nullptr; // NOLINT(cppcoreguidelines-avoid-non-const-global-variables) +#endif + +#define D_PRFX_ZCDIMMER "ZCDimmer" +#define D_CMND_DIMMERSET "Set" // Set percent as float value for dimmer +#define D_CMND_GATEENABLE "GateTime" // Override the GATE ON time DEBUG PURPOSE + +const char kZCDimmerCommands[] PROGMEM = D_PRFX_ZCDIMMER "|" D_CMND_DIMMERSET "|" D_CMND_GATEENABLE; + +void (* const ZCDimmerCommand[])(void) PROGMEM = { + &CmndZCDimmerSet//,&CmndZCGateEnableTime + }; + +extern "C" void IRAM_ATTR ACDimmerZeroCross(uint32_t time) { + ac_zero_cross_dimmer.dimmer_in_use = false; + ac_zero_cross_dimmer.cycle_time_us = time - ac_zero_cross_dimmer.crossed_zero_at; + ac_zero_cross_dimmer.crossed_zero_at = time; + for (uint8_t i=0; i < MAX_PWMS; i++) { + if (Pin(GPIO_PWM1, i) == -1) continue; + digitalWrite(Pin(GPIO_PWM1, i), LOW ^ ac_zero_cross_dimmer.fallingEdgeDimmer); + ac_zero_cross_dimmer.dimmer_in_use |= ac_zero_cross_dimmer.lastlight[i] > 0; + ac_zero_cross_dimmer.triggered[i] = false; + } +} + +void ACDimmerInit() +{ + for (uint8_t i = 0 ; i < 5; i++) { + ac_zero_cross_dimmer.detailpower[i] = Settings->zcdimmerset[i]; + ac_zero_cross_dimmer.fallingEdgeDimmer = Settings->flag6.zcfallingedge; + } +} + +extern "C" void IRAM_ATTR ACDimmerTimer_intr() { + + uint32_t time_since_zc = micros() - ac_zero_cross_dimmer.crossed_zero_at; + // If no ZC signal received yet. + if (ac_zero_cross_dimmer.crossed_zero_at == 0) return; + +#ifdef ZC_DEBUG + ac_zero_cross_dimmer.intr_counter++; + // Check for missed Zero-Cross event. Single failure will correct + if (time_since_zc > 10100) { + ac_zero_cross_dimmer.crossed_zero_at += ac_zero_cross_dimmer.cycle_time_us; + ac_zero_cross_dimmer.missed_zero_cross++; + time_since_zc += ac_zero_cross_dimmer.cycle_time_us; + } +#endif + ac_zero_cross_dimmer.actual_tigger_Period = TRIGGER_PERIOD; + for (uint8_t i = 0 ; i < MAX_PWMS; i++ ) { + if (Pin(GPIO_PWM1, i) == -1) continue; + + if (time_since_zc + TRIGGER_PERIOD + 30 >= ac_zero_cross_dimmer.enable_time_us[i]){ + // Very close to the fire event. Loop the last µseconds to wait. +#ifdef ESP8266 + // on ESP8266 we can change dynamically the trigger interval. + ac_zero_cross_dimmer.actual_tigger_Period = tmin(ac_zero_cross_dimmer.actual_tigger_Period*2,ac_zero_cross_dimmer.enable_time_us[i] - time_since_zc); +#endif +#ifdef ESP32 + while (time_since_zc < ac_zero_cross_dimmer.enable_time_us[i]) { + time_since_zc = micros() - ac_zero_cross_dimmer.crossed_zero_at; + } +#endif + if (time_since_zc+5 >= ac_zero_cross_dimmer.enable_time_us[i] && !ac_zero_cross_dimmer.triggered[i] ) { + digitalWrite(Pin(GPIO_PWM1, i), HIGH ^ ac_zero_cross_dimmer.fallingEdgeDimmer ); + ac_zero_cross_dimmer.triggered[i] = true; + ac_zero_cross_dimmer.accurracy[i] = time_since_zc-ac_zero_cross_dimmer.enable_time_us[i]; + } + if (time_since_zc >= ac_zero_cross_dimmer.disable_time_us[i]) { + digitalWrite(Pin(GPIO_PWM1, i), LOW ^ ac_zero_cross_dimmer.fallingEdgeDimmer ); + } + } + } +} + +#ifdef ESP8266 +extern "C" uint32_t IRAM_ATTR ACDimmerTimer_intr_ESP8266() { + ACDimmerTimer_intr(); + return ac_zero_cross_dimmer.actual_tigger_Period * 80; +} +#endif // ESP8266 + +void ACDimmerInterruptDisable(bool disable) +{ + AddLog(LOG_LEVEL_INFO, PSTR("ZCD: Zero-CrossDimmer enabled: %d"),!disable); + ac_zero_cross_dimmer.timer_iterrupt_started = !disable; + if (disable) { + //stop the interrupt +#ifdef ESP32 + if (dimmer_timer != nullptr) { +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) + timerStop(dimmer_timer); +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 + timerAlarmDisable(dimmer_timer); +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 + } +#endif + } else { + for (uint8_t i = 0 ; i < MAX_PWMS; i++) { + if (Pin(GPIO_PWM1, i) != -1) { + pinMode(Pin(GPIO_PWM1, i), OUTPUT); + AddLog(LOG_LEVEL_INFO, PSTR("ZCD: Zero-CrossDimmer Pin %d set"),Pin(GPIO_PWM1, i)); + } + } +#ifdef ESP32 +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) + if (dimmer_timer == nullptr) { + dimmer_timer = timerBegin(1000000); // 1 MHz + timerAttachInterrupt(dimmer_timer, &ACDimmerTimer_intr); + // For ESP32, we can't use dynamic interval calculation because the timerX functions + // are not callable from ISR (placed in flash storage). + // Here we just use an interrupt firing every 75 µs. + timerAlarm(dimmer_timer, TRIGGER_PERIOD, true, 0); + } + timerStart(dimmer_timer); +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 + if (dimmer_timer == nullptr) { + // 80 Divider -> 1 count=1µs + dimmer_timer = timerBegin(0, 80, true); + timerAttachInterrupt(dimmer_timer, &ACDimmerTimer_intr, true); + // For ESP32, we can't use dynamic interval calculation because the timerX functions + // are not callable from ISR (placed in flash storage). + // Here we just use an interrupt firing every 75 µs. + timerAlarmWrite(dimmer_timer, TRIGGER_PERIOD , true); + } + timerAlarmEnable(dimmer_timer); +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 +#endif + } +} + +void ACDimmerControllTrigger(void) { +#ifdef ESP32 + if (ac_zero_cross_dimmer.timer_iterrupt_started != ac_zero_cross_dimmer.dimmer_in_use) { + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ZCD: ZeroEnable %d --> %d ... change..."),ac_zero_cross_dimmer.timer_iterrupt_started, ac_zero_cross_dimmer.dimmer_in_use); + ACDimmerInterruptDisable(!ac_zero_cross_dimmer.dimmer_in_use); + } +#endif + for (uint8_t i = 0; i < MAX_PWMS; i++){ + if (Pin(GPIO_PWM1, i) == -1) continue; + ac_zero_cross_dimmer.disable_time_us[i] = (ac_zero_cross_dimmer.cycle_time_us * 99) / 100; + if (ac_zero_cross_dimmer.detailpower[i]){ + ac_zero_cross_dimmer.lastlight[i] = changeUIntScale(ac_zero_cross_dimmer.detailpower[i]/10, 0, 1000, 0, 1023); + } else { + ac_zero_cross_dimmer.lastlight[i] = Light.fade_running ? Light.fade_cur_10[i] : Light.fade_start_10[i]; + } + ac_zero_cross_dimmer.enable_time_us[i] = (ac_zero_cross_dimmer.cycle_time_us * (1023 - ac_zero_cross_power(ac_zero_cross_dimmer.lastlight[i]))) / 1023; + if (ac_zero_cross_dimmer.enable_time_us[i] > ac_zero_cross_dimmer.disable_time_us[i]) { + // do not set HIGH near to the zero cross + ac_zero_cross_dimmer.enable_time_us[i] = 99999; + } +#ifdef ESP32 + if (ac_zero_cross_dimmer.detailpower[i]){ + float state = (float)(1 - (ac_zero_cross_dimmer.detailpower[i]/10000.0)); + //state = std::acos(1 - (2 * state)) / 3.14159 * ac_zero_cross_dimmer.cycle_time_us; + state = std::acos(1 - (2 * state)) / 3.14159 * ac_zero_cross_dimmer.cycle_time_us; + //AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ZCD: Float2: %*_f"),0,&state); + ac_zero_cross_dimmer.enable_time_us[i] = (uint32_t)state; + } +#endif + + } + +} + +void ACDimmerLogging(void) +{ + bool alarmEnabled = false; + uint32_t timercounter = ac_zero_cross_dimmer.intr_counter; + +#ifdef ESP32 + if (dimmer_timer != nullptr) { +#if ( defined(ESP_ARDUINO_VERSION_MAJOR) && (ESP_ARDUINO_VERSION_MAJOR >= 3) ) + alarmEnabled = true; // we assume it's started, there is no API to check whether it's running + timercounter = (uint32_t)timerRead(dimmer_timer); +#else // ESP_ARDUINO_VERSION_MAJOR >= 3 + alarmEnabled = timerAlarmEnabled(dimmer_timer); + timercounter = (uint32_t)timerRead(dimmer_timer); +#endif // ESP_ARDUINO_VERSION_MAJOR >= 3 + } +#endif + + AddLog(LOG_LEVEL_DEBUG, PSTR("ZCD: ZeroEnable %d -> %d, Alarm %d, intr: %ld, cycle time: %ld µs, missed zc %ld"), + ac_zero_cross_dimmer.dimmer_in_use, ac_zero_cross_dimmer.timer_iterrupt_started, alarmEnabled, timercounter, + ac_zero_cross_dimmer.cycle_time_us, ac_zero_cross_dimmer.missed_zero_cross + ); + for (uint8_t i = 0; i < MAX_PWMS; i++){ + if (Pin(GPIO_PWM1, i) == -1) continue; + + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR("ZCD: PWM[%d] en: %ld µs, dis: %ld µs, fade: %d, cur: %d, end: %d, lastlight: %d, acc: %ld"), + i+1, ac_zero_cross_dimmer.enable_time_us[i], ac_zero_cross_dimmer.disable_time_us[i], + Light.fade_cur_10[i], Light.fade_start_10[i], Light.fade_end_10[i], ac_zero_cross_dimmer.lastlight[i], + ac_zero_cross_dimmer.accurracy[i] + ); + if (ac_zero_cross_dimmer.accurracy[i]) ac_zero_cross_dimmer.accurracy[i]=0; + } +} + +#ifdef USE_WEBSERVER +#ifdef ZCDIMMERSET_SHOW +void ACDimmerShow(void) +{ + char c_ZCDimmerSetBuffer[8]; + for (uint8_t i = 0; i < MAX_PWMS; i++){ + if (Pin(GPIO_PWM1, i) == -1) continue; + if (ac_zero_cross_dimmer.detailpower[i]){ + dtostrfd(ac_zero_cross_dimmer.detailpower[i]/100.0, 2, c_ZCDimmerSetBuffer); + WSContentSend_PD(PSTR("{s}ZCDimmer%d{m}%s %%{e}"), i+1, c_ZCDimmerSetBuffer); + } + } +} +#endif // ZCDIMMERSET_SHOW +#endif // USE_WEBSERVER + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +void CmndZCDimmerSet(void) +{ + if ((XdrvMailbox.index > 0) && (XdrvMailbox.index <= MAX_PWMS)) { + if (XdrvMailbox.data_len > 0) { + Settings->zcdimmerset[XdrvMailbox.index-1] = ac_zero_cross_dimmer.detailpower[XdrvMailbox.index-1] = (uint16_t)(100 * CharToFloat(XdrvMailbox.data)); + } + ResponseCmndIdxFloat((float)(ac_zero_cross_dimmer.detailpower[XdrvMailbox.index-1]) / 100, 2); + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv68(uint32_t function) +{ + bool result = false; + if (Settings->flag4.zerocross_dimmer) { + switch (function) { + case FUNC_INIT: + ACDimmerInit(); +#ifdef ESP32 + //ACDimmerInterruptDisable(false); +#endif +#ifdef ESP8266 + setTimer1Callback(&ACDimmerTimer_intr_ESP8266); +#endif + break; + case FUNC_EVERY_SECOND: + ACDimmerLogging(); + break; + case FUNC_EVERY_100_MSECOND: + ACDimmerControllTrigger(); + break; + case FUNC_INTERRUPT_STOP: + ACDimmerInterruptDisable(true); + break; + case FUNC_INTERRUPT_START: + ACDimmerInterruptDisable(false); + break; + case FUNC_COMMAND: + result = DecodeCommand(kZCDimmerCommands, ZCDimmerCommand); + break; +#ifdef USE_WEBSERVER +#ifdef ZCDIMMERSET_SHOW + case FUNC_WEB_SENSOR: + ACDimmerShow(); + break; +#endif // ZCDIMMERSET_SHOW +#endif // USE_WEBSERVER + case FUNC_ACTIVE: + result = true; + break; + } + } + return result; +} + +#endif // USE_AC_ZERO_CROSS_DIMMER diff --git a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino index be93d5c35..8c9134f6f 100644 --- a/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino +++ b/tasmota/tasmota_xdrv_driver/xdrv_82_esp32_ethernet.ino @@ -1,471 +1,471 @@ -/* - xdrv_82_esp32_ethernet.ino - ESP32 (PoE) ethernet support for Tasmota - - Copyright (C) 2021 Theo Arends - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program 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 General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . -*/ - -#ifdef ESP32 -#include "sdkconfig.h" -#ifdef CONFIG_ETH_ENABLED -#ifdef USE_ETHERNET -/*********************************************************************************************\ - * Ethernet support for ESP32 - * - * Dedicated fixed Phy pins (EMAC) - * GPIO17 - EMAC_CLK_OUT_180 - * GPIO19 - EMAC_TXD0(RMII) - * GPIO21 - EMAC_TX_EN(RMII) - * GPIO22 - EMAC_TXD1(RMII) - * GPIO25 - EMAC_RXD0(RMII) - * GPIO26 - EMAC_RXD1(RMII) - * GPIO27 - EMAC_RX_CRS_DV - * - * {"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} - * GPIO12 = ETH POWER - * GPIO18 = ETH MDIO - * GPIO23 = ETH MDC - * #define ETH_TYPE 0 // LAN8720 - * #define ETH_CLKMODE ETH_CLOCK_GPIO17_OUT - * #define ETH_ADDRESS 0 - * - * {"NAME":"wESP32","GPIO":[0,0,1,0,1,1,0,0,1,1,1,1,5568,5600,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} - * GPIO16 = ETH MDC - * GPIO17 = ETH MDIO - * #define ETH_TYPE 0 // LAN8720 - * #define ETH_CLKMODE ETH_CLOCK_GPIO0_IN - * #define ETH_ADDRESS 0 - * - * {"NAME":"WT32-ETH01","GPIO":[1,1,1,1,1,1,0,0,1,0,1,1,3840,576,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,1],"FLAG":0,"BASE":1} - * GPIO16 = Force Hi - * GPIO18 = ETH MDIO - * GPIO23 = ETH MDC - * #define ETH_TYPE 0 // LAN8720 - * #define ETH_CLKMODE ETH_CLOCK_GPIO0_IN - * #define ETH_ADDRESS 1 - * - * Used SPI - * SPI_MOSI - * SPI_MISO - * SPI_CLK - * SPI_RST = Tasmota ETH_POWER - * SPI_IRQ = Tasmota ETH_MDIO - * SPI_CS = Tasmota ETH_MDC -\*********************************************************************************************/ - -#define XDRV_82 82 - -/* -// Olimex ESP32-PoE -#define ETH_CLKMODE ETH_CLOCK_GPIO17_OUT -#define ETH_POWER_PIN 12 - -//******************************************************************************************** - -#ifndef ETH_ADDRESS -#define ETH_ADDRESS 0 // ETH.h uint8_t: 0 = PHY0 .. 31 = PHY31 -#endif - -#ifndef ETH_TYPE -#define ETH_TYPE 0 // 0 = LAN8720, 1 = TLK110/IP101, 2 = RTL8201, 3 = DP83848, 4 = DM9051, 5 = KSZ8081, 6 = KSZ8041, 7 = JL1101, 8 = W5500, 9 = KSZ8851 -#endif - -#ifndef ETH_CLKMODE -#define ETH_CLKMODE ETH_CLOCK_GPIO0_IN // ETH.h eth_clock_mode_t: 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT -#endif -*/ - -#include - -#define ETH_USES_SPI 0x80 // Use the highest significant bit to mark SPI Ethernet - -const uint8_t eth_type_xtable[] = { -#if CONFIG_ETH_USE_ESP32_EMAC - ETH_PHY_LAN8720, // 0 = LAN8720 - ETH_PHY_TLK110, // 1 = TLK110/IP101 - ETH_PHY_RTL8201, // 2 = RTL8201 - ETH_PHY_DP83848, // 3 = DP83848 - -#if CONFIG_ETH_SPI_ETHERNET_DM9051 - ETH_PHY_DM9051 | ETH_USES_SPI, // 4 = 10 = DM9051 -#else - 0, // 4 = 10 = DM9051 -#endif - - ETH_PHY_KSZ8081, // 5 = KSZ8081 - ETH_PHY_KSZ8041, // 6 = KSZ8041 - ETH_PHY_JL1101, // 7 = JL1101 -#else - 0, // 0 = LAN8720 - 0, // 1 = TLK110/IP101 - 0, // 2 = RTL8201 - 0, // 3 = DP83848 - -#if CONFIG_ETH_SPI_ETHERNET_DM9051 - ETH_PHY_DM9051 | ETH_USES_SPI, // 4 = 10 = DM9051 -#else - 0, // 4 = 10 = DM9051 -#endif - - 0, // 5 = KSZ8081 - 0, // 6 = KSZ8041 - 0, // 7 = JL1101 -#endif // CONFIG_ETH_USE_ESP32_EMAC - -#if CONFIG_ETH_SPI_ETHERNET_W5500 - ETH_PHY_W5500 | ETH_USES_SPI, // 8 = W5500 -#else - 0, // 8 = W5500 -#endif - -#if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL - ETH_PHY_KSZ8851 | ETH_USES_SPI, // 9 = KSZ8851 -#else - 0, // 9 = KSZ8851 -#endif -}; -char eth_hostname[sizeof(TasmotaGlobal.hostname)]; -uint8_t eth_config_change; - -extern esp_netif_t* get_esp_interface_netif(esp_interface_t interface); - -void EthernetEvent(arduino_event_t *event); -void EthernetEvent(arduino_event_t *event) { - switch (event->event_id) { - case ARDUINO_EVENT_ETH_START: - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH D_ATTEMPTING_CONNECTION)); - ETH.setHostname(eth_hostname); - break; - - case ARDUINO_EVENT_ETH_CONNECTED: - AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ETH D_CONNECTED " at %dMbps%s, Mac %s, Hostname %s"), - ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : "", - ETH.macAddress().c_str(), eth_hostname - ); - - // AddLog(LOG_LEVEL_DEBUG, D_LOG_ETH "ETH.enableIPV6() -> %i", ETH.enableIPV6()); - break; - - case ARDUINO_EVENT_ETH_GOT_IP: - // AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH "Mac %s, IPAddress %_I, Hostname %s"), - // ETH.macAddress().c_str(), (uint32_t)ETH.localIP(), eth_hostname); - Settings->eth_ipv4_address[1] = (uint32_t)ETH.gatewayIP(); - Settings->eth_ipv4_address[2] = (uint32_t)ETH.subnetMask(); - if (0 == Settings->eth_ipv4_address[0]) { // At this point ETH.dnsIP() are NOT correct unless DHCP - Settings->eth_ipv4_address[3] = (uint32_t)ETH.dnsIP(); - Settings->eth_ipv4_address[4] = (uint32_t)ETH.dnsIP(1); - } - TasmotaGlobal.rules_flag.eth_connected = 1; - TasmotaGlobal.global_state.eth_down = 0; -#ifndef FIRMWARE_MINIMAL - AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: IPv4 %_I, mask %_I, gateway %_I"), - event->event_info.got_ip.ip_info.ip.addr, - event->event_info.got_ip.ip_info.netmask.addr, - event->event_info.got_ip.ip_info.gw.addr); -#endif // FIRMWARE_MINIMAL - WiFiHelper::scrubDNS(); // internal calls to reconnect can zero the DNS servers, save DNS for future use - break; - -#ifdef USE_IPV6 - case ARDUINO_EVENT_ETH_GOT_IP6: - { - ip_addr_t ip_addr6; - ip_addr_copy_from_ip6(ip_addr6, event->event_info.got_ip6.ip6_info.ip); - IPAddress addr(&ip_addr6); -#ifndef FIRMWARE_MINIMAL - AddLog(LOG_LEVEL_DEBUG, PSTR("%s: IPv6 %s %s"), - event->event_id == ARDUINO_EVENT_ETH_GOT_IP6 ? "ETH" : "WIF", - IPv6isLocal(addr) ? PSTR("Local") : PSTR("Global"), addr.toString().c_str()); -#endif // FIRMWARE_MINIMAL - if (!IPv6isLocal(addr)) { // declare network up on IPv6 - TasmotaGlobal.rules_flag.eth_connected = 1; - TasmotaGlobal.global_state.eth_down = 0; - } - WiFiHelper::scrubDNS(); // internal calls to reconnect can zero the DNS servers, save DNS for future use - } - break; -#endif // USE_IPV6 - - case ARDUINO_EVENT_ETH_DISCONNECTED: - AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ETH "Disconnected")); - TasmotaGlobal.rules_flag.eth_disconnected = 1; - TasmotaGlobal.global_state.eth_down = 1; - break; - - case ARDUINO_EVENT_ETH_STOP: - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH "Stopped")); - TasmotaGlobal.global_state.eth_down = 1; - break; - - default: - break; - } -} - -void EthernetSetIp(void) { - // Set static IP - ETH.config(Settings->eth_ipv4_address[0], // IPAddress local_ip - Settings->eth_ipv4_address[1], // IPAddress gateway - Settings->eth_ipv4_address[2], // IPAddress subnet - Settings->eth_ipv4_address[3], // IPAddress dns1 - Settings->eth_ipv4_address[4]); // IPAddress dns2 -} - -void EthernetInit(void) { - if (!Settings->flag4.network_ethernet) { return; } - - int32_t eth_type = (Settings->eth_type < sizeof(eth_type_xtable)) ? eth_type_xtable[Settings->eth_type] : 0; // make sure we don't overflow - bool eth_uses_spi = (eth_type & ETH_USES_SPI); - eth_type = eth_type & 0x7F; // remove SPI flag -#if CONFIG_ETH_USE_ESP32_EMAC - if (WT32_ETH01 == TasmotaGlobal.module_type) { - Settings->eth_address = 1; // EthAddress - Settings->eth_type = ETH_PHY_LAN8720; // EthType 0 = LAN8720 - Settings->eth_clk_mode = 0; // EthClockMode 0 = ETH_CLOCK_GPIO0_IN - } -#endif // CONFIG_ETH_USE_ESP32_EMAC - - if (eth_uses_spi) { - // Uses SPI Ethernet and needs at least SPI CS being ETH MDC - if (!PinUsed(GPIO_ETH_PHY_MDC, GPIO_ANY)) { -#ifndef FIRMWARE_MINIMAL - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ETH "No ETH MDC as SPI CS GPIO defined")); -#endif // FIRMWARE_MINIMAL - return; - } - } else { - // Native ESP32 - if (!PinUsed(GPIO_ETH_PHY_MDC, GPIO_ANY) && !PinUsed(GPIO_ETH_PHY_MDIO)) { // && should be || but keep for backward compatibility -#ifndef FIRMWARE_MINIMAL - AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ETH "No ETH MDC and ETH MDIO GPIO defined")); -#endif // FIRMWARE_MINIMAL - return; - } - } - - eth_config_change = 0; - - strlcpy(eth_hostname, TasmotaGlobal.hostname, sizeof(eth_hostname) -5); // Make sure there is room for "-eth" - strcat(eth_hostname, "-eth"); - - WiFi.onEvent(EthernetEvent); - - int eth_mdc = Pin(GPIO_ETH_PHY_MDC, GPIO_ANY); // Ethernet SPI CS (chip select) - uint32_t spi_bus = GetPin(eth_mdc) - AGPIO(GPIO_ETH_PHY_MDC); // 0 or 1 - int eth_mdio = Pin(GPIO_ETH_PHY_MDIO); // Ethernet SPI IRQ - int eth_power = Pin(GPIO_ETH_PHY_POWER); // Ethernet SPI RST - -#ifdef USE_IPV6 - ETH.enableIPv6(); // enable Link-Local -#endif // USE_IPV6 - - bool init_ok = false; - if (!eth_uses_spi) { -#if CONFIG_ETH_USE_ESP32_EMAC - #ifdef CONFIG_IDF_TARGET_ESP32P4 - init_ok = (ETH.begin((eth_phy_type_t)eth_type, Settings->eth_address, eth_mdc, eth_mdio, eth_power, EMAC_CLK_EXT_IN)); - #else - init_ok = (ETH.begin((eth_phy_type_t)eth_type, Settings->eth_address, eth_mdc, eth_mdio, eth_power, (eth_clock_mode_t)Settings->eth_clk_mode)); - #endif //CONFIG_IDF_TARGET_ESP32P4 -#endif // CONFIG_ETH_USE_ESP32_EMAC - } else { - // ETH_SPI_SUPPORTS_CUSTOM - // SPISettings(ETH_PHY_SPI_FREQ_MHZ * 1000 * 1000, MSBFIRST, SPI_MODE0); // 20MHz -/* - SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1); - init_ok = (ETH.begin((eth_phy_type_t)eth_type, Settings->eth_address, eth_mdc, eth_mdio, eth_power, SPI, ETH_PHY_SPI_FREQ_MHZ)); -*/ -#if CONFIG_SOC_SPI_PERIPH_NUM > 2 - if ((1 == spi_bus) && TasmotaGlobal.spi_enabled2) - init_ok = (ETH.begin((eth_phy_type_t)eth_type, Settings->eth_address, eth_mdc, eth_mdio, eth_power, SPI3_HOST, Pin(GPIO_SPI_CLK, 1), Pin(GPIO_SPI_MISO, 1), Pin(GPIO_SPI_MOSI, 1), ETH_PHY_SPI_FREQ_MHZ)); - else -#endif - init_ok = (ETH.begin((eth_phy_type_t)eth_type, Settings->eth_address, eth_mdc, eth_mdio, eth_power, SPI2_HOST, Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), ETH_PHY_SPI_FREQ_MHZ)); - } - if (!init_ok) { - AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH "Bad EthType %i or init error"),eth_type); - return; - }; - - if (Settings->eth_ipv4_address[0]) { - EthernetSetIp(); // Set static IP - } -} - -IPAddress EthernetLocalIP(void) { - return ETH.localIP(); -} - -// Check to see if we have any routable IP address -// IPv4 has always priority -// Copy the value of the IP if pointer provided (optional) -bool EthernetGetIP(IPAddress *ip) { -#ifdef USE_IPV6 - if ((uint32_t)ETH.localIP() != 0) { - if (ip != nullptr) { *ip = ETH.localIP(); } - return true; - } - IPAddress lip; - if (EthernetGetIPv6(&lip)) { - if (ip != nullptr) { *ip = lip; } - return true; - } - if (ip != nullptr) { *ip = IPAddress(); } - return false; -#else - // IPv4 only - if (ip != nullptr) { *ip = ETH.localIP(); } - return (uint32_t)ETH.localIP() != 0; -#endif // USE_IPV6 -} -bool EthernetHasIP(void) { - return EthernetGetIP(nullptr); -} -String EthernetGetIPStr(void) { - IPAddress ip; - if (EthernetGetIP(&ip)) { - return ip.toString(); - } else { - return String(); - } -} - -char* EthernetHostname(void) { - return eth_hostname; -} - -String EthernetMacAddress(void) { - return ETH.macAddress(); -} - -void EthernetConfigChange(void) { - if (eth_config_change) { - eth_config_change--; - if (!eth_config_change) { - EthernetSetIp(); - } - } -} - -/*********************************************************************************************\ - * Commands -\*********************************************************************************************/ - -#define D_CMND_ETHADDRESS "Address" -#define D_CMND_ETHTYPE "Type" -#define D_CMND_ETHCLOCKMODE "ClockMode" -#define D_CMND_ETHIPADDRESS D_CMND_IPADDRESS -#define D_CMND_ETHGATEWAY D_JSON_GATEWAY -#define D_CMND_ETHNETMASK D_JSON_SUBNETMASK -#define D_CMND_ETHDNS D_JSON_DNSSERVER - -const char kEthernetCommands[] PROGMEM = "Eth|" // Prefix - "ernet|" D_CMND_ETHADDRESS "|" D_CMND_ETHTYPE "|" D_CMND_ETHCLOCKMODE "|" - D_CMND_ETHIPADDRESS "|" D_CMND_ETHGATEWAY "|" D_CMND_ETHNETMASK "|" D_CMND_ETHDNS ; - -void (* const EthernetCommand[])(void) PROGMEM = { - &CmndEthernet, &CmndEthAddress, &CmndEthType, &CmndEthClockMode, - &CmndEthSetIpConfig, &CmndEthSetIpConfig, &CmndEthSetIpConfig, &CmndEthSetIpConfig }; - -#define ETH_PARAM_OFFSET 4 // Offset of command index in above table of first CmndEthIpConfig - -void CmndEthernet(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { - Settings->flag4.network_ethernet = XdrvMailbox.payload; - TasmotaGlobal.restart_flag = 2; - } - ResponseCmndStateText(Settings->flag4.network_ethernet); -} - -void CmndEthAddress(void) { - if ((XdrvMailbox.payload >= -1) && (XdrvMailbox.payload <= 31)) { - Settings->eth_address = XdrvMailbox.payload; - TasmotaGlobal.restart_flag = 2; - } - ResponseCmndNumber(Settings->eth_address); -} - -void CmndEthType(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < sizeof(eth_type_xtable))) { - Settings->eth_type = XdrvMailbox.payload; - TasmotaGlobal.restart_flag = 2; - } - ResponseCmndNumber(Settings->eth_type); -} - -void CmndEthClockMode(void) { - if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 3)) { - Settings->eth_clk_mode = XdrvMailbox.payload; - TasmotaGlobal.restart_flag = 2; - } - ResponseCmndNumber(Settings->eth_clk_mode); -} - -void CmndEthSetIpConfig(void) { - uint32_t param_id = XdrvMailbox.command_code -ETH_PARAM_OFFSET; - - char cmnd_idx[2] = { 0 }; - if (3 == param_id) { // EthDnsServer - if ((XdrvMailbox.index < 1) || (XdrvMailbox.index > 2)) { - XdrvMailbox.index = 1; - } - cmnd_idx[0] = '0' + XdrvMailbox.index; - param_id += XdrvMailbox.index -1; // EthDnsServer2 - } - - if (XdrvMailbox.data_len) { - uint32_t ipv4_address; - if (ParseIPv4(&ipv4_address, XdrvMailbox.data)) { - Settings->eth_ipv4_address[param_id] = ipv4_address; - eth_config_change = 2; - } - } - - char network_address[22] = { 0 }; - if (0 == param_id) { - if (!Settings->eth_ipv4_address[0]) { - ext_snprintf_P(network_address, sizeof(network_address), PSTR(" (%_I)"), (uint32_t)ETH.localIP()); - } - } - Response_P(PSTR("{\"%s%s\":\"%_I%s\"}"), XdrvMailbox.command, cmnd_idx, Settings->eth_ipv4_address[param_id], network_address); -} - -/*********************************************************************************************\ - * Interface -\*********************************************************************************************/ - -bool Xdrv82(uint32_t function) { - bool result = false; - - switch (function) { - case FUNC_EVERY_SECOND: - EthernetConfigChange(); - break; - case FUNC_COMMAND: - result = DecodeCommand(kEthernetCommands, EthernetCommand); - break; - case FUNC_INIT: - EthernetInit(); - break; - case FUNC_ACTIVE: - result = true; - break; - } - return result; -} - -#endif // USE_ETHERNET -#endif // CONFIG_IDF_TARGET_ESP32C2 -#endif // ESP32 +/* + xdrv_82_esp32_ethernet.ino - ESP32 (PoE) ethernet support for Tasmota + + Copyright (C) 2021 Theo Arends + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +*/ + +#ifdef ESP32 +#include "sdkconfig.h" +#ifdef CONFIG_ETH_ENABLED +#ifdef USE_ETHERNET +/*********************************************************************************************\ + * Ethernet support for ESP32 + * + * Dedicated fixed Phy pins (EMAC) + * GPIO17 - EMAC_CLK_OUT_180 + * GPIO19 - EMAC_TXD0(RMII) + * GPIO21 - EMAC_TX_EN(RMII) + * GPIO22 - EMAC_TXD1(RMII) + * GPIO25 - EMAC_RXD0(RMII) + * GPIO26 - EMAC_RXD1(RMII) + * GPIO27 - EMAC_RX_CRS_DV + * + * {"NAME":"Olimex ESP32-PoE","GPIO":[1,1,1,1,1,1,0,0,5536,1,1,1,1,0,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} + * GPIO12 = ETH POWER + * GPIO18 = ETH MDIO + * GPIO23 = ETH MDC + * #define ETH_TYPE 0 // LAN8720 + * #define ETH_CLKMODE ETH_CLOCK_GPIO17_OUT + * #define ETH_ADDRESS 0 + * + * {"NAME":"wESP32","GPIO":[0,0,1,0,1,1,0,0,1,1,1,1,5568,5600,1,0,0,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,0,0,1],"FLAG":0,"BASE":1} + * GPIO16 = ETH MDC + * GPIO17 = ETH MDIO + * #define ETH_TYPE 0 // LAN8720 + * #define ETH_CLKMODE ETH_CLOCK_GPIO0_IN + * #define ETH_ADDRESS 0 + * + * {"NAME":"WT32-ETH01","GPIO":[1,1,1,1,1,1,0,0,1,0,1,1,3840,576,5600,0,0,0,0,5568,0,0,0,0,0,0,0,0,1,1,0,1,1,0,0,1],"FLAG":0,"BASE":1} + * GPIO16 = Force Hi + * GPIO18 = ETH MDIO + * GPIO23 = ETH MDC + * #define ETH_TYPE 0 // LAN8720 + * #define ETH_CLKMODE ETH_CLOCK_GPIO0_IN + * #define ETH_ADDRESS 1 + * + * Used SPI + * SPI_MOSI + * SPI_MISO + * SPI_CLK + * SPI_RST = Tasmota ETH_POWER + * SPI_IRQ = Tasmota ETH_MDIO + * SPI_CS = Tasmota ETH_MDC +\*********************************************************************************************/ + +#define XDRV_82 82 + +/* +// Olimex ESP32-PoE +#define ETH_CLKMODE ETH_CLOCK_GPIO17_OUT +#define ETH_POWER_PIN 12 + +//******************************************************************************************** + +#ifndef ETH_ADDRESS +#define ETH_ADDRESS 0 // ETH.h uint8_t: 0 = PHY0 .. 31 = PHY31 +#endif + +#ifndef ETH_TYPE +#define ETH_TYPE 0 // 0 = LAN8720, 1 = TLK110/IP101, 2 = RTL8201, 3 = DP83848, 4 = DM9051, 5 = KSZ8081, 6 = KSZ8041, 7 = JL1101, 8 = W5500, 9 = KSZ8851 +#endif + +#ifndef ETH_CLKMODE +#define ETH_CLKMODE ETH_CLOCK_GPIO0_IN // ETH.h eth_clock_mode_t: 0 = ETH_CLOCK_GPIO0_IN, 1 = ETH_CLOCK_GPIO0_OUT, 2 = ETH_CLOCK_GPIO16_OUT, 3 = ETH_CLOCK_GPIO17_OUT +#endif +*/ + +#include + +#define ETH_USES_SPI 0x80 // Use the highest significant bit to mark SPI Ethernet + +const uint8_t eth_type_xtable[] = { +#if CONFIG_ETH_USE_ESP32_EMAC + ETH_PHY_LAN8720, // 0 = LAN8720 + ETH_PHY_TLK110, // 1 = TLK110/IP101 + ETH_PHY_RTL8201, // 2 = RTL8201 + ETH_PHY_DP83848, // 3 = DP83848 + +#if CONFIG_ETH_SPI_ETHERNET_DM9051 + ETH_PHY_DM9051 | ETH_USES_SPI, // 4 = 10 = DM9051 +#else + 0, // 4 = 10 = DM9051 +#endif + + ETH_PHY_KSZ8081, // 5 = KSZ8081 + ETH_PHY_KSZ8041, // 6 = KSZ8041 + ETH_PHY_JL1101, // 7 = JL1101 +#else + 0, // 0 = LAN8720 + 0, // 1 = TLK110/IP101 + 0, // 2 = RTL8201 + 0, // 3 = DP83848 + +#if CONFIG_ETH_SPI_ETHERNET_DM9051 + ETH_PHY_DM9051 | ETH_USES_SPI, // 4 = 10 = DM9051 +#else + 0, // 4 = 10 = DM9051 +#endif + + 0, // 5 = KSZ8081 + 0, // 6 = KSZ8041 + 0, // 7 = JL1101 +#endif // CONFIG_ETH_USE_ESP32_EMAC + +#if CONFIG_ETH_SPI_ETHERNET_W5500 + ETH_PHY_W5500 | ETH_USES_SPI, // 8 = W5500 +#else + 0, // 8 = W5500 +#endif + +#if CONFIG_ETH_SPI_ETHERNET_KSZ8851SNL + ETH_PHY_KSZ8851 | ETH_USES_SPI, // 9 = KSZ8851 +#else + 0, // 9 = KSZ8851 +#endif +}; +char eth_hostname[sizeof(TasmotaGlobal.hostname)]; +uint8_t eth_config_change; + +extern esp_netif_t* get_esp_interface_netif(esp_interface_t interface); + +void EthernetEvent(arduino_event_t *event); +void EthernetEvent(arduino_event_t *event) { + switch (event->event_id) { + case ARDUINO_EVENT_ETH_START: + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH D_ATTEMPTING_CONNECTION)); + ETH.setHostname(eth_hostname); + break; + + case ARDUINO_EVENT_ETH_CONNECTED: + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ETH D_CONNECTED " at %dMbps%s, Mac %s, Hostname %s"), + ETH.linkSpeed(), (ETH.fullDuplex()) ? " Full Duplex" : "", + ETH.macAddress().c_str(), eth_hostname + ); + + // AddLog(LOG_LEVEL_DEBUG, D_LOG_ETH "ETH.enableIPV6() -> %i", ETH.enableIPV6()); + break; + + case ARDUINO_EVENT_ETH_GOT_IP: + // AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH "Mac %s, IPAddress %_I, Hostname %s"), + // ETH.macAddress().c_str(), (uint32_t)ETH.localIP(), eth_hostname); + Settings->eth_ipv4_address[1] = (uint32_t)ETH.gatewayIP(); + Settings->eth_ipv4_address[2] = (uint32_t)ETH.subnetMask(); + if (0 == Settings->eth_ipv4_address[0]) { // At this point ETH.dnsIP() are NOT correct unless DHCP + Settings->eth_ipv4_address[3] = (uint32_t)ETH.dnsIP(); + Settings->eth_ipv4_address[4] = (uint32_t)ETH.dnsIP(1); + } + TasmotaGlobal.rules_flag.eth_connected = 1; + TasmotaGlobal.global_state.eth_down = 0; +#ifndef FIRMWARE_MINIMAL + AddLog(LOG_LEVEL_DEBUG, PSTR("ETH: IPv4 %_I, mask %_I, gateway %_I"), + event->event_info.got_ip.ip_info.ip.addr, + event->event_info.got_ip.ip_info.netmask.addr, + event->event_info.got_ip.ip_info.gw.addr); +#endif // FIRMWARE_MINIMAL + WiFiHelper::scrubDNS(); // internal calls to reconnect can zero the DNS servers, save DNS for future use + break; + +#ifdef USE_IPV6 + case ARDUINO_EVENT_ETH_GOT_IP6: + { + ip_addr_t ip_addr6; + ip_addr_copy_from_ip6(ip_addr6, event->event_info.got_ip6.ip6_info.ip); + IPAddress addr(&ip_addr6); +#ifndef FIRMWARE_MINIMAL + AddLog(LOG_LEVEL_DEBUG, PSTR("%s: IPv6 %s %s"), + event->event_id == ARDUINO_EVENT_ETH_GOT_IP6 ? "ETH" : "WIF", + IPv6isLocal(addr) ? PSTR("Local") : PSTR("Global"), addr.toString().c_str()); +#endif // FIRMWARE_MINIMAL + if (!IPv6isLocal(addr)) { // declare network up on IPv6 + TasmotaGlobal.rules_flag.eth_connected = 1; + TasmotaGlobal.global_state.eth_down = 0; + } + WiFiHelper::scrubDNS(); // internal calls to reconnect can zero the DNS servers, save DNS for future use + } + break; +#endif // USE_IPV6 + + case ARDUINO_EVENT_ETH_DISCONNECTED: + AddLog(LOG_LEVEL_INFO, PSTR(D_LOG_ETH "Disconnected")); + TasmotaGlobal.rules_flag.eth_disconnected = 1; + TasmotaGlobal.global_state.eth_down = 1; + break; + + case ARDUINO_EVENT_ETH_STOP: + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH "Stopped")); + TasmotaGlobal.global_state.eth_down = 1; + break; + + default: + break; + } +} + +void EthernetSetIp(void) { + // Set static IP + ETH.config(Settings->eth_ipv4_address[0], // IPAddress local_ip + Settings->eth_ipv4_address[1], // IPAddress gateway + Settings->eth_ipv4_address[2], // IPAddress subnet + Settings->eth_ipv4_address[3], // IPAddress dns1 + Settings->eth_ipv4_address[4]); // IPAddress dns2 +} + +void EthernetInit(void) { + if (!Settings->flag4.network_ethernet) { return; } + + int32_t eth_type = (Settings->eth_type < sizeof(eth_type_xtable)) ? eth_type_xtable[Settings->eth_type] : 0; // make sure we don't overflow + bool eth_uses_spi = (eth_type & ETH_USES_SPI); + eth_type = eth_type & 0x7F; // remove SPI flag +#if CONFIG_ETH_USE_ESP32_EMAC + if (WT32_ETH01 == TasmotaGlobal.module_type) { + Settings->eth_address = 1; // EthAddress + Settings->eth_type = ETH_PHY_LAN8720; // EthType 0 = LAN8720 + Settings->eth_clk_mode = 0; // EthClockMode 0 = ETH_CLOCK_GPIO0_IN + } +#endif // CONFIG_ETH_USE_ESP32_EMAC + + if (eth_uses_spi) { + // Uses SPI Ethernet and needs at least SPI CS being ETH MDC + if (!PinUsed(GPIO_ETH_PHY_MDC, GPIO_ANY)) { +#ifndef FIRMWARE_MINIMAL + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ETH "No ETH MDC as SPI CS GPIO defined")); +#endif // FIRMWARE_MINIMAL + return; + } + } else { + // Native ESP32 + if (!PinUsed(GPIO_ETH_PHY_MDC, GPIO_ANY) && !PinUsed(GPIO_ETH_PHY_MDIO)) { // && should be || but keep for backward compatibility +#ifndef FIRMWARE_MINIMAL + AddLog(LOG_LEVEL_DEBUG_MORE, PSTR(D_LOG_ETH "No ETH MDC and ETH MDIO GPIO defined")); +#endif // FIRMWARE_MINIMAL + return; + } + } + + eth_config_change = 0; + + strlcpy(eth_hostname, TasmotaGlobal.hostname, sizeof(eth_hostname) -5); // Make sure there is room for "-eth" + strcat(eth_hostname, "-eth"); + + WiFi.onEvent(EthernetEvent); + + int eth_mdc = Pin(GPIO_ETH_PHY_MDC, GPIO_ANY); // Ethernet SPI CS (chip select) + uint32_t spi_bus = GetPin(eth_mdc) - AGPIO(GPIO_ETH_PHY_MDC); // 0 or 1 + int eth_mdio = Pin(GPIO_ETH_PHY_MDIO); // Ethernet SPI IRQ + int eth_power = Pin(GPIO_ETH_PHY_POWER); // Ethernet SPI RST + +#ifdef USE_IPV6 + ETH.enableIPv6(); // enable Link-Local +#endif // USE_IPV6 + + bool init_ok = false; + if (!eth_uses_spi) { +#if CONFIG_ETH_USE_ESP32_EMAC + #ifdef CONFIG_IDF_TARGET_ESP32P4 + init_ok = (ETH.begin((eth_phy_type_t)eth_type, Settings->eth_address, eth_mdc, eth_mdio, eth_power, EMAC_CLK_EXT_IN)); + #else + init_ok = (ETH.begin((eth_phy_type_t)eth_type, Settings->eth_address, eth_mdc, eth_mdio, eth_power, (eth_clock_mode_t)Settings->eth_clk_mode)); + #endif //CONFIG_IDF_TARGET_ESP32P4 +#endif // CONFIG_ETH_USE_ESP32_EMAC + } else { + // ETH_SPI_SUPPORTS_CUSTOM + // SPISettings(ETH_PHY_SPI_FREQ_MHZ * 1000 * 1000, MSBFIRST, SPI_MODE0); // 20MHz +/* + SPI.begin(Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), -1); + init_ok = (ETH.begin((eth_phy_type_t)eth_type, Settings->eth_address, eth_mdc, eth_mdio, eth_power, SPI, ETH_PHY_SPI_FREQ_MHZ)); +*/ +#if CONFIG_SOC_SPI_PERIPH_NUM > 2 + if ((1 == spi_bus) && TasmotaGlobal.spi_enabled2) + init_ok = (ETH.begin((eth_phy_type_t)eth_type, Settings->eth_address, eth_mdc, eth_mdio, eth_power, SPI3_HOST, Pin(GPIO_SPI_CLK, 1), Pin(GPIO_SPI_MISO, 1), Pin(GPIO_SPI_MOSI, 1), ETH_PHY_SPI_FREQ_MHZ)); + else +#endif + init_ok = (ETH.begin((eth_phy_type_t)eth_type, Settings->eth_address, eth_mdc, eth_mdio, eth_power, SPI2_HOST, Pin(GPIO_SPI_CLK), Pin(GPIO_SPI_MISO), Pin(GPIO_SPI_MOSI), ETH_PHY_SPI_FREQ_MHZ)); + } + if (!init_ok) { + AddLog(LOG_LEVEL_DEBUG, PSTR(D_LOG_ETH "Bad EthType %i or init error"),eth_type); + return; + }; + + if (Settings->eth_ipv4_address[0]) { + EthernetSetIp(); // Set static IP + } +} + +IPAddress EthernetLocalIP(void) { + return ETH.localIP(); +} + +// Check to see if we have any routable IP address +// IPv4 has always priority +// Copy the value of the IP if pointer provided (optional) +bool EthernetGetIP(IPAddress *ip) { +#ifdef USE_IPV6 + if ((uint32_t)ETH.localIP() != 0) { + if (ip != nullptr) { *ip = ETH.localIP(); } + return true; + } + IPAddress lip; + if (EthernetGetIPv6(&lip)) { + if (ip != nullptr) { *ip = lip; } + return true; + } + if (ip != nullptr) { *ip = IPAddress(); } + return false; +#else + // IPv4 only + if (ip != nullptr) { *ip = ETH.localIP(); } + return (uint32_t)ETH.localIP() != 0; +#endif // USE_IPV6 +} +bool EthernetHasIP(void) { + return EthernetGetIP(nullptr); +} +String EthernetGetIPStr(void) { + IPAddress ip; + if (EthernetGetIP(&ip)) { + return ip.toString(); + } else { + return String(); + } +} + +char* EthernetHostname(void) { + return eth_hostname; +} + +String EthernetMacAddress(void) { + return ETH.macAddress(); +} + +void EthernetConfigChange(void) { + if (eth_config_change) { + eth_config_change--; + if (!eth_config_change) { + EthernetSetIp(); + } + } +} + +/*********************************************************************************************\ + * Commands +\*********************************************************************************************/ + +#define D_CMND_ETHADDRESS "Address" +#define D_CMND_ETHTYPE "Type" +#define D_CMND_ETHCLOCKMODE "ClockMode" +#define D_CMND_ETHIPADDRESS D_CMND_IPADDRESS +#define D_CMND_ETHGATEWAY D_JSON_GATEWAY +#define D_CMND_ETHNETMASK D_JSON_SUBNETMASK +#define D_CMND_ETHDNS D_JSON_DNSSERVER + +const char kEthernetCommands[] PROGMEM = "Eth|" // Prefix + "ernet|" D_CMND_ETHADDRESS "|" D_CMND_ETHTYPE "|" D_CMND_ETHCLOCKMODE "|" + D_CMND_ETHIPADDRESS "|" D_CMND_ETHGATEWAY "|" D_CMND_ETHNETMASK "|" D_CMND_ETHDNS ; + +void (* const EthernetCommand[])(void) PROGMEM = { + &CmndEthernet, &CmndEthAddress, &CmndEthType, &CmndEthClockMode, + &CmndEthSetIpConfig, &CmndEthSetIpConfig, &CmndEthSetIpConfig, &CmndEthSetIpConfig }; + +#define ETH_PARAM_OFFSET 4 // Offset of command index in above table of first CmndEthIpConfig + +void CmndEthernet(void) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 1)) { + Settings->flag4.network_ethernet = XdrvMailbox.payload; + TasmotaGlobal.restart_flag = 2; + } + ResponseCmndStateText(Settings->flag4.network_ethernet); +} + +void CmndEthAddress(void) { + if ((XdrvMailbox.payload >= -1) && (XdrvMailbox.payload <= 31)) { + Settings->eth_address = XdrvMailbox.payload; + TasmotaGlobal.restart_flag = 2; + } + ResponseCmndNumber(Settings->eth_address); +} + +void CmndEthType(void) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < sizeof(eth_type_xtable))) { + Settings->eth_type = XdrvMailbox.payload; + TasmotaGlobal.restart_flag = 2; + } + ResponseCmndNumber(Settings->eth_type); +} + +void CmndEthClockMode(void) { + if ((XdrvMailbox.payload >= 0) && (XdrvMailbox.payload <= 3)) { + Settings->eth_clk_mode = XdrvMailbox.payload; + TasmotaGlobal.restart_flag = 2; + } + ResponseCmndNumber(Settings->eth_clk_mode); +} + +void CmndEthSetIpConfig(void) { + uint32_t param_id = XdrvMailbox.command_code -ETH_PARAM_OFFSET; + + char cmnd_idx[2] = { 0 }; + if (3 == param_id) { // EthDnsServer + if ((XdrvMailbox.index < 1) || (XdrvMailbox.index > 2)) { + XdrvMailbox.index = 1; + } + cmnd_idx[0] = '0' + XdrvMailbox.index; + param_id += XdrvMailbox.index -1; // EthDnsServer2 + } + + if (XdrvMailbox.data_len) { + uint32_t ipv4_address; + if (ParseIPv4(&ipv4_address, XdrvMailbox.data)) { + Settings->eth_ipv4_address[param_id] = ipv4_address; + eth_config_change = 2; + } + } + + char network_address[22] = { 0 }; + if (0 == param_id) { + if (!Settings->eth_ipv4_address[0]) { + ext_snprintf_P(network_address, sizeof(network_address), PSTR(" (%_I)"), (uint32_t)ETH.localIP()); + } + } + Response_P(PSTR("{\"%s%s\":\"%_I%s\"}"), XdrvMailbox.command, cmnd_idx, Settings->eth_ipv4_address[param_id], network_address); +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +bool Xdrv82(uint32_t function) { + bool result = false; + + switch (function) { + case FUNC_EVERY_SECOND: + EthernetConfigChange(); + break; + case FUNC_COMMAND: + result = DecodeCommand(kEthernetCommands, EthernetCommand); + break; + case FUNC_INIT: + EthernetInit(); + break; + case FUNC_ACTIVE: + result = true; + break; + } + return result; +} + +#endif // USE_ETHERNET +#endif // CONFIG_IDF_TARGET_ESP32C2 +#endif // ESP32 diff --git a/tools/fw_RfSensor_attiny85/TheoV2Sensor2/TheoV2Sensor2.ino b/tools/fw_RfSensor_attiny85/TheoV2Sensor2/TheoV2Sensor2.ino index 1ab3ecc30..2a0f8f00a 100644 --- a/tools/fw_RfSensor_attiny85/TheoV2Sensor2/TheoV2Sensor2.ino +++ b/tools/fw_RfSensor_attiny85/TheoV2Sensor2/TheoV2Sensor2.ino @@ -11,7 +11,7 @@ * Purpose : Arduino Source code for Sensor based on Atmel ATTiny85, running on 8MHz * Version : R201 - DHT11 or DHT22 and Vcc test * Date : 20140414 -* 20140507 - R202 - Verwijdering VCC_LOOP +* 20140507 - R202 - Verwijdering VCC_LOOP * * This code turns an Atmel ATTiny85 chip into a Sensor using the TheoV2 protocol. * This code is not of any use without running a Unit within RF range to receive sensor data. @@ -80,18 +80,18 @@ void loop() int payload2 = 0; VccTest++; - if (VccTest == 0) // Do not run the Vcc test too often to save Battery power - { - Voltage = ReadVcc(); - if (Voltage <= BATT_LOW) - Voltage |= 0x80; - } + if (VccTest == 0) // Do not run the Vcc test too often to save Battery power + { + Voltage = ReadVcc(); + if (Voltage <= BATT_LOW) + Voltage |= 0x80; + } if (GetPayload(payload1, payload2) == 0) SendData(payload1, payload2); // Watchdog_sleep(SEND_DELAY + CHANNEL); // Go to deep sleep mode for some time - Watchdog_sleep(SEND_DELAY - SENSOR_TYPE - CHANNEL); // Go to deep sleep mode for some time but not longer than 150 sec + Watchdog_sleep(SEND_DELAY - SENSOR_TYPE - CHANNEL); // Go to deep sleep mode for some time but not longer than 150 sec } //***************************************************************************** diff --git a/tools/fw_SonoffZigbeeBridgePro_cc2652/SonoffZBPro_coord_20230507.hex b/tools/fw_SonoffZigbeeBridgePro_cc2652/SonoffZBPro_coord_20230507.hex index b3af2829a..153e28dee 100644 --- a/tools/fw_SonoffZigbeeBridgePro_cc2652/SonoffZBPro_coord_20230507.hex +++ b/tools/fw_SonoffZigbeeBridgePro_cc2652/SonoffZBPro_coord_20230507.hex @@ -1,11293 +1,11293 @@ -:1000000000200120F54E0200916C0200916C02006C -:10001000916C0200916C0200916C0200916C0200E4 -:10002000916C0200916C0200916C0200916C0200D4 -:0C003000916C0200916C020071F4000061 -:10003C002DE9F04F99B0054680780224532800F240 -:10004C00C785DFE810F054009900A800B800C8007C -:10005C00DA00EA000C011B01C5052A01380159011F -:10006C00C505C505C505C505C505C505C505C50534 -:10007C00C505C505C505C505C505C505C505C50524 -:10008C00C505C505C505650188019401A001AB0135 -:10009C00BA01D401EB0107023A02C505C505C50535 -:1000AC00C505C505C505600276028C02A202B80220 -:1000BC00CD02DE020303C505C505C505C505C5058D -:1000CC00C50538034C036003C5056D037703950321 -:1000DC009E03AA03B603C503CF03F2030F04340433 -:1000EC003C044E045B0467048B0492049504EC1CE2 -:1000FC00E97A2A7B002320461EF094F88DF818002C -:10010C0006AB65200021012222F0B2FADFF8180BB1 -:10011C000078012800F25B85204629F0ACFC002811 -:10012C0000F0558505460079012840F0508529F0EE -:10013C0035FA00274FF400018DF83F008DF8380098 -:10014C00000ACDF83A108DF841708DF83E708DF89C -:10015C0040008DF839000EAE214606F10A0029F058 -:10016C0008FD297815223346017069788770417033 -:10017C004520FF2100F029BD29F0ADFC6979AA7951 -:10018C000023002425F0FCF98DF838000EAB652017 -:10019C00012100F053BC29F043FA29F0B9FB0146C8 -:1001AC000EA8022229F043FC8DF8180006AB65203E -:1001BC00022100F043BC29F033FA29F0A9FB0146D7 -:1001CC000EA8032229F033FC8DF8180006AB65202D -:1001DC00032100F033BC29F023FA29F099FBEA79CA -:1001EC0001460EA80023002427F058F88DF81800BB -:1001FC0006AB6520042100F021BC29F011FA29F08E -:10020C0087FB01460EA8052229F011FC8DF8180079 -:10021C0006AB6520052100F011BC0020DFF8304A48 -:10022C0029F0E0F8ADF85800681DA0478046E81D9D -:10023C00A04795F809B0824605F10A07BBF1100FEB -:10024C0000F2AE830EAC5E46002E00F0AC83384656 -:10025C0029F0E0FC24F8020B013E0237F4E729F008 -:10026C00DFF929F055FB01460EA8102229F0DFFB1F -:10027C008DF8180006AB65200721DFE329F0D0F9D3 -:10028C0029F046FB01460EA8112229F0D0FB8DF86F -:10029C00180006AB65200821D0E329F01CFC6A7B12 -:1002AC00691D0023002423F01FFE8DF838000EABCF -:1002BC0065200A21C2E302208DF8200029F00BFCF6 -:1002CC00ADF81800681D29F0A5FCEA79064605F181 -:1002DC0008018DF838200EAF781C28F053FF06A8C3 -:1002EC0031463A460023002420F084FB8DF8580058 -:1002FC0016AB65200B21A1E329F0EDFB00210024B6 -:10030C0023F048F88DF838000EAB65200C2195E3EE -:10031C000020DFF83C4929F065F8ADF85800681D5D -:10032C00A047804695F80F9005F11000A04705F105 -:10033C001304AD7C83460F2D00F247830EAE2F467F -:10034C00002F00F04583204629F064FC26F8020BB0 -:10035C00013F0234F4E729F063F929F04AF828F058 -:10036C0001FF40F0468306A829F003FC46E329F080 -:10037C0057F929F03EF828F0F5FE40F04D8306A819 -:10038C0029F0F7FB4DE329F0A6FB29F09EFA8DF836 -:10039C0038000EAB6520232100F016BCDFF888185E -:1003AC00C8208DF81800E81C0978002900F081831A -:1003BC0028F065FB8DF81800A3E36879EE1CFE2885 -:1003CC000BD1A879FF2808D12878082805D3304606 -:1003DC0029F020FC314625F0FBFA0EA9304628F016 -:1003EC0043F8002800F09183054600249FE3E81CA5 -:1003FC00042126F08DF8E97929F02EFCDFF8441859 -:10040C008DF83800022028F063FCDFF83C1803203C -:10041C0028F05EFC0EAB65202621D5E329F055FBB8 -:10042C00044605F10E0029F0F5FB297C6A7C034695 -:10043C00E878CDE90012AA1D214625F053FDDFF81E -:10044C0000188DF83800042028F042FC0EAB652013 -:10045C002721B9E34FF00208E81C8DF8408029F001 -:10046C00D9FBADF8380068798DF85800A81D29F033 -:10047C00D1FB2E7A044600270935CDE9005716A882 -:10048C000EA92246334621F0C7F829F0E7F810D11F -:10049C00DFF890078DF84080CDE9005722463346AF -:1004AC00C08AADF8380016A80EA921F0B5F88DF861 -:1004BC00180006AB6520282186E30226E81C8DF87F -:1004CC00406029F0A7FB29F023FAED7904460EA829 -:1004DC00002321462A4627F069FE29F0BFF80ED1E9 -:1004EC00DFF840078DF8406021462A460023C08A79 -:1004FC00ADF838000EA827F059FE8DF8180006ABA1 -:10050C006520292160E329F08BF8ADF83800681DCF -:10051C00042125F0FDFF6A7AAB7A00240146009491 -:10052C000EA825F00BFD8DF8180006AB65203021C8 -:10053C0084E229F075F829F0CDF9312201238DF8E8 -:10054C00580016A8CDE90004DFF8F0060EA921F03A -:10055C0063F88DF8180006AB652031216EE229F0A6 -:10056C005FF829F0B7F9322201238DF8580016A84C -:10057C00CDE90004DFF8C4060EA921F04DF88DF882 -:10058C00180006AB6520322158E229F049F829F011 -:10059C00A1F9332201238DF8580016A8CDE90004E7 -:1005AC00DFF898060EA921F037F88DF8180006AB85 -:1005BC006520332142E229F033F8ADF83800687B2E -:1005CC000024691D0094C0F3400200F001030EA842 -:1005DC0022F0C2FE8DF8180006AB652034212DE206 -:1005EC0029F01EF86A7BADF83800691D0EA80023AF -:1005FC00002426F0F3F98DF8180006AB65203521A0 -:10060C001CE22C4614F8030B04281ABFE8782C1DA6 -:10061C0002208DF84000204629F0FCFADFF818661D -:10062C00A5780121E278ADF8380000230024317060 -:10063C000EA829461EF066FE8DF818002846347068 -:10064C0026F008FA06AB65203621F7E129F043FACB -:10065C00ADF83800687904218DF84000A81D25F00C -:10066C0057FF0446AE7AEF7A05F10C0029F0D2FA66 -:10067C00DFF8B0850546214632463B4628F08FFE12 -:10068C000EA820F0A5FF28F0E9FF10D1022021468A -:10069C0032463B468DF84000B8F81600ADF83800ED -:1006AC0028F07DFE0EA820F093FF8DF8180006AB05 -:1006BC006520372188E26C7829F00DFA0146DFF8C5 -:1006CC007405007820F070F98DF8380004F0E00023 -:1006DC00202840F07C820EAB65203E2174E26C78C1 -:1006EC0029F0F9F90146DFF84C05007821F07CFC83 -:1006FC008DF8380004F0E000202840F068820EAB42 -:10070C0065203F2160E200206C788DF83800DFF81E -:10071C0018050078411E022980F09481022095E191 -:10072C0029F0D9F929F0D1F88DF838000EAB6520F5 -:10073C00422149E2002006908DF83D00CDF83900A9 -:10074C00E81C06A926F0BCFD8DF83800069850B1BF -:10075C0028F02CFE81788DF83B10C1788DF83C1078 -:10076C0000798DF83D000EAB6520432106222CE26A -:10077C00E81C28F084F98DF838000EAB6520442174 -:10078C0022E229F0A8F96979AA790DF0BBFF8DF85E -:10079C0038000EAB6520452116E229F09CF96979E9 -:1007AC00AA791AF08FFC8DF838000EAB6520462123 -:1007BC000AE2EC7829F089F90146204622F080FE05 -:1007CC00B0FA80F0472140098DF838000EABC1E13A -:1007DC00E87800248DF8384023F0F6FB0EAB65204A -:1007EC0047212BE1E8780EA926F08EFD06468DF800 -:1007FC00180040000130C5B2284629F00FFA002835 -:10080C0000F0A381044600F8016B00219DF818202C -:10081C00914280F0BE809DF83830013100F8023BE7 -:10082C009DF8393000F8013CF2E70EAC132120465C -:10083C0028F044FBEE7829F048F90146304626F0C2 -:10084C0031F9002800F088810021231D8DF8381023 -:10085C0028F0ACFDC11C827818468DF83B2028F09E -:10086C0091FC7CE10020EC78CDF84600CDF84200FC -:10087C00CDF83E00CDF83A0029F027F9AA79ADF869 -:10088C0038000F2A28BF0F228DF83A2022B10EA86B -:10089C00E91D033028F076FC0EA9204601221CF03D -:1008AC00CBFF8DF8180006AB65204B218CE128F0AE -:1008BC0069FA8DF838000EAB65204C2184E1E8789C -:1008CC0029798DF838100EA9032800F05F810228D1 -:1008DC0000F06281012840F06681522021F0C8FBB3 -:1008EC0064E129F0F8F869790246A81D1BF054FA66 -:1008FC008DF838000EAB65204E2165E129F0EBF840 -:10090C000146687919F05AFF8DF838000EAB652056 -:10091C004F2159E1C34D0822E88A05F13901ADF8A0 -:10092C003800C24800788DF83A00A88CADF83B002E -:10093C00688BADF83D000EACE01D28F023FC04F1F3 -:10094C000F0005F11C01082228F01CFC287E502108 -:10095C00182223468DF84F00652036E1B248007806 -:10096C00002800F0018112200AE120F07DFD2EE12B -:10097C0000208DF83800E878010606D5A94910F05A -:10098C007F0018BF012081F868000EAB6520532151 -:10099C001AE1652049212A46234621F069FE39E1F6 -:1009AC0080208DF863003E78102E52D80DF1180976 -:1009BC00013734464D46002C4DD0384629F02AF9E3 -:1009CC0025F8020B013C0237F5E780208DF8630017 -:1009DC0027780F2F54D801340DF1180A3E46002EFB -:1009EC0050D0204629F016F92AF8020B013E0234A9 -:1009FC00F5E7084629F00EF9ADF81800687E06A94F -:100A0C0028F0B8FB0EA921201BF018FB8DF858001C -:100A1C0016AB6520212111E0084629F0FBF8ADF852 -:100A2C001800687E06A928F0A5FB0EA922201BF051 -:100A3C0005FB8DF8580016AB65202221012221F010 -:100A4C0017FEC5E0002840F0B580042008F002FE37 -:100A5C00B3E080200DE0BBF1100F0CD80EA90020E4 -:100A6C0052465B468DE84202039016A8414615F0AB -:100A7C0009FA8DF863000DF1630365200621A3E0EC -:100A8C0080200FE00F2D0FD80EA9002002974A46A8 -:100A9C005B46CDE9005106A9CDE9031016A84146E5 -:100AAC0015F098F98DF863000DF163036520202192 -:100ABC008AE016A90EAD2A4618F076FD04469DF87C -:100ACC005800F0B1614904EB4400002641F8206065 -:100ADC0001EB800046609DF94B00B0F1FF3F03DC59 -:100AEC0005F1130022F07CFF0EAD1421284628F0EE -:100AFC00E5F90420214614222B4625F05BFC8DF8E9 -:100B0C00186006AB652024215EE0182029F086F8D9 -:100B1C00002800F083800446BDF83800002118221C -:100B2C00234628F0B1F90546002818BFC82519201E -:100B3C0029F074F8002867D007460130002D4BD0FF -:100B4C001821FF2228F0B4F950E0002049218DF83B -:100B5C00180006AB652037E001208DF838000EAB8D -:100B6C0065204A21132230E028F0B5FF044605F138 -:100B7C000D0029F04FF80246691D204625F0F4F9C6 -:100B8C008DF838000EAB652051211DE0522021F06C -:100B9C006FFA2748002104E0522021F069FA24481A -:100BAC000121017002E0522025F036FA0EAB6520CF -:100BBC004D2109E001208DF8380004F0E0002028D8 -:100BCC0005D10EAB65204021012221F051FD0024FE -:100BDC00204619B0BDE8F08F3146082228F0D2FA31 -:100BEC0007F109002146102228F0CCFA65202521B6 -:100BFC0019223B463D7021F03BFD3846192128F067 -:100C0C005DF9384629F008F8002CE0D02046182170 -:100C1C0028F054F9204628F0FFFFD8E7C825FFF745 -:100C2C00E4BB00BF407B002018260020C426002017 -:100C3C00D527002096880020952700207C260020B0 -:100C4C0059680200CD6D0200494E0100804300201E -:100C5C00219C02002DE9F04F99B080466FF00700FF -:100C6C00DFF8DCA80630ADF852009AF80000022834 -:100C7C0014D1DFF8C808007880B9B8F8080010B1B2 -:100C8C001020012101E0302000210AF03FFE00205D -:100C9C008DF81C0007A9522021F0EAF90DF11C096E -:100CAC0098F80810D8F804004A4610F001FAE8B198 -:100CBC009DF81E609DF81F409DF82050BDF82670D1 -:100CCC0028F066FC844211D127F003004FF6F8712E -:100CDC0080B288420AD0012D08D8022E06D29AF88A -:100CEC000000022808D19DF84D0028B1D32016F041 -:100CFC000AF819B0BDE8F08FB8F82800ADF8480034 -:100D0C00B8F83200ADF82A009DF82200D0B1D8F81E -:100D1C0004109DF81D209DF83830012027F0E4F9CF -:100D2C0008B1CF20E3E7DFF81C08C078012809D10F -:100D3C00B8F8280028F04BFE20B1417901F0E7010A -:100D4C00083141719DF8210068B1BDF82610FF20D3 -:100D5C0025F0A8FE9DF82110E0B141F001012C26F0 -:100D6C008DF8211017E09DF83900002800F0EB8079 -:100D7C009DF83D10FF2902D0002940F02681DFF8B4 -:100D8C00C807BDF82620C18A8A4240F0278101207D -:100D9C00222607E0082601F00300012808BF46F0D0 -:100DAC00110601209AF800104FF6F877012908D89F -:100DBC003446B20758BF64F07F04002808BF34469D -:100DCC0000E034469DF82200DFF87C575FFA84FB84 -:100DDC0030B9E87A20B10BF02200222840F0808054 -:100DEC001BF0400004901CD0012903D8A87B80077D -:100DFC0000F1D880119801780C2900F2DB800122D7 -:100E0C0041F298438A401A4200F0D480032902D15F -:100E1C0040780D2805D007A822F036F901283FF4B8 -:100E2C0068AFA88CB8F8441081420AD198F84620D3 -:100E3C00B8F84210B8F8280000230093002307F0FC -:100E4C00E5FC9DF82200F8B1B8F84210B8F828007B -:100E5C0022F0EAFB002800F08F800646D8F8040048 -:100E6C009DF81D10F2780844417B8A421EBF002277 -:100E7C007260F1700130042125F04AFB71688842E0 -:100E8C00FFF437AF013070609AF80000022834D2BA -:100E9C00A87B80077FF52DAF9DF84D004FF6F876B7 -:100EAC0060B1BDF8280027F06BFB002800F007812B -:100EBC00D8F80400417801F0DF0141709DF82E0054 -:100ECC00002800F0DF80D8F80400817901398171A5 -:100EDC008DF82E1004F07F00090640F0D680D3E088 -:100EEC000BF0420042287FF41CAF1198007800F000 -:100EFC00FE0006287FF415AF72E77FF4FAAE95F882 -:100F0C002600092802D004287FF4F3AE5FEA8B6038 -:100F1C0000F19E80049800283FF4EBAE11989DF8E8 -:100F2C0038100078042808BF022900F045810728F2 -:100F3C0008BF042900F009810C2840F04D8107A856 -:100F4C0015F0AEFAD5E6BDF8260022F00DFE0238FB -:100F5C00DFF8F415B0FA80F0CA8A4109BDF8260012 -:100F6C00904208BF023100293FD09DF81E20002A74 -:100F7C0056D001F1400455E09DF84D00B8B3042063 -:100F8C0026F06CF800283FF4B4AE01464FF4B27072 -:100F9C000880B8F828004880DFF8B00500781EF00B -:100FAC007DF8A6E611980178A1F10C0212F10C0F54 -:100FBC003FF62CAFE88ABDF8262082427FF496AE2D -:100FCC00BDF8280024F02CF990E6109A9DF83C000E -:100FDC0020F060FF30B101200026E3E690F82600F7 -:100FEC000428F8D100260020DCE600241AE095F84D -:100FFC006C0001287FF448AF11980078062803D1C3 -:10100C00049800287FF440AFF81DBDF82A1080B278 -:10101C0081423FF46EAE07A841461EF0FFFA68E627 -:10102C0001F1200422F0A0FD0138B0FA80F0400953 -:10103C0044EA00069DF81E0000283FF4B2AE119859 -:10104C00007827F0F1FA012818BF04F07E06A8E614 -:10105C0098F8460028F080F99DF82E00012840F001 -:10106C00B480B8F82800BDF82810814240F0AD805B -:10107C00BDF8260022F078FD022804BF00208DF870 -:10108C002E00A2E004F07F000446210702D44FF0AA -:10109C00000A34E0E1B24A0722D4C9069DF82110B7 -:1010AC0028D5C1F3820212B1072A18BF013A002ACF -:1010BC0008BF044601F0E30040EA820118E0D320A7 -:1010CC0015F021FEDFF888040078002800F09F80DE -:1010DC00DFF8801451F82000C0EB0010810098E07C -:1010EC009DF8210000F0E00100F0E30040EAD1019E -:1010FC008DF82110D8F804004FF4805A017295F83D -:10110C002600092801D0042823D1E98ABDF826003D -:10111C0088420AD022F028FD022806D09DF8210032 -:10112C0000F0030001287FF4E4AD9DF81E000028B8 -:10113C0047D011989DF838100078042808BF022970 -:10114C003AD0072848D1042946D107A817F040FF08 -:10115C00CFE5E7B214F0610F46D0F80709D0B8F824 -:10116C00281007A8A94615F0E3FB002864D004F06A -:10117C009F040025E7B2A00609D598F84600D8F8D8 -:10118C003C2028F0E9F807A815A905F04DFC7806D5 -:10119C0040F12681B8F8281007A80DF152022B4611 -:1011AC0010F002F800286FD005461198007801283D -:1011BC0008BF4AF0100A13E107A9002010F068FFDD -:1011CC0097E598F8460028F0C7F8D8F83C2007A80F -:1011DC0015A905F029FC8CE503287FF48AAD07A836 -:1011EC0000210FF0EFFC84E59DF81E0001285AD178 -:1011FC0011980078032849D0052854D1B8F8281044 -:10120C0007A80DF1520200230FF0CEFF71E5D14873 -:10121C000168D1480268BDF82800904701287FF486 -:10122C0068ADCE480168BDF828008847CC480168F5 -:10123C00BDF8280088475CE526F0E4FA9DF82E10EE -:10124C000546BDF8280019B9B8F82810884291D085 -:10125C00B9F81610814204D1BA48807800283FF4BE -:10126C0089AFB8F8281007A82A4609F027FA0028F1 -:10127C0000F09B8038074AF0040ABDF8260048BFEE -:10128C00F01DADF8520075E70025A9E0BDF8260069 -:10129C0027F076F938B1B8F8281007A80DF15202EA -:1012AC0000230FF081FF9DF82E0088B323F066FD1C -:1012BC0000287FF41EAD9DF83900A0B3109A9DF85C -:1012CC003C009DF83D1020F0E5FD002870D09DF805 -:1012DC003D00002875D0109928F042FB9DF8243071 -:1012EC00ADF8520011209DF823209DF821104AF0F2 -:1012FC00400A002B08BF0920002A18BF083000291B -:10130C0018BF0130D8F804100A5C013A0A5462E0A4 -:10131C009DF81E0001287FF47EAE119800780328FA -:10132C003FF4E7AC77E69DF82010BDF826000029C5 -:10133C00ADF8520000F0D3804020BDF8261009F122 -:10134C001D0200EAC4059DF820002B4618F0C2FDD2 -:10135C0038B1D8F804004AF0200A017801F03F01B6 -:10136C0001709DF8390048B1BDF8261009F1200034 -:10137C0021F06CFE4AF0400AADF852009DF81E00B8 -:10138C00012806D0BDF82810BDF82600002214F064 -:10139C0085FFBDF82810BDF826002A4612F0BEFBCA -:1013AC00002818BF4AF0200A15E004F0DF04E0E63C -:1013BC00BDF82610BDF828000B2200231AF07AFC89 -:1013CC0097E4BDF82600ADF8520028F000FB002889 -:1013DC0008BF4AF0400A26F015FA05464FF6F87693 -:1013EC00B01DBDF8521080B20F1A5E4818BF2F46C0 -:1013FC000078012805D1F01DB8F8321080B2814276 -:10140C002FD160B2B0F1FF3F3FF773AC002F3FF428 -:10141C0070ACB8F8080028F001FC00283FF469AC67 -:10142C00B8F80820D8F80410054627F0ABFE9DF854 -:10143C001E10002098F80830B8F8282016908DF867 -:10144C005410BDF8521015ACCDE9007ACDE9020468 -:10145C00284610F0DDFB70B3284628F0DDFBFFF7C3 -:10146C0048BCB8F828108142CBD0701CBDF826209F -:10147C0080B28242C5D2BDF828008142C1D028F08A -:10148C00A6FA0028BDD0017901390129B9D84088C4 -:10149C0001218DF85410ADF8600015AD28461EF0F2 -:1014AC002DFD0028ADD0281D1DF0F0FC0028A8D083 -:1014BC0021F0DAFEA5E72348407800283FF419AC68 -:1014CC0000208DF81870ADF81900DDF826004FEAF1 -:1014DC003040059005A827F0CDFCFFF70ABC390772 -:1014EC003FF52AAF9DF81E1001293FF425AF0021CE -:1014FC0018F0B0FC20B1407901380228FFF41CAF81 -:10150C00B8F84410BDF8520022F08EF830B1807853 -:10151C0026F0B8FB01380728FFF40EAFBDF8280001 -:10152C0027F02EF818B104208DF8200004E7BDF840 -:10153C002610BDF8280002223FE700BFD527002067 -:10154C0018260020E8250020407B002098880020E9 -:10155C00C727002060B70200942300209C230020A2 -:10156C0098230020D32700202DE9F0438DB00546A9 -:10157C0080780224252800F27380DFE810F0260022 -:10158C00A400C400D700EA00F8000601B602B602B7 -:10159C001D012E01B602B602B602B602B602460113 -:1015AC004B01B602B602540158016101B602B602F3 -:1015BC00B602B602B602B602B602B602B6026B01AB -:1015CC006E017101740178017F01DFF8D47500247C -:1015DC000E258DF804403878012807D801A81DF095 -:1015EC00EDF804469DF8040005EB4005EEB23046DC -:1015FC0028F014FB002800F087824FF00008054605 -:10160C00431C0021082280F80080012027F03CFCBC -:10161C0027F0C4FF6872000A0721A872DFF884055E -:10162C00E972007828733878012800F262829DF8FC -:10163C000420002A6A7300F05E8205F10E0000217E -:10164C002346914280F0578213F8022B013100F8A7 -:10165C00022B13F8012C00F8012C9DF80420F0E764 -:10166C00A0F140010D291FD8DFE811F00E00100188 -:10167C003F023F021E012E013F023F023A0145018B -:10168C00500165013F02740101ACE91C0822201DC8 -:10169C0027F078FD204619F0E1FFBDF80600402147 -:1016AC00ADF828000AABEEE0632800F069816428ED -:1016BC0000F07681E02840F0188200244720E021D9 -:1016CC00002200230FE2202028F0A8FA002800F0C6 -:1016DC00C1812021FF22044627F0EAFB631C012074 -:1016EC000021082227F0D0FB0546002818BF012551 -:1016FC0001AB84200021042227F0C6FB002800F057 -:10170C000582023506E2E81C28F084FAADF80400E4 -:10171C00832028F09CF9014601AA832028F070F858 -:10172C008DF828000AAB6720022190E1E81C042107 -:10173C0024F0EEFE0190842028F089F9014601AADC -:10174C00842028F05DF88DF828000AAB672003216F -:10175C007DE1612028F07BF90146EA1C612028F02C -:10176C004FF88DF8040001AB672004216FE1622073 -:10177C0028F06DF90146EA1C622028F041F88DF83A -:10178C00040001AB6720052161E100208DF8040005 -:10179C00E81C28F03FFA6A7900F4F851002A00F0AE -:1017AC004981B1F5A06F04D04FF6FF71884240F02B -:1017BC004B814FF0FF3045E128F002FA044628F047 -:1017CC00FDF9D949604301ACB0FBF1F1204628F09A -:1017DC008EF9672009210422ABE0DFF8B4632D7980 -:1017EC00306840B901AC204627F09AFD0120214613 -:1017FC000EF028FA3060052D00F06981002D00F004 -:10180C006981642122F040F966E115F8032B672009 -:10181C0010216EE0E87823F093FD8DF8040001AB05 -:10182C006720112113E100246720142102E0002419 -:10183C0067201521ADF80840019401AB062252E156 -:10184C0000246720162109228DF80C40CDE90144B3 -:10185C0001AB48E1F52020210BE0F520212108E027 -:10186C00F520222105E04FF6F570232108E0F52044 -:10187C0024218DF8040001AB6720E8E0F520252138 -:10188C00ADF8040001AB67200222E1E0E81C28F06F -:10189C00C1F9ADF8060001AC204617F055FB231D2D -:1018AC00672041210822D3E0E81C0AA926F0DCFDC0 -:1018BC0000288DF8040000F0CF8001A81821FF2229 -:1018CC00013027F0F5FAF4E0E81C0AA926F0CCFD6B -:1018DC0000288DF8040000F0F1804FF0FF30EFE0AD -:1018EC0015F8030F697822F0B3F828806720482197 -:1018FC0002222B46ACE0E87824F058FF01AC0146FC -:10190C00204618F0E7FC6720492111E0EC1C20462A -:10191C0026F066FA002818BF2046B5F80B1019F00F -:10192C00F1F901AC0146204618F0D4FC67204A219D -:10193C00242223468CE001ACE91C0822204627F027 -:10194C0021FC204627F0D8F98DF828000AAB672037 -:10195C004B217CE04FF0FF3095F80380691D01901E -:10196C00ADF81000CDE90200FE208DF806002879B4 -:10197C0003288DF8300020D10AA828F0FAF821E0CD -:10198C000024E91C08228DF8284001AD284627F0D8 -:10199C00F9FB28461DF07AFA0AAB67206321A1E017 -:1019AC00B5F80B006A7B0024E91C8DF804400AF0A2 -:1019BC0067F801AB6720642194E0084628F02AF907 -:1019CC00ADF82800AF7B002F00F0DD807E0095F88D -:1019DC000D90304628F022F9002800F0D48005F153 -:1019EC000F013246044627F0CDFB00940AA940466D -:1019FC004A463B460DF0F8F9002800F0BA8083788F -:101A0C0001784278057946798DF806308DF8041006 -:101A1C008DF80520C3788DF809608DF808508DF885 -:101A2C00073001A98B1D811D40794200184627F013 -:101A3C00A9FBA5E0B1F5A06F03D04FF6FF7188426A -:101A4C0002D100205549086001AB67200621012214 -:101A5C0020F00EFE002448E0182028F0DFF840B3F8 -:101A6C00BDF828100446009006200022182324F00C -:101A7C008BFCB8B9BDF8285001AE21461022701C61 -:101A8C0027F080FB444F05EB450506F1110057F894 -:101A9C00251028F02CF807EB8500416806F115009D -:101AAC0028F025F82046182127F008FA204628F0BF -:101ABC00B3F801AB672044211922C9E7BDF828000F -:101ACC00ADF8050001AB672045210322C0E7314981 -:101ADC0001220A7021F08BF9002467200A218DF86D -:101AEC00044001AB012220F0C3FD20460DB0BDE83F -:101AFC00F08385F80D806720002132462B4620F0BC -:101B0C00B7FD284628F088F87CBBA3E7019800BAFB -:101B1C00C4F809000AAB83200021022227F0B4F993 -:101B2C0020B1043506E000BF40420F00BDF828008C -:101B3C00A4F80D0004F10F0361200021012227F00D -:101B4C00A3F9002818BF083504F110036220002106 -:101B5C00102227F099F9002818BF1035234625705C -:101B6C0067200121202220F083FD204628F054F824 -:101B7C0070E74FF6FF70ADF808006FF480300190FD -:101B8C00204628F049F801AB67204D210E225FE773 -:101B9C00248800209227002018830020048800202D -:101BAC0018260020C42600202DE9F04F85B084783B -:101BBC000226362C00F2BE820546DFE814F06C01DA -:101BCC00740172007C017800BB02BB0281003700FB -:101BDC004C008C009F00AD00BB02B5009001BB0215 -:101BEC00BB029A01AD01BB01BB02BB02BB02BB0233 -:101BFC00BB02BB02BB0237004C00BB02BB02BB02E8 -:101C0C00BB02BB02BB02BB02BB02BB02BB02BB02E0 -:101C1C00BB02BB02BB02BB02BB02BB02BB02BD00D0 -:101C2C00EB00CB01FF005B005B00DB0127F047FF03 -:101C3C00242840F0AA8102AB352000210422002484 -:101C4C0027F022F9002800F0FC81012002228DF8F7 -:101C5C0010000020FCE100208DF8100027F02FFF71 -:101C6C000646092C40F0ED8095F8059095F8068015 -:101C7C000720EFE0DFF82465306880B1406A70B16E -:101C8C0002A927F025FF0546342C40F02C8228466B -:101C9C0027F0C0FF002800F02582042041E2032039 -:101CAC003FE2DFF80835612002210A223FE202AC54 -:101CBC00E220214624F0B0F961200421082288E1B9 -:101CCC0027F0FDFE0446681D27F0A4FF242C40F0ED -:101CDC0087810020FBE1E878032800F29781281D1A -:101CEC0027F098FF0246E878DFF8B81431F81010A6 -:101CFC00DFF8B404007827F0F7FE88E1E8780328D1 -:101D0C0000F28981DFF89C1431F81010DFF8980488 -:101D1C0000781CF067FE7FE127F018FEADF8080094 -:101D2C0002AB61200C2103E1002661200E2101226F -:101D3C008DF8086002AB1BE2DFF8606401208DF8BF -:101D4C0010003068002800F02C810069002800F099 -:101D5C00288102A927F0BCFE042124F0D9FB00281D -:101D6C0000F0EC81044627F059FF002800F01C819C -:101D7C002146054627F0A2F83068BDF80C10224623 -:101D8C002B4606690298B0478DF81000284627F0BC -:101D9C0043FF09E1DFF804442068002800F00881C3 -:101DAC008069002800F0048102A927F091FE2068C8 -:101DBC00BDF80C10826902989047FAE0DFF8DC73EA -:101DCC003868002800F0FB80C069002800F0F7801C -:101DDC0002A927F07DFE9DF80850BDF80AB0BDF8A9 -:101DEC000C90044627F016FFA6788046F72E28BFE5 -:101DFC006FF00806B01C5FFA80FA504627F00EFF11 -:101E0C00002800F09D81012D044608BFBBF1000F96 -:101E1C0000F09A813868A11CF3B24246C569029859 -:101E2C0000914946A8470746002840F093810027B7 -:101E3C0061203321524623466670277020F018FC2F -:101E4C0088E1681D27F0E6FE8146E81D27F0E2FEDA -:101E5C008046092002AF242E18BF2F1808BF352644 -:101E6C00304609EB080527F0F2FD854201D9022026 -:101E7C0057E1B9F1000F04D1304641463A4622F001 -:101E8C0047FA304641463A4627F0BAFC002800F0A3 -:101E9C00E5800A2045E1E878012802D0002840F0CE -:101EAC00488127F0D7F940F259600121ADF80800BC -:101EBC0002AB61203CE00120EC1C8DF80800E22014 -:101ECC00214620F0D5F830B901200821224627F010 -:101EDC0097FC8DF8080002AB6120032126E1E8781D -:101EEC00291D012800F0E180002840F0E580E02069 -:101EFC00DFE027F0E4FD0446681D27F08BFE242C60 -:101F0C000FBF00200146204627F052FD8DF8080037 -:101F1C0002AB6120122109E127F0D1FD24280CBF6E -:101F2C00002027F094FDADF8080002AB61201321CE -:101F3C000222FCE0E8788DF8080099488068D0F817 -:101F4C00302402A9E02090478DF8100004AB6120EA -:101F5C001421EBE0914C206898B3806A88B302A9F5 -:101F6C0027F0B6FD2068BDF80C10826A02989047E5 -:101F7C00014627E0894C206868B3C06858B327F045 -:101F8C009EFD2168C968884726E08046693800268E -:101F9C0080B2032838BF0126681D082C40D1057873 -:101FAC0041E003208DF8100004AB61203021BDE02E -:101FBC0003208DF8100004AB61203121B6E003271B -:101FCC00CDE0002102AC204627F091FD61203221AA -:101FDC0004222346ABE0032027F095FC3621A5E034 -:101FEC0005F10806ED790146A8426CD9204600227D -:101FFC0027F000FC09288DF808006AD1002D68D064 -:10200C0020462946324627F0FBFB62E0022027F0EF -:10201C007AFC0A218AE0022027F075FC0B2185E06E -:10202C0027F0F8FD0546404627F011FD0227A8428F -:10203C0088BF7700CFB100268DF80870612021464B -:10204C0092E002988DF810400422ADF812000220A4 -:10205C008DF8110004AB6120082168E0012E62D1DB -:10206C00E220394620F004F85BE0471BB8B2F728B1 -:10207C0028BFF727B81CC6B2304627F0CFFD002882 -:10208C0060D01FFA87FB00F1020982464846594688 -:10209C0026F014FF404629465A464B4626F0F4FEDD -:1020AC000546002867D00A2770E00878022814D269 -:1020BC0052201FF0DDFF00E002208DF8080002AB7B -:1020CC0061200F2132E02046324627F093FB8DF839 -:1020DC00080002AB6120072128E002A9522023F05E -:1020EC009BFFECE702359DF8080015F8018BBDF855 -:1020FC000C7001280ED1BDF80A0058B9384641467B -:10210C002A4622F005F9012F04D1E22029461FF0BE -:10211C00AFFF01273068394642462B46466A029883 -:10212C00B0478DF8100004AB61202146012220F04D -:10213C009FFA0026304605B0BDE8F08F052031E748 -:10214C0010270CE0102776E7A9F169000328BFF4EB -:10215C0061AE0227204627F05FFD002FE9D0002654 -:10216C008DF80870612033218DF8096002AB0222D2 -:10217C0020F07EFADEE78AF8017000276120214604 -:10218C00324653468AF8007020F072FA504627F017 -:10219C0043FD002D7FF44FAFCBE700BF5C27002041 -:1021AC000C01002064BC02009688002000BC0200D8 -:1021BC002DE9F04F8FB00C4648070FD4200441D4C2 -:1021CC00E00400F19781200600F1C081A00700F126 -:1021DC00D481200500F1F3810020B4E1DFF8200563 -:1021EC000178062900F2AD81DFE811F007009401B7 -:1021FC00AB01AB019901AB01A001DFF81055DFF881 -:10220C0004152A7891F82B30022A02D19E0600F18F -:10221C0098815E0700F19D819B0740F19281042318 -:10222C00037091F82C30DB0700F08B8191F82E3085 -:10223C00002B00F0528225F03CFE0420012102F01C -:10224C00A3FA57E2DFF8C8040394DFF8BCB4DFF854 -:10225C00B094DFF8C474DFF8AC44DFF8B054DFF8A6 -:10226C00BCA448F20208008802909BF800001CF005 -:10227C00E7FB002800F03A8106460078D3282DD1E0 -:10228C00F089404540F019813878002800F015811C -:10229C0099F80000012840F0108126F0BBFE0028C0 -:1022AC0040F00B817088002840F00781A24604ACF6 -:1022BC001221204626F002FE27F0ACF930462146CA -:1022CC0018F02EFCBDF81C00B0F5285FC0F088801B -:1022DC00012002211FF078FA54462AE099F80010E8 -:1022EC00884217D1012834D0032840F0E6802878A2 -:1022FC000138012800F2E180B078012851D0002883 -:10230C0040F0DB807078002800F0BF8000201DF0CA -:10231C000DFFD2E00A2811D194F82B00BA46B71C55 -:10232C003071A16909B138468847384625F03AFA28 -:10233C005746DFF8D853DFF8E4A3BEE0297800292C -:10234C0040F0BB80092840F0B880A168B01C8847D9 -:10235C00B3E028780138012800F2AF80707860B1C2 -:10236C0094F8330094F83410013084F83300C0B280 -:10237C00884202D9012000219DE099F80100032830 -:10238C0058D0022871D0012840F097803878002866 -:10239C0000F08C8026F03EFE002800F09280012098 -:1023AC0085E07078002875D027F0F8F84FF6FE71AC -:1023BC00884203D1BAF81600884207D0AAF8161042 -:1023CC00ADF8281053200AA91FF052FE1EF04CFD48 -:1023DC0025F048FA00208AF826001DF0C5FB6CE0B9 -:1023EC00CF48006809A90AAA17F0DEF80746029838 -:1023FC005446C64DDFF824A3874212D29DF838000C -:10240C0010B1FD208DF838000420394614220AAB97 -:10241C0023F0D0FFC34907EB470001EB80000121FB -:10242C0041720020012184F83200012002F0ACF945 -:10243C00B94F42E0A2460AACAB20002122461CF068 -:10244C00F9FC042004945446DFF8D0A2AF4D8DF86B -:10245C00140004A80FF038FD27F0DCF89BF80000FE -:10246C004FF4805141F288321DE0012020714FF46D -:10247C008060ADF828000AA819F0B6F827F0CAF861 -:10248C00A4484FF4805102680BE010F0C1FB606966 -:10249C0098B9A2E702204FF4805140F6B83289F87F -:1024AC0002009BF8000027F01FFB06E0002084F8D8 -:1024BC0032000120012102F067F9304625F0CCFCF6 -:1024CC00D3E694F8350020B1E0690028F5D08047B8 -:1024DC00F3E70020002102220023ADF8280002209F -:1024EC008DF830000AA825F061FEB5E7039880F45A -:1024FC00004028E0854800780138012859D88048E8 -:10250C00017803294DD0012953D1417800201FF0C7 -:10251C005BF94EE0012001211FF056F911E025F086 -:10252C00C8FC0420012102F02FF90AE0002132221C -:10253C000170744880F82A1073480421007827F041 -:10254C00D3FA84F004000FB0BDE8F08F84F0800063 -:10255C00F9E70522027091F82C2092072CD591F8FE -:10256C002E204ABB052202600120487000201CF07E -:10257C004DFB022024F0DAFEE3E7644800780138D2 -:10258C0001280BD80020CDE90A000AA812F00EFD94 -:10259C0020B15D48022100781BF054FD84F002004C -:1025AC00D1E78178022904D10121817000201FF02C -:1025BC00E7F884F48050C6E705200021B3E75348C0 -:1025CC000078002840F08680DFF838A1DAF80C504B -:1025DC00002D79D004A80DF1280B01300BF1040665 -:1025EC000390002D6DD0A87A18B10138A87200069E -:1025FC0046D19AF83180B8F1000F11D00020A91CF7 -:10260C0008228DF82800304626F0BCFD584619F0FB -:10261C0025F828B12A88BDF82A00314623F0A4FCFD -:10262C00AF1C0DF127015A46384616F0BDFF814606 -:10263C00384609A923F0E3F9B8F1000F05D09DF84D -:10264C00380040F0020002281CD1DAF80800A0B1D2 -:10265C0003983946082226F095FD022000220C230F -:10266C008DF81000BDF82400ADF81A00264800784B -:10267C0004A90091092120F0F8FB28461EF052FA1B -:10268C00ED68AEE7384623F097FF9DF82700012848 -:10269C00DBD15846142126F011FC224A09EB4900E3 -:1026AC0000215B4642F8201002EB800014224160AE -:1026BC004172FF2049468DF83800042023F07AFE41 -:1026CC00C3E7DAF80C0028B90F484FF40061007822 -:1026DC001CF088F984F4006035E7013A012A09D826 -:1026EC00032202600120487001201CF08FFA0120A7 -:1026FC0024F01CFE287800287FF423AF04205CE72C -:10270C0008880020AC2200209F880020182600207A -:10271C00C6BC020064270020AA270020407B0020B2 -:10272C00DC870020804300202DE9F04F9DB004464B -:10273C00DFF84005406818B18047002800F0798226 -:10274C00DFF834A5DFF834B50D940DF138099AF89B -:10275C000000411E002C0B9118BF01218BF80F10AB -:10276C009BF802800BF118049BF801100027002540 -:10277C000C91C0B287421ED2B84517D0FEB20021D0 -:10278C004A460423304626F0C5FC0E9810F4403F10 -:10279C0040F0040018BF0135C0B27C2806D1304689 -:1027AC000621F82225F030FCF82020709AF8000061 -:1027BC000C340137DDE7E9B201380022884204D13C -:1027CC009BF80500002800F05182CDF82880DDF838 -:1027DC0034804FF001094046B8F1000F08BF1020BB -:1027EC00059015AD00200190DDE90B74002638042E -:1027FC0000F0F9819BF80F0008B98BF80F90E0B24C -:10280C0000210EAA042326F085FC0E98B8F1000FC7 -:10281C0018D010F4403F18D04FF400509AF8001024 -:10282C000136013FABF810009BF80F0001388BF814 -:10283C000F0059FA84F0B0FBF1F202FB11048BF893 -:10284C000D40D4E70021049102E0CDE90B7404960D -:10285C00C0B20A9E4FF00009702804D00C98702169 -:10286C00C0B221F0FDFEF4B200210EAA04232046D2 -:10287C0026F050FC9DF83800FE2803D02046FE219F -:10288C0021F0EEFE20460621FE2225F0BDFB4FF482 -:10289C0000500C9F0BF116010022ABF814908BF832 -:1028AC000C60A146ABF81000FF208BF80E00F8B2BC -:1028BC008BF80D70400050FA87F001EB8000B0F8F7 -:1028CC0006A0DFF8B00302706000ABF812A050FA5B -:1028DC0086F09BF80F6001EB8002FE20114601F898 -:1028EC00020F32F8060F03910890E3480292047825 -:1028FC0014A821F0A9F956FA87F0CDF824900138E4 -:10290C0090FBF4F101FB140000905FFA87FB0C972D -:10291C00CB4500F06081ABEB0900B0FA80F04009C8 -:10292C0007900020069000204FF00109C00740F0EE -:10293C009D801FFA8AF4162C71D9CE480078002895 -:10294C0040F07181AAF1070758460FAAB9B216F0E8 -:10295C00AFFEBDF84A6006F11000A0420FD89DF8FA -:10296C00460096280BD1A7EB06099DF84520314669 -:10297C005B461FFA89F840461AF0CAF918B3AAF157 -:10298C00010A4FF001095446A0B2172864D3362827 -:10299C00A4F1160658462A4688BF2026A41BB3B2BB -:1029AC00A1B226F0B7FB3004EED015FA86F010F881 -:1029BC00010C962801D0013EF5E7DDF8348006EBDA -:1029CC00040A0020B2E79DF84700C10701D1800737 -:1029DC0004D40020CA46DDF83480A5E7F01D83B28C -:1029EC00089813FA80F4B4F5005F01D90120F2E7DE -:1029FC0080B2A54918440A1A5846414626F08AFB6B -:102A0C0006980130B4F5005F069004D101204FF414 -:102A1C0000510891DEE70020CA460894DBE70698CF -:102A2C0010B1964926F0D0FC0098C0B2834500F056 -:102A3C00D88091490C98097859FA80F0DDF82490E7 -:102A4C00B0FBF1F202FB11078C4907EB470001EBDD -:102A5C008000B0F81CA058E78948149900684268B7 -:102A6C00884890470020DDF8348005E0069810B1C6 -:102A7C00824926F0A9FC002007900C980A907D480A -:102A8C000078002840F0CF8008981021C0F5005243 -:102A9C00103883B20998C1F2001221F0F1F8754A8E -:102AAC00117808431499107075480068426875488D -:102ABC00904707980A9A88B16F4800780BEB000191 -:102ACC00013991FBF0F202FB10126C49D0B24000BC -:102ADC0050FA82F001EB8000B0F81CA0DFF89CB13A -:102AEC0008990298099C01238BF80E200180ABF801 -:102AFC001010BBF912209BF80D102046ABF814A057 -:102B0C0023F040F9BBF914209BF80E102046022349 -:102B1C0023F038F9BBF81000049CB8F1000FC0F595 -:102B2C00005007D00599DFF850A18842A4BF0121BD -:102B3C00019101E0DFF840A1059988424FF07C013A -:102B4C00B8BF7821099E304621F08AFD0DF01EFB9E -:102B5C0007469BF80F000621FC22C01B8BF80F00C8 -:102B6C00304625F051FA0399FC209BF80E30087082 -:102B7C009BF8021017FA84F00C9301449AF80000A9 -:102B8C00B1FBF0F202FB10118BF802100A9101312B -:102B9C00CAB2B2FBF0F202FB10118BF8011003EB7E -:102BAC0043010BEB8101898B102906D10C99013162 -:102BBC00B1FBF0F202FB10100C900B98C01BB8F19B -:102BCC00000F0B903FF410AE019880F00100C0078D -:102BDC007FF40AAE07E00120CB464FF001090790C5 -:102BEC004DE700984AE77C2021F054FD0446FF286D -:102BFC0025D17E2021F04EFD0446FF281FD19BF8E5 -:102C0C00014004EB44000BEB8000807DFF2812D0C8 -:102C1C009AF800009BF802100144013991FBF0F284 -:102C2C0002FB10140BE01648149900684268154812 -:102C3C00904700221AE020467E2121F011FDE0B2DF -:102C4C00FE218BF80340400050FA84F00BEB80001F -:102C5C00808BABF806009BF8020021F001FD0020F0 -:102C6C008BF80500BBF81000C0F5005210B21DB077 -:102C7C00BDE8F08FA023002097880020A0800020C2 -:102C8C00D801001000400340002000112DE9F04F46 -:102C9C0089B021F05DFADFF810158122DFF8148578 -:102CAC00DFF814A5DFF82045DFF814E50A70DFF82B -:102CBC00FC140860DFF8F804FF2101700020DFF835 -:102CCC000415A8F800008AF80000DFF8F004096881 -:102CDC00007891F808B04FF6FE718EF80000594458 -:102CEC008AB2A168D1F80031DB899A4200F267817F -:102CFC000422DFF8DC54A8F80020DFF8D024126896 -:102D0C009668330ECEF80C60C6F301592B706FF039 -:102D1C00FF0303EA1627B3B2D1F8B86047EA1327CA -:102D2C00AEF8047036781EB9B9F1020F00F0478185 -:102D3C00B9F1030F00F043811B0A03F0070316B12E -:102D4C00002B00F03C81DFF88CC4042B9CF800C0F5 -:102D5C0008BFBCF1000F00F032813EB1DFF878649F -:102D6C003678862E02D1022B40F02981BB0416D472 -:102D7C00BBB203F00703022B08BFBCF1000F20D03D -:102D8C00DFF854140978862909D10020764621F001 -:102D9C0017FADFF84004B64690F800C030780028E7 -:102DAC004ED0BCF1000F4BD1012800F00881032854 -:102DBC003FD0022844D1BEF80400400740F0FF8009 -:102DCC003EE0D1F8D40090F88300022800F0808017 -:102DDC0027460520147BF246A946A8F8000026F0E9 -:102DEC00A7FB0546DFF8F003007886286DD1B8689C -:102DFC00016C096811B9D0F84C05804760B200210C -:102E0C00002626F04FFFB9680A6C12685077086CE0 -:102E1C0000688677086C0068C477284626F034FE74 -:102E2C00BAF8041099F8000001F010011CF0F0FE43 -:102E3C004EE0BEF8040000F00700032840F0BF800D -:102E4C00BEF80400010700F1BA80810402D48105A8 -:102E5C0000F1B5809EF80E20C2F38107012F00F01F -:102E6C00AE809609012E00F0AA80B9F1010F11D89D -:102E7C0040F0020101F0070103290BD117B93F2AD9 -:102E8C0040F29D8037B9A168D1F8AC1009780029BF -:102E9C0000F095804FF6FB71B9F1020F0BEB010CB2 -:102EAC0019D1CF4BD95D9B5D03EB01090023402A5F -:102EBC00B7FA87F238BF012352091A40430616D4D9 -:102ECC00002A08BF09F1020915E0284626F0DCFDAE -:102EDC0025F04CFA75E0C14B402AD95D9B5D03EBA4 -:102EEC00010908D3420648BFA9F1020903E0002AF0 -:102EFC0018BF4FF00209C0F300205FFA89F11FFAE6 -:102F0C008CF30A1A8EF801009A4258DC6044039143 -:102F1C00B346401AA168AEF806007430D1F85012CE -:102F2C0080B28847A6490028886048D07421CDE932 -:102F3C00019725F0C3FFA24F0020B870A548007878 -:102F4C0020B9387900F020008AF8000078789AF8D7 -:102F5C000010DFF878C24FF000092E4600299A497C -:102F6C003DD000284FF000003AD1B88800F007009F -:102F7C00032807D0012832D18868D0F8D40090F803 -:102F8C00820060B3C8684069007818B125F028FE4B -:102F9C00FE280DD08C488068D0F84C02804738B998 -:102FAC0089488068D0F844028047002800F0F780F8 -:102FBC00834F0120B870DFF814C22E4610E025F0C4 -:102FCC0077FC26F0B5FA814900240A6813681C7155 -:102FDC0012680A6026F058FD09B0BDE8F08F002099 -:102FEC00BC6804F1740184F830B06160A165797833 -:102FFC00BB88FA880029A381029B228184F83A308D -:10300C00337808BF994697F80EB084F84990019D23 -:10301C00A4F85C20FF22B8F80030A273CBF301199E -:10302C005E1A797BA8F8006001F0780160F38201E8 -:10303C0001EB09002074280600F0AE80DCF80000DB -:10304C0004AF039A10FA86F000F10801384626F016 -:10305C0051FE56FA85F0CBF38105A8F80000207CD0 -:10306C0000F04008CDB3B9F1020F06D1B8F1000F52 -:10307C0003D0B4F8440004AF06E0BDF810000237EA -:10308C00A4F84400A4F84200564EF189884203D0BB -:10309C004FF6FF7188425ED1032D11D104F132003D -:1030AC00394626F066FD464CF11CA068323024F0FF -:1030BC00F6FA454900284ED094F80EB008370EE0C9 -:1030CC0037F8020BB1898842608606D04FF6FF7143 -:1030DC003B4C88423C493ED101E03B49384CBBF16A -:1030EC00400F20D3B9F1020F06D16DB9B8F1000F22 -:1030FC000AD13348806803E0A068017C490603D4F8 -:10310C0039880237A0F84210BBF1C00F06D32C4C03 -:10311C003946A068283026F02CFD03E0284C38886E -:10312C00A168088528498968A088D1F8AC20127854 -:10313C00B2B1B9F1020F13D200F00700012802D08E -:10314C0003282FD11E4C6DB9264AA368D289B3F837 -:10315C004230934206D018F058FE19F04FF830E781 -:10316C0000F00700032806D0012815D1D1F8D400AF -:10317C0090F8820080B1A068D1F848128847104AB4 -:10318C0050B90020D17B9070907BC1F3011100F0FD -:10319C00780008449168087408F042FA11E7084F67 -:1031AC00B87808E7064CDDE7AC88002034880020AE -:1031BC00B1880020A6860020AF880020AE880020B1 -:1031CC0024250020748800200C010020C0870020DA -:1031DC00BF880020BE880020B488002058BC0200A4 -:1031EC0054BC0200E88600202DE9F04F97B0DFF8C0 -:1031FC0010850546DFF80C6598F800000328307040 -:10320C0040F04C81002088F8000030700DAC204656 -:10321C0026F0BBFC2046002124F069FEDFF8E89480 -:10322C00B0603A21484625F049FE4FF0FF30A9F82E -:10323C001400C9F81000C9F80C0022F0B9FD0020E8 -:10324C0029461DF0F1FF06F11001F06026F02BFC71 -:10325C00D6E90502DFF8B474B0FBF2F1C9B2032968 -:10326C0028BF032189F800103970B2F5005F40F0D7 -:10327C001281B0EB413FC0F00E81F068002800F0E5 -:10328C000A814FF40050FF224FF000084FF0885B8A -:10329C00A9F80600FF2089F8032089F8058005901D -:1032AC000020089000200B9000200990002007902F -:1032BC000020069000200A9000200C90FF20029025 -:1032CC00FF200490FF200390CCB2A04580F0E98051 -:1032DC005FFA88F6002116AA0423304625F01AFF5F -:1032EC00DFF830443046002115AAA04730460121B2 -:1032FC0014AAA0473046022113AAA04716996FF0D2 -:10330C006F0050FA81F2C8B20E2A06D8012303FAD4 -:10331C0002F245F201131A4203D1A0F1FE02022A75 -:10332C0004D242F28352B2EB914F1ED0304614F0CD -:10333C0021FADFF8D0130028087040F0D280304614 -:10334C00002116AA042325F0E5FEDFF8C843304619 -:10335C00002115AAA0473046012114AAA0473046E7 -:10336C00022113AAA0471699C8B208EB4802CA4614 -:10337C003D4609EB8209C1F30142090A4C46FD287E -:10338C0004F8160F61709DF85610E270A17001D907 -:10339C00102135E0BDF854104FF6FF7291422FD139 -:1033AC000EA820F051FC304600214FF088524FF40B -:1033BC0000534FF4005725F0ADFE6FF0030313FAE2 -:1033CC0087F7B8B250F80B104A1C01D10328F6D875 -:1033DC0001220126D3B2042B06D8CBB2FF2B18BF87 -:1033EC0016460132090AF5E740F80B10CA480E9947 -:1033FC0000684268C948904757FA86F081B2207835 -:10340C00A9F81C109DF85210702889F81A10BDF8F4 -:10341C005010A9F81E109DF84E1089F81B10BDF81D -:10342C004C10A9F8201011D07828D14614D07C2843 -:10343C002F4616D07E281AD0FE281FD0FF2823D165 -:10344C000898CDF80C800130089020E00A98D146FD -:10345C002F4601300A901AE006982F46013006904C -:10346C0015E00798CDF81080013007900FE009980F -:10347C00013009901FFA88F0029008E00B98CDF803 -:10348C00148001300B9002E00C9801300C903978CC -:10349C0008F1010818E7012088F8000017B0BDE812 -:1034AC00F08F0C98974E00060BD10B98C0B20128E8 -:1034BC0007D80A98C0B2012803D80998C0B20128CD -:1034CC0011D99348042200240270CAB2E0B290428F -:1034DC0010D214F04FF93178013408433978307038 -:1034EC00F3E7884E1BE0089BD8B2A04219D188485C -:1034FC0000220270002089F8030089F80100481EA0 -:10350C007E2189F80200B9F81C00A9F806000020F9 -:10351C0021F0A6F899F80200FE2121F0A1F83078EC -:10352C00BCE70A98000624D00B98059A000603D134 -:10353C00039A180600F08480754802210127D5B241 -:10354C0089F80220017017FA82F0B0FBF4F101FB4C -:10355C00140089F80100284614F00CF93070284644 -:10356C00FE2121F07DF889F805700020FFF7DCF8CA -:10357C00D5E70B98059A000621D06548012189F8FA -:10358C000220017011FA82F0049AB0FBF4F101FBF5 -:10359C00140091B2FF2989F801001FD10299FF296B -:1035AC0019BF89F8031001EB410089F8030000EB07 -:1035BC00400009EB8000808BA9F80600AFE7DDE93D -:1035CC000620104300063FF47CAF22F0C5FBA0425E -:1035DC0080F085804E48032101703EE0480089F858 -:1035EC00032010FA82F009EB8000818B1829A9F8CE -:1035FC00061094D30739D0B20EAA89B216F058F837 -:10360C009DF843004007B0D5B9F80610BDF8462028 -:10361C00002399F8030000930323891A0EAA073993 -:10362C0089B206F0B5FE00287FF479AFBDF84410DE -:10363C0000293FF474AF9DF848001DF085F86EE743 -:10364C0022F08AFB0621A042314838BF032103290E -:10365C00017002D0062952D061E722F07DFB0546AD -:10366C0089F80C0000EB400009EB8000408BA9F8B6 -:10367C000D000CF08BFD39782844B0FBF1F202FB05 -:10368C00110089F802000130C2B2B2FBF1F202FB68 -:10369C00110089F801007C2020F0FCFFFF2812D1DA -:1036AC007E2020F0F7FFFF280DD1FF2020F0F2FF45 -:1036BC00FF2808D1782020F0EDFF014699F8010091 -:1036CC00FF2918BF0846C1B289F80300490051FA16 -:1036DC0080F009EB8000808BA9F806001AE70898A7 -:1036EC00000609D099F80200FE213C46374620F02E -:1036FC00B7FF2478039A40E7054806210170FEE7DE -:10370C0088270020A0230020A0800020978800207C -:10371C00A38800203B930200D80100100040034016 -:10372C002DE9F84305460C46480413D4A00024D4D4 -:10373C00A0075CD460057ED4200500F1068120072B -:10374C0000F13B81600040F1F68019F049FF24F054 -:10375C008044F0E025F0ECFEDFF81C140F6D3FB157 -:10376C00D7E90A1202F0E04201F00A01891849D0A7 -:10377C0026F08AF924F48044DDE0BB48DFF8FC73C2 -:10378C00016841F080010160B878012804D104205F -:10379C0020F0E8FF0020B87025F0CAFE0646042091 -:1037AC0025F06EFFDFF8D8130A68904219D12A7EF3 -:1037BC00BAB1FA68AAB1DFF8C003806C002800F037 -:1037CC009780C16840F603020988914206D0C06810 -:1037DC0040F604010088884240F08A8005F114000C -:1037EC0088E040F6C4120860C5E9042284E009F0C0 -:1037FC0061FBDFF88403006C002840F09D8024F00E -:10380C00020498E0D7E90A65D7E90A12AA43B14342 -:10381C00C7E90A1226F038F9B8680028AAD056EA87 -:10382C000500A7D0D7F808C03869B7F93010324670 -:10383C002B46E0479EE725F07BFE054623F0B0FCC7 -:10384C00002800F0B780CC48876B002F00F0B280C6 -:10385C00DFF828830420CB49002288F81800C648DA -:10386C0025F0C0F826F03AF9C74826F007F9C74802 -:10387C000068006B8047C8F810000125042088F808 -:10388C00025021F08DFD386990F82810C8F804001A -:10389C00490703D5436A04210022984701201BF0F5 -:1038AC0029FCD8F80400457612F0F0FFD8F8040093 -:1038BC0081680B461A465B684BB11E88A6F6030658 -:1038CC00072EF7D805FA06F616F0830FF2D0537BC5 -:1038DC0003F0F003013353730023FD6853602D880C -:1038EC00A5F60305012D00F28A80C8F810309FE080 -:1038FC0005F110001EF0ACFA304626F0C5F821F0A8 -:10390C0067FD78B12E6A28466FF4807100224FF063 -:10391C000073B0479848806B10B119F061FE01E05C -:10392C0044F00204EE692846002100224FF0806327 -:10393C00B04724F0005434B1974821462830BDE8F4 -:10394C00F84326F081B9BDE8F8838C4EB078012895 -:10395C0004D1042020F006FF0020B07021F038FDC7 -:10396C0038B170686FF4807100224FF00073056AF3 -:10397C00A847306950B185480068006B80473269B0 -:10398C007168801A000BC860002030617A4D814943 -:10399C000022284625F026F802203076286C20B12B -:1039AC007D480221283026F04FF919F019FE24F435 -:1039BC000064C0E726F092F841E025F0B9FD054619 -:1039CC0023F0EEFBA0B1DFF8B48198F800000007FB -:1039DC000ED498F9000000280AD4684613F0E4F9D4 -:1039EC0008B1009820B1DFF8B49199F8610048B3A0 -:1039FC0026F074F819F0F4FD24F008049BE7034654 -:103A0C0033F8385FA5B190F8445090F8456005F054 -:103A1C00F00580F8445006F0F005013580F845506B -:103A2C0000255360C5634587507B00F0F000507350 -:103A3C0057480022C2610160012024F003F824F4ED -:103A4C00806478E700260127602E0FD009EB060072 -:103A5C00817A31B18772407A07FA00F0C0B220F057 -:103A6C009BFE2036F0E700BFCC210840032088F8ED -:103A7C001800454826F002F826F030F8444F3E4D29 -:103A8C000022786900207861F968F860284644497A -:103A9C0024F0A8FF3D480068006B8047D8F80C1054 -:103AAC00D8F82020411A02EB1130B0EB113F38BF8F -:103ABC004FF0FF3098F82410C8F8200021B1D8F846 -:103ACC000810B0EBC12F20D923F0CCFFB8B140F6D1 -:103ADC000900414621F83C0F002048804A7B02F047 -:103AEC00F00201324A730A7B02F0F0020A7348605A -:103AFC00F8613960B8F83E0010F4406FFAD000203D -:103B0C00C8F82000012088F824001DF045FB25484A -:103B1C00002101600220002123F094FF022020F0FC -:103B2C0021FE102011F08CFE98F8010020B9D8F875 -:103B3C000400503026F084F81B48807810B90D2012 -:103B4C0011F07EFE98F8250028B1002088F8250099 -:103B5C00052020F007FE002088F818001348C8F84C -:103B6C001C000220B5F85610B5F85420914208BF3D -:103B7C00072018F07DFE3DE730210020D01E0020EC -:103B8C00D426002089710200207F00208C010010B7 -:103B9C0000100440D10C010070200020B87B0020E4 -:103BAC0051D6010000000460ACBB0200A903010067 -:103BBC002DE9F04F8DB084780226142C00F21F8270 -:103BCC000546DFE814F02900150015004A008500B1 -:103BDC001C021C021C021C021C021C021C021C02E9 -:103BEC001C021C021C028E009C00AF00BE00CC000C -:103BFC0001206A78022C8DF83100089240F0C080C8 -:103C0C00E878291D03288DF82C0040F0E18009A8E4 -:103C1C00082225F0B7FAE0E010208DF824001020DF -:103C2C0025F0FCFF98B10446DFF8E0032146606004 -:103C3C00E81C10F0FFFA8DF8240028B9204623F078 -:103C4C0051FB8DF8240010B1204625F0E5FF00262D -:103C5C0009AB642000210122C2E10020CDF82A002A -:103C6C00ADF82E00CDF8260002208DF82C00E81CB3 -:103C7C0025F0D0FFADF824006979A8798DF82D10C6 -:103C8C0025F010FB8346E81D25F0C4FF95F80C9039 -:103C9C008046687AAC7A95F80BA04FEA49078DF804 -:103CAC003100384625F0BAFF002800F01081CDE92C -:103CBC00074806464FF0000805EB0800474570D052 -:103CCC000D3025F0A7FF26F8080008F10208F3E7ED -:103CDC00E87820F065FE8DF8240009AB64200421FF -:103CEC0089E1E978032900F25281281DDFE811F0FF -:103CFC000400510155015D0118F05CFE76E1E81CF1 -:103D0C0025F088FFC04C6668002E00F0E4806A79CC -:103D1C00002A00F0E4803368A91D184425F032FA1B -:103D2C000020D9E0B84EEC1C04212046376822F064 -:103D3C00EFFB002F4AD0B968814200F0A0803F68A9 -:103D4C00F7E7A888ADF82400E87809A924F058FA18 -:103D5C008DF832000DF13203642013214BE1002663 -:103D6C00E878ADF8246009A923F066FCBDF82400BE -:103D7C000DF1320314210222ADF8320064202FE140 -:103D8C00E81C02218DF82C1025F044FFADF824001E -:103D9C00002005F10608ADF82E0068798DF82D008D -:103DAC0026E0BBF1000F00F0B580437B0DF1310133 -:103DBC000E30CDE90496CDE9000107985946CDE9BE -:103DCC00020A09A8089A1DF089FEA4E0012000E16E -:103DDC00084625F01FFFADF82400287B8DF82D0038 -:103DEC0005F10D0025F016FFADF82E0005F10F08BA -:103DFC0098F8000025F056FA054608F1010025F068 -:103E0C0009FF98F8036098F804A098F805B081466B -:103E1C00022C8DF8326009D108F1060025F0FAFE6B -:103E2C00074608F1080007F10A0104E098F806704B -:103E3C0008F1070039464DB10A3189B2FB2907D385 -:103E4C00DFF8C481D8F8040000286ED0022009E005 -:103E5C000DF132018DE8030C09A84A463B46294670 -:103E6C0003F016FF089E8DF8310006F0E0002028C4 -:103E7C0040F0C4800DF1310364202146BBE0EC1D01 -:103E8C00204625F0C7FE6D7A002D00F0978005F1D5 -:103E9C0002098246484625F0C1FE002800F09880B1 -:103EAC000026457080462A460670786800EB0A01A9 -:103EBC0008F1020025F066F95FFA89F264201221FC -:103ECC0043461EF0D5FB404625F0A6FE97E0102099 -:103EDC008DF8320024E010208DF8240016E0D6F87E -:103EEC0000C0F38AB28A3169757EB77E06F118007C -:103EFC00CDE900C0301DCDE9025703F0C9FE8DF8A5 -:103F0C002400606825F088FE0020606009AB642006 -:103F1C00112170E002208DF83200304625F07CFE35 -:103F2C000DF132036420032165E007F11C0025F03C -:103F3C0075FE0028C8F8040055D000F11C010C22B5 -:103F4C00016000208DF83100D8F8040009A9043074 -:103F5C0025F018F9D8F804000F214FF47A72056196 -:103F6C002A4DC17680F81AB080F819A00676C7825F -:103F7C00A0F814900821287825F0B6FD089E00289A -:103F8C003FF473AF287808211AF05CF86DE7022033 -:103F9C002CE000781AF086F828E0007825F082F9F9 -:103FAC0018B324F063FE002020E025F033FEA9793D -:103FBC0025F096FBB0FA80F0400917E03068B84263 -:103FCC0001D138683060384625F026FE002000E02C -:103FDC0010200026207064201221022223466670D5 -:103FEC001EF046FB0BE010203CE701208DF824006E -:103FFC0009AB6420102101221EF03AFB002630464A -:10400C000DB0BDE8F08F00BF5C2600209688002024 -:10401C002DE9F04F8FB00C4608040CD4A00426D424 -:10402C00DFF88853287802282DD1E10740F0018170 -:10403C00A10641D558E0DFF86C0300781AF000FDBA -:10404C0090B10178DFF8602305460020602808D085 -:10405C00135C08308B42F9D1104450F8041C2846EC -:10406C008847284623F0F8FE84F4004595E11DF0BE -:10407C003BFC28B10546FCF7EDFD284623F0ECFE91 -:10408C0084F4005589E1A1062ED4012814D8E10648 -:10409C0000F11781610600F12F81210600F13D81AD -:1040AC00E10500F13F81210500F14181E10400F1BE -:1040BC005481610400F15B81A10700F1E080A1054E -:1040CC0000F1FA80210700F11181610500F11981DD -:1040DC00E0034FF0000540F160811BF037FFB6485C -:1040EC00C57084F4803558E1AE4F202138781FF02C -:1040FC0061F8DFF8C4820125D8F80810084317D0FE -:10410C0025F05EFD054625F059FD68434FF47A71A4 -:10411C00B0FBF1F0D8F80810401A4FEA500538BF40 -:10412C006FF00045002908BF0D46002D00F0C2803D -:10413C0000200421002222F055FD06464FF0060A0D -:10414C004FF0FF094FF6FF780DF1080B002E4DD004 -:10415C00304604210022374622F044FD06463889B9 -:10416C00401B38BF002038810004EFD1B87BD0B39E -:10417C0001280AD17889400707D4386887F80DA040 -:10418C00B721407B1DF068FBE0E739685A468DF893 -:10419C000690ADF80480086AC97F0CF089FF0128ED -:1041AC001BD1B87BB97A8DF838000907788A40F0B2 -:1041BC008002ADF8362006D540F4C070ADF836005C -:1041CC00387B8DF83A00786910B1007BADF8180097 -:1041DC00584601A9002202F027FC387B87F80DA075 -:1041EC0016F038F8B2E701207873AFE7DFF8C88132 -:1041FC006C4F22F057FE00200121002222F0F2FC2D -:10420C0018B13878202119F01DFF0020042100225C -:10421C00002622F0E7FC002847D006890421002262 -:10422C0022F0E0FCA0B10289B1B2914228BF16463F -:10423C00F4E7654890F82C100F2906D190F8260069 -:10424C00022802D3002021F07BF884F00105A4E0C1 -:10425C00A8B2B1B2814223D9D6FA55F0202180B24E -:10426C004200387825F040FC25F0AAFC054625F0E4 -:10427C00A5FC68434FF47A71B0FBF1F615E0534896 -:10428C00007818B302AD284625F0A5FB25F074F98B -:10429C004F490B784F490A7829461AF0A7FE22E0BD -:1042AC003878202119F0CEFE0026C8F8086084F07A -:1042BC00200572E000259CE715F0C8FB84F400751E -:1042CC006BE008F05DF984F0100566E03E48418B28 -:1042DC00012025F099FC2878022804D131480121CD -:1042EC0000781AF07FFB84F0020556E03248012179 -:1042FC0084F00805817050E00CF0D4F884F040058F -:10430C004BE0022808BF15F0A5FE2F480121808C38 -:10431C0025F06CFC84F480653FE024F091F984F086 -:10432C0080053AE022F0BAFA84F4807535E01BF08F -:10433C0049FB2048007801280CD11D48007848B171 -:10434C004FF47A7100FB01F216484FF400610078CB -:10435C0025F0C7FB84F400651FE01748017819B1FC -:10436C00002101701BF02EFB84F4805515E01448DD -:10437C00006880B11149097801290CD18047114896 -:10438C00006800B1804707484FF480414FF47A72BF -:10439C00007825F0A6FB84F4804528460FB0BDE8D4 -:1043AC00F08F00BF9888002030B50200182600203E -:1043BC00BC270020BD270020E8250020BA270020BC -:1043CC008423002090230020407B0020972700208E -:1043DC00C0270020C22700202DE9FE4F8846080484 -:1043EC0026D45FEAC87004BF0020BDE8FE8FE54804 -:1043FC00056825F0E5FB044625F0E0FB60434FF42F -:10440C007A714FF6FF72B0FBF1F14FF6FF70002D91 -:10441C0000F01A812B886C88CB1A9BB29C4240F21C -:10442C001C81E31A94B2A342B8BF1A46ED68EEE7BA -:10443C00DFF840A3CDF804809AF800001AF000FBD6 -:10444C00002800F0FC8006460078012840F0EC8043 -:10445C00DAF8041096F83390D6F814B096F8138066 -:10446C0021B148468847002840F0DE80718896F8D4 -:10447C003100022222F05EF90546002842D0287A4B -:10448C00297CA0F10108FF2900F0BB80707F4F460A -:10449C00C00718BF0027E97C287D0144B94204D825 -:1044AC00E974FF2101FA00F06874A969A87C96F8F8 -:1044BC003020896A10FB0710F16A24F063FE287D16 -:1044CC00697CB7FBF0F202FB107001228240D2B281 -:1044DC000A436A74C8457CD196F83010AB7C13FB48 -:1044EC000713A9698B844FF4FF7303FA00F0C0B271 -:1044FC001043FF2868746CD1287C1AF0CFFDFF2084 -:10450C0028747FE0707FC00700F08E80B07F24F0AD -:10451C00C9FE002800F0888004461C2025F07EFB94 -:10452C00002800F081801C21054624F0C7FCB07FD8 -:10453C0002A923F081F89DF809000221287528466C -:10454C0023F0D0F8708896F8312096F8301096F851 -:10455C003330A880287DEA71FF2202FA00F06874DB -:10456C0060680078A9742874302013FB010080B2B5 -:10457C0022F074FD0028A8615DD004461A20B11CFD -:10458C002060708CA080A01D23F048FEF27F04F107 -:10459C003000B17F96F82830C4F81CB084F819802C -:1045AC00A062307CE273744A217563750121A07599 -:1045BC00928C2282F28EA285F28C6282B6F8110065 -:1045CC00A4F817009AF8000085F8089019F03AFD45 -:1045DC0055E725F0F5FA044625F0F0FA60434FF460 -:1045EC007A71B0FBF1F0654928806348097800794D -:1045FC004843642148436249097800FB0100688004 -:10460C0000E04F46E87C297D6A7C01440139B942BF -:10461C0018BFFF2A0CD186F83300708806F11C01F4 -:10462C0086F8342016F0A5FF304623F015FC03E77E -:10463C00C845F9D1EFE7284623F064F8F4E7019870 -:10464C0080F40040BDE8FE8F92B282424BD04948C4 -:10465C000121007825F048FA45E0A879022806D116 -:10466C00287CFF2837D0A86923F0F6FB33E025F02F -:10467C00A7FA044625F0A2FA60434FF47A71B0FB16 -:10468C00F1F03F49288095F83800097888421BD210 -:10469C0095F83620FF2A06D195F83720013085F899 -:1046AC00380085F8362095F8351095F8394082F0A9 -:1046BC00FF0300200126C7B2A7421DD206FA07F756 -:1046CC001F4214D10130F6E7EA8BA87E95F82A1028 -:1046DC00E9231EF0B9FE284623F014F825480121E1 -:1046EC00007819F0AFFC88F00100BDE8FE8FFBB23A -:1046FC0001441A4385F83620AB8F95F83440C8B284 -:10470C0004FB10339EB2A64203D2FF2285F836205A -:10471C0002E0FF2A08D12346184A174E1278367940 -:10472C0072436426724302E095F83A2023466A806D -:10473C002A8D0E0606D022F0200244432A852A6CCC -:10474C00224404E042F020012A6C2985297A85F85C -:10475C002E10E9796A6285F82D10D9B26984054961 -:10476C00496811B188470028B8D105F1100004F050 -:10477C0021FAB3E73C260020407B0020B027002024 -:10478C00B6270020546500207FB50138072800F2B9 -:10479C004C810C46DFE810F008002C0054006E0031 -:1047AC0089004901A600C900CB48007801380128CE -:1047BC0000F23B81002C00F04781002003210024F3 -:1047CC001FF07CF8C64DC74E0420042132222870FD -:1047DC00307825F089F90820002107F097F8307817 -:1047EC006C704FF4805104B0BDE870401AF0FAB808 -:1047FC000020002524F05EFDBB480121017004203F -:10480C008DF80D0074B1B548B34C4585207801285E -:10481C0003D1072023F066F92078022802D1062064 -:10482C0023F060F9AE48042132220570AD480078BF -:10483C0025F05AF9A94890F82B1001F0FE01F2E08E -:10484C00A54800780138012800F2EF80A548042122 -:10485C003222007825F048F9002C00F00F819F4C93 -:10486C009F48012101702069002800F0EC801FF0A6 -:10487C00C7FBF8E70120002C8DF80D007BD0974882 -:10488C0000219B4A80F82A10984824F0DBFE924CB9 -:10489C002078012803D1072023F024F9207802285E -:1048AC0070D1062023F01EF96CE002208DF80D006B -:1048BC008A48002C73D000218D4A80F82A108B482E -:1048CC0024F0C0FE002003211EF0F8FF824C20785B -:1048DC00012803D1072023F005F92078002877D18F -:1048EC00092073E07C4D00208DF80D00002C2878F9 -:1048FC007BD018B9092023F0F5F82878022806D1C6 -:10490C000820002107F002F8042023F0EBF810F047 -:10491C00F1FF73480021C822017070480D2180F806 -:10492C002A10704825F06FF878E005208DF80D00FE -:10493C0069480078022878D1002C00F0C3806848C0 -:10494C000022C178C270017042F20800002106F00A -:10495C00DDFF62480D2190F82B2080F82A10C178D9 -:10496C0002F0DF02002980F82B200CBF04200D2060 -:10497C0023F0B8F859E05848007818B95748022184 -:10498C0080F82A105648002132220170554825F033 -:10499C003AF8524890F82B1001F0FD0143E0082141 -:1049AC0080F82A104C490978012911D890F82E006A -:1049BC0070B900200DF10A018DF80A0052201DF08B -:1049CC0057FB24F0F3F91EF09BFB002023F08AF830 -:1049DC004348002132220170424825F014F83F4828 -:1049EC0090F82B1001F0FB011DE03C4C022812D179 -:1049FC0094F82E0078B194F82B00002140F02000A0 -:104A0C0084F82B0005208DF80D00082006F07EFFA1 -:104A1C000A2023F067F8022084F82A002F4890F827 -:104A2C002B1001F0EF0180F82B102C4800220323EF -:104A3C0090F82A008DF80C002A48007803A9009100 -:104A4C000A211EF012FA7FBD244C0720254D4FF48D -:104A5C00805184F82A0001208DF80D00287819F077 -:104A6C00C1FF0020002622F031F82878022141F203 -:104A7C00883284F82B6025F037F8D6E7174C0220E3 -:104A8C0000218DF80B1084F82A001548017094F859 -:104A9C002B000DF10B0100F0FD0084F82B00012020 -:104AAC008DF80D0052201DF0E3FA24F07FF91EF072 -:104ABC0027FB002023F016F820690028B5D01FF042 -:104ACC009FFAF9E70548022180F82A1090F82B107C -:104ADC0041F02001A7E700BF18260020AC220020DF -:104AEC00088800209F880020AD270020407B0020F4 -:104AFC008027002092B0DFF8EC92D9F8000010B1BA -:104B0C00002180F84510483020F02AFE24F010FDDA -:104B1C008046072011F006F917F0E0FE10B1B248FC -:104B2C0024F0AAFE1AF03EFB01AD284624F09AFBB5 -:104B3C000427002029468DF8047024F09BFBAB4C15 -:104B4C00206023F0E9FF0AAD284624F03BFA002050 -:104B5C0029468DF8287024F03DFAA54E306023F0DC -:104B6C00E5FF06AD284624F03DFA002029468DF8D5 -:104B7C00187024F03FFA31689E4D286019B99E4890 -:104B8C0024F07AFE286810B99C4824F075FE206841 -:104B9C0010B99B4824F070FE1CF086FDD9F800007B -:104BAC004FF0FF3438B1CDE9104410A9082223F09E -:104BBC0039FA01281BD1CDE91044082025F02EF834 -:104BCC00002846D005460026052E04D824F0BEFE4B -:104BDC00A8530236F8E74FF6300029460822E88041 -:104BEC00884824F0CFFA284625F016F809E0D9F8C1 -:104BFC000010CDE910440029DFD08248082224F0AF -:104C0C00C1FA10AA0120082124F0F4FD092800D0D3 -:104C1C00D8B921F079FD800712D4CDE91044CDE943 -:104C2C000E440EAB01200021082224F02DF960B9AE -:104C3C000EA810A9082223F0F5F9002800F0CB806B -:104C4C00704A0120082124F0DBFD6E49E2201DF0A2 -:104C5C000FFA12F077FB282024F0E0FF6A4E0028B0 -:104C6C00306055D0694F6A4C07F10C0524F0C7FE33 -:104C7C0024F018FA3068056007F1100524F0BFFE27 -:104C8C0064498968D1F84C1388473068456007F14E -:104C9C00140524F0B4FE1CF00DF93068856007F1A2 -:104CAC00180524F0ACFE19F05BFD3068C56007F107 -:104CBC001C0524F0A4FE1FF0CFFB3068056107F142 -:104CCC00200524F09CFE1EF0B1FA3068456107F116 -:104CDC00240524F094FE1DF043F93068856107F13A -:104CEC00280524F08CFE23F02FFD3068C56107F1F8 -:104CFC002C0524F084FE20F0BBFC3068056207F123 -:104D0C00300524F07CFE387024F014F830684562CD -:104D1C0018F08CFE404841494FF00009CDF8409006 -:104D2C0001603F480321119010A820F0F1FA24F003 -:104D3C0091FB404624F0A8FE17F0DEFE24F02EFE78 -:104D4C0001201DF095FE19F033FF3748007802283A -:104D5C0008D134480078012804D14FF400400121D7 -:104D6C0006F0D4FD294F4FF48041387824F07CFCB8 -:104D7C002E484FF0FF3100680DF036FCDFF8B080A4 -:104D8C0078684FF0FF310DF02FFC3068002550F89B -:104D9C002510096821B9691C092D0D46F7D3EFE7D9 -:104DAC0024F0CFFD316851F825100C68C1F8009043 -:104DBC0024F0A3FE58F825200020214690470446F5 -:104DCC0024F0BFFD316851F825100A6822430A60AF -:104DDC0024F093FED4E70B480EA9082224F0D2F954 -:104DEC0033E700BF5C270020F0B50200F0870020FD -:104DFC00F4870020F88700200EB6020021B60200CE -:104E0C0034B602009E8700206C8800208821002088 -:104E1C00094702000C0100209C230020A5C70100BB -:104E2C00008D1500D527002018260020488800206A -:104E3C0074B802002DE9F04F89B08A4608040DD4ED -:104E4C005FEACA7040F01D815FEA8A7000F12B8125 -:104E5C005FEA0A7000F13381002042E1A24F3878FA -:104E6C0019F0EEFDDFF88892A04C06464FF0000BCF -:104E7C0048F21508002E00F001813078312838D026 -:104E8C00322849D0D32840F0B380F089404573D004 -:104E9C00382840F0AD80CDF820B0CDE906BB3046C7 -:104EAC0006A920F03DFB9DF81C10052968D8307B25 -:104EBC00002840F09D809DF81D00002800F098808F -:104ECC00052800F29580069823F0ADFD002840F0EF -:104EDC008F80707C87497870708808809DF81D00E1 -:104EEC00214601388DF81D0006A890E82C002CC135 -:104EFC007EE0B87803287BD899F82E10804823F0F0 -:104F0C0092FD002874D1FF207C4960717088088064 -:104F1C00B088794908806BE06079FF2814D00020B4 -:104F2C0016F074FA0246B9F8701078783346CDF85A -:104F3C0000B012F04FFD6079002859D03878082164 -:104F4C00322224F0D1FD53E099F81810706820FA41 -:104F5C0001F2D2071ABF3144097A002106F1080286 -:104F6C0000231B2B42D020FA03F5ED0702D0D55CB1 -:104F7C00A9421ED80133F4E7304621F007FD37E093 -:104F8C00FF293DD0FE2956D199F872109DF81E00CC -:104F9C00884202D860BBFF292AD11CF06BFE06990F -:104FAC0000201B2859D021FA00F2D20757D101302A -:104FBC00F7E7B9F86E004F49334608804E4802882F -:104FCC004E48018810200090002012F003FD0120B3 -:104FDC00F870B87840B93C2002214EF66022B880B7 -:104FEC00387824F081FDB8780130B87084F805B0B9 -:104FFC00304622F031FF387819F022FD064639E7A9 -:10500C0099F872109DF81E00884203D80028EFD141 -:10501C00FF29EDD11CF02EFE069838B1D9F82810D6 -:10502C00814203D0C9F8280022F06CFDBDF82000A5 -:10503C0023F0BAFBDCE7307B0028D9D170882D49EE -:10504C00802200230880707CCDE900BBCDE902BB37 -:10505C00CDE904BB11F074FBCAE71B2000E0C0B221 -:10506C0099F818108142C3D02649087099F80700A6 -:10507C00642100FB01F23878012162E78AF40040D8 -:10508C002FE020491A4C08782076E1201CF0F0FF24 -:10509C0022F038FD0020A4F87000012016F0B6F9BB -:1050AC008AF001001DE010488188B1B101394EF63B -:1050BC00602281800078022124F016FD0FE00B4C59 -:1050CC00607938B12179206823F0ADFC10B9607992 -:1050DC00013860718AF0080003E0002181708AF0C9 -:1050EC00020009B0BDE8F08FCC24002040870020DE -:1050FC00407B00207A8700205E840020DA8000202C -:10510C0000F8FF079B8800202DE9FE4F0746086832 -:10511C000024B0B1D7E9018A0E4624F009FA814681 -:10512C00D8F8E800082888BF0124B068204202D1D2 -:10513C007068204208D003203074484624F0A4FC48 -:10514C0000242046BDE8FE8FD8F8C01069B198F84D -:10515C00F8100029EFD006213174D8F8C410C8F823 -:10516C00C4604E6198F8FC100DE000210522C8E9DE -:10517C003066C8E93411C8E9361198F8FC100029DA -:10518C0008BF0122327400220129726109D1022068 -:10519C004FF4E02188F8FC0098F8FB001FF0C8FFE2 -:1051AC00706889490138884205D8042020F0F8F845 -:1051BC00062020F0F5F8022020F0F2F898F8F8001C -:1051CC0040B9DAF83C003168814203D298F8FC000F -:1051DC0000286CD0D8E9361009B118B900E028B312 -:1051EC0024F015FCDAF80000416941F0010141613D -:1051FC00484624F049FC98F8F80008B10124A0E7CF -:10520C0008F16C05D8F8EC10284624F0B3FB002804 -:10521C00F4D0D8F8C00003210174384612F0EAFF2C -:10522C0028460021002424F0A5FB8AE79AF8040004 -:10523C0024F0D2FC654CDAF810100222206991FAA5 -:10524C00A1F1B1FA81F14368D8F8CC00406800684C -:10525C0098472069DAF8141002224368D8F8CC0079 -:10526C0091FAA1F1B1FA81F14068006898479AF877 -:10527C00040022F087FA9AF8040024F0AFFC24F022 -:10528C00C6FB0020C8F8E000D8F8C0000068B0F5F4 -:10529C00806F01D924F0BBFB98F8FE000028A1D147 -:1052AC00DAF80000416841F0020141609AE798F891 -:1052BC00F90020B1D8F8EC0001307FF48BAF4846F0 -:1052CC0024F0E2FBB2683AB1D8F8E80002210928D0 -:1052DC0038BF0121009103E008F1F4020020009096 -:1052EC00746834B1D8F8E8000227092838BF0127C0 -:1052FC0002E008F1F6040027DAF80000334D4168AB -:10530C0041F002014160D6F800B0D946BBF1000F64 -:10531C0040D0D8F8E800019209284FF0010011D2D2 -:10532C002A68B9F1000F1FD0C0071DD02178DAF818 -:10533C0000009268904700281EBF3C44A9F1010967 -:10534C000120EDE72A68B9F1000F16D0C00714D080 -:10535C002188DAF800009268904700281EBF3C4470 -:10536C00A9F101090120EDE7DAF80000D26802A9E1 -:10537C009047DDE90120107007E0DAF80000D268F0 -:10538C0002A99047DDE9012010800098ABF1010BD8 -:10539C000244BBE7D8F8F000DAF80010CA68024003 -:1053AC00102802D1002AF9D101E0002AF6D0706849 -:1053BC0022F070F8D8F8C0100020C8F8C400C8F863 -:1053CC00C00008741AE700BFFEFFFF0FC4010010F5 -:1053DC002DE9F04F85B08846080418D4A948007808 -:1053EC00012802D85FEAC87155D15FEA88714CD4A4 -:1053FC00022807D1A4480078012803D15FEA48703D -:10540C0000F188805FEA087057D400202BE1DFF8A8 -:10541C005CA29AF8000019F013FB002800F021811F -:10542C000546807FC8B9688C132816D190486E88C1 -:10543C0000F11C09002049464F46002818BF071DE3 -:10544C00086850B1014631F8042BB242F4D14468DB -:10545C003C6024F0E1FB2046F3E7A87A05F1020B4F -:10546C00022840F0E480DFF8089295F83170BBF820 -:10547C00006009F11C000068A0B10188B14202D1A2 -:10548C008178B94242D00430F5E7794801210170A6 -:10549C0088F00200E7E07648406900B1804788F068 -:1054AC000100E0E0D9F81C40002C57D001206168C5 -:1054BC00002955D001300C46F9E77048DFF8B0915F -:1054CC00807BD9F81C60000760D424F079FB04467B -:1054DC0024F074FB6A4A60434FF47A71B0FBF1F02C -:1054EC00D9F818101288411A91427AD3B1FBF2FB09 -:1054FC000BFB02F2511A08445E49C9F818001FFA56 -:10550C008BF00978884288BF8B4641E0594909786D -:10551C00C170A3E05E495D4800224FF6FE73002483 -:10552C000978023079B130F8025C9D4208D0458888 -:10553C00013D45802D0406BF027020F8023C012479 -:10554C0001390630EEE734B1484804214FF4FA72C1 -:10555C00007824F0C9FA88F0040084E000240020CC -:10556C00454980B20988884261D2082024F056FB54 -:10557C0000285CD000210680877041603D49097885 -:10558C00C170D9F81C1079B360603FE04FF0010B8B -:10559C0000205FFA8BF44FF0000A071D002808BFAB -:1055AC0009F11C0796B1F078C0FA5BF1A042F170DA -:1055BC0006D8756830463D6024F02EFB2E46F1E788 -:1055CC00716830460AF1010A0E46E6E75FEA0A40C6 -:1055DC0007D100200821C9F818002448007819F0D8 -:1055EC0001FA88F008003EE0C9F81C002348807BD3 -:1055FC0000070BD424F0E4FA044624F0DFFA6043ED -:10560C004FF47A71B0FBF1F0C9F818001B48807B9D -:10561C0000070CD59AF8000008211DF0CBFD30B91D -:10562C001748082102889AF8000024F05AFA2878C2 -:10563C00022810D0012811D1297EAA89EB7C05F112 -:10564C001C006C696E7E8DE85A0005F110035946FA -:10565C0005F0FEF802E0284615F0A0FA284622F0E4 -:10566C00FBFB88F4004005B0BDE8F08F9588002066 -:10567C002C240020B52700207A270020407B002016 -:10568C007E27002018260020D52700204C6D0020F6 -:10569C00912700202DE9F04F87B0851C83462846C2 -:1056AC0024F0E9F901AC06461821204623F006FC4B -:1056BC009BF801A004F10B002946009524F059FA3F -:1056CC006FF001009BF80A1002240122ADF81800BB -:1056DC0000208DF81A408DF80C0001F00800C1F381 -:1056EC00C007890782EAD00507D4002808BF012427 -:1056FC00B946A8460027002507E004244FF000090E -:10570C004FF00008002808BF03248548007850EAB1 -:10571C000A000BD0834890F82600082809D123F002 -:10572C0079FC00285AD0BAF1010F57D14FF0C309B8 -:10573C0001E04FF0C2090025BAF1000F10D07F48EC -:10574C00007890B9BAF1010F0FD1002E55D000207E -:10575C00214601228DF81A0001A814F03BFA0AE048 -:10576C0001A81BF06DF986B91CE001A82146524630 -:10577C0014F030FAB6B17179BAF1020F41F040026F -:10578C00727104BF41F0600171719BF80A104906F7 -:10579C0003D5717941F080017171B1790024013127 -:1057AC00B17100E00124B0FA80F149090D422CD10D -:1057BC0007D1002D18BF814641F20100494618F06F -:1057CC009EFF14B9009819F061FBBDF818004FF654 -:1057DC00FE71884218BF24F02BFA16E0DEB3327942 -:1057EC00A24218BFBAF1020F12D1D01EC0B20128CA -:1057FC001BD857EA050020D12AE0022021460122BD -:10580C008DF81A0001A814F0E5F907B0BDE8F08F87 -:10581C004FF00009009953468DF81A903088ADF876 -:10582C00180024F0E5F9012586E7501EC0B20128C6 -:10583C000ED849EA0800012807D1308821F0AAF9CE -:10584C0050B93088ADF8180008E0308824F0F0F931 -:10585C00009819F01BFB0026BDF818004FF6FE71DE -:10586C0088421ED120F08EFF10B1BDF8180011E057 -:10587C00BAF1000F04D02C4D288821F08BF930B1EF -:10588C009BF80A0000F002001FF0BAFD00E0288827 -:10589C00ADF818004FF6FE71884202D14FF0C709DF -:1058AC0049E79BF80A200099534624F0A1F910B15E -:1058BC004FF001093FE71D48016811B1BDF8180010 -:1058CC008847BDF818000099224606F0D9F806461C -:1058DC00174818490A6800784FF4803124F004F90D -:1058EC0001211548C17096B1AAF10100C0B201287E -:1058FC0007D81020BAF1020F08BF082071790843AD -:10590C0070714FF0000901258DF81A9014E74FF6CD -:10591C00FE7000254FF001090026ADF818000BE7CA -:10592C00F4240020407B00207427002098230020C2 -:10593C0098880020B0BC0200E82500201826002022 -:10594C002DE9F04F8DB0044600209A4616460F46BE -:10595C00CDE90B00CDE9090087488568804614F035 -:10596C00B8FD1C2803D014F0B4FD1B281BD13088C3 -:10597C0040F60201884218BFB0F5C15F03D1F07B3D -:10598C00022810D93EE043F6070188420BD196F865 -:10599C002400032807D33069784940F0806020F058 -:1059AC00604088422ED100206FB366B3387825FA58 -:1059BC0000F0C00726D03046002124F029F97048A9 -:1059CC00C4E90176006880B109A800900CA90BAA63 -:1059DC000AAB304609F00CFF0B980B214FF6FF7207 -:1059EC00502321F06FFFFF280CD023F0A1FD654F51 -:1059FC0006467878012802D840B1012070E0304684 -:105A0C0024F042F800200DB0BDE8F08F09F064FEE0 -:105A1C005D480DF10409016841F0020101605B4829 -:105A2C00C8F80000484623F00DFCDFF864B15A4971 -:105A3C004A469BF801009BF80050039055482830CB -:105A4C001EF0F8FE554856494A461EF0F3FE4846ED -:105A5C0023F008FBDFF84C81534A19214B46029581 -:105A6C0040461DF0B7FA514A08F11C001A214B466A -:105A7C001DF0B0FA4E484F4923F0D5FF4E484F4920 -:105A8C0023F0D1FF4E48006810F4402F06D04D4A49 -:105A9C0007F128000421002321F04CFB9BF80200A5 -:105AAC0010B10D2010F03EF908F1400022F0A5FFD6 -:105ABC0008F1380022F0A1FF434900200722387674 -:105ACC00B8843862386181F860200521C7E902107A -:105ADC003E49F96138700420002121F0B3FF787839 -:105AEC002C4941F8204001307870304623F0CCFF2F -:105AFC00BAF1000F06D10DF1040A354920225046A7 -:105B0C0024F0F8F8DAE90012BAF81000DAE90635F0 -:105B1C00002AB2FA82F608BF40F6C4126261216014 -:105B2C0060832563760926764FF4FA76C4E903621E -:105B3C0001226276274AC4E90722C4E90923DAF86C -:105B4C000C0000B12062DAF8140000B16062DAF8DF -:105B5C00080000B1E06104F13800C82123F0AEF96F -:105B6C0004F15000002121F0ADFF1B4904F1B800F5 -:105B7C0023F059FF204646E7CC2108400F000005D2 -:105B8C0074260020D01E002000200940110000E0E7 -:105B9C00ACBB020070200020BD80020028800020D9 -:105BAC00E54901003021002051D60100ADB80100BB -:105BBC00647F002065710200207F00206980020054 -:105BCC00B44F005049000200B87B0020A90301002B -:105BDC0064B90200BB2E0100259B02002DE9F04F99 -:105BEC0087B000240293002A00F03D81074603A8E9 -:105BFC0092460E464FF0200B10300190504610F894 -:105C0C00011B25290CD0002900F02A81022EC0F09E -:105C1C00D980013E002F00F0D48007F8011BD1E0A1 -:105C2C009AF801002D2806D19AF802000AF1030314 -:105C3C004FF0010C03E00AF102034FF0000C302886 -:105C4C000CBF13F8011B01462A2920D1029D2A689A -:105C5C00111D2960D2F8009013F8011BB9F1FF3F18 -:105C6C00DCBFC9F100094FF0010C2E291ED11A46D8 -:105C7C0012F8011B2A291CD1029D2A68111D2960CA -:105C8C009D1C126859782B4622EAE27821E04FF0ED -:105C9C000009A1F13002092AE7D809EB890201EBCE -:105CAC004201A1F1300913F8011BF2E74FF0FF3864 -:105CBC000FE04FF00008A1F13003092B08D808EBD6 -:105CCC00880301EB4301A1F1300812F8011BF2E744 -:105CDC00134630284FF0000241F0200008BF4A461E -:105CEC006C2808BF13F8011B9A46692901D0642956 -:105CFC000CD1029B1868011D19609045C8BF424623 -:105D0C00DDF8048001686FF009031EE075290AD0E4 -:105D1C00A1F16F00092858D8DFE800F005695F5F32 -:105D2C00835F5F5F5F05029D2868031D2B609045B4 -:105D3C004FF00803C8BF4246782908BF10237529C5 -:105D4C0008BF0A23DDF8048001684046654616F05A -:105D5C00A5FBAC460546A8EB0001A9EB0100BCF184 -:105D6C00000F0DD109E0022E05D3013E17B107F843 -:105D7C0001BB00E00027013801340128F3DA0138B7 -:105D8C000A465AB1022E06D3013E1FB12B7807F8F2 -:105D9C00013B00E00027013A0135F2E70C44BCF16D -:105DAC00000F3FF42BAF0128FFF628AF022E05D3CE -:105DBC00013E17B107F801BB00E0002701380134A0 -:105DCC00F1E700270134824618E7632905D1029ACE -:105DDC001068011D1160006804E0AAF10100022E98 -:105DEC003AD300788DF80C00012103ADB5E7029A87 -:105DFC00DDF804801023CDF800C01068011D11607F -:105E0C001099082200290168404616F047FB054608 -:105E1C004FF04000DDF800C005F8010DA8EB0501BE -:105E2C009BE7029ACDF800C01068011D1160109913 -:105E3C0005680F480029002D08BF0546284623F0A9 -:105E4C0025FB0146804538BF414618F1010208BFC9 -:105E5C000146DDF800C080E7002103AD82467CE7F7 -:105E6C000FB100203870204607B0BDE8F08F00BF9E -:105E7C00C0A202002DE9FC47044601900578944825 -:105E8C00465D9448E840ADF80260C00740F01E81C2 -:105E9C000D2D13D1904E0DF10201B068D0F82824CD -:105EAC0053209047BDF802104FF6FD70814214D874 -:105EBC00208990B14FF0000AA146AEE00C2D0ED017 -:105ECC00072D13D0052D0ED1A078012800F0FE80EF -:105EDC00207C304400F1240716E0B068CDE0606807 -:105EEC00C08AC0050AD44FF0000A09E0A07848B176 -:105EFC00A07D00EBC00006EB800705E04FF0010A27 -:105F0C00374605E006F11B07ADF802704FF0000AAA -:105F1C00384621F0A3F838B38146072D44D12078B8 -:105F2C0089F80000607889F80100A07889F80200EF -:105F3C000028E17889F80310D4F80510C9F804108A -:105F4C005AD0A07D002889F8080049D0A169002901 -:105F5C0046D000EBC00009F110068200304623F059 -:105F6C0011F9C9F80C6040E00C2D40F0AF80A1464F -:105F7C0059F8040F002800F0A98023F0D9FA8046C4 -:105F8C0055488068D0F8541348468847384621F065 -:105F9C0065F88146404623F077FDB9F1000F00F01B -:105FAC00958023F08DFC38E023F08AFC052D34D14C -:105FBC0009F11806D9F804102422304623F0E2F82F -:105FCC00D9F8141099F8102009F13C00C9F80460B4 -:105FDC0023F0D8F8D9F804002430C9F814001CE0D8 -:105FEC00002089F80800C9F80C00A069A8B123F0BA -:105FFC0013FE0020A0750FE01B2009F110061B22D8 -:10600C0089F808003046A16923F0BCF8C9F80C6087 -:10601C00A06923F001FE0020A0613048016819B18D -:10602C0048468847002846D10D2D2BD16068017851 -:10603C008A0720D42A4AC1F38301927C91421AD157 -:10604C0040783F2817D894F83000022813D199F8DB -:10605C00470009F146011DF07FFF01984FF6FF72D2 -:10606C00418E91421FD14068807902281BD348464B -:10607C0019F04CFE50B318488068D0F8541301A89E -:10608C00884723E00C2D0ED160781A280BD0D9F854 -:10609C00040040B1C08AC00705D099F8100009F17E -:1060AC000F011DF059FFBAF1000F04D10D484946FC -:1060BC00007818F0F3FF0C2D08D1019850F8041F4C -:1060CC0021B105498968D1F85413D9E7BDE8FC879B -:1060DC00E0BA020019C206000C010020582700206B -:1060EC00407B0020988800202DE9F04F8DB00646AB -:1060FC00806A447874B18D4909788C4280F01281A1 -:10610C008B49023022462AB130F8023B013A21F881 -:10611C00023BF8E78748C18A708988422FD18348AF -:10612C000078A04240F2FE80B589814A214628467B -:10613C0022F020F8284616F089FE06468248077899 -:10614C00BE4204D14FF6FE7016F080FE0646BE42EB -:10615C0080F0E880DFF8F48108EBC6094F4657F869 -:10616C00040F08B123F058FD002C00F0B180600042 -:10617C0023F054FD0028386040F0AC80D2E0B27CB3 -:10618C00002A00F0CF806A4F0025AC4205D037F8CA -:10619C0015208A4203D00135F7E7A04600E0A84657 -:1061AC00002113F057FE002800F0AD8081464079A5 -:1061BC00012840F0A88099F8060010F0180F00F0A4 -:1061CC00A280B9F80210204622F0C2F8A54202D3F0 -:1061DC00002800F098805848CDE90498B6F80C9047 -:1061EC004FF6FE7A00780890544800780A90002008 -:1061FC0006960B9052481130099052480430079083 -:10620C0000200C90DDE909564FF0000BF6B135F883 -:10621C00117C574518BF4F4502D1013E1C35F5E79F -:10622C002046394622F094F80028F6D12878013817 -:10623C000528F2D80C980BF1010BC007EDD00B9888 -:10624C005FFA8BF1C0B28142E7D356E0DDE90786F5 -:10625C002EB338F8047C574518BF4F4503D1013E87 -:10626C0008F12408F4E72046394622F071F800289A -:10627C00F5D198F8050001380528F0D898F80000F9 -:10628C0001380228EBD30C980BF1010BC007E6D0B8 -:10629C000B985FFA8BF1C0B28142E0D32DE05FEA3C -:1062AC000B6028D00B98000625D101205FFA8BF5E6 -:1062BC000B90012D4FF001000C90A3D023F046FB66 -:1062CC00C0B2B0FBF5F101FB15000B90012098E773 -:1062DC00002038601E4989F80140A9F8025009785D -:1062EC0008F83610F4B1E8B1114962000DB0BDE800 -:1062FC00F04F22F047BF4FF6FE770498069EDDF86C -:10630C00148047800A4FB37CF47CB269B1890125B3 -:10631C00581EB07470895FFA88F68DE8D00003952A -:10632C0010F058FB0DB0BDE8F08F00BFDBBC0200D5 -:10633C00F0850020407B0020E6BC0200D5BC0200AA -:10634C00DC5B0020B05400209ABC0200E027002047 -:10635C00CE2700202DE9F04F87B005462C200E46A5 -:10636C0023F05CFC002844D0778B044623F016F90C -:10637C000021E1840121874208BF02212170707B3A -:10638C00A0703169081A6060204618F087FB3178DC -:10639C00834F01F00301387B012908BF0520607091 -:1063AC00C0B222F03FFF4FF0FF316077A182217F16 -:1063BC00326908440A44317D3261081A3075E07044 -:1063CC00A069013017D0207C032816D8DFE800F034 -:1063DC0002170209062021466082284616F0A2FF09 -:1063EC0010B3042021466082284607F0A5FB054621 -:1063FC001BE01025CFE0A32517E0A12515E0002018 -:10640C00B3256082F87A80B997F8410001280CD145 -:10641C00A07D4FF6FF7619F039FE0025A082B04220 -:10642C0008BF6FF05E0500E000252078022807D138 -:10643C0004F1080622F0DEFB0146304623F099FBFE -:10644C00280640F0A580574F3878013801281AD813 -:10645C0094F8260010B994F82700A0B1A078E17840 -:10646C00227F08441044043023F0D8FB58B1A178A3 -:10647C00E2780646207F114408446168021D3046CC -:10648C0022F080FE00E0002620460EF083F905463F -:10649C003878012802D12DB9002575E0022873D176 -:1064AC00002D71D0002E73D00DF1080800274FF08D -:1064BC00010B4FF4D00908F1080A94F8260018B91A -:1064CC0094F8270000285FD0A178E278207F11444F -:1064DC0008443146021D606822F054FE94F82600F0 -:1064EC0020B184F82670C4F8129007E094F82700C5 -:1064FC0020B12D4884F82770C4F8120020460EF005 -:10650C0049F910B10021054639E04046142122F02A -:10651C00D5FC608A8DF819B0F0B9A08A40F203114D -:10652C00884216D0682817D16068C17B052929D10B -:10653C002A30FF21082222F081FA18B34FF0FF30E5 -:10654C006946CDE900001948006823F012FBFC20D5 -:10655C0000E0FF208DF81800504669460022002507 -:10656C0013F022F801469DF8000038B104201422E3 -:10657C0043461FF01FFF0321002500E003210329E0 -:10658C009BD101E00221FAE716B1304623F044FB1F -:10659C00204623F041FBE8B207B0BDE8F08F00BF06 -:1065AC00407B00201826002000000301DC8700201F -:1065BC0014F04AF88848DFF824B2DFF824A2DFF898 -:1065CC002482894D894E0027006817F07BFFDBF889 -:1065DC0000004FF0FF310CF007F823F0B2F99AF8F5 -:1065EC0002109AF80420D8F800409AF806308AF87D -:1065FC0002708AF804708AF80670002918BF44F0FB -:10660C000404002A18BF44F08004002B18BF44F087 -:10661C000204C8F8004023F070FAD8F80000010614 -:10662C0044BF20F08000C8F80000287818F008FA61 -:10663C00002848D0DAF80C10044651B19AF8010041 -:10664C00012804D0022804D1204688473BE020468C -:10665C008847204617F0E3FAA8B304460C20B1464D -:10666C002F4623F0DBFA80B1064623F06AF9054683 -:10667C002078B46098B1304623F0CEFA606821F0EF -:10668C00EBFB204623F0C8FA16E0606821F0E4FB2F -:10669C00204623F0C1FA3D464E46002713E0D9F8B8 -:1066AC000000314623F0D6F8D8F8000040F0100076 -:1066BC00C8F8000023F09FF928463C464E460027B8 -:1066CC0023F01BFA2546D8F80000C10631D53068F6 -:1066DC0023F0BAF8F0B922F085FFD8B9A94623F017 -:1066EC0030F90446306823F0A9F878B10546806883 -:1066FC004188406817F046FCA868406821F0ACFB64 -:10670C00A86823F089FA284623F086FA204623F05D -:10671C00F4F94D46306823F097F830B1D8F8000002 -:10672C0020F01000C8F8000003E023F064F9D8F85A -:10673C00000081070FD508F00BFD21F0D3F820B134 -:10674C0023F059F9D8F8000005E0D8F8000020F043 -:10675C000200C8F80000010725D5706823F06EF818 -:10676C0090B1DAF80810044641B19AF8000028B14B -:10677C00022826D0012804D1A0688847A0681AF006 -:10678C002FFD204623F048FA706823F05DF830B1F5 -:10679C00D8F8000020F00800C8F8000003E023F04F -:1067AC002AF9D8F8000041077FF511AF20F004005A -:1067BC00C8F80000306823F047F800287FF407AFD2 -:1067CC0002E0A0688847DCE7D8F8000040F0100031 -:1067DC00C8F800005846F7E6488800204C8800208E -:1067EC003425002050880020B98800202426002061 -:1067FC002DE9F04F93B004461EF0C0FA08B11120F9 -:10680C0006E1207F4FF6FE75B8B183480078810011 -:10681C0041EA401061882077FF2020F043F90021E5 -:10682C0080B1E08A05F1010B012640F00400E08202 -:10683C00207F40F00100207707E0002000264FF673 -:10684C00FE7B08E000264FF6FE7B74480078022899 -:10685C0038BF012188010490678838461DF084F9FF -:10686C0008B10020607694F81AA0BAF1000F04D198 -:10687C006B4890F800A084F81AA094F90000C5B2F7 -:10688C00B0F1FF3F07DDE07E40B966480178E17664 -:10689C000131017002E005F003052570207EDFF860 -:1068AC008491012805D199F80B0010B90DB900207D -:1068BC002076DFF8688198F80000012831D899F823 -:1068CC000E0080072DD5E6B1E08A410606D5BAF157 -:1068DC00010F03D120F00400E08222E0A188E07EC9 -:1068EC00627DADF822708DF82AA0ADF824108DF8D9 -:1068FC002B0006A803F0E2FE00283FF480AF2578B9 -:10690C000FE038461DF030F958B1002DDCD020696D -:10691C0000780A2805D8012101FA00F010F4836FE1 -:10692C00D2D14FF6FE7A012D07D1206900780228CA -:10693C0003D1E08A40F04000E082EEBBE08A10F028 -:10694C00400039D198F80000012835D899F80E008C -:10695C00800731D5049DA71D6188607E3A462B4681 -:10696C0013F0B8FA28B100206076E08A40F02000DD -:10697C00E082387870B1618804F108001CF066FB85 -:10698C0083466088834504BF00203870E08A40F05D -:10699C004000E0822078012804D0A18860882A4633 -:1069AC000FF07CFCA18860882A460DF0B7F818B16E -:1069BC00E08A40F02000E0820DF11701204605F03E -:1069CC007DFA06461FFA8BF0504508BFB4F802B0AA -:1069DC00EEB12078617D94F82C50B9F816209DF812 -:1069EC00173007948DF81800608DADF81A00E08A06 -:1069FC0006ACCDE90254CDE900101FFA8BF13046FC -:106A0C000BF006F9102803D1304623F005F91020BD -:106A1C0013B0BDE8F08F00BFB3270020182600206C -:106A2C00CFBC0200407B00202DE9F04F99B012AF93 -:106A3C008A4604461C219346384622F03FFA2046EB -:106A4C0039460CF0C5F99DF855009DF85C100843CB -:106A5C0007D09DF8480041060CD560891DF084F8DC -:106A6C0030B140F2351010F04EF919B0BDE8F08F8E -:106A7C009DF84800C0F3401900F00C0510F0200FF1 -:106A8C0018BF042D21D1E08D9DF8483010F0800105 -:106A9C000CD15A060AD59DF84920920706D143F02D -:106AAC00040202F00C020C2A40F0CA804FF00008DD -:106ABC00012213F003031ED0012B46D0022BD4D19C -:106ACC00A08912A91AF038FECFE7A68922F066FD3C -:106ADC00864202D1E08D010609D4A68922F05EFD22 -:106AEC00864200F08B80E08D010600F18780000665 -:106AFC0079D4A0897BE0544EF37A012B02D1A3798F -:106B0C00002B78D00223A7898DF84430ADF83C7067 -:106B1C0081BB042D75D1207C4E4D8DF85E0028680C -:106B2C000028A2D022F03AFD87429ED1E08D217937 -:106B3C0094F830202D684346CDE903028DE8020A13 -:106B4C000FA812A95246A8478FE7002918BF0121A8 -:106B5C0052EA010003D1A08912A914F00AFDA08900 -:106B6C000797ADF81800A0798DF81A0006A819F04F -:106B7C009DF97AE7ADF8300016989DF84A109DF80B -:106B8C004B208DF8203094F832300B9060898DF8C2 -:106B9C002310DDF84E108DF8222094F830208DF85B -:106BAC003830ADF81800B08CCDF826109DF85C107C -:106BBC008DF83720ADF82400207CADF82A10A17C8C -:106BCC008DF8320020798DF834109DF85F108DF817 -:106BDC0033009DF85D008DF836108DF8350006A851 -:106BEC0001F0E8FF41E7A089ADF86200608912A9C5 -:106BFC001EF0DEF910B14FF49A7034E74FF0010932 -:106C0C0041E71AB912A9384614F0B3FC10480078C1 -:106C1C00022809D10D480078012805D1204611F031 -:106C2C0033FB00283FF421AFA07CE17CB28C5346AF -:106C3C008DE8020A039012A80FA90EF0C3FF14E707 -:106C4C004FF00108002234E7407B0020D5270020BC -:106C5C00182600203C2400202DE9F04F97B0044664 -:106C6C0080690DF15B0200214FF0000890F800B034 -:106C7C009C200BF09BF97B480078012808D8002059 -:106C8C0004211CF0E5FE80469DF85B00404400E0CA -:106C9C000120C1B200258DF85B0059457DD9A0EBD0 -:106CAC000B060221F0B2022828BF0E461A207043B0 -:106CBC00C0B222F0B3FF0027002800F0BF80099477 -:106CCC000BA907965FFA86FACDF814805FFA88F65E -:106CDC000446D8464FF000090690CDF820B0043198 -:106CEC000A915FFA89F050455DD25FFA88F0B042A4 -:106CFC0056D21FF05BFD00284AD05B490546888CB4 -:106D0C0039312080A01C22F034FF4FF60270A4F819 -:106D1C00170028888DF82C706082ADF82E00A97AA7 -:106D2C0061760BA812F010F9014604F10A00012952 -:106D3C0003D10A9922F01DFF03E04FF0FF314160AF -:106D4C000160287948B1484991F83810013102287E -:106D5C00217612D80221012811E04348022190F833 -:106D6C0038006175298800290A4618BF012222754E -:106D7C0018BF411E2176002008E00121032821754F -:106D8C0002D16775012001E001206075A0751A34ED -:106D9C0008F1010809F10109A3E7002600274DE0DD -:106DAC000598CBFA50F830480FAD4FF0020BAE1CE3 -:106DBC0000F139075FFA89F050453AD25FFA88F151 -:106DCC0087202A460BF0F2F8BDF8460039462080A1 -:106DDC00A01C22F0CEFE04F10A00314622F0C9FEBE -:106DEC00BDF83C001F49204B012209F1010908F1B3 -:106DFC00010860820978022938BF022293F83830E2 -:106E0C006275A3F1010238BF4FF0FF3202294FF037 -:106E1C000001227638BF012184F817B04900A17512 -:106E2C00002818BF01209DF84E10207561761A3489 -:106E3C00C0E7069FDDE908B4079E0025607CF1B22F -:106E4C009DF85B300022CDE90275CDE900B1A11CA3 -:106E5C000AF01EFB17B1384622F0DEFE17B0BDE873 -:106E6C00F08F00BF18260020407B00202DE9F04752 -:106E7C008AB0DFF8C0810446D8F80000416E02A841 -:106E8C008847DFF8B4A1DAF80800016C096811B979 -:106E9C00D0F84C058047694801210170DAF80C00E4 -:106EAC00C068007830B9DAF808000021D0F858240E -:106EBC000120904722F0FFFC476805893878C0F321 -:106ECC00401128460FF040FADFF874910790D9F87A -:106EDC00101019B122F0EFFC0C308847D9F80800DB -:106EEC0008B18047089057480078F0B1D9F82010C5 -:106EFC00B9B1884755490028554B0A4608BF02329C -:106F0C0012781A708DF82420CA1C002818BF4A1C4D -:106F1C0010788DF825004C481978022908BF0230EA -:106F2C0000E0494801880131018016F05FF84A48B9 -:106F3C00484E0078F57350B122F0BDFC007D30B1A5 -:106F4C00284621F047FF1FF0EBF800286BD00025F6 -:106F5C003761758022F0ECFA07467580059524B1EF -:106F6C00012C31D13D483E49C1613C483949027B35 -:106F7C00437BC47D416045804D6002F0F00202739A -:106F8C0003F0F0020232427304F0F0020432C275D4 -:106F9C004A7B22F00F02531C4B73DAF808301B6C3F -:106FAC001C6864682478A40608D52E4C42F00202B2 -:106FBC004C601B685B689B784A73A3732A4E7060A5 -:106FCC00707B00F0F00070732848D8F8001008228D -:106FDC00274B0C6D00210068CDE9002102AA314637 -:106FEC00A0472449B0F1FF3F088007DD224819492A -:106FFC000160224801780131017010E0D9F800409D -:10700C0044B1DAF80800002100220023006C00686B -:10701C000C30A047012041F2883114F043F9384676 -:10702C0022F032FD02E0E1200BF050FB0AB0BDE88B -:10703C00F08700BF308800200C010020A32700201F -:10704C0024B802001C25002094860020A68700206E -:10705C00A6880020A885002090270020A08300206F -:10706C00006A18003086002074250020D8260020E5 -:10707C00E99200008A880020202500201925002094 -:10708C00B0B5784C20780E2850D8DFE800F0E34FEC -:10709C004F5E084F4F4F4F4F584F0808080073482A -:1070AC000078B0B1A078012830D1E0780130E070E0 -:1070BC00C0B2032851D870484FF6FF71808C8842BB -:1070CC004FD06C48012101704FF44170A4F80100BD -:1070DC0049E06C480021E170017000201CF0B0FE0A -:1070EC0018B120780D38012862D861480078022840 -:1070FC0003D10820012104F009FC052020F0F2FC4A -:10710C0042F21070BDE8B04020F092B803282AD1AA -:10711C0057480078022826D15648012101700320D7 -:10712C000021A070544880F826101CE015F0F6FEE3 -:10713C00554810210078BDE8B04016F083BF4A488E -:10714C00008800F007000128A9D148480078F8B160 -:10715C000020BDE8B0401AF013BB48480078012865 -:10716C0001D10020A07019F07FFE20F07BFB3E487F -:10717C008078000703D54248007801286AD1A078AE -:10718C00032867D108200121BDE8B04004F0BEBB44 -:10719C003D481021007816F055FF00201CF050FEE1 -:1071AC00334D297810B361B3207801292AD036E009 -:1071BC00062020F097FC2C4CA078000704D54FF447 -:1071CC000040012104F0A2FB29480078012809D8CD -:1071DC00208800F00700022804D0002000210022A3 -:1071EC0021F078FFBDE8B04015F098BE022903D11C -:1071FC000820012104F08AFB052020F073FC0120FB -:10720C00A7E720780A280AD11748008800F0070061 -:10721C00022813D01848082180F826100EE0032805 -:10722C000CD115F07BFE19480078022806D10120FC -:10723C001FF04CFC02200121FDF7A6FA062020F0DD -:10724C0051FC2878012805D80748008800F0070071 -:10725C00022800D1B0BD002000210022BDE8B040C2 -:10726C0021F038BFC426002026870020BB880020D0 -:10727C00182600209E880020407B00209388002048 -:10728C00BA270020AE220020998800200888002010 -:10729C002DE9F04F93B01C9C08901D4606928B462E -:1072AC0020461EF035FB074620461EF019FB002633 -:1072BC000790002F00F0E780002D18BF01254FF03C -:1072CC000008680100F14001BBF1000F08BF690123 -:1072DC0005914FF6FE754FF00A0108BF0821049185 -:1072EC0009A90431019100F108010C3003910290BD -:1072FC00207C804580F0C280380600F0BF8004EB13 -:10730C00C80B9BF81C00C00740F0B28060480078A6 -:10731C00012802D89BF81600D8B34FF0000A9BF84E -:10732C0016000F96CDE90D6678B15A49BBF81800D6 -:10733C0091F86810012923D1FF21ADF8340003988E -:10734C0041F208098BF81A103EE0BBF81800A8426D -:10735C0036D104208DF824009BF81D00ADF83000C8 -:10736C0009A818F0CBFD089C0198002100220023ED -:10737C00ADF83450A58016F055FFDDE9049024E0FB -:10738C00089C4FF00C09A080681CADF834000298E2 -:10739C001BE0BBF8180022F01AFB0028BDD00079C6 -:1073AC0040F002000328B8D19BF81C0040F080008C -:1073BC008BF81C00079800065DD04FF0010AAEE771 -:1073CC00ADF83400DDE90490089C8DF836000120FE -:1073DC008DF83900207D8DF838000DA808F0F0F8F4 -:1073EC009DF8480078BB109806994176417DA0F82D -:1073FC0016908BF81B109BF8161019B1254991F8B3 -:10740C00681001771C9A51890185518A4185117D3B -:10741C0080F82C10517980F83A109BF81A1080F8EB -:10742C003B102189A0F84010617D80F849106268FA -:10743C002169C263406C227D21F0A4FE0DA81BF0D3 -:10744C0057F89DF848009BF81C1041F001028BF88E -:10745C001C2020B141F009008BF81C0004E00798B7 -:10746C00013FA0EB0A0007901C9C4FF6FE7500260E -:10747C0008F101083CE700200790F9E720460021BD -:10748C0017F00EF90646304613B0BDE8F08F00BF7A -:10749C0018260020407B0020BFB581780446481E8A -:1074AC000B2812D8DFE800F006525C6A267885902B -:1074BC00A430B23900208DF80400E0780F28C0F019 -:1074CC00B28002208DF80400B3E0FF2940F0D38095 -:1074DC000025E01C04218DF803501FF019F86C49AD -:1074EC0008606C48058011F083FE0DF103036F20DA -:1074FC00FF21BDE000208DF80800E07802F0AAF82A -:10750C0002AB6F200521B3E020F02CFB8DF80E00B0 -:10751C000DF10E036F200A21AAE000208DF80F0058 -:10752C00E01C22F077FB0546601D04211EF0F0FFE5 -:10753C00014628460DF0CCF8504A3520282122F07F -:10754C005FF90DF10F036F200C2191E000208DF8F5 -:10755C000600E0780F2870D302208DF8060072E048 -:10756C00E07847490DF10703002818BF0120087087 -:10757C00002003218DF807006F2079E0E2780020CD -:10758C00211D8DF80A0004F10C00022A68D0012A92 -:10759C006AD117F0E3FE65E000208DF80C00E0786E -:1075AC00002818BF012020F055FE03AB6F200621E8 -:1075BC005EE0E078211D19F0DBFA8DF80D000DF17D -:1075CC000D036F20072153E00020E57804218DF88E -:1075DC000900201D1EF09CFF002D014618BF01253F -:1075EC00284621F0D9FB0DF109036F2008213FE05B -:1075FC0000208DF80B00E078002818BF012022F045 -:10760C00B7F80DF10B036F20092131E000208DF844 -:10761C000500E07804281BD21B4A01211070512070 -:10762C0022F0EEF817E0194A01211070522022F0D6 -:10763C00E7F801AB6F2001211AE0124A012110700A -:10764C00532022F0DDF80DF106036F2002210FE02C -:10765C0002208DF805000DF105036F200B2107E0CA -:10766C000BF0A6F88DF80A000DF10A036F20042127 -:10767C0001221AF0FDFF002004B0B0BDF082002002 -:10768C00AE270020C2270020CC270020C8270020CE -:10769C00082500200425002070B590B004468078A1 -:1076AC0021F0E2F8002800F0D38005466078A0F1C4 -:1076BC00E101E873102906D91A2818BFCD2808D083 -:1076CC001D2806D04BE0012202FA01F16C4A11424E -:1076DC00F2D06C4E3078012802D8688900056CD441 -:1076EC002846002108F0BEFBC0B3307801282BD807 -:1076FC006548807B800727D52968086A20B3C97F35 -:10770C0003AA09F0D5FC6078E92808D12868E27B47 -:10771C000123418900880093E92301F077F8286858 -:10772C00BDF8161001809DF81120BDF81810BDF899 -:10773C001600002A18BF012292010CF0EFF918B1C3 -:10774C00688940F0200068816A896178288920F076 -:10775C00A9FA28813078012831D971E060788DF848 -:10776C001000A07B03958DF81100287C00283ED0DA -:10777C0003A812F06FFE9DF81030E92B00D03BB936 -:10778C002868E27B012641890088009601F03EF8CA -:10779C003C480078012853D83B48807B80074FD564 -:1077AC00687B022802D1688940073BD46078E928BD -:1077BC0046D128461BF03CFA42E0052068736078FD -:1077CC00E9283DD03148006800B18047304E306820 -:1077DC00B0B32D48807B800732D52868418900885A -:1077EC001BF022FF60B361783268904728E003A851 -:1077FC0005F0EEFD2348007820B19DF810300128EB -:10780C0002D0BAE79DF81030002BB6D1286800885A -:10781C001CF0AAF90028AED11C4800680028AAD098 -:10782C008047A8E7286800881CF09EF9002811BF43 -:10783C00032028684FF6FF71018008BF052068738C -:10784C00687B022804BF06206873A07812F002FD42 -:10785C001FF028FB0B48007802280ED10D48007849 -:10786C0058B900200DF10B018DF80B0052201AF0C5 -:10787C00FFFB2020012104F049F810B070BD00BFBF -:10788C000101010018260020407B00207C230020F1 -:10789C0080230020D52700202DE9F04F8BB0846980 -:1078AC0006462588B4F8029028461CF05DF901289C -:1078BC000DD1307C717C00228023CDE90052CDE9C2 -:1078CC000220B21C48F2060017F0F0FCD4E0284667 -:1078DC001CF04AF920B96B480088854240F0C780FB -:1078EC0008962679651D5EB1700022F097F938B1C3 -:1078FC000246304629460A9221F036FB054602E044 -:10790C00002000260A9015F8017B57B1780022F070 -:10791C0085F930B1024638462946099221F024FBFC -:10792C0002E0002000270990B8191421DFF85CB19F -:10793C004FF6FF754FF0000801EB4000C0B2079006 -:10794C007800069070000590DBF800B0BBF1000FDA -:10795C0069D0DBF8040001780029F5D09BF80E20E3 -:10796C00D207F1D0DBF808401CB10120A0478246B9 -:10797C0001E0D0F808A0BAF1000FE5D0BAF8020087 -:10798C00814518BFA94526D1DAF808309AF80720A6 -:10799C000A9930461EF0D4F840B9DAF810309AF84B -:1079AC000C20099938461EF0CBF8A0B107981FF0AF -:1079BC0055FB38B30546D2202870089840882F73A1 -:1079CC002E7168804EB10A99059A05F11400A860D1 -:1079DC0021F0D8FB03E014BBB6E70020A86047B148 -:1079EC0005EB46000999069A1430286121F0CAFB70 -:1079FC0001E000202861DBF804002946406800788B -:107A0C0017F04CFB9AF80000214A5FFA88F108F154 -:107A1C000108002C4FF6FF7550543FF495AF5046BB -:107A2C0022F0FAF890E7089C0A9D5FEA086011D0F2 -:107A3C0014485FFA88F3227C617C0088CDE900034E -:107A4C0013480023CDE90202A21C48F2060017F0ED -:107A5C002DFC01E0207B90B115B1284622F0DCF81A -:107A6C00099848B10BB0BDE8F04F22F0D5B80648E4 -:107A7C00007802283FF41DAF0BB0BDE8F08F4FF03B -:107A8C000008D5E7708700201826002020880020E9 -:107A9C00148100202DE9F04788B004464FF0FF30E8 -:107AAC0002214FF6FE79CDE90200E089002808BFDB -:107ABC000821A66916F801A030B1714835880088F4 -:107ACC00854213D16F4E06E06E4831461FF0E7FD3C -:107ADC0090B36B4805884D4518BF002E29D1207BEB -:107AEC00002840F0C9806948406843E06648007847 -:107AFC0001281CD8284621F06AFFC0B10179002664 -:107B0C0001292DD140880DF110088DF81060ADF8C9 -:107B1C001C00404618F0F2F90646002818BF08F180 -:107B2C000406BAF1000F18BF4FF0FF3AD3E7002656 -:107B3C0016E05648406825E05348007801280DD8D7 -:107B4C00304621F098FF48B101790139012905D857 -:107B5C00BAF1000F18BF4FF0FF3ABBE74FF6FE75B6 -:107B6C00207B002840F08880484840684D4518BF6D -:107B7C00002E07D1E1894FF0810881B100F8018B0B -:107B8C0002AE11E05FFA8AF1022902D24FF000082E -:107B9C0007E0217B01296FD04FF0800801E009F14B -:107BAC00010500F8018B0EB1314600E002A921F06D -:107BBC00E0FF0570064605803348007838B10B2786 -:107BCC0001284BD15FFA8AF0012804D046E05FFA15 -:107BDC008AF0012824D10B27B8F1000F3ED1284898 -:107BEC00A9B20088814239D100250DF107008DF82A -:107BFC00075016F0E3FDA8B1E1890322002908BF64 -:107C0C000922A1698B5C9DF8072000EB43019A4285 -:107C1C000BD9D21A0D258DF8072005EB420708E089 -:107C2C000B271BE00C27B57018E000220D278DF8F0 -:107C3C000720F370331DB27012060DD011F8022B11 -:107C4C0003F8022B11F8012C03F8012C9DF80720E6 -:107C5C00013A8DF80720EFE721F0DEFFE2890B4DAA -:107C6C001020A11CFBB2A87004F1110042F40042D8 -:107C7C0017F0CCFB0020A87008B0BDE8F08700BF5F -:107C8C0070870020C8870020182600207C26002042 -:107C9C002DE9F04F8BB0002900F0EA80DDF858A0F8 -:107CAC000746007A0D46994690465FEA0A718DF8B0 -:107CBC00060012D4387A02240F2800F2DA8001214F -:107CCC00814011F00B0F19D003288DF8100024D12E -:107CDC0002A8394621F04DFF22E0022840F0C8806E -:107CEC003C8821F05BFC8442E4D0388801210322DB -:107CFC0013F0E8F90028DDD0CD24BAE048F20400F6 -:107D0C00014200F0B68038881BF02EFF002800F0EE -:107D1C00AB800F2038728DF810003888ADF8080051 -:107D2C005FEA8A7014D40020ADF81800534800683C -:107D3C0088B14168A942FAD1826862B129780220DF -:107D4C00904768B10188ADF8181021F065FF07E085 -:107D5C004FF6FF7002E0A86810B14088ADF818002B -:107D6C00CAF380129DF810301798DDE9141B8DF8BA -:107D7C00052010225C1E02EADA0218BF01240F2B28 -:107D8C00134618BF43EA84035FEACA6458BF13461C -:107D9C000AF0400243EA92125FEA4A73ADF82020DF -:107DAC0044BF4032ADF820208DF824000791ADF887 -:107DBC001A90ADF8168000229BF800007C7A7E8920 -:107DCC005FEA8A618DF804202D498DF8220028780D -:107DDC008DF81340ADF8146009788DF8120048BF87 -:107DEC0004218DF8231020F003FD28B1016919B18D -:107DFC0002A888477C7A7E893046214621F070FCA7 -:107E0C0028B120F0CFFE48450DD2022413E001A882 -:107E1C0020F0A4FF48450AD21A4801680029F4D082 -:107E2C0002A8884706E002A806F0D8FB02E002A8E8 -:107E3C0000F0C0FE04469DF8100002280CD1BDF8DD -:107E4C00086021F0ABFB864206D19BF80010287825 -:107E5C00424623461BF0F8FA5CB99BF8000000245C -:107E6C0001308BF8000004E0387A0F287FF42CAF37 -:107E7C00022420460BB0BDE8F08F00BF2088002004 -:107E8C00E71D0020F42600202DE9F04F8DB00746A9 -:107E9C00C08914468946073086B2304610F084FA01 -:107EAC000546FF280AD13046FAF73EFCB04205DA07 -:107EBC0070480778002F08BF0527A3E06D4E307877 -:107ECC00C0B91CB1022C15D1FF2D13D1387A002268 -:107EDC0003238DF81C007868009206906648C188D0 -:107EEC00C07805AA02F054FA9DF824003874BDF845 -:107EFC002000B881DFF880B1002104239BF80340F7 -:107F0C00BBF806A00CAA204621F004F99DF830001D -:107F1C007E2805D120467C211CF0A2FB9DF8300068 -:107F2C007C286BD1FD8905F107081AFA88F0B0F5A9 -:107F3C00005F65D8BB88C5F385120490F888494664 -:107F4C001FFA88F94FEA850C8DF82DC042EA83128E -:107F5C008DF82A00C0F301208DF82C209A088DF89A -:107F6C002B203A7A05EB0A07B9F10D0F40EA820093 -:107F7C008DF829004AD23F482A460197CDF80CC00B -:107F8C0000F11C06304621F0B5FEDDF82900711910 -:107F9C0000220027029170519DF82D000871681D78 -:107FAC0081B2304621F024FBDDF8291032464B46D5 -:107FBC00715196212F4D8DF82F10039921F0E1F975 -:107FCC0002998DF82E000B98C1F8030020465146FB -:107FDC001BF056FE04EB4401049A28700BEB810154 -:107FEC008A83BBF806104144ABF8061050B10198D7 -:107FFC0081B2204618F0A8FB2F7803E0012700E09F -:10800C000527377038460DB0BDE8F08F8946084615 -:10801C002946002221F0ECFA0DF12901052220F06D -:10802C0035F996214A462B468DF82F109DF82D10C8 -:10803C0021F0A7F951468DF82E0020461BF020FEAA -:10804C003070B9B220460DF1290207231BF018FE3F -:10805C00317851EA00073770D4D104EB440004990D -:10806C0000270BEB80008183BBF806004044ABF883 -:10807C000600C7E7A0230020A08000202DE9FC47C4 -:10808C00D0E900588246D8F80000D0F8409019F496 -:10809C00F06FC0F8449035D05FEA495117D5D5E957 -:1080AC001401411A50461DF0F1FED8F80000816908 -:1080BC00C90605D401688DF807109DF80710F6E77E -:1080CC00296801312960A97B09B90121A973696C5F -:1080DC0040684FF0004600F00F0404EA0100B0FACB -:1080EC0080F126FA01F1014005D02F6C1FB12A68EE -:1080FC00AB6C5046B847B4FA84F026FA00F0204036 -:10810C004042A863D5F85801D8F83C1009F0400754 -:10811C0040680068D0F804251140394347D0DAE9AB -:10812C000064504614F0C6FED7B1F07C90B90BE059 -:10813C00316F69B10068B16EB26F8854306FB16F36 -:10814C0001310138B167306720688169C906EFD504 -:10815C00F07C28B1D6E91401411A50461DF096FE68 -:10816C0096F86400E0B13079022819D017B1B179D2 -:10817C00012901D0316F99B90024B16E01283467FF -:10818C0086F86440B46607D1B36CB26FD6F8CC6095 -:10819C0050460094B04703E006F17C0021F050FDFE -:1081AC00504609F0E5FAD5F858014068006800F22D -:1081BC0004500068D8F83810084228D0D5F8F800D8 -:1081CC0028B3DAE90076504611F0C4FE50460CF0A4 -:1081DC001DFD7879012812D1D7F8F40078B997F8F9 -:1081EC00E80060B1002087F8E800BB6CD7F8EC1011 -:1081FC00D7F8FC20D7F8504100905046A047D7F84C -:10820C00F80020B93068816B41F4006181635FEA4A -:10821C00095023D5D8F8000081690907FCD4016BFB -:10822C0021F480710163297A91B10020287295F8AC -:10823C004400800606D52C6C24B1AB6C5046202132 -:10824C000022A047504601211EF0A1F9D8F80000E9 -:10825C00816B21F400618163687908B1BDE8FC870A -:10826C0005F58070BDE8FC4721F0EABC2DE9FE4F16 -:10827C001D4614460F46814621F05AF9DFF8C0A17D -:10828C0083464FF6FD78DAE90010494518BF0846D9 -:10829C0060B1B83021F098FC40B19AF82400CAF8CB -:1082AC00209040F004008AF824009FE01FF0AAFB05 -:1082BC00002868D006466348CDF808B0DDE90CB854 -:1082CC0021F0DCFB604908F0200EB1F854000130BD -:1082DC006FF31F30A1F85400B5605C480025C6E967 -:1082EC0003792268D4F80C8086F83250C6E9085518 -:1082FC000BEA000C207C72632279C6E906CEC6F824 -:10830C00408086F8440086F83820B1F8541086F87E -:10831C003350D4E905533186A168C6E91253F16391 -:10832C00A18BA6F8501028B9B8F1000F1CBF012082 -:10833C0086F844004AB9387B00F00F00022804D1BB -:10834C00012086F83800B8687063DDF808B00822A0 -:10835C00FF2353FA82F23C46D0B2851A18BF01258E -:10836C007F680FB1002DF4D1208800F47C40B0F56B -:10837C00305F0BD196F833000022082340F0100038 -:10838C0086F8330004E008F101082FE000220223F4 -:10839C004CEA03004EEA02012B4DC6E90601DAF85D -:1083AC002000484507D19AF82400C1071CBF00F0F3 -:1083BC00FE008AF824002648046854B1A96CEA6CC3 -:1083CC0005F1400005F1380300903046A04703301A -:1083DC0013D1FD209AF82410CAF820904FFA80F897 -:1083EC0041F004018AF8241020F0ACFE584621F02C -:1083FC004BFB0FFA88F0BDE8FE8FB6F83080B5F86D -:10840C005410414501D020F09DFEC0B2012801D886 -:10841C00FE20DFE7002089F8FC0096F8330040F0DE -:10842C00800086F83300A86BB04205D0F068007B62 -:10843C0000F00F000228D9D115F0D2F8D6E700BF12 -:10844C0070200020207F002030210020FFEFFF9FB4 -:10845C00842600202DE9FF41DFF8BC810020039029 -:10846C000290D8F83840B4B3D8F84C0010B9D8F80A -:10847C00480070B3D8F8480060B12069D8F84810AB -:10848C000969814206D194F83300C00602D5D8F8A8 -:10849C004C0090B1002702A887F0010103AA10F04C -:1084AC001FFE0546FFB9F5B10299002900F09D8029 -:1084BC005A4820F031F9002714E0D8F84800C06879 -:1084CC0040880028F9D0D8F84800C06840880128B6 -:1084DC00F3D00127DFE752480221283021F0B4FB0A -:1084EC000027002500242CB34E48466816B302988A -:1084FC00B0FA80F04009284001281BD1D8F8480078 -:10850C00D8F84C10039A87F00103CDE9003208F13A -:10851C00380208F14003B047012868D0022809D17D -:10852C00D8F84800012201230069D8F84810B1F9A5 -:10853C00301065E02046002C18BF0120384001287F -:10854C0051D1394821694068814203D034484FF4F5 -:10855C00806145E00298002818BF012028400128BE -:10856C0006D1D8F8480018B9D8F84C0000284DD0DE -:10857C0008201FF08FFD94F833004C25C00658BF1F -:10858C00482508F138001FF013F848F80500274B70 -:10859C00D4E90601C2439A60DA681043D860C84334 -:1085AC00186058680843214658600820E5681FF099 -:1085BC0049FA28461FF076F9288843F60601411A35 -:1085CC00022906D3B0F5C15F03D040F60201884200 -:1085DC0003D1012029461FF035FA11484FF0804194 -:1085EC00283021F031FBBDE8FF8100277BE70398A1 -:1085FC00002818BF0446B4F930102069012200236A -:10860C000092002206F03AFABDE8FF8108201CF027 -:10861C00C3F8BDE8FF8100BF30210020647F00203B -:10862C007020002084260020D01E0020081004405A -:10863C002DE9F0478AB0684D2868416E02A888473A -:10864C00664FF87918B1B87908B10020C0E020F075 -:10865C006FFFDFF88CA1804600249AF80000800799 -:10866C004FF0000005D47D2000210DF06DFE8DF83B -:10867C0018408DF80C4002945A4C0790616911B166 -:10868C009AF800008847E06808B180470890387A6B -:10869C0098B1606A88B180475349544B8A1D0028B1 -:1086AC0018BF0A1D12781A708DF82420CA1D0028D4 -:1086BC0018BF4A1D10788DF825004D4EDFF8349107 -:1086CC0000200590317BF27EB0607080D9F80800F4 -:1086DC0001F070018031317302F08001D0F8282450 -:1086EC00F4206331F17603218DF8181006F11C018A -:1086FC009047387980B99AF8000080060CD5286824 -:10870C00C06B8047317BB060029001F0F001023108 -:10871C00317301218DF80C1029683748344E384BD1 -:10872C000D6D4FF08071006801913449009102AADF -:10873C003146A84705463348B5F1FF3F058035DD86 -:10874C00B879002100240130B87178790130787142 -:10875C00FE60F8790130F871022012F0A3FD3C7133 -:10876C002948D9F808200188D2F8AC30D2F8D420A6 -:10877C001C7841EAC411D48C0180D2E9117193F8B0 -:10878C0000C0538D7486C481C0F80710C0F8037004 -:10879C008381508DC6E90A710CF001013086308B53 -:1087AC0020F0800040EAC110308309E0626812B109 -:1087BC00002000219047022041F2883112F072FD16 -:1087CC00404621F061F90020B5F1FF3FC8BF012000 -:1087DC000AB0BDE8F08700BF3088002014250020C7 -:1087EC00AD88002024B80200A6870020A5880020B0 -:1087FC00E87F00200C010020D82600202000430038 -:10880C00C90E010088880020E88600202DE9F84375 -:10881C00994617460C4680461AF006FF089D0646F8 -:10882C003DB936B9404621463A46BDE8F84318F002 -:10883C00F5BA6EB3002D3ED0624C207808B10128F9 -:10884C0003D16148806800B18047B9F1000F4BD06B -:10885C002078012800F2A5805C48807B800740D5F9 -:10886C005948C26812B13046494690475848317849 -:10887C000078884224BF01313170C9B20024814292 -:10888C0030D140461AF014F87470012701242EE000 -:10889C004C4800240127B9F1000F007829D0012D94 -:1088AC0027D1012825D84948807B800719D5404617 -:1088BC0019F0FEFF15E0B078B9F1000F0AD1C1191B -:1088CC004808022938BF01207178B07011B94149AC -:1088DC000978717040490978884202D90027002430 -:1088EC0005E00024012702E00027002437703548FA -:1088FC000078012D08BF02282BD084F001010F4213 -:10890C004DD1012812D83148807B80070ED54046C6 -:10891C0021F05DF850B11FB9417901F0FE014171B0 -:10892C00ECB3417941F00101417100E0BCB3254C3D -:10893C002078012821D82548807B80071DD540460A -:10894C001FF012FEC8B100204146BDE8F84321F0EB -:10895C005BB9A9F119010229CFD3B9F1000F08D0E5 -:10896C00B9F1E10F18BFB9F1F10FC6D0B9F1EB0FA6 -:10897C001AD1154900220A70BFE71448408B4045B4 -:10898C000DD10120414621F03FF92078022806D173 -:10899C004FF400500121BDE8F84302F0B7BFBDE829 -:1089AC00F88300240127A4E7074A0C4913780978B7 -:1089BC000133DDB28D4228BF0023137028BF012480 -:1089CC009BE700BF1826002074230020407B00206A -:1089DC00D1BC0200D0BC020093270020C627002087 -:1089EC002DE9FE4FD0F80080994614460E4682467B -:1089FC0013B10020C9F8000020F09AFD834698F8C6 -:108A0C00070038B198F8640048B121F04FF86FF0C6 -:108A1C000805B3E021F04AF86FF00E05AEE0002C2B -:108A2C004AD0504614F046FA00200121C8E91A64D5 -:108A3C00C8F87040C8F87800C8F8380088F80C00FE -:108A4C0088F80A00504688F864101BF0C1F95046AB -:108A5C0008F08EFE08F14C0402AD204629461EF0AB -:108A6C00C9FDD8F870100746D8F878008F4288BF37 -:108A7C000F46029930443A4621F03CF920463946DB -:108A8C001DF030F8D8F87000D8F87810C01B3944B5 -:108A9C00012FC8F87000C8F8781001DB0028DCD171 -:108AAC0098F8041002290CD10020C8F8680088F846 -:108ABC006400C8F870001BE020F0F8FF6FF00905A7 -:108ACC005CE0A8B90020D8F86860012988F8640037 -:108ADC00C8F868000CD10124584688F8104020F0E2 -:108AEC00D3FF98F80F0000284BD020F021FD8346CF -:108AFC0020F0DCFF98F8040008B100252FE0D8F82E -:108B0C00701008F17C0031B30C9920F033FF10B1D8 -:108B1C00012088F80C0020F00BFD0446504614F0A0 -:108B2C00C9F90020C8F86800C8F8700088F864001B -:108B3C00504608F01DFE98F80A6098F80C50204634 -:108B4C0020F0A2FF002D18BF6FF00C05002E18BFEF -:108B5C006FF00D0503E00021002520F00BFF20F045 -:108B6C00E7FCB9F1000F07D098F8041001291CBFDD -:108B7C00D8F87810C9F8001020F086FF2846BDE818 -:108B8C00FE8F002598F810000028AED020F0D0FC05 -:108B9C00A8F80F4020F078FFD8F84830D8F87820A3 -:108BAC00D8F8CC70504631460095B84788F80F502D -:108BBC00E8E77047F0B587B004466F48007878B1A5 -:108BCC00228B0020E57A01210390CDE901008DF87C -:108BDC000910500706D402F008030121002008E018 -:108BEC00BA20AAE0402012F008038DF8060008BF56 -:108BFC000321402606EA82064BB1C02093068DF86D -:108C0C0006004FF0010358BF02238DF807305309BB -:108C1C0003EA121202F00802324342EA0106217AF8 -:108C2C0003290AD8DFE801F00215112540F00407EA -:108C3C0020F0B4FC8DF8067008E00F291DD140F02F -:108C4C00080046F004068DF806002088ADF80400F4 -:108C5C0013E04A4991F86810002900F080802788B9 -:108C6C0040F0080006F58056FF258DF806003846C2 -:108C7C007EE001A920461CF0B3F90027208BC00729 -:108C8C000ED09DF8060010F00C0F58D09DF8060081 -:108C9C0000F00C01042904BF40F020008DF8060000 -:108CAC00A07C8DF8080001A806F08AFC9DF818003D -:108CBC00002842D10498C682B4F81B10A0F81910F1 -:108CCC00217A012903D12D4991F868100177A17EF1 -:108CDC00E37F0185228B80F82C301306428508D562 -:108CEC00D20506D5417D94F820001DF0CEFCA17E66 -:108CFC000498878780F83B5080F84A10A17A80F856 -:108D0C003A10D4F80E10C0F83E10A17F80F84B102A -:108D1C00617F80F84910406C6169628A20F032FAF8 -:108D2C00208B400604D51648016809B101A8884774 -:108D3C0001A819F0DDFB9DF8180007B0F0BD2088E4 -:108D4C0016F094FE48B19DF8060040F020008DF816 -:108D5C000600208BC00799D1A2E7BB20EDE740F0BD -:108D6C000C00278846F004068DF806004FF6FD70BF -:108D7C00ADF8040082E700BF2C240020407B0020CB -:108D8C00602700202DE9F04F89B0714F14460A4638 -:108D9C00064610460492B98C1AF046FC054610B1F2 -:108DAC006878002866D0B06A4FF00E09B34690F888 -:108DBC000180867890F805A05FEA886158BF4FF073 -:108DCC000609B0F80300039004981AF0ADFF18F0F0 -:108DDC00870F4CD108F01801182948D09BF81C10AB -:108DEC00894544D100EB0A020021BBF80C00B146C6 -:108DFC000091D1B292460E46049B494632460EF083 -:108E0C0051FD032836D008F07801B8BB18F0180FC4 -:108E1C0062D05FEAC86088464FF0030058BF01205B -:108E2C0040EA0108BBF80C00414611F013F888B178 -:108E3C00817911F0180F0DD0417901290AD14DB16A -:108E4C00B98C40881AF0F0FB20B1407810B16978E9 -:108E5C0088420FD320F087FA88B94FF0FF3020807A -:108E6C009BF8080000286BD0DBF8181069E0D320C1 -:108E7C000DF049FF002009B0BDE8F08F884620882E -:108E8C004FF6FF718842F5D10121BBF80C00324638 -:108E9C0000914946049B0EF005FD0398414685B2AE -:108EAC00284618F075FAF98A88420CD1284620F029 -:108EBC008EFD20B300790138012820D805A9284659 -:108ECC001CF086FD21E0DBF8280080F805A009B035 -:108EDC00BDE8F04F1EF096BC787B884608B120F0B8 -:108EEC0042FA03984FF6FE710022434680B203F01B -:108EFC00EBFD0028C3D14FF6FF702080C4E71FF0B4 -:108F0C0079FE014605A820F034FE9BF808000128E4 -:108F1C0004D1DBF8181007A820F02BFEDBF8281082 -:108F2C00BBF80C00497805AA07ABCDE9003200224A -:108F3C004B4641F030010291294608F0DDFE99E7DD -:108F4C000021BBF80C00324620F04CFE97E700BF26 -:108F5C00407B002070B58AB000F116050446284607 -:108F6C001AF0DEFF67480078013801282BD8002062 -:108F7C001021012214238DF8110005AE0DF1110002 -:108F8C00CDE90210CDE900620DF11201042000229E -:108F9C001BF04EF950B15C48006804A905AE32468E -:108FAC0010F002FBC728ADF812000CD806F108002F -:108FBC002946082220F0E6F8BDF8121004201422ED -:108FCC0033461DF0F7F92846FF2108221FF036FD25 -:108FDC0010B14E480121017028461BF0ADFC2079E0 -:108FEC000138052800F28B80DFE800F00389345C3F -:108FFC008903A01D0021102913D0425C0131002AE5 -:10900C00F9D061791EF0F0F84348424D90F84100D8 -:10901C0008B12878D8B160790DF066FF002028706F -:10902C0015E03D4890F8410088B905AC002062215C -:10903C000025224610F086FC204600211EF0D4F8B4 -:10904C0000200DF051FFCDE90755CDE905551FF076 -:10905C00BBF854E00DF1120128461DF0C2FA60B1C4 -:10906C000DF112024FF6FE7029461CF093FF2846B4 -:10907C0000210022002315F0D5F8BDF8126005A9D7 -:10908C0030461CF0ADFA059828B905A81AF0A0F9DD -:10909C0008B905980680A11D284610F05BFD13F059 -:1090AC00F5FC2CE01A4E307848B30DF1120105AAEC -:1090BC00284610F079FA01469DF81200F8B1002507 -:1090CC0001201422ADF8240006958DF82650059544 -:1090DC0005AB04201DF06EF906344FF4817010219D -:1090EC00224620F087FB28B94FF4817010212246CC -:1090FC0020F086FB01200321357018F065FB0AB0C7 -:10910C0070BD00BF18260020DC8700209C88002042 -:10911C00B0220020AF220020407B002070B58CB024 -:10912C00044600208DF82C00CDE906000890A078AC -:10913C00411E052925D82220DFE801F00321212C2E -:10914C0023036248007820BB20F000FB40B9604D3F -:10915C00A168082205F1180020F014F82088288056 -:10916C005C480078022814D1A0680DF1030101AA13 -:10917C0010F01AFA9DF8140038B1B1206CE01B20E5 -:10918C0008E0B3208DF82C0059E09DF8030000286E -:10919C00F3D023208DF81C000120A17B8DF81A0040 -:1091AC0020888DF81D102169ADF81800607B08919E -:1091BC00012804BF21208DF81A0006A806F000FA39 -:1091CC009DF82C00D8BB0998456C05202870A07818 -:1091DC006870A81C616819B110221FF0D3FF04E05D -:1091EC000021C160816041600160A078062801D037 -:1091FC00012803D1E078A874133500E01235A1687A -:10920C00284620F086F8A17805F1080006290AD82E -:10921C00012202FA01F111F0520F04D02E49096813 -:10922C0020F0A7FC01E0217B017020881AF09CFC47 -:10923C0010B109980421C1829DF82C0070B123480B -:10924C00007838B920F082FA20B921480021C0E911 -:10925C00061101809DF82C000CB070BDA07804287C -:10926C0014D1A06801AD0DF103012A4610F09CF950 -:10927C0006469DF8030018B94FF6FF708642DED003 -:10928C00206968B106A80EF045F90CE0206918B108 -:10929C0006A80EF03FF9D2E706A819F029F9CEE797 -:1092AC0006A819F025F9A16805F1080008221FF09D -:1092BC0069FF0120314614222B46ADF81400002022 -:1092CC00CDE9010004201DF075F8B8E71826002040 -:1092DC0050240020AC270020DC870020F8B5634E1A -:1092EC0001211D461446F068C068017060480021D9 -:1092FC00017060480170B068016C096811B9D0F850 -:10930C004C0580475C48076847B15C4822462B46B1 -:10931C004188B068006C00680C30B84715F0E24F1B -:10932C0014D057480178013901705448406818B17D -:10933C005448C1890131C181B068006C0068406833 -:10934C00007880066FD41CF0B1FF6FE020070CD4BE -:10935C004A48406818B14B48C1890131C18148481D -:10936C000178013901701D205EE0454C42F2054246 -:10937C002078013820704448418841F00400904224 -:10938C0018D13E48406818B13E48C2890132C281AA -:10939C003C4842890132428142F20542E12091422D -:1093AC0008BF1C2009F092F9207800284AD094F9C3 -:1093BC00000040E0314842F606024188914212D04A -:1093CC00B1F5105F49D140693349086019F010FCC0 -:1093DC002E48007850B32F480168013138BF016026 -:1093EC000021018122E0406818B12648C189013171 -:1093FC00C18126480078C8B125480421007802288C -:10940C00204808BF0621425A013242522148416885 -:10941C00013138BF41600189428901318BB2018130 -:10942C00934288BF4181E92009F050F91448017832 -:10943C0041B190F9000000280ADCB068D0F84C0566 -:10944C00804705E0B0680021D0F8582400209047F0 -:10945C00F0680021C0680170F8BD406800283FF436 -:10946C0082AF0848C1890131C1817CE70C01002021 -:10947C0017250020A327002024B80200A88500206F -:10948C001925002094860020A08300201C25002094 -:10949C00A68800204C87002044880020FEB5044696 -:1094AC002C2020F0BBFB002820614BD02C211FF07E -:1094BC0005FD256920884FF6FF760DF10301AE827C -:1094CC0011F0A8FB48B30DF1030069461EF0CCFF68 -:1094DC00BDF80020B24220D0584902EB4200AA82CB -:1094EC0006226A82002251F820302A744FF47A72D4 -:1094FC00AB6151F820300133B3FBF2F541F8203069 -:10950C0005FB12324AB901EB8000012101724C4873 -:10951C004FF40061007814F095FD21692088083122 -:10952C0011F078FB1FF076FD256970B14FF4D00077 -:10953C00C5F812000220287442480168A961013163 -:10954C00016021E010202075FEBDA88AB0421BD11D -:10955C003D4F05F1080039681EF0A1F858B93D6877 -:10956C001FF048FB014628461EF099F818B91FF069 -:10957C0051FD00285FD02169208802F0EDFB2569A0 -:10958C0000B1AE8200202874A88AB04231D12F4895 -:10959C00C17A11BB90F8410001281ED10DF10B02CC -:1095AC00002001213A2301271EF004FD08B1AE82F0 -:1095BC0013E09DF80B002F74A8754FF46810C5F8D4 -:1095CC001200234801684A1CA961026029B91C4891 -:1095DC004FF40071007814F035FD2569A88AB0426B -:1095EC0007D1A1202075284620F016FB0020206111 -:1095FC00FEBD287C012801D10E210CE0A06808B129 -:10960C000D2108E01FF006FD0D2118B9A078C00748 -:10961C0008BF052125690D482977A17801F00301C0 -:10962C00007B012908BF05206870C0B21FF0FAFD4D -:10963C0021694877FEBD2569A6E700BF1883002085 -:10964C0099880020FC260020DC870020407B00202D -:10965C0008250020F0B587B0624C054694F82B0025 -:10966C0028B9614F0421387819F0A4FD30B35F4854 -:10967C00407808BB5E480078022803D194F82B0090 -:10968C00800619D494F82E0005F0C60668B1A80718 -:10969C000BD594F82B00C00607D41EF00AFC04204E -:1096AC000121FBF771F886F0020694F82B1006F0F6 -:1096BC003F00084384F82B0007B0F0BD94F82B0052 -:1096CC0005F006062178304384F82B0051B1E0B345 -:1096DC004648002101703878042107B0BDE8F040FD -:1096EC0014F0B0BC012004F12E03002101222070E3 -:1096FC0055201FF0C9FB94F82E0080B33C4800782D -:10970C000138012809D83B4D0021082228681FF098 -:10971C0095F910B91FF07EFC20B334480721017075 -:10972C0094F82B000021304340F0100084F82B00FB -:10973C00002005F07BF80028BED000201DF0C6F9F3 -:10974C0007200021FBF720F8B6E728480721017015 -:10975C000720002107B0BDE8F040FBF715B894F8DE -:10976C002B00B4E728680DF11B0101AA0FF01CFFB8 -:10977C000546214800780028CFD09DF81400FD281C -:10978C00CBD00228C9D01D480088854217D201AE23 -:10979C00142130461FF092FBFF2029461422334639 -:1097AC008DF8140004201CF005FE154905EB45004E -:1097BC00002241F8202001EB80004272426000251B -:1097CC005520012104F82E5F224620F019F8FF20C5 -:1097DC0003211AF073F8054804210570387814F049 -:1097EC0031FC69E7AC2200209F880020088800200B -:1097FC0018260020DC870020AA270020C6BC020007 -:10980C00804300202DE9F04788B00646109C0020CC -:10981C00DD099A461746C3F3C308E060A060606098 -:10982C002060E9B1E9462146102248461FF0AAFC07 -:10983C002046314610221FF0A5FC484620F039F98D -:10984C000020102805D0315C225C5140215401309D -:10985C00F7E70AF1800A1FFA8AF04FEA102901E0B3 -:10986C004FEA1A296E46280418D030462146102299 -:10987C00013D1FF087FC2046394610221FF082FC68 -:10988C00304620F016F90020102805D0395C225CF7 -:10989C00514021540130F7E70744E4E7B8F1000FD9 -:1098AC0025D06846214610221FF06CFCB8F10E0F33 -:1098BC0040D30025204639464246E560A5606560E8 -:1098CC0025601FF05FFC80202146102204F8080060 -:1098DC0004AE30461FF056FC684620F0EAF8102D16 -:1098EC0048D0705D615D484060550135F7E76E46C4 -:1098FC002146102230461FF045FC002780201FF027 -:10990C00EEFF21461022C4F80170C4F80570C4F8AB -:10991C0009706773207004AD28461FF033FC304685 -:10992C0020F0C7F8102F42D0E85DE15D4840E055CB -:10993C000137F7E70026204639464246A681A66045 -:10994C00666026601FF01EFC80202146102204F861 -:10995C0008001FF0C4FF04AD28461FF013FC684636 -:10996C0020F0A7F8102E22D0A85DA15D4840A0558C -:10997C000136F7E76F462146102238461FF002FCED -:10998C0000253046214610221FF0A9FF2560656096 -:10999C00A560A5811FF0F6FB384620F08AF8102D43 -:1099AC0005D0705D615D484060550135F7E708B042 -:1099BC00BDE8F0872DE9F84FD0E90158D8F8001030 -:1099CC00CA690A62D20740F0A480D8E9040105F103 -:1099DC00C8094FF0000A4FF0000B0843D5F8CC1023 -:1099EC0049680968C1F8040505F130000090BBF125 -:1099FC00010F00F29780D5F8C000002800F092808B -:109A0C00D5F8E0C0D5F8CC70DC2224232024BCF19E -:109A1C00000F08BFD82208BF1C2358F8033008BF1A -:109A2C0018247F68D8F8146058F804403F68D7F8B9 -:109A3C000415314211D0A16849070ED10168D5F83F -:109A4C00D0408C4209D1416939B9D8F800104C6A20 -:109A5C0024F002044C62C7F804659968490702D0E7 -:109A6C000BF1010BC3E7AB58002BF9D045F802A062 -:109A7C00D5E934121A44BCFA8CF35B09C5F8D4202E -:109A8C005B01C5F8E0300368994228BF9A420CD2BA -:109A9C002846414602F0AAF895F8FE000028DFD0CF -:109AAC001FF0BCF818BF8862DAE7D9F800204B46E3 -:109ABC0080F810A02AB153690BB11A46FBE702F1EA -:109ACC0014031860C5F8D4A0BCF1000F4169C0F8AC -:109ADC0014A04FF0D800C5F8C01008BFDC202858DF -:109AEC00C5F8D00059B12846414602F07FF895F8E8 -:109AFC00FE0050B11FF092F818BF886205E0D8F84C -:109B0C000000416A21F003014162009820F09EF8A8 -:109B1C00A6E7D5F8C0203AB103211174BDE8F84F7F -:109B2C000EF068BBBDE8F88F486820F00200486072 -:109B3C00486A20F003004862D8E904021043D5F8C3 -:109B4C00CC2052681268D062C2F80405486920F033 -:109B5C0001004861012008624046BDE8F84F1DF045 -:109B6C007BB970472DE9F04F8BB0DFF8A08104462C -:109B7C00D8F80800D0F80001807AC00020F04EF828 -:109B8C000028099000F0B5804FF000091FF0D0FCC0 -:109B9C00009001AEFF270025D8F80800EAB2D0F8F3 -:109BAC000011CB7A9A422CD2D0F88824D02031469E -:109BBC008DF80650ADF80440904700BB9DF810009E -:109BCC0020B101281BD19DF80F1001E09DF80B105E -:109BDC00A9B100284FF0080008BF042000218142E1 -:109BEC0003D272180131D770F9E73044314680F84E -:109BFC000390D8F80800D0F89424D0209047013571 -:109C0C00CAE74FF6FF7701AE0DF1140A4FF0FF3B98 -:109C1C004FF00009C9885FFA89F291426BD9ADF80F -:109C2C000620D0F88824D1203146ADF80440904766 -:109C3C0030B1D8F8080009F10109D0F80011E9E7B2 -:109C4C00BDF80800B842F4D0ADF81400D8F80800FC -:109C5C005146D0F88824D4209047002841D10025C3 -:109C6C00D8F80820D2F80001C1888D4216D2D2F85B -:109C7C008824D1203146ADF80650ADF80440904709 -:109C8C0028B9BDF81400BDF80810814201D0013587 -:109C9C00E6E7D8F80800D0F80001C1888D42C8D199 -:109CAC00CDE907BB099AADF81A70ADF81870807A37 -:109CBC00C1000020814214D0131808309B88A342A5 -:109CCC00F8D11118002241F8082C09990844514682 -:109CDC0020F8047CD8F80800D0F89424D4209047BD -:109CEC00A7E700981FF0D0FE09981FF095FF1920E8 -:109CFC0008E01A2006E000981FF0C6FE09981FF035 -:109D0C008BFF00200BB0BDE8F08F00BF0C010020D2 -:109D1C00FEB50C4615F032F8A00600F18280200446 -:109D2C0000F1AF80E00607D52E208DF804006048C6 -:109D3C001FF075FE01A88847E00707D025208DF895 -:109D4C0004005B481FF06BFE01A88847A00707D5ED -:109D5C0026208DF8040056481FF061FE01A88847A4 -:109D6C00600707D527208DF8040051481FF057FED7 -:109D7C0001A88847200707D529208DF804004C48F6 -:109D8C001FF04DFE01A88847600607D52D20ADF8C1 -:109D9C00040047481FF043FE01A88847200607D55A -:109DAC003020ADF8040042481FF039FE01A8884766 -:109DBC00E00507D53520ADF804003D481FF02FFE17 -:109DCC0001A88847200505D53720ADF8040001A867 -:109DDC001FF092FFE00405D53820ADF8040001A86F -:109DEC001FF08AFF324CA068D0F898000068B0B120 -:109DFC001FF09EFBA168D1F898100A68029200220D -:109E0C000A601FF041FEA068D0F8981002984860D4 -:109E1C00A168D1F840138847A0681FF00DFC002002 -:109E2C00FEBD234E02ADB068C06B04301CF0DBFFEE -:109E3C00002802903FF473AF1FF07AFBB168C96B36 -:109E4C000A7B013A0A731FF01FFEB1680298D1F821 -:109E5C009810077848608DF80470417839B1162F46 -:109E6C000BD1B068D0F8541328468847DBE7B168AB -:109E7C00D1F840138847162FD5D0B0681FF0DCFB03 -:109E8C00D1E70B4DA868D0F89400007814F0D8FDF9 -:109E9C00002802903FF446AFA968D1F898104860AA -:109EAC00A968D1F840138847A8681FF0C5FBE9E7FB -:109EBC000C0100202DE9F04706680446307B02288F -:109ECC0012D196F823006568D6E904A79146884616 -:109EDC0080B1B16858481FF04DFD40B100206FF0C3 -:109EEC00010786F8250055E06FF0060752E00120C7 -:109EFC0086F82600002052492246F0614F48C6F8E9 -:109F0C00008086F821901EF06DFD297827201EF028 -:109F1C0035F850463946062203F0DAFF58B196F868 -:109F2C00260098B344481FF08BFE002086F82600CC -:109F3C0086F825002AE0434D434FD5F8800320F0E6 -:109F4C000200C5F8800396F82000042804D157F8C5 -:109F5C004C0C4169272088470220C5F8FC02386860 -:109F6C00416806208847C0B14020286080202860C6 -:109F7C0096F8260038B130481FF062FE002086F8B3 -:109F8C00260086F825000020C5F8FC024FF0FF30B3 -:109F9C00F061F7693846BDE8F0870220BA461BF03D -:109FAC00FFF90027B9F1020F0AD0B9F1040F4FF0F5 -:109FBC00000006D0B9F1060018BF0120800000E0B7 -:109FCC000020C5F84C010123D8F80C10D8E9010287 -:109FDC00C5F85011C5F8547186F82430DAF8003001 -:109FEC001D690B46A847256895F8200002281BD050 -:109FFC000428CFD1DAF80000816915488847B0F100 -:10A00C00FF3FDCBF4FF0FF30E8610020EF6985F8BF -:10A01C00240095F821100339022928BF85F8250062 -:10A02C00204619F0C1FCB5E708484FF0FF311FF08E -:10A03C00A1FCEF69AEE700BF307E0020B4840020A5 -:10A04C0089C5010004440240FC010010807E002000 -:10A05C00010000802DE9F0415A4E04465A4DB0687B -:10A06C00D0F8D41091F88380297819B1D0F84C0528 -:10A07C008047B068016C096811B9D0F84C0580476D -:10A08C00524F0120062C3C7028701ED8DFE804F0DB -:10A09C00040422252B5140004E4800214170B06829 -:10A0AC00026CD0F8D41010684B4AC08A40064FF0AE -:10A0BC004E0058BF2520085C107014BBC97801B342 -:10A0CC00022828BF022010701BE0B068D0F84C05A5 -:10A0DC0080472EE018F04CFD2BE03E4800214170EB -:10A0EC0018F070F825E03A4800213A4A0170B0683F -:10A0FC00006C006890F8691090F86A00517036494D -:10A10C00087009F0F5F8B068006C006888B940E098 -:10A11C00B068324A006C016891F86D1011803049BA -:10A12C00006890F86E00002808BF0120087019F034 -:10A13C00BBFF28480078A0B9B268106C016829B937 -:10A14C00D2F84C058047B068006C01684968254A14 -:10A15C00097801F02001117023490068406880786B -:10A16C0008703878062814D8012101FA00F010F094 -:10A17C004C0F0ED01FF0DCF90446387802280AD1B7 -:10A18C008320287020461FF07FFCBDE8F04119F0B9 -:10A19C0077BBBDE8F0811548017819B914490978E5 -:10A1AC000029EDD00221B8F1010F297004D10078FB -:10A1BC00832808BF15F0DAF92046BDE8F0411FF0FE -:10A1CC0063BC00BF0C010020B4880020B7880020BD -:10A1DC00A527002021260020B5880020AE8700206E -:10A1EC00B6880020C0880020C1880020AC880020E0 -:10A1FC00AF8800202DE9F0438BB0DFF884810C464A -:10A20C00054600208DF81300D8F80010002900F046 -:10A21C00AD80032D18BF022D03D191F8420090425E -:10A22C0008D1584900201BF03FFD3DB1012D03D151 -:10A23C0085240BE0002099E0032D0DD10121D8F8E5 -:10A24C000000032D80F8411003D114B18DF8134098 -:10A25C000DE000245DB91EE0022D07D1D8F80000F6 -:10A26C000CB1022100E0012180F841100024D8F843 -:10A27C00000090F84190B9F1010F0ED190F8431005 -:10A28C0019B1013980F8431005E090F8481011B16C -:10A29C00013980F848104FF0010990F8431049B18A -:10A2AC00426C00F12E03074602EB41018A1E00F1BD -:10A2BC0026010CE090F8481000295AD0C26C00F12D -:10A2CC000E0300F1200702EB41018A1E811D1E784E -:10A2DC00158802228DF828201CBB17B32A4A127845 -:10A2EC0080F8422003208DF81C007888ADF82000FF -:10A2FC0005AC20461FF03DFC7878BB7BCDE90054C3 -:10A30C00CDE902602120B9F1010F08BF222008A974 -:10A31C00BA1D11F093FE1D481A4900881BF0C4FCAD -:10A32C0023E041880DF1130448F220020123ADF81B -:10A33C0020104178CDE9004108A917F06DF9D8F843 -:10A34C00000090F8401002290DD1418C48F22002F7 -:10A35C000123ADF8201090F821102030CDE90041F8 -:10A36C0008A917F059F915F057FB01200BB0BDE8FF -:10A37C00F08300214FF6FF75FF260027A9E700BFE9 -:10A38C0038270020959902007C2600202E7E002084 -:10A39C002DE9F04F89B08246129803F0F00403F0D7 -:10A3AC000F0B002818BF01200392103C0025B4FAB3 -:10A3BC0084F464092040D4880290107A92886FF358 -:10A3CC009F2400F03F0024036FF39F2244EA0060B7 -:10A3DC00544C104400905248007804AEC2B2ABB258 -:10A3EC00934280F09580A27801355FFA8AF7974204 -:10A3FC0073D08AB20195172A6DD3A1F1070938469B -:10A40C0032461FFA89F421460FF052F99DF81B8051 -:10A41C0008F00300022826D1BBF1030F00F27D8067 -:10A42C000398007ADFE80BF0140205109DF8181061 -:10A43C0007E09DF81810884215D10398BDF8161046 -:10A44C00C088884204D00EE00498009981420AD159 -:10A45C000298002854D012980021836882893046D3 -:10A46C0015F0F2FF60B15FEA48701CD5BDF81E0014 -:10A47C0084421CD9A9EB000188B21728BDD228E070 -:10A48C0012988088E0B3129BDA8819689B681A448A -:10A49C000B7815789D42E6D1013802F1010201F1E9 -:10A4AC000101F5D12CE01F4C0120607104E038460D -:10A4BC00214616F049F91B4C00200025F8F734F919 -:10A4CC001748E17800780131B1FBF0F202FB101A69 -:10A4DC0003E013480078134C019D5FFA8AF1C2B275 -:10A4EC0051FA80F1013991FBF2F303FB121A5FFA76 -:10A4FC008AF1490051FA8AF104EB8101898B6DE7ED -:10A50C00039D96E81F001FC5002009B0BDE8F08F21 -:10A51C000399002088810A20F7E70420F5E700BFA3 -:10A52C0097880020A0800020B0B560480021604CC6 -:10A53C00016094F83A01032812D002282ED0012889 -:10A54C0040F0AF8094F8400111F070F9002084F8CD -:10A55C0040015948817B0220002908BF06209EE05B -:10A56C0054480168B1F5C060C4F82C01B8BFC1F5FE -:10A57C00C060D4F81011002900D5494288422ADD68 -:10A58C00D4F814011CF08EFDD4F818011CF09CFDBD -:10A59C00D4F828011CF0BCFD01201DE045480568DD -:10A5AC001EF010FEC4F814011EF014FEC4F81801BD -:10A5BC001EF018FEB5F5C061C4F82801C4F81011DE -:10A5CC0009D094F830215AB1D4F81401D4F82021D0 -:10A5DC00D4F82C110AE0002084F8300106205EE04B -:10A5EC00C4F82401D4E94502C4F82C110223C4F8A0 -:10A5FC001C01002948BF6FF0010301EB4101194414 -:10A60C00042391FBF3F111440029C4F820110FDD50 -:10A61C001F2931D3D4F824212AB33E28A8BF3E20C9 -:10A62C000130292928BF2921C4F81C010B3909E064 -:10A63C00D4F82421032A09D111F1140FD8BF6FF0DB -:10A64C0013011531C4F82011002113E00128D8BFE3 -:10A65C000120013811F10A0FD8BF6FF00901C4F8BD -:10A66C001C010B3103E0332928BF33211539C4F801 -:10A67C0020110321C4F824111CF014FD01201CF03E -:10A68C0035FDD4F820011CF01FFDD4F824011CF07A -:10A69C003FFDA5F2FF510420032938BF0620C4F862 -:10A6AC003C01BDE8B04005F0EBBC00BF3C500C4099 -:10A6BC00D81B002008400C4090BA02002DE9F84F3E -:10A6CC00584BDD1D584B93F800B000235B4505D269 -:10A6DC0015F8054C2CB108350133F7E74FF000099C -:10A6EC009DE04FF000095B4500F099804F4B0092C4 -:10A6FC00504A4FF0000805F8019C1E1D4C4BB2F857 -:10A70C0016A04FF6FE721F78012307B336F8044CDF -:10A71C008C4218BF544503D12436013F5B00F4E74B -:10A72C003478042C03D0012C06D0002CF4D109F180 -:10A73C00010905F8019CEFE702F1010CB0F80AE001 -:10A74C001FFA8CF4A64508BF48EA0308E4E73B4C23 -:10A75C00DFF8E0E0384B2678BEF824700A33B6B147 -:10A76C0033F80A4C8C4218BF944202D11C33013E80 -:10A77C00F5E71C88BC42F9D1DC79002CF6D01C7AA8 -:10A78C00002CF3D009F1010905F8019CEEE72C49E6 -:10A79C005FFA89F309788B4284BF05F8011C89465E -:10A7AC00009A5FEA096102D0817C012901D1002164 -:10A7BC0002E09EF80210013105F8031C9EF801100E -:10A7CC009EF80730B8F1000F05F8022C05F8041CB0 -:10A7DC008189C07C05F8053C25F8071C287011D030 -:10A7EC00184D194BBBF1000F0CD01E78284619469A -:10A7FC002EB14B1C051DABF1010B9642F2D1C0F8EA -:10A80C0000800A70114C4021207818F0D3FC20B93C -:10A81C002078402164221FF064F94FF0010948466A -:10A82C00BDE8F88F42760020D2BC0200B054002064 -:10A83C00E6BC0200407B0020DC5B0020D5BC0200A3 -:10A84C00D8BC0200C87A00204084002098880020E0 -:10A85C002DE9FE4F074600789B468A46029200F08F -:10A86C000C000C2808D1B888FE211AF0B3F8FE2889 -:10A87C00019008BF012019E059480568B878FF28F5 -:10A88C0008D01EF00FFD40B1064600781DF0B0FF59 -:10A89C00054603E02DB16E6800E00026FE20019015 -:10A8AC000EE0FE2000250026019009E01EF0FAFCC7 -:10A8BC00002800F09280064600781DF099FF0546AE -:10A8CC00002E00F08A80AA684AB1317802209047A5 -:10A8DC004FF6FE7440B104881FF09EF904E0B06896 -:10A8EC004FF6FE7400B1448839893078A14211D0FA -:10A8FC0010B909B900200DE028B14FF6FE720132F3 -:10A90C0092B2914206D0A1F580714FF6013289B214 -:10A91C00914244D897F80290B870387DD7F81080DF -:10A92C003030C0B21CF09AFBB8B304461A20514622 -:10A93C0020707868C4F80200A01D1DF06FFCBBF8F5 -:10A94C000100A4F817000C983A7D397B84F820009C -:10A95C000E986175A284E0610D986076F878E073CA -:10A96C00307820759BF80000A075788BA0857889CD -:10A97C006082029820820F9884F82E0032B104F184 -:10A98C0030004146A0621EF0FDFB01E00020A062F9 -:10A99C0070682146007814F081FB87F802903878B3 -:10A9AC0000F00C000C280DD0B8780026FF287FF49E -:10A9BC0087AF28680025002600283FF481AF466841 -:10A9CC0005467DE70199B888C9B21AF003F8FE284C -:10A9DC000146019001D0019868E7BDE8FE8F00BFE9 -:10A9EC00208800202DE9FF47D0E901590E46044686 -:10A9FC001EF09EFD95F8FD1021B97169102901D842 -:10AA0C00032906D81FF040F80024204604B0BDE806 -:10AA1C00F087012785F8FD701FF036F800204E4AAC -:10AA2C0085F8FC00C5E93000C5F8C80085F8FE00C3 -:10AA3C003069C5F8E4007069C5F8E800307B85F82A -:10AA4C00F9000028317885F8F8107168C5F8EC1019 -:10AA5C00B9F80E10A5F8F610317E52F8211085F8D1 -:10AA6C00FA1008BF1027C5F8F07099F80C000BF01D -:10AA7C0059F9204616F0C8F899F83B00374985F883 -:10AA8C00FB008A46D4E901873A6B97F83A000DF03F -:10AA9C0043FC7A6B98F8FB0051460DF03DFC98F89E -:10AAAC00F91097F83800012915D1FA6A51460DF0C2 -:10AABC0033FCBA6A97F8390046F202010DF02CFC0F -:10AACC0098F8FB0026491DF03DFA98F8FB0021464A -:10AADC001EF054F80AE0BA6A46F202010DF01CFCB2 -:10AAEC00FA6A97F8390051460DF016FCE8464046D4 -:10AAFC001EF0B8FA99F805001A4A4346CDE9004011 -:10AB0C00284699F8041018F065FA40461EF09AFB96 -:10AB1C00D9F80800144942460094029005F130001F -:10AB2C0019F088FE12F0F2FD104AC5F8CC0005F1C0 -:10AB3C001C00042123461CF0FDFA95F8F80008B11E -:10AB4C00B06805E005F16C0000211CF0BBFF084863 -:10AB5C00C5F8BC0059E700BF30BA02000260002003 -:10AB6C00CD090100C199000047650200259802003B -:10AB7C004B9A0200FEB504465A480078A04213D9FD -:10AB8C0008780D46012801D1686868B168780128F9 -:10AB9C0001D1A86840B1544F57F834601EF0C8FC7E -:10ABAC00F17921B11EF070FF00242046FEBD07EBA9 -:10ABBC00C40401216768F1711EF066FF002005F1E5 -:10ABCC00040C7074F081B06030602988B180A98B5E -:10ABDC00C6E93D00C6E90E0086F86400B186297D01 -:10ABEC002B69B1719CE80610C6F85021BCF1000F1E -:10ABFC00C6E910C34FF0FF32C6F8CC10A969C6E9FC -:10AC0C003B203163A97F86F83610296AC6E91A0001 -:10AC1C00C6E91C00B16486F8E800C6F8580102D1F8 -:10AC2C003249C6E9101097F840000BF07BF8D7E9D1 -:10AC3C00031206F14C001EF0EDFAD7E9051206F1ED -:10AC4C00D0001EF0E7FA2A4938680968C9688847B5 -:10AC5C007A6C97F8240046F202010DF05DFB254D4D -:10AC6C00BA6C97F8200029460DF056FBF8690128BC -:10AC7C000CD1FA6C97F8280029460DF04DFB3A6D73 -:10AC8C0097F82C0046F202010DF046FB12F03EFD47 -:10AC9C00C6F85801204605F08FFD174A06F5AE7030 -:10ACAC00042123461CF046FA6D4628461EF0DAF9BC -:10ACBC00387A7968114A2B460094019006F11400F9 -:10ACCC0018F088F906F17C0000211CF0FBFE06F55B -:10ACDC00807000211CF0F6FE3868D7E90C12106069 -:10ACEC00486062E7CABC02003CBC0200573E01004F -:10ACFC00D001001002600020B58C02008980000099 -:10AD0C002DE9F84F0CF09EFC5E480024002690F8CC -:10AD1C0000A0544510D2E0B21BF048FD50B10179AF -:10AD2C0041F00401042905D1807A1CF0ABFF002806 -:10AD3C0018BF01360134ECE700241BF00FFB05466D -:10AD4C000027E0B285420AD919F0E4FF28B1807CD3 -:10AD5C001CF098FF002818BF01370134F1E707EB0E -:10AD6C0006085FEA086032D04FF47F7000EA880969 -:10AD7C0048461EF053FF50B34946FF2204461EF0CE -:10AD8C0097F800275FFA86F94FF0000B574529D248 -:10AD9C005FFA8BF0484525D2F8B21BF007FDA0B145 -:10ADAC000646007940F0040004280ED1B07A1CF05D -:10ADBC0069FF50B10146727A30885FFA88F30093CC -:10ADCC00234614F04FFF0BF1010B0137DEE7002493 -:10ADDC004FF000082C48007BE0B11EF023FAC0F1C4 -:10ADEC00540018E000275FFA88F9F8B28542F1D9CF -:10ADFC0019F090FF60B10646807C1CF043FF38B11F -:10AE0C000146727C30882346CDF8009014F02AFF5E -:10AE1C000137EAE76220C1B20322A2462546B1FB04 -:10AE2C00F2F9B9F11F0F28BF4FF01F09C0B25FFA3A -:10AE3C0088F14446002818BF0120420102F1400766 -:10AE4C0049452A4684BF47014C46E0B2394612F0C8 -:10AE5C0004FA0022064617F0400008BF621E40EAC2 -:10AE6C000601A8EB02080020D2B2002905EB8205EE -:10AE7C00DCD0BAF1000F02D050461EF0CDFE3046A9 -:10AE8C00BDE8F88FE6BC0200407B00202DE9F84FAE -:10AE9C00814608688B469046D9E900454768068983 -:10AEAC005548E1681EF066FD18B16FF00100BDE871 -:10AEBC00F88F524852494FF0000A4A46C4F814B071 -:10AECC0084F80980C4F804A084F802A01DF08AFD5F -:10AEDC00297827201DF052F838463146062202F018 -:10AEEC00F7FF40B144481EF0ABFE4FF0FF3084F842 -:10AEFC0001A0BDE8F88F434F57F84C0C416927204F -:10AF0C008847414E0220C6F8FC023868416806208A -:10AF1C00884760B1402030608020306036481EF099 -:10AF2C008FFE002060704FF0FF30BDE8F88F0220DC -:10AF3C001AF036FA3A68DBF810009BF82010D26948 -:10AF4C0090473A689BF820009BF821101368A8F1F1 -:10AF5C000102B2FA82F252099847DBE90610C6F8F0 -:10AF6C0050010020C6F85401C6F8581159B13A687E -:10AF7C00DBF80400002315690022A84738688169B2 -:10AF8C00224801308847207A042804D057F84C0C0A -:10AF9C000169272088473B68DBF81C10DBE90202BB -:10AFAC001C690B46A047D9F8004001206070207A3C -:10AFBC00022815D004281BD13868144D8169284605 -:10AFCC008847B0F1FF3FDCBF4FF0FF3060600020DE -:10AFDC006070A81CC6F88403484610F017FF04E004 -:10AFEC000B484FF0FF311EF0C5FC6068BDE8F88FD0 -:10AFFC000020BDE8F88F00BF307E0020B484002014 -:10B00C00CDD20100FC01001004440240010000807C -:10B01C00807E0020F0B587B05C4E0446306848B3A3 -:10B02C0090F8401001293FD1022180F840102030C7 -:10B03C00214612F056FE05463068C169436B90F804 -:10B04C003220007E16F058FAB5FA85F137684D09B2 -:10B05C00002887F8430043D040001EF0DFFD37681E -:10B06C007864C8B397F843104A0049491EF08AF82F -:10B07C00376835E050201EF0D1FD306050B35021C0 -:10B08C0005461DF01BFF2846214612F02AFE08B388 -:10B09C003068012180F840103E483F49008807B0D5 -:10B0AC00BDE8F0401AF000BE02200DF10F0148F28D -:10B0BC00200201238DF8180088208DF80F0060887D -:10B0CC00ADF810006078CDE9001004A9204616F008 -:10B0DC00A3FA49E088201CE0882001258DF80F0098 -:10B0EC007B69BA7CF96B97F8380016F005FA316871 -:10B0FC0081F8480058B140001EF090FD3168C864DA -:10B10C0030B191F848104A0021491EF03BF86DB35C -:10B11C0086208DF80F0002200DF10F0548F2200259 -:10B12C0001238DF818006088ADF810006078CDE927 -:10B13C00005004A9204616F06FFA306890B190F8D0 -:10B14C00401002290ED1418848F220020123ADF8AB -:10B15C00101002218DF818104178CDE9005104A986 -:10B16C0016F05AFA14F058FC07B0F0BD306890F89D -:10B17C00431019B990F848000028C9D000200021CC -:10B18C00002207B0BDE8F040FFF734B838270020A4 -:10B19C00148100202E7E00209599020070B5604D20 -:10B1AC000446A8684169497F002973D0D0F8D4209F -:10B1BC00B4F84210D28C91426CD1D0F86C1304F1DB -:10B1CC0028008847002865D0A868002241694A7782 -:10B1DC00D0F8D41091F8291021B1E868816A0220C6 -:10B1EC008847A868006F90F82B0018B1E868816A4E -:10B1FC0001208847207CC00608D5E868816A1020A9 -:10B20C008847A868D0F8281380208847E868C16B65 -:10B21C0020208847A868D0F8FC14C06810308847F4 -:10B22C006268A86813785278416902F00F064E766E -:10B23C00C2F300114269917603F00F0142699177D4 -:10B24C001909D0F8D42082F82C10D0F8D410426907 -:10B25C0091F84F30927F0F2B05D09A4203D266683B -:10B26C00F67806B91A464A730022C16881F8302074 -:10B27C00D0F8D410497B0F290DD14169C97E022920 -:10B28C0008D1D0F864018047A868D0F86C01BDE8FB -:10B29C007040004770BDD0F80C2520469047A96837 -:10B2AC004869C07E022814D1C868D1F8FC148847BC -:10B2BC00AA684FF47076D2F8D430D2E90301D2F8F0 -:10B2CC00F0245B7B31F8131006FA03F3591A9047FC -:10B2DC00A968D1F8D400D1F8B431228990F82C1097 -:10B2EC0002209847A968D1F8D400427B90F82C0032 -:10B2FC0090420FD04869D1F8FC148847A86841697E -:10B30C00D0F87C018860A868D0F8F02440694169C5 -:10B31C009047A968D1F828131020BDE87040084761 -:10B32C000C0100202DE9F84F0446B0F82490C17BA5 -:10B33C00008A1EF0D5F948B9A07B032806D009F184 -:10B34C00140A1FFA8AF0F128C0F0A28009F11E0A33 -:10B35C001FFA8AF0FB280BD309F110001EF05EFCDB -:10B36C0050B3834610304FF01E0ACBF8040001E0B6 -:10B37C004FF0000B4FF0820801251FFA8AF01EF0E7 -:10B38C004DFCA0B10746A0783870E0787870207931 -:10B39C00B8706079F8708DB1A07BA11D3871A07B5D -:10B3AC00032813D1781D08221DF0ECFE12E0BBF12E -:10B3BC00000F01D05F4666E0BDE8F88FA079FE1D56 -:10B3CC003871E0797871E07BB8710BE008787871AE -:10B3DC004878B871E07B07F110067873207CB8735D -:10B3EC00607CF873207D3070607D7070A07DB070D3 -:10B3FC00607EF070301DE1691EF079FB0020307228 -:10B40C002DB14FEA192006F10B05B07201E006F1DF -:10B41C000A05BBF1000F86F809901ED01F48204E7C -:10B42C004FF47A720168CBF800100F21C0F800B00D -:10B43C0030788BF80C1008211EF056FB18B13078C0 -:10B44C00082112F0FFFDE069A16A4A46CBF808001A -:10B45C00DBF804001DF096FE05E0A16A28464A467A -:10B46C001DF090FE4D4494F82C005FFA8AF2414690 -:10B47C003B46287094F82D00687094F82E00A87044 -:10B48C00442017F0F5F83846BDE8F84F1EF0C4BB61 -:10B49C0000254FF081084FF0000B6EE75C26002072 -:10B4AC0096880020F8B50446007D50B15A4994F9AD -:10B4BC001800C968D1F880108847013004BFE82013 -:10B4CC00F8BD554EE27BB568D5F80011E86B0978EC -:10B4DC000AB1807A00E0C07A81429CBFF120F8BDAD -:10B4EC00636A94F8392094F83810A08DD5F88C52F2 -:10B4FC00278C0097A84700285ED00546002028809E -:10B50C006868A16AA28D1EF0F5FB04F1300005F10C -:10B51C0084010CC80CC1028880788870B0680A80DD -:10B52C002146D0F8442505F1900090476089B36816 -:10B53C00A5F89A00207B85F89C00607B85F89D001F -:10B54C00A27DD4F80E00D4F81210D3F848359847E1 -:10B55C00A5F89E00E07D85F8A000207E85F8A1006E -:10B56C0094F83C0085F86C00228CA5F8A8202AB32E -:10B57C00E169D5F8A4001EF0BDFB1DF0EBFDB5F89C -:10B58C00A800E8B1D5F8A400D0B16868411E696084 -:10B59C00F82100F8011C6868411E6960002100F860 -:10B5AC00011CB5F8A8006968091A6960A9652989A0 -:10B5BC0008440230288103E01A20F8BD1DF0CAFDB2 -:10B5CC00B5F89E10C8051DD594F83B20E8202AB18B -:10B5DC0011F0040208BF11F0010100D0F8BDB168F0 -:10B5EC00486ED1F8FC14884794F83B004FF47A71FC -:10B5FC00B268484309490978B0FBF1F1506ED2F8B2 -:10B60C00F4249047B0682946D0F89400007813F0E1 -:10B61C0045FD0020F8BD00BF0C010020B0880020C3 -:10B62C00F8B5554F554E564D38883168EC8808445E -:10B63C00224600F10801A868806D1EF05BFBA9682A -:10B64C003888504B8A6D2044388022448A65326891 -:10B65C0081B20832565C811C398089B2515C1970F8 -:10B66C00C11C0730398089B2515838806846009126 -:10B67C0004211AF04DFF00901CF016FEA968C86357 -:10B68C0000981CF0AFFAA968A1F840003E48007879 -:10B69C0018B11EF095FAA968C863EA2019F002FAED -:10B6AC003A48426812B1A8680121904738480221F3 -:10B6BC00384C0170E0684069007830B1A87B800993 -:10B6CC0017F0A6FC08B10120A870A878A96800287A -:10B6DC000A7C70B218BF42F004020A7400210027E1 -:10B6EC001EF0E0FA0146A86880F8461000F17401DB -:10B6FC00B0F85C2080F8486080F84770816501895B -:10B70C00511A426811444160417B890709D5A168EF -:10B71C00D1F808138847A868416E11B1B0F86810C9 -:10B72C00F1B190F8601049B1A168D1F80C138847B9 -:10B73C00A868C16C11B1B0F8501089B1A168D1F8EA -:10B74C00B820137823B1926C12B19047A868A16805 -:10B75C00D1F8581288470020A8601CF007FEF8BDED -:10B76C00A068D0F8541205F1080088470020A860A2 -:10B77C0010F044FDF8BD00BFA6860020C087002055 -:10B78C0024250020B18800208427002024B8020042 -:10B79C00AC8800200C0100202DE9F84FD0E90054B2 -:10B7AC00994616468A46834613B10020C9F8000014 -:10B7BC0076B11DF0BDFE0746E87968B195F8E80052 -:10B7CC0088B138461EF060F96FF00800BDE8F88FBC -:10B7DC006FF00900BDE8F88F38461EF055F96FF090 -:10B7EC000E00BDE8F88F0020012105F58078C5E931 -:10B7FC003BA6C5F8F460C5F8FC0085F8E810E863D2 -:10B80C006873E872404600211EF0B4F820461DF023 -:10B81C007FFF38461EF038F91DF0D9F808B9687961 -:10B82C00C0B395F84400C00606D52C6C24B1AB6CA3 -:10B83C00584610210022A0471DF07AFE04465846B7 -:10B84C0009F0E4F920461EF01FF9687960B90A99ED -:10B85C0040461EF08FF808B10120687358460EF070 -:10B86C0079FB002085F8E800B9F1000F1CBFD5F872 -:10B87C00FC00C9F80000E87A28B10020E8726FF0EB -:10B88C000D00BDE8F88F687B002818BF6FF00C0026 -:10B89C00BDE8F88FDBE9005495F84400C00614D5D8 -:10B8AC002F6CAB6C584610210022B8470DE0D5F830 -:10B8BC00FC0031460AEB0002204618F0D5FFD5F803 -:10B8CC00FC10361A0144C5F8FC10002EEFD12046AE -:10B8DC001DF0D8FC0028FAD020461DF00DFF95F87D -:10B8EC004400800605D52C6CAB6C584620210022F8 -:10B8FC00A0470020B9F1000F85F8E800C8D0D5F8B2 -:10B90C00FC00C9F800000020BDE8F88F7CB5584D4C -:10B91C00584E4CF6C0722B78347883F0010384F0C7 -:10B92C000204234308BF1040534C00295249898C10 -:10B93C000CBF21EA00000843A08401B2B1F1FF3F23 -:10B94C0008DC01200DF103018DF80300522016F0E4 -:10B95C008FFBA08C810400F1828081B20A042AD46E -:10B96C0001047CD04FF0FF3101913178022976D15E -:10B97C002978002973D121682346013101A908BF18 -:10B98C000B46C207224608BF0B461D6852F8046FCF -:10B99C00B54298BF1A46050758BF1A46C30606D5C6 -:10B9AC002546136855F8086FB34288BF2A468306AC -:10B9BC001ED4134623E0480451D504F11000226A2A -:10B9CC00016812B11268914211D02C4D20620129EC -:10B9DC00287803D1012112F035FB7CBD012113F035 -:10B9EC0001F8216A28780A6801211EF07AF87CBDDA -:10B9FC002346156853F80C6FB54298BF13464204A2 -:10BA0C0001D41A4606E022461D6852F8106FB54262 -:10BA1C0098BF1A46C30401D4134606E023461568A2 -:10BA2C0053F8146FB54298BF1346820701D41A46D7 -:10BA3C0006E022461D6852F8186FB54298BF1A46A8 -:10BA4C00400701D4104606E02046136850F81C5FEE -:10BA5C00AB4298BF1046884218BF0028AFD10020D7 -:10BA6C00012120620548007812F0BCFF7CBD00BFAC -:10BA7C00D527002018260020F0820020988800206E -:10BA8C002DE9FF4715460F46814639B138461DF062 -:10BA9C00F2FF18B10446A5F1010A4EE04A48A0F1A4 -:10BAAC0024014A480678701C01386DD001F1240439 -:10BABC0091F82810FF292146F6D1002C64D0E81EFD -:10BACC00C0B201280DD84248B0F80080B8F1000F80 -:10BADC0007D00320042117F0BBFFA6EB080181421D -:10BAEC006FDDA5F1010A5FFA8AF001280DD83948FB -:10BAFC00B0F80080B8F1000F07D00120022117F038 -:10BB0C00A7FFA6EB080181425BDD0120E846394620 -:10BB1C00ADF802908DF8000008F104001DF0F9FB5F -:10BB2C00404605F015FF0020A071BDF80C006080A8 -:10BB3C002948818C48461AF048F84AF60121002021 -:10BB4C002571A4F80090A4F8091080212082E060EF -:10BB5C00E072E07184F8211020490978013149081C -:10BB6C0021725FFA8AF1042938BF01208000012973 -:10BB7C0060710BD81A48007858B11A4951F8200056 -:10BB8C00C0EB0010800006E0002409E06FF001001B -:10BB9C0004E014480068012184F82010A061E061E1 -:10BBAC0000200421002517F053FF0849097888422A -:10BBBC0024BF0D48057008F04FFE204604B0BDE8C8 -:10BBCC00F0870024F9E700BFB0540020E6BC020067 -:10BBDC00C0BC0200C2BC0200407B0020D1BC0200F1 -:10BBEC00C827002060B70200872700202DE9FC4FF2 -:10BBFC00D0F8C080D0F8D0C0D0F8E820D8F8003009 -:10BC0C00C346E6469C4511D3D8F814B0BBF1000FDF -:10BC1C0000F0898090F8FC3005244FF0000E002BCA -:10BC2C0008BF0124DBF800308BF81040A3EB0E05A5 -:10BC3C00A2F1080AB5F5806F28BF4FF48065D0F8E3 -:10BC4C00D82032B101F1200301F12402C0F8DC50FC -:10BC5C0005E0C0F8D85001F1180301F11C020026D0 -:10BC6C00BAF1000FC8BF0126DBF8044012681F6848 -:10BC7C00CDF800E07CB1354B53F82630BB6005FAAB -:10BC8C0006F30126BAF1000FC8BF02260EFB0633DD -:10BC9C002344013B05E02E4B53F82630BB6000F1EA -:10BCAC00F6033B6043F6F0740191D1F8009004EB7D -:10BCBC000516264009F1080EC7F804E0BC683443A9 -:10BCCC00BC600024BAF1000FC8BF0124DBF8087077 -:10BCDC009FB16146DFF87CC05CF824308C469360E1 -:10BCEC0005FA04F30124BAF1000FC8BF022400992D -:10BCFC0001FB043139444C1E05E0154951F8241060 -:10BD0C0000F1F40491605460C2F800E09168314392 -:10BD1C009160C34504BF05EB0C01C0F8D01090F83E -:10BD2C00FE10019A09B1BDE8FC8FD9F8241041F03E -:10BD3C000301C9F82410D0F8CC00D2E904124068F1 -:10BD4C00114300688162BDE8FC8F00BF18BA020085 -:10BD5C0020BA020028BA0200F0B58BB0ADF80A0088 -:10BD6C00002001F108070C468DF8080038461CF03D -:10BD7C0037F808B306AE0DF10701384632460DF020 -:10BD8C0013FC05464FF6FF7085421FD09DF8070047 -:10BD9C0000B39DF82800002844D0FF280AD00228C0 -:10BDAC0048D0FD2806D001284DD13F4800780138F5 -:10BDBC00012844D93E4844E002A80DF0C5F80128FA -:10BDCC0002D102A818F0CAFBA1205AE03848C4F8E6 -:10BDDC00120055E006F10800394608221DF0D2F990 -:10BDEC0040F2FF10ADF828001DF0B0FD00F00F0080 -:10BDFC0000272946142233468DF82A000420CDE969 -:10BE0C0006771AF0D7FA2B4905EB450041F820705C -:10BE1C0001EB80002649C0E90177C4F8121001211A -:10BE2C00417210E0052060829DF82B0000F07F002D -:10BE3C00A08208E01C480078411E022923D24FF052 -:10BE4C008170C4F812001B4A05EB4501002052F822 -:10BE5C0021305D1C42F82150A3610A232074B5FBEC -:10BE6C00F3F303EB8303A5EB430353B902EB81001C -:10BE7C000121017210484FF48061007812F0E2F851 -:10BE8C0000200BB0F0BD30B90848C4F812009DF882 -:10BE9C002A0084F8280004F11E0006F1080108228B -:10BEAC001DF070F9CFE700BF18260020000001013B -:10BEBC00000003018043002099880020F8B50D464E -:10BECC00417F0446827F1020002908BF0820607043 -:10BEDC000AB108306070217F09B101306070A1791E -:10BEEC0021B1217A00EB410002306070267E474977 -:10BEFC00002E18BF0E26097802290BD14249097869 -:10BF0C00012907D12178012904D04149097809B1C7 -:10BF1C00012100E0002184F83410217D31440844D3 -:10BF2C002870217E31B13B48007B1DF07BF92978CC -:10BF3C0008442870C0B274283DD81DF06FFED0B3F1 -:10BF4C00054634482178677E237F94F818E094F8EE -:10BF5C0006C0627F807C002B41EA800007F0030161 -:10BF6C00A77F40EA811094F83410287018BF012381 -:10BF7C0040EA032040EA4E2040EAC22040EA073063 -:10BF8C0040EA8C2040EA4130000A6870A078A87022 -:10BF9C00E078E8702079287160796871A07EA871CA -:10BFAC00E07EE871607F40B1216A05F108001DF068 -:10BFBC00E0FD102702E0002523E00827A07F20B138 -:10BFCC00616AE8191DF0D5FD0837A07970B1207AA7 -:10BFDC00E855E8190237617A4170E819227AE1686C -:10BFEC0052001DF0CFF8207A07EB4007207F08B1F4 -:10BFFC00F9B268546078227D2169284430441DF0E0 -:10C00C00C1F82846F8BD00BFBA270020182600202A -:10C01C00CC270020407B00202DE9F04F85B007464F -:10C02C008A465818D7F80880D8F80410884202D9E4 -:10C03C006FF003057BE04E4D7C68DDF838904FF0D7 -:10C04C00FF319B46164628681DF094FC6068B8F8D2 -:10C05C002010C5E901015FEAC97014D15FEA89704B -:10C06C0023D5D8F80C0000287AD0D8F81010002965 -:10C07C0076D001228DE80700384651465B463246A1 -:10C08C0013F098F90EE0A068C14300EA0B0211EA24 -:10C09C000B0F1CBFD8F808100A4400EA0A013846F6 -:10C0AC0006F074FF08B105463DE0D8F800005C4688 -:10C0BC003546039600EB0A09ECB3384612F0D4FD72 -:10C0CC0078BB384619F004FB58BB02208DF813904E -:10C0DC008DF810004FEA19208DF812004FEA194024 -:10C0EC008DF811002248018938461CF0FEFE5FFADB -:10C0FC0089F0C0F58076B44238BF264604A80421E6 -:10C10C0013F05CFD68B92846314613F057FD40B971 -:10C11C001748A41BB144018938461CF0EFFE354486 -:10C12C00CAE74FF0FF35124800681DF089FD28461C -:10C13C0005B0BDE8F08F0E98400701D40025F2E75A -:10C14C00D8F80C0060B1D8F8101049B100228DE875 -:10C15C000700384651465B46039A13F02BF9A2E7C9 -:10C16C00034800681DF06CFD6FF00705DFE700BFAA -:10C17C000C2400202DE9F0418AB0514F0546387847 -:10C18C00022804D14D480078002800F09480DFF894 -:10C19C00348198F82600082802D0042840F08B80BF -:10C1AC0007AC284621461BF0D7FF387802280BD164 -:10C1BC001CF020FDA11C1BF072FA28B1BDF81C600C -:10C1CC001DF0ECF9864276D01DF03DFC0234BDF832 -:10C1DC001C00214608F08EFE01286CD06E463046BD -:10C1EC001DF0F9FB304621461BF059FA68B1BDF839 -:10C1FC001C601DF0C1F9864207D0BDF81C004146F9 -:10C20C0021F81A0F4B2015F033FF3878012819D874 -:10C21C00AD8A1DF0C3F9854214D020461DF02BFCCD -:10C22C0030B100790138012802D8204612F02EFED8 -:10C23C002648016831B124480078012802D1BDF8A4 -:10C24C001C008847BDF81C00002100261AF0DEFDFA -:10C25C00B8F82410BDF81C0019F0B7FCBDF81C0090 -:10C26C008DF80C60ADF80E0003AD28460CF06CFE9A -:10C27C0070B1CDE900662E1D684631461BF00FFAF1 -:10C28C0030B1304621461DF044F803A805F060FBA0 -:10C29C00281D21461DF03DF828460FF0DFF950B15E -:10C2AC00BDF81C00BDF80E10814204D0ADF80E0094 -:10C2BC0003A805F04DFB0AB0BDE8F081D52700209E -:10C2CC0018260020407B0020BA270020982300204D -:10C2DC002DE9F047012816D1DFF830A1DAF8340146 -:10C2EC00012813D10220CAF8340119F077FD01207E -:10C2FC00012419F095FA60B1CAF834411BF062FBC5 -:10C30C004FF0FF347FE06FF001047CE06FF0040429 -:10C31C0079E09AF85A419AF859119AF85801002C78 -:10C32C0018BF0124002918BF0234002818BF043498 -:10C33C0001201DF0A5F9013818BF01209AF8381119 -:10C34C00B1FA81F1490910EA010902D1002007F084 -:10C35C00DFF9DAF808002E4D10F0010807D12D4F47 -:10C36C00286A8168384688470428F9D00646404632 -:10C37C001DF0F1FAB8F1000F08D1012E04D1286A92 -:10C38C0001214268234890471CF014FF286841693A -:10C39C00204688479AF8540118B14FF480601DF07C -:10C3AC0075F99AF8530118B14FF481601DF06EF9CC -:10C3BC0019480121016003200021CAF834011748F3 -:10C3CC000160204615F09AFC0128FAD1144E306811 -:10C3DC00042019F025FA044612480125B9F1000F82 -:10C3EC000560306802D1012007F092F91DF0E8F8E1 -:10C3FC00082019F015FA0443CAF8345118BF4FF04D -:10C40C00FF341BF0DFFA2046BDE8F087D81B002074 -:10C41C00B801001000400340282008600C200840A0 -:10C42C002C2009400C4009407CB54B4EB068016C87 -:10C43C00D0F8D420096892F8835019B9D0F84C057B -:10C44C008047B068D0F8B800007800B315F0BAFE99 -:10C45C004349424809680068096C884705461DF045 -:10C46C0067F804463F48017811B93F49097821B370 -:10C47C003E4902220A700078832808BF13F076F830 -:10C48C001DF01AFB1DF030FA0420884757E01DF010 -:10C49C004FF804463348017811B933490978C9B3C8 -:10C4AC0002223249012D0A7004D10078832808BF7A -:10C4BC0013F05CF81DF000FB41E01DF015FA0020B4 -:10C4CC008847B0680DF10701D0F82824F420904774 -:10C4DC009DF90700854223DB254D287800BB1DF014 -:10C4EC00EBFA25480078042803D0B068D0F84C0546 -:10C4FC0080471E48042101702878013028701DF0F7 -:10C50C00F3F909B1032088471C48032101801DF071 -:10C51C00D3FB14E01548832101701DF0CDFA0CE01B -:10C52C00124883210170002017F0F6FD1DF0C4FAAB -:10C53C001048F16880780969087017F0A1F9F06863 -:10C54C00C068007800B17CBDB0680021D0F85824D8 -:10C55C00002090477CBD00BF0C010020D826002095 -:10C56C0030880020AC880020AF880020B4880020E0 -:10C57C00A527002021260020B7880020AE870020A8 -:10C58C002DE9F84F494C1021207816F013FE28B9EC -:10C59C00207810214FF47A721DF0A3FA44480178E8 -:10C5AC000139017009065AD043484FF000084FF684 -:10C5BC00FE790026041D41480578AE421DD2207834 -:10C5CC00C0B1FF2816D001382070000612D1607857 -:10C5DC00032807D134F8041C34F8020C022211F0A1 -:10C5EC0063F8607801281EBFA4F8018024F8029C2F -:10C5FC0024F8049C08340136DFE73148DFF8C4A086 -:10C60C00314C4FF00008002790F800B05F4519D06E -:10C61C0007EB87000AEB4005287A013828720006E0 -:10C62C000ED12046294619F02BF9064610B130469A -:10C63C0019F068FE002EF4D185F80080A5F8029060 -:10C64C000137E3E721482249007830B10A780AB172 -:10C65C00013A0A7008310138F7E7BDE8F88F15493F -:10C66C00002209780170002005211AF0BBFA04465B -:10C67C000626002C98D020460521002225461AF0CB -:10C68C00B1FA044628890028F3D001382881000427 -:10C69C00EFD16889400702D5287B18F0C9FE2868BD -:10C6AC00F0216E73407B15F0D7F8E2E798880020F4 -:10C6BC0017870020DFBC0200E04C0020DABC02002F -:10C6CC00D9BC0200D07E0020A31A02009ABC020042 -:10C6DC00E02700202DE9F04F85B006464D48DFF8E5 -:10C6EC003C9114460D464FF6FE774FF6FE780078D7 -:10C6FC00019049480078049001200290002003909A -:10C70C00474800F1110B47480430009099F800C0DD -:10C71C004FF0000E0020C00774D1049B5946C1464F -:10C72C0003B331F8118CB84518BFB04502D11C3198 -:10C73C00013BF5E7A84518BFA045F8D00A78501E74 -:10C74C000628F4D8072A01D1C146F0E702980EF169 -:10C75C00010EC007EBD103985FFA8EF2C0B2824291 -:10C76C00E5D351E0BCF1010F2AD8DDE9001ABAF18A -:10C77C00000F25D031F8048CB84518BFB04503D153 -:10C78C002431AAF1010AF2E7A84518BFA045F7D059 -:10C79C004B79581E0628F3D8087801380228EFD3B5 -:10C7AC00072B01D1C146EBE702980EF1010EC00731 -:10C7BC00E6D103985FFA8EF2C0B28242E0D323E056 -:10C7CC00C8465FEA0E6002D00398000603D0012031 -:10C7DC00B845A0D018E000205FFA8EFADFF83C9044 -:10C7EC0002900120BAF1010F03903FF48FAF1DF0BE -:10C7FC00ADF8C0B2B0FBFAF101FB1A0003900020B7 -:10C80C00029083E74FF6FE781FFA88F005B0BDE87A -:10C81C00F08F00BFE6BC0200D5BC02001826002039 -:10C82C00DC5B0020B05400202DE9F04395B00446A9 -:10C83C0000208DF81F00208817F096F9002840F092 -:10C84C0081804B48007810B14FF0B30908E0A07814 -:10C85C00042803D11CF0DEFB002876D04FF0B6097B -:10C86C0000261E201AF0FAFB0546BEB303209DF8E5 -:10C87C0052108DF81E0010A808AF08303A4610F080 -:10C88C00A9FF0CAE0DF11E0008213A46334612F0FA -:10C89C005DFCA068314610221BF0C4FBE0B11FFA0E -:10C8AC0088F702AE0420002214233946009619F0B2 -:10C8BC006BFD9DF91B00B0F1FF3F03DC06F113008B -:10C8CC0017F08EF80220394614228DF8180002ABAE -:10C8DC00042019F06FFD01E04FF0AD09B9F1000F24 -:10C8EC0017D09DF81F00012813D19DF9531000207B -:10C8FC00CDE91000002903D401208DF85100FF2050 -:10C90C008DF850001FFA88F110AB0420142219F096 -:10C91C0051FDBDB1092085F81D9008222870208892 -:10C92C006880A0782871681D61681CF02BFCA168D8 -:10C93C0005F10D0010221CF025FC0E48294600784C -:10C94C0012F0ACFB15B0BDE8F08360680DF11F016F -:10C95C0010AA0CF029FE80469DF81F0018B14FF06C -:10C96C00000901267DE74FF0AD09002679E700BFED -:10C97C0018260020998800202DE9F843DFF8308133 -:10C98C000C46914607462246B8F8241013F046FC94 -:10C99C00002879D0068905464FF6FE70864204BF02 -:10C9AC00C320BDE8F8831CF0F9FD864204BFC22009 -:10C9BC00BDE8F8832988B8F8240088421CBFA8F881 -:10C9CC002410084615F020FCE87A3946013088F826 -:10C9DC00380008F139001DF0CCF802208DF8010068 -:10C9EC00684619F047FF002851D007460069062118 -:10C9FC000126017098F80E104170BE771CF0FAF801 -:10CA0C0078624020BE7687F81890F8822889788062 -:10CA1C00384611F05DFF002845D1092008F11A01B4 -:10CA2C0088F826002889A8F81A0098F81800A0425F -:10CA3C0018BF88F818401F4C4B20A04708F1240160 -:10CA4C005020A04708F11801E120A04708F1160179 -:10CA5C005320A04708200121FEF758FF4FF4005047 -:10CA6C000021FEF753FF144C4FF48061207811F035 -:10CA7C00B9FF1348007802280BD110480078012820 -:10CA8C0007D14FF4DC6208E0CA20BDE8F88310201F -:10CA9C0009E0082010F098FF820020784FF48061A4 -:10CAAC001DF022F80020074900220A70BDE8F88327 -:10CABC00407B00207D20020098880020D527002094 -:10CACC00182600209E8800202DE9F0474FF6FC76B2 -:10CADC00B04201D100240FE0884600211D46924649 -:10CAEC00002414F055FCDFF814910746680606D4B0 -:10CAFC00B9F81600874202D12046BDE8F0873846C7 -:10CB0C0029460DF0A7F930B9B01C002180B20DF008 -:10CB1C00A1F9002860D0B11C078089B2884505F0C6 -:10CB2C00010118BFA0F8028045EA8101BAF1010F9A -:10CB3C00817142D101214171334915F0180F99F8D7 -:10CB4C001420097818BF0A4602714046B9F824101F -:10CB5C0016F06AFD0028BDD12A482C49DFF8B0A098 -:10CB6C00274B0022007891F800C06245B2D0C2EB8E -:10CB7C00C20600270AEB8604B8420BD003EBC705AC -:10CB8C0021886D888D4201D00137F5E70132F9B269 -:10CB9C008842EAD120461C211CF090F94AF601206B -:10CBAC002AF82680A4F811001A48007801304008B1 -:10CBBC002074B9F8240060818CE7417901293FF495 -:10CBCC0089AF114915F0180F08BF09F11301097845 -:10CBDC0080F805A001717DE715F0180F0CD00949FC -:10CBEC0007480978063039B110F8082B013912F0D2 -:10CBFC00180FF8D10E388EE702247DE7407B002019 -:10CC0C00E04C0020DABC0200DCBC0200D5BC020007 -:10CC1C00DC5B0020D1BC0200F0B58DB00546007C79 -:10CC2C000F2873D36E68686908AC0021224613F094 -:10CC3C0043F89DF82000002868D1287C0B2865D388 -:10CC4C00307A022862D1B189C8B2FF285ED19DF832 -:10CC5C00220010F0FD0F59D1404F97F8263043F0C9 -:10CC6C000402062A04D13E4A1268AAB1C90B1FE07D -:10CC7C003B4A126812B19579012DF4D0082B01D0E2 -:10CC8C00042B43D17589002A42D0917902293FD1D6 -:10CC9C00284619F021FB39E0727C71893088002319 -:10CCAC0000930023FBF7B2FDB089C10B9DF8220065 -:10CCBC0032888DF80D10B17B9DF824308DF8100062 -:10CCCC009DF825509DF83200ADF8082072898DF83A -:10CCDC000C109DF821108DF80E308DF813508DF836 -:10CCEC001400ADF80A20727C9DF826608DF81110A6 -:10CCFC00E11D8DF812208DF80F6002AD082205F1B0 -:10CD0C000D001CF03FFA28461CF080FF0DB0F0BD62 -:10CD1C00B98CA942FAD1012806D0E11D07F13900DE -:10CD2C001AF0BDFC0028F1D10E484FF400710078C8 -:10CD3C0016F040FA0028E9D140F20120ADF80D00C0 -:10CD4C00B86A029097F82E008DF80C0002A812F029 -:10CD5C0021F900289CD01AF085FDD7E7407B0020F4 -:10CD6C00CC26002098880020F0B59DB04668077A44 -:10CD7C0010AD0446342128461CF0A0F88DF8407004 -:10CD8C00294636F8020B16F09DF902201A9604F18A -:10CD9C0028018DF84100608EADF84E009DF84000E2 -:10CDAC0002388DF85C0006A81CF0F9F89DF84200DA -:10CDBC0003287AD19DF843501CF0EAFB854274D1CC -:10CDCC009DF84400002870D19DF8450000286CD1D6 -:10CDDC009DF84600002868D19DF85D00002864D1BC -:10CDEC009DF84700002860D19DF8480000285CD1D0 -:10CDFC0009A81C211CF062F8BDF84E001A9A9DF887 -:10CE0C005C30ADF82E00154615F8010B00F003014F -:10CE1C008DF82400032916D100F00C060C2E05D039 -:10CE2C00082E08D101268DF8306004E0B2F80150CC -:10CE3C00ADF82850D51C35F8046BADF82A6035F8E0 -:10CE4C00026CADF82C60521B0D9513445242032911 -:10CE5C008DF838308DF8312027D100F00C010429E1 -:10CE6C0023D010F0200108BF10F080001DD1FE204F -:10CE7C009DF85310B4F8422000238DF827000C487D -:10CE8C0040788DF8260094F846008DF81400B4F81C -:10CE9C004700ADF81500E06BCDE90013CDE90203B6 -:10CEAC0009A806A905AB08F08DFE1DB0F0BD00BFAA -:10CEBC00C02600202DE9F047DFF83491D9F840A0C6 -:10CECC00BAF1000F00F089800AF10C020820FF2152 -:10CEDC0051FA80F0C3B21B1A18BF012312686AB151 -:10CEEC0063B11388A3F60303012B01D90432EFE7D6 -:10CEFC00DAF8100092E8FA003830FAC0DAF80820B4 -:10CF0C000025DAE90A10CAE90A55B2B110F0E24478 -:10CF1C000CD021F00F0220F0E2434FF0000852EA4F -:10CF2C00030005D01CF057FAB04701E088460446D0 -:10CF3C001CF051FA42462346B0471CF0F9FA04465D -:10CF4C00B9F8560001306FF31F30A9F856004FF6B0 -:10CF5C00FD70AAF8300009F140008AF833501AF03D -:10CF6C0027FB20461CF090FDB9F85600B9F8541078 -:10CF7C00884232D11F48204940680D6830B190F882 -:10CF8C00FC200720002A08BF052000E005204C6883 -:10CF9C000FF06EFC55B195F8FC00002100284FF005 -:10CFAC00000008BF286885F8FC1000E0002044B1A0 -:10CFBC0094F8FC200021002502B9256884F8FC10A7 -:10CFCC0000E00025A84288BF0546681C05D035B98D -:10CFDC000020BDE8F0471BF041B8BDE8F0871CF01D -:10CFEC00EDFDB5FBF0F10548BDE8F0471BF094BB37 -:10CFFC0030210020D01E002070200020207F002037 -:10D00C002DE9F04186B01D4614460E46022818D074 -:10D01C00012818D0002876D1012E6BD0022E72D1A7 -:10D02C0008201AF05FFD3E480021437B3D48026812 -:10D03C0040480088CDE9021104913F49CDE90045F3 -:10D04C0055E0002000E00120032E00D0F6B91BF0C3 -:10D05C00E1FF032E18BF002835D102201AF042FD43 -:10D06C002F48304C417B206810F0CCFE2E4989783B -:10D07C0001F00801014345D12C48017801310170C0 -:10D08C00C8B2042849D12A48206046E0711E80F0BD -:10D09C00010018BF0121084335D10A201AF022FDE6 -:10D0AC0026484FF48061007811F09CFC0DF11601BC -:10D0BC00502018F0B1FF2249BDF8160088840021D9 -:10D0CC001CF094FD29E0164890F80D80154807686F -:10D0DC00184806881CF03AFC0121002204903046C6 -:10D0EC004346CDE90045CDE9022113493A4605F006 -:10D0FC00CFFB07E008201AF0F5FC20462146002261 -:10D10C001BF0E8FF48B10F4801214FF47A72007808 -:10D11C0006B0BDE8F0411CF0E7BC06B0BDE8F081FC -:10D12C00CC22002070880020268700208927002030 -:10D13C0000F8FF0780270020B426002098880020E4 -:10D14C00407B0020998800202DE9F04F8BB00C46D5 -:10D15C000690C9881F460792E07816F0CFF9002890 -:10D16C007ED0217D0546C0B219F0AFFE002879D0E3 -:10D17C000646E188E0780597DDE9177900224FF043 -:10D18C00000815F095FC8346E0787071E188A07D6D -:10D19C0086F80880227DF1807081F06821691BF08F -:10D1AC00F1FF86F8149077824FF000090027BBF14D -:10D1BC00000F4AD05FFA89F0854246D906EBC00AC7 -:10D1CC009BF80110504600F8168F012904D1012755 -:10D1DC000770BBF8020005E0BBF802008AF81D00DE -:10D1EC001BF076F9AAF8180022789BF80410520666 -:10D1FC008AF81A1005D59AF81C2042F002028AF817 -:10D20C001C20C7B9204AD28A904214D11E48A17062 -:10D21C00DDE90613CDF80080828C159801901698E4 -:10D22C00CDE90208204608F0CDFC9AF81C0040F02D -:10D23C0005008AF81C0009F10109E188E0785FFA21 -:10D24C0089F215F035FC8346B1E7304619F0C8F881 -:10D25C000599DDE9142320460096FAF719F810E039 -:10D26C00B92000E010208DF82800E078A17D8DF821 -:10D27C002300E0888DF82410ADF8260008A81BF0D8 -:10D28C005FFC0BB0BDE8F08F407B00202DE9F84F20 -:10D29C00816A91F90120002A2AD4824602F01F00EB -:10D2AC0000EB40049AF81C300234A34220D18B1CB2 -:10D2BC00D2B24FF6FE784FF6FE7C08B1B1F802C040 -:10D2CC00DFF804914FF0000B4FF6FE770021B9F810 -:10D2DC001650814211D29C7814F0880F08D133F883 -:10D2EC00037BBEB2AE4208BF04F0070B0131F0E77E -:10D2FC00D320BDE8F84F09F006BD5FEA0B6006D1FC -:10D30C001FFA8CF0B9B215F0B3FC00284FD0BAF864 -:10D31C000C001CF05CFB98B10021027AC1712B4906 -:10D32C0009788A4208D30131490801725FFA8BF1FE -:10D33C00072938BF0BF1010B80F809B0BDE8F88F55 -:10D34C0008F10101BAF80C0089B217F0C9FC20B140 -:10D35C0005461E48297C007815E016F047F930B3D5 -:10D36C001C2105461BF0AAFD4AF60120A5F8110068 -:10D37C00BAF80C002880B9F82400688113480078AA -:10D38C00411C49082974814208D301304008287493 -:10D39C005FFA8BF0072838BF0BF1010B002085F8E2 -:10D3AC0011B02873023528461AF01AFD08B1BDE8F1 -:10D3BC00F88F9AF808000028F9D0DAF818102846E7 -:10D3CC00BDE8F84F1CF0D5BB407B0020D1BC02005F -:10D3DC007CB50568002D6DD004464748026842B103 -:10D3EC00217928469047012803D1688920F0010053 -:10D3FC006881687B02282DD1688980072ED5207919 -:10D40C00CD282BD0F02829D0688A00060CD5A87E10 -:10D41C0050B1A8732868008816F0A6FB40B94FF4E9 -:10D42C00987009F070FC03E0344800780130A87360 -:10D43C002079002856D004202021687330480088B9 -:10D44C002881A87B0138A876A8732E48007810F0A4 -:10D45C00F9FD687B40F0040006282BD12B49288B62 -:10D46C00C98A884214D02849097889B12968098861 -:10D47C00ADF8000001208DF80500287BADF80210F6 -:10D48C008DF8040020798DF8060068461BF0F2FC3C -:10D49C006889C0070ED0217928461BF040F86889AE -:10D4AC0020F0010068812868008816F05DFB217966 -:10D4BC0008B121B17CBD39B140F2311001E040F22C -:10D4CC002D1009F020FC7CBD40F22F1009F01BFC44 -:10D4DC00002560798542EDD24FF49B7009F013FC66 -:10D4EC000135F6E7002660798642A4D24FF49B7092 -:10D4FC0009F009FC0136F6E738240020B627002095 -:10D50C007C27002098880020E9250020407B002003 -:10D51C00BFB54A4D044695F82600092800F28C80C8 -:10D52C00012101FA00F040F20A21084200F0848047 -:10D53C006178F1B141F2030011F0E1F84048007854 -:10D54C0002280ED13F4801780B2904BF0A21017033 -:10D55C003D48002101703D484FF48041007811F0A6 -:10D56C0041FA6178A88C1CF041FB002085F826005C -:10D57C0060E00220002111F0C2F834F8020FE882BA -:10D58C005320214614F074FD95F82600092802D08A -:10D59C00A88C14F039FE01200DF10F018DF80F004D -:10D5AC00422014F065FD04200DF1070485F82600D7 -:10D5BC004A20214618F030FD05F11C0021461CF0D4 -:10D5CC00D8FA204801780B2902D10621017003E01A -:10D5DC00A88C00211CF00AFB194C207802280AD2D6 -:10D5EC00688B4FF6FE7188420ED00DF107010022B8 -:10D5FC00FEF746FA08E007D1E98A032011F07FF81C -:10D60C00698B042011F07BF8A87B0DF10F01C0F39E -:10D61C00C0008DF80F00522014F02AFD207802284B -:10D62C0008D1A87B00074CBF4FF40040012001211A -:10D63C00FEF76CF91AF07EFEBFBD00BF407B0020E8 -:10D64C0018260020C4260020CC2700209888002013 -:10D65C002DE9F0418846080430D45FEAC86000F137 -:10D66C0081805FEA887000F182805FEA087000F1C7 -:10D67C00818018F4706F00F082805FEA085004D546 -:10D68C0000201BF0C5F988F400685FEA485004D507 -:10D69C0001201BF0BDF988F480685FEA885004D53E -:10D6AC0002201BF0B5F988F400785FEAC85068D501 -:10D6BC0003201BF0ADF988F4807862E0324F3878A3 -:10D6CC0011F0BEF900284AD0054646680078411E84 -:10D6DC0005290DD91A282CD024282ED0D12833D0A6 -:10D6EC00D32835D0FD2836D128461AF088FB32E0F5 -:10D6FC00DFE801F0030B310F311B66B3304611F03C -:10D70C001DFC30461CF088FA25E0284614F08CFEEF -:10D71C0021E0F478701CE11CC9B21BF099F8611D72 -:10D72C0056FA81F101F8010C15E028461AF064FF55 -:10D73C0011E02846FDF7F6FD0DE0F0780530C1B29A -:10D74C0030461BF007FF06E028461BF00FFF02E0F7 -:10D75C00284611F061F828461AF07EFBAFE788F4F2 -:10D76C0000480EE01AF02EF888F0100809E088F056 -:10D77C00020806E00DF002FB88F0080801E04FF00B -:10D78C0000084046BDE8F0819688002070B50C4634 -:10D79C0008041CD4E00729D144480078012805D896 -:10D7AC00A00745D4A00654D4600474D4E0062DD44C -:10D7BC00200744BF84F0080070BDE0053DD460072D -:10D7CC005FD400202146BDE8704009F0DDBB344E2B -:10D7DC00307811F035F930B1054607F043FC284696 -:10D7EC001AF03AFBF4E784F4004070BD01201AF003 -:10D7FC0079F92C480F220F2381782B48008800F0F0 -:10D80C000700FFF7FDFB84F0010070BD2548007890 -:10D81C0010F0D8FC28480078012806D127484FF48E -:10D82C000061642200781CF05FF984F0100070BD78 -:10D83C000AF046FA84F0020070BD214890F82600E8 -:10D84C00082801D0042801D11BF038FA84F4807028 -:10D85C0070BD1748007860B912480078062802D1CC -:10D86C0007201AF03FF913480078012808BF19F077 -:10D87C00F1FC0B481021007810F0E4FB84F0200040 -:10D88C0070BDFF20032116F019F81BF093FE0D4814 -:10D89C0001210160FEE714F041FB84F4804070BD6F -:10D8AC0099880020C42600202687002018260020F6 -:10D8BC00BB880020BA270020BD27002098880020B4 -:10D8CC00407B00207C052043F0B58DB0044603203E -:10D8DC000D468DF830000AAE30461CF04AF91BF0AC -:10D8EC0089F90146304619F0DAFE50B1287D40F036 -:10D8FC000201032905D1297A09B1FF2914D182200B -:10D90C0000E084208DF82700E289207C0DF12701AE -:10D91C000123CDE9001004F11100A11C42F40042D6 -:10D92C0013F07AFE0DB0F0BD032804D1A87DFF28BA -:10D93C00E5D00028E3D0304F4FF0FF300822CDE97E -:10D94C00060006A93E1D30461AF06CFB18BB2B488E -:10D95C006188C08A81421ED03878FF280AD0297A83 -:10D96C00814207D078884FF6FF71884202D06989CE -:10D97C00884210D10020314608228DF8080002AFF1 -:10D98C00381D1BF0FFFB38460DF068FE6088BDF8B3 -:10D99C000A1081422DD1E08905F10C0621281CD1F9 -:10D9AC008C206989AB7D32468DF82700287A17F0D8 -:10D9BC00E7FA0028A8D11BF09CFF287D0328A3D1EF -:10D9CC0002A9304617F00CFB00289DD130460021EF -:10D9DC000022002310F026FC96E76989287AAB7D9B -:10D9EC0032461AF093FA08B188208BE71BF081FFBE -:10D9FC008AE78D2086E700BF00260020407B0020B0 -:10DA0C002DE9F04F8BB04B4FB868D0F80001807AFD -:10DA1C00C0001CF003F9002809907ED00DF1040B16 -:10DA2C0000264FF6FF7A0BF103051BF081FD0DF17B -:10DA3C0014090090B868B2B2D0F800110B899A4260 -:10DA4C0063D201244FF00008C97A5FFA88F28A4247 -:10DA5C0021D2D0F88824D02059468DF80680ADF814 -:10DA6C000460904728B1B86808F10108D0F800119B -:10DA7C00EAE79DF8100000240128F4D19DF80F006E -:10DA8C000028F0D10020082806D0295C0130FF299D -:10DA9C00F9D00024E7E70CB10136CBE70024B868D5 -:10DAAC00E1B2D0F80021D2888A42F5D9D0F8882486 -:10DABC00ADF80610D1205946ADF80460904710BB64 -:10DACC00BDF8080050451ED0ADF81400B8684946A2 -:10DADC00D0F88824D420904708BB4FF0FF3049463B -:10DAEC00ADF81AA0ADF818A0CDE90700B868D0F8C9 -:10DAFC009424D4209047B8685946ADF808A0D0F8C3 -:10DB0C009424D12090470134C9E700981BF0BCFF46 -:10DB1C0009981CF081F8002008E01A2006E0009813 -:10DB2C001BF0B2FF09981CF077F819200BB0BDE878 -:10DB3C00F08F00BF0C010020F0B589B00546002025 -:10DB4C0001F108060C468DF80F0030461AF048F922 -:10DB5C0018B9284631460DF05DF804AD0DF10F01F2 -:10DB6C0030462A460BF020FD3B4E4FF6FF773178BE -:10DB7C004A1E9DF80F10012A10D879B900200DF11A -:10DB8C000F01CDE90000684604AA0BF00DFDB84268 -:10DB9C001ABF01218DF80F109DF80F10B1B1B842CA -:10DBAC0014D09DF8201099B3FF2926D0022918BF54 -:10DBBC00FD2912D12A4900EB400001EB8000A1693C -:10DBCC0050F8042F91420FD2A22042E0307810B9C5 -:10DBDC001BF0BCFDC0B1A1203BE0012938D130784D -:10DBEC000138012806D90FE0013101603078411E5F -:10DBFC0002291ED24FF0817007E0307801380128DD -:10DC0C009CBF012084F826001448C4F812001FE0C1 -:10DC1C00052060829DF8230000F07F00A08212484E -:10DC2C000078002818BF012084F8270084F826000B -:10DC3C000EE030B90B48C4F812009DF8220084F8AD -:10DC4C00280004F11E0005F1080108221BF09AFAC5 -:10DC5C00002009B0F0BD00BF182600200000030111 -:10DC6C008043002000000101942700202DE9F84F8B -:10DC7C001D4600928B4681461BF05AFC444A824654 -:10DC8C0000214FF4A060012705F1010C002392F84C -:10DC9C006040602935D007FA03FE1EEA040F0AD053 -:10DCAC00BCF1000F18BF9D4205D1561896F80A809A -:10DCBC00B8F1000F04D000F5807020310133E8E793 -:10DCCC0024EA0E040125737282F8604092F86240D7 -:10DCDC00B572013482F862409EB142F801902D4930 -:10DCEC00BBF1020F86F808B0716011D0BBF1010FC7 -:10DCFC0034D1591DB1740A2131820A998968716134 -:10DD0C002CE0FE2450461BF0BFFE60B2BDE8F88F3D -:10DD1C00718A5A1D0A9B02F00F0221F4706141EACC -:10DD2C000221718221F0F8015A7902F01F0241EAB6 -:10DD3C00C201718221F4C0419A7902F0030241EAD6 -:10DD4C00423140F20362328271824EF6FF72114010 -:10DD5C00DA7902F0010241EA023171820B9A42B186 -:10DD6C0011785278920042EA411108430A4908435B -:10DD7C0000E000200099B06101B171600748416872 -:10DD8C0009B9C0F804900FF02BFC747ABAE700BF05 -:10DD9C00B87B0020BB2E010001000406D01E002021 -:10DDAC007CB504468078022820D0012840F08C8075 -:10DDBC00267D00208DF8060006F1180019F04EF9AA -:10DDCC00054610B901208DF80600607940F002007C -:10DDDC00022824D1002D4CD0E078002818BF012057 -:10DDEC001BF0EBFA23D01BF0C5FA25E000208DF8D0 -:10DDFC0007002C2019F032F9054610B901208DF8D6 -:10DE0C000700607940F0020002280CD1002D54D09C -:10DE1C00E0781BF0D2FA31D01BF0ACFA33E00220E0 -:10DE2C008DF8060025E002208DF8070045E0A01DC6 -:10DE3C00042118F06DFBA860A07C32462874E07CAD -:10DE4C006874207D15342146A87505F117001BF068 -:10DE5C0099F9A05DA874A019417869758178297524 -:10DE6C000521C07829802946E8741848007811F0FB -:10DE7C0015F90DF106037520012122E0A01D0421E6 -:10DE8C0018F046FBA860A07C04F115011022287440 -:10DE9C00E07C2875207D687505F11C001BF072F97B -:10DEAC0004F12500042118F033FB0821A861074870 -:10DEBC0029802946007811F0F1F80DF1070375203F -:10DECC000221012214F0D4FB00207CBDA488002088 -:10DEDC002DE9F04F89B00E46834601A82021144647 -:10DEEC001AF0ECFF202E08D0182E04D0102E0CBFE8 -:10DEFC000127002702E0022700E0032744F2040A6E -:10DF0C004FF00108C4F2020A40F2B01908FA04F505 -:10DF1C00C1F200090094CAF80054D9F8000044F288 -:10DF2C00007441692720C4F2020488470320C4F816 -:10DF3C008080C4F88400C4F80080C4F888004FF6D0 -:10DF4C000850CFF6FF7021588F4218BF2750182E5B -:10DF5C00CAF8FC5315D101A8594618221BF0CAFE69 -:10DF6C000320C4F8880000BFD4F890008007FBD1D0 -:10DF7C000020C4F248200121016020260DF1040B81 -:10DF8C0011E0BBF1000F18BF002E10D00320C4F815 -:10DF9C00880000BFD4F890008007FBD10020C4F2A9 -:10DFAC00482001210160CAF800B0CAF808600325B6 -:10DFBC00CCF2000501201BF012FDD4F89000284291 -:10DFCC00F8D0D4F890000540C4F88850D9F8000077 -:10DFDC00016A27208847D9F8000001692720884763 -:10DFEC000020B0EB957F07D1DAF800040099C0430C -:10DFFC00C84000F0010000E0012009B0BDE8F08F3E -:10E00C002DE9F04F8BB04248DFF80CB100240DF134 -:10E01C001C0A4FF000084FF000090027007801900F -:10E02C0000EBC00086003B480078013040080290AD -:10E03C0046455CD01FFA89F1032000221023CDF84D -:10E04C0000A018F0A1F900284CD19DF821300BEB61 -:10E05C000801BDF81C009DF820200C82CC60CC720D -:10E06C004B714AF601232BF80800BDF81E000A710B -:10E07C00A1F80930029B48800B72BDF82230CB808E -:10E08C000A9B5D1C04D081F82040C1E9063315E0E1 -:10E09C00013A012A09D8214A12784AB1204B53F887 -:10E0AC002220C2EB0212920004E06FF0010203E0A6 -:10E0BC001B4A126881F820408A61CA614FF6FF71D1 -:10E0CC0088420FD0ADF8180001208DF80C0003A881 -:10E0DC0011F014FF28B11348818CBDF81C0017F007 -:10E0EC0074FD013708F1240809F10109A0E70020AB -:10E0FC000421002415F0ACFC0199884224BF0A4885 -:10E10C00047006F0A9FBF8B20BB0BDE8F08F00BFAD -:10E11C00E6BC0200D1BC0200B0540020C82700208D -:10E12C0060B70200407B0020872700202DE9F041DA -:10E13C00414F04467878C8B1DFF80081B8F8540034 -:10E14C00B8F8561088421ED008F13801204619F054 -:10E15C0040FA80B9D8F8480010B10069A04207D045 -:10E16C0008F14001204619F034FA03E0BDE8F081D3 -:10E17C00D8F8480038B1B0F9301020460A224FF0D8 -:10E18C00E04308F035F81BF0D3F92D4D0646284630 -:10E19C0002C8A14208BF28460021016078780138E6 -:10E1AC007870000636D17C60387E02280ED10820AB -:10E1BC0016F0F2FA30461BF067FC04F150004FF0F9 -:10E1CC00FF311BF0D7FB1BF0B3F9064605F1280015 -:10E1DC001BF038FD40461BF0FDFC1A481BF032FDCD -:10E1EC0008F11C001BF0F6FC17481BF0E5FC174867 -:10E1FC001BF0E2FC1648416811B107F1500088474A -:10E20C0007F1280019F0EEFB1248807810B10D20B0 -:10E21C0007F016FB7868A04204BF002078603046F7 -:10E22C001BF032FC04F150001BF008FD04F1B800A7 -:10E23C00BDE8F0411BF0C0BCD01E002030210020F6 -:10E24C007020002028800020647F0020207F002088 -:10E25C0074260020ACBB02002DE9F0478EB080463E -:10E26C000E2016468A468DF81A308DF818208DF837 -:10E27C00190001208DF81C003E48B8F1000F077BF7 -:10E28C008DF81B7021D00AEB0605687B11F0FEFEA1 -:10E29C00002403463A2802D03B2B0BD13B230DF133 -:10E2AC000409002011214A4619F084FE002808BFF9 -:10E2BC0009F1010428780994384305F8050B0DF190 -:10E2CC002B0029461BF055FC36E001AD0020112136 -:10E2DC003A2300242A4619F06DFE08B109942BE06C -:10E2EC00DFF894906C1C012101220994D9F80430B8 -:10E2FC00581CC9F804000AEB06000090384612F0CE -:10E30C00CAF81AF077FC01460DF12B001BF031FC1A -:10E31C00B9F80000194901300968A9F8000080B269 -:10E32C00814203D3D9F80400012805D114484FF4D5 -:10E33C00007100780FF086FE0DF12B000AEB06053C -:10E34C000422691C08301AF01DFF1AF806008DF81B -:10E35C0037005CB106A90DF12B024046534606F07E -:10E36C0091F8297801F0F801297000E0A1200EB095 -:10E37C00BDE8F087407B002004250020ACBC0200E7 -:10E38C00998800202DE9FE431BF0D2F8DFF80C91A0 -:10E39C00804699F80100B8B14148032201688260B7 -:10E3AC00C80711D03F4C2068416802208847019073 -:10E3BC00206841680120884702903B4801A91C3025 -:10E3CC0011F084F917F04CFDD9F80450EDB1364931 -:10E3DC00686A01AF01F11C06A96A884219D230465D -:10E3EC00394612F06FFA013011D0D5E90912E869FB -:10E3FC00541A08443946082C28BF082422461BF01E -:10E40C0079FC686A20446862E6E700240CE0D5E9F0 -:10E41C0009010024884207D309F10400294618F0A9 -:10E42C00EDF985F83240012499F8010088B9D9F842 -:10E43C00040018B180681AF017FB0AE01A481C3067 -:10E44C001AF0E5FF28B9194A4FF0FF30012110F0FE -:10E45C0053FB40461BF018FBF4B1A868002201687E -:10E46C00CA628A690AB10223137091F83030012B09 -:10E47C0007D0022B10D101F134001BF0E1FBBDE8F9 -:10E48C00FE8322B1CB6800219847BDE8FE830C695E -:10E49C00CA698B6A0021A047BDE8FE8318230020BF -:10E4AC0008800240CC0100107422002080A90300D7 -:10E4BC0070B586B0454D0446A868D0F8F41091F8B4 -:10E4CC004420B2F1820318BF531C81F84430D0F8B9 -:10E4DC00F40090F8441000EBD10090F82C104A088E -:10E4EC0080F82C20C807A86809D1D0F8F41091F94D -:10E4FC004420531C12F1020F81F84430E7DCD0F8B1 -:10E50C00F420114611F8443F802B25D8D0F8302444 -:10E51C00E1209047AA6802208DF814004FF0FF30DC -:10E52C00D2F8F430ADF80C009878022823D00128EA -:10E53C0024D030BB1BF042FB4FF47A71244B0022E9 -:10E54C00B1FBF0F023490BF045FCE0B3A8681A21AD -:10E55C00D0F8F400417004E0907810B91C4814F025 -:10E56C0007F92A202070A868D0F84013204606B07E -:10E57C00BDE870400847D2F86814F7E708208021FE -:10E58C0001E007208321D2F8786303F149020023CC -:10E59C00CDE9003203AA4FF6FF73B047A0F1DB01BF -:10E5AC00182910D8012202FA01F10B4A11420AD0A3 -:10E5BC00A968D1F8F41048702A202070A868D0F807 -:10E5CC0040132046884706B070BD00BF0C010020E8 -:10E5DC0058880020FD2C0100112400012DE9F04386 -:10E5EC0089B004464648807860B9E07AFE2809D1A3 -:10E5FC00684624211AF062FC208B10F00D0F06D017 -:10E60C00B62400E00124204609B0BDE8F083207A4E -:10E61C000028F5D001288DF8080011D002281CD054 -:10E62C0003281ED00F2820D102204FF000080B2603 -:10E63C004FF000098DF808002088ADF8000019E0B3 -:10E64C00B4F800804FF6FF700F26ADF800000220E2 -:10E65C004FEA18298DF808000CE02088ADF800006E -:10E66C0003E0684621461BF084FA4FF000080326AD -:10E67C004FF0000906F00C0707200C2F08BF0920EB -:10E68C00A17C08448DF81F00C0B21BF0C7FAA0B3E0 -:10E69C000890054686700C2F11BFE81C85F8049075 -:10E6AC0085F80380681DA17B0170E17B4170217CA2 -:10E6BC008170617CC1700430628A61691AF062FDFC -:10E6CC001AF066FF81098000033069702870B7FA70 -:10E6DC0087F04009ADF80E0003208DF80C00A07EE9 -:10E6EC008DF80D00A089ADF80A0068461BF026FADB -:10E6FC00044628461BF090FA85E7102483E700BFF8 -:10E70C00C02600202DE9F04F85B0054691460E46F7 -:10E71C00C80731D12846314612F03AFE404FF98AEB -:10E72C00884242D02846022132460CF0CBFCE0B3A2 -:10E73C0028464FF6FE7102223346FEF7C5F990BB10 -:10E74C004FEA152806F0DF0A70061ED402A92846E7 -:10E75C0017F03EF968B9B98C284616F0C1FAA0B189 -:10E76C00871C384619F03CFB78B102A839461BF0DF -:10E77C0000FA46F0200A08E0B0074CBF46F0100A39 -:10E78C0046F0080A4FF0FF08FC25264800220778BF -:10E79C00791C01702248012100913946C08A034638 -:10E7AC0009F080F818B1C72036E0002034E00E20C4 -:10E7BC001AF0200408BF06208DF8110004A818F0E8 -:10E7CC0059F840B34FF0010B064680F81EB01AF012 -:10E7DC0011FA70623069002141710AF0780187707A -:10E7EC00C57080F8048080F800B041701CB1063010 -:10E7FC0002A91BF0BEF96FF00300B9F1000F708095 -:10E80C0005D009480078484588BF86F81A903046EC -:10E81C0010F05EF800E0102005B0BDE8F08F00BFEE -:10E82C00407B0020BC880020CFBC02002DE9FE4FAD -:10E83C008A4683461AF000FEDFF80891DFF8FC8068 -:10E84C003F4E99F8001098F80200B07339B10007E8 -:10E85C0013D501200DF10A018DF80A000AE0002001 -:10E86C0000240EF093FCB07B000706D58DF80B400E -:10E87C000DF10B01522013F0FBFB0FF0D7F819F040 -:10E88C0087FF38B105460EF0E3FD13F031FF0DF0B4 -:10E89C00B5F808E009F052F80546307E012101FA7E -:10E8AC0000F0294908604FF6FE74012D2FD10FF0AE -:10E8BC0029FC1BF04BF807462448234900680860E4 -:10E8CC00FF20022114F0FAFF601C7483F482B084E0 -:10E8DC00002013F0CFF907F07F00584400F16406D4 -:10E8EC001B480078012808D10020BAF1010F1CBF89 -:10E8FC00CDE90000684615F013FB114A2120742164 -:10E90C001AF07EFF0020022114F0D8FF00E0002650 -:10E91C0028460CF0FFFF601C80B2834507D0012015 -:10E92C0089F8000018F01EF8B0B219F025FF98F81D -:10E93C00020019F04DFB2846BDE8FE8F268700200B -:10E94C00407B0020C4260020708800206C2700200B -:10E95C00182600202DE9F0438FB014F0EFFB3F4F49 -:10E96C0097F82600082806D00120C7E90C003C487F -:10E97C000078F87078710DF11408242140461AF0D3 -:10E98C009DFA39480F25374EDFF8E0900DF13B0129 -:10E99C008DF83B5000783570013818BF01208DF888 -:10E9AC001E004620C847324800248DF800400078ED -:10E9BC008DF801001AF0ECFD8DF8020097F8380084 -:10E9CC008DF80640ADF8034007F139010F2838BF28 -:10E9DC0005468DF805506D46E81D1BF0CAF84FF042 -:10E9EC00FF303278234EADF80F008DF8110097F8F8 -:10E9FC00720031468DF81200284610F092FE452028 -:10EA0C003146C84705F028FFB88D97F82F108DF8C0 -:10EA1C0020408DF834408DF82940ADF81C00387E2C -:10EA2C008DF81F1007F116018DF81A00B88CADF88F -:10EA3C0018005320C84707F11A014B20C847F87932 -:10EA4C00642100FB01F20C48082100781BF04CF803 -:10EA5C00404606F0BFFB0FB0BDE8F083407B0020C2 -:10EA6C00E6BC0200A9270020182600207D20020009 -:10EA7C00D827002008870020988800202DE9F84F1F -:10EA8C004FF00056002A984617460C46824618BF8F -:10EA9C004FF080464D1C1AF04BFD814635B1504667 -:10EAAC002146002213F0B2F904460FE03748816C7E -:10EABC0011B10969514506D0C16C11B109695145B3 -:10EACC0003D0846B02E0846C00E0C46C34B194F924 -:10EADC003300B0F1FF3F03DD042451E003244FE089 -:10EAEC00DFF8A8B00A9DDBF84800844218D0DBF8A8 -:10EAFC004C00844214D05046214642462B460AF024 -:10EB0C0033FB0028E8D02248017E012937D0007E53 -:10EB1C00042834D01F48204928301BF095F82EE0EB -:10EB2C00DBF848000022334617F008FFDBF84C00F6 -:10EB3C000022334617F002FF1848002F18BF00F5CB -:10EB4C00803018F0AFFE85B1DBF848001AF0EFFE0C -:10EB5C00DBF84C001AF0EBFE20690E49086291F8C4 -:10EB6C00240040F0010081F82400B8F1000F06D019 -:10EB7C00DBF83810504601222B460AF0F5FA8324B4 -:10EB8C0048461AF081FF2046BDE8F88F302100205E -:10EB9C00D01E002070200020020000400100010463 -:10EBAC002DE9F0410546880058BFBDE8F0810020F2 -:10EBBC00002410F09FFA3D493D483E4FCC6108605F -:10EBCC0040F60A008846B887FC8797F8480000F0A2 -:10EBDC00F00087F848003C6497F8490000F0F0001A -:10EBEC00013087F84900284607F050FEAC68012038 -:10EBFC0021460E46496849B10A88A2F60302072A43 -:10EC0C00F7D800FA02F212F0830FF2D0707B00F00A -:10EC1C00F000707307F13C0070602748806B28B1DE -:10EC2C00C0680088A0F6030002281AD3284630F8E2 -:10EC3C00381FB1B10021E9636987386495F8440045 -:10EC4C0095F8451000F0F00085F8440001F0F00054 -:10EC5C00013085F8450097F8490000F0F00087F87E -:10EC6C00490019F0EFFF1548F86197F8250030B10D -:10EC7C0017F050FE0028FBD012F042FB0BE00120F5 -:10EC8C001AF0FEFC012806D0707B00F0F000013079 -:10EC9C0070730B48F86100202146C8F81C00C8F8B6 -:10ECAC0000400120BDE8F04118F0CCBE001004403B -:10ECBC0001010E04D01E0020302100202D37000051 -:10ECCC00850802002DE9F04788B0434D0A460446FA -:10ECDC001046A98C14F0A8FC40B1417831B9072139 -:10ECEC0041703E490978013149080170A06A10222F -:10ECFC004778F90658BF082217F08F0F13D1BB06BF -:10ED0C0048BF0832237F93420DD190F8029090F8BF -:10ED1C000780B0F805A0B0F80360002909D407F00B -:10ED2C00700708200DE0D32008B0BDE8F04707F0CD -:10ED3C00EABF00F1080106A81AF01BFF07F06007F4 -:10ED4C001020B90606D5A16A014404A81AF011FFD7 -:10ED5C0007F05007B6B24946304615F051FD204930 -:10ED6C00097888421ED21F4900EB800001EB40005D -:10ED7C0010F8061F41452CD980F80080E88A86429D -:10ED8C0013D0A1891FFA8AF401223B462046FDF7D5 -:10ED9C009BFEF0B904A806A90297CDE900103046F5 -:10EDAC00214612E0E88A864207D1A1891FFA8AF02F -:10EDBC0001223B46FDF788FE0BE004A806A902974A -:10EDCC00CDE900101FFA8AF1304642464B4602F05C -:10EDDC0093FF08B0BDE8F087407B0020D1BC020057 -:10EDEC00D9BC0200D07E00202DE9F84F0746087AE6 -:10EDFC000C4640F00201032917D10025B7B1FF2FB3 -:10EE0C0014D09A4616460AB903280ED00FF03AFAD7 -:10EE1C00204611F021F88146207A4FF6FE71B0F1B0 -:10EE2C00010B18BFB346894503D100252846BDE820 -:10EE3C00F88F0138DDF82880314EB0FA80F04409A3 -:10EE4C002E4801780020814230D03278BA4208D165 -:10EE5C007278A24205D17288914502D132799345DC -:10EE6C0002D00E360130EEE706B32649C7B235465E -:10EE7C00B1F80090BAF1000FD8D0B8F8004028468D -:10EE8C00214619F0F5F960B92846214618F060FAC8 -:10EE9C0030B1022039464A46334617F08BFA00E06F -:10EEAC00002508F10208AAF1010AE3E70DF10300BD -:10EEBC0017F0F4F805460028B8D0134885F804B0CC -:10EECC00A5F802906C702F7041460078504538BF01 -:10EEDC0082464FEA4A0285F805A0A81D1AF052F99D -:10EEEC009DF80310064AC1EBC10002EB4003054834 -:10EEFC000288022017F05EFA98E700BFE2BC02001D -:10EF0C0018870020C2B40200D3BC02002DE9F843DC -:10EF1C00804600683B4BD8E9012118603A480260F2 -:10EF2C003A4820221AF0E6FED8F80C003849DFF8EF -:10EF3C00E89090E8FC00FCC1D8F80C00354990E84A -:10EF4C00FC00FCC1D8F81000494690E8FC00FCC15C -:10EF5C00324D402299F80C00D8F8141040F0800083 -:10EF6C0089F80C0028461AF0C5FEE87BD8F8181072 -:10EF7C00202240F0A500E873294D28461AF0BAFE6D -:10EF8C0040F20540697BAA7CEB7DC5F80490288291 -:10EF9C0003202875287B40F08000287301F0F000D6 -:10EFAC0020490230687302F0E0000A460130A87470 -:10EFBC0003F0F0000130E875D8F81C0090E8F80078 -:10EFCC00F8C2087BCB7B4A7B40F08000087303F0CF -:10EFDC0070008430C87302F0F000013048734FF4B5 -:10EFEC0058600861D8F820000F4908600F48C068C5 -:10EFFC004069007808B111F00FFBBDE8F84315F03B -:10F00C00D3BD00BF6488002068880020C083002026 -:10F01C007885002090850020A8850020E87F0020BE -:10F02C00A083002030860020608800200C01002086 -:10F03C002DE9F04387B0DFF8FC8081462025EFF303 -:10F04C00118085F31188D8F830501DB180F31188E8 -:10F05C0000256AE0C8F83090374F80F31188002003 -:10F06C00C9F80C104FF48031C9F81C20C9E9120002 -:10F07C00C9E90801002B18BF1F46D7E90116C9F8CA -:10F08C001810397B012905D1C9E91060C9F8146041 -:10F09C0030460DE0294A002031460023002519F0A6 -:10F0AC0011FFC9E910012649C9F814008E423CD859 -:10F0BC000021DFF890E0C9E9160197F800C0C9F803 -:10F0CC005410BCF1020F08BF0146C9F8501001AB37 -:10F0DC009EE8F5001946BCF1000FF5C108F11C00C3 -:10F0EC001A4ACDF808900090174808BF0246142120 -:10F0FC0009F1280018F0F2F905462020EFF31181F0 -:10F10C0080F3118881F3118899F8100010B94846E2 -:10F11C0012F056FC35B108F12800494619F06CF98B -:10F12C004D4602E00025C8F83050284607B0BDE82F -:10F13C00F08300BFA01F002084B9020040420F00E2 -:10F14C003F420F0060BA0200E9360200D192020081 -:10F15C002DE9FC47434FDFF810810DF1070A4FF002 -:10F16C00000918F0BFFB002800F0798050460121FF -:10F17C0014F016FD38780528F3D8DFE800F0030901 -:10F18C000F1928469DF80700FE28EAD1032462E0F7 -:10F19C00B8689DF80710022441705CE0B8689DF8CF -:10F1AC000710042481707878002808BF052452E0E9 -:10F1BC009DF8070088F800907870033017F04EFF28 -:10F1CC000028B86049D079780124017043E098F8A0 -:10F1DC000000411C88F80010B96808449DF807101D -:10F1EC00C17018F07FFB054698F8000079780A1A70 -:10F1FC00B9680844E9B203308A421ADA91B214F0C1 -:10F20C00CFFC787888F800001FE07878BD689DF80E -:10F21C0007400330C6B22846314619F019FBA0420C -:10F22C0015D17B68B3B1304629460022002498479B -:10F23C0011E014F0B5FC98F800007978284488F8AF -:10F24C000000C0B288427FF48CAF052403E028464E -:10F25C0018F002FE00243C7083E700203870BDE8F3 -:10F26C00FC8700BFF425002092880020F8B50446E6 -:10F27C004048C16819B12046BDE8F84008473E4EE9 -:10F28C003068074658B1054660882988814203D109 -:10F29C002079A978814216D0A8692F46F2E71C2064 -:10F2AC001AF0BCFC002863D01C21054619F006FEA0 -:10F2BC00FF20E8724FF6FE7028813068002818BFD6 -:10F2CC0007F1180635602079217A627A237BA870C1 -:10F2DC0060880129AA7169712B75288005F10C00D1 -:10F2EC0007BF4FF0FF31C0E9001104F10D011AF016 -:10F2FC0040FC2249A07A0978884239D961790129E0 -:10F30C0003D01AF029FA98B3A07AA97A884202D9C4 -:10F31C00E27A102A05D3884206D1E97AE27A8A4247 -:10F32C0002D20022012101E001220021144B1B78A2 -:10F33C00022B01D2A31D01E005D1E31D1B7813B1F3 -:10F34C0072B9228808E00F4A538B2288D31AB3FA79 -:10F35C0083F35B09194203D0A872E07A2A81E87220 -:10F36C00E07908B101202871A07908B10120E8707A -:10F37C00F8BD00BF3C830020E487002093270020C9 -:10F38C0018260020407B00201EF0040F14BFEFF362 -:10F39C00098169468869A1F1480214BF82F3098882 -:10F3AC00954621ED100BF1EE102A41F8082DEFF3E4 -:10F3BC00118102B400B5DFF8D8E0F047374A126883 -:10F3CC00116801EA000010605DF804EB1EF0080FF4 -:10F3DC0009D101BC80F311885DF8080BE1EE100A2D -:10F3EC00BDEC100B704704BC1EF0040F14BFEFF300 -:10F3FC0009816946A1F1200114BF81F309888D466A -:10F40C004A604FF08070C86125488861234B1B68A7 -:10F41C001868086040F201101860704702B401B41B -:10F42C00EFF3148100291CBF002282F3148802B46C -:10F43C0002B4DFF860E0F04701BC01BC00281CBF3F -:10F44C00022181F3148801BCDFF84CE0F0470F482F -:10F45C004FF08051016001BC80F3118800BF00BFE8 -:10F46C00FFF7FEBF1EF0040F14BFEFF309816946CE -:10F47C0001F1200151F8080BE1EE100AB1EC100B70 -:10F48C0014BF81F309888D46704700BF04ED00E07E -:10F49C00DDCB01008B9B0200919B0200B8BC0200EB -:10F4AC0028F400002DE9FE4FD0E90085994614465A -:10F4BC000F46834613B10020C9F8000074B11AF04E -:10F4CC0037F8064698F8070058B198F8E80070B17C -:10F4DC0030461AF0D9FA6FF008056DE06FF00905A7 -:10F4EC006AE030461AF0D0FA6FF00E0564E00020A6 -:10F4FC000121C8E93B74C8F8F440C8F8FC0088F84E -:10F50C00E810C8F83C0088F80D0088F80B00284675 -:10F51C0001951AF0FDF830461AF0B6FA08F1D0064B -:10F52C000DF1080A1AF004F804463046514616F05C -:10F53C00F0FA0546D8F8F400D8F8FC10854288BFDC -:10F54C000546029839442A461AF0D4FB304629461F -:10F55C0014F022FCD8F8F400D8F8FC10401BC8F8C2 -:10F56C00F4004819C8F8FC0020461AF08DFA012D59 -:10F57C0003DBD8F8F4000028D4D119F0D9FF0446E5 -:10F58C00D8F8FC0050B101981AF0C2F8584605F0B2 -:10F59C003DFBD8F8FC0008B1002502E06FF00F0528 -:10F5AC000020B9F1000F18BFC9F80000002088F83E -:10F5BC00E80020461AF068FA2846BDE8FE8F70472E -:10F5CC00F8B504460020A5782075C4E9030045F081 -:10F5DC00020000F0030002280CD115F00C0005F01D -:10F5EC00030218BF042809D1022A05D1E90601D467 -:10F5FC0002210FE0012619E0022106E00C2803D0BD -:10F60C000828F1D0012100E00321022A02D1EA06E8 -:10F61C000E460BD448B10E1D0C2807D8012202FA55 -:10F62C0000F041F21012104200D04E1D28060AD5EF -:10F63C00E078800706D0A8074FF0030058BF0220DF -:10F64C00064400E00136278819F0A8FF87420BD04A -:10F65C00A80609D51F48416920468847206918B972 -:10F66C00A07800F0DF00A070207D00B1F8BD6179BA -:10F67C005020751C8DF8000020798DF8021021693E -:10F68C0028448DF8010029B10A7F497F10440844B1 -:10F69C008DF80100684613F0C9FBA0B1012180F878 -:10F6AC0048504176218841806188018721792269FF -:10F6BC0080F8421001692944416412B1127F11444F -:10F6CC004164E060F8BD20461AF0E1F81020207586 -:10F6DC00F8BD00BF502400202DE9FF413B4E96F8A9 -:10F6EC00420100286AD1012086F8420119F0D4FFAA -:10F6FC00374F86F87001374D7868C6F86C01387B47 -:10F70C0086F84101A86810F4402F13D1386988B1EC -:10F71C0028686421C0F3066000FB01F41AF04EFA6D -:10F72C00B4FBF0F22C4906F19400002315F0E8FC30 -:10F73C0019F038FD01AC20461AF0B3F82749A84659 -:10F74C00002506F10C00002219F0FFFD20461AF0EE -:10F75C00A8F8234906F15000082219F0F6FD214AB9 -:10F76C0006F1D8003221002313F034FC1E4C1F4A42 -:10F77C0006F1F4002C2100232560454613F02AFCE9 -:10F78C00D8F80800797BC0F3815021B1032804BF5D -:10F79C00012186F83911032803D040F00200022819 -:10F7AC0010D1206840F040002060022015F0F8FDD8 -:10F7BC006868400702D4002015F0F2FD002004B068 -:10F7CC00BDE8F08114F094FAF2E700BFD81B0020DA -:10F7DC0090BA0200AC4F0050A79402000F7B0100BE -:10F7EC003D28020071CB01009022084035A5000095 -:10F7FC002DE9F8431D46434BDDF8208043F6060601 -:10F80C001C68038814F0007411D0B34227D0B3F5F0 -:10F81C00C15F33D040F60206B3423ED100F1120371 -:10F82C000B604169116081692960C1692EE0B342A6 -:10F83C000AD0B3F5C15F03D040F60206B34203D140 -:10F84C0000F11203143002E000F11A031C300B60BB -:10F85C000068106000202860C8F800004BE000F140 -:10F86C001A034FF000090B60C1691160016A29602D -:10F87C00416AC8F8001000F118011CE000F11203F5 -:10F88C000B6041691160416A2960816AC8F80010F7 -:10F89C0000F1100190F80F900DE000F11A030B60CD -:10F8AC00C1691160816A2960C16AC8F8001000F151 -:10F8BC00180190F82490286868B10E8819F068FD3A -:10F8CC00042808D8074606F0070148460EF018FF32 -:10F8DC00296841F82700D8F8000060B119F058FDEC -:10F8EC00042808D805464846FF210EF009FFD8F831 -:10F8FC00001041F82500002C18BF01242046BDE85B -:10F90C00F88300BF941200507CB50446007A02289C -:10F91C0003D3208814F028F910B1022630467CBDA0 -:10F92C00207A032806D10DF10201204615F058FB70 -:10F93C0018B9F2E72088ADF80200608A44301AF05A -:10F94C006DF9002864D04421054619F0B7FAA07A65 -:10F95C00694617F071FE9DF800009DF8011085F8BE -:10F96C003A0085F839102846012117F0BBFE05F145 -:10F97C0010002146242219F005FC628A616905F108 -:10F98C0044002864AA8719F0FDFBBDF80200A8808A -:10F99C0020480178E971013101701AF011F906461D -:10F9AC001AF00CF970434FF47A710026B0FBF1F0A9 -:10F9BC00FF218DF80460288095F8390001FA00F0D9 -:10F9CC00217E85F8370085F83600207A8DF8060000 -:10F9DC0001F001008DF8050001A819F0BFF9298D7F -:10F9EC00023885F83400C0B241F0080183B2298591 -:10F9FC00A98F8AB2B2FBF3F202FB1010000418BFFD -:10FA0C0001322A720448012100780EF01BFB85E7B5 -:10FA1C00102683E7948800203C2600202DE9F04135 -:10FA2C008AB0DFF8E080D8F8000070B9364C206856 -:10FA3C0028B936488068D0F84C0580472068344C8B -:10FA4C00016A204688473348E06133480068016901 -:10FA5C0031B12E488068D0F8D40090F85300884714 -:10FA6C002A4DA868D0F8D40090F9420010F086FB1B -:10FA7C00411C03D0294940EAE0704882274C002001 -:10FA8C0060606080207B617B40F08000207301F01F -:10FA9C00F00001306073A868D0F8C403804730B917 -:10FAAC001F4810210170E868142140680170D8F8D3 -:10FABC000000C0B10020002714F02EFB124E30685D -:10FACC00416E02AD2846884731680597D8F800008A -:10FADC002A4600230E6D0821CDE900172146B047B8 -:10FAEC00104804600AE010480C4A094B01680648AB -:10FAFC00006804680D48A047C8F800000AB0BDE8CB -:10FB0C00F08100BFD8260020308800200C01002096 -:10FB1C00E083002054F100805C880020C08300202A -:10FB2C00B088002020250020648800204873002025 -:10FB3C002DE9F04788B0DFF8FCA0D0F804803E4EE9 -:10FB4C007F2400217F23DAF8280020EA0800CAF875 -:10FB5C0028001B2915D020FA01F2D2070FD000275C -:10FB6C00324612682AB19578A94208BF013718327B -:10FB7C00F7E7DAB2FDB295423CBFCCB23B4601315D -:10FB8C00E7E7B8F1000F15D0CAF8288001AC1821AE -:10FB9C00201D19F093F90120CDF804808DF8080090 -:10FBAC009AF82E008DF8090020460EF0D3FF08B00D -:10FBBC00BDE8F087204EDFF884804FF6FF793046A1 -:10FBCC000768BFB13888BAF8241088420FD1B978C9 -:10FBDC00A1420CD1B8F8001049451DD11AF004F817 -:10FBEC00AAF82400398881423046E9D102E007F1B5 -:10FBFC001800E5E78AF81840FEF7ACFE0028D6D0CE -:10FC0C0000208AF826000E4801680029CFD0C420B5 -:10FC1C0008B0BDE8F047084700208AF826000848DD -:10FC2C00016809B1C4208847002008B0BDE8F0473E -:10FC3C0016F01EBA407B0020E487002080270020AD -:10FC4C00002500202DE9F04389B03F4A127882420A -:10FC5C0009D93C4A3D4F002952F8306018BF0F4675 -:10FC6C0096F8521021B10025284609B0BDE8F08362 -:10FC7C0002EBC009D9F804406078022826D1022092 -:10FC8C0086F8520012F07EF80DF10C08404619F07F -:10FC9C0081FA3868002541468DF8145006958DF888 -:10FCAC000C500490207812F0A3FD00287060DBD07B -:10FCBC0019F02CFFF87988B1B87939684843642178 -:10FCCC00B0FBF1F1706819F01EFF07E000F0F2FCD8 -:10FCDC00012086F85200207886F854006D4628469C -:10FCEC0019F0DFFD002000212A46CDF808908DF890 -:10FCFC0000000190164813F031F9B06070B138680B -:10FD0C003060B97986F85310F87902280CD00128A4 -:10FD1C0012D0A0B9484613F06AF810E070680028B9 -:10FD2C00A1D019F0EDFE9EE7B8884FF6FF7241089E -:10FD3C0048460CF0EBFB02E0484613F0A5FE4D469E -:10FD4C0092E700BF24BB02008FBA02002CBC020059 -:10FD5C00FD2A02002DE9F04F85B0044600880DF114 -:10FD6C00060116F063FE0546182019F057FF4FF6F2 -:10FD7C00FE7970B11821064619F0A0F86088182198 -:10FD8C00324619F03DFD09F101006080304619F052 -:10FD9C0043FF0020A4F80090002D20715DD1DFF806 -:10FDAC00C0A0BDF80640DAF80000B8B3142019F072 -:10FDBC0035FF98B3834604AB4C2000210222002768 -:10FDCC0019F062F8009404EB440402AE0BEB44000F -:10FDDC004FEA4408851C122F17D0B84505D1DAF824 -:10FDEC00000000EB440128460AE0B81C062233460A -:10FDFC0081B24C2019F048F80BEB07003146023069 -:10FE0C00062219F0BFF90637E5E74C2014215A46B3 -:10FE1C0019F0F6FC584619F0FFFE009C04AB4C2080 -:10FE2C000021022219F030F8B8B9DAF8000050B10C -:10FE3C0004EB440130F81100484504D1BDF8100022 -:10FE4C0030B1013802E0BDF810000130ADF81000FF -:10FE5C0004AA4C20022119F0D3FC05B0BDE8F08FA8 -:10FE6C00E0260020F8B5067B07460D46304618F014 -:10FE7C00FBFC18B104464089002726E07A893868D3 -:10FE8C00314616F0FCFF0026002869D00446068196 -:10FE9C0017F8100F207478886082384619F076F8BD -:10FEAC006061388961892083B87AA07621F460700A -:10FEBC004907608105D42B490978013140EAC1100A -:10FECC0001E040F0800001276081C0F3C21195B1C0 -:10FEDC00022262732268D289520702D5224A128A00 -:10FEEC00228169B36FF07F0220F4607002EBC111C4 -:10FEFC000843608124E039B1810607D4C1060BD4D4 -:10FF0C0040070FD4012013E000261AE019F01EFD63 -:10FF1C0000F07F005F300BE019F018FD00F00F00CF -:10FF2C000A3005E01148058819F010FD2840023010 -:10FF3C0020810F4804216173202100780EF082F893 -:10FF4C0001266FB12289617B20460CF0C7F938B1CC -:10FF5C00606908B119F060FE204619F05DFE0026BC -:10FF6C003046F8BDC5270020407B0020BEBC0200F7 -:10FF7C00988800202DE9F0418AB03E4E0546306845 -:10FF8C0020B13D490978A94209D82DE013F094FE1F -:10FF9C003068002448B338490978A94225D94FF074 -:10FFAC00FF3119F0E7FC354905EB450001EB800406 -:10FFBC0067683878A8B9A568A9682A6848424B1EB2 -:10FFCC001A42B8600DD16A688A420AD31040824244 -:10FFDC0007D1686910B10068786029E0298B042981 -:10FFEC0007D3306819F02CFE002420460AB0BDE877 -:04FFFC00F08106EB9F -:020000021000EC -:1000000081000069A8B90DF10408404619F062FBAF -:10001000002041468DF810008DF80400E869059035 -:10002000287E12F06BFC0028E1D0298B06EB8102C0 -:100030001061786031440A7B01320A73298CC6E969 -:100040000101204616F0ECFF01203870AB20318909 -:100050008DF82700204618F04EFF0DF127000121F2 -:100060000FF0B2FD31890546204618F04DFF15B955 -:1000700020460EF0FFFD306819F0E8FDBBE700BF39 -:100080000C240020F3BA0200A0B902002DE9F84FB9 -:100090003C4C3D4E3D4D42F62A294FF0010A4FF0AF -:1000A000030B00274FF00508D4F83C01062833D88D -:1000B000DFE800F00433183B203D4B000F20F060D8 -:1000C000C6F8109013F09AF845F804AC55F8040CF3 -:1000D0008007FBD5C6F81CA094F8390190B1012027 -:1000E000EF6210E02F60C4F83CB128688007FCD4B0 -:1000F0000320DBE72F60C4F83C8128688007FCD42C -:100100000520D3E70320C6F800B0C4F83C012F60F7 -:1001100029688907FCD4C9E7FEE70126022084F894 -:100120003A6112F0ABFB2E6009E0022000E00320F0 -:1001300084F83A01002012F0A1FB0120286004F1AC -:100140005000BDE8F84F19F049BD002045F8040CF7 -:10015000286055F8040C8007FBD428688007FCD47D -:100160000B480025012105600A4801600D2005F0BB -:100170006DFB022014F0FCFAC4F83C5184F83B51AA -:10018000BDE8F88FD81B002000400C4058600C40A0 -:100190003C500C4004800C402DE9FE4FDFF8F4B0D9 -:1001A00001219BF80C4001AA204619F0C6F86A46C6 -:1001B0002046022119F0C1F8DFF8DC909BF80EE030 -:1001C0009BF80D00BDF800C099F800100EF1010376 -:1001D0000746B3FBF1F404FB11359DF80240ADB2C4 -:1001E000FEB2B5420FD0A642634618BF102372007C -:1001F00052FA87F20BEB82029383721CB2FBF1F38B -:1002000003FB1127ECE7DFF894A0002401270DF190 -:10021000080857FA8EF2C9B2C5B2B2FBF1F303FB7C -:100220001121A94232D0690051FA80F00BEB800213 -:1002300032F81C0F102806D1284607F0A1FA8AF8D8 -:100240000000013417E028460421022313F01EFDAC -:100250008AF80000284600214246042318F060FF77 -:100260009DF808007C2802D0FE2804D10DE0284625 -:10027000782114F0FBF999F80010681C9BF80EE047 -:10028000B0FBF1F202FB1100C3E7FEE7E0B2BDE80C -:10029000FE8F00BFA080002097880020A0230020B0 -:1002A0002DE9FE4F05460F465818AE687168884222 -:1002B00002D96FF0030564E0DFF8E8800C9C4FF092 -:1002C000FF3199469246D8F8000019F059FBE00733 -:1002D00011D1A0071ED5306851464A463844CAB1EC -:1002E00011F8013B10F8014B013A1C40A342F6D033 -:1002F0006FF0060541E0D8E90101CB4301EA0902AC -:1003000013EA090F18BF02442846394009F0E8FEF5 -:10031000054690BB306802970196074412F00EFC28 -:10032000CB4655460090BBF1000F16D05E46BBF1A0 -:10033000080F28BF082619F001F9804628463946DB -:10034000324617F071FD0446404619F0A3FB2CB964 -:1003500037443544ABEB060BE5E70024009817F073 -:10036000B1F8DFF84080DDE901210C9814B14FF0BD -:10037000FF3502E0400707D40025D8F8000019F047 -:1003800065FC2846BDE8FE8F10680844B9F1000FEF -:10039000F2D010F8011B1AF8012BA9F101098A42C9 -:1003A000F4D0E4E7DC250020B0B50C46880722D461 -:1003B000600758BFB0BD354D0120A870042014F06F -:1003C000F5FF33480068006B8047E8602D48806B7C -:1003D000F0B16968046961B1A1420AD094F82800BB -:1003E000400704D5636A2046042100229847012073 -:1003F00060766C600DE0FCF763FD2248006CE0B3B2 -:10040000214844F002012830BDE8B04019F022BC78 -:100410006C6860681F4900780860022014F0C6FF0D -:10042000102005F085FC012028761B48807810B943 -:100430000D2005F07DFC6868416818488A680AB993 -:10044000C96821B100218160154940F8141C154983 -:1004500007220A6001680021016042684160124978 -:10046000124AE9610168114301601A2019F0BCFBCE -:100470001920BDE8B04019F0B7BBBDE8B0400DF0A1 -:10048000B5B800BF3021002070200020D01E002011 -:100490008C010010D0210840ACBB020014100440B5 -:1004A0005100070600000460ADEB00000240004070 -:1004B0002DE9F84F3A48DFF8EC90DFF8ECB0DFF8C0 -:1004C000EC8000264FF0060A00210078C700B742F2 -:1004D00042D009EB0605A878E0B30138A870687926 -:1004E00018F0C8F9A8B30446A87800B3A87948B3AF -:1004F000287970B3E9780139E970090629D19BF8A8 -:10050000011001382871E970617B032921D10006AF -:100510001BD00420607319F01FFA00F00F00202197 -:100520000130208198F800000DF092FD11E0607B11 -:1005300084F80DA002280CD02068F021407B11F037 -:1005400091F906E0607B032803D12846214610F08C -:1005500001FF01210836BAE798F8000001290BD104 -:10056000402112F02DFEC0B998F80000402164220D -:10057000BDE8F84F19F0BBBA40210EF039FA0C482B -:100580000178012909D1002101700A48007806F09C -:10059000B1FCBDE8F84F12F06DBEBDE8F88F00BFAA -:1005A000D2BC020042760020407B002098880020C8 -:1005B000DA270020DB27002070B58AB04FF4806175 -:1005C000041D4588ADF826108189807B0894ADF81C -:1005D00024500328ADF81C1034D0022806D0B0BB3C -:1005E00040F601000026ADF826005AE032480078B7 -:1005F00001285FD10DF11B0101AA204608F0DAFFA6 -:1006000004469DF81B00012854D19DF814000228CF -:1006100050D101AD1421284618F056FC274904EBAF -:10062000440000222B4641F8202001EB80002146A7 -:1006300042604272FF2014228DF81400042015F04D -:10064000BFFE37E0102000268DF8270029E00DF1CD -:100650001B0101AA204608F0ADFF01469DF81B00D2 -:1006600001281DD19DF81400022819D1134A002336 -:1006700001EB4100CDE9013342F8203002EB80006C -:1006800014224360FF208DF814009DF816000130FD -:1006900000F00F008DF8160001AB042015F090FE5D -:1006A000012607A801F050FE26B118B928462146B8 -:1006B00002F044FA0AB070BDBB270020804300203E -:1006C0002DE9F047A4B018F039FF34490A78012A1F -:1006D00004D124B0BDE8F04719F0DCB94FF00109AE -:1006E00081F8009019F0D6F9FEF7FCFF082005F01C -:1006F0001FFB21AC204618F0BBFC4FF0FF30294A0D -:10070000102123462290264812F06AFC2648284DE4 -:1007100000260DF1040A0478244890F8008047462A -:10072000A74212D8286850F8271021F0FF004AF895 -:100730002700880707D4F8B201F0010118F088FCFF -:1007400009FA07F006430137EAE71A4806601A4833 -:10075000C16801F44001B1F5800F09D10068000EB5 -:1007600018BF01205AF8201041F007014AF8201064 -:100770001248A4EB080204230AEB880103EB82026F -:1007800040EA880019F0BCFA0D482022016862F3A3 -:100790000D21016024B0BDE8F08700BF962700203E -:1007A000608400203D1C02009FB6020045B6020096 -:1007B00014BB0200D0200240A84F00500010084097 -:1007C00000300940FEB5D0E9005401A818F030FC13 -:1007D00095F834003649374A384E085C95F835109C -:1007E000515C354A084395F83610515C2A6B40EA53 -:1007F0000103316820684F680299B847206840F2C9 -:10080000F272E1692E4B2F4F426494F854209A5CA7 -:1008100094F85530FB5C1A430129426311D101461B -:10082000D4E90A2351F8307FFF2A27F4004718BF84 -:1008300007F50047FF2B0F6009D00A6842F4804299 -:1008400008E0014651F8302F22F400420A600A689D -:1008500022F480420A60C16A41F01001C162016B5A -:1008600041F001010163E16B09B3A16BF9B1012111 -:1008700018F090F8D5F85801E16B40680068C16243 -:10088000C0F8041591FAA1F17268B1FA81F15368C8 -:10089000022298477068A16B02224368D5F858017C -:1008A00091FAA1F1B1FA81F1406800689847FEBD64 -:1008B000A8BC0200C8BC02009AB60200D001001019 -:1008C00091BC02008CBC02002DE9F04186B018F00A -:1008D00079FF0446002718F075FF10B180690137D1 -:1008E000FBE7DFF8CC8098F80000012831D818F039 -:1008F00069FF304EB18C28B102888A4229D08069C4 -:100900000028F8D11C2019F08FF910B30546B08CDF -:100910002880307EA87018F041FE6871264806F1E4 -:1009200039010078A87105F10C0019F028F90DF1D2 -:100930001701412015F076FB20489DF81710AC6197 -:100940002C460088002908BF6FF00100013728817C -:1009500000E000251A48FBB200210278934201D240 -:1009600000260BE0BE1A0020C7B2974202D2A4694B -:100970000130F9E7F0B2052828BF05261148F6B284 -:10098000CDE902411049CDE900260022007803F0AC -:100990001DFD98F8000008B1012803D115B12846C3 -:1009A00019F040F916F064FF06B0BDE8F08100BF11 -:1009B00018260020407B0020D827002070870020C8 -:1009C000C3880020C288002084870020F8B5044630 -:1009D00018F036FB07464568204618F0CBF898B16A -:1009E000D7E9014618F0AAFD0546D4F8C000C8B101 -:1009F00004210174384606F00DFCD4F8C800C0B1DB -:100A0000416949B10846FBE718F098FD0446D5F85E -:100A1000C000B0B310303BE0D4F8C010416101F128 -:100A200014000BE03068416821F002014160284663 -:100A300031E0D4F8C000C4F8C800143001680027C1 -:100A40000760C4E93477C4E93677C4F8C01031B31D -:100A500020463146FBF7D0F8D4F8C000C4F8E07067 -:100A60000068B0F5806F03D920463146FBF7C4F823 -:100A700094F8FE0010BB3068416841F0020141600B -:100A80001CE095F8FB00002114F058FB05F1FC0078 -:100A9000012101702046BDE8F84018F0FBBF94F832 -:100AA000FB000021C4F8C47014F048FB012084F856 -:100AB000FC003068416A21F003014162284618F0C9 -:100AC000E9FF04F13000BDE8F84019F0C5B87047FF -:100AD00070B5C1680C6991F8381041F002032246E4 -:100AE00003F0030302F8011B022B3BD111F00C03AE -:100AF00001F0030518BF042B2DD1022D01D1CE0624 -:100B000030D4C26892F83B2062700234022D01D1C9 -:100B1000CA0626D4C26892F83E202270C26892F8B3 -:100B20003F206270C26892F84020A270C26892F8BA -:100B30004120E2704BB1221D0C2B13D8012505FA80 -:100B400003F341F210152B420CD0C26892F83A2000 -:100B50002271621D06E00C2B2ED0082BCDD014463E -:100B6000D4E72246C46801F0020394F8395005F036 -:100B700003051D4309D1658D2D0606D4134E357826 -:100B800084F849506C1C347001E094F8495009060F -:100B9000157010D5C16891F839105170C16891F87D -:100BA0003940A40707D091F84B1091701BB1C06871 -:100BB00090F84C00D07070BDC26892F83C20627012 -:100BC000C26892F83D20A27003349FE79488002009 -:100BD0002DE9F8430546007F04282FD1A86A4678FE -:100BE000B0F802900E2E38D80C460127DFE806F048 -:100BF00008080841414141414141412A2A38410008 -:100C000031480078012833D83048807B80072FD5C1 -:100C10001FFA89F80021404609F022F900283FD048 -:100C2000817911F0180F3BD0AA894388698900881F -:100C30000027009200220FF0ECF81AE0D32006F013 -:100C400068F829E020480078012811D81F48807BE7 -:100C500080070DD519F008F80AE00127002408E004 -:100C600019480078012803D81848807B80071DD4D4 -:100C7000012768891FFA89F2314618F0C7FF688991 -:100C800012F078FF40B1A87C022805D327B10F48A5 -:100C9000A989C08A814200D100242046BDE8F8839A -:100CA00040460121012716F085F9E2E71FFA89F88D -:100CB000404617F0AFFF40460CF05AFEB0F1C507B2 -:100CC00018BF0127D5E700BF18260020407B002071 -:100CD0002DE9FE4F4FF4804018F00AFAA0B1354CD0 -:100CE00035496068D1F8132009786FF39F5201F0FD -:100CF0000401806842EA417101AA03F047F8606884 -:100D00008168012016F0A4FE2E482C4F2C4D44F291 -:100D1000020B00244FF0000A00F14009BAF1020F63 -:100D20003CD055F82A80D8F80000A0B3D8F80000CD -:100D3000806918F0DDF90646D8F800000023324635 -:100D400015F002FE16F00A0F1ED0D8F800008069D8 -:100D5000B9686BEA00000840B860D8F80000C069C4 -:100D6000396821EA000038601020D8F8001016F029 -:100D70006FFED8F80010484616F00AF9002044F03B -:100D80000204C8F8000006E02EB1D8F800000D49B2 -:100D900044F4804408650AF1010ABFE724B10A4817 -:100DA0002146283018F056FF06F0FCFEBDE8FE4F45 -:100DB000F7F756BBD01E0020850300210C1004401D -:100DC00014BC020030210020702000202DE9FC47D7 -:100DD0003A4D0446286810B194B1BDE8FC87122052 -:100DE00018F022FF00282860F7D04FF6FE7200218D -:100DF000531C1229F0D04618425206317380F8E78E -:100E000001AB4C200021022218F044F800284CD1FC -:100E1000BDF80400002848D0032846D8182018F050 -:100E200003FFDFF89C90044600264FF6FE784FF053 -:100E3000020A0027032F34D028680622831907EB03 -:100E400047000AEB400081B24C2018F023F828BB81 -:100E50002868815B414518BF002C1FD03044002218 -:100E6000182341880620009415F094FA2868D4E9E4 -:100E70000423304402F2E9324188226101EB41004F -:100E800049F8202009EB8000182243600620234601 -:100E900015F096FA2046182118F016F80636013794 -:100EA000C8E714B1204618F0BDFE064B71200021A2 -:100EB000082217F0EFFFBDE8FC8700BFE026002006 -:100EC00018830020AC260020F8B53948394D01219F -:100ED000394E0768E868C0680170002002F002011E -:100EE000F07003F0E040401817D096F90600012892 -:100EF00002DBB0790138B07196F90500012802DBF8 -:100F00007079013870712D48426803F0807082B1A9 -:100F1000D8B10020002190470CE01446D00323D420 -:100F2000A0032ED4600230D5002038710BF06CF98C -:100F30002BE050B196F90700012802DBF079013867 -:100F4000F0710120307117F069FF002038710BF04B -:100F50005BF97079F8B196F90500002823DCA868E0 -:100F6000D0F84C0580471EE01548007820B10520D8 -:100F700017F036FF13F082FD00203871F1F78CFE78 -:100F800003E00020387111F0DFF8A00648BF18F028 -:100F9000A7FE707938B900200021B070A868D0F899 -:100FA000582400209047E8680021C0680170F8BD0F -:100FB000748800200C0100201425002024B80200B1 -:100FC00090270020B0B58CB004464089ADF80000F1 -:100FD00060684178821C019206298DF8021003D0C6 -:100FE000042907D0012936D1817C13228DF8031002 -:100FF0001B2101E01A211222851801440391029558 -:1010000031D0284616F0F2FE01282CD117F0F8FD59 -:101010000146284616F049FB28BB264800780128DF -:1010200024D8684618F03EFC01281FD102980DF123 -:10103000160113F0DBFF012818D10021BDF81600BE -:1010400061721D496081097891B16168097805294B -:101050000ED101210DE00021029100F11201807EEC -:1010600003918DF81000684610F060FD0CB0B0BD23 -:10107000002100222173CDE906220892ADF8180064 -:10108000207A8DF81D108DF81C0001208DF81A00B3 -:1010900006A8FEF79BFA9DF82C000028E6D10998D7 -:1010A000227A6168406C18F073F806A811F026FAED -:1010B000DCE700BF18260020D02700202DE9F041F2 -:1010C0000E46054610463421144617F0FDFE082E44 -:1010D0004ED326702146288811F0FAFF8046688892 -:1010E00008216081A888A081A879A074E87961703E -:1010F000E074E07920B1102105F1080061706061B1 -:10110000207A28B101F1080029446070A16100E053 -:1011100008460021616284F82010617919B1295CC8 -:10112000013060706171617FF1B1421C6270295CB5 -:101130000230607084F82010AA5C914284F821206B -:1011400010D9194A4F00194E1278914288BF1827BA -:101150003A462918304618F01BF860786662384421 -:10116000607001E0002161772178C2B2914203D220 -:1011700000263046BDE8F081B8FA88F2091A55FA1F -:1011800080F05609A2792177A062002AF1D00E30B2 -:10119000A062A1F10E0020770548007B18F048F806 -:1011A000217F081A2077E4E7DBBC0200F0850020ED -:1011B000407B00202DE9F04105460026806A1C4650 -:1011C000174688461680007817F034FA40B16889CF -:1011D00012F0D0FC022811BF00266889388026460C -:1011E000A86A007801380A2846D8DFE800F0060C23 -:1011F0001116242C45383C4A5200284641463A46AE -:10120000F7F7C6FD41E028464146FDF761FD3DE0A8 -:1012100028463146FFF7DCFC37E0287F02282BD137 -:1012200026B920486989C08A814228D1304629469A -:1012300000F034FF29E0688912F09CFCE0B92846F0 -:10124000F4F758FF22E017486989C08A814213D118 -:10125000287F022810D128460CF06AFE16E02846A6 -:10126000FCF71AF812E00F486989C08A814203D15D -:1012700028460BF0BFF909E0D32005F04AFD00260F -:1012800004E0304629460FF021FF06463046BDE80F -:10129000F081054800780128F1D128460CF018FEAD -:1012A000F4E700BF407B0020BA2700202DE9F04181 -:1012B000056804464FF0FF30E86218F03FF98046B9 -:1012C00095F83000042809D13349497831B13349C0 -:1012D00003228A604A6822F003024A602E4F6B693B -:1012E0002F4E00217A68B34204D01AB979780029C8 -:1012F00018BF01210023042804D11AB17B78002BE8 -:1013000018BF012341EA0300012808BF14F0AEFD15 -:1013100095F8320030B1404618F0BCFB4FF0FF307A -:10132000BDE8F08195F83000042804D1381D294625 -:1013300015F039FD03E0381D294615F029FE01207E -:1013400085F83200404618F0A5FB0020FDF720F894 -:10135000246894F83000012812D0022813D0042801 -:10136000DCD10E4DD4E90901884211D2012018F0D8 -:101370003CFB28688007F9D00020FDF709F8F1E769 -:101380000020BDE8F081216A04F1340018F0F8FA79 -:10139000E06ABDE8F08100BF182300200880024009 -:1013A00080A9030070B586B03449002808705DD16B -:1013B000344C207830B93249097819B9082016F030 -:1013C00097FB207801284ED80020CDE90300CDE915 -:1013D000010017F025FE002845D02B4D05F13904FA -:1013E000204617F043FD18B92849204618F0C7FBDE -:1013F00005F11601532010F041FEA87B0DF11701F5 -:10140000C0F3C0008DF81700522010F037FE0820FE -:1014100085F8260003F026FA04F072FA1C480168E9 -:1014200009B9012101601B484FF4407100780CF0AC -:101430000FFE01AC204614F0F1F8204600210026F2 -:1014400015F0D8FE95F8410010B9002005F052FDC6 -:101450001148CDE90366CDE90166807B012802D001 -:10146000012014F00BFE012015F036FB0948022183 -:1014700000780CF0EDFD06B070BD00BFBB88002009 -:10148000C426002018260020407B00209E870020D4 -:101490000825002099880020CC2200202DE9F84F53 -:1014A0008A468DF8030062B13848514601234068EE -:1014B00002700DF1030048F231020DF0ADFF044659 -:1014C00060E00B9F162405201E4617FB0400C0B2E7 -:1014D00018F0AAFB002854D0814604220C980A99DF -:1014E00017FB04280024CB460BF8014F00F1190527 -:1014F0008BF801600BF104068BF803708BF8021077 -:10150000E0B2B84229D2A5F11701304618F037FBF6 -:1015100006F10800A5F10F0118F031FB15F8071CC2 -:10152000861D0134017015F8061C417015F8051C64 -:10153000817015F8042C41EA8201817015F8032CA2 -:1015400041EA0211817015F8021CC17015F8011CE6 -:10155000017129781A354171D2E70C4D5FFA88F391 -:101560000DF10300514648F23102C5F804B00DF008 -:1015700053FF0446484618F055FB054801306860A3 -:1015800000E010242046BDE8F88F00BF7C26002034 -:10159000DC7D00202DE9F04742F22C0940F2100AD0 -:1015A00042F20C0640F2B81715460C468046C4F2CB -:1015B0000909C4F2090AC4F20806C1F2000708F0DA -:1015C0004FFB44F20C00C4F2090000210160D9F87D -:1015D00000003868816927208847306B4FF6FF711B -:1015E000CFF6FE6108403063B06F20F48070B067C2 -:1015F0003868016B4FF4806088473868016B4FF49E -:10160000816088473868016B4FF4C060884742F2B8 -:101610002800C6F2080001210160C6F8804131604F -:10162000DAF80000800705D4681C08BF4FF0404579 -:10163000CAF80C50D9F80000F0698007FCD500BF4B -:10164000072010F03FFB0228FAD1B8F1000F16D1A5 -:1016500044F20004C4F20304386A816820468847D3 -:101660000428F9D0012804D1386A032142682046B1 -:101670009047D6F8180220F00300C6F81802386820 -:10168000806BBDE8F04700472DE9F04385B0064682 -:1016900000200D46049017F051FF334CDFF8C49042 -:1016A00080462168D9F80000CB6C04AA0521984730 -:1016B00001A817F0ABFE2D48019626F00106039510 -:1016C00020F00107BE420AD12B490878FE281BD022 -:1016D0002068826BD9F8000091F900100EE02448D0 -:1016E00020F0010086421BD123494878FE280BD008 -:1016F0002068826BD9F8000091F901109047812889 -:1017000002D01C4818F08DF92168D9F80000002299 -:10171000CB6A01A998470546B0F1FF3F07DC03E01B -:10172000144818F07EF9FE25124818F07AF9BE42E6 -:1017300001D1114806E00E4820F00100864202D196 -:101740000D4801300570012021680490D9F800008F -:10175000CB6C04AA05219847404618F09BF905B0C8 -:10176000BDE8F083D826002030880020B161020057 -:101770004D4B02000C010020142500202DE9FC47F0 -:1017800006680446707A00286BD0D4F80490D6F826 -:101790005801D0F80480D9F8347020460BF090FB43 -:1017A000706F20B306F14C05284618F04BFA316FE4 -:1017B000884221D2307902281ED0B06E002850D045 -:1017C00020460BF07DFB346F284618F03BFA201AB8 -:1017D000D6F868A0B46F7067284618F033FA002175 -:1017E000F1740AEB040108440190706F0CE0B06ED4 -:1017F00010B1306F0028D5D106F14C0001A914F0CA -:101800008EF901217067F17458B30021B173B0F5FE -:10181000806F84BF4FF48060706701990123014499 -:10182000013979601049B96043F6F07101EB00109D -:101830000840B9680843B860D9F83C10D9F80000EE -:1018400091FAA1F2B2FA82F203FA02F2D8F8003069 -:101850009A61D6F85821526812689162012117F0F6 -:10186000A5F8BDE8FC8700BF0180000C7CB53A4DAF -:101870000446A868D0F8B810097859B194F89820AF -:1018800004F190014AB1152217F0D8F958BF25226A -:101890009A5C09E00121217514E0252217F0CEF9A8 -:1018A00058BF25229A5C023284F86A20002284F80C -:1018B0006920042284F86B2004F1700248C948C2F0 -:1018C00009881180214611F82C2FB1F872300F2AA7 -:1018D00021F8163CB1F8743021F8113C0BD0D0F847 -:1018E0000463B4F8A8000023B0FA80F0420920464F -:1018F000B04700B17CBD214611F83C0FFF2801D153 -:10190000A06D30B1A868D0F8FC222046904700288E -:10191000F0D1A868B4F89A3094F89C1004F19002C1 -:10192000D0F87463002000902046B0470028E1D131 -:10193000A8682189D0F80021D289914205D9E520F3 -:101940006070A86800F51B7001E000F51E7001686A -:101950002046884700207CBD0C0100202DE9F0477F -:1019600088B004466FF00100A081002004F1040853 -:101970008DF8100004AD4146281D17F0D0FC284614 -:1019800009F072FE012809D1BDF81C00BDF8121043 -:10199000A0816088814222D004AD01E060880025EA -:1019A000EA46ADF8020000264FF6FE7950468DF863 -:1019B000006007F0CFFA012808BF56460746B5B1C8 -:1019C000A88901210125A081204610F0D1F8012F1E -:1019D00006D1ADF802903046022110F0C9F8012579 -:1019E000204611F0A3FA284608B0BDE8F087012F81 -:1019F00013D1BDF80C00A0810AF1040016F0F6F92D -:101A0000012817D1204609F047F905463046022142 -:101A1000ADF8029010F0ACF8E2E76088484504D1D8 -:101A2000404616F0E3F901280CD1204609F034F9BC -:101A30000546D5E7404616F0D9F90128CFD1204612 -:101A40000321CAE70025CBE72DE9F0438FB080469C -:101A5000374800240394CDE90144077814F05AFE76 -:101A60004FFA80F901ADBC4212D2E6B207200C2237 -:101A70002B4631460EF07AF940B9B9F1FF3F05DC4B -:101A8000072031460C222B4614F09AFC0134EAE779 -:101A90004FF0FF300C22CDE90200781E01AB85B279 -:101AA000072029460EF062F940B9B9F1FF3F05DC85 -:101AB00001AB072029460C2214F082FC04AD18214A -:101AC000284617F001FA822018212A4617F098FEBE -:101AD000B8F1010F08BF002804D104AA8220182100 -:101AE00017F094FE0AAD1121284617F0EDF93A20BF -:101AF00011212A4617F084FEB8F1010F08BF002813 -:101B000004D10AAA3A20112117F080FE0AAA3B202C -:101B1000112117F075FEB8F1010F08BF002804D19C -:101B20000AAA3B20112117F071FE0FB0BDE8F08327 -:101B3000D7BC0200B0B517F00FFF2C4C02210025D6 -:101B4000207040F60F70A17430492581C4E9075513 -:101B50002576A0850F202071012084F86C00E072AA -:101B600040F20510A08122480078E07121480078F9 -:101B7000607021480078A07020488078A0732048C9 -:101B8000007820826FF00100A0846083E0821D480D -:101B90000078E0741C480078207504F1390017F0D3 -:101BA000EEFF40F20F5004F16E030021022284F890 -:101BB000415084F86850A4F866001548007884F80D -:101BC0006A001448007884F869001348007884F8A3 -:101BD0006B00892017F05EF908B1A4F86E50002060 -:101BE00010F04EF8A4F87050B0BD00BF407B00204C -:101BF000B7270020CF270020C427002026870020F9 -:101C0000C3270020D1270020D2270020192600203A -:101C1000BC270020BD270020BF2700202DE9F04F62 -:101C200087B082462420994614460F4617F0FCFFE1 -:101C3000002800904DD0DDF844802421054617F09F -:101C400043F9DFF8B8B09BF80000012813D83846F4 -:101C500017F0C3FE50B1007940F00200032802BF24 -:101C60004FF4806020EA081048EA0008DDE91232EB -:101C7000C8F3802602E0DDE9123200262048ADF8E4 -:101C80001840109C0221808C2F8029722973688152 -:101C90000098ADF80A808DF80C404473C0F820A07D -:101CA00080F81F908DF81A30D2E90001CDE90401C7 -:101CB00068463146FEF7DCF8012807D19BF8001092 -:101CC00049B10020B6B1012906D013E0009817F001 -:101CD000A9FF10200EE066B1204616F0CBFD40B102 -:101CE00004460068008818F005F810B1204607F097 -:101CF000F5FE002007B0BDE8F08F00BF18260020D9 -:101D0000407B00202DE9F04F85B0894619461F46DB -:101D10001446054612F07AFD3249DDF84080097814 -:101D2000884207D2304900EB800001EB4000B0F858 -:101D300004B001E04FF6FE7B18F0100A4FF01000DF -:101D400008BF082018F02001019118BF08308DF855 -:101D5000110004A814F094FD002840D0064601208C -:101D60000094B07716F04CFF706202AC58462146E2 -:101D700013F034FE18B101203462707705E0BAF137 -:101D8000000F02D00E9CAB45F5D034694FEA192004 -:101D9000A071280A84F80590E570A77084F8018086 -:101DA000207102202070584611F0C4FF0099BAF14A -:101DB000000F0844E07101D1082005E00E9904F1FC -:101DC000080017F0DCFE1020019919B10F9920448A -:101DD00017F0D5FE3046A6F802B00CF07FFD05B036 -:101DE000BDE8F08FD9BC0200D07E002070B59EB057 -:101DF000314D0021742228780130287001AC212057 -:101E0000234617F047F82878742122468DF80400FD -:101E1000212017F0FBFC294E294C3078A178814213 -:101E200006D2002012F012F8012801D1042000E0AF -:101E30000D2015F05DFEA98C01204FF6FF72914236 -:101E400037D0E98A4FF6FE72914232D01D480078B1 -:101E5000022803D31C480078012808D101200DF185 -:101E600003018DF80300522010F008F904E04FF44C -:101E700000500121F9F750FD1448007818B130786E -:101E8000A17881420DD2012011F0E0FF012808D194 -:101E90000020297EE0700E4817F0FFFDA178013187 -:101EA00006E00120297EE070094817F0F9FD0021C5 -:101EB000A1701EB070BD00BF407B0020B92700207C -:101EC000AC22002018260020D5270020B8270020AB -:101ED0009687002070B596B004460079042805D195 -:101EE0003348007810B117F09BF810B1C22016B03B -:101EF00070BD3048016809AD284617F040FE2168E2 -:101F0000284615F064FF0028F0D020680DF102018A -:101F10000BAA07F04FFB9DF80210C2200029E6D063 -:101F20009DF83C100129E2D105AD4FF481700021EC -:101F3000102200262B4616F0ADFF032008212A466A -:101F40008DF803000DF1030001AB0DF005F9412000 -:101F5000CDE9106612968DF854608DF842004FF46A -:101F60008D70ADF8440010A8FDF730FB9DF85400CB -:101F70000028BBD11398456C0F2028702079687019 -:101F800016F03EFE09AC01460822204617F000F983 -:101F9000A81C214617F0F3FD05F10A0001A9102243 -:101FA00017F0F6F810A810F0A9FA9DF854009EE773 -:101FB00018260020DC870020F8B51446A0F198020E -:101FC000062A0AD80FF20401DFE802F00411111109 -:101FD0001A1D31003048807C2CE08B282DD08728BA -:101FE00044D0802803D12C48808C208023E0812895 -:101FF0003AD3D82838D82849084410F8810C19E079 -:1020000014F0B2F916E02148007801282CD82048B5 -:10201000204A4FF6FE730025017800208D4209D238 -:1020200032F8086B9E4218BF01300135F6E71A48B6 -:1020300090F8260020700020F8BD14480078012890 -:1020400012D81348134A00234FF6FE750026007875 -:10205000864213D21788AF4203D0DFB28F420FD02F -:10206000013301360832F3E7C920F8BD084612F003 -:1020700057FE18B1014620461C2204E0C120F8BDDD -:1020800011462046082217F083F8D4E718260020CE -:10209000DABC0200E04C0020407B00207FB5044603 -:1020A00000200D46ADF80C000290CDE90000886AD2 -:1020B0004078C10604D0D32004F02BFE002448E071 -:1020C000810644BF01218DF80C10010644BF012197 -:1020D0008DF80B10400605D4287AE8B105F11800F8 -:1020E000002107E001208DF80A00E879D8B105F158 -:1020F00014000121066836B168463146023017F0F7 -:102100003EFD9DF80A10A8890129ADF8000006D10E -:10211000B6FA86F14E090AE0A889ADF800006846D3 -:102120000EF0A6FA15E0A8890126ADF800001049C6 -:10213000097871B1012902D10E4A12784AB10229F7 -:1021400003D10D49498B884203D1688911F012FDF2 -:1021500010B1204604B070BD002EE0D116F050FD45 -:1021600068460649023015F0A0FA0028D7D1F0E7FA -:1021700018260020C9270020407B0020C8870020A7 -:1021800070B541F21C30C5F20000066840F2B01490 -:10219000C1F2000413F07EFC40F28440C4F26020DF -:1021A00000250560206C806C804740F28010C4F2EE -:1021B0002830006850B140F28051C4F22031B6F1AD -:1021C000FF30096818BF304602F09DF842F28C11CA -:1021D000C4F208010D6042F24801C4F203010A682A -:1021E00040F23913282063F31B42C4F209000A604D -:1021F000016801F44051B1F5805F09D101684FF6E3 -:10220000EF72CFF6FC42114001F50032026001602E -:102210000025C4F224350126EE612068016A1420ED -:10222000884742F20000C4F20900016841F4E0214D -:10223000016044F6B4702E60C5F20000006800F43E -:102240004000B0F5000F06D1206C416C43F2BD7028 -:10225000C0F2860088470C20C4F26820016800297B -:10226000FCD170BD2DE9F04387B00446084699467D -:1022700090460E4616F009FC304614F0A3F92E4F96 -:10228000386858B10320314608228DF8100002AD9D -:10229000284616F07DFF3968284688472748007889 -:1022A00001283AD80220ADF80A4003968DF81000B4 -:1022B0000020ADF80800304617F0E3FBB9F1000F3D -:1022C00027D128B9204631460DF082F9AA2820D11D -:1022D00016F0A6FEE8B905AAAB2000210CF0B0FD6F -:1022E0000DF107013046002207F064F91448007828 -:1022F000012808D19DF8070028B900208DF81100A9 -:1023000002A80AF0D6FC01208DF8110002A80AF0FC -:10231000D0FC3046414612F071FF2046002114F0F7 -:102320007BFD0848818C204613F055FC15F000FA1F -:1023300007B0BDE8F08300BFF82300201826002076 -:10234000B2270020407B002070B586B00446807A1A -:1023500058B9E07AC00608D43048C825007801286A -:1023600053D12D48007801284FD1616820880DF1A4 -:10237000160213F015FEA07A98B12B4E306A70B198 -:10238000208861686D460822ADF80000A81C16F090 -:10239000FFFE2089316AADF80A00284688470025EB -:1023A00036E0E07AC10602D4C0F380001FE01C488A -:1023B0001C490078097808431AD100206D46142181 -:1023C0008DF81500284616F07FFD60680DF11501A7 -:1023D0002A4607F0EFF89DF81500002818BF0120E5 -:1023E0009DF810100239B1FA81F14909084028B16D -:1023F000204609F09EFC054620B9BEE7E07A0007BA -:10240000BBD4AD25606814F0DDF8204604F062FE10 -:10241000284606B070BD00BFD72700209C8800204A -:10242000F4240020AE2700203C830020BCB50446E5 -:102430004089410622D432490978012927D83149F7 -:10244000897B89072ED523684021228B01EA9011D0 -:1024500018881B6A9D8800914FF6FE73294602F08A -:102460007DFBA84202D0218B884217D1206802222E -:1024700000230188284609F023FC13E02068008827 -:1024800011F078FB40B16FF0010001300CE002293F -:1024900008D117F077F801E0206800884FF6FE7148 -:1024A000884201D1CD250FE02168088080B211F06B -:1024B00061FBB0FA80F0226813494009D0811046D0 -:1024C00006F0F0FF054630B120682946407B0FF04A -:1024D000C9F990B90CE00A4800250078022807D114 -:1024E0000A48007820B920200121F9F715FA0025C3 -:1024F0001CB120460121FDF7BBFC2846BCBD00BF36 -:1025000018260020407B0020B94C0200D52700206F -:1025100070B50546C80713D1880758BF70BD334C46 -:102520001C200021A0471D200021A0471E200021C3 -:10253000A0472F4C1C200021A0471D20002136E081 -:102540002A4E1C2000211446B0471D200021B04710 -:102550001E200021B04728460AF05AF92188C50FED -:1025600040F60200814206D043F60700814204D0C3 -:10257000B1F5C15F14D1E07B01E094F8240040067E -:102580000ED01C20002115F0F1FC1D2005B33221D6 -:1025900015F0ECFC1E202F21BDE8704015F0E6BCC4 -:1025A0001C20134C55B12F21A0471D203221A047DC -:1025B0001E2000212246BDE8704010470021A047A0 -:1025C0001D200021A0471E200021A0471C2007E05D -:1025D000002115F0CBFC1E20002115F0C7FC1E20A9 -:1025E0000121BDE8704016F033BD00BF51900200DC -:1025F0006D7F02002DE9F0418EB004464A1E002096 -:1026000012F1030F0AD809AA0490029107922F4AE7 -:1026100006928DF814000222684600E003220C9016 -:102620008DF834202020EFF3118680F31188608A22 -:1026300030B1608A01386082012086F3118842E05F -:1026400000293DD02248012104F1140790F80880A8 -:102650000172806909AD45620B9011F0BDF8A06967 -:1026600009970A900560A5619DF83400022808D1F9 -:1026700018494A680C98016042601060486005F093 -:102680002BFD86F31188404611F0C4F82021EFF3AA -:10269000118081F311880C9939B10A684B681A606E -:1026A0004A6809684A6000210C910B9900224A622D -:1026B00080F311889DF83400002818BF012002E043 -:1026C00086F3118800200EB0BDE8F0815B4F020058 -:1026D0003822002008200020B0B504463048007899 -:1026E000A8B130488068006C0068007D78B144B1C2 -:1026F0001B2C06D0E92C0AD12B484088B0F5105F7E -:1027000005D12948C07B16F06BFB12F0B7F92748BA -:102710000021017026480170A4B922488068D0F8D1 -:10272000D41091F85310882908D022490978052936 -:1027300008D1006C0068C08A400703D417F046FA3D -:102740001D494860174DA868D0F8B8100A7872B1D2 -:10275000496C61B120468847E868C068007898B93C -:10276000A8680021D0F85824002090470CE0D0F849 -:10277000AC00007808B90EF0E5FA0CF0D1FEA868BC -:10278000D0F8701220468847A868006C006818B11D -:10279000007D352808BFB0BDBDE8B04016F03EBB97 -:1027A000902700200C010020A88500202126002071 -:1027B000B4880020B7880020542600202DE9F0437B -:1027C00087B0044600200D4631498DF807002F4898 -:1027D00009780078084301D1012452E0F4B1EDB149 -:1027E0000DF108080DF107012846424606F0E2FE09 -:1027F00081464FF6FF70814521D09DF8070078B1E2 -:102800009DF8180060B99DF81B001022234600F0C7 -:102810007F01052013F0D4FD002432E0022430E0D3 -:102820001C4800260788B1B2B94208D20520102200 -:1028300023460DF09BFA092803D00136F3E7B224B2 -:102840001FE008F108002946082216F0A1FC46F016 -:10285000800000244946142243468DF81B000420C2 -:1028600003948DF81840029413F0AAFD0A4909EB6D -:10287000490041F8204001EB80000121C0E90144FA -:102880004172204607B0BDE8F08300BFAC270020AE -:1028900018260020C4BC0200804300202DE9F04728 -:1028A00088B006461398DDF840A01D46914688463C -:1028B00050B1149C4FF6F777601E80B2B84204D333 -:1028C00017F04AF80446F7E70024C120BAF10F0FC9 -:1028D0004DD111990F294AD1264F129887F82F0010 -:1028E00040F60F7087F82E50C7F82890B8854FF63D -:1028F000FF7086420AD120494FF6F77008300E88E3 -:1029000080B2864202D117F027F80646B8F1000FD0 -:10291000BE8409D0404616F0A9FA012804D107F177 -:102920003900414617F02BF907F13905284616F012 -:102930009DFA18B9E220294613F074FB0020FC82AE -:10294000182187F83800788340F60F70B885052085 -:1029500087F8260001AC201D16F0B6FAB86A01907F -:1029600097F82E008DF8090020460CF0F9F808B011 -:10297000BDE8F087407B00208027002070B520391B -:10298000062918D8DFE801F01A23042D3840480042 -:10299000147800222321FF2CF1D0D0E9015695F8BC -:1029A000FB0010F0FFFA726B2B49204685F8FB40C4 -:1029B00005F0B8FC49E06FF001044AE0406890F887 -:1029C000F910012943D1012180F8FC103DE0456850 -:1029D0000021002495F8FB0012F0B0FB85F8FC40C4 -:1029E00037E0446894F8FB00FF282ED010F0DAFAA4 -:1029F000FF2084F8FB0028E04068D0F8C01031BB0D -:102A0000012180F8FE1020E04068D0F8C010F1B934 -:102A1000002480F8FE401CE04168D1F8C020B2B12B -:102A200091F8FE209AB180680268D0E90430546AB7 -:102A3000184344F003045462D1F8CC104968096883 -:102A40008862506840F002005060002401E04FF0BE -:102A5000FF34204670BD00BF026000202DE9F04F1A -:102A600085B080460FF0A4FA002864D08346471C46 -:102A7000002400254FF000099BF8000084421FD27B -:102A8000384616F0FEFFC0B101790139012914D88A -:102A900090F8200088B10C2017F0C6F868B13946CC -:102AA000064617F06CF80020B06015B1CAF808604F -:102AB00000E0354609F10109B24608370134DBE789 -:102AC0005FEA096034D002205FFA89F98DF81000BE -:102AD000B8F80200ADF808004FEAC90017F0A4F8F2 -:102AE000A0B107460024A5B1E0B2294607EBC0001B -:102AF00017F045F8AE68284617F094F801343546CB -:102B0000F1E7AC68284617F08DF82546002DF8D17E -:102B10000EE0002048F21F014A463B46CDE9001076 -:102B200008F1110002A901F0FBF9384617F07AF814 -:102B3000584617F077F805B0BDE8F08F2DE9FF4152 -:102B400005464FF6FE70854222D00C4601B3DFF8F1 -:102B5000C480D8F80C7007B3B91C2046082215F0C1 -:102B600067FA60B198F830000026B87211E0B11C25 -:102B70002046082215F05CFA0028374645D1FE6849 -:102B8000002EF4D1102017F04FF8F860A8B93AE001 -:102B90000226304604B0BDE8F081102017F044F85A -:102BA000C8F80C0078B31C484FF400614FF47A72F7 -:102BB000007816F09CFFD8F80C0098F8301000262A -:102BC0000580851C0822C66081722846214616F0C1 -:102BD000DFFAD8F808000028DBD001AC294608222B -:102BE000601C16F0D5FA04F10A01284612F00DFF18 -:102BF0000948092100220C238DF804600094007814 -:102C000010F039F9C5E70126C3E798F83000B07233 -:102C10000026BEE7AC2200209F8800202DE9F84F57 -:102C200016F0D0FD2F4D2C4644F8100F16F0C4FDC1 -:102C30000027206818B100F118040137F9E72C6962 -:102C4000002C46D04FF6FE70DFF89CA0DFF8A0B055 -:102C5000DFF898900026FDB201301FFA80F8F0B23C -:102C6000A84235D2504616F001F9012806D104F1E8 -:102C70000C01504614F019FD38B922E0B9F80000F3 -:102C8000404502D0218881421BD12089BBF81A100F -:102C9000884203D14FF6FE71884208D1154800786A -:102CA000022801D2E07801E001D1207948B19BF8F7 -:102CB00012006179814208D10F48A17900788142E0 -:102CC00003D0204611F0A2F9013FA4690136C6E7FE -:102CD000044D6A6922B12869F9B2BDE8F84F10477E -:102CE000BDE8F88FAC2200209687002080270020C6 -:102CF000407B002018260020D8270020B0B52F4C9C -:102D0000608810B12E49098814E02E494FF4707282 -:102D10008968D1F8F410C98F02FA01F12A4A01F545 -:102D20007071127851434FF47A72B1FBF2F1244A78 -:102D3000118089B288421AD225492448096800685E -:102D4000096C88472278C1B2914288BF20706088A0 -:102D50000130608016F038FF4FF47A711E4B00226C -:102D6000B1FBF0F01B49BDE8B04007F039B894F969 -:102D7000000013F07BFC134901258A68D2F8F42087 -:102D8000936992F8442098548868D0F8F40090F839 -:102D9000442000EBD20002F00703427905FA03F366 -:102DA0009A43427100202070608088680421D0F826 -:102DB00094000078BDE8B0400BF04AB94C240020E4 -:102DC000DA6B00200C010020B0880020D8260020FB -:102DD00030880020FD2C010058880020F0B500222A -:102DE000C1F802204A73838D027F4B83C3890A7521 -:102DF0004B81836A1C4614F8015B15F003060D70C5 -:102E000003D0032E43D0022E28D105F00C060C2E41 -:102E100005D015F0100702D15C788C709C1C082E30 -:102E200002D101260E7306E000270C2E0F7302D18B -:102E300034F8020B08E0467906F00306012E04D1AF -:102E400045F00C0540890D708880E80606D420887E -:102E5000C8806088088120790534C870204610F841 -:102E6000016B4E756EB2B6F1FF3F0BDD00244C7066 -:102E70000861181A131840424873D8B20B75824281 -:102E800005D3F0BD607810F0FC0F487003D000202F -:102E900008754873F0BD10F003000CD00328F6D07D -:102EA000A078C87505F00300022811BFE01CE07887 -:102EB0000876201DDCE7A01CDAE77047F8B5164657 -:102EC0000F46054616F03AFB0446092F3AD8DFE8CC -:102ED00007F00508111417313B1B4B2C3068286094 -:102EE0004AE001206876D5E9040160306031C5E927 -:102EF000040141E0306868833EE03068A8853BE02B -:102F000030682249886037E01F4820490025806BDF -:102F1000097E91BB88BB1E483168283016F084FAC0 -:102F200031681C4816F080FA26E02020314614F063 -:102F30008FFD21E0306801281BD018B9802015F0E2 -:102F4000AFF819E0032518E00F4810490025806B01 -:102F5000097E91B988B93168192015F015F83168E2 -:102F60001A2015F011F807E03078064981F8600062 -:102F700002E0802011F016FC8325204616F08AFD21 -:102F80002846F8BDB87B002030210020D01E00204C -:102F900070200020288000202DE9F84F93464268D9 -:102FA0000546936803EA0100884255D1D5F808A088 -:102FB000DAF804408C429CBF6FF00300BDE8F88F44 -:102FC0000BEB01066FF00500A64247D803EA0B039E -:102FD0005B4543D1BAF82000DFF89490E846C9F881 -:102FE00008005068C9F80400DAF800004618BBF180 -:102FF000000F39D028460BF03DFE88BB284612F062 -:103000006DFB68BBBBF5803F05D3B0B218B94FF478 -:103010008034D82002E0DAF8084020208DF8000043 -:10302000300AB9F808108DF803608DF80200300CF2 -:103030008DF80100284615F05EFF404604210CF093 -:10304000C3FDB9F808100746284615F05DFF3FB9E3 -:10305000ABEB040B2644CAE76FF00400BDE8F88F21 -:103060004FF0FF30BDE8F88F0020BDE8F88F00BFBB -:103070000C240020F8B50446807A022851D1A07BA8 -:10308000E0B12948006800284BD026480078012884 -:1030900047D126480078C00743D0042013F0E4FF4E -:1030A00000283ED001464FF4B27008806088488006 -:1030B0001F480078BDE8F8400BF0F6BF20480168D3 -:1030C00079B11E4F386860B11B4E306848B1194D58 -:1030D000286830B113480078012802D160888847F9 -:1030E00030B1608801210122BDE8F84000F02EB81F -:1030F0001448007830B1144951F82000C0EB00109A -:10310000810001E01048016860883A689047012812 -:1031100007D160883168884760882968BDE8F84031 -:103120000847F8BDBA27002084230020CC270020C0 -:1031300098880020982300209C23002094230020BE -:1031400088230020C727002060B702002DE9F84F30 -:1031500014460E46824614F07FF9D6B3C8BB2B49FD -:103160002948012600940978043051B10278FF2AD9 -:1031700003D030F8042C524504D0243001397600B5 -:10318000F3E700262248254FDFF894B06FEA0609DE -:103190000025047800205FFA85F8A04518D217F8BA -:1031A000081099B15BF8282032420FD0084615F07C -:1031B00061FB50B1417B052907D15BF828102546FA -:1031C00001EA09014BF8281000E000200135E2E790 -:1031D000009C70B1417B05290BD10168A1F800A0CA -:1031E000012141730B4820210078BDE8F84F0AF017 -:1031F0002FBF34B10848818C5046BDE8F84F0EF01F -:103200007DBABDE8F88F00BFB0540020E6BC0200D4 -:10321000D2BC020098880020407B0020408400201F -:10322000C87A0020F0B5314A046A516B137D0C61F5 -:10323000446A01F1200C032B0B704C61846A8C6191 -:10324000C46ACC6190E8F000ACE8F00000F1400402 -:1032500000F110074C64F0CF01F1300CACE8F00045 -:10326000046B0C64446B8C64846BC06BCC64086529 -:103270000BD8DFE803F0020D1016156DC4B2106C08 -:10328000936C55F824404C600FE0002000230CE0C4 -:103290001748406D06E0174880694860D0E90A3059 -:1032A00003E000204860106C936C926BC1E902034C -:1032B00032B12BB110F8014B013B02F8014BF8E79A -:1032C0000D4802684A6590F824208A6590F8252008 -:1032D000CA65C28C0A66826A4A66C26A8A66026BDC -:1032E000CA66426B0A67806B4867F0BD381F0020D2 -:1032F000A01F00203822002004ED00E07CB5002053 -:103300008DF8070016F0D8FC29494FF0FF32294DFF -:10331000294C097802FA01F188432880A068D0F886 -:10332000B800017841B3826B32B30DF1070142F26C -:103330001A009047214E3078B8B17078A8B99DF83E -:10334000070090B1A068D0F8B800C06D68B18047A0 -:1033500058B1E2681A495268097812780832514324 -:10336000B0FBF1F0298808442880288871789DF8FE -:10337000072011FB020028801248007810B116F0D7 -:10338000A1FC01E016F09CFCA068006C006840B154 -:103390000D48007810B90D48007818B10C4802218A -:1033A00001707CBD0A488321017010F06FFA7CBD6A -:1033B000B5880020AE8700200C01002021260020C7 -:1033C000B0880020B7880020AC880020AF8800209B -:1033D000B4880020F8B5304D212074212A4616F01B -:1033E0000FFA80B100240FF0C9F82D4800780128A9 -:1033F00098BFFAF70BFE2B48006800B180470CF02D -:1034000065FB2046F8BD2120002174222B460024B4 -:1034100015F040FD0028E6D1E88A4FF6FE7188429B -:10342000E1D095F82600082801D0042831D10DF10B -:1034300003061A4F0124422031468DF80340B84755 -:1034400005F12F014320B84705F12C014720B8476B -:1034500005F11C014A20B84705F11A014B20B84775 -:1034600005F124015020B84705F116015320B84753 -:1034700005F12D015420B84705F11801E120B847A6 -:10348000A87B3146C0F3C0008DF803005220B84736 -:10349000A9E7FEF74FFBA5E7407B00207D20020057 -:1034A0001826002004240020F0B58BB00546022029 -:1034B0008DF829000AA813F0E3F9002857D0044634 -:1034C000006946F2040101800120A077A07615F082 -:1034D00097FB284865806062E07E20B92648017825 -:1034E000E17601310170207E234F012805D1F87A61 -:1034F00018B9207808B9002020760DF12701204660 -:10350000F8F7E2FC80B30546242016F08DFB02900C -:1035100038B32421064615F0D7FC0DF106015020E2 -:1035200012F080FDF88ABDF806109DF82720ADF84E -:1035300020006088718130800220307330720298E0 -:103540000562617DC2770122C28141738DF814103A -:10355000E08AADF8120002A816F03AF9029816F0C7 -:1035600061FB284616F05EFB204616F05BFB0BB0B5 -:10357000F0BD00BFC8870020407B0020F0B589B0B7 -:10358000304CADF82210154607460E9AC22094F82A -:103590002610ADF82020042952D0082950D04FF62B -:1035A000FE70824201D1C3204AE001A81C211E46C0 -:1035B00015F08AFC03200DF1220184F8260050202A -:1035C0000EF05CFD08A94B200EF058FDBDF822005E -:1035D00039462576A673A084BDF82000608304F1E7 -:1035E000390016F0CCFA06F04E0080308DF81E003F -:1035F00015480078012803D80F98013084F8380066 -:1036000002208DF80F500F2521468DF81A00BDF8C5 -:10361000200001F82D5FADF81200BDF82200ADF8D2 -:103620001C0000208DF80C0054200EF027FD04F83B -:103630002C5F472021460EF021FD01A803F09AFDE2 -:1036400009B0F0BD407B0020182600202DE9FC4782 -:103650000B9C88468DF80700042015211E4617464E -:1036600014FB0100012151FA80F016F0DDFA002868 -:103670004BD081460C990A980025CA460AF8017F6A -:1036800004278AF802008AF801600AF1040001F1B7 -:103690000C068AF80340E9B2A14223D2A6F10C013C -:1036A00016F06DFA16F8041C017016F8021C417031 -:1036B00016F8011C8170317AC170317A032908D162 -:1036C0000430314616F05BFAB17A153700F8011B69 -:1036D00005E031780E370171717841710630183686 -:1036E0000135D8E70B4DFBB20DF10700414648F21A -:1036F0003302C5F804A00BF08FFE0446484616F0CE -:1037000091FA05480130686000E010242046BDE8C9 -:10371000FC8700BF7C260020DC7D002070B5F8B15E -:10372000012858D1012015F0B1FF012853D02D4CAC -:1037300094F8380100284ED12848294E0569306890 -:1037400010F4402F30D17DB314F032F9502016F030 -:103750004CF90120A84704F1940016F03FFA25E047 -:1037600016F064FA1E48006810F4402F0AD11B4876 -:1037700004693CB11B48943016F086F914F008F93E -:103780000020A047174C94F8380120B31648016870 -:1037900021F08001016080218160032010F0E8FFAA -:1037A000002084F8380116E016F044FA012084F86D -:1037B0003801306810F4402F00D14DB9207A8006CE -:1037C00006D4094880218160016841F080010160D0 -:1037D000032011F0EBFD002070BD00BF90BA020085 -:1037E000B44F0050D81B002090220840F0B585B09F -:1037F00004464078DB3818280DD8012101FA00F082 -:103800002C49084207D02C488068D0F80412204682 -:10381000884705B0F0BD284EB068D0F8FC112046AE -:10382000884758B9607C40B1271D97F8300020B90F -:10383000B068D0F8B810097811B100206070E2E7E4 -:10384000D0F8342207F10E01092090470028F4D067 -:103850000546B068F91DD0F83024E7209047B068DD -:1038600004F10801D0F8302450209047B068B91D09 -:10387000D0F83024E1209047022023894FF6FF72D0 -:103880008DF810004FF0FF30ADF80800B068D0F8A8 -:10389000C061A07A009002A92846B047A0F1DB01E0 -:1038A0001829B6D8012202FA01F1024A1142C5D103 -:1038B000AFE700BF112000010C0100202DE9FC47FB -:1038C0000446E820002C59D08A46002956D060686A -:1038D000DFF8B49000260DF10408411E61603F211D -:1038E00000F8011CA16D6068B1FA81F1421E49091E -:1038F0006260C90100F8011C0220A4F8540020896C -:1039000002302081022E36D01AF836002A2802D042 -:10391000FF282ED12FE00AEBC605686848B3D9F816 -:103920000810D1F8B8108969884707466068C01B3D -:10393000606069684A0707D4D9F808200023D2F8E4 -:10394000B820D56922460AE0D9E902239B68D2F85B -:10395000B8201B78D56922468DF804304346A84725 -:1039600070B1208938442081B4F854003844A4F858 -:1039700054000136C6E7606820650020BDE8FC877A -:10398000EB20BDE8FC8700BF0C010020F8B52B48F8 -:103990000068C06B80472A492C4B09681B68411A94 -:1039A000284800788200B1FBF2F1274A12688B4266 -:1039B00001D9934202D38A42134623D9591A4FF0B0 -:1039C0000003A1FB001263F1000303FB0020204A67 -:1039D0001268538B12691A4464328D1A60F1000622 -:1039E000681E76F100000DDB16F0EEF8074628465B -:1039F000314600233A4615F06BFA0446E81B76F18F -:103A0000000001D2012015E015F0A1FF114E05467E -:103A1000306816F0DFF810B1306816F035F8284637 -:103A200016F071F83068214616F0D6F8306816F0B6 -:103A3000D5F8002008490870F8BD00BF3088002084 -:103A40002C880020B0880020388800203C88002086 -:103A5000D826002028270020B2880020B0B586B0E4 -:103A60000446008810F086F810B915F0D9FA08B1AC -:103A700006B0B0BDA178207A39B30428F8D129481E -:103A80000DF10301006801AA05F094FD01469DF8BF -:103A900003000028ECD09DF814000128E8D19DF91E -:103AA00017200020CDE90100002A03D401208DF861 -:103AB0001500FF208DF8140001AB0420142212F031 -:103AC0007FFC022015F042FED2E70428D0D1154831 -:103AD0000DF10301006801AD2A4605F06BFD0446B7 -:103AE0009DF803000028C3D09DF814000128BFD121 -:103AF00002208DF814009DF91700B0F1FF3F03DCA0 -:103B000005F113000FF072FF01AB042021461422CF -:103B100012F056FC002015F02BFE01200121F0F7D9 -:103B200039FEA5E7DC870020F8B515460E460446A9 -:103B300010F020F808B10020F8BD204600210DF05B -:103B40002DFC294606F08CF9C8B1074640790328B8 -:103B500007D00128EFD1788807210FF0A7FD0028B2 -:103B6000E9D1B87910F0180F1AD0788821460022D0 -:103B70004FF6FE73009030460CF04BF934E02046CF -:103B800014F0AAFA15F029FF0028D4D04179CA0709 -:103B9000D1D08A0706D441F002010127417109E022 -:103BA000022707E0304621460122012709F082FD65 -:103BB0000028C0D0304600210DF0F0FB0B49C98A27 -:103BC000884206D10A48294602782046FAF7A0FD25 -:103BD0000AE0304621463A4609F06CFD0028AAD199 -:103BE0002046294613F018F90120F8BD407B00203B -:103BF000CEBC020070B5314B04255C6859B952B196 -:103C0000D379157B2B440C2505EB4305EBB2502BE8 -:103C100084BF102070BD2170EBB28169052B09783B -:103C2000617081694978A17023D3291FE1701178EF -:103C3000217191786171D178A1711179E171517916 -:103C40002172917901F00F016172D179A172D57958 -:103C500095B10021A9420FD2956815F81150E5726F -:103C6000956805EB410501316D7825730234D579EE -:103C7000F0E70021E17016E004F10B01147B0C70F9 -:103C8000157B85B10024AC420DD2156901EB4406C9 -:103C900015F814507570156905EB440501346D78FD -:103CA000B570157BEFE700F11102811C104648F258 -:103CB0000402BDE870400BF0AFBB00BF7C260020C3 -:103CC0002DE9F8432020EFF3118980F311882C4867 -:103CD0000068006B80472B4E4FF000082A4F0122EE -:103CE00086F85D8086F85C20D7E9104522462B4691 -:103CF00015F0EEF8A0FB042300FB053301FB0431B3 -:103D0000746DC7E91221B168B268611A821A9142D2 -:103D100005D986F85C8089F31188BDE8F883051B16 -:103D200089F311880020854206D304442D1A01200E -:103D300021460AF09DFBF6E72021EFF3118781F37E -:103D4000118896F85D1019B1002021460AF090FB09 -:103D5000411C05D0B16D401B884288BF084600E079 -:103D6000B06D011914F0B6FD002086F85C0001204A -:103D700086F85E00B46087F31188BDE8F88300BF61 -:103D80008C01001008200020207C0020F0B585B0B8 -:103D90000D4600211446CDE90311CDE9011101A919 -:103DA000009104A903AA02ABFBF728FD029F394644 -:103DB000002F18BF0121019E0140002E324618BF7E -:103DC00001221140002D10D411B3049840F22B2190 -:103DD00005806FF39F5538462A4613F0F9F903988A -:103DE000314609F005F8676010E0C9B104984FF05A -:103DF000FF316FF39F552A46018030462B2113F087 -:103E0000E7F90398314609F0BFFB666015201EE014 -:103E1000C8B104984FF6FF720188914214D110E0A6 -:103E200078B16FF39F5503982B212A4613F0D0F9F0 -:103E3000FF2806D004984FF0FF3101801420656000 -:103E400005E0032005E004980580658010202080AF -:103E5000832005B0F0BD7047B0B588B0C189044675 -:103E6000A1F1210002281ED3A1F50040022826D38B -:103E700048F22100081A022832D227480078002888 -:103E800047D126480068002843D048F2210202208A -:103E9000914208BF0320A169627C097808B0BDE89F -:103EA000B040F6F7ADB9207B98BB6D462046294659 -:103EB0000FF0E8FF20462946F9F70CFD29E02046DF -:103EC0000AF056F928B30446007818B96088211D15 -:103ED00014F064F9204608B0BDE8B04015F0A2BE69 -:103EE000202916D10C48007898B96D4620462946FD -:103EF00007F00AFB2846F7F793F89DF8120010B177 -:103F0000059815F08FFE9DF8180010B1079815F070 -:103F100089FE08B0B0BD00BF182600203827002059 -:103F20002DE9FE4F89462E4C097ADDF830A0174660 -:103F30001D464FF0000866680F2904BF4FF6FC715C -:103F4000A9F8001048F21F018A45029011BF4FF0F6 -:103F5000010B002006F8010B4FF0020B0BF1500192 -:103F60003046019100F8017BB8F1090F14D861784F -:103F700005EBC10115F003FE617808F101080BF1B2 -:103F8000080B01316170C9B2B942EDD1002086F849 -:103F900000806070029C19E00A2030706078B8429E -:103FA00012D2BAF11F0F08BF13F05AF948F21F00DE -:103FB0008245DDE901B409D10A484FF480410A2263 -:103FC000007815F097FD01E0DDE901B45FFA8BF3AD -:103FD00020464946524603B0BDE8F04F0BF01CBAEC -:103FE0007C260020998800202DE9FE4F9946154631 -:103FF0000F46044615F0E8FD4FF47A71B1FBF0F07E -:10400000454315F0A4FC80462046394613F0D0FD08 -:10401000AB4688B10646006815F036FD3068594653 -:1040200015F0DAFD306815F0D9FD0824404615F08A -:104030006AFD2046BDE8FE8F142015F0F5FD00282E -:10404000F3D0EA460646504615F031FC01205946A9 -:10405000524602968DF800001348B9F1000F08BFD0 -:104060004D4601950EF080FF306070B10F4A00217F -:1040700086F80C90B76034713161116849B10A69F2 -:104080000AB11146FBE70E6105E0304615F0CAFDA6 -:10409000CBE716603068594615F09EFD306815F084 -:1040A0009DFD0024C2E700BF91E501006C260020C1 -:1040B0002DE9FF41044690F91900B0F1FF3F01DD01 -:1040C000BDE8FF81207D40F002000328F8D1DFF831 -:1040D000A480D8F80800D0F89810098911F00A0FC8 -:1040E000EED061684A78C2F38102032A8DF80C2071 -:1040F00008D0022A0CD1B1F80520ADF80420B1F89F -:10410000032005E0053101A815F039FDD8F80800B5 -:10411000C16BA4F10C0795B201AE0868C0B190F96B -:104120001910B1F1FF3F3946F7DC017D41F0020182 -:1041300003293946F1D14268D8F808002946D0F859 -:1041400068333046984700283946E6D0002CB7D16E -:1041500015F000FA30B101A82946002210F0E4FE63 -:10416000BDE8FF81D8F80C002946826F01A890476E -:10417000BDE8FF810C01002010B52E488168D1F800 -:10418000B020D1F8881311608168D1F8B020D1F83F -:104190009C1351608168D1F8B020D1F8A0139160D0 -:1041A0008268D2F8B010D2F88032CB60D2F8B0106A -:1041B000D2F8A4330B61D2F8B010D2F87C324B6144 -:1041C000D2F8B010D2F884328B610021D2F8B0302E -:1041D000D961D2F8B030D2F88C431C62164CD2F8B8 -:1041E000B0305962D2F8B0309C62144CD2F8B03082 -:1041F000DC62D2F8B430D2F848241A608268D2F86F -:10420000B430D2F8A8235A608268D2F8B430D2F819 -:10421000AC239A608068D0F8B420D0F8B433D3606F -:10422000D0F8B420D0F8B0331361D0F8AC000170EE -:1042300010BD00BF0C010020619B0200C99C020060 -:10424000F8B5064600780C4615F032F808B1B825E6 -:1042500057E00025002C54D03078257320701420AE -:1042600015F0E2FC0028A0604AD031780170B6F861 -:1042700001104180B6F8031081808179727901F0D4 -:10428000F00102F00F0211448171F179A068083643 -:10429000C17171B1480015F0C7FC0146A06881608A -:1042A00051B1C2792AB136F8023B013A21F8023BFA -:1042B000F8E70027002501E0102501273178017378 -:1042C00079B1480015F0B0FC0146A068016149B120 -:1042D000027B731C2AB133F8026B013A21F8026B9E -:1042E000F8E777B1816819B1084615F09BFCA06822 -:1042F000017B19B1006915F095FCA06815F092FCDE -:1043000010252846F8BDF0B581B044F6AC71C5F271 -:1043100000014A6846F2092605469007C4F20806DD -:1043200005D40868F02242EA104086F84D004AF2AF -:104330000440C4F20C004FF0012202604AF2000077 -:1043400040F2F017C4F20C00C1F2000700888C683C -:10435000386801682046884704F04070B0F1807FDB -:1043600003D1307840F0020030703868214642684E -:104370002846904706F080FD41F20C40C5F200004F -:1043800000684BF20E02C0F30531C4F20C0211704A -:10439000C1054FF0130158BF232140237354382126 -:1043A00001EA901000F56050A2F85C00386881685E -:1043B0002046884702200CF0D1FE40F29440C4F21F -:1043C00060200121016001B0F0BD70472DE9FE4F72 -:1043D000DDF834808DF80B0005209B4616460D460F -:1043E00008EB480400EB8400C0B215F01DFC002867 -:1043F00046D08146042001950E9D002700EB8400E5 -:10440000CA464FF6FE740AF8016F00900C988AF8BD -:1044100001B00AF104064FF0FF0B8AF803808AF816 -:104420000200F8B2404517D205F10C01304615F0F4 -:10443000A6FBA8783072A8797072697986F80AB0FC -:1044400040EA011070722889001B18BF0120F07229 -:104450000C360137AD69E4E700980B4D019948F23D -:104460003002C3B20DF10B00C5F804A00AF0D4FF6E -:104470000446484615F0D6FB04480130686000E069 -:1044800010242046BDE8FE8F7C260020DC7D002025 -:104490002DE9F04F8FB082460E46087849789B464A -:1044A0001446F378B27801EB0009042B38BF91442D -:1044B000F76838BF00225FFA82F815F048FA2349FE -:1044C00000250190C96811B1F078884700E000200C -:1044D00000900BA83946102215F02AF80746B0FACA -:1044E00080F0F1784009032988BF01255BFA89F142 -:1044F000284041445FFA89F5BAF1000F0FD0F0B1BE -:104500000DF108090F46484615F0C2F908950BA8A9 -:1045100011F0EFFF0E48006815F0A7FA0EE070B139 -:104520000DF108090F46484615F0B2F908950BA899 -:1045300011F0DFFF0648006815F09AFA0746019867 -:1045400015F0E1FAF8B20FB0BDE8F08F04250020B5 -:10455000F4870020B0B52A498968D1F8D420527B6D -:104560000F2A1FD0D1F8AC301B78DBB1D1F8EC109A -:104570000024274D51F82210224A127851434FF45B -:104580007A72B1FBF2F32049204A0968C91A38BF90 -:1045900021461268D21A38BF22462D68EB1A38BF5E -:1045A000234605E01849194A194B096812681B6827 -:1045B0004FF47A74634383420DD96243824211D926 -:1045C0004FF47A725143134A8142127811D9012073 -:1045D000AAB1002111E00F480178002003290ED074 -:1045E00003210AE00B4801780120022907D00221AB -:1045F00003E001210120012A01D0064A1170B0BD5B -:104600000C010020B0880020108800200C880020B9 -:1046100018880020A08800202DE9F041DFF8B8803C -:10462000D8F80810D1F8E8000068002852D0D1F876 -:10463000E03042681B689A4208DDD1F84C0580479B -:10464000D8F80800D0F8E800006858B144680FF0C6 -:1046500085FD844206D9D8F80800D0F8D404BDE816 -:10466000F0410047D8F80800D0F8E8100C688CB387 -:104670006668B6F1FF3F08DCD0F84C058047D8F8F3 -:104680000800D0F8E80004686668A768257B0FF08A -:1046900065FDD8F80810864206D8D1F800152046E6 -:1046A00088472846B847DDE7D1F8E800006848B1F8 -:1046B000D1F8E01040680968884203DABDE8F041AB -:1046C0000EF07CBF13F0D4FAD8F808000021D0F81F -:1046D000E8000160BDE8F0810C01002010B52E4A11 -:1046E0001278022A49D12B4A1278002A45D1C207F2 -:1046F00006D02A4A136A1160934204BF0023136252 -:10470000020708D5254A134643F8041FDC699C427A -:1047100004BF00231362C20608D5204A134643F89B -:10472000081F9C699C4204BF00231362820608D5BF -:104730001A4A134643F80C1F5C699C4204BF0023CD -:104740001362820708D5154A134643F8181F9C6860 -:104750009C4204BF00231362420708D50F4A134648 -:1047600043F81C1F5C689C4204BF00231362C20410 -:1047700003D50A4A4FF47A735361400408D50748B9 -:10478000024642F8101F1169914204BF00210162E4 -:1047900010BD00BFD527002018260020F082002081 -:1047A000F0B591B004460078A678676828B1B85D86 -:1047B000617840EA0102BA5503E020460CF018FC8B -:1047C000BA5DA16904F10800D2B20DF1370313F00C -:1047D00058FB6078A178E278237F8DF82700608A03 -:1047E0008DF82410A18A8DF825308DF8262060B927 -:1047F00040F20112914208D194F8281004F11E00F1 -:104800000DF1030208F0ECFF03E00DF1030205F0E7 -:104810009FF8FF208DF823000DF103000C90207C01 -:10482000022803D003280FD1022000E000200DF160 -:1048300013058DF823000DF123000DF1030208216B -:104840002B460AF089FC0C956368207809A90DF1C4 -:104850003702FFF71DFEB95D01F0F801B95511B03F -:10486000F0BD704770B586B0274C2848217801AA62 -:104870000BF028FA002004218DF80A008DF80800BA -:1048800000200FF0EBF822490D78A8421CD211F05D -:104890007FFFC8B91F48068836B1032004210FF0F6 -:1048A000DDF8A91B814202DD01208DF808001A48BD -:1048B000068836B1012002210FF0D0F8A91B8142F1 -:1048C00002DD01208DF80A002278104C01A8214653 -:1048D0000AF02DFF452021460DF0D0FB0F4810496E -:1048E0009DF80A200078097808409DF808101143C7 -:1048F00018BF012108408DF817000DF11701412064 -:104900000DF0BCFB06B070BDA92700200887002071 -:10491000E6BC0200C0BC0200C2BC0200F4240020BD -:10492000872700202DE9FE4329482C4E4FF0000830 -:104930000DF1040900240778BC421FD2E0B211F047 -:104940003BFFC8B1054600790138022814D3E87945 -:10495000411CE97196F8671088420DD92888A5F89E -:1049600009800DF0ABFF2888494611F037F848461A -:104970000AF092FA0EF07EFC0134DDE715484FF69E -:10498000FE774FF0000800F10C04134805788DB154 -:1049900034F80C0CB8420AD021784A1C227096F8E0 -:1049A0006720914203D9A4F805800DF087FF1C34DD -:1049B000013DECE70A490020032808BFBDE8FE835B -:1049C00011F8202012B1013A01F820200130F3E75C -:1049D000E6BC0200DC5B0020D5BC0200407B00206E -:1049E000348700202DE9FC412A4D95F8610000280C -:1049F00044D000240026602C40D095F86100F0409F -:104A0000C00702D120340136F5E7112095F8618006 -:104A100000FA06F714F092FD95F86110B94385F895 -:104A2000611015F037F8281928D0817A31B3102198 -:104A3000194A2C59B14011EA080190F9091052F8AD -:104A400021804668CFB209D006F006FB002079B27B -:104A500000224FF00073009020460EE0017A0229F8 -:104A600002D1C17CC90601D406F0F6FACDF8008067 -:104A700079B2204600224FF00063B04795F86100FC -:104A800028B106480021BDE8FC4115F0E3B8BDE8B7 -:104A9000FC8100BFB87B00209430044028800020B7 -:104AA0002DE9F84F82462948007888429CBF0520AE -:104AB000BDE8F88F50460C46009208F0CDF9074645 -:104AC00023484FF6FE7C0078874215D14FF6FE70E2 -:104AD00008F0C2F94FF6FE7CB8420ED11D49002005 -:104AE00001230A78BB4208D211F8335095423CBFEB -:104AF00018462A460133F5E73846DFF858B0C6B203 -:104B00000BEBC609C84628F802CF454655F8020FF8 -:104B100018B115F087F8002028604CB167003846BE -:104B200015F082F8286070B100993A4614F030FB15 -:104B30000948A8F800A089F8014000780BF8360071 -:104B40000020BDE8F88F0120BDE8F88FDBBC020033 -:104B50009ABC0200E0270020CE2700202DE9F84370 -:104B6000994616460F4604460FF004F818B16FF048 -:104B70000100013007E02548089D017820460EF02D -:104B800095FD18B1204680B2BDE8F883204600218B -:104B90000CF004FC294605F063F978B380464079AF -:104BA0004FF6FE75042816D001281FD198F806107C -:104BB000B8F8020011F0180F10D01549B842097862 -:104BC00088F8041018BFB0421DD1384631464A4615 -:104BD000F7F786FD06E04FF6FE70D4E70D49097D34 -:104BE00088F80410A842CED198F80500022805D014 -:104BF000204607210EF05AFD0028C3D12046BDE80B -:104C0000F84313F069BA4845DFD0EBE7D0BC0200A7 -:104C1000DCBC0200407B0020F8B505680446D5F8EE -:104C2000F80000B1F8BD68796668022807D105F17F -:104C3000D000694612F0E4FCC5F8F80009E0D5F8A8 -:104C4000EC10D5F8FC20D5F8F4001144C5F8F800B4 -:104C500000910028E6D031688A6B22F400628A63F2 -:104C600095F84410C90608D52F6C37B1AB6C2046B7 -:104C700010210022B847D5F8F800B0F5806F84BF46 -:104C80004FF48060C5F8F8000099336B01444A1E68 -:104C90003168B66B1A600E4A9A6043F6F07202EB06 -:104CA000001010409A6810439860D5F85801406889 -:104CB000006886620846022113F078FE287A0028F0 -:104CC000B0D120460121012612F0B9F82E72F8BDAC -:104CD000018000C0BFB523490020234D0022086099 -:104CE0002249C5E9020008602149087001212970A4 -:104CF00020490D2A03D041F822000132F9E71E486D -:104D00001E4901601E484DF2F02101601D481E49F8 -:104D1000016001202871286900B1BFBD01AC2046A7 -:104D200014F0C5FD00200121224602908DF80400F8 -:104D300016480EF019F9286114F04CFF0028ECD148 -:104D40002C78002C1CBF4AF20034C1F2E11414F09C -:104D50003BFFB4FBF0F1286914F03EFF286914F022 -:104D60003DFFBFBD14880020B82400201C8800200F -:104D7000A0880020488100200C880020F824010031 -:104D80001088002018880020905F010099C1010060 -:104D90002DE9F04F85B0264801ACDFF89C80DFF8A4 -:104DA0009CA04FF00109251D00F11C062148077841 -:104DB000D7B316F818BCABF10100012831D8306820 -:104DC00030B156F8041C02311CBF0138306028E0B5 -:104DD000D8F80020C2B19AF8000030B1184951F853 -:104DE0002000C0EB0010810001E01548016836F892 -:104DF0001C0C9047BBF1020F08BF012804D11149D8 -:104E000036F81C0C0968884736F81A0C8DF804909F -:104E1000ADF8100020460BF077F810B128460AF0E4 -:104E20003BF8013F2436C3E705B0BDE8F08F00BF73 -:104E3000B0540020E6BC020094230020C7270020C5 -:104E400060B702009C23002070B52C4D00282B6811 -:104E500041D0044643B9FA2014F0E6FE0028286049 -:104E600049D0002101702B68187815262178082276 -:104E700010FB0630417061788170A178C170E178D3 -:104E800001712179417161798171A179C171E179F2 -:104E90000172217A4172617A8172A17AC172E17ADA -:104EA0000173217B41730E3004F10D0114F070F990 -:104EB00028680178013101702B68187800FB06F131 -:104EC000E52918D3012110FB061014F03BFD2868DA -:104ED000002101700FE073B1187838B1012115225B -:104EE00010FB021014F02EFD2B6823B1184614F0AD -:104EF00099FE00202860002070BD00BF44270020DC -:104F0000F0B585B070B1044628480D46C08AA0426D -:104F10000AD113F075FE2649284612F0C6FB80F030 -:104F2000010602E000263AE012260020ADF8064015 -:104F30008DF8040001AF384604F00CF858B104377E -:104F4000384612F053FF012805D12846394612F0A1 -:104F5000ACFB80F001061748007818B3122E08D178 -:104F6000012806D12046294605F0F8FA002818BF86 -:104F70000026204629460AF02BFB0A280AD0A02842 -:104F800006D1204629460FF0E5FE204609F02AFF0B -:104F9000012E04D12046002110F0CEFE012630461D -:104FA00005B0F0BD122EDDD0E3E700BF407B00204E -:104FB000C887002018260020B0B588B00446407984 -:104FC0008DF81C0020798DF81E00274800788DF898 -:104FD0001F00206820B312F009FF08B32348002502 -:104FE000007801282AD820680DF1120110F00DFD7B -:104FF000BDF812004FF6FE71884208BF6FF037050A -:10500000A179F1B96FF00201013189B2884218D05B -:10501000ADF8140001208DF81D002068069009E00D -:1050200000208DF81D0013F0EBFD06906FF00200DC -:10503000ADF8140005A803F08BFC0546E8B208B0F3 -:10504000B0BDADF80400607901218DF810508DF8E5 -:105050000E1021688DF80F0001ACA01C14F08FFD1C -:10506000204614F0CDFDE9E7CD27002018260020CA -:1050700010B5017801290DD0022921D0FD2934D0A5 -:10508000D32939D01A29BDE8104018BF03F022BA3D -:1050900002F0B0BE2248007802282CD11D4C2078A6 -:1050A0000138012827D814F05DFB48B3FCF79EFEB9 -:1050B00008B32078022823D1BDE8104004F0D0BF07 -:1050C000144800780138012815D8134800780728BB -:1050D00018BF082805D11149097811B90121EFF746 -:1050E00059FBBDE81040F1F7D1BF0E49096811B175 -:1050F000BDE81040084710BDBDE81040FEF7ACBE4B -:1051000014F060FB002814BF01200020BDE810400F -:105110000BF012B81826002008880020BB88002059 -:10512000C4260020D82400202DE9FC470B9C8DF8D4 -:1051300007001E461746884604EB840000F1040968 -:10514000012050FA89F014F06FFD00283FD082460C -:105150000A9A0C980023514601F8017F8A700A1DB3 -:10516000CC704E70DEB2A6421ED20678167046781B -:105170005670467906F007069670877917F0180F73 -:105180000AD07D07C7F300174FF0060558BF022568 -:105190003D4446EAC505957085780133D570C578DC -:1051A000083015710532DDE70B4D5FFA89F30DF11B -:1051B000070048F23202696041460AF02DF90446C0 -:1051C000504614F02FFD05480130686000E01024BF -:1051D0002046BDE8FC8700BF7C260020DC7D002047 -:1051E00070B58EB02A4E044601200DF103018DF8F2 -:1051F0000300B068D0F830245220904700252821C1 -:1052000084F82050657501A80C3013F05DFE43F65C -:10521000FF702146ADF80B502546ADF82A000F204F -:105220008DF828002068019031F8040FADF80800CF -:1052300015F8060F8DF80A002089ADF80D00A07A48 -:10524000002818BF01208DF80F00E07A002818BF51 -:1052500001208DF81000207B002818BF01208DF858 -:1052600011000C48007801280AD1B068D0F8302429 -:1052700050209047B0682946D0F83024E12090476C -:10528000B068D0F8281201A8884700200EB070BD81 -:105290000C010020182600202DE9F0410C460804DE -:1052A0000AD460045CBF0020BDE8F0810FF012FA60 -:1052B00084F48040BDE8F081244F387809F0C6FBC3 -:1052C00000283FD005460078A0F12301022917D21B -:1052D0000C2011F0C9FE90B306460020C6E900007C -:1052E000B06005203070E878A9783171707114F0E1 -:1052F0009BFCB06018B3EA78696813F049FF1EE0C0 -:1053000027281CD1082011F0AFFEA8B106460120C5 -:1053100005F10108307098F80000033014F084FCA7 -:10532000706048B198F80010CA1C414613F030FF75 -:105330007878314609F0B8FE284612F093FD2846E9 -:1053400012F090FD84F40040BDE8F0817227002047 -:10535000B0B50446007D012805D0152803D02528C6 -:1053600001D035281FD1217E0A071DD4254D617833 -:10537000A868D0F8D42092F8822072B11B290CD1F1 -:10538000E868816A01208847A868D0F82C134FF498 -:105390008060884700216170A868D0F830232046DB -:1053A000BDE8B0401047217E4A060BD4152801D035 -:1053B000012801D109070FD4617879B11B290FD1D8 -:1053C000232013E00F488068006D016819B16078F0 -:1053D000BDE8B0400847B0BD312007E00D2100E036 -:1053E0000E21084A926852F82110085C2070054886 -:1053F00021468068D0F894000078BDE8B04009F0FC -:1054000053BE00BF0C01002070B5284D2878052838 -:1054100039D8022837D0274C0420254E2070264842 -:10542000B268417801314170D2F8D400C9B290F825 -:105430002430994204D9E120BDE87040FDF74CB911 -:10544000297804290BD1D2F8B8100A780AB3C96CAC -:10545000F9B102208847B0682978D0F8D400174AFB -:1054600090F8310013780133834238BF184610702A -:10547000052908BF70BD032914D183202070BDE821 -:10548000704013F07BBA0A488068D0F84C0580471A -:10549000C1E70A4990F831000A780132824238BFE8 -:1054A00010460870BDE87040FDF728BFB78800209F -:1054B0000C010020B488002021260020B58800209F -:1054C0007FB5244C2448254E254D012101226065DD -:1054D00030680368284698473068012142682846AA -:1054E000904713F06FFA1F48082200F12001204670 -:1054F00013F04EFE1C4900200A5C235C934207D146 -:1055000001300828F8D113481849082213F040FE4A -:1055100004F1080005F0ECFCA16809B100208847FF -:105520000C4806F019FF0CF011FC01AC204614F0F9 -:105530004FFA0F4D0020002122468DF80400284626 -:1055400012F06EFF0B48056013F0DAFF002004B084 -:1055500070BD00BFD42000204F9B0200D801001076 -:1055600000400340A87F05005CBC0200F012005020 -:10557000248500204888002070B5012953D00446B6 -:10558000002942D128480121057A01722021EFF338 -:10559000118681F3118894F82010032916D002296E -:1055A0001BD0012929D12168E26C63681960616808 -:1055B000236859601168914204D1A169C26822EA46 -:1055C0000101C160606AC0B1C0680FE02068616815 -:1055D000086060682168486012E0616A69B10A6821 -:1055E000C8684B681A604A6809684A6028B101684F -:1055F0004268116041680068416020460EF056FE26 -:1056000086F3118828460EF005F9216B481C0AD054 -:1056100006480029406818BF08464368D4E90A21B3 -:10562000BDE87040184770BD38220020A01F002040 -:105630002DE9F0418CB0DFF8A8800446D8F80800C6 -:10564000D0F83C03804708B1FC2045E001AD21467D -:105650001122284614F054FBA07D618A667C677D88 -:105660000B228DF81A00B4F81700ADF8161004F1EB -:1056700019018DF815608DF81970ADF81B00606A7E -:105680000A90D8F80800D0F8D40090F853008DF8AC -:10569000180005F1190014F033FB56B100200B90EF -:1056A00087B107EBC700800014F0BEFA0B9048B931 -:1056B00011E0812014F0B8FA0B9060B18121FF2233 -:1056C00013F0FCFBD8F80800D0F8442301A9072008 -:1056D0009047002000E01A200CB0BDE8F08100BF28 -:1056E0000C010020F0B581B040F2A416C1F2000612 -:1056F000F06B0125016801208847012849D03068F6 -:105700004AF20007C468C4F20C0738463C21012263 -:1057100000230025A047E0B338884AF20445C007BB -:10572000C4F20C050AD14FF00120286038884FF6EA -:10573000DC60CFF6FF703058804708E04FF6DC6041 -:10574000CFF6FF70305880474FF08070286042F2EB -:10575000300048F2D072C4F20900C2F200020068C0 -:1057600048F2D4711268C2F200010860801A47F64C -:10577000B432C2F2000244F240211368C0F20F01B9 -:105780004843A3EB93010125B1EB104F98BF010CE7 -:105790001160284601B0F0BD70B513F011FF13F091 -:1057A00087FF13F08BFF044600F00C000C2803D198 -:1057B00000BF00BF30BF3BE060071ED40DF07EFA93 -:1057C000054600EB800001214600012012F03EFC5E -:1057D000864212D91C4CA5F11800606104F10C003E -:1057E00013F07FF900BF00BF0120F6F777FD00BF7F -:1057F00000BF002084F820001CE000BF00BF20078D -:1058000015D40E4E0E4D306881682846884704280E -:10581000F9D0B0FA80F004F01001400940EA11100C -:1058200014F006FA074801210160006800E030BF6B -:1058300000BF00BFBDE8704013F0C8BED801001023 -:10584000004003402C200940D81B00202DE9F041E6 -:10585000264F05463E1813F071FE044696F84A019D -:10586000013886F84A0100063AD1214800EB85014B -:1058700010F825804E885FEA08600DD45FEA486022 -:105880001FD41C48006881693046884730460CF0B8 -:1058900019FA0228FAD11AE0164F3868016A304620 -:1058A00088473868816A304688473868016B3046D7 -:1058B0008847114801210160104801688907FCD51B -:1058C00005E007EB8600D0F8601100208847A5F1BD -:1058D000120010F1060F03D808F03F00FFF7B6FFE3 -:1058E000204614F0D7F80020BDE8F081D81B002036 -:1058F00046B60200B80100102820086028200840A1 -:105900002DE9FF4726480DF1040A00270AF1040497 -:105910000397CDE9017790F800902248C84600F13E -:105920003906FDB24D4510D20720294600220C232E -:10593000CDF800A010F02EFD30462146082212F0CE -:1059400077FB08B90137ECE7B846002300214D4545 -:1059500028BF012101980028024618BF01224D45A9 -:1059600038BF01231343012B18D10F4B1C78ACB95E -:10597000114000F2E2404FF00101019019700B4913 -:10598000086018BFA9F101085FFA88F101AB072090 -:105990000C2210F015FD064800210180BDE8FF87AC -:1059A000D7BC0200407B002085270020082500206E -:1059B00004250020BFB590F91910B1F1FF3F00DDBB -:1059C000BFBD017D0429FBD8012202FA01F111F0CB -:1059D0001A0FF5D0234DA968D1F89810098911F054 -:1059E0000A0FEDD040684178C1F3810103298DF899 -:1059F0000C1008D002290AD1B0F80510B0F8034005 -:105A0000ADF8041003E0411D01A814F0B8F813F03C -:105A1000A1FD28B1A1B201A801220FF085FABFBDF6 -:105A2000E868A4B22146426F01A890471E2800D022 -:105A300068B901A8214601220FF076FAE868006DE6 -:105A40008047FE28BCD1E868416D002007E0E86887 -:105A5000006D8047FF28B3D1E868416D0120884779 -:105A6000BFBD00BF0C010020B0B52B4CA068416940 -:105A70000A7EFF2A4DD0D0F8D43093F88330022B21 -:105A800012D1D0F804054D698047A1680A69CB6B33 -:105A9000D1F8D41091F82C1032F811101A89104452 -:105AA000281AA0EB01102CE08B7EA3B1022A12D1A0 -:105AB000D0F804058047D4E902124B695268D1F846 -:105AC000D4101B6912780979C01A6FF007039A1A6B -:105AD00012FB010015E0D0F804054D698047D4E9B8 -:105AE00002120B69CC6BD1F8D41091F82C1033F85A -:105AF0001110238918444418D2F8B4008047204478 -:105B0000281A002805D44FF6FF71884238BF014695 -:105B100000E0002188B2B0BD0C0100202DE9F04169 -:105B20002A4B012702462024187A1F72EFF3118CAA -:105B300084F3118854698C4202D18CF3118840E0BF -:105B40001D6A8F40002905EBC10648BF03F12C06F2 -:105B500048BF002792F82050012D26D1D2F800E04E -:105B6000D2F84C805568C5F800E0D2F804E015681A -:105B7000C5F804E0D8F80050454505D1D2F818E042 -:105B8000DD6825EA0E05DD609D699542354601D147 -:105B9000DE613568D5F804E01560C2F804E0CEF89F -:105BA00000206A60DD683D43DD60D6649761516125 -:105BB000B1F1FF3FDCBF0021D961012119748CF3E1 -:105BC00011880DF027FE2046BDE8F0813822002024 -:105BD0002DE9F84F0546007D1E4690460F463830A9 -:105BE000C0B211F041FAC8B304460D9829461C22F0 -:105BF00000900120DDF830A0DDE90A9B207004F15F -:105C00001C0013F0C5FAA01C39460A2213F0C0FA92 -:105C10000020A4F80C8084F813B084F81890C4F81D -:105C200014A0E0620098607630782074B6F8010025 -:105C3000A4F811002A7D6889E0812AB104F13800B6 -:105C4000E062296913F0A4FA607F800708D00A484F -:105C50000168204659B1BDE8F84F0847BDE8F88F04 -:105C6000064821460078BDE8F84F09F01DBABDE8A6 -:105C7000F84F12F0F7B800BFF826002095880020F2 -:105C80002DE9F04F89B04FF0000B04461421CDE907 -:105C900002BB04AD284613F017F924484FF0FF0A61 -:105CA00005F108094FF000088DF820A0061DB8F195 -:105CB000C80F34D01FFA88F7042014222B46394627 -:105CC0000AF054F838BB44B113F0B6FC86F805B0BE -:105CD00046F804BCC6F800B01DE004203946002296 -:105CE0001423009510F056FB484602A9082212F032 -:105CF0009FF940B901207071DDE904010B3031607A -:105D000046F8040C049013F097FC2846142113F075 -:105D1000DBF88DF820A00C3608F10108C7E714B1B4 -:105D200000200DF063FE09B0BDE8F08F8043002035 -:105D30002DE9F041254E0546371813F0FFFB0446C8 -:105D400097F84A01411C87F84A11C8BBDFF88080E8 -:105D5000A5F1120010F1060F18F8257003D807F00E -:105D60003F00FFF7E5FF08EB8500458838060CD4B7 -:105D700078061FD417480068416928468847284696 -:105D80000BF0C2FF0128FAD11AE0124E3068C16947 -:105D9000284688473068416A284688473068C16A83 -:105DA000284688470C48012101600C480168890792 -:105DB000FCD505E006EB8500D0F86011012088478E -:105DC000204613F067FE0020BDE8F081D81B0020BC -:105DD00046B60200B80100102820086028200840BC -:105DE0002DE9FE4FDDF830800E9E92460C460F21C5 -:105DF00006EB080201EB4201C9B2502984BF102012 -:105E0000BDE8FE8FCDE9011020489B460F9FDDF8CD -:105E10003490456813F0C8FBA0421CBF0220BDE8C7 -:105E2000FE8F25F8024B12F0EBFE0146284613F0D8 -:105E3000A6FE4FEA1B2180F8038080F801B0817034 -:105E4000DDE9013100F804ABB8F1000F09D019F811 -:105E5000022BA8F10108027019F8012C42700230DF -:105E6000F2E700F8026B4EB117F8022B013E00F882 -:105E7000012C17F8012C00F8022BF4E7034820222C -:105E800003B0BDE8F04F09F0C7BA00BF7C26002080 -:105E90002DE9F043844608981C460625034405EB8B -:105EA0004303DBB2502B84BF1020BDE8F083234DA9 -:105EB0009CF80880DDF824904FF6FD7E6F68079D02 -:105EC000B8F10F0F02D0B8F1020F08D10EF102069F -:105ED000BCF80080B6B2B04508BFACF800E0BA70BC -:105EE000120A3C71FA700EF1020292B2914208BF9E -:105EF000714607F8051B090A07F8041C4CB144B1A8 -:105F000015F8021B013C397015F8011C7970023735 -:105F1000F5E7387058B1791C48B119F8022B0138EF -:105F200001F8022B19F8012C01F8012CF4E70348C1 -:105F300061460622BDE8F04309F06EBA7C260020D7 -:105F4000F0B585B0294E0446B068D0F8FC11204663 -:105F5000884788B9B068D0F82C112046884758B9CE -:105F6000607C40B1271D97F8300020B9B068D0F8A8 -:105F7000B810097849B100206070B068D0F84411B9 -:105F8000204605B0BDE8F0400847D0F8342207F1BC -:105F90000E01092090470028EDD00546B068F91D94 -:105FA000D0F83024E7209047B06804F10801D0F819 -:105FB000302450209047B068B91DD0F83024E1203B -:105FC0009047022023894FF6FF728DF810004FF0A2 -:105FD000FF30ADF80800B068D0F8C061A07A00903A -:105FE00002A92846B04705B0F0BD00BF0C01002053 -:105FF0008B4208BF824207D9009A002A01D0106064 -:106000005160002100207047002B08BF002A10D1EA -:10601000009A002A01D01060516002000B0000219C -:106020000020002B08BF002A1CBFC943C04301F059 -:1060300040B9F0B51C4615460B460246002000212B -:10604000B4FA84F6202E04BFB5FA85F62036B3FAEA -:1060500083F7202F04BFB2FA82F72037F61BB6F180 -:10606000200727BF05FA07F400257F42B4403EBF52 -:1060700025FA07F73C43B540A34208BFAA4201D323 -:10608000521BA341404149416D0845EAC47564086B -:10609000761EF1D5059F002F01D03A607B60F0BDE0 -:1060A000FEB50D46C9890446A1F50040022812D369 -:1060B000132920D048F20402B4F90400914206D119 -:1060C000A18C052903D80221A1844021A180B0F12F -:1060D000FF3F1ADDFEBD284608F04AF80028F9D037 -:1060E0000446007818B9E989204607F06DFD20467E -:1060F00013F098FDFEBD6C462846214612F032F89A -:10610000698820460CF0B7F9FEBD94F824000130F0 -:10611000C6B2304613F088FD0028DBD00546A079D2 -:1061200027792870E0796870A81CA28CA16A0131D7 -:10613000013A13F02DF847F08001452032462B46F6 -:106140000CF09CFA2846BDE8FE4013F06BBD70478A -:106150002DE9FF478146284888460024002690F80C -:1061600000A054450BD2E0B20FF000F828B105466C -:1061700040790644F7B2B94503D30134F1E7B320BF -:1061800037E04046182112F09FFE6979A9EB07001D -:106190000844C0B205EB4000C088A8F80A0012F01D -:1061A0002FFD0146404613F0EAFC6878012806D12D -:1061B000012088F814006888A8F80C0012E06888AC -:1061C00001A90FF09DFF68B19DF80C1008F10C00BB -:1061D000032988F8141019BFBDF80410018001A923 -:1061E00013F0CDFC2878297988F80800002088F879 -:1061F000161004B0BDE8F087E2BC02002DE9F041C2 -:10620000002918D41F4615460E46044612F03EFDDE -:1062100080462046314680220BF0FEFD20B1064626 -:1062200090F9330000280AD4404613F017FD0021EE -:106230000220BDE8F08100200021BDE8F081D6E910 -:10624000080145F00A0547F0E04728403940084377 -:1062500010D0404613F002FDD6E9082303EA0701F7 -:1062600002EA050042404B40C4E92C01C6E908237C -:10627000BDE8F081B1680B48814203D0B168C4F831 -:10628000A810B0604046C4E9285713F0E7FC04F1B9 -:1062900050004FF0FF3113F073FBD4E92C01BDE83F -:1062A000F08100BF8DDC0100F0B589B017460C46C7 -:1062B00005460DF05FFC18B10026304609B0F0BD70 -:1062C0002846002100260BF069F8394603F0C8FD86 -:1062D0000028F2D007468079C007EDD0204612F0A2 -:1062E00055F9012818D10420ADF816408DF8140096 -:1062F00005AF384602F02EFE01260128DDD1002030 -:106300003A1D2146CDE90000CDE902061048037888 -:10631000284600F065FBD0E7B8794007CCD513F0EC -:1063200043F9A0420CD100202146CDE90000CDE97F -:10633000020005A8021D06480378284600F050FB1D -:10634000B87981075CBF00F0FB00B8710126B4E7A3 -:10635000CFBC02007CB5284E04460D460DF1070166 -:10636000B068D0F828244F20904712F0E9FE0428A6 -:1063700009D1A5B121494FF47A72600113F0D8FA1E -:1063800000F53E702DE012F0DBFE68B1ADB11B49A7 -:106390004FF47A72E00013F0CBFAF83021E04FF4BA -:1063A000867000EB44101CE05DB114494FF47A7222 -:1063B000600013F0BDFA263006E0602000EBC40058 -:1063C0000FE0102000EB44009DF807104FF0FF3263 -:1063D00002FA01F1F268C94352681278083202FBEE -:1063E00001000C21122C88BF28210844034980B2E7 -:1063F0000978484380007CBD0C010020B088002053 -:106400002DE9FF4121480026DFF8888006602048FA -:1064100006604FF47000C8F800001F4806701F485F -:10642000067013F094FA1E4F0446386840B113F01A -:10643000D1FB10B1386813F027FB386813F066F809 -:1064400001AD284613F033FA164801212A46029678 -:106450008DF804600CF088FD386028B91248806817 -:10646000D0F84C058047386813F0B8FB204613F08D -:106470004AFB0D488068D0F814150F208847D8F8DB -:10648000000004F099FABDE8FF8100BF2C880020CD -:10649000388800203C8800208C880020B2880020AA -:1064A00028270020CD5702000C0100202DE9F041E3 -:1064B000806A224A0121012584784678512014708F -:1064C00013F0A4F91E4805701E484EF660250EB163 -:1064D000203007E01C490978002914BF00EB810037 -:1064E0004FF47A75194906684FF480400F780021FF -:1064F000F5F712FADFF85880022198F8000008F04A -:1065000077FA06FB05F0B0FBF7F2E0070AD1A00727 -:1065100058BFBDE8F08198F800000221BDE8F041C5 -:1065200013F0E5BA4FF480401146FEF7D7F84FF468 -:1065300080400121BDE8F041F5F7EEB9CC270020FD -:106540009727002060B70200C2270020C127002043 -:10655000988800202DE9F04F85B0814680690DF1C3 -:10656000120200214FF000080778A32008F068FC11 -:10657000BDF91200D0FA57FB1FFA8BF0032828BF91 -:106580004FF0030B5FEA0B4016D00BEB4B00C00043 -:1065900080B213F049FBA8B182465FFA8BF5002464 -:1065A0000646AC420CD257FA84F1A220324608F0DB -:1065B00047FC01341836F4E74FF0000B4FF0000AA7 -:1065C000002204E0B5224FF0000B4FF0000A99F8CA -:1065D00011005FFA8BF19DF81230CDE902A8CDE9E8 -:1065E000007109F10201FDF731F8BAF1000F02D094 -:1065F000504613F017FB05B0BDE8F08F70B586B0BC -:1066000085690446284611F0F1FB30B112F0F8FA22 -:106610000146284611F049F828B120480178D1B345 -:106620000020049003E01D480495017828460229C3 -:1066300004D11B49A28B498B8A422CD1217B51BBAF -:10664000297A00268DF81660CA094DB28DF81520FA -:10665000C1F38012002D8DF8142005D420B94FF419 -:1066600000500121F5F758F904A8FEF7A5FC8DF8B4 -:106670000F000DF10F00A11C48F234020123CDE9F7 -:10668000000604F111000AF0CDFF002D03D4049898 -:1066900008B912F091FB06B070BD00BF18260020AB -:1066A000407B00202DE9F04F85B0814680690DF1D7 -:1066B000130200214FF0000807789D20FBF77CFCB7 -:1066C0009DF81300B84225D9A0EB070A5FFA8AF0BB -:1066D0000A2828BF4FF00A0A4FEACA00C0B213F0D6 -:1066E000A3FAB8B1834600245FFA8AF50646E0B201 -:1066F000A84213D257FA84F18B203246FBF75CFC98 -:1067000070790138C1B2032928BF0320707108369F -:106710000134ECE74FF0000A4FF0000B99F811003C -:106720005FFA8AF19DF813300022CDE902B8CDE975 -:10673000007109F10201FEF7F7FCBBF1000F02D076 -:10674000584613F06FFA05B0BDE8F08F2DE9FE4F03 -:10675000DDF838908DF80B0001209B4614460D465D -:1067600009F10A0650FA86F013F05EFAC8B30195F3 -:1067700005460746DDE90C8A594605F8014F681CB5 -:1067800013F0BBF94FEA1A21B9F1000F80F8049019 -:1067900080F802A080F80080C1704FEA1821417093 -:1067A00004D00F9905304A4612F0F2FCDFF83C8025 -:1067B00010980199F3B248F2380288F802000DF1FE -:1067C0000B00C8F8045008F027FE0446384613F0C2 -:1067D00029FA002088F8020005480130C8F80400B2 -:1067E00000E010242046BDE8FE8F00BF7C2600207C -:1067F000DC7D002070B5044613F0A9F824498860B8 -:10680000A0070A4604F1080020F0030008BF201D7D -:10681000112828BF04321368002400221D68B5F136 -:10682000FF3F07DD54B116682E448642166012D22F -:106830002E4608E085F00046002404E0854208D298 -:1068400001242E461A469D593344002DE7D10024D9 -:1068500019E01A462E46002AF9D0331A042B08D321 -:10686000135040F0004313600A4B5C68201A5860D4 -:1068700008E0084B10685C68201A5860106840F007 -:1068800000401060141D886813F03DF9204670BD6B -:10689000D02500204425002010B586B00146427E58 -:1068A0008068002343F606040593CDE90333029381 -:1068B000438003881C1B022C10D3B3F5C15F03D0A7 -:1068C00040F60204A34212D1038A002A23F4FE6395 -:1068D00012BF038243F43472028208E0038B23F474 -:1068E000FE630AB1038302E043F4347202830022A0 -:1068F0004A7602A9009105A904AA03ABF8F77EFF26 -:1069000028B105984FF6FF71008888420ED0049C8C -:106910000299204606F06CFA0748016821B120462A -:1069200006B0BDE81040084706B010BD049C0299AF -:10693000204606F029FEEFE77426002070B50C46CD -:10694000214900228D1D214909788A4210D2C37C39 -:106950006E789E4207D1838935F8066C9E4202D13B -:1069600015F8043C13B908350132EEE78A4201D12B -:10697000002070BD287828B31548818C20460EF081 -:10698000B5F910B12878013828701248011D124855 -:10699000007802464AB10B78FF2B03D031F8043C53 -:1069A000A34204D02431013AF4E7297802E029789F -:1069B00001392970094AC9B21278104488423CBF93 -:1069C00000202870012070BD42760020D2BC020059 -:1069D000407B0020B0540020E6BC0200D5BC020081 -:1069E0002DE9F84F0B9F05460220DDF834B099469B -:1069F00090460E4607F1010ABBF1000F00EB4A007A -:106A000008BF02208DF8010068460FF039FFB8B3C7 -:106A100004460A9884F81A90A6806580E076A07FE4 -:106A200001280AD112F0C0FDB04206D0B8F1000F23 -:106A300006BF0020A077C4F8248005202169BBF19F -:106A4000000F087018D00C9881F801A08D1C00214F -:106A5000CAB2BA4208D210F8022B01312A7010F8DB -:106A6000012C6A700235F3E712F09EFD287012F0D7 -:106A70009BFD000A687000E04F70204607F02EFF73 -:106A8000BDE8F88F70B5274CA068D0F8D4204169D4 -:106A9000557B00224A77C16891F83020013281F895 -:106AA0003020C16891F83010042908D1D0F8640171 -:106AB0008047A068D0F86C01BDE870400047E068EE -:106AC000C16B20208847A268D2F8D40090F84F60AC -:106AD0000F2E0FD05169437B897F99420AD24173AF -:106AE000D2F8D400D2F81415407B8847A268D2F8B7 -:106AF000D40000E02E46407B4FF470718140D2E913 -:106B0000030390F8304033F816306400A340B3EB31 -:106B1000910F88BF8B08D2F8F024A1EB4301BDE8A8 -:106B2000704010470C0100202DE9F0418AB0204F41 -:106B30000DF108083868416E404688473868C06BD8 -:106B400080471C4C002502900595217BA060658044 -:106B500001F0F0010231217301218DF80C1012F0C7 -:106B6000EDFC064614480221154BC068806901708F -:106B700012483A680068176DCDE900152146424673 -:106B8000B8470546304612F085FFB5F1FF3F06DDF8 -:106B90000C4804600C4801780131017004E00320C6 -:106BA00041F2883104F084FB0AB0BDE8F08100BFF7 -:106BB00030880020642500200C010020D826002009 -:106BC000F1E201002025002019250020F8B5154626 -:106BD000044625480E461168D268AF690068002F48 -:106BE00018BF3846206321616261D5E9042100297C -:106BF00008BF4FF4007162B1D31D11444FF0FF3054 -:106C000023F007032063C91A21F00701C4E90A131E -:106C100008E00731082221F00701A1620CF018FEFC -:106C2000E062F0B1D5E9010104F13803EA69666375 -:106C300007C395F8200084F8480018B10B48416953 -:106C40000131416100206065204604F021FC08B15B -:106C50000230F8BD054804F1080111F0D3FB002013 -:106C6000F8BD0120F8BD00BF788800203822002040 -:106C7000BFB545680446287805380B2815D8DFE8E5 -:106C800000F006140C1415141414141B144220469E -:106C900004B0BDE8B040FAF795B9681C019060896E -:106CA000ADF8000068460DF0F7FBBFBD204604B00C -:106CB000BDE8B04011F045BC681C0DF10A010EF0B2 -:106CC00095F90128F1D150208DF80C0000208DF8A5 -:106CD0000E00207A09388DF80D0003A80CF0ACF8EE -:106CE0000028E2D00446BDF80A0005F10901227D22 -:106CF0006080087884F83800206912F049FA20464C -:106D000007F0ECFDBFBD204604B0BDE8B04010F078 -:106D10001BB970472DE9F04F8DB0169E1A9F0B904E -:106D20004FF6FF70ADF83010388086B11C4673B155 -:106D3000DDF86490B9F1000F09D0DDF85CB0BBF16B -:106D4000000F04D0DDF860A0BAF5005F04D9042577 -:106D5000E8B20DB0BDE8F08F0BA806AA214607F0F7 -:106D600047F905460028F3D11048806803F038FB46 -:106D700080460F48ADF814400496ADF80EA0ADF86B -:106D80000CB0CDF808901223C188C07802AA0092F6 -:106D900006AAF3F703FB054610B9BDF81C003880BE -:106DA00002484146806806F079FED1E7A023002022 -:106DB000A08000202DE9F84F002480460021002209 -:106DC0000460684602F092F9204DDFF884A0814605 -:106DD0004FF0FF374FF0190B0020602C1ED02A19FE -:106DE000917AB9B1107A022816D0DAF80400418BF2 -:106DF0000069084495F8621011FB0B0150690EF010 -:106E000060FE064612F0E0FEB6FBF0F0B84238BF76 -:106E1000074601202034E0E70120002709EA0001AD -:106E2000012904D10099B94238BF0F4606E0B9F1F3 -:106E3000000F01D0009F01E0C10701D0C8F8007029 -:106E400040EA090000F00100BDE8F88FB87B00209F -:106E5000D01E00202DE9F84F0546D1F800902348B8 -:106E600000268B46814588BF032612F067FBDFF8BA -:106E700080A08046DAF80440601B18BF01205AF851 -:106E8000207025B105F1B80012F0A4FE28B96FB149 -:106E900007F1B80012F09EFE40B19AF82400CAF83B -:106EA000205040F002008AF8240018E0601BDBF854 -:106EB00000104FEA9904B0FA80F0400940EA40001F -:106EC0000AEB800081609BF80810017412F07CFED0 -:106ED000B4FBF0F105F1B80011F024FC8326404624 -:106EE00012F0D8FD3046BDE8F88F00BF03093D0021 -:106EF00070200020F0B587B00546112012F094FEF6 -:106F0000002841D004463B2000211122234611F0E5 -:106F1000C1FF90BB2078A8422FD1112012F084FE2F -:106F200058B305463A20002111222B4611F0B2FF3A -:106F3000E0B93A201121224612F068FC1348144FA0 -:106F4000012180F8411078682146B0F1004F84BFDC -:106F50000020786001AE3046112212F019F97868ED -:106F6000182132460690822012F050FC284611214A -:106F700011F0AAFF284612F055FE2046112111F00B -:106F8000A3FF204612F04EFE07B0F0BD407B00206C -:106F90000425002070B524480C460078012801D84B -:106FA00060061CD420060CD4A0052BD420052ED4BA -:106FB00060055CBF002070BD05F0EAFF84F48060CE -:106FC00070BD04F0FDF808F01FF901200FF084FDFA -:106FD00003200121EDF7DEFB84F0800070BD134E2D -:106FE0003068F0B1808802F019FA3068056812F054 -:106FF00019FE3560ADB1EA882D686DB1E888801A58 -:10700000E880F9E702F0FAF884F4007070BD05F04A -:1070100053F884F4006070BD05484021007812F0F8 -:1070200069FD84F0400070BD18260020DC26002099 -:10703000998800207CB520480C46017029BB1F4868 -:10704000007802281BD109F015FF0CF0D5FAB0B179 -:107050001C21054611F038FF194E708B06F11C01FA -:107060002880A81C12F08BFD4AF60120A5F811001B -:1070700014480078013040082874B08C68811248A8 -:10708000007810B9032010F033FD1048016951B1A8 -:107090000B488DF80040C28A408BADF8040068466A -:1070A000ADF8022088470A48022102220023007816 -:1070B0000DF087F97CBD00BFBB880020182600209A -:1070C000407B0020D1BC0200C42600203C8300206D -:1070D00099880020B0B586B00589044612F064FA9C -:1070E000854212D10020ADF810006068039012F0C4 -:1070F000C8FC78B30179013903292BD840790121E3 -:1071000021EAD0008DF812002DE020890021ADF891 -:107110000C006068049001ACAB20224607F090FEA2 -:107120000DF103012046002202F044FA10480078D5 -:10713000012808D19DF8030028B900208DF814001B -:1071400003A800F039FA01208DF8140003A800F01C -:1071500033FA0BE0248812F027FA844206D100208B -:107160008DF81200039003A8FDF726FF06B0B0BD0E -:10717000B227002070B588B000266D460446202155 -:107180000672284611F0A0FE284621460B2211F077 -:10719000FFFFB4F80B0004F10E010A228DF80D6018 -:1071A000ADF80B0005F10E0011F0F2FFA07ECDF856 -:1071B0001A60ADF81E60C1071CBF01218DF81A10BE -:1071C000810744BF01218DF81B10410744BF0121F5 -:1071D0008DF81C10010744BF01218DF81D104106D8 -:1071E00044BF01218DF81E10000644BF01208DF818 -:1071F0001F000020ADF80C00208BADF818000448EB -:107200008068D0F8F41268468847002008B070BD46 -:107210000C010020F8B5D0E901650446287912F088 -:10722000E1FCD6F8CC206969286852681268D162FE -:1072300096F8F93013B9C368DB06FCD4436823F031 -:10724000020343602B69D3621943476A27F003079F -:107250004762C2F80415416921F001014161012131 -:107260000162D6E93512D6F8C00001604AB1EB6977 -:107270009B68C3F309139A4203D91144DA431144BA -:107280000160D6F8DC204AB16B6A9B68C3F309132E -:107290009A4203D9DB431A4411440160204609F0A5 -:1072A000B9FC287910F074FA2879BDE8F84012F09A -:1072B0009BBC70472DE9F04387B0C468DFF8889025 -:1072C00000264FF001081B2E11D0D9F8280008FA2B -:1072D00006F7384209D0A55D12F05AF9854204D963 -:1072E000D9F82800B843C9F828000136EBE7D9F8E7 -:1072F0002860C6B16C461821201D11F0E5FD012063 -:1073000000968DF8040000208DF8070099F82E00F3 -:107310008DF80500204607F023FC062089F826009A -:1073200007B0BDE8F0830020002189F8260041F273 -:10733000040007F0EAF9054801680029F0D0C420EC -:1073400007B0BDE8F0430847407B0020002500203F -:10735000BFB50FF0DFF904462148012100F10E020C -:10736000552012F04DFA04F0010418B914B10020B0 -:107370000FF0B2FB1B4DE220691C0EF053FE2046BD -:1073800005F00AFF0020CDE90200CDE900002878D1 -:1073900001280ED814486946102210F049FE18B191 -:1073A00068460EF03BF904E00F496846102211F0E0 -:1073B000EFFE6A466220102112F022FA2CB120B9A9 -:1073C0006A466220102112F021FA20460EF014FEC7 -:1073D0001CB1002001210CF077FA002004B0B0BDF0 -:1073E000CC2200201826002034BB0200F0B589B062 -:1073F000044640890E46010742D5800706D5607BCA -:10740000062803D0CD2E18BFF02E37D1207B0FF0E9 -:1074100003FCA8B3217B676905467EB108220FF003 -:107420000FFC70B16FB1428801780379B87895F894 -:107430000AC0CDE900C60BF03FF803E004220FF0CC -:10744000FFFBEFB178682168CDF80E00387A096A41 -:107450008DF81C00E86809780690787B8A09402935 -:107460008DF81D003878009538BF042200F04001E7 -:1074700000F0200302A8EFF711FF02E0E92EC5D0CB -:10748000002009B0F0BD704770B50546407D164636 -:1074900001220FF055F9C6B90446B0B1E87D94F861 -:1074A0003510884211D194F83910237A0A18287EB1 -:1074B0009A420BD2FF2817D1002084F8352084F897 -:1074C0003800FF208840C0B20EE070BDFF280BD10D -:1074D000E28BA07E94F82A1000230BF0BBFF20461D -:1074E000BDE8704010F014B984F8370084F8360015 -:1074F00012F06CFB054612F067FB68434FF47A719B -:10750000B0FBF1F00121208094F83A00608003483C -:107510000078BDE8704006F09BBD00BF3C2600200F -:10752000B0B586B0044601208DF814002046F9F766 -:10753000CFFA206918B11F48816820468847207D0E -:1075400058BB0020CDE90000029001208DF8020018 -:107550008DF80500D4E902010088ADF80000087D2F -:1075600009308DF804006846F8F730F89DF81400EB -:1075700098B903980E21406C0546013005F8091BA7 -:10758000A168496812F0FBFAE0680169027D2846AB -:1075900011F0FEFD68460AF0B1FFE06808B112F094 -:1075A00041FB204612F079F99DF81400207506B0D1 -:1075B000B0BD00BF50240020B0B586B00446002006 -:1075C000CDE90000029040F20910ADF804002088D7 -:1075D000ADF80000207A012812D121208DF8020098 -:1075E0001948007878B912F0B7F860B9174D61689A -:1075F000082205F1180011F0CBFD2088288002E058 -:1076000001208DF802006846F7F7E0FF9DF81400AE -:1076100050B903980721406C00F8011B616812F013 -:10762000AEFA68460AF06AFF0748007838B912F0E7 -:1076300093F820B905480021C0E9061101809DF8A2 -:10764000140006B0B0BD00BF182600205024002052 -:107650002DE9F04F85B02048DFF884A000274FF6D1 -:10766000FF7B007800901D48047801A8051DA74203 -:107670002FD007EBC7003AF82010594527D00AEB66 -:10768000800801208DF80400B8F80200ADF8100061 -:1076900001A808F039FCD0B1124EDDF80090B9F124 -:1076A000000F14D03088B8F80010884208D0BDF818 -:1076B0000610884204D0B11C28460FF0F6FF10B126 -:1076C000304610F02FFE1C36A9F10109E7E701371B -:1076D000CDE705B0BDE8F08FD5BC0200E6BC0200E6 -:1076E000B0540020DC5B00202DE9F0418AB0054653 -:1076F00020480078012839D81F4FF88AA84203D1C2 -:1077000085B30CF065FF2BE0284612F066F948B30C -:10771000044600790138012824D860884FF0000819 -:107720008DF81880ADF8240006AE304608F0ECFB6A -:10773000C0B1208811496D46088005F10B00311D4C -:1077400012F01DFA00200DF061FEADF814008DF866 -:10775000168028460222217902F042FAC4F80C80F1 -:10776000012004E0B98C28460EF035FA00200AB05A -:10777000BDE8F08118260020407B002074270020FF -:107780002DE9FC41204F0446786808B18047B0B32A -:10779000F868BA69610312F089F9012500282FD42D -:1077A0001A4904EB440001EB8006F07DFE2838BF47 -:1077B000451C1748F5750021042340EA0520019077 -:1077C00001AA20460CF062FA387018B903207076CE -:1077D000FF20B0750F4F12F0A6F800234FF0FF08FE -:1077E0000025B84712F09FF80123B84712F09BF824 -:1077F0000223B847102086F81880B08300E00B25DC -:107800002846BDE8FC8100BFA0230020A080002006 -:10781000FF000F96915D0200F8B50446FD201D465D -:107820008DF8030020461E68324600F025F910B19D -:1078300001208DF803009DF80300FD2815D1E068B4 -:10784000007B00F00F0002280FD176B13768204688 -:1078500031463A4600F010F920B9002F3E46F5D1E6 -:10786000002602E002208DF803009DF80300FD28A9 -:1078700004D1E06B10B104208DF803009DF8037073 -:10788000042F0FD0022F06D0012F0FD128462146FA -:107890000FF089FA0AE0326822B1284621460FF03B -:1078A0006FFA03E0284621460FF072FB78B2F8BD6C -:1078B0002DE9F843994615460F4606460CF0A6FFFB -:1078C0001E49DDF820800C78A04216D21C4900EB3E -:1078D000800201EB420212F8073FAB429CBF03203B -:1078E000BDE8F883B8F1000F24D000EB80001570DC -:1078F00001EB4000A0F804901CE04FF6FE70002160 -:107900000CF084FFA04204BF0220BDE8F883B8F168 -:10791000000F0FD00A4900EB800001F8107001EB56 -:107920004000FF2181710749C571A0F8049046808D -:10793000C97C01720020BDE8F88300BFD9BC0200F9 -:10794000D07E0020407B002010B505F087FD044666 -:1079500088BBFBF73FFDC8B111F026FE184908802F -:1079600020B91848018821F00701018016480078E5 -:10797000022804D001280BD11448007840B91548DA -:10798000002180F826101248032103E0092409E0B1 -:107990000F48012181700F4800F139010E4812F0A3 -:1079A000EEF800240D48002101800748007810B946 -:1079B00000200CF04BFA002C18BF0124204610BD0B -:1079C000708700202687002018260020D42700205A -:1079D000C4260020407B002096870020042500203C -:1079E0002DE9F04F87B080465868DDF840A08B46FF -:1079F0001F469146002100251B2906D020FA01F2DE -:107A0000D20718BF01350131F6E728064FF0000113 -:107A100014D0E8B212F008F990B1044607F108005A -:107A2000002100221B290CD07B68CB40DB0703D050 -:107A3000435CD6B20132A3550131F3E7002401E0E3 -:107A4000002400217B68BA78E8B2CDE900B902AD24 -:107A50000591084985E811044046FEF777FE2CB1F0 -:107A6000204607B0BDE8F04F12F0DCB807B0BDE823 -:107A7000F08F00BF7A87002070B5B2FA82F3B1FAB6 -:107A800081F45B096409B0B312B190F844506DB34E -:107A900089B191F844406CB3446B0E69096C056977 -:107AA0008908A408AE4214BFED6800252944611A74 -:107AB000B1F1704F22DAB2B1D168097B01F00F0148 -:107AC000022915D1516B0569006C14698008890879 -:107AD000A54214BFE26800221044081AB0F1704FAA -:107AE00001DB012804DB0124012304E0002302E080 -:107AF000012400E0002404EA030070BD00240029F2 -:107B0000C8BF0124002AF6D00129D5DAF3E770476F -:107B1000F8B5F0B10446007A00F0FE00022818D152 -:107B200020460D4600F03EFEFF281CBF1E20F8BD7B -:107B30001B49227A194B0846022A08BF18460668D4 -:107B4000002005280AD026FA00F7FF0703D00130ED -:107B5000F7E7E820F8BDC6B2052E05D1022A18BF06 -:107B6000032A0DD11A20F8BD022A0AD1228803EB7C -:107B700080012B0ACB728D720A72120A4A7206E0D9 -:107B800005202268636801EBC001CB608A60227A1D -:107B9000C0B201210DF028F80020F8BD08850020B2 -:107BA000E08100202DE9F84F204E214FDFF884803E -:107BB00000254FF0010B4FF002094FF0110A602D24 -:107BC00008BFBDE8F88F7C192ED0A07A01282BD1F0 -:107BD000607A41B20BFA00F01131C0B20BFA01F138 -:107BE000CA43326072681143716010F059FA04F1AF -:107BF000100000210EF00EF9812809D1A06920B1F2 -:107C000000210EF007F9812802D184F80A900BE0D8 -:107C1000607A97F861100AFA00F00843002187F8AB -:107C20006100404612F016F82035C8E708100440FD -:107C3000B87B00202880002070B5044610F068FA58 -:107C400041F288300DF0DEFF1A4D287801280BD85C -:107C5000194E4FF48071307806F0CAFE30784FF438 -:107C6000807105F02DFC2878022804D14FF40050D3 -:107C70000121F3F751FE012C15D1104803210224F4 -:107C8000104D817004700E48012101700E4805F1FD -:107C9000390111F074FF85F826400FF0E9FDBDE8C9 -:107CA00070400DF003BD41F28830BDE870400FF028 -:107CB000C5BA00BF1826002098880020C4260020DE -:107CC0009E880020407B00209687002080B51F48BA -:107CD000007860B111F05CFCEE281DD811F058FC62 -:107CE0001030C0B211F066FC194801211BE01948A0 -:107CF0000078082815D10FF01BFD09200FF0F8FEC1 -:107D000015480078072813D0052815D101200EF05A -:107D1000B5F903F055FA0FE00020BDE880400EF001 -:107D2000ADB90B4810210078BDE8804006F090B94D -:107D300007200121ECF72EFD08480078012818BF24 -:107D400080BDBDE880400FF08BBA00BFBB8800202B -:107D500099880020C426002008880020BA27002027 -:107D6000BCB50446807A01280CD1207B00218DF817 -:107D7000071060BB1D488DF80510007802281CD242 -:107D8000E07A1CE0258811F0FDFBE27A85420ED1F5 -:107D9000012A01D1207B07E01348008800F007008A -:107DA000022804D101202073FFF746FF16E0237B51 -:107DB0002088A11CFAF756FA10E002D100208DF8B5 -:107DC000040010F0F9FF01A809F05CF9207BFFF72F -:107DD00033FF0DF1070152200AF050F90448816980 -:107DE00009B120468847BCBD268700201826002000 -:107DF0003C830020B0B588B0044602208DF80A000C -:107E0000E08894F82420617EADF80200607D8DF852 -:107E100010108DF80C00A088ADF80E00501E8DF8E3 -:107E20001200A06A411C069100788DF81100608A4A -:107E3000ADF81400A08DADF81C00684604F0CCF835 -:107E400005460F48007818B169462046FEF728F924 -:107E5000BDF80E100B480023152B0BD030F8334023 -:107E60001A4601338C42F7D100EBC20041686846E4 -:107E7000884703E015B968460DF010FB08B0B0BDA7 -:107E8000DC27002064AE02002DE9F0418EB00546EB -:107E900011F054FBDFF88080044669681022D8F89E -:107EA0000800D0F808010068836B0AAF384698478D -:107EB000064638BBD8F80800D0F808010068016908 -:107EC00001AE304688470D206A6901978DF824007D -:107ED000D5E9020105926A8B0290288BCDE9031146 -:107EE0000790A88B8DF82500101A0890084406907A -:107EF000D8F80800D0E94112086811688A6931464B -:107F000090470646204611F0C5FD002E18BFE42616 -:107F100030460EB0BDE8F0810C01002070B51F4D59 -:107F2000A868D0F8B8100A781D4991F900101AB164 -:107F3000002902D41B49097811B1D0F84C058047BB -:107F400011F0FCFAEA68184C126921781278914213 -:107F500007D116490978490703D411F09BFD012088 -:107F600070BD11F097FD0EF04FF920780FF01AFA5E -:107F700078B1E86824780669204631780CF062F818 -:107F8000347030B1A868D0F8D40090F9420010F0F5 -:107F900092FDBDE8704010F041BF00BF0C01002011 -:107FA000B4880020A78800204C260020AD8800203F -:107FB00070B51C480025204C05701B4805701B48F7 -:107FC00005701B4885601B480570A068D0F800113B -:107FD000D0F85022C889103080B29047174E3060D8 -:107FE00020B9A068D0F84C0580473068A168D1F866 -:107FF0000011C989006085801031C1801048316846 -:10800000C0E900150CF0D6FDE068C068007800B14A -:1080100070BDA0680021D0F858240020BDE8704051 -:10802000104700BFAC880020BE880020AE8800202A -:1080300024250020AF8800200C0100207488002037 -:10804000C0870020B0B5234C0021A068D0F8E8001C -:108050000160A168D1F8D8000068B8B1D1F8E0207B -:1080600040681268904211DA0CF078F8A168D1F8F3 -:10807000D82012685368834204DA5060A168D1F8AE -:10808000D8000268D1F8E8000260A168D1F8DC00ED -:10809000006848B1D1F8E82013681BB15B684568F7 -:1080A0009D4201DA1060A168D1F8E800006848B18B -:1080B000D1F8E01040680968884203DABDE8B040B2 -:1080C0000BF07CBA0FF0D4FDA0680021D0F8E800D6 -:1080D0000160B0BD0C0100202DE9F041044680682C -:1080E0001F4F206297F85E00E8B197F85C00D0B9A6 -:1080F0001C480068006B8047DFF86C80D8E9105698 -:108100002A46334610F0E4FEA0FB052300FB0633AD -:1081100001FB0531C8E91221B9687B6DBA689A1A6A -:10812000411A91420CD90EF077F901212175A2680C -:108130001044E06097F85C0078B187F85D100CE0BF -:1081400001212175A2681118181A8242E16004D237 -:108150001046BDE8F04110F0BDBBBDE8F08100BFA6 -:10816000082000208C010010207C0020002840D036 -:108170002DE9F0418EB01F490AAE002503904FF063 -:1081800020080896059507918DF8185001A801213F -:108190000D901948EFF3118788F31188047A017262 -:1081A00080690C900BF018FB14494A680D98016027 -:1081B000426010604860FFF78FFF0C9846620B9694 -:1081C0000A96204687F311880BF024FBEFF3118009 -:1081D00088F311880D990A684B681A604A68096823 -:1081E0004A600D9580F311880C9845620EB0BDE889 -:1081F000F04170471185020038220020082000203D -:10820000F8B5D0E90167054611F098F90446D6F8AB -:10821000C00008B396F8F81019B9007C033801289B -:108220001FD82846FEF7F6FFD6F8C000002202232A -:10823000016805463DB12F7C033F022F28BF2B74F8 -:108240002A606D69F6E73246016052F8C81F79B1BD -:108250004A695AB11146FBE73868416821F00201CA -:1082600041602046BDE8F84011F014BC01F1140251 -:1082700010600020C6E93000C6E93400C6E93600C7 -:10828000204611F007FC06F13000BDE8F84011F07F -:10829000E3BCFEE770B5204D04462878C0B3A07C4F -:1082A000B0B360890BF066FC022801D0607978B326 -:1082B0001A482978821C0B465BB132F8025CA68909 -:1082C000AE4203D11578E67CAE4223D00632013BA4 -:1082D000F2E7821E481C4FF6FE7101381AD0931D3A -:1082E00052888A421A46F8D10C2004211880A089AD -:1082F00023F8040CE07C0A4C03F8020C20780AF006 -:108300005FFF28B9207804214FF4FA7211F0F2FBD4 -:10831000012070BD002070BD912700204C6D002011 -:1083200095880020FF2804BF4FF0FF3070472DE9EB -:10833000F84F1D4B0C4605464FF4BE21AF0004F02C -:10834000020643EA80004158C9B2914217D117484A -:108350004FEA14299A4647EA0008834611F0EEF8DE -:108360000BF10101220C88F8009039430A7048F0A3 -:108370000201220E0A7011F08DFB534605E024F035 -:10838000FF0100F5BE201143016026B945EA030054 -:1083900004F0010101700648012181EA56013843C9 -:1083A00001600020BDE8F88F002002400110084065 -:1083B000001A44422DE9F84F214CDFF880A0814695 -:1083C00000254FF0010BE8469AF80000E778C0B2AC -:1083D000A9B281422ED2A078FEB2864220D0304689 -:1083E00000214246042310F09BFE9DF800007828EF -:1083F00016D0FF2801D07E2803D130467C210CF016 -:1084000035F906EB4600E77004EB8000808BE080D6 -:108410004844B0F5005F0ED9304678210CF026F9BB -:108420009AF800005BFA87F10135B1FBF0F202FB2C -:108430001017CCE7FF27F8B2BDE8F88F9788002027 -:10844000A08000207CB50C46080426D4E00704BFB9 -:1084500000207CBD1E48007808F0C4FF054668B1C6 -:1084600001200DF107018DF80700522009F006FEEA -:108470000020002610F024FF1448867002200EF021 -:10848000F3FD38B101464570332008700F48C078BD -:1084900006F00AFE84F001007CBD0C4E307806F038 -:1084A000D5FA80B1054600780D2805D00C2806D1F4 -:1084B000284610F073FB02E02846F4F75BFC2846E0 -:1084C0000FF0D0FCEAE784F400407CBDC026002019 -:1084D0008D88002010B5044600780438052831D86E -:1084E000DFE800F0030D151E26311D480078013825 -:1084F000012827D82046BDE81040F0F731BD1848C4 -:108500000078F8B92046BDE81040F8F755B814488F -:108510000078012816D12046BDE810400EF0B4BA0C -:108520000F48007870B92046BDE8104010F0F4BB49 -:108530000B4800780138012804D82046BDE81040D7 -:1085400010F0AEBE10BD0648007820B9607F10B9AB -:10855000601D03F093FA2046BDE8104011F086BB81 -:10856000182600202DE9F0418EB0054610F0E6FFF8 -:10857000DFF87C80044669681022D8F80800D0F83B -:1085800008010068836B0AAF38469847064628BB47 -:10859000D8F80800D0F808010068016901AE30463B -:1085A00088470D2005F1080301978DF824000FCBB3 -:1085B000CDE90311CDE905320290288B0790688B35 -:1085C0000890287F8DF82500D8F80800D0E94112DE -:1085D000086811684A69314690470646204611F0FE -:1085E00059FA002E18BFE42630460EB0BDE8F081DF -:1085F0000C01002070B51E4DA868D0F8B8100A789C -:108600001C4991F900101AB1002902D41A490978BD -:1086100011B1D0F84C05804710F090FFEA68174C74 -:10862000126921781278914206D1154909784907D3 -:1086300002D411F02FFA17E011F02CFA0DF0E4FD3E -:1086400020780EF0AFFE78B1E868247806692046FD -:1086500031780BF0F7FC347030B1A868D0F8D40052 -:1086600090F9420010F027FA10F0D8FB012070BDFD -:108670000C010020B4880020A78800204C26002090 -:10868000AD880020F8B5044690F8300003282DD1BD -:1086900004F12801887C032828D11D4E0023B068EE -:1086A000D0F8D4201632D55CCF5CAF422DD1013347 -:1086B000082BF8D1D0F830244A20904767680DF194 -:1086C00002052946388810F0C9FF50209047788865 -:1086D000294610F0C3FF4B209047B7F80500294604 -:1086E00010F0BCFF53209047002100E0E82108482B -:1086F0008068D0F8F40041702A2020700448806817 -:10870000D0F8401320468847F8BDEA21F1E700BFC2 -:108710000C01002070B5044610F010FF184E0546FD -:10872000307810B1174811F068F91748007810B187 -:10873000144811F062F91548007870B914480078AF -:1087400058B91448007840B91348007828B913483C -:10875000007810B91248007820B1284611F09AF933 -:10876000002070BD0DF050FD2846347011F092F9D4 -:10877000601E022802D3034811F03FF9012070BDAA -:10878000A02700200C010020AE880020AC8800202B -:10879000AF880020B4880020A7880020AD88002082 -:1087A000B28800202DE9FE4F0446007A02280ED13F -:1087B00020888DF80A10090A04250DF108088DF8A3 -:1087C0000B108DF80800000A8DF8090001E008255B -:1087D000A0461648DFF858B00026EA4600F1080720 -:1087E0000BF10809052E1CD0207A1049022808BF79 -:1087F00059460968F140C9070ED00228394650464B -:108800002A4608BF494611F07BFA404651462A469F -:108810000FF00EFC012805D009F1040908370136D4 -:10882000E0E7FF26F0B2BDE8FE8F00BFE081002048 -:108830000885002010B5407820B11C48002180F840 -:10884000261010BD194C082084F8260094F8380032 -:1088500058B91748016809B100208847A18C052044 -:1088600005F053FFA08C09F0D5FC124800780128D0 -:108870000AD1002011F0CCF9E18A062005F045FF6D -:10888000618B042005F041FF0C4800680028D8D017 -:10889000094800780128D4D109484FF480414FF4A9 -:1088A0007A720078BDE8104011F021B9407B0020B9 -:1088B0000025002018260020BA270020842300204D -:1088C000988800202DE9F041064600888846114628 -:1088D00014460AF0FDFB7088E1796081B088A081C0 -:1088E000B079A074F079E0740820607021B1102094 -:1088F00006F1080160706161217A29B100F1080573 -:1089000030446570A06100E00546607918B1705D83 -:1089100001356570607120460DF0F8F9074688B999 -:10892000A179701951B10E30A0620848007B10F097 -:108930007FFC2844A8EB00000E3802E0A062A8EB00 -:10894000050020773846BDE8F08100BF407B00205D -:10895000BCB5044602208DF8050001A80DF090FF7B -:10896000B8B30546006904210180217A0139B1FAC2 -:1089700081F1490949014170627A012A04BF4031FD -:108980004170A27A012A19BF0120A8768031417076 -:10899000607A012804D1606808B1012169772862F2 -:1089A000E07A012804BF0120E88220880BF0E2F879 -:1089B00018B1E88A40F00400E8820120A87710F09E -:1089C0001FF90548686220886880284605F086FF00 -:1089D000BCBD1020BCBD00BFC88700202DE9FE43F0 -:1089E00080460A201E4691460F46002908BF00EB2C -:1089F00043008DF8090002A80DF042FF00B30546C0 -:108A000046EA471049462C69607009202070A01C76 -:108A100011F0B5F8BFB10126AE7710F0F1F81148AA -:108A20006C462146686240460CF0D8FF08B12C62C3 -:108A30006E772846A5F8028005F050FFBDE8FE835A -:108A40000120BDE8FE830A9804F10A01002EE2D05D -:108A500010F8022B013E01F8022B10F8012C01F84E -:108A6000012CF3E7C88700202DE9F041154610F0EE -:108A70006EFF804625B3DFF874C0DFF874E0002392 -:108A80000027BCF80060DEF80020FCB2AC420CD23B -:108A90007008862809D87444701C0137217BACF813 -:108AA0000000915523730646EFE7DCF80420AC4242 -:108AB00018BF002A06D0BCF802104FF48770904708 -:108AC0000A48426812B1A8B2002190470748002125 -:108AD000202200230180064988680C310EF0A1FD98 -:108AE0004046BDE8F04111F00EB800BF64260020FA -:108AF00048230020F0B589B0ADF8201007907BB373 -:108B000072B391B207A802AA1C4605F071FA064694 -:108B100038BB194F786808B1804728B3B86801F0AE -:108B20005FFC05461548002203230092C188C078E7 -:108B300002AAF1F733FC06460A2818D0F0B2A8B909 -:108B400002A821460222EFF7A5F9064678B9BDF83A -:108B5000141061B19DF8180007F0FCFD3E7806E0A6 -:108B60000426F0B209B0F0BD0B26FAE70126B8687A -:108B7000294604F093FFF4E7A0230020A080002002 -:108B800080B50DF05DF918480023811C1748027864 -:108B90004FF6FE703AB1C1F80230088021F8023C6D -:108BA0000831013AF6E7134A1149002312780831D7 -:108BB0002AB101F80A3B013A21F8100CF8E70E49F6 -:108BC0000E4A097819B122F8080B0139FAE70C4866 -:108BD0000C494FF47A72007808700B481021007825 -:108BE000BDE8804010F083BFE02700209ABC02005F -:108BF000D07E0020D9BC0200D2BC02004276002008 -:108C0000DFBC02001787002098880020F8B5D0E963 -:108C100000670D46044610F091FC96F8311041BBF8 -:108C20001949097829B30121A6F8311010F032FF53 -:108C30001648002D18BF284601784268012908BF50 -:108C4000002A1BD086F83010D0E90210C6E9024293 -:108C50000F4A104B3062B8683161A0F580719142C3 -:108C600038BF034606F13400736100210EF030FF77 -:108C700002E010F00FFF00242046F8BD83680022B8 -:108C8000002BDFD1F7E700BF18230020B8BA02009D -:108C900001FFFF0080A90300B0B586B00446807ACA -:108CA00058BB60680DF117016A4600F083FC01466D -:108CB000E07AC00621D49DF8170001281DD19DF847 -:108CC0001000022819D1164A002301EB4100CDE91A -:108CD000003342F8203002EB800014224360FF2072 -:108CE0006B468DF810009DF81200013000F00F0067 -:108CF0008DF8120004200DF063FB2046F9F724FBE9 -:108D0000054648B9A07A38B9E07AC00604D410F014 -:108D10004BFC6168F9F712FF284606B0B0BD00BFF2 -:108D20008043002010B586B00021C27AADF80C1047 -:108D30000188ADF80E104168049102F0400112065E -:108D400002D421B901200DE039B905200AE0807A6A -:108D5000012814BF0320002004E0807A012814BFFA -:108D6000072004208DF8140001ACAB20002122461E -:108D700006F066F80DF103012046002200F01AFC0F -:108D80000A480078012808D19DF8030028B900207E -:108D90008DF8150003A803F08CFF01208DF8150055 -:108DA00003A803F086FF06B010BD00BFB227002065 -:108DB00010B51D48007810B91C48007820B11C4837 -:108DC0008068D0F84C05804710F0B8FB19490A7844 -:108DD000022A24D10122184C0A702378062B05D8C8 -:108DE0009A4012F04C0F1CBF83220A7010F052FE02 -:108DF0002078042807D80121814011F0130F02D0F8 -:108E0000FAF77CFA207806280DD8012101FA00F043 -:108E100010F04C0F07D0BDE810400AF037BDBDE898 -:108E2000104010F037BE10BDAC880020AF88002085 -:108E30000C010020B4880020B78800202DE9F04103 -:108E400086B0DFF8708098F8650078BB012088F85C -:108E50006500C8F80480C8F800800DF041FF16488E -:108E600001AA114690E8F8000420F8C104901348C4 -:108E700008F11004124900F11C03204608F092F892 -:108E8000C8F84C400AF08AFC0E48D0E9102347F697 -:108E90009160101A73F1000031BF4FF0FF300020D5 -:108EA00047F6906110F014F8C8F8580006B0BDE815 -:108EB000F08100BF08200020CCBA0200A01F0020D3 -:108EC000C13C0100207C002010B58CB00446007A23 -:108ED000042802D110F0A4F810B1C2200CB010BDCB -:108EE000A07850B960680DF1030101AA00F062FB9F -:108EF0009DF803000028F0D0A0780021CDE90611EC -:108F00008DF82C10089140F20B11ADF81C10412186 -:108F1000002808BF612120888DF81A10ADF81800CC -:108F200006A8F6F753FB9DF82C000028D6D1099827 -:108F30001021406C0170A1784170217A817003305A -:108F4000616810F01CFE06A809F0D8FA9DF82C0004 -:108F5000C4E770472DE9F843044600206FF0010193 -:108F60004FF6FE72A04648F8040FA8F8081038F82B -:108F7000021CC8F80400914202D1C0B2BDE8F883D7 -:108F8000DFF8549000250020B9F80070BAB2A9B2F9 -:108F90009142F2D24A0012FA85F3D9F8042012F86D -:108FA00023301B0716D001EB4101638802EB8101DE -:108FB0004A8893420ED10E1D30460EF017FF01284D -:108FC00005D14046314610F0AAF9B9F80070A581E4 -:108FD00001203D460135D9E73426002070B51B4EEF -:108FE00004464FF48061307805F002FD18480921ED -:108FF00080F8261017480078022802D11648002170 -:10900000017065690FF0FCFD144928460EF04DFB18 -:10901000D8B110200EF028F8B8B105460220A16999 -:109020002870A06AB0F801206A80C07868704A2071 -:1090300009F024F8A07910B90948052101703078A9 -:109040002946BDE8704006F02FB870BD9888002012 -:10905000407B002018260020CC270020C887002055 -:10906000C42600202DE9F04188B0ADF81C10069010 -:1090700006A801AA002104F0BBFF054668BB194EF3 -:10908000706808B1804738B3B06801F0A9F9164F8D -:1090900004464FF000080323CDF80080F988F878E3 -:1090A00001AAF1F77BF9054688B9BDF810109DF8C3 -:1090B000140007F04FFBF988F878CDF8008001AA7A -:1090C0000323F1F76BF935780A2818BF0125B0683A -:1090D000214604F0E3FC00E00B25E8B208B0BDE84F -:1090E000F08100BFA0230020A080002010B504461E -:1090F0001E4849B138300068B0B1C3681B7B03F02B -:109100000F03022BF7D100E0806B68B102B1106051 -:10911000C268137B03F00F03022B08D151B1016920 -:109120008A8DC968114415E0002100201CE001204F -:10913000002119E012880169A2F60302012A4A8B74 -:109140008CBF0969496919231144094A92F86220C0 -:1091500012FB0311406B0CF0B4FC206010F034FDE6 -:109160002168B1FBF0F10120216010BD3021002009 -:10917000B87B00202DE9F84F07461E4815460E46DD -:10918000009300F138094C4624680CB1B442FBD17D -:109190004FF0000A00F1400B44B32069D4F800807E -:1091A000B84220D1204600224FF080530DF0CCFB76 -:1091B000009870B1204600224FF080730DF0C4FB80 -:1091C00030690D49086291F8240040F0010081F8EF -:1091D0002400484621460DF017FB584621460DF065 -:1091E000D7FE0AF1010A002D4446D5D15046BDE80C -:1091F000F88F00BF30210020702000202DE9F043BF -:109200008BB005AC20460EF053FC8220182122467C -:1092100010F0FCFA18480DF10808002508F10409BF -:109220000778164800F13906ECB2BD4210D207208B -:10923000214600220C23CDF800800DF0ABF830461B -:10924000494608220EF0F4FE01350028ECD004E077 -:109250004FF0FF30013CCDE903000A980290A1B223 -:1092600002AB07200C220DF0ABF80548002101806D -:109270000BB0BDE8F08300BFD7BC0200407B0020EC -:1092800004250020F0B585B005461E481E4FA9698B -:1092900000883E460C88844218BF002616D1688894 -:1092A00003A901F0BDFC01280DD19DF813209DF804 -:1092B00011009DF81210042A08BFCF2912D0542A99 -:1092C00008BFEF2911D00020002112E0297C687C22 -:1092D00048F202022346CDE90021A91C80220DF0AC -:1092E0006FFB0DE08C2802D0E9E74428EBD1112177 -:1092F0005F203971F87028462146324604F03EFA64 -:1093000005B0F0BD7087002026870020BCB504465C -:109310000022806982230192817839B3FF294FF0BE -:10932000000524D0194A0088128880B290420DD1DD -:1093300001A80CF039FC019A00230546002A08BF59 -:109340006FF07C03002818BF012510E01049097850 -:10935000022908D20FF00EF96FF07603002808BF3B -:109360006FF07E0301E00CD1802300220025D9B2EA -:109370002046FAF73FFC1DB1019808B110F052FCED -:10938000BCBD002200250023F1E700BF708700204C -:109390001826002070B588B004461E48A1690088D0 -:1093A0000E784A7846EA022282421DD18A78102A33 -:1093B00028BF10228DF80C2003AD681C03310FF07C -:1093C000E7FE812011212A4610F020FA9DF80C00BA -:1093D0001149002818BF01200A8822F0100242EA31 -:1093E00000100880002000E084208DF80900207C17 -:1093F0000DF1090148F2140203238DF80B608DF87A -:109400000A60CDE9001004F11100A11C08F00AF96E -:1094100008B070BD7087002026870020B0B588B0E6 -:1094200010F0DBFA18B304461D480078012804D177 -:10943000607900F0E7000830607100208DF80400CA -:109440006088ADF8100001AD284606F05DFD20886B -:1094500004350695ADF8140010F0A6F8ADF81C0020 -:109460006079810601D5410603D4002102E0002085 -:1094700014E001218DF81F008DF81E1005A80DF0D5 -:10948000C7FA30B128460DF09DF8284605F004FDD6 -:1094900003E0607900F0FB006071012008B0B0BD0E -:1094A000D027002070B590B06E460C46054640218E -:1094B00030460FF009FD304629460A220FF068FEBB -:1094C000D5F80A00E989CDF80A0006F10E000DF082 -:1094D000B8F8288AADF81700688AADF83B00E87F35 -:1094E000ADF82C0010F0A0FB0A9070B1EA7F296A59 -:1094F0000FF04EFE4CB10A999DF82C00A04720B108 -:109500000A9810F08FFB1A240AE007488068D0F808 -:1095100088126846884704460A9808B110F082FB12 -:10952000204610B070BD00BF0C010020F8B50C46FD -:10953000064610F003F81D4F0546B8687EB1D0F816 -:1095400094000121007802F0D7FC284610F0A2FA1E -:10955000204609F0F7FF0EF03BFB10B3F8BDD0F842 -:1095600038038047C0B105F0B3FBA8B1F868806943 -:10957000007888B9FAF70AFA0D4E307860B9B86801 -:1095800000210027D0F89400007802F0B5FC10B953 -:10959000204607F0B1FB37702846BDE8F84010F0D0 -:1095A00079BABDE8F8400BF09DBA00BF0C0100206D -:1095B000B28800202DE9F0418CB00D4601464FF6EF -:1095C000FF70ADF81A008DB381B30027082614464A -:1095D0000DF11C080420002214232F70CDE9026134 -:1095E0000DF11A01CDE900860AF028FE70B1CDE92F -:1095F000047704A80DF11A0100221423CDE9008696 -:10960000CDE9026004200AF019FE01E00120287073 -:10961000BDF81A0054B107490988884206D207A943 -:10962000204614220FF0B4FDBDF81A000CB0BDE8BE -:10963000F08100BFC6BC0200F0B589B0ADF82010C3 -:10964000079043B33AB391B207A802AA1C4604F0AC -:10965000CFFC064600BB174F786808B18047F0B1D1 -:10966000B86800F0BDFE05461348002203230092AF -:10967000C188C07802AAF0F791FE90B1C0B20A2862 -:1096800011D102A821460122EEF704FC064600286B -:1096900018BF012608E00426304609B0F0BD0B26AD -:1096A000FAE70D2600E00126B868294604F0F6F92D -:1096B000F2E700BFA0230020A0800020FEB51446E2 -:1096C0000DF1050207230D4606460FF029FD9DF812 -:1096D00005109DF806209DF8073026749DF8096056 -:1096E000A5819DF80B009DF808504FEA910C01F000 -:1096F0000301A07242EA012E9A009DF80A30B101DE -:1097000084F808C042EA9512A4F806E01F06A28079 -:1097100041EA976161720121962803F0030008BFB6 -:1097200004210843E07205F03F00800140EA960002 -:10973000E0814FEA0E3040EA0C6010442060FEBD2C -:109740002DE9FF41DFF870800C460546ADF80400B6 -:1097500002208DF80C00B8F8241001A80EF0F8F9DA -:109760001A281BD01548164900234FF6FF770278B8 -:10977000FF209A420BD031F82360BE4203D1FF286C -:1097800008BFD8B201E0AE420AD00133F1E7FF28AA -:1097900009D1B8F8241001A810F06AFA002008E0F6 -:1097A00001EB830003E021F8205001EB80004480AE -:1097B000012004B0BDE8F081407B0020D6BC02004F -:1097C0008086002070B514460E460FF0B7FE0325C4 -:1097D000052E2CD8DFE806F003090E2B161B1949BD -:1097E0008A6CCAB1896C098E02E0154991F8601043 -:1097F00021801BE01149097E0239B1FA81F1490942 -:10980000217013E00C490A68226049680DE00A499A -:109810000A681AB1D26802E0802508E000222260BE -:10982000496809B1C96800E000216160832510F032 -:1098300031F9284670BD00BF70200020D01E0020E6 -:10984000B87B002030210020F8B504460FF076FEEA -:109850001A4F05464FF0FF30386204F1B80010F09F -:1098600013F9174EB6F85600B6F85410884210D1C6 -:10987000144890F82400397E022918BF002808D027 -:10988000284610F007F9072002F0F8FF0FF056FE07 -:109890000546B6F85600B6F85410884206D10A4874 -:1098A00010F0F2F808200AF07DFF02E0012084F8B1 -:1098B000FC002846BDE8F84010F0ECB8D01E0020AF -:1098C0003021002070200020207F00201C480078DC -:1098D00030B1022810D001281CD144F2010101E06E -:1098E0004FF48041174A002811806FF0710108BFC2 -:1098F0006FF07001917014E0124844F202016FF0B1 -:109900007F02018010490978012908BF6FF07702B2 -:10991000827006E00B484FF40062018862F3DF01B9 -:1099200001800848A021094A41810021C0F8032094 -:10993000C1710173018941F430510181704700BF49 -:109940001826002026870020D5270020000050A0E0 -:10995000E0B51346062813D0052814D088BBA1F122 -:109960003A00022816D3622917D068291DD0B1F514 -:10997000817F12D040F20310814222D114491AE0B3 -:109980000093062001E005200093002210230CF034 -:1099900001FD8CBD0846012101E00846002110228E -:1099A00002B0BDE880400FF075BA07480078013872 -:1099B000012806D80549184610220FF0E9FB0020BF -:1099C0008CBD0A208CBD00BF1826002054BB0200AD -:1099D00044BB020070B504461848C168896909781B -:1099E00019B117480121017070BD164E164D31781E -:1099F0008A00B5FBF2F2A24204D28068D0F84C058E -:109A00008047317804FB01F01049096801EB8004BC -:109A10000F480068C06B8047211AA1F54871B1F169 -:109A2000FF3F05DC2918091B013148BF00F54874C8 -:109A300008482146BDE87040F7F726BE0C0100201B -:109A4000B2880020B0880020FFF6C2FF2C880020DA -:109A500030880020B16102002DE9F8431B4C1A4800 -:109A60002188868C81845020214608F007FB184805 -:109A700025884FF6FE78174C08F10109077887B161 -:109A800060892946B04208D0A84207D020461C2150 -:109A90000FF01AFA4946A4F800806181013F1C3496 -:109AA000EDE70D4C206868B106200DF0DDFA48B1F5 -:109AB0004FF4807185804180D52101702168BDE817 -:109AC000F8430847BDE8F883407B00203277002048 -:109AD000D5BC0200DC5B002054270020F8B501460D -:109AE00000681B4D0022002304882D6855B16E7B51 -:109AF000052E05D12E683688A64208BF01320133F3 -:109B00000435F2E7134C0526DBB20127D2B2258AD1 -:109B10004E734E8946F400664E810F4E3678B3423E -:109B20000E4B28BF3D461B789A4228BF3D460D810B -:109B30004FF6FF720188914205D0A18C0EF008F813 -:109B40001A2818BFF8BD0120BDE8F8400FF027BF64 -:109B500054880020407B0020E0BC0200E1BC0200F1 -:109B60002DE9FF410D4603A90DF10A0208F066FF39 -:109B7000044678BB039FBDF80A007880182010F0D7 -:109B800053F838B37988064600900620002218233F -:109B90004FF000080CF0FEFB3046294610220FF073 -:109BA000F7FA7988062018223346C6E904880CF0B3 -:109BB00007FC304618210FF087F9304610F032F8D4 -:109BC0007888064900EB400041F8208001EB8000D6 -:109BD000C0F80480204604B0BDE8F081188300205E -:109BE000F8B50746042014460E468DF80100684675 -:109BF0000CF046FE48B30546006907210170397D27 -:109C00004170797D8170B97DC17007F10B002862C8 -:109C100040F20110A5F81D000EF0F2FF0E484021A1 -:109C200068620120A87606F0FD0001280B4808BFF5 -:109C30004FF48861E982012C0088688004BF00200D -:109C40002876284604F04AFE00E0102003494FF62B -:109C5000FE720A80F8BD00BFC8870020742700206C -:109C6000B0B51020C4F209000168890733D444F666 -:109C7000B470C5F200000068810248BFB0BD40F278 -:109C8000EC11C1F2000109680124096804EB207598 -:109C90008847C0F13E00C11007220729B8BFC21093 -:109CA00041F20C30C5F200000068AA42C0F3032064 -:109CB000D8BF2A46801A0F28A8BF0F200128D8BF76 -:109CC000204646F20D2140F0F000C4F2080181F870 -:109CD0004D000878B0BDFD21C4F20001C160B0BDE7 -:109CE0002DE9F84FDFF87090DFF870B000244FF0E6 -:109CF000010AE846002599F800009BF80370C0B2FD -:109D0000A9B2814225D29BF80200FEB2864213D04E -:109D100030460021424604230FF002FA9DF800006D -:109D20007C2818BFFF2811D106EB46000BEB800002 -:109D3000808B201A00F5005499F800005AFA87F138 -:109D40000135B1FBF0F202FB1017D8E77E28EBD00B -:109D5000F2E72046BDE8F88F97880020A080002019 -:109D6000F8B51E4D04464FF0FF3128680FF008FE8D -:109D7000D4E901677168388CC5E90110796911BBB4 -:109D8000398B29440A7B013A0A7311061BD12046FC -:109D900004F070FFB92029898DF8030020460FF0E8 -:109DA000AAF80DF10300012105F00EFF29892046D4 -:109DB0000FF0AAF870680FF0BEFE388B002105EB9B -:109DC00080000161A86881B22046F6F780FE00207D -:109DD000307028680FF03AFFF8BD00BF0C24002057 -:109DE0002DE9FE438BB11D681E46804685B10FF0FC -:109DF000AEFD044628680FF0EDFE10B128680FF0A4 -:109E000043FE20460FF07FFE1BE00220BDE8FE83EC -:109E10000C2017460C46FCF7EDFCE0B1E946054680 -:109E200048460FF044FD002041464A4602958DF811 -:109E300000000190094809F097F885E8910050B1B9 -:109E40003560286841460FF0C7FE28680FF0C6FE4F -:109E50000020BDE8FE830820BDE8FE83019B0200D0 -:109E6000F8B50A461C491D4D00234FF6FE760C78C6 -:109E700002F040019C420DD035F83370874207D183 -:109E8000B04209D005EBC307BF7957407F0613D511 -:109E90000133EFE7224600E0DAB24FF6FE73984254 -:109EA00008BFA24211D10026B44207D005EBC6007C -:109EB000007928B10136F7E7DAB206E0224604E07D -:109EC00035F836000CF0A8FFF2B20020A24238BFED -:109ED00005EBC200F8BD00BFDABC0200E04C002078 -:109EE0007CB51C4616460D46042803D0022812D025 -:109EF00001282BD128460121224601F0E9F828B398 -:109F00004EB1284602F0A8FF12490978884202D2D1 -:109F1000012030701AE028460021FFF7A1FF70B140 -:109F2000817911F0180F0AD00B49438800884FF649 -:109F3000FE7200920022C98A05F06BFF08E0074814 -:109F4000214602782846F4F7E3FB08B100207CBDE7 -:109F500001207CBD9ABC0200407B0020CEBC0200E8 -:109F600070B50568D5F8F81031B3D5F858214468B4 -:109F70005668A16B20683268D16202210EF00AFD9A -:109F8000D5F85801A16B154A40680068C0F804155F -:109F900091FAA1F112683068B1FA81F192699047A3 -:109FA0000446D5F8F800011B6879022806D105F1AE -:109FB000D0000BF09DFD0BE000240CE0D5F8F40080 -:109FC000D5F8FC200A44401AC5F8FC20C5F8F40076 -:109FD0000020C5F8F800204670BD00BFD401001075 -:109FE0007FB50020ADF80C000190ADF808001420FA -:109FF0000FF01AFED8B1044618480068A0B1022636 -:10A0000001AD142E06D0A019294606220FF0C0F883 -:10A010000636F6E703A9204602220FF0B9F84C20D5 -:10A02000142122460FF0F2FB20460FF0FBFD182012 -:10A030000FF0FAFD88B1182104460EF045FF002507 -:10A04000022D07D8A9B20620182223460CF0B8F931 -:10A050000135F5E720460FF0E5FD7FBDE026002045 -:10A060001CB51B480078022831D11A4C206910B168 -:10A0700009F0CCFFFAE70EF063F9174801780829D8 -:10A0800008D0012905D101200021BDE81C40EAF7D4 -:10A0900081BBC170082101700FF012F80A200DF089 -:10A0A00027FD0E480221007804F0A2FC4FF4804006 -:10A0B00000210024F1F730FC0DF1070152208DF84A -:10A0C000074007F0DBFF08200021EAF763FB1CBD17 -:10A0D00018260020AC220020088800209888002044 -:10A0E0002DE9F843DFF874901446D9F8082002EA05 -:10A0F00001038B4221D1806843688B4220D96618C6 -:10A100006FF005059E4226D82240A24223D1006866 -:10A11000471808F013FD8046ACB10FF00FFA064661 -:10A1200038460DF090FE054630460FF0B3FC5DB9A1 -:10A13000D9F80400241A0744EEE76FF004050AE09A -:10A140006FF0030507E0002540460DF0BBF9002D38 -:10A1500018BF4FF0FF352846BDE8F883DC25002006 -:10A1600070B51C4DA968086C006828B9D1F84C0579 -:10A170008047A868006C00684068174E007800F0BF -:10A18000200030700FF0DAF9044614480178832972 -:10A1900011D13178A1B1A868016C096891F87810E3 -:10A1A00011B9D0F84C05804720460FF073FCBDE88C -:10A1B00070400BF0ABBA2046BDE870400FF06ABCAF -:10A1C0008521017020460FF065FC0020BDE870403D -:10A1D000F8F782BA0C010020C0880020B488002063 -:10A1E000BCB5044640780AF00DFA6078A0F1190178 -:10A1F000022903D3F12801D0E12809D1144D287890 -:10A2000018B900200BF0A2F8287880F0010000E0D7 -:10A2100000200F4908701048007802280BD10D4823 -:10A22000007840B9607840F00200EB2803D130207C -:10A230000021F1F771FB094863780122818C408B82 -:10A2400000920022EEF7E8FABDE8BC400CF030BE08 -:10A25000A7270020D527002018260020407B0020BB -:10A260007FB50EF007FBA8B1417B062912D101682A -:10A2700045890A7A8DF80C200C88ADF804400CF062 -:10A2800047F8280504D5002021460CF09DFC20B19C -:10A29000012000E0002004B070BD104DA98C01A881 -:10A2A0000FF0E6FC002000210CF08EFC04464FF677 -:10A2B000FF7674B120680188B142E9D0A98C0DF015 -:10A2C00047FC1A28E4D0204600210CF07DFC04460F -:10A2D000EFE700200FF063FBDAE700BF407B0020D0 -:10A2E00070B50D46242104460EF0EEFD8DB328789E -:10A2F0001A4E207068786070A878A070E878E070D6 -:10A300002879207168796071A879A071E879E07185 -:10A31000287A2072687A6072A87AA072E87AE0726D -:10A3200004F10C00E968B047287C2074687C6074F4 -:10A33000287DA07404F11300A969B047E96904F10C -:10A340001700B04795F82000E07695F821002077B7 -:10A3500070BD4FF6FE70208070BD00BFFB9A0200FA -:10A3600070B5184B2021EFF3118081F31188174C41 -:10A370001548DA6C02609C64154C1A661C64154B17 -:10A3800004689C420FD14268144B22F47F421A4465 -:10A39000426081760021C160D0F82C1221F040414A -:10A3A000C0F82C1270BD0C4D0024362CEBD00E2CB6 -:10A3B0008EBF42F8245053F8246042F824600134E0 -:10A3C000F3E700BF381F002008ED00E00020000088 -:10A3D0000020012000000000916C02000000FA053E -:10A3E0002DE9F04385B007461C480125846984B3F4 -:10A3F000666990F808800572B868012807D10025C1 -:10A400004046BD603C61FE6009F004FA21E0386915 -:10A41000A0421AD0204607F114090EF06DFB01A9E5 -:10A420000025484632466162CDE903450DF04EF9FC -:10A4300038694069864203DD38693146FBF76EFBB7 -:10A44000404609F0E7F9656203E0404609F0E2F9A9 -:10A450000125284605B0BDE8F08300BF3822002062 -:10A46000B0B592B0044600684189CA0735D021F0E2 -:10A47000010141810168086AC97F01AD2A46FEF7E2 -:10A4800021FA50BB0B990878042826D10020CDF87A -:10A490004200CDF83E00CDF83A00BDF80E00ADF810 -:10A4A00038000EA8497802308A0644BF01228DF890 -:10A4B00043200A0644BF01228DF84220490605F1D7 -:10A4C000140158BF05F1180109680FF058FB2079F5 -:10A4D0008DF844000EA80FF093FB12B0B0BD41F20E -:10A4E0009420C5F20000D0F884104FF20002C0F6AC -:10A4F000FF72114041F200020068C0F6B43291428E -:10A5000011D1C0F30332082AC0F340610ED0092AEA -:10A5100011D00F2A07D1020213D400F08072A9B122 -:10A52000A2B1112000E0FF2040B270470A200029AC -:10A5300008BF0C20F8E74FF0FF30002908BF0920C2 -:10A54000F2E70E20002908BF0D20EDE70B20002ABE -:10A5500018BF1020002918BF0F20E5E77FB505467A -:10A5600008460C460FF08DFA98B10188A94210D028 -:10A57000017904290DD80139058001290DD8144924 -:10A58000097869B1134A52F82110C1EB0111890011 -:10A5900008E00025284604B070BD6FF0010104E01A -:10A5A0000C490968002280F820208161C1610021E6 -:10A5B0006E46ADF802500125C160301D21468DF870 -:10A5C00000500EF0ACFE3046F7F7C8F9E2E700BFE6 -:10A5D000C827002060B70200B0B51D4DE868D0F86C -:10A5E000880080470EF0AAFF0446E868C06D8047E7 -:10A5F0000FF062F9496A90F942008847D5E90201F3 -:10A60000D0F8AC00896C007888470FF055F9096ED6 -:10A61000C08C88470FF050F9496E408D88470FF085 -:10A620004BF9896E4430884720460FF033FA0FF01B -:10A6300043F9096B90F843008847A868D0F83024A4 -:10A64000D0F8D40000F129015220BDE8B0401047F5 -:10A650000C010020BFB5002000210DF0C5FE134CF9 -:10A660000021206000200DF0BFFE606001AC20469C -:10A670000FF0AEF90E4D0121224628460DF0D0FE16 -:10A680000C4C25600FF0F8F821680B4A0AF03CF8F2 -:10A690000A4908700EF0A0FF09480EF0A3FF094810 -:10A6A00009490A4A09F09EFABFBD00BF24260020CE -:10A6B0005C8500204C88002050880020B98800204C -:10A6C00051B701007D8602008D52020065860200AE -:10A6D0001CB5E12903D01949097801B91CBD0189CC -:10A6E0000131018188B2884208D016480021A0F8C3 -:10A6F00070100120BDE81C4000F08EBE10480078AC -:10A700000028EBD00F4CB4F870108142E6D900203D -:10A7100000F082FE642100FB01F2B4F87010B2FB7D -:10A72000F1F21A2ADAD3084A1268002AD6D0ADF814 -:10A730000600ADF8041001A890471CBDDEBC020065 -:10A74000CA270020407B0020D4240020F8B50E4604 -:10A7500007460EF0F3FE80250446022E0AD816495D -:10A76000F0B201EB40162EB1B07A10B13068B842A9 -:10A7700005D0802520460FF08DF92846F8BD0F48FA -:10A78000017E022911D1717A4FF4A062406802EB78 -:10A7900001210B4A11430B4A114000220AF01CF818 -:10A7A0000546304600F058FCE4E7304600F054FC23 -:10A7B00002F01CFF8125DDE7B87B0020D01E0020C1 -:10A7C0000100080401FF080470B586B004468DF846 -:10A7D00016004FF6FC700D46ADF81410081A032849 -:10A7E00012D8022810D000208DF8170005A803F019 -:10A7F0002EFF06461148012104701148017008F02F -:10A8000039FD304606B070BD0220ADF806508DF817 -:10A81000040001A8FEF79EFB0126012809D1BDF81E -:10A8200006008DF81760ADF8140005A803F00FFFBF -:10A8300006464FF6FC708542DCD2E0E7DB270020BD -:10A84000DA27002070B592B0044605300DF12A01D8 -:10A850000AF0CCFB012802D0207902282ED0608893 -:10A860000BA900F0DDF9012828D10DF11A000DF136 -:10A8700003010E900BAD01AE28463246FEF79AFE5C -:10A880009DF80300D0B19DF8161006F108000DF1F7 -:10A890001A0202F0A5FF00200F95119001208DF8FB -:10A8A000420040F20110ADF8400004208DF836005F -:10A8B0006088ADF834000DA8EEF736FC12B070BD1C -:10A8C0002DE9F0410646087A0D46904601280EBF54 -:10A8D000288828460AF0B8F84FF6FE71884203D15E -:10A8E00000210846BDE8F0811249DFF84CC0002283 -:10A8F0000B786146002BF3D00F78B74210D12C7A39 -:10A900004F78012C05D1012F0AD14C88A04207D1E4 -:10A910000AE02FB94C88A04202D10C794445E0D01E -:10A920000E31013B0132E5E7C2EBC2000CEB400106 -:10A93000D7E700BFE2BC0200188700202DE9FC47E2 -:10A9400004460D4640689146DFF868A09846A16825 -:10A9500040680A8CCAF804002046CAF808200E682D -:10A9600004F088F9074610BB701903218DF8041014 -:10A97000010A8DF80700000C8DF80610BAF80810CF -:10A980008DF8050020460EF0B6FA01A8042105F066 -:10A990001BF910B14FF0FF3704E0484641460DF077 -:10A9A000F7F80746BAF8081020460EF0ADFA384618 -:10A9B000BDE8FC870C240020B0B51749CA6892692D -:10A9C00012781AB1154801210170B0BD154B144A17 -:10A9D000154D1B7812689B0003FB0024B5FBF3F2B6 -:10A9E000824203D28868D0F84C0580470F4800683F -:10A9F000C06B8047211AA1F54871B1F1FF3F05DC1A -:10AA0000291B0144013148BF00F54874084821461C -:10AA1000BDE8B040F6F738BE0C010020B288002037 -:10AA20002C880020B0880020FFF6C2FF308800206C -:10AA30004D4B020070B5194D0446287820B11848D6 -:10AA40008068D0F84C058047154E164A052CB06832 -:10AA5000D0F8D410C98C11800BD8DFE804F0030DB6 -:10AA60000D050A0D012002E00AF0A4F80320287069 -:10AA700070BDD0F84C058047022028700AF09AF883 -:10AA8000B0684FF6FF72D0F8D410CA840649D0F8E7 -:10AA9000D400C08C48860549C88170BDAE880020AE -:10AAA0000C01002046730020E87F0020E88600208B -:10AAB00070B50446B0F90E00227A81B2920702D531 -:10AAC000227B1F2A0CD8154A6368D26C52F820509A -:10AAD0009D4218BF42F820304A42E281227B0BE0BF -:10AAE0000E4B1D6D45F820400D4DDB6C53F820607A -:10AAF000AE4218BF43F82050102901D30A4902E0A2 -:10AB0000042902D3074901440A70217AC90718BFF2 -:10AB100007F02AFC0020A060002070BD381F002034 -:10AB200095F3000014ED00E0F0E300E080690278A6 -:10AB30000A70B0F801304B8002B17047C2788B8840 -:10AB400062F302038B80C278D20862F3C3038B8066 -:10AB5000C278120962F304138B806FF3DF2302794A -:10AB600002F0F80243EA02228A8022F4E0620379CA -:10AB700003F0070342EA03228A8042798A718279CC -:10AB8000CA71C2790A72027A4A72427A8A72827AE7 -:10AB9000CA72B0F80B208A81427B8A73827BCA73A7 -:10ABA000C07B087470477047B0B588B004464089D0 -:10ABB00006AD294600F034F80DF117016A46284623 -:10ABC000FEF7F8FC9DF8170070B19DF81000FD2805 -:10ABD00018BF002808D11048007828B9607A18B941 -:10ABE0006068007806280FD0607A18B9606800782D -:10ABF000072809D0207B18B960680078052805D19E -:10AC0000064841682046884708B0B0BD4FF49A70A6 -:10AC1000FCF77FF8F8E700BFB127002050240020A0 -:10AC200070B5064619480C46C08AB04206D10DF0F0 -:10AC3000E7FF014620460EF0A2FF06E00EF0A2FC60 -:10AC4000B04205D120460EF0CCFE0125284670BD4D -:10AC5000304621460AF0C2FE05460D48007800281D -:10AC6000F4D10EF079FD0028F0D1002DEED10025B1 -:10AC7000002EEBD007480188B142E7D100F118015E -:10AC8000204608220EF084FADFE700BF407B002058 -:10AC900018260020502400202DE9F04104464FF6EC -:10ACA000FE70A081207850B3184F04F104080025ED -:10ACB0004FF0000C388883B2AAB29A4221D25300D6 -:10ACC00013FA85F67B6813F82610090715D120784A -:10ACD00003EB86066188307002EB420003EB8000D4 -:10ACE0004180043041460EF01AFB3046A5810EF03B -:10ACF000FBFB38884FF0010C05460135DBE74FF0D0 -:10AD0000000C5FFA8CF0BDE8F08100BF3426002013 -:10AD10002DE9F04F85B005460C464FF6F77035B972 -:10AD2000844204D90026304605B0BDE8F08F1449AE -:10AD300008300DF10408134E4FF0010B08F104091F -:10AD40001FFA80FA0F78002FECD03079FF2814D04A -:10AD500075B170888DF804B0ADF81000404605F06C -:10AD6000D3F850B1284649460CF09FFC28B1DAE7E9 -:10AD7000544502D03088A042D5D02436013FE2E7C6 -:10AD8000E6BC0200B054002070B51B4C264630686B -:10AD900088B1017B01390173090609D121682E466A -:10ADA000814208BF2646016831600EF03BFFEEE7A6 -:10ADB00005460646EBE7104C606848B1C17E013994 -:10ADC000C176090605D10EF02DFF0020606000E07D -:10ADD0000020216801B968B1084C08214FF47A724B -:10ADE00020780EF087FE28B120780821BDE8704059 -:10ADF00003F02EB970BD00BF5C26002096880020AD -:10AE0000B0B540F2E014C1F20004206800214268AD -:10AE1000012090472068016801208847F0B14AF27C -:10AE20000000C4F20C0001884AF20445C907C4F2CC -:10AE30000C050AD14FF00121296000884FF6A0606F -:10AE4000CFF6FF702058804708E04FF6A060CFF69D -:10AE5000FF70205880474FF08070286042F2300029 -:10AE6000C4F209000068E0680068804748F2D871C1 -:10AE7000C2F200010860B0BD44F6B070C5F2000037 -:10AE80000168C90633D441F25031C5F200010968A6 -:10AE90004CF20042C3F6FF7211404CF20002C1F6C0 -:10AEA0000742914218BF704740680F220104800397 -:10AEB0004FF0000058BF081610F1240FD8BF6FF0F4 -:10AEC00023001B28A8BF1B2024300321A1EB101155 -:10AED00022FA01F122EA00004FF6FF7222FA00F096 -:10AEE00040EA01404AF21801C4F20C0108607047C0 -:10AEF0002DE9F041154F164A164B174CDFF838C0B4 -:10AF0000DFF838E0DFF838800E4D0F4E0021C0E941 -:10AF10000A11C0E90043C0E90227104A104B114C46 -:10AF2000C0E90465C0E9068EC0E908C1C0E90C4368 -:10AF30008263BDE8F08100BF29F90100CDC60100A0 -:10AF4000156D0100C5B7010065900100F58A01008B -:10AF500039960100D5F80100F5310000E19C0100AF -:10AF600061C60100F97F0200F8B51A4E0546306847 -:10AF700028B119490978A9420AD8002428E005F027 -:10AF80000FFC3068002418B313490978A9421FD96F -:10AF9000124A05EB450102EB81044FF0FF31D4E981 -:10AFA00001570EF0EDFC287870B970683968421EC0 -:10AFB0000A4209D17968814206D3B06808408142CB -:10AFC00002D10120287000E0002430680EF03EFE1F -:10AFD0002046F8BDDC250020F3BA0200A0B902002B -:10AFE00070B5184C607858BB17481849184D0022A6 -:10AFF000033020F00300091A0346E06029600E18B0 -:10B00000B34202D204C32968F9E721F00301002208 -:10B01000104E014441F8042CE82101602968EC3904 -:10B0200021F0030140F8E81F30600020FBF7E2FB4D -:10B0300001216170E168C6E9001028680438606089 -:10B0400070BD00BF44250020C588002000200120DD -:10B05000E0870020D0250020F8B505460EF06EFAF6 -:10B06000044665B3A87A50B36F7A01260CF000FD50 -:10B07000697A48B1144A48B21130536806FA00F0B0 -:10B080008343C0435360106006FA01F30F49002266 -:10B0900006FA07F02A72AA72C5E90422AA61C5E974 -:10B0A000002291F8605091F862202B4381F86030C3 -:10B0B00012B1013A81F86220C0B209F073FB204658 -:10B0C000BDE8F8400EF0E6BC08100440B87B002054 -:10B0D000F8B515460E460446012905D119480178F0 -:10B0E000204608F0E3FAA0B92046002106F056F900 -:10B0F0002946FEF7B5FE012E07D14FF6FE7750B177 -:10B100004179012907D140880AE0C8B14079B042AD -:10B1100016D10020F8BD68064FF6FE7058BF2046D5 -:10B1200008490D7886B2BE420AD03046294608F05A -:10B13000BDFA0028EDD12046A64208BF3846F1E707 -:10B140000120F8BDD0BC02002DE9F041D0E9014852 -:10B150000546D8F80000416821F002014160204610 -:10B160000EF03EFDD4F8CC0008F054FE04F130009F -:10B170000EF06EFD94F8F80018B904F16C000EF0B2 -:10B1800063FDD5E901750D4E95F83800B04795F887 -:10B190003900B04795F83A00B04797F8FB00B04740 -:10B1A00098F80C00FAF752FB04F11C000CF020FC9C -:10B1B000002084F8FD00BDE8F08100BFA52F02004B -:10B1C0002DE9F04385B01A480DF10808002708F171 -:10B1D000040490F80090174800F139054F4523D238 -:10B1E000FEB2072000220C23CDF8008031460BF080 -:10B1F000D1F82846214608220CF01AFFA0B92046B3 -:10B20000002108220DF020FC01370028E6D020465E -:10B21000294608220DF0BCFF002031460C22029086 -:10B2200002AB07200BF0CCF805B0BDE8F08300BFFF -:10B23000D7BC0200407B0020F0B58DB0451D044610 -:10B240000DF11601284609F0D1FE01282BD16088A6 -:10B2500006AE3146FFF7E4FC012824D10DF10601CA -:10B260001020099101F076FB012000270A958DF846 -:10B270002E0040F201100C97ADF82C000B4800781E -:10B280008DF822006088ADF8200008AC2046EDF76C -:10B290004BFFBDF816008DF82C700A96ADF8200013 -:10B2A0002046EDF741FF0DB0F0BD00BF8A2700201A -:10B2B00070B50D4606460EF04AFB04460EF084FCBF -:10B2C0000146B5FBF0F0022E06D0012E09D1A942AD -:10B2D0000ED91148006808E0A9420CD90E48406810 -:10B2E00003E0A9420BD90C4880680EF0C9F90DE0C3 -:10B2F0000B49094B07E008490B1D084903E00649C3 -:10B3000001F1080307490022FEF76AFD2046BDE867 -:10B3100070400EF0F8BB00BFC4250020098E02006B -:10B32000598E0200D1820200F8B51C4F06460D4628 -:10B33000F868C068007828B9B8680021D0F85824A7 -:10B34000012090470EF0FAF804460CF091FC3046CC -:10B350000EF0C0FC0646B868D0F8E010D0F8EC005B -:10B3600050F825000860B968D1F8E4100860B868A2 -:10B37000D0F8E00000680CF05DF8B868D0F8E02480 -:10B38000D0F8D800016830469047B868D0F8D404A7 -:10B3900080472046BDE8F8400EF07CBB0C01002041 -:10B3A00010B51B4C0121A06842695177D0F8D42018 -:10B3B000527B0F2A04D1D0F86401BDE81040004749 -:10B3C000D0F8A8000170E068016C20208847A068D0 -:10B3D000104A4FF47074C1688A61D0F8D430D0E953 -:10B3E00003215B7B9C4031F8131092F830305B00F6 -:10B3F0009940B1EB940F88BFA108962303EB41015C -:10B40000D0F8F03402F11000BDE81040184700BF3A -:10B410000C010020856A010070B518490A780021E6 -:10B42000012A4FF0000213D8154A02F11003154A01 -:10B430001478002264B113F80C5CFF2D05D01D8830 -:10B440001DB108B1198000E02A442433013CF1E722 -:10B450000E4C0D4B4FF6FE752478183364B133F85B -:10B46000186CAE4205D01E881EB108B1198000E0EC -:10B4700032441C33013CF1E790B270BD1826002025 -:10B48000B0540020E6BC0200DC5B0020D5BC02000A -:10B4900070B51A491A4A04460AF058FA0146E061A2 -:10B4A000012051B3002184F8200061626069B0F18D -:10B4B000FF3F1ADD60690121124A01FA00F0A06124 -:10B4C0006069157A1172116A01EBC000E0642020F6 -:10B4D000EFF3118680F3118820460DF02BFA86F3E6 -:10B4E0001188284608F096F906E00648A161214631 -:10B4F0002C30E0640CF086FF002070BD5575020012 -:10B50000FD2C02003822002070B5427C0C46017CE4 -:10B510008569227042886170A91C62802888A08099 -:10B52000A01D0EF02CFBA87A0026A073B5F80B0026 -:10B53000E66166612082687B0E35A07458B14000D8 -:10B540000EF072FB606130B10246A07C29460DF01E -:10B5500011FD054600E0A67415F8010B207658B1E0 -:10B5600040000EF061FBE06130B10246207E2946CA -:10B57000BDE870400DF0FEBC0020207670BDB0B577 -:10B5800086B00C46ADF80000002101256078CDE9B9 -:10B5900001118DF805508DF8030094F9000000F0BA -:10B5A0000C01002800F0030200F0200048BF8031A9 -:10B5B0000223012A08BF1223184408448DF8020010 -:10B5C0006846F4F703F89DF8140088B903984576A7 -:10B5D00061884187D4F80610C0F83E10617D80F87C -:10B5E0004910B4F81710A0F84B10684606F086FF13 -:10B5F00006B0B0BD10B586B004460020617800905A -:10B600008DF81400CDE901000220012918BF04299A -:10B6100023D18DF8040001208DF8050021208DF83C -:10B6200002002078ADF800006846F3F7CFFF9DF8E0 -:10B630001400B8B903980821406C0170617841701A -:10B640006178022903D1616802300EF098FA6846E9 -:10B6500006F054FF9DF8140004E0022901D10A20ED -:10B66000D7E7B32006B010BD2DE9F84304466FF0CC -:10B67000010004F10409A081608048460CF0B6FB8B -:10B68000012822D1144E00274FF0000831888AB2D9 -:10B69000B8B290421BD2420012FA87F3726812F8D5 -:10B6A00023301B070FD000EB400002EB800548461B -:10B6B000291D0BF0FAFF318828B16888A7814FF067 -:10B6C00001080F4660800137E1E74FF000085FFA9C -:10B6D00088F0BDE8F88300BF342600202DE9FF473D -:10B6E00004460120022108F0B9F92070C0B220B34D -:10B6F000C0000EF099FA00B380461348E9464FF0B7 -:10B70000010A09F104064746841C10480578B5B1C2 -:10B71000A078013801280DD820888DF800A0ADF858 -:10B720000C00484604F0F0FB20B1384631460EF0DC -:10B7300026FA07462434013DE9E74FF00008404669 -:10B7400004B0BDE8F08700BFB0540020E6BC0200A2 -:10B750002DE9F04106460C2090460D460EF064FAA5 -:10B76000044608200EF060FA94B1074680B1B8F1A3 -:10B77000000F7E807D60A7600CD028460CF072FB25 -:10B7800038460EF04FFA2046BDE8F0410EF04ABAB6 -:10B79000BDE8F081002021463870074840680EF06F -:10B7A0005FF80648016841F008010160044800683C -:10B7B000BDE8F04102F08CBE242600205088002015 -:10B7C0004C8800202DE9F04389B0109EADF8201080 -:10B7D000079046B31C4633B3154607A802AA214674 -:10B7E00002F006FC0746F8B9DFF84490D9F80800E3 -:10B7F000FEF7F6FD80460F48002203230092C18821 -:10B80000C07802AAEEF7CAFD074630B902A8294659 -:10B810002246334604F01EFE0746D9F8080041468A -:10B8200002F03CF900E00427F8B209B0BDE8F0836B -:10B83000A0230020A0800020F8B5054616484BF252 -:10B84000F521174E006800FB01F714483C0A006818 -:10B8500000F44020B0F5802F10D11248006880031A -:10B860000CD4F0680068804704F04EFF3168C96866 -:10B870008847C010390B484304EBE0342DB90A481F -:10B88000006820F07F40204444083069416C204625 -:10B89000BDE8F840084700BF08400C40B44F0050D6 -:10B8A000E00100108C13005010200940F8B5164F2D -:10B8B0001648BD6C0DF024FC044615480168066866 -:10B8C000214011F0200318BF002D0AD02846002285 -:10B8D0003D650BF039F80F484FF4804128300EF0E9 -:10B8E000B9F904EA060010F4602008BFF8BD0A495F -:10B8F00091F8612042EA504081F861000748002138 -:10B90000BDE8F8400EF0A6B93021002020000E005E -:10B910000C10044070200020B87B002028800020FC -:10B92000BFB5184D0446287820B91748018941F061 -:10B9300001010181204606F07FFBBCB1134890F85D -:10B94000410098B9287888B96C460020622100250A -:10B950002246FDF7FDFF204600210BF04BFC0020A6 -:10B96000FBF7C8FACDE90255CDE90055084C20682F -:10B9700030B128B105680EF055F925602846F8E782 -:10B98000BFBD00BF1826002026870020407B002076 -:10B99000DC26002070B51A4E044604211D4630787E -:10B9A00007F00EFC08B1012070BD07F063FC022D0A -:10B9B00023D808200EF038F9B8B1124905460868B6 -:10B9C00020B1016809B10846FBE701460D6040213E -:10B9D000307807F0F5FB01460020AC80C1F5167207 -:10B9E00009042860EA8002D070BD102070BD307854 -:10B9F00040214FF416720EF07DF8002070BD00BF9C -:10BA000099880020DC260020B0B58CB006AC182147 -:10BA100020460DF059FA154D822018212246A847DC -:10BA200001AC112120460DF04FFA3A201121224697 -:10BA3000A8473B2011212246A8470D48002180F845 -:10BA400041100C480078013801280CD80A4A4FF4FC -:10BA5000817010210DF0D4FE28B9074A4FF481708F -:10BA600010210DF0D3FE0CB0B0BD00BF0D98020048 -:10BA7000407B00201826002044BB0200F0B585B0B2 -:10BA800080B3194FFC686CB305461CB3A61C29464D -:10BA9000082230460CF0CCFA08B9E468F5E7B8683B -:10BAA000A8B102AD31460822681C0DF071FB05F10A -:10BAB0000A01304609F0A9FF0120092100220C23C8 -:10BAC00000958DF808000948007807F0D4F9204661 -:10BAD00005F02EF8F86828B904484FF400610078A2 -:10BAE00002F086FF05B0F0BDAC2200209F88002048 -:10BAF0002DE9F0410446007A012801D1258803E0B0 -:10BB0000204608F0A1FF05464FF6FE70854208BFAB -:10BB1000BDE8F0811048471C104806781048B0F87E -:10BB200000809EB1217A3878012902D1012801D004 -:10BB300009E040B9B7F80100A84204D1781E414697 -:10BB4000FF220DF0BBF90E37013EEAE72846BDE8BB -:10BB5000F04105F039B800BF18870020E2BC0200B0 -:10BB6000C2B4020070B505460DF0E8FC164E04465E -:10BB7000B068D0F8E010D0F8EC0050F8250008606C -:10BB8000B168D1F8E410086010480068C06B8047C5 -:10BB9000104AB1681368D1F8E01063B90C4B1B78F8 -:10BBA0009B00B0FBF3F50868854204D9B5FBF0F5BE -:10BBB00068435843106008680BF03CFC2046BDE821 -:10BBC00070400DF067BF00BF0C01002030880020DE -:10BBD000B08800202C880020BCB51A4900200968D4 -:10BBE00011B104310130FAE7C5B268000EF01CF85B -:10BBF00018B3144904460020096831B131F8042B08 -:10BC0000C3B2013024F81320F6E70F49B1F86E00F3 -:10BC1000CA8A904207D101F1390200212B460094D3 -:10BC200002F026F906E001F1390200212B460094CA -:10BC3000FCF7D4FE20460DF0F5FFBDE8BC400BF04C -:10BC400017BE00BF40270020407B002000B1704796 -:10BC5000B0B51A4CE06C58B340F2000CEFF3118011 -:10BC60008CF311882020EFF3118180F31188D4E93F -:10BC70001650E16CB1FA81F1C1F11F0100EBC10175 -:10BC80008D4215D2086802680A6051600A688A42CB -:10BC900004D1416AE26C22EA0101E16401F048FA50 -:10BCA000E16C29B1E06DB1FA81F1C1F11F01E5E765 -:10BCB000002084F84800BDE8B0407047A01F002075 -:10BCC0002DE9FF41044604201E4690460F468DF89C -:10BCD0000D0003A80AF0D4FDC0B1054646B101200D -:10BCE000AF80A8770020E876287840F080002870A0 -:10BCF0002869390AC1700321877080F801800170BA -:10BD0000204607F037FF18B100200AE001200DE0BF -:10BD100001AE2046314609F061FE0028F4D02E62C3 -:10BD20000120687728466C8002F0D8FD04B0BDE899 -:10BD3000F081B0B58CB0044601206D4611213A2344 -:10BD40008DF81E0020882A46ADF81C006068099016 -:10BD500000200CF035F928B1684611210DF0B4F837 -:10BD6000002001E09DF8000001218DF81F00681CF3 -:10BD700025898DF8291008900DF016FC854202D116 -:10BD80000020002106E02089ADF8140060680690CC -:10BD900005A901200B918DF82A0007A8EDF7C4F939 -:10BDA0000CB0B0BDF0B589B0054600200C460121AD -:10BDB000ADF810200890CDE905504FF6FC708DF8D5 -:10BDC0001E108DF813408DF81210101A032811D888 -:10BDD00002280FD000208DF81D0004A8EDF7A4F96B -:10BDE0000646284621460BF005FA07F043FA30468E -:10BDF00009B0F0BD02206F46ADF802208DF80000BA -:10BE00003846FDF7A7F801260128EAD1381D8DF83C -:10BE10001D600690E1E77047BFB50568174A687A6C -:10BE2000012807D11268686990F82110406992686A -:10BE3000904714E068696C4690F821101068826899 -:10BE4000204690476869416990F82120204608F013 -:10BE50009DFA08B1686801E06FF003006860084867 -:10BE600040210160802101600021C0F8FC12022005 -:10BE700008F07EFC03480DF0E9FEBFBDFC01001098 -:10BE800004440240307E0020F8B506680D460446A2 -:10BE90000DF054FB16490978012902D196F82210B9 -:10BEA00019B10DF0F7FD00241FE0012786F822707C -:10BEB0000DF0F0FD0F49002D18BF294648680A789B -:10BEC0007060002086F82020022A4FF0000208BF90 -:10BED0008A6886F8240086F8250086F82370B26008 -:10BEE00086F826000A20F9F723FF2046F8BD00BF98 -:10BEF0009927002004BB020070B5194A194C103272 -:10BF00002378002918BF0121002573B112F8106CA5 -:10BF100005F00105864206BF11700E4616783543BE -:10BF200018BF01251832013BEFE7A078E90708D0D8 -:10BF300098B90120012609F039FA022009F036FAF1 -:10BF400008E0012809D1012008F012FC022008F0C5 -:10BF50000FFCFF26A0783044A07005F0010070BDF2 -:10BF6000B46E0020442500202DE9FF41194F4FF603 -:10BF7000FE764FF000086C464FF6FE7080B2B0427D -:10BF800024D10DF0E9FC0546F88A85424FF6FE7093 -:10BF9000F4D00DF0F7FA85424FF6FE70EED0284649 -:10BFA00007F0E8FD00284FF6FE70E7D1002D4FF6B0 -:10BFB000FE70E3D020468DF80080ADF80250FCF70B -:10BFC000C9FF002818BF35462846D7E704B0BDE8AA -:10BFD000F08100BF407B00202DE9F843194E044654 -:10BFE00000274FF0D3084FF6FF79366836B3E08963 -:10BFF000F18881421AD1A07C20300BF035F800285E -:10C00000F3D02146202205460DF0C2F8A27C2AB1C9 -:10C0100005F12000A861A1690DF0BAF83079294630 -:10C0200085F8008003F040F80127DEE74945DCD1C0 -:10C0300001B20029DFD41328D7D1DCE7F8B2BDE87C -:10C04000F88300BF682700202DE9F843194C099FA9 -:10C050008146884611461D4660683E7A0DF08FFD88 -:10C06000089905700A0A41708270397AC170397A6C -:10C07000012908D003290AD104300A9D39460DF060 -:10C080007EFD057003E039780171797841711020E7 -:10C090000C2341464A46A070012E08BF0E232046BD -:10C0A000032E08BF152303F0B7F90021A170BDE8E6 -:10C0B000F88300BF7C2600202DE9FC4118200DF0FC -:10C0C000B3FD60B3044617484FF00008002700F1A5 -:10C0D0000806032F1AD03078012814D1BDB20620EB -:10C0E00000221823009429460AF054F958B956E959 -:10C0F000020118222346C4E90401062029460AF059 -:10C100005FF986F800800C360137E2E720461821F7 -:10C110000CF0DAFE2046BDE8FC410DF083BDBDE821 -:10C12000FC8100BF18830020F0B585B0194EB268BD -:10C13000116F91F82B1059BBD2F8D410897839B30C -:10C14000C168007AD2F88821904708B30446B068E5 -:10C15000016F91F82B2042F0040281F82B20D0F8D7 -:10C160005C1302AD28468847F0680127816A0120E8 -:10C170008847B0682A46D0F87863016FD0F8D400B9 -:10C18000C38C01F120002146CDE900700520B047A5 -:10C1900005B0F0BD0C01002070B517480D22002439 -:10C1A00001680131B1FBF2F303FB1211134A52F89B -:10C1B000213042F82140016011490868C01A086026 -:10C1C000F8F7C8F90F4D2E780DF0FEFC04462869EB -:10C1D0000DF000FD00B170BD002E1CBF4AF200360C -:10C1E000C1F2E116B6FBF4F128690DF0F5FC2869FF -:10C1F000BDE870400DF0F2BC14880020488100209A -:10C200001C880020B824002010B51648816829B188 -:10C21000154908308968D1F8541288470DF08EF915 -:10C22000124900240A6813681C7112680A600DF034 -:10C2300031FC0F48017811B90E49097849B10470F1 -:10C240000C48047004F018F80748C168C9680978F8 -:10C2500001B110BD80680021D0F858240020BDE84D -:10C2600010401047242500200C010020C08700202A -:10C27000AC880020AF88002010B514480068C06B5F -:10C28000804714491248144A09780068890001FB64 -:10C2900000F4B2FBF1F1884204D910488068D0F86C -:10C2A0004C0580470E480168214401600D48214437 -:10C2B000F5F7EAF909488068D0F8E40480470DF002 -:10C2C0003DF9BDE810400DF0E5BB00BF308800200F -:10C2D00038880020B0880020FFF6C2FF0C01002043 -:10C2E0002C880020B161020070B568B115460E4679 -:10C2F000044604290AD0022E11D0012E04D10120B7 -:10C3000009F0ACFA114905E0C12070BD042009F024 -:10C31000A5FA0D490978884284BF112070BD0C49E7 -:10C320000020258166736060086820B1416809B10A -:10C330000846FBE7011D07480C602021007801F04A -:10C3400087FE002070BD00BFE3BC0200E5BC020018 -:10C350005488002098880020FEB5044614486D4695 -:10C36000046028460DF034FB124E002000212A46BE -:10C370008DF8000030460CF053F80F4F07F13405EC -:10C380007E6028460DF072FA0C480521BC630C4C07 -:10C390004FF440620023BA642A46C7E910100949E5 -:10C3A00020460AF0C5FCBC600CF0DBFDFEBD00BF02 -:10C3B0005C27002040850020882100208037002055 -:10C3C000D87C0020014B00007CB5044606981D4631 -:10C3D0000B46362902DB174A00210AE012491646AD -:10C3E000124AE381096E51F82310914207D00021CF -:10C3F0000F4A0091002108F063FD01207CBD184622 -:10C4000005F090FF286969682073C4E90016287A4E -:10C41000A060297D11B140F00200A0602046FEF727 -:10C4200047FB00207CBD00BF381F0020916C02003C -:10C43000B3AF02006FB1020010B596B0184C2020C7 -:10C44000EFF3118180F31188E06810B90AF04DF91B -:10C45000FAE7E068216A134A0223B0FA80F0C0F1DB -:10C460001F00137501EBC002E26151F8300000219A -:10C470002174A06140F2000CEFF311808CF311885D -:10C480002020EFF3118180F311880CF00DFDA169DC -:10C4900068461C301C310AF037FC16B010BD00BFD6 -:10C4A00038220020381F00202DE9F041B3F1FF3F72 -:10C4B00003DC5B42B1F1FF3F24DD4FF0000C4FF095 -:10C4C000010EDFF85080471E0026B1FBF3F505FB97 -:10C4D000131418F80440BC55013E8B422946F4D988 -:10C4E0003044714230230138914203DA00F80139B7 -:10C4F0000131F9E7BEF1000F0CBF80F800C0013038 -:10C50000BDE8F081013A49424FF02D0C4FF0000E8A -:10C51000D7E700BFC7A2020070B511B3154602B33A -:10C5200006680C4606F069FCB0680DF0ADFA47F6F7 -:10C53000FF704FF6FF71854238BF28468D4218BF05 -:10C540004500A6F8585060080FD04FF47A7100FBF0 -:10C5500001F40DF039FBB4FBF0F1A04288BF0121DA -:10C5600004E0BDE870400BF018B80021B068A6F8F0 -:10C57000561089B20DF030FBB0680DF02FFB022091 -:10C5800086F8500070BD7047B0B5056804460CF0E1 -:10C59000D5FF002185F8241095F82120033A022ABE -:10C5A00028BF85F825100DF075FA0F488168B1F1A4 -:10C5B000FF3FDCBF4FF0FF31E9610C4901602046CD -:10C5C00007F0F8F995F82000022804D10848BDE8E2 -:10C5D000B0400DF03BBBD5E9002CE96995F821305E -:10C5E0002046BDE8B0406047884702400100008017 -:10C5F000807E0020FEB5876A04467E7801ADB91CB6 -:10C6000028460DF0BCFA1548294639300BF04DF894 -:10C61000B8B11F2E12D806F01F0568000DF004FBFC -:10C6200078B1064607F10A0000218D420AD000EBDE -:10C630004102128826F811200131F6E7D320FAF7DB -:10C6400068FBFEBDA089009601AA00212B4601F0DF -:10C650000FFC30460DF0E6FAFEBD00BF407B002027 -:10C66000F8B5174E706808B1804730B3B068FDF771 -:10C67000B7FE144F044600253978E8B2884206D246 -:10C68000FBF77EF83178013508433070F4E70E4F40 -:10C6900000203578F8707870481E7E21B870B88B0D -:10C6A000F880002007F0E2FFB878FE2107F0DEFFF7 -:10C6B000B068214601F0F2F900E00B252846F8BDEC -:10C6C000A023002097880020A0800020F0B587B02C -:10C6D000ADF81810059033B32AB31C466B461146CB -:10C6E00005A81A4601F084FC0546E8B9114F7868A0 -:10C6F00008B18047D8B1B868FDF772FE06466846B3 -:10C7000021460022EBF7C6FB054638B9BDF80C10F0 -:10C7100021B19DF8100004F01DF83D78B86831464D -:10C7200001F0BCF900E00425284607B0F0BD0B2558 -:10C73000FAE700BFA02300202DE9FE4F1648174E50 -:10C74000DFF85C904FF6FF774FF00208EB464FF0B2 -:10C75000FF3A0A240578E5B13088B84216D07188CE -:10C7600071B10139718089B2B1FBF4F202EB82023E -:10C77000A1EB420151B90CF0DBFC0BF0E9F905E04B -:10C780000CF0D6FC0DF074FAC6F800A00436013D9A -:10C79000E1E7BDE8FE8F00BFD6BC02008086002026 -:10C7A000407B00202DE9FC41E84604464146FEF767 -:10C7B00037FA30B31448DFF854C000210078CFB204 -:10C7C00087421BD2FB0053FA81F363441B7AC3B147 -:10C7D00007EBC707C3F10806F5B2674408EB050687 -:10C7E0002F4435783A78AA4206D1013B07F1010778 -:10C7F00006F10106F5D104E00131E0E72046F6F745 -:10C8000053FEBDE8FC8100BF8E270020186A00207F -:10C8100010B586B0184C00218068CDE90411CDE92F -:10C820000211019402A9009105A904AA03ABF2F731 -:10C83000E5FF05994FF6FF720988914201D00C4639 -:10C8400017E00399002918BF01210140012904D1F3 -:10C85000029911B101AA084602E050B1049801AA58 -:10C860002B210BF00FFCFF2803D00198204000F192 -:10C870000044204606B010BDFFFF3F0070B50546DE -:10C880000CF05CFE174E044696F82400A84386F888 -:10C890002400306820B1B8300DF09CF9054600E066 -:10C8A0000025706818B1B8300DF094F9054396F87A -:10C8B000240030B92DB9306A18B190F828108907D2 -:10C8C00004D42046BDE870400DF0E4B8456A204627 -:10C8D0000DF0E0F8306A022100220024A8473462FB -:10C8E00070BD00BF7020002070B5B0B00FAC8421C7 -:10C8F00020460CF0E9FA154803A90A4690E86800BA -:10C90000042068C28DF82800CDE9014102F050FCF6 -:10C9100001A80AA9FCF77AF998B106AD0C490446BA -:10C92000142228460CF0FEFD204629460DF098F909 -:10C93000054620460CF0B4F9002D18BF4FF0FF3526 -:10C9400001E04FF0FF35284630B070BDA0BB0200BB -:10C950001C86002010282FD1FEB5184E0C463078CA -:10C960008DF804000DF032F905460DF02DF96843FD -:10C970004FF47A77B0FBF7F08DF805000DF026F94B -:10C9800005460DF021F96843B0FBF7F0000A8DF879 -:10C9900006000CF035F901AD01460222E81C0CF04E -:10C9A000F7FB002000212A4640230094ECF730FFDB -:10C9B00020783070BDE8FE40704700BF91880020AD -:10C9C000F8B5184DA87808B1012429E00DF103014C -:10C9D000E12009F027FB144E9DF803100024307E5F -:10C9E00081421DD001270DF1020152208DF8024035 -:10C9F000AF7005F043FB307E0B380F2804D806F1EA -:10CA00001801E12005F03AFB0DF1020152208DF8EA -:10CA1000027005F033FB002000240CF051FCAC70D8 -:10CA20002046F8BDC0260020407B00207FB504468C -:10CA30001748184E00783178084302D1608800B159 -:10CA40007FBDA0690578FF2D08BFFE2528460AF0A6 -:10CA50001FFF8DF80F000CF0E3FA10B1284609F023 -:10CA6000FFFF307810B9284609F0FAFF207B002834 -:10CA7000E6D100200DF10F0148F236020123CDE985 -:10CA8000001004F11100A11C04F0CCFD7FBD00BF1B -:10CA9000AF270020182600202DE9FC410020ADF82A -:10CAA000040014200DF0C0F840B3DFF854800446B1 -:10CAB000D8F80000F8B100264FF6FE770025122EB8 -:10CAC0000DD08119A019062202300CF061FBD8F8B4 -:10CAD0000000815BB94218BF01350636EFE7ADF8BB -:10CAE000045001A9204602220CF052FB4C201421D4 -:10CAF00022460CF08BFE20460DF094F8BDE8FC8138 -:10CB0000E026002010B50DF0D5F809F0F9FF134C20 -:10CB1000A068D0F8D40090F843000AF055FCA06853 -:10CB200000210024D0F858240120904704F0BEF8DA -:10CB30000AF00EF8F9F764FC09481221C0E9004434 -:10CB4000846008480CF0C0F9074804700748047076 -:10CB5000F8F7C0F8BDE810400CF074B90C010020E3 -:10CB60004C87002094860020A6880020A5880020FD -:10CB7000B0B5174C6068216801EA000521EA00029F -:10CB8000680622601DD51348006800F44000B0F527 -:10CB9000000F03D11048006807F0D0FD04200CF00E -:10CBA00075FD811E022905D207F0A8F8022007F0C2 -:10CBB000DFFD03E0012808BF07F0A0F8202008F0FF -:10CBC00035FE280648BF04F0C7F9A560B0BD00BF18 -:10CBD00090220840B44F0050D02600202DE9F041AB -:10CBE0004FF02008EFF3118188F311880122144FD0 -:10CBF00011490D7A0A72114991F8486081F848206C -:10CC00000021104A3C7D3975396D1268D2B251F855 -:10CC10002210886040F2000CEFF311808CF3118831 -:10CC2000D1E900018847EFF3118088F311883C7542 -:10CC300046EA0520BDE8F08138220020A01F002030 -:10CC4000381F002004ED00E0F8B541680A780F2A8B -:10CC500013D0082A1FD0062A1CD140894A1C0292F0 -:10CC6000ADF80400B1F80900ADF80C00C87A8DF8F1 -:10CC70000E0001A806F03CF98FBD40898A1CADF872 -:10CC8000040048780A31029203918DF8060001A849 -:10CC9000EFF7D0FD8FBD4089ADF8040048788DF8DE -:10CCA0000600022804BF881C029001A806F002F9C1 -:10CCB0008FBDB0B586B0044600202121CDE900002B -:10CCC00002904FF48670ADF804002088ADF80000A3 -:10CCD000607A0028684608BF01218DF80210F2F73B -:10CCE00075FC9DF8140098B90398456C062005F86A -:10CCF000010B616828460CF042FFA0782872E078AA -:10CD00006872207AA872684605F0F8FB9DF8140056 -:10CD1000217A002908BF084606B0B0BD2DE9F04FC2 -:10CD200089B006468800994690460F1D4FF0000BCB -:10CD30000DF1040A8DF80300380415D0B8B23C4652 -:10CD4000B1B25246202828BF2024A5B248462B461F -:10CD50000CF0E6F95FFA8BF051462A460BF09CFA8C -:10CD6000834626443F1BE7E75FFA8BF00DF1030192 -:10CD700001220BF091FAB0EB080018BF012040002F -:10CD800009B0BDE8F08FF0B540F6FF7C10F8013B2C -:10CD90000024082CFAD00646DF0716F8015B0AD1FA -:10CDA000467806F00F070337122F0AD187783A0624 -:10CDB00009D403300DE001F8015B304601345B0813 -:10CDC000E7E7023006E0C27807F07F07043047EA61 -:10CDD000C2171237320942EA0515654508BFF0BD92 -:10CDE000ED43002FEAD04A5D013F0A700131F8E7B8 -:10CDF00089B36FF0C0020B0E02EA8112202B05D01E -:10CE0000212B05D0A02B05D1302118E0102116E0F0 -:10CE1000202114E0B1F1807F01D240210FE0102BDE -:10CE200005D0112B05D0402B05D1702107E05021F2 -:10CE300005E0602103E09021502B08BF80211143C1 -:10CE400041F00F0104C8531C18BF8A42FAD14FF0B9 -:10CE5000FF3140F8041C7047B0B51749174A00234A -:10CE60000978994206D002EBC3046488844203D057 -:10CE70000133F6E70C4600E0DCB24FF6FE73984251 -:10CE800008BF8C4201D02046B0BD0024A14204D08E -:10CE900012F8340018B10134F8E70C46F3E702EB5E -:10CEA000C405E4B268686B800028ECD00CF0BAFED0 -:10CEB00000206860E7E700BF9ABC0200E02700207E -:10CEC00070B50468616F59B3D4F858214568566845 -:10CED000E96B28683268D16201210BF05BFDD4F860 -:10CEE0005801E96B0F4A40680068C0F8041591FAD0 -:10CEF000A1F112683068B1FA81F192699047616FCF -:10CF0000091AE07C20B104F14C0006F04BFF05E06B -:10CF1000206FA26F401A20675018A067002060673A -:10CF200070BD00BFD40100101CB5002008F06AFEDF -:10CF30000CF03AFB04460BF063FE01460F48002359 -:10CF40008278204606F0D6FF002008F05BFE0D48F0 -:10CF50000078022810D10A48007801280CD16C46CC -:10CF600020460CF03EFD0CF00DFB07490B780749FD -:10CF70000A78214602F040F81CBD00BF2687002039 -:10CF8000BA27002018260020C0270020C227002032 -:10CF90002DE9FC4114200CF047FE40B3044615482F -:10CFA0004FF00008002700F10806C82F1AD030788B -:10CFB000012814D1BDB20420002214230094294674 -:10CFC00009F0E8F958B956E9020114222346C4E9E8 -:10CFD00000010420294609F0F3F986F800800C3698 -:10CFE0000137E2E72046BDE8FC410CF01BBEBDE87E -:10CFF000FC8100BF8043002070B50CF09FFA164DF5 -:10D000002E782978012902D10CF044FD0EE001218F -:10D0100029700CF03FFD1148C168C968097829B929 -:10D0200080680021D0F85824012090470CF04EFE73 -:10D0300004460CF083FA04B92E700CF02BFD07485F -:10D04000C168C968097829B980680021D0F85824D6 -:10D0500000209047204670BD162500200C010020BE -:10D06000F8B5174E154D044631682868496D884754 -:10D070006040B0F1FF3F07DC124FB868D0F8D40031 -:10D0800090F8830001280BD10CF03EFC832808BFE8 -:10D09000F8BD0C488068D0F84C05BDE8F840004762 -:10D0A00009F0B2F80CF030FC832803D0B868D0F84F -:10D0B0004C058047BDE8F8400BF0B0BED8260020F4 -:10D0C000308800200C01002010B5184C0021A06809 -:10D0D000D0F8E8000160A068D0F8D8100968B9B1AC -:10D0E000D0F8E02049681268914211DA07F036F86A -:10D0F000A168D1F8D82012685368834204DA5060DE -:10D10000A168D1F8D8000268D1F8E8000260A068F0 -:10D11000D0F8DC10096841B1D0F8E80002681AB113 -:10D1200052684B68934200DA016010BD0C01002088 -:10D130002DE9F047164C002100F12C03154D4FF05E -:10D14000010A80F8281084F848100ECBD4E914891D -:10D15000A76D2E7DC4E91503226585F814A001632F -:10D1600040F2000CEFF311818CF31188D0E9053205 -:10D17000C169104698472020EFF3118180F3118890 -:10D180002E7584F848A0C4E91489A765BDE8F08726 -:10D19000A01F0020381F00202DE9F84380461548C5 -:10D1A0001549DFF858900078002818BF0120087052 -:10D1B0000024312C08BFBDE8F88309EBC40039F81E -:10D1C000347046884568384631462A460CF018FBCC -:10D1D00068B93846B8F1000F04D031462A460CF041 -:10D1E00015FB04E0002132462B460BF053FE0134C0 -:10D1F000DFE700BFB2270020C488002010AA020089 -:10D20000B0B58EB001AC0546342120460BF05CFE73 -:10D21000D5F8020029690022CDF80E00287D0B9177 -:10D220004FF6FF71ADF8001069468DF82000287F99 -:10D230008DF80900288DADF81400287E8DF80A00BD -:10D24000687E8DF80800688DADF8320095F82C00E6 -:10D250008DF83400FF208DF802002046E9F7EAFB44 -:10D2600000200EB0B0BD7CB5054600EB4000144672 -:10D270000E4602308DF8050001A809F001FB18B335 -:10D280000169082201F8022B05F01F02324301F860 -:10D29000012C0022D3B2AB420ED2237801320B70A4 -:10D2A00063784B70E678A378043406F0070663F3DE -:10D2B00006168E700331EDE7012181764FF6FC7181 -:10D2C000418001F00BFB7CBD01207CBDB0B5056841 -:10D2D00004460CF033F9A97819B1BDE8B0400CF060 -:10D2E000D9BB002169700CF0D5FB0E488168B1F103 -:10D2F000FF3FDCBF4FF0FF3169600B490160204602 -:10D30000FEF78AFD287A022804D10848BDE8B0401B -:10D310000CF09CBC6B7AD5E904C269682046BDE874 -:10D32000B04060478847024003000080807E0020B4 -:10D330001CB50C46097F052904D104F10801FDF74D -:10D340006FFC18B304F108000DF106010BF092F820 -:10D35000BDF806004FF6FF71884204BFA1201CBD36 -:10D36000217801290FD10A4A00EB400102EB81012B -:10D37000A26951F8043F9A423CBFA2201CBDA08282 -:10D38000501C086000E0A08200201CBDC8201CBD0D -:10D39000188300202DE9F04385B01548154F00266D -:10D3A0004FF0FF080DF104090024007800EBC000E5 -:10D3B0008500B54218D0B81990F82110802910D1F5 -:10D3C000B95980F8218010224B46019141680291A1 -:10D3D000017D80698DF80C100490A1B2032008F043 -:10D3E000EFFF24360134E4E705B0BDE8F08300BF69 -:10D3F000E6BC0200B0540020F8B50D480D49FF22EC -:10D400000088097841430C480BF058FD0B480C4943 -:10D410000C4A0D4B0D4C0E4D0E4E0F4FC1610021AD -:10D42000C0E90176C0E90354C0E905320170F8BDD6 -:10D43000C2B40200E2BC020018870020EC230020E6 -:10D440009D4502008D050200FD250200F91B02002A -:10D45000F1BA0100D5600200F5ED000010B5154AE3 -:10D46000212074210CF0CCF90A38B0FA80F044097C -:10D4700005F064F80A28104808BF02340078012833 -:10D4800004D805F09BF80A2808BF04340B4801684B -:10D4900019B188470A2808BF083405F0F9FF0A289F -:10D4A00008BF103404F0E2F80A2808BF20342046F0 -:10D4B00010BD00BF407B002018260020FC23002068 -:10D4C0002DE9F84305461548DFF8549088460024B6 -:10D4D00000F1140699F80000C1B28C4228BFBDE8E3 -:10D4E000F883FF2D08D156F8107C0CF095F987428F -:10D4F00009D099F8000003E016F8141CA94202D0E4 -:10D5000018360134E8E70CF022FA31680A6822EA9A -:10D5100008020A60BDE8F8430CF0F5BAB46E0020CA -:10D5200044250020B0B51448144D807B95F839117E -:10D53000084306D00CF002F895F83B1121B10CF02D -:10D54000A9FA00242046B0BD012485F83B410CF027 -:10D55000A1FA022007F02AFF0D20F8F7E9FB08489E -:10D5600001680029EED1074940220A604A60002183 -:10D5700085F83A11C461E4E790BA0200D81B002094 -:10D5800004800C4038500C4079B36FF0C0020B0E91 -:10D5900002EA8112202B05D0212B05D0A02B05D12A -:10D5A000302118E0102116E0202114E0B1F1807F35 -:10D5B00001D240210FE0102B05D0112B05D0402BBC -:10D5C00005D1702107E0502105E0602103E09021A2 -:10D5D000502B08BF8021114341F00F0104C8531C98 -:10D5E00018BF8A42FAD140F8041C70471CB5154890 -:10D5F000017E022904D11920BDE81C400BF040BD7A -:10D60000017E01291DD0007E04281AD00BF096FF60 -:10D61000044601A8F9F7CEFB28B101990A4831B1B7 -:10D620000BF080F80AE008480CF02EFA06E00CF047 -:10D630002BFA0648042128300CF00CFB20460CF095 -:10D6400029FA1CBDD01E0020647F0020702000201D -:10D65000B0B54FF0FF300BF04BFD104D04461049B4 -:10D66000E86988420DD10F480F4900220BF0C0F93C -:10D670000220287607F0B2FE18B9FAF793FAEAF713 -:10D68000EFFE0A48044208BFB0BD09484FF0005100 -:10D690002830BDE8B0400CF0DDBA00BFD01E00203D -:10D6A0002D37000030210020D10C01000200004085 -:10D6B00070200020F8B5174F06460D46F88AB04294 -:10D6C00001D1012405E0304629460023FEF7F8FA8F -:10D6D00004463046002103F061FEF98A884216D1E3 -:10D6E00028460021FCF7BCFB68B1817911F0180FC6 -:10D6F00009D04388F98A00884FF6FE720092002212 -:10D7000002F087FB03E02846012109F053FC204684 -:10D71000F8BD00BF407B00202DE9FF41144DD5E945 -:10D7200000673879F8F704FB0BF008FF04463078FF -:10D73000B0B90DF1040840460BF09AFCB87979793C -:10D740000C4A434601950290301D05F049FC3868AB -:10D750004FF0FF31C16208498160012131704160A1 -:10D7600020460CF097F9024804B0BDE8F08100BFF4 -:10D7700044BC02008B9902000018002010B5174B22 -:10D780000C0A5B68597000219C701970117801F0C7 -:10D790001F01D9705178197191785971D1789971A7 -:10D7A0001179D9715179197291795972D179997226 -:10D7B000117AD972517A1973917A5973D17A99730E -:10D7C000117B00F11102D973811C104648F202024C -:10D7D0001023BDE8104001F01FBE00BF7C260020D2 -:10D7E0002DE9F04385B050B3144642B30DF104085F -:10D7F0000E46054640F20110002110220027434644 -:10D800000BF048FB06F00F062046C6F1100908EBA6 -:10D8100006014A460BF0BCFC04EB090041463246C7 -:10D820000BF0B6FC082F0AD0E85DE15D4840E11935 -:10D83000E0550A7AE85D013750400872F2E705B01A -:10D84000BDE8F083F8B50D4609881446074609F08F -:10D850002FF908B1B820F8BD114806780BF098FAF6 -:10D86000B04224BFB220F8BD18200CF0DDF9A0B101 -:10D87000064607710020294612223060B01D0BF0C9 -:10D8800087FC0848016811B108460968FBE7066093 -:10D890000CB106F083FB0020F8BD1020F8BD00BFDE -:10D8A000CDBC0200EC260020F8B505460020164F3E -:10D8B0000C462860F868C068007828B9B86800216C -:10D8C000D0F85824012090470BF038FE0646284631 -:10D8D00021460BF0FBF821462046006828B142683B -:10D8E0006B68934201DB0146F7E70D602860206812 -:10D8F000A84203D1B868D0F8D40480473046BDE8C8 -:10D90000F8400CF0C7B800BF0C010020E0B5174983 -:10D91000FF238868426913764269D37E012B16D1B2 -:10D920000021D176C16BC97AC1B1FF218DF80710F2 -:10D93000D0F8D41091F84320B1F85210ADF805108A -:10D94000D0F8D4138DF8042001A888478CBDD0F8F6 -:10D95000D400427B90F82C00904200D18CBDC86866 -:10D96000406C8047BDE88C4009F040BD0C010020B0 -:10D9700010B5164900220C2A0BD08B1804325B8894 -:10D980008342F8D188181249097800F8041CC52090 -:10D9900010BD00224FF6FE730C2A05D08C180432FD -:10D9A00064889C42F8D108E000220C2A04BFC720FA -:10D9B00010BD8B5C0432002BF7D11144044A21F8CE -:10D9C000020C0020127801F8042C10BD34870020CE -:10D9D000DDBC0200C10714D1010715D4C10616D45D -:10D9E000810617D4C10418D4810719D441071AD469 -:10D9F00041041BD4002110F4204F08BF4FF0FF3129 -:10DA000016E00C48016813E00A48416810E0094834 -:10DA100081680DE00748C1680AE00648416907E0EF -:10DA20000448816904E00348C16901E001480169D3 -:10DA300008467047F082002010B51548007802288B -:10DA400022D112480078F8B94FF6FF700021EDF7A7 -:10DA500063FF104C012040F6B831A04708204FF476 -:10DA6000DC71A04710206421A04720206421A0473A -:10DA70004FF480504FF47A71A047074A352028218F -:10DA8000BDE810400BF0C2BE10BD00BFD52700207E -:10DA900018260020DD460100F082002070B5174AEC -:10DAA0000546906910B30123147A137209BBE96823 -:10DAB000426905F11406914202DAE968F8F72EF896 -:10DAC0003068B04213D06869016869614E6080684F -:10DAD00028614169E9602021EFF3118581F3118804 -:10DAE000294607F0D3F985F3118802E070BD0120C3 -:10DAF000A8602046BDE8704005F08CBE38220020AA -:10DB0000B0B58AB01048C178D9B901250F4924228F -:10DB1000C57001AC20460CF0F3F84FF400708DF89E -:10DB200024500D4D0D4922460023069008480590CB -:10DB30000020049007480190284609F0F9F80848A9 -:10DB400045630AB0B0BD00BFA01F0020C0B80200EE -:10DB50001868002085A20200307D0020B59B0200DD -:10DB60003822002021F003010844009940F8083CC5 -:10DB700040F80C2C40F8041C029940F8101C019944 -:10DB800040F8141C0F4940F8181C4FF0FF3140F8C2 -:10DB90001C1C40E9091140E90B1140E9131140E94F -:10DBA000111140E90F1140E90D1140F8781DC0E94D -:10DBB0000911C0E90111C0E90311C0E90511C0E96B -:10DBC000071170471D8902002DE9F041077B0446CB -:10DBD0000D20884600EB4700C5B228460CF024F81B -:10DBE00008B306462078211D3070701C0BF0C7FF6B -:10DBF000A07804F10E013A467072E078B072607B52 -:10DC00003773F07206F10D000AF008FD48F080004D -:10DC10002A463346C1B2452004F030FD3046BDE807 -:10DC2000F0410BF0FFBFBDE8F0812DE9F041044663 -:10DC300008200BF0F9FF10B305462078C71C02201E -:10DC400050FA87F8404609F00FFA6860A0B1FE214B -:10DC5000FFB2017021463A46686801300CF050F876 -:10DC60006E683946701C0AF0F9FDB9194870002039 -:10DC7000A5F80280287003E028460BF0D3FF0025AA -:10DC800020460AF0EFF82846BDE8F0812DE9F04182 -:10DC9000D0F8A8501F4616468846044625B12046AF -:10DCA000414632463B46A847D4E928010F4006408A -:10DCB00056EA070008BFBDE8F081204641468022B1 -:10DCC00004F0AAF8C4E92C6740B1D4F8A810816028 -:10DCD000D0E90812B143BA43C0E908120020C4F8E1 -:10DCE000A80004F15000BDE8F0410BF0AFBF70B5E3 -:10DCF00020220D4604460BF04BFAA87C0026E66174 -:10DD0000666160B140000BF08FFF606130B1AA7CAA -:10DD1000696952000BF03CFA002600E00126287EDB -:10DD200048B140000BF080FFE06128B12A7EE9692C -:10DD300052000BF02DFA4EB1606908B10BF072FF82 -:10DD4000E06908B10BF06EFF002070BD012070BDCE -:10DD500070B5044613480168F1B1114E3068D8B16E -:10DD60000E4D2868C0B160888847A8B90E48007871 -:10DD700030B10E4951F82000C0EB0010810001E0E5 -:10DD80000A480168608832689047012804D1608899 -:10DD90002968BDE87040084770BD00BF9C23002083 -:10DDA0009423002088230020C727002060B70200AA -:10DDB0007FB50BF0C3FB114E04463078C8B901ADF6 -:10DDC00028460BF055F900200E4A27212B468DF8E6 -:10DDD0000C004FF0FF300290094805F001F90A48A5 -:10DDE0000121012509F074FE0848002109F070FEA8 -:10DDF000357020460BF04EFE7FBD00BF9A270020F5 -:10DE0000B484002093820100307E0020807E0020B8 -:10DE100070B588B0134E0D460446C22096F8261001 -:10DE200004291CD008291AD086F82E50B46201A803 -:10DE3000182104300BF048F802208DF809500194A5 -:10DE400086F8260001208DF808000748007802288F -:10DE500002D106480021017001A800F081FE08B03F -:10DE600070BD00BF407B002018260020CC2700207A -:10DE70002DE9F84FDFF854B00646DBF8000010B388 -:10DE80000E20DDF828801C4691460D4600EB43002D -:10DE900009F0EAF8B8B1074605714680D420494632 -:10DEA0004FEA440A3870781D0BF069FE07F10E0046 -:10DEB000414652467C730BF06BF9DBF80010384694 -:10DEC000BDE8F84F0847BDE8F88F00BF5027002095 -:10DED00070B504468069A16A4D788E780BF0D1FD4B -:10DEE00088B10179013901290DD801210E2D14D8ED -:10DEF0009EB9002101750C4935B151F82510C1EBCF -:10DF00000111890001E070BD09680122C0E9061114 -:10DF100080F8202005F0AEF9002104480278A0899D -:10DF2000BDE8704001F082BC60B70200CC27002041 -:10DF300070B5154E04464FF6FE713088884221D1E7 -:10DF4000162009F091F8E8B10546A07902210028D1 -:10DF500008BF0121697001202870A06A4078A8726A -:10DF6000000702D4A08903F0A1FCA169A81C0BF052 -:10DF700006FE00202946E8740448007801F094F871 -:10DF8000A089308070BD00BF7427002098880020D1 -:10DF9000F8B50D4606460BF0DAFC134F0446387808 -:10DFA00008B100251BE0B5F5877F07D906F5877016 -:10DFB0003861A5F587704FF4877501E0002038615E -:10DFC000B8800A4831462A460BF09AFE0120387084 -:10DFD000786901307861284606F02EFB0546204618 -:10DFE0000BF091FD2846F8BD702400203872002007 -:10DFF00070B50023B3EB113F1CBF052070BD037843 -:10E000003F2B84BF092070BD44880026B6EB942FB7 -:10E010001CBF072070BD8588B6EB952F1CBF08205C -:10E0200070BD0A480078032804BF032070BDD18169 -:10E03000962100201372D4809580917221039081E3 -:10E0400041EA03612943116070BD00BF88270020A9 -:10E050002DE9F84305461448DFF85080894603212E -:10E06000002400F10C0798F80000C2B2944218D2C4 -:10E0700017F80C2CAA4211D10BF069FCB9680646BE -:10E0800038680A6842EA09020A6008B10BF09BFC92 -:10E0900030460BF038FD98F80000002118370134A5 -:10E0A000E3E7C8B2BDE8F883B46E00204425002041 -:10E0B0007CB5154E0446B07808B1012521E00DF17C -:10E0C0000701E12007F0AEFF9DF807000025A04200 -:10E0D00017D00120B07001200BF0F2F80DF106010D -:10E0E00052208DF8065003F0C9FF204603F07AF95C -:10E0F00038B1064801216422047030780BF0FAFC34 -:10E10000BA2528467CBD00BFC02600208D8800208F -:10E1100080B51348007802280BD001280BD088B9AD -:10E120001148022181700F48018821F00701018008 -:10E1300080BD022000E001200A490A8822F007027F -:10E140001044088009480AF091FE0028064819BFCB -:10E150004FF44171A0F801100021817080BD00BF13 -:10E160001826002026870020C42600208E87002045 -:10E1700070B50546807C0C2826BFA869C67A0026A3 -:10E180000E2000EB46000BF04FFD044618B1AD69C0 -:10E190002878207008B1204670BD201D691C0BF046 -:10E1A000EEFCB5F8090060800020002E2073F2D04C -:10E1B000E87A04F10E012073287B607305F10D00ED -:10E1C0003206E8D030F8022B013E21F8022BF7E7A7 -:10E1D000F8B5144D044612484FF6FF762988B1422F -:10E1E00002D111490978298007684FB17868017810 -:10E1F00021B140680178204604F0C0FD3F68F4E793 -:10E200002888B04203D0C1B2204604F0B7FD0BF01D -:10E21000CBF906490880BDE8F8400AF0F1BC00BF20 -:10E220002088002076270020968800207087002014 -:10E230002DE9FF41DFF84C80074613480D4616468E -:10E240003946D8F8044009F030FA0F21002818BFE9 -:10E2500002218DF80C100D4900282046098808BFBE -:10E260006FF00201ADF8041039460BF088FC4670DF -:10E27000057001A9404600220A2301F0CDF804B040 -:10E28000BDE8F0817C260020C88700207087002030 -:10E290007FB5154E307828BB04208DF80000134858 -:10E2A000C08AADF802000AF0ABFC6D4601462C1D99 -:10E2B00020460BF034F82846F3F750FB0BF062F9D8 -:10E2C0004FF6FE7188420BD0BDF80210884207D08D -:10E2D000ADF8020020460BF084FB6846F3F73EFBE6 -:10E2E000012030707FBD00BFEC230020407B002068 -:10E2F00070B5154E01211C461546F068C0680170C6 -:10E30000F06880690078022803D0B068D0F84C0526 -:10E31000804705F0020004F0885140180AD00B48ED -:10E320000178013901700021F0688069017009F0FD -:10E330006FF803E0B068D0F84C058047F068002122 -:10E34000C068017070BD00BF0C01002019250020BD -:10E35000B0B5164CA06800F1D8030ECB1568D0F804 -:10E36000E024186809684042904755B1A168686880 -:10E37000D1F8E01009688842A4BF401A68602D688F -:10E38000F3E7A068D0E9381212680B68934207D00F -:10E390000A60A068D0F8E000006809F04BF8A068B7 -:10E3A000D0F8D404BDE8B040004700BF0C01002005 -:10E3B00070B5164E0446F068C068007828B9B06899 -:10E3C0000021D0F85824012090470BF0B7F80546FB -:10E3D000B068D0F8F824D0F8D8102046904730B96B -:10E3E000B068D0F8DC10D0F8F82420469047B06828 -:10E3F000D0F8E8000068A04203D107F0EFFEF9F77B -:10E4000021FE2846BDE870400BF044BB0C01002003 -:10E410001249134A096892F82620002918BF0222DF -:10E42000D2B2062A05D0052A07D10F49096899B149 -:10E4300008470C49096879B1084721B1897902294F -:10E4400004D0012904D140780BF0DCBBFDF7C4BB3C -:10E450000649096801B10847704700BFCC26002073 -:10E46000407B0020FC240020F8240020782300209A -:10E470002DE9F047054615488A464FF0FF394FF021 -:10E48000000804686768BC421DD026462468307DB9 -:10E490000028F8D06DB1F06850450AD1306918B144 -:10E4A00030625044F06001E086F81480D6E906102E -:10E4B0008847307D0028E6D0F068A0EB0A00484588 -:10E4C00038BF8146DFE74846BDE8F08708200020D6 -:10E4D000B0B5164A0121147A11722022EFF311858A -:10E4E00082F31188024652F8143F93420FD010680D -:10E4F0000368136001745A60C16809B100220A758B -:10E500008068294606F0C2FC85F3118808E0017C8A -:10E51000C90706BF418A01310121418285F3118873 -:10E520002046BDE8B04005F075B900BF3822002094 -:10E5300070B5144E2021B06DEFF3118581F3118871 -:10E54000F16CF26DB1FA81F1C1F11F0102EBC10171 -:10E55000884210D20C480121047A01720B4809F05C -:10E56000BDFC002086F84800204685F31188BDE8F0 -:10E57000704005F04FB9002086F8480085F31188F7 -:10E5800070BD00BFA01F00203822002069030200D8 -:10E5900010B5044681680079FFF75AFD207B00B171 -:10E5A00010BD20680BF070FA0F480168A14207D037 -:10E5B0000A69A24201D01146FAE722690A6101E024 -:10E5C0002169016000212161416829B1086908B110 -:10E5D0000146FBE70C6100E04460044841680078B4 -:10E5E000BDE81040FFF734BD6C2600202C2600202B -:10E5F000B0B50446C068256990F8381001F00301F1 -:10E6000001290ED1297C61B9416C0A78052A08D10B -:10E6100049780322062908BF0222012908BF0222E5 -:10E620002A740021297090F84810A97090F84210BF -:10E630000069E97068600AF0E3FA014605F1080034 -:10E640000BF09DFA2069F6F7ABF82075B0BD10B558 -:10E6500086B0044600200121CDE9000002904FF46D -:10E660008170ADF804002088ADF80000E078012842 -:10E67000684608BF21218DF80210F0F7A7FF9DF82A -:10E68000140088B903980921406C0170A178417089 -:10E69000208805F06FFA10B103980421C182684602 -:10E6A00003F02CFF9DF8140006B010BDFEB5047CED -:10E6B00000F11C03012201256CB11E78F70718BF79 -:10E6C00016F00C0F01D1002502E0760748BF0022AA -:10E6D0000833013CF0E7037A0BB1002413E0012D6D -:10E6E00018BF0129F9D101248DF808204179827AD7 -:10E6F0000472C0888DF803108DF80420ADF8060070 -:10E7000068460AF023FA2046FEBD70470F280ED84F -:10E7100040F20252DFE800F014101210080D081049 -:10E7200010100D100810100D4FF2011208E01E28F5 -:10E7300002D141F2011203E0002201E04FF48172A4 -:10E7400031B1FF2907D14FF203101040C03008E06B -:10E7500042F0300005E0C8070CBF42F0200042F054 -:10E760001000000400F203707047704780B50C4938 -:10E7700008700C48002101700B480C490088088083 -:10E780000B480C490BF0FBF90B480C4901600C4895 -:10E790000C4900780870BDE8804007F075BA00BFEA -:10E7A0009588002094880020782700202E7E002065 -:10E7B0008E870020B4260020DC870020AC260020B5 -:10E7C000B427002093880020F8B50446134800259C -:10E7D000061D134807783046394639B110F8242B06 -:10E7E000013A022A38BF01350139F6E7280611D06F -:10E7F000E8B240000BF018FA60B1014667B1327818 -:10E80000013A012A9CBF36F8042C21F8022B243649 -:10E81000013FF3E7002000252570F8BDB05400202B -:10E82000E6BC020070B50646807C0930C5B22846B9 -:10E830000BF0FAF918B30446B0782070F0786070E5 -:10E84000307BA070B07BE070F07B2071307C607119 -:10E85000707CA071307DE071707D207204F1090040 -:10E86000B27CB1690AF094FC4520FF212A46234678 -:10E8700003F004FF2046BDE870400BF0D3B970BD33 -:10E8800070B506468078032101EB4000C5B22846EA -:10E890000BF0CAF900B304463078207070786070CD -:10E8A000B078A070706870B1E11C0022B3789A4211 -:10E8B00009D210F8023B013201F8023B10F8013C8A -:10E8C00001F8013CF2E74520C4212A46234603F023 -:10E8D000D5FE20460BF0A6F9002070BDB0B5044669 -:10E8E000144890F8261004290AD0082908D0217865 -:10E8F00001F00301012908D121690978062904D111 -:10E9000061884FF6FE72914201D1C22508E0C08AAB -:10E91000814201D1207F40B12046E7F76FFF0546D5 -:10E9200020460BF07FF92846B0BD2046FEF768FC74 -:10E93000F5E700BF407B0020B0B58AB0114DC5E9B6 -:10E9400000011148426001AC20460AF0EDFE0320B0 -:10E950002146ADF820004FF4E130079001208DF8FA -:10E96000180040F20110ADF8040008480390084870 -:10E9700002900020ECF704F9A86006F06FFC0AB0E2 -:10E98000B0BD00BF4823002064260020FD6F0200B8 -:10E99000698A010020291CBF6FF0010070477CB517 -:10E9A00004464068114EA1684068098CC6E901011F -:10E9B000204600F05FF988B9C72031898DF807003B -:10E9C00020460AF098FA0DF10700012101F0FCF849 -:10E9D0003189054620460AF097FA15B14FF0FF300D -:10E9E0007CBD204600F046F97CBD00BF0C24002011 -:10E9F00070B50D4606460AF0AAFF04463046294681 -:10EA000009F0D6F890B1054600680BF03DF828688B -:10EA10000AF07CFD0C490868854209D00169A942C9 -:10EA200001D00846FAE72969016103E0022505E003 -:10EA30002869086028460BF0F5F8002520460BF001 -:10EA400062F8284670BD00BF6C2600202DE9F04119 -:10EA500004461348DFF84C800027002600F1080523 -:10EA600098F80000874217D215F8080CA04210D180 -:10EA7000284608F0BEF90646286828B1F8B24FF4D7 -:10EA80000041FFF7E5FA04E0F8B24FF40041FEF769 -:10EA900017FD18350137E3E73046BDE8F08100BFC8 -:10EAA000B46E00204425002070B50446807861686B -:10EAB0000A5C0D1802F0070262700A5C2846042105 -:10EAC000C2F3C102227410F8016B07F027FD052183 -:10EAD000A061B006217704F1080004D40021C0E948 -:10EAE0000011052005E0691D0BF049F8207F083072 -:10EAF0002077217C012904D1C1B20130695C2077E3 -:10EB0000A17570BDF8B506461148012714460D469B -:10EB100047700720F7F70CF9022006F047FC312078 -:10EB2000314609F031FA0B480321002241600168A7 -:10EB300021F0030165F3000165F34101016006481E -:10EB40002146006803680020984704480760F8BD24 -:10EB5000182300200C800240CC010010A802504273 -:10EB600070B58AB000266C4605462821867120467D -:10EB70000AF0AAF904F1190005F10B010B220AF0C1 -:10EB800007FB28680B490860204629680AF0B5FF92 -:10EB9000A888ADF81360ADF81100D5F80700CDF8DE -:10EBA000150005488068D0F87C142046884700206E -:10EBB0000AB070BD008800200C0100201CB5154C67 -:10EBC00010200DF106018DF80600A068D0F8302461 -:10EBD0005A2090474FF4FA70ADF80400A068D0F8BE -:10EBE000302401A95520904707200DF103018DF82D -:10EBF0000300A068D0F830245920904709200DF177 -:10EC000007018DF80700A068D0F83024E020904775 -:10EC10001CBD00BF0C01002010B513490446487804 -:10EC200008B1486A10B900204870086A09F0F2FD7E -:10EC30000E48006840B10E480078012808BF002C3B -:10EC40000BD0642000210AE00CB1032000E0052075 -:10EC50000021BDE81040E5F79DBD64200121BDE81D -:10EC60001040EFF7E9BD00BFAC2200206C27002068 -:10EC7000182600202DE9F8430446144E05200DF116 -:10EC800003080DF10209A5688DF8030031892046BB -:10EC90000AF031F94046012100F096FF4846012173 -:10ECA00008F076FF3189074620460AF02DF94FB962 -:10ECB0009DF80200C00705D0686A0028E6D00AF077 -:10ECC0002BFCE3E73846BDE8F88300BF0C240020A6 -:10ECD0000E48007888B90E48007870B90D48007861 -:10ECE00058B90D48007840B90C48007828B90C484C -:10ECF000007810B90B48007808B1002070470A4826 -:10ED00000078B0FA80F04009704700BFAC8800205E -:10ED1000AF880020B4880020A7880020AD8800209C -:10ED200016250020A32700201725002010B5044633 -:10ED3000812804D310488068D0F84C0580470AF039 -:10ED4000FDFB0E490C700C498968D1F8B8100A789F -:10ED50000B4991F900101AB1002902D40949097828 -:10ED600019B10AF097FE012010BD0AF093FEBDE82C -:10ED70001040F9F7D3B800BF0C0100204C2600204A -:10ED8000B4880020A788002080B50AF0D7FB134A7A -:10ED90000023117813708A070CD4490719D50AF09B -:10EDA00079FE0F4800218068D0F858240020BDE883 -:10EDB000804010470AF06EFE0948C168C9680978AA -:10EDC00029B980680021D0F85824012090470AF022 -:10EDD000B5FBBDE880400AF05DBE00BF8C88002016 -:10EDE0000C0100202DE9F843044613484FF6FE7944 -:10EDF000124D09F1010806786FF00100013087B269 -:10EE0000BEB12888A0420DD1A81C08F0EFFF68B958 -:10EE100065B128461C210AF057F8A5F80A80A5F824 -:10EE2000009003E0BC4201D14845EDD11C35013EC4 -:10EE3000E6E7BDE8F88300BFD5BC0200DC5B00203C -:10EE400010B51446AB2808D0A2280CD0A32812D0A5 -:10EE5000A12817D10F48008811E00B48016820460F -:10EE60000AF08DFE0CE0094802685AB108462146B6 -:10EE7000BDE8104010470648016819B18847208056 -:10EE8000002010BDB52010BDDC87002034240020F8 -:10EE9000F42300202E7E0020BFB50AF0F2FD90B1D1 -:10EEA0000546408801242421FF228DF80040ADF85A -:10EEB0000C0028460AF002F8802085F821006846F8 -:10EEC00005F052FB00E000240020042104F0C6FD00 -:10EED00005490978884204D2044801210170F5F7F8 -:10EEE000C1FC204604B0B0BDE6BC0200872700206C -:10EEF000F8B50AF02CFD1349002200230025002458 -:10EF0000886048680668A6B1B6F1FF3F05DD5BB1D1 -:10EF1000176835443744176009E0AC4238BF2C46C7 -:10EF200086F00046002302E00123024635463044C5 -:10EF3000E8E788680AF0E7FDA54288BF2C4620462E -:10EF4000F8BD00BFD02500201CB501784478827838 -:10EF5000FB298DF806408DF8072001D304200DE031 -:10EF600004F01F01152908D80C4A52F8211021B1CC -:10EF700088478DF8050018B90EE001208DF80500CE -:10EF800004F0E000202807D10DF1050360200021E6 -:10EF9000032203F073FB1CBD1CBD00BFE021002059 -:10EFA000B0B588B0134D0446286808B101201EE0B2 -:10EFB00008200AF039FE2860C0B12168016021797B -:10EFC0000171B4F80510A0F8051001AD1821281D35 -:10EFD00009F07AFF2068019020798DF809006079A6 -:10EFE0008DF808002846FFF7BBFD00E0102008B0B0 -:10EFF000B0BD00BFCC2600202DE9F8438046032099 -:10F000001E46144689468DF80100684607F038FC14 -:10F010000125B0B1074600690B218670447001706C -:10F02000BD7709F0EDFD084800217D77BD76A7F892 -:10F030000280C7E90890054801703846FFF74EFC8A -:10F0400005462846BDE8F883C8870020972700209A -:10F05000B0B50C480C490D4AC0E904210C490978A7 -:10F06000C90702D1816951B9B0BD0A4A0D490C4D99 -:10F07000094B0A4CC0E90615C0E908438262BDE8A5 -:10F08000B04008477423002079750200914D0100BB -:10F09000CC270020A93401007D1202004197010015 -:10F0A00039C7010071790200F8B511B3044612485E -:10F0B0000D46A0F11001114800780130013804BF5D -:10F0C0000320F8BD01F11806097CA1423146F5D1B3 -:10F0D0000AF03DFC07463046294607F00DFC204665 -:10F0E0004FF40041FEF7B4FF38460AF00CFD002053 -:10F0F000F8BD0520F8BD00BFB46E002044250020F7 -:10F10000B0B5124949684A68D2E90115D46860B1BE -:10F1100055EA040005D00E480022C2610D4A503263 -:10F12000026021B1F0F751FA01E001B1884755EAD8 -:10F13000040008BFB0BD09F08BFD05B1A84704B1BC -:10F14000A0470448BDE8B04008F0B2BBD01E002084 -:10F15000001004400100070670B58AB01C46154631 -:10F1600002460B46002006AE102805D0295C81F02F -:10F17000360131540130F7E7304601210094EAF7B7 -:10F1800047FB02A8214610220AF002F800201028AE -:10F1900005D0295C81F05C0131540130F7E700941F -:10F1A00006A802AA01218023EAF732FB0AB070BD4B -:10F1B00070B50AF0C3F9104E04463078B0B90F4D5F -:10F1C0000F4A31210023284603F00AFF05F11C00F5 -:10F1D00006F110010422082309F0BAFE094A4FF093 -:10F1E000FF3001210125FFF78DFC35702046BDE879 -:10F1F00070400AF04FBC00BF18230020742200208A -:10F2000091E3000080A9030080B51248007805282A -:10F210001BD108F08BFF062008F06AFC0E4800782E -:10F2200001280AD80D48008800F00700022804D001 -:10F2300000200021002209F053FF04F01BF8F9F729 -:10F24000DDFFBDE88040FDF76FBEBDE8804004F003 -:10F2500011B800BFC42600201826002026870020F1 -:10F260007CB5856904460421284607F057F90E4B02 -:10F2700029796A7902250126009040F20110ADF843 -:10F28000050068461D72094D8DF804102E70084D5A -:10F290002A70627C074D2A7062881A80FFF780FE10 -:10F2A00008B108F0E5FA7CBD84870020AB27002078 -:10F2B000C3880020C2880020F8B5144F14460546C4 -:10F2C000069A079E8DF8031078680370130AC670BB -:10F2D0004270837036B108990430324609F058FF05 -:10F2E000301D00E0042048F20601C3B20DF1030016 -:10F2F0002A46691AB1FA81F149090901B970214612 -:10F3000000F08AF80021B970F8BD00BF7C2600200B -:10F310001FB504461348406842700170207A0F28D8 -:10F3200001D0022814D120884FF6FC71401A03281E -:10F330000ED802280CD002208DF80C000AF034F907 -:10F34000ADF80400074801A93622022300F064F852 -:10F35000044821463622022304B0BDE8104000F0E4 -:10F360005BB800BF7C26002070B586B00C46134900 -:10F370000546114800780978084301D1012019E0B9 -:10F38000BDB1B4B1284601F0ADFB064605F1100051 -:10F390000AF046FC86420CD102AE002000212A462B -:10F3A00090230096EAF734FA30462146F3F706FA3E -:10F3B00000E0022006B070BDAC2700201826002017 -:10F3C0002DE9F047DDE90897DDF828A080461C46C6 -:10F3D00015460E463846C4B1B84208D140463146BB -:10F3E0004A463B46FBF7AAFA0146002071B92A7843 -:10F3F00019F80010BAF1000F18BF11408A4207D166 -:10F4000001350136013C0130E5E70020BDE8F08719 -:10F410006FF00600BDE8F08770B588B004460020A4 -:10F420000F260133CDF81A00ADF81E00CDF81600F6 -:10F43000087A8DF81C0008880B49ADF81400207874 -:10F440004D6805F8010D88780331CDE90051074971 -:10F45000CDE9020605A8E8F721FC10B921780131B1 -:10F46000217008B070BD00BF7C26002094250020CC -:10F4700010B50446812804D30F488068D0F84C05A5 -:10F4800080470AF05BF80D490C700B498968D1F888 -:10F49000B8100A780A4991F900101AB1002902D46B -:10F4A0000849097811B10AF0F5FA03E00AF0F2FA16 -:10F4B000F9F7A0F8012010BD0C0100204C26002017 -:10F4C000B4880020A788002010B5114CA068D0F89F -:10F4D0005C028047B8B10F4900222223CA814A75D5 -:10F4E0000D4A4B8212780A75A268D2F8D42092F89D -:10F4F000243092F831200A74084A4B741278504331 -:10F500008000C86110BD1C20BDE81040F3F7E4B8CE -:10F510000C010020A0830020B5880020B0880020C6 -:10F5200010B50AF00BF80F490F4C49682268914258 -:10F5300002D00E4A12781AB1BDE810400AF0AABAF9 -:10F540000B4A92F90020002AF6D40A4A1278002ABF -:10F55000F2D121600AF09EFA2068BDE81040FDF764 -:10F560007FBD00BF4C26002028880020AF880020E7 -:10F57000B4880020A7880020B0B511488068D0F872 -:10F580001814D0F8D40090F85300884740F6387526 -:10F59000042808BF43F66C450AF0D9F90446094827 -:10F5A000007845430AF010FBB5FBF0F00649074B25 -:10F5B0000022FAF715FC2046BDE8B0400AF0A3BAD5 -:10F5C0000C010020B0880020517C02002027002080 -:10F5D0002DE9F84381461248884600240025861C00 -:10F5E00010480778BC4218D2280616D1304608F0D9 -:10F5F000FDFB70B136F8020C002541464845304607 -:10F6000008BF0A2508F051F8002818BF65F05F050B -:10F6100000E000251C360134E4E7E8B2BDE8F883D9 -:10F62000DC5B0020D5BC0200BCB50D461349044686 -:10F630004089097839B11049C98A884203D1BDE8A7 -:10F64000BC4000F0C5B90021FAF70AFC60B180792E -:10F6500010F0180F08D02B8D627F6189A0896C8E05 -:10F66000009400F0D6FBBCBD6189A089002202B0E5 -:10F67000BDE8B040FEF71EB8407B0020BD2700204B -:10F6800000B5EFF3038212F0FF0F0DD06A46A2F12E -:10F69000200282F309886FF0020E10604FF0807133 -:10F6A000D1610B49916170475DF804EB694681F3C4 -:10F6B000098880F308884FF00200EFF3148180F38B -:10F6C00014880448016821F040410160704700BF80 -:10F6D000A8F6010034EF00E0F8B50E46044609F044 -:10F6E0002DFF0546D4E90101814205D128460AF0E3 -:10F6F000D1F94FF0FF30F8BDE3682168A26901330A -:10F70000B3FBF0F707FB103702FB071031460AF096 -:10F71000F7FAA0686169E7600130A060884288BF9D -:10F720000146284661610AF0B5F9A068F8BD70B5D8 -:10F73000054600780C46164608220870687848701E -:10F74000A97840EA01106070E878A070297940EA51 -:10F750008100A070697940EAC100A070A97940EAEF -:10F76000C110E91DA070E01C09F012FD04F10B00AE -:10F7700005F10F01032209F00BFD0F2E24BFA87C19 -:10F78000A07370BD70B506680D46044609F0D6FE3C -:10F790000F490978012901D1317819B10AF07AF9B4 -:10F7A000002413E0012131700AF074F90948002D9A -:10F7B00018BF2846017842683172326102290CBFB5 -:10F7C00080680020F0600A20F6F7B2FA204670BD8B -:10F7D00098270020F4BA02002DE9FF41124C0025C1 -:10F7E0004FF0FF360DF104080027208881B28F42C8 -:10F7F00028BFBDE8FF8161684A57B2F1FF3F0FDCC7 -:10F800004B19D0B210F07F00187003D14346039615 -:10F81000CDE90166B9B201200C2206F0D1FD2088A5 -:10F820000C350137E2E700BF34260020FEB5044660 -:10F83000032017460E468DF8090002A807F020F8AD -:10F8400005460120C5B129690C228F704E700A70DF -:10F85000A87709F0D5F909486E4631466862204616 -:10F8600006F0BCF810B101202E62687701206C8090 -:10F87000A8762846FFF732F8FEBD00BFC8870020F3 -:10F88000F8B5124D0446002629880844B0F5877F54 -:10F890000AD90F48C1F587770844B9B202F04EFF84 -:10F8A0002E80E41B00213E4609480844A1B202F024 -:10F8B00045FF28884FF48772204481B2B1FBF2F1F2 -:10F8C00001FB12002880301980B2F8BDBC26002050 -:10F8D0001C700020F8B5114F0546786808B18047C4 -:10F8E00080B1B868FAF77CFD04460D4806787EB909 -:10F8F0000C48C088C0F5005000B2A84204DB1DB11E -:10F90000042605E00B2607E00020E2F713FF3E780F -:10F91000B8682146FEF7C2F83046F8BDA0230020A3 -:10F9200088270020A0800020F0B589B0ADF8201015 -:10F93000079007A802AA00210024FEF759FBB0B9DE -:10F940000C4FB868FAF74CFD05460B4800940323AA -:10F95000C188C07802AAEAF721FD0646B868BDF85A -:10F9600016702946FEF79AF8002E08BF3C4620463E -:10F9700009B0F0BDA0230020A080002010B509F040 -:10F98000DDFD0F4C217E022902D0217E042904D105 -:10F990000E490C680AF07EF810E00AF07BF809487E -:10F9A0000068006B8047084AA0FB020301FB02319C -:10F9B00010F1905041F17A00E16C0C18204610BD16 -:10F9C000D01E00208C01001000093D0004300440CE -:10F9D00010B50F4C4FF48051207803F0F1FB18B1B3 -:10F9E0000C480121017010BD0B4802780B480178CA -:10F9F000012918BF03210020EEF78AFE084920786C -:10FA00000A884FF48051BDE810400AF073B800BF77 -:10FA100098880020E8250020BF270020BE2700206E -:10FA2000BCBC020010B5134C206808B3C16C11B106 -:10FA30000AF04EF82068416C11B10AF049F82068CC -:10FA4000416911B10AF044F82068C16911B10AF0A6 -:10FA50003FF82068416B11B10AF03AF82068C16B99 -:10FA600011B10AF035F820680AF0DCF800202060B7 -:10FA700010BD00BF38270020BFB501AD0446AB2044 -:10FA800000212A46FFF7DCF909F0BAF801462846BA -:10FA900007F00BFE88B101A9204605F09FFF50B189 -:10FAA00001A803A907F012FC50B101A80DF1020151 -:10FAB00006F09DFD08B1002000E0012004B0B0BDBB -:10FAC00003980079002818BF0120F7E72DE9F041DD -:10FAD00086B012480DF104080027002508F1020441 -:10FAE0000678B9B2B14214D2082000221423CDF80E -:10FAF000008006F04FFC50B99DF80400FF2806D0A6 -:10FB000021460022FDF79EFE002808BF013501377F -:10FB1000E7E7A8B206B0BDE8F08100BFCDBC0200A7 -:10FB20007CB50446032007F0E3FFA07905F0CEFC86 -:10FB30000E4D2089E67A2188A278AB78CDE90006BF -:10FB400004F10C00F3F71AFD044660B9A878000729 -:10FB500004D40748007830B9082001E04FF4004091 -:10FB60000121EBF7D9FE20467CBD00BF268700208F -:10FB7000C6260020BCB5114C206970B11049012582 -:10FB80008D70FFF7CDFFB8B120698DF8075004F0F4 -:10FB90003DFA0C480DF1070107E0094800218DF8F6 -:10FBA0000610817007480DF10601007800910321CD -:10FBB0000122012303F05FF9BCBD00BFAC2200208D -:10FBC000088800209F88002010B588B00C460021CE -:10FBD000049140B1CDE902400F48406802A909F004 -:10FBE000ADFF013815E00DF10700039001200290F0 -:10FBF00008788DF807000848406802A909F09EFFC0 -:10FC000018B1013C04D00120E4E74FF0FF3000E0E0 -:10FC1000002008B010BD00BF0C240020B0B50C4679 -:10FC2000054609F08BFC0F490A78862A10D18722F5 -:10FC30000A700D49CA890132CA8109F02BFF0B48AD -:10FC40000078A84208D1002C14BF1B20002004E03B -:10FC5000BDE8B04009F01EBFE920BDE8B040F2F7B2 -:10FC60003BBD00BFB488002044860020C18800202E -:10FC7000F0B5059E00244FF6FF7C0027B44220D249 -:10FC80001D8865451AD017B13F88874201D2854249 -:10FC900004D81D1D1F4601342B46EFE71F46B44212 -:10FCA00005D23D88654502D001340437F7E73C466C -:10FCB00054F8045D3D609C422746F8D8D9709A708C -:10FCC0001880F0BDB0B5054600781446E91C1070E8 -:10FCD000687800F00F005070687800099070A8787C -:10FCE00000F00300D070A878C0F380001071A878ED -:10FCF000C0F3C3005071A878C0099071D01D0822CC -:10FD000009F046FA04F10F0005F10B01032209F096 -:10FD10003FFAA87BA074B0BD10B550B1014650F8B1 -:10FD20000C0C18B911F8020CFF2804D0084608F092 -:10FD300099F8052010BD0A4C207801F8020C0948FA -:10FD40000278094802F03AFD01281CBF042010BDCA -:10FD500020784FF40051FEF77BF9002010BD00BF62 -:10FD600098880020D4BC02003C2700202DE9F041F7 -:10FD7000124C07462068F0B10E460169D9B115460C -:10FD8000826A984622B1380431460130904700E03B -:10FD90000020A84204BF0020BDE8F0812068314661 -:10FDA0002A464346046938040130A047012804BFAD -:10FDB0000A20BDE8F0810920BDE8F0815C27002021 -:10FDC00041F218324FF68850C5F20002CFF6FF70AC -:10FDD000116810584FF20003C0B27F2888BF00207E -:10FDE0001268C0F6FF731A4041F20003C0F6B43344 -:10FDF0009A4207D1090F022906D307D0032901D15E -:10FE0000153004E0FF2002E00A2000E00B3040B291 -:10FE100070472DE9F0410C4605463AB12846214687 -:10FE20000B220023BDE8F041FBF74ABFDDF8188044 -:10FE3000204600211E46FAF713F860B10746807984 -:10FE4000C00708D0404631462A46ECF749FC4FF639 -:10FE5000FE71884201D1BDE8F081788020462946B4 -:10FE60000C22DEE71FB5014604208DF80000087A59 -:10FE700001280AD003280AD0022814D10888ADF836 -:10FE800002006846F9F766F808E008880DE06C465D -:10FE9000201D09F044FA2046FBF7E6FB38B9684616 -:10FEA000F1F75CFD03E04FF6FE70ADF80C00BDF815 -:10FEB0000C0004B010BD7047B0B505464068007D29 -:10FEC0001030C0B207F0D0F8D0B16B680446A87803 -:10FED00029881D781A7D6181207304F1100060600B -:10FEE000C5F340152272657202252580196909F053 -:10FEF0004FF9044821460078BDE8B040FFF7D4B878 -:10FF0000B0BD00BF9588002070B5064600204FF6B2 -:10FF1000FE713446B060718044F8040F304606F03C -:10FF200023FC0546012812D10A48B189406801EB3B -:10FF3000410100EB810041887180061D304607F0C9 -:10FF400055FF012803D12046314609F0E8F928463B -:10FF500070BD00BF342600202DE9FF4110486C46DB -:10FF60004FF00108251D861C0E480778AFB1B07808 -:10FF7000013803280ED8F07800070BD430888DF8AC -:10FF80000080ADF80C002046FFF7BEFF10B12846F8 -:10FF9000FEF782FF2436013FE8E7BDE8FF8100BF9E -:10FFA000B0540020E6BC0200B0B505F097F80E4C46 -:10FFB0000E4D1420611CA8470A202146A84709209D -:10FFC0002146A8470A490820A847B92000F01BFA93 -:10FFD000084C1420A0470A20A0470920A047082069 -:10FFE0002146BDE8B0400847006400208F9A020017 -:10FFF00002200020A52F02002DE9F04107460E4601 -:020000022000DC -:100000005818B9684968884284BF6FF00300BDE89A -:10001000F081DFF830804FF0FF311C461546D8F8EC -:10002000000009F0ADFC384631462A462346FAF76F -:1000300085FC0446D8F8000009F008FE2046BDE81B -:10004000F08100BF0C24002010B504281CD10F48FB -:1000500009F0C0FDC0B109F0B7FD04460B4809F036 -:10006000B7FD604380084A280ED8084809F00CFD07 -:10007000052005F09BF90648012180F82510054868 -:100080000421283009F0E6FD002010BD647F002027 -:10009000D01E002070200020BCB504460DF10702E0 -:1000A000002001213A2307F08BFF4FF6FF75B8B906 -:1000B0009DF80700A04212D00DF106020020012198 -:1000C0003B2307F07DFF58B99DF80600A04207D1F9 -:1000D0009DF80700A04205D22046F6F70BFF3A250F -:1000E0002846BCBD3B25FBE770B588B00546806956 -:1000F000048810480088844207D103AB8120002186 -:100100001122002608F0C6FE58B1297C687C48F20E -:1001100011022346CDE90021A91C842206F050FCDF -:1001200006E0687C0096A91C03AB224602F046FC60 -:1001300008B070BD70870020E0B500218DF8071071 -:1001400050B110480DF10701002201230078009101 -:10015000032102F090FE8CBD0949487850B1086A2D -:1001600040B100224A7008F055FB3220BDE88C40B7 -:1001700008F008BB03200021BDE88C40E4F70ABB6F -:10018000AC2200209F880020E0B58DF807000D48C4 -:100190000DF10701C0680069007805F0CFFA0B493E -:1001A0000948096800680A6E9DF9071090470146E2 -:1001B000074A6FF39F5191420EBF4FF0FF30054940 -:1001C00048608CBD0C010020688800203088002029 -:1001D000FFFF3F004C260020B0B5104CA068016C1A -:1001E000096811B9D0F84C0580470D4D286808F012 -:1001F00061F8A168096C0968C860286807F0F8FC14 -:10020000A168096C096808820648007828B109F0DD -:10021000DDFCA168096C0968C860B0BD0C01002054 -:1002200044880020842700202DE9FC4106464FF039 -:10023000FF300D469046CDE900006846314607F094 -:1002400034FA07460B48046884B11FB12088A842DD -:1002500006D008E004F10C00314607F026FA10B190 -:10026000A078404502D004F11800ECE72046BDE834 -:10027000FC8100BFE487002010B5114CA068D0F8C5 -:10028000AC00007808B900F05DFDFFF749F9A068FF -:10029000D0F8B800007818B10A48016801208847F2 -:1002A000F8F786FDA068D0F8B8100A783AB1496925 -:1002B00029B1D0F828131020BDE81040084710BD20 -:1002C0000C01002024270020B0B5A0B00E4D04463C -:1002D000012085F83000686B08B902A868632046E1 -:1002E000F2F7A0FF03200B4A287508480068A16BAD -:1002F000C3B2074800910F2B38BF024600200021EF -:1003000004F0DEFD20B0B0BD381F002004ED00E099 -:1003100014AF020047B00200F0B52022EFF31181C4 -:1003200082F3118890F8282012B181F31188F0BD72 -:100330000C4A012492F8483082F84840466B456ADE -:10034000776806604760386080F82840D46C2C439A -:10035000D464706081F3118803B1F0BDBDE8F04052 -:10036000FEF7E6B8A01F0020B0B5124CD4E9165134 -:10037000E06CB0FA80F0C0F11F0001EBC00108682A -:1003800002680A6051600A688A4204D1416AE26CDC -:1003900022EA0101E164FCF7CBFEE06C40B1E16DC3 -:1003A000B0FA80F0C0F11F0001EBC0018D42E6D32E -:1003B000B0BD00BFA01F0020F8B50646C86860B1F8 -:1003C00010F00F0009D1376814460D4609F0B6F851 -:1003D00097F8251021B109F05DFB4FF0FF30F8BD13 -:1003E000012187F8251009F055FB296807F10C0C4D -:1003F00091E88D0029468CE88D0030462246BDE804 -:10040000F840E9F75DBDB0B504461420002108F0BE -:100410001FFE07250A20002108F01AFE681C0FD0D5 -:1004200024FA05F000F00101092008F011FE0A206D -:10043000012108F00DFE082009F0D7FA013DE9E797 -:100440001420012108F004FE4FF42F70BDE8B040E5 -:1004500009F0CBBA2DE9F0410F460646C1898089E3 -:1004600098461446727A337C451AA8B2FCF756FCBB -:1004700008B1BDE8F081E919B28914FA81F090421F -:1004800006D9F1890620A14238BF0520BDE8F081D8 -:10049000307C89B24246234608F042FE0020BDE887 -:1004A000F0817CB540EAC1000D46164640EA421193 -:1004B000069800F8011B194609F01FFB044636B1E7 -:1004C00008F09EFB0146204609F059FB0834012D37 -:1004D0000DD10DF10702002001213A23002507F07C -:1004E0006FFD9DF80710002818BF294621707CBDBC -:1004F0007CB515460DF106020C4605F051FD08B11C -:1005000001207CBDBDF806606946304605F06EF8F6 -:10051000009858B120462946F9F722FB20460121D0 -:1005200008F0E6FBFCF7B8FA00207CBD684602F054 -:1005300055FF08B111207CBD00980680EAE7FEE770 -:1005400010B50E480078012816D10D4805F016FAAE -:100550000C4C204607F0DCFB0B48046106F040F928 -:1005600040F2000CEFF311808CF3118809F025FBA9 -:10057000BDE81040FBF760BF08F0BCFFA01F0020E3 -:10058000B51B020098840020381F00202DE9FC4193 -:100590000E48104F00264FF0000805780C480488DC -:1005A000B5420FD0B1B2022000222346009705F0D9 -:1005B000F1FE20B93878FF2818BF08F101080E377E -:1005C0000136EDE71FFA88F0BDE8FC81E2BC0200CD -:1005D000C2B4020018870020B0B5054608F0AEFF8F -:1005E000044605F011FE0D48012D06D101210170D0 -:1005F0000B48008B40F0200007E00021017040789C -:1006000028B90748008B20F02000054908832046C0 -:1006100009F040FABDE8B04008F000BC70270020A7 -:10062000E87F0020E0B50E480122018B41F0550122 -:1006300001830C49C96849690A70018B807EADF855 -:10064000021042F202018DF804000748ADF80010D4 -:100650000649006809684A6A694690478CBD00BF30 -:10066000E87F00200C010020D826002030880020E0 -:10067000B0B504460F480078012815D80E48807B95 -:10068000800711D5A07A01280ED0258808F07AFFBE -:10069000854209D0E07A012806D0208807F076FF4D -:1006A00010B1208801F002F92046BDE8B040F7F70C -:1006B00057BB00BF18260020407B002010B5104C0F -:1006C000607890B10121217008F08CF86078FF28E3 -:1006D00010D0002161704FF47A7100FB01F20948DB -:1006E0008021007809F006FA04E000202070002044 -:1006F00008F078F802494120BDE8104001F0BEBC86 -:10070000F42400209888002070B542F2A45EC2F262 -:10071000000E1B38DEF8083000FB00F1A3FB012CB3 -:10072000DB1701FB00F4DEF80C6003FB01C1DEF80F -:100730000430C6FB0421C3FB0021DEF80050100981 -:1007400040EA01700909401941EBE571000C40EAEB -:10075000014070BDB0B50446481D85B2204629460B -:1007600008F0C0FB00F0FD022046294607F052FCCD -:100770000A4904EB440001EB800515F8190F58B144 -:100780002046022108F0AEFB00F0FC0220460221C8 -:1007900007F040FC00202870B0BD00BFA080002002 -:1007A000B0B510484FF470510F4D006801EA802039 -:1007B0004142C5E90101012006F02EFD044608F082 -:1007C000BDFE296839B109F065F94CB12046BDE894 -:1007D000B04008F085BF2C60BDE8B04009F05AB9C0 -:1007E000B0BD00BF30240340DC2500202DE9F041DE -:1007F00087680E4619447868814284BF6FF0030011 -:10080000BDE8F081DFF82C804FF0FF311C46154623 -:10081000D8F8000009F0B4F8386822468119284653 -:1008200009F06EFAD8F8000009F010FA0020BDE8CF -:10083000F08100BFDC25002070B505460F480C464E -:10084000A0F1100609F083F80D490978013101394A -:100850000ED0337C06F118021646AB42F7D104E005 -:100860002978A14205D0A5F10C021568002DF7D119 -:10087000002509F048F9284670BD00BFB46E00207D -:100880004425002080B50D4801420CD0012008F01D -:10089000FDFE012808D10B4800210C4AC1610A491C -:1008A000CA613C31016080BD09F08EF93221B1FB93 -:1008B000F0F10348BDE8804007F034BF0400002099 -:1008C000647F002000100440D01E00202D3700005F -:1008D00070B50E46044608F031FE0546A068B8B172 -:1008E00020682169A26901FB0201304609F008FA7B -:1008F000D4E9010122690139A160511CB1FBF0F278 -:1009000002FB10102061284609F0C4F8A06870BDF1 -:10091000284609F0BFF84FF0FF3070BD70B50446AF -:100920000F48056802F0A6FC0E4810210078FDF77C -:100930008FFBD62685B16868007858B1042006F090 -:1009400093FB38B1014644800670686840680078BF -:10095000FEF7AAFB2D68EDE7BDE87040FCF7E4BAAE -:100960002088002099880020B0B5044608F048F996 -:10097000A51C0146284606F098FE50B10C48416976 -:1009800011B12046884780B9E07ABDE8B040F7F75A -:1009900053B906480078012807D8A27AE37A20885C -:1009A0002946BDE8B040F1F75DBCB0BD1826002077 -:1009B0003C830020F8B5114E0D46044631680F46C1 -:1009C00059B108460979A14204D1C188A94204BF9E -:1009D0000020F8BD01680746F2E7082009F024F975 -:1009E00050B1014600200860CD800C713268002AA9 -:1009F00008BF37463960F8BD1020F8BD68270020D1 -:100A000070B5114D134604460E0A13F8012B6868A1 -:100A1000102A01704FF020314670C0F80710C0F85E -:100A20000B10C0F80F1028BF1022827040F8031F6F -:100A3000194608F0ADFB2846214614221323BDE8D1 -:100A40007040FEF7E9BC00BF7C260020B0B586B040 -:100A5000054600206C4618212872204608F034FA1A -:100A6000204629460B2208F093FB04F10B0005F108 -:100A70000B01082208F08CFBA88AADF81400A87DB1 -:100A80008DF8160003488068D0F81C12204688476D -:100A900006B0B0BD0C01002010B5427B042A01D184 -:100AA000027C0AB1002010BD40690028FAD002780B -:100AB0009207F7D14A68437B547DA342F2D109885B -:100AC00043898B42EED1D18883888B42EAD19178D9 -:100AD0008078884204D0107800F00C000428E1D11E -:100AE000012010BDF8B504464FF6FF76002541F20F -:100AF00021070F2D14D82078082106F0B4FD80219D -:100B000059B13246014218BFD243120487EA460265 -:100B100058BF720049081646F2E701350134E8E78C -:100B2000B0B2102106F09FFD4FF6FF714840F8BDAE -:100B300070B5114E04460822A51CF0682946023003 -:100B400007F076FA18B156F80C0F04460CE00C3694 -:100B5000366886B156F80C0F29460822023007F095 -:100B600067FA0028F4D03068C06830602046BDE8DD -:100B7000704009F057B870BDAC220020E0B50023EA -:100B8000CDE9003361B10F4A0428137008D8DFE8BB -:100B900000F0030B09131100BDE88C4000F04DBAC2 -:100BA00002208CBD012010706A4608461146FEF7EF -:100BB000DBFB8CBD012010706A4608461146F1F738 -:100BC000FDFD8CBD942700201FB54FF6FE718842B5 -:100BD0001AD00E4900234A1C0D49097899420BD0BE -:100BE00014781CB9B2F80140844202D00E320133AD -:100BF000F4E7DAB2914207D1ADF80C0004208DF889 -:100C00000000684603F0B0FC1FBD00BF188700203D -:100C1000E2BC02007FB5D0E90154204606F022F97B -:100C20002068416821F002014160416921F00F0113 -:100C300041610321016202A808F0FAF9074995F819 -:100C4000F93095F8FA202068D5E9396509680C680B -:100C50000399CDE90065A0477FBD00BFC401001026 -:100C600010B508F06BFC0C49097869B90B49097893 -:100C700051B90B49097839B90A49097821B90A49A2 -:100C8000097811F0FD0F04D0002408F003FF20467E -:100C900010BD0124F9E700BFAC880020AF88002018 -:100CA000B4880020A7880020AD880020F0B589B066 -:100CB0000F4C2068A8B1002001ADC6B21F2E0DD880 -:100CC000AF1903F053F80021202905D020FA01F2D2 -:100CD000083107F8012BF7E7301DEEE7216801A87E -:100CE00088470448018B41F00401018309B0F0BD3D -:100CF0004C270020E87F0020FEB50F4D0446E86831 -:100D00008069007800B1FEBD0D4F0C4E3968306827 -:100D10004B6C01AA022198479DF804000028F2D0EC -:100D20000CB901F0EFF9E8680121806901703968B8 -:100D30003068C9698847FEBD0C010020D826002014 -:100D40003088002010B508F0F9FB04460C48007804 -:100D500020B12046BDE8104008F09CBE094890F93B -:100D600000000028F5D4084890F900000028F0D4CD -:100D7000064800780028ECD105F046FAE9E700BF04 -:100D8000AD880020AC880020B4880020A78800200F -:100D90001CB50E21F8288DF8071017D10E4CA0684D -:100DA000D0F8D41091F884208AB191F8421014221E -:100DB0008DF80720142905D0D0F830240DF1070153 -:100DC000E0209047A068D0F8CC0380471CBD91F884 -:100DD00042100E29F0D1F5E70C01002070B5054650 -:100DE00008F0ACFB0F4E0446B068D0F8F824D0F8F9 -:100DF000D8102846904730B9B068D0F8DC10D0F849 -:100E0000F82428469047B068D0F8E8100968A9424D -:100E100002D1D0F8D80480472046BDE8704008F0E1 -:100E200039BE00BF0C010020F8B515460F46064636 -:100E300002F0E2FBC8B11C21044608F045F8284640 -:100E4000002D08BF0120A07467812680074890F814 -:100E50006C00012812BF0720284606F019FF6074B5 -:100E600003480078013040082074F8BD407B002022 -:100E7000D1BC0200F8B50F484FF6FE750E4C6F1C42 -:100E800006784EB12CB120461C2108F01DF8678170 -:100E900025801C34013EF4E7084900200022032A83 -:100EA00008BFF8BD01EB820301F8220001325D802A -:100EB000F5E700BFD5BC0200DC5B002034870020D2 -:100EC00010B50D49002481F826400C49087003F044 -:100ED00075FF08F089FC0A480460FFF7CBFF09485A -:100EE0000078012803D806F033FCF7F749FEF0F745 -:100EF00021FE0548046010BD407B0020988800203A -:100F0000E487002018260020CC260020F8B5114FD9 -:100F10000C463968C9B115468A69B2B18A6AB2B15C -:100F200000042146461C3046904780B1A8421CBFB1 -:100F30000C20F8BD3868214682693046904701464A -:100F40000020012908BF0A20F8BD0020F8BD0920B3 -:100F5000F8BD00BF5C270020B0B508F0EFFA0446EA -:100F600008F06FFD0028FBD0032003F001FC0B48C4 -:100F7000002180F83811204608F08CFD084881686F -:100F800002200D4688470446102004F04FFC24B18F -:100F900003202946BDE8B0400847B0BDD81B00205B -:100FA00090BA0200F8B592E87800771C08BF0526D1 -:100FB000002780F828700127C0E9043100F11801EA -:100FC000B740F0C11169C0E90B110849CA6D02EBC5 -:100FD000C602426301F140024060006000F1080176 -:100FE000104607F00FFA0020F8BD00BFA01F002038 -:100FF00070B50446417880786268267F1044A6F177 -:101000000D02B2FA82F2520941EA4211227C41EA0F -:10101000C20100F8011BA16908F06FFD05460D2E05 -:1010200005D104F10801284608F0A9FD0835207C07 -:10103000012804BFA07D287070BDB0B588B0002025 -:101040000DF10B018DF80B00CDE90000684603AAF5 -:10105000F8F7B0FA04469DF80B0078B103AD1421FF -:10106000284607F031FFFF20214614222B468DF839 -:101070001C00042005F0A4F9002000E0012008B0C5 -:10108000B0BD0000BFB504460F48002590F826000B -:10109000082801D0042814D14FF6FD70ADF80400E3 -:1010A00007F0AEFD0290207861788DF80D508DF834 -:1010B0000F508DF80C108DF80E0001A8F7F748FCC2 -:1010C0000546284604B0B0BD407B0020FEB58E6AC0 -:1010D0000446777807F01F00012812D101ADB11C3A -:1010E000284608F04CFD0A482946393006F0DDFA5A -:1010F00050B11F2F05D8B6F80B10B07A02F0B8FA2D -:1011000003E0D320F5F705FE00242046FEBD00BF16 -:10111000407B002010B50446C00704D00C4A2120B3 -:10112000742108F073FB200748BFFEF755FB094800 -:101130000078012803D8A00748BFFCF72BF9600707 -:1011400005D50548006810B1BDE81040004710BD46 -:10115000407B0020182600200824002080B546F29D -:1011600000014BF64C4E4BF6504CC4F20C01C0F251 -:10117000020EC0F2020C00BF0B6800BF4A68934227 -:10118000FCD1834208BF80BD1EF803201EF800304A -:101190009A424FF0FF3338BF01231A441CF8022053 -:1011A0000A60E9E70E485022016841F4087121F015 -:1011B000020101600B48032140F8041C41F2300198 -:1011C00081600121016082604FF4CA620160826027 -:1011D0004FF48652016082600160034801607047ED -:1011E00000000460586004400041044070B50446AB -:1011F0004668082005F038FF90B1054601202870A8 -:101200003078033008F010FD686048B13178CA1CAE -:10121000314608F075FD064829460078FDF744FF81 -:10122000606806F01FFE2046BDE8704008F0FABC7A -:10123000C8260020B0B504460C480D46007808B911 -:1012400004F0BCFD0A480078A0429CBF0020B0BD5D -:10125000094A084904EB4400002D18BF294652F8FA -:10126000200082692046BDE8B04010479B2700203F -:10127000F3BA02009CBC0200A0B902001FB50E49DF -:101280004FF6FF730A780D49A2B131F8044B013AC9 -:101290009C42F9D08442F7D14FF0FF32ADF8040000 -:1012A000074841F8042C02218DF80C10818C01A80C -:1012B00008F0DEFC1FBD00BFD6BC02008086002007 -:1012C000407B002070B1B0B5044608F040FB0D49EA -:1012D000886054F8042D002A05D40B498A6801322D -:1012E0008A600BE0704722F00042074B22605D6885 -:1012F0002A445A600A68A24288BF0C60BDE8B04028 -:1013000008F001BCD025002044250020B0B508F02D -:1013100015F9044608F095FB0C48002180F83811B7 -:10132000032003F025FA204608F0B4FB0848816842 -:1013300002200D4688470446102004F077FA24B1B5 -:1013400003202946BDE8B0400847B0BDD81B0020A7 -:1013500090BA020070B500250C4645710D4806781C -:101360000D48AE420CD0415D227B914201D0013547 -:10137000F7E72046F8F7B2FBE8B2864218BF70BD27 -:101380000620002160732068407BBDE8704000F0BB -:1013900069BA00BFD2BC02004084002010B50446E8 -:1013A00048060FD40E480078012815D8204608F0CA -:1013B00014FB88B1007909490138C98A022838BF6D -:1013C0000C4609E0FF20214605F072FB0349002886 -:1013D000CC8A08BF6FF00104A0B210BD407B002092 -:1013E000182600201CB58DF80700022004F036FAFC -:1013F00008B1012415E007F099FC012488B10DF132 -:101400000701E12000F03AFE0DF1060152208DF8AF -:10141000064000F033FE044800248470002007F0EA -:101420004FFF20461CBD00BFC02600202DE9FC4711 -:101430009846AAB115460E46074600244FF0FF3ADB -:101440000DF1040931192A1B38464B46CDF800A08E -:10145000E7F7CCFA01990C4428B96D1AF2D102E0F1 -:1014600000246FF00900B8F1000F18BFC8F8004061 -:10147000BDE8FC8710B50E4C322000210122234626 -:1014800007F008FD0B4B33200021012207F002FD7D -:1014900009482178007801294FF4006113BFBDE8A5 -:1014A00010406422BDE81040FDF7A2BA08F022BB4C -:1014B000BD270020BC27002098880020B0B50F4C25 -:1014C0000F4D48F201012078A84720784FF40041E1 -:1014D000A847207848F22101A847207848F2220145 -:1014E000A84720782021A84720782121A8472078E4 -:1014F00022212A46BDE8B040104700BF998800204D -:10150000B50902002DE9F041DFF83CC04FF0000EB4 -:101510004FF00008864513D01F4615466DB131F8CF -:101520001E603C88A64202BF5FFA88F62CF816407F -:1015300008F101080237013DF0E70EF1010EE9E77D -:101540005FFA88F0BDE8F08114810020E0B58DF8E5 -:1015500007000D48017821B100210170EFF7B4F9BF -:1015600010E00A48816819B10DF10700884709E0C9 -:101570000020012102228DF805000548007801AB0A -:1015800002F01FFF00208CBDAB2700203C83002011 -:10159000998800207FB504468069068808F004F821 -:1015A000864209D107F0EAFB05460B48012106F007 -:1015B00049FE681E002301E080230020227C617C1C -:1015C000C0B2CDE9006048F205000392024A0292DF -:1015D000A21CFDF771FE7FBD1481002070B504468A -:1015E0000F481E461546406808F087FA052D05701D -:1015F00001D8467006E0FE2D06D3DDE90421FF2D5B -:10160000427003D0062303E0052301E00823418054 -:10161000034821463822BDE87040FDF7FDBE00BFFB -:101620007C2600202DE9F041DFF83C80DDE9067CD6 -:101630001C46D8F80460250605D017F8015B013C6C -:1016400006F8015BF7E7BCF1000F18BF4FF0010C83 -:101650004FEA8C1488F80240FDF7DEFE002188F87E -:101660000210BDE8F08100BF7C260020B0B5142038 -:1016700008F0DAFAD0B11421044607F025FC4C201A -:101680001421224608F0BCF80546092804D14C2054 -:101690001421224608F0BAF8204608F0C3FA044A9A -:1016A0007120082108F0ACF82843B0BD0A20B0BD75 -:1016B000AC260020B0B5104CA068D0F8E0038047FD -:1016C000A068D0F818028047A068D0F8F0028047E0 -:1016D0000025A068072D07D0D0F8A00050F82500FD -:1016E00000B180470135F4E7D0F858038047EB207C -:1016F00007F060FF0120B0BD0C01002070B590B074 -:101700006E460C4605464021304607F0DDFB40F2B0 -:101710000110ADF80A40ADF80050ADF811000120FD -:101720008DF80E0002208DF808008DF80C0004489A -:101730008068D0F888123046884710B070BD00BF6E -:101740000C010020E0B502464878800709D00D481A -:101750000368ABB108461146002202B0BDE88040E4 -:101760001847094801916946ADF8002004F08EF849 -:1017700030B10621417300680021407B00F072F80F -:101780008CBD00BFF0260020990A02001CB50F4C4A -:10179000032184F82A1001218DF8071008B10022D6 -:1017A0000AE06079022801D8013003E0206902F0E4 -:1017B0002DFC00200122607105480DF10701012375 -:1017C00000910321007801F056FB1CBDAC220020E3 -:1017D0009F880020BCB504460D480E4D417044B1B1 -:1017E0000D484FF480510078FDF702F905F1330000 -:1017F00000E0281D002184F0010201230170064849 -:101800000DF1070100910121007801F034FBBCBD0E -:1018100008880020AC2200209F88002010B50446D4 -:1018200020B90E488068D0F84C05804707F086FE46 -:101830000B490A78A2430A7008F02CF9FFF782FAE4 -:101840000648C168C968097801B110BD80680021E7 -:10185000D0F858240020BDE8104010470C010020AB -:10186000AD880020B0B5044614200D4605F0FCFB01 -:1018700058B101460C2008700B488C7000244D7044 -:101880008C730078FDF710FC0CE0204606F0F2FFA8 -:1018900038B106214173007B03F0D0FD2046F8F7F4 -:1018A000DFFC10242046B0BD988800202DE9F041CF -:1018B00004460F484FF00008062600270568A5B12A -:1018C00028680188A1420ED16989A5F808804907D6 -:1018D00003D5287B03F0B2FD2868407BF0216E73AE -:1018E000FFF7C0FF0137281DE8E7F8B2BDE8F08137 -:1018F00054880020B0B507F021FE05460D48046865 -:1019000094B10D4854F80C1C007821B14FF40051EB -:10191000FCF79EFB03E04FF40051FBF7D1FD0548B7 -:101920002146002203F02AFD284608F0B3F820469D -:10193000B0BD00BF3C27002098880020B0B5017DD5 -:1019400005460C30022904D003291AD108F099F871 -:1019500002E0008808F041F8044690B16878F12868 -:1019600018BFE12806D1A079012806D1208808F007 -:1019700065F902E008B90020A071A07908B101382A -:10198000A071B0BD10B50D4C207838B90C480D4988 -:101990004FF4D67208F0B4F9012020700A480221F1 -:1019A00080F88F10012180F88510002180F8451003 -:1019B000042180F89D100321017010BD8B270020A9 -:1019C0004C40002164A80200DB030021B0B52021B7 -:1019D000EFF3118481F3118801250B49CA6A0D6068 -:1019E0004069030CB0F5802F38BF04239818486174 -:1019F00006482321006802680020904704480560DB -:101A000084F31188B0BD00BF042009408401001098 -:101A100080022443B0B5104C00252574E06810B94D -:101A200004F063FEFAE7E068216AB0FA80F0C0F1E2 -:101A30001F0001EBC000E169814209D2E061A169A8 -:101A4000026801F11C0002F11C01A26105F05CF9C1 -:101A5000207C0028E1D1B0BD3822002070B50D46B1 -:101A6000044607F06BFDD4E901128A4204D108F064 -:101A700011F84FF0FF3070BDE36822680133B3FB0B -:101A8000F1F606FB11315554E160A168626901313C -:101A9000A160914288BF0A46626107F0FBFFA0681F -:101AA00070BD10B58EB0E1B10C460168086AC0B1D6 -:101AB000C97F01AAEFF702FB6188BDF81020002062 -:101AC0008A420FD19DF8061001290BD10B9801789D -:101AD000012906D121788078401AB0FA80F04009B7 -:101AE00000E000200EB010BDF0B585B007461546E9 -:101AF0000E460088DDE90E121C46F2F7D1FF0528DC -:101B00000FD080B9DDE90C10DDE90A32CDE90032F1 -:101B1000CDE90210384631462A462346E6F7BEF89C -:101B200002E0022000E0102005B0F0BDB0B5044690 -:101B3000202005F099FAC0B1054604201022287033 -:101B4000D4E90001C5F80200A81D07F021FBE168F7 -:101B500005F1160007F0E3FB208A2946E8830348D5 -:101B60000078BDE8B040FDF79FBAB0BD998800206D -:101B700010B50F4A8389526803EB430302EB8304D9 -:101B80004A1E012A0AD84288022962800BD10430F9 -:101B900006F02CF938B90020207004E0221D011D48 -:101BA000104607F0BCFB2046BDE8104007F09CBC87 -:101BB0003426002010B50C48032290F8481001216B -:101BC00080F8481009480275094A137A11720069B1 -:101BD00040B1084C204607F0ADFD2046BDE810405E -:101BE00007F0AEBD10BD00BFA01F0020381F0020B1 -:101BF0003822002087740100F8B50E48048820467A -:101C000008F012F8A0B12146FF22054607F056F968 -:101C1000094800270678B74207D2F9B202202246C7 -:101C20002B46FEF7A3F80137F5E7284607F0FAFF41 -:101C30000020F8BDC2B40200E2BC0200F8B50D48B5 -:101C40000D4D0E4F0126046804608CB1B4FA84F087 -:101C5000696880F01F0006FA00F251F820109443E2 -:101C60000029F2D057F820205203EED58847ECE740 -:101C7000F8BD00BFE020024014BB02000010084085 -:101C8000F0B585B00D4F04460B480D4D6E463246FB -:101C9000397880F872402846FEF714F83A783046D2 -:101CA00029468DF81240FDF742FD4520294600F0F7 -:101CB000E5F905B0F0BD00BF407B0020A92700205A -:101CC0000887002042F24011C4F208010A68496DF9 -:101CD000C30701D1002106E002F0010301F0040175 -:101CE000C91818BF0121830744BF02F0020341EA6B -:101CF0005301400744BF02F0040041EA9001022072 -:101D0000002918BF0120704742F24011C4F20801B7 -:101D10000A68496DC30701D1012106E002F0010301 -:101D200001F00401C91818BF0121830744BF02F064 -:101D3000020301EA5301400744BF02F0040001EA34 -:101D400090010220002918BF0120704770B58AB0A9 -:101D50000C4C4FF48061DD224FF48066204607F082 -:101D6000ADF801AD284607F081FD042007492A4659 -:101D70000023CDE905460490034804F0D9FF0AB0DA -:101D800070BD00BF54610020807C002011910200D2 -:101D900070B507F0D3FB04460B48017821B120460B -:101DA000BDE8704007F076BE012101700748057854 -:101DB0000748002DF3D0064656F80C1B8968884763 -:101DC000013D3046F5E700BF9C27002000000000E1 -:101DD00000000000B0B511F1800201D1002112E035 -:101DE0000C4A002303EB830544577F2C09D005449C -:101DF000D5F801501540954203D08C4201DC0133E7 -:101E0000F0E72BB1591E01EB81010844D0F8012005 -:101E10001046B0BDFFFF3F00F0B50F4C00234FF060 -:101E2000580C8EB20027B3F5307F0FD0E1180D8E1D -:101E3000B54208D139B10D69854204D14AB191F852 -:101E40003350154203D158330137ECE700210846DF -:101E5000F0BD07FB0C41FAE75865002070B5044659 -:101E600005680D48C6680D480068006B8047811BF7 -:101E7000080B05EB1132B5EB113F40F6C41188BFDA -:101E800050082060884204D880084A2802D84FF4BD -:101E90009671216070BD00BFD01E00208C01001023 -:101EA0002DE9F04105460E480078A8429CBF00206D -:101EB000BDE8F081164688460027BD4208D036F8B6 -:101EC000174007F071FB844201D00137F5E7FDB2FE -:101ED000A5EB0800B0FA80F04009BDE8F08100BF32 -:101EE000DBBC020070B507F029FB04460B48017803 -:101EF00021B12046BDE8704007F0CCBD0121017042 -:101F0000074805780748002DF3D0064656F80C1B05 -:101F100089688847013D3046F5E700BF9D270020CE -:101F200013BC0200B8BB020010B586B00DF117005B -:101F3000F9F7D4FBB0B19DF8172004467AB14FF6FB -:101F4000FC701F212346ADF80C000F208DF8140003 -:101F50000020CDE90010044803A9F1F7E1FF204675 -:101F600007F060FE06B010BD7C26002010B50B4CBB -:101F700048F215012070FEF71DFD20783821FEF78C -:101F800019FD07480749084A20610848C4E90221A9 -:101F9000022101724FF6FE71018010BDCC24002099 -:101FA000B1320200FD5402001D5F02007A8700205A -:101FB0002DE9F041C189846948F21F00814208BFC0 -:101FC00001342778F800013007F02EFE804670B10A -:101FD0004546661C002405F8017BBC4207D2284612 -:101FE000314607F0CCFD013408350836F5E74046A8 -:101FF000BDE8F08110B502460E480023006838B1F4 -:102000000479944202D1C4888C4203D00346F5E798 -:10201000012010BD01680BB1196006E011B1054A3D -:10202000116002E0034900220A6007F0FBFD002076 -:1020300010BD00BF6827002010B5EEF7C7FE0C4C9E -:10204000207840B906F0DCFD0246AB20002103F009 -:10205000EFFD207810B106F0E3FF28B1054800211C -:102060000170054801210170BDE8104003F0AEBFCA -:10207000182600209D8800209C880020B0B50C46C2 -:102080000546522806D0E22D0BD10B48214607F019 -:1020900076FD06E0074821780078084304BF012058 -:1020A000B0BD064821468068D0F830242846BDE8F7 -:1020B000B0401047AD2700209E8700200C01002073 -:1020C00010B50423082200F0010403EA901302EA89 -:1020D000503223441A44102303EA1050104401F0F4 -:1020E000010240EA4210402202EA9102104480229A -:1020F00002EA512210444FF4807202EA114108436F -:1021000080B210BD10B50D4C2078FE2807D00C48C9 -:102110000068826B0B48006894F900109047607863 -:10212000FE2807D006480068826B0648006894F9CC -:1021300001109047FE206070207010BD1425002013 -:1021400030880020D826002010B5EB2002F0B0FC2B -:102150000B48002404700B480078862802D1002028 -:1021600002F034F807F0EAF907490A6813681C71AD -:1021700012680A6007F08EFCBDE8104006F0FCB85B -:10218000AF880020B4880020C08700200C480E4B88 -:102190008068DB68D0F8D410D0F8EC00497B50F8A8 -:1021A000210008490A680B60991A084A12789200BF -:1021B00091FBF2F1B1FBF0F202FB1010704700BF8F -:1021C0000C0100202C880020F8860020B088002018 -:1021D000B0B50F4CA168D1F8B8000278B2B1C569AA -:1021E000A5B1086C0268D06D28B102210023A84770 -:1021F000A168086C0268106E40B1D1F8B8100023D5 -:10220000D1F81CC00821BDE8B0406047B0BD00BF98 -:102210000C0100202DE9F04104460D484FF6FE78F0 -:102220000C4D08F1010706787EB16889A04218BFFD -:10223000002D02D11C35013EF6E728461C2106F090 -:1022400043FE6F81A5F80080F4E7BDE8F08100BF90 -:10225000D5BC0200DC5B0020B0B570B104460E486E -:10226000416851B100220D462B4625B1A34202D050 -:102270001D681A46F8E7A34200D0B0BDA14219BFBD -:102280002068106021684160204607F075FC2046F8 -:10229000BDE8B04007F0C6BC44260020012919D093 -:1022A00010B5B0F90E0000EBE03181EAE03084B205 -:1022B000204600F037F80848084AC16C51F824302D -:1022C000934218BF41F82420006D002140F82410EB -:1022D000BDE81040704700BF381F0020916C02001D -:1022E000F8B50D4E04460D4F306E50F82100B8423F -:1022F00001D00020F8BD0A480D461C300090204651 -:1023000005F0F2F80028F4D0306E50F82500C01B1C -:1023100018BF2046F8BD00BF381F0020916C020096 -:10232000A01F002010280FD310380E4A01234109A6 -:1023300000F01F0002EB810103FA00F0D1F8F02059 -:10234000C1F87001104070470F281CBF0020704773 -:1023500004480168026822F00202026001F00200F3 -:10236000704700BF10E000E010280FD310380E4A6D -:102370000123410900F01F0002EB810103FA00F084 -:10238000D1F8F020C1F8F000104070470F281CBFB2 -:102390000020704704480168026842F002020260AF -:1023A00001F00200704700BF10E000E000B170478C -:1023B00080B52021EFF3118081F311880A49CA6C9E -:1023C00022B180F31188FCF7B3F804E0002281F811 -:1023D000482080F3118805490122087A0A72BDE875 -:1023E000804001F017BA00BFA01F00203822002053 -:1023F000BCB50D4D286840B96C46204606F096FFE6 -:1024000001202146EDF724FC28600849097851B9DC -:1024100048B107490978012903D1642101F03AFB49 -:10242000BCBD00F0EAFCBCBD24880020922700203F -:102430009C8800201FB5044600790B2101EB400069 -:10244000C0B204F011FE38B123790DF1050223B1B9 -:10245000012B04D1511D07E01FBDD11C04E0D11D8B -:10246000032B08BF02F10901A2890A8004B0BDE86C -:10247000104005F0F7BC70B505460D200E4607F07C -:10248000D3FBC0B10680044615F8020BA0702946A4 -:1024900015F8010CE070201D07F071FB287AC121AE -:1024A0000D2223462073452000F0E8F82046BDE8C1 -:1024B000704007F0B7BB70BD2DE9F84317460E46D4 -:1024C000044606F0F5FEB0B10546DDE9089808209F -:1024D00004F0CAFD78B10146C780067180F8039008 -:1024E000847080F80180FE20087068680078BDE87C -:1024F000F843FCF7D9BDBDE8F883000010B50446E9 -:10250000007DA0B92046EEF7E3FA206918B10A4829 -:10251000816820468847207D28B1E06807F082FB6B -:102520000020E06003E0E068FCF7D8F92075204661 -:10253000BDE8104007F0B1B95024002070B50C2060 -:1025400007F072FBA8B10C4E04464FF0FF30002597 -:10255000A060606020603088854207D2A9B2012067 -:102560000C222346FDF702FC0135F4E7204607F074 -:1025700059FB002070BD00BF342600202DE9FC412E -:102580000D4D4FF00008002600272888874228BFFD -:10259000BDE8FC816868B9B200220C2384190120CF -:1025A000009403F0F7FE20B92078FF2808BF84F8D4 -:1025B00000800C360137E8E73426002070B5102083 -:1025C00007F032FBB0B104464FF0FF300026E06068 -:1025D000A0606060206008480578AE4207D2F1B282 -:1025E000032010222346FDF7C1FB0136F5E7204604 -:1025F00007F018FB002070BDE6BC0200F0B585B006 -:102600004FF0FF300027ADF810000390CDE9010036 -:10261000084801AD048808480678B74224BF05B0D1 -:10262000F0BDF9B2022022462B4603F0C9FE013765 -:10263000F3E700BFC2B40200E2BC020070B50E486E -:102640008068D0F8D810096819B9D0F8DC000068A3 -:1026500080B106F073FF044607F0A8F8054601F0C4 -:102660007DFD0646204607F015FA701C281A98BF13 -:10267000012070BD002070BD0C0100202DE9F0414B -:102680000746D01C984614460D4604F0EDFC80B178 -:10269000064685704770047024B1F01C41462246FE -:1026A00007F02EFB044831460078BDE8F041FCF706 -:1026B000FBBCBDE8F08100BF8E88002010B5094941 -:1026C000094C0020A04709490120A04708490620DD -:1026D000A04708490720A047074908202246BDE82F -:1026E0001040104781E80100DD8C0200395A0200D9 -:1026F0003F3902009D510200CD51020080B5EFF735 -:1027000019FA0B4A2120742107F080F802F09EFC90 -:1027100008480078012898BF02F0B0FC064800681D -:1027200000B1804702F076F9BDE88040F7F758BC69 -:10273000407B00201826002000240020F8B50D4E14 -:102740000C464FF487727788F188C91B01F58771B1 -:1027500091FBF2F303FB12118AB2A24238BF0C467E -:102760000549A5B22A46394407F0CAFAE019708033 -:102770002846F8BD702400202A71002070B5D0B121 -:1027800005680446BDB12868A8B107F0E0F8064620 -:10279000286807F01FFA10B1286807F075F9286853 -:1027A00006F0B4FE2846FEF78DFD00253046256074 -:1027B00007F0A9F900E00225284670BDF8B51746D4 -:1027C0000D46064607F0C3F83168044639B14FF0AC -:1027D000FF3051F80C1C01300029FAD100E0002034 -:1027E000B84205D23046294604F086F8012500E0BB -:1027F0000025204607F087F92846F8BD0B4A1278D5 -:10280000012A11D10A4A127882420DD9094A0A4B8B -:10281000002918BF0A4600EB400103EB810053F882 -:102820002110CB6811461847002070479C270020D4 -:1028300000000000B8B90200000000000B48016869 -:102840008907FCD50A4801210A4AD0F83C01012831 -:102850004FF0010008BF2020906108230020106085 -:102860000548036043601160704700BF58600C402A -:10287000D81B002000400C4038500C4040F00201B2 -:10288000022918BF70477CB50A4D0B4C80B27022EC -:10289000042329684E68009020460021B04728682C -:1028A000002170227023D0F80CC0204602B0BDE891 -:1028B00070406047A401001000A00C4070B50E4AA3 -:1028C0000C4900234FF6FE7403251278053193421C -:1028D00028BF70BD4E78F60709D131F8036C8642E7 -:1028E00005D10E78012E04BF21F8034C0D7008317C -:1028F0000133ECE7E04C0020DABC02000C4A12780D -:10290000012A11D1094A127882420DD9094A0A4B8B -:10291000002918BF0A4600EB400103EB810053F881 -:102920002110CB68114618470020704713BC0200E5 -:102930009D27002024B90200B8BB020080B50146E3 -:1029400000780C2803D00D2814D1486801E04868AD -:10295000C83078B1027802F00302032A0AD18078E5 -:1029600000F00300032805D103480078FCF79CFB26 -:10297000012080BD002080BDC026002010B586B09B -:1029800001AC1121204606F09FFA81201121224638 -:1029900006F036FF70B901AB81200021112206F04C -:1029A00079FA38B99DF8040020B10348018841F054 -:1029B0001001018006B010BD268700207CB50C46B2 -:1029C0000D491D7800268DF8070049684A70120AE3 -:1029D0000E70081D8A701A78CA7013F8012B1946F8 -:1029E00006F0D6FB281D214648F21102C3B20DF1B4 -:1029F0000700FCF711FD7CBD7C260020F0B587B0F8 -:102A000001AD04461821284606F05EFA0027022F81 -:102A100084BF07B0F0BDFEB2062018222B46314617 -:102A2000FDF7A4F9012C08BF002805D10620314686 -:102A300018222B4603F0C4FC0137E8E7BCB50C466E -:102A40000DF10601154603F0D2FD0146C82091B9EB -:102A50000949096879B1BDF806200020032804BFA0 -:102A6000C820BCBD0B88934202D006310130F5E787 -:102A7000288000202160BCBDE0260020BCB50D4DA3 -:102A80000028A968D1F8C81318BF01208847044658 -:102A900000200DF107018DF80700A868D0F8302458 -:102AA00056209047A8680449D0F83024E220904787 -:102AB0002046BCBD0C0100209E8700202DE9F84374 -:102AC00007460C480C4C90468946002605786DB1A7 -:102AD0002078B84207D12046494605F0CFFB10B117 -:102AE000464504D201360E34013DF0E7002420466D -:102AF000BDE8F883E2BC020018870020B0B5056885 -:102B00000446B5F85610A86807F066F8A86807F0FC -:102B100065F8204605F0BBFCB5F8580040B14FF60B -:102B2000FF71884204D00138A5F85800000400D095 -:102B3000B0BD2046BDE8B04004F02FBD70B50D4ECD -:102B40000D4C30688168204688470546606840F033 -:102B50003000606028060AD03068002142682046B4 -:102B6000904730688168204688470028F9D1E8B24C -:102B700070BD00BFD8010010004003400B480C4A54 -:102B8000D0E90210137B0068D1F8E01003F0F003E5 -:102B900002330078096813730844064909784843EA -:102BA0000549096801EB8000906070470C01002026 -:102BB000A8850020B08800202C880020F8B50E4E93 -:102BC0000C4605460027ACB1606841196160B068E9 -:102BD000D0F8E8201268944204D1B1F1FF3F01DC43 -:102BE000676005E0B1F1FF3F02DCD0F84C0580479B -:102BF0002468E8E7F8BD00BF0C01002080B50C4850 -:102C0000007806280ED10B480178013101700A487E -:102C10000188022906D3013901800620BDE88040E1 -:102C2000E4F72AB9FDF7D8FABDE88040F7F798BA7B -:102C3000B7880020A6270020AE87002010B58EB0F0 -:102C400001680446086AA0B1C97F01AAEEF736FA06 -:102C50000948BDF80E10C08A81420AD020689DF84C -:102C600021200388BDF8100000934FF6FE73FDF796 -:102C7000D0F80EB010BD00BF407B00204FF6FE73B1 -:102C8000984203D002F06003602B01D1012070470D -:102C9000930608D4084B5206DB8A09D4834209D331 -:102CA0008B42F3D906E00448C08A8842EED901E09D -:102CB0008342EBD200207047407B002070B520207B -:102CC000EFF3118480F3118809480068006B804796 -:102CD000084AD2E91556084AD2E9102384F311882C -:102CE00006F0F6F8281AB04288BF002070BD00BF79 -:102CF0008C01001008200020207C002070B50E48B8 -:102D00000121047A017285692020EFF3118680F396 -:102D10001188284600F060FD032085F82000284631 -:102D200001F0C4FA86F311886D602D602046BDE87D -:102D3000704000F06FBD00BF3822002010B5F7F7DB -:102D40000FFB04F0D5FF02F0B1F90B4C94F83C00F6 -:102D500010B9012084F83C00F6F770F803F0C0FFCA -:102D600003F0FAFFFAF7CCFE02F05CF806F042FD41 -:102D70000120207010BD00BFA01F0020B0B5054687 -:102D80000C460846D121FDF757FD08B14570B0BD8E -:102D9000022004F069F940B101464570D120087065 -:102DA0002046BDE8B040FCF77FB903481021007809 -:102DB000BDE8B040FBF74CB99988002070B50568B4 -:102DC000686810B10C46642901D9002070BD2968DB -:102DD00001FB04F66421B6FBF1F106F09AFE014610 -:102DE000B0FA80F0400909B985F853400021632EFC -:102DF00088BF012185F8511070BDB0B5046800216D -:102E000084F8511094F85210012906D194F8540016 -:102E1000002106F01DF9012006E094F8535000212E -:102E2000FFF7CCFF84F8535094F8501002291CBFD0 -:102E3000002184F85010B0BDB0B504460078617828 -:102E4000084406F0F1FE054698B12178284606F0C0 -:102E50003BF84FF6FE70688006F0A6FBA88020784D -:102E6000617828442975286104F0D2FC6875A0783F -:102E700028762846B0BD2DE9F843CBB1089CBCB1FB -:102E80008046981C1F4616468946C0B204F0ECF8EE -:102E900070B10546023021463A4606F079F96E7067 -:102EA00085F8009040462946BDE8F843FCF7FCB899 -:102EB000BDE8F883B0B505460E2004F0D5F8A0B102 -:102EC00004460720207028886080A8780228207196 -:102ED00004D16968601D082206F05AF903482146AA -:102EE0000078BDE8B040FCF7DFB8B0BD998800209D -:102EF000B0B50446102004F0B7F8A0B1054605208F -:102F0000616808222870208868802089A881281D8F -:102F100006F03EF9A07A2946A87303480078BDE878 -:102F2000B040FCF7C1B8B0BD99880020B0B50578B5 -:102F3000ADB1044603F018FC01280FD10948A1895E -:102F4000406801EB410210F82210294205D100EB44 -:102F500082002943017006F0C7FA0120B0BD0020AD -:102F6000B0BD00BF342600201FB582B100230193FD -:102F7000D2E9013412788DF80420094A02930394AF -:102F800002F11C0301AA03F0CCFF04B010BD044AF7 -:102F900002F11C03002204B0BDE8104003F0C1BFE1 -:102FA000A01F0020FF2817D0B0B5044605F012FB83 -:102FB0000A4D286850F82410204606F068FD68681D -:102FC00050F8241011B1002140F82410A868002105 -:102FD00040F82410BDE8B040704700BF14BB0200A9 -:102FE000BBB12DE9F04786B0DFF82CE0EC46664631 -:102FF0009EE8B00786E8B007D3E900451B7A8DF854 -:103000000830634601940495FFF76AF906B0BDE8FD -:10301000F0870023FFF764B960BA02000A49097813 -:1030200009B10120704709490978FF2904BF002030 -:103030007047084B064A0433022808BF131D18685E -:10304000C84000F00100704770270020B1880020C0 -:1030500008850020E0810020BCB50C4605460DF136 -:1030600007016A46204602F001FA10B14FF6FE74DD -:103070000EE09DF8070000992870696030B1421E8B -:1030800001EB400030F8024C6A7001E000206870EB -:103090002046BCBDB0B50446007A38B1254635F8A7 -:1030A0000C0FE968F1F72CFF01280AD0E07968B12C -:1030B00034F80A0FD4F80A10F1F722FF0128254648 -:1030C00004D12888FAF754FC0120B0BD0020B0BD1F -:1030D000C0F340228A7100F003028A70C0F380229C -:1030E0004A77C0F300224A71C0F3403281F83120A0 -:1030F000C0F300320A72C0F3C022CA71C2B2800BA0 -:103100009309C2F383020B71CA70704710B5012096 -:10311000FFF7B4FC0446FBF751FD0948007801288D -:1031200098BF04F025FB05F019FA02F0C7FB05F083 -:1031300007F904480078FDF7C3FE204610BD00BF24 -:103140001826002098880020B0B50B4890F86640FB -:1031500084B10A48058806F0FFFB28404FF47A71D5 -:1031600014FB010206484FF480710078BDE8B040BE -:1031700006F0BDBCB0BD00BF407B00209EBB02007E -:103180009888002010B542F28C11C4F20801086042 -:10319000D1F8980040F2B81440F00300C1F898004C -:1031A000C1F20004206881692020884742F22C0087 -:1031B000C4F2090000682068806BBDE81040004739 -:1031C00070B50D46064606F0C2FB04463046294659 -:1031D00004F0EEFC60B1006806F0FAFC054606F06B -:1031E000F3FC4FF47A71B1FBF0F0B5FBF0F500E0C1 -:1031F0000025204606F087FC284670BD7CB50C4DA6 -:103200000C4C00214FF4C072072328684668022046 -:1032100000902046B047286800214FF4C072072371 -:10322000D0F80CC0204602B0BDE87040604700BF37 -:10323000A401001000A00C4080B50B4902220A72C4 -:103240000A4A10704FF6FE70088005F0D9FC04F0B1 -:1032500019F8074804F04CF8FFF790FB05F086FAE0 -:10326000BDE88040FEF72AB97087002099880020C9 -:10327000942500200B48007802280BD20A48807B56 -:10328000800708D509484FF4807140F6C4120078D1 -:1032900006F030BCF6D105484FF480710078FAF79B -:1032A000D7BE00BF18260020407B00209988002050 -:1032B000B0B50546242003F0D7FE98B1044632206D -:1032C000A9681B2220702878A0706868606004F1EB -:1032D000080005F05DFF044821460078BDE8B040D5 -:1032E000FBF7E2BEB0BD00BFCC24002070B5FEF7F6 -:1032F0005FFEC0B10446451C0026207886420DD2F0 -:10330000284606F0BEFB30B100790138012802D80A -:103310002846FBF7C1FD08350136EEE72046BDE83B -:10332000704006F07FBC70BD80B50C490978022959 -:1033300008BF012800D080BD0948C0780028FAD114 -:10334000FDF798FD06F00EFA18B1BDE88040F6F7DB -:1033500087BE0020BDE88040FEF718BA182600207E -:10336000C4260020F8B50D4F06461C461546786861 -:1033700006F005FC681EB0FA80F040098001012CBF -:1033800008BF8030796834220923087238463146F4 -:1033900001B0BDE8F040FCF73FB800BF7C2600203C -:1033A0001FB50D4C030A002962685370107018BFD6 -:1033B0000121880115220223A0704FF6FD70ADF89F -:1033C00004000F208DF80C0001A92046FCF724F81A -:1033D0000021A17004B010BD7C260020B0B50021F2 -:1033E00001600C490A6892B100254FF6FE74AB1DCE -:1033F000182B0CD0555BA5421D46F8D11A44063A4D -:1034000002600868C118002001F8020CB0BDC82095 -:10341000B0BD00BFE0260020B0B586B00446002055 -:103420006D4618212075284605F04EFD2846214698 -:103430000A2205F0ADFE6089ADF80A0004488068F4 -:10344000D0F8F81228468847002006B0B0BD00BF6B -:103450000C0100202DE9F0411D4616468846044621 -:1034600005F026FF90B10746062003F0FDFD68B188 -:103470000146868084704570FD200870786881F868 -:1034800003800078BDE8F041FBF70EBEBDE8F08197 -:1034900070B586B001AC1421FF22204605F00EFD68 -:1034A000094800260578AE420AD2F1B2082014225B -:1034B0002346FCF75BFC01360A28F4D10A2000E021 -:1034C000002006B070BD00BFCDBC020010B50246A2 -:1034D0000C480023006838B10479944202D1C488B2 -:1034E0008C4203D00346F5E7002010BD0549002BB0 -:1034F00018BF194602680A6006F094FB00F04EFD02 -:10350000012010BDEC2600202DE9F04105460B48B6 -:103510000B4E88460027047864B13078A84206D163 -:103520003046414604F0AAFE002818BF01370E3687 -:10353000013CF1E7B8B2BDE8F08100BFE2BC020097 -:1035400018870020B0B50D4D0446E8688069007802 -:1035500001280AD104F03CFB40B1E8688069017899 -:10356000012902D10021017024B1B0BDBDE8B040F5 -:10357000F3F7DABABDE8B04003F04ABF0C0100200F -:1035800010B504460B480068A04204D80A48806879 -:10359000D0F84C058047B4F1FF3F04DC0648806852 -:1035A000D0F84C05804705F0C9FFBDE8104006F093 -:1035B00071BA00BF388800200C010020B0B5044665 -:1035C0000A480068A04204D809488068D0F84C0531 -:1035D000804705F0B3FF0546064804602046F7F72C -:1035E000EBF92846BDE8B04006F054BA3888002010 -:1035F0000C0100203C880020B0B54FF6FE704FF65D -:10360000FF7101F073FB00B1B0BD0848084D0478AC -:103610000020002CF8D0A97C09B1697C19B9288850 -:10362000FFF74CF928461C35013CF2E7D5BC0200F7 -:10363000DC5B0020B0B505460C480C46007801283C -:1036400009D80948808CA04205D1284606F0C5F962 -:1036500008B10830B0BD2846214601F047FB0028DC -:1036600018BF1030B0BD00BF407B002018260020DE -:10367000B0B50B4D0C4695F87210814228BFB0BD15 -:10368000FEF7FEFA074864210480E87900FB01F2A6 -:1036900005484FF400710078BDE8B04006F02ABA42 -:1036A000407B0020327700209888002070B50D4EB6 -:1036B0000C46B18CFFF7BEFF88B10546807804F058 -:1036C000E7FA697859B150B1884298BF0846727BD1 -:1036D000012A18BF0846A0429CBF012070BD0020EF -:1036E00070BD00BF407B002070B504460C4801212E -:1036F0000160D4E91001D4E91623851841EB0306D3 -:10370000280C002240EA064100F00CF8D4E9162308 -:10371000D4E9060150346CC4BDE87040084700BFCE -:103720000420094010B50C4605F04AFF0B498A6990 -:10373000A31A0632B3F1004F09D8131BB3F1FF3FB0 -:103740002346C8BF1346A24298BF23461A460A60C2 -:1037500000B110BDBDE8104005F038BF1820094089 -:1037600010B5044608480949094A0A4BC4E9021041 -:10377000002004F11001C4E90032A061064804F001 -:1037800041FE204610BD00BFA99B0200AF9B020076 -:10379000A39B02009D9B02009C26002010B588B0D0 -:1037A00001AC0A491C22204606F0AAFA0020094A68 -:1037B000002123468DF810000A20039002208DF886 -:1037C00004000348EBF73AFC08B010BD84B90200CE -:1037D000207C00203D980200B0B50D49CA680368FE -:1037E00044682360436804686360C46C8369256827 -:1037F000A54204BF9A43CA608A69824204BF00227C -:10380000CA6101220A74022180F82010B0BD00BFF5 -:103810003822002000B1704710B50B4C2020EFF388 -:10382000118180F31188207C28B1084890F8480065 -:1038300008B9FEF7EFF80020207240F2000CEFF319 -:1038400011808CF3118810BD38220020A01F0020A9 -:10385000F8B50E460B4900281C464D68314618BF86 -:1038600005462F682846002A08BF0822B8470746A1 -:1038700030B9054A204600212B46009601F020FB76 -:103880003846F8BDA01F0020DBB0020080B50D480F -:103890000078062809D005280BD00228BDE8804012 -:1038A00018BF05F06BB806F058B9BDE8804006F0C7 -:1038B00051B906F003FA00B180BD1C20BDE880407C -:1038C000EEF70ABFB7880020BCB5054600200C46BD -:1038D0000DF10703002101228DF80700032005F0F8 -:1038E000D9FA00B1BCBD9DF80700FF2D0DF107020C -:1038F00014BFA04320438DF807000121032005F0E9 -:1039000085FFBCBD10B5427801788378C478002A61 -:1039100018BF41F00201002B18BF41F00401002C38 -:1039200018BF41F008010279002A18BF41F0400198 -:103930004079002818BF41F08001C8B210BDBFB562 -:1039400004460DF10205082234F8020BADF802001E -:10395000A81C214605F01CFC207AC9210D222B460B -:103960008DF80C00B4F80900ADF80D004520FEF705 -:1039700085FE002004B0B0BD01467F30C0B20328F0 -:103980003CBF042070470120012911D080290FD0AD -:1039900003290DD0022904BF0220704701F0FE0068 -:1039A000842804BF032070470020882908BF032013 -:1039B00070470000B0B50B49402200240A60802205 -:1039C0000A60C1F8FC42056895F8260020B1064857 -:1039D00006F03CF985F826400220BDE8B04000F032 -:1039E000C7BE00BF04440240307E0020B0B550B1D5 -:1039F00004460078102200F07F010520FDF786FACA -:103A000000202070B0BD064800250488A542F9D2E8 -:103A1000A9B205201022FDF779FA0135F6E700BFBB -:103A2000C4BC0200B0B50D4611461A46F6F748FF71 -:103A300090B12946044604F021FC68B1204629468D -:103A400000F0DAFC30B96588204605F0BFF9284659 -:103A5000FDF7BAF80020B0BDB420B0BD70B50C4B76 -:103A60000A4A1C780432002374B112F8245B002641 -:103A70008D4298BF012685424FF0000528BF0125E1 -:103A8000013C35402B44EFE7D8B270BDB054002064 -:103A9000E6BC020010B5046894F85220012A05D152 -:103AA00094F85400012105F0D3FA02E0FFF786F9FB -:103AB00050B194F8500002281CBF012084F8500037 -:103AC000012084F8510010BD002010BDB0B50B4D91 -:103AD00004462878A04201D10020B0BD58B908485A -:103AE0008068D0F83803804728B12046F4F712FEEA -:103AF00008B12C70F0E7E220B0BD00BFAB88002019 -:103B00000C01002070B5B0B10546007A00F0FE004F -:103B1000022810D12846F4F745FEFF280BD02A7A58 -:103B200000210646002401F05FF82A7A3046002181 -:103B300001F034FE00E0E824204670BD86B0044663 -:103B400009486D46047009480068EFF3118180F35D -:103B500011882846152105F0B7F9054A2846152190 -:103B6000234604F0D4FFFEE786270020B4BC020001 -:103B700078BA02004FF6F871884206D30830BF22A7 -:103B8000C1B222FA01F1C90701D1002070470549ED -:103B900000B251F82010044802780220114208BFF8 -:103BA0000120704744B9020090880020F0B50B4A0C -:103BB0000B4D00234FF4877654888B4224BF084670 -:103BC000F0BDA7B201340133EF5DA4B200F8017B70 -:103BD000B4FBF6F707FB16445480EEE7BC26002042 -:103BE0001C700020F8B5094F0C46054605F0AFFEE5 -:103BF000064607480749084AC7E90254FAF79CFEF7 -:103C00003046BDE8F84005F07EBF00BF70240020BC -:103C10002A710020387200201D3C0200B0B50C460D -:103C20000B4D0021E880698010B1E96801B1884737 -:103C30003CB100202870AA68A9881AB111B92046A1 -:103C40009047A98811B12869FAF7A2F9B0BD00BF61 -:103C50007024002070B50B4E05460B4C306881680F -:103C60002046884700F00300002128603068426841 -:103C70002046904730688168204688470028F9D15F -:103C800070BD00BFD8010010004003402DE9FC4189 -:103C90000B4C0746984615460E46606808B18047AB -:103CA00058B10421E0682A464346009106EB4731AB -:103CB00005F03CF9C00FBDE8FC810B20BDE8FC819C -:103CC000A023002010B5FEF70DF9012003F0A4FA9F -:103CD000044605F033FC08490A683AB105F0DAFEFB -:103CE0004CB12046BDE8104005F0FABC0C60BDE8C0 -:103CF000104005F0CFBE10BD0C2400207CB50B4D4C -:103D00000B4C00214FF040521C23286846680320CA -:103D100000902046B047286800214FF40072092324 -:103D20004568012000902046A8477CBDA4010010F2 -:103D300000A00C40B0B50C4D297A09B10720B0BDE8 -:103D4000A98CFFF777FC0028F8D0044680786D7BBB -:103D500003F09EFF012D03D16178884298BF084689 -:103D6000002808BF0720B0BD407B0020B0B505F09B -:103D7000E5FB0A4991E83C000F1D1CC70B69084C84 -:103D80001C4485EA950383EA43030C61534083EAAC -:103D900002150D6005F07EFE6019B0BD1C86002086 -:103DA000C5870500F8B50C46054605F0C7FB2B1D79 -:103DB0006E690ECB8F1AA74238BF3C46224423447B -:103DC000B24288BF16466E61B3FBF1F606FB1131B5 -:103DD000C5E9022105F05EFE2046F8BD70B5066813 -:103DE000054605F0ABFB0446707A70B9012070728D -:103DF000284602F067F8686805F08AFC2846EDF767 -:103E0000BDFC2846002103F01AF82046BDE87040AA -:103E100005F040BEF8B5D0E9006505F08FFB04461B -:103E2000307870B1287905F0F3F9012806D12868B7 -:103E300000274760301D05F0D3FE37702879F1F771 -:103E400005FD2046BDE8F84005F024BEB0B58AB0B7 -:103E5000F1F756FD04AD82200021182200242B46E4 -:103E600005F018F858B9681C69461022CDE90244DB -:103E7000CDE9004404F0DCF8B0FA80F044092046B3 -:103E80000AB0B0BDB0B585690C460846294605F0B4 -:103E900076FE287A2072B5F80900608104F10C00E2 -:103EA000E97A0329217506D105F10C0105F067FEB9 -:103EB000287DA075B0BDA9890180B0BD1CB5816900 -:103EC0000B880A4909888B4204D1094A194600F037 -:103ED0001FFD1CBD017C427C48F20304CDE900417A -:103EE000811C1046802202F06BFD1CBD70870020F3 -:103EF000FC870020BFB514464FF6FD720A4DADF8A1 -:103F000004200F228DF80C206A6822F8020B10465C -:103F100005F035FE686813220B23847201A9284638 -:103F2000FBF77AFA04B0B0BD7C260020BCB54FF098 -:103F3000FF316C460028CDE9001118BF0446AB20C4 -:103F40000021224601F074FE054D2146284605F069 -:103F500016FE712008212A4605F058FCBCBD00BFA2 -:103F6000AC26002010B50C4A1278A2B103466E2888 -:103F700028BF6E23323B322838BF002308783C2408 -:103F800043431BB2012A08BF93FBF4F082B2FF2A1D -:103F900028BFFF20087010BD9E270020F0B585B017 -:103FA0006C460B4F0026A51C3F687FB13879B91DC0 -:103FB00012228DF80000284605F0EAF8F1B2082038 -:103FC0001422234602F0FCF90136EDE705B0F0BDFE -:103FD000EC260020F8B50C4D044600262846002E9D -:103FE00008BF2E46006858B10179A14206D1016888 -:103FF0003160076805F016FE3846F4E70646EEE73E -:10400000BDE8F840FFF7CABFEC26002010B50C4908 -:1040100001F110031C682CB1844205D004F118038F -:104020002246F7E7022010BD0B69834219BF816960 -:10403000916182690A6105F0F5FD002010BD00BFA5 -:10404000AC22002010B50C4A12688AB1FF2911D0A9 -:1040500013788B420ED854781C448C420AD9C91A62 -:10406000C01A5268C9B2C0B2515C105C884201D11A -:10407000002010BD012010BD6088002009490848BB -:1040800089680088D1F8D420D084074800220270C3 -:10409000D1F8D4000549C08C48860549C8817047CD -:1040A000467300200C010020AE880020E87F00202D -:1040B000E886002009480A49C0680A7B406802F087 -:1040C000F002033200780A73064A12785043064A17 -:1040D0001278504380008860704700BF0C010020B8 -:1040E000A8850020B0880020B688002010B50B4CB1 -:1040F000207830B101280AD0022803D1F8F743FA1A -:1041000005E010BD06488068D0F84C0580470020C7 -:104110002070BDE8104004F081BE00BFA027002041 -:104120000C010020B0B5044605F008FA054602204F -:104130000021F7F7BDF808490648224609680068DB -:104140008B694FF0FF3198472846BDE8B04005F035 -:10415000A1BC00BFD826002030880020F8B505F0AB -:10416000EDF9044608480068C06B804705460748DB -:10417000067807480768204605F08CFCE81BB1006C -:10418000B0FBF1F0F8BD00BF30880020B0880020FF -:104190002C8800200C4800224FF470038168D1F86D -:1041A000D8100A608168D1F8DC100A608168D1F803 -:1041B000E0100B608168D1F8E4100B608068D0F8E3 -:1041C000E8000260704700BF0C01002080B50B487A -:1041D00081890131818105F0B1F909490A78862A7E -:1041E00008D187220A7005F055FCE920BDE880401F -:1041F000EEF772BABDE8804005F04CBC4486002062 -:10420000B488002080B50948012101700848406841 -:1042100018B10848818901318181F02000F048FC03 -:1042200005480078BDE88040E5F71ABF2126002048 -:10423000A885002094860020B7880020F0B585B0BE -:104240000B4C246884B1256A75B1DDE90C6CDDE99D -:104250000A470004049100210130CDE90047CDE96F -:10426000026C0024A84700B10A24204605B0F0BD26 -:104270005C270020F0B589B005AD0C460146102240 -:104280001027284605F054F901AE304605F026F90E -:1042900005483146CDE90347CDE90154006805F0F2 -:1042A000EDFB09B0F0BD00BFF887002010B590F815 -:1042B000480088B12020EFF3118480F3118807486B -:1042C00041690139416105D1054884F31188016ACA -:1042D0000020884784F3118810BD00BF38220020D9 -:1042E000381F002080B568B101460068D1E901237C -:1042F00048B111461A4604F029FB0648BDE8804043 -:1043000004F024BB80BD04480021BDE8804004F0D7 -:104310001DBB00BFA2A20200A4A2020070B50B4602 -:104320000B490025312D11D031F835602C4601356F -:104330008642F7D101EBC4004188994206D140681A -:1043400011461A46BDE8704004F022BF70BD00BFA0 -:1043500010AA020070B50948094C84420BD0094DDF -:10436000094EB54207D0F5E8020110F8012B54F8C8 -:1043700022209047F5E705F07DFC70BD9CC002004F -:1043800090C00200E4C0020034C1020083B0029079 -:10439000002001918DF8030082420BD00299095C44 -:1043A000019B1B5C013059409DF8033019438DF887 -:1043B0000310F1E79DF80300B0FA80F0400903B064 -:1043C00070472DE9F041804610461E4617460D46BF -:1043D00002F04AFE70B104462FB126B120463146A4 -:1043E0003A4604F0D5FE257040462146BDE8F0412E -:1043F000FAF75ABEBDE8F08170B5B0B14279A2B10A -:10440000831D14461D4662B11E888E4204D1013CB4 -:104410002606447102D108E025F8026B0233013A06 -:10442000F1E720061CBF012070BD002070BD000018 -:1044300010B5017840786424012808BF632429B1AD -:10444000052004F0F5FE201AA0F10D040448007BBD -:1044500020B104F0EDFE201AA0F10E04E0B210BD70 -:10446000407B00200549064A0A6006490870064854 -:10447000064901600648074901607047F42600209C -:1044800015F900003C260020F02600208974010068 -:10449000F826002011900200B0B505460C2002F06D -:1044A000E3FD80B104460620696808222070288850 -:1044B0006080201D04F06CFE034821460078BDE8B2 -:1044C000B040FAF7F1BDB0BD99880020B0B50648FC -:1044D000084B0649084C064A084DC0E90152C0E99C -:1044E00003414361B0BD00BF50240020C19B0200C6 -:1044F000F1E50100A99400006163000049CC0100CE -:10450000B0B50648084B0649084C064A084DC0E9B4 -:104510000152C0E903414361B0BD00BF50240020F7 -:10452000C19B0200F1E50100A99400006163000055 -:10453000B17D0200B0B50648084B0649084C064A52 -:10454000084DC0E90152C0E903414361B0BD00BF5D -:1045500050240020C19B0200F1E50100A994000055 -:1045600061630000716C0100B0B5054602F0FCF813 -:10457000044601280ED10848A9892B78406801EB30 -:10458000410110F821209A4300F8212000EB81001E -:1045900004F0AAFF2046B0BD34260020F8B5094833 -:1045A0000A4D0027067808480488BE4208BFF8BDB7 -:1045B000B9B2022022462B4601F002FF0E35013728 -:1045C000F3E700BFE2BC0200C2B40200188700207B -:1045D000E0B50A48007801280FD80120F7F7C4FC9D -:1045E0000749ADF80600C8820DF106015320FDF71A -:1045F00045FDBDF80600FCF791F98CBD182600209A -:10460000407B002010B504460948807B000707D492 -:104610000648006820B1074808210078F9F718FD1E -:104620002046BDE81040EFF7D0BE00BF4424002074 -:10463000407B002095880020F8B50A4E054605F01D -:1046400086F9044608482A46002375800027D0E9E9 -:10465000011004F0F0FE00B17780204605F053FA17 -:104660007088F8BD6426002048230020B0B50C46B1 -:1046700000210546224603F0CDFC0748007800B132 -:10468000B0BD7C2C04BF0548C570044905EB45004E -:1046900001EB80008475B0BDA0230020A080002025 -:1046A000F8B50B4F044600266D463978F0B28842C3 -:1046B0000AD200212A46042304F032FD9DF80000AE -:1046C000A04202D00136F0E7FF26F0B2F8BD00BFED -:1046D00097880020F8B505F03AF90A4E0446756847 -:1046E0005DB145B128682F6904F010FF284605F038 -:1046F00099FA3D46F5E7002070602046BDE8F84095 -:1047000005F001BA6C26002070B50A4C03462078EB -:104710000E280CD8084E00EB400506F8350006EBD5 -:10472000C5056A610022E9602A74C5E90132411CAD -:10473000217070BD44250020B46E002008490A4B4A -:10474000421808499A42096808D801F44001B1F5B5 -:10475000000F03D105490968496C0847704700BF3D -:104760005C8F82FFB44F0050B71E0500F0010010AF -:1047700070B50B4D04462E1804F0E0FE96F8431178 -:10478000013986F84311090605D10121AA68A14023 -:1047900022EA0101A96005F07DF9002070BD00BF8B -:1047A000D81B0020B0B5054604F0C8FE04460848F2 -:1047B0000178A94301700078000704D40548082156 -:1047C000283005F047FA2046BDE8B04005F062B950 -:1047D000D01E002070200020F8B515460E46074672 -:1047E00004F0ACFE044608484068B84201D00325F6 -:1047F00004E03046294601F00DFB0546204605F051 -:1048000049F92846F8BD00BFD01E0020B0B50A4ABD -:10481000931C0A4A14780022944209D01D888542CC -:1048200003D113F8025C8D4203D00A330132F3E75F -:104830002246D0B2B0BD00BFD07E0020D9BC02005D -:1048400010B586B08AB19368062B03D35C1C01D0E7 -:1048500000200DE0002404930194D2E90034D268D2 -:10486000CDE90234059201AA00E0002204F03EF8EE -:1048700006B010BD2DE9F04106460A4815460C4623 -:1048800000278046BC4209D0D8F80020E95D306896 -:104890009269904708B10137F4E73C462046BDE8ED -:1048A000F08100BFD001001080B5094800780228CF -:1048B00002D24CF2101107E008D10120F9F78AF872 -:1048C0000449002808BF01310348018080BD00BFB2 -:1048D000182600202182FFFFFC8700201CB582697A -:1048E000094913785278098943EA022211400AD013 -:1048F000064A047C1388427CCDE90014811C1046D2 -:10490000002200F05BFE1CBD26870020708700207F -:1049100010B50B4B0C0A5B68597000219C70197024 -:104920001178D970517800F111021971811C10466B -:1049300048F203020523BDE81040FAF76DBD00BF41 -:104940007C2600201FB5044600208DF80000684634 -:104950002146043005F013F904F062FB00B11FBDDD -:104960006846F6F781FE0128F9D00DF10E0200200D -:10497000214601F015FB1FBD10B50A490122087A36 -:104980000A7209494C6944B122684A61FEF742FF44 -:104990002046BDE8104001F05BBBBDE81040FEF7CB -:1049A00039BF00BF38220020A01F002080B50B4A6D -:1049B0000146106878B143681B788B4205D00246E7 -:1049C00000680028F7D1022080BD0168116005F061 -:1049D00029F9002080BD012080BD00BF2088002073 -:1049E00010B5A1F1FE020A4BB2FA82F254091B681B -:1049F00053B1DA888242FAD11A79240605D1521AC3 -:104A0000B2FA82F25409F2E7FE22104610BD00BF4E -:104A1000EC26002070B586B001AC1421FF222046A0 -:104A200004F04CFA074800260578AE4224BF06B0D1 -:104A300070BDF1B208201422234601F0C1FC0136FA -:104A4000F3E700BFCDBC02001FB5014604208DF87E -:104A50000000087A022806D10888ADF802006846EE -:104A6000F4F778FA06E06C46201D04F058FC204666 -:104A7000F6F7FAFDBDF80C0004B010BD0849094A6C -:104A8000096852F82130034442F8213006498A6807 -:104A900001328A6005490A6810440860EFF75ABD80 -:104AA0001488002048810020B82400201C880020A1 -:104AB0007CB504461630C0B2092810D8084EB0683C -:104AC000D0F8282401AD2046294690470198294670 -:104AD00001300190B068D0F83024204690477CBD6A -:104AE0000C01002010B50B4CE0688169097802299F -:104AF00007D1C168097821B1A068D0F84C0580477A -:104B0000E068C168097819B9806901780229FCD088 -:104B100010BD00BF0C010020094800210122C18105 -:104B20004175084942820978017507498968D1F8B9 -:104B3000D41091F8242091F8311001744274704718 -:104B4000A0830020B58800200C01002010B50A4881 -:104B5000FE210A4C4170A068D0F8E800006848B116 -:104B6000E0680121C068017003F0CEFBE06800211D -:104B7000C068017010BD00BF142500200C0100208A -:104B800080B50A480021017001F03EFBF7F73CFBBD -:104B90000748C168C968097801B180BD80680021F3 -:104BA000D0F858240020BDE880401047AD88002090 -:104BB0000C01002007480849084AC0E904210849B7 -:104BC000084AC0E9082140F20551C183F721C173A9 -:104BD000704700BFE87F0020F8860020C0870020D3 -:104BE00008850020E081002070B50B4C094B022A9B -:104BF000254608BF1D4601262D6806FA00F009B1BA -:104C0000284301E025EA0000022A14BF2060186052 -:104C100070BD00BF08850020E081002010B50B4C5E -:104C2000E068C068007828B9A0680021D0F858244E -:104C30000120904704F082FC04F02CFFA068D0F81B -:104C4000B800806EBDE81040004700BF0C01002096 -:104C5000B0B50D460446FFF781FAA84205D30848CF -:104C60008068D0F8E0000068054405486560806809 -:104C7000D0F8DC10D0F8EC242046BDE8B040104756 -:104C80000C01002010B50B4CA268D2F8E030D2F82D -:104C9000EC2052F821101960A268D2F8E4201160CB -:104CA000FEF76EFCA068D0F8E0000068BDE8104098 -:104CB00002F0C0BB0C01002010B58EB00C4691B1C3 -:104CC000014601AA2046ECF7F9F99DF80A0050B117 -:104CD0009DF805209DF820300020214603F00AFAB7 -:104CE00008B1A42000E000200EB010BDB0B502460F -:104CF00009484FF6FF740378084801E01C30013B77 -:104D000043B105889542F9D145898D4218BFA1422A -:104D1000F4D1B0BD0020B0BDD5BC0200DC5B0020EA -:104D2000B0B50146094800234FF6FE7402780848E2 -:104D30004AB10588A54203D0DDB28D4204D00133CB -:104D40001C30013AF4E70020B0BD00BFD5BC020022 -:104D5000DC5B0020F8B50D460A490446084809788E -:104D600002304E1C013E09D0294600F11C0702F01A -:104D70009CFC00283846F5D027F81E4CF8BD00BF33 -:104D8000DC5B0020D5BC020080B5042000F066FD8D -:104D900008490978884284BF012080BDFF2000F0C7 -:104DA0005DFD0146044802780020914288BF012041 -:104DB00080BD00BFE3BC0200E4BC020080B540F24D -:104DC000011000F08DFF02F0C3FD0748007808B124 -:104DD000012807D105480078012803D1BDE88040AB -:104DE000FAF736B980BD00BF18260020BA27002088 -:104DF000B0B50B4A0023156C946CC0E901452A78C4 -:104E000041B1BE2A06D1691C631C11F8014B013B5C -:104E1000BE2CFAD00360B2F1BE0018BF0120B0BDB5 -:104E2000381F00200B4890F8641001B17047012131 -:104E300080F864102021EFF3118281F311884FF084 -:104E4000FF31C162016C826C21F007011144083905 -:104E5000C1637047381F0020B0B50446826081618D -:104E600000201D462075D3E9010120610648E1615B -:104E7000214603F0C7FA287820B12046BDE8B040AB -:104E800003F02FBEB0BD00BF0820002070B50B4A54 -:104E9000D368C56C84696E682343056046603060E2 -:104EA0006860D360012380F820301374202081F3E0 -:104EB0001188EFF3118180F3118870BD3822002032 -:104EC000BFB50A4C1C34A04208BFBFBD01AC0028CE -:104ED000089D18BF0446064884E82C0050F82100BD -:104EE00003F034FD2046FFF7FDF9FEE7A01F002088 -:104EF00074BC02000A48083880F308880948016831 -:104F000041F47001016000BF00BF04F0B5FE08B1BC -:104F1000FFF720FA03F01EFF002004F0A2FD00BFFF -:104F20000040012088ED00E0B0B5A0B10546007A50 -:104F300000F0FE0002280ED128461446F3F732FC9A -:104F4000FF2808D02A7A002C18BF0124214600F03F -:104F500025FC0020B0BDE820B0BD10B52021EFF346 -:104F6000118481F31188017C02290CD102688168C7 -:104F700043681A6000220274426800684260084672 -:104F80002146FFF783FF84F3118810BD1CB5ADF8EF -:104F9000061009490C6864B10DF106010091114633 -:104FA0001A460123A0470021002808BF6FF04D01D9 -:104FB00000E0B621C8B21CBDF023002070B54E8BB6 -:104FC0000C46054604F0F0FA864203D02846FAF76C -:104FD00053FD30B104482146C2682846BDE8704000 -:104FE0001047012070BD00BF50240020B0B50C4612 -:104FF000054603F005FE0146284602F056FB20B1A7 -:105000000548C08A20800120B0BD28462146BDE861 -:10501000B04000F0FABC00BF407B002010B5F8F7AC -:10502000EBF905480549064A064B074CC0E9014320 -:10503000C0E9032110BD00BF2C24002055D1000081 -:10504000ED73010051610100253A02007FB54FF078 -:10505000FF30094E00250390CDE9010001AC3088F6 -:10506000854228BF7FBDA9B201200C22234601F052 -:10507000A7F90135F3E700BF342600207FB54FF0D4 -:10508000FF3000266C46CDE90200CDE9000006485D -:105090000578AE4228BF7FBDF1B20320102223461F -:1050A00001F08EF90136F4E7E6BC020080B508484D -:1050B00090F8281001B180BD012180F8281004F07B -:1050C00099FB04480021FEF74BFB0349486080BD73 -:1050D000381F00207C840020A01F002080B50A49D2 -:1050E000142004F0D4FC1420002103F0B1FF0120AF -:1050F00004F07BFC1420012103F0AAFF4FF40C7094 -:10510000BDE8804004F071BC01640020BFB50446D6 -:1051100053B100200190D3E901051B7803958DF868 -:105120000430029001AB00E0034B2046FFF794FEF1 -:10513000204604B0B0BD00BFDCBB0200FF2808BFA2 -:105140007047B0B50D46044604F0F8F90649C5F3BA -:10515000024311F8242002F0F8021A4401F8242036 -:10516000BDE8B04004F096BC0210084010B50146FE -:1051700008480023027808484AB10478FF2C03D07D -:10518000DCB28C4204D00133013A0E30F4E7002047 -:1051900010BD00BFE2BC02001887002080B50346A6 -:1051A0000848007858B908481978007801B908B952 -:1051B00029B120B94520CB210122FDF75FFA00205B -:1051C00080BD00BF95270020F4240020BFB5044611 -:1051D000082234F8020BADF8040001AD2146A81CEA -:1051E00003F0D6FF2089CA210C222B46ADF80E0011 -:1051F0004520FDF743FA002004B0B0BDB0B50D4620 -:10520000044604F03EFC80B101790139C9B203299A -:105210000BD8012D18BF012902D8008804F00EFD1B -:105220002046BDE8B040F9F737BEB0BDBCB5044676 -:1052300005200D468DF8050001A801F021FB58B1AD -:105240000169220ACA7041F203320D718C700A8022 -:105250004480F9F743FBBCBD0120BCBD10B504F090 -:1052600076FB0446074800212022002301800649DE -:1052700088680C3102F0D5F92046BDE8104004F0F2 -:1052800042BC00BF642600204823002010B504461D -:1052900001F0A2FEA0420BDDA0B2FAF7F1FA054838 -:1052A0000121817104480068BDE81040F9F710B988 -:1052B000FEE700BF342500204C880020F8B50A4FD7 -:1052C00006460D464FF0FF311446386804F058FB8F -:1052D000304629462246F4F703FF0446386804F0B6 -:1052E000B5FC2046F8BD00BFDC250020F8B50A4F0C -:1052F00006460D464FF0FF311446386804F040FB77 -:10530000304629462246EDF747FE0446386804F049 -:105310009DFC2046F8BD00BF0C24002070B5094A52 -:105320001378322B04BF012070BD074E046803EBD5 -:10533000C305406801331370721974515060002026 -:10534000117270BD8E270020186A002010B586B03B -:105350006C461621A01C03F0B7FD02208DF8080052 -:105360000548418B808CADF80A002046ADF800104E -:10537000FEF752F806B010BD407B002070B5144611 -:105380000D46064604F0E3FA3168A94218BFA4F1BD -:105390000C0655F80C1C3160FF2105F8021C002199 -:1053A00045F80C1CBDE8704004F0ADBBB0B5044638 -:1053B000012000FA04F504F0C1F807498A682A437D -:1053C0008A60214491F84321013281F8432104F09D -:1053D00061FB0020B0BD00BFD81B00200A48406818 -:1053E000826800F13801134652680AB18A42FAD144 -:1053F000597B090706D1408F40F60901884204BF56 -:105400000120704700207047D01E002010B550B911 -:105410000020F6F7A9FD04464FF6FE70844206D13F -:105420000548007818B10020F6F79EFD0446EFF716 -:1054300019FA204610BD00BFE7BC020010B50A4BA8 -:105440000749084A1B780439013A43B112F8014F61 -:10545000013B04318442F8D100200860107010BD77 -:10546000C87A002040840020D2BC0200B0B51446A7 -:105470000D46F7F7F1FC07490978884224BF04205C -:10548000B0BD054901EBC00041782970406820603B -:105490000020B0BD9ABC0200E0270020E0B5B0F9C2 -:1054A0000E10002901D4027B02B18CBD89B21329F0 -:1054B000FBD0037C427C41F40041CDE90013811C08 -:1054C00010468422002301F07BFA8CBD09498A78BA -:1054D000920703D5084A1278824200D170470C2007 -:1054E0008870088840F0020020F0050008800C2039 -:1054F00002F074BD26870020D8270020B0B5094CE3 -:10550000E17809B1C17801B1B0BD40780028FBD184 -:1055100005480025A0F870500120F5F77DFFE570E3 -:10552000B0BD00BFCC240020407B0020B0B5856911 -:105530000C460421284600F0F1FF20602879052858 -:10554000207102D868796071B0BDFE2805D36979F1 -:10555000FF28A17104BFE8882081B0BD80B508494B -:105560000870084909780843000602D1062002F0B5 -:10557000BFFA054820210078BDE88040F8F768BDF3 -:10558000BB880020C4260020998800201FB50A4B44 -:10559000ADF804005C68A170010A20700220E2707E -:1055A00001228DF80C006170184601A90423F9F757 -:1055B00033FF04B010BD00BF7C260020BCB50A4CF0 -:1055C0008DF807000DF1070063681A70069A150A36 -:1055D0005A7010229D70A27048F215020323F9F749 -:1055E0001BFF0021A170BCBD7C26002010B500224D -:1055F0000A60094A12686AB16FF017039C1D09D04E -:1056000013441B8B83422346F8D1101912300860D3 -:10561000002010BDC82010BDE0260020B0B588B025 -:1056200004AD044669461022284603F07BFF064875 -:105630002946006804F014FB05992046102203F067 -:10564000A7FD08B0B0BD00BFF087002070B50546CB -:10565000142016460C4604F0E7FA58B10649012317 -:105660000661846083734FF499730A688381C0E98B -:105670000025086070BD00BF208800200749087021 -:105680000749097831B9074991F82F1011B1064936 -:1056900002220A7048F20201FBF78CB99F880020B1 -:1056A00018260020AC220020AC27002070B50A4E3E -:1056B000084C0025042130782570F9F799F93078E5 -:1056C0000421F7F7FDFE84F82B500020BDE8704060 -:1056D000E3F7C6BFAC2200209F8800207CB50A4EAD -:1056E000044606208DF807002046318903F003FCAC -:1056F0000DF107000121FAF767FA318905462046C6 -:1057000003F002FC28467CBD0C24002080B50A482A -:1057100042F204414088884206D042F20341884266 -:105720000CBF0020E92003E0012000F099FD1B20C0 -:10573000BDE88040ECF7D0BF3086002010B50A4AA3 -:1057400012687AB1137883420CD854781C4484428E -:1057500008D9C01A526891F90040C0B2105684426C -:10576000C8BF087010BD00BF6088002078B110B5B8 -:105770000169074C206029B906488068D0F84C05BB -:1057800080472068406804490860BDE810407047C1 -:105790005C8800200C0100203088002010B50A4CE5 -:1057A000084B0434022A08BF1C1D2268012303FA97 -:1057B00000F0002922EA000318BF42EA0003236038 -:1057C00010BD00BF08850020E081002080B503F0F7 -:1057D000B5FE08490A7842F002020A7004F05AF94C -:1057E000054800218068D0F894000078BDE880402A -:1057F000F8F72EBC8C8800200C01002008480021FE -:105800000170084801700848C168C968097801B189 -:10581000704780680021D0F858240020104700BF4E -:10582000B4880020212600200C010020B0B50446D9 -:105830000948056855B1A868204205D0D5E903326A -:1058400020460021984718B92D68F3E70020B0BD25 -:105850004FF0FF30B0BD00BFD81B002010B5A0F145 -:10586000FF02094B0021B2FA82F252091B6843B1D0 -:105870005C7B0433241AB4FA84F46409144321448D -:10588000F4E7C8B210BD00BF54880020F8B580B15D -:10589000054609480C4600260168374651B10E46B8 -:1058A00008462146A84700210128F6D0301D3E4673 -:1058B000F2E700273846F8BD54880020F8B5094DB6 -:1058C000094E2C685CB1D4E90007006AB047206833 -:1058D000B0476069B0472046B0473C46F2E7002039 -:1058E0002860F8BD54880020259C020010B50A4AA3 -:1058F00000F11C01007C0023927883420AD2140636 -:1059000008D011F8334004F08D04812C08BF013A0F -:105910000133F2E7D0B210BD4426002010B50A4A88 -:1059200000F11C01007C0023527883420AD2140645 -:1059300008D011F8334004F00D04012C08BF013ADF -:105940000133F2E7D0B210BD442600207FB51346E4 -:10595000D0E90A24BE251AB104F8015B013AFAE73E -:10596000D0E90A54D0E90D26C06BCDE900160290AB -:10597000291F2046F8F7F6F804B070BD10B50A4BA1 -:105980002022EFF3118182F311889A6B002A04DC44 -:105990005C6B44F82200501C9863002081F311884E -:1059A000012AB8BF012010BDA01F002070B50A4D0C -:1059B00004462020EFF3118180F31188A86B461E66 -:1059C000701C0128B8BF70BD686B50F826102046C7 -:1059D0008847013EF4E700BFA01F00207FB56D4659 -:1059E000ADF8020000260C4628468DF80060F3F75B -:1059F000B1FA291D07BF66602660204604F0BFF893 -:105A0000204602F0F3F904B070BDBFB50C46014664 -:105A100000206D468DF80000281D03F080FC28460C -:105A2000F5F722FEBDF802004FF6FE712080401A05 -:105A300018BF012004B0B0BDBFB5044600880DF109 -:105A4000050508226168ADF80500A81C03F0A0FB5D -:105A5000217A0B222B4601704520C821FCF70EFE4F -:105A6000002004B0B0BD10B504460E2004F0DCF8F0 -:105A700078B1A16BD4F83E200160426094F84210E6 -:105A8000017294F84A1001736188418194F84910B9 -:105A9000417310BD80B541F21830C5F200000068B6 -:105AA0004FF20001C0F6FF71084041F20001C0F65C -:105AB000B431884204D1FAF783F91328C8BF80BDF6 -:105AC000FEE7B0B50C460546F9F758FF291A04F56C -:105AD0007A72C4EB9100012898BF01200023B2EB39 -:105AE000910F28BF1846B1F1404F28BF1846B0BDEE -:105AF000B0B50C46054603F021FDD5E901122B692E -:105B0000A24238BF1446121BAA601A19B2FBF1F365 -:105B100003FB1121296103F0BDFF2046B0BDF8B59C -:105B20000C46054603F00AFDEA6895E8C20001321A -:105B3000B2FBF6F303FB16252944216003F0AAFF0C -:105B4000701BF11B814238BF0846F8BDF0B54FF01D -:105B5000000C844504BF0020F0BD1D4616464EB122 -:105B600031F81C7035F8024B013EA74204BF0120FA -:105B7000F0BDF4E70CF1010CEBE770B514460E46EE -:105B8000054603F011FD03F00FFD0B2E0CBFA842DC -:105B900070BD2046002101F03FF9204600211E2261 -:105BA000BDE87040E8F7B4BD70B5044608460D4640 -:105BB00002F024FE30B182683AB101202946012664 -:105BC000904705E00026266003E0406800268068D4 -:105BD0002060304670BD2DE9F0414FF6FE780C464E -:105BE000054608F1010728462146FFF77FF838B13E -:105BF0001C21064603F068F97781A6F80080F2E7D9 -:105C0000BDE8F08140B10246074800210170074815 -:105C10000221007803F06EBF0348012101700348A0 -:105C200002210078F8F7E4BE2C240020958800209B -:105C300080B5AB2807D0A1281CBFB52080BD108837 -:105C40000549088004E003481146006803F097FF07 -:105C5000002080BDDC8700202E7E002010B5044689 -:105C6000062001F001FA60B1014608200870208882 -:105C70004880A078087103480078BDE81040F9F723 -:105C800013BA10BD99880020B0B50848084C0578B3 -:105C900005EB45004100204603F016F94FF6FE7073 -:105CA0001DB124F8060B013DFAE7B0BD9127002095 -:105CB0004C6D002038B10246074841610748012178 -:105CC000007803F017BF0448002141610348012117 -:105CD0000078F8F78DBE00BF2C24002095880020A6 -:105CE000B0B5094D288060B100EB4000800084B25F -:105CF000204603F099FF686028B1214603F0E4F8DC -:105D0000B0BD00206860B0BD342600200949837909 -:105D1000CA7A2BB15AB98078B0FA80F0400970473E -:105D20002AB1C98A4089401A18BF01207047002053 -:105D3000704700BF407B0020B0B50546084800789A -:105D4000012888BFB0BD28460C46F1F7CDFC4FF6C0 -:105D5000FD7029460D222346BDE8B040F5F7B0BFDF -:105D600018260020084800F1180108480278002091 -:105D7000824205D00B78FE2B03D00C310130F7E7BF -:105D80001046C0B2704700BFA08000209788002056 -:105D90001CB56FF0D24401948DF806100421ADF8C3 -:105DA000042001AA01EB8301042389B2FDF76EFFF1 -:105DB000014908701CBD00BFA0230020B0B50748F2 -:105DC000074D04782CB155F80C0B00698047013C55 -:105DD000F8E7044801210170B0BD00BFF3BA02002A -:105DE000A0B902009B27002006480122017A027216 -:105DF00005480160054890F8481080F8482004489C -:105E00000160704738220020EC870020A01F00208E -:105E1000E887002010B50C460849097E02290AD1FE -:105E200001F046FD04B12060C1B20220012908BF83 -:105E30006FF07E0000E00120C0B210BDD01E002037 -:105E400010B50848084900224FF6FE730024007878 -:105E5000844228BF10BD8A718A804B8021F8083B9C -:105E60000134F5E7DABC0200E04C002010B5074829 -:105E7000002403210460064801600220FEF778FC3C -:105E80000720EFF7E3FC0348447010BDA80250421E -:105E90001080024018230020F8B50C46D0E9001607 -:105EA000002701F14C053068013C47F1000182698F -:105EB000D20606D429B10068C1B22846FBF7CEFD50 -:105EC000F1E7F8BDD0E900100A6C5AB191F844101E -:105ED000090707D501684FF480624A648A6B42F46F -:105EE00080628A630068816B41F040018163704782 -:105EF000FEB5074609981C4615460E46FFF7E6FA1A -:105F0000054831463A4683780898CDE9004028464E -:105F1000EDF734FBFEBD00BF2687002010B5044618 -:105F2000062001F0A1F858B1014631200870206820 -:105F3000C1F8020003480078BDE81040F9F7B4B892 -:105F400010BD00BFCC240020F8B5094F06461C4602 -:105F50001546786803F0D1FD447005703846314627 -:105F60003022062301B0BDE8F040F9F755BA00BF72 -:105F70007C2600204FF6FE73984218BF002901D1FD -:105F8000012070479A42FBD0F8B5ADF80C20029181 -:105F9000ADF8040001A8F1F79DF8002004B080BD21 -:105FA000BFB5ADF8020002206D4614468DF8000022 -:105FB000281D03F0B4F92846EBF7D0FCBDF80C100F -:105FC0000138218018BFC82004B0B0BD80B502F0F0 -:105FD000B5FB08480078012807D00028BDE88040BC -:105FE00018BFFEF78DBAFEF771BABDE88040FEF724 -:105FF000A1BA00BF1826002010B50446EBF724FD17 -:106000002046FCF7FBFC2046EFF73AFE04480078F8 -:1060100000B110BD2046BDE8104000F0FDBA00BF41 -:106020001826002080B5E22806D1084A0846114605 -:1060300003F0A5FD002080BD034A9268D2F8282411 -:10604000BDE88040104700BF0C0100209E87002063 -:1060500010B50446103001F06BFA204650F80C1FC2 -:1060600009B101F085FE044821465022406843688A -:10607000BDE81040184700BFA01F002018B1052040 -:106080000121DEF787BB0748417831B1016A21B1B0 -:10609000002141700020F8F7BFBD05200021DEF788 -:1060A00079BB00BFAC22002010B5084900220B7854 -:1060B0000749934205D00C78FF2C04D00E310132F1 -:1060C000F7E70021FF220270084610BDE2BC020083 -:1060D00018870020094908480A780530002142B194 -:1060E00010F8053CFF2B1CBF037819440E30013A11 -:1060F000F5E788B2704700BF18870020E2BC0200B5 -:106100007FB5ADF80C0004206E460C468DF80000FB -:106110003046F9F7F9FE054628B10320311D2072FB -:10612000204603F02CFD284604B070BD10B5084C85 -:10613000A16829B1074909680844EEF70BFA08B1CC -:10614000012010BDE068013038BFE060002010BDC4 -:10615000B82400201C880020084A002800F0010113 -:1061600018BF0120138843EAC01010800448028B36 -:1061700022F0800242EAC11101837047E8860020C4 -:10618000E87F0020B0B5044603F0D8F9054600F0DA -:106190003BF8054844860548C481284603F07AFC4C -:1061A000BDE8B04002F03ABEE87F0020E88600205B -:1061B00010B5084C0121E068C06801700648FE2156 -:1061C0000170F6F759F801F011F9E0680021C06894 -:1061D000017010BD0C0100201425002010B5074CE3 -:1061E0006078FE2809D006480068826B0548006880 -:1061F00094F901109047FE20607010BD1425002016 -:1062000030880020D826002080B508488068D0F863 -:10621000B8000078B0FA80F04009FDF783FF044829 -:10622000017811B101780139017080BD0C010020A5 -:106230001B25002010B5044620B907488068D0F817 -:106240004C05804703F07AF904490A78A2430A70A2 -:10625000BDE8104003F01EBC0C010020AD880020FA -:1062600010B5044620B907488068D0F84C0580472F -:1062700003F064F904490A7822430A70BDE810402B -:1062800003F008BC0C010020AD880020B0B5054625 -:1062900008488068D0F8D84003F050F924680CB161 -:1062A000AC42FBD103F0F6FB002C18BF01242046C2 -:1062B000B0BD00BF0C01002008480178832918BF39 -:1062C000704707490978032902D10020EFF79CB8ED -:1062D000852101701D20ECF7FFB900BFB4880020B4 -:1062E000B788002010B504460848006820B101882E -:1062F000A1420AD00430F8E7082003F095FC20B151 -:10630000024904800A680860426010BD40270020EE -:1063100098B110B5044600F011F82068006A03F047 -:1063200081FC206803F07EFC606908B103F07AFC10 -:106330002046BDE8104003F075BC7047094B0021B2 -:106340001A6852B1824202D0131D1146F8E7054A7D -:106350001368834202D0406848607047406810600C -:10636000704700BF5488002010B50848084A4FF60F -:10637000FE730178002031B132F81C4B9C4218BFEB -:1063800001300139F7E780B210BD00BFD5BC020073 -:10639000DC5B0020BCB5094C246864B1E46954B1ED -:1063A0000004069D01300095A04701460020012908 -:1063B00008BF0A20BCBD0A20BCBD00BF5C2700206E -:1063C00010B5094C24686CB164695CB100040130FB -:1063D000A04701460A200A2908BF0920002908BF52 -:1063E000084610BD002010BD5C270020B0B5044653 -:1063F00002F058FA074D2978884202D36868FBF703 -:106400002BFFE87820710130E870204601F036F863 -:106410002079B0BD4426002010B52020EFF3118470 -:1064200080F3118805480068006B8047044AD2E970 -:10643000102384F3118802F04BFD10BD8C01001075 -:10644000207C002070B504462020EFF3118580F3F6 -:106450001188207D40B1E668FFF7DEFF216A301A1F -:10646000884288BF002000E0002085F3118870BDBD -:106470004A1C08BF05212022EFF3118382F3118803 -:1064800001228A40C0E90812034AD26D02EBC10121 -:10649000416383F311887047A01F002000B170474B -:1064A00010B5074C207C28B1064890F8480008B980 -:1064B000FBF7B0FA00202072BDE81040704700BF23 -:1064C00038220020A01F002080B540F2E010C1F269 -:1064D00000000068012142680120904742F230002C -:1064E000C4F20900006848F2D071C2F200010860ED -:1064F00080BD7178CDF8248006940797CDF80CB054 -:1065000002900D208DF8280000988DF82900307831 -:10651000584408444946CDE904007047013903292D -:1065200084BF4FF0FE307047DFE801F0020B040932 -:10653000007870478178008840EA01407047006821 -:10654000704700887047F8B5466804460027D6F8BB -:10655000C85065B1696968686F61C6F8C81000F015 -:106560009FFFD6F8BC20204629469047EFE7F8BDAC -:1065700081B14A6872B10A78042A0BD18A684AB19B -:1065800002680023916153624B68D361896891620C -:10659000EAF78CBE6FF002007047B0B505680220C4 -:1065A0000C46FEF7E5F864B1D5F8EC000021B1EB3C -:1065B000107F06D10420FEF7DBF84FF0FF30C5F85E -:1065C000EC00B0BDF8B50DF10E0100F010F860B9A7 -:1065D00002208DF80000BDF80E00ADF80C006846F2 -:1065E000FDF7C2FF013818BF012004B080BDBFB560 -:1065F0000C46014602206D468DF80000281D02F071 -:106600008EFE2846F5F730F8BDF80C1001382180D1 -:1066100018BFC82004B0B0BDBFB56D4604462846BB -:10662000FEF7FCFF40F2011010212A4603F0E8F8C3 -:1066300034B128B96A4640F20110102103F0E6F89F -:10664000BFBDCA071CBF012202704A0744BF012216 -:106650004270CA0644BF0122C2708A0644BF0122AA -:106660000271C90544BF0121C171704710F1140FB7 -:10667000A8BF6FF0130045F6A61110F15A0F98BF8E -:106680006FF05900C0EB00200844462180B2B0FBF7 -:10669000F1F0C0B27047B0B50C46054600F0BCFA48 -:1066A00068B100F11B01007C0022824207D211F880 -:1066B0003230AB4208BF01F832400132F5E7B0BDDD -:1066C00070B50446006C04F144052CCDA0FB010616 -:1066D00002FB0161C6184D41300C002240EA054121 -:1066E000FDF720F8C4E9146570BD81B040F2000CDC -:1066F000EFF311808CF3118800200090009810B9FE -:1067000000980130F9E72020EFF3118180F3118820 -:1067100001B07047E0B500200DF1070201218DF8AE -:106720000700032003F06CF830B90DF107030320D4 -:106730000021012202F0AEFB9DF807008CBD000095 -:1067400010B5084B1B6853B1DC79844205D19C8895 -:106750008C4202D19C79944201D00C33F2E7184666 -:1067600010BD00BF54650020084980890A88904206 -:1067700024BF00207047496800EB400011F820005A -:1067800010F00F0018BF0120704700BF3426002012 -:106790000849486809880131013904BF0120704760 -:1067A00000F10C0200780007104604BF002070477B -:1067B000F2E700BF34260020014607480278074868 -:1067C00042B10379042B02D80B0404D00139013AF9 -:1067D0002430F5E700207047E6BC0200B0540020EA -:1067E00080B50648006938B1054802F0A3FF0548A6 -:1067F000BDE8804002F0A4BF80BD00BF381F00206C -:10680000357F0200BD850200B0B50D46044602F09A -:1068100095FED5E9001211B14A606A6800E0626035 -:10682000002A18BF14462160BDE8B04003F032B919 -:106830001CB500200DF10204064905228DF8020066 -:10684000601C02F0A5FC4120802106222346FBF7B4 -:1068500015FF1CBD00BC02001CB50446042001F05D -:10686000B5FF20780DF10303C62105228DF8030042 -:10687000D4F8020001904520FBF700FF00201CBD6A -:10688000B0B50125382185700170FCF7D5FA0446B2 -:1068900028B1A577257002F0B3F90248606220465E -:1068A000B0BD00BFC887002080B508484FF6FE7213 -:1068B000C18A914202D0807B800700D480BDEEF770 -:1068C00031F8BDE88040E4F721BA00BF407B0020EA -:1068D00010B50446064800682060064840686060BD -:1068E000F8F706FB083838BF0020A06010BD00BFD5 -:1068F000E087002044250020B0B50C46054603F093 -:1069000026F84CB1002144F80C1C296819B10D4639 -:1069100055F80C1DFAE72C60BDE8B04003F0F3B861 -:10692000B0B502F00BFE0446064890F8380118B1E5 -:1069300000F0ACFB054600E00125204603F0AAF874 -:106940002846B0BDD81B0020F8B51D4616460446A3 -:1069500002F0F4FD44B104F1200720348ECF33431C -:106960002F432A4331438EC4BDE8F84003F092B868 -:1069700080B5084A002001211070852002F040FFF8 -:1069800000B180BD034B852000210122BDE880407D -:1069900002F080BA9A8800201CB5044600200190BD -:1069A00001A9204602F055FD9DF8040000B11CBD70 -:1069B000BDF806004006FAD5608801F0FBFE1CBD5C -:1069C0001CB5084C8DF807000DF1070064682270B3 -:1069D0001A0A63700423A2700022E270049AF8F786 -:1069E0001BFD1CBD7C26002070B5084E05461446D4 -:1069F000706803F0C4F870682946352209230472D0 -:106A00003046BDE87040F8F707BD00BF7C26002087 -:106A100010B504460748007810B102F001FB20B120 -:106A20002046BDE81040F2F737B92046BDE81040D7 -:106A3000F2F778B91826002010B5084A126842B15A -:106A40000023032B05D01488844204D0063201337E -:106A5000F7E7C82010BD00200B8010BDE026002005 -:106A600080B5002206490A7020B10120087005494E -:106A7000087001E003480270FBF7BAFC012080BDFA -:106A80009D8800209C8800201FB5418801B11FBD52 -:106A9000041D01A92046FEF7A9FA0128F7D102F04A -:106AA00083FDADF80C00029401A8F0F713FB1FBDA5 -:106AB00010B5084B1B6853B11A79824218BFFF28E2 -:106AC000F8D11A4632F8064F8C42F3D100E000228A -:106AD000104610BDEC260020084A92F82E10814284 -:106AE00002D1117801B1704710B9002182F82B1042 -:106AF00002F82E0F5520012102F088BEAC220020A2 -:106B000006480021FF2201700549C96809690A7019 -:106B100004494FF0FF3242600A6070474C26002063 -:106B20000C0100202888002010B5044620B9064832 -:106B30008068D0F84C0580470448017821430170F3 -:106B4000BDE81040F6F758BA0C010020AD880020CF -:106B50000748002101700748C168C968097801B178 -:106B6000704780680021D0F858240020104700BFEB -:106B7000AD8800200C010020B0B50C460546FDF79D -:106B8000EDFA2044686005488068D0F8D810D0F845 -:106B9000EC242846BDE8B040104700BF0C0100209F -:106BA000084A0021032904BF0020704702EB81033B -:106BB0005B88834202D112F821300BB90131F1E731 -:106BC0000120704734870020084A002818BF021DA2 -:106BD000106848B14289120504D529B102681288AB -:106BE0008A4201D0021DF3E7704700BF548800209D -:106BF000084B002818BF031D186848B1437B8B421F -:106C000004D12AB10368DB895B0701D5031DF3E7D3 -:106C1000704700BF5488002010B508490431096846 -:106C200049B10B7C01F11B02002BF8D012F8084B84 -:106C3000013B8442F8D1084610BD00BF4426002025 -:106C400010B500F11B03007C60B113F8084B01384C -:106C50008C42F9D113F8070C104303F8070CA3F189 -:106C60000D0010BD002010BD10B58AB001AC064962 -:106C70002022204603F044F8044809902046E8F713 -:106C80004BF90AB010BD00BF94BD02008C26002055 -:106C90001EF0040F14BFEFF30980684685462DE906 -:106CA000F00F684671467446024A9047684621468E -:106CB000FEE700BFE192020010B5418203461430A6 -:106CC000012100249861C3E90241117819745861C7 -:106CD00002481946BDE8104001F094BBA4260020EC -:106CE000084890F8641001B17047012180F86410E1 -:106CF000C06D00213029F7D042185260425008314F -:106D0000F8E700BFA01F00202DE9F04F2DED108BFC -:106D1000C0F800D0D1F800D0BDEC108BBDE8F08FEA -:106D200000BF00BF00BF00BF00BF00BF00BF00BF6B -:106D300010B504460748002A08BF02462046EFF770 -:106D400045FF20B101462046EEF716FC0024204600 -:106D500010BD00BFC0B80200084890F8381001B15B -:106D60007047012180F83810006A00213029F7D0DF -:106D70004218526042500831F8E700BF3822002024 -:106D800070B514460D46064602F0D8FB6168C5E9A9 -:106D900000416168002918BF0E4635606560BDE896 -:106DA000704002F077BEB0B50C46054602F0C6FB57 -:106DB0000021616029680A1D2160002908BF2A1D81 -:106DC00014602C60BDE8B04002F064BE10B504460B -:106DD000022001F0FBFC032001F0F8FC0020EEF79C -:106DE00033F84520C72101222346FBF747FC00204A -:106DF00010BDB0B5054602F0AAFD2C6844B154F8A8 -:106E00000C1C2960FF2104F8021C002144F80C1C12 -:106E100002F079FE2046B0BDB0B50D460021002439 -:106E2000FAF7BCFA2946F3F71BF828B16FF0011105 -:106E300084718480016000E004242046B0BDB0B5B8 -:106E4000056802200C46FEF7B1FA54B1D5F8EC0003 -:106E50000021B1EB107F04D10420BDE8B040FEF763 -:106E6000A5BAB0BD0068C168490701D58168FAE7D5 -:106E70000221C0F88010C168C90702D1D0F88C1077 -:106E8000F9E70021C0F88010704770B504461C2057 -:106E900015460E4602F0C8FE48B100210673458132 -:106EA000A0F80D10C17301814161C0E9004170BDBE -:106EB00080B502F093FC00B180BD002001210022CA -:106EC000FFF796FE0028F7D001680029F4D0BDE84E -:106ED0008040EBF7ABBA70B50446182000EBC40550 -:106EE000681802F0A1FE064630B13046294601F08E -:106EF000EBFF70193474F060304670BD027A0B7A83 -:106F00009A420AD1032A0AD0022A06D109880088A7 -:106F1000401AB0FA80F0400970470020704700F036 -:106F2000C4BBF8B514460D460646002024210022B5 -:106F30000027FCF78DFC28B131462A46234601F094 -:106F400037FA07463846F8BDF8B54189ADF8041060 -:106F500041684A788DF8062089788DF80C100AB9B6 -:106F6000407A10B101A8ECF779FD8FBD10B5064845 -:106F7000006940B1054C204602F0DCFB2046BDE82C -:106F8000104002F0DDBB10BD381F0020BF8B000099 -:106F9000B0B50C46054602F0D1FA002121606968BF -:106FA0006160002908BF29460C606C60BDE8B040F4 -:106FB00002F070BD012918BF704710B500210446CA -:106FC000FFF72AFF0348002102782046BDE8104061 -:106FD000E7F79EBBCEBC0200074841880088401AF4 -:106FE0004FF4877100F5877090FBF1F25143081A56 -:106FF00000F5877080B27047BC26002010B502F003 -:10700000A6FC04460548426812B14188002090471A -:107010002046BDE8104002F076BD00BF6426002087 -:107020004FF6FF70814208BF704710B50C46E9F774 -:1070300047FB0349E0B2BDE8104002F028BD00BFA5 -:107040000160002080B5074909688A7902B180BDD6 -:10705000C2680968407800F0A5FFBDE8804000F0F4 -:1070600007BC00BFCC26002010B568B104460C3028 -:10707000EFF7C0FB0146002029B1FF22086001F1B3 -:107080000C000C818A7210BD002010BD10B506489E -:107090003C21012200230068C4680448A04700285E -:1070A00018BF012010BD00BFA401001000A00C40BB -:1070B0001CB5064980B24FF47F42082309684C682A -:1070C000009003483021A0471CBD00BFA401001060 -:1070D00000A00C401CB5064980B24FF4F802122300 -:1070E00009684C68009003480421A0471CBD00BFFC -:1070F000A401001000A00C401CB5064980B24FF45A -:107100000032112309684C68009003480421A0470D -:107110001CBD00BFA401001000A00C401CB5064916 -:1071200080B24FF440620A2309684C68009003481B -:107130002021A0471CBD00BFA401001000A00C40EE -:1071400050B14AB110B5044608300EC0214604487B -:10715000FFF71EFF002010BD6FF00200704700BF58 -:10716000D81B002005480649C069884208BFF6F7C9 -:107170003DBA04480421283002F06CBDD01E002026 -:107180002D3700007020002080B54FF0FF3001F057 -:10719000AFFF800758BF80BD03484FF4006128301F -:1071A000BDE8804002F056BD702000200648007EF9 -:1071B000022804D10548816C09B9C06C08B10020CF -:1071C00070470120704700BFD01E002030210020F2 -:1071D00070B5144600220E46054600F053FFFF2806 -:1071E00007D02B2E18BF40F22B2646EA842145F803 -:1071F000201070BD10B586B08DF80410024601ACA9 -:107200001146601C102201F0C3FF3B2011212246D1 -:1072100002F0FCFA06B010BDF8B500210391CDE9EB -:10722000011101218DF80410034901F11C0201A98B -:1072300000F06CF904B080BDA01F0020B0B5074D70 -:10724000044604212878FBF7BBFF00B1B0BD2878C5 -:1072500004212246BDE8B04002F04CBC99880020D1 -:1072600080B502F079FB42F21071084042180448E0 -:107270004FF480410078BDE8804002F03BBC00BF85 -:107280009988002080B50648064902F078FC00F095 -:10729000CFFAFDF7C3FEBDE8804000F0D9BA00BFC9 -:1072A000968700208E87002010B503460648446864 -:1072B000A2700A0A21701946032362700422BDE8F5 -:1072C0001040F8F7A9B800BF7C2600201CB50C467A -:1072D000002121600DF10601FFF789F908B1C820EE -:1072E0001CBDBDF806002146BDE81C40FEF77EB976 -:1072F00010B50446007801F081FA08B1022010BDF3 -:10730000204600210022FEF7A1F9B0FA80F04009E2 -:10731000000110BDB0B5074B00221B6843B11C79BA -:107320008442FAD1DC88D5B2013221F81540F4E765 -:10733000D0B2B0BDEC260020E0B58DF805000648BF -:107340000121002203238DF80410007801A9009187 -:107350000A21FBF790FD8CBD9F88002058B1074B98 -:1073600042791B789A4206D2531C437100EB4200CB -:10737000C180012070470020704700BFD3BC0200CD -:1073800001684268054BC3F80720C3F80310044A9C -:1073900001684068C2E90A10704700BFE886002013 -:1073A000E87F002010B504460B38102804D30448A9 -:1073B0008068D0F84C05804702488473012010BDD6 -:1073C0000C010020E87F002010B504460B3810287F -:1073D00004D304488068D0F84C0580470248847381 -:1073E00010BD00BF0C010020E87F00200648017896 -:1073F00041F004010170054800218068D0F8940034 -:107400000078F6F725BE00BF8C8800200C01002014 -:1074100080B50648006838B1F2F7DCFA0448006825 -:10742000BDE88040F3F7C8BA80BD00BF38880020AF -:107430003C88002070B5074E044602F07FF80546F0 -:1074400020463460F2F7C6FA2846BDE8704002F0E4 -:1074500021BB00BF388800200749096849B10A6884 -:107460001388834203D1126A5278D20701D00431C3 -:10747000F3E70846704700BF54880020074A516868 -:1074800019B10B682BB11946FAE700210160111DF3 -:1074900001E0002202600860704700BF442600201F -:1074A00080B507490138884205D80620FDF760F904 -:1074B0000420FDF75DF90220BDE88040FDF758B9D2 -:1074C000FEFFFF0F10B5064C28B1064801210068E9 -:1074D000426820469047606820F03000606010BD30 -:1074E00000400340D80100101CB504460498002B4E -:1074F0000090054808BF03462046F4F765FF0028C2 -:1075000018BF002420461CBD60BA020070B51346A7 -:107510000C46054600201C2100220026FCF798F9A5 -:1075200020B12946224600F07BFF0646304670BD5A -:1075300000F11401816141612021EFF3118281F397 -:10754000118801684368196041680068416082F3EE -:107550001188704710B5074C207C08B1FAF75AFA29 -:107560000020207240F2000CEFF311808CF31188A0 -:1075700010BD00BF3822002080B502F02EFA50B1B5 -:1075800001460079421E0120012A03D88A6981F848 -:107590002000CA6180BD002080BDB0B505680446EA -:1075A00095F85000022808D1A86802F06DFA20462C -:1075B000FBF723FC002085F85000B0BDB0B50546B0 -:1075C00001F0BCFF2C6834B1216802C5002918BF46 -:1075D0000D1D0021296002F05DFA2046B0BD70B596 -:1075E0000C46064601F0AAFF0025246824B1216953 -:1075F000B14208BF2546F8E702F04CFA284670BDB4 -:10760000F8B50C46054601F099FF95E8C2002D69D2 -:107610002944216002F03EFA701B874238BF384689 -:10762000F8BDBCB5046825790DB9A4792CB14FF02B -:10763000FF340094E1F7DAF9BCBD02B0BDE8B04018 -:10764000F9F7F4BE10B50C4601F0D8F838B100F1E6 -:107650000C0120460222BDE8104001F099BD4FF414 -:107660009970208010BD10B54A1E012101FA02F365 -:1076700000221C0404BF90B210BD034218BF0A438D -:10768000C3F34E034900F4E710B562B10C780378F8 -:10769000A34206D1013A00F1010001F10101F5D147 -:1076A0001C46181B10BD002010BD10B50822130683 -:1076B00007D00B7804789C4203D1013A01300131A4 -:1076C000F5E7D0B2B0FA80F0400910BD10B503461E -:1076D0001B68834204D09C6864699442F8DA00E035 -:1076E000034658680B6048600160596010BD000097 -:1076F00058B1064B1A6822B11346D268002AFBD152 -:107700000C33817100211860C160704754650020FE -:10771000064A1168814205D031B10A46C9688142E2 -:10772000FAD10C32C168116002F07CBA54650020B5 -:1077300080B506484FF480710078FBF741FD00B139 -:1077400080BDBDE88040FBF795BD00BF9988002053 -:1077500080B50548FF22007800EBC0008100034897 -:1077600001F0ACFB80BD00BFE6BC0200B0540020BD -:1077700080B50548FF22007800EBC0008100034877 -:1077800001F09CFB80BD00BFE6BC0200B0540020AD -:10779000102809D31038012200F01F01400902FA15 -:1077A00001F1024A42F82010704700BF80E200E079 -:1077B000E0B50178B0F801000DF1050303228DF862 -:1077C0000510ADF806004F208021FAF757FF8CBD59 -:1077D00080B505480021017004480170FAF76EFF7A -:1077E000BDE88040FFF724B8A1880020A2880020CF -:1077F000B0B50546C0780C460870281D02F010FA96 -:107800006080A81D02F00CFAA08005F10800B0BD50 -:10781000B0B5064D2C78601C2870204601F02AF87F -:10782000002CF7D00028F5D12046B0BD8F8800206D -:1078300003480449044A054BC0E90132C16070475E -:10784000F4240020099C02003DFB0000B5720100F9 -:107850000348064B0349044AC0E90121C36070474D -:10786000F42400203DFB0000B5720100099C0200D9 -:1078700010B5064C206818B102F0D4F90020206041 -:1078800000F05EFDBDE8104001F000B8CC260020FD -:1078900080B505494870054880210078F7F7A8F8B9 -:1078A000F8F70CFF002080BDF42400209888002009 -:1078B00006490A68002AFCD10022CA610860C8692A -:1078C0000028FCD00020C8614868704700100440C0 -:1078D00070B50024A34208D050F824506E1C04D088 -:1078E00015408D4202D00134F4E7FF24E0B270BDB0 -:1078F000064841880088401A4FF4877100F5877068 -:1079000090FBF1F202FB110080B27047BC26002010 -:107910008068D0E90020C1E9002004484FF470528B -:10792000006802EA80208860704700BF302403406E -:107930000648B0F870100131A0F8701088B2884283 -:1079400008BF70470120F3F767BD00BF407B0020F0 -:1079500003480449044A054BC0E90132C16070473D -:1079600074230020D1A60100317902004570020085 -:10797000054806494FF0FF32007818B141F8042B52 -:107980000138FAE7704700BFD6BC020080860020AD -:1079900005484FF4825100680028044848BF4FF45E -:1079A00041510160704700BFAC4F005028A10C400E -:1079B00005484FF4805100680028044848BF4FF440 -:1079C00040510160704700BFAC4F0050A8A00C4070 -:1079D00080B505480068FAF7E9FC04480068BDE88E -:1079E0008040FBF717BF00BFE8870020EC8700202E -:1079F000B0B5044601F0A2FD054604482146FEF755 -:107A000003FF2846BDE8B04002F044B8D81B002070 -:107A1000064A0021B1F5307F06D0501890F9333076 -:107A2000002B02D55831F5E700207047586500203B -:107A3000E0B5064901AAFCF7CFFE9DF806108128A3 -:107A400018BF6FF07F0148B28CBD00BF0100030476 -:107A50000A460146044843682BB18068084202D0B8 -:107A60000248406818477047ACBB0200D01E002097 -:107A700005480068C00704BF00207047034800683D -:107A8000C0B2C009704700BF402108400000044058 -:107A9000BCB5044680686A46ECF778F90546832849 -:107AA00004D1694620460022FCF796FE2846BCBD5C -:107AB00010B504463A2000211122234601F0EAF9CC -:107AC00000B110BD01484068606110BD0425002070 -:107AD0001FB5044600200390CDE9010001208DF878 -:107AE000040001AA2046FFF7E7F8204604B010BDC5 -:107AF00005490A78824208BF704708700348102180 -:107B00000078F6F7A5BA00BFC426002099880020A7 -:107B100080B506484FF480710078FBF751FB00B147 -:107B200080BDBDE88040FBF7A5BB00BF9988002061 -:107B3000F8B54188ADF80410411D02910179407FEC -:107B40008DF806008DF80C1001A8F1F7BDF98FBD76 -:107B500070B50C460646EFF7DBFF05461E2800D041 -:107B600025B9304621460122FDF7DEF9284670BDD1 -:107B700010B5064890F82E0028B1002000210024FE -:107B8000E6F75AFE00B10124204610BDAC220020C9 -:107B9000FEB50290002000916946019003484068BC -:107BA00001F0CCFF013806B080BD00BF0C240020DE -:107BB000064A12683AB11379834202D193688B4224 -:107BC00001D01032F5E71046704700BF6C26002048 -:107BD000E0B5064904486A46096800684B6C022112 -:107BE00098479DF800008CBDD826002030880020E2 -:107BF00005490968401A054909788900B0FBF1F286 -:107C000002FB1100704700BF2C880020B0880020C4 -:107C100000F120014FF0FF32C9B2192938BF00F13D -:107C200045024038C1B2252938BF0246D0B270475C -:107C300080B50649044809680068096C8847BDE8B2 -:107C40008040FEF713BD00BFD826002030880020FA -:107C500005480178832918BF704700210170034847 -:107C60000170F8F709BB00BFAC880020AF88002086 -:107C700080B501F063FC0449044A09681160BDE85D -:107C8000804001F007BF00BF388800203C880020FA -:107C90000C2884BF01207047062884BF032070474A -:107CA000022884BF05207047002818BF07207047AE -:107CB00041F01001F1290AD112F0300F07D080B540 -:107CC00001F04AFE00F007000230BDE88040704736 -:107CD00080B5064A12682AB1926A1AB100040130CE -:107CE000904700E0002080B280BD00BF5C270020EC -:107CF000F8B501A80021FDF77BF8039A6846BE217C -:107D00008242009228BF8FBD1170009A0132F7E7BE -:107D100001460120886000200861C86001F114005C -:107D200088614861014800F06DBB00BF94260020C7 -:107D300010B50446006800F02DFB04482168242299 -:107D40004068436898470020206010BDA01F0020B5 -:107D500010B504460068FFF7EBFB044821681C22BD -:107D60004068436898470020206010BDA01F002095 -:107D700010B50446006800F00BF80448216858224A -:107D80004068436898470020206010BDA01F002075 -:107D90002021EFF3118281F311888168C368196093 -:107DA000C16883685960002182F31188EDF7E4BB54 -:107DB00041680978102908BFFFF7C6B8092904D01F -:107DC000052918BF7047E9F7FDB800F0BABB884233 -:107DD00004BF012070470246002032B129B180B5AE -:107DE0001046FFF762FCBDE88040704750B10022AA -:107DF0000021072A07D8835C0132002BF9D001212A -:107E00000922F6E70021C8B27047E0B54178408802 -:107E10000DF1050303228DF80510ADF8060044208E -:107E20008021FAF72BFC8CBD80B540F2A813C1F27B -:107E300000031B689B69984740F28441C4F26021AB -:107E400000220A6080BD80B540F2A811C1F2000195 -:107E500009684969884740F28441C4F260210022E0 -:107E60000A6080BD80B550B110F8021CFF291CBF0C -:107E7000042080BD0C38F9F725FA002080BD0520CC -:107E800080BD70B50E46014618461C46154601F0E9 -:107E900076FE04F10800314601F02FFE057070BD3A -:107EA0001CB504686479022C02D1E7F701FB1CBD04 -:107EB000049C049402B0BDE81040E3F773BCF8B52D -:107EC0000F20B421012200238DF80C004FF6FC7026 -:107ED000ADF8040001A8F7F71BFA8FBD10B5EFF35A -:107EE0001484002C1CBF002181F314888047002CCF -:107EF0001CBF022181F3148810BDB0B50B460020D1 -:107F00001C2100220024FBF7A3FC18B10546FFF753 -:107F1000FFFE2C462046B0BD10B5054CD4F800C07D -:107F2000BCF1000F04BFB62010BDBDE81040604793 -:107F30003024002010B5054C2069F2F751FAA168F1 -:107F400001B9E060481CA06010BD00BF381F0020D0 -:107F5000FF2807D0044A526852F820308B4218BFDD -:107F600042F82010704700BF14BB0200FF2808D061 -:107F7000044A52F82030DBB28B421CBF42EA800038 -:107F80000170704700100840102801D3044A02E035 -:107F9000042801D3014A8154704700BF14ED00E06A -:107FA000F0E300E0F8B5054B1B682BB1CDE90212F8 -:107FB0008DF8040001A898478FBD00BFDC24002085 -:107FC00010B514460A46014623F001003A2811BFB5 -:107FD0000A201846234600F05DFF10BD010700F09F -:107FE00002004FF0030158BF012141EA400001495E -:107FF000087070479088002050B180B5073080B27B -:10800000F0F7D8F9FF28BDE8804004BF0120704791 -:1080100000207047E0B58DF807200DF1070201231D -:10802000FBF734FE014908708CBD00BFA02300207F -:1080300010B54AB111F8013B10F8014B013A9C42CE -:108040001CBF002010BDF4E7012010BD0022012854 -:108050004FF0000004BF40F2EE204FF47A72022984 -:1080600008BF0246104670470548B0F85410B0F8F3 -:108070005600814218BF70470820FCF793BB00BF31 -:1080800030210020B0B5144640F2FF32502305469F -:10809000FFF71EFC1CB155F82010890A2160B0BD05 -:1080A00010B5044601F04AFA03490A7822430A70DF -:1080B000BDE8104001F0EEBCD01E0020B0B5054870 -:1080C0004468C56901F018FB014620462A46BDE810 -:1080D000B0401047D01E002010B5044600F04AFA08 -:1080E00030B9204600F03CFD002808BF6FF00104C5 -:1080F000A0B210BD10B5054CD4F808C0BCF1000FFB -:1081000004BF012010BDBDE81040604704250020D9 -:1081100001284FF00100044A08BF0320012110701C -:10812000852001F073BB00BF9A88002010B5054C74 -:1081300004212078F6F75CFC20780421BDE810408B -:10814000F5F7BEB999880020F8B5ADF804000448E9 -:1081500002918DF80C20416809B101A888478FBDB4 -:108160003C830020B0B585690C4635F8020B24F835 -:10817000020B2946204601F002FD287A2072B0BD8C -:10818000E0B5ADF8000004488DF8021001920168D6 -:1081900009B1684688478CBD3C8300201FB5ADF807 -:1081A000020000206C468DF80000201D01F0B7F899 -:1081B0002046E9F7D3FB1FBD10B5034604484468C9 -:1081C000218019460223BDE81040F7F725B900BF0A -:1081D0007C26002004480078052818BF7047034813 -:1081E00080210078F5F734BFC4260020998800204C -:1081F00004480178012903D100210170024801706F -:10820000FAF7F6B89D8800209C88002010B50C462F -:1082100000F0F4FA30B10C302146022200F0B8FF31 -:10822000002010BD022010BD10B50446087A0328B6 -:10823000207219BF08882080204601F0A0FC002091 -:10824000608110BD054A12683AB153681B7809B1C4 -:10825000002BF8D000F8013BF5E77047208800209C -:10826000044981F82F0001210028034818BF02218A -:1082700001707047AC220020AC27002050B1821D55 -:10828000407938B132F8023B01388B4204BF0120FB -:108290007047F6E70020704710B5054BC0B22AB111 -:1082A00011F8014B013A6040185CF7E710BD00BFC0 -:1082B000A0AB020004490968401A04490978890002 -:1082C000B0FBF1F0704700BF2C880020B088002080 -:1082D000054800224FF0807341790131417100203F -:1082E0000021F6F705B800BF14250020044800213E -:1082F00001700448007800B17047F7F7BDBF00BFB8 -:10830000AF880020AC88002080B505488068D0F890 -:10831000DC04804701F012F9BDE8804001F0BABBEF -:108320000C01002058B110B51C21044600F0CCFD12 -:108330006FF00100411C20806181BDE81040704752 -:10834000B0B5054C206820B1856901F06BFC28466A -:10835000F9E700202060B0BDE4870020054A38B16D -:1083600032F8023B01388B4204BF01207047F6E728 -:1083700000207047F0850020044800210170044867 -:10838000007800B17047F7F777BF00BFAC880020D6 -:10839000AF8800202021EFF3118281F3118801685A -:1083A0004368196041680068416082F31188704732 -:1083B00010B504460448002B08BF03462046FCF7CE -:1083C0004BFD204610BD00BFDCBB0200B0B5054D23 -:1083D0000024022C08BFB0BD55F8240080470134AA -:1083E000F7E700BF7CBC020010B50B460020082157 -:1083F00000220024FBF72CFA10B104464060006014 -:10840000204610BD2022EFF3118382F3118808600B -:1084100042684A6042681160416083F31188704786 -:1084200010B504460448002A08BF02462046FEF75D -:1084300043FC204610BD00BFE8BB020010B5044657 -:108440000448002A08BF02462046F8F7ABFD204644 -:1084500010BD00BFCCBA02002021EFF3118281F3DE -:1084600011888168C3681960C1688068416082F3BF -:10847000118870471CB50C4601A9FEF727FF10B103 -:108480004FF6FF7101E00199498821801CBD016808 -:1084900091F8512022B1012A18BF7047FAF7ADBCFC -:1084A00091F85310FBF7F6BAB0B50C46054601F04B -:1084B0004EFA296844F80C1C2C60BDE8B04001F06D -:1084C00022BB70B514460D460646F7F7F4FC30465D -:1084D00029462246BDE87040EAF71AB8F8B5ADF86B -:1084E0000C0004208DF800006846F7F70DFDBDF87C -:1084F000020004B080BD41B2002211F1760FB8BF76 -:10850000012251000138052838BF01210846704773 -:1085100010B52021EFF3118481F311888068214682 -:10852000FCF7B4FC84F3118810BD0B46416911B10E -:108530004878800700D070478A888878097BFAF7E6 -:1085400089BFE0B541894068ADF8041040788DF8E6 -:10855000060001A8FDF782FB8CBD000010B5044C9D -:10856000606820B101F05EFB00206060208010BDDB -:108570003426002080B501F030FA28B100790138A6 -:1085800004283CBF012080BD002080BD80B501F0E3 -:1085900024FA28B10079013802283CBF012080BDAF -:1085A000002080BD0446FEF7E1FC0348032101756D -:1085B000204601F056FA00BF381F002004488168A9 -:1085C0000139816018BF7047D0E90310F5F766BA2A -:1085D000381F0020FF2806D0034911F8202002F0A0 -:1085E000FB0201F8202070470210084010B5044C2F -:1085F000207818B1FBF77AFD0020207010BD00BF75 -:10860000AB88002080B580780530C0B201F00CFB4B -:1086100018B1BDE8804001F005BB80BD130608BF5E -:10862000704711F8023B013A037011F8013C4370A6 -:108630000230F3E7014600200A2906D8012202FA97 -:1086400001F111F4836F18BF0120704780B5044811 -:10865000407808B900F03CFDBDE88040F8F72EB83E -:10866000F424002003480121017103480068F5F754 -:108670002FBF00BF342500204C8800200348012173 -:10868000817003480068F5F723BF00BF3425002040 -:108690004C88002080B50448006801F071F900287A -:1086A00018BF6FF0020080BDDC25002080B50448B3 -:1086B000006801F065F9002818BF6FF0020080BD66 -:1086C0000C240020022807D0032804D180B5E7F746 -:1086D000DDFC002080BDFEE7F4F724BF044890F8DD -:1086E000411119B1D0F86C0100B10047704700BFCB -:1086F000D81B002000214FF0FF320174C0E9022195 -:1087000001710160C0E90511818370471CB5C2F396 -:10871000800302F001040093C2F340032246E6F70F -:10872000B3F91CBD10B5012998BF0121044601F021 -:1087300053FA2046BDE8104001F050BA0248034900 -:10874000034AC0E90221704704250020419202003B -:1087500065E200000249034A0A6003490870704755 -:10876000582700203D290200C0260020044900208F -:108770000022092A08BF704741F822000132F8E7B9 -:108780003C83002002460448012100780AB101F030 -:10879000B1B9F5F75DBC00BF9988002080B5FDF741 -:1087A000B9FF80075CBF002080BD0020FEF794F970 -:1087B000012080BD0449B1F86E20824208BF704795 -:1087C000A1F86E00FFF7A4B9407B0020082884BF01 -:1087D00002207047024A0146002042F821007047FB -:1087E0003C830020E0B58DF807000348C16911B152 -:1087F0000DF1070088478CBD3C83002001460448EA -:10880000006818B1426812788A42F9D1704700BFF7 -:10881000208800200349044A086010608420042155 -:1088200000F0F4BF708800206C270020044989689C -:10883000D1F8E420D1F8EC1051F820001060704716 -:108840000C0100200021082904BF01207047425C70 -:108850000131FF2A1CBF00207047F4E710B5002249 -:1088600000238A4224BFD8B210BD10F8014B013258 -:108870006340F6E70449096821B10A7B824201D0CE -:108880000431F8E7084670475488002010B5044CBE -:10889000206820B14168216001F0C4F9F8E710BDFB -:1088A000402700200448011D0020096809B101305B -:1088B000FBE7C0B2704700BF442600200448806830 -:1088C000D0F8B800007808B1F3F79EBCFFF754BDAC -:1088D0000C010020B0B50C46054600F0A9FF024887 -:1088E00044650565B0BD00BF0820002080B5044B7D -:1088F0001C33FFF7A3FD4169002908BF084680BD6E -:10890000A01F00202022EFF3118382F31188026B55 -:108910001143016383F31188F7F7FEBC00BF00BF6A -:1089200000BF00BF0498804700980199029ADDF8C3 -:108930000CE0104710B52021EFF3118481F311886A -:108940002146FCF7A3FA84F3118810BD83B0C0B5AB -:1089500003AF0EC703A9009100F004F8BDE88840FA -:1089600003B07047E0B50246002001914FF0FF319F -:10897000009001AB0020DDF737F98CBD044800788A -:10898000042803D8022801D0DEF776BA704700BF6A -:10899000B7880020B0B50C46054600F0CFFDA96CA5 -:1089A000A143A964BDE8B04001F074B8B0B50C466D -:1089B000054600F0C3FDA96C2143A964BDE8B040A1 -:1089C00001F068B880B5E6F78DFEE7F779FEF7F7B6 -:1089D000EBFABDE88040E1F7CAB82020EFF311813F -:1089E00080F31188B1FA81F081F311884009704752 -:1089F00010B52023EFF3118483F31188C0E900211F -:108A000084F3118810BD10B5044600F097FD0021D5 -:108A1000C4E90011BDE8104001F03CB8E0B58DF8A4 -:108A200007000DF10703412081210122F9F726FEFD -:108A30008CBDE0B50022009068468DF80410ADF8BA -:108A40000520F6F7ADFA8CBD28B132B110F8013B24 -:108A5000013A8B42F9D000207047012070471CB5C5 -:108A60000C6891F90430CDE9001201212246E5F7A6 -:108A700003F91CBDD0E9002092F83010043918BF6A -:108A8000012152690078F6F73DB81CB501A9FEF73F -:108A90001DFC044610B90198E7F762F920461CBD99 -:108AA0000A7A02720A7A022A02D109880180704782 -:108AB000082200F06DBB80B5F7F766FB013004BFFC -:108AC000E82080BDF6F72CFD002080BD0A4609682D -:108AD00029B18142FAD1006810600120704700205E -:108AE000704710B52021EFF3118481F31188EFF75F -:108AF000F3FA84F3118810BD10B52021EFF311842F -:108B000081F31188FAF768FE84F3118810BD81B0F3 -:108B1000C0B5039303AB009300F0EAFBBDE88840C7 -:108B200001B0704780B5F5F743F9024801210170A3 -:108B300080BD00BF9827002080B5F5F739F90248BD -:108B40000121017080BD00BF9927002010B5C478B5 -:108B5000C2880179037A2046BDE81040FAF77ABC52 -:108B600080B500F03AFF08B1007908B1002080BD5F -:108B7000012080BD0349096821FA00F000F00100DE -:108B8000704700BFC0200240FF2803D0024A92680D -:108B900042F82010704700BF14BB02008178437870 -:108BA000024840780A46FAF755BC00BFC0260020AC -:108BB00003488068D0F80001807B2238C0B270473B -:108BC0000C01002003480078012898BF01F094B8F8 -:108BD0000020704718260020034800218068D0F844 -:108BE000B8000170704700BF0C01002003480178F5 -:108BF000FE20002908BFFF20704700BF702700201B -:108C000010B5034CE2202146FDF70CFA204610BDBA -:108C1000C8870020034991F82610082908BFEEF7FD -:108C200063BD7047407B0020D5F8CC10D8F8140005 -:108C300049680968D1F80425024270472275026C20 -:108C4000D0F8D4301268D28A52064FF04E027047E4 -:108C5000034801680029FCD000210160704700BF73 -:108C60001C100440E0B5C2F3800302F0010200933F -:108C70000123E5F709FF8CBD4168034A0978D170EB -:108C800000785070704700BFC026002003490122C1 -:108C900091F8480081F84820704700BFA01F0020CD -:108CA00010B5046804F1340000F0CEFF002084F811 -:108CB000310010BD042805D180B51046E7F782FDCC -:108CC000BDE880400020704780B50F20F8F722FAF9 -:108CD00000200221BDE88040FAF7F6BD08288FBFCA -:108CE0000220024A42F82010002070473C830020F6 -:108CF0001CB50C4601A9FEF7E9FA00B11CBD0199AB -:108D00000C711CBDE0B501904FF40070ADF800008F -:108D10006846F2F76FFC8CBD0179042904D0022962 -:108D200018BF7047F2F788BAF1F78CBD80B50348D9 -:108D30008068D0F83403804780BD00BF0C0100205C -:108D400010B5034C207000F011FC607010BD00BF26 -:108D5000722700200349002912BF01C90020002109 -:108D6000ECF7AEBBB8BD020010B510F8014BFBF735 -:108D70005FFB012C08BF0838C0B210BD03490020BA -:108D8000096809B10130FBE7C0B2704720880020B4 -:108D900003490020096809B10130FBE7C0B2704700 -:108DA000EC26002020220028024818BF24228150EF -:108DB000704700BFAC22002080B50020FDF78CFE7C -:108DC000FF200321BDE88040FAF77EBD80B503494E -:108DD000FF22098800F072F8012080BDC2B40200B1 -:108DE00003490979002918BF06304001704700BFC8 -:108DF000B82400200249088602498881704700BFD4 -:108E0000E87F0020E886002003488068D0F82C1313 -:108E10004FF48050084700BF0C0100200348007841 -:108E200008B1F4F7E9B80020704700BFAD88002012 -:108E300003488068D0F82C134FF40070084700BF37 -:108E40000C0100200248034A07210023FEF778B9ED -:108E500008860020D19C020003488068D0F82C13BB -:108E60004FF40060084700BF0C010020E0B500216E -:108E7000CDE900116946FEF718FC80F001008CBDB9 -:108E8000034A516811B1527802B10847704700BFD8 -:108E9000E82500201CB514460A4601460093002030 -:108EA0002346FDF777FA1CBD10B5034CE06BF6F7CF -:108EB000E7FB0020E06210BD381F00200B46114682 -:108EC0001A4600F0F7BA00BF0A46002100F0F2BAD5 -:108ED00040B584B002AE0096EDF78AF8029A039B83 -:108EE00004B040BDE0B50DF10702012300F018F910 -:108EF0009DF807008CBD4FF6FF70814208BF704798 -:108F0000C8B2002100F0A4B84FF6FF70814208BF3C -:108F10007047C8B2012100F09BB880684FF0FF3263 -:108F20000A60D0E90120C1E90120704710B504684A -:108F3000D4F824C0029C0294BDE81040604780B57C -:108F40008022F8F769FF08B1C06880BD002080BDAD -:108F5000B0B50024551E80E836008361C0E90444A2 -:108F6000B0BD80B500F094F800F07AF8BDE880401C -:108F700000F096B828B131F8023B013822F8023BE4 -:108F8000F8E70846704780B510EB520041F1000148 -:108F90000023FFF79DFF80BD017809B100207047D5 -:108FA00040680028FAD0FCF75EBD0A7A032A0272F4 -:108FB00008BF00F0E4BD09880180704710B50023A8 -:108FC0009A4208BF10BDCC5CC4540133F8E70000DE -:108FD000B0B5024991E83C003CC0B0BDF4BA020013 -:108FE000024A02EBC000F6F7CDBB00BF1CBC02007A -:108FF000B0B5024991E83C003CC0B0BD04BB0200E2 -:10900000024A02EBC000F2F73FBF00BF24BC0200DF -:10901000014602480078F6F747B800BF3C2600201A -:109020000248FF2108220068FFF70EBDDC87002000 -:109030000249D1E90012C0E900127047381F002030 -:109040000249896851F82000704700BF14BB020034 -:10905000FF281CBF014A8154704700BF0020024016 -:1090600001480249816070470C010020FCA2020007 -:109070000121002201724FF0FF31C0E90021704749 -:10908000102802D3014910380860704700EF00E053 -:1090900001480249016070470C010020C4B402007D -:1090A00001480249C16070470C01002098AD0200E0 -:1090B000024908701021F4F7CBBF00BF968800204A -:1090C0000248012180F82610704700BF407B002035 -:1090D0000248007800B17047FFF78AB818260020D0 -:1090E000024880F82F20E5F73BBC00BF407B002002 -:1090F00002490A681040C2430A60704710100440D9 -:1091000002490A681040C2430A60704708100440D0 -:1091100000F02CFA01490860DDF750FAC82600205B -:1091200001EB40310148C06800F00EB9A0230020D7 -:10913000B9F82410ADF8000058468DF80880704743 -:10914000B068D0F81814D0F8D40090F8530008474D -:10915000B5F8541001396FF31F31A5F8541070475A -:1091600094F8220085F8AA00606AC5F8AC00704740 -:109170000746287C05F1110103288DF8200070476F -:1091800000246A1D3346CDE90071CDE90204704721 -:109190002AB111F8013B013A00F8013BF8E77047AA -:1091A000F0B5024991E8FC00FCC0F0BDB8B902007E -:1091B00002484FF000410160704700BF00A10C4021 -:1091C0000248016841F00301016070472422084011 -:1091D00002480068C0F30720704700BF30A00C4071 -:1091E00002480068C0F38440704700BF04A00C40F0 -:1091F00002480068C0F38120704700BF20A00C40E7 -:10920000024840210160FDF75FB900BFA8A00C40F3 -:109210000249084490F84A01704700BFD81B00205B -:1092200010B50023541E80E81E00C0E9043310BDB1 -:109230000249C96801B10847002070470425002091 -:1092400000F00300022101FA00F000F01C0070475A -:1092500000214FF0FF32C0E90011C0E90221704740 -:1092600000F0AEF9014801210160FEE77C052043D2 -:1092700070B5024991E87C007CC070BDB8BA0200AC -:10928000024A02EBC000EFF7C1BC00BF34BC0200D1 -:1092900000680121806900F0080081EAD000704771 -:1092A00080B50079EDF726FEBDE88040F9F7E2BF12 -:1092B00080B5FFF7A3FA08B1406880BD002080BDEB -:1092C0000249002818BF012008707047A827002015 -:1092D000024901220A60D0E906010847042009403A -:1092E0000249012281F83020F6F7EEBF381F002036 -:1092F000E0B501930023009301ABDCF775FC8CBD56 -:1093000080B50A46D0F803101046FFF7DDFD80BD9A -:109310000068002180F822100A20ECF797BA09B102 -:1093200000F02DBC00214160016070474FF4C8017E -:109330004FF47A72C0E900217047042303EB8101E6 -:10934000042389B2FFF7ECBE10B50468D4F81CC042 -:10935000BDE810406047234603958DF80450029500 -:10936000FBF7D4BE8DF85400B8F84700ADF85500AF -:109370007047BBF80C00049901224346E3F7AABBEF -:1093800005F1080004F10A010822FFF701BF41EAD4 -:109390009011800002308DF82D10704740F203715B -:1093A0004FF6FF720523FEF793BA98F8720001306A -:1093B000C0B2CDE90005704701788DF839104178C9 -:1093C0008DF83A107047A8702079E870607900280D -:1093D000287170470BEB4B0001EB8000A0F81CA03C -:1093E0007047DAF80860DAF81000BAF93010704700 -:1093F0008DF8630002208DF86000E81C2047ADF86E -:1094000038006E7B05F10E0000F00ABC00214160BF -:1094100081600160FF2101717047D0E90110401A9D -:10942000B0FA80F040097047062902D34A1C18BFE1 -:109430007047FDF71DB81CB54FF0FF340094FEF7E0 -:109440002FFD1CBD80B5F0F741FABDE88040FBF769 -:109450002BBA806902780A70B0F801004880704722 -:1094600080B5EEF7A5FDBDE88040FCF7C7B980B533 -:10947000FAF704FEBDE8804000F02EBC80B5FFF78F -:10948000EFFFBDE8804000F015BC0021425C0131D7 -:10949000002AFBD1481E70470021425C0131002A9E -:1094A000FBD1481E704780B5FFF7AAFEBDE880409B -:1094B000F7F752BD00239A4208BF7047C1540133E9 -:1094C000F9E70B46D0F80320C11D184600F018BC80 -:1094D0000068002101700A20ECF7B8B90021C0E94A -:1094E0000011C0E902117047017841F0800101705C -:1094F000FEF71EB901480178FDE700BFA01F00205C -:109500000148C069004700BF381F0020E0B5019046 -:1095100001A8FEF70DFC8CBD05300A21B0FBF1F06F -:10952000EEF724BEC0E9011204210170002070474B -:10953000C0E9011202210170002070472021EFF3E1 -:10954000118081F31188704701480078704700BF8F -:10955000AB88002001480078704700BFA227002098 -:109560000A46034669208021F9F788B80148007847 -:10957000704700BF96880020431C4520C02101226F -:10958000F9F77CB80148408B704700BF407B002052 -:1095900001480078704700BF8D2700200148807C7B -:1095A000704700BF407B00200148C08A704700BF61 -:1095B000407B002001490870704700BF8D270020C4 -:1095C0000020EFF3108072B6704770470020EFF371 -:1095D000108062B67047704701490870704700BF3D -:1095E0008E88002001494860704700BFF4250020A4 -:1095F00001480078704700BF702400200B460146E8 -:1096000010461A46FEF748BE0148006800F01EBB2F -:10961000DC2500200148006800F018BB0C24002065 -:109620009BF800004FF48051F5F7E2B902208DF865 -:109630004000E81C00F0F4BA0420394614222B46FE -:10964000FCF7BEBED0F85413D0F898000430084799 -:109650000221808C1080832000F0D8B8ADF8020081 -:10966000B068D0F8302470478DF818009DF840009D -:109670000F287047014A5160107070472C26002057 -:1096800018B1006808B100F0FFB9704701490968D6 -:1096900009680847E001001001490968C96A0847DC -:1096A000B80100100148006800680047E801001098 -:1096B0000148006840680047E801001001488068E0 -:1096C000704700BFD81B00200149202200F018BBC2 -:1096D00064B902000149202200F012BB24B9020043 -:1096E000E0B5019001A8FEF733FB8CBDA1F1FE00AF -:1096F000B0FA80F0400970470148006D704700BF24 -:10970000A01F00200068016B21F480710163704785 -:109710000068016B41F40071016370470068016BE0 -:1097200041F48071016370470149242200F0E8BAD6 -:109730009CB8020001490860704700BFE426002081 -:1097400001490860704700BFE826002001494870C1 -:10975000704700BF08880020014890F8310070472A -:10976000AC220020014890F82E007047AC22002067 -:10977000014981F832007047AC220020014981F88C -:1097800031007047AC220020014800210170704771 -:10979000AB88002001490860704700BF24270020E3 -:1097A00001480078704700BFBF880020014800686A -:1097B000704700BF3C8800200148002101607047CD -:1097C000E487002001480068704700BFE48700205C -:1097D00000680149EFF766BEB94C02000148007805 -:1097E000704700BFA8270020014800210160704792 -:1097F0005488002080B5F1F7F3FB4BF6BE2080BD06 -:1098000013460A4601460020F6F7B0BA13460A4648 -:1098100001460020FCF7D4BD01488069C06B704749 -:109820003822002080B51046F7F7F4F9002080BDFB -:1098300001460148FCF744BF207C00200148C06C71 -:10984000F6F76ABD0820002001680A6802605060CF -:10985000084670470168081AB0FA80F0400970475E -:10986000426808604A6011604160704701492422E3 -:1098700000F046BAC0B8020001488069704700BFD6 -:10988000382200202020EFF3118180F31188FEE7B9 -:1098900080B52421FFF718FB80BD006908B100F0F6 -:1098A000C1B970470088B0FA80F0400970470021C4 -:1098B0000170C0E901117047D5E90201D0F8D40068 -:1098C0007047DAF80800006C006870474846214687 -:1098D0003246FFF75DBC691D05F10D02F6F708BEC3 -:1098E000ADF8380068790024704784F80FA084F838 -:1098F0000E907047B068D0F8B800C16C7047002077 -:109900008DF82700F9F7B6BC316828688A6D2146C2 -:1099100010478DF8080002AB61207047ADF83800A1 -:10992000681D00F07DB92046FF214FF0FF327047DF -:109930000978B2FBF1F10844704700224FF08073C0 -:10994000FDF702B8C521C2B24520F8F797BE80B531 -:10995000FFF7F4FD000480BD80B5FAF707FA80B286 -:1099600080BD00214FF0FF32E7F714BE01EB40004D -:1099700030F8020C70474068002180F8FD107047F5 -:1099800080B5E8F737FE013880BD406801210068E6 -:10999000C1647047012085210022E0F731BC80B509 -:1099A000F6F71AFE002080BD80B5F6F73BFE0020DA -:1099B00080BD80B5FAF7DAF9C0B280BD0A4601462B -:1099C0000020F7F7A3BA80B5F4F782FD002080BD30 -:1099D0000021C0E900118160704701460020F1F7C5 -:1099E00097B901464A20FCF71DBB0138FDD17047ED -:1099F000704740680021017070478068D0F84C05BE -:109A00000047DBF80000F4F763BDD7E901102A46F0 -:109A100020470421007800F06DB840465146E2F737 -:109A2000EBB88068D0F84C0500478068D0F8401348 -:109A3000704700220023FBF769BB00230024FEF7D8 -:109A4000BBBB80B5EBF74EFE80BD40686C3000F0CC -:109A5000FDB84FF6FF70F5F7C5B901460020FEF7D7 -:109A600037B9FBF7A3FFF6F76AFD0222E1F714BA54 -:109A70000122E1F711BA0222F6F79EBC0122F6F7A5 -:109A80009BBC0021F1F744B9002101757047002209 -:109A9000EEF748BC80F3118870470122E2F772BFED -:109AA0000022E2F76FBF6FF00100704703689B6808 -:109AB00018470268D26810475846FFF7EBBF2146A7 -:109AC000FAF7D8BB2046FFF7E5BFE81C00F0A8B8BE -:109AD000084600F0A7B8281D00F0A2B82846FDF7F8 -:109AE00087BEE81C00F09CB82846FFF7D3BF0123CF -:109AF000EAF77ABA0023EAF777BA40F8041B70470E -:109B0000D0E901100847000CFFF7C4BF01680968DD -:109B100008470268126910470168C96908470021AF -:109B2000018070470720F2F7A9BE0022FAF754BE61 -:109B30000022FAF751BE01680968084702681269F5 -:109B40001047013080B270470021EFF7ABBC032013 -:109B5000F9F7F4FF0620DDF78FB90220DDF78CB9A5 -:109B6000E920E8F7B9BD0846ECF744BE0846F7F728 -:109B7000A9BB0846FCF7ACBE0121F4F797BD08224B -:109B8000FFF706BB0021F8F789BBC0B2F2F75EB859 -:109B9000000AFCF783BC0021016070478069FFF771 -:109BA000E2BF8069FFF7E2BF8069FFF7E2BF80692B -:109BB00000F0A4B8FEF70AFCFCE70020F8F7F6BBBB -:109BC00001207047FEF7E6BB0A207047FCF724BC73 -:109BD000FCF738BC007D704781607047FEF781BF9D -:109BE000FFF7D0BFF8F79EBBF8F7BEBB0020704769 -:109BF000FEF7AABAFFF7A5BFEDF71CBAF1F7CABE88 -:109C0000F6F7B2BEF7F7A2BCE7F7CCBBFBF7B5BFE0 -:109C1000FBF7A4BCF9F788BBE5F72EBB0020704723 -:109C200000887047F7F74EBBECF7E4BDF1F7E8B8F2 -:109C3000F9F7A8BAFCF748BC00207047EAF712BE53 -:109C4000FBF758B980687047FDF772BCF4F740BC69 -:109C5000FEF702BCFEF756BEF6F75EBBF8F7A6BBF2 -:109C6000FCF786BCF4F7D4B8F5F7B2BEFDF760BFD9 -:109C7000F9F748BFF9F762B8E8F782BA00207047F1 -:109C8000002070470020704700207047F320704785 -:109C90000020704700207047DC207047DD207047AF -:109CA000002070470020704700207047C220704796 -:109CB000FCF7DCBCE5F7B8BEFFF77BBE01207047C0 -:109CC000F5F702BCFAF728BFFFF7A8B8DEF7B6BC75 -:109CD00000207047F8F75ABAECF792BBFAF73EBA91 -:109CE000FEF704BB0020704700207047002070473B -:109CF0000020704701207047002070470120704706 -:0C9D0000FFF75CB9DFF800F01D870310CE -:109D10005465726D696E6174696E672065786563FC -:109D20007574696F6E2E2E2E0A00464F52434544BD -:109D30000044454255474556540056454354424C0D -:109D400000556E6B6E6F776E004D53544B455252FB -:109D50003A20537461636B696E67204572726F724B -:109D6000202852442F5752206661696C6564292C63 -:109D700020537461636B2050757368004D554E53CA -:109D8000544B4552523A20556E737461636B696E41 -:109D900067204572726F72202852442F57522066F6 -:109DA00061696C6564292C20537461636B20506F6A -:109DB00070004441434356494F4C3A20446174611A -:109DC000204163636573732056696F6C6174696FBA -:109DD0006E202852442F5752206661696C656429B1 -:109DE000004941434356494F4C3A20496E737472BF -:109DF000756374696F6E2041636365737320566980 -:109E00006F6C6174696F6E0053544B4552523A2027 -:109E1000427573204661756C742063617573656467 -:109E200020627920537461636B205075736800550C -:109E30004E53544B4552523A204275732046617539 -:109E40006C7420636175736564206279205374615A -:109E5000636B20506F7000494D5052454349534544 -:109E600052523A2044656C617965642042757320D2 -:109E70004661756C742C206578616374206164643C -:109E80007220756E6B6E6F776E005052454349536A -:109E90004552523A20496D6D65646961746520428E -:109EA0007573204661756C742C206578616374202D -:109EB00061646472206B6E6F776E00494255534542 -:109EC00052523A20496E737472756374696F6E20D2 -:109ED0004163636573732056696F6C6174696F6E5B -:109EE00000554E444546494E5354523A20556E64EF -:109EF0006566696E656420696E73747275637469F2 -:109F00006F6E00494E5653544154453A20496E767F -:109F1000616C6964204550535220616E6420696E03 -:109F2000737472756374696F6E20636F6D62696EAE -:109F30006174696F6E00494E5650433A20496E76FF -:109F4000616C6964205043004E4F43503A20417485 -:109F500074656D7074696E6720746F207573652009 -:109F6000636F2D70726F636573736F720053544B20 -:109F70004F463A20537461636B206F766572666C4E -:109F80006F77206572726F7220686173206F6363F0 -:109F9000757272656400554E414C49474E45443ACE -:109FA00020556E616C69676E6564206D656D6F72BA -:109FB00079206163636573730044495642595A4579 -:109FC000524F0045585445524E414C00564341545F -:109FD0004348004457545452415000424B5054009F -:109FE00048414C54454400457863657074696F6E10 -:109FF00020233A00457863657074696F6E206F6343 -:10A0000063757272656420696E20495352207468CA -:10A0100072656164206174205043203D20307825B2 -:10A020003038782E0A00457863657074696F6E2049 -:10A030006F6363757272656420696E206261636B21 -:10A0400067726F756E6420746872656164206174F4 -:10A05000205043203D203078253038782E0A0042A9 -:10A060006F67757320457863657074696F6E2072D1 -:10A07000657475726E2076616C75653A202530388E -:10A08000782E0A005461736B005377690048776932 -:10A09000004D61696E006D61696E28290045786325 -:10A0A000657074696F6E206F63637572726564208A -:10A0B000696E20546872656164547970655F2573B8 -:10A0C0002E0A002573206E616D653A2025732C20C1 -:10A0D00068616E646C653A20307825782E0A002518 -:10A0E0007320737461636B20626173653A2030780A -:10A0F00025782E0A00257320737461636B207369C1 -:10A100007A653A20307825782E0A005230203D209A -:10A110003078253038782020523820203D20307883 -:10A12000253038780A005231203D203078253038EB -:10A13000782020523920203D203078253038780A88 -:10A14000005232203D20307825303878202052319E -:10A1500030203D203078253038780A005233203DB9 -:10A16000203078253038782020523131203D203081 -:10A1700078253038780A005234203D203078253058 -:10A1800038782020523132203D2030782530387800 -:10A190000A005235203D2030782530387820205371 -:10A1A000502852313329203D203078253038780A24 -:10A1B000005236203D2030782530387820204C520F -:10A1C0002852313429203D203078253038780A0053 -:10A1D0005237203D203078253038782020504328D1 -:10A1E00052313529203D203078253038780A00500A -:10A1F0005352203D203078253038780A00494353A7 -:10A2000052203D203078253038780A004D4D465395 -:10A2100052203D203078253032780A004246535291 -:10A22000203D203078253032780A005546535220A0 -:10A230003D203078253034780A0048465352203D7E -:10A24000203078253038780A0044465352203D208B -:10A250003078253038780A004D4D4152203D20306D -:10A2600078253038780A0042464152203D20307827 -:10A27000253038780A0041465352203D2030782559 -:10A280003038780A0074692E73797362696F732E9F -:10A290006B6E6C2E5461736B2E49646C65546173E4 -:10A2A0006B000A0069643A20307825782061303AE2 -:10A2B00020307825782061313A20307825780A00DE -:10A2C000286E756C6C2900303132333435363738AE -:10A2D00039616263646566004E414D4500457272A6 -:10A2E0006F72207261697365643A2000417373650F -:10A2F0007274206661696C65643A2000B087002042 -:10A3000064800020A88600207C81002000000000DE -:10A3100000840020B8870020D0840020B886002068 -:10A32000708200209CB7020074BB02000ABC0200CD -:10A3300090BB020082BB0200C88600204827002094 -:10A340001C2700200C2700201027002018270020A1 -:10A3500014270020042700200827002000270020C1 -:10A36000D8860020DC800020588600209C820020B7 -:10A37000FAB2020088B202006CB30200DEB302003F -:10A3800050B4020048BA0200D0BB0200C4BB0200B5 -:10A39000B388002058870020E0240020EC840020AF -:10A3A000C8230020A8880020A9880020B0810020B0 -:10A3B0006C860020641E00208F27002000B202005F -:10A3C000A0AC0200000000000000000064BB02001E -:10A3D000C478002084880020808800203427002052 -:10A3E0003027002040880020E0B60200D8850020F9 -:10A3F000887D00200000000000000000B42500203F -:10A40000000000000000000000000000000000004C -:10A41000E4220020487500202C270020014A031068 -:10A4200049480310D549031015470310415F010047 -:10A430005D49031081470310A1460310954803109E -:10A4400045450310254A031021440310ED4703102E -:10A4500099490310E1480310214903105553031093 -:10A4600089520310CD520310655003108D4E031016 -:10A47000856A0100A1B301000DD9010000000000B0 -:10A4800059510310ED50031029C10100CD4B0310A9 -:10A490002952031011530310A955031075550310C9 -:10A4A00069530310DD55031035550310695A010037 -:10A4B00021540310855C03100D5603104D5D0310ED -:10A4C000A9640310B55B03106D570310E561031019 -:10A4D000095E0310C55803108560031071610310F5 -:10A4E000B16203109963031055630310FD600310FC -:10A4F000B15E0310ED370100D55A0310D559031092 -:10A5000009630310D963031019640310555F031026 -:10A51000C56403104D620310716403108D64031051 -:10A5200055640310E1640310297503107972031058 -:10A53000A16B0310F57203109D740310797403105E -:10A540002D74031061730310FD7303105574031011 -:10A5500015750310D96C0310FD7403106D180100FC -:10A56000E17403103D75031051530100F9640310A9 -:10A57000CD6803102D710310C1740310F56E031024 -:10A58000B9730310B1B40000056E0310B1400100AF -:10A59000B5590100A1770310797D03103D7E0310AA -:10A5A00049750310157E0310357D0310997603104D -:10A5B000997C0310257B031071780310B57D03107F -:10A5C000ED7C0310857E03102D790310B97A0310FA -:10A5D000917B0310B1790310ED7B0310E97D03102B -:10A5E000617E0310357A0310D57E0310457C03107D -:10A5F000A57E0310BD7E0310BD380100D980031075 -:10A60000E97E031049830310898403108D810310B0 -:10A610007D820310E58403102B840310C58303108F -:10A62000918703106188031045880310F18503109A -:10A63000B18803107D880310C98803101D8703109B -:10A64000A186031001850310E18803109988031087 -:10A65000F987031079410100359C0310819D031097 -:10A66000E99A0310359B0310C19B0310419A031014 -:10A67000F18803101D8C0310618F0310F1940310F7 -:10A68000919E0310C19E03103D9E0310699E03100E -:10A69000259E0310619D03100D9E0310819B0310E6 -:10A6A000ED93031055990310C9970310D99803101F -:10A6B000BD950310959C0310C19D0310A59E03102A -:10A6C0007D9E0310C9910310D9A50100699C031058 -:10A6D000DD9D031095900310FD9B0310CD99031091 -:10A6E000D98B0200019D0310E19C0310219D0310F2 -:10A6F000419D0310BD9C0310F59D0310A19D031007 -:10A7000055980310E1920310999A0310B99E031013 -:10A71000559E031079390200F784020039A2031014 -:10A72000117C020069A1031075A20310C59E0310DD -:10A73000B9A10310F9A1031015A103109DA20310E4 -:10A7400089970200538F0100CD3A0200ED85020087 -:10A75000499502002D95010031A90310ADA2031007 -:10A76000BDE40000B9A8031099A503108586010077 -:10A7700039A803106DA90310315601006DAC031008 -:10A7800099B1031009AF031059B1031001B10310BF -:10A790009DA90310A19C02009D9C02008D9C0200BB -:10A7A000819C0200959C0200999C0200859C0200FD -:10A7B000919C0200A59C0200A99C0200899C0200B9 -:10A7C000F1B9031075BA031081BB03109541020063 -:10A7D00045800100C9D0010019460100BD2B0200CF -:10A7E00051E301008D620200A9D80100514C020022 -:10A7F000796B0200CD8A0200B1E30100DD0D020099 -:10A80000DD9C0200854C020029B301002D88020066 -:10A8100065BB01003D26020045880200E59C020060 -:10A82000ED9C0200719B00000DDA0000E9C60310E8 -:10A83000E99C0200815E0000ED9B020005390200E8 -:10A84000A18A0200C12002004F9B0200878F0200F4 -:10A85000C58B0200AD9C0200910D020065850100D0 -:10A86000897E0100614000218D4000219940002136 -:10A87000FF4000216F410021074C657900F009F885 -:10A8800061796940490703D50121044A89031160B0 -:10A8900070BD70B5024908478003002108110440CB -:10A8A0002D59000000F00AF800480047577F0000CB -:10A8B00000F00AF8004800471B880000806B0C4934 -:10A8C0000007000F48717047094A0A491823507958 -:10A8D000CB56497EC018814201DD084602E00F28B0 -:10A8E00000DD0F20D189090909010143D181704799 -:10A8F000E00200218800002110B53348314C804728 -:10A90000012807D02034217D002903D101212F4ABD -:10A910000905916010BD072801D02D4A10472D4A26 -:10A920004A60C872704701222C4B02212A481847FE -:10A93000274810B5F83080472948406A00280DD1D3 -:10A9400028490A200856002809DA401C07D0084682 -:10A950002038406A2449884200D1804710BDFFF763 -:10A96000E2FF10BD0021224B204A08461847012073 -:10A970002049400208602048FB2201781140017004 -:10A9800013480C30004710B51C4988471549203939 -:10A99000012807D0020404D5002008851848486221 -:10A9A000012010BD4A6A0A4B0C339A4201D1154A64 -:10A9B00005E00B494A6A144B9A42F2D1134A4A62A3 -:10A9C00010BD00006001002175A6020000110440C6 -:10A9D000A9910200E1400021060800009F06000046 -:10A9E0000801002154010021639202001941002155 -:10A9F000B5B4020080E100E080030021F796020078 -:10AA00000F41002157410021699502004D4100216D -:10AA10008F000100DC27002087000100182600209D -:10AA200035002800F082002028000100C527002002 -:10AA300029000100C6270020840004006C270020A4 -:10AA400086000100D92200202A000100D82700201A -:10AA50002B000100C32700202C000100D22700207A -:10AA60002D000800192600202E000100C427002018 -:10AA70002F000100CF27002030000100B727002061 -:10AA800032000100BD27002033000100BC27002058 -:10AA900034000100BF27002036000100BE2700203F -:10AAA00038000100CE27002039000100D127002006 -:10AAB000830002008027002063000100D0270020CF -:10AAC00065000100D72700206D000100C488002028 -:10AAD00071000800AC26002066000100B2270020AB -:10AAE00043000100B6270020440002007C2700201C -:10AAF00045000100B0270020460002007827002012 -:10AB000047000800B426002048000100B4270020B8 -:10AB10004B000100B327002004000100D9270020CA -:10AB2000A1000100D627002037000100CB2700201C -:10AB300088000100CA2700203C000100D327002024 -:10AB40003D000100C92700204900020082270020A3 -:10AB500067000100B12700204D0002007E27002081 -:10AB60004E000100B52700204F0002007A27002088 -:10AB70003E000100BA27002051000100CC27002030 -:10AB800052000100C827002053000100C227002006 -:10AB900054000100C0270020000000000000000059 -:10ABA0000097B92EE5725CCB5DCAE473B82F0196AD -:10ABB000BA2D03945FC8E671E7705EC90295BB2C9D -:10ABC000E3745ACD0691BF28BE2907905BCCE2758D -:10ABD00059CEE077BC2B05920493BD2AE17658CF7D -:10ABE00051C6E87FB4230D9A0C9BB522E97E50C76D -:10ABF000EB7C52C50E99B720B6210F9853C4EA7D5D -:10AC0000B2250B9C57C0EE79EF7856C10A9DB3244C -:10AC1000089FB126ED7A54C355C2EC7BB027099E3C -:10AC2000A2351B8C47D0FE69FF6846D11A8DA3342C -:10AC3000188FA136FD6A44D345D2FC6BA037198E1C -:10AC400041D6F86FA4331D8A1C8BA532F96E40D70C -:10AC5000FB6C42D51E89A730A6311F8843D4FA6DFC -:10AC6000F3644ADD1681AF38AE3917804BDCF265EC -:10AC700049DEF067AC3B15821483AD3AF16648DFDC -:10AC80001087A93EF5624CDB4DDAF463A83F1186CC -:10AC9000AA3D13844FD8F661F7604ED91285AB3CBC -:10ACA000000136360101000102010001030100012B -:10ACB00004010606080400000C0100340D01000F19 -:10ACC00010040101140100FF16080000200200001A -:10ACD000220100FF23010001240100FE25010008DC -:10ACE0002602000028010001290100012A020000BB -:10ACF0002C01000F2E02000030010001310100087C -:10AD0000320200FF34010007350102FF3601000066 -:10AD10003701000138010001390100FF3A01000F3D -:10AD20003C0200FF3E01010F3F0100014001041FF2 -:10AD300041010001420100FF43010080440800007E -:10AD40004E0100084F01000F50010001510100FFAA -:10AD5000520100005301000054010001580400009A -:10AD60005C0400006004000064040000680400004B -:10AD70006C040000700400007404000078040000FB -:10AD80007C040000800100FF8101000182010001BC -:10AD90008301020284010001A4270020B88800205A -:10ADA000BD8800208C270020AA880020A127002031 -:10ADB0009F2700209597020061A00000B78A02003B -:10ADC00061620200356202002DED010071F40100A4 -:10ADD000450D02001D180200296B0200814B020084 -:10ADE00059610200B99C0200ED8B0200D9050200F6 -:10ADF000B14A0200016B020085610200F58D02007C -:10AE0000817302001D4C020001640100117B0100EE -:10AE1000053B0200D1EC0100890102006F940200A1 -:10AE20007D94020000000000317C0200A7AB01000D -:10AE300035AA01007D40020000000000DD61020033 -:10AE4000A197020005420200318E020000000000BE -:10AE50000000000035C40000D17B0200250602007E -:10AE6000610C02001300000081C100001F000000FF -:10AE70005D2A01001F800000ED320200000000008A -:10AE8000A17A000001000000A17A00000200000089 -:10AE90008592010002800000634801000300000069 -:10AEA000BD3E0200040000000D930100048000007C -:10AEB0004F6101000500000095150200060000002A -:10AEC000A57800003000000061F2010031000000B0 -:10AED000656C000032000000A56601003300000030 -:10AEE0005565010034000000FD65010036000000DA -:10AEF0002DCA010011000000E9000200140000004A -:10AF00009593010015000000DD480200FFFF0000DE -:10AF10000000000068617264776172652065786383 -:10AF2000657074696F6E206964203D2025642C2053 -:10AF30007063203D2030782530387820282F4170EC -:10AF4000706C69636174696F6E732F74692F7369B4 -:10AF50006D706C656C696E6B5F6363313378785FBD -:10AF60006363323678785F73646B5F375F31305F6D -:10AF700030305F39382F6B65726E656C2F74697273 -:10AF8000746F73372F7061636B616765732F7469BA -:10AF90002F73797362696F732F66616D696C792F96 -:10AFA00061726D2F6D332F4877692E633A313039D6 -:10AFB00032290048776920616C7265616479206488 -:10AFC0006566696E65643A20696E74722320256433 -:10AFD00020282F4170706C69636174696F6E732FE4 -:10AFE00074692F73696D706C656C696E6B5F6363F8 -:10AFF000313378785F6363323678785F73646B5F80 -:10B00000375F31305F30305F39382F6B65726E6576 -:10B010006C2F746972746F73372F7061636B616723 -:10B0200065732F74692F73797362696F732F66610B -:10B030006D696C792F61726D2F6D332F4877692E92 -:10B04000633A33383529006E6F204953522C2069FA -:10B0500064203D2025642C207063203D203078251D -:10B0600030387820282F4170706C69636174696F83 -:10B070006E732F74692F73696D706C656C696E6B7C -:10B080005F6363313378785F6363323678785F73F8 -:10B09000646B5F375F31305F30305F39382F6B65FD -:10B0A000726E656C2F746972746F73372F70616381 -:10B0B0006B616765732F74692F73797362696F733E -:10B0C0002F66616D696C792F61726D2F6D332F481A -:10B0D00077692E633A3130393529006F7574206FE6 -:10B0E00066206D656D6F72793A20686561703D30DC -:10B0F0007825782C2073697A653D257520282F41A5 -:10B1000070706C69636174696F6E732F74692F73EB -:10B11000696D706C656C696E6B5F636331337878F1 -:10B120005F6363323678785F73646B5F375F3130AB -:10B130005F30305F39382F6B65726E656C2F7469C4 -:10B1400072746F73372F7061636B616765732F74EF -:10B15000692F73797362696F732F72756E74696D7D -:10B16000652F4D656D6F72792E633A373829006906 -:10B170006E746E756D3A202564206973206F757446 -:10B18000206F662072616E676520282F4170706C99 -:10B1900069636174696F6E732F74692F73696D7061 -:10B1A0006C656C696E6B5F6363313378785F636382 -:10B1B000323678785F73646B5F375F31305F303081 -:10B1C0005F39382F6B65726E656C2F746972746F9E -:10B1D00073372F7061636B616765732F74692F73A9 -:10B1E000797362696F732F66616D696C792F617213 -:10B1F0006D2F6D332F4877692E633A333737290027 -:10B20000360001000600000000000000000F0000F2 -:10B21000000000000000000000000000000003002B -:10B22000FFFF00000403FFFF0000FFFF0F00E80323 -:10B230000005401F0310000100000000FF3F0F0049 -:10B240000800050B00000000000000000300010FD3 -:10B2500000000000000000000000000000000000EE -:10B2600000000000000000000000000000000000DE -:10B2700000000000000000000000000000000000CE -:10B28000AD00000200000000010171010101010197 -:10B2900011010101310101010101800100011001D1 -:10B2A00061013B00140063017301720162014301FB -:10B2B0000001130106013D013500040112010001E6 -:10B2C00000010001000104010401330133013C01CC -:10B2D0004401320136000001000165010001350022 -:10B2E0008101000105018201830100016601000165 -:10B2F0000001080109010A010B010300710030017E -:10B30000600011007000310220035004800007002B -:10B3100010006100000014006300730072006200FE -:10B3200043000000130006000000000004001200AB -:10B330000000000000000000040004003700370097 -:10B340003C02440000000000000000006500000016 -:10B350003500810000000500000083000000660049 -:10B3600000000000080009000A000B00030271023F -:10B370003001600211027002010202020202800228 -:10B380000002100261023A0041006302730272027D -:10B3900062024302000213023800000200020402AB -:10B3A000120200020002000200020402040237003E -:10B3B00037003C024402000239000002000265022C -:10B3C00000023502810200020502820283020002AD -:10B3D000660200020002080209020A020B020103CF -:10B3E00071030103010301030103010322030203AB -:10B3F0000103000310030003000300030003000324 -:10B4000000030003420300032403060300030003B8 -:10B410000403120325032303250323030403040366 -:10B42000000300030003440300030003230300039D -:10B4300065032100350381030003050300030003B6 -:10B440000003000325032303080309030A030B0376 -:10B450000304710402046004110470040204020471 -:10B4600001040204000410046104000414046304D1 -:10B470007304720462044304000413040604000409 -:10B480000004040412040004000400040004510435 -:10B4900064000004000400044404000400040004E8 -:10B4A00000046504000435048104640005040004FC -:10B4B00083040004660400040004080409040A0468 -:10B4C0000B040E004F990200079B0200299C02000A -:10B4D000259C020031800200BD8F0200B59402005D -:10B4E00069700200657E0200F36D0200F9680200D7 -:10B4F000BD2702007D530200A98402004DEA01002D -:10B50000A9F00100F9BE010051E001008B94020096 -:10B5100089760200CD9B0200E19D01008196020028 -:10B52000FD6E0200AB8F02007F9B0200AB76020033 -:10B5300001000000A1560000060000006BE70100BA -:10B5400008000000358801000B0000003D190200D2 -:10B5500010000000753001000A000000E1A10100A8 -:10B56000020000001DD500000500000025CC0000F1 -:10B570000700000011E401000C000000A5760000A7 -:10B580000D000000610C00006400000051DD0100AE -:10B59000FF0000000000000000B000403400000088 -:10B5A000FF00000060830020200000008083002056 -:10B5B00020000000000000000C0000000D00000052 -:10B5C000FF000000FF00000060180020501800205D -:10B5D00040000000200000001300000014000000E4 -:10B5E000130000001500000016000000000200001B -:10B5F00052616E646F6D5F736565644175746F6DE4 -:10B60000617469632829206661696C65640041453D -:10B610005343434D206F70656E206661696C6564AD -:10B6200000414553454342206F70656E2066616955 -:10B630006C65640054524E47206F70656E206661E1 -:10B64000696C656400058E0000008E0001008E00AC -:10B6500002008E0003008F0000018F0000028F00A7 -:10B6600000038E0001048E0000058E0008048E0089 -:10B67000000489000006500000007F0001003F0028 -:10B6800004003F0002003F0001007F0002008E0026 -:10B6900002048E0001028E00010100060286821E55 -:10B6A0000128000000000000000000000001003040 -:10B6B00000000000000000000003FF18640000000C -:10B6C0000000000000000000785634120000000066 -:10B6D000BAAB000000000001000000000000000004 -:10B6E000C003000080070000000F0000001E0000E3 -:10B6F000003C00000078000000F0000000E00100C5 -:10B7000000C003000080070000000F0000001E00C2 -:10B7100000003C00000078000000F0000000F00095 -:10B720000000004017FF0000000000000400FFFFC1 -:10B730000800000010000000401800203018002011 -:10B74000401A0020301A00200A0000000900000002 -:10B750000C0000000B00000009080AFF0A000000AE -:10B760000A000000020000000400000008000000C1 -:10B7700010000000200000004000000080000000D9 -:10B7800000010000000200000004000000080000AA -:10B790000010000000200000004000000000000039 -:10B7A00002000000020000000A0000000200000089 -:10B7B0000200010000000000000000000000000086 -:10B7C0000000000000000000000000000000000079 -:10B7D0000E000000F3990200A79A0200BD52020079 -:10B7E00011790200A10702009586020069AF0100ED -:10B7F000ED07020009960200A1020100619D01000F -:10B8000095E90100ED5202001B8F0200C53C0200C9 -:10B81000AD86020081FF0000F9FF010015960200CD -:10B8200025C0000000000000000000000000000033 -:10B830000000000000000000000000000000000008 -:10B8400000000000000000000000000000000000F8 -:10B850000060250000100000A87F002040000000CC -:10B86000000000000000000000093D00140000007E -:10B87000640000005DD600001D9D00001D4000001A -:10B88000DD530000E543000099D70000414E000061 -:10B8900045840100BD210000995201000000000014 -:10B8A0000000000000000000000000000000000098 -:10B8B0000100000000C201000300000000000000C1 -:10B8C0000000000000000000000000000100000077 -:10B8D0000000000000020000000000000000000066 -:10B8E00001000000022C0000000000000000000029 -:10B8F0000000000000000000000000000000000048 -:10B90000000000000208000000000000000000002D -:10B91000000101000800FFFF0C260020A0240020E9 -:10B920008824002000000000FFFFFFFF000000004F -:10B930000000000040420F0008000000000000006E -:10B9400000000000080000000800000008000000DF -:10B9500008000000040000000200000001000000D8 -:10B9600001000000FFFFFFFF0000000000000000DA -:10B97000000000003A013A01000000000000000051 -:10B98000000000000000000000000000E8030000CC -:10B9900000000000000000000000000000000000A7 -:10B9A000D4B70200BA8800206CBC0200FCB70200C9 -:10B9B000648700204CB802000100000040420F00E4 -:10B9C0000100000000000000000000000000000076 -:10B9D00003080000000000000000000000016509ED -:10B9E0000000000000000000012C0000000000002A -:10B9F000000000000001001E000000000000000028 -:10BA000049B101007D29010077990200F1A90000E8 -:10BA10001551000001820100038000C0038000D5A1 -:10BA2000038000CC038000DD0380000C0380005DF8 -:10BA30000000000002000000010000000300000000 -:10BA4000100000002000000000000500BD00B7004D -:10BA5000B100BC001C0030003800080038010200B2 -:10BA600000000000000000000100000000000000D5 -:10BA7000E0000000010000005B41737365727420F8 -:10BA8000526561736F6E5D20307825303258000248 -:10BA90000000000099570100C58602000101010065 -:10BAA00000000000032C0000000000000000000067 -:10BAB0000000000000000000020000000000000084 -:10BAC00000000000FFFFFFFF00000000000000007A -:10BAD0000000000000000000050000000000000061 -:10BAE000001610000018151002000224145800005F -:10BAF000100000020200000000000000FFFFFFFF36 -:10BB0000000000000200000000000000FFFFFFFF37 -:10BB100000000000E81D0020D07900204C7A0020B1 -:10BB2000FFFFFFFF0C78002096BC02006878002021 -:10BB300098BC0200000000000000000000000000AF -:10BB4000000000005A6967426565416C6C69616E6E -:10BB500063653039D0D1D2D3D4D5D6D7D8D9DADBB2 -:10BB6000DCDDDEDF88B22400881300001000000056 -:10BB70000000000100A6AAACA4A9A9A399B19ABC8F -:10BB8000B6A8313118191A22311C1E203131343136 -:10BB9000313117191A21241B1D1F313133317F0018 -:10BBA000FF0000000000000000010000FF00010095 -:10BBB000C38402000700000000BA0200487400209D -:10BBC00020B702000C0E020B040B0A070800110F2D -:10BBD000000120181A18182C34041E000000000060 -:10BBE0000000000000000000000000000000000055 -:10BBF00000000000FF0000000000000080A903001A -:10BC000002010207016BB1340100020402010101CB -:10BC100001090201782100207C210020C08500203C -:10BC2000CBBC0200C8820020CCBC0200E8030000AC -:10BC3000000064004C790020F4BB0200DC6B0020A3 -:10BC400098B502002084002084BC02000102000399 -:10BC50000200010300BE020800BE040AFFFFFFFF4E -:10BC6000FFFFFFFF000800040002000100000500C4 -:10BC700000600000DDA20200ECA20200794902008F -:10BC8000DD860200000002400929FF0000081018AC -:10BC900020000102030406010701F4010000000076 -:10BCA000220001004400010000204060E803000081 -:10BCB00088130000200000007C1F00208813200053 -:10BCC000000000002800C800000801402001080F03 -:10BCD000030C1E040A3205050808FA0CFF040001D3 -:08BCE0004503011E483033004A -:10BCE8004D59000039E1000000000000000000008C -:10BCF800000000000D870200658C020049980100D1 -:10BD0800C9960200319B02002B9B02005F8A020049 -:10BD1800000000001F9B02004DA701007DF90100F3 -:10BD2800317A0200C59701003F8F0200BD2E010045 -:10BD38007982000011C80100917A02000000000019 -:10BD4800D51D0200F5860200556E0100258B020004 -:10BD5800E18F0200D1940200D18F02009198020075 -:10BD6800719A02006B9A0200398B0200019002005E -:10BD780011930200F18F0200DD9402007D9A020007 -:10BD8800779A02003195020025950200842500204B -:10BD98004C1D002004B90200D0B90200E8B9020025 -:10BDA800A0B60200E4B80200A4BA02000000000035 -:08BDB800000000000000000083 -:10BDC00001E500000FA1020100BF0514BF027D9C28 -:10BDD000023F001D370100F1007016B5FFECC604EC -:10BDE0000000EEC806EF0000F1CA0040F4CC0A6F74 -:10BDF0000000F6CF0040F7D00090FFFAD41000000A -:10BE0000FBD612DF0000FD931819E05328FA071043 -:10BE10005600400259320000FF035D380000046301 -:10BE20004EFF0000051772000006FF2A4F1480071E -:10BE30005F2814FF80085A331080095FFF3F10808D -:10BE40000A664F1080FF0BCB2130800CCC27FF3FC0 -:10BE5000800DCDC33F800EFFD6271B800FDA2F1B2E -:10BE6000FF8010DE391B8011E5FF4F1B8012E04779 -:10BE70003080FF13E2613F8014F575BF3F807FFF84 -:10BE8000FF3F0CEF04021D6022500400200031002F -:10BE9000B000727E00B400022000200101718140D8 -:10BEA00000340131003801B2013C0239003108058B -:10BEB00070003528CFC6016CDC1FC73700FD033783 -:10BEC0004441050200A585E50215A02726FF0C27A1 -:10BED000051B00207B3477127F2CC81F0020003107 -:10BEE000163F717C881737E0017000312CFF022368 -:10BEF000108219BF4834B134F80130A0492F9F0196 -:10BF0000FFC1FD0100E8BC02009B54BD3E33696CDB -:10BF10001EEA562F9701B57D1B60D7BD3B00003D43 -:10BF200061C4DB7515625F0CA574645F04ADDD3F11 -:10BF30000000382200200031527F06254025B05CE9 -:10BF4000023000316400345A0F3B3E6E0F06080089 -:10BF500000FFFF54F058A0E10F3938006FB202170C -:10BF6000EF12877F262BD4D7FFFD0307C2018387FB -:10BF700003FF00C3060201A86001FE1C70FFFF2B37 -:10BF80005EC80103BF073205838700017105B20156 -:10BF9000700401718DFF16FAB279F7DEADB33BFF85 -:10BFA00014FEFE93DF2C14000C01AC2930864901ED -:10BFB0000C99D780874485E51945BB995C3835BE17 -:10BFC0006080007532001002641001007D9EAF2F6A -:10BFD000FC167116B183880F00D388FDF317720029 -:10BFE000012345678967ABCDEF037F0AA6440503AC -:10BFF000219F28FFDD7D002019780100F53994F09C -:10C000000B9200542500202B942600339C0034A46E -:10C010000034083F05E9FF8C30AEE880AFAE87748E -:10C02000012C0032B13F12A9B1B39F0EF00034B61B -:10C030001F18F3881325FC2D80803E05007FF40136 -:10C04000E803FFFFFE2CB173010383D1A200003C83 -:10C0500000A3F034A927A5D130BCC10F011ED10027 -:10C06000F0FF0102010A031E0103EF0101780175CF -:10C0700060030808DF020403090801E2FE057700F7 -:10C080000DFE8560E00102A7B00101FFF000000095 -:10C090000193020087CD0100C3940200000000005C -:10C0A0001000000000000000100000000000000070 -:10C0B0001000000000000000100000000000000060 -:10C0C0001000000000000000100000000000000050 -:10C0D000E56000000000000010000000000000000B -:10C0E000D8000000C0BD0200D81B00209CC0020088 -:10C0F000301A0020A4C0020030180020ACC002009A -:10C10000401A0020B4C0020040180020BCC0020049 -:10C1100050180020C4C0020060180020CCC00200EB -:10C12000E0270020D4C002000C010020DCC0020087 -:04C13000001B0020D0 -:020000040005F5 -:207FA800000080011000C0FFFDFF58003AC1F9F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 -:207FC800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC508FEC5FFFFFFFF00FFFFFF00C5C5FF97 -:187FE800000000FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 -:00000001FF +:1000000000200120F54E0200916C0200916C02006C +:10001000916C0200916C0200916C0200916C0200E4 +:10002000916C0200916C0200916C0200916C0200D4 +:0C003000916C0200916C020071F4000061 +:10003C002DE9F04F99B0054680780224532800F240 +:10004C00C785DFE810F054009900A800B800C8007C +:10005C00DA00EA000C011B01C5052A01380159011F +:10006C00C505C505C505C505C505C505C505C50534 +:10007C00C505C505C505C505C505C505C505C50524 +:10008C00C505C505C505650188019401A001AB0135 +:10009C00BA01D401EB0107023A02C505C505C50535 +:1000AC00C505C505C505600276028C02A202B80220 +:1000BC00CD02DE020303C505C505C505C505C5058D +:1000CC00C50538034C036003C5056D037703950321 +:1000DC009E03AA03B603C503CF03F2030F04340433 +:1000EC003C044E045B0467048B0492049504EC1CE2 +:1000FC00E97A2A7B002320461EF094F88DF818002C +:10010C0006AB65200021012222F0B2FADFF8180BB1 +:10011C000078012800F25B85204629F0ACFC002811 +:10012C0000F0558505460079012840F0508529F0EE +:10013C0035FA00274FF400018DF83F008DF8380098 +:10014C00000ACDF83A108DF841708DF83E708DF89C +:10015C0040008DF839000EAE214606F10A0029F058 +:10016C0008FD297815223346017069788770417033 +:10017C004520FF2100F029BD29F0ADFC6979AA7951 +:10018C000023002425F0FCF98DF838000EAB652017 +:10019C00012100F053BC29F043FA29F0B9FB0146C8 +:1001AC000EA8022229F043FC8DF8180006AB65203E +:1001BC00022100F043BC29F033FA29F0A9FB0146D7 +:1001CC000EA8032229F033FC8DF8180006AB65202D +:1001DC00032100F033BC29F023FA29F099FBEA79CA +:1001EC0001460EA80023002427F058F88DF81800BB +:1001FC0006AB6520042100F021BC29F011FA29F08E +:10020C0087FB01460EA8052229F011FC8DF8180079 +:10021C0006AB6520052100F011BC0020DFF8304A48 +:10022C0029F0E0F8ADF85800681DA0478046E81D9D +:10023C00A04795F809B0824605F10A07BBF1100FEB +:10024C0000F2AE830EAC5E46002E00F0AC83384656 +:10025C0029F0E0FC24F8020B013E0237F4E729F008 +:10026C00DFF929F055FB01460EA8102229F0DFFB1F +:10027C008DF8180006AB65200721DFE329F0D0F9D3 +:10028C0029F046FB01460EA8112229F0D0FB8DF86F +:10029C00180006AB65200821D0E329F01CFC6A7B12 +:1002AC00691D0023002423F01FFE8DF838000EABCF +:1002BC0065200A21C2E302208DF8200029F00BFCF6 +:1002CC00ADF81800681D29F0A5FCEA79064605F181 +:1002DC0008018DF838200EAF781C28F053FF06A8C3 +:1002EC0031463A460023002420F084FB8DF8580058 +:1002FC0016AB65200B21A1E329F0EDFB00210024B6 +:10030C0023F048F88DF838000EAB65200C2195E3EE +:10031C000020DFF83C4929F065F8ADF85800681D5D +:10032C00A047804695F80F9005F11000A04705F105 +:10033C001304AD7C83460F2D00F247830EAE2F467F +:10034C00002F00F04583204629F064FC26F8020BB0 +:10035C00013F0234F4E729F063F929F04AF828F058 +:10036C0001FF40F0468306A829F003FC46E329F080 +:10037C0057F929F03EF828F0F5FE40F04D8306A819 +:10038C0029F0F7FB4DE329F0A6FB29F09EFA8DF836 +:10039C0038000EAB6520232100F016BCDFF888185E +:1003AC00C8208DF81800E81C0978002900F081831A +:1003BC0028F065FB8DF81800A3E36879EE1CFE2885 +:1003CC000BD1A879FF2808D12878082805D3304606 +:1003DC0029F020FC314625F0FBFA0EA9304628F016 +:1003EC0043F8002800F09183054600249FE3E81CA5 +:1003FC00042126F08DF8E97929F02EFCDFF8441859 +:10040C008DF83800022028F063FCDFF83C1803203C +:10041C0028F05EFC0EAB65202621D5E329F055FBB8 +:10042C00044605F10E0029F0F5FB297C6A7C034695 +:10043C00E878CDE90012AA1D214625F053FDDFF81E +:10044C0000188DF83800042028F042FC0EAB652013 +:10045C002721B9E34FF00208E81C8DF8408029F001 +:10046C00D9FBADF8380068798DF85800A81D29F033 +:10047C00D1FB2E7A044600270935CDE9005716A882 +:10048C000EA92246334621F0C7F829F0E7F810D11F +:10049C00DFF890078DF84080CDE9005722463346AF +:1004AC00C08AADF8380016A80EA921F0B5F88DF861 +:1004BC00180006AB6520282186E30226E81C8DF87F +:1004CC00406029F0A7FB29F023FAED7904460EA829 +:1004DC00002321462A4627F069FE29F0BFF80ED1E9 +:1004EC00DFF840078DF8406021462A460023C08A79 +:1004FC00ADF838000EA827F059FE8DF8180006ABA1 +:10050C006520292160E329F08BF8ADF83800681DCF +:10051C00042125F0FDFF6A7AAB7A00240146009491 +:10052C000EA825F00BFD8DF8180006AB65203021C8 +:10053C0084E229F075F829F0CDF9312201238DF8E8 +:10054C00580016A8CDE90004DFF8F0060EA921F03A +:10055C0063F88DF8180006AB652031216EE229F0A6 +:10056C005FF829F0B7F9322201238DF8580016A84C +:10057C00CDE90004DFF8C4060EA921F04DF88DF882 +:10058C00180006AB6520322158E229F049F829F011 +:10059C00A1F9332201238DF8580016A8CDE90004E7 +:1005AC00DFF898060EA921F037F88DF8180006AB85 +:1005BC006520332142E229F033F8ADF83800687B2E +:1005CC000024691D0094C0F3400200F001030EA842 +:1005DC0022F0C2FE8DF8180006AB652034212DE206 +:1005EC0029F01EF86A7BADF83800691D0EA80023AF +:1005FC00002426F0F3F98DF8180006AB65203521A0 +:10060C001CE22C4614F8030B04281ABFE8782C1DA6 +:10061C0002208DF84000204629F0FCFADFF818661D +:10062C00A5780121E278ADF8380000230024317060 +:10063C000EA829461EF066FE8DF818002846347068 +:10064C0026F008FA06AB65203621F7E129F043FACB +:10065C00ADF83800687904218DF84000A81D25F00C +:10066C0057FF0446AE7AEF7A05F10C0029F0D2FA66 +:10067C00DFF8B0850546214632463B4628F08FFE12 +:10068C000EA820F0A5FF28F0E9FF10D1022021468A +:10069C0032463B468DF84000B8F81600ADF83800ED +:1006AC0028F07DFE0EA820F093FF8DF8180006AB05 +:1006BC006520372188E26C7829F00DFA0146DFF8C5 +:1006CC007405007820F070F98DF8380004F0E00023 +:1006DC00202840F07C820EAB65203E2174E26C78C1 +:1006EC0029F0F9F90146DFF84C05007821F07CFC83 +:1006FC008DF8380004F0E000202840F068820EAB42 +:10070C0065203F2160E200206C788DF83800DFF81E +:10071C0018050078411E022980F09481022095E191 +:10072C0029F0D9F929F0D1F88DF838000EAB6520F5 +:10073C00422149E2002006908DF83D00CDF83900A9 +:10074C00E81C06A926F0BCFD8DF83800069850B1BF +:10075C0028F02CFE81788DF83B10C1788DF83C1078 +:10076C0000798DF83D000EAB6520432106222CE26A +:10077C00E81C28F084F98DF838000EAB6520442174 +:10078C0022E229F0A8F96979AA790DF0BBFF8DF85E +:10079C0038000EAB6520452116E229F09CF96979E9 +:1007AC00AA791AF08FFC8DF838000EAB6520462123 +:1007BC000AE2EC7829F089F90146204622F080FE05 +:1007CC00B0FA80F0472140098DF838000EABC1E13A +:1007DC00E87800248DF8384023F0F6FB0EAB65204A +:1007EC0047212BE1E8780EA926F08EFD06468DF800 +:1007FC00180040000130C5B2284629F00FFA002835 +:10080C0000F0A381044600F8016B00219DF818202C +:10081C00914280F0BE809DF83830013100F8023BE7 +:10082C009DF8393000F8013CF2E70EAC132120465C +:10083C0028F044FBEE7829F048F90146304626F0C2 +:10084C0031F9002800F088810021231D8DF8381023 +:10085C0028F0ACFDC11C827818468DF83B2028F09E +:10086C0091FC7CE10020EC78CDF84600CDF84200FC +:10087C00CDF83E00CDF83A0029F027F9AA79ADF869 +:10088C0038000F2A28BF0F228DF83A2022B10EA86B +:10089C00E91D033028F076FC0EA9204601221CF03D +:1008AC00CBFF8DF8180006AB65204B218CE128F0AE +:1008BC0069FA8DF838000EAB65204C2184E1E8789C +:1008CC0029798DF838100EA9032800F05F810228D1 +:1008DC0000F06281012840F06681522021F0C8FBB3 +:1008EC0064E129F0F8F869790246A81D1BF054FA66 +:1008FC008DF838000EAB65204E2165E129F0EBF840 +:10090C000146687919F05AFF8DF838000EAB652056 +:10091C004F2159E1C34D0822E88A05F13901ADF8A0 +:10092C003800C24800788DF83A00A88CADF83B002E +:10093C00688BADF83D000EACE01D28F023FC04F1F3 +:10094C000F0005F11C01082228F01CFC287E502108 +:10095C00182223468DF84F00652036E1B248007806 +:10096C00002800F0018112200AE120F07DFD2EE12B +:10097C0000208DF83800E878010606D5A94910F05A +:10098C007F0018BF012081F868000EAB6520532151 +:10099C001AE1652049212A46234621F069FE39E1F6 +:1009AC0080208DF863003E78102E52D80DF1180976 +:1009BC00013734464D46002C4DD0384629F02AF9E3 +:1009CC0025F8020B013C0237F5E780208DF8630017 +:1009DC0027780F2F54D801340DF1180A3E46002EFB +:1009EC0050D0204629F016F92AF8020B013E0234A9 +:1009FC00F5E7084629F00EF9ADF81800687E06A94F +:100A0C0028F0B8FB0EA921201BF018FB8DF858001C +:100A1C0016AB6520212111E0084629F0FBF8ADF852 +:100A2C001800687E06A928F0A5FB0EA922201BF051 +:100A3C0005FB8DF8580016AB65202221012221F010 +:100A4C0017FEC5E0002840F0B580042008F002FE37 +:100A5C00B3E080200DE0BBF1100F0CD80EA90020E4 +:100A6C0052465B468DE84202039016A8414615F0AB +:100A7C0009FA8DF863000DF1630365200621A3E0EC +:100A8C0080200FE00F2D0FD80EA9002002974A46A8 +:100A9C005B46CDE9005106A9CDE9031016A84146E5 +:100AAC0015F098F98DF863000DF163036520202192 +:100ABC008AE016A90EAD2A4618F076FD04469DF87C +:100ACC005800F0B1614904EB4400002641F8206065 +:100ADC0001EB800046609DF94B00B0F1FF3F03DC59 +:100AEC0005F1130022F07CFF0EAD1421284628F0EE +:100AFC00E5F90420214614222B4625F05BFC8DF8E9 +:100B0C00186006AB652024215EE0182029F086F8D9 +:100B1C00002800F083800446BDF83800002118221C +:100B2C00234628F0B1F90546002818BFC82519201E +:100B3C0029F074F8002867D007460130002D4BD0FF +:100B4C001821FF2228F0B4F950E0002049218DF83B +:100B5C00180006AB652037E001208DF838000EAB8D +:100B6C0065204A21132230E028F0B5FF044605F138 +:100B7C000D0029F04FF80246691D204625F0F4F9C6 +:100B8C008DF838000EAB652051211DE0522021F06C +:100B9C006FFA2748002104E0522021F069FA24481A +:100BAC000121017002E0522025F036FA0EAB6520CF +:100BBC004D2109E001208DF8380004F0E0002028D8 +:100BCC0005D10EAB65204021012221F051FD0024FE +:100BDC00204619B0BDE8F08F3146082228F0D2FA31 +:100BEC0007F109002146102228F0CCFA65202521B6 +:100BFC0019223B463D7021F03BFD3846192128F067 +:100C0C005DF9384629F008F8002CE0D02046182170 +:100C1C0028F054F9204628F0FFFFD8E7C825FFF745 +:100C2C00E4BB00BF407B002018260020C426002017 +:100C3C00D527002096880020952700207C260020B0 +:100C4C0059680200CD6D0200494E0100804300201E +:100C5C00219C02002DE9F04F99B080466FF00700FF +:100C6C00DFF8DCA80630ADF852009AF80000022834 +:100C7C0014D1DFF8C808007880B9B8F8080010B1B2 +:100C8C001020012101E0302000210AF03FFE00205D +:100C9C008DF81C0007A9522021F0EAF90DF11C096E +:100CAC0098F80810D8F804004A4610F001FAE8B198 +:100CBC009DF81E609DF81F409DF82050BDF82670D1 +:100CCC0028F066FC844211D127F003004FF6F8712E +:100CDC0080B288420AD0012D08D8022E06D29AF88A +:100CEC000000022808D19DF84D0028B1D32016F041 +:100CFC000AF819B0BDE8F08FB8F82800ADF8480034 +:100D0C00B8F83200ADF82A009DF82200D0B1D8F81E +:100D1C0004109DF81D209DF83830012027F0E4F9CF +:100D2C0008B1CF20E3E7DFF81C08C078012809D10F +:100D3C00B8F8280028F04BFE20B1417901F0E7010A +:100D4C00083141719DF8210068B1BDF82610FF20D3 +:100D5C0025F0A8FE9DF82110E0B141F001012C26F0 +:100D6C008DF8211017E09DF83900002800F0EB8079 +:100D7C009DF83D10FF2902D0002940F02681DFF8B4 +:100D8C00C807BDF82620C18A8A4240F0278101207D +:100D9C00222607E0082601F00300012808BF46F0D0 +:100DAC00110601209AF800104FF6F877012908D89F +:100DBC003446B20758BF64F07F04002808BF34469D +:100DCC0000E034469DF82200DFF87C575FFA84FB84 +:100DDC0030B9E87A20B10BF02200222840F0808054 +:100DEC001BF0400004901CD0012903D8A87B80077D +:100DFC0000F1D880119801780C2900F2DB800122D7 +:100E0C0041F298438A401A4200F0D480032902D15F +:100E1C0040780D2805D007A822F036F901283FF4B8 +:100E2C0068AFA88CB8F8441081420AD198F84620D3 +:100E3C00B8F84210B8F8280000230093002307F0FC +:100E4C00E5FC9DF82200F8B1B8F84210B8F828007B +:100E5C0022F0EAFB002800F08F800646D8F8040048 +:100E6C009DF81D10F2780844417B8A421EBF002277 +:100E7C007260F1700130042125F04AFB71688842E0 +:100E8C00FFF437AF013070609AF80000022834D2BA +:100E9C00A87B80077FF52DAF9DF84D004FF6F876B7 +:100EAC0060B1BDF8280027F06BFB002800F007812B +:100EBC00D8F80400417801F0DF0141709DF82E0054 +:100ECC00002800F0DF80D8F80400817901398171A5 +:100EDC008DF82E1004F07F00090640F0D680D3E088 +:100EEC000BF0420042287FF41CAF1198007800F000 +:100EFC00FE0006287FF415AF72E77FF4FAAE95F882 +:100F0C002600092802D004287FF4F3AE5FEA8B6038 +:100F1C0000F19E80049800283FF4EBAE11989DF8E8 +:100F2C0038100078042808BF022900F045810728F2 +:100F3C0008BF042900F009810C2840F04D8107A856 +:100F4C0015F0AEFAD5E6BDF8260022F00DFE0238FB +:100F5C00DFF8F415B0FA80F0CA8A4109BDF8260012 +:100F6C00904208BF023100293FD09DF81E20002A74 +:100F7C0056D001F1400455E09DF84D00B8B3042063 +:100F8C0026F06CF800283FF4B4AE01464FF4B27072 +:100F9C000880B8F828004880DFF8B00500781EF00B +:100FAC007DF8A6E611980178A1F10C0212F10C0F54 +:100FBC003FF62CAFE88ABDF8262082427FF496AE2D +:100FCC00BDF8280024F02CF990E6109A9DF83C000E +:100FDC0020F060FF30B101200026E3E690F82600F7 +:100FEC000428F8D100260020DCE600241AE095F84D +:100FFC006C0001287FF448AF11980078062803D1C3 +:10100C00049800287FF440AFF81DBDF82A1080B278 +:10101C0081423FF46EAE07A841461EF0FFFA68E627 +:10102C0001F1200422F0A0FD0138B0FA80F0400953 +:10103C0044EA00069DF81E0000283FF4B2AE119859 +:10104C00007827F0F1FA012818BF04F07E06A8E614 +:10105C0098F8460028F080F99DF82E00012840F001 +:10106C00B480B8F82800BDF82810814240F0AD805B +:10107C00BDF8260022F078FD022804BF00208DF870 +:10108C002E00A2E004F07F000446210702D44FF0AA +:10109C00000A34E0E1B24A0722D4C9069DF82110B7 +:1010AC0028D5C1F3820212B1072A18BF013A002ACF +:1010BC0008BF044601F0E30040EA820118E0D320A7 +:1010CC0015F021FEDFF888040078002800F09F80DE +:1010DC00DFF8801451F82000C0EB0010810098E07C +:1010EC009DF8210000F0E00100F0E30040EAD1019E +:1010FC008DF82110D8F804004FF4805A017295F83D +:10110C002600092801D0042823D1E98ABDF826003D +:10111C0088420AD022F028FD022806D09DF8210032 +:10112C0000F0030001287FF4E4AD9DF81E000028B8 +:10113C0047D011989DF838100078042808BF022970 +:10114C003AD0072848D1042946D107A817F040FF08 +:10115C00CFE5E7B214F0610F46D0F80709D0B8F824 +:10116C00281007A8A94615F0E3FB002864D004F06A +:10117C009F040025E7B2A00609D598F84600D8F8D8 +:10118C003C2028F0E9F807A815A905F04DFC7806D5 +:10119C0040F12681B8F8281007A80DF152022B4611 +:1011AC0010F002F800286FD005461198007801283D +:1011BC0008BF4AF0100A13E107A9002010F068FFDD +:1011CC0097E598F8460028F0C7F8D8F83C2007A80F +:1011DC0015A905F029FC8CE503287FF48AAD07A836 +:1011EC0000210FF0EFFC84E59DF81E0001285AD178 +:1011FC0011980078032849D0052854D1B8F8281044 +:10120C0007A80DF1520200230FF0CEFF71E5D14873 +:10121C000168D1480268BDF82800904701287FF486 +:10122C0068ADCE480168BDF828008847CC480168F5 +:10123C00BDF8280088475CE526F0E4FA9DF82E10EE +:10124C000546BDF8280019B9B8F82810884291D085 +:10125C00B9F81610814204D1BA48807800283FF4BE +:10126C0089AFB8F8281007A82A4609F027FA0028F1 +:10127C0000F09B8038074AF0040ABDF8260048BFEE +:10128C00F01DADF8520075E70025A9E0BDF8260069 +:10129C0027F076F938B1B8F8281007A80DF15202EA +:1012AC0000230FF081FF9DF82E0088B323F066FD1C +:1012BC0000287FF41EAD9DF83900A0B3109A9DF85C +:1012CC003C009DF83D1020F0E5FD002870D09DF805 +:1012DC003D00002875D0109928F042FB9DF8243071 +:1012EC00ADF8520011209DF823209DF821104AF0F2 +:1012FC00400A002B08BF0920002A18BF083000291B +:10130C0018BF0130D8F804100A5C013A0A5462E0A4 +:10131C009DF81E0001287FF47EAE119800780328FA +:10132C003FF4E7AC77E69DF82010BDF826000029C5 +:10133C00ADF8520000F0D3804020BDF8261009F122 +:10134C001D0200EAC4059DF820002B4618F0C2FDD2 +:10135C0038B1D8F804004AF0200A017801F03F01B6 +:10136C0001709DF8390048B1BDF8261009F1200034 +:10137C0021F06CFE4AF0400AADF852009DF81E00B8 +:10138C00012806D0BDF82810BDF82600002214F064 +:10139C0085FFBDF82810BDF826002A4612F0BEFBCA +:1013AC00002818BF4AF0200A15E004F0DF04E0E63C +:1013BC00BDF82610BDF828000B2200231AF07AFC89 +:1013CC0097E4BDF82600ADF8520028F000FB002889 +:1013DC0008BF4AF0400A26F015FA05464FF6F87693 +:1013EC00B01DBDF8521080B20F1A5E4818BF2F46C0 +:1013FC000078012805D1F01DB8F8321080B2814276 +:10140C002FD160B2B0F1FF3F3FF773AC002F3FF428 +:10141C0070ACB8F8080028F001FC00283FF469AC67 +:10142C00B8F80820D8F80410054627F0ABFE9DF854 +:10143C001E10002098F80830B8F8282016908DF867 +:10144C005410BDF8521015ACCDE9007ACDE9020468 +:10145C00284610F0DDFB70B3284628F0DDFBFFF7C3 +:10146C0048BCB8F828108142CBD0701CBDF826209F +:10147C0080B28242C5D2BDF828008142C1D028F08A +:10148C00A6FA0028BDD0017901390129B9D84088C4 +:10149C0001218DF85410ADF8600015AD28461EF0F2 +:1014AC002DFD0028ADD0281D1DF0F0FC0028A8D083 +:1014BC0021F0DAFEA5E72348407800283FF419AC68 +:1014CC0000208DF81870ADF81900DDF826004FEAF1 +:1014DC003040059005A827F0CDFCFFF70ABC390772 +:1014EC003FF52AAF9DF81E1001293FF425AF0021CE +:1014FC0018F0B0FC20B1407901380228FFF41CAF81 +:10150C00B8F84410BDF8520022F08EF830B1807853 +:10151C0026F0B8FB01380728FFF40EAFBDF8280001 +:10152C0027F02EF818B104208DF8200004E7BDF840 +:10153C002610BDF8280002223FE700BFD527002067 +:10154C0018260020E8250020407B002098880020E9 +:10155C00C727002060B70200942300209C230020A2 +:10156C0098230020D32700202DE9F0438DB00546A9 +:10157C0080780224252800F27380DFE810F0260022 +:10158C00A400C400D700EA00F8000601B602B602B7 +:10159C001D012E01B602B602B602B602B602460113 +:1015AC004B01B602B602540158016101B602B602F3 +:1015BC00B602B602B602B602B602B602B6026B01AB +:1015CC006E017101740178017F01DFF8D47500247C +:1015DC000E258DF804403878012807D801A81DF095 +:1015EC00EDF804469DF8040005EB4005EEB23046DC +:1015FC0028F014FB002800F087824FF00008054605 +:10160C00431C0021082280F80080012027F03CFCBC +:10161C0027F0C4FF6872000A0721A872DFF884055E +:10162C00E972007828733878012800F262829DF8FC +:10163C000420002A6A7300F05E8205F10E0000217E +:10164C002346914280F0578213F8022B013100F8A7 +:10165C00022B13F8012C00F8012C9DF80420F0E764 +:10166C00A0F140010D291FD8DFE811F00E00100188 +:10167C003F023F021E012E013F023F023A0145018B +:10168C00500165013F02740101ACE91C0822201DC8 +:10169C0027F078FD204619F0E1FFBDF80600402147 +:1016AC00ADF828000AABEEE0632800F069816428ED +:1016BC0000F07681E02840F0188200244720E021D9 +:1016CC00002200230FE2202028F0A8FA002800F0C6 +:1016DC00C1812021FF22044627F0EAFB631C012074 +:1016EC000021082227F0D0FB0546002818BF012551 +:1016FC0001AB84200021042227F0C6FB002800F057 +:10170C000582023506E2E81C28F084FAADF80400E4 +:10171C00832028F09CF9014601AA832028F070F858 +:10172C008DF828000AAB6720022190E1E81C042107 +:10173C0024F0EEFE0190842028F089F9014601AADC +:10174C00842028F05DF88DF828000AAB672003216F +:10175C007DE1612028F07BF90146EA1C612028F02C +:10176C004FF88DF8040001AB672004216FE1622073 +:10177C0028F06DF90146EA1C622028F041F88DF83A +:10178C00040001AB6720052161E100208DF8040005 +:10179C00E81C28F03FFA6A7900F4F851002A00F0AE +:1017AC004981B1F5A06F04D04FF6FF71884240F02B +:1017BC004B814FF0FF3045E128F002FA044628F047 +:1017CC00FDF9D949604301ACB0FBF1F1204628F09A +:1017DC008EF9672009210422ABE0DFF8B4632D7980 +:1017EC00306840B901AC204627F09AFD0120214613 +:1017FC000EF028FA3060052D00F06981002D00F004 +:10180C006981642122F040F966E115F8032B672009 +:10181C0010216EE0E87823F093FD8DF8040001AB05 +:10182C006720112113E100246720142102E0002419 +:10183C0067201521ADF80840019401AB062252E156 +:10184C0000246720162109228DF80C40CDE90144B3 +:10185C0001AB48E1F52020210BE0F520212108E027 +:10186C00F520222105E04FF6F570232108E0F52044 +:10187C0024218DF8040001AB6720E8E0F520252138 +:10188C00ADF8040001AB67200222E1E0E81C28F06F +:10189C00C1F9ADF8060001AC204617F055FB231D2D +:1018AC00672041210822D3E0E81C0AA926F0DCFDC0 +:1018BC0000288DF8040000F0CF8001A81821FF2229 +:1018CC00013027F0F5FAF4E0E81C0AA926F0CCFD6B +:1018DC0000288DF8040000F0F1804FF0FF30EFE0AD +:1018EC0015F8030F697822F0B3F828806720482197 +:1018FC0002222B46ACE0E87824F058FF01AC0146FC +:10190C00204618F0E7FC6720492111E0EC1C20462A +:10191C0026F066FA002818BF2046B5F80B1019F00F +:10192C00F1F901AC0146204618F0D4FC67204A219D +:10193C00242223468CE001ACE91C0822204627F027 +:10194C0021FC204627F0D8F98DF828000AAB672037 +:10195C004B217CE04FF0FF3095F80380691D01901E +:10196C00ADF81000CDE90200FE208DF806002879B4 +:10197C0003288DF8300020D10AA828F0FAF821E0CD +:10198C000024E91C08228DF8284001AD284627F0D8 +:10199C00F9FB28461DF07AFA0AAB67206321A1E017 +:1019AC00B5F80B006A7B0024E91C8DF804400AF0A2 +:1019BC0067F801AB6720642194E0084628F02AF907 +:1019CC00ADF82800AF7B002F00F0DD807E0095F88D +:1019DC000D90304628F022F9002800F0D48005F153 +:1019EC000F013246044627F0CDFB00940AA940466D +:1019FC004A463B460DF0F8F9002800F0BA8083788F +:101A0C0001784278057946798DF806308DF8041006 +:101A1C008DF80520C3788DF809608DF808508DF885 +:101A2C00073001A98B1D811D40794200184627F013 +:101A3C00A9FBA5E0B1F5A06F03D04FF6FF7188426A +:101A4C0002D100205549086001AB67200621012214 +:101A5C0020F00EFE002448E0182028F0DFF840B3F8 +:101A6C00BDF828100446009006200022182324F00C +:101A7C008BFCB8B9BDF8285001AE21461022701C61 +:101A8C0027F080FB444F05EB450506F1110057F894 +:101A9C00251028F02CF807EB8500416806F115009D +:101AAC0028F025F82046182127F008FA204628F0BF +:101ABC00B3F801AB672044211922C9E7BDF828000F +:101ACC00ADF8050001AB672045210322C0E7314981 +:101ADC0001220A7021F08BF9002467200A218DF86D +:101AEC00044001AB012220F0C3FD20460DB0BDE83F +:101AFC00F08385F80D806720002132462B4620F0BC +:101B0C00B7FD284628F088F87CBBA3E7019800BAFB +:101B1C00C4F809000AAB83200021022227F0B4F993 +:101B2C0020B1043506E000BF40420F00BDF828008C +:101B3C00A4F80D0004F10F0361200021012227F00D +:101B4C00A3F9002818BF083504F110036220002106 +:101B5C00102227F099F9002818BF1035234625705C +:101B6C0067200121202220F083FD204628F054F824 +:101B7C0070E74FF6FF70ADF808006FF480300190FD +:101B8C00204628F049F801AB67204D210E225FE773 +:101B9C00248800209227002018830020048800202D +:101BAC0018260020C42600202DE9F04F85B084783B +:101BBC000226362C00F2BE820546DFE814F06C01DA +:101BCC00740172007C017800BB02BB0281003700FB +:101BDC004C008C009F00AD00BB02B5009001BB0215 +:101BEC00BB029A01AD01BB01BB02BB02BB02BB0233 +:101BFC00BB02BB02BB0237004C00BB02BB02BB02E8 +:101C0C00BB02BB02BB02BB02BB02BB02BB02BB02E0 +:101C1C00BB02BB02BB02BB02BB02BB02BB02BD00D0 +:101C2C00EB00CB01FF005B005B00DB0127F047FF03 +:101C3C00242840F0AA8102AB352000210422002484 +:101C4C0027F022F9002800F0FC81012002228DF8F7 +:101C5C0010000020FCE100208DF8100027F02FFF71 +:101C6C000646092C40F0ED8095F8059095F8068015 +:101C7C000720EFE0DFF82465306880B1406A70B16E +:101C8C0002A927F025FF0546342C40F02C8228466B +:101C9C0027F0C0FF002800F02582042041E2032039 +:101CAC003FE2DFF80835612002210A223FE202AC54 +:101CBC00E220214624F0B0F961200421082288E1B9 +:101CCC0027F0FDFE0446681D27F0A4FF242C40F0ED +:101CDC0087810020FBE1E878032800F29781281D1A +:101CEC0027F098FF0246E878DFF8B81431F81010A6 +:101CFC00DFF8B404007827F0F7FE88E1E8780328D1 +:101D0C0000F28981DFF89C1431F81010DFF8980488 +:101D1C0000781CF067FE7FE127F018FEADF8080094 +:101D2C0002AB61200C2103E1002661200E2101226F +:101D3C008DF8086002AB1BE2DFF8606401208DF8BF +:101D4C0010003068002800F02C810069002800F099 +:101D5C00288102A927F0BCFE042124F0D9FB00281D +:101D6C0000F0EC81044627F059FF002800F01C819C +:101D7C002146054627F0A2F83068BDF80C10224623 +:101D8C002B4606690298B0478DF81000284627F0BC +:101D9C0043FF09E1DFF804442068002800F00881C3 +:101DAC008069002800F0048102A927F091FE2068C8 +:101DBC00BDF80C10826902989047FAE0DFF8DC73EA +:101DCC003868002800F0FB80C069002800F0F7801C +:101DDC0002A927F07DFE9DF80850BDF80AB0BDF8A9 +:101DEC000C90044627F016FFA6788046F72E28BFE5 +:101DFC006FF00806B01C5FFA80FA504627F00EFF11 +:101E0C00002800F09D81012D044608BFBBF1000F96 +:101E1C0000F09A813868A11CF3B24246C569029859 +:101E2C0000914946A8470746002840F093810027B7 +:101E3C0061203321524623466670277020F018FC2F +:101E4C0088E1681D27F0E6FE8146E81D27F0E2FEDA +:101E5C008046092002AF242E18BF2F1808BF352644 +:101E6C00304609EB080527F0F2FD854201D9022026 +:101E7C0057E1B9F1000F04D1304641463A4622F001 +:101E8C0047FA304641463A4627F0BAFC002800F0A3 +:101E9C00E5800A2045E1E878012802D0002840F0CE +:101EAC00488127F0D7F940F259600121ADF80800BC +:101EBC0002AB61203CE00120EC1C8DF80800E22014 +:101ECC00214620F0D5F830B901200821224627F010 +:101EDC0097FC8DF8080002AB6120032126E1E8781D +:101EEC00291D012800F0E180002840F0E580E02069 +:101EFC00DFE027F0E4FD0446681D27F08BFE242C60 +:101F0C000FBF00200146204627F052FD8DF8080037 +:101F1C0002AB6120122109E127F0D1FD24280CBF6E +:101F2C00002027F094FDADF8080002AB61201321CE +:101F3C000222FCE0E8788DF8080099488068D0F817 +:101F4C00302402A9E02090478DF8100004AB6120EA +:101F5C001421EBE0914C206898B3806A88B302A9F5 +:101F6C0027F0B6FD2068BDF80C10826A02989047E5 +:101F7C00014627E0894C206868B3C06858B327F045 +:101F8C009EFD2168C968884726E08046693800268E +:101F9C0080B2032838BF0126681D082C40D1057873 +:101FAC0041E003208DF8100004AB61203021BDE02E +:101FBC0003208DF8100004AB61203121B6E003271B +:101FCC00CDE0002102AC204627F091FD61203221AA +:101FDC0004222346ABE0032027F095FC3621A5E034 +:101FEC0005F10806ED790146A8426CD9204600227D +:101FFC0027F000FC09288DF808006AD1002D68D064 +:10200C0020462946324627F0FBFB62E0022027F0EF +:10201C007AFC0A218AE0022027F075FC0B2185E06E +:10202C0027F0F8FD0546404627F011FD0227A8428F +:10203C0088BF7700CFB100268DF80870612021464B +:10204C0092E002988DF810400422ADF812000220A4 +:10205C008DF8110004AB6120082168E0012E62D1DB +:10206C00E220394620F004F85BE0471BB8B2F728B1 +:10207C0028BFF727B81CC6B2304627F0CFFD002882 +:10208C0060D01FFA87FB00F1020982464846594688 +:10209C0026F014FF404629465A464B4626F0F4FEDD +:1020AC000546002867D00A2770E00878022814D269 +:1020BC0052201FF0DDFF00E002208DF8080002AB7B +:1020CC0061200F2132E02046324627F093FB8DF839 +:1020DC00080002AB6120072128E002A9522023F05E +:1020EC009BFFECE702359DF8080015F8018BBDF855 +:1020FC000C7001280ED1BDF80A0058B9384641467B +:10210C002A4622F005F9012F04D1E22029461FF0BE +:10211C00AFFF01273068394642462B46466A029883 +:10212C00B0478DF8100004AB61202146012220F04D +:10213C009FFA0026304605B0BDE8F08F052031E748 +:10214C0010270CE0102776E7A9F169000328BFF4EB +:10215C0061AE0227204627F05FFD002FE9D0002654 +:10216C008DF80870612033218DF8096002AB0222D2 +:10217C0020F07EFADEE78AF8017000276120214604 +:10218C00324653468AF8007020F072FA504627F017 +:10219C0043FD002D7FF44FAFCBE700BF5C27002041 +:1021AC000C01002064BC02009688002000BC0200D8 +:1021BC002DE9F04F8FB00C4648070FD4200441D4C2 +:1021CC00E00400F19781200600F1C081A00700F126 +:1021DC00D481200500F1F3810020B4E1DFF8200563 +:1021EC000178062900F2AD81DFE811F007009401B7 +:1021FC00AB01AB019901AB01A001DFF81055DFF881 +:10220C0004152A7891F82B30022A02D19E0600F18F +:10221C0098815E0700F19D819B0740F19281042318 +:10222C00037091F82C30DB0700F08B8191F82E3085 +:10223C00002B00F0528225F03CFE0420012102F01C +:10224C00A3FA57E2DFF8C8040394DFF8BCB4DFF854 +:10225C00B094DFF8C474DFF8AC44DFF8B054DFF8A6 +:10226C00BCA448F20208008802909BF800001CF005 +:10227C00E7FB002800F03A8106460078D3282DD1E0 +:10228C00F089404540F019813878002800F015811C +:10229C0099F80000012840F0108126F0BBFE0028C0 +:1022AC0040F00B817088002840F00781A24604ACF6 +:1022BC001221204626F002FE27F0ACF930462146CA +:1022CC0018F02EFCBDF81C00B0F5285FC0F088801B +:1022DC00012002211FF078FA54462AE099F80010E8 +:1022EC00884217D1012834D0032840F0E6802878A2 +:1022FC000138012800F2E180B078012851D0002883 +:10230C0040F0DB807078002800F0BF8000201DF0CA +:10231C000DFFD2E00A2811D194F82B00BA46B71C55 +:10232C003071A16909B138468847384625F03AFA28 +:10233C005746DFF8D853DFF8E4A3BEE0297800292C +:10234C0040F0BB80092840F0B880A168B01C8847D9 +:10235C00B3E028780138012800F2AF80707860B1C2 +:10236C0094F8330094F83410013084F83300C0B280 +:10237C00884202D9012000219DE099F80100032830 +:10238C0058D0022871D0012840F097803878002866 +:10239C0000F08C8026F03EFE002800F09280012098 +:1023AC0085E07078002875D027F0F8F84FF6FE71AC +:1023BC00884203D1BAF81600884207D0AAF8161042 +:1023CC00ADF8281053200AA91FF052FE1EF04CFD48 +:1023DC0025F048FA00208AF826001DF0C5FB6CE0B9 +:1023EC00CF48006809A90AAA17F0DEF80746029838 +:1023FC005446C64DDFF824A3874212D29DF838000C +:10240C0010B1FD208DF838000420394614220AAB97 +:10241C0023F0D0FFC34907EB470001EB80000121FB +:10242C0041720020012184F83200012002F0ACF945 +:10243C00B94F42E0A2460AACAB20002122461CF068 +:10244C00F9FC042004945446DFF8D0A2AF4D8DF86B +:10245C00140004A80FF038FD27F0DCF89BF80000FE +:10246C004FF4805141F288321DE0012020714FF46D +:10247C008060ADF828000AA819F0B6F827F0CAF861 +:10248C00A4484FF4805102680BE010F0C1FB606966 +:10249C0098B9A2E702204FF4805140F6B83289F87F +:1024AC0002009BF8000027F01FFB06E0002084F8D8 +:1024BC0032000120012102F067F9304625F0CCFCF6 +:1024CC00D3E694F8350020B1E0690028F5D08047B8 +:1024DC00F3E70020002102220023ADF8280002209F +:1024EC008DF830000AA825F061FEB5E7039880F45A +:1024FC00004028E0854800780138012859D88048E8 +:10250C00017803294DD0012953D1417800201FF0C7 +:10251C005BF94EE0012001211FF056F911E025F086 +:10252C00C8FC0420012102F02FF90AE0002132221C +:10253C000170744880F82A1073480421007827F041 +:10254C00D3FA84F004000FB0BDE8F08F84F0800063 +:10255C00F9E70522027091F82C2092072CD591F8FE +:10256C002E204ABB052202600120487000201CF07E +:10257C004DFB022024F0DAFEE3E7644800780138D2 +:10258C0001280BD80020CDE90A000AA812F00EFD94 +:10259C0020B15D48022100781BF054FD84F002004C +:1025AC00D1E78178022904D10121817000201FF02C +:1025BC00E7F884F48050C6E705200021B3E75348C0 +:1025CC000078002840F08680DFF838A1DAF80C504B +:1025DC00002D79D004A80DF1280B01300BF1040665 +:1025EC000390002D6DD0A87A18B10138A87200069E +:1025FC0046D19AF83180B8F1000F11D00020A91CF7 +:10260C0008228DF82800304626F0BCFD584619F0FB +:10261C0025F828B12A88BDF82A00314623F0A4FCFD +:10262C00AF1C0DF127015A46384616F0BDFF814606 +:10263C00384609A923F0E3F9B8F1000F05D09DF84D +:10264C00380040F0020002281CD1DAF80800A0B1D2 +:10265C0003983946082226F095FD022000220C230F +:10266C008DF81000BDF82400ADF81A00264800784B +:10267C0004A90091092120F0F8FB28461EF052FA1B +:10268C00ED68AEE7384623F097FF9DF82700012848 +:10269C00DBD15846142126F011FC224A09EB4900E3 +:1026AC0000215B4642F8201002EB800014224160AE +:1026BC004172FF2049468DF83800042023F07AFE41 +:1026CC00C3E7DAF80C0028B90F484FF40061007822 +:1026DC001CF088F984F4006035E7013A012A09D826 +:1026EC00032202600120487001201CF08FFA0120A7 +:1026FC0024F01CFE287800287FF423AF04205CE72C +:10270C0008880020AC2200209F880020182600207A +:10271C00C6BC020064270020AA270020407B0020B2 +:10272C00DC870020804300202DE9F04F9DB004464B +:10273C00DFF84005406818B18047002800F0798226 +:10274C00DFF834A5DFF834B50D940DF138099AF89B +:10275C000000411E002C0B9118BF01218BF80F10AB +:10276C009BF802800BF118049BF801100027002540 +:10277C000C91C0B287421ED2B84517D0FEB20021D0 +:10278C004A460423304626F0C5FC0E9810F4403F10 +:10279C0040F0040018BF0135C0B27C2806D1304689 +:1027AC000621F82225F030FCF82020709AF8000061 +:1027BC000C340137DDE7E9B201380022884204D13C +:1027CC009BF80500002800F05182CDF82880DDF838 +:1027DC0034804FF001094046B8F1000F08BF1020BB +:1027EC00059015AD00200190DDE90B74002638042E +:1027FC0000F0F9819BF80F0008B98BF80F90E0B24C +:10280C0000210EAA042326F085FC0E98B8F1000FC7 +:10281C0018D010F4403F18D04FF400509AF8001024 +:10282C000136013FABF810009BF80F0001388BF814 +:10283C000F0059FA84F0B0FBF1F202FB11048BF893 +:10284C000D40D4E70021049102E0CDE90B7404960D +:10285C00C0B20A9E4FF00009702804D00C98702169 +:10286C00C0B221F0FDFEF4B200210EAA04232046D2 +:10287C0026F050FC9DF83800FE2803D02046FE219F +:10288C0021F0EEFE20460621FE2225F0BDFB4FF482 +:10289C0000500C9F0BF116010022ABF814908BF832 +:1028AC000C60A146ABF81000FF208BF80E00F8B2BC +:1028BC008BF80D70400050FA87F001EB8000B0F8F7 +:1028CC0006A0DFF8B00302706000ABF812A050FA5B +:1028DC0086F09BF80F6001EB8002FE20114601F898 +:1028EC00020F32F8060F03910890E3480292047825 +:1028FC0014A821F0A9F956FA87F0CDF824900138E4 +:10290C0090FBF4F101FB140000905FFA87FB0C972D +:10291C00CB4500F06081ABEB0900B0FA80F04009C8 +:10292C0007900020069000204FF00109C00740F0EE +:10293C009D801FFA8AF4162C71D9CE480078002895 +:10294C0040F07181AAF1070758460FAAB9B216F0E8 +:10295C00AFFEBDF84A6006F11000A0420FD89DF8FA +:10296C00460096280BD1A7EB06099DF84520314669 +:10297C005B461FFA89F840461AF0CAF918B3AAF157 +:10298C00010A4FF001095446A0B2172864D3362827 +:10299C00A4F1160658462A4688BF2026A41BB3B2BB +:1029AC00A1B226F0B7FB3004EED015FA86F010F881 +:1029BC00010C962801D0013EF5E7DDF8348006EBDA +:1029CC00040A0020B2E79DF84700C10701D1800737 +:1029DC0004D40020CA46DDF83480A5E7F01D83B28C +:1029EC00089813FA80F4B4F5005F01D90120F2E7DE +:1029FC0080B2A54918440A1A5846414626F08AFB6B +:102A0C0006980130B4F5005F069004D101204FF414 +:102A1C0000510891DEE70020CA460894DBE70698CF +:102A2C0010B1964926F0D0FC0098C0B2834500F056 +:102A3C00D88091490C98097859FA80F0DDF82490E7 +:102A4C00B0FBF1F202FB11078C4907EB470001EBDD +:102A5C008000B0F81CA058E78948149900684268B7 +:102A6C00884890470020DDF8348005E0069810B1C6 +:102A7C00824926F0A9FC002007900C980A907D480A +:102A8C000078002840F0CF8008981021C0F5005243 +:102A9C00103883B20998C1F2001221F0F1F8754A8E +:102AAC00117808431499107075480068426875488D +:102ABC00904707980A9A88B16F4800780BEB000191 +:102ACC00013991FBF0F202FB10126C49D0B24000BC +:102ADC0050FA82F001EB8000B0F81CA0DFF89CB13A +:102AEC0008990298099C01238BF80E200180ABF801 +:102AFC001010BBF912209BF80D102046ABF814A057 +:102B0C0023F040F9BBF914209BF80E102046022349 +:102B1C0023F038F9BBF81000049CB8F1000FC0F595 +:102B2C00005007D00599DFF850A18842A4BF0121BD +:102B3C00019101E0DFF840A1059988424FF07C013A +:102B4C00B8BF7821099E304621F08AFD0DF01EFB9E +:102B5C0007469BF80F000621FC22C01B8BF80F00C8 +:102B6C00304625F051FA0399FC209BF80E30087082 +:102B7C009BF8021017FA84F00C9301449AF80000A9 +:102B8C00B1FBF0F202FB10118BF802100A9101312B +:102B9C00CAB2B2FBF0F202FB10118BF8011003EB7E +:102BAC0043010BEB8101898B102906D10C99013162 +:102BBC00B1FBF0F202FB10100C900B98C01BB8F19B +:102BCC00000F0B903FF410AE019880F00100C0078D +:102BDC007FF40AAE07E00120CB464FF001090790C5 +:102BEC004DE700984AE77C2021F054FD0446FF286D +:102BFC0025D17E2021F04EFD0446FF281FD19BF8E5 +:102C0C00014004EB44000BEB8000807DFF2812D0C8 +:102C1C009AF800009BF802100144013991FBF0F284 +:102C2C0002FB10140BE01648149900684268154812 +:102C3C00904700221AE020467E2121F011FDE0B2DF +:102C4C00FE218BF80340400050FA84F00BEB80001F +:102C5C00808BABF806009BF8020021F001FD0020F0 +:102C6C008BF80500BBF81000C0F5005210B21DB077 +:102C7C00BDE8F08FA023002097880020A0800020C2 +:102C8C00D801001000400340002000112DE9F04F46 +:102C9C0089B021F05DFADFF810158122DFF8148578 +:102CAC00DFF814A5DFF82045DFF814E50A70DFF82B +:102CBC00FC140860DFF8F804FF2101700020DFF835 +:102CCC000415A8F800008AF80000DFF8F004096881 +:102CDC00007891F808B04FF6FE718EF80000594458 +:102CEC008AB2A168D1F80031DB899A4200F267817F +:102CFC000422DFF8DC54A8F80020DFF8D024126896 +:102D0C009668330ECEF80C60C6F301592B706FF039 +:102D1C00FF0303EA1627B3B2D1F8B86047EA1327CA +:102D2C00AEF8047036781EB9B9F1020F00F0478185 +:102D3C00B9F1030F00F043811B0A03F0070316B12E +:102D4C00002B00F03C81DFF88CC4042B9CF800C0F5 +:102D5C0008BFBCF1000F00F032813EB1DFF878649F +:102D6C003678862E02D1022B40F02981BB0416D472 +:102D7C00BBB203F00703022B08BFBCF1000F20D03D +:102D8C00DFF854140978862909D10020764621F001 +:102D9C0017FADFF84004B64690F800C030780028E7 +:102DAC004ED0BCF1000F4BD1012800F00881032854 +:102DBC003FD0022844D1BEF80400400740F0FF8009 +:102DCC003EE0D1F8D40090F88300022800F0808017 +:102DDC0027460520147BF246A946A8F8000026F0E9 +:102DEC00A7FB0546DFF8F003007886286DD1B8689C +:102DFC00016C096811B9D0F84C05804760B200210C +:102E0C00002626F04FFFB9680A6C12685077086CE0 +:102E1C0000688677086C0068C477284626F034FE74 +:102E2C00BAF8041099F8000001F010011CF0F0FE43 +:102E3C004EE0BEF8040000F00700032840F0BF800D +:102E4C00BEF80400010700F1BA80810402D48105A8 +:102E5C0000F1B5809EF80E20C2F38107012F00F01F +:102E6C00AE809609012E00F0AA80B9F1010F11D89D +:102E7C0040F0020101F0070103290BD117B93F2AD9 +:102E8C0040F29D8037B9A168D1F8AC1009780029BF +:102E9C0000F095804FF6FB71B9F1020F0BEB010CB2 +:102EAC0019D1CF4BD95D9B5D03EB01090023402A5F +:102EBC00B7FA87F238BF012352091A40430616D4D9 +:102ECC00002A08BF09F1020915E0284626F0DCFDAE +:102EDC0025F04CFA75E0C14B402AD95D9B5D03EBA4 +:102EEC00010908D3420648BFA9F1020903E0002AF0 +:102EFC0018BF4FF00209C0F300205FFA89F11FFAE6 +:102F0C008CF30A1A8EF801009A4258DC6044039143 +:102F1C00B346401AA168AEF806007430D1F85012CE +:102F2C0080B28847A6490028886048D07421CDE932 +:102F3C00019725F0C3FFA24F0020B870A548007878 +:102F4C0020B9387900F020008AF8000078789AF8D7 +:102F5C000010DFF878C24FF000092E4600299A497C +:102F6C003DD000284FF000003AD1B88800F007009F +:102F7C00032807D0012832D18868D0F8D40090F803 +:102F8C00820060B3C8684069007818B125F028FE4B +:102F9C00FE280DD08C488068D0F84C02804738B998 +:102FAC0089488068D0F844028047002800F0F780F8 +:102FBC00834F0120B870DFF814C22E4610E025F0C4 +:102FCC0077FC26F0B5FA814900240A6813681C7155 +:102FDC0012680A6026F058FD09B0BDE8F08F002099 +:102FEC00BC6804F1740184F830B06160A165797833 +:102FFC00BB88FA880029A381029B228184F83A308D +:10300C00337808BF994697F80EB084F84990019D23 +:10301C00A4F85C20FF22B8F80030A273CBF301199E +:10302C005E1A797BA8F8006001F0780160F38201E8 +:10303C0001EB09002074280600F0AE80DCF80000DB +:10304C0004AF039A10FA86F000F10801384626F016 +:10305C0051FE56FA85F0CBF38105A8F80000207CD0 +:10306C0000F04008CDB3B9F1020F06D1B8F1000F52 +:10307C0003D0B4F8440004AF06E0BDF810000237EA +:10308C00A4F84400A4F84200564EF189884203D0BB +:10309C004FF6FF7188425ED1032D11D104F132003D +:1030AC00394626F066FD464CF11CA068323024F0FF +:1030BC00F6FA454900284ED094F80EB008370EE0C9 +:1030CC0037F8020BB1898842608606D04FF6FF7143 +:1030DC003B4C88423C493ED101E03B49384CBBF16A +:1030EC00400F20D3B9F1020F06D16DB9B8F1000F22 +:1030FC000AD13348806803E0A068017C490603D4F8 +:10310C0039880237A0F84210BBF1C00F06D32C4C03 +:10311C003946A068283026F02CFD03E0284C38886E +:10312C00A168088528498968A088D1F8AC20127854 +:10313C00B2B1B9F1020F13D200F00700012802D08E +:10314C0003282FD11E4C6DB9264AA368D289B3F837 +:10315C004230934206D018F058FE19F04FF830E781 +:10316C0000F00700032806D0012815D1D1F8D400AF +:10317C0090F8820080B1A068D1F848128847104AB4 +:10318C0050B90020D17B9070907BC1F3011100F0FD +:10319C00780008449168087408F042FA11E7084F67 +:1031AC00B87808E7064CDDE7AC88002034880020AE +:1031BC00B1880020A6860020AF880020AE880020B1 +:1031CC0024250020748800200C010020C0870020DA +:1031DC00BF880020BE880020B488002058BC0200A4 +:1031EC0054BC0200E88600202DE9F04F97B0DFF8C0 +:1031FC0010850546DFF80C6598F800000328307040 +:10320C0040F04C81002088F8000030700DAC204656 +:10321C0026F0BBFC2046002124F069FEDFF8E89480 +:10322C00B0603A21484625F049FE4FF0FF30A9F82E +:10323C001400C9F81000C9F80C0022F0B9FD0020E8 +:10324C0029461DF0F1FF06F11001F06026F02BFC71 +:10325C00D6E90502DFF8B474B0FBF2F1C9B2032968 +:10326C0028BF032189F800103970B2F5005F40F0D7 +:10327C001281B0EB413FC0F00E81F068002800F0E5 +:10328C000A814FF40050FF224FF000084FF0885B8A +:10329C00A9F80600FF2089F8032089F8058005901D +:1032AC000020089000200B9000200990002007902F +:1032BC000020069000200A9000200C90FF20029025 +:1032CC00FF200490FF200390CCB2A04580F0E98051 +:1032DC005FFA88F6002116AA0423304625F01AFF5F +:1032EC00DFF830443046002115AAA04730460121B2 +:1032FC0014AAA0473046022113AAA04716996FF0D2 +:10330C006F0050FA81F2C8B20E2A06D8012303FAD4 +:10331C0002F245F201131A4203D1A0F1FE02022A75 +:10332C0004D242F28352B2EB914F1ED0304614F0CD +:10333C0021FADFF8D0130028087040F0D280304614 +:10334C00002116AA042325F0E5FEDFF8C843304619 +:10335C00002115AAA0473046012114AAA0473046E7 +:10336C00022113AAA0471699C8B208EB4802CA4614 +:10337C003D4609EB8209C1F30142090A4C46FD287E +:10338C0004F8160F61709DF85610E270A17001D907 +:10339C00102135E0BDF854104FF6FF7291422FD139 +:1033AC000EA820F051FC304600214FF088524FF40B +:1033BC0000534FF4005725F0ADFE6FF0030313FAE2 +:1033CC0087F7B8B250F80B104A1C01D10328F6D875 +:1033DC0001220126D3B2042B06D8CBB2FF2B18BF87 +:1033EC0016460132090AF5E740F80B10CA480E9947 +:1033FC0000684268C948904757FA86F081B2207835 +:10340C00A9F81C109DF85210702889F81A10BDF8F4 +:10341C005010A9F81E109DF84E1089F81B10BDF81D +:10342C004C10A9F8201011D07828D14614D07C2843 +:10343C002F4616D07E281AD0FE281FD0FF2823D165 +:10344C000898CDF80C800130089020E00A98D146FD +:10345C002F4601300A901AE006982F46013006904C +:10346C0015E00798CDF81080013007900FE009980F +:10347C00013009901FFA88F0029008E00B98CDF803 +:10348C00148001300B9002E00C9801300C903978CC +:10349C0008F1010818E7012088F8000017B0BDE812 +:1034AC00F08F0C98974E00060BD10B98C0B20128E8 +:1034BC0007D80A98C0B2012803D80998C0B20128CD +:1034CC0011D99348042200240270CAB2E0B290428F +:1034DC0010D214F04FF93178013408433978307038 +:1034EC00F3E7884E1BE0089BD8B2A04219D188485C +:1034FC0000220270002089F8030089F80100481EA0 +:10350C007E2189F80200B9F81C00A9F806000020F9 +:10351C0021F0A6F899F80200FE2121F0A1F83078EC +:10352C00BCE70A98000624D00B98059A000603D134 +:10353C00039A180600F08480754802210127D5B241 +:10354C0089F80220017017FA82F0B0FBF4F101FB4C +:10355C00140089F80100284614F00CF93070284644 +:10356C00FE2121F07DF889F805700020FFF7DCF8CA +:10357C00D5E70B98059A000621D06548012189F8FA +:10358C000220017011FA82F0049AB0FBF4F101FBF5 +:10359C00140091B2FF2989F801001FD10299FF296B +:1035AC0019BF89F8031001EB410089F8030000EB07 +:1035BC00400009EB8000808BA9F80600AFE7DDE93D +:1035CC000620104300063FF47CAF22F0C5FBA0425E +:1035DC0080F085804E48032101703EE0480089F858 +:1035EC00032010FA82F009EB8000818B1829A9F8CE +:1035FC00061094D30739D0B20EAA89B216F058F837 +:10360C009DF843004007B0D5B9F80610BDF8462028 +:10361C00002399F8030000930323891A0EAA073993 +:10362C0089B206F0B5FE00287FF479AFBDF84410DE +:10363C0000293FF474AF9DF848001DF085F86EE743 +:10364C0022F08AFB0621A042314838BF032103290E +:10365C00017002D0062952D061E722F07DFB0546AD +:10366C0089F80C0000EB400009EB8000408BA9F8B6 +:10367C000D000CF08BFD39782844B0FBF1F202FB05 +:10368C00110089F802000130C2B2B2FBF1F202FB68 +:10369C00110089F801007C2020F0FCFFFF2812D1DA +:1036AC007E2020F0F7FFFF280DD1FF2020F0F2FF45 +:1036BC00FF2808D1782020F0EDFF014699F8010091 +:1036CC00FF2918BF0846C1B289F80300490051FA16 +:1036DC0080F009EB8000808BA9F806001AE70898A7 +:1036EC00000609D099F80200FE213C46374620F02E +:1036FC00B7FF2478039A40E7054806210170FEE7DE +:10370C0088270020A0230020A0800020978800207C +:10371C00A38800203B930200D80100100040034016 +:10372C002DE9F84305460C46480413D4A00024D4D4 +:10373C00A0075CD460057ED4200500F1068120072B +:10374C0000F13B81600040F1F68019F049FF24F054 +:10375C008044F0E025F0ECFEDFF81C140F6D3FB157 +:10376C00D7E90A1202F0E04201F00A01891849D0A7 +:10377C0026F08AF924F48044DDE0BB48DFF8FC73C2 +:10378C00016841F080010160B878012804D104205F +:10379C0020F0E8FF0020B87025F0CAFE0646042091 +:1037AC0025F06EFFDFF8D8130A68904219D12A7EF3 +:1037BC00BAB1FA68AAB1DFF8C003806C002800F037 +:1037CC009780C16840F603020988914206D0C06810 +:1037DC0040F604010088884240F08A8005F114000C +:1037EC0088E040F6C4120860C5E9042284E009F0C0 +:1037FC0061FBDFF88403006C002840F09D8024F00E +:10380C00020498E0D7E90A65D7E90A12AA43B14342 +:10381C00C7E90A1226F038F9B8680028AAD056EA87 +:10382C000500A7D0D7F808C03869B7F93010324670 +:10383C002B46E0479EE725F07BFE054623F0B0FCC7 +:10384C00002800F0B780CC48876B002F00F0B280C6 +:10385C00DFF828830420CB49002288F81800C648DA +:10386C0025F0C0F826F03AF9C74826F007F9C74802 +:10387C000068006B8047C8F810000125042088F808 +:10388C00025021F08DFD386990F82810C8F804001A +:10389C00490703D5436A04210022984701201BF0F5 +:1038AC0029FCD8F80400457612F0F0FFD8F8040093 +:1038BC0081680B461A465B684BB11E88A6F6030658 +:1038CC00072EF7D805FA06F616F0830FF2D0537BC5 +:1038DC0003F0F003013353730023FD6853602D880C +:1038EC00A5F60305012D00F28A80C8F810309FE080 +:1038FC0005F110001EF0ACFA304626F0C5F821F0A8 +:10390C0067FD78B12E6A28466FF4807100224FF063 +:10391C000073B0479848806B10B119F061FE01E05C +:10392C0044F00204EE692846002100224FF0806327 +:10393C00B04724F0005434B1974821462830BDE8F4 +:10394C00F84326F081B9BDE8F8838C4EB078012895 +:10395C0004D1042020F006FF0020B07021F038FDC7 +:10396C0038B170686FF4807100224FF00073056AF3 +:10397C00A847306950B185480068006B80473269B0 +:10398C007168801A000BC860002030617A4D814943 +:10399C000022284625F026F802203076286C20B12B +:1039AC007D480221283026F04FF919F019FE24F435 +:1039BC000064C0E726F092F841E025F0B9FD054619 +:1039CC0023F0EEFBA0B1DFF8B48198F800000007FB +:1039DC000ED498F9000000280AD4684613F0E4F9D4 +:1039EC0008B1009820B1DFF8B49199F8610048B3A0 +:1039FC0026F074F819F0F4FD24F008049BE7034654 +:103A0C0033F8385FA5B190F8445090F8456005F054 +:103A1C00F00580F8445006F0F005013580F845506B +:103A2C0000255360C5634587507B00F0F000507350 +:103A3C0057480022C2610160012024F003F824F4ED +:103A4C00806478E700260127602E0FD009EB060072 +:103A5C00817A31B18772407A07FA00F0C0B220F057 +:103A6C009BFE2036F0E700BFCC210840032088F8ED +:103A7C001800454826F002F826F030F8444F3E4D29 +:103A8C000022786900207861F968F860284644497A +:103A9C0024F0A8FF3D480068006B8047D8F80C1054 +:103AAC00D8F82020411A02EB1130B0EB113F38BF8F +:103ABC004FF0FF3098F82410C8F8200021B1D8F846 +:103ACC000810B0EBC12F20D923F0CCFFB8B140F6D1 +:103ADC000900414621F83C0F002048804A7B02F047 +:103AEC00F00201324A730A7B02F0F0020A7348605A +:103AFC00F8613960B8F83E0010F4406FFAD000203D +:103B0C00C8F82000012088F824001DF045FB25484A +:103B1C00002101600220002123F094FF022020F0FC +:103B2C0021FE102011F08CFE98F8010020B9D8F875 +:103B3C000400503026F084F81B48807810B90D2012 +:103B4C0011F07EFE98F8250028B1002088F8250099 +:103B5C00052020F007FE002088F818001348C8F84C +:103B6C001C000220B5F85610B5F85420914208BF3D +:103B7C00072018F07DFE3DE730210020D01E0020EC +:103B8C00D426002089710200207F00208C010010B7 +:103B9C0000100440D10C010070200020B87B0020E4 +:103BAC0051D6010000000460ACBB0200A903010067 +:103BBC002DE9F04F8DB084780226142C00F21F8270 +:103BCC000546DFE814F02900150015004A008500B1 +:103BDC001C021C021C021C021C021C021C021C02E9 +:103BEC001C021C021C028E009C00AF00BE00CC000C +:103BFC0001206A78022C8DF83100089240F0C080C8 +:103C0C00E878291D03288DF82C0040F0E18009A8E4 +:103C1C00082225F0B7FAE0E010208DF824001020DF +:103C2C0025F0FCFF98B10446DFF8E0032146606004 +:103C3C00E81C10F0FFFA8DF8240028B9204623F078 +:103C4C0051FB8DF8240010B1204625F0E5FF00262D +:103C5C0009AB642000210122C2E10020CDF82A002A +:103C6C00ADF82E00CDF8260002208DF82C00E81CB3 +:103C7C0025F0D0FFADF824006979A8798DF82D10C6 +:103C8C0025F010FB8346E81D25F0C4FF95F80C9039 +:103C9C008046687AAC7A95F80BA04FEA49078DF804 +:103CAC003100384625F0BAFF002800F01081CDE92C +:103CBC00074806464FF0000805EB0800474570D052 +:103CCC000D3025F0A7FF26F8080008F10208F3E7ED +:103CDC00E87820F065FE8DF8240009AB64200421FF +:103CEC0089E1E978032900F25281281DDFE811F0FF +:103CFC000400510155015D0118F05CFE76E1E81CF1 +:103D0C0025F088FFC04C6668002E00F0E4806A79CC +:103D1C00002A00F0E4803368A91D184425F032FA1B +:103D2C000020D9E0B84EEC1C04212046376822F064 +:103D3C00EFFB002F4AD0B968814200F0A0803F68A9 +:103D4C00F7E7A888ADF82400E87809A924F058FA18 +:103D5C008DF832000DF13203642013214BE1002663 +:103D6C00E878ADF8246009A923F066FCBDF82400BE +:103D7C000DF1320314210222ADF8320064202FE140 +:103D8C00E81C02218DF82C1025F044FFADF824001E +:103D9C00002005F10608ADF82E0068798DF82D008D +:103DAC0026E0BBF1000F00F0B580437B0DF1310133 +:103DBC000E30CDE90496CDE9000107985946CDE9BE +:103DCC00020A09A8089A1DF089FEA4E0012000E16E +:103DDC00084625F01FFFADF82400287B8DF82D0038 +:103DEC0005F10D0025F016FFADF82E0005F10F08BA +:103DFC0098F8000025F056FA054608F1010025F068 +:103E0C0009FF98F8036098F804A098F805B081466B +:103E1C00022C8DF8326009D108F1060025F0FAFE6B +:103E2C00074608F1080007F10A0104E098F806704B +:103E3C0008F1070039464DB10A3189B2FB2907D385 +:103E4C00DFF8C481D8F8040000286ED0022009E005 +:103E5C000DF132018DE8030C09A84A463B46294670 +:103E6C0003F016FF089E8DF8310006F0E0002028C4 +:103E7C0040F0C4800DF1310364202146BBE0EC1D01 +:103E8C00204625F0C7FE6D7A002D00F0978005F1D5 +:103E9C0002098246484625F0C1FE002800F09880B1 +:103EAC000026457080462A460670786800EB0A01A9 +:103EBC0008F1020025F066F95FFA89F264201221FC +:103ECC0043461EF0D5FB404625F0A6FE97E0102099 +:103EDC008DF8320024E010208DF8240016E0D6F87E +:103EEC0000C0F38AB28A3169757EB77E06F118007C +:103EFC00CDE900C0301DCDE9025703F0C9FE8DF8A5 +:103F0C002400606825F088FE0020606009AB642006 +:103F1C00112170E002208DF83200304625F07CFE35 +:103F2C000DF132036420032165E007F11C0025F03C +:103F3C0075FE0028C8F8040055D000F11C010C22B5 +:103F4C00016000208DF83100D8F8040009A9043074 +:103F5C0025F018F9D8F804000F214FF47A72056196 +:103F6C002A4DC17680F81AB080F819A00676C7825F +:103F7C00A0F814900821287825F0B6FD089E00289A +:103F8C003FF473AF287808211AF05CF86DE7022033 +:103F9C002CE000781AF086F828E0007825F082F9F9 +:103FAC0018B324F063FE002020E025F033FEA9793D +:103FBC0025F096FBB0FA80F0400917E03068B84263 +:103FCC0001D138683060384625F026FE002000E02C +:103FDC0010200026207064201221022223466670D5 +:103FEC001EF046FB0BE010203CE701208DF824006E +:103FFC0009AB6420102101221EF03AFB002630464A +:10400C000DB0BDE8F08F00BF5C2600209688002024 +:10401C002DE9F04F8FB00C4608040CD4A00426D424 +:10402C00DFF88853287802282DD1E10740F0018170 +:10403C00A10641D558E0DFF86C0300781AF000FDBA +:10404C0090B10178DFF8602305460020602808D085 +:10405C00135C08308B42F9D1104450F8041C2846EC +:10406C008847284623F0F8FE84F4004595E11DF0BE +:10407C003BFC28B10546FCF7EDFD284623F0ECFE91 +:10408C0084F4005589E1A1062ED4012814D8E10648 +:10409C0000F11781610600F12F81210600F13D81AD +:1040AC00E10500F13F81210500F14181E10400F1BE +:1040BC005481610400F15B81A10700F1E080A1054E +:1040CC0000F1FA80210700F11181610500F11981DD +:1040DC00E0034FF0000540F160811BF037FFB6485C +:1040EC00C57084F4803558E1AE4F202138781FF02C +:1040FC0061F8DFF8C4820125D8F80810084317D0FE +:10410C0025F05EFD054625F059FD68434FF47A71A4 +:10411C00B0FBF1F0D8F80810401A4FEA500538BF40 +:10412C006FF00045002908BF0D46002D00F0C2803D +:10413C0000200421002222F055FD06464FF0060A0D +:10414C004FF0FF094FF6FF780DF1080B002E4DD004 +:10415C00304604210022374622F044FD06463889B9 +:10416C00401B38BF002038810004EFD1B87BD0B39E +:10417C0001280AD17889400707D4386887F80DA040 +:10418C00B721407B1DF068FBE0E739685A468DF893 +:10419C000690ADF80480086AC97F0CF089FF0128ED +:1041AC001BD1B87BB97A8DF838000907788A40F0B2 +:1041BC008002ADF8362006D540F4C070ADF836005C +:1041CC00387B8DF83A00786910B1007BADF8180097 +:1041DC00584601A9002202F027FC387B87F80DA075 +:1041EC0016F038F8B2E701207873AFE7DFF8C88132 +:1041FC006C4F22F057FE00200121002222F0F2FC2D +:10420C0018B13878202119F01DFF0020042100225C +:10421C00002622F0E7FC002847D006890421002262 +:10422C0022F0E0FCA0B10289B1B2914228BF16463F +:10423C00F4E7654890F82C100F2906D190F8260069 +:10424C00022802D3002021F07BF884F00105A4E0C1 +:10425C00A8B2B1B2814223D9D6FA55F0202180B24E +:10426C004200387825F040FC25F0AAFC054625F0E4 +:10427C00A5FC68434FF47A71B0FBF1F615E0534896 +:10428C00007818B302AD284625F0A5FB25F074F98B +:10429C004F490B784F490A7829461AF0A7FE22E0BD +:1042AC003878202119F0CEFE0026C8F8086084F07A +:1042BC00200572E000259CE715F0C8FB84F400751E +:1042CC006BE008F05DF984F0100566E03E48418B28 +:1042DC00012025F099FC2878022804D131480121CD +:1042EC0000781AF07FFB84F0020556E03248012179 +:1042FC0084F00805817050E00CF0D4F884F040058F +:10430C004BE0022808BF15F0A5FE2F480121808C38 +:10431C0025F06CFC84F480653FE024F091F984F086 +:10432C0080053AE022F0BAFA84F4807535E01BF08F +:10433C0049FB2048007801280CD11D48007848B171 +:10434C004FF47A7100FB01F216484FF400610078CB +:10435C0025F0C7FB84F400651FE01748017819B1FC +:10436C00002101701BF02EFB84F4805515E01448DD +:10437C00006880B11149097801290CD18047114896 +:10438C00006800B1804707484FF480414FF47A72BF +:10439C00007825F0A6FB84F4804528460FB0BDE8D4 +:1043AC00F08F00BF9888002030B50200182600203E +:1043BC00BC270020BD270020E8250020BA270020BC +:1043CC008423002090230020407B0020972700208E +:1043DC00C0270020C22700202DE9FE4F8846080484 +:1043EC0026D45FEAC87004BF0020BDE8FE8FE54804 +:1043FC00056825F0E5FB044625F0E0FB60434FF42F +:10440C007A714FF6FF72B0FBF1F14FF6FF70002D91 +:10441C0000F01A812B886C88CB1A9BB29C4240F21C +:10442C001C81E31A94B2A342B8BF1A46ED68EEE7BA +:10443C00DFF840A3CDF804809AF800001AF000FBD6 +:10444C00002800F0FC8006460078012840F0EC8043 +:10445C00DAF8041096F83390D6F814B096F8138066 +:10446C0021B148468847002840F0DE80718896F8D4 +:10447C003100022222F05EF90546002842D0287A4B +:10448C00297CA0F10108FF2900F0BB80707F4F460A +:10449C00C00718BF0027E97C287D0144B94204D825 +:1044AC00E974FF2101FA00F06874A969A87C96F8F8 +:1044BC003020896A10FB0710F16A24F063FE287D16 +:1044CC00697CB7FBF0F202FB107001228240D2B281 +:1044DC000A436A74C8457CD196F83010AB7C13FB48 +:1044EC000713A9698B844FF4FF7303FA00F0C0B271 +:1044FC001043FF2868746CD1287C1AF0CFFDFF2084 +:10450C0028747FE0707FC00700F08E80B07F24F0AD +:10451C00C9FE002800F0888004461C2025F07EFB94 +:10452C00002800F081801C21054624F0C7FCB07FD8 +:10453C0002A923F081F89DF809000221287528466C +:10454C0023F0D0F8708896F8312096F8301096F851 +:10455C003330A880287DEA71FF2202FA00F06874DB +:10456C0060680078A9742874302013FB010080B2B5 +:10457C0022F074FD0028A8615DD004461A20B11CFD +:10458C002060708CA080A01D23F048FEF27F04F107 +:10459C003000B17F96F82830C4F81CB084F819802C +:1045AC00A062307CE273744A217563750121A07599 +:1045BC00928C2282F28EA285F28C6282B6F8110065 +:1045CC00A4F817009AF8000085F8089019F03AFD45 +:1045DC0055E725F0F5FA044625F0F0FA60434FF460 +:1045EC007A71B0FBF1F0654928806348097800794D +:1045FC004843642148436249097800FB0100688004 +:10460C0000E04F46E87C297D6A7C01440139B942BF +:10461C0018BFFF2A0CD186F83300708806F11C01F4 +:10462C0086F8342016F0A5FF304623F015FC03E77E +:10463C00C845F9D1EFE7284623F064F8F4E7019870 +:10464C0080F40040BDE8FE8F92B282424BD04948C4 +:10465C000121007825F048FA45E0A879022806D116 +:10466C00287CFF2837D0A86923F0F6FB33E025F02F +:10467C00A7FA044625F0A2FA60434FF47A71B0FB16 +:10468C00F1F03F49288095F83800097888421BD210 +:10469C0095F83620FF2A06D195F83720013085F899 +:1046AC00380085F8362095F8351095F8394082F0A9 +:1046BC00FF0300200126C7B2A7421DD206FA07F756 +:1046CC001F4214D10130F6E7EA8BA87E95F82A1028 +:1046DC00E9231EF0B9FE284623F014F825480121E1 +:1046EC00007819F0AFFC88F00100BDE8FE8FFBB23A +:1046FC0001441A4385F83620AB8F95F83440C8B284 +:10470C0004FB10339EB2A64203D2FF2285F836205A +:10471C0002E0FF2A08D12346184A174E1278367940 +:10472C0072436426724302E095F83A2023466A806D +:10473C002A8D0E0606D022F0200244432A852A6CCC +:10474C00224404E042F020012A6C2985297A85F85C +:10475C002E10E9796A6285F82D10D9B26984054961 +:10476C00496811B188470028B8D105F1100004F050 +:10477C0021FAB3E73C260020407B0020B027002024 +:10478C00B6270020546500207FB50138072800F2B9 +:10479C004C810C46DFE810F008002C0054006E0031 +:1047AC0089004901A600C900CB48007801380128CE +:1047BC0000F23B81002C00F04781002003210024F3 +:1047CC001FF07CF8C64DC74E0420042132222870FD +:1047DC00307825F089F90820002107F097F8307817 +:1047EC006C704FF4805104B0BDE870401AF0FAB808 +:1047FC000020002524F05EFDBB480121017004203F +:10480C008DF80D0074B1B548B34C4585207801285E +:10481C0003D1072023F066F92078022802D1062064 +:10482C0023F060F9AE48042132220570AD480078BF +:10483C0025F05AF9A94890F82B1001F0FE01F2E08E +:10484C00A54800780138012800F2EF80A548042122 +:10485C003222007825F048F9002C00F00F819F4C93 +:10486C009F48012101702069002800F0EC801FF0A6 +:10487C00C7FBF8E70120002C8DF80D007BD0974882 +:10488C0000219B4A80F82A10984824F0DBFE924CB9 +:10489C002078012803D1072023F024F9207802285E +:1048AC0070D1062023F01EF96CE002208DF80D006B +:1048BC008A48002C73D000218D4A80F82A108B482E +:1048CC0024F0C0FE002003211EF0F8FF824C20785B +:1048DC00012803D1072023F005F92078002877D18F +:1048EC00092073E07C4D00208DF80D00002C2878F9 +:1048FC007BD018B9092023F0F5F82878022806D1C6 +:10490C000820002107F002F8042023F0EBF810F047 +:10491C00F1FF73480021C822017070480D2180F806 +:10492C002A10704825F06FF878E005208DF80D00FE +:10493C0069480078022878D1002C00F0C3806848C0 +:10494C000022C178C270017042F20800002106F00A +:10495C00DDFF62480D2190F82B2080F82A10C178D9 +:10496C0002F0DF02002980F82B200CBF04200D2060 +:10497C0023F0B8F859E05848007818B95748022184 +:10498C0080F82A105648002132220170554825F033 +:10499C003AF8524890F82B1001F0FD0143E0082141 +:1049AC0080F82A104C490978012911D890F82E006A +:1049BC0070B900200DF10A018DF80A0052201DF08B +:1049CC0057FB24F0F3F91EF09BFB002023F08AF830 +:1049DC004348002132220170424825F014F83F4828 +:1049EC0090F82B1001F0FB011DE03C4C022812D179 +:1049FC0094F82E0078B194F82B00002140F02000A0 +:104A0C0084F82B0005208DF80D00082006F07EFFA1 +:104A1C000A2023F067F8022084F82A002F4890F827 +:104A2C002B1001F0EF0180F82B102C4800220323EF +:104A3C0090F82A008DF80C002A48007803A9009100 +:104A4C000A211EF012FA7FBD244C0720254D4FF48D +:104A5C00805184F82A0001208DF80D00287819F077 +:104A6C00C1FF0020002622F031F82878022141F203 +:104A7C00883284F82B6025F037F8D6E7174C0220E3 +:104A8C0000218DF80B1084F82A001548017094F859 +:104A9C002B000DF10B0100F0FD0084F82B00012020 +:104AAC008DF80D0052201DF0E3FA24F07FF91EF072 +:104ABC0027FB002023F016F820690028B5D01FF042 +:104ACC009FFAF9E70548022180F82A1090F82B107C +:104ADC0041F02001A7E700BF18260020AC220020DF +:104AEC00088800209F880020AD270020407B0020F4 +:104AFC008027002092B0DFF8EC92D9F8000010B1BA +:104B0C00002180F84510483020F02AFE24F010FDDA +:104B1C008046072011F006F917F0E0FE10B1B248FC +:104B2C0024F0AAFE1AF03EFB01AD284624F09AFBB5 +:104B3C000427002029468DF8047024F09BFBAB4C15 +:104B4C00206023F0E9FF0AAD284624F03BFA002050 +:104B5C0029468DF8287024F03DFAA54E306023F0DC +:104B6C00E5FF06AD284624F03DFA002029468DF8D5 +:104B7C00187024F03FFA31689E4D286019B99E4890 +:104B8C0024F07AFE286810B99C4824F075FE206841 +:104B9C0010B99B4824F070FE1CF086FDD9F800007B +:104BAC004FF0FF3438B1CDE9104410A9082223F09E +:104BBC0039FA01281BD1CDE91044082025F02EF834 +:104BCC00002846D005460026052E04D824F0BEFE4B +:104BDC00A8530236F8E74FF6300029460822E88041 +:104BEC00884824F0CFFA284625F016F809E0D9F8C1 +:104BFC000010CDE910440029DFD08248082224F0AF +:104C0C00C1FA10AA0120082124F0F4FD092800D0D3 +:104C1C00D8B921F079FD800712D4CDE91044CDE943 +:104C2C000E440EAB01200021082224F02DF960B9AE +:104C3C000EA810A9082223F0F5F9002800F0CB806B +:104C4C00704A0120082124F0DBFD6E49E2201DF0A2 +:104C5C000FFA12F077FB282024F0E0FF6A4E0028B0 +:104C6C00306055D0694F6A4C07F10C0524F0C7FE33 +:104C7C0024F018FA3068056007F1100524F0BFFE27 +:104C8C0064498968D1F84C1388473068456007F14E +:104C9C00140524F0B4FE1CF00DF93068856007F1A2 +:104CAC00180524F0ACFE19F05BFD3068C56007F107 +:104CBC001C0524F0A4FE1FF0CFFB3068056107F142 +:104CCC00200524F09CFE1EF0B1FA3068456107F116 +:104CDC00240524F094FE1DF043F93068856107F13A +:104CEC00280524F08CFE23F02FFD3068C56107F1F8 +:104CFC002C0524F084FE20F0BBFC3068056207F123 +:104D0C00300524F07CFE387024F014F830684562CD +:104D1C0018F08CFE404841494FF00009CDF8409006 +:104D2C0001603F480321119010A820F0F1FA24F003 +:104D3C0091FB404624F0A8FE17F0DEFE24F02EFE78 +:104D4C0001201DF095FE19F033FF3748007802283A +:104D5C0008D134480078012804D14FF400400121D7 +:104D6C0006F0D4FD294F4FF48041387824F07CFCB8 +:104D7C002E484FF0FF3100680DF036FCDFF8B080A4 +:104D8C0078684FF0FF310DF02FFC3068002550F89B +:104D9C002510096821B9691C092D0D46F7D3EFE7D9 +:104DAC0024F0CFFD316851F825100C68C1F8009043 +:104DBC0024F0A3FE58F825200020214690470446F5 +:104DCC0024F0BFFD316851F825100A6822430A60AF +:104DDC0024F093FED4E70B480EA9082224F0D2F954 +:104DEC0033E700BF5C270020F0B50200F0870020FD +:104DFC00F4870020F88700200EB6020021B60200CE +:104E0C0034B602009E8700206C8800208821002088 +:104E1C00094702000C0100209C230020A5C70100BB +:104E2C00008D1500D527002018260020488800206A +:104E3C0074B802002DE9F04F89B08A4608040DD4ED +:104E4C005FEACA7040F01D815FEA8A7000F12B8125 +:104E5C005FEA0A7000F13381002042E1A24F3878FA +:104E6C0019F0EEFDDFF88892A04C06464FF0000BCF +:104E7C0048F21508002E00F001813078312838D026 +:104E8C00322849D0D32840F0B380F089404573D004 +:104E9C00382840F0AD80CDF820B0CDE906BB3046C7 +:104EAC0006A920F03DFB9DF81C10052968D8307B25 +:104EBC00002840F09D809DF81D00002800F098808F +:104ECC00052800F29580069823F0ADFD002840F0EF +:104EDC008F80707C87497870708808809DF81D00E1 +:104EEC00214601388DF81D0006A890E82C002CC135 +:104EFC007EE0B87803287BD899F82E10804823F0F0 +:104F0C0092FD002874D1FF207C4960717088088064 +:104F1C00B088794908806BE06079FF2814D00020B4 +:104F2C0016F074FA0246B9F8701078783346CDF85A +:104F3C0000B012F04FFD6079002859D03878082164 +:104F4C00322224F0D1FD53E099F81810706820FA41 +:104F5C0001F2D2071ABF3144097A002106F1080286 +:104F6C0000231B2B42D020FA03F5ED0702D0D55CB1 +:104F7C00A9421ED80133F4E7304621F007FD37E093 +:104F8C00FF293DD0FE2956D199F872109DF81E00CC +:104F9C00884202D860BBFF292AD11CF06BFE06990F +:104FAC0000201B2859D021FA00F2D20757D101302A +:104FBC00F7E7B9F86E004F49334608804E4802882F +:104FCC004E48018810200090002012F003FD0120B3 +:104FDC00F870B87840B93C2002214EF66022B880B7 +:104FEC00387824F081FDB8780130B87084F805B0B9 +:104FFC00304622F031FF387819F022FD064639E7A9 +:10500C0099F872109DF81E00884203D80028EFD141 +:10501C00FF29EDD11CF02EFE069838B1D9F82810D6 +:10502C00814203D0C9F8280022F06CFDBDF82000A5 +:10503C0023F0BAFBDCE7307B0028D9D170882D49EE +:10504C00802200230880707CCDE900BBCDE902BB37 +:10505C00CDE904BB11F074FBCAE71B2000E0C0B221 +:10506C0099F818108142C3D02649087099F80700A6 +:10507C00642100FB01F23878012162E78AF40040D8 +:10508C002FE020491A4C08782076E1201CF0F0FF24 +:10509C0022F038FD0020A4F87000012016F0B6F9BB +:1050AC008AF001001DE010488188B1B101394EF63B +:1050BC00602281800078022124F016FD0FE00B4C59 +:1050CC00607938B12179206823F0ADFC10B9607992 +:1050DC00013860718AF0080003E0002181708AF0C9 +:1050EC00020009B0BDE8F08FCC24002040870020DE +:1050FC00407B00207A8700205E840020DA8000202C +:10510C0000F8FF079B8800202DE9FE4F0746086832 +:10511C000024B0B1D7E9018A0E4624F009FA814681 +:10512C00D8F8E800082888BF0124B068204202D1D2 +:10513C007068204208D003203074484624F0A4FC48 +:10514C0000242046BDE8FE8FD8F8C01069B198F84D +:10515C00F8100029EFD006213174D8F8C410C8F823 +:10516C00C4604E6198F8FC100DE000210522C8E9DE +:10517C003066C8E93411C8E9361198F8FC100029DA +:10518C0008BF0122327400220129726109D1022068 +:10519C004FF4E02188F8FC0098F8FB001FF0C8FFE2 +:1051AC00706889490138884205D8042020F0F8F845 +:1051BC00062020F0F5F8022020F0F2F898F8F8001C +:1051CC0040B9DAF83C003168814203D298F8FC000F +:1051DC0000286CD0D8E9361009B118B900E028B312 +:1051EC0024F015FCDAF80000416941F0010141613D +:1051FC00484624F049FC98F8F80008B10124A0E7CF +:10520C0008F16C05D8F8EC10284624F0B3FB002804 +:10521C00F4D0D8F8C00003210174384612F0EAFF2C +:10522C0028460021002424F0A5FB8AE79AF8040004 +:10523C0024F0D2FC654CDAF810100222206991FAA5 +:10524C00A1F1B1FA81F14368D8F8CC00406800684C +:10525C0098472069DAF8141002224368D8F8CC0079 +:10526C0091FAA1F1B1FA81F14068006898479AF877 +:10527C00040022F087FA9AF8040024F0AFFC24F022 +:10528C00C6FB0020C8F8E000D8F8C0000068B0F5F4 +:10529C00806F01D924F0BBFB98F8FE000028A1D147 +:1052AC00DAF80000416841F0020141609AE798F891 +:1052BC00F90020B1D8F8EC0001307FF48BAF4846F0 +:1052CC0024F0E2FBB2683AB1D8F8E80002210928D0 +:1052DC0038BF0121009103E008F1F4020020009096 +:1052EC00746834B1D8F8E8000227092838BF0127C0 +:1052FC0002E008F1F6040027DAF80000334D4168AB +:10530C0041F002014160D6F800B0D946BBF1000F64 +:10531C0040D0D8F8E800019209284FF0010011D2D2 +:10532C002A68B9F1000F1FD0C0071DD02178DAF818 +:10533C0000009268904700281EBF3C44A9F1010967 +:10534C000120EDE72A68B9F1000F16D0C00714D080 +:10535C002188DAF800009268904700281EBF3C4470 +:10536C00A9F101090120EDE7DAF80000D26802A9E1 +:10537C009047DDE90120107007E0DAF80000D268F0 +:10538C0002A99047DDE9012010800098ABF1010BD8 +:10539C000244BBE7D8F8F000DAF80010CA68024003 +:1053AC00102802D1002AF9D101E0002AF6D0706849 +:1053BC0022F070F8D8F8C0100020C8F8C400C8F863 +:1053CC00C00008741AE700BFFEFFFF0FC4010010F5 +:1053DC002DE9F04F85B08846080418D4A948007808 +:1053EC00012802D85FEAC87155D15FEA88714CD4A4 +:1053FC00022807D1A4480078012803D15FEA48703D +:10540C0000F188805FEA087057D400202BE1DFF8A8 +:10541C005CA29AF8000019F013FB002800F021811F +:10542C000546807FC8B9688C132816D190486E88C1 +:10543C0000F11C09002049464F46002818BF071DE3 +:10544C00086850B1014631F8042BB242F4D14468DB +:10545C003C6024F0E1FB2046F3E7A87A05F1020B4F +:10546C00022840F0E480DFF8089295F83170BBF820 +:10547C00006009F11C000068A0B10188B14202D1A2 +:10548C008178B94242D00430F5E7794801210170A6 +:10549C0088F00200E7E07648406900B1804788F068 +:1054AC000100E0E0D9F81C40002C57D001206168C5 +:1054BC00002955D001300C46F9E77048DFF8B0915F +:1054CC00807BD9F81C60000760D424F079FB04467B +:1054DC0024F074FB6A4A60434FF47A71B0FBF1F02C +:1054EC00D9F818101288411A91427AD3B1FBF2FB09 +:1054FC000BFB02F2511A08445E49C9F818001FFA56 +:10550C008BF00978884288BF8B4641E0594909786D +:10551C00C170A3E05E495D4800224FF6FE73002483 +:10552C000978023079B130F8025C9D4208D0458888 +:10553C00013D45802D0406BF027020F8023C012479 +:10554C0001390630EEE734B1484804214FF4FA72C1 +:10555C00007824F0C9FA88F0040084E000240020CC +:10556C00454980B20988884261D2082024F056FB54 +:10557C0000285CD000210680877041603D49097885 +:10558C00C170D9F81C1079B360603FE04FF0010B8B +:10559C0000205FFA8BF44FF0000A071D002808BFAB +:1055AC0009F11C0796B1F078C0FA5BF1A042F170DA +:1055BC0006D8756830463D6024F02EFB2E46F1E788 +:1055CC00716830460AF1010A0E46E6E75FEA0A40C6 +:1055DC0007D100200821C9F818002448007819F0D8 +:1055EC0001FA88F008003EE0C9F81C002348807BD3 +:1055FC0000070BD424F0E4FA044624F0DFFA6043ED +:10560C004FF47A71B0FBF1F0C9F818001B48807B9D +:10561C0000070CD59AF8000008211DF0CBFD30B91D +:10562C001748082102889AF8000024F05AFA2878C2 +:10563C00022810D0012811D1297EAA89EB7C05F112 +:10564C001C006C696E7E8DE85A0005F110035946FA +:10565C0005F0FEF802E0284615F0A0FA284622F0E4 +:10566C00FBFB88F4004005B0BDE8F08F9588002066 +:10567C002C240020B52700207A270020407B002016 +:10568C007E27002018260020D52700204C6D0020F6 +:10569C00912700202DE9F04F87B0851C83462846C2 +:1056AC0024F0E9F901AC06461821204623F006FC4B +:1056BC009BF801A004F10B002946009524F059FA3F +:1056CC006FF001009BF80A1002240122ADF81800BB +:1056DC0000208DF81A408DF80C0001F00800C1F381 +:1056EC00C007890782EAD00507D4002808BF012427 +:1056FC00B946A8460027002507E004244FF000090E +:10570C004FF00008002808BF03248548007850EAB1 +:10571C000A000BD0834890F82600082809D123F002 +:10572C0079FC00285AD0BAF1010F57D14FF0C309B8 +:10573C0001E04FF0C2090025BAF1000F10D07F48EC +:10574C00007890B9BAF1010F0FD1002E55D000207E +:10575C00214601228DF81A0001A814F03BFA0AE048 +:10576C0001A81BF06DF986B91CE001A82146524630 +:10577C0014F030FAB6B17179BAF1020F41F040026F +:10578C00727104BF41F0600171719BF80A104906F7 +:10579C0003D5717941F080017171B1790024013127 +:1057AC00B17100E00124B0FA80F149090D422CD10D +:1057BC0007D1002D18BF814641F20100494618F06F +:1057CC009EFF14B9009819F061FBBDF818004FF654 +:1057DC00FE71884218BF24F02BFA16E0DEB3327942 +:1057EC00A24218BFBAF1020F12D1D01EC0B20128CA +:1057FC001BD857EA050020D12AE0022021460122BD +:10580C008DF81A0001A814F0E5F907B0BDE8F08F87 +:10581C004FF00009009953468DF81A903088ADF876 +:10582C00180024F0E5F9012586E7501EC0B20128C6 +:10583C000ED849EA0800012807D1308821F0AAF9CE +:10584C0050B93088ADF8180008E0308824F0F0F931 +:10585C00009819F01BFB0026BDF818004FF6FE71DE +:10586C0088421ED120F08EFF10B1BDF8180011E057 +:10587C00BAF1000F04D02C4D288821F08BF930B1EF +:10588C009BF80A0000F002001FF0BAFD00E0288827 +:10589C00ADF818004FF6FE71884202D14FF0C709DF +:1058AC0049E79BF80A200099534624F0A1F910B15E +:1058BC004FF001093FE71D48016811B1BDF8180010 +:1058CC008847BDF818000099224606F0D9F806461C +:1058DC00174818490A6800784FF4803124F004F90D +:1058EC0001211548C17096B1AAF10100C0B201287E +:1058FC0007D81020BAF1020F08BF082071790843AD +:10590C0070714FF0000901258DF81A9014E74FF6CD +:10591C00FE7000254FF001090026ADF818000BE7CA +:10592C00F4240020407B00207427002098230020C2 +:10593C0098880020B0BC0200E82500201826002022 +:10594C002DE9F04F8DB0044600209A4616460F46BE +:10595C00CDE90B00CDE9090087488568804614F035 +:10596C00B8FD1C2803D014F0B4FD1B281BD13088C3 +:10597C0040F60201884218BFB0F5C15F03D1F07B3D +:10598C00022810D93EE043F6070188420BD196F865 +:10599C002400032807D33069784940F0806020F058 +:1059AC00604088422ED100206FB366B3387825FA58 +:1059BC0000F0C00726D03046002124F029F97048A9 +:1059CC00C4E90176006880B109A800900CA90BAA63 +:1059DC000AAB304609F00CFF0B980B214FF6FF7207 +:1059EC00502321F06FFFFF280CD023F0A1FD654F51 +:1059FC0006467878012802D840B1012070E0304684 +:105A0C0024F042F800200DB0BDE8F08F09F064FEE0 +:105A1C005D480DF10409016841F0020101605B4829 +:105A2C00C8F80000484623F00DFCDFF864B15A4971 +:105A3C004A469BF801009BF80050039055482830CB +:105A4C001EF0F8FE554856494A461EF0F3FE4846ED +:105A5C0023F008FBDFF84C81534A19214B46029581 +:105A6C0040461DF0B7FA514A08F11C001A214B466A +:105A7C001DF0B0FA4E484F4923F0D5FF4E484F4920 +:105A8C0023F0D1FF4E48006810F4402F06D04D4A49 +:105A9C0007F128000421002321F04CFB9BF80200A5 +:105AAC0010B10D2010F03EF908F1400022F0A5FFD6 +:105ABC0008F1380022F0A1FF434900200722387674 +:105ACC00B8843862386181F860200521C7E902107A +:105ADC003E49F96138700420002121F0B3FF787839 +:105AEC002C4941F8204001307870304623F0CCFF2F +:105AFC00BAF1000F06D10DF1040A354920225046A7 +:105B0C0024F0F8F8DAE90012BAF81000DAE90635F0 +:105B1C00002AB2FA82F608BF40F6C4126261216014 +:105B2C0060832563760926764FF4FA76C4E903621E +:105B3C0001226276274AC4E90722C4E90923DAF86C +:105B4C000C0000B12062DAF8140000B16062DAF8DF +:105B5C00080000B1E06104F13800C82123F0AEF96F +:105B6C0004F15000002121F0ADFF1B4904F1B800F5 +:105B7C0023F059FF204646E7CC2108400F000005D2 +:105B8C0074260020D01E002000200940110000E0E7 +:105B9C00ACBB020070200020BD80020028800020D9 +:105BAC00E54901003021002051D60100ADB80100BB +:105BBC00647F002065710200207F00206980020054 +:105BCC00B44F005049000200B87B0020A90301002B +:105BDC0064B90200BB2E0100259B02002DE9F04F99 +:105BEC0087B000240293002A00F03D81074603A8E9 +:105BFC0092460E464FF0200B10300190504610F894 +:105C0C00011B25290CD0002900F02A81022EC0F09E +:105C1C00D980013E002F00F0D48007F8011BD1E0A1 +:105C2C009AF801002D2806D19AF802000AF1030314 +:105C3C004FF0010C03E00AF102034FF0000C302886 +:105C4C000CBF13F8011B01462A2920D1029D2A689A +:105C5C00111D2960D2F8009013F8011BB9F1FF3F18 +:105C6C00DCBFC9F100094FF0010C2E291ED11A46D8 +:105C7C0012F8011B2A291CD1029D2A68111D2960CA +:105C8C009D1C126859782B4622EAE27821E04FF0ED +:105C9C000009A1F13002092AE7D809EB890201EBCE +:105CAC004201A1F1300913F8011BF2E74FF0FF3864 +:105CBC000FE04FF00008A1F13003092B08D808EBD6 +:105CCC00880301EB4301A1F1300812F8011BF2E744 +:105CDC00134630284FF0000241F0200008BF4A461E +:105CEC006C2808BF13F8011B9A46692901D0642956 +:105CFC000CD1029B1868011D19609045C8BF424623 +:105D0C00DDF8048001686FF009031EE075290AD0E4 +:105D1C00A1F16F00092858D8DFE800F005695F5F32 +:105D2C00835F5F5F5F05029D2868031D2B609045B4 +:105D3C004FF00803C8BF4246782908BF10237529C5 +:105D4C0008BF0A23DDF8048001684046654616F05A +:105D5C00A5FBAC460546A8EB0001A9EB0100BCF184 +:105D6C00000F0DD109E0022E05D3013E17B107F843 +:105D7C0001BB00E00027013801340128F3DA0138B7 +:105D8C000A465AB1022E06D3013E1FB12B7807F8F2 +:105D9C00013B00E00027013A0135F2E70C44BCF16D +:105DAC00000F3FF42BAF0128FFF628AF022E05D3CE +:105DBC00013E17B107F801BB00E0002701380134A0 +:105DCC00F1E700270134824618E7632905D1029ACE +:105DDC001068011D1160006804E0AAF10100022E98 +:105DEC003AD300788DF80C00012103ADB5E7029A87 +:105DFC00DDF804801023CDF800C01068011D11607F +:105E0C001099082200290168404616F047FB054608 +:105E1C004FF04000DDF800C005F8010DA8EB0501BE +:105E2C009BE7029ACDF800C01068011D1160109913 +:105E3C0005680F480029002D08BF0546284623F0A9 +:105E4C0025FB0146804538BF414618F1010208BFC9 +:105E5C000146DDF800C080E7002103AD82467CE7F7 +:105E6C000FB100203870204607B0BDE8F08F00BF9E +:105E7C00C0A202002DE9FC47044601900578944825 +:105E8C00465D9448E840ADF80260C00740F01E81C2 +:105E9C000D2D13D1904E0DF10201B068D0F82824CD +:105EAC0053209047BDF802104FF6FD70814214D874 +:105EBC00208990B14FF0000AA146AEE00C2D0ED017 +:105ECC00072D13D0052D0ED1A078012800F0FE80EF +:105EDC00207C304400F1240716E0B068CDE0606807 +:105EEC00C08AC0050AD44FF0000A09E0A07848B176 +:105EFC00A07D00EBC00006EB800705E04FF0010A27 +:105F0C00374605E006F11B07ADF802704FF0000AAA +:105F1C00384621F0A3F838B38146072D44D12078B8 +:105F2C0089F80000607889F80100A07889F80200EF +:105F3C000028E17889F80310D4F80510C9F804108A +:105F4C005AD0A07D002889F8080049D0A169002901 +:105F5C0046D000EBC00009F110068200304623F059 +:105F6C0011F9C9F80C6040E00C2D40F0AF80A1464F +:105F7C0059F8040F002800F0A98023F0D9FA8046C4 +:105F8C0055488068D0F8541348468847384621F065 +:105F9C0065F88146404623F077FDB9F1000F00F01B +:105FAC00958023F08DFC38E023F08AFC052D34D14C +:105FBC0009F11806D9F804102422304623F0E2F82F +:105FCC00D9F8141099F8102009F13C00C9F80460B4 +:105FDC0023F0D8F8D9F804002430C9F814001CE0D8 +:105FEC00002089F80800C9F80C00A069A8B123F0BA +:105FFC0013FE0020A0750FE01B2009F110061B22D8 +:10600C0089F808003046A16923F0BCF8C9F80C6087 +:10601C00A06923F001FE0020A0613048016819B18D +:10602C0048468847002846D10D2D2BD16068017851 +:10603C008A0720D42A4AC1F38301927C91421AD157 +:10604C0040783F2817D894F83000022813D199F8DB +:10605C00470009F146011DF07FFF01984FF6FF72D2 +:10606C00418E91421FD14068807902281BD348464B +:10607C0019F04CFE50B318488068D0F8541301A89E +:10608C00884723E00C2D0ED160781A280BD0D9F854 +:10609C00040040B1C08AC00705D099F8100009F17E +:1060AC000F011DF059FFBAF1000F04D10D484946FC +:1060BC00007818F0F3FF0C2D08D1019850F8041F4C +:1060CC0021B105498968D1F85413D9E7BDE8FC879B +:1060DC00E0BA020019C206000C010020582700206B +:1060EC00407B0020988800202DE9F04F8DB00646AB +:1060FC00806A447874B18D4909788C4280F01281A1 +:10610C008B49023022462AB130F8023B013A21F881 +:10611C00023BF8E78748C18A708988422FD18348AF +:10612C000078A04240F2FE80B589814A214628467B +:10613C0022F020F8284616F089FE06468248077899 +:10614C00BE4204D14FF6FE7016F080FE0646BE42EB +:10615C0080F0E880DFF8F48108EBC6094F4657F869 +:10616C00040F08B123F058FD002C00F0B180600042 +:10617C0023F054FD0028386040F0AC80D2E0B27CB3 +:10618C00002A00F0CF806A4F0025AC4205D037F8CA +:10619C0015208A4203D00135F7E7A04600E0A84657 +:1061AC00002113F057FE002800F0AD8081464079A5 +:1061BC00012840F0A88099F8060010F0180F00F0A4 +:1061CC00A280B9F80210204622F0C2F8A54202D3F0 +:1061DC00002800F098805848CDE90498B6F80C9047 +:1061EC004FF6FE7A00780890544800780A90002008 +:1061FC0006960B9052481130099052480430079083 +:10620C0000200C90DDE909564FF0000BF6B135F883 +:10621C00117C574518BF4F4502D1013E1C35F5E79F +:10622C002046394622F094F80028F6D12878013817 +:10623C000528F2D80C980BF1010BC007EDD00B9888 +:10624C005FFA8BF1C0B28142E7D356E0DDE90786F5 +:10625C002EB338F8047C574518BF4F4503D1013E87 +:10626C0008F12408F4E72046394622F071F800289A +:10627C00F5D198F8050001380528F0D898F80000F9 +:10628C0001380228EBD30C980BF1010BC007E6D0B8 +:10629C000B985FFA8BF1C0B28142E0D32DE05FEA3C +:1062AC000B6028D00B98000625D101205FFA8BF5E6 +:1062BC000B90012D4FF001000C90A3D023F046FB66 +:1062CC00C0B2B0FBF5F101FB15000B90012098E773 +:1062DC00002038601E4989F80140A9F8025009785D +:1062EC0008F83610F4B1E8B1114962000DB0BDE800 +:1062FC00F04F22F047BF4FF6FE770498069EDDF86C +:10630C00148047800A4FB37CF47CB269B1890125B3 +:10631C00581EB07470895FFA88F68DE8D00003952A +:10632C0010F058FB0DB0BDE8F08F00BFDBBC0200D5 +:10633C00F0850020407B0020E6BC0200D5BC0200AA +:10634C00DC5B0020B05400209ABC0200E027002047 +:10635C00CE2700202DE9F04F87B005462C200E46A5 +:10636C0023F05CFC002844D0778B044623F016F90C +:10637C000021E1840121874208BF02212170707B3A +:10638C00A0703169081A6060204618F087FB3178DC +:10639C00834F01F00301387B012908BF0520607091 +:1063AC00C0B222F03FFF4FF0FF316077A182217F16 +:1063BC00326908440A44317D3261081A3075E07044 +:1063CC00A069013017D0207C032816D8DFE800F034 +:1063DC0002170209062021466082284616F0A2FF09 +:1063EC0010B3042021466082284607F0A5FB054621 +:1063FC001BE01025CFE0A32517E0A12515E0002018 +:10640C00B3256082F87A80B997F8410001280CD145 +:10641C00A07D4FF6FF7619F039FE0025A082B04220 +:10642C0008BF6FF05E0500E000252078022807D138 +:10643C0004F1080622F0DEFB0146304623F099FBFE +:10644C00280640F0A580574F3878013801281AD813 +:10645C0094F8260010B994F82700A0B1A078E17840 +:10646C00227F08441044043023F0D8FB58B1A178A3 +:10647C00E2780646207F114408446168021D3046CC +:10648C0022F080FE00E0002620460EF083F905463F +:10649C003878012802D12DB9002575E0022873D176 +:1064AC00002D71D0002E73D00DF1080800274FF08D +:1064BC00010B4FF4D00908F1080A94F8260018B91A +:1064CC0094F8270000285FD0A178E278207F11444F +:1064DC0008443146021D606822F054FE94F82600F0 +:1064EC0020B184F82670C4F8129007E094F82700C5 +:1064FC0020B12D4884F82770C4F8120020460EF005 +:10650C0049F910B10021054639E04046142122F02A +:10651C00D5FC608A8DF819B0F0B9A08A40F203114D +:10652C00884216D0682817D16068C17B052929D10B +:10653C002A30FF21082222F081FA18B34FF0FF30E5 +:10654C006946CDE900001948006823F012FBFC20D5 +:10655C0000E0FF208DF81800504669460022002507 +:10656C0013F022F801469DF8000038B104201422E3 +:10657C0043461FF01FFF0321002500E003210329E0 +:10658C009BD101E00221FAE716B1304623F044FB1F +:10659C00204623F041FBE8B207B0BDE8F08F00BF06 +:1065AC00407B00201826002000000301DC8700201F +:1065BC0014F04AF88848DFF824B2DFF824A2DFF898 +:1065CC002482894D894E0027006817F07BFFDBF889 +:1065DC0000004FF0FF310CF007F823F0B2F99AF8F5 +:1065EC0002109AF80420D8F800409AF806308AF87D +:1065FC0002708AF804708AF80670002918BF44F0FB +:10660C000404002A18BF44F08004002B18BF44F087 +:10661C000204C8F8004023F070FAD8F80000010614 +:10662C0044BF20F08000C8F80000287818F008FA61 +:10663C00002848D0DAF80C10044651B19AF8010041 +:10664C00012804D0022804D1204688473BE020468C +:10665C008847204617F0E3FAA8B304460C20B1464D +:10666C002F4623F0DBFA80B1064623F06AF9054683 +:10667C002078B46098B1304623F0CEFA606821F0EF +:10668C00EBFB204623F0C8FA16E0606821F0E4FB2F +:10669C00204623F0C1FA3D464E46002713E0D9F8B8 +:1066AC000000314623F0D6F8D8F8000040F0100076 +:1066BC00C8F8000023F09FF928463C464E460027B8 +:1066CC0023F01BFA2546D8F80000C10631D53068F6 +:1066DC0023F0BAF8F0B922F085FFD8B9A94623F017 +:1066EC0030F90446306823F0A9F878B10546806883 +:1066FC004188406817F046FCA868406821F0ACFB64 +:10670C00A86823F089FA284623F086FA204623F05D +:10671C00F4F94D46306823F097F830B1D8F8000002 +:10672C0020F01000C8F8000003E023F064F9D8F85A +:10673C00000081070FD508F00BFD21F0D3F820B134 +:10674C0023F059F9D8F8000005E0D8F8000020F043 +:10675C000200C8F80000010725D5706823F06EF818 +:10676C0090B1DAF80810044641B19AF8000028B14B +:10677C00022826D0012804D1A0688847A0681AF006 +:10678C002FFD204623F048FA706823F05DF830B1F5 +:10679C00D8F8000020F00800C8F8000003E023F04F +:1067AC002AF9D8F8000041077FF511AF20F004005A +:1067BC00C8F80000306823F047F800287FF407AFD2 +:1067CC0002E0A0688847DCE7D8F8000040F0100031 +:1067DC00C8F800005846F7E6488800204C8800208E +:1067EC003425002050880020B98800202426002061 +:1067FC002DE9F04F93B004461EF0C0FA08B11120F9 +:10680C0006E1207F4FF6FE75B8B183480078810011 +:10681C0041EA401061882077FF2020F043F90021E5 +:10682C0080B1E08A05F1010B012640F00400E08202 +:10683C00207F40F00100207707E0002000264FF673 +:10684C00FE7B08E000264FF6FE7B74480078022899 +:10685C0038BF012188010490678838461DF084F9FF +:10686C0008B10020607694F81AA0BAF1000F04D198 +:10687C006B4890F800A084F81AA094F90000C5B2F7 +:10688C00B0F1FF3F07DDE07E40B966480178E17664 +:10689C000131017002E005F003052570207EDFF860 +:1068AC008491012805D199F80B0010B90DB900207D +:1068BC002076DFF8688198F80000012831D899F823 +:1068CC000E0080072DD5E6B1E08A410606D5BAF157 +:1068DC00010F03D120F00400E08222E0A188E07EC9 +:1068EC00627DADF822708DF82AA0ADF824108DF8D9 +:1068FC002B0006A803F0E2FE00283FF480AF2578B9 +:10690C000FE038461DF030F958B1002DDCD020696D +:10691C0000780A2805D8012101FA00F010F4836FE1 +:10692C00D2D14FF6FE7A012D07D1206900780228CA +:10693C0003D1E08A40F04000E082EEBBE08A10F028 +:10694C00400039D198F80000012835D899F80E008C +:10695C00800731D5049DA71D6188607E3A462B4681 +:10696C0013F0B8FA28B100206076E08A40F02000DD +:10697C00E082387870B1618804F108001CF066FB85 +:10698C0083466088834504BF00203870E08A40F05D +:10699C004000E0822078012804D0A18860882A4633 +:1069AC000FF07CFCA18860882A460DF0B7F818B16E +:1069BC00E08A40F02000E0820DF11701204605F03E +:1069CC007DFA06461FFA8BF0504508BFB4F802B0AA +:1069DC00EEB12078617D94F82C50B9F816209DF812 +:1069EC00173007948DF81800608DADF81A00E08A06 +:1069FC0006ACCDE90254CDE900101FFA8BF13046FC +:106A0C000BF006F9102803D1304623F005F91020BD +:106A1C0013B0BDE8F08F00BFB3270020182600206C +:106A2C00CFBC0200407B00202DE9F04F99B012AF93 +:106A3C008A4604461C219346384622F03FFA2046EB +:106A4C0039460CF0C5F99DF855009DF85C100843CB +:106A5C0007D09DF8480041060CD560891DF084F8DC +:106A6C0030B140F2351010F04EF919B0BDE8F08F8E +:106A7C009DF84800C0F3401900F00C0510F0200FF1 +:106A8C0018BF042D21D1E08D9DF8483010F0800105 +:106A9C000CD15A060AD59DF84920920706D143F02D +:106AAC00040202F00C020C2A40F0CA804FF00008DD +:106ABC00012213F003031ED0012B46D0022BD4D19C +:106ACC00A08912A91AF038FECFE7A68922F066FD3C +:106ADC00864202D1E08D010609D4A68922F05EFD22 +:106AEC00864200F08B80E08D010600F18780000665 +:106AFC0079D4A0897BE0544EF37A012B02D1A3798F +:106B0C00002B78D00223A7898DF84430ADF83C7067 +:106B1C0081BB042D75D1207C4E4D8DF85E0028680C +:106B2C000028A2D022F03AFD87429ED1E08D217937 +:106B3C0094F830202D684346CDE903028DE8020A13 +:106B4C000FA812A95246A8478FE7002918BF0121A8 +:106B5C0052EA010003D1A08912A914F00AFDA08900 +:106B6C000797ADF81800A0798DF81A0006A819F04F +:106B7C009DF97AE7ADF8300016989DF84A109DF80B +:106B8C004B208DF8203094F832300B9060898DF8C2 +:106B9C002310DDF84E108DF8222094F830208DF85B +:106BAC003830ADF81800B08CCDF826109DF85C107C +:106BBC008DF83720ADF82400207CADF82A10A17C8C +:106BCC008DF8320020798DF834109DF85F108DF817 +:106BDC0033009DF85D008DF836108DF8350006A851 +:106BEC0001F0E8FF41E7A089ADF86200608912A9C5 +:106BFC001EF0DEF910B14FF49A7034E74FF0010932 +:106C0C0041E71AB912A9384614F0B3FC10480078C1 +:106C1C00022809D10D480078012805D1204611F031 +:106C2C0033FB00283FF421AFA07CE17CB28C5346AF +:106C3C008DE8020A039012A80FA90EF0C3FF14E707 +:106C4C004FF00108002234E7407B0020D5270020BC +:106C5C00182600203C2400202DE9F04F97B0044664 +:106C6C0080690DF15B0200214FF0000890F800B034 +:106C7C009C200BF09BF97B480078012808D8002059 +:106C8C0004211CF0E5FE80469DF85B00404400E0CA +:106C9C000120C1B200258DF85B0059457DD9A0EBD0 +:106CAC000B060221F0B2022828BF0E461A207043B0 +:106CBC00C0B222F0B3FF0027002800F0BF80099477 +:106CCC000BA907965FFA86FACDF814805FFA88F65E +:106CDC000446D8464FF000090690CDF820B0043198 +:106CEC000A915FFA89F050455DD25FFA88F0B042A4 +:106CFC0056D21FF05BFD00284AD05B490546888CB4 +:106D0C0039312080A01C22F034FF4FF60270A4F819 +:106D1C00170028888DF82C706082ADF82E00A97AA7 +:106D2C0061760BA812F010F9014604F10A00012952 +:106D3C0003D10A9922F01DFF03E04FF0FF314160AF +:106D4C000160287948B1484991F83810013102287E +:106D5C00217612D80221012811E04348022190F833 +:106D6C0038006175298800290A4618BF012222754E +:106D7C0018BF411E2176002008E00121032821754F +:106D8C0002D16775012001E001206075A0751A34ED +:106D9C0008F1010809F10109A3E7002600274DE0DD +:106DAC000598CBFA50F830480FAD4FF0020BAE1CE3 +:106DBC0000F139075FFA89F050453AD25FFA88F151 +:106DCC0087202A460BF0F2F8BDF8460039462080A1 +:106DDC00A01C22F0CEFE04F10A00314622F0C9FEBE +:106DEC00BDF83C001F49204B012209F1010908F1B3 +:106DFC00010860820978022938BF022293F83830E2 +:106E0C006275A3F1010238BF4FF0FF3202294FF037 +:106E1C000001227638BF012184F817B04900A17512 +:106E2C00002818BF01209DF84E10207561761A3489 +:106E3C00C0E7069FDDE908B4079E0025607CF1B22F +:106E4C009DF85B300022CDE90275CDE900B1A11CA3 +:106E5C000AF01EFB17B1384622F0DEFE17B0BDE873 +:106E6C00F08F00BF18260020407B00202DE9F04752 +:106E7C008AB0DFF8C0810446D8F80000416E02A841 +:106E8C008847DFF8B4A1DAF80800016C096811B979 +:106E9C00D0F84C058047694801210170DAF80C00E4 +:106EAC00C068007830B9DAF808000021D0F858240E +:106EBC000120904722F0FFFC476805893878C0F321 +:106ECC00401128460FF040FADFF874910790D9F87A +:106EDC00101019B122F0EFFC0C308847D9F80800DB +:106EEC0008B18047089057480078F0B1D9F82010C5 +:106EFC00B9B1884755490028554B0A4608BF02329C +:106F0C0012781A708DF82420CA1C002818BF4A1C4D +:106F1C0010788DF825004C481978022908BF0230EA +:106F2C0000E0494801880131018016F05FF84A48B9 +:106F3C00484E0078F57350B122F0BDFC007D30B1A5 +:106F4C00284621F047FF1FF0EBF800286BD00025F6 +:106F5C003761758022F0ECFA07467580059524B1EF +:106F6C00012C31D13D483E49C1613C483949027B35 +:106F7C00437BC47D416045804D6002F0F00202739A +:106F8C0003F0F0020232427304F0F0020432C275D4 +:106F9C004A7B22F00F02531C4B73DAF808301B6C3F +:106FAC001C6864682478A40608D52E4C42F00202B2 +:106FBC004C601B685B689B784A73A3732A4E7060A5 +:106FCC00707B00F0F00070732848D8F8001008228D +:106FDC00274B0C6D00210068CDE9002102AA314637 +:106FEC00A0472449B0F1FF3F088007DD224819492A +:106FFC000160224801780131017010E0D9F800409D +:10700C0044B1DAF80800002100220023006C00686B +:10701C000C30A047012041F2883114F043F9384676 +:10702C0022F032FD02E0E1200BF050FB0AB0BDE88B +:10703C00F08700BF308800200C010020A32700201F +:10704C0024B802001C25002094860020A68700206E +:10705C00A6880020A885002090270020A08300206F +:10706C00006A18003086002074250020D8260020E5 +:10707C00E99200008A880020202500201925002094 +:10708C00B0B5784C20780E2850D8DFE800F0E34FEC +:10709C004F5E084F4F4F4F4F584F0808080073482A +:1070AC000078B0B1A078012830D1E0780130E070E0 +:1070BC00C0B2032851D870484FF6FF71808C8842BB +:1070CC004FD06C48012101704FF44170A4F80100BD +:1070DC0049E06C480021E170017000201CF0B0FE0A +:1070EC0018B120780D38012862D861480078022840 +:1070FC0003D10820012104F009FC052020F0F2FC4A +:10710C0042F21070BDE8B04020F092B803282AD1AA +:10711C0057480078022826D15648012101700320D7 +:10712C000021A070544880F826101CE015F0F6FEE3 +:10713C00554810210078BDE8B04016F083BF4A488E +:10714C00008800F007000128A9D148480078F8B160 +:10715C000020BDE8B0401AF013BB48480078012865 +:10716C0001D10020A07019F07FFE20F07BFB3E487F +:10717C008078000703D54248007801286AD1A078AE +:10718C00032867D108200121BDE8B04004F0BEBB44 +:10719C003D481021007816F055FF00201CF050FEE1 +:1071AC00334D297810B361B3207801292AD036E009 +:1071BC00062020F097FC2C4CA078000704D54FF447 +:1071CC000040012104F0A2FB29480078012809D8CD +:1071DC00208800F00700022804D0002000210022A3 +:1071EC0021F078FFBDE8B04015F098BE022903D11C +:1071FC000820012104F08AFB052020F073FC0120FB +:10720C00A7E720780A280AD11748008800F0070061 +:10721C00022813D01848082180F826100EE0032805 +:10722C000CD115F07BFE19480078022806D10120FC +:10723C001FF04CFC02200121FDF7A6FA062020F0DD +:10724C0051FC2878012805D80748008800F0070071 +:10725C00022800D1B0BD002000210022BDE8B040C2 +:10726C0021F038BFC426002026870020BB880020D0 +:10727C00182600209E880020407B00209388002048 +:10728C00BA270020AE220020998800200888002010 +:10729C002DE9F04F93B01C9C08901D4606928B462E +:1072AC0020461EF035FB074620461EF019FB002633 +:1072BC000790002F00F0E780002D18BF01254FF03C +:1072CC000008680100F14001BBF1000F08BF690123 +:1072DC0005914FF6FE754FF00A0108BF0821049185 +:1072EC0009A90431019100F108010C3003910290BD +:1072FC00207C804580F0C280380600F0BF8004EB13 +:10730C00C80B9BF81C00C00740F0B28060480078A6 +:10731C00012802D89BF81600D8B34FF0000A9BF84E +:10732C0016000F96CDE90D6678B15A49BBF81800D6 +:10733C0091F86810012923D1FF21ADF8340003988E +:10734C0041F208098BF81A103EE0BBF81800A8426D +:10735C0036D104208DF824009BF81D00ADF83000C8 +:10736C0009A818F0CBFD089C0198002100220023ED +:10737C00ADF83450A58016F055FFDDE9049024E0FB +:10738C00089C4FF00C09A080681CADF834000298E2 +:10739C001BE0BBF8180022F01AFB0028BDD00079C6 +:1073AC0040F002000328B8D19BF81C0040F080008C +:1073BC008BF81C00079800065DD04FF0010AAEE771 +:1073CC00ADF83400DDE90490089C8DF836000120FE +:1073DC008DF83900207D8DF838000DA808F0F0F8F4 +:1073EC009DF8480078BB109806994176417DA0F82D +:1073FC0016908BF81B109BF8161019B1254991F8B3 +:10740C00681001771C9A51890185518A4185117D3B +:10741C0080F82C10517980F83A109BF81A1080F8EB +:10742C003B102189A0F84010617D80F849106268FA +:10743C002169C263406C227D21F0A4FE0DA81BF0D3 +:10744C0057F89DF848009BF81C1041F001028BF88E +:10745C001C2020B141F009008BF81C0004E00798B7 +:10746C00013FA0EB0A0007901C9C4FF6FE7500260E +:10747C0008F101083CE700200790F9E720460021BD +:10748C0017F00EF90646304613B0BDE8F08F00BF7A +:10749C0018260020407B0020BFB581780446481E8A +:1074AC000B2812D8DFE800F006525C6A267885902B +:1074BC00A430B23900208DF80400E0780F28C0F019 +:1074CC00B28002208DF80400B3E0FF2940F0D38095 +:1074DC000025E01C04218DF803501FF019F86C49AD +:1074EC0008606C48058011F083FE0DF103036F20DA +:1074FC00FF21BDE000208DF80800E07802F0AAF82A +:10750C0002AB6F200521B3E020F02CFB8DF80E00B0 +:10751C000DF10E036F200A21AAE000208DF80F0058 +:10752C00E01C22F077FB0546601D04211EF0F0FFE5 +:10753C00014628460DF0CCF8504A3520282122F07F +:10754C005FF90DF10F036F200C2191E000208DF8F5 +:10755C000600E0780F2870D302208DF8060072E048 +:10756C00E07847490DF10703002818BF0120087087 +:10757C00002003218DF807006F2079E0E2780020CD +:10758C00211D8DF80A0004F10C00022A68D0012A92 +:10759C006AD117F0E3FE65E000208DF80C00E0786E +:1075AC00002818BF012020F055FE03AB6F200621E8 +:1075BC005EE0E078211D19F0DBFA8DF80D000DF17D +:1075CC000D036F20072153E00020E57804218DF88E +:1075DC000900201D1EF09CFF002D014618BF01253F +:1075EC00284621F0D9FB0DF109036F2008213FE05B +:1075FC0000208DF80B00E078002818BF012022F045 +:10760C00B7F80DF10B036F20092131E000208DF844 +:10761C000500E07804281BD21B4A01211070512070 +:10762C0022F0EEF817E0194A01211070522022F0D6 +:10763C00E7F801AB6F2001211AE0124A012110700A +:10764C00532022F0DDF80DF106036F2002210FE02C +:10765C0002208DF805000DF105036F200B2107E0CA +:10766C000BF0A6F88DF80A000DF10A036F20042127 +:10767C0001221AF0FDFF002004B0B0BDF082002002 +:10768C00AE270020C2270020CC270020C8270020CE +:10769C00082500200425002070B590B004468078A1 +:1076AC0021F0E2F8002800F0D38005466078A0F1C4 +:1076BC00E101E873102906D91A2818BFCD2808D083 +:1076CC001D2806D04BE0012202FA01F16C4A11424E +:1076DC00F2D06C4E3078012802D8688900056CD441 +:1076EC002846002108F0BEFBC0B3307801282BD807 +:1076FC006548807B800727D52968086A20B3C97F35 +:10770C0003AA09F0D5FC6078E92808D12868E27B47 +:10771C000123418900880093E92301F077F8286858 +:10772C00BDF8161001809DF81120BDF81810BDF899 +:10773C001600002A18BF012292010CF0EFF918B1C3 +:10774C00688940F0200068816A896178288920F076 +:10775C00A9FA28813078012831D971E060788DF848 +:10776C001000A07B03958DF81100287C00283ED0DA +:10777C0003A812F06FFE9DF81030E92B00D03BB936 +:10778C002868E27B012641890088009601F03EF8CA +:10779C003C480078012853D83B48807B80074FD564 +:1077AC00687B022802D1688940073BD46078E928BD +:1077BC0046D128461BF03CFA42E0052068736078FD +:1077CC00E9283DD03148006800B18047304E306820 +:1077DC00B0B32D48807B800732D52868418900885A +:1077EC001BF022FF60B361783268904728E003A851 +:1077FC0005F0EEFD2348007820B19DF810300128EB +:10780C0002D0BAE79DF81030002BB6D1286800885A +:10781C001CF0AAF90028AED11C4800680028AAD098 +:10782C008047A8E7286800881CF09EF9002811BF43 +:10783C00032028684FF6FF71018008BF052068738C +:10784C00687B022804BF06206873A07812F002FD42 +:10785C001FF028FB0B48007802280ED10D48007849 +:10786C0058B900200DF10B018DF80B0052201AF0C5 +:10787C00FFFB2020012104F049F810B070BD00BFBF +:10788C000101010018260020407B00207C230020F1 +:10789C0080230020D52700202DE9F04F8BB0846980 +:1078AC0006462588B4F8029028461CF05DF901289C +:1078BC000DD1307C717C00228023CDE90052CDE9C2 +:1078CC000220B21C48F2060017F0F0FCD4E0284667 +:1078DC001CF04AF920B96B480088854240F0C780FB +:1078EC0008962679651D5EB1700022F097F938B1C3 +:1078FC000246304629460A9221F036FB054602E044 +:10790C00002000260A9015F8017B57B1780022F070 +:10791C0085F930B1024638462946099221F024FBFC +:10792C0002E0002000270990B8191421DFF85CB19F +:10793C004FF6FF754FF0000801EB4000C0B2079006 +:10794C007800069070000590DBF800B0BBF1000FDA +:10795C0069D0DBF8040001780029F5D09BF80E20E3 +:10796C00D207F1D0DBF808401CB10120A0478246B9 +:10797C0001E0D0F808A0BAF1000FE5D0BAF8020087 +:10798C00814518BFA94526D1DAF808309AF80720A6 +:10799C000A9930461EF0D4F840B9DAF810309AF84B +:1079AC000C20099938461EF0CBF8A0B107981FF0AF +:1079BC0055FB38B30546D2202870089840882F73A1 +:1079CC002E7168804EB10A99059A05F11400A860D1 +:1079DC0021F0D8FB03E014BBB6E70020A86047B148 +:1079EC0005EB46000999069A1430286121F0CAFB70 +:1079FC0001E000202861DBF804002946406800788B +:107A0C0017F04CFB9AF80000214A5FFA88F108F154 +:107A1C000108002C4FF6FF7550543FF495AF5046BB +:107A2C0022F0FAF890E7089C0A9D5FEA086011D0F2 +:107A3C0014485FFA88F3227C617C0088CDE900034E +:107A4C0013480023CDE90202A21C48F2060017F0ED +:107A5C002DFC01E0207B90B115B1284622F0DCF81A +:107A6C00099848B10BB0BDE8F04F22F0D5B80648E4 +:107A7C00007802283FF41DAF0BB0BDE8F08F4FF03B +:107A8C000008D5E7708700201826002020880020E9 +:107A9C00148100202DE9F04788B004464FF0FF30E8 +:107AAC0002214FF6FE79CDE90200E089002808BFDB +:107ABC000821A66916F801A030B1714835880088F4 +:107ACC00854213D16F4E06E06E4831461FF0E7FD3C +:107ADC0090B36B4805884D4518BF002E29D1207BEB +:107AEC00002840F0C9806948406843E06648007847 +:107AFC0001281CD8284621F06AFFC0B10179002664 +:107B0C0001292DD140880DF110088DF81060ADF8C9 +:107B1C001C00404618F0F2F90646002818BF08F180 +:107B2C000406BAF1000F18BF4FF0FF3AD3E7002656 +:107B3C0016E05648406825E05348007801280DD8D7 +:107B4C00304621F098FF48B101790139012905D857 +:107B5C00BAF1000F18BF4FF0FF3ABBE74FF6FE75B6 +:107B6C00207B002840F08880484840684D4518BF6D +:107B7C00002E07D1E1894FF0810881B100F8018B0B +:107B8C0002AE11E05FFA8AF1022902D24FF000082E +:107B9C0007E0217B01296FD04FF0800801E009F14B +:107BAC00010500F8018B0EB1314600E002A921F06D +:107BBC00E0FF0570064605803348007838B10B2786 +:107BCC0001284BD15FFA8AF0012804D046E05FFA15 +:107BDC008AF0012824D10B27B8F1000F3ED1284898 +:107BEC00A9B20088814239D100250DF107008DF82A +:107BFC00075016F0E3FDA8B1E1890322002908BF64 +:107C0C000922A1698B5C9DF8072000EB43019A4285 +:107C1C000BD9D21A0D258DF8072005EB420708E089 +:107C2C000B271BE00C27B57018E000220D278DF8F0 +:107C3C000720F370331DB27012060DD011F8022B11 +:107C4C0003F8022B11F8012C03F8012C9DF80720E6 +:107C5C00013A8DF80720EFE721F0DEFFE2890B4DAA +:107C6C001020A11CFBB2A87004F1110042F40042D8 +:107C7C0017F0CCFB0020A87008B0BDE8F08700BF5F +:107C8C0070870020C8870020182600207C26002042 +:107C9C002DE9F04F8BB0002900F0EA80DDF858A0F8 +:107CAC000746007A0D46994690465FEA0A718DF8B0 +:107CBC00060012D4387A02240F2800F2DA8001214F +:107CCC00814011F00B0F19D003288DF8100024D12E +:107CDC0002A8394621F04DFF22E0022840F0C8806E +:107CEC003C8821F05BFC8442E4D0388801210322DB +:107CFC0013F0E8F90028DDD0CD24BAE048F20400F6 +:107D0C00014200F0B68038881BF02EFF002800F0EE +:107D1C00AB800F2038728DF810003888ADF8080051 +:107D2C005FEA8A7014D40020ADF81800534800683C +:107D3C0088B14168A942FAD1826862B129780220DF +:107D4C00904768B10188ADF8181021F065FF07E085 +:107D5C004FF6FF7002E0A86810B14088ADF818002B +:107D6C00CAF380129DF810301798DDE9141B8DF8BA +:107D7C00052010225C1E02EADA0218BF01240F2B28 +:107D8C00134618BF43EA84035FEACA6458BF13461C +:107D9C000AF0400243EA92125FEA4A73ADF82020DF +:107DAC0044BF4032ADF820208DF824000791ADF887 +:107DBC001A90ADF8168000229BF800007C7A7E8920 +:107DCC005FEA8A618DF804202D498DF8220028780D +:107DDC008DF81340ADF8146009788DF8120048BF87 +:107DEC0004218DF8231020F003FD28B1016919B18D +:107DFC0002A888477C7A7E893046214621F070FCA7 +:107E0C0028B120F0CFFE48450DD2022413E001A882 +:107E1C0020F0A4FF48450AD21A4801680029F4D082 +:107E2C0002A8884706E002A806F0D8FB02E002A8E8 +:107E3C0000F0C0FE04469DF8100002280CD1BDF8DD +:107E4C00086021F0ABFB864206D19BF80010287825 +:107E5C00424623461BF0F8FA5CB99BF8000000245C +:107E6C0001308BF8000004E0387A0F287FF42CAF37 +:107E7C00022420460BB0BDE8F08F00BF2088002004 +:107E8C00E71D0020F42600202DE9F04F8DB00746A9 +:107E9C00C08914468946073086B2304610F084FA01 +:107EAC000546FF280AD13046FAF73EFCB04205DA07 +:107EBC0070480778002F08BF0527A3E06D4E307877 +:107ECC00C0B91CB1022C15D1FF2D13D1387A002268 +:107EDC0003238DF81C007868009206906648C188D0 +:107EEC00C07805AA02F054FA9DF824003874BDF845 +:107EFC002000B881DFF880B1002104239BF80340F7 +:107F0C00BBF806A00CAA204621F004F99DF830001D +:107F1C007E2805D120467C211CF0A2FB9DF8300068 +:107F2C007C286BD1FD8905F107081AFA88F0B0F5A9 +:107F3C00005F65D8BB88C5F385120490F888494664 +:107F4C001FFA88F94FEA850C8DF82DC042EA83128E +:107F5C008DF82A00C0F301208DF82C209A088DF89A +:107F6C002B203A7A05EB0A07B9F10D0F40EA820093 +:107F7C008DF829004AD23F482A460197CDF80CC00B +:107F8C0000F11C06304621F0B5FEDDF82900711910 +:107F9C0000220027029170519DF82D000871681D78 +:107FAC0081B2304621F024FBDDF8291032464B46D5 +:107FBC00715196212F4D8DF82F10039921F0E1F975 +:107FCC0002998DF82E000B98C1F8030020465146FB +:107FDC001BF056FE04EB4401049A28700BEB810154 +:107FEC008A83BBF806104144ABF8061050B10198D7 +:107FFC0081B2204618F0A8FB2F7803E0012700E09F +:10800C000527377038460DB0BDE8F08F8946084615 +:10801C002946002221F0ECFA0DF12901052220F06D +:10802C0035F996214A462B468DF82F109DF82D10C8 +:10803C0021F0A7F951468DF82E0020461BF020FEAA +:10804C003070B9B220460DF1290207231BF018FE3F +:10805C00317851EA00073770D4D104EB440004990D +:10806C0000270BEB80008183BBF806004044ABF883 +:10807C000600C7E7A0230020A08000202DE9FC47C4 +:10808C00D0E900588246D8F80000D0F8409019F496 +:10809C00F06FC0F8449035D05FEA495117D5D5E957 +:1080AC001401411A50461DF0F1FED8F80000816908 +:1080BC00C90605D401688DF807109DF80710F6E77E +:1080CC00296801312960A97B09B90121A973696C5F +:1080DC0040684FF0004600F00F0404EA0100B0FACB +:1080EC0080F126FA01F1014005D02F6C1FB12A68EE +:1080FC00AB6C5046B847B4FA84F026FA00F0204036 +:10810C004042A863D5F85801D8F83C1009F0400754 +:10811C0040680068D0F804251140394347D0DAE9AB +:10812C000064504614F0C6FED7B1F07C90B90BE059 +:10813C00316F69B10068B16EB26F8854306FB16F36 +:10814C0001310138B167306720688169C906EFD504 +:10815C00F07C28B1D6E91401411A50461DF096FE68 +:10816C0096F86400E0B13079022819D017B1B179D2 +:10817C00012901D0316F99B90024B16E01283467FF +:10818C0086F86440B46607D1B36CB26FD6F8CC6095 +:10819C0050460094B04703E006F17C0021F050FDFE +:1081AC00504609F0E5FAD5F858014068006800F22D +:1081BC0004500068D8F83810084228D0D5F8F800D8 +:1081CC0028B3DAE90076504611F0C4FE50460CF0A4 +:1081DC001DFD7879012812D1D7F8F40078B997F8F9 +:1081EC00E80060B1002087F8E800BB6CD7F8EC1011 +:1081FC00D7F8FC20D7F8504100905046A047D7F84C +:10820C00F80020B93068816B41F4006181635FEA4A +:10821C00095023D5D8F8000081690907FCD4016BFB +:10822C0021F480710163297A91B10020287295F8AC +:10823C004400800606D52C6C24B1AB6C5046202132 +:10824C000022A047504601211EF0A1F9D8F80000E9 +:10825C00816B21F400618163687908B1BDE8FC870A +:10826C0005F58070BDE8FC4721F0EABC2DE9FE4F16 +:10827C001D4614460F46814621F05AF9DFF8C0A17D +:10828C0083464FF6FD78DAE90010494518BF0846D9 +:10829C0060B1B83021F098FC40B19AF82400CAF8CB +:1082AC00209040F004008AF824009FE01FF0AAFB05 +:1082BC00002868D006466348CDF808B0DDE90CB854 +:1082CC0021F0DCFB604908F0200EB1F854000130BD +:1082DC006FF31F30A1F85400B5605C480025C6E967 +:1082EC0003792268D4F80C8086F83250C6E9085518 +:1082FC000BEA000C207C72632279C6E906CEC6F824 +:10830C00408086F8440086F83820B1F8541086F87E +:10831C003350D4E905533186A168C6E91253F16391 +:10832C00A18BA6F8501028B9B8F1000F1CBF012082 +:10833C0086F844004AB9387B00F00F00022804D1BB +:10834C00012086F83800B8687063DDF808B00822A0 +:10835C00FF2353FA82F23C46D0B2851A18BF01258E +:10836C007F680FB1002DF4D1208800F47C40B0F56B +:10837C00305F0BD196F833000022082340F0100038 +:10838C0086F8330004E008F101082FE000220223F4 +:10839C004CEA03004EEA02012B4DC6E90601DAF85D +:1083AC002000484507D19AF82400C1071CBF00F0F3 +:1083BC00FE008AF824002648046854B1A96CEA6CC3 +:1083CC0005F1400005F1380300903046A04703301A +:1083DC0013D1FD209AF82410CAF820904FFA80F897 +:1083EC0041F004018AF8241020F0ACFE584621F02C +:1083FC004BFB0FFA88F0BDE8FE8FB6F83080B5F86D +:10840C005410414501D020F09DFEC0B2012801D886 +:10841C00FE20DFE7002089F8FC0096F8330040F0DE +:10842C00800086F83300A86BB04205D0F068007B62 +:10843C0000F00F000228D9D115F0D2F8D6E700BF12 +:10844C0070200020207F002030210020FFEFFF9FB4 +:10845C00842600202DE9FF41DFF8BC810020039029 +:10846C000290D8F83840B4B3D8F84C0010B9D8F80A +:10847C00480070B3D8F8480060B12069D8F84810AB +:10848C000969814206D194F83300C00602D5D8F8A8 +:10849C004C0090B1002702A887F0010103AA10F04C +:1084AC001FFE0546FFB9F5B10299002900F09D8029 +:1084BC005A4820F031F9002714E0D8F84800C06879 +:1084CC0040880028F9D0D8F84800C06840880128B6 +:1084DC00F3D00127DFE752480221283021F0B4FB0A +:1084EC000027002500242CB34E48466816B302988A +:1084FC00B0FA80F04009284001281BD1D8F8480078 +:10850C00D8F84C10039A87F00103CDE9003208F13A +:10851C00380208F14003B047012868D0022809D17D +:10852C00D8F84800012201230069D8F84810B1F9A5 +:10853C00301065E02046002C18BF0120384001287F +:10854C0051D1394821694068814203D034484FF4F5 +:10855C00806145E00298002818BF012028400128BE +:10856C0006D1D8F8480018B9D8F84C0000284DD0DE +:10857C0008201FF08FFD94F833004C25C00658BF1F +:10858C00482508F138001FF013F848F80500274B70 +:10859C00D4E90601C2439A60DA681043D860C84334 +:1085AC00186058680843214658600820E5681FF099 +:1085BC0049FA28461FF076F9288843F60601411A35 +:1085CC00022906D3B0F5C15F03D040F60201884200 +:1085DC0003D1012029461FF035FA11484FF0804194 +:1085EC00283021F031FBBDE8FF8100277BE70398A1 +:1085FC00002818BF0446B4F930102069012200236A +:10860C000092002206F03AFABDE8FF8108201CF027 +:10861C00C3F8BDE8FF8100BF30210020647F00203B +:10862C007020002084260020D01E0020081004405A +:10863C002DE9F0478AB0684D2868416E02A888473A +:10864C00664FF87918B1B87908B10020C0E020F075 +:10865C006FFFDFF88CA1804600249AF80000800799 +:10866C004FF0000005D47D2000210DF06DFE8DF83B +:10867C0018408DF80C4002945A4C0790616911B166 +:10868C009AF800008847E06808B180470890387A6B +:10869C0098B1606A88B180475349544B8A1D0028B1 +:1086AC0018BF0A1D12781A708DF82420CA1D0028D4 +:1086BC0018BF4A1D10788DF825004D4EDFF8349107 +:1086CC0000200590317BF27EB0607080D9F80800F4 +:1086DC0001F070018031317302F08001D0F8282450 +:1086EC00F4206331F17603218DF8181006F11C018A +:1086FC009047387980B99AF8000080060CD5286824 +:10870C00C06B8047317BB060029001F0F001023108 +:10871C00317301218DF80C1029683748344E384BD1 +:10872C000D6D4FF08071006801913449009102AADF +:10873C003146A84705463348B5F1FF3F058035DD86 +:10874C00B879002100240130B87178790130787142 +:10875C00FE60F8790130F871022012F0A3FD3C7133 +:10876C002948D9F808200188D2F8AC30D2F8D420A6 +:10877C001C7841EAC411D48C0180D2E9117193F8B0 +:10878C0000C0538D7486C481C0F80710C0F8037004 +:10879C008381508DC6E90A710CF001013086308B53 +:1087AC0020F0800040EAC110308309E0626812B109 +:1087BC00002000219047022041F2883112F072FD16 +:1087CC00404621F061F90020B5F1FF3FC8BF012000 +:1087DC000AB0BDE8F08700BF3088002014250020C7 +:1087EC00AD88002024B80200A6870020A5880020B0 +:1087FC00E87F00200C010020D82600202000430038 +:10880C00C90E010088880020E88600202DE9F84375 +:10881C00994617460C4680461AF006FF089D0646F8 +:10882C003DB936B9404621463A46BDE8F84318F002 +:10883C00F5BA6EB3002D3ED0624C207808B10128F9 +:10884C0003D16148806800B18047B9F1000F4BD06B +:10885C002078012800F2A5805C48807B800740D5F9 +:10886C005948C26812B13046494690475848317849 +:10887C000078884224BF01313170C9B20024814292 +:10888C0030D140461AF014F87470012701242EE000 +:10889C004C4800240127B9F1000F007829D0012D94 +:1088AC0027D1012825D84948807B800719D5404617 +:1088BC0019F0FEFF15E0B078B9F1000F0AD1C1191B +:1088CC004808022938BF01207178B07011B94149AC +:1088DC000978717040490978884202D90027002430 +:1088EC0005E00024012702E00027002437703548FA +:1088FC000078012D08BF02282BD084F001010F4213 +:10890C004DD1012812D83148807B80070ED54046C6 +:10891C0021F05DF850B11FB9417901F0FE014171B0 +:10892C00ECB3417941F00101417100E0BCB3254C3D +:10893C002078012821D82548807B80071DD540460A +:10894C001FF012FEC8B100204146BDE8F84321F0EB +:10895C005BB9A9F119010229CFD3B9F1000F08D0E5 +:10896C00B9F1E10F18BFB9F1F10FC6D0B9F1EB0FA6 +:10897C001AD1154900220A70BFE71448408B4045B4 +:10898C000DD10120414621F03FF92078022806D173 +:10899C004FF400500121BDE8F84302F0B7BFBDE829 +:1089AC00F88300240127A4E7074A0C4913780978B7 +:1089BC000133DDB28D4228BF0023137028BF012480 +:1089CC009BE700BF1826002074230020407B00206A +:1089DC00D1BC0200D0BC020093270020C627002087 +:1089EC002DE9FE4FD0F80080994614460E4682467B +:1089FC0013B10020C9F8000020F09AFD834698F8C6 +:108A0C00070038B198F8640048B121F04FF86FF0C6 +:108A1C000805B3E021F04AF86FF00E05AEE0002C2B +:108A2C004AD0504614F046FA00200121C8E91A64D5 +:108A3C00C8F87040C8F87800C8F8380088F80C00FE +:108A4C0088F80A00504688F864101BF0C1F95046AB +:108A5C0008F08EFE08F14C0402AD204629461EF0AB +:108A6C00C9FDD8F870100746D8F878008F4288BF37 +:108A7C000F46029930443A4621F03CF920463946DB +:108A8C001DF030F8D8F87000D8F87810C01B3944B5 +:108A9C00012FC8F87000C8F8781001DB0028DCD171 +:108AAC0098F8041002290CD10020C8F8680088F846 +:108ABC006400C8F870001BE020F0F8FF6FF00905A7 +:108ACC005CE0A8B90020D8F86860012988F8640037 +:108ADC00C8F868000CD10124584688F8104020F0E2 +:108AEC00D3FF98F80F0000284BD020F021FD8346CF +:108AFC0020F0DCFF98F8040008B100252FE0D8F82E +:108B0C00701008F17C0031B30C9920F033FF10B1D8 +:108B1C00012088F80C0020F00BFD0446504614F0A0 +:108B2C00C9F90020C8F86800C8F8700088F864001B +:108B3C00504608F01DFE98F80A6098F80C50204634 +:108B4C0020F0A2FF002D18BF6FF00C05002E18BFEF +:108B5C006FF00D0503E00021002520F00BFF20F045 +:108B6C00E7FCB9F1000F07D098F8041001291CBFDD +:108B7C00D8F87810C9F8001020F086FF2846BDE818 +:108B8C00FE8F002598F810000028AED020F0D0FC05 +:108B9C00A8F80F4020F078FFD8F84830D8F87820A3 +:108BAC00D8F8CC70504631460095B84788F80F502D +:108BBC00E8E77047F0B587B004466F48007878B1A5 +:108BCC00228B0020E57A01210390CDE901008DF87C +:108BDC000910500706D402F008030121002008E018 +:108BEC00BA20AAE0402012F008038DF8060008BF56 +:108BFC000321402606EA82064BB1C02093068DF86D +:108C0C0006004FF0010358BF02238DF807305309BB +:108C1C0003EA121202F00802324342EA0106217AF8 +:108C2C0003290AD8DFE801F00215112540F00407EA +:108C3C0020F0B4FC8DF8067008E00F291DD140F02F +:108C4C00080046F004068DF806002088ADF80400F4 +:108C5C0013E04A4991F86810002900F080802788B9 +:108C6C0040F0080006F58056FF258DF806003846C2 +:108C7C007EE001A920461CF0B3F90027208BC00729 +:108C8C000ED09DF8060010F00C0F58D09DF8060081 +:108C9C0000F00C01042904BF40F020008DF8060000 +:108CAC00A07C8DF8080001A806F08AFC9DF818003D +:108CBC00002842D10498C682B4F81B10A0F81910F1 +:108CCC00217A012903D12D4991F868100177A17EF1 +:108CDC00E37F0185228B80F82C301306428508D562 +:108CEC00D20506D5417D94F820001DF0CEFCA17E66 +:108CFC000498878780F83B5080F84A10A17A80F856 +:108D0C003A10D4F80E10C0F83E10A17F80F84B102A +:108D1C00617F80F84910406C6169628A20F032FAF8 +:108D2C00208B400604D51648016809B101A8884774 +:108D3C0001A819F0DDFB9DF8180007B0F0BD2088E4 +:108D4C0016F094FE48B19DF8060040F020008DF816 +:108D5C000600208BC00799D1A2E7BB20EDE740F0BD +:108D6C000C00278846F004068DF806004FF6FD70BF +:108D7C00ADF8040082E700BF2C240020407B0020CB +:108D8C00602700202DE9F04F89B0714F14460A4638 +:108D9C00064610460492B98C1AF046FC054610B1F2 +:108DAC006878002866D0B06A4FF00E09B34690F888 +:108DBC000180867890F805A05FEA886158BF4FF073 +:108DCC000609B0F80300039004981AF0ADFF18F0F0 +:108DDC00870F4CD108F01801182948D09BF81C10AB +:108DEC00894544D100EB0A020021BBF80C00B146C6 +:108DFC000091D1B292460E46049B494632460EF083 +:108E0C0051FD032836D008F07801B8BB18F0180FC4 +:108E1C0062D05FEAC86088464FF0030058BF01205B +:108E2C0040EA0108BBF80C00414611F013F888B178 +:108E3C00817911F0180F0DD0417901290AD14DB16A +:108E4C00B98C40881AF0F0FB20B1407810B16978E9 +:108E5C0088420FD320F087FA88B94FF0FF3020807A +:108E6C009BF8080000286BD0DBF8181069E0D320C1 +:108E7C000DF049FF002009B0BDE8F08F884620882E +:108E8C004FF6FF718842F5D10121BBF80C00324638 +:108E9C0000914946049B0EF005FD0398414685B2AE +:108EAC00284618F075FAF98A88420CD1284620F029 +:108EBC008EFD20B300790138012820D805A9284659 +:108ECC001CF086FD21E0DBF8280080F805A009B035 +:108EDC00BDE8F04F1EF096BC787B884608B120F0B8 +:108EEC0042FA03984FF6FE710022434680B203F01B +:108EFC00EBFD0028C3D14FF6FF702080C4E71FF0B4 +:108F0C0079FE014605A820F034FE9BF808000128E4 +:108F1C0004D1DBF8181007A820F02BFEDBF8281082 +:108F2C00BBF80C00497805AA07ABCDE9003200224A +:108F3C004B4641F030010291294608F0DDFE99E7DD +:108F4C000021BBF80C00324620F04CFE97E700BF26 +:108F5C00407B002070B58AB000F116050446284607 +:108F6C001AF0DEFF67480078013801282BD8002062 +:108F7C001021012214238DF8110005AE0DF1110002 +:108F8C00CDE90210CDE900620DF11201042000229E +:108F9C001BF04EF950B15C48006804A905AE32468E +:108FAC0010F002FBC728ADF812000CD806F108002F +:108FBC002946082220F0E6F8BDF8121004201422ED +:108FCC0033461DF0F7F92846FF2108221FF036FD25 +:108FDC0010B14E480121017028461BF0ADFC2079E0 +:108FEC000138052800F28B80DFE800F00389345C3F +:108FFC008903A01D0021102913D0425C0131002AE5 +:10900C00F9D061791EF0F0F84348424D90F84100D8 +:10901C0008B12878D8B160790DF066FF002028706F +:10902C0015E03D4890F8410088B905AC002062215C +:10903C000025224610F086FC204600211EF0D4F8B4 +:10904C0000200DF051FFCDE90755CDE905551FF076 +:10905C00BBF854E00DF1120128461DF0C2FA60B1C4 +:10906C000DF112024FF6FE7029461CF093FF2846B4 +:10907C0000210022002315F0D5F8BDF8126005A9D7 +:10908C0030461CF0ADFA059828B905A81AF0A0F9DD +:10909C0008B905980680A11D284610F05BFD13F059 +:1090AC00F5FC2CE01A4E307848B30DF1120105AAEC +:1090BC00284610F079FA01469DF81200F8B1002507 +:1090CC0001201422ADF8240006958DF82650059544 +:1090DC0005AB04201DF06EF906344FF4817010219D +:1090EC00224620F087FB28B94FF4817010212246CC +:1090FC0020F086FB01200321357018F065FB0AB0C7 +:10910C0070BD00BF18260020DC8700209C88002042 +:10911C00B0220020AF220020407B002070B58CB024 +:10912C00044600208DF82C00CDE906000890A078AC +:10913C00411E052925D82220DFE801F00321212C2E +:10914C0023036248007820BB20F000FB40B9604D3F +:10915C00A168082205F1180020F014F82088288056 +:10916C005C480078022814D1A0680DF1030101AA13 +:10917C0010F01AFA9DF8140038B1B1206CE01B20E5 +:10918C0008E0B3208DF82C0059E09DF8030000286E +:10919C00F3D023208DF81C000120A17B8DF81A0040 +:1091AC0020888DF81D102169ADF81800607B08919E +:1091BC00012804BF21208DF81A0006A806F000FA39 +:1091CC009DF82C00D8BB0998456C05202870A07818 +:1091DC006870A81C616819B110221FF0D3FF04E05D +:1091EC000021C160816041600160A078062801D037 +:1091FC00012803D1E078A874133500E01235A1687A +:10920C00284620F086F8A17805F1080006290AD82E +:10921C00012202FA01F111F0520F04D02E49096813 +:10922C0020F0A7FC01E0217B017020881AF09CFC47 +:10923C0010B109980421C1829DF82C0070B123480B +:10924C00007838B920F082FA20B921480021C0E911 +:10925C00061101809DF82C000CB070BDA07804287C +:10926C0014D1A06801AD0DF103012A4610F09CF950 +:10927C0006469DF8030018B94FF6FF708642DED003 +:10928C00206968B106A80EF045F90CE0206918B108 +:10929C0006A80EF03FF9D2E706A819F029F9CEE797 +:1092AC0006A819F025F9A16805F1080008221FF09D +:1092BC0069FF0120314614222B46ADF81400002022 +:1092CC00CDE9010004201DF075F8B8E71826002040 +:1092DC0050240020AC270020DC870020F8B5634E1A +:1092EC0001211D461446F068C068017060480021D9 +:1092FC00017060480170B068016C096811B9D0F850 +:10930C004C0580475C48076847B15C4822462B46B1 +:10931C004188B068006C00680C30B84715F0E24F1B +:10932C0014D057480178013901705448406818B17D +:10933C005448C1890131C181B068006C0068406833 +:10934C00007880066FD41CF0B1FF6FE020070CD4BE +:10935C004A48406818B14B48C1890131C18148481D +:10936C000178013901701D205EE0454C42F2054246 +:10937C002078013820704448418841F00400904224 +:10938C0018D13E48406818B13E48C2890132C281AA +:10939C003C4842890132428142F20542E12091422D +:1093AC0008BF1C2009F092F9207800284AD094F9C3 +:1093BC00000040E0314842F606024188914212D04A +:1093CC00B1F5105F49D140693349086019F010FCC0 +:1093DC002E48007850B32F480168013138BF016026 +:1093EC000021018122E0406818B12648C189013171 +:1093FC00C18126480078C8B125480421007802288C +:10940C00204808BF0621425A013242522148416885 +:10941C00013138BF41600189428901318BB2018130 +:10942C00934288BF4181E92009F050F91448017832 +:10943C0041B190F9000000280ADCB068D0F84C0566 +:10944C00804705E0B0680021D0F8582400209047F0 +:10945C00F0680021C0680170F8BD406800283FF436 +:10946C0082AF0848C1890131C1817CE70C01002021 +:10947C0017250020A327002024B80200A88500206F +:10948C001925002094860020A08300201C25002094 +:10949C00A68800204C87002044880020FEB5044696 +:1094AC002C2020F0BBFB002820614BD02C211FF07E +:1094BC0005FD256920884FF6FF760DF10301AE827C +:1094CC0011F0A8FB48B30DF1030069461EF0CCFF68 +:1094DC00BDF80020B24220D0584902EB4200AA82CB +:1094EC0006226A82002251F820302A744FF47A72D4 +:1094FC00AB6151F820300133B3FBF2F541F8203069 +:10950C0005FB12324AB901EB8000012101724C4873 +:10951C004FF40061007814F095FD21692088083122 +:10952C0011F078FB1FF076FD256970B14FF4D00077 +:10953C00C5F812000220287442480168A961013163 +:10954C00016021E010202075FEBDA88AB0421BD11D +:10955C003D4F05F1080039681EF0A1F858B93D6877 +:10956C001FF048FB014628461EF099F818B91FF069 +:10957C0051FD00285FD02169208802F0EDFB2569A0 +:10958C0000B1AE8200202874A88AB04231D12F4895 +:10959C00C17A11BB90F8410001281ED10DF10B02CC +:1095AC00002001213A2301271EF004FD08B1AE82F0 +:1095BC0013E09DF80B002F74A8754FF46810C5F8D4 +:1095CC001200234801684A1CA961026029B91C4891 +:1095DC004FF40071007814F035FD2569A88AB0426B +:1095EC0007D1A1202075284620F016FB0020206111 +:1095FC00FEBD287C012801D10E210CE0A06808B129 +:10960C000D2108E01FF006FD0D2118B9A078C00748 +:10961C0008BF052125690D482977A17801F00301C0 +:10962C00007B012908BF05206870C0B21FF0FAFD4D +:10963C0021694877FEBD2569A6E700BF1883002085 +:10964C0099880020FC260020DC870020407B00202D +:10965C0008250020F0B587B0624C054694F82B0025 +:10966C0028B9614F0421387819F0A4FD30B35F4854 +:10967C00407808BB5E480078022803D194F82B0090 +:10968C00800619D494F82E0005F0C60668B1A80718 +:10969C000BD594F82B00C00607D41EF00AFC04204E +:1096AC000121FBF771F886F0020694F82B1006F0F6 +:1096BC003F00084384F82B0007B0F0BD94F82B0052 +:1096CC0005F006062178304384F82B0051B1E0B345 +:1096DC004648002101703878042107B0BDE8F040FD +:1096EC0014F0B0BC012004F12E03002101222070E3 +:1096FC0055201FF0C9FB94F82E0080B33C4800782D +:10970C000138012809D83B4D0021082228681FF098 +:10971C0095F910B91FF07EFC20B334480721017075 +:10972C0094F82B000021304340F0100084F82B00FB +:10973C00002005F07BF80028BED000201DF0C6F9F3 +:10974C0007200021FBF720F8B6E728480721017015 +:10975C000720002107B0BDE8F040FBF715B894F8DE +:10976C002B00B4E728680DF11B0101AA0FF01CFFB8 +:10977C000546214800780028CFD09DF81400FD281C +:10978C00CBD00228C9D01D480088854217D201AE23 +:10979C00142130461FF092FBFF2029461422334639 +:1097AC008DF8140004201CF005FE154905EB45004E +:1097BC00002241F8202001EB80004272426000251B +:1097CC005520012104F82E5F224620F019F8FF20C5 +:1097DC0003211AF073F8054804210570387814F049 +:1097EC0031FC69E7AC2200209F880020088800200B +:1097FC0018260020DC870020AA270020C6BC020007 +:10980C00804300202DE9F04788B00646109C0020CC +:10981C00DD099A461746C3F3C308E060A060606098 +:10982C002060E9B1E9462146102248461FF0AAFC07 +:10983C002046314610221FF0A5FC484620F039F98D +:10984C000020102805D0315C225C5140215401309D +:10985C00F7E70AF1800A1FFA8AF04FEA102901E0B3 +:10986C004FEA1A296E46280418D030462146102299 +:10987C00013D1FF087FC2046394610221FF082FC68 +:10988C00304620F016F90020102805D0395C225CF7 +:10989C00514021540130F7E70744E4E7B8F1000FD9 +:1098AC0025D06846214610221FF06CFCB8F10E0F33 +:1098BC0040D30025204639464246E560A5606560E8 +:1098CC0025601FF05FFC80202146102204F8080060 +:1098DC0004AE30461FF056FC684620F0EAF8102D16 +:1098EC0048D0705D615D484060550135F7E76E46C4 +:1098FC002146102230461FF045FC002780201FF027 +:10990C00EEFF21461022C4F80170C4F80570C4F8AB +:10991C0009706773207004AD28461FF033FC304685 +:10992C0020F0C7F8102F42D0E85DE15D4840E055CB +:10993C000137F7E70026204639464246A681A66045 +:10994C00666026601FF01EFC80202146102204F861 +:10995C0008001FF0C4FF04AD28461FF013FC684636 +:10996C0020F0A7F8102E22D0A85DA15D4840A0558C +:10997C000136F7E76F462146102238461FF002FCED +:10998C0000253046214610221FF0A9FF2560656096 +:10999C00A560A5811FF0F6FB384620F08AF8102D43 +:1099AC0005D0705D615D484060550135F7E708B042 +:1099BC00BDE8F0872DE9F84FD0E90158D8F8001030 +:1099CC00CA690A62D20740F0A480D8E9040105F103 +:1099DC00C8094FF0000A4FF0000B0843D5F8CC1023 +:1099EC0049680968C1F8040505F130000090BBF125 +:1099FC00010F00F29780D5F8C000002800F092808B +:109A0C00D5F8E0C0D5F8CC70DC2224232024BCF19E +:109A1C00000F08BFD82208BF1C2358F8033008BF1A +:109A2C0018247F68D8F8146058F804403F68D7F8B9 +:109A3C000415314211D0A16849070ED10168D5F83F +:109A4C00D0408C4209D1416939B9D8F800104C6A20 +:109A5C0024F002044C62C7F804659968490702D0E7 +:109A6C000BF1010BC3E7AB58002BF9D045F802A062 +:109A7C00D5E934121A44BCFA8CF35B09C5F8D4202E +:109A8C005B01C5F8E0300368994228BF9A420CD2BA +:109A9C002846414602F0AAF895F8FE000028DFD0CF +:109AAC001FF0BCF818BF8862DAE7D9F800204B46E3 +:109ABC0080F810A02AB153690BB11A46FBE702F1EA +:109ACC0014031860C5F8D4A0BCF1000F4169C0F8AC +:109ADC0014A04FF0D800C5F8C01008BFDC202858DF +:109AEC00C5F8D00059B12846414602F07FF895F8E8 +:109AFC00FE0050B11FF092F818BF886205E0D8F84C +:109B0C000000416A21F003014162009820F09EF8A8 +:109B1C00A6E7D5F8C0203AB103211174BDE8F84F7F +:109B2C000EF068BBBDE8F88F486820F00200486072 +:109B3C00486A20F003004862D8E904021043D5F8C3 +:109B4C00CC2052681268D062C2F80405486920F033 +:109B5C0001004861012008624046BDE8F84F1DF045 +:109B6C007BB970472DE9F04F8BB0DFF8A08104462C +:109B7C00D8F80800D0F80001807AC00020F04EF828 +:109B8C000028099000F0B5804FF000091FF0D0FCC0 +:109B9C00009001AEFF270025D8F80800EAB2D0F8F3 +:109BAC000011CB7A9A422CD2D0F88824D02031469E +:109BBC008DF80650ADF80440904700BB9DF810009E +:109BCC0020B101281BD19DF80F1001E09DF80B105E +:109BDC00A9B100284FF0080008BF042000218142E1 +:109BEC0003D272180131D770F9E73044314680F84E +:109BFC000390D8F80800D0F89424D0209047013571 +:109C0C00CAE74FF6FF7701AE0DF1140A4FF0FF3B98 +:109C1C004FF00009C9885FFA89F291426BD9ADF80F +:109C2C000620D0F88824D1203146ADF80440904766 +:109C3C0030B1D8F8080009F10109D0F80011E9E7B2 +:109C4C00BDF80800B842F4D0ADF81400D8F80800FC +:109C5C005146D0F88824D4209047002841D10025C3 +:109C6C00D8F80820D2F80001C1888D4216D2D2F85B +:109C7C008824D1203146ADF80650ADF80440904709 +:109C8C0028B9BDF81400BDF80810814201D0013587 +:109C9C00E6E7D8F80800D0F80001C1888D42C8D199 +:109CAC00CDE907BB099AADF81A70ADF81870807A37 +:109CBC00C1000020814214D0131808309B88A342A5 +:109CCC00F8D11118002241F8082C09990844514682 +:109CDC0020F8047CD8F80800D0F89424D4209047BD +:109CEC00A7E700981FF0D0FE09981FF095FF1920E8 +:109CFC0008E01A2006E000981FF0C6FE09981FF035 +:109D0C008BFF00200BB0BDE8F08F00BF0C010020D2 +:109D1C00FEB50C4615F032F8A00600F18280200446 +:109D2C0000F1AF80E00607D52E208DF804006048C6 +:109D3C001FF075FE01A88847E00707D025208DF895 +:109D4C0004005B481FF06BFE01A88847A00707D5ED +:109D5C0026208DF8040056481FF061FE01A88847A4 +:109D6C00600707D527208DF8040051481FF057FED7 +:109D7C0001A88847200707D529208DF804004C48F6 +:109D8C001FF04DFE01A88847600607D52D20ADF8C1 +:109D9C00040047481FF043FE01A88847200607D55A +:109DAC003020ADF8040042481FF039FE01A8884766 +:109DBC00E00507D53520ADF804003D481FF02FFE17 +:109DCC0001A88847200505D53720ADF8040001A867 +:109DDC001FF092FFE00405D53820ADF8040001A86F +:109DEC001FF08AFF324CA068D0F898000068B0B120 +:109DFC001FF09EFBA168D1F898100A68029200220D +:109E0C000A601FF041FEA068D0F8981002984860D4 +:109E1C00A168D1F840138847A0681FF00DFC002002 +:109E2C00FEBD234E02ADB068C06B04301CF0DBFFEE +:109E3C00002802903FF473AF1FF07AFBB168C96B36 +:109E4C000A7B013A0A731FF01FFEB1680298D1F821 +:109E5C009810077848608DF80470417839B1162F46 +:109E6C000BD1B068D0F8541328468847DBE7B168AB +:109E7C00D1F840138847162FD5D0B0681FF0DCFB03 +:109E8C00D1E70B4DA868D0F89400007814F0D8FDF9 +:109E9C00002802903FF446AFA968D1F898104860AA +:109EAC00A968D1F840138847A8681FF0C5FBE9E7FB +:109EBC000C0100202DE9F04706680446307B02288F +:109ECC0012D196F823006568D6E904A79146884616 +:109EDC0080B1B16858481FF04DFD40B100206FF0C3 +:109EEC00010786F8250055E06FF0060752E00120C7 +:109EFC0086F82600002052492246F0614F48C6F8E9 +:109F0C00008086F821901EF06DFD297827201EF028 +:109F1C0035F850463946062203F0DAFF58B196F868 +:109F2C00260098B344481FF08BFE002086F82600CC +:109F3C0086F825002AE0434D434FD5F8800320F0E6 +:109F4C000200C5F8800396F82000042804D157F8C5 +:109F5C004C0C4169272088470220C5F8FC02386860 +:109F6C00416806208847C0B14020286080202860C6 +:109F7C0096F8260038B130481FF062FE002086F8B3 +:109F8C00260086F825000020C5F8FC024FF0FF30B3 +:109F9C00F061F7693846BDE8F0870220BA461BF03D +:109FAC00FFF90027B9F1020F0AD0B9F1040F4FF0F5 +:109FBC00000006D0B9F1060018BF0120800000E0B7 +:109FCC000020C5F84C010123D8F80C10D8E9010287 +:109FDC00C5F85011C5F8547186F82430DAF8003001 +:109FEC001D690B46A847256895F8200002281BD050 +:109FFC000428CFD1DAF80000816915488847B0F100 +:10A00C00FF3FDCBF4FF0FF30E8610020EF6985F8BF +:10A01C00240095F821100339022928BF85F8250062 +:10A02C00204619F0C1FCB5E708484FF0FF311FF08E +:10A03C00A1FCEF69AEE700BF307E0020B4840020A5 +:10A04C0089C5010004440240FC010010807E002000 +:10A05C00010000802DE9F0415A4E04465A4DB0687B +:10A06C00D0F8D41091F88380297819B1D0F84C0528 +:10A07C008047B068016C096811B9D0F84C0580476D +:10A08C00524F0120062C3C7028701ED8DFE804F0DB +:10A09C00040422252B5140004E4800214170B06829 +:10A0AC00026CD0F8D41010684B4AC08A40064FF0AE +:10A0BC004E0058BF2520085C107014BBC97801B342 +:10A0CC00022828BF022010701BE0B068D0F84C05A5 +:10A0DC0080472EE018F04CFD2BE03E4800214170EB +:10A0EC0018F070F825E03A4800213A4A0170B0683F +:10A0FC00006C006890F8691090F86A00517036494D +:10A10C00087009F0F5F8B068006C006888B940E098 +:10A11C00B068324A006C016891F86D1011803049BA +:10A12C00006890F86E00002808BF0120087019F034 +:10A13C00BBFF28480078A0B9B268106C016829B937 +:10A14C00D2F84C058047B068006C01684968254A14 +:10A15C00097801F02001117023490068406880786B +:10A16C0008703878062814D8012101FA00F010F094 +:10A17C004C0F0ED01FF0DCF90446387802280AD1B7 +:10A18C008320287020461FF07FFCBDE8F04119F0B9 +:10A19C0077BBBDE8F0811548017819B914490978E5 +:10A1AC000029EDD00221B8F1010F297004D10078FB +:10A1BC00832808BF15F0DAF92046BDE8F0411FF0FE +:10A1CC0063BC00BF0C010020B4880020B7880020BD +:10A1DC00A527002021260020B5880020AE8700206E +:10A1EC00B6880020C0880020C1880020AC880020E0 +:10A1FC00AF8800202DE9F0438BB0DFF884810C464A +:10A20C00054600208DF81300D8F80010002900F046 +:10A21C00AD80032D18BF022D03D191F8420090425E +:10A22C0008D1584900201BF03FFD3DB1012D03D151 +:10A23C0085240BE0002099E0032D0DD10121D8F8E5 +:10A24C000000032D80F8411003D114B18DF8134098 +:10A25C000DE000245DB91EE0022D07D1D8F80000F6 +:10A26C000CB1022100E0012180F841100024D8F843 +:10A27C00000090F84190B9F1010F0ED190F8431005 +:10A28C0019B1013980F8431005E090F8481011B16C +:10A29C00013980F848104FF0010990F8431049B18A +:10A2AC00426C00F12E03074602EB41018A1E00F1BD +:10A2BC0026010CE090F8481000295AD0C26C00F12D +:10A2CC000E0300F1200702EB41018A1E811D1E784E +:10A2DC00158802228DF828201CBB17B32A4A127845 +:10A2EC0080F8422003208DF81C007888ADF82000FF +:10A2FC0005AC20461FF03DFC7878BB7BCDE90054C3 +:10A30C00CDE902602120B9F1010F08BF222008A974 +:10A31C00BA1D11F093FE1D481A4900881BF0C4FCAD +:10A32C0023E041880DF1130448F220020123ADF81B +:10A33C0020104178CDE9004108A917F06DF9D8F843 +:10A34C00000090F8401002290DD1418C48F22002F7 +:10A35C000123ADF8201090F821102030CDE90041F8 +:10A36C0008A917F059F915F057FB01200BB0BDE8FF +:10A37C00F08300214FF6FF75FF260027A9E700BFE9 +:10A38C0038270020959902007C2600202E7E002084 +:10A39C002DE9F04F89B08246129803F0F00403F0D7 +:10A3AC000F0B002818BF01200392103C0025B4FAB3 +:10A3BC0084F464092040D4880290107A92886FF358 +:10A3CC009F2400F03F0024036FF39F2244EA0060B7 +:10A3DC00544C104400905248007804AEC2B2ABB258 +:10A3EC00934280F09580A27801355FFA8AF7974204 +:10A3FC0073D08AB20195172A6DD3A1F1070938469B +:10A40C0032461FFA89F421460FF052F99DF81B8051 +:10A41C0008F00300022826D1BBF1030F00F27D8067 +:10A42C000398007ADFE80BF0140205109DF8181061 +:10A43C0007E09DF81810884215D10398BDF8161046 +:10A44C00C088884204D00EE00498009981420AD159 +:10A45C000298002854D012980021836882893046D3 +:10A46C0015F0F2FF60B15FEA48701CD5BDF81E0014 +:10A47C0084421CD9A9EB000188B21728BDD228E070 +:10A48C0012988088E0B3129BDA8819689B681A448A +:10A49C000B7815789D42E6D1013802F1010201F1E9 +:10A4AC000101F5D12CE01F4C0120607104E038460D +:10A4BC00214616F049F91B4C00200025F8F734F919 +:10A4CC001748E17800780131B1FBF0F202FB101A69 +:10A4DC0003E013480078134C019D5FFA8AF1C2B275 +:10A4EC0051FA80F1013991FBF2F303FB121A5FFA76 +:10A4FC008AF1490051FA8AF104EB8101898B6DE7ED +:10A50C00039D96E81F001FC5002009B0BDE8F08F21 +:10A51C000399002088810A20F7E70420F5E700BFA3 +:10A52C0097880020A0800020B0B560480021604CC6 +:10A53C00016094F83A01032812D002282ED0012889 +:10A54C0040F0AF8094F8400111F070F9002084F8CD +:10A55C0040015948817B0220002908BF06209EE05B +:10A56C0054480168B1F5C060C4F82C01B8BFC1F5FE +:10A57C00C060D4F81011002900D5494288422ADD68 +:10A58C00D4F814011CF08EFDD4F818011CF09CFDBD +:10A59C00D4F828011CF0BCFD01201DE045480568DD +:10A5AC001EF010FEC4F814011EF014FEC4F81801BD +:10A5BC001EF018FEB5F5C061C4F82801C4F81011DE +:10A5CC0009D094F830215AB1D4F81401D4F82021D0 +:10A5DC00D4F82C110AE0002084F8300106205EE04B +:10A5EC00C4F82401D4E94502C4F82C110223C4F8A0 +:10A5FC001C01002948BF6FF0010301EB4101194414 +:10A60C00042391FBF3F111440029C4F820110FDD50 +:10A61C001F2931D3D4F824212AB33E28A8BF3E20C9 +:10A62C000130292928BF2921C4F81C010B3909E064 +:10A63C00D4F82421032A09D111F1140FD8BF6FF0DB +:10A64C0013011531C4F82011002113E00128D8BFE3 +:10A65C000120013811F10A0FD8BF6FF00901C4F8BD +:10A66C001C010B3103E0332928BF33211539C4F801 +:10A67C0020110321C4F824111CF014FD01201CF03E +:10A68C0035FDD4F820011CF01FFDD4F824011CF07A +:10A69C003FFDA5F2FF510420032938BF0620C4F862 +:10A6AC003C01BDE8B04005F0EBBC00BF3C500C4099 +:10A6BC00D81B002008400C4090BA02002DE9F84F3E +:10A6CC00584BDD1D584B93F800B000235B4505D269 +:10A6DC0015F8054C2CB108350133F7E74FF000099C +:10A6EC009DE04FF000095B4500F099804F4B0092C4 +:10A6FC00504A4FF0000805F8019C1E1D4C4BB2F857 +:10A70C0016A04FF6FE721F78012307B336F8044CDF +:10A71C008C4218BF544503D12436013F5B00F4E74B +:10A72C003478042C03D0012C06D0002CF4D109F180 +:10A73C00010905F8019CEFE702F1010CB0F80AE001 +:10A74C001FFA8CF4A64508BF48EA0308E4E73B4C23 +:10A75C00DFF8E0E0384B2678BEF824700A33B6B147 +:10A76C0033F80A4C8C4218BF944202D11C33013E80 +:10A77C00F5E71C88BC42F9D1DC79002CF6D01C7AA8 +:10A78C00002CF3D009F1010905F8019CEEE72C49E6 +:10A79C005FFA89F309788B4284BF05F8011C89465E +:10A7AC00009A5FEA096102D0817C012901D1002164 +:10A7BC0002E09EF80210013105F8031C9EF801100E +:10A7CC009EF80730B8F1000F05F8022C05F8041CB0 +:10A7DC008189C07C05F8053C25F8071C287011D030 +:10A7EC00184D194BBBF1000F0CD01E78284619469A +:10A7FC002EB14B1C051DABF1010B9642F2D1C0F8EA +:10A80C0000800A70114C4021207818F0D3FC20B93C +:10A81C002078402164221FF064F94FF0010948466A +:10A82C00BDE8F88F42760020D2BC0200B054002064 +:10A83C00E6BC0200407B0020DC5B0020D5BC0200A3 +:10A84C00D8BC0200C87A00204084002098880020E0 +:10A85C002DE9FE4F074600789B468A46029200F08F +:10A86C000C000C2808D1B888FE211AF0B3F8FE2889 +:10A87C00019008BF012019E059480568B878FF28F5 +:10A88C0008D01EF00FFD40B1064600781DF0B0FF59 +:10A89C00054603E02DB16E6800E00026FE20019015 +:10A8AC000EE0FE2000250026019009E01EF0FAFCC7 +:10A8BC00002800F09280064600781DF099FF0546AE +:10A8CC00002E00F08A80AA684AB1317802209047A5 +:10A8DC004FF6FE7440B104881FF09EF904E0B06896 +:10A8EC004FF6FE7400B1448839893078A14211D0FA +:10A8FC0010B909B900200DE028B14FF6FE720132F3 +:10A90C0092B2914206D0A1F580714FF6013289B214 +:10A91C00914244D897F80290B870387DD7F81080DF +:10A92C003030C0B21CF09AFBB8B304461A20514622 +:10A93C0020707868C4F80200A01D1DF06FFCBBF8F5 +:10A94C000100A4F817000C983A7D397B84F820009C +:10A95C000E986175A284E0610D986076F878E073CA +:10A96C00307820759BF80000A075788BA0857889CD +:10A97C006082029820820F9884F82E0032B104F184 +:10A98C0030004146A0621EF0FDFB01E00020A062F9 +:10A99C0070682146007814F081FB87F802903878B3 +:10A9AC0000F00C000C280DD0B8780026FF287FF49E +:10A9BC0087AF28680025002600283FF481AF466841 +:10A9CC0005467DE70199B888C9B21AF003F8FE284C +:10A9DC000146019001D0019868E7BDE8FE8F00BFE9 +:10A9EC00208800202DE9FF47D0E901590E46044686 +:10A9FC001EF09EFD95F8FD1021B97169102901D842 +:10AA0C00032906D81FF040F80024204604B0BDE806 +:10AA1C00F087012785F8FD701FF036F800204E4AAC +:10AA2C0085F8FC00C5E93000C5F8C80085F8FE00C3 +:10AA3C003069C5F8E4007069C5F8E800307B85F82A +:10AA4C00F9000028317885F8F8107168C5F8EC1019 +:10AA5C00B9F80E10A5F8F610317E52F8211085F8D1 +:10AA6C00FA1008BF1027C5F8F07099F80C000BF01D +:10AA7C0059F9204616F0C8F899F83B00374985F883 +:10AA8C00FB008A46D4E901873A6B97F83A000DF03F +:10AA9C0043FC7A6B98F8FB0051460DF03DFC98F89E +:10AAAC00F91097F83800012915D1FA6A51460DF0C2 +:10AABC0033FCBA6A97F8390046F202010DF02CFC0F +:10AACC0098F8FB0026491DF03DFA98F8FB0021464A +:10AADC001EF054F80AE0BA6A46F202010DF01CFCB2 +:10AAEC00FA6A97F8390051460DF016FCE8464046D4 +:10AAFC001EF0B8FA99F805001A4A4346CDE9004011 +:10AB0C00284699F8041018F065FA40461EF09AFB96 +:10AB1C00D9F80800144942460094029005F130001F +:10AB2C0019F088FE12F0F2FD104AC5F8CC0005F1C0 +:10AB3C001C00042123461CF0FDFA95F8F80008B11E +:10AB4C00B06805E005F16C0000211CF0BBFF084863 +:10AB5C00C5F8BC0059E700BF30BA02000260002003 +:10AB6C00CD090100C199000047650200259802003B +:10AB7C004B9A0200FEB504465A480078A04213D9FD +:10AB8C0008780D46012801D1686868B168780128F9 +:10AB9C0001D1A86840B1544F57F834601EF0C8FC7E +:10ABAC00F17921B11EF070FF00242046FEBD07EBA9 +:10ABBC00C40401216768F1711EF066FF002005F1E5 +:10ABCC00040C7074F081B06030602988B180A98B5E +:10ABDC00C6E93D00C6E90E0086F86400B186297D01 +:10ABEC002B69B1719CE80610C6F85021BCF1000F1E +:10ABFC00C6E910C34FF0FF32C6F8CC10A969C6E9FC +:10AC0C003B203163A97F86F83610296AC6E91A0001 +:10AC1C00C6E91C00B16486F8E800C6F8580102D1F8 +:10AC2C003249C6E9101097F840000BF07BF8D7E9D1 +:10AC3C00031206F14C001EF0EDFAD7E9051206F1ED +:10AC4C00D0001EF0E7FA2A4938680968C9688847B5 +:10AC5C007A6C97F8240046F202010DF05DFB254D4D +:10AC6C00BA6C97F8200029460DF056FBF8690128BC +:10AC7C000CD1FA6C97F8280029460DF04DFB3A6D73 +:10AC8C0097F82C0046F202010DF046FB12F03EFD47 +:10AC9C00C6F85801204605F08FFD174A06F5AE7030 +:10ACAC00042123461CF046FA6D4628461EF0DAF9BC +:10ACBC00387A7968114A2B460094019006F11400F9 +:10ACCC0018F088F906F17C0000211CF0FBFE06F55B +:10ACDC00807000211CF0F6FE3868D7E90C12106069 +:10ACEC00486062E7CABC02003CBC0200573E01004F +:10ACFC00D001001002600020B58C02008980000099 +:10AD0C002DE9F84F0CF09EFC5E480024002690F8CC +:10AD1C0000A0544510D2E0B21BF048FD50B10179AF +:10AD2C0041F00401042905D1807A1CF0ABFF002806 +:10AD3C0018BF01360134ECE700241BF00FFB05466D +:10AD4C000027E0B285420AD919F0E4FF28B1807CD3 +:10AD5C001CF098FF002818BF01370134F1E707EB0E +:10AD6C0006085FEA086032D04FF47F7000EA880969 +:10AD7C0048461EF053FF50B34946FF2204461EF0CE +:10AD8C0097F800275FFA86F94FF0000B574529D248 +:10AD9C005FFA8BF0484525D2F8B21BF007FDA0B145 +:10ADAC000646007940F0040004280ED1B07A1CF05D +:10ADBC0069FF50B10146727A30885FFA88F30093CC +:10ADCC00234614F04FFF0BF1010B0137DEE7002493 +:10ADDC004FF000082C48007BE0B11EF023FAC0F1C4 +:10ADEC00540018E000275FFA88F9F8B28542F1D9CF +:10ADFC0019F090FF60B10646807C1CF043FF38B11F +:10AE0C000146727C30882346CDF8009014F02AFF5E +:10AE1C000137EAE76220C1B20322A2462546B1FB04 +:10AE2C00F2F9B9F11F0F28BF4FF01F09C0B25FFA3A +:10AE3C0088F14446002818BF0120420102F1400766 +:10AE4C0049452A4684BF47014C46E0B2394612F0C8 +:10AE5C0004FA0022064617F0400008BF621E40EAC2 +:10AE6C000601A8EB02080020D2B2002905EB8205EE +:10AE7C00DCD0BAF1000F02D050461EF0CDFE3046A9 +:10AE8C00BDE8F88FE6BC0200407B00202DE9F84FAE +:10AE9C00814608688B469046D9E900454768068983 +:10AEAC005548E1681EF066FD18B16FF00100BDE871 +:10AEBC00F88F524852494FF0000A4A46C4F814B071 +:10AECC0084F80980C4F804A084F802A01DF08AFD5F +:10AEDC00297827201DF052F838463146062202F018 +:10AEEC00F7FF40B144481EF0ABFE4FF0FF3084F842 +:10AEFC0001A0BDE8F88F434F57F84C0C416927204F +:10AF0C008847414E0220C6F8FC023868416806208A +:10AF1C00884760B1402030608020306036481EF099 +:10AF2C008FFE002060704FF0FF30BDE8F88F0220DC +:10AF3C001AF036FA3A68DBF810009BF82010D26948 +:10AF4C0090473A689BF820009BF821101368A8F1F1 +:10AF5C000102B2FA82F252099847DBE90610C6F8F0 +:10AF6C0050010020C6F85401C6F8581159B13A687E +:10AF7C00DBF80400002315690022A84738688169B2 +:10AF8C00224801308847207A042804D057F84C0C0A +:10AF9C000169272088473B68DBF81C10DBE90202BB +:10AFAC001C690B46A047D9F8004001206070207A3C +:10AFBC00022815D004281BD13868144D8169284605 +:10AFCC008847B0F1FF3FDCBF4FF0FF3060600020DE +:10AFDC006070A81CC6F88403484610F017FF04E004 +:10AFEC000B484FF0FF311EF0C5FC6068BDE8F88FD0 +:10AFFC000020BDE8F88F00BF307E0020B484002014 +:10B00C00CDD20100FC01001004440240010000807C +:10B01C00807E0020F0B587B05C4E0446306848B3A3 +:10B02C0090F8401001293FD1022180F840102030C7 +:10B03C00214612F056FE05463068C169436B90F804 +:10B04C003220007E16F058FAB5FA85F137684D09B2 +:10B05C00002887F8430043D040001EF0DFFD37681E +:10B06C007864C8B397F843104A0049491EF08AF82F +:10B07C00376835E050201EF0D1FD306050B35021C0 +:10B08C0005461DF01BFF2846214612F02AFE08B388 +:10B09C003068012180F840103E483F49008807B0D5 +:10B0AC00BDE8F0401AF000BE02200DF10F0148F28D +:10B0BC00200201238DF8180088208DF80F0060887D +:10B0CC00ADF810006078CDE9001004A9204616F008 +:10B0DC00A3FA49E088201CE0882001258DF80F0098 +:10B0EC007B69BA7CF96B97F8380016F005FA316871 +:10B0FC0081F8480058B140001EF090FD3168C864DA +:10B10C0030B191F848104A0021491EF03BF86DB35C +:10B11C0086208DF80F0002200DF10F0548F2200259 +:10B12C0001238DF818006088ADF810006078CDE927 +:10B13C00005004A9204616F06FFA306890B190F8D0 +:10B14C00401002290ED1418848F220020123ADF8AB +:10B15C00101002218DF818104178CDE9005104A986 +:10B16C0016F05AFA14F058FC07B0F0BD306890F89D +:10B17C00431019B990F848000028C9D000200021CC +:10B18C00002207B0BDE8F040FFF734B838270020A4 +:10B19C00148100202E7E00209599020070B5604D20 +:10B1AC000446A8684169497F002973D0D0F8D4209F +:10B1BC00B4F84210D28C91426CD1D0F86C1304F1DB +:10B1CC0028008847002865D0A868002241694A7782 +:10B1DC00D0F8D41091F8291021B1E868816A0220C6 +:10B1EC008847A868006F90F82B0018B1E868816A4E +:10B1FC0001208847207CC00608D5E868816A1020A9 +:10B20C008847A868D0F8281380208847E868C16B65 +:10B21C0020208847A868D0F8FC14C06810308847F4 +:10B22C006268A86813785278416902F00F064E766E +:10B23C00C2F300114269917603F00F0142699177D4 +:10B24C001909D0F8D42082F82C10D0F8D410426907 +:10B25C0091F84F30927F0F2B05D09A4203D266683B +:10B26C00F67806B91A464A730022C16881F8302074 +:10B27C00D0F8D410497B0F290DD14169C97E022920 +:10B28C0008D1D0F864018047A868D0F86C01BDE8FB +:10B29C007040004770BDD0F80C2520469047A96837 +:10B2AC004869C07E022814D1C868D1F8FC148847BC +:10B2BC00AA684FF47076D2F8D430D2E90301D2F8F0 +:10B2CC00F0245B7B31F8131006FA03F3591A9047FC +:10B2DC00A968D1F8D400D1F8B431228990F82C1097 +:10B2EC0002209847A968D1F8D400427B90F82C0032 +:10B2FC0090420FD04869D1F8FC148847A86841697E +:10B30C00D0F87C018860A868D0F8F02440694169C5 +:10B31C009047A968D1F828131020BDE87040084761 +:10B32C000C0100202DE9F84F0446B0F82490C17BA5 +:10B33C00008A1EF0D5F948B9A07B032806D009F184 +:10B34C00140A1FFA8AF0F128C0F0A28009F11E0A33 +:10B35C001FFA8AF0FB280BD309F110001EF05EFCDB +:10B36C0050B3834610304FF01E0ACBF8040001E0B6 +:10B37C004FF0000B4FF0820801251FFA8AF01EF0E7 +:10B38C004DFCA0B10746A0783870E0787870207931 +:10B39C00B8706079F8708DB1A07BA11D3871A07B5D +:10B3AC00032813D1781D08221DF0ECFE12E0BBF12E +:10B3BC00000F01D05F4666E0BDE8F88FA079FE1D56 +:10B3CC003871E0797871E07BB8710BE008787871AE +:10B3DC004878B871E07B07F110067873207CB8735D +:10B3EC00607CF873207D3070607D7070A07DB070D3 +:10B3FC00607EF070301DE1691EF079FB0020307228 +:10B40C002DB14FEA192006F10B05B07201E006F1DF +:10B41C000A05BBF1000F86F809901ED01F48204E7C +:10B42C004FF47A720168CBF800100F21C0F800B00D +:10B43C0030788BF80C1008211EF056FB18B13078C0 +:10B44C00082112F0FFFDE069A16A4A46CBF808001A +:10B45C00DBF804001DF096FE05E0A16A28464A467A +:10B46C001DF090FE4D4494F82C005FFA8AF2414690 +:10B47C003B46287094F82D00687094F82E00A87044 +:10B48C00442017F0F5F83846BDE8F84F1EF0C4BB61 +:10B49C0000254FF081084FF0000B6EE75C26002072 +:10B4AC0096880020F8B50446007D50B15A4994F9AD +:10B4BC001800C968D1F880108847013004BFE82013 +:10B4CC00F8BD554EE27BB568D5F80011E86B0978EC +:10B4DC000AB1807A00E0C07A81429CBFF120F8BDAD +:10B4EC00636A94F8392094F83810A08DD5F88C52F2 +:10B4FC00278C0097A84700285ED00546002028809E +:10B50C006868A16AA28D1EF0F5FB04F1300005F10C +:10B51C0084010CC80CC1028880788870B0680A80DD +:10B52C002146D0F8442505F1900090476089B36816 +:10B53C00A5F89A00207B85F89C00607B85F89D001F +:10B54C00A27DD4F80E00D4F81210D3F848359847E1 +:10B55C00A5F89E00E07D85F8A000207E85F8A1006E +:10B56C0094F83C0085F86C00228CA5F8A8202AB32E +:10B57C00E169D5F8A4001EF0BDFB1DF0EBFDB5F89C +:10B58C00A800E8B1D5F8A400D0B16868411E696084 +:10B59C00F82100F8011C6868411E6960002100F860 +:10B5AC00011CB5F8A8006968091A6960A9652989A0 +:10B5BC0008440230288103E01A20F8BD1DF0CAFDB2 +:10B5CC00B5F89E10C8051DD594F83B20E8202AB18B +:10B5DC0011F0040208BF11F0010100D0F8BDB168F0 +:10B5EC00486ED1F8FC14884794F83B004FF47A71FC +:10B5FC00B268484309490978B0FBF1F1506ED2F8B2 +:10B60C00F4249047B0682946D0F89400007813F0E1 +:10B61C0045FD0020F8BD00BF0C010020B0880020C3 +:10B62C00F8B5554F554E564D38883168EC8808445E +:10B63C00224600F10801A868806D1EF05BFBA9682A +:10B64C003888504B8A6D2044388022448A65326891 +:10B65C0081B20832565C811C398089B2515C1970F8 +:10B66C00C11C0730398089B2515838806846009126 +:10B67C0004211AF04DFF00901CF016FEA968C86357 +:10B68C0000981CF0AFFAA968A1F840003E48007879 +:10B69C0018B11EF095FAA968C863EA2019F002FAED +:10B6AC003A48426812B1A8680121904738480221F3 +:10B6BC00384C0170E0684069007830B1A87B800993 +:10B6CC0017F0A6FC08B10120A870A878A96800287A +:10B6DC000A7C70B218BF42F004020A7400210027E1 +:10B6EC001EF0E0FA0146A86880F8461000F17401DB +:10B6FC00B0F85C2080F8486080F84770816501895B +:10B70C00511A426811444160417B890709D5A168EF +:10B71C00D1F808138847A868416E11B1B0F86810C9 +:10B72C00F1B190F8601049B1A168D1F80C138847B9 +:10B73C00A868C16C11B1B0F8501089B1A168D1F8EA +:10B74C00B820137823B1926C12B19047A868A16805 +:10B75C00D1F8581288470020A8601CF007FEF8BDED +:10B76C00A068D0F8541205F1080088470020A860A2 +:10B77C0010F044FDF8BD00BFA6860020C087002055 +:10B78C0024250020B18800208427002024B8020042 +:10B79C00AC8800200C0100202DE9F84FD0E90054B2 +:10B7AC00994616468A46834613B10020C9F8000014 +:10B7BC0076B11DF0BDFE0746E87968B195F8E80052 +:10B7CC0088B138461EF060F96FF00800BDE8F88FBC +:10B7DC006FF00900BDE8F88F38461EF055F96FF090 +:10B7EC000E00BDE8F88F0020012105F58078C5E931 +:10B7FC003BA6C5F8F460C5F8FC0085F8E810E863D2 +:10B80C006873E872404600211EF0B4F820461DF023 +:10B81C007FFF38461EF038F91DF0D9F808B9687961 +:10B82C00C0B395F84400C00606D52C6C24B1AB6CA3 +:10B83C00584610210022A0471DF07AFE04465846B7 +:10B84C0009F0E4F920461EF01FF9687960B90A99ED +:10B85C0040461EF08FF808B10120687358460EF070 +:10B86C0079FB002085F8E800B9F1000F1CBFD5F872 +:10B87C00FC00C9F80000E87A28B10020E8726FF0EB +:10B88C000D00BDE8F88F687B002818BF6FF00C0026 +:10B89C00BDE8F88FDBE9005495F84400C00614D5D8 +:10B8AC002F6CAB6C584610210022B8470DE0D5F830 +:10B8BC00FC0031460AEB0002204618F0D5FFD5F803 +:10B8CC00FC10361A0144C5F8FC10002EEFD12046AE +:10B8DC001DF0D8FC0028FAD020461DF00DFF95F87D +:10B8EC004400800605D52C6CAB6C584620210022F8 +:10B8FC00A0470020B9F1000F85F8E800C8D0D5F8B2 +:10B90C00FC00C9F800000020BDE8F88F7CB5584D4C +:10B91C00584E4CF6C0722B78347883F0010384F0C7 +:10B92C000204234308BF1040534C00295249898C10 +:10B93C000CBF21EA00000843A08401B2B1F1FF3F23 +:10B94C0008DC01200DF103018DF80300522016F0E4 +:10B95C008FFBA08C810400F1828081B20A042AD46E +:10B96C0001047CD04FF0FF3101913178022976D15E +:10B97C002978002973D121682346013101A908BF18 +:10B98C000B46C207224608BF0B461D6852F8046FCF +:10B99C00B54298BF1A46050758BF1A46C30606D5C6 +:10B9AC002546136855F8086FB34288BF2A468306AC +:10B9BC001ED4134623E0480451D504F11000226A2A +:10B9CC00016812B11268914211D02C4D20620129EC +:10B9DC00287803D1012112F035FB7CBD012113F035 +:10B9EC0001F8216A28780A6801211EF07AF87CBDDA +:10B9FC002346156853F80C6FB54298BF13464204A2 +:10BA0C0001D41A4606E022461D6852F8106FB54262 +:10BA1C0098BF1A46C30401D4134606E023461568A2 +:10BA2C0053F8146FB54298BF1346820701D41A46D7 +:10BA3C0006E022461D6852F8186FB54298BF1A46A8 +:10BA4C00400701D4104606E02046136850F81C5FEE +:10BA5C00AB4298BF1046884218BF0028AFD10020D7 +:10BA6C00012120620548007812F0BCFF7CBD00BFAC +:10BA7C00D527002018260020F0820020988800206E +:10BA8C002DE9FF4715460F46814639B138461DF062 +:10BA9C00F2FF18B10446A5F1010A4EE04A48A0F1A4 +:10BAAC0024014A480678701C01386DD001F1240439 +:10BABC0091F82810FF292146F6D1002C64D0E81EFD +:10BACC00C0B201280DD84248B0F80080B8F1000F80 +:10BADC0007D00320042117F0BBFFA6EB080181421D +:10BAEC006FDDA5F1010A5FFA8AF001280DD83948FB +:10BAFC00B0F80080B8F1000F07D00120022117F038 +:10BB0C00A7FFA6EB080181425BDD0120E846394620 +:10BB1C00ADF802908DF8000008F104001DF0F9FB5F +:10BB2C00404605F015FF0020A071BDF80C006080A8 +:10BB3C002948818C48461AF048F84AF60121002021 +:10BB4C002571A4F80090A4F8091080212082E060EF +:10BB5C00E072E07184F8211020490978013149081C +:10BB6C0021725FFA8AF1042938BF01208000012973 +:10BB7C0060710BD81A48007858B11A4951F8200056 +:10BB8C00C0EB0010800006E0002409E06FF001001B +:10BB9C0004E014480068012184F82010A061E061E1 +:10BBAC0000200421002517F053FF0849097888422A +:10BBBC0024BF0D48057008F04FFE204604B0BDE8C8 +:10BBCC00F0870024F9E700BFB0540020E6BC020067 +:10BBDC00C0BC0200C2BC0200407B0020D1BC0200F1 +:10BBEC00C827002060B70200872700202DE9FC4FF2 +:10BBFC00D0F8C080D0F8D0C0D0F8E820D8F8003009 +:10BC0C00C346E6469C4511D3D8F814B0BBF1000FDF +:10BC1C0000F0898090F8FC3005244FF0000E002BCA +:10BC2C0008BF0124DBF800308BF81040A3EB0E05A5 +:10BC3C00A2F1080AB5F5806F28BF4FF48065D0F8E3 +:10BC4C00D82032B101F1200301F12402C0F8DC50FC +:10BC5C0005E0C0F8D85001F1180301F11C020026D0 +:10BC6C00BAF1000FC8BF0126DBF8044012681F6848 +:10BC7C00CDF800E07CB1354B53F82630BB6005FAAB +:10BC8C0006F30126BAF1000FC8BF02260EFB0633DD +:10BC9C002344013B05E02E4B53F82630BB6000F1EA +:10BCAC00F6033B6043F6F0740191D1F8009004EB7D +:10BCBC000516264009F1080EC7F804E0BC683443A9 +:10BCCC00BC600024BAF1000FC8BF0124DBF8087077 +:10BCDC009FB16146DFF87CC05CF824308C469360E1 +:10BCEC0005FA04F30124BAF1000FC8BF022400992D +:10BCFC0001FB043139444C1E05E0154951F8241060 +:10BD0C0000F1F40491605460C2F800E09168314392 +:10BD1C009160C34504BF05EB0C01C0F8D01090F83E +:10BD2C00FE10019A09B1BDE8FC8FD9F8241041F03E +:10BD3C000301C9F82410D0F8CC00D2E904124068F1 +:10BD4C00114300688162BDE8FC8F00BF18BA020085 +:10BD5C0020BA020028BA0200F0B58BB0ADF80A0088 +:10BD6C00002001F108070C468DF8080038461CF03D +:10BD7C0037F808B306AE0DF10701384632460DF020 +:10BD8C0013FC05464FF6FF7085421FD09DF8070047 +:10BD9C0000B39DF82800002844D0FF280AD00228C0 +:10BDAC0048D0FD2806D001284DD13F4800780138F5 +:10BDBC00012844D93E4844E002A80DF0C5F80128FA +:10BDCC0002D102A818F0CAFBA1205AE03848C4F8E6 +:10BDDC00120055E006F10800394608221DF0D2F990 +:10BDEC0040F2FF10ADF828001DF0B0FD00F00F0080 +:10BDFC0000272946142233468DF82A000420CDE969 +:10BE0C0006771AF0D7FA2B4905EB450041F820705C +:10BE1C0001EB80002649C0E90177C4F8121001211A +:10BE2C00417210E0052060829DF82B0000F07F002D +:10BE3C00A08208E01C480078411E022923D24FF052 +:10BE4C008170C4F812001B4A05EB4501002052F822 +:10BE5C0021305D1C42F82150A3610A232074B5FBEC +:10BE6C00F3F303EB8303A5EB430353B902EB81001C +:10BE7C000121017210484FF48061007812F0E2F851 +:10BE8C0000200BB0F0BD30B90848C4F812009DF882 +:10BE9C002A0084F8280004F11E0006F1080108228B +:10BEAC001DF070F9CFE700BF18260020000001013B +:10BEBC00000003018043002099880020F8B50D464E +:10BECC00417F0446827F1020002908BF0820607043 +:10BEDC000AB108306070217F09B101306070A1791E +:10BEEC0021B1217A00EB410002306070267E474977 +:10BEFC00002E18BF0E26097802290BD14249097869 +:10BF0C00012907D12178012904D04149097809B1C7 +:10BF1C00012100E0002184F83410217D31440844D3 +:10BF2C002870217E31B13B48007B1DF07BF92978CC +:10BF3C0008442870C0B274283DD81DF06FFED0B3F1 +:10BF4C00054634482178677E237F94F818E094F8EE +:10BF5C0006C0627F807C002B41EA800007F0030161 +:10BF6C00A77F40EA811094F83410287018BF012381 +:10BF7C0040EA032040EA4E2040EAC22040EA073063 +:10BF8C0040EA8C2040EA4130000A6870A078A87022 +:10BF9C00E078E8702079287160796871A07EA871CA +:10BFAC00E07EE871607F40B1216A05F108001DF068 +:10BFBC00E0FD102702E0002523E00827A07F20B138 +:10BFCC00616AE8191DF0D5FD0837A07970B1207AA7 +:10BFDC00E855E8190237617A4170E819227AE1686C +:10BFEC0052001DF0CFF8207A07EB4007207F08B1F4 +:10BFFC00F9B268546078227D2169284430441DF0E0 +:10C00C00C1F82846F8BD00BFBA270020182600202A +:10C01C00CC270020407B00202DE9F04F85B007464F +:10C02C008A465818D7F80880D8F80410884202D9E4 +:10C03C006FF003057BE04E4D7C68DDF838904FF0D7 +:10C04C00FF319B46164628681DF094FC6068B8F8D2 +:10C05C002010C5E901015FEAC97014D15FEA89704B +:10C06C0023D5D8F80C0000287AD0D8F81010002965 +:10C07C0076D001228DE80700384651465B463246A1 +:10C08C0013F098F90EE0A068C14300EA0B0211EA24 +:10C09C000B0F1CBFD8F808100A4400EA0A013846F6 +:10C0AC0006F074FF08B105463DE0D8F800005C4688 +:10C0BC003546039600EB0A09ECB3384612F0D4FD72 +:10C0CC0078BB384619F004FB58BB02208DF813904E +:10C0DC008DF810004FEA19208DF812004FEA194024 +:10C0EC008DF811002248018938461CF0FEFE5FFADB +:10C0FC0089F0C0F58076B44238BF264604A80421E6 +:10C10C0013F05CFD68B92846314613F057FD40B971 +:10C11C001748A41BB144018938461CF0EFFE354486 +:10C12C00CAE74FF0FF35124800681DF089FD28461C +:10C13C0005B0BDE8F08F0E98400701D40025F2E75A +:10C14C00D8F80C0060B1D8F8101049B100228DE875 +:10C15C000700384651465B46039A13F02BF9A2E7C9 +:10C16C00034800681DF06CFD6FF00705DFE700BFAA +:10C17C000C2400202DE9F0418AB0514F0546387847 +:10C18C00022804D14D480078002800F09480DFF894 +:10C19C00348198F82600082802D0042840F08B80BF +:10C1AC0007AC284621461BF0D7FF387802280BD164 +:10C1BC001CF020FDA11C1BF072FA28B1BDF81C600C +:10C1CC001DF0ECF9864276D01DF03DFC0234BDF832 +:10C1DC001C00214608F08EFE01286CD06E463046BD +:10C1EC001DF0F9FB304621461BF059FA68B1BDF839 +:10C1FC001C601DF0C1F9864207D0BDF81C004146F9 +:10C20C0021F81A0F4B2015F033FF3878012819D874 +:10C21C00AD8A1DF0C3F9854214D020461DF02BFCCD +:10C22C0030B100790138012802D8204612F02EFED8 +:10C23C002648016831B124480078012802D1BDF8A4 +:10C24C001C008847BDF81C00002100261AF0DEFDFA +:10C25C00B8F82410BDF81C0019F0B7FCBDF81C0090 +:10C26C008DF80C60ADF80E0003AD28460CF06CFE9A +:10C27C0070B1CDE900662E1D684631461BF00FFAF1 +:10C28C0030B1304621461DF044F803A805F060FBA0 +:10C29C00281D21461DF03DF828460FF0DFF950B15E +:10C2AC00BDF81C00BDF80E10814204D0ADF80E0094 +:10C2BC0003A805F04DFB0AB0BDE8F081D52700209E +:10C2CC0018260020407B0020BA270020982300204D +:10C2DC002DE9F047012816D1DFF830A1DAF8340146 +:10C2EC00012813D10220CAF8340119F077FD01207E +:10C2FC00012419F095FA60B1CAF834411BF062FBC5 +:10C30C004FF0FF347FE06FF001047CE06FF0040429 +:10C31C0079E09AF85A419AF859119AF85801002C78 +:10C32C0018BF0124002918BF0234002818BF043498 +:10C33C0001201DF0A5F9013818BF01209AF8381119 +:10C34C00B1FA81F1490910EA010902D1002007F084 +:10C35C00DFF9DAF808002E4D10F0010807D12D4F47 +:10C36C00286A8168384688470428F9D00646404632 +:10C37C001DF0F1FAB8F1000F08D1012E04D1286A92 +:10C38C0001214268234890471CF014FF286841693A +:10C39C00204688479AF8540118B14FF480601DF07C +:10C3AC0075F99AF8530118B14FF481601DF06EF9CC +:10C3BC0019480121016003200021CAF834011748F3 +:10C3CC000160204615F09AFC0128FAD1144E306811 +:10C3DC00042019F025FA044612480125B9F1000F82 +:10C3EC000560306802D1012007F092F91DF0E8F8E1 +:10C3FC00082019F015FA0443CAF8345118BF4FF04D +:10C40C00FF341BF0DFFA2046BDE8F087D81B002074 +:10C41C00B801001000400340282008600C200840A0 +:10C42C002C2009400C4009407CB54B4EB068016C87 +:10C43C00D0F8D420096892F8835019B9D0F84C057B +:10C44C008047B068D0F8B800007800B315F0BAFE99 +:10C45C004349424809680068096C884705461DF045 +:10C46C0067F804463F48017811B93F49097821B370 +:10C47C003E4902220A700078832808BF13F076F830 +:10C48C001DF01AFB1DF030FA0420884757E01DF010 +:10C49C004FF804463348017811B933490978C9B3C8 +:10C4AC0002223249012D0A7004D10078832808BF7A +:10C4BC0013F05CF81DF000FB41E01DF015FA0020B4 +:10C4CC008847B0680DF10701D0F82824F420904774 +:10C4DC009DF90700854223DB254D287800BB1DF014 +:10C4EC00EBFA25480078042803D0B068D0F84C0546 +:10C4FC0080471E48042101702878013028701DF0F7 +:10C50C00F3F909B1032088471C48032101801DF071 +:10C51C00D3FB14E01548832101701DF0CDFA0CE01B +:10C52C00124883210170002017F0F6FD1DF0C4FAAB +:10C53C001048F16880780969087017F0A1F9F06863 +:10C54C00C068007800B17CBDB0680021D0F85824D8 +:10C55C00002090477CBD00BF0C010020D826002095 +:10C56C0030880020AC880020AF880020B4880020E0 +:10C57C00A527002021260020B7880020AE870020A8 +:10C58C002DE9F84F494C1021207816F013FE28B9EC +:10C59C00207810214FF47A721DF0A3FA44480178E8 +:10C5AC000139017009065AD043484FF000084FF684 +:10C5BC00FE790026041D41480578AE421DD2207834 +:10C5CC00C0B1FF2816D001382070000612D1607857 +:10C5DC00032807D134F8041C34F8020C022211F0A1 +:10C5EC0063F8607801281EBFA4F8018024F8029C2F +:10C5FC0024F8049C08340136DFE73148DFF8C4A086 +:10C60C00314C4FF00008002790F800B05F4519D06E +:10C61C0007EB87000AEB4005287A013828720006E0 +:10C62C000ED12046294619F02BF9064610B130469A +:10C63C0019F068FE002EF4D185F80080A5F8029060 +:10C64C000137E3E721482249007830B10A780AB172 +:10C65C00013A0A7008310138F7E7BDE8F88F15493F +:10C66C00002209780170002005211AF0BBFA04465B +:10C67C000626002C98D020460521002225461AF0CB +:10C68C00B1FA044628890028F3D001382881000427 +:10C69C00EFD16889400702D5287B18F0C9FE2868BD +:10C6AC00F0216E73407B15F0D7F8E2E798880020F4 +:10C6BC0017870020DFBC0200E04C0020DABC02002F +:10C6CC00D9BC0200D07E0020A31A02009ABC020042 +:10C6DC00E02700202DE9F04F85B006464D48DFF8E5 +:10C6EC003C9114460D464FF6FE774FF6FE780078D7 +:10C6FC00019049480078049001200290002003909A +:10C70C00474800F1110B47480430009099F800C0DD +:10C71C004FF0000E0020C00774D1049B5946C1464F +:10C72C0003B331F8118CB84518BFB04502D11C3198 +:10C73C00013BF5E7A84518BFA045F8D00A78501E74 +:10C74C000628F4D8072A01D1C146F0E702980EF169 +:10C75C00010EC007EBD103985FFA8EF2C0B2824291 +:10C76C00E5D351E0BCF1010F2AD8DDE9001ABAF18A +:10C77C00000F25D031F8048CB84518BFB04503D153 +:10C78C002431AAF1010AF2E7A84518BFA045F7D059 +:10C79C004B79581E0628F3D8087801380228EFD3B5 +:10C7AC00072B01D1C146EBE702980EF1010EC00731 +:10C7BC00E6D103985FFA8EF2C0B28242E0D323E056 +:10C7CC00C8465FEA0E6002D00398000603D0012031 +:10C7DC00B845A0D018E000205FFA8EFADFF83C9044 +:10C7EC0002900120BAF1010F03903FF48FAF1DF0BE +:10C7FC00ADF8C0B2B0FBFAF101FB1A0003900020B7 +:10C80C00029083E74FF6FE781FFA88F005B0BDE87A +:10C81C00F08F00BFE6BC0200D5BC02001826002039 +:10C82C00DC5B0020B05400202DE9F04395B00446A9 +:10C83C0000208DF81F00208817F096F9002840F092 +:10C84C0081804B48007810B14FF0B30908E0A07814 +:10C85C00042803D11CF0DEFB002876D04FF0B6097B +:10C86C0000261E201AF0FAFB0546BEB303209DF8E5 +:10C87C0052108DF81E0010A808AF08303A4610F080 +:10C88C00A9FF0CAE0DF11E0008213A46334612F0FA +:10C89C005DFCA068314610221BF0C4FBE0B11FFA0E +:10C8AC0088F702AE0420002214233946009619F0B2 +:10C8BC006BFD9DF91B00B0F1FF3F03DC06F113008B +:10C8CC0017F08EF80220394614228DF8180002ABAE +:10C8DC00042019F06FFD01E04FF0AD09B9F1000F24 +:10C8EC0017D09DF81F00012813D19DF9531000207B +:10C8FC00CDE91000002903D401208DF85100FF2050 +:10C90C008DF850001FFA88F110AB0420142219F096 +:10C91C0051FDBDB1092085F81D9008222870208892 +:10C92C006880A0782871681D61681CF02BFCA168D8 +:10C93C0005F10D0010221CF025FC0E48294600784C +:10C94C0012F0ACFB15B0BDE8F08360680DF11F016F +:10C95C0010AA0CF029FE80469DF81F0018B14FF06C +:10C96C00000901267DE74FF0AD09002679E700BFED +:10C97C0018260020998800202DE9F843DFF8308133 +:10C98C000C46914607462246B8F8241013F046FC94 +:10C99C00002879D0068905464FF6FE70864204BF02 +:10C9AC00C320BDE8F8831CF0F9FD864204BFC22009 +:10C9BC00BDE8F8832988B8F8240088421CBFA8F881 +:10C9CC002410084615F020FCE87A3946013088F826 +:10C9DC00380008F139001DF0CCF802208DF8010068 +:10C9EC00684619F047FF002851D007460069062118 +:10C9FC000126017098F80E104170BE771CF0FAF801 +:10CA0C0078624020BE7687F81890F8822889788062 +:10CA1C00384611F05DFF002845D1092008F11A01B4 +:10CA2C0088F826002889A8F81A0098F81800A0425F +:10CA3C0018BF88F818401F4C4B20A04708F1240160 +:10CA4C005020A04708F11801E120A04708F1160179 +:10CA5C005320A04708200121FEF758FF4FF4005047 +:10CA6C000021FEF753FF144C4FF48061207811F035 +:10CA7C00B9FF1348007802280BD110480078012820 +:10CA8C0007D14FF4DC6208E0CA20BDE8F88310201F +:10CA9C0009E0082010F098FF820020784FF48061A4 +:10CAAC001DF022F80020074900220A70BDE8F88327 +:10CABC00407B00207D20020098880020D527002094 +:10CACC00182600209E8800202DE9F0474FF6FC76B2 +:10CADC00B04201D100240FE0884600211D46924649 +:10CAEC00002414F055FCDFF814910746680606D4B0 +:10CAFC00B9F81600874202D12046BDE8F0873846C7 +:10CB0C0029460DF0A7F930B9B01C002180B20DF008 +:10CB1C00A1F9002860D0B11C078089B2884505F0C6 +:10CB2C00010118BFA0F8028045EA8101BAF1010F9A +:10CB3C00817142D101214171334915F0180F99F8D7 +:10CB4C001420097818BF0A4602714046B9F824101F +:10CB5C0016F06AFD0028BDD12A482C49DFF8B0A098 +:10CB6C00274B0022007891F800C06245B2D0C2EB8E +:10CB7C00C20600270AEB8604B8420BD003EBC705AC +:10CB8C0021886D888D4201D00137F5E70132F9B269 +:10CB9C008842EAD120461C211CF090F94AF601206B +:10CBAC002AF82680A4F811001A48007801304008B1 +:10CBBC002074B9F8240060818CE7417901293FF495 +:10CBCC0089AF114915F0180F08BF09F11301097845 +:10CBDC0080F805A001717DE715F0180F0CD00949FC +:10CBEC0007480978063039B110F8082B013912F0D2 +:10CBFC00180FF8D10E388EE702247DE7407B002019 +:10CC0C00E04C0020DABC0200DCBC0200D5BC020007 +:10CC1C00DC5B0020D1BC0200F0B58DB00546007C79 +:10CC2C000F2873D36E68686908AC0021224613F094 +:10CC3C0043F89DF82000002868D1287C0B2865D388 +:10CC4C00307A022862D1B189C8B2FF285ED19DF832 +:10CC5C00220010F0FD0F59D1404F97F8263043F0C9 +:10CC6C000402062A04D13E4A1268AAB1C90B1FE07D +:10CC7C003B4A126812B19579012DF4D0082B01D0E2 +:10CC8C00042B43D17589002A42D0917902293FD1D6 +:10CC9C00284619F021FB39E0727C71893088002319 +:10CCAC0000930023FBF7B2FDB089C10B9DF8220065 +:10CCBC0032888DF80D10B17B9DF824308DF8100062 +:10CCCC009DF825509DF83200ADF8082072898DF83A +:10CCDC000C109DF821108DF80E308DF813508DF836 +:10CCEC001400ADF80A20727C9DF826608DF81110A6 +:10CCFC00E11D8DF812208DF80F6002AD082205F1B0 +:10CD0C000D001CF03FFA28461CF080FF0DB0F0BD62 +:10CD1C00B98CA942FAD1012806D0E11D07F13900DE +:10CD2C001AF0BDFC0028F1D10E484FF400710078C8 +:10CD3C0016F040FA0028E9D140F20120ADF80D00C0 +:10CD4C00B86A029097F82E008DF80C0002A812F029 +:10CD5C0021F900289CD01AF085FDD7E7407B0020F4 +:10CD6C00CC26002098880020F0B59DB04668077A44 +:10CD7C0010AD0446342128461CF0A0F88DF8407004 +:10CD8C00294636F8020B16F09DF902201A9604F18A +:10CD9C0028018DF84100608EADF84E009DF84000E2 +:10CDAC0002388DF85C0006A81CF0F9F89DF84200DA +:10CDBC0003287AD19DF843501CF0EAFB854274D1CC +:10CDCC009DF84400002870D19DF8450000286CD1D6 +:10CDDC009DF84600002868D19DF85D00002864D1BC +:10CDEC009DF84700002860D19DF8480000285CD1D0 +:10CDFC0009A81C211CF062F8BDF84E001A9A9DF887 +:10CE0C005C30ADF82E00154615F8010B00F003014F +:10CE1C008DF82400032916D100F00C060C2E05D039 +:10CE2C00082E08D101268DF8306004E0B2F80150CC +:10CE3C00ADF82850D51C35F8046BADF82A6035F8E0 +:10CE4C00026CADF82C60521B0D9513445242032911 +:10CE5C008DF838308DF8312027D100F00C010429E1 +:10CE6C0023D010F0200108BF10F080001DD1FE204F +:10CE7C009DF85310B4F8422000238DF827000C487D +:10CE8C0040788DF8260094F846008DF81400B4F81C +:10CE9C004700ADF81500E06BCDE90013CDE90203B6 +:10CEAC0009A806A905AB08F08DFE1DB0F0BD00BFAA +:10CEBC00C02600202DE9F047DFF83491D9F840A0C6 +:10CECC00BAF1000F00F089800AF10C020820FF2152 +:10CEDC0051FA80F0C3B21B1A18BF012312686AB151 +:10CEEC0063B11388A3F60303012B01D90432EFE7D6 +:10CEFC00DAF8100092E8FA003830FAC0DAF80820B4 +:10CF0C000025DAE90A10CAE90A55B2B110F0E24478 +:10CF1C000CD021F00F0220F0E2434FF0000852EA4F +:10CF2C00030005D01CF057FAB04701E088460446D0 +:10CF3C001CF051FA42462346B0471CF0F9FA04465D +:10CF4C00B9F8560001306FF31F30A9F856004FF6B0 +:10CF5C00FD70AAF8300009F140008AF833501AF03D +:10CF6C0027FB20461CF090FDB9F85600B9F8541078 +:10CF7C00884232D11F48204940680D6830B190F882 +:10CF8C00FC200720002A08BF052000E005204C6883 +:10CF9C000FF06EFC55B195F8FC00002100284FF005 +:10CFAC00000008BF286885F8FC1000E0002044B1A0 +:10CFBC0094F8FC200021002502B9256884F8FC10A7 +:10CFCC0000E00025A84288BF0546681C05D035B98D +:10CFDC000020BDE8F0471BF041B8BDE8F0871CF01D +:10CFEC00EDFDB5FBF0F10548BDE8F0471BF094BB37 +:10CFFC0030210020D01E002070200020207F002037 +:10D00C002DE9F04186B01D4614460E46022818D074 +:10D01C00012818D0002876D1012E6BD0022E72D1A7 +:10D02C0008201AF05FFD3E480021437B3D48026812 +:10D03C0040480088CDE9021104913F49CDE90045F3 +:10D04C0055E0002000E00120032E00D0F6B91BF0C3 +:10D05C00E1FF032E18BF002835D102201AF042FD43 +:10D06C002F48304C417B206810F0CCFE2E4989783B +:10D07C0001F00801014345D12C48017801310170C0 +:10D08C00C8B2042849D12A48206046E0711E80F0BD +:10D09C00010018BF0121084335D10A201AF022FDE6 +:10D0AC0026484FF48061007811F09CFC0DF11601BC +:10D0BC00502018F0B1FF2249BDF8160088840021D9 +:10D0CC001CF094FD29E0164890F80D80154807686F +:10D0DC00184806881CF03AFC0121002204903046C6 +:10D0EC004346CDE90045CDE9022113493A4605F006 +:10D0FC00CFFB07E008201AF0F5FC20462146002261 +:10D10C001BF0E8FF48B10F4801214FF47A72007808 +:10D11C0006B0BDE8F0411CF0E7BC06B0BDE8F081FC +:10D12C00CC22002070880020268700208927002030 +:10D13C0000F8FF0780270020B426002098880020E4 +:10D14C00407B0020998800202DE9F04F8BB00C46D5 +:10D15C000690C9881F460792E07816F0CFF9002890 +:10D16C007ED0217D0546C0B219F0AFFE002879D0E3 +:10D17C000646E188E0780597DDE9177900224FF043 +:10D18C00000815F095FC8346E0787071E188A07D6D +:10D19C0086F80880227DF1807081F06821691BF08F +:10D1AC00F1FF86F8149077824FF000090027BBF14D +:10D1BC00000F4AD05FFA89F0854246D906EBC00AC7 +:10D1CC009BF80110504600F8168F012904D1012755 +:10D1DC000770BBF8020005E0BBF802008AF81D00DE +:10D1EC001BF076F9AAF8180022789BF80410520666 +:10D1FC008AF81A1005D59AF81C2042F002028AF817 +:10D20C001C20C7B9204AD28A904214D11E48A17062 +:10D21C00DDE90613CDF80080828C159801901698E4 +:10D22C00CDE90208204608F0CDFC9AF81C0040F02D +:10D23C0005008AF81C0009F10109E188E0785FFA21 +:10D24C0089F215F035FC8346B1E7304619F0C8F881 +:10D25C000599DDE9142320460096FAF719F810E039 +:10D26C00B92000E010208DF82800E078A17D8DF821 +:10D27C002300E0888DF82410ADF8260008A81BF0D8 +:10D28C005FFC0BB0BDE8F08F407B00202DE9F84F20 +:10D29C00816A91F90120002A2AD4824602F01F00EB +:10D2AC0000EB40049AF81C300234A34220D18B1CB2 +:10D2BC00D2B24FF6FE784FF6FE7C08B1B1F802C040 +:10D2CC00DFF804914FF0000B4FF6FE770021B9F810 +:10D2DC001650814211D29C7814F0880F08D133F883 +:10D2EC00037BBEB2AE4208BF04F0070B0131F0E77E +:10D2FC00D320BDE8F84F09F006BD5FEA0B6006D1FC +:10D30C001FFA8CF0B9B215F0B3FC00284FD0BAF864 +:10D31C000C001CF05CFB98B10021027AC1712B4906 +:10D32C0009788A4208D30131490801725FFA8BF1FE +:10D33C00072938BF0BF1010B80F809B0BDE8F88F55 +:10D34C0008F10101BAF80C0089B217F0C9FC20B140 +:10D35C0005461E48297C007815E016F047F930B3D5 +:10D36C001C2105461BF0AAFD4AF60120A5F8110068 +:10D37C00BAF80C002880B9F82400688113480078AA +:10D38C00411C49082974814208D301304008287493 +:10D39C005FFA8BF0072838BF0BF1010B002085F8E2 +:10D3AC0011B02873023528461AF01AFD08B1BDE8F1 +:10D3BC00F88F9AF808000028F9D0DAF818102846E7 +:10D3CC00BDE8F84F1CF0D5BB407B0020D1BC02005F +:10D3DC007CB50568002D6DD004464748026842B103 +:10D3EC00217928469047012803D1688920F0010053 +:10D3FC006881687B02282DD1688980072ED5207919 +:10D40C00CD282BD0F02829D0688A00060CD5A87E10 +:10D41C0050B1A8732868008816F0A6FB40B94FF4E9 +:10D42C00987009F070FC03E0344800780130A87360 +:10D43C002079002856D004202021687330480088B9 +:10D44C002881A87B0138A876A8732E48007810F0A4 +:10D45C00F9FD687B40F0040006282BD12B49288B62 +:10D46C00C98A884214D02849097889B12968098861 +:10D47C00ADF8000001208DF80500287BADF80210F6 +:10D48C008DF8040020798DF8060068461BF0F2FC3C +:10D49C006889C0070ED0217928461BF040F86889AE +:10D4AC0020F0010068812868008816F05DFB217966 +:10D4BC0008B121B17CBD39B140F2311001E040F22C +:10D4CC002D1009F020FC7CBD40F22F1009F01BFC44 +:10D4DC00002560798542EDD24FF49B7009F013FC66 +:10D4EC000135F6E7002660798642A4D24FF49B7092 +:10D4FC0009F009FC0136F6E738240020B627002095 +:10D50C007C27002098880020E9250020407B002003 +:10D51C00BFB54A4D044695F82600092800F28C80C8 +:10D52C00012101FA00F040F20A21084200F0848047 +:10D53C006178F1B141F2030011F0E1F84048007854 +:10D54C0002280ED13F4801780B2904BF0A21017033 +:10D55C003D48002101703D484FF48041007811F0A6 +:10D56C0041FA6178A88C1CF041FB002085F826005C +:10D57C0060E00220002111F0C2F834F8020FE882BA +:10D58C005320214614F074FD95F82600092802D08A +:10D59C00A88C14F039FE01200DF10F018DF80F004D +:10D5AC00422014F065FD04200DF1070485F82600D7 +:10D5BC004A20214618F030FD05F11C0021461CF0D4 +:10D5CC00D8FA204801780B2902D10621017003E01A +:10D5DC00A88C00211CF00AFB194C207802280AD2D6 +:10D5EC00688B4FF6FE7188420ED00DF107010022B8 +:10D5FC00FEF746FA08E007D1E98A032011F07FF81C +:10D60C00698B042011F07BF8A87B0DF10F01C0F39E +:10D61C00C0008DF80F00522014F02AFD207802284B +:10D62C0008D1A87B00074CBF4FF40040012001211A +:10D63C00FEF76CF91AF07EFEBFBD00BF407B0020E8 +:10D64C0018260020C4260020CC2700209888002013 +:10D65C002DE9F0418846080430D45FEAC86000F137 +:10D66C0081805FEA887000F182805FEA087000F1C7 +:10D67C00818018F4706F00F082805FEA085004D546 +:10D68C0000201BF0C5F988F400685FEA485004D507 +:10D69C0001201BF0BDF988F480685FEA885004D53E +:10D6AC0002201BF0B5F988F400785FEAC85068D501 +:10D6BC0003201BF0ADF988F4807862E0324F3878A3 +:10D6CC0011F0BEF900284AD0054646680078411E84 +:10D6DC0005290DD91A282CD024282ED0D12833D0A6 +:10D6EC00D32835D0FD2836D128461AF088FB32E0F5 +:10D6FC00DFE801F0030B310F311B66B3304611F03C +:10D70C001DFC30461CF088FA25E0284614F08CFEEF +:10D71C0021E0F478701CE11CC9B21BF099F8611D72 +:10D72C0056FA81F101F8010C15E028461AF064FF55 +:10D73C0011E02846FDF7F6FD0DE0F0780530C1B29A +:10D74C0030461BF007FF06E028461BF00FFF02E0F7 +:10D75C00284611F061F828461AF07EFBAFE788F4F2 +:10D76C0000480EE01AF02EF888F0100809E088F056 +:10D77C00020806E00DF002FB88F0080801E04FF00B +:10D78C0000084046BDE8F0819688002070B50C4634 +:10D79C0008041CD4E00729D144480078012805D896 +:10D7AC00A00745D4A00654D4600474D4E0062DD44C +:10D7BC00200744BF84F0080070BDE0053DD460072D +:10D7CC005FD400202146BDE8704009F0DDBB344E2B +:10D7DC00307811F035F930B1054607F043FC284696 +:10D7EC001AF03AFBF4E784F4004070BD01201AF003 +:10D7FC0079F92C480F220F2381782B48008800F0F0 +:10D80C000700FFF7FDFB84F0010070BD2548007890 +:10D81C0010F0D8FC28480078012806D127484FF48E +:10D82C000061642200781CF05FF984F0100070BD78 +:10D83C000AF046FA84F0020070BD214890F82600E8 +:10D84C00082801D0042801D11BF038FA84F4807028 +:10D85C0070BD1748007860B912480078062802D1CC +:10D86C0007201AF03FF913480078012808BF19F077 +:10D87C00F1FC0B481021007810F0E4FB84F0200040 +:10D88C0070BDFF20032116F019F81BF093FE0D4814 +:10D89C0001210160FEE714F041FB84F4804070BD6F +:10D8AC0099880020C42600202687002018260020F6 +:10D8BC00BB880020BA270020BD27002098880020B4 +:10D8CC00407B00207C052043F0B58DB0044603203E +:10D8DC000D468DF830000AAE30461CF04AF91BF0AC +:10D8EC0089F90146304619F0DAFE50B1287D40F036 +:10D8FC000201032905D1297A09B1FF2914D182200B +:10D90C0000E084208DF82700E289207C0DF12701AE +:10D91C000123CDE9001004F11100A11C42F40042D6 +:10D92C0013F07AFE0DB0F0BD032804D1A87DFF28BA +:10D93C00E5D00028E3D0304F4FF0FF300822CDE97E +:10D94C00060006A93E1D30461AF06CFB18BB2B488E +:10D95C006188C08A81421ED03878FF280AD0297A83 +:10D96C00814207D078884FF6FF71884202D06989CE +:10D97C00884210D10020314608228DF8080002AFF1 +:10D98C00381D1BF0FFFB38460DF068FE6088BDF8B3 +:10D99C000A1081422DD1E08905F10C0621281CD1F9 +:10D9AC008C206989AB7D32468DF82700287A17F0D8 +:10D9BC00E7FA0028A8D11BF09CFF287D0328A3D1EF +:10D9CC0002A9304617F00CFB00289DD130460021EF +:10D9DC000022002310F026FC96E76989287AAB7D9B +:10D9EC0032461AF093FA08B188208BE71BF081FFBE +:10D9FC008AE78D2086E700BF00260020407B0020B0 +:10DA0C002DE9F04F8BB04B4FB868D0F80001807AFD +:10DA1C00C0001CF003F9002809907ED00DF1040B16 +:10DA2C0000264FF6FF7A0BF103051BF081FD0DF17B +:10DA3C0014090090B868B2B2D0F800110B899A4260 +:10DA4C0063D201244FF00008C97A5FFA88F28A4247 +:10DA5C0021D2D0F88824D02059468DF80680ADF814 +:10DA6C000460904728B1B86808F10108D0F800119B +:10DA7C00EAE79DF8100000240128F4D19DF80F006E +:10DA8C000028F0D10020082806D0295C0130FF299D +:10DA9C00F9D00024E7E70CB10136CBE70024B868D5 +:10DAAC00E1B2D0F80021D2888A42F5D9D0F8882486 +:10DABC00ADF80610D1205946ADF80460904710BB64 +:10DACC00BDF8080050451ED0ADF81400B8684946A2 +:10DADC00D0F88824D420904708BB4FF0FF3049463B +:10DAEC00ADF81AA0ADF818A0CDE90700B868D0F8C9 +:10DAFC009424D4209047B8685946ADF808A0D0F8C3 +:10DB0C009424D12090470134C9E700981BF0BCFF46 +:10DB1C0009981CF081F8002008E01A2006E0009813 +:10DB2C001BF0B2FF09981CF077F819200BB0BDE878 +:10DB3C00F08F00BF0C010020F0B589B00546002025 +:10DB4C0001F108060C468DF80F0030461AF048F922 +:10DB5C0018B9284631460DF05DF804AD0DF10F01F2 +:10DB6C0030462A460BF020FD3B4E4FF6FF773178BE +:10DB7C004A1E9DF80F10012A10D879B900200DF11A +:10DB8C000F01CDE90000684604AA0BF00DFDB84268 +:10DB9C001ABF01218DF80F109DF80F10B1B1B842CA +:10DBAC0014D09DF8201099B3FF2926D0022918BF54 +:10DBBC00FD2912D12A4900EB400001EB8000A1693C +:10DBCC0050F8042F91420FD2A22042E0307810B9C5 +:10DBDC001BF0BCFDC0B1A1203BE0012938D130784D +:10DBEC000138012806D90FE0013101603078411E5F +:10DBFC0002291ED24FF0817007E0307801380128DD +:10DC0C009CBF012084F826001448C4F812001FE0C1 +:10DC1C00052060829DF8230000F07F00A08212484E +:10DC2C000078002818BF012084F8270084F826000B +:10DC3C000EE030B90B48C4F812009DF8220084F8AD +:10DC4C00280004F11E0005F1080108221BF09AFAC5 +:10DC5C00002009B0F0BD00BF182600200000030111 +:10DC6C008043002000000101942700202DE9F84F8B +:10DC7C001D4600928B4681461BF05AFC444A824654 +:10DC8C0000214FF4A060012705F1010C002392F84C +:10DC9C006040602935D007FA03FE1EEA040F0AD053 +:10DCAC00BCF1000F18BF9D4205D1561896F80A809A +:10DCBC00B8F1000F04D000F5807020310133E8E793 +:10DCCC0024EA0E040125737282F8604092F86240D7 +:10DCDC00B572013482F862409EB142F801902D4930 +:10DCEC00BBF1020F86F808B0716011D0BBF1010FC7 +:10DCFC0034D1591DB1740A2131820A998968716134 +:10DD0C002CE0FE2450461BF0BFFE60B2BDE8F88F3D +:10DD1C00718A5A1D0A9B02F00F0221F4706141EACC +:10DD2C000221718221F0F8015A7902F01F0241EAB6 +:10DD3C00C201718221F4C0419A7902F0030241EAD6 +:10DD4C00423140F20362328271824EF6FF72114010 +:10DD5C00DA7902F0010241EA023171820B9A42B186 +:10DD6C0011785278920042EA411108430A4908435B +:10DD7C0000E000200099B06101B171600748416872 +:10DD8C0009B9C0F804900FF02BFC747ABAE700BF05 +:10DD9C00B87B0020BB2E010001000406D01E002021 +:10DDAC007CB504468078022820D0012840F08C8075 +:10DDBC00267D00208DF8060006F1180019F04EF9AA +:10DDCC00054610B901208DF80600607940F002007C +:10DDDC00022824D1002D4CD0E078002818BF012057 +:10DDEC001BF0EBFA23D01BF0C5FA25E000208DF8D0 +:10DDFC0007002C2019F032F9054610B901208DF8D6 +:10DE0C000700607940F0020002280CD1002D54D09C +:10DE1C00E0781BF0D2FA31D01BF0ACFA33E00220E0 +:10DE2C008DF8060025E002208DF8070045E0A01DC6 +:10DE3C00042118F06DFBA860A07C32462874E07CAD +:10DE4C006874207D15342146A87505F117001BF068 +:10DE5C0099F9A05DA874A019417869758178297524 +:10DE6C000521C07829802946E8741848007811F0FB +:10DE7C0015F90DF106037520012122E0A01D0421E6 +:10DE8C0018F046FBA860A07C04F115011022287440 +:10DE9C00E07C2875207D687505F11C001BF072F97B +:10DEAC0004F12500042118F033FB0821A861074870 +:10DEBC0029802946007811F0F1F80DF1070375203F +:10DECC000221012214F0D4FB00207CBDA488002088 +:10DEDC002DE9F04F89B00E46834601A82021144647 +:10DEEC001AF0ECFF202E08D0182E04D0102E0CBFE8 +:10DEFC000127002702E0022700E0032744F2040A6E +:10DF0C004FF00108C4F2020A40F2B01908FA04F505 +:10DF1C00C1F200090094CAF80054D9F8000044F288 +:10DF2C00007441692720C4F2020488470320C4F816 +:10DF3C008080C4F88400C4F80080C4F888004FF6D0 +:10DF4C000850CFF6FF7021588F4218BF2750182E5B +:10DF5C00CAF8FC5315D101A8594618221BF0CAFE69 +:10DF6C000320C4F8880000BFD4F890008007FBD1D0 +:10DF7C000020C4F248200121016020260DF1040B81 +:10DF8C0011E0BBF1000F18BF002E10D00320C4F815 +:10DF9C00880000BFD4F890008007FBD10020C4F2A9 +:10DFAC00482001210160CAF800B0CAF808600325B6 +:10DFBC00CCF2000501201BF012FDD4F89000284291 +:10DFCC00F8D0D4F890000540C4F88850D9F8000077 +:10DFDC00016A27208847D9F8000001692720884763 +:10DFEC000020B0EB957F07D1DAF800040099C0430C +:10DFFC00C84000F0010000E0012009B0BDE8F08F3E +:10E00C002DE9F04F8BB04248DFF80CB100240DF134 +:10E01C001C0A4FF000084FF000090027007801900F +:10E02C0000EBC00086003B480078013040080290AD +:10E03C0046455CD01FFA89F1032000221023CDF84D +:10E04C0000A018F0A1F900284CD19DF821300BEB61 +:10E05C000801BDF81C009DF820200C82CC60CC720D +:10E06C004B714AF601232BF80800BDF81E000A710B +:10E07C00A1F80930029B48800B72BDF82230CB808E +:10E08C000A9B5D1C04D081F82040C1E9063315E0E1 +:10E09C00013A012A09D8214A12784AB1204B53F887 +:10E0AC002220C2EB0212920004E06FF0010203E0A6 +:10E0BC001B4A126881F820408A61CA614FF6FF71D1 +:10E0CC0088420FD0ADF8180001208DF80C0003A881 +:10E0DC0011F014FF28B11348818CBDF81C0017F007 +:10E0EC0074FD013708F1240809F10109A0E70020AB +:10E0FC000421002415F0ACFC0199884224BF0A4885 +:10E10C00047006F0A9FBF8B20BB0BDE8F08F00BFAD +:10E11C00E6BC0200D1BC0200B0540020C82700208D +:10E12C0060B70200407B0020872700202DE9F041DA +:10E13C00414F04467878C8B1DFF80081B8F8540034 +:10E14C00B8F8561088421ED008F13801204619F054 +:10E15C0040FA80B9D8F8480010B10069A04207D045 +:10E16C0008F14001204619F034FA03E0BDE8F081D3 +:10E17C00D8F8480038B1B0F9301020460A224FF0D8 +:10E18C00E04308F035F81BF0D3F92D4D0646284630 +:10E19C0002C8A14208BF28460021016078780138E6 +:10E1AC007870000636D17C60387E02280ED10820AB +:10E1BC0016F0F2FA30461BF067FC04F150004FF0F9 +:10E1CC00FF311BF0D7FB1BF0B3F9064605F1280015 +:10E1DC001BF038FD40461BF0FDFC1A481BF032FDCD +:10E1EC0008F11C001BF0F6FC17481BF0E5FC174867 +:10E1FC001BF0E2FC1648416811B107F1500088474A +:10E20C0007F1280019F0EEFB1248807810B10D20B0 +:10E21C0007F016FB7868A04204BF002078603046F7 +:10E22C001BF032FC04F150001BF008FD04F1B800A7 +:10E23C00BDE8F0411BF0C0BCD01E002030210020F6 +:10E24C007020002028800020647F0020207F002088 +:10E25C0074260020ACBB02002DE9F0478EB080463E +:10E26C000E2016468A468DF81A308DF818208DF837 +:10E27C00190001208DF81C003E48B8F1000F077BF7 +:10E28C008DF81B7021D00AEB0605687B11F0FEFEA1 +:10E29C00002403463A2802D03B2B0BD13B230DF133 +:10E2AC000409002011214A4619F084FE002808BFF9 +:10E2BC0009F1010428780994384305F8050B0DF190 +:10E2CC002B0029461BF055FC36E001AD0020112136 +:10E2DC003A2300242A4619F06DFE08B109942BE06C +:10E2EC00DFF894906C1C012101220994D9F80430B8 +:10E2FC00581CC9F804000AEB06000090384612F0CE +:10E30C00CAF81AF077FC01460DF12B001BF031FC1A +:10E31C00B9F80000194901300968A9F8000080B269 +:10E32C00814203D3D9F80400012805D114484FF4D5 +:10E33C00007100780FF086FE0DF12B000AEB06053C +:10E34C000422691C08301AF01DFF1AF806008DF81B +:10E35C0037005CB106A90DF12B024046534606F07E +:10E36C0091F8297801F0F801297000E0A1200EB095 +:10E37C00BDE8F087407B002004250020ACBC0200E7 +:10E38C00998800202DE9FE431BF0D2F8DFF80C91A0 +:10E39C00804699F80100B8B14148032201688260B7 +:10E3AC00C80711D03F4C2068416802208847019073 +:10E3BC00206841680120884702903B4801A91C3025 +:10E3CC0011F084F917F04CFDD9F80450EDB1364931 +:10E3DC00686A01AF01F11C06A96A884219D230465D +:10E3EC00394612F06FFA013011D0D5E90912E869FB +:10E3FC00541A08443946082C28BF082422461BF01E +:10E40C0079FC686A20446862E6E700240CE0D5E9F0 +:10E41C0009010024884207D309F10400294618F0A9 +:10E42C00EDF985F83240012499F8010088B9D9F842 +:10E43C00040018B180681AF017FB0AE01A481C3067 +:10E44C001AF0E5FF28B9194A4FF0FF30012110F0FE +:10E45C0053FB40461BF018FBF4B1A868002201687E +:10E46C00CA628A690AB10223137091F83030012B09 +:10E47C0007D0022B10D101F134001BF0E1FBBDE8F9 +:10E48C00FE8322B1CB6800219847BDE8FE830C695E +:10E49C00CA698B6A0021A047BDE8FE8318230020BF +:10E4AC0008800240CC0100107422002080A90300D7 +:10E4BC0070B586B0454D0446A868D0F8F41091F8B4 +:10E4CC004420B2F1820318BF531C81F84430D0F8B9 +:10E4DC00F40090F8441000EBD10090F82C104A088E +:10E4EC0080F82C20C807A86809D1D0F8F41091F94D +:10E4FC004420531C12F1020F81F84430E7DCD0F8B1 +:10E50C00F420114611F8443F802B25D8D0F8302444 +:10E51C00E1209047AA6802208DF814004FF0FF30DC +:10E52C00D2F8F430ADF80C009878022823D00128EA +:10E53C0024D030BB1BF042FB4FF47A71244B0022E9 +:10E54C00B1FBF0F023490BF045FCE0B3A8681A21AD +:10E55C00D0F8F400417004E0907810B91C4814F025 +:10E56C0007F92A202070A868D0F84013204606B07E +:10E57C00BDE870400847D2F86814F7E708208021FE +:10E58C0001E007208321D2F8786303F149020023CC +:10E59C00CDE9003203AA4FF6FF73B047A0F1DB01BF +:10E5AC00182910D8012202FA01F10B4A11420AD0A3 +:10E5BC00A968D1F8F41048702A202070A868D0F807 +:10E5CC0040132046884706B070BD00BF0C010020E8 +:10E5DC0058880020FD2C0100112400012DE9F04386 +:10E5EC0089B004464648807860B9E07AFE2809D1A3 +:10E5FC00684624211AF062FC208B10F00D0F06D017 +:10E60C00B62400E00124204609B0BDE8F083207A4E +:10E61C000028F5D001288DF8080011D002281CD054 +:10E62C0003281ED00F2820D102204FF000080B2603 +:10E63C004FF000098DF808002088ADF8000019E0B3 +:10E64C00B4F800804FF6FF700F26ADF800000220E2 +:10E65C004FEA18298DF808000CE02088ADF800006E +:10E66C0003E0684621461BF084FA4FF000080326AD +:10E67C004FF0000906F00C0707200C2F08BF0920EB +:10E68C00A17C08448DF81F00C0B21BF0C7FAA0B3E0 +:10E69C000890054686700C2F11BFE81C85F8049075 +:10E6AC0085F80380681DA17B0170E17B4170217CA2 +:10E6BC008170617CC1700430628A61691AF062FDFC +:10E6CC001AF066FF81098000033069702870B7FA70 +:10E6DC0087F04009ADF80E0003208DF80C00A07EE9 +:10E6EC008DF80D00A089ADF80A0068461BF026FADB +:10E6FC00044628461BF090FA85E7102483E700BFF8 +:10E70C00C02600202DE9F04F85B0054691460E46F7 +:10E71C00C80731D12846314612F03AFE404FF98AEB +:10E72C00884242D02846022132460CF0CBFCE0B3A2 +:10E73C0028464FF6FE7102223346FEF7C5F990BB10 +:10E74C004FEA152806F0DF0A70061ED402A92846E7 +:10E75C0017F03EF968B9B98C284616F0C1FAA0B189 +:10E76C00871C384619F03CFB78B102A839461BF0DF +:10E77C0000FA46F0200A08E0B0074CBF46F0100A39 +:10E78C0046F0080A4FF0FF08FC25264800220778BF +:10E79C00791C01702248012100913946C08A034638 +:10E7AC0009F080F818B1C72036E0002034E00E20C4 +:10E7BC001AF0200408BF06208DF8110004A818F0E8 +:10E7CC0059F840B34FF0010B064680F81EB01AF012 +:10E7DC0011FA70623069002141710AF0780187707A +:10E7EC00C57080F8048080F800B041701CB1063010 +:10E7FC0002A91BF0BEF96FF00300B9F1000F708095 +:10E80C0005D009480078484588BF86F81A903046EC +:10E81C0010F05EF800E0102005B0BDE8F08F00BFEE +:10E82C00407B0020BC880020CFBC02002DE9FE4FAD +:10E83C008A4683461AF000FEDFF80891DFF8FC8068 +:10E84C003F4E99F8001098F80200B07339B10007E8 +:10E85C0013D501200DF10A018DF80A000AE0002001 +:10E86C0000240EF093FCB07B000706D58DF80B400E +:10E87C000DF10B01522013F0FBFB0FF0D7F819F040 +:10E88C0087FF38B105460EF0E3FD13F031FF0DF0B4 +:10E89C00B5F808E009F052F80546307E012101FA7E +:10E8AC0000F0294908604FF6FE74012D2FD10FF0AE +:10E8BC0029FC1BF04BF807462448234900680860E4 +:10E8CC00FF20022114F0FAFF601C7483F482B084E0 +:10E8DC00002013F0CFF907F07F00584400F16406D4 +:10E8EC001B480078012808D10020BAF1010F1CBF89 +:10E8FC00CDE90000684615F013FB114A2120742164 +:10E90C001AF07EFF0020022114F0D8FF00E0002650 +:10E91C0028460CF0FFFF601C80B2834507D0012015 +:10E92C0089F8000018F01EF8B0B219F025FF98F81D +:10E93C00020019F04DFB2846BDE8FE8F268700200B +:10E94C00407B0020C4260020708800206C2700200B +:10E95C00182600202DE9F0438FB014F0EFFB3F4F49 +:10E96C0097F82600082806D00120C7E90C003C487F +:10E97C000078F87078710DF11408242140461AF0D3 +:10E98C009DFA39480F25374EDFF8E0900DF13B0129 +:10E99C008DF83B5000783570013818BF01208DF888 +:10E9AC001E004620C847324800248DF800400078ED +:10E9BC008DF801001AF0ECFD8DF8020097F8380084 +:10E9CC008DF80640ADF8034007F139010F2838BF28 +:10E9DC0005468DF805506D46E81D1BF0CAF84FF042 +:10E9EC00FF303278234EADF80F008DF8110097F8F8 +:10E9FC00720031468DF81200284610F092FE452028 +:10EA0C003146C84705F028FFB88D97F82F108DF8C0 +:10EA1C0020408DF834408DF82940ADF81C00387E2C +:10EA2C008DF81F1007F116018DF81A00B88CADF88F +:10EA3C0018005320C84707F11A014B20C847F87932 +:10EA4C00642100FB01F20C48082100781BF04CF803 +:10EA5C00404606F0BFFB0FB0BDE8F083407B0020C2 +:10EA6C00E6BC0200A9270020182600207D20020009 +:10EA7C00D827002008870020988800202DE9F84F1F +:10EA8C004FF00056002A984617460C46824618BF8F +:10EA9C004FF080464D1C1AF04BFD814635B1504667 +:10EAAC002146002213F0B2F904460FE03748816C7E +:10EABC0011B10969514506D0C16C11B109695145B3 +:10EACC0003D0846B02E0846C00E0C46C34B194F924 +:10EADC003300B0F1FF3F03DD042451E003244FE089 +:10EAEC00DFF8A8B00A9DDBF84800844218D0DBF8A8 +:10EAFC004C00844214D05046214642462B460AF024 +:10EB0C0033FB0028E8D02248017E012937D0007E53 +:10EB1C00042834D01F48204928301BF095F82EE0EB +:10EB2C00DBF848000022334617F008FFDBF84C00F6 +:10EB3C000022334617F002FF1848002F18BF00F5CB +:10EB4C00803018F0AFFE85B1DBF848001AF0EFFE0C +:10EB5C00DBF84C001AF0EBFE20690E49086291F8C4 +:10EB6C00240040F0010081F82400B8F1000F06D019 +:10EB7C00DBF83810504601222B460AF0F5FA8324B4 +:10EB8C0048461AF081FF2046BDE8F88F302100205E +:10EB9C00D01E002070200020020000400100010463 +:10EBAC002DE9F0410546880058BFBDE8F0810020F2 +:10EBBC00002410F09FFA3D493D483E4FCC6108605F +:10EBCC0040F60A008846B887FC8797F8480000F0A2 +:10EBDC00F00087F848003C6497F8490000F0F0001A +:10EBEC00013087F84900284607F050FEAC68012038 +:10EBFC0021460E46496849B10A88A2F60302072A43 +:10EC0C00F7D800FA02F212F0830FF2D0707B00F00A +:10EC1C00F000707307F13C0070602748806B28B1DE +:10EC2C00C0680088A0F6030002281AD3284630F8E2 +:10EC3C00381FB1B10021E9636987386495F8440045 +:10EC4C0095F8451000F0F00085F8440001F0F00054 +:10EC5C00013085F8450097F8490000F0F00087F87E +:10EC6C00490019F0EFFF1548F86197F8250030B10D +:10EC7C0017F050FE0028FBD012F042FB0BE00120F5 +:10EC8C001AF0FEFC012806D0707B00F0F000013079 +:10EC9C0070730B48F86100202146C8F81C00C8F8B6 +:10ECAC0000400120BDE8F04118F0CCBE001004403B +:10ECBC0001010E04D01E0020302100202D37000051 +:10ECCC00850802002DE9F04788B0434D0A460446FA +:10ECDC001046A98C14F0A8FC40B1417831B9072139 +:10ECEC0041703E490978013149080170A06A10222F +:10ECFC004778F90658BF082217F08F0F13D1BB06BF +:10ED0C0048BF0832237F93420DD190F8029090F8BF +:10ED1C000780B0F805A0B0F80360002909D407F00B +:10ED2C00700708200DE0D32008B0BDE8F04707F0CD +:10ED3C00EABF00F1080106A81AF01BFF07F06007F4 +:10ED4C001020B90606D5A16A014404A81AF011FFD7 +:10ED5C0007F05007B6B24946304615F051FD204930 +:10ED6C00097888421ED21F4900EB800001EB40005D +:10ED7C0010F8061F41452CD980F80080E88A86429D +:10ED8C0013D0A1891FFA8AF401223B462046FDF7D5 +:10ED9C009BFEF0B904A806A90297CDE900103046F5 +:10EDAC00214612E0E88A864207D1A1891FFA8AF02F +:10EDBC0001223B46FDF788FE0BE004A806A902974A +:10EDCC00CDE900101FFA8AF1304642464B4602F05C +:10EDDC0093FF08B0BDE8F087407B0020D1BC020057 +:10EDEC00D9BC0200D07E00202DE9F84F0746087AE6 +:10EDFC000C4640F00201032917D10025B7B1FF2FB3 +:10EE0C0014D09A4616460AB903280ED00FF03AFAD7 +:10EE1C00204611F021F88146207A4FF6FE71B0F1B0 +:10EE2C00010B18BFB346894503D100252846BDE820 +:10EE3C00F88F0138DDF82880314EB0FA80F04409A3 +:10EE4C002E4801780020814230D03278BA4208D165 +:10EE5C007278A24205D17288914502D132799345DC +:10EE6C0002D00E360130EEE706B32649C7B235465E +:10EE7C00B1F80090BAF1000FD8D0B8F8004028468D +:10EE8C00214619F0F5F960B92846214618F060FAC8 +:10EE9C0030B1022039464A46334617F08BFA00E06F +:10EEAC00002508F10208AAF1010AE3E70DF10300BD +:10EEBC0017F0F4F805460028B8D0134885F804B0CC +:10EECC00A5F802906C702F7041460078504538BF01 +:10EEDC0082464FEA4A0285F805A0A81D1AF052F99D +:10EEEC009DF80310064AC1EBC10002EB4003054834 +:10EEFC000288022017F05EFA98E700BFE2BC02001D +:10EF0C0018870020C2B40200D3BC02002DE9F843DC +:10EF1C00804600683B4BD8E9012118603A480260F2 +:10EF2C003A4820221AF0E6FED8F80C003849DFF8EF +:10EF3C00E89090E8FC00FCC1D8F80C00354990E84A +:10EF4C00FC00FCC1D8F81000494690E8FC00FCC15C +:10EF5C00324D402299F80C00D8F8141040F0800083 +:10EF6C0089F80C0028461AF0C5FEE87BD8F8181072 +:10EF7C00202240F0A500E873294D28461AF0BAFE6D +:10EF8C0040F20540697BAA7CEB7DC5F80490288291 +:10EF9C0003202875287B40F08000287301F0F000D6 +:10EFAC0020490230687302F0E0000A460130A87470 +:10EFBC0003F0F0000130E875D8F81C0090E8F80078 +:10EFCC00F8C2087BCB7B4A7B40F08000087303F0CF +:10EFDC0070008430C87302F0F000013048734FF4B5 +:10EFEC0058600861D8F820000F4908600F48C068C5 +:10EFFC004069007808B111F00FFBBDE8F84315F03B +:10F00C00D3BD00BF6488002068880020C083002026 +:10F01C007885002090850020A8850020E87F0020BE +:10F02C00A083002030860020608800200C01002086 +:10F03C002DE9F04387B0DFF8FC8081462025EFF303 +:10F04C00118085F31188D8F830501DB180F31188E8 +:10F05C0000256AE0C8F83090374F80F31188002003 +:10F06C00C9F80C104FF48031C9F81C20C9E9120002 +:10F07C00C9E90801002B18BF1F46D7E90116C9F8CA +:10F08C001810397B012905D1C9E91060C9F8146041 +:10F09C0030460DE0294A002031460023002519F0A6 +:10F0AC0011FFC9E910012649C9F814008E423CD859 +:10F0BC000021DFF890E0C9E9160197F800C0C9F803 +:10F0CC005410BCF1020F08BF0146C9F8501001AB37 +:10F0DC009EE8F5001946BCF1000FF5C108F11C00C3 +:10F0EC001A4ACDF808900090174808BF0246142120 +:10F0FC0009F1280018F0F2F905462020EFF31181F0 +:10F10C0080F3118881F3118899F8100010B94846E2 +:10F11C0012F056FC35B108F12800494619F06CF98B +:10F12C004D4602E00025C8F83050284607B0BDE82F +:10F13C00F08300BFA01F002084B9020040420F00E2 +:10F14C003F420F0060BA0200E9360200D192020081 +:10F15C002DE9FC47434FDFF810810DF1070A4FF002 +:10F16C00000918F0BFFB002800F0798050460121FF +:10F17C0014F016FD38780528F3D8DFE800F0030901 +:10F18C000F1928469DF80700FE28EAD1032462E0F7 +:10F19C00B8689DF80710022441705CE0B8689DF8CF +:10F1AC000710042481707878002808BF052452E0E9 +:10F1BC009DF8070088F800907870033017F04EFF28 +:10F1CC000028B86049D079780124017043E098F8A0 +:10F1DC000000411C88F80010B96808449DF807101D +:10F1EC00C17018F07FFB054698F8000079780A1A70 +:10F1FC00B9680844E9B203308A421ADA91B214F0C1 +:10F20C00CFFC787888F800001FE07878BD689DF80E +:10F21C0007400330C6B22846314619F019FBA0420C +:10F22C0015D17B68B3B1304629460022002498479B +:10F23C0011E014F0B5FC98F800007978284488F8AF +:10F24C000000C0B288427FF48CAF052403E028464E +:10F25C0018F002FE00243C7083E700203870BDE8F3 +:10F26C00FC8700BFF425002092880020F8B50446E6 +:10F27C004048C16819B12046BDE8F84008473E4EE9 +:10F28C003068074658B1054660882988814203D109 +:10F29C002079A978814216D0A8692F46F2E71C2064 +:10F2AC001AF0BCFC002863D01C21054619F006FEA0 +:10F2BC00FF20E8724FF6FE7028813068002818BFD6 +:10F2CC0007F1180635602079217A627A237BA870C1 +:10F2DC0060880129AA7169712B75288005F10C00D1 +:10F2EC0007BF4FF0FF31C0E9001104F10D011AF016 +:10F2FC0040FC2249A07A0978884239D961790129E0 +:10F30C0003D01AF029FA98B3A07AA97A884202D9C4 +:10F31C00E27A102A05D3884206D1E97AE27A8A4247 +:10F32C0002D20022012101E001220021144B1B78A2 +:10F33C00022B01D2A31D01E005D1E31D1B7813B1F3 +:10F34C0072B9228808E00F4A538B2288D31AB3FA79 +:10F35C0083F35B09194203D0A872E07A2A81E87220 +:10F36C00E07908B101202871A07908B10120E8707A +:10F37C00F8BD00BF3C830020E487002093270020C9 +:10F38C0018260020407B00201EF0040F14BFEFF362 +:10F39C00098169468869A1F1480214BF82F3098882 +:10F3AC00954621ED100BF1EE102A41F8082DEFF3E4 +:10F3BC00118102B400B5DFF8D8E0F047374A126883 +:10F3CC00116801EA000010605DF804EB1EF0080FF4 +:10F3DC0009D101BC80F311885DF8080BE1EE100A2D +:10F3EC00BDEC100B704704BC1EF0040F14BFEFF300 +:10F3FC0009816946A1F1200114BF81F309888D466A +:10F40C004A604FF08070C86125488861234B1B68A7 +:10F41C001868086040F201101860704702B401B41B +:10F42C00EFF3148100291CBF002282F3148802B46C +:10F43C0002B4DFF860E0F04701BC01BC00281CBF3F +:10F44C00022181F3148801BCDFF84CE0F0470F482F +:10F45C004FF08051016001BC80F3118800BF00BFE8 +:10F46C00FFF7FEBF1EF0040F14BFEFF309816946CE +:10F47C0001F1200151F8080BE1EE100AB1EC100B70 +:10F48C0014BF81F309888D46704700BF04ED00E07E +:10F49C00DDCB01008B9B0200919B0200B8BC0200EB +:10F4AC0028F400002DE9FE4FD0E90085994614465A +:10F4BC000F46834613B10020C9F8000074B11AF04E +:10F4CC0037F8064698F8070058B198F8E80070B17C +:10F4DC0030461AF0D9FA6FF008056DE06FF00905A7 +:10F4EC006AE030461AF0D0FA6FF00E0564E00020A6 +:10F4FC000121C8E93B74C8F8F440C8F8FC0088F84E +:10F50C00E810C8F83C0088F80D0088F80B00284675 +:10F51C0001951AF0FDF830461AF0B6FA08F1D0064B +:10F52C000DF1080A1AF004F804463046514616F05C +:10F53C00F0FA0546D8F8F400D8F8FC10854288BFDC +:10F54C000546029839442A461AF0D4FB304629461F +:10F55C0014F022FCD8F8F400D8F8FC10401BC8F8C2 +:10F56C00F4004819C8F8FC0020461AF08DFA012D59 +:10F57C0003DBD8F8F4000028D4D119F0D9FF0446E5 +:10F58C00D8F8FC0050B101981AF0C2F8584605F0B2 +:10F59C003DFBD8F8FC0008B1002502E06FF00F0528 +:10F5AC000020B9F1000F18BFC9F80000002088F83E +:10F5BC00E80020461AF068FA2846BDE8FE8F70472E +:10F5CC00F8B504460020A5782075C4E9030045F081 +:10F5DC00020000F0030002280CD115F00C0005F01D +:10F5EC00030218BF042809D1022A05D1E90601D467 +:10F5FC0002210FE0012619E0022106E00C2803D0BD +:10F60C000828F1D0012100E00321022A02D1EA06E8 +:10F61C000E460BD448B10E1D0C2807D8012202FA55 +:10F62C0000F041F21012104200D04E1D28060AD5EF +:10F63C00E078800706D0A8074FF0030058BF0220DF +:10F64C00064400E00136278819F0A8FF87420BD04A +:10F65C00A80609D51F48416920468847206918B972 +:10F66C00A07800F0DF00A070207D00B1F8BD6179BA +:10F67C005020751C8DF8000020798DF8021021693E +:10F68C0028448DF8010029B10A7F497F10440844B1 +:10F69C008DF80100684613F0C9FBA0B1012180F878 +:10F6AC0048504176218841806188018721792269FF +:10F6BC0080F8421001692944416412B1127F11444F +:10F6CC004164E060F8BD20461AF0E1F81020207586 +:10F6DC00F8BD00BF502400202DE9FF413B4E96F8A9 +:10F6EC00420100286AD1012086F8420119F0D4FFAA +:10F6FC00374F86F87001374D7868C6F86C01387B47 +:10F70C0086F84101A86810F4402F13D1386988B1EC +:10F71C0028686421C0F3066000FB01F41AF04EFA6D +:10F72C00B4FBF0F22C4906F19400002315F0E8FC30 +:10F73C0019F038FD01AC20461AF0B3F82749A84659 +:10F74C00002506F10C00002219F0FFFD20461AF0EE +:10F75C00A8F8234906F15000082219F0F6FD214AB9 +:10F76C0006F1D8003221002313F034FC1E4C1F4A42 +:10F77C0006F1F4002C2100232560454613F02AFCE9 +:10F78C00D8F80800797BC0F3815021B1032804BF5D +:10F79C00012186F83911032803D040F00200022819 +:10F7AC0010D1206840F040002060022015F0F8FDD8 +:10F7BC006868400702D4002015F0F2FD002004B068 +:10F7CC00BDE8F08114F094FAF2E700BFD81B0020DA +:10F7DC0090BA0200AC4F0050A79402000F7B0100BE +:10F7EC003D28020071CB01009022084035A5000095 +:10F7FC002DE9F8431D46434BDDF8208043F6060601 +:10F80C001C68038814F0007411D0B34227D0B3F5F0 +:10F81C00C15F33D040F60206B3423ED100F1120371 +:10F82C000B604169116081692960C1692EE0B342A6 +:10F83C000AD0B3F5C15F03D040F60206B34203D140 +:10F84C0000F11203143002E000F11A031C300B60BB +:10F85C000068106000202860C8F800004BE000F140 +:10F86C001A034FF000090B60C1691160016A29602D +:10F87C00416AC8F8001000F118011CE000F11203F5 +:10F88C000B6041691160416A2960816AC8F80010F7 +:10F89C0000F1100190F80F900DE000F11A030B60CD +:10F8AC00C1691160816A2960C16AC8F8001000F151 +:10F8BC00180190F82490286868B10E8819F068FD3A +:10F8CC00042808D8074606F0070148460EF018FF32 +:10F8DC00296841F82700D8F8000060B119F058FDEC +:10F8EC00042808D805464846FF210EF009FFD8F831 +:10F8FC00001041F82500002C18BF01242046BDE85B +:10F90C00F88300BF941200507CB50446007A02289C +:10F91C0003D3208814F028F910B1022630467CBDA0 +:10F92C00207A032806D10DF10201204615F058FB70 +:10F93C0018B9F2E72088ADF80200608A44301AF05A +:10F94C006DF9002864D04421054619F0B7FAA07A65 +:10F95C00694617F071FE9DF800009DF8011085F8BE +:10F96C003A0085F839102846012117F0BBFE05F145 +:10F97C0010002146242219F005FC628A616905F108 +:10F98C0044002864AA8719F0FDFBBDF80200A8808A +:10F99C0020480178E971013101701AF011F906461D +:10F9AC001AF00CF970434FF47A710026B0FBF1F0A9 +:10F9BC00FF218DF80460288095F8390001FA00F0D9 +:10F9CC00217E85F8370085F83600207A8DF8060000 +:10F9DC0001F001008DF8050001A819F0BFF9298D7F +:10F9EC00023885F83400C0B241F0080183B2298591 +:10F9FC00A98F8AB2B2FBF3F202FB1010000418BFFD +:10FA0C0001322A720448012100780EF01BFB85E7B5 +:10FA1C00102683E7948800203C2600202DE9F04135 +:10FA2C008AB0DFF8E080D8F8000070B9364C206856 +:10FA3C0028B936488068D0F84C0580472068344C8B +:10FA4C00016A204688473348E06133480068016901 +:10FA5C0031B12E488068D0F8D40090F85300884714 +:10FA6C002A4DA868D0F8D40090F9420010F086FB1B +:10FA7C00411C03D0294940EAE0704882274C002001 +:10FA8C0060606080207B617B40F08000207301F01F +:10FA9C00F00001306073A868D0F8C403804730B917 +:10FAAC001F4810210170E868142140680170D8F8D3 +:10FABC000000C0B10020002714F02EFB124E30685D +:10FACC00416E02AD2846884731680597D8F800008A +:10FADC002A4600230E6D0821CDE900172146B047B8 +:10FAEC00104804600AE010480C4A094B01680648AB +:10FAFC00006804680D48A047C8F800000AB0BDE8CB +:10FB0C00F08100BFD8260020308800200C01002096 +:10FB1C00E083002054F100805C880020C08300202A +:10FB2C00B088002020250020648800204873002025 +:10FB3C002DE9F04788B0DFF8FCA0D0F804803E4EE9 +:10FB4C007F2400217F23DAF8280020EA0800CAF875 +:10FB5C0028001B2915D020FA01F2D2070FD000275C +:10FB6C00324612682AB19578A94208BF013718327B +:10FB7C00F7E7DAB2FDB295423CBFCCB23B4601315D +:10FB8C00E7E7B8F1000F15D0CAF8288001AC1821AE +:10FB9C00201D19F093F90120CDF804808DF8080090 +:10FBAC009AF82E008DF8090020460EF0D3FF08B00D +:10FBBC00BDE8F087204EDFF884804FF6FF793046A1 +:10FBCC000768BFB13888BAF8241088420FD1B978C9 +:10FBDC00A1420CD1B8F8001049451DD11AF004F817 +:10FBEC00AAF82400398881423046E9D102E007F1B5 +:10FBFC001800E5E78AF81840FEF7ACFE0028D6D0CE +:10FC0C0000208AF826000E4801680029CFD0C420B5 +:10FC1C0008B0BDE8F047084700208AF826000848DD +:10FC2C00016809B1C4208847002008B0BDE8F0473E +:10FC3C0016F01EBA407B0020E487002080270020AD +:10FC4C00002500202DE9F04389B03F4A127882420A +:10FC5C0009D93C4A3D4F002952F8306018BF0F4675 +:10FC6C0096F8521021B10025284609B0BDE8F08362 +:10FC7C0002EBC009D9F804406078022826D1022092 +:10FC8C0086F8520012F07EF80DF10C08404619F07F +:10FC9C0081FA3868002541468DF8145006958DF888 +:10FCAC000C500490207812F0A3FD00287060DBD07B +:10FCBC0019F02CFFF87988B1B87939684843642178 +:10FCCC00B0FBF1F1706819F01EFF07E000F0F2FCD8 +:10FCDC00012086F85200207886F854006D4628469C +:10FCEC0019F0DFFD002000212A46CDF808908DF890 +:10FCFC0000000190164813F031F9B06070B138680B +:10FD0C003060B97986F85310F87902280CD00128A4 +:10FD1C0012D0A0B9484613F06AF810E070680028B9 +:10FD2C00A1D019F0EDFE9EE7B8884FF6FF7241089E +:10FD3C0048460CF0EBFB02E0484613F0A5FE4D469E +:10FD4C0092E700BF24BB02008FBA02002CBC020059 +:10FD5C00FD2A02002DE9F04F85B0044600880DF114 +:10FD6C00060116F063FE0546182019F057FF4FF6F2 +:10FD7C00FE7970B11821064619F0A0F86088182198 +:10FD8C00324619F03DFD09F101006080304619F052 +:10FD9C0043FF0020A4F80090002D20715DD1DFF806 +:10FDAC00C0A0BDF80640DAF80000B8B3142019F072 +:10FDBC0035FF98B3834604AB4C2000210222002768 +:10FDCC0019F062F8009404EB440402AE0BEB44000F +:10FDDC004FEA4408851C122F17D0B84505D1DAF824 +:10FDEC00000000EB440128460AE0B81C062233460A +:10FDFC0081B24C2019F048F80BEB07003146023069 +:10FE0C00062219F0BFF90637E5E74C2014215A46B3 +:10FE1C0019F0F6FC584619F0FFFE009C04AB4C2080 +:10FE2C000021022219F030F8B8B9DAF8000050B10C +:10FE3C0004EB440130F81100484504D1BDF8100022 +:10FE4C0030B1013802E0BDF810000130ADF81000FF +:10FE5C0004AA4C20022119F0D3FC05B0BDE8F08FA8 +:10FE6C00E0260020F8B5067B07460D46304618F014 +:10FE7C00FBFC18B104464089002726E07A893868D3 +:10FE8C00314616F0FCFF0026002869D00446068196 +:10FE9C0017F8100F207478886082384619F076F8BD +:10FEAC006061388961892083B87AA07621F460700A +:10FEBC004907608105D42B490978013140EAC1100A +:10FECC0001E040F0800001276081C0F3C21195B1C0 +:10FEDC00022262732268D289520702D5224A128A00 +:10FEEC00228169B36FF07F0220F4607002EBC111C4 +:10FEFC000843608124E039B1810607D4C1060BD4D4 +:10FF0C0040070FD4012013E000261AE019F01EFD63 +:10FF1C0000F07F005F300BE019F018FD00F00F00CF +:10FF2C000A3005E01148058819F010FD2840023010 +:10FF3C0020810F4804216173202100780EF082F893 +:10FF4C0001266FB12289617B20460CF0C7F938B1CC +:10FF5C00606908B119F060FE204619F05DFE0026BC +:10FF6C003046F8BDC5270020407B0020BEBC0200F7 +:10FF7C00988800202DE9F0418AB03E4E0546306845 +:10FF8C0020B13D490978A94209D82DE013F094FE1F +:10FF9C003068002448B338490978A94225D94FF074 +:10FFAC00FF3119F0E7FC354905EB450001EB800406 +:10FFBC0067683878A8B9A568A9682A6848424B1EB2 +:10FFCC001A42B8600DD16A688A420AD31040824244 +:10FFDC0007D1686910B10068786029E0298B042981 +:10FFEC0007D3306819F02CFE002420460AB0BDE877 +:04FFFC00F08106EB9F +:020000021000EC +:1000000081000069A8B90DF10408404619F062FBAF +:10001000002041468DF810008DF80400E869059035 +:10002000287E12F06BFC0028E1D0298B06EB8102C0 +:100030001061786031440A7B01320A73298CC6E969 +:100040000101204616F0ECFF01203870AB20318909 +:100050008DF82700204618F04EFF0DF127000121F2 +:100060000FF0B2FD31890546204618F04DFF15B955 +:1000700020460EF0FFFD306819F0E8FDBBE700BF39 +:100080000C240020F3BA0200A0B902002DE9F84FB9 +:100090003C4C3D4E3D4D42F62A294FF0010A4FF0AF +:1000A000030B00274FF00508D4F83C01062833D88D +:1000B000DFE800F00433183B203D4B000F20F060D8 +:1000C000C6F8109013F09AF845F804AC55F8040CF3 +:1000D0008007FBD5C6F81CA094F8390190B1012027 +:1000E000EF6210E02F60C4F83CB128688007FCD4B0 +:1000F0000320DBE72F60C4F83C8128688007FCD42C +:100100000520D3E70320C6F800B0C4F83C012F60F7 +:1001100029688907FCD4C9E7FEE70126022084F894 +:100120003A6112F0ABFB2E6009E0022000E00320F0 +:1001300084F83A01002012F0A1FB0120286004F1AC +:100140005000BDE8F84F19F049BD002045F8040CF7 +:10015000286055F8040C8007FBD428688007FCD47D +:100160000B480025012105600A4801600D2005F0BB +:100170006DFB022014F0FCFAC4F83C5184F83B51AA +:10018000BDE8F88FD81B002000400C4058600C40A0 +:100190003C500C4004800C402DE9FE4FDFF8F4B0D9 +:1001A00001219BF80C4001AA204619F0C6F86A46C6 +:1001B0002046022119F0C1F8DFF8DC909BF80EE030 +:1001C0009BF80D00BDF800C099F800100EF1010376 +:1001D0000746B3FBF1F404FB11359DF80240ADB2C4 +:1001E000FEB2B5420FD0A642634618BF102372007C +:1001F00052FA87F20BEB82029383721CB2FBF1F38B +:1002000003FB1127ECE7DFF894A0002401270DF190 +:10021000080857FA8EF2C9B2C5B2B2FBF1F303FB7C +:100220001121A94232D0690051FA80F00BEB800213 +:1002300032F81C0F102806D1284607F0A1FA8AF8D8 +:100240000000013417E028460421022313F01EFDAC +:100250008AF80000284600214246042318F060FF77 +:100260009DF808007C2802D0FE2804D10DE0284625 +:10027000782114F0FBF999F80010681C9BF80EE047 +:10028000B0FBF1F202FB1100C3E7FEE7E0B2BDE80C +:10029000FE8F00BFA080002097880020A0230020B0 +:1002A0002DE9FE4F05460F465818AE687168884222 +:1002B00002D96FF0030564E0DFF8E8800C9C4FF092 +:1002C000FF3199469246D8F8000019F059FBE00733 +:1002D00011D1A0071ED5306851464A463844CAB1EC +:1002E00011F8013B10F8014B013A1C40A342F6D033 +:1002F0006FF0060541E0D8E90101CB4301EA0902AC +:1003000013EA090F18BF02442846394009F0E8FEF5 +:10031000054690BB306802970196074412F00EFC28 +:10032000CB4655460090BBF1000F16D05E46BBF1A0 +:10033000080F28BF082619F001F9804628463946DB +:10034000324617F071FD0446404619F0A3FB2CB964 +:1003500037443544ABEB060BE5E70024009817F073 +:10036000B1F8DFF84080DDE901210C9814B14FF0BD +:10037000FF3502E0400707D40025D8F8000019F047 +:1003800065FC2846BDE8FE8F10680844B9F1000FEF +:10039000F2D010F8011B1AF8012BA9F101098A42C9 +:1003A000F4D0E4E7DC250020B0B50C46880722D461 +:1003B000600758BFB0BD354D0120A870042014F06F +:1003C000F5FF33480068006B8047E8602D48806B7C +:1003D000F0B16968046961B1A1420AD094F82800BB +:1003E000400704D5636A2046042100229847012073 +:1003F00060766C600DE0FCF763FD2248006CE0B3B2 +:10040000214844F002012830BDE8B04019F022BC78 +:100410006C6860681F4900780860022014F0C6FF0D +:10042000102005F085FC012028761B48807810B943 +:100430000D2005F07DFC6868416818488A680AB993 +:10044000C96821B100218160154940F8141C154983 +:1004500007220A6001680021016042684160124978 +:10046000124AE9610168114301601A2019F0BCFBCE +:100470001920BDE8B04019F0B7BBBDE8B0400DF0A1 +:10048000B5B800BF3021002070200020D01E002011 +:100490008C010010D0210840ACBB020014100440B5 +:1004A0005100070600000460ADEB00000240004070 +:1004B0002DE9F84F3A48DFF8EC90DFF8ECB0DFF8C0 +:1004C000EC8000264FF0060A00210078C700B742F2 +:1004D00042D009EB0605A878E0B30138A870687926 +:1004E00018F0C8F9A8B30446A87800B3A87948B3AF +:1004F000287970B3E9780139E970090629D19BF8A8 +:10050000011001382871E970617B032921D10006AF +:100510001BD00420607319F01FFA00F00F00202197 +:100520000130208198F800000DF092FD11E0607B11 +:1005300084F80DA002280CD02068F021407B11F037 +:1005400091F906E0607B032803D12846214610F08C +:1005500001FF01210836BAE798F8000001290BD104 +:10056000402112F02DFEC0B998F80000402164220D +:10057000BDE8F84F19F0BBBA40210EF039FA0C482B +:100580000178012909D1002101700A48007806F09C +:10059000B1FCBDE8F84F12F06DBEBDE8F88F00BFAA +:1005A000D2BC020042760020407B002098880020C8 +:1005B000DA270020DB27002070B58AB04FF4806175 +:1005C000041D4588ADF826108189807B0894ADF81C +:1005D00024500328ADF81C1034D0022806D0B0BB3C +:1005E00040F601000026ADF826005AE032480078B7 +:1005F00001285FD10DF11B0101AA204608F0DAFFA6 +:1006000004469DF81B00012854D19DF814000228CF +:1006100050D101AD1421284618F056FC274904EBAF +:10062000440000222B4641F8202001EB80002146A7 +:1006300042604272FF2014228DF81400042015F04D +:10064000BFFE37E0102000268DF8270029E00DF1CD +:100650001B0101AA204608F0ADFF01469DF81B00D2 +:1006600001281DD19DF81400022819D1134A002336 +:1006700001EB4100CDE9013342F8203002EB80006C +:1006800014224360FF208DF814009DF816000130FD +:1006900000F00F008DF8160001AB042015F090FE5D +:1006A000012607A801F050FE26B118B928462146B8 +:1006B00002F044FA0AB070BDBB270020804300203E +:1006C0002DE9F047A4B018F039FF34490A78012A1F +:1006D00004D124B0BDE8F04719F0DCB94FF00109AE +:1006E00081F8009019F0D6F9FEF7FCFF082005F01C +:1006F0001FFB21AC204618F0BBFC4FF0FF30294A0D +:10070000102123462290264812F06AFC2648284DE4 +:1007100000260DF1040A0478244890F8008047462A +:10072000A74212D8286850F8271021F0FF004AF895 +:100730002700880707D4F8B201F0010118F088FCFF +:1007400009FA07F006430137EAE71A4806601A4833 +:10075000C16801F44001B1F5800F09D10068000EB5 +:1007600018BF01205AF8201041F007014AF8201064 +:100770001248A4EB080204230AEB880103EB82026F +:1007800040EA880019F0BCFA0D482022016862F3A3 +:100790000D21016024B0BDE8F08700BF962700203E +:1007A000608400203D1C02009FB6020045B6020096 +:1007B00014BB0200D0200240A84F00500010084097 +:1007C00000300940FEB5D0E9005401A818F030FC13 +:1007D00095F834003649374A384E085C95F835109C +:1007E000515C354A084395F83610515C2A6B40EA53 +:1007F0000103316820684F680299B847206840F2C9 +:10080000F272E1692E4B2F4F426494F854209A5CA7 +:1008100094F85530FB5C1A430129426311D101461B +:10082000D4E90A2351F8307FFF2A27F4004718BF84 +:1008300007F50047FF2B0F6009D00A6842F4804299 +:1008400008E0014651F8302F22F400420A600A689D +:1008500022F480420A60C16A41F01001C162016B5A +:1008600041F001010163E16B09B3A16BF9B1012111 +:1008700018F090F8D5F85801E16B40680068C16243 +:10088000C0F8041591FAA1F17268B1FA81F15368C8 +:10089000022298477068A16B02224368D5F858017C +:1008A00091FAA1F1B1FA81F1406800689847FEBD64 +:1008B000A8BC0200C8BC02009AB60200D001001019 +:1008C00091BC02008CBC02002DE9F04186B018F00A +:1008D00079FF0446002718F075FF10B180690137D1 +:1008E000FBE7DFF8CC8098F80000012831D818F039 +:1008F00069FF304EB18C28B102888A4229D08069C4 +:100900000028F8D11C2019F08FF910B30546B08CDF +:100910002880307EA87018F041FE6871264806F1E4 +:1009200039010078A87105F10C0019F028F90DF1D2 +:100930001701412015F076FB20489DF81710AC6197 +:100940002C460088002908BF6FF00100013728817C +:1009500000E000251A48FBB200210278934201D240 +:1009600000260BE0BE1A0020C7B2974202D2A4694B +:100970000130F9E7F0B2052828BF05261148F6B284 +:10098000CDE902411049CDE900260022007803F0AC +:100990001DFD98F8000008B1012803D115B12846C3 +:1009A00019F040F916F064FF06B0BDE8F08100BF11 +:1009B00018260020407B0020D827002070870020C8 +:1009C000C3880020C288002084870020F8B5044630 +:1009D00018F036FB07464568204618F0CBF898B16A +:1009E000D7E9014618F0AAFD0546D4F8C000C8B101 +:1009F00004210174384606F00DFCD4F8C800C0B1DB +:100A0000416949B10846FBE718F098FD0446D5F85E +:100A1000C000B0B310303BE0D4F8C010416101F128 +:100A200014000BE03068416821F002014160284663 +:100A300031E0D4F8C000C4F8C800143001680027C1 +:100A40000760C4E93477C4E93677C4F8C01031B31D +:100A500020463146FBF7D0F8D4F8C000C4F8E07067 +:100A60000068B0F5806F03D920463146FBF7C4F823 +:100A700094F8FE0010BB3068416841F0020141600B +:100A80001CE095F8FB00002114F058FB05F1FC0078 +:100A9000012101702046BDE8F84018F0FBBF94F832 +:100AA000FB000021C4F8C47014F048FB012084F856 +:100AB000FC003068416A21F003014162284618F0C9 +:100AC000E9FF04F13000BDE8F84019F0C5B87047FF +:100AD00070B5C1680C6991F8381041F002032246E4 +:100AE00003F0030302F8011B022B3BD111F00C03AE +:100AF00001F0030518BF042B2DD1022D01D1CE0624 +:100B000030D4C26892F83B2062700234022D01D1C9 +:100B1000CA0626D4C26892F83E202270C26892F8B3 +:100B20003F206270C26892F84020A270C26892F8BA +:100B30004120E2704BB1221D0C2B13D8012505FA80 +:100B400003F341F210152B420CD0C26892F83A2000 +:100B50002271621D06E00C2B2ED0082BCDD014463E +:100B6000D4E72246C46801F0020394F8395005F036 +:100B700003051D4309D1658D2D0606D4134E357826 +:100B800084F849506C1C347001E094F8495009060F +:100B9000157010D5C16891F839105170C16891F87D +:100BA0003940A40707D091F84B1091701BB1C06871 +:100BB00090F84C00D07070BDC26892F83C20627012 +:100BC000C26892F83D20A27003349FE79488002009 +:100BD0002DE9F8430546007F04282FD1A86A4678FE +:100BE000B0F802900E2E38D80C460127DFE806F048 +:100BF00008080841414141414141412A2A38410008 +:100C000031480078012833D83048807B80072FD5C1 +:100C10001FFA89F80021404609F022F900283FD048 +:100C2000817911F0180F3BD0AA894388698900881F +:100C30000027009200220FF0ECF81AE0D32006F013 +:100C400068F829E020480078012811D81F48807BE7 +:100C500080070DD519F008F80AE00127002408E004 +:100C600019480078012803D81848807B80071DD4D4 +:100C7000012768891FFA89F2314618F0C7FF688991 +:100C800012F078FF40B1A87C022805D327B10F48A5 +:100C9000A989C08A814200D100242046BDE8F8839A +:100CA00040460121012716F085F9E2E71FFA89F88D +:100CB000404617F0AFFF40460CF05AFEB0F1C507B2 +:100CC00018BF0127D5E700BF18260020407B002071 +:100CD0002DE9FE4F4FF4804018F00AFAA0B1354CD0 +:100CE00035496068D1F8132009786FF39F5201F0FD +:100CF0000401806842EA417101AA03F047F8606884 +:100D00008168012016F0A4FE2E482C4F2C4D44F291 +:100D1000020B00244FF0000A00F14009BAF1020F63 +:100D20003CD055F82A80D8F80000A0B3D8F80000CD +:100D3000806918F0DDF90646D8F800000023324635 +:100D400015F002FE16F00A0F1ED0D8F800008069D8 +:100D5000B9686BEA00000840B860D8F80000C069C4 +:100D6000396821EA000038601020D8F8001016F029 +:100D70006FFED8F80010484616F00AF9002044F03B +:100D80000204C8F8000006E02EB1D8F800000D49B2 +:100D900044F4804408650AF1010ABFE724B10A4817 +:100DA0002146283018F056FF06F0FCFEBDE8FE4F45 +:100DB000F7F756BBD01E0020850300210C1004401D +:100DC00014BC020030210020702000202DE9FC47D7 +:100DD0003A4D0446286810B194B1BDE8FC87122052 +:100DE00018F022FF00282860F7D04FF6FE7200218D +:100DF000531C1229F0D04618425206317380F8E78E +:100E000001AB4C200021022218F044F800284CD1FC +:100E1000BDF80400002848D0032846D8182018F050 +:100E200003FFDFF89C90044600264FF6FE784FF053 +:100E3000020A0027032F34D028680622831907EB03 +:100E400047000AEB400081B24C2018F023F828BB81 +:100E50002868815B414518BF002C1FD03044002218 +:100E6000182341880620009415F094FA2868D4E9E4 +:100E70000423304402F2E9324188226101EB41004F +:100E800049F8202009EB8000182243600620234601 +:100E900015F096FA2046182118F016F80636013794 +:100EA000C8E714B1204618F0BDFE064B71200021A2 +:100EB000082217F0EFFFBDE8FC8700BFE026002006 +:100EC00018830020AC260020F8B53948394D01219F +:100ED000394E0768E868C0680170002002F002011E +:100EE000F07003F0E040401817D096F90600012892 +:100EF00002DBB0790138B07196F90500012802DBF8 +:100F00007079013870712D48426803F0807082B1A9 +:100F1000D8B10020002190470CE01446D00323D420 +:100F2000A0032ED4600230D5002038710BF06CF98C +:100F30002BE050B196F90700012802DBF079013867 +:100F4000F0710120307117F069FF002038710BF04B +:100F50005BF97079F8B196F90500002823DCA868E0 +:100F6000D0F84C0580471EE01548007820B10520D8 +:100F700017F036FF13F082FD00203871F1F78CFE78 +:100F800003E00020387111F0DFF8A00648BF18F028 +:100F9000A7FE707938B900200021B070A868D0F899 +:100FA000582400209047E8680021C0680170F8BD0F +:100FB000748800200C0100201425002024B80200B1 +:100FC00090270020B0B58CB004464089ADF80000F1 +:100FD00060684178821C019206298DF8021003D0C6 +:100FE000042907D0012936D1817C13228DF8031002 +:100FF0001B2101E01A211222851801440391029558 +:1010000031D0284616F0F2FE01282CD117F0F8FD59 +:101010000146284616F049FB28BB264800780128DF +:1010200024D8684618F03EFC01281FD102980DF123 +:10103000160113F0DBFF012818D10021BDF81600BE +:1010400061721D496081097891B16168097805294B +:101050000ED101210DE00021029100F11201807EEC +:1010600003918DF81000684610F060FD0CB0B0BD23 +:10107000002100222173CDE906220892ADF8180064 +:10108000207A8DF81D108DF81C0001208DF81A00B3 +:1010900006A8FEF79BFA9DF82C000028E6D10998D7 +:1010A000227A6168406C18F073F806A811F026FAED +:1010B000DCE700BF18260020D02700202DE9F041F2 +:1010C0000E46054610463421144617F0FDFE082E44 +:1010D0004ED326702146288811F0FAFF8046688892 +:1010E00008216081A888A081A879A074E87961703E +:1010F000E074E07920B1102105F1080061706061B1 +:10110000207A28B101F1080029446070A16100E053 +:1011100008460021616284F82010617919B1295CC8 +:10112000013060706171617FF1B1421C6270295CB5 +:101130000230607084F82010AA5C914284F821206B +:1011400010D9194A4F00194E1278914288BF1827BA +:101150003A462918304618F01BF860786662384421 +:10116000607001E0002161772178C2B2914203D220 +:1011700000263046BDE8F081B8FA88F2091A55FA1F +:1011800080F05609A2792177A062002AF1D00E30B2 +:10119000A062A1F10E0020770548007B18F048F806 +:1011A000217F081A2077E4E7DBBC0200F0850020ED +:1011B000407B00202DE9F04105460026806A1C4650 +:1011C000174688461680007817F034FA40B16889CF +:1011D00012F0D0FC022811BF00266889388026460C +:1011E000A86A007801380A2846D8DFE800F0060C23 +:1011F0001116242C45383C4A5200284641463A46AE +:10120000F7F7C6FD41E028464146FDF761FD3DE0A8 +:1012100028463146FFF7DCFC37E0287F02282BD137 +:1012200026B920486989C08A814228D1304629469A +:1012300000F034FF29E0688912F09CFCE0B92846F0 +:10124000F4F758FF22E017486989C08A814213D118 +:10125000287F022810D128460CF06AFE16E02846A6 +:10126000FCF71AF812E00F486989C08A814203D15D +:1012700028460BF0BFF909E0D32005F04AFD00260F +:1012800004E0304629460FF021FF06463046BDE80F +:10129000F081054800780128F1D128460CF018FEAD +:1012A000F4E700BF407B0020BA2700202DE9F04181 +:1012B000056804464FF0FF30E86218F03FF98046B9 +:1012C00095F83000042809D13349497831B13349C0 +:1012D00003228A604A6822F003024A602E4F6B693B +:1012E0002F4E00217A68B34204D01AB979780029C8 +:1012F00018BF01210023042804D11AB17B78002BE8 +:1013000018BF012341EA0300012808BF14F0AEFD15 +:1013100095F8320030B1404618F0BCFB4FF0FF307A +:10132000BDE8F08195F83000042804D1381D294625 +:1013300015F039FD03E0381D294615F029FE01207E +:1013400085F83200404618F0A5FB0020FDF720F894 +:10135000246894F83000012812D0022813D0042801 +:10136000DCD10E4DD4E90901884211D2012018F0D8 +:101370003CFB28688007F9D00020FDF709F8F1E769 +:101380000020BDE8F081216A04F1340018F0F8FA79 +:10139000E06ABDE8F08100BF182300200880024009 +:1013A00080A9030070B586B03449002808705DD16B +:1013B000344C207830B93249097819B9082016F030 +:1013C00097FB207801284ED80020CDE90300CDE915 +:1013D000010017F025FE002845D02B4D05F13904FA +:1013E000204617F043FD18B92849204618F0C7FBDE +:1013F00005F11601532010F041FEA87B0DF11701F5 +:10140000C0F3C0008DF81700522010F037FE0820FE +:1014100085F8260003F026FA04F072FA1C480168E9 +:1014200009B9012101601B484FF4407100780CF0AC +:101430000FFE01AC204614F0F1F8204600210026F2 +:1014400015F0D8FE95F8410010B9002005F052FDC6 +:101450001148CDE90366CDE90166807B012802D001 +:10146000012014F00BFE012015F036FB0948022183 +:1014700000780CF0EDFD06B070BD00BFBB88002009 +:10148000C426002018260020407B00209E870020D4 +:101490000825002099880020CC2200202DE9F84F53 +:1014A0008A468DF8030062B13848514601234068EE +:1014B00002700DF1030048F231020DF0ADFF044659 +:1014C00060E00B9F162405201E4617FB0400C0B2E7 +:1014D00018F0AAFB002854D0814604220C980A99DF +:1014E00017FB04280024CB460BF8014F00F1190527 +:1014F0008BF801600BF104068BF803708BF8021077 +:10150000E0B2B84229D2A5F11701304618F037FBF6 +:1015100006F10800A5F10F0118F031FB15F8071CC2 +:10152000861D0134017015F8061C417015F8051C64 +:10153000817015F8042C41EA8201817015F8032CA2 +:1015400041EA0211817015F8021CC17015F8011CE6 +:10155000017129781A354171D2E70C4D5FFA88F391 +:101560000DF10300514648F23102C5F804B00DF008 +:1015700053FF0446484618F055FB054801306860A3 +:1015800000E010242046BDE8F88F00BF7C26002034 +:10159000DC7D00202DE9F04742F22C0940F2100AD0 +:1015A00042F20C0640F2B81715460C468046C4F2CB +:1015B0000909C4F2090AC4F20806C1F2000708F0DA +:1015C0004FFB44F20C00C4F2090000210160D9F87D +:1015D00000003868816927208847306B4FF6FF711B +:1015E000CFF6FE6108403063B06F20F48070B067C2 +:1015F0003868016B4FF4806088473868016B4FF49E +:10160000816088473868016B4FF4C060884742F2B8 +:101610002800C6F2080001210160C6F8804131604F +:10162000DAF80000800705D4681C08BF4FF0404579 +:10163000CAF80C50D9F80000F0698007FCD500BF4B +:10164000072010F03FFB0228FAD1B8F1000F16D1A5 +:1016500044F20004C4F20304386A816820468847D3 +:101660000428F9D0012804D1386A032142682046B1 +:101670009047D6F8180220F00300C6F81802386820 +:10168000806BBDE8F04700472DE9F04385B0064682 +:1016900000200D46049017F051FF334CDFF8C49042 +:1016A00080462168D9F80000CB6C04AA0521984730 +:1016B00001A817F0ABFE2D48019626F00106039510 +:1016C00020F00107BE420AD12B490878FE281BD022 +:1016D0002068826BD9F8000091F900100EE02448D0 +:1016E00020F0010086421BD123494878FE280BD008 +:1016F0002068826BD9F8000091F901109047812889 +:1017000002D01C4818F08DF92168D9F80000002299 +:10171000CB6A01A998470546B0F1FF3F07DC03E01B +:10172000144818F07EF9FE25124818F07AF9BE42E6 +:1017300001D1114806E00E4820F00100864202D196 +:101740000D4801300570012021680490D9F800008F +:10175000CB6C04AA05219847404618F09BF905B0C8 +:10176000BDE8F083D826002030880020B161020057 +:101770004D4B02000C010020142500202DE9FC47F0 +:1017800006680446707A00286BD0D4F80490D6F826 +:101790005801D0F80480D9F8347020460BF090FB43 +:1017A000706F20B306F14C05284618F04BFA316FE4 +:1017B000884221D2307902281ED0B06E002850D045 +:1017C00020460BF07DFB346F284618F03BFA201AB8 +:1017D000D6F868A0B46F7067284618F033FA002175 +:1017E000F1740AEB040108440190706F0CE0B06ED4 +:1017F00010B1306F0028D5D106F14C0001A914F0CA +:101800008EF901217067F17458B30021B173B0F5FE +:10181000806F84BF4FF48060706701990123014499 +:10182000013979601049B96043F6F07101EB00109D +:101830000840B9680843B860D9F83C10D9F80000EE +:1018400091FAA1F2B2FA82F203FA02F2D8F8003069 +:101850009A61D6F85821526812689162012117F0F6 +:10186000A5F8BDE8FC8700BF0180000C7CB53A4DAF +:101870000446A868D0F8B810097859B194F89820AF +:1018800004F190014AB1152217F0D8F958BF25226A +:101890009A5C09E00121217514E0252217F0CEF9A8 +:1018A00058BF25229A5C023284F86A20002284F80C +:1018B0006920042284F86B2004F1700248C948C2F0 +:1018C00009881180214611F82C2FB1F872300F2AA7 +:1018D00021F8163CB1F8743021F8113C0BD0D0F847 +:1018E0000463B4F8A8000023B0FA80F0420920464F +:1018F000B04700B17CBD214611F83C0FFF2801D153 +:10190000A06D30B1A868D0F8FC222046904700288E +:10191000F0D1A868B4F89A3094F89C1004F19002C1 +:10192000D0F87463002000902046B0470028E1D131 +:10193000A8682189D0F80021D289914205D9E520F3 +:101940006070A86800F51B7001E000F51E7001686A +:101950002046884700207CBD0C0100202DE9F0477F +:1019600088B004466FF00100A081002004F1040853 +:101970008DF8100004AD4146281D17F0D0FC284614 +:1019800009F072FE012809D1BDF81C00BDF8121043 +:10199000A0816088814222D004AD01E060880025EA +:1019A000EA46ADF8020000264FF6FE7950468DF863 +:1019B000006007F0CFFA012808BF56460746B5B1C8 +:1019C000A88901210125A081204610F0D1F8012F1E +:1019D00006D1ADF802903046022110F0C9F8012579 +:1019E000204611F0A3FA284608B0BDE8F087012F81 +:1019F00013D1BDF80C00A0810AF1040016F0F6F92D +:101A0000012817D1204609F047F905463046022142 +:101A1000ADF8029010F0ACF8E2E76088484504D1D8 +:101A2000404616F0E3F901280CD1204609F034F9BC +:101A30000546D5E7404616F0D9F90128CFD1204612 +:101A40000321CAE70025CBE72DE9F0438FB080469C +:101A5000374800240394CDE90144077814F05AFE76 +:101A60004FFA80F901ADBC4212D2E6B207200C2237 +:101A70002B4631460EF07AF940B9B9F1FF3F05DC4B +:101A8000072031460C222B4614F09AFC0134EAE779 +:101A90004FF0FF300C22CDE90200781E01AB85B279 +:101AA000072029460EF062F940B9B9F1FF3F05DC85 +:101AB00001AB072029460C2214F082FC04AD18214A +:101AC000284617F001FA822018212A4617F098FEBE +:101AD000B8F1010F08BF002804D104AA8220182100 +:101AE00017F094FE0AAD1121284617F0EDF93A20BF +:101AF00011212A4617F084FEB8F1010F08BF002813 +:101B000004D10AAA3A20112117F080FE0AAA3B202C +:101B1000112117F075FEB8F1010F08BF002804D19C +:101B20000AAA3B20112117F071FE0FB0BDE8F08327 +:101B3000D7BC0200B0B517F00FFF2C4C02210025D6 +:101B4000207040F60F70A17430492581C4E9075513 +:101B50002576A0850F202071012084F86C00E072AA +:101B600040F20510A08122480078E07121480078F9 +:101B7000607021480078A07020488078A0732048C9 +:101B8000007820826FF00100A0846083E0821D480D +:101B90000078E0741C480078207504F1390017F0D3 +:101BA000EEFF40F20F5004F16E030021022284F890 +:101BB000415084F86850A4F866001548007884F80D +:101BC0006A001448007884F869001348007884F8A3 +:101BD0006B00892017F05EF908B1A4F86E50002060 +:101BE00010F04EF8A4F87050B0BD00BF407B00204C +:101BF000B7270020CF270020C427002026870020F9 +:101C0000C3270020D1270020D2270020192600203A +:101C1000BC270020BD270020BF2700202DE9F04F62 +:101C200087B082462420994614460F4617F0FCFFE1 +:101C3000002800904DD0DDF844802421054617F09F +:101C400043F9DFF8B8B09BF80000012813D83846F4 +:101C500017F0C3FE50B1007940F00200032802BF24 +:101C60004FF4806020EA081048EA0008DDE91232EB +:101C7000C8F3802602E0DDE9123200262048ADF8E4 +:101C80001840109C0221808C2F8029722973688152 +:101C90000098ADF80A808DF80C404473C0F820A07D +:101CA00080F81F908DF81A30D2E90001CDE90401C7 +:101CB00068463146FEF7DCF8012807D19BF8001092 +:101CC00049B10020B6B1012906D013E0009817F001 +:101CD000A9FF10200EE066B1204616F0CBFD40B102 +:101CE00004460068008818F005F810B1204607F097 +:101CF000F5FE002007B0BDE8F08F00BF18260020D9 +:101D0000407B00202DE9F04F85B0894619461F46DB +:101D10001446054612F07AFD3249DDF84080097814 +:101D2000884207D2304900EB800001EB4000B0F858 +:101D300004B001E04FF6FE7B18F0100A4FF01000DF +:101D400008BF082018F02001019118BF08308DF855 +:101D5000110004A814F094FD002840D0064601208C +:101D60000094B07716F04CFF706202AC58462146E2 +:101D700013F034FE18B101203462707705E0BAF137 +:101D8000000F02D00E9CAB45F5D034694FEA192004 +:101D9000A071280A84F80590E570A77084F8018086 +:101DA000207102202070584611F0C4FF0099BAF14A +:101DB000000F0844E07101D1082005E00E9904F1FC +:101DC000080017F0DCFE1020019919B10F9920448A +:101DD00017F0D5FE3046A6F802B00CF07FFD05B036 +:101DE000BDE8F08FD9BC0200D07E002070B59EB057 +:101DF000314D0021742228780130287001AC212057 +:101E0000234617F047F82878742122468DF80400FD +:101E1000212017F0FBFC294E294C3078A178814213 +:101E200006D2002012F012F8012801D1042000E0AF +:101E30000D2015F05DFEA98C01204FF6FF72914236 +:101E400037D0E98A4FF6FE72914232D01D480078B1 +:101E5000022803D31C480078012808D101200DF185 +:101E600003018DF80300522010F008F904E04FF44C +:101E700000500121F9F750FD1448007818B130786E +:101E8000A17881420DD2012011F0E0FF012808D194 +:101E90000020297EE0700E4817F0FFFDA178013187 +:101EA00006E00120297EE070094817F0F9FD0021C5 +:101EB000A1701EB070BD00BF407B0020B92700207C +:101EC000AC22002018260020D5270020B8270020AB +:101ED0009687002070B596B004460079042805D195 +:101EE0003348007810B117F09BF810B1C22016B03B +:101EF00070BD3048016809AD284617F040FE2168E2 +:101F0000284615F064FF0028F0D020680DF102018A +:101F10000BAA07F04FFB9DF80210C2200029E6D063 +:101F20009DF83C100129E2D105AD4FF481700021EC +:101F3000102200262B4616F0ADFF032008212A466A +:101F40008DF803000DF1030001AB0DF005F9412000 +:101F5000CDE9106612968DF854608DF842004FF46A +:101F60008D70ADF8440010A8FDF730FB9DF85400CB +:101F70000028BBD11398456C0F2028702079687019 +:101F800016F03EFE09AC01460822204617F000F983 +:101F9000A81C214617F0F3FD05F10A0001A9102243 +:101FA00017F0F6F810A810F0A9FA9DF854009EE773 +:101FB00018260020DC870020F8B51446A0F198020E +:101FC000062A0AD80FF20401DFE802F00411111109 +:101FD0001A1D31003048807C2CE08B282DD08728BA +:101FE00044D0802803D12C48808C208023E0812895 +:101FF0003AD3D82838D82849084410F8810C19E079 +:1020000014F0B2F916E02148007801282CD82048B5 +:10201000204A4FF6FE730025017800208D4209D238 +:1020200032F8086B9E4218BF01300135F6E71A48B6 +:1020300090F8260020700020F8BD14480078012890 +:1020400012D81348134A00234FF6FE750026007875 +:10205000864213D21788AF4203D0DFB28F420FD02F +:10206000013301360832F3E7C920F8BD084612F003 +:1020700057FE18B1014620461C2204E0C120F8BDDD +:1020800011462046082217F083F8D4E718260020CE +:10209000DABC0200E04C0020407B00207FB5044603 +:1020A00000200D46ADF80C000290CDE90000886AD2 +:1020B0004078C10604D0D32004F02BFE002448E071 +:1020C000810644BF01218DF80C10010644BF012197 +:1020D0008DF80B10400605D4287AE8B105F11800F8 +:1020E000002107E001208DF80A00E879D8B105F158 +:1020F00014000121066836B168463146023017F0F7 +:102100003EFD9DF80A10A8890129ADF8000006D10E +:10211000B6FA86F14E090AE0A889ADF800006846D3 +:102120000EF0A6FA15E0A8890126ADF800001049C6 +:10213000097871B1012902D10E4A12784AB10229F7 +:1021400003D10D49498B884203D1688911F012FDF2 +:1021500010B1204604B070BD002EE0D116F050FD45 +:1021600068460649023015F0A0FA0028D7D1F0E7FA +:1021700018260020C9270020407B0020C8870020A7 +:1021800070B541F21C30C5F20000066840F2B01490 +:10219000C1F2000413F07EFC40F28440C4F26020DF +:1021A00000250560206C806C804740F28010C4F2EE +:1021B0002830006850B140F28051C4F22031B6F1AD +:1021C000FF30096818BF304602F09DF842F28C11CA +:1021D000C4F208010D6042F24801C4F203010A682A +:1021E00040F23913282063F31B42C4F209000A604D +:1021F000016801F44051B1F5805F09D101684FF6E3 +:10220000EF72CFF6FC42114001F50032026001602E +:102210000025C4F224350126EE612068016A1420ED +:10222000884742F20000C4F20900016841F4E0214D +:10223000016044F6B4702E60C5F20000006800F43E +:102240004000B0F5000F06D1206C416C43F2BD7028 +:10225000C0F2860088470C20C4F26820016800297B +:10226000FCD170BD2DE9F04387B00446084699467D +:1022700090460E4616F009FC304614F0A3F92E4F96 +:10228000386858B10320314608228DF8100002AD9D +:10229000284616F07DFF3968284688472748007889 +:1022A00001283AD80220ADF80A4003968DF81000B4 +:1022B0000020ADF80800304617F0E3FBB9F1000F3D +:1022C00027D128B9204631460DF082F9AA2820D11D +:1022D00016F0A6FEE8B905AAAB2000210CF0B0FD6F +:1022E0000DF107013046002207F064F91448007828 +:1022F000012808D19DF8070028B900208DF81100A9 +:1023000002A80AF0D6FC01208DF8110002A80AF0FC +:10231000D0FC3046414612F071FF2046002114F0F7 +:102320007BFD0848818C204613F055FC15F000FA1F +:1023300007B0BDE8F08300BFF82300201826002076 +:10234000B2270020407B002070B586B00446807A1A +:1023500058B9E07AC00608D43048C825007801286A +:1023600053D12D48007801284FD1616820880DF1A4 +:10237000160213F015FEA07A98B12B4E306A70B198 +:10238000208861686D460822ADF80000A81C16F090 +:10239000FFFE2089316AADF80A00284688470025EB +:1023A00036E0E07AC10602D4C0F380001FE01C488A +:1023B0001C490078097808431AD100206D46142181 +:1023C0008DF81500284616F07FFD60680DF11501A7 +:1023D0002A4607F0EFF89DF81500002818BF0120E5 +:1023E0009DF810100239B1FA81F14909084028B16D +:1023F000204609F09EFC054620B9BEE7E07A0007BA +:10240000BBD4AD25606814F0DDF8204604F062FE10 +:10241000284606B070BD00BFD72700209C8800204A +:10242000F4240020AE2700203C830020BCB50446E5 +:102430004089410622D432490978012927D83149F7 +:10244000897B89072ED523684021228B01EA9011D0 +:1024500018881B6A9D8800914FF6FE73294602F08A +:102460007DFBA84202D0218B884217D1206802222E +:1024700000230188284609F023FC13E02068008827 +:1024800011F078FB40B16FF0010001300CE002293F +:1024900008D117F077F801E0206800884FF6FE7148 +:1024A000884201D1CD250FE02168088080B211F06B +:1024B00061FBB0FA80F0226813494009D0811046D0 +:1024C00006F0F0FF054630B120682946407B0FF04A +:1024D000C9F990B90CE00A4800250078022807D114 +:1024E0000A48007820B920200121F9F715FA0025C3 +:1024F0001CB120460121FDF7BBFC2846BCBD00BF36 +:1025000018260020407B0020B94C0200D52700206F +:1025100070B50546C80713D1880758BF70BD334C46 +:102520001C200021A0471D200021A0471E200021C3 +:10253000A0472F4C1C200021A0471D20002136E081 +:102540002A4E1C2000211446B0471D200021B04710 +:102550001E200021B04728460AF05AF92188C50FED +:1025600040F60200814206D043F60700814204D0C3 +:10257000B1F5C15F14D1E07B01E094F8240040067E +:102580000ED01C20002115F0F1FC1D2005B33221D6 +:1025900015F0ECFC1E202F21BDE8704015F0E6BCC4 +:1025A0001C20134C55B12F21A0471D203221A047DC +:1025B0001E2000212246BDE8704010470021A047A0 +:1025C0001D200021A0471E200021A0471C2007E05D +:1025D000002115F0CBFC1E20002115F0C7FC1E20A9 +:1025E0000121BDE8704016F033BD00BF51900200DC +:1025F0006D7F02002DE9F0418EB004464A1E002096 +:1026000012F1030F0AD809AA0490029107922F4AE7 +:1026100006928DF814000222684600E003220C9016 +:102620008DF834202020EFF3118680F31188608A22 +:1026300030B1608A01386082012086F3118842E05F +:1026400000293DD02248012104F1140790F80880A8 +:102650000172806909AD45620B9011F0BDF8A06967 +:1026600009970A900560A5619DF83400022808D1F9 +:1026700018494A680C98016042601060486005F093 +:102680002BFD86F31188404611F0C4F82021EFF3AA +:10269000118081F311880C9939B10A684B681A606E +:1026A0004A6809684A6000210C910B9900224A622D +:1026B00080F311889DF83400002818BF012002E043 +:1026C00086F3118800200EB0BDE8F0815B4F020058 +:1026D0003822002008200020B0B504463048007899 +:1026E000A8B130488068006C0068007D78B144B1C2 +:1026F0001B2C06D0E92C0AD12B484088B0F5105F7E +:1027000005D12948C07B16F06BFB12F0B7F92748BA +:102710000021017026480170A4B922488068D0F8D1 +:10272000D41091F85310882908D022490978052936 +:1027300008D1006C0068C08A400703D417F046FA3D +:102740001D494860174DA868D0F8B8100A7872B1D2 +:10275000496C61B120468847E868C068007898B93C +:10276000A8680021D0F85824002090470CE0D0F849 +:10277000AC00007808B90EF0E5FA0CF0D1FEA868BC +:10278000D0F8701220468847A868006C006818B11D +:10279000007D352808BFB0BDBDE8B04016F03EBB97 +:1027A000902700200C010020A88500202126002071 +:1027B000B4880020B7880020542600202DE9F0437B +:1027C00087B0044600200D4631498DF807002F4898 +:1027D00009780078084301D1012452E0F4B1EDB149 +:1027E0000DF108080DF107012846424606F0E2FE09 +:1027F00081464FF6FF70814521D09DF8070078B1E2 +:102800009DF8180060B99DF81B001022234600F0C7 +:102810007F01052013F0D4FD002432E0022430E0D3 +:102820001C4800260788B1B2B94208D20520102200 +:1028300023460DF09BFA092803D00136F3E7B224B2 +:102840001FE008F108002946082216F0A1FC46F016 +:10285000800000244946142243468DF81B000420C2 +:1028600003948DF81840029413F0AAFD0A4909EB6D +:10287000490041F8204001EB80000121C0E90144FA +:102880004172204607B0BDE8F08300BFAC270020AE +:1028900018260020C4BC0200804300202DE9F04728 +:1028A00088B006461398DDF840A01D46914688463C +:1028B00050B1149C4FF6F777601E80B2B84204D333 +:1028C00017F04AF80446F7E70024C120BAF10F0FC9 +:1028D0004DD111990F294AD1264F129887F82F0010 +:1028E00040F60F7087F82E50C7F82890B8854FF63D +:1028F000FF7086420AD120494FF6F77008300E88E3 +:1029000080B2864202D117F027F80646B8F1000FD0 +:10291000BE8409D0404616F0A9FA012804D107F177 +:102920003900414617F02BF907F13905284616F012 +:102930009DFA18B9E220294613F074FB0020FC82AE +:10294000182187F83800788340F60F70B885052085 +:1029500087F8260001AC201D16F0B6FAB86A01907F +:1029600097F82E008DF8090020460CF0F9F808B011 +:10297000BDE8F087407B00208027002070B520391B +:10298000062918D8DFE801F01A23042D3840480042 +:10299000147800222321FF2CF1D0D0E9015695F8BC +:1029A000FB0010F0FFFA726B2B49204685F8FB40C4 +:1029B00005F0B8FC49E06FF001044AE0406890F887 +:1029C000F910012943D1012180F8FC103DE0456850 +:1029D0000021002495F8FB0012F0B0FB85F8FC40C4 +:1029E00037E0446894F8FB00FF282ED010F0DAFAA4 +:1029F000FF2084F8FB0028E04068D0F8C01031BB0D +:102A0000012180F8FE1020E04068D0F8C010F1B934 +:102A1000002480F8FE401CE04168D1F8C020B2B12B +:102A200091F8FE209AB180680268D0E90430546AB7 +:102A3000184344F003045462D1F8CC104968096883 +:102A40008862506840F002005060002401E04FF0BE +:102A5000FF34204670BD00BF026000202DE9F04F1A +:102A600085B080460FF0A4FA002864D08346471C46 +:102A7000002400254FF000099BF8000084421FD27B +:102A8000384616F0FEFFC0B101790139012914D88A +:102A900090F8200088B10C2017F0C6F868B13946CC +:102AA000064617F06CF80020B06015B1CAF808604F +:102AB00000E0354609F10109B24608370134DBE789 +:102AC0005FEA096034D002205FFA89F98DF81000BE +:102AD000B8F80200ADF808004FEAC90017F0A4F8F2 +:102AE000A0B107460024A5B1E0B2294607EBC0001B +:102AF00017F045F8AE68284617F094F801343546CB +:102B0000F1E7AC68284617F08DF82546002DF8D17E +:102B10000EE0002048F21F014A463B46CDE9001076 +:102B200008F1110002A901F0FBF9384617F07AF814 +:102B3000584617F077F805B0BDE8F08F2DE9FF4152 +:102B400005464FF6FE70854222D00C4601B3DFF8F1 +:102B5000C480D8F80C7007B3B91C2046082215F0C1 +:102B600067FA60B198F830000026B87211E0B11C25 +:102B70002046082215F05CFA0028374645D1FE6849 +:102B8000002EF4D1102017F04FF8F860A8B93AE001 +:102B90000226304604B0BDE8F081102017F044F85A +:102BA000C8F80C0078B31C484FF400614FF47A72F7 +:102BB000007816F09CFFD8F80C0098F8301000262A +:102BC0000580851C0822C66081722846214616F0C1 +:102BD000DFFAD8F808000028DBD001AC294608222B +:102BE000601C16F0D5FA04F10A01284612F00DFF18 +:102BF0000948092100220C238DF804600094007814 +:102C000010F039F9C5E70126C3E798F83000B07233 +:102C10000026BEE7AC2200209F8800202DE9F84F57 +:102C200016F0D0FD2F4D2C4644F8100F16F0C4FDC1 +:102C30000027206818B100F118040137F9E72C6962 +:102C4000002C46D04FF6FE70DFF89CA0DFF8A0B055 +:102C5000DFF898900026FDB201301FFA80F8F0B23C +:102C6000A84235D2504616F001F9012806D104F1E8 +:102C70000C01504614F019FD38B922E0B9F80000F3 +:102C8000404502D0218881421BD12089BBF81A100F +:102C9000884203D14FF6FE71884208D1154800786A +:102CA000022801D2E07801E001D1207948B19BF8F7 +:102CB00012006179814208D10F48A17900788142E0 +:102CC00003D0204611F0A2F9013FA4690136C6E7FE +:102CD000044D6A6922B12869F9B2BDE8F84F10477E +:102CE000BDE8F88FAC2200209687002080270020C6 +:102CF000407B002018260020D8270020B0B52F4C9C +:102D0000608810B12E49098814E02E494FF4707282 +:102D10008968D1F8F410C98F02FA01F12A4A01F545 +:102D20007071127851434FF47A72B1FBF2F1244A78 +:102D3000118089B288421AD225492448096800685E +:102D4000096C88472278C1B2914288BF20706088A0 +:102D50000130608016F038FF4FF47A711E4B00226C +:102D6000B1FBF0F01B49BDE8B04007F039B894F969 +:102D7000000013F07BFC134901258A68D2F8F42087 +:102D8000936992F8442098548868D0F8F40090F839 +:102D9000442000EBD20002F00703427905FA03F366 +:102DA0009A43427100202070608088680421D0F826 +:102DB00094000078BDE8B0400BF04AB94C240020E4 +:102DC000DA6B00200C010020B0880020D8260020FB +:102DD00030880020FD2C010058880020F0B500222A +:102DE000C1F802204A73838D027F4B83C3890A7521 +:102DF0004B81836A1C4614F8015B15F003060D70C5 +:102E000003D0032E43D0022E28D105F00C060C2E41 +:102E100005D015F0100702D15C788C709C1C082E30 +:102E200002D101260E7306E000270C2E0F7302D18B +:102E300034F8020B08E0467906F00306012E04D1AF +:102E400045F00C0540890D708880E80606D420887E +:102E5000C8806088088120790534C870204610F841 +:102E6000016B4E756EB2B6F1FF3F0BDD00244C7066 +:102E70000861181A131840424873D8B20B75824281 +:102E800005D3F0BD607810F0FC0F487003D000202F +:102E900008754873F0BD10F003000CD00328F6D07D +:102EA000A078C87505F00300022811BFE01CE07887 +:102EB0000876201DDCE7A01CDAE77047F8B5164657 +:102EC0000F46054616F03AFB0446092F3AD8DFE8CC +:102ED00007F00508111417313B1B4B2C3068286094 +:102EE0004AE001206876D5E9040160306031C5E927 +:102EF000040141E0306868833EE03068A8853BE02B +:102F000030682249886037E01F4820490025806BDF +:102F1000097E91BB88BB1E483168283016F084FAC0 +:102F200031681C4816F080FA26E02020314614F063 +:102F30008FFD21E0306801281BD018B9802015F0E2 +:102F4000AFF819E0032518E00F4810490025806B01 +:102F5000097E91B988B93168192015F015F83168E2 +:102F60001A2015F011F807E03078064981F8600062 +:102F700002E0802011F016FC8325204616F08AFD21 +:102F80002846F8BDB87B002030210020D01E00204C +:102F900070200020288000202DE9F84F93464268D9 +:102FA0000546936803EA0100884255D1D5F808A088 +:102FB000DAF804408C429CBF6FF00300BDE8F88F44 +:102FC0000BEB01066FF00500A64247D803EA0B039E +:102FD0005B4543D1BAF82000DFF89490E846C9F881 +:102FE00008005068C9F80400DAF800004618BBF180 +:102FF000000F39D028460BF03DFE88BB284612F062 +:103000006DFB68BBBBF5803F05D3B0B218B94FF478 +:103010008034D82002E0DAF8084020208DF8000043 +:10302000300AB9F808108DF803608DF80200300CF2 +:103030008DF80100284615F05EFF404604210CF093 +:10304000C3FDB9F808100746284615F05DFF3FB9E3 +:10305000ABEB040B2644CAE76FF00400BDE8F88F21 +:103060004FF0FF30BDE8F88F0020BDE8F88F00BFBB +:103070000C240020F8B50446807A022851D1A07BA8 +:10308000E0B12948006800284BD026480078012884 +:1030900047D126480078C00743D0042013F0E4FF4E +:1030A00000283ED001464FF4B27008806088488006 +:1030B0001F480078BDE8F8400BF0F6BF20480168D3 +:1030C00079B11E4F386860B11B4E306848B1194D58 +:1030D000286830B113480078012802D160888847F9 +:1030E00030B1608801210122BDE8F84000F02EB81F +:1030F0001448007830B1144951F82000C0EB00109A +:10310000810001E01048016860883A689047012812 +:1031100007D160883168884760882968BDE8F84031 +:103120000847F8BDBA27002084230020CC270020C0 +:1031300098880020982300209C23002094230020BE +:1031400088230020C727002060B702002DE9F84F30 +:1031500014460E46824614F07FF9D6B3C8BB2B49FD +:103160002948012600940978043051B10278FF2AD9 +:1031700003D030F8042C524504D0243001397600B5 +:10318000F3E700262248254FDFF894B06FEA0609DE +:103190000025047800205FFA85F8A04518D217F8BA +:1031A000081099B15BF8282032420FD0084615F07C +:1031B00061FB50B1417B052907D15BF828102546FA +:1031C00001EA09014BF8281000E000200135E2E790 +:1031D000009C70B1417B05290BD10168A1F800A0CA +:1031E000012141730B4820210078BDE8F84F0AF017 +:1031F0002FBF34B10848818C5046BDE8F84F0EF01F +:103200007DBABDE8F88F00BFB0540020E6BC0200D4 +:10321000D2BC020098880020407B0020408400201F +:10322000C87A0020F0B5314A046A516B137D0C61F5 +:10323000446A01F1200C032B0B704C61846A8C6191 +:10324000C46ACC6190E8F000ACE8F00000F1400402 +:1032500000F110074C64F0CF01F1300CACE8F00045 +:10326000046B0C64446B8C64846BC06BCC64086529 +:103270000BD8DFE803F0020D1016156DC4B2106C08 +:10328000936C55F824404C600FE0002000230CE0C4 +:103290001748406D06E0174880694860D0E90A3059 +:1032A00003E000204860106C936C926BC1E902034C +:1032B00032B12BB110F8014B013B02F8014BF8E79A +:1032C0000D4802684A6590F824208A6590F8252008 +:1032D000CA65C28C0A66826A4A66C26A8A66026BDC +:1032E000CA66426B0A67806B4867F0BD381F0020D2 +:1032F000A01F00203822002004ED00E07CB5002053 +:103300008DF8070016F0D8FC29494FF0FF32294DFF +:10331000294C097802FA01F188432880A068D0F886 +:10332000B800017841B3826B32B30DF1070142F26C +:103330001A009047214E3078B8B17078A8B99DF83E +:10334000070090B1A068D0F8B800C06D68B18047A0 +:1033500058B1E2681A495268097812780832514324 +:10336000B0FBF1F0298808442880288871789DF8FE +:10337000072011FB020028801248007810B116F0D7 +:10338000A1FC01E016F09CFCA068006C006840B154 +:103390000D48007810B90D48007818B10C4802218A +:1033A00001707CBD0A488321017010F06FFA7CBD6A +:1033B000B5880020AE8700200C01002021260020C7 +:1033C000B0880020B7880020AC880020AF8800209B +:1033D000B4880020F8B5304D212074212A4616F01B +:1033E0000FFA80B100240FF0C9F82D4800780128A9 +:1033F00098BFFAF70BFE2B48006800B180470CF02D +:1034000065FB2046F8BD2120002174222B460024B4 +:1034100015F040FD0028E6D1E88A4FF6FE7188429B +:10342000E1D095F82600082801D0042831D10DF10B +:1034300003061A4F0124422031468DF80340B84755 +:1034400005F12F014320B84705F12C014720B8476B +:1034500005F11C014A20B84705F11A014B20B84775 +:1034600005F124015020B84705F116015320B84753 +:1034700005F12D015420B84705F11801E120B847A6 +:10348000A87B3146C0F3C0008DF803005220B84736 +:10349000A9E7FEF74FFBA5E7407B00207D20020057 +:1034A0001826002004240020F0B58BB00546022029 +:1034B0008DF829000AA813F0E3F9002857D0044634 +:1034C000006946F2040101800120A077A07615F082 +:1034D00097FB284865806062E07E20B92648017825 +:1034E000E17601310170207E234F012805D1F87A61 +:1034F00018B9207808B9002020760DF12701204660 +:10350000F8F7E2FC80B30546242016F08DFB02900C +:1035100038B32421064615F0D7FC0DF106015020E2 +:1035200012F080FDF88ABDF806109DF82720ADF84E +:1035300020006088718130800220307330720298E0 +:103540000562617DC2770122C28141738DF814103A +:10355000E08AADF8120002A816F03AF9029816F0C7 +:1035600061FB284616F05EFB204616F05BFB0BB0B5 +:10357000F0BD00BFC8870020407B0020F0B589B0B7 +:10358000304CADF82210154607460E9AC22094F82A +:103590002610ADF82020042952D0082950D04FF62B +:1035A000FE70824201D1C3204AE001A81C211E46C0 +:1035B00015F08AFC03200DF1220184F8260050202A +:1035C0000EF05CFD08A94B200EF058FDBDF822005E +:1035D00039462576A673A084BDF82000608304F1E7 +:1035E000390016F0CCFA06F04E0080308DF81E003F +:1035F00015480078012803D80F98013084F8380066 +:1036000002208DF80F500F2521468DF81A00BDF8C5 +:10361000200001F82D5FADF81200BDF82200ADF8D2 +:103620001C0000208DF80C0054200EF027FD04F83B +:103630002C5F472021460EF021FD01A803F09AFDE2 +:1036400009B0F0BD407B0020182600202DE9FC4782 +:103650000B9C88468DF80700042015211E4617464E +:1036600014FB0100012151FA80F016F0DDFA002868 +:103670004BD081460C990A980025CA460AF8017F6A +:1036800004278AF802008AF801600AF1040001F1B7 +:103690000C068AF80340E9B2A14223D2A6F10C013C +:1036A00016F06DFA16F8041C017016F8021C417031 +:1036B00016F8011C8170317AC170317A032908D162 +:1036C0000430314616F05BFAB17A153700F8011B69 +:1036D00005E031780E370171717841710630183686 +:1036E0000135D8E70B4DFBB20DF10700414648F21A +:1036F0003302C5F804A00BF08FFE0446484616F0CE +:1037000091FA05480130686000E010242046BDE8C9 +:10371000FC8700BF7C260020DC7D002070B5F8B15E +:10372000012858D1012015F0B1FF012853D02D4CAC +:1037300094F8380100284ED12848294E0569306890 +:1037400010F4402F30D17DB314F032F9502016F030 +:103750004CF90120A84704F1940016F03FFA25E047 +:1037600016F064FA1E48006810F4402F0AD11B4876 +:1037700004693CB11B48943016F086F914F008F93E +:103780000020A047174C94F8380120B31648016870 +:1037900021F08001016080218160032010F0E8FFAA +:1037A000002084F8380116E016F044FA012084F86D +:1037B0003801306810F4402F00D14DB9207A8006CE +:1037C00006D4094880218160016841F080010160D0 +:1037D000032011F0EBFD002070BD00BF90BA020085 +:1037E000B44F0050D81B002090220840F0B585B09F +:1037F00004464078DB3818280DD8012101FA00F082 +:103800002C49084207D02C488068D0F80412204682 +:10381000884705B0F0BD284EB068D0F8FC112046AE +:10382000884758B9607C40B1271D97F8300020B90F +:10383000B068D0F8B810097811B100206070E2E7E4 +:10384000D0F8342207F10E01092090470028F4D067 +:103850000546B068F91DD0F83024E7209047B068DD +:1038600004F10801D0F8302450209047B068B91D09 +:10387000D0F83024E1209047022023894FF6FF72D0 +:103880008DF810004FF0FF30ADF80800B068D0F8A8 +:10389000C061A07A009002A92846B047A0F1DB01E0 +:1038A0001829B6D8012202FA01F1024A1142C5D103 +:1038B000AFE700BF112000010C0100202DE9FC47FB +:1038C0000446E820002C59D08A46002956D060686A +:1038D000DFF8B49000260DF10408411E61603F211D +:1038E00000F8011CA16D6068B1FA81F1421E49091E +:1038F0006260C90100F8011C0220A4F8540020896C +:1039000002302081022E36D01AF836002A2802D042 +:10391000FF282ED12FE00AEBC605686848B3D9F816 +:103920000810D1F8B8108969884707466068C01B3D +:10393000606069684A0707D4D9F808200023D2F8E4 +:10394000B820D56922460AE0D9E902239B68D2F85B +:10395000B8201B78D56922468DF804304346A84725 +:1039600070B1208938442081B4F854003844A4F858 +:1039700054000136C6E7606820650020BDE8FC877A +:10398000EB20BDE8FC8700BF0C010020F8B52B48F8 +:103990000068C06B80472A492C4B09681B68411A94 +:1039A000284800788200B1FBF2F1274A12688B4266 +:1039B00001D9934202D38A42134623D9591A4FF0B0 +:1039C0000003A1FB001263F1000303FB0020204A67 +:1039D0001268538B12691A4464328D1A60F1000622 +:1039E000681E76F100000DDB16F0EEF8074628465B +:1039F000314600233A4615F06BFA0446E81B76F18F +:103A0000000001D2012015E015F0A1FF114E05467E +:103A1000306816F0DFF810B1306816F035F8284637 +:103A200016F071F83068214616F0D6F8306816F0B6 +:103A3000D5F8002008490870F8BD00BF3088002084 +:103A40002C880020B0880020388800203C88002086 +:103A5000D826002028270020B2880020B0B586B0E4 +:103A60000446008810F086F810B915F0D9FA08B1AC +:103A700006B0B0BDA178207A39B30428F8D129481E +:103A80000DF10301006801AA05F094FD01469DF8BF +:103A900003000028ECD09DF814000128E8D19DF91E +:103AA00017200020CDE90100002A03D401208DF861 +:103AB0001500FF208DF8140001AB0420142212F031 +:103AC0007FFC022015F042FED2E70428D0D1154831 +:103AD0000DF10301006801AD2A4605F06BFD0446B7 +:103AE0009DF803000028C3D09DF814000128BFD121 +:103AF00002208DF814009DF91700B0F1FF3F03DCA0 +:103B000005F113000FF072FF01AB042021461422CF +:103B100012F056FC002015F02BFE01200121F0F7D9 +:103B200039FEA5E7DC870020F8B515460E460446A9 +:103B300010F020F808B10020F8BD204600210DF05B +:103B40002DFC294606F08CF9C8B1074640790328B8 +:103B500007D00128EFD1788807210FF0A7FD0028B2 +:103B6000E9D1B87910F0180F1AD0788821460022D0 +:103B70004FF6FE73009030460CF04BF934E02046CF +:103B800014F0AAFA15F029FF0028D4D04179CA0709 +:103B9000D1D08A0706D441F002010127417109E022 +:103BA000022707E0304621460122012709F082FD65 +:103BB0000028C0D0304600210DF0F0FB0B49C98A27 +:103BC000884206D10A48294602782046FAF7A0FD25 +:103BD0000AE0304621463A4609F06CFD0028AAD199 +:103BE0002046294613F018F90120F8BD407B00203B +:103BF000CEBC020070B5314B04255C6859B952B196 +:103C0000D379157B2B440C2505EB4305EBB2502BE8 +:103C100084BF102070BD2170EBB28169052B09783B +:103C2000617081694978A17023D3291FE1701178EF +:103C3000217191786171D178A1711179E171517916 +:103C40002172917901F00F016172D179A172D57958 +:103C500095B10021A9420FD2956815F81150E5726F +:103C6000956805EB410501316D7825730234D579EE +:103C7000F0E70021E17016E004F10B01147B0C70F9 +:103C8000157B85B10024AC420DD2156901EB4406C9 +:103C900015F814507570156905EB440501346D78FD +:103CA000B570157BEFE700F11102811C104648F258 +:103CB0000402BDE870400BF0AFBB00BF7C260020C3 +:103CC0002DE9F8432020EFF3118980F311882C4867 +:103CD0000068006B80472B4E4FF000082A4F0122EE +:103CE00086F85D8086F85C20D7E9104522462B4691 +:103CF00015F0EEF8A0FB042300FB053301FB0431B3 +:103D0000746DC7E91221B168B268611A821A9142D2 +:103D100005D986F85C8089F31188BDE8F883051B16 +:103D200089F311880020854206D304442D1A01200E +:103D300021460AF09DFBF6E72021EFF3118781F37E +:103D4000118896F85D1019B1002021460AF090FB09 +:103D5000411C05D0B16D401B884288BF084600E079 +:103D6000B06D011914F0B6FD002086F85C0001204A +:103D700086F85E00B46087F31188BDE8F88300BF61 +:103D80008C01001008200020207C0020F0B585B0B8 +:103D90000D4600211446CDE90311CDE9011101A919 +:103DA000009104A903AA02ABFBF728FD029F394644 +:103DB000002F18BF0121019E0140002E324618BF7E +:103DC00001221140002D10D411B3049840F22B2190 +:103DD00005806FF39F5538462A4613F0F9F903988A +:103DE000314609F005F8676010E0C9B104984FF05A +:103DF000FF316FF39F552A46018030462B2113F087 +:103E0000E7F90398314609F0BFFB666015201EE014 +:103E1000C8B104984FF6FF720188914214D110E0A6 +:103E200078B16FF39F5503982B212A4613F0D0F9F0 +:103E3000FF2806D004984FF0FF3101801420656000 +:103E400005E0032005E004980580658010202080AF +:103E5000832005B0F0BD7047B0B588B0C189044675 +:103E6000A1F1210002281ED3A1F50040022826D38B +:103E700048F22100081A022832D227480078002888 +:103E800047D126480068002843D048F2210202208A +:103E9000914208BF0320A169627C097808B0BDE89F +:103EA000B040F6F7ADB9207B98BB6D462046294659 +:103EB0000FF0E8FF20462946F9F70CFD29E02046DF +:103EC0000AF056F928B30446007818B96088211D15 +:103ED00014F064F9204608B0BDE8B04015F0A2BE69 +:103EE000202916D10C48007898B96D4620462946FD +:103EF00007F00AFB2846F7F793F89DF8120010B177 +:103F0000059815F08FFE9DF8180010B1079815F070 +:103F100089FE08B0B0BD00BF182600203827002059 +:103F20002DE9FE4F89462E4C097ADDF830A0174660 +:103F30001D464FF0000866680F2904BF4FF6FC715C +:103F4000A9F8001048F21F018A45029011BF4FF0F6 +:103F5000010B002006F8010B4FF0020B0BF1500192 +:103F60003046019100F8017BB8F1090F14D861784F +:103F700005EBC10115F003FE617808F101080BF1B2 +:103F8000080B01316170C9B2B942EDD1002086F849 +:103F900000806070029C19E00A2030706078B8429E +:103FA00012D2BAF11F0F08BF13F05AF948F21F00DE +:103FB0008245DDE901B409D10A484FF480410A2263 +:103FC000007815F097FD01E0DDE901B45FFA8BF3AD +:103FD00020464946524603B0BDE8F04F0BF01CBAEC +:103FE0007C260020998800202DE9FE4F9946154631 +:103FF0000F46044615F0E8FD4FF47A71B1FBF0F07E +:10400000454315F0A4FC80462046394613F0D0FD08 +:10401000AB4688B10646006815F036FD3068594653 +:1040200015F0DAFD306815F0D9FD0824404615F08A +:104030006AFD2046BDE8FE8F142015F0F5FD00282E +:10404000F3D0EA460646504615F031FC01205946A9 +:10405000524602968DF800001348B9F1000F08BFD0 +:104060004D4601950EF080FF306070B10F4A00217F +:1040700086F80C90B76034713161116849B10A69F2 +:104080000AB11146FBE70E6105E0304615F0CAFDA6 +:10409000CBE716603068594615F09EFD306815F084 +:1040A0009DFD0024C2E700BF91E501006C260020C1 +:1040B0002DE9FF41044690F91900B0F1FF3F01DD01 +:1040C000BDE8FF81207D40F002000328F8D1DFF831 +:1040D000A480D8F80800D0F89810098911F00A0FC8 +:1040E000EED061684A78C2F38102032A8DF80C2071 +:1040F00008D0022A0CD1B1F80520ADF80420B1F89F +:10410000032005E0053101A815F039FDD8F80800B5 +:10411000C16BA4F10C0795B201AE0868C0B190F96B +:104120001910B1F1FF3F3946F7DC017D41F0020182 +:1041300003293946F1D14268D8F808002946D0F859 +:1041400068333046984700283946E6D0002CB7D16E +:1041500015F000FA30B101A82946002210F0E4FE63 +:10416000BDE8FF81D8F80C002946826F01A890476E +:10417000BDE8FF810C01002010B52E488168D1F800 +:10418000B020D1F8881311608168D1F8B020D1F83F +:104190009C1351608168D1F8B020D1F8A0139160D0 +:1041A0008268D2F8B010D2F88032CB60D2F8B0106A +:1041B000D2F8A4330B61D2F8B010D2F87C324B6144 +:1041C000D2F8B010D2F884328B610021D2F8B0302E +:1041D000D961D2F8B030D2F88C431C62164CD2F8B8 +:1041E000B0305962D2F8B0309C62144CD2F8B03082 +:1041F000DC62D2F8B430D2F848241A608268D2F86F +:10420000B430D2F8A8235A608268D2F8B430D2F819 +:10421000AC239A608068D0F8B420D0F8B433D3606F +:10422000D0F8B420D0F8B0331361D0F8AC000170EE +:1042300010BD00BF0C010020619B0200C99C020060 +:10424000F8B5064600780C4615F032F808B1B825E6 +:1042500057E00025002C54D03078257320701420AE +:1042600015F0E2FC0028A0604AD031780170B6F861 +:1042700001104180B6F8031081808179727901F0D4 +:10428000F00102F00F0211448171F179A068083643 +:10429000C17171B1480015F0C7FC0146A06881608A +:1042A00051B1C2792AB136F8023B013A21F8023BFA +:1042B000F8E70027002501E0102501273178017378 +:1042C00079B1480015F0B0FC0146A068016149B120 +:1042D000027B731C2AB133F8026B013A21F8026B9E +:1042E000F8E777B1816819B1084615F09BFCA06822 +:1042F000017B19B1006915F095FCA06815F092FCDE +:1043000010252846F8BDF0B581B044F6AC71C5F271 +:1043100000014A6846F2092605469007C4F20806DD +:1043200005D40868F02242EA104086F84D004AF2AF +:104330000440C4F20C004FF0012202604AF2000077 +:1043400040F2F017C4F20C00C1F2000700888C683C +:10435000386801682046884704F04070B0F1807FDB +:1043600003D1307840F0020030703868214642684E +:104370002846904706F080FD41F20C40C5F200004F +:1043800000684BF20E02C0F30531C4F20C0211704A +:10439000C1054FF0130158BF232140237354382126 +:1043A00001EA901000F56050A2F85C00386881685E +:1043B0002046884702200CF0D1FE40F29440C4F21F +:1043C00060200121016001B0F0BD70472DE9FE4F72 +:1043D000DDF834808DF80B0005209B4616460D460F +:1043E00008EB480400EB8400C0B215F01DFC002867 +:1043F00046D08146042001950E9D002700EB8400E5 +:10440000CA464FF6FE740AF8016F00900C988AF8BD +:1044100001B00AF104064FF0FF0B8AF803808AF816 +:104420000200F8B2404517D205F10C01304615F0F4 +:10443000A6FBA8783072A8797072697986F80AB0FC +:1044400040EA011070722889001B18BF0120F07229 +:104450000C360137AD69E4E700980B4D019948F23D +:104460003002C3B20DF10B00C5F804A00AF0D4FF6E +:104470000446484615F0D6FB04480130686000E069 +:1044800010242046BDE8FE8F7C260020DC7D002025 +:104490002DE9F04F8FB082460E46087849789B464A +:1044A0001446F378B27801EB0009042B38BF91442D +:1044B000F76838BF00225FFA82F815F048FA2349FE +:1044C00000250190C96811B1F078884700E000200C +:1044D00000900BA83946102215F02AF80746B0FACA +:1044E00080F0F1784009032988BF01255BFA89F142 +:1044F000284041445FFA89F5BAF1000F0FD0F0B1BE +:104500000DF108090F46484615F0C2F908950BA8A9 +:1045100011F0EFFF0E48006815F0A7FA0EE070B139 +:104520000DF108090F46484615F0B2F908950BA899 +:1045300011F0DFFF0648006815F09AFA0746019867 +:1045400015F0E1FAF8B20FB0BDE8F08F04250020B5 +:10455000F4870020B0B52A498968D1F8D420527B6D +:104560000F2A1FD0D1F8AC301B78DBB1D1F8EC109A +:104570000024274D51F82210224A127851434FF45B +:104580007A72B1FBF2F32049204A0968C91A38BF90 +:1045900021461268D21A38BF22462D68EB1A38BF5E +:1045A000234605E01849194A194B096812681B6827 +:1045B0004FF47A74634383420DD96243824211D926 +:1045C0004FF47A725143134A8142127811D9012073 +:1045D000AAB1002111E00F480178002003290ED074 +:1045E00003210AE00B4801780120022907D00221AB +:1045F00003E001210120012A01D0064A1170B0BD5B +:104600000C010020B0880020108800200C880020B9 +:1046100018880020A08800202DE9F041DFF8B8803C +:10462000D8F80810D1F8E8000068002852D0D1F876 +:10463000E03042681B689A4208DDD1F84C0580479B +:10464000D8F80800D0F8E800006858B144680FF0C6 +:1046500085FD844206D9D8F80800D0F8D404BDE816 +:10466000F0410047D8F80800D0F8E8100C688CB387 +:104670006668B6F1FF3F08DCD0F84C058047D8F8F3 +:104680000800D0F8E80004686668A768257B0FF08A +:1046900065FDD8F80810864206D8D1F800152046E6 +:1046A00088472846B847DDE7D1F8E800006848B1F8 +:1046B000D1F8E01040680968884203DABDE8F041AB +:1046C0000EF07CBF13F0D4FAD8F808000021D0F81F +:1046D000E8000160BDE8F0810C01002010B52E4A11 +:1046E0001278022A49D12B4A1278002A45D1C207F2 +:1046F00006D02A4A136A1160934204BF0023136252 +:10470000020708D5254A134643F8041FDC699C427A +:1047100004BF00231362C20608D5204A134643F89B +:10472000081F9C699C4204BF00231362820608D5BF +:104730001A4A134643F80C1F5C699C4204BF0023CD +:104740001362820708D5154A134643F8181F9C6860 +:104750009C4204BF00231362420708D50F4A134648 +:1047600043F81C1F5C689C4204BF00231362C20410 +:1047700003D50A4A4FF47A735361400408D50748B9 +:10478000024642F8101F1169914204BF00210162E4 +:1047900010BD00BFD527002018260020F082002081 +:1047A000F0B591B004460078A678676828B1B85D86 +:1047B000617840EA0102BA5503E020460CF018FC8B +:1047C000BA5DA16904F10800D2B20DF1370313F00C +:1047D00058FB6078A178E278237F8DF82700608A03 +:1047E0008DF82410A18A8DF825308DF8262060B927 +:1047F00040F20112914208D194F8281004F11E00F1 +:104800000DF1030208F0ECFF03E00DF1030205F0E7 +:104810009FF8FF208DF823000DF103000C90207C01 +:10482000022803D003280FD1022000E000200DF160 +:1048300013058DF823000DF123000DF1030208216B +:104840002B460AF089FC0C956368207809A90DF1C4 +:104850003702FFF71DFEB95D01F0F801B95511B03F +:10486000F0BD704770B586B0274C2848217801AA62 +:104870000BF028FA002004218DF80A008DF80800BA +:1048800000200FF0EBF822490D78A8421CD211F05D +:104890007FFFC8B91F48068836B1032004210FF0F6 +:1048A000DDF8A91B814202DD01208DF808001A48BD +:1048B000068836B1012002210FF0D0F8A91B8142F1 +:1048C00002DD01208DF80A002278104C01A8214653 +:1048D0000AF02DFF452021460DF0D0FB0F4810496E +:1048E0009DF80A200078097808409DF808101143C7 +:1048F00018BF012108408DF817000DF11701412064 +:104900000DF0BCFB06B070BDA92700200887002071 +:10491000E6BC0200C0BC0200C2BC0200F4240020BD +:10492000872700202DE9FE4329482C4E4FF0000830 +:104930000DF1040900240778BC421FD2E0B211F047 +:104940003BFFC8B1054600790138022814D3E87945 +:10495000411CE97196F8671088420DD92888A5F89E +:1049600009800DF0ABFF2888494611F037F848461A +:104970000AF092FA0EF07EFC0134DDE715484FF69E +:10498000FE774FF0000800F10C04134805788DB154 +:1049900034F80C0CB8420AD021784A1C227096F8E0 +:1049A0006720914203D9A4F805800DF087FF1C34DD +:1049B000013DECE70A490020032808BFBDE8FE835B +:1049C00011F8202012B1013A01F820200130F3E75C +:1049D000E6BC0200DC5B0020D5BC0200407B00206E +:1049E000348700202DE9FC412A4D95F8610000280C +:1049F00044D000240026602C40D095F86100F0409F +:104A0000C00702D120340136F5E7112095F8618006 +:104A100000FA06F714F092FD95F86110B94385F895 +:104A2000611015F037F8281928D0817A31B3102198 +:104A3000194A2C59B14011EA080190F9091052F8AD +:104A400021804668CFB209D006F006FB002079B27B +:104A500000224FF00073009020460EE0017A0229F8 +:104A600002D1C17CC90601D406F0F6FACDF8008067 +:104A700079B2204600224FF00063B04795F86100FC +:104A800028B106480021BDE8FC4115F0E3B8BDE8B7 +:104A9000FC8100BFB87B00209430044028800020B7 +:104AA0002DE9F84F82462948007888429CBF0520AE +:104AB000BDE8F88F50460C46009208F0CDF9074645 +:104AC00023484FF6FE7C0078874215D14FF6FE70E2 +:104AD00008F0C2F94FF6FE7CB8420ED11D49002005 +:104AE00001230A78BB4208D211F8335095423CBFEB +:104AF00018462A460133F5E73846DFF858B0C6B203 +:104B00000BEBC609C84628F802CF454655F8020FF8 +:104B100018B115F087F8002028604CB167003846BE +:104B200015F082F8286070B100993A4614F030FB15 +:104B30000948A8F800A089F8014000780BF8360071 +:104B40000020BDE8F88F0120BDE8F88FDBBC020033 +:104B50009ABC0200E0270020CE2700202DE9F84370 +:104B6000994616460F4604460FF004F818B16FF048 +:104B70000100013007E02548089D017820460EF02D +:104B800095FD18B1204680B2BDE8F883204600218B +:104B90000CF004FC294605F063F978B380464079AF +:104BA0004FF6FE75042816D001281FD198F806107C +:104BB000B8F8020011F0180F10D01549B842097862 +:104BC00088F8041018BFB0421DD1384631464A4615 +:104BD000F7F786FD06E04FF6FE70D4E70D49097D34 +:104BE00088F80410A842CED198F80500022805D014 +:104BF000204607210EF05AFD0028C3D12046BDE80B +:104C0000F84313F069BA4845DFD0EBE7D0BC0200A7 +:104C1000DCBC0200407B0020F8B505680446D5F8EE +:104C2000F80000B1F8BD68796668022807D105F17F +:104C3000D000694612F0E4FCC5F8F80009E0D5F8A8 +:104C4000EC10D5F8FC20D5F8F4001144C5F8F800B4 +:104C500000910028E6D031688A6B22F400628A63F2 +:104C600095F84410C90608D52F6C37B1AB6C2046B7 +:104C700010210022B847D5F8F800B0F5806F84BF46 +:104C80004FF48060C5F8F8000099336B01444A1E68 +:104C90003168B66B1A600E4A9A6043F6F07202EB06 +:104CA000001010409A6810439860D5F85801406889 +:104CB000006886620846022113F078FE287A0028F0 +:104CC000B0D120460121012612F0B9F82E72F8BDAC +:104CD000018000C0BFB523490020234D0022086099 +:104CE0002249C5E9020008602149087001212970A4 +:104CF00020490D2A03D041F822000132F9E71E486D +:104D00001E4901601E484DF2F02101601D481E49F8 +:104D1000016001202871286900B1BFBD01AC2046A7 +:104D200014F0C5FD00200121224602908DF80400F8 +:104D300016480EF019F9286114F04CFF0028ECD148 +:104D40002C78002C1CBF4AF20034C1F2E11414F09C +:104D50003BFFB4FBF0F1286914F03EFF286914F022 +:104D60003DFFBFBD14880020B82400201C8800200F +:104D7000A0880020488100200C880020F824010031 +:104D80001088002018880020905F010099C1010060 +:104D90002DE9F04F85B0264801ACDFF89C80DFF8A4 +:104DA0009CA04FF00109251D00F11C062148077841 +:104DB000D7B316F818BCABF10100012831D8306820 +:104DC00030B156F8041C02311CBF0138306028E0B5 +:104DD000D8F80020C2B19AF8000030B1184951F853 +:104DE0002000C0EB0010810001E01548016836F892 +:104DF0001C0C9047BBF1020F08BF012804D11149D8 +:104E000036F81C0C0968884736F81A0C8DF804909F +:104E1000ADF8100020460BF077F810B128460AF0E4 +:104E20003BF8013F2436C3E705B0BDE8F08F00BF73 +:104E3000B0540020E6BC020094230020C7270020C5 +:104E400060B702009C23002070B52C4D00282B6811 +:104E500041D0044643B9FA2014F0E6FE0028286049 +:104E600049D0002101702B68187815262178082276 +:104E700010FB0630417061788170A178C170E178D3 +:104E800001712179417161798171A179C171E179F2 +:104E90000172217A4172617A8172A17AC172E17ADA +:104EA0000173217B41730E3004F10D0114F070F990 +:104EB00028680178013101702B68187800FB06F131 +:104EC000E52918D3012110FB061014F03BFD2868DA +:104ED000002101700FE073B1187838B1012115225B +:104EE00010FB021014F02EFD2B6823B1184614F0AD +:104EF00099FE00202860002070BD00BF44270020DC +:104F0000F0B585B070B1044628480D46C08AA0426D +:104F10000AD113F075FE2649284612F0C6FB80F030 +:104F2000010602E000263AE012260020ADF8064015 +:104F30008DF8040001AF384604F00CF858B104377E +:104F4000384612F053FF012805D12846394612F0A1 +:104F5000ACFB80F001061748007818B3122E08D178 +:104F6000012806D12046294605F0F8FA002818BF86 +:104F70000026204629460AF02BFB0A280AD0A02842 +:104F800006D1204629460FF0E5FE204609F02AFF0B +:104F9000012E04D12046002110F0CEFE012630461D +:104FA00005B0F0BD122EDDD0E3E700BF407B00204E +:104FB000C887002018260020B0B588B00446407984 +:104FC0008DF81C0020798DF81E00274800788DF898 +:104FD0001F00206820B312F009FF08B32348002502 +:104FE000007801282AD820680DF1120110F00DFD7B +:104FF000BDF812004FF6FE71884208BF6FF037050A +:10500000A179F1B96FF00201013189B2884218D05B +:10501000ADF8140001208DF81D002068069009E00D +:1050200000208DF81D0013F0EBFD06906FF00200DC +:10503000ADF8140005A803F08BFC0546E8B208B0F3 +:10504000B0BDADF80400607901218DF810508DF8E5 +:105050000E1021688DF80F0001ACA01C14F08FFD1C +:10506000204614F0CDFDE9E7CD27002018260020CA +:1050700010B5017801290DD0022921D0FD2934D0A5 +:10508000D32939D01A29BDE8104018BF03F022BA3D +:1050900002F0B0BE2248007802282CD11D4C2078A6 +:1050A0000138012827D814F05DFB48B3FCF79EFEB9 +:1050B00008B32078022823D1BDE8104004F0D0BF07 +:1050C000144800780138012815D8134800780728BB +:1050D00018BF082805D11149097811B90121EFF746 +:1050E00059FBBDE81040F1F7D1BF0E49096811B175 +:1050F000BDE81040084710BDBDE81040FEF7ACBE4B +:1051000014F060FB002814BF01200020BDE810400F +:105110000BF012B81826002008880020BB88002059 +:10512000C4260020D82400202DE9FC470B9C8DF8D4 +:1051300007001E461746884604EB840000F1040968 +:10514000012050FA89F014F06FFD00283FD082460C +:105150000A9A0C980023514601F8017F8A700A1DB3 +:10516000CC704E70DEB2A6421ED20678167046781B +:105170005670467906F007069670877917F0180F73 +:105180000AD07D07C7F300174FF0060558BF022568 +:105190003D4446EAC505957085780133D570C578DC +:1051A000083015710532DDE70B4D5FFA89F30DF11B +:1051B000070048F23202696041460AF02DF90446C0 +:1051C000504614F02FFD05480130686000E01024BF +:1051D0002046BDE8FC8700BF7C260020DC7D002047 +:1051E00070B58EB02A4E044601200DF103018DF8F2 +:1051F0000300B068D0F830245220904700252821C1 +:1052000084F82050657501A80C3013F05DFE43F65C +:10521000FF702146ADF80B502546ADF82A000F204F +:105220008DF828002068019031F8040FADF80800CF +:1052300015F8060F8DF80A002089ADF80D00A07A48 +:10524000002818BF01208DF80F00E07A002818BF51 +:1052500001208DF81000207B002818BF01208DF858 +:1052600011000C48007801280AD1B068D0F8302429 +:1052700050209047B0682946D0F83024E12090476C +:10528000B068D0F8281201A8884700200EB070BD81 +:105290000C010020182600202DE9F0410C460804DE +:1052A0000AD460045CBF0020BDE8F0810FF012FA60 +:1052B00084F48040BDE8F081244F387809F0C6FBC3 +:1052C00000283FD005460078A0F12301022917D21B +:1052D0000C2011F0C9FE90B306460020C6E900007C +:1052E000B06005203070E878A9783171707114F0E1 +:1052F0009BFCB06018B3EA78696813F049FF1EE0C0 +:1053000027281CD1082011F0AFFEA8B106460120C5 +:1053100005F10108307098F80000033014F084FCA7 +:10532000706048B198F80010CA1C414613F030FF75 +:105330007878314609F0B8FE284612F093FD2846E9 +:1053400012F090FD84F40040BDE8F0817227002047 +:10535000B0B50446007D012805D0152803D02528C6 +:1053600001D035281FD1217E0A071DD4254D617833 +:10537000A868D0F8D42092F8822072B11B290CD1F1 +:10538000E868816A01208847A868D0F82C134FF498 +:105390008060884700216170A868D0F830232046DB +:1053A000BDE8B0401047217E4A060BD4152801D035 +:1053B000012801D109070FD4617879B11B290FD1D8 +:1053C000232013E00F488068006D016819B16078F0 +:1053D000BDE8B0400847B0BD312007E00D2100E036 +:1053E0000E21084A926852F82110085C2070054886 +:1053F00021468068D0F894000078BDE8B04009F0FC +:1054000053BE00BF0C01002070B5284D2878052838 +:1054100039D8022837D0274C0420254E2070264842 +:10542000B268417801314170D2F8D400C9B290F825 +:105430002430994204D9E120BDE87040FDF74CB911 +:10544000297804290BD1D2F8B8100A780AB3C96CAC +:10545000F9B102208847B0682978D0F8D400174AFB +:1054600090F8310013780133834238BF184610702A +:10547000052908BF70BD032914D183202070BDE821 +:10548000704013F07BBA0A488068D0F84C0580471A +:10549000C1E70A4990F831000A780132824238BFE8 +:1054A00010460870BDE87040FDF728BFB78800209F +:1054B0000C010020B488002021260020B58800209F +:1054C0007FB5244C2448254E254D012101226065DD +:1054D00030680368284698473068012142682846AA +:1054E000904713F06FFA1F48082200F12001204670 +:1054F00013F04EFE1C4900200A5C235C934207D146 +:1055000001300828F8D113481849082213F040FE4A +:1055100004F1080005F0ECFCA16809B100208847FF +:105520000C4806F019FF0CF011FC01AC204614F0F9 +:105530004FFA0F4D0020002122468DF80400284626 +:1055400012F06EFF0B48056013F0DAFF002004B084 +:1055500070BD00BFD42000204F9B0200D801001076 +:1055600000400340A87F05005CBC0200F012005020 +:10557000248500204888002070B5012953D00446B6 +:10558000002942D128480121057A01722021EFF338 +:10559000118681F3118894F82010032916D002296E +:1055A0001BD0012929D12168E26C63681960616808 +:1055B000236859601168914204D1A169C26822EA46 +:1055C0000101C160606AC0B1C0680FE02068616815 +:1055D000086060682168486012E0616A69B10A6821 +:1055E000C8684B681A604A6809684A6028B101684F +:1055F0004268116041680068416020460EF056FE26 +:1056000086F3118828460EF005F9216B481C0AD054 +:1056100006480029406818BF08464368D4E90A21B3 +:10562000BDE87040184770BD38220020A01F002040 +:105630002DE9F0418CB0DFF8A8800446D8F80800C6 +:10564000D0F83C03804708B1FC2045E001AD21467D +:105650001122284614F054FBA07D618A667C677D88 +:105660000B228DF81A00B4F81700ADF8161004F1EB +:1056700019018DF815608DF81970ADF81B00606A7E +:105680000A90D8F80800D0F8D40090F853008DF8AC +:10569000180005F1190014F033FB56B100200B90EF +:1056A00087B107EBC700800014F0BEFA0B9048B931 +:1056B00011E0812014F0B8FA0B9060B18121FF2233 +:1056C00013F0FCFBD8F80800D0F8442301A9072008 +:1056D0009047002000E01A200CB0BDE8F08100BF28 +:1056E0000C010020F0B581B040F2A416C1F2000612 +:1056F000F06B0125016801208847012849D03068F6 +:105700004AF20007C468C4F20C0738463C21012263 +:1057100000230025A047E0B338884AF20445C007BB +:10572000C4F20C050AD14FF00120286038884FF6EA +:10573000DC60CFF6FF703058804708E04FF6DC6041 +:10574000CFF6FF70305880474FF08070286042F2EB +:10575000300048F2D072C4F20900C2F200020068C0 +:1057600048F2D4711268C2F200010860801A47F64C +:10577000B432C2F2000244F240211368C0F20F01B9 +:105780004843A3EB93010125B1EB104F98BF010CE7 +:105790001160284601B0F0BD70B513F011FF13F091 +:1057A00087FF13F08BFF044600F00C000C2803D198 +:1057B00000BF00BF30BF3BE060071ED40DF07EFA93 +:1057C000054600EB800001214600012012F03EFC5E +:1057D000864212D91C4CA5F11800606104F10C003E +:1057E00013F07FF900BF00BF0120F6F777FD00BF7F +:1057F00000BF002084F820001CE000BF00BF20078D +:1058000015D40E4E0E4D306881682846884704280E +:10581000F9D0B0FA80F004F01001400940EA11100C +:1058200014F006FA074801210160006800E030BF6B +:1058300000BF00BFBDE8704013F0C8BED801001023 +:10584000004003402C200940D81B00202DE9F041E6 +:10585000264F05463E1813F071FE044696F84A019D +:10586000013886F84A0100063AD1214800EB85014B +:1058700010F825804E885FEA08600DD45FEA486022 +:105880001FD41C48006881693046884730460CF0B8 +:1058900019FA0228FAD11AE0164F3868016A304620 +:1058A00088473868816A304688473868016B3046D7 +:1058B0008847114801210160104801688907FCD51B +:1058C00005E007EB8600D0F8601100208847A5F1BD +:1058D000120010F1060F03D808F03F00FFF7B6FFE3 +:1058E000204614F0D7F80020BDE8F081D81B002036 +:1058F00046B60200B80100102820086028200840A1 +:105900002DE9FF4726480DF1040A00270AF1040497 +:105910000397CDE9017790F800902248C84600F13E +:105920003906FDB24D4510D20720294600220C232E +:10593000CDF800A010F02EFD30462146082212F0CE +:1059400077FB08B90137ECE7B846002300214D4545 +:1059500028BF012101980028024618BF01224D45A9 +:1059600038BF01231343012B18D10F4B1C78ACB95E +:10597000114000F2E2404FF00101019019700B4913 +:10598000086018BFA9F101085FFA88F101AB072090 +:105990000C2210F015FD064800210180BDE8FF87AC +:1059A000D7BC0200407B002085270020082500206E +:1059B00004250020BFB590F91910B1F1FF3F00DDBB +:1059C000BFBD017D0429FBD8012202FA01F111F0CB +:1059D0001A0FF5D0234DA968D1F89810098911F054 +:1059E0000A0FEDD040684178C1F3810103298DF899 +:1059F0000C1008D002290AD1B0F80510B0F8034005 +:105A0000ADF8041003E0411D01A814F0B8F813F03C +:105A1000A1FD28B1A1B201A801220FF085FABFBDF6 +:105A2000E868A4B22146426F01A890471E2800D022 +:105A300068B901A8214601220FF076FAE868006DE6 +:105A40008047FE28BCD1E868416D002007E0E86887 +:105A5000006D8047FF28B3D1E868416D0120884779 +:105A6000BFBD00BF0C010020B0B52B4CA068416940 +:105A70000A7EFF2A4DD0D0F8D43093F88330022B21 +:105A800012D1D0F804054D698047A1680A69CB6B33 +:105A9000D1F8D41091F82C1032F811101A89104452 +:105AA000281AA0EB01102CE08B7EA3B1022A12D1A0 +:105AB000D0F804058047D4E902124B695268D1F846 +:105AC000D4101B6912780979C01A6FF007039A1A6B +:105AD00012FB010015E0D0F804054D698047D4E9B8 +:105AE00002120B69CC6BD1F8D41091F82C1033F85A +:105AF0001110238918444418D2F8B4008047204478 +:105B0000281A002805D44FF6FF71884238BF014695 +:105B100000E0002188B2B0BD0C0100202DE9F04169 +:105B20002A4B012702462024187A1F72EFF3118CAA +:105B300084F3118854698C4202D18CF3118840E0BF +:105B40001D6A8F40002905EBC10648BF03F12C06F2 +:105B500048BF002792F82050012D26D1D2F800E04E +:105B6000D2F84C805568C5F800E0D2F804E015681A +:105B7000C5F804E0D8F80050454505D1D2F818E042 +:105B8000DD6825EA0E05DD609D699542354601D147 +:105B9000DE613568D5F804E01560C2F804E0CEF89F +:105BA00000206A60DD683D43DD60D6649761516125 +:105BB000B1F1FF3FDCBF0021D961012119748CF3E1 +:105BC00011880DF027FE2046BDE8F0813822002024 +:105BD0002DE9F84F0546007D1E4690460F463830A9 +:105BE000C0B211F041FAC8B304460D9829461C22F0 +:105BF00000900120DDF830A0DDE90A9B207004F15F +:105C00001C0013F0C5FAA01C39460A2213F0C0FA92 +:105C10000020A4F80C8084F813B084F81890C4F81D +:105C200014A0E0620098607630782074B6F8010025 +:105C3000A4F811002A7D6889E0812AB104F13800B6 +:105C4000E062296913F0A4FA607F800708D00A484F +:105C50000168204659B1BDE8F84F0847BDE8F88F04 +:105C6000064821460078BDE8F84F09F01DBABDE8A6 +:105C7000F84F12F0F7B800BFF826002095880020F2 +:105C80002DE9F04F89B04FF0000B04461421CDE907 +:105C900002BB04AD284613F017F924484FF0FF0A61 +:105CA00005F108094FF000088DF820A0061DB8F195 +:105CB000C80F34D01FFA88F7042014222B46394627 +:105CC0000AF054F838BB44B113F0B6FC86F805B0BE +:105CD00046F804BCC6F800B01DE004203946002296 +:105CE0001423009510F056FB484602A9082212F032 +:105CF0009FF940B901207071DDE904010B3031607A +:105D000046F8040C049013F097FC2846142113F075 +:105D1000DBF88DF820A00C3608F10108C7E714B1B4 +:105D200000200DF063FE09B0BDE8F08F8043002035 +:105D30002DE9F041254E0546371813F0FFFB0446C8 +:105D400097F84A01411C87F84A11C8BBDFF88080E8 +:105D5000A5F1120010F1060F18F8257003D807F00E +:105D60003F00FFF7E5FF08EB8500458838060CD4B7 +:105D700078061FD417480068416928468847284696 +:105D80000BF0C2FF0128FAD11AE0124E3068C16947 +:105D9000284688473068416A284688473068C16A83 +:105DA000284688470C48012101600C480168890792 +:105DB000FCD505E006EB8500D0F86011012088478E +:105DC000204613F067FE0020BDE8F081D81B0020BC +:105DD00046B60200B80100102820086028200840BC +:105DE0002DE9FE4FDDF830800E9E92460C460F21C5 +:105DF00006EB080201EB4201C9B2502984BF102012 +:105E0000BDE8FE8FCDE9011020489B460F9FDDF8CD +:105E10003490456813F0C8FBA0421CBF0220BDE8C7 +:105E2000FE8F25F8024B12F0EBFE0146284613F0D8 +:105E3000A6FE4FEA1B2180F8038080F801B0817034 +:105E4000DDE9013100F804ABB8F1000F09D019F811 +:105E5000022BA8F10108027019F8012C42700230DF +:105E6000F2E700F8026B4EB117F8022B013E00F882 +:105E7000012C17F8012C00F8022BF4E7034820222C +:105E800003B0BDE8F04F09F0C7BA00BF7C26002080 +:105E90002DE9F043844608981C460625034405EB8B +:105EA0004303DBB2502B84BF1020BDE8F083234DA9 +:105EB0009CF80880DDF824904FF6FD7E6F68079D02 +:105EC000B8F10F0F02D0B8F1020F08D10EF102069F +:105ED000BCF80080B6B2B04508BFACF800E0BA70BC +:105EE000120A3C71FA700EF1020292B2914208BF9E +:105EF000714607F8051B090A07F8041C4CB144B1A8 +:105F000015F8021B013C397015F8011C7970023735 +:105F1000F5E7387058B1791C48B119F8022B0138EF +:105F200001F8022B19F8012C01F8012CF4E70348C1 +:105F300061460622BDE8F04309F06EBA7C260020D7 +:105F4000F0B585B0294E0446B068D0F8FC11204663 +:105F5000884788B9B068D0F82C112046884758B9CE +:105F6000607C40B1271D97F8300020B9B068D0F8A8 +:105F7000B810097849B100206070B068D0F84411B9 +:105F8000204605B0BDE8F0400847D0F8342207F1BC +:105F90000E01092090470028EDD00546B068F91D94 +:105FA000D0F83024E7209047B06804F10801D0F819 +:105FB000302450209047B068B91DD0F83024E1203B +:105FC0009047022023894FF6FF728DF810004FF0A2 +:105FD000FF30ADF80800B068D0F8C061A07A00903A +:105FE00002A92846B04705B0F0BD00BF0C01002053 +:105FF0008B4208BF824207D9009A002A01D0106064 +:106000005160002100207047002B08BF002A10D1EA +:10601000009A002A01D01060516002000B0000219C +:106020000020002B08BF002A1CBFC943C04301F059 +:1060300040B9F0B51C4615460B460246002000212B +:10604000B4FA84F6202E04BFB5FA85F62036B3FAEA +:1060500083F7202F04BFB2FA82F72037F61BB6F180 +:10606000200727BF05FA07F400257F42B4403EBF52 +:1060700025FA07F73C43B540A34208BFAA4201D323 +:10608000521BA341404149416D0845EAC47564086B +:10609000761EF1D5059F002F01D03A607B60F0BDE0 +:1060A000FEB50D46C9890446A1F50040022812D369 +:1060B000132920D048F20402B4F90400914206D119 +:1060C000A18C052903D80221A1844021A180B0F12F +:1060D000FF3F1ADDFEBD284608F04AF80028F9D037 +:1060E0000446007818B9E989204607F06DFD20467E +:1060F00013F098FDFEBD6C462846214612F032F89A +:10610000698820460CF0B7F9FEBD94F824000130F0 +:10611000C6B2304613F088FD0028DBD00546A079D2 +:1061200027792870E0796870A81CA28CA16A0131D7 +:10613000013A13F02DF847F08001452032462B46F6 +:106140000CF09CFA2846BDE8FE4013F06BBD70478A +:106150002DE9FF478146284888460024002690F80C +:1061600000A054450BD2E0B20FF000F828B105466C +:1061700040790644F7B2B94503D30134F1E7B320BF +:1061800037E04046182112F09FFE6979A9EB07001D +:106190000844C0B205EB4000C088A8F80A0012F01D +:1061A0002FFD0146404613F0EAFC6878012806D12D +:1061B000012088F814006888A8F80C0012E06888AC +:1061C00001A90FF09DFF68B19DF80C1008F10C00BB +:1061D000032988F8141019BFBDF80410018001A923 +:1061E00013F0CDFC2878297988F80800002088F879 +:1061F000161004B0BDE8F087E2BC02002DE9F041C2 +:10620000002918D41F4615460E46044612F03EFDDE +:1062100080462046314680220BF0FEFD20B1064626 +:1062200090F9330000280AD4404613F017FD0021EE +:106230000220BDE8F08100200021BDE8F081D6E910 +:10624000080145F00A0547F0E04728403940084377 +:1062500010D0404613F002FDD6E9082303EA0701F7 +:1062600002EA050042404B40C4E92C01C6E908237C +:10627000BDE8F081B1680B48814203D0B168C4F831 +:10628000A810B0604046C4E9285713F0E7FC04F1B9 +:1062900050004FF0FF3113F073FBD4E92C01BDE83F +:1062A000F08100BF8DDC0100F0B589B017460C46C7 +:1062B00005460DF05FFC18B10026304609B0F0BD70 +:1062C0002846002100260BF069F8394603F0C8FD86 +:1062D0000028F2D007468079C007EDD0204612F0A2 +:1062E00055F9012818D10420ADF816408DF8140096 +:1062F00005AF384602F02EFE01260128DDD1002030 +:106300003A1D2146CDE90000CDE902061048037888 +:10631000284600F065FBD0E7B8794007CCD513F0EC +:1063200043F9A0420CD100202146CDE90000CDE97F +:10633000020005A8021D06480378284600F050FB1D +:10634000B87981075CBF00F0FB00B8710126B4E7A3 +:10635000CFBC02007CB5284E04460D460DF1070166 +:10636000B068D0F828244F20904712F0E9FE0428A6 +:1063700009D1A5B121494FF47A72600113F0D8FA1E +:1063800000F53E702DE012F0DBFE68B1ADB11B49A7 +:106390004FF47A72E00013F0CBFAF83021E04FF4BA +:1063A000867000EB44101CE05DB114494FF47A7222 +:1063B000600013F0BDFA263006E0602000EBC40058 +:1063C0000FE0102000EB44009DF807104FF0FF3263 +:1063D00002FA01F1F268C94352681278083202FBEE +:1063E00001000C21122C88BF28210844034980B2E7 +:1063F0000978484380007CBD0C010020B088002053 +:106400002DE9FF4121480026DFF8888006602048FA +:1064100006604FF47000C8F800001F4806701F485F +:10642000067013F094FA1E4F0446386840B113F01A +:10643000D1FB10B1386813F027FB386813F066F809 +:1064400001AD284613F033FA164801212A46029678 +:106450008DF804600CF088FD386028B91248806817 +:10646000D0F84C058047386813F0B8FB204613F08D +:106470004AFB0D488068D0F814150F208847D8F8DB +:10648000000004F099FABDE8FF8100BF2C880020CD +:10649000388800203C8800208C880020B2880020AA +:1064A00028270020CD5702000C0100202DE9F041E3 +:1064B000806A224A0121012584784678512014708F +:1064C00013F0A4F91E4805701E484EF660250EB163 +:1064D000203007E01C490978002914BF00EB810037 +:1064E0004FF47A75194906684FF480400F780021FF +:1064F000F5F712FADFF85880022198F8000008F04A +:1065000077FA06FB05F0B0FBF7F2E0070AD1A00727 +:1065100058BFBDE8F08198F800000221BDE8F041C5 +:1065200013F0E5BA4FF480401146FEF7D7F84FF468 +:1065300080400121BDE8F041F5F7EEB9CC270020FD +:106540009727002060B70200C2270020C127002043 +:10655000988800202DE9F04F85B0814680690DF1C3 +:10656000120200214FF000080778A32008F068FC11 +:10657000BDF91200D0FA57FB1FFA8BF0032828BF91 +:106580004FF0030B5FEA0B4016D00BEB4B00C00043 +:1065900080B213F049FBA8B182465FFA8BF5002464 +:1065A0000646AC420CD257FA84F1A220324608F0DB +:1065B00047FC01341836F4E74FF0000B4FF0000AA7 +:1065C000002204E0B5224FF0000B4FF0000A99F8CA +:1065D00011005FFA8BF19DF81230CDE902A8CDE9E8 +:1065E000007109F10201FDF731F8BAF1000F02D094 +:1065F000504613F017FB05B0BDE8F08F70B586B0BC +:1066000085690446284611F0F1FB30B112F0F8FA22 +:106610000146284611F049F828B120480178D1B345 +:106620000020049003E01D480495017828460229C3 +:1066300004D11B49A28B498B8A422CD1217B51BBAF +:10664000297A00268DF81660CA094DB28DF81520FA +:10665000C1F38012002D8DF8142005D420B94FF419 +:1066600000500121F5F758F904A8FEF7A5FC8DF8B4 +:106670000F000DF10F00A11C48F234020123CDE9F7 +:10668000000604F111000AF0CDFF002D03D4049898 +:1066900008B912F091FB06B070BD00BF18260020AB +:1066A000407B00202DE9F04F85B0814680690DF1D7 +:1066B000130200214FF0000807789D20FBF77CFCB7 +:1066C0009DF81300B84225D9A0EB070A5FFA8AF0BB +:1066D0000A2828BF4FF00A0A4FEACA00C0B213F0D6 +:1066E000A3FAB8B1834600245FFA8AF50646E0B201 +:1066F000A84213D257FA84F18B203246FBF75CFC98 +:1067000070790138C1B2032928BF0320707108369F +:106710000134ECE74FF0000A4FF0000B99F811003C +:106720005FFA8AF19DF813300022CDE902B8CDE975 +:10673000007109F10201FEF7F7FCBBF1000F02D076 +:10674000584613F06FFA05B0BDE8F08F2DE9FE4F03 +:10675000DDF838908DF80B0001209B4614460D465D +:1067600009F10A0650FA86F013F05EFAC8B30195F3 +:1067700005460746DDE90C8A594605F8014F681CB5 +:1067800013F0BBF94FEA1A21B9F1000F80F8049019 +:1067900080F802A080F80080C1704FEA1821417093 +:1067A00004D00F9905304A4612F0F2FCDFF83C8025 +:1067B00010980199F3B248F2380288F802000DF1FE +:1067C0000B00C8F8045008F027FE0446384613F0C2 +:1067D00029FA002088F8020005480130C8F80400B2 +:1067E00000E010242046BDE8FE8F00BF7C2600207C +:1067F000DC7D002070B5044613F0A9F824498860B8 +:10680000A0070A4604F1080020F0030008BF201D7D +:10681000112828BF04321368002400221D68B5F136 +:10682000FF3F07DD54B116682E448642166012D22F +:106830002E4608E085F00046002404E0854208D298 +:1068400001242E461A469D593344002DE7D10024D9 +:1068500019E01A462E46002AF9D0331A042B08D321 +:10686000135040F0004313600A4B5C68201A5860D4 +:1068700008E0084B10685C68201A5860106840F007 +:1068800000401060141D886813F03DF9204670BD6B +:10689000D02500204425002010B586B00146427E58 +:1068A0008068002343F606040593CDE90333029381 +:1068B000438003881C1B022C10D3B3F5C15F03D0A7 +:1068C00040F60204A34212D1038A002A23F4FE6395 +:1068D00012BF038243F43472028208E0038B23F474 +:1068E000FE630AB1038302E043F4347202830022A0 +:1068F0004A7602A9009105A904AA03ABF8F77EFF26 +:1069000028B105984FF6FF71008888420ED0049C8C +:106910000299204606F06CFA0748016821B120462A +:1069200006B0BDE81040084706B010BD049C0299AF +:10693000204606F029FEEFE77426002070B50C46CD +:10694000214900228D1D214909788A4210D2C37C39 +:106950006E789E4207D1838935F8066C9E4202D13B +:1069600015F8043C13B908350132EEE78A4201D12B +:10697000002070BD287828B31548818C20460EF081 +:10698000B5F910B12878013828701248011D124855 +:10699000007802464AB10B78FF2B03D031F8043C53 +:1069A000A34204D02431013AF4E7297802E029789F +:1069B00001392970094AC9B21278104488423CBF93 +:1069C00000202870012070BD42760020D2BC020059 +:1069D000407B0020B0540020E6BC0200D5BC020081 +:1069E0002DE9F84F0B9F05460220DDF834B099469B +:1069F00090460E4607F1010ABBF1000F00EB4A007A +:106A000008BF02208DF8010068460FF039FFB8B3C7 +:106A100004460A9884F81A90A6806580E076A07FE4 +:106A200001280AD112F0C0FDB04206D0B8F1000F23 +:106A300006BF0020A077C4F8248005202169BBF19F +:106A4000000F087018D00C9881F801A08D1C00214F +:106A5000CAB2BA4208D210F8022B01312A7010F8DB +:106A6000012C6A700235F3E712F09EFD287012F0D7 +:106A70009BFD000A687000E04F70204607F02EFF73 +:106A8000BDE8F88F70B5274CA068D0F8D4204169D4 +:106A9000557B00224A77C16891F83020013281F895 +:106AA0003020C16891F83010042908D1D0F8640171 +:106AB0008047A068D0F86C01BDE870400047E068EE +:106AC000C16B20208847A268D2F8D40090F84F60AC +:106AD0000F2E0FD05169437B897F99420AD24173AF +:106AE000D2F8D400D2F81415407B8847A268D2F8B7 +:106AF000D40000E02E46407B4FF470718140D2E913 +:106B0000030390F8304033F816306400A340B3EB31 +:106B1000910F88BF8B08D2F8F024A1EB4301BDE8A8 +:106B2000704010470C0100202DE9F0418AB0204F41 +:106B30000DF108083868416E404688473868C06BD8 +:106B400080471C4C002502900595217BA060658044 +:106B500001F0F0010231217301218DF80C1012F0C7 +:106B6000EDFC064614480221154BC068806901708F +:106B700012483A680068176DCDE900152146424673 +:106B8000B8470546304612F085FFB5F1FF3F06DDF8 +:106B90000C4804600C4801780131017004E00320C6 +:106BA00041F2883104F084FB0AB0BDE8F08100BFF7 +:106BB00030880020642500200C010020D826002009 +:106BC000F1E201002025002019250020F8B5154626 +:106BD000044625480E461168D268AF690068002F48 +:106BE00018BF3846206321616261D5E9042100297C +:106BF00008BF4FF4007162B1D31D11444FF0FF3054 +:106C000023F007032063C91A21F00701C4E90A131E +:106C100008E00731082221F00701A1620CF018FEFC +:106C2000E062F0B1D5E9010104F13803EA69666375 +:106C300007C395F8200084F8480018B10B48416953 +:106C40000131416100206065204604F021FC08B15B +:106C50000230F8BD054804F1080111F0D3FB002013 +:106C6000F8BD0120F8BD00BF788800203822002040 +:106C7000BFB545680446287805380B2815D8DFE8E5 +:106C800000F006140C1415141414141B144220469E +:106C900004B0BDE8B040FAF795B9681C019060896E +:106CA000ADF8000068460DF0F7FBBFBD204604B00C +:106CB000BDE8B04011F045BC681C0DF10A010EF0B2 +:106CC00095F90128F1D150208DF80C0000208DF8A5 +:106CD0000E00207A09388DF80D0003A80CF0ACF8EE +:106CE0000028E2D00446BDF80A0005F10901227D22 +:106CF0006080087884F83800206912F049FA20464C +:106D000007F0ECFDBFBD204604B0BDE8B04010F078 +:106D10001BB970472DE9F04F8DB0169E1A9F0B904E +:106D20004FF6FF70ADF83010388086B11C4673B155 +:106D3000DDF86490B9F1000F09D0DDF85CB0BBF16B +:106D4000000F04D0DDF860A0BAF5005F04D9042577 +:106D5000E8B20DB0BDE8F08F0BA806AA214607F0F7 +:106D600047F905460028F3D11048806803F038FB46 +:106D700080460F48ADF814400496ADF80EA0ADF86B +:106D80000CB0CDF808901223C188C07802AA0092F6 +:106D900006AAF3F703FB054610B9BDF81C003880BE +:106DA00002484146806806F079FED1E7A023002022 +:106DB000A08000202DE9F84F002480460021002209 +:106DC0000460684602F092F9204DDFF884A0814605 +:106DD0004FF0FF374FF0190B0020602C1ED02A19FE +:106DE000917AB9B1107A022816D0DAF80400418BF2 +:106DF0000069084495F8621011FB0B0150690EF010 +:106E000060FE064612F0E0FEB6FBF0F0B84238BF76 +:106E1000074601202034E0E70120002709EA0001AD +:106E2000012904D10099B94238BF0F4606E0B9F1F3 +:106E3000000F01D0009F01E0C10701D0C8F8007029 +:106E400040EA090000F00100BDE8F88FB87B00209F +:106E5000D01E00202DE9F84F0546D1F800902348B8 +:106E600000268B46814588BF032612F067FBDFF8BA +:106E700080A08046DAF80440601B18BF01205AF851 +:106E8000207025B105F1B80012F0A4FE28B96FB149 +:106E900007F1B80012F09EFE40B19AF82400CAF83B +:106EA000205040F002008AF8240018E0601BDBF854 +:106EB00000104FEA9904B0FA80F0400940EA40001F +:106EC0000AEB800081609BF80810017412F07CFED0 +:106ED000B4FBF0F105F1B80011F024FC8326404624 +:106EE00012F0D8FD3046BDE8F88F00BF03093D0021 +:106EF00070200020F0B587B00546112012F094FEF6 +:106F0000002841D004463B2000211122234611F0E5 +:106F1000C1FF90BB2078A8422FD1112012F084FE2F +:106F200058B305463A20002111222B4611F0B2FF3A +:106F3000E0B93A201121224612F068FC1348144FA0 +:106F4000012180F8411078682146B0F1004F84BFDC +:106F50000020786001AE3046112212F019F97868ED +:106F6000182132460690822012F050FC284611214A +:106F700011F0AAFF284612F055FE2046112111F00B +:106F8000A3FF204612F04EFE07B0F0BD407B00206C +:106F90000425002070B524480C460078012801D84B +:106FA00060061CD420060CD4A0052BD420052ED4BA +:106FB00060055CBF002070BD05F0EAFF84F48060CE +:106FC00070BD04F0FDF808F01FF901200FF084FDFA +:106FD00003200121EDF7DEFB84F0800070BD134E2D +:106FE0003068F0B1808802F019FA3068056812F054 +:106FF00019FE3560ADB1EA882D686DB1E888801A58 +:10700000E880F9E702F0FAF884F4007070BD05F04A +:1070100053F884F4006070BD05484021007812F0F8 +:1070200069FD84F0400070BD18260020DC26002099 +:10703000998800207CB520480C46017029BB1F4868 +:10704000007802281BD109F015FF0CF0D5FAB0B179 +:107050001C21054611F038FF194E708B06F11C01FA +:107060002880A81C12F08BFD4AF60120A5F811001B +:1070700014480078013040082874B08C68811248A8 +:10708000007810B9032010F033FD1048016951B1A8 +:107090000B488DF80040C28A408BADF8040068466A +:1070A000ADF8022088470A48022102220023007816 +:1070B0000DF087F97CBD00BFBB880020182600209A +:1070C000407B0020D1BC0200C42600203C8300206D +:1070D00099880020B0B586B00589044612F064FA9C +:1070E000854212D10020ADF810006068039012F0C4 +:1070F000C8FC78B30179013903292BD840790121E3 +:1071000021EAD0008DF812002DE020890021ADF891 +:107110000C006068049001ACAB20224607F090FEA2 +:107120000DF103012046002202F044FA10480078D5 +:10713000012808D19DF8030028B900208DF814001B +:1071400003A800F039FA01208DF8140003A800F01C +:1071500033FA0BE0248812F027FA844206D100208B +:107160008DF81200039003A8FDF726FF06B0B0BD0E +:10717000B227002070B588B000266D460446202155 +:107180000672284611F0A0FE284621460B2211F077 +:10719000FFFFB4F80B0004F10E010A228DF80D6018 +:1071A000ADF80B0005F10E0011F0F2FFA07ECDF856 +:1071B0001A60ADF81E60C1071CBF01218DF81A10BE +:1071C000810744BF01218DF81B10410744BF0121F5 +:1071D0008DF81C10010744BF01218DF81D104106D8 +:1071E00044BF01218DF81E10000644BF01208DF818 +:1071F0001F000020ADF80C00208BADF818000448EB +:107200008068D0F8F41268468847002008B070BD46 +:107210000C010020F8B5D0E901650446287912F088 +:10722000E1FCD6F8CC206969286852681268D162FE +:1072300096F8F93013B9C368DB06FCD4436823F031 +:10724000020343602B69D3621943476A27F003079F +:107250004762C2F80415416921F001014161012131 +:107260000162D6E93512D6F8C00001604AB1EB6977 +:107270009B68C3F309139A4203D91144DA431144BA +:107280000160D6F8DC204AB16B6A9B68C3F309132E +:107290009A4203D9DB431A4411440160204609F0A5 +:1072A000B9FC287910F074FA2879BDE8F84012F09A +:1072B0009BBC70472DE9F04387B0C468DFF8889025 +:1072C00000264FF001081B2E11D0D9F8280008FA2B +:1072D00006F7384209D0A55D12F05AF9854204D963 +:1072E000D9F82800B843C9F828000136EBE7D9F8E7 +:1072F0002860C6B16C461821201D11F0E5FD012063 +:1073000000968DF8040000208DF8070099F82E00F3 +:107310008DF80500204607F023FC062089F826009A +:1073200007B0BDE8F0830020002189F8260041F273 +:10733000040007F0EAF9054801680029F0D0C420EC +:1073400007B0BDE8F0430847407B0020002500203F +:10735000BFB50FF0DFF904462148012100F10E020C +:10736000552012F04DFA04F0010418B914B10020B0 +:107370000FF0B2FB1B4DE220691C0EF053FE2046BD +:1073800005F00AFF0020CDE90200CDE900002878D1 +:1073900001280ED814486946102210F049FE18B191 +:1073A00068460EF03BF904E00F496846102211F0E0 +:1073B000EFFE6A466220102112F022FA2CB120B9A9 +:1073C0006A466220102112F021FA20460EF014FEC7 +:1073D0001CB1002001210CF077FA002004B0B0BDF0 +:1073E000CC2200201826002034BB0200F0B589B062 +:1073F000044640890E46010742D5800706D5607BCA +:10740000062803D0CD2E18BFF02E37D1207B0FF0E9 +:1074100003FCA8B3217B676905467EB108220FF003 +:107420000FFC70B16FB1428801780379B87895F894 +:107430000AC0CDE900C60BF03FF803E004220FF0CC +:10744000FFFBEFB178682168CDF80E00387A096A41 +:107450008DF81C00E86809780690787B8A09402935 +:107460008DF81D003878009538BF042200F04001E7 +:1074700000F0200302A8EFF711FF02E0E92EC5D0CB +:10748000002009B0F0BD704770B50546407D164636 +:1074900001220FF055F9C6B90446B0B1E87D94F861 +:1074A0003510884211D194F83910237A0A18287EB1 +:1074B0009A420BD2FF2817D1002084F8352084F897 +:1074C0003800FF208840C0B20EE070BDFF280BD10D +:1074D000E28BA07E94F82A1000230BF0BBFF20461D +:1074E000BDE8704010F014B984F8370084F8360015 +:1074F00012F06CFB054612F067FB68434FF47A719B +:10750000B0FBF1F00121208094F83A00608003483C +:107510000078BDE8704006F09BBD00BF3C2600200F +:10752000B0B586B0044601208DF814002046F9F766 +:10753000CFFA206918B11F48816820468847207D0E +:1075400058BB0020CDE90000029001208DF8020018 +:107550008DF80500D4E902010088ADF80000087D2F +:1075600009308DF804006846F8F730F89DF81400EB +:1075700098B903980E21406C0546013005F8091BA7 +:10758000A168496812F0FBFAE0680169027D2846AB +:1075900011F0FEFD68460AF0B1FFE06808B112F094 +:1075A00041FB204612F079F99DF81400207506B0D1 +:1075B000B0BD00BF50240020B0B586B00446002006 +:1075C000CDE90000029040F20910ADF804002088D7 +:1075D000ADF80000207A012812D121208DF8020098 +:1075E0001948007878B912F0B7F860B9174D61689A +:1075F000082205F1180011F0CBFD2088288002E058 +:1076000001208DF802006846F7F7E0FF9DF81400AE +:1076100050B903980721406C00F8011B616812F013 +:10762000AEFA68460AF06AFF0748007838B912F0E7 +:1076300093F820B905480021C0E9061101809DF8A2 +:10764000140006B0B0BD00BF182600205024002052 +:107650002DE9F04F85B02048DFF884A000274FF6D1 +:10766000FF7B007800901D48047801A8051DA74203 +:107670002FD007EBC7003AF82010594527D00AEB66 +:10768000800801208DF80400B8F80200ADF8100061 +:1076900001A808F039FCD0B1124EDDF80090B9F124 +:1076A000000F14D03088B8F80010884208D0BDF818 +:1076B0000610884204D0B11C28460FF0F6FF10B126 +:1076C000304610F02FFE1C36A9F10109E7E701371B +:1076D000CDE705B0BDE8F08FD5BC0200E6BC0200E6 +:1076E000B0540020DC5B00202DE9F0418AB0054653 +:1076F00020480078012839D81F4FF88AA84203D1C2 +:1077000085B30CF065FF2BE0284612F066F948B30C +:10771000044600790138012824D860884FF0000819 +:107720008DF81880ADF8240006AE304608F0ECFB6A +:10773000C0B1208811496D46088005F10B00311D4C +:1077400012F01DFA00200DF061FEADF814008DF866 +:10775000168028460222217902F042FAC4F80C80F1 +:10776000012004E0B98C28460EF035FA00200AB05A +:10777000BDE8F08118260020407B002074270020FF +:107780002DE9FC41204F0446786808B18047B0B32A +:10779000F868BA69610312F089F9012500282FD42D +:1077A0001A4904EB440001EB8006F07DFE2838BF47 +:1077B000451C1748F5750021042340EA0520019077 +:1077C00001AA20460CF062FA387018B903207076CE +:1077D000FF20B0750F4F12F0A6F800234FF0FF08FE +:1077E0000025B84712F09FF80123B84712F09BF824 +:1077F0000223B847102086F81880B08300E00B25DC +:107800002846BDE8FC8100BFA0230020A080002006 +:10781000FF000F96915D0200F8B50446FD201D465D +:107820008DF8030020461E68324600F025F910B19D +:1078300001208DF803009DF80300FD2815D1E068B4 +:10784000007B00F00F0002280FD176B13768204688 +:1078500031463A4600F010F920B9002F3E46F5D1E6 +:10786000002602E002208DF803009DF80300FD28A9 +:1078700004D1E06B10B104208DF803009DF8037073 +:10788000042F0FD0022F06D0012F0FD128462146FA +:107890000FF089FA0AE0326822B1284621460FF03B +:1078A0006FFA03E0284621460FF072FB78B2F8BD6C +:1078B0002DE9F843994615460F4606460CF0A6FFFB +:1078C0001E49DDF820800C78A04216D21C4900EB3E +:1078D000800201EB420212F8073FAB429CBF03203B +:1078E000BDE8F883B8F1000F24D000EB80001570DC +:1078F00001EB4000A0F804901CE04FF6FE70002160 +:107900000CF084FFA04204BF0220BDE8F883B8F168 +:10791000000F0FD00A4900EB800001F8107001EB56 +:107920004000FF2181710749C571A0F8049046808D +:10793000C97C01720020BDE8F88300BFD9BC0200F9 +:10794000D07E0020407B002010B505F087FD044666 +:1079500088BBFBF73FFDC8B111F026FE184908802F +:1079600020B91848018821F00701018016480078E5 +:10797000022804D001280BD11448007840B91548DA +:10798000002180F826101248032103E0092409E0B1 +:107990000F48012181700F4800F139010E4812F0A3 +:1079A000EEF800240D48002101800748007810B946 +:1079B00000200CF04BFA002C18BF0124204610BD0B +:1079C000708700202687002018260020D42700205A +:1079D000C4260020407B002096870020042500203C +:1079E0002DE9F04F87B080465868DDF840A08B46FF +:1079F0001F469146002100251B2906D020FA01F2DE +:107A0000D20718BF01350131F6E728064FF0000113 +:107A100014D0E8B212F008F990B1044607F108005A +:107A2000002100221B290CD07B68CB40DB0703D050 +:107A3000435CD6B20132A3550131F3E7002401E0E3 +:107A4000002400217B68BA78E8B2CDE900B902AD24 +:107A50000591084985E811044046FEF777FE2CB1F0 +:107A6000204607B0BDE8F04F12F0DCB807B0BDE823 +:107A7000F08F00BF7A87002070B5B2FA82F3B1FAB6 +:107A800081F45B096409B0B312B190F844506DB34E +:107A900089B191F844406CB3446B0E69096C056977 +:107AA0008908A408AE4214BFED6800252944611A74 +:107AB000B1F1704F22DAB2B1D168097B01F00F0148 +:107AC000022915D1516B0569006C14698008890879 +:107AD000A54214BFE26800221044081AB0F1704FAA +:107AE00001DB012804DB0124012304E0002302E080 +:107AF000012400E0002404EA030070BD00240029F2 +:107B0000C8BF0124002AF6D00129D5DAF3E770476F +:107B1000F8B5F0B10446007A00F0FE00022818D152 +:107B200020460D4600F03EFEFF281CBF1E20F8BD7B +:107B30001B49227A194B0846022A08BF18460668D4 +:107B4000002005280AD026FA00F7FF0703D00130ED +:107B5000F7E7E820F8BDC6B2052E05D1022A18BF06 +:107B6000032A0DD11A20F8BD022A0AD1228803EB7C +:107B700080012B0ACB728D720A72120A4A7206E0D9 +:107B800005202268636801EBC001CB608A60227A1D +:107B9000C0B201210DF028F80020F8BD08850020B2 +:107BA000E08100202DE9F84F204E214FDFF884803E +:107BB00000254FF0010B4FF002094FF0110A602D24 +:107BC00008BFBDE8F88F7C192ED0A07A01282BD1F0 +:107BD000607A41B20BFA00F01131C0B20BFA01F138 +:107BE000CA43326072681143716010F059FA04F1AF +:107BF000100000210EF00EF9812809D1A06920B1F2 +:107C000000210EF007F9812802D184F80A900BE0D8 +:107C1000607A97F861100AFA00F00843002187F8AB +:107C20006100404612F016F82035C8E708100440FD +:107C3000B87B00202880002070B5044610F068FA58 +:107C400041F288300DF0DEFF1A4D287801280BD85C +:107C5000194E4FF48071307806F0CAFE30784FF438 +:107C6000807105F02DFC2878022804D14FF40050D3 +:107C70000121F3F751FE012C15D1104803210224F4 +:107C8000104D817004700E48012101700E4805F1FD +:107C9000390111F074FF85F826400FF0E9FDBDE8C9 +:107CA00070400DF003BD41F28830BDE870400FF028 +:107CB000C5BA00BF1826002098880020C4260020DE +:107CC0009E880020407B00209687002080B51F48BA +:107CD000007860B111F05CFCEE281DD811F058FC62 +:107CE0001030C0B211F066FC194801211BE01948A0 +:107CF0000078082815D10FF01BFD09200FF0F8FEC1 +:107D000015480078072813D0052815D101200EF05A +:107D1000B5F903F055FA0FE00020BDE880400EF001 +:107D2000ADB90B4810210078BDE8804006F090B94D +:107D300007200121ECF72EFD08480078012818BF24 +:107D400080BDBDE880400FF08BBA00BFBB8800202B +:107D500099880020C426002008880020BA27002027 +:107D6000BCB50446807A01280CD1207B00218DF817 +:107D7000071060BB1D488DF80510007802281CD242 +:107D8000E07A1CE0258811F0FDFBE27A85420ED1F5 +:107D9000012A01D1207B07E01348008800F007008A +:107DA000022804D101202073FFF746FF16E0237B51 +:107DB0002088A11CFAF756FA10E002D100208DF8B5 +:107DC000040010F0F9FF01A809F05CF9207BFFF72F +:107DD00033FF0DF1070152200AF050F90448816980 +:107DE00009B120468847BCBD268700201826002000 +:107DF0003C830020B0B588B0044602208DF80A000C +:107E0000E08894F82420617EADF80200607D8DF852 +:107E100010108DF80C00A088ADF80E00501E8DF8E3 +:107E20001200A06A411C069100788DF81100608A4A +:107E3000ADF81400A08DADF81C00684604F0CCF835 +:107E400005460F48007818B169462046FEF728F924 +:107E5000BDF80E100B480023152B0BD030F8334023 +:107E60001A4601338C42F7D100EBC20041686846E4 +:107E7000884703E015B968460DF010FB08B0B0BDA7 +:107E8000DC27002064AE02002DE9F0418EB00546EB +:107E900011F054FBDFF88080044669681022D8F89E +:107EA0000800D0F808010068836B0AAF384698478D +:107EB000064638BBD8F80800D0F808010068016908 +:107EC00001AE304688470D206A6901978DF824007D +:107ED000D5E9020105926A8B0290288BCDE9031146 +:107EE0000790A88B8DF82500101A0890084406907A +:107EF000D8F80800D0E94112086811688A6931464B +:107F000090470646204611F0C5FD002E18BFE42616 +:107F100030460EB0BDE8F0810C01002070B51F4D59 +:107F2000A868D0F8B8100A781D4991F900101AB164 +:107F3000002902D41B49097811B1D0F84C058047BB +:107F400011F0FCFAEA68184C126921781278914213 +:107F500007D116490978490703D411F09BFD012088 +:107F600070BD11F097FD0EF04FF920780FF01AFA5E +:107F700078B1E86824780669204631780CF062F818 +:107F8000347030B1A868D0F8D40090F9420010F0F5 +:107F900092FDBDE8704010F041BF00BF0C01002011 +:107FA000B4880020A78800204C260020AD8800203F +:107FB00070B51C480025204C05701B4805701B48F7 +:107FC00005701B4885601B480570A068D0F800113B +:107FD000D0F85022C889103080B29047174E3060D8 +:107FE00020B9A068D0F84C0580473068A168D1F866 +:107FF0000011C989006085801031C1801048316846 +:10800000C0E900150CF0D6FDE068C068007800B14A +:1080100070BDA0680021D0F858240020BDE8704051 +:10802000104700BFAC880020BE880020AE8800202A +:1080300024250020AF8800200C0100207488002037 +:10804000C0870020B0B5234C0021A068D0F8E8001C +:108050000160A168D1F8D8000068B8B1D1F8E0207B +:1080600040681268904211DA0CF078F8A168D1F8F3 +:10807000D82012685368834204DA5060A168D1F8AE +:10808000D8000268D1F8E8000260A168D1F8DC00ED +:10809000006848B1D1F8E82013681BB15B684568F7 +:1080A0009D4201DA1060A168D1F8E800006848B18B +:1080B000D1F8E01040680968884203DABDE8B040B2 +:1080C0000BF07CBA0FF0D4FDA0680021D0F8E800D6 +:1080D0000160B0BD0C0100202DE9F041044680682C +:1080E0001F4F206297F85E00E8B197F85C00D0B9A6 +:1080F0001C480068006B8047DFF86C80D8E9105698 +:108100002A46334610F0E4FEA0FB052300FB0633AD +:1081100001FB0531C8E91221B9687B6DBA689A1A6A +:10812000411A91420CD90EF077F901212175A2680C +:108130001044E06097F85C0078B187F85D100CE0BF +:1081400001212175A2681118181A8242E16004D237 +:108150001046BDE8F04110F0BDBBBDE8F08100BFA6 +:10816000082000208C010010207C0020002840D036 +:108170002DE9F0418EB01F490AAE002503904FF063 +:1081800020080896059507918DF8185001A801213F +:108190000D901948EFF3118788F31188047A017262 +:1081A00080690C900BF018FB14494A680D98016027 +:1081B000426010604860FFF78FFF0C9846620B9694 +:1081C0000A96204687F311880BF024FBEFF3118009 +:1081D00088F311880D990A684B681A604A68096823 +:1081E0004A600D9580F311880C9845620EB0BDE889 +:1081F000F04170471185020038220020082000203D +:10820000F8B5D0E90167054611F098F90446D6F8AB +:10821000C00008B396F8F81019B9007C033801289B +:108220001FD82846FEF7F6FFD6F8C000002202232A +:10823000016805463DB12F7C033F022F28BF2B74F8 +:108240002A606D69F6E73246016052F8C81F79B1BD +:108250004A695AB11146FBE73868416821F00201CA +:1082600041602046BDE8F84011F014BC01F1140251 +:1082700010600020C6E93000C6E93400C6E93600C7 +:10828000204611F007FC06F13000BDE8F84011F07F +:10829000E3BCFEE770B5204D04462878C0B3A07C4F +:1082A000B0B360890BF066FC022801D0607978B326 +:1082B0001A482978821C0B465BB132F8025CA68909 +:1082C000AE4203D11578E67CAE4223D00632013BA4 +:1082D000F2E7821E481C4FF6FE7101381AD0931D3A +:1082E00052888A421A46F8D10C2004211880A089AD +:1082F00023F8040CE07C0A4C03F8020C20780AF006 +:108300005FFF28B9207804214FF4FA7211F0F2FBD4 +:10831000012070BD002070BD912700204C6D002011 +:1083200095880020FF2804BF4FF0FF3070472DE9EB +:10833000F84F1D4B0C4605464FF4BE21AF0004F02C +:10834000020643EA80004158C9B2914217D117484A +:108350004FEA14299A4647EA0008834611F0EEF8DE +:108360000BF10101220C88F8009039430A7048F0A3 +:108370000201220E0A7011F08DFB534605E024F035 +:10838000FF0100F5BE201143016026B945EA030054 +:1083900004F0010101700648012181EA56013843C9 +:1083A00001600020BDE8F88F002002400110084065 +:1083B000001A44422DE9F84F214CDFF880A0814695 +:1083C00000254FF0010BE8469AF80000E778C0B2AC +:1083D000A9B281422ED2A078FEB2864220D0304689 +:1083E00000214246042310F09BFE9DF800007828EF +:1083F00016D0FF2801D07E2803D130467C210CF016 +:1084000035F906EB4600E77004EB8000808BE080D6 +:108410004844B0F5005F0ED9304678210CF026F9BB +:108420009AF800005BFA87F10135B1FBF0F202FB2C +:108430001017CCE7FF27F8B2BDE8F88F9788002027 +:10844000A08000207CB50C46080426D4E00704BFB9 +:1084500000207CBD1E48007808F0C4FF054668B1C6 +:1084600001200DF107018DF80700522009F006FEEA +:108470000020002610F024FF1448867002200EF021 +:10848000F3FD38B101464570332008700F48C078BD +:1084900006F00AFE84F001007CBD0C4E307806F038 +:1084A000D5FA80B1054600780D2805D00C2806D1F4 +:1084B000284610F073FB02E02846F4F75BFC2846E0 +:1084C0000FF0D0FCEAE784F400407CBDC026002019 +:1084D0008D88002010B5044600780438052831D86E +:1084E000DFE800F0030D151E26311D480078013825 +:1084F000012827D82046BDE81040F0F731BD1848C4 +:108500000078F8B92046BDE81040F8F755B814488F +:108510000078012816D12046BDE810400EF0B4BA0C +:108520000F48007870B92046BDE8104010F0F4BB49 +:108530000B4800780138012804D82046BDE81040D7 +:1085400010F0AEBE10BD0648007820B9607F10B9AB +:10855000601D03F093FA2046BDE8104011F086BB81 +:10856000182600202DE9F0418EB0054610F0E6FFF8 +:10857000DFF87C80044669681022D8F80800D0F83B +:1085800008010068836B0AAF38469847064628BB47 +:10859000D8F80800D0F808010068016901AE30463B +:1085A00088470D2005F1080301978DF824000FCBB3 +:1085B000CDE90311CDE905320290288B0790688B35 +:1085C0000890287F8DF82500D8F80800D0E94112DE +:1085D000086811684A69314690470646204611F0FE +:1085E00059FA002E18BFE42630460EB0BDE8F081DF +:1085F0000C01002070B51E4DA868D0F8B8100A789C +:108600001C4991F900101AB1002902D41A490978BD +:1086100011B1D0F84C05804710F090FFEA68174C74 +:10862000126921781278914206D1154909784907D3 +:1086300002D411F02FFA17E011F02CFA0DF0E4FD3E +:1086400020780EF0AFFE78B1E868247806692046FD +:1086500031780BF0F7FC347030B1A868D0F8D40052 +:1086600090F9420010F027FA10F0D8FB012070BDFD +:108670000C010020B4880020A78800204C26002090 +:10868000AD880020F8B5044690F8300003282DD1BD +:1086900004F12801887C032828D11D4E0023B068EE +:1086A000D0F8D4201632D55CCF5CAF422DD1013347 +:1086B000082BF8D1D0F830244A20904767680DF194 +:1086C00002052946388810F0C9FF50209047788865 +:1086D000294610F0C3FF4B209047B7F80500294604 +:1086E00010F0BCFF53209047002100E0E82108482B +:1086F0008068D0F8F40041702A2020700448806817 +:10870000D0F8401320468847F8BDEA21F1E700BFC2 +:108710000C01002070B5044610F010FF184E0546FD +:10872000307810B1174811F068F91748007810B187 +:10873000144811F062F91548007870B914480078AF +:1087400058B91448007840B91348007828B913483C +:10875000007810B91248007820B1284611F09AF933 +:10876000002070BD0DF050FD2846347011F092F9D4 +:10877000601E022802D3034811F03FF9012070BDAA +:10878000A02700200C010020AE880020AC8800202B +:10879000AF880020B4880020A7880020AD88002082 +:1087A000B28800202DE9FE4F0446007A02280ED13F +:1087B00020888DF80A10090A04250DF108088DF8A3 +:1087C0000B108DF80800000A8DF8090001E008255B +:1087D000A0461648DFF858B00026EA4600F1080720 +:1087E0000BF10809052E1CD0207A1049022808BF79 +:1087F00059460968F140C9070ED00228394650464B +:108800002A4608BF494611F07BFA404651462A469F +:108810000FF00EFC012805D009F1040908370136D4 +:10882000E0E7FF26F0B2BDE8FE8F00BFE081002048 +:108830000885002010B5407820B11C48002180F840 +:10884000261010BD194C082084F8260094F8380032 +:1088500058B91748016809B100208847A18C052044 +:1088600005F053FFA08C09F0D5FC124800780128D0 +:108870000AD1002011F0CCF9E18A062005F045FF6D +:10888000618B042005F041FF0C4800680028D8D017 +:10889000094800780128D4D109484FF480414FF4A9 +:1088A0007A720078BDE8104011F021B9407B0020B9 +:1088B0000025002018260020BA270020842300204D +:1088C000988800202DE9F041064600888846114628 +:1088D00014460AF0FDFB7088E1796081B088A081C0 +:1088E000B079A074F079E0740820607021B1102094 +:1088F00006F1080160706161217A29B100F1080573 +:1089000030446570A06100E00546607918B1705D83 +:1089100001356570607120460DF0F8F9074688B999 +:10892000A179701951B10E30A0620848007B10F097 +:108930007FFC2844A8EB00000E3802E0A062A8EB00 +:10894000050020773846BDE8F08100BF407B00205D +:10895000BCB5044602208DF8050001A80DF090FF7B +:10896000B8B30546006904210180217A0139B1FAC2 +:1089700081F1490949014170627A012A04BF4031FD +:108980004170A27A012A19BF0120A8768031417076 +:10899000607A012804D1606808B1012169772862F2 +:1089A000E07A012804BF0120E88220880BF0E2F879 +:1089B00018B1E88A40F00400E8820120A87710F09E +:1089C0001FF90548686220886880284605F086FF00 +:1089D000BCBD1020BCBD00BFC88700202DE9FE43F0 +:1089E00080460A201E4691460F46002908BF00EB2C +:1089F00043008DF8090002A80DF042FF00B30546C0 +:108A000046EA471049462C69607009202070A01C76 +:108A100011F0B5F8BFB10126AE7710F0F1F81148AA +:108A20006C462146686240460CF0D8FF08B12C62C3 +:108A30006E772846A5F8028005F050FFBDE8FE835A +:108A40000120BDE8FE830A9804F10A01002EE2D05D +:108A500010F8022B013E01F8022B10F8012C01F84E +:108A6000012CF3E7C88700202DE9F041154610F0EE +:108A70006EFF804625B3DFF874C0DFF874E0002392 +:108A80000027BCF80060DEF80020FCB2AC420CD23B +:108A90007008862809D87444701C0137217BACF813 +:108AA0000000915523730646EFE7DCF80420AC4242 +:108AB00018BF002A06D0BCF802104FF48770904708 +:108AC0000A48426812B1A8B2002190470748002125 +:108AD000202200230180064988680C310EF0A1FD98 +:108AE0004046BDE8F04111F00EB800BF64260020FA +:108AF00048230020F0B589B0ADF8201007907BB373 +:108B000072B391B207A802AA1C4605F071FA064694 +:108B100038BB194F786808B1804728B3B86801F0AE +:108B20005FFC05461548002203230092C188C078E7 +:108B300002AAF1F733FC06460A2818D0F0B2A8B909 +:108B400002A821460222EFF7A5F9064678B9BDF83A +:108B5000141061B19DF8180007F0FCFD3E7806E0A6 +:108B60000426F0B209B0F0BD0B26FAE70126B8687A +:108B7000294604F093FFF4E7A0230020A080002002 +:108B800080B50DF05DF918480023811C1748027864 +:108B90004FF6FE703AB1C1F80230088021F8023C6D +:108BA0000831013AF6E7134A1149002312780831D7 +:108BB0002AB101F80A3B013A21F8100CF8E70E49F6 +:108BC0000E4A097819B122F8080B0139FAE70C4866 +:108BD0000C494FF47A72007808700B481021007825 +:108BE000BDE8804010F083BFE02700209ABC02005F +:108BF000D07E0020D9BC0200D2BC02004276002008 +:108C0000DFBC02001787002098880020F8B5D0E963 +:108C100000670D46044610F091FC96F8311041BBF8 +:108C20001949097829B30121A6F8311010F032FF53 +:108C30001648002D18BF284601784268012908BF50 +:108C4000002A1BD086F83010D0E90210C6E9024293 +:108C50000F4A104B3062B8683161A0F580719142C3 +:108C600038BF034606F13400736100210EF030FF77 +:108C700002E010F00FFF00242046F8BD83680022B8 +:108C8000002BDFD1F7E700BF18230020B8BA02009D +:108C900001FFFF0080A90300B0B586B00446807ACA +:108CA00058BB60680DF117016A4600F083FC01466D +:108CB000E07AC00621D49DF8170001281DD19DF847 +:108CC0001000022819D1164A002301EB4100CDE91A +:108CD000003342F8203002EB800014224360FF2072 +:108CE0006B468DF810009DF81200013000F00F0067 +:108CF0008DF8120004200DF063FB2046F9F724FBE9 +:108D0000054648B9A07A38B9E07AC00604D410F014 +:108D10004BFC6168F9F712FF284606B0B0BD00BFF2 +:108D20008043002010B586B00021C27AADF80C1047 +:108D30000188ADF80E104168049102F0400112065E +:108D400002D421B901200DE039B905200AE0807A6A +:108D5000012814BF0320002004E0807A012814BFFA +:108D6000072004208DF8140001ACAB20002122461E +:108D700006F066F80DF103012046002200F01AFC0F +:108D80000A480078012808D19DF8030028B900207E +:108D90008DF8150003A803F08CFF01208DF8150055 +:108DA00003A803F086FF06B010BD00BFB227002065 +:108DB00010B51D48007810B91C48007820B11C4837 +:108DC0008068D0F84C05804710F0B8FB19490A7844 +:108DD000022A24D10122184C0A702378062B05D8C8 +:108DE0009A4012F04C0F1CBF83220A7010F052FE02 +:108DF0002078042807D80121814011F0130F02D0F8 +:108E0000FAF77CFA207806280DD8012101FA00F043 +:108E100010F04C0F07D0BDE810400AF037BDBDE898 +:108E2000104010F037BE10BDAC880020AF88002085 +:108E30000C010020B4880020B78800202DE9F04103 +:108E400086B0DFF8708098F8650078BB012088F85C +:108E50006500C8F80480C8F800800DF041FF16488E +:108E600001AA114690E8F8000420F8C104901348C4 +:108E700008F11004124900F11C03204608F092F892 +:108E8000C8F84C400AF08AFC0E48D0E9102347F697 +:108E90009160101A73F1000031BF4FF0FF300020D5 +:108EA00047F6906110F014F8C8F8580006B0BDE815 +:108EB000F08100BF08200020CCBA0200A01F0020D3 +:108EC000C13C0100207C002010B58CB00446007A23 +:108ED000042802D110F0A4F810B1C2200CB010BDCB +:108EE000A07850B960680DF1030101AA00F062FB9F +:108EF0009DF803000028F0D0A0780021CDE90611EC +:108F00008DF82C10089140F20B11ADF81C10412186 +:108F1000002808BF612120888DF81A10ADF81800CC +:108F200006A8F6F753FB9DF82C000028D6D1099827 +:108F30001021406C0170A1784170217A817003305A +:108F4000616810F01CFE06A809F0D8FA9DF82C0004 +:108F5000C4E770472DE9F843044600206FF0010193 +:108F60004FF6FE72A04648F8040FA8F8081038F82B +:108F7000021CC8F80400914202D1C0B2BDE8F883D7 +:108F8000DFF8549000250020B9F80070BAB2A9B2F9 +:108F90009142F2D24A0012FA85F3D9F8042012F86D +:108FA00023301B0716D001EB4101638802EB8101DE +:108FB0004A8893420ED10E1D30460EF017FF01284D +:108FC00005D14046314610F0AAF9B9F80070A581E4 +:108FD00001203D460135D9E73426002070B51B4EEF +:108FE00004464FF48061307805F002FD18480921ED +:108FF00080F8261017480078022802D11648002170 +:10900000017065690FF0FCFD144928460EF04DFB18 +:10901000D8B110200EF028F8B8B105460220A16999 +:109020002870A06AB0F801206A80C07868704A2071 +:1090300009F024F8A07910B90948052101703078A9 +:109040002946BDE8704006F02FB870BD9888002012 +:10905000407B002018260020CC270020C887002055 +:10906000C42600202DE9F04188B0ADF81C10069010 +:1090700006A801AA002104F0BBFF054668BB194EF3 +:10908000706808B1804738B3B06801F0A9F9164F8D +:1090900004464FF000080323CDF80080F988F878E3 +:1090A00001AAF1F77BF9054688B9BDF810109DF8C3 +:1090B000140007F04FFBF988F878CDF8008001AA7A +:1090C0000323F1F76BF935780A2818BF0125B0683A +:1090D000214604F0E3FC00E00B25E8B208B0BDE84F +:1090E000F08100BFA0230020A080002010B504461E +:1090F0001E4849B138300068B0B1C3681B7B03F02B +:109100000F03022BF7D100E0806B68B102B1106051 +:10911000C268137B03F00F03022B08D151B1016920 +:109120008A8DC968114415E0002100201CE001204F +:10913000002119E012880169A2F60302012A4A8B74 +:109140008CBF0969496919231144094A92F86220C0 +:1091500012FB0311406B0CF0B4FC206010F034FDE6 +:109160002168B1FBF0F10120216010BD3021002009 +:10917000B87B00202DE9F84F07461E4815460E46DD +:10918000009300F138094C4624680CB1B442FBD17D +:109190004FF0000A00F1400B44B32069D4F800807E +:1091A000B84220D1204600224FF080530DF0CCFB76 +:1091B000009870B1204600224FF080730DF0C4FB80 +:1091C00030690D49086291F8240040F0010081F8EF +:1091D0002400484621460DF017FB584621460DF065 +:1091E000D7FE0AF1010A002D4446D5D15046BDE80C +:1091F000F88F00BF30210020702000202DE9F043BF +:109200008BB005AC20460EF053FC8220182122467C +:1092100010F0FCFA18480DF10808002508F10409BF +:109220000778164800F13906ECB2BD4210D207208B +:10923000214600220C23CDF800800DF0ABF830461B +:10924000494608220EF0F4FE01350028ECD004E077 +:109250004FF0FF30013CCDE903000A980290A1B223 +:1092600002AB07200C220DF0ABF80548002101806D +:109270000BB0BDE8F08300BFD7BC0200407B0020EC +:1092800004250020F0B585B005461E481E4FA9698B +:1092900000883E460C88844218BF002616D1688894 +:1092A00003A901F0BDFC01280DD19DF813209DF804 +:1092B00011009DF81210042A08BFCF2912D0542A99 +:1092C00008BFEF2911D00020002112E0297C687C22 +:1092D00048F202022346CDE90021A91C80220DF0AC +:1092E0006FFB0DE08C2802D0E9E74428EBD1112177 +:1092F0005F203971F87028462146324604F03EFA64 +:1093000005B0F0BD7087002026870020BCB504465C +:109310000022806982230192817839B3FF294FF0BE +:10932000000524D0194A0088128880B290420DD1DD +:1093300001A80CF039FC019A00230546002A08BF59 +:109340006FF07C03002818BF012510E01049097850 +:10935000022908D20FF00EF96FF07603002808BF3B +:109360006FF07E0301E00CD1802300220025D9B2EA +:109370002046FAF73FFC1DB1019808B110F052FCED +:10938000BCBD002200250023F1E700BF708700204C +:109390001826002070B588B004461E48A1690088D0 +:1093A0000E784A7846EA022282421DD18A78102A33 +:1093B00028BF10228DF80C2003AD681C03310FF07C +:1093C000E7FE812011212A4610F020FA9DF80C00BA +:1093D0001149002818BF01200A8822F0100242EA31 +:1093E00000100880002000E084208DF80900207C17 +:1093F0000DF1090148F2140203238DF80B608DF87A +:109400000A60CDE9001004F11100A11C08F00AF96E +:1094100008B070BD7087002026870020B0B588B0E6 +:1094200010F0DBFA18B304461D480078012804D177 +:10943000607900F0E7000830607100208DF80400CA +:109440006088ADF8100001AD284606F05DFD20886B +:1094500004350695ADF8140010F0A6F8ADF81C0020 +:109460006079810601D5410603D4002102E0002085 +:1094700014E001218DF81F008DF81E1005A80DF0D5 +:10948000C7FA30B128460DF09DF8284605F004FDD6 +:1094900003E0607900F0FB006071012008B0B0BD0E +:1094A000D027002070B590B06E460C46054640218E +:1094B00030460FF009FD304629460A220FF068FEBB +:1094C000D5F80A00E989CDF80A0006F10E000DF082 +:1094D000B8F8288AADF81700688AADF83B00E87F35 +:1094E000ADF82C0010F0A0FB0A9070B1EA7F296A59 +:1094F0000FF04EFE4CB10A999DF82C00A04720B108 +:109500000A9810F08FFB1A240AE007488068D0F808 +:1095100088126846884704460A9808B110F082FB12 +:10952000204610B070BD00BF0C010020F8B50C46FD +:10953000064610F003F81D4F0546B8687EB1D0F816 +:1095400094000121007802F0D7FC284610F0A2FA1E +:10955000204609F0F7FF0EF03BFB10B3F8BDD0F842 +:1095600038038047C0B105F0B3FBA8B1F868806943 +:10957000007888B9FAF70AFA0D4E307860B9B86801 +:1095800000210027D0F89400007802F0B5FC10B953 +:10959000204607F0B1FB37702846BDE8F84010F0D0 +:1095A00079BABDE8F8400BF09DBA00BF0C0100206D +:1095B000B28800202DE9F0418CB00D4601464FF6EF +:1095C000FF70ADF81A008DB381B30027082614464A +:1095D0000DF11C080420002214232F70CDE9026134 +:1095E0000DF11A01CDE900860AF028FE70B1CDE92F +:1095F000047704A80DF11A0100221423CDE9008696 +:10960000CDE9026004200AF019FE01E00120287073 +:10961000BDF81A0054B107490988884206D207A943 +:10962000204614220FF0B4FDBDF81A000CB0BDE8BE +:10963000F08100BFC6BC0200F0B589B0ADF82010C3 +:10964000079043B33AB391B207A802AA1C4604F0AC +:10965000CFFC064600BB174F786808B18047F0B1D1 +:10966000B86800F0BDFE05461348002203230092AF +:10967000C188C07802AAF0F791FE90B1C0B20A2862 +:1096800011D102A821460122EEF704FC064600286B +:1096900018BF012608E00426304609B0F0BD0B26AD +:1096A000FAE70D2600E00126B868294604F0F6F92D +:1096B000F2E700BFA0230020A0800020FEB51446E2 +:1096C0000DF1050207230D4606460FF029FD9DF812 +:1096D00005109DF806209DF8073026749DF8096056 +:1096E000A5819DF80B009DF808504FEA910C01F000 +:1096F0000301A07242EA012E9A009DF80A30B101DE +:1097000084F808C042EA9512A4F806E01F06A28079 +:1097100041EA976161720121962803F0030008BFB6 +:1097200004210843E07205F03F00800140EA960002 +:10973000E0814FEA0E3040EA0C6010442060FEBD2C +:109740002DE9FF41DFF870800C460546ADF80400B6 +:1097500002208DF80C00B8F8241001A80EF0F8F9DA +:109760001A281BD01548164900234FF6FF770278B8 +:10977000FF209A420BD031F82360BE4203D1FF286C +:1097800008BFD8B201E0AE420AD00133F1E7FF28AA +:1097900009D1B8F8241001A810F06AFA002008E0F6 +:1097A00001EB830003E021F8205001EB80004480AE +:1097B000012004B0BDE8F081407B0020D6BC02004F +:1097C0008086002070B514460E460FF0B7FE0325C4 +:1097D000052E2CD8DFE806F003090E2B161B1949BD +:1097E0008A6CCAB1896C098E02E0154991F8601043 +:1097F00021801BE01149097E0239B1FA81F1490942 +:10980000217013E00C490A68226049680DE00A499A +:109810000A681AB1D26802E0802508E000222260BE +:10982000496809B1C96800E000216160832510F032 +:1098300031F9284670BD00BF70200020D01E0020E6 +:10984000B87B002030210020F8B504460FF076FEEA +:109850001A4F05464FF0FF30386204F1B80010F09F +:1098600013F9174EB6F85600B6F85410884210D1C6 +:10987000144890F82400397E022918BF002808D027 +:10988000284610F007F9072002F0F8FF0FF056FE07 +:109890000546B6F85600B6F85410884206D10A4874 +:1098A00010F0F2F808200AF07DFF02E0012084F8B1 +:1098B000FC002846BDE8F84010F0ECB8D01E0020AF +:1098C0003021002070200020207F00201C480078DC +:1098D00030B1022810D001281CD144F2010101E06E +:1098E0004FF48041174A002811806FF0710108BFC2 +:1098F0006FF07001917014E0124844F202016FF0B1 +:109900007F02018010490978012908BF6FF07702B2 +:10991000827006E00B484FF40062018862F3DF01B9 +:1099200001800848A021094A41810021C0F8032094 +:10993000C1710173018941F430510181704700BF49 +:109940001826002026870020D5270020000050A0E0 +:10995000E0B51346062813D0052814D088BBA1F122 +:109960003A00022816D3622917D068291DD0B1F514 +:10997000817F12D040F20310814222D114491AE0B3 +:109980000093062001E005200093002210230CF034 +:1099900001FD8CBD0846012101E00846002110228E +:1099A00002B0BDE880400FF075BA07480078013872 +:1099B000012806D80549184610220FF0E9FB0020BF +:1099C0008CBD0A208CBD00BF1826002054BB0200AD +:1099D00044BB020070B504461848C168896909781B +:1099E00019B117480121017070BD164E164D31781E +:1099F0008A00B5FBF2F2A24204D28068D0F84C058E +:109A00008047317804FB01F01049096801EB8004BC +:109A10000F480068C06B8047211AA1F54871B1F169 +:109A2000FF3F05DC2918091B013148BF00F54874C8 +:109A300008482146BDE87040F7F726BE0C0100201B +:109A4000B2880020B0880020FFF6C2FF2C880020DA +:109A500030880020B16102002DE9F8431B4C1A4800 +:109A60002188868C81845020214608F007FB184805 +:109A700025884FF6FE78174C08F10109077887B161 +:109A800060892946B04208D0A84207D020461C2150 +:109A90000FF01AFA4946A4F800806181013F1C3496 +:109AA000EDE70D4C206868B106200DF0DDFA48B1F5 +:109AB0004FF4807185804180D52101702168BDE817 +:109AC000F8430847BDE8F883407B00203277002048 +:109AD000D5BC0200DC5B002054270020F8B501460D +:109AE00000681B4D0022002304882D6855B16E7B51 +:109AF000052E05D12E683688A64208BF01320133F3 +:109B00000435F2E7134C0526DBB20127D2B2258AD1 +:109B10004E734E8946F400664E810F4E3678B3423E +:109B20000E4B28BF3D461B789A4228BF3D460D810B +:109B30004FF6FF720188914205D0A18C0EF008F813 +:109B40001A2818BFF8BD0120BDE8F8400FF027BF64 +:109B500054880020407B0020E0BC0200E1BC0200F1 +:109B60002DE9FF410D4603A90DF10A0208F066FF39 +:109B7000044678BB039FBDF80A007880182010F0D7 +:109B800053F838B37988064600900620002218233F +:109B90004FF000080CF0FEFB3046294610220FF073 +:109BA000F7FA7988062018223346C6E904880CF0B3 +:109BB00007FC304618210FF087F9304610F032F8D4 +:109BC0007888064900EB400041F8208001EB8000D6 +:109BD000C0F80480204604B0BDE8F081188300205E +:109BE000F8B50746042014460E468DF80100684675 +:109BF0000CF046FE48B30546006907210170397D27 +:109C00004170797D8170B97DC17007F10B002862C8 +:109C100040F20110A5F81D000EF0F2FF0E484021A1 +:109C200068620120A87606F0FD0001280B4808BFF5 +:109C30004FF48861E982012C0088688004BF00200D +:109C40002876284604F04AFE00E0102003494FF62B +:109C5000FE720A80F8BD00BFC8870020742700206C +:109C6000B0B51020C4F209000168890733D444F666 +:109C7000B470C5F200000068810248BFB0BD40F278 +:109C8000EC11C1F2000109680124096804EB207598 +:109C90008847C0F13E00C11007220729B8BFC21093 +:109CA00041F20C30C5F200000068AA42C0F3032064 +:109CB000D8BF2A46801A0F28A8BF0F200128D8BF76 +:109CC000204646F20D2140F0F000C4F2080181F870 +:109CD0004D000878B0BDFD21C4F20001C160B0BDE7 +:109CE0002DE9F84FDFF87090DFF870B000244FF0E6 +:109CF000010AE846002599F800009BF80370C0B2FD +:109D0000A9B2814225D29BF80200FEB2864213D04E +:109D100030460021424604230FF002FA9DF800006D +:109D20007C2818BFFF2811D106EB46000BEB800002 +:109D3000808B201A00F5005499F800005AFA87F138 +:109D40000135B1FBF0F202FB1017D8E77E28EBD00B +:109D5000F2E72046BDE8F88F97880020A080002019 +:109D6000F8B51E4D04464FF0FF3128680FF008FE8D +:109D7000D4E901677168388CC5E90110796911BBB4 +:109D8000398B29440A7B013A0A7311061BD12046FC +:109D900004F070FFB92029898DF8030020460FF0E8 +:109DA000AAF80DF10300012105F00EFF29892046D4 +:109DB0000FF0AAF870680FF0BEFE388B002105EB9B +:109DC00080000161A86881B22046F6F780FE00207D +:109DD000307028680FF03AFFF8BD00BF0C24002057 +:109DE0002DE9FE438BB11D681E46804685B10FF0FC +:109DF000AEFD044628680FF0EDFE10B128680FF0A4 +:109E000043FE20460FF07FFE1BE00220BDE8FE83EC +:109E10000C2017460C46FCF7EDFCE0B1E946054680 +:109E200048460FF044FD002041464A4602958DF811 +:109E300000000190094809F097F885E8910050B1B9 +:109E40003560286841460FF0C7FE28680FF0C6FE4F +:109E50000020BDE8FE830820BDE8FE83019B0200D0 +:109E6000F8B50A461C491D4D00234FF6FE760C78C6 +:109E700002F040019C420DD035F83370874207D183 +:109E8000B04209D005EBC307BF7957407F0613D511 +:109E90000133EFE7224600E0DAB24FF6FE73984254 +:109EA00008BFA24211D10026B44207D005EBC6007C +:109EB000007928B10136F7E7DAB206E0224604E07D +:109EC00035F836000CF0A8FFF2B20020A24238BFED +:109ED00005EBC200F8BD00BFDABC0200E04C002078 +:109EE0007CB51C4616460D46042803D0022812D025 +:109EF00001282BD128460121224601F0E9F828B398 +:109F00004EB1284602F0A8FF12490978884202D2D1 +:109F1000012030701AE028460021FFF7A1FF70B140 +:109F2000817911F0180F0AD00B49438800884FF649 +:109F3000FE7200920022C98A05F06BFF08E0074814 +:109F4000214602782846F4F7E3FB08B100207CBDE7 +:109F500001207CBD9ABC0200407B0020CEBC0200E8 +:109F600070B50568D5F8F81031B3D5F858214468B4 +:109F70005668A16B20683268D16202210EF00AFD9A +:109F8000D5F85801A16B154A40680068C0F804155F +:109F900091FAA1F112683068B1FA81F192699047A3 +:109FA0000446D5F8F800011B6879022806D105F1AE +:109FB000D0000BF09DFD0BE000240CE0D5F8F40080 +:109FC000D5F8FC200A44401AC5F8FC20C5F8F40076 +:109FD0000020C5F8F800204670BD00BFD401001075 +:109FE0007FB50020ADF80C000190ADF808001420FA +:109FF0000FF01AFED8B1044618480068A0B1022636 +:10A0000001AD142E06D0A019294606220FF0C0F883 +:10A010000636F6E703A9204602220FF0B9F84C20D5 +:10A02000142122460FF0F2FB20460FF0FBFD182012 +:10A030000FF0FAFD88B1182104460EF045FF002507 +:10A04000022D07D8A9B20620182223460CF0B8F931 +:10A050000135F5E720460FF0E5FD7FBDE026002045 +:10A060001CB51B480078022831D11A4C206910B168 +:10A0700009F0CCFFFAE70EF063F9174801780829D8 +:10A0800008D0012905D101200021BDE81C40EAF7D4 +:10A0900081BBC170082101700FF012F80A200DF089 +:10A0A00027FD0E480221007804F0A2FC4FF4804006 +:10A0B00000210024F1F730FC0DF1070152208DF84A +:10A0C000074007F0DBFF08200021EAF763FB1CBD17 +:10A0D00018260020AC220020088800209888002044 +:10A0E0002DE9F843DFF874901446D9F8082002EA05 +:10A0F00001038B4221D1806843688B4220D96618C6 +:10A100006FF005059E4226D82240A24223D1006866 +:10A11000471808F013FD8046ACB10FF00FFA064661 +:10A1200038460DF090FE054630460FF0B3FC5DB9A1 +:10A13000D9F80400241A0744EEE76FF004050AE09A +:10A140006FF0030507E0002540460DF0BBF9002D38 +:10A1500018BF4FF0FF352846BDE8F883DC25002006 +:10A1600070B51C4DA968086C006828B9D1F84C0579 +:10A170008047A868006C00684068174E007800F0BF +:10A18000200030700FF0DAF9044614480178832972 +:10A1900011D13178A1B1A868016C096891F87810E3 +:10A1A00011B9D0F84C05804720460FF073FCBDE88C +:10A1B00070400BF0ABBA2046BDE870400FF06ABCAF +:10A1C0008521017020460FF065FC0020BDE870403D +:10A1D000F8F782BA0C010020C0880020B488002063 +:10A1E000BCB5044640780AF00DFA6078A0F1190178 +:10A1F000022903D3F12801D0E12809D1144D287890 +:10A2000018B900200BF0A2F8287880F0010000E0D7 +:10A2100000200F4908701048007802280BD10D4823 +:10A22000007840B9607840F00200EB2803D130207C +:10A230000021F1F771FB094863780122818C408B82 +:10A2400000920022EEF7E8FABDE8BC400CF030BE08 +:10A25000A7270020D527002018260020407B0020BB +:10A260007FB50EF007FBA8B1417B062912D101682A +:10A2700045890A7A8DF80C200C88ADF804400CF062 +:10A2800047F8280504D5002021460CF09DFC20B19C +:10A29000012000E0002004B070BD104DA98C01A881 +:10A2A0000FF0E6FC002000210CF08EFC04464FF677 +:10A2B000FF7674B120680188B142E9D0A98C0DF015 +:10A2C00047FC1A28E4D0204600210CF07DFC04460F +:10A2D000EFE700200FF063FBDAE700BF407B0020D0 +:10A2E00070B50D46242104460EF0EEFD8DB328789E +:10A2F0001A4E207068786070A878A070E878E070D6 +:10A300002879207168796071A879A071E879E07185 +:10A31000287A2072687A6072A87AA072E87AE0726D +:10A3200004F10C00E968B047287C2074687C6074F4 +:10A33000287DA07404F11300A969B047E96904F10C +:10A340001700B04795F82000E07695F821002077B7 +:10A3500070BD4FF6FE70208070BD00BFFB9A0200FA +:10A3600070B5184B2021EFF3118081F31188174C41 +:10A370001548DA6C02609C64154C1A661C64154B17 +:10A3800004689C420FD14268144B22F47F421A4465 +:10A39000426081760021C160D0F82C1221F040414A +:10A3A000C0F82C1270BD0C4D0024362CEBD00E2CB6 +:10A3B0008EBF42F8245053F8246042F824600134E0 +:10A3C000F3E700BF381F002008ED00E00020000088 +:10A3D0000020012000000000916C02000000FA053E +:10A3E0002DE9F04385B007461C480125846984B3F4 +:10A3F000666990F808800572B868012807D10025C1 +:10A400004046BD603C61FE6009F004FA21E0386915 +:10A41000A0421AD0204607F114090EF06DFB01A9E5 +:10A420000025484632466162CDE903450DF04EF9FC +:10A4300038694069864203DD38693146FBF76EFBB7 +:10A44000404609F0E7F9656203E0404609F0E2F9A9 +:10A450000125284605B0BDE8F08300BF3822002062 +:10A46000B0B592B0044600684189CA0735D021F0E2 +:10A47000010141810168086AC97F01AD2A46FEF7E2 +:10A4800021FA50BB0B990878042826D10020CDF87A +:10A490004200CDF83E00CDF83A00BDF80E00ADF810 +:10A4A00038000EA8497802308A0644BF01228DF890 +:10A4B00043200A0644BF01228DF84220490605F1D7 +:10A4C000140158BF05F1180109680FF058FB2079F5 +:10A4D0008DF844000EA80FF093FB12B0B0BD41F20E +:10A4E0009420C5F20000D0F884104FF20002C0F6AC +:10A4F000FF72114041F200020068C0F6B43291428E +:10A5000011D1C0F30332082AC0F340610ED0092AEA +:10A5100011D00F2A07D1020213D400F08072A9B122 +:10A52000A2B1112000E0FF2040B270470A200029AC +:10A5300008BF0C20F8E74FF0FF30002908BF0920C2 +:10A54000F2E70E20002908BF0D20EDE70B20002ABE +:10A5500018BF1020002918BF0F20E5E77FB505467A +:10A5600008460C460FF08DFA98B10188A94210D028 +:10A57000017904290DD80139058001290DD8144924 +:10A58000097869B1134A52F82110C1EB0111890011 +:10A5900008E00025284604B070BD6FF0010104E01A +:10A5A0000C490968002280F820208161C1610021E6 +:10A5B0006E46ADF802500125C160301D21468DF870 +:10A5C00000500EF0ACFE3046F7F7C8F9E2E700BFE6 +:10A5D000C827002060B70200B0B51D4DE868D0F86C +:10A5E000880080470EF0AAFF0446E868C06D8047E7 +:10A5F0000FF062F9496A90F942008847D5E90201F3 +:10A60000D0F8AC00896C007888470FF055F9096ED6 +:10A61000C08C88470FF050F9496E408D88470FF085 +:10A620004BF9896E4430884720460FF033FA0FF01B +:10A6300043F9096B90F843008847A868D0F83024A4 +:10A64000D0F8D40000F129015220BDE8B0401047F5 +:10A650000C010020BFB5002000210DF0C5FE134CF9 +:10A660000021206000200DF0BFFE606001AC20469C +:10A670000FF0AEF90E4D0121224628460DF0D0FE16 +:10A680000C4C25600FF0F8F821680B4A0AF03CF8F2 +:10A690000A4908700EF0A0FF09480EF0A3FF094810 +:10A6A00009490A4A09F09EFABFBD00BF24260020CE +:10A6B0005C8500204C88002050880020B98800204C +:10A6C00051B701007D8602008D52020065860200AE +:10A6D0001CB5E12903D01949097801B91CBD0189CC +:10A6E0000131018188B2884208D016480021A0F8C3 +:10A6F00070100120BDE81C4000F08EBE10480078AC +:10A700000028EBD00F4CB4F870108142E6D900203D +:10A7100000F082FE642100FB01F2B4F87010B2FB7D +:10A72000F1F21A2ADAD3084A1268002AD6D0ADF814 +:10A730000600ADF8041001A890471CBDDEBC020065 +:10A74000CA270020407B0020D4240020F8B50E4604 +:10A7500007460EF0F3FE80250446022E0AD816495D +:10A76000F0B201EB40162EB1B07A10B13068B842A9 +:10A7700005D0802520460FF08DF92846F8BD0F48FA +:10A78000017E022911D1717A4FF4A062406802EB78 +:10A7900001210B4A11430B4A114000220AF01CF818 +:10A7A0000546304600F058FCE4E7304600F054FC23 +:10A7B00002F01CFF8125DDE7B87B0020D01E0020C1 +:10A7C0000100080401FF080470B586B004468DF846 +:10A7D00016004FF6FC700D46ADF81410081A032849 +:10A7E00012D8022810D000208DF8170005A803F019 +:10A7F0002EFF06461148012104701148017008F02F +:10A8000039FD304606B070BD0220ADF806508DF817 +:10A81000040001A8FEF79EFB0126012809D1BDF81E +:10A8200006008DF81760ADF8140005A803F00FFFBF +:10A8300006464FF6FC708542DCD2E0E7DB270020BD +:10A84000DA27002070B592B0044605300DF12A01D8 +:10A850000AF0CCFB012802D0207902282ED0608893 +:10A860000BA900F0DDF9012828D10DF11A000DF136 +:10A8700003010E900BAD01AE28463246FEF79AFE5C +:10A880009DF80300D0B19DF8161006F108000DF1F7 +:10A890001A0202F0A5FF00200F95119001208DF8FB +:10A8A000420040F20110ADF8400004208DF836005F +:10A8B0006088ADF834000DA8EEF736FC12B070BD1C +:10A8C0002DE9F0410646087A0D46904601280EBF54 +:10A8D000288828460AF0B8F84FF6FE71884203D15E +:10A8E00000210846BDE8F0811249DFF84CC0002283 +:10A8F0000B786146002BF3D00F78B74210D12C7A39 +:10A900004F78012C05D1012F0AD14C88A04207D1E4 +:10A910000AE02FB94C88A04202D10C794445E0D01E +:10A920000E31013B0132E5E7C2EBC2000CEB400106 +:10A93000D7E700BFE2BC0200188700202DE9FC47E2 +:10A9400004460D4640689146DFF868A09846A16825 +:10A9500040680A8CCAF804002046CAF808200E682D +:10A9600004F088F9074610BB701903218DF8041014 +:10A97000010A8DF80700000C8DF80610BAF80810CF +:10A980008DF8050020460EF0B6FA01A8042105F066 +:10A990001BF910B14FF0FF3704E0484641460DF077 +:10A9A000F7F80746BAF8081020460EF0ADFA384618 +:10A9B000BDE8FC870C240020B0B51749CA6892692D +:10A9C00012781AB1154801210170B0BD154B144A17 +:10A9D000154D1B7812689B0003FB0024B5FBF3F2B6 +:10A9E000824203D28868D0F84C0580470F4800683F +:10A9F000C06B8047211AA1F54871B1F1FF3F05DC1A +:10AA0000291B0144013148BF00F54874084821461C +:10AA1000BDE8B040F6F738BE0C010020B288002037 +:10AA20002C880020B0880020FFF6C2FF308800206C +:10AA30004D4B020070B5194D0446287820B11848D6 +:10AA40008068D0F84C058047154E164A052CB06832 +:10AA5000D0F8D410C98C11800BD8DFE804F0030DB6 +:10AA60000D050A0D012002E00AF0A4F80320287069 +:10AA700070BDD0F84C058047022028700AF09AF883 +:10AA8000B0684FF6FF72D0F8D410CA840649D0F8E7 +:10AA9000D400C08C48860549C88170BDAE880020AE +:10AAA0000C01002046730020E87F0020E88600208B +:10AAB00070B50446B0F90E00227A81B2920702D531 +:10AAC000227B1F2A0CD8154A6368D26C52F820509A +:10AAD0009D4218BF42F820304A42E281227B0BE0BF +:10AAE0000E4B1D6D45F820400D4DDB6C53F820607A +:10AAF000AE4218BF43F82050102901D30A4902E0A2 +:10AB0000042902D3074901440A70217AC90718BFF2 +:10AB100007F02AFC0020A060002070BD381F002034 +:10AB200095F3000014ED00E0F0E300E080690278A6 +:10AB30000A70B0F801304B8002B17047C2788B8840 +:10AB400062F302038B80C278D20862F3C3038B8066 +:10AB5000C278120962F304138B806FF3DF2302794A +:10AB600002F0F80243EA02228A8022F4E0620379CA +:10AB700003F0070342EA03228A8042798A718279CC +:10AB8000CA71C2790A72027A4A72427A8A72827AE7 +:10AB9000CA72B0F80B208A81427B8A73827BCA73A7 +:10ABA000C07B087470477047B0B588B004464089D0 +:10ABB00006AD294600F034F80DF117016A46284623 +:10ABC000FEF7F8FC9DF8170070B19DF81000FD2805 +:10ABD00018BF002808D11048007828B9607A18B941 +:10ABE0006068007806280FD0607A18B9606800782D +:10ABF000072809D0207B18B960680078052805D19E +:10AC0000064841682046884708B0B0BD4FF49A70A6 +:10AC1000FCF77FF8F8E700BFB127002050240020A0 +:10AC200070B5064619480C46C08AB04206D10DF0F0 +:10AC3000E7FF014620460EF0A2FF06E00EF0A2FC60 +:10AC4000B04205D120460EF0CCFE0125284670BD4D +:10AC5000304621460AF0C2FE05460D48007800281D +:10AC6000F4D10EF079FD0028F0D1002DEED10025B1 +:10AC7000002EEBD007480188B142E7D100F118015E +:10AC8000204608220EF084FADFE700BF407B002058 +:10AC900018260020502400202DE9F04104464FF6EC +:10ACA000FE70A081207850B3184F04F104080025ED +:10ACB0004FF0000C388883B2AAB29A4221D25300D6 +:10ACC00013FA85F67B6813F82610090715D120784A +:10ACD00003EB86066188307002EB420003EB8000D4 +:10ACE0004180043041460EF01AFB3046A5810EF03B +:10ACF000FBFB38884FF0010C05460135DBE74FF0D0 +:10AD0000000C5FFA8CF0BDE8F08100BF3426002013 +:10AD10002DE9F04F85B005460C464FF6F77035B972 +:10AD2000844204D90026304605B0BDE8F08F1449AE +:10AD300008300DF10408134E4FF0010B08F104091F +:10AD40001FFA80FA0F78002FECD03079FF2814D04A +:10AD500075B170888DF804B0ADF81000404605F06C +:10AD6000D3F850B1284649460CF09FFC28B1DAE7E9 +:10AD7000544502D03088A042D5D02436013FE2E7C6 +:10AD8000E6BC0200B054002070B51B4C264630686B +:10AD900088B1017B01390173090609D121682E466A +:10ADA000814208BF2646016831600EF03BFFEEE7A6 +:10ADB00005460646EBE7104C606848B1C17E013994 +:10ADC000C176090605D10EF02DFF0020606000E07D +:10ADD0000020216801B968B1084C08214FF47A724B +:10ADE00020780EF087FE28B120780821BDE8704059 +:10ADF00003F02EB970BD00BF5C26002096880020AD +:10AE0000B0B540F2E014C1F20004206800214268AD +:10AE1000012090472068016801208847F0B14AF27C +:10AE20000000C4F20C0001884AF20445C907C4F2CC +:10AE30000C050AD14FF00121296000884FF6A0606F +:10AE4000CFF6FF702058804708E04FF6A060CFF69D +:10AE5000FF70205880474FF08070286042F2300029 +:10AE6000C4F209000068E0680068804748F2D871C1 +:10AE7000C2F200010860B0BD44F6B070C5F2000037 +:10AE80000168C90633D441F25031C5F200010968A6 +:10AE90004CF20042C3F6FF7211404CF20002C1F6C0 +:10AEA0000742914218BF704740680F220104800397 +:10AEB0004FF0000058BF081610F1240FD8BF6FF0F4 +:10AEC00023001B28A8BF1B2024300321A1EB101155 +:10AED00022FA01F122EA00004FF6FF7222FA00F096 +:10AEE00040EA01404AF21801C4F20C0108607047C0 +:10AEF0002DE9F041154F164A164B174CDFF838C0B4 +:10AF0000DFF838E0DFF838800E4D0F4E0021C0E941 +:10AF10000A11C0E90043C0E90227104A104B114C46 +:10AF2000C0E90465C0E9068EC0E908C1C0E90C4368 +:10AF30008263BDE8F08100BF29F90100CDC60100A0 +:10AF4000156D0100C5B7010065900100F58A01008B +:10AF500039960100D5F80100F5310000E19C0100AF +:10AF600061C60100F97F0200F8B51A4E0546306847 +:10AF700028B119490978A9420AD8002428E005F027 +:10AF80000FFC3068002418B313490978A9421FD96F +:10AF9000124A05EB450102EB81044FF0FF31D4E981 +:10AFA00001570EF0EDFC287870B970683968421EC0 +:10AFB0000A4209D17968814206D3B06808408142CB +:10AFC00002D10120287000E0002430680EF03EFE1F +:10AFD0002046F8BDDC250020F3BA0200A0B902002B +:10AFE00070B5184C607858BB17481849184D0022A6 +:10AFF000033020F00300091A0346E06029600E18B0 +:10B00000B34202D204C32968F9E721F00301002208 +:10B01000104E014441F8042CE82101602968EC3904 +:10B0200021F0030140F8E81F30600020FBF7E2FB4D +:10B0300001216170E168C6E9001028680438606089 +:10B0400070BD00BF44250020C588002000200120DD +:10B05000E0870020D0250020F8B505460EF06EFAF6 +:10B06000044665B3A87A50B36F7A01260CF000FD50 +:10B07000697A48B1144A48B21130536806FA00F0B0 +:10B080008343C0435360106006FA01F30F49002266 +:10B0900006FA07F02A72AA72C5E90422AA61C5E974 +:10B0A000002291F8605091F862202B4381F86030C3 +:10B0B00012B1013A81F86220C0B209F073FB204658 +:10B0C000BDE8F8400EF0E6BC08100440B87B002054 +:10B0D000F8B515460E460446012905D119480178F0 +:10B0E000204608F0E3FAA0B92046002106F056F900 +:10B0F0002946FEF7B5FE012E07D14FF6FE7750B177 +:10B100004179012907D140880AE0C8B14079B042AD +:10B1100016D10020F8BD68064FF6FE7058BF2046D5 +:10B1200008490D7886B2BE420AD03046294608F05A +:10B13000BDFA0028EDD12046A64208BF3846F1E707 +:10B140000120F8BDD0BC02002DE9F041D0E9014852 +:10B150000546D8F80000416821F002014160204610 +:10B160000EF03EFDD4F8CC0008F054FE04F130009F +:10B170000EF06EFD94F8F80018B904F16C000EF0B2 +:10B1800063FDD5E901750D4E95F83800B04795F887 +:10B190003900B04795F83A00B04797F8FB00B04740 +:10B1A00098F80C00FAF752FB04F11C000CF020FC9C +:10B1B000002084F8FD00BDE8F08100BFA52F02004B +:10B1C0002DE9F04385B01A480DF10808002708F171 +:10B1D000040490F80090174800F139054F4523D238 +:10B1E000FEB2072000220C23CDF8008031460BF080 +:10B1F000D1F82846214608220CF01AFFA0B92046B3 +:10B20000002108220DF020FC01370028E6D020465E +:10B21000294608220DF0BCFF002031460C22029086 +:10B2200002AB07200BF0CCF805B0BDE8F08300BFFF +:10B23000D7BC0200407B0020F0B58DB0451D044610 +:10B240000DF11601284609F0D1FE01282BD16088A6 +:10B2500006AE3146FFF7E4FC012824D10DF10601CA +:10B260001020099101F076FB012000270A958DF846 +:10B270002E0040F201100C97ADF82C000B4800781E +:10B280008DF822006088ADF8200008AC2046EDF76C +:10B290004BFFBDF816008DF82C700A96ADF8200013 +:10B2A0002046EDF741FF0DB0F0BD00BF8A2700201A +:10B2B00070B50D4606460EF04AFB04460EF084FCBF +:10B2C0000146B5FBF0F0022E06D0012E09D1A942AD +:10B2D0000ED91148006808E0A9420CD90E48406810 +:10B2E00003E0A9420BD90C4880680EF0C9F90DE0C3 +:10B2F0000B49094B07E008490B1D084903E00649C3 +:10B3000001F1080307490022FEF76AFD2046BDE867 +:10B3100070400EF0F8BB00BFC4250020098E02006B +:10B32000598E0200D1820200F8B51C4F06460D4628 +:10B33000F868C068007828B9B8680021D0F85824A7 +:10B34000012090470EF0FAF804460CF091FC3046CC +:10B350000EF0C0FC0646B868D0F8E010D0F8EC005B +:10B3600050F825000860B968D1F8E4100860B868A2 +:10B37000D0F8E00000680CF05DF8B868D0F8E02480 +:10B38000D0F8D800016830469047B868D0F8D404A7 +:10B3900080472046BDE8F8400EF07CBB0C01002041 +:10B3A00010B51B4C0121A06842695177D0F8D42018 +:10B3B000527B0F2A04D1D0F86401BDE81040004749 +:10B3C000D0F8A8000170E068016C20208847A068D0 +:10B3D000104A4FF47074C1688A61D0F8D430D0E953 +:10B3E00003215B7B9C4031F8131092F830305B00F6 +:10B3F0009940B1EB940F88BFA108962303EB41015C +:10B40000D0F8F03402F11000BDE81040184700BF3A +:10B410000C010020856A010070B518490A780021E6 +:10B42000012A4FF0000213D8154A02F11003154A01 +:10B430001478002264B113F80C5CFF2D05D01D8830 +:10B440001DB108B1198000E02A442433013CF1E722 +:10B450000E4C0D4B4FF6FE752478183364B133F85B +:10B46000186CAE4205D01E881EB108B1198000E0EC +:10B4700032441C33013CF1E790B270BD1826002025 +:10B48000B0540020E6BC0200DC5B0020D5BC02000A +:10B4900070B51A491A4A04460AF058FA0146E061A2 +:10B4A000012051B3002184F8200061626069B0F18D +:10B4B000FF3F1ADD60690121124A01FA00F0A06124 +:10B4C0006069157A1172116A01EBC000E0642020F6 +:10B4D000EFF3118680F3118820460DF02BFA86F3E6 +:10B4E0001188284608F096F906E00648A161214631 +:10B4F0002C30E0640CF086FF002070BD5575020012 +:10B50000FD2C02003822002070B5427C0C46017CE4 +:10B510008569227042886170A91C62802888A08099 +:10B52000A01D0EF02CFBA87A0026A073B5F80B0026 +:10B53000E66166612082687B0E35A07458B14000D8 +:10B540000EF072FB606130B10246A07C29460DF01E +:10B5500011FD054600E0A67415F8010B207658B1E0 +:10B5600040000EF061FBE06130B10246207E2946CA +:10B57000BDE870400DF0FEBC0020207670BDB0B577 +:10B5800086B00C46ADF80000002101256078CDE9B9 +:10B5900001118DF805508DF8030094F9000000F0BA +:10B5A0000C01002800F0030200F0200048BF8031A9 +:10B5B0000223012A08BF1223184408448DF8020010 +:10B5C0006846F4F703F89DF8140088B903984576A7 +:10B5D00061884187D4F80610C0F83E10617D80F87C +:10B5E0004910B4F81710A0F84B10684606F086FF13 +:10B5F00006B0B0BD10B586B004460020617800905A +:10B600008DF81400CDE901000220012918BF04299A +:10B6100023D18DF8040001208DF8050021208DF83C +:10B6200002002078ADF800006846F3F7CFFF9DF8E0 +:10B630001400B8B903980821406C0170617841701A +:10B640006178022903D1616802300EF098FA6846E9 +:10B6500006F054FF9DF8140004E0022901D10A20ED +:10B66000D7E7B32006B010BD2DE9F84304466FF0CC +:10B67000010004F10409A081608048460CF0B6FB8B +:10B68000012822D1144E00274FF0000831888AB2D9 +:10B69000B8B290421BD2420012FA87F3726812F8D5 +:10B6A00023301B070FD000EB400002EB800548461B +:10B6B000291D0BF0FAFF318828B16888A7814FF067 +:10B6C00001080F4660800137E1E74FF000085FFA9C +:10B6D00088F0BDE8F88300BF342600202DE9FF473D +:10B6E00004460120022108F0B9F92070C0B220B34D +:10B6F000C0000EF099FA00B380461348E9464FF0B7 +:10B70000010A09F104064746841C10480578B5B1C2 +:10B71000A078013801280DD820888DF800A0ADF858 +:10B720000C00484604F0F0FB20B1384631460EF0DC +:10B7300026FA07462434013DE9E74FF00008404669 +:10B7400004B0BDE8F08700BFB0540020E6BC0200A2 +:10B750002DE9F04106460C2090460D460EF064FAA5 +:10B76000044608200EF060FA94B1074680B1B8F1A3 +:10B77000000F7E807D60A7600CD028460CF072FB25 +:10B7800038460EF04FFA2046BDE8F0410EF04ABAB6 +:10B79000BDE8F081002021463870074840680EF06F +:10B7A0005FF80648016841F008010160044800683C +:10B7B000BDE8F04102F08CBE242600205088002015 +:10B7C0004C8800202DE9F04389B0109EADF8201080 +:10B7D000079046B31C4633B3154607A802AA214674 +:10B7E00002F006FC0746F8B9DFF84490D9F80800E3 +:10B7F000FEF7F6FD80460F48002203230092C18821 +:10B80000C07802AAEEF7CAFD074630B902A8294659 +:10B810002246334604F01EFE0746D9F8080041468A +:10B8200002F03CF900E00427F8B209B0BDE8F0836B +:10B83000A0230020A0800020F8B5054616484BF252 +:10B84000F521174E006800FB01F714483C0A006818 +:10B8500000F44020B0F5802F10D11248006880031A +:10B860000CD4F0680068804704F04EFF3168C96866 +:10B870008847C010390B484304EBE0342DB90A481F +:10B88000006820F07F40204444083069416C204625 +:10B89000BDE8F840084700BF08400C40B44F0050D6 +:10B8A000E00100108C13005010200940F8B5164F2D +:10B8B0001648BD6C0DF024FC044615480168066866 +:10B8C000214011F0200318BF002D0AD02846002285 +:10B8D0003D650BF039F80F484FF4804128300EF0E9 +:10B8E000B9F904EA060010F4602008BFF8BD0A495F +:10B8F00091F8612042EA504081F861000748002138 +:10B90000BDE8F8400EF0A6B93021002020000E005E +:10B910000C10044070200020B87B002028800020FC +:10B92000BFB5184D0446287820B91748018941F061 +:10B9300001010181204606F07FFBBCB1134890F85D +:10B94000410098B9287888B96C460020622100250A +:10B950002246FDF7FDFF204600210BF04BFC0020A6 +:10B96000FBF7C8FACDE90255CDE90055084C20682F +:10B9700030B128B105680EF055F925602846F8E782 +:10B98000BFBD00BF1826002026870020407B002076 +:10B99000DC26002070B51A4E044604211D4630787E +:10B9A00007F00EFC08B1012070BD07F063FC022D0A +:10B9B00023D808200EF038F9B8B1124905460868B6 +:10B9C00020B1016809B10846FBE701460D6040213E +:10B9D000307807F0F5FB01460020AC80C1F5167207 +:10B9E00009042860EA8002D070BD102070BD307854 +:10B9F00040214FF416720EF07DF8002070BD00BF9C +:10BA000099880020DC260020B0B58CB006AC182147 +:10BA100020460DF059FA154D822018212246A847DC +:10BA200001AC112120460DF04FFA3A201121224697 +:10BA3000A8473B2011212246A8470D48002180F845 +:10BA400041100C480078013801280CD80A4A4FF4FC +:10BA5000817010210DF0D4FE28B9074A4FF481708F +:10BA600010210DF0D3FE0CB0B0BD00BF0D98020048 +:10BA7000407B00201826002044BB0200F0B585B0B2 +:10BA800080B3194FFC686CB305461CB3A61C29464D +:10BA9000082230460CF0CCFA08B9E468F5E7B8683B +:10BAA000A8B102AD31460822681C0DF071FB05F10A +:10BAB0000A01304609F0A9FF0120092100220C23C8 +:10BAC00000958DF808000948007807F0D4F9204661 +:10BAD00005F02EF8F86828B904484FF400610078A2 +:10BAE00002F086FF05B0F0BDAC2200209F88002048 +:10BAF0002DE9F0410446007A012801D1258803E0B0 +:10BB0000204608F0A1FF05464FF6FE70854208BFAB +:10BB1000BDE8F0811048471C104806781048B0F87E +:10BB200000809EB1217A3878012902D1012801D004 +:10BB300009E040B9B7F80100A84204D1781E414697 +:10BB4000FF220DF0BBF90E37013EEAE72846BDE8BB +:10BB5000F04105F039B800BF18870020E2BC0200B0 +:10BB6000C2B4020070B505460DF0E8FC164E04465E +:10BB7000B068D0F8E010D0F8EC0050F8250008606C +:10BB8000B168D1F8E410086010480068C06B8047C5 +:10BB9000104AB1681368D1F8E01063B90C4B1B78F8 +:10BBA0009B00B0FBF3F50868854204D9B5FBF0F5BE +:10BBB00068435843106008680BF03CFC2046BDE821 +:10BBC00070400DF067BF00BF0C01002030880020DE +:10BBD000B08800202C880020BCB51A4900200968D4 +:10BBE00011B104310130FAE7C5B268000EF01CF85B +:10BBF00018B3144904460020096831B131F8042B08 +:10BC0000C3B2013024F81320F6E70F49B1F86E00F3 +:10BC1000CA8A904207D101F1390200212B460094D3 +:10BC200002F026F906E001F1390200212B460094CA +:10BC3000FCF7D4FE20460DF0F5FFBDE8BC400BF04C +:10BC400017BE00BF40270020407B002000B1704796 +:10BC5000B0B51A4CE06C58B340F2000CEFF3118011 +:10BC60008CF311882020EFF3118180F31188D4E93F +:10BC70001650E16CB1FA81F1C1F11F0100EBC10175 +:10BC80008D4215D2086802680A6051600A688A42CB +:10BC900004D1416AE26C22EA0101E16401F048FA50 +:10BCA000E16C29B1E06DB1FA81F1C1F11F01E5E765 +:10BCB000002084F84800BDE8B0407047A01F002075 +:10BCC0002DE9FF41044604201E4690460F468DF89C +:10BCD0000D0003A80AF0D4FDC0B1054646B101200D +:10BCE000AF80A8770020E876287840F080002870A0 +:10BCF0002869390AC1700321877080F801800170BA +:10BD0000204607F037FF18B100200AE001200DE0BF +:10BD100001AE2046314609F061FE0028F4D02E62C3 +:10BD20000120687728466C8002F0D8FD04B0BDE899 +:10BD3000F081B0B58CB0044601206D4611213A2344 +:10BD40008DF81E0020882A46ADF81C006068099016 +:10BD500000200CF035F928B1684611210DF0B4F837 +:10BD6000002001E09DF8000001218DF81F00681CF3 +:10BD700025898DF8291008900DF016FC854202D116 +:10BD80000020002106E02089ADF8140060680690CC +:10BD900005A901200B918DF82A0007A8EDF7C4F939 +:10BDA0000CB0B0BDF0B589B0054600200C460121AD +:10BDB000ADF810200890CDE905504FF6FC708DF8D5 +:10BDC0001E108DF813408DF81210101A032811D888 +:10BDD00002280FD000208DF81D0004A8EDF7A4F96B +:10BDE0000646284621460BF005FA07F043FA30468E +:10BDF00009B0F0BD02206F46ADF802208DF80000BA +:10BE00003846FDF7A7F801260128EAD1381D8DF83C +:10BE10001D600690E1E77047BFB50568174A687A6C +:10BE2000012807D11268686990F82110406992686A +:10BE3000904714E068696C4690F821101068826899 +:10BE4000204690476869416990F82120204608F013 +:10BE50009DFA08B1686801E06FF003006860084867 +:10BE600040210160802101600021C0F8FC12022005 +:10BE700008F07EFC03480DF0E9FEBFBDFC01001098 +:10BE800004440240307E0020F8B506680D460446A2 +:10BE90000DF054FB16490978012902D196F82210B9 +:10BEA00019B10DF0F7FD00241FE0012786F822707C +:10BEB0000DF0F0FD0F49002D18BF294648680A789B +:10BEC0007060002086F82020022A4FF0000208BF90 +:10BED0008A6886F8240086F8250086F82370B26008 +:10BEE00086F826000A20F9F723FF2046F8BD00BF98 +:10BEF0009927002004BB020070B5194A194C103272 +:10BF00002378002918BF0121002573B112F8106CA5 +:10BF100005F00105864206BF11700E4616783543BE +:10BF200018BF01251832013BEFE7A078E90708D0D8 +:10BF300098B90120012609F039FA022009F036FAF1 +:10BF400008E0012809D1012008F012FC022008F0C5 +:10BF50000FFCFF26A0783044A07005F0010070BDF2 +:10BF6000B46E0020442500202DE9FF41194F4FF603 +:10BF7000FE764FF000086C464FF6FE7080B2B0427D +:10BF800024D10DF0E9FC0546F88A85424FF6FE7093 +:10BF9000F4D00DF0F7FA85424FF6FE70EED0284649 +:10BFA00007F0E8FD00284FF6FE70E7D1002D4FF6B0 +:10BFB000FE70E3D020468DF80080ADF80250FCF70B +:10BFC000C9FF002818BF35462846D7E704B0BDE8AA +:10BFD000F08100BF407B00202DE9F843194E044654 +:10BFE00000274FF0D3084FF6FF79366836B3E08963 +:10BFF000F18881421AD1A07C20300BF035F800285E +:10C00000F3D02146202205460DF0C2F8A27C2AB1C9 +:10C0100005F12000A861A1690DF0BAF83079294630 +:10C0200085F8008003F040F80127DEE74945DCD1C0 +:10C0300001B20029DFD41328D7D1DCE7F8B2BDE87C +:10C04000F88300BF682700202DE9F843194C099FA9 +:10C050008146884611461D4660683E7A0DF08FFD88 +:10C06000089905700A0A41708270397AC170397A6C +:10C07000012908D003290AD104300A9D39460DF060 +:10C080007EFD057003E039780171797841711020E7 +:10C090000C2341464A46A070012E08BF0E232046BD +:10C0A000032E08BF152303F0B7F90021A170BDE8E6 +:10C0B000F88300BF7C2600202DE9FC4118200DF0FC +:10C0C000B3FD60B3044617484FF00008002700F1A5 +:10C0D0000806032F1AD03078012814D1BDB20620EB +:10C0E00000221823009429460AF054F958B956E959 +:10C0F000020118222346C4E90401062029460AF059 +:10C100005FF986F800800C360137E2E720461821F7 +:10C110000CF0DAFE2046BDE8FC410DF083BDBDE821 +:10C12000FC8100BF18830020F0B585B0194EB268BD +:10C13000116F91F82B1059BBD2F8D410897839B30C +:10C14000C168007AD2F88821904708B30446B068E5 +:10C15000016F91F82B2042F0040281F82B20D0F8D7 +:10C160005C1302AD28468847F0680127816A0120E8 +:10C170008847B0682A46D0F87863016FD0F8D400B9 +:10C18000C38C01F120002146CDE900700520B047A5 +:10C1900005B0F0BD0C01002070B517480D22002439 +:10C1A00001680131B1FBF2F303FB1211134A52F89B +:10C1B000213042F82140016011490868C01A086026 +:10C1C000F8F7C8F90F4D2E780DF0FEFC04462869EB +:10C1D0000DF000FD00B170BD002E1CBF4AF200360C +:10C1E000C1F2E116B6FBF4F128690DF0F5FC2869FF +:10C1F000BDE870400DF0F2BC14880020488100209A +:10C200001C880020B824002010B51648816829B188 +:10C21000154908308968D1F8541288470DF08EF915 +:10C22000124900240A6813681C7112680A600DF034 +:10C2300031FC0F48017811B90E49097849B10470F1 +:10C240000C48047004F018F80748C168C9680978F8 +:10C2500001B110BD80680021D0F858240020BDE84D +:10C2600010401047242500200C010020C08700202A +:10C27000AC880020AF88002010B514480068C06B5F +:10C28000804714491248144A09780068890001FB64 +:10C2900000F4B2FBF1F1884204D910488068D0F86C +:10C2A0004C0580470E480168214401600D48214437 +:10C2B000F5F7EAF909488068D0F8E40480470DF002 +:10C2C0003DF9BDE810400DF0E5BB00BF308800200F +:10C2D00038880020B0880020FFF6C2FF0C01002043 +:10C2E0002C880020B161020070B568B115460E4679 +:10C2F000044604290AD0022E11D0012E04D10120B7 +:10C3000009F0ACFA114905E0C12070BD042009F024 +:10C31000A5FA0D490978884284BF112070BD0C49E7 +:10C320000020258166736060086820B1416809B10A +:10C330000846FBE7011D07480C602021007801F04A +:10C3400087FE002070BD00BFE3BC0200E5BC020018 +:10C350005488002098880020FEB5044614486D4695 +:10C36000046028460DF034FB124E002000212A46BE +:10C370008DF8000030460CF053F80F4F07F13405EC +:10C380007E6028460DF072FA0C480521BC630C4C07 +:10C390004FF440620023BA642A46C7E910100949E5 +:10C3A00020460AF0C5FCBC600CF0DBFDFEBD00BF02 +:10C3B0005C27002040850020882100208037002055 +:10C3C000D87C0020014B00007CB5044606981D4631 +:10C3D0000B46362902DB174A00210AE012491646AD +:10C3E000124AE381096E51F82310914207D00021CF +:10C3F0000F4A0091002108F063FD01207CBD184622 +:10C4000005F090FF286969682073C4E90016287A4E +:10C41000A060297D11B140F00200A0602046FEF727 +:10C4200047FB00207CBD00BF381F0020916C02003C +:10C43000B3AF02006FB1020010B596B0184C2020C7 +:10C44000EFF3118180F31188E06810B90AF04DF91B +:10C45000FAE7E068216A134A0223B0FA80F0C0F1DB +:10C460001F00137501EBC002E26151F8300000219A +:10C470002174A06140F2000CEFF311808CF311885D +:10C480002020EFF3118180F311880CF00DFDA169DC +:10C4900068461C301C310AF037FC16B010BD00BFD6 +:10C4A00038220020381F00202DE9F041B3F1FF3F72 +:10C4B00003DC5B42B1F1FF3F24DD4FF0000C4FF095 +:10C4C000010EDFF85080471E0026B1FBF3F505FB97 +:10C4D000131418F80440BC55013E8B422946F4D988 +:10C4E0003044714230230138914203DA00F80139B7 +:10C4F0000131F9E7BEF1000F0CBF80F800C0013038 +:10C50000BDE8F081013A49424FF02D0C4FF0000E8A +:10C51000D7E700BFC7A2020070B511B3154602B33A +:10C5200006680C4606F069FCB0680DF0ADFA47F6F7 +:10C53000FF704FF6FF71854238BF28468D4218BF05 +:10C540004500A6F8585060080FD04FF47A7100FBF0 +:10C5500001F40DF039FBB4FBF0F1A04288BF0121DA +:10C5600004E0BDE870400BF018B80021B068A6F8F0 +:10C57000561089B20DF030FBB0680DF02FFB022091 +:10C5800086F8500070BD7047B0B5056804460CF0E1 +:10C59000D5FF002185F8241095F82120033A022ABE +:10C5A00028BF85F825100DF075FA0F488168B1F1A4 +:10C5B000FF3FDCBF4FF0FF31E9610C4901602046CD +:10C5C00007F0F8F995F82000022804D10848BDE8E2 +:10C5D000B0400DF03BBBD5E9002CE96995F821305E +:10C5E0002046BDE8B0406047884702400100008017 +:10C5F000807E0020FEB5876A04467E7801ADB91CB6 +:10C6000028460DF0BCFA1548294639300BF04DF894 +:10C61000B8B11F2E12D806F01F0568000DF004FBFC +:10C6200078B1064607F10A0000218D420AD000EBDE +:10C630004102128826F811200131F6E7D320FAF7DB +:10C6400068FBFEBDA089009601AA00212B4601F0DF +:10C650000FFC30460DF0E6FAFEBD00BF407B002027 +:10C66000F8B5174E706808B1804730B3B068FDF771 +:10C67000B7FE144F044600253978E8B2884206D246 +:10C68000FBF77EF83178013508433070F4E70E4F40 +:10C6900000203578F8707870481E7E21B870B88B0D +:10C6A000F880002007F0E2FFB878FE2107F0DEFFF7 +:10C6B000B068214601F0F2F900E00B252846F8BDEC +:10C6C000A023002097880020A0800020F0B587B02C +:10C6D000ADF81810059033B32AB31C466B461146CB +:10C6E00005A81A4601F084FC0546E8B9114F7868A0 +:10C6F00008B18047D8B1B868FDF772FE06466846B3 +:10C7000021460022EBF7C6FB054638B9BDF80C10F0 +:10C7100021B19DF8100004F01DF83D78B86831464D +:10C7200001F0BCF900E00425284607B0F0BD0B2558 +:10C73000FAE700BFA02300202DE9FE4F1648174E50 +:10C74000DFF85C904FF6FF774FF00208EB464FF0B2 +:10C75000FF3A0A240578E5B13088B84216D07188CE +:10C7600071B10139718089B2B1FBF4F202EB82023E +:10C77000A1EB420151B90CF0DBFC0BF0E9F905E04B +:10C780000CF0D6FC0DF074FAC6F800A00436013D9A +:10C79000E1E7BDE8FE8F00BFD6BC02008086002026 +:10C7A000407B00202DE9FC41E84604464146FEF767 +:10C7B00037FA30B31448DFF854C000210078CFB204 +:10C7C00087421BD2FB0053FA81F363441B7AC3B147 +:10C7D00007EBC707C3F10806F5B2674408EB050687 +:10C7E0002F4435783A78AA4206D1013B07F1010778 +:10C7F00006F10106F5D104E00131E0E72046F6F745 +:10C8000053FEBDE8FC8100BF8E270020186A00207F +:10C8100010B586B0184C00218068CDE90411CDE92F +:10C820000211019402A9009105A904AA03ABF2F731 +:10C83000E5FF05994FF6FF720988914201D00C4639 +:10C8400017E00399002918BF01210140012904D1F3 +:10C85000029911B101AA084602E050B1049801AA58 +:10C860002B210BF00FFCFF2803D00198204000F192 +:10C870000044204606B010BDFFFF3F0070B50546DE +:10C880000CF05CFE174E044696F82400A84386F888 +:10C890002400306820B1B8300DF09CF9054600E066 +:10C8A0000025706818B1B8300DF094F9054396F87A +:10C8B000240030B92DB9306A18B190F828108907D2 +:10C8C00004D42046BDE870400DF0E4B8456A204627 +:10C8D0000DF0E0F8306A022100220024A8473462FB +:10C8E00070BD00BF7020002070B5B0B00FAC8421C7 +:10C8F00020460CF0E9FA154803A90A4690E86800BA +:10C90000042068C28DF82800CDE9014102F050FCF6 +:10C9100001A80AA9FCF77AF998B106AD0C490446BA +:10C92000142228460CF0FEFD204629460DF098F909 +:10C93000054620460CF0B4F9002D18BF4FF0FF3526 +:10C9400001E04FF0FF35284630B070BDA0BB0200BB +:10C950001C86002010282FD1FEB5184E0C463078CA +:10C960008DF804000DF032F905460DF02DF96843FD +:10C970004FF47A77B0FBF7F08DF805000DF026F94B +:10C9800005460DF021F96843B0FBF7F0000A8DF879 +:10C9900006000CF035F901AD01460222E81C0CF04E +:10C9A000F7FB002000212A4640230094ECF730FFDB +:10C9B00020783070BDE8FE40704700BF91880020AD +:10C9C000F8B5184DA87808B1012429E00DF103014C +:10C9D000E12009F027FB144E9DF803100024307E5F +:10C9E00081421DD001270DF1020152208DF8024035 +:10C9F000AF7005F043FB307E0B380F2804D806F1EA +:10CA00001801E12005F03AFB0DF1020152208DF8EA +:10CA1000027005F033FB002000240CF051FCAC70D8 +:10CA20002046F8BDC0260020407B00207FB504468C +:10CA30001748184E00783178084302D1608800B159 +:10CA40007FBDA0690578FF2D08BFFE2528460AF0A6 +:10CA50001FFF8DF80F000CF0E3FA10B1284609F023 +:10CA6000FFFF307810B9284609F0FAFF207B002834 +:10CA7000E6D100200DF10F0148F236020123CDE985 +:10CA8000001004F11100A11C04F0CCFD7FBD00BF1B +:10CA9000AF270020182600202DE9FC410020ADF82A +:10CAA000040014200DF0C0F840B3DFF854800446B1 +:10CAB000D8F80000F8B100264FF6FE770025122EB8 +:10CAC0000DD08119A019062202300CF061FBD8F8B4 +:10CAD0000000815BB94218BF01350636EFE7ADF8BB +:10CAE000045001A9204602220CF052FB4C201421D4 +:10CAF00022460CF08BFE20460DF094F8BDE8FC8138 +:10CB0000E026002010B50DF0D5F809F0F9FF134C20 +:10CB1000A068D0F8D40090F843000AF055FCA06853 +:10CB200000210024D0F858240120904704F0BEF8DA +:10CB30000AF00EF8F9F764FC09481221C0E9004434 +:10CB4000846008480CF0C0F9074804700748047076 +:10CB5000F8F7C0F8BDE810400CF074B90C010020E3 +:10CB60004C87002094860020A6880020A5880020FD +:10CB7000B0B5174C6068216801EA000521EA00029F +:10CB8000680622601DD51348006800F44000B0F527 +:10CB9000000F03D11048006807F0D0FD04200CF00E +:10CBA00075FD811E022905D207F0A8F8022007F0C2 +:10CBB000DFFD03E0012808BF07F0A0F8202008F0FF +:10CBC00035FE280648BF04F0C7F9A560B0BD00BF18 +:10CBD00090220840B44F0050D02600202DE9F041AB +:10CBE0004FF02008EFF3118188F311880122144FD0 +:10CBF00011490D7A0A72114991F8486081F848206C +:10CC00000021104A3C7D3975396D1268D2B251F855 +:10CC10002210886040F2000CEFF311808CF3118831 +:10CC2000D1E900018847EFF3118088F311883C7542 +:10CC300046EA0520BDE8F08138220020A01F002030 +:10CC4000381F002004ED00E0F8B541680A780F2A8B +:10CC500013D0082A1FD0062A1CD140894A1C0292F0 +:10CC6000ADF80400B1F80900ADF80C00C87A8DF8F1 +:10CC70000E0001A806F03CF98FBD40898A1CADF872 +:10CC8000040048780A31029203918DF8060001A849 +:10CC9000EFF7D0FD8FBD4089ADF8040048788DF8DE +:10CCA0000600022804BF881C029001A806F002F9C1 +:10CCB0008FBDB0B586B0044600202121CDE900002B +:10CCC00002904FF48670ADF804002088ADF80000A3 +:10CCD000607A0028684608BF01218DF80210F2F73B +:10CCE00075FC9DF8140098B90398456C062005F86A +:10CCF000010B616828460CF042FFA0782872E078AA +:10CD00006872207AA872684605F0F8FB9DF8140056 +:10CD1000217A002908BF084606B0B0BD2DE9F04FC2 +:10CD200089B006468800994690460F1D4FF0000BCB +:10CD30000DF1040A8DF80300380415D0B8B23C4652 +:10CD4000B1B25246202828BF2024A5B248462B461F +:10CD50000CF0E6F95FFA8BF051462A460BF09CFA8C +:10CD6000834626443F1BE7E75FFA8BF00DF1030192 +:10CD700001220BF091FAB0EB080018BF012040002F +:10CD800009B0BDE8F08FF0B540F6FF7C10F8013B2C +:10CD90000024082CFAD00646DF0716F8015B0AD1FA +:10CDA000467806F00F070337122F0AD187783A0624 +:10CDB00009D403300DE001F8015B304601345B0813 +:10CDC000E7E7023006E0C27807F07F07043047EA61 +:10CDD000C2171237320942EA0515654508BFF0BD92 +:10CDE000ED43002FEAD04A5D013F0A700131F8E7B8 +:10CDF00089B36FF0C0020B0E02EA8112202B05D01E +:10CE0000212B05D0A02B05D1302118E0102116E0F0 +:10CE1000202114E0B1F1807F01D240210FE0102BDE +:10CE200005D0112B05D0402B05D1702107E05021F2 +:10CE300005E0602103E09021502B08BF80211143C1 +:10CE400041F00F0104C8531C18BF8A42FAD14FF0B9 +:10CE5000FF3140F8041C7047B0B51749174A00234A +:10CE60000978994206D002EBC3046488844203D057 +:10CE70000133F6E70C4600E0DCB24FF6FE73984251 +:10CE800008BF8C4201D02046B0BD0024A14204D08E +:10CE900012F8340018B10134F8E70C46F3E702EB5E +:10CEA000C405E4B268686B800028ECD00CF0BAFED0 +:10CEB00000206860E7E700BF9ABC0200E02700207E +:10CEC00070B50468616F59B3D4F858214568566845 +:10CED000E96B28683268D16201210BF05BFDD4F860 +:10CEE0005801E96B0F4A40680068C0F8041591FAD0 +:10CEF000A1F112683068B1FA81F192699047616FCF +:10CF0000091AE07C20B104F14C0006F04BFF05E06B +:10CF1000206FA26F401A20675018A067002060673A +:10CF200070BD00BFD40100101CB5002008F06AFEDF +:10CF30000CF03AFB04460BF063FE01460F48002359 +:10CF40008278204606F0D6FF002008F05BFE0D48F0 +:10CF50000078022810D10A48007801280CD16C46CC +:10CF600020460CF03EFD0CF00DFB07490B780749FD +:10CF70000A78214602F040F81CBD00BF2687002039 +:10CF8000BA27002018260020C0270020C227002032 +:10CF90002DE9FC4114200CF047FE40B3044615482F +:10CFA0004FF00008002700F10806C82F1AD030788B +:10CFB000012814D1BDB20420002214230094294674 +:10CFC00009F0E8F958B956E9020114222346C4E9E8 +:10CFD00000010420294609F0F3F986F800800C3698 +:10CFE0000137E2E72046BDE8FC410CF01BBEBDE87E +:10CFF000FC8100BF8043002070B50CF09FFA164DF5 +:10D000002E782978012902D10CF044FD0EE001218F +:10D0100029700CF03FFD1148C168C968097829B929 +:10D0200080680021D0F85824012090470CF04EFE73 +:10D0300004460CF083FA04B92E700CF02BFD07485F +:10D04000C168C968097829B980680021D0F85824D6 +:10D0500000209047204670BD162500200C010020BE +:10D06000F8B5174E154D044631682868496D884754 +:10D070006040B0F1FF3F07DC124FB868D0F8D40031 +:10D0800090F8830001280BD10CF03EFC832808BFE8 +:10D09000F8BD0C488068D0F84C05BDE8F840004762 +:10D0A00009F0B2F80CF030FC832803D0B868D0F84F +:10D0B0004C058047BDE8F8400BF0B0BED8260020F4 +:10D0C000308800200C01002010B5184C0021A06809 +:10D0D000D0F8E8000160A068D0F8D8100968B9B1AC +:10D0E000D0F8E02049681268914211DA07F036F86A +:10D0F000A168D1F8D82012685368834204DA5060DE +:10D10000A168D1F8D8000268D1F8E8000260A068F0 +:10D11000D0F8DC10096841B1D0F8E80002681AB113 +:10D1200052684B68934200DA016010BD0C01002088 +:10D130002DE9F047164C002100F12C03154D4FF05E +:10D14000010A80F8281084F848100ECBD4E914891D +:10D15000A76D2E7DC4E91503226585F814A001632F +:10D1600040F2000CEFF311818CF31188D0E9053205 +:10D17000C169104698472020EFF3118180F3118890 +:10D180002E7584F848A0C4E91489A765BDE8F08726 +:10D19000A01F0020381F00202DE9F84380461548C5 +:10D1A0001549DFF858900078002818BF0120087052 +:10D1B0000024312C08BFBDE8F88309EBC40039F81E +:10D1C000347046884568384631462A460CF018FBCC +:10D1D00068B93846B8F1000F04D031462A460CF041 +:10D1E00015FB04E0002132462B460BF053FE0134C0 +:10D1F000DFE700BFB2270020C488002010AA020089 +:10D20000B0B58EB001AC0546342120460BF05CFE73 +:10D21000D5F8020029690022CDF80E00287D0B9177 +:10D220004FF6FF71ADF8001069468DF82000287F99 +:10D230008DF80900288DADF81400287E8DF80A00BD +:10D24000687E8DF80800688DADF8320095F82C00E6 +:10D250008DF83400FF208DF802002046E9F7EAFB44 +:10D2600000200EB0B0BD7CB5054600EB4000144672 +:10D270000E4602308DF8050001A809F001FB18B335 +:10D280000169082201F8022B05F01F02324301F860 +:10D29000012C0022D3B2AB420ED2237801320B70A4 +:10D2A00063784B70E678A378043406F0070663F3DE +:10D2B00006168E700331EDE7012181764FF6FC7181 +:10D2C000418001F00BFB7CBD01207CBDB0B5056841 +:10D2D00004460CF033F9A97819B1BDE8B0400CF060 +:10D2E000D9BB002169700CF0D5FB0E488168B1F103 +:10D2F000FF3FDCBF4FF0FF3169600B490160204602 +:10D30000FEF78AFD287A022804D10848BDE8B0401B +:10D310000CF09CBC6B7AD5E904C269682046BDE874 +:10D32000B04060478847024003000080807E0020B4 +:10D330001CB50C46097F052904D104F10801FDF74D +:10D340006FFC18B304F108000DF106010BF092F820 +:10D35000BDF806004FF6FF71884204BFA1201CBD36 +:10D36000217801290FD10A4A00EB400102EB81012B +:10D37000A26951F8043F9A423CBFA2201CBDA08282 +:10D38000501C086000E0A08200201CBDC8201CBD0D +:10D39000188300202DE9F04385B01548154F00266D +:10D3A0004FF0FF080DF104090024007800EBC000E5 +:10D3B0008500B54218D0B81990F82110802910D1F5 +:10D3C000B95980F8218010224B46019141680291A1 +:10D3D000017D80698DF80C100490A1B2032008F043 +:10D3E000EFFF24360134E4E705B0BDE8F08300BF69 +:10D3F000E6BC0200B0540020F8B50D480D49FF22EC +:10D400000088097841430C480BF058FD0B480C4943 +:10D410000C4A0D4B0D4C0E4D0E4E0F4FC1610021AD +:10D42000C0E90176C0E90354C0E905320170F8BDD6 +:10D43000C2B40200E2BC020018870020EC230020E6 +:10D440009D4502008D050200FD250200F91B02002A +:10D45000F1BA0100D5600200F5ED000010B5154AE3 +:10D46000212074210CF0CCF90A38B0FA80F044097C +:10D4700005F064F80A28104808BF02340078012833 +:10D4800004D805F09BF80A2808BF04340B4801684B +:10D4900019B188470A2808BF083405F0F9FF0A289F +:10D4A00008BF103404F0E2F80A2808BF20342046F0 +:10D4B00010BD00BF407B002018260020FC23002068 +:10D4C0002DE9F84305461548DFF8549088460024B6 +:10D4D00000F1140699F80000C1B28C4228BFBDE8E3 +:10D4E000F883FF2D08D156F8107C0CF095F987428F +:10D4F00009D099F8000003E016F8141CA94202D0E4 +:10D5000018360134E8E70CF022FA31680A6822EA9A +:10D5100008020A60BDE8F8430CF0F5BAB46E0020CA +:10D5200044250020B0B51448144D807B95F839117E +:10D53000084306D00CF002F895F83B1121B10CF02D +:10D54000A9FA00242046B0BD012485F83B410CF027 +:10D55000A1FA022007F02AFF0D20F8F7E9FB08489E +:10D5600001680029EED1074940220A604A60002183 +:10D5700085F83A11C461E4E790BA0200D81B002094 +:10D5800004800C4038500C4079B36FF0C0020B0E91 +:10D5900002EA8112202B05D0212B05D0A02B05D12A +:10D5A000302118E0102116E0202114E0B1F1807F35 +:10D5B00001D240210FE0102B05D0112B05D0402BBC +:10D5C00005D1702107E0502105E0602103E09021A2 +:10D5D000502B08BF8021114341F00F0104C8531C98 +:10D5E00018BF8A42FAD140F8041C70471CB5154890 +:10D5F000017E022904D11920BDE81C400BF040BD7A +:10D60000017E01291DD0007E04281AD00BF096FF60 +:10D61000044601A8F9F7CEFB28B101990A4831B1B7 +:10D620000BF080F80AE008480CF02EFA06E00CF047 +:10D630002BFA0648042128300CF00CFB20460CF095 +:10D6400029FA1CBDD01E0020647F0020702000201D +:10D65000B0B54FF0FF300BF04BFD104D04461049B4 +:10D66000E86988420DD10F480F4900220BF0C0F93C +:10D670000220287607F0B2FE18B9FAF793FAEAF713 +:10D68000EFFE0A48044208BFB0BD09484FF0005100 +:10D690002830BDE8B0400CF0DDBA00BFD01E00203D +:10D6A0002D37000030210020D10C01000200004085 +:10D6B00070200020F8B5174F06460D46F88AB04294 +:10D6C00001D1012405E0304629460023FEF7F8FA8F +:10D6D00004463046002103F061FEF98A884216D1E3 +:10D6E00028460021FCF7BCFB68B1817911F0180FC6 +:10D6F00009D04388F98A00884FF6FE720092002212 +:10D7000002F087FB03E02846012109F053FC204684 +:10D71000F8BD00BF407B00202DE9FF41144DD5E945 +:10D7200000673879F8F704FB0BF008FF04463078FF +:10D73000B0B90DF1040840460BF09AFCB87979793C +:10D740000C4A434601950290301D05F049FC3868AB +:10D750004FF0FF31C16208498160012131704160A1 +:10D7600020460CF097F9024804B0BDE8F08100BFF4 +:10D7700044BC02008B9902000018002010B5174B22 +:10D780000C0A5B68597000219C701970117801F0C7 +:10D790001F01D9705178197191785971D1789971A7 +:10D7A0001179D9715179197291795972D179997226 +:10D7B000117AD972517A1973917A5973D17A99730E +:10D7C000117B00F11102D973811C104648F202024C +:10D7D0001023BDE8104001F01FBE00BF7C260020D2 +:10D7E0002DE9F04385B050B3144642B30DF104085F +:10D7F0000E46054640F20110002110220027434644 +:10D800000BF048FB06F00F062046C6F1100908EBA6 +:10D8100006014A460BF0BCFC04EB090041463246C7 +:10D820000BF0B6FC082F0AD0E85DE15D4840E11935 +:10D83000E0550A7AE85D013750400872F2E705B01A +:10D84000BDE8F083F8B50D4609881446074609F08F +:10D850002FF908B1B820F8BD114806780BF098FAF6 +:10D86000B04224BFB220F8BD18200CF0DDF9A0B101 +:10D87000064607710020294612223060B01D0BF0C9 +:10D8800087FC0848016811B108460968FBE7066093 +:10D890000CB106F083FB0020F8BD1020F8BD00BFDE +:10D8A000CDBC0200EC260020F8B505460020164F3E +:10D8B0000C462860F868C068007828B9B86800216C +:10D8C000D0F85824012090470BF038FE0646284631 +:10D8D00021460BF0FBF821462046006828B142683B +:10D8E0006B68934201DB0146F7E70D602860206812 +:10D8F000A84203D1B868D0F8D40480473046BDE8C8 +:10D90000F8400CF0C7B800BF0C010020E0B5174983 +:10D91000FF238868426913764269D37E012B16D1B2 +:10D920000021D176C16BC97AC1B1FF218DF80710F2 +:10D93000D0F8D41091F84320B1F85210ADF805108A +:10D94000D0F8D4138DF8042001A888478CBDD0F8F6 +:10D95000D400427B90F82C00904200D18CBDC86866 +:10D96000406C8047BDE88C4009F040BD0C010020B0 +:10D9700010B5164900220C2A0BD08B1804325B8894 +:10D980008342F8D188181249097800F8041CC52090 +:10D9900010BD00224FF6FE730C2A05D08C180432FD +:10D9A00064889C42F8D108E000220C2A04BFC720FA +:10D9B00010BD8B5C0432002BF7D11144044A21F8CE +:10D9C000020C0020127801F8042C10BD34870020CE +:10D9D000DDBC0200C10714D1010715D4C10616D45D +:10D9E000810617D4C10418D4810719D441071AD469 +:10D9F00041041BD4002110F4204F08BF4FF0FF3129 +:10DA000016E00C48016813E00A48416810E0094834 +:10DA100081680DE00748C1680AE00648416907E0EF +:10DA20000448816904E00348C16901E001480169D3 +:10DA300008467047F082002010B51548007802288B +:10DA400022D112480078F8B94FF6FF700021EDF7A7 +:10DA500063FF104C012040F6B831A04708204FF476 +:10DA6000DC71A04710206421A04720206421A0473A +:10DA70004FF480504FF47A71A047074A352028218F +:10DA8000BDE810400BF0C2BE10BD00BFD52700207E +:10DA900018260020DD460100F082002070B5174AEC +:10DAA0000546906910B30123147A137209BBE96823 +:10DAB000426905F11406914202DAE968F8F72EF896 +:10DAC0003068B04213D06869016869614E6080684F +:10DAD00028614169E9602021EFF3118581F3118804 +:10DAE000294607F0D3F985F3118802E070BD0120C3 +:10DAF000A8602046BDE8704005F08CBE38220020AA +:10DB0000B0B58AB01048C178D9B901250F4924228F +:10DB1000C57001AC20460CF0F3F84FF400708DF89E +:10DB200024500D4D0D4922460023069008480590CB +:10DB30000020049007480190284609F0F9F80848A9 +:10DB400045630AB0B0BD00BFA01F0020C0B80200EE +:10DB50001868002085A20200307D0020B59B0200DD +:10DB60003822002021F003010844009940F8083CC5 +:10DB700040F80C2C40F8041C029940F8101C019944 +:10DB800040F8141C0F4940F8181C4FF0FF3140F8C2 +:10DB90001C1C40E9091140E90B1140E9131140E94F +:10DBA000111140E90F1140E90D1140F8781DC0E94D +:10DBB0000911C0E90111C0E90311C0E90511C0E96B +:10DBC000071170471D8902002DE9F041077B0446CB +:10DBD0000D20884600EB4700C5B228460CF024F81B +:10DBE00008B306462078211D3070701C0BF0C7FF6B +:10DBF000A07804F10E013A467072E078B072607B52 +:10DC00003773F07206F10D000AF008FD48F080004D +:10DC10002A463346C1B2452004F030FD3046BDE807 +:10DC2000F0410BF0FFBFBDE8F0812DE9F041044663 +:10DC300008200BF0F9FF10B305462078C71C02201E +:10DC400050FA87F8404609F00FFA6860A0B1FE214B +:10DC5000FFB2017021463A46686801300CF050F876 +:10DC60006E683946701C0AF0F9FDB9194870002039 +:10DC7000A5F80280287003E028460BF0D3FF0025AA +:10DC800020460AF0EFF82846BDE8F0812DE9F04182 +:10DC9000D0F8A8501F4616468846044625B12046AF +:10DCA000414632463B46A847D4E928010F4006408A +:10DCB00056EA070008BFBDE8F081204641468022B1 +:10DCC00004F0AAF8C4E92C6740B1D4F8A810816028 +:10DCD000D0E90812B143BA43C0E908120020C4F8E1 +:10DCE000A80004F15000BDE8F0410BF0AFBF70B5E3 +:10DCF00020220D4604460BF04BFAA87C0026E66174 +:10DD0000666160B140000BF08FFF606130B1AA7CAA +:10DD1000696952000BF03CFA002600E00126287EDB +:10DD200048B140000BF080FFE06128B12A7EE9692C +:10DD300052000BF02DFA4EB1606908B10BF072FF82 +:10DD4000E06908B10BF06EFF002070BD012070BDCE +:10DD500070B5044613480168F1B1114E3068D8B16E +:10DD60000E4D2868C0B160888847A8B90E48007871 +:10DD700030B10E4951F82000C0EB0010810001E0E5 +:10DD80000A480168608832689047012804D1608899 +:10DD90002968BDE87040084770BD00BF9C23002083 +:10DDA0009423002088230020C727002060B70200AA +:10DDB0007FB50BF0C3FB114E04463078C8B901ADF6 +:10DDC00028460BF055F900200E4A27212B468DF8E6 +:10DDD0000C004FF0FF300290094805F001F90A48A5 +:10DDE0000121012509F074FE0848002109F070FEA8 +:10DDF000357020460BF04EFE7FBD00BF9A270020F5 +:10DE0000B484002093820100307E0020807E0020B8 +:10DE100070B588B0134E0D460446C22096F8261001 +:10DE200004291CD008291AD086F82E50B46201A803 +:10DE3000182104300BF048F802208DF809500194A5 +:10DE400086F8260001208DF808000748007802288F +:10DE500002D106480021017001A800F081FE08B03F +:10DE600070BD00BF407B002018260020CC2700207A +:10DE70002DE9F84FDFF854B00646DBF8000010B388 +:10DE80000E20DDF828801C4691460D4600EB43002D +:10DE900009F0EAF8B8B1074605714680D420494632 +:10DEA0004FEA440A3870781D0BF069FE07F10E0046 +:10DEB000414652467C730BF06BF9DBF80010384694 +:10DEC000BDE8F84F0847BDE8F88F00BF5027002095 +:10DED00070B504468069A16A4D788E780BF0D1FD4B +:10DEE00088B10179013901290DD801210E2D14D8ED +:10DEF0009EB9002101750C4935B151F82510C1EBCF +:10DF00000111890001E070BD09680122C0E9061114 +:10DF100080F8202005F0AEF9002104480278A0899D +:10DF2000BDE8704001F082BC60B70200CC27002041 +:10DF300070B5154E04464FF6FE713088884221D1E7 +:10DF4000162009F091F8E8B10546A07902210028D1 +:10DF500008BF0121697001202870A06A4078A8726A +:10DF6000000702D4A08903F0A1FCA169A81C0BF052 +:10DF700006FE00202946E8740448007801F094F871 +:10DF8000A089308070BD00BF7427002098880020D1 +:10DF9000F8B50D4606460BF0DAFC134F0446387808 +:10DFA00008B100251BE0B5F5877F07D906F5877016 +:10DFB0003861A5F587704FF4877501E0002038615E +:10DFC000B8800A4831462A460BF09AFE0120387084 +:10DFD000786901307861284606F02EFB0546204618 +:10DFE0000BF091FD2846F8BD702400203872002007 +:10DFF00070B50023B3EB113F1CBF052070BD037843 +:10E000003F2B84BF092070BD44880026B6EB942FB7 +:10E010001CBF072070BD8588B6EB952F1CBF08205C +:10E0200070BD0A480078032804BF032070BDD18169 +:10E03000962100201372D4809580917221039081E3 +:10E0400041EA03612943116070BD00BF88270020A9 +:10E050002DE9F84305461448DFF85080894603212E +:10E06000002400F10C0798F80000C2B2944218D2C4 +:10E0700017F80C2CAA4211D10BF069FCB9680646BE +:10E0800038680A6842EA09020A6008B10BF09BFC92 +:10E0900030460BF038FD98F80000002118370134A5 +:10E0A000E3E7C8B2BDE8F883B46E00204425002041 +:10E0B0007CB5154E0446B07808B1012521E00DF17C +:10E0C0000701E12007F0AEFF9DF807000025A04200 +:10E0D00017D00120B07001200BF0F2F80DF106010D +:10E0E00052208DF8065003F0C9FF204603F07AF95C +:10E0F00038B1064801216422047030780BF0FAFC34 +:10E10000BA2528467CBD00BFC02600208D8800208F +:10E1100080B51348007802280BD001280BD088B9AD +:10E120001148022181700F48018821F00701018008 +:10E1300080BD022000E001200A490A8822F007027F +:10E140001044088009480AF091FE0028064819BFCB +:10E150004FF44171A0F801100021817080BD00BF13 +:10E160001826002026870020C42600208E87002045 +:10E1700070B50546807C0C2826BFA869C67A0026A3 +:10E180000E2000EB46000BF04FFD044618B1AD69C0 +:10E190002878207008B1204670BD201D691C0BF046 +:10E1A000EEFCB5F8090060800020002E2073F2D04C +:10E1B000E87A04F10E012073287B607305F10D00ED +:10E1C0003206E8D030F8022B013E21F8022BF7E7A7 +:10E1D000F8B5144D044612484FF6FF762988B1422F +:10E1E00002D111490978298007684FB17868017810 +:10E1F00021B140680178204604F0C0FD3F68F4E793 +:10E200002888B04203D0C1B2204604F0B7FD0BF01D +:10E21000CBF906490880BDE8F8400AF0F1BC00BF20 +:10E220002088002076270020968800207087002014 +:10E230002DE9FF41DFF84C80074613480D4616468E +:10E240003946D8F8044009F030FA0F21002818BFE9 +:10E2500002218DF80C100D4900282046098808BFBE +:10E260006FF00201ADF8041039460BF088FC4670DF +:10E27000057001A9404600220A2301F0CDF804B040 +:10E28000BDE8F0817C260020C88700207087002030 +:10E290007FB5154E307828BB04208DF80000134858 +:10E2A000C08AADF802000AF0ABFC6D4601462C1D99 +:10E2B00020460BF034F82846F3F750FB0BF062F9D8 +:10E2C0004FF6FE7188420BD0BDF80210884207D08D +:10E2D000ADF8020020460BF084FB6846F3F73EFBE6 +:10E2E000012030707FBD00BFEC230020407B002068 +:10E2F00070B5154E01211C461546F068C0680170C6 +:10E30000F06880690078022803D0B068D0F84C0526 +:10E31000804705F0020004F0885140180AD00B48ED +:10E320000178013901700021F0688069017009F0FD +:10E330006FF803E0B068D0F84C058047F068002122 +:10E34000C068017070BD00BF0C01002019250020BD +:10E35000B0B5164CA06800F1D8030ECB1568D0F804 +:10E36000E024186809684042904755B1A168686880 +:10E37000D1F8E01009688842A4BF401A68602D688F +:10E38000F3E7A068D0E9381212680B68934207D00F +:10E390000A60A068D0F8E000006809F04BF8A068B7 +:10E3A000D0F8D404BDE8B040004700BF0C01002005 +:10E3B00070B5164E0446F068C068007828B9B06899 +:10E3C0000021D0F85824012090470BF0B7F80546FB +:10E3D000B068D0F8F824D0F8D8102046904730B96B +:10E3E000B068D0F8DC10D0F8F82420469047B06828 +:10E3F000D0F8E8000068A04203D107F0EFFEF9F77B +:10E4000021FE2846BDE870400BF044BB0C01002003 +:10E410001249134A096892F82620002918BF0222DF +:10E42000D2B2062A05D0052A07D10F49096899B149 +:10E4300008470C49096879B1084721B1897902294F +:10E4400004D0012904D140780BF0DCBBFDF7C4BB3C +:10E450000649096801B10847704700BFCC26002073 +:10E46000407B0020FC240020F8240020782300209A +:10E470002DE9F047054615488A464FF0FF394FF021 +:10E48000000804686768BC421DD026462468307DB9 +:10E490000028F8D06DB1F06850450AD1306918B144 +:10E4A00030625044F06001E086F81480D6E906102E +:10E4B0008847307D0028E6D0F068A0EB0A00484588 +:10E4C00038BF8146DFE74846BDE8F08708200020D6 +:10E4D000B0B5164A0121147A11722022EFF311858A +:10E4E00082F31188024652F8143F93420FD010680D +:10E4F0000368136001745A60C16809B100220A758B +:10E500008068294606F0C2FC85F3118808E0017C8A +:10E51000C90706BF418A01310121418285F3118873 +:10E520002046BDE8B04005F075B900BF3822002094 +:10E5300070B5144E2021B06DEFF3118581F3118871 +:10E54000F16CF26DB1FA81F1C1F11F0102EBC10171 +:10E55000884210D20C480121047A01720B4809F05C +:10E56000BDFC002086F84800204685F31188BDE8F0 +:10E57000704005F04FB9002086F8480085F31188F7 +:10E5800070BD00BFA01F00203822002069030200D8 +:10E5900010B5044681680079FFF75AFD207B00B171 +:10E5A00010BD20680BF070FA0F480168A14207D037 +:10E5B0000A69A24201D01146FAE722690A6101E024 +:10E5C0002169016000212161416829B1086908B110 +:10E5D0000146FBE70C6100E04460044841680078B4 +:10E5E000BDE81040FFF734BD6C2600202C2600202B +:10E5F000B0B50446C068256990F8381001F00301F1 +:10E6000001290ED1297C61B9416C0A78052A08D10B +:10E6100049780322062908BF0222012908BF0222E5 +:10E620002A740021297090F84810A97090F84210BF +:10E630000069E97068600AF0E3FA014605F1080034 +:10E640000BF09DFA2069F6F7ABF82075B0BD10B558 +:10E6500086B0044600200121CDE9000002904FF46D +:10E660008170ADF804002088ADF80000E078012842 +:10E67000684608BF21218DF80210F0F7A7FF9DF82A +:10E68000140088B903980921406C0170A178417089 +:10E69000208805F06FFA10B103980421C182684602 +:10E6A00003F02CFF9DF8140006B010BDFEB5047CED +:10E6B00000F11C03012201256CB11E78F70718BF79 +:10E6C00016F00C0F01D1002502E0760748BF0022AA +:10E6D0000833013CF0E7037A0BB1002413E0012D6D +:10E6E00018BF0129F9D101248DF808204179827AD7 +:10E6F0000472C0888DF803108DF80420ADF8060070 +:10E7000068460AF023FA2046FEBD70470F280ED84F +:10E7100040F20252DFE800F014101210080D081049 +:10E7200010100D100810100D4FF2011208E01E28F5 +:10E7300002D141F2011203E0002201E04FF48172A4 +:10E7400031B1FF2907D14FF203101040C03008E06B +:10E7500042F0300005E0C8070CBF42F0200042F054 +:10E760001000000400F203707047704780B50C4938 +:10E7700008700C48002101700B480C490088088083 +:10E780000B480C490BF0FBF90B480C4901600C4895 +:10E790000C4900780870BDE8804007F075BA00BFEA +:10E7A0009588002094880020782700202E7E002065 +:10E7B0008E870020B4260020DC870020AC260020B5 +:10E7C000B427002093880020F8B50446134800259C +:10E7D000061D134807783046394639B110F8242B06 +:10E7E000013A022A38BF01350139F6E7280611D06F +:10E7F000E8B240000BF018FA60B1014667B1327818 +:10E80000013A012A9CBF36F8042C21F8022B243649 +:10E81000013FF3E7002000252570F8BDB05400202B +:10E82000E6BC020070B50646807C0930C5B22846B9 +:10E830000BF0FAF918B30446B0782070F0786070E5 +:10E84000307BA070B07BE070F07B2071307C607119 +:10E85000707CA071307DE071707D207204F1090040 +:10E86000B27CB1690AF094FC4520FF212A46234678 +:10E8700003F004FF2046BDE870400BF0D3B970BD33 +:10E8800070B506468078032101EB4000C5B22846EA +:10E890000BF0CAF900B304463078207070786070CD +:10E8A000B078A070706870B1E11C0022B3789A4211 +:10E8B00009D210F8023B013201F8023B10F8013C8A +:10E8C00001F8013CF2E74520C4212A46234603F023 +:10E8D000D5FE20460BF0A6F9002070BDB0B5044669 +:10E8E000144890F8261004290AD0082908D0217865 +:10E8F00001F00301012908D121690978062904D111 +:10E9000061884FF6FE72914201D1C22508E0C08AAB +:10E91000814201D1207F40B12046E7F76FFF0546D5 +:10E9200020460BF07FF92846B0BD2046FEF768FC74 +:10E93000F5E700BF407B0020B0B58AB0114DC5E9B6 +:10E9400000011148426001AC20460AF0EDFE0320B0 +:10E950002146ADF820004FF4E130079001208DF8FA +:10E96000180040F20110ADF8040008480390084870 +:10E9700002900020ECF704F9A86006F06FFC0AB0E2 +:10E98000B0BD00BF4823002064260020FD6F0200B8 +:10E99000698A010020291CBF6FF0010070477CB517 +:10E9A00004464068114EA1684068098CC6E901011F +:10E9B000204600F05FF988B9C72031898DF807003B +:10E9C00020460AF098FA0DF10700012101F0FCF849 +:10E9D0003189054620460AF097FA15B14FF0FF300D +:10E9E0007CBD204600F046F97CBD00BF0C24002011 +:10E9F00070B50D4606460AF0AAFF04463046294681 +:10EA000009F0D6F890B1054600680BF03DF828688B +:10EA10000AF07CFD0C490868854209D00169A942C9 +:10EA200001D00846FAE72969016103E0022505E003 +:10EA30002869086028460BF0F5F8002520460BF001 +:10EA400062F8284670BD00BF6C2600202DE9F04119 +:10EA500004461348DFF84C800027002600F1080523 +:10EA600098F80000874217D215F8080CA04210D180 +:10EA7000284608F0BEF90646286828B1F8B24FF4D7 +:10EA80000041FFF7E5FA04E0F8B24FF40041FEF769 +:10EA900017FD18350137E3E73046BDE8F08100BFC8 +:10EAA000B46E00204425002070B50446807861686B +:10EAB0000A5C0D1802F0070262700A5C2846042105 +:10EAC000C2F3C102227410F8016B07F027FD052183 +:10EAD000A061B006217704F1080004D40021C0E948 +:10EAE0000011052005E0691D0BF049F8207F083072 +:10EAF0002077217C012904D1C1B20130695C2077E3 +:10EB0000A17570BDF8B506461148012714460D469B +:10EB100047700720F7F70CF9022006F047FC312078 +:10EB2000314609F031FA0B480321002241600168A7 +:10EB300021F0030165F3000165F34101016006481E +:10EB40002146006803680020984704480760F8BD24 +:10EB5000182300200C800240CC010010A802504273 +:10EB600070B58AB000266C4605462821867120467D +:10EB70000AF0AAF904F1190005F10B010B220AF0C1 +:10EB800007FB28680B490860204629680AF0B5FF92 +:10EB9000A888ADF81360ADF81100D5F80700CDF8DE +:10EBA000150005488068D0F87C142046884700206E +:10EBB0000AB070BD008800200C0100201CB5154C67 +:10EBC00010200DF106018DF80600A068D0F8302461 +:10EBD0005A2090474FF4FA70ADF80400A068D0F8BE +:10EBE000302401A95520904707200DF103018DF82D +:10EBF0000300A068D0F830245920904709200DF177 +:10EC000007018DF80700A068D0F83024E020904775 +:10EC10001CBD00BF0C01002010B513490446487804 +:10EC200008B1486A10B900204870086A09F0F2FD7E +:10EC30000E48006840B10E480078012808BF002C3B +:10EC40000BD0642000210AE00CB1032000E0052075 +:10EC50000021BDE81040E5F79DBD64200121BDE81D +:10EC60001040EFF7E9BD00BFAC2200206C27002068 +:10EC7000182600202DE9F8430446144E05200DF116 +:10EC800003080DF10209A5688DF8030031892046BB +:10EC90000AF031F94046012100F096FF4846012173 +:10ECA00008F076FF3189074620460AF02DF94FB962 +:10ECB0009DF80200C00705D0686A0028E6D00AF077 +:10ECC0002BFCE3E73846BDE8F88300BF0C240020A6 +:10ECD0000E48007888B90E48007870B90D48007861 +:10ECE00058B90D48007840B90C48007828B90C484C +:10ECF000007810B90B48007808B1002070470A4826 +:10ED00000078B0FA80F04009704700BFAC8800205E +:10ED1000AF880020B4880020A7880020AD8800209C +:10ED200016250020A32700201725002010B5044633 +:10ED3000812804D310488068D0F84C0580470AF039 +:10ED4000FDFB0E490C700C498968D1F8B8100A789F +:10ED50000B4991F900101AB1002902D40949097828 +:10ED600019B10AF097FE012010BD0AF093FEBDE82C +:10ED70001040F9F7D3B800BF0C0100204C2600204A +:10ED8000B4880020A788002080B50AF0D7FB134A7A +:10ED90000023117813708A070CD4490719D50AF09B +:10EDA00079FE0F4800218068D0F858240020BDE883 +:10EDB000804010470AF06EFE0948C168C9680978AA +:10EDC00029B980680021D0F85824012090470AF022 +:10EDD000B5FBBDE880400AF05DBE00BF8C88002016 +:10EDE0000C0100202DE9F843044613484FF6FE7944 +:10EDF000124D09F1010806786FF00100013087B269 +:10EE0000BEB12888A0420DD1A81C08F0EFFF68B958 +:10EE100065B128461C210AF057F8A5F80A80A5F824 +:10EE2000009003E0BC4201D14845EDD11C35013EC4 +:10EE3000E6E7BDE8F88300BFD5BC0200DC5B00203C +:10EE400010B51446AB2808D0A2280CD0A32812D0A5 +:10EE5000A12817D10F48008811E00B48016820460F +:10EE60000AF08DFE0CE0094802685AB108462146B6 +:10EE7000BDE8104010470648016819B18847208056 +:10EE8000002010BDB52010BDDC87002034240020F8 +:10EE9000F42300202E7E0020BFB50AF0F2FD90B1D1 +:10EEA0000546408801242421FF228DF80040ADF85A +:10EEB0000C0028460AF002F8802085F821006846F8 +:10EEC00005F052FB00E000240020042104F0C6FD00 +:10EED00005490978884204D2044801210170F5F7F8 +:10EEE000C1FC204604B0B0BDE6BC0200872700206C +:10EEF000F8B50AF02CFD1349002200230025002458 +:10EF0000886048680668A6B1B6F1FF3F05DD5BB1D1 +:10EF1000176835443744176009E0AC4238BF2C46C7 +:10EF200086F00046002302E00123024635463044C5 +:10EF3000E8E788680AF0E7FDA54288BF2C4620462E +:10EF4000F8BD00BFD02500201CB501784478827838 +:10EF5000FB298DF806408DF8072001D304200DE031 +:10EF600004F01F01152908D80C4A52F8211021B1CC +:10EF700088478DF8050018B90EE001208DF80500CE +:10EF800004F0E000202807D10DF1050360200021E6 +:10EF9000032203F073FB1CBD1CBD00BFE021002059 +:10EFA000B0B588B0134D0446286808B101201EE0B2 +:10EFB00008200AF039FE2860C0B12168016021797B +:10EFC0000171B4F80510A0F8051001AD1821281D35 +:10EFD00009F07AFF2068019020798DF809006079A6 +:10EFE0008DF808002846FFF7BBFD00E0102008B0B0 +:10EFF000B0BD00BFCC2600202DE9F8438046032099 +:10F000001E46144689468DF80100684607F038FC14 +:10F010000125B0B1074600690B218670447001706C +:10F02000BD7709F0EDFD084800217D77BD76A7F892 +:10F030000280C7E90890054801703846FFF74EFC8A +:10F0400005462846BDE8F883C8870020972700209A +:10F05000B0B50C480C490D4AC0E904210C490978A7 +:10F06000C90702D1816951B9B0BD0A4A0D490C4D99 +:10F07000094B0A4CC0E90615C0E908438262BDE8A5 +:10F08000B04008477423002079750200914D0100BB +:10F09000CC270020A93401007D1202004197010015 +:10F0A00039C7010071790200F8B511B3044612485E +:10F0B0000D46A0F11001114800780130013804BF5D +:10F0C0000320F8BD01F11806097CA1423146F5D1B3 +:10F0D0000AF03DFC07463046294607F00DFC204665 +:10F0E0004FF40041FEF7B4FF38460AF00CFD002053 +:10F0F000F8BD0520F8BD00BFB46E002044250020F7 +:10F10000B0B5124949684A68D2E90115D46860B1BE +:10F1100055EA040005D00E480022C2610D4A503263 +:10F12000026021B1F0F751FA01E001B1884755EAD8 +:10F13000040008BFB0BD09F08BFD05B1A84704B1BC +:10F14000A0470448BDE8B04008F0B2BBD01E002084 +:10F15000001004400100070670B58AB01C46154631 +:10F1600002460B46002006AE102805D0295C81F02F +:10F17000360131540130F7E7304601210094EAF7B7 +:10F1800047FB02A8214610220AF002F800201028AE +:10F1900005D0295C81F05C0131540130F7E700941F +:10F1A00006A802AA01218023EAF732FB0AB070BD4B +:10F1B00070B50AF0C3F9104E04463078B0B90F4D5F +:10F1C0000F4A31210023284603F00AFF05F11C00F5 +:10F1D00006F110010422082309F0BAFE094A4FF093 +:10F1E000FF3001210125FFF78DFC35702046BDE879 +:10F1F00070400AF04FBC00BF18230020742200208A +:10F2000091E3000080A9030080B51248007805282A +:10F210001BD108F08BFF062008F06AFC0E4800782E +:10F2200001280AD80D48008800F00700022804D001 +:10F2300000200021002209F053FF04F01BF8F9F729 +:10F24000DDFFBDE88040FDF76FBEBDE8804004F003 +:10F2500011B800BFC42600201826002026870020F1 +:10F260007CB5856904460421284607F057F90E4B02 +:10F2700029796A7902250126009040F20110ADF843 +:10F28000050068461D72094D8DF804102E70084D5A +:10F290002A70627C074D2A7062881A80FFF780FE10 +:10F2A00008B108F0E5FA7CBD84870020AB27002078 +:10F2B000C3880020C2880020F8B5144F14460546C4 +:10F2C000069A079E8DF8031078680370130AC670BB +:10F2D0004270837036B108990430324609F058FF05 +:10F2E000301D00E0042048F20601C3B20DF1030016 +:10F2F0002A46691AB1FA81F149090901B970214612 +:10F3000000F08AF80021B970F8BD00BF7C2600200B +:10F310001FB504461348406842700170207A0F28D8 +:10F3200001D0022814D120884FF6FC71401A03281E +:10F330000ED802280CD002208DF80C000AF034F907 +:10F34000ADF80400074801A93622022300F064F852 +:10F35000044821463622022304B0BDE8104000F0E4 +:10F360005BB800BF7C26002070B586B00C46134900 +:10F370000546114800780978084301D1012019E0B9 +:10F38000BDB1B4B1284601F0ADFB064605F1100051 +:10F390000AF046FC86420CD102AE002000212A462B +:10F3A00090230096EAF734FA30462146F3F706FA3E +:10F3B00000E0022006B070BDAC2700201826002017 +:10F3C0002DE9F047DDE90897DDF828A080461C46C6 +:10F3D00015460E463846C4B1B84208D140463146BB +:10F3E0004A463B46FBF7AAFA0146002071B92A7843 +:10F3F00019F80010BAF1000F18BF11408A4207D166 +:10F4000001350136013C0130E5E70020BDE8F08719 +:10F410006FF00600BDE8F08770B588B004460020A4 +:10F420000F260133CDF81A00ADF81E00CDF81600F6 +:10F43000087A8DF81C0008880B49ADF81400207874 +:10F440004D6805F8010D88780331CDE90051074971 +:10F45000CDE9020605A8E8F721FC10B921780131B1 +:10F46000217008B070BD00BF7C26002094250020CC +:10F4700010B50446812804D30F488068D0F84C05A5 +:10F4800080470AF05BF80D490C700B498968D1F888 +:10F49000B8100A780A4991F900101AB1002902D46B +:10F4A0000849097811B10AF0F5FA03E00AF0F2FA16 +:10F4B000F9F7A0F8012010BD0C0100204C26002017 +:10F4C000B4880020A788002010B5114CA068D0F89F +:10F4D0005C028047B8B10F4900222223CA814A75D5 +:10F4E0000D4A4B8212780A75A268D2F8D42092F89D +:10F4F000243092F831200A74084A4B741278504331 +:10F500008000C86110BD1C20BDE81040F3F7E4B8CE +:10F510000C010020A0830020B5880020B0880020C6 +:10F5200010B50AF00BF80F490F4C49682268914258 +:10F5300002D00E4A12781AB1BDE810400AF0AABAF9 +:10F540000B4A92F90020002AF6D40A4A1278002ABF +:10F55000F2D121600AF09EFA2068BDE81040FDF764 +:10F560007FBD00BF4C26002028880020AF880020E7 +:10F57000B4880020A7880020B0B511488068D0F872 +:10F580001814D0F8D40090F85300884740F6387526 +:10F59000042808BF43F66C450AF0D9F90446094827 +:10F5A000007845430AF010FBB5FBF0F00649074B25 +:10F5B0000022FAF715FC2046BDE8B0400AF0A3BAD5 +:10F5C0000C010020B0880020517C02002027002080 +:10F5D0002DE9F84381461248884600240025861C00 +:10F5E00010480778BC4218D2280616D1304608F0D9 +:10F5F000FDFB70B136F8020C002541464845304607 +:10F6000008BF0A2508F051F8002818BF65F05F050B +:10F6100000E000251C360134E4E7E8B2BDE8F883D9 +:10F62000DC5B0020D5BC0200BCB50D461349044686 +:10F630004089097839B11049C98A884203D1BDE8A7 +:10F64000BC4000F0C5B90021FAF70AFC60B180792E +:10F6500010F0180F08D02B8D627F6189A0896C8E05 +:10F66000009400F0D6FBBCBD6189A089002202B0E5 +:10F67000BDE8B040FEF71EB8407B0020BD2700204B +:10F6800000B5EFF3038212F0FF0F0DD06A46A2F12E +:10F69000200282F309886FF0020E10604FF0807133 +:10F6A000D1610B49916170475DF804EB694681F3C4 +:10F6B000098880F308884FF00200EFF3148180F38B +:10F6C00014880448016821F040410160704700BF80 +:10F6D000A8F6010034EF00E0F8B50E46044609F044 +:10F6E0002DFF0546D4E90101814205D128460AF0E3 +:10F6F000D1F94FF0FF30F8BDE3682168A26901330A +:10F70000B3FBF0F707FB103702FB071031460AF096 +:10F71000F7FAA0686169E7600130A060884288BF9D +:10F720000146284661610AF0B5F9A068F8BD70B5D8 +:10F73000054600780C46164608220870687848701E +:10F74000A97840EA01106070E878A070297940EA51 +:10F750008100A070697940EAC100A070A97940EAEF +:10F76000C110E91DA070E01C09F012FD04F10B00AE +:10F7700005F10F01032209F00BFD0F2E24BFA87C19 +:10F78000A07370BD70B506680D46044609F0D6FE3C +:10F790000F490978012901D1317819B10AF07AF9B4 +:10F7A000002413E0012131700AF074F90948002D9A +:10F7B00018BF2846017842683172326102290CBFB5 +:10F7C00080680020F0600A20F6F7B2FA204670BD8B +:10F7D00098270020F4BA02002DE9FF41124C0025C1 +:10F7E0004FF0FF360DF104080027208881B28F42C8 +:10F7F00028BFBDE8FF8161684A57B2F1FF3F0FDCC7 +:10F800004B19D0B210F07F00187003D14346039615 +:10F81000CDE90166B9B201200C2206F0D1FD2088A5 +:10F820000C350137E2E700BF34260020FEB5044660 +:10F83000032017460E468DF8090002A807F020F8AD +:10F8400005460120C5B129690C228F704E700A70DF +:10F85000A87709F0D5F909486E4631466862204616 +:10F8600006F0BCF810B101202E62687701206C8090 +:10F87000A8762846FFF732F8FEBD00BFC8870020F3 +:10F88000F8B5124D0446002629880844B0F5877F54 +:10F890000AD90F48C1F587770844B9B202F04EFF84 +:10F8A0002E80E41B00213E4609480844A1B202F024 +:10F8B00045FF28884FF48772204481B2B1FBF2F1F2 +:10F8C00001FB12002880301980B2F8BDBC26002050 +:10F8D0001C700020F8B5114F0546786808B18047C4 +:10F8E00080B1B868FAF77CFD04460D4806787EB909 +:10F8F0000C48C088C0F5005000B2A84204DB1DB11E +:10F90000042605E00B2607E00020E2F713FF3E780F +:10F91000B8682146FEF7C2F83046F8BDA0230020A3 +:10F9200088270020A0800020F0B589B0ADF8201015 +:10F93000079007A802AA00210024FEF759FBB0B9DE +:10F940000C4FB868FAF74CFD05460B4800940323AA +:10F95000C188C07802AAEAF721FD0646B868BDF85A +:10F9600016702946FEF79AF8002E08BF3C4620463E +:10F9700009B0F0BDA0230020A080002010B509F040 +:10F98000DDFD0F4C217E022902D0217E042904D105 +:10F990000E490C680AF07EF810E00AF07BF809487E +:10F9A0000068006B8047084AA0FB020301FB02319C +:10F9B00010F1905041F17A00E16C0C18204610BD16 +:10F9C000D01E00208C01001000093D0004300440CE +:10F9D00010B50F4C4FF48051207803F0F1FB18B1B3 +:10F9E0000C480121017010BD0B4802780B480178CA +:10F9F000012918BF03210020EEF78AFE084920786C +:10FA00000A884FF48051BDE810400AF073B800BF77 +:10FA100098880020E8250020BF270020BE2700206E +:10FA2000BCBC020010B5134C206808B3C16C11B106 +:10FA30000AF04EF82068416C11B10AF049F82068CC +:10FA4000416911B10AF044F82068C16911B10AF0A6 +:10FA50003FF82068416B11B10AF03AF82068C16B99 +:10FA600011B10AF035F820680AF0DCF800202060B7 +:10FA700010BD00BF38270020BFB501AD0446AB2044 +:10FA800000212A46FFF7DCF909F0BAF801462846BA +:10FA900007F00BFE88B101A9204605F09FFF50B189 +:10FAA00001A803A907F012FC50B101A80DF1020151 +:10FAB00006F09DFD08B1002000E0012004B0B0BDBB +:10FAC00003980079002818BF0120F7E72DE9F041DD +:10FAD00086B012480DF104080027002508F1020441 +:10FAE0000678B9B2B14214D2082000221423CDF80E +:10FAF000008006F04FFC50B99DF80400FF2806D0A6 +:10FB000021460022FDF79EFE002808BF013501377F +:10FB1000E7E7A8B206B0BDE8F08100BFCDBC0200A7 +:10FB20007CB50446032007F0E3FFA07905F0CEFC86 +:10FB30000E4D2089E67A2188A278AB78CDE90006BF +:10FB400004F10C00F3F71AFD044660B9A878000729 +:10FB500004D40748007830B9082001E04FF4004091 +:10FB60000121EBF7D9FE20467CBD00BF268700208F +:10FB7000C6260020BCB5114C206970B11049012582 +:10FB80008D70FFF7CDFFB8B120698DF8075004F0F4 +:10FB90003DFA0C480DF1070107E0094800218DF8F6 +:10FBA0000610817007480DF10601007800910321CD +:10FBB0000122012303F05FF9BCBD00BFAC2200208D +:10FBC000088800209F88002010B588B00C460021CE +:10FBD000049140B1CDE902400F48406802A909F004 +:10FBE000ADFF013815E00DF10700039001200290F0 +:10FBF00008788DF807000848406802A909F09EFFC0 +:10FC000018B1013C04D00120E4E74FF0FF3000E0E0 +:10FC1000002008B010BD00BF0C240020B0B50C4679 +:10FC2000054609F08BFC0F490A78862A10D18722F5 +:10FC30000A700D49CA890132CA8109F02BFF0B48AD +:10FC40000078A84208D1002C14BF1B20002004E03B +:10FC5000BDE8B04009F01EBFE920BDE8B040F2F7B2 +:10FC60003BBD00BFB488002044860020C18800202E +:10FC7000F0B5059E00244FF6FF7C0027B44220D249 +:10FC80001D8865451AD017B13F88874201D2854249 +:10FC900004D81D1D1F4601342B46EFE71F46B44212 +:10FCA00005D23D88654502D001340437F7E73C466C +:10FCB00054F8045D3D609C422746F8D8D9709A708C +:10FCC0001880F0BDB0B5054600781446E91C1070E8 +:10FCD000687800F00F005070687800099070A8787C +:10FCE00000F00300D070A878C0F380001071A878ED +:10FCF000C0F3C3005071A878C0099071D01D0822CC +:10FD000009F046FA04F10F0005F10B01032209F096 +:10FD10003FFAA87BA074B0BD10B550B1014650F8B1 +:10FD20000C0C18B911F8020CFF2804D0084608F092 +:10FD300099F8052010BD0A4C207801F8020C0948FA +:10FD40000278094802F03AFD01281CBF042010BDCA +:10FD500020784FF40051FEF77BF9002010BD00BF62 +:10FD600098880020D4BC02003C2700202DE9F041F7 +:10FD7000124C07462068F0B10E460169D9B115460C +:10FD8000826A984622B1380431460130904700E03B +:10FD90000020A84204BF0020BDE8F0812068314661 +:10FDA0002A464346046938040130A047012804BFAD +:10FDB0000A20BDE8F0810920BDE8F0815C27002021 +:10FDC00041F218324FF68850C5F20002CFF6FF70AC +:10FDD000116810584FF20003C0B27F2888BF00207E +:10FDE0001268C0F6FF731A4041F20003C0F6B43344 +:10FDF0009A4207D1090F022906D307D0032901D15E +:10FE0000153004E0FF2002E00A2000E00B3040B291 +:10FE100070472DE9F0410C4605463AB12846214687 +:10FE20000B220023BDE8F041FBF74ABFDDF8188044 +:10FE3000204600211E46FAF713F860B10746807984 +:10FE4000C00708D0404631462A46ECF749FC4FF639 +:10FE5000FE71884201D1BDE8F081788020462946B4 +:10FE60000C22DEE71FB5014604208DF80000087A59 +:10FE700001280AD003280AD0022814D10888ADF836 +:10FE800002006846F9F766F808E008880DE06C465D +:10FE9000201D09F044FA2046FBF7E6FB38B9684616 +:10FEA000F1F75CFD03E04FF6FE70ADF80C00BDF815 +:10FEB0000C0004B010BD7047B0B505464068007D29 +:10FEC0001030C0B207F0D0F8D0B16B680446A87803 +:10FED00029881D781A7D6181207304F1100060600B +:10FEE000C5F340152272657202252580196909F053 +:10FEF0004FF9044821460078BDE8B040FFF7D4B878 +:10FF0000B0BD00BF9588002070B5064600204FF6B2 +:10FF1000FE713446B060718044F8040F304606F03C +:10FF200023FC0546012812D10A48B189406801EB3B +:10FF3000410100EB810041887180061D304607F0C9 +:10FF400055FF012803D12046314609F0E8F928463B +:10FF500070BD00BF342600202DE9FF4110486C46DB +:10FF60004FF00108251D861C0E480778AFB1B07808 +:10FF7000013803280ED8F07800070BD430888DF8AC +:10FF80000080ADF80C002046FFF7BEFF10B12846F8 +:10FF9000FEF782FF2436013FE8E7BDE8FF8100BF9E +:10FFA000B0540020E6BC0200B0B505F097F80E4C46 +:10FFB0000E4D1420611CA8470A202146A84709209D +:10FFC0002146A8470A490820A847B92000F01BFA93 +:10FFD000084C1420A0470A20A0470920A047082069 +:10FFE0002146BDE8B0400847006400208F9A020017 +:10FFF00002200020A52F02002DE9F04107460E4601 +:020000022000DC +:100000005818B9684968884284BF6FF00300BDE89A +:10001000F081DFF830804FF0FF311C461546D8F8EC +:10002000000009F0ADFC384631462A462346FAF76F +:1000300085FC0446D8F8000009F008FE2046BDE81B +:10004000F08100BF0C24002010B504281CD10F48FB +:1000500009F0C0FDC0B109F0B7FD04460B4809F036 +:10006000B7FD604380084A280ED8084809F00CFD07 +:10007000052005F09BF90648012180F82510054868 +:100080000421283009F0E6FD002010BD647F002027 +:10009000D01E002070200020BCB504460DF10702E0 +:1000A000002001213A2307F08BFF4FF6FF75B8B906 +:1000B0009DF80700A04212D00DF106020020012198 +:1000C0003B2307F07DFF58B99DF80600A04207D1F9 +:1000D0009DF80700A04205D22046F6F70BFF3A250F +:1000E0002846BCBD3B25FBE770B588B00546806956 +:1000F000048810480088844207D103AB8120002186 +:100100001122002608F0C6FE58B1297C687C48F20E +:1001100011022346CDE90021A91C842206F050FCDF +:1001200006E0687C0096A91C03AB224602F046FC60 +:1001300008B070BD70870020E0B500218DF8071071 +:1001400050B110480DF10701002201230078009101 +:10015000032102F090FE8CBD0949487850B1086A2D +:1001600040B100224A7008F055FB3220BDE88C40B7 +:1001700008F008BB03200021BDE88C40E4F70ABB6F +:10018000AC2200209F880020E0B58DF807000D48C4 +:100190000DF10701C0680069007805F0CFFA0B493E +:1001A0000948096800680A6E9DF9071090470146E2 +:1001B000074A6FF39F5191420EBF4FF0FF30054940 +:1001C00048608CBD0C010020688800203088002029 +:1001D000FFFF3F004C260020B0B5104CA068016C1A +:1001E000096811B9D0F84C0580470D4D286808F012 +:1001F00061F8A168096C0968C860286807F0F8FC14 +:10020000A168096C096808820648007828B109F0DD +:10021000DDFCA168096C0968C860B0BD0C01002054 +:1002200044880020842700202DE9FC4106464FF039 +:10023000FF300D469046CDE900006846314607F094 +:1002400034FA07460B48046884B11FB12088A842DD +:1002500006D008E004F10C00314607F026FA10B190 +:10026000A078404502D004F11800ECE72046BDE834 +:10027000FC8100BFE487002010B5114CA068D0F8C5 +:10028000AC00007808B900F05DFDFFF749F9A068FF +:10029000D0F8B800007818B10A48016801208847F2 +:1002A000F8F786FDA068D0F8B8100A783AB1496925 +:1002B00029B1D0F828131020BDE81040084710BD20 +:1002C0000C01002024270020B0B5A0B00E4D04463C +:1002D000012085F83000686B08B902A868632046E1 +:1002E000F2F7A0FF03200B4A287508480068A16BAD +:1002F000C3B2074800910F2B38BF024600200021EF +:1003000004F0DEFD20B0B0BD381F002004ED00E099 +:1003100014AF020047B00200F0B52022EFF31181C4 +:1003200082F3118890F8282012B181F31188F0BD72 +:100330000C4A012492F8483082F84840466B456ADE +:10034000776806604760386080F82840D46C2C439A +:10035000D464706081F3118803B1F0BDBDE8F04052 +:10036000FEF7E6B8A01F0020B0B5124CD4E9165134 +:10037000E06CB0FA80F0C0F11F0001EBC00108682A +:1003800002680A6051600A688A4204D1416AE26CDC +:1003900022EA0101E164FCF7CBFEE06C40B1E16DC3 +:1003A000B0FA80F0C0F11F0001EBC0018D42E6D32E +:1003B000B0BD00BFA01F0020F8B50646C86860B1F8 +:1003C00010F00F0009D1376814460D4609F0B6F851 +:1003D00097F8251021B109F05DFB4FF0FF30F8BD13 +:1003E000012187F8251009F055FB296807F10C0C4D +:1003F00091E88D0029468CE88D0030462246BDE804 +:10040000F840E9F75DBDB0B504461420002108F0BE +:100410001FFE07250A20002108F01AFE681C0FD0D5 +:1004200024FA05F000F00101092008F011FE0A206D +:10043000012108F00DFE082009F0D7FA013DE9E797 +:100440001420012108F004FE4FF42F70BDE8B040E5 +:1004500009F0CBBA2DE9F0410F460646C1898089E3 +:1004600098461446727A337C451AA8B2FCF756FCBB +:1004700008B1BDE8F081E919B28914FA81F090421F +:1004800006D9F1890620A14238BF0520BDE8F081D8 +:10049000307C89B24246234608F042FE0020BDE887 +:1004A000F0817CB540EAC1000D46164640EA421193 +:1004B000069800F8011B194609F01FFB044636B1E7 +:1004C00008F09EFB0146204609F059FB0834012D37 +:1004D0000DD10DF10702002001213A23002507F07C +:1004E0006FFD9DF80710002818BF294621707CBDBC +:1004F0007CB515460DF106020C4605F051FD08B11C +:1005000001207CBDBDF806606946304605F06EF8F6 +:10051000009858B120462946F9F722FB20460121D0 +:1005200008F0E6FBFCF7B8FA00207CBD684602F054 +:1005300055FF08B111207CBD00980680EAE7FEE770 +:1005400010B50E480078012816D10D4805F016FAAE +:100550000C4C204607F0DCFB0B48046106F040F928 +:1005600040F2000CEFF311808CF3118809F025FBA9 +:10057000BDE81040FBF760BF08F0BCFFA01F0020E3 +:10058000B51B020098840020381F00202DE9FC4193 +:100590000E48104F00264FF0000805780C480488DC +:1005A000B5420FD0B1B2022000222346009705F0D9 +:1005B000F1FE20B93878FF2818BF08F101080E377E +:1005C0000136EDE71FFA88F0BDE8FC81E2BC0200CD +:1005D000C2B4020018870020B0B5054608F0AEFF8F +:1005E000044605F011FE0D48012D06D101210170D0 +:1005F0000B48008B40F0200007E00021017040789C +:1006000028B90748008B20F02000054908832046C0 +:1006100009F040FABDE8B04008F000BC70270020A7 +:10062000E87F0020E0B50E480122018B41F0550122 +:1006300001830C49C96849690A70018B807EADF855 +:10064000021042F202018DF804000748ADF80010D4 +:100650000649006809684A6A694690478CBD00BF30 +:10066000E87F00200C010020D826002030880020E0 +:10067000B0B504460F480078012815D80E48807B95 +:10068000800711D5A07A01280ED0258808F07AFFBE +:10069000854209D0E07A012806D0208807F076FF4D +:1006A00010B1208801F002F92046BDE8B040F7F70C +:1006B00057BB00BF18260020407B002010B5104C0F +:1006C000607890B10121217008F08CF86078FF28E3 +:1006D00010D0002161704FF47A7100FB01F20948DB +:1006E0008021007809F006FA04E000202070002044 +:1006F00008F078F802494120BDE8104001F0BEBC86 +:10070000F42400209888002070B542F2A45EC2F262 +:10071000000E1B38DEF8083000FB00F1A3FB012CB3 +:10072000DB1701FB00F4DEF80C6003FB01C1DEF80F +:100730000430C6FB0421C3FB0021DEF80050100981 +:1007400040EA01700909401941EBE571000C40EAEB +:10075000014070BDB0B50446481D85B2204629460B +:1007600008F0C0FB00F0FD022046294607F052FCCD +:100770000A4904EB440001EB800515F8190F58B144 +:100780002046022108F0AEFB00F0FC0220460221C8 +:1007900007F040FC00202870B0BD00BFA080002002 +:1007A000B0B510484FF470510F4D006801EA802039 +:1007B0004142C5E90101012006F02EFD044608F082 +:1007C000BDFE296839B109F065F94CB12046BDE894 +:1007D000B04008F085BF2C60BDE8B04009F05AB9C0 +:1007E000B0BD00BF30240340DC2500202DE9F041DE +:1007F00087680E4619447868814284BF6FF0030011 +:10080000BDE8F081DFF82C804FF0FF311C46154623 +:10081000D8F8000009F0B4F8386822468119284653 +:1008200009F06EFAD8F8000009F010FA0020BDE8CF +:10083000F08100BFDC25002070B505460F480C464E +:10084000A0F1100609F083F80D490978013101394A +:100850000ED0337C06F118021646AB42F7D104E005 +:100860002978A14205D0A5F10C021568002DF7D119 +:10087000002509F048F9284670BD00BFB46E00207D +:100880004425002080B50D4801420CD0012008F01D +:10089000FDFE012808D10B4800210C4AC1610A491C +:1008A000CA613C31016080BD09F08EF93221B1FB93 +:1008B000F0F10348BDE8804007F034BF0400002099 +:1008C000647F002000100440D01E00202D3700005F +:1008D00070B50E46044608F031FE0546A068B8B172 +:1008E00020682169A26901FB0201304609F008FA7B +:1008F000D4E9010122690139A160511CB1FBF0F278 +:1009000002FB10102061284609F0C4F8A06870BDF1 +:10091000284609F0BFF84FF0FF3070BD70B50446AF +:100920000F48056802F0A6FC0E4810210078FDF77C +:100930008FFBD62685B16868007858B1042006F090 +:1009400093FB38B1014644800670686840680078BF +:10095000FEF7AAFB2D68EDE7BDE87040FCF7E4BAAE +:100960002088002099880020B0B5044608F048F996 +:10097000A51C0146284606F098FE50B10C48416976 +:1009800011B12046884780B9E07ABDE8B040F7F75A +:1009900053B906480078012807D8A27AE37A20885C +:1009A0002946BDE8B040F1F75DBCB0BD1826002077 +:1009B0003C830020F8B5114E0D46044631680F46C1 +:1009C00059B108460979A14204D1C188A94204BF9E +:1009D0000020F8BD01680746F2E7082009F024F975 +:1009E00050B1014600200860CD800C713268002AA9 +:1009F00008BF37463960F8BD1020F8BD68270020D1 +:100A000070B5114D134604460E0A13F8012B6868A1 +:100A1000102A01704FF020314670C0F80710C0F85E +:100A20000B10C0F80F1028BF1022827040F8031F6F +:100A3000194608F0ADFB2846214614221323BDE8D1 +:100A40007040FEF7E9BC00BF7C260020B0B586B040 +:100A5000054600206C4618212872204608F034FA1A +:100A6000204629460B2208F093FB04F10B0005F108 +:100A70000B01082208F08CFBA88AADF81400A87DB1 +:100A80008DF8160003488068D0F81C12204688476D +:100A900006B0B0BD0C01002010B5427B042A01D184 +:100AA000027C0AB1002010BD40690028FAD002780B +:100AB0009207F7D14A68437B547DA342F2D109885B +:100AC00043898B42EED1D18883888B42EAD19178D9 +:100AD0008078884204D0107800F00C000428E1D11E +:100AE000012010BDF8B504464FF6FF76002541F20F +:100AF00021070F2D14D82078082106F0B4FD80219D +:100B000059B13246014218BFD243120487EA460265 +:100B100058BF720049081646F2E701350134E8E78C +:100B2000B0B2102106F09FFD4FF6FF714840F8BDAE +:100B300070B5114E04460822A51CF0682946023003 +:100B400007F076FA18B156F80C0F04460CE00C3694 +:100B5000366886B156F80C0F29460822023007F095 +:100B600067FA0028F4D03068C06830602046BDE8DD +:100B7000704009F057B870BDAC220020E0B50023EA +:100B8000CDE9003361B10F4A0428137008D8DFE8BB +:100B900000F0030B09131100BDE88C4000F04DBAC2 +:100BA00002208CBD012010706A4608461146FEF7EF +:100BB000DBFB8CBD012010706A4608461146F1F738 +:100BC000FDFD8CBD942700201FB54FF6FE718842B5 +:100BD0001AD00E4900234A1C0D49097899420BD0BE +:100BE00014781CB9B2F80140844202D00E320133AD +:100BF000F4E7DAB2914207D1ADF80C0004208DF889 +:100C00000000684603F0B0FC1FBD00BF188700203D +:100C1000E2BC02007FB5D0E90154204606F022F97B +:100C20002068416821F002014160416921F00F0113 +:100C300041610321016202A808F0FAF9074995F819 +:100C4000F93095F8FA202068D5E9396509680C680B +:100C50000399CDE90065A0477FBD00BFC401001026 +:100C600010B508F06BFC0C49097869B90B49097893 +:100C700051B90B49097839B90A49097821B90A49A2 +:100C8000097811F0FD0F04D0002408F003FF20467E +:100C900010BD0124F9E700BFAC880020AF88002018 +:100CA000B4880020A7880020AD880020F0B589B066 +:100CB0000F4C2068A8B1002001ADC6B21F2E0DD880 +:100CC000AF1903F053F80021202905D020FA01F2D2 +:100CD000083107F8012BF7E7301DEEE7216801A87E +:100CE00088470448018B41F00401018309B0F0BD3D +:100CF0004C270020E87F0020FEB50F4D0446E86831 +:100D00008069007800B1FEBD0D4F0C4E3968306827 +:100D10004B6C01AA022198479DF804000028F2D0EC +:100D20000CB901F0EFF9E8680121806901703968B8 +:100D30003068C9698847FEBD0C010020D826002014 +:100D40003088002010B508F0F9FB04460C48007804 +:100D500020B12046BDE8104008F09CBE094890F93B +:100D600000000028F5D4084890F900000028F0D4CD +:100D7000064800780028ECD105F046FAE9E700BF04 +:100D8000AD880020AC880020B4880020A78800200F +:100D90001CB50E21F8288DF8071017D10E4CA0684D +:100DA000D0F8D41091F884208AB191F8421014221E +:100DB0008DF80720142905D0D0F830240DF1070153 +:100DC000E0209047A068D0F8CC0380471CBD91F884 +:100DD00042100E29F0D1F5E70C01002070B5054650 +:100DE00008F0ACFB0F4E0446B068D0F8F824D0F8F9 +:100DF000D8102846904730B9B068D0F8DC10D0F849 +:100E0000F82428469047B068D0F8E8100968A9424D +:100E100002D1D0F8D80480472046BDE8704008F0E1 +:100E200039BE00BF0C010020F8B515460F46064636 +:100E300002F0E2FBC8B11C21044608F045F8284640 +:100E4000002D08BF0120A07467812680074890F814 +:100E50006C00012812BF0720284606F019FF6074B5 +:100E600003480078013040082074F8BD407B002022 +:100E7000D1BC0200F8B50F484FF6FE750E4C6F1C42 +:100E800006784EB12CB120461C2108F01DF8678170 +:100E900025801C34013EF4E7084900200022032A83 +:100EA00008BFF8BD01EB820301F8220001325D802A +:100EB000F5E700BFD5BC0200DC5B002034870020D2 +:100EC00010B50D49002481F826400C49087003F044 +:100ED00075FF08F089FC0A480460FFF7CBFF09485A +:100EE0000078012803D806F033FCF7F749FEF0F745 +:100EF00021FE0548046010BD407B0020988800203A +:100F0000E487002018260020CC260020F8B5114FD9 +:100F10000C463968C9B115468A69B2B18A6AB2B15C +:100F200000042146461C3046904780B1A8421CBFB1 +:100F30000C20F8BD3868214682693046904701464A +:100F40000020012908BF0A20F8BD0020F8BD0920B3 +:100F5000F8BD00BF5C270020B0B508F0EFFA0446EA +:100F600008F06FFD0028FBD0032003F001FC0B48C4 +:100F7000002180F83811204608F08CFD084881686F +:100F800002200D4688470446102004F04FFC24B18F +:100F900003202946BDE8B0400847B0BDD81B00205B +:100FA00090BA0200F8B592E87800771C08BF0526D1 +:100FB000002780F828700127C0E9043100F11801EA +:100FC000B740F0C11169C0E90B110849CA6D02EBC5 +:100FD000C602426301F140024060006000F1080176 +:100FE000104607F00FFA0020F8BD00BFA01F002038 +:100FF00070B50446417880786268267F1044A6F177 +:101000000D02B2FA82F2520941EA4211227C41EA0F +:10101000C20100F8011BA16908F06FFD05460D2E05 +:1010200005D104F10801284608F0A9FD0835207C07 +:10103000012804BFA07D287070BDB0B588B0002025 +:101040000DF10B018DF80B00CDE90000684603AAF5 +:10105000F8F7B0FA04469DF80B0078B103AD1421FF +:10106000284607F031FFFF20214614222B468DF839 +:101070001C00042005F0A4F9002000E0012008B0C5 +:10108000B0BD0000BFB504460F48002590F826000B +:10109000082801D0042814D14FF6FD70ADF80400E3 +:1010A00007F0AEFD0290207861788DF80D508DF834 +:1010B0000F508DF80C108DF80E0001A8F7F748FCC2 +:1010C0000546284604B0B0BD407B0020FEB58E6AC0 +:1010D0000446777807F01F00012812D101ADB11C3A +:1010E000284608F04CFD0A482946393006F0DDFA5A +:1010F00050B11F2F05D8B6F80B10B07A02F0B8FA2D +:1011000003E0D320F5F705FE00242046FEBD00BF16 +:10111000407B002010B50446C00704D00C4A2120B3 +:10112000742108F073FB200748BFFEF755FB094800 +:101130000078012803D8A00748BFFCF72BF9600707 +:1011400005D50548006810B1BDE81040004710BD46 +:10115000407B0020182600200824002080B546F29D +:1011600000014BF64C4E4BF6504CC4F20C01C0F251 +:10117000020EC0F2020C00BF0B6800BF4A68934227 +:10118000FCD1834208BF80BD1EF803201EF800304A +:101190009A424FF0FF3338BF01231A441CF8022053 +:1011A0000A60E9E70E485022016841F4087121F015 +:1011B000020101600B48032140F8041C41F2300198 +:1011C00081600121016082604FF4CA620160826027 +:1011D0004FF48652016082600160034801607047ED +:1011E00000000460586004400041044070B50446AB +:1011F0004668082005F038FF90B1054601202870A8 +:101200003078033008F010FD686048B13178CA1CAE +:10121000314608F075FD064829460078FDF744FF81 +:10122000606806F01FFE2046BDE8704008F0FABC7A +:10123000C8260020B0B504460C480D46007808B911 +:1012400004F0BCFD0A480078A0429CBF0020B0BD5D +:10125000094A084904EB4400002D18BF294652F8FA +:10126000200082692046BDE8B04010479B2700203F +:10127000F3BA02009CBC0200A0B902001FB50E49DF +:101280004FF6FF730A780D49A2B131F8044B013AC9 +:101290009C42F9D08442F7D14FF0FF32ADF8040000 +:1012A000074841F8042C02218DF80C10818C01A80C +:1012B00008F0DEFC1FBD00BFD6BC02008086002007 +:1012C000407B002070B1B0B5044608F040FB0D49EA +:1012D000886054F8042D002A05D40B498A6801322D +:1012E0008A600BE0704722F00042074B22605D6885 +:1012F0002A445A600A68A24288BF0C60BDE8B04028 +:1013000008F001BCD025002044250020B0B508F02D +:1013100015F9044608F095FB0C48002180F83811B7 +:10132000032003F025FA204608F0B4FB0848816842 +:1013300002200D4688470446102004F077FA24B1B5 +:1013400003202946BDE8B0400847B0BDD81B0020A7 +:1013500090BA020070B500250C4645710D4806781C +:101360000D48AE420CD0415D227B914201D0013547 +:10137000F7E72046F8F7B2FBE8B2864218BF70BD27 +:101380000620002160732068407BBDE8704000F0BB +:1013900069BA00BFD2BC02004084002010B50446E8 +:1013A00048060FD40E480078012815D8204608F0CA +:1013B00014FB88B1007909490138C98A022838BF6D +:1013C0000C4609E0FF20214605F072FB0349002886 +:1013D000CC8A08BF6FF00104A0B210BD407B002092 +:1013E000182600201CB58DF80700022004F036FAFC +:1013F00008B1012415E007F099FC012488B10DF132 +:101400000701E12000F03AFE0DF1060152208DF8AF +:10141000064000F033FE044800248470002007F0EA +:101420004FFF20461CBD00BFC02600202DE9FC4711 +:101430009846AAB115460E46074600244FF0FF3ADB +:101440000DF1040931192A1B38464B46CDF800A08E +:10145000E7F7CCFA01990C4428B96D1AF2D102E0F1 +:1014600000246FF00900B8F1000F18BFC8F8004061 +:10147000BDE8FC8710B50E4C322000210122234626 +:1014800007F008FD0B4B33200021012207F002FD7D +:1014900009482178007801294FF4006113BFBDE8A5 +:1014A00010406422BDE81040FDF7A2BA08F022BB4C +:1014B000BD270020BC27002098880020B0B50F4C25 +:1014C0000F4D48F201012078A84720784FF40041E1 +:1014D000A847207848F22101A847207848F2220145 +:1014E000A84720782021A84720782121A8472078E4 +:1014F00022212A46BDE8B040104700BF998800204D +:10150000B50902002DE9F041DFF83CC04FF0000EB4 +:101510004FF00008864513D01F4615466DB131F8CF +:101520001E603C88A64202BF5FFA88F62CF816407F +:1015300008F101080237013DF0E70EF1010EE9E77D +:101540005FFA88F0BDE8F08114810020E0B58DF8E5 +:1015500007000D48017821B100210170EFF7B4F9BF +:1015600010E00A48816819B10DF10700884709E0C9 +:101570000020012102228DF805000548007801AB0A +:1015800002F01FFF00208CBDAB2700203C83002011 +:10159000998800207FB504468069068808F004F821 +:1015A000864209D107F0EAFB05460B48012106F007 +:1015B00049FE681E002301E080230020227C617C1C +:1015C000C0B2CDE9006048F205000392024A0292DF +:1015D000A21CFDF771FE7FBD1481002070B504468A +:1015E0000F481E461546406808F087FA052D05701D +:1015F00001D8467006E0FE2D06D3DDE90421FF2D5B +:10160000427003D0062303E0052301E00823418054 +:10161000034821463822BDE87040FDF7FDBE00BFFB +:101620007C2600202DE9F041DFF83C80DDE9067CD6 +:101630001C46D8F80460250605D017F8015B013C6C +:1016400006F8015BF7E7BCF1000F18BF4FF0010C83 +:101650004FEA8C1488F80240FDF7DEFE002188F87E +:101660000210BDE8F08100BF7C260020B0B5142038 +:1016700008F0DAFAD0B11421044607F025FC4C201A +:101680001421224608F0BCF80546092804D14C2054 +:101690001421224608F0BAF8204608F0C3FA044A9A +:1016A0007120082108F0ACF82843B0BD0A20B0BD75 +:1016B000AC260020B0B5104CA068D0F8E0038047FD +:1016C000A068D0F818028047A068D0F8F0028047E0 +:1016D0000025A068072D07D0D0F8A00050F82500FD +:1016E00000B180470135F4E7D0F858038047EB207C +:1016F00007F060FF0120B0BD0C01002070B590B074 +:101700006E460C4605464021304607F0DDFB40F2B0 +:101710000110ADF80A40ADF80050ADF811000120FD +:101720008DF80E0002208DF808008DF80C0004489A +:101730008068D0F888123046884710B070BD00BF6E +:101740000C010020E0B502464878800709D00D481A +:101750000368ABB108461146002202B0BDE88040E4 +:101760001847094801916946ADF8002004F08EF849 +:1017700030B10621417300680021407B00F072F80F +:101780008CBD00BFF0260020990A02001CB50F4C4A +:10179000032184F82A1001218DF8071008B10022D6 +:1017A0000AE06079022801D8013003E0206902F0E4 +:1017B0002DFC00200122607105480DF10701012375 +:1017C00000910321007801F056FB1CBDAC220020E3 +:1017D0009F880020BCB504460D480E4D417044B1B1 +:1017E0000D484FF480510078FDF702F905F1330000 +:1017F00000E0281D002184F0010201230170064849 +:101800000DF1070100910121007801F034FBBCBD0E +:1018100008880020AC2200209F88002010B50446D4 +:1018200020B90E488068D0F84C05804707F086FE46 +:101830000B490A78A2430A7008F02CF9FFF782FAE4 +:101840000648C168C968097801B110BD80680021E7 +:10185000D0F858240020BDE8104010470C010020AB +:10186000AD880020B0B5044614200D4605F0FCFB01 +:1018700058B101460C2008700B488C7000244D7044 +:101880008C730078FDF710FC0CE0204606F0F2FFA8 +:1018900038B106214173007B03F0D0FD2046F8F7F4 +:1018A000DFFC10242046B0BD988800202DE9F041CF +:1018B00004460F484FF00008062600270568A5B12A +:1018C00028680188A1420ED16989A5F808804907D6 +:1018D00003D5287B03F0B2FD2868407BF0216E73AE +:1018E000FFF7C0FF0137281DE8E7F8B2BDE8F08137 +:1018F00054880020B0B507F021FE05460D48046865 +:1019000094B10D4854F80C1C007821B14FF40051EB +:10191000FCF79EFB03E04FF40051FBF7D1FD0548B7 +:101920002146002203F02AFD284608F0B3F820469D +:10193000B0BD00BF3C27002098880020B0B5017DD5 +:1019400005460C30022904D003291AD108F099F871 +:1019500002E0008808F041F8044690B16878F12868 +:1019600018BFE12806D1A079012806D1208808F007 +:1019700065F902E008B90020A071A07908B101382A +:10198000A071B0BD10B50D4C207838B90C480D4988 +:101990004FF4D67208F0B4F9012020700A480221F1 +:1019A00080F88F10012180F88510002180F8451003 +:1019B000042180F89D100321017010BD8B270020A9 +:1019C0004C40002164A80200DB030021B0B52021B7 +:1019D000EFF3118481F3118801250B49CA6A0D6068 +:1019E0004069030CB0F5802F38BF04239818486174 +:1019F00006482321006802680020904704480560DB +:101A000084F31188B0BD00BF042009408401001098 +:101A100080022443B0B5104C00252574E06810B94D +:101A200004F063FEFAE7E068216AB0FA80F0C0F1E2 +:101A30001F0001EBC000E169814209D2E061A169A8 +:101A4000026801F11C0002F11C01A26105F05CF9C1 +:101A5000207C0028E1D1B0BD3822002070B50D46B1 +:101A6000044607F06BFDD4E901128A4204D108F064 +:101A700011F84FF0FF3070BDE36822680133B3FB0B +:101A8000F1F606FB11315554E160A168626901313C +:101A9000A160914288BF0A46626107F0FBFFA0681F +:101AA00070BD10B58EB0E1B10C460168086AC0B1D6 +:101AB000C97F01AAEFF702FB6188BDF81020002062 +:101AC0008A420FD19DF8061001290BD10B9801789D +:101AD000012906D121788078401AB0FA80F04009B7 +:101AE00000E000200EB010BDF0B585B007461546E9 +:101AF0000E460088DDE90E121C46F2F7D1FF0528DC +:101B00000FD080B9DDE90C10DDE90A32CDE90032F1 +:101B1000CDE90210384631462A462346E6F7BEF89C +:101B200002E0022000E0102005B0F0BDB0B5044690 +:101B3000202005F099FAC0B1054604201022287033 +:101B4000D4E90001C5F80200A81D07F021FBE168F7 +:101B500005F1160007F0E3FB208A2946E8830348D5 +:101B60000078BDE8B040FDF79FBAB0BD998800206D +:101B700010B50F4A8389526803EB430302EB8304D9 +:101B80004A1E012A0AD84288022962800BD10430F9 +:101B900006F02CF938B90020207004E0221D011D48 +:101BA000104607F0BCFB2046BDE8104007F09CBC87 +:101BB0003426002010B50C48032290F8481001216B +:101BC00080F8481009480275094A137A11720069B1 +:101BD00040B1084C204607F0ADFD2046BDE810405E +:101BE00007F0AEBD10BD00BFA01F0020381F0020B1 +:101BF0003822002087740100F8B50E48048820467A +:101C000008F012F8A0B12146FF22054607F056F968 +:101C1000094800270678B74207D2F9B202202246C7 +:101C20002B46FEF7A3F80137F5E7284607F0FAFF41 +:101C30000020F8BDC2B40200E2BC0200F8B50D48B5 +:101C40000D4D0E4F0126046804608CB1B4FA84F087 +:101C5000696880F01F0006FA00F251F820109443E2 +:101C60000029F2D057F820205203EED58847ECE740 +:101C7000F8BD00BFE020024014BB02000010084085 +:101C8000F0B585B00D4F04460B480D4D6E463246FB +:101C9000397880F872402846FEF714F83A783046D2 +:101CA00029468DF81240FDF742FD4520294600F0F7 +:101CB000E5F905B0F0BD00BF407B0020A92700205A +:101CC0000887002042F24011C4F208010A68496DF9 +:101CD000C30701D1002106E002F0010301F0040175 +:101CE000C91818BF0121830744BF02F0020341EA6B +:101CF0005301400744BF02F0040041EA9001022072 +:101D0000002918BF0120704742F24011C4F20801B7 +:101D10000A68496DC30701D1012106E002F0010301 +:101D200001F00401C91818BF0121830744BF02F064 +:101D3000020301EA5301400744BF02F0040001EA34 +:101D400090010220002918BF0120704770B58AB0A9 +:101D50000C4C4FF48061DD224FF48066204607F082 +:101D6000ADF801AD284607F081FD042007492A4659 +:101D70000023CDE905460490034804F0D9FF0AB0DA +:101D800070BD00BF54610020807C002011910200D2 +:101D900070B507F0D3FB04460B48017821B120460B +:101DA000BDE8704007F076BE012101700748057854 +:101DB0000748002DF3D0064656F80C1B8968884763 +:101DC000013D3046F5E700BF9C27002000000000E1 +:101DD00000000000B0B511F1800201D1002112E035 +:101DE0000C4A002303EB830544577F2C09D005449C +:101DF000D5F801501540954203D08C4201DC0133E7 +:101E0000F0E72BB1591E01EB81010844D0F8012005 +:101E10001046B0BDFFFF3F00F0B50F4C00234FF060 +:101E2000580C8EB20027B3F5307F0FD0E1180D8E1D +:101E3000B54208D139B10D69854204D14AB191F852 +:101E40003350154203D158330137ECE700210846DF +:101E5000F0BD07FB0C41FAE75865002070B5044659 +:101E600005680D48C6680D480068006B8047811BF7 +:101E7000080B05EB1132B5EB113F40F6C41188BFDA +:101E800050082060884204D880084A2802D84FF4BD +:101E90009671216070BD00BFD01E00208C01001023 +:101EA0002DE9F04105460E480078A8429CBF00206D +:101EB000BDE8F081164688460027BD4208D036F8B6 +:101EC000174007F071FB844201D00137F5E7FDB2FE +:101ED000A5EB0800B0FA80F04009BDE8F08100BF32 +:101EE000DBBC020070B507F029FB04460B48017803 +:101EF00021B12046BDE8704007F0CCBD0121017042 +:101F0000074805780748002DF3D0064656F80C1B05 +:101F100089688847013D3046F5E700BF9D270020CE +:101F200013BC0200B8BB020010B586B00DF117005B +:101F3000F9F7D4FBB0B19DF8172004467AB14FF6FB +:101F4000FC701F212346ADF80C000F208DF8140003 +:101F50000020CDE90010044803A9F1F7E1FF204675 +:101F600007F060FE06B010BD7C26002010B50B4CBB +:101F700048F215012070FEF71DFD20783821FEF78C +:101F800019FD07480749084A20610848C4E90221A9 +:101F9000022101724FF6FE71018010BDCC24002099 +:101FA000B1320200FD5402001D5F02007A8700205A +:101FB0002DE9F041C189846948F21F00814208BFC0 +:101FC00001342778F800013007F02EFE804670B10A +:101FD0004546661C002405F8017BBC4207D2284612 +:101FE000314607F0CCFD013408350836F5E74046A8 +:101FF000BDE8F08110B502460E480023006838B1F4 +:102000000479944202D1C4888C4203D00346F5E798 +:10201000012010BD01680BB1196006E011B1054A3D +:10202000116002E0034900220A6007F0FBFD002076 +:1020300010BD00BF6827002010B5EEF7C7FE0C4C9E +:10204000207840B906F0DCFD0246AB20002103F009 +:10205000EFFD207810B106F0E3FF28B1054800211C +:102060000170054801210170BDE8104003F0AEBFCA +:10207000182600209D8800209C880020B0B50C46C2 +:102080000546522806D0E22D0BD10B48214607F019 +:1020900076FD06E0074821780078084304BF012058 +:1020A000B0BD064821468068D0F830242846BDE8F7 +:1020B000B0401047AD2700209E8700200C01002073 +:1020C00010B50423082200F0010403EA901302EA89 +:1020D000503223441A44102303EA1050104401F0F4 +:1020E000010240EA4210402202EA9102104480229A +:1020F00002EA512210444FF4807202EA114108436F +:1021000080B210BD10B50D4C2078FE2807D00C48C9 +:102110000068826B0B48006894F900109047607863 +:10212000FE2807D006480068826B0648006894F9CC +:1021300001109047FE206070207010BD1425002013 +:1021400030880020D826002010B5EB2002F0B0FC2B +:102150000B48002404700B480078862802D1002028 +:1021600002F034F807F0EAF907490A6813681C71AD +:1021700012680A6007F08EFCBDE8104006F0FCB85B +:10218000AF880020B4880020C08700200C480E4B88 +:102190008068DB68D0F8D410D0F8EC00497B50F8A8 +:1021A000210008490A680B60991A084A12789200BF +:1021B00091FBF2F1B1FBF0F202FB1010704700BF8F +:1021C0000C0100202C880020F8860020B088002018 +:1021D000B0B50F4CA168D1F8B8000278B2B1C569AA +:1021E000A5B1086C0268D06D28B102210023A84770 +:1021F000A168086C0268106E40B1D1F8B8100023D5 +:10220000D1F81CC00821BDE8B0406047B0BD00BF98 +:102210000C0100202DE9F04104460D484FF6FE78F0 +:102220000C4D08F1010706787EB16889A04218BFFD +:10223000002D02D11C35013EF6E728461C2106F090 +:1022400043FE6F81A5F80080F4E7BDE8F08100BF90 +:10225000D5BC0200DC5B0020B0B570B104460E486E +:10226000416851B100220D462B4625B1A34202D050 +:102270001D681A46F8E7A34200D0B0BDA14219BFBD +:102280002068106021684160204607F075FC2046F8 +:10229000BDE8B04007F0C6BC44260020012919D093 +:1022A00010B5B0F90E0000EBE03181EAE03084B205 +:1022B000204600F037F80848084AC16C51F824302D +:1022C000934218BF41F82420006D002140F82410EB +:1022D000BDE81040704700BF381F0020916C02001D +:1022E000F8B50D4E04460D4F306E50F82100B8423F +:1022F00001D00020F8BD0A480D461C300090204651 +:1023000005F0F2F80028F4D0306E50F82500C01B1C +:1023100018BF2046F8BD00BF381F0020916C020096 +:10232000A01F002010280FD310380E4A01234109A6 +:1023300000F01F0002EB810103FA00F0D1F8F02059 +:10234000C1F87001104070470F281CBF0020704773 +:1023500004480168026822F00202026001F00200F3 +:10236000704700BF10E000E010280FD310380E4A6D +:102370000123410900F01F0002EB810103FA00F084 +:10238000D1F8F020C1F8F000104070470F281CBFB2 +:102390000020704704480168026842F002020260AF +:1023A00001F00200704700BF10E000E000B170478C +:1023B00080B52021EFF3118081F311880A49CA6C9E +:1023C00022B180F31188FCF7B3F804E0002281F811 +:1023D000482080F3118805490122087A0A72BDE875 +:1023E000804001F017BA00BFA01F00203822002053 +:1023F000BCB50D4D286840B96C46204606F096FFE6 +:1024000001202146EDF724FC28600849097851B9DC +:1024100048B107490978012903D1642101F03AFB49 +:10242000BCBD00F0EAFCBCBD24880020922700203F +:102430009C8800201FB5044600790B2101EB400069 +:10244000C0B204F011FE38B123790DF1050223B1B9 +:10245000012B04D1511D07E01FBDD11C04E0D11D8B +:10246000032B08BF02F10901A2890A8004B0BDE86C +:10247000104005F0F7BC70B505460D200E4607F07C +:10248000D3FBC0B10680044615F8020BA0702946A4 +:1024900015F8010CE070201D07F071FB287AC121AE +:1024A0000D2223462073452000F0E8F82046BDE8C1 +:1024B000704007F0B7BB70BD2DE9F84317460E46D4 +:1024C000044606F0F5FEB0B10546DDE9089808209F +:1024D00004F0CAFD78B10146C780067180F8039008 +:1024E000847080F80180FE20087068680078BDE87C +:1024F000F843FCF7D9BDBDE8F883000010B50446E9 +:10250000007DA0B92046EEF7E3FA206918B10A4829 +:10251000816820468847207D28B1E06807F082FB6B +:102520000020E06003E0E068FCF7D8F92075204661 +:10253000BDE8104007F0B1B95024002070B50C2060 +:1025400007F072FBA8B10C4E04464FF0FF30002597 +:10255000A060606020603088854207D2A9B2012067 +:102560000C222346FDF702FC0135F4E7204607F074 +:1025700059FB002070BD00BF342600202DE9FC412E +:102580000D4D4FF00008002600272888874228BFFD +:10259000BDE8FC816868B9B200220C2384190120CF +:1025A000009403F0F7FE20B92078FF2808BF84F8D4 +:1025B00000800C360137E8E73426002070B5102083 +:1025C00007F032FBB0B104464FF0FF300026E06068 +:1025D000A0606060206008480578AE4207D2F1B282 +:1025E000032010222346FDF7C1FB0136F5E7204604 +:1025F00007F018FB002070BDE6BC0200F0B585B006 +:102600004FF0FF300027ADF810000390CDE9010036 +:10261000084801AD048808480678B74224BF05B0D1 +:10262000F0BDF9B2022022462B4603F0C9FE013765 +:10263000F3E700BFC2B40200E2BC020070B50E486E +:102640008068D0F8D810096819B9D0F8DC000068A3 +:1026500080B106F073FF044607F0A8F8054601F0C4 +:102660007DFD0646204607F015FA701C281A98BF13 +:10267000012070BD002070BD0C0100202DE9F0414B +:102680000746D01C984614460D4604F0EDFC80B178 +:10269000064685704770047024B1F01C41462246FE +:1026A00007F02EFB044831460078BDE8F041FCF706 +:1026B000FBBCBDE8F08100BF8E88002010B5094941 +:1026C000094C0020A04709490120A04708490620DD +:1026D000A04708490720A047074908202246BDE82F +:1026E0001040104781E80100DD8C0200395A0200D9 +:1026F0003F3902009D510200CD51020080B5EFF735 +:1027000019FA0B4A2120742107F080F802F09EFC90 +:1027100008480078012898BF02F0B0FC064800681D +:1027200000B1804702F076F9BDE88040F7F758BC69 +:10273000407B00201826002000240020F8B50D4E14 +:102740000C464FF487727788F188C91B01F58771B1 +:1027500091FBF2F303FB12118AB2A24238BF0C467E +:102760000549A5B22A46394407F0CAFAE019708033 +:102770002846F8BD702400202A71002070B5D0B121 +:1027800005680446BDB12868A8B107F0E0F8064620 +:10279000286807F01FFA10B1286807F075F9286853 +:1027A00006F0B4FE2846FEF78DFD00253046256074 +:1027B00007F0A9F900E00225284670BDF8B51746D4 +:1027C0000D46064607F0C3F83168044639B14FF0AC +:1027D000FF3051F80C1C01300029FAD100E0002034 +:1027E000B84205D23046294604F086F8012500E0BB +:1027F0000025204607F087F92846F8BD0B4A1278D5 +:10280000012A11D10A4A127882420DD9094A0A4B8B +:10281000002918BF0A4600EB400103EB810053F882 +:102820002110CB6811461847002070479C270020D4 +:1028300000000000B8B90200000000000B48016869 +:102840008907FCD50A4801210A4AD0F83C01012831 +:102850004FF0010008BF2020906108230020106085 +:102860000548036043601160704700BF58600C402A +:10287000D81B002000400C4038500C4040F00201B2 +:10288000022918BF70477CB50A4D0B4C80B27022EC +:10289000042329684E68009020460021B04728682C +:1028A000002170227023D0F80CC0204602B0BDE891 +:1028B00070406047A401001000A00C4070B50E4AA3 +:1028C0000C4900234FF6FE7403251278053193421C +:1028D00028BF70BD4E78F60709D131F8036C8642E7 +:1028E00005D10E78012E04BF21F8034C0D7008317C +:1028F0000133ECE7E04C0020DABC02000C4A12780D +:10290000012A11D1094A127882420DD9094A0A4B8B +:10291000002918BF0A4600EB400103EB810053F881 +:102920002110CB68114618470020704713BC0200E5 +:102930009D27002024B90200B8BB020080B50146E3 +:1029400000780C2803D00D2814D1486801E04868AD +:10295000C83078B1027802F00302032A0AD18078E5 +:1029600000F00300032805D103480078FCF79CFB26 +:10297000012080BD002080BDC026002010B586B09B +:1029800001AC1121204606F09FFA81201121224638 +:1029900006F036FF70B901AB81200021112206F04C +:1029A00079FA38B99DF8040020B10348018841F054 +:1029B0001001018006B010BD268700207CB50C46B2 +:1029C0000D491D7800268DF8070049684A70120AE3 +:1029D0000E70081D8A701A78CA7013F8012B1946F8 +:1029E00006F0D6FB281D214648F21102C3B20DF1B4 +:1029F0000700FCF711FD7CBD7C260020F0B587B0F8 +:102A000001AD04461821284606F05EFA0027022F81 +:102A100084BF07B0F0BDFEB2062018222B46314617 +:102A2000FDF7A4F9012C08BF002805D10620314686 +:102A300018222B4603F0C4FC0137E8E7BCB50C466E +:102A40000DF10601154603F0D2FD0146C82091B9EB +:102A50000949096879B1BDF806200020032804BFA0 +:102A6000C820BCBD0B88934202D006310130F5E787 +:102A7000288000202160BCBDE0260020BCB50D4DA3 +:102A80000028A968D1F8C81318BF01208847044658 +:102A900000200DF107018DF80700A868D0F8302458 +:102AA00056209047A8680449D0F83024E220904787 +:102AB0002046BCBD0C0100209E8700202DE9F84374 +:102AC00007460C480C4C90468946002605786DB1A7 +:102AD0002078B84207D12046494605F0CFFB10B117 +:102AE000464504D201360E34013DF0E7002420466D +:102AF000BDE8F883E2BC020018870020B0B5056885 +:102B00000446B5F85610A86807F066F8A86807F0FC +:102B100065F8204605F0BBFCB5F8580040B14FF60B +:102B2000FF71884204D00138A5F85800000400D095 +:102B3000B0BD2046BDE8B04004F02FBD70B50D4ECD +:102B40000D4C30688168204688470546606840F033 +:102B50003000606028060AD03068002142682046B4 +:102B6000904730688168204688470028F9D1E8B24C +:102B700070BD00BFD8010010004003400B480C4A54 +:102B8000D0E90210137B0068D1F8E01003F0F003E5 +:102B900002330078096813730844064909784843EA +:102BA0000549096801EB8000906070470C01002026 +:102BB000A8850020B08800202C880020F8B50E4E93 +:102BC0000C4605460027ACB1606841196160B068E9 +:102BD000D0F8E8201268944204D1B1F1FF3F01DC43 +:102BE000676005E0B1F1FF3F02DCD0F84C0580479B +:102BF0002468E8E7F8BD00BF0C01002080B50C4850 +:102C0000007806280ED10B480178013101700A487E +:102C10000188022906D3013901800620BDE88040E1 +:102C2000E4F72AB9FDF7D8FABDE88040F7F798BA7B +:102C3000B7880020A6270020AE87002010B58EB0F0 +:102C400001680446086AA0B1C97F01AAEEF736FA06 +:102C50000948BDF80E10C08A81420AD020689DF84C +:102C600021200388BDF8100000934FF6FE73FDF796 +:102C7000D0F80EB010BD00BF407B00204FF6FE73B1 +:102C8000984203D002F06003602B01D1012070470D +:102C9000930608D4084B5206DB8A09D4834209D331 +:102CA0008B42F3D906E00448C08A8842EED901E09D +:102CB0008342EBD200207047407B002070B520207B +:102CC000EFF3118480F3118809480068006B804796 +:102CD000084AD2E91556084AD2E9102384F311882C +:102CE00006F0F6F8281AB04288BF002070BD00BF79 +:102CF0008C01001008200020207C002070B50E48B8 +:102D00000121047A017285692020EFF3118680F396 +:102D10001188284600F060FD032085F82000284631 +:102D200001F0C4FA86F311886D602D602046BDE87D +:102D3000704000F06FBD00BF3822002010B5F7F7DB +:102D40000FFB04F0D5FF02F0B1F90B4C94F83C00F6 +:102D500010B9012084F83C00F6F770F803F0C0FFCA +:102D600003F0FAFFFAF7CCFE02F05CF806F042FD41 +:102D70000120207010BD00BFA01F0020B0B5054687 +:102D80000C460846D121FDF757FD08B14570B0BD8E +:102D9000022004F069F940B101464570D120087065 +:102DA0002046BDE8B040FCF77FB903481021007809 +:102DB000BDE8B040FBF74CB99988002070B50568B4 +:102DC000686810B10C46642901D9002070BD2968DB +:102DD00001FB04F66421B6FBF1F106F09AFE014610 +:102DE000B0FA80F0400909B985F853400021632EFC +:102DF00088BF012185F8511070BDB0B5046800216D +:102E000084F8511094F85210012906D194F8540016 +:102E1000002106F01DF9012006E094F8535000212E +:102E2000FFF7CCFF84F8535094F8501002291CBFD0 +:102E3000002184F85010B0BDB0B504460078617828 +:102E4000084406F0F1FE054698B12178284606F0C0 +:102E50003BF84FF6FE70688006F0A6FBA88020784D +:102E6000617828442975286104F0D2FC6875A0783F +:102E700028762846B0BD2DE9F843CBB1089CBCB1FB +:102E80008046981C1F4616468946C0B204F0ECF8EE +:102E900070B10546023021463A4606F079F96E7067 +:102EA00085F8009040462946BDE8F843FCF7FCB899 +:102EB000BDE8F883B0B505460E2004F0D5F8A0B102 +:102EC00004460720207028886080A8780228207196 +:102ED00004D16968601D082206F05AF903482146AA +:102EE0000078BDE8B040FCF7DFB8B0BD998800209D +:102EF000B0B50446102004F0B7F8A0B1054605208F +:102F0000616808222870208868802089A881281D8F +:102F100006F03EF9A07A2946A87303480078BDE878 +:102F2000B040FCF7C1B8B0BD99880020B0B50578B5 +:102F3000ADB1044603F018FC01280FD10948A1895E +:102F4000406801EB410210F82210294205D100EB44 +:102F500082002943017006F0C7FA0120B0BD0020AD +:102F6000B0BD00BF342600201FB582B100230193FD +:102F7000D2E9013412788DF80420094A02930394AF +:102F800002F11C0301AA03F0CCFF04B010BD044AF7 +:102F900002F11C03002204B0BDE8104003F0C1BFE1 +:102FA000A01F0020FF2817D0B0B5044605F012FB83 +:102FB0000A4D286850F82410204606F068FD68681D +:102FC00050F8241011B1002140F82410A868002105 +:102FD00040F82410BDE8B040704700BF14BB0200A9 +:102FE000BBB12DE9F04786B0DFF82CE0EC46664631 +:102FF0009EE8B00786E8B007D3E900451B7A8DF854 +:103000000830634601940495FFF76AF906B0BDE8FD +:10301000F0870023FFF764B960BA02000A49097813 +:1030200009B10120704709490978FF2904BF002030 +:103030007047084B064A0433022808BF131D18685E +:10304000C84000F00100704770270020B1880020C0 +:1030500008850020E0810020BCB50C4605460DF136 +:1030600007016A46204602F001FA10B14FF6FE74DD +:103070000EE09DF8070000992870696030B1421E8B +:1030800001EB400030F8024C6A7001E000206870EB +:103090002046BCBDB0B50446007A38B1254635F8A7 +:1030A0000C0FE968F1F72CFF01280AD0E07968B12C +:1030B00034F80A0FD4F80A10F1F722FF0128254648 +:1030C00004D12888FAF754FC0120B0BD0020B0BD1F +:1030D000C0F340228A7100F003028A70C0F380229C +:1030E0004A77C0F300224A71C0F3403281F83120A0 +:1030F000C0F300320A72C0F3C022CA71C2B2800BA0 +:103100009309C2F383020B71CA70704710B5012096 +:10311000FFF7B4FC0446FBF751FD0948007801288D +:1031200098BF04F025FB05F019FA02F0C7FB05F083 +:1031300007F904480078FDF7C3FE204610BD00BF24 +:103140001826002098880020B0B50B4890F86640FB +:1031500084B10A48058806F0FFFB28404FF47A71D5 +:1031600014FB010206484FF480710078BDE8B040BE +:1031700006F0BDBCB0BD00BF407B00209EBB02007E +:103180009888002010B542F28C11C4F20801086042 +:10319000D1F8980040F2B81440F00300C1F898004C +:1031A000C1F20004206881692020884742F22C0087 +:1031B000C4F2090000682068806BBDE81040004739 +:1031C00070B50D46064606F0C2FB04463046294659 +:1031D00004F0EEFC60B1006806F0FAFC054606F06B +:1031E000F3FC4FF47A71B1FBF0F0B5FBF0F500E0C1 +:1031F0000025204606F087FC284670BD7CB50C4DA6 +:103200000C4C00214FF4C072072328684668022046 +:1032100000902046B047286800214FF4C072072371 +:10322000D0F80CC0204602B0BDE87040604700BF37 +:10323000A401001000A00C4080B50B4902220A72C4 +:103240000A4A10704FF6FE70088005F0D9FC04F0B1 +:1032500019F8074804F04CF8FFF790FB05F086FAE0 +:10326000BDE88040FEF72AB97087002099880020C9 +:10327000942500200B48007802280BD20A48807B56 +:10328000800708D509484FF4807140F6C4120078D1 +:1032900006F030BCF6D105484FF480710078FAF79B +:1032A000D7BE00BF18260020407B00209988002050 +:1032B000B0B50546242003F0D7FE98B1044632206D +:1032C000A9681B2220702878A0706868606004F1EB +:1032D000080005F05DFF044821460078BDE8B040D5 +:1032E000FBF7E2BEB0BD00BFCC24002070B5FEF7F6 +:1032F0005FFEC0B10446451C0026207886420DD2F0 +:10330000284606F0BEFB30B100790138012802D80A +:103310002846FBF7C1FD08350136EEE72046BDE83B +:10332000704006F07FBC70BD80B50C490978022959 +:1033300008BF012800D080BD0948C0780028FAD114 +:10334000FDF798FD06F00EFA18B1BDE88040F6F7DB +:1033500087BE0020BDE88040FEF718BA182600207E +:10336000C4260020F8B50D4F06461C461546786861 +:1033700006F005FC681EB0FA80F040098001012CBF +:1033800008BF8030796834220923087238463146F4 +:1033900001B0BDE8F040FCF73FB800BF7C2600203C +:1033A0001FB50D4C030A002962685370107018BFD6 +:1033B0000121880115220223A0704FF6FD70ADF89F +:1033C00004000F208DF80C0001A92046FCF724F81A +:1033D0000021A17004B010BD7C260020B0B50021F2 +:1033E00001600C490A6892B100254FF6FE74AB1DCE +:1033F000182B0CD0555BA5421D46F8D11A44063A4D +:1034000002600868C118002001F8020CB0BDC82095 +:10341000B0BD00BFE0260020B0B586B00446002055 +:103420006D4618212075284605F04EFD2846214698 +:103430000A2205F0ADFE6089ADF80A0004488068F4 +:10344000D0F8F81228468847002006B0B0BD00BF6B +:103450000C0100202DE9F0411D4616468846044621 +:1034600005F026FF90B10746062003F0FDFD68B188 +:103470000146868084704570FD200870786881F868 +:1034800003800078BDE8F041FBF70EBEBDE8F08197 +:1034900070B586B001AC1421FF22204605F00EFD68 +:1034A000094800260578AE420AD2F1B2082014225B +:1034B0002346FCF75BFC01360A28F4D10A2000E021 +:1034C000002006B070BD00BFCDBC020010B50246A2 +:1034D0000C480023006838B10479944202D1C488B2 +:1034E0008C4203D00346F5E7002010BD0549002BB0 +:1034F00018BF194602680A6006F094FB00F04EFD02 +:10350000012010BDEC2600202DE9F04105460B48B6 +:103510000B4E88460027047864B13078A84206D163 +:103520003046414604F0AAFE002818BF01370E3687 +:10353000013CF1E7B8B2BDE8F08100BFE2BC020097 +:1035400018870020B0B50D4D0446E8688069007802 +:1035500001280AD104F03CFB40B1E8688069017899 +:10356000012902D10021017024B1B0BDBDE8B040F5 +:10357000F3F7DABABDE8B04003F04ABF0C0100200F +:1035800010B504460B480068A04204D80A48806879 +:10359000D0F84C058047B4F1FF3F04DC0648806852 +:1035A000D0F84C05804705F0C9FFBDE8104006F093 +:1035B00071BA00BF388800200C010020B0B5044665 +:1035C0000A480068A04204D809488068D0F84C0531 +:1035D000804705F0B3FF0546064804602046F7F72C +:1035E000EBF92846BDE8B04006F054BA3888002010 +:1035F0000C0100203C880020B0B54FF6FE704FF65D +:10360000FF7101F073FB00B1B0BD0848084D0478AC +:103610000020002CF8D0A97C09B1697C19B9288850 +:10362000FFF74CF928461C35013CF2E7D5BC0200F7 +:10363000DC5B0020B0B505460C480C46007801283C +:1036400009D80948808CA04205D1284606F0C5F962 +:1036500008B10830B0BD2846214601F047FB0028DC +:1036600018BF1030B0BD00BF407B002018260020DE +:10367000B0B50B4D0C4695F87210814228BFB0BD15 +:10368000FEF7FEFA074864210480E87900FB01F2A6 +:1036900005484FF400710078BDE8B04006F02ABA42 +:1036A000407B0020327700209888002070B50D4EB6 +:1036B0000C46B18CFFF7BEFF88B10546807804F058 +:1036C000E7FA697859B150B1884298BF0846727BD1 +:1036D000012A18BF0846A0429CBF012070BD0020EF +:1036E00070BD00BF407B002070B504460C4801212E +:1036F0000160D4E91001D4E91623851841EB0306D3 +:10370000280C002240EA064100F00CF8D4E9162308 +:10371000D4E9060150346CC4BDE87040084700BFCE +:103720000420094010B50C4605F04AFF0B498A6990 +:10373000A31A0632B3F1004F09D8131BB3F1FF3FB0 +:103740002346C8BF1346A24298BF23461A460A60C2 +:1037500000B110BDBDE8104005F038BF1820094089 +:1037600010B5044608480949094A0A4BC4E9021041 +:10377000002004F11001C4E90032A061064804F001 +:1037800041FE204610BD00BFA99B0200AF9B020076 +:10379000A39B02009D9B02009C26002010B588B0D0 +:1037A00001AC0A491C22204606F0AAFA0020094A68 +:1037B000002123468DF810000A20039002208DF886 +:1037C00004000348EBF73AFC08B010BD84B90200CE +:1037D000207C00203D980200B0B50D49CA680368FE +:1037E00044682360436804686360C46C8369256827 +:1037F000A54204BF9A43CA608A69824204BF00227C +:10380000CA6101220A74022180F82010B0BD00BFF5 +:103810003822002000B1704710B50B4C2020EFF388 +:10382000118180F31188207C28B1084890F8480065 +:1038300008B9FEF7EFF80020207240F2000CEFF319 +:1038400011808CF3118810BD38220020A01F0020A9 +:10385000F8B50E460B4900281C464D68314618BF86 +:1038600005462F682846002A08BF0822B8470746A1 +:1038700030B9054A204600212B46009601F020FB76 +:103880003846F8BDA01F0020DBB0020080B50D480F +:103890000078062809D005280BD00228BDE8804012 +:1038A00018BF05F06BB806F058B9BDE8804006F0C7 +:1038B00051B906F003FA00B180BD1C20BDE880407C +:1038C000EEF70ABFB7880020BCB5054600200C46BD +:1038D0000DF10703002101228DF80700032005F0F8 +:1038E000D9FA00B1BCBD9DF80700FF2D0DF107020C +:1038F00014BFA04320438DF807000121032005F0E9 +:1039000085FFBCBD10B5427801788378C478002A61 +:1039100018BF41F00201002B18BF41F00401002C38 +:1039200018BF41F008010279002A18BF41F0400198 +:103930004079002818BF41F08001C8B210BDBFB562 +:1039400004460DF10205082234F8020BADF802001E +:10395000A81C214605F01CFC207AC9210D222B460B +:103960008DF80C00B4F80900ADF80D004520FEF705 +:1039700085FE002004B0B0BD01467F30C0B20328F0 +:103980003CBF042070470120012911D080290FD0AD +:1039900003290DD0022904BF0220704701F0FE0068 +:1039A000842804BF032070470020882908BF032013 +:1039B00070470000B0B50B49402200240A60802205 +:1039C0000A60C1F8FC42056895F8260020B1064857 +:1039D00006F03CF985F826400220BDE8B04000F032 +:1039E000C7BE00BF04440240307E0020B0B550B1D5 +:1039F00004460078102200F07F010520FDF786FACA +:103A000000202070B0BD064800250488A542F9D2E8 +:103A1000A9B205201022FDF779FA0135F6E700BFBB +:103A2000C4BC0200B0B50D4611461A46F6F748FF71 +:103A300090B12946044604F021FC68B1204629468D +:103A400000F0DAFC30B96588204605F0BFF9284659 +:103A5000FDF7BAF80020B0BDB420B0BD70B50C4B76 +:103A60000A4A1C780432002374B112F8245B002641 +:103A70008D4298BF012685424FF0000528BF0125E1 +:103A8000013C35402B44EFE7D8B270BDB054002064 +:103A9000E6BC020010B5046894F85220012A05D152 +:103AA00094F85400012105F0D3FA02E0FFF786F9FB +:103AB00050B194F8500002281CBF012084F8500037 +:103AC000012084F8510010BD002010BDB0B50B4D91 +:103AD00004462878A04201D10020B0BD58B908485A +:103AE0008068D0F83803804728B12046F4F712FEEA +:103AF00008B12C70F0E7E220B0BD00BFAB88002019 +:103B00000C01002070B5B0B10546007A00F0FE004F +:103B1000022810D12846F4F745FEFF280BD02A7A58 +:103B200000210646002401F05FF82A7A3046002181 +:103B300001F034FE00E0E824204670BD86B0044663 +:103B400009486D46047009480068EFF3118180F35D +:103B500011882846152105F0B7F9054A2846152190 +:103B6000234604F0D4FFFEE786270020B4BC020001 +:103B700078BA02004FF6F871884206D30830BF22A7 +:103B8000C1B222FA01F1C90701D1002070470549ED +:103B900000B251F82010044802780220114208BFF8 +:103BA0000120704744B9020090880020F0B50B4A0C +:103BB0000B4D00234FF4877654888B4224BF084670 +:103BC000F0BDA7B201340133EF5DA4B200F8017B70 +:103BD000B4FBF6F707FB16445480EEE7BC26002042 +:103BE0001C700020F8B5094F0C46054605F0AFFEE5 +:103BF000064607480749084AC7E90254FAF79CFEF7 +:103C00003046BDE8F84005F07EBF00BF70240020BC +:103C10002A710020387200201D3C0200B0B50C460D +:103C20000B4D0021E880698010B1E96801B1884737 +:103C30003CB100202870AA68A9881AB111B92046A1 +:103C40009047A98811B12869FAF7A2F9B0BD00BF61 +:103C50007024002070B50B4E05460B4C306881680F +:103C60002046884700F00300002128603068426841 +:103C70002046904730688168204688470028F9D15F +:103C800070BD00BFD8010010004003402DE9FC4189 +:103C90000B4C0746984615460E46606808B18047AB +:103CA00058B10421E0682A464346009106EB4731AB +:103CB00005F03CF9C00FBDE8FC810B20BDE8FC819C +:103CC000A023002010B5FEF70DF9012003F0A4FA9F +:103CD000044605F033FC08490A683AB105F0DAFEFB +:103CE0004CB12046BDE8104005F0FABC0C60BDE8C0 +:103CF000104005F0CFBE10BD0C2400207CB50B4D4C +:103D00000B4C00214FF040521C23286846680320CA +:103D100000902046B047286800214FF40072092324 +:103D20004568012000902046A8477CBDA4010010F2 +:103D300000A00C40B0B50C4D297A09B10720B0BDE8 +:103D4000A98CFFF777FC0028F8D0044680786D7BBB +:103D500003F09EFF012D03D16178884298BF084689 +:103D6000002808BF0720B0BD407B0020B0B505F09B +:103D7000E5FB0A4991E83C000F1D1CC70B69084C84 +:103D80001C4485EA950383EA43030C61534083EAAC +:103D900002150D6005F07EFE6019B0BD1C86002086 +:103DA000C5870500F8B50C46054605F0C7FB2B1D79 +:103DB0006E690ECB8F1AA74238BF3C46224423447B +:103DC000B24288BF16466E61B3FBF1F606FB1131B5 +:103DD000C5E9022105F05EFE2046F8BD70B5066813 +:103DE000054605F0ABFB0446707A70B9012070728D +:103DF000284602F067F8686805F08AFC2846EDF767 +:103E0000BDFC2846002103F01AF82046BDE87040AA +:103E100005F040BEF8B5D0E9006505F08FFB04461B +:103E2000307870B1287905F0F3F9012806D12868B7 +:103E300000274760301D05F0D3FE37702879F1F771 +:103E400005FD2046BDE8F84005F024BEB0B58AB0B7 +:103E5000F1F756FD04AD82200021182200242B46E4 +:103E600005F018F858B9681C69461022CDE90244DB +:103E7000CDE9004404F0DCF8B0FA80F044092046B3 +:103E80000AB0B0BDB0B585690C460846294605F0B4 +:103E900076FE287A2072B5F80900608104F10C00E2 +:103EA000E97A0329217506D105F10C0105F067FEB9 +:103EB000287DA075B0BDA9890180B0BD1CB5816900 +:103EC0000B880A4909888B4204D1094A194600F037 +:103ED0001FFD1CBD017C427C48F20304CDE900417A +:103EE000811C1046802202F06BFD1CBD70870020F3 +:103EF000FC870020BFB514464FF6FD720A4DADF8A1 +:103F000004200F228DF80C206A6822F8020B10465C +:103F100005F035FE686813220B23847201A9284638 +:103F2000FBF77AFA04B0B0BD7C260020BCB54FF098 +:103F3000FF316C460028CDE9001118BF0446AB20C4 +:103F40000021224601F074FE054D2146284605F069 +:103F500016FE712008212A4605F058FCBCBD00BFA2 +:103F6000AC26002010B50C4A1278A2B103466E2888 +:103F700028BF6E23323B322838BF002308783C2408 +:103F800043431BB2012A08BF93FBF4F082B2FF2A1D +:103F900028BFFF20087010BD9E270020F0B585B017 +:103FA0006C460B4F0026A51C3F687FB13879B91DC0 +:103FB00012228DF80000284605F0EAF8F1B2082038 +:103FC0001422234602F0FCF90136EDE705B0F0BDFE +:103FD000EC260020F8B50C4D044600262846002E9D +:103FE00008BF2E46006858B10179A14206D1016888 +:103FF0003160076805F016FE3846F4E70646EEE73E +:10400000BDE8F840FFF7CABFEC26002010B50C4908 +:1040100001F110031C682CB1844205D004F118038F +:104020002246F7E7022010BD0B69834219BF816960 +:10403000916182690A6105F0F5FD002010BD00BFA5 +:10404000AC22002010B50C4A12688AB1FF2911D0A9 +:1040500013788B420ED854781C448C420AD9C91A62 +:10406000C01A5268C9B2C0B2515C105C884201D11A +:10407000002010BD012010BD6088002009490848BB +:1040800089680088D1F8D420D084074800220270C3 +:10409000D1F8D4000549C08C48860549C8817047CD +:1040A000467300200C010020AE880020E87F00202D +:1040B000E886002009480A49C0680A7B406802F087 +:1040C000F002033200780A73064A12785043064A17 +:1040D0001278504380008860704700BF0C010020B8 +:1040E000A8850020B0880020B688002010B50B4CB1 +:1040F000207830B101280AD0022803D1F8F743FA1A +:1041000005E010BD06488068D0F84C0580470020C7 +:104110002070BDE8104004F081BE00BFA027002041 +:104120000C010020B0B5044605F008FA054602204F +:104130000021F7F7BDF808490648224609680068DB +:104140008B694FF0FF3198472846BDE8B04005F035 +:10415000A1BC00BFD826002030880020F8B505F0AB +:10416000EDF9044608480068C06B804705460748DB +:10417000067807480768204605F08CFCE81BB1006C +:10418000B0FBF1F0F8BD00BF30880020B0880020FF +:104190002C8800200C4800224FF470038168D1F86D +:1041A000D8100A608168D1F8DC100A608168D1F803 +:1041B000E0100B608168D1F8E4100B608068D0F8E3 +:1041C000E8000260704700BF0C01002080B50B487A +:1041D00081890131818105F0B1F909490A78862A7E +:1041E00008D187220A7005F055FCE920BDE880401F +:1041F000EEF772BABDE8804005F04CBC4486002062 +:10420000B488002080B50948012101700848406841 +:1042100018B10848818901318181F02000F048FC03 +:1042200005480078BDE88040E5F71ABF2126002048 +:10423000A885002094860020B7880020F0B585B0BE +:104240000B4C246884B1256A75B1DDE90C6CDDE99D +:104250000A470004049100210130CDE90047CDE96F +:10426000026C0024A84700B10A24204605B0F0BD26 +:104270005C270020F0B589B005AD0C460146102240 +:104280001027284605F054F901AE304605F026F90E +:1042900005483146CDE90347CDE90154006805F0F2 +:1042A000EDFB09B0F0BD00BFF887002010B590F815 +:1042B000480088B12020EFF3118480F3118807486B +:1042C00041690139416105D1054884F31188016ACA +:1042D0000020884784F3118810BD00BF38220020D9 +:1042E000381F002080B568B101460068D1E901237C +:1042F00048B111461A4604F029FB0648BDE8804043 +:1043000004F024BB80BD04480021BDE8804004F0D7 +:104310001DBB00BFA2A20200A4A2020070B50B4602 +:104320000B490025312D11D031F835602C4601356F +:104330008642F7D101EBC4004188994206D140681A +:1043400011461A46BDE8704004F022BF70BD00BFA0 +:1043500010AA020070B50948094C84420BD0094DDF +:10436000094EB54207D0F5E8020110F8012B54F8C8 +:1043700022209047F5E705F07DFC70BD9CC002004F +:1043800090C00200E4C0020034C1020083B0029079 +:10439000002001918DF8030082420BD00299095C44 +:1043A000019B1B5C013059409DF8033019438DF887 +:1043B0000310F1E79DF80300B0FA80F0400903B064 +:1043C00070472DE9F041804610461E4617460D46BF +:1043D00002F04AFE70B104462FB126B120463146A4 +:1043E0003A4604F0D5FE257040462146BDE8F0412E +:1043F000FAF75ABEBDE8F08170B5B0B14279A2B10A +:10440000831D14461D4662B11E888E4204D1013CB4 +:104410002606447102D108E025F8026B0233013A06 +:10442000F1E720061CBF012070BD002070BD000018 +:1044300010B5017840786424012808BF632429B1AD +:10444000052004F0F5FE201AA0F10D040448007BBD +:1044500020B104F0EDFE201AA0F10E04E0B210BD70 +:10446000407B00200549064A0A6006490870064854 +:10447000064901600648074901607047F42600209C +:1044800015F900003C260020F02600208974010068 +:10449000F826002011900200B0B505460C2002F06D +:1044A000E3FD80B104460620696808222070288850 +:1044B0006080201D04F06CFE034821460078BDE8B2 +:1044C000B040FAF7F1BDB0BD99880020B0B50648FC +:1044D000084B0649084C064A084DC0E90152C0E99C +:1044E00003414361B0BD00BF50240020C19B0200C6 +:1044F000F1E50100A99400006163000049CC0100CE +:10450000B0B50648084B0649084C064A084DC0E9B4 +:104510000152C0E903414361B0BD00BF50240020F7 +:10452000C19B0200F1E50100A99400006163000055 +:10453000B17D0200B0B50648084B0649084C064A52 +:10454000084DC0E90152C0E903414361B0BD00BF5D +:1045500050240020C19B0200F1E50100A994000055 +:1045600061630000716C0100B0B5054602F0FCF813 +:10457000044601280ED10848A9892B78406801EB30 +:10458000410110F821209A4300F8212000EB81001E +:1045900004F0AAFF2046B0BD34260020F8B5094833 +:1045A0000A4D0027067808480488BE4208BFF8BDB7 +:1045B000B9B2022022462B4601F002FF0E35013728 +:1045C000F3E700BFE2BC0200C2B40200188700207B +:1045D000E0B50A48007801280FD80120F7F7C4FC9D +:1045E0000749ADF80600C8820DF106015320FDF71A +:1045F00045FDBDF80600FCF791F98CBD182600209A +:10460000407B002010B504460948807B000707D492 +:104610000648006820B1074808210078F9F718FD1E +:104620002046BDE81040EFF7D0BE00BF4424002074 +:10463000407B002095880020F8B50A4E054605F01D +:1046400086F9044608482A46002375800027D0E9E9 +:10465000011004F0F0FE00B17780204605F053FA17 +:104660007088F8BD6426002048230020B0B50C46B1 +:1046700000210546224603F0CDFC0748007800B132 +:10468000B0BD7C2C04BF0548C570044905EB45004E +:1046900001EB80008475B0BDA0230020A080002025 +:1046A000F8B50B4F044600266D463978F0B28842C3 +:1046B0000AD200212A46042304F032FD9DF80000AE +:1046C000A04202D00136F0E7FF26F0B2F8BD00BFED +:1046D00097880020F8B505F03AF90A4E0446756847 +:1046E0005DB145B128682F6904F010FF284605F038 +:1046F00099FA3D46F5E7002070602046BDE8F84095 +:1047000005F001BA6C26002070B50A4C03462078EB +:104710000E280CD8084E00EB400506F8350006EBD5 +:10472000C5056A610022E9602A74C5E90132411CAD +:10473000217070BD44250020B46E002008490A4B4A +:10474000421808499A42096808D801F44001B1F5B5 +:10475000000F03D105490968496C0847704700BF3D +:104760005C8F82FFB44F0050B71E0500F0010010AF +:1047700070B50B4D04462E1804F0E0FE96F8431178 +:10478000013986F84311090605D10121AA68A14023 +:1047900022EA0101A96005F07DF9002070BD00BF8B +:1047A000D81B0020B0B5054604F0C8FE04460848F2 +:1047B0000178A94301700078000704D40548082156 +:1047C000283005F047FA2046BDE8B04005F062B950 +:1047D000D01E002070200020F8B515460E46074672 +:1047E00004F0ACFE044608484068B84201D00325F6 +:1047F00004E03046294601F00DFB0546204605F051 +:1048000049F92846F8BD00BFD01E0020B0B50A4ABD +:10481000931C0A4A14780022944209D01D888542CC +:1048200003D113F8025C8D4203D00A330132F3E75F +:104830002246D0B2B0BD00BFD07E0020D9BC02005D +:1048400010B586B08AB19368062B03D35C1C01D0E7 +:1048500000200DE0002404930194D2E90034D268D2 +:10486000CDE90234059201AA00E0002204F03EF8EE +:1048700006B010BD2DE9F04106460A4815460C4623 +:1048800000278046BC4209D0D8F80020E95D306896 +:104890009269904708B10137F4E73C462046BDE8ED +:1048A000F08100BFD001001080B5094800780228CF +:1048B00002D24CF2101107E008D10120F9F78AF872 +:1048C0000449002808BF01310348018080BD00BFB2 +:1048D000182600202182FFFFFC8700201CB582697A +:1048E000094913785278098943EA022211400AD013 +:1048F000064A047C1388427CCDE90014811C1046D2 +:10490000002200F05BFE1CBD26870020708700207F +:1049100010B50B4B0C0A5B68597000219C70197024 +:104920001178D970517800F111021971811C10466B +:1049300048F203020523BDE81040FAF76DBD00BF41 +:104940007C2600201FB5044600208DF80000684634 +:104950002146043005F013F904F062FB00B11FBDDD +:104960006846F6F781FE0128F9D00DF10E0200200D +:10497000214601F015FB1FBD10B50A490122087A36 +:104980000A7209494C6944B122684A61FEF742FF44 +:104990002046BDE8104001F05BBBBDE81040FEF7CB +:1049A00039BF00BF38220020A01F002080B50B4A6D +:1049B0000146106878B143681B788B4205D00246E7 +:1049C00000680028F7D1022080BD0168116005F061 +:1049D00029F9002080BD012080BD00BF2088002073 +:1049E00010B5A1F1FE020A4BB2FA82F254091B681B +:1049F00053B1DA888242FAD11A79240605D1521AC3 +:104A0000B2FA82F25409F2E7FE22104610BD00BF4E +:104A1000EC26002070B586B001AC1421FF222046A0 +:104A200004F04CFA074800260578AE4224BF06B0D1 +:104A300070BDF1B208201422234601F0C1FC0136FA +:104A4000F3E700BFCDBC02001FB5014604208DF87E +:104A50000000087A022806D10888ADF802006846EE +:104A6000F4F778FA06E06C46201D04F058FC204666 +:104A7000F6F7FAFDBDF80C0004B010BD0849094A6C +:104A8000096852F82130034442F8213006498A6807 +:104A900001328A6005490A6810440860EFF75ABD80 +:104AA0001488002048810020B82400201C880020A1 +:104AB0007CB504461630C0B2092810D8084EB0683C +:104AC000D0F8282401AD2046294690470198294670 +:104AD00001300190B068D0F83024204690477CBD6A +:104AE0000C01002010B50B4CE0688169097802299F +:104AF00007D1C168097821B1A068D0F84C0580477A +:104B0000E068C168097819B9806901780229FCD088 +:104B100010BD00BF0C010020094800210122C18105 +:104B20004175084942820978017507498968D1F8B9 +:104B3000D41091F8242091F8311001744274704718 +:104B4000A0830020B58800200C01002010B50A4881 +:104B5000FE210A4C4170A068D0F8E800006848B116 +:104B6000E0680121C068017003F0CEFBE06800211D +:104B7000C068017010BD00BF142500200C0100208A +:104B800080B50A480021017001F03EFBF7F73CFBBD +:104B90000748C168C968097801B180BD80680021F3 +:104BA000D0F858240020BDE880401047AD88002090 +:104BB0000C01002007480849084AC0E904210849B7 +:104BC000084AC0E9082140F20551C183F721C173A9 +:104BD000704700BFE87F0020F8860020C0870020D3 +:104BE00008850020E081002070B50B4C094B022A9B +:104BF000254608BF1D4601262D6806FA00F009B1BA +:104C0000284301E025EA0000022A14BF2060186052 +:104C100070BD00BF08850020E081002010B50B4C5E +:104C2000E068C068007828B9A0680021D0F858244E +:104C30000120904704F082FC04F02CFFA068D0F81B +:104C4000B800806EBDE81040004700BF0C01002096 +:104C5000B0B50D460446FFF781FAA84205D30848CF +:104C60008068D0F8E0000068054405486560806809 +:104C7000D0F8DC10D0F8EC242046BDE8B040104756 +:104C80000C01002010B50B4CA268D2F8E030D2F82D +:104C9000EC2052F821101960A268D2F8E4201160CB +:104CA000FEF76EFCA068D0F8E0000068BDE8104098 +:104CB00002F0C0BB0C01002010B58EB00C4691B1C3 +:104CC000014601AA2046ECF7F9F99DF80A0050B117 +:104CD0009DF805209DF820300020214603F00AFAB7 +:104CE00008B1A42000E000200EB010BDB0B502460F +:104CF00009484FF6FF740378084801E01C30013B77 +:104D000043B105889542F9D145898D4218BFA1422A +:104D1000F4D1B0BD0020B0BDD5BC0200DC5B0020EA +:104D2000B0B50146094800234FF6FE7402780848E2 +:104D30004AB10588A54203D0DDB28D4204D00133CB +:104D40001C30013AF4E70020B0BD00BFD5BC020022 +:104D5000DC5B0020F8B50D460A490446084809788E +:104D600002304E1C013E09D0294600F11C0702F01A +:104D70009CFC00283846F5D027F81E4CF8BD00BF33 +:104D8000DC5B0020D5BC020080B5042000F066FD8D +:104D900008490978884284BF012080BDFF2000F0C7 +:104DA0005DFD0146044802780020914288BF012041 +:104DB00080BD00BFE3BC0200E4BC020080B540F24D +:104DC000011000F08DFF02F0C3FD0748007808B124 +:104DD000012807D105480078012803D1BDE88040AB +:104DE000FAF736B980BD00BF18260020BA27002088 +:104DF000B0B50B4A0023156C946CC0E901452A78C4 +:104E000041B1BE2A06D1691C631C11F8014B013B5C +:104E1000BE2CFAD00360B2F1BE0018BF0120B0BDB5 +:104E2000381F00200B4890F8641001B17047012131 +:104E300080F864102021EFF3118281F311884FF084 +:104E4000FF31C162016C826C21F007011144083905 +:104E5000C1637047381F0020B0B50446826081618D +:104E600000201D462075D3E9010120610648E1615B +:104E7000214603F0C7FA287820B12046BDE8B040AB +:104E800003F02FBEB0BD00BF0820002070B50B4A54 +:104E9000D368C56C84696E682343056046603060E2 +:104EA0006860D360012380F820301374202081F3E0 +:104EB0001188EFF3118180F3118870BD3822002032 +:104EC000BFB50A4C1C34A04208BFBFBD01AC0028CE +:104ED000089D18BF0446064884E82C0050F82100BD +:104EE00003F034FD2046FFF7FDF9FEE7A01F002088 +:104EF00074BC02000A48083880F308880948016831 +:104F000041F47001016000BF00BF04F0B5FE08B1BC +:104F1000FFF720FA03F01EFF002004F0A2FD00BFFF +:104F20000040012088ED00E0B0B5A0B10546007A50 +:104F300000F0FE0002280ED128461446F3F732FC9A +:104F4000FF2808D02A7A002C18BF0124214600F03F +:104F500025FC0020B0BDE820B0BD10B52021EFF346 +:104F6000118481F31188017C02290CD102688168C7 +:104F700043681A6000220274426800684260084672 +:104F80002146FFF783FF84F3118810BD1CB5ADF8EF +:104F9000061009490C6864B10DF106010091114633 +:104FA0001A460123A0470021002808BF6FF04D01D9 +:104FB00000E0B621C8B21CBDF023002070B54E8BB6 +:104FC0000C46054604F0F0FA864203D02846FAF76C +:104FD00053FD30B104482146C2682846BDE8704000 +:104FE0001047012070BD00BF50240020B0B50C4612 +:104FF000054603F005FE0146284602F056FB20B1A7 +:105000000548C08A20800120B0BD28462146BDE861 +:10501000B04000F0FABC00BF407B002010B5F8F7AC +:10502000EBF905480549064A064B074CC0E9014320 +:10503000C0E9032110BD00BF2C24002055D1000081 +:10504000ED73010051610100253A02007FB54FF078 +:10505000FF30094E00250390CDE9010001AC3088F6 +:10506000854228BF7FBDA9B201200C22234601F052 +:10507000A7F90135F3E700BF342600207FB54FF0D4 +:10508000FF3000266C46CDE90200CDE9000006485D +:105090000578AE4228BF7FBDF1B20320102223461F +:1050A00001F08EF90136F4E7E6BC020080B508484D +:1050B00090F8281001B180BD012180F8281004F07B +:1050C00099FB04480021FEF74BFB0349486080BD73 +:1050D000381F00207C840020A01F002080B50A49D2 +:1050E000142004F0D4FC1420002103F0B1FF0120AF +:1050F00004F07BFC1420012103F0AAFF4FF40C7094 +:10510000BDE8804004F071BC01640020BFB50446D6 +:1051100053B100200190D3E901051B7803958DF868 +:105120000430029001AB00E0034B2046FFF794FEF1 +:10513000204604B0B0BD00BFDCBB0200FF2808BFA2 +:105140007047B0B50D46044604F0F8F90649C5F3BA +:10515000024311F8242002F0F8021A4401F8242036 +:10516000BDE8B04004F096BC0210084010B50146FE +:1051700008480023027808484AB10478FF2C03D07D +:10518000DCB28C4204D00133013A0E30F4E7002047 +:1051900010BD00BFE2BC02001887002080B50346A6 +:1051A0000848007858B908481978007801B908B952 +:1051B00029B120B94520CB210122FDF75FFA00205B +:1051C00080BD00BF95270020F4240020BFB5044611 +:1051D000082234F8020BADF8040001AD2146A81CEA +:1051E00003F0D6FF2089CA210C222B46ADF80E0011 +:1051F0004520FDF743FA002004B0B0BDB0B50D4620 +:10520000044604F03EFC80B101790139C9B203299A +:105210000BD8012D18BF012902D8008804F00EFD1B +:105220002046BDE8B040F9F737BEB0BDBCB5044676 +:1052300005200D468DF8050001A801F021FB58B1AD +:105240000169220ACA7041F203320D718C700A8022 +:105250004480F9F743FBBCBD0120BCBD10B504F090 +:1052600076FB0446074800212022002301800649DE +:1052700088680C3102F0D5F92046BDE8104004F0F2 +:1052800042BC00BF642600204823002010B504461D +:1052900001F0A2FEA0420BDDA0B2FAF7F1FA054838 +:1052A0000121817104480068BDE81040F9F710B988 +:1052B000FEE700BF342500204C880020F8B50A4FD7 +:1052C00006460D464FF0FF311446386804F058FB8F +:1052D000304629462246F4F703FF0446386804F0B6 +:1052E000B5FC2046F8BD00BFDC250020F8B50A4F0C +:1052F00006460D464FF0FF311446386804F040FB77 +:10530000304629462246EDF747FE0446386804F049 +:105310009DFC2046F8BD00BF0C24002070B5094A52 +:105320001378322B04BF012070BD074E046803EBD5 +:10533000C305406801331370721974515060002026 +:10534000117270BD8E270020186A002010B586B03B +:105350006C461621A01C03F0B7FD02208DF8080052 +:105360000548418B808CADF80A002046ADF800104E +:10537000FEF752F806B010BD407B002070B5144611 +:105380000D46064604F0E3FA3168A94218BFA4F1BD +:105390000C0655F80C1C3160FF2105F8021C002199 +:1053A00045F80C1CBDE8704004F0ADBBB0B5044638 +:1053B000012000FA04F504F0C1F807498A682A437D +:1053C0008A60214491F84321013281F8432104F09D +:1053D00061FB0020B0BD00BFD81B00200A48406818 +:1053E000826800F13801134652680AB18A42FAD144 +:1053F000597B090706D1408F40F60901884204BF56 +:105400000120704700207047D01E002010B550B911 +:105410000020F6F7A9FD04464FF6FE70844206D13F +:105420000548007818B10020F6F79EFD0446EFF716 +:1054300019FA204610BD00BFE7BC020010B50A4BA8 +:105440000749084A1B780439013A43B112F8014F61 +:10545000013B04318442F8D100200860107010BD77 +:10546000C87A002040840020D2BC0200B0B51446A7 +:105470000D46F7F7F1FC07490978884224BF04205C +:10548000B0BD054901EBC00041782970406820603B +:105490000020B0BD9ABC0200E0270020E0B5B0F9C2 +:1054A0000E10002901D4027B02B18CBD89B21329F0 +:1054B000FBD0037C427C41F40041CDE90013811C08 +:1054C00010468422002301F07BFA8CBD09498A78BA +:1054D000920703D5084A1278824200D170470C2007 +:1054E0008870088840F0020020F0050008800C2039 +:1054F00002F074BD26870020D8270020B0B5094CE3 +:10550000E17809B1C17801B1B0BD40780028FBD184 +:1055100005480025A0F870500120F5F77DFFE570E3 +:10552000B0BD00BFCC240020407B0020B0B5856911 +:105530000C460421284600F0F1FF20602879052858 +:10554000207102D868796071B0BDFE2805D36979F1 +:10555000FF28A17104BFE8882081B0BD80B508494B +:105560000870084909780843000602D1062002F0B5 +:10557000BFFA054820210078BDE88040F8F768BDF3 +:10558000BB880020C4260020998800201FB50A4B44 +:10559000ADF804005C68A170010A20700220E2707E +:1055A00001228DF80C006170184601A90423F9F757 +:1055B00033FF04B010BD00BF7C260020BCB50A4CF0 +:1055C0008DF807000DF1070063681A70069A150A36 +:1055D0005A7010229D70A27048F215020323F9F749 +:1055E0001BFF0021A170BCBD7C26002010B500224D +:1055F0000A60094A12686AB16FF017039C1D09D04E +:1056000013441B8B83422346F8D1101912300860D3 +:10561000002010BDC82010BDE0260020B0B588B025 +:1056200004AD044669461022284603F07BFF064875 +:105630002946006804F014FB05992046102203F067 +:10564000A7FD08B0B0BD00BFF087002070B50546CB +:10565000142016460C4604F0E7FA58B10649012317 +:105660000661846083734FF499730A688381C0E98B +:105670000025086070BD00BF208800200749087021 +:105680000749097831B9074991F82F1011B1064936 +:1056900002220A7048F20201FBF78CB99F880020B1 +:1056A00018260020AC220020AC27002070B50A4E3E +:1056B000084C0025042130782570F9F799F93078E5 +:1056C0000421F7F7FDFE84F82B500020BDE8704060 +:1056D000E3F7C6BFAC2200209F8800207CB50A4EAD +:1056E000044606208DF807002046318903F003FCAC +:1056F0000DF107000121FAF767FA318905462046C6 +:1057000003F002FC28467CBD0C24002080B50A482A +:1057100042F204414088884206D042F20341884266 +:105720000CBF0020E92003E0012000F099FD1B20C0 +:10573000BDE88040ECF7D0BF3086002010B50A4AA3 +:1057400012687AB1137883420CD854781C4484428E +:1057500008D9C01A526891F90040C0B2105684426C +:10576000C8BF087010BD00BF6088002078B110B5B8 +:105770000169074C206029B906488068D0F84C05BB +:1057800080472068406804490860BDE810407047C1 +:105790005C8800200C0100203088002010B50A4CE5 +:1057A000084B0434022A08BF1C1D2268012303FA97 +:1057B00000F0002922EA000318BF42EA0003236038 +:1057C00010BD00BF08850020E081002080B503F0F7 +:1057D000B5FE08490A7842F002020A7004F05AF94C +:1057E000054800218068D0F894000078BDE880402A +:1057F000F8F72EBC8C8800200C01002008480021FE +:105800000170084801700848C168C968097801B189 +:10581000704780680021D0F858240020104700BF4E +:10582000B4880020212600200C010020B0B50446D9 +:105830000948056855B1A868204205D0D5E903326A +:1058400020460021984718B92D68F3E70020B0BD25 +:105850004FF0FF30B0BD00BFD81B002010B5A0F145 +:10586000FF02094B0021B2FA82F252091B6843B1D0 +:105870005C7B0433241AB4FA84F46409144321448D +:10588000F4E7C8B210BD00BF54880020F8B580B15D +:10589000054609480C4600260168374651B10E46B8 +:1058A00008462146A84700210128F6D0301D3E4673 +:1058B000F2E700273846F8BD54880020F8B5094DB6 +:1058C000094E2C685CB1D4E90007006AB047206833 +:1058D000B0476069B0472046B0473C46F2E7002039 +:1058E0002860F8BD54880020259C020010B50A4AA3 +:1058F00000F11C01007C0023927883420AD2140636 +:1059000008D011F8334004F08D04812C08BF013A0F +:105910000133F2E7D0B210BD4426002010B50A4A88 +:1059200000F11C01007C0023527883420AD2140645 +:1059300008D011F8334004F00D04012C08BF013ADF +:105940000133F2E7D0B210BD442600207FB51346E4 +:10595000D0E90A24BE251AB104F8015B013AFAE73E +:10596000D0E90A54D0E90D26C06BCDE900160290AB +:10597000291F2046F8F7F6F804B070BD10B50A4BA1 +:105980002022EFF3118182F311889A6B002A04DC44 +:105990005C6B44F82200501C9863002081F311884E +:1059A000012AB8BF012010BDA01F002070B50A4D0C +:1059B00004462020EFF3118180F31188A86B461E66 +:1059C000701C0128B8BF70BD686B50F826102046C7 +:1059D0008847013EF4E700BFA01F00207FB56D4659 +:1059E000ADF8020000260C4628468DF80060F3F75B +:1059F000B1FA291D07BF66602660204604F0BFF893 +:105A0000204602F0F3F904B070BDBFB50C46014664 +:105A100000206D468DF80000281D03F080FC28460C +:105A2000F5F722FEBDF802004FF6FE712080401A05 +:105A300018BF012004B0B0BDBFB5044600880DF109 +:105A4000050508226168ADF80500A81C03F0A0FB5D +:105A5000217A0B222B4601704520C821FCF70EFE4F +:105A6000002004B0B0BD10B504460E2004F0DCF8F0 +:105A700078B1A16BD4F83E200160426094F84210E6 +:105A8000017294F84A1001736188418194F84910B9 +:105A9000417310BD80B541F21830C5F200000068B6 +:105AA0004FF20001C0F6FF71084041F20001C0F65C +:105AB000B431884204D1FAF783F91328C8BF80BDF6 +:105AC000FEE7B0B50C460546F9F758FF291A04F56C +:105AD0007A72C4EB9100012898BF01200023B2EB39 +:105AE000910F28BF1846B1F1404F28BF1846B0BDEE +:105AF000B0B50C46054603F021FDD5E901122B692E +:105B0000A24238BF1446121BAA601A19B2FBF1F365 +:105B100003FB1121296103F0BDFF2046B0BDF8B59C +:105B20000C46054603F00AFDEA6895E8C20001321A +:105B3000B2FBF6F303FB16252944216003F0AAFF0C +:105B4000701BF11B814238BF0846F8BDF0B54FF01D +:105B5000000C844504BF0020F0BD1D4616464EB122 +:105B600031F81C7035F8024B013EA74204BF0120FA +:105B7000F0BDF4E70CF1010CEBE770B514460E46EE +:105B8000054603F011FD03F00FFD0B2E0CBFA842DC +:105B900070BD2046002101F03FF9204600211E2261 +:105BA000BDE87040E8F7B4BD70B5044608460D4640 +:105BB00002F024FE30B182683AB101202946012664 +:105BC000904705E00026266003E0406800268068D4 +:105BD0002060304670BD2DE9F0414FF6FE780C464E +:105BE000054608F1010728462146FFF77FF838B13E +:105BF0001C21064603F068F97781A6F80080F2E7D9 +:105C0000BDE8F08140B10246074800210170074815 +:105C10000221007803F06EBF0348012101700348A0 +:105C200002210078F8F7E4BE2C240020958800209B +:105C300080B5AB2807D0A1281CBFB52080BD108837 +:105C40000549088004E003481146006803F097FF07 +:105C5000002080BDDC8700202E7E002010B5044689 +:105C6000062001F001FA60B1014608200870208882 +:105C70004880A078087103480078BDE81040F9F723 +:105C800013BA10BD99880020B0B50848084C0578B3 +:105C900005EB45004100204603F016F94FF6FE7073 +:105CA0001DB124F8060B013DFAE7B0BD9127002095 +:105CB0004C6D002038B10246074841610748012178 +:105CC000007803F017BF0448002141610348012117 +:105CD0000078F8F78DBE00BF2C24002095880020A6 +:105CE000B0B5094D288060B100EB4000800084B25F +:105CF000204603F099FF686028B1214603F0E4F8DC +:105D0000B0BD00206860B0BD342600200949837909 +:105D1000CA7A2BB15AB98078B0FA80F0400970473E +:105D20002AB1C98A4089401A18BF01207047002053 +:105D3000704700BF407B0020B0B50546084800789A +:105D4000012888BFB0BD28460C46F1F7CDFC4FF6C0 +:105D5000FD7029460D222346BDE8B040F5F7B0BFDF +:105D600018260020084800F1180108480278002091 +:105D7000824205D00B78FE2B03D00C310130F7E7BF +:105D80001046C0B2704700BFA08000209788002056 +:105D90001CB56FF0D24401948DF806100421ADF8C3 +:105DA000042001AA01EB8301042389B2FDF76EFFF1 +:105DB000014908701CBD00BFA0230020B0B50748F2 +:105DC000074D04782CB155F80C0B00698047013C55 +:105DD000F8E7044801210170B0BD00BFF3BA02002A +:105DE000A0B902009B27002006480122017A027216 +:105DF00005480160054890F8481080F8482004489C +:105E00000160704738220020EC870020A01F00208E +:105E1000E887002010B50C460849097E02290AD1FE +:105E200001F046FD04B12060C1B20220012908BF83 +:105E30006FF07E0000E00120C0B210BDD01E002037 +:105E400010B50848084900224FF6FE730024007878 +:105E5000844228BF10BD8A718A804B8021F8083B9C +:105E60000134F5E7DABC0200E04C002010B5074829 +:105E7000002403210460064801600220FEF778FC3C +:105E80000720EFF7E3FC0348447010BDA80250421E +:105E90001080024018230020F8B50C46D0E9001607 +:105EA000002701F14C053068013C47F1000182698F +:105EB000D20606D429B10068C1B22846FBF7CEFD50 +:105EC000F1E7F8BDD0E900100A6C5AB191F844101E +:105ED000090707D501684FF480624A648A6B42F46F +:105EE00080628A630068816B41F040018163704782 +:105EF000FEB5074609981C4615460E46FFF7E6FA1A +:105F0000054831463A4683780898CDE9004028464E +:105F1000EDF734FBFEBD00BF2687002010B5044618 +:105F2000062001F0A1F858B1014631200870206820 +:105F3000C1F8020003480078BDE81040F9F7B4B892 +:105F400010BD00BFCC240020F8B5094F06461C4602 +:105F50001546786803F0D1FD447005703846314627 +:105F60003022062301B0BDE8F040F9F755BA00BF72 +:105F70007C2600204FF6FE73984218BF002901D1FD +:105F8000012070479A42FBD0F8B5ADF80C20029181 +:105F9000ADF8040001A8F1F79DF8002004B080BD21 +:105FA000BFB5ADF8020002206D4614468DF8000022 +:105FB000281D03F0B4F92846EBF7D0FCBDF80C100F +:105FC0000138218018BFC82004B0B0BD80B502F0F0 +:105FD000B5FB08480078012807D00028BDE88040BC +:105FE00018BFFEF78DBAFEF771BABDE88040FEF724 +:105FF000A1BA00BF1826002010B50446EBF724FD17 +:106000002046FCF7FBFC2046EFF73AFE04480078F8 +:1060100000B110BD2046BDE8104000F0FDBA00BF41 +:106020001826002080B5E22806D1084A0846114605 +:1060300003F0A5FD002080BD034A9268D2F8282411 +:10604000BDE88040104700BF0C0100209E87002063 +:1060500010B50446103001F06BFA204650F80C1FC2 +:1060600009B101F085FE044821465022406843688A +:10607000BDE81040184700BFA01F002018B1052040 +:106080000121DEF787BB0748417831B1016A21B1B0 +:10609000002141700020F8F7BFBD05200021DEF788 +:1060A00079BB00BFAC22002010B5084900220B7854 +:1060B0000749934205D00C78FF2C04D00E310132F1 +:1060C000F7E70021FF220270084610BDE2BC020083 +:1060D00018870020094908480A780530002142B194 +:1060E00010F8053CFF2B1CBF037819440E30013A11 +:1060F000F5E788B2704700BF18870020E2BC0200B5 +:106100007FB5ADF80C0004206E460C468DF80000FB +:106110003046F9F7F9FE054628B10320311D2072FB +:10612000204603F02CFD284604B070BD10B5084C85 +:10613000A16829B1074909680844EEF70BFA08B1CC +:10614000012010BDE068013038BFE060002010BDC4 +:10615000B82400201C880020084A002800F0010113 +:1061600018BF0120138843EAC01010800448028B36 +:1061700022F0800242EAC11101837047E8860020C4 +:10618000E87F0020B0B5044603F0D8F9054600F0DA +:106190003BF8054844860548C481284603F07AFC4C +:1061A000BDE8B04002F03ABEE87F0020E88600205B +:1061B00010B5084C0121E068C06801700648FE2156 +:1061C0000170F6F759F801F011F9E0680021C06894 +:1061D000017010BD0C0100201425002010B5074CE3 +:1061E0006078FE2809D006480068826B0548006880 +:1061F00094F901109047FE20607010BD1425002016 +:1062000030880020D826002080B508488068D0F863 +:10621000B8000078B0FA80F04009FDF783FF044829 +:10622000017811B101780139017080BD0C010020A5 +:106230001B25002010B5044620B907488068D0F817 +:106240004C05804703F07AF904490A78A2430A70A2 +:10625000BDE8104003F01EBC0C010020AD880020FA +:1062600010B5044620B907488068D0F84C0580472F +:1062700003F064F904490A7822430A70BDE810402B +:1062800003F008BC0C010020AD880020B0B5054625 +:1062900008488068D0F8D84003F050F924680CB161 +:1062A000AC42FBD103F0F6FB002C18BF01242046C2 +:1062B000B0BD00BF0C01002008480178832918BF39 +:1062C000704707490978032902D10020EFF79CB8ED +:1062D000852101701D20ECF7FFB900BFB4880020B4 +:1062E000B788002010B504460848006820B101882E +:1062F000A1420AD00430F8E7082003F095FC20B151 +:10630000024904800A680860426010BD40270020EE +:1063100098B110B5044600F011F82068006A03F047 +:1063200081FC206803F07EFC606908B103F07AFC10 +:106330002046BDE8104003F075BC7047094B0021B2 +:106340001A6852B1824202D0131D1146F8E7054A7D +:106350001368834202D0406848607047406810600C +:10636000704700BF5488002010B50848084A4FF60F +:10637000FE730178002031B132F81C4B9C4218BFEB +:1063800001300139F7E780B210BD00BFD5BC020073 +:10639000DC5B0020BCB5094C246864B1E46954B1ED +:1063A0000004069D01300095A04701460020012908 +:1063B00008BF0A20BCBD0A20BCBD00BF5C2700206E +:1063C00010B5094C24686CB164695CB100040130FB +:1063D000A04701460A200A2908BF0920002908BF52 +:1063E000084610BD002010BD5C270020B0B5044653 +:1063F00002F058FA074D2978884202D36868FBF703 +:106400002BFFE87820710130E870204601F036F863 +:106410002079B0BD4426002010B52020EFF3118470 +:1064200080F3118805480068006B8047044AD2E970 +:10643000102384F3118802F04BFD10BD8C01001075 +:10644000207C002070B504462020EFF3118580F3F6 +:106450001188207D40B1E668FFF7DEFF216A301A1F +:10646000884288BF002000E0002085F3118870BDBD +:106470004A1C08BF05212022EFF3118382F3118803 +:1064800001228A40C0E90812034AD26D02EBC10121 +:10649000416383F311887047A01F002000B170474B +:1064A00010B5074C207C28B1064890F8480008B980 +:1064B000FBF7B0FA00202072BDE81040704700BF23 +:1064C00038220020A01F002080B540F2E010C1F269 +:1064D00000000068012142680120904742F230002C +:1064E000C4F20900006848F2D071C2F200010860ED +:1064F00080BD7178CDF8248006940797CDF80CB054 +:1065000002900D208DF8280000988DF82900307831 +:10651000584408444946CDE904007047013903292D +:1065200084BF4FF0FE307047DFE801F0020B040932 +:10653000007870478178008840EA01407047006821 +:10654000704700887047F8B5466804460027D6F8BB +:10655000C85065B1696968686F61C6F8C81000F015 +:106560009FFFD6F8BC20204629469047EFE7F8BDAC +:1065700081B14A6872B10A78042A0BD18A684AB19B +:1065800002680023916153624B68D361896891620C +:10659000EAF78CBE6FF002007047B0B505680220C4 +:1065A0000C46FEF7E5F864B1D5F8EC000021B1EB3C +:1065B000107F06D10420FEF7DBF84FF0FF30C5F85E +:1065C000EC00B0BDF8B50DF10E0100F010F860B9A7 +:1065D00002208DF80000BDF80E00ADF80C006846F2 +:1065E000FDF7C2FF013818BF012004B080BDBFB560 +:1065F0000C46014602206D468DF80000281D02F071 +:106600008EFE2846F5F730F8BDF80C1001382180D1 +:1066100018BFC82004B0B0BDBFB56D4604462846BB +:10662000FEF7FCFF40F2011010212A4603F0E8F8C3 +:1066300034B128B96A4640F20110102103F0E6F89F +:10664000BFBDCA071CBF012202704A0744BF012216 +:106650004270CA0644BF0122C2708A0644BF0122AA +:106660000271C90544BF0121C171704710F1140FB7 +:10667000A8BF6FF0130045F6A61110F15A0F98BF8E +:106680006FF05900C0EB00200844462180B2B0FBF7 +:10669000F1F0C0B27047B0B50C46054600F0BCFA48 +:1066A00068B100F11B01007C0022824207D211F880 +:1066B0003230AB4208BF01F832400132F5E7B0BDDD +:1066C00070B50446006C04F144052CCDA0FB010616 +:1066D00002FB0161C6184D41300C002240EA054121 +:1066E000FDF720F8C4E9146570BD81B040F2000CDC +:1066F000EFF311808CF3118800200090009810B9FE +:1067000000980130F9E72020EFF3118180F3118820 +:1067100001B07047E0B500200DF1070201218DF8AE +:106720000700032003F06CF830B90DF107030320D4 +:106730000021012202F0AEFB9DF807008CBD000095 +:1067400010B5084B1B6853B1DC79844205D19C8895 +:106750008C4202D19C79944201D00C33F2E7184666 +:1067600010BD00BF54650020084980890A88904206 +:1067700024BF00207047496800EB400011F820005A +:1067800010F00F0018BF0120704700BF3426002012 +:106790000849486809880131013904BF0120704760 +:1067A00000F10C0200780007104604BF002070477B +:1067B000F2E700BF34260020014607480278074868 +:1067C00042B10379042B02D80B0404D00139013AF9 +:1067D0002430F5E700207047E6BC0200B0540020EA +:1067E00080B50648006938B1054802F0A3FF0548A6 +:1067F000BDE8804002F0A4BF80BD00BF381F00206C +:10680000357F0200BD850200B0B50D46044602F09A +:1068100095FED5E9001211B14A606A6800E0626035 +:10682000002A18BF14462160BDE8B04003F032B919 +:106830001CB500200DF10204064905228DF8020066 +:10684000601C02F0A5FC4120802106222346FBF7B4 +:1068500015FF1CBD00BC02001CB50446042001F05D +:10686000B5FF20780DF10303C62105228DF8030042 +:10687000D4F8020001904520FBF700FF00201CBD6A +:10688000B0B50125382185700170FCF7D5FA0446B2 +:1068900028B1A577257002F0B3F90248606220465E +:1068A000B0BD00BFC887002080B508484FF6FE7213 +:1068B000C18A914202D0807B800700D480BDEEF770 +:1068C00031F8BDE88040E4F721BA00BF407B0020EA +:1068D00010B50446064800682060064840686060BD +:1068E000F8F706FB083838BF0020A06010BD00BFD5 +:1068F000E087002044250020B0B50C46054603F093 +:1069000026F84CB1002144F80C1C296819B10D4639 +:1069100055F80C1DFAE72C60BDE8B04003F0F3B861 +:10692000B0B502F00BFE0446064890F8380118B1E5 +:1069300000F0ACFB054600E00125204603F0AAF874 +:106940002846B0BDD81B0020F8B51D4616460446A3 +:1069500002F0F4FD44B104F1200720348ECF33431C +:106960002F432A4331438EC4BDE8F84003F092B868 +:1069700080B5084A002001211070852002F040FFF8 +:1069800000B180BD034B852000210122BDE880407D +:1069900002F080BA9A8800201CB5044600200190BD +:1069A00001A9204602F055FD9DF8040000B11CBD70 +:1069B000BDF806004006FAD5608801F0FBFE1CBD5C +:1069C0001CB5084C8DF807000DF1070064682270B3 +:1069D0001A0A63700423A2700022E270049AF8F786 +:1069E0001BFD1CBD7C26002070B5084E05461446D4 +:1069F000706803F0C4F870682946352209230472D0 +:106A00003046BDE87040F8F707BD00BF7C26002087 +:106A100010B504460748007810B102F001FB20B120 +:106A20002046BDE81040F2F737B92046BDE81040D7 +:106A3000F2F778B91826002010B5084A126842B15A +:106A40000023032B05D01488844204D0063201337E +:106A5000F7E7C82010BD00200B8010BDE026002005 +:106A600080B5002206490A7020B10120087005494E +:106A7000087001E003480270FBF7BAFC012080BDFA +:106A80009D8800209C8800201FB5418801B11FBD52 +:106A9000041D01A92046FEF7A9FA0128F7D102F04A +:106AA00083FDADF80C00029401A8F0F713FB1FBDA5 +:106AB00010B5084B1B6853B11A79824218BFFF28E2 +:106AC000F8D11A4632F8064F8C42F3D100E000228A +:106AD000104610BDEC260020084A92F82E10814284 +:106AE00002D1117801B1704710B9002182F82B1042 +:106AF00002F82E0F5520012102F088BEAC220020A2 +:106B000006480021FF2201700549C96809690A7019 +:106B100004494FF0FF3242600A6070474C26002063 +:106B20000C0100202888002010B5044620B9064832 +:106B30008068D0F84C0580470448017821430170F3 +:106B4000BDE81040F6F758BA0C010020AD880020CF +:106B50000748002101700748C168C968097801B178 +:106B6000704780680021D0F858240020104700BFEB +:106B7000AD8800200C010020B0B50C460546FDF79D +:106B8000EDFA2044686005488068D0F8D810D0F845 +:106B9000EC242846BDE8B040104700BF0C0100209F +:106BA000084A0021032904BF0020704702EB81033B +:106BB0005B88834202D112F821300BB90131F1E731 +:106BC0000120704734870020084A002818BF021DA2 +:106BD000106848B14289120504D529B102681288AB +:106BE0008A4201D0021DF3E7704700BF548800209D +:106BF000084B002818BF031D186848B1437B8B421F +:106C000004D12AB10368DB895B0701D5031DF3E7D3 +:106C1000704700BF5488002010B508490431096846 +:106C200049B10B7C01F11B02002BF8D012F8084B84 +:106C3000013B8442F8D1084610BD00BF4426002025 +:106C400010B500F11B03007C60B113F8084B01384C +:106C50008C42F9D113F8070C104303F8070CA3F189 +:106C60000D0010BD002010BD10B58AB001AC064962 +:106C70002022204603F044F8044809902046E8F713 +:106C80004BF90AB010BD00BF94BD02008C26002055 +:106C90001EF0040F14BFEFF30980684685462DE906 +:106CA000F00F684671467446024A9047684621468E +:106CB000FEE700BFE192020010B5418203461430A6 +:106CC000012100249861C3E90241117819745861C7 +:106CD00002481946BDE8104001F094BBA4260020EC +:106CE000084890F8641001B17047012180F86410E1 +:106CF000C06D00213029F7D042185260425008314F +:106D0000F8E700BFA01F00202DE9F04F2DED108BFC +:106D1000C0F800D0D1F800D0BDEC108BBDE8F08FEA +:106D200000BF00BF00BF00BF00BF00BF00BF00BF6B +:106D300010B504460748002A08BF02462046EFF770 +:106D400045FF20B101462046EEF716FC0024204600 +:106D500010BD00BFC0B80200084890F8381001B15B +:106D60007047012180F83810006A00213029F7D0DF +:106D70004218526042500831F8E700BF3822002024 +:106D800070B514460D46064602F0D8FB6168C5E9A9 +:106D900000416168002918BF0E4635606560BDE896 +:106DA000704002F077BEB0B50C46054602F0C6FB57 +:106DB0000021616029680A1D2160002908BF2A1D81 +:106DC00014602C60BDE8B04002F064BE10B504460B +:106DD000022001F0FBFC032001F0F8FC0020EEF79C +:106DE00033F84520C72101222346FBF747FC00204A +:106DF00010BDB0B5054602F0AAFD2C6844B154F8A8 +:106E00000C1C2960FF2104F8021C002144F80C1C12 +:106E100002F079FE2046B0BDB0B50D460021002439 +:106E2000FAF7BCFA2946F3F71BF828B16FF0011105 +:106E300084718480016000E004242046B0BDB0B5B8 +:106E4000056802200C46FEF7B1FA54B1D5F8EC0003 +:106E50000021B1EB107F04D10420BDE8B040FEF763 +:106E6000A5BAB0BD0068C168490701D58168FAE7D5 +:106E70000221C0F88010C168C90702D1D0F88C1077 +:106E8000F9E70021C0F88010704770B504461C2057 +:106E900015460E4602F0C8FE48B100210673458132 +:106EA000A0F80D10C17301814161C0E9004170BDBE +:106EB00080B502F093FC00B180BD002001210022CA +:106EC000FFF796FE0028F7D001680029F4D0BDE84E +:106ED0008040EBF7ABBA70B50446182000EBC40550 +:106EE000681802F0A1FE064630B13046294601F08E +:106EF000EBFF70193474F060304670BD027A0B7A83 +:106F00009A420AD1032A0AD0022A06D109880088A7 +:106F1000401AB0FA80F0400970470020704700F036 +:106F2000C4BBF8B514460D460646002024210022B5 +:106F30000027FCF78DFC28B131462A46234601F094 +:106F400037FA07463846F8BDF8B54189ADF8041060 +:106F500041684A788DF8062089788DF80C100AB9B6 +:106F6000407A10B101A8ECF779FD8FBD10B5064845 +:106F7000006940B1054C204602F0DCFB2046BDE82C +:106F8000104002F0DDBB10BD381F0020BF8B000099 +:106F9000B0B50C46054602F0D1FA002121606968BF +:106FA0006160002908BF29460C606C60BDE8B040F4 +:106FB00002F070BD012918BF704710B500210446CA +:106FC000FFF72AFF0348002102782046BDE8104061 +:106FD000E7F79EBBCEBC0200074841880088401AF4 +:106FE0004FF4877100F5877090FBF1F25143081A56 +:106FF00000F5877080B27047BC26002010B502F003 +:10700000A6FC04460548426812B14188002090471A +:107010002046BDE8104002F076BD00BF6426002087 +:107020004FF6FF70814208BF704710B50C46E9F774 +:1070300047FB0349E0B2BDE8104002F028BD00BFA5 +:107040000160002080B5074909688A7902B180BDD6 +:10705000C2680968407800F0A5FFBDE8804000F0F4 +:1070600007BC00BFCC26002010B568B104460C3028 +:10707000EFF7C0FB0146002029B1FF22086001F1B3 +:107080000C000C818A7210BD002010BD10B506489E +:107090003C21012200230068C4680448A04700285E +:1070A00018BF012010BD00BFA401001000A00C40BB +:1070B0001CB5064980B24FF47F42082309684C682A +:1070C000009003483021A0471CBD00BFA401001060 +:1070D00000A00C401CB5064980B24FF4F802122300 +:1070E00009684C68009003480421A0471CBD00BFFC +:1070F000A401001000A00C401CB5064980B24FF45A +:107100000032112309684C68009003480421A0470D +:107110001CBD00BFA401001000A00C401CB5064916 +:1071200080B24FF440620A2309684C68009003481B +:107130002021A0471CBD00BFA401001000A00C40EE +:1071400050B14AB110B5044608300EC0214604487B +:10715000FFF71EFF002010BD6FF00200704700BF58 +:10716000D81B002005480649C069884208BFF6F7C9 +:107170003DBA04480421283002F06CBDD01E002026 +:107180002D3700007020002080B54FF0FF3001F057 +:10719000AFFF800758BF80BD03484FF4006128301F +:1071A000BDE8804002F056BD702000200648007EF9 +:1071B000022804D10548816C09B9C06C08B10020CF +:1071C00070470120704700BFD01E002030210020F2 +:1071D00070B5144600220E46054600F053FFFF2806 +:1071E00007D02B2E18BF40F22B2646EA842145F803 +:1071F000201070BD10B586B08DF80410024601ACA9 +:107200001146601C102201F0C3FF3B2011212246D1 +:1072100002F0FCFA06B010BDF8B500210391CDE9EB +:10722000011101218DF80410034901F11C0201A98B +:1072300000F06CF904B080BDA01F0020B0B5074D70 +:10724000044604212878FBF7BBFF00B1B0BD2878C5 +:1072500004212246BDE8B04002F04CBC99880020D1 +:1072600080B502F079FB42F21071084042180448E0 +:107270004FF480410078BDE8804002F03BBC00BF85 +:107280009988002080B50648064902F078FC00F095 +:10729000CFFAFDF7C3FEBDE8804000F0D9BA00BFC9 +:1072A000968700208E87002010B503460648446864 +:1072B000A2700A0A21701946032362700422BDE8F5 +:1072C0001040F8F7A9B800BF7C2600201CB50C467A +:1072D000002121600DF10601FFF789F908B1C820EE +:1072E0001CBDBDF806002146BDE81C40FEF77EB976 +:1072F00010B50446007801F081FA08B1022010BDF3 +:10730000204600210022FEF7A1F9B0FA80F04009E2 +:10731000000110BDB0B5074B00221B6843B11C79BA +:107320008442FAD1DC88D5B2013221F81540F4E765 +:10733000D0B2B0BDEC260020E0B58DF805000648BF +:107340000121002203238DF80410007801A9009187 +:107350000A21FBF790FD8CBD9F88002058B1074B98 +:1073600042791B789A4206D2531C437100EB4200CB +:10737000C180012070470020704700BFD3BC0200CD +:1073800001684268054BC3F80720C3F80310044A9C +:1073900001684068C2E90A10704700BFE886002013 +:1073A000E87F002010B504460B38102804D30448A9 +:1073B0008068D0F84C05804702488473012010BDD6 +:1073C0000C010020E87F002010B504460B3810287F +:1073D00004D304488068D0F84C0580470248847381 +:1073E00010BD00BF0C010020E87F00200648017896 +:1073F00041F004010170054800218068D0F8940034 +:107400000078F6F725BE00BF8C8800200C01002014 +:1074100080B50648006838B1F2F7DCFA0448006825 +:10742000BDE88040F3F7C8BA80BD00BF38880020AF +:107430003C88002070B5074E044602F07FF80546F0 +:1074400020463460F2F7C6FA2846BDE8704002F0E4 +:1074500021BB00BF388800200749096849B10A6884 +:107460001388834203D1126A5278D20701D00431C3 +:10747000F3E70846704700BF54880020074A516868 +:1074800019B10B682BB11946FAE700210160111DF3 +:1074900001E0002202600860704700BF442600201F +:1074A00080B507490138884205D80620FDF760F904 +:1074B0000420FDF75DF90220BDE88040FDF758B9D2 +:1074C000FEFFFF0F10B5064C28B1064801210068E9 +:1074D000426820469047606820F03000606010BD30 +:1074E00000400340D80100101CB504460498002B4E +:1074F0000090054808BF03462046F4F765FF0028C2 +:1075000018BF002420461CBD60BA020070B51346A7 +:107510000C46054600201C2100220026FCF798F9A5 +:1075200020B12946224600F07BFF0646304670BD5A +:1075300000F11401816141612021EFF3118281F397 +:10754000118801684368196041680068416082F3EE +:107550001188704710B5074C207C08B1FAF75AFA29 +:107560000020207240F2000CEFF311808CF31188A0 +:1075700010BD00BF3822002080B502F02EFA50B1B5 +:1075800001460079421E0120012A03D88A6981F848 +:107590002000CA6180BD002080BDB0B505680446EA +:1075A00095F85000022808D1A86802F06DFA20462C +:1075B000FBF723FC002085F85000B0BDB0B50546B0 +:1075C00001F0BCFF2C6834B1216802C5002918BF46 +:1075D0000D1D0021296002F05DFA2046B0BD70B596 +:1075E0000C46064601F0AAFF0025246824B1216953 +:1075F000B14208BF2546F8E702F04CFA284670BDB4 +:10760000F8B50C46054601F099FF95E8C2002D69D2 +:107610002944216002F03EFA701B874238BF384689 +:10762000F8BDBCB5046825790DB9A4792CB14FF02B +:10763000FF340094E1F7DAF9BCBD02B0BDE8B04018 +:10764000F9F7F4BE10B50C4601F0D8F838B100F1E6 +:107650000C0120460222BDE8104001F099BD4FF414 +:107660009970208010BD10B54A1E012101FA02F365 +:1076700000221C0404BF90B210BD034218BF0A438D +:10768000C3F34E034900F4E710B562B10C780378F8 +:10769000A34206D1013A00F1010001F10101F5D147 +:1076A0001C46181B10BD002010BD10B50822130683 +:1076B00007D00B7804789C4203D1013A01300131A4 +:1076C000F5E7D0B2B0FA80F0400910BD10B503461E +:1076D0001B68834204D09C6864699442F8DA00E035 +:1076E000034658680B6048600160596010BD000097 +:1076F00058B1064B1A6822B11346D268002AFBD152 +:107700000C33817100211860C160704754650020FE +:10771000064A1168814205D031B10A46C9688142E2 +:10772000FAD10C32C168116002F07CBA54650020B5 +:1077300080B506484FF480710078FBF741FD00B139 +:1077400080BDBDE88040FBF795BD00BF9988002053 +:1077500080B50548FF22007800EBC0008100034897 +:1077600001F0ACFB80BD00BFE6BC0200B0540020BD +:1077700080B50548FF22007800EBC0008100034877 +:1077800001F09CFB80BD00BFE6BC0200B0540020AD +:10779000102809D31038012200F01F01400902FA15 +:1077A00001F1024A42F82010704700BF80E200E079 +:1077B000E0B50178B0F801000DF1050303228DF862 +:1077C0000510ADF806004F208021FAF757FF8CBD59 +:1077D00080B505480021017004480170FAF76EFF7A +:1077E000BDE88040FFF724B8A1880020A2880020CF +:1077F000B0B50546C0780C460870281D02F010FA96 +:107800006080A81D02F00CFAA08005F10800B0BD50 +:10781000B0B5064D2C78601C2870204601F02AF87F +:10782000002CF7D00028F5D12046B0BD8F8800206D +:1078300003480449044A054BC0E90132C16070475E +:10784000F4240020099C02003DFB0000B5720100F9 +:107850000348064B0349044AC0E90121C36070474D +:10786000F42400203DFB0000B5720100099C0200D9 +:1078700010B5064C206818B102F0D4F90020206041 +:1078800000F05EFDBDE8104001F000B8CC260020FD +:1078900080B505494870054880210078F7F7A8F8B9 +:1078A000F8F70CFF002080BDF42400209888002009 +:1078B00006490A68002AFCD10022CA610860C8692A +:1078C0000028FCD00020C8614868704700100440C0 +:1078D00070B50024A34208D050F824506E1C04D088 +:1078E00015408D4202D00134F4E7FF24E0B270BDB0 +:1078F000064841880088401A4FF4877100F5877068 +:1079000090FBF1F202FB110080B27047BC26002010 +:107910008068D0E90020C1E9002004484FF470528B +:10792000006802EA80208860704700BF302403406E +:107930000648B0F870100131A0F8701088B2884283 +:1079400008BF70470120F3F767BD00BF407B0020F0 +:1079500003480449044A054BC0E90132C16070473D +:1079600074230020D1A60100317902004570020085 +:10797000054806494FF0FF32007818B141F8042B52 +:107980000138FAE7704700BFD6BC020080860020AD +:1079900005484FF4825100680028044848BF4FF45E +:1079A00041510160704700BFAC4F005028A10C400E +:1079B00005484FF4805100680028044848BF4FF440 +:1079C00040510160704700BFAC4F0050A8A00C4070 +:1079D00080B505480068FAF7E9FC04480068BDE88E +:1079E0008040FBF717BF00BFE8870020EC8700202E +:1079F000B0B5044601F0A2FD054604482146FEF755 +:107A000003FF2846BDE8B04002F044B8D81B002070 +:107A1000064A0021B1F5307F06D0501890F9333076 +:107A2000002B02D55831F5E700207047586500203B +:107A3000E0B5064901AAFCF7CFFE9DF806108128A3 +:107A400018BF6FF07F0148B28CBD00BF0100030476 +:107A50000A460146044843682BB18068084202D0B8 +:107A60000248406818477047ACBB0200D01E002097 +:107A700005480068C00704BF00207047034800683D +:107A8000C0B2C009704700BF402108400000044058 +:107A9000BCB5044680686A46ECF778F90546832849 +:107AA00004D1694620460022FCF796FE2846BCBD5C +:107AB00010B504463A2000211122234601F0EAF9CC +:107AC00000B110BD01484068606110BD0425002070 +:107AD0001FB5044600200390CDE9010001208DF878 +:107AE000040001AA2046FFF7E7F8204604B010BDC5 +:107AF00005490A78824208BF704708700348102180 +:107B00000078F6F7A5BA00BFC426002099880020A7 +:107B100080B506484FF480710078FBF751FB00B147 +:107B200080BDBDE88040FBF7A5BB00BF9988002061 +:107B3000F8B54188ADF80410411D02910179407FEC +:107B40008DF806008DF80C1001A8F1F7BDF98FBD76 +:107B500070B50C460646EFF7DBFF05461E2800D041 +:107B600025B9304621460122FDF7DEF9284670BDD1 +:107B700010B5064890F82E0028B1002000210024FE +:107B8000E6F75AFE00B10124204610BDAC220020C9 +:107B9000FEB50290002000916946019003484068BC +:107BA00001F0CCFF013806B080BD00BF0C240020DE +:107BB000064A12683AB11379834202D193688B4224 +:107BC00001D01032F5E71046704700BF6C26002048 +:107BD000E0B5064904486A46096800684B6C022112 +:107BE00098479DF800008CBDD826002030880020E2 +:107BF00005490968401A054909788900B0FBF1F286 +:107C000002FB1100704700BF2C880020B0880020C4 +:107C100000F120014FF0FF32C9B2192938BF00F13D +:107C200045024038C1B2252938BF0246D0B270475C +:107C300080B50649044809680068096C8847BDE8B2 +:107C40008040FEF713BD00BFD826002030880020FA +:107C500005480178832918BF704700210170034847 +:107C60000170F8F709BB00BFAC880020AF88002086 +:107C700080B501F063FC0449044A09681160BDE85D +:107C8000804001F007BF00BF388800203C880020FA +:107C90000C2884BF01207047062884BF032070474A +:107CA000022884BF05207047002818BF07207047AE +:107CB00041F01001F1290AD112F0300F07D080B540 +:107CC00001F04AFE00F007000230BDE88040704736 +:107CD00080B5064A12682AB1926A1AB100040130CE +:107CE000904700E0002080B280BD00BF5C270020EC +:107CF000F8B501A80021FDF77BF8039A6846BE217C +:107D00008242009228BF8FBD1170009A0132F7E7BE +:107D100001460120886000200861C86001F114005C +:107D200088614861014800F06DBB00BF94260020C7 +:107D300010B50446006800F02DFB04482168242299 +:107D40004068436898470020206010BDA01F0020B5 +:107D500010B504460068FFF7EBFB044821681C22BD +:107D60004068436898470020206010BDA01F002095 +:107D700010B50446006800F00BF80448216858224A +:107D80004068436898470020206010BDA01F002075 +:107D90002021EFF3118281F311888168C368196093 +:107DA000C16883685960002182F31188EDF7E4BB54 +:107DB00041680978102908BFFFF7C6B8092904D01F +:107DC000052918BF7047E9F7FDB800F0BABB884233 +:107DD00004BF012070470246002032B129B180B5AE +:107DE0001046FFF762FCBDE88040704750B10022AA +:107DF0000021072A07D8835C0132002BF9D001212A +:107E00000922F6E70021C8B27047E0B54178408802 +:107E10000DF1050303228DF80510ADF8060044208E +:107E20008021FAF72BFC8CBD80B540F2A813C1F27B +:107E300000031B689B69984740F28441C4F26021AB +:107E400000220A6080BD80B540F2A811C1F2000195 +:107E500009684969884740F28441C4F260210022E0 +:107E60000A6080BD80B550B110F8021CFF291CBF0C +:107E7000042080BD0C38F9F725FA002080BD0520CC +:107E800080BD70B50E46014618461C46154601F0E9 +:107E900076FE04F10800314601F02FFE057070BD3A +:107EA0001CB504686479022C02D1E7F701FB1CBD04 +:107EB000049C049402B0BDE81040E3F773BCF8B52D +:107EC0000F20B421012200238DF80C004FF6FC7026 +:107ED000ADF8040001A8F7F71BFA8FBD10B5EFF35A +:107EE0001484002C1CBF002181F314888047002CCF +:107EF0001CBF022181F3148810BDB0B50B460020D1 +:107F00001C2100220024FBF7A3FC18B10546FFF753 +:107F1000FFFE2C462046B0BD10B5054CD4F800C07D +:107F2000BCF1000F04BFB62010BDBDE81040604793 +:107F30003024002010B5054C2069F2F751FAA168F1 +:107F400001B9E060481CA06010BD00BF381F0020D0 +:107F5000FF2807D0044A526852F820308B4218BFDD +:107F600042F82010704700BF14BB0200FF2808D061 +:107F7000044A52F82030DBB28B421CBF42EA800038 +:107F80000170704700100840102801D3044A02E035 +:107F9000042801D3014A8154704700BF14ED00E06A +:107FA000F0E300E0F8B5054B1B682BB1CDE90212F8 +:107FB0008DF8040001A898478FBD00BFDC24002085 +:107FC00010B514460A46014623F001003A2811BFB5 +:107FD0000A201846234600F05DFF10BD010700F09F +:107FE00002004FF0030158BF012141EA400001495E +:107FF000087070479088002050B180B5073080B27B +:10800000F0F7D8F9FF28BDE8804004BF0120704791 +:1080100000207047E0B58DF807200DF1070201231D +:10802000FBF734FE014908708CBD00BFA02300207F +:1080300010B54AB111F8013B10F8014B013A9C42CE +:108040001CBF002010BDF4E7012010BD0022012854 +:108050004FF0000004BF40F2EE204FF47A72022984 +:1080600008BF0246104670470548B0F85410B0F8F3 +:108070005600814218BF70470820FCF793BB00BF31 +:1080800030210020B0B5144640F2FF32502305469F +:10809000FFF71EFC1CB155F82010890A2160B0BD05 +:1080A00010B5044601F04AFA03490A7822430A70DF +:1080B000BDE8104001F0EEBCD01E0020B0B5054870 +:1080C0004468C56901F018FB014620462A46BDE810 +:1080D000B0401047D01E002010B5044600F04AFA08 +:1080E00030B9204600F03CFD002808BF6FF00104C5 +:1080F000A0B210BD10B5054CD4F808C0BCF1000FFB +:1081000004BF012010BDBDE81040604704250020D9 +:1081100001284FF00100044A08BF0320012110701C +:10812000852001F073BB00BF9A88002010B5054C74 +:1081300004212078F6F75CFC20780421BDE810408B +:10814000F5F7BEB999880020F8B5ADF804000448E9 +:1081500002918DF80C20416809B101A888478FBDB4 +:108160003C830020B0B585690C4635F8020B24F835 +:10817000020B2946204601F002FD287A2072B0BD8C +:10818000E0B5ADF8000004488DF8021001920168D6 +:1081900009B1684688478CBD3C8300201FB5ADF807 +:1081A000020000206C468DF80000201D01F0B7F899 +:1081B0002046E9F7D3FB1FBD10B5034604484468C9 +:1081C000218019460223BDE81040F7F725B900BF0A +:1081D0007C26002004480078052818BF7047034813 +:1081E00080210078F5F734BFC4260020998800204C +:1081F00004480178012903D100210170024801706F +:10820000FAF7F6B89D8800209C88002010B50C462F +:1082100000F0F4FA30B10C302146022200F0B8FF31 +:10822000002010BD022010BD10B50446087A0328B6 +:10823000207219BF08882080204601F0A0FC002091 +:10824000608110BD054A12683AB153681B7809B1C4 +:10825000002BF8D000F8013BF5E77047208800209C +:10826000044981F82F0001210028034818BF02218A +:1082700001707047AC220020AC27002050B1821D55 +:10828000407938B132F8023B01388B4204BF0120FB +:108290007047F6E70020704710B5054BC0B22AB111 +:1082A00011F8014B013A6040185CF7E710BD00BFC0 +:1082B000A0AB020004490968401A04490978890002 +:1082C000B0FBF1F0704700BF2C880020B088002080 +:1082D000054800224FF0807341790131417100203F +:1082E0000021F6F705B800BF14250020044800213E +:1082F00001700448007800B17047F7F7BDBF00BFB8 +:10830000AF880020AC88002080B505488068D0F890 +:10831000DC04804701F012F9BDE8804001F0BABBEF +:108320000C01002058B110B51C21044600F0CCFD12 +:108330006FF00100411C20806181BDE81040704752 +:10834000B0B5054C206820B1856901F06BFC28466A +:10835000F9E700202060B0BDE4870020054A38B16D +:1083600032F8023B01388B4204BF01207047F6E728 +:1083700000207047F0850020044800210170044867 +:10838000007800B17047F7F777BF00BFAC880020D6 +:10839000AF8800202021EFF3118281F3118801685A +:1083A0004368196041680068416082F31188704732 +:1083B00010B504460448002B08BF03462046FCF7CE +:1083C0004BFD204610BD00BFDCBB0200B0B5054D23 +:1083D0000024022C08BFB0BD55F8240080470134AA +:1083E000F7E700BF7CBC020010B50B460020082157 +:1083F00000220024FBF72CFA10B104464060006014 +:10840000204610BD2022EFF3118382F3118808600B +:1084100042684A6042681160416083F31188704786 +:1084200010B504460448002A08BF02462046FEF75D +:1084300043FC204610BD00BFE8BB020010B5044657 +:108440000448002A08BF02462046F8F7ABFD204644 +:1084500010BD00BFCCBA02002021EFF3118281F3DE +:1084600011888168C3681960C1688068416082F3BF +:10847000118870471CB50C4601A9FEF727FF10B103 +:108480004FF6FF7101E00199498821801CBD016808 +:1084900091F8512022B1012A18BF7047FAF7ADBCFC +:1084A00091F85310FBF7F6BAB0B50C46054601F04B +:1084B0004EFA296844F80C1C2C60BDE8B04001F06D +:1084C00022BB70B514460D460646F7F7F4FC30465D +:1084D00029462246BDE87040EAF71AB8F8B5ADF86B +:1084E0000C0004208DF800006846F7F70DFDBDF87C +:1084F000020004B080BD41B2002211F1760FB8BF76 +:10850000012251000138052838BF01210846704773 +:1085100010B52021EFF3118481F311888068214682 +:10852000FCF7B4FC84F3118810BD0B46416911B10E +:108530004878800700D070478A888878097BFAF7E6 +:1085400089BFE0B541894068ADF8041040788DF8E6 +:10855000060001A8FDF782FB8CBD000010B5044C9D +:10856000606820B101F05EFB00206060208010BDDB +:108570003426002080B501F030FA28B100790138A6 +:1085800004283CBF012080BD002080BD80B501F0E3 +:1085900024FA28B10079013802283CBF012080BDAF +:1085A000002080BD0446FEF7E1FC0348032101756D +:1085B000204601F056FA00BF381F002004488168A9 +:1085C0000139816018BF7047D0E90310F5F766BA2A +:1085D000381F0020FF2806D0034911F8202002F0A0 +:1085E000FB0201F8202070470210084010B5044C2F +:1085F000207818B1FBF77AFD0020207010BD00BF75 +:10860000AB88002080B580780530C0B201F00CFB4B +:1086100018B1BDE8804001F005BB80BD130608BF5E +:10862000704711F8023B013A037011F8013C4370A6 +:108630000230F3E7014600200A2906D8012202FA97 +:1086400001F111F4836F18BF0120704780B5044811 +:10865000407808B900F03CFDBDE88040F8F72EB83E +:10866000F424002003480121017103480068F5F754 +:108670002FBF00BF342500204C8800200348012173 +:10868000817003480068F5F723BF00BF3425002040 +:108690004C88002080B50448006801F071F900287A +:1086A00018BF6FF0020080BDDC25002080B50448B3 +:1086B000006801F065F9002818BF6FF0020080BD66 +:1086C0000C240020022807D0032804D180B5E7F746 +:1086D000DDFC002080BDFEE7F4F724BF044890F8DD +:1086E000411119B1D0F86C0100B10047704700BFCB +:1086F000D81B002000214FF0FF320174C0E9022195 +:1087000001710160C0E90511818370471CB5C2F396 +:10871000800302F001040093C2F340032246E6F70F +:10872000B3F91CBD10B5012998BF0121044601F021 +:1087300053FA2046BDE8104001F050BA0248034900 +:10874000034AC0E90221704704250020419202003B +:1087500065E200000249034A0A6003490870704755 +:10876000582700203D290200C0260020044900208F +:108770000022092A08BF704741F822000132F8E7B9 +:108780003C83002002460448012100780AB101F030 +:10879000B1B9F5F75DBC00BF9988002080B5FDF741 +:1087A000B9FF80075CBF002080BD0020FEF794F970 +:1087B000012080BD0449B1F86E20824208BF704795 +:1087C000A1F86E00FFF7A4B9407B0020082884BF01 +:1087D00002207047024A0146002042F821007047FB +:1087E0003C830020E0B58DF807000348C16911B152 +:1087F0000DF1070088478CBD3C83002001460448EA +:10880000006818B1426812788A42F9D1704700BFF7 +:10881000208800200349044A086010608420042155 +:1088200000F0F4BF708800206C270020044989689C +:10883000D1F8E420D1F8EC1051F820001060704716 +:108840000C0100200021082904BF01207047425C70 +:108850000131FF2A1CBF00207047F4E710B5002249 +:1088600000238A4224BFD8B210BD10F8014B013258 +:108870006340F6E70449096821B10A7B824201D0CE +:108880000431F8E7084670475488002010B5044CBE +:10889000206820B14168216001F0C4F9F8E710BDFB +:1088A000402700200448011D0020096809B101305B +:1088B000FBE7C0B2704700BF442600200448806830 +:1088C000D0F8B800007808B1F3F79EBCFFF754BDAC +:1088D0000C010020B0B50C46054600F0A9FF024887 +:1088E00044650565B0BD00BF0820002080B5044B7D +:1088F0001C33FFF7A3FD4169002908BF084680BD6E +:10890000A01F00202022EFF3118382F31188026B55 +:108910001143016383F31188F7F7FEBC00BF00BF6A +:1089200000BF00BF0498804700980199029ADDF8C3 +:108930000CE0104710B52021EFF3118481F311886A +:108940002146FCF7A3FA84F3118810BD83B0C0B5AB +:1089500003AF0EC703A9009100F004F8BDE88840FA +:1089600003B07047E0B50246002001914FF0FF319F +:10897000009001AB0020DDF737F98CBD044800788A +:10898000042803D8022801D0DEF776BA704700BF6A +:10899000B7880020B0B50C46054600F0CFFDA96CA5 +:1089A000A143A964BDE8B04001F074B8B0B50C466D +:1089B000054600F0C3FDA96C2143A964BDE8B040A1 +:1089C00001F068B880B5E6F78DFEE7F779FEF7F7B6 +:1089D000EBFABDE88040E1F7CAB82020EFF311813F +:1089E00080F31188B1FA81F081F311884009704752 +:1089F00010B52023EFF3118483F31188C0E900211F +:108A000084F3118810BD10B5044600F097FD0021D5 +:108A1000C4E90011BDE8104001F03CB8E0B58DF8A4 +:108A200007000DF10703412081210122F9F726FEFD +:108A30008CBDE0B50022009068468DF80410ADF8BA +:108A40000520F6F7ADFA8CBD28B132B110F8013B24 +:108A5000013A8B42F9D000207047012070471CB5C5 +:108A60000C6891F90430CDE9001201212246E5F7A6 +:108A700003F91CBDD0E9002092F83010043918BF6A +:108A8000012152690078F6F73DB81CB501A9FEF73F +:108A90001DFC044610B90198E7F762F920461CBD99 +:108AA0000A7A02720A7A022A02D109880180704782 +:108AB000082200F06DBB80B5F7F766FB013004BFFC +:108AC000E82080BDF6F72CFD002080BD0A4609682D +:108AD00029B18142FAD1006810600120704700205E +:108AE000704710B52021EFF3118481F31188EFF75F +:108AF000F3FA84F3118810BD10B52021EFF311842F +:108B000081F31188FAF768FE84F3118810BD81B0F3 +:108B1000C0B5039303AB009300F0EAFBBDE88840C7 +:108B200001B0704780B5F5F743F9024801210170A3 +:108B300080BD00BF9827002080B5F5F739F90248BD +:108B40000121017080BD00BF9927002010B5C478B5 +:108B5000C2880179037A2046BDE81040FAF77ABC52 +:108B600080B500F03AFF08B1007908B1002080BD5F +:108B7000012080BD0349096821FA00F000F00100DE +:108B8000704700BFC0200240FF2803D0024A92680D +:108B900042F82010704700BF14BB02008178437870 +:108BA000024840780A46FAF755BC00BFC0260020AC +:108BB00003488068D0F80001807B2238C0B270473B +:108BC0000C01002003480078012898BF01F094B8F8 +:108BD0000020704718260020034800218068D0F844 +:108BE000B8000170704700BF0C01002003480178F5 +:108BF000FE20002908BFFF20704700BF702700201B +:108C000010B5034CE2202146FDF70CFA204610BDBA +:108C1000C8870020034991F82610082908BFEEF7FD +:108C200063BD7047407B0020D5F8CC10D8F8140005 +:108C300049680968D1F80425024270472275026C20 +:108C4000D0F8D4301268D28A52064FF04E027047E4 +:108C5000034801680029FCD000210160704700BF73 +:108C60001C100440E0B5C2F3800302F0010200933F +:108C70000123E5F709FF8CBD4168034A0978D170EB +:108C800000785070704700BFC026002003490122C1 +:108C900091F8480081F84820704700BFA01F0020CD +:108CA00010B5046804F1340000F0CEFF002084F811 +:108CB000310010BD042805D180B51046E7F782FDCC +:108CC000BDE880400020704780B50F20F8F722FAF9 +:108CD00000200221BDE88040FAF7F6BD08288FBFCA +:108CE0000220024A42F82010002070473C830020F6 +:108CF0001CB50C4601A9FEF7E9FA00B11CBD0199AB +:108D00000C711CBDE0B501904FF40070ADF800008F +:108D10006846F2F76FFC8CBD0179042904D0022962 +:108D200018BF7047F2F788BAF1F78CBD80B50348D9 +:108D30008068D0F83403804780BD00BF0C0100205C +:108D400010B5034C207000F011FC607010BD00BF26 +:108D5000722700200349002912BF01C90020002109 +:108D6000ECF7AEBBB8BD020010B510F8014BFBF735 +:108D70005FFB012C08BF0838C0B210BD03490020BA +:108D8000096809B10130FBE7C0B2704720880020B4 +:108D900003490020096809B10130FBE7C0B2704700 +:108DA000EC26002020220028024818BF24228150EF +:108DB000704700BFAC22002080B50020FDF78CFE7C +:108DC000FF200321BDE88040FAF77EBD80B503494E +:108DD000FF22098800F072F8012080BDC2B40200B1 +:108DE00003490979002918BF06304001704700BFC8 +:108DF000B82400200249088602498881704700BFD4 +:108E0000E87F0020E886002003488068D0F82C1313 +:108E10004FF48050084700BF0C0100200348007841 +:108E200008B1F4F7E9B80020704700BFAD88002012 +:108E300003488068D0F82C134FF40070084700BF37 +:108E40000C0100200248034A07210023FEF778B9ED +:108E500008860020D19C020003488068D0F82C13BB +:108E60004FF40060084700BF0C010020E0B500216E +:108E7000CDE900116946FEF718FC80F001008CBDB9 +:108E8000034A516811B1527802B10847704700BFD8 +:108E9000E82500201CB514460A4601460093002030 +:108EA0002346FDF777FA1CBD10B5034CE06BF6F7CF +:108EB000E7FB0020E06210BD381F00200B46114682 +:108EC0001A4600F0F7BA00BF0A46002100F0F2BAD5 +:108ED00040B584B002AE0096EDF78AF8029A039B83 +:108EE00004B040BDE0B50DF10702012300F018F910 +:108EF0009DF807008CBD4FF6FF70814208BF704798 +:108F0000C8B2002100F0A4B84FF6FF70814208BF3C +:108F10007047C8B2012100F09BB880684FF0FF3263 +:108F20000A60D0E90120C1E90120704710B504684A +:108F3000D4F824C0029C0294BDE81040604780B57C +:108F40008022F8F769FF08B1C06880BD002080BDAD +:108F5000B0B50024551E80E836008361C0E90444A2 +:108F6000B0BD80B500F094F800F07AF8BDE880401C +:108F700000F096B828B131F8023B013822F8023BE4 +:108F8000F8E70846704780B510EB520041F1000148 +:108F90000023FFF79DFF80BD017809B100207047D5 +:108FA00040680028FAD0FCF75EBD0A7A032A0272F4 +:108FB00008BF00F0E4BD09880180704710B50023A8 +:108FC0009A4208BF10BDCC5CC4540133F8E70000DE +:108FD000B0B5024991E83C003CC0B0BDF4BA020013 +:108FE000024A02EBC000F6F7CDBB00BF1CBC02007A +:108FF000B0B5024991E83C003CC0B0BD04BB0200E2 +:10900000024A02EBC000F2F73FBF00BF24BC0200DF +:10901000014602480078F6F747B800BF3C2600201A +:109020000248FF2108220068FFF70EBDDC87002000 +:109030000249D1E90012C0E900127047381F002030 +:109040000249896851F82000704700BF14BB020034 +:10905000FF281CBF014A8154704700BF0020024016 +:1090600001480249816070470C010020FCA2020007 +:109070000121002201724FF0FF31C0E90021704749 +:10908000102802D3014910380860704700EF00E053 +:1090900001480249016070470C010020C4B402007D +:1090A00001480249C16070470C01002098AD0200E0 +:1090B000024908701021F4F7CBBF00BF968800204A +:1090C0000248012180F82610704700BF407B002035 +:1090D0000248007800B17047FFF78AB818260020D0 +:1090E000024880F82F20E5F73BBC00BF407B002002 +:1090F00002490A681040C2430A60704710100440D9 +:1091000002490A681040C2430A60704708100440D0 +:1091100000F02CFA01490860DDF750FAC82600205B +:1091200001EB40310148C06800F00EB9A0230020D7 +:10913000B9F82410ADF8000058468DF80880704743 +:10914000B068D0F81814D0F8D40090F8530008474D +:10915000B5F8541001396FF31F31A5F8541070475A +:1091600094F8220085F8AA00606AC5F8AC00704740 +:109170000746287C05F1110103288DF8200070476F +:1091800000246A1D3346CDE90071CDE90204704721 +:109190002AB111F8013B013A00F8013BF8E77047AA +:1091A000F0B5024991E8FC00FCC0F0BDB8B902007E +:1091B00002484FF000410160704700BF00A10C4021 +:1091C0000248016841F00301016070472422084011 +:1091D00002480068C0F30720704700BF30A00C4071 +:1091E00002480068C0F38440704700BF04A00C40F0 +:1091F00002480068C0F38120704700BF20A00C40E7 +:10920000024840210160FDF75FB900BFA8A00C40F3 +:109210000249084490F84A01704700BFD81B00205B +:1092200010B50023541E80E81E00C0E9043310BDB1 +:109230000249C96801B10847002070470425002091 +:1092400000F00300022101FA00F000F01C0070475A +:1092500000214FF0FF32C0E90011C0E90221704740 +:1092600000F0AEF9014801210160FEE77C052043D2 +:1092700070B5024991E87C007CC070BDB8BA0200AC +:10928000024A02EBC000EFF7C1BC00BF34BC0200D1 +:1092900000680121806900F0080081EAD000704771 +:1092A00080B50079EDF726FEBDE88040F9F7E2BF12 +:1092B00080B5FFF7A3FA08B1406880BD002080BDEB +:1092C0000249002818BF012008707047A827002015 +:1092D000024901220A60D0E906010847042009403A +:1092E0000249012281F83020F6F7EEBF381F002036 +:1092F000E0B501930023009301ABDCF775FC8CBD56 +:1093000080B50A46D0F803101046FFF7DDFD80BD9A +:109310000068002180F822100A20ECF797BA09B102 +:1093200000F02DBC00214160016070474FF4C8017E +:109330004FF47A72C0E900217047042303EB8101E6 +:10934000042389B2FFF7ECBE10B50468D4F81CC042 +:10935000BDE810406047234603958DF80450029500 +:10936000FBF7D4BE8DF85400B8F84700ADF85500AF +:109370007047BBF80C00049901224346E3F7AABBEF +:1093800005F1080004F10A010822FFF701BF41EAD4 +:109390009011800002308DF82D10704740F203715B +:1093A0004FF6FF720523FEF793BA98F8720001306A +:1093B000C0B2CDE90005704701788DF839104178C9 +:1093C0008DF83A107047A8702079E870607900280D +:1093D000287170470BEB4B0001EB8000A0F81CA03C +:1093E0007047DAF80860DAF81000BAF93010704700 +:1093F0008DF8630002208DF86000E81C2047ADF86E +:1094000038006E7B05F10E0000F00ABC00214160BF +:1094100081600160FF2101717047D0E90110401A9D +:10942000B0FA80F040097047062902D34A1C18BFE1 +:109430007047FDF71DB81CB54FF0FF340094FEF7E0 +:109440002FFD1CBD80B5F0F741FABDE88040FBF769 +:109450002BBA806902780A70B0F801004880704722 +:1094600080B5EEF7A5FDBDE88040FCF7C7B980B533 +:10947000FAF704FEBDE8804000F02EBC80B5FFF78F +:10948000EFFFBDE8804000F015BC0021425C0131D7 +:10949000002AFBD1481E70470021425C0131002A9E +:1094A000FBD1481E704780B5FFF7AAFEBDE880409B +:1094B000F7F752BD00239A4208BF7047C1540133E9 +:1094C000F9E70B46D0F80320C11D184600F018BC80 +:1094D0000068002101700A20ECF7B8B90021C0E94A +:1094E0000011C0E902117047017841F0800101705C +:1094F000FEF71EB901480178FDE700BFA01F00205C +:109500000148C069004700BF381F0020E0B5019046 +:1095100001A8FEF70DFC8CBD05300A21B0FBF1F06F +:10952000EEF724BEC0E9011204210170002070474B +:10953000C0E9011202210170002070472021EFF3E1 +:10954000118081F31188704701480078704700BF8F +:10955000AB88002001480078704700BFA227002098 +:109560000A46034669208021F9F788B80148007847 +:10957000704700BF96880020431C4520C02101226F +:10958000F9F77CB80148408B704700BF407B002052 +:1095900001480078704700BF8D2700200148807C7B +:1095A000704700BF407B00200148C08A704700BF61 +:1095B000407B002001490870704700BF8D270020C4 +:1095C0000020EFF3108072B6704770470020EFF371 +:1095D000108062B67047704701490870704700BF3D +:1095E0008E88002001494860704700BFF4250020A4 +:1095F00001480078704700BF702400200B460146E8 +:1096000010461A46FEF748BE0148006800F01EBB2F +:10961000DC2500200148006800F018BB0C24002065 +:109620009BF800004FF48051F5F7E2B902208DF865 +:109630004000E81C00F0F4BA0420394614222B46FE +:10964000FCF7BEBED0F85413D0F898000430084799 +:109650000221808C1080832000F0D8B8ADF8020081 +:10966000B068D0F8302470478DF818009DF840009D +:109670000F287047014A5160107070472C26002057 +:1096800018B1006808B100F0FFB9704701490968D6 +:1096900009680847E001001001490968C96A0847DC +:1096A000B80100100148006800680047E801001098 +:1096B0000148006840680047E801001001488068E0 +:1096C000704700BFD81B00200149202200F018BBC2 +:1096D00064B902000149202200F012BB24B9020043 +:1096E000E0B5019001A8FEF733FB8CBDA1F1FE00AF +:1096F000B0FA80F0400970470148006D704700BF24 +:10970000A01F00200068016B21F480710163704785 +:109710000068016B41F40071016370470068016BE0 +:1097200041F48071016370470149242200F0E8BAD6 +:109730009CB8020001490860704700BFE426002081 +:1097400001490860704700BFE826002001494870C1 +:10975000704700BF08880020014890F8310070472A +:10976000AC220020014890F82E007047AC22002067 +:10977000014981F832007047AC220020014981F88C +:1097800031007047AC220020014800210170704771 +:10979000AB88002001490860704700BF24270020E3 +:1097A00001480078704700BFBF880020014800686A +:1097B000704700BF3C8800200148002101607047CD +:1097C000E487002001480068704700BFE48700205C +:1097D00000680149EFF766BEB94C02000148007805 +:1097E000704700BFA8270020014800210160704792 +:1097F0005488002080B5F1F7F3FB4BF6BE2080BD06 +:1098000013460A4601460020F6F7B0BA13460A4648 +:1098100001460020FCF7D4BD01488069C06B704749 +:109820003822002080B51046F7F7F4F9002080BDFB +:1098300001460148FCF744BF207C00200148C06C71 +:10984000F6F76ABD0820002001680A6802605060CF +:10985000084670470168081AB0FA80F0400970475E +:10986000426808604A6011604160704701492422E3 +:1098700000F046BAC0B8020001488069704700BFD6 +:10988000382200202020EFF3118180F31188FEE7B9 +:1098900080B52421FFF718FB80BD006908B100F0F6 +:1098A000C1B970470088B0FA80F0400970470021C4 +:1098B0000170C0E901117047D5E90201D0F8D40068 +:1098C0007047DAF80800006C006870474846214687 +:1098D0003246FFF75DBC691D05F10D02F6F708BEC3 +:1098E000ADF8380068790024704784F80FA084F838 +:1098F0000E907047B068D0F8B800C16C7047002077 +:109900008DF82700F9F7B6BC316828688A6D2146C2 +:1099100010478DF8080002AB61207047ADF83800A1 +:10992000681D00F07DB92046FF214FF0FF327047DF +:109930000978B2FBF1F10844704700224FF08073C0 +:10994000FDF702B8C521C2B24520F8F797BE80B531 +:10995000FFF7F4FD000480BD80B5FAF707FA80B286 +:1099600080BD00214FF0FF32E7F714BE01EB40004D +:1099700030F8020C70474068002180F8FD107047F5 +:1099800080B5E8F737FE013880BD406801210068E6 +:10999000C1647047012085210022E0F731BC80B509 +:1099A000F6F71AFE002080BD80B5F6F73BFE0020DA +:1099B00080BD80B5FAF7DAF9C0B280BD0A4601462B +:1099C0000020F7F7A3BA80B5F4F782FD002080BD30 +:1099D0000021C0E900118160704701460020F1F7C5 +:1099E00097B901464A20FCF71DBB0138FDD17047ED +:1099F000704740680021017070478068D0F84C05BE +:109A00000047DBF80000F4F763BDD7E901102A46F0 +:109A100020470421007800F06DB840465146E2F737 +:109A2000EBB88068D0F84C0500478068D0F8401348 +:109A3000704700220023FBF769BB00230024FEF7D8 +:109A4000BBBB80B5EBF74EFE80BD40686C3000F0CC +:109A5000FDB84FF6FF70F5F7C5B901460020FEF7D7 +:109A600037B9FBF7A3FFF6F76AFD0222E1F714BA54 +:109A70000122E1F711BA0222F6F79EBC0122F6F7A5 +:109A80009BBC0021F1F744B9002101757047002209 +:109A9000EEF748BC80F3118870470122E2F772BFED +:109AA0000022E2F76FBF6FF00100704703689B6808 +:109AB00018470268D26810475846FFF7EBBF2146A7 +:109AC000FAF7D8BB2046FFF7E5BFE81C00F0A8B8BE +:109AD000084600F0A7B8281D00F0A2B82846FDF7F8 +:109AE00087BEE81C00F09CB82846FFF7D3BF0123CF +:109AF000EAF77ABA0023EAF777BA40F8041B70470E +:109B0000D0E901100847000CFFF7C4BF01680968DD +:109B100008470268126910470168C96908470021AF +:109B2000018070470720F2F7A9BE0022FAF754BE61 +:109B30000022FAF751BE01680968084702681269F5 +:109B40001047013080B270470021EFF7ABBC032013 +:109B5000F9F7F4FF0620DDF78FB90220DDF78CB9A5 +:109B6000E920E8F7B9BD0846ECF744BE0846F7F728 +:109B7000A9BB0846FCF7ACBE0121F4F797BD08224B +:109B8000FFF706BB0021F8F789BBC0B2F2F75EB859 +:109B9000000AFCF783BC0021016070478069FFF771 +:109BA000E2BF8069FFF7E2BF8069FFF7E2BF80692B +:109BB00000F0A4B8FEF70AFCFCE70020F8F7F6BBBB +:109BC00001207047FEF7E6BB0A207047FCF724BC73 +:109BD000FCF738BC007D704781607047FEF781BF9D +:109BE000FFF7D0BFF8F79EBBF8F7BEBB0020704769 +:109BF000FEF7AABAFFF7A5BFEDF71CBAF1F7CABE88 +:109C0000F6F7B2BEF7F7A2BCE7F7CCBBFBF7B5BFE0 +:109C1000FBF7A4BCF9F788BBE5F72EBB0020704723 +:109C200000887047F7F74EBBECF7E4BDF1F7E8B8F2 +:109C3000F9F7A8BAFCF748BC00207047EAF712BE53 +:109C4000FBF758B980687047FDF772BCF4F740BC69 +:109C5000FEF702BCFEF756BEF6F75EBBF8F7A6BBF2 +:109C6000FCF786BCF4F7D4B8F5F7B2BEFDF760BFD9 +:109C7000F9F748BFF9F762B8E8F782BA00207047F1 +:109C8000002070470020704700207047F320704785 +:109C90000020704700207047DC207047DD207047AF +:109CA000002070470020704700207047C220704796 +:109CB000FCF7DCBCE5F7B8BEFFF77BBE01207047C0 +:109CC000F5F702BCFAF728BFFFF7A8B8DEF7B6BC75 +:109CD00000207047F8F75ABAECF792BBFAF73EBA91 +:109CE000FEF704BB0020704700207047002070473B +:109CF0000020704701207047002070470120704706 +:0C9D0000FFF75CB9DFF800F01D870310CE +:109D10005465726D696E6174696E672065786563FC +:109D20007574696F6E2E2E2E0A00464F52434544BD +:109D30000044454255474556540056454354424C0D +:109D400000556E6B6E6F776E004D53544B455252FB +:109D50003A20537461636B696E67204572726F724B +:109D6000202852442F5752206661696C6564292C63 +:109D700020537461636B2050757368004D554E53CA +:109D8000544B4552523A20556E737461636B696E41 +:109D900067204572726F72202852442F57522066F6 +:109DA00061696C6564292C20537461636B20506F6A +:109DB00070004441434356494F4C3A20446174611A +:109DC000204163636573732056696F6C6174696FBA +:109DD0006E202852442F5752206661696C656429B1 +:109DE000004941434356494F4C3A20496E737472BF +:109DF000756374696F6E2041636365737320566980 +:109E00006F6C6174696F6E0053544B4552523A2027 +:109E1000427573204661756C742063617573656467 +:109E200020627920537461636B205075736800550C +:109E30004E53544B4552523A204275732046617539 +:109E40006C7420636175736564206279205374615A +:109E5000636B20506F7000494D5052454349534544 +:109E600052523A2044656C617965642042757320D2 +:109E70004661756C742C206578616374206164643C +:109E80007220756E6B6E6F776E005052454349536A +:109E90004552523A20496D6D65646961746520428E +:109EA0007573204661756C742C206578616374202D +:109EB00061646472206B6E6F776E00494255534542 +:109EC00052523A20496E737472756374696F6E20D2 +:109ED0004163636573732056696F6C6174696F6E5B +:109EE00000554E444546494E5354523A20556E64EF +:109EF0006566696E656420696E73747275637469F2 +:109F00006F6E00494E5653544154453A20496E767F +:109F1000616C6964204550535220616E6420696E03 +:109F2000737472756374696F6E20636F6D62696EAE +:109F30006174696F6E00494E5650433A20496E76FF +:109F4000616C6964205043004E4F43503A20417485 +:109F500074656D7074696E6720746F207573652009 +:109F6000636F2D70726F636573736F720053544B20 +:109F70004F463A20537461636B206F766572666C4E +:109F80006F77206572726F7220686173206F6363F0 +:109F9000757272656400554E414C49474E45443ACE +:109FA00020556E616C69676E6564206D656D6F72BA +:109FB00079206163636573730044495642595A4579 +:109FC000524F0045585445524E414C00564341545F +:109FD0004348004457545452415000424B5054009F +:109FE00048414C54454400457863657074696F6E10 +:109FF00020233A00457863657074696F6E206F6343 +:10A0000063757272656420696E20495352207468CA +:10A0100072656164206174205043203D20307825B2 +:10A020003038782E0A00457863657074696F6E2049 +:10A030006F6363757272656420696E206261636B21 +:10A0400067726F756E6420746872656164206174F4 +:10A05000205043203D203078253038782E0A0042A9 +:10A060006F67757320457863657074696F6E2072D1 +:10A07000657475726E2076616C75653A202530388E +:10A08000782E0A005461736B005377690048776932 +:10A09000004D61696E006D61696E28290045786325 +:10A0A000657074696F6E206F63637572726564208A +:10A0B000696E20546872656164547970655F2573B8 +:10A0C0002E0A002573206E616D653A2025732C20C1 +:10A0D00068616E646C653A20307825782E0A002518 +:10A0E0007320737461636B20626173653A2030780A +:10A0F00025782E0A00257320737461636B207369C1 +:10A100007A653A20307825782E0A005230203D209A +:10A110003078253038782020523820203D20307883 +:10A12000253038780A005231203D203078253038EB +:10A13000782020523920203D203078253038780A88 +:10A14000005232203D20307825303878202052319E +:10A1500030203D203078253038780A005233203DB9 +:10A16000203078253038782020523131203D203081 +:10A1700078253038780A005234203D203078253058 +:10A1800038782020523132203D2030782530387800 +:10A190000A005235203D2030782530387820205371 +:10A1A000502852313329203D203078253038780A24 +:10A1B000005236203D2030782530387820204C520F +:10A1C0002852313429203D203078253038780A0053 +:10A1D0005237203D203078253038782020504328D1 +:10A1E00052313529203D203078253038780A00500A +:10A1F0005352203D203078253038780A00494353A7 +:10A2000052203D203078253038780A004D4D465395 +:10A2100052203D203078253032780A004246535291 +:10A22000203D203078253032780A005546535220A0 +:10A230003D203078253034780A0048465352203D7E +:10A24000203078253038780A0044465352203D208B +:10A250003078253038780A004D4D4152203D20306D +:10A2600078253038780A0042464152203D20307827 +:10A27000253038780A0041465352203D2030782559 +:10A280003038780A0074692E73797362696F732E9F +:10A290006B6E6C2E5461736B2E49646C65546173E4 +:10A2A0006B000A0069643A20307825782061303AE2 +:10A2B00020307825782061313A20307825780A00DE +:10A2C000286E756C6C2900303132333435363738AE +:10A2D00039616263646566004E414D4500457272A6 +:10A2E0006F72207261697365643A2000417373650F +:10A2F0007274206661696C65643A2000B087002042 +:10A3000064800020A88600207C81002000000000DE +:10A3100000840020B8870020D0840020B886002068 +:10A32000708200209CB7020074BB02000ABC0200CD +:10A3300090BB020082BB0200C88600204827002094 +:10A340001C2700200C2700201027002018270020A1 +:10A3500014270020042700200827002000270020C1 +:10A36000D8860020DC800020588600209C820020B7 +:10A37000FAB2020088B202006CB30200DEB302003F +:10A3800050B4020048BA0200D0BB0200C4BB0200B5 +:10A39000B388002058870020E0240020EC840020AF +:10A3A000C8230020A8880020A9880020B0810020B0 +:10A3B0006C860020641E00208F27002000B202005F +:10A3C000A0AC0200000000000000000064BB02001E +:10A3D000C478002084880020808800203427002052 +:10A3E0003027002040880020E0B60200D8850020F9 +:10A3F000887D00200000000000000000B42500203F +:10A40000000000000000000000000000000000004C +:10A41000E4220020487500202C270020014A031068 +:10A4200049480310D549031015470310415F010047 +:10A430005D49031081470310A1460310954803109E +:10A4400045450310254A031021440310ED4703102E +:10A4500099490310E1480310214903105553031093 +:10A4600089520310CD520310655003108D4E031016 +:10A47000856A0100A1B301000DD9010000000000B0 +:10A4800059510310ED50031029C10100CD4B0310A9 +:10A490002952031011530310A955031075550310C9 +:10A4A00069530310DD55031035550310695A010037 +:10A4B00021540310855C03100D5603104D5D0310ED +:10A4C000A9640310B55B03106D570310E561031019 +:10A4D000095E0310C55803108560031071610310F5 +:10A4E000B16203109963031055630310FD600310FC +:10A4F000B15E0310ED370100D55A0310D559031092 +:10A5000009630310D963031019640310555F031026 +:10A51000C56403104D620310716403108D64031051 +:10A5200055640310E1640310297503107972031058 +:10A53000A16B0310F57203109D740310797403105E +:10A540002D74031061730310FD7303105574031011 +:10A5500015750310D96C0310FD7403106D180100FC +:10A56000E17403103D75031051530100F9640310A9 +:10A57000CD6803102D710310C1740310F56E031024 +:10A58000B9730310B1B40000056E0310B1400100AF +:10A59000B5590100A1770310797D03103D7E0310AA +:10A5A00049750310157E0310357D0310997603104D +:10A5B000997C0310257B031071780310B57D03107F +:10A5C000ED7C0310857E03102D790310B97A0310FA +:10A5D000917B0310B1790310ED7B0310E97D03102B +:10A5E000617E0310357A0310D57E0310457C03107D +:10A5F000A57E0310BD7E0310BD380100D980031075 +:10A60000E97E031049830310898403108D810310B0 +:10A610007D820310E58403102B840310C58303108F +:10A62000918703106188031045880310F18503109A +:10A63000B18803107D880310C98803101D8703109B +:10A64000A186031001850310E18803109988031087 +:10A65000F987031079410100359C0310819D031097 +:10A66000E99A0310359B0310C19B0310419A031014 +:10A67000F18803101D8C0310618F0310F1940310F7 +:10A68000919E0310C19E03103D9E0310699E03100E +:10A69000259E0310619D03100D9E0310819B0310E6 +:10A6A000ED93031055990310C9970310D99803101F +:10A6B000BD950310959C0310C19D0310A59E03102A +:10A6C0007D9E0310C9910310D9A50100699C031058 +:10A6D000DD9D031095900310FD9B0310CD99031091 +:10A6E000D98B0200019D0310E19C0310219D0310F2 +:10A6F000419D0310BD9C0310F59D0310A19D031007 +:10A7000055980310E1920310999A0310B99E031013 +:10A71000559E031079390200F784020039A2031014 +:10A72000117C020069A1031075A20310C59E0310DD +:10A73000B9A10310F9A1031015A103109DA20310E4 +:10A7400089970200538F0100CD3A0200ED85020087 +:10A75000499502002D95010031A90310ADA2031007 +:10A76000BDE40000B9A8031099A503108586010077 +:10A7700039A803106DA90310315601006DAC031008 +:10A7800099B1031009AF031059B1031001B10310BF +:10A790009DA90310A19C02009D9C02008D9C0200BB +:10A7A000819C0200959C0200999C0200859C0200FD +:10A7B000919C0200A59C0200A99C0200899C0200B9 +:10A7C000F1B9031075BA031081BB03109541020063 +:10A7D00045800100C9D0010019460100BD2B0200CF +:10A7E00051E301008D620200A9D80100514C020022 +:10A7F000796B0200CD8A0200B1E30100DD0D020099 +:10A80000DD9C0200854C020029B301002D88020066 +:10A8100065BB01003D26020045880200E59C020060 +:10A82000ED9C0200719B00000DDA0000E9C60310E8 +:10A83000E99C0200815E0000ED9B020005390200E8 +:10A84000A18A0200C12002004F9B0200878F0200F4 +:10A85000C58B0200AD9C0200910D020065850100D0 +:10A86000897E0100614000218D4000219940002136 +:10A87000FF4000216F410021074C657900F009F885 +:10A8800061796940490703D50121044A89031160B0 +:10A8900070BD70B5024908478003002108110440CB +:10A8A0002D59000000F00AF800480047577F0000CB +:10A8B00000F00AF8004800471B880000806B0C4934 +:10A8C0000007000F48717047094A0A491823507958 +:10A8D000CB56497EC018814201DD084602E00F28B0 +:10A8E00000DD0F20D189090909010143D181704799 +:10A8F000E00200218800002110B53348314C804728 +:10A90000012807D02034217D002903D101212F4ABD +:10A910000905916010BD072801D02D4A10472D4A26 +:10A920004A60C872704701222C4B02212A481847FE +:10A93000274810B5F83080472948406A00280DD1D3 +:10A9400028490A200856002809DA401C07D0084682 +:10A950002038406A2449884200D1804710BDFFF763 +:10A96000E2FF10BD0021224B204A08461847012073 +:10A970002049400208602048FB2201781140017004 +:10A9800013480C30004710B51C4988471549203939 +:10A99000012807D0020404D5002008851848486221 +:10A9A000012010BD4A6A0A4B0C339A4201D1154A64 +:10A9B00005E00B494A6A144B9A42F2D1134A4A62A3 +:10A9C00010BD00006001002175A6020000110440C6 +:10A9D000A9910200E1400021060800009F06000046 +:10A9E0000801002154010021639202001941002155 +:10A9F000B5B4020080E100E080030021F796020078 +:10AA00000F41002157410021699502004D4100216D +:10AA10008F000100DC27002087000100182600209D +:10AA200035002800F082002028000100C527002002 +:10AA300029000100C6270020840004006C270020A4 +:10AA400086000100D92200202A000100D82700201A +:10AA50002B000100C32700202C000100D22700207A +:10AA60002D000800192600202E000100C427002018 +:10AA70002F000100CF27002030000100B727002061 +:10AA800032000100BD27002033000100BC27002058 +:10AA900034000100BF27002036000100BE2700203F +:10AAA00038000100CE27002039000100D127002006 +:10AAB000830002008027002063000100D0270020CF +:10AAC00065000100D72700206D000100C488002028 +:10AAD00071000800AC26002066000100B2270020AB +:10AAE00043000100B6270020440002007C2700201C +:10AAF00045000100B0270020460002007827002012 +:10AB000047000800B426002048000100B4270020B8 +:10AB10004B000100B327002004000100D9270020CA +:10AB2000A1000100D627002037000100CB2700201C +:10AB300088000100CA2700203C000100D327002024 +:10AB40003D000100C92700204900020082270020A3 +:10AB500067000100B12700204D0002007E27002081 +:10AB60004E000100B52700204F0002007A27002088 +:10AB70003E000100BA27002051000100CC27002030 +:10AB800052000100C827002053000100C227002006 +:10AB900054000100C0270020000000000000000059 +:10ABA0000097B92EE5725CCB5DCAE473B82F0196AD +:10ABB000BA2D03945FC8E671E7705EC90295BB2C9D +:10ABC000E3745ACD0691BF28BE2907905BCCE2758D +:10ABD00059CEE077BC2B05920493BD2AE17658CF7D +:10ABE00051C6E87FB4230D9A0C9BB522E97E50C76D +:10ABF000EB7C52C50E99B720B6210F9853C4EA7D5D +:10AC0000B2250B9C57C0EE79EF7856C10A9DB3244C +:10AC1000089FB126ED7A54C355C2EC7BB027099E3C +:10AC2000A2351B8C47D0FE69FF6846D11A8DA3342C +:10AC3000188FA136FD6A44D345D2FC6BA037198E1C +:10AC400041D6F86FA4331D8A1C8BA532F96E40D70C +:10AC5000FB6C42D51E89A730A6311F8843D4FA6DFC +:10AC6000F3644ADD1681AF38AE3917804BDCF265EC +:10AC700049DEF067AC3B15821483AD3AF16648DFDC +:10AC80001087A93EF5624CDB4DDAF463A83F1186CC +:10AC9000AA3D13844FD8F661F7604ED91285AB3CBC +:10ACA000000136360101000102010001030100012B +:10ACB00004010606080400000C0100340D01000F19 +:10ACC00010040101140100FF16080000200200001A +:10ACD000220100FF23010001240100FE25010008DC +:10ACE0002602000028010001290100012A020000BB +:10ACF0002C01000F2E02000030010001310100087C +:10AD0000320200FF34010007350102FF3601000066 +:10AD10003701000138010001390100FF3A01000F3D +:10AD20003C0200FF3E01010F3F0100014001041FF2 +:10AD300041010001420100FF43010080440800007E +:10AD40004E0100084F01000F50010001510100FFAA +:10AD5000520100005301000054010001580400009A +:10AD60005C0400006004000064040000680400004B +:10AD70006C040000700400007404000078040000FB +:10AD80007C040000800100FF8101000182010001BC +:10AD90008301020284010001A4270020B88800205A +:10ADA000BD8800208C270020AA880020A127002031 +:10ADB0009F2700209597020061A00000B78A02003B +:10ADC00061620200356202002DED010071F40100A4 +:10ADD000450D02001D180200296B0200814B020084 +:10ADE00059610200B99C0200ED8B0200D9050200F6 +:10ADF000B14A0200016B020085610200F58D02007C +:10AE0000817302001D4C020001640100117B0100EE +:10AE1000053B0200D1EC0100890102006F940200A1 +:10AE20007D94020000000000317C0200A7AB01000D +:10AE300035AA01007D40020000000000DD61020033 +:10AE4000A197020005420200318E020000000000BE +:10AE50000000000035C40000D17B0200250602007E +:10AE6000610C02001300000081C100001F000000FF +:10AE70005D2A01001F800000ED320200000000008A +:10AE8000A17A000001000000A17A00000200000089 +:10AE90008592010002800000634801000300000069 +:10AEA000BD3E0200040000000D930100048000007C +:10AEB0004F6101000500000095150200060000002A +:10AEC000A57800003000000061F2010031000000B0 +:10AED000656C000032000000A56601003300000030 +:10AEE0005565010034000000FD65010036000000DA +:10AEF0002DCA010011000000E9000200140000004A +:10AF00009593010015000000DD480200FFFF0000DE +:10AF10000000000068617264776172652065786383 +:10AF2000657074696F6E206964203D2025642C2053 +:10AF30007063203D2030782530387820282F4170EC +:10AF4000706C69636174696F6E732F74692F7369B4 +:10AF50006D706C656C696E6B5F6363313378785FBD +:10AF60006363323678785F73646B5F375F31305F6D +:10AF700030305F39382F6B65726E656C2F74697273 +:10AF8000746F73372F7061636B616765732F7469BA +:10AF90002F73797362696F732F66616D696C792F96 +:10AFA00061726D2F6D332F4877692E633A313039D6 +:10AFB00032290048776920616C7265616479206488 +:10AFC0006566696E65643A20696E74722320256433 +:10AFD00020282F4170706C69636174696F6E732FE4 +:10AFE00074692F73696D706C656C696E6B5F6363F8 +:10AFF000313378785F6363323678785F73646B5F80 +:10B00000375F31305F30305F39382F6B65726E6576 +:10B010006C2F746972746F73372F7061636B616723 +:10B0200065732F74692F73797362696F732F66610B +:10B030006D696C792F61726D2F6D332F4877692E92 +:10B04000633A33383529006E6F204953522C2069FA +:10B0500064203D2025642C207063203D203078251D +:10B0600030387820282F4170706C69636174696F83 +:10B070006E732F74692F73696D706C656C696E6B7C +:10B080005F6363313378785F6363323678785F73F8 +:10B09000646B5F375F31305F30305F39382F6B65FD +:10B0A000726E656C2F746972746F73372F70616381 +:10B0B0006B616765732F74692F73797362696F733E +:10B0C0002F66616D696C792F61726D2F6D332F481A +:10B0D00077692E633A3130393529006F7574206FE6 +:10B0E00066206D656D6F72793A20686561703D30DC +:10B0F0007825782C2073697A653D257520282F41A5 +:10B1000070706C69636174696F6E732F74692F73EB +:10B11000696D706C656C696E6B5F636331337878F1 +:10B120005F6363323678785F73646B5F375F3130AB +:10B130005F30305F39382F6B65726E656C2F7469C4 +:10B1400072746F73372F7061636B616765732F74EF +:10B15000692F73797362696F732F72756E74696D7D +:10B16000652F4D656D6F72792E633A373829006906 +:10B170006E746E756D3A202564206973206F757446 +:10B18000206F662072616E676520282F4170706C99 +:10B1900069636174696F6E732F74692F73696D7061 +:10B1A0006C656C696E6B5F6363313378785F636382 +:10B1B000323678785F73646B5F375F31305F303081 +:10B1C0005F39382F6B65726E656C2F746972746F9E +:10B1D00073372F7061636B616765732F74692F73A9 +:10B1E000797362696F732F66616D696C792F617213 +:10B1F0006D2F6D332F4877692E633A333737290027 +:10B20000360001000600000000000000000F0000F2 +:10B21000000000000000000000000000000003002B +:10B22000FFFF00000403FFFF0000FFFF0F00E80323 +:10B230000005401F0310000100000000FF3F0F0049 +:10B240000800050B00000000000000000300010FD3 +:10B2500000000000000000000000000000000000EE +:10B2600000000000000000000000000000000000DE +:10B2700000000000000000000000000000000000CE +:10B28000AD00000200000000010171010101010197 +:10B2900011010101310101010101800100011001D1 +:10B2A00061013B00140063017301720162014301FB +:10B2B0000001130106013D013500040112010001E6 +:10B2C00000010001000104010401330133013C01CC +:10B2D0004401320136000001000165010001350022 +:10B2E0008101000105018201830100016601000165 +:10B2F0000001080109010A010B010300710030017E +:10B30000600011007000310220035004800007002B +:10B3100010006100000014006300730072006200FE +:10B3200043000000130006000000000004001200AB +:10B330000000000000000000040004003700370097 +:10B340003C02440000000000000000006500000016 +:10B350003500810000000500000083000000660049 +:10B3600000000000080009000A000B00030271023F +:10B370003001600211027002010202020202800228 +:10B380000002100261023A0041006302730272027D +:10B3900062024302000213023800000200020402AB +:10B3A000120200020002000200020402040237003E +:10B3B00037003C024402000239000002000265022C +:10B3C00000023502810200020502820283020002AD +:10B3D000660200020002080209020A020B020103CF +:10B3E00071030103010301030103010322030203AB +:10B3F0000103000310030003000300030003000324 +:10B4000000030003420300032403060300030003B8 +:10B410000403120325032303250323030403040366 +:10B42000000300030003440300030003230300039D +:10B4300065032100350381030003050300030003B6 +:10B440000003000325032303080309030A030B0376 +:10B450000304710402046004110470040204020471 +:10B4600001040204000410046104000414046304D1 +:10B470007304720462044304000413040604000409 +:10B480000004040412040004000400040004510435 +:10B4900064000004000400044404000400040004E8 +:10B4A00000046504000435048104640005040004FC +:10B4B00083040004660400040004080409040A0468 +:10B4C0000B040E004F990200079B0200299C02000A +:10B4D000259C020031800200BD8F0200B59402005D +:10B4E00069700200657E0200F36D0200F9680200D7 +:10B4F000BD2702007D530200A98402004DEA01002D +:10B50000A9F00100F9BE010051E001008B94020096 +:10B5100089760200CD9B0200E19D01008196020028 +:10B52000FD6E0200AB8F02007F9B0200AB76020033 +:10B5300001000000A1560000060000006BE70100BA +:10B5400008000000358801000B0000003D190200D2 +:10B5500010000000753001000A000000E1A10100A8 +:10B56000020000001DD500000500000025CC0000F1 +:10B570000700000011E401000C000000A5760000A7 +:10B580000D000000610C00006400000051DD0100AE +:10B59000FF0000000000000000B000403400000088 +:10B5A000FF00000060830020200000008083002056 +:10B5B00020000000000000000C0000000D00000052 +:10B5C000FF000000FF00000060180020501800205D +:10B5D00040000000200000001300000014000000E4 +:10B5E000130000001500000016000000000200001B +:10B5F00052616E646F6D5F736565644175746F6DE4 +:10B60000617469632829206661696C65640041453D +:10B610005343434D206F70656E206661696C6564AD +:10B6200000414553454342206F70656E2066616955 +:10B630006C65640054524E47206F70656E206661E1 +:10B64000696C656400058E0000008E0001008E00AC +:10B6500002008E0003008F0000018F0000028F00A7 +:10B6600000038E0001048E0000058E0008048E0089 +:10B67000000489000006500000007F0001003F0028 +:10B6800004003F0002003F0001007F0002008E0026 +:10B6900002048E0001028E00010100060286821E55 +:10B6A0000128000000000000000000000001003040 +:10B6B00000000000000000000003FF18640000000C +:10B6C0000000000000000000785634120000000066 +:10B6D000BAAB000000000001000000000000000004 +:10B6E000C003000080070000000F0000001E0000E3 +:10B6F000003C00000078000000F0000000E00100C5 +:10B7000000C003000080070000000F0000001E00C2 +:10B7100000003C00000078000000F0000000F00095 +:10B720000000004017FF0000000000000400FFFFC1 +:10B730000800000010000000401800203018002011 +:10B74000401A0020301A00200A0000000900000002 +:10B750000C0000000B00000009080AFF0A000000AE +:10B760000A000000020000000400000008000000C1 +:10B7700010000000200000004000000080000000D9 +:10B7800000010000000200000004000000080000AA +:10B790000010000000200000004000000000000039 +:10B7A00002000000020000000A0000000200000089 +:10B7B0000200010000000000000000000000000086 +:10B7C0000000000000000000000000000000000079 +:10B7D0000E000000F3990200A79A0200BD52020079 +:10B7E00011790200A10702009586020069AF0100ED +:10B7F000ED07020009960200A1020100619D01000F +:10B8000095E90100ED5202001B8F0200C53C0200C9 +:10B81000AD86020081FF0000F9FF010015960200CD +:10B8200025C0000000000000000000000000000033 +:10B830000000000000000000000000000000000008 +:10B8400000000000000000000000000000000000F8 +:10B850000060250000100000A87F002040000000CC +:10B86000000000000000000000093D00140000007E +:10B87000640000005DD600001D9D00001D4000001A +:10B88000DD530000E543000099D70000414E000061 +:10B8900045840100BD210000995201000000000014 +:10B8A0000000000000000000000000000000000098 +:10B8B0000100000000C201000300000000000000C1 +:10B8C0000000000000000000000000000100000077 +:10B8D0000000000000020000000000000000000066 +:10B8E00001000000022C0000000000000000000029 +:10B8F0000000000000000000000000000000000048 +:10B90000000000000208000000000000000000002D +:10B91000000101000800FFFF0C260020A0240020E9 +:10B920008824002000000000FFFFFFFF000000004F +:10B930000000000040420F0008000000000000006E +:10B9400000000000080000000800000008000000DF +:10B9500008000000040000000200000001000000D8 +:10B9600001000000FFFFFFFF0000000000000000DA +:10B97000000000003A013A01000000000000000051 +:10B98000000000000000000000000000E8030000CC +:10B9900000000000000000000000000000000000A7 +:10B9A000D4B70200BA8800206CBC0200FCB70200C9 +:10B9B000648700204CB802000100000040420F00E4 +:10B9C0000100000000000000000000000000000076 +:10B9D00003080000000000000000000000016509ED +:10B9E0000000000000000000012C0000000000002A +:10B9F000000000000001001E000000000000000028 +:10BA000049B101007D29010077990200F1A90000E8 +:10BA10001551000001820100038000C0038000D5A1 +:10BA2000038000CC038000DD0380000C0380005DF8 +:10BA30000000000002000000010000000300000000 +:10BA4000100000002000000000000500BD00B7004D +:10BA5000B100BC001C0030003800080038010200B2 +:10BA600000000000000000000100000000000000D5 +:10BA7000E0000000010000005B41737365727420F8 +:10BA8000526561736F6E5D20307825303258000248 +:10BA90000000000099570100C58602000101010065 +:10BAA00000000000032C0000000000000000000067 +:10BAB0000000000000000000020000000000000084 +:10BAC00000000000FFFFFFFF00000000000000007A +:10BAD0000000000000000000050000000000000061 +:10BAE000001610000018151002000224145800005F +:10BAF000100000020200000000000000FFFFFFFF36 +:10BB0000000000000200000000000000FFFFFFFF37 +:10BB100000000000E81D0020D07900204C7A0020B1 +:10BB2000FFFFFFFF0C78002096BC02006878002021 +:10BB300098BC0200000000000000000000000000AF +:10BB4000000000005A6967426565416C6C69616E6E +:10BB500063653039D0D1D2D3D4D5D6D7D8D9DADBB2 +:10BB6000DCDDDEDF88B22400881300001000000056 +:10BB70000000000100A6AAACA4A9A9A399B19ABC8F +:10BB8000B6A8313118191A22311C1E203131343136 +:10BB9000313117191A21241B1D1F313133317F0018 +:10BBA000FF0000000000000000010000FF00010095 +:10BBB000C38402000700000000BA0200487400209D +:10BBC00020B702000C0E020B040B0A070800110F2D +:10BBD000000120181A18182C34041E000000000060 +:10BBE0000000000000000000000000000000000055 +:10BBF00000000000FF0000000000000080A903001A +:10BC000002010207016BB1340100020402010101CB +:10BC100001090201782100207C210020C08500203C +:10BC2000CBBC0200C8820020CCBC0200E8030000AC +:10BC3000000064004C790020F4BB0200DC6B0020A3 +:10BC400098B502002084002084BC02000102000399 +:10BC50000200010300BE020800BE040AFFFFFFFF4E +:10BC6000FFFFFFFF000800040002000100000500C4 +:10BC700000600000DDA20200ECA20200794902008F +:10BC8000DD860200000002400929FF0000081018AC +:10BC900020000102030406010701F4010000000076 +:10BCA000220001004400010000204060E803000081 +:10BCB00088130000200000007C1F00208813200053 +:10BCC000000000002800C800000801402001080F03 +:10BCD000030C1E040A3205050808FA0CFF040001D3 +:08BCE0004503011E483033004A +:10BCE8004D59000039E1000000000000000000008C +:10BCF800000000000D870200658C020049980100D1 +:10BD0800C9960200319B02002B9B02005F8A020049 +:10BD1800000000001F9B02004DA701007DF90100F3 +:10BD2800317A0200C59701003F8F0200BD2E010045 +:10BD38007982000011C80100917A02000000000019 +:10BD4800D51D0200F5860200556E0100258B020004 +:10BD5800E18F0200D1940200D18F02009198020075 +:10BD6800719A02006B9A0200398B0200019002005E +:10BD780011930200F18F0200DD9402007D9A020007 +:10BD8800779A02003195020025950200842500204B +:10BD98004C1D002004B90200D0B90200E8B9020025 +:10BDA800A0B60200E4B80200A4BA02000000000035 +:08BDB800000000000000000083 +:10BDC00001E500000FA1020100BF0514BF027D9C28 +:10BDD000023F001D370100F1007016B5FFECC604EC +:10BDE0000000EEC806EF0000F1CA0040F4CC0A6F74 +:10BDF0000000F6CF0040F7D00090FFFAD41000000A +:10BE0000FBD612DF0000FD931819E05328FA071043 +:10BE10005600400259320000FF035D380000046301 +:10BE20004EFF0000051772000006FF2A4F1480071E +:10BE30005F2814FF80085A331080095FFF3F10808D +:10BE40000A664F1080FF0BCB2130800CCC27FF3FC0 +:10BE5000800DCDC33F800EFFD6271B800FDA2F1B2E +:10BE6000FF8010DE391B8011E5FF4F1B8012E04779 +:10BE70003080FF13E2613F8014F575BF3F807FFF84 +:10BE8000FF3F0CEF04021D6022500400200031002F +:10BE9000B000727E00B400022000200101718140D8 +:10BEA00000340131003801B2013C0239003108058B +:10BEB00070003528CFC6016CDC1FC73700FD033783 +:10BEC0004441050200A585E50215A02726FF0C27A1 +:10BED000051B00207B3477127F2CC81F0020003107 +:10BEE000163F717C881737E0017000312CFF022368 +:10BEF000108219BF4834B134F80130A0492F9F0196 +:10BF0000FFC1FD0100E8BC02009B54BD3E33696CDB +:10BF10001EEA562F9701B57D1B60D7BD3B00003D43 +:10BF200061C4DB7515625F0CA574645F04ADDD3F11 +:10BF30000000382200200031527F06254025B05CE9 +:10BF4000023000316400345A0F3B3E6E0F06080089 +:10BF500000FFFF54F058A0E10F3938006FB202170C +:10BF6000EF12877F262BD4D7FFFD0307C2018387FB +:10BF700003FF00C3060201A86001FE1C70FFFF2B37 +:10BF80005EC80103BF073205838700017105B20156 +:10BF9000700401718DFF16FAB279F7DEADB33BFF85 +:10BFA00014FEFE93DF2C14000C01AC2930864901ED +:10BFB0000C99D780874485E51945BB995C3835BE17 +:10BFC0006080007532001002641001007D9EAF2F6A +:10BFD000FC167116B183880F00D388FDF317720029 +:10BFE000012345678967ABCDEF037F0AA6440503AC +:10BFF000219F28FFDD7D002019780100F53994F09C +:10C000000B9200542500202B942600339C0034A46E +:10C010000034083F05E9FF8C30AEE880AFAE87748E +:10C02000012C0032B13F12A9B1B39F0EF00034B61B +:10C030001F18F3881325FC2D80803E05007FF40136 +:10C04000E803FFFFFE2CB173010383D1A200003C83 +:10C0500000A3F034A927A5D130BCC10F011ED10027 +:10C06000F0FF0102010A031E0103EF0101780175CF +:10C0700060030808DF020403090801E2FE057700F7 +:10C080000DFE8560E00102A7B00101FFF000000095 +:10C090000193020087CD0100C3940200000000005C +:10C0A0001000000000000000100000000000000070 +:10C0B0001000000000000000100000000000000060 +:10C0C0001000000000000000100000000000000050 +:10C0D000E56000000000000010000000000000000B +:10C0E000D8000000C0BD0200D81B00209CC0020088 +:10C0F000301A0020A4C0020030180020ACC002009A +:10C10000401A0020B4C0020040180020BCC0020049 +:10C1100050180020C4C0020060180020CCC00200EB +:10C12000E0270020D4C002000C010020DCC0020087 +:04C13000001B0020D0 +:020000040005F5 +:207FA800000080011000C0FFFDFF58003AC1F9F1FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF40 +:207FC800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC508FEC5FFFFFFFF00FFFFFF00C5C5FF97 +:187FE800000000FF00000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF92 +:00000001FF diff --git a/tools/fw_SonoffZigbeeBridgePro_cc2652/SonoffZBPro_coord_20240710.hex b/tools/fw_SonoffZigbeeBridgePro_cc2652/SonoffZBPro_coord_20240710.hex index 8cbeec0fe..236536748 100644 --- a/tools/fw_SonoffZigbeeBridgePro_cc2652/SonoffZBPro_coord_20240710.hex +++ b/tools/fw_SonoffZigbeeBridgePro_cc2652/SonoffZBPro_coord_20240710.hex @@ -1,11264 +1,11264 @@ -:100000000030012001520200696F0200696F020096 -:10001000696F0200696F0200696F0200696F020078 -:10002000696F0200696F0200696F0200696F020068 -:0C003000696F0200696F0200A9F6000071 -:10003C002DE9F04F99B0054680780224532800F240 -:10004C00CF85DFE810F054009900A800B800C80074 -:10005C00DA00EA000C011B01CD052A013801590117 -:10006C00CD05CD05CD05CD05CD05CD05CD05CD05F4 -:10007C00CD05CD05CD05CD05CD05CD05CD05CD05E4 -:10008C00CD05CD05CD0565018A019601A201AD0115 -:10009C00BC01D601ED0109023C02CD05CD05CD0513 -:1000AC00CD05CD05CD05620278028E02A402BA02FE -:1000BC00CF02E0020503CD05CD05CD05CD05CD055F -:1000CC00CD053A034E036203CD056F037903970305 -:1000DC00A003AC03B803C703D103F4031104360423 -:1000EC003E0450045D0469048D0494049704EC1CD4 -:1000FC00E97A2A7B002320461EF0F2F88DF81800CE -:10010C0006AB65200021012222F038FBDFF8280B1A -:10011C000078012800F26385204629F019FE00289A -:10012C0000F05D8505460079012840F0588529F0DE -:10013C0093FB00274FF400018DF83F008DF8380039 -:10014C00000ACDF83A108DF841708DF83E708DF89C -:10015C0040008DF839000EAE214606F10A0029F058 -:10016C0078FE2978152233460170697887704170C2 -:10017C004520FF2100F031BD29F01DFE6979AA79D7 -:10018C000023002425F09AFB8DF838000EAB652077 -:10019C00012100F05ABC29F095FB29F017FD01460E -:1001AC000EA8022229F0A7FD8DF8180006AB6520D9 -:1001BC00022100F04ABC29F085FB29F007FD01461D -:1001CC000EA8032229F097FD8DF8180006AB6520C8 -:1001DC00032100F03ABC29F075FB29F0F7FCEA7911 -:1001EC0001460EA80023002427F0C2F98DF8180050 -:1001FC0006AB6520042100F028BC29F063FB29F034 -:10020C00E5FC01460EA8052229F075FD8DF81800B5 -:10021C0006AB6520052100F018BC0020DFF8404A31 -:10022C0029F037FAADF85800681DA0478046E81D44 -:10023C00A04795F809A0814605F10A07BAF1100FFD -:10024C0000F2B2830EAC5546002D00F0B083384658 -:10025C0029F050FE24F8020B013D0237F4E729F097 -:10026C0031FB29F0B3FC01460EA8102229F043FD06 -:10027C008DF8180006AB65200721E6E329F022FB78 -:10028C0029F0A4FC01460EA8112229F034FD8DF8AA -:10029C00180006AB65200821D7E329F08CFD6A7B9A -:1002AC00691D0023002423F071FF8DF838000EAB7C -:1002BC0065200A21C9E302208DF8200029F07BFD7E -:1002CC00ADF81800681D29F015FEEA79064605F10F -:1002DC0008018DF838200EAF781C29F0B1F806A86B -:1002EC0031463A460023002420F02EFC8DF85800AD -:1002FC0016AB65200B21A8E329F05DFD002100243D -:10030C0023F04AF98DF838000EAB65200C219CE3E4 -:10031C000020DFF84C4929F0BCF9ADF85800681DF5 -:10032C00A047814695F80FA005F11000A04795F85D -:10033C0012B0074605F11304BBF10F0F00F249830D -:10034C000EAE5D46002D00F04783204629F0D2FD0D -:10035C0026F8020B013D0234F4E729F0B3FA29F038 -:10036C009FF929F05DF840F04B8306A829F071FD48 -:10037C004BE329F0A7FA29F093F929F051F840F052 -:10038C00528306A829F065FD52E329F014FD29F0EB -:10039C00FAFB8DF838000EAB6520232100F01CBC55 -:1003AC00DFF89418C8208DF81800E81C097800298B -:1003BC0000F0878328F0D3FC8DF81800A9E3687946 -:1003CC00EE1CFE280BD1A879FF2808D12878082824 -:1003DC0005D3304629F08EFD314625F097FC0EA949 -:1003EC00304628F099F9002800F097830546002440 -:1003FC00A5E3E81C042126F0BBF9E97929F09CFD62 -:10040C00DFF850188DF83800022028F0DDFDDFF8F9 -:10041C004818032028F0D8FD0EAB65202621DBE31D -:10042C0029F0C3FC044605F10E0029F063FD297C7C -:10043C006A7C0346E878CDE90012AA1D214625F016 -:10044C00C1FEDFF80C188DF83800042028F0BCFD34 -:10045C000EAB65202721BFE34FF00208E81C8DF896 -:10046C00408029F047FDADF8380068798DF85800C8 -:10047C00A81D29F03FFD2E7A044600270935CDE949 -:10048C00005716A80EA92246334621F04BF929F045 -:10049C0043FA10D1DFF89C078DF84080CDE9005766 -:1004AC0022463346C08AADF8380016A80EA921F0B2 -:1004BC0039F98DF8180006AB652028218CE302264B -:1004CC00E81C8DF8406029F015FD29F07FFBED79D3 -:1004DC0004460EA8002321462A4627F0BFFF29F028 -:1004EC001BFA0ED1DFF84C078DF8406021462A46E6 -:1004FC000023C08AADF838000EA827F0AFFF8DF8A6 -:10050C00180006AB6520292166E329F0DBF9ADF86C -:10051C003800681D042126F02BF96A7AAB7A002486 -:10052C00014600940EA825F079FE8DF8180006AB54 -:10053C006520302189E229F0C5F929F029FB312207 -:10054C0001238DF8580016A8CDE90004DFF8FC064D -:10055C000EA921F0E7F88DF8180006AB65203121C3 -:10056C0073E229F0AFF929F013FB322201238DF845 -:10057C00580016A8CDE90004DFF8D0060EA921F02A -:10058C00D1F88DF8180006AB652032215DE229F018 -:10059C0099F929F0FDFA332201238DF8580016A899 -:1005AC00CDE90004DFF8A4060EA921F0BBF88DF804 -:1005BC00180006AB6520332147E229F083F9ADF82A -:1005CC003800687B0024691D0094C0F3400200F0E1 -:1005DC0001030EA822F0C2FF8DF8180006AB6520AF -:1005EC00342132E229F06EF96A7BADF83800691DCE -:1005FC000EA80023002426F05DFB8DF8180006AB36 -:10060C006520352121E22C4614F8030B04281ABF6F -:10061C00E8782C1D02208DF84000204629F06AFC59 -:10062C00DFF82466A5780121E278ADF838000023C4 -:10063C00002431700EA829461EF0C4FE8DF8180057 -:10064C002846347026F072FB06AB65203621FCE19F -:10065C0029F0B1FBADF83800687904218DF8400021 -:10066C00A81D26F085F80446AE7AEF7A05F10C0049 -:10067C0029F040FCDFF8BC850546214632463B4656 -:10068C0029F015F80EA821F029F829F045F910D118 -:10069C000220214632463B468DF84000B8F8160041 -:1006AC00ADF8380029F003F80EA821F017F88DF8F2 -:1006BC00180006AB652037218EE26C7829F07BFBA5 -:1006CC000146DFF88005007820F018FA8DF8380024 -:1006DC0004F0E000202840F082820EAB65203E2121 -:1006EC007AE26C7829F067FB0146DFF85805007850 -:1006FC0021F000FD8DF8380004F0E000202840F0D7 -:10070C006E820EAB65203F2166E200206C788DF87E -:10071C003800DFF824050078411E022980F0998109 -:10072C0002209AE129F047FB29F02DFA8DF83800C8 -:10073C000EAB652042214FE2002006908DF83D0063 -:10074C00CDF83900E81C06A926F024FF8DF83800F6 -:10075C00069850B128F081FF81788DF83B10C17854 -:10076C008DF83C1000798DF83D000EAB65204321CF -:10077C00062232E2E81C28F0F2FA8DF838000EABB3 -:10078C006520442128E229F016FB6979AA790EF03C -:10079C00D7F88DF838000EAB652045211CE229F006 -:1007AC000AFB6979AA791AF0A1FC8DF838000EAB16 -:1007BC006520462110E2EC7829F0F7FA0146204634 -:1007CC0022F0DCF9B0FA80F0472140098DF83800AE -:1007DC000EABC7E1E87800248DF8384023F046FDD5 -:1007EC000EAB6520472130E1E8780EA926F0F6FE25 -:1007FC0006468DF8180040000130C5B2284629F095 -:10080C007DFB002800F0A981044600F8016B002153 -:10081C009DF81820914280F0C0809DF8383001314D -:10082C0000F8023B9DF8393000F8013CF2E70EACC1 -:10083C001321204629F06CFAEE7829F0B6FA01461D -:10084C00304626F09BFA002800F08E810021231DF3 -:10085C008DF8381028F001FFC11C827818468DF8ED -:10086C003B2028F0EDFD82E10020EC78CDF846002D -:10087C00CDF84200CDF83E00CDF83A0029F095FABB -:10088C00AA79ADF838000F2A28BF0F228DF83A202C -:10089C0022B10EA8E91D033028F0D2FD0EA9204686 -:1008AC0001221DF0BDF88DF8180006AB65204B2118 -:1008BC0092E128F00DF98DF838000EAB65204C2133 -:1008CC008AE1E87829798DF838100EA9032800F010 -:1008DC006581022800F06881012840F06C8152206B -:1008EC0021F04CFC6AE129F066FA69790246A81DF0 -:1008FC001BF013FB8DF838000EAB65204E216BE11D -:10090C0029F059FA0146687919F0A8FF8DF83800DA -:10091C000EAB65204F215FE1C64D0822E88A05F138 -:10092C003901ADF83800C54800788DF83A00A88C2C -:10093C00ADF83B00688BADF83D000EACE01D28F027 -:10094C007FFD04F10F0005F11C01082228F078FD51 -:10095C00287E5021182223468DF84F0065203CE15B -:10096C00B5480078002800F00781122010E120F033 -:10097C0053F834E100208DF83800E87841B2B1F139 -:10098C00FF3F06DC10F07F00AA4918BF012081F858 -:10099C0068000EAB652053211EE1652049212A46D3 -:1009AC00234621F0EBFE3DE180208DF8630097F8A3 -:1009BC0000B0BBF1100F53D87E1C4FEA4B0500243E -:1009CC0006AFA5424ED0301929F094FA38530234B0 -:1009DC00F7E780208DF8630026780F2E58D80597FE -:1009EC00671C75004FF0000806AC454552D007EB6C -:1009FC00080029F07FFA24F8080008F10208F4E74F -:100A0C00084629F077FAADF81800687E06A928F098 -:100A1C000FFD0EA921201BF0D1FB8DF8580016AB51 -:100A2C006520212111E0084629F064FAADF8180080 -:100A3C00687E06A928F0FCFC0EA922201BF0BEFB48 -:100A4C008DF8580016AB65202221012221F096FE6C -:100A5C00C6E0002840F0B680042009F001F8B4E0AC -:100A6C0080200EE0BAF1100F0DD80EA900204A46D6 -:100A7C005346CDE9001BCDE9027016A8414615F08E -:100A8C0031FA8DF863000DF1630365200621A3E0B4 -:100A9C0080200FE0BBF10F0F0ED80EA90020CDE97E -:100AAC0002645246CDE900B1049016A8059B494654 -:100ABC0015F0C0F98DF863000DF16303652020215A -:100ACC008AE016A90EAD2A4618F03CFE04469DF8A5 -:100ADC005800F0B1614904EB4400002641F8206055 -:100AEC0001EB800046609DF94B00B0F1FF3F03DC49 -:100AFC0005F1130023F03AF80EAD1421284629F025 -:100B0C0007F90420214614222B4625F097FD8DF879 -:100B1C00186006AB652024215EE0182029F0EEF960 -:100B2C00002800F083800446BDF83800002118220C -:100B3C00234628F01BFB0546002818BFC8251920A2 -:100B4C0029F0DCF9002867D007460130002D4BD086 -:100B5C001821FF2229F086F850E0002049218DF859 -:100B6C00180006AB652037E001208DF838000EAB7D -:100B7C0065204A21132230E029F01DF9044605F1C5 -:100B8C000D0029F0B7F90246691D204625F05CFBE3 -:100B9C008DF838000EAB652051211DE0522021F05C -:100BAC00EDFA2748002104E0522021F0E7FA24480E -:100BBC000121017002E0522025F09EFB0EAB652056 -:100BCC004D2109E001208DF8380004F0E0002028C8 -:100BDC0005D10EAB65204021012221F0CFFD002470 -:100BEC00204619B0BDE8F08F3146082228F028FCC9 -:100BFC0007F109002146102228F022FC652025214E -:100C0C0019223B463D7021F0B9FD3846192129F0D7 -:100C1C007FF8384629F070F9002CE0D020461821D6 -:100C2C0029F076F8204629F067F9D8E7C825FFF7B0 -:100C3C00DEBB00BFA86D002024260020D02600209B -:100C4C00E52700209A7A0020A5270020882600207E -:100C5C00B96A02007F70020019500100F0330020C5 -:100C6C00019F02002DE9F04F99B080466FF007000C -:100C7C00DFF8DCA80630ADF852009AF80000022824 -:100C8C0014D1DFF8C808007880B9B8F8080010B1A2 -:100C9C001020012101E0302000210AF0E5FD0020A8 -:100CAC008DF81C0007A9522021F068FA0DF11C09DF -:100CBC0098F80810D8F804004A4610F089FAE8B100 -:100CCC009DF81E609DF81F409DF82050BDF82670C1 -:100CDC0028F0BCFD844211D127F003004FF6F871C7 -:100CEC0080B288420AD0012D08D8022E06D29AF87A -:100CFC000000022808D19DF84D0028B1D32019F02E -:100D0C0076FC19B0BDE8F08FB8F82800ADF84800B3 -:100D1C00B8F83200ADF82A009DF82200D0B1D8F80E -:100D2C0004109DF81D209DF83830012027F034FB6D -:100D3C0008B1CF20E3E7DFF81C08C078012809D1FF -:100D4C00B8F8280028F0A7FF20B1417901F0E7019D -:100D5C00083141719DF8210068B1BDF82610FF20C3 -:100D6C0026F00CF89DF82110E0B141F001012C2681 -:100D7C008DF8211017E09DF83900002800F0EB8069 -:100D8C009DF83D10FF2902D0002940F02681DFF8A4 -:100D9C00C807BDF82620C18A8A4240F0278101206D -:100DAC00222607E0082601F00300012808BF46F0C0 -:100DBC00110601209AF800104FF6F877012908D88F -:100DCC00B207344658BF64F07F04002808BF34468D -:100DDC0000E034469DF82200DFF87C575FFA84FB74 -:100DEC0030B9E87A20B10BF02200222840F0808044 -:100DFC001BF0400004901CD0012903D8A87B80076D -:100E0C0000F1D880119801780C2900F2DB800122C6 -:100E1C0041F298438A401A4200F0D480032902D14F -:100E2C0040780D2805D007A822F0F4F901283FF4EA -:100E3C0068AFA88CB8F8441081420AD198F84620C3 -:100E4C00B8F84210B8F8280000230093002307F0EC -:100E5C0001FE9DF82200F8B1B8F84210B8F828004D -:100E6C0022F0E4FC002800F08F800646D8F804003D -:100E7C009DF81D10F2780844417B8A421EBF002267 -:100E8C007260F1700130042125F072FC71688842A7 -:100E9C00FFF437AF013070609AF80000022834D2AA -:100EAC00A87B80077FF52DAF9DF84D004FF6F876A7 -:100EBC0060B1BDF8280027F0BBFC002800F00781CA -:100ECC00D8F80400417801F0DF0141709DF82E0044 -:100EDC00002800F0DF80D8F8040081790139817195 -:100EEC008DF82E1004F07F00090640F0D680D3E078 -:100EFC000BF0420042287FF41CAF1198007800F0F0 -:100F0C00FE0006287FF415AF72E77FF4FAAE95F871 -:100F1C002600092802D004287FF4F3AE5FEA8B6028 -:100F2C0000F19E80049800283FF4EBAE11989DF8D8 -:100F3C0038100078042808BF022900F045810728E2 -:100F4C0008BF042900F009810C2840F04D8107A846 -:100F5C0015F080FBD5E6BDF8260022F0E7FE02383E -:100F6C00DFF8F415B0FA80F0CA8A4109BDF8260002 -:100F7C00904208BF023100293FD09DF81E20002A64 -:100F8C0056D001F1400455E09DF84D00B8B3042053 -:100F9C0026F0CEF900283FF4B4AE01464FF4B270FF -:100FAC000880B8F828004880DFF8B00500781EF0FB -:100FBC00D5F8A6E611980178A1F10C0212F10C0FEC -:100FCC003FF62CAFE88ABDF8262082427FF496AE1D -:100FDC00BDF8280024F0AAFA90E6109A9DF83C007F -:100FEC0020F0DEFF30B101200026E3E690F8260069 -:100FFC000428F8D100260020DCE600241AE095F83D -:10100C006C0001287FF448AF11980078062803D1B2 -:10101C00049800287FF440AFF81DBDF82A1080B268 -:10102C0081423FF46EAE07A841461EF02BFB68E6EA -:10103C0001F1200422F07AFE0138B0FA80F0400968 -:10104C0044EA00069DF81E0000283FF4B2AE119849 -:10105C00007827F041FC012818BF04F07E06A8E6B2 -:10106C0098F8460028F0D6FA9DF82E00012840F09A -:10107C00B480B8F82800BDF82810814240F0AD804B -:10108C00BDF8260022F052FE022804BF00208DF885 -:10109C002E00A2E004F07F000446210702D44FF09A -:1010AC00000A34E0E1B24A0722D4C9069DF82110A7 -:1010BC0028D5C1F3820212B1072A18BF013A002ABF -:1010CC0008BF044601F0E30040EA820118E0D32097 -:1010DC0019F08DFADFF888040078002800F09F8062 -:1010EC00DFF8801451F82000C0EB0010810098E06C -:1010FC009DF8210000F0E00100F0E30040EAD1018E -:10110C008DF82110D8F804004FF4805A017295F82C -:10111C002600092801D0042823D1E98ABDF826002D -:10112C0088420AD022F002FE022806D09DF8210047 -:10113C0000F0030001287FF4E4AD9DF81E000028A8 -:10114C0047D011989DF838100078042808BF022960 -:10115C003AD0072848D1042946D107A817F0C2FF76 -:10116C00CFE5E7B214F0610F46D0F80709D0B8F814 -:10117C00281007A8A94615F0B5FC002864D004F087 -:10118C009F040025E7B2A00609D598F84600D8F8C8 -:10119C003C2028F03FFA07A815A905F06BFC78064F -:1011AC0040F12681B8F8281007A80DF152022B4601 -:1011BC0010F08AF800286FD00546119800780128A5 -:1011CC0008BF4AF0100A13E107A9002010F024FE12 -:1011DC0097E598F8460028F01DFAD8F83C2007A8A7 -:1011EC0015A905F047FC8CE503287FF48AAD07A808 -:1011FC0000210FF079FC84E59DF81E0001285AD1DE -:10120C0011980078032849D0052854D1B8F8281033 -:10121C0007A80DF15202002310F056F871E5D148E1 -:10122C000168D1480268BDF82800904701287FF476 -:10123C0068ADCE480168BDF828008847CC480168E5 -:10124C00BDF8280088475CE526F034FC9DF82E108C -:10125C000546BDF8280019B9B8F82810884291D075 -:10126C00B9F81610814204D1BA48807800283FF4AE -:10127C0089AFB8F8281007A82A460AF0B9F8002850 -:10128C0000F09B8038074AF0040ABDF8260048BFDE -:10129C00F01DADF8520075E70025A9E0BDF8260059 -:1012AC0027F0C6FA38B1B8F8281007A80DF1520289 -:1012BC00002310F009F89DF82E0088B323F0CAFE25 -:1012CC0000287FF41EAD9DF83900A0B3109A9DF84C -:1012DC003C009DF83D1020F063FE002870D09DF876 -:1012EC003D00002875D0109928F098FC9DF824300A -:1012FC00ADF8520011209DF823209DF821104AF0E2 -:10130C00400A002B08BF0920002A18BF083000290A -:10131C0018BF0130D8F804100A5C013A0A5462E094 -:10132C009DF81E0001287FF47EAE119800780328EA -:10133C003FF4E7AC77E69DF82010BDF826000029B5 -:10134C00ADF8520000F0D3804020BDF8261009F112 -:10135C001D0200EAC4059DF820002B4618F048FE3B -:10136C0038B1D8F804004AF0200A017801F03F01A6 -:10137C0001709DF8390048B1BDF8261009F1200024 -:10138C0021F02AFF4AF0400AADF852009DF81E00E9 -:10139C00012806D0BDF82810BDF82600002214F054 -:1013AC00ABFFBDF82810BDF826002A4612F0D2FB80 -:1013BC00002818BF4AF0200A15E004F0DF04E0E62C -:1013CC00BDF82610BDF828000B2200231AF033FDBF -:1013DC0097E4BDF82600ADF8520028F05CFC00281C -:1013EC0008BF4AF0400A26F065FB05464FF6F87632 -:1013FC00B01DBDF8521080B20F1A5E4818BF2F46B0 -:10140C000078012805D1F01DB8F8321080B2814265 -:10141C002FD160B2B0F1FF3F3FF773AC002F3FF418 -:10142C0070ACB8F8080028F069FD00283FF469ACEE -:10143C00B8F80820D8F80410054628F001F89DF8F3 -:10144C001E10002098F80830B8F8282016908DF857 -:10145C005410BDF8521015ACCDE9007ACDE9020458 -:10146C00284610F065FC70B3284628F045FDFFF7C0 -:10147C0048BCB8F828108142CBD0701CBDF826208F -:10148C0080B28242C5D2BDF828008142C1D028F07A -:10149C0002FC0028BDD0017901390129B9D8408856 -:1014AC0001218DF85410ADF8600015AD28461EF0E2 -:1014BC0059FD0028ADD0281D1DF048FD0028A8D0EE -:1014CC0021F0D4FFA5E72348407800283FF419AC5D -:1014DC0000208DF81870ADF81900DDF826004FEAE1 -:1014EC003040059005A827F037FEFFF70ABC3907F6 -:1014FC003FF52AAF9DF81E1001293FF425AF0021BE -:10150C0018F036FD20B1407901380228FFF41CAFE9 -:10151C00B8F84410BDF8520022F088F930B1807848 -:10152C0026F0F8FC01380728FFF40EAFBDF82800B0 -:10153C0027F07EF918B104208DF8200004E7BDF8DF -:10154C002610BDF8280002223FE700BFE527002047 -:10155C0024260020E8250020A86D00209C7A00207D -:10156C00D727002090B40200942300209C23002055 -:10157C0098230020E32700202DE9F0438DB0054689 -:10158C0080780224252800F27380DFE810F0260012 -:10159C00A400C400D700EA00F8000601B602B602A7 -:1015AC001D012E01B602B602B602B602B602460103 -:1015BC004B01B602B602540158016101B602B602E3 -:1015CC00B602B602B602B602B602B602B6026B019B -:1015DC006E017101740178017F01DFF8D47500246C -:1015EC000E258DF804403878012807D801A81DF085 -:1015FC0073F904469DF8040005EB4005EEB2304645 -:10160C0028F07CFC002800F087824FF0000805468B -:10161C00431C0021082280F80080012027F0A6FD41 -:10162C0028F01AF96872000A0721A872DFF88405FD -:10163C00E972007828733878012800F262829DF8EC -:10164C000420002A6A7300F05E8205F10E0000216E -:10165C002346914280F0578213F8022B013100F897 -:10166C00022B13F8012C00F8012C9DF80420F0E754 -:10167C00A0F140010D291FD8DFE811F00E00100178 -:10168C003F023F021E012E013F023F023A0145017B -:10169C00500165013F02740101ACE91C0822201DB8 -:1016AC0027F0CEFE204619F0EDFFBDF806004021D4 -:1016BC00ADF828000AABEEE0632800F069816428DD -:1016CC0000F07681E02840F0188200244720E021C9 -:1016DC00002200230FE2202028F010FC002800F04C -:1016EC00C1812021FF22044628F0BCFA631C012092 -:1016FC000021082227F03AFD0546002818BF0125D5 -:10170C0001AB84200021042227F030FD002800F0DA -:10171C000582023506E2E81C28F0ECFBADF804006B -:10172C00832028F001FB014601AA832028F0C6F98A -:10173C008DF828000AAB6720022190E1E81C0421F7 -:10174C0025F016F80190842028F0EEFA014601AA43 -:10175C00842028F0B3F98DF828000AAB6720032108 -:10176C007DE1612028F0E0FA0146EA1C612028F0B6 -:10177C00A5F98DF8040001AB672004216FE162200C -:10178C0028F0D2FA0146EA1C622028F097F98DF86D -:10179C00040001AB6720052161E100208DF80400F5 -:1017AC00E81C28F0A7FB6A7900F4F851002A00F035 -:1017BC004981B1F5A06F04D04FF6FF71884240F01B -:1017CC004B814FF0FF3045E128F06AFB044628F0CE -:1017DC0065FBD949604301ACB0FBF1F1204628F020 -:1017EC00F6FA672009210422ABE0DFF8B4632D7907 -:1017FC00306840B901AC204627F0F0FE01202146AC -:10180C000EF03AFB3060052D00F06981002D00F0E0 -:10181C006981642122F01AFA66E115F8032B67201E -:10182C0010216EE0E87823F011FF8DF8040001AB75 -:10183C006720112113E100246720142102E0002409 -:10184C0067201521ADF80840019401AB062252E146 -:10185C0000246720162109228DF80C40CDE90144A3 -:10186C0001AB48E1F52020210BE0F520212108E017 -:10187C00F520222105E04FF6F570232108E0F52034 -:10188C0024218DF8040001AB6720E8E0F520252128 -:10189C00ADF8040001AB67200222E1E0E81C28F05F -:1018AC0029FBADF8060001AC204617F0D7FB231D31 -:1018BC00672041210822D3E0E81C0AA926F02CFF5E -:1018CC0000288DF8040000F0CF8001A81821FF2219 -:1018DC00013028F0C7F9F4E0E81C0AA926F01CFF37 -:1018EC0000288DF8040000F0F1804FF0FF30EFE09D -:1018FC0015F8030F697822F071F9288067204821C8 -:10190C0002222B46ACE0E87825F080F801AC0146C9 -:10191C00204618F06DFD6720492111E0EC1C204693 -:10192C0026F0C6FB002818BF2046B5F80B1019F09E -:10193C0039FA01AC0146204618F05AFD67204A21BD -:10194C00242223468CE001ACE91C0822204627F017 -:10195C0077FD204627F04CFB8DF828000AAB67205A -:10196C004B217CE04FF0FF3095F80380691D01900E -:10197C00ADF81000CDE90200FE208DF806002879A4 -:10198C0003288DF8300020D10AA828F062FA21E053 -:10199C000024E91C08228DF8284001AD284627F0C8 -:1019AC004FFD28461DF0D2FA0AAB67206321A1E057 -:1019BC00B5F80B006A7B0024E91C8DF804400AF092 -:1019CC0085F901AB6720642194E0084628F092FA6F -:1019DC00ADF82800AF7B002F00F0DD807E0095F87D -:1019EC000D90304628F08AFA002800F0D48005F1DA -:1019FC000F013246044627F023FD00940AA9404605 -:101A0C004A463B460DF07EFA002800F0BA808378F7 -:101A1C0001784278057946798DF806308DF80410F6 -:101A2C008DF80520C3788DF809608DF808508DF875 -:101A3C00073001A98B1D811D40794200184627F003 -:101A4C00FFFCA5E0B1F5A06F03D04FF6FF71884203 -:101A5C0002D100205549086001AB67200621012204 -:101A6C0020F08CFE002448E0182028F047FA40B300 -:101A7C00BDF828100446009006200022182324F0FC -:101A8C00C7FDB8B9BDF8285001AE21461022701C14 -:101A9C0027F0D6FC444F05EB450506F1110057F82D -:101AAC00251028F094F907EB8500416806F1150024 -:101ABC0028F08DF92046182128F02AF9204628F024 -:101ACC001BFA01AB672044211922C9E7BDF8280095 -:101ADC00ADF8050001AB672045210322C0E7314971 -:101AEC0001220A7021F049FA002467200A218DF89E -:101AFC00044001AB012220F041FE20460DB0BDE8B0 -:101B0C00F08385F80D806720002132462B4620F0AB -:101B1C0035FE284628F0F0F97CBBA3E7019800BA03 -:101B2C00C4F809000AAB83200021022227F01EFB17 -:101B3C0020B1043506E000BF40420F00BDF828007C -:101B4C00A4F80D0004F10F0361200021012227F0FD -:101B5C000DFB002804F1100318BF0835622000218A -:101B6C00102227F003FB0028234618BF10356720EE -:101B7C0001212022257020F001FE204628F0BCF91E -:101B8C0070E74FF6FF70ADF808006FF480300190ED -:101B9C00204628F0B1F901AB67204D210E225FE7FA -:101BAC00287A0020A227002030750020087A002017 -:101BBC0024260020D02600202DE9F04F85B0847813 -:101BCC000226362C00F2BF820546DFE814F06B01CA -:101BDC00730172007B017800BC02BC0281003700EB -:101BEC004C008C009F00AD00BC02B5008F01BC0204 -:101BFC00BC029901AC01BA01BC02BC02BC02BC0221 -:101C0C00BC02BC02BC0237004C00BC02BC02BC02D1 -:101C1C00BC02BC02BC02BC02BC02BC02BC02BC02C8 -:101C2C00BC02BC02BC02BC02BC02BC02BC02BD00B9 -:101C3C00EB00CA01FF005B005B00DA0128F0AFF893 -:101C4C00242840F0A98102AB352000210422002475 -:101C5C0027F08CFA002800F0FB81012002228DF87D -:101C6C0010000020FBE100208DF8100028F097F800 -:101C7C000646092C40F0EC8095F8059095F8068006 -:101C8C000720EEE0DFF82465306880B1406A70B15F -:101C9C0002A928F08DF80546342C40F02A822846FB -:101CAC0028F028F9002800F02382042042E20320C7 -:101CBC0040E2DFF80835612002210A2240E202AC42 -:101CCC00E220214624F018FB61200421082287E140 -:101CDC0028F065F80446681D28F00CF9242C40F017 -:101CEC0086810020F9E1E878032800F29681281D0E -:101CFC0028F000F90246E878DFF8B81431F8101033 -:101D0C00DFF8B404007828F05FF887E1E87803285E -:101D1C0000F28881DFF89C1431F81010DFF8980479 -:101D2C0000781DF059FE7EE127F06EFFADF808003B -:101D3C0002AB61200C2102E1002661200E21012260 -:101D4C008DF8086002AB1CE2DFF8606401208DF8AE -:101D5C0010003068002800F02B810069002800F08A -:101D6C00278102A928F024F8042124F001FD002881 -:101D7C0000F0ED81044628F0C1F8002800F01B812A -:101D8C002146054627F0C4FF3068BDF80C102246EA -:101D9C002B4606690298B0478DF81000284628F0AB -:101DAC00ABF808E1DFF804442068002800F0078154 -:101DBC008069002800F0038102A927F0F9FF206850 -:101DCC00BDF80C10826902989047F9E0DFF8DC73DB -:101DDC003868002800F0FA80C069002800F0F6800E -:101DEC0002A927F0E5FF9DF80850BDF80AB0BDF830 -:101DFC000C90044628F07EF8A6788046F72E28BF73 -:101E0C00F726B01C5FFA80FA504628F077F80028C5 -:101E1C0000F09F81012D044608BFBBF1000F00F0BC -:101E2C009C813868A11C42463346C56902980091D2 -:101E3C004946A8470746002840F0958100276120B5 -:101E4C003321524623466670277020F097FC8AE1B6 -:101E5C00681D28F04FF88146E81D28F04BF88046A5 -:101E6C00092002AF242E18BF2F1809EB080508BF54 -:101E7C003526304627F058FF854201D9022059E11A -:101E8C00B9F1000F04D1304641463A4623F098F997 -:101E9C00304641463A4627F011FE002800F0E58016 -:101EAC000A2047E1E878012802D0002840F04A8156 -:101EBC0027F02EFB40F259600121ADF8080002AB6F -:101ECC0061203CE00120EC1C8DF80800E22021464A -:101EDC0020F054F930B901200821224627F0EEFDFC -:101EEC008DF8080002AB6120032128E1E878291D58 -:101EFC00012800F0E080002840F0E480E020DEE0E3 -:101F0C0027F04DFF0446681D27F0F4FF242C0FBF6B -:101F1C0000200146204627F0AFFE8DF8080002ABEA -:101F2C00612012210BE127F03AFF24280CBF00207E -:101F3C0027F0FAFEADF8080002AB61201321022253 -:101F4C00FEE0E8788DF8080099488068D0F83024D5 -:101F5C0002A9E02090478DF8100004AB61201421F9 -:101F6C00EDE0924C206898B3806A88B302A927F000 -:101F7C001FFF2068BDF80C10826A0298904701463A -:101F8C0027E08A4C206868B3C06858B327F007FF75 -:101F9C002168C968884726E083466938002680B2E4 -:101FAC00032838BF0126681D082C40D1057841E074 -:101FBC0003208DF8100004AB61203021BFE003201A -:101FCC008DF8100004AB61203121B8E00327CFE07D -:101FDC00002102AC204627F0FAFE612032210422B7 -:101FEC002346ADE0032027F0ECFD3621A7E005F1F8 -:101FFC000806ED790146A8426BD92046002227F04D -:10200C0057FD09288DF8080069D1002D67D02046AE -:10201C002946324627F052FD61E0022027F0D1FD1F -:10202C000A218CE0022027F0CCFD0B2187E027F061 -:10203C0061FF0546584627F077FE0227A84288BF65 -:10204C007700CFB100268DF808706120214694E00E -:10205C0002988DF810400422ADF8120002208DF881 -:10206C00110004AB612008216AE0012E64D1E2204A -:10207C00394620F083F85DE0401B87B2F72F28BF6C -:10208C00F727B81C5FFA80F8404627F037FF002886 -:10209C0061D000F1020A81463946504627F038FEDD -:1020AC00584629463A46534627F060F8054600281C -:1020BC006AD00A2773E00878022814D2522020F044 -:1020CC005DF800E002208DF8080002AB61200F21C2 -:1020DC0035E02046324627F0EBFC8DF8080002ABC9 -:1020EC00612007212BE002A9522024F005F9ECE72E -:1020FC0002359DF8080015F8018B012811D1BDF8A7 -:10210C000A0070B9BDF80C7041462A46384623F0D7 -:10211C0057F8012F07D1E220294620F02FF801278C -:10212C0001E0BDF80C703068394642462B46466AD1 -:10213C000298B0478DF8100004AB612021460122B3 -:10214C0020F01CFB0026304605B0BDE8F08F0520C2 -:10215C002FE710270CE0102774E7A9F1690003287A -:10216C00BFF45FAE0227204627F0C6FE002FE9D051 -:10217C0000268DF80870612033218DF8096002ABC0 -:10218C00022220F0FBFADEE789F8017000276120BB -:10219C00214642464B4689F8007020F0EFFA48463B -:1021AC0027F0AAFE002D7FF44DAFCBE76827002067 -:1021BC000C01002054BA02009A7A0020F0B90200F7 -:1021CC002DE9F04F9DB00446DFF89C05406818B12E -:1021DC008047002800F05682DFF890A5DFF890B514 -:1021EC000D940DF138099AF80000411E002C0B914A -:1021FC000BF1180418BF01219BF802800027002561 -:10220C008BF80F109BF801100C91C0B287421ED2B4 -:10221C00B84517D0FEB200214A460423304627F0B9 -:10222C00D7F80E9810F4403F40F00400C0B218BF2D -:10223C0001357C2806D130460621F82226F03CF8E0 -:10224C00F82020709AF800000C340137DDE7E9B271 -:10225C0001380024884204D19BF80500002800F0C6 -:10226C007F82DDF83490CDF82880DFF8FC84B9F15A -:10227C00000F484608BF1020059015AD00200190B6 -:10228C00DDE90B740026380400F0FE819BF80F008A -:10229C0010B901208BF80F00E0B200210EAA042324 -:1022AC0027F096F80E98B9F1000F19D010F4403FB2 -:1022BC0019D04FF400509AF800100136013FABF8DA -:1022CC0010009BF80F0001388BF80F00012050FA1A -:1022DC0084F0B0FBF1F202FB11048BF80D40D2E755 -:1022EC000021049102E0CDE90B740496C0B20A9E61 -:1022FC004FF0000A702804D00C987021C0B222F064 -:10230C001BFB5FFA86F900210EAA0423484627F02E -:10231C005FF89DF83800FE2803D04846FE2122F0D5 -:10232C000BFB48460621FE2225F0C6FF4FF4005059 -:10233C000C9F0BF11601ABF814A000228BF80C606B -:10234C00ABF81000FF2088F800208BF80E00F8B2D4 -:10235C008BF80D70400050FA87F001EB8000B0F85C -:10236C0006A04FEA490050FA86F09BF80F6001EB8B -:10237C008002FE20ABF812A0114601F8020F32F8D1 -:10238C00060F03910890DFF8E4030292047814A876 -:10239C0021F090FD56FA87F0CDF82490013890FB8F -:1023AC00F4F101FB140000905FFA87FB0C97CB450E -:1023BC0000F06281ABEB0900B0FA80F040090790A5 -:1023CC00002006900020DDF83490C00740F09E807D -:1023DC001FFA8AF4162C6ED998F80000002840F0E9 -:1023EC007381AAF1070758460FAAB9B218F0C0F8C2 -:1023FC00BDF84A6006F11000A0423BD89DF846009B -:10240C00962837D1A7EB06099DF8452031465B4647 -:10241C001FFA89F840461BF043FE58BB9DF8470055 -:10242C00C10701D1800704D40020CA46DFF83883E5 -:10243C00C9E7F01D83B2089813FA80F4B4F5005F75 -:10244C0001D90120F2E780B2CC4918440A1A584647 -:10245C00414626F0BDFF06980130B4F5005F0690AA -:10246C0004D101204FF400510891DEE70020CA4648 -:10247C000894DBE7AAF1010ADFF8EC825446A0B21B -:10248C00172836D33628A4F1160658462A4688BF94 -:10249C002026A41BB3B2A1B226F09AFF3004EED0D2 -:1024AC0015FA86F010F8010C962801D0013EF5E7DC -:1024BC0006EB040A86E7069810B1AD4927F0DBF865 -:1024CC000098C0B2834500F0DB800C990120DDF848 -:1024DC00249050FA81F0A5490978B0FBF1F202FB87 -:1024EC001107A34907EB470001EB8000B0F81CA0D3 -:1024FC005AE7A0481499006842689F48904700200A -:10250C0007900C980A90DDF8349008E0069810B10A -:10251C00974927F0B0F8002007900C980A9098F88B -:10252C000000002840F0D08008981021C0F500521F -:10253C00103883B20998C1F2001221F0D7FC98F838 -:10254C0000100843149988F800008A480068426813 -:10255C008948904707980A9A88B1844800780BEB11 -:10256C000001013991FBF0F202FB10128049D0B24C -:10257C00400050FA82F001EB8000B0F81CA0DFF8AC -:10258C00F0B108990298099C01238BF80E20018068 -:10259C00ABF81010BBF912209BF80D102046ABF8CD -:1025AC0014A023F05FFDBBF914209BF80E102046FD -:1025BC00022323F057FDBBF81000049CB9F1000F67 -:1025CC00C0F5005007D00599DFF8A0A18842A4BF40 -:1025DC000121019101E0DFF894A1059988424FF0A7 -:1025EC007C01B8BF7821099E304622F0A5F90DF088 -:1025FC00E3FE07469BF80F000621FC22C01B8BF85C -:10260C000F00304625F058FE0399FC209BF80E3045 -:10261C0008709BF8021017FA84F00C9301449AF896 -:10262C000000B1FBF0F202FB10118BF802100A91C2 -:10263C000131CAB2B2FBF0F202FB10118BF801109F -:10264C0003EB43010BEB8101898B102906D10C990B -:10265C000131B1FBF0F202FB10100C900B98C01B77 -:10266C00B9F1000F0B903FF40BAE019880F0010014 -:10267C00C0077FF405AE07E00120CB46079042E788 -:10268C0000984BE700246BE07C2022F06FF90446A5 -:10269C00FF284ED17E2022F069F90446FF2848D14C -:1026AC009BF8014004EB44000BEB8000807DFF287D -:1026BC003BD09AF800009BF802100144013991FBC1 -:1026CC00F0F202FB101434E02A48149900684268B6 -:1026DC0029489047264E254F00253878854213D23D -:1026EC00ECB2204615F0CEF898F80010084388F8A4 -:1026FC0000003DB138780138854203D020467E2158 -:10270C0022F01AF90135E8E7B18B01380024B070DA -:10271C00C0B2F4707470F180FE2122F00DF900202B -:10272C007C2122F009F974711AE020467E2122F0F6 -:10273C0003F9E0B2FE218BF80340400050FA84F01C -:10274C000BEB8000808BABF806009BF8020022F0AC -:10275C00F3F800208BF80500BBF81000C0F500540E -:10276C0020B21DB0BDE8F08FA02300209B7A002082 -:10277C00B8720020D8010010004003400020001166 -:10278C002DE9F04F8FB00C4648070FD4200441D4EC -:10279C00E00400F19781200600F1C081A00700F150 -:1027AC00D481200500F1F3810020B4E1DFF820058D -:1027BC000178062900F2AD81DFE811F007009401E1 -:1027CC00AB01AB019901AB01A001DFF81055DFF8AB -:1027DC0004152A7891F82B30022A02D19E0600F1BA -:1027EC0098815E0700F19D819B0740F19281042343 -:1027FC00037091F82C30DB0700F08B8191F82E30B0 -:10280C00002B00F0528225F09EFC0420012101F0E7 -:10281C00EFFF57E2DFF8C8040394DFF8BCB4DFF82D -:10282C00B094DFF8C474DFF8AC44DFF8B054DFF8D0 -:10283C00BCA448F20208008802909BF800001CF02F -:10284C0031F9002800F03A8106460078D3282DD1C2 -:10285C00F089404540F019813878002800F0158146 -:10286C0099F80000012840F0108126F031FD002875 -:10287C0040F00B817088002840F00781A24604AC20 -:10288C001221204627F044FA27F016F8304621464C -:10289C0018F096F9BDF81C00B0F5285FC0F08880E0 -:1028AC00012002211FF016F854462AE099F8001076 -:1028BC00884217D1012834D0032840F0E6802878CC -:1028CC000138012800F2E180B078012851D00028AD -:1028DC0040F0DB807078002800F0BF8000201DF0F5 -:1028EC0059FCD2E00A2811D194F82B00BA46B71C37 -:1028FC003071A16909B138468847384625F0AAF8E5 -:10290C005746DFF8D853DFF8E4A3BEE02978002956 -:10291C0040F0BB80092840F0B880A168B01C884703 -:10292C00B3E028780138012800F2AF80707860B1EC -:10293C0094F8330094F83410013084F83300C0B2AA -:10294C00884202D9012000219DE099F8010003285A -:10295C0058D0022871D0012840F097803878002890 -:10296C0000F08C8026F0B4FC002800F0928001204E -:10297C0085E07078002875D026F06EFF4FF6FE715A -:10298C00884203D1BAF81600884207D0AAF816106C -:10299C00ADF8281053200AA91FF0F0FB1EF00EFB17 -:1029AC0025F0B8F800208AF826001DF03BF96CE001 -:1029BC00CF48006809A90AAA16F0C4FE0746029877 -:1029CC005446C64DDFF824A3874212D29DF8380036 -:1029DC0010B1FD208DF838000420394614220AABC2 -:1029EC0023F02CFEC34907EB470001EB80000121CB -:1029FC0041720020012184F83200012001F0F8FE20 -:102A0C00B94F42E0A2460AACAB20002122461CF092 -:102A1C0071FA042004945446DFF8D0A2AF4D8DF81F -:102A2C00140004A80FF054FB26F046FF9BF800009E -:102A3C004FF4805141F288321DE0012020714FF497 -:102A4C008060ADF828000AA818F0E2FD26F034FFEB -:102A5C00A4484FF4805102680BE010F0F9F860695B -:102A6C0098B9A2E702204FF4805140F6B83289F8A9 -:102A7C0002009BF8000027F0A7F906E0002084F87C -:102A8C0032000120012101F0B3FE304625F02EFB6F -:102A9C00D3E694F8350020B1E0690028F5D08047E2 -:102AAC00F3E70020002102220023ADF828000220C9 -:102ABC008DF830000AA825F0D1FCB5E7039880F416 -:102ACC00004028E0854800780138012859D8804812 -:102ADC00017803294DD0012953D1417800201EF0F3 -:102AEC00F9FE4EE0012001211EF0F4FE11E025F06C -:102AFC002AFB0420012101F07BFE0AE00021322296 -:102B0C000170744880F82A1073480421007827F06B -:102B1C005BF984F004000FB0BDE8F08F84F0800006 -:102B2C00F9E70522027091F82C2092072CD591F828 -:102B3C002E204ABB052202600120487000201CF0A8 -:102B4C0097F8022024F05CFDE3E764480078013834 -:102B5C0001280BD80020CDE90A000AA812F024F8AD -:102B6C0020B15D48022100781BF0CAFA84F0020003 -:102B7C00D1E78178022904D10121817000201EF057 -:102B8C0085FE84F48050C6E705200021B3E7534846 -:102B9C000078002840F08680DFF838A1DAF80C5075 -:102BAC00002D79D004A80DF1280B01300BF104068F -:102BBC000390002D6DD0A87A18B10138A8720006C8 -:102BCC0046D19AF83180B8F1000F11D00020A91C21 -:102BDC0008228DF82800304626F032FC584618F0B2 -:102BEC0051FD28B12A88BDF82A00314623F02CFB70 -:102BFC00AF1C0DF127015A46384616F0A3FD81464D -:102C0C00384609A923F099F8B8F1000F05D09DF8C2 -:102C1C00380040F0020002281CD1DAF80800A0B1FC -:102C2C0003983946082226F00BFC022000220C23C4 -:102C3C008DF81000BDF82400ADF81A002648007875 -:102C4C0004A90091092120F0D6F928461EF014F8A9 -:102C5C00ED68AEE7384623F0CAFD9DF82700012841 -:102C6C00DBD15846142127F053F8224A09EB4900CE -:102C7C0000215B4642F8201002EB800014224160D8 -:102C8C004172FF2049468DF83800042023F0D6FC11 -:102C9C00C3E7DAF80C0028B90F484FF4006100784C -:102CAC001CF09AFE84F4006035E7013A012A09D839 -:102CBC00032202600120487001201BF0D9FF012083 -:102CCC0024F09EFC287800287FF423AF04205CE7D6 -:102CDC000C7A0020AC220020A37A002024260020AD -:102CEC00C0BA020070270020BA270020A86D00206F -:102CFC00EC580020F03300202DE9F04F89B021F082 -:102D0C0079FBDFF810158122DFF81485DFF814A5A4 -:102D1C00DFF82045DFF814E50A70DFF8FC140860D2 -:102D2C00DFF8F804FF2101700020DFF80415A8F883 -:102D3C0000008AF80000DFF8F0040968007891F8C8 -:102D4C0008B04FF6FE718EF8000059448AB2A168A3 -:102D5C00D1F80031DB899A4200F267810422DFF856 -:102D6C00DC54A8F80020DFF8D02412689668330EE3 -:102D7C00CEF80C60C6F301592B706FF0FF0303EA19 -:102D8C001627B3B2D1F8B86047EA1327AEF804702F -:102D9C0036781EB9B9F1020F00F04781B9F1030F73 -:102DAC0000F043811B0A03F0070316B1002B00F05F -:102DBC003C81DFF88CC4042B9CF800C008BFBCF12C -:102DCC00000F00F032813EB1DFF878643678862E41 -:102DDC0002D1022B40F02981BB0416D4BBB203F004 -:102DEC000703022B08BFBCF1000F20D0DFF85414EE -:102DFC000978862909D10020764621F04FFBDFF8AF -:102E0C004004B64690F800C0307800284ED0BCF193 -:102E1C00000F4BD1012800F0088103283FD0022875 -:102E2C0044D1BEF80400400740F0FF803EE0D1F8EA -:102E3C00D40090F88300022800F0808027460520FB -:102E4C00147BF246A946A8F8000026F0CFFC0546F4 -:102E5C00DFF8F003007886286DD1B868016C09683A -:102E6C0011B9D0F84C05804760B20021002623F040 -:102E7C0012FDB9680A6C12685077086C0068867786 -:102E8C00086C0068C477284626F06BFFBAF804106B -:102E9C0099F8000001F010011CF018FF4EE0BEF88C -:102EAC00040000F00700032840F0BF80BEF80400C7 -:102EBC00010700F1BA80810402D4810500F1B580CC -:102ECC009EF80E20C2F38107012F00F0AE80960908 -:102EDC00012E00F0AA80B9F1010F11D840F00201C7 -:102EEC0001F0070103290BD117B93F2A40F29D804D -:102EFC0037B9A168D1F8AC100978002900F0958099 -:102F0C004FF6FB71B9F1020F0BEB010C19D1CF4B42 -:102F1C00D95D9B5D03EB01090023402AB7FA87F2C8 -:102F2C0038BF012352091A40430616D4002A08BFA1 -:102F3C0009F1020915E0284626F013FF25F06EFB77 -:102F4C0075E0C14B402AD95D9B5D03EB010908D3A9 -:102F5C00420648BFA9F1020903E0002A18BF4FF04E -:102F6C000209C0F300205FFA89F11FFA8CF30A1AE8 -:102F7C008EF801009A4258DC60440391B346401A23 -:102F8C00A168AEF806007430D1F8501280B28847B0 -:102F9C00A6490028886048D07421CDE9019726F015 -:102FAC00B7FEA24F0020B870A548007820B9387938 -:102FBC0000F020008AF8000078789AF80010DFF80A -:102FCC0078C24FF000092E4600299A493DD00028BE -:102FDC004FF000003AD1B88800F00700032807D062 -:102FEC00012832D18868D0F8D40090F8820060B300 -:102FFC00C8684069007818B125F06EFFFE280DD026 -:10300C008C488068D0F84C02804738B98948806871 -:10301C00D0F844028047002800F0F780834F01204D -:10302C00B870DFF814C22E4610E025F0B1FD26F082 -:10303C00DDFB814900240A6813681C7112680A6060 -:10304C0026F08FFE09B0BDE8F08F0020BC6804F1BB -:10305C00740184F830B06160A1657978BB88FA8816 -:10306C000029A381029B228184F83A30337808BF6F -:10307C009946B8F8003097F80EB0019DA4F85C2082 -:10308C00FF2284F84990A2735E1A797BCBF3011965 -:10309C00A8F8006001F0780160F3820101EB0900EF -:1030AC002074280600F0AE80DCF8000004AF039A10 -:1030BC0010FA86F000F10801384626F045FF56FA62 -:1030CC0085F0CBF38105A8F80000207C00F04008C7 -:1030DC00CDB3B9F1020F06D1B8F1000F03D0B4F89B -:1030EC00440004AF06E0BDF810000237A4F8440019 -:1030FC00A4F84200564EF189884203D04FF6FF7176 -:10310C0088425ED1032D11D104F13200394626F0EC -:10311C00A0FE464CF11CA068323024F018FC454946 -:10312C0000284ED094F80EB008370EE037F8020B9A -:10313C00B1898842608606D04FF6FF713B4C8842BD -:10314C003C493ED101E03B49384CBBF1400F20D308 -:10315C00B9F1020F06D16DB9B8F1000F0AD133489D -:10316C00806803E0A068017C490603D439880237E3 -:10317C00A0F84210BBF1C00F06D32C4C3946A06806 -:10318C00283026F066FE03E0284C3888A1680885B4 -:10319C0028498968A088D1F8AC201278B2B1B9F16D -:1031AC00020F13D200F00700012802D003282FD100 -:1031BC001E4C6DB9264AA368D289B3F842309342AB -:1031CC0006D01FF01AFA19F011F930E700F00700D9 -:1031DC00032806D0012815D1D1F8D40090F882002C -:1031EC0080B1A068D1F848128847104A50B9002025 -:1031FC00D17B9070907BC1F3011100F078000844F2 -:10320C009168087408F0ECFB11E7084FB87808E7F0 -:10321C00064CDDE7B07A0020387A0020B57A002021 -:10322C00BE780020B37A0020B27A0020342500202A -:10323C00787A00200C010020D8790020C37A002075 -:10324C00C27A0020B87A002048BA020044BA0200C0 -:10325C00007900202DE9F04F97B0DFF80C8505467A -:10326C00DFF8086598F800000328307040F04981B9 -:10327C00002088F8000030700DAC204626F0F5FDDB -:10328C002046002125F0D8F9DFF8E494B0603A210B -:10329C00484626F03DFD4FF0FF30A9F81400C9F860 -:1032AC001000C9F80C0022F0F3FE002029461EF095 -:1032BC0065F806F11001F06026F065FDD6E905020F -:1032CC00DFF8B074B0FBF2F1C9B2032928BF0321B7 -:1032DC00B2F5005F89F80010397040F00F81B0EB47 -:1032EC00413FC0F00B81F068002800F007814FF4DB -:1032FC000050FF224FF000084FF0885BA9F8060041 -:10330C00FF2089F8032089F805800590002008909B -:10331C0000200B90002009900020079000200690C0 -:10332C0000200A9000200C90FF200290FF200490B7 -:10333C00FF200390CCB2A04580F0E6805FFA88F6BF -:10334C00002116AA0423304626F042F8DFF82C445C -:10335C003046002115AAA0473046012114AAA047E7 -:10336C003046022113AAA04716996FF06F0050FA4D -:10337C0081F2C8B20E2A06D8012303FA02F245F2F2 -:10338C0001131A4203D1A0F1FE02022A04D242F226 -:10339C008352B2EB914F1ED0304614F073FADFF823 -:1033AC00CC130028087040F0CF803046002116AABC -:1033BC00042326F00DF8DFF8C4433046002115AA8B -:1033CC00A0473046012114AAA0473046022113AA77 -:1033DC00A0471699C8B208EB48023D46CA4609EB0D -:1033EC008204C1F30142090AE1759DF8561004F1FB -:1033FC001609FD28627689F80000217601D9102182 -:10340C0036E0BDF854104FF6FF72914230D10EA841 -:10341C0020F050FD304600214FF088524FF40053FD -:10342C004FF4005725F0D4FF6FF0030313FA87F71E -:10343C00B8B250F80B104A1C01D10328F6D801225F -:10344C000126D3B2042B06D8CBB2FF2B18BF1646DD -:10345C000132090AF5E740F80B10C9480E990068CB -:10346C004268C848904757FA86F081B299F8000034 -:10347C00A1839DF852107028A176BDF85010E183FD -:10348C009DF84E10E176BDF84C10218411D07828AF -:10349C00D14614D07C282F4616D07E281AD0FE2870 -:1034AC001FD0FF2823D10898CDF80C80013008904C -:1034BC0020E00A98D1462F4601300A901AE006986F -:1034CC002F460130069015E00798CDF8108001309A -:1034DC0007900FE00998013009901FFA88F00290CC -:1034EC0008E00B98CDF8148001300B9002E00C989A -:1034FC0001300C90397808F101081BE7012088F89D -:10350C00000017B0BDE8F08F0C98984E00060BD158 -:10351C000B98C0B2012807D80A98C0B2012803D86A -:10352C000998C0B2012811D99348042200240270D2 -:10353C00CAB2E0B2904210D214F0A4F9317801343E -:10354C00084339783070F3E7884E1BE0089BD8B2FB -:10355C00A04219D1884800220270002089F803008B -:10356C0089F80100481E7E2189F80200B9F81C0078 -:10357C00A9F80600002021F0DFF999F80200FE21DD -:10358C0021F0DAF93078BCE70A98000624D00B98C1 -:10359C00059A000603D1039A180600F08480764839 -:1035AC0002210127D5B289F80220017017FA82F0A6 -:1035BC00B0FBF4F101FB140089F80100284614F06B -:1035CC0061F930702846FE2121F0B6F989F80570B2 -:1035DC000020FEF7F5FDD5E70B98059A000621D0E3 -:1035EC006548012189F80220017011FA82F0049AD1 -:1035FC00B0FBF4F101FB140091B2FF2989F8010032 -:10360C001FD10299FF2919BF89F8031001EB410062 -:10361C0089F8030000EB400009EB8000808BA9F8CF -:10362C000600AFE7DDE90620104300063FF47CAF4F -:10363C0022F002FDA04280F085804F4803210170EA -:10364C003EE0480089F8032010FA82F009EB800074 -:10365C00818B1829A9F8061094D30739D0B20EAA79 -:10366C0089B216F085FF9DF843004007B0D5B9F834 -:10367C000610BDF84620002399F80300009303239D -:10368C00891A0EAA073989B206F0B0FF00287FF418 -:10369C0079AFBDF8441000293FF474AF9DF8480091 -:1036AC001DF0D6F86EE722F0C7FC0621A042324886 -:1036BC0038BF03210329017002D0062952D061E7DB -:1036CC0022F0BAFC054689F80C0000EB400009EB2F -:1036DC008000408BA9F80D000CF06EFE3978284460 -:1036EC00B0FBF1F202FB110089F802000130C2B20A -:1036FC00B2FBF1F202FB110089F801007C2021F0F1 -:10370C0035F9FF2812D17E2021F030F9FF280DD198 -:10371C00FF2021F02BF9FF2808D1782021F026F981 -:10372C00014699F80100FF2918BF0846C1B289F873 -:10373C000300490051FA80F009EB8000808BA9F856 -:10374C0006001AE70898000609D099F80200FE2135 -:10375C003C46374621F0F0F82478039A40E70648B7 -:10376C0006210170FEE700BF98270020A02300204F -:10377C00B87200209B7A0020A77A0020F7950200EF -:10378C00D8010010004003402DE9F84305460C46D3 -:10379C00480413D4A00024D4A0075CD460057ED4C4 -:1037AC00200500F10681200700F13B81600040F10B -:1037BC00F6801AF009F824F08044F0E026F016F8B0 -:1037CC00DFF81C140F6D3FB1D7E90A1202F0E0428A -:1037DC0001F00A01891849D026F0C3FA24F4804478 -:1037EC00DDE0BB48DFF8FC73016841F0800101604B -:1037FC00B878012804D1042021F020F90020B870F9 -:10380C0025F0F4FF0646042026F098F8DFF8D813CC -:10381C000A68904219D12A7EBAB1FA68AAB1DFF8C7 -:10382C00C003806C002800F09780C16840F603024A -:10383C000988914206D0C06840F60401008888428D -:10384C0040F08A8005F1140088E040F6C41208604C -:10385C00C5E9042284E009F0ABFBDFF88403006CBB -:10386C00002840F09D8024F0020498E0D7E90A6516 -:10387C00D7E90A12AA43B143C7E90A1226F071FA32 -:10388C00B8680028AAD056EA0500A7D0D7F808C017 -:10389C003869B7F9301032462B46E0479EE725F0E1 -:1038AC00A5FF054623F0E6FD002800F0B780CC48C4 -:1038BC00876B002F00F0B280DFF828830420CB49FF -:1038CC00002288F81800C64825F0FCF926F076FA94 -:1038DC00C74826F040FAC7480068006B8047C8F814 -:1038EC0010000125042088F8025021F0DFFE386911 -:1038FC0090F82810C8F80400490703D5436A04213E -:10390C000022984701201BF055FCD8F8040045769E -:10391C0013F096F8D8F8040081680B461A465B68D9 -:10392C004BB11E88A6F60306072EF7D805FA06F645 -:10393C0016F0830FF2D0537B03F0F0030133537373 -:10394C000023FD6853602D88A5F60305012D00F2B8 -:10395C008A80C8F810309FE005F110001EF0FEFAC6 -:10396C00304626F0FEF921F0B9FE78B12E6A2846D1 -:10397C006FF4807100224FF00073B0479848806B51 -:10398C0010B119F021FF01E044F00204EE69284661 -:10399C00002100224FF08063B04724F0005434B172 -:1039AC00974821462830BDE8F84326F0BDBABDE85B -:1039BC00F8838C4EB078012804D1042021F03EF815 -:1039CC000020B07021F08AFE38B170686FF48071FD -:1039DC0000224FF00073056AA847306950B1854842 -:1039EC000068006B804732697168801A000BC860F0 -:1039FC00002030617A4D81490022284625F062F979 -:103A0C0002203076286C20B17D480221283026F027 -:103A1C008BFA19F0D9FE24F40064C0E726F0CEF935 -:103A2C0041E025F0E3FE054623F024FDA0B1DFF8CC -:103A3C00B48198F8000000070ED498F90000002813 -:103A4C000AD4684613F038FA08B1009820B1DFF8B0 -:103A5C00B49199F8610048B326F0B0F919F0B4FEAE -:103A6C0024F008049BE7034633F8385FA5B190F8BF -:103A7C00445090F8456005F0F00580F8445006F08D -:103A8C00F005013580F8455000255360C563458726 -:103A9C00507B00F0F000507357480022C261016067 -:103AAC00012024F027F924F4806478E7002601270C -:103ABC00602E0FD009EB0600817A31B18772407A03 -:103ACC0007FA00F0C0B220F0D3FF2036F0E700BFB9 -:103ADC00CC210840032088F81800454826F03BF913 -:103AEC0026F06CF9444F3E4D002278690020786135 -:103AFC00F968F8602846444925F0E4F83D48006828 -:103B0C00006B8047D8F80C10D8F82020411A02EB33 -:103B1C001130B0EB113F38BF4FF0FF3098F8241044 -:103B2C00C8F8200021B1D8F80810B0EBC12F20D96B -:103B3C0024F0F0F8B8B140F60900414621F83C0FEA -:103B4C00002048804A7B02F0F00201324A730A7B63 -:103B5C0002F0F0020A734860F8613960B8F83E0070 -:103B6C0010F4406FFAD00020C8F82000012088F82B -:103B7C0024001DF0BBFB2548002101600220002120 -:103B8C0024F0B8F8022020F059FF102012F008FBA6 -:103B9C0098F8010020B9D8F80400503026F0C0F98C -:103BAC001B48807810B90D2012F0FAFA98F825000D -:103BBC0028B1002088F82500052020F03FFF0020C8 -:103BCC0088F818001348C8F81C000220B5F85610E5 -:103BDC00B5F85420914208BF072018F077FF3DE755 -:103BEC0030210020D01E0020E02600205D74020051 -:103BFC00387100208C01001000100440F50C0100FD -:103C0C0070200020206E002039D8010000000460D4 -:103C1C009CB90200D50501002DE9F04F8DB08478D8 -:103C2C000226142C00F21F820546DFE814F029004E -:103C3C00150015004A0085001C021C021C021C0207 -:103C4C001C021C021C021C021C021C021C028E0008 -:103C5C009C00AF00BE00CC0001206A78022C8DF8CD -:103C6C003100089240F0C080E878291D03288DF8B7 -:103C7C002C0040F0E18009A8082225F0E1FBE0E0EF -:103C8C0010208DF82400102026F038F998B1044645 -:103C9C00DFF8E00321466060E81C10F017FC8DF89B -:103CAC00240028B9204623F087FC8DF8240010B19D -:103CBC00204626F021F9002609AB642000210122C0 -:103CCC00C2E10020CDF82A00ADF82E00CDF8260078 -:103CDC0002208DF82C00E81C26F00CF9ADF824001D -:103CEC006979A8798DF82D1025F03AFC8346E81DEA -:103CFC0026F000F995F80C908046687AAC7A95F825 -:103D0C000BA04FEA49078DF83100384626F0F6F83B -:103D1C00002800F01081CDE9074806464FF0000856 -:103D2C0005EB0800474570D00D3026F0E3F826F877 -:103D3C00080008F10208F3E7E87820F083FF8DF81B -:103D4C00240009AB6420042189E1E978032900F2FD -:103D5C005281281DDFE811F00400510155015D016D -:103D6C0018F056FF76E1E81C26F0C4F8C04C6668E3 -:103D7C00002E00F0E4806A79002A00F0E4803368B9 -:103D8C00A91D184425F05CFB0020D9E0B84EEC1CB2 -:103D9C0004212046376822F0EBFC002F4AD0B9688A -:103DAC00814200F0A0803F68F7E7A888ADF82400B6 -:103DBC00E87809A924F07CFB8DF832000DF1320370 -:103DCC00642013214BE10026E878ADF8246009A9A2 -:103DDC0023F08AFDBDF824000DF1320314210222D8 -:103DEC00ADF8320064202FE1E81C02218DF82C1074 -:103DFC0026F080F8ADF82400002005F10608ADF897 -:103E0C002E0068798DF82D0026E0BBF1000F00F034 -:103E1C00B580437B0DF131010E30CDE90496CDE92F -:103E2C00000107985946CDE9020A09A8089A1DF025 -:103E3C00DBFEA4E0012000E1084626F05BF8ADF8BB -:103E4C002400287B8DF82D0005F10D0026F052F88A -:103E5C00ADF82E0005F10F0898F8000025F080FB56 -:103E6C00054608F1010026F045F898F8036098F82B -:103E7C0004A098F805B08146022C8DF8326009D167 -:103E8C0008F1060026F036F8074608F1080007F19D -:103E9C000A0104E098F8067008F1070039464DB1A4 -:103EAC000A3189B2FB2907D3DFF8C481D8F80400A2 -:103EBC0000286ED0022009E00DF132018DE8030CD0 -:103ECC0009A84A463B46294603F012FD089E8DF888 -:103EDC00310006F0E000202840F0C4800DF13103E1 -:103EEC0064202146BBE0EC1D204626F003F86D7AD9 -:103EFC00002D00F0978005F102098246484625F016 -:103F0C00FDFF002800F098800026457080462A4668 -:103F1C000670786800EB0A0108F1020025F090FAAF -:103F2C005FFA89F26420122143461EF027FC4046BA -:103F3C0025F0E2FF97E010208DF8320024E01020ED -:103F4C008DF8240016E0D6F800C0F38AB28A3169E5 -:103F5C00757EB77E06F11800CDE900C0301DCDE9A5 -:103F6C00025703F0C5FC8DF82400606825F0C4FFEF -:103F7C000020606009AB6420112170E002208DF8F4 -:103F8C003200304625F0B8FF0DF1320364200321D6 -:103F9C0065E007F11C0025F0B1FF0028C8F804000B -:103FAC0055D000F11C010C22016000208DF831006D -:103FBC00D8F8040009A9043025F042FAD8F8040016 -:103FCC000F214FF47A7205612A4DC17680F81AB030 -:103FDC0080F819A00676C782A0F8149008212878DA -:103FEC0025F0F2FE089E00283FF473AF28780821D4 -:103FFC001AF086F86DE702202CE000781AF0B0F881 -:10400C0028E0007825F0ACFA18B324F0ABFF0020C0 -:10401C0020E025F06FFFA97925F0C0FCB0FA80F004 -:10402C00400917E03068B84201D138683060384632 -:10403C0025F062FF002000E0102000262070642094 -:10404C0012210222234666701EF098FB0BE0102012 -:10405C003CE701208DF8240009AB642010210122DB -:10406C001EF08CFB002630460DB0BDE8F08F00BF73 -:10407C00682600209A7A00202DE9F04F8FB00C466C -:10408C0008040CD4A00426D4DFF88853287802281E -:10409C002DD1E10740F00381A10641D558E0DFF8AE -:1040AC006C0300781AF0FEFC90B10178DFF8602305 -:1040BC0005460020602808D0135C08308B42F9D1EB -:1040CC00104450F8041C28468847284624F00EF863 -:1040DC0084F4004595E11DF08DFC28B10546FCF7F4 -:1040EC00C1FD284624F002F884F4005589E1A106AC -:1040FC002ED4012814D8E10600F11781610600F1D5 -:10410C002F81210600F13D81E10500F13F81210560 -:10411C0000F14181E10400F15481610400F15B8103 -:10412C00A10700F1E280A10500F1FA80210700F15E -:10413C001181610500F11981E0034FF0000540F198 -:10414C0060811BF037FFB648C57084F4803558E1A8 -:10415C00AE4F202138781FF02FF9DFF8C4824FF0D2 -:10416C000109D8F80810084317D025F099FE054628 -:10417C0025F094FE68434FF47A71B0FBF1F0D8F857 -:10418C000810401A4FEA500938BF6FF0004900255B -:10419C00002964D0B9F1000F61D000200421002265 -:1041AC0022F08CFE06464FF0060A4FF0FF0B4FF63E -:1041BC00FF7802AD002E4ED0304604210022374647 -:1041CC0022F07CFE06463889B0EB090038BF00208F -:1041DC0038810004EED1B87BD0B301280AD178899C -:1041EC00400707D4386887F80DA0B721407B1DF035 -:1041FC00B9FBDFE739682A468DF806B0ADF80480C4 -:10420C00086AC97F0CF0E4FF01281BD1B87BB97A8E -:10421C008DF838000907788A40F08002ADF8362016 -:10422C0006D540F4C070ADF83600387B8DF83A00F6 -:10423C00786910B1007BADF81800284601A900225E -:10424C0002F018FC387B87F80DA016F091F8B1E756 -:10425C0001207873AEE7DFF8C8816C4F4D4622F031 -:10426C007AFF00200121002222F028FE18B13878B4 -:10427C00202119F045FF002004210022002622F005 -:10428C001DFE002847D006890421002222F016FECC -:10429C00A0B1B1B20689B14238BF0E46F4E764480A -:1042AC0090F82C100F2906D190F82600022802D382 -:1042BC00002021F0CBF984F00105A2E0A8B2B1B244 -:1042CC00814223D9D6FA55F0202180B242003878A9 -:1042DC0025F07AFD25F0E4FD054625F0DFFD684369 -:1042EC004FF47A71B0FBF1F615E05248007808B340 -:1042FC0002AD284625F0D3FC25F09CFA4E490B78EC -:10430C004E490A7829461AF0D1FE20E0387820214F -:10431C0019F0F6FE0026C8F8086084F0200570E05D -:10432C0015F062FC84F400756BE008F04FFA84F031 -:10433C00100566E03E48418B012025F0D5FD28781C -:10434C00022804D13148012100781BF045FB84F090 -:10435C00020556E03248012184F00805817050E0D6 -:10436C000CF0B6F984F040054BE0022808BF15F0BC -:10437C00FFFE2F480121808C25F0A8FD84F4806578 -:10438C003FE024F0B5FA84F080053AE022F0B6FB69 -:10439C0084F4807535E01BF073FB2048007801280D -:1043AC000CD11D48007848B14FF47A7100FB01F232 -:1043BC0016484FF40061007825F003FD84F4006585 -:1043CC001FE01748017819B1002101701BF058FB50 -:1043DC0084F4805515E01448006880B111490978BF -:1043EC0001290CD180471148006800B1804707486B -:1043FC004FF480414FF47A72007825F0E2FC84F49B -:10440C00804528460FB0BDE8F08F00BF9C7A002095 -:10441C00BCB2020024260020CC270020CD2700208F -:10442C00E8250020CA2700208423002090230020A8 -:10443C00A86D0020A7270020D0270020D22700201D -:10444C002DE9FE4F8846080426D45FEAC87004BFE5 -:10445C000020BDE8FE8FE548056825F021FD0446E7 -:10446C0025F01CFD60434FF47A714FF6FF72B0FBE0 -:10447C00F1F14FF6FF70002D00F01A812B886C883B -:10448C00CB1A9BB29C4240F21C81E31A94B2A34219 -:10449C00B8BF1A46ED68EEE7DFF840A3CDF804800C -:1044AC009AF800001AF0FEFA002800F0FC8006468C -:1044BC000078012840F0EC80DAF8041096F833907C -:1044CC00D6F814B096F8138021B1484688470028D6 -:1044DC0040F0DE80718896F83100022222F05AFA00 -:1044EC000546002842D0287A297CA0F10108FF2932 -:1044FC0000F0BB80707F4F46C00718BF0027E97CD7 -:10450C00287D0144B94204D8E974FF2101FA00F076 -:10451C006874A969A87C96F83020896A10FB07108A -:10452C00F16A24F08DFF287D697CB7FBF0F202FB69 -:10453C00107001228240D2B20A436A74C8457CD101 -:10454C0096F83010AB7C13FB0713A9698B844FF4DE -:10455C00FF7303FA00F0C0B21043FF2868746CD1EB -:10456C00287C1AF0FBFDFF2028747FE0707FC007C9 -:10457C0000F08E80B07F24F0F3FF002800F08880DC -:10458C0004461C2025F0BAFC002800F081801C2178 -:10459C00054625F0BDFBB07F02A923F0A5F99DF8D7 -:1045AC00090002212875284623F0F4F9708896F842 -:1045BC00312096F8301096F83330A880287DEA71B7 -:1045CC00FF2202FA00F0687460680078A9742874FD -:1045DC00302013FB010080B222F0AAFE0028A86153 -:1045EC005DD004461A20B11C2060708CA080A01DE8 -:1045FC0023F06CFFF27F04F13000B17F96F8283085 -:10460C00C4F81CB084F81980A062307CE273744A40 -:10461C00217563750121A075928C2282F28EA28580 -:10462C00F28C6282B6F81100A4F817009AF8000018 -:10463C0085F8089019F064FD55E725F031FC044627 -:10464C0025F02CFC60434FF47A71B0FBF1F0654916 -:10465C0028806348097800794843642148436249BB -:10466C00097800FB0100688000E04F46E87C297D5A -:10467C006A7C01440139B94218BFFF2A0CD186F873 -:10468C003300708806F11C0186F8342016F085FF83 -:10469C00304623F02BFD03E7C845F9D1EFE7284658 -:1046AC0023F088F9F4E7019880F40040BDE8FE8F10 -:1046BC0092B282424BD049480121007825F084FB0C -:1046CC0045E0A879022806D1287CFF2837D0A869B4 -:1046DC0023F00CFD33E025F0E3FB044625F0DEFB74 -:1046EC0060434FF47A71B0FBF1F03F49288095F8A4 -:1046FC003800097888421BD295F83620FF2A06D15B -:10470C0095F83720013085F8380085F8362095F873 -:10471C00351095F8394082F0FF0300200126C7B20E -:10472C00A7421DD206FA07F71F4214D10130F6E753 -:10473C00EA8BA87E95F82A10E9231EF087FF2846FD -:10474C0023F038F925480121007819F0D9FC88F0BC -:10475C000100BDE8FE8FFBB201441A4385F83620F8 -:10476C00AB8F95F83440C8B204FB10339EB2A6420E -:10477C0003D2FF2285F8362002E0FF2A08D1234617 -:10478C00184A174E1278367972436426724302E047 -:10479C0095F83A2023466A802A8D0E0606D022F020 -:1047AC00200244432A852A6C224404E042F0200172 -:1047BC002A6C2985297A85F82E10E9796A6285F8A0 -:1047CC002D10D9B269840549496811B18847002870 -:1047DC00B8D105F1100004F011FBB3E74826002016 -:1047EC00A86D0020C0270020C62700206C53002095 -:1047FC007FB50138072800F24C810C46DFE810F039 -:10480C0008002C0054006E0089004901A600C90064 -:10481C00CB4800780138012800F23B81002C00F0D5 -:10482C0047810020032100241FF02CF9C64DC74EF0 -:10483C000420042132222870307825F0C5FA082093 -:10484C00002107F011F830786C704FF4805104B0EF -:10485C00BDE870401BF0C0B80020002524F088FE95 -:10486C00BB480121017004208DF80D0074B1B548CE -:10487C00B34C45852078012803D1072023F08AFA10 -:10488C002078022802D1062023F084FAAE480421B5 -:10489C0032220570AD48007825F096FAA94890F8B8 -:1048AC002B1001F0FE01F2E0A54800780138012838 -:1048BC0000F2EF80A54804213222007825F084FA1A -:1048CC00002C00F00F819F4C9F4801210170206942 -:1048DC00002800F0EC801FF0E5FCF8E70120002C2C -:1048EC008DF80D007BD0974800219B4A80F82A1048 -:1048FC00984824F0FFFF924C2078012803D1072020 -:10490C0023F048FA2078022870D1062023F042FACE -:10491C006CE002208DF80D008A48002C73D0002129 -:10492C008D4A80F82A108B4824F0E4FF00200321E4 -:10493C001FF0A8F8824C2078012803D1072023F01F -:10494C0029FA2078002877D1092073E07C4D0020CB -:10495C008DF80D00002C28787BD018B9092023F095 -:10496C0019FA2878022806D10820002106F07CFFCD -:10497C00042023F00FFA10F095FF73480021C82291 -:10498C00017070480D2180F82A10704825F0A3F9A9 -:10499C0078E005208DF80D0069480078022878D160 -:1049AC00002C00F0C38068480022C178C2700170EE -:1049BC0042F20800002106F057FF62480D2190F8E2 -:1049CC002B2080F82A10C17802F0DF02002980F831 -:1049DC002B200CBF04200D2023F0DCF959E05848A3 -:1049EC00007818B95748022180F82A10564800213F -:1049FC0032220170554825F06EF9524890F82B1070 -:104A0C0001F0FD0143E0082180F82A104C49097897 -:104A1C00012911D890F82E0070B900200DF10A016F -:104A2C008DF80A0052201DF0A9FB24F031FB1EF07A -:104A3C002DFC002023F0AEF94348002132220170F6 -:104A4C00424825F048F93F4890F82B1001F0FB0143 -:104A5C001DE03C4C022812D194F82E0078B194F849 -:104A6C002B00002140F0200084F82B0005208DF84D -:104A7C000D00082006F0F8FE0A2023F08BF9022026 -:104A8C0084F82A002F4890F82B1001F0EF0180F8E1 -:104A9C002B102C480022032390F82A008DF80C00D0 -:104AAC002A48007803A900910A211EF0A4FA7FBDC0 -:104ABC00244C0720254D4FF4805184F82A00012006 -:104ACC008DF80D0028781AF087FF0020002622F0C0 -:104ADC0069F92878022141F2883284F82B6025F09C -:104AEC0073F9D6E7174C022000218DF80B1084F8CF -:104AFC002A001548017094F82B000DF10B0100F001 -:104B0C00FD0084F82B0001208DF80D0052201DF0C3 -:104B1C0035FB24F0BDFA1EF0B9FB002023F03AF966 -:104B2C0020690028B5D01FF0BDFBF9E7054802212C -:104B3C0080F82A1090F82B1041F02001A7E700BF55 -:104B4C0024260020AC2200200C7A0020A37A00201E -:104B5C00BD270020A86D00209027002092B0DFF820 -:104B6C00EC92D9F8000010B1002180F845104830C3 -:104B7C0020F094FF24F03AFE8046072011F0AAF8AA -:104B8C0017F0DAFF10B1B24824F0D4FF1AF06AFB28 -:104B9C0001AD284624F0C4FC0427002029468DF8DA -:104BAC00047024F0C5FCAB4C206024F031F90AAD44 -:104BBC00284624F065FB002029468DF8287024F047 -:104BCC0067FBA54E306024F02DF906AD284624F085 -:104BDC0067FB002029468DF8187024F069FB3168BA -:104BEC009E4D286019B99E4824F0A4FF286810B97E -:104BFC009C4824F09FFF206810B99B4824F09AFF32 -:104C0C001CF0D8FDD9F800004FF0FF3438B1CDE9D5 -:104C1C00104410A9082223F05DFB01281BD1CDE91B -:104C2C001044082025F06AF9002846D005460026D5 -:104C3C00052E04D824F0E8FFA8530236F8E74FF607 -:104C4C00300029460822E880884824F0F9FB2846E1 -:104C5C0025F052F909E0D9F80010CDE910440029EB -:104C6C00DFD08248082224F0EBFB10AA0120082197 -:104C7C0024F01EFF092800D0D8B921F075FE80075A -:104C8C0012D4CDE91044CDE90E440EAB0120002125 -:104C9C00082224F06BFA60B90EA810A9082223F0A0 -:104CAC0019FB002800F0CB80704A0120082124F069 -:104CBC0005FF6E49E2201DF061FA12F0CBFB2820B3 -:104CCC0025F01CF96A4E0028306055D0694F6A4CAB -:104CDC0007F10C0524F0FBFF24F042FB3068056063 -:104CEC0007F1100524F0F3FF64498968D1F84C13DF -:104CFC0088473068456007F1140524F0E8FF1CF084 -:104D0C0083F93068856007F1180524F0E0FF19F08D -:104D1C00B5FD3068C56007F11C0524F0D8FF1FF005 -:104D2C0007FD3068056107F1200524F0D0FF1EF067 -:104D3C007FFB3068456107F1240524F0C8FF1DF0A6 -:104D4C0095F93068856107F1280524F0C0FF23F040 -:104D5C0053FE3068C56107F12C0524F0B8FF20F034 -:104D6C0025FE3068056207F1300524F0B0FF38707D -:104D7C0024F05CF93068456218F0B6FE40484149B1 -:104D8C004FF00009CDF8409001603F48032111908D -:104D9C0010A820F043FC24F0BBFC404624F0E1FFBB -:104DAC0017F0ECFA24F058FF01201DF0C7FE19F0A3 -:104DBC0031FF37480078022808D1344800780128A0 -:104DCC0004D14FF40040012106F04EFD294F4FF461 -:104DDC008041387824F0A6FD2E484FF0FF31006852 -:104DEC000DF022FCDFF8B08078684FF0FF310DF049 -:104DFC001BFC3068002550F82510096821B9691C86 -:104E0C00092D0D46F7D3EFE724F0F9FE316851F880 -:104E1C0025100C68C1F8009024F0DFFF58F825200D -:104E2C00002021469047044624F0E9FE316851F8F1 -:104E3C0025100A6822430A6024F0CFFFD4E70B4800 -:104E4C000EA9082224F0FCFA33E700BF68270020E3 -:104E5C00B4B60200F4790020F8790020FC79002027 -:104E6C0068B802007BB80200B2B80200B679002024 -:104E7C00707A002088210020E14902000C010020FA -:104E8C009C23002001CA0100008D1500E52700209D -:104E9C00242600204C7A0020A4B502002DE9F04F06 -:104EAC0089B08A4608040DD45FEACA7040F01F81AD -:104EBC005FEA8A7000F12D815FEA0A7000F135819A -:104ECC00002044E1A34F387819F0ECFDDFF88C9208 -:104EDC00A64DA14C06464FF0000B48F21508002ECB -:104EEC0000F00281307831283AD032284BD0D328C8 -:104EFC0040F0B480F089404574D0382840F0AE8042 -:104F0C00CDF820B0CDE906BB304606A920F0A6FCB2 -:104F1C009DF81C10052969D8307B002840F09E8034 -:104F2C009DF81D00002800F09980052800F296805D -:104F3C00069823F0E8FE002840F09080707C8849A9 -:104F4C00AC467870708808809DF81D0021460138A9 -:104F5C008DF81D0006A890E82C002CC165467DE05C -:104F6C00B87803287AD899F82E10284623F0CBFE6F -:104F7C00002873D1FF207C49607170880880B0884C -:104F8C00784908806AE06079FF2814D0002016F078 -:104F9C0051FA0246B9F8701078783346CDF800B063 -:104FAC0012F0A0FD6079002858D038780821322200 -:104FBC0024F00AFF52E099F81810706820FA01F2F8 -:104FCC00D2071ABF3144097A002100221B2A43D090 -:104FDC0020FA02F3DB0703D0B3181B7A99421ED8D0 -:104FEC000132F3E7304621F03DFE37E0FF293DD09A -:104FFC00FE2956D199F872109DF81E00884202D8ED -:10500C0060BBFF292AD11CF0BBFE069900201B288F -:10501C0059D021FA00F2D20757D10130F7E7B9F88D -:10502C006E004F49334608804E4802884E4801882E -:10503C0010200090002012F055FD0120F870B87877 -:10504C0040B93C2002214EF66022B880387824F01A -:10505C00BBFEB8780130B87084F805B0304623F048 -:10506C0045F8387819F01EFD064638E799F87210A5 -:10507C009DF81E00884203D80028EFD1FF29EDD1FE -:10508C001CF07EFE069838B1D9F82810814203D066 -:10509C00C9F8280022F08EFEBDF8200023F0DCFCBD -:1050AC00DCE7307B0028D9D170882D498022002381 -:1050BC000880707CCDE900BBCDE902BBCDE904BB17 -:1050CC0011F01CFBCAE71B2000E0C0B299F81810C5 -:1050DC008142C3D02649087099F80700642100FB6F -:1050EC0001F23878012163E78AF400402FE020496F -:1050FC001A4C08782076E1201DF040F822F05AFE78 -:10510C000020A4F87000012016F094F98AF0010038 -:10511C001DE010488188B1B101394EF660228180C2 -:10512C000078022124F050FE0FE00B4C607938B16E -:10513C002179206823F0E7FD10B96079013860719E -:10514C008AF0080003E0002181708AF0020009B0A7 -:10515C00BDE8F08FCC24002058790020A86D0020E9 -:10516C009279002076760020F272002000F8FF077A -:10517C009F7A00202DE9F04F85B08846080418D49A -:10518C00AA480078012802D85FEAC87156D15FEAB4 -:10519C0088714DD4022807D1A5480078012803D185 -:1051AC005FEA487000F18A805FEA087059D40020E9 -:1051BC002DE1DFF860A29AF8000019F073FC0028CA -:1051CC0000F023810546807FD0B9688C132817D155 -:1051DC00DFF844926E880021D9F81C000F1D0029BD -:1051EC0008BF09F11C0758B101884468B14204D1C9 -:1051FC003C6024F081FE2046F5E701462046EDE7B1 -:10520C00A87A05F1020B022840F0E580DFF808923D -:10521C0095F83170BBF8006009F11C000068A0B172 -:10522C000188B14202D18178B94243D00430F5E70C -:10523C0079480121017088F00200E8E07648406965 -:10524C0000B1804788F00100E1E0D9F81C0000288B -:10525C0058D0012204464068114601320028F9D189 -:10526C0052E07048DFF8B091807BD9F81C600007E1 -:10527C0060D424F015FE044624F010FE6A4A604304 -:10528C004FF47A71B0FBF1F0D9F818101288411A6A -:10529C0091427AD3B1FBF2FB0BFB02F2511A084498 -:1052AC005E49C9F818001FFA8BF00978884288BF4C -:1052BC008B4641E059490978C170A3E05E495D48CD -:1052CC0000224FF6FE7300240978023079B130F8D1 -:1052DC00025C9D4208D04588013D45802D0406BFE7 -:1052EC00027020F8023C012401390630EEE734B19B -:1052FC00484804214FF4FA72007824F065FD88F0D8 -:10530C00040084E000240021454889B200888142D1 -:10531C0061D2082024F0F2FD00285CD00021068028 -:10532C00877041603D490978C170D9F81C1079B378 -:10533C0060603FE04FF0010B00205FFA8BF44FF000 -:10534C00000A071D002808BF09F11C0796B1F07868 -:10535C00C0FA5BF1A042F17006D8756830463D602A -:10536C0024F0CAFD2E46F1E7716830460AF1010AB5 -:10537C000E46E6E75FEA0A4007D100200821C9F88B -:10538C001800244800781AF027FB88F008003EE04B -:10539C00C9F81C002348807B00070BD424F080FD47 -:1053AC00044624F07BFD60434FF47A71B0FBF1F0BE -:1053BC00C9F818001B48807B00070CD59AF8000030 -:1053CC0008211DF0F9FF30B91748082102889AF816 -:1053DC00000024F0F6FC2878022810D0012811D106 -:1053EC00297EAA89EB7C05F11C006C696E7E8DE828 -:1053FC005A0005F11003594605F08EFA02E02846D2 -:10540C0015F01CFC284622F071FE88F4004005B013 -:10541C00BDE8F08F997A00202C240020C5270020AD -:10542C008A270020A86D00208E270020242600202B -:10543C00E5270020B45F0020A12700202DE9FE4FB6 -:10544C00074608680024B0B1D7E9018A0E4624F05B -:10545C00CDF98146D8F8E800082888BF0124B06847 -:10546C00204202D17068204208D003203074484694 -:10547C0024F077FC00242046BDE8FE8FD8F8C0103D -:10548C0069B198F8F8100029EFD006213174D8F8DA -:10549C00C410C8F8C4604E6198F8FC100DE00021EF -:1054AC000522C8E93066C8E93411C8E9361198F804 -:1054BC00FC10002908BF01223274002201297261FC -:1054CC0009D102204FF4E02188F8FC0098F8FB0089 -:1054DC001FF0B4FF706889490138884205D8042050 -:1054EC0020F0E4F8062020F0E1F8022020F0DEF8AD -:1054FC0098F8F80040B9DAF83C003168814203D2E0 -:10550C0098F8FC0000286CD0D8E9361009B118B90D -:10551C0000E028B324F0E3FBDAF80000416941F025 -:10552C0001014161484624F01CFC98F8F80008B1D0 -:10553C000124A0E708F16C05D8F8EC10284624F0FB -:10554C0077FB0028F4D0D8F8C0000321017438464A -:10555C0012F0B2FF28460021002424F069FB8AE7F0 -:10556C009AF8040024F0A8FC654CDAF8101002221A -:10557C00206991FAA1F1B1FA81F14368D8F8CC0015 -:10558C004068006898472069DAF8141002224368D2 -:10559C00D8F8CC0091FAA1F1B1FA81F14068006819 -:1055AC0098479AF8040022F045FA9AF8040024F07F -:1055BC0085FC24F094FB0020C8F8E000D8F8C0006B -:1055CC000068B0F5806F01D924F089FB98F8FE00D3 -:1055DC000028A1D1DAF80000416841F002014160D5 -:1055EC009AE798F8F90020B1D8F8EC0001307FF474 -:1055FC008BAF484624F0B5FBB2683AB1D8F8E80056 -:10560C000221092838BF0121009103E008F1F402BE -:10561C0000200090746834B1D8F8E80002270928FB -:10562C0038BF012702E008F1F6040027DAF8000081 -:10563C00334D416841F002014160D6F800B0D946C3 -:10564C00BBF1000F40D0D8F8E800019209284FF0C8 -:10565C00010011D22A68B9F1000F1FD0C0071DD06C -:10566C002178DAF800009268904700281EBF3C446D -:10567C00A9F101090120EDE72A68B9F1000F16D054 -:10568C00C00714D02188DAF80000926890470028EF -:10569C001EBF3C44A9F101090120EDE7DAF8000036 -:1056AC00D26802A99047DDE90120107007E0DAF812 -:1056BC000000D26802A99047DDE901201080009813 -:1056CC00ABF1010B0244BBE7D8F8F000DAF800109C -:1056DC00CA680240102802D1002AF9D101E0002A40 -:1056EC00F6D0706822F040F8D8F8C0100020C8F846 -:1056FC00C400C8F8C00008741AE700BFFEFFFF0F13 -:10570C00C40100102DE9F04F87B0851C8346284654 -:10571C0024F01EFB01AC06461821204624F0F8FAB2 -:10572C009BF801A004F10B002946009524F091FB95 -:10573C006FF001009BF80A1002240122ADF818004A -:10574C0000208DF81A408DF80C0001F00800C1F310 -:10575C00C007890782EAD00507D40028B946A846B5 -:10576C0008BF01240027002507E004244FF000099E -:10577C004FF00008002808BF03248548007850EA41 -:10578C000A000BD0834890F82600082809D123F092 -:10579C009FFD00285AD0BAF1010F57D14FF0C30921 -:1057AC0001E04FF0C2090025BAF1000F10D07F487C -:1057BC00007890B9BAF1010F0FD1002E63D0002000 -:1057CC00214601228DF81A0001A814F0D1FA0AE042 -:1057DC0001A81BF0DFF986B91CE001A8214652464E -:1057EC0014F0C6FAB6B17179BAF1020F41F0400269 -:1057FC00727104BF41F0600171719BF80A10490687 -:10580C0003D5717941F080017171B17900240131B6 -:10581C00B17100E00124B0FA80F149090D423AD18E -:10582C0007D1002D18BF814641F20100494621F0F5 -:10583C00B0F814B9009819F089FBBDF818004FF6B0 -:10584C00FE71884218BF24F063FB24E0DEB332798A -:10585C00A24218BFBAF1020F20D1D01EC0B201284B -:10586C0002D857EA050006D1501EC0B2012822D832 -:10587C0059EA08011FD0308821F0F8FA20BB308893 -:10588C00ADF8180022E00220214601228DF81A0002 -:10589C0001A814F06DFA07B0BDE8F08F4FF00009C5 -:1058AC00009953468DF81A903088ADF8180024F002 -:1058BC000FFB012578E7012802D8308824F028FB5B -:1058CC00009819F043FB0026BDF818004FF6FE7146 -:1058DC0088421ED121F086F810B1BDF8180011E0F5 -:1058EC00BAF1000F04D02C4D288821F0BFFA30B14A -:1058FC009BF80A0000F002001FF008FF00E0288867 -:10590C00ADF818004FF6FE71884202D14FF0C7096E -:10591C0049E79BF80A200099534624F0D9FA10B1B4 -:10592C004FF001093FE71D48016811B1BDF818009F -:10593C008847BDF818000099224606F0C7F90646BC -:10594C00174818490A6800784FF4803124F03CFA63 -:10595C0001211548C17096B1AAF10100C0B201280D -:10596C0007D81020BAF1020F08BF0820717908433C -:10597C0070714FF0000901258DF81A9014E74FF65D -:10598C00FE7000254FF001090026ADF818000BE75A -:10599C0004250020A86D00208027002098230020DB -:1059AC009C7A0020ACBA0200E825002024260020B6 -:1059BC002DE9F04F8DB0044600209A4616460F464E -:1059CC00CDE90B00CDE909008A488568804615F0C1 -:1059DC0061FA1C2803D015F05DFA1B281BD1308806 -:1059EC0040F60201884218BFB0F5C15F03D1F07BCD -:1059FC00022810D93EE043F6070188420BD196F8F5 -:105A0C002400032807D330697B4940F0806020F0E4 -:105A1C00604088422ED100206FB366B3387825FAE7 -:105A2C0000F0C00726D03046002124F061FA7348FC -:105A3C00C4E90176006880B109A800900CA90BAAF2 -:105A4C000AAB304609F0D6FE0B980B214FF6FF72CD -:105A5C00502322F08FF8FF280CD023F0C7FE684F9C -:105A6C0006467878012802D840B1012070E0304613 -:105A7C0024F077F900200DB0BDE8F08F09F02EFE70 -:105A8C0060480DF10409016841F0020101605E48B3 -:105A9C00C8F80000484623F033FDDFF870B15D49CB -:105AAC004A469BF801009BF8005003905848283058 -:105ABC001EF0D3FD584859494A461EF0CEFD4846C3 -:105ACC0023F02EFCDFF85881564A19214B460295DB -:105ADC0040461DF045FB544A08F11C001A214B4668 -:105AEC001DF03EFB5148524924F009F951485249E6 -:105AFC0024F005F95148006810F4402F06D0504AA4 -:105B0C0007F128000421002321F07EFC9BF8020001 -:105B1C0010B10D2010F0DEF808F1400023F0DDF894 -:105B2C0008F1380023F0D9F84649002007223876CE -:105B3C00B8843862386181F860200521C7E9021009 -:105B4C004149F96138700420002122F0D3F87878AB -:105B5C002F4941F8204001307870304624F001F98B -:105B6C00BAF1000F02D0DAF8000008E00DF1040AD7 -:105B7C0036492022504624F0E7F94FF0FF30DAF88E -:105B8C000420BAF81010DAE90635002AB2FA82F6C7 -:105B9C0008BF40F6C412206001207609618325639A -:105BAC0060762B4826764FF4FA766261C4E903627C -:105BBC00C4E90700C4E90903DAF80C0000B120625B -:105BCC00DAF8140000B16062DAF8080000B1E061A4 -:105BDC0004F13800C82124F09BF804F15000002196 -:105BEC0022F0C8F81B4904F1B80024F088F82046CC -:105BFC0041E700BFCC2108400F00000580260020A3 -:105C0C00D01E002000200940110000E09CB90200C9 -:105C1C00702000206D83020040720020714C010046 -:105C2C003021002039D8010049B901007C710020D5 -:105C3C00397402003871002019830200B44F0050EF -:105C4C00B1000200206E0020D505010094B60200C0 -:105C5C00236E0100059E02002DE9F04F87B0002451 -:105C6C000293002A00F03A81074603A892460E469A -:105C7C004FF0200B10300190504610F8011B2529D5 -:105C8C000CD0002900F02781022EC0F0D680013EF6 -:105C9C00002F00F0D18007F8011BCEE09AF801002C -:105CAC002D2806D19AF802000AF103034FF0010CDB -:105CBC0003E00AF102034FF0000C30280CBF13F87C -:105CCC00011B01462A2920D1029D2A68111D296039 -:105CDC00D2F8009013F8011BB9F1FF3FDCBFC9F1FA -:105CEC0000094FF0010C2E291ED11A4612F8011B87 -:105CFC002A291CD1029D2A68111D29609D1C12683D -:105D0C0059782B4622EAE27821E04FF00009A1F104 -:105D1C003002092AE7D809EB890201EB4201A1F113 -:105D2C00300913F8011BF2E74FF0FF380FE04FF08A -:105D3C000008A1F13003092B08D808EB880301EB0C -:105D4C004301A1F1300812F8011BF2E71346302889 -:105D5C004FF0000241F0200008BF4A466C2808BFF3 -:105D6C0013F8011B9A46692901D0642909D1029BB9 -:105D7C001868011D196090456FF00903C8BF4246B1 -:105D8C001BE075290AD0A1F16F00092858D8DFE86B -:105D9C0000F005695F5F835F5F5F5F05029D2868A8 -:105DAC00031D2B6090454FF00803C8BF424678296D -:105DBC0008BF1023752908BF0A23DDF80480016889 -:105DCC004046654616F062FCAC460546A8EB000161 -:105DDC00A9EB0100BCF1000F0DD109E0022E05D397 -:105DEC00013E17B107F801BB00E000270138013470 -:105DFC000128F3DA01380A465AB1022E06D3013EC5 -:105E0C001FB12B7807F8013B00E00027013A013560 -:105E1C00F2E70C44BCF1000F3FF42EAF0128FFF663 -:105E2C002BAF022E05D3013E17B107F801BB00E0E2 -:105E3C00002701380134F1E70027013482461BE7C3 -:105E4C00632905D1029A1068011D1160006804E0F5 -:105E5C00AAF10100022E3AD300788DF80C00012132 -:105E6C0003ADB5E7029ADDF804801023CDF800C02D -:105E7C001068011D11601099082200290168404624 -:105E8C0016F004FC05464FF04000DDF800C005F8A4 -:105E9C00010DA8EB05019BE7029ACDF800C0106834 -:105EAC00011D1160109905680E480029002D08BFCE -:105EBC000546284623F048FC8045014638BF41463C -:105ECC0018F1010208BF0146DDF800C080E700218F -:105EDC0003AD82467CE70FB100203870204607B036 -:105EEC00BDE8F08F7CBA02002DE9F04F8DB006466C -:105EFC00806A447874B18D4909788C4280F01281A3 -:105F0C008B49023022462AB130F8023B013A21F883 -:105F1C00023BF8E78748C18A708988422FD18348B1 -:105F2C000078A04240F2FE80B589814A214628467D -:105F3C0022F078FA284617F017F8064682480778B8 -:105F4C00BE4204D14FF6FE7017F00EF80646BE4264 -:105F5C0080F0E880DFF8F48108EBC6094F4657F86B -:105F6C00040F08B123F0C8FF002C00F0B1806000D2 -:105F7C0023F0C4FF0028386040F0AC80D2E0B27C43 -:105F8C00002A00F0CF806A4F0025AC4205D037F8CC -:105F9C0015208A4203D00135F7E7A04600E0A84659 -:105FAC00002113F0E5FF002800F0AD808146407918 -:105FBC00012840F0A88099F8060010F0180F00F0A6 -:105FCC00A280B9F80210204622F01AFBA54202D397 -:105FDC00002800F098805848CDE90498B6F80C9049 -:105FEC004FF6FE7A00780890544800780A9000200A -:105FFC0006960B9052481130099052480430079085 -:10600C0000200C90DDE909564FF0000BF6B135F885 -:10601C00117C574518BF4F4502D1013E1C35F5E7A1 -:10602C002046394622F0ECFA0028F6D128780138BF -:10603C000528F2D80C980BF1010BC007EDD00B988A -:10604C005FFA8BF1C0B28142E7D356E0DDE90786F7 -:10605C002EB338F8047C574518BF4F4503D1013E89 -:10606C0008F12408F4E72046394622F0C9FA002842 -:10607C00F5D198F8050001380528F0D898F80000FB -:10608C0001380228EBD30C980BF1010BC007E6D0BA -:10609C000B985FFA8BF1C0B28142E0D32DE05FEA3E -:1060AC000B6028D00B98000625D101205FFA8BF5E8 -:1060BC000B90012D4FF001000C90A3D023F0A4FD08 -:1060CC00C0B2B0FBF5F101FB15000B90012098E775 -:1060DC00002038601E4989F80140A9F8025009785F -:1060EC0008F83610F4B1E8B1114962000DB0BDE802 -:1060FC00F04F23F0A5B94FF6FE770498069EDDF815 -:10610C00148047800A4FB37CF47CB269B1890125B5 -:10611C00581EB07470895FFA88F68DE8D00003952C -:10612C0010F032FD0DB0BDE8F08F00BFD8BA020000 -:10613C0008780020A86D0020E3BA0200D1BA020052 -:10614C003056002020450020D7BA0200503D0020D8 -:10615C00DE2700202DE9F04F87B005462C200E4697 -:10616C0023F0CCFE002844D0778B044623F074FB3C -:10617C000021E1840121874208BF02212170707B3C -:10618C00A0703169081A6060204618F0B9FC3178AB -:10619C00834F01F00301387B012908BF0520607093 -:1061AC00C0B223F09DF94FF0FF316077A182217FBF -:1061BC00326908440A44317D3261081A3075E07046 -:1061CC00A069013017D0207C032816D8DFE800F036 -:1061DC0002170209062021466082284617F064F94E -:1061EC0010B3042021466082284607F027FD05469F -:1061FC001BE01025CFE0A32517E0A12515E000201A -:10620C00B3256082F87A80B997F8410001280CD147 -:10621C00A07D4FF6FF7619F06DFF0025A082B042ED -:10622C0008BF6FF05E0500E000252078022807D13A -:10623C0004F1080622F05AFE0146304623F009FE0E -:10624C00280640F0A580574F3878013801281AD815 -:10625C0094F8260010B994F82700A0B1A078E17842 -:10626C00227F08441044043023F048FE58B1A17832 -:10627C00E2780646207F114408446168021D3046CE -:10628C0023F0DEF800E0002620460EF00BFB05465E -:10629C003878012802D12DB9002575E0022873D178 -:1062AC00002D71D0002E73D00DF1080800274FF08F -:1062BC00010B4FF4D00908F1080A94F8260018B91C -:1062CC0094F8270000285FD0A178E278207F114451 -:1062DC0008443146021D606823F0B2F894F8260099 -:1062EC0020B184F82670C4F8129007E094F82700C7 -:1062FC0020B12D4884F82770C4F8120020460EF007 -:10630C00D1FA10B10021054639E04046142123F0A2 -:10631C00FFFC608A8DF819B0F0B9A08A40F2031125 -:10632C00884216D0682817D16068C17B052929D10D -:10633C002A30FF21082222F0F1FC18B34FF0FF3075 -:10634C006946CDE900001948006823F082FDFC2065 -:10635C0000E0FF208DF81800504669460022002509 -:10636C0013F0F0F901469DF8000038B10420142216 -:10637C00434620F063F90321002500E003210329A3 -:10638C009BD101E00221FAE716B1304623F0B4FDAF -:10639C00204623F0B1FDE8B207B0BDE8F08F00BF96 -:1063AC00A86D00202426002000000301EC580020DA -:1063BC002DE9FC470446019007788A48C65D8A4857 -:1063CC00F840ADF80260C00740F00A810D2F13D1E0 -:1063DC00864D0DF10201A868D0F82824532090476F -:1063EC00BDF802104FF6FD70814214D8208990B18F -:1063FC004FF0000A25469CE00C2F0ED0072F13D02F -:10640C00052F0ED1A078012800F0EA80207C3044C2 -:10641C0000F1240916E0A868BBE06068C08AC005DA -:10642C000AD44FF0000A09E0A07848B1A07D00EB37 -:10643C00C00006EB800905E04FF0010AB14605E00B -:10644C0006F11B09ADF802904FF0000A484620F007 -:10645C006FFF00B30546072F3CD120782870607879 -:10646C006870A078A8700028E178E970D4F805105D -:10647C0069604FD0A07D0028287241D0A169002905 -:10648C003ED000EBC00005F110068200304622F031 -:10649C00D7FFEE6037E00C2F40F0A280254655F870 -:1064AC00040F002800F09C8023F0A0F980464F4890 -:1064BC008068D0F8541328468847484620F038FFA7 -:1064CC000546404623F04DFC002D00F0898023F05A -:1064DC0055FB2EE023F052FB052F2AD105F11806AF -:1064EC0069682422304622F0ABFF69692A7C05F1E9 -:1064FC003C006E6022F0A4FF68682430686118E0EC -:10650C0000202872E860A06998B123F0F5FC002007 -:10651C00A0750DE01B2005F110061B2228723046D9 -:10652C00A16922F08DFFEE60A06923F0E5FC00204C -:10653C00A0612F48016819B128468847002844D12A -:10654C000D2F2BD1606801788A0720D4294AC1F31A -:10655C008301927C91421AD140783F2817D894F845 -:10656C003000022813D195F8470005F146011DF0C3 -:10657C0045FE01984FF6FF72418E91421DD1406845 -:10658C008079022819D3284619F01EFC40B317480D -:10659C008068D0F8541301A8884721E00C2F0CD147 -:1065AC0060781A2809D0686838B1C08AC00704D04E -:1065BC00287C05F10F011DF021FEBAF1000F04D16A -:1065CC000D482946007818F0C9FD0C2F08D1019808 -:1065DC0050F8041F21B105498968D1F85413DBE741 -:1065EC00BDE8FC878EB8020019C206000C01002021 -:1065FC0064270020A86D00209C7A002014F074F809 -:10660C008848DFF824B2DFF824A2DFF82482894D11 -:10661C00894E0027006818F013F8DBF800004FF0E3 -:10662C00FF310CF001F823F0EAFA9AF802109AF80C -:10663C000420D8F800409AF806308AF802708AF8DC -:10664C0004708AF80670002918BF44F00404002A6C -:10665C0018BF44F08004002B18BF44F00204C8F8A3 -:10666C00004023F0BAFBD8F80000010644BF20F02C -:10667C008000C8F80000287818F014FA002848D0D8 -:10668C00DAF80C10044651B19AF80100012804D034 -:10669C00022804D1204688473BE020468847204604 -:1066AC0016F09CFEA8B304460C20B1462F4623F0EE -:1066BC0025FC80B1064623F0A2FA05462078B4608A -:1066CC0098B1304623F018FC606821F00FFD20468D -:1066DC0023F012FC16E0606821F008FD204623F040 -:1066EC000BFC3D464E46002713E0D9F8000031461E -:1066FC0023F00EFAD8F8000040F01000C8F80000A3 -:10670C0023F0E1FA28463C464E46002723F065FB71 -:10671C002546D8F80000C10631D5306823F0F2F9CF -:10672C00F0B923F0B1F8D8B9A94623F068FA0446B9 -:10673C00306823F0E1F978B10546806841884068FB -:10674C0017F04EFCA868406821F0D0FCA86823F034 -:10675C00D3FB284623F0D0FB204623F03EFB4D46CE -:10676C00306823F0CFF930B1D8F8000020F01000D9 -:10677C00C8F8000003E023F0A6FAD8F8000081075F -:10678C000FD508F001FE21F005FA20B123F09BFA99 -:10679C00D8F8000005E0D8F8000020F00200C8F896 -:1067AC000000010725D5706823F0A6F990B1DAF83E -:1067BC000810044641B19AF8000028B1022826D0EE -:1067CC00012804D1A0688847A0681AF0B3FD2046C0 -:1067DC0023F092FB706823F095F930B1D8F80000E3 -:1067EC0020F00800C8F8000003E023F06CFAD8F899 -:1067FC00000041077FF511AF20F00400C8F800003D -:10680C00306823F07FF900287FF407AF02E0A0681E -:10681C008847DCE7D8F8000040F01000C8F800000A -:10682C005846F7E64C7A0020507A00204425002088 -:10683C00547A0020BD7A0020302600202DE9F04F3C -:10684C0093B004461EF006FC08B1112006E1207F2F -:10685C004FF6FE75B8B183480078810041EA4010CC -:10686C0061882077FF2020F089FA002180B1E08A2E -:10687C0005F1010B012640F00400E082207F40F07E -:10688C000100207707E0002000264FF6FE7B08E091 -:10689C0000264FF6FE7B74480078022838BF012191 -:1068AC0088010490678838461DF040FA08B1002032 -:1068BC00607694F81AA0BAF1000F04D16B4890F8E6 -:1068CC0000A084F81AA094F90000C5B2B0F1FF3F03 -:1068DC0007DDE07E40B966480178E1760131017050 -:1068EC0002E005F003052570207EDFF88491012875 -:1068FC0005D199F80B0010B90DB900202076DFF8FE -:10690C00688198F80000012831D899F80E008007AA -:10691C002DD5E6B1E08A410606D5BAF1010F03D1B7 -:10692C0020F00400E08222E0A188E07E627DADF8D8 -:10693C0022708DF82AA0ADF824108DF82B0006A833 -:10694C0004F056FD00283FF480AF25780FE0384660 -:10695C001DF0ECF958B1002DDCD0206900780A2824 -:10696C0005D8012101FA00F010F4836FD2D14FF653 -:10697C00FE7A012D07D120690078022803D1E08A24 -:10698C0040F04000E082EEBBE08A10F0400039D1CC -:10699C0098F80000012835D899F80E00800731D5F9 -:1069AC00049DA71D6188607E3A462B4613F020FBA0 -:1069BC0028B100206076E08A40F02000E082387830 -:1069CC0070B1618804F108001CF006FC83466088F5 -:1069DC00834504BF00203870E08A40F04000E0821C -:1069EC002078012804D0A18860882A460FF084FC06 -:1069FC00A18860882A460DF0ADF818B1E08A40F005 -:106A0C002000E0820DF11701204605F07DFB0646C3 -:106A1C001FFA8BF0504508BFB4F802B0EEB12078E5 -:106A2C00617D94F82C50B9F816209DF81730079416 -:106A3C008DF81800608DADF81A00E08A06ACCDE92F -:106A4C000254CDE900101FFA8BF130460BF070F9AF -:106A5C00102803D1304623F04FFA102013B0BDE8B4 -:106A6C00F08F00BFC327002024260020CBBA0200E1 -:106A7C00A86D00202DE9F04F99B012AF8A4604465C -:106A8C001C219346384623F043F9204639460CF036 -:106A9C009BFA9DF855009DF85C10084307D09DF8B3 -:106AAC00480041060CD560891DF040F930B140F228 -:106ABC00351013F09CFD19B0BDE8F08F9DF848001F -:106ACC0000F00C0510F0200FC0F3401918BF042D76 -:106ADC0021D1E08D9DF8483010F080010CD15A0680 -:106AEC000AD59DF84920920706D143F0040202F022 -:106AFC000C020C2A40F0CA804FF00008012213F05F -:106B0C0003031ED0012B46D0022BD4D1A08912A98D -:106B1C001AF098FECFE7A68922F09EFE864202D19B -:106B2C00E08D010609D4A68922F096FE864200F07B -:106B3C008B80E08D010600F18780000679D4A08956 -:106B4C007BE0544EF37A012B02D1A379002B78D041 -:106B5C000223A7898DF84430ADF83C7081BB042D1D -:106B6C0075D1207C4E4D8DF85E0028680028A2D08F -:106B7C0022F072FE87429ED1E08D217994F830206C -:106B8C002D684346CDE903028DE8020A0FA812A92D -:106B9C005246A8478FE7002918BF012152EA01008D -:106BAC0003D1A08912A914F0F8FCA0890797ADF8BD -:106BBC001800A0798DF81A0006A819F0ABF97AE73D -:106BCC00ADF8300016989DF84A109DF84B208DF8C2 -:106BDC00203094F832300B9060898DF82310DDF85A -:106BEC004E108DF8222094F830208DF83830ADF806 -:106BFC001800B08CCDF826109DF85C108DF837205D -:106C0C00ADF82400207CADF82A10A17C8DF8320060 -:106C1C0020798DF834109DF85F108DF833009DF8B5 -:106C2C005D008DF836108DF8350006A802F0E6F8F8 -:106C3C0041E7A089ADF86200608912A91EF03EFB05 -:106C4C0010B14FF49A7034E74FF0010941E71AB9CB -:106C5C0012A9384614F0A1FC10480078022809D17A -:106C6C000D480078012805D1204611F04DFB002875 -:106C7C003FF421AFA07CE17CB28C53468DE8020A34 -:106C8C00039012A80FA90EF075FF14E74FF001083E -:106C9C00002234E7A86D0020E527002024260020E0 -:106CAC003C2400202DE9F04F95B0044680690DF18D -:106CBC0053020021002690F800A09C200BF07AFAD9 -:106CCC007D480078012808D8002004211CF086FF9C -:106CDC0006469DF85300304400E00120C1B2002567 -:106CEC008DF85300514540F28180A0EB0A005FFA09 -:106CFC0080F90220B9F1020F28BF81461A2009FB46 -:106D0C0000F023F0FBF80027002800F0C380079464 -:106D1C0009A90496F6B28346D04600240590CDF816 -:106D2C0018A004310891E0B2484566D25FFA88F0A9 -:106D3C00B0425FD21FF06AFE002853D05F4905466F -:106D4C00888C393122F0D0FD4FF60270ABF8170069 -:106D5C0028888DF82470ABF81200ADF82600A97ABB -:106D6C008BF8191009A812F079F901460BF10A00F9 -:106D7C00012903D1089923F06CF803E04FF0FF319F -:106D8C0041600160287950B14C4991F838100131BB -:106D9C0002288BF8181015D80221012814E0474856 -:106DAC00022190F838008BF81510298800290A4622 -:106DBC0018BF01228BF8142018BF411E00208BF83D -:106DCC0018100BE0012103288BF8141003D18BF859 -:106DDC001570012002E001208BF815008BF81600CD -:106DEC000BF11A0B08F1010801349CE74FF0000974 -:106DFC0000274FE00498CAFA50F830480DAD4FF018 -:106E0C00020AAE1C00F13907E0B248453ED25FFAE7 -:106E1C0088F187202A460BF0CDF9BDF83E003946A3 -:106E2C0022F062FD0BF10A00314623F012F8BDF896 -:106E3C0034002149214B012208F10108ABF8120062 -:106E4C000978022938BF022293F838308BF81520C4 -:106E5C00A3F1010238BF4FF0FF3202294FF00001BD -:106E6C008BF8182038BF01218BF817A04900002897 -:106E7C008BF8161018BF01209DF8461001348BF8C2 -:106E8C0014008BF819100BF11A0BBDE7079CDDE908 -:106E9C00057A0025607C9DF85330A11C0022CDE9B9 -:106EAC0000A9CDE902750AF007FB17B1384623F0AB -:106EBC0023F815B0BDE8F08F24260020A86D002023 -:106ECC002DE9F0478AB0DFF8C0810446D8F80000FD -:106EDC00416E02A88847DFF8B4A1DAF80800016C0B -:106EEC00096811B9D0F84C05804769480121017037 -:106EFC00DAF80C00C068007830B9DAF80800002124 -:106F0C00D0F858240120904722F033FE47680589B9 -:106F1C003878C0F3401128460FF09AFADFF87491D4 -:106F2C000790D9F8101019B122F023FE0C308847C5 -:106F3C00D9F8080008B18047089057480078F0B19C -:106F4C00D9F82010B9B1884755490028554B0A4645 -:106F5C0008BF023212781A708DF82420CA1C00283F -:106F6C0018BF4A1C10788DF825004C481978022956 -:106F7C0008BF023000E0494801880131018016F059 -:106F8C00C3F84A48484E0078F57350B122F0F1FD31 -:106F9C00007D30B1284622F08FF81FF047FA002808 -:106FAC006BD000253761758022F020FC0746758078 -:106FBC00059524B1012C31D13D483E49C1613C4875 -:106FCC003949027B437BC47D416045804D6002F0B2 -:106FDC00F002027303F0F0020232427304F0F0028A -:106FEC000432C2754A7B22F00F02531C4B73DAF841 -:106FFC0008301B6C1C6864682478A40608D52E4CD9 -:10700C0042F002024C601B685B689B784A73A37366 -:10701C002A4E7060707B00F0F00070732848D8F82E -:10702C0000100822274B0C6D00210068CDE90021CF -:10703C0002AA3146A0472449B0F1FF3F088007DD82 -:10704C00224819490160224801780131017010E091 -:10705C00D9F8004044B1DAF80800002100220023DE -:10706C00006C00680C30A047012041F2883114F00C -:10707C002DF9384622F075FE02E0E1200BF046FBBC -:10708C000AB0BDE8F08700BF347A00200C01002064 -:10709C00B327002054B502002C250020AC7800202A -:1070AC00BE790020AA7A0020C0770020A0270020FB -:1070BC00B8750020006A180048780020742500205C -:1070CC00E4260020F59600008E7A00203025002062 -:1070DC0029250020B0B5784C20780E2850D8DFE850 -:1070EC0000F0E34F4F5E084F4F4F4F4F584F08087B -:1070FC00080073480078B0B1A078012830D1E0784E -:10710C000130E070C0B2032851D870484FF6FF71BF -:10711C00808C88424FD06C48012101704FF4417033 -:10712C00A4F8010049E06C480021E17001700020D6 -:10713C001CF0D8FF18B120780D38012862D86148AE -:10714C000078022803D10820012104F08DFB0520D2 -:10715C0020F020FE42F21070BDE8B04020F0D2B911 -:10716C0003282AD157480078022826D156480121F5 -:10717C00017003200021A070544880F826101CE0F8 -:10718C0015F05AFF554810210078BDE8B04016F0B4 -:10719C00B7BF4A48008800F007000128A9D1484829 -:1071AC000078F8B10020BDE8B0401AF06FBB484839 -:1071BC000078012801D10020A07019F0FFFE20F00A -:1071CC00A9FC3E488078000703D542480078012886 -:1071DC006AD1A078032867D108200121BDE8B0400E -:1071EC0004F042BB3D481021007816F089FF0020C6 -:1071FC001CF078FF334D297810B361B32078012946 -:10720C002AD036E0062020F0C5FD2C4CA0780007D3 -:10721C0004D54FF40040012104F026FB29480078E6 -:10722C00012809D8208800F00700022804D000208B -:10723C000021002222F0ACF8BDE8B04015F0FCBEF5 -:10724C00022903D10820012104F00EFB052020F0B7 -:10725C00A1FD0120A7E720780A280AD11748008849 -:10726C0000F00700022813D01848082180F82610D7 -:10727C000EE003280CD115F0DFFE19480078022827 -:10728C0006D101201FF08EFD02200121FDF7B0FA7E -:10729C00062020F07FFD2878012805D807480088B3 -:1072AC0000F00700022800D1B0BD00200021002210 -:1072BC00BDE8B04022F06CB8D02600203E7900200A -:1072CC00BF7A002024260020A27A0020A86D00207E -:1072DC00977A0020CA270020AE2200209D7A002039 -:1072EC000C7A00202DE9F04F93B01C9C08901D46A1 -:1072FC0006928B4620461EF0A9FC074620461EF03F -:10730C008DFC00260790002F00F0E980002D18BF9F -:10731C0001256801BBF1000F00F140014FF0000B9B -:10732C0008BF69014FF6FE7503914FF00A0108BFC3 -:10733C000821029109A90431019100F108010C30D6 -:10734C0005910490207C834580F0C480380600F0C1 -:10735C00C18004EBCB0898F81C00C00740F0B78044 -:10736C0061480078012820D898F8160028B10F96AB -:10737C00CDE90D664FF0010A1FE0B8F8180022F0B5 -:10738C008AFC90B1007940F0020003280DD198F8E6 -:10739C001C004FF0000A40F0800088F81C00079891 -:1073AC00000604D10020079091E04FF0010A98F8F4 -:1073BC001600CDE90D660F96C0B14C49089CB8F883 -:1073CC00180091F86810012908D1FF21ADF834009C -:1073DC00059841F2080988F81A1024E0A080681C6E -:1073EC004FF00C09ADF8340004981CE0B8F8180004 -:1073FC00089CA84213D104208DF8240098F81D0095 -:10740C00ADF8300009A818F0ADFD0198002100225C -:10741C000023A580ADF8345016F062FF01E0ADF802 -:10742C003400DDE902908DF8360001208DF839002A -:10743C00207D8DF838000DA807F018FF9DF8480046 -:10744C0078BB109806994176417DA0F8169088F883 -:10745C001B1098F8161019B1244991F8681001778F -:10746C001C9A51890185518A4185117D80F82C1017 -:10747C00517980F83A1098F81A1080F83B1021894D -:10748C00A0F84010617D80F8491062682169C263E0 -:10749C00406C227D21F0D4FF0DA81BF0AFF89DF8B5 -:1074AC00480098F81C1041F0010288F81C2020B10B -:1074BC0041F0090088F81C0005E007998AF00100EA -:1074CC00013F091A07911C9C4FF6FE7500260BF123 -:1074DC00010B37E72046002117F070F906463046BD -:1074EC0013B0BDE8F08F00BF24260020A86D00204B -:1074FC00BFB581780446481E0B2812D8DFE800F08F -:10750C0006525C6A26788590A430B23900208DF83A -:10751C000400E0780F28C0F0B28002208DF804003F -:10752C00B3E0FF2940F0D3800025E01C04218DF846 -:10753C0003501FF01DF96C4908606C48058011F070 -:10754C00E1FE0DF103036F20FF21BDE000208DF85B -:10755C000800E07802F084FA02AB6F200521B3E05A -:10756C0020F058FC8DF80E000DF10E036F200A214F -:10757C00AAE000208DF80F00E01C22F0BBFC0546B1 -:10758C00601D04211FF0F4F8014628460DF028F97F -:10759C00504A3520282122F091FA0DF10F036F206B -:1075AC000C2191E000208DF80600E0780F2870D3B4 -:1075BC0002208DF8060072E0E07847490DF10703D0 -:1075CC00002818BF01200870002003218DF8070047 -:1075DC006F2079E0E2780020211D8DF80A0004F17B -:1075EC000C00022A68D0012A6AD117F017FF65E057 -:1075FC0000208DF80C00E078002818BF012020F046 -:10760C0081FF03AB6F2006215EE0E078211D19F0AD -:10761C0059FB8DF80D000DF10D036F20072153E080 -:10762C000020E57804218DF80900201D1FF0A0F83A -:10763C00002D014618BF0125284621F01FFD0DF134 -:10764C0009036F2008213FE000208DF80B00E07843 -:10765C00002818BF012022F0E9F90DF10B036F206F -:10766C00092131E000208DF80500E07804281BD2B8 -:10767C001B4A01211070512022F020FA17E0194A00 -:10768C0001211070522022F019FA01AB6F20012158 -:10769C001AE0124A01211070532022F00FFA0DF15A -:1076AC0006036F2002210FE002208DF805000DF17A -:1076BC0005036F200B2107E00BF09AF88DF80A00F8 -:1076CC000DF10A036F20042101221BF057F8002052 -:1076DC0004B0B0BD08750020BE270020D2270020C2 -:1076EC00DC270020D8270020182500201425002096 -:1076FC0070B590B00446807821F026FA002800F08E -:10770C00D38005466078A0F1E101E873102906D911 -:10771C001A2818BFCD2808D01D2806D04BE001220E -:10772C0002FA01F16C4A1142F2D06C4E3078012809 -:10773C0002D8688900056CD42846002108F072F93B -:10774C00C0B3307801282BD86548807B800727D5BB -:10775C002968086A20B3C97F03AA09F039FD60784B -:10776C00E92808D12868E27B01234189008800932D -:10777C00E92301F06FF92868BDF8161001809DF817 -:10778C001120BDF81810BDF81600002A18BF0122F0 -:10779C0092010CF0DFF918B1688940F02000688183 -:1077AC006A896178288920F0C5FB28813078012806 -:1077BC0031D971E060788DF81000A07B03958DF8BD -:1077CC001100287C00283ED003A811F0FDFF9DF885 -:1077DC001030E92B00D03BB92868E27B01264189A7 -:1077EC000088009601F036F93C480078012853D8FF -:1077FC003B48807B80074FD5687B022802D1688983 -:10780C0040073BD46078E92846D128461BF0B6FAED -:10781C0042E0052068736078E9283DD03148006863 -:10782C0000B18047304E3068B0B32D48807B800764 -:10783C0032D52868418900881BF0F8FF60B3617865 -:10784C003268904728E003A805F044FE23480078EE -:10785C0020B19DF81030012802D0BAE79DF8103005 -:10786C00002BB6D1286800881CF060FA0028AED135 -:10787C001C4800680028AAD08047A8E72868008820 -:10788C001CF054FA002811BF032028684FF6FF7132 -:10789C00018008BF05206873687B022804BF06209E -:1078AC006873A07812F064FD1FF055FC0B4800784B -:1078BC0002280ED10D48007858B900200DF10B01AB -:1078CC008DF80B0052201AF059FC2020012103F0F6 -:1078DC00CBFF10B070BD00BF0101010024260020B9 -:1078EC00A86D00207C23002080230020E5270020A9 -:1078FC002DE9F04F8BB0002900F0EC80DDF858A09A -:10790C000746007A0D46994690465FEA0A718DF853 -:10791C00060012D4387A02240F2800F2DC800121F0 -:10792C00814011F00B0F19D003288DF8100024D1D1 -:10793C0002A8394622F08DFA22E0022840F0CA80D3 -:10794C003C8821F089FF8442E4D03888012103224D -:10795C0013F0CCFB0028DDD0CD24BCE048F20400B1 -:10796C00014200F0B88038881CF0E0F9002800F0E3 -:10797C00AD800F2038728DF810003888ADF80800F3 -:10798C005FEA8A7014D40020ADF8180054480068DF -:10799C0088B14168A942FAD1826862B12978022083 -:1079AC00904768B10188ADF8181022F0A5FA07E0ED -:1079BC004FF6FF7002E0A86810B14088ADF81800CF -:1079CC00CAF380121798DDE9141B8DF805209DF879 -:1079DC001020531E18BF01230F3A18BF9A001AF03B -:1079EC00100318BF13464FFA8AF2002A0AF040021D -:1079FC0048BF43F0100343EA92125FEA4A73ADF8B2 -:107A0C00202044BF42F04002ADF820208DF8240025 -:107A1C000791ADF81A90ADF8168000229BF8000083 -:107A2C007C7A7E895FEA8A618DF804202D498DF875 -:107A3C00220028788DF81340ADF8146009788DF881 -:107A4C00120048BF04218DF8231021F029F828B129 -:107A5C00016919B102A888477C7A7E893046214693 -:107A6C0021F09CFF28B121F019FA48450DD20224CF -:107A7C0013E001A821F0F8FA48450AD21A48016827 -:107A8C000029F4D002A8884706E002A806F0C4FE3C -:107A9C0002E002A801F0B2F904469DF81000022899 -:107AAC000CD1BDF8086021F0D7FE864206D19BF8B8 -:107ABC0000102878424623461BF0C8FD5CB99BF8A1 -:107ACC000000002401308BF8000004E0387A0F2805 -:107ADC007FF42AAF022420460BB0BDE8F08F00BF24 -:107AEC00247A0020E71D002000270020F8B57B4EEB -:107AFC000446B068D0F8B8100A78CAB18A6BBAB12B -:107B0C00896DA9B10DF1030142F21A009047B068DA -:107B1C00D0F8B800806D8047002738B19DF803007D -:107B2C0020B1A4F1E100B0FA80F04709B06800E0A0 -:107B3C000027D0F8401400208847C07B012502287C -:107B4C0008BF0525B168086C0068002800F0C480E7 -:107B5C00E92C12D01B2C03D06CB90021417077E0BA -:107B6C00027D052A05D0D1F8D41091F88210002995 -:107B7C00F3D017B96BE0002F49D0F068816DF1207C -:107B8C008847B068016C09688A7E2AB1CB8A5B078A -:107B9C0020D4501E887633E0D0F83C058047B1687D -:107BAC000A6C126888B3D08A40072ED4D1F8D4005E -:107BBC0090F834009076D1F8D40090F82220531C21 -:107BCC0080F82230086C006840688270F068016AA6 -:107BDC00284664E00A7E02F07F020A76016C09688E -:107BEC000A7D032A5DD1CA8A22F00402CA82006C83 -:107BFC000068817E01398176394801880131018024 -:107C0C00F068D0F8AC008047F8BD547020E01C2C14 -:107C1C004FD0E12C1BD1D1F83C058047B26801460E -:107C2C00106C006899B1C18A490710D4D2F8D410ED -:107C3C0091F834108176D2F8D40090F822104B1CB5 -:107C4C0080F82230106C006840688170BEE7447088 -:107C5C00B068D0F86C12006C00688847B068016C92 -:107C6C000A68D28A120614D5D0F8B810097839B936 -:107C7C00D0F8D400F16890F84300096B8847B068DD -:107C8C00D0F8D400F16890F94200496A8847B0688E -:107C9C00016C00200860B068D0F8281310208847C9 -:107CAC00F8BDF068816DF0208847B068816C096878 -:107CBC00D1E7096E09680029D0D08847B068002147 -:107CCC00006C0160F068C068007828B9B0680021C9 -:107CDC00D0F8582400209047F8BD00BF0C010020BC -:107CEC00822700202DE9F04788B004464FF0FF3082 -:107CFC0002214FF6FE79CDE90200E089002808BF89 -:107D0C000821A66916F801A030B1704835880088A2 -:107D1C00854213D16E4E06E06D4831461FF017FEBA -:107D2C0090B36A4805884D4518BF002E29D1207B99 -:107D3C00002840F0C8806848406843E065480078F7 -:107D4C0001281CD8284621F0A6FFC0B101790026D5 -:107D5C0001292DD140880DF110088DF81060ADF877 -:107D6C001C00404618F0FEF80646002818BF08F123 -:107D7C000406BAF1000F18BF4FF0FF3AD3E7002604 -:107D8C0016E05548406825E05248007801280DD887 -:107D9C00304621F0DDFF48B101790139012905D8C0 -:107DAC00BAF1000F18BF4FF0FF3ABBE74FF6FE7564 -:107DBC00207B002840F08780474840684D4518BF1D -:107DCC00002E07D1E1894FF0810881B100F8018BB9 -:107DDC0002AE11E05FFA8AF1022902D24FF00008DC -:107DEC0007E0217B01296ED04FF0800801E009F1FA -:107DFC00010500F8018B0EB1314600E002A922F01A -:107E0C0028F80570064605803248007838B10B27F3 -:107E1C0001284AD15FFA8AF0012804D045E05FFAC4 -:107E2C008AF0012822D10B27B8F1000F3DD1274849 -:107E3C00A9B20088814238D100250DF107008DF8D8 -:107E4C00075016F049FD98B1E1890322002908BFBB -:107E5C000922A1698A5C9DF8071091420BD9891AF5 -:107E6C000D238DF8071003EB410708E00B271CE0EE -:107E7C000C27B57019E000210D278DF80710F27052 -:107E8C005200331DB17009060DD0815C03F8021B42 -:107E9C0081180232497803F8011C9DF8071001394A -:107EAC008DF80710EFE722F027F8E2890A4D102031 -:107EBC00A11CFBB2A87004F1110042F4004217F0AF -:107ECC0005FB0020A87008B0BDE8F0878879002079 -:107EDC00E079002024260020882600202DE9F04F90 -:107EEC008DB00746C08914468946073086B23046A5 -:107EFC0010F09AFA0546FF280AD13046FAF760F9D5 -:107F0C00B04205DA70480778002F08BF0527A3E0B8 -:107F1C006D4E3078C0B91CB1022C15D1FF2D13D188 -:107F2C00387A002203238DF81C00786800920690A2 -:107F3C006648C188C07805AA02F058FB9DF8240059 -:107F4C003874BDF82000B881DFF880B1002104231B -:107F5C009BF80340BBF806A00CAA204621F038FA87 -:107F6C009DF830007E2805D120467C211CF0E4FCD5 -:107F7C009DF830007C286BD1FD8905F107081AFAB1 -:107F8C0088F0B0F5005F65D8BB88C5F38512049006 -:107F9C00F88849461FFA88F94FEA850C8DF82DC0F0 -:107FAC0042EA83128DF82A00C0F301208DF82C20B0 -:107FBC009A088DF82B203A7A05EB0A07B9F10D0FC8 -:107FCC0040EA82008DF829004AD23F482A460197A0 -:107FDC00CDF80CC000F11C06304621F0B5FFDDF8E1 -:107FEC002900711900220027029170519DF82D0073 -:107FFC000871681D81B2304621F04CFCDDF8291067 -:10800C0032464B46715196212F4D8DF82F10039906 -:10801C0021F015FB02998DF82E000B98C1F8030086 -:10802C00204651461BF062FF04EB4401049A287071 -:10803C000BEB81018A83BBF806104144ABF80610A8 -:10804C0050B1019881B2204618F002FC2F7803E061 -:10805C00012700E00527377038460DB0BDE8F08FDA -:10806C00894608462946002221F014FC0DF129010D -:10807C00052220F063FA96214A462B468DF82F10E4 -:10808C009DF82D1021F0DBFA51468DF82E0020467C -:10809C001BF02CFF3070B9B220460DF129020723DA -:1080AC001BF024FF317851EA00073770D4D104EB70 -:1080BC004400049900270BEB80008183BBF8060079 -:1080CC004044ABF80600C7E7A0230020B87200209C -:1080DC002DE9F04F8BB0876904463D88B7F80290C4 -:1080EC0028461BF023FE01280DD1207C617C002248 -:1080FC008023CDE90052CDE90220A21C48F20600F3 -:10810C0017F034F9D1E028461BF010FE20B969486D -:10811C000088854240F0C4803E7905375EB170001E -:10812C0021F0ECFE38B10246304639460A9221F075 -:10813C0079F8074602E0002000260A9017F8015B48 -:10814C0055B1680021F0DAFE30B182462846394636 -:10815C00524621F067F802E04FF0000A0025A819FA -:10816C001421564F01EB4000C0B2079068000690F6 -:10817C0070000590A01C0890002009903F68002F0B -:10818C006AD0786801780029F8D0BA7BD207F5D08C -:10819C00D7F80880B8F1000F03D00120C047834600 -:1081AC0001E0D0F808B0BBF1000FE7D0BBF802003B -:1081BC00814503D04FF6FF70814511D1DBF80830B3 -:1081CC009BF807200A9930461DF041FE78B9DBF880 -:1081DC0010309BF80C20284651461DF038FE30B963 -:1081EC00B8F1000FCAD0584621F086FEC6E70798B2 -:1081FC001FF09EF838B30146D220087008980491FD -:10820C0000880D730E7148803EB101F11400059A7F -:10821C0088600A9921F014F901E00020886055B1BA -:10822C000499069A01EB460014300861514621F07E -:10823C0007F9049902E00499002008617868406805 -:10824C00007816F08BFF099B9BF800001C4AD9B2F2 -:10825C00013350540993C3E7099B0A9D180610D0AB -:10826C001448DBB2227C617C0088CDE90003144801 -:10827C000023CDE9020248F20600089A17F076F8BE -:10828C0001E0207BA0B115B1284621F035FEBAF1F2 -:10829C00000F0AD050460BB0BDE8F04F21F02CBEB9 -:1082AC000548007802283FF420AF0BB0BDE8F08FF2 -:1082BC000023D5E78879002024260020247A00208A -:1082CC002C7300202DE9FC47D0E900588246D8F8E1 -:1082DC000000D0F8409019F4F06FC0F8449035D0FD -:1082EC005FEA495117D5D5E91401411A50461DF0E2 -:1082FC003DFFD8F800008169C90605D401688DF8E6 -:10830C0007109DF80710F6E7296801312960A97B51 -:10831C0009B90121A973696C40684FF0004600F05F -:10832C000F0404EA0100B0FA80F126FA01F10140D1 -:10833C0005D02F6C1FB12A68AB6C5046B847B4FA05 -:10834C0084F026FA00F020404042A863D5F858018A -:10835C00D8F83C1009F0400740680068D0F80425B4 -:10836C001140394347D0DAE90064504614F030FE2E -:10837C00D7B1F07C90B90BE0316F69B10068B16E88 -:10838C00B26F8854306FB16F01310138B16730670B -:10839C0020688169C906EFD5F07C28B1D6E91401B3 -:1083AC00411A50461DF0E2FE96F86400E0B13079B7 -:1083BC00022819D017B1B179012901D0316F99B9BF -:1083CC000024B16E0128346786F86440B46607D186 -:1083DC00B36CB26FD6F8CC6050460094B04703E053 -:1083EC0006F17C0021F09CFD504609F0C9FAD5F845 -:1083FC0058014068006800F204500068D8F8381042 -:10840C00084228D0D5F8F80028B3DAE900765046AF -:10841C0011F02EFE50460CF0E1FC7879012812D1B7 -:10842C00D7F8F40078B997F8E80060B1002087F825 -:10843C00E800BB6CD7F8EC10D7F8FC20D7F850410B -:10844C0000905046A047D7F8F80020B93068816BEF -:10845C0041F4006181635FEA095023D5D8F800002C -:10846C0081690907FCD4016B21F480710163297ABD -:10847C0091B10020287295F84400800606D52C6C2A -:10848C0024B1AB6C504620210022A047504601215C -:10849C001EF098F9D8F80000816B21F4006181631B -:1084AC00687908B1BDE8FC8705F58070BDE8FC472C -:1084BC0021F036BD2DE9FE4F1D4614460F46814670 -:1084CC0021F094F9DFF8C0A183464FF6FD78DAE984 -:1084DC000010494518BF084660B1B83021F0E4FCE3 -:1084EC0040B19AF82400CAF8209040F004008AF8B1 -:1084FC0024009FE01FF0DEFB002868D0064663488E -:10850C00CDF808B0DDE90CB821F025FC604908F085 -:10851C00200EB1F8540001306FF31F30A1F8540055 -:10852C00B5605C480025C6E903792268D4F80C8054 -:10853C0086F83250C6E908550BEA000C207C7263B1 -:10854C002279C6E906CEC6F8408086F8440086F843 -:10855C003820B1F8541086F83350D4E905533186DD -:10856C00A168C6E91253F163A18BA6F8501028B983 -:10857C00B8F1000F1CBF012086F844004AB9387BC3 -:10858C0000F00F00022804D1012086F83800B868EA -:10859C007063DDF808B00822FF2353FA82F23C46E0 -:1085AC00D0B2851A18BF01257F680FB1002DF4D108 -:1085BC00208800F47C40B0F5305F0BD196F8330086 -:1085CC000022082340F0100086F8330004E008F184 -:1085DC0001082FE0002202234CEA03004EEA0201BC -:1085EC002B4DC6E90601DAF82000484507D19AF868 -:1085FC002400C1071CBF00F0FE008AF824002648A6 -:10860C00046854B1A96CEA6C05F1400005F138031B -:10861C0000903046A047033013D1FD209AF8241067 -:10862C00CAF820904FFA80F841F004018AF824101F -:10863C0020F0E6FE584621F094FB0FFA88F0BDE8D6 -:10864C00FE8FB6F83080B5F85410414501D020F0BB -:10865C00D7FEC0B2012801D8FE20DFE7002089F840 -:10866C00FC0096F8330040F0800086F83300A86BCD -:10867C00B04205D0F068007B00F00F000228D9D181 -:10868C0015F0A2F8D6E700BF70200020387100204A -:10869C0030210020FFEFFF9F902600202DE9FF41A5 -:1086AC00DFF8BC81002003900290D8F83840B4B3B6 -:1086BC00D8F84C0010B9D8F8480070B3D8F8480076 -:1086CC0060B12069D8F848100969814206D194F844 -:1086DC003300C00602D5D8F84C0090B1002702A890 -:1086EC0087F0010103AA10F085FD0546FFB9F5B12D -:1086FC000299002900F09D805A4820F065F9002766 -:10870C0014E0D8F84800C06840880028F9D0D8F8A0 -:10871C004800C06840880128F3D00127DFE75248A1 -:10872C000221283021F000FC0027002500242CB366 -:10873C004E48466816B30298B0FA80F040092840BB -:10874C0001281BD1D8F84800D8F84C10039A87F0B0 -:10875C000103CDE9003208F1380208F14003B047BB -:10876C00012868D0022809D1D8F848000122012339 -:10877C000069D8F84810B1F9301065E0002C20469B -:10878C0018BF01203840012851D13948216940686F -:10879C00814203D034484FF4806145E002980028B0 -:1087AC0018BF01202840012806D1D8F8480018B974 -:1087BC00D8F84C0000284DD008201FF0C3FD94F8C9 -:1087CC0033004C25C00608F1380058BF48251FF06F -:1087DC0047F848F80500274BD4E90601C2439A60D4 -:1087EC00DA681043D860C8431860586808432146BB -:1087FC0058600820E5681FF07DFA28461FF0AAF99A -:10880C00288843F60601411A022906D3B0F5C15F48 -:10881C0003D040F60201884203D1012029461FF003 -:10882C0069FA11484FF08041283021F07DFBBDE8FA -:10883C00FF8100277BE70398002818BF044601221C -:10884C000023B4F9301020690092002205F0BEF824 -:10885C00BDE8FF8108201CF00BF9BDE8FF8100BFCB -:10886C00302100207C7100207020002090260020F8 -:10887C00D01E0020081004402DE9F0478AB0684D46 -:10888C002868416E02A88847664FF87918B1B87904 -:10889C0008B10020C0E020F0A9FFDFF88CA18046D1 -:1088AC0000249AF8000080074FF0000005D47D20CA -:1088BC0000210DF0CDFD8DF818408DF80C40029480 -:1088CC005A4C0790616911B19AF800008847E0682A -:1088DC0008B180470890387A98B1606A88B18047AF -:1088EC005349544B8A1D002818BF0A1D12781A7060 -:1088FC008DF82420CA1D002818BF4A1D10788DF849 -:10890C0025004D4EDFF8349100200590317BF27E2E -:10891C00B0607080D9F8080001F0700180313173BB -:10892C0002F08001D0F82824F4206331F176032181 -:10893C008DF8181006F11C019047387980B99AF817 -:10894C00000080060CD52868C06B8047317BB06076 -:10895C00029001F0F0010231317301218DF80C10FD -:10896C0029683748344E384B0D6D4FF080710068D4 -:10897C0001913449009102AA3146A8470546334873 -:10898C00B5F1FF3F058035DDB879002100240130B9 -:10899C00B871787901307871FE60F8790130F8712E -:1089AC00022012F093FC3C712948D9F80820018868 -:1089BC00D2F8AC30D2F8D4201C7841EAC411D48C53 -:1089CC000180D2E9117193F800C0538D7486C48173 -:1089DC00C0F80710C0F803708381508DC6E90A7186 -:1089EC000CF001013086308B20F0800040EAC11081 -:1089FC00308309E0626812B1002000219047022008 -:108A0C0041F2883112F062FC404621F0AAF90020B4 -:108A1C00B5F1FF3FC8BF01200AB0BDE8F08700BF29 -:108A2C00347A002024250020B17A002054B50200AD -:108A3C00BE790020A97A0020007200200C010020D1 -:108A4C00E426002020004300E90F01008C7A00206E -:108A5C00007900202DE9F843994617460C468046CC -:108A6C001AF0E4FE089D06463DB936B9404621464B -:108A7C003A46BDE8F84318F07BBA6EB3002D3ED0F1 -:108A8C00624C207808B1012803D16148806800B19C -:108A9C008047B9F1000F4BD02078012800F2A58057 -:108AAC005C48807B800740D55948C26812B130467B -:108ABC0049469047584831780078884224BF0131A4 -:108ACC0031700024C9B2814230D1404619F056FFB2 -:108ADC007470012701242EE04C4800240127B9F1C1 -:108AEC00000F007829D0012D27D1012825D849481D -:108AFC00807B800719D5404619F040FF15E0B0780F -:108B0C00B9F1000F0AD1C1194808022938BF012058 -:108B1C007178B07011B94149097871704049097880 -:108B2C00884202D90027002405E00024012702E036 -:108B3C0000270024377035480078012D08BF022823 -:108B4C002BD084F001010F424DD1012812D83148AD -:108B5C00807B80070ED5404621F09DF850B11FB99F -:108B6C00417901F0FE014171ECB3417941F0010111 -:108B7C00417100E0BCB3254C2078012821D8254850 -:108B8C00807B80071DD540461FF046FEC8B10020F3 -:108B9C004146BDE8F84321F0A7B9A9F11901022912 -:108BAC00CFD3B9F1000F08D0B9F1E10F18BFB9F16B -:108BBC00F10FC6D0B9F1EB0F1AD1154900220A708A -:108BCC00BFE71448408B40450DD10120414621F0B0 -:108BDC008BF92078022806D14FF400500121BDE812 -:108BEC00F84302F041BEBDE8F88300240127A4E756 -:108BFC00074A0C49137809780133DDB28D4228BF3E -:108C0C000023137028BF01249BE700BF24260020FB -:108C1C0074230020A86D0020CDBA0200CCBA02004B -:108C2C00A3270020D62700202DE9FE4FD0F8008086 -:108C3C00994614460E46824613B10020C9F800002E -:108C4C0020F0D4FD834698F8070038B198F86400FA -:108C5C0048B121F09BF86FF00805B4E021F096F8CC -:108C6C006FF00E05AFE0002C4AD0504614F0B0F96E -:108C7C0000200121C8E91A64C8F87040C8F87800CF -:108C8C00C8F8380088F80C0088F80A00504688F8B4 -:108C9C0064101BF0EFF9504608F072FE08F14C041A -:108CAC0002AD204629461EF0FDFDD8F87810D8F804 -:108CBC0070707218B84238BF0746029910463A468F -:108CCC0021F042F9204639461DF093F8D8F870008F -:108CDC00D8F87810C21B3944012FC8F87020C8F896 -:108CEC00781001DBB842DCD198F8041002290CD1C1 -:108CFC000020C8F8680088F86400C8F870001CE010 -:108D0C0021F044F86FF009055DE0B84215D1002060 -:108D1C00D8F86860012988F86400C8F868000CD19C -:108D2C000124584688F8104021F01BF898F80F00E1 -:108D3C0000284BD020F05AFD834621F027F898F8F4 -:108D4C00040008B100252FE0D8F8701008F17C0061 -:108D5C0031B30C9920F06CFF10B1012088F80C0095 -:108D6C0020F044FD0446504614F032F90020C8F8B7 -:108D7C006800C8F8700088F86400504608F000FEDF -:108D8C0098F80A6098F80C50204620F0EAFF002D65 -:108D9C0018BF6FF00C05002E18BF6FF00D0503E027 -:108DAC000021002520F044FF20F020FDB9F1000F38 -:108DBC0007D098F8041001291CBFD8F87810C9F80E -:108DCC00001020F0CEFF2846BDE8FE8F002598F855 -:108DDC0010000028AED020F009FDA8F80F4020F0BC -:108DEC00C0FFD8F84830D8F87820D8F8CC70504666 -:108DFC0031460095B84788F80F50E8E7F0B587B0D2 -:108E0C0004466F48007878B1228B0020E57A012166 -:108E1C000390CDE901008DF80910500706D402F03B -:108E2C0008030121002008E0BA20ABE0402012F03A -:108E3C0008038DF8060008BF0321402606EA8206C7 -:108E4C004BB1C02093068DF806004FF0010358BFBC -:108E5C0002238DF80730530903EA121202F00802BC -:108E6C00324342EA0106217A03290AD8DFE801F0ED -:108E7C000215112640F0040720F0EEFC8DF8067068 -:108E8C0008E00F291ED140F0080046F004068DF8CA -:108E9C0006002088ADF8040014E04A4991F86810E7 -:108EAC00002900F08180278840F0080006F58056E4 -:108EBC00FF258DF80600ADF8047004E001A92046EA -:108ECC001CF014FA0027208BC0070ED09DF806006A -:108EDC0010F00C0F58D09DF8060000F00C0104297E -:108EEC0004BF40F020008DF80600A07C8DF808002F -:108EFC0001A806F0BBF99DF81800002842D104988F -:108F0C00C682B4F81B10A0F81910217A012903D1DC -:108F1C002C4991F868100177A17EE37F0185228BA3 -:108F2C0080F82C301306428508D5D20506D5417D34 -:108F3C0094F820001DF0D9FCA17E0498878780F856 -:108F4C003B5080F84A10A17A80F83A10D4F80E10F1 -:108F5C00C0F83E10A17F80F84B10617F80F849105B -:108F6C00406C6169628A20F06BFA208B400604D554 -:108F7C001548016809B101A8884701A819F03EFB02 -:108F8C009DF8180007B0F0BD208816F0CDFD48B153 -:108F9C009DF8060040F020008DF80600208BC007DD -:108FAC0099D1A2E7BB20EDE727884FF6FD7140F081 -:108FBC000C0046F00406ADF804108DF8060082E7AC -:108FCC002C240020A86D00206C2700202DE9F04FE8 -:108FDC0089B0714F14460A46064610460492B98C65 -:108FEC001AF024FC054610B16878002866D0B06AE7 -:108FFC004FF00E09B34690F80180867890F805A0E2 -:10900C005FEA886158BF4FF00609B0F8030003907F -:10901C0004981AF0DBFF18F0870F4CD108F01801F8 -:10902C00182948D09BF81C10894544D100EB0A0242 -:10903C000021BBF80C00B1460091D1B292460E460D -:10904C00049B494632460EF0B5FC032836D008F096 -:10905C007801B8BB18F0180F62D05FEAC860884678 -:10906C004FF0030058BF012040EA0108BBF80C0088 -:10907C00414610F07DFF88B1817911F0180F0DD0A9 -:10908C00417901290AD14DB1B98C40881AF0CEFB37 -:10909C0020B1407810B1697888420FD320F0C1FA22 -:1090AC0088B94FF0FF3020809BF8080000286BD067 -:1090BC00DBF8181069E0D32011F099FA002009B000 -:1090CC00BDE8F08F884620884FF6FF718842F5D1B5 -:1090DC000121BBF80C00324600914946049B0EF06E -:1090EC0069FC0398414685B2284618F0FBF9F98AC9 -:1090FC0088420CD1284620F0CEFD20B300790138EF -:10910C00012820D805A928461CF000FE21E0DBF838 -:10911C00280080F805A009B0BDE8F04F1EF0CABCCD -:10912C00787B884608B120F07CFA03984FF6FE71E4 -:10913C000022434680B203F0E1FF0028C3D14FF672 -:10914C00FF702080C4E71FF0D1FE014605A820F077 -:10915C0080FE9BF80800012804D1DBF8181007A842 -:10916C0020F077FEDBF82810BBF80C00497805AA34 -:10917C0007ABCDE9003200224B4641F030010291A1 -:10918C00294608F0BDFE99E70021BBF80C003246D9 -:10919C0020F098FE97E700BFA86D002070B58AB04C -:1091AC0000F11605044628461BF00CF867480078B9 -:1091BC00013801282BD800201021012214238DF80E -:1091CC00110005AE0DF11100CDE90210CDE90062E0 -:1091DC000DF11201042000221BF098F950B15C48EB -:1091EC00006804A905AE324610F0ACFAC728ADF8F9 -:1091FC0012000CD806F108002946082220F020F9AC -:10920C00BDF812100420142233461DF017FA28461C -:10921C00FF2108221FF082FD10B14E480121017080 -:10922C0028461BF0DBFC20790138052800F28B80E6 -:10923C00DFE800F00389345C8903A01D00211029AC -:10924C0013D0425C0131002AF9D061791EF036F955 -:10925C004348424D90F8410008B12878D8B1607964 -:10926C000DF0CAFE0020287015E03D4890F8410032 -:10927C0088B905AC002062210025224610F030FC94 -:10928C00204600211EF01AF900200DF0B5FECDE9A4 -:10929C000755CDE905551FF0EFF854E00DF112011B -:1092AC0028461DF0B9FA60B10DF112024FF6FE70AE -:1092BC0029461CF0DFFF284600210022002315F070 -:1092CC000FF8BDF8126005A930461CF027FB059875 -:1092DC0028B905A81AF07EF908B905980680A11DD1 -:1092EC00284610F005FD13F0FFFC2CE01A4E3078E8 -:1092FC0048B30DF1120105AA284610F023FA0146D5 -:10930C009DF81200F8B1002501201422ADF82400BC -:10931C0006958DF82650059505AB04201DF08EF9A9 -:10932C0006344FF481701021224620F0C1FB28B97D -:10933C004FF481701021224620F0C0FB0120032144 -:10934C00357018F0C7FA0AB070BD00BF2426002093 -:10935C00EC580020A07A0020B0220020AF22002080 -:10936C00A86D00202DE9FE4FD0E90198D8F8001027 -:10937C00CA690A62D20740F0AF80D8E904014FF005 -:10938C00000A4FF0000B0843D9F8CC104968096863 -:10939C00C1F8040509F13000029009F1C8000190F0 -:1093AC00BBF1010F00F2A180D9F8C000002800F039 -:1093BC009C80D9F8E010DC22D9F8CC70202300294D -:1093CC0008BFD82208BF182358F803404FF02403D5 -:1093DC0008BF1C237F68D8F8146058F803303F6826 -:1093EC00D7F80455354211D0A46864070ED104682F -:1093FC00D9F8D050A54209D144693CB9D8F80040FD -:10940C00656A25F002056562C7F804659B685B0711 -:10941C0002D00BF1010BC3E759F80230002BF8D046 -:10942C0049F802A0B1FA81F1D9E93442490900683E -:10943C0049011A448442C9F8D420C9F8E01028BF65 -:10944C0082420CD24846414602F0F6FC99F8FE00E6 -:10945C000028DED01FF05EFD18BF8862D9E720F02F -:10946C00C5F9D9F8C820D9F8C010019B81F810A013 -:10947C0022B113465269002AFBD114331960C9F882 -:10948C00D4A04A69C1F814A0D9F8E01000294FF013 -:10949C00DC01C9F8C02008BFD82159F80110C9F85F -:1094AC00D01020F05EFCD9F8C00058B148464146B7 -:1094BC0002F0C2FC99F8FE0050B11FF02BFD18BF52 -:1094CC00886205E0D8F80000416A21F0030141628E -:1094DC00029820F02BFD9CE7D9F8C0203AB103216B -:1094EC001174BDE8FE4F0EF0E7BFBDE8FE8F486873 -:1094FC0020F002004860486A20F003004862D8E976 -:10950C0004021043D9F8CC2052681268D062C2F819 -:10951C000405486920F001004861012008624046BA -:10952C00BDE8FE4F1DF0F1BD70B58CB004460020B7 -:10953C008DF82C00CDE906000890A078411E052975 -:10954C0025D82220DFE801F00321212C23036248D7 -:10955C00007820BB20F058FA40B9604DA168082271 -:10956C0005F118001FF06CFF208828805C480078FB -:10957C00022814D1A0680DF1030101AA10F0E2F841 -:10958C009DF8140038B1B1206CE01B2008E0B3202A -:10959C008DF82C0059E09DF803000028F3D023200F -:1095AC008DF81C000120A17B8DF81A0020888DF805 -:1095BC001D102169ADF81800607B0891012804BFCB -:1095CC0021208DF81A0006A805F050FE9DF82C00FD -:1095DC00D8BB0998456C05202870A0786870A81C29 -:1095EC00616819B110221FF02BFF04E00021C1604B -:1095FC00816041600160A078062801D0012803D168 -:10960C00E078A874133500E01235A16828461FF0E5 -:10961C00DEFFA17805F1080006290AD8012202FA1A -:10962C0001F111F0520F04D02E49096820F011FC01 -:10963C0001E0217B017020881AF078FB10B10998A9 -:10964C000421C1829DF82C0070B12348007838B9F0 -:10965C0020F0DAF920B921480021C0E90611018077 -:10966C009DF82C000CB070BDA078042814D1A06813 -:10967C0001AD0DF103012A4610F064F806469DF881 -:10968C00030018B94FF6FF708642DED0206968B12E -:10969C0006A80DF0C7FF0CE0206918B106A80DF064 -:1096AC00C1FFD2E706A818F0A9FFCEE706A818F06C -:1096BC00A5FFA16805F1080008221FF0C1FE0120DA -:1096CC00314614222B46ADF814000020CDE90100E0 -:1096DC0004201CF0B3FFB8E72426002050240020FF -:1096EC00BC270020EC580020F8B5634E01211D4624 -:1096FC001446F068C0680170604800210170604831 -:10970C000170B068016C096811B9D0F84C0580473C -:10971C005C48076847B15C4822462B464188B068D4 -:10972C00006C00680C30B84715F0E24F14D0574865 -:10973C000178013901705448406818B15448C18906 -:10974C000131C181B068006C006840680078800607 -:10975C006FD41AF02FF86FE020070CD44A484068F9 -:10976C0018B14B48C1890131C18148480178013990 -:10977C0001701D205EE0454C42F205422078013814 -:10978C0020704448418841F00400904218D13E4872 -:10979C00406818B13E48C2890132C2813C484289B6 -:1097AC000132428142F20542E120914208BF1C2065 -:1097BC0008F0ACFF207800284AD094F9000040E073 -:1097CC00314842F606024188914212D0B1F5105F41 -:1097DC0049D140693349086019F0B0FA2E48007835 -:1097EC0050B32F480168013138BF0160002101815D -:1097FC0022E0406818B12648C1890131C181264850 -:10980C000078C8B12548042100780228204808BFF8 -:10981C000621425A0132425221484168013138BF77 -:10982C0041600189428901318BB20181934288BF29 -:10983C004181E92008F06AFF1448017841B190F9A0 -:10984C00000000280ADCB068D0F84C05804705E021 -:10985C00B0680021D0F8582400209047F06800210F -:10986C00C0680170F8BD406800283FF482AF08481A -:10987C00C1890131C1817CE70C0100202725002022 -:10988C00B327002054B50200C07700202925002002 -:10989C00AC780020B87500202C250020AA7A002076 -:1098AC0064790020487A0020FEB504462C2020F074 -:1098BC0025FB002820614BD02C2120F029FA2569AA -:1098CC0020884FF6FF760DF10301AE8211F0F2F90C -:1098DC0048B30DF1030069461EF01EFFBDF80020D1 -:1098EC00B24220D0584902EB4200AA8206226A8278 -:1098FC00002251F820302A744FF47A72AB6151F87F -:10990C0020300133B3FBF2F541F8203005FB123265 -:10991C004AB901EB8000012101724C484FF40061FF -:10992C00007814F0EDFB21692088083111F0C2F9A0 -:10993C001FF0CEFC256970B1022028744FF4D000C2 -:10994C00C5F8120042480168A9610131016021E0AB -:10995C0010202075FEBDA88AB0421BD13D4F05F1E9 -:10996C00080039681DF0F3FF58B93D681FF0BEFAC6 -:10997C00014628461DF0EBFF18B91FF0A9FC002882 -:10998C005FD02169208802F00DFB256900B1AE8201 -:10999C0000202874A88AB04231D12F48C17A11BB5B -:1099AC0090F8410001281ED10DF10B02002001217D -:1099BC003A2301271EF03AFC08B1AE8213E09DF861 -:1099CC000B002F74A8754FF46810C5F812002348CB -:1099DC0001684A1CA961026029B91C484FF4007146 -:1099EC00007814F08DFB2569A88AB04207D1A1201C -:1099FC002075284620F080FA00202061FEBD287CCE -:109A0C00012801D10E210CE0A06808B10D2108E05D -:109A1C001FF05EFC0D2118B9A078C00708BF052106 -:109A2C0025692977A1780C4801F00301007B0129F5 -:109A3C0008BF05206870C0B21FF052FD216948773D -:109A4C00FEBD2569A6E700BF307500209D7A002079 -:109A5C0008270020EC580020A86D002018250020B5 -:109A6C00F0B587B0624C054694F82B0028B9614FCD -:109A7C000421387819F0A0FC30B35F48407808BB5B -:109A8C005E480078022803D194F82B00800619D484 -:109A9C0094F82E0005F0C60668B1A8070BD594F80B -:109AAC002B00C00607D41EF04EFB04200121FAF750 -:109ABC009FFE86F0020694F82B1006F03F00084338 -:109ACC0084F82B0007B0F0BD94F82B0005F00606C7 -:109ADC002178304384F82B0051B1E0B34648002183 -:109AEC0001703878042107B0BDE8F04014F008BBD1 -:109AFC00012004F12E0300210122207055201FF0BB -:109B0C0035FB94F82E0080B33C48007801380128CE -:109B1C0009D83B4D0021082228681FF0FFF810B926 -:109B2C001FF0D6FB20B334480721017094F82B00AA -:109B3C000021304340F0100084F82B00002005F089 -:109B4C0027F80028BED000201DF02CF9072000219A -:109B5C00FAF74EFEB6E728480721017007200021CE -:109B6C0007B0BDE8F040FAF743BE94F82B00B4E719 -:109B7C0028680DF11B0101AA0FF0E4FD05462148F0 -:109B8C0000780028CFD09DF81400FD28CBD00228F7 -:109B9C00C9D01D480088854217D201AE1421304629 -:109BAC0020F0B6F8FF202946142233468DF8140015 -:109BBC0004201CF043FD154905EB4500002241F83B -:109BCC00202001EB800042724260002555200121CB -:109BDC0004F82E5F22461FF071FFFF20032119F0BD -:109BEC0051FF054804210570387814F089FA69E7AB -:109BFC00AC220020A37A00200C7A0020242600201E -:109C0C00EC580020BA270020C0BA0200F033002024 -:109C1C002DE9F04788B00646109C0020DD099A46D5 -:109C2C001746C3F3C308E060A06060602060E9B130 -:109C3C00E9462146102248461FF002FC20463146D8 -:109C4C0010221FF0FDFB484620F0A3F8002010283E -:109C5C0005D0315C225C514021540130F7E70AF108 -:109C6C00800A1FFA8AF04FEA102901E04FEA1A29FC -:109C7C006E46280418D0304621461022013D1FF0B4 -:109C8C00DFFB2046394610221FF0DAFB304620F06D -:109C9C0080F80020102805D0395C225C51402154FA -:109CAC000130F7E70744E4E7B8F1000F25D0684628 -:109CBC00214610221FF0C4FBB8F10E0F40D3002533 -:109CCC00204639464246E560A560656025601FF078 -:109CDC00B7FB80202146102204F8080004AE304661 -:109CEC001FF0AEFB684620F054F8102D48D0705D84 -:109CFC00615D484060550135F7E76E4621461022FC -:109D0C0030461FF09DFB002780201FF04BFF2146A3 -:109D1C001022C4F80170C4F80570C4F80970677398 -:109D2C00207004AD28461FF08BFB304620F031F834 -:109D3C00102F42D0E85DE15D4840E0550137F7E770 -:109D4C000026204639464246A681A66066602660FB -:109D5C001FF076FB80202146102204F808001FF02B -:109D6C0021FF04AD28461FF06BFB684620F011F86C -:109D7C00102E22D0A85DA15D4840A0550136F7E712 -:109D8C006F462146102238461FF05AFB00253046FC -:109D9C00214610221FF006FF25606560A560A58195 -:109DAC001FF04EFB38461FF0F4FF102D05D0705DF0 -:109DBC00615D484060550135F7E708B0BDE8F087B4 -:109DCC002DE9F04F8BB0DFF8A0810446D8F80800DD -:109DDC00D0F80001807AC00020F090F8002809909B -:109DEC0000F0B6800DF1040A0AF103071FF0FEFC27 -:109DFC004FF00009FF2600250090D8F80800EAB2C1 -:109E0C00D0F80011CB7A9A422AD2D0F88824D020EC -:109E1C0051468DF80650ADF804409047F0B99DF8C6 -:109E2C00100020B1012819D19DF80F1001E09DF808 -:109E3C000B1099B100284FF0080008BF0420002136 -:109E4C00814202D27E540131FAE707F80090D8F82B -:109E5C0008005146D0F89424D02090470135CCE727 -:109E6C004FF6FF7701AE0DF1140A4FF0FF3B4FF0A8 -:109E7C000009C9885FFA89F291426BD9ADF80620C6 -:109E8C00D0F88824D1203146ADF80440904730B149 -:109E9C00D8F8080009F10109D0F80011E9E7BDF87C -:109EAC000800B842F4D0ADF81400D8F808005146B8 -:109EBC00D0F88824D4209047002841D10025D8F828 -:109ECC000820D2F80001C1888D4216D2D2F888241D -:109EDC00D1203146ADF80650ADF80440904728B972 -:109EEC00BDF81400BDF80810814201D00135E6E739 -:109EFC00D8F80800D0F80001C1888D42C8D1CDE94E -:109F0C0007BB099AADF81A70ADF81870807AC100C9 -:109F1C000020814214D0131808309B88A342F8D13A -:109F2C001118002241F8082C09990844514620F8D0 -:109F3C00047CD8F80800D0F89424D4209047A7E7E4 -:109F4C0000981FF00EFF09981FF0D6FF192008E0AB -:109F5C001A2006E000981FF004FF09981FF0CCFFB0 -:109F6C0000200BB0BDE8F08F0C010020FEB50C46B4 -:109F7C0014F036FFA00600F18280200400F1AF80BF -:109F8C00E00607D52E208DF8040060481FF0AFFEC8 -:109F9C0001A88847E00707D025208DF804005B480E -:109FAC001FF0A5FE01A88847A00707D526208DF82D -:109FBC00040056481FF09BFE01A88847600707D590 -:109FCC0027208DF8040051481FF091FE01A8884706 -:109FDC00200707D529208DF804004C481FF087FE78 -:109FEC0001A88847600607D52D20ADF80400474826 -:109FFC001FF07DFE01A88847200607D53020ADF85C -:10A00C00040042481FF073FE01A88847E00507D5FD -:10A01C003520ADF804003D481FF069FE01A88847C3 -:10A02C00200505D53720ADF8040001A81FF0D2FF9C -:10A03C00E00405D53820ADF8040001A81FF0CAFFD4 -:10A04C00324CA068D0F898000068B0B11FF0CEFB7D -:10A05C00A168D1F898100A68029200220A601FF0D9 -:10A06C0080FEA068D0F8981002984860A168D1F8DA -:10A07C0040138847A0681FF031FC0020FEBD234E22 -:10A08C0002ADB068C06B04301DF006F800280290D9 -:10A09C003FF473AF1FF0AAFBB168C96B0A7B013A9E -:10A0AC000A731FF05EFEB1680298D1F89810077819 -:10A0BC0048608DF80470417839B1162F0BD1B06817 -:10A0CC00D0F8541328468847DBE7B168D1F8401321 -:10A0DC008847162FD5D0B0681FF000FCD1E70B4D88 -:10A0EC00A868D0F89400007814F0DCFC00280290EA -:10A0FC003FF446AFA968D1F898104860A968D1F828 -:10A10C0040138847A8681FF0E9FBE9E70C01002021 -:10A11C002DE9F04706680446307B022812D196F8E8 -:10A12C0023006568D6E904A79146884680B1B168DA -:10A13C0058481FF07DFD40B100206FF0010786F8F4 -:10A14C00250055E06FF0060752E0012086F8260046 -:10A15C00002052492246F0614F48C6F8008086F82C -:10A16C0021901EF0AFFD297827201EF043F85046B1 -:10A17C003946062209F080FA58B196F8260098B3B1 -:10A18C0044481FF0CDFE002086F8260086F82500F6 -:10A19C002AE0434D434FD5F8800320F00200C5F868 -:10A1AC00800396F82000042804D157F84C0C416920 -:10A1BC00272088470220C5F8FC0238684168062031 -:10A1CC008847C0B1402028608020286096F826007F -:10A1DC0038B130481FF0A4FE002086F8260086F81F -:10A1EC0025000020C5F8FC024FF0FF30F061F76944 -:10A1FC003846BDE8F0870220BA461BF057FA002714 -:10A20C00B9F1020F0AD0B9F1040F4FF0000006D0DB -:10A21C00B9F1060018BF0120800000E00020C5F84D -:10A22C004C010123D8F80C10D8E90102C5F85011E3 -:10A23C00C5F8547186F82430DAF800301D690B46E5 -:10A24C00A847256895F8200002281BD00428CFD1F8 -:10A25C00DAF80000816915488847B0F1FF3FDCBF90 -:10A26C004FF0FF30E8610020EF6985F8240095F885 -:10A27C0021100339022928BF85F82500204619F042 -:10A28C0059FCB5E708484FF0FF311FF0D1FCEF69DE -:10A29C00AEE700BF98700020CC76002079C7010093 -:10A2AC0004440240FC010010E87000200100008012 -:10A2BC002DE9F0415A4E04465A4DB068D0F8D410EE -:10A2CC0091F88380297819B1D0F84C058047B06893 -:10A2DC00016C096811B9D0F84C058047524F012028 -:10A2EC00062C3C7028701ED8DFE804F004042225EC -:10A2FC002B5140004E4800214170B068026CD0F8E0 -:10A30C00D41010684B4AC08A40064FF04E0058BF1C -:10A31C002520085C107014BBC97801B3022828BF33 -:10A32C00022010701BE0B068D0F84C0580472EE07E -:10A33C0018F0C4FC2BE03E480021417017F0C8FF18 -:10A34C0025E03A4800213A4A0170B068006C006878 -:10A35C0090F8691090F86A0051703649087008F04E -:10A36C00E3FFB068006C006888B940E0B068324A1E -:10A37C00006C016891F86D1011803049006890F8FC -:10A38C006E00002808BF0120087019F0DFFF284874 -:10A39C000078A0B9B268106C016829B9D2F84C05E4 -:10A3AC008047B068006C01684968254A097801F05B -:10A3BC002001117023490068406880780870387853 -:10A3CC00062814D8012101FA00F010F04C0F0ED021 -:10A3DC001FF00CFA0446387802280AD18320287022 -:10A3EC0020461FF0BEFCBDE8F04118F067BDBDE88B -:10A3FC00F0811548017819B9144909780029EDD074 -:10A40C000221B8F1010F297004D10078832808BF0C -:10A41C0015F0E0F82046BDE8F0411FF0A2BC00BFEB -:10A42C000C010020B87A0020BB7A0020B527002050 -:10A43C002D260020B97A0020C6790020BA7A002097 -:10A44C00C47A0020C57A0020B07A0020B37A0020AC -:10A45C002DE9F0438BB0DFF884810C4605460020D3 -:10A46C008DF81300D8F80010002900F0AD80032DF2 -:10A47C0018BF022D03D191F84200904208D15849DF -:10A48C0000201BF081FD3DB1012D03D185240BE093 -:10A49C00002099E0032D0DD10121D8F80000032DE7 -:10A4AC0080F8411003D114B18DF813400DE0002455 -:10A4BC005DB91EE0022D07D1D8F800000CB10221C5 -:10A4CC0000E0012180F841100024D8F8000090F839 -:10A4DC004190B9F1010F0ED190F8431019B1013927 -:10A4EC0080F8431005E090F8481011B1013980F85C -:10A4FC0048104FF0010990F8431049B1426C00F13B -:10A50C002E03074602EB41018A1E00F126010CE0E6 -:10A51C0090F8481000295AD0C26C00F10E0300F1DB -:10A52C00200702EB41018A1E811D1E78158802222C -:10A53C008DF828201CBB17B32A4A127880F84220C9 -:10A54C0003208DF81C007888ADF8200005AC20465F -:10A55C001FF07FFC7878BB7BCDE90054CDE902601D -:10A56C002120B9F1010F08BF2220BA1D08A911F052 -:10A57C0025FE1D481A4900881BF006FD23E0418882 -:10A58C000DF1130448F220020123ADF8201041789C -:10A59C00CDE9004108A917F0C5F8D8F8000090F8EB -:10A5AC00401002290DD1418C48F220020123ADF854 -:10A5BC00201090F821102030CDE9004108A917F0A7 -:10A5CC00B1F815F087FA01200BB0BDE8F0834FF617 -:10A5DC00FF75FF2600210027A9E700BF44270020B4 -:10A5EC00519C020088260020967000202DE9F04F27 -:10A5FC0089B08246129803F0F00403F00F0B002888 -:10A60C0018BF0120103C03920025B4FA84F46409AD -:10A61C002040D4880290107A92886FF39F2400F027 -:10A62C003F0024036FF39F2244EA0060544C104413 -:10A63C0000905248007804AEC2B2ABB2934280F0A4 -:10A64C009580A27801355FFA8AF7974273D08AB267 -:10A65C000195172A6DD3A1F10709384632461FFA26 -:10A66C0089F421460FF084FF9DF81B8008F003004D -:10A67C00022826D1BBF1030F00F27D800398007AEB -:10A68C00DFE80BF0140205109DF8181007E09DF898 -:10A69C001810884215D10398BDF81610C08888424E -:10A6AC0004D00EE00498009981420AD10298002847 -:10A6BC0054D01298002183688289304615F048FFE7 -:10A6CC0060B15FEA48701CD5BDF81E0084421CD9ED -:10A6DC00A9EB000188B21728BDD228E01298808817 -:10A6EC00E0B3129BDA8819689B681A440B781578CA -:10A6FC009D42E6D1013802F1010201F10101F5D1CF -:10A70C002CE01F4C0120607104E03846214616F005 -:10A71C009FF81B4C00200025F7F752FD1748E178F5 -:10A72C0000780131B1FBF0F202FB101A03E0134880 -:10A73C000078134C019D5FFA8AF1C2B251FA80F194 -:10A74C00013991FBF2F303FB121A5FFA8AF149000B -:10A75C0051FA8AF104EB8101898B6DE7039D96E830 -:10A76C001F001FC5002009B0BDE8F08F0399002021 -:10A77C0088810A20F7E70420F5E700BF9B7A0020C8 -:10A78C00B8720020B0B560480021604C016094F8AC -:10A79C003A01032812D002282ED0012840F0AF80B5 -:10A7AC0094F8400111F090F8002084F840015948C9 -:10A7BC00817B0220002908BF06209EE054480168D6 -:10A7CC00B1F5C060C4F82C01B8BFC1F5C060D4F8B5 -:10A7DC001011002900D5494288422ADDD4F8140111 -:10A7EC001CF0CAFDD4F818011CF0D8FDD4F82801CF -:10A7FC001CF0F8FD01201DE0454805681EF040FEE8 -:10A80C00C4F814011EF044FEC4F818011EF048FEF2 -:10A81C00B5F5C061C4F82801C4F8101109D094F83A -:10A82C0030215AB1D4F81401D4F82021D4F82C11C9 -:10A83C000AE0002084F8300106205EE0C4F8240110 -:10A84C00D4E94502C4F82C110223C4F81C010029D8 -:10A85C0001EB410148BF6FF001031944042391FB44 -:10A86C00F3F111440029C4F820110FDD1F2931D355 -:10A87C00D4F824212AB33E28A8BF3E200130292930 -:10A88C00A8BF2921C4F81C010B3909E0D4F82421F4 -:10A89C00032A09D111F1140FD8BF6FF01301153130 -:10A8AC00C4F82011002113E00128D8BF0120013881 -:10A8BC0011F10A0FD8BF6FF00901C4F81C010B315C -:10A8CC0003E03329A8BF33211539C4F82011032123 -:10A8DC00C4F824111CF050FD01201CF071FDD4F8BB -:10A8EC0020011CF05BFDD4F824011CF07BFDA5F2CB -:10A8FC00FF510420032938BF0620C4F83C01BDE8F1 -:10A90C00B04005F04FBC00BF3C500C40D81B0020A1 -:10A91C0008400C4018B802002DE9FE4F074600789D -:10A92C009B468A46029200F00C000C2808D1B8888D -:10A93C00FE211AF0A1F9FE28019008BF012019E0B0 -:10A94C0059480568B878FF2808D01EF009FE40B1B8 -:10A95C00064600781EF0A4F8054603E02DB16E689B -:10A96C0000E00026FE2001900EE0FE2000250026CF -:10A97C00019009E01EF0F4FD002800F092800646DC -:10A98C0000781EF08DF80546002E00F08A80AA682B -:10A99C004AB13178022090474FF6FE7440B10488DA -:10A9AC001FF0AAFA04E0B0684FF6FE7400B14488B8 -:10A9BC0039893078A14211D010B909B900200DE0C5 -:10A9CC0028B14FF6FE72013292B2914206D0A1F537 -:10A9DC0080714FF6013289B2914244D897F80290B7 -:10A9EC00B870387DD7F810803030C0B21CF0A0FCA5 -:10A9FC00B8B304461A20514620707868C4F8020097 -:10AA0C00A01D1DF063FDBBF80100A4F817000C9805 -:10AA1C003A7D397B84F820000E986175A284E06140 -:10AA2C000D986076F878E073307820759BF800000C -:10AA3C00A075788BA08578896082029820820F9807 -:10AA4C0084F82E0032B104F130004146A0621EF0B1 -:10AA5C00F7FC01E00020A06270682146007814F039 -:10AA6C007DFB87F80290387800F00C000C280DD094 -:10AA7C00B8780026FF287FF487AF286800250026C9 -:10AA8C0000283FF481AF466805467DE70199B888F8 -:10AA9C00C9B21AF0F1F8FE280146019001D00198D4 -:10AAAC0068E7BDE8FE8F00BF247A00202DE9FF4740 -:10AABC00D0E901590E4604461EF098FE95F8FD109B -:10AACC0021B97169102901D8032906D81FF049F959 -:10AADC000024204604B0BDE8F087012785F8FD70FE -:10AAEC001FF03FF900204E4A85F8FC00C5E9300004 -:10AAFC00C5F8C80085F8FE003069C5F8E400706937 -:10AB0C00C5F8E800307B85F8F9000028317885F825 -:10AB1C00F8107168C5F8EC10B9F80E10A5F8F6101D -:10AB2C00317E52F8211085F8FA1008BF1027C5F8AD -:10AB3C00F07099F80C000BF0CDF8204616F00EF9D9 -:10AB4C0099F83B00374985F8FB008A46D4E9018720 -:10AB5C003A6B97F83A000DF01FFC7A6B98F8FB00F3 -:10AB6C0051460DF019FC98F8F91097F838000129A6 -:10AB7C0015D1FA6A51460DF00FFCBA6A97F83900F4 -:10AB8C0046F202010DF008FC98F8FB0026491DF076 -:10AB9C0023FB98F8FB0021461EF06CF90AE0BA6A18 -:10ABAC0046F202010DF0F8FBFA6A97F839005146AB -:10ABBC000DF0F2FBE84640461EF0B2FB99F805009A -:10ABCC001A4A4346CDE90040284699F8041018F07B -:10ABDC00C7FA40461EF094FCD9F8080014494246C6 -:10ABEC000094029005F1300019F037FD12F082FE4E -:10ABFC00104AC5F8CC0005F11C00042123461CF0BA -:10AC0C0003FC95F8F80008B1B06805E005F16C009C -:10AC1C0000211DF0AFF80848C5F8BC0059E700BF8B -:10AC2C00B8B7020002600020ED0E01007193000025 -:10AC3C0045110200E19A0200259D02002DE9F84F12 -:10AC4C000CF088FD5F4800254FF0000A0478A542FF -:10AC5C0011D2E8B21BF0DAFE58B1017941F00401CF -:10AC6C00042906D1807A1DF055F9002818BF0AF185 -:10AC7C00010A0135EBE700271BF0B4FC0546002662 -:10AC8C00F8B285420AD91AF0B1F928B1807C1DF0CE -:10AC9C0041F9002818BF01360137F1E706EB0A0924 -:10ACAC005FEA096032D04FF47F7000EA89073846BA -:10ACBC001FF024F950B33946FF2280461EF0D2FF14 -:10ACCC0000275FFA8AFA4FF0000BA7422AD25FFAEC -:10ACDC008BF0504526D2F8B21BF098FEA0B1064678 -:10ACEC00007940F0040004280ED1B07A1DF012F95E -:10ACFC0050B10146727A30885FFA89F3009343466B -:10AD0C0015F00EF80BF1010B0137DEE74FF00008E0 -:10AD1C004FF000092C48007BD8B11EF0E1FBC0F1CC -:10AD2C00540017E000245FFA89F7E0B28542F1D9AC -:10AD3C001AF05CF958B10646807C1DF0EBF830B186 -:10AD4C000146727C30884346009714F0E9FF0134C9 -:10AD5C00EBE76220C1B203224546B1FBF2FABAF12D -:10AD6C001F0F28BF4FF01F0AC0B25FFA89F72A469F -:10AD7C00002818BF0120410101F14004574588BF4C -:10AD8C00440128BF57462146384612F0F4FA0646CD -:10AD9C0014F0400040EA0601A7F1010008BFA9EB3E -:10ADAC000009C0B208BF05EB800500200029DBD0EC -:10ADBC00B8F1000F02D040461FF09EF83046BDE8B7 -:10ADCC00F88F00BFE3BA0200A86D0020FEB5044660 -:10ADDC005A480078A04213D908780D46012801D1B1 -:10ADEC00686868B16878012801D1A86840B1544FEF -:10ADFC0057F834601EF0FAFCF17921B11EF0B1FF66 -:10AE0C0000242046FEBD07EBC40401216768F171E4 -:10AE1C001EF0A7FF002005F1040C7074F081B060E7 -:10AE2C0030602988B180A98BC6E93D00C6E90E00C7 -:10AE3C0086F86400B186297D2B69B1719CE80610F7 -:10AE4C00C6F85021BCF1000FC6E910C34FF0FF3219 -:10AE5C00C6F8CC10A969C6E93B203163A97F86F8F6 -:10AE6C003610296AC6E91A00C6E91C00B16486F8D6 -:10AE7C00E800C6F8580102D13249C6E9101097F81B -:10AE8C0040000AF027FFD7E9031206F14C001EF030 -:10AE9C001FFBD7E9051206F1D0001EF019FB2A4959 -:10AEAC0038680968C96888477A6C97F8240046F2B4 -:10AEBC0002010DF071FA254DBA6C97F82000294665 -:10AECC000DF06AFAF86901280CD1FA6C97F8280091 -:10AEDC0029460DF061FA3A6D97F82C0046F2020102 -:10AEEC000DF05AFA12F006FDC6F85801204605F08E -:10AEFC0079FD174A06F5AE70042123461CF084FA3E -:10AF0C006D4628461EF00CFA387A7968114A2B46A1 -:10AF1C000094019006F1140018F022F906F17C005F -:10AF2C0000211CF027FF06F5807000211CF022FF89 -:10AF3C003868D7E90C121060486062E7C6BA0200A4 -:10AF4C002CBA0200C3730100D00100100260002073 -:10AF5C00AD8F0200D18200002DE9F84F81460868C0 -:10AF6C008B469046D9E90045476806895548E16803 -:10AF7C001EF05EFE18B16FF00100BDE8F88F52486C -:10AF8C0052494FF0000A4A46C4F814B084F80980BC -:10AF9C00C4F804A084F802A01DF094FE29782720A0 -:10AFAC001DF028F938463146062208F065FB40B101 -:10AFBC0044481EF0B5FF4FF0FF3084F801A0BDE807 -:10AFCC00F88F434F57F84C0C416927208847414E66 -:10AFDC000220C6F8FC02386841680620884760B138 -:10AFEC00402030608020306036481EF099FF0020F1 -:10AFFC0060704FF0FF30BDE8F88F02201AF056FB5E -:10B00C003A68DBF810009BF82010D26990473A6838 -:10B01C009BF820009BF821101368A8F10102B2FAEA -:10B02C0082F252099847DBE90610C6F8500100205D -:10B03C00C6F85401C6F8581159B13A68DBF8040047 -:10B04C00002315690022A84738688169224801301D -:10B05C008847207A042804D057F84C0C0169272023 -:10B06C0088473B68DBF81C10DBE902021C690B46C5 -:10B07C00A047D9F8004001206070207A022815D032 -:10B08C0004281BD13868144D816928468847B0F1D3 -:10B09C00FF3FDCBF4FF0FF30606000206070A81CE9 -:10B0AC00C6F88403484610F071FF04E00B484FF0DB -:10B0BC00FF311EF0BDFD6068BDE8F88F0020BDE8D3 -:10B0CC00F88F00BF98700020CC76002051D401007E -:10B0DC00FC0100100444024001000080E8700020D4 -:10B0EC00F0B587B05C4E0446306848B390F8401019 -:10B0FC0001293FD1022180F840102030214612F066 -:10B10C001DFE05463068C169436B90F83220007E05 -:10B11C0016F078FAB5FA85F137684D09002887F8EA -:10B12C00430043D040001EF0E9FE37687864C8B392 -:10B13C0097F843104A0049491EF082F9376835E008 -:10B14C0050201EF0DBFE306050B3502105461EF03F -:10B15C00DFFD2846214612F0F1FD08B330680121CD -:10B16C0080F840103E483F49008807B0BDE8F040E9 -:10B17C001AF00ABF02200DF10F0148F22002012340 -:10B18C008DF8180088208DF80F006088ADF810003D -:10B19C006078CDE9001004A9204616F0C3FA49E006 -:10B1AC0088201CE0882001258DF80F007B69BA7C73 -:10B1BC00F96B97F8380016F025FA316881F84800D9 -:10B1CC0058B140001EF09AFE3168C86430B191F855 -:10B1DC0048104A0021491EF033F96DB386208DF8D2 -:10B1EC000F0002200DF10F0548F2200201238DF80B -:10B1FC0018006088ADF810006078CDE9005004A903 -:10B20C00204616F08FFA306890B190F84010022961 -:10B21C000ED1418848F220020123ADF81010022112 -:10B22C008DF818104178CDE9005104A916F07AFA7E -:10B23C0014F050FC07B0F0BD306890F8431019B909 -:10B24C0090F848000028C9D000200021002207B047 -:10B25C00BDE8F040FFF7FCB8442700202C73002019 -:10B26C0096700020519C020070B5604D0446A86891 -:10B27C004169497F002973D0D0F8D420B4F842102A -:10B28C00D28C91426CD1D0F86C1304F12800884711 -:10B29C00002865D0A868002241694A77D0F8D410FC -:10B2AC0091F8291021B1E868816A02208847A868C2 -:10B2BC00006F90F82B0018B1E868816A012088476C -:10B2CC00207CC00608D5E868816A10208847A868E9 -:10B2DC00D0F8281380208847E868C16B2020884765 -:10B2EC00A868D0F8FC14C068103088476268A86859 -:10B2FC0013785278416902F00F064E76C2F30011B2 -:10B30C004269917603F00F01426991771909D0F8DF -:10B31C00D42082F82C10D0F8D410426991F84F3018 -:10B32C00927F0F2B05D09A4203D26668F67806B945 -:10B33C001A464A730022C16881F83020D0F8D41024 -:10B34C00497B0F290DD14169C97E022908D1D0F85A -:10B35C0064018047A868D0F86C01BDE870400047D4 -:10B36C0070BDD0F80C2520469047A9684869C07E6E -:10B37C00022814D1C868D1F8FC148847AA684FF485 -:10B38C007076D2F8D430D2E90301D2F8F0245B7B8A -:10B39C0031F8131006FA03F3591A9047A968D1F83B -:10B3AC00D400D1F8B431228990F82C10022098479F -:10B3BC00A968D1F8D400427B90F82C0090420FD0B1 -:10B3CC004869D1F8FC148847A8684169D0F87C0119 -:10B3DC008860A868D0F8F024406941699047A96852 -:10B3EC00D1F828131020BDE8704008470C0100204C -:10B3FC002DE9F84F544B554D93F800B000235B45A5 -:10B40C0004D2AC782CB108350133F8E74FF00009C1 -:10B41C0097E04FF000095B4500F093804C4B009295 -:10B42C004D4A4FF0000885F806901E1D494BB2F8A6 -:10B43C0016A04FF6FE721F78012307B336F8044CA2 -:10B44C008C4218BF544503D12436013F5B00F4E70E -:10B45C003478042C03D0012C06D0002CF4D109F143 -:10B46C00010985F80690EFE702F1010CB0F80AE04B -:10B47C001FFA8CF4A64508BF48EA0308E4E7384CE9 -:10B48C00DFF8D4E0354B2678BEF824700A33B6B119 -:10B49C0033F80A4C8C4218BF944202D11C33013E43 -:10B4AC00F5E71C88BC42F9D1DC79002CF6D01C7A6B -:10B4BC00002CF3D009F1010985F80690EEE7294933 -:10B4CC005FFA89F309788B4284BFA9718946009A87 -:10B4DC005FEA096102D0817C012901D1002102E0DF -:10B4EC009EF80210013129719EF801109EF8073068 -:10B4FC00B8F1000F6A71E9708189C07CAB7029804A -:10B50C00E87111D0184D194BBBF1000F0CD01E78FF -:10B51C00284619462EB14B1C051DABF1010B96426A -:10B52C00F2D1C0F800800A70114C4021207817F03D -:10B53C0043FF20B92078402164221EF042FC4FF0DA -:10B54C0001094846BDE8F88FCEBA0200AA6800206F -:10B55C0020450020E3BA0200A86D002030560020E0 -:10B56C00D1BA0200D4BA0200306D00205876002007 -:10B57C009C7A0020F8B50446007D50B15A4994F9E4 -:10B58C001800C968D1F880108847013004BFE82042 -:10B59C00F8BD554EE27BB568D5F80011E86B09781B -:10B5AC000AB1807A00E0C07A81429CBFF120F8BDDC -:10B5BC00636A94F8392094F83810A08DD5F88C5221 -:10B5CC00278C0097A84700285ED0054600202880CD -:10B5DC006868A28DA16A1EF0B7FC04F1300005F179 -:10B5EC0084010CC80CC1028880788870B0680A800D -:10B5FC002146D0F8442505F1900090476089B36846 -:10B60C00A5F89A00207B85F89C00607B85F89D004E -:10B61C00A27DD4F80E00D4F81210D3F84835984710 -:10B62C00A5F89E00E07D85F8A000207E85F8A1009D -:10B63C0094F83C0085F86C00228CA5F8A8202AB35D -:10B64C00E169D5F8A4001EF07FFC1DF0E1FEB5F811 -:10B65C00A800E8B1D5F8A400D0B16868411E6960B3 -:10B66C00F82100F8011C6868411E6960002100F88F -:10B67C00011CB5F8A8006968091A6960A9652989CF -:10B68C0008440230288103E01A20F8BD1DF0C0FEEA -:10B69C00B5F89E10C8051DD594F83B20E8202AB1BA -:10B6AC0011F0040208BF11F0010100D0F8BDB1681F -:10B6BC00486ED1F8FC14884794F83B004FF47A712B -:10B6CC00B268484309490978B0FBF1F1506ED2F8E1 -:10B6DC00F4249047B0682946D0F89400007813F011 -:10B6EC003DFD0020F8BD00BF0C010020B47A002005 -:10B6FC002DE9F84F0446B0F82490C17B008A1EF067 -:10B70C004DF948B9A07B032806D009F1140A1FFA99 -:10B71C008AF0F128C0F09E8009F11E0A1FFA8AF007 -:10B72C00FB280AD309F110001EF0E8FB40B30646D3 -:10B73C0010304FF01E0A706000E000264FF08208B7 -:10B74C004FF0010B1FFA8AF01EF0D8FBB0B1074680 -:10B75C00A078BBF1000F3870E07878702079B87061 -:10B76C006079F8700ED0A07BA11D3871A07B0328E6 -:10B77C0010D1781D08221DF063FE0FE0002E64D15D -:10B78C00BDE8F88FA079FD1D3871E0797871E07B08 -:10B79C00B8710BE0087878714878B871E07B07F1E4 -:10B7AC0010057873207CB873607CF873207D28704A -:10B7BC00607D6870A07DA870607EE870281DE169CE -:10B7CC001EF005FB0020BBF1000F28720FBF05F126 -:10B7DC000A0B4FEA1920A87205F10B0B85F809909A -:10B7EC00CEB11F481F4D4FF47A72016831600F21A2 -:10B7FC0006602878317308211EF0E6FA18B1287813 -:10B80C00082112F07DFCE069A16A4A46B0607068BC -:10B81C001DF016FE05E0A16A58464A461DF010FEC2 -:10B82C00CB4494F82C005FFA8AF241463B468BF8E5 -:10B83C00000094F82D008BF8010094F82E008BF882 -:10B84C000200442016F09AFF3E463046BDE8F84F01 -:10B85C001EF052BB4FF0000B4FF08108002671E731 -:10B86C00682600209A7A00207CB5594D594E4CF62A -:10B87C00C0722B78347883F0010384F002042343E4 -:10B88C00554C08BF104000295349898C0CBF21EA44 -:10B89C000000084301B2A084B1F1FF3F08DC012095 -:10B8AC000DF103018DF80300522016F067FCA08CFB -:10B8BC0081046BD401B2B1F1FF3F2ADD010465D0E4 -:10B8CC004FF0FF310191317802295FD1297800299D -:10B8DC005CD121682346013101A908BF0B46C20780 -:10B8EC0008BF0B4622461D6852F8046FB54298BF3C -:10B8FC001A46050758BF1A46C30606D525461368CF -:10B90C0055F8086FB34288BF2A46830607D41346FE -:10B91C000CE080B2400439D504F110003EE023461F -:10B92C00156853F80C6FB54298BF1346420401D406 -:10B93C001A4606E022461D6852F8106FB54298BFB1 -:10B94C001A46C30401D4134606E02346156853F87F -:10B95C00146FB54298BF1346820701D41A4606E00D -:10B96C0022461D6852F8186FB54298BF1A46400718 -:10B97C0001D4104606E02046136850F81C5FAB4219 -:10B98C0098BF1046884218BF002807D1002001211B -:10B99C0020621248007814F01FF87CBD226A0168FE -:10B9AC0012B11268914211D00C4D206201292878F5 -:10B9BC0003D1012112F0A4FB7CBD012114F00CF881 -:10B9CC00216A28780A6801211EF0FBF97CBD00BFB2 -:10B9DC00E527002024260020087500209C7A0020F2 -:10B9EC00F8B5554F554E564D38883168EC8808449B -:10B9FC00224600F10801A868806D1EF0A5FAA9681E -:10BA0C003888504B8A6D2044388022448A653268CD -:10BA1C0081B20832565C811C398089B2515C197034 -:10BA2C00C11C0730398089B2515838806846009162 -:10BA3C0004211AF09DFE00901CF08EFDA968C863CD -:10BA4C0000981CF027FAA968A1F840003E4800783D -:10BA5C0018B11EF025FAA968C863EA2019F074F928 -:10BA6C003A48426812B1A86801219047384802212F -:10BA7C00384C0170E0684069007830B1A87B8009CF -:10BA8C0017F08CFB08B10120A870A968A8780A7C73 -:10BA9C00002870B218BF42F0040200270A7400217B -:10BAAC001AF0F9FE0146A86880F8461000F17401FE -:10BABC00B0F85C2080F8486080F847708165018997 -:10BACC00511A426811444160417B890709D5A1682C -:10BADC00D1F808138847A868416E11B1B0F8681006 -:10BAEC00F1B190F8601049B1A168D1F80C138847F6 -:10BAFC00A868C16C11B1B0F8501089B1A168D1F827 -:10BB0C00B820137823B1926C12B19047A868A16841 -:10BB1C00D1F8581288470020A8601CF07FFDF8BDB2 -:10BB2C00A068D0F8541205F1080088470020A860DE -:10BB3C0010F05CFCF8BD00BFBE780020D879002066 -:10BB4C0034250020B57A00209427002054B502003B -:10BB5C00B07A00200C0100202DE9F84FD0E90054F8 -:10BB6C00994616468A46834613B10020C9F8000050 -:10BB7C0076B11DF03BFE0746E87968B195F8E80010 -:10BB8C0088B138461EF0EDF86FF00800BDE8F88F6C -:10BB9C006FF00900BDE8F88F38461EF0E2F86FF040 -:10BBAC000E00BDE8F88F0020012105F58078C5E96D -:10BBBC003BA6C5F8F460C5F8FC0085F8E810E8630E -:10BBCC006873E872404600211EF032F820461DF0E2 -:10BBDC00FDFE38461EF0C5F81DF069F808B9687905 -:10BBEC00C0B395F84400C00606D52C6C24B1AB6CE0 -:10BBFC00584610210022A0471DF0F8FD0446584677 -:10BC0C0009F0ECF820461EF0ACF8687960B90A9996 -:10BC1C0040461EF00DF808B10120687358460EF02E -:10BC2C0027FA002085F8E800B9F1000F1CBFD5F801 -:10BC3C00FC00C9F80000E87A28B10020E8726FF027 -:10BC4C000D00BDE8F88F687B002818BF6FF00C0062 -:10BC5C00BDE8F88FDBE9005495F84400C00614D514 -:10BC6C002F6CAB6C584610210022B8470DE0D5F86C -:10BC7C00FC0031460AEB0002204618F047FFD5F8CD -:10BC8C00FC10361A0144C5F8FC10002EEFD12046EA -:10BC9C001DF056FC0028FAD020461DF08BFE95F8BE -:10BCAC004400800605D52C6CAB6C58462021002234 -:10BCBC00A0470020B9F1000F85F8E800C8D0D5F8EE -:10BCCC00FC00C9F800000020BDE8F88F2DE9FF4703 -:10BCDC0015460F46814639B138461EF039F818B171 -:10BCEC000446A5F1010A4EE04A48A0F124014A4855 -:10BCFC000678701C01386DD001F1240491F82810DD -:10BD0C00FF292146F6D1002C64D0E81EC0B20128D0 -:10BD1C000DD84248B0F80080B8F1000F07D00320CE -:10BD2C00042117F05BFFA6EB080181426FDDA5F142 -:10BD3C00010A5FFA8AF001280DD83948B0F8008062 -:10BD4C00B8F1000F07D00120022117F047FFA6EB36 -:10BD5C00080181425BDD0120E8463946ADF80290CE -:10BD6C008DF8000008F104001DF031FC404605F090 -:10BD7C007FFE0020A071BDF80C0060802948818CEA -:10BD8C0048461AF092F84AF6012100202571A4F8D1 -:10BD9C000090A4F8091080212082E060E072E0712C -:10BDAC0084F82110204909780131490821725FFA81 -:10BDBC008AF1042938BF01208000012960710BD859 -:10BDCC001A48007858B11A4951F82000C0EB0010FD -:10BDDC00800006E0002409E06FF0010004E0144844 -:10BDEC000068012184F82010A061E061002004218A -:10BDFC00002517F0F3FE08490978884224BF0D4846 -:10BE0C00057008F0B1FD204604B0BDE8F0870024B1 -:10BE1C00F9E700BF20450020E3BA0200BABA0200DD -:10BE2C00BCBA0200A86D0020CDBA0200D8270020B1 -:10BE3C0090B40200972700202DE9FC4FD0F8C08069 -:10BE4C00D0F8D0C0D0F8E820D8F80030C346E64689 -:10BE5C009C4511D3D8F814B0BBF1000F00F08980C9 -:10BE6C0090F8FC3005244FF0000E002B08BF012485 -:10BE7C00DBF800308BF81040A3EB0E05A2F1080A9A -:10BE8C00B5F5806F28BF4FF48065D0F8D82032B15B -:10BE9C0001F1200301F12402C0F8DC5005E0C0F8E8 -:10BEAC00D85001F1180301F11C020026BAF1000F61 -:10BEBC00C8BF0126DBF8044012681F68CDF800E00B -:10BECC007CB1354B53F82630BB6005FA06F30126DE -:10BEDC00BAF1000FC8BF02260EFB06332344013B08 -:10BEEC0005E02E4B53F82630BB6000F1F6033B60A7 -:10BEFC0043F6F0740191D1F8009004EB051626403E -:10BF0C0009F1080EC7F804E0BC683443BC60002497 -:10BF1C00BAF1000FC8BF0124DBF808709FB161466D -:10BF2C00DFF87CC05CF824308C46936005FA04F38F -:10BF3C000124BAF1000FC8BF0224009901FB04319F -:10BF4C0039444C1E05E0154951F8241000F1F40455 -:10BF5C0091605460C2F800E0916831439160C34530 -:10BF6C0004BF05EB0C01C0F8D01090F8FE10019A3C -:10BF7C0009B1BDE8FC8FD9F8241041F00301C9F8D0 -:10BF8C002410D0F8CC00D2E90412406811430068A8 -:10BF9C008162BDE8FC8F00BFA0B70200A8B7020009 -:10BFAC00B0B70200F0B58BB0ADF80A00002001F17B -:10BFBC0008070C468DF8080038461CF079F808B3D1 -:10BFCC0006AE0DF10701384632460DF0BBFB0546B7 -:10BFDC004FF6FF7085421FD09DF8070000B39DF807 -:10BFEC002800002844D0FF280AD0022848D0FD2879 -:10BFFC0006D001284DD13F4800780138012844D99A -:10C00C003E4844E002A80DF029F8012802D102A80C -:10C01C0018F010FCA1205AE03848C4F8120055E082 -:10C02C0006F10800394608221DF00AFA40F2FF100A -:10C03C00ADF828001DF0E8FD00F00F0000272946A0 -:10C04C00142233468DF82A000420CDE906771AF025 -:10C05C00F5FA2B4905EB450041F8207001EB800007 -:10C06C002649C0E90177C4F812100121417210E091 -:10C07C00052060829DF82B0000F07F00A08208E074 -:10C08C001C480078411E022923D24FF08170C4F85D -:10C09C0012001B4A05EB4501002052F821305D1CB3 -:10C0AC0042F82150A3610A232074B5FBF3F303EB90 -:10C0BC008303A5EB430353B902EB81000121017209 -:10C0CC0010484FF48061007812F01AF800200BB081 -:10C0DC00F0BD30B90848C4F812009DF82A0084F865 -:10C0EC00280004F11E0006F1080108221DF0A8F931 -:10C0FC00CFE700BF2426002000000101000003014F -:10C10C00F03300209D7A0020F8B50D46417F04469F -:10C11C00827F1020002908BF082060700AB1083007 -:10C12C006070217F09B101306070A17921B1217A51 -:10C13C0000EB410002306070267E4749002E18BF8C -:10C14C000E26097802290BD142490978012907D119 -:10C15C002178012904D04149097809B1012100E075 -:10C16C00002184F83410217D314408442870217E4C -:10C17C0031B13B48007B1DF0B3F929780844287095 -:10C18C00C0B274283DD81DF0B9FED0B30546344872 -:10C19C002178677E237F94F806C094F818E0627FBC -:10C1AC00807C002B41EA800007F00301A77F40EA66 -:10C1BC00811094F83410287018BF012340EA032032 -:10C1CC0040EA4E2040EAC22040EA073040EA8C2088 -:10C1DC0040EA4130000A6870A078A870E078E870F6 -:10C1EC002079287160796871A07EA871E07EE87171 -:10C1FC00607F40B1216A05F108001DF02AFE10276E -:10C20C0002E0002523E00827A07F20B1616AE8192D -:10C21C001DF01FFE0837A07970B1207AE855E81997 -:10C22C000237617A4170E819227AE16852001DF0F8 -:10C23C0007F9207A07EB4007207F08B1F9B2685460 -:10C24C006078227D2169284430441DF0F9F8284695 -:10C25C00F8BD00BFCA27002024260020DC270020C0 -:10C26C00A86D00202DE9F04F85B007468A46581876 -:10C27C00D7F80880D8F80410884202D96FF003056B -:10C28C007BE04E4D7C68DDF838904FF0FF319B46DB -:10C29C00164628681DF0CCFC6068B8F82010C5E97B -:10C2AC0001015FEAC97014D15FEA897023D5D8F80F -:10C2BC000C0000287AD0D8F81010002976D0012272 -:10C2CC008DE80700384651465B46324613F0D2F8EB -:10C2DC000EE0A068C14300EA0B0211EA0B0F1CBF71 -:10C2EC00D8F808100A4400EA0A01384606F0FEFDA8 -:10C2FC0008B105463DE0D8F800005C46354603968B -:10C30C0000EB0A09ECB3384612F0E0FC78BB384677 -:10C31C0019F07CFB58BB02208DF813908DF810009F -:10C32C004FEA19208DF812004FEA19408DF81100D0 -:10C33C002248018938461CF036FF5FFA89F0C0F5B7 -:10C34C008076B44238BF264604A8042113F094FC2E -:10C35C0068B92846314613F08FFC40B91748A41B26 -:10C36C00B144018938461CF027FF3544CAE74FF029 -:10C37C00FF35124800681DF0D3FD284605B0BDE816 -:10C38C00F08F0E98400701D40025F2E7D8F80C0086 -:10C39C0060B1D8F8101049B100228DE8070038467A -:10C3AC0051465B46039A13F065F8A2E70348006810 -:10C3BC001DF0B6FD6FF00705DFE700BF0C24002071 -:10C3CC002DE9F0418AB0514F05463878022804D146 -:10C3DC004D480078002800F09480DFF8348198F8FC -:10C3EC002600082802D0042840F08B8007AC284691 -:10C3FC0021461CF009F8387802280BD11CF076FD88 -:10C40C00A11C1BF0A4FA28B1BDF81C601DF024FA85 -:10C41C00864276D01DF084FC0234BDF81C00214607 -:10C42C0008F050FE01286CD06E4630461DF037FCEB -:10C43C00304621461BF08BFA68B1BDF81C601DF02C -:10C44C00F9F9864207D0BDF81C00414621F81A0FB5 -:10C45C004B2015F093FE3878012819D8AD8A1DF0C1 -:10C46C00FBF9854214D020461DF072FC30B10079E6 -:10C47C000138012802D8204612F068FD26480168D0 -:10C48C0031B124480078012802D1BDF81C0088473E -:10C49C00BDF81C00002100261AF011FEB8F824107B -:10C4AC00BDF81C0019F001FDBDF81C008DF80C60E6 -:10C4BC00ADF80E0003AD28460CF0D0FD70B1CDE9FF -:10C4CC0000662E1D684631461BF041FA30B13046ED -:10C4DC0021461DF07CF803A805F0CAFA281D214658 -:10C4EC001DF075F828460FF0CDF850B1BDF81C00C2 -:10C4FC00BDF80E10814204D0ADF80E0003A805F073 -:10C50C00B7FA0AB0BDE8F081E52700202426002008 -:10C51C00A86D0020CA270020982300202DE9F047A1 -:10C52C00012816D1DFF830A1DAF83401012813D133 -:10C53C000220CAF8340119F0C1FD0120012419F0C0 -:10C54C00F5FA60B1CAF834411BF094FB4FF0FF349C -:10C55C007FE06FF001047CE06FF0040479E09AF85E -:10C56C005A419AF859119AF85801002C18BF012415 -:10C57C00002918BF0234002818BF043401201DF014 -:10C58C00DDF9013818BF01209AF83811B1FA81F1A0 -:10C59C00490910EA010902D1002007F03DF9DAF847 -:10C5AC0008002E4D10F0010807D12D4F286A816824 -:10C5BC00384688470428F9D0064640461DF029FB2A -:10C5CC00B8F1000F08D1012E04D1286A012142686C -:10C5DC00234890471CF04CFF286841692046884747 -:10C5EC009AF8540118B14FF480601DF0ADF99AF827 -:10C5FC00530118B14FF481601DF0A6F919480121BF -:10C60C00016003200021CAF834011748016020465C -:10C61C0015F0FAFB0128FAD1144E3068042019F0F9 -:10C62C0085FA044612480125B9F1000F05603068FF -:10C63C0002D1012007F0F0F81DF039FB082019F0A9 -:10C64C0075FA0443CAF8345118BF4FF0FF341BF08D -:10C65C0011FB2046BDE8F087D81B0020B801001064 -:10C66C0000400340282008600C2008402C20094082 -:10C67C000C4009407CB54B4EB068016CD0F8D4200E -:10C68C00096892F8835019B9D0F84C058047B06806 -:10C69C00D0F8B800007800B315F01AFE43494248B0 -:10C6AC0009680068096C884705461DF09FF8044628 -:10C6BC003F48017811B93F49097821B33E4902221C -:10C6CC000A700078832808BF12F084FF1DF064FB09 -:10C6DC001DF06DFA0420884757E01DF087F80446DA -:10C6EC003348017811B933490978C9B30222324968 -:10C6FC00012D0A7004D10078832808BF12F06AFF5C -:10C70C001DF04AFB41E01DF052FA00208847B0684A -:10C71C000DF10701D0F82824F42090479DF907006B -:10C72C00854223DB254D287800BB1DF035FB2548C1 -:10C73C000078042803D0B068D0F84C0580471E4818 -:10C74C00042101702878013028701DF030FA09B1ED -:10C75C00032088471C48032101801DF01DFC14E0B8 -:10C76C001548832101701DF017FB0CE01248832142 -:10C77C000170002017F022FE1DF00EFB1048F1682E -:10C78C0080780969087016F099FBF068C068007829 -:10C79C0000B17CBDB0680021D0F85824002090472F -:10C7AC007CBD00BF0C010020E4260020347A002060 -:10C7BC00B07A0020B37A0020B87A0020B527002088 -:10C7CC002D260020BB7A0020C67900202DE9F84FD9 -:10C7DC00494C1021207816F0EFFD28B92078102153 -:10C7EC004FF47A721DF0EDFA44480178013901706A -:10C7FC0009065AD043484FF000084FF6FE79002640 -:10C80C00041D41480578AE421DD22078C0B1FF28E6 -:10C81C0016D001382070000612D16078032807D199 -:10C82C0034F8041C34F8020C022211F031F8607850 -:10C83C0001281EBFA4F8018024F8029C24F8049C53 -:10C84C0008340136DFE73148DFF8C4A0314C4FF033 -:10C85C000008002790F800B05F4519D007EB87005F -:10C86C000AEB4005287A0138287200060ED12046C2 -:10C87C00294619F0A3F9064610B1304619F09CFE72 -:10C88C00002EF4D185F80080A5F802900137E3E77B -:10C89C0021482249007830B10A780AB1013A0A706D -:10C8AC0008310138F7E7BDE8F88F154900220978FF -:10C8BC000170002005211AF001FB04460626002C0D -:10C8CC0098D020460521002225461AF0F7FA044696 -:10C8DC0028890028F3D0013828810004EFD1688919 -:10C8EC00400702D5287B18F029FF2868F0216E73C9 -:10C8FC00407B15F037F8E2E79C7A00202F79002076 -:10C90C00DCBA02004C500020D6BA0200D5BA0200A4 -:10C91C00B25C0020AF1B0200D7BA0200503D0020D1 -:10C92C002DE9F04F85B006464D48DFF83C91144692 -:10C93C000D464FF6FE774FF6FE7800780190494889 -:10C94C00007804900120029000200390474800F1E9 -:10C95C00110B47480430009099F800C04FF0000EBE -:10C96C000020C00774D1049B5946C14603B331F86B -:10C97C00118CB84518BFB04502D11C31013BF5E70D -:10C98C00A84518BFA045F8D00A78501E0628F4D840 -:10C99C00072A01D1C146F0E702980EF1010EC0073B -:10C9AC00EBD103985FFA8EF2C0B28242E5D351E02C -:10C9BC00BCF1010F2AD8DDE9001ABAF1000F25D01D -:10C9CC0031F8048CB84518BFB04503D12431AAF115 -:10C9DC00010AF2E7A84518BFA045F7D04B79581EBD -:10C9EC000628F3D8087801380228EFD3072B01D199 -:10C9FC00C146EBE702980EF1010EC007E6D1039891 -:10CA0C005FFA8EF2C0B28242E0D323E0C8465FEAFE -:10CA1C000E6002D00398000603D00120B845A0D0C8 -:10CA2C0018E000205FFA8EFADFF83C9002900120AB -:10CA3C00BAF1010F03903FF48FAF1DF0E5F8C0B2CF -:10CA4C00B0FBFAF101FB1A0003900020029083E77F -:10CA5C004FF6FE781FFA88F005B0BDE8F08F00BFE6 -:10CA6C00E3BA0200D1BA020024260020305600207E -:10CA7C00204500202DE9F04395B0044600208DF8A8 -:10CA8C001F00208817F052F9002840F081804B4895 -:10CA9C00007810B14FF0B30908E0A078042803D156 -:10CAAC001CF016FC002876D04FF0B60900261E208C -:10CABC001AF03EFC0546BEB303209DF852108DF8CB -:10CACC001E0010A808AF08303A4610F077FF0CAEE5 -:10CADC000DF11E0008213A46334612F097FBA06870 -:10CAEC00314610221BF0F6FBE0B11FFA88F702AEBC -:10CAFC000420002214233946009619F089FD9DF973 -:10CB0C001B00B0F1FF3F03DC06F1130017F02EF809 -:10CB1C000220394614228DF8180002AB042019F0BB -:10CB2C008DFD01E04FF0AD09B9F1000F17D09DF864 -:10CB3C001F00012813D19DF953100020CDE91000DE -:10CB4C00002903D401208DF85100FF208DF85000EE -:10CB5C001FFA88F110AB0420142219F06FFDBDB13F -:10CB6C00092085F81D900822287020886880A078FC -:10CB7C002871681D61681CF063FCA16805F10D004B -:10CB8C0010221CF05DFC0E482946007812F0E6FAE3 -:10CB9C0015B0BDE8F08360680DF11F0110AA0CF010 -:10CBAC00D1FD80469DF81F0018B14FF000090126F9 -:10CBBC007DE74FF0AD09002679E700BF2426002061 -:10CBCC009D7A00202DE9F843DFF830810C46914620 -:10CBDC0007462246B8F8241013F0A4FB002879D09D -:10CBEC00068905464FF6FE70864204BFC320BDE899 -:10CBFC00F8831CF031FE864204BFC220BDE8F883E6 -:10CC0C002988B8F8240088421CBFA8F824100846CC -:10CC1C0015F080FBE87A3946013088F8380008F1C5 -:10CC2C0039001DF016F902208DF80100684619F044 -:10CC3C0051FF002851D007460069062101260170DA -:10CC4C0098F80E104170BE771CF050F978624020B5 -:10CC5C00BE7687F81890F88228897880384611F0CB -:10CC6C00C5FE002845D1092008F11A0188F82600D4 -:10CC7C002889A8F81A0098F81800A04218BF88F85C -:10CC8C0018401F4C4B20A04708F124015020A0470E -:10CC9C0008F11801E120A04708F116015320A04724 -:10CCAC0008200121FEF7E0FD4FF400500021FEF7B3 -:10CCBC00DBFD144C4FF48061207812F08DFE13488C -:10CCCC00007802280BD110480078012807D14FF4C6 -:10CCDC00DC6208E0CA20BDE8F883102009E00820D7 -:10CCEC000EF0FCFF820020784FF480611DF06CF890 -:10CCFC000020074900220A70BDE8F883A86D0020C7 -:10CD0C00892102009C7A0020E5270020242600209F -:10CD1C00A27A0020F0B58DB00546007C0F2873D3A5 -:10CD2C006E68686908AC0021224613F023F89DF860 -:10CD3C002000002868D1287C0B2865D3307A022883 -:10CD4C0062D1B189C8B2FF285ED19DF8220010F0E3 -:10CD5C00FD0F59D1404F97F8263043F00402062AB4 -:10CD6C0004D13E4A1268AAB1C90B1FE03B4A1268B3 -:10CD7C0012B19579012DF4D0082B01D0042B43D19D -:10CD8C007589002A42D0917902293FD1284618F0A2 -:10CD9C00E5FE39E0727C7189308800230093002312 -:10CDAC00FBF758FEB089C10B9DF8220032888DF834 -:10CDBC000D10B17B9DF824308DF810009DF8255096 -:10CDCC009DF83200ADF8082072898DF80C109DF892 -:10CDDC0021108DF80E308DF813508DF81400ADF82D -:10CDEC000A20727C9DF826608DF81110E11D8DF8DB -:10CDFC0012208DF80F6002AD082205F10D001CF019 -:10CE0C001FFB28461DF072F80DB0F0BDB98CA9427D -:10CE1C00FAD1012806D0E11D07F139001AF097FD6F -:10CE2C000028F1D10E484FF40071007816F0C4FAC6 -:10CE3C000028E9D140F20120ADF80D00B86A02904B -:10CE4C0097F82E008DF80C0002A812F003F90028B8 -:10CE5C009CD01AF05FFED7E7A86D0020D8260020E2 -:10CE6C009C7A0020F0B59DB04668077A10AD044658 -:10CE7C00342128461CF04CFF8DF84070294636F8BA -:10CE8C00020B16F0E5F902201A9604F128018DF830 -:10CE9C004100608EADF84E009DF8400002388DF8D0 -:10CEAC005C0006A81CF0D9F99DF8420003287AD141 -:10CEBC009DF843501CF0CAFC854274D19DF8440087 -:10CECC00002870D19DF8450000286CD19DF84600D3 -:10CEDC00002868D19DF85D00002864D19DF84700BA -:10CEEC00002860D19DF8480000285CD109A81C21BD -:10CEFC001CF00EFFBDF84E001A9A9DF85C30ADF890 -:10CF0C002E00154615F8010B00F003018DF82400D6 -:10CF1C00032916D100F00C060C2E05D0082E08D1D2 -:10CF2C0001268DF8306004E0B2F80150ADF82850BD -:10CF3C00D51C35F8046BADF82A6035F8026CADF8E9 -:10CF4C002C60521B0D951344524203298DF8383036 -:10CF5C008DF8312027D100F00C01042923D010F0DA -:10CF6C00200120D140B200281DD4FE209DF8531082 -:10CF7C00B4F8422000238DF827000C4840788DF837 -:10CF8C00260094F846008DF81400B4F84700ADF86C -:10CF9C001500E06BCDE90013CDE9020309A806A941 -:10CFAC0005AB08F0E7FD1DB0F0BD00BFCC2600209E -:10CFBC002DE9F047DFF83491D9F840A0BAF1000F11 -:10CFCC0000F088800AF10C020820FF2151FA80F051 -:10CFDC00C3B21B1A18BF012312686AB163B113885C -:10CFEC00A3F60303012B01D90432EFE7DAF81000A2 -:10CFFC0092E8FA003830FAC0DAF808200025DAE9AD -:10D00C000A10CAE90A55B2B110F0E2440CD021F072 -:10D01C000F0220F0E2434FF0000852EA030005D063 -:10D02C001CF030FBB04701E0884604461CF02AFB9C -:10D03C0042462346B0471CF0D9FB0446B9F85600CB -:10D04C0001306FF31F30A9F856004FF6FD70AAF8A7 -:10D05C00300009F140008AF833501AF001FC2046E8 -:10D06C001CF07FFEB9F85600B9F85410884231D143 -:10D07C001F48204940680D6830B190F8FC2007200B -:10D08C00002A08BF052000E005204C680FF01EFDAB -:10D09C0055B195F8FC00002100284FF0000008BFA6 -:10D0AC00286885F8FC1000E0002044B194F8FC20BE -:10D0BC000021002502B9256884F8FC1000E0002549 -:10D0CC00A84288BF0546681C04D02DB9BDE8F047BE -:10D0DC001BF01CB9BDE8F0871CF0E0FEB5FBF0F1CD -:10D0EC000548BDE8F0471BF06FBC00BF30210020A5 -:10D0FC00D01E002070200020387100202DE9F04750 -:10D10C004FF6FC76B04201D100240FE08846002196 -:10D11C001D469246002414F0E5F9DFF810910746FD -:10D12C00680606D4B9F81600874202D12046BDE83D -:10D13C00F087384629460CF01BFF30B9B01C002193 -:10D14C0080B20CF015FF00285ED0B11C078089B2AC -:10D15C00884505F0010118BFA0F8028045EA81015D -:10D16C00BAF1010F817140D101214171324915F0A1 -:10D17C00180F99F8142018BF0A7802714046B9F8B4 -:10D18C00241016F053FB0028BED12A482B49DFF897 -:10D19C00B0C0274D0022007809788A42B4D0C2EB87 -:10D1AC00C20400260CEB8404B0420BD005EBC6077E -:10D1BC0023887F889F4201D00136F5E70132F3B214 -:10D1CC009842EAD120461C211CF0A2FDB9F824009B -:10D1DC00A4F8008060814AF60120A4F811001948D7 -:10D1EC0000780130400820748EE7417901293FF422 -:10D1FC008BAF114915F0180F08BF09F1130109780D -:10D20C0080F805A001717FE715F0180F0CD00949C3 -:10D21C0007480978063039B110F8082B013912F09B -:10D22C00180FF8D10E3890E702247FE7A86D002084 -:10D23C004C500020D6BA0200D9BA0200D1BA020072 -:10D24C0030560020CDBA02002DE9F04186B01D46C3 -:10D25C0014460E46022818D0012818D0002876D182 -:10D26C00012E6BD0022E72D108201AF093FD3E488D -:10D27C000021437B3D48026840480088CDE90211FB -:10D28C0004913F49CDE9004555E0002000E0012024 -:10D29C00032E00D0F6B91CF01BF8032E18BF002883 -:10D2AC0035D102201AF076FD2F48304C417B206896 -:10D2BC0010F0D6FD2E49897801F00801014345D1C3 -:10D2CC002C48017801310170C8B2042849D12A4890 -:10D2DC00206046E0711E80F0010018BF0121084358 -:10D2EC0035D10A201AF056FD26484FF4806100789B -:10D2FC0012F072FB0DF11601502018F0FDFF2249BF -:10D30C00BDF81600888400211CF0E0FD29E01648C9 -:10D31C0090F80D8015480768184806881CF074FCB6 -:10D32C0001210022049030464346CDE90045CDE969 -:10D33C00022113493A4605F0CBFA07E008201AF00F -:10D34C0029FD2046214600221CF022F848B10F4846 -:10D35C0001214FF47A72007806B0BDE8F0411CF060 -:10D36C0033BD06B0BDE8F081CC220020747A0020D9 -:10D37C003E7900209927002000F8FF079027002015 -:10D38C00C02600209C7A0020A86D00209D7A0020E9 -:10D39C002DE9F04F8BB00C460690C9881F460792BA -:10D3AC00E07816F08FF900287ED0217D0546C0B2BA -:10D3BC0019F0E4FE002879D00646E188E07805975C -:10D3CC00DDE9177900224FF0000815F0F7FB8346D2 -:10D3DC00E0787071E188A07D86F80880227DF1806C -:10D3EC007081F06821691CF02BF886F81490778214 -:10D3FC004FF000090027BBF1000F4AD05FFA89F00B -:10D40C00854246D906EBC00A9BF80110504600F83D -:10D41C00168F012904D101270770BBF8020005E023 -:10D42C00BBF802008AF81D001BF0AAF9AAF8180034 -:10D43C0022789BF8041052068AF81A1005D59AF82F -:10D44C001C2042F002028AF81C20C7B9204AD28A5A -:10D45C00904214D11E48A170DDE90613CDF800806E -:10D46C00828C159801901698CDE90208204608F098 -:10D47C0081FB9AF81C0040F005008AF81C0009F1A9 -:10D48C000109E188E0785FFA89F215F097FB834691 -:10D49C00B1E7304619F0E8F80599DDE91423204688 -:10D4AC000096F9F71FFF10E0B92000E010208DF86E -:10D4BC002800E078A17D8DF82300E0888DF82410F9 -:10D4CC00ADF8260008A81BF0B7FC0BB0BDE8F08F38 -:10D4DC00A86D00207CB50568002D6DD0044647482A -:10D4EC00026842B1217928469047012803D1688906 -:10D4FC0020F001006881687B02282DD168898007A3 -:10D50C002ED52079CD282BD0F02829D0688A00067A -:10D51C000CD5A87E50B1A8732868008816F006FCBC -:10D52C0040B94FF498700DF062F803E0344800787D -:10D53C000130A8732079002856D00420202168736C -:10D54C00304800882881A87B0138A876A8732E481B -:10D55C00007810F0D5FD687B40F0040006282BD134 -:10D56C002B49288BC98A884214D02849097889B15B -:10D57C0029680988ADF8000001208DF80500287B8A -:10D58C00ADF802108DF8040020798DF8060068467D -:10D59C001BF0E2FD6889C0070ED0217928461BF0EC -:10D5AC0016F9688920F0010068812868008816F057 -:10D5BC00BDFB217908B121B17CBD39B140F23110EC -:10D5CC0001E040F22D100DF012F87CBD40F22F104E -:10D5DC000DF00DF8002560798542EDD24FF49B706B -:10D5EC000DF005F80135F6E7002660798642A4D2E5 -:10D5FC004FF49B700CF0FBFF0136F6E7382400204B -:10D60C00C62700208C2700209C7A0020E9250020CA -:10D61C00A86D0020BFB54A4D044695F82600092890 -:10D62C0000F28C80012101FA00F040F20A2108423C -:10D63C0000F084806178F1B141F2030019F0A9F98E -:10D64C004048007802280ED13F4801780B2904BFCE -:10D65C000A2101703D48002101703D484FF4804182 -:10D66C00007812F0B9F96178A88C1CF02FFC00201E -:10D67C0085F8260060E00220002119F08AF934F8C0 -:10D68C00020FE8825320214614F078FD95F826000D -:10D69C00092802D0A88C14F03DFE01200DF10F01D9 -:10D6AC008DF80F00422014F069FD04200DF10704E1 -:10D6BC0085F826004A20214618F01EFE05F11C00B4 -:10D6CC0021461CF0C6FB204801780B2902D106210B -:10D6DC00017003E0A88C00211CF0F8FB194C207899 -:10D6EC0002280AD2688B4FF6FE7188420ED00DF1DB -:10D6FC0007010022FEF7EAFA08E007D1E98A0320C5 -:10D70C0019F047F9698B042019F043F9A87B0DF146 -:10D71C000F01C0F3C0008DF80F00522014F02EFD45 -:10D72C002078022808D1A87B00074CBF4FF400409A -:10D73C0001200121FEF798F81AF054FFBFBD00BF7D -:10D74C00A86D002024260020D0260020DC270020F5 -:10D75C009C7A00202DE9F0418846080430D45FEA19 -:10D76C00C86000F181805FEA887000F182805FEA16 -:10D77C00087000F1818018F4706F00F082805FEA0D -:10D78C00085004D500201BF0B3FA88F400685FEA57 -:10D79C00485004D501201BF0ABFA88F480685FEA8E -:10D7AC00885004D502201BF0A3FA88F400785FEAB5 -:10D7BC00C85068D503201BF09BFA88F4807862E08F -:10D7CC00324F387811F06EF900284AD00546466879 -:10D7DC000078411E05290DD91A282CD024282ED0CA -:10D7EC00D12833D0D32835D0FD2836D128461AF08D -:10D7FC006EFC32E0DFE801F0030B310F311B66B336 -:10D80C00304611F0FBFB30461CF076FB25E0284639 -:10D81C0014F090FE21E0F478701CE11CC9B21BF0EE -:10D82C0087F9611D56FA81F101F8010C15E02846C3 -:10D83C001BF03AF811E02846FDF75AFF0DE0F0789E -:10D84C000530C1B230461BF0E3FF06E028461BF062 -:10D85C00EBFF02E0284611F06DF828461AF046FC62 -:10D86C00AFE788F400480EE01AF004F988F01008CD -:10D87C0009E088F0020806E00DF0D0FA88F00808FC -:10D88C0001E04FF000084046BDE8F0819A7A002094 -:10D89C0070B50C4608041CD4E00729D14448007824 -:10D8AC00012805D8A00745D4A00654D4600474D42C -:10D8BC00E0062DD4200744BF84F0080070BDE005BD -:10D8CC003DD460075FD400202146BDE8704009F0CC -:10D8DC00E3BB344E307811F0E5F830B1054607F073 -:10D8EC00DBFA28461AF002FCF4E784F4004070BD21 -:10D8FC0001201AF04FFA2C480F220F2381782B4865 -:10D90C00008800F00700FFF79FFC84F0010070BD59 -:10D91C002548007810F0B4FC28480078012806D17E -:10D92C0027484FF40061642200781CF04DFA84F013 -:10D93C00100070BD0AF098FA84F0020070BD214806 -:10D94C0090F82600082801D0042801D11BF032FBE6 -:10D95C0084F4807070BD1748007860B91248007864 -:10D96C00062802D107201AF015FA1348007801286E -:10D97C0008BF19F0D9FD0B481021007810F0C0FB3E -:10D98C0084F0200070BDFF20032116F07BF81CF002 -:10D99C008AF90D4801210160FEE714F045FB84F47F -:10D9AC00804070BD9D7A0020D02600203E7900205A -:10D9BC0024260020BF7A0020CA270020CD27002073 -:10D9CC009C7A0020A86D00207C0520432DE9F84F9F -:10D9DC004FF00054002A994616460F46804618BF51 -:10D9EC004FF080444D1C1BF001FF824635B1404680 -:10D9FC003946002214F090FA07460FE03C48816C3F -:10DA0C0011B10969414506D0C16C11B10969414593 -:10DA1C0003D0876B02E0876C00E0C76C37B197F9D5 -:10DA2C003300B0F1FF3F03DD04245BE0032459E035 -:10DA3C00DFF8BCB00A9DDBF84800874218D0DBF851 -:10DA4C004C00874229D0404639464A462B460BF0BB -:10DA5C0015FC0028E8D02748017E012941D0007E22 -:10DA6C0004283ED02448254928301CF05DFA38E0C3 -:10DA7C00DBF848000022234619F0CCF81BF046FFD7 -:10DA8C001F48002E18BF00F580301AF063F8F5B16E -:10DA9C00DBF848001CF0AEF80CE01BF037FF184820 -:10DAAC00002E00F100501CBF0120C2F202401AF0FF -:10DABC0051F865B1DBF84C001CF09CF838690E4944 -:10DACC00086291F8240040F0010081F82400B9F1BB -:10DADC00000F06D0DBF83810404601222B460BF025 -:10DAEC00CDFB832450461CF03CF92046BDE8F88F52 -:10DAFC0030210020D01E00207020002002000040A9 -:10DB0C0001000104F0B58DB0044603200D468DF8DC -:10DB1C0030000AAE30461CF09CF91BF0E7F90146C8 -:10DB2C00304619F014FF50B1287D40F00201032952 -:10DB3C0005D1297A09B1FF2914D1822000E0842073 -:10DB4C008DF82700E289207C0DF127010123CDE916 -:10DB5C00001004F11100A11C42F4004213F0E2FD8C -:10DB6C000DB0F0BD032804D1A87DFF28E5D0002816 -:10DB7C00E3D0304F4FF0FF300822CDE9060006A964 -:10DB8C003E1D30461AF0A6FB18BB2B486188C08A94 -:10DB9C0081421ED03878FF280AD0297A814207D0DA -:10DBAC0078884FF6FF71884202D06989884210D17B -:10DBBC000020314608228DF8080002AF381D1BF0FA -:10DBCC003FFC38460DF05EFD6088BDF80A108142BE -:10DBDC002DD1E08905F10C0621281CD18C206989F6 -:10DBEC00AB7D32468DF82700287A17F04FFB0028C2 -:10DBFC00A8D11BF0F5FF287D0328A3D102A930463C -:10DC0C0017F074FB00289DD1304600210022002320 -:10DC1C0010F066FB96E76989287AAB7D32461AF0DC -:10DC2C00BFFA08B188208BE71BF0DAFF8AE78D205A -:10DC3C0086E700BF0C260020A86D0020F0B589B047 -:10DC4C000546002001F108060C468DF80F00304601 -:10DC5C001AF02EFA18B9284631460DF02BF804ADFF -:10DC6C000DF10F0130462A460BF06CFD3B4E4FF682 -:10DC7C00FF7731784A1E9DF80F10012A10D879B918 -:10DC8C0000200DF10F01CDE90000684604AA0BF04D -:10DC9C0059FDB8421ABF01218DF80F109DF80F10D5 -:10DCAC00B1B1B84214D09DF8201099B3FF2926D0F9 -:10DCBC00022918BFFD2912D12A4900EB400001EBC3 -:10DCCC008000A16950F8042F91420FD2A22042E0AB -:10DCDC00307810B91BF098FEC0B1A1203BE00129AF -:10DCEC0038D130780138012806D90FE001310160B4 -:10DCFC003078411E02291ED24FF0817007E0307837 -:10DD0C00013801289CBF012084F826001448C4F86F -:10DD1C0012001FE0052060829DF8230000F07F00B8 -:10DD2C00A08212480078002818BF012084F8270030 -:10DD3C0084F826000EE030B90B48C4F812009DF8A8 -:10DD4C00220084F8280004F11E0005F108010822C5 -:10DD5C001BF076FB002009B0F0BD00BF242600208C -:10DD6C0000000301F033002000000101A427002073 -:10DD7C002DE9F047816A91F90120002A28D48246C6 -:10DD8C0002F01F0000EB40049AF81C300234A3424E -:10DD9C001ED18B1CD2B24FF6FE784FF6FE7C08B12A -:10DDAC00B1F802C0DFF8F49000264FF6FE770021A0 -:10DDBC00B9F81650814210D29C7814F0880F07D114 -:10DDCC0033F8037BAF4208BF04F007060131F1E7DB -:10DDDC00D320BDE8F0470CF00ABC300606D11FFA80 -:10DDEC008CF0B9B214F0EAFF002849D0BAF80C0054 -:10DDFC001BF051FF80B10021027AC17128490978CA -:10DE0C008A4206D3013149080172F1B2072938BFA1 -:10DE1C0001364672BDE8F08708F10101BAF80C0032 -:10DE2C0089B217F0C9F820B105461D48297C007845 -:10DE3C0015E015F0DDFC18B31C2105461BF068FF3E -:10DE4C004AF60120A5F81100BAF80C002880B9F8A0 -:10DE5C002400688112480078411C490829748142C9 -:10DE6C0006D3013040082874F0B2072838BF0136B9 -:10DE7C0000206E742873023528461AF019F908B17F -:10DE8C00BDE8F0879AF808000028F9D0DAF81810E5 -:10DE9C002846BDE8F0471BF0DCBF00BFA86D002092 -:10DEAC00CDBA02002DE9F84F1D4600928B468146F3 -:10DEBC001BF09CFC444A82464FF4A06000210127D1 -:10DECC0005F1010C002392F86040602935D007FA67 -:10DEDC0003FE1EEA040F0AD0BCF1000F18BF9D42CE -:10DEEC0005D1561896F80A80B8F1000F04D02031ED -:10DEFC0000F580700133E8E724EA0E040125737203 -:10DF0C0082F8604092F86240B572013482F8624047 -:10DF1C009EB142F801902D49BBF1020F86F808B072 -:10DF2C00716011D0BBF1010F34D1591DB1740A21AC -:10DF3C0031820A99896871612CE0FE2450461BF0ED -:10DF4C0010FF60B2BDE8F88F718A5A1D0A9B02F06F -:10DF5C000F0221F4706141EA0221718221F0F80173 -:10DF6C005A7902F01F0241EAC201718221F4C041C8 -:10DF7C009A7902F0030241EA423140F203623282A2 -:10DF8C0071824EF6FF721140DA7902F0010241EA19 -:10DF9C00023171820B9A42B111785278920042EAA6 -:10DFAC00411108430A49084300E000200099B06180 -:10DFBC0001B171600748416809B9C0F804900FF0CD -:10DFCC0003FC747ABAE700BF206E0020236E0100B8 -:10DFDC0001000406D01E00202DE9F04F8BB04A4FF3 -:10DFEC00B868D0F80001807AC0001BF087FF0028C9 -:10DFFC0009907DD000244FF6FF7B1BF0F7FB0090BF -:10E00C0001AD0DF114094FF0FF3AB868A2B2D0F887 -:10E01C0000110B899A4263D24FF001080026C97A8D -:10E02C00F2B28A4222D2D0F88824D02029468DF828 -:10E03C000660ADF80440904720B1B8680136D0F8BE -:10E04C000011ECE79DF810004FF000080128F4D106 -:10E05C009DF80F000028F0D103200B2809D0295C73 -:10E06C000130FF29F9D04FF00008E6E7B8F1000FB6 -:10E07C0001D00134C9E70026B868F1B2D0F800210C -:10E08C00D2888A42F5D9D0F88824ADF80610D12070 -:10E09C002946ADF80440904700BBBDF80800584530 -:10E0AC001CD0ADF81400B8684946D0F88824D420A8 -:10E0BC009047F8B9B8684946CDE907AAADF81AB047 -:10E0CC00ADF818B0D0F89424D4209047B8682946FD -:10E0DC00ADF808B0D0F89424D12090470136CBE7A6 -:10E0EC0000981BF03EFE09981BF006FF002008E08C -:10E0FC001A2006E000981BF034FE09981BF0FCFE79 -:10E10C0019200BB0BDE8F08F0C0100207CB5044643 -:10E11C008078022820D0012840F08C80267D0020B9 -:10E12C008DF8060006F1180019F002F9054610B931 -:10E13C0001208DF80600607940F00200022824D1FD -:10E14C00002D4CD0E078002818BF01201BF08CFA71 -:10E15C0023D01BF06DFA25E000208DF807002C2051 -:10E16C0019F0E6F8054610B901208DF80700607922 -:10E17C0040F0020002280CD1002D54D0E0781BF0A6 -:10E18C0073FA31D01BF054FA33E002208DF80600FC -:10E19C0025E002208DF8070045E0A01D042118F0B1 -:10E1AC00E7FAA860A07C32462874E07C6874207D75 -:10E1BC0015342146A87505F117001BF041F9A05D37 -:10E1CC00A874A01941786975817829750521C078E2 -:10E1DC0029802946E8741848007810F0BFFF0DF12B -:10E1EC0006037520012122E0A01D042118F0C0FABD -:10E1FC00A860A07C04F1150110222874E07C28751D -:10E20C00207D687505F11C001BF01AF904F125003E -:10E21C00042118F0ADFA0821A86107482980294685 -:10E22C00007810F09BFF0DF10703752002210122ED -:10E23C0014F0A4FA00207CBDA87A00202DE9F04F40 -:10E24C008BB04248DFF80CB100240DF11C0A4FF0E2 -:10E25C0000084FF0000900270078019000EBC00087 -:10E26C0086003B48007801304008029046455CD05F -:10E27C001FFA89F1032000221023CDF800A018F01A -:10E28C00C7F900284CD19DF821300BEB0801BDF8E3 -:10E29C001C009DF820200C82CC60CC724B714AF68D -:10E2AC0001232BF80800BDF81E000A71A1F80930F3 -:10E2BC00029B48800B72BDF82230CB800A9B5D1C00 -:10E2CC0004D081F82040C1E9063315E0013A012A57 -:10E2DC0009D8214A12784AB1204B53F82220C2EBBC -:10E2EC000212920004E06FF0010203E01B4A126874 -:10E2FC0081F820408A61CA614FF6FF7188420FD0C5 -:10E30C00ADF8180001208DF80C0003A811F02AFEBE -:10E31C0028B11348818CBDF81C0017F0C6FD0137DD -:10E32C0008F1240809F10109A0E7002004210024C8 -:10E33C0015F054FC0199884224BF0A48047006F079 -:10E34C0013FBF8B20BB0BDE8F08F00BFE3BA0200CC -:10E35C00CDBA020020450020D827002090B402003E -:10E36C00A86D0020972700202DE9F041414F04466D -:10E37C007878C8B1DFF80081B8F85400B8F85610B6 -:10E38C0088421ED008F13801204619F07AFA80B97B -:10E39C00D8F8480010B10069A04207D008F140013C -:10E3AC00204619F06EFA03E0BDE8F081D8F8480079 -:10E3BC0038B1B0F9301020460A224FF0E04307F094 -:10E3CC0045FF1BF013FA2D4D0646284602C8A14204 -:10E3DC0008BF284600210160787801387870000663 -:10E3EC0036D17C60387E02280ED1082016F040FB16 -:10E3FC0030461BF0B6FC04F150004FF0FF311BF01F -:10E40C0017FC1BF0F3F9064605F128001BF08AFDFA -:10E41C0040461BF04FFD1A481BF084FD08F11C0010 -:10E42C001BF048FD17481BF037FD17481BF034FD57 -:10E43C001648416811B107F15000884707F12800D0 -:10E44C0019F028FC1248807810B10D2007F0A8FEB6 -:10E45C007868A04204BF0020786030461BF081FC35 -:10E46C0004F150001BF05AFD04F1B800BDE8F04176 -:10E47C001BF012BDD01E0020302100207020002087 -:10E48C00407200207C710020387100208026002012 -:10E49C009CB902002DE9F0478EB080460E2016463E -:10E4AC008A468DF81A308DF818208DF81900012045 -:10E4BC008DF81C003E48B8F1000F077B8DF81B70DF -:10E4CC0020D00AEB0605687B11F014FE034620F001 -:10E4DC00010000243A280AD10DF104090020112171 -:10E4EC004A4619F0A3FE002808BF09F10104287858 -:10E4FC000994384305F8050B0DF12B0029461BF048 -:10E50C00A8FC36E001AD002011213A2300242A4654 -:10E51C0019F08CFE08B109942BE0DFF898906C1C74 -:10E52C00012101220994D9F80430581CC9F80400BF -:10E53C000AEB06000090384612F031F81AF0D6FCBF -:10E54C0001460DF12B001BF084FCB9F800001A49B0 -:10E55C0001300968A9F8000080B2814203D3D9F8D0 -:10E56C000400012805D115484FF4007100780FF014 -:10E57C00C7FD0DF12B000AEB06050422691C0830BF -:10E58C001AF05EFF1AF806008DF837005CB106A988 -:10E59C000DF12B024046534606F05EF8297801F047 -:10E5AC00F801297000E0A1200EB0BDE8F08700BF93 -:10E5BC00A86D002014250020A8BA02009D7A002026 -:10E5CC002DE9FE431BF012F9DFF80C91804699F807 -:10E5DC000100B8B14148032201688260C80711D01C -:10E5EC003F4C2068416802208847019020684168B0 -:10E5FC000120884702903B4801A91C3011F09AF881 -:10E60C0017F09EFDD9F80450EDB13649686A01AF98 -:10E61C0001F11C06A96A884219D23046394612F01B -:10E62C00D5F9013011D0D5E90912E869541A08441A -:10E63C003946082C28BF082422461BF085FC686A42 -:10E64C0020446862E6E700240CE0D5E909010024C7 -:10E65C00884207D309F10400294618F0FFF985F820 -:10E66C003240012499F8010088B9D9F8040018B196 -:10E67C0080681AF069FB0AE01A481C301BF025F878 -:10E68C0028B9194A4FF0FF30012110F067FA4046C3 -:10E69C001BF067FBF4B1A86800220168CA628A69A2 -:10E6AC000AB10223137091F83030012B07D0022BE2 -:10E6BC0010D101F134001BF033FCBDE8FE8322B114 -:10E6CC00CB6800219847BDE8FE830C69CA698B6A48 -:10E6DC000021A047BDE8FE831823002008800240DB -:10E6EC00CC0100107422002080A9030070B586B004 -:10E6FC00454D0446A868D0F8F41091F84420B2F1C6 -:10E70C00820318BF531C81F84430D0F8F40090F801 -:10E71C00441000EBD10090F82C104A0880F82C2003 -:10E72C00C807A86809D1D0F8F41091F94420531CFB -:10E73C0012F1020F81F84430E7DCD0F8F4201146D6 -:10E74C0011F8443F802B25D8D0F83024E120904795 -:10E75C00AA6802208DF814004FF0FF30D2F8F43084 -:10E76C00ADF80C009878022823D0012824D030BBB7 -:10E77C001BF094FB4FF47A71244B0022B1FBF0F0A8 -:10E78C0023490BF0B5FBE0B3A8681A21D0F8F400CC -:10E79C00417004E0907810B91C4814F04FF82A200E -:10E7AC002070A868D0F84013204606B0BDE8704031 -:10E7BC000847D2F86814F7E70820802101E0072009 -:10E7CC008321D2F8786303F149020023CDE90032AA -:10E7DC0003AA4FF6FF73B047A0F1DB01182910D83C -:10E7EC00012202FA01F10B4A11420AD0A968D1F8B0 -:10E7FC00F41048702A202070A868D0F840132046E6 -:10E80C00884706B070BD00BF0C0100205C7A002068 -:10E81C003D2D0100112400012DE9F04389B004467F -:10E82C004648807860B9E07AFE2809D168462421F0 -:10E83C001BF06EFA208B10F00D0F06D0B62400E002 -:10E84C000124204609B0BDE8F083207A0028F5D0D9 -:10E85C0001288DF8080011D002281CD003281ED0E6 -:10E86C000F2820D102204FF000080B264FF0000992 -:10E87C008DF808002088ADF8000019E0B4F800808D -:10E88C004FF6FF700F26ADF8000002204FEA182952 -:10E89C008DF808000CE02088ADF8000003E0684615 -:10E8AC0021461BF0D6FA4FF0000803264FF0000962 -:10E8BC0006F00C0707200C2F08BF0920A17C084488 -:10E8CC008DF81F00C0B21BF019FBA0B305460C2F2E -:10E8DC000890867011BFE81C85F8049085F80380B9 -:10E8EC00681DA17B0170E17B4170217C8170617C92 -:10E8FC00C1700430628A61691AF0A2FD1AF0A6FF99 -:10E90C0081098000033069702870B7FA87F04009DC -:10E91C00ADF80E0003208DF80C00A07E8DF80D00D4 -:10E92C00A089ADF80A0068461BF078FA0446284620 -:10E93C001BF0E2FA85E7102483E700BFCC26002009 -:10E94C002DE9F04F85B0054691460E46C80731D1EA -:10E95C002846314612F0C6FD404FF98A884242D013 -:10E96C002846022132460CF0C1FBE0B328464FF694 -:10E97C00FE7102223346FEF7C1FB90BB4FEA15280D -:10E98C0006F0DF0A70061ED402A9284617F0BEF95D -:10E99C0068B9B98C284616F00FFBA0B1871C384615 -:10E9AC0019F086FB78B102A839461BF052FA46F0F2 -:10E9BC00200A08E0B0074FF0FF084CBF46F0100AE1 -:10E9CC0046F0080AFC25264800220778791C0170BD -:10E9DC002248012100913946C08A034608F0EAFF1B -:10E9EC0018B1C72037E0002035E01AF020044FF0B2 -:10E9FC000E0008BF06208DF8110004A818F06AF864 -:10EA0C0040B34FF0010B064680F81EB01AF06EFAB8 -:10EA1C0070623069002141710AF078018770C5700D -:10EA2C0080F8048080F800B041701CB1063002A957 -:10EA3C001BF00FFA6FF00300B9F1000F708005D0D6 -:10EA4C0008480078484588BF86F81A9030460FF081 -:10EA5C00CDFF00E0102005B0BDE8F08FA86D0020C0 -:10EA6C00C07A0020CBBA02002DE9F04788B0444DA3 -:10EA7C000A4604461046A98C14F0D8FE40B14178E1 -:10EA8C0031B9072141703F490978013149080170BA -:10EA9C00A06A477817F08F0F18D1F9064FF01002C3 -:10EAAC0058BF0822BB0648BF0832237F93420DD1C2 -:10EABC0090F8029090F80780B0F805A0B0F80360C9 -:10EACC00002909D407F0700708200DE0D32008B006 -:10EADC00BDE8F0470BF08BBD00F1080106A81BF058 -:10EAEC00B8F907F060071020B90606D5A16A0144F1 -:10EAFC0004A81BF0AEF907F05007B6B249463046F1 -:10EB0C0015F0EAFF2049097888421ED21F4900EB14 -:10EB1C00800001EB400010F8061F41452CD980F80D -:10EB2C000080E88A864213D0A1891FFA8AF4012258 -:10EB3C003B462046FEF7E2FAF0B904A806A9029774 -:10EB4C00CDE900103046214612E0E88A864207D112 -:10EB5C00A1891FFA8AF001223B46FEF7CFFA0BE09F -:10EB6C0004A806A90297CDE900101FFA8AF13046D5 -:10EB7C0042464B4603F0C4F908B0BDE8F08700BF2D -:10EB8C00A86D0020CDBA0200D5BA0200B25C0020FC -:10EB9C002DE9FE4F8A4683461AF0ACFDDFF808914A -:10EBAC00DFF8FC803F4E99F8001098F80200B07323 -:10EBBC0039B1000713D501200DF10A018DF80A00B7 -:10EBCC000AE0002000240EF06FFBB07B000706D596 -:10EBDC008DF80B400DF10B01522013F0CFFA0EF013 -:10EBEC0083FF19F02DFF38B105460EF0F3FC13F03E -:10EBFC0005FE0CF051FF08E008F028FF0546307EBA -:10EC0C00012101FA00F0294908604FF6FE74012D2C -:10EC1C002FD10FF0D5FA1AF0F7FF074624482349F5 -:10EC2C0000680860FF20022114F02CFF601C748324 -:10EC3C00F482B084002013F0A3F807F07F0058444E -:10EC4C0000F164061B480078012808D10020BAF1B5 -:10EC5C00010F1CBFCDE90000684615F0B3FA114A4C -:10EC6C00212074211AF02AFF0020022114F00AFF3F -:10EC7C0000E0002628460CF09BFE601C80B2834509 -:10EC8C0007D0012089F8000017F0D8FFB0B219F0B6 -:10EC9C00CBFE98F8020019F0D7FA2846BDE8FE8F93 -:10ECAC003E790020A86D0020D0260020747A002028 -:10ECBC0078270020242600202DE9F0438FB014F093 -:10ECCC0003FB3F4F97F82600082806D00120C7E920 -:10ECDC000C003C480078F87078710DF11408242170 -:10ECEC0040461BF015F839480F25374EDFF8E090F9 -:10ECFC000DF13B018DF83B5000783570013818BF91 -:10ED0C0001208DF81E004620C847324800248DF89B -:10ED1C00004000788DF801001AF098FD8DF8020083 -:10ED2C0097F838008DF80640ADF8034007F139012B -:10ED3C000F2838BF05468DF805506D46E81D1BF0B1 -:10ED4C0088F84FF0FF303278234EADF80F008DF875 -:10ED5C00110097F8720031468DF81200284610F019 -:10ED6C0014FD45203146C84705F0FEFDB88D97F8D7 -:10ED7C002F108DF820408DF834408DF82940ADF8D7 -:10ED8C001C00387E8DF81F1007F116018DF81A0043 -:10ED9C00B88CADF818005320C84707F11A014B2066 -:10EDAC00C847F879642100FB01F20C48082100786F -:10EDBC001BF00AF8404606F03DFA0FB0BDE8F083B0 -:10EDCC00A86D0020E3BA0200B927002024260020F9 -:10EDDC0089210200E8270020207900209C7A00205D -:10EDEC002DE9F0410546880058BFBDE8F0810020B0 -:10EDFC00002410F0DFF93D493D483E4FCC610860DE -:10EE0C0040F60A008846B887FC8797F8480000F05F -:10EE1C00F00087F848003C6497F8490000F0F000D7 -:10EE2C00013087F84900284607F00AFEAC6801203B -:10EE3C0021460E46496849B10A88A2F60302072A00 -:10EE4C00F7D800FA02F212F0830FF2D0707B00F0C8 -:10EE5C00F000707307F13C0070602748806B28B19C -:10EE6C00C0680088A0F6030002281AD3284630F8A0 -:10EE7C00381FB1B10021E9636987386495F8440003 -:10EE8C0095F8451000F0F00085F8440001F0F00012 -:10EE9C00013085F8450097F8490000F0F00087F83C -:10EEAC0049001AF04BF81548F86197F8250030B175 -:10EEBC0017F09CFE0028FBD012F0CCFA0BE00120DE -:10EECC001AF03CFD012806D0707B00F0F0000130F8 -:10EEDC0070730B48F86100202146C8F81C00C8F874 -:10EEEC0000400120BDE8F04118F004BF00100440C0 -:10EEFC0001010E04D01E00203021002095370000A7 -:10EF0C008D0902002DE9F84F0746087A0C4640F0AF -:10EF1C000201032917D10025B7B1FF2F14D09A464F -:10EF2C0016460AB903280ED00FF00AFA204610F044 -:10EF3C00C8FF8146207A4FF6FE71B0F1010B18BF65 -:10EF4C00B346894503D100252846BDE8F88F013822 -:10EF5C00DDF82880314EB0FA80F044092E48017853 -:10EF6C000020814230D03278BA4208D17278A24265 -:10EF7C0005D17288914502D13279934502D00E3673 -:10EF8C000130EEE706B32649C7B23546B1F800901A -:10EF9C00BAF1000FD8D0B8F800402846214619F035 -:10EFAC00BFFA60B92846214618F03CFB30B102206C -:10EFBC0039464A46334617F041FB00E0002508F17C -:10EFCC000208AAF1010AE3E70DF1030017F0ECF9CE -:10EFDC0005460028B8D0134885F804B0A5F802906F -:10EFEC006C702F7041460078504538BF8246A81D82 -:10EFFC004FEA4A0285F805A01AF022FA9DF8031090 -:10F00C00064AC1EBC10002EB40030548028802200E -:10F01C0017F014FB98E700BFDFBA0200307900202C -:10F02C004EB20200CFBA02002DE9F84380460068C8 -:10F03C003B4BD8E9012118603A4802603A4820223B -:10F04C001AF082FFD8F80C003849DFF8E89090E805 -:10F05C00FC00FCC1D8F80C00354990E8FC00FCC160 -:10F06C00D8F81000494690E8FC00FCC1324D402213 -:10F07C0099F80C00D8F8141040F0800089F80C00B6 -:10F08C0028461AF061FFE87BD8F81810202240F0CF -:10F09C00A500E873294D28461AF056FF40F20540AA -:10F0AC00697BAA7CEB7DC5F8049028820320287527 -:10F0BC00287B40F08000287301F0F00020490230DA -:10F0CC00687302F0E0000A460130A87403F0F00007 -:10F0DC000130E875D8F81C0090E8F800F8C2087BFD -:10F0EC00CB7B4A7B40F08000087303F070008430C7 -:10F0FC00C87302F0F000013048734FF45860086197 -:10F10C00D8F820000F4908600F48C06840690078A3 -:10F11C0008B111F005FBBDE8F84315F097BE00BF30 -:10F12C00687A00206C7A0020D87500209077002037 -:10F13C00A8770020C077002000720020B87500204E -:10F14C0048780020647A00200C0100202DE9F0435F -:10F15C0087B0DFF8FC8081462025EFF3118085F322 -:10F16C001188D8F830501DB180F3118800256AE061 -:10F17C00C8F83090374F80F311880020C9F80C1074 -:10F18C004FF48031C9F81C20002BC9E91200C9E9E1 -:10F19C00080118BF1F46D7E90116C9F81810397BAA -:10F1AC00012905D1C9E91060C9F8146030460DE099 -:10F1BC00294A002031460023002519F041FFC9E9F6 -:10F1CC0010012649C9F814008E423CD80021DFF802 -:10F1DC0090E0C9E9160197F800C0C9F85410BCF1C9 -:10F1EC00020F08BF0146BCF1000FC9F8501001AB6B -:10F1FC009EE8F5001946F5C108F11C001A4ACDF835 -:10F20C0008900090174808BF024609F12800142105 -:10F21C0018F0CEFA05462020EFF3118180F3118807 -:10F22C0081F3118899F8100010B9484612F04EFC81 -:10F23C0035B108F12800494619F036FA4D4602E07E -:10F24C000025C8F83050284607B0BDE8F08300BF51 -:10F25C00A01F00200CB7020040420F003F420F00DD -:10F26C00E8B70200ED3802008D950200F8B50446AF -:10F27C000020A5782075C4E9030045F0020000F0D9 -:10F28C00030002280CD115F00C0005F0030218BF86 -:10F29C00042809D1022A05D1E90601D402210FE084 -:10F2AC00012619E0022106E00C2803D00828F1D031 -:10F2BC00012100E00321022A02D1EA060E460BD4FA -:10F2CC0048B10E1D0C2807D8012202FA00F041F2B9 -:10F2DC001012104200D04E1D68B2B0F1FF3F0ADC94 -:10F2EC00E078800706D0A8074FF0030058BF022033 -:10F2FC00064400E0013627881AF0AEFA87420BD09C -:10F30C00A80609D51F48416920468847206918B9C5 -:10F31C00A07800F0DF00A070207D00B1F8BD61790D -:10F32C005020751C8DF8000020798DF80210216991 -:10F33C0028448DF8010029B10A7F497F1044084404 -:10F34C008DF80100684613F037FEA0B1012180F85A -:10F35C004850417621884180618801872179226952 -:10F36C0080F8421001692944416412B1127F1144A2 -:10F37C004164E060F8BD20461AF0E7FB10202075D0 -:10F38C00F8BD00BF502400202DE9FC47434FDFF8A7 -:10F39C0010810DF1070A4FF0000918F0FBFB002853 -:10F3AC0000F079805046012114F030FD38780528A2 -:10F3BC00F3D8DFE800F003090F1928469DF8070081 -:10F3CC00FE28EAD1032462E0B8689DF807100224F5 -:10F3DC0041705CE0B8689DF807100424817078785F -:10F3EC00002808BF052452E09DF8070088F800901B -:10F3FC007870033017F09CFF0028B86049D07978FA -:10F40C000124017043E098F80000411C88F80010BA -:10F41C00B96808449DF80710C17018F0BBFB05468D -:10F42C0098F8000079780A1AB9680844E9B20330F0 -:10F43C008A421ADA91B214F0E9FC787888F8000064 -:10F44C001FE07878BD689DF807400330C6B22846A7 -:10F45C00314619F06DFBA04215D17B68B3B1304633 -:10F46C00294600220024984711E014F0CFFC98F8AC -:10F47C0000007978284488F80000C0B288427FF4F4 -:10F48C008CAF052403E0284618F030FE00243C70B5 -:10F49C0083E700203870BDE8FC8700BFF42500200E -:10F4AC00967A0020F8B504464048C16819B1204648 -:10F4BC00BDE8F84008473E4E3068074658B105464F -:10F4CC0060882988814203D12079A978814216D09D -:10F4DC00A8692F46F2E71C201AF010FD002863D013 -:10F4EC001C2105461AF014FCFF20E8724FF6FE7042 -:10F4FC0028813068002818BF07F11806356020797C -:10F50C00217A627A237BA87060880129AA716971BB -:10F51C002B75288005F10C0007BF4FF0FF31C0E9B7 -:10F52C00001104F10D011AF094FC2249A07A09781B -:10F53C00884239D96179012903D01AF06BFA98B352 -:10F54C00A07AA97A884202D9E27A102A05D3884295 -:10F55C0006D1E97AE27A8A4202D20022012101E044 -:10F56C0001220021144B1B78022B01D2A31D01E0B8 -:10F57C0005D1E31D1B7813B172B9228808E00F4A3C -:10F58C00538B2288D31AB3FA83F35B09194203D045 -:10F59C00A872E07A2A81E872E07908B1012028711A -:10F5AC00A07908B10120E870F8BD00BF54750020A7 -:10F5BC00E8790020A327002024260020A86D002035 -:10F5CC001EF0040F14BFEFF3098169468869A1F19D -:10F5DC00480214BF82F30988954621ED100BF1EE19 -:10F5EC00102A41F8082DEFF3118102B400B5DFF8B1 -:10F5FC00D8E0F047374A1268116801EA0000106041 -:10F60C005DF804EB1EF0080F09D101BC80F31188E2 -:10F61C005DF8080BE1EE100ABDEC100B704704BC52 -:10F62C001EF0040F14BFEFF309816946A1F120010C -:10F63C0014BF81F309888D464A604FF08070C86111 -:10F64C0025488861234B1B681868086040F201103C -:10F65C001860704702B401B4EFF3148100291CBF89 -:10F66C00002282F3148802B402B4DFF860E0F047A1 -:10F67C0001BC01BC00281CBF022181F3148801BC11 -:10F68C00DFF84CE0F0470F484FF08051016001BCAF -:10F69C0080F3118800BF00BFFFF7FEBF1EF0040F00 -:10F6AC0014BFEFF30981694601F1200151F8080BF1 -:10F6BC00E1EE100AB1EC100B14BF81F309888D46F2 -:10F6CC00704700BF04ED00E0CDCD01006B9E020041 -:10F6DC00719E0200B4BA020060F600002DE9FF41F1 -:10F6EC003B4E96F8420100286AD1012086F842016F -:10F6FC001AF030F9374F86F87001374D7868C6F834 -:10F70C006C01387B86F84101A86810F4402F13D1A6 -:10F71C00386988B128686421C0F3066000FB01F4E5 -:10F72C001AF0BCFBB4FBF0F22C4906F19400002358 -:10F73C0015F06CFE19F094FE01AC20461AF00FFA8D -:10F74C002749A846002506F10C00002219F05BFFA2 -:10F75C0020461AF004FA234906F15000082219F049 -:10F76C0052FF214A06F1D8003221002313F0F8FC95 -:10F77C001E4C1F4A06F1F4002C210023256045463F -:10F78C0013F0EEFCD8F80800797BC0F3815021B15E -:10F79C00032804BF012186F83911032803D040F057 -:10F7AC000200022810D1206840F0400020600220A6 -:10F7BC0015F07CFF6868400702D4002015F076FF36 -:10F7CC00002004B0BDE8F08114F0E4FBF2E700BFC8 -:10F7DC00D81B002018B80200AC4F005063970200F1 -:10F7EC00ABDD01000929020061CD01009022084027 -:10F7FC0091A700002DE9F8431D46434BDDF820800E -:10F80C0043F606061C68038814F0007411D0B3424A -:10F81C0027D0B3F5C15F33D040F60206B3423ED1D8 -:10F82C0000F112030B604169116081692960C169A3 -:10F83C002EE0B3420AD0B3F5C15F03D040F6020606 -:10F84C00B34203D100F11203143002E000F11A03A9 -:10F85C001C300B600068106000202860C8F80000A5 -:10F86C004BE000F11A034FF000090B60C169116005 -:10F87C00016A2960416AC8F8001000F118011CE007 -:10F88C0000F112030B6041691160416A2960816AC1 -:10F89C00C8F8001000F1100190F80F900DE000F185 -:10F8AC001A030B60C1691160816A2960C16AC8F8CA -:10F8BC00001000F1180190F82490286868B10E88A7 -:10F8CC0019F0C4FE042808D8074606F0070148467C -:10F8DC000EF0A4FF296841F82700D8F8000060B1A9 -:10F8EC0019F0B4FE042808D805464846FF210EF04E -:10F8FC0095FFD8F8001041F82500002C18BF012402 -:10F90C002046BDE8F88300BF941200502DE9FE4F4D -:10F91C00D0E90085994614460F46834613B1002062 -:10F92C00C9F8000074B119F061FF064698F8070099 -:10F93C0058B198F8E80070B130461AF012FA6FF02E -:10F94C0008046CE06FF0090469E030461AF009FA1B -:10F95C006FF00E0463E000200121C8E93B74C8F885 -:10F96C00F440C8F8FC0088F8E810C8F83C0088F8A7 -:10F97C000D0088F80B00284601951AF027F8304640 -:10F98C001AF0EFF908F1D0060DF1080A19F02EFF64 -:10F99C0004463046514616F043FAD8F8F450D8F8DD -:10F9AC00FC10A842394438BF054602982A461AF082 -:10F9BC00CBFA3046294614F041FBD8F8F400D8F8BD -:10F9CC00FC10401BC8F8F4004819C8F8FC0020468D -:10F9DC001AF0C7F9012D03DBD8F8F4000028D5D1B3 -:10F9EC0019F004FF0746D8F8FC0050B1019819F043 -:10F9FC00EDFF584605F0F2F9D8F8FC0010B10024E0 -:10FA0C0002E000206FF00F04B9F1000F18BFC9F825 -:10FA1C000000002088F8E80038461AF0A2F92046C9 -:10FA2C00BDE8FE8F2DE9F041047B06468846204652 -:10FA3C0019F08AF8054610B168892C4625E07289C0 -:10FA4C003068214617F074FB002700286AD0044662 -:10FA5C00078116F8100F207470886082304619F0F8 -:10FA6C00F3FB6061308961892083B07AA07621F440 -:10FA7C0060704907608105D42C490978013140EA4E -:10FA8C00C11001E040F080006081C0F3C211B8F1F8 -:10FA9C00000F12D0022262732268D289520702D55B -:10FAAC00234A128A228169B36FF07F0220F46070BE -:10FABC0002EBC1110843608124E039B1810607D4FF -:10FACC00C1060BD440070FD4012013E000271AE025 -:10FADC001AF09AF800F07F005F300BE01AF094F8FF -:10FAEC0000F00F000A3005E0124806881AF08CF876 -:10FAFC0030400230208110480421617320210078AD -:10FB0C000EF0FEFA01276DB92289617B20460CF0BC -:10FB1C00DDFC38B1606908B11AF0EEF920461AF034 -:10FB2C00EBF900273846BDE8F08100BFD52700204F -:10FB3C00A86D0020B8BA02009C7A00207CB504465F -:10FB4C00007A022803D3208814F0F0F810B10226B2 -:10FB5C0030467CBD207A032806D10DF102012046E7 -:10FB6C0015F0C4FB18B9F2E72088ADF80200608AE2 -:10FB7C0044301AF0C3F9002864D0442105461AF029 -:10FB8C00C7F8A07A694617F0AFFE9DF800009DF803 -:10FB9C00011085F83A0085F839102846012117F034 -:10FBAC00F9FE05F110002146242219F049FC628A65 -:10FBBC00616905F144002864AA8719F041FCBDF87D -:10FBCC000200A88020480178E971013101701AF017 -:10FBDC0067F906461AF062F970434FF47A71002601 -:10FBEC00B0FBF1F0FF218DF80460288095F8390006 -:10FBFC0001FA00F0217E85F8370085F83600207A6E -:10FC0C008DF8060001F001008DF8050001A819F02F -:10FC1C002BFA298D023885F83400C0B241F0080166 -:10FC2C0083B22985A98F8AB2B2FBF3F202FB1010C2 -:10FC3C000004064818BF013201212A7200780EF028 -:10FC4C005FFA85E7102683E7987A00204826002083 -:10FC5C002DE9F04F85B0044600880DF1060117F030 -:10FC6C0051F8054618201AF049F94FF6FE7768B19D -:10FC7C00182106461AF04CF860881821324619F003 -:10FC8C001DFF781C608030461AF036F90020278062 -:10FC9C00002D207160D1DFF8C8A0BDF80640DAF85D -:10FCAC000000D0B314201AF029F9B0B3834604AB8A -:10FCBC004C2000210222002719F058FA009404EB82 -:10FCCC00440402AE0BEB44004FEA4408851C122F8F -:10FCDC0018D0B84505D1DAF8000000EB44012846ED -:10FCEC000BE007F102094C20062233461FFA89F17A -:10FCFC0019F03CFA09EB0B003146062219F0A0FB77 -:10FD0C000637E4E74C2014215A4619F0D7FE584622 -:10FD1C001AF0F2F8009C4FF6FE7704AB4C20002151 -:10FD2C00022219F023FAB8B9DAF8000050B104EB4A -:10FD3C00440130F81100B84204D1BDF8100030B1C4 -:10FD4C00013802E0BDF810000130ADF8100004AA33 -:10FD5C004C20022119F0B2FE05B0BDE8F08F00BFB7 -:10FD6C00EC2600202DE9F04788B0DFF8FCA0D0F895 -:10FD7C0004803E4E7F2400217F23DAF8280020EAFD -:10FD8C000800CAF828001B2915D020FA01F2D20766 -:10FD9C000FD00027324612682AB19578A94208BFC5 -:10FDAC0001371832F7E7DAB2FDB295423CBFCCB25C -:10FDBC003B460131E7E7B8F1000F15D0CAF82880AF -:10FDCC0001AC1821201D19F0A3FF0120CDF80480EF -:10FDDC008DF808009AF82E008DF8090020460EF0D8 -:10FDEC00EBFE08B0BDE8F087204EDFF884804FF6BC -:10FDFC00FF7930460768BFB13888BAF824108842BA -:10FE0C000FD1B978A1420CD1B8F8001049451DD1D9 -:10FE1C001AF05AF8AAF82400398881423046E9D100 -:10FE2C0002E007F11800E5E78AF81840FEF744FFF6 -:10FE3C000028D6D000208AF826000E480168002938 -:10FE4C00CFD0C42008B0BDE8F047084700208AF89E -:10FE5C0026000848016809B1C4208847002008B072 -:10FE6C00BDE8F04716F08ABAA86D0020E8790020AA -:10FE7C0090270020102500202DE9F04389B03F4A3F -:10FE8C001278824209D93C4A3D4F002952F8306021 -:10FE9C0018BF0F4696F8521021B10025284609B01C -:10FEAC00BDE8F08302EBC009D9F804406078022861 -:10FEBC0026D1022086F8520011F0EAFF0DF10C0851 -:10FECC00404619F0C5FA3868002541468DF81450A3 -:10FEDC0006958DF80C500490207812F0EFFC002859 -:10FEEC007060DBD019F082FFF87988B1B879396885 -:10FEFC0048436421B0FBF1F1706819F074FF07E01E -:10FF0C0000F0EEFC012086F85200207886F85400B0 -:10FF1C006D46284619F023FE002000212A46CDF814 -:10FF2C0008908DF800000190164813F0DDF8B060D1 -:10FF3C0070B138683060B97986F85310F8790228B6 -:10FF4C000CD0012812D0A0B9484613F016F810E0D6 -:10FF5C0070680028A1D019F043FF9EE7B8884FF6CF -:10FF6C00FF72410848460BF02DFF02E0484613F0A3 -:10FF7C006DFE4D4692E700BFF4B80200C3B8020014 -:10FF8C001CBA0200092C0200F0B58BB0364D286863 -:10FF9C0070B9364C206828B935488068D0F84C05C3 -:10FFAC0080472068334C016A204688473248E0611C -:10FFBC0032480068016931B12D488068D0F8D4000E -:10FFCC0090F8530088472A4EB068D0F8D40090F9C6 -:10FFDC00420010F02FF9411C03D0294940EAE0708F -:10FFEC004882274C002060606080207B617B40F061 -:04FFFC0080002073EE -:020000021000EC -:1000000001F0F00001306073B068D0F8C40380479D -:1000100030B91F4810210170F06814214068017048 -:100020002868D8B10020002614F0CEF9124F3868A5 -:10003000416E03A8884717480696806808B1804734 -:1000400009903968286800230D6D0821CDE9001654 -:1000500003AA2146A8471048046009E00F480B4A4C -:10006000074B01680448006804680D48A0472860F1 -:100070000BB0F0BDE4260020347A00200C010020F3 -:10008000F875002054F10080607A0020D8750020B7 -:10009000B47A002054B5020030250020687A002090 -:1000A000B06500202DE9F0418AB03E4E054630682B -:1000B00020B13D490978A94209D82DE013F038FF55 -:1000C0003068002448B338490978A94225D94FF04F -:1000D000FF3119F0B3FD354905EB450001EB800414 -:1000E00067683878A8B9A568A9682A6848424B1E8D -:1000F0001A42B8600DD16A688A420AD3104082421F -:1001000007D1686910B10068786029E0298B04295B -:1001100007D3306819F00AFF002420460AB0BDE872 -:10012000F08106EB81000069A8B90DF10408404692 -:1001300019F02EFC002041468DF810008DF80400C7 -:10014000E8690590287E12F03FFC0028E1D0298B59 -:1001500006EB81021061786031440A7B01320A7338 -:10016000298CC6E90101204617F0C4F80120387037 -:10017000AB2031898DF82700204619F01AF80DF1CF -:10018000270001210FF07EFD31890546204619F038 -:1001900019F815B920460EF09FFD306819F0C6FE1B -:1001A000BBE700BF0C2400208DB9020028B7020075 -:1001B0002DE9F84F3C4C3D4E3D4D42F62A294FF07B -:1001C000010A4FF0030B00274FF00508D4F83C015B -:1001D000062833D8DFE800F00433183B203D4B00FD -:1001E0000F20F060C6F8109013F00AF945F804AC3F -:1001F00055F8040C8007FBD5C6F81CA094F839010B -:1002000090B10120EF6210E02F60C4F83CB1286883 -:100210008007FCD40320DBE72F60C4F83C8128680A -:100220008007FCD40520D3E70320C6F800B0C4F84B -:100230003C012F6029688907FCD4C9E7FEE7012645 -:10024000022084F83A6112F07FFB2E6009E0022060 -:1002500000E0032084F83A01002012F075FB012031 -:10026000286004F15000BDE8F84F19F027BE0020C7 -:1002700045F8040C286055F8040C8007FBD4286866 -:100280008007FCD40B480025012105600A48016065 -:100290000D2005F08BFF022014F0D6FBC4F83C5172 -:1002A00084F83B51BDE8F88FD81B002000400C407B -:1002B00058600C403C500C4004800C4070B5C16844 -:1002C0000C6991F8381041F00203224603F0030351 -:1002D00002F8011B022B3BD111F00C0301F00305C6 -:1002E00018BF042B2DD1022D01D1CE0630D4C26807 -:1002F00092F83B2062700234022D01D1CA0626D446 -:10030000C26892F83E202270C26892F83F20627064 -:10031000C26892F84020A270C26892F84120E27050 -:100320004BB1221D0C2B13D8012505FA03F341F222 -:1003300010152B420CD0C26892F83A202271621D2F -:1003400006E00C2B32D0082BCDD01446D4E7224641 -:10035000C46801F0020394F8395005F003051D4309 -:1003600009D1658D2D0606D4154E357884F849508F -:100370006C1C347001E094F8495049B21570B1F129 -:10038000FF3F00DD70BDC16891F839105170C16840 -:1003900091F83940A407F5D091F84B10002B9170DB -:1003A000F0D0C06890F84C00D07070BDC26892F870 -:1003B0003C206270C26892F83D20A27003349BE733 -:1003C000987A00202DE9FE4FDFF8F4B001219BF868 -:1003D0000C4001AA204619F00EF96A462046022177 -:1003E00019F009F9DFF8DC909BF80EE09BF80D009E -:1003F000BDF800C099F800100EF101030746B3FBE9 -:10040000F1F404FB11359DF80240ADB2FEB2B542E5 -:100410000FD0A642634618BF1023720052FA87F22B -:100420000BEB82029383721CB2FBF1F303FB1127E7 -:10043000ECE7DFF894A0002401270DF1080857FA33 -:100440008EF2C9B2C5B2B2FBF1F303FB1121A9428E -:1004500032D0690051FA80F00BEB800232F81C0FA9 -:10046000102806D1284607F013FA8AF80000013454 -:1004700017E028460421022313F03EFD8AF800000D -:10048000284600214246042318F0A8FF9DF80800E2 -:100490007C2802D0FE2804D10DE02846782114F0F3 -:1004A00051FA99F80010681C9BF80EE0B0FBF1F2CD -:1004B00002FB1100C3E7FEE7E0B2BDE8FE8F00BF1C -:1004C000B87200209B7A0020A02300202DE9FE4F67 -:1004D00005460F465818AE687168884202D96FF019 -:1004E000030564E0DFF8E8800C9C4FF0FF3199468B -:1004F0009246D8F8000019F0A1FBE00711D1A0073F -:100500001ED5306851464A463844CAB110F8013BFE -:1005100011F8014B013A23409C42F6D06FF00605DA -:1005200041E0D8E90101CB4301EA090213EA090FCE -:1005300018BF02443940284609F060FE054690BBCA -:10054000306802970196074412F07EFBCB46554671 -:100550000090BBF1000F16D0BBF1080F5E4628BF1C -:10056000082619F049F9804628463946324617F0E0 -:100570007FFE0446404619F0FAFB2CB93744354457 -:10058000ABEB060BE5E70024009817F005F9DFF860 -:100590004080DDE901210C9814B14FF0FF3502E0F5 -:1005A000400707D40025D8F8000019F0BFFC284602 -:1005B000BDE8FE8F10680844B9F1000FF2D010F8C2 -:1005C000011B1AF8012BA9F101098A42F4D0E4E7D2 -:1005D000DC250020B0B50C46880722D4600758BF40 -:1005E000B0BD354D0120A870042015F065F83348E2 -:1005F0000068006B8047E8602D48806BF0B1696847 -:10060000046961B1A1420AD094F82800400704D5DA -:10061000636A2046042100229847012060766C60BE -:100620000DE0FCF7CBFC2248006CE0B3214844F01D -:1006300002012830BDE8B04019F07CBC6C686068ED -:100640001F4900780860022015F036F8102005F0E8 -:1006500047FB012028761B48807810B90D2005F053 -:100660003FFB6868416818488A680AB9C96821B1BF -:1006700000218160154940F8141C154907220A60C1 -:10068000016800210160426841601249124AE96133 -:100690000168114301601A2019F016FC1920BDE809 -:1006A000B04019F011BCBDE8B0400DF093B800BFE8 -:1006B0003021002070200020D01E00208C0100106E -:1006C000D02108409CB902001410044051000706D4 -:1006D00000000460EDED0000024000402DE9F84FFD -:1006E0003A48DFF8EC90DFF8ECB0DFF8EC80002659 -:1006F0004FF0060A00210078C700B74242D009EB4C -:100700000605A878E0B30138A870687918F022FAD5 -:10071000A8B30446A87800B3A87948B3287970B381 -:10072000E9780139E970090629D19BF801100138EF -:100730002871E970617B032921D100061BD00420B8 -:10074000607319F067FA00F00F002021013020815A -:1007500098F800000DF0DAFC11E0607B84F80DA041 -:1007600002280CD02068F021407B11F001F906E04E -:10077000607B032803D12846214610F095FE012115 -:100780000836BAE798F8000001290BD1402112F091 -:1007900019FEC0B998F8000040216422BDE8F84F66 -:1007A00019F015BB40210FF01DF90C480178012903 -:1007B00009D1002101700A48007806F023FCBDE849 -:1007C000F84F12F059BEBDE8F88F00BFCEBA020054 -:1007D000AA680020A86D00209C7A0020EA2700204B -:1007E000EB27002070B58AB04FF48061041D458866 -:1007F000ADF826108189807B0894ADF82450032839 -:10080000ADF81C1034D0022806D0B0BB40F6010071 -:100810000026ADF826005AE03248007801285FD162 -:100820000DF11B0101AA204608F092FF04469DF835 -:100830001B00012854D19DF81400022850D101ADAD -:100840001421284619F06AFA274904EB44000022D3 -:100850002B4641F8202001EB800021464260427285 -:10086000FF2014228DF81400042015F0EDFE37E06F -:10087000102000268DF8270029E00DF11B0101AAA8 -:10088000204608F065FF01469DF81B0001281DD198 -:100890009DF81400022819D1134A002301EB4100EE -:1008A000CDE9013342F8203002EB8000142243608E -:1008B000FF208DF814009DF81600013000F00F00A5 -:1008C0008DF8160001AB042015F0BEFE012607A826 -:1008D00001F05AFD26B118B92846214602F04EF91A -:1008E0000AB070BDCB270020F03300202DE9F0477F -:1008F000A4B018F081FF34490A78012A04D124B049 -:10090000BDE8F04719F033BA4FF0010981F80090C3 -:1009100019F02DFAFEF7E8FE082005F0E1F921AC08 -:10092000204618F003FDDFF8A4A02A4A1021234630 -:10093000DAF80C002290264812F018FC2648002510 -:1009400001AF0478254890F800804646A64213D8A7 -:10095000DAF8000050F8261021F0FF0047F82600D2 -:10096000880707D4F0B201F0010118F0CFFC09FAB2 -:1009700006F005430136E9E7194805601948C168E2 -:1009800001F44001B1F5800F09D10068000E18BFD5 -:10099000012057F8201041F0070147F820101248B5 -:1009A000A4EB0802042307EB880103EB820240EA70 -:1009B000880019F0CFFA0D482022016862F30D215A -:1009C000016024B0BDE8F087A6270020E4B802004B -:1009D00078760020491D020017B802000BB702000C -:1009E000D0200240A84F00500010084000300940BD -:1009F000FEB5D0E9005401A818F078FC95F8340051 -:100A00003649374A384E085C95F83510515C354AFE -:100A1000084395F83610515C2A6B40EA01033168AF -:100A200020684F680299B847206840F2F272E16985 -:100A30002E4B2F4F426494F854209A5C94F8553012 -:100A4000FB5C1A430129426311D10146D4E90A2310 -:100A500051F8307FFF2A27F4004718BF07F50047F9 -:100A6000FF2B0F6009D00A6842F4804208E001467B -:100A700051F8302F22F400420A600A6822F48042C2 -:100A80000A60C16A41F01001C162016B41F00101CD -:100A90000163E16B09B3A16BF9B1012118F0EAF828 -:100AA000D5F85801E16B40680068C162C0F80415D0 -:100AB00091FAA1F17268B1FA81F153680222984764 -:100AC0007068A16B02224368D5F8580191FAA1F130 -:100AD000B1FA81F1406800689847FEBDA4BA0200EF -:100AE000C2BA020083BA0200D00100108DBA02001F -:100AF00088BA02002DE9F8430546007F04282FD16B -:100B0000A86A4678B0F802900E2E38D80C46012715 -:100B1000DFE806F008080841414141414141412ACE -:100B20002A38410031480078012833D83048807B8A -:100B300080072FD51FFA89F80021404609F01EFAD8 -:100B400000283FD0817911F0180F3BD0AA89438843 -:100B5000698900880027009200220FF08FF91AE0BF -:100B6000D32009F04AFD29E020480078012811D857 -:100B70001F48807B80070DD519F0E6F90AE00127B0 -:100B8000002408E019480078012803D81848807B21 -:100B900080071DD4012768891FFA89F2314619F0B0 -:100BA000A5F9688913F0C8F840B1A87C022805D3DC -:100BB00027B10F48A989C08A814200D1002420466C -:100BC000BDE8F88340460121012716F04BFBE2E720 -:100BD0001FFA89F8404618F099F940460DF0A6FC36 -:100BE000B0F1C50718BF0127D5E700BF24260020B4 -:100BF000A86D00202DE9F04186B018F041FF0446B1 -:100C0000002718F03DFF10B180690137FBE7DFF8DE -:100C1000C88098F80000012831D818F031FF2F4E15 -:100C2000B18C28B102888A4229D080690028F8D185 -:100C30001C2019F069F910B30546B08C2880307E6D -:100C4000A87018F009FE6871254806F1390100788E -:100C5000A87105F10C0019F002F90DF117014120FE -:100C600015F050FB1F489DF81710AC612C4600880A -:100C7000002908BF6FF001000137288100E000253E -:100C80001948FBB200210278934201D200260BE002 -:100C9000B81A0026F7B2974202D2A4690136F9E7E2 -:100CA000C6B2052E28BF05261048CDE902411049DD -:100CB000CDE900260022007803F072FC98F80000CD -:100CC00008B1012803D115B1284619F01BF916F017 -:100CD00027FF06B0BDE8F08124260020A86D002083 -:100CE000E827002088790020C77A0020C67A0020F3 -:100CF0009C7900202DE9FE4F4FF4804018F056FB00 -:100D0000A0B1354C35496068D1F8132009786FF3EC -:100D10009F5201F00401806842EA417101AA03F088 -:100D20001DF960688168012016F0EAFF2E482C4FFB -:100D30002C4D44F2020B00244FF0000A00F1400950 -:100D4000BAF1020F3CD055F82A80D8F80000A0B3C1 -:100D5000D8F80000806918F029FB0646D8F8000092 -:100D60000023324615F05CFF16F00A0F1ED0D8F8AB -:100D700000008069B9686BEA00000840B860D8F8E4 -:100D80000000C069396821EA000038601020D8F8F6 -:100D9000001016F0B5FFD8F80010484616F03EFADD -:100DA000002044F00204C8F8000006E02EB1D8F894 -:100DB00000000D4944F4804408650AF1010ABFE7C8 -:100DC00024B10A482146283019F0B4F806F0BEFFD5 -:100DD000BDE8FE4FF7F768BCD01E00208503002158 -:100DE0000C10044004BA02003021002070200020C2 -:100DF0002DE9FC473A4D0446286810B194B1BDE88E -:100E0000FC87122019F080F800282860F7D04FF6F0 -:100E1000FE720021531C1229F0D0461842520631AE -:100E20007380F8E701AB4C200021022218F0A4F9EE -:100E300000284CD1BDF80400002848D0032846D82B -:100E4000182019F061F8DFF89C90044600264FF650 -:100E5000FE784FF0020A0027032F34D028680622BC -:100E6000831907EB47000AEB400081B24C2018F0D1 -:100E700083F928BB2868815B414518BF002C1FD02F -:100E800030440022182341880620009415F0C6FB48 -:100E90002868D4E90423304402F2E932418822610F -:100EA00001EB410049F8202009EB80001822436043 -:100EB0000620234615F0C8FB2046182118F02EFF07 -:100EC00006360137C8E714B1204619F01BF8064B67 -:100ED00071200021082218F04FF9BDE8FC8700BFFF -:100EE000EC26002030750020B8260020F8B5044616 -:100EF00018F004FA07464568204617F0B7FFB8B166 -:100F0000D7E9014618F078FC0546D4F8C000B8B11E -:100F100004210174384606F005FAD4F8C800B0B1CF -:100F2000014640690028FBD1D4F8C000486112E0B6 -:100F300018F062FC0446D5F8C00078B3103034E0F5 -:100F40003068416821F002014160284630E0D4F861 -:100F5000C000C4F8C800416900274761C4E934777C -:100F6000C4E93677C4F8C01031B320463146FAF7E9 -:100F700069FFD4F8C000C4F8E0700068B0F5806F75 -:100F800003D920463146FAF75DFF94F8FE0010BB06 -:100F90003068416841F0020141601CE095F8FB00B7 -:100FA000002114F051FA05F1FC00012101702046E6 -:100FB000BDE8F84018F0DBBE94F8FB000021C4F84F -:100FC000C47014F041FA012084F8FC003068416AD2 -:100FD00021F003014162284618F0C9FE04F13000F7 -:100FE000BDE8F84018F0A8BFF8B53948394D0121DF -:100FF000394E0768E868C0680170002002F00201FD -:10100000F07003F0E040401817D096F90600012870 -:1010100002DBB0790138B07196F90500012802DBD6 -:101020007079013870712D48426803F0807082B188 -:10103000D8B10020002190470CE01446500223D480 -:10104000E00326D4A00330D50020387111F002F956 -:101050002BE050B196F90700012802DBF079013846 -:10106000F0710120307118F04BF8002038710BF04E -:10107000C3F97079F8B196F90500002823DCA86857 -:10108000D0F84C0580471EE0002038710BF0B4F911 -:101090000BE01348007820B1052018F013F813F086 -:1010A0003FFE00203871F1F72DFEA00648BF18F072 -:1010B00087FF707938B900200021B070A868D0F897 -:1010C000582400209047E8680021C0680170F8BDEE -:1010D000787A00200C0100202425002054B502005D -:1010E000A0270020B0B58CB004464089ADF80000C0 -:1010F00060684178821C019206298DF8021003D0A5 -:10110000042907D0012936D1817C13228DF80310E0 -:101110001B2101E01A211222851801440391029536 -:1011200031D0284616F0CAFF01282CD117F0E4FE72 -:101130000146284616F011FC28BB264800780128F5 -:1011400024D8684618F00CFD01281FD102980DF133 -:10115000160114F0D1F8012818D10021BDF81600AD -:1011600061721D496081097891B16168097805292A -:101170000ED101210DE00021029100F11201807ECB -:1011800003918DF81000684610F056FD0CB0B0BD0C -:10119000002100222173CDE90622ADF81800207A43 -:1011A00008928DF81D108DF81C0001208DF81A0092 -:1011B00006A8FEF761F89DF82C000028E6D10998F2 -:1011C000227A6168406C18F041F906A811F01CFA07 -:1011D000DCE700BF24260020E02700202DE9F041B5 -:1011E0000E46054610463421144618F097FD082E89 -:1011F0004ED326702146288812F030F88046688841 -:1012000008216081A888A081A879A074E87961701C -:10121000E074E07920B1102105F10800617060618F -:10122000207A28B101F1080029446070A16100E032 -:1012300008460021616284F82010617919B1295CA7 -:10124000013060706171617FF1B1421C6270295C94 -:101250000230607084F82010AA5C914284F821204A -:1012600010D9194A4F00194E1278914288BF182799 -:10127000291830463A4618F0E9F860786662384432 -:10128000607001E0002161772178C2B2914203D2FF -:1012900000263046BDE8F081B8FA88F2091A55FAFE -:1012A00080F05609A2792177A062002AF1D00E3091 -:1012B000A062A1F10E0020770548007B18F016F916 -:1012C000217F081A2077E4E7D8BA020008780020C6 -:1012D000A86D00202DE9F04105460026806A1C46D5 -:1012E000174688461680007817F0FCFA40B16889E6 -:1012F00012F022FD022811BF002668893880264698 -:10130000A86A007801380A2846D8DFE800F0060C01 -:101310001116242C45383C4A5200284641463A468C -:10132000F7F75AFE41E028464146FDF7A3FB3DE0B2 -:1013300028463146FFF7DEFB37E0287F02282BD115 -:1013400026B920486989C08A814228D13046294679 -:1013500000F068FD29E0688912F0EEFCE0B928464B -:10136000F4F7C8FD22E017486989C08A814213D189 -:10137000287F022810D128460CF008FE16E02846E7 -:10138000FCF7FCFC12E00F486989C08A814203D156 -:1013900028460BF027FA09E0D32009F02EF90026A1 -:1013A00004E0304629460FF05FFF06463046BDE8B0 -:1013B000F081054800780128F1D128460CF0B6FDEF -:1013C000F4E700BFA86D0020CA27002070B586B0E2 -:1013D0003449002808705DD1344C207830B9324946 -:1013E000097819B9082016F0DBFC207801284ED8BE -:1013F0000020CDE90300CDE9010017F06FFF0028C0 -:1014000045D02B4D05F13904204617F0A1FE18B93F -:101410002849204618F023FD05F11601532010F04D -:10142000B3FEA87B0DF11701C0F3C0008DF81700C3 -:10143000522010F0A9FE082085F8260003F09AFA41 -:1014400004F036FA1C48016809B9012101601B4803 -:101450004FF4407100780CF059FE01AC204614F0B6 -:101460007BFA20460021002616F02EF895F8410060 -:1014700010B9002005F0C6FD1148CDE90366CDE99D -:101480000166807B012802D0012014F07DFF01203D -:1014900015F08EFC0948022100780CF037FE06B0EA -:1014A00070BD00BFBF7A0020D02600202426002077 -:1014B000A86D0020B6790020182500209D7A002014 -:1014C000CC2200202DE9F84F8A468DF8030062B146 -:1014D000384851460123406802700DF1030048F27C -:1014E00031020DF0F9FF044660E00B9F1624052041 -:1014F0001E4617FB0400C0B218F006FD002854D0A9 -:10150000814604220C980A9917FB04280024CB4634 -:101510000BF8014F00F119058BF801600BF104067F -:101520008BF803708BF80210E0B2B84229D2A5F113 -:101530001701304618F093FC06F10800A5F10F01E1 -:1015400018F08DFC15F8071C861D0134017015F884 -:10155000061C417015F8051C817015F8042C41EA31 -:101560008201817015F8032C41EA0211817015F88F -:10157000021CC17015F8011C017129781A354171DE -:10158000D2E70C4D5FFA88F30DF10300514648F2A3 -:101590003102C5F804B00DF09FFF0446484618F02C -:1015A000B1FC05480130686000E010242046BDE829 -:1015B000F88F00BF88260020447000202DE9F041FC -:1015C000056804464FF0FF30E86218F015F98046D0 -:1015D00095F83000042809D13249497831B13249AF -:1015E00003228A604A6822F003024A602D4F6B6929 -:1015F0002E4E00217A68B34204D01AB979780029B6 -:1016000018BF01210023042804D11AB17B78002BD4 -:1016100018BF012341EA0300012808BF14F096FD1A -:1016200095F8320030B1404618F0A1FB4FF0FF3082 -:10163000BDE8F08195F83000042804D1381D294612 -:1016400015F0FEFD03E0381D294615F0E7FD0120E9 -:1016500085F83200404618F08AFBFCF7B7FF246893 -:1016600094F83000012811D0022812D00428DDD1CE -:101670000D4DD4E90901884210D2012018F080FBF9 -:1016800028688007F9D0FCF7A1FFF2E70020BDE849 -:10169000F081216A04F1340018F0D0FAE06ABDE864 -:1016A000F08100BF182300200880024080A90300B9 -:1016B0002DE9F04F85B0044610F000FD00286ED0F3 -:1016C00026468346471C00244FF000084FF00009CF -:1016D0009BF80000844222D2384618F03FFBD8B174 -:1016E00001790139012917D890F82000A0B10C2008 -:1016F00018F00AFC80B13946054618F0B0FB00200E -:1017000009F10109A860B8F1000F28461CBFCAF80A -:1017100008504046AA46804608370134D8E75FEAB9 -:10172000096039D002205FFA89F937468DF8100038 -:101730007088ADF808004FEAC90018F0E5FBC0B1A9 -:1017400005460024B8F1000F17D0E0B2414605EB82 -:10175000C00018F084FBD8F80860404618F0D2FBAF -:101760000134B046EEE7D8F80840404618F0CAFB0E -:10177000A046B8F1000FF6D10EE0002048F21F019C -:101780004A462B46CDE9001007F1110002A902F0EC -:10179000AFFC284618F0B6FB584618F0B3FB05B06E -:1017A000BDE8F08FF8B53B4E0446B068D0F8B810ED -:1017B000097859B194F8982004F190014AB11522A2 -:1017C00017F0B8FB58BF25229A5C09E0012121756A -:1017D00014E0252217F0AEFB58BF25229A5C023296 -:1017E00084F86A20002284F86920042284F86B209F -:1017F00004F1700228C928C209881180254615F80D -:101800002C1FB5F872200F2925F8162CB5F8742076 -:1018100025F8112C0CD0D0F80473B4F8A800294690 -:101820000023B0FA80F042092046B84700B1F8BD65 -:10183000214611F83C0FFF2801D1A06D30B1B068EE -:10184000D0F8FC22204690470028F0D1B06805F17E -:101850006402B4F89A3094F89C10D0F874530020C5 -:1018600000902046A8470028E1D1B0682189D0F82F -:101870000021D289914205D9E5206070B06800F559 -:101880001B7001E000F51E700168204688470020AB -:10189000F8BD00BF0C0100202DE9F04385B00646DD -:1018A00000200D46049017F0A7FF334CDFF8C490DA -:1018B00080462168D9F80000CB6C04AA052198471E -:1018C00001A817F001FF2D48019626F001060395A7 -:1018D00020F00107BE420AD12B490878FE281BD010 -:1018E0002068826BD9F8000091F900100EE02448BE -:1018F00020F0010086421BD123494878FE280BD0F6 -:101900002068826BD9F8000091F901109047812876 -:1019100002D01C4818F0EDF92168D9F80000002227 -:10192000CB6A01A998470546B0F1FF3F07DC03E009 -:10193000144818F0DEF9FE25124818F0DAF9BE4214 -:1019400001D1114806E00E4820F00100864202D184 -:101950000D4801300570012021680490D9F800007D -:10196000CB6C04AA05219847404618F000FA05B050 -:10197000BDE8F083E4260020347A0020BD64020034 -:10198000F14D02000C010020242500202DE9FC4728 -:1019900006680446707A00286BD0D4F80490D6F814 -:1019A0005801D0F80480D9F8347020460BF016FBAB -:1019B000706F20B306F14C05284618F0B3FA316F6A -:1019C000884221D2307902281ED0B06E002850D033 -:1019D00020460BF003FB346F284618F0A3FA201AB8 -:1019E000D6F868A0B46F7067284618F09BFA0021FB -:1019F000F1740AEB040108440190706F0CE0B06EC2 -:101A000010B1306F0028D5D106F14C0001A914F0B7 -:101A10000DFA01217067F17458B30021B0F5806FA1 -:101A2000B17384BF4FF48060706701230199014452 -:101A3000013979601049B96043F6F07101EB00108B -:101A40000840B9680843B860D9F83C10D9F80000DC -:101A500091FAA1F2B2FA82F203FA02F2D8F8003057 -:101A60009A61D6F85821526812689162012117F0E4 -:101A70000DF9BDE8FC8700BF0180000C2DE9F0479F -:101A800088B004466FF00100A081002004F1040832 -:101A90008DF8100004AD4146281D17F09EFD284624 -:101AA00009F0F6FD012809D1BDF81C00BDF812109F -:101AB000A0816088814222D004AD01E060880025C9 -:101AC000EA46ADF8020000264FF6FE7950468DF842 -:101AD000006007F0C9FA0128074608BF5646B5B1AD -:101AE000A88901210125A081204610F0C7F8012F07 -:101AF00006D1ADF802903046022110F0BFF8012562 -:101B0000204611F0D9FA284608B0BDE8F087012F29 -:101B100013D1BDF80C00A0810AF1040016F0CEFA32 -:101B2000012817D1204609F007F905463046022161 -:101B3000ADF8029010F0A2F8E2E76088484504D1C1 -:101B4000404616F0BBFA01280CD1204609F0F4F803 -:101B50000546D5E7404616F0B1FA0128CFD1204618 -:101B60000321CAE70025CBE72DE9F0438FB080467B -:101B7000374800240394CDE90144077814F0FAFEB5 -:101B80004FFA80F901ADBC4212D2E6B207200C2216 -:101B90002B4631460EF048F940B9B9F1FF3F05DC5C -:101BA000072031460C222B4614F04EFD0134EAE7A3 -:101BB0004FF0FF300C22CDE90200781E01AB85B258 -:101BC000072029460EF030F940B9B9F1FF3F05DC96 -:101BD00001AB072029460C2214F036FD04AD182174 -:101BE000284618F09BF8822018212A4617F066FF35 -:101BF000B8F1010F08BF002804D104AA82201821DF -:101C000017F062FF0AAD1121284618F087F83A2034 -:101C100011212A4617F052FFB8F1010F08BF002822 -:101C200004D10AAA3A20112117F04EFF0AAA3B203C -:101C3000112117F043FFB8F1010F08BF002804D1AC -:101C40000AAA3B20112117F03FFF0FB0BDE8F08337 -:101C5000D3BA0200B0B517F0DDFF2C4C02210025ED -:101C6000207040F60F70A17430492581C4E90755F2 -:101C70002576A0850F202071012084F86C00E07289 -:101C800040F20510A08122480078E07121480078D8 -:101C9000607021480078A07020488078A0732048A8 -:101CA000007820826FF00100A0846083E0821D48EC -:101CB0000078E0741C480078207504F1390018F0B1 -:101CC000CEF840F20F5004F16E030021022284F896 -:101CD000415084F86850A4F866001548007884F8EC -:101CE0006A001448007884F869001348007884F882 -:101CF0006B00892017F040FA08B1A4F86E5000205C -:101D000010F044F8A4F87050B0BD00BFA86D0020DA -:101D1000C7270020DF270020D42700203E7900209D -:101D2000D3270020E1270020E227002025260020DD -:101D3000CC270020CD270020CF2700202DE9F04F11 -:101D400087B082462420994614460F4618F0DCF8E6 -:101D5000002800904DD0DDF844802421054617F07E -:101D6000DDFFDFF8B8B09BF80000012813D8384633 -:101D700017F097FF50B1007940F00200032802BF2E -:101D80004FF4806020EA081048EA0008DDE91232CA -:101D9000C8F3802602E0DDE9123200262048ADF8C3 -:101DA0001840109C0221808C2F8029722973688131 -:101DB0000098ADF80A808DF80C404473C0F820A05C -:101DC00080F81F908DF81A30D2E90001CDE90401A6 -:101DD00068463146FDF72CFE012807D19BF800101C -:101DE00049B10020B6B1012906D013E0009818F0DF -:101DF00089F810200EE066B1204616F0ABFE40B127 -:101E000004460068008818F0E5F810B1204607F095 -:101E100033FF002007B0BDE8F08F00BF242600206C -:101E2000A86D00207FB5044600200D46ADF80C00DB -:101E30000290CDE90000886A4078C10604D0D32022 -:101E400008F0DBFB00244AE0820641B244BF0122D5 -:101E50008DF80C20B1F1FF3FDCBF01218DF80B1094 -:101E6000400605D4287AE8B105F11800002107E002 -:101E700001208DF80A00E879D8B105F1140001219C -:101E8000066836B168463146023017F0E8FF9DF823 -:101E90000A10A8890129ADF8000006D1B6FA86F12A -:101EA0004E090AE0A889ADF8000068460EF064FC0F -:101EB00015E0A8890126ADF800001049097871B134 -:101EC000012902D10E4A12784AB1022903D10D49E3 -:101ED000498B884203D1688911F02EFF10B120464A -:101EE00004B070BD002EE0D117F006F86846064930 -:101EF000023015F032FD0028D7D1F0E7242600206B -:101F0000D9270020A86D0020E07900202DE9F04FAE -:101F100085B0894619461F461446054612F0E2FD73 -:101F20003249DDF840800978884207D2304900EB19 -:101F3000800001EB4000B0F804B001E04FF6FE7BFA -:101F400018F0100A4FF0100008BF082018F0200108 -:101F5000019118BF08308DF8110004A814F0C0FDDD -:101F6000002840D0064601200094B07716F0C4FF48 -:101F7000706202AC5846214613F0CEFE18B1012023 -:101F80003462707705E0BAF1000F02D00E9CAB45C9 -:101F9000F5D034694FEA1920A071280A84F8059019 -:101FA000E570A77084F801802071022020705846E7 -:101FB00012F012F80099BAF1000F0844E07101D153 -:101FC000082005E00E9904F1080017F048FF1020E2 -:101FD000019919B10F99204417F041FF3046A6F836 -:101FE00002B00CF009FD05B0BDE8F08FD5BA0200D3 -:101FF000B25C002070B59EB0314D0021742228786B -:102000000130287001AC2120234617F0B5F828785C -:10201000742122468DF80400212017F055FD294E29 -:10202000294C3078A178814206D2002012F060F865 -:10203000012801D1042000E00D2015F0B1FEA98C8B -:1020400001204FF6FF72914237D0E98A4FF6FE72B7 -:10205000914232D01D480078022803D31C480078F2 -:10206000012808D101200DF103018DF80300522051 -:1020700010F08AF804E04FF400500121F9F7FAFB60 -:102080001448007818B13078A17881420DD201202F -:1020900012F02EF8012808D10020297EE0700E48A9 -:1020A00017F068FEA178013106E00120297EE0707A -:1020B000094817F062FE0021A1701EB070BD00BF7C -:1020C000A86D0020C9270020AC2200202426002073 -:1020D000E5270020C8270020AE79002070B596B013 -:1020E00004460079042805D13348007810B117F070 -:1020F000F5F810B1C22016B070BD3048016809ADC6 -:10210000284617F0ACFE2168284615F0C8FF0028C5 -:10211000F0D020680DF102010BAA07F019FB9DF821 -:102120000210C2200029E6D09DF83C100129E2D11E -:1021300005AD4FF481700021102200262B4617F0C8 -:102140001BF8032008212A468DF803000DF1030037 -:1021500001AB0DF061F84120CDE9106612968DF8C3 -:1021600054608DF842004FF48D70ADF8440010A813 -:10217000FDF782F89DF854000028BBD11398456CF8 -:102180000F2028702079687016F0B6FE09AC014661 -:102190000822204617F05AF9A81C214617F05FFEC6 -:1021A00005F10A0001A9102217F050F910A810F04B -:1021B0002BFA9DF854009EE724260020EC580020BE -:1021C000F8B51446A0F19802062A0AD80FF20401C5 -:1021D000DFE802F0041111111A1D31003048807C33 -:1021E0002CE08B282DD0872844D0802803D12C4880 -:1021F000808C208023E081283AD3D82838D82849F9 -:10220000084410F8810C19E014F0F2F916E02148A6 -:10221000007801282CD82048204A4FF6FE7300256C -:10222000017800208D4209D232F8086B9E4218BF17 -:1022300001300135F6E71A4890F82600207000209A -:10224000F8BD14480078012812D81348134A002317 -:102250004FF6FE7500260078864213D21788AF42EB -:1022600003D0DFB28F420FD0013301360832F3E7DB -:10227000C920F8BD084612F0BFFE18B1014620463D -:102280001C2204E0C120F8BD11462046082217F0A8 -:10229000DDF8D4E724260020D6BA02004C500020F6 -:1022A000A86D00202DE9F04387B004460846994602 -:1022B00090460E4616F059FD304614F09EFA2E4F09 -:1022C000386858B10320314608228DF8100002AD5D -:1022D000284617F0BBF83968284688472748007811 -:1022E00001283AD80220ADF80A4003968DF8100074 -:1022F0000020ADF80800304617F030FDB9F1000FAE -:1023000027D128B9204631460DF096F9AA2820D1C8 -:1023100016F0E4FFE8B905AAAB2000210CF0F0FDAF -:102320000DF107013046002207F012FA1448007838 -:10233000012808D19DF8070028B900208DF8110068 -:1023400002A80AF0AEFD01208DF8110002A80AF0E3 -:10235000A8FD3046414613F0D7F82046002114F07E -:10236000B4FE0848818C204613F0A5FD15F038FB1B -:1023700007B0BDE8F08300BFF8230020242600202A -:10238000C2270020A86D002070B586B00446807A70 -:1023900058B9E07AC00608D43048C825007801282A -:1023A00053D12D48007801284FD1616820880DF164 -:1023B000160213F065FFA07A98B12B4E306A70B107 -:1023C000208861686D460822ADF80000A81C17F04F -:1023D0003DF82089316AADF80A0028468847002573 -:1023E00036E0E07AC10602D4C0F380001FE01C484A -:1023F0001C490078097808431AD100206D46142141 -:102400008DF81500284617F089FC60680DF115015C -:102410002A4607F09DF99DF81500002818BF0120F5 -:102420009DF810100239B1FA81F14909084028B12C -:10243000204609F03FFD054620B9BEE7E07A0007D7 -:10244000BBD4AD25606814F0D8F9204604F01AFF1B -:10245000284606B070BD00BFE7270020A07A002004 -:1024600004250020BE27002054750020BCB504467A -:102470004089410622D432490978012927D83149B7 -:10248000897B89072ED523684021228B01EA901190 -:1024900018881B6A9D8800914FF6FE73294602F04A -:1024A00045FCA84202D0218B884217D12068022225 -:1024B00000230188284609F0C4FC13E02068008846 -:1024C00011F03AFC40B16FF0010001300CE002293C -:1024D00008D117F0B5F901E0206800884FF6FE71C9 -:1024E000884201D1CD250FE02168088080B211F02B -:1024F00023FCB0FA80F0226813494009D0811046CD -:1025000007F05AF8054630B120682946407B0FF0A5 -:102510002FFA90B90CE00A4800250078022807D16C -:102520000A48007820B920200121F9F7A3F90025F5 -:102530001CB120460121FDF77BFA2846BCBD00BF37 -:1025400024260020A86D0020914F0200E5270020DE -:1025500070B50446C80711D1880758BF70BD324C0A -:102560001C200021A0471D200021A0471E20002183 -:10257000A0472E4C2E4D1C2021463DE02A4E1C200B -:1025800000211546B0471D200021B0471E20002124 -:10259000B04720460AF06AFA2988C60F40F60200C2 -:1025A000224C814206D043F60700814204D0B1F5A7 -:1025B000C15F14D1E87B01E095F8240040060ED0FD -:1025C0001C202146002205F0EDFE1D20214606B309 -:1025D000322205F0E7FE1E2021462F221FE046B1E1 -:1025E000134D1C2021462F22A8471D2021463222B0 -:1025F00007E00F4D611C1C200022A8471D2021462A -:102600000022A8471E20214600222B46BDE870402C -:102610001847002205F0C6FE611C1E200022BDE8FE -:10262000704005F0BFBE00BF0D93020000600020A7 -:10263000A58301002DE9F0418EB004464A1E00201A -:1026400012F1030F0AD809AA0490029107922F4AA7 -:1026500006928DF814000222684600E003220C90D6 -:102660008DF834202020EFF3118680F31188608AE2 -:1026700030B1608A01386082012086F3118842E01F -:1026800000293DD02248012104F1140790F8088068 -:102690000172806909AD45620B9011F09FF9A06944 -:1026A00009970A900560A5619DF83400022808D1B9 -:1026B00018494A680C98016042601060486005F053 -:1026C00095FD86F31188404611F0A6F92021EFF31D -:1026D000118081F311880C9939B10A684B681A602E -:1026E0004A6809684A6000210C910B9900224A62ED -:1026F00080F311889DF83400002818BF012002E003 -:1027000086F3118800200EB0BDE8F0816752020008 -:102710003822002008200020B0B504463048007858 -:10272000A8B130488068006C0068007D78B144B181 -:102730001B2C06D0E92C0AD12B484088B0F5105F3D -:1027400005D12948C07B16F0BDFC12F0E9FA2748F4 -:102750000021017026480170A4B922488068D0F891 -:10276000D41091F85310882908D0224909780529F6 -:1027700008D1006C0068C08A400703D417F096FBAC -:102780001D494860174DA868D0F8B8100A7872B192 -:10279000496C61B120468847E868C068007898B9FC -:1027A000A8680021D0F85824002090470CE0D0F809 -:1027B000AC00007808B90EF06FFB0DF069FDA86859 -:1027C000D0F8701220468847A868006C006818B1DD -:1027D000007D352808BFB0BDBDE8B04016F090BC04 -:1027E000A02700200C010020C07700202D2600200B -:1027F000B87A0020BB7A0020602600202DE9F04343 -:1028000087B0044600200D4631498DF807002F4857 -:1028100009780078084301D1012452E0F4B1EDB108 -:102820000DF108080DF107012846424606F090FF19 -:1028300081464FF6FF70814521D09DF8070078B1A1 -:102840009DF8180060B99DF81B001022234600F087 -:102850007F01052013F0F8FE002432E0022430E06E -:102860001C4800260788B1B2B94208D205201022C0 -:1028700023460DF0D9FA092803D00136F3E7B22434 -:102880001FE008F108002946082216F0DFFD46F097 -:10289000800000244946142243468DF81B00042082 -:1028A00003948DF81840029413F0CEFE0A4909EB08 -:1028B000490041F8204001EB80000121C0E90144BA -:1028C0004172204607B0BDE8F08300BFBC2700205E -:1028D00024260020BEBA0200F03300202DE9F04784 -:1028E00088B006461398DDF840A01D4691468846FC -:1028F00050B1149C4FF6F777601E80B2B84204D3F3 -:1029000017F088F90446F7E70024C120BAF10F0F49 -:102910004DD111990F294AD1264F129887F82F00CF -:1029200040F60F7087F82E50C7F82890B8854FF6FC -:10293000FF7086420AD120494FF6F77008300E88A2 -:1029400080B2864202D117F065F90646B8F1000F51 -:10295000BE8409D0404616F0FBFB012804D107F1E4 -:102960003900414617F07BFA07F13905284616F081 -:10297000EFFB18B9E220294613F0C4FC0020FC82CA -:10298000182187F83800788340F60F70B885052045 -:1029900087F8260001AC201D17F0C0F9B86A019035 -:1029A00097F82E008DF8090020460CF00BF908B0BE -:1029B000BDE8F087A86D0020902700202DE9F8439E -:1029C00015460C46804608F0A7FA2C4800212D4FEA -:1029D00001602B4881460068386881692720884754 -:1029E000294E2A49306B08403063B06F20F4807064 -:1029F000B0673868016B4FF4806088473868016BB6 -:102A00004FF4816088473868016B4FF4C060884795 -:102A10001F48012101601F48C6F8804131600168EC -:102A2000890704D4691C08BF4FF04045C560D9F838 -:102A30000000F0698007FCD507200FF0C9F90228D3 -:102A4000FAD1B8F1000F13D1134C386A81682046CF -:102A500088470428F9D0012804D1386A0321426844 -:102A600020469047D6F8180220F00300C6F8180256 -:102A70003868806BBDE8F843004700BF0C40094050 -:102A80002C200940B80100100C200840FFFFFEFE7A -:102A900028200860100009400040034070B520392C -:102AA000062918D8DFE801F01A23042D3840480021 -:102AB000147800222321FF2CF1D0D0E9015695F89B -:102AC000FB0010F035FB726B2B49204685F8FB406C -:102AD00005F068FC49E06FF001044AE0406890F8B6 -:102AE000F910012943D1012180F8FC103DE045682F -:102AF0000021002495F8FB0012F0A6FC85F8FC40AC -:102B000037E0446894F8FB00FF282ED010F010FB4B -:102B1000FF2084F8FB0028E04068D0F8C01031BBEB -:102B2000012180F8FE1020E04068D0F8C010F1B913 -:102B3000002480F8FE401CE04168D1F8C020B2B10A -:102B400091F8FE209AB180680268D0E90430546A96 -:102B5000184344F003045462D1F8CC104968096862 -:102B60008862506840F002005060002401E04FF09D -:102B7000FF34204670BD00BF026000202DE9FF41F8 -:102B800005464FF6FE70854222D00C4601B3DFF8B1 -:102B9000C480D8F80C7007B3B91C2046082215F081 -:102BA0009FFB60B198F830000026B87211E0B11CAC -:102BB0002046082215F094FB0028374645D1FE68D0 -:102BC000002EF4D1102017F09FF9F860A8B93AE070 -:102BD0000226304604B0BDE8F081102017F094F9C9 -:102BE000C8F80C0078B31C484FF400614FF47A72B7 -:102BF000007817F0ECF8D8F80C0098F830100026A0 -:102C00000580851C0822C66081722846214616F080 -:102C10001DFCD8F808000028DBD001AC29460822AA -:102C2000601C16F013FC04F10A01284613F08BF81F -:102C30000948092100220C238DF8046000940078D3 -:102C400010F0DFF9C5E70126C3E798F83000B0724D -:102C50000026BEE7AC220020A37A00202DE9F84F21 -:102C600016F00EFF2F4D2C4644F8100F16F002FF01 -:102C70000027206818B100F118040137F9E72C6922 -:102C8000002C46D04FF6FE70DFF89CA0DFF8A0B015 -:102C9000DFF898900026FDB201301FFA80F8F0B2FC -:102CA000A84235D2504616F053FA012806D104F155 -:102CB0000C01504614F051FE38B922E0B9F800007A -:102CC000404502D0218881421BD12089BBF81A10CF -:102CD000884203D14FF6FE71884208D1154800782A -:102CE000022801D2E07801E001D1207948B19BF8B7 -:102CF00012006179814208D10F48A17900788142A0 -:102D000003D0204611F0D4FA013FA4690136C6E78A -:102D1000044D6A6922B12869F9B2BDE8F84F10473D -:102D2000BDE8F88FAC220020AE790020902700206B -:102D3000A86D002024260020E8270020B0B52F4CE5 -:102D4000608810B12E49098814E02E494FF4707242 -:102D50008968D1F8F410C98F02FA01F12A4A01F505 -:102D60007071127851434FF47A72B1FBF2F1244A38 -:102D7000118089B288421AD225492448096800681E -:102D8000096C88472278C1B2914288BF2070608860 -:102D90000130608017F088F84FF47A711E4B0022E2 -:102DA000B1FBF0F01B49BDE8B04007F0A7B894F9BB -:102DB000000013F08BFD134901258A68D2F8F42036 -:102DC000936992F8442098548868D0F8F40090F8F9 -:102DD000442000EBD20002F00703427905FA03F326 -:102DE0009A43427100202070608088680421D0F8E6 -:102DF00094000078BDE8B0400BF088B94C24002066 -:102E0000425E00200C010020B47A0020E42600205D -:102E1000347A00203D2D01005C7A0020F8B516467A -:102E20000F46054616F0E8FC0446092F3AD8DFE8BD -:102E300007F00508111417313B1B4B2C3068286034 -:102E40004AE001206876D5E9040160306031C5E9C7 -:102E5000040141E0306868833EE03068A8853BE0CB -:102E600030682249886037E01F4820490025806B80 -:102E7000097E91BB88BB1E483168283016F032FCB1 -:102E800031681C4816F02EFC26E02020314614F054 -:102E900037FF21E0306801281BD018B9802015F0D9 -:102EA00057FA19E0032518E00F4810490025806BF8 -:102EB000097E91B988B93168192015F0A1F93168F6 -:102EC0001A2015F09DF907E03078064981F8600076 -:102ED00002E0802011F0D2FD8325204616F047FF46 -:102EE0002846F8BD206E002030210020D01E002092 -:102EF00070200020407200202DE9F84F9346426870 -:102F00000546936803EA0100884255D1D5F808A028 -:102F1000DAF804408C429CBF6FF00300BDE8F88FE4 -:102F20000BEB01066FF00500A64247D803EA0B033E -:102F30005B4543D1BAF82000DFF89490E846C9F821 -:102F400008005068C9F80400DAF800004618BBF120 -:102F5000000F39D028460BF0BFFE88BB284612F080 -:102F60005BFD68BBBBF5803F05D3B0B218B94FF429 -:102F70008034D82002E0DAF8084020208DF80000E4 -:102F8000300AB9F808108DF803608DF80200300C93 -:102F90008DF80100284616F00CF9404604210CF08B -:102FA00071FEB9F808100746284616F00BF93FB92C -:102FB000ABEB040B2644CAE76FF00400BDE8F88FC2 -:102FC0004FF0FF30BDE8F88F0020BDE8F88F00BF5C -:102FD0000C240020F0B50022C1F802204A73838D32 -:102FE000027F4B83C3890A754B81836A1C4614F8A0 -:102FF000015B15F003060D7003D0032E45D0022EA1 -:1030000028D105F00C060C2E05D015F0100702D1C2 -:103010005C788C709C1C082E02D101260E7306E091 -:1030200000270C2E0F7302D134F8020B08E046790A -:1030300006F00306012E04D145F00C0540890D7001 -:103040008880E80606D42088C880608808812079B6 -:103050000534C870204610F8016B4E756EB2B6F19B -:10306000FF3F0BDD00244C700861181A1318404212 -:103070004873D8B20B75824207D3F0BD607803283D -:10308000487002D828B1032805D10020087548737C -:10309000F0BDA01CE8E7A078C87505F00300022881 -:1030A00011BFE01CE0780876201DDDE7F8B5044686 -:1030B000807A022851D1A07BE0B12948006800281D -:1030C0004BD026480078012847D126480078C00711 -:1030D00043D0042014F032F900283ED001464FF4CA -:1030E000B2700880608848801F480078BDE8F840CA -:1030F0000CF03AB82048016879B11E4F386860B1C9 -:103100001B4E306848B1194D286830B1134800781B -:10311000012802D16088884730B1608801210122EE -:10312000BDE8F84000F02EB81448007830B11449DA -:1031300051F82000C0EB0010810001E01048016848 -:1031400060883A689047012807D1608831688847CD -:1031500060882968BDE8F8400847F8BDCA27002004 -:1031600084230020DC2700209C7A00209823002064 -:103170009C2300209423002088230020D7270020B0 -:1031800090B402002DE9F84F14460E46824614F022 -:10319000CDFAD6B3C8BB2B4929480126009409783B -:1031A000043051B10278FF2A03D030F8042C524584 -:1031B00004D0243001397600F3E700262248254F59 -:1031C000DFF894B06FEA06090025047800205FFA62 -:1031D00085F8A04518D217F8081099B15BF8282097 -:1031E00032420FD0084615F0B5FC50B1417B05299D -:1031F00007D15BF82810254601EA09014BF8281091 -:1032000000E000200135E2E7009C70B1417B052918 -:103210000BD10168A1F800A0012141730B482021C6 -:103220000078BDE8F84F0AF071BF34B10848818CCE -:103230005046BDE8F84F0EF0E7BABDE8F88F00BF82 -:1032400020450020E3BA0200CEBA02009C7A00209A -:10325000A86D002058760020306D0020F0B5314A6E -:10326000046A516B137D0C61446A01F1200C032B3D -:103270000B704C61846A8C61C46ACC6190E8F00088 -:10328000ACE8F00000F1400400F110074C64F0CF0E -:1032900001F1300CACE8F000046B0C64446B8C64FE -:1032A000846BC06BCC6408650BD8DFE803F0020DBB -:1032B0001016156DC4B2106C936C55F824404C6018 -:1032C0000FE0002000230CE01748406D06E017488F -:1032D00080694860D0E90A3003E000204860106C43 -:1032E000936C926BC1E9020332B12BB110F8014B20 -:1032F000013B02F8014BF8E70D4802684A6590F877 -:1033000024208A6590F82520CA65C28C0A66826AE4 -:103310004A66C26A8A66026BCA66426B0A67806B3B -:103320004867F0BD381F0020A01F00203822002071 -:1033300004ED00E07CB500208DF8070016F02CFEAF -:1033400029494FF0FF32294D294C097802FA01F141 -:1033500088432880A068D0F8B800017841B3826B18 -:1033600032B30DF1070142F21A009047214E307836 -:10337000B8B17078A8B99DF8070090B1A068D0F8EE -:10338000B800C06D68B1804758B1E2681A49526808 -:103390000978127808325143B0FBF1F029880844CB -:1033A0002880288871789DF8072011FB020028806A -:1033B0001248007810B116F0F5FD01E016F0F0FDAE -:1033C000A068006C006840B10D48007810B90D4845 -:1033D000007818B10C48022101707CBD0A48832195 -:1033E00001700FF071FD7CBDB97A0020C679002014 -:1033F0000C0100202D260020B47A0020BB7A00208A -:10340000B07A0020B37A0020B87A0020F8B5304DA9 -:10341000212074212A4616F051FB80B100240FF0C0 -:1034200033F92D480078012898BFFAF70DFF2B4893 -:10343000006800B180470CF0A7FB2046F8BD2120B2 -:10344000002174222B46002415F096FE0028E6D1B8 -:10345000E88A4FF6FE718842E1D095F826000828E8 -:1034600001D0042831D10DF103061A4F0124422066 -:1034700031468DF80340B84705F12F014320B84786 -:1034800005F12C014720B84705F11C014A20B84737 -:1034900005F11A014B20B84705F124015020B84727 -:1034A00005F116015320B84705F12D015420B84706 -:1034B00005F11801E120B847A87B3146C0F3C000F0 -:1034C0008DF803005220B847A9E7FEF7C3FBA5E734 -:1034D000A86D002089210200242600200424002059 -:1034E000F0B58BB0054602208DF829000AA813F02C -:1034F000F7FA002857D00446006946F2040101801B -:103500000120A077A07615F0F7FC2848658060625E -:10351000E07E20B926480178E17601310170207EF5 -:10352000234F012805D1F87A18B9207808B900206E -:1035300020760DF127012046F8F7ECFD80B3054613 -:10354000242016F0E1FC029038B32421064616F040 -:10355000E5FB0DF10601502012F0D4FEF88ABDF80B -:1035600006109DF82720ADF820006088718130801A -:1035700002203073307202980562617DC2770122A9 -:10358000C28141738DF81410E08AADF8120002A8D0 -:1035900016F07CFA029816F0B5FC284616F0B2FC3C -:1035A000204616F0AFFC0BB0F0BD00BFE079002064 -:1035B000A86D0020F0B589B0304CADF8221015464A -:1035C00007460E9AC22094F82610ADF82020042950 -:1035D00052D0082950D04FF6FE70824201D1C3204C -:1035E0004AE001A81C211E4616F098FB03200DF1AD -:1035F000220184F8260050200EF0C6FD08A94B20B9 -:103600000EF0C2FDBDF8220039462576A673A084CF -:10361000BDF82000608304F1390016F020FC06F0AC -:103620004E0080308DF81E0015480078012803D820 -:103630000F98013084F8380002208DF80F500F25C4 -:1036400021468DF81A00BDF8200001F82D5FADF875 -:103650001200BDF82200ADF81C0000208DF80C000F -:1036600054200EF091FD04F82C5F472021460EF007 -:103670008BFD01A803F09CF809B0F0BDA86D0020F7 -:10368000242600202DE9F04F89B00E46814601A87E -:103690002021904616F042FB202E08D0182E09D08B -:1036A000102E0CBF4FF0010A4FF0000A04E04FF05B -:1036B000030A01E04FF0020A0125234F234805FACF -:1036C00008F47C608346006841692720884703200E -:1036D000C7F88053C7F88403C7F80053C7F88803B6 -:1036E000B868824518BFC7F808A0182E3C6008D1FA -:1036F00001AE49461822304616F02CFC30462021F7 -:1037000001E048463146002200230FF001FE104838 -:1037100013F0BAFD0546DBF80000016A2720884750 -:10372000DBF800000169272088470020B0EB957F77 -:1037300006D17868C04320FA08F000F0010000E0EC -:10374000012009B0BDE8F08F00440240B001001034 -:10375000030000C070B52548066813F0FDF9244841 -:103760000025244C0560206C806C8047224800684E -:1037700038B122480068B6F1FF3018BF304602F079 -:1037800007FB1F4840F2391205601E48016862F3CA -:103790001B4101601C48016801F44051B1F5805F94 -:1037A00006D10168194A114001F50032026001603A -:1037B000174D0126EE612068016A142088471548DC -:1037C000016841F4E021016013482E60006800F4B4 -:1037D0004000B0F5000F03D1206C416C0F488847C2 -:1037E0000F4801680029FCD170BD00BF1C130050B8 -:1037F00084046042B001001080012843800520430A -:103800008C2108404820034028000940EFFFFCFCC1 -:103810000000244300200940B44F0050BD3786000B -:103820000C00684270B5F8B1012858D1012016F09B -:103830008BF8012853D02D4C94F8380100284ED134 -:103840002848294E0569306810F4402F30D17DB3E7 -:1038500014F006FA502016F093FA0120A84704F15C -:10386000940016F02BFB25E016F050FB1E48006874 -:1038700010F4402F0AD11B4804693CB11B48943016 -:1038800016F06FFA14F0DCF90020A047174C94F8FA -:10389000380120B31648016821F0800101608021C1 -:1038A0008160032011F0D0F8002084F8380116E080 -:1038B00016F030FB012084F83801306810F4402FF6 -:1038C00000D14DB9207A800606D409488021816054 -:1038D000016841F080010160032011F0EDFE00203D -:1038E00070BD00BF18B80200B44F0050D81B0020B4 -:1038F000902208402DE9FC470446E820002C59D0CE -:103900008A46002956D06068DFF8B49000260DF191 -:103910000408411E61603F2100F8011CA16D606830 -:10392000B1FA81F1421E49096260C90100F8011C27 -:103930000220A4F85400208902302081022E36D0C3 -:103940001AF836002A2802D0FF282ED12FE00AEBE1 -:10395000C605686848B3D9F80810D1F8B810896965 -:10396000884707466068C01B606069684A0707D4DB -:10397000D9F808200023D2F8B820D56922460AE0F9 -:10398000D9E902239B68D2F8B8201B78D569224672 -:103990008DF804304346A84770B12089384420810F -:1039A000B4F854003844A4F854000136C6E76068FF -:1039B00020650020BDE8FC87EB20BDE8FC8700BF48 -:1039C0000C010020F8B52B480068C06B80472A49DD -:1039D0002C4B09681B68411A284800788200B1FB0B -:1039E000F2F1274A12688B4201D9934202D38A42EC -:1039F000134623D9591A4FF00003A1FB001263F1BB -:103A0000000303FB0020204A1268538B12691A44FA -:103A100064328D1A60F10006681E76F100000DDB3D -:103A200016F042FA07462846314600233A4615F07A -:103A30000DFB0446E81B76F1000001D2012015E0E1 -:103A400016F0E3F8114E0546306816F033FA10B15F -:103A5000306816F086F9284616F0C5F93068214618 -:103A600016F02AFA306816F029FA00200849087082 -:103A7000F8BD00BF347A0020307A0020B47A0020EC -:103A80003C7A0020407A0020E426002034270020E1 -:103A9000B67A0020B0B586B00446008810F04CF924 -:103AA00010B915F01BFC08B106B0B0BDA178207AA2 -:103AB00039B30428F8D129480DF10301006801AA9F -:103AC00005F046FE01469DF803000028ECD09DF865 -:103AD00014000128E8D19DF917200020CDE901004C -:103AE000002A03D401208DF81500FF208DF8140062 -:103AF00001AB0420142212F0A7FD022015F084FF70 -:103B0000D2E70428D0D115480DF10301006801ADBA -:103B10002A4605F01DFE04469DF803000028C3D088 -:103B20009DF814000128BFD102208DF814009DF9E2 -:103B30001700B0F1FF3F03DC05F1130010F01CF893 -:103B400001AB04202146142212F07EFD002015F066 -:103B50006DFF01200121F0F751FEA5E7EC58002090 -:103B6000F8B515460E46044610F0E6F808B10020F8 -:103B7000F8BD204600210DF0BBFC294606F0FEF9F9 -:103B8000C8B107464079032807D00128EFD17888CB -:103B900007210FF08DFE0028E9D1B87910F0180F39 -:103BA0001AD07888214600224FF6FE7300903046E6 -:103BB0000CF064F934E0204614F0E6FB16F071F8DE -:103BC0000028D4D04179CA07D1D08A0706D441F061 -:103BD00002010127417109E0022707E03046214632 -:103BE0000122012709F05AFE0028C0D030460021EA -:103BF0000DF07EFC0B49C98A884206D10A48294645 -:103C000002782046FAF7A2FE0AE0304621463A46FC -:103C100009F044FE0028AAD12046294613F055FA9F -:103C20000120F8BDA86D0020CABA02002DE9F84FA6 -:103C3000DDF82CB088468DF80300042015211E46BF -:103C400017461BFB0100012151FA80F016F05CF9C8 -:103C5000002849D081460C990A9800240425CA46B8 -:103C60000AF8017F8AF802008AF801600AF104006C -:103C700001F10C068AF803B0E1B2594521D2A6F150 -:103C80000C07394616F0EBF8397A0170B97A4170B1 -:103C9000F97A8170397DC170397D032908D10430EA -:103CA000314616F0DCF8B17A153500F8011B05E055 -:103CB00031780E3501717178417106301836013452 -:103CC000DAE70B4EEBB20DF10300414648F2330246 -:103CD000C6F804A00BF000FC0446484616F012F9A2 -:103CE00004480130706000E010242046BDE8F88FE1 -:103CF000882600204470002070B5314B04255C6894 -:103D000059B952B1D379157B2B440C2505EB4305EA -:103D1000EBB2502B84BF102070BD2170EBB28169D3 -:103D2000052B0978617081694978A17023D3291F17 -:103D3000E1701178217191786171D178A171117957 -:103D4000E17151792172917901F00F016172D1799C -:103D5000A172D57995B10021A9420FD2956815F8C5 -:103D60001150E572956805EB410501316D782573B9 -:103D70000234D579F0E70021E17016E004F10B017F -:103D8000147B0C70157B85B10024AC420DD21569F3 -:103D900001EB440615F814507570156905EB4405E0 -:103DA00001346D78B570157BEFE700F11102811CCD -:103DB000104648F20402BDE870400BF08DBB00BF16 -:103DC000882600207FB504464078DB3818280CD8B8 -:103DD000012101FA00F02C49084206D02B488068E6 -:103DE000D0F80412204688477FBD284EB068D0F82E -:103DF000FC112046884750B9607C38B194F83400F3 -:103E000020B9B068D0F8B810097811B100206070FE -:103E1000E4E7D0F8342204F1120109209047002889 -:103E2000F4D00546B06804F10B01D0F83024E72047 -:103E30009047B06804F10801D0F830245020904732 -:103E4000B06804F10A01D0F83024E1209047022044 -:103E500023894FF6FF728DF80C004FF0FF30ADF85C -:103E60000400B068D0F8C061A07A009001A928468B -:103E7000B047A0F1DB011829B6D8012202FA01F1FE -:103E8000014A1142C3D1AFE7112000010C0100200B -:103E90002DE9F8432020EFF3118980F311882C4895 -:103EA0000068006B80472B4E4FF000082A4F01221C -:103EB00086F85D8086F85C20D7E9104522462B46BF -:103EC00015F0C4F8A0FB042300FB053301FB04310B -:103ED000746DC7E91221B168B268611A821A914201 -:103EE00005D986F85C8089F31188BDE8F883051B45 -:103EF00089F311880020854206D304442D1A01203D -:103F000021460AF073FBF6E72021EFF3118781F3D6 -:103F1000118896F85D1019B1002021460AF066FB61 -:103F2000411C05D0411BB06D814238BF084600E0FE -:103F3000B06D011914F03EFE002086F85C000120EF -:103F400086F85E00B46087F31188BDE8F88300BF8F -:103F50008C01001008200020886E0020F0B585B08C -:103F60000D4600211446CDE90311CDE9011101A947 -:103F7000009104A903AA02ABFBF742FC029F002FA9 -:103F8000394618BF0121019E0140002E324618BF5C -:103F900001221140002D10D411B3049840F22B21BE -:103FA00005806FF39F5538462A4613F07BFA039835 -:103FB000314608F0ABFF676010E0C9B104984FF0DC -:103FC000FF316FF39F552A46018030462B2113F0B5 -:103FD00069FA0398314609F0CBFB666015201EE0B4 -:103FE000C8B104984FF6FF720188914214D110E0D5 -:103FF00078B16FF39F5503982B212A4613F052FA9C -:10400000FF2806D004984FF0FF310180142065602E -:1040100005E0032005E004980580658010202080DD -:10402000832005B0F0BD7047B0B588B0C1890446A3 -:10403000A1F1210002281ED3A1F50040022826D3B9 -:1040400048F22100081A022832D2274800780028B6 -:1040500047D126480068002843D048F221020220B8 -:10406000914208BF0320A169627C097808B0BDE8CD -:10407000B040F6F7F3B9207B98BB6D462046294641 -:1040800010F052F820462946F9F742FD29E0204673 -:104090000AF0CCF828B30446007818B96088211DCE -:1040A00014F0D4F9204608B0BDE8B04015F02ABF9E -:1040B000202916D10C48007898B96D46204629462B -:1040C00007F036FA2846F7F711F89DF8120010B1FC -:1040D000059815F017FF9DF8180010B1079815F016 -:1040E00011FF08B0B0BD00BF2426002044270020E7 -:1040F0002DE9FE4F8946097A2D4CDDF830A0174690 -:104100001D464FF000080F29666804BF4FF6FC718A -:10411000A9F8001048F21F018A45029011BF4FF024 -:10412000010B002006F8010B4FF0020B30460BF19B -:10413000500100F8017B0191B8F1090F14D86178A2 -:1041400005EBC10115F08BFE617808F101080BF158 -:10415000080B01316170C9B2B942EDD1002086F877 -:1041600000806070029C19E00A2030706078B842CC -:1041700012D2BAF11F0F08BF13F0DCF948F21F008A -:104180008245DDE901B409D10A484FF480410A2291 -:10419000007815F01FFE01E0DDE901B45FFA8BF352 -:1041A00020464946524603B0BDE8F04F0BF094B9A3 -:1041B000882600209D7A00202DE9FE4F994615465D -:1041C0000F46044615F070FE4FF47A71B1FBF0F023 -:1041D000454315F01AFD80462046394613F040FE4F -:1041E000AB4688B10646006815F0BBFD30685946FD -:1041F00015F062FE306815F061FE0824404615F0A7 -:10420000F2FD2046BDE8FE8F142015F07DFE00284B -:10421000F3D0EA460646504615F0A7FC0120029668 -:10422000594652468DF80000B9F1000F124808BFF8 -:104230004D4601950EF05EFF306070B10F4A0021CF -:1042400086F80C90B76034713161116849B10A4643 -:1042500009690029FBD1166105E0304615F052FED0 -:10426000CBE716603068594615F026FE306815F029 -:1042700025FE0024C2E700BFA5EE0100782600203D -:104280002DE9FF41044690F91900B0F1FF3F01DD2F -:10429000BDE8FF81207D40F002000328F8D1DFF85F -:1042A000A480D8F80800D0F89810098911F00A0FF6 -:1042B000EED061684A78C2F38102032A8DF80C209F -:1042C00008D0022A0CD1B1F80520ADF80420B1F8CD -:1042D000032005E0053101A815F0C1FDD8F808005C -:1042E000C16BA4F10C0795B201AE0868C0B190F99A -:1042F0001910B1F1FF3F3946F7DC017D41F00201B1 -:1043000003293946F1D14268D8F808002946D0F887 -:1043100068333046984700283946E6D0002CB7D19C -:1043200015F076FA30B101A82946002210F082FF7C -:10433000BDE8FF81D8F80C002946826F01A890479C -:10434000BDE8FF810C010020B0B52B498968D1F888 -:10435000D420527B0F2A1FD0D1F8AC301B78DBB1B0 -:10436000D1F8EC10274B0024274D51F82210234A96 -:10437000127851434FF47A72B1FBF2F22049096886 -:10438000891A38BF21461B689B1A38BF23462D68FF -:10439000AA1A38BF224605E01A4A194913681A4A70 -:1043A000096812684FF47A74624382420CD96343FD -:1043B00083420FD94FF47A734B43144983420978EF -:1043C0000ED991B100210EE01049097803290CD0D3 -:1043D000032108E00D490978022906D0022102E0F4 -:1043E000012902D00121094B19700021824288BFA6 -:1043F00001210846B0BD00BF0C010020B47A0020A6 -:10440000147A0020107A00201C7A0020A47A002060 -:1044100010B52E488168D1F8B020D1F8881311600A -:104420008168D1F8B020D1F89C1351608168D1F82F -:10443000B020D1F8A01391608268D2F8B010D2F801 -:104440008032CB60D2F8B010D2F8A4330B61D2F82E -:10445000B010D2F87C324B61D2F8B010D2F884326E -:104460008B610021D2F8B030D961D2F8B030D2F8E7 -:104470008C431C62164CD2F8B0305962D2F8B0307E -:104480009C62144CD2F8B030DC62D2F8B430D2F86E -:1044900048241A608268D2F8B430D2F8A8235A604F -:1044A0008268D2F8B430D2F8AC239A608068D0F831 -:1044B000B420D0F8B433D360D0F8B420D0F8B033FF -:1044C0001361D0F8AC00017010BD00BF0C010020DA -:1044D000419E0200A99F0200F8B5064600780C46EE -:1044E00015F044F808B1B82557E00025002C54D049 -:1044F000307825732070142015F006FD0028A06088 -:104500004AD031780170B6F801104180B6F8031036 -:1045100081808179727901F0F00102F00F0211447B -:104520008171F179A0680836C17171B1480015F048 -:10453000EBFC0146A068816051B1C2792AB136F81E -:10454000023B013A21F8023BF8E70027002501E091 -:10455000102501273178017379B1480015F0D4FC9A -:104560000146A068016149B1027B731C2AB133F88E -:10457000026B013A21F8026BF8E777B1816819B153 -:10458000084615F0BFFCA068017B19B1006915F061 -:10459000B9FCA06815F0B6FC10252846F8BD704798 -:1045A0002DE9FE4FDDF834808DF80B0005209B4689 -:1045B00016460D4608EB480400EB8400C0B215F027 -:1045C000A3FC002846D08146042001950E9D0027BB -:1045D00000EB8400CA464FF6FE740AF8016F0090A3 -:1045E0000C988AF801B00AF104064FF0FF0B8AF824 -:1045F00003808AF80200F8B2404517D205F10C0199 -:10460000304615F02CFCA8783072A8797072697960 -:1046100086F80AB040EA011070722889001B18BFA2 -:1046200001200137F0720C36AD69E4E700980B4DBC -:10463000019948F23002C3B20DF10B00C5F804A095 -:104640000AF04AFF0446484615F05CFC0448013075 -:10465000686000E010242046BDE8FE8F8826002018 -:10466000447000202DE9F04F8FB00E469B468246E5 -:10467000087849781446F378B27801EB0009042BE6 -:1046800038BF9144F76838BF00225FFA82F815F00E -:10469000BCFA234900250190C96811B1F078884718 -:1046A00000E0002000900BA83946102215F09EF87B -:1046B0000746B0FA80F0F178400903295BFA89F1E6 -:1046C00088BF0125414428405FFA89F5BAF1000FFF -:1046D0000FD0F0B10DF108090F46484615F036FA33 -:1046E00008950BA812F034F80E48006815F02AFB64 -:1046F0000EE070B10DF108090F46484615F026FA94 -:1047000008950BA812F024F80648006815F01DFB68 -:104710000746019815F067FBF8B20FB0BDE8F08FBF -:1047200014250020F87900202DE9F041DFF8B88049 -:10473000D8F80810D1F8E8000068002852D0D1F865 -:10474000E03042681B689A4208DDD1F84C0580478A -:10475000D8F80800D0F8E800006858B144680FF0B5 -:104760004FFE844206D9D8F80800D0F8D404BDE83A -:10477000F0410047D8F80800D0F8E8100C688CB376 -:104780006668B6F1FF3F08DCD0F84C058047D8F8E2 -:104790000800D0F8E80004686668A768257B0FF079 -:1047A0002FFED8F80810864206D8D1F8001520460A -:1047B00088472846B847DDE7D1F8E800006848B1E7 -:1047C000D1F8E01040680968884203DABDE8F0419A -:1047D0000EF0D8BF13F094FBD8F808000021D0F8F1 -:1047E000E8000160BDE8F0810C01002010B52E4A00 -:1047F0001278022A49D12B4A1278002A45D1C207E1 -:1048000006D02A4A136A1160934204BF0023136240 -:10481000020708D5254A134643F8041FDC699C4269 -:1048200004BF00231362C20608D5204A134643F88A -:10483000081F9C699C4204BF00231362820608D5AE -:104840001A4A134643F80C1F5C699C4204BF0023BC -:104850001362820708D5154A134643F8181F9C684F -:104860009C4204BF00231362420708D50F4A134637 -:1048700043F81C1F5C689C4204BF00231362C204FF -:1048800003D50A4A4FF47A735361400408D50748A8 -:10489000024642F8101F1169914204BF00210162D3 -:1048A00010BD00BFE5270020242600200875002049 -:1048B000F0B591B004460078A678676828B1B85D75 -:1048C000617840EA0102BA5503E020460CF05FFC33 -:1048D000BA5DA16904F10800D2B20DF1370313F0FB -:1048E0001AFC6078A178E278237F8DF82700608A2F -:1048F0008DF82410A18A8DF825308DF8262060B916 -:1049000040F20112914208D194F8281004F11E00DF -:104910000DF1030209F058F803E00DF1030205F070 -:10492000E5F8FF208DF823000DF103000C90207CAA -:10493000022803D003280FD1022000E000200DF14F -:1049400013058DF823000DF123000DF1030208215A -:104950002B460AF061FC0C956368207809A90DF1DB -:104960003702FFF77FFEB95D01F0F801B95511B0CC -:10497000F0BD704770B586B0274C2848217801AA51 -:104980000BF0FEF9002004218DF80A008DF80800D4 -:1049900000200FF029F922490D78A8421CD212F00C -:1049A00027F8C8B91F48068836B1032004210FF044 -:1049B0001BF9A91B814202DD01208DF808001A486D -:1049C000068836B1012002210FF00EF9A91B8142A1 -:1049D00002DD01208DF80A002278104C01A8214642 -:1049E0000AF0D9FE452021460DF0CEFB0F481049B4 -:1049F0009DF80A200078097808409DF808101143B6 -:104A000018BF012108400DF117018DF81700412052 -:104A10000DF0BAFB06B070BDB92700202079002048 -:104A2000E3BA0200BABA0200BCBA020004250020B0 -:104A3000972700202DE9F84F82462A4800788842BF -:104A40009CBF0520BDE8F88F50460C46009208F048 -:104A500091FA074624484FF6FE7C0078874216D12B -:104A60004FF6FE7008F086FA4FF6FE7CB8420FD182 -:104A70001E49002001230A78BB4209D211F83350A5 -:104A8000D2B295423CBF18462A460133F4E7384675 -:104A9000DFF858B0C6B20BEBC609C84628F802CFFB -:104AA000454655F8020F18B115F02CFA0020286081 -:104AB0004CB16700384615F027FA286070B10099AC -:104AC0003A4614F0C3FC0A48A8F800A089F801404F -:104AD00000780BF836000020BDE8F88F0120BDE813 -:104AE000F88F00BFD8BA0200D7BA0200503D0020AC -:104AF000DE2700202DE9FE4329482C4E4FF0000808 -:104B00000DF1040900240778BC421FD2E0B211F075 -:104B100083FFC8B1054600790138022814D3E8792B -:104B2000411CE97196F8671088420DD92888A5F8CC -:104B300009800DF029FF2888494611F0EDF8484614 -:104B40000AF00AFA0EF098FC0134DDE715484FF63A -:104B5000FE774FF0000800F10C04134805788DB182 -:104B600034F80C0CB8420AD021784A1C227096F80E -:104B70006720914203D9A4F805800DF005FF1C348D -:104B8000013DECE70A490020032808BFBDE8FE8389 -:104B900011F8202012B1013A01F820200130F3E78A -:104BA000E3BA020030560020D1BA0200A86D0020FE -:104BB0004C790020B0B588B0044640798DF81C00CF -:104BC00020798DF81E00284800788DF81F00206895 -:104BD000E8B113F073FAD0B124480078012825D841 -:104BE00020680DF1120111F0AEF86FF00200A27909 -:104BF000411CBDF81200DAB98AB2904218D0ADF863 -:104C0000140001208DF81D002068069009E00020A6 -:104C10008DF81D0014F070F906906FF00200ADF8E9 -:104C2000140005A803F064FF054619E0002517E00D -:104C3000012289B20025ADF804008DF80E206279BA -:104C400088428DF80F2008BF6FF0370521688DF876 -:104C5000105001ACA01C15F002F9204615F040F9E7 -:104C6000E8B208B0B0BD00BFDD2700202426002038 -:104C70002DE9FC412A4D95F86100002844D000241C -:104C80000026602C40D095F86100F040C00702D1AA -:104C900020340136F5E7112095F8618000FA06F717 -:104CA00014F0AAFD95F86110B94385F8611015F06C -:104CB0005EF8281928D0817A31B31021194A2C596D -:104CC000B14011EA080190F9091052F821804668B4 -:104CD000CFB209D006F0D4F9002079B200224FF00B -:104CE0000073009020460EE0017A022902D1C17CB7 -:104CF000C90601D406F0C4F9CDF8008079B2204687 -:104D000000224FF00063B04795F8610028B10648D3 -:104D10000021BDE8FC4115F00DB9BDE8FC8100BFE4 -:104D2000206E002094300440407200202DE9F843AA -:104D3000994616460F4604460EF0FEFF18B16FF076 -:104D40000100013007E02548089D017820460EF05B -:104D5000AFFD18B1204680B2BDE8F883204600219F -:104D60000CF0C6FB294605F009F978B38046407976 -:104D70004FF6FE75042816D001281FD198F80610AA -:104D8000B8F8020011F0180F10D01549B842097890 -:104D900088F8041018BFB0421DD1384631464A4643 -:104DA000F7F7C4FD06E04FF6FE70D4E70D49097D24 -:104DB00088F80410A842CED198F80500022805D042 -:104DC000204607210EF074FD0028C3D12046BDE81F -:104DD000F84313F0D9BA4845DFD0EBE7CCBA02006C -:104DE000D9BA0200A86D0020F8B505680446D5F8C8 -:104DF000F80000B1F8BD68796668022807D105F1AE -:104E0000D000694612F054FDC5F8F80009E0D5F865 -:104E1000EC10D5F8FC20D5F8F4001144C5F8F800E2 -:104E200000910028E6D031688A6B22F400628A6320 -:104E300095F84410C90608D52F6C37B1AB6C2046E5 -:104E400010210022B847D5F8F800B0F5806F84BF74 -:104E50004FF48060C5F8F8000099336B01444A1E96 -:104E60003168B66B1A600E4A9A6043F6F07202EB34 -:104E7000001010409A6810439860D5F858014068B7 -:104E8000006886620846022113F000FF287A002895 -:104E9000B0D120460121012612F02AF92E72F8BD68 -:104EA000018000C010B5017801290BD002291FD064 -:104EB000FD2932D0D32937D01A2939D1BDE8104085 -:104EC00002F062BE2448007802282CD11F4C2078C2 -:104ED0000138012827D814F0A3FD68B3FDF78AF83C -:104EE00008B32078022827D1BDE8104005F046B964 -:104EF000164800780138012815D815480078072889 -:104F000018BF082805D11349097811B90121EFF715 -:104F100075FCBDE81040F2F7E3B81049096811B11B -:104F2000BDE81040084710BDBDE81040FFF77CB851 -:104F3000BDE8104003F056BB14F0A2FD002814BFDA -:104F400001200020BDE810400BF02AB924260020E3 -:104F50000C7A0020BF7A0020D0260020D824002020 -:104F60002DE9F04F85B0264801ACDFF89C80DFF8D2 -:104F70009CA04FF00109251D00F11C06214807786F -:104F8000D7B316F818BCABF10100012831D830684E -:104F900030B156F8041C02311CBF0138306028E0E3 -:104FA000D8F80020C2B19AF8000030B1184951F881 -:104FB0002000C0EB0010810001E01548016836F8C0 -:104FC0001C0C9047BBF1020F08BF012804D1114906 -:104FD00036F81C0C0968884736F81A0C8DF80490CE -:104FE000ADF8100020460AF0C3FF10B1284609F0C2 -:104FF000B3FF2436013FC3E705B0BDE8F08F00BF23 -:1050000020450020E3BA020094230020D727002087 -:1050100090B402009C23002070B52C4D00282B6812 -:1050200041D0044643B9FA2014F06EFF00282860EE -:1050300049D0002101702B681878152621780822A4 -:1050400010FB0630417061788170A178C170E17801 -:1050500001712179417161798171A179C171E17920 -:105060000172217A4172617A8172A17AC172E17A08 -:105070000173217B41730E3004F10D0114F0E6F948 -:1050800028680178013101702B68187800FB06F15F -:10509000E52918D3012110FB061014F084FD2868BF -:1050A000002101700FE073B1187838B10121152289 -:1050B00010FB021014F077FD2B6823B1184614F092 -:1050C00021FF00202860002070BD00BF5027002075 -:1050D000F0B585B070B1044628480D46C08AA0429C -:1050E0000AD113F009FF2649284612F036FC80F059 -:1050F000010602E000263AE012260020ADF8064044 -:105100008DF8040001AF384603F0AEFF58B1043704 -:10511000384612F0D3FF012805D12846394612F04F -:105120001CFC80F001061748007818B3122E08D135 -:10513000012806D12046294605F060FA002818BF4C -:105140000026204629460AF077FA0A280AD0A02825 -:1051500006D1204629460FF069FF204609F074FE6B -:10516000012E04D12046002110F056FF01263046C2 -:1051700005B0F0BD122EDDD0E3E700BFA86D002022 -:10518000E0790020242600202DE9FC470B9C8DF8B7 -:1051900007001E461746884604EB840000F1040908 -:1051A000012050FA89F014F0AFFE00283FD082466B -:1051B0000A9A0C980023514601F8017F8A700A1D53 -:1051C000CC704E70DEB2A6421ED2067816704678BB -:1051D0005670467906F007069670877917F0180F13 -:1051E0000AD07D07C7F300174FF0060558BF022508 -:1051F0003D4446EAC505957085780133D570C5787C -:10520000083015710532DDE70B4D5FFA89F30DF1BA -:10521000070048F23202696041460AF05DF904462F -:10522000504614F06FFE05480130686000E010241D -:105230002046BDE8FC8700BF88260020447000207F -:1052400070B58EB02A4E044601200DF103018DF891 -:105250000300B068D0F83024522090470025282160 -:1052600084F82050657501A80C3014F057FD43F602 -:10527000FF702146ADF80B502546ADF82A000F20EF -:105280008DF828002068019031F8040FADF808006F -:1052900015F8060F8DF80A002089ADF80D00A07AE8 -:1052A000002818BF01208DF80F00E07A002818BFF1 -:1052B00001208DF81000207B002818BF01208DF8F8 -:1052C00011000C48007801280AD1B068D0F83024C9 -:1052D00050209047B0682946D0F83024E12090470C -:1052E000B068D0F8281201A8884700200EB070BD21 -:1052F0000C010020242600202DE9F0410C46080472 -:105300000AD460045CBF0020BDE8F0810FF04EFBC2 -:1053100084F48040BDE8F081244F387809F0C8FB60 -:1053200000283FD005460078A0F12301022917D2BA -:105330000C2012F003F890B306460020C6E90000E6 -:10534000B06005203070E878A9783171707114F080 -:10535000DBFDB06018B3EA78696814F077F81EE0F6 -:1053600027281CD1082011F0E9FFA8B1064601202A -:1053700005F10108307098F80000033014F0C4FD06 -:10538000706048B198F80010CA1C414614F05EF8ED -:105390007878314609F0E8FE284612F0ADFE28463E -:1053A00012F0AAFE84F40040BDE8F0817E270020C0 -:1053B000B0B50446007D012805D0152803D0252866 -:1053C00001D035281FD1217E0A071DD4254D6178D3 -:1053D000A868D0F8D42092F8822072B11B290CD191 -:1053E000E868816A01208847A868D0F82C134FF438 -:1053F0008060884700216170A868D0F8302320467B -:10540000BDE8B0401047217E4A060BD4152801D0D4 -:10541000012801D109070FD4617879B11B290FD177 -:10542000232013E00F488068006D016819B160788F -:10543000BDE8B0400847B0BD312007E00D2100E0D5 -:105440000E21084A926852F82110085C2070054825 -:1054500021468068D0F894000078BDE8B04009F09B -:1054600083BE00BF0C01002070B5284D28780528A8 -:1054700039D8022837D0274C0420254E20702648E2 -:10548000B268417801314170D2F8D400C9B290F8C5 -:105490002430994204D9E120BDE87040FDF73CB9C1 -:1054A000297804290BD1D2F8B8100A780AB3C96C4C -:1054B000F9B102208847B0682978D0F8D400174A9B -:1054C00090F8310013780133834238BF184605291C -:1054D000107008BF70BD032914D183202070BDE86F -:1054E000704013F0BBBB0A488068D0F84C05804779 -:1054F000C1E70A4990F831000A780132824238BF88 -:1055000010460870BDE87040FDF714BFBB7A00205C -:105510000C010020B87A00202D260020B97A002046 -:105520007FB5244C2448254E254D0121012260657C -:105530003068036828469847306801214268284649 -:10554000904713F0AFFB1F48082200F120012046CE -:1055500013F07CFF1C4900200A5C235C934207D1B6 -:1055600001300828F8D113481849082213F06EFFBB -:1055700004F1080005F00CFDA16809B1002088477E -:105580000C4806F0E1FF0CF067FC01AC204614F07B -:1055900083FB0F4D0020002122468DF80400284691 -:1055A00013F096F80B48056014F008F9002004B0D9 -:1055B00070BD00BFD42000202F9E0200D801001033 -:1055C00000400340A87F05004CBA0200F0120050D2 -:1055D0003C7700204C7A002070B5012953D0044656 -:1055E000002942D128480121057A01722021EFF3D8 -:1055F000118681F3118894F82010032916D002290E -:105600001BD0012929D12168E26C636819606168A7 -:10561000236859601168914204D1A169C26822EAE5 -:105620000101C160606AC0B1C0680FE020686168B4 -:10563000086060682168486012E0616A69B10A68C0 -:10564000C8684B681A604A6809684A6028B10168EE -:105650004268116041680068416020460EF094FF86 -:1056600086F3118828460EF0D7F9216B481C0AD022 -:1056700006480029406818BF0846D4E90A21436853 -:10568000BDE87040184770BD38220020A01F0020E0 -:105690002DE9F0412B4B012702462024187A1F7276 -:1056A000EFF3118C84F3118854698C4202D18CF38E -:1056B000118841E01D6A002907FA01F705EBC106D0 -:1056C00048BF03F12C0648BF002792F82050012D57 -:1056D00026D1D2F800E0D2F84C805568C5F800E039 -:1056E000D2F804E01568C5F804E0D8F80050454544 -:1056F00005D1D2F818E0DD6825EA0E05DD609D6968 -:105700009542354601D1DE613568D5F804E0156073 -:10571000C2F804E0CEF800206A60DD683D43DD6039 -:10572000B1F1FF3FD66497615161DCBF0021D961BF -:10573000012119748CF311880EF06EF92046BDE832 -:10574000F08100BF382200202DE9F0418CB0DFF855 -:10575000A8800446D8F80800D0F83C03804708B178 -:10576000FC2045E001AD21461122284614F0F2FB51 -:10577000A07D618A667C677D0B228DF81A00B4F8E3 -:105780001700ADF8161004F119018DF815608DF8A9 -:105790001970ADF81B00606A0A90D8F80800D0F8BC -:1057A000D40090F853008DF8180005F1190014F09A -:1057B000D1FB56B100200B9087B107EBC7008000EA -:1057C00014F0A2FB0B9048B911E0812014F09CFB6F -:1057D0000B9060B18121FF2214F04AFAD8F808003A -:1057E000D0F8442301A907209047002000E01A20A8 -:1057F0000CB0BDE8F08100BF0C01002070B514F0C2 -:1058000058FA14F0B3F814F0B7F8044600F00C009E -:105810000C2803D100BF00BF30BF3BE060071ED49F -:105820000DF0F2FA054600EB800001214600012050 -:1058300012F064FD864212D91C4CA5F1180060617B -:1058400004F10C0013F0BDFA00BF00BF0120F6F711 -:105850006BFE00BF00BF002084F820001CE000BFEA -:1058600000BF200715D40E4E0E4D306881682846C3 -:1058700088470428F9D0B0FA80F004F010014009FC -:1058800040EA111014F044FB074801210160006850 -:1058900000E030BF00BF00BFBDE8704014F00DBA9B -:1058A000D8010010004003402C200940D81B0020E4 -:1058B0002DE9FF4726480DF1040A00270AF10404E8 -:1058C0000397CDE9017790F800902248C84600F18F -:1058D0003906FDB24D4510D20720294600220C237F -:1058E000CDF800A010F09AFE30462146082212F0B2 -:1058F000F7FC08B90137ECE7B846002300214D4515 -:1059000028BF012101980028024618BF01224D45F9 -:1059100038BF01231343012B18D10F4B1C78ACB9AE -:10592000114000F2E2404FF00101019019700B4963 -:10593000086018BFA9F1010801AB07200C225FFA2B -:1059400088F110F081FE064800210180BDE8FF8744 -:10595000D3BA0200A86D002095270020182500204A -:1059600014250020BFB590F91910B1F1FF3F00DDFB -:10597000BFBD017D0429FBD8012202FA01F111F01B -:105980001A0FF5D0234DA968D1F89810098911F0A4 -:105990000A0FEDD040684178C1F3810103298DF8E9 -:1059A0000C1008D002290AD1B0F80510B0F8034055 -:1059B000ADF8041003E0411D01A814F050FA13F0F3 -:1059C00027FF28B1A1B201A801220FF033FCBFBD0F -:1059D000E868A4B22146426F01A890471E2800D073 -:1059E00068B901A8214601220FF024FCE868006D87 -:1059F0008047FE28BCD1E868416D002007E0E868D8 -:105A0000006D8047FF28B3D1E868416D01208847C9 -:105A1000BFBD00BF0C010020B0B52B4CA068416990 -:105A20000A7EFF2A4DD0D0F8D43093F88330022B71 -:105A300012D1D0F804054D698047A1680A69CB6B83 -:105A4000D1F8D41091F82C1032F811101A891044A2 -:105A5000281AA0EB01102CE08B7EA3B1022A12D1F0 -:105A6000D0F804058047D4E902124B695268D1F896 -:105A7000D4101B6912780979C01A6FF007039A1ABB -:105A800012FB010015E0D0F804054D698047D4E908 -:105A900002120B69CC6BD1F8D41091F82C1033F8AA -:105AA0001110238918444418D2F8B40080472044C8 -:105AB000281A002805D44FF6FF718842B8BF014666 -:105AC00000E0002188B2B0BD0C010020BFB5204924 -:105AD0000020204D002208601F49C5E9020008602F -:105AE0001E490870012129701D490D2A03D041F873 -:105AF00022000132F9E71B481B4901601B484DF2A7 -:105B0000F02101601A481B490160012028712869B1 -:105B100000B1BFBD01AC204614F027F800200121E0 -:105B2000224602908DF8040013480DF0E3FA286134 -:105B300014F0C0F90028ECD114F0B6F90F49B1FB0C -:105B4000F0F1286914F0B8F9286914F0B7F9BFBD6D -:105B5000187A0020B8240020207A0020A47A00209F -:105B600060730020107A0020F8240100147A0020CD -:105B70001C7A0020905F010019C3010000A3E1110D -:105B80002DE9F84F0546007D1E4690460F463830F9 -:105B9000C0B211F0D3FBC8B304460D9829461C22AD -:105BA00000900120DDF830A0DDE90A9B207004F1AF -:105BB0001C0013F04BFCA01C39460A2213F046FCD3 -:105BC0000020A4F80C8084F813B084F81890C4F86E -:105BD00014A0E0620098607630782074B6F8010076 -:105BE000A4F811002A7D6889E0812AB104F1380007 -:105BF000E062296913F02AFC607F800708D00A4818 -:105C00000168204659B1BDE8F84F0847BDE8F88F54 -:105C1000064821460078BDE8F84F09F0A5BABDE86E -:105C2000F84F12F069BA00BF04270020997A0020CB -:105C30002DE9F04F89B04FF0000B04461421CDE957 -:105C400002BB04AD284614F069F824484FF0FF0A5F -:105C500005F108094FF000088DF820A0061DB8F1E5 -:105C6000C80F34D01FFA88F7042014222B46394677 -:105C70000AF0DAF838BB44B113F030FE86F805B00C -:105C800046F804BCC6F800B01DE0042039460022E6 -:105C90001423009510F0C2FC484602A9082212F015 -:105CA0001FFB40B901207071DDE904010B30316048 -:105CB00046F8040C049013F011FE2846142114F049 -:105CC0002DF88DF820A00C3608F10108C7E714B1B3 -:105CD00000200DF051FF09B0BDE8F08FF033002037 -:105CE0002DE9F041254E0546371813F085FD044691 -:105CF00097F84A01411C87F84A1128B1204614F050 -:105D000036F80020BDE8F081DFF8748018F82570BF -:105D100007F03F00142898BFFFF7E2FF08EB85006B -:105D2000458878B2B0F1FF3F0CDD78061FD41548E6 -:105D3000006841692846884728460CF06BF801281E -:105D4000FAD1DBE70F4E3068C169284688473068D2 -:105D5000416A284688473068C16A284688470A4809 -:105D600001210160094801688907FCD5C6E706EBF7 -:105D70008500D0F8601101208847BFE7D81B0020BC -:105D80007CB30200B80100102820086028200840D9 -:105D9000F8B505462248234E4168890705D40168B5 -:105DA000F02242EA114186F84D101F494FF00122BE -:105DB0001F4F0A601D4909883968096884682046B0 -:105DC0008847A00105D4E00103D5307840F00200F7 -:105DD00030703868214642682846904710F0A8FE87 -:105DE0001448154A0068C0F305311170C1054FF021 -:105DF000130158BF232140237354382101EA901026 -:105E000000F56050A2F85C00386881682046884739 -:105E100002200DF0ADFF094801210160F8BD00BF6F -:105E2000AC4F00500962084004A40C4000A00C4094 -:105E3000F00100100C1400500EB00C4094046042AD -:105E40002DE9FE4FDDF830800E9E92460C460F2164 -:105E500006EB080201EB4201C9B2502984BF1020B1 -:105E6000BDE8FE8FCDE9011020489B460F9FDDF86D -:105E70003490456813F0F6FCA0421CBF0220BDE838 -:105E8000FE8F25F8024B13F037F80146284613F031 -:105E9000E6FF4FEA1B2180F8038080F801B0817093 -:105EA000DDE9013100F804ABB8F1000F09D019F8B1 -:105EB000022BA8F10108027019F8012C427002307F -:105EC000F2E700F8026B4EB117F8022B013E00F822 -:105ED000012C17F8012C00F8022BF4E703482022CC -:105EE00003B0BDE8F04F09F0F7BA00BF88260020E4 -:105EF0002DE9F043844608981C460625034405EB2B -:105F00004303DBB2502B84BF1020BDE8F083234D48 -:105F10009CF80880DDF824904FF6FD7E6F68079DA1 -:105F2000B8F10F0F02D0B8F1020F08D10EF102063E -:105F3000BCF80080B6B2B04508BFACF800E0BA705B -:105F4000120A3C71FA700EF1020292B2914208BF3D -:105F5000714607F8051B090A07F8041C4CB144B147 -:105F600015F8021B013C397015F8011C79700237D5 -:105F7000F5E7387058B1791C48B119F8022B01388F -:105F800001F8022B19F8012C01F8012CF4E7034861 -:105F900061460622BDE8F04309F09EBA882600203B -:105FA0008B4208BF824207D9009A002A01D01060B4 -:105FB0005160002100207047002B08BF002A10D13B -:105FC000009A002A01D01060516002000B000021ED -:105FD0000020002B08BF002A1CBFC943C04304F0A7 -:105FE00032BEF0B51C4615460B4602460020002185 -:105FF000B4FA84F6202E04BFB5FA85F62036B3FA3B -:1060000083F7202F04BFB2FA82F72037F61BB6F1D0 -:10601000200727BF05FA07F400257F42B4403EBFA2 -:1060200025FA07F73C43B540A34208BFAA4201D373 -:10603000521BA341404149416D0845EAC4756408BB -:10604000761EF1D5059F002F01D03A607B60F0BD30 -:10605000FEB50D46C9890446A1F50040022812D3B9 -:10606000132920D048F20402B4F90400914206D169 -:10607000A18C052903D80221A1844021A180B0F17F -:10608000FF3F1ADDFEBD284608F0D0F80028F9D001 -:106090000446007818B9E989204607F0F3FD204648 -:1060A00013F030FFFEBD6C462846214612F0B2F9CF -:1060B000698820460CF065FAFEBD94F82400013092 -:1060C000C6B2304613F020FF0028DBD00546A07989 -:1060D00027792870E0796870A81CA28CA16A013128 -:1060E000013A13F0B3F947F08001452032462B46C0 -:1060F0000CF04AFB2846BDE8FE4013F003BF704792 -:106100002DE9FE438146284888460026002704786A -:10611000A6420BD2F0B20FF0AFF928B10546407994 -:106120000744F8B2484504D80136F1E7B320BDE88A -:10613000FE834046182113F0F1FD6979A9EB0700B1 -:106140000844C0B205EB4000C088A8F80A0012F06D -:10615000D3FE0146404613F082FE6878012806D13E -:10616000012088F814006888A8F80C0012E06888FC -:10617000694610F04BF968B19DF8081008F10C0061 -:10618000032988F8141019BFBDF800100180694672 -:1061900013F065FE2878297988F80800002088F82F -:1061A0001610BDE8FE8300BFDFBA0200F8B5254F28 -:1061B00005463E1813F020FB044696F84A010138C4 -:1061C00086F84A01000637D11F4810F9251000EB68 -:1061D00085004588CEB2B1F1FF3F0CDD70061FD4BB -:1061E0001A48006881692846884728460BF0F0FD68 -:1061F0000228FAD11AE0154F3868016A2846884704 -:106200003868816A284688473868016B284688477D -:106210000F48012101600F4801688907FCD505E09E -:1062200007EB8500D0F860110020884706F03F009A -:10623000142898BFFFF7BAFF204613F098FD0020FE -:10624000F8BD00BFD81B00207CB30200B8010010CD -:1062500028200860282008402DE9F041002918D4A2 -:106260001F4615460E46044612F08CFE8046204618 -:10627000314680220BF056FE20B1064690F93300DD -:1062800000280AD4404613F059FE00210220BDE840 -:10629000F08100200021BDE8F081D6E9080145F039 -:1062A0000A0547F0E04728403940084310D04046EF -:1062B00013F044FED6E9082303EA070102EA0500C9 -:1062C00042404B40C4E92C01C6E90823BDE8F081F7 -:1062D000B1680B48814203D0B168C4F8A810B0601F -:1062E0004046C4E9285713F029FE04F150004FF04E -:1062F000FF3113F0A3FCD4E92C01BDE8F08100BF0D -:10630000E7DC0100F0B589B017460C4605460DF0F4 -:1063100013FD18B10026304609B0F0BD2846002113 -:1063200000260BF0E5F8394603F028FE0028F2D0ED -:1063300007468079C007EDD0204612F07FFA012889 -:1063400018D10420ADF816408DF8140005AF38467A -:1063500002F08AFE01260128DDD100203A1D2146E7 -:10636000CDE90000CDE9020610480378284600F088 -:1063700011FCD0E7B8794007CCD513F073FAA042EE -:106380000CD100202146CDE90000CDE9020005A88E -:10639000021D06480378284600F0FCFBB879810707 -:1063A0005CBF00F0FB00B8710126B4E7CBBA020075 -:1063B0007FB5294E0446B068D0F8FC1120468847C6 -:1063C00080B9B068D0F82C112046884750B9607C5D -:1063D00038B194F8340020B9B068D0F8B810097812 -:1063E00049B100206070B068D0F84411204604B074 -:1063F000BDE870400847D0F8342204F112010920AA -:1064000090470028EDD00546B06804F10B01D0F8A4 -:106410003024E7209047B06804F10801D0F8302418 -:1064200050209047B06804F10A01D0F83024E120F0 -:106430009047022023894FF6FF728DF80C004FF031 -:10644000FF30ADF80400B068D0F8C061A07A0090C9 -:1064500001A92846B0477FBD0C0100207CB5284E1D -:1064600004460D460DF10701B068D0F828244F20EE -:10647000904712F0C3FF042809D1A5B121494FF478 -:106480007A72600113F0B7FB00F53E702DE012F058 -:10649000B5FF68B1ADB11B494FF47A72E00013F05B -:1064A000AAFBF83021E04FF4867000EB44101CE0AA -:1064B0005DB114494FF47A72600013F09CFB2630F2 -:1064C00006E0602000EBC4000FE0102000EB440069 -:1064D0009DF807104FF0FF3202FA01F1F268C9434C -:1064E00052681278083202FB01000C21122C88BF7E -:1064F00028210844034980B20978484380007CBDC4 -:106500000C010020B47A0020F0B58BB0214D286832 -:10651000416E03A888472868C06B80471E49002643 -:10652000039006960A7B88604E8002F0F0020232E9 -:106530000A7301218DF8101013F05EF90446174814 -:106540000227C068806907701548806808B18047D5 -:10655000099029681348144B0D6DCDE900760E4F54 -:10656000006803AA3946A8470646204613F0FFFBF9 -:10657000B6F1FF3F06DD0D4807600D480178013197 -:10658000017004E0032041F2883104F0A5FE0BB055 -:10659000F0BD00BF347A0020642500200C010020EB -:1065A00054B50200E4260020ADE3010030250020B0 -:1065B000292500202DE9F04F85B0814680690DF135 -:1065C000120200214FF000080778A32008F098FC81 -:1065D000BDF91200D0FA57F01FFA80FBBBF1030F90 -:1065E00028BF4FF0030BBBF1000F16D00BEB4B0095 -:1065F000C00080B213F088FCA8B182465FFA8BF528 -:1066000000240646AC420CD257FA84F1A22032464E -:1066100008F076FC01341836F4E74FF0000B4FF029 -:10662000000A002204E0B5224FF0000B4FF0000AF0 -:1066300099F811005FFA8BF19DF81230CDE902A8AC -:10664000CDE9007109F10201FDF7F0FABAF1000F8E -:1066500002D0504613F056FC05B0BDE8F08F7047ED -:106660002DE9F041806A224A01210125847846788B -:106670005120147013F028FA1E4805701E484EF67B -:1066800060250EB1203007E01C490978002914BFAD -:1066900000EB81004FF47A75194906684FF4804089 -:1066A0000F780021F5F7E6F8DFF85880022198F816 -:1066B000000009F097F906FB05F0B0FBF7F2E007E0 -:1066C0000AD1A00758BFBDE8F08198F80000022168 -:1066D000BDE8F04113F07BBB4FF480401146FEF75C -:1066E00085F84FF480400121BDE8F041F5F7C2B8CC -:1066F000DC270020A727002090B40200D22700202A -:10670000D12700209C7A00202DE9FE4FDDF838903B -:106710008DF80B0001209B4614460D4609F10A0630 -:1067200050FA86F013F0F0FBC8B301950546074612 -:10673000DDE90C8A594605F8014F681C13F04DFB42 -:106740004FEA1A21B9F1000F80F8049080F802A0F6 -:1067500080F80080C1704FEA1821417004D00F9971 -:1067600005304A4612F072FEDFF83C80109801991D -:10677000F3B248F2380288F802000DF10B00C8F8B5 -:10678000045008F0A9FE0446384613F0BBFB002075 -:1067900088F8020005480130C8F8040000E0102421 -:1067A0002046BDE8FE8F00BF8826002044700020F0 -:1067B00070B588B000266D46044620210672284632 -:1067C00013F0ACFA284621460B2212F03FFEB4F833 -:1067D0000B0004F10E010A228DF80D60ADF80B00DC -:1067E00005F10E0012F032FE94F91A00CDF81A608D -:1067F000ADF81E60C207C1B21CBF01228DF81A207D -:106800008A0744BF01228DF81B204A0744BF01229A -:106810008DF81C200A0744BF01228DF81D2049066F -:1068200044BF01218DF81E10B0F1FF3FDCBF0120F5 -:106830008DF81F000020ADF80C00208BADF818007B -:1068400004488068D0F8F41268468847002008B0F1 -:1068500070BD00BF0C010020B0B586B0274D0C46BE -:106860000278A968D1F890309B5CA3F10B028DF8F7 -:106870000030062A0DD8DFE802F0040E381338384D -:1068800017004470A968D1F8A41306B0BDE8B04061 -:10689000084753BB2FE01A2C0AD10020019024E0B6 -:1068A00000798DF8020020E011F026FCA9681CE0B8 -:1068B00090F89D2001908DF80220C2680292028A11 -:1068C000ADF80C20827DD20606D4D1F8D430827E79 -:1068D00093F834309A1A00E000228DF80E20427F9F -:1068E000C08B8DF80F20ADF81000D1F83815684630 -:1068F0008DF80140884706B0B0BD00BF0C010020F4 -:1069000070B5284CA068D0F8D4204169557B00228E -:106910004A77C16891F83020013281F83020C1688F -:1069200091F83010042908D1D0F864018047A0689C -:10693000D0F86C01BDE870400047E068C16B2020D2 -:106940008847A268D2F8D41091F84F600F2E0FD06C -:1069500050694B7B807F98420AD24873D2F8D400AA -:10696000D2F81415407B8847A268D2F8D41000E012 -:106970002E46D2E90303497B90F8304033F81630B5 -:106980006400A3404FF4707404FA01F1B3EB910F6B -:1069900028BF8B08D2F8F024A1EB4301BDE870407A -:1069A000104700BF0C01002070B5044613F02DF90C -:1069B00024498860A0070A4604F1080020F003007B -:1069C00008BF201D112828BF0432002413680022AC -:1069D0001D68B5F1FF3F07DD54B116682E448642AD -:1069E000166012D22E4608E085F00046002404E02E -:1069F000854208D201242E461A469D593344002D63 -:106A0000E7D1002419E01A462E46002AF9D0331A9D -:106A1000042B08D3135040F0004313600A4B5C680A -:106A2000201A586008E0084B10685C68201A58600B -:106A3000106840F000401060141D886813F0D3F90E -:106A4000204670BDD02500200026002010B586B05D -:106A50000146427E8068002343F606040593CDE993 -:106A600003330293438003881C1B022C10D3B3F51D -:106A7000C15F03D040F60204A34212D1038A002A68 -:106A800023F4FE6312BF038243F43472028208E0EF -:106A9000038B23F4FE630AB1038302E043F43472F0 -:106AA000028300224A7602A9009105A904AA03AB39 -:106AB000F8F7A6FE28B105984FF6FF7100888842C6 -:106AC0000ED0049C0299204606F020FA074801687F -:106AD00021B1204606B0BDE81040084706B010BD01 -:106AE000049C0299204606F043FEEFE78026002032 -:106AF00070B50C46214900228D1D214909788A4232 -:106B000010D2C37C6E789E4207D1838935F8066C1B -:106B10009E4202D115F8043C13B908350132EEE764 -:106B20008A4201D1002070BD287828B31548818C95 -:106B300020460EF047FA10B1287801382870124824 -:106B4000011D1248007802464AB10B78FF2B03D092 -:106B500031F8043CA34204D02431013AF4E7297807 -:106B600002E0297801392970094AC9B21278104423 -:106B700088423CBF00202870012070BDAA68002018 -:106B8000CEBA0200A86D002020450020E3BA020022 -:106B9000D1BA02002DE9F84F0B9FDDF834B005465D -:106BA0000220994690460E4607F1010ABBF1000FFC -:106BB00000EB4A0008BF02208DF8010068460FF084 -:106BC0008FFFB8B304460A9884F81A90A6806580AF -:106BD000E076A07F01280AD112F044FEB04206D030 -:106BE000B8F1000F06BF0020A077C4F8248005206C -:106BF0002169BBF1000F087018D00C9881F801A032 -:106C00008D1C0021CAB2BA4208D210F8022B013101 -:106C10002A7010F8012C6A700235F3E712F022FE98 -:106C2000287012F01FFE000A687000E04F702046C6 -:106C300007F0E2FEBDE8F88F70B586B085690446BE -:106C4000284611F03BFA30B112F056F901462846B9 -:106C500010F083FE20B11F480178C9B3002002E084 -:106C60001C48017828460229049004D11A49A28BB5 -:106C7000498B8A422CD1217B51BB297A00268DF881 -:106C80001660CA094DB28DF81520C1F380128DF837 -:106C9000142030B9002D04D44FF400500121F4F732 -:106CA000E9FD04A8FDF786FF8DF80F000DF10F0038 -:106CB000A11C48F234020123CDE9000604F11100C1 -:106CC0000AF036FD002D03D4049808B912F0E6F955 -:106CD00006B070BD24260020A86D0020F8B515462A -:106CE000044625480E461168D268AF690068002F37 -:106CF00018BF3846216120636261D5E9042100296B -:106D000008BF4FF4007162B1D31D11444FF0FF3042 -:106D100023F007032063C91A21F00701C4E90A130D -:106D200008E00731082221F00701A1620CF092FE71 -:106D3000E062F0B1D5E9010104F13803EA69666364 -:106D400007C395F8200084F8480018B10B48416942 -:106D50000131416100206065204604F0ADFB08B1BF -:106D60000230F8BD054804F1080111F0A3FC002031 -:106D7000F8BD0120F8BD00BF7C7A00203822002039 -:106D8000BFB545680446287805380B2815D8DFE8D4 -:106D900000F006140C1415141414141B144220468D -:106DA00004B0BDE8B040FAF79DB9681C0190608955 -:106DB000ADF8000068460DF0DBFCBFBD204604B016 -:106DC000BDE8B04011F015BD681C0DF10A010EF0D0 -:106DD00093FA0128F1D150208DF80C0000208DF895 -:106DE0000E00207A09388DF80D0003A80CF0EAF89F -:106DF0000028E2D00446BDF80A0005F10901227D11 -:106E00006080087884F83800206912F01FFB204663 -:106E100007F0F2FDBFBD204604B0BDE8B04010F061 -:106E2000D9B970472DE9F04F8DB0169E1A9F0B907F -:106E30004FF6FF70ADF83010388086B11C4673B144 -:106E4000DDF86490B9F1000F09D0DDF85CB0BBF15A -:106E5000000F04D0DDF860A0BAF5005F04D9042566 -:106E6000E8B20DB0BDE8F08F0BA806AA214607F0E6 -:106E7000EDF805460028F3D11048806803F03EFB8A -:106E800080460F48ADF814400496ADF80EA0ADF85A -:106E90000CB0CDF808901223C188C07802AA0092E5 -:106EA00006AAF3F7A9FB054610B9BDF81C00388007 -:106EB00002484146806806F04FFED1E7A02300203B -:106EC000B87200202DE9F84F0024804600210022EE -:106ED0000460684602F094F9204DDFF884A08146F2 -:106EE0004FF0FF374FF0190B0020602C1ED02A19ED -:106EF000917AB9B1107A022816D0DAF80400418BE1 -:106F00000069084495F8621011FB0B0150690EF0FE -:106F10005FFF064612F0C8FFB6FBF0F0B84238BF7C -:106F2000074601202034E0E70120002709EA00019C -:106F3000012904D10099B94238BF0F4606E0B9F1E2 -:106F4000000F01D0009F01E0C10701D0C8F8007018 -:106F500040EA090000F00100BDE8F88F206E002033 -:106F6000D01E00202DE9F84F0546D1F800902348A7 -:106F700000268B46814588BF032612F03DFCDFF8D2 -:106F800080A08046DAF80440601B18BF01205AF840 -:106F9000207025B105F1B80012F08CFF28B96FB14F -:106FA00007F1B80012F086FF40B19AF82400CAF841 -:106FB000205040F002008AF8240018E0601BDBF843 -:106FC00000104FEA9904B0FA80F0400940EA40000E -:106FD0000AEB800081609BF80810017412F064FFD6 -:106FE000B4FBF0F105F1B80011F0F4FC8326404643 -:106FF00012F0BDFE3046BDE8F88F00BF03093D002A -:1070000070200020F0B587B00546112012F07CFFFB -:10701000002841D004463B2000211122234612F0D3 -:10702000ABF890BB2078A8422FD1112012F06CFF52 -:1070300058B305463A20002111222B4612F09CF845 -:10704000E0B93A201121224612F03EFD1348144FB8 -:10705000012180F8411078682146B0F1004F84BFCB -:107060000020786001AE1122304612F0EFF9786806 -:10707000182132460690822012F026FD2846112162 -:1070800012F04CFE284612F03DFF2046112112F06E -:1070900045FE204612F036FF07B0F0BDA86D002077 -:1070A0001425002070B524480C460078012801D82A -:1070B00060061CD420060CD4A0052BD420052ED4A9 -:1070C00060055CBF002070BD05F0F0FF84F48060B7 -:1070D00070BD04F089F808F0F7F801200FF068FEA1 -:1070E00003200121EDF78AFB84F0800070BD134E70 -:1070F0003068F0B1808802F01BFA3068056812F041 -:1071000001FF3560ADB1EA882D686DB1E888801A5D -:10711000E880F9E702F0FCF884F4007070BD05F037 -:107120008BF884F4006070BD05484021007812F0AF -:1071300051FE84F0400070BD24260020E826002087 -:107140009D7A00207CB520480C46017029BB1F4861 -:10715000007802281BD109F037FF0CF04FFBB0B1CB -:107160001C21054612F0DAFD194E708B06F11C0148 -:107170002880A81C12F073FE4AF60120A5F8110021 -:1071800014480078013040082874B08C6881124897 -:10719000007810B9032010F003FE1048016951B1C6 -:1071A0000B488DF80040C28A408BADF80400684659 -:1071B000ADF8022088470A48022102220023007805 -:1071C0000DF06CFA7CBD00BFBF7A002024260020A1 -:1071D000A86D0020CDBA0200D026002054750020F2 -:1071E0009D7A00202DE9F04F85B0814680690DF130 -:1071F000130200214FF0000807789D20FAF7E0FF06 -:107200009DF81300B84222D9C01BC4B20A2C28BF73 -:107210000A24E00012F078FEC8B182461848002522 -:1072200056468346E8B2A04214D257FA85F18B2025 -:107230003246FAF7C5FF70795A46C1002BFA01F1C0 -:10724000032888BF0321013571710836EAE700245D -:107250004FF0000A99F811009DF8133009F102016E -:107260000022CDE90074CDE902A8FDF78DFFBAF147 -:10727000000F02D0504612F045FE05B0BDE8F08F79 -:1072800003000102B0B586B00589044612F0EAFA9F -:10729000854212D10020ADF810006068039012F012 -:1072A0005DFD78B30179013903292BD8407901219B -:1072B00021EAD0008DF812002DE020890021ADF8E0 -:1072C0000C006068049001ACAB20224607F018FE69 -:1072D0000DF103012046002202F03AFA104800782E -:1072E000012808D19DF8030028B900208DF814006A -:1072F00003A800F0E9F901208DF8140003A800F0BC -:10730000E3F90BE0248812F0ADFA844206D10020A4 -:107310008DF81200039003A8FDF74CFC06B0B0BD39 -:10732000C2270020F8B5D0E901650446287912F09B -:10733000C9FDD6F8CC206969286852681268D16204 -:1073400096F8F93013B9C368DB06FCD4436823F020 -:10735000020343602B69D3621943476A27F003078E -:107360004762C2F80415416921F001014161012120 -:107370000162D6E93512D6F8C00001604AB1EB6966 -:107380009B68C3F309139A4203D91144DA431144A9 -:107390000160D6F8DC204AB16B6A9B68C3F309131D -:1073A0009A4203D9DB431A4411440160204609F094 -:1073B000DBFC287910F044FB2879BDE8F84012F096 -:1073C00083BD70472DE9F04387B0C468DFF888902B -:1073D00000264FF001081B2E11D0D9F8280008FA1A -:1073E00006F7384209D0A55D12F030FA854204D97B -:1073F000D9F82800B843C9F828000136EBE7D9F8D6 -:107400002860C6B16C461821201D12F087FC0120AF -:1074100000968DF8040000208DF8070099F82E00E2 -:107420008DF80500204607F0CDFB062089F82600E0 -:1074300007B0BDE8F0830020002189F8260041F262 -:1074400004000FF0ACFA054801680029F0D0C42010 -:1074500007B0BDE8F0430847A86D002010250020C4 -:10746000BFB50FF087FA04462148012100F10E0252 -:10747000552012F023FB04F0010418B914B10020C8 -:107480000FF096FC1B4DE220691C0EF03BFF2046DE -:1074900005F010FF0020CDE90200CDE900002878BA -:1074A00001280ED814486946102210F019FF18B1AF -:1074B00068460EF051FA04E00F496846102211F0B8 -:1074C000C5FF6A466220102112F0F8FA2CB120B9EB -:1074D0006A466220102112F0F7FA20460EF0FCFEF8 -:1074E0001CB1002001210CF0D3FA002004B0B0BD83 -:1074F000CC2200202426002004B90200F0B589B077 -:10750000044640890E46010742D5800706D5607BB8 -:10751000062803D0CD2E18BFF02E37D1207B0FF0D8 -:10752000E7FCA8B3217B676905467EB108220FF00E -:10753000F3FC70B16FB1428801780379B87895F89F -:107540000AC0CDE900C60BF03DF803E004220FF0BD -:10755000E3FCEFB178682168CDF80E00387A096A4B -:107560008DF81C00E86809780690787B8A09402924 -:107570008DF81D003878009538BF042200F04001D6 -:1075800000F0200302A8EFF7B3FE02E0E92EC5D019 -:10759000002009B0F0BD704770B50546407D164625 -:1075A00001220FF0FDF9C6B90446B0B1E87D94F8A8 -:1075B0003510884211D194F83910237A0A18287EA0 -:1075C0009A420BD2FF2817D1002084F8352084F886 -:1075D0003800FF208840C0B20EE070BDFF280BD1FC -:1075E000E28BA07E94F82A1000230CF035F8204698 -:1075F000BDE8704010F0E4B984F8370084F8360034 -:1076000012F054FC054612F04FFC68434FF47A71B7 -:10761000B0FBF1F00121208094F83A00608003482B -:107620000078BDE8704006F071BD00BF482600201C -:10763000B0B586B0044601208DF814002046F8F756 -:107640003DFE206918B11F48816820468847207D8B -:1076500058BB0020CDE90000029001208DF8020007 -:107660008DF80500D4E902010088ADF80000087D1E -:1076700009308DF804006846F7F7FEFD9DF8140008 -:1076800098B903980E21406C0546013005F8091B96 -:10769000A168496812F0E3FBE0680169027D2846B1 -:1076A00011F0D4FE68460AF0AFFFE06808B112F0AE -:1076B00029FC204612F04FFA9DF81400207506B000 -:1076C000B0BD00BF50240020B0B586B004460020F5 -:1076D000CDE90000029040F20910ADF804002088C6 -:1076E000ADF80000207A012812D121208DF8020087 -:1076F0001948007878B912F08DF960B9174D6168B2 -:10770000082205F1180011F0A1FE2088288002E06F -:1077100001208DF802006846F7F7AEFD9DF81400D1 -:1077200050B903980721406C00F8011B616812F002 -:1077300096FB68460AF068FF0748007838B912F0EF -:1077400069F920B905480021C0E9061101809DF8BA -:10775000140006B0B0BD00BF242600205024002035 -:107760002DE9F04F85B02048DFF884A000274FF6C0 -:10777000FF7B007800901D48047801A8051DA742F2 -:107780002FD007EBC7003AF82010594527D00AEB55 -:10779000800801208DF80400B8F80200ADF8100050 -:1077A00001A808F0E5FBD0B1124EDDF80090B9F168 -:1077B000000F14D03088B8F80010884208D0BDF807 -:1077C0000610884204D0B11C284610F0C6F810B14B -:1077D000304610F0FFFE1C36A9F10109E7E701373A -:1077E000CDE705B0BDE8F08FD1BA0200E3BA0200E0 -:1077F00020450020305600202DE9F0418AB0054692 -:1078000020480078012839D81F4FF88AA84203D1B0 -:1078100085B30DF049F82BE0284612F042FA48B340 -:10782000044600790138012824D860884FF0000808 -:107830008DF81880ADF8240006AE304608F098FBAD -:10784000C0B1208811496D46088005F10B00311D3B -:1078500012F005FB00200DF05FFFADF814008DF86D -:10786000168028460222217902F088FAC4F80C809A -:10787000012004E0B98C28460EF01DFB00200AB060 -:10788000BDE8F08124260020A86D0020802700207C -:107890002DE9FC41204F0446786808B18047B0B319 -:1078A000F868BA69610312F071FA012500282FD433 -:1078B0001A4904EB440001EB8006F07DFE2838BF36 -:1078C000451C174800210423F57540EA0520019066 -:1078D00001AA20460CF010FB387018B9032070760E -:1078E000FF20B0750F4F12F07CF900234FF0FF0816 -:1078F0000025B84712F075F90123B84712F071F965 -:107900000223B847102086F81880B08300E00B25CA -:107910002846BDE8FC8100BFA0230020B8720020EB -:10792000FF000F9671600200F8B50446FD201D4669 -:107930008DF8030020461E68324600F071F910B140 -:1079400001208DF803009DF80300FD2815D1A6B194 -:10795000E068007B00F00F0002280ED13768204657 -:1079600031463A4600F05CF920B9002F3E46F5D189 -:10797000002602E002208DF803009DF80300FD2898 -:1079800004D1E06B10B104208DF803009DF8037062 -:10799000042F0FD0022F06D0012F0FD128462146E9 -:1079A0000FF04EFC0AE0326822B1284621460FF063 -:1079B00053FB03E0284621460FF030FC78B2F8BDB7 -:1079C0002DE9F843994615460F4606460DF08AF80C -:1079D0001E49DDF820800C78A04216D21C4900EB2D -:1079E000800201EB420212F8073FAB429CBF03202A -:1079F000BDE8F883B8F1000F24D000EB80001570CB -:107A000001EB4000A0F804901CE04FF6FE7000214E -:107A10000DF068F8A04204BF0220BDE8F883B8F179 -:107A2000000F0FD00A4900EB800001F8107001EB45 -:107A30004000FF2181710749C571A0F8049046807C -:107A4000C97C01720020BDE8F88300BFD5BA0200EE -:107A5000B25C0020A86D002010B505F0C1FD044601 -:107A600088BBFBF7D3FCC8B111F0FCFE18490880B5 -:107A700020B91848018821F00701018016480078D4 -:107A8000022804D001280BD11448007840B91548C9 -:107A9000002180F826101248032103E0092409E0A0 -:107AA0000F48012181700F4800F139010E4812F092 -:107AB000D6F900240D48002101800748007810B94C -:107AC00000200CF015FB002C18BF0124204610BD2F -:107AD000887900203E79002024260020E427002019 -:107AE000D0260020A86D0020AE79002014250020AB -:107AF0002DE9F04F87B080465868DDF840A08B46EE -:107B00001F469146002100251B2906D020FA01F2CC -:107B1000D20718BF01350131F6E728064FF0000102 -:107B200014D0E8B212F0F0F990B1044607F1080061 -:107B3000002100221B290CD07B68CB40DB0703D03F -:107B4000435CD6B20132A3550131F3E7002401E0D2 -:107B5000002400217B68BA78E8B2CDE900B902AD13 -:107B60000591084985E811044046FEF7CDFD2CB18A -:107B7000204607B0BDE8F04F12F0C4B907B0BDE829 -:107B8000F08F00BF9279002070B588B004460220C3 -:107B90008DF80A00E08894F82420617EADF8020098 -:107BA000607D8DF810108DF80C00A088ADF80E00E7 -:107BB000501E8DF81200A06A411C069100788DF8C5 -:107BC0001100608AADF81400A08DADF81C00684665 -:107BD00003F02EFF05461048007818B1694620468C -:107BE000FEF736FABDF80E200C4900204FF6FF7361 -:107BF000C4B231F834609E4208D001309642F7D1C9 -:107C000001EBC40041686846884703E015B968463F -:107C10000DF0E2FD08B070BDEC270020DCAE0200E4 -:107C200070B5B2FA82F3B1FA81F45B096409B0B3BA -:107C300012B190F844506DB389B191F844406CB3DF -:107C4000446B0E69096C05698908A408AE4214BF2B -:107C5000ED6800252944611AB1F1704F22DAB2B102 -:107C6000D168097B01F00F01022915D1516B05691B -:107C7000006C146980088908A54214BFE2680022DC -:107C80001044081AB0F1704F01DB012804DB012415 -:107C9000012304E0002302E0012400E0002404EAC0 -:107CA000030070BD00240029C8BF0124002AF6D0BB -:107CB0000129D5DAF3E77047F8B5F0B10446007A48 -:107CC00000F0FE00022818D120460D4600F03AFED2 -:107CD000FF281CBF1E20F8BD227A1B49194B022A1F -:107CE000084608BF18460668002005280AD026FA6C -:107CF00000F7FF0703D00130F7E7E820F8BDC6B270 -:107D0000052E05D1022A18BF032A0DD11A20F8BD6D -:107D1000022A0AD1228803EB80012B0ACB728D72D2 -:107D20000A72120A4A7206E005202268636801EBB3 -:107D3000C001CB608A60227AC0B201210DF0A6F8A2 -:107D40000020F8BD20770020F87300202DE9F84FBF -:107D5000204E214FDFF8848000254FF0010B4FF0BB -:107D600002094FF0110A602D08BFBDE8F88F7C1999 -:107D70002ED0A07A01282BD1607A41B20BFA00F004 -:107D80001131C0B20BFA01F1CA433260726811437B -:107D9000716010F0DDFA04F1100000210EF0AAF974 -:107DA000812809D1A06920B100210EF0A3F9812812 -:107DB00002D184F80A900BE0607A97F861100AFA11 -:107DC00000F00843002187F86100404612F0B2F845 -:107DD0002035C8E708100440206E002040720020C3 -:107DE00070B5044610F0ECFA41F288300EF07AF8E3 -:107DF0001A4D287801280BD8194E4FF4807130782D -:107E000007F0F0FD30784FF4807105F04DFC2878D4 -:107E1000022804D14FF400500121F3F72BFD012C6F -:107E200015D1104803210224104D817004700E48B2 -:107E3000012101700E4805F1390112F010F885F8A2 -:107E400026400FF06DFEBDE870400DF0CDBD41F253 -:107E50008830BDE870400FF05BBB00BF24260020D7 -:107E60009C7A0020D0260020A27A0020A86D002055 -:107E7000AE79002080B51F48007860B111F0E6FCB3 -:107E8000EE281DD811F0E2FC1030C0B211F0F0FC69 -:107E9000194801211BE019480078082815D10FF076 -:107EA0009FFD09200FF07CFF15480078072813D0AC -:107EB000052815D101200EF067FA03F095F90FE0BF -:107EC0000020BDE880400EF05FBA0B48102100781A -:107ED000BDE8804006F01AB907200121ECF78EFCBE -:107EE00008480078012818BF80BDBDE880400FF029 -:107EF00021BB00BFBF7A00209D7A0020D026002041 -:107F00000C7A0020CA270020BCB50446807A0128DC -:107F10000CD1207B00218DF8071060BB1D488DF827 -:107F20000510007802281CD2E07A1CE0258811F0A8 -:107F300087FCE27A85420ED1012A01D1207B07E03D -:107F40001348008800F00700022804D101202073A4 -:107F5000FFF746FF16E0237B2088A11CFAF7A2F961 -:107F600010E002D100208DF8040011F097F801A86C -:107F700009F056F9207BFFF733FF0DF1070152207E -:107F80000AF002F90448816909B120468847BCBD5E -:107F90003E79002024260020547500202DE9F04170 -:107FA0008EB0054611F028FCDFF880800446696831 -:107FB0001022D8F80800D0F808010068836B0AAFD7 -:107FC00038469847064638BBD8F80800D0F808016C -:107FD0000068016901AE304688470D206A69019743 -:107FE0008DF82400D5E9020105926A8B0290288B56 -:107FF000CDE903110790A88B8DF82500101A089081 -:1080000008440690D8F80800D0E9411208681168C1 -:108010008A69314690470646204611F0A8FE002E98 -:1080200018BFE42630460EB0BDE8F0810C010020F8 -:1080300070B51F4DA868D0F8B8100A781D4991F99D -:1080400000101AB1002902D41B49097811B1D0F8E7 -:108050004C05804711F0D0FBEA68184C1269217872 -:108060001278914207D116490978490703D411F0D3 -:108070007EFE012070BD11F07AFE0EF04BFA2078E2 -:108080000FF0FAFA78B1E86824780669204631786A -:108090000CF02AF9347030B1A868D0F8D40090F907 -:1080A000420010F078FEBDE8704011F029B800BF22 -:1080B0000C010020B87A0020AB7A0020582600205E -:1080C000B17A002070B51C480025204C05701B4873 -:1080D00005701B4805701B4885601B480570A0682B -:1080E000D0F80011D0F85022C889103080B29047E3 -:1080F000174E306020B9A068D0F84C058047306832 -:10810000A168D1F80011C989006085801031C18053 -:1081100010483168C0E900150CF09EFEE068C068A8 -:10812000007800B170BDA0680021D0F8582400206C -:10813000BDE87040104700BFB07A0020C27A00202E -:10814000B27A002034250020B37A00200C010020F0 -:10815000787A0020D8790020B0B5234C0021A0689F -:10816000D0F8E8000160A168D1F8D8000068B8B183 -:10817000D1F8E02040681268904211DA0CF040F922 -:10818000A168D1F8D82012685368834204DA50609D -:10819000A168D1F8D8000268D1F8E8000260A168AF -:1081A000D1F8DC00006848B1D1F8E82013681BB1B1 -:1081B0005B6845689D4201DA1060A168D1F8E8006B -:1081C000006848B1D1F8E01040680968884203DAD5 -:1081D000BDE8B0400BF0D6BA0FF092FEA0680021C7 -:1081E000D0F8E8000160B0BD0C0100202DE9F0419D -:1081F000044680681F4F206297F85E00E8B197F848 -:108200005C00D0B91C480068006B8047DFF86C80C8 -:10821000D8E910562A46334610F018FFA0FB052374 -:1082200000FB063301FB0531C8E91221B9687B6DFB -:10823000BA689A1A411A91420CD90EF031FA01210A -:108240002175A2681044E06097F85C0078B187F867 -:108250005D100CE001212175A2681118181A8242E4 -:10826000E16004D21046BDE8F04110F0A3BCBDE8C7 -:10827000F08100BF082000208C010010886E0020D3 -:10828000002840D02DE9F0418EB01F490AAE0025EC -:1082900003904FF020080896059507918DF8185027 -:1082A00001A801210D901948EFF3118788F3118877 -:1082B000047A017280690C900BF090FB14494A68B3 -:1082C0000D980160426010604860FFF78FFF0C98C6 -:1082D00046620B960A96204687F311880BF09CFBAA -:1082E000EFF3118088F311880D990A684B681A60C2 -:1082F0004A6809684A600D9580F311880C984562B8 -:108300000EB0BDE8F0417047C1870200382200205E -:108310000820002070B5204D04462878C0B3A07C0A -:10832000B0B360890BF008FD022801D0607978B302 -:108330001A482978821C0B465BB132F8025CA68988 -:10834000AE4203D11578E67CAE4223D00632013B23 -:10835000F2E7821E481C4FF6FE7101381AD0931DB9 -:1083600052888A421A46F8D10C2004211880A0892C -:1083700023F8040CE07C0A4C03F8020C20780BF084 -:1083800021F828B9207804214FF4FA7211F022FD67 -:10839000012070BD002070BDA1270020B45F002027 -:1083A000997A0020FF2804BF4FF0FF3070472DE975 -:1083B000F84F1D4B0C4605464FF4BE21AF0004F0AC -:1083C000020643EA80004158C9B2914217D11748CA -:1083D0004FEA14299A4647EA0008834611F00CFA3E -:1083E0000BF10101220C88F8009039430A7048F023 -:1083F0000201220E0A7011F0BAFC534605E024F087 -:10840000FF0100F5BE201143016026B945EA0300D3 -:1084100004F0010101700648012181EA5601384348 -:1084200001600020BDE8F88F0020024001100840E4 -:10843000001A44422DE9F84F214CDFF880A0814614 -:1084400000254FF0010BE8469AF80000E778C0B22B -:10845000A9B281422ED2A078FEB2864220D0304608 -:1084600000214246042310F0B9FF9DF8000078284F -:1084700016D0FF2801D07E2803D130467C210CF095 -:1084800061FA06EB4600E77004EB8000808BE08029 -:108490004844B0F5005F0ED9304678210CF052FA0E -:1084A0009AF800005BFA87F10135B1FBF0F202FBAC -:1084B0001017CCE7FF27F8B2BDE8F88F9B7A0020B1 -:1084C000B8720020F8B5D0E90167054611F094F9BB -:1084D0000446D6F8C00098B396F8F81019B9007C95 -:1084E0000338012831D82846FEF71CFFD6F8C00013 -:1084F00000220223016805463DB12F7C033F022F75 -:1085000028BF2B742A606D69F6E73246016052F885 -:10851000C81F21B10A4649690029FBD114321060F5 -:108520000020C6E93000C6E93400C6E9360020461E -:1085300011F01DFC06F13000BDE8F84011F0FCBC64 -:108540003868416821F0020141602046BDE8F840EA -:1085500011F00DBC7CB50C46080426D4E00704BF1E -:1085600000207CBD1E48007808F0E6FF054668B193 -:1085700001200DF107018DF80700522009F004FEDB -:108580000020002610F0FAFF1448867002200EF03A -:10859000D5FE38B101464570332008700F48C078C9 -:1085A00006F0E2FD84F001007CBD0C4E307806F050 -:1085B0007FFA80B1054600780D2805D00C2806D139 -:1085C000284610F067FC02E02846F4F751FC2846E4 -:1085D0000FF092FDEAE784F400407CBDCC26002039 -:1085E000917A002010B5044600780438052831D867 -:1085F000DFE800F0030D151E26311D480078013814 -:10860000012827D82046BDE81040F0F7CDBD184816 -:108610000078F8B92046BDE81040F8F7E3B81448F0 -:108620000078012816D12046BDE810400EF098BB16 -:108630000F48007870B92046BDE8104010F0E8BC43 -:108640000B4800780138012804D82046BDE81040C6 -:1086500010F084BF10BD0648007820B9607F10B9C3 -:10866000601D03F059FA2046BDE8104011F06EBCC1 -:108670002426002010B586B0002190F90B20ADF81B -:108680000C100188B2F1FF3FADF80E104168049163 -:1086900002F0400102DD21B901200DE039B90520C9 -:1086A0000AE0807A012814BF0320002004E0807AC9 -:1086B000012814BF072004208DF8140001ACAB2062 -:1086C0000021224606F01CFC0DF103012046002289 -:1086D00001F03EF80A480078012808D19DF803000F -:1086E00028B900208DF8150003A804F0DAFB01205A -:1086F0008DF8150003A804F0D4FB06B010BD00BF30 -:10870000C22700202DE9F0418EB0054611F074F823 -:10871000DFF87C80044669681022D8F80800D0F899 -:1087200008010068836B0AAF38469847064628BBA5 -:10873000D8F80800D0F808010068016901AE304699 -:1087400088470D2005F1080301978DF824000FCB11 -:10875000CDE90311CDE905320290288B0790688B93 -:108760000890287F8DF82500D8F80800D0E941123C -:10877000086811684A69314690470646204611F05C -:10878000F6FA002E18BFE42630460EB0BDE8F081A0 -:108790000C01002070B51E4DA868D0F8B8100A78FA -:1087A0001C4991F900101AB1002902D41A4909781C -:1087B00011B1D0F84C05804711F01EF8EA68174C4B -:1087C000126921781278914206D115490978490732 -:1087D00002D411F0CCFA17E011F0C9FA0DF09AFEAC -:1087E00020780EF049FF78B1E868247806692046C1 -:1087F00031780BF079FD347030B1A868D0F8D4002E -:1088000090F9420010F0C7FA10F07AFC012070BD18 -:108810000C010020B87A0020AB7A002058260020F6 -:10882000B17A0020F8B5044690F8300003282ED124 -:1088300094F83A0003282AD11D4E04F128010023A0 -:10884000B068D0F8D4201632D55CCF5CAF422DD1C1 -:108850000133082BF8D1D0F830244A2090476768BC -:108860000DF102052946388811F050F85020904744 -:108870007888294611F04AF84B209047B7F8050050 -:10888000294611F043F853209047002100E0E821E9 -:1088900007488068D0F8F40041702A20207004480E -:1088A0008068D0F8401320468847F8BDEA21F1E7F8 -:1088B0000C01002070B5044610F09EFF184E0546CE -:1088C000307810B1174811F000FA1748007810B14D -:1088D000144811F0FAF91548007870B91448007876 -:1088E00058B91448007840B91348007828B913489B -:1088F000007810B91248007820B1284611F037FAF4 -:10890000002070BD0DF006FE2846347011F02FFADD -:10891000601E022802D3034811F0D7F9012070BD70 -:10892000B02700200C010020B27A0020B07A00208D -:10893000B37A0020B87A0020AB7A0020B17A002008 -:10894000B67A00202DE9FE4F0446007A02280ED1A7 -:1089500020888DF80A10090A04250DF108088DF801 -:108960000B108DF80800000A8DF8090001E00825B9 -:10897000A0461648DFF858B00026EA4600F108077E -:108980000BF10809052E1CD0207A1049022808BFD7 -:1089900059460968F140C9070ED0022839465046A9 -:1089A0002A4608BF494611F0D5FA404651462A46A4 -:1089B0000FF096FC012805D009F1040908370136AB -:1089C000E0E7FF26F0B2BDE8FE8F00BFF87300209D -:1089D0002077002010B5407820B11C48002180F895 -:1089E000261010BD194C082084F8260094F8380091 -:1089F00058B91748016809B100208847A18C0520A3 -:108A00000DF0CDFFA08C09F08BFC124800780128F6 -:108A10000AD1002011F06CFAE18A06200DF0BFFFA8 -:108A2000618B04200DF0BBFF0C4800680028D8D0F3 -:108A3000094800780128D4D109484FF480414FF407 -:108A40007A720078BDE8104011F0C1B9A86D00201D -:108A50001025002024260020CA270020842300207F -:108A60009C7A00202DE9F041064600888846114690 -:108A700014460AF0F3FB7088E1796081B088A08128 -:108A8000B079A074F079E0740820607021B11020F2 -:108A900006F1080160706161217A29B100F10805D1 -:108AA00030446570A06100E00546607918B1705DE2 -:108AB00001356570607120460DF098FA074688B957 -:108AC000A179701951B10E30A0620848007B10F0F6 -:108AD0000DFD2844A8EB00000E3802E0A062A8EBD0 -:108AE000050020773846BDE8F08100BFA86D002062 -:108AF000BCB5044602208DF8050001A80DF0F0FF7A -:108B0000B8B30546006904210180217A0139B1FA20 -:108B100081F1490949014170627A012A04BF40315B -:108B20004170A27A012A19BF0120A87680314170D4 -:108B3000607A012804D1606808B101216977286250 -:108B4000E07A012804BF0120E88220880BF0F4F8C5 -:108B500018B1E88A40F00400E8820120A87710F0FC -:108B6000CBF90548686220886880284605F044FFF4 -:108B7000BCBD1020BCBD00BFE07900202DE9FE4344 -:108B800080460A201E4691460F46002908BF00EB8A -:108B900043008DF8090002A80DF0A2FF00B30546BE -:108BA00046EA471049462C69607009202070A01CD5 -:108BB00011F055F9BFB10126AE7710F09DF91148BB -:108BC0006C462146686240460DF0A6F808B12C625A -:108BD0006E772846A5F8028005F00EFFBDE8FE83FB -:108BE0000120BDE8FE830A9804F10A01002EE2D0BC -:108BF00010F8022B013E01F8022B10F8012C01F8AD -:108C0000012CF3E7E07900202DE9F041154610F042 -:108C1000FCFF804625B3DFF874C0DFF874E0002362 -:108C20000027BCF80060DEF80020FCB2AC420CD299 -:108C30007008862809D87444701C0137217BACF871 -:108C40000000915523730646EFE7DCF80420AC42A0 -:108C500018BF002A06D0BCF802104FF48770904766 -:108C60000A48426812B1A8B2002190470748002183 -:108C7000202200230180064988680C310EF029FE6D -:108C80004046BDE8F04111F0AEB800BF70260020AC -:108C900048230020F0B589B0ADF8201007907BB3D1 -:108CA00072B391B207A802AA1C4605F0CFF9064696 -:108CB00038BB194F786808B1804728B3B86801F00D -:108CC0001DFC05461548002203230092C188C07888 -:108CD00002AAF1F791FC06460A2818D0F0B2A8B90A -:108CE00002A821460222EFF7FFF8064678B9BDF840 -:108CF000141061B19DF8180007F0B0FD3E7806E051 -:108D00000426F0B209B0F0BD0B26FAE70126B868D8 -:108D1000294604F021FFF4E7A0230020B8720020C8 -:108D200080B50DF0FDF918480023811C1748027822 -:108D30004FF6FE703AB1C1F80230088021F8023CCB -:108D40000831013AF6E7134A114900231278083135 -:108D50002AB101F80A3B013A21F8100CF8E70E4954 -:108D60000E4A097819B122F8080B0139FAE70C48C4 -:108D70000C494FF47A72007808700B481021007883 -:108D8000BDE8804011F023B8503D0020D7BA020062 -:108D9000B25C0020D5BA0200CEBA0200AA68002058 -:108DA000DCBA02002F7900209C7A0020F8B5D0E9C7 -:108DB00000670D46044610F01FFD96F8311049BBC0 -:108DC0001949097831B30121A6F8311010F0CFFF0D -:108DD0001649002D18BF29460A784868012A08BF9D -:108DE00000281BD0C6E90240D1E9020186F83020F4 -:108DF0000F4A104B3061B8683162A0F58071914222 -:108E000038BF034606F13400002173610EF0B8FF4D -:108E10002046F8BD10F0ABFF0020F8BD8B680020A5 -:108E2000002BDFD1F5E700BF1823002040B8020077 -:108E300001FFFF0080A90300B0B586B00446807A28 -:108E400058BB60680DF117016A4600F081FC0146CD -:108E5000E07AC00621D49DF8170001281DD19DF8A5 -:108E60001000022819D1164A002301EB4100CDE978 -:108E7000003342F8203002EB800014224360FF20D0 -:108E80006B468DF810009DF81200013000F00F00C5 -:108E90008DF8120004200DF0D7FB2046F9F774FA84 -:108EA000054648B9A07A38B9E07AC00604D410F073 -:108EB000D9FC6168F9F762FE284606B0B0BD00BF74 -:108EC000F033002010B51D48007810B91C48007818 -:108ED00020B11C488068D0F84C05804710F08CFC0D -:108EE00019490A78022A24D10122184C0A702378E1 -:108EF000062B05D89A4012F04C0F1CBF83220A7033 -:108F000010F035FF2078042807D80121814011F0A6 -:108F1000130F02D0FAF70EFA207806280DD8012197 -:108F200001FA00F010F04C0F07D0BDE8104009F036 -:108F3000CBBFBDE8104010F01ABF10BDB07A0020C2 -:108F4000B37A00200C010020B87A0020BB7A002000 -:108F50002DE9F04186B0DFF8708098F8650078BBA5 -:108F6000012088F86500C8F80480C8F800800EF079 -:108F700023F8164801AA114690E8F8000420F8C129 -:108F80000490134808F11004124900F11C03204614 -:108F900008F0B2F8C8F84C400AF002FD0E48D0E9DB -:108FA000102347F69160101A73F1000031BF4FF0A3 -:108FB000FF30002047F6906110F048F8C8F85800DC -:108FC00006B0BDE8F08100BF0820002054B80200C0 -:108FD000A01F0020913E0100886E002010B58CB0CB -:108FE0000446007A042802D110F078F910B1C220AA -:108FF0000CB010BDA07850B960680DF1030101AA52 -:1090000000F0A6FB9DF803000028F0D0A078002116 -:10901000CDE906118DF82C10089140F20B11ADF836 -:109020001C104121002808BF612120888DF81A10EA -:10903000ADF8180006A8F6F71FF99DF82C000028D7 -:10904000D6D109981021406C0170A1784170217A25 -:1090500081700330616810F002FF06A809F0D4FAAD -:109060009DF82C00C4E770472DE9F8430446002022 -:109070006FF001014FF6FE72A04648F8040FA8F801 -:10908000081038F8021CC8F80400914202D1C0B29E -:10909000BDE8F883DFF8549000250020B9F800708F -:1090A000BAB2A9B29142F2D24A0012FA85F3D9F8C3 -:1090B000042012F823301B0716D001EB410163880E -:1090C00002EB81014A8893420ED10E1D30460EF00C -:1090D000F5FF012805D14046314610F07EFAB9F877 -:1090E0000070A58101203D460135D9E740260020CA -:1090F00070B51B4E04464FF48061307806F072FC68 -:109100001848092180F8261017480078022802D153 -:1091100016480021017065690FF0EEFE14492846DB -:109120000EF01BFCD8B110200EF008F9B8B10546BE -:109130000220A1692870A06AB0F801206A80C07876 -:1091400068704A2009F020F8A07910B90948052173 -:10915000017030782946BDE8704006F005B870BD52 -:109160009C7A0020A86D002024260020DC27002007 -:10917000E0790020D02600202DE9F04188B0ADF83C -:109180001C10069006A801AA002104F05FFF054606 -:1091900068BB194E706808B1804738B3B06801F0F9 -:1091A000ADF9164F04464FF000080323CDF80080B8 -:1091B000F988F87801AAF1F71FFA054688B9BDF8D1 -:1091C00010109DF8140007F049FBF988F878CDF8E5 -:1091D000008001AA0323F1F70FFA35780A2818BF97 -:1091E0000125B068214604F0B7FC00E00B25E8B289 -:1091F00008B0BDE8F08100BFA0230020B8720020B5 -:1092000010B504461E4849B138300068B0B1C36893 -:109210001B7B03F00F03022BF7D101E0806B68B1D9 -:1092200002B11060C268137B03F00F03022B08D158 -:1092300051B101698A8DC968114415E000210020EF -:109240001CE00120002119E012880169A2F6030246 -:10925000012A4A8B8CBF0969496919231144094ABB -:1092600092F8622012FB0311406B0CF0B1FD2060FC -:1092700010F01AFE2168B1FBF0F10120216010BD51 -:1092800030210020206E00202DE9F84F07461E48AF -:1092900015460E46009300F138094C4624680CB17F -:1092A000B442FBD14FF0000A00F1400B44B32069F7 -:1092B000D4F80080B84220D1204600224FF08053DD -:1092C0000DF0AEFC009870B1204600224FF0807384 -:1092D0000DF0A6FC30690D49086291F8240040F0B9 -:1092E000010081F82400484621460DF0BDFB584698 -:1092F00021460DF093FF0AF1010A002D4446D5D115 -:109300005046BDE8F88F00BF3021002070200020BB -:109310002DE9F0438BB005AC20460EF021FD8220F4 -:109320001821224610F0D0FB18480DF1080800253E -:1093300008F104090778164800F13906ECB2BD427D -:1093400010D20720214600220C23CDF800800DF01A -:1093500065F93046494608220EF0C2FF0135002863 -:10936000ECD004E04FF0FF30013CCDE903000A9857 -:109370000290A1B202AB07200C220DF065F905485E -:10938000002101800BB0BDE8F08300BFD3BA02001A -:10939000A86D002014250020F0B585B005461E48B4 -:1093A0001E4FA96900883E460C88844218BF0026DB -:1093B00016D1688803A901F083FC01280DD19DF81E -:1093C00013209DF812109DF81100042A08BFCF2920 -:1093D00012D0542A08BFEF2911D00020002112E03A -:1093E000297C687C48F202022346CDE90021A91CB1 -:1093F00080220DF051FC0DE08C2802D0E9E74428D2 -:10940000EBD111215F203971F87028462146324690 -:1094100004F0A8FA05B0F0BD887900203E7900205C -:10942000BCB504460022806982230192817839B359 -:10943000FF294FF0000524D0194A0088128880B215 -:1094400090420DD101A80CF089FF019A0023054636 -:10945000002A08BF6FF07C03002818BF012510E028 -:1094600010490978022908D20FF0DCF96FF0760371 -:10947000002808BF6FF07E0301E00CD1802300229A -:109480000025D9B22046FAF737FC1DB1019808B182 -:1094900010F038FDBCBD002200250023F1E700BF1D -:1094A000887900202426002070B588B004461E4824 -:1094B000A16900880E784A7846EA022282421DD1CC -:1094C0008A78102A28BF102203318DF80C2003ADB2 -:1094D000681C0FF0BBFF812011212A4610F0F4FA1E -:1094E0009DF80C001149002818BF01200A8822F0BD -:1094F000100242EA00100880002000E084208DF86D -:109500000900207C0DF1090148F2140203238DF8B3 -:109510000B608DF80A60CDE9001004F11100A11C68 -:1095200008F006F908B070BD887900203E79002067 -:10953000B0B588B010F0B5FB18B304461D480078EC -:10954000012804D1607900F0E70008306071002044 -:109550008DF804006088ADF8100001AD284606F0D3 -:1095600007FD208804350695ADF8140010F07AF94F -:10957000ADF81C006079810601D5410603D40021B5 -:1095800002E0002014E001218DF81F008DF81E106C -:1095900005A80DF0A9FB30B128460DF02EF928469C -:1095A00005F0DAFC03E0607900F0FB006071012057 -:1095B00008B0B0BDE027002070B590B06E460C46F4 -:1095C00005464021304610F0A9FB304629460A22C4 -:1095D0000FF03CFFD5F80A00E989CDF80A0006F142 -:1095E0000E000DF049F9288AADF81700688AADF829 -:1095F0003B00E87FADF82C0010F086FC0A9070B1BB -:10960000EA7F296A0FF022FF4CB10A999DF82C00DD -:10961000A04720B10A9810F075FC1A240AE0074808 -:109620008068D0F888126846884704460A9808B1CE -:1096300010F068FC204610B070BD00BF0C01002087 -:10964000F8B50C46064610F0D7F81D4F0546B86829 -:109650007EB1D0F894000121007802F00DFD28467B -:1096600010F085FB20460AF051F80EF009FC10B30B -:10967000F8BDD0F838038047C0B105F05BFBA8B156 -:10968000F8688069007888B9FAF79CF90D4E30784F -:1096900060B9B86800210027D0F89400007802F083 -:1096A000EBFC10B9204607F0D1FB37702846BDE827 -:1096B000F84010F05CBBBDE8F8400BF065BB00BFA4 -:1096C0000C010020B67A002070B51A4800211B4D0D -:1096D0000160194801604FF470002860184801705B -:1096E0001848017010F091FA174E0446306830B9EE -:1096F00016488068D0F84C058047306828B110F0D3 -:10970000D9FB10B1306810F02CFB3068012110F04B -:10971000D3FB306810F0D2FB204610F064FB0B48FE -:109720008068D0F814150F2088472868BDE870407D -:1097300001F092B9307A00203C7A0020407A002073 -:10974000907A0020B67A0020342700200C010020F7 -:109750002DE9F0418CB00D4601464FF6FF70ADF893 -:109760001A008DB381B30027082614460DF11C089A -:109770000420002214232F70CDE902610DF11A019B -:10978000CDE900860AF0C8FE70B1CDE9047704A8DF -:109790000DF11A0100221423CDE90086CDE9026003 -:1097A00004200AF0B9FE01E001202870BDF81A007B -:1097B00054B107490988884206D207A920461422D5 -:1097C0000FF044FEBDF81A000CB0BDE8F08100BFF8 -:1097D000C0BA0200B0B592B0044600684189CA0719 -:1097E00038D021F0010141810168086AC97F01ADCB -:1097F0002A46FFF737F968BB0B990878042829D166 -:109800000020CDF84200CDF83E00CDF83A00BDF87A -:109810000E00ADF838000EA891F9011002308A064A -:1098200044BF01228DF84320B1F1FF3FCAB2DCBF33 -:1098300001218DF84210510605F1140158BF05F1C0 -:109840001801096810F00BFB20798DF844000EA870 -:1098500010F046FB12B0B0BDF0B589B0ADF82010E5 -:10986000079043B33AB391B207A802AA1C4604F08A -:10987000EDFB064600BB174F786808B18047F0B192 -:10988000B86800F03BFE054613480022032300920F -:10989000C188C07802AAF0F7AFFE90B1C0B20A2822 -:1098A00011D102A821460122EEF71EFB0646002830 -:1098B00018BF012608E00426304609B0F0BD0B268B -:1098C000FAE70D2600E00126B868294604F044F9BD -:1098D000F2E700BFA0230020B87200202DE9FF416D -:1098E000DFF870800C460546ADF8040002208DF8C4 -:1098F0000C00B8F8241001A80EF082FA1A281BD028 -:109900001548164900234FF6FF770278FF209A4248 -:109910000BD031F82360BE4203D1FF2808BFD8B274 -:1099200001E0AE420AD00133F1E7FF2809D1B8F8CF -:10993000241001A810F00CFB002008E001EB8300CC -:1099400003E021F8205001EB80004480012004B0A6 -:10995000BDE8F081A86D0020D2BA020098780020FE -:1099600070B514460E460FF047FF0325052E2CD880 -:10997000DFE806F003090E2B161B19498A6CCAB1E1 -:10998000896C098E02E0154991F8601021801BE076 -:109990001149097E0239B1FA81F14909217013E0B8 -:1099A0000C490A68226049680DE00A490A681AB140 -:1099B000D26802E0802508E000222260496809B1EF -:1099C000C96800E000216160832510F0D0F92846C5 -:1099D00070BD00BF70200020D01E0020206E00202F -:1099E00030210020F8B504460FF006FF1A4F054657 -:1099F0004FF0FF30386204F1B80010F0B2F9174EA2 -:109A0000B6F85600B6F85410884210D1144890F8B1 -:109A10002400397E022918BF002808D0284610F0FB -:109A2000A6F9072003F058F80FF0E6FE0546B6F851 -:109A30005600B6F85410884206D10A4810F091F941 -:109A400008200BF01BF802E0012084F8FC002846F7 -:109A5000BDE8F84010F08BB9D01E00203021002066 -:109A600070200020387100201C48007830B1022896 -:109A700010D001281CD144F2010101E04FF48041D3 -:109A8000174A002811806FF0710108BF6FF0700154 -:109A9000917014E0124844F202016FF07F020180DD -:109AA00010490978012908BF6FF07702827006E03B -:109AB0000B484FF40062018862F3DF01018008481F -:109AC000A021094A41810021C0F80320C17101731E -:109AD000018941F430510181704700BF24260020E4 -:109AE0003E790020E5270020000050A0E0B5134695 -:109AF000062813D0052814D088BBA1F13A0002280B -:109B000016D3622917D068291DD0B1F5817F12D0F4 -:109B100040F20310814222D114491AE0009306203A -:109B200001E005200093002210230CF077FD8CBD8E -:109B30000846012101E008460021102202B0BDE8DC -:109B400080400FF019BB074800780138012806D87B -:109B50000549184610220FF079FC00208CBD0A2020 -:109B60008CBD00BF2426002024B9020014B90200D5 -:109B700070B504461848C1688969097819B1174851 -:109B80000121017070BD164E164D31788A00B5FB6B -:109B9000F2F2A24204D28068D0F84C0580473178B6 -:109BA00004FB01F01049096801EB80040F480068CC -:109BB000C06B8047211AA1F54871B1F1FF3F05DC68 -:109BC0002918091B013148BF00F54874084821468F -:109BD000BDE87040F7F760BE0C010020B67A0020A7 -:109BE000B47A0020FFF6C2FF307A0020347A0020D9 -:109BF000BD6402002DE9F8431B4C1A482188868C6D -:109C000081845020214608F0BFFA184825884FF675 -:109C1000FE78174C08F10109077887B16089294659 -:109C2000B04208D0A84207D020461C2110F076F898 -:109C30004946A4F800806181013F1C34EDE70D4CDA -:109C4000206868B106200DF079FB48B14FF48071AF -:109C500085804180D52101702168BDE8F84308471F -:109C6000BDE8F883A86D00209A690020D1BA0200EF -:109C70003056002060270020F8B5014600681B4DD3 -:109C80000022002304882D6855B16E7B052E05D176 -:109C90002E683688A64208BF013201330435F2E748 -:109CA000134C0526DBB20127D2B2258A4E734E89AA -:109CB00046F400664E810F4E3678B3420E4B28BFF5 -:109CC0003D461B789A424FF6FF7228BF3D460D81F4 -:109CD0000188914205D0A18C0EF092F81A2818BF85 -:109CE000F8BD0120BDE8F8400FF0B7BF587A00205A -:109CF000A86D0020DDBA0200DEBA02002DE9FF41A6 -:109D00000D4603A90DF10A0208F0FEFE044678BBD9 -:109D1000039FBDF80A007880182010F0F5F838B3DA -:109D20007988064600900620002218234FF000088C -:109D30000CF074FC3046294610220FF087FB79881E -:109D4000062018223346C6E904880CF07DFC304614 -:109D500018210FF0E3FF304610F0D4F87888064958 -:109D600000EB400041F8208001EB8000C0F8048047 -:109D7000204604B0BDE8F08130750020F8B50746F4 -:109D8000042014460E468DF8010068460CF0A8FE2B -:109D900048B30546006907210170397D4170797D1E -:109DA0008170B97DC17007F10B00286240F201108B -:109DB000A5F81D000FF0A0F80E48402168620120B0 -:109DC000A876701E10F0FD0F0B4808BF4FF4886195 -:109DD000012C0088E982688004BF0020287628468C -:109DE00004F00AFE00E0102003494FF6FE720A80DC -:109DF000F8BD00BFE0790020802700202DE9F84F52 -:109E0000DFF87090DFF870B000244FF0010AE846E8 -:109E1000002599F800009BF80370C0B2A9B28142F6 -:109E200025D29BF80200FEB2864213D030460021B4 -:109E3000424604230FF0D2FA9DF800007C2818BF98 -:109E4000FF2811D106EB46000BEB8000808B201A17 -:109E500000F5005499F800005AFA87F10135B1FB7A -:109E6000F0F202FB1017D8E77E28EBD0F2E720468D -:109E7000BDE8F88F9B7A0020B8720020F8B51E4D1F -:109E800004464FF0FF3128680FF0D8FED4E901678F -:109E90007168388CC5E90110796911BB398B294487 -:109EA0000A7B013A0A7311061BD1204604F014FF05 -:109EB000B92029898DF8030020460FF07AF90DF1B9 -:109EC0000300012105F0DEFE298920460FF07AF912 -:109ED00070680FF0A0FF388B002105EB8000016156 -:109EE000A86881B22046FCF7BAFB002030702868D1 -:109EF00010F01CF8F8BD00BF0C2400202DE9FE4333 -:109F00008BB11D681E46804685B10FF07EFE04466B -:109F100028680FF0CFFF10B128680FF022FF20460D -:109F20000FF061FF1BE00220BDE8FE830C20174606 -:109F30000C46FCF739FDE0B1E946054648460FF00E -:109F400014FE002041464A4602958DF8000001901B -:109F5000094809F0CFF885E8910050B135602868CC -:109F600041460FF0A9FF28680FF0A8FF0020BDE8C8 -:109F7000FE830820BDE8FE83E19D0200F8B50A4695 -:109F80001C491D4D00234FF6FE760C7802F040016F -:109F90009C420DD035F83370874207D1B04209D0CA -:109FA00005EBC307BF7957407F0613D50133EFE7B1 -:109FB000224600E0DAB24FF6FE73984208BFA24292 -:109FC00011D10026B44207D005EBC600007928B1B4 -:109FD0000136F7E7DAB206E0224604E035F836004B -:109FE0000DF073F8F2B20020A24238BF05EBC200B8 -:109FF000F8BD00BFD6BA02004C5000207CB51C460C -:10A0000016460D46042803D0022812D001282BD171 -:10A0100028460121224601F06FF828B34EB12846A8 -:10A0200002F0A8FF12490978884202D2012030705C -:10A030001AE028460021FFF7A1FF70B1817911F0E5 -:10A04000180F0AD00B49438800884FF6FE72009221 -:10A050000022C98A05F012FF08E00748214602786D -:10A060002846F4F773FC08B100207CBD01207CBDBC -:10A07000D7BA0200A86D0020CABA020070B5056800 -:10A08000D5F8F81031B3D5F8582144685668A16B5B -:10A0900020683268D16202210EF0ECFDD5F858013B -:10A0A000A16B154A40680068C0F8041591FAA1F147 -:10A0B00012683068B1FA81F1926990470446D5F888 -:10A0C000F800011B6879022806D105F1D0000BF0D9 -:10A0D00096FE0BE000240CE0D5F8F400D5F8FC2047 -:10A0E0000A44401AC5F8FC20C5F8F4000020C5F861 -:10A0F000F800204670BD00BFD40100107FB50020DD -:10A10000ADF80C000190ADF8080014200FF0FCFE33 -:10A11000D8B1044618480068A0B1022601AD142E3B -:10A1200006D0A019294606220FF090F90636F6E768 -:10A1300003A9204602220FF089F94C20142122465F -:10A140000FF0C2FC20460FF0DDFE18200FF0DCFE01 -:10A1500088B1182104460FF0E1FD0025022D07D833 -:10A16000A9B20620182223460CF06EFA0135F5E755 -:10A1700020460FF0C7FE7FBDEC2600201CB51B4813 -:10A180000078022831D11A4C206910B10AF090F8F9 -:10A19000FAE70EF02DFA17480178082908D00129AE -:10A1A00005D101200021BDE81C40EAF727BBC170A2 -:10A1B000082101700FF0E2F80A200DF0F1FD0E48C1 -:10A1C0000221007805F00EFC4FF4804000210024AD -:10A1D000F1F750FB0DF1070152208DF8074007F011 -:10A1E000D3FF08200021EAF709FB1CBD242600202C -:10A1F000AC2200200C7A00209C7A00202DE9F84344 -:10A20000DFF874901446D9F8082002EA01038B4263 -:10A2100021D1806843688B4220D966186FF005050C -:10A220009E4226D82240A24223D10068471808F057 -:10A230000BFD8046ACB10FF0DFFA064638460EF053 -:10A2400025F8054630460FF092FD5DB9D9F80400B7 -:10A25000241A0744EEE76FF004050AE06FF00305E7 -:10A2600007E0002540460DF097FA002D18BF4FF08B -:10A27000FF352846BDE8F883DC25002070B51C4D6D -:10A28000A968086C006828B9D1F84C058047A8680F -:10A29000006C00684068174E007800F020003070B5 -:10A2A0000FF0AAFA044614480178832911D13178B5 -:10A2B000A1B1A868016C096891F8781011B9D0F8BB -:10A2C0004C05804720460FF052FDBDE870400BF072 -:10A2D000BBBB2046BDE870400FF049BD8521017031 -:10A2E00020460FF044FD0020BDE87040F8F714BA96 -:10A2F0000C010020C47A0020B87A0020BCB50446C6 -:10A3000040780AF0EBFA6078A0F11901022903D332 -:10A31000F12801D0E12809D1144D287818B900207E -:10A320000BF09AF9287880F0010000E000200F4936 -:10A3300008701048007802280BD10D48007840B909 -:10A34000607840F00200EB2803D130200021F1F7C3 -:10A3500091FA094863780122818C408B0092002297 -:10A36000EEF77EFBBDE8BC400CF0FBBEB72700203B -:10A37000E527002024260020A86D00207FB50EF0E0 -:10A38000E9FBA8B1417B062912D1016845890A7A07 -:10A390008DF80C200C88ADF804400CF013F928055A -:10A3A00004D5002021460CF07BFD20B1012000E007 -:10A3B000002004B070BD104DA98C01A80FF0C8FD9D -:10A3C000002000210CF06CFD04464FF6FF7674B1BE -:10A3D00020680188B142E9D0A98C0DF011FD1A283E -:10A3E000E4D0204600210CF05BFD0446EFE700209E -:10A3F0000FF033FCDAE700BFA86D002070B50D4602 -:10A40000242104460FF08AFC8DB328781A4E207060 -:10A4100068786070A878A070E878E070287920717A -:10A4200068796071A879A071E879E071287A207262 -:10A43000687A6072A87AA072E87AE07204F10C007F -:10A44000E968B047287C2074687C6074287DA0741B -:10A4500004F11300A969B047E96904F11700B04796 -:10A4600095F82000E07695F82100207770BD4FF632 -:10A47000FE70208070BD00BFDB9D020070B5184BE0 -:10A480002021EFF3118081F31188174C1548DA6C05 -:10A4900002609C64154C1A661C64154B04689C424F -:10A4A0000FD14268144B22F47F421A4442608176F5 -:10A4B0000021C160D0F82C1221F04041C0F82C12CC -:10A4C00070BD0C4D0024362CEBD00E2C8EBF42F804 -:10A4D000245053F8246042F824600134F3E700BFAD -:10A4E000381F002008ED00E00010000000300120BF -:10A4F00000000000696F02000000FA052DE9F0433A -:10A5000085B007461C480125846984B3666990F8C4 -:10A5100008800572B868012807D100254046BD6053 -:10A520003C61FE6009F078FA21E03869A0421AD057 -:10A53000204607F114090EF05AFC01A900254846EF -:10A5400032466162CDE903450DF018FA3869406979 -:10A55000864203DD38693146FBF79AF8404609F038 -:10A560005BFA656203E0404609F056FA0125284689 -:10A5700005B0BDE8F08300BF38220020FEB51446C8 -:10A580000DF1050207230D4606460EF027FF9DF844 -:10A5900005109DF806209DF8073026749DF80A6086 -:10A5A000A5819DF80B009DF808504FEA910C01F031 -:10A5B0000301A07242EA01219A009DF8093084F853 -:10A5C00008C042EA9512E1809F01A28047EA9607FF -:10A5D00067720127962806F0030008BF0427384356 -:10A5E000E07205F03F00800140EA9300E08108033B -:10A5F00040EA0C6010442060FEBD70477FB5054600 -:10A6000008460C460FF0AAFB98B10188A94210D069 -:10A61000017904290DD80139058001290DD8144983 -:10A62000097869B1134A52F82110C1EB0111890070 -:10A6300008E00025284604B070BD6FF0010104E079 -:10A640000C490968002280F820208161C161002145 -:10A650006E46ADF802500125C160301D21468DF8CF -:10A6600000500EF0BAFF3046F7F708FAE2E700BFF5 -:10A67000D827002090B40200B0B51D4DE868D0F88E -:10A68000880080470FF0B8F80446E868C06D80473E -:10A690000FF070FA496A90F942008847D5E9020143 -:10A6A000D0F8AC00896C007888470FF063FA096E27 -:10A6B000C08C88470FF05EFA496E408D88470FF0D6 -:10A6C00059FA896E4430884720460FF050FB0FF04E -:10A6D00051FA096B90F843008847A868D0F83024F5 -:10A6E000D0F8D40000F129015220BDE8B040104755 -:10A6F0000C010020BFB5002000210EF06DFB134CB3 -:10A700000021206000200EF067FB606001AC204655 -:10A710000FF0C2FA0E4D0121224628460DF0D8FF57 -:10A720000C4C25600FF006FA21680B4A0AF058F924 -:10A730000A4908700FF0A2F809480FF0A5F8094877 -:10A7400009490A4A09F084FBBFBD00BF302600203A -:10A7500074770020507A0020547A0020BD7A0020BF -:10A7600079B701002D890200995502001589020070 -:10A770001CB5E12903D01949097801B91CBD01892B -:10A780000131018188B2884208D016480021A0F822 -:10A7900070100120BDE81C4000F052BE1048007847 -:10A7A0000028EBD00F4CB4F870108142E6D900209D -:10A7B00000F046FE642100FB01F2B4F87010B2FB19 -:10A7C000F1F21A2ADAD3084A1268002AD6D0ADF874 -:10A7D0000600ADF8041001A890471CBDDBBA0200CA -:10A7E000DA270020A86D0020D4240020F8B50E46FA -:10A7F00007460FF001F880250446022E0AD81649B4 -:10A80000F0B201EB40162EB1B07A10B13068B84208 -:10A8100005D0802520460FF0AAFA2846F8BD0F483B -:10A82000017E022911D1717A4FF4A062406802EBD7 -:10A8300001210B4A11430B4A114000220AF038F95A -:10A840000546304600F01CFCE4E7304600F018FCFA -:10A8500002F0C0FF8125DDE7206E0020D01E002021 -:10A860000100080401FF080470B586B004468DF8A5 -:10A8700016004FF6FC700D46ADF81410081A0328A8 -:10A8800012D8022810D000208DF8170005A803F078 -:10A890006CFF06461148012104701148017008F050 -:10A8A000EBFD304606B070BD0220ADF806508DF8C5 -:10A8B000040001A8FEF7D8FB0126012809D1BDF844 -:10A8C00006008DF81760ADF8140005A803F04DFFE1 -:10A8D00006464FF6FC708542DCD2E0E7EB2700200D -:10A8E000EA27002070B592B0044605300DF12A0128 -:10A8F0000AF002FD012802D0207902282ED06088BB -:10A900000BA900F0DDF9012828D10DF11A000DF195 -:10A9100003010E900BAD01AE28463246FEF718FF3C -:10A920009DF80300D0B19DF8161006F108000DF156 -:10A930001A0203F049F800200F95119001208DF8BC -:10A94000420040F20110ADF8400004208DF83600BE -:10A950006088ADF834000DA8EEF7ECFD12B070BDC4 -:10A960002DE9F0410646087A0D46904601280EBFB3 -:10A97000288828460AF0BAF94FF6FE71884203D1BA -:10A9800000210846BDE8F0811249DFF84CC00022E2 -:10A990000B786146002BF3D00F78B74210D12C7A98 -:10A9A0004F78012C05D1012F0AD14C88A04207D144 -:10A9B0000AE02FB94C88A04202D10C794445E0D07E -:10A9C0000E31013B0132E5E7C2EBC2000CEB400166 -:10A9D000D7E700BFDFBA0200307900202DE9FC473D -:10A9E00004460D4640689146DFF868A09846A16885 -:10A9F00040680A8CCAF804002046CAF808200E688D -:10AA000004F06AF9074610BB03208DF804007019A2 -:10AA1000010A8DF80700000C8DF80610BAF808102E -:10AA20008DF8050020460EF0C4FB01A8042105F0B6 -:10AA300029F910B14FF0FF3704E0484641460DF0C8 -:10AA4000FFF90746BAF8081020460EF0BBFB38465F -:10AA5000BDE8FC870C240020B0B51749CA6892698C -:10AA600012781AB1154801210170B0BD154B144A76 -:10AA7000154D1B7812689B0003FB0024B5FBF3F215 -:10AA8000824203D28868D0F84C0580470F4800689E -:10AA9000C06B8047211AA1F54871B1F1FF3F05DC79 -:10AAA000291B0144013148BF00F54874084821467C -:10AAB000BDE8B040F6F7F0BE0C010020B67A0020E9 -:10AAC000307A0020B47A0020FFF6C2FF347A0020EA -:10AAD000F14D020070B5194D0446287820B1184890 -:10AAE0008068D0F84C058047154E164A052CB06892 -:10AAF000D0F8D410C98C11800BD8DFE804F0030D16 -:10AB00000D050A0D012002E00AF0A6F903202870C5 -:10AB100070BDD0F84C058047022028700AF09CF9DF -:10AB2000B0684FF6FF72D0F8D410CA840649D0F846 -:10AB3000D400C08C48860549C88170BDB27A002017 -:10AB40000C010020AE65002000720020007900207A -:10AB500070B50446B0F90E00227A81B2920702D590 -:10AB6000227B1F2A0CD8154A6368D26C52F82050F9 -:10AB70009D4218BF42F820304A42E281227B0BE01E -:10AB80000E4B1D6D45F820400D4DDB6C53F82060D9 -:10AB9000AE4218BF43F82050102901D30A4902E001 -:10ABA000042902D3074901440A70217AC90718BF52 -:10ABB00007F060FC0020A060002070BD381F00205E -:10ABC000CDF5000014ED00E0F0E300E080690278CC -:10ABD0000A70B0F801304B8002B17047C2788B88A0 -:10ABE00062F302038B80C278D20862F3C3038B80C6 -:10ABF000C278120962F304138B806FF3DF230279AA -:10AC000002F0F80243EA02228A8022F4E062037929 -:10AC100003F0070342EA03228A8042798A7182792B -:10AC2000CA71C2790A72027A4A72427A8A72827A46 -:10AC3000CA72B0F80B208A81427B8A73827BCA7306 -:10AC4000C07B087470477047B0B588B0044640892F -:10AC500006AD294600F034F80DF117016A46284682 -:10AC6000FEF776FD9DF8170070B19DF81000FD28E5 -:10AC700018BF002808D11048007828B9607A18B9A0 -:10AC80006068007806280FD0607A18B9606800788C -:10AC9000072809D0207B18B960680078052805D1FD -:10ACA000064841682046884708B0B0BD4FF49A7006 -:10ACB000FFF7A3FCF8E700BFC127002050240020C5 -:10ACC00070B5064619480C46C08AB04206D10EF04F -:10ACD00013F9014620460FF0C2F806E00EF0B0FD71 -:10ACE000B04205D120460EF0E0FF0125284670BD98 -:10ACF000304621460BF010F805460D480078002834 -:10AD0000F4D10EF087FE0028F0D1002DEED1002501 -:10AD1000002EEBD007480188B142E7D100F11801BD -:10AD2000204608220EF092FBDFE700BFA86D00204E -:10AD300024260020502400202DE9F04104464FF63F -:10AD4000FE70A081207850B3184F04F1040800254C -:10AD50004FF0000C388883B2AAB29A4221D2530035 -:10AD600013FA85F67B6813F82610090715D12078A9 -:10AD700003EB86066188307002EB420003EB800033 -:10AD80004180043041460EF028FC3046A5810EF08B -:10AD900009FD38884FF0010C05460135DBE74FF01F -:10ADA000000C5FFA8CF0BDE8F08100BF4026002067 -:10ADB0002DE9F04F85B005460C464FF6F77035B9D2 -:10ADC000844204D90026304605B0BDE8F08F14490E -:10ADD00008300DF10408134E4FF0010B08F104097F -:10ADE0001FFA80FA0F78002FECD03079FF2814D0AA -:10ADF00075B170888DF804B0ADF81000404605F0CC -:10AE0000B7F850B1284649460CF0A7FD28B1DAE75B -:10AE1000544502D03088A042D5D02436013FE2E725 -:10AE2000E3BA02002045002070B51B4C264630686E -:10AE300088B1017B01390173090609D121682E46C9 -:10AE4000814208BF2646016831600FF05BF8EEE7EB -:10AE500005460646EBE7104C606848B1C17E0139F3 -:10AE6000C176090605D10FF04DF80020606000E0C2 -:10AE70000020216808430DD0084C08214FF47A7255 -:10AE800020780EF0A7FF28B120780821BDE8704097 -:10AE900003F03CB970BD00BF682600209A7A0020FC -:10AEA0001A481B4AD0F8841000681140194A914290 -:10AEB00011D1C0F30332C0F34061082A0ED0092A31 -:10AEC00011D00F2A07D1020213D400F08072A9B169 -:10AED000A2B1112000E0FF2040B270470A200029F3 -:10AEE00008BF0C20F8E74FF0FF30002908BF092009 -:10AEF000F2E70E20002908BF0D20EDE70B20002A05 -:10AF000018BF1020002918BF0F20E5E79412005049 -:10AF100000F0FF0F0010B40B10B517480168890747 -:10AF200026D417480468A00221D416480068006897 -:10AF30008047C0F13E000722C1100729B8BFC210E8 -:10AF4000012000EB24718A42D8BF0A460E490968E5 -:10AF5000C1F30321891A0F29A8BF0F210129D8BFE6 -:10AF6000014641F0F000094981F84D00087810BD14 -:10AF70000249C16010BD00BF10000940FD00004043 -:10AF8000B44F0050EC0100100C1300500D6208404B -:10AF90002DE9F041154F164A164B174CDFF838C013 -:10AFA000DFF838E0DFF838800E4D0F4E0021C0E9A1 -:10AFB0000A11C0E90043C0E90227104A104B114CA6 -:10AFC000C0E90465C0E9068EC0E908C1C0E90C43C8 -:10AFD0008263BDE8F08100BF91F9010029C9010039 -:10AFE000256E0100EDB7010079910100958C0100FB -:10AFF000599801003DF9010061320000FD9D0100FA -:10B00000BDC80100A9820200F8B51A4E0546306895 -:10B0100028B119490978A9420AD8002428E005F086 -:10B0200043FC3068002418B313490978A9421FD99A -:10B03000124A05EB450102EB81044FF0FF31D4E9E0 -:10B0400001570EF0FBFD287870B970683968421E10 -:10B050000A4209D17968814206D3B068084081422A -:10B0600002D10120287000E0002430680EF05EFF5D -:10B070002046F8BDDC2500208DB9020028B702006B -:10B08000F8B505460EF0B8FB0446A87A50B36F7ABF -:10B0900001260CF045FE697A48B1154A48B21130D4 -:10B0A000536806FA00F08343C0435360106006FA09 -:10B0B00001F31049002206FA07F02A72AA72C5E9C4 -:10B0C0000422AA61C5E9002291F8605091F862203B -:10B0D0002B4381F8603012B1013A81F86220C0B28E -:10B0E00009F0CCFC2046BDE8F8400EF040BE00BFA1 -:10B0F00008100440206E0020F8B515460E460446A0 -:10B10000012905D119480178204608F0D1FBA0B9E2 -:10B110002046002106F0ECF92946FEF72FFF012E0C -:10B1200007D14FF6FE7750B14179012907D1408808 -:10B130000AE0C8B14079B04216D10020F8BD6806D7 -:10B140004FF6FE7058BF204608490D7886B2BE42C1 -:10B150000AD03046294608F0ABFB0028EDD1A642C4 -:10B16000204608BF3846F1E70120F8BDCCBA0200FE -:10B170002DE9F041D0E901480546D8F800004168C2 -:10B1800021F00201416020460EF09AFED4F8CC0076 -:10B1900008F092FF04F130000EF0CAFE94F8F800B7 -:10B1A00018B904F16C000EF0BFFED5E901750D4E23 -:10B1B00095F83800B04795F83900B04795F83A004F -:10B1C000B04797F8FB00B04798F80C00FAF7EEFF8D -:10B1D00004F11C000CF064FD002084F8FD00BDE8C3 -:10B1E000F08100BF313102002DE9F04385B01A48EB -:10B1F0000DF10808002708F1040490F800901748A2 -:10B2000000F139054F4523D2FEB2072000220C235E -:10B21000CDF8008031460BF001FA2846214608227D -:10B220000DF05EF8A0B92046002108220DF07CFD4B -:10B2300001370028E6D02046294608220EF006F9FC -:10B24000002031460C22029002AB07200BF0FCF9E3 -:10B2500005B0BDE8F08300BFD3BA0200A86D00209E -:10B26000F0B58DB0451D04460DF1160128460AF0D3 -:10B2700043F801282BD1608806AE3146FFF720FD48 -:10B28000012824D10DF106011020099101F090FC54 -:10B29000012000270A958DF82E0040F201100C972E -:10B2A000ADF82C000B4800788DF822006088ADF8CE -:10B2B000200008AC2046EEF73DF9BDF816008DF8E9 -:10B2C0002C700A96ADF820002046EEF733F90DB049 -:10B2D000F0BD00BF9A27002070B50D4606460EF05F -:10B2E00094FC04460EF0E0FD0146B5FBF0F0022EA2 -:10B2F00006D0012E09D1A9420ED91148006808E0F4 -:10B30000A9420CD90E48406803E0A9420BD90C4869 -:10B3100080680EF013FB0DE00B49094B07E008496C -:10B320000B1D084903E0064901F108030749002203 -:10B33000FEF7E4FD2046BDE870400EF054BD00BFAE -:10B34000C4250020ED9002003D910200818502009D -:10B35000F8B51C4F06460D46F868C068007828B955 -:10B36000B8680021D0F85824012090470EF044FA24 -:10B3700004460CF0C5FD30460EF01CFE0646B868CB -:10B38000D0F8E010D0F8EC0050F825000860B9685B -:10B39000D1F8E4100860B868D0F8E00000680CF05C -:10B3A000B3F9B868D0F8E024D0F8D8000168304686 -:10B3B0009047B868D0F8D40480472046BDE8F840EC -:10B3C0000EF0D5BC0C01002010B51B4C0121A0686B -:10B3D00042695177D0F8D420527B0F2A04D1D0F89B -:10B3E0006401BDE810400047D0F8A8000170E06893 -:10B3F000016C20208847A068104AC1688A61D0F893 -:10B40000D430D0E903215B7B92F8304031F813103F -:10B410006400A1404FF4707404FA03F3B1EB930F8E -:10B4200028BF9908962303EB4101D0F8F03402F1CC -:10B430001000BDE8104018470C0100200169010010 -:10B4400070B518490A780021012A4FF0000213D87C -:10B45000154A02F11003154A1478002264B113F85A -:10B460000C5CFF2D05D01D881DB108B1198000E0CE -:10B470002A442433013CF1E70E4C0D4B4FF6FE7588 -:10B480002478183364B133F8186CAE4205D01E88A6 -:10B490001EB108B1198000E032441C33013CF1E7D1 -:10B4A00090B270BD2426002020450020E3BA02009F -:10B4B00030560020D1BA020070B51A491A4A044623 -:10B4C0000AF0E2FB0146E061012051B3002184F85B -:10B4D000200061626069B0F1FF3F1ADD60690121FF -:10B4E000124A01FA00F0A0616069157A1172116ABE -:10B4F00001EBC000E0642020EFF3118680F3118897 -:10B5000020460DF087FB86F31188284608F084FA60 -:10B5100006E00648A16121462C30E0640DF0CAF82F -:10B52000002070BD05780200492E0200382200205C -:10B5300070B5427C0C46017C85692270428861703E -:10B54000A91C62802888A080A01D0EF088FCA87A23 -:10B550000026A073B5F80B00E66166612082687B67 -:10B560000E35A07458B140000EF0CEFC606130B1D1 -:10B570000246A07C29460DF05BFE054600E0A6745D -:10B5800015F8010B207658B140000EF0BDFCE061CB -:10B5900030B10246207E2946BDE870400DF048BE1D -:10B5A0000020207670BDB0B586B00C46ADF8000026 -:10B5B000002101256078CDE901118DF805508DF845 -:10B5C000030094F9000000F00C01002800F00302D1 -:10B5D00000F0200048BF80310223012A08BF122357 -:10B5E000184408448DF802006846F3F745FE9DF8BC -:10B5F000140088B90398457661884187D4F806100D -:10B60000C0F83E10617D80F84910B4F81710A0F81A -:10B610004B10684606F0F8FF06B0B0BD10B586B016 -:10B6200004460020617800908DF81400CDE90100F7 -:10B630000220012918BF042923D18DF8040001201C -:10B640008DF8050021208DF802002078ADF800006B -:10B650006846F3F711FE9DF81400B8B90398082165 -:10B66000406C0170617841706178022903D1616892 -:10B6700002300EF0F4FB684606F0C6FF9DF8140099 -:10B6800004E0022901D10A20D7E7B32006B010BD9B -:10B690002DE9F84304466FF0010004F10409A0818C -:10B6A000608048460CF00AFD012822D1144E002784 -:10B6B0004FF0000831888AB2B8B290421BD24200E3 -:10B6C00012FA87F3726812F823301B070FD000EBD1 -:10B6D000400002EB80054846291D0CF03EF93188F8 -:10B6E00028B16888A7814FF001080F4660800137B4 -:10B6F000E1E74FF000085FFA88F0BDE8F88300BF8B -:10B70000402600202DE9FF4704460120022108F0D1 -:10B710006BFA2070C0B220B3C0000EF0F5FB00B38E -:10B7200080461348E9464FF0010A09F104064746EE -:10B73000841C10480578B5B1A078013801280DD8CF -:10B7400020888DF800A0ADF80C00484604F010FCED -:10B7500020B1384631460EF082FB07462434013DC5 -:10B76000E9E74FF00008404604B0BDE8F08700BFAD -:10B7700020450020E3BA02002DE9F04106460C20E6 -:10B7800090460D460EF0C0FB044608200EF0BCFBB0 -:10B7900094B1074680B1B8F1000F7E807D60A7604C -:10B7A0000CD028460CF0A8FC38460EF0ABFB204627 -:10B7B000BDE8F0410EF0A6BBBDE8F08100202146B7 -:10B7C0003870074840680EF0A9F90648016841F052 -:10B7D0000801016004480068BDE8F04102F036BF8E -:10B7E00030260020547A0020507A00202DE9F043C2 -:10B7F00089B0109EADF82010079046B31C4633B3B5 -:10B80000154607A802AA214602F020FC0746F8B90F -:10B81000DFF84490D9F80800FEF770FE80460F4824 -:10B82000002203230092C188C07802AAEEF7E4FE4A -:10B83000074630B902A829462246334604F08EFE58 -:10B840000746D9F80800414602F086F900E00427CF -:10B85000F8B209B0BDE8F083A0230020B872002040 -:10B86000F8B5174C607850BB1648184D00210330CE -:10B8700020F0030614483246801B286083199A4240 -:10B8800002D202C22868F9E720F003000021104F1D -:10B89000304440F8041CE820314630602868EC3819 -:10B8A00020F0030041F8E80F00203960FBF77CF836 -:10B8B000C7E9006001206070286804386060F8BD46 -:10B8C00000260020C97A0020003001201C6E0020D4 -:10B8D000D0250020F8B5054616484BF2F521174E45 -:10B8E000006800FB01F714483C0A006800F440209F -:10B8F000B0F5802F10D11248006880030CD4F06896 -:10B900000068804707F022FD3168C9688847C01089 -:10B91000390B484304EBE0342DB90A48006820F0A5 -:10B920007F40204444083069416C2046BDE8F8401F -:10B93000084700BF08400C40B44F0050E001001021 -:10B940008C13005010200940F8B5164F1648BD6CF6 -:10B950000DF034FD0446154801680668214011F0D9 -:10B96000200318BF002D0AD0284600223D650BF0A9 -:10B9700057F90F484FF4804128300EF0DBFA04EA03 -:10B98000060010F4602008BFF8BD0A4991F8612054 -:10B9900042EA504081F8610007480021BDE8F840C4 -:10B9A0000EF0C8BA3021002020000E000C10044018 -:10B9B00070200020206E002040720020BFB5184D7E -:10B9C0000446287820B91748018941F00101018116 -:10B9D000204606F0B7FBBCB1134890F8410098B977 -:10B9E000287888B96C460020622100252246FEF79F -:10B9F0007DF8204600210BF067FD0020FBF702FBDD -:10BA0000CDE90255CDE90055084C206830B128B188 -:10BA100005680EF077FA25602846F8E7BFBD00BF3D -:10BA2000242600203E790020A86D0020E826002072 -:10BA30002DE9F8431A4E04464FF000094FF0D308A1 -:10BA40004FF6FF7736683EB3E089F18881421BD11B -:10BA5000A07C20300BF072FC0028F3D0214620227D -:10BA600005460DF0F3FCA27C2AB105F12000A86187 -:10BA7000A1690DF0EBFC3079294685F8008003F0D0 -:10BA800073FB4FF00109DDE7B942DBD101B20029B8 -:10BA9000DED41328D6D1DBE75FFA89F0BDE8F8835E -:10BAA00074270020B0B58CB006AC182120460EF0EB -:10BAB00035F9154D822018212246A84701AC1121E5 -:10BAC00020460EF02BF93A2011212246A8473B20B0 -:10BAD00011212246A8470D48002180F841100C484A -:10BAE0000078013801280CD80A4A4FF481701021DF -:10BAF0000DF0E4FF28B9074A4FF4817010210DF0D2 -:10BB0000E3FF0CB0B0BD00BFC99A0200A86D0020D1 -:10BB10002426002014B90200F0B585B080B3194F77 -:10BB2000FC686CB305461CB3A61C294608223046A7 -:10BB30000CF0D6FB08B9E468F5E7B868A8B102AD27 -:10BB400031460822681C0DF081FC05F10A013046DF -:10BB50000AF0F9F80120092100220C2300958DF844 -:10BB600008000948007807F04CFA204605F08AF8EA -:10BB7000F86828B904484FF40061007803F032FFF8 -:10BB800005B0F0BDAC220020A37A00202DE9F041E1 -:10BB90000446007A012801D1258803E0204609F0F7 -:10BBA000A5F805464FF6FE70854208BFBDE8F08156 -:10BBB0001048471C104806781048B0F800809EB125 -:10BBC000217A3878012902D1012801D009E040B951 -:10BBD000B7F80100A84204D1781E4146FF220EF0BA -:10BBE00047F80E37013EEAE72846BDE8F04105F088 -:10BBF00095B800BF30790020DFBA02004EB20200D3 -:10BC000070B505460DF0F8FD164E0446B068D0F844 -:10BC1000E010D0F8EC0050F825000860B168D1F8C9 -:10BC2000E410086010480068C06B8047104AB16893 -:10BC30001368D1F8E01063B90C4B1B789B00B0FB84 -:10BC4000F3F50868854204D9B5FBF0F5684358431D -:10BC5000106008680BF058FD2046BDE870400EF0FB -:10BC600086B800BF0C010020347A0020B47A00208E -:10BC7000307A0020BCB51A490020096811B104319E -:10BC80000130FAE7C5B268000EF03EF918B3144966 -:10BC900004460020096831B131F8042BC3B20130E9 -:10BCA00024F81320F6E70F49B1F86E00CA8A9042D3 -:10BCB00007D101F1390200212B46009402F006F968 -:10BCC00006E001F1390200212B460094FCF756FFF3 -:10BCD00020460EF017F9BDE8BC400BF021BF00BFB5 -:10BCE0004C270020A86D0020C1071CD101071DD4DE -:10BCF000C1061ED481061FD4C10420D4810721D4DB -:10BD0000410722D4410423D400F40051012200B29F -:10BD100082EA51310022B0F1FF3FC8BF012202EA9E -:10BD20000100404270470C48006870470A4840686C -:10BD300070470948806870470748C06870470648E0 -:10BD4000406970470448806970470348C06970477C -:10BD500001480069704700BF0875002000B17047B6 -:10BD6000B0B51A4CE06C58B340F2000CEFF3118000 -:10BD70008CF311882020EFF3118180F31188D4E92E -:10BD80001650E16CB1FA81F1C1F11F0100EBC10164 -:10BD9000A94215D9086802680A6051600A688A4297 -:10BDA00004D1416AE26C22EA0101E16401F04EFA39 -:10BDB000E16C29B1E06DB1FA81F1C1F11F01E5E754 -:10BDC000002084F84800BDE8B0407047A01F002064 -:10BDD00070B521B3154612B306680C4607F0D3F8C8 -:10BDE000B0680DF0BEFF47F6FF704FF6FF71854259 -:10BDF00038BF284640008D4208BF4FF0FF30A6F8FC -:10BE0000580060080FD04FF47A7100FB01F40EF077 -:10BE10004BF8B4FBF0F1A04288BF012104E0BDE87B -:10BE200070400BF012BD0021B068A6F8561089B220 -:10BE30000EF042F8B0680EF041F8022086F850008B -:10BE400070BD2DE9FF41044604201E4690460F4672 -:10BE50008DF80D0003A80AF043FEC0B1054646B1B7 -:10BE60000120AF80A8770020E876287840F0800095 -:10BE700028702869390AC1700321877080F8018011 -:10BE80000170204607F058FF18B100200AE0012099 -:10BE90000DE001AE2046314609F03EFF0028F4D007 -:10BEA0002E620120687728466C8002F0A5FD04B060 -:10BEB000BDE8F081B0B58CB0044601206D4611217B -:10BEC0003A238DF81E0020882A46ADF81C006068D1 -:10BED000099000200CF0B0F928B1684611210DF04E -:10BEE0001DFF002001E09DF8000001218DF81F00DA -:10BEF000681C25898DF8291008900DF0B3FC854247 -:10BF000002D10020002106E02089ADF8140060680D -:10BF1000069005A901200B918DF82A0007A8EDF7DE -:10BF200009FB0CB0B0BDF0B589B0054600200C4649 -:10BF30000121ADF810200890CDE905504FF6FC70B6 -:10BF40008DF81E108DF813408DF81210101A03286A -:10BF500011D802280FD000208DF81D0004A8EDF79D -:10BF6000E9FA0646284621460BF0AEFA07F084FAB5 -:10BF7000304609B0F0BD02206F46ADF802208DF8C2 -:10BF800000003846FDF770F801260128EAD1381D77 -:10BF90008DF81D600690E1E7BFB50568174A687A1D -:10BFA000012807D11268686990F8211040699268E9 -:10BFB000904714E068696C4690F821101068826818 -:10BFC000204690476869416990F82120204608F092 -:10BFD0002FFB08B1686801E06FF003006860084853 -:10BFE00040210160802101600021C0F8FC12022084 -:10BFF00008F02AFD03480DF099FFBFBDFC010010B9 -:10C000000444024098700020F8B506680D460446C6 -:10C010000DF0F2FB16490978012902D196F8221099 -:10C0200019B10DF0A4FE00241FE0012786F822704C -:10C030000DF09DFE0F49002D18BF294648680A786B -:10C040007060002086F82020022A4FF0000208BF0E -:10C050008A6886F8240086F8250086F82370B26086 -:10C0600086F826000A20F9F73BFE2046F8BD00BFFF -:10C07000A9270020D4B8020070B5194A194C103213 -:10C080002378002918BF0121002573B112F8106C24 -:10C0900005F00105864206BF11700E46167835433D -:10C0A00018BF01251832013BEFE7A078E90708D057 -:10C0B00098B90120012609F0FFFA022009F0FCFAE4 -:10C0C00008E0012809D1012008F0BEFC022008F098 -:10C0D000BBFCFF26A0783044A07005F0010070BDC5 -:10C0E0001C610020002600202DE9FF41194F4FF66A -:10C0F000FE764FF000086C464FF6FE7080B2B042FC -:10C1000024D10DF087FD0546F88A85424FF6FE7072 -:10C11000F4D00DF095FB85424FF6FE70EED0284628 -:10C1200007F00AFE00284FF6FE70E7D1002D4FF60B -:10C13000FE70E3D020468DF80080ADF80250FCF789 -:10C1400093FF002818BF35462846D7E704B0BDE85E -:10C15000F08100BFA86D002070B5194E044604217F -:10C160001D46307807F02EF908B1012070BD07F0A8 -:10C1700083F9022D21D808200DF0C6FEA8B105468E -:10C180001048016811B108460968FBE705604021C5 -:10C19000307807F017F901460020AC80C1F516721F -:10C1A00009042860EA8002D070BD102070BD30788C -:10C1B00040214FF416720DF00DFE002070BD00BF3F -:10C1C0009D7A0020E82600202DE9F843194C099FAC -:10C1D0008146884611461D4660683E7A0DF03FFE56 -:10C1E000089905700A0A41708270397AC170397AEB -:10C1F000012908D003290AD104300A9D39460DF0DF -:10C200002EFE057003E039780171797841711020B4 -:10C210000C2341464A46012EA070204608BF0E233B -:10C22000032E08BF152303F057F90021A170BDE8C4 -:10C23000F88300BF882600202DE9FC4118200DF06E -:10C2400063FE60B3044617484FF00008002700F172 -:10C250000806032F1AD03078012814D1BDB2062069 -:10C2600000221823009429460AF0D8F958B956E953 -:10C27000020118222346C4E90401062029460AF0D7 -:10C28000E3F986F800800C360137E2E720461821F2 -:10C290000DF044FD2046BDE8FC410DF033BEBDE885 -:10C2A000FC8100BF30750020F0B585B0194EB26832 -:10C2B000116F91F82B1059BBD2F8D410897839B38B -:10C2C000C168007AD2F88821904708B30446B06864 -:10C2D000016F91F82B2042F0040281F82B20D0F856 -:10C2E0005C1302AD28468847F0680127816A012067 -:10C2F0008847B0682A46D0F87863016FD0F8D40038 -:10C30000C38C01F120002146CDE900700520B04723 -:10C3100005B0F0BD0C01002070B517480D220024B7 -:10C3200001680131B1FBF2F303FB1211134A52F819 -:10C33000213042F82140016011490868C01A0860A4 -:10C34000F8F702F80F4D2E780DF0AEFD044628697F -:10C350000DF0B0FD00B170BD002E1CBF4AF20036DA -:10C36000C1F2E1162869B6FBF4F10DF0A5FD2869CC -:10C37000BDE870400DF0A2BD187A00206073002067 -:10C38000207A0020B824002010B50DF003FE0AF03A -:10C3900023FD144CA068D0F8D40090F843000BF0B3 -:10C3A0007DF9A06800210024D0F85824012090478E -:10C3B00004F026FD0AF038FD08F03EF8FDF784F998 -:10C3C00009481221C0E90044846008480DF0A6FC29 -:10C3D0000748047007480470F9F778FBBDE810407F -:10C3E0000CF0A2BE0C01002064790020AC78002083 -:10C3F000AA7A0020A97A002010B51648816829B1D0 -:10C40000154908308968D1F8541288470DF0F4F9BD -:10C41000124900240A6813681C7112680A600DF042 -:10C42000A6FC0F48017811B90E49097849B104708A -:10C430000C48047003F0A4FF0748C168C968097874 -:10C4400001B110BD80680021D0F858240020BDE85B -:10C4500010401047342500200C010020D87900201E -:10C46000B07A0020B37A0020B0B514480068C06BE1 -:10C4700080471348144900780D6884001148B0FBC8 -:10C48000F4F0854204D911488068D0F84C05804703 -:10C490000F48016804FB0511016004FB05110D48FC -:10C4A000F5F7FAF909488068D0F8E40480470DF000 -:10C4B000A3F9BDE8B0400DF05ABC00BF347A0020AB -:10C4C000B47A0020FFF6C2FF3C7A00200C01002065 -:10C4D000307A0020BD64020070B568B115460E4682 -:10C4E000044604290AD0022E11D0012E04D10120C5 -:10C4F00009F052FB114905E0C12070BD042009F08C -:10C500004BFB0D490978884284BF112070BD0C494E -:10C510000020258166736060086820B1014640688C -:10C520000028FBD1043107480C602021007801F07D -:10C53000EDFD002070BD00BFE0BA0200E2BA0200CB -:10C54000587A00209C7A0020FEB5044614486D46B7 -:10C55000046028460DF0A0FB124E002000212A4660 -:10C560008DF8000030460CF0B3F80F4F07F134059A -:10C570007E6028460DF0D8FA0C480521BC630C4CAF -:10C580004FF440620023BA642A46C7E910100949F3 -:10C5900020460AF039FDBC600CF041FEFEBD00BF34 -:10C5A000682700205877002088210020F0270020ED -:10C5B000406F0020694B00007CB5044606981D467C -:10C5C0000B46362902DB174A00210AE012491646BB -:10C5D000124AE381096E51F82310914207D00021DD -:10C5E0000F4A0091002108F0D7FD01207CBD1846BC -:10C5F00005F01EFF286969682073C4E90016287ACF -:10C60000A060297D11B140F00200A0602046FEF735 -:10C610009FFA00207CBD00BF381F0020696F020018 -:10C620000FAC02002BAE020010B596B0184C2020C3 -:10C63000EFF3118180F31188E06810B90AF085F9F1 -:10C64000FAE7E068216A134A0223B0FA80F0C0F1E9 -:10C650001F00137501EBC002E26151F830000021A8 -:10C660002174A06140F2000CEFF311808CF311886B -:10C670002020EFF3118180F311880CF087FDA16970 -:10C6800068461C301C310AF0ABFC16B010BD00BF70 -:10C6900038220020381F00202DE9F041B3F1FF3F80 -:10C6A00003DC5B42B1F1FF3F24DD4FF0000C4FF0A3 -:10C6B000010EDFF85080471E0026B1FBF3F505FBA5 -:10C6C000131418F80440BC55013E8B422946F4D996 -:10C6D0003044714230230138914203DA00F80139C5 -:10C6E0000131F9E7BEF1000F0CBF80F800C0013046 -:10C6F000BDE8F081013A49424FF02D0C4FF0000E99 -:10C70000D7E700BFA1B80200F0B540F6FF7C10F8F3 -:10C71000013B0024082CFAD00646DF0716F8015B1F -:10C720000DD1467806F00F070337122F0DD190F97F -:10C730000220D7B2B2F1FF3F09DD03300DE001F86E -:10C74000015B304601345B08E4E7023006E0C27862 -:10C7500007F07F07043047EAC2171237320942EA6E -:10C760000515654508BFF0BDED43002FEAD04A5DD1 -:10C77000013F0A700131F8E7B0B5056804460DF0D5 -:10C780003BF8002185F8241095F82120033A022A6D -:10C7900028BF85F825100DF0EAFA0F488168B1F13D -:10C7A000FF3FDCBF4FF0FF31E9610C4901602046DB -:10C7B00007F0C6F995F82000022804D10848BDE822 -:10C7C000B0400DF0B3BBD5E9002CE96995F82130F4 -:10C7D0002046BDE8B0406047884702400100008025 -:10C7E000E8700020FEB5876A04467E7801ADB91C6A -:10C7F00028460DF034FB1548294639300BF0ADF8CA -:10C80000B8B11F2E12D806F01F0568000DF07CFB92 -:10C8100078B1064607F10A0000218D420AD000EBEC -:10C820004102128826F811200131F6E7D320FDF7E6 -:10C83000E4FEFEBDA089009601AA00212B4601F06E -:10C8400045FB30460DF05EFBFEBD00BFA86D00202D -:10C85000B0B58AB0144DC5E900011448426001AC7E -:10C8600020460DF0BFF803202146ADF820004FF41C -:10C87000E130079001208DF8180040F20110ADF86A -:10C8800004000B4804900B4803900B480290059855 -:10C8900040F0200005900020EEF79EFAA86008F016 -:10C8A00063FE0AB0B0BD00BF482300207026002000 -:10C8B000816B0200FF600100098C0100F8B5174E82 -:10C8C000706808B1804730B3B068FDF717FE144FA9 -:10C8D000044600253978E8B2884206D2FAF7D8FF34 -:10C8E0003178013508433070F4E70E4F0020357879 -:10C8F000F8707870481E7E21B870B88BF8800020E0 -:10C9000008F020F8B878FE2108F01CF8B06821463D -:10C9100001F022F900E00B252846F8BDA0230020F5 -:10C920009B7A0020B8720020F0B587B0ADF81810DF -:10C93000059033B32AB31C466B46114605A81A4628 -:10C9400001F084FB0546E8B9114F786808B18047CB -:10C95000D8B1B868FDF7D2FD0646684621460022E8 -:10C96000EBF7C2FA054638B9BDF80C1021B19DF8B5 -:10C97000100003F073FF3D78B868314601F0ECF821 -:10C9800000E00425284607B0F0BD0B25FAE700BFFC -:10C99000A02300202DE9FE4F1648174EDFF85C90CB -:10C9A0004FF6FF774FF00208EB464FF0FF3A0A24AC -:10C9B0000578E5B13088B84216D0718871B1013977 -:10C9C000718089B2B1FBF4F202EB8202A1EB420169 -:10C9D00051B90CF00BFD0BF013FA05E00CF006FD5D -:10C9E0000DF0B6FAC6F800A00436013DE1E7BDE857 -:10C9F000FE8F00BFD2BA020098780020A86D0020F8 -:10CA00002DE9FC41E84604464146FEF759F930B3AA -:10CA10001448DFF854C000210078CFB287421BD2FF -:10CA2000FB0053FA81F363441B7AC3B107EBC707DA -:10CA3000C3F10805674458FA85F657FA85F7357843 -:10CA40003A78AA4206D1013B07F1010706F1010637 -:10CA5000F5D104E00131E0E72046F6F741FDBDE8FD -:10CA6000FC8100BF9E270020F05A002010B586B040 -:10CA7000184C00218068CDE90411CDE90211019420 -:10CA800002A9009105A904AA03ABF2F7B9FE059922 -:10CA90004FF6FF720988914201D00C4617E00399C6 -:10CAA000002918BF01210140012904D1029911B1C7 -:10CAB00001AA084602E050B1049801AA2B210BF00C -:10CAC00039FCFF2803D00198204000F100442046A3 -:10CAD00006B010BDFFFF3F0070B505460CF08CFEA0 -:10CAE000174E044696F82400A84386F824003068C0 -:10CAF00020B1B8300DF0DEF9054600E00025706881 -:10CB000018B1B8300DF0D6F9054396F8240030B9C5 -:10CB10002DB9306A18B190F82810890704D420463E -:10CB2000BDE870400DF023B9456A20460DF01FF9AD -:10CB3000306A022100220024A847346270BD00BF81 -:10CB40007020002070B5B0B00FAC842120460DF0ED -:10CB5000E5F8154803A90A4690E86800042068C271 -:10CB60008DF82800CDE9014102F082FB01A80AA955 -:10CB7000FCF71CF998B106AD0C490446142228466E -:10CB80000CF02EFE204629460DF0DAF90546204627 -:10CB90000CF002FA002D18BF4FF0FF3501E04FF006 -:10CBA000FF35284630B070BD90B9020034780020BF -:10CBB00010282FD1FEB5184E0C4630788DF80400A1 -:10CBC0000DF074F905460DF06FF968434FF47A776C -:10CBD000B0FBF7F08DF805000DF068F905460DF093 -:10CBE00063F96843B0FBF7F0000A8DF806000CF01B -:10CBF00083F901AD01460222E81C0CF027FC00205D -:10CC000000212A4640230094EDF708F82078307080 -:10CC1000BDE8FE40704700BF957A0020F8B5184D7A -:10CC2000A87808B1012429E00DF10301E12009F001 -:10CC300069FB144E9DF803100024307E81421DD004 -:10CC400001270DF1020152208DF80240AF7005F06E -:10CC50009BFA307E0B380F2804D806F11801E1202A -:10CC600005F092FA0DF1020152208DF8027005F0E4 -:10CC70008BFA002000240CF081FCAC702046F8BD3B -:10CC8000CC260020A86D00207FB504461748184E1A -:10CC900000783178084302D1608800B17FBDA06977 -:10CCA0000578FF2D08BFFE2528460AF049FF8DF8BC -:10CCB0000F000CF013FB10B128460AF03DF8307855 -:10CCC00010B928460AF038F8207B0028E6D1002069 -:10CCD0000DF10F0148F236020123CDE9001004F1F5 -:10CCE0001100A11C04F024FD7FBD00BFBF27002060 -:10CCF000242600202DE9FC410020ADF8040014207A -:10CD00000DF002F940B3DFF854800446D8F8000073 -:10CD1000F8B100264FF6FE770025122E0DD08119AE -:10CD2000A019062202300CF091FBD8F80000815BBC -:10CD3000B94218BF01350636EFE7ADF8045001A936 -:10CD4000204602220CF082FB4C20142122460CF0DB -:10CD5000BBFE20460DF0D6F8BDE8FC81EC26002095 -:10CD6000B0B5174C6068216801EA000521EA0002AD -:10CD7000680622601DD51348006800F44000B0F535 -:10CD8000000F03D11048006807F044FE04200CF0A7 -:10CD9000DBFD811E022905D207F002F9022007F00F -:10CDA00053FE03E0012808BF07F0FAF8202008F03E -:10CDB000C3FE280648BF04F079F9A560B0BD00BFE6 -:10CDC00090220840B44F0050DC2600202DE9F041AD -:10CDD0004FF02008EFF3118188F311880122144FDE -:10CDE00011490D7A0A72114991F8486081F848207A -:10CDF0000021104A3C7D3975396D1268D2B251F864 -:10CE00002210886040F2000CEFF311808CF311883F -:10CE1000D1E900018847EFF3118088F311883C7550 -:10CE200046EA0520BDE8F08138220020A01F00203E -:10CE3000381F002004ED00E0F8B541680A780F2A99 -:10CE400013D0082A1FD0062A1CD140894A1C0292FE -:10CE5000ADF80400B1F80900ADF80C00C87A8DF8FF -:10CE60000E0001A806F00AF98FBD40898A1CADF8B2 -:10CE7000040048780A31029203918DF8060001A857 -:10CE8000EFF7FEFD8FBD4089ADF804004878022819 -:10CE90008DF8060004BF881C029001A806F0D0F8A7 -:10CEA0008FBDB0B586B0044600202121CDE9000039 -:10CEB00002904FF48670ADF804002088ADF80000B1 -:10CEC000607A0028684608BF01218DF80210F2F749 -:10CED000D3F99DF8140098B90398456C062005F81D -:10CEE000010B616828460CF0BAFFA0782872E07840 -:10CEF0006872207AA872684605F086FB9DF81400D7 -:10CF0000217A002908BF084606B0B0BD89B36FF08A -:10CF1000C0020B0E02EA8112202B05D0212B05D076 -:10CF2000A02B05D1302118E0102116E0202114E0BB -:10CF3000B1F1807F01D240210FE0102B05D0112BE1 -:10CF400005D0402B05D1702107E0502105E060217C -:10CF500003E09021502B08BF8021114341F00F01C5 -:10CF600004C8531C18BF8A42FAD14FF0FF3140F871 -:10CF7000041C7047B0B51749174A00230978994235 -:10CF800006D002EBC3046488844203D00133F6E781 -:10CF90000C4600E0DCB24FF6FE73984208BF8C42AC -:10CFA00001D02046B0BD0024A14204D012F83400C4 -:10CFB00018B10134F8E70C46F3E702EBC405E4B21C -:10CFC00068686B800028ECD00CF09CFF0020686043 -:10CFD000E7E700BFD7BA0200503D002070B50468F3 -:10CFE000616F59B3D4F8582145685668E96B2868D1 -:10CFF0003268D16201210BF03DFED4F85801E96B93 -:10D000000F4A40680068C0F8041591FAA1F112684F -:10D010003068B1FA81F192699047616F091AE07C3A -:10D0200020B104F14C0007F00FF805E0206FA26F6B -:10D03000401A20675018A0670020606770BD00BFCD -:10D04000D40100101CB5002008F04CFF0CF00AFCC5 -:10D0500004460BF051FF01460F480023827820461A -:10D0600007F09AF8002008F03DFF0D4800780228EC -:10D0700010D10A48007801280CD16C4620460CF0EB -:10D0800014FE0CF0DDFB07490B7807490A782146AE -:10D0900002F012F81CBD00BF3E790020CA27002014 -:10D0A00024260020D0270020D22700202DE9FC4193 -:10D0B00014200CF029FF40B3044615484FF0000837 -:10D0C000002700F10806C82F1AD03078012814D1A3 -:10D0D000BDB20420002214230094294609F09EFAD0 -:10D0E00058B956E9020114222346C4E9000104207C -:10D0F000294609F0A9FA86F800800C360137E2E7E4 -:10D100002046BDE8FC410CF0FDBEBDE8FC8100BF3F -:10D11000F033002070B50CF06FFB164D2E78297897 -:10D12000012902D10CF023FE0EE0012129700CF040 -:10D130001EFE1148C168C968097829B980680021B4 -:10D14000D0F85824012090470CF030FF04460CF032 -:10D1500053FB04B92E700CF00AFE0748C168C96879 -:10D16000097829B980680021D0F858240020904718 -:10D17000204670BD262500200C010020F8B5174E72 -:10D18000154D044631682868496D88476040B0F104 -:10D19000FF3F07DC124FB868D0F8D40090F8830046 -:10D1A00001280BD10CF00EFD832808BFF8BD0C48F8 -:10D1B0008068D0F84C05BDE8F840004709F0AAF9AE -:10D1C0000CF000FD832803D0B868D0F84C058047E8 -:10D1D000BDE8F8400BF094BFE4260020347A00202C -:10D1E0000C01002010B5184C0021A068D0F8E80010 -:10D1F0000160A068D0F8D8100968B9B1D0F8E02073 -:10D2000049681268914211DA07F0FAF8A168D1F87A -:10D21000D82012685368834204DA5060A168D1F8BC -:10D22000D8000268D1F8E8000260A068D0F8DC10ED -:10D23000096841B1D0F8E80002681AB152684B6839 -:10D24000934200DA016010BD0C0100202DE9F04787 -:10D25000164C002100F12C03154D4FF0010A80F807 -:10D26000281084F848100ECBD4E91489A76D2E7DC0 -:10D27000C4E91503226585F814A0016340F2000C8F -:10D28000EFF311818CF31188D0E90532C1691046A2 -:10D2900098472020EFF3118180F311882E7584F8D0 -:10D2A00048A0C4E91489A765BDE8F087A01F002045 -:10D2B000381F00202DE9F843804615481549DFF84E -:10D2C00058900078002818BF012000240870E0B2B0 -:10D2D00039F83050CDB109EBC00047884668284680 -:10D2E000394632460CF0EAFB68B92846B8F1000F1F -:10D2F00004D0394632460CF0E7FB04E000213A4600 -:10D3000033460BF039FF0134E1E7BDE8F88300BF95 -:10D31000C2270020C87A0020FCA60200B0B58EB05B -:10D3200001AC0546342120460CF0F8FCD5F802008B -:10D3300029690022CDF80E00287D0B914FF6FF7170 -:10D34000ADF8001069468DF82000287F8DF809009F -:10D35000288DADF81400287E8DF80A00687E8DF8BF -:10D360000800688DADF8320095F82C008DF8340077 -:10D37000FF208DF802002046E9F782FB00200EB066 -:10D38000B0BD7CB5054600EB400014460E460230A9 -:10D390008DF8050001A809F0A3FB18B30169082264 -:10D3A00001F8022B05F01F02324301F8012C002284 -:10D3B000D3B2AB420ED2237801320B7063784B703C -:10D3C000E678A378043406F0070663F306168E7039 -:10D3D0000331EDE7012181764FF6FC71418001F0C8 -:10D3E0000BFB7CBD01207CBD2DE9F84304460820E1 -:10D3F0000CF08AFD20B305462078C61C022050FAA6 -:10D4000086F8404609F09AFF6860B0B1FE215FFAE5 -:10D4100086F9017021464A46686801300CF09AFD91 -:10D420006F684946781C0BF089FB57FA86F1487003 -:10D430000020A5F80280287003E028460CF062FD69 -:10D44000002520460AF058FE2846BDE8F8837047BC -:10D45000B0B5056804460CF0CFF9A97819B1BDE85C -:10D46000B0400CF084BC002169700CF080FC0E48C8 -:10D470008168B1F1FF3FDCBF4FF0FF3169600B49BC -:10D4800001602046FEF788FD287A022804D108486A -:10D49000BDE8B0400CF04ABD6B7AD5E904C26968BA -:10D4A0002046BDE8B0406047884702400300008046 -:10D4B000E87000201CB50C46097F052904D104F151 -:10D4C0000801FDF7FDFB18B304F108000DF106019A -:10D4D0000BF028F9BDF806004FF6FF71884204BF33 -:10D4E000A1201CBD217801290FD10A4A00EB40017F -:10D4F00002EB8101A26951F8043F9A423CBFA2208D -:10D500001CBDA082501C086000E0A08200201CBD51 -:10D51000C8201CBD307500202DE9F04385B01548AA -:10D52000154F00264FF0FF080DF104090024007884 -:10D5300000EBC0008500B54218D0B81990F8211052 -:10D54000802910D1B95980F8218010224B460191D1 -:10D5500041680291017D80698DF80C100490A1B2A0 -:10D56000032009F071F824360134E4E705B0BDE882 -:10D57000F08300BFE3BA020020450020F8B50D4853 -:10D580000D49FF220088097841430C480CF070FBDC -:10D590000B480C490C4A0D4B0D4C0E4D0E4E0F4FC7 -:10D5A000C1610021C0E90176C0E90354C0E9053238 -:10D5B0000170F8BD4EB20200DFBA020030790020DF -:10D5C000EC2300207548020095060200092702009E -:10D5D000051D02008DBB0100E163020011EF000098 -:10D5E00010B5154A212074210CF068FA0A38B0FAF7 -:10D5F00080F0440905F028F80A28104808BF0234D2 -:10D600000078012804D805F05FF80A2808BF043420 -:10D610000B48016819B188470A2808BF083406F08A -:10D6200039F80A2808BF103404F0A6F80A2808BF01 -:10D630002034204610BD00BFA86D00202426002005 -:10D64000FC230020B0B5134D0124E86B01680120D4 -:10D65000884701281BD028683C2101220023002490 -:10D66000C5680D48A84790B106F07EFC0B480C49F0 -:10D670000068D1E900238860C01A0A4BA2EB92022D -:10D680005843B2EB104F98BF020C01240A602046A9 -:10D69000B0BD00BFA401001000A00C403020094024 -:10D6A000F424002040420F002DE9F84305461548B8 -:10D6B000DFF854908846002400F1140699F8000021 -:10D6C000C1B28C4228BFBDE8F883FF2D08D156F8BF -:10D6D000107C0CF0FFF9874209D099F8000003E0B4 -:10D6E00016F8141CA94202D018360134E8E70CF0F1 -:10D6F0008CFA31680A6822EA08020A60BDE8F84339 -:10D700000CF071BB1C61002000260020B0B514484D -:10D71000144D807B95F83911084306D00CF06CF855 -:10D7200095F83B1121B10CF022FB00242046B0BD3E -:10D73000012485F83B410CF01AFB022007F0BCFFE6 -:10D740000D20F8F7CDFA084801680029EED1074905 -:10D7500040220A604A60002185F83A11C461E4E77A -:10D7600018B80200D81B002004800C4038500C4030 -:10D7700079B36FF0C0020B0E02EA8112202B05D0A4 -:10D78000212B05D0A02B05D1302118E0102116E067 -:10D79000202114E0B1F1807F01D240210FE0102B55 -:10D7A00005D0112B05D0402B05D1702107E0502169 -:10D7B00005E0602103E09021502B08BF8021114338 -:10D7C00041F00F0104C8531C18BF8A42FAD140F837 -:10D7D000041C70471CB51548017E022904D119208C -:10D7E000BDE81C400BF0AABD017E01291DD0007EC2 -:10D7F00004281AD00CF000F8044601A8F9F762FBDF -:10D8000028B101990A4831B10BF0E4F80AE0084860 -:10D810000CF0A7FA06E00CF0A4FA06480421283020 -:10D820000CF088FB20460CF0A2FA1CBDD01E002094 -:10D830007C71002070200020B0B54FF0FF300BF05D -:10D84000B5FD104D04461049E86988420DD10F48D6 -:10D850000F4900220BF03CFA0220287607F044FF23 -:10D8600018B9FAF773FAEAF71FFF0A48044208BF2B -:10D87000B0BD09484FF000512830BDE8B0400CF071 -:10D8800059BB00BFD01E002095370000302100207A -:10D89000F50C01000200004070200020F8B5174F81 -:10D8A00006460D46F88AB04201D1012405E0304613 -:10D8B00029460023FEF7C5FA04463046002103F04E -:10D8C00017FEF98A884216D128460021FCF756FB3C -:10D8D00068B1817911F0180F09D04388F98A00885E -:10D8E0004FF6FE720092002202F0C8FA03E02846CA -:10D8F000012109F0B7FC2046F8BD00BFA86D00204B -:10D900002DE9FF41144DD5E900673879F8F7E8F9BA -:10D910000BF072FF04463078B0B90DF104084046B0 -:10D920000BF004FDB87979790C4A434601950290D1 -:10D93000301D05F01BFC38684FF0FF31C16208490B -:10D94000816001213170416020460CF010FA0248DC -:10D9500004B0BDE8F08100BF34BA0200479C020069 -:10D960000018002010B5174B0C0A5B685970002195 -:10D970009C701970117801F01F01D97051781971DC -:10D9800091785971D17899711179D9715179197248 -:10D9900091795972D1799972117AD972517A197330 -:10D9A000917A5973D17A9973117B00F11102D9736D -:10D9B000811C104648F202021023BDE8104001F01D -:10D9C0008BBD00BF882600202DE9F04385B050B301 -:10D9D000144642B30DF104080E46054640F201100C -:10D9E00000211022002743460BF0C6FB06F00F066D -:10D9F0002046C6F1100908EB06014A460BF026FD49 -:10DA000004EB0900414632460BF020FD082F0AD0F6 -:10DA1000E85DE15D4840E119E0550A7AE85D0137CB -:10DA200050400872F2E705B0BDE8F083F8B50D4646 -:10DA300009881446074609F0A7F908B1B820F8BDCF -:10DA4000114806780BF04AF8B04224BFB220F8BD66 -:10DA500018200CF059FAA0B106460771002029469B -:10DA600012223060B01D0BF0F1FC0848016811B1C2 -:10DA700008460968FBE706600CB106F0E1FB0020F0 -:10DA8000F8BD1020F8BD00BFC9BA0200F82600207A -:10DA9000E0B51749FF238868426913764269D37E4F -:10DAA000012B16D10021D176C16BC97AC1B1FF21FA -:10DAB0008DF80710D0F8D41091F84320B1F8521027 -:10DAC000ADF80510D0F8D4138DF8042001A88847CC -:10DAD0008CBDD0F8D400427B90F82C00904200D14D -:10DAE0008CBDC868406C8047BDE88C4009F0E8BD3B -:10DAF0000C01002010B515480078022822D11248E8 -:10DB00000078F8B94FF6FF700021EDF7B3FE104C26 -:10DB1000012040F6B831A04708204FF4DC71A0473F -:10DB200010206421A04720206421A0474FF480509A -:10DB30004FF47A71A047074A35202821BDE81040EC -:10DB40000BF0C2BF10BD00BFE52700202426002037 -:10DB5000ED4701000875002070B5174A0546906929 -:10DB600010B30123147A137209BBE968426905F105 -:10DB70001406914202DAE968F7F78AFD3068B0428C -:10DB800013D06869016869614E60806828614169E5 -:10DB9000E9602021EFF3118581F31188294607F010 -:10DBA000E1FA85F3118802E070BD0120A8602046EB -:10DBB000BDE8704005F030BF38220020B0B58AB013 -:10DBC0001048C178D9B901250F492422C57001AC8C -:10DBD00020460CF0BFF94FF400708DF824500D4D25 -:10DBE0000D49224600230690084805900020049025 -:10DBF00007480190284609F007FA084845630AB02B -:10DC0000B0BD00BFA01F0020F0B50200F0580020FA -:10DC1000D2B60200986F0020959E020038220020A4 -:10DC200021F003010844009940F8083C40F80C2C0E -:10DC300040F8041C029940F8101C019940F8141C8B -:10DC40000F4940F8181C4FF0FF3140F81C1C40E908 -:10DC5000091140E90B1140E9131140E9111140E9A4 -:10DC60000F1140E90D1140F8781DC0E90911C0E914 -:10DC70000111C0E90311C0E90511C0E9071170479E -:10DC8000FD8B02002DE9F041077B04460D208846FC -:10DC900000EB4700C5B228460CF036F908B306463B -:10DCA0002078211D3070701C0CF0D9F8A07804F198 -:10DCB0000E013A467072E078B072607B3773F07292 -:10DCC00006F10D000AF002FE48F080002A463346B5 -:10DCD000C1B2452004F058FD3046BDE8F0410CF0DB -:10DCE00011B9BDE8F0812DE9F041D0F8A8501F46E8 -:10DCF00016468846044625B12046414632463B46F4 -:10DD0000A847D4E928010F40064056EA070008BF9B -:10DD1000BDE8F08120464146802204F003F9C4E9C1 -:10DD20002C6740B1D4F8A8108160D0E90812B14343 -:10DD3000BA43C0E908120020C4F8A80004F150005A -:10DD4000BDE8F0410CF0F2B870B520220D46044653 -:10DD50000BF07CFBA87C0026E661666160B14000A8 -:10DD60000CF0D2F8606130B1AA7C696952000BF006 -:10DD70006DFB002600E00126287E48B140000CF033 -:10DD8000C3F8E06128B12A7EE96952000BF05EFB1E -:10DD90004EB1606908B10CF0B5F8E06908B10CF05B -:10DDA000B1F8002070BD012070BD704770B5044609 -:10DDB00013480168F1B1114E3068D8B10E4D286892 -:10DDC000C0B160888847A8B90E48007830B10E49C4 -:10DDD00051F82000C0EB0010810001E00A48016802 -:10DDE000608832689047012804D160882968BDE8BE -:10DDF0007040084770BD00BF9C2300209423002082 -:10DE000088230020D727002090B402007FB50BF0B4 -:10DE1000F3FC114E04463078C8B901AD28460BF02A -:10DE200085FA00200E4A27212B468DF80C004FF072 -:10DE3000FF300290094805F099F90A4801210125AF -:10DE400009F09EFF0848002109F09AFF357020462E -:10DE50000BF08DFF7FBD00BFAA270020CC760020ED -:10DE600027E8010098700020E870002070B588B0A5 -:10DE7000134E0D460446C22096F8261004291CD0E5 -:10DE800008291AD086F82E50B46201A8182104304F -:10DE90000BF044FF02208DF80950019486F826000B -:10DEA00001208DF8080007480078022802D10648B2 -:10DEB0000021017001A800F085FE08B070BD00BF10 -:10DEC000A86D002024260020DC2700202DE9F84F33 -:10DED000DFF854B00646DBF8000010B30E20DDF882 -:10DEE00028801C4691460D4600EB430009F026FAB7 -:10DEF000B8B1074605714680D42049464FEA440A26 -:10DF00003870781D0BF0ABFF07F10E00414652460A -:10DF10007C730BF09BFADBF800103846BDE8F84F35 -:10DF20000847BDE8F88F00BF5C27002070B50446A5 -:10DF30008069A16A4D788E780BF010FF88B1017965 -:10DF4000013901290DD801210E2D14D89EB90021C7 -:10DF500001750C4935B151F82510C1EB011189004B -:10DF600001E070BD09680122C0E9061180F8202097 -:10DF700005F082FA002104480278A089BDE87040CB -:10DF800001F088BC90B40200DC27002070B5154E6B -:10DF900004464FF6FE713088884221D1162009F0E0 -:10DFA000CDF9E8B10546A0790221002808BF01217A -:10DFB000012069702870A06A4078A872000702D416 -:10DFC000A08903F0F9FCA169A81C0BF048FF002010 -:10DFD0002946E8740448007801F0C6F8A08930802A -:10DFE00070BD00BF802700209C7A0020F8B50D4648 -:10DFF00006460BF00AFE134F0446387808B1002598 -:10E000001BE0B5F5877F07D906F587703861A5F560 -:10E0100087704FF4877501E000203861B8800A48A6 -:10E0200031462A460BF096FF01203870786901309E -:10E030007861284606F06CFC054620460BF0D3FEBE -:10E040002846F8BD70240020A064002070B500238D -:10E05000B3EB113F1CBF052070BD03783F2B84BF7D -:10E06000092070BD44880026B6EB942F1CBF072002 -:10E0700070BD8588B6EB952F1CBF082070BD0A487F -:10E080000078032804BF032070BDD18196210020B1 -:10E090001372D480958091722103908141EA0361CB -:10E0A0002943116070BD00BF982700202DE9F0477B -:10E0B0008AB006468800994690460C1D00270DF14F -:10E0C000080A8DF80700200412D0A5B2B1B2484664 -:10E0D0005246202D28BF20252B460BF07FF9F8B2A1 -:10E0E00051462A460AF030FA07462E44641BEAE7F6 -:10E0F000F8B20DF1070101220AF026FAB0EB080090 -:10E1000018BF012040000AB0BDE8F0872DE9F843B0 -:10E1100005461448DFF8508089460321002400F1A9 -:10E120000C0798F80000C2B2944218D217F80C2CD1 -:10E13000AA4211D10BF069FDB968064638680A6831 -:10E1400042EA09020A6008B10BF0A1FD30460BF06B -:10E150004AFE98F80000002118370134E3E7C8B2FE -:10E16000BDE8F8831C610020002600207CB5154E18 -:10E170000446B07808B1012521E00DF10701E12046 -:10E1800008F0C0F89DF807000025A04217D0012034 -:10E19000B07001200BF0F2F90DF1060152208DF85C -:10E1A000065003F0F1FF204603F0C6F938B10648E7 -:10E1B00001216422047030780BF00CFEBA25284649 -:10E1C0007CBD00BFCC260020917A002080B513488A -:10E1D000007802280BD001280BD088B91148022101 -:10E1E00081700F48018821F00701018080BD022065 -:10E1F00000E001200A490A8822F007021044088042 -:10E2000009480AF0A5FF0028064819BF4FF44171DC -:10E21000A0F801100021817080BD00BF24260020DD -:10E220003E790020D0260020A679002070B5054652 -:10E23000807C0C2826BFA869C67A00260E2000EB39 -:10E2400046000BF061FE044618B1AD6928782070D5 -:10E2500008B1204670BD201D691C0BF000FEB5F80A -:10E26000090060800020002E2073F2D0E87A04F1CB -:10E270000E012073287B607305F10D003206E8D093 -:10E2800030F8022B013E21F8022BF7E7F8B5144DC8 -:10E29000044612484FF6FF762988B14202D111494F -:10E2A0000978298007684FB17868017821B1406802 -:10E2B0000178204604F028FE3F68F4E72888B04241 -:10E2C00003D0C1B2204604F01FFE0BF0CBFA064982 -:10E2D0000880BDE8F8400AF00FBE00BF247A002095 -:10E2E000862700209A7A0020887900202DE9FF41B6 -:10E2F000DFF84C80074613480D4616463946D8F8D5 -:10E30000044009F02AFB0F21002818BF0221002831 -:10E3100020468DF80C100C49098808BF6FF00201E7 -:10E32000ADF8041039460BF09AFD4670057001A94E -:10E33000404600220A2301F0CFF804B0BDE8F08186 -:10E3400088260020E0790020887900207FB5154ECE -:10E35000307828BB04208DF800001348C08AADF83F -:10E3600002000AF0C9FD6D4601462C1D20460BF047 -:10E3700034F92846F3F782FB0BF062FA4FF6FE7190 -:10E3800088420BD0BDF80210884207D0ADF80200D9 -:10E3900020460BF08AFC6846F3F770FB01203070D2 -:10E3A0007FBD00BFEC230020A86D002070B5154E86 -:10E3B00001211C461546F068C0680170F06880694C -:10E3C0000078022803D0B068D0F84C05804705F0EB -:10E3D000020004F0885140180AD00B480178013936 -:10E3E00001700021F0688069017009F07BF903E099 -:10E3F000B068D0F84C058047F0680021C068017013 -:10E4000070BD00BF0C01002029250020B0B5164CBE -:10E41000A06800F1D8030ECB1568D0F8E024186886 -:10E4200009684042904755B1A1686868D1F8E0108A -:10E4300009688842A4BF401A68602D68F3E7A068A5 -:10E44000D0E9381212680B68934207D00A60A068BE -:10E45000D0F8E000006809F057F9A068D0F8D404BB -:10E46000BDE8B040004700BF0C010020F8B50446ED -:10E470000020154F0D462060F868C068007828B964 -:10E48000B8680021D0F85824012090470BF0B4F967 -:10E490000646204629460AF089FC284601460068BF -:10E4A00018B1426863689342F8DA0C60206028680B -:10E4B000A04203D1B868D0F8D40480473046BDE804 -:10E4C000F8400BF054BC00BF0C01002070B5164E94 -:10E4D0000446F068C068007828B9B0680021D0F818 -:10E4E0005824012090470BF087F90546B068D0F812 -:10E4F000F824D0F8D8102046904730B9B068D0F84A -:10E50000DC10D0F8F82420469047B068D0F8E80036 -:10E510000068A04203D107F0E7FFF9F71DFE284687 -:10E52000BDE870400BF023BC0C01002010B515496C -:10E530006FF00B024AB18B180432DB898342F9D1A8 -:10E54000881800F10801C52016E06FF00B024FF6A5 -:10E55000FE732AB18C180432E4899C42F9D107E099 -:10E560006FF00B0262B18B1804321B7B002BF9D1C8 -:10E570001144488108310020034A12780A7010BD06 -:10E58000C72010BD4C790020DABA02001249134AA4 -:10E59000096892F82620002918BF0222D2B2062A62 -:10E5A00005D0052A07D10F49096899B108470C49D8 -:10E5B000096879B1084721B18979022904D0012974 -:10E5C00004D140780BF08EBCFDF754BB06490968B6 -:10E5D00001B10847704700BFD8260020A86D002071 -:10E5E0000C25002008250020782300202DE9F04785 -:10E5F000054615488A464FF0FF394FF00008046879 -:10E600006768BC421DD026462468307D0028F8D0BB -:10E610006DB1F06850450AD1306918B1306250448C -:10E62000F06001E086F81480D6E906108847307D56 -:10E630000028E6D0F068A0EB0A00484538BF8146C4 -:10E64000DFE74846BDE8F08708200020B0B5164A4D -:10E650000121147A11722022EFF3118582F31188BF -:10E66000024652F8143F93420FD0106803681360BB -:10E6700001745A60C16809B100220A758068294690 -:10E6800006F070FD85F3118808E0017CC90706BF1C -:10E69000418A01310121418285F311882046BDE87C -:10E6A000B04005F0B9B900BF3822002070B5144E53 -:10E6B0002021B06DEFF3118581F31188F16CF26DBB -:10E6C000B1FA81F1C1F11F0102EBC101814210D900 -:10E6D0000C480121047A01720B4809F049FD002021 -:10E6E00086F84800204685F31188BDE8704005F0A3 -:10E6F00093B9002086F8480085F3118870BD00BFEB -:10E70000A01F00203822002071040200B0B504468A -:10E71000C068256990F8381001F0030101290ED175 -:10E72000297C61B9416C0A78052A08D1497803220D -:10E73000062908BF0222012908BF02222A740021EB -:10E74000297090F84810A97090F842100069E9709B -:10E7500068600AF0D1FB014605F108000BF07FFB71 -:10E760002069F6F7A5F82075B0BD10B586B004464F -:10E7700000200121CDE9000002904FF48170ADF836 -:10E7800004002088ADF80000E0780128684608BF42 -:10E7900021218DF80210F0F76FFD9DF8140088B963 -:10E7A00003980921406C0170A1784170208805F020 -:10E7B000C3FA10B103980421C182684603F024FF14 -:10E7C0009DF8140006B010BDFEB5047C00F11C03DA -:10E7D000012201256CB11E78F70718BF16F00C0F47 -:10E7E00001D1002502E0760748BF00220833013C32 -:10E7F000F0E7037A0BB1002413E0012D18BF0129C3 -:10E80000F9D101248DF808204179827A0472C088F8 -:10E810008DF803108DF80420ADF8060068460AF064 -:10E8200011FB2046FEBDFEE70F280ED840F2025233 -:10E83000DFE800F014101210080D081010100D1071 -:10E840000810100D4FF2011208E01E2802D141F20B -:10E85000011203E0002201E04FF4817231B1FF297F -:10E8600007D14FF203101040C03008E042F03000F2 -:10E8700005E0C8070CBF42F0200042F01000000481 -:10E8800000F203707047704780B50C4908700C485F -:10E89000002101700B480C49008808800B480C4986 -:10E8A0000BF0DDFA0B480C4901600C480C4900786C -:10E8B0000870BDE8804007F057BB00BF997A002080 -:10E8C000987A00208827002096700020A6790020E2 -:10E8D000C0260020EC580020B8260020C4270020C5 -:10E8E000977A0020F8B5044613480025061D134802 -:10E8F00007783046394639B110F8242B013A022AFC -:10E9000038BF01350139F6E7280611D0E8B24000DA -:10E910000BF0FAFA60B1014667B13278013A012A88 -:10E920009CBF36F8042C21F8022B2436013FF3E774 -:10E93000002000252570F8BD20450020E3BA020024 -:10E9400070B50646807C0930C5B228460BF0DCFA6B -:10E9500018B30446B0782070F0786070307BA070F7 -:10E96000B07BE070F07B2071307C6071707CA071B6 -:10E97000307DE071707D207204F10900B27CB169D4 -:10E980000AF064FD4520FF212A46234603F0FCFEE1 -:10E990002046BDE870400BF0B5BA70BD70B50646B4 -:10E9A0008078032101EB4000C5B228460BF0ACFA99 -:10E9B00000B304463078207070786070B078A07032 -:10E9C000706870B1E11C0022B3789A4209D210F845 -:10E9D000023B013201F8023B10F8013C01F8013C16 -:10E9E000F2E74520C4212A46234603F0CDFE204607 -:10E9F0000BF088FA002070BDB0B50446144890F8BA -:10EA0000261004290AD0082908D0217801F0030132 -:10EA1000012908D121690978062904D161884FF6B6 -:10EA2000FE72914201D1C22508E0C08A814201D123 -:10EA3000207F40B12046E7F707FF054620460BF050 -:10EA400061FA2846B0BD2046FEF768FCF5E700BF36 -:10EA5000A86D002020291CBF6FF0010070477CB515 -:10EA600004464068114EA1684068098CC6E901015E -:10EA7000204600F031F988B9C72031898DF80700A8 -:10EA800020460AF096FB0DF10700012101F0FAF88B -:10EA90003189054620460AF095FB15B14FF0FF304D -:10EAA0007CBD204600F018F97CBD00BF0C2400207E -:10EAB0002DE9F04104461348DFF84C80002700267A -:10EAC00000F1080598F80000874217D215F8080CE5 -:10EAD000A04210D1284608F0E5FA0646286828B179 -:10EAE000F8B24FF40041FFF711FB04E0F8B24FF425 -:10EAF0000041FEF7D9FD18350137E3E73046BDE8A0 -:10EB0000F08100BF1C6100200026002070B5044683 -:10EB1000807861680A5C0D1802F0070262700A5C76 -:10EB200028460421C2F3C102227410F8016B07F0D9 -:10EB300025FE0521A061B006217704F1080004D468 -:10EB40000021C0E90011052005E0691D0BF087F9DF -:10EB5000207F08302077217C012904D1C1B2013007 -:10EB6000695C2077A17570BDF8B50646114801278C -:10EB700014460D4647700720F7F7B2F8022006F05A -:10EB80009BFD3120314609F03BFB0B48032100225D -:10EB90004160016821F0030165F3000165F3410163 -:10EBA0000160064821460068036800209847044831 -:10EBB0000760F8BD182300200C800240CC01001033 -:10EBC000A802504270B58AB000266C46054628213E -:10EBD000867120460BF0A2F804F1190005F10B0133 -:10EBE0000B220AF033FC28680B490860204629688C -:10EBF0000BF0F3F8A888ADF81360ADF81100D5F864 -:10EC00000700CDF8150005488068D0F87C14204630 -:10EC1000884700200AB070BD047A00200C01002053 -:10EC20001CB5154C10200DF106018DF80600A068EA -:10EC3000D0F830245A2090474FF4FA70ADF8040011 -:10EC4000A068D0F8302401A95520904707200DF185 -:10EC500003018DF80300A068D0F8302459209047B4 -:10EC600009200DF107018DF80700A068D0F83024C5 -:10EC7000E02090471CBD00BF0C01002010B51349D7 -:10EC80000446487808B1486A10B900204870086AFC -:10EC900009F030FF0E48006840B10E4800780128A6 -:10ECA00008BF002C0BD0642000210AE00CB1032027 -:10ECB00000E005200021BDE81040E5F79FBD64207D -:10ECC0000121BDE81040EFF769BF00BFAC22002072 -:10ECD00078270020242600202DE9F8430446144E0E -:10ECE00005200DF103080DF10209A5688DF8030058 -:10ECF000318920460AF05DFA4046012100F0C2FF4A -:10ED00004846012109F09CF83189074620460AF05F -:10ED100059FA4FB99DF80200C00705D0686A00286B -:10ED2000E6D00AF057FDE3E73846BDE8F88300BFB8 -:10ED30000C2400200E48007888B90E48007870B97D -:10ED40000D48007858B90D48007840B90C48007853 -:10ED500028B90C48007810B90B48007808B1002099 -:10ED600070470A480078B0FA80F04009704700BF49 -:10ED7000B07A0020B37A0020B87A0020AB7A002065 -:10ED8000B17A002026250020B32700202725002067 -:10ED900010B50446812804D310488068D0F84C058B -:10EDA00080470AF029FD0E490C700C498968D1F89A -:10EDB000B8100A780B4991F900101AB1002902D451 -:10EDC0000949097819B10AF0D2FF012010BD0AF0F3 -:10EDD000CEFFBDE81040F9F72BB900BF0C010020B1 -:10EDE00058260020B87A0020AB7A002080B50AF0BF -:10EDF00003FD134A0023117813708A070CD44907C6 -:10EE000019D50AF0B4FF0F4800218068D0F85824C3 -:10EE10000020BDE8804010470AF0A9FF0948C168FA -:10EE2000C968097829B980680021D0F858240120E0 -:10EE300090470AF0E1FCBDE880400AF098BF00BFAF -:10EE4000907A00200C0100202DE9F8430446134875 -:10EE50004FF6FE79124D09F1010806786FF00100B6 -:10EE6000013087B2BEB12888A0420DD1A81C09F09C -:10EE700025F968B965B128461C210AF04FFFA5F8AD -:10EE80000A80A5F8009003E0BC4201D14845EDD1CD -:10EE90001C35013EE6E7BDE8F88300BFD1BA0200A9 -:10EEA0003056002010B5044681680079FFF72EF92E -:10EEB000207B00B110BD20680AF053FF0E480168A6 -:10EEC0000246A14204D00A460969A142FBD1103290 -:10EED000216911600021216150F8041F21B1084609 -:10EEE00009690029FBD110300460044841680078AA -:10EEF000BDE81040FFF70AB9782600203826002028 -:10EF000010B51446AB2808D0A2280CD0A32812D0E4 -:10EF1000A12817D10F48008811E00B48016820464E -:10EF20000AF09DFF0CE0094802685AB108462146E4 -:10EF3000BDE8104010470648016819B18847208095 -:10EF4000002010BDB52010BDEC5800203424002056 -:10EF5000F423002096700020BFB50AF0FFFE90B1A8 -:10EF60000546408801242421FF228DF80040ADF899 -:10EF70000C0028460AF07CFE802085F821006846B7 -:10EF800005F05EFC00E000240020042104F02CFECB -:10EF900005490978884204D2044801210170F5F737 -:10EFA000E9FC204604B0B0BDE3BA02009727002078 -:10EFB000F8B50AF02AFE1349002200230025002498 -:10EFC000886048680668A6B1B6F1FF3F05DD5BB111 -:10EFD000176835443744176009E0AC4286F00046B4 -:10EFE00098BF2C46002302E00123024635463044F8 -:10EFF000E8E788680AF0F7FEA54288BF2C4620465D -:10F00000F8BD00BFD02500201CB501784478827877 -:10F01000FB298DF806408DF8072001D304200DE070 -:10F0200004F01F01152908D80C4A52F8211021B10B -:10F0300088478DF8050018B90EE001208DF805000D -:10F0400004F0E000202807D10DF105036020002125 -:10F05000032203F099FB1CBD1CBD00BFE021002072 -:10F06000B0B588B0134D0446286808B101201EE0F1 -:10F0700008200AF049FF2860C0B1216801602179A9 -:10F080000171B4F80510A0F8051001AD1821281D74 -:10F090000AF044FE2068019020798DF8090060791B -:10F0A0008DF808002846FFF78DFD00E0102008B01D -:10F0B000B0BD00BFD82600202DE9F84380460320CC -:10F0C0001E46144689468DF80100684607F008FD83 -:10F0D0000125B0B1074600690B21867044700170AC -:10F0E000BD7709F009FF084800217D77BD76A7F8B4 -:10F0F0000280C7E90890054801703846FFF77CFC9C -:10F1000005462846BDE8F883E0790020A7270020BF -:10F11000B0B50C480C490D4AC0E904210C490978E6 -:10F12000C90702D1816951B9B0BD0A4A0D490C4DD8 -:10F13000094B0A4CC0E90615C0E908438262BDE8E4 -:10F14000B04008477423002029780200614F010075 -:10F15000DC270020E1340100D1130200DD9801001A -:10F1600095C90100217C0200F8B511B3044612488C -:10F170000D46A0F11001114800780130013804BF9C -:10F180000320F8BD01F11806097CA1423146F5D1F2 -:10F190000AF03BFD07463046294607F019FD204698 -:10F1A0004FF40041FEF7B2FF38460AF01CFE002083 -:10F1B000F8BD0520F8BD00BF1C610020002600201E -:10F1C000B0B5124949684A68D2E90115D46860B1FE -:10F1D00055EA040005D00E480022C2610D4A5032A3 -:10F1E000026021B1F5F7C5FB01E001B1884755EA9E -:10F1F000040008BFB0BD09F0A7FE05B1A84704B1DF -:10F20000A0470448BDE8B04008F0AABCD01E0020CA -:10F21000001004400100070670B58AB01C46154670 -:10F2200002460B46002006AE102805D0295C81F06E -:10F23000360131540130F7E7304601210094EAF7F6 -:10F24000EDFC02A8214610220AF000F90020102847 -:10F2500005D0295C81F05C0131540130F7E700945E -:10F2600006A802AA01218023EAF7D8FC0AB070BDE3 -:10F2700070B50AF0C1FA104E04463078B0B90F4D9F -:10F280000F4A31210023284603F070FF05F11C00CE -:10F2900006F110010422082309F0B8FF094A4FF0D3 -:10F2A000FF3001210125FFF75FFC35702046BDE8E6 -:10F2B00070400AF05CBD00BF1823002074220020BB -:10F2C000CDE5000080A9030080B51248007805282C -:10F2D0001BD109F083F8062008F062FD0E48007883 -:10F2E00001280AD80D48008800F00700022804D041 -:10F2F0000020002100220AF051F804F0BDF8FAF7CE -:10F3000007F8BDE88040FDF79DBEBDE8804004F0F1 -:10F31000B3B800BFD0260020242600203E7900206C -:10F320007CB5856904460421284607F027FA0E4B70 -:10F3300029796A7902250126009040F20110ADF882 -:10F34000050068461D72094D8DF804102E70084D99 -:10F350002A70627C074D2A7062881A80FFF780FE4F -:10F3600008B108F0DDFB7CBD9C790020BB270020A4 -:10F37000C77A0020C67A0020F8B5144F1446054617 -:10F38000069A079E8DF8031078680370130AC670FA -:10F390004270837036B10899043032460AF056F84C -:10F3A000301D00E0042048F20601C3B20DF1030055 -:10F3B0002A46691AB1FA81F149090901B970214651 -:10F3C00000F08AF80021B970F8BD00BF882600203F -:10F3D0001FB504461348406842700170207A0F2818 -:10F3E00001D0022814D120884FF6FC71401A03285E -:10F3F0000ED802280CD002208DF80C000AF032FA48 -:10F40000ADF80400074801A93622022300F064F891 -:10F41000044821463622022304B0BDE8104000F023 -:10F420005BB800BF8826002070B586B00C46134933 -:10F430000546114800780978084301D1012019E0F8 -:10F44000BDB1B4B1284601F0F7FB064605F1100046 -:10F450000AF056FD86420CD102AE002000212A4659 -:10F4600090230096EAF7DAFB30462146F3F7C6F917 -:10F4700000E0022006B070BDBC270020242600203A -:10F480002DE9F047DDE90897DDF828A080461C4605 -:10F4900015460E463846C4B1B84208D140463146FA -:10F4A0004A463B46FBF79AFA0146002071B919F823 -:10F4B00000102A78BAF1000F18BF11408A4207D114 -:10F4C00001350136013C0130E5E70020BDE8F08759 -:10F4D0006FF00600BDE8F08770B588B004460020E4 -:10F4E0000F260133CDF81A00ADF81E00CDF8160036 -:10F4F000087A8DF81C0008880B49ADF814002078B4 -:10F500004D6805F8010D88780331CDE900510749B0 -:10F51000CDE9020605A8E8F7F1F910B92178013123 -:10F52000217008B070BD00BF8826002094250020FF -:10F5300010B50446812804D30F488068D0F84C05E4 -:10F5400080470AF059F90D490C700B498968D1F8C8 -:10F55000B8100A780A4991F900101AB1002902D4AA -:10F560000849097811B10AF002FC03E00AF0FFFB38 -:10F57000F9F710F9012010BD0C01002058260020D9 -:10F58000B87A0020AB7A002010B5114CA068D0F8F2 -:10F590005C028047B8B10F4900222223CA814A7514 -:10F5A0000D4A4B8212780A75A268D2F8D42092F8DC -:10F5B000243092F831200A74084A4B741278504370 -:10F5C0008000C86110BD1C20BDE81040F3F7A4B84E -:10F5D0000C010020B8750020B97A0020B47A002010 -:10F5E000B0B511488068D0F81814D0F8D40090F85D -:10F5F0005300884740F63875042808BF43F66C4529 -:10F600000AF003FB04460948007845430AF04CFC25 -:10F61000B5FBF0F00649074B0022FAF76FFC2046D5 -:10F62000BDE8B0400AF0DFBB0C010020B47A002036 -:10F63000E17E02002C2700202DE9F8438146124884 -:10F64000884600240025861C10480778BC4218D242 -:10F65000280616D1304608F031FD70B136F8020C9C -:10F66000002541464845304608BF0A2508F075F98F -:10F67000002818BF65F05F0500E000251C36013446 -:10F68000E4E7E8B2BDE8F88330560020D1BA0200C2 -:10F69000BCB50D46134904464089097839B1104973 -:10F6A000C98A884203D1BDE8BC4000F0EFB900210F -:10F6B000FAF764FC60B1807910F0180F08D02B8D38 -:10F6C000627F6189A0896C8E009400F0D7FBBCBD7D -:10F6D0006189A089002202B0BDE8B040FEF7DEB823 -:10F6E000A86D0020CD27002000B5EFF3038212F0B3 -:10F6F000FF0F0DD06A46A2F1200282F309886FF055 -:10F70000020E10604FF08071D1610B49916170471A -:10F710005DF804EB694681F3098880F308884FF0AF -:10F720000200EFF3148180F314880448016821F08B -:10F7300040410160704700BF10F7010034EF00E066 -:10F74000F8B50E4604460AF057F80546D4E901011B -:10F75000814205D128460AF00AFB4FF0FF30F8BD80 -:10F76000E3682168A2690133B3FBF0F707FB1037A8 -:10F7700002FB071031460AF0EDFBA0686169E76003 -:10F7800001308842A06088BF0146284661610AF0C6 -:10F79000EEFAA068F8BD70B5054600780C4616462E -:10F7A0000822087068784870A97840EA01106070F3 -:10F7B000E878A070297940EA8100A070697940EA70 -:10F7C000C100A070A97940EAC110E91DA070E01C39 -:10F7D00009F03CFE04F10B0005F10F01032209F0D2 -:10F7E00035FE0F2E24BFA87CA07370BD70B50668CF -:10F7F0000D4604460AF000F80F490978012901D1A5 -:10F80000317819B10AF0B3FA002413E00121317004 -:10F810000AF0ADFA0948002D18BF28460178426861 -:10F820003172326102290CBF80680020F0600A202A -:10F83000F6F756FA204670BDA8270020C4B802008B -:10F840002DE9FF41124C00254FF0FF360DF1040861 -:10F850000027208881B28F4228BFBDE8FF81616800 -:10F860004A57B2F1FF3F0FDC4B19D0B210F07F00C6 -:10F87000187003D143460396CDE90166B9B2012061 -:10F880000C2206F0E1FE20880C350137E2E700BFCC -:10F8900040260020FEB50446032017460E468DF88C -:10F8A000090002A807F01CF905460120C5B1296925 -:10F8B0000C228F704E700A70A87709F01DFB094862 -:10F8C0006E4631466862204606F026FA10B10120E5 -:10F8D0002E62687701206C80A8762846FFF78CF8A6 -:10F8E000FEBD00BFE0790020F8B5124D04460026A9 -:10F8F00029880844B0F5877F0AD90F48C1F5877772 -:10F900000844B9B203F040FD2E80E41B00213E46BE -:10F9100009480844A1B203F037FD28884FF48772E4 -:10F92000204481B2B1FBF2F101FB120028803019B2 -:10F9300080B2F8BDC826002084620020F8B5114FBF -:10F940000546786808B1804780B1B868FAF7D6FDF7 -:10F9500004460D4806787EB90C48C088C0F50050B2 -:10F9600000B2A84204DB1DB1042605E00B2607E027 -:10F970000020E2F72BFC3E78B8682146FEF7ECF851 -:10F980003046F8BDA023002098270020B872002040 -:10F99000F0B589B0ADF82010079007A802AA0021A1 -:10F9A0000024FEF753FBB0B90C4FB868FAF7A6FD78 -:10F9B00005460B4800940323C188C07802AAEAF7E1 -:10F9C0001BFE0646B868BDF816702946FEF7C4F857 -:10F9D000002E08BF3C46204609B0F0BDA023002001 -:10F9E000B872002070B50D4606460AF00EF90446BE -:10F9F0003046294608F034FAB0B1054600680AF0EE -:10FA0000B0F9286809F0E0FE0A490868854204D088 -:10FA100001460069A842FBD11031286908602846D8 -:10FA20000AF070FA002500E0022520460AF0DBF912 -:10FA3000284670BD7826002010B509F0DDFE0F4C79 -:10FA4000217E022902D0217E042904D10E490C68AE -:10FA50000AF08DF910E00AF08AF909480068006B95 -:10FA60008047084AA0FB020301FB023110F19050CD -:10FA700041F17A00E16C0C18204610BDD01E002028 -:10FA80008C01001000093D000430044010B50F4CFB -:10FA90004FF48051207803F095FC18B10C480121F7 -:10FAA000017010BD0B4802780B480178012918BF7E -:10FAB00003210020EEF74AFF084920780A884FF416 -:10FAC0008051BDE810400AF085B900BF9C7A002043 -:10FAD000E8250020CF270020CE27002096BA02007C -:10FAE00010B5134C206808B3C16C11B10AF060F96D -:10FAF0002068416C11B10AF05BF92068416911B1CD -:10FB00000AF056F92068C16911B10AF051F920686C -:10FB1000416B11B10AF04CF92068C16B11B10AF0C8 -:10FB200047F920680AF0EEF90020206010BD00BF00 -:10FB300044270020BFB501AD0446AB2000212A4672 -:10FB4000FFF7DEF909F0D8F90146284607F005FF6E -:10FB500088B101A9204606F0DFF850B101A803A939 -:10FB600007F01EFD50B101A80DF1020106F05AFE8A -:10FB700008B1002000E0012004B0B0BD0398007976 -:10FB8000002818BF0120F7E72DE9F04186B01248A0 -:10FB90000DF104080027002508F102040678B9B227 -:10FBA000B14214D2082000221423CDF8008006F0C0 -:10FBB00035FD50B99DF80400FF2806D021460022EB -:10FBC000FDF734FF002808BF01350137E7E7A8B289 -:10FBD00006B0BDE8F08100BFC9BA02007CB504469A -:10FBE000032008F0DDF8A07905F00EFE0E4D208907 -:10FBF000E67A2188A278AB78CDE9000604F10C0002 -:10FC0000F3F7D8FC044660B9A878000704D4074885 -:10FC1000007830B9082001E04FF400400121EBF7F3 -:10FC200029FE20467CBD00BF3E790020D226002060 -:10FC3000BCB5114C206970B1104901258D70FFF7DA -:10FC4000CDFFB8B120698DF8075004F031FB0C48A6 -:10FC50000DF1070107E0094800218DF806108170B9 -:10FC600007480DF1060100780091032101220123CC -:10FC700003F0C7F9BCBD00BFAC2200200C7A002005 -:10FC8000A37A002010B588B00C460021049140B141 -:10FC9000CDE902400F48406802A90AF0BFF80138D8 -:10FCA00015E00DF1070003900120029008788DF80F -:10FCB00007000848406802A90AF0B0F818B1013CF2 -:10FCC00004D00120E4E74FF0FF3000E0002008B04E -:10FCD00010BD00BF0C240020B0B50C46054609F04D -:10FCE0008BFD0F490A78862A10D187220A700D49A8 -:10FCF000CA890132CA810AF03AF80B480078A84252 -:10FD000008D1002C14BF1B20002004E0BDE8B04047 -:10FD10000AF02DB8E920BDE8B040F2F7FDBC00BF05 -:10FD2000B87A00205C780020C57A0020F0B5059EE6 -:10FD300000244FF6FF7C0027B44220D21D88654581 -:10FD40001AD017B13F88874201D2854204D81D1DC1 -:10FD50001F4601342B46EFE71F46B44205D23D88CB -:10FD6000654502D001340437F7E73C4654F8045D9A -:10FD70003D609C422746F8D8D9709A701880F0BD33 -:10FD8000B0B5054600781446E91C1070687800F09C -:10FD90000F005070687800099070A87800F0030098 -:10FDA000D070A878C0F380001071A878C0F3C300A9 -:10FDB0005071A878C0099071D01D082209F046FB47 -:10FDC00004F10F0005F10B01032209F03FFBA87BB2 -:10FDD000A074B0BD10B550B1014650F80C0C18B964 -:10FDE00011F8020CFF2804D0084608F085F9052018 -:10FDF00010BD0A4C207801F8020C09480278094825 -:10FE000002F042FD01281CBF042010BD20784FF4F1 -:10FE10000051FEF77BF9002010BD00BF9C7A002046 -:10FE2000D0BA0200482700202DE9F041124F0E46BB -:10FE30003968F1B115460A69DAB18A6A00041C46CC -:10FE400000F101081AB140463146904700E0002019 -:10FE5000A84204BF0020BDE8F081386831462A4638 -:10FE6000234607694046B847012804BF0A20BDE879 -:10FE7000F0810920BDE8F081682700202DE9F041DC -:10FE80000C4605463AB1284621460B220023BDE820 -:10FE9000F041FBF7D6BFDDF81880204600211E4652 -:10FEA000FAF76CF860B107468079C00708D0404681 -:10FEB00031462A46ECF73AFD4FF6FE71884201D1F1 -:10FEC000BDE8F0817880204629460C22DEE71FB588 -:10FED000014604208DF80000087A01280AD0032882 -:10FEE0000AD0022814D10888ADF802006846F9F754 -:10FEF000BBF808E008880DE06C46201D09F06DFB9A -:10FF00002046FBF7C5FB38B96846F1F7B7FD03E0BB -:10FF10004FF6FE70ADF80C00BDF80C0004B010BD3B -:10FF2000B0B505464068007D1030C0B207F006FA53 -:10FF3000D0B16B680446A87829881D781A7D618144 -:10FF4000207304F110006060C5F3401522726572E1 -:10FF500002252580196909F079FA044821460078BC -:10FF6000BDE8B040FFF700B9B0BD00BF997A0020EE -:10FF700070B5064600204FF6FE713446B0607180C1 -:10FF800044F8040F304606F01FFD0546012812D143 -:10FF90000A48B189406801EB410100EB81004188CA -:10FFA0007180061D304608F089F8012803D12046EB -:10FFB000314609F012FB284670BD00BF40260020E4 -:10FFC0002DE9FF4110486C464FF00108251D861CA5 -:10FFD0000E480778AFB1B078013803280ED8F07812 -:10FFE00000070BD430888DF80080ADF80C00204657 -:10FFF000FFF7BEFF10B12846FEF7AEFF2436013FE3 -:020000022000DC -:10000000E8E7BDE8FF8100BF20450020E3BA020019 -:10001000B0B505F0E9F90E4C0E4D1420611CA8474F -:100020000A202146A84709202146A8470A49082056 -:10003000A847B92000F06BFA084C1420A0470A200A -:10004000A0470920A04708202146BDE8B040084746 -:1000500000640020699D020002200020313102006E -:100060002DE9F04107460E465818B968496888429C -:1000700084BF6FF00300BDE8F081DFF830804FF0FF -:10008000FF311C461546D8F8000009F0D7FD384668 -:1000900031462A462346FAF7A1FC0446D8F8000068 -:1000A00009F044FF2046BDE8F08100BF0C24002089 -:1000B00010B504281CD10F4809F0FCFEC0B109F0AE -:1000C000F3FE04460B4809F0F3FE604380084A281B -:1000D0000ED8084809F045FE052005F0EDFA06485F -:1000E000012180F8251005480421283009F022FF5D -:1000F000002010BD7C710020D01E00207020002048 -:10010000BCB504460DF10702002001213A2308F096 -:1001100093F84FF6FF75B8B99DF80700A04212D0CA -:100120000DF10602002001213B2308F085F858B9A3 -:100130009DF80600A04207D19DF80700A04205D215 -:100140002046F6F75FFF3A252846BCBD3B25FBE776 -:1001500070B588B0054680690488104800888442DC -:1001600007D103AB812000211122002609F004F8F9 -:1001700058B1297C687C48F211022346CDE9002160 -:10018000A91C842206F088FD06E0687C0096A91C64 -:1001900003AB224602F078FC08B070BD88790020DD -:1001A000E0B500218DF8071050B110480DF107019E -:1001B0000022012300780091032102F022FF8CBD70 -:1001C0000949487850B1086A40B100224A7008F0E5 -:1001D00091FC3220BDE88C4008F02CBC03200021AB -:1001E000BDE88C40E4F70ABBAC220020A37A0020D3 -:1001F000862806D1114801880520142908BF04204B -:10020000704701467F30C0B203283CBF04207047CE -:100210000120012911D080290FD003290DD00229F6 -:1002200004BF0220704701F0FE00842804BF0320B1 -:1002300070470020882908BF0320704784270020CA -:10024000E0B58DF807000D480DF10701C0680069A1 -:10025000007805F011FC0B490948096800680A6E2E -:100260009DF9071090470146074A6FF39F5191424D -:100270000EBF4FF0FF30054948608CBD0C010020D7 -:100280006C7A0020347A0020FFFF3F0058260020BF -:1002900010B509F0B1FA0D49097819B1BDE810405F -:1002A00009F065BD0A4991F900100029F6D4094901 -:1002B00009780029F2D10849084C4968216009F001 -:1002C00056FD2068BDE81040FCF758BFB37A002007 -:1002D000B87A0020AB7A0020582600202C7A002023 -:1002E000B0B5104CA068016C096811B9D0F84C0584 -:1002F00080470D4D286808F035F9A168096C096838 -:10030000C860286807F0CCFDA168096C09680882FC -:100310000648007828B109F0C9FDA168096C096890 -:10032000C860B0BD0C010020487A0020942700204E -:100330002DE9FC4106464FF0FF300D469046CDE9D1 -:1003400000006846314607F008FB07460B48046882 -:1003500084B11FB12088A84206D008E004F10C0047 -:10036000314607F0FAFA10B1A078404502D004F106 -:100370001800ECE72046BDE8FC8100BFE8790020CA -:1003800010B5114CA068D0F8AC00007808B900F0A6 -:1003900083FDFFF77DFFA068D0F8B800007818B1A2 -:1003A0000A48016801208847F8F78CFDA068D0F85A -:1003B000B8100A783AB1496929B1D0F82813102049 -:1003C000BDE81040084710BD0C0100203027002078 -:1003D000B0B5A0B00E4D0446012085F83000686B22 -:1003E00008B902A868632046F2F738FF03200B4AD9 -:1003F000287508480068A16BC3B2074800910F2B0D -:1004000038BF02460020002104F0C6FE20B0B0BD77 -:10041000381F002004ED00E050AB0200C3AC020026 -:10042000F0B52022EFF3118182F3118890F8282093 -:1004300012B181F31188F0BD0C4A012492F84830C2 -:1004400082F84840466B456A7768066047603860C6 -:1004500080F82840D46C2C43D464706081F31188F8 -:1004600003B1F0BDBDE8F040FEF720B9A01F0020A9 -:10047000B0B5124CD4E91651E06CB0FA80F0C0F17E -:100480001F0001EBC001086802680A6051600A6839 -:100490008A4204D1416AE26C22EA0101E164FCF77C -:1004A000D5FEE06C40B1E16DB0FA80F0C0F11F0004 -:1004B00001EBC001A942E6D8B0BD00BFA01F0020DB -:1004C000F8B50646C86860B110F00F0009D137686A -:1004D00014460D4609F090F997F8251021B109F05E -:1004E00046FC4FF0FF30F8BD012187F8251009F0D8 -:1004F0003EFC296807F10C0C91E88D0029468CE838 -:100500008D0030462246BDE8F840E9F707BEB0B599 -:1005100004461420002108F0F9FE07250A200021D6 -:1005200008F0F4FE681C0FD024FA05F000F0010179 -:10053000092008F0EBFE0A20012108F0E7FE082060 -:1005400009F01EFC013DE9E71420012108F0DEFE60 -:100550004FF42F70BDE8B04009F012BC2DE9F04116 -:100560000F460646C189808998461446727A337CC4 -:10057000451AA8B2FDF79AFD08B1BDE8F081E91966 -:10058000B28914FA81F0904206D9F1890620A1427D -:1005900038BF0520BDE8F081307C89B24246234651 -:1005A00008F01CFF0020BDE8F0817CB540EAC100E6 -:1005B0000D46164640EA4211069800F8011B1946FE -:1005C00009F00BFC044636B108F096FC01462046C3 -:1005D00009F045FC0834012D0DD10DF10702002072 -:1005E00001213A23002507F027FE9DF80710002877 -:1005F00018BF294621707CBD7CB515460DF1060259 -:100600000C4605F03DFE08B101207CBDBDF806603A -:100610006946304605F088F9009858B120462946C9 -:10062000F9F76CFB2046012108F0DEFCFCF762FBC9 -:1006300000207CBD684602F0D3FF08B111207CBDCC -:1006400000980680EAE7704710B50E480078012848 -:1006500016D10D4805F030FB0C4C204607F0B0FCDD -:100660000B48046106F0ECF940F2000CEFF3118046 -:100670008CF3118809F011FCBDE81040FBF7D4BFE2 -:1006800009F096F8A01F0020C11C0200B0760020DF -:10069000381F00202DE9FC410E48104F00264FF076 -:1006A000000805780C480488B5420FD0B1B202208A -:1006B00000222346009705F0B1FF20B93878FF28C3 -:1006C00018BF08F101080E370136EDE71FFA88F070 -:1006D000BDE8FC81DFBA02004EB202003079002092 -:1006E000B0B5054609F088F8044605F013FF0D483B -:1006F000012D06D1012101700B48008B40F0200034 -:1007000007E000210170407828B90748008B20F0ED -:10071000200005490883204609F029FBBDE8B040C8 -:1007200008F0EEBC7C27002000720020E0B50E48E7 -:100730000122018B41F0550101830C49C9684969C7 -:100740000A70018B807EADF8021042F202018DF832 -:1007500004000748ADF800100649006809684A6AB5 -:10076000694690478CBD00BF007200200C0100203C -:10077000E4260020347A0020B0B504460F48007803 -:10078000012815D80E48807B800711D5A07A012852 -:100790000ED0258809F054F8854209D0E07A012866 -:1007A00006D0208808F04AF810B1208801F004F93A -:1007B0002046BDE8B040F7F7A7BB00BF24260020C5 -:1007C000A86D002010B5104C607890B10121217007 -:1007D00008F060F96078FF2810D0002161704FF4B4 -:1007E0007A7100FB01F209488021007809F0F2FAE1 -:1007F00004E000202070002008F04CF9024941205C -:10080000BDE8104001F0C0BC042500209C7A002007 -:100810000E480F4A0F4B0168825800680340D0B25F -:100820000D4A7F2888BF0020934207D1090F022973 -:1008300006D307D0032901D1153004E0FF2002E0E0 -:100840000A2000E00B3040B2704700BF1813005080 -:1008500088FDFFFF00F0FF0F0010B40BB0B5044699 -:10086000481D85B22046294608F09AFC00F0FD029A -:100870002046294607F026FD0A4904EB440001EB17 -:10088000800515F8190F58B12046022108F088FCA0 -:1008900000F0FC022046022107F014FD0020287021 -:1008A000B0BD00BFB8720020B0B510484FF4705111 -:1008B0000F4D006801EA80204142C5E90101012095 -:1008C00006F014FE044608F097FF296839B109F0D4 -:1008D0004EFA4CB12046BDE8B04009F05FB82C603C -:1008E000BDE8B04009F043BAB0BD00BF30240340BA -:1008F000DC2500202DE9F04187680E461944786810 -:10090000814284BF6FF00300BDE8F081DFF82C80E6 -:100910004FF0FF311C461546D8F8000009F08EF95B -:10092000386822468119284609F014FBD8F80000DF -:1009300009F0FCFA0020BDE8F08100BFDC250020B2 -:1009400070B505460F480C46A0F1100609F05DF998 -:100950000D490978013101390ED0337C06F11802B6 -:100960001646AB42F7D104E02978A14205D0A5F1A3 -:100970000C021568002DF7D1002509F034FA28463D -:1009800070BD00BF1C6100200026002080B50D480E -:1009900001420CD0012008F0D7FF012808D10B48F4 -:1009A00000210C4AC1610A49CA613C31016080BD25 -:1009B00009F07AFA3221B1FBF0F10348BDE880403A -:1009C00008F008B8040000207C71002000100440EA -:1009D000D01E00209537000070B50E46044608F082 -:1009E0000BFF0546A068B8B120682169A26901FB28 -:1009F0000201304609F0AEFAD4E901012269013959 -:100A0000A160511CB1FBF0F202FB101020612846DE -:100A100009F0ADF9A06870BD284609F0A8F94FF0BB -:100A2000FF3070BD10B50F4C32200021012223464B -:100A300008F0A2FB0C4B33200021012208F09CFBA4 -:100A40000A4821780078012906D14FF40061642218 -:100A5000BDE8104009F0BEB94FF40061BDE8104098 -:100A6000FEF7C0BFCD270020CC2700209C7A0020B5 -:100A700070B504460F48056802F0FEFC0E481021D0 -:100A80000078FDF743FBD62685B16868007858B139 -:100A9000042006F053FC38B10146448006706868B3 -:100AA00040680078FEF760FB2D68EDE7BDE8704018 -:100AB000FCF7C8BA247A00209D7A0020B0B504461D -:100AC00008F01AFAA51C0146284606F046FF50B168 -:100AD0000C48416911B12046884780B9E07ABDE8E9 -:100AE000B040F7F77DB906480078012807D8A27A08 -:100AF000E37A20882946BDE8B040F1F7D3BBB0BD0A -:100B00002426002054750020F8B5114E0D460446E9 -:100B100031680F4659B108460979A14204D1C1880C -:100B2000A94204BF0020F8BD01680746F2E708208B -:100B300009F0EAF950B1014600200860CD800C713F -:100B40003268002A08BF37463960F8BD1020F8BD6A -:100B50007427002070B5114D134604460E0A13F891 -:100B6000012B6868102A01704FF020314670C0F8E0 -:100B70000710C0F80B10C0F80F1028BF10228270A9 -:100B800040F8031F194608F061FC2846214614224C -:100B90001323BDE87040FEF79FBC00BF88260020ED -:100BA000B0B586B0054600206C4618212872204654 -:100BB00009F0B4F8204629460B2208F047FC04F15E -:100BC0000B0005F10B01082208F040FCA88AADF8E3 -:100BD0001400A87D8DF8160003488068D0F81C1218 -:100BE0002046884706B0B0BD0C01002010B5427BFE -:100BF000042A01D1027C0AB1002010BD40690028FE -:100C0000FAD002789207F7D14A68437B547DA34219 -:100C1000F2D1098843898B42EED1D18883888B42F7 -:100C2000EAD191788078884204D0107800F00C00E6 -:100C30000428E1D1012010BDF8B504464FF6FF7637 -:100C4000002541F221070F2D14D82078082106F045 -:100C500062FE802159B10142324618BFD2431204CC -:100C600087EA460258BF720049081646F2E7013586 -:100C70000134E8E7B0B2102106F04DFE4FF6FF71E7 -:100C80004840F8BD70B5114E04460822A51CF06816 -:100C90002946023007F024FB18B156F80C0F044621 -:100CA0000CE00C36366886B156F80C0F294608223F -:100CB000023007F015FB0028F4D03068C0683060BF -:100CC0002046BDE8704009F01DB970BDAC2200207F -:100CD000E0B50023CDE9003361B10F4A0428137059 -:100CE00008D8DFE800F0030B09131100BDE88C40C1 -:100CF00000F072BA02208CBD012010706A460846CE -:100D00001146FEF791FB8CBD012010706A46084623 -:100D10001146F1F773FD8CBDA42700201FB54FF6D7 -:100D2000FE7188421AD00E4900234A1C0D490978E9 -:100D300099420BD014781CB9B2F80140844202D019 -:100D40000E320133F4E7DAB2914207D1ADF80C006C -:100D500004208DF80000684603F072FD1FBD00BF3F -:100D600030790020DFBA02007FB5D0E90154204677 -:100D700006F0D1F92068416821F002014160416923 -:100D800021F00F0141610321016202A808F0AEFACF -:100D9000074995F8F93095F8FA202068D5E93965C2 -:100DA00009680C680399CDE90065A0477FBD00BFC5 -:100DB000C401001010B508F01FFD0C49097869B98D -:100DC0000B49097851B90B49097839B90A490978A9 -:100DD00021B90A49097811F0FD0F04D0002408F068 -:100DE000C6FF204610BD0124F9E700BFB07A0020FD -:100DF000B37A0020B87A0020AB7A0020B17A0020C4 -:100E0000F0B589B00F4C2068A8B1002001ADC6B282 -:100E10001F2E0DD8AF1903F0FBF80021202905D0B3 -:100E200020FA01F2083107F8012BF7E7301DEEE751 -:100E3000216801A888470448018B41F0040101831F -:100E400009B0F0BD5827002000720020FEB50F4DFC -:100E50000446E8688069007800B1FEBD0D4F0C4E75 -:100E6000396830684B6C01AA022198479DF804004C -:100E70000028F2D00CB901F0CBF9E86801218069B3 -:100E8000017039683068C9698847FEBD0C010020CF -:100E9000E4260020347A002010B508F0ADFC0446AA -:100EA0000C48007820B12046BDE8104008F05FBF34 -:100EB000094890F900000028F5D4084890F900008E -:100EC0000028F0D4064800780028ECD105F022FB79 -:100ED000E9E700BFB17A0020B07A0020B87A00209C -:100EE000AB7A00201CB50E21F8288DF8071017D119 -:100EF0000E4CA068D0F8D41091F884208AB191F8F3 -:100F0000421014228DF80720142905D0D0F830247F -:100F10000DF10701E0209047A068D0F8CC0380478E -:100F20001CBD91F842100E29F0D1F5E70C0100200C -:100F300070B5054608F060FC0F4E0446B068D0F866 -:100F4000F824D0F8D8102846904730B9B068D0F8C7 -:100F5000DC10D0F8F82428469047B068D0F8E810A4 -:100F60000968A94202D1D0F8D80480472046BDE8DC -:100F7000704008F0FCBE00BF0C010020F8B515461B -:100F80000F46064602F03AFCC8B11C21044608F0A0 -:100F9000C5FE002D284608BF012067812680A07469 -:100FA000074890F86C00012812BF0720284606F079 -:100FB000B7FF607403480078013040082074F8BD22 -:100FC000A86D0020CDBA0200F8B50F484FF6FE75A7 -:100FD0000E4C6F1C06784EB12CB120461C2108F037 -:100FE0009DFE678125801C34013EF4E708490020FE -:100FF0000022032A08BFF8BD01EB820301F822009A -:1010000001325D80F5E700BFD1BA02003056002002 -:101010004C79002010B50D49002481F826400C4978 -:10102000087004F037F808F03DFD0A480460FFF747 -:10103000CBFF09480078012803D806F0E1FCF7F758 -:101040006FFEF0F707FE0548046010BDA86D002094 -:101050009C7A0020E879002024260020D826002051 -:10106000F8B5114F0C463968C9B115468A69B2B155 -:101070008A6AB2B100042146461C3046904780B1CE -:10108000A8421CBF0C20F8BD386821468269304652 -:10109000904701460020012908BF0A20F8BD002022 -:1010A000F8BD0920F8BD00BF68270020B0B508F0E2 -:1010B000A3FB044608F02DFE0028FBD0032003F01C -:1010C000C3FC0B48002180F83811204608F04FFE81 -:1010D0000848816802200D4688470446102004F025 -:1010E0002BFD24B103202946BDE8B0400847B0BD20 -:1010F000D81B002018B80200F8B592E87800771CD9 -:1011000008BF0526002780F828700127C0E90431B0 -:1011100000F11801B740F0C11169C0E90B1108498D -:10112000CA6D02EBC602426301F1400240600060FA -:1011300000F10801104607F0BDFA0020F8BD00BF1D -:10114000A01F00202DE9F0414768044608F054FB39 -:1011500005464FF00008D7F8C8609EB17169706805 -:10116000C6F81480C7F8C81006F004FB284608F03B -:10117000FEFDD7F8BC2020463146904708F03CFBE6 -:101180000546E8E72846BDE8F04108F0F0BD70B537 -:101190000446417880786268267F1044A6F10D02EB -:1011A000B2FA82F2520941EA4211227C41EAC201BA -:1011B00000F8011BA16908F010FE05460D2E05D1AF -:1011C00004F10801284608F04AFE0835207C012871 -:1011D00004BFA07D287070BDB0B588B000200DF1AF -:1011E0000B018DF80B00CDE90000684603AAF8F763 -:1011F000AFFA04469DF80B0078B103AD14212846E0 -:1012000008F08CFDFF20214614222B468DF81C008F -:10121000042005F019FA002000E0012008B0B0BD5C -:10122000BFB504460F48002590F82600082801D0D5 -:10123000042814D14FF6FD70ADF8040007F05CFEF1 -:101240000290207861788DF80D508DF80F508DF850 -:101250000C108DF80E0001A8F7F74AFC0546284649 -:1012600004B0B0BDA86D0020FEB58E6A0446777844 -:1012700007F01F00012812D101ADB11C284608F06B -:10128000EEFD0A482946393006F067FB50B11F2FA2 -:1012900005D8B6F80B10B07A02F0ECFA03E0D320D0 -:1012A000F9F7ABF900242046FEBD00BFA86D002071 -:1012B00010B50446C00704D00C4A2120742108F060 -:1012C00003FC200748BFFEF7BBFA09480078012855 -:1012D00003D8A00748BFFCF71FF9600705D50548EC -:1012E000006810B1BDE81040004710BDA86D002097 -:1012F00024260020082400200E485022016841F4D2 -:10130000087121F0020101600B48032140F8041C20 -:1013100041F2300181600121016082604FF4CA62B4 -:10132000016082604FF48652016082600160034870 -:1013300001607047000004605860044000410440B0 -:1013400070B504464668082005F0F8FF90B10546E0 -:10135000012028703078033008F0D6FD686048B16D -:101360003178CA1C314608F0F5FD06482946007858 -:10137000FDF7FAFE606806F0BFFE2046BDE870404B -:1013800008F0C0BDD4260020B0B504460C480D4678 -:10139000007808B904F082FE0A480078A0429CBF99 -:1013A0000020B0BD094A0849002D04EB440018BFD5 -:1013B000294652F8200082692046BDE8B040104717 -:1013C000AB2700208DB9020098BA020028B70200AE -:1013D0001FB50E494FF6FF730A780D49A2B131F8D7 -:1013E000044B013A9C42F9D08442F7D14FF0FF32CE -:1013F000ADF80400074841F8042C02218DF80C10C8 -:10140000818C01A808F0A4FD1FBD00BFD2BA020064 -:1014100098780020A86D002070B1B0B5044608F09F -:10142000F4FB0D49886054F8042D002A05D40B49BB -:101430008A6801328A600BE0704722F00042074B55 -:1014400022605D682A445A600A68A24288BF0C6024 -:10145000BDE8B04008F0C7BCD02500200026002021 -:10146000B0B508F0C9F9044608F053FC0C48002157 -:1014700080F83811032003F0E7FA204608F077FCE3 -:101480000848816802200D4688470446102004F071 -:1014900053FB24B103202946BDE8B0400847B0BD46 -:1014A000D81B002018B8020070B500250C46457105 -:1014B0000D4806780D48AE420CD0415D227B91422A -:1014C00001D00135F7E72046F8F7D6FBE8B28642AF -:1014D00018BF70BD0620002160732068407BBDE806 -:1014E000704000F045BA00BFCEBA02005876002026 -:1014F00010B5044648060FD40E480078012815D8C8 -:10150000204608F0CEFB88B1094900790138C98A24 -:10151000022838BF0C4609E0FF20214605F034FCC4 -:1015200003490028CC8A08BF6FF00104A0B210BDA7 -:10153000A86D0020242600201CB58DF8070002208D -:1015400004F02AFB08B1012415E007F06BFD01242B -:1015500088B10DF10701E12000F016FE0DF1060142 -:1015600052208DF8064000F00FFE044800248470DD -:10157000002008F003F820461CBD00BFCC26002048 -:101580002DE9FC479846AAB115460E4607460024A9 -:101590004FF0FF3A0DF1040931192A1B38464B462A -:1015A000CDF800A0E7F746FB01990C4428B96D1A65 -:1015B000F2D102E000246FF00900B8F1000F18BF6B -:1015C000C8F80040BDE8FC87B0B50F4C0F4D48F29D -:1015D00001012078A84720784FF40041A8472078DF -:1015E00048F22101A847207848F22201A847207834 -:1015F0002021A84720782121A847207822212A46A7 -:10160000BDE8B040104700BF9D7A0020090B0200E2 -:101610002DE9F041DFF83CC04FF0000E4FF000081C -:10162000864513D01F4615466DB131F81E603C88C3 -:10163000A64202BF5FFA88F62CF8164008F10108AE -:101640000237013DF0E70EF1010EE9E75FFA88F09D -:10165000BDE8F0812C730020E0B58DF807000D483F -:10166000017821B100210170EFF7C4FA10E00A48B7 -:10167000816819B10DF10700884709E000200121B8 -:1016800002228DF805000548007801AB03F006F84A -:1016900000208CBDBB270020547500209D7A0020BF -:1016A0007FB504468069068808F0DCF8864209D1D7 -:1016B00007F008FA05460B48012106F01BFF681EDB -:1016C000002301E080230020227C617CC0B2CDE9B0 -:1016D000006048F205000392024A0292A21CFDF744 -:1016E0004BFE7FBD2C73002070B504460F481E468C -:1016F0001546406808F071FB052D057001D846704D -:1017000006E0FE2D06D3DDE90421FF2D427003D053 -:10171000062303E0052301E0082341800348214616 -:101720003822BDE87040FDF7D7BE00BF88260020F4 -:101730002DE9F041DFF83C80DDE9067C1C46D8F855 -:101740000460250605D017F8015B013C06F8015B33 -:10175000F7E7BCF1000F18BF4FF0010C4FEA8C14F3 -:1017600088F80240FDF7B8FE002188F80210BDE8B5 -:10177000F08100BF88260020B0B5142008F0C4FB1B -:10178000D0B11421044608F0C9FA4C201421224695 -:1017900008F094F90546092804D14C20142122466A -:1017A00008F092F9204608F0ADFB044A71200821A8 -:1017B00008F084F92843B0BD0A20B0BDB826002047 -:1017C000B0B5104CA068D0F8E0038047A068D0F80E -:1017D00018028047A068D0F8F00280470025A06872 -:1017E000072D07D0D0F8A00050F8250000B18047A1 -:1017F0000135F4E7D0F858038047EB2008F038F8BB -:101800000120B0BD0C01002070B590B06E460C46B2 -:1018100005464021304608F081FA40F20110ADF84B -:101820000A40ADF80050ADF8110001208DF80E000F -:1018300002208DF808008DF80C0004488068D0F86C -:1018400088123046884710B070BD00BF0C010020E0 -:10185000E0B502464878800709D00D480368ABB16F -:1018600008461146002202B0BDE8804018470948EA -:1018700001916946ADF8002004F0A6F930B10621C7 -:10188000417300680021407B00F072F88CBD00BFFE -:10189000FC260020ED0B02001CB50F4C032184F840 -:1018A0002A1001218DF8071008B100220AE06079A2 -:1018B000022801D8013003E0206902F0F9FC002081 -:1018C0000122607105480DF10701012300910321F8 -:1018D000007801F096FB1CBDAC220020A37A00200A -:1018E000BCB504460D480E4D417044B10D484FF44F -:1018F00080510078FEF776F805F1330000E0281DEE -:10190000002184F001020123017006480DF1070156 -:1019100000910121007801F074FBBCBD0C7A00201D -:10192000AC220020A37A002010B5044620B90E484E -:101930008068D0F84C05804707F05EFF0B490A78B5 -:10194000A2430A7008F013FAFFF7A6FA0648C16826 -:10195000C968097801B110BD80680021D0F8582409 -:101960000020BDE8104010470C010020B17A002093 -:10197000B0B5044614200D4605F0E0FC58B1014610 -:101980000C2008700B488C7000244D708C7300780C -:10199000FDF7EAFB0CE0204607F0DCF838B1062141 -:1019A0004173007B03F0D0FE2046F8F7E7FC1024DB -:1019B0002046B0BD9C7A00202DE9F04104460F4836 -:1019C0004FF00008062600270568A5B128680188A1 -:1019D000A1420ED16989A5F80880490703D5287B63 -:1019E00003F0B2FE2868407BF0216E73FFF7C0FF62 -:1019F0000137281DE8E7F8B2BDE8F081587A0020E9 -:101A0000B0B507F0F9FE05460D48046894B10D48DD -:101A100054F80C1C007821B14FF40051FCF776FB10 -:101A200003E04FF40051FBF73FFE0548214600223A -:101A300003F02AFE284608F09AF92046B0BD00BF00 -:101A4000482700209C7A0020B0B5017D05460C3067 -:101A5000022904D003291AD108F080F902E0008895 -:101A600008F01FF9044690B16878F12818BFE12802 -:101A700006D1A079012806D1208808F04FFA02E0AB -:101A800008B90020A071A07908B10138A071B0BDDB -:101A900010B50D4C207838B90C480D494FF4D6726A -:101AA00008F058FA012020700A48022180F88F10AF -:101AB000012180F88510002180F84510042180F86C -:101AC0009D100321017010BD9B2700204C40002178 -:101AD00050A50200DB030021B0B52021EFF31184F3 -:101AE00081F3118801250B49CA6A0D604069030C16 -:101AF000B0F5802F38BF0423981848610648232189 -:101B000000680268002090470448056084F311884B -:101B1000B0BD00BF042009408401001080022443AE -:101B2000B0B5104C00252574E06810B904F00DFF25 -:101B3000FAE7E068216AB0FA80F0C0F11F0001EB1B -:101B4000C000E169884209D9E061A169026801F138 -:101B50001C0002F11C01A26105F042FA207C002861 -:101B6000E1D1B0BD3822002070B50D46044607F023 -:101B700043FED4E901128A4204D108F0F8F84FF08C -:101B8000FF3070BDE36822680133B3FBF1F606FB5A -:101B900011315554E160A168626901319142A1603F -:101BA00088BF0A46626108F0E2F8A06870BD10B50F -:101BB0008EB0E1B10C460168086AC0B1C97F01AAC4 -:101BC000EFF70CFB6188BDF8102000208A420FD18E -:101BD0009DF8061001290BD10B980178012906D137 -:101BE00021788078401AB0FA80F0400900E00020A7 -:101BF0000EB010BDF0B585B0074615460E460088FC -:101C0000DDE90E121C46F2F715FF05280FD080B94A -:101C1000DDE90C10DDE90A32CDE90032CDE9021030 -:101C2000384631462A462346E5F768FE02E00220A0 -:101C300000E0102005B0F0BDB0B50446202005F04E -:101C40007DFBC0B10546042010222870D4E90001B4 -:101C5000C5F80200A81D07F0F9FBE16805F11600C0 -:101C600007F0BBFC208A2946E88303480078BDE8DA -:101C7000B040FDF779BAB0BD9D7A002010B50F4A8B -:101C80008389526803EB430302EB83044A1E012A53 -:101C90000AD84288022962800BD1043006F00EFA7D -:101CA00038B90020207004E0221D011D104607F005 -:101CB00094FC2046BDE8104007F074BD402600208B -:101CC00010B50C48032290F84810012180F8481004 -:101CD00009480275094A137A1172006940B1084C2B -:101CE000204607F085FE2046BDE8104007F086BE7E -:101CF00010BD00BFA01F0020381F00203822002088 -:101D00004FD40100F8B50E480488204608F0FCF8CE -:101D1000A0B12146FF22054607F0AAFF0948002787 -:101D20000678B74207D2F9B2022022462B46FEF7C8 -:101D30007BF80137F5E7284608F0E4F80020F8BD05 -:101D40004EB20200DFBA0200F8B50D480D4D0E4F3D -:101D50000126046804608CB1B4FA84F0696880F0EC -:101D60001F0006FA00F251F8201094430029F2D027 -:101D700057F820205203EED58847ECE7F8BD00BFA6 -:101D8000E0200240E4B8020000100840F0B585B041 -:101D90000D4F04460B480D4D6E463246397880F89B -:101DA00072402846FDF7ECFF3A78304629468DF818 -:101DB0001240FDF7F0FC4520294600F0E5F905B09A -:101DC000F0BD00BFA86D0020B927002020790020B9 -:101DD0000F49C3070A68496D01D1002106E001F0EF -:101DE000040102F00103C91818BF0121830744BF91 -:101DF00002F0020341EA5301400744BF02F004002D -:101E000041EA90010220002918BF0120704700BF5D -:101E1000402108400F49C3070A68496D01D10121DB -:101E200006E001F0040102F00103C91818BF012106 -:101E3000830744BF02F0020301EA5301400744BF95 -:101E400002F0040001EA90010220002918BF0120DD -:101E5000704700BF4021084070B58AB00C4C4FF469 -:101E60008061DD224FF48066204607F001FF01AD5E -:101E7000284607F059FE042007492A460023CDE9E9 -:101E800005460490034805F0BFF80AB070BD00BFD6 -:101E90004C4C0020E86E0020CD93020070B507F096 -:101EA000ABFC04460B48017821B12046BDE87040E8 -:101EB00007F05DBF01210170074805780748002D34 -:101EC000F3D0064656F80C1B89688847013D30461A -:101ED000F5E700BFAC270020000000000000000074 -:101EE000B0B511F1800201D1002112E00C4A0023AB -:101EF00003EB830544577F2C09D00544D5F80150E6 -:101F00001540954203D08C4201DC0133F0E72BB140 -:101F1000591E01EB81010844D0F801201046B0BDE4 -:101F2000FFFF3F00F0B50F4C00234FF0580C8EB26E -:101F30000027B3F5307F0FD0E1180D8EB54208D1E0 -:101F400039B10D69854204D14AB191F83350154237 -:101F500003D158330137ECE700210846F0BD07FBF9 -:101F60000C41FAE77053002070B5044605680D482F -:101F7000C6680D480068006B8047811B080B05EBA5 -:101F80001132B5EB113F40F6C41188BF50088842AA -:101F9000206004D880084A2802D84FF49671216046 -:101FA00070BD00BFD01E00208C0100102DE9F04153 -:101FB00005460E480078A8429CBF0020BDE8F0818D -:101FC000164688460027BD4208D036F8174007F06D -:101FD00049FC844201D00137F5E7FDB2A5EB0800CA -:101FE000B0FA80F04009BDE8F08100BFD8BA020025 -:101FF00070B507F001FC04460B48017821B120467A -:10200000BDE8704007F0B3BE0121017007480578B4 -:102010000748002DF3D0064656F80C1B8968884700 -:10202000013D3046F5E700BFAD27002003BA0200AE -:10203000A8B9020010B586B00DF11700F9F762FBE0 -:10204000B0B19DF8172004467AB14FF6FC701F21FD -:102050002346ADF80C000F208DF814000020CDE9C8 -:102060000010044803A9F2F743F8204607F04AFF9E -:1020700006B010BD8826002010B50B4C48F21501A3 -:102080002070FEF741FD20783821FEF73DFD07481E -:102090000749084A20610848C4E902210221017267 -:1020A0004FF6FE71018010BDCC240020B534020033 -:1020B00039580200FD610200927900202DE9F041BB -:1020C000C189846948F21F00814208BF0134277822 -:1020D000F800013007F018FF804670B14546661CD5 -:1020E000002405F8017BBC4207D22846314607F0A0 -:1020F000B6FE013408350836F5E74046BDE8F08104 -:1021000010B502460E480024006860B123460479E9 -:1021100094420446F8D1C4888C420446F4D1016844 -:102120001BB1196008E0012010BD11B1044A116013 -:1021300002E0034900220A6007F0E4FE002010BD1F -:102140007427002010B5EEF753FE0C4C207840B9F0 -:1021500006F0D2FE0246AB20002103F0D9FE207823 -:1021600010B107F0BBF828B10548002101700548FF -:1021700001210170BDE8104004F098B82426002029 -:10218000A17A0020A07A0020B0B50C46054652285E -:1021900006D0E22D0BD10B48214607F060FE06E089 -:1021A000074821780078084304BF0120B0BD0648E5 -:1021B00021468068D0F830242846BDE8B04010475A -:1021C000BD270020B67900200C01002010B50423A3 -:1021D000082200F0010403EA901302EA503223447B -:1021E0001A44102303EA1050104401F0010240EA9F -:1021F0004210402202EA91021044802202EA512257 -:1022000010444FF4807202EA1141084380B210BDBD -:1022100010B50D4C2078FE2807D00C480068826B62 -:102220000B48006894F9001090476078FE2807D0AA -:1022300006480068826B0648006894F901109047D0 -:10224000FE206070207010BD24250020347A00200C -:10225000E426002010B5EB2002F07CFD0B480024A2 -:1022600004700B480078862802D1002002F01CF987 -:1022700007F0C2FA07490A6813681C7112680A60FD -:1022800007F075FDBDE8104006F0CEB9B37A002026 -:10229000B87A0020D87900200C480E4B8068DB68A3 -:1022A000D0F8D410D0F8EC00497B50F82100084950 -:1022B0000A680B60991A084A1278920091FBF2F1B1 -:1022C000B1FBF0F202FB1010704700BF0C010020C0 -:1022D000307A002010790020B47A0020B0B50F4C7D -:1022E000A168D1F8B8000278B2B1C569A5B1086C8F -:1022F0000268D06D28B102210023A847A168086CAC -:102300000268106E40B1D1F8B8100023D1F81CC09B -:102310000821BDE8B0406047B0BD00BF0C010020FF -:102320002DE9F04104460D484FF6FE780C4D08F1BA -:10233000010706787EB16889A04218BF002D02D13E -:102340001C35013EF6E728461C2107F0E7FC6F81AB -:10235000A5F80080F4E7BDE8F08100BFD1BA020023 -:1023600030560020B0B570B104460E48416851B1F6 -:1023700000220D462B4625B1A34202D01D681A4605 -:10238000F8E7A34200D0B0BDA14208BF021D2068FB -:102390001060204607F060FD2046BDE8B04007F021 -:1023A000B1BD00BF50260020012919D010B5C08949 -:1023B00001B280EAE130A0EBE13084B2204600F0C7 -:1023C00037F80848084AC16C51F82430934218BFC6 -:1023D00041F824200021006D40F82410BDE8104091 -:1023E000704700BF381F0020696F0200F8B50D4E1E -:1023F00004460D4F306E50F82100B84201D0002045 -:10240000F8BD0A480D461C300090204605F0D6F96C -:102410000028F4D0306E50F82500C01B18BF2046AD -:10242000F8BD00BF381F0020696F0200A01F002008 -:1024300010280FD310380E4A0123410900F01F0065 -:1024400002EB810103FA00F0D1F8F020C1F870012D -:10245000104070470F281CBF0020704704480168D7 -:10246000026822F00202026001F00200704700BF21 -:1024700010E000E010280FD310380E4A0123410964 -:1024800000F01F0002EB810103FA00F0D1F8F02008 -:10249000C1F8F000104070470F281CBF00207047A3 -:1024A00004480168026842F00202026001F0020082 -:1024B000704700BF10E000E000B1704780B52021F8 -:1024C000EFF3118081F311880A49CA6C22B180F3BD -:1024D0001188FCF7EBF804E0002281F8482080F333 -:1024E000118805490122087A0A72BDE8804001F08E -:1024F00093BA00BFA01F002038220020BCB50D4DAC -:10250000286840B96C46204607F06EF80120214645 -:10251000EDF7B8FC28600849097851B948B1074976 -:102520000978012903D1642101F096FBBCBD00F0BC -:102530002AFDBCBD287A0020A2270020A07A002016 -:102540001FB5044600790B2101EB4000C0B204F036 -:10255000F5FE38B122790DF1050122B1012A04D12D -:10256000053107E01FBD033104E00723032A08BF3C -:1025700009231944A2890A8004B0BDE8104005F07F -:10258000BBBD70B505460D200E4607F0BDFCC0B1C1 -:102590000680044615F8020BA070294615F8010CB8 -:1025A000E070201D07F05BFC287AC1210D22234634 -:1025B0002073452000F0E8F82046BDE8704007F0A1 -:1025C000A1BC70BD2DE9F84317460E46044606F03F -:1025D000CDFFB0B10546DDE90898082004F0AEFE55 -:1025E00078B10146C780067180F80390847080F846 -:1025F0000180FE20087068680078BDE8F843FCF7A9 -:10260000B3BDBDE8F883704710B50446007D98B9A6 -:102610002046EDF753FE206918B10A48816820462C -:102620008847217DE06821B107F06CFC0020E06064 -:1026300002E0FCF7E1F920752046BDE8104007F004 -:102640008ABA00BF5024002070B50C2007F05CFC53 -:10265000A8B10C4E04464FF0FF300025A06060602A -:1026600020603088854207D2A9B201200C2223467F -:10267000FDF7DAFB0135F4E7204607F043FC0020C4 -:1026800070BD00BF402600202DE9FC410D4D4FF0EC -:102690000008002600272888874228BFBDE8FC8163 -:1026A0006868B9B200220C2384190120009403F059 -:1026B000B5FF20B92078FF2808BF84F800800C36C9 -:1026C0000137E8E74026002070B5102007F01CFC19 -:1026D000B0B104464FF0FF300026E060A0606060BB -:1026E000206008480578AE4207D2F1B203201022DC -:1026F0002346FDF799FB0136F5E7204607F002FC7B -:10270000002070BDE3BA0200F0B585B04FF0FF3095 -:102710000027ADF810000390CDE90100084801AD95 -:10272000048808480678B74224BF05B0F0BDF9B266 -:10273000022022462B4603F087FF0137F3E700BF54 -:102740004EB20200DFBA020070B50E488068D0F8C1 -:10275000D810096819B9D0F8DC00006880B107F01A -:102760004BF8044607F080F9054601F049FE06469D -:10277000204607F0FCFA701C281A98BF012070BD93 -:10278000002070BD0C0100202DE9F0410746D01C4F -:10279000984614460D4604F0D1FD80B1064685707A -:1027A0004770047024B1F01C4146224607F0D2FB6A -:1027B000044831460078BDE8F041FCF7D5BCBDE8DF -:1027C000F08100BF927A002010B50949094C002021 -:1027D000A04709490120A04708490620A047084909 -:1027E0000720A047074908202246BDE810401047AF -:1027F0009DE90100D58F0200755D0200073B0200D4 -:10280000A9540200D954020080B5EFF723FA0B4A0D -:102810002120742107F058F902F09EFD0848007845 -:10282000012898BF02F0B0FD0648006800B180475B -:1028300002F042FABDE88040F7F760BCA86D0020C6 -:10284000242600200024002070B5D0B1056804467D -:10285000BDB12868A8B107F0D8F90646286807F086 -:1028600029FB10B1286807F07CFA286806F0ACFF55 -:102870002846FEF7D1FD00253046256007F0B3FA63 -:1028800000E00225284670BDF8B517460D460646FD -:1028900007F0BBF93168044639B14FF0FF3051F809 -:1028A0000C1C01300029FAD100E00020B84205D20A -:1028B0003046294604F08CF9012500E00025204629 -:1028C00007F091FA2846F8BD0B4A1278012A11D177 -:1028D0000A4A127882420DD9094A0029094B18BFC9 -:1028E0000A4600EB400103EB810053F82110CB684E -:1028F0001146184700207047AC2700200000000058 -:1029000040B70200000000000B4801688907FCD5B1 -:102910000A4801210A4AD0F83C0101284FF0010081 -:1029200008BF202008239061002010600548036044 -:1029300043601160704700BF58600C40D81B0020F6 -:1029400000400C4038500C4040F00201022918BFF2 -:1029500070477CB50A4D0B4C80B270220423296865 -:102960004E68009020460021B04728680021702260 -:102970007023D0F80CC0204602B0BDE8704060471C -:10298000A401001000A00C4070B50E4A0C490023B1 -:102990004FF6FE74032512780531934228BF70BDAF -:1029A0004E78F60709D131F8036C864205D10E78CE -:1029B000012E04BF21F8034C0D7008310133ECE700 -:1029C0004C500020D6BA02000C4A1278012A11D1CC -:1029D000094A127882420DD9094A0029094B18BFC9 -:1029E0000A4600EB400103EB810053F82110CB684D -:1029F000114618470020704703BA0200AD27002097 -:102A000054B60200A8B9020080B5014600780C282F -:102A100003D00D2814D1486801E04868C83078B167 -:102A2000027802F00302032A0AD1807800F0030042 -:102A3000032805D103480078FCF796FB012080BDF0 -:102A4000002080BDCC26002010B586B001AC11213D -:102A5000204607F063F981201121224607F02EF865 -:102A600070B901AB81200021112206F085FB38B935 -:102A70009DF8040020B10348018841F01001018055 -:102A800006B010BD3E7900207CB50C460D491D787E -:102A900000268DF8070049684A70120A0E70081D5A -:102AA0008A701A78CA7013F8012B194606F0CEFC0A -:102AB000281D214648F21102C3B20DF10700FCF7B0 -:102AC0000BFD7CBD88260020F0B587B001AD044623 -:102AD0001821284607F022F90027022F84BF07B0EB -:102AE000F0BDFEB2062018222B463146FDF79CF9B8 -:102AF000012C08BF002805D10620314618222B469C -:102B000003F0A2FD0137E8E7BCB50C460DF1060164 -:102B1000154603F087FE0146C82091B909490968A6 -:102B200079B1BDF806200020032804BFC820BCBD31 -:102B30000B88934202D006310130F5E7288000204F -:102B40002160BCBDEC260020BCB50D4D0028A96855 -:102B5000D1F8C81318BF01208847044600200DF1A2 -:102B600007018DF80700A868D0F830245620904758 -:102B7000A8680449D0F83024E22090472046BCBD24 -:102B80000C010020B679002010B502460D48002443 -:102B90000068A0B12346047994420446F8D1C48861 -:102BA0008C420446F4D10749002B18BF194602682D -:102BB0000A6007F0A7F901F043FB012010BD0020D7 -:102BC00010BD00BFF82600202DE9F84307460C4849 -:102BD0000C4C90468946002605786DB12078B842A5 -:102BE00007D12046494605F0A1FC10B1464504D264 -:102BF00001360E34013DF0E700242046BDE8F8839D -:102C0000DFBA020030790020B0B505680446B5F897 -:102C10005610A86807F050F9A86807F04FF9204649 -:102C200005F08DFDB5F8580040B14FF6FF718842B0 -:102C300004D00138A5F85800000400D0B0BD2046EB -:102C4000BDE8B04004F001BE70B50D4E0D4C3068CB -:102C50008168204688470546606840F03000606023 -:102C600028060AD030680021426820469047306824 -:102C70008168204688470028F9D1E8B270BD00BFBE -:102C8000D80100100040034080B50E490C48096887 -:102C90000068096C884710F1140F45F6A611A8BF0B -:102CA0006FF0130010F15A0FD8BF6FF05900C0EB4E -:102CB00000200844462180B2B0FBF1F0C0B280BDD4 -:102CC000E4260020347A00200B480C4AD0E9021098 -:102CD000137B0068D1F8E01003F0F00302330078B2 -:102CE0000968137308440649097848430549096887 -:102CF00001EB8000906070470C010020C07700203D -:102D0000B47A0020307A0020F8B50E4E0C46054605 -:102D10000027ACB1606841196160B068D0F8E82064 -:102D20001268944204D1B1F1FF3F01DC676005E015 -:102D3000B1F1FF3F02DCD0F84C0580472468E8E79A -:102D4000F8BD00BF0C01002080B50C4800780628B3 -:102D50000ED10B480178013101700A48018802291F -:102D600006D3013901800620BDE88040E4F7AEB803 -:102D7000FDF7B6FABDE88040F7F780BABB7A0020CD -:102D8000B6270020C679002010B58EB00168044631 -:102D9000086AA0B1C97F01AAEEF720FA0948BDF878 -:102DA0000E10C08A81420AD020689DF82120038835 -:102DB000BDF8100000934FF6FE73FDF75FF80EB0FC -:102DC00010BD00BFA86D00204FF6FE73984203D0DF -:102DD00002F06003602B01D101207047930608D4F4 -:102DE000084B5206DB8A09D4834209D38B42F3D9BC -:102DF00006E00448C08A8842EED901E08342EBD263 -:102E000000207047A86D002070B52020EFF31184DA -:102E100080F3118809480068006B8047084AD2E9AE -:102E20001556084AD2E9102384F3118806F00EF9EA -:102E3000281AB04288BF002070BD00BF8C0100106E -:102E400008200020886E002070B50E480121047A09 -:102E5000017285692020EFF3118680F311882846DE -:102E600000F0BCFD032085F82000284601F08CFB13 -:102E700086F311886D602D602046BDE8704000F03B -:102E8000CBBD00BF3822002010B5F7F7F7FA05F0E8 -:102E900087F802F091FA0B4C94F83C0010B901202D -:102EA00084F83C00F6F754F804F086F804F0C0F813 -:102EB000FAF784FE02F022F906F0FAFD01202070F4 -:102EC00010BD00BFA01F002080B50E480078062866 -:102ED00007D0052809D002280BD1BDE8804006F0B4 -:102EE000ACBFBDE8804006F0A5BF07F057F820B1A1 -:102EF00080BDBDE8804005F0B1BE1C20BDE880402B -:102F0000EFF70ABCBB7A0020B0B505460C46084670 -:102F1000D121FDF715FD08B14570B0BD022004F0C8 -:102F20000DFA40B101464570D12008702046BDE839 -:102F3000B040FCF719B9034810210078BDE8B04053 -:102F4000FBF7E4B89D7A002070B50568686810B199 -:102F50000C46642901D9002070BD296801FB04F6E4 -:102F60006421B6FBF1F106F044FF0146B0FA80F0AF -:102F7000400909B985F853400021632E88BF01211B -:102F800085F8511070BDB0B50468002184F8511067 -:102F900094F85210012906D194F85400002106F04B -:102FA000B5F9012006E094F853500021FFF7CCFF5B -:102FB00084F8535094F8501002291CBF002184F863 -:102FC0005010B0BDB0B5044600786178084406F0F2 -:102FD0009BFF054698B12178284606F09FFE4FF6E4 -:102FE000FE70688006F03EFCA88020786178284456 -:102FF0002975286104F064FD6875A0782876284654 -:10300000B0BD2DE9F843CBB1089CBCB18046981CFB -:103010001F4616468946C0B204F090F970B10546C5 -:10302000023021463A4606F011FA6E7085F800909B -:1030300040462946BDE8F843FCF796B8BDE8F8835A -:10304000B0B505460E2004F079F9A0B1044607207A -:10305000207028886080A8780228207104D16968CF -:10306000601D082206F0F2F9034821460078BDE809 -:10307000B040FCF779B8B0BD9D7A0020B0B50446E9 -:10308000102004F05BF9A0B1054605206168082214 -:103090002870208868802089A881281D06F0D6F92C -:1030A000A07A2946A87303480078BDE8B040FCF731 -:1030B0005BB8B0BD9D7A0020B0B50578ADB10446CF -:1030C00003F082FC01280FD10948A189406801EB77 -:1030D000410210F82210294205D100EB8200294359 -:1030E000017006F05FFB0120B0BD0020B0BD00BF45 -:1030F000402600201FB582B100230193D2E901349C -:1031000012788DF80420094A0293039402F11C03FB -:1031100001AA04F065FF04B010BD044A02F11C03CB -:10312000002204B0BDE8104004F05ABFA01F0020E8 -:10313000FF2817D0B0B5044605F0A4FB0A4D286857 -:1031400050F82410204606F00FFE686850F824104E -:1031500011B1002140F82410A868002140F8241083 -:10316000BDE8B040704700BFE4B80200BBB12DE934 -:10317000F04786B0DFF82CE0EC4666469EE8B007E4 -:1031800086E8B007D3E900451B7A8DF8083063461E -:1031900001940495FFF72AF906B0BDE8F0870023F3 -:1031A000FFF724B9E8B702000A49097809B10120FC -:1031B000704709490978FF2904BF00207047084B70 -:1031C000064A0433022808BF131D1868C84000F0DF -:1031D000010070477C270020B57A0020207700206E -:1031E000F8730020BCB50C4605460DF107016A4690 -:1031F000204602F0C1FA10B14FF6FE740EE09DF8C1 -:10320000070000992870696030B1421E01EB400050 -:1032100030F8024C6A7001E0002068702046BCBDA6 -:10322000B0B50446007A38B1254635F80C0FE96888 -:10323000F1F74EFF01280AD0E07968B134F80A0F9F -:10324000D4F80A10F1F744FF0128254604D1288854 -:10325000FBF76CF90120B0BD0020B0BDC0F34022E7 -:103260008A7100F003028A70C0F380224A77C0F3AB -:1032700000224A71C0F3403281F83120C0F300329D -:103280000A72C0F3C022CA71C2B2800B9309C2F3A2 -:1032900083020B71CA70704710B50120FFF754FC10 -:1032A0000446FBF7BDFC09480078012898BF04F0EC -:1032B000B7FB05F0ABFA02F09FFC05F099F9044862 -:1032C0000078FDF7A7FE204610BD00BF2426002091 -:1032D0009C7A0020B0B50B4890F8664084B10A484B -:1032E000058806F097FC28404FF47A7114FB010220 -:1032F00006484FF480710078BDE8B04006F067BD25 -:10330000B0BD00BFA86D00208EB902009C7A0020DD -:10331000F0B50B4C0B4D50B149B10B4E0327376044 -:10332000B768BF07FCD101262E602060A1602AB1DA -:1033300023B10120C5F800042262A362F0BD00BFE2 -:1033400004400240000048428847024070B50D4BDF -:103350001B3800FB00F193E87000DB6801FB00F212 -:1033600083FB0223C6FB0123C5FB002310091909B7 -:1033700040EA0370001941EBE471000C40EA01409F -:1033800070BD00BFA425002070B50C4D4FF48773AD -:103390006E88EA88921B02F5877292FBF3F404FBB5 -:1033A000132294B28C4228BF0C4605492246314470 -:1033B00006F0D0FDA0196880204670BD7024002062 -:1033C0009263002070B50D46064606F01EFC0446CA -:1033D0003046294604F044FD60B1006806F068FDFF -:1033E000054606F061FD4FF47A71B1FBF0F0B5FBD4 -:1033F000F0F500E00025204606F0F5FC284670BDFB -:103400007CB50C4D0C4C00214FF4C072072328688A -:103410004668022000902046B047286800214FF4FB -:10342000C0720723D0F80CC0204602B0BDE870403F -:10343000604700BFA401001000A00C4080B50B49FC -:1034400002220A720A4A10704FF6FE70088005F0D8 -:1034500053FD04F081F8074804F0B4F8FFF7F4FADC -:1034600005F0DCFABDE88040FEF7AEB888790020B0 -:103470009D7A0020942500200B48007802280BD26A -:103480000A48807B800708D509484FF4807140F6D0 -:10349000C412007806F09EBCF6D105484FF4807146 -:1034A0000078FAF733BE00BF24260020A86D002064 -:1034B0009D7A0020B0B50546242003F03FFF98B167 -:1034C00004463220A9681B2220702878A070686802 -:1034D000606004F1080005F0B9FF04482146007857 -:1034E000BDE8B040FBF740BEB0BD00BFCC2400201B -:1034F00070B5FEF7E3FDC0B10446451C00262078F8 -:1035000086420DD2284606F029FC30B100790138F8 -:10351000012802D82846FBF71FFD08350136EEE7E3 -:103520002046BDE8704006F0EDBC70BD80B50C498A -:103530000978022908BF012800D080BD0948C07859 -:103540000028FAD1FDF740FD06F06AFA18B1BDE88F -:103550008040F6F713BE0020BDE88040FEF79CB91E -:1035600024260020D0260020F8B50D4F06461C4624 -:103570001546786806F073FC681EB0FA80F04009C2 -:103580008001012C08BF8030796834220923087239 -:103590003846314601B0BDE8F040FBF79DBF00BFA3 -:1035A000882600201FB50D4C030A0029626853705D -:1035B000107018BF0121152202238801A0704FF658 -:1035C000FD70ADF804000F208DF80C0001A9204615 -:1035D000FBF782FF0021A17004B010BD88260020F7 -:1035E000B0B5002101600C490A6892B100254FF680 -:1035F000FE74AB1D182B0CD0555BA5421D46F8D1AF -:103600001A44063A02600868C118002001F8020C4A -:10361000B0BDC820B0BD00BFEC260020B0B586B05C -:10362000044600206D4618212075284606F076FBDA -:10363000284621460A2205F009FF6089ADF80A00F4 -:1036400004488068D0F8F81228468847002006B061 -:10365000B0BD00BF0C0100202DE9F0411D4616460B -:103660008846044605F082FF90B10746062003F025 -:1036700065FE68B10146868084704570FD20087043 -:10368000786881F803800078BDE8F041FBF76CBDF5 -:10369000BDE8F08170B586B001AC1421FF22204650 -:1036A00006F0E6FA094800260578AE420AD2F1B2E1 -:1036B000082014222346FCF7B7FB01360A28F4D170 -:1036C0000A2000E0002006B070BD00BFC9BA0200A9 -:1036D0002DE9F04105460B480B4E8846002704783B -:1036E00064B13078A84206D13046414604F01EFF4E -:1036F000002818BF01370E36013CF1E7B8B2BDE82B -:10370000F08100BFDFBA020030790020B0B50D4D66 -:103710000446E8688069007801280AD104F0B0FB0B -:1037200040B1E86880690178012902D10021017067 -:1037300024B1B0BDBDE8B040F2F7E6BEBDE8B04090 -:1037400003F0D0BF0C01002010B504460B48006800 -:10375000A04204D80A488068D0F84C058047B4F1EC -:10376000FF3F04DC06488068D0F84C05804706F02F -:1037700043F8BDE8104006F0FABA00BF3C7A0020DA -:103780000C010020B0B504460A480068A04204D8E5 -:1037900009488068D0F84C05804706F02DF80546AA -:1037A000064804602046F7F757F92846BDE8B040C0 -:1037B00006F0DDBA3C7A00200C010020407A00209F -:1037C0000B480178832902D0017886290BD10A4958 -:1037D0000978032902D10020F1F746BE8521017046 -:1037E0001D20EEF799BF03488068D0F84C050047CC -:1037F000B87A00200C010020BB7A0020B0B54FF64B -:10380000FE704FF6FF7101F0DDFB00B1B0BD08485E -:10381000084D04780020002CF8D0A97C09B1697CFF -:1038200019B92888FFF7B0F828461C35013CF2E7A3 -:10383000D1BA020030560020B0B505460C480C46FF -:103840000078012809D80948808CA04205D1284673 -:1038500006F027FA08B10830B0BD2846214601F02D -:10386000B1FB002818BF1030B0BD00BFA86D00200C -:1038700024260020B0B50B4D0C4695F872108142FD -:1038800028BFB0BDFEF782FA074864210480E879BA -:1038900000FB01F205484FF400710078BDE8B0402C -:1038A00006F098BAA86D00209A6900209C7A002042 -:1038B00070B50D4E0C46B18CFFF7BEFF88B10546C2 -:1038C000807804F02DFB697859B150B1884298BFD7 -:1038D0000846727B012A18BF0846A0429CBF0120FF -:1038E00070BD002070BD00BFA86D002070B50446FB -:1038F0000C4801210160D4E91001D4E91623851890 -:1039000041EB0306280C002240EA064100F00CF8C7 -:10391000D4E91623D4E9060150346CC4BDE87040E4 -:10392000084700BF0420094010B50C4606F0C1F955 -:103930000B498A69A31A0632B3F1004F09D8131B49 -:10394000B3F1FF3F2346C8BF1346A24298BF2346A8 -:103950001A460A6000B110BDBDE8104006F0ADB9CE -:103960001820094010B5044608480949094A0A4B7D -:10397000C4E90210002004F11001C4E90032A06182 -:10398000064804F097FE204610BD00BF899E020045 -:103990008F9E0200839E02007D9E0200A8260020CA -:1039A00010B588B001AC0A491C22204606F0D2FAB4 -:1039B0000020094A002123468DF810000A200390B8 -:1039C00002208DF804000348EBF7C6FB08B010BDD9 -:1039D0000CB70200886E0020F99A0200B0B50D49BC -:1039E000CA68036844682360436804686360C46C01 -:1039F00083692568A54204BF9A43CA608A698242E6 -:103A000004BF0022CA6101220A74022180F820103A -:103A1000B0BD00BF3822002000B1704710B50B4C7C -:103A20002020EFF3118180F31188207C28B1084811 -:103A300090F8480008B9FEF773F80020207240F2B1 -:103A4000000CEFF311808CF3118810BD3822002098 -:103A5000A01F0020F8B50E460B4900281C464D68F3 -:103A6000314618BF0546002A2F6808BF082228469D -:103A7000B847074630B9054A204600212B46009634 -:103A800001F08AFB3846F8BDA01F002077AD020088 -:103A9000BCB5054600200C460DF1070300210122AC -:103AA0008DF80700032005F067FB00B1BCBD9DF851 -:103AB0000700FF2D0DF1070214BFA0432043012191 -:103AC0008DF80700032005F0FFFFBCBD10B542785C -:103AD00001788378C478002A18BF41F00201002BD6 -:103AE00018BF41F00401002C18BF41F00801027911 -:103AF000002A18BF41F040014079002818BF41F06A -:103B00008001C8B210BDBFB504460DF10205082200 -:103B100034F8020BADF80200A81C214605F096FC13 -:103B2000207AC9210D222B468DF80C00B4F809002B -:103B3000ADF80D004520FEF727FE002004B0B0BD13 -:103B4000B0B50B49402200240A6080220A60C1F807 -:103B5000FC42056895F8260020B1064806F0E6F913 -:103B600085F826400220BDE8B04000F06DBF00BFE0 -:103B70000444024098700020B0B550B1044600786B -:103B8000102200F07F010520FDF76AFA0020207066 -:103B9000B0BD064800250488A542F9D2A9B2052087 -:103BA0001022FDF75DFA0135F6E700BFBEBA02004C -:103BB000B0B50D4611461A46F6F7D2FE90B1294629 -:103BC000044604F0B3FC68B12046294600F081FDAC -:103BD00030B96588204605F06BFA2846FDF79EF857 -:103BE0000020B0BDB420B0BD70B50C4B0A4A1C78A3 -:103BF0000432002374B112F8245B00268D4298BF72 -:103C0000012685424FF0000528BF0125013C3540C3 -:103C10002B44EFE7D8B270BD20450020E3BA020084 -:103C200010F1240FD8BF6FF023001B28A8BF1B2062 -:103C300003210F222430A1EB101122EA000022FA06 -:103C400001F14FF6FF7222FA00F040EA014001490B -:103C50000860704718A00C4010B5046894F8522012 -:103C6000012A05D194F85400012105F04FFB02E030 -:103C7000FFF76AF950B194F8500002281CBF0120E8 -:103C800084F85000012084F8510010BD002010BDC0 -:103C9000B0B50B4D04462878A04201D10020B0BD3C -:103CA00058B908488068D0F83803804728B12046C2 -:103CB000F4F700FE08B12C70F0E7E220B0BD00BFC1 -:103CC000AF7A00200C01002070B5B0B10546007A33 -:103CD00000F0FE00022810D12846F4F733FEFF283A -:103CE0000BD02A7A00210646002401F0CFF82A7A68 -:103CF0003046002101F0E4F800E0E824204670BDE1 -:103D000086B0044609486D46047009480068EFF320 -:103D1000118180F311882846152105F0FFFF054A1F -:103D200028461521234605F06DF8FEE7962700206A -:103D3000B0BA020000B802004FF6F871884206D30C -:103D40000830BF22C1B222FA01F1C90701D1002017 -:103D50007047054900B251F820100448027802204B -:103D6000114208BF0120704774B60200947A002007 -:103D7000B0B50A490A4A0B4B0C684D68AC42FCD1FD -:103D8000844208BFB0BD155C145DAC424FF0FF35F6 -:103D900038BF01252C441C5D0C60EDE700600C4031 -:103DA0003CBA020040BA020010B50A4C002120685B -:103DB000426801209047206801680120884708B1C7 -:103DC00000F0D2F804480068E068006880470349C2 -:103DD000C86010BDE001001030200940F42400202C -:103DE00010B50A490A4C0860D1F8980040F0030069 -:103DF000C1F898002068816920208847054800683C -:103E00002068806BBDE81040004700BF8C2108404F -:103E1000B80100102C200940F0B50B4A0B4D0023CF -:103E20004FF4877654888B4224BF0846F0BDA7B272 -:103E300001340133EF5DA4B200F8017BB4FBF6F767 -:103E400007FB16445480EEE7C82600208462002059 -:103E5000F8B5094F0C46054605F0D7FE064607485B -:103E60000749084AC7E90254F8F7F2FC3046BDE8B2 -:103E7000F84005F0B8BF00BF702400209263002016 -:103E8000A0640020893E0200B0B50C460B4D002115 -:103E9000E880698010B1E96801B188473CB1002031 -:103EA0002870AA68A9881AB111B920469047A98834 -:103EB00011B12869FAF79AF8B0BD00BF702400204C -:103EC00070B50B4E05460B4C30688168204688471C -:103ED00000F00300002128603068426820469047C7 -:103EE00030688168204688470028F9D170BD00BF3E -:103EF000D8010010004003402DE9FC410B4C07465F -:103F0000984615460E46606808B1804758B10421AE -:103F1000E0682A464346009106EB473105F064F914 -:103F2000C00FBDE8FC810B20BDE8FC81A023002070 -:103F300010B5FEF75DF8012003F0D8FA044605F04D -:103F40005BFC08490A683AB105F011FF4CB1204604 -:103F5000BDE8104005F022BD0C60BDE8104005F042 -:103F600006BF10BD0C24002010B50A480B4C018878 -:103F7000C907094907D14FF001222260008808686B -:103F8000BDE810400047086880474FF0807020600F -:103F900010BD00BF00A00C408000001004A40C4025 -:103FA0007CB50B4D0B4C00214FF040521C23286870 -:103FB0004668032000902046B047286800214FF44F -:103FC000007209234568012000902046A8477CBD67 -:103FD000A401001000A00C40B0B50C4D297A09B125 -:103FE0000720B0BDA98CFFF727FC0028F8D00446B5 -:103FF00080786D7B03F094FF012D03D161788842B6 -:1040000098BF0846002808BF0720B0BDA86D002053 -:10401000B0B505F0F1FB0A4991E83C000F1D1CC743 -:104020000B69084C1C4485EA950383EA43030C6141 -:10403000534083EA02150D6005F099FE6019B0BD8A -:1040400034780020C5870500F8B50C46054605F014 -:10405000D3FB2B1D6E690ECB8F1AA74238BF3C468F -:1040600022442344B24288BF16466E61B3FBF1F688 -:1040700006FB1131C5E9022105F079FE2046F8BDA5 -:1040800070B50668054605F0B7FB0446707A70B94E -:1040900001207072284602F085F8686805F096FCE9 -:1040A0002846EDF773FC2846002103F021F820464E -:1040B000BDE8704005F05BBEF8B5D0E9006505F0DD -:1040C0009BFB0446307870B1287905F0FFF9012890 -:1040D00006D1286800274760301D05F0F1FE3770D3 -:1040E0002879F2F763F82046BDE8F84005F03FBEB6 -:1040F000B0B58AB0F1F7DCFB04AD822000211822B4 -:1041000000242B4605F038F858B9681C694610227F -:10411000CDE90244CDE9004404F0E2F8B0FA80F0C1 -:10412000440920460AB0B0BDB0B585690C460846C2 -:10413000294605F094FE287A2072B5F809006081BE -:1041400004F10C00E97A0329217506D105F10C016F -:1041500005F085FE287DA075B0BDA9890180B0BDA0 -:104160001CB581690B880A4909888B4204D1094A28 -:10417000194600F01FFD1CBD017C427C48F203047F -:10418000CDE90041811C1046802202F085FD1CBD56 -:1041900088790020007A0020BFB514464FF6FD72E2 -:1041A0000A4DADF804200F228DF80C206A6822F821 -:1041B000020B104605F053FE686813220B2384722D -:1041C00001A92846FBF788F904B0B0BD8826002075 -:1041D000BCB54FF0FF316C460028CDE9001118BF87 -:1041E0000446AB200021224601F092FE054D2146F7 -:1041F000284605F034FE712008212A4605F064FCAB -:10420000BCBD00BFB826002010B50C4A1278A2B180 -:104210006E28034628BF6E23323B322838BF002366 -:1042200008783C2443431BB2012A08BF93FBF4F0F7 -:1042300080B2FF2828BFFF20087010BDAE270020E5 -:10424000F0B585B06C460B4F0026A51C3F687FB1CA -:104250003879B91D12228DF80000284605F0F6F8CD -:10426000F1B208201422234602F0EEF90136EDE700 -:1042700005B0F0BDF8260020F8B50C4D0446002628 -:104280002846002E08BF2E46006858B10179A14289 -:1042900006D101683160076805F034FE3846F4E75E -:1042A0000646EEE7BDE8F840FFF7CABFF826002053 -:1042B00010B50C4901F1100322461C687CB104F1D1 -:1042C00018038442F8D151F8103F834218BF02F11D -:1042D000180182690A6005F015FE002010BD022059 -:1042E00010BD00BFAC22002010B50C4A12688AB184 -:1042F000FF2911D013788B420ED854781C448C427D -:104300000AD9C91AC01A5268C9B2C0B2515C105C4D -:10431000884201D1002010BD012010BD647A002028 -:104320000949084889680088D1F8D420D084074812 -:1043300000220270D1F8D4000549C08C4886054996 -:10434000C8817047AE6500200C010020B27A0020C1 -:10435000007200200079002009480A49C0680A7BE1 -:10436000406802F0F002033200780A73064A1278BD -:104370005043064A1278504380008860704700BF5F -:104380000C010020C0770020B47A0020BA7A002007 -:1043900010B50B4C207830B101280AD0022803D187 -:1043A00002F0EBF905E010BD06488068D0F84C0536 -:1043B000804700202070BDE8104004F0A1BE00BF7F -:1043C000B02700200C010020B0B5044605F014FA17 -:1043D000054602200021F6F77FFF084906482246DD -:1043E000096800688B694FF0FF3198472846BDE89F -:1043F000B04005F0BCBC00BFE4260020347A0020A9 -:10440000F8B505F0F9F9044608480068C06B804724 -:1044100005460748067807480768204605F0A7FCC8 -:10442000E81BB100B0FBF1F0F8BD00BF347A00200A -:10443000B47A0020307A0020BFB505F0E6FB01AD6C -:104440000446284605F091FB002001212A460290EF -:104450008DF804000448FEF74DFE0449086020462C -:1044600005F0C1FCBFBD00BFD95A020034270020AF -:104470000C4800224FF470038168D1F8D8100A600C -:104480008168D1F8DC100A608168D1F8E0100B6017 -:104490008168D1F8E4100B608068D0F8E800026011 -:1044A000704700BF0C01002080B50B4881890131A5 -:1044B000818105F0A1F909490A78862A08D1872265 -:1044C0000A7005F054FCE920BDE88040EEF724B9FD -:1044D000BDE8804005F04BBC5C780020B87A002035 -:1044E00080B50948012101700848406818B10848A2 -:1044F000818901318181F02000F02CFC0548007891 -:10450000BDE88040E5F7DABE2D260020C077002008 -:10451000AC780020BB7A0020F0B585B00B4C246845 -:1045200084B1256A75B1DDE90C6CDDE90A47000448 -:10453000049100210130CDE90047CDE9026C00244F -:10454000A84700B10A24204605B0F0BD6827002026 -:10455000F0B589B005AD0C4601461022102728465B -:1045600005F044F901AE304605F016F9054831462C -:10457000CDE90347CDE90154006805F0ECFB09B033 -:10458000F0BD00BFFC79002010B590F8480088B15C -:104590002020EFF3118480F3118807484169013925 -:1045A000416105D1054884F31188016A00208847DC -:1045B00084F3118810BD00BF38220020381F00206E -:1045C00080B568B101460068D1E9012348B11146C0 -:1045D0001A4604F02BFB0648BDE8804004F026BBD9 -:1045E00080BD04480021BDE8804004F01FBB00BF2F -:1045F000C4BA0200EFB6020070B50948094C844203 -:104600000BD0094D094EB54207D0F5E8020110F86C -:10461000012B54F822209047F5E705F09DFC70BD72 -:10462000A0BE020094BE0200E8BE020038BF020035 -:1046300083B00290002001918DF8030082420BD0DC -:104640000299095C019B1B5C013059409DF80330C5 -:1046500019438DF80310F1E79DF80300B0FA80F0DC -:10466000400903B07047B2B110B586B09368062B0D -:1046700003D35C1C01D000200BE0002404930194C0 -:10468000D2E90034D268CDE90234059201AA04F0DF -:104690009DFA06B010BD002204F098BA2DE9F04151 -:1046A000804610461E4617460D4602F047FE70B182 -:1046B00004462FB126B1204631463A4604F0C6FEE4 -:1046C000257040462146BDE8F041FAF74DBDBDE8F2 -:1046D000F08170B5B0B14279A2B1831D14461D4678 -:1046E00062B11E888E4204D1013C2606447102D17B -:1046F00008E025F8026B0233013AF1E720061CBFFF -:10470000012070BD002070BD10B501784078642490 -:10471000012808BF632429B1052004F0E7FE201A10 -:10472000A0F10D040448007B20B104F0DFFE201A44 -:10473000A0F10E04E0B210BDA86D00200549064AA4 -:104740000A6006490870064806490160064807499C -:10475000016070470027002049FB00004826002028 -:10476000FC2600209975010004270020CD9202004C -:10477000B0B505460C2002F0E1FD80B104460620EC -:1047800069680822207028886080201D04F05EFE81 -:10479000034821460078BDE8B040FAF7E5BCB0BD5B -:1047A0009D7A0020B0B50648084B0649084C064AD9 -:1047B000084DC0E90152C0E903414361B0BD00BFEB -:1047C00050240020A19E02000DE70100B5980000D2 -:1047D0006161000039CE0100B0B50648084B0649BA -:1047E000084C064A084DC0E90152C0E90341436143 -:1047F000B0BD00BF50240020A19E02000DE70100C3 -:10480000B59800006161000081800200B0B50648E3 -:10481000084B0649084C064A084DC0E90152C0E958 -:1048200003414361B0BD00BF50240020A19E02009F -:104830000DE70100B598000061610000816D010085 -:10484000B0B5054602F0C0F8044601280ED108486C -:10485000A9892B78406801EB410110F821209A4387 -:1048600000F8212000EB810004F09CFF2046B0BD41 -:1048700040260020F8B509480A4D00270678084868 -:104880000488BE4208BFF8BDB9B2022022462B46BA -:1048900001F0DAFE0E350137F3E700BFDFBA0200A0 -:1048A0004EB2020030790020E0B50A4800780128B5 -:1048B0000FD80120F7F718FC0749ADF80600C882A9 -:1048C0000DF106015320FDF75FFCBDF80600FCF773 -:1048D000CFF88CBD24260020A86D002010B504461A -:1048E0000948807B000707D40648006820B10748C4 -:1048F00008210078F9F70AFC2046BDE81040F2F7DD -:104900004ABE00BF44240020A86D0020997A0020F0 -:10491000F8B50A4E054605F078F9044608482A46D7 -:10492000002375800027D0E9011004F0E2FE00B1F9 -:104930007780204605F057FA7088F8BD7026002071 -:1049400048230020B0B50C4600210546224603F05E -:10495000B9FC0748007800B1B0BD7C2C054904BF04 -:104960000448C57005EB450001EB80008475B0BDBF -:10497000A0230020B8720020F8B50B4F0446002693 -:104980006D463978F0B288420AD200212A460423C3 -:1049900004F024FD9DF80000A04202D00136F0E7AB -:1049A000FF26F0B2F8BD00BF9B7A0020F8B505F0F5 -:1049B0002CF90A4E044675685DB145B128682F6927 -:1049C00004F002FF284605F09DFA3D46F5E7002079 -:1049D00070602046BDE8F84005F005BA7826002052 -:1049E00070B50A4C034620780E280CD8084E00EB10 -:1049F000400506F8350006EBC5056A610022E9604E -:104A00002A74C5E90132411C217070BD00260020C6 -:104A10001C61002008490A4B421808499A4209685B -:104A200008D801F44001B1F5000F03D10549096828 -:104A3000496C0847704700BF5C8F82FFB44F00503D -:104A4000B71E0500F001001070B50B4D04462E187E -:104A500004F0D2FE96F84311013986F84311090695 -:104A600005D10121AA68A14022EA0101A96005F04F -:104A70007EF9002070BD00BFD81B0020B0B50546F0 -:104A800004F0BAFE044608480178A9430170007892 -:104A9000000704D405480821283005F04BFA2046C9 -:104AA000BDE8B04005F063B9D01E002070200020A2 -:104AB000F8B515460E46074604F09EFE0446084823 -:104AC0004068B84201D0032504E03046294601F091 -:104AD00011FB0546204605F04AF92846F8BD00BFFF -:104AE000D01E0020B0B50A4A931C0A4A147800224E -:104AF000944209D01D88854203D113F8025C8D428F -:104B000003D00A330132F3E72246D0B2B0BD00BF72 -:104B1000B25C0020D5BA02002DE9F04106460A48F1 -:104B200015460C4600278046BC4209D0D8F8002024 -:104B3000E95D30689269904708B10137F4E73C4677 -:104B40002046BDE8F08100BFD001001080B50948C3 -:104B50000078022802D24CF2101107E008D101209F -:104B6000F7F7C2F80449002808BF01310348018063 -:104B700080BD00BF242600202182FFFF007A002094 -:104B80001CB58269094913785278098943EA0222DF -:104B900011400AD0064A047C1388427CCDE90014F7 -:104BA000811C1046002200F0A7FE1CBD3E790020AB -:104BB0008879002010B50B4B0C0A5B6859700021F6 -:104BC0009C7019701178D970517800F11102197127 -:104BD000811C104648F203020523BDE81040FAF795 -:104BE0007BBC00BF882600201FB5044600208DF83E -:104BF000000068462146043005F031F904F06EFBF0 -:104C000000B11FBD6846F6F743FD0128F9D00DF14C -:104C10000E020020214601F033FB1FBD10B50A49EA -:104C20000122087A0A7209494C6944B122684A6132 -:104C3000FEF7F2FE2046BDE8104001F079BBBDE86A -:104C40001040FEF7E9BE00BF38220020A01F002060 -:104C500080B50B4A0146106878B143681B788B42D7 -:104C600005D0024600680028F7D1022080BD016807 -:104C7000116005F047F9002080BD012080BD00BF14 -:104C8000247A002010B5A1F1FE020A4BB2FA82F29A -:104C900054091B6853B1DA888242FAD11A79E407C1 -:104CA00005D1521AB2FA82F25409F2E7FE221046F6 -:104CB00010BD00BFF826002070B586B001AC1421ED -:104CC000FF22204604F0D4FF074800260578AE42B4 -:104CD00024BF06B070BDF1B208201422234601F0B3 -:104CE000B3FC0136F3E700BFC9BA02001FB50146A5 -:104CF00004208DF80000087A022806D10888ADF853 -:104D000002006846F4F7B0F906E06C46201D04F096 -:104D100064FC2046F6F7BCFCBDF80C0004B010BDE6 -:104D20000849094A096852F82130034442F8213001 -:104D300006498A6801328A6005490A681044086099 -:104D4000EFF702BB187A002060730020B82400201F -:104D5000207A00207CB504461630C0B2092810D84D -:104D6000084EB068D0F8282401AD20462946904767 -:104D70000198294601300190B068D0F830242046CF -:104D800090477CBD0C01002010B50B4CE068816998 -:104D90000978022907D1C168097821B1A068D0F843 -:104DA0004C058047E068C168097819B980690178C5 -:104DB0000229FCD010BD00BF0C01002009480021D1 -:104DC0000122C1814175084942820978017507496C -:104DD0008968D1F8D41091F8242091F83110017429 -:104DE00042747047B8750020B97A00200C01002089 -:104DF00010B50A48FE210A4C4170A068D0F8E800BE -:104E0000006848B1E0680121C068017003F0D4FB7C -:104E1000E0680021C068017010BD00BF242500209B -:104E20000C01002080B50A480021017001F072FBDE -:104E3000F7F7E2FA0748C168C968097801B180BD8F -:104E400080680021D0F858240020BDE88040104739 -:104E5000B17A00200C01002007480849084AC0E93F -:104E600004210849084AC0E9082140F20551C183DC -:104E7000F721C173704700BF007200201079002035 -:104E8000D879002020770020F873002070B50B4CF3 -:104E9000094B022A254608BF1D4601262D6806FA41 -:104EA00000F009B1284301E025EA0000022A14BFFE -:104EB0002060186070BD00BF20770020F8730020CC -:104EC00070B50B4C094B251D022A08BF1D1D01267C -:104ED0002D6806FA00F0002925EA000618BF45EA09 -:104EE0000006022A08BF1C46666070BD20770020BD -:104EF000F873002010B50B4CE068C068007828B942 -:104F0000A0680021D0F858240120904704F074FCD8 -:104F100004F02DFFA068D0F8B800806EBDE8104006 -:104F2000004700BF0C010020B0B50D460446FFF756 -:104F300067FAA84205D308488068D0F8E000006806 -:104F40000544054865608068D0F8DC10D0F8EC2492 -:104F50002046BDE8B04010470C01002010B50B4CB6 -:104F6000A268D2F8E030D2F8EC2052F82110196093 -:104F7000A268D2F8E4201160FEF7E6FBA068D0F842 -:104F8000E0000068BDE8104002F0BEBB0C0100204C -:104F900010B58EB00C4691B1014601AA2046ECF73F -:104FA0001DF99DF80A0050B19DF805209DF82030AC -:104FB0000020214603F0F6F908B1A42000E000200B -:104FC0000EB010BDB0B5024609484FF6FF74037825 -:104FD000084801E01C30013B43B105889542F9D1F6 -:104FE00045898D4218BFA142F4D1B0BD0020B0BDAB -:104FF000D1BA020030560020B0B50146094800235E -:105000004FF6FE74027808484AB10588A54203D0DD -:10501000DDB28D4204D001331C30013AF4E70020A8 -:10502000B0BD00BFD1BA020030560020F8B50D4621 -:105030000A4904460848097802304E1C013E09D04E -:10504000294600F11C0702F088FC00283846F5D0FC -:1050500027F81E4CF8BD00BF30560020D1BA020020 -:1050600080B5042000F098FD08490978884284BF83 -:10507000012080BDFF2000F08FFD0146044802782A -:105080000020914288BF012080BD00BFE0BA02002D -:10509000E1BA020080B540F2011000F091FF02F089 -:1050A000AFFD0748007808B1012807D1054800780E -:1050B000012803D1BDE88040FAF72AB880BD00BFBF -:1050C00024260020CA270020B0B50B4A0023156C07 -:1050D000946CC0E901452A7841B1BE2A06D1691C09 -:1050E000631C11F8014B013BBE2CFAD00360B2F1F6 -:1050F000BE0018BF0120B0BD381F00200B4890F83B -:10510000641001B17047012180F864102021EFF391 -:10511000118281F311884FF0FF31C162016C826C02 -:1051200021F0070111440839C1637047381F00207E -:10513000B0B504468260816100201D462075D3E928 -:10514000010120610648E161214603F0B3FA2878A5 -:1051500020B12046BDE8B04003F033BEB0BD00BF73 -:105160000820002070B50B4AD368C56C84696E684E -:1051700023430560466030606860D360012380F897 -:1051800020301374202081F31188EFF3118180F314 -:10519000118870BD38220020BFB50A4C1C34A042D3 -:1051A00008BFBFBD01AC0028089D18BF04460648D3 -:1051B00084E82C0050F8210003F038FD2046FFF76A -:1051C000FFF9FEE7A01F002064BA020070B50B4C87 -:1051D0000B460021CDB234F8356076B101318642FC -:1051E000F8D104EBC5004188994206D140681146C8 -:1051F0001A46BDE8704004F029B970BDFCA6020053 -:105200000A48083880F308880948016841F47001A9 -:10521000016000BF00BF04F0A1FE08B1FFF7ECF988 -:1052200003F01EFF002004F089FD00BF00400120B4 -:1052300088ED00E0B0B5A0B10546007A00F0FE00B0 -:1052400002280ED128461446F3F77CFBFF2808D02D -:10525000002C2A7A18BF01242146FFF731FE0020D6 -:10526000B0BDE820B0BD10B52021EFF3118481F36B -:105270001188017C02290CD10268816843681A6098 -:105280000022027442680068426008462146FFF727 -:1052900069FF84F3118810BD1CB5ADF806100949EB -:1052A0000C6864B10DF10601009111461A46012304 -:1052B000A0470021002808BF6FF04D0100E0B62193 -:1052C000C8B21CBDF023002070B54E8B0C460546BD -:1052D00004F0C8FA864203D02846FAF72BFC30B116 -:1052E00004482146C2682846BDE8704010470120A6 -:1052F00070BD00BF50240020B0B50C46054603F039 -:10530000FBFD0146284602F028FB20B10548C08A73 -:1053100020800120B0BD28462146BDE8B04000F005 -:1053200012BD00BFA86D002010B5F8F727F9054899 -:105330000549064A064B074CC0E90143C0E9032171 -:1053400010BD00BF2C2400209DD30000FD7401007F -:1053500001610100B13B02007FB54FF0FF30094E03 -:1053600000250390CDE9010001AC3088854228BFBB -:105370007FBDA9B201200C22234601F065F9013559 -:10538000F3E700BF402600207FB54FF0FF30002636 -:105390006C46CDE90200CDE9000006480578AE4232 -:1053A00028BF7FBDF1B203201022234601F04CF943 -:1053B0000136F4E7E3BA020080B5084890F82810F7 -:1053C00001B180BD012180F8281004F071FB044870 -:1053D0000021FEF7C7FA0349486080BD381F00204E -:1053E00094760020A01F002080B50A49142004F004 -:1053F000BBFC1420002103F089FF012004F0C0FC55 -:105400001420012103F082FF4FF40C70BDE88040AE -:1054100004F0B6BC01640020BFB5044653B10020BF -:105420000190D3E901051B7803958DF804300290B3 -:1054300001AB00E0034B2046FFF77AFE204604B0A4 -:10544000B0BD00BFCCB90200FF2808BF7047B0B59F -:105450000D46044604F0D0F90649C5F3024311F89D -:10546000242002F0F8021A4401F82420BDE8B040DC -:1054700004F07DBC0210084010B501460848002326 -:10548000027808484AB10478FF2C03D0DCB28C4281 -:1054900004D001330E30013AF4E7002010BD00BF04 -:1054A000DFBA02003079002080B503460848007852 -:1054B00058B908481978007801B908B929B120B954 -:1054C0004520CB210122FDF75FF9002080BD00BF00 -:1054D000A527002004250020BFB50446082234F883 -:1054E000020BADF8040001AD2146A81C03F0AEFF8D -:1054F0002089CA210C222B46ADF80E004520FDF76D -:1055000043F9002004B0B0BDB0B50D46044604F028 -:1055100025FC80B101790139C9B203290BD8012DCD -:1055200018BF012902D8008804F0F8FC2046BDE825 -:10553000B040F9F711BDB0BDBCB5044605200D461D -:105540008DF8050001A801F0CBFA58B10169220AD3 -:10555000CA7041F203320D718C700A804480F9F7F1 -:105560004BFABCBD0120BCBD10B504F04EFB044697 -:1055700007480021202200230180064988680C3159 -:1055800002F0A7F92046BDE8104004F02CBC00BF93 -:10559000702600204823002010B5044601F098FE34 -:1055A000A0420BDDA0B2FAF79FF9054801218171F5 -:1055B00004480068BDE81040F9F748B8FEE700BFAE -:1055C00044250020507A0020F8B50A4F06460D46C3 -:1055D0004FF0FF311446386804F030FB304629465E -:1055E0002246F4F70BFE0446386804F09FFC204680 -:1055F000F8BD00BFDC250020F8B50A4F06460D4671 -:105600004FF0FF311446386804F018FB3046294645 -:105610002246EDF771FC0446386804F087FC20460A -:10562000F8BD00BF0C24002070B5094A1378322B56 -:1056300004BF012070BD074E046803EBC30540683A -:10564000013313707219745150600020117270BDD3 -:105650009E270020F05A002010B586B06C46162117 -:10566000A01C04F05BFB02208DF808000548418B6C -:10567000808CADF80A002046ADF80010FDF7CEFF93 -:1056800006B010BDA86D002070B514460D46064644 -:1056900004F0BBFA3168A94218BFA4F10C0655F812 -:1056A0000C1C3160FF2105F8021C002145F80C1C80 -:1056B000BDE8704004F097BBB0B50446012000FA85 -:1056C00004F504F099F807498A682A438A6021445E -:1056D00091F84321013281F8432104F048FB002076 -:1056E000B0BD00BFD81B00200A484068826800F1A6 -:1056F0003801134652680AB18A42FAD1597B090728 -:1057000006D1408F40F60901884204BF012070474E -:1057100000207047D01E002010B550B90020F6F7C9 -:10572000E3FC04464FF6FE70844206D1054800783B -:1057300018B10020F6F7D8FC0446EFF71BF9204615 -:1057400010BD00BFE4BA020010B50A4B0749084A71 -:105750001B780439013A43B112F8014F013B04317F -:105760008442F8D100200860107010BD306D002018 -:1057700058760020CEBA0200B0B514460D46F7F7B1 -:10578000F9FB07490978884224BF0420B0BD0549C8 -:1057900001EBC00041782970406820600020B0BD56 -:1057A000D7BA0200503D002007480068C00608D460 -:1057B00006480749006808400649884204BF01209E -:1057C00070470020704700BFB04F0050501300508A -:1057D00000C4FF3F00C0071CE0B5B0F90E1000295F -:1057E00001D4027B02B18CBD89B21329FBD0037CAA -:1057F000427C41F40041CDE90013811C1046842213 -:10580000002301F049FA8CBD09498A78920703D533 -:10581000084A1278824200D170470C2088700888AC -:1058200040F0020020F0050008800C2002F012BDBC -:105830003E790020E8270020B0B5094CE17809B195 -:10584000C17801B1B0BD40780028FBD105480025E2 -:10585000A0F870500120F5F7F3FDE570B0BD00BF72 -:10586000CC240020A86D0020B0B585690C46042129 -:10587000284600F083FF206028790528207102D88F -:1058800068796071B0BDFE2805D36979FF28A171E0 -:1058900004BFE8882081B0BD80B508490870084978 -:1058A00009780843000602D1062002F079FA05487B -:1058B00020210078BDE88040F8F728BCBF7A00209E -:1058C000D02600209D7A00201FB50A4BADF80400B9 -:1058D0005C68A170010A20700220E27001228DF83C -:1058E0000C006170184601A90423F9F7F5FD04B016 -:1058F00010BD00BF88260020BCB50A4C8DF80700FB -:105900000DF1070063681A70069A150A5A70102282 -:105910009D70A27048F215020323F9F7DDFD002106 -:10592000A170BCBD8826002010B500220A60094A7B -:1059300012686AB16FF017039C1D09D013441B8BCA -:1059400083422346F8D1101912300860002010BDA0 -:10595000C82010BDEC260020B0B588B004AD0446C8 -:1059600069461022284603F03BFF06482946006896 -:1059700004F0E6FA05992046102203F067FD08B00E -:10598000B0BD00BFF479002070B50546142016465E -:105990000C4604F0B9FA58B1064901230661846047 -:1059A00083734FF499730A688381C0E90025086006 -:1059B00070BD00BF247A00200749087007490978A4 -:1059C00031B9074991F82F1011B1064902220A7026 -:1059D00048F20201FBF798B8A37A002024260020A1 -:1059E000AC220020BC27002070B50A4E084C0025D0 -:1059F000042130782570F9F7F5FF30780421F7F7A6 -:105A000053FE84F82B500020BDE87040E4F72EB818 -:105A1000AC220020A37A00207CB50A4E0446062062 -:105A20008DF807002046318903F0C3FB0DF1070014 -:105A30000121FAF727F931890546204603F0C2FB18 -:105A400028467CBD0C24002080B50A4842F204415F -:105A50004088884206D042F2034188420CBF0020B1 -:105A6000E92003E0012000F081FD1B20BDE880401B -:105A7000ECF752BE4878002010B50A4A12687AB195 -:105A8000137883420CD854781C44844208D9C01A35 -:105A9000526891F90040C0B210568442C8BF0870E5 -:105AA00010BD00BF647A002078B110B50169074CC1 -:105AB000206029B906488068D0F84C0580472068E6 -:105AC000406804490860BDE810407047607A0020D3 -:105AD0000C010020347A002080B503F08DFE0849C7 -:105AE0000A7842F002020A7004F041F905480021E8 -:105AF0008068D0F894000078BDE88040F8F706BBD5 -:105B0000907A00200C01002008480021017008480C -:105B100001700848C168C968097801B17047806898 -:105B20000021D0F858240020104700BFB87A002088 -:105B30002D2600200C010020B0B504460948056858 -:105B400055B1A868204205D0D5E90332204600218E -:105B5000984718B92D68F3E70020B0BD4FF0FF302B -:105B6000B0BD00BFD81B002010B50446094800682E -:105B700020B130F8041BA142F9D110BD082004F077 -:105B8000C3F90028F9D0034904800A68086042601C -:105B900010BD00BF4C27002010B5A0F1FF02094B3B -:105BA0000021B2FA82F252091B6843B15C7B0433D4 -:105BB000241AB4FA84F4640914432144F4E7C8B203 -:105BC00010BD00BF587A0020F8B580B105460948DD -:105BD0000C4600260168374651B10E46084621465C -:105BE000A84700210128F6D0301D3E46F2E70027E5 -:105BF0003846F8BD587A0020F8B5094D094E2C6892 -:105C00005CB1D4E90007006AB0472068B04760691A -:105C1000B0472046B0473C46F2E700202860F8BD78 -:105C2000587A0020059F020010B50A4A00F11C01B5 -:105C3000007C0023927883420AD2140608D011F81F -:105C4000334004F08D04812C08BF013A0133F2E7A0 -:105C5000D0B210BD5026002010B50A4A00F11C0138 -:105C6000007C0023527883420AD2140608D011F82F -:105C7000334004F00D04012C08BF013A0133F2E770 -:105C8000D0B210BD502600207FB51346D0E90A24BB -:105C9000BE251AB104F8015B013AFAE7D0E90A54CB -:105CA000D0E90D26C06BCDE900160290291F2046D1 -:105CB000F7F7B6FF04B070BD10B50A4B2022EFF322 -:105CC000118182F311889A6B002A04DC5C6B44F822 -:105CD0002200501C9863002081F31188012AB8BF6C -:105CE000012010BDA01F002070B50A4D04462020E1 -:105CF000EFF3118180F31188A86B461E701C0128F8 -:105D0000B8BF70BD686B50F8261020468847013E2A -:105D1000F4E700BFA01F00207FB56D46ADF802007C -:105D200000260C4628468DF80060F3F79DF9291DE2 -:105D300007BF66602660204604F091F8204602F016 -:105D4000BDF904B070BDBFB50C46014600206D46DC -:105D50008DF80000281D03F040FC2846F5F798FC5C -:105D6000BDF802004FF6FE712080401A18BF0120D6 -:105D700004B0B0BDBFB5044600880DF1050508228A -:105D80006168ADF80500A81C03F060FB217A0B22C6 -:105D90002B4601704520C821FCF7F6FC002004B01A -:105DA000B0BD10B504460E2004F0AEF878B1A16B7A -:105DB000D4F83E200160426094F84210017294F8D9 -:105DC0004A1001736188418194F84910417310BDF4 -:105DD000B0B50C460546F9F72FFE291A04F57A727C -:105DE000C4EB9100012898BF01200023B2EB910F72 -:105DF00028BF1846B1F1404F28BF1846B0BDB0B516 -:105E00000C46054603F0F8FCD5E901122B69A242C5 -:105E100038BF1446121BAA601A19B2FBF1F303FB38 -:105E20001121296103F0A3FF2046B0BDF8B50C464F -:105E3000054603F0E1FCEA6895E8C2000132B2FBD6 -:105E4000F6F303FB16252944216003F090FF701B35 -:105E5000F11B814238BF0846F8BDF0B54FF0000C89 -:105E6000844504BF0020F0BD1D4616464EB131F8F2 -:105E70001C7035F8024B013EA74204BF0120F0BD63 -:105E8000F4E70CF1010CEBE770B514460E4605463D -:105E900003F0E8FC03F0E6FC0B2E0CBFA84270BD3B -:105EA0002046002101F011F9204600211E22BDE804 -:105EB0007040E8F74BBD2DE9F0414FF6FE780C46F7 -:105EC000054608F1010728462146FFF77BF838B15F -:105ED0001C21064603F022FF7781A6F80080F2E736 -:105EE000BDE8F08140B10246074800210170074833 -:105EF0000221007803F06EBF0348012101700348BE -:105F000002210078F9F76EBD2C240020997A002038 -:105F100080B5AB2807D0A1281CBFB52080BD108854 -:105F20000549088004E003481146006803F097FF24 -:105F3000002080BDEC5800209670002010B504466B -:105F4000062001F0FBF960B10146082008702088A6 -:105F50004880A078087103480078BDE81040F9F740 -:105F600003B910BD9D7A0020B0B50848084C0578EB -:105F700005EB45004100204603F0D0FE4FF6FE70D1 -:105F80001DB124F8060B013DFAE7B0BDA1270020A2 -:105F9000B45F002038B1024607484161074801213B -:105FA000007803F017BF0448002141610348012134 -:105FB0000078F9F717BD00BF2C240020997A002043 -:105FC000B0B5094D288060B100EB4000800084B27C -:105FD000204603F099FF686028B1214603F09EFE39 -:105FE000B0BD00206860B0BD40260020094983791B -:105FF000CA7A2BB15AB98078B0FA80F0400970475C -:106000002AB1C98A4089401A18BF01207047002070 -:10601000704700BFA86D0020B0B50546084800785D -:10602000012888BFB0BD28460C46F1F7E5FB4FF6C6 -:10603000FD7029460D222346BDE8B040F5F701BFAB -:1060400024260020084800F11801084802780020A2 -:10605000824205D00B78FE2B03D00C310130F7E7DC -:106060001046C0B2704700BFB87200209B7A002073 -:106070001CB56FF0D24401948DF806100421ADF8E0 -:10608000042001AA01EB8301042389B2FDF734FF48 -:10609000014908701CBD00BFA0230020B0B507480F -:1060A000074D04782CB155F80C0B00698047013C72 -:1060B000F8E7044801210170B0BD00BF8DB90200AE -:1060C00028B70200AB27002006480122017A02729D -:1060D00005480160054890F8481080F848200448B9 -:1060E0000160704738220020F0790020A01F0020B6 -:1060F000EC79002010B50C460849097E02290AD126 -:1061000001F02EFD04B12060C1B20220012908BFB8 -:106110006FF07E0000E00120C0B210BDD01E002054 -:1061200010B50848084900224FF6FE730024007895 -:10613000844228BF10BD8A718A804B8021F8083BB9 -:106140000134F5E7D6BA02004C50002010B50748DC -:10615000002403210460064801600220FEF774FC5D -:106160000720F0F723F80348447010BDA8025042FE -:106170001080024018230020F8B50C46D0E9001624 -:10618000002701F14C053068013C47F100018269AC -:10619000D20606D429B10068C1B22846FBF7E4FC58 -:1061A000F1E7F8BDD0E900100A6C5AB191F844103B -:1061B000090707D501684FF480624A648A6B42F48C -:1061C00080628A630068816B41F04001816370479F -:1061D000FEB5074609981C4615460E46FFF714FB08 -:1061E000054831463A4683780898CDE9004028466C -:1061F000EDF7E0F9FEBD00BF3E79002010B5044682 -:10620000062001F09BF858B1014631200870206843 -:10621000C1F8020003480078BDE81040F8F7A4BFB9 -:1062200010BD00BFCC240020F8B5094F06461C461F -:106230001546786803F0D1FD447005703846314644 -:106240003022062301B0BDE8F040F9F745B900BFA0 -:10625000882600204FF6FE73984218BF002901D10E -:10626000012070479A42FBD0F8B5ADF80C2002919E -:10627000ADF8040001A8F1F705F8002004B080BDD6 -:10628000BFB5ADF8020002206D4614468DF800003F -:10629000281D03F0A2F92846EBF7F0FBBDF80C101F -:1062A0000138218018BFC82004B0B0BD80B502F00D -:1062B0009DFB08480078012804D038B9BDE880402B -:1062C000FEF770BABDE88040FEF7A0BABDE8804096 -:1062D000FEF782BA2426002010B50446EBF744FCF2 -:1062E0002046FCF7F1FB2046EFF7A2FC04480078BB -:1062F00000B110BD2046BDE8104000F0A8BA00BFB4 -:106300002426002080B5E22806D1084A0846114616 -:1063100003F0A5FD002080BD034A9268D2F828242E -:10632000BDE88040104700BF0C010020B679002076 -:1063300010B50446103001F053FA204650F80C1FF7 -:1063400009B101F07DFE04482146502240684368AF -:10635000BDE81040184700BFA01F002070B50446DC -:1063600008460E4602F0A2FB30B1826832B101202D -:1063700031460125904704E0002001E04068806834 -:1063800000252060284670BD18B105200121DEF7E8 -:1063900035BA0748417831B1016A21B10021417015 -:1063A0000020F8F76BBC05200021DEF727BA00BFFC -:1063B000AC22002010B5084900220B78074993420F -:1063C00005D00C78FF2C04D00E310132F7E7002104 -:1063D000FF220270084610BDDFBA020030790020AB -:1063E000094908480A780530002142B110F8053CF7 -:1063F000FF2B1CBF037819440E30013AF5E788B231 -:10640000704700BF30790020DFBA02007FB5ADF8D9 -:106410000C0004206E460C468DF800003046F9F75B -:10642000A7FD054628B10320311D2072204603F048 -:1064300016FD284604B070BD10B5084CA16829B1FE -:10644000074909680844EDF77FFF08B1012010BD36 -:10645000E068013038BFE060002010BDB8240020A3 -:10646000207A0020084A002800F0010118BF01200E -:10647000138843EAC01010800448028B22F0800287 -:1064800042EAC111018370470079002000720020A8 -:10649000B0B5044603F0B0F9054600F03BF80548F6 -:1064A00044860548C481284603F061FCBDE8B0403D -:1064B00002F026BE007200200079002010B5084CC2 -:1064C0000121E068C06801700648FE210170F5F7FF -:1064D000CBFF01F0F5F8E0680021C068017010BD45 -:1064E0000C0100202425002010B5074C6078FE2800 -:1064F00009D006480068826B0548006894F90110CD -:106500009047FE20607010BD24250020347A0020C2 -:10651000E426002080B508488068D0F8B8000078EC -:10652000B0FA80F04009FDF74FFF0448017811B13F -:1065300001780139017080BD0C0100202B2500205D -:1065400010B5044620B907488068D0F84C0580474C -:1065500003F052F904490A78A2430A70BDE81040DA -:1065600003F005BC0C010020B17A002010B50446F0 -:1065700020B907488068D0F84C05804703F03CF903 -:1065800004490A7822430A70BDE8104003F0EFBBCB -:106590000C010020B17A0020B0B50546084880689B -:1065A000D0F8D84003F028F924680CB1AC42FBD1F4 -:1065B00003F0DDFB002C18BF01242046B0BD00BF56 -:1065C0000C01002098B110B5044601F0C1F8206814 -:1065D000006A03F097FC206803F094FC606908B13E -:1065E00003F090FC2046BDE8104003F08BBC7047E0 -:1065F00010B50848084A4FF6FE730178002031B103 -:1066000032F81C4B9C4218BF01300139F7E780B2C9 -:1066100010BD00BFD1BA020030560020BCB5094CF5 -:10662000246864B1E46954B10004069D013000950A -:10663000A04701460020012908BF0A20BCBD0A204E -:10664000BCBD00BF6827002010B5094C24686CB1A0 -:1066500064695CB100040130A04701460A200A29A0 -:1066600008BF0920002908BF084610BD002010BD42 -:1066700068270020B0B5044602F084FA074D297857 -:10668000884202D36868FBF76DFEE878207101301C -:10669000E870204601F074FC2079B0BD502600203F -:1066A00010B52020EFF3118480F3118805480068AD -:1066B000006B8047044AD2E9102384F3118802F06A -:1066C000C5FC10BD8C010010886E002070B504461A -:1066D0002020EFF3118580F31188207D40B1E6681A -:1066E000FFF7DEFF216A301A884288BF002000E0F1 -:1066F000002085F3118870BD4A1C08BF05212022A7 -:10670000EFF3118382F3118801228A40C0E9081255 -:10671000034AD26D02EBC101416383F311887047D4 -:10672000A01F002000B1704710B5074C207C28B195 -:10673000064890F8480008B9FBF7F2F900202072EB -:10674000BDE81040704700BF38220020A01F002085 -:106750007178CDF8248006940797CDF80CB002909C -:106760000D208DF8280000988DF8290030785844C5 -:1067700008444946CDE904007047704701390329B0 -:1067800084BF4FF0FE307047DFE801F0020B0409D0 -:10679000007870478178008840EA014070470068BF -:1067A00070470088704781B14A6872B10A78042A3C -:1067B0000BD18A684AB102680023916153624B6829 -:1067C000D36189689162EAF7F9BE6FF00200704701 -:1067D000B0B5056802200C46FEF736F964B1D5F86D -:1067E000EC000021B1EB107F06D10420FEF72CF95C -:1067F0004FF0FF30C5F8EC00B0BDF8B50DF10E015B -:1068000000F010F860B902208DF80000BDF80E000D -:10681000ADF80C006846FEF713F8013818BF0120E8 -:1068200004B080BDBFB50C46014602206D468DF810 -:106830000000281D02F0D1FE2846F4F729FFBDF81C -:106840000C100138218018BFC82004B0B0BDBFB5FE -:106850006D4604462846FFF77FF840F201101021EC -:106860002A4603F02BF934B128B96A4640F20110E8 -:10687000102103F029F9BFBDCA071CBF0122027015 -:106880004A0744BF01224270CA0644BF0122C270B7 -:106890008A0644BF01220271C90544BF0121C171AA -:1068A000704710F1140F45F6A611A8BF6FF0130042 -:1068B00010F15A0FD8BF6FF05900C0EB0020084408 -:1068C000462180B2B0FBF1F0C0B2704710F1140F56 -:1068D00045F6A611A8BF6FF0130010F15A0FD8BFEC -:1068E0006FF05900C0EB00200844462180B2B0FB95 -:1068F000F1F0C0B27047B0B50C46054600F0F8FAAA -:1069000068B100F11B01007C0022824207D211F81D -:106910003230AB4208BF01F832400132F5E7B0BD7A -:1069200070B50446006C04F144052CCDA0FB0106B3 -:1069300002FB0161C6184D41300C002240EA0541BE -:10694000FCF7F2FFC4E9146570BD81B040F2000CA1 -:10695000EFF311808CF3118800200090009810B99B -:1069600000980130F9E72020EFF3118180F31188BE -:1069700001B07047E0B500200DF1070201218DF84C -:106980000700032003F09AF830B90DF10703032044 -:106990000021012202F0F0FB9DF807008CBD70473A -:1069A00010B5084B1B6853B1DC79844205D19C8833 -:1069B0008C4202D19C79944201D00C33F2E7184604 -:1069C00010BD00BF6C530020084980890A8890429E -:1069D00024BF00207047496800EB400011F82000F8 -:1069E00010F00F0018BF0120704700BF40260020A4 -:1069F0000849486809880131013904BF01207047FE -:106A000000F10C0200780007104604BF0020704718 -:106A1000F2E700BF402600200146074802780748F9 -:106A200042B10379042B02D80B0404D00139013A96 -:106A30002430F5E700207047E3BA0200204500202B -:106A400080B50648006938B1054802F0D1FF054815 -:106A5000BDE8804002F0D2BF80BD00BF381F0020DB -:106A6000C98102006D880200B0B50D46044602F0EF -:106A7000C3FED5E9001211B14A606A6800E06260A5 -:106A8000002A18BF14462160BDE8B04003F06FB97A -:106A90001CB500200DF10204064905228DF8020004 -:106AA000601C02F0D3FC4120802106222346FBF724 -:106AB0006BFE1CBDF0B902001CB50446042001F0B9 -:106AC000DDFF20780DF10303C62105228DF80300B8 -:106AD000D4F8020001904520FBF756FE00201CBDB3 -:106AE000B0B50125382185700170FCF76BFA0446BA -:106AF00028B1A577257002F0FFF9024860622046B0 -:106B0000B0BD00BFE079002080B508484FF6FE72A6 -:106B1000C18A914202D0807B800700D480BDEDF70E -:106B2000E9FFBDE88040E4F78FB800BFA86D002002 -:106B300080B5FEF739FE60B10648006881034FEA70 -:106B400000414FF0000058BF0816BDE88040FDF737 -:106B500067B880BDB44F005080B50648064900684C -:106B600008400649884204D1F9F752FE1328C8BFED -:106B700080BDFEE71813005000F0FF0F0010B40BAB -:106B8000202918BF704710B503F03FF804460548A8 -:106B9000426812B14188002090472046BDE810406D -:106BA00003F021B97026002010B50446064800689D -:106BB0002060064840686060F8F7FAF9083838BF86 -:106BC0000020A06010BD00BF1C6E00200026002029 -:106BD000B0B50C46054603F018F84CB1002144F856 -:106BE0000C1C296819B10D4655F80C1DFAE72C60EC -:106BF000BDE8B04003F0F7B8B0B502F0FDFD0446C3 -:106C0000064890F8380118B100F0AAFB054600E0EC -:106C10000125204603F0ABF82846B0BDD81B002064 -:106C2000F8B51D461646044602F0E6FD44B104F1EF -:106C3000200720348ECF33432F432A4331438EC461 -:106C4000BDE8F84003F093B880B5084A0020012160 -:106C50001070852002F032FF00B180BD034B85200B -:106C600000210122BDE8804002F086BA9E7A002011 -:106C70001CB504460020019001A9204602F047FD02 -:106C80009DF8040000B11CBDBDF806004006FAD511 -:106C9000608801F0E7FE1CBD1CB5084C8DF80700AC -:106CA0000DF10700646822701A0A63700423A27051 -:106CB0000022E270049AF8F70FFC1CBD8826002021 -:106CC00070B5084E05461446706803F0C8F8706841 -:106CD00029463522092304723046BDE87040F8F792 -:106CE000FBBB00BF8826002010B50446074800788B -:106CF00010B102F0F3FA20B12046BDE81040F2F7DF -:106D00009BB82046BDE81040F1F7B4BC2426002013 -:106D100010B5084A126842B10023032B05D014882D -:106D2000844204D006320133F7E7C82010BD0020AA -:106D30000B8010BDEC26002080B5002206490A70A9 -:106D400020B1012008700549087001E00348027075 -:106D5000FBF7D4FB012080BDA17A0020A07A00209F -:106D60001FB5418801B11FBD041D01A92046FEF7D2 -:106D7000C3FA0128F7D102F075FDADF80C000294BA -:106D800001A8F0F77FFA1FBD10B5084B1B6853B17F -:106D90001A79824218BFFF28F8D11A4632F8064FF6 -:106DA0008C42F3D100E00022104610BDF8260020EE -:106DB000084A92F82E10814202D1117801B1704731 -:106DC00010B9002182F82B1002F82E0F5520012156 -:106DD00002F07ABEAC22002006480021FF2201709A -:106DE0000549C96809690A7004494FF0FF324260D9 -:106DF0000A607047582600200C0100202C7A0020E1 -:106E000010B5044620B906488068D0F84C05804784 -:106E10000448017821430170BDE81040F6F77AB9C3 -:106E20000C010020B17A00200748002101700748BA -:106E3000C168C968097801B1704780680021D0F83D -:106E400058240020104700BFB17A00200C01002018 -:106E5000B0B50C460546FDF7D3FA204468600548F6 -:106E60008068D0F8D810D0F8EC242846BDE8B040AF -:106E7000104700BF0C010020084A0021032904BF6D -:106E80000020704702EB81035B88834202D112F835 -:106E900021300BB90131F1E7012070474C79002016 -:106EA000084A002818BF021D106848B1428912051F -:106EB00004D529B1026812888A4201D0021DF3E785 -:106EC000704700BF587A0020084B002818BF031DE8 -:106ED000186848B1437B8B4204D12AB10368DB892F -:106EE0005B0701D5031DF3E7704700BF587A002008 -:106EF00010B508490431096849B10A7C00239A4257 -:106F0000F9D001EBC3040133E47E8442F7D1084693 -:106F100010BD00BF5026002010B500F11B03007CFF -:106F200060B113F8084B01388C42F9D113F8070C03 -:106F3000104303F8070CA3F10D0010BD002010BD95 -:106F400010B58AB001AC06492022204603F002F8B1 -:106F5000044809902046E8F76DF80AB010BD00BF5C -:106F600094BB0200982600201EF0040F14BFEFF31C -:106F70000980684685462DE9F00F684671467446DB -:106F8000024A904768462146FEE700BF9D950200F1 -:106F900010B5418203461430012100249861C3E9F1 -:106FA000024111781974586102481946BDE8104031 -:106FB00001F080BBB0260020084890F8641001B1B1 -:106FC0007047012180F86410C06D00213029F7D08E -:106FD0004218526042500831F8E700BFA01F00205D -:106FE0002DE9F04F2DED108BC0F800D0D1F800D076 -:106FF000BDEC108BBDE8F08F00BF00BF00BF00BF2D -:1070000000BF00BF00BF00BF10B504460748002AFC -:1070100008BF02462046EFF761FE20B10146204638 -:10702000EEF7DAFA0024204610BD00BFF0B50200EA -:10703000084890F8381001B17047012180F83810E5 -:10704000006A00213029F7D04218526042500831BE -:10705000F8E700BF3822002070B514460D460646FA -:1070600002F0CAFB6168C5E900416168002918BFE8 -:107070000E4635606560BDE8704002F078BE10B520 -:107080000446022001F0FAFC032001F0F7FC002086 -:10709000EDF7C2FF4520C72101222346FBF774FB11 -:1070A000002010BDB0B5054602F0AFFD2C6844B11C -:1070B00054F80C1C2960FF2104F8021C002144F83C -:1070C0000C1C02F090FE2046B0BDB0B50D4600216C -:1070D0000024FAF70DFA2946F2F750FF28B16FF0B5 -:1070E000011184718480016000E004242046B0BD59 -:1070F000B0B5056802200C46FEF7DEFA54B1D5F8AB -:10710000EC000021B1EB107F04D10420BDE8B040B9 -:10711000FEF7D2BAB0BD0068C168490701D58168E1 -:10712000FAE70221C0F88010C168C90702D1D0F87F -:107130008C10F9E70021C0F88010704770B5044644 -:107140001C2015460E4602F0DFFE48B100210673F2 -:107150004581A0F80D10C17301814161C0E9004172 -:1071600070BD80B502F098FC00B180BD0020012107 -:107170000022FFF7A9FE0028F7D001680029F4D00B -:10718000BDE88040EBF772B970B50446182000EBFB -:10719000C405681802F0B8FE064630B130462946EC -:1071A00002F0BCFD70193474F060304670BD027A94 -:1071B0000B7A9A420AD1032A0AD0022A06D10988F8 -:1071C0000088401AB0FA80F04009704700207047EC -:1071D00000F0C3BBF8B54189ADF8041041684A78A6 -:1071E0008DF8062089788DF80C100AB9407A10B114 -:1071F00001A8ECF74FFC8FBD10B50648006940B1FF -:10720000054C204602F0F4FB2046BDE8104002F099 -:10721000F5BB10BD381F002027400100B0B50C465B -:10722000054602F0E9FA00212160696800296160E1 -:1072300008BF29460C606C60BDE8B04002F097BD05 -:10724000B0B50C46054602F0D7FA00216160296806 -:107250000029216008BF29464C602C60BDE8B04081 -:1072600002F085BD012918BF704710B50021044602 -:10727000FFF72BFF0348002102782046BDE81040AD -:10728000E7F764BBCABA020070B50646064D04466D -:107290006FF39D06012002F073FDA8680642F9D045 -:1072A000A8682040286070BD8847024080B5054826 -:1072B00001210068426801209047034803490068A3 -:1072C000486080BDE001001030200940F424002017 -:1072D000074841880088401A4FF4877100F587708D -:1072E00090FBF1F25143081A00F5877080B27047A5 -:1072F000C82600204FF6FF70814208BF704710B5C6 -:107300000C46E9F7F3FA0349E0B2BDE8104002F099 -:107310002BBD00BF0160002080B5074909688A794C -:1073200002B180BDC2680968407800F077FFBDE80F -:10733000804000F0F5BB00BFD826002010B568B132 -:1073400004460C30EFF730FB0146002029B1FF2244 -:10735000086001F10C000C818A7210BD002010BD84 -:1073600010B506483C21012200230068C468044887 -:10737000A047002818BF012010BD00BFA4010010C5 -:1073800000A00C401CB5064980B24FF47F42082390 -:1073900009684C68009003483021A0471CBD00BF1D -:1073A000A401001000A00C401CB5064980B24FF4A7 -:1073B000F802122309684C68009003480421A04792 -:1073C0001CBD00BFA401001000A00C401CB5064964 -:1073D00080B24FF40032112309684C6800900348D2 -:1073E0000421A0471CBD00BFA401001000A00C4058 -:1073F0001CB5064980B24FF440620A2309684C6804 -:10740000009003482021A0471CBD00BFA40100102C -:1074100000A00C4050B14AB110B5044608300EC06F -:1074200021460448FFF7FAFE002010BD6FF002006D -:10743000704700BFD81B002005480649C069884234 -:1074400008BFF6F7C7B904480421283002F072BD1E -:10745000D01E0020953700007020002080B54FF02E -:10746000FF3001F0A3FF800758BF80BD03484FF4F1 -:1074700000612830BDE8804002F05CBD7020002033 -:107480000648007E022804D10548816C09B9C06C09 -:1074900008B1002070470120704700BFD01E0020B7 -:1074A0003021002070B5144600220E46054600F03B -:1074B00041FFFF2807D02B2E18BF40F22B2646EAAB -:1074C000842145F8201070BD10B586B08DF80410E9 -:1074D000024601AC1146601C102201F0B7FF3B20B0 -:1074E0001121224602F0F0FA06B010BDF8B50021D5 -:1074F0000391CDE9011101218DF80410034901F137 -:107500001C0201A900F043FE04B080BDA01F0020B2 -:10751000B0B5074D044604212878FBF753FF00B1AE -:10752000B0BD287804212246BDE8B04002F052BC2C -:107530009D7A002080B502F06DFB42F21071084088 -:10754000421804484FF480410078BDE8804002F0C2 -:1075500041BC00BF9D7A002080B50648064902F074 -:107560007EFC00F0BDFAFDF7DFFEBDE8804000F0D4 -:10757000C7BA00BFAE790020A679002010B5034637 -:1075800006484468A2700A0A2170194603236270F3 -:107590000422BDE81040F7F79FBF00BF88260020F7 -:1075A0001CB50C46002121600DF10601FFF73AF9E8 -:1075B00008B1C8201CBDBDF806002146BDE81C402E -:1075C000FEF7B2B910B50446007801F06FFA08B1C1 -:1075D000022010BD204600210022FEF7D5F9B0FAA6 -:1075E00080F04009000110BDB0B5074B00221B68B8 -:1075F00043B11C798442FAD1DC88D5B2013221F83A -:107600001540F4E7D0B2B0BDF8260020E0B58DF803 -:10761000050006480121002203238DF8041000789C -:1076200001A900910A21FBF7ECFC8CBDA37A002094 -:1076300058B1074B42791B789A4206D2531C4371CA -:1076400000EB4200C180012070470020704700BF5E -:10765000CFBA020001684268054BC3F80720C3F89F -:107660000310044A01684068C2E90A10704700BF6D -:10767000007900200072002010B504460B38102855 -:1076800004D304488068D0F84C05804702488473CE -:10769000012010BD0C0100200072002010B504462E -:1076A0000B38102804D304488068D0F84C05804774 -:1076B0000248847310BD00BF0C010020007200203E -:1076C0000648017841F004010170054800218068F6 -:1076D000D0F894000078F6F719BD00BF907A00202A -:1076E0000C01002080B50648006838B1F2F740FA76 -:1076F00004480068BDE88040F3F7AEB980BD00BF24 -:107700003C7A0020407A002070B5074E044602F013 -:1077100073F8054620463460F2F72AFA2846BDE899 -:10772000704002F024BB00BF3C7A00200749096882 -:1077300049B10A681388834203D1126A5278D2078A -:1077400001D00431F3E70846704700BF587A0020A3 -:10775000074B002211461A684AB1131D8242F9D123 -:10776000034A1368834218BF0A1D406810607047BF -:10777000587A002080B507490138884205D806208C -:10778000FDF762F90420FDF75FF90220BDE88040B3 -:10779000FDF75AB9FEFFFF0F10B5064C28B1064899 -:1077A00001210068426820469047606820F0300060 -:1077B000606010BD00400340D80100101CB50446B5 -:1077C0000498002B0090054808BF03462046F4F7B4 -:1077D000F3FE002818BF002420461CBDE8B70200B5 -:1077E00000F11401816141612021EFF3118281F3E5 -:1077F000118801684368196041680068416082F33C -:107800001188704710B5074C207C08B1FAF788F949 -:107810000020207240F2000CEFF311808CF31188ED -:1078200010BD00BF3822002080B502F03AFA50B1F6 -:1078300001460079421E0120012A03D88A6981F895 -:107840002000CA6180BD002080BDB0B50568044637 -:1078500095F85000022808D1A86802F082FA204664 -:10786000FBF791FB002085F85000B0BDB0B5054690 -:1078700001F0C2FF2C6834B121680029296008BFDB -:10788000294600224A6002F072FA2046B0BD70B567 -:107890000D460646002401F0AFFF2D6825B1296989 -:1078A000B14208BF2C46F8E702F061FA204670BDED -:1078B000F8B50C46054601F09FFF95E8C2002D691A -:1078C0002944216002F053FA701B874238BF3846C2 -:1078D000F8BDBCB5046825790DB9A4792CB14FF079 -:1078E000FF340094E1F7A6F9BCBD02B0BDE8B0409A -:1078F000F9F746BE10B50C4601F0D8F838B100F1E2 -:107900000C0120460222BDE8104001F09FBD4FF45B -:107910009970208010BD10B54A1E012101FA02F3B2 -:1079200000221C0404BF90B210BD0342C3F34E03F7 -:1079300018BF0A434900F4E710B562B10C78037828 -:10794000A34206D1013A00F1010001F10101F5D194 -:107950001C46181B10BD002010BD10B508221306D0 -:1079600007D00B7804789C4203D1013A01300131F1 -:10797000F5E7D0B2B0FA80F0400910BD10B503466B -:107980001B68834204D09C6864699442F8DA00E082 -:10799000034658680B6048600160596010BD70472D -:1079A000064B1A6822B11346D268002AFBD10C3369 -:1079B000817100211860C160704700BF6C530020C6 -:1079C000064A1168814205D031B10A46C968814230 -:1079D000FAD10C32C168116002F094BA6C530020E5 -:1079E00080B506484FF480710078FBF7EBFC00B1DE -:1079F00080BDBDE88040FBF73FBD00BF9D7A002001 -:107A000080B50548FF22007800EBC00081000348E4 -:107A100002F02EF980BD00BFE3BA0200204500202D -:107A200080B50548FF22007800EBC00081000348C4 -:107A300002F01EF980BD00BFE3BA0200204500201D -:107A4000102809D31038012200F01F01400902FA62 -:107A500001F1024A42F82010704700BF80E200E0C6 -:107A6000E0B50178B0F801000DF1050303228DF8AF -:107A70000510ADF806004F208021FAF785FE8CBD79 -:107A800080B505480021017004480170FAF79CFE9A -:107A9000BDE88040FEF7FCBFA57A0020A67A002052 -:107AA000B0B50546C0780C460870281D02F028FACB -:107AB0006080A81D02F024FAA08005F10800B0BD86 -:107AC000B0B5064D2C78601C2870204601F042F8B5 -:107AD000002CF7D00028F5D12046B0BD937A0020C5 -:107AE00003480449044A054BC0E90132C1607047AC -:107AF00004250020E99E020071FD0000C57301000D -:107B00000348064B0349044AC0E90121C36070479A -:107B10000425002071FD0000C5730100E99E0200EC -:107B200010B5064C206818B102F0ECF90020206076 -:107B300000F05EFDBDE8104001F018B8D826002026 -:107B400080B505494870054880210078F7F74AFF5D -:107B5000F8F738FE002080BD042500209C7A002024 -:107B600006490A68002AFCD10022CA610860C86977 -:107B70000028FCD00020C86148687047001004400D -:107B800070B50024A34208D050F824506E1C04D0D5 -:107B900015408D4202D00134F4E7FF24E0B270BDFD -:107BA000064841880088401A4FF4877100F58770B5 -:107BB00090FBF1F202FB110080B27047C826002052 -:107BC0008068D0E90020C1E9002004484FF47052D9 -:107BD000006802EA80208860704700BF30240340BC -:107BE0000648B0F870100131A0F8701088B28842D1 -:107BF00008BF70470120F3F723BC00BFA86D002029 -:107C000003480449044A054BC0E90132C16070478A -:107C10007423002071A70100E17B020019730200A8 -:107C2000054806494FF0FF32007818B141F8042B9F -:107C30000138FAE7704700BFD2BA020098780020F6 -:107C400005484FF4825100680028044848BF4FF4AB -:107C500041510160704700BFAC4F005028A10C405B -:107C600005484FF4805100680028044848BF4FF48D -:107C700040510160704700BFAC4F0050A8A00C40BD -:107C800080B505480068FAF717FC04480068BDE8AD -:107C90008040FBF7C1BE00BFEC790020F0790020E6 -:107CA000B0B5044601F0A8FD054604482146FEF79C -:107CB000DBFE2846BDE8B04002F059B8D81B0020D2 -:107CC000064A0021B1F5307F06D0501890F93330C4 -:107CD000002B02D55831F5E7002070477053002083 -:107CE000E0B5064901AAFCF7E3FE9DF806108128DD -:107CF00018BF6FF07F0148B28CBD00BF01000304C4 -:107D00000A460146044843682BB18068084202D005 -:107D100002484068184770479CB90200D01E0020F6 -:107D200005480068C00704BF00207047034800688A -:107D3000C0B2C009704700BF4021084000000440A5 -:107D4000BCB5044680686A46ECF708F90546832806 -:107D500004D1694620460022FCF7AAFE2846BCBD95 -:107D600010B504463A2000211122234601F004FAFE -:107D700000B110BD01484068606110BD14250020AD -:107D80001FB5044600200390CDE9010001208DF8C5 -:107D9000040001AA2046FFF7FBF8204604B010BDFE -:107DA00005490A78824208BF7047087003481021CD -:107DB0000078F6F7ABB900BFD02600209D7A0020EE -:107DC00080B506484FF480710078FBF7FBFA00B1EC -:107DD00080BDBDE88040FBF74FBB00BF9D7A00200F -:107DE000F8B54188ADF80410411D02910179407F3A -:107DF0008DF806008DF80C1001A8F1F7EFF88FBD93 -:107E000070B50C460646EFF757FF05461E2800D012 -:107E100025B9304621460122FDF70CFA284670BDEF -:107E200010B5064890F82E0028B10020002100244B -:107E3000E6F7B4FE00B10124204610BDAC220020BC -:107E4000FEB5029000200091694601900348406809 -:107E500001F0E4FF013806B080BD00BF0C24002013 -:107E6000064A12683AB11379834202D193688B4271 -:107E700001D01032F5E71046704700BF7826002089 -:107E8000E0B5064904486A46096800684B6C02215F -:107E900098479DF800008CBDE4260020347A00202D -:107EA00005490968401A054909788900B0FBF1F2D3 -:107EB00002FB1100704700BF307A0020B47A002026 -:107EC00000F120014FF0FF32C9B2192938BF00F18B -:107ED00045024038C1B2252938BF0246D0B27047AA -:107EE00005480178832918BF7047002101700348B5 -:107EF0000170F8F745BA00BFB07A0020B37A0020CD -:107F000080B501F079FC0449044A09681160BDE8B4 -:107F1000804001F02CBF00BF3C7A0020407A002056 -:107F20000C2884BF01207047062884BF03207047B7 -:107F3000022884BF05207047002818BF072070471B -:107F400041F01001F1290AD112F0300F07D080B5AD -:107F500001F060FE00F007000230BDE8804070478D -:107F600080B5064A12682AB1926A1AB1000401303B -:107F7000904700E0002080B280BD00BF682700204D -:107F800006494B680A1D23B119461B68002BFAD11C -:107F900000E0114600220260086070475026002071 -:107FA000F8B501A80021FDF78FF8039A6846BE21B5 -:107FB0008242009228BF8FBD1170009A0132F7E70C -:107FC00001460120886000200861C86001F11400AA -:107FD00088614861014800F06DBB00BFA026002009 -:107FE00070B514460D460646002024210022FBF7FA -:107FF00031FD20B131462A46234600F03FFB70BDDB -:1080000010B50446006800F02BFB044821682422C8 -:108010004068436898470020206010BDA01F0020E2 -:1080200010B504460068FFF7DBFB044821681C22FA -:108030004068436898470020206010BDA01F0020C2 -:1080400010B50446006800F00BF804482168582277 -:108050004068436898470020206010BDA01F0020A2 -:108060002021EFF3118281F311888168C3681960C0 -:10807000C16883685960002182F31188EDF7ACBABA -:1080800041680978102908BFFFF7A4B8092904D06E -:10809000052918BF7047E9F725B800F0AABB884248 -:1080A00004BF012070470246002032B129B180B5DB -:1080B0001046FFF752FCBDE88040704750B10022E7 -:1080C0000021072A07D8835C0132002BF9D0012157 -:1080D0000922F6E70021C8B27047E0B54178408830 -:1080E0000DF1050303228DF80510ADF806004420BC -:1080F0008021FAF749FB8CBD80B550B110F8021C05 -:10810000FF291CBF042080BD0C38F9F785F9002039 -:1081100080BD052080BD70B50E46014618461C4640 -:10812000154601F09CFE04F10800314601F055FEB1 -:10813000057070BD1CB504686479022C02D1E7F7A4 -:10814000EBFB1CBD049C049402B0BDE81040E3F7B7 -:1081500009BDF8B50F20B421012200238DF80C00D1 -:108160004FF6FC70ADF8040001A8F7F731F98FBDA8 -:1081700010B5EFF31484002C1CBF002181F3148888 -:108180008047002C1CBF022181F3148810BDB0B5BC -:1081900013460C46054600201C210022FBF75AFC22 -:1081A00018B12946224600F093FAB0BD10B5054C2F -:1081B000D4F800C0BCF1000F04BFB62010BDBDE86C -:1081C000104060473024002010B5054C2069F2F7BC -:1081D00095F9A16801B9E060481CA06010BD00BF1E -:1081E000381F0020FF2807D0044A526852F8203078 -:1081F0008B4218BF42F82010704700BFE4B802005D -:10820000102801D3044A02E0042801D3014A815412 -:10821000704700BF14ED00E0F0E300E0F8B5054B57 -:108220001B682BB1CDE902128DF8040001A8984714 -:108230008FBD00BFDC24002010B514460A4601465D -:1082400023F001003A2811BF0A201846234600F007 -:1082500093FF10BD010700F002004FF0030158BF6B -:10826000012141EA4000014908707047947A0020DA -:1082700080B5044B1B689B699847034900220A603C -:1082800080BD00BFA80100108404604280B504498D -:10829000096849698847034900220A6080BD00BF18 -:1082A000A80100108404604250B180B5073080B24C -:1082B000F0F7C0F8FF28BDE8804004BF01207047F8 -:1082C00000207047E0B58DF807200DF1070201236B -:1082D000FBF712FE014908708CBD00BFA0230020EF -:1082E00010B54AB111F8013B10F8014B013A9C421C -:1082F0001CBF002010BDF4E7012010BD00220128A2 -:108300004FF0000004BF40F2EE204FF47A720229D1 -:1083100008BF0246104670470548B0F85410B0F840 -:108320005600814218BF70470820FCF7A7BB00BF6A -:1083300030210020B0B5144640F2FF3250230546EC -:10834000FFF71EFC1CB155F82010890A2160B0BD52 -:1083500010B5044601F050FA03490A7822430A7026 -:10836000BDE8104001F003BDD01E0020B0B50548A7 -:108370004468C56901F01EFB014620462A46BDE857 -:10838000B0401047D01E002010B5044600F04AFA55 -:1083900030B9204600F060FD002808BF6FF00104EE -:1083A000A0B210BD10B5054CD4F808C0BCF1000F48 -:1083B00004BF012010BDBDE8104060471425002017 -:1083C00001284FF00100044A08BF0320012110706A -:1083D000852001F079BB00BF9E7A002010B5054CC6 -:1083E00004212078F7F7FEFA20780421BDE8104038 -:1083F000F5F75AB99D7A0020F8B5ADF804000448A5 -:1084000002918DF80C20416809B101A888478FBD01 -:1084100054750020B0B585690C4635F8020B24F878 -:10842000020B2946204601F01AFD287A2072B0BDC1 -:10843000E0B5ADF8000004488DF802100192016823 -:1084400009B1684688478CBD547500201FB5ADF84A -:10845000020000206C468DF80000201D01F0BDF8E0 -:108460002046E9F70BFB1FBD10B5034604484468DE -:10847000218019460223BDE81040F7F72DB800BF50 -:108480008826002004480078052818BF7047034854 -:1084900080210078F5F73ABED02600209D7A002092 -:1084A00004480178012903D10021017002480170BC -:1084B000FAF724B8A17A0020A07A002010B50C4663 -:1084C00000F0F4FA30B10C302146022200F0BEFF79 -:1084D000002010BD022010BD10B50446087A032804 -:1084E000207219BF08882080204601F0B8FC0020C7 -:1084F000608110BD054A12683AB153681B7809B112 -:10850000002BF8D000F8013BF5E77047247A0020F3 -:10851000044981F82F0001210028034818BF0221D7 -:1085200001707047AC220020BC27002050B1821D92 -:10853000407938B132F8023B01388B4204BF012048 -:108540007047F6E70020704710B5054BC0B22AB15E -:1085500011F8014B013A6040185CF7E710BD00BF0D -:108560008CA8020004490968401A04490978890066 -:10857000B0FBF1F0704700BF307A0020B47A0020E1 -:10858000054800224FF0807341790131417100208C -:108590000021F5F70BBF00BF24250020044800216F -:1085A00001700448007800B17047F7F7E9BE00BFDA -:1085B000B37A0020B07A002080B505488068D0F8F2 -:1085C000DC04804701F018F9BDE8804001F0CFBB22 -:1085D0000C01002058B110B51C21044601F09EFB8F -:1085E0006FF00100411C20806181BDE810407047A0 -:1085F000B0B5054C206820B1856901F083FC2846A0 -:10860000F9E700202060B0BDE8790020054A38B1C4 -:1086100032F8023B01388B4204BF01207047F6E775 -:1086200000207047087800200448002101700448A9 -:10863000007800B17047F7F7A3BE00BFB07A002002 -:10864000B37A002010B50B4600201C210022FBF756 -:1086500001FA044610B12046FFF7B2FC204610BDD7 -:108660002021EFF3118281F31188016843681960BA -:1086700041680068416082F31188704710B5044674 -:108680000448002B08BF03462046FCF751FD204656 -:1086900010BD00BFCCB90200B0B5054D0024022CBE -:1086A00008BFB0BD55F8240080470134F7E700BF8C -:1086B0006CBA02002022EFF3118382F31188086064 -:1086C00042684A6042681160416083F311887047D4 -:1086D00010B504460448002A08BF02462046FEF7AB -:1086E00057FC204610BD00BFD8B9020010B50446A3 -:1086F0000448002A08BF02462046F8F7FDFC204641 -:1087000010BD00BF54B802002021EFF3118281F3A5 -:1087100011888168C3681960C1688068416082F30C -:10872000118870471CB50C4601A9FEF739FF10B13E -:108730004FF6FF7101E00199498821801CBD016855 -:1087400091F8512022B1012A18BF7047FAF71BBCDB -:1087500091F85310FBF780BAB0B50C46054601F00E -:1087600054FA296844F80C1C2C60BDE8B04001F0B4 -:108770003ABB70B514460D46064600F046F8304642 -:1087800029462246BDE87040E9F7E2BEF8B5ADF8EB -:108790000C0004208DF800006846F7F7E9FBBDF8EF -:1087A000020004B080BD41B2002211F1760FB8BFC3 -:1087B000012201385100052838BF012108467047C1 -:1087C00010B52021EFF3118481F3118880682146D0 -:1087D000FCF7C8FC84F3118810BD0B46416911B148 -:1087E0004878800700D070478A888878097BFAF734 -:1087F00033BFE0B541894068ADF8041040788DF88A -:10880000060001A8FDF79AFB8CBD704710B5044C1B -:10881000606820B101F076FB00206060208010BD10 -:108820004026002080B501F03CFA28B100790138DB -:1088300004283CBF012080BD002080BD80B501F030 -:1088400030FA28B10079013802283CBF012080BDF0 -:10885000002080BD0446FEF7CFFC034803210175CC -:10886000204601F06BFA00BF381F002004488168E1 -:108870000139816018BF7047D0E90310F5F76CB972 -:10888000381F0020FF2806D0034911F8202002F0ED -:10889000FB0201F8202070470210084010B5044C7C -:1088A000207818B1FBF774FD0020207010BD00BFC8 -:1088B000AF7A002080B580780530C0B201F024FB8B -:1088C00018B1BDE8804001F01DBB80BD130608BF94 -:1088D000704711F8023B013A037011F8013C4370F4 -:1088E0000230F3E7014600200A2906D8012202FAE5 -:1088F00001F111F4836F18BF0120704780B504485F -:10890000407808B900F042FDBDE88040F7F75ABF53 -:108910000425002003480121017103480068F5F790 -:1089200095BE00BF44250020507A00200348012155 -:10893000817003480068F5F789BE00BF4425002018 -:10894000507A002080B50448006801F077F90028CB -:1089500018BF6FF0020080BDDC25002080B5044800 -:10896000006801F06BF9002818BF6FF0020080BDAD -:108970000C240020022807D0032804D180B5E7F793 -:1089800017FC002080BDFEE7F4F7C0BE044890F855 -:10899000411119B1D0F86C0100B10047704700BF18 -:1089A000D81B002000214FF0FF320174C0E90221E2 -:1089B00001710160C0E90511818370471CB5C2F3E4 -:1089C000800302F001040093C2F340032246E5F75E -:1089D00003F81CBD10B50129044698BF012101F020 -:1089E0006BFA2046BDE8104001F068BA024803491E -:1089F000034AC0E90221704714250020FD940200BB -:108A0000A1E400000249034A0A6003490870704764 -:108A100064270020092A0200CC26002004490020F7 -:108A20000022092A08BF704741F822000132F8E706 -:108A30005475002002460448012100780AB101F073 -:108A4000C9B9F5F763BB00BF9D7A002080B5FDF77B -:108A500091FF80075CBF002080BD0020FEF7A8F9D1 -:108A6000012080BD0449B1F86E20824208BF7047E2 -:108A7000A1F86E00FFF7A4B9A86D0020082884BFF4 -:108A800002207047024A0146002042F82100704748 -:108A900054750020E0B58DF807000348C16911B195 -:108AA0000DF1070088478CBD54750020014604482D -:108AB000006818B1426812788A42F9D1704700BF45 -:108AC000247A00200448002100680A460131002869 -:108AD000FAD1D0B2704700BF247A002004480021A8 -:108AE00000680A4601310028FAD1D0B2704700BFB1 -:108AF000F82600200349044A0860106084200421FD -:108B000000F0E2BF747A00207827002004498968C9 -:108B1000D1F8E420D1F8EC1051F820001060704733 -:108B20000C0100200021082904BF01207047425C8D -:108B30000131FF2A1CBF00207047F4E710B5002266 -:108B400000238A4224BFD8B210BD10F8014B013275 -:108B50006340F6E70449096821B10A7B824201D0EB -:108B60000431F8E708467047587A002010B5044CE5 -:108B7000206820B14168216001F0C4F9F8E710BD18 -:108B80004C27002004480021043000680A460131C7 -:108B90000028FAD1D0B270475026002004488068DF -:108BA000D0F8B800007808B1F3F726BCFFF73CBD59 -:108BB0000C010020B0B50C46054600F097FF0248B6 -:108BC00044650565B0BD00BF0820002080B5044B9A -:108BD0001C33FFF78BFD4169002908BF084680BDA3 -:108BE000A01F00202022EFF3118382F31188026B73 -:108BF0001143016383F31188F7F712BC00BF00BF74 -:108C000000BF00BF0498804700980199029ADDF8E0 -:108C10000CE0104710B52021EFF3118481F3118887 -:108C20002146FCF79FFA84F3118810BD83B0C0B5CC -:108C300003AF0EC703A9009100F004F8BDE8884017 -:108C400003B07047E0B50246002001914FF0FF31BC -:108C5000009001AB0020DDF705F88CBD04480078DA -:108C6000042803D8022801D0DEF730B9704700BFCE -:108C7000BB7A0020B0B50C46054600F0BDFDA96CDE -:108C8000A143A964BDE8B04001F071B8B0B50C468D -:108C9000054600F0B1FDA96C2143A964BDE8B040D0 -:108CA00001F065B880B5E6F71FFDE7F71FFEF7F79F -:108CB000AFF9BDE88040EBF772BC2020EFF31181E3 -:108CC00080F31188B1FA81F081F31188400970476F -:108CD00010B52023EFF3118483F31188C0E900213C -:108CE00084F3118810BD10B5044600F085FD002105 -:108CF000C4E90011BDE8104001F039B8E0B58DF8C5 -:108D000007000DF10703412081210122F9F73CFD05 -:108D10008CBDE0B50022009068468DF80410ADF8D7 -:108D20000520F6F79DF98CBD28B132B110F8013B52 -:108D3000013A8B42F9D000207047012070471CB5E2 -:108D40000C6891F90430CDE9001201212246E5F7C3 -:108D5000AFF81CBDD0E9002092F83010043918BFDC -:108D6000012152690078F5F7FFBE1CB501A9FEF795 -:108D700017FC044610B90198E6F770FF20461CBDA9 -:108D80000A7A02720A7A022A02D10988018070479F -:108D9000082200F05BBB80B5F7F752FA013004BF40 -:108DA000E82080BDF7F774FA002080BD0A46096804 -:108DB00029B18142FAD1006810600120704700207B -:108DC000704710B52021EFF3118481F31188EFF77C -:108DD0000DFA84F3118810BD80B50B4600200821E0 -:108DE0000022FAF737FE08B14060006080BD10B580 -:108DF0002021EFF3118481F31188FAF7EFFD84F35A -:108E0000118810BD81B0C0B5039303AB009300F08F -:108E1000CDFBBDE8884001B07047FEE780B5F4F7B0 -:108E2000F5FF02480121017080BD00BFA827002086 -:108E300080B5F4F7EBFF02480121017080BD00BF4F -:108E4000A927002010B5C478C2880179037A20468A -:108E5000BDE81040FAF700BC80B500F022FF08B171 -:108E6000007908B1002080BD012080BD0349096858 -:108E700021FA00F000F00100704700BFC02002405E -:108E8000FF2803D0024A926842F82010704700BFC2 -:108E9000E4B8020081784378024840780A46FAF73D -:108EA000DBBB00BFCC26002003488068D0F800015F -:108EB000807B2238C0B270470C0100200348007844 -:108EC000012898BF01F088B80020704724260020B0 -:108ED000034800218068D0F8B8000170704700BFD7 -:108EE0000C01002003480178FE20002908BFFF2064 -:108EF000704700BF7C27002010B5034CE2202146BC -:108F0000FDF700FA204610BDE0790020034991F8F2 -:108F10002610082908BFEEF76FBC7047A86D002027 -:108F2000D9F8CC10D8F8140049680968D1F804259C -:108F3000024270472275026CD0F8D4301268D28A8F -:108F400052064FF04E027047034801680029FCD0DA -:108F500000210160704700BF1C100440E0B5C2F35F -:108F6000800302F0010200930123E4F735FD8CBD7C -:108F70004168034A0978D17000785070704700BF8B -:108F8000CC2600200349012291F8480081F84820AE -:108F9000704700BFA01F002010B5046804F1340022 -:108FA00000F0C2FF002084F8310010BD042805D174 -:108FB00080B51046E7F71CFDBDE8804000207047F3 -:108FC00080B50F20F8F774F900200221BDE8804039 -:108FD000FAF75EBD08288FBF0220024A42F820102F -:108FE00000207047547500201CB50C4601A9FEF7FF -:108FF000D7FA00B11CBD01990C711CBDE0B5019000 -:109000004FF40070ADF800006846F2F707FB8CBD26 -:109010000179042904D0022918BF7047F2F720B95A -:10902000F1F760BC80B503488068D0F8340380470E -:1090300080BD00BF0C01002010B5034C207000F073 -:10904000F3FB607010BD00BF7E27002040B584B0E8 -:1090500002AE0096ECF7A4FF029A039B04B040BD59 -:109060000349002912BF01C900200021ECF758BABA -:10907000B8BB020010B510F8014BFBF745FB012C03 -:1090800008BF0838C0B210BD20220028024818BF0F -:1090900024228150704700BFAC22002080B5002000 -:1090A000FDF786FEFF200321BDE88040FAF7F0BC03 -:1090B00080B50349FF22098800F0DAFD012080BD58 -:1090C0004EB2020003490979002918BF0630400159 -:1090D000704700BFB82400200249088602498881F1 -:1090E000704700BF007200200079002003488068AC -:1090F000D0F82C134FF48050084700BF0C0100201B -:109100000348007808B1F4F705B80020704700BFA5 -:10911000B17A002003488068D0F82C134FF4007017 -:10912000084700BF0C0100200248034A0721002322 -:10913000FEF770B920780020B19F020003488068D4 -:10914000D0F82C134FF40060084700BF0C0100203A -:10915000E0B50021CDE900116946FEF7FEFB80F085 -:1091600001008CBD034A516811B1527802B1084721 -:10917000704700BFE82500201CB514460A4601468A -:10918000009300202346FDF749FA1CBD10B5034C9F -:10919000E06BF6F7A9FA0020E06210BD381F00204E -:1091A000E0B50DF10702012300F018F99DF8070062 -:1091B0008CBD4FF6FF70814208BF7047C8B20021D6 -:1091C00000F0A4B84FF6FF70814208BF7047C8B2E4 -:1091D000012100F09BB880684FF0FF320A60D0E9AF -:1091E0000120C1E90120704710B50468D4F824C0FB -:1091F000029C0294BDE81040604780B58022F8F7D9 -:1092000091FE08B1C06880BD002080BDB0B50024CB -:10921000551E80E836008361C0E90444B0BD80B5C6 -:1092200000F094F800F07AF8BDE8804000F096B8BD -:1092300028B131F8023B013822F8023BF8E7084632 -:10924000704780B510EB520041F100010023FFF799 -:10925000FDFE80BD017809B10020704740680028FC -:10926000FAD0FCF79EBD0A7A032A027208BF00F00A -:10927000F6BD09880180704710B500239A4208BFE7 -:1092800010BDCC5CC4540133F8E70000B0B502490E -:1092900091E83C003CC0B0BDC4B80200024A02EBF9 -:1092A000C000F6F7A3BA00BF0CBA0200B0B502497D -:1092B00091E83C003CC0B0BDD4B80200024A02EBC9 -:1092C000C000F2F7A1BE00BF14BA02000146024876 -:1092D0000078F5F749BF00BF482600200248FF216B -:1092E00008220068FFF720BDEC5800200249D1E9B0 -:1092F0000012C0E900127047381F00200249896837 -:1093000051F82000704700BFE4B80200FF281CBFDE -:10931000014A8154704700BF0020024001480249C1 -:10932000816070470C010020E89F020001210022AB -:1093300001724FF0FF31C0E900217047102802D3BD -:10934000014910380860704700EF00E00148024909 -:10935000016070470C01002050B202000148024930 -:10936000C16070470C01002084AA02000249087005 -:109370001021F4F7CBBE00BF9A7A002002480121E9 -:1093800080F82610704700BFA86D002002480078C2 -:1093900000B17047FFF784B824260020024880F807 -:1093A0002F20E5F78FBC00BFA86D002002490A6896 -:1093B0001040C2430A6070471010044002490A6816 -:1093C0001040C2430A6070470810044000F02CFAB5 -:1093D00001490860DDF718F9D426002001EB40317F -:1093E0000148C06800F00EB9A0230020B9F824108D -:1093F000ADF8000058468DF808807047B068D0F886 -:109400001814D0F8D40090F853000847B5F8541059 -:1094100001396FF31F31A5F85410704794F82200FA -:1094200085F8AA00606AC5F8AC0070470746287C3A -:1094300005F1110103288DF82000704700246A1DF2 -:109440003346CDE90071CDE9020470472AB111F825 -:10945000013B013A00F8013BF8E77047F0B50249DB -:1094600091E8FC00FCC0F0BD40B7020002484FF09C -:1094700000410160704700BF00A10C400248016834 -:1094800041F003010160704724220840024800684F -:10949000C0F30720704700BF30A00C4002480068AE -:1094A000C0F38440704700BF04A00C40024800682D -:1094B000C0F38120704700BF20A00C40024840212B -:1094C0000160FDF7F3BE00BFA8A00C4002490844AC -:1094D00090F84A01704700BFD81B002010B5002348 -:1094E000541E80E81E00C0E9043310BD0249C9685B -:1094F00001B10847002070471425002000F0030048 -:10950000022101FA00F000F01C00704700214FF02A -:10951000FF32C0E90011C0E90221704700F0C9FB29 -:10952000014801210160FEE77C05204370B5024936 -:1095300091E87C007CC070BD40B80200024A02EB9A -:10954000C000EFF733BC00BF24BA0200006801215D -:10955000806900F0080081EAD000704780B500798A -:10956000EDF750FDBDE88040F9F786BF80B5FFF705 -:109570009DFA08B1406880BD002080BD00280249E6 -:1095800018BF012008707047B82700200249012247 -:109590000A60D0E906010847042009400249012277 -:1095A00081F83020F6F714BF381F0020E0B5019392 -:1095B0000023009301ABDCF755FB8CBD80B50A4658 -:1095C000D0F80310104600F0A9FB80BD0068002110 -:1095D00080F822100A20ECF7E9BD09B100F03FBC89 -:1095E00000214160016070474FF4C8014FF47A7266 -:1095F000C0E900217047042303EB8101042389B2F1 -:10960000FFF7ECBE10B50468D4F81CC0BDE81040EC -:109610006047234603958DF804500295FBF7FCBE86 -:109620008DF85400B8F84700ADF855007047BBF806 -:109630000C00049901224346E3F766BD05F10800DA -:1096400004F10A010822FFF701BF41EA90118000EE -:1096500002308DF82D10704740F203714FF6FF7203 -:109660000523FEF78DBA01788DF8391041788DF811 -:109670003A107047A8702079E87060790028287146 -:1096800070470BEB4B0001EB8000A0F81CA070476B -:10969000DAF80860DAF81000BAF9301070478DF87F -:1096A000630002208DF86000E81C2047ADF8380008 -:1096B0006E7B05F10E0000F023BC98F872000130BB -:1096C000C0B2CDE9000570470021416081600160B2 -:1096D000FF2101717047D0E90110401AB0FA80F003 -:1096E00040097047062902D34A1C18BF7047FDF78E -:1096F00003B81CB54FF0FF340094FEF71BFD1CBDF2 -:1097000080B5F0F7B1F9BDE88040FBF71FBA80697A -:1097100002780A70B0F801004880704780B5EEF713 -:10972000D1FCBDE88040FCF7EFB980B5FAF7F8FD51 -:10973000BDE8804000F040BC80B5FFF7EFFFBDE81A -:10974000804000F027BC0021425C0131002AFBD19F -:10975000481E70470021425C0131002AFBD1481E9F -:10976000704780B5FFF7AAFEBDE88040F7F79EBCC2 -:1097700000239A4208BF7047C1540133F9E70B46F2 -:10978000D0F80320C11D184600F0E4BB006800219A -:1097900001700A20ECF70ABD0021C0E90011C0E900 -:1097A00002117047017841F080010170FEF718B98D -:1097B00001480178FDE700BFA01F00200148C069F3 -:1097C000004700BF381F0020E0B5019001A8FEF758 -:1097D00017FC8CBD05300A21B0FBF1F0EEF750BD4F -:1097E000C0E901120421017000207047C0E9011294 -:1097F00002210170002070472021EFF3118081F3D6 -:109800001188704701480078704700BFAF7A002088 -:1098100001480078704700BFB22700200A4603467F -:1098200069208021F8F7B0BF01480078704700BF79 -:109830009A7A0020431C4520C0210122F8F7A4BFDA -:109840000148408B704700BFA86D00200148007898 -:10985000704700BF9D2700200148807C704700BFF3 -:10986000A86D00200148C08A704700BFA86D002085 -:1098700001490870704700BF9D270020014908700A -:10988000704700BF927A002001494860704700BFCE -:10989000F425002001480078704700BF70240020A4 -:1098A0000B46014610461A46FEF74EBE01480068B8 -:1098B00000F03CBBDC2500200148006800F036BB0E -:1098C0000C2400209BF800004FF48051F6F78AB872 -:1098D00002208DF84000E81C00F012BB042039463D -:1098E00014222B46FCF7B0BED0F85413D0F89800E1 -:1098F00004300847ABF800000BF1020000F0AFBAEB -:109900000221808C1080832000F0DEB8ADF80200C8 -:10991000B068D0F830247047DBF84C0000222346B2 -:10992000FDF77EB98DF818009DF840000F287047AC -:10993000014A5160107070473826002018B1006845 -:1099400008B100F00EBA7047014909680968084774 -:10995000E001001001490968C96A0847B801001010 -:109960000148006800680047E801001001480068ED -:1099700040680047E801001001488068704700BF58 -:10998000D81B00200149202200F0E4BA94B602005E -:109990000149202200F0DEBA54B60200E0B5019081 -:1099A00001A8FEF73DFB8CBDA1F1FE00B0FA80F0EE -:1099B000400970470148006D704700BFA01F00209C -:1099C0000068016B21F48071016370470068016BCE -:1099D00041F40071016370470068016B41F48071CC -:1099E000016370470149242200F0B4BACCB50200EB -:1099F00001490860704700BFF02600200149086057 -:109A0000704700BFF426002001494870704700BF2E -:109A10000C7A0020014890F831007047AC220020F9 -:109A2000014890F82E007047AC220020014981F8CF -:109A300032007047AC220020014981F831007047A4 -:109A4000AC2200200148002101707047AF7A00204D -:109A500001490860704700BF3027002001480078A6 -:109A6000704700BFC37A002001480068704700BFFC -:109A7000407A00200148002101607047E879002009 -:109A800001480068704700BFE8790020006801497C -:109A9000EFF792BD914F020001480078704700BF78 -:109AA000B82700200148002101607047587A002043 -:109AB00080B5F1F7D5FE4BF6BE2080BD13460A46B1 -:109AC00001460020F6F7B0B913460A4601460020C9 -:109AD000FCF7BABD01488069C06B7047382200208E -:109AE00080B51046F7F740F9002080BD01460148D7 -:109AF000FCF716BF886E00200148C06CF6F790BCDA -:109B00000820002001680A6802605060084670471B -:109B10000168081AB0FA80F040097047426808608E -:109B20004A601160416070470149242200F012BA76 -:109B3000F0B5020001488069704700BF382200205C -:109B40002020EFF3118180F31188FEE780B52421F6 -:109B500000F0E4F880BD006908B100F0D3B97047A7 -:109B60000088B0FA80F04009704700210170C0E918 -:109B700001117047D5E90201D0F8D4007047DAF836 -:109B80000800006C00687047284621463246FFF7FF -:109B90005DBC691D05F10D02F6F72EBDADF838006C -:109BA000687900247047C521C2B24520F8F7ECBDA2 -:109BB00084F80FA084F80E907047B068D0F8B80011 -:109BC000C16C7047316828688A6D214610478DF84E -:109BD000080002AB61207047ADF83800681D00F046 -:109BE0008FB92046FF214FF0FF32704700208DF8DB -:109BF0002700F9F741BC0978B2FBF1F1084470473E -:109C000000224FF08073FDF70BB880B5FFF7F4FD2D -:109C1000000480BD80B5FAF7FBF980B280BD002159 -:109C20004FF0FF32E8F7CABE01EB400030F8020CFB -:109C300070474068002180F8FD10704780B5E8F754 -:109C4000F9FC013880BD406801210068C16470479B -:109C5000012085210022E0F701BC80B5F6F740FD28 -:109C6000002080BD80B5F6F761FD002080BD0000BA -:109C70000B4611461A46FFF77BBD80B5FAF7C8F9C7 -:109C8000C0B280BD0A4601460020F7F7E9B980B5A9 -:109C9000F4F7DCFC002080BD0021C0E900118160E8 -:109CA000704701460020F1F783B801464A20FCF7CF -:109CB00029BBEFF3108072B67047EFF3108062B6E5 -:109CC000704740680021017070478068D0F84C05EB -:109CD0000047DBF80000F4F7B9BCD7E901102A46C9 -:109CE00020470421007800F075B840465146E2F75D -:109CF000A9B88068D0F84C0500478068D0F84013B8 -:109D0000704700230024FEF7AFBB00220023FBF7BF -:109D100083BB80B5F3F796FC80BD00000A460021A6 -:109D2000FFF726BD40686C3000F000B94FF6FF70B9 -:109D3000F5F78AB801460020FEF712B9FBF7D4FF09 -:109D4000FFF76BF80222E1F70DB90122E1F70AB93A -:109D50000222F6F7B5BB0122F6F7B2BB0021F1F7FC -:109D600027B80021017570470022EEF71BBB80F376 -:109D7000118870470122E2F72BBF0022E2F728BFCB -:109D80000138FDD170476FF00100704703689B6890 -:109D900018470268D26810475846FFF7E8BF2146C7 -:109DA000FAF7D6BB2046FFF7E2BFE81C00F0A8B8E0 -:109DB000084600F0A7B8281D00F0A2B82846FDF715 -:109DC0006FBEE81C00F09CB82846FFF7D0BF012307 -:109DD000EAF7F2B90023EAF7EFB940F8041B70473D -:109DE000D0E901100847000CFFF7C1BF01680968FE -:109DF00008470268126910470168C96908470021CD -:109E0000018070470720F2F767BE0022FAF750BEC4 -:109E10000022FAF74DBE0168096808470268126916 -:109E20001047013080B270470021EFF7C5BB032017 -:109E3000F9F766FF0620DDF749B80220DDF746B8DE -:109E4000E920E8F769BC0846ECF7AEBD0846F7F72D -:109E5000E3BA0846FCF7A8BE0121F4F7B5BC082216 -:109E6000FFF7F4BA0021F8F79FBAC0B2F1F776BF56 -:109E7000000AFCF757BC0021016070478069FFF7BA -:109E8000E2BF8069FFF7E2BF8069FFF7E2BF806948 -:109E900000F0A4B8FEF700FCFCE70020F8F70CBBCC -:109EA00001207047FEF7DCBB0A207047FCF7F8BBC7 -:109EB000FCF70CBC007D704781607047FEF781BFE6 -:109EC000FFF7D0BFF8F7B4BAF8F7D4BA002070475C -:109ED000FEF792BAFFF7A5BFEDF734B9F2F73CB938 -:109EE000F6F7ECBDF7F7B8BBE7F770BAFBF7CCBFF6 -:109EF000FBF7D2BCF9F71ABBE5F7DABA00207047D6 -:109F000000887047F7F788BAECF74EBDF9F74CBFF9 -:109F1000F9F766BFFDF7CAB900207047EAF72ABD16 -:109F2000FBF76EB980687047FDF75ABCF4F78EBB3B -:109F3000FEF7EABBFEF756BEF6F772BAF8F7BCBA00 -:109F4000FCF731BCF3F792BFF5F7A0BDFDF748BFB2 -:109F5000F9F7BABEFFF790B9F8F796BFE9F7FABB81 -:109F60000020704700207047002070470020704795 -:109F7000F32070470020704700207047DC207047B6 -:109F8000DD20704700207047002070470020704798 -:109F9000C2207047E5F7FEBFFFF76FBE0120704794 -:109FA000F5F7F2BAFAF70ABFFFF7AAB8DEF76ABC0C -:109FB00000207047F8F770B9EFF786BBFAF720BAC0 -:109FC000FEF7ECBA00207047002070470020704771 -:109FD0000020704701207047002070470120704723 -:089FE000DFF800F01D870310FB -:109FE800C87900207C720020C0780020947300207B -:109FF8000000000018760020D0790020E8760020C4 -:10A00800D078002088740020CCB4020063B9020024 -:10A01800FAB902007FB9020071B90200E0780020A5 -:10A028005427002028270020182700201C2700205C -:10A038002427002020270020102700201427002094 -:10A048000C270020F0780020F4720020707800209F -:10A05800B474002086B0020014B00200F8B0020008 -:10A068006AB10200DCB10200D0B70200C0B9020038 -:10A07800B4B90200B77A002070790020E0240020EB -:10A0880004770020C8230020AC7A0020AD7A002095 -:10A09800C873002084780020641E00209F270020B9 -:10A0A8008CAF02008CA90200000000000000000034 -:10A0B80034B902002C6B0020887A0020847A0020B2 -:10A0C800402700203C270020447A002010B40200DA -:10A0D800F0770020F06F0020000000000000000072 -:10A0E800B42500200000000000000000000000006F -:10A0F80000000000E4220020B0670020382700207C -:10A10800014A031049480310D549031015470310A5 -:10A11800B16301005D49031081470310A146031094 -:10A128009548031045450310254A031021440310A0 -:10A13800ED47031099490310E14803102149031022 -:10A148005553031089520310CD5203106550031064 -:10A158008D4E031001690100C9B3010091DA0100B5 -:10A168000000000059510310ED500310A9C201006E -:10A17800CD4B03102952031011530310A955031096 -:10A188007555031069530310DD5503103555031039 -:10A19800195A010021540310855C03100D56031051 -:10A1A8004D5D0310A9640310B55B03106D570310D0 -:10A1B800E5610310095E0310C5580310856003109C -:10A1C80071610310B16203109963031055630310A2 -:10A1D800FD600310B15E0310C53D0100D55A0310A0 -:10A1E800D559031009630310D963031019640310C8 -:10A1F800555F0310C56403104D62031071640310AA -:10A208008D64031055640310E1640310297503106D -:10A2180079720310A16B0310F57203109D7403107B -:10A22800797403102D74031061730310FD73031008 -:10A238005574031015750310D96C0310FD740310C1 -:10A24800A5170100E17403103D750310B153010017 -:10A25800F97A0000CD6803102D710310C174031042 -:10A26800F56E0310B973031081B50000056E031075 -:10A278008142010065590100A1770310797D03101F -:10A288003D7E031049750310157E0310357D0310BC -:10A2980099760310997C0310257B031071780310BD -:10A2A800B57D0310ED7C0310857E03102D79031016 -:10A2B800B97A0310917B0310B1790310ED7B031079 -:10A2C800E97D0310617E0310357A0310D57E0310F3 -:10A2D800457C0310A57E0310BD7E0310F5380100F0 -:10A2E800D9800310E97E0310498303108984031081 -:10A2F8008D8103107D820310E58403102B840310E5 -:10A30800C5830310918703106188031045880310E3 -:10A3180059680100B18803107D880310C9880310AB -:10A328001D870310A186031001850310E18803101F -:10A3380099880310F987031011440100359C031014 -:10A34800819D0310E99A0310359B0310C19B0310EC -:10A35800419A0310F18803101D8C0310618F0310BC -:10A36800F1940310919E0310C19E03103D9E0310AB -:10A37800699E0310259E0310619D03100D9E031016 -:10A38800819B0310ED93031055990310C99703108F -:10A39800D9980310BD950310959C0310C19D031017 -:10A3A800A59E03107D9E0310C991031079A6010094 -:10A3B800699C0310DD9D031095900310FD9B03100D -:10A3C800CD990310D18E0200019D0310E19C03106A -:10A3D800219D0310419D0310BD9C0310F59D0310A2 -:10A3E800A19D031055980310E1920310999A031048 -:10A3F800B99E0310559E0310F1010200A7870200C1 -:10A4080039A20310C17E020069A1031075A20310CE -:10A41800C59E0310B9A10310F9A1031015A10310DB -:10A428009DA20310459A020087E80100913C0200B2 -:10A438009D880200059802004196010031A9031089 -:10A44800ADA20310F9E60000B9A8031099A50310FE -:10A458002588010039A803106DA903104957010088 -:10A468006DAC031099B1031009AF031059B1031073 -:10A4780001B103109DA90310859F0200819F02006E -:10A48800719F0200659F0200799F02007D9F020074 -:10A49800699F0200759F0200899F02008D9F02003C -:10A4A8006D9F0200F1B9031075BA031081BB031048 -:10A4B8007144020059810100E5D1010029470100DA -:10A4C800092D02000DE40100996502006DE4010008 -:10A4D800294F0200516E0200AD8D0200CDE401004B -:10A4E800310F0200BD9F02005D4F020051B3010011 -:10A4F8000D8B020001BC010049270200258B0200D8 -:10A50800C59F0200CD9F0200CD9D0000E5DF000041 -:10A51800E9C60310C99F0200BD630000CD9E02007A -:10A52800CD3A0200818D0200CD2102002F9E02004B -:10A5380043920200BD8E0200919F0200E50E0200C8 -:10A54800058701009D7F0100614000218D400021A9 -:10A5580099400021FF4000216F410021074C657997 -:10A5680000F009F861796940490703D50121044AD7 -:10A578008903116070BD70B5024908478003002146 -:10A58800081104402D59000000F00AF8004800475F -:10A59800577F000000F00AF8004800471B880000B9 -:10A5A800806B0C490007000F48717047094A0A4937 -:10A5B80018235079CB56497EC018814201DD0846E0 -:10A5C80002E00F2800DD0F20D189090909010143A4 -:10A5D800D1817047E00200218800002110B533487E -:10A5E800314C8047012807D02034217D002903D130 -:10A5F80001212F4A0905916010BD072801D02D4A75 -:10A6080010472D4A4A60C872704701222C4B02211C -:10A618002A481847274810B5F83080472948406A23 -:10A6280000280DD128490A200856002809DA401CBC -:10A6380007D008462038406A2449884200D180471C -:10A6480010BDFFF7E2FF10BD0021224B204A08464B -:10A65800184701202049400208602048FB22017861 -:10A668001140017013480C30004710B51C49884749 -:10A6780015492039012807D0020404D5002008858F -:10A6880018484862012010BD4A6A0A4B0C339A42A6 -:10A6980001D1154A05E00B494A6A144B9A42F2D196 -:10A6A800134A4A6210BD00006001002175A602002D -:10A6B80000110440A9910200E140002106080000B1 -:10A6C8009F06000008010021540100216392020046 -:10A6D80019410021B5B4020080E100E080030021A7 -:10A6E800F79602000F4100215741002169950200A9 -:10A6F8004D4100218F000100EC2700208700010058 -:10A7080024260020350028000875002028000100B4 -:10A71800D527002029000100D62700208400040046 -:10A728007827002086000100D92200202A00010095 -:10A73800E82700202B000100D32700202C0001006F -:10A74800E22700202D000800252600202E00010009 -:10A75800D42700202F000100DF270020300001004F -:10A76800C727002032000100CD2700203300010058 -:10A77800CC27002034000100CF270020360001003C -:10A78800CE27002038000100DE2700203900010014 -:10A79800E1270020830002009027002063000100C9 -:10A7A800E027002065000100E72700206D00010078 -:10A7B800C87A002071000800B82600206600010051 -:10A7C800C227002043000100C627002044000200E1 -:10A7D8008C27002045000100C02700204600020009 -:10A7E8008827002047000800C026002048000100F4 -:10A7F800C42700204B000100C327002004000100EB -:10A80800E9270020A1000100E62700203700010009 -:10A81800DB27002088000100DA2700203C00010027 -:10A82800E32700203D000100D9270020490002004D -:10A838009227002067000100C12700204D00020078 -:10A848008E2700204E000100C52700204F0002007F -:10A858008A2700203E000100CA270020510001007D -:10A86800DC27002052000100D827002053000100F7 -:10A87800D227002054000100D0270020000000004B -:10A88800000000000097B92EE5725CCB5DCAE47346 -:10A89800B82F0196BA2D03945FC8E671E7705EC9B8 -:10A8A8000295BB2CE3745ACD0691BF28BE290790A8 -:10A8B8005BCCE27559CEE077BC2B05920493BD2A98 -:10A8C800E17658CF51C6E87FB4230D9A0C9BB52288 -:10A8D800E97E50C7EB7C52C50E99B720B6210F9878 -:10A8E80053C4EA7DB2250B9C57C0EE79EF7856C168 -:10A8F8000A9DB324089FB126ED7A54C355C2EC7B58 -:10A90800B027099EA2351B8C47D0FE69FF6846D147 -:10A918001A8DA334188FA136FD6A44D345D2FC6B37 -:10A92800A037198E41D6F86FA4331D8A1C8BA53227 -:10A93800F96E40D7FB6C42D51E89A730A6311F8817 -:10A9480043D4FA6DF3644ADD1681AF38AE39178007 -:10A958004BDCF26549DEF067AC3B15821483AD3AF7 -:10A96800F16648DF1087A93EF5624CDB4DDAF463E7 -:10A97800A83F1186AA3D13844FD8F661F7604ED9D7 -:10A988001285AB3C000136360101000102010001CD -:10A998000301000104010606080400000C0100344C -:10A9A8000D01000F10040101140100FF160800003A -:10A9B80020020000220100FF23010001240100FE03 -:10A9C80025010008260200002801000129010001D4 -:10A9D8002A0200002C01000F2E02000030010001A5 -:10A9E80031010008320200FF34010007350102FF7F -:10A9F800360100003701000138010001390100FF6C -:10AA08003A01000F3C0200FF3E01010F3F01000127 -:10AA18004001041F41010001420100FF4301008081 -:10AA2800440800004E0100084F01000F50010001CA -:10AA3800510100FF520100005301000054010001C0 -:10AA4800580400005C040000600400006404000076 -:10AA5800680400006C040000700400007404000026 -:10AA6800780400007C040000800100FF81010001DF -:10AA7800820100018301020284010001B427002041 -:10AA8800BC7A0020C17A00209C270020AE7A0020E2 -:10AA9800B1270020AF270020519A0200BDA2000074 -:10AAA800978D02006D6502004165020091ED01007D -:10AAB80031F50100990E020029190200016E020009 -:10AAC800254E020065640200999F0200E58E02008F -:10AAD800E1060200554D0200D96D020091640200A2 -:10AAE800D990020055760200F54E0200C996010081 -:10AAF800B97C0100C93C020035ED010041020200A9 -:10AB08002B9702003997020000000000892C0200F0 -:10AB180047060200D5AA01002143020000000000F8 -:10AB2800E96402005D9A0200E14402001591020006 -:10AB3800000000000000000081C60000817E0200C5 -:10AB48002D070200B50D02006861726477617265B5 -:10AB580020657863657074696F6E206964203D2094 -:10AB680025642C207063203D2030782530387820EB -:10AB7800282F55736572732F6B6F656E6B6B2F473C -:10AB880069742F53494D504C454C494E4B2D434306 -:10AB9800313358322D323658322D53444B2D5A4EBC -:10ABA800502F73696D706C656C696E6B5F63633190 -:10ABB8003378785F6363323678785F73646B5F37B6 -:10ABC8005F34315F30305F31372F6B65726E656C83 -:10ABD8002F746972746F73372F7061636B61676567 -:10ABE800732F74692F73797362696F732F66616D40 -:10ABF800696C792F61726D2F6D332F4877692E63D9 -:10AC08003A31303932290048776920616C726561C0 -:10AC1800647920646566696E65643A20696E747249 -:10AC28002320256420282F55736572732F6B6F6559 -:10AC38006E6B6B2F4769742F53494D504C454C49E7 -:10AC48004E4B2D4343313358322D323658322D5323 -:10AC5800444B2D5A4E502F73696D706C656C696E3C -:10AC68006B5F6363313378785F6363323678785F1C -:10AC780073646B5F375F34315F30305F31372F6B10 -:10AC880065726E656C2F746972746F73372F70619B -:10AC9800636B616765732F74692F73797362696F6A -:10ACA800732F66616D696C792F61726D2F6D332F0B -:10ACB8004877692E633A33383529006E6F20495337 -:10ACC800522C206964203D2025642C207063203D8F -:10ACD8002030782530387820282F55736572732FE7 -:10ACE8006B6F656E6B6B2F4769742F53494D504CD2 -:10ACF800454C494E4B2D4343313358322D3236584B -:10AD0800322D53444B2D5A4E502F73696D706C651C -:10AD18006C696E6B5F6363313378785F6363323677 -:10AD280078785F73646B5F375F34315F30305F31E1 -:10AD3800372F6B65726E656C2F746972746F733719 -:10AD48002F7061636B616765732F74692F737973F3 -:10AD580062696F732F66616D696C792F61726D2FEF -:10AD68006D332F4877692E633A3130393529006FB2 -:10AD78007574206F66206D656D6F72793A2068650D -:10AD880061703D307825782C2073697A653D25758A -:10AD980020282F55736572732F6B6F656E6B6B2F41 -:10ADA8004769742F53494D504C454C494E4B2D43E0 -:10ADB80043313358322D323658322D53444B2D5AA5 -:10ADC8004E502F73696D706C656C696E6B5F636351 -:10ADD800313378785F6363323678785F73646B5F9A -:10ADE800375F34315F30305F31372F6B65726E6596 -:10ADF8006C2F746972746F73372F7061636B61673E -:10AE080065732F74692F73797362696F732F727505 -:10AE18006E74696D652F4D656D6F72792E633A3763 -:10AE2800382900696E746E756D3A2025642069733F -:10AE3800206F7574206F662072616E676520282FF9 -:10AE480055736572732F6B6F656E6B6B2F476974E3 -:10AE58002F53494D504C454C494E4B2D43433133AC -:10AE680058322D323658322D53444B2D5A4E502FCE -:10AE780073696D706C656C696E6B5F636331337891 -:10AE8800785F6363323678785F73646B5F375F34FB -:10AE9800315F30305F31372F6B65726E656C2F74A0 -:10AEA8006972746F73372F7061636B616765732F95 -:10AEB80074692F73797362696F732F66616D696C3A -:10AEC800792F61726D2F6D332F4877692E633A336E -:10AED8003737290013000000CDC300001F00000011 -:10AEE800B11601001F800000F134020000000000CC -:10AEF800F17C000001000000F17C0000020000006D -:10AF08009993010002800000B77C01000300000053 -:10AF18006141020004000000219401000480000047 -:10AF28006790010005000000A1160200060000005D -:10AF3800DD8000003000000021F301003100000036 -:10AF4800B16C000032000000E57101003300000020 -:10AF5800B565010034000000396C010036000000BE -:10AF680089CC01001100000051010200140000000A -:10AF7800A994010015000000814B0200FFFF0000AA -:10AF8800000000003600010006000000000000007C -:10AF9800000F00000000000000000000000000009A -:10AFA80000000300FFFF00000403FFFF0000FFFF95 -:10AFB8000F00E8030005401F031000010000000017 -:10AFC800FF3F0F000800050B000000000000000014 -:10AFD8000300010F00000000000000000000000056 -:10AFE8000000000000000000000000000000000059 -:10AFF8000000000000000000000000000000000049 -:10B0080000000000AD000002000000000101710115 -:10B018000101010111010101310101010101800159 -:10B028000001100161013B0014006301730172010A -:10B03800620143010001130106013D0135000401CD -:10B0480012010001000100010001040104013301A3 -:10B0580033013C0144013201360000010001650161 -:10B068000001350081010001050182018301000111 -:10B07800660100010001080109010A010B01030032 -:10B08800710030016000110070003102200350048B -:10B0980080000700100061000000140063007300C6 -:10B0A8007200620043000000130006000000000068 -:10B0B800040012000000000000000000040004006A -:10B0C800370037003C024400000000000000000088 -:10B0D80065000000350081000000050000008300C5 -:10B0E8000000660000000000080009000A000B00CC -:10B0F80003027102300160021102700201020202B1 -:10B10800020280020002100261023A00410063025A -:10B118007302720262024302000213023800000244 -:10B1280000020402120200020002000200020402ED -:10B138000402370037003C024402000239000002D2 -:10B148000002650200023502810200020502820245 -:10B1580083020002660200020002080209020A02D3 -:10B168000B0201037103010301030103010301033E -:10B17800220302030103000310030003000300037A -:10B188000003000300030003420300032403060333 -:10B1980000030003040312032503230325032303E9 -:10B1A8000403040300030003000344030003000333 -:10B1B800230300036503210035038103000305030E -:10B1C8000003000300030003250323030803090306 -:10B1D8000A030B03030471040204600411047004DD -:10B1E80002040204010402040004100461040004BF -:10B1F8001404630473047204620443040004130413 -:10B2080006040004000404041204000400040004FA -:10B218000004510464000004000400044404000411 -:10B22800000400040004650400043504810464007B -:10B2380005040004830400046604000400040804F0 -:10B2480009040A040B040E000B9C0200E79D02008F -:10B25800099F0200059F0200E18202007992020024 -:10B26800719702003D730200F9800200A570020088 -:10B27800D16B020089280200895602005987020012 -:10B28800B1EA010069F1010079C001000DE1010096 -:10B298004797020039790200AD9E0200FD9E010029 -:10B2A8003D990200AF710200679202005F9E0200A2 -:10B2B8005B79020001000000115700000600000041 -:10B2C8009F79020008000000D58901000B000000EA -:10B2D800491A020010000000AD3001000A00000009 -:10B2E800FDA201000200000021D6000005000000B8 -:10B2F80021CD0000070000008DE501000C000000D2 -:10B30800FD7600000D000000710C000064000000D4 -:10B31800ADDD0100FF00000000000000001000404B -:10B3280015000000FF0000007875002020000000D4 -:10B338009875002020000000000000000C000000AC -:10B348000D000000FF000000FF0000002018002092 -:10B358001018002004000000020000000500000092 -:10B36800100000000F000000110000001200000093 -:10B37800000200008E0000008E0001008E00020016 -:10B388008E0003008F0000018F0000028F00000371 -:10B398008E0001048E0000058E0008048E00000453 -:10B3A80089000006500000007F0001003F000400F3 -:10B3B8003F0002003F0001007F0002008E000204EF -:10B3C8008E0001028E00010101280000000000002B -:10B3D8000000000000010030000000000000000034 -:10B3E8000003FF18640000000000000000000000D7 -:10B3F8007856341200000000BAAB000000000001CB -:10B408000000000000000000C003000080070000EA -:10B41800000F0000001E0000003C00000078000043 -:10B4280000F0000000E0010000C0030000800700F9 -:10B4380000000F0000001E0000003C000000780023 -:10B448000000F0000000F0000000004017FF0000BE -:10B45800000000000400FFFF0800000010000000CA -:10B468004018002030180020401A0020301A002010 -:10B478000A000000090000000C0000000B0000009A -:10B4880009080AFF0A0000000A0000000200000084 -:10B498000400000008000000100000002000000068 -:10B4A80040000000800000000001000000020000D1 -:10B4B8000004000000080000001000000020000048 -:10B4C8000040000000000000020000000200000030 -:10B4D8000A00000002000000020001000000000055 -:10B4E8000000000000000000000000000000000054 -:10B4F80000000000000000000E000000C39C0200D5 -:10B50800879D0200C9550200C17B0200A9080200FC -:10B518004589020009B00100F5080200AD98020053 -:10B52800CD0401007D9E010055EA0100F955020095 -:10B53800D7910200313F02005D890200A500010099 -:10B5480061000200B998020071C20000000000000A -:10B5580000000000000000000000000000000000E3 -:10B5680000000000000000000000000000000000D3 -:10B57800000000000000000000602500001000002E -:10B58800C071002040000000000000000000000022 -:10B5980000093D00140000006400000061D70000AD -:10B5A800799F000085400000815100004D44000053 -:10B5B8009DD80000A94E0000558501008D27000088 -:10B5C800F952010000000000000000000000000027 -:10B5D80000000000000000000100000000C201009F -:10B5E8000300000000000000000000000000000050 -:10B5F8000000000001000000000000000002000040 -:10B60800000000000000000001000000022C000003 -:10B618000000000000000000000000000000000022 -:10B628000000000000000000000000000208000008 -:10B638000000000000000000000101000800FFFFFA -:10B6480018260020A02400208824002000000000E4 -:10B65800FFFFFFFF000000000000000040420F0055 -:10B6680008000000000000000000000008000000C2 -:10B6780008000000080000000800000004000000A6 -:10B68800020000000100000001000000FFFFFFFFB2 -:10B698000000000000000000000000003A013A012C -:10B6A80000000000000000000000000052616E640D -:10B6B8006F6D5F736565644175746F6D61746963FF -:10B6C8002829206661696C65640074692E73797332 -:10B6D80062696F732E6B6E6C2E5461736B2E4964A6 -:10B6E8006C655461736B0069643A20307825782062 -:10B6F80061303A20307825782061313A2030782539 -:10B70800780A00050000000000000000E8030000BF -:10B718000000000000000000000000000000000021 -:10B7280004B50200BE7A00205CBA02002CB5020003 -:10B738007C7900207CB502000100000040420F0027 -:10B7480001000000000000000000000000000000F0 -:10B758000308000000000000000000000001650967 -:10B768000000000000000000012C000000000000A4 -:10B77800000000000001001E0000000000000000A2 -:10B7880071B101009D2A0100339C0200B9AA000092 -:10B7980049540000C5840100038000C0038000D51F -:10B7A800038000CC038000DD0380000C0380005D73 -:10B7B800000000000200000001000000030000007B -:10B7C800100000002000000000000500BD00B700C8 -:10B7D800B100BC001C00300038000800380102002D -:10B7E8000000000000000000010000000000000050 -:10B7F800E0000000010000005B4173736572742073 -:10B80800526561736F6E5D20307825303258001EA6 -:10B8180000000000FD5701007589020001010100C8 -:10B8280000000000032C00000000000000000000E1 -:10B8380000000000000000000200000000000000FE -:10B8480000000000FFFFFFFF0000000000000000F4 -:10B8580000000000000000000500000000000000DB -:10B8680041455343434D206F70656E206661696C96 -:10B87800656400414553454342206F70656E2066FC -:10B8880061696C656400001610000018151002004C -:10B898000224145800001000003031323334353699 -:10B8A8003738396162636465660054524E47206FC9 -:10B8B80070656E206661696C6564000202000000B4 -:10B8C80000000000FFFFFFFF000000000200000072 -:10B8D80000000000FFFFFFFF00000000E81D00203F -:10B8E800386C0020B46C0020FFFFFFFF746A002052 -:10B8F80092BA0200D06A002094BA02000000000048 -:10B908000000000000000000000000005A696742C3 -:10B918006565416C6C69616E63653039D0D1D2D38D -:10B92800D4D5D6D7D8D9DADBDCDDDEDF88B224007F -:10B9380088130000100000000000000141737365C7 -:10B948007274206661696C65643A20004572726F92 -:10B9580072207261697365643A200000A6AAACA4DB -:10B96800A9A9A399B19ABCB6A8313118191A2231DC -:10B978001C1E2031313431313117191A21241B1D75 -:10B988001F31313331027F00FF000000000000004A -:10B9980000010000FF00010073870200070000009B -:10B9A80088B70200B066002050B402000C0E020BEB -:10B9B800040B0A070800110F000120181A18182C88 -:10B9C80034041E0000000000000000000000000019 -:10B9D800000000000000000000000000FF00000060 -:10B9E8000000000080A90300020102070146D934C3 -:10B9F800010002040201010101090201782100206D -:10BA08007C210020D8770020C7BA0200E07400200B -:10BA1800C8BA0200E803000000006400B46B00200C -:10BA2800E4B90200445E002024B302003876002006 -:10BA380074BA0200010200030200010300BE0208FA -:10BA480000BE040AFFFFFFFFFFFFFFFF000800041E -:10BA580000020001000005000060000054B9020067 -:10BA680044B902001D4C02008D890200000002400A -:10BA78000929FF00286E756C6C2900000602868271 -:10BA880000081018200001020304060107018813AA -:10BA98000000000022000100440001000020406076 -:10BAA800E803000088130000200000007C1F00202D -:10BAB8002000000000002800C80000080A0001401B -:10BAC8002001080F030C1E040A190505082864FA4A -:0DBAD8000CFF0400014503011E483033003F -:10BAE800BD59000075E300000000000000000000E0 -:10BAF80000000000BD8902005D8F0200E599010089 -:10BB080085990200119E02000B9E02003F8D0200E3 -:10BB180000000000FF9D0200EDA7010039FA0100B6 -:10BB2800E17C020061990100FB9102001D2E0100D9 -:10BB3800C18400006DCA0100417D020000000000C0 -:10BB4800E11E0200A5890200656F01001D8E02003A -:10BB58009D9202008D9702008D9202004D9B02007B -:10BB68004B9D0200459D0200318E0200BD920200ED -:10BB7800CD950200AD92020099970200579D0200F0 -:10BB8800519D0200ED970200E197020084250020F4 -:10BB98004C1D002034B6020058B7020070B70200EE -:10BBA800D0B3020014B602002CB802000000000056 -:08BBB800000000000000000085 -:10BBC00001E500000FA1020100BF0514BF02619F43 -:10BBD000023F0025380100D1007016B5FFECC60405 -:10BBE0000000EEC806EF0000F1CA0040F4CC0A6F76 -:10BBF0000000F6CF0040F7D00090FFFAD41000000C -:10BC0000FBD612DF0000FD931819E05328FA071045 -:10BC10005600400259320000FF035D380000046303 -:10BC20004EFF0000051772000006FF2A4F14800720 -:10BC30005F2814FF80085A331080095FFF3F10808F -:10BC40000A664F1080FF0BCB2130800CCC27FF3FC2 -:10BC5000800DCDC33F800EFFD6271B800FDA2F1B30 -:10BC6000FF8010DE391B8011E5FF4F1B8012E0477B -:10BC70003080FF13E2613F8014F575BF3F807FFF86 -:10BC8000FF3F0CEF04021D60225004002000310031 -:10BC9000B000727E00B400022000200101718140DA -:10BCA00000340131003801B2013C0239003108058D -:10BCB00070003528CFC6016CDC1FC73700FD033785 -:10BCC00044490602005588E50215A02726FF0C27E7 -:10BCD000051B00207B9C69127F2CC81F00200031AF -:10BCE000163F71807A1737E0017000312CFF022374 -:10BCF000287419BF4834B134F80130A0492F9F018E -:10BD0000FF11080200E8BA02009B54BB3E33416FAA -:10BD10001EEA562F9701C57D1B60D7253C00003DCC -:10BD200061C4DB8515625F0CFD74645F0419E13F3B -:10BD30000000382200200031527F06255825B05CD3 -:10BD4000023000316400345A0F3B9A6E0F02080033 -:10BD500033FFFF54F058A00FF03938006FB2027172 -:10BD60003F0E873F2A2BD4D7FDFF0307C2018387ED -:10BD700003007FC3060201A860011C70FFFFFF2BB8 -:10BD80005EC80103075F32058387000171050170FA -:10BD9000D90401718DFF1686B079F76AB1563BFF61 -:10BDA00024FEFE94DF1C14000C012971D686480184 -:10BDB0000C99D7808744911AF245BB9D5C389CBD95 -:10BDC000325032003A001102641001007D9EAF3BF8 -:10BDD0001731FE177183880F00D388F3FE183200E5 -:10BDE0000123456789ABB3CDEF037F0AA7040503A1 -:10BDF000225F2845FF7000202979010019FA95B0CB -:10BE00000B92C054250020A095260033A80034B022 -:10BE10000034083F05FF748CF0AFA880B06E4FD49B -:10BE200001003296B1FF1275B2B45F0EF00034B665 -:10BE3000DF1888F91325BC4AB0E001FFFF80FF3E00 -:10BE40000500F401E803FF9DFF011100010384D107 -:10BE5000A30000A33C00A4F0AA27A6D130BDC10FC7 -:10BE6000F9011FD100F00102010A037F1E01030145 -:10BE7000013C017660FF0308080204030908BE01C3 -:10BE8000E20A05000D028660E00B0102A8B001FF86 -:10BE9000F0000000BD95020009C701007F97020075 -:10BEA0000000000010000000000000001000000072 -:10BEB0000000000010000000000000001000000062 -:10BEC0000000000010000000000000001000000052 -:10BED00000000000D9520000000000001000000027 -:10BEE00000000000D8000000C0BB0200D81B0020EA -:10BEF000A0BE0200301A0020A8BE020030180020A8 -:10BF0000B0BE0200401A0020B8BE02004018002057 -:10BF1000C0BE020010180020C8BE02002018002079 -:10BF2000D0BE0200F0270020D8BE02000C01002085 -:08BF3000E0BE0200001B00202E -:020000025000AC -:107FA800000080011000C0FFFDFF5800FFC1B9FDAF -:107FB800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 -:107FC800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 -:107FD800C508FEC5FFFFFFFF00FFFFFF00C5C5FF87 -:107FE800000000FF00000000FFFFFFFFFFFFFFFF92 -:087FF800FFFFFFFFFFFFFFFF89 -:00000001FF +:100000000030012001520200696F0200696F020096 +:10001000696F0200696F0200696F0200696F020078 +:10002000696F0200696F0200696F0200696F020068 +:0C003000696F0200696F0200A9F6000071 +:10003C002DE9F04F99B0054680780224532800F240 +:10004C00CF85DFE810F054009900A800B800C80074 +:10005C00DA00EA000C011B01CD052A013801590117 +:10006C00CD05CD05CD05CD05CD05CD05CD05CD05F4 +:10007C00CD05CD05CD05CD05CD05CD05CD05CD05E4 +:10008C00CD05CD05CD0565018A019601A201AD0115 +:10009C00BC01D601ED0109023C02CD05CD05CD0513 +:1000AC00CD05CD05CD05620278028E02A402BA02FE +:1000BC00CF02E0020503CD05CD05CD05CD05CD055F +:1000CC00CD053A034E036203CD056F037903970305 +:1000DC00A003AC03B803C703D103F4031104360423 +:1000EC003E0450045D0469048D0494049704EC1CD4 +:1000FC00E97A2A7B002320461EF0F2F88DF81800CE +:10010C0006AB65200021012222F038FBDFF8280B1A +:10011C000078012800F26385204629F019FE00289A +:10012C0000F05D8505460079012840F0588529F0DE +:10013C0093FB00274FF400018DF83F008DF8380039 +:10014C00000ACDF83A108DF841708DF83E708DF89C +:10015C0040008DF839000EAE214606F10A0029F058 +:10016C0078FE2978152233460170697887704170C2 +:10017C004520FF2100F031BD29F01DFE6979AA79D7 +:10018C000023002425F09AFB8DF838000EAB652077 +:10019C00012100F05ABC29F095FB29F017FD01460E +:1001AC000EA8022229F0A7FD8DF8180006AB6520D9 +:1001BC00022100F04ABC29F085FB29F007FD01461D +:1001CC000EA8032229F097FD8DF8180006AB6520C8 +:1001DC00032100F03ABC29F075FB29F0F7FCEA7911 +:1001EC0001460EA80023002427F0C2F98DF8180050 +:1001FC0006AB6520042100F028BC29F063FB29F034 +:10020C00E5FC01460EA8052229F075FD8DF81800B5 +:10021C0006AB6520052100F018BC0020DFF8404A31 +:10022C0029F037FAADF85800681DA0478046E81D44 +:10023C00A04795F809A0814605F10A07BAF1100FFD +:10024C0000F2B2830EAC5546002D00F0B083384658 +:10025C0029F050FE24F8020B013D0237F4E729F097 +:10026C0031FB29F0B3FC01460EA8102229F043FD06 +:10027C008DF8180006AB65200721E6E329F022FB78 +:10028C0029F0A4FC01460EA8112229F034FD8DF8AA +:10029C00180006AB65200821D7E329F08CFD6A7B9A +:1002AC00691D0023002423F071FF8DF838000EAB7C +:1002BC0065200A21C9E302208DF8200029F07BFD7E +:1002CC00ADF81800681D29F015FEEA79064605F10F +:1002DC0008018DF838200EAF781C29F0B1F806A86B +:1002EC0031463A460023002420F02EFC8DF85800AD +:1002FC0016AB65200B21A8E329F05DFD002100243D +:10030C0023F04AF98DF838000EAB65200C219CE3E4 +:10031C000020DFF84C4929F0BCF9ADF85800681DF5 +:10032C00A047814695F80FA005F11000A04795F85D +:10033C0012B0074605F11304BBF10F0F00F249830D +:10034C000EAE5D46002D00F04783204629F0D2FD0D +:10035C0026F8020B013D0234F4E729F0B3FA29F038 +:10036C009FF929F05DF840F04B8306A829F071FD48 +:10037C004BE329F0A7FA29F093F929F051F840F052 +:10038C00528306A829F065FD52E329F014FD29F0EB +:10039C00FAFB8DF838000EAB6520232100F01CBC55 +:1003AC00DFF89418C8208DF81800E81C097800298B +:1003BC0000F0878328F0D3FC8DF81800A9E3687946 +:1003CC00EE1CFE280BD1A879FF2808D12878082824 +:1003DC0005D3304629F08EFD314625F097FC0EA949 +:1003EC00304628F099F9002800F097830546002440 +:1003FC00A5E3E81C042126F0BBF9E97929F09CFD62 +:10040C00DFF850188DF83800022028F0DDFDDFF8F9 +:10041C004818032028F0D8FD0EAB65202621DBE31D +:10042C0029F0C3FC044605F10E0029F063FD297C7C +:10043C006A7C0346E878CDE90012AA1D214625F016 +:10044C00C1FEDFF80C188DF83800042028F0BCFD34 +:10045C000EAB65202721BFE34FF00208E81C8DF896 +:10046C00408029F047FDADF8380068798DF85800C8 +:10047C00A81D29F03FFD2E7A044600270935CDE949 +:10048C00005716A80EA92246334621F04BF929F045 +:10049C0043FA10D1DFF89C078DF84080CDE9005766 +:1004AC0022463346C08AADF8380016A80EA921F0B2 +:1004BC0039F98DF8180006AB652028218CE302264B +:1004CC00E81C8DF8406029F015FD29F07FFBED79D3 +:1004DC0004460EA8002321462A4627F0BFFF29F028 +:1004EC001BFA0ED1DFF84C078DF8406021462A46E6 +:1004FC000023C08AADF838000EA827F0AFFF8DF8A6 +:10050C00180006AB6520292166E329F0DBF9ADF86C +:10051C003800681D042126F02BF96A7AAB7A002486 +:10052C00014600940EA825F079FE8DF8180006AB54 +:10053C006520302189E229F0C5F929F029FB312207 +:10054C0001238DF8580016A8CDE90004DFF8FC064D +:10055C000EA921F0E7F88DF8180006AB65203121C3 +:10056C0073E229F0AFF929F013FB322201238DF845 +:10057C00580016A8CDE90004DFF8D0060EA921F02A +:10058C00D1F88DF8180006AB652032215DE229F018 +:10059C0099F929F0FDFA332201238DF8580016A899 +:1005AC00CDE90004DFF8A4060EA921F0BBF88DF804 +:1005BC00180006AB6520332147E229F083F9ADF82A +:1005CC003800687B0024691D0094C0F3400200F0E1 +:1005DC0001030EA822F0C2FF8DF8180006AB6520AF +:1005EC00342132E229F06EF96A7BADF83800691DCE +:1005FC000EA80023002426F05DFB8DF8180006AB36 +:10060C006520352121E22C4614F8030B04281ABF6F +:10061C00E8782C1D02208DF84000204629F06AFC59 +:10062C00DFF82466A5780121E278ADF838000023C4 +:10063C00002431700EA829461EF0C4FE8DF8180057 +:10064C002846347026F072FB06AB65203621FCE19F +:10065C0029F0B1FBADF83800687904218DF8400021 +:10066C00A81D26F085F80446AE7AEF7A05F10C0049 +:10067C0029F040FCDFF8BC850546214632463B4656 +:10068C0029F015F80EA821F029F829F045F910D118 +:10069C000220214632463B468DF84000B8F8160041 +:1006AC00ADF8380029F003F80EA821F017F88DF8F2 +:1006BC00180006AB652037218EE26C7829F07BFBA5 +:1006CC000146DFF88005007820F018FA8DF8380024 +:1006DC0004F0E000202840F082820EAB65203E2121 +:1006EC007AE26C7829F067FB0146DFF85805007850 +:1006FC0021F000FD8DF8380004F0E000202840F0D7 +:10070C006E820EAB65203F2166E200206C788DF87E +:10071C003800DFF824050078411E022980F0998109 +:10072C0002209AE129F047FB29F02DFA8DF83800C8 +:10073C000EAB652042214FE2002006908DF83D0063 +:10074C00CDF83900E81C06A926F024FF8DF83800F6 +:10075C00069850B128F081FF81788DF83B10C17854 +:10076C008DF83C1000798DF83D000EAB65204321CF +:10077C00062232E2E81C28F0F2FA8DF838000EABB3 +:10078C006520442128E229F016FB6979AA790EF03C +:10079C00D7F88DF838000EAB652045211CE229F006 +:1007AC000AFB6979AA791AF0A1FC8DF838000EAB16 +:1007BC006520462110E2EC7829F0F7FA0146204634 +:1007CC0022F0DCF9B0FA80F0472140098DF83800AE +:1007DC000EABC7E1E87800248DF8384023F046FDD5 +:1007EC000EAB6520472130E1E8780EA926F0F6FE25 +:1007FC0006468DF8180040000130C5B2284629F095 +:10080C007DFB002800F0A981044600F8016B002153 +:10081C009DF81820914280F0C0809DF8383001314D +:10082C0000F8023B9DF8393000F8013CF2E70EACC1 +:10083C001321204629F06CFAEE7829F0B6FA01461D +:10084C00304626F09BFA002800F08E810021231DF3 +:10085C008DF8381028F001FFC11C827818468DF8ED +:10086C003B2028F0EDFD82E10020EC78CDF846002D +:10087C00CDF84200CDF83E00CDF83A0029F095FABB +:10088C00AA79ADF838000F2A28BF0F228DF83A202C +:10089C0022B10EA8E91D033028F0D2FD0EA9204686 +:1008AC0001221DF0BDF88DF8180006AB65204B2118 +:1008BC0092E128F00DF98DF838000EAB65204C2133 +:1008CC008AE1E87829798DF838100EA9032800F010 +:1008DC006581022800F06881012840F06C8152206B +:1008EC0021F04CFC6AE129F066FA69790246A81DF0 +:1008FC001BF013FB8DF838000EAB65204E216BE11D +:10090C0029F059FA0146687919F0A8FF8DF83800DA +:10091C000EAB65204F215FE1C64D0822E88A05F138 +:10092C003901ADF83800C54800788DF83A00A88C2C +:10093C00ADF83B00688BADF83D000EACE01D28F027 +:10094C007FFD04F10F0005F11C01082228F078FD51 +:10095C00287E5021182223468DF84F0065203CE15B +:10096C00B5480078002800F00781122010E120F033 +:10097C0053F834E100208DF83800E87841B2B1F139 +:10098C00FF3F06DC10F07F00AA4918BF012081F858 +:10099C0068000EAB652053211EE1652049212A46D3 +:1009AC00234621F0EBFE3DE180208DF8630097F8A3 +:1009BC0000B0BBF1100F53D87E1C4FEA4B0500243E +:1009CC0006AFA5424ED0301929F094FA38530234B0 +:1009DC00F7E780208DF8630026780F2E58D80597FE +:1009EC00671C75004FF0000806AC454552D007EB6C +:1009FC00080029F07FFA24F8080008F10208F4E74F +:100A0C00084629F077FAADF81800687E06A928F098 +:100A1C000FFD0EA921201BF0D1FB8DF8580016AB51 +:100A2C006520212111E0084629F064FAADF8180080 +:100A3C00687E06A928F0FCFC0EA922201BF0BEFB48 +:100A4C008DF8580016AB65202221012221F096FE6C +:100A5C00C6E0002840F0B680042009F001F8B4E0AC +:100A6C0080200EE0BAF1100F0DD80EA900204A46D6 +:100A7C005346CDE9001BCDE9027016A8414615F08E +:100A8C0031FA8DF863000DF1630365200621A3E0B4 +:100A9C0080200FE0BBF10F0F0ED80EA90020CDE97E +:100AAC0002645246CDE900B1049016A8059B494654 +:100ABC0015F0C0F98DF863000DF16303652020215A +:100ACC008AE016A90EAD2A4618F03CFE04469DF8A5 +:100ADC005800F0B1614904EB4400002641F8206055 +:100AEC0001EB800046609DF94B00B0F1FF3F03DC49 +:100AFC0005F1130023F03AF80EAD1421284629F025 +:100B0C0007F90420214614222B4625F097FD8DF879 +:100B1C00186006AB652024215EE0182029F0EEF960 +:100B2C00002800F083800446BDF83800002118220C +:100B3C00234628F01BFB0546002818BFC8251920A2 +:100B4C0029F0DCF9002867D007460130002D4BD086 +:100B5C001821FF2229F086F850E0002049218DF859 +:100B6C00180006AB652037E001208DF838000EAB7D +:100B7C0065204A21132230E029F01DF9044605F1C5 +:100B8C000D0029F0B7F90246691D204625F05CFBE3 +:100B9C008DF838000EAB652051211DE0522021F05C +:100BAC00EDFA2748002104E0522021F0E7FA24480E +:100BBC000121017002E0522025F09EFB0EAB652056 +:100BCC004D2109E001208DF8380004F0E0002028C8 +:100BDC0005D10EAB65204021012221F0CFFD002470 +:100BEC00204619B0BDE8F08F3146082228F028FCC9 +:100BFC0007F109002146102228F022FC652025214E +:100C0C0019223B463D7021F0B9FD3846192129F0D7 +:100C1C007FF8384629F070F9002CE0D020461821D6 +:100C2C0029F076F8204629F067F9D8E7C825FFF7B0 +:100C3C00DEBB00BFA86D002024260020D02600209B +:100C4C00E52700209A7A0020A5270020882600207E +:100C5C00B96A02007F70020019500100F0330020C5 +:100C6C00019F02002DE9F04F99B080466FF007000C +:100C7C00DFF8DCA80630ADF852009AF80000022824 +:100C8C0014D1DFF8C808007880B9B8F8080010B1A2 +:100C9C001020012101E0302000210AF0E5FD0020A8 +:100CAC008DF81C0007A9522021F068FA0DF11C09DF +:100CBC0098F80810D8F804004A4610F089FAE8B100 +:100CCC009DF81E609DF81F409DF82050BDF82670C1 +:100CDC0028F0BCFD844211D127F003004FF6F871C7 +:100CEC0080B288420AD0012D08D8022E06D29AF87A +:100CFC000000022808D19DF84D0028B1D32019F02E +:100D0C0076FC19B0BDE8F08FB8F82800ADF84800B3 +:100D1C00B8F83200ADF82A009DF82200D0B1D8F80E +:100D2C0004109DF81D209DF83830012027F034FB6D +:100D3C0008B1CF20E3E7DFF81C08C078012809D1FF +:100D4C00B8F8280028F0A7FF20B1417901F0E7019D +:100D5C00083141719DF8210068B1BDF82610FF20C3 +:100D6C0026F00CF89DF82110E0B141F001012C2681 +:100D7C008DF8211017E09DF83900002800F0EB8069 +:100D8C009DF83D10FF2902D0002940F02681DFF8A4 +:100D9C00C807BDF82620C18A8A4240F0278101206D +:100DAC00222607E0082601F00300012808BF46F0C0 +:100DBC00110601209AF800104FF6F877012908D88F +:100DCC00B207344658BF64F07F04002808BF34468D +:100DDC0000E034469DF82200DFF87C575FFA84FB74 +:100DEC0030B9E87A20B10BF02200222840F0808044 +:100DFC001BF0400004901CD0012903D8A87B80076D +:100E0C0000F1D880119801780C2900F2DB800122C6 +:100E1C0041F298438A401A4200F0D480032902D14F +:100E2C0040780D2805D007A822F0F4F901283FF4EA +:100E3C0068AFA88CB8F8441081420AD198F84620C3 +:100E4C00B8F84210B8F8280000230093002307F0EC +:100E5C0001FE9DF82200F8B1B8F84210B8F828004D +:100E6C0022F0E4FC002800F08F800646D8F804003D +:100E7C009DF81D10F2780844417B8A421EBF002267 +:100E8C007260F1700130042125F072FC71688842A7 +:100E9C00FFF437AF013070609AF80000022834D2AA +:100EAC00A87B80077FF52DAF9DF84D004FF6F876A7 +:100EBC0060B1BDF8280027F0BBFC002800F00781CA +:100ECC00D8F80400417801F0DF0141709DF82E0044 +:100EDC00002800F0DF80D8F8040081790139817195 +:100EEC008DF82E1004F07F00090640F0D680D3E078 +:100EFC000BF0420042287FF41CAF1198007800F0F0 +:100F0C00FE0006287FF415AF72E77FF4FAAE95F871 +:100F1C002600092802D004287FF4F3AE5FEA8B6028 +:100F2C0000F19E80049800283FF4EBAE11989DF8D8 +:100F3C0038100078042808BF022900F045810728E2 +:100F4C0008BF042900F009810C2840F04D8107A846 +:100F5C0015F080FBD5E6BDF8260022F0E7FE02383E +:100F6C00DFF8F415B0FA80F0CA8A4109BDF8260002 +:100F7C00904208BF023100293FD09DF81E20002A64 +:100F8C0056D001F1400455E09DF84D00B8B3042053 +:100F9C0026F0CEF900283FF4B4AE01464FF4B270FF +:100FAC000880B8F828004880DFF8B00500781EF0FB +:100FBC00D5F8A6E611980178A1F10C0212F10C0FEC +:100FCC003FF62CAFE88ABDF8262082427FF496AE1D +:100FDC00BDF8280024F0AAFA90E6109A9DF83C007F +:100FEC0020F0DEFF30B101200026E3E690F8260069 +:100FFC000428F8D100260020DCE600241AE095F83D +:10100C006C0001287FF448AF11980078062803D1B2 +:10101C00049800287FF440AFF81DBDF82A1080B268 +:10102C0081423FF46EAE07A841461EF02BFB68E6EA +:10103C0001F1200422F07AFE0138B0FA80F0400968 +:10104C0044EA00069DF81E0000283FF4B2AE119849 +:10105C00007827F041FC012818BF04F07E06A8E6B2 +:10106C0098F8460028F0D6FA9DF82E00012840F09A +:10107C00B480B8F82800BDF82810814240F0AD804B +:10108C00BDF8260022F052FE022804BF00208DF885 +:10109C002E00A2E004F07F000446210702D44FF09A +:1010AC00000A34E0E1B24A0722D4C9069DF82110A7 +:1010BC0028D5C1F3820212B1072A18BF013A002ABF +:1010CC0008BF044601F0E30040EA820118E0D32097 +:1010DC0019F08DFADFF888040078002800F09F8062 +:1010EC00DFF8801451F82000C0EB0010810098E06C +:1010FC009DF8210000F0E00100F0E30040EAD1018E +:10110C008DF82110D8F804004FF4805A017295F82C +:10111C002600092801D0042823D1E98ABDF826002D +:10112C0088420AD022F002FE022806D09DF8210047 +:10113C0000F0030001287FF4E4AD9DF81E000028A8 +:10114C0047D011989DF838100078042808BF022960 +:10115C003AD0072848D1042946D107A817F0C2FF76 +:10116C00CFE5E7B214F0610F46D0F80709D0B8F814 +:10117C00281007A8A94615F0B5FC002864D004F087 +:10118C009F040025E7B2A00609D598F84600D8F8C8 +:10119C003C2028F03FFA07A815A905F06BFC78064F +:1011AC0040F12681B8F8281007A80DF152022B4601 +:1011BC0010F08AF800286FD00546119800780128A5 +:1011CC0008BF4AF0100A13E107A9002010F024FE12 +:1011DC0097E598F8460028F01DFAD8F83C2007A8A7 +:1011EC0015A905F047FC8CE503287FF48AAD07A808 +:1011FC0000210FF079FC84E59DF81E0001285AD1DE +:10120C0011980078032849D0052854D1B8F8281033 +:10121C0007A80DF15202002310F056F871E5D148E1 +:10122C000168D1480268BDF82800904701287FF476 +:10123C0068ADCE480168BDF828008847CC480168E5 +:10124C00BDF8280088475CE526F034FC9DF82E108C +:10125C000546BDF8280019B9B8F82810884291D075 +:10126C00B9F81610814204D1BA48807800283FF4AE +:10127C0089AFB8F8281007A82A460AF0B9F8002850 +:10128C0000F09B8038074AF0040ABDF8260048BFDE +:10129C00F01DADF8520075E70025A9E0BDF8260059 +:1012AC0027F0C6FA38B1B8F8281007A80DF1520289 +:1012BC00002310F009F89DF82E0088B323F0CAFE25 +:1012CC0000287FF41EAD9DF83900A0B3109A9DF84C +:1012DC003C009DF83D1020F063FE002870D09DF876 +:1012EC003D00002875D0109928F098FC9DF824300A +:1012FC00ADF8520011209DF823209DF821104AF0E2 +:10130C00400A002B08BF0920002A18BF083000290A +:10131C0018BF0130D8F804100A5C013A0A5462E094 +:10132C009DF81E0001287FF47EAE119800780328EA +:10133C003FF4E7AC77E69DF82010BDF826000029B5 +:10134C00ADF8520000F0D3804020BDF8261009F112 +:10135C001D0200EAC4059DF820002B4618F048FE3B +:10136C0038B1D8F804004AF0200A017801F03F01A6 +:10137C0001709DF8390048B1BDF8261009F1200024 +:10138C0021F02AFF4AF0400AADF852009DF81E00E9 +:10139C00012806D0BDF82810BDF82600002214F054 +:1013AC00ABFFBDF82810BDF826002A4612F0D2FB80 +:1013BC00002818BF4AF0200A15E004F0DF04E0E62C +:1013CC00BDF82610BDF828000B2200231AF033FDBF +:1013DC0097E4BDF82600ADF8520028F05CFC00281C +:1013EC0008BF4AF0400A26F065FB05464FF6F87632 +:1013FC00B01DBDF8521080B20F1A5E4818BF2F46B0 +:10140C000078012805D1F01DB8F8321080B2814265 +:10141C002FD160B2B0F1FF3F3FF773AC002F3FF418 +:10142C0070ACB8F8080028F069FD00283FF469ACEE +:10143C00B8F80820D8F80410054628F001F89DF8F3 +:10144C001E10002098F80830B8F8282016908DF857 +:10145C005410BDF8521015ACCDE9007ACDE9020458 +:10146C00284610F065FC70B3284628F045FDFFF7C0 +:10147C0048BCB8F828108142CBD0701CBDF826208F +:10148C0080B28242C5D2BDF828008142C1D028F07A +:10149C0002FC0028BDD0017901390129B9D8408856 +:1014AC0001218DF85410ADF8600015AD28461EF0E2 +:1014BC0059FD0028ADD0281D1DF048FD0028A8D0EE +:1014CC0021F0D4FFA5E72348407800283FF419AC5D +:1014DC0000208DF81870ADF81900DDF826004FEAE1 +:1014EC003040059005A827F037FEFFF70ABC3907F6 +:1014FC003FF52AAF9DF81E1001293FF425AF0021BE +:10150C0018F036FD20B1407901380228FFF41CAFE9 +:10151C00B8F84410BDF8520022F088F930B1807848 +:10152C0026F0F8FC01380728FFF40EAFBDF82800B0 +:10153C0027F07EF918B104208DF8200004E7BDF8DF +:10154C002610BDF8280002223FE700BFE527002047 +:10155C0024260020E8250020A86D00209C7A00207D +:10156C00D727002090B40200942300209C23002055 +:10157C0098230020E32700202DE9F0438DB0054689 +:10158C0080780224252800F27380DFE810F0260012 +:10159C00A400C400D700EA00F8000601B602B602A7 +:1015AC001D012E01B602B602B602B602B602460103 +:1015BC004B01B602B602540158016101B602B602E3 +:1015CC00B602B602B602B602B602B602B6026B019B +:1015DC006E017101740178017F01DFF8D47500246C +:1015EC000E258DF804403878012807D801A81DF085 +:1015FC0073F904469DF8040005EB4005EEB2304645 +:10160C0028F07CFC002800F087824FF0000805468B +:10161C00431C0021082280F80080012027F0A6FD41 +:10162C0028F01AF96872000A0721A872DFF88405FD +:10163C00E972007828733878012800F262829DF8EC +:10164C000420002A6A7300F05E8205F10E0000216E +:10165C002346914280F0578213F8022B013100F897 +:10166C00022B13F8012C00F8012C9DF80420F0E754 +:10167C00A0F140010D291FD8DFE811F00E00100178 +:10168C003F023F021E012E013F023F023A0145017B +:10169C00500165013F02740101ACE91C0822201DB8 +:1016AC0027F0CEFE204619F0EDFFBDF806004021D4 +:1016BC00ADF828000AABEEE0632800F069816428DD +:1016CC0000F07681E02840F0188200244720E021C9 +:1016DC00002200230FE2202028F010FC002800F04C +:1016EC00C1812021FF22044628F0BCFA631C012092 +:1016FC000021082227F03AFD0546002818BF0125D5 +:10170C0001AB84200021042227F030FD002800F0DA +:10171C000582023506E2E81C28F0ECFBADF804006B +:10172C00832028F001FB014601AA832028F0C6F98A +:10173C008DF828000AAB6720022190E1E81C0421F7 +:10174C0025F016F80190842028F0EEFA014601AA43 +:10175C00842028F0B3F98DF828000AAB6720032108 +:10176C007DE1612028F0E0FA0146EA1C612028F0B6 +:10177C00A5F98DF8040001AB672004216FE162200C +:10178C0028F0D2FA0146EA1C622028F097F98DF86D +:10179C00040001AB6720052161E100208DF80400F5 +:1017AC00E81C28F0A7FB6A7900F4F851002A00F035 +:1017BC004981B1F5A06F04D04FF6FF71884240F01B +:1017CC004B814FF0FF3045E128F06AFB044628F0CE +:1017DC0065FBD949604301ACB0FBF1F1204628F020 +:1017EC00F6FA672009210422ABE0DFF8B4632D7907 +:1017FC00306840B901AC204627F0F0FE01202146AC +:10180C000EF03AFB3060052D00F06981002D00F0E0 +:10181C006981642122F01AFA66E115F8032B67201E +:10182C0010216EE0E87823F011FF8DF8040001AB75 +:10183C006720112113E100246720142102E0002409 +:10184C0067201521ADF80840019401AB062252E146 +:10185C0000246720162109228DF80C40CDE90144A3 +:10186C0001AB48E1F52020210BE0F520212108E017 +:10187C00F520222105E04FF6F570232108E0F52034 +:10188C0024218DF8040001AB6720E8E0F520252128 +:10189C00ADF8040001AB67200222E1E0E81C28F05F +:1018AC0029FBADF8060001AC204617F0D7FB231D31 +:1018BC00672041210822D3E0E81C0AA926F02CFF5E +:1018CC0000288DF8040000F0CF8001A81821FF2219 +:1018DC00013028F0C7F9F4E0E81C0AA926F01CFF37 +:1018EC0000288DF8040000F0F1804FF0FF30EFE09D +:1018FC0015F8030F697822F071F9288067204821C8 +:10190C0002222B46ACE0E87825F080F801AC0146C9 +:10191C00204618F06DFD6720492111E0EC1C204693 +:10192C0026F0C6FB002818BF2046B5F80B1019F09E +:10193C0039FA01AC0146204618F05AFD67204A21BD +:10194C00242223468CE001ACE91C0822204627F017 +:10195C0077FD204627F04CFB8DF828000AAB67205A +:10196C004B217CE04FF0FF3095F80380691D01900E +:10197C00ADF81000CDE90200FE208DF806002879A4 +:10198C0003288DF8300020D10AA828F062FA21E053 +:10199C000024E91C08228DF8284001AD284627F0C8 +:1019AC004FFD28461DF0D2FA0AAB67206321A1E057 +:1019BC00B5F80B006A7B0024E91C8DF804400AF092 +:1019CC0085F901AB6720642194E0084628F092FA6F +:1019DC00ADF82800AF7B002F00F0DD807E0095F87D +:1019EC000D90304628F08AFA002800F0D48005F1DA +:1019FC000F013246044627F023FD00940AA9404605 +:101A0C004A463B460DF07EFA002800F0BA808378F7 +:101A1C0001784278057946798DF806308DF80410F6 +:101A2C008DF80520C3788DF809608DF808508DF875 +:101A3C00073001A98B1D811D40794200184627F003 +:101A4C00FFFCA5E0B1F5A06F03D04FF6FF71884203 +:101A5C0002D100205549086001AB67200621012204 +:101A6C0020F08CFE002448E0182028F047FA40B300 +:101A7C00BDF828100446009006200022182324F0FC +:101A8C00C7FDB8B9BDF8285001AE21461022701C14 +:101A9C0027F0D6FC444F05EB450506F1110057F82D +:101AAC00251028F094F907EB8500416806F1150024 +:101ABC0028F08DF92046182128F02AF9204628F024 +:101ACC001BFA01AB672044211922C9E7BDF8280095 +:101ADC00ADF8050001AB672045210322C0E7314971 +:101AEC0001220A7021F049FA002467200A218DF89E +:101AFC00044001AB012220F041FE20460DB0BDE8B0 +:101B0C00F08385F80D806720002132462B4620F0AB +:101B1C0035FE284628F0F0F97CBBA3E7019800BA03 +:101B2C00C4F809000AAB83200021022227F01EFB17 +:101B3C0020B1043506E000BF40420F00BDF828007C +:101B4C00A4F80D0004F10F0361200021012227F0FD +:101B5C000DFB002804F1100318BF0835622000218A +:101B6C00102227F003FB0028234618BF10356720EE +:101B7C0001212022257020F001FE204628F0BCF91E +:101B8C0070E74FF6FF70ADF808006FF480300190ED +:101B9C00204628F0B1F901AB67204D210E225FE7FA +:101BAC00287A0020A227002030750020087A002017 +:101BBC0024260020D02600202DE9F04F85B0847813 +:101BCC000226362C00F2BF820546DFE814F06B01CA +:101BDC00730172007B017800BC02BC0281003700EB +:101BEC004C008C009F00AD00BC02B5008F01BC0204 +:101BFC00BC029901AC01BA01BC02BC02BC02BC0221 +:101C0C00BC02BC02BC0237004C00BC02BC02BC02D1 +:101C1C00BC02BC02BC02BC02BC02BC02BC02BC02C8 +:101C2C00BC02BC02BC02BC02BC02BC02BC02BD00B9 +:101C3C00EB00CA01FF005B005B00DA0128F0AFF893 +:101C4C00242840F0A98102AB352000210422002475 +:101C5C0027F08CFA002800F0FB81012002228DF87D +:101C6C0010000020FBE100208DF8100028F097F800 +:101C7C000646092C40F0EC8095F8059095F8068006 +:101C8C000720EEE0DFF82465306880B1406A70B15F +:101C9C0002A928F08DF80546342C40F02A822846FB +:101CAC0028F028F9002800F02382042042E20320C7 +:101CBC0040E2DFF80835612002210A2240E202AC42 +:101CCC00E220214624F018FB61200421082287E140 +:101CDC0028F065F80446681D28F00CF9242C40F017 +:101CEC0086810020F9E1E878032800F29681281D0E +:101CFC0028F000F90246E878DFF8B81431F8101033 +:101D0C00DFF8B404007828F05FF887E1E87803285E +:101D1C0000F28881DFF89C1431F81010DFF8980479 +:101D2C0000781DF059FE7EE127F06EFFADF808003B +:101D3C0002AB61200C2102E1002661200E21012260 +:101D4C008DF8086002AB1CE2DFF8606401208DF8AE +:101D5C0010003068002800F02B810069002800F08A +:101D6C00278102A928F024F8042124F001FD002881 +:101D7C0000F0ED81044628F0C1F8002800F01B812A +:101D8C002146054627F0C4FF3068BDF80C102246EA +:101D9C002B4606690298B0478DF81000284628F0AB +:101DAC00ABF808E1DFF804442068002800F0078154 +:101DBC008069002800F0038102A927F0F9FF206850 +:101DCC00BDF80C10826902989047F9E0DFF8DC73DB +:101DDC003868002800F0FA80C069002800F0F6800E +:101DEC0002A927F0E5FF9DF80850BDF80AB0BDF830 +:101DFC000C90044628F07EF8A6788046F72E28BF73 +:101E0C00F726B01C5FFA80FA504628F077F80028C5 +:101E1C0000F09F81012D044608BFBBF1000F00F0BC +:101E2C009C813868A11C42463346C56902980091D2 +:101E3C004946A8470746002840F0958100276120B5 +:101E4C003321524623466670277020F097FC8AE1B6 +:101E5C00681D28F04FF88146E81D28F04BF88046A5 +:101E6C00092002AF242E18BF2F1809EB080508BF54 +:101E7C003526304627F058FF854201D9022059E11A +:101E8C00B9F1000F04D1304641463A4623F098F997 +:101E9C00304641463A4627F011FE002800F0E58016 +:101EAC000A2047E1E878012802D0002840F04A8156 +:101EBC0027F02EFB40F259600121ADF8080002AB6F +:101ECC0061203CE00120EC1C8DF80800E22021464A +:101EDC0020F054F930B901200821224627F0EEFDFC +:101EEC008DF8080002AB6120032128E1E878291D58 +:101EFC00012800F0E080002840F0E480E020DEE0E3 +:101F0C0027F04DFF0446681D27F0F4FF242C0FBF6B +:101F1C0000200146204627F0AFFE8DF8080002ABEA +:101F2C00612012210BE127F03AFF24280CBF00207E +:101F3C0027F0FAFEADF8080002AB61201321022253 +:101F4C00FEE0E8788DF8080099488068D0F83024D5 +:101F5C0002A9E02090478DF8100004AB61201421F9 +:101F6C00EDE0924C206898B3806A88B302A927F000 +:101F7C001FFF2068BDF80C10826A0298904701463A +:101F8C0027E08A4C206868B3C06858B327F007FF75 +:101F9C002168C968884726E083466938002680B2E4 +:101FAC00032838BF0126681D082C40D1057841E074 +:101FBC0003208DF8100004AB61203021BFE003201A +:101FCC008DF8100004AB61203121B8E00327CFE07D +:101FDC00002102AC204627F0FAFE612032210422B7 +:101FEC002346ADE0032027F0ECFD3621A7E005F1F8 +:101FFC000806ED790146A8426BD92046002227F04D +:10200C0057FD09288DF8080069D1002D67D02046AE +:10201C002946324627F052FD61E0022027F0D1FD1F +:10202C000A218CE0022027F0CCFD0B2187E027F061 +:10203C0061FF0546584627F077FE0227A84288BF65 +:10204C007700CFB100268DF808706120214694E00E +:10205C0002988DF810400422ADF8120002208DF881 +:10206C00110004AB612008216AE0012E64D1E2204A +:10207C00394620F083F85DE0401B87B2F72F28BF6C +:10208C00F727B81C5FFA80F8404627F037FF002886 +:10209C0061D000F1020A81463946504627F038FEDD +:1020AC00584629463A46534627F060F8054600281C +:1020BC006AD00A2773E00878022814D2522020F044 +:1020CC005DF800E002208DF8080002AB61200F21C2 +:1020DC0035E02046324627F0EBFC8DF8080002ABC9 +:1020EC00612007212BE002A9522024F005F9ECE72E +:1020FC0002359DF8080015F8018B012811D1BDF8A7 +:10210C000A0070B9BDF80C7041462A46384623F0D7 +:10211C0057F8012F07D1E220294620F02FF801278C +:10212C0001E0BDF80C703068394642462B46466AD1 +:10213C000298B0478DF8100004AB612021460122B3 +:10214C0020F01CFB0026304605B0BDE8F08F0520C2 +:10215C002FE710270CE0102774E7A9F1690003287A +:10216C00BFF45FAE0227204627F0C6FE002FE9D051 +:10217C0000268DF80870612033218DF8096002ABC0 +:10218C00022220F0FBFADEE789F8017000276120BB +:10219C00214642464B4689F8007020F0EFFA48463B +:1021AC0027F0AAFE002D7FF44DAFCBE76827002067 +:1021BC000C01002054BA02009A7A0020F0B90200F7 +:1021CC002DE9F04F9DB00446DFF89C05406818B12E +:1021DC008047002800F05682DFF890A5DFF890B514 +:1021EC000D940DF138099AF80000411E002C0B914A +:1021FC000BF1180418BF01219BF802800027002561 +:10220C008BF80F109BF801100C91C0B287421ED2B4 +:10221C00B84517D0FEB200214A460423304627F0B9 +:10222C00D7F80E9810F4403F40F00400C0B218BF2D +:10223C0001357C2806D130460621F82226F03CF8E0 +:10224C00F82020709AF800000C340137DDE7E9B271 +:10225C0001380024884204D19BF80500002800F0C6 +:10226C007F82DDF83490CDF82880DFF8FC84B9F15A +:10227C00000F484608BF1020059015AD00200190B6 +:10228C00DDE90B740026380400F0FE819BF80F008A +:10229C0010B901208BF80F00E0B200210EAA042324 +:1022AC0027F096F80E98B9F1000F19D010F4403FB2 +:1022BC0019D04FF400509AF800100136013FABF8DA +:1022CC0010009BF80F0001388BF80F00012050FA1A +:1022DC0084F0B0FBF1F202FB11048BF80D40D2E755 +:1022EC000021049102E0CDE90B740496C0B20A9E61 +:1022FC004FF0000A702804D00C987021C0B222F064 +:10230C001BFB5FFA86F900210EAA0423484627F02E +:10231C005FF89DF83800FE2803D04846FE2122F0D5 +:10232C000BFB48460621FE2225F0C6FF4FF4005059 +:10233C000C9F0BF11601ABF814A000228BF80C606B +:10234C00ABF81000FF2088F800208BF80E00F8B2D4 +:10235C008BF80D70400050FA87F001EB8000B0F85C +:10236C0006A04FEA490050FA86F09BF80F6001EB8B +:10237C008002FE20ABF812A0114601F8020F32F8D1 +:10238C00060F03910890DFF8E4030292047814A876 +:10239C0021F090FD56FA87F0CDF82490013890FB8F +:1023AC00F4F101FB140000905FFA87FB0C97CB450E +:1023BC0000F06281ABEB0900B0FA80F040090790A5 +:1023CC00002006900020DDF83490C00740F09E807D +:1023DC001FFA8AF4162C6ED998F80000002840F0E9 +:1023EC007381AAF1070758460FAAB9B218F0C0F8C2 +:1023FC00BDF84A6006F11000A0423BD89DF846009B +:10240C00962837D1A7EB06099DF8452031465B4647 +:10241C001FFA89F840461BF043FE58BB9DF8470055 +:10242C00C10701D1800704D40020CA46DFF83883E5 +:10243C00C9E7F01D83B2089813FA80F4B4F5005F75 +:10244C0001D90120F2E780B2CC4918440A1A584647 +:10245C00414626F0BDFF06980130B4F5005F0690AA +:10246C0004D101204FF400510891DEE70020CA4648 +:10247C000894DBE7AAF1010ADFF8EC825446A0B21B +:10248C00172836D33628A4F1160658462A4688BF94 +:10249C002026A41BB3B2A1B226F09AFF3004EED0D2 +:1024AC0015FA86F010F8010C962801D0013EF5E7DC +:1024BC0006EB040A86E7069810B1AD4927F0DBF865 +:1024CC000098C0B2834500F0DB800C990120DDF848 +:1024DC00249050FA81F0A5490978B0FBF1F202FB87 +:1024EC001107A34907EB470001EB8000B0F81CA0D3 +:1024FC005AE7A0481499006842689F48904700200A +:10250C0007900C980A90DDF8349008E0069810B10A +:10251C00974927F0B0F8002007900C980A9098F88B +:10252C000000002840F0D08008981021C0F500521F +:10253C00103883B20998C1F2001221F0D7FC98F838 +:10254C0000100843149988F800008A480068426813 +:10255C008948904707980A9A88B1844800780BEB11 +:10256C000001013991FBF0F202FB10128049D0B24C +:10257C00400050FA82F001EB8000B0F81CA0DFF8AC +:10258C00F0B108990298099C01238BF80E20018068 +:10259C00ABF81010BBF912209BF80D102046ABF8CD +:1025AC0014A023F05FFDBBF914209BF80E102046FD +:1025BC00022323F057FDBBF81000049CB9F1000F67 +:1025CC00C0F5005007D00599DFF8A0A18842A4BF40 +:1025DC000121019101E0DFF894A1059988424FF0A7 +:1025EC007C01B8BF7821099E304622F0A5F90DF088 +:1025FC00E3FE07469BF80F000621FC22C01B8BF85C +:10260C000F00304625F058FE0399FC209BF80E3045 +:10261C0008709BF8021017FA84F00C9301449AF896 +:10262C000000B1FBF0F202FB10118BF802100A91C2 +:10263C000131CAB2B2FBF0F202FB10118BF801109F +:10264C0003EB43010BEB8101898B102906D10C990B +:10265C000131B1FBF0F202FB10100C900B98C01B77 +:10266C00B9F1000F0B903FF40BAE019880F0010014 +:10267C00C0077FF405AE07E00120CB46079042E788 +:10268C0000984BE700246BE07C2022F06FF90446A5 +:10269C00FF284ED17E2022F069F90446FF2848D14C +:1026AC009BF8014004EB44000BEB8000807DFF287D +:1026BC003BD09AF800009BF802100144013991FBC1 +:1026CC00F0F202FB101434E02A48149900684268B6 +:1026DC0029489047264E254F00253878854213D23D +:1026EC00ECB2204615F0CEF898F80010084388F8A4 +:1026FC0000003DB138780138854203D020467E2158 +:10270C0022F01AF90135E8E7B18B01380024B070DA +:10271C00C0B2F4707470F180FE2122F00DF900202B +:10272C007C2122F009F974711AE020467E2122F0F6 +:10273C0003F9E0B2FE218BF80340400050FA84F01C +:10274C000BEB8000808BABF806009BF8020022F0AC +:10275C00F3F800208BF80500BBF81000C0F500540E +:10276C0020B21DB0BDE8F08FA02300209B7A002082 +:10277C00B8720020D8010010004003400020001166 +:10278C002DE9F04F8FB00C4648070FD4200441D4EC +:10279C00E00400F19781200600F1C081A00700F150 +:1027AC00D481200500F1F3810020B4E1DFF820058D +:1027BC000178062900F2AD81DFE811F007009401E1 +:1027CC00AB01AB019901AB01A001DFF81055DFF8AB +:1027DC0004152A7891F82B30022A02D19E0600F1BA +:1027EC0098815E0700F19D819B0740F19281042343 +:1027FC00037091F82C30DB0700F08B8191F82E30B0 +:10280C00002B00F0528225F09EFC0420012101F0E7 +:10281C00EFFF57E2DFF8C8040394DFF8BCB4DFF82D +:10282C00B094DFF8C474DFF8AC44DFF8B054DFF8D0 +:10283C00BCA448F20208008802909BF800001CF02F +:10284C0031F9002800F03A8106460078D3282DD1C2 +:10285C00F089404540F019813878002800F0158146 +:10286C0099F80000012840F0108126F031FD002875 +:10287C0040F00B817088002840F00781A24604AC20 +:10288C001221204627F044FA27F016F8304621464C +:10289C0018F096F9BDF81C00B0F5285FC0F08880E0 +:1028AC00012002211FF016F854462AE099F8001076 +:1028BC00884217D1012834D0032840F0E6802878CC +:1028CC000138012800F2E180B078012851D00028AD +:1028DC0040F0DB807078002800F0BF8000201DF0F5 +:1028EC0059FCD2E00A2811D194F82B00BA46B71C37 +:1028FC003071A16909B138468847384625F0AAF8E5 +:10290C005746DFF8D853DFF8E4A3BEE02978002956 +:10291C0040F0BB80092840F0B880A168B01C884703 +:10292C00B3E028780138012800F2AF80707860B1EC +:10293C0094F8330094F83410013084F83300C0B2AA +:10294C00884202D9012000219DE099F8010003285A +:10295C0058D0022871D0012840F097803878002890 +:10296C0000F08C8026F0B4FC002800F0928001204E +:10297C0085E07078002875D026F06EFF4FF6FE715A +:10298C00884203D1BAF81600884207D0AAF816106C +:10299C00ADF8281053200AA91FF0F0FB1EF00EFB17 +:1029AC0025F0B8F800208AF826001DF03BF96CE001 +:1029BC00CF48006809A90AAA16F0C4FE0746029877 +:1029CC005446C64DDFF824A3874212D29DF8380036 +:1029DC0010B1FD208DF838000420394614220AABC2 +:1029EC0023F02CFEC34907EB470001EB80000121CB +:1029FC0041720020012184F83200012001F0F8FE20 +:102A0C00B94F42E0A2460AACAB20002122461CF092 +:102A1C0071FA042004945446DFF8D0A2AF4D8DF81F +:102A2C00140004A80FF054FB26F046FF9BF800009E +:102A3C004FF4805141F288321DE0012020714FF497 +:102A4C008060ADF828000AA818F0E2FD26F034FFEB +:102A5C00A4484FF4805102680BE010F0F9F860695B +:102A6C0098B9A2E702204FF4805140F6B83289F8A9 +:102A7C0002009BF8000027F0A7F906E0002084F87C +:102A8C0032000120012101F0B3FE304625F02EFB6F +:102A9C00D3E694F8350020B1E0690028F5D08047E2 +:102AAC00F3E70020002102220023ADF828000220C9 +:102ABC008DF830000AA825F0D1FCB5E7039880F416 +:102ACC00004028E0854800780138012859D8804812 +:102ADC00017803294DD0012953D1417800201EF0F3 +:102AEC00F9FE4EE0012001211EF0F4FE11E025F06C +:102AFC002AFB0420012101F07BFE0AE00021322296 +:102B0C000170744880F82A1073480421007827F06B +:102B1C005BF984F004000FB0BDE8F08F84F0800006 +:102B2C00F9E70522027091F82C2092072CD591F828 +:102B3C002E204ABB052202600120487000201CF0A8 +:102B4C0097F8022024F05CFDE3E764480078013834 +:102B5C0001280BD80020CDE90A000AA812F024F8AD +:102B6C0020B15D48022100781BF0CAFA84F0020003 +:102B7C00D1E78178022904D10121817000201EF057 +:102B8C0085FE84F48050C6E705200021B3E7534846 +:102B9C000078002840F08680DFF838A1DAF80C5075 +:102BAC00002D79D004A80DF1280B01300BF104068F +:102BBC000390002D6DD0A87A18B10138A8720006C8 +:102BCC0046D19AF83180B8F1000F11D00020A91C21 +:102BDC0008228DF82800304626F032FC584618F0B2 +:102BEC0051FD28B12A88BDF82A00314623F02CFB70 +:102BFC00AF1C0DF127015A46384616F0A3FD81464D +:102C0C00384609A923F099F8B8F1000F05D09DF8C2 +:102C1C00380040F0020002281CD1DAF80800A0B1FC +:102C2C0003983946082226F00BFC022000220C23C4 +:102C3C008DF81000BDF82400ADF81A002648007875 +:102C4C0004A90091092120F0D6F928461EF014F8A9 +:102C5C00ED68AEE7384623F0CAFD9DF82700012841 +:102C6C00DBD15846142127F053F8224A09EB4900CE +:102C7C0000215B4642F8201002EB800014224160D8 +:102C8C004172FF2049468DF83800042023F0D6FC11 +:102C9C00C3E7DAF80C0028B90F484FF4006100784C +:102CAC001CF09AFE84F4006035E7013A012A09D839 +:102CBC00032202600120487001201BF0D9FF012083 +:102CCC0024F09EFC287800287FF423AF04205CE7D6 +:102CDC000C7A0020AC220020A37A002024260020AD +:102CEC00C0BA020070270020BA270020A86D00206F +:102CFC00EC580020F03300202DE9F04F89B021F082 +:102D0C0079FBDFF810158122DFF81485DFF814A5A4 +:102D1C00DFF82045DFF814E50A70DFF8FC140860D2 +:102D2C00DFF8F804FF2101700020DFF80415A8F883 +:102D3C0000008AF80000DFF8F0040968007891F8C8 +:102D4C0008B04FF6FE718EF8000059448AB2A168A3 +:102D5C00D1F80031DB899A4200F267810422DFF856 +:102D6C00DC54A8F80020DFF8D02412689668330EE3 +:102D7C00CEF80C60C6F301592B706FF0FF0303EA19 +:102D8C001627B3B2D1F8B86047EA1327AEF804702F +:102D9C0036781EB9B9F1020F00F04781B9F1030F73 +:102DAC0000F043811B0A03F0070316B1002B00F05F +:102DBC003C81DFF88CC4042B9CF800C008BFBCF12C +:102DCC00000F00F032813EB1DFF878643678862E41 +:102DDC0002D1022B40F02981BB0416D4BBB203F004 +:102DEC000703022B08BFBCF1000F20D0DFF85414EE +:102DFC000978862909D10020764621F04FFBDFF8AF +:102E0C004004B64690F800C0307800284ED0BCF193 +:102E1C00000F4BD1012800F0088103283FD0022875 +:102E2C0044D1BEF80400400740F0FF803EE0D1F8EA +:102E3C00D40090F88300022800F0808027460520FB +:102E4C00147BF246A946A8F8000026F0CFFC0546F4 +:102E5C00DFF8F003007886286DD1B868016C09683A +:102E6C0011B9D0F84C05804760B20021002623F040 +:102E7C0012FDB9680A6C12685077086C0068867786 +:102E8C00086C0068C477284626F06BFFBAF804106B +:102E9C0099F8000001F010011CF018FF4EE0BEF88C +:102EAC00040000F00700032840F0BF80BEF80400C7 +:102EBC00010700F1BA80810402D4810500F1B580CC +:102ECC009EF80E20C2F38107012F00F0AE80960908 +:102EDC00012E00F0AA80B9F1010F11D840F00201C7 +:102EEC0001F0070103290BD117B93F2A40F29D804D +:102EFC0037B9A168D1F8AC100978002900F0958099 +:102F0C004FF6FB71B9F1020F0BEB010C19D1CF4B42 +:102F1C00D95D9B5D03EB01090023402AB7FA87F2C8 +:102F2C0038BF012352091A40430616D4002A08BFA1 +:102F3C0009F1020915E0284626F013FF25F06EFB77 +:102F4C0075E0C14B402AD95D9B5D03EB010908D3A9 +:102F5C00420648BFA9F1020903E0002A18BF4FF04E +:102F6C000209C0F300205FFA89F11FFA8CF30A1AE8 +:102F7C008EF801009A4258DC60440391B346401A23 +:102F8C00A168AEF806007430D1F8501280B28847B0 +:102F9C00A6490028886048D07421CDE9019726F015 +:102FAC00B7FEA24F0020B870A548007820B9387938 +:102FBC0000F020008AF8000078789AF80010DFF80A +:102FCC0078C24FF000092E4600299A493DD00028BE +:102FDC004FF000003AD1B88800F00700032807D062 +:102FEC00012832D18868D0F8D40090F8820060B300 +:102FFC00C8684069007818B125F06EFFFE280DD026 +:10300C008C488068D0F84C02804738B98948806871 +:10301C00D0F844028047002800F0F780834F01204D +:10302C00B870DFF814C22E4610E025F0B1FD26F082 +:10303C00DDFB814900240A6813681C7112680A6060 +:10304C0026F08FFE09B0BDE8F08F0020BC6804F1BB +:10305C00740184F830B06160A1657978BB88FA8816 +:10306C000029A381029B228184F83A30337808BF6F +:10307C009946B8F8003097F80EB0019DA4F85C2082 +:10308C00FF2284F84990A2735E1A797BCBF3011965 +:10309C00A8F8006001F0780160F3820101EB0900EF +:1030AC002074280600F0AE80DCF8000004AF039A10 +:1030BC0010FA86F000F10801384626F045FF56FA62 +:1030CC0085F0CBF38105A8F80000207C00F04008C7 +:1030DC00CDB3B9F1020F06D1B8F1000F03D0B4F89B +:1030EC00440004AF06E0BDF810000237A4F8440019 +:1030FC00A4F84200564EF189884203D04FF6FF7176 +:10310C0088425ED1032D11D104F13200394626F0EC +:10311C00A0FE464CF11CA068323024F018FC454946 +:10312C0000284ED094F80EB008370EE037F8020B9A +:10313C00B1898842608606D04FF6FF713B4C8842BD +:10314C003C493ED101E03B49384CBBF1400F20D308 +:10315C00B9F1020F06D16DB9B8F1000F0AD133489D +:10316C00806803E0A068017C490603D439880237E3 +:10317C00A0F84210BBF1C00F06D32C4C3946A06806 +:10318C00283026F066FE03E0284C3888A1680885B4 +:10319C0028498968A088D1F8AC201278B2B1B9F16D +:1031AC00020F13D200F00700012802D003282FD100 +:1031BC001E4C6DB9264AA368D289B3F842309342AB +:1031CC0006D01FF01AFA19F011F930E700F00700D9 +:1031DC00032806D0012815D1D1F8D40090F882002C +:1031EC0080B1A068D1F848128847104A50B9002025 +:1031FC00D17B9070907BC1F3011100F078000844F2 +:10320C009168087408F0ECFB11E7084FB87808E7F0 +:10321C00064CDDE7B07A0020387A0020B57A002021 +:10322C00BE780020B37A0020B27A0020342500202A +:10323C00787A00200C010020D8790020C37A002075 +:10324C00C27A0020B87A002048BA020044BA0200C0 +:10325C00007900202DE9F04F97B0DFF80C8505467A +:10326C00DFF8086598F800000328307040F04981B9 +:10327C00002088F8000030700DAC204626F0F5FDDB +:10328C002046002125F0D8F9DFF8E494B0603A210B +:10329C00484626F03DFD4FF0FF30A9F81400C9F860 +:1032AC001000C9F80C0022F0F3FE002029461EF095 +:1032BC0065F806F11001F06026F065FDD6E905020F +:1032CC00DFF8B074B0FBF2F1C9B2032928BF0321B7 +:1032DC00B2F5005F89F80010397040F00F81B0EB47 +:1032EC00413FC0F00B81F068002800F007814FF4DB +:1032FC000050FF224FF000084FF0885BA9F8060041 +:10330C00FF2089F8032089F805800590002008909B +:10331C0000200B90002009900020079000200690C0 +:10332C0000200A9000200C90FF200290FF200490B7 +:10333C00FF200390CCB2A04580F0E6805FFA88F6BF +:10334C00002116AA0423304626F042F8DFF82C445C +:10335C003046002115AAA0473046012114AAA047E7 +:10336C003046022113AAA04716996FF06F0050FA4D +:10337C0081F2C8B20E2A06D8012303FA02F245F2F2 +:10338C0001131A4203D1A0F1FE02022A04D242F226 +:10339C008352B2EB914F1ED0304614F073FADFF823 +:1033AC00CC130028087040F0CF803046002116AABC +:1033BC00042326F00DF8DFF8C4433046002115AA8B +:1033CC00A0473046012114AAA0473046022113AA77 +:1033DC00A0471699C8B208EB48023D46CA4609EB0D +:1033EC008204C1F30142090AE1759DF8561004F1FB +:1033FC001609FD28627689F80000217601D9102182 +:10340C0036E0BDF854104FF6FF72914230D10EA841 +:10341C0020F050FD304600214FF088524FF40053FD +:10342C004FF4005725F0D4FF6FF0030313FA87F71E +:10343C00B8B250F80B104A1C01D10328F6D801225F +:10344C000126D3B2042B06D8CBB2FF2B18BF1646DD +:10345C000132090AF5E740F80B10C9480E990068CB +:10346C004268C848904757FA86F081B299F8000034 +:10347C00A1839DF852107028A176BDF85010E183FD +:10348C009DF84E10E176BDF84C10218411D07828AF +:10349C00D14614D07C282F4616D07E281AD0FE2870 +:1034AC001FD0FF2823D10898CDF80C80013008904C +:1034BC0020E00A98D1462F4601300A901AE006986F +:1034CC002F460130069015E00798CDF8108001309A +:1034DC0007900FE00998013009901FFA88F00290CC +:1034EC0008E00B98CDF8148001300B9002E00C989A +:1034FC0001300C90397808F101081BE7012088F89D +:10350C00000017B0BDE8F08F0C98984E00060BD158 +:10351C000B98C0B2012807D80A98C0B2012803D86A +:10352C000998C0B2012811D99348042200240270D2 +:10353C00CAB2E0B2904210D214F0A4F9317801343E +:10354C00084339783070F3E7884E1BE0089BD8B2FB +:10355C00A04219D1884800220270002089F803008B +:10356C0089F80100481E7E2189F80200B9F81C0078 +:10357C00A9F80600002021F0DFF999F80200FE21DD +:10358C0021F0DAF93078BCE70A98000624D00B98C1 +:10359C00059A000603D1039A180600F08480764839 +:1035AC0002210127D5B289F80220017017FA82F0A6 +:1035BC00B0FBF4F101FB140089F80100284614F06B +:1035CC0061F930702846FE2121F0B6F989F80570B2 +:1035DC000020FEF7F5FDD5E70B98059A000621D0E3 +:1035EC006548012189F80220017011FA82F0049AD1 +:1035FC00B0FBF4F101FB140091B2FF2989F8010032 +:10360C001FD10299FF2919BF89F8031001EB410062 +:10361C0089F8030000EB400009EB8000808BA9F8CF +:10362C000600AFE7DDE90620104300063FF47CAF4F +:10363C0022F002FDA04280F085804F4803210170EA +:10364C003EE0480089F8032010FA82F009EB800074 +:10365C00818B1829A9F8061094D30739D0B20EAA79 +:10366C0089B216F085FF9DF843004007B0D5B9F834 +:10367C000610BDF84620002399F80300009303239D +:10368C00891A0EAA073989B206F0B0FF00287FF418 +:10369C0079AFBDF8441000293FF474AF9DF8480091 +:1036AC001DF0D6F86EE722F0C7FC0621A042324886 +:1036BC0038BF03210329017002D0062952D061E7DB +:1036CC0022F0BAFC054689F80C0000EB400009EB2F +:1036DC008000408BA9F80D000CF06EFE3978284460 +:1036EC00B0FBF1F202FB110089F802000130C2B20A +:1036FC00B2FBF1F202FB110089F801007C2021F0F1 +:10370C0035F9FF2812D17E2021F030F9FF280DD198 +:10371C00FF2021F02BF9FF2808D1782021F026F981 +:10372C00014699F80100FF2918BF0846C1B289F873 +:10373C000300490051FA80F009EB8000808BA9F856 +:10374C0006001AE70898000609D099F80200FE2135 +:10375C003C46374621F0F0F82478039A40E70648B7 +:10376C0006210170FEE700BF98270020A02300204F +:10377C00B87200209B7A0020A77A0020F7950200EF +:10378C00D8010010004003402DE9F84305460C46D3 +:10379C00480413D4A00024D4A0075CD460057ED4C4 +:1037AC00200500F10681200700F13B81600040F10B +:1037BC00F6801AF009F824F08044F0E026F016F8B0 +:1037CC00DFF81C140F6D3FB1D7E90A1202F0E0428A +:1037DC0001F00A01891849D026F0C3FA24F4804478 +:1037EC00DDE0BB48DFF8FC73016841F0800101604B +:1037FC00B878012804D1042021F020F90020B870F9 +:10380C0025F0F4FF0646042026F098F8DFF8D813CC +:10381C000A68904219D12A7EBAB1FA68AAB1DFF8C7 +:10382C00C003806C002800F09780C16840F603024A +:10383C000988914206D0C06840F60401008888428D +:10384C0040F08A8005F1140088E040F6C41208604C +:10385C00C5E9042284E009F0ABFBDFF88403006CBB +:10386C00002840F09D8024F0020498E0D7E90A6516 +:10387C00D7E90A12AA43B143C7E90A1226F071FA32 +:10388C00B8680028AAD056EA0500A7D0D7F808C017 +:10389C003869B7F9301032462B46E0479EE725F0E1 +:1038AC00A5FF054623F0E6FD002800F0B780CC48C4 +:1038BC00876B002F00F0B280DFF828830420CB49FF +:1038CC00002288F81800C64825F0FCF926F076FA94 +:1038DC00C74826F040FAC7480068006B8047C8F814 +:1038EC0010000125042088F8025021F0DFFE386911 +:1038FC0090F82810C8F80400490703D5436A04213E +:10390C000022984701201BF055FCD8F8040045769E +:10391C0013F096F8D8F8040081680B461A465B68D9 +:10392C004BB11E88A6F60306072EF7D805FA06F645 +:10393C0016F0830FF2D0537B03F0F0030133537373 +:10394C000023FD6853602D88A5F60305012D00F2B8 +:10395C008A80C8F810309FE005F110001EF0FEFAC6 +:10396C00304626F0FEF921F0B9FE78B12E6A2846D1 +:10397C006FF4807100224FF00073B0479848806B51 +:10398C0010B119F021FF01E044F00204EE69284661 +:10399C00002100224FF08063B04724F0005434B172 +:1039AC00974821462830BDE8F84326F0BDBABDE85B +:1039BC00F8838C4EB078012804D1042021F03EF815 +:1039CC000020B07021F08AFE38B170686FF48071FD +:1039DC0000224FF00073056AA847306950B1854842 +:1039EC000068006B804732697168801A000BC860F0 +:1039FC00002030617A4D81490022284625F062F979 +:103A0C0002203076286C20B17D480221283026F027 +:103A1C008BFA19F0D9FE24F40064C0E726F0CEF935 +:103A2C0041E025F0E3FE054623F024FDA0B1DFF8CC +:103A3C00B48198F8000000070ED498F90000002813 +:103A4C000AD4684613F038FA08B1009820B1DFF8B0 +:103A5C00B49199F8610048B326F0B0F919F0B4FEAE +:103A6C0024F008049BE7034633F8385FA5B190F8BF +:103A7C00445090F8456005F0F00580F8445006F08D +:103A8C00F005013580F8455000255360C563458726 +:103A9C00507B00F0F000507357480022C261016067 +:103AAC00012024F027F924F4806478E7002601270C +:103ABC00602E0FD009EB0600817A31B18772407A03 +:103ACC0007FA00F0C0B220F0D3FF2036F0E700BFB9 +:103ADC00CC210840032088F81800454826F03BF913 +:103AEC0026F06CF9444F3E4D002278690020786135 +:103AFC00F968F8602846444925F0E4F83D48006828 +:103B0C00006B8047D8F80C10D8F82020411A02EB33 +:103B1C001130B0EB113F38BF4FF0FF3098F8241044 +:103B2C00C8F8200021B1D8F80810B0EBC12F20D96B +:103B3C0024F0F0F8B8B140F60900414621F83C0FEA +:103B4C00002048804A7B02F0F00201324A730A7B63 +:103B5C0002F0F0020A734860F8613960B8F83E0070 +:103B6C0010F4406FFAD00020C8F82000012088F82B +:103B7C0024001DF0BBFB2548002101600220002120 +:103B8C0024F0B8F8022020F059FF102012F008FBA6 +:103B9C0098F8010020B9D8F80400503026F0C0F98C +:103BAC001B48807810B90D2012F0FAFA98F825000D +:103BBC0028B1002088F82500052020F03FFF0020C8 +:103BCC0088F818001348C8F81C000220B5F85610E5 +:103BDC00B5F85420914208BF072018F077FF3DE755 +:103BEC0030210020D01E0020E02600205D74020051 +:103BFC00387100208C01001000100440F50C0100FD +:103C0C0070200020206E002039D8010000000460D4 +:103C1C009CB90200D50501002DE9F04F8DB08478D8 +:103C2C000226142C00F21F820546DFE814F029004E +:103C3C00150015004A0085001C021C021C021C0207 +:103C4C001C021C021C021C021C021C021C028E0008 +:103C5C009C00AF00BE00CC0001206A78022C8DF8CD +:103C6C003100089240F0C080E878291D03288DF8B7 +:103C7C002C0040F0E18009A8082225F0E1FBE0E0EF +:103C8C0010208DF82400102026F038F998B1044645 +:103C9C00DFF8E00321466060E81C10F017FC8DF89B +:103CAC00240028B9204623F087FC8DF8240010B19D +:103CBC00204626F021F9002609AB642000210122C0 +:103CCC00C2E10020CDF82A00ADF82E00CDF8260078 +:103CDC0002208DF82C00E81C26F00CF9ADF824001D +:103CEC006979A8798DF82D1025F03AFC8346E81DEA +:103CFC0026F000F995F80C908046687AAC7A95F825 +:103D0C000BA04FEA49078DF83100384626F0F6F83B +:103D1C00002800F01081CDE9074806464FF0000856 +:103D2C0005EB0800474570D00D3026F0E3F826F877 +:103D3C00080008F10208F3E7E87820F083FF8DF81B +:103D4C00240009AB6420042189E1E978032900F2FD +:103D5C005281281DDFE811F00400510155015D016D +:103D6C0018F056FF76E1E81C26F0C4F8C04C6668E3 +:103D7C00002E00F0E4806A79002A00F0E4803368B9 +:103D8C00A91D184425F05CFB0020D9E0B84EEC1CB2 +:103D9C0004212046376822F0EBFC002F4AD0B9688A +:103DAC00814200F0A0803F68F7E7A888ADF82400B6 +:103DBC00E87809A924F07CFB8DF832000DF1320370 +:103DCC00642013214BE10026E878ADF8246009A9A2 +:103DDC0023F08AFDBDF824000DF1320314210222D8 +:103DEC00ADF8320064202FE1E81C02218DF82C1074 +:103DFC0026F080F8ADF82400002005F10608ADF897 +:103E0C002E0068798DF82D0026E0BBF1000F00F034 +:103E1C00B580437B0DF131010E30CDE90496CDE92F +:103E2C00000107985946CDE9020A09A8089A1DF025 +:103E3C00DBFEA4E0012000E1084626F05BF8ADF8BB +:103E4C002400287B8DF82D0005F10D0026F052F88A +:103E5C00ADF82E0005F10F0898F8000025F080FB56 +:103E6C00054608F1010026F045F898F8036098F82B +:103E7C0004A098F805B08146022C8DF8326009D167 +:103E8C0008F1060026F036F8074608F1080007F19D +:103E9C000A0104E098F8067008F1070039464DB1A4 +:103EAC000A3189B2FB2907D3DFF8C481D8F80400A2 +:103EBC0000286ED0022009E00DF132018DE8030CD0 +:103ECC0009A84A463B46294603F012FD089E8DF888 +:103EDC00310006F0E000202840F0C4800DF13103E1 +:103EEC0064202146BBE0EC1D204626F003F86D7AD9 +:103EFC00002D00F0978005F102098246484625F016 +:103F0C00FDFF002800F098800026457080462A4668 +:103F1C000670786800EB0A0108F1020025F090FAAF +:103F2C005FFA89F26420122143461EF027FC4046BA +:103F3C0025F0E2FF97E010208DF8320024E01020ED +:103F4C008DF8240016E0D6F800C0F38AB28A3169E5 +:103F5C00757EB77E06F11800CDE900C0301DCDE9A5 +:103F6C00025703F0C5FC8DF82400606825F0C4FFEF +:103F7C000020606009AB6420112170E002208DF8F4 +:103F8C003200304625F0B8FF0DF1320364200321D6 +:103F9C0065E007F11C0025F0B1FF0028C8F804000B +:103FAC0055D000F11C010C22016000208DF831006D +:103FBC00D8F8040009A9043025F042FAD8F8040016 +:103FCC000F214FF47A7205612A4DC17680F81AB030 +:103FDC0080F819A00676C782A0F8149008212878DA +:103FEC0025F0F2FE089E00283FF473AF28780821D4 +:103FFC001AF086F86DE702202CE000781AF0B0F881 +:10400C0028E0007825F0ACFA18B324F0ABFF0020C0 +:10401C0020E025F06FFFA97925F0C0FCB0FA80F004 +:10402C00400917E03068B84201D138683060384632 +:10403C0025F062FF002000E0102000262070642094 +:10404C0012210222234666701EF098FB0BE0102012 +:10405C003CE701208DF8240009AB642010210122DB +:10406C001EF08CFB002630460DB0BDE8F08F00BF73 +:10407C00682600209A7A00202DE9F04F8FB00C466C +:10408C0008040CD4A00426D4DFF88853287802281E +:10409C002DD1E10740F00381A10641D558E0DFF8AE +:1040AC006C0300781AF0FEFC90B10178DFF8602305 +:1040BC0005460020602808D0135C08308B42F9D1EB +:1040CC00104450F8041C28468847284624F00EF863 +:1040DC0084F4004595E11DF08DFC28B10546FCF7F4 +:1040EC00C1FD284624F002F884F4005589E1A106AC +:1040FC002ED4012814D8E10600F11781610600F1D5 +:10410C002F81210600F13D81E10500F13F81210560 +:10411C0000F14181E10400F15481610400F15B8103 +:10412C00A10700F1E280A10500F1FA80210700F15E +:10413C001181610500F11981E0034FF0000540F198 +:10414C0060811BF037FFB648C57084F4803558E1A8 +:10415C00AE4F202138781FF02FF9DFF8C4824FF0D2 +:10416C000109D8F80810084317D025F099FE054628 +:10417C0025F094FE68434FF47A71B0FBF1F0D8F857 +:10418C000810401A4FEA500938BF6FF0004900255B +:10419C00002964D0B9F1000F61D000200421002265 +:1041AC0022F08CFE06464FF0060A4FF0FF0B4FF63E +:1041BC00FF7802AD002E4ED0304604210022374647 +:1041CC0022F07CFE06463889B0EB090038BF00208F +:1041DC0038810004EED1B87BD0B301280AD178899C +:1041EC00400707D4386887F80DA0B721407B1DF035 +:1041FC00B9FBDFE739682A468DF806B0ADF80480C4 +:10420C00086AC97F0CF0E4FF01281BD1B87BB97A8E +:10421C008DF838000907788A40F08002ADF8362016 +:10422C0006D540F4C070ADF83600387B8DF83A00F6 +:10423C00786910B1007BADF81800284601A900225E +:10424C0002F018FC387B87F80DA016F091F8B1E756 +:10425C0001207873AEE7DFF8C8816C4F4D4622F031 +:10426C007AFF00200121002222F028FE18B13878B4 +:10427C00202119F045FF002004210022002622F005 +:10428C001DFE002847D006890421002222F016FECC +:10429C00A0B1B1B20689B14238BF0E46F4E764480A +:1042AC0090F82C100F2906D190F82600022802D382 +:1042BC00002021F0CBF984F00105A2E0A8B2B1B244 +:1042CC00814223D9D6FA55F0202180B242003878A9 +:1042DC0025F07AFD25F0E4FD054625F0DFFD684369 +:1042EC004FF47A71B0FBF1F615E05248007808B340 +:1042FC0002AD284625F0D3FC25F09CFA4E490B78EC +:10430C004E490A7829461AF0D1FE20E0387820214F +:10431C0019F0F6FE0026C8F8086084F0200570E05D +:10432C0015F062FC84F400756BE008F04FFA84F031 +:10433C00100566E03E48418B012025F0D5FD28781C +:10434C00022804D13148012100781BF045FB84F090 +:10435C00020556E03248012184F00805817050E0D6 +:10436C000CF0B6F984F040054BE0022808BF15F0BC +:10437C00FFFE2F480121808C25F0A8FD84F4806578 +:10438C003FE024F0B5FA84F080053AE022F0B6FB69 +:10439C0084F4807535E01BF073FB2048007801280D +:1043AC000CD11D48007848B14FF47A7100FB01F232 +:1043BC0016484FF40061007825F003FD84F4006585 +:1043CC001FE01748017819B1002101701BF058FB50 +:1043DC0084F4805515E01448006880B111490978BF +:1043EC0001290CD180471148006800B1804707486B +:1043FC004FF480414FF47A72007825F0E2FC84F49B +:10440C00804528460FB0BDE8F08F00BF9C7A002095 +:10441C00BCB2020024260020CC270020CD2700208F +:10442C00E8250020CA2700208423002090230020A8 +:10443C00A86D0020A7270020D0270020D22700201D +:10444C002DE9FE4F8846080426D45FEAC87004BFE5 +:10445C000020BDE8FE8FE548056825F021FD0446E7 +:10446C0025F01CFD60434FF47A714FF6FF72B0FBE0 +:10447C00F1F14FF6FF70002D00F01A812B886C883B +:10448C00CB1A9BB29C4240F21C81E31A94B2A34219 +:10449C00B8BF1A46ED68EEE7DFF840A3CDF804800C +:1044AC009AF800001AF0FEFA002800F0FC8006468C +:1044BC000078012840F0EC80DAF8041096F833907C +:1044CC00D6F814B096F8138021B1484688470028D6 +:1044DC0040F0DE80718896F83100022222F05AFA00 +:1044EC000546002842D0287A297CA0F10108FF2932 +:1044FC0000F0BB80707F4F46C00718BF0027E97CD7 +:10450C00287D0144B94204D8E974FF2101FA00F076 +:10451C006874A969A87C96F83020896A10FB07108A +:10452C00F16A24F08DFF287D697CB7FBF0F202FB69 +:10453C00107001228240D2B20A436A74C8457CD101 +:10454C0096F83010AB7C13FB0713A9698B844FF4DE +:10455C00FF7303FA00F0C0B21043FF2868746CD1EB +:10456C00287C1AF0FBFDFF2028747FE0707FC007C9 +:10457C0000F08E80B07F24F0F3FF002800F08880DC +:10458C0004461C2025F0BAFC002800F081801C2178 +:10459C00054625F0BDFBB07F02A923F0A5F99DF8D7 +:1045AC00090002212875284623F0F4F9708896F842 +:1045BC00312096F8301096F83330A880287DEA71B7 +:1045CC00FF2202FA00F0687460680078A9742874FD +:1045DC00302013FB010080B222F0AAFE0028A86153 +:1045EC005DD004461A20B11C2060708CA080A01DE8 +:1045FC0023F06CFFF27F04F13000B17F96F8283085 +:10460C00C4F81CB084F81980A062307CE273744A40 +:10461C00217563750121A075928C2282F28EA28580 +:10462C00F28C6282B6F81100A4F817009AF8000018 +:10463C0085F8089019F064FD55E725F031FC044627 +:10464C0025F02CFC60434FF47A71B0FBF1F0654916 +:10465C0028806348097800794843642148436249BB +:10466C00097800FB0100688000E04F46E87C297D5A +:10467C006A7C01440139B94218BFFF2A0CD186F873 +:10468C003300708806F11C0186F8342016F085FF83 +:10469C00304623F02BFD03E7C845F9D1EFE7284658 +:1046AC0023F088F9F4E7019880F40040BDE8FE8F10 +:1046BC0092B282424BD049480121007825F084FB0C +:1046CC0045E0A879022806D1287CFF2837D0A869B4 +:1046DC0023F00CFD33E025F0E3FB044625F0DEFB74 +:1046EC0060434FF47A71B0FBF1F03F49288095F8A4 +:1046FC003800097888421BD295F83620FF2A06D15B +:10470C0095F83720013085F8380085F8362095F873 +:10471C00351095F8394082F0FF0300200126C7B20E +:10472C00A7421DD206FA07F71F4214D10130F6E753 +:10473C00EA8BA87E95F82A10E9231EF087FF2846FD +:10474C0023F038F925480121007819F0D9FC88F0BC +:10475C000100BDE8FE8FFBB201441A4385F83620F8 +:10476C00AB8F95F83440C8B204FB10339EB2A6420E +:10477C0003D2FF2285F8362002E0FF2A08D1234617 +:10478C00184A174E1278367972436426724302E047 +:10479C0095F83A2023466A802A8D0E0606D022F020 +:1047AC00200244432A852A6C224404E042F0200172 +:1047BC002A6C2985297A85F82E10E9796A6285F8A0 +:1047CC002D10D9B269840549496811B18847002870 +:1047DC00B8D105F1100004F011FBB3E74826002016 +:1047EC00A86D0020C0270020C62700206C53002095 +:1047FC007FB50138072800F24C810C46DFE810F039 +:10480C0008002C0054006E0089004901A600C90064 +:10481C00CB4800780138012800F23B81002C00F0D5 +:10482C0047810020032100241FF02CF9C64DC74EF0 +:10483C000420042132222870307825F0C5FA082093 +:10484C00002107F011F830786C704FF4805104B0EF +:10485C00BDE870401BF0C0B80020002524F088FE95 +:10486C00BB480121017004208DF80D0074B1B548CE +:10487C00B34C45852078012803D1072023F08AFA10 +:10488C002078022802D1062023F084FAAE480421B5 +:10489C0032220570AD48007825F096FAA94890F8B8 +:1048AC002B1001F0FE01F2E0A54800780138012838 +:1048BC0000F2EF80A54804213222007825F084FA1A +:1048CC00002C00F00F819F4C9F4801210170206942 +:1048DC00002800F0EC801FF0E5FCF8E70120002C2C +:1048EC008DF80D007BD0974800219B4A80F82A1048 +:1048FC00984824F0FFFF924C2078012803D1072020 +:10490C0023F048FA2078022870D1062023F042FACE +:10491C006CE002208DF80D008A48002C73D0002129 +:10492C008D4A80F82A108B4824F0E4FF00200321E4 +:10493C001FF0A8F8824C2078012803D1072023F01F +:10494C0029FA2078002877D1092073E07C4D0020CB +:10495C008DF80D00002C28787BD018B9092023F095 +:10496C0019FA2878022806D10820002106F07CFFCD +:10497C00042023F00FFA10F095FF73480021C82291 +:10498C00017070480D2180F82A10704825F0A3F9A9 +:10499C0078E005208DF80D0069480078022878D160 +:1049AC00002C00F0C38068480022C178C2700170EE +:1049BC0042F20800002106F057FF62480D2190F8E2 +:1049CC002B2080F82A10C17802F0DF02002980F831 +:1049DC002B200CBF04200D2023F0DCF959E05848A3 +:1049EC00007818B95748022180F82A10564800213F +:1049FC0032220170554825F06EF9524890F82B1070 +:104A0C0001F0FD0143E0082180F82A104C49097897 +:104A1C00012911D890F82E0070B900200DF10A016F +:104A2C008DF80A0052201DF0A9FB24F031FB1EF07A +:104A3C002DFC002023F0AEF94348002132220170F6 +:104A4C00424825F048F93F4890F82B1001F0FB0143 +:104A5C001DE03C4C022812D194F82E0078B194F849 +:104A6C002B00002140F0200084F82B0005208DF84D +:104A7C000D00082006F0F8FE0A2023F08BF9022026 +:104A8C0084F82A002F4890F82B1001F0EF0180F8E1 +:104A9C002B102C480022032390F82A008DF80C00D0 +:104AAC002A48007803A900910A211EF0A4FA7FBDC0 +:104ABC00244C0720254D4FF4805184F82A00012006 +:104ACC008DF80D0028781AF087FF0020002622F0C0 +:104ADC0069F92878022141F2883284F82B6025F09C +:104AEC0073F9D6E7174C022000218DF80B1084F8CF +:104AFC002A001548017094F82B000DF10B0100F001 +:104B0C00FD0084F82B0001208DF80D0052201DF0C3 +:104B1C0035FB24F0BDFA1EF0B9FB002023F03AF966 +:104B2C0020690028B5D01FF0BDFBF9E7054802212C +:104B3C0080F82A1090F82B1041F02001A7E700BF55 +:104B4C0024260020AC2200200C7A0020A37A00201E +:104B5C00BD270020A86D00209027002092B0DFF820 +:104B6C00EC92D9F8000010B1002180F845104830C3 +:104B7C0020F094FF24F03AFE8046072011F0AAF8AA +:104B8C0017F0DAFF10B1B24824F0D4FF1AF06AFB28 +:104B9C0001AD284624F0C4FC0427002029468DF8DA +:104BAC00047024F0C5FCAB4C206024F031F90AAD44 +:104BBC00284624F065FB002029468DF8287024F047 +:104BCC0067FBA54E306024F02DF906AD284624F085 +:104BDC0067FB002029468DF8187024F069FB3168BA +:104BEC009E4D286019B99E4824F0A4FF286810B97E +:104BFC009C4824F09FFF206810B99B4824F09AFF32 +:104C0C001CF0D8FDD9F800004FF0FF3438B1CDE9D5 +:104C1C00104410A9082223F05DFB01281BD1CDE91B +:104C2C001044082025F06AF9002846D005460026D5 +:104C3C00052E04D824F0E8FFA8530236F8E74FF607 +:104C4C00300029460822E880884824F0F9FB2846E1 +:104C5C0025F052F909E0D9F80010CDE910440029EB +:104C6C00DFD08248082224F0EBFB10AA0120082197 +:104C7C0024F01EFF092800D0D8B921F075FE80075A +:104C8C0012D4CDE91044CDE90E440EAB0120002125 +:104C9C00082224F06BFA60B90EA810A9082223F0A0 +:104CAC0019FB002800F0CB80704A0120082124F069 +:104CBC0005FF6E49E2201DF061FA12F0CBFB2820B3 +:104CCC0025F01CF96A4E0028306055D0694F6A4CAB +:104CDC0007F10C0524F0FBFF24F042FB3068056063 +:104CEC0007F1100524F0F3FF64498968D1F84C13DF +:104CFC0088473068456007F1140524F0E8FF1CF084 +:104D0C0083F93068856007F1180524F0E0FF19F08D +:104D1C00B5FD3068C56007F11C0524F0D8FF1FF005 +:104D2C0007FD3068056107F1200524F0D0FF1EF067 +:104D3C007FFB3068456107F1240524F0C8FF1DF0A6 +:104D4C0095F93068856107F1280524F0C0FF23F040 +:104D5C0053FE3068C56107F12C0524F0B8FF20F034 +:104D6C0025FE3068056207F1300524F0B0FF38707D +:104D7C0024F05CF93068456218F0B6FE40484149B1 +:104D8C004FF00009CDF8409001603F48032111908D +:104D9C0010A820F043FC24F0BBFC404624F0E1FFBB +:104DAC0017F0ECFA24F058FF01201DF0C7FE19F0A3 +:104DBC0031FF37480078022808D1344800780128A0 +:104DCC0004D14FF40040012106F04EFD294F4FF461 +:104DDC008041387824F0A6FD2E484FF0FF31006852 +:104DEC000DF022FCDFF8B08078684FF0FF310DF049 +:104DFC001BFC3068002550F82510096821B9691C86 +:104E0C00092D0D46F7D3EFE724F0F9FE316851F880 +:104E1C0025100C68C1F8009024F0DFFF58F825200D +:104E2C00002021469047044624F0E9FE316851F8F1 +:104E3C0025100A6822430A6024F0CFFFD4E70B4800 +:104E4C000EA9082224F0FCFA33E700BF68270020E3 +:104E5C00B4B60200F4790020F8790020FC79002027 +:104E6C0068B802007BB80200B2B80200B679002024 +:104E7C00707A002088210020E14902000C010020FA +:104E8C009C23002001CA0100008D1500E52700209D +:104E9C00242600204C7A0020A4B502002DE9F04F06 +:104EAC0089B08A4608040DD45FEACA7040F01F81AD +:104EBC005FEA8A7000F12D815FEA0A7000F135819A +:104ECC00002044E1A34F387819F0ECFDDFF88C9208 +:104EDC00A64DA14C06464FF0000B48F21508002ECB +:104EEC0000F00281307831283AD032284BD0D328C8 +:104EFC0040F0B480F089404574D0382840F0AE8042 +:104F0C00CDF820B0CDE906BB304606A920F0A6FCB2 +:104F1C009DF81C10052969D8307B002840F09E8034 +:104F2C009DF81D00002800F09980052800F296805D +:104F3C00069823F0E8FE002840F09080707C8849A9 +:104F4C00AC467870708808809DF81D0021460138A9 +:104F5C008DF81D0006A890E82C002CC165467DE05C +:104F6C00B87803287AD899F82E10284623F0CBFE6F +:104F7C00002873D1FF207C49607170880880B0884C +:104F8C00784908806AE06079FF2814D0002016F078 +:104F9C0051FA0246B9F8701078783346CDF800B063 +:104FAC0012F0A0FD6079002858D038780821322200 +:104FBC0024F00AFF52E099F81810706820FA01F2F8 +:104FCC00D2071ABF3144097A002100221B2A43D090 +:104FDC0020FA02F3DB0703D0B3181B7A99421ED8D0 +:104FEC000132F3E7304621F03DFE37E0FF293DD09A +:104FFC00FE2956D199F872109DF81E00884202D8ED +:10500C0060BBFF292AD11CF0BBFE069900201B288F +:10501C0059D021FA00F2D20757D10130F7E7B9F88D +:10502C006E004F49334608804E4802884E4801882E +:10503C0010200090002012F055FD0120F870B87877 +:10504C0040B93C2002214EF66022B880387824F01A +:10505C00BBFEB8780130B87084F805B0304623F048 +:10506C0045F8387819F01EFD064638E799F87210A5 +:10507C009DF81E00884203D80028EFD1FF29EDD1FE +:10508C001CF07EFE069838B1D9F82810814203D066 +:10509C00C9F8280022F08EFEBDF8200023F0DCFCBD +:1050AC00DCE7307B0028D9D170882D498022002381 +:1050BC000880707CCDE900BBCDE902BBCDE904BB17 +:1050CC0011F01CFBCAE71B2000E0C0B299F81810C5 +:1050DC008142C3D02649087099F80700642100FB6F +:1050EC0001F23878012163E78AF400402FE020496F +:1050FC001A4C08782076E1201DF040F822F05AFE78 +:10510C000020A4F87000012016F094F98AF0010038 +:10511C001DE010488188B1B101394EF660228180C2 +:10512C000078022124F050FE0FE00B4C607938B16E +:10513C002179206823F0E7FD10B96079013860719E +:10514C008AF0080003E0002181708AF0020009B0A7 +:10515C00BDE8F08FCC24002058790020A86D0020E9 +:10516C009279002076760020F272002000F8FF077A +:10517C009F7A00202DE9F04F85B08846080418D49A +:10518C00AA480078012802D85FEAC87156D15FEAB4 +:10519C0088714DD4022807D1A5480078012803D185 +:1051AC005FEA487000F18A805FEA087059D40020E9 +:1051BC002DE1DFF860A29AF8000019F073FC0028CA +:1051CC0000F023810546807FD0B9688C132817D155 +:1051DC00DFF844926E880021D9F81C000F1D0029BD +:1051EC0008BF09F11C0758B101884468B14204D1C9 +:1051FC003C6024F081FE2046F5E701462046EDE7B1 +:10520C00A87A05F1020B022840F0E580DFF808923D +:10521C0095F83170BBF8006009F11C000068A0B172 +:10522C000188B14202D18178B94243D00430F5E70C +:10523C0079480121017088F00200E8E07648406965 +:10524C0000B1804788F00100E1E0D9F81C0000288B +:10525C0058D0012204464068114601320028F9D189 +:10526C0052E07048DFF8B091807BD9F81C600007E1 +:10527C0060D424F015FE044624F010FE6A4A604304 +:10528C004FF47A71B0FBF1F0D9F818101288411A6A +:10529C0091427AD3B1FBF2FB0BFB02F2511A084498 +:1052AC005E49C9F818001FFA8BF00978884288BF4C +:1052BC008B4641E059490978C170A3E05E495D48CD +:1052CC0000224FF6FE7300240978023079B130F8D1 +:1052DC00025C9D4208D04588013D45802D0406BFE7 +:1052EC00027020F8023C012401390630EEE734B19B +:1052FC00484804214FF4FA72007824F065FD88F0D8 +:10530C00040084E000240021454889B200888142D1 +:10531C0061D2082024F0F2FD00285CD00021068028 +:10532C00877041603D490978C170D9F81C1079B378 +:10533C0060603FE04FF0010B00205FFA8BF44FF000 +:10534C00000A071D002808BF09F11C0796B1F07868 +:10535C00C0FA5BF1A042F17006D8756830463D602A +:10536C0024F0CAFD2E46F1E7716830460AF1010AB5 +:10537C000E46E6E75FEA0A4007D100200821C9F88B +:10538C001800244800781AF027FB88F008003EE04B +:10539C00C9F81C002348807B00070BD424F080FD47 +:1053AC00044624F07BFD60434FF47A71B0FBF1F0BE +:1053BC00C9F818001B48807B00070CD59AF8000030 +:1053CC0008211DF0F9FF30B91748082102889AF816 +:1053DC00000024F0F6FC2878022810D0012811D106 +:1053EC00297EAA89EB7C05F11C006C696E7E8DE828 +:1053FC005A0005F11003594605F08EFA02E02846D2 +:10540C0015F01CFC284622F071FE88F4004005B013 +:10541C00BDE8F08F997A00202C240020C5270020AD +:10542C008A270020A86D00208E270020242600202B +:10543C00E5270020B45F0020A12700202DE9FE4FB6 +:10544C00074608680024B0B1D7E9018A0E4624F05B +:10545C00CDF98146D8F8E800082888BF0124B06847 +:10546C00204202D17068204208D003203074484694 +:10547C0024F077FC00242046BDE8FE8FD8F8C0103D +:10548C0069B198F8F8100029EFD006213174D8F8DA +:10549C00C410C8F8C4604E6198F8FC100DE00021EF +:1054AC000522C8E93066C8E93411C8E9361198F804 +:1054BC00FC10002908BF01223274002201297261FC +:1054CC0009D102204FF4E02188F8FC0098F8FB0089 +:1054DC001FF0B4FF706889490138884205D8042050 +:1054EC0020F0E4F8062020F0E1F8022020F0DEF8AD +:1054FC0098F8F80040B9DAF83C003168814203D2E0 +:10550C0098F8FC0000286CD0D8E9361009B118B90D +:10551C0000E028B324F0E3FBDAF80000416941F025 +:10552C0001014161484624F01CFC98F8F80008B1D0 +:10553C000124A0E708F16C05D8F8EC10284624F0FB +:10554C0077FB0028F4D0D8F8C0000321017438464A +:10555C0012F0B2FF28460021002424F069FB8AE7F0 +:10556C009AF8040024F0A8FC654CDAF8101002221A +:10557C00206991FAA1F1B1FA81F14368D8F8CC0015 +:10558C004068006898472069DAF8141002224368D2 +:10559C00D8F8CC0091FAA1F1B1FA81F14068006819 +:1055AC0098479AF8040022F045FA9AF8040024F07F +:1055BC0085FC24F094FB0020C8F8E000D8F8C0006B +:1055CC000068B0F5806F01D924F089FB98F8FE00D3 +:1055DC000028A1D1DAF80000416841F002014160D5 +:1055EC009AE798F8F90020B1D8F8EC0001307FF474 +:1055FC008BAF484624F0B5FBB2683AB1D8F8E80056 +:10560C000221092838BF0121009103E008F1F402BE +:10561C0000200090746834B1D8F8E80002270928FB +:10562C0038BF012702E008F1F6040027DAF8000081 +:10563C00334D416841F002014160D6F800B0D946C3 +:10564C00BBF1000F40D0D8F8E800019209284FF0C8 +:10565C00010011D22A68B9F1000F1FD0C0071DD06C +:10566C002178DAF800009268904700281EBF3C446D +:10567C00A9F101090120EDE72A68B9F1000F16D054 +:10568C00C00714D02188DAF80000926890470028EF +:10569C001EBF3C44A9F101090120EDE7DAF8000036 +:1056AC00D26802A99047DDE90120107007E0DAF812 +:1056BC000000D26802A99047DDE901201080009813 +:1056CC00ABF1010B0244BBE7D8F8F000DAF800109C +:1056DC00CA680240102802D1002AF9D101E0002A40 +:1056EC00F6D0706822F040F8D8F8C0100020C8F846 +:1056FC00C400C8F8C00008741AE700BFFEFFFF0F13 +:10570C00C40100102DE9F04F87B0851C8346284654 +:10571C0024F01EFB01AC06461821204624F0F8FAB2 +:10572C009BF801A004F10B002946009524F091FB95 +:10573C006FF001009BF80A1002240122ADF818004A +:10574C0000208DF81A408DF80C0001F00800C1F310 +:10575C00C007890782EAD00507D40028B946A846B5 +:10576C0008BF01240027002507E004244FF000099E +:10577C004FF00008002808BF03248548007850EA41 +:10578C000A000BD0834890F82600082809D123F092 +:10579C009FFD00285AD0BAF1010F57D14FF0C30921 +:1057AC0001E04FF0C2090025BAF1000F10D07F487C +:1057BC00007890B9BAF1010F0FD1002E63D0002000 +:1057CC00214601228DF81A0001A814F0D1FA0AE042 +:1057DC0001A81BF0DFF986B91CE001A8214652464E +:1057EC0014F0C6FAB6B17179BAF1020F41F0400269 +:1057FC00727104BF41F0600171719BF80A10490687 +:10580C0003D5717941F080017171B17900240131B6 +:10581C00B17100E00124B0FA80F149090D423AD18E +:10582C0007D1002D18BF814641F20100494621F0F5 +:10583C00B0F814B9009819F089FBBDF818004FF6B0 +:10584C00FE71884218BF24F063FB24E0DEB332798A +:10585C00A24218BFBAF1020F20D1D01EC0B201284B +:10586C0002D857EA050006D1501EC0B2012822D832 +:10587C0059EA08011FD0308821F0F8FA20BB308893 +:10588C00ADF8180022E00220214601228DF81A0002 +:10589C0001A814F06DFA07B0BDE8F08F4FF00009C5 +:1058AC00009953468DF81A903088ADF8180024F002 +:1058BC000FFB012578E7012802D8308824F028FB5B +:1058CC00009819F043FB0026BDF818004FF6FE7146 +:1058DC0088421ED121F086F810B1BDF8180011E0F5 +:1058EC00BAF1000F04D02C4D288821F0BFFA30B14A +:1058FC009BF80A0000F002001FF008FF00E0288867 +:10590C00ADF818004FF6FE71884202D14FF0C7096E +:10591C0049E79BF80A200099534624F0D9FA10B1B4 +:10592C004FF001093FE71D48016811B1BDF818009F +:10593C008847BDF818000099224606F0C7F90646BC +:10594C00174818490A6800784FF4803124F03CFA63 +:10595C0001211548C17096B1AAF10100C0B201280D +:10596C0007D81020BAF1020F08BF0820717908433C +:10597C0070714FF0000901258DF81A9014E74FF65D +:10598C00FE7000254FF001090026ADF818000BE75A +:10599C0004250020A86D00208027002098230020DB +:1059AC009C7A0020ACBA0200E825002024260020B6 +:1059BC002DE9F04F8DB0044600209A4616460F464E +:1059CC00CDE90B00CDE909008A488568804615F0C1 +:1059DC0061FA1C2803D015F05DFA1B281BD1308806 +:1059EC0040F60201884218BFB0F5C15F03D1F07BCD +:1059FC00022810D93EE043F6070188420BD196F8F5 +:105A0C002400032807D330697B4940F0806020F0E4 +:105A1C00604088422ED100206FB366B3387825FAE7 +:105A2C0000F0C00726D03046002124F061FA7348FC +:105A3C00C4E90176006880B109A800900CA90BAAF2 +:105A4C000AAB304609F0D6FE0B980B214FF6FF72CD +:105A5C00502322F08FF8FF280CD023F0C7FE684F9C +:105A6C0006467878012802D840B1012070E0304613 +:105A7C0024F077F900200DB0BDE8F08F09F02EFE70 +:105A8C0060480DF10409016841F0020101605E48B3 +:105A9C00C8F80000484623F033FDDFF870B15D49CB +:105AAC004A469BF801009BF8005003905848283058 +:105ABC001EF0D3FD584859494A461EF0CEFD4846C3 +:105ACC0023F02EFCDFF85881564A19214B460295DB +:105ADC0040461DF045FB544A08F11C001A214B4668 +:105AEC001DF03EFB5148524924F009F951485249E6 +:105AFC0024F005F95148006810F4402F06D0504AA4 +:105B0C0007F128000421002321F07EFC9BF8020001 +:105B1C0010B10D2010F0DEF808F1400023F0DDF894 +:105B2C0008F1380023F0D9F84649002007223876CE +:105B3C00B8843862386181F860200521C7E9021009 +:105B4C004149F96138700420002122F0D3F87878AB +:105B5C002F4941F8204001307870304624F001F98B +:105B6C00BAF1000F02D0DAF8000008E00DF1040AD7 +:105B7C0036492022504624F0E7F94FF0FF30DAF88E +:105B8C000420BAF81010DAE90635002AB2FA82F6C7 +:105B9C0008BF40F6C412206001207609618325639A +:105BAC0060762B4826764FF4FA766261C4E903627C +:105BBC00C4E90700C4E90903DAF80C0000B120625B +:105BCC00DAF8140000B16062DAF8080000B1E061A4 +:105BDC0004F13800C82124F09BF804F15000002196 +:105BEC0022F0C8F81B4904F1B80024F088F82046CC +:105BFC0041E700BFCC2108400F00000580260020A3 +:105C0C00D01E002000200940110000E09CB90200C9 +:105C1C00702000206D83020040720020714C010046 +:105C2C003021002039D8010049B901007C710020D5 +:105C3C00397402003871002019830200B44F0050EF +:105C4C00B1000200206E0020D505010094B60200C0 +:105C5C00236E0100059E02002DE9F04F87B0002451 +:105C6C000293002A00F03A81074603A892460E469A +:105C7C004FF0200B10300190504610F8011B2529D5 +:105C8C000CD0002900F02781022EC0F0D680013EF6 +:105C9C00002F00F0D18007F8011BCEE09AF801002C +:105CAC002D2806D19AF802000AF103034FF0010CDB +:105CBC0003E00AF102034FF0000C30280CBF13F87C +:105CCC00011B01462A2920D1029D2A68111D296039 +:105CDC00D2F8009013F8011BB9F1FF3FDCBFC9F1FA +:105CEC0000094FF0010C2E291ED11A4612F8011B87 +:105CFC002A291CD1029D2A68111D29609D1C12683D +:105D0C0059782B4622EAE27821E04FF00009A1F104 +:105D1C003002092AE7D809EB890201EB4201A1F113 +:105D2C00300913F8011BF2E74FF0FF380FE04FF08A +:105D3C000008A1F13003092B08D808EB880301EB0C +:105D4C004301A1F1300812F8011BF2E71346302889 +:105D5C004FF0000241F0200008BF4A466C2808BFF3 +:105D6C0013F8011B9A46692901D0642909D1029BB9 +:105D7C001868011D196090456FF00903C8BF4246B1 +:105D8C001BE075290AD0A1F16F00092858D8DFE86B +:105D9C0000F005695F5F835F5F5F5F05029D2868A8 +:105DAC00031D2B6090454FF00803C8BF424678296D +:105DBC0008BF1023752908BF0A23DDF80480016889 +:105DCC004046654616F062FCAC460546A8EB000161 +:105DDC00A9EB0100BCF1000F0DD109E0022E05D397 +:105DEC00013E17B107F801BB00E000270138013470 +:105DFC000128F3DA01380A465AB1022E06D3013EC5 +:105E0C001FB12B7807F8013B00E00027013A013560 +:105E1C00F2E70C44BCF1000F3FF42EAF0128FFF663 +:105E2C002BAF022E05D3013E17B107F801BB00E0E2 +:105E3C00002701380134F1E70027013482461BE7C3 +:105E4C00632905D1029A1068011D1160006804E0F5 +:105E5C00AAF10100022E3AD300788DF80C00012132 +:105E6C0003ADB5E7029ADDF804801023CDF800C02D +:105E7C001068011D11601099082200290168404624 +:105E8C0016F004FC05464FF04000DDF800C005F8A4 +:105E9C00010DA8EB05019BE7029ACDF800C0106834 +:105EAC00011D1160109905680E480029002D08BFCE +:105EBC000546284623F048FC8045014638BF41463C +:105ECC0018F1010208BF0146DDF800C080E700218F +:105EDC0003AD82467CE70FB100203870204607B036 +:105EEC00BDE8F08F7CBA02002DE9F04F8DB006466C +:105EFC00806A447874B18D4909788C4280F01281A3 +:105F0C008B49023022462AB130F8023B013A21F883 +:105F1C00023BF8E78748C18A708988422FD18348B1 +:105F2C000078A04240F2FE80B589814A214628467D +:105F3C0022F078FA284617F017F8064682480778B8 +:105F4C00BE4204D14FF6FE7017F00EF80646BE4264 +:105F5C0080F0E880DFF8F48108EBC6094F4657F86B +:105F6C00040F08B123F0C8FF002C00F0B1806000D2 +:105F7C0023F0C4FF0028386040F0AC80D2E0B27C43 +:105F8C00002A00F0CF806A4F0025AC4205D037F8CC +:105F9C0015208A4203D00135F7E7A04600E0A84659 +:105FAC00002113F0E5FF002800F0AD808146407918 +:105FBC00012840F0A88099F8060010F0180F00F0A6 +:105FCC00A280B9F80210204622F01AFBA54202D397 +:105FDC00002800F098805848CDE90498B6F80C9049 +:105FEC004FF6FE7A00780890544800780A9000200A +:105FFC0006960B9052481130099052480430079085 +:10600C0000200C90DDE909564FF0000BF6B135F885 +:10601C00117C574518BF4F4502D1013E1C35F5E7A1 +:10602C002046394622F0ECFA0028F6D128780138BF +:10603C000528F2D80C980BF1010BC007EDD00B988A +:10604C005FFA8BF1C0B28142E7D356E0DDE90786F7 +:10605C002EB338F8047C574518BF4F4503D1013E89 +:10606C0008F12408F4E72046394622F0C9FA002842 +:10607C00F5D198F8050001380528F0D898F80000FB +:10608C0001380228EBD30C980BF1010BC007E6D0BA +:10609C000B985FFA8BF1C0B28142E0D32DE05FEA3E +:1060AC000B6028D00B98000625D101205FFA8BF5E8 +:1060BC000B90012D4FF001000C90A3D023F0A4FD08 +:1060CC00C0B2B0FBF5F101FB15000B90012098E775 +:1060DC00002038601E4989F80140A9F8025009785F +:1060EC0008F83610F4B1E8B1114962000DB0BDE802 +:1060FC00F04F23F0A5B94FF6FE770498069EDDF815 +:10610C00148047800A4FB37CF47CB269B1890125B5 +:10611C00581EB07470895FFA88F68DE8D00003952C +:10612C0010F032FD0DB0BDE8F08F00BFD8BA020000 +:10613C0008780020A86D0020E3BA0200D1BA020052 +:10614C003056002020450020D7BA0200503D0020D8 +:10615C00DE2700202DE9F04F87B005462C200E4697 +:10616C0023F0CCFE002844D0778B044623F074FB3C +:10617C000021E1840121874208BF02212170707B3C +:10618C00A0703169081A6060204618F0B9FC3178AB +:10619C00834F01F00301387B012908BF0520607093 +:1061AC00C0B223F09DF94FF0FF316077A182217FBF +:1061BC00326908440A44317D3261081A3075E07046 +:1061CC00A069013017D0207C032816D8DFE800F036 +:1061DC0002170209062021466082284617F064F94E +:1061EC0010B3042021466082284607F027FD05469F +:1061FC001BE01025CFE0A32517E0A12515E000201A +:10620C00B3256082F87A80B997F8410001280CD147 +:10621C00A07D4FF6FF7619F06DFF0025A082B042ED +:10622C0008BF6FF05E0500E000252078022807D13A +:10623C0004F1080622F05AFE0146304623F009FE0E +:10624C00280640F0A580574F3878013801281AD815 +:10625C0094F8260010B994F82700A0B1A078E17842 +:10626C00227F08441044043023F048FE58B1A17832 +:10627C00E2780646207F114408446168021D3046CE +:10628C0023F0DEF800E0002620460EF00BFB05465E +:10629C003878012802D12DB9002575E0022873D178 +:1062AC00002D71D0002E73D00DF1080800274FF08F +:1062BC00010B4FF4D00908F1080A94F8260018B91C +:1062CC0094F8270000285FD0A178E278207F114451 +:1062DC0008443146021D606823F0B2F894F8260099 +:1062EC0020B184F82670C4F8129007E094F82700C7 +:1062FC0020B12D4884F82770C4F8120020460EF007 +:10630C00D1FA10B10021054639E04046142123F0A2 +:10631C00FFFC608A8DF819B0F0B9A08A40F2031125 +:10632C00884216D0682817D16068C17B052929D10D +:10633C002A30FF21082222F0F1FC18B34FF0FF3075 +:10634C006946CDE900001948006823F082FDFC2065 +:10635C0000E0FF208DF81800504669460022002509 +:10636C0013F0F0F901469DF8000038B10420142216 +:10637C00434620F063F90321002500E003210329A3 +:10638C009BD101E00221FAE716B1304623F0B4FDAF +:10639C00204623F0B1FDE8B207B0BDE8F08F00BF96 +:1063AC00A86D00202426002000000301EC580020DA +:1063BC002DE9FC470446019007788A48C65D8A4857 +:1063CC00F840ADF80260C00740F00A810D2F13D1E0 +:1063DC00864D0DF10201A868D0F82824532090476F +:1063EC00BDF802104FF6FD70814214D8208990B18F +:1063FC004FF0000A25469CE00C2F0ED0072F13D02F +:10640C00052F0ED1A078012800F0EA80207C3044C2 +:10641C0000F1240916E0A868BBE06068C08AC005DA +:10642C000AD44FF0000A09E0A07848B1A07D00EB37 +:10643C00C00006EB800905E04FF0010AB14605E00B +:10644C0006F11B09ADF802904FF0000A484620F007 +:10645C006FFF00B30546072F3CD120782870607879 +:10646C006870A078A8700028E178E970D4F805105D +:10647C0069604FD0A07D0028287241D0A169002905 +:10648C003ED000EBC00005F110068200304622F031 +:10649C00D7FFEE6037E00C2F40F0A280254655F870 +:1064AC00040F002800F09C8023F0A0F980464F4890 +:1064BC008068D0F8541328468847484620F038FFA7 +:1064CC000546404623F04DFC002D00F0898023F05A +:1064DC0055FB2EE023F052FB052F2AD105F11806AF +:1064EC0069682422304622F0ABFF69692A7C05F1E9 +:1064FC003C006E6022F0A4FF68682430686118E0EC +:10650C0000202872E860A06998B123F0F5FC002007 +:10651C00A0750DE01B2005F110061B2228723046D9 +:10652C00A16922F08DFFEE60A06923F0E5FC00204C +:10653C00A0612F48016819B128468847002844D12A +:10654C000D2F2BD1606801788A0720D4294AC1F31A +:10655C008301927C91421AD140783F2817D894F845 +:10656C003000022813D195F8470005F146011DF0C3 +:10657C0045FE01984FF6FF72418E91421DD1406845 +:10658C008079022819D3284619F01EFC40B317480D +:10659C008068D0F8541301A8884721E00C2F0CD147 +:1065AC0060781A2809D0686838B1C08AC00704D04E +:1065BC00287C05F10F011DF021FEBAF1000F04D16A +:1065CC000D482946007818F0C9FD0C2F08D1019808 +:1065DC0050F8041F21B105498968D1F85413DBE741 +:1065EC00BDE8FC878EB8020019C206000C01002021 +:1065FC0064270020A86D00209C7A002014F074F809 +:10660C008848DFF824B2DFF824A2DFF82482894D11 +:10661C00894E0027006818F013F8DBF800004FF0E3 +:10662C00FF310CF001F823F0EAFA9AF802109AF80C +:10663C000420D8F800409AF806308AF802708AF8DC +:10664C0004708AF80670002918BF44F00404002A6C +:10665C0018BF44F08004002B18BF44F00204C8F8A3 +:10666C00004023F0BAFBD8F80000010644BF20F02C +:10667C008000C8F80000287818F014FA002848D0D8 +:10668C00DAF80C10044651B19AF80100012804D034 +:10669C00022804D1204688473BE020468847204604 +:1066AC0016F09CFEA8B304460C20B1462F4623F0EE +:1066BC0025FC80B1064623F0A2FA05462078B4608A +:1066CC0098B1304623F018FC606821F00FFD20468D +:1066DC0023F012FC16E0606821F008FD204623F040 +:1066EC000BFC3D464E46002713E0D9F8000031461E +:1066FC0023F00EFAD8F8000040F01000C8F80000A3 +:10670C0023F0E1FA28463C464E46002723F065FB71 +:10671C002546D8F80000C10631D5306823F0F2F9CF +:10672C00F0B923F0B1F8D8B9A94623F068FA0446B9 +:10673C00306823F0E1F978B10546806841884068FB +:10674C0017F04EFCA868406821F0D0FCA86823F034 +:10675C00D3FB284623F0D0FB204623F03EFB4D46CE +:10676C00306823F0CFF930B1D8F8000020F01000D9 +:10677C00C8F8000003E023F0A6FAD8F8000081075F +:10678C000FD508F001FE21F005FA20B123F09BFA99 +:10679C00D8F8000005E0D8F8000020F00200C8F896 +:1067AC000000010725D5706823F0A6F990B1DAF83E +:1067BC000810044641B19AF8000028B1022826D0EE +:1067CC00012804D1A0688847A0681AF0B3FD2046C0 +:1067DC0023F092FB706823F095F930B1D8F80000E3 +:1067EC0020F00800C8F8000003E023F06CFAD8F899 +:1067FC00000041077FF511AF20F00400C8F800003D +:10680C00306823F07FF900287FF407AF02E0A0681E +:10681C008847DCE7D8F8000040F01000C8F800000A +:10682C005846F7E64C7A0020507A00204425002088 +:10683C00547A0020BD7A0020302600202DE9F04F3C +:10684C0093B004461EF006FC08B1112006E1207F2F +:10685C004FF6FE75B8B183480078810041EA4010CC +:10686C0061882077FF2020F089FA002180B1E08A2E +:10687C0005F1010B012640F00400E082207F40F07E +:10688C000100207707E0002000264FF6FE7B08E091 +:10689C0000264FF6FE7B74480078022838BF012191 +:1068AC0088010490678838461DF040FA08B1002032 +:1068BC00607694F81AA0BAF1000F04D16B4890F8E6 +:1068CC0000A084F81AA094F90000C5B2B0F1FF3F03 +:1068DC0007DDE07E40B966480178E1760131017050 +:1068EC0002E005F003052570207EDFF88491012875 +:1068FC0005D199F80B0010B90DB900202076DFF8FE +:10690C00688198F80000012831D899F80E008007AA +:10691C002DD5E6B1E08A410606D5BAF1010F03D1B7 +:10692C0020F00400E08222E0A188E07E627DADF8D8 +:10693C0022708DF82AA0ADF824108DF82B0006A833 +:10694C0004F056FD00283FF480AF25780FE0384660 +:10695C001DF0ECF958B1002DDCD0206900780A2824 +:10696C0005D8012101FA00F010F4836FD2D14FF653 +:10697C00FE7A012D07D120690078022803D1E08A24 +:10698C0040F04000E082EEBBE08A10F0400039D1CC +:10699C0098F80000012835D899F80E00800731D5F9 +:1069AC00049DA71D6188607E3A462B4613F020FBA0 +:1069BC0028B100206076E08A40F02000E082387830 +:1069CC0070B1618804F108001CF006FC83466088F5 +:1069DC00834504BF00203870E08A40F04000E0821C +:1069EC002078012804D0A18860882A460FF084FC06 +:1069FC00A18860882A460DF0ADF818B1E08A40F005 +:106A0C002000E0820DF11701204605F07DFB0646C3 +:106A1C001FFA8BF0504508BFB4F802B0EEB12078E5 +:106A2C00617D94F82C50B9F816209DF81730079416 +:106A3C008DF81800608DADF81A00E08A06ACCDE92F +:106A4C000254CDE900101FFA8BF130460BF070F9AF +:106A5C00102803D1304623F04FFA102013B0BDE8B4 +:106A6C00F08F00BFC327002024260020CBBA0200E1 +:106A7C00A86D00202DE9F04F99B012AF8A4604465C +:106A8C001C219346384623F043F9204639460CF036 +:106A9C009BFA9DF855009DF85C10084307D09DF8B3 +:106AAC00480041060CD560891DF040F930B140F228 +:106ABC00351013F09CFD19B0BDE8F08F9DF848001F +:106ACC0000F00C0510F0200FC0F3401918BF042D76 +:106ADC0021D1E08D9DF8483010F080010CD15A0680 +:106AEC000AD59DF84920920706D143F0040202F022 +:106AFC000C020C2A40F0CA804FF00008012213F05F +:106B0C0003031ED0012B46D0022BD4D1A08912A98D +:106B1C001AF098FECFE7A68922F09EFE864202D19B +:106B2C00E08D010609D4A68922F096FE864200F07B +:106B3C008B80E08D010600F18780000679D4A08956 +:106B4C007BE0544EF37A012B02D1A379002B78D041 +:106B5C000223A7898DF84430ADF83C7081BB042D1D +:106B6C0075D1207C4E4D8DF85E0028680028A2D08F +:106B7C0022F072FE87429ED1E08D217994F830206C +:106B8C002D684346CDE903028DE8020A0FA812A92D +:106B9C005246A8478FE7002918BF012152EA01008D +:106BAC0003D1A08912A914F0F8FCA0890797ADF8BD +:106BBC001800A0798DF81A0006A819F0ABF97AE73D +:106BCC00ADF8300016989DF84A109DF84B208DF8C2 +:106BDC00203094F832300B9060898DF82310DDF85A +:106BEC004E108DF8222094F830208DF83830ADF806 +:106BFC001800B08CCDF826109DF85C108DF837205D +:106C0C00ADF82400207CADF82A10A17C8DF8320060 +:106C1C0020798DF834109DF85F108DF833009DF8B5 +:106C2C005D008DF836108DF8350006A802F0E6F8F8 +:106C3C0041E7A089ADF86200608912A91EF03EFB05 +:106C4C0010B14FF49A7034E74FF0010941E71AB9CB +:106C5C0012A9384614F0A1FC10480078022809D17A +:106C6C000D480078012805D1204611F04DFB002875 +:106C7C003FF421AFA07CE17CB28C53468DE8020A34 +:106C8C00039012A80FA90EF075FF14E74FF001083E +:106C9C00002234E7A86D0020E527002024260020E0 +:106CAC003C2400202DE9F04F95B0044680690DF18D +:106CBC0053020021002690F800A09C200BF07AFAD9 +:106CCC007D480078012808D8002004211CF086FF9C +:106CDC0006469DF85300304400E00120C1B2002567 +:106CEC008DF85300514540F28180A0EB0A005FFA09 +:106CFC0080F90220B9F1020F28BF81461A2009FB46 +:106D0C0000F023F0FBF80027002800F0C380079464 +:106D1C0009A90496F6B28346D04600240590CDF816 +:106D2C0018A004310891E0B2484566D25FFA88F0A9 +:106D3C00B0425FD21FF06AFE002853D05F4905466F +:106D4C00888C393122F0D0FD4FF60270ABF8170069 +:106D5C0028888DF82470ABF81200ADF82600A97ABB +:106D6C008BF8191009A812F079F901460BF10A00F9 +:106D7C00012903D1089923F06CF803E04FF0FF319F +:106D8C0041600160287950B14C4991F838100131BB +:106D9C0002288BF8181015D80221012814E0474856 +:106DAC00022190F838008BF81510298800290A4622 +:106DBC0018BF01228BF8142018BF411E00208BF83D +:106DCC0018100BE0012103288BF8141003D18BF859 +:106DDC001570012002E001208BF815008BF81600CD +:106DEC000BF11A0B08F1010801349CE74FF0000974 +:106DFC0000274FE00498CAFA50F830480DAD4FF018 +:106E0C00020AAE1C00F13907E0B248453ED25FFAE7 +:106E1C0088F187202A460BF0CDF9BDF83E003946A3 +:106E2C0022F062FD0BF10A00314623F012F8BDF896 +:106E3C0034002149214B012208F10108ABF8120062 +:106E4C000978022938BF022293F838308BF81520C4 +:106E5C00A3F1010238BF4FF0FF3202294FF00001BD +:106E6C008BF8182038BF01218BF817A04900002897 +:106E7C008BF8161018BF01209DF8461001348BF8C2 +:106E8C0014008BF819100BF11A0BBDE7079CDDE908 +:106E9C00057A0025607C9DF85330A11C0022CDE9B9 +:106EAC0000A9CDE902750AF007FB17B1384623F0AB +:106EBC0023F815B0BDE8F08F24260020A86D002023 +:106ECC002DE9F0478AB0DFF8C0810446D8F80000FD +:106EDC00416E02A88847DFF8B4A1DAF80800016C0B +:106EEC00096811B9D0F84C05804769480121017037 +:106EFC00DAF80C00C068007830B9DAF80800002124 +:106F0C00D0F858240120904722F033FE47680589B9 +:106F1C003878C0F3401128460FF09AFADFF87491D4 +:106F2C000790D9F8101019B122F023FE0C308847C5 +:106F3C00D9F8080008B18047089057480078F0B19C +:106F4C00D9F82010B9B1884755490028554B0A4645 +:106F5C0008BF023212781A708DF82420CA1C00283F +:106F6C0018BF4A1C10788DF825004C481978022956 +:106F7C0008BF023000E0494801880131018016F059 +:106F8C00C3F84A48484E0078F57350B122F0F1FD31 +:106F9C00007D30B1284622F08FF81FF047FA002808 +:106FAC006BD000253761758022F020FC0746758078 +:106FBC00059524B1012C31D13D483E49C1613C4875 +:106FCC003949027B437BC47D416045804D6002F0B2 +:106FDC00F002027303F0F0020232427304F0F0028A +:106FEC000432C2754A7B22F00F02531C4B73DAF841 +:106FFC0008301B6C1C6864682478A40608D52E4CD9 +:10700C0042F002024C601B685B689B784A73A37366 +:10701C002A4E7060707B00F0F00070732848D8F82E +:10702C0000100822274B0C6D00210068CDE90021CF +:10703C0002AA3146A0472449B0F1FF3F088007DD82 +:10704C00224819490160224801780131017010E091 +:10705C00D9F8004044B1DAF80800002100220023DE +:10706C00006C00680C30A047012041F2883114F00C +:10707C002DF9384622F075FE02E0E1200BF046FBBC +:10708C000AB0BDE8F08700BF347A00200C01002064 +:10709C00B327002054B502002C250020AC7800202A +:1070AC00BE790020AA7A0020C0770020A0270020FB +:1070BC00B8750020006A180048780020742500205C +:1070CC00E4260020F59600008E7A00203025002062 +:1070DC0029250020B0B5784C20780E2850D8DFE850 +:1070EC0000F0E34F4F5E084F4F4F4F4F584F08087B +:1070FC00080073480078B0B1A078012830D1E0784E +:10710C000130E070C0B2032851D870484FF6FF71BF +:10711C00808C88424FD06C48012101704FF4417033 +:10712C00A4F8010049E06C480021E17001700020D6 +:10713C001CF0D8FF18B120780D38012862D86148AE +:10714C000078022803D10820012104F08DFB0520D2 +:10715C0020F020FE42F21070BDE8B04020F0D2B911 +:10716C0003282AD157480078022826D156480121F5 +:10717C00017003200021A070544880F826101CE0F8 +:10718C0015F05AFF554810210078BDE8B04016F0B4 +:10719C00B7BF4A48008800F007000128A9D1484829 +:1071AC000078F8B10020BDE8B0401AF06FBB484839 +:1071BC000078012801D10020A07019F0FFFE20F00A +:1071CC00A9FC3E488078000703D542480078012886 +:1071DC006AD1A078032867D108200121BDE8B0400E +:1071EC0004F042BB3D481021007816F089FF0020C6 +:1071FC001CF078FF334D297810B361B32078012946 +:10720C002AD036E0062020F0C5FD2C4CA0780007D3 +:10721C0004D54FF40040012104F026FB29480078E6 +:10722C00012809D8208800F00700022804D000208B +:10723C000021002222F0ACF8BDE8B04015F0FCBEF5 +:10724C00022903D10820012104F00EFB052020F0B7 +:10725C00A1FD0120A7E720780A280AD11748008849 +:10726C0000F00700022813D01848082180F82610D7 +:10727C000EE003280CD115F0DFFE19480078022827 +:10728C0006D101201FF08EFD02200121FDF7B0FA7E +:10729C00062020F07FFD2878012805D807480088B3 +:1072AC0000F00700022800D1B0BD00200021002210 +:1072BC00BDE8B04022F06CB8D02600203E7900200A +:1072CC00BF7A002024260020A27A0020A86D00207E +:1072DC00977A0020CA270020AE2200209D7A002039 +:1072EC000C7A00202DE9F04F93B01C9C08901D46A1 +:1072FC0006928B4620461EF0A9FC074620461EF03F +:10730C008DFC00260790002F00F0E980002D18BF9F +:10731C0001256801BBF1000F00F140014FF0000B9B +:10732C0008BF69014FF6FE7503914FF00A0108BFC3 +:10733C000821029109A90431019100F108010C30D6 +:10734C0005910490207C834580F0C480380600F0C1 +:10735C00C18004EBCB0898F81C00C00740F0B78044 +:10736C0061480078012820D898F8160028B10F96AB +:10737C00CDE90D664FF0010A1FE0B8F8180022F0B5 +:10738C008AFC90B1007940F0020003280DD198F8E6 +:10739C001C004FF0000A40F0800088F81C00079891 +:1073AC00000604D10020079091E04FF0010A98F8F4 +:1073BC001600CDE90D660F96C0B14C49089CB8F883 +:1073CC00180091F86810012908D1FF21ADF834009C +:1073DC00059841F2080988F81A1024E0A080681C6E +:1073EC004FF00C09ADF8340004981CE0B8F8180004 +:1073FC00089CA84213D104208DF8240098F81D0095 +:10740C00ADF8300009A818F0ADFD0198002100225C +:10741C000023A580ADF8345016F062FF01E0ADF802 +:10742C003400DDE902908DF8360001208DF839002A +:10743C00207D8DF838000DA807F018FF9DF8480046 +:10744C0078BB109806994176417DA0F8169088F883 +:10745C001B1098F8161019B1244991F8681001778F +:10746C001C9A51890185518A4185117D80F82C1017 +:10747C00517980F83A1098F81A1080F83B1021894D +:10748C00A0F84010617D80F8491062682169C263E0 +:10749C00406C227D21F0D4FF0DA81BF0AFF89DF8B5 +:1074AC00480098F81C1041F0010288F81C2020B10B +:1074BC0041F0090088F81C0005E007998AF00100EA +:1074CC00013F091A07911C9C4FF6FE7500260BF123 +:1074DC00010B37E72046002117F070F906463046BD +:1074EC0013B0BDE8F08F00BF24260020A86D00204B +:1074FC00BFB581780446481E0B2812D8DFE800F08F +:10750C0006525C6A26788590A430B23900208DF83A +:10751C000400E0780F28C0F0B28002208DF804003F +:10752C00B3E0FF2940F0D3800025E01C04218DF846 +:10753C0003501FF01DF96C4908606C48058011F070 +:10754C00E1FE0DF103036F20FF21BDE000208DF85B +:10755C000800E07802F084FA02AB6F200521B3E05A +:10756C0020F058FC8DF80E000DF10E036F200A214F +:10757C00AAE000208DF80F00E01C22F0BBFC0546B1 +:10758C00601D04211FF0F4F8014628460DF028F97F +:10759C00504A3520282122F091FA0DF10F036F206B +:1075AC000C2191E000208DF80600E0780F2870D3B4 +:1075BC0002208DF8060072E0E07847490DF10703D0 +:1075CC00002818BF01200870002003218DF8070047 +:1075DC006F2079E0E2780020211D8DF80A0004F17B +:1075EC000C00022A68D0012A6AD117F017FF65E057 +:1075FC0000208DF80C00E078002818BF012020F046 +:10760C0081FF03AB6F2006215EE0E078211D19F0AD +:10761C0059FB8DF80D000DF10D036F20072153E080 +:10762C000020E57804218DF80900201D1FF0A0F83A +:10763C00002D014618BF0125284621F01FFD0DF134 +:10764C0009036F2008213FE000208DF80B00E07843 +:10765C00002818BF012022F0E9F90DF10B036F206F +:10766C00092131E000208DF80500E07804281BD2B8 +:10767C001B4A01211070512022F020FA17E0194A00 +:10768C0001211070522022F019FA01AB6F20012158 +:10769C001AE0124A01211070532022F00FFA0DF15A +:1076AC0006036F2002210FE002208DF805000DF17A +:1076BC0005036F200B2107E00BF09AF88DF80A00F8 +:1076CC000DF10A036F20042101221BF057F8002052 +:1076DC0004B0B0BD08750020BE270020D2270020C2 +:1076EC00DC270020D8270020182500201425002096 +:1076FC0070B590B00446807821F026FA002800F08E +:10770C00D38005466078A0F1E101E873102906D911 +:10771C001A2818BFCD2808D01D2806D04BE001220E +:10772C0002FA01F16C4A1142F2D06C4E3078012809 +:10773C0002D8688900056CD42846002108F072F93B +:10774C00C0B3307801282BD86548807B800727D5BB +:10775C002968086A20B3C97F03AA09F039FD60784B +:10776C00E92808D12868E27B01234189008800932D +:10777C00E92301F06FF92868BDF8161001809DF817 +:10778C001120BDF81810BDF81600002A18BF0122F0 +:10779C0092010CF0DFF918B1688940F02000688183 +:1077AC006A896178288920F0C5FB28813078012806 +:1077BC0031D971E060788DF81000A07B03958DF8BD +:1077CC001100287C00283ED003A811F0FDFF9DF885 +:1077DC001030E92B00D03BB92868E27B01264189A7 +:1077EC000088009601F036F93C480078012853D8FF +:1077FC003B48807B80074FD5687B022802D1688983 +:10780C0040073BD46078E92846D128461BF0B6FAED +:10781C0042E0052068736078E9283DD03148006863 +:10782C0000B18047304E3068B0B32D48807B800764 +:10783C0032D52868418900881BF0F8FF60B3617865 +:10784C003268904728E003A805F044FE23480078EE +:10785C0020B19DF81030012802D0BAE79DF8103005 +:10786C00002BB6D1286800881CF060FA0028AED135 +:10787C001C4800680028AAD08047A8E72868008820 +:10788C001CF054FA002811BF032028684FF6FF7132 +:10789C00018008BF05206873687B022804BF06209E +:1078AC006873A07812F064FD1FF055FC0B4800784B +:1078BC0002280ED10D48007858B900200DF10B01AB +:1078CC008DF80B0052201AF059FC2020012103F0F6 +:1078DC00CBFF10B070BD00BF0101010024260020B9 +:1078EC00A86D00207C23002080230020E5270020A9 +:1078FC002DE9F04F8BB0002900F0EC80DDF858A09A +:10790C000746007A0D46994690465FEA0A718DF853 +:10791C00060012D4387A02240F2800F2DC800121F0 +:10792C00814011F00B0F19D003288DF8100024D1D1 +:10793C0002A8394622F08DFA22E0022840F0CA80D3 +:10794C003C8821F089FF8442E4D03888012103224D +:10795C0013F0CCFB0028DDD0CD24BCE048F20400B1 +:10796C00014200F0B88038881CF0E0F9002800F0E3 +:10797C00AD800F2038728DF810003888ADF80800F3 +:10798C005FEA8A7014D40020ADF8180054480068DF +:10799C0088B14168A942FAD1826862B12978022083 +:1079AC00904768B10188ADF8181022F0A5FA07E0ED +:1079BC004FF6FF7002E0A86810B14088ADF81800CF +:1079CC00CAF380121798DDE9141B8DF805209DF879 +:1079DC001020531E18BF01230F3A18BF9A001AF03B +:1079EC00100318BF13464FFA8AF2002A0AF040021D +:1079FC0048BF43F0100343EA92125FEA4A73ADF8B2 +:107A0C00202044BF42F04002ADF820208DF8240025 +:107A1C000791ADF81A90ADF8168000229BF8000083 +:107A2C007C7A7E895FEA8A618DF804202D498DF875 +:107A3C00220028788DF81340ADF8146009788DF881 +:107A4C00120048BF04218DF8231021F029F828B129 +:107A5C00016919B102A888477C7A7E893046214693 +:107A6C0021F09CFF28B121F019FA48450DD20224CF +:107A7C0013E001A821F0F8FA48450AD21A48016827 +:107A8C000029F4D002A8884706E002A806F0C4FE3C +:107A9C0002E002A801F0B2F904469DF81000022899 +:107AAC000CD1BDF8086021F0D7FE864206D19BF8B8 +:107ABC0000102878424623461BF0C8FD5CB99BF8A1 +:107ACC000000002401308BF8000004E0387A0F2805 +:107ADC007FF42AAF022420460BB0BDE8F08F00BF24 +:107AEC00247A0020E71D002000270020F8B57B4EEB +:107AFC000446B068D0F8B8100A78CAB18A6BBAB12B +:107B0C00896DA9B10DF1030142F21A009047B068DA +:107B1C00D0F8B800806D8047002738B19DF803007D +:107B2C0020B1A4F1E100B0FA80F04709B06800E0A0 +:107B3C000027D0F8401400208847C07B012502287C +:107B4C0008BF0525B168086C0068002800F0C480E7 +:107B5C00E92C12D01B2C03D06CB90021417077E0BA +:107B6C00027D052A05D0D1F8D41091F88210002995 +:107B7C00F3D017B96BE0002F49D0F068816DF1207C +:107B8C008847B068016C09688A7E2AB1CB8A5B078A +:107B9C0020D4501E887633E0D0F83C058047B1687D +:107BAC000A6C126888B3D08A40072ED4D1F8D4005E +:107BBC0090F834009076D1F8D40090F82220531C21 +:107BCC0080F82230086C006840688270F068016AA6 +:107BDC00284664E00A7E02F07F020A76016C09688E +:107BEC000A7D032A5DD1CA8A22F00402CA82006C83 +:107BFC000068817E01398176394801880131018024 +:107C0C00F068D0F8AC008047F8BD547020E01C2C14 +:107C1C004FD0E12C1BD1D1F83C058047B26801460E +:107C2C00106C006899B1C18A490710D4D2F8D410ED +:107C3C0091F834108176D2F8D40090F822104B1CB5 +:107C4C0080F82230106C006840688170BEE7447088 +:107C5C00B068D0F86C12006C00688847B068016C92 +:107C6C000A68D28A120614D5D0F8B810097839B936 +:107C7C00D0F8D400F16890F84300096B8847B068DD +:107C8C00D0F8D400F16890F94200496A8847B0688E +:107C9C00016C00200860B068D0F8281310208847C9 +:107CAC00F8BDF068816DF0208847B068816C096878 +:107CBC00D1E7096E09680029D0D08847B068002147 +:107CCC00006C0160F068C068007828B9B0680021C9 +:107CDC00D0F8582400209047F8BD00BF0C010020BC +:107CEC00822700202DE9F04788B004464FF0FF3082 +:107CFC0002214FF6FE79CDE90200E089002808BF89 +:107D0C000821A66916F801A030B1704835880088A2 +:107D1C00854213D16E4E06E06D4831461FF017FEBA +:107D2C0090B36A4805884D4518BF002E29D1207B99 +:107D3C00002840F0C8806848406843E065480078F7 +:107D4C0001281CD8284621F0A6FFC0B101790026D5 +:107D5C0001292DD140880DF110088DF81060ADF877 +:107D6C001C00404618F0FEF80646002818BF08F123 +:107D7C000406BAF1000F18BF4FF0FF3AD3E7002604 +:107D8C0016E05548406825E05248007801280DD887 +:107D9C00304621F0DDFF48B101790139012905D8C0 +:107DAC00BAF1000F18BF4FF0FF3ABBE74FF6FE7564 +:107DBC00207B002840F08780474840684D4518BF1D +:107DCC00002E07D1E1894FF0810881B100F8018BB9 +:107DDC0002AE11E05FFA8AF1022902D24FF00008DC +:107DEC0007E0217B01296ED04FF0800801E009F1FA +:107DFC00010500F8018B0EB1314600E002A922F01A +:107E0C0028F80570064605803248007838B10B27F3 +:107E1C0001284AD15FFA8AF0012804D045E05FFAC4 +:107E2C008AF0012822D10B27B8F1000F3DD1274849 +:107E3C00A9B20088814238D100250DF107008DF8D8 +:107E4C00075016F049FD98B1E1890322002908BFBB +:107E5C000922A1698A5C9DF8071091420BD9891AF5 +:107E6C000D238DF8071003EB410708E00B271CE0EE +:107E7C000C27B57019E000210D278DF80710F27052 +:107E8C005200331DB17009060DD0815C03F8021B42 +:107E9C0081180232497803F8011C9DF8071001394A +:107EAC008DF80710EFE722F027F8E2890A4D102031 +:107EBC00A11CFBB2A87004F1110042F4004217F0AF +:107ECC0005FB0020A87008B0BDE8F0878879002079 +:107EDC00E079002024260020882600202DE9F04F90 +:107EEC008DB00746C08914468946073086B23046A5 +:107EFC0010F09AFA0546FF280AD13046FAF760F9D5 +:107F0C00B04205DA70480778002F08BF0527A3E0B8 +:107F1C006D4E3078C0B91CB1022C15D1FF2D13D188 +:107F2C00387A002203238DF81C00786800920690A2 +:107F3C006648C188C07805AA02F058FB9DF8240059 +:107F4C003874BDF82000B881DFF880B1002104231B +:107F5C009BF80340BBF806A00CAA204621F038FA87 +:107F6C009DF830007E2805D120467C211CF0E4FCD5 +:107F7C009DF830007C286BD1FD8905F107081AFAB1 +:107F8C0088F0B0F5005F65D8BB88C5F38512049006 +:107F9C00F88849461FFA88F94FEA850C8DF82DC0F0 +:107FAC0042EA83128DF82A00C0F301208DF82C20B0 +:107FBC009A088DF82B203A7A05EB0A07B9F10D0FC8 +:107FCC0040EA82008DF829004AD23F482A460197A0 +:107FDC00CDF80CC000F11C06304621F0B5FFDDF8E1 +:107FEC002900711900220027029170519DF82D0073 +:107FFC000871681D81B2304621F04CFCDDF8291067 +:10800C0032464B46715196212F4D8DF82F10039906 +:10801C0021F015FB02998DF82E000B98C1F8030086 +:10802C00204651461BF062FF04EB4401049A287071 +:10803C000BEB81018A83BBF806104144ABF80610A8 +:10804C0050B1019881B2204618F002FC2F7803E061 +:10805C00012700E00527377038460DB0BDE8F08FDA +:10806C00894608462946002221F014FC0DF129010D +:10807C00052220F063FA96214A462B468DF82F10E4 +:10808C009DF82D1021F0DBFA51468DF82E0020467C +:10809C001BF02CFF3070B9B220460DF129020723DA +:1080AC001BF024FF317851EA00073770D4D104EB70 +:1080BC004400049900270BEB80008183BBF8060079 +:1080CC004044ABF80600C7E7A0230020B87200209C +:1080DC002DE9F04F8BB0876904463D88B7F80290C4 +:1080EC0028461BF023FE01280DD1207C617C002248 +:1080FC008023CDE90052CDE90220A21C48F20600F3 +:10810C0017F034F9D1E028461BF010FE20B969486D +:10811C000088854240F0C4803E7905375EB170001E +:10812C0021F0ECFE38B10246304639460A9221F075 +:10813C0079F8074602E0002000260A9017F8015B48 +:10814C0055B1680021F0DAFE30B182462846394636 +:10815C00524621F067F802E04FF0000A0025A819FA +:10816C001421564F01EB4000C0B2079068000690F6 +:10817C0070000590A01C0890002009903F68002F0B +:10818C006AD0786801780029F8D0BA7BD207F5D08C +:10819C00D7F80880B8F1000F03D00120C047834600 +:1081AC0001E0D0F808B0BBF1000FE7D0BBF802003B +:1081BC00814503D04FF6FF70814511D1DBF80830B3 +:1081CC009BF807200A9930461DF041FE78B9DBF880 +:1081DC0010309BF80C20284651461DF038FE30B963 +:1081EC00B8F1000FCAD0584621F086FEC6E70798B2 +:1081FC001FF09EF838B30146D220087008980491FD +:10820C0000880D730E7148803EB101F11400059A7F +:10821C0088600A9921F014F901E00020886055B1BA +:10822C000499069A01EB460014300861514621F07E +:10823C0007F9049902E00499002008617868406805 +:10824C00007816F08BFF099B9BF800001C4AD9B2F2 +:10825C00013350540993C3E7099B0A9D180610D0AB +:10826C001448DBB2227C617C0088CDE90003144801 +:10827C000023CDE9020248F20600089A17F076F8BE +:10828C0001E0207BA0B115B1284621F035FEBAF1F2 +:10829C00000F0AD050460BB0BDE8F04F21F02CBEB9 +:1082AC000548007802283FF420AF0BB0BDE8F08FF2 +:1082BC000023D5E78879002024260020247A00208A +:1082CC002C7300202DE9FC47D0E900588246D8F8E1 +:1082DC000000D0F8409019F4F06FC0F8449035D0FD +:1082EC005FEA495117D5D5E91401411A50461DF0E2 +:1082FC003DFFD8F800008169C90605D401688DF8E6 +:10830C0007109DF80710F6E7296801312960A97B51 +:10831C0009B90121A973696C40684FF0004600F05F +:10832C000F0404EA0100B0FA80F126FA01F10140D1 +:10833C0005D02F6C1FB12A68AB6C5046B847B4FA05 +:10834C0084F026FA00F020404042A863D5F858018A +:10835C00D8F83C1009F0400740680068D0F80425B4 +:10836C001140394347D0DAE90064504614F030FE2E +:10837C00D7B1F07C90B90BE0316F69B10068B16E88 +:10838C00B26F8854306FB16F01310138B16730670B +:10839C0020688169C906EFD5F07C28B1D6E91401B3 +:1083AC00411A50461DF0E2FE96F86400E0B13079B7 +:1083BC00022819D017B1B179012901D0316F99B9BF +:1083CC000024B16E0128346786F86440B46607D186 +:1083DC00B36CB26FD6F8CC6050460094B04703E053 +:1083EC0006F17C0021F09CFD504609F0C9FAD5F845 +:1083FC0058014068006800F204500068D8F8381042 +:10840C00084228D0D5F8F80028B3DAE900765046AF +:10841C0011F02EFE50460CF0E1FC7879012812D1B7 +:10842C00D7F8F40078B997F8E80060B1002087F825 +:10843C00E800BB6CD7F8EC10D7F8FC20D7F850410B +:10844C0000905046A047D7F8F80020B93068816BEF +:10845C0041F4006181635FEA095023D5D8F800002C +:10846C0081690907FCD4016B21F480710163297ABD +:10847C0091B10020287295F84400800606D52C6C2A +:10848C0024B1AB6C504620210022A047504601215C +:10849C001EF098F9D8F80000816B21F4006181631B +:1084AC00687908B1BDE8FC8705F58070BDE8FC472C +:1084BC0021F036BD2DE9FE4F1D4614460F46814670 +:1084CC0021F094F9DFF8C0A183464FF6FD78DAE984 +:1084DC000010494518BF084660B1B83021F0E4FCE3 +:1084EC0040B19AF82400CAF8209040F004008AF8B1 +:1084FC0024009FE01FF0DEFB002868D0064663488E +:10850C00CDF808B0DDE90CB821F025FC604908F085 +:10851C00200EB1F8540001306FF31F30A1F8540055 +:10852C00B5605C480025C6E903792268D4F80C8054 +:10853C0086F83250C6E908550BEA000C207C7263B1 +:10854C002279C6E906CEC6F8408086F8440086F843 +:10855C003820B1F8541086F83350D4E905533186DD +:10856C00A168C6E91253F163A18BA6F8501028B983 +:10857C00B8F1000F1CBF012086F844004AB9387BC3 +:10858C0000F00F00022804D1012086F83800B868EA +:10859C007063DDF808B00822FF2353FA82F23C46E0 +:1085AC00D0B2851A18BF01257F680FB1002DF4D108 +:1085BC00208800F47C40B0F5305F0BD196F8330086 +:1085CC000022082340F0100086F8330004E008F184 +:1085DC0001082FE0002202234CEA03004EEA0201BC +:1085EC002B4DC6E90601DAF82000484507D19AF868 +:1085FC002400C1071CBF00F0FE008AF824002648A6 +:10860C00046854B1A96CEA6C05F1400005F138031B +:10861C0000903046A047033013D1FD209AF8241067 +:10862C00CAF820904FFA80F841F004018AF824101F +:10863C0020F0E6FE584621F094FB0FFA88F0BDE8D6 +:10864C00FE8FB6F83080B5F85410414501D020F0BB +:10865C00D7FEC0B2012801D8FE20DFE7002089F840 +:10866C00FC0096F8330040F0800086F83300A86BCD +:10867C00B04205D0F068007B00F00F000228D9D181 +:10868C0015F0A2F8D6E700BF70200020387100204A +:10869C0030210020FFEFFF9F902600202DE9FF41A5 +:1086AC00DFF8BC81002003900290D8F83840B4B3B6 +:1086BC00D8F84C0010B9D8F8480070B3D8F8480076 +:1086CC0060B12069D8F848100969814206D194F844 +:1086DC003300C00602D5D8F84C0090B1002702A890 +:1086EC0087F0010103AA10F085FD0546FFB9F5B12D +:1086FC000299002900F09D805A4820F065F9002766 +:10870C0014E0D8F84800C06840880028F9D0D8F8A0 +:10871C004800C06840880128F3D00127DFE75248A1 +:10872C000221283021F000FC0027002500242CB366 +:10873C004E48466816B30298B0FA80F040092840BB +:10874C0001281BD1D8F84800D8F84C10039A87F0B0 +:10875C000103CDE9003208F1380208F14003B047BB +:10876C00012868D0022809D1D8F848000122012339 +:10877C000069D8F84810B1F9301065E0002C20469B +:10878C0018BF01203840012851D13948216940686F +:10879C00814203D034484FF4806145E002980028B0 +:1087AC0018BF01202840012806D1D8F8480018B974 +:1087BC00D8F84C0000284DD008201FF0C3FD94F8C9 +:1087CC0033004C25C00608F1380058BF48251FF06F +:1087DC0047F848F80500274BD4E90601C2439A60D4 +:1087EC00DA681043D860C8431860586808432146BB +:1087FC0058600820E5681FF07DFA28461FF0AAF99A +:10880C00288843F60601411A022906D3B0F5C15F48 +:10881C0003D040F60201884203D1012029461FF003 +:10882C0069FA11484FF08041283021F07DFBBDE8FA +:10883C00FF8100277BE70398002818BF044601221C +:10884C000023B4F9301020690092002205F0BEF824 +:10885C00BDE8FF8108201CF00BF9BDE8FF8100BFCB +:10886C00302100207C7100207020002090260020F8 +:10887C00D01E0020081004402DE9F0478AB0684D46 +:10888C002868416E02A88847664FF87918B1B87904 +:10889C0008B10020C0E020F0A9FFDFF88CA18046D1 +:1088AC0000249AF8000080074FF0000005D47D20CA +:1088BC0000210DF0CDFD8DF818408DF80C40029480 +:1088CC005A4C0790616911B19AF800008847E0682A +:1088DC0008B180470890387A98B1606A88B18047AF +:1088EC005349544B8A1D002818BF0A1D12781A7060 +:1088FC008DF82420CA1D002818BF4A1D10788DF849 +:10890C0025004D4EDFF8349100200590317BF27E2E +:10891C00B0607080D9F8080001F0700180313173BB +:10892C0002F08001D0F82824F4206331F176032181 +:10893C008DF8181006F11C019047387980B99AF817 +:10894C00000080060CD52868C06B8047317BB06076 +:10895C00029001F0F0010231317301218DF80C10FD +:10896C0029683748344E384B0D6D4FF080710068D4 +:10897C0001913449009102AA3146A8470546334873 +:10898C00B5F1FF3F058035DDB879002100240130B9 +:10899C00B871787901307871FE60F8790130F8712E +:1089AC00022012F093FC3C712948D9F80820018868 +:1089BC00D2F8AC30D2F8D4201C7841EAC411D48C53 +:1089CC000180D2E9117193F800C0538D7486C48173 +:1089DC00C0F80710C0F803708381508DC6E90A7186 +:1089EC000CF001013086308B20F0800040EAC11081 +:1089FC00308309E0626812B1002000219047022008 +:108A0C0041F2883112F062FC404621F0AAF90020B4 +:108A1C00B5F1FF3FC8BF01200AB0BDE8F08700BF29 +:108A2C00347A002024250020B17A002054B50200AD +:108A3C00BE790020A97A0020007200200C010020D1 +:108A4C00E426002020004300E90F01008C7A00206E +:108A5C00007900202DE9F843994617460C468046CC +:108A6C001AF0E4FE089D06463DB936B9404621464B +:108A7C003A46BDE8F84318F07BBA6EB3002D3ED0F1 +:108A8C00624C207808B1012803D16148806800B19C +:108A9C008047B9F1000F4BD02078012800F2A58057 +:108AAC005C48807B800740D55948C26812B130467B +:108ABC0049469047584831780078884224BF0131A4 +:108ACC0031700024C9B2814230D1404619F056FFB2 +:108ADC007470012701242EE04C4800240127B9F1C1 +:108AEC00000F007829D0012D27D1012825D849481D +:108AFC00807B800719D5404619F040FF15E0B0780F +:108B0C00B9F1000F0AD1C1194808022938BF012058 +:108B1C007178B07011B94149097871704049097880 +:108B2C00884202D90027002405E00024012702E036 +:108B3C0000270024377035480078012D08BF022823 +:108B4C002BD084F001010F424DD1012812D83148AD +:108B5C00807B80070ED5404621F09DF850B11FB99F +:108B6C00417901F0FE014171ECB3417941F0010111 +:108B7C00417100E0BCB3254C2078012821D8254850 +:108B8C00807B80071DD540461FF046FEC8B10020F3 +:108B9C004146BDE8F84321F0A7B9A9F11901022912 +:108BAC00CFD3B9F1000F08D0B9F1E10F18BFB9F16B +:108BBC00F10FC6D0B9F1EB0F1AD1154900220A708A +:108BCC00BFE71448408B40450DD10120414621F0B0 +:108BDC008BF92078022806D14FF400500121BDE812 +:108BEC00F84302F041BEBDE8F88300240127A4E756 +:108BFC00074A0C49137809780133DDB28D4228BF3E +:108C0C000023137028BF01249BE700BF24260020FB +:108C1C0074230020A86D0020CDBA0200CCBA02004B +:108C2C00A3270020D62700202DE9FE4FD0F8008086 +:108C3C00994614460E46824613B10020C9F800002E +:108C4C0020F0D4FD834698F8070038B198F86400FA +:108C5C0048B121F09BF86FF00805B4E021F096F8CC +:108C6C006FF00E05AFE0002C4AD0504614F0B0F96E +:108C7C0000200121C8E91A64C8F87040C8F87800CF +:108C8C00C8F8380088F80C0088F80A00504688F8B4 +:108C9C0064101BF0EFF9504608F072FE08F14C041A +:108CAC0002AD204629461EF0FDFDD8F87810D8F804 +:108CBC0070707218B84238BF0746029910463A468F +:108CCC0021F042F9204639461DF093F8D8F870008F +:108CDC00D8F87810C21B3944012FC8F87020C8F896 +:108CEC00781001DBB842DCD198F8041002290CD1C1 +:108CFC000020C8F8680088F86400C8F870001CE010 +:108D0C0021F044F86FF009055DE0B84215D1002060 +:108D1C00D8F86860012988F86400C8F868000CD19C +:108D2C000124584688F8104021F01BF898F80F00E1 +:108D3C0000284BD020F05AFD834621F027F898F8F4 +:108D4C00040008B100252FE0D8F8701008F17C0061 +:108D5C0031B30C9920F06CFF10B1012088F80C0095 +:108D6C0020F044FD0446504614F032F90020C8F8B7 +:108D7C006800C8F8700088F86400504608F000FEDF +:108D8C0098F80A6098F80C50204620F0EAFF002D65 +:108D9C0018BF6FF00C05002E18BF6FF00D0503E027 +:108DAC000021002520F044FF20F020FDB9F1000F38 +:108DBC0007D098F8041001291CBFD8F87810C9F80E +:108DCC00001020F0CEFF2846BDE8FE8F002598F855 +:108DDC0010000028AED020F009FDA8F80F4020F0BC +:108DEC00C0FFD8F84830D8F87820D8F8CC70504666 +:108DFC0031460095B84788F80F50E8E7F0B587B0D2 +:108E0C0004466F48007878B1228B0020E57A012166 +:108E1C000390CDE901008DF80910500706D402F03B +:108E2C0008030121002008E0BA20ABE0402012F03A +:108E3C0008038DF8060008BF0321402606EA8206C7 +:108E4C004BB1C02093068DF806004FF0010358BFBC +:108E5C0002238DF80730530903EA121202F00802BC +:108E6C00324342EA0106217A03290AD8DFE801F0ED +:108E7C000215112640F0040720F0EEFC8DF8067068 +:108E8C0008E00F291ED140F0080046F004068DF8CA +:108E9C0006002088ADF8040014E04A4991F86810E7 +:108EAC00002900F08180278840F0080006F58056E4 +:108EBC00FF258DF80600ADF8047004E001A92046EA +:108ECC001CF014FA0027208BC0070ED09DF806006A +:108EDC0010F00C0F58D09DF8060000F00C0104297E +:108EEC0004BF40F020008DF80600A07C8DF808002F +:108EFC0001A806F0BBF99DF81800002842D104988F +:108F0C00C682B4F81B10A0F81910217A012903D1DC +:108F1C002C4991F868100177A17EE37F0185228BA3 +:108F2C0080F82C301306428508D5D20506D5417D34 +:108F3C0094F820001DF0D9FCA17E0498878780F856 +:108F4C003B5080F84A10A17A80F83A10D4F80E10F1 +:108F5C00C0F83E10A17F80F84B10617F80F849105B +:108F6C00406C6169628A20F06BFA208B400604D554 +:108F7C001548016809B101A8884701A819F03EFB02 +:108F8C009DF8180007B0F0BD208816F0CDFD48B153 +:108F9C009DF8060040F020008DF80600208BC007DD +:108FAC0099D1A2E7BB20EDE727884FF6FD7140F081 +:108FBC000C0046F00406ADF804108DF8060082E7AC +:108FCC002C240020A86D00206C2700202DE9F04FE8 +:108FDC0089B0714F14460A46064610460492B98C65 +:108FEC001AF024FC054610B16878002866D0B06AE7 +:108FFC004FF00E09B34690F80180867890F805A0E2 +:10900C005FEA886158BF4FF00609B0F8030003907F +:10901C0004981AF0DBFF18F0870F4CD108F01801F8 +:10902C00182948D09BF81C10894544D100EB0A0242 +:10903C000021BBF80C00B1460091D1B292460E460D +:10904C00049B494632460EF0B5FC032836D008F096 +:10905C007801B8BB18F0180F62D05FEAC860884678 +:10906C004FF0030058BF012040EA0108BBF80C0088 +:10907C00414610F07DFF88B1817911F0180F0DD0A9 +:10908C00417901290AD14DB1B98C40881AF0CEFB37 +:10909C0020B1407810B1697888420FD320F0C1FA22 +:1090AC0088B94FF0FF3020809BF8080000286BD067 +:1090BC00DBF8181069E0D32011F099FA002009B000 +:1090CC00BDE8F08F884620884FF6FF718842F5D1B5 +:1090DC000121BBF80C00324600914946049B0EF06E +:1090EC0069FC0398414685B2284618F0FBF9F98AC9 +:1090FC0088420CD1284620F0CEFD20B300790138EF +:10910C00012820D805A928461CF000FE21E0DBF838 +:10911C00280080F805A009B0BDE8F04F1EF0CABCCD +:10912C00787B884608B120F07CFA03984FF6FE71E4 +:10913C000022434680B203F0E1FF0028C3D14FF672 +:10914C00FF702080C4E71FF0D1FE014605A820F077 +:10915C0080FE9BF80800012804D1DBF8181007A842 +:10916C0020F077FEDBF82810BBF80C00497805AA34 +:10917C0007ABCDE9003200224B4641F030010291A1 +:10918C00294608F0BDFE99E70021BBF80C003246D9 +:10919C0020F098FE97E700BFA86D002070B58AB04C +:1091AC0000F11605044628461BF00CF867480078B9 +:1091BC00013801282BD800201021012214238DF80E +:1091CC00110005AE0DF11100CDE90210CDE90062E0 +:1091DC000DF11201042000221BF098F950B15C48EB +:1091EC00006804A905AE324610F0ACFAC728ADF8F9 +:1091FC0012000CD806F108002946082220F020F9AC +:10920C00BDF812100420142233461DF017FA28461C +:10921C00FF2108221FF082FD10B14E480121017080 +:10922C0028461BF0DBFC20790138052800F28B80E6 +:10923C00DFE800F00389345C8903A01D00211029AC +:10924C0013D0425C0131002AF9D061791EF036F955 +:10925C004348424D90F8410008B12878D8B1607964 +:10926C000DF0CAFE0020287015E03D4890F8410032 +:10927C0088B905AC002062210025224610F030FC94 +:10928C00204600211EF01AF900200DF0B5FECDE9A4 +:10929C000755CDE905551FF0EFF854E00DF112011B +:1092AC0028461DF0B9FA60B10DF112024FF6FE70AE +:1092BC0029461CF0DFFF284600210022002315F070 +:1092CC000FF8BDF8126005A930461CF027FB059875 +:1092DC0028B905A81AF07EF908B905980680A11DD1 +:1092EC00284610F005FD13F0FFFC2CE01A4E3078E8 +:1092FC0048B30DF1120105AA284610F023FA0146D5 +:10930C009DF81200F8B1002501201422ADF82400BC +:10931C0006958DF82650059505AB04201DF08EF9A9 +:10932C0006344FF481701021224620F0C1FB28B97D +:10933C004FF481701021224620F0C0FB0120032144 +:10934C00357018F0C7FA0AB070BD00BF2426002093 +:10935C00EC580020A07A0020B0220020AF22002080 +:10936C00A86D00202DE9FE4FD0E90198D8F8001027 +:10937C00CA690A62D20740F0AF80D8E904014FF005 +:10938C00000A4FF0000B0843D9F8CC104968096863 +:10939C00C1F8040509F13000029009F1C8000190F0 +:1093AC00BBF1010F00F2A180D9F8C000002800F039 +:1093BC009C80D9F8E010DC22D9F8CC70202300294D +:1093CC0008BFD82208BF182358F803404FF02403D5 +:1093DC0008BF1C237F68D8F8146058F803303F6826 +:1093EC00D7F80455354211D0A46864070ED104682F +:1093FC00D9F8D050A54209D144693CB9D8F80040FD +:10940C00656A25F002056562C7F804659B685B0711 +:10941C0002D00BF1010BC3E759F80230002BF8D046 +:10942C0049F802A0B1FA81F1D9E93442490900683E +:10943C0049011A448442C9F8D420C9F8E01028BF65 +:10944C0082420CD24846414602F0F6FC99F8FE00E6 +:10945C000028DED01FF05EFD18BF8862D9E720F02F +:10946C00C5F9D9F8C820D9F8C010019B81F810A013 +:10947C0022B113465269002AFBD114331960C9F882 +:10948C00D4A04A69C1F814A0D9F8E01000294FF013 +:10949C00DC01C9F8C02008BFD82159F80110C9F85F +:1094AC00D01020F05EFCD9F8C00058B148464146B7 +:1094BC0002F0C2FC99F8FE0050B11FF02BFD18BF52 +:1094CC00886205E0D8F80000416A21F0030141628E +:1094DC00029820F02BFD9CE7D9F8C0203AB103216B +:1094EC001174BDE8FE4F0EF0E7BFBDE8FE8F486873 +:1094FC0020F002004860486A20F003004862D8E976 +:10950C0004021043D9F8CC2052681268D062C2F819 +:10951C000405486920F001004861012008624046BA +:10952C00BDE8FE4F1DF0F1BD70B58CB004460020B7 +:10953C008DF82C00CDE906000890A078411E052975 +:10954C0025D82220DFE801F00321212C23036248D7 +:10955C00007820BB20F058FA40B9604DA168082271 +:10956C0005F118001FF06CFF208828805C480078FB +:10957C00022814D1A0680DF1030101AA10F0E2F841 +:10958C009DF8140038B1B1206CE01B2008E0B3202A +:10959C008DF82C0059E09DF803000028F3D023200F +:1095AC008DF81C000120A17B8DF81A0020888DF805 +:1095BC001D102169ADF81800607B0891012804BFCB +:1095CC0021208DF81A0006A805F050FE9DF82C00FD +:1095DC00D8BB0998456C05202870A0786870A81C29 +:1095EC00616819B110221FF02BFF04E00021C1604B +:1095FC00816041600160A078062801D0012803D168 +:10960C00E078A874133500E01235A16828461FF0E5 +:10961C00DEFFA17805F1080006290AD8012202FA1A +:10962C0001F111F0520F04D02E49096820F011FC01 +:10963C0001E0217B017020881AF078FB10B10998A9 +:10964C000421C1829DF82C0070B12348007838B9F0 +:10965C0020F0DAF920B921480021C0E90611018077 +:10966C009DF82C000CB070BDA078042814D1A06813 +:10967C0001AD0DF103012A4610F064F806469DF881 +:10968C00030018B94FF6FF708642DED0206968B12E +:10969C0006A80DF0C7FF0CE0206918B106A80DF064 +:1096AC00C1FFD2E706A818F0A9FFCEE706A818F06C +:1096BC00A5FFA16805F1080008221FF0C1FE0120DA +:1096CC00314614222B46ADF814000020CDE90100E0 +:1096DC0004201CF0B3FFB8E72426002050240020FF +:1096EC00BC270020EC580020F8B5634E01211D4624 +:1096FC001446F068C0680170604800210170604831 +:10970C000170B068016C096811B9D0F84C0580473C +:10971C005C48076847B15C4822462B464188B068D4 +:10972C00006C00680C30B84715F0E24F14D0574865 +:10973C000178013901705448406818B15448C18906 +:10974C000131C181B068006C006840680078800607 +:10975C006FD41AF02FF86FE020070CD44A484068F9 +:10976C0018B14B48C1890131C18148480178013990 +:10977C0001701D205EE0454C42F205422078013814 +:10978C0020704448418841F00400904218D13E4872 +:10979C00406818B13E48C2890132C2813C484289B6 +:1097AC000132428142F20542E120914208BF1C2065 +:1097BC0008F0ACFF207800284AD094F9000040E073 +:1097CC00314842F606024188914212D0B1F5105F41 +:1097DC0049D140693349086019F0B0FA2E48007835 +:1097EC0050B32F480168013138BF0160002101815D +:1097FC0022E0406818B12648C1890131C181264850 +:10980C000078C8B12548042100780228204808BFF8 +:10981C000621425A0132425221484168013138BF77 +:10982C0041600189428901318BB20181934288BF29 +:10983C004181E92008F06AFF1448017841B190F9A0 +:10984C00000000280ADCB068D0F84C05804705E021 +:10985C00B0680021D0F8582400209047F06800210F +:10986C00C0680170F8BD406800283FF482AF08481A +:10987C00C1890131C1817CE70C0100202725002022 +:10988C00B327002054B50200C07700202925002002 +:10989C00AC780020B87500202C250020AA7A002076 +:1098AC0064790020487A0020FEB504462C2020F074 +:1098BC0025FB002820614BD02C2120F029FA2569AA +:1098CC0020884FF6FF760DF10301AE8211F0F2F90C +:1098DC0048B30DF1030069461EF01EFFBDF80020D1 +:1098EC00B24220D0584902EB4200AA8206226A8278 +:1098FC00002251F820302A744FF47A72AB6151F87F +:10990C0020300133B3FBF2F541F8203005FB123265 +:10991C004AB901EB8000012101724C484FF40061FF +:10992C00007814F0EDFB21692088083111F0C2F9A0 +:10993C001FF0CEFC256970B1022028744FF4D000C2 +:10994C00C5F8120042480168A9610131016021E0AB +:10995C0010202075FEBDA88AB0421BD13D4F05F1E9 +:10996C00080039681DF0F3FF58B93D681FF0BEFAC6 +:10997C00014628461DF0EBFF18B91FF0A9FC002882 +:10998C005FD02169208802F00DFB256900B1AE8201 +:10999C0000202874A88AB04231D12F48C17A11BB5B +:1099AC0090F8410001281ED10DF10B02002001217D +:1099BC003A2301271EF03AFC08B1AE8213E09DF861 +:1099CC000B002F74A8754FF46810C5F812002348CB +:1099DC0001684A1CA961026029B91C484FF4007146 +:1099EC00007814F08DFB2569A88AB04207D1A1201C +:1099FC002075284620F080FA00202061FEBD287CCE +:109A0C00012801D10E210CE0A06808B10D2108E05D +:109A1C001FF05EFC0D2118B9A078C00708BF052106 +:109A2C0025692977A1780C4801F00301007B0129F5 +:109A3C0008BF05206870C0B21FF052FD216948773D +:109A4C00FEBD2569A6E700BF307500209D7A002079 +:109A5C0008270020EC580020A86D002018250020B5 +:109A6C00F0B587B0624C054694F82B0028B9614FCD +:109A7C000421387819F0A0FC30B35F48407808BB5B +:109A8C005E480078022803D194F82B00800619D484 +:109A9C0094F82E0005F0C60668B1A8070BD594F80B +:109AAC002B00C00607D41EF04EFB04200121FAF750 +:109ABC009FFE86F0020694F82B1006F03F00084338 +:109ACC0084F82B0007B0F0BD94F82B0005F00606C7 +:109ADC002178304384F82B0051B1E0B34648002183 +:109AEC0001703878042107B0BDE8F04014F008BBD1 +:109AFC00012004F12E0300210122207055201FF0BB +:109B0C0035FB94F82E0080B33C48007801380128CE +:109B1C0009D83B4D0021082228681FF0FFF810B926 +:109B2C001FF0D6FB20B334480721017094F82B00AA +:109B3C000021304340F0100084F82B00002005F089 +:109B4C0027F80028BED000201DF02CF9072000219A +:109B5C00FAF74EFEB6E728480721017007200021CE +:109B6C0007B0BDE8F040FAF743BE94F82B00B4E719 +:109B7C0028680DF11B0101AA0FF0E4FD05462148F0 +:109B8C0000780028CFD09DF81400FD28CBD00228F7 +:109B9C00C9D01D480088854217D201AE1421304629 +:109BAC0020F0B6F8FF202946142233468DF8140015 +:109BBC0004201CF043FD154905EB4500002241F83B +:109BCC00202001EB800042724260002555200121CB +:109BDC0004F82E5F22461FF071FFFF20032119F0BD +:109BEC0051FF054804210570387814F089FA69E7AB +:109BFC00AC220020A37A00200C7A0020242600201E +:109C0C00EC580020BA270020C0BA0200F033002024 +:109C1C002DE9F04788B00646109C0020DD099A46D5 +:109C2C001746C3F3C308E060A06060602060E9B130 +:109C3C00E9462146102248461FF002FC20463146D8 +:109C4C0010221FF0FDFB484620F0A3F8002010283E +:109C5C0005D0315C225C514021540130F7E70AF108 +:109C6C00800A1FFA8AF04FEA102901E04FEA1A29FC +:109C7C006E46280418D0304621461022013D1FF0B4 +:109C8C00DFFB2046394610221FF0DAFB304620F06D +:109C9C0080F80020102805D0395C225C51402154FA +:109CAC000130F7E70744E4E7B8F1000F25D0684628 +:109CBC00214610221FF0C4FBB8F10E0F40D3002533 +:109CCC00204639464246E560A560656025601FF078 +:109CDC00B7FB80202146102204F8080004AE304661 +:109CEC001FF0AEFB684620F054F8102D48D0705D84 +:109CFC00615D484060550135F7E76E4621461022FC +:109D0C0030461FF09DFB002780201FF04BFF2146A3 +:109D1C001022C4F80170C4F80570C4F80970677398 +:109D2C00207004AD28461FF08BFB304620F031F834 +:109D3C00102F42D0E85DE15D4840E0550137F7E770 +:109D4C000026204639464246A681A66066602660FB +:109D5C001FF076FB80202146102204F808001FF02B +:109D6C0021FF04AD28461FF06BFB684620F011F86C +:109D7C00102E22D0A85DA15D4840A0550136F7E712 +:109D8C006F462146102238461FF05AFB00253046FC +:109D9C00214610221FF006FF25606560A560A58195 +:109DAC001FF04EFB38461FF0F4FF102D05D0705DF0 +:109DBC00615D484060550135F7E708B0BDE8F087B4 +:109DCC002DE9F04F8BB0DFF8A0810446D8F80800DD +:109DDC00D0F80001807AC00020F090F8002809909B +:109DEC0000F0B6800DF1040A0AF103071FF0FEFC27 +:109DFC004FF00009FF2600250090D8F80800EAB2C1 +:109E0C00D0F80011CB7A9A422AD2D0F88824D020EC +:109E1C0051468DF80650ADF804409047F0B99DF8C6 +:109E2C00100020B1012819D19DF80F1001E09DF808 +:109E3C000B1099B100284FF0080008BF0420002136 +:109E4C00814202D27E540131FAE707F80090D8F82B +:109E5C0008005146D0F89424D02090470135CCE727 +:109E6C004FF6FF7701AE0DF1140A4FF0FF3B4FF0A8 +:109E7C000009C9885FFA89F291426BD9ADF80620C6 +:109E8C00D0F88824D1203146ADF80440904730B149 +:109E9C00D8F8080009F10109D0F80011E9E7BDF87C +:109EAC000800B842F4D0ADF81400D8F808005146B8 +:109EBC00D0F88824D4209047002841D10025D8F828 +:109ECC000820D2F80001C1888D4216D2D2F888241D +:109EDC00D1203146ADF80650ADF80440904728B972 +:109EEC00BDF81400BDF80810814201D00135E6E739 +:109EFC00D8F80800D0F80001C1888D42C8D1CDE94E +:109F0C0007BB099AADF81A70ADF81870807AC100C9 +:109F1C000020814214D0131808309B88A342F8D13A +:109F2C001118002241F8082C09990844514620F8D0 +:109F3C00047CD8F80800D0F89424D4209047A7E7E4 +:109F4C0000981FF00EFF09981FF0D6FF192008E0AB +:109F5C001A2006E000981FF004FF09981FF0CCFFB0 +:109F6C0000200BB0BDE8F08F0C010020FEB50C46B4 +:109F7C0014F036FFA00600F18280200400F1AF80BF +:109F8C00E00607D52E208DF8040060481FF0AFFEC8 +:109F9C0001A88847E00707D025208DF804005B480E +:109FAC001FF0A5FE01A88847A00707D526208DF82D +:109FBC00040056481FF09BFE01A88847600707D590 +:109FCC0027208DF8040051481FF091FE01A8884706 +:109FDC00200707D529208DF804004C481FF087FE78 +:109FEC0001A88847600607D52D20ADF80400474826 +:109FFC001FF07DFE01A88847200607D53020ADF85C +:10A00C00040042481FF073FE01A88847E00507D5FD +:10A01C003520ADF804003D481FF069FE01A88847C3 +:10A02C00200505D53720ADF8040001A81FF0D2FF9C +:10A03C00E00405D53820ADF8040001A81FF0CAFFD4 +:10A04C00324CA068D0F898000068B0B11FF0CEFB7D +:10A05C00A168D1F898100A68029200220A601FF0D9 +:10A06C0080FEA068D0F8981002984860A168D1F8DA +:10A07C0040138847A0681FF031FC0020FEBD234E22 +:10A08C0002ADB068C06B04301DF006F800280290D9 +:10A09C003FF473AF1FF0AAFBB168C96B0A7B013A9E +:10A0AC000A731FF05EFEB1680298D1F89810077819 +:10A0BC0048608DF80470417839B1162F0BD1B06817 +:10A0CC00D0F8541328468847DBE7B168D1F8401321 +:10A0DC008847162FD5D0B0681FF000FCD1E70B4D88 +:10A0EC00A868D0F89400007814F0DCFC00280290EA +:10A0FC003FF446AFA968D1F898104860A968D1F828 +:10A10C0040138847A8681FF0E9FBE9E70C01002021 +:10A11C002DE9F04706680446307B022812D196F8E8 +:10A12C0023006568D6E904A79146884680B1B168DA +:10A13C0058481FF07DFD40B100206FF0010786F8F4 +:10A14C00250055E06FF0060752E0012086F8260046 +:10A15C00002052492246F0614F48C6F8008086F82C +:10A16C0021901EF0AFFD297827201EF043F85046B1 +:10A17C003946062209F080FA58B196F8260098B3B1 +:10A18C0044481FF0CDFE002086F8260086F82500F6 +:10A19C002AE0434D434FD5F8800320F00200C5F868 +:10A1AC00800396F82000042804D157F84C0C416920 +:10A1BC00272088470220C5F8FC0238684168062031 +:10A1CC008847C0B1402028608020286096F826007F +:10A1DC0038B130481FF0A4FE002086F8260086F81F +:10A1EC0025000020C5F8FC024FF0FF30F061F76944 +:10A1FC003846BDE8F0870220BA461BF057FA002714 +:10A20C00B9F1020F0AD0B9F1040F4FF0000006D0DB +:10A21C00B9F1060018BF0120800000E00020C5F84D +:10A22C004C010123D8F80C10D8E90102C5F85011E3 +:10A23C00C5F8547186F82430DAF800301D690B46E5 +:10A24C00A847256895F8200002281BD00428CFD1F8 +:10A25C00DAF80000816915488847B0F1FF3FDCBF90 +:10A26C004FF0FF30E8610020EF6985F8240095F885 +:10A27C0021100339022928BF85F82500204619F042 +:10A28C0059FCB5E708484FF0FF311FF0D1FCEF69DE +:10A29C00AEE700BF98700020CC76002079C7010093 +:10A2AC0004440240FC010010E87000200100008012 +:10A2BC002DE9F0415A4E04465A4DB068D0F8D410EE +:10A2CC0091F88380297819B1D0F84C058047B06893 +:10A2DC00016C096811B9D0F84C058047524F012028 +:10A2EC00062C3C7028701ED8DFE804F004042225EC +:10A2FC002B5140004E4800214170B068026CD0F8E0 +:10A30C00D41010684B4AC08A40064FF04E0058BF1C +:10A31C002520085C107014BBC97801B3022828BF33 +:10A32C00022010701BE0B068D0F84C0580472EE07E +:10A33C0018F0C4FC2BE03E480021417017F0C8FF18 +:10A34C0025E03A4800213A4A0170B068006C006878 +:10A35C0090F8691090F86A0051703649087008F04E +:10A36C00E3FFB068006C006888B940E0B068324A1E +:10A37C00006C016891F86D1011803049006890F8FC +:10A38C006E00002808BF0120087019F0DFFF284874 +:10A39C000078A0B9B268106C016829B9D2F84C05E4 +:10A3AC008047B068006C01684968254A097801F05B +:10A3BC002001117023490068406880780870387853 +:10A3CC00062814D8012101FA00F010F04C0F0ED021 +:10A3DC001FF00CFA0446387802280AD18320287022 +:10A3EC0020461FF0BEFCBDE8F04118F067BDBDE88B +:10A3FC00F0811548017819B9144909780029EDD074 +:10A40C000221B8F1010F297004D10078832808BF0C +:10A41C0015F0E0F82046BDE8F0411FF0A2BC00BFEB +:10A42C000C010020B87A0020BB7A0020B527002050 +:10A43C002D260020B97A0020C6790020BA7A002097 +:10A44C00C47A0020C57A0020B07A0020B37A0020AC +:10A45C002DE9F0438BB0DFF884810C4605460020D3 +:10A46C008DF81300D8F80010002900F0AD80032DF2 +:10A47C0018BF022D03D191F84200904208D15849DF +:10A48C0000201BF081FD3DB1012D03D185240BE093 +:10A49C00002099E0032D0DD10121D8F80000032DE7 +:10A4AC0080F8411003D114B18DF813400DE0002455 +:10A4BC005DB91EE0022D07D1D8F800000CB10221C5 +:10A4CC0000E0012180F841100024D8F8000090F839 +:10A4DC004190B9F1010F0ED190F8431019B1013927 +:10A4EC0080F8431005E090F8481011B1013980F85C +:10A4FC0048104FF0010990F8431049B1426C00F13B +:10A50C002E03074602EB41018A1E00F126010CE0E6 +:10A51C0090F8481000295AD0C26C00F10E0300F1DB +:10A52C00200702EB41018A1E811D1E78158802222C +:10A53C008DF828201CBB17B32A4A127880F84220C9 +:10A54C0003208DF81C007888ADF8200005AC20465F +:10A55C001FF07FFC7878BB7BCDE90054CDE902601D +:10A56C002120B9F1010F08BF2220BA1D08A911F052 +:10A57C0025FE1D481A4900881BF006FD23E0418882 +:10A58C000DF1130448F220020123ADF8201041789C +:10A59C00CDE9004108A917F0C5F8D8F8000090F8EB +:10A5AC00401002290DD1418C48F220020123ADF854 +:10A5BC00201090F821102030CDE9004108A917F0A7 +:10A5CC00B1F815F087FA01200BB0BDE8F0834FF617 +:10A5DC00FF75FF2600210027A9E700BF44270020B4 +:10A5EC00519C020088260020967000202DE9F04F27 +:10A5FC0089B08246129803F0F00403F00F0B002888 +:10A60C0018BF0120103C03920025B4FA84F46409AD +:10A61C002040D4880290107A92886FF39F2400F027 +:10A62C003F0024036FF39F2244EA0060544C104413 +:10A63C0000905248007804AEC2B2ABB2934280F0A4 +:10A64C009580A27801355FFA8AF7974273D08AB267 +:10A65C000195172A6DD3A1F10709384632461FFA26 +:10A66C0089F421460FF084FF9DF81B8008F003004D +:10A67C00022826D1BBF1030F00F27D800398007AEB +:10A68C00DFE80BF0140205109DF8181007E09DF898 +:10A69C001810884215D10398BDF81610C08888424E +:10A6AC0004D00EE00498009981420AD10298002847 +:10A6BC0054D01298002183688289304615F048FFE7 +:10A6CC0060B15FEA48701CD5BDF81E0084421CD9ED +:10A6DC00A9EB000188B21728BDD228E01298808817 +:10A6EC00E0B3129BDA8819689B681A440B781578CA +:10A6FC009D42E6D1013802F1010201F10101F5D1CF +:10A70C002CE01F4C0120607104E03846214616F005 +:10A71C009FF81B4C00200025F7F752FD1748E178F5 +:10A72C0000780131B1FBF0F202FB101A03E0134880 +:10A73C000078134C019D5FFA8AF1C2B251FA80F194 +:10A74C00013991FBF2F303FB121A5FFA8AF149000B +:10A75C0051FA8AF104EB8101898B6DE7039D96E830 +:10A76C001F001FC5002009B0BDE8F08F0399002021 +:10A77C0088810A20F7E70420F5E700BF9B7A0020C8 +:10A78C00B8720020B0B560480021604C016094F8AC +:10A79C003A01032812D002282ED0012840F0AF80B5 +:10A7AC0094F8400111F090F8002084F840015948C9 +:10A7BC00817B0220002908BF06209EE054480168D6 +:10A7CC00B1F5C060C4F82C01B8BFC1F5C060D4F8B5 +:10A7DC001011002900D5494288422ADDD4F8140111 +:10A7EC001CF0CAFDD4F818011CF0D8FDD4F82801CF +:10A7FC001CF0F8FD01201DE0454805681EF040FEE8 +:10A80C00C4F814011EF044FEC4F818011EF048FEF2 +:10A81C00B5F5C061C4F82801C4F8101109D094F83A +:10A82C0030215AB1D4F81401D4F82021D4F82C11C9 +:10A83C000AE0002084F8300106205EE0C4F8240110 +:10A84C00D4E94502C4F82C110223C4F81C010029D8 +:10A85C0001EB410148BF6FF001031944042391FB44 +:10A86C00F3F111440029C4F820110FDD1F2931D355 +:10A87C00D4F824212AB33E28A8BF3E200130292930 +:10A88C00A8BF2921C4F81C010B3909E0D4F82421F4 +:10A89C00032A09D111F1140FD8BF6FF01301153130 +:10A8AC00C4F82011002113E00128D8BF0120013881 +:10A8BC0011F10A0FD8BF6FF00901C4F81C010B315C +:10A8CC0003E03329A8BF33211539C4F82011032123 +:10A8DC00C4F824111CF050FD01201CF071FDD4F8BB +:10A8EC0020011CF05BFDD4F824011CF07BFDA5F2CB +:10A8FC00FF510420032938BF0620C4F83C01BDE8F1 +:10A90C00B04005F04FBC00BF3C500C40D81B0020A1 +:10A91C0008400C4018B802002DE9FE4F074600789D +:10A92C009B468A46029200F00C000C2808D1B8888D +:10A93C00FE211AF0A1F9FE28019008BF012019E0B0 +:10A94C0059480568B878FF2808D01EF009FE40B1B8 +:10A95C00064600781EF0A4F8054603E02DB16E689B +:10A96C0000E00026FE2001900EE0FE2000250026CF +:10A97C00019009E01EF0F4FD002800F092800646DC +:10A98C0000781EF08DF80546002E00F08A80AA682B +:10A99C004AB13178022090474FF6FE7440B10488DA +:10A9AC001FF0AAFA04E0B0684FF6FE7400B14488B8 +:10A9BC0039893078A14211D010B909B900200DE0C5 +:10A9CC0028B14FF6FE72013292B2914206D0A1F537 +:10A9DC0080714FF6013289B2914244D897F80290B7 +:10A9EC00B870387DD7F810803030C0B21CF0A0FCA5 +:10A9FC00B8B304461A20514620707868C4F8020097 +:10AA0C00A01D1DF063FDBBF80100A4F817000C9805 +:10AA1C003A7D397B84F820000E986175A284E06140 +:10AA2C000D986076F878E073307820759BF800000C +:10AA3C00A075788BA08578896082029820820F9807 +:10AA4C0084F82E0032B104F130004146A0621EF0B1 +:10AA5C00F7FC01E00020A06270682146007814F039 +:10AA6C007DFB87F80290387800F00C000C280DD094 +:10AA7C00B8780026FF287FF487AF286800250026C9 +:10AA8C0000283FF481AF466805467DE70199B888F8 +:10AA9C00C9B21AF0F1F8FE280146019001D00198D4 +:10AAAC0068E7BDE8FE8F00BF247A00202DE9FF4740 +:10AABC00D0E901590E4604461EF098FE95F8FD109B +:10AACC0021B97169102901D8032906D81FF049F959 +:10AADC000024204604B0BDE8F087012785F8FD70FE +:10AAEC001FF03FF900204E4A85F8FC00C5E9300004 +:10AAFC00C5F8C80085F8FE003069C5F8E400706937 +:10AB0C00C5F8E800307B85F8F9000028317885F825 +:10AB1C00F8107168C5F8EC10B9F80E10A5F8F6101D +:10AB2C00317E52F8211085F8FA1008BF1027C5F8AD +:10AB3C00F07099F80C000BF0CDF8204616F00EF9D9 +:10AB4C0099F83B00374985F8FB008A46D4E9018720 +:10AB5C003A6B97F83A000DF01FFC7A6B98F8FB00F3 +:10AB6C0051460DF019FC98F8F91097F838000129A6 +:10AB7C0015D1FA6A51460DF00FFCBA6A97F83900F4 +:10AB8C0046F202010DF008FC98F8FB0026491DF076 +:10AB9C0023FB98F8FB0021461EF06CF90AE0BA6A18 +:10ABAC0046F202010DF0F8FBFA6A97F839005146AB +:10ABBC000DF0F2FBE84640461EF0B2FB99F805009A +:10ABCC001A4A4346CDE90040284699F8041018F07B +:10ABDC00C7FA40461EF094FCD9F8080014494246C6 +:10ABEC000094029005F1300019F037FD12F082FE4E +:10ABFC00104AC5F8CC0005F11C00042123461CF0BA +:10AC0C0003FC95F8F80008B1B06805E005F16C009C +:10AC1C0000211DF0AFF80848C5F8BC0059E700BF8B +:10AC2C00B8B7020002600020ED0E01007193000025 +:10AC3C0045110200E19A0200259D02002DE9F84F12 +:10AC4C000CF088FD5F4800254FF0000A0478A542FF +:10AC5C0011D2E8B21BF0DAFE58B1017941F00401CF +:10AC6C00042906D1807A1DF055F9002818BF0AF185 +:10AC7C00010A0135EBE700271BF0B4FC0546002662 +:10AC8C00F8B285420AD91AF0B1F928B1807C1DF0CE +:10AC9C0041F9002818BF01360137F1E706EB0A0924 +:10ACAC005FEA096032D04FF47F7000EA89073846BA +:10ACBC001FF024F950B33946FF2280461EF0D2FF14 +:10ACCC0000275FFA8AFA4FF0000BA7422AD25FFAEC +:10ACDC008BF0504526D2F8B21BF098FEA0B1064678 +:10ACEC00007940F0040004280ED1B07A1DF012F95E +:10ACFC0050B10146727A30885FFA89F3009343466B +:10AD0C0015F00EF80BF1010B0137DEE74FF00008E0 +:10AD1C004FF000092C48007BD8B11EF0E1FBC0F1CC +:10AD2C00540017E000245FFA89F7E0B28542F1D9AC +:10AD3C001AF05CF958B10646807C1DF0EBF830B186 +:10AD4C000146727C30884346009714F0E9FF0134C9 +:10AD5C00EBE76220C1B203224546B1FBF2FABAF12D +:10AD6C001F0F28BF4FF01F0AC0B25FFA89F72A469F +:10AD7C00002818BF0120410101F14004574588BF4C +:10AD8C00440128BF57462146384612F0F4FA0646CD +:10AD9C0014F0400040EA0601A7F1010008BFA9EB3E +:10ADAC000009C0B208BF05EB800500200029DBD0EC +:10ADBC00B8F1000F02D040461FF09EF83046BDE8B7 +:10ADCC00F88F00BFE3BA0200A86D0020FEB5044660 +:10ADDC005A480078A04213D908780D46012801D1B1 +:10ADEC00686868B16878012801D1A86840B1544FEF +:10ADFC0057F834601EF0FAFCF17921B11EF0B1FF66 +:10AE0C0000242046FEBD07EBC40401216768F171E4 +:10AE1C001EF0A7FF002005F1040C7074F081B060E7 +:10AE2C0030602988B180A98BC6E93D00C6E90E00C7 +:10AE3C0086F86400B186297D2B69B1719CE80610F7 +:10AE4C00C6F85021BCF1000FC6E910C34FF0FF3219 +:10AE5C00C6F8CC10A969C6E93B203163A97F86F8F6 +:10AE6C003610296AC6E91A00C6E91C00B16486F8D6 +:10AE7C00E800C6F8580102D13249C6E9101097F81B +:10AE8C0040000AF027FFD7E9031206F14C001EF030 +:10AE9C001FFBD7E9051206F1D0001EF019FB2A4959 +:10AEAC0038680968C96888477A6C97F8240046F2B4 +:10AEBC0002010DF071FA254DBA6C97F82000294665 +:10AECC000DF06AFAF86901280CD1FA6C97F8280091 +:10AEDC0029460DF061FA3A6D97F82C0046F2020102 +:10AEEC000DF05AFA12F006FDC6F85801204605F08E +:10AEFC0079FD174A06F5AE70042123461CF084FA3E +:10AF0C006D4628461EF00CFA387A7968114A2B46A1 +:10AF1C000094019006F1140018F022F906F17C005F +:10AF2C0000211CF027FF06F5807000211CF022FF89 +:10AF3C003868D7E90C121060486062E7C6BA0200A4 +:10AF4C002CBA0200C3730100D00100100260002073 +:10AF5C00AD8F0200D18200002DE9F84F81460868C0 +:10AF6C008B469046D9E90045476806895548E16803 +:10AF7C001EF05EFE18B16FF00100BDE8F88F52486C +:10AF8C0052494FF0000A4A46C4F814B084F80980BC +:10AF9C00C4F804A084F802A01DF094FE29782720A0 +:10AFAC001DF028F938463146062208F065FB40B101 +:10AFBC0044481EF0B5FF4FF0FF3084F801A0BDE807 +:10AFCC00F88F434F57F84C0C416927208847414E66 +:10AFDC000220C6F8FC02386841680620884760B138 +:10AFEC00402030608020306036481EF099FF0020F1 +:10AFFC0060704FF0FF30BDE8F88F02201AF056FB5E +:10B00C003A68DBF810009BF82010D26990473A6838 +:10B01C009BF820009BF821101368A8F10102B2FAEA +:10B02C0082F252099847DBE90610C6F8500100205D +:10B03C00C6F85401C6F8581159B13A68DBF8040047 +:10B04C00002315690022A84738688169224801301D +:10B05C008847207A042804D057F84C0C0169272023 +:10B06C0088473B68DBF81C10DBE902021C690B46C5 +:10B07C00A047D9F8004001206070207A022815D032 +:10B08C0004281BD13868144D816928468847B0F1D3 +:10B09C00FF3FDCBF4FF0FF30606000206070A81CE9 +:10B0AC00C6F88403484610F071FF04E00B484FF0DB +:10B0BC00FF311EF0BDFD6068BDE8F88F0020BDE8D3 +:10B0CC00F88F00BF98700020CC76002051D401007E +:10B0DC00FC0100100444024001000080E8700020D4 +:10B0EC00F0B587B05C4E0446306848B390F8401019 +:10B0FC0001293FD1022180F840102030214612F066 +:10B10C001DFE05463068C169436B90F83220007E05 +:10B11C0016F078FAB5FA85F137684D09002887F8EA +:10B12C00430043D040001EF0E9FE37687864C8B392 +:10B13C0097F843104A0049491EF082F9376835E008 +:10B14C0050201EF0DBFE306050B3502105461EF03F +:10B15C00DFFD2846214612F0F1FD08B330680121CD +:10B16C0080F840103E483F49008807B0BDE8F040E9 +:10B17C001AF00ABF02200DF10F0148F22002012340 +:10B18C008DF8180088208DF80F006088ADF810003D +:10B19C006078CDE9001004A9204616F0C3FA49E006 +:10B1AC0088201CE0882001258DF80F007B69BA7C73 +:10B1BC00F96B97F8380016F025FA316881F84800D9 +:10B1CC0058B140001EF09AFE3168C86430B191F855 +:10B1DC0048104A0021491EF033F96DB386208DF8D2 +:10B1EC000F0002200DF10F0548F2200201238DF80B +:10B1FC0018006088ADF810006078CDE9005004A903 +:10B20C00204616F08FFA306890B190F84010022961 +:10B21C000ED1418848F220020123ADF81010022112 +:10B22C008DF818104178CDE9005104A916F07AFA7E +:10B23C0014F050FC07B0F0BD306890F8431019B909 +:10B24C0090F848000028C9D000200021002207B047 +:10B25C00BDE8F040FFF7FCB8442700202C73002019 +:10B26C0096700020519C020070B5604D0446A86891 +:10B27C004169497F002973D0D0F8D420B4F842102A +:10B28C00D28C91426CD1D0F86C1304F12800884711 +:10B29C00002865D0A868002241694A77D0F8D410FC +:10B2AC0091F8291021B1E868816A02208847A868C2 +:10B2BC00006F90F82B0018B1E868816A012088476C +:10B2CC00207CC00608D5E868816A10208847A868E9 +:10B2DC00D0F8281380208847E868C16B2020884765 +:10B2EC00A868D0F8FC14C068103088476268A86859 +:10B2FC0013785278416902F00F064E76C2F30011B2 +:10B30C004269917603F00F01426991771909D0F8DF +:10B31C00D42082F82C10D0F8D410426991F84F3018 +:10B32C00927F0F2B05D09A4203D26668F67806B945 +:10B33C001A464A730022C16881F83020D0F8D41024 +:10B34C00497B0F290DD14169C97E022908D1D0F85A +:10B35C0064018047A868D0F86C01BDE870400047D4 +:10B36C0070BDD0F80C2520469047A9684869C07E6E +:10B37C00022814D1C868D1F8FC148847AA684FF485 +:10B38C007076D2F8D430D2E90301D2F8F0245B7B8A +:10B39C0031F8131006FA03F3591A9047A968D1F83B +:10B3AC00D400D1F8B431228990F82C10022098479F +:10B3BC00A968D1F8D400427B90F82C0090420FD0B1 +:10B3CC004869D1F8FC148847A8684169D0F87C0119 +:10B3DC008860A868D0F8F024406941699047A96852 +:10B3EC00D1F828131020BDE8704008470C0100204C +:10B3FC002DE9F84F544B554D93F800B000235B45A5 +:10B40C0004D2AC782CB108350133F8E74FF00009C1 +:10B41C0097E04FF000095B4500F093804C4B009295 +:10B42C004D4A4FF0000885F806901E1D494BB2F8A6 +:10B43C0016A04FF6FE721F78012307B336F8044CA2 +:10B44C008C4218BF544503D12436013F5B00F4E70E +:10B45C003478042C03D0012C06D0002CF4D109F143 +:10B46C00010985F80690EFE702F1010CB0F80AE04B +:10B47C001FFA8CF4A64508BF48EA0308E4E7384CE9 +:10B48C00DFF8D4E0354B2678BEF824700A33B6B119 +:10B49C0033F80A4C8C4218BF944202D11C33013E43 +:10B4AC00F5E71C88BC42F9D1DC79002CF6D01C7A6B +:10B4BC00002CF3D009F1010985F80690EEE7294933 +:10B4CC005FFA89F309788B4284BFA9718946009A87 +:10B4DC005FEA096102D0817C012901D1002102E0DF +:10B4EC009EF80210013129719EF801109EF8073068 +:10B4FC00B8F1000F6A71E9708189C07CAB7029804A +:10B50C00E87111D0184D194BBBF1000F0CD01E78FF +:10B51C00284619462EB14B1C051DABF1010B96426A +:10B52C00F2D1C0F800800A70114C4021207817F03D +:10B53C0043FF20B92078402164221EF042FC4FF0DA +:10B54C0001094846BDE8F88FCEBA0200AA6800206F +:10B55C0020450020E3BA0200A86D002030560020E0 +:10B56C00D1BA0200D4BA0200306D00205876002007 +:10B57C009C7A0020F8B50446007D50B15A4994F9E4 +:10B58C001800C968D1F880108847013004BFE82042 +:10B59C00F8BD554EE27BB568D5F80011E86B09781B +:10B5AC000AB1807A00E0C07A81429CBFF120F8BDDC +:10B5BC00636A94F8392094F83810A08DD5F88C5221 +:10B5CC00278C0097A84700285ED0054600202880CD +:10B5DC006868A28DA16A1EF0B7FC04F1300005F179 +:10B5EC0084010CC80CC1028880788870B0680A800D +:10B5FC002146D0F8442505F1900090476089B36846 +:10B60C00A5F89A00207B85F89C00607B85F89D004E +:10B61C00A27DD4F80E00D4F81210D3F84835984710 +:10B62C00A5F89E00E07D85F8A000207E85F8A1009D +:10B63C0094F83C0085F86C00228CA5F8A8202AB35D +:10B64C00E169D5F8A4001EF07FFC1DF0E1FEB5F811 +:10B65C00A800E8B1D5F8A400D0B16868411E6960B3 +:10B66C00F82100F8011C6868411E6960002100F88F +:10B67C00011CB5F8A8006968091A6960A9652989CF +:10B68C0008440230288103E01A20F8BD1DF0C0FEEA +:10B69C00B5F89E10C8051DD594F83B20E8202AB1BA +:10B6AC0011F0040208BF11F0010100D0F8BDB1681F +:10B6BC00486ED1F8FC14884794F83B004FF47A712B +:10B6CC00B268484309490978B0FBF1F1506ED2F8E1 +:10B6DC00F4249047B0682946D0F89400007813F011 +:10B6EC003DFD0020F8BD00BF0C010020B47A002005 +:10B6FC002DE9F84F0446B0F82490C17B008A1EF067 +:10B70C004DF948B9A07B032806D009F1140A1FFA99 +:10B71C008AF0F128C0F09E8009F11E0A1FFA8AF007 +:10B72C00FB280AD309F110001EF0E8FB40B30646D3 +:10B73C0010304FF01E0A706000E000264FF08208B7 +:10B74C004FF0010B1FFA8AF01EF0D8FBB0B1074680 +:10B75C00A078BBF1000F3870E07878702079B87061 +:10B76C006079F8700ED0A07BA11D3871A07B0328E6 +:10B77C0010D1781D08221DF063FE0FE0002E64D15D +:10B78C00BDE8F88FA079FD1D3871E0797871E07B08 +:10B79C00B8710BE0087878714878B871E07B07F1E4 +:10B7AC0010057873207CB873607CF873207D28704A +:10B7BC00607D6870A07DA870607EE870281DE169CE +:10B7CC001EF005FB0020BBF1000F28720FBF05F126 +:10B7DC000A0B4FEA1920A87205F10B0B85F809909A +:10B7EC00CEB11F481F4D4FF47A72016831600F21A2 +:10B7FC0006602878317308211EF0E6FA18B1287813 +:10B80C00082112F07DFCE069A16A4A46B0607068BC +:10B81C001DF016FE05E0A16A58464A461DF010FEC2 +:10B82C00CB4494F82C005FFA8AF241463B468BF8E5 +:10B83C00000094F82D008BF8010094F82E008BF882 +:10B84C000200442016F09AFF3E463046BDE8F84F01 +:10B85C001EF052BB4FF0000B4FF08108002671E731 +:10B86C00682600209A7A00207CB5594D594E4CF62A +:10B87C00C0722B78347883F0010384F002042343E4 +:10B88C00554C08BF104000295349898C0CBF21EA44 +:10B89C000000084301B2A084B1F1FF3F08DC012095 +:10B8AC000DF103018DF80300522016F067FCA08CFB +:10B8BC0081046BD401B2B1F1FF3F2ADD010465D0E4 +:10B8CC004FF0FF310191317802295FD1297800299D +:10B8DC005CD121682346013101A908BF0B46C20780 +:10B8EC0008BF0B4622461D6852F8046FB54298BF3C +:10B8FC001A46050758BF1A46C30606D525461368CF +:10B90C0055F8086FB34288BF2A46830607D41346FE +:10B91C000CE080B2400439D504F110003EE023461F +:10B92C00156853F80C6FB54298BF1346420401D406 +:10B93C001A4606E022461D6852F8106FB54298BFB1 +:10B94C001A46C30401D4134606E02346156853F87F +:10B95C00146FB54298BF1346820701D41A4606E00D +:10B96C0022461D6852F8186FB54298BF1A46400718 +:10B97C0001D4104606E02046136850F81C5FAB4219 +:10B98C0098BF1046884218BF002807D1002001211B +:10B99C0020621248007814F01FF87CBD226A0168FE +:10B9AC0012B11268914211D00C4D206201292878F5 +:10B9BC0003D1012112F0A4FB7CBD012114F00CF881 +:10B9CC00216A28780A6801211EF0FBF97CBD00BFB2 +:10B9DC00E527002024260020087500209C7A0020F2 +:10B9EC00F8B5554F554E564D38883168EC8808449B +:10B9FC00224600F10801A868806D1EF0A5FAA9681E +:10BA0C003888504B8A6D2044388022448A653268CD +:10BA1C0081B20832565C811C398089B2515C197034 +:10BA2C00C11C0730398089B2515838806846009162 +:10BA3C0004211AF09DFE00901CF08EFDA968C863CD +:10BA4C0000981CF027FAA968A1F840003E4800783D +:10BA5C0018B11EF025FAA968C863EA2019F074F928 +:10BA6C003A48426812B1A86801219047384802212F +:10BA7C00384C0170E0684069007830B1A87B8009CF +:10BA8C0017F08CFB08B10120A870A968A8780A7C73 +:10BA9C00002870B218BF42F0040200270A7400217B +:10BAAC001AF0F9FE0146A86880F8461000F17401FE +:10BABC00B0F85C2080F8486080F847708165018997 +:10BACC00511A426811444160417B890709D5A1682C +:10BADC00D1F808138847A868416E11B1B0F8681006 +:10BAEC00F1B190F8601049B1A168D1F80C138847F6 +:10BAFC00A868C16C11B1B0F8501089B1A168D1F827 +:10BB0C00B820137823B1926C12B19047A868A16841 +:10BB1C00D1F8581288470020A8601CF07FFDF8BDB2 +:10BB2C00A068D0F8541205F1080088470020A860DE +:10BB3C0010F05CFCF8BD00BFBE780020D879002066 +:10BB4C0034250020B57A00209427002054B502003B +:10BB5C00B07A00200C0100202DE9F84FD0E90054F8 +:10BB6C00994616468A46834613B10020C9F8000050 +:10BB7C0076B11DF03BFE0746E87968B195F8E80010 +:10BB8C0088B138461EF0EDF86FF00800BDE8F88F6C +:10BB9C006FF00900BDE8F88F38461EF0E2F86FF040 +:10BBAC000E00BDE8F88F0020012105F58078C5E96D +:10BBBC003BA6C5F8F460C5F8FC0085F8E810E8630E +:10BBCC006873E872404600211EF032F820461DF0E2 +:10BBDC00FDFE38461EF0C5F81DF069F808B9687905 +:10BBEC00C0B395F84400C00606D52C6C24B1AB6CE0 +:10BBFC00584610210022A0471DF0F8FD0446584677 +:10BC0C0009F0ECF820461EF0ACF8687960B90A9996 +:10BC1C0040461EF00DF808B10120687358460EF02E +:10BC2C0027FA002085F8E800B9F1000F1CBFD5F801 +:10BC3C00FC00C9F80000E87A28B10020E8726FF027 +:10BC4C000D00BDE8F88F687B002818BF6FF00C0062 +:10BC5C00BDE8F88FDBE9005495F84400C00614D514 +:10BC6C002F6CAB6C584610210022B8470DE0D5F86C +:10BC7C00FC0031460AEB0002204618F047FFD5F8CD +:10BC8C00FC10361A0144C5F8FC10002EEFD12046EA +:10BC9C001DF056FC0028FAD020461DF08BFE95F8BE +:10BCAC004400800605D52C6CAB6C58462021002234 +:10BCBC00A0470020B9F1000F85F8E800C8D0D5F8EE +:10BCCC00FC00C9F800000020BDE8F88F2DE9FF4703 +:10BCDC0015460F46814639B138461EF039F818B171 +:10BCEC000446A5F1010A4EE04A48A0F124014A4855 +:10BCFC000678701C01386DD001F1240491F82810DD +:10BD0C00FF292146F6D1002C64D0E81EC0B20128D0 +:10BD1C000DD84248B0F80080B8F1000F07D00320CE +:10BD2C00042117F05BFFA6EB080181426FDDA5F142 +:10BD3C00010A5FFA8AF001280DD83948B0F8008062 +:10BD4C00B8F1000F07D00120022117F047FFA6EB36 +:10BD5C00080181425BDD0120E8463946ADF80290CE +:10BD6C008DF8000008F104001DF031FC404605F090 +:10BD7C007FFE0020A071BDF80C0060802948818CEA +:10BD8C0048461AF092F84AF6012100202571A4F8D1 +:10BD9C000090A4F8091080212082E060E072E0712C +:10BDAC0084F82110204909780131490821725FFA81 +:10BDBC008AF1042938BF01208000012960710BD859 +:10BDCC001A48007858B11A4951F82000C0EB0010FD +:10BDDC00800006E0002409E06FF0010004E0144844 +:10BDEC000068012184F82010A061E061002004218A +:10BDFC00002517F0F3FE08490978884224BF0D4846 +:10BE0C00057008F0B1FD204604B0BDE8F0870024B1 +:10BE1C00F9E700BF20450020E3BA0200BABA0200DD +:10BE2C00BCBA0200A86D0020CDBA0200D8270020B1 +:10BE3C0090B40200972700202DE9FC4FD0F8C08069 +:10BE4C00D0F8D0C0D0F8E820D8F80030C346E64689 +:10BE5C009C4511D3D8F814B0BBF1000F00F08980C9 +:10BE6C0090F8FC3005244FF0000E002B08BF012485 +:10BE7C00DBF800308BF81040A3EB0E05A2F1080A9A +:10BE8C00B5F5806F28BF4FF48065D0F8D82032B15B +:10BE9C0001F1200301F12402C0F8DC5005E0C0F8E8 +:10BEAC00D85001F1180301F11C020026BAF1000F61 +:10BEBC00C8BF0126DBF8044012681F68CDF800E00B +:10BECC007CB1354B53F82630BB6005FA06F30126DE +:10BEDC00BAF1000FC8BF02260EFB06332344013B08 +:10BEEC0005E02E4B53F82630BB6000F1F6033B60A7 +:10BEFC0043F6F0740191D1F8009004EB051626403E +:10BF0C0009F1080EC7F804E0BC683443BC60002497 +:10BF1C00BAF1000FC8BF0124DBF808709FB161466D +:10BF2C00DFF87CC05CF824308C46936005FA04F38F +:10BF3C000124BAF1000FC8BF0224009901FB04319F +:10BF4C0039444C1E05E0154951F8241000F1F40455 +:10BF5C0091605460C2F800E0916831439160C34530 +:10BF6C0004BF05EB0C01C0F8D01090F8FE10019A3C +:10BF7C0009B1BDE8FC8FD9F8241041F00301C9F8D0 +:10BF8C002410D0F8CC00D2E90412406811430068A8 +:10BF9C008162BDE8FC8F00BFA0B70200A8B7020009 +:10BFAC00B0B70200F0B58BB0ADF80A00002001F17B +:10BFBC0008070C468DF8080038461CF079F808B3D1 +:10BFCC0006AE0DF10701384632460DF0BBFB0546B7 +:10BFDC004FF6FF7085421FD09DF8070000B39DF807 +:10BFEC002800002844D0FF280AD0022848D0FD2879 +:10BFFC0006D001284DD13F4800780138012844D99A +:10C00C003E4844E002A80DF029F8012802D102A80C +:10C01C0018F010FCA1205AE03848C4F8120055E082 +:10C02C0006F10800394608221DF00AFA40F2FF100A +:10C03C00ADF828001DF0E8FD00F00F0000272946A0 +:10C04C00142233468DF82A000420CDE906771AF025 +:10C05C00F5FA2B4905EB450041F8207001EB800007 +:10C06C002649C0E90177C4F812100121417210E091 +:10C07C00052060829DF82B0000F07F00A08208E074 +:10C08C001C480078411E022923D24FF08170C4F85D +:10C09C0012001B4A05EB4501002052F821305D1CB3 +:10C0AC0042F82150A3610A232074B5FBF3F303EB90 +:10C0BC008303A5EB430353B902EB81000121017209 +:10C0CC0010484FF48061007812F01AF800200BB081 +:10C0DC00F0BD30B90848C4F812009DF82A0084F865 +:10C0EC00280004F11E0006F1080108221DF0A8F931 +:10C0FC00CFE700BF2426002000000101000003014F +:10C10C00F03300209D7A0020F8B50D46417F04469F +:10C11C00827F1020002908BF082060700AB1083007 +:10C12C006070217F09B101306070A17921B1217A51 +:10C13C0000EB410002306070267E4749002E18BF8C +:10C14C000E26097802290BD142490978012907D119 +:10C15C002178012904D04149097809B1012100E075 +:10C16C00002184F83410217D314408442870217E4C +:10C17C0031B13B48007B1DF0B3F929780844287095 +:10C18C00C0B274283DD81DF0B9FED0B30546344872 +:10C19C002178677E237F94F806C094F818E0627FBC +:10C1AC00807C002B41EA800007F00301A77F40EA66 +:10C1BC00811094F83410287018BF012340EA032032 +:10C1CC0040EA4E2040EAC22040EA073040EA8C2088 +:10C1DC0040EA4130000A6870A078A870E078E870F6 +:10C1EC002079287160796871A07EA871E07EE87171 +:10C1FC00607F40B1216A05F108001DF02AFE10276E +:10C20C0002E0002523E00827A07F20B1616AE8192D +:10C21C001DF01FFE0837A07970B1207AE855E81997 +:10C22C000237617A4170E819227AE16852001DF0F8 +:10C23C0007F9207A07EB4007207F08B1F9B2685460 +:10C24C006078227D2169284430441DF0F9F8284695 +:10C25C00F8BD00BFCA27002024260020DC270020C0 +:10C26C00A86D00202DE9F04F85B007468A46581876 +:10C27C00D7F80880D8F80410884202D96FF003056B +:10C28C007BE04E4D7C68DDF838904FF0FF319B46DB +:10C29C00164628681DF0CCFC6068B8F82010C5E97B +:10C2AC0001015FEAC97014D15FEA897023D5D8F80F +:10C2BC000C0000287AD0D8F81010002976D0012272 +:10C2CC008DE80700384651465B46324613F0D2F8EB +:10C2DC000EE0A068C14300EA0B0211EA0B0F1CBF71 +:10C2EC00D8F808100A4400EA0A01384606F0FEFDA8 +:10C2FC0008B105463DE0D8F800005C46354603968B +:10C30C0000EB0A09ECB3384612F0E0FC78BB384677 +:10C31C0019F07CFB58BB02208DF813908DF810009F +:10C32C004FEA19208DF812004FEA19408DF81100D0 +:10C33C002248018938461CF036FF5FFA89F0C0F5B7 +:10C34C008076B44238BF264604A8042113F094FC2E +:10C35C0068B92846314613F08FFC40B91748A41B26 +:10C36C00B144018938461CF027FF3544CAE74FF029 +:10C37C00FF35124800681DF0D3FD284605B0BDE816 +:10C38C00F08F0E98400701D40025F2E7D8F80C0086 +:10C39C0060B1D8F8101049B100228DE8070038467A +:10C3AC0051465B46039A13F065F8A2E70348006810 +:10C3BC001DF0B6FD6FF00705DFE700BF0C24002071 +:10C3CC002DE9F0418AB0514F05463878022804D146 +:10C3DC004D480078002800F09480DFF8348198F8FC +:10C3EC002600082802D0042840F08B8007AC284691 +:10C3FC0021461CF009F8387802280BD11CF076FD88 +:10C40C00A11C1BF0A4FA28B1BDF81C601DF024FA85 +:10C41C00864276D01DF084FC0234BDF81C00214607 +:10C42C0008F050FE01286CD06E4630461DF037FCEB +:10C43C00304621461BF08BFA68B1BDF81C601DF02C +:10C44C00F9F9864207D0BDF81C00414621F81A0FB5 +:10C45C004B2015F093FE3878012819D8AD8A1DF0C1 +:10C46C00FBF9854214D020461DF072FC30B10079E6 +:10C47C000138012802D8204612F068FD26480168D0 +:10C48C0031B124480078012802D1BDF81C0088473E +:10C49C00BDF81C00002100261AF011FEB8F824107B +:10C4AC00BDF81C0019F001FDBDF81C008DF80C60E6 +:10C4BC00ADF80E0003AD28460CF0D0FD70B1CDE9FF +:10C4CC0000662E1D684631461BF041FA30B13046ED +:10C4DC0021461DF07CF803A805F0CAFA281D214658 +:10C4EC001DF075F828460FF0CDF850B1BDF81C00C2 +:10C4FC00BDF80E10814204D0ADF80E0003A805F073 +:10C50C00B7FA0AB0BDE8F081E52700202426002008 +:10C51C00A86D0020CA270020982300202DE9F047A1 +:10C52C00012816D1DFF830A1DAF83401012813D133 +:10C53C000220CAF8340119F0C1FD0120012419F0C0 +:10C54C00F5FA60B1CAF834411BF094FB4FF0FF349C +:10C55C007FE06FF001047CE06FF0040479E09AF85E +:10C56C005A419AF859119AF85801002C18BF012415 +:10C57C00002918BF0234002818BF043401201DF014 +:10C58C00DDF9013818BF01209AF83811B1FA81F1A0 +:10C59C00490910EA010902D1002007F03DF9DAF847 +:10C5AC0008002E4D10F0010807D12D4F286A816824 +:10C5BC00384688470428F9D0064640461DF029FB2A +:10C5CC00B8F1000F08D1012E04D1286A012142686C +:10C5DC00234890471CF04CFF286841692046884747 +:10C5EC009AF8540118B14FF480601DF0ADF99AF827 +:10C5FC00530118B14FF481601DF0A6F919480121BF +:10C60C00016003200021CAF834011748016020465C +:10C61C0015F0FAFB0128FAD1144E3068042019F0F9 +:10C62C0085FA044612480125B9F1000F05603068FF +:10C63C0002D1012007F0F0F81DF039FB082019F0A9 +:10C64C0075FA0443CAF8345118BF4FF0FF341BF08D +:10C65C0011FB2046BDE8F087D81B0020B801001064 +:10C66C0000400340282008600C2008402C20094082 +:10C67C000C4009407CB54B4EB068016CD0F8D4200E +:10C68C00096892F8835019B9D0F84C058047B06806 +:10C69C00D0F8B800007800B315F01AFE43494248B0 +:10C6AC0009680068096C884705461DF09FF8044628 +:10C6BC003F48017811B93F49097821B33E4902221C +:10C6CC000A700078832808BF12F084FF1DF064FB09 +:10C6DC001DF06DFA0420884757E01DF087F80446DA +:10C6EC003348017811B933490978C9B30222324968 +:10C6FC00012D0A7004D10078832808BF12F06AFF5C +:10C70C001DF04AFB41E01DF052FA00208847B0684A +:10C71C000DF10701D0F82824F42090479DF907006B +:10C72C00854223DB254D287800BB1DF035FB2548C1 +:10C73C000078042803D0B068D0F84C0580471E4818 +:10C74C00042101702878013028701DF030FA09B1ED +:10C75C00032088471C48032101801DF01DFC14E0B8 +:10C76C001548832101701DF017FB0CE01248832142 +:10C77C000170002017F022FE1DF00EFB1048F1682E +:10C78C0080780969087016F099FBF068C068007829 +:10C79C0000B17CBDB0680021D0F85824002090472F +:10C7AC007CBD00BF0C010020E4260020347A002060 +:10C7BC00B07A0020B37A0020B87A0020B527002088 +:10C7CC002D260020BB7A0020C67900202DE9F84FD9 +:10C7DC00494C1021207816F0EFFD28B92078102153 +:10C7EC004FF47A721DF0EDFA44480178013901706A +:10C7FC0009065AD043484FF000084FF6FE79002640 +:10C80C00041D41480578AE421DD22078C0B1FF28E6 +:10C81C0016D001382070000612D16078032807D199 +:10C82C0034F8041C34F8020C022211F031F8607850 +:10C83C0001281EBFA4F8018024F8029C24F8049C53 +:10C84C0008340136DFE73148DFF8C4A0314C4FF033 +:10C85C000008002790F800B05F4519D007EB87005F +:10C86C000AEB4005287A0138287200060ED12046C2 +:10C87C00294619F0A3F9064610B1304619F09CFE72 +:10C88C00002EF4D185F80080A5F802900137E3E77B +:10C89C0021482249007830B10A780AB1013A0A706D +:10C8AC0008310138F7E7BDE8F88F154900220978FF +:10C8BC000170002005211AF001FB04460626002C0D +:10C8CC0098D020460521002225461AF0F7FA044696 +:10C8DC0028890028F3D0013828810004EFD1688919 +:10C8EC00400702D5287B18F029FF2868F0216E73C9 +:10C8FC00407B15F037F8E2E79C7A00202F79002076 +:10C90C00DCBA02004C500020D6BA0200D5BA0200A4 +:10C91C00B25C0020AF1B0200D7BA0200503D0020D1 +:10C92C002DE9F04F85B006464D48DFF83C91144692 +:10C93C000D464FF6FE774FF6FE7800780190494889 +:10C94C00007804900120029000200390474800F1E9 +:10C95C00110B47480430009099F800C04FF0000EBE +:10C96C000020C00774D1049B5946C14603B331F86B +:10C97C00118CB84518BFB04502D11C31013BF5E70D +:10C98C00A84518BFA045F8D00A78501E0628F4D840 +:10C99C00072A01D1C146F0E702980EF1010EC0073B +:10C9AC00EBD103985FFA8EF2C0B28242E5D351E02C +:10C9BC00BCF1010F2AD8DDE9001ABAF1000F25D01D +:10C9CC0031F8048CB84518BFB04503D12431AAF115 +:10C9DC00010AF2E7A84518BFA045F7D04B79581EBD +:10C9EC000628F3D8087801380228EFD3072B01D199 +:10C9FC00C146EBE702980EF1010EC007E6D1039891 +:10CA0C005FFA8EF2C0B28242E0D323E0C8465FEAFE +:10CA1C000E6002D00398000603D00120B845A0D0C8 +:10CA2C0018E000205FFA8EFADFF83C9002900120AB +:10CA3C00BAF1010F03903FF48FAF1DF0E5F8C0B2CF +:10CA4C00B0FBFAF101FB1A0003900020029083E77F +:10CA5C004FF6FE781FFA88F005B0BDE8F08F00BFE6 +:10CA6C00E3BA0200D1BA020024260020305600207E +:10CA7C00204500202DE9F04395B0044600208DF8A8 +:10CA8C001F00208817F052F9002840F081804B4895 +:10CA9C00007810B14FF0B30908E0A078042803D156 +:10CAAC001CF016FC002876D04FF0B60900261E208C +:10CABC001AF03EFC0546BEB303209DF852108DF8CB +:10CACC001E0010A808AF08303A4610F077FF0CAEE5 +:10CADC000DF11E0008213A46334612F097FBA06870 +:10CAEC00314610221BF0F6FBE0B11FFA88F702AEBC +:10CAFC000420002214233946009619F089FD9DF973 +:10CB0C001B00B0F1FF3F03DC06F1130017F02EF809 +:10CB1C000220394614228DF8180002AB042019F0BB +:10CB2C008DFD01E04FF0AD09B9F1000F17D09DF864 +:10CB3C001F00012813D19DF953100020CDE91000DE +:10CB4C00002903D401208DF85100FF208DF85000EE +:10CB5C001FFA88F110AB0420142219F06FFDBDB13F +:10CB6C00092085F81D900822287020886880A078FC +:10CB7C002871681D61681CF063FCA16805F10D004B +:10CB8C0010221CF05DFC0E482946007812F0E6FAE3 +:10CB9C0015B0BDE8F08360680DF11F0110AA0CF010 +:10CBAC00D1FD80469DF81F0018B14FF000090126F9 +:10CBBC007DE74FF0AD09002679E700BF2426002061 +:10CBCC009D7A00202DE9F843DFF830810C46914620 +:10CBDC0007462246B8F8241013F0A4FB002879D09D +:10CBEC00068905464FF6FE70864204BFC320BDE899 +:10CBFC00F8831CF031FE864204BFC220BDE8F883E6 +:10CC0C002988B8F8240088421CBFA8F824100846CC +:10CC1C0015F080FBE87A3946013088F8380008F1C5 +:10CC2C0039001DF016F902208DF80100684619F044 +:10CC3C0051FF002851D007460069062101260170DA +:10CC4C0098F80E104170BE771CF050F978624020B5 +:10CC5C00BE7687F81890F88228897880384611F0CB +:10CC6C00C5FE002845D1092008F11A0188F82600D4 +:10CC7C002889A8F81A0098F81800A04218BF88F85C +:10CC8C0018401F4C4B20A04708F124015020A0470E +:10CC9C0008F11801E120A04708F116015320A04724 +:10CCAC0008200121FEF7E0FD4FF400500021FEF7B3 +:10CCBC00DBFD144C4FF48061207812F08DFE13488C +:10CCCC00007802280BD110480078012807D14FF4C6 +:10CCDC00DC6208E0CA20BDE8F883102009E00820D7 +:10CCEC000EF0FCFF820020784FF480611DF06CF890 +:10CCFC000020074900220A70BDE8F883A86D0020C7 +:10CD0C00892102009C7A0020E5270020242600209F +:10CD1C00A27A0020F0B58DB00546007C0F2873D3A5 +:10CD2C006E68686908AC0021224613F023F89DF860 +:10CD3C002000002868D1287C0B2865D3307A022883 +:10CD4C0062D1B189C8B2FF285ED19DF8220010F0E3 +:10CD5C00FD0F59D1404F97F8263043F00402062AB4 +:10CD6C0004D13E4A1268AAB1C90B1FE03B4A1268B3 +:10CD7C0012B19579012DF4D0082B01D0042B43D19D +:10CD8C007589002A42D0917902293FD1284618F0A2 +:10CD9C00E5FE39E0727C7189308800230093002312 +:10CDAC00FBF758FEB089C10B9DF8220032888DF834 +:10CDBC000D10B17B9DF824308DF810009DF8255096 +:10CDCC009DF83200ADF8082072898DF80C109DF892 +:10CDDC0021108DF80E308DF813508DF81400ADF82D +:10CDEC000A20727C9DF826608DF81110E11D8DF8DB +:10CDFC0012208DF80F6002AD082205F10D001CF019 +:10CE0C001FFB28461DF072F80DB0F0BDB98CA9427D +:10CE1C00FAD1012806D0E11D07F139001AF097FD6F +:10CE2C000028F1D10E484FF40071007816F0C4FAC6 +:10CE3C000028E9D140F20120ADF80D00B86A02904B +:10CE4C0097F82E008DF80C0002A812F003F90028B8 +:10CE5C009CD01AF05FFED7E7A86D0020D8260020E2 +:10CE6C009C7A0020F0B59DB04668077A10AD044658 +:10CE7C00342128461CF04CFF8DF84070294636F8BA +:10CE8C00020B16F0E5F902201A9604F128018DF830 +:10CE9C004100608EADF84E009DF8400002388DF8D0 +:10CEAC005C0006A81CF0D9F99DF8420003287AD141 +:10CEBC009DF843501CF0CAFC854274D19DF8440087 +:10CECC00002870D19DF8450000286CD19DF84600D3 +:10CEDC00002868D19DF85D00002864D19DF84700BA +:10CEEC00002860D19DF8480000285CD109A81C21BD +:10CEFC001CF00EFFBDF84E001A9A9DF85C30ADF890 +:10CF0C002E00154615F8010B00F003018DF82400D6 +:10CF1C00032916D100F00C060C2E05D0082E08D1D2 +:10CF2C0001268DF8306004E0B2F80150ADF82850BD +:10CF3C00D51C35F8046BADF82A6035F8026CADF8E9 +:10CF4C002C60521B0D951344524203298DF8383036 +:10CF5C008DF8312027D100F00C01042923D010F0DA +:10CF6C00200120D140B200281DD4FE209DF8531082 +:10CF7C00B4F8422000238DF827000C4840788DF837 +:10CF8C00260094F846008DF81400B4F84700ADF86C +:10CF9C001500E06BCDE90013CDE9020309A806A941 +:10CFAC0005AB08F0E7FD1DB0F0BD00BFCC2600209E +:10CFBC002DE9F047DFF83491D9F840A0BAF1000F11 +:10CFCC0000F088800AF10C020820FF2151FA80F051 +:10CFDC00C3B21B1A18BF012312686AB163B113885C +:10CFEC00A3F60303012B01D90432EFE7DAF81000A2 +:10CFFC0092E8FA003830FAC0DAF808200025DAE9AD +:10D00C000A10CAE90A55B2B110F0E2440CD021F072 +:10D01C000F0220F0E2434FF0000852EA030005D063 +:10D02C001CF030FBB04701E0884604461CF02AFB9C +:10D03C0042462346B0471CF0D9FB0446B9F85600CB +:10D04C0001306FF31F30A9F856004FF6FD70AAF8A7 +:10D05C00300009F140008AF833501AF001FC2046E8 +:10D06C001CF07FFEB9F85600B9F85410884231D143 +:10D07C001F48204940680D6830B190F8FC2007200B +:10D08C00002A08BF052000E005204C680FF01EFDAB +:10D09C0055B195F8FC00002100284FF0000008BFA6 +:10D0AC00286885F8FC1000E0002044B194F8FC20BE +:10D0BC000021002502B9256884F8FC1000E0002549 +:10D0CC00A84288BF0546681C04D02DB9BDE8F047BE +:10D0DC001BF01CB9BDE8F0871CF0E0FEB5FBF0F1CD +:10D0EC000548BDE8F0471BF06FBC00BF30210020A5 +:10D0FC00D01E002070200020387100202DE9F04750 +:10D10C004FF6FC76B04201D100240FE08846002196 +:10D11C001D469246002414F0E5F9DFF810910746FD +:10D12C00680606D4B9F81600874202D12046BDE83D +:10D13C00F087384629460CF01BFF30B9B01C002193 +:10D14C0080B20CF015FF00285ED0B11C078089B2AC +:10D15C00884505F0010118BFA0F8028045EA81015D +:10D16C00BAF1010F817140D101214171324915F0A1 +:10D17C00180F99F8142018BF0A7802714046B9F8B4 +:10D18C00241016F053FB0028BED12A482B49DFF897 +:10D19C00B0C0274D0022007809788A42B4D0C2EB87 +:10D1AC00C20400260CEB8404B0420BD005EBC6077E +:10D1BC0023887F889F4201D00136F5E70132F3B214 +:10D1CC009842EAD120461C211CF0A2FDB9F824009B +:10D1DC00A4F8008060814AF60120A4F811001948D7 +:10D1EC0000780130400820748EE7417901293FF422 +:10D1FC008BAF114915F0180F08BF09F1130109780D +:10D20C0080F805A001717FE715F0180F0CD00949C3 +:10D21C0007480978063039B110F8082B013912F09B +:10D22C00180FF8D10E3890E702247FE7A86D002084 +:10D23C004C500020D6BA0200D9BA0200D1BA020072 +:10D24C0030560020CDBA02002DE9F04186B01D46C3 +:10D25C0014460E46022818D0012818D0002876D182 +:10D26C00012E6BD0022E72D108201AF093FD3E488D +:10D27C000021437B3D48026840480088CDE90211FB +:10D28C0004913F49CDE9004555E0002000E0012024 +:10D29C00032E00D0F6B91CF01BF8032E18BF002883 +:10D2AC0035D102201AF076FD2F48304C417B206896 +:10D2BC0010F0D6FD2E49897801F00801014345D1C3 +:10D2CC002C48017801310170C8B2042849D12A4890 +:10D2DC00206046E0711E80F0010018BF0121084358 +:10D2EC0035D10A201AF056FD26484FF4806100789B +:10D2FC0012F072FB0DF11601502018F0FDFF2249BF +:10D30C00BDF81600888400211CF0E0FD29E01648C9 +:10D31C0090F80D8015480768184806881CF074FCB6 +:10D32C0001210022049030464346CDE90045CDE969 +:10D33C00022113493A4605F0CBFA07E008201AF00F +:10D34C0029FD2046214600221CF022F848B10F4846 +:10D35C0001214FF47A72007806B0BDE8F0411CF060 +:10D36C0033BD06B0BDE8F081CC220020747A0020D9 +:10D37C003E7900209927002000F8FF079027002015 +:10D38C00C02600209C7A0020A86D00209D7A0020E9 +:10D39C002DE9F04F8BB00C460690C9881F460792BA +:10D3AC00E07816F08FF900287ED0217D0546C0B2BA +:10D3BC0019F0E4FE002879D00646E188E07805975C +:10D3CC00DDE9177900224FF0000815F0F7FB8346D2 +:10D3DC00E0787071E188A07D86F80880227DF1806C +:10D3EC007081F06821691CF02BF886F81490778214 +:10D3FC004FF000090027BBF1000F4AD05FFA89F00B +:10D40C00854246D906EBC00A9BF80110504600F83D +:10D41C00168F012904D101270770BBF8020005E023 +:10D42C00BBF802008AF81D001BF0AAF9AAF8180034 +:10D43C0022789BF8041052068AF81A1005D59AF82F +:10D44C001C2042F002028AF81C20C7B9204AD28A5A +:10D45C00904214D11E48A170DDE90613CDF800806E +:10D46C00828C159801901698CDE90208204608F098 +:10D47C0081FB9AF81C0040F005008AF81C0009F1A9 +:10D48C000109E188E0785FFA89F215F097FB834691 +:10D49C00B1E7304619F0E8F80599DDE91423204688 +:10D4AC000096F9F71FFF10E0B92000E010208DF86E +:10D4BC002800E078A17D8DF82300E0888DF82410F9 +:10D4CC00ADF8260008A81BF0B7FC0BB0BDE8F08F38 +:10D4DC00A86D00207CB50568002D6DD0044647482A +:10D4EC00026842B1217928469047012803D1688906 +:10D4FC0020F001006881687B02282DD168898007A3 +:10D50C002ED52079CD282BD0F02829D0688A00067A +:10D51C000CD5A87E50B1A8732868008816F006FCBC +:10D52C0040B94FF498700DF062F803E0344800787D +:10D53C000130A8732079002856D00420202168736C +:10D54C00304800882881A87B0138A876A8732E481B +:10D55C00007810F0D5FD687B40F0040006282BD134 +:10D56C002B49288BC98A884214D02849097889B15B +:10D57C0029680988ADF8000001208DF80500287B8A +:10D58C00ADF802108DF8040020798DF8060068467D +:10D59C001BF0E2FD6889C0070ED0217928461BF0EC +:10D5AC0016F9688920F0010068812868008816F057 +:10D5BC00BDFB217908B121B17CBD39B140F23110EC +:10D5CC0001E040F22D100DF012F87CBD40F22F104E +:10D5DC000DF00DF8002560798542EDD24FF49B706B +:10D5EC000DF005F80135F6E7002660798642A4D2E5 +:10D5FC004FF49B700CF0FBFF0136F6E7382400204B +:10D60C00C62700208C2700209C7A0020E9250020CA +:10D61C00A86D0020BFB54A4D044695F82600092890 +:10D62C0000F28C80012101FA00F040F20A2108423C +:10D63C0000F084806178F1B141F2030019F0A9F98E +:10D64C004048007802280ED13F4801780B2904BFCE +:10D65C000A2101703D48002101703D484FF4804182 +:10D66C00007812F0B9F96178A88C1CF02FFC00201E +:10D67C0085F8260060E00220002119F08AF934F8C0 +:10D68C00020FE8825320214614F078FD95F826000D +:10D69C00092802D0A88C14F03DFE01200DF10F01D9 +:10D6AC008DF80F00422014F069FD04200DF10704E1 +:10D6BC0085F826004A20214618F01EFE05F11C00B4 +:10D6CC0021461CF0C6FB204801780B2902D106210B +:10D6DC00017003E0A88C00211CF0F8FB194C207899 +:10D6EC0002280AD2688B4FF6FE7188420ED00DF1DB +:10D6FC0007010022FEF7EAFA08E007D1E98A0320C5 +:10D70C0019F047F9698B042019F043F9A87B0DF146 +:10D71C000F01C0F3C0008DF80F00522014F02EFD45 +:10D72C002078022808D1A87B00074CBF4FF400409A +:10D73C0001200121FEF798F81AF054FFBFBD00BF7D +:10D74C00A86D002024260020D0260020DC270020F5 +:10D75C009C7A00202DE9F0418846080430D45FEA19 +:10D76C00C86000F181805FEA887000F182805FEA16 +:10D77C00087000F1818018F4706F00F082805FEA0D +:10D78C00085004D500201BF0B3FA88F400685FEA57 +:10D79C00485004D501201BF0ABFA88F480685FEA8E +:10D7AC00885004D502201BF0A3FA88F400785FEAB5 +:10D7BC00C85068D503201BF09BFA88F4807862E08F +:10D7CC00324F387811F06EF900284AD00546466879 +:10D7DC000078411E05290DD91A282CD024282ED0CA +:10D7EC00D12833D0D32835D0FD2836D128461AF08D +:10D7FC006EFC32E0DFE801F0030B310F311B66B336 +:10D80C00304611F0FBFB30461CF076FB25E0284639 +:10D81C0014F090FE21E0F478701CE11CC9B21BF0EE +:10D82C0087F9611D56FA81F101F8010C15E02846C3 +:10D83C001BF03AF811E02846FDF75AFF0DE0F0789E +:10D84C000530C1B230461BF0E3FF06E028461BF062 +:10D85C00EBFF02E0284611F06DF828461AF046FC62 +:10D86C00AFE788F400480EE01AF004F988F01008CD +:10D87C0009E088F0020806E00DF0D0FA88F00808FC +:10D88C0001E04FF000084046BDE8F0819A7A002094 +:10D89C0070B50C4608041CD4E00729D14448007824 +:10D8AC00012805D8A00745D4A00654D4600474D42C +:10D8BC00E0062DD4200744BF84F0080070BDE005BD +:10D8CC003DD460075FD400202146BDE8704009F0CC +:10D8DC00E3BB344E307811F0E5F830B1054607F073 +:10D8EC00DBFA28461AF002FCF4E784F4004070BD21 +:10D8FC0001201AF04FFA2C480F220F2381782B4865 +:10D90C00008800F00700FFF79FFC84F0010070BD59 +:10D91C002548007810F0B4FC28480078012806D17E +:10D92C0027484FF40061642200781CF04DFA84F013 +:10D93C00100070BD0AF098FA84F0020070BD214806 +:10D94C0090F82600082801D0042801D11BF032FBE6 +:10D95C0084F4807070BD1748007860B91248007864 +:10D96C00062802D107201AF015FA1348007801286E +:10D97C0008BF19F0D9FD0B481021007810F0C0FB3E +:10D98C0084F0200070BDFF20032116F07BF81CF002 +:10D99C008AF90D4801210160FEE714F045FB84F47F +:10D9AC00804070BD9D7A0020D02600203E7900205A +:10D9BC0024260020BF7A0020CA270020CD27002073 +:10D9CC009C7A0020A86D00207C0520432DE9F84F9F +:10D9DC004FF00054002A994616460F46804618BF51 +:10D9EC004FF080444D1C1BF001FF824635B1404680 +:10D9FC003946002214F090FA07460FE03C48816C3F +:10DA0C0011B10969414506D0C16C11B10969414593 +:10DA1C0003D0876B02E0876C00E0C76C37B197F9D5 +:10DA2C003300B0F1FF3F03DD04245BE0032459E035 +:10DA3C00DFF8BCB00A9DDBF84800874218D0DBF851 +:10DA4C004C00874229D0404639464A462B460BF0BB +:10DA5C0015FC0028E8D02748017E012941D0007E22 +:10DA6C0004283ED02448254928301CF05DFA38E0C3 +:10DA7C00DBF848000022234619F0CCF81BF046FFD7 +:10DA8C001F48002E18BF00F580301AF063F8F5B16E +:10DA9C00DBF848001CF0AEF80CE01BF037FF184820 +:10DAAC00002E00F100501CBF0120C2F202401AF0FF +:10DABC0051F865B1DBF84C001CF09CF838690E4944 +:10DACC00086291F8240040F0010081F82400B9F1BB +:10DADC00000F06D0DBF83810404601222B460BF025 +:10DAEC00CDFB832450461CF03CF92046BDE8F88F52 +:10DAFC0030210020D01E00207020002002000040A9 +:10DB0C0001000104F0B58DB0044603200D468DF8DC +:10DB1C0030000AAE30461CF09CF91BF0E7F90146C8 +:10DB2C00304619F014FF50B1287D40F00201032952 +:10DB3C0005D1297A09B1FF2914D1822000E0842073 +:10DB4C008DF82700E289207C0DF127010123CDE916 +:10DB5C00001004F11100A11C42F4004213F0E2FD8C +:10DB6C000DB0F0BD032804D1A87DFF28E5D0002816 +:10DB7C00E3D0304F4FF0FF300822CDE9060006A964 +:10DB8C003E1D30461AF0A6FB18BB2B486188C08A94 +:10DB9C0081421ED03878FF280AD0297A814207D0DA +:10DBAC0078884FF6FF71884202D06989884210D17B +:10DBBC000020314608228DF8080002AF381D1BF0FA +:10DBCC003FFC38460DF05EFD6088BDF80A108142BE +:10DBDC002DD1E08905F10C0621281CD18C206989F6 +:10DBEC00AB7D32468DF82700287A17F04FFB0028C2 +:10DBFC00A8D11BF0F5FF287D0328A3D102A930463C +:10DC0C0017F074FB00289DD1304600210022002320 +:10DC1C0010F066FB96E76989287AAB7D32461AF0DC +:10DC2C00BFFA08B188208BE71BF0DAFF8AE78D205A +:10DC3C0086E700BF0C260020A86D0020F0B589B047 +:10DC4C000546002001F108060C468DF80F00304601 +:10DC5C001AF02EFA18B9284631460DF02BF804ADFF +:10DC6C000DF10F0130462A460BF06CFD3B4E4FF682 +:10DC7C00FF7731784A1E9DF80F10012A10D879B918 +:10DC8C0000200DF10F01CDE90000684604AA0BF04D +:10DC9C0059FDB8421ABF01218DF80F109DF80F10D5 +:10DCAC00B1B1B84214D09DF8201099B3FF2926D0F9 +:10DCBC00022918BFFD2912D12A4900EB400001EBC3 +:10DCCC008000A16950F8042F91420FD2A22042E0AB +:10DCDC00307810B91BF098FEC0B1A1203BE00129AF +:10DCEC0038D130780138012806D90FE001310160B4 +:10DCFC003078411E02291ED24FF0817007E0307837 +:10DD0C00013801289CBF012084F826001448C4F86F +:10DD1C0012001FE0052060829DF8230000F07F00B8 +:10DD2C00A08212480078002818BF012084F8270030 +:10DD3C0084F826000EE030B90B48C4F812009DF8A8 +:10DD4C00220084F8280004F11E0005F108010822C5 +:10DD5C001BF076FB002009B0F0BD00BF242600208C +:10DD6C0000000301F033002000000101A427002073 +:10DD7C002DE9F047816A91F90120002A28D48246C6 +:10DD8C0002F01F0000EB40049AF81C300234A3424E +:10DD9C001ED18B1CD2B24FF6FE784FF6FE7C08B12A +:10DDAC00B1F802C0DFF8F49000264FF6FE770021A0 +:10DDBC00B9F81650814210D29C7814F0880F07D114 +:10DDCC0033F8037BAF4208BF04F007060131F1E7DB +:10DDDC00D320BDE8F0470CF00ABC300606D11FFA80 +:10DDEC008CF0B9B214F0EAFF002849D0BAF80C0054 +:10DDFC001BF051FF80B10021027AC17128490978CA +:10DE0C008A4206D3013149080172F1B2072938BFA1 +:10DE1C0001364672BDE8F08708F10101BAF80C0032 +:10DE2C0089B217F0C9F820B105461D48297C007845 +:10DE3C0015E015F0DDFC18B31C2105461BF068FF3E +:10DE4C004AF60120A5F81100BAF80C002880B9F8A0 +:10DE5C002400688112480078411C490829748142C9 +:10DE6C0006D3013040082874F0B2072838BF0136B9 +:10DE7C0000206E742873023528461AF019F908B17F +:10DE8C00BDE8F0879AF808000028F9D0DAF81810E5 +:10DE9C002846BDE8F0471BF0DCBF00BFA86D002092 +:10DEAC00CDBA02002DE9F84F1D4600928B468146F3 +:10DEBC001BF09CFC444A82464FF4A06000210127D1 +:10DECC0005F1010C002392F86040602935D007FA67 +:10DEDC0003FE1EEA040F0AD0BCF1000F18BF9D42CE +:10DEEC0005D1561896F80A80B8F1000F04D02031ED +:10DEFC0000F580700133E8E724EA0E040125737203 +:10DF0C0082F8604092F86240B572013482F8624047 +:10DF1C009EB142F801902D49BBF1020F86F808B072 +:10DF2C00716011D0BBF1010F34D1591DB1740A21AC +:10DF3C0031820A99896871612CE0FE2450461BF0ED +:10DF4C0010FF60B2BDE8F88F718A5A1D0A9B02F06F +:10DF5C000F0221F4706141EA0221718221F0F80173 +:10DF6C005A7902F01F0241EAC201718221F4C041C8 +:10DF7C009A7902F0030241EA423140F203623282A2 +:10DF8C0071824EF6FF721140DA7902F0010241EA19 +:10DF9C00023171820B9A42B111785278920042EAA6 +:10DFAC00411108430A49084300E000200099B06180 +:10DFBC0001B171600748416809B9C0F804900FF0CD +:10DFCC0003FC747ABAE700BF206E0020236E0100B8 +:10DFDC0001000406D01E00202DE9F04F8BB04A4FF3 +:10DFEC00B868D0F80001807AC0001BF087FF0028C9 +:10DFFC0009907DD000244FF6FF7B1BF0F7FB0090BF +:10E00C0001AD0DF114094FF0FF3AB868A2B2D0F887 +:10E01C0000110B899A4263D24FF001080026C97A8D +:10E02C00F2B28A4222D2D0F88824D02029468DF828 +:10E03C000660ADF80440904720B1B8680136D0F8BE +:10E04C000011ECE79DF810004FF000080128F4D106 +:10E05C009DF80F000028F0D103200B2809D0295C73 +:10E06C000130FF29F9D04FF00008E6E7B8F1000FB6 +:10E07C0001D00134C9E70026B868F1B2D0F800210C +:10E08C00D2888A42F5D9D0F88824ADF80610D12070 +:10E09C002946ADF80440904700BBBDF80800584530 +:10E0AC001CD0ADF81400B8684946D0F88824D420A8 +:10E0BC009047F8B9B8684946CDE907AAADF81AB047 +:10E0CC00ADF818B0D0F89424D4209047B8682946FD +:10E0DC00ADF808B0D0F89424D12090470136CBE7A6 +:10E0EC0000981BF03EFE09981BF006FF002008E08C +:10E0FC001A2006E000981BF034FE09981BF0FCFE79 +:10E10C0019200BB0BDE8F08F0C0100207CB5044643 +:10E11C008078022820D0012840F08C80267D0020B9 +:10E12C008DF8060006F1180019F002F9054610B931 +:10E13C0001208DF80600607940F00200022824D1FD +:10E14C00002D4CD0E078002818BF01201BF08CFA71 +:10E15C0023D01BF06DFA25E000208DF807002C2051 +:10E16C0019F0E6F8054610B901208DF80700607922 +:10E17C0040F0020002280CD1002D54D0E0781BF0A6 +:10E18C0073FA31D01BF054FA33E002208DF80600FC +:10E19C0025E002208DF8070045E0A01D042118F0B1 +:10E1AC00E7FAA860A07C32462874E07C6874207D75 +:10E1BC0015342146A87505F117001BF041F9A05D37 +:10E1CC00A874A01941786975817829750521C078E2 +:10E1DC0029802946E8741848007810F0BFFF0DF12B +:10E1EC0006037520012122E0A01D042118F0C0FABD +:10E1FC00A860A07C04F1150110222874E07C28751D +:10E20C00207D687505F11C001BF01AF904F125003E +:10E21C00042118F0ADFA0821A86107482980294685 +:10E22C00007810F09BFF0DF10703752002210122ED +:10E23C0014F0A4FA00207CBDA87A00202DE9F04F40 +:10E24C008BB04248DFF80CB100240DF11C0A4FF0E2 +:10E25C0000084FF0000900270078019000EBC00087 +:10E26C0086003B48007801304008029046455CD05F +:10E27C001FFA89F1032000221023CDF800A018F01A +:10E28C00C7F900284CD19DF821300BEB0801BDF8E3 +:10E29C001C009DF820200C82CC60CC724B714AF68D +:10E2AC0001232BF80800BDF81E000A71A1F80930F3 +:10E2BC00029B48800B72BDF82230CB800A9B5D1C00 +:10E2CC0004D081F82040C1E9063315E0013A012A57 +:10E2DC0009D8214A12784AB1204B53F82220C2EBBC +:10E2EC000212920004E06FF0010203E01B4A126874 +:10E2FC0081F820408A61CA614FF6FF7188420FD0C5 +:10E30C00ADF8180001208DF80C0003A811F02AFEBE +:10E31C0028B11348818CBDF81C0017F0C6FD0137DD +:10E32C0008F1240809F10109A0E7002004210024C8 +:10E33C0015F054FC0199884224BF0A48047006F079 +:10E34C0013FBF8B20BB0BDE8F08F00BFE3BA0200CC +:10E35C00CDBA020020450020D827002090B402003E +:10E36C00A86D0020972700202DE9F041414F04466D +:10E37C007878C8B1DFF80081B8F85400B8F85610B6 +:10E38C0088421ED008F13801204619F07AFA80B97B +:10E39C00D8F8480010B10069A04207D008F140013C +:10E3AC00204619F06EFA03E0BDE8F081D8F8480079 +:10E3BC0038B1B0F9301020460A224FF0E04307F094 +:10E3CC0045FF1BF013FA2D4D0646284602C8A14204 +:10E3DC0008BF284600210160787801387870000663 +:10E3EC0036D17C60387E02280ED1082016F040FB16 +:10E3FC0030461BF0B6FC04F150004FF0FF311BF01F +:10E40C0017FC1BF0F3F9064605F128001BF08AFDFA +:10E41C0040461BF04FFD1A481BF084FD08F11C0010 +:10E42C001BF048FD17481BF037FD17481BF034FD57 +:10E43C001648416811B107F15000884707F12800D0 +:10E44C0019F028FC1248807810B10D2007F0A8FEB6 +:10E45C007868A04204BF0020786030461BF081FC35 +:10E46C0004F150001BF05AFD04F1B800BDE8F04176 +:10E47C001BF012BDD01E0020302100207020002087 +:10E48C00407200207C710020387100208026002012 +:10E49C009CB902002DE9F0478EB080460E2016463E +:10E4AC008A468DF81A308DF818208DF81900012045 +:10E4BC008DF81C003E48B8F1000F077B8DF81B70DF +:10E4CC0020D00AEB0605687B11F014FE034620F001 +:10E4DC00010000243A280AD10DF104090020112171 +:10E4EC004A4619F0A3FE002808BF09F10104287858 +:10E4FC000994384305F8050B0DF12B0029461BF048 +:10E50C00A8FC36E001AD002011213A2300242A4654 +:10E51C0019F08CFE08B109942BE0DFF898906C1C74 +:10E52C00012101220994D9F80430581CC9F80400BF +:10E53C000AEB06000090384612F031F81AF0D6FCBF +:10E54C0001460DF12B001BF084FCB9F800001A49B0 +:10E55C0001300968A9F8000080B2814203D3D9F8D0 +:10E56C000400012805D115484FF4007100780FF014 +:10E57C00C7FD0DF12B000AEB06050422691C0830BF +:10E58C001AF05EFF1AF806008DF837005CB106A988 +:10E59C000DF12B024046534606F05EF8297801F047 +:10E5AC00F801297000E0A1200EB0BDE8F08700BF93 +:10E5BC00A86D002014250020A8BA02009D7A002026 +:10E5CC002DE9FE431BF012F9DFF80C91804699F807 +:10E5DC000100B8B14148032201688260C80711D01C +:10E5EC003F4C2068416802208847019020684168B0 +:10E5FC000120884702903B4801A91C3011F09AF881 +:10E60C0017F09EFDD9F80450EDB13649686A01AF98 +:10E61C0001F11C06A96A884219D23046394612F01B +:10E62C00D5F9013011D0D5E90912E869541A08441A +:10E63C003946082C28BF082422461BF085FC686A42 +:10E64C0020446862E6E700240CE0D5E909010024C7 +:10E65C00884207D309F10400294618F0FFF985F820 +:10E66C003240012499F8010088B9D9F8040018B196 +:10E67C0080681AF069FB0AE01A481C301BF025F878 +:10E68C0028B9194A4FF0FF30012110F067FA4046C3 +:10E69C001BF067FBF4B1A86800220168CA628A69A2 +:10E6AC000AB10223137091F83030012B07D0022BE2 +:10E6BC0010D101F134001BF033FCBDE8FE8322B114 +:10E6CC00CB6800219847BDE8FE830C69CA698B6A48 +:10E6DC000021A047BDE8FE831823002008800240DB +:10E6EC00CC0100107422002080A9030070B586B004 +:10E6FC00454D0446A868D0F8F41091F84420B2F1C6 +:10E70C00820318BF531C81F84430D0F8F40090F801 +:10E71C00441000EBD10090F82C104A0880F82C2003 +:10E72C00C807A86809D1D0F8F41091F94420531CFB +:10E73C0012F1020F81F84430E7DCD0F8F4201146D6 +:10E74C0011F8443F802B25D8D0F83024E120904795 +:10E75C00AA6802208DF814004FF0FF30D2F8F43084 +:10E76C00ADF80C009878022823D0012824D030BBB7 +:10E77C001BF094FB4FF47A71244B0022B1FBF0F0A8 +:10E78C0023490BF0B5FBE0B3A8681A21D0F8F400CC +:10E79C00417004E0907810B91C4814F04FF82A200E +:10E7AC002070A868D0F84013204606B0BDE8704031 +:10E7BC000847D2F86814F7E70820802101E0072009 +:10E7CC008321D2F8786303F149020023CDE90032AA +:10E7DC0003AA4FF6FF73B047A0F1DB01182910D83C +:10E7EC00012202FA01F10B4A11420AD0A968D1F8B0 +:10E7FC00F41048702A202070A868D0F840132046E6 +:10E80C00884706B070BD00BF0C0100205C7A002068 +:10E81C003D2D0100112400012DE9F04389B004467F +:10E82C004648807860B9E07AFE2809D168462421F0 +:10E83C001BF06EFA208B10F00D0F06D0B62400E002 +:10E84C000124204609B0BDE8F083207A0028F5D0D9 +:10E85C0001288DF8080011D002281CD003281ED0E6 +:10E86C000F2820D102204FF000080B264FF0000992 +:10E87C008DF808002088ADF8000019E0B4F800808D +:10E88C004FF6FF700F26ADF8000002204FEA182952 +:10E89C008DF808000CE02088ADF8000003E0684615 +:10E8AC0021461BF0D6FA4FF0000803264FF0000962 +:10E8BC0006F00C0707200C2F08BF0920A17C084488 +:10E8CC008DF81F00C0B21BF019FBA0B305460C2F2E +:10E8DC000890867011BFE81C85F8049085F80380B9 +:10E8EC00681DA17B0170E17B4170217C8170617C92 +:10E8FC00C1700430628A61691AF0A2FD1AF0A6FF99 +:10E90C0081098000033069702870B7FA87F04009DC +:10E91C00ADF80E0003208DF80C00A07E8DF80D00D4 +:10E92C00A089ADF80A0068461BF078FA0446284620 +:10E93C001BF0E2FA85E7102483E700BFCC26002009 +:10E94C002DE9F04F85B0054691460E46C80731D1EA +:10E95C002846314612F0C6FD404FF98A884242D013 +:10E96C002846022132460CF0C1FBE0B328464FF694 +:10E97C00FE7102223346FEF7C1FB90BB4FEA15280D +:10E98C0006F0DF0A70061ED402A9284617F0BEF95D +:10E99C0068B9B98C284616F00FFBA0B1871C384615 +:10E9AC0019F086FB78B102A839461BF052FA46F0F2 +:10E9BC00200A08E0B0074FF0FF084CBF46F0100AE1 +:10E9CC0046F0080AFC25264800220778791C0170BD +:10E9DC002248012100913946C08A034608F0EAFF1B +:10E9EC0018B1C72037E0002035E01AF020044FF0B2 +:10E9FC000E0008BF06208DF8110004A818F06AF864 +:10EA0C0040B34FF0010B064680F81EB01AF06EFAB8 +:10EA1C0070623069002141710AF078018770C5700D +:10EA2C0080F8048080F800B041701CB1063002A957 +:10EA3C001BF00FFA6FF00300B9F1000F708005D0D6 +:10EA4C0008480078484588BF86F81A9030460FF081 +:10EA5C00CDFF00E0102005B0BDE8F08FA86D0020C0 +:10EA6C00C07A0020CBBA02002DE9F04788B0444DA3 +:10EA7C000A4604461046A98C14F0D8FE40B14178E1 +:10EA8C0031B9072141703F490978013149080170BA +:10EA9C00A06A477817F08F0F18D1F9064FF01002C3 +:10EAAC0058BF0822BB0648BF0832237F93420DD1C2 +:10EABC0090F8029090F80780B0F805A0B0F80360C9 +:10EACC00002909D407F0700708200DE0D32008B006 +:10EADC00BDE8F0470BF08BBD00F1080106A81BF058 +:10EAEC00B8F907F060071020B90606D5A16A0144F1 +:10EAFC0004A81BF0AEF907F05007B6B249463046F1 +:10EB0C0015F0EAFF2049097888421ED21F4900EB14 +:10EB1C00800001EB400010F8061F41452CD980F80D +:10EB2C000080E88A864213D0A1891FFA8AF4012258 +:10EB3C003B462046FEF7E2FAF0B904A806A9029774 +:10EB4C00CDE900103046214612E0E88A864207D112 +:10EB5C00A1891FFA8AF001223B46FEF7CFFA0BE09F +:10EB6C0004A806A90297CDE900101FFA8AF13046D5 +:10EB7C0042464B4603F0C4F908B0BDE8F08700BF2D +:10EB8C00A86D0020CDBA0200D5BA0200B25C0020FC +:10EB9C002DE9FE4F8A4683461AF0ACFDDFF808914A +:10EBAC00DFF8FC803F4E99F8001098F80200B07323 +:10EBBC0039B1000713D501200DF10A018DF80A00B7 +:10EBCC000AE0002000240EF06FFBB07B000706D596 +:10EBDC008DF80B400DF10B01522013F0CFFA0EF013 +:10EBEC0083FF19F02DFF38B105460EF0F3FC13F03E +:10EBFC0005FE0CF051FF08E008F028FF0546307EBA +:10EC0C00012101FA00F0294908604FF6FE74012D2C +:10EC1C002FD10FF0D5FA1AF0F7FF074624482349F5 +:10EC2C0000680860FF20022114F02CFF601C748324 +:10EC3C00F482B084002013F0A3F807F07F0058444E +:10EC4C0000F164061B480078012808D10020BAF1B5 +:10EC5C00010F1CBFCDE90000684615F0B3FA114A4C +:10EC6C00212074211AF02AFF0020022114F00AFF3F +:10EC7C0000E0002628460CF09BFE601C80B2834509 +:10EC8C0007D0012089F8000017F0D8FFB0B219F0B6 +:10EC9C00CBFE98F8020019F0D7FA2846BDE8FE8F93 +:10ECAC003E790020A86D0020D0260020747A002028 +:10ECBC0078270020242600202DE9F0438FB014F093 +:10ECCC0003FB3F4F97F82600082806D00120C7E920 +:10ECDC000C003C480078F87078710DF11408242170 +:10ECEC0040461BF015F839480F25374EDFF8E090F9 +:10ECFC000DF13B018DF83B5000783570013818BF91 +:10ED0C0001208DF81E004620C847324800248DF89B +:10ED1C00004000788DF801001AF098FD8DF8020083 +:10ED2C0097F838008DF80640ADF8034007F139012B +:10ED3C000F2838BF05468DF805506D46E81D1BF0B1 +:10ED4C0088F84FF0FF303278234EADF80F008DF875 +:10ED5C00110097F8720031468DF81200284610F019 +:10ED6C0014FD45203146C84705F0FEFDB88D97F8D7 +:10ED7C002F108DF820408DF834408DF82940ADF8D7 +:10ED8C001C00387E8DF81F1007F116018DF81A0043 +:10ED9C00B88CADF818005320C84707F11A014B2066 +:10EDAC00C847F879642100FB01F20C48082100786F +:10EDBC001BF00AF8404606F03DFA0FB0BDE8F083B0 +:10EDCC00A86D0020E3BA0200B927002024260020F9 +:10EDDC0089210200E8270020207900209C7A00205D +:10EDEC002DE9F0410546880058BFBDE8F0810020B0 +:10EDFC00002410F0DFF93D493D483E4FCC610860DE +:10EE0C0040F60A008846B887FC8797F8480000F05F +:10EE1C00F00087F848003C6497F8490000F0F000D7 +:10EE2C00013087F84900284607F00AFEAC6801203B +:10EE3C0021460E46496849B10A88A2F60302072A00 +:10EE4C00F7D800FA02F212F0830FF2D0707B00F0C8 +:10EE5C00F000707307F13C0070602748806B28B19C +:10EE6C00C0680088A0F6030002281AD3284630F8A0 +:10EE7C00381FB1B10021E9636987386495F8440003 +:10EE8C0095F8451000F0F00085F8440001F0F00012 +:10EE9C00013085F8450097F8490000F0F00087F83C +:10EEAC0049001AF04BF81548F86197F8250030B175 +:10EEBC0017F09CFE0028FBD012F0CCFA0BE00120DE +:10EECC001AF03CFD012806D0707B00F0F0000130F8 +:10EEDC0070730B48F86100202146C8F81C00C8F874 +:10EEEC0000400120BDE8F04118F004BF00100440C0 +:10EEFC0001010E04D01E00203021002095370000A7 +:10EF0C008D0902002DE9F84F0746087A0C4640F0AF +:10EF1C000201032917D10025B7B1FF2F14D09A464F +:10EF2C0016460AB903280ED00FF00AFA204610F044 +:10EF3C00C8FF8146207A4FF6FE71B0F1010B18BF65 +:10EF4C00B346894503D100252846BDE8F88F013822 +:10EF5C00DDF82880314EB0FA80F044092E48017853 +:10EF6C000020814230D03278BA4208D17278A24265 +:10EF7C0005D17288914502D13279934502D00E3673 +:10EF8C000130EEE706B32649C7B23546B1F800901A +:10EF9C00BAF1000FD8D0B8F800402846214619F035 +:10EFAC00BFFA60B92846214618F03CFB30B102206C +:10EFBC0039464A46334617F041FB00E0002508F17C +:10EFCC000208AAF1010AE3E70DF1030017F0ECF9CE +:10EFDC0005460028B8D0134885F804B0A5F802906F +:10EFEC006C702F7041460078504538BF8246A81D82 +:10EFFC004FEA4A0285F805A01AF022FA9DF8031090 +:10F00C00064AC1EBC10002EB40030548028802200E +:10F01C0017F014FB98E700BFDFBA0200307900202C +:10F02C004EB20200CFBA02002DE9F84380460068C8 +:10F03C003B4BD8E9012118603A4802603A4820223B +:10F04C001AF082FFD8F80C003849DFF8E89090E805 +:10F05C00FC00FCC1D8F80C00354990E8FC00FCC160 +:10F06C00D8F81000494690E8FC00FCC1324D402213 +:10F07C0099F80C00D8F8141040F0800089F80C00B6 +:10F08C0028461AF061FFE87BD8F81810202240F0CF +:10F09C00A500E873294D28461AF056FF40F20540AA +:10F0AC00697BAA7CEB7DC5F8049028820320287527 +:10F0BC00287B40F08000287301F0F00020490230DA +:10F0CC00687302F0E0000A460130A87403F0F00007 +:10F0DC000130E875D8F81C0090E8F800F8C2087BFD +:10F0EC00CB7B4A7B40F08000087303F070008430C7 +:10F0FC00C87302F0F000013048734FF45860086197 +:10F10C00D8F820000F4908600F48C06840690078A3 +:10F11C0008B111F005FBBDE8F84315F097BE00BF30 +:10F12C00687A00206C7A0020D87500209077002037 +:10F13C00A8770020C077002000720020B87500204E +:10F14C0048780020647A00200C0100202DE9F0435F +:10F15C0087B0DFF8FC8081462025EFF3118085F322 +:10F16C001188D8F830501DB180F3118800256AE061 +:10F17C00C8F83090374F80F311880020C9F80C1074 +:10F18C004FF48031C9F81C20002BC9E91200C9E9E1 +:10F19C00080118BF1F46D7E90116C9F81810397BAA +:10F1AC00012905D1C9E91060C9F8146030460DE099 +:10F1BC00294A002031460023002519F041FFC9E9F6 +:10F1CC0010012649C9F814008E423CD80021DFF802 +:10F1DC0090E0C9E9160197F800C0C9F85410BCF1C9 +:10F1EC00020F08BF0146BCF1000FC9F8501001AB6B +:10F1FC009EE8F5001946F5C108F11C001A4ACDF835 +:10F20C0008900090174808BF024609F12800142105 +:10F21C0018F0CEFA05462020EFF3118180F3118807 +:10F22C0081F3118899F8100010B9484612F04EFC81 +:10F23C0035B108F12800494619F036FA4D4602E07E +:10F24C000025C8F83050284607B0BDE8F08300BF51 +:10F25C00A01F00200CB7020040420F003F420F00DD +:10F26C00E8B70200ED3802008D950200F8B50446AF +:10F27C000020A5782075C4E9030045F0020000F0D9 +:10F28C00030002280CD115F00C0005F0030218BF86 +:10F29C00042809D1022A05D1E90601D402210FE084 +:10F2AC00012619E0022106E00C2803D00828F1D031 +:10F2BC00012100E00321022A02D1EA060E460BD4FA +:10F2CC0048B10E1D0C2807D8012202FA00F041F2B9 +:10F2DC001012104200D04E1D68B2B0F1FF3F0ADC94 +:10F2EC00E078800706D0A8074FF0030058BF022033 +:10F2FC00064400E0013627881AF0AEFA87420BD09C +:10F30C00A80609D51F48416920468847206918B9C5 +:10F31C00A07800F0DF00A070207D00B1F8BD61790D +:10F32C005020751C8DF8000020798DF80210216991 +:10F33C0028448DF8010029B10A7F497F1044084404 +:10F34C008DF80100684613F037FEA0B1012180F85A +:10F35C004850417621884180618801872179226952 +:10F36C0080F8421001692944416412B1127F1144A2 +:10F37C004164E060F8BD20461AF0E7FB10202075D0 +:10F38C00F8BD00BF502400202DE9FC47434FDFF8A7 +:10F39C0010810DF1070A4FF0000918F0FBFB002853 +:10F3AC0000F079805046012114F030FD38780528A2 +:10F3BC00F3D8DFE800F003090F1928469DF8070081 +:10F3CC00FE28EAD1032462E0B8689DF807100224F5 +:10F3DC0041705CE0B8689DF807100424817078785F +:10F3EC00002808BF052452E09DF8070088F800901B +:10F3FC007870033017F09CFF0028B86049D07978FA +:10F40C000124017043E098F80000411C88F80010BA +:10F41C00B96808449DF80710C17018F0BBFB05468D +:10F42C0098F8000079780A1AB9680844E9B20330F0 +:10F43C008A421ADA91B214F0E9FC787888F8000064 +:10F44C001FE07878BD689DF807400330C6B22846A7 +:10F45C00314619F06DFBA04215D17B68B3B1304633 +:10F46C00294600220024984711E014F0CFFC98F8AC +:10F47C0000007978284488F80000C0B288427FF4F4 +:10F48C008CAF052403E0284618F030FE00243C70B5 +:10F49C0083E700203870BDE8FC8700BFF42500200E +:10F4AC00967A0020F8B504464048C16819B1204648 +:10F4BC00BDE8F84008473E4E3068074658B105464F +:10F4CC0060882988814203D12079A978814216D09D +:10F4DC00A8692F46F2E71C201AF010FD002863D013 +:10F4EC001C2105461AF014FCFF20E8724FF6FE7042 +:10F4FC0028813068002818BF07F11806356020797C +:10F50C00217A627A237BA87060880129AA716971BB +:10F51C002B75288005F10C0007BF4FF0FF31C0E9B7 +:10F52C00001104F10D011AF094FC2249A07A09781B +:10F53C00884239D96179012903D01AF06BFA98B352 +:10F54C00A07AA97A884202D9E27A102A05D3884295 +:10F55C0006D1E97AE27A8A4202D20022012101E044 +:10F56C0001220021144B1B78022B01D2A31D01E0B8 +:10F57C0005D1E31D1B7813B172B9228808E00F4A3C +:10F58C00538B2288D31AB3FA83F35B09194203D045 +:10F59C00A872E07A2A81E872E07908B1012028711A +:10F5AC00A07908B10120E870F8BD00BF54750020A7 +:10F5BC00E8790020A327002024260020A86D002035 +:10F5CC001EF0040F14BFEFF3098169468869A1F19D +:10F5DC00480214BF82F30988954621ED100BF1EE19 +:10F5EC00102A41F8082DEFF3118102B400B5DFF8B1 +:10F5FC00D8E0F047374A1268116801EA0000106041 +:10F60C005DF804EB1EF0080F09D101BC80F31188E2 +:10F61C005DF8080BE1EE100ABDEC100B704704BC52 +:10F62C001EF0040F14BFEFF309816946A1F120010C +:10F63C0014BF81F309888D464A604FF08070C86111 +:10F64C0025488861234B1B681868086040F201103C +:10F65C001860704702B401B4EFF3148100291CBF89 +:10F66C00002282F3148802B402B4DFF860E0F047A1 +:10F67C0001BC01BC00281CBF022181F3148801BC11 +:10F68C00DFF84CE0F0470F484FF08051016001BCAF +:10F69C0080F3118800BF00BFFFF7FEBF1EF0040F00 +:10F6AC0014BFEFF30981694601F1200151F8080BF1 +:10F6BC00E1EE100AB1EC100B14BF81F309888D46F2 +:10F6CC00704700BF04ED00E0CDCD01006B9E020041 +:10F6DC00719E0200B4BA020060F600002DE9FF41F1 +:10F6EC003B4E96F8420100286AD1012086F842016F +:10F6FC001AF030F9374F86F87001374D7868C6F834 +:10F70C006C01387B86F84101A86810F4402F13D1A6 +:10F71C00386988B128686421C0F3066000FB01F4E5 +:10F72C001AF0BCFBB4FBF0F22C4906F19400002358 +:10F73C0015F06CFE19F094FE01AC20461AF00FFA8D +:10F74C002749A846002506F10C00002219F05BFFA2 +:10F75C0020461AF004FA234906F15000082219F049 +:10F76C0052FF214A06F1D8003221002313F0F8FC95 +:10F77C001E4C1F4A06F1F4002C210023256045463F +:10F78C0013F0EEFCD8F80800797BC0F3815021B15E +:10F79C00032804BF012186F83911032803D040F057 +:10F7AC000200022810D1206840F0400020600220A6 +:10F7BC0015F07CFF6868400702D4002015F076FF36 +:10F7CC00002004B0BDE8F08114F0E4FBF2E700BFC8 +:10F7DC00D81B002018B80200AC4F005063970200F1 +:10F7EC00ABDD01000929020061CD01009022084027 +:10F7FC0091A700002DE9F8431D46434BDDF820800E +:10F80C0043F606061C68038814F0007411D0B3424A +:10F81C0027D0B3F5C15F33D040F60206B3423ED1D8 +:10F82C0000F112030B604169116081692960C169A3 +:10F83C002EE0B3420AD0B3F5C15F03D040F6020606 +:10F84C00B34203D100F11203143002E000F11A03A9 +:10F85C001C300B600068106000202860C8F80000A5 +:10F86C004BE000F11A034FF000090B60C169116005 +:10F87C00016A2960416AC8F8001000F118011CE007 +:10F88C0000F112030B6041691160416A2960816AC1 +:10F89C00C8F8001000F1100190F80F900DE000F185 +:10F8AC001A030B60C1691160816A2960C16AC8F8CA +:10F8BC00001000F1180190F82490286868B10E88A7 +:10F8CC0019F0C4FE042808D8074606F0070148467C +:10F8DC000EF0A4FF296841F82700D8F8000060B1A9 +:10F8EC0019F0B4FE042808D805464846FF210EF04E +:10F8FC0095FFD8F8001041F82500002C18BF012402 +:10F90C002046BDE8F88300BF941200502DE9FE4F4D +:10F91C00D0E90085994614460F46834613B1002062 +:10F92C00C9F8000074B119F061FF064698F8070099 +:10F93C0058B198F8E80070B130461AF012FA6FF02E +:10F94C0008046CE06FF0090469E030461AF009FA1B +:10F95C006FF00E0463E000200121C8E93B74C8F885 +:10F96C00F440C8F8FC0088F8E810C8F83C0088F8A7 +:10F97C000D0088F80B00284601951AF027F8304640 +:10F98C001AF0EFF908F1D0060DF1080A19F02EFF64 +:10F99C0004463046514616F043FAD8F8F450D8F8DD +:10F9AC00FC10A842394438BF054602982A461AF082 +:10F9BC00CBFA3046294614F041FBD8F8F400D8F8BD +:10F9CC00FC10401BC8F8F4004819C8F8FC0020468D +:10F9DC001AF0C7F9012D03DBD8F8F4000028D5D1B3 +:10F9EC0019F004FF0746D8F8FC0050B1019819F043 +:10F9FC00EDFF584605F0F2F9D8F8FC0010B10024E0 +:10FA0C0002E000206FF00F04B9F1000F18BFC9F825 +:10FA1C000000002088F8E80038461AF0A2F92046C9 +:10FA2C00BDE8FE8F2DE9F041047B06468846204652 +:10FA3C0019F08AF8054610B168892C4625E07289C0 +:10FA4C003068214617F074FB002700286AD0044662 +:10FA5C00078116F8100F207470886082304619F0F8 +:10FA6C00F3FB6061308961892083B07AA07621F440 +:10FA7C0060704907608105D42C490978013140EA4E +:10FA8C00C11001E040F080006081C0F3C211B8F1F8 +:10FA9C00000F12D0022262732268D289520702D55B +:10FAAC00234A128A228169B36FF07F0220F46070BE +:10FABC0002EBC1110843608124E039B1810607D4FF +:10FACC00C1060BD440070FD4012013E000271AE025 +:10FADC001AF09AF800F07F005F300BE01AF094F8FF +:10FAEC0000F00F000A3005E0124806881AF08CF876 +:10FAFC0030400230208110480421617320210078AD +:10FB0C000EF0FEFA01276DB92289617B20460CF0BC +:10FB1C00DDFC38B1606908B11AF0EEF920461AF034 +:10FB2C00EBF900273846BDE8F08100BFD52700204F +:10FB3C00A86D0020B8BA02009C7A00207CB504465F +:10FB4C00007A022803D3208814F0F0F810B10226B2 +:10FB5C0030467CBD207A032806D10DF102012046E7 +:10FB6C0015F0C4FB18B9F2E72088ADF80200608AE2 +:10FB7C0044301AF0C3F9002864D0442105461AF029 +:10FB8C00C7F8A07A694617F0AFFE9DF800009DF803 +:10FB9C00011085F83A0085F839102846012117F034 +:10FBAC00F9FE05F110002146242219F049FC628A65 +:10FBBC00616905F144002864AA8719F041FCBDF87D +:10FBCC000200A88020480178E971013101701AF017 +:10FBDC0067F906461AF062F970434FF47A71002601 +:10FBEC00B0FBF1F0FF218DF80460288095F8390006 +:10FBFC0001FA00F0217E85F8370085F83600207A6E +:10FC0C008DF8060001F001008DF8050001A819F02F +:10FC1C002BFA298D023885F83400C0B241F0080166 +:10FC2C0083B22985A98F8AB2B2FBF3F202FB1010C2 +:10FC3C000004064818BF013201212A7200780EF028 +:10FC4C005FFA85E7102683E7987A00204826002083 +:10FC5C002DE9F04F85B0044600880DF1060117F030 +:10FC6C0051F8054618201AF049F94FF6FE7768B19D +:10FC7C00182106461AF04CF860881821324619F003 +:10FC8C001DFF781C608030461AF036F90020278062 +:10FC9C00002D207160D1DFF8C8A0BDF80640DAF85D +:10FCAC000000D0B314201AF029F9B0B3834604AB8A +:10FCBC004C2000210222002719F058FA009404EB82 +:10FCCC00440402AE0BEB44004FEA4408851C122F8F +:10FCDC0018D0B84505D1DAF8000000EB44012846ED +:10FCEC000BE007F102094C20062233461FFA89F17A +:10FCFC0019F03CFA09EB0B003146062219F0A0FB77 +:10FD0C000637E4E74C2014215A4619F0D7FE584622 +:10FD1C001AF0F2F8009C4FF6FE7704AB4C20002151 +:10FD2C00022219F023FAB8B9DAF8000050B104EB4A +:10FD3C00440130F81100B84204D1BDF8100030B1C4 +:10FD4C00013802E0BDF810000130ADF8100004AA33 +:10FD5C004C20022119F0B2FE05B0BDE8F08F00BFB7 +:10FD6C00EC2600202DE9F04788B0DFF8FCA0D0F895 +:10FD7C0004803E4E7F2400217F23DAF8280020EAFD +:10FD8C000800CAF828001B2915D020FA01F2D20766 +:10FD9C000FD00027324612682AB19578A94208BFC5 +:10FDAC0001371832F7E7DAB2FDB295423CBFCCB25C +:10FDBC003B460131E7E7B8F1000F15D0CAF82880AF +:10FDCC0001AC1821201D19F0A3FF0120CDF80480EF +:10FDDC008DF808009AF82E008DF8090020460EF0D8 +:10FDEC00EBFE08B0BDE8F087204EDFF884804FF6BC +:10FDFC00FF7930460768BFB13888BAF824108842BA +:10FE0C000FD1B978A1420CD1B8F8001049451DD1D9 +:10FE1C001AF05AF8AAF82400398881423046E9D100 +:10FE2C0002E007F11800E5E78AF81840FEF744FFF6 +:10FE3C000028D6D000208AF826000E480168002938 +:10FE4C00CFD0C42008B0BDE8F047084700208AF89E +:10FE5C0026000848016809B1C4208847002008B072 +:10FE6C00BDE8F04716F08ABAA86D0020E8790020AA +:10FE7C0090270020102500202DE9F04389B03F4A3F +:10FE8C001278824209D93C4A3D4F002952F8306021 +:10FE9C0018BF0F4696F8521021B10025284609B01C +:10FEAC00BDE8F08302EBC009D9F804406078022861 +:10FEBC0026D1022086F8520011F0EAFF0DF10C0851 +:10FECC00404619F0C5FA3868002541468DF81450A3 +:10FEDC0006958DF80C500490207812F0EFFC002859 +:10FEEC007060DBD019F082FFF87988B1B879396885 +:10FEFC0048436421B0FBF1F1706819F074FF07E01E +:10FF0C0000F0EEFC012086F85200207886F85400B0 +:10FF1C006D46284619F023FE002000212A46CDF814 +:10FF2C0008908DF800000190164813F0DDF8B060D1 +:10FF3C0070B138683060B97986F85310F8790228B6 +:10FF4C000CD0012812D0A0B9484613F016F810E0D6 +:10FF5C0070680028A1D019F043FF9EE7B8884FF6CF +:10FF6C00FF72410848460BF02DFF02E0484613F0A3 +:10FF7C006DFE4D4692E700BFF4B80200C3B8020014 +:10FF8C001CBA0200092C0200F0B58BB0364D286863 +:10FF9C0070B9364C206828B935488068D0F84C05C3 +:10FFAC0080472068334C016A204688473248E0611C +:10FFBC0032480068016931B12D488068D0F8D4000E +:10FFCC0090F8530088472A4EB068D0F8D40090F9C6 +:10FFDC00420010F02FF9411C03D0294940EAE0708F +:10FFEC004882274C002060606080207B617B40F061 +:04FFFC0080002073EE +:020000021000EC +:1000000001F0F00001306073B068D0F8C40380479D +:1000100030B91F4810210170F06814214068017048 +:100020002868D8B10020002614F0CEF9124F3868A5 +:10003000416E03A8884717480696806808B1804734 +:1000400009903968286800230D6D0821CDE9001654 +:1000500003AA2146A8471048046009E00F480B4A4C +:10006000074B01680448006804680D48A0472860F1 +:100070000BB0F0BDE4260020347A00200C010020F3 +:10008000F875002054F10080607A0020D8750020B7 +:10009000B47A002054B5020030250020687A002090 +:1000A000B06500202DE9F0418AB03E4E054630682B +:1000B00020B13D490978A94209D82DE013F038FF55 +:1000C0003068002448B338490978A94225D94FF04F +:1000D000FF3119F0B3FD354905EB450001EB800414 +:1000E00067683878A8B9A568A9682A6848424B1E8D +:1000F0001A42B8600DD16A688A420AD3104082421F +:1001000007D1686910B10068786029E0298B04295B +:1001100007D3306819F00AFF002420460AB0BDE872 +:10012000F08106EB81000069A8B90DF10408404692 +:1001300019F02EFC002041468DF810008DF80400C7 +:10014000E8690590287E12F03FFC0028E1D0298B59 +:1001500006EB81021061786031440A7B01320A7338 +:10016000298CC6E90101204617F0C4F80120387037 +:10017000AB2031898DF82700204619F01AF80DF1CF +:10018000270001210FF07EFD31890546204619F038 +:1001900019F815B920460EF09FFD306819F0C6FE1B +:1001A000BBE700BF0C2400208DB9020028B7020075 +:1001B0002DE9F84F3C4C3D4E3D4D42F62A294FF07B +:1001C000010A4FF0030B00274FF00508D4F83C015B +:1001D000062833D8DFE800F00433183B203D4B00FD +:1001E0000F20F060C6F8109013F00AF945F804AC3F +:1001F00055F8040C8007FBD5C6F81CA094F839010B +:1002000090B10120EF6210E02F60C4F83CB1286883 +:100210008007FCD40320DBE72F60C4F83C8128680A +:100220008007FCD40520D3E70320C6F800B0C4F84B +:100230003C012F6029688907FCD4C9E7FEE7012645 +:10024000022084F83A6112F07FFB2E6009E0022060 +:1002500000E0032084F83A01002012F075FB012031 +:10026000286004F15000BDE8F84F19F027BE0020C7 +:1002700045F8040C286055F8040C8007FBD4286866 +:100280008007FCD40B480025012105600A48016065 +:100290000D2005F08BFF022014F0D6FBC4F83C5172 +:1002A00084F83B51BDE8F88FD81B002000400C407B +:1002B00058600C403C500C4004800C4070B5C16844 +:1002C0000C6991F8381041F00203224603F0030351 +:1002D00002F8011B022B3BD111F00C0301F00305C6 +:1002E00018BF042B2DD1022D01D1CE0630D4C26807 +:1002F00092F83B2062700234022D01D1CA0626D446 +:10030000C26892F83E202270C26892F83F20627064 +:10031000C26892F84020A270C26892F84120E27050 +:100320004BB1221D0C2B13D8012505FA03F341F222 +:1003300010152B420CD0C26892F83A202271621D2F +:1003400006E00C2B32D0082BCDD01446D4E7224641 +:10035000C46801F0020394F8395005F003051D4309 +:1003600009D1658D2D0606D4154E357884F849508F +:100370006C1C347001E094F8495049B21570B1F129 +:10038000FF3F00DD70BDC16891F839105170C16840 +:1003900091F83940A407F5D091F84B10002B9170DB +:1003A000F0D0C06890F84C00D07070BDC26892F870 +:1003B0003C206270C26892F83D20A27003349BE733 +:1003C000987A00202DE9FE4FDFF8F4B001219BF868 +:1003D0000C4001AA204619F00EF96A462046022177 +:1003E00019F009F9DFF8DC909BF80EE09BF80D009E +:1003F000BDF800C099F800100EF101030746B3FBE9 +:10040000F1F404FB11359DF80240ADB2FEB2B542E5 +:100410000FD0A642634618BF1023720052FA87F22B +:100420000BEB82029383721CB2FBF1F303FB1127E7 +:10043000ECE7DFF894A0002401270DF1080857FA33 +:100440008EF2C9B2C5B2B2FBF1F303FB1121A9428E +:1004500032D0690051FA80F00BEB800232F81C0FA9 +:10046000102806D1284607F013FA8AF80000013454 +:1004700017E028460421022313F03EFD8AF800000D +:10048000284600214246042318F0A8FF9DF80800E2 +:100490007C2802D0FE2804D10DE02846782114F0F3 +:1004A00051FA99F80010681C9BF80EE0B0FBF1F2CD +:1004B00002FB1100C3E7FEE7E0B2BDE8FE8F00BF1C +:1004C000B87200209B7A0020A02300202DE9FE4F67 +:1004D00005460F465818AE687168884202D96FF019 +:1004E000030564E0DFF8E8800C9C4FF0FF3199468B +:1004F0009246D8F8000019F0A1FBE00711D1A0073F +:100500001ED5306851464A463844CAB110F8013BFE +:1005100011F8014B013A23409C42F6D06FF00605DA +:1005200041E0D8E90101CB4301EA090213EA090FCE +:1005300018BF02443940284609F060FE054690BBCA +:10054000306802970196074412F07EFBCB46554671 +:100550000090BBF1000F16D0BBF1080F5E4628BF1C +:10056000082619F049F9804628463946324617F0E0 +:100570007FFE0446404619F0FAFB2CB93744354457 +:10058000ABEB060BE5E70024009817F005F9DFF860 +:100590004080DDE901210C9814B14FF0FF3502E0F5 +:1005A000400707D40025D8F8000019F0BFFC284602 +:1005B000BDE8FE8F10680844B9F1000FF2D010F8C2 +:1005C000011B1AF8012BA9F101098A42F4D0E4E7D2 +:1005D000DC250020B0B50C46880722D4600758BF40 +:1005E000B0BD354D0120A870042015F065F83348E2 +:1005F0000068006B8047E8602D48806BF0B1696847 +:10060000046961B1A1420AD094F82800400704D5DA +:10061000636A2046042100229847012060766C60BE +:100620000DE0FCF7CBFC2248006CE0B3214844F01D +:1006300002012830BDE8B04019F07CBC6C686068ED +:100640001F4900780860022015F036F8102005F0E8 +:1006500047FB012028761B48807810B90D2005F053 +:100660003FFB6868416818488A680AB9C96821B1BF +:1006700000218160154940F8141C154907220A60C1 +:10068000016800210160426841601249124AE96133 +:100690000168114301601A2019F016FC1920BDE809 +:1006A000B04019F011BCBDE8B0400DF093B800BFE8 +:1006B0003021002070200020D01E00208C0100106E +:1006C000D02108409CB902001410044051000706D4 +:1006D00000000460EDED0000024000402DE9F84FFD +:1006E0003A48DFF8EC90DFF8ECB0DFF8EC80002659 +:1006F0004FF0060A00210078C700B74242D009EB4C +:100700000605A878E0B30138A870687918F022FAD5 +:10071000A8B30446A87800B3A87948B3287970B381 +:10072000E9780139E970090629D19BF801100138EF +:100730002871E970617B032921D100061BD00420B8 +:10074000607319F067FA00F00F002021013020815A +:1007500098F800000DF0DAFC11E0607B84F80DA041 +:1007600002280CD02068F021407B11F001F906E04E +:10077000607B032803D12846214610F095FE012115 +:100780000836BAE798F8000001290BD1402112F091 +:1007900019FEC0B998F8000040216422BDE8F84F66 +:1007A00019F015BB40210FF01DF90C480178012903 +:1007B00009D1002101700A48007806F023FCBDE849 +:1007C000F84F12F059BEBDE8F88F00BFCEBA020054 +:1007D000AA680020A86D00209C7A0020EA2700204B +:1007E000EB27002070B58AB04FF48061041D458866 +:1007F000ADF826108189807B0894ADF82450032839 +:10080000ADF81C1034D0022806D0B0BB40F6010071 +:100810000026ADF826005AE03248007801285FD162 +:100820000DF11B0101AA204608F092FF04469DF835 +:100830001B00012854D19DF81400022850D101ADAD +:100840001421284619F06AFA274904EB44000022D3 +:100850002B4641F8202001EB800021464260427285 +:10086000FF2014228DF81400042015F0EDFE37E06F +:10087000102000268DF8270029E00DF11B0101AAA8 +:10088000204608F065FF01469DF81B0001281DD198 +:100890009DF81400022819D1134A002301EB4100EE +:1008A000CDE9013342F8203002EB8000142243608E +:1008B000FF208DF814009DF81600013000F00F00A5 +:1008C0008DF8160001AB042015F0BEFE012607A826 +:1008D00001F05AFD26B118B92846214602F04EF91A +:1008E0000AB070BDCB270020F03300202DE9F0477F +:1008F000A4B018F081FF34490A78012A04D124B049 +:10090000BDE8F04719F033BA4FF0010981F80090C3 +:1009100019F02DFAFEF7E8FE082005F0E1F921AC08 +:10092000204618F003FDDFF8A4A02A4A1021234630 +:10093000DAF80C002290264812F018FC2648002510 +:1009400001AF0478254890F800804646A64213D8A7 +:10095000DAF8000050F8261021F0FF0047F82600D2 +:10096000880707D4F0B201F0010118F0CFFC09FAB2 +:1009700006F005430136E9E7194805601948C168E2 +:1009800001F44001B1F5800F09D10068000E18BFD5 +:10099000012057F8201041F0070147F820101248B5 +:1009A000A4EB0802042307EB880103EB820240EA70 +:1009B000880019F0CFFA0D482022016862F30D215A +:1009C000016024B0BDE8F087A6270020E4B802004B +:1009D00078760020491D020017B802000BB702000C +:1009E000D0200240A84F00500010084000300940BD +:1009F000FEB5D0E9005401A818F078FC95F8340051 +:100A00003649374A384E085C95F83510515C354AFE +:100A1000084395F83610515C2A6B40EA01033168AF +:100A200020684F680299B847206840F2F272E16985 +:100A30002E4B2F4F426494F854209A5C94F8553012 +:100A4000FB5C1A430129426311D10146D4E90A2310 +:100A500051F8307FFF2A27F4004718BF07F50047F9 +:100A6000FF2B0F6009D00A6842F4804208E001467B +:100A700051F8302F22F400420A600A6822F48042C2 +:100A80000A60C16A41F01001C162016B41F00101CD +:100A90000163E16B09B3A16BF9B1012118F0EAF828 +:100AA000D5F85801E16B40680068C162C0F80415D0 +:100AB00091FAA1F17268B1FA81F153680222984764 +:100AC0007068A16B02224368D5F8580191FAA1F130 +:100AD000B1FA81F1406800689847FEBDA4BA0200EF +:100AE000C2BA020083BA0200D00100108DBA02001F +:100AF00088BA02002DE9F8430546007F04282FD16B +:100B0000A86A4678B0F802900E2E38D80C46012715 +:100B1000DFE806F008080841414141414141412ACE +:100B20002A38410031480078012833D83048807B8A +:100B300080072FD51FFA89F80021404609F01EFAD8 +:100B400000283FD0817911F0180F3BD0AA89438843 +:100B5000698900880027009200220FF08FF91AE0BF +:100B6000D32009F04AFD29E020480078012811D857 +:100B70001F48807B80070DD519F0E6F90AE00127B0 +:100B8000002408E019480078012803D81848807B21 +:100B900080071DD4012768891FFA89F2314619F0B0 +:100BA000A5F9688913F0C8F840B1A87C022805D3DC +:100BB00027B10F48A989C08A814200D1002420466C +:100BC000BDE8F88340460121012716F04BFBE2E720 +:100BD0001FFA89F8404618F099F940460DF0A6FC36 +:100BE000B0F1C50718BF0127D5E700BF24260020B4 +:100BF000A86D00202DE9F04186B018F041FF0446B1 +:100C0000002718F03DFF10B180690137FBE7DFF8DE +:100C1000C88098F80000012831D818F031FF2F4E15 +:100C2000B18C28B102888A4229D080690028F8D185 +:100C30001C2019F069F910B30546B08C2880307E6D +:100C4000A87018F009FE6871254806F1390100788E +:100C5000A87105F10C0019F002F90DF117014120FE +:100C600015F050FB1F489DF81710AC612C4600880A +:100C7000002908BF6FF001000137288100E000253E +:100C80001948FBB200210278934201D200260BE002 +:100C9000B81A0026F7B2974202D2A4690136F9E7E2 +:100CA000C6B2052E28BF05261048CDE902411049DD +:100CB000CDE900260022007803F072FC98F80000CD +:100CC00008B1012803D115B1284619F01BF916F017 +:100CD00027FF06B0BDE8F08124260020A86D002083 +:100CE000E827002088790020C77A0020C67A0020F3 +:100CF0009C7900202DE9FE4F4FF4804018F056FB00 +:100D0000A0B1354C35496068D1F8132009786FF3EC +:100D10009F5201F00401806842EA417101AA03F088 +:100D20001DF960688168012016F0EAFF2E482C4FFB +:100D30002C4D44F2020B00244FF0000A00F1400950 +:100D4000BAF1020F3CD055F82A80D8F80000A0B3C1 +:100D5000D8F80000806918F029FB0646D8F8000092 +:100D60000023324615F05CFF16F00A0F1ED0D8F8AB +:100D700000008069B9686BEA00000840B860D8F8E4 +:100D80000000C069396821EA000038601020D8F8F6 +:100D9000001016F0B5FFD8F80010484616F03EFADD +:100DA000002044F00204C8F8000006E02EB1D8F894 +:100DB00000000D4944F4804408650AF1010ABFE7C8 +:100DC00024B10A482146283019F0B4F806F0BEFFD5 +:100DD000BDE8FE4FF7F768BCD01E00208503002158 +:100DE0000C10044004BA02003021002070200020C2 +:100DF0002DE9FC473A4D0446286810B194B1BDE88E +:100E0000FC87122019F080F800282860F7D04FF6F0 +:100E1000FE720021531C1229F0D0461842520631AE +:100E20007380F8E701AB4C200021022218F0A4F9EE +:100E300000284CD1BDF80400002848D0032846D82B +:100E4000182019F061F8DFF89C90044600264FF650 +:100E5000FE784FF0020A0027032F34D028680622BC +:100E6000831907EB47000AEB400081B24C2018F0D1 +:100E700083F928BB2868815B414518BF002C1FD02F +:100E800030440022182341880620009415F0C6FB48 +:100E90002868D4E90423304402F2E932418822610F +:100EA00001EB410049F8202009EB80001822436043 +:100EB0000620234615F0C8FB2046182118F02EFF07 +:100EC00006360137C8E714B1204619F01BF8064B67 +:100ED00071200021082218F04FF9BDE8FC8700BFFF +:100EE000EC26002030750020B8260020F8B5044616 +:100EF00018F004FA07464568204617F0B7FFB8B166 +:100F0000D7E9014618F078FC0546D4F8C000B8B11E +:100F100004210174384606F005FAD4F8C800B0B1CF +:100F2000014640690028FBD1D4F8C000486112E0B6 +:100F300018F062FC0446D5F8C00078B3103034E0F5 +:100F40003068416821F002014160284630E0D4F861 +:100F5000C000C4F8C800416900274761C4E934777C +:100F6000C4E93677C4F8C01031B320463146FAF7E9 +:100F700069FFD4F8C000C4F8E0700068B0F5806F75 +:100F800003D920463146FAF75DFF94F8FE0010BB06 +:100F90003068416841F0020141601CE095F8FB00B7 +:100FA000002114F051FA05F1FC00012101702046E6 +:100FB000BDE8F84018F0DBBE94F8FB000021C4F84F +:100FC000C47014F041FA012084F8FC003068416AD2 +:100FD00021F003014162284618F0C9FE04F13000F7 +:100FE000BDE8F84018F0A8BFF8B53948394D0121DF +:100FF000394E0768E868C0680170002002F00201FD +:10100000F07003F0E040401817D096F90600012870 +:1010100002DBB0790138B07196F90500012802DBD6 +:101020007079013870712D48426803F0807082B188 +:10103000D8B10020002190470CE01446500223D480 +:10104000E00326D4A00330D50020387111F002F956 +:101050002BE050B196F90700012802DBF079013846 +:10106000F0710120307118F04BF8002038710BF04E +:10107000C3F97079F8B196F90500002823DCA86857 +:10108000D0F84C0580471EE0002038710BF0B4F911 +:101090000BE01348007820B1052018F013F813F086 +:1010A0003FFE00203871F1F72DFEA00648BF18F072 +:1010B00087FF707938B900200021B070A868D0F897 +:1010C000582400209047E8680021C0680170F8BDEE +:1010D000787A00200C0100202425002054B502005D +:1010E000A0270020B0B58CB004464089ADF80000C0 +:1010F00060684178821C019206298DF8021003D0A5 +:10110000042907D0012936D1817C13228DF80310E0 +:101110001B2101E01A211222851801440391029536 +:1011200031D0284616F0CAFF01282CD117F0E4FE72 +:101130000146284616F011FC28BB264800780128F5 +:1011400024D8684618F00CFD01281FD102980DF133 +:10115000160114F0D1F8012818D10021BDF81600AD +:1011600061721D496081097891B16168097805292A +:101170000ED101210DE00021029100F11201807ECB +:1011800003918DF81000684610F056FD0CB0B0BD0C +:10119000002100222173CDE90622ADF81800207A43 +:1011A00008928DF81D108DF81C0001208DF81A0092 +:1011B00006A8FEF761F89DF82C000028E6D10998F2 +:1011C000227A6168406C18F041F906A811F01CFA07 +:1011D000DCE700BF24260020E02700202DE9F041B5 +:1011E0000E46054610463421144618F097FD082E89 +:1011F0004ED326702146288812F030F88046688841 +:1012000008216081A888A081A879A074E87961701C +:10121000E074E07920B1102105F10800617060618F +:10122000207A28B101F1080029446070A16100E032 +:1012300008460021616284F82010617919B1295CA7 +:10124000013060706171617FF1B1421C6270295C94 +:101250000230607084F82010AA5C914284F821204A +:1012600010D9194A4F00194E1278914288BF182799 +:10127000291830463A4618F0E9F860786662384432 +:10128000607001E0002161772178C2B2914203D2FF +:1012900000263046BDE8F081B8FA88F2091A55FAFE +:1012A00080F05609A2792177A062002AF1D00E3091 +:1012B000A062A1F10E0020770548007B18F016F916 +:1012C000217F081A2077E4E7D8BA020008780020C6 +:1012D000A86D00202DE9F04105460026806A1C46D5 +:1012E000174688461680007817F0FCFA40B16889E6 +:1012F00012F022FD022811BF002668893880264698 +:10130000A86A007801380A2846D8DFE800F0060C01 +:101310001116242C45383C4A5200284641463A468C +:10132000F7F75AFE41E028464146FDF7A3FB3DE0B2 +:1013300028463146FFF7DEFB37E0287F02282BD115 +:1013400026B920486989C08A814228D13046294679 +:1013500000F068FD29E0688912F0EEFCE0B928464B +:10136000F4F7C8FD22E017486989C08A814213D189 +:10137000287F022810D128460CF008FE16E02846E7 +:10138000FCF7FCFC12E00F486989C08A814203D156 +:1013900028460BF027FA09E0D32009F02EF90026A1 +:1013A00004E0304629460FF05FFF06463046BDE8B0 +:1013B000F081054800780128F1D128460CF0B6FDEF +:1013C000F4E700BFA86D0020CA27002070B586B0E2 +:1013D0003449002808705DD1344C207830B9324946 +:1013E000097819B9082016F0DBFC207801284ED8BE +:1013F0000020CDE90300CDE9010017F06FFF0028C0 +:1014000045D02B4D05F13904204617F0A1FE18B93F +:101410002849204618F023FD05F11601532010F04D +:10142000B3FEA87B0DF11701C0F3C0008DF81700C3 +:10143000522010F0A9FE082085F8260003F09AFA41 +:1014400004F036FA1C48016809B9012101601B4803 +:101450004FF4407100780CF059FE01AC204614F0B6 +:101460007BFA20460021002616F02EF895F8410060 +:1014700010B9002005F0C6FD1148CDE90366CDE99D +:101480000166807B012802D0012014F07DFF01203D +:1014900015F08EFC0948022100780CF037FE06B0EA +:1014A00070BD00BFBF7A0020D02600202426002077 +:1014B000A86D0020B6790020182500209D7A002014 +:1014C000CC2200202DE9F84F8A468DF8030062B146 +:1014D000384851460123406802700DF1030048F27C +:1014E00031020DF0F9FF044660E00B9F1624052041 +:1014F0001E4617FB0400C0B218F006FD002854D0A9 +:10150000814604220C980A9917FB04280024CB4634 +:101510000BF8014F00F119058BF801600BF104067F +:101520008BF803708BF80210E0B2B84229D2A5F113 +:101530001701304618F093FC06F10800A5F10F01E1 +:1015400018F08DFC15F8071C861D0134017015F884 +:10155000061C417015F8051C817015F8042C41EA31 +:101560008201817015F8032C41EA0211817015F88F +:10157000021CC17015F8011C017129781A354171DE +:10158000D2E70C4D5FFA88F30DF10300514648F2A3 +:101590003102C5F804B00DF09FFF0446484618F02C +:1015A000B1FC05480130686000E010242046BDE829 +:1015B000F88F00BF88260020447000202DE9F041FC +:1015C000056804464FF0FF30E86218F015F98046D0 +:1015D00095F83000042809D13249497831B13249AF +:1015E00003228A604A6822F003024A602D4F6B6929 +:1015F0002E4E00217A68B34204D01AB979780029B6 +:1016000018BF01210023042804D11AB17B78002BD4 +:1016100018BF012341EA0300012808BF14F096FD1A +:1016200095F8320030B1404618F0A1FB4FF0FF3082 +:10163000BDE8F08195F83000042804D1381D294612 +:1016400015F0FEFD03E0381D294615F0E7FD0120E9 +:1016500085F83200404618F08AFBFCF7B7FF246893 +:1016600094F83000012811D0022812D00428DDD1CE +:101670000D4DD4E90901884210D2012018F080FBF9 +:1016800028688007F9D0FCF7A1FFF2E70020BDE849 +:10169000F081216A04F1340018F0D0FAE06ABDE864 +:1016A000F08100BF182300200880024080A90300B9 +:1016B0002DE9F04F85B0044610F000FD00286ED0F3 +:1016C00026468346471C00244FF000084FF00009CF +:1016D0009BF80000844222D2384618F03FFBD8B174 +:1016E00001790139012917D890F82000A0B10C2008 +:1016F00018F00AFC80B13946054618F0B0FB00200E +:1017000009F10109A860B8F1000F28461CBFCAF80A +:1017100008504046AA46804608370134D8E75FEAB9 +:10172000096039D002205FFA89F937468DF8100038 +:101730007088ADF808004FEAC90018F0E5FBC0B1A9 +:1017400005460024B8F1000F17D0E0B2414605EB82 +:10175000C00018F084FBD8F80860404618F0D2FBAF +:101760000134B046EEE7D8F80840404618F0CAFB0E +:10177000A046B8F1000FF6D10EE0002048F21F019C +:101780004A462B46CDE9001007F1110002A902F0EC +:10179000AFFC284618F0B6FB584618F0B3FB05B06E +:1017A000BDE8F08FF8B53B4E0446B068D0F8B810ED +:1017B000097859B194F8982004F190014AB11522A2 +:1017C00017F0B8FB58BF25229A5C09E0012121756A +:1017D00014E0252217F0AEFB58BF25229A5C023296 +:1017E00084F86A20002284F86920042284F86B209F +:1017F00004F1700228C928C209881180254615F80D +:101800002C1FB5F872200F2925F8162CB5F8742076 +:1018100025F8112C0CD0D0F80473B4F8A800294690 +:101820000023B0FA80F042092046B84700B1F8BD65 +:10183000214611F83C0FFF2801D1A06D30B1B068EE +:10184000D0F8FC22204690470028F0D1B06805F17E +:101850006402B4F89A3094F89C10D0F874530020C5 +:1018600000902046A8470028E1D1B0682189D0F82F +:101870000021D289914205D9E5206070B06800F559 +:101880001B7001E000F51E700168204688470020AB +:10189000F8BD00BF0C0100202DE9F04385B00646DD +:1018A00000200D46049017F0A7FF334CDFF8C490DA +:1018B00080462168D9F80000CB6C04AA052198471E +:1018C00001A817F001FF2D48019626F001060395A7 +:1018D00020F00107BE420AD12B490878FE281BD010 +:1018E0002068826BD9F8000091F900100EE02448BE +:1018F00020F0010086421BD123494878FE280BD0F6 +:101900002068826BD9F8000091F901109047812876 +:1019100002D01C4818F0EDF92168D9F80000002227 +:10192000CB6A01A998470546B0F1FF3F07DC03E009 +:10193000144818F0DEF9FE25124818F0DAF9BE4214 +:1019400001D1114806E00E4820F00100864202D184 +:101950000D4801300570012021680490D9F800007D +:10196000CB6C04AA05219847404618F000FA05B050 +:10197000BDE8F083E4260020347A0020BD64020034 +:10198000F14D02000C010020242500202DE9FC4728 +:1019900006680446707A00286BD0D4F80490D6F814 +:1019A0005801D0F80480D9F8347020460BF016FBAB +:1019B000706F20B306F14C05284618F0B3FA316F6A +:1019C000884221D2307902281ED0B06E002850D033 +:1019D00020460BF003FB346F284618F0A3FA201AB8 +:1019E000D6F868A0B46F7067284618F09BFA0021FB +:1019F000F1740AEB040108440190706F0CE0B06EC2 +:101A000010B1306F0028D5D106F14C0001A914F0B7 +:101A10000DFA01217067F17458B30021B0F5806FA1 +:101A2000B17384BF4FF48060706701230199014452 +:101A3000013979601049B96043F6F07101EB00108B +:101A40000840B9680843B860D9F83C10D9F80000DC +:101A500091FAA1F2B2FA82F203FA02F2D8F8003057 +:101A60009A61D6F85821526812689162012117F0E4 +:101A70000DF9BDE8FC8700BF0180000C2DE9F0479F +:101A800088B004466FF00100A081002004F1040832 +:101A90008DF8100004AD4146281D17F09EFD284624 +:101AA00009F0F6FD012809D1BDF81C00BDF812109F +:101AB000A0816088814222D004AD01E060880025C9 +:101AC000EA46ADF8020000264FF6FE7950468DF842 +:101AD000006007F0C9FA0128074608BF5646B5B1AD +:101AE000A88901210125A081204610F0C7F8012F07 +:101AF00006D1ADF802903046022110F0BFF8012562 +:101B0000204611F0D9FA284608B0BDE8F087012F29 +:101B100013D1BDF80C00A0810AF1040016F0CEFA32 +:101B2000012817D1204609F007F905463046022161 +:101B3000ADF8029010F0A2F8E2E76088484504D1C1 +:101B4000404616F0BBFA01280CD1204609F0F4F803 +:101B50000546D5E7404616F0B1FA0128CFD1204618 +:101B60000321CAE70025CBE72DE9F0438FB080467B +:101B7000374800240394CDE90144077814F0FAFEB5 +:101B80004FFA80F901ADBC4212D2E6B207200C2216 +:101B90002B4631460EF048F940B9B9F1FF3F05DC5C +:101BA000072031460C222B4614F04EFD0134EAE7A3 +:101BB0004FF0FF300C22CDE90200781E01AB85B258 +:101BC000072029460EF030F940B9B9F1FF3F05DC96 +:101BD00001AB072029460C2214F036FD04AD182174 +:101BE000284618F09BF8822018212A4617F066FF35 +:101BF000B8F1010F08BF002804D104AA82201821DF +:101C000017F062FF0AAD1121284618F087F83A2034 +:101C100011212A4617F052FFB8F1010F08BF002822 +:101C200004D10AAA3A20112117F04EFF0AAA3B203C +:101C3000112117F043FFB8F1010F08BF002804D1AC +:101C40000AAA3B20112117F03FFF0FB0BDE8F08337 +:101C5000D3BA0200B0B517F0DDFF2C4C02210025ED +:101C6000207040F60F70A17430492581C4E90755F2 +:101C70002576A0850F202071012084F86C00E07289 +:101C800040F20510A08122480078E07121480078D8 +:101C9000607021480078A07020488078A0732048A8 +:101CA000007820826FF00100A0846083E0821D48EC +:101CB0000078E0741C480078207504F1390018F0B1 +:101CC000CEF840F20F5004F16E030021022284F896 +:101CD000415084F86850A4F866001548007884F8EC +:101CE0006A001448007884F869001348007884F882 +:101CF0006B00892017F040FA08B1A4F86E5000205C +:101D000010F044F8A4F87050B0BD00BFA86D0020DA +:101D1000C7270020DF270020D42700203E7900209D +:101D2000D3270020E1270020E227002025260020DD +:101D3000CC270020CD270020CF2700202DE9F04F11 +:101D400087B082462420994614460F4618F0DCF8E6 +:101D5000002800904DD0DDF844802421054617F07E +:101D6000DDFFDFF8B8B09BF80000012813D8384633 +:101D700017F097FF50B1007940F00200032802BF2E +:101D80004FF4806020EA081048EA0008DDE91232CA +:101D9000C8F3802602E0DDE9123200262048ADF8C3 +:101DA0001840109C0221808C2F8029722973688131 +:101DB0000098ADF80A808DF80C404473C0F820A05C +:101DC00080F81F908DF81A30D2E90001CDE90401A6 +:101DD00068463146FDF72CFE012807D19BF800101C +:101DE00049B10020B6B1012906D013E0009818F0DF +:101DF00089F810200EE066B1204616F0ABFE40B127 +:101E000004460068008818F0E5F810B1204607F095 +:101E100033FF002007B0BDE8F08F00BF242600206C +:101E2000A86D00207FB5044600200D46ADF80C00DB +:101E30000290CDE90000886A4078C10604D0D32022 +:101E400008F0DBFB00244AE0820641B244BF0122D5 +:101E50008DF80C20B1F1FF3FDCBF01218DF80B1094 +:101E6000400605D4287AE8B105F11800002107E002 +:101E700001208DF80A00E879D8B105F1140001219C +:101E8000066836B168463146023017F0E8FF9DF823 +:101E90000A10A8890129ADF8000006D1B6FA86F12A +:101EA0004E090AE0A889ADF8000068460EF064FC0F +:101EB00015E0A8890126ADF800001049097871B134 +:101EC000012902D10E4A12784AB1022903D10D49E3 +:101ED000498B884203D1688911F02EFF10B120464A +:101EE00004B070BD002EE0D117F006F86846064930 +:101EF000023015F032FD0028D7D1F0E7242600206B +:101F0000D9270020A86D0020E07900202DE9F04FAE +:101F100085B0894619461F461446054612F0E2FD73 +:101F20003249DDF840800978884207D2304900EB19 +:101F3000800001EB4000B0F804B001E04FF6FE7BFA +:101F400018F0100A4FF0100008BF082018F0200108 +:101F5000019118BF08308DF8110004A814F0C0FDDD +:101F6000002840D0064601200094B07716F0C4FF48 +:101F7000706202AC5846214613F0CEFE18B1012023 +:101F80003462707705E0BAF1000F02D00E9CAB45C9 +:101F9000F5D034694FEA1920A071280A84F8059019 +:101FA000E570A77084F801802071022020705846E7 +:101FB00012F012F80099BAF1000F0844E07101D153 +:101FC000082005E00E9904F1080017F048FF1020E2 +:101FD000019919B10F99204417F041FF3046A6F836 +:101FE00002B00CF009FD05B0BDE8F08FD5BA0200D3 +:101FF000B25C002070B59EB0314D0021742228786B +:102000000130287001AC2120234617F0B5F828785C +:10201000742122468DF80400212017F055FD294E29 +:10202000294C3078A178814206D2002012F060F865 +:10203000012801D1042000E00D2015F0B1FEA98C8B +:1020400001204FF6FF72914237D0E98A4FF6FE72B7 +:10205000914232D01D480078022803D31C480078F2 +:10206000012808D101200DF103018DF80300522051 +:1020700010F08AF804E04FF400500121F9F7FAFB60 +:102080001448007818B13078A17881420DD201202F +:1020900012F02EF8012808D10020297EE0700E48A9 +:1020A00017F068FEA178013106E00120297EE0707A +:1020B000094817F062FE0021A1701EB070BD00BF7C +:1020C000A86D0020C9270020AC2200202426002073 +:1020D000E5270020C8270020AE79002070B596B013 +:1020E00004460079042805D13348007810B117F070 +:1020F000F5F810B1C22016B070BD3048016809ADC6 +:10210000284617F0ACFE2168284615F0C8FF0028C5 +:10211000F0D020680DF102010BAA07F019FB9DF821 +:102120000210C2200029E6D09DF83C100129E2D11E +:1021300005AD4FF481700021102200262B4617F0C8 +:102140001BF8032008212A468DF803000DF1030037 +:1021500001AB0DF061F84120CDE9106612968DF8C3 +:1021600054608DF842004FF48D70ADF8440010A813 +:10217000FDF782F89DF854000028BBD11398456CF8 +:102180000F2028702079687016F0B6FE09AC014661 +:102190000822204617F05AF9A81C214617F05FFEC6 +:1021A00005F10A0001A9102217F050F910A810F04B +:1021B0002BFA9DF854009EE724260020EC580020BE +:1021C000F8B51446A0F19802062A0AD80FF20401C5 +:1021D000DFE802F0041111111A1D31003048807C33 +:1021E0002CE08B282DD0872844D0802803D12C4880 +:1021F000808C208023E081283AD3D82838D82849F9 +:10220000084410F8810C19E014F0F2F916E02148A6 +:10221000007801282CD82048204A4FF6FE7300256C +:10222000017800208D4209D232F8086B9E4218BF17 +:1022300001300135F6E71A4890F82600207000209A +:10224000F8BD14480078012812D81348134A002317 +:102250004FF6FE7500260078864213D21788AF42EB +:1022600003D0DFB28F420FD0013301360832F3E7DB +:10227000C920F8BD084612F0BFFE18B1014620463D +:102280001C2204E0C120F8BD11462046082217F0A8 +:10229000DDF8D4E724260020D6BA02004C500020F6 +:1022A000A86D00202DE9F04387B004460846994602 +:1022B00090460E4616F059FD304614F09EFA2E4F09 +:1022C000386858B10320314608228DF8100002AD5D +:1022D000284617F0BBF83968284688472748007811 +:1022E00001283AD80220ADF80A4003968DF8100074 +:1022F0000020ADF80800304617F030FDB9F1000FAE +:1023000027D128B9204631460DF096F9AA2820D1C8 +:1023100016F0E4FFE8B905AAAB2000210CF0F0FDAF +:102320000DF107013046002207F012FA1448007838 +:10233000012808D19DF8070028B900208DF8110068 +:1023400002A80AF0AEFD01208DF8110002A80AF0E3 +:10235000A8FD3046414613F0D7F82046002114F07E +:10236000B4FE0848818C204613F0A5FD15F038FB1B +:1023700007B0BDE8F08300BFF8230020242600202A +:10238000C2270020A86D002070B586B00446807A70 +:1023900058B9E07AC00608D43048C825007801282A +:1023A00053D12D48007801284FD1616820880DF164 +:1023B000160213F065FFA07A98B12B4E306A70B107 +:1023C000208861686D460822ADF80000A81C17F04F +:1023D0003DF82089316AADF80A0028468847002573 +:1023E00036E0E07AC10602D4C0F380001FE01C484A +:1023F0001C490078097808431AD100206D46142141 +:102400008DF81500284617F089FC60680DF115015C +:102410002A4607F09DF99DF81500002818BF0120F5 +:102420009DF810100239B1FA81F14909084028B12C +:10243000204609F03FFD054620B9BEE7E07A0007D7 +:10244000BBD4AD25606814F0D8F9204604F01AFF1B +:10245000284606B070BD00BFE7270020A07A002004 +:1024600004250020BE27002054750020BCB504467A +:102470004089410622D432490978012927D83149B7 +:10248000897B89072ED523684021228B01EA901190 +:1024900018881B6A9D8800914FF6FE73294602F04A +:1024A00045FCA84202D0218B884217D12068022225 +:1024B00000230188284609F0C4FC13E02068008846 +:1024C00011F03AFC40B16FF0010001300CE002293C +:1024D00008D117F0B5F901E0206800884FF6FE71C9 +:1024E000884201D1CD250FE02168088080B211F02B +:1024F00023FCB0FA80F0226813494009D0811046CD +:1025000007F05AF8054630B120682946407B0FF0A5 +:102510002FFA90B90CE00A4800250078022807D16C +:102520000A48007820B920200121F9F7A3F90025F5 +:102530001CB120460121FDF77BFA2846BCBD00BF37 +:1025400024260020A86D0020914F0200E5270020DE +:1025500070B50446C80711D1880758BF70BD324C0A +:102560001C200021A0471D200021A0471E20002183 +:10257000A0472E4C2E4D1C2021463DE02A4E1C200B +:1025800000211546B0471D200021B0471E20002124 +:10259000B04720460AF06AFA2988C60F40F60200C2 +:1025A000224C814206D043F60700814204D0B1F5A7 +:1025B000C15F14D1E87B01E095F8240040060ED0FD +:1025C0001C202146002205F0EDFE1D20214606B309 +:1025D000322205F0E7FE1E2021462F221FE046B1E1 +:1025E000134D1C2021462F22A8471D2021463222B0 +:1025F00007E00F4D611C1C200022A8471D2021462A +:102600000022A8471E20214600222B46BDE870402C +:102610001847002205F0C6FE611C1E200022BDE8FE +:10262000704005F0BFBE00BF0D93020000600020A7 +:10263000A58301002DE9F0418EB004464A1E00201A +:1026400012F1030F0AD809AA0490029107922F4AA7 +:1026500006928DF814000222684600E003220C90D6 +:102660008DF834202020EFF3118680F31188608AE2 +:1026700030B1608A01386082012086F3118842E01F +:1026800000293DD02248012104F1140790F8088068 +:102690000172806909AD45620B9011F09FF9A06944 +:1026A00009970A900560A5619DF83400022808D1B9 +:1026B00018494A680C98016042601060486005F053 +:1026C00095FD86F31188404611F0A6F92021EFF31D +:1026D000118081F311880C9939B10A684B681A602E +:1026E0004A6809684A6000210C910B9900224A62ED +:1026F00080F311889DF83400002818BF012002E003 +:1027000086F3118800200EB0BDE8F0816752020008 +:102710003822002008200020B0B504463048007858 +:10272000A8B130488068006C0068007D78B144B181 +:102730001B2C06D0E92C0AD12B484088B0F5105F3D +:1027400005D12948C07B16F0BDFC12F0E9FA2748F4 +:102750000021017026480170A4B922488068D0F891 +:10276000D41091F85310882908D0224909780529F6 +:1027700008D1006C0068C08A400703D417F096FBAC +:102780001D494860174DA868D0F8B8100A7872B192 +:10279000496C61B120468847E868C068007898B9FC +:1027A000A8680021D0F85824002090470CE0D0F809 +:1027B000AC00007808B90EF06FFB0DF069FDA86859 +:1027C000D0F8701220468847A868006C006818B1DD +:1027D000007D352808BFB0BDBDE8B04016F090BC04 +:1027E000A02700200C010020C07700202D2600200B +:1027F000B87A0020BB7A0020602600202DE9F04343 +:1028000087B0044600200D4631498DF807002F4857 +:1028100009780078084301D1012452E0F4B1EDB108 +:102820000DF108080DF107012846424606F090FF19 +:1028300081464FF6FF70814521D09DF8070078B1A1 +:102840009DF8180060B99DF81B001022234600F087 +:102850007F01052013F0F8FE002432E0022430E06E +:102860001C4800260788B1B2B94208D205201022C0 +:1028700023460DF0D9FA092803D00136F3E7B22434 +:102880001FE008F108002946082216F0DFFD46F097 +:10289000800000244946142243468DF81B00042082 +:1028A00003948DF81840029413F0CEFE0A4909EB08 +:1028B000490041F8204001EB80000121C0E90144BA +:1028C0004172204607B0BDE8F08300BFBC2700205E +:1028D00024260020BEBA0200F03300202DE9F04784 +:1028E00088B006461398DDF840A01D4691468846FC +:1028F00050B1149C4FF6F777601E80B2B84204D3F3 +:1029000017F088F90446F7E70024C120BAF10F0F49 +:102910004DD111990F294AD1264F129887F82F00CF +:1029200040F60F7087F82E50C7F82890B8854FF6FC +:10293000FF7086420AD120494FF6F77008300E88A2 +:1029400080B2864202D117F065F90646B8F1000F51 +:10295000BE8409D0404616F0FBFB012804D107F1E4 +:102960003900414617F07BFA07F13905284616F081 +:10297000EFFB18B9E220294613F0C4FC0020FC82CA +:10298000182187F83800788340F60F70B885052045 +:1029900087F8260001AC201D17F0C0F9B86A019035 +:1029A00097F82E008DF8090020460CF00BF908B0BE +:1029B000BDE8F087A86D0020902700202DE9F8439E +:1029C00015460C46804608F0A7FA2C4800212D4FEA +:1029D00001602B4881460068386881692720884754 +:1029E000294E2A49306B08403063B06F20F4807064 +:1029F000B0673868016B4FF4806088473868016BB6 +:102A00004FF4816088473868016B4FF4C060884795 +:102A10001F48012101601F48C6F8804131600168EC +:102A2000890704D4691C08BF4FF04045C560D9F838 +:102A30000000F0698007FCD507200FF0C9F90228D3 +:102A4000FAD1B8F1000F13D1134C386A81682046CF +:102A500088470428F9D0012804D1386A0321426844 +:102A600020469047D6F8180220F00300C6F8180256 +:102A70003868806BBDE8F843004700BF0C40094050 +:102A80002C200940B80100100C200840FFFFFEFE7A +:102A900028200860100009400040034070B520392C +:102AA000062918D8DFE801F01A23042D3840480021 +:102AB000147800222321FF2CF1D0D0E9015695F89B +:102AC000FB0010F035FB726B2B49204685F8FB406C +:102AD00005F068FC49E06FF001044AE0406890F8B6 +:102AE000F910012943D1012180F8FC103DE045682F +:102AF0000021002495F8FB0012F0A6FC85F8FC40AC +:102B000037E0446894F8FB00FF282ED010F010FB4B +:102B1000FF2084F8FB0028E04068D0F8C01031BBEB +:102B2000012180F8FE1020E04068D0F8C010F1B913 +:102B3000002480F8FE401CE04168D1F8C020B2B10A +:102B400091F8FE209AB180680268D0E90430546A96 +:102B5000184344F003045462D1F8CC104968096862 +:102B60008862506840F002005060002401E04FF09D +:102B7000FF34204670BD00BF026000202DE9FF41F8 +:102B800005464FF6FE70854222D00C4601B3DFF8B1 +:102B9000C480D8F80C7007B3B91C2046082215F081 +:102BA0009FFB60B198F830000026B87211E0B11CAC +:102BB0002046082215F094FB0028374645D1FE68D0 +:102BC000002EF4D1102017F09FF9F860A8B93AE070 +:102BD0000226304604B0BDE8F081102017F094F9C9 +:102BE000C8F80C0078B31C484FF400614FF47A72B7 +:102BF000007817F0ECF8D8F80C0098F830100026A0 +:102C00000580851C0822C66081722846214616F080 +:102C10001DFCD8F808000028DBD001AC29460822AA +:102C2000601C16F013FC04F10A01284613F08BF81F +:102C30000948092100220C238DF8046000940078D3 +:102C400010F0DFF9C5E70126C3E798F83000B0724D +:102C50000026BEE7AC220020A37A00202DE9F84F21 +:102C600016F00EFF2F4D2C4644F8100F16F002FF01 +:102C70000027206818B100F118040137F9E72C6922 +:102C8000002C46D04FF6FE70DFF89CA0DFF8A0B015 +:102C9000DFF898900026FDB201301FFA80F8F0B2FC +:102CA000A84235D2504616F053FA012806D104F155 +:102CB0000C01504614F051FE38B922E0B9F800007A +:102CC000404502D0218881421BD12089BBF81A10CF +:102CD000884203D14FF6FE71884208D1154800782A +:102CE000022801D2E07801E001D1207948B19BF8B7 +:102CF00012006179814208D10F48A17900788142A0 +:102D000003D0204611F0D4FA013FA4690136C6E78A +:102D1000044D6A6922B12869F9B2BDE8F84F10473D +:102D2000BDE8F88FAC220020AE790020902700206B +:102D3000A86D002024260020E8270020B0B52F4CE5 +:102D4000608810B12E49098814E02E494FF4707242 +:102D50008968D1F8F410C98F02FA01F12A4A01F505 +:102D60007071127851434FF47A72B1FBF2F1244A38 +:102D7000118089B288421AD225492448096800681E +:102D8000096C88472278C1B2914288BF2070608860 +:102D90000130608017F088F84FF47A711E4B0022E2 +:102DA000B1FBF0F01B49BDE8B04007F0A7B894F9BB +:102DB000000013F08BFD134901258A68D2F8F42036 +:102DC000936992F8442098548868D0F8F40090F8F9 +:102DD000442000EBD20002F00703427905FA03F326 +:102DE0009A43427100202070608088680421D0F8E6 +:102DF00094000078BDE8B0400BF088B94C24002066 +:102E0000425E00200C010020B47A0020E42600205D +:102E1000347A00203D2D01005C7A0020F8B516467A +:102E20000F46054616F0E8FC0446092F3AD8DFE8BD +:102E300007F00508111417313B1B4B2C3068286034 +:102E40004AE001206876D5E9040160306031C5E9C7 +:102E5000040141E0306868833EE03068A8853BE0CB +:102E600030682249886037E01F4820490025806B80 +:102E7000097E91BB88BB1E483168283016F032FCB1 +:102E800031681C4816F02EFC26E02020314614F054 +:102E900037FF21E0306801281BD018B9802015F0D9 +:102EA00057FA19E0032518E00F4810490025806BF8 +:102EB000097E91B988B93168192015F0A1F93168F6 +:102EC0001A2015F09DF907E03078064981F8600076 +:102ED00002E0802011F0D2FD8325204616F047FF46 +:102EE0002846F8BD206E002030210020D01E002092 +:102EF00070200020407200202DE9F84F9346426870 +:102F00000546936803EA0100884255D1D5F808A028 +:102F1000DAF804408C429CBF6FF00300BDE8F88FE4 +:102F20000BEB01066FF00500A64247D803EA0B033E +:102F30005B4543D1BAF82000DFF89490E846C9F821 +:102F400008005068C9F80400DAF800004618BBF120 +:102F5000000F39D028460BF0BFFE88BB284612F080 +:102F60005BFD68BBBBF5803F05D3B0B218B94FF429 +:102F70008034D82002E0DAF8084020208DF80000E4 +:102F8000300AB9F808108DF803608DF80200300C93 +:102F90008DF80100284616F00CF9404604210CF08B +:102FA00071FEB9F808100746284616F00BF93FB92C +:102FB000ABEB040B2644CAE76FF00400BDE8F88FC2 +:102FC0004FF0FF30BDE8F88F0020BDE8F88F00BF5C +:102FD0000C240020F0B50022C1F802204A73838D32 +:102FE000027F4B83C3890A754B81836A1C4614F8A0 +:102FF000015B15F003060D7003D0032E45D0022EA1 +:1030000028D105F00C060C2E05D015F0100702D1C2 +:103010005C788C709C1C082E02D101260E7306E091 +:1030200000270C2E0F7302D134F8020B08E046790A +:1030300006F00306012E04D145F00C0540890D7001 +:103040008880E80606D42088C880608808812079B6 +:103050000534C870204610F8016B4E756EB2B6F19B +:10306000FF3F0BDD00244C700861181A1318404212 +:103070004873D8B20B75824207D3F0BD607803283D +:10308000487002D828B1032805D10020087548737C +:10309000F0BDA01CE8E7A078C87505F00300022881 +:1030A00011BFE01CE0780876201DDDE7F8B5044686 +:1030B000807A022851D1A07BE0B12948006800281D +:1030C0004BD026480078012847D126480078C00711 +:1030D00043D0042014F032F900283ED001464FF4CA +:1030E000B2700880608848801F480078BDE8F840CA +:1030F0000CF03AB82048016879B11E4F386860B1C9 +:103100001B4E306848B1194D286830B1134800781B +:10311000012802D16088884730B1608801210122EE +:10312000BDE8F84000F02EB81448007830B11449DA +:1031300051F82000C0EB0010810001E01048016848 +:1031400060883A689047012807D1608831688847CD +:1031500060882968BDE8F8400847F8BDCA27002004 +:1031600084230020DC2700209C7A00209823002064 +:103170009C2300209423002088230020D7270020B0 +:1031800090B402002DE9F84F14460E46824614F022 +:10319000CDFAD6B3C8BB2B4929480126009409783B +:1031A000043051B10278FF2A03D030F8042C524584 +:1031B00004D0243001397600F3E700262248254F59 +:1031C000DFF894B06FEA06090025047800205FFA62 +:1031D00085F8A04518D217F8081099B15BF8282097 +:1031E00032420FD0084615F0B5FC50B1417B05299D +:1031F00007D15BF82810254601EA09014BF8281091 +:1032000000E000200135E2E7009C70B1417B052918 +:103210000BD10168A1F800A0012141730B482021C6 +:103220000078BDE8F84F0AF071BF34B10848818CCE +:103230005046BDE8F84F0EF0E7BABDE8F88F00BF82 +:1032400020450020E3BA0200CEBA02009C7A00209A +:10325000A86D002058760020306D0020F0B5314A6E +:10326000046A516B137D0C61446A01F1200C032B3D +:103270000B704C61846A8C61C46ACC6190E8F00088 +:10328000ACE8F00000F1400400F110074C64F0CF0E +:1032900001F1300CACE8F000046B0C64446B8C64FE +:1032A000846BC06BCC6408650BD8DFE803F0020DBB +:1032B0001016156DC4B2106C936C55F824404C6018 +:1032C0000FE0002000230CE01748406D06E017488F +:1032D00080694860D0E90A3003E000204860106C43 +:1032E000936C926BC1E9020332B12BB110F8014B20 +:1032F000013B02F8014BF8E70D4802684A6590F877 +:1033000024208A6590F82520CA65C28C0A66826AE4 +:103310004A66C26A8A66026BCA66426B0A67806B3B +:103320004867F0BD381F0020A01F00203822002071 +:1033300004ED00E07CB500208DF8070016F02CFEAF +:1033400029494FF0FF32294D294C097802FA01F141 +:1033500088432880A068D0F8B800017841B3826B18 +:1033600032B30DF1070142F21A009047214E307836 +:10337000B8B17078A8B99DF8070090B1A068D0F8EE +:10338000B800C06D68B1804758B1E2681A49526808 +:103390000978127808325143B0FBF1F029880844CB +:1033A0002880288871789DF8072011FB020028806A +:1033B0001248007810B116F0F5FD01E016F0F0FDAE +:1033C000A068006C006840B10D48007810B90D4845 +:1033D000007818B10C48022101707CBD0A48832195 +:1033E00001700FF071FD7CBDB97A0020C679002014 +:1033F0000C0100202D260020B47A0020BB7A00208A +:10340000B07A0020B37A0020B87A0020F8B5304DA9 +:10341000212074212A4616F051FB80B100240FF0C0 +:1034200033F92D480078012898BFFAF70DFF2B4893 +:10343000006800B180470CF0A7FB2046F8BD2120B2 +:10344000002174222B46002415F096FE0028E6D1B8 +:10345000E88A4FF6FE718842E1D095F826000828E8 +:1034600001D0042831D10DF103061A4F0124422066 +:1034700031468DF80340B84705F12F014320B84786 +:1034800005F12C014720B84705F11C014A20B84737 +:1034900005F11A014B20B84705F124015020B84727 +:1034A00005F116015320B84705F12D015420B84706 +:1034B00005F11801E120B847A87B3146C0F3C000F0 +:1034C0008DF803005220B847A9E7FEF7C3FBA5E734 +:1034D000A86D002089210200242600200424002059 +:1034E000F0B58BB0054602208DF829000AA813F02C +:1034F000F7FA002857D00446006946F2040101801B +:103500000120A077A07615F0F7FC2848658060625E +:10351000E07E20B926480178E17601310170207EF5 +:10352000234F012805D1F87A18B9207808B900206E +:1035300020760DF127012046F8F7ECFD80B3054613 +:10354000242016F0E1FC029038B32421064616F040 +:10355000E5FB0DF10601502012F0D4FEF88ABDF80B +:1035600006109DF82720ADF820006088718130801A +:1035700002203073307202980562617DC2770122A9 +:10358000C28141738DF81410E08AADF8120002A8D0 +:1035900016F07CFA029816F0B5FC284616F0B2FC3C +:1035A000204616F0AFFC0BB0F0BD00BFE079002064 +:1035B000A86D0020F0B589B0304CADF8221015464A +:1035C00007460E9AC22094F82610ADF82020042950 +:1035D00052D0082950D04FF6FE70824201D1C3204C +:1035E0004AE001A81C211E4616F098FB03200DF1AD +:1035F000220184F8260050200EF0C6FD08A94B20B9 +:103600000EF0C2FDBDF8220039462576A673A084CF +:10361000BDF82000608304F1390016F020FC06F0AC +:103620004E0080308DF81E0015480078012803D820 +:103630000F98013084F8380002208DF80F500F25C4 +:1036400021468DF81A00BDF8200001F82D5FADF875 +:103650001200BDF82200ADF81C0000208DF80C000F +:1036600054200EF091FD04F82C5F472021460EF007 +:103670008BFD01A803F09CF809B0F0BDA86D0020F7 +:10368000242600202DE9F04F89B00E46814601A87E +:103690002021904616F042FB202E08D0182E09D08B +:1036A000102E0CBF4FF0010A4FF0000A04E04FF05B +:1036B000030A01E04FF0020A0125234F234805FACF +:1036C00008F47C608346006841692720884703200E +:1036D000C7F88053C7F88403C7F80053C7F88803B6 +:1036E000B868824518BFC7F808A0182E3C6008D1FA +:1036F00001AE49461822304616F02CFC30462021F7 +:1037000001E048463146002200230FF001FE104838 +:1037100013F0BAFD0546DBF80000016A2720884750 +:10372000DBF800000169272088470020B0EB957F77 +:1037300006D17868C04320FA08F000F0010000E0EC +:10374000012009B0BDE8F08F00440240B001001034 +:10375000030000C070B52548066813F0FDF9244841 +:103760000025244C0560206C806C8047224800684E +:1037700038B122480068B6F1FF3018BF304602F079 +:1037800007FB1F4840F2391205601E48016862F3CA +:103790001B4101601C48016801F44051B1F5805F94 +:1037A00006D10168194A114001F50032026001603A +:1037B000174D0126EE612068016A142088471548DC +:1037C000016841F4E021016013482E60006800F4B4 +:1037D0004000B0F5000F03D1206C416C0F488847C2 +:1037E0000F4801680029FCD170BD00BF1C130050B8 +:1037F00084046042B001001080012843800520430A +:103800008C2108404820034028000940EFFFFCFCC1 +:103810000000244300200940B44F0050BD3786000B +:103820000C00684270B5F8B1012858D1012016F09B +:103830008BF8012853D02D4C94F8380100284ED134 +:103840002848294E0569306810F4402F30D17DB3E7 +:1038500014F006FA502016F093FA0120A84704F15C +:10386000940016F02BFB25E016F050FB1E48006874 +:1038700010F4402F0AD11B4804693CB11B48943016 +:1038800016F06FFA14F0DCF90020A047174C94F8FA +:10389000380120B31648016821F0800101608021C1 +:1038A0008160032011F0D0F8002084F8380116E080 +:1038B00016F030FB012084F83801306810F4402FF6 +:1038C00000D14DB9207A800606D409488021816054 +:1038D000016841F080010160032011F0EDFE00203D +:1038E00070BD00BF18B80200B44F0050D81B0020B4 +:1038F000902208402DE9FC470446E820002C59D0CE +:103900008A46002956D06068DFF8B49000260DF191 +:103910000408411E61603F2100F8011CA16D606830 +:10392000B1FA81F1421E49096260C90100F8011C27 +:103930000220A4F85400208902302081022E36D0C3 +:103940001AF836002A2802D0FF282ED12FE00AEBE1 +:10395000C605686848B3D9F80810D1F8B810896965 +:10396000884707466068C01B606069684A0707D4DB +:10397000D9F808200023D2F8B820D56922460AE0F9 +:10398000D9E902239B68D2F8B8201B78D569224672 +:103990008DF804304346A84770B12089384420810F +:1039A000B4F854003844A4F854000136C6E76068FF +:1039B00020650020BDE8FC87EB20BDE8FC8700BF48 +:1039C0000C010020F8B52B480068C06B80472A49DD +:1039D0002C4B09681B68411A284800788200B1FB0B +:1039E000F2F1274A12688B4201D9934202D38A42EC +:1039F000134623D9591A4FF00003A1FB001263F1BB +:103A0000000303FB0020204A1268538B12691A44FA +:103A100064328D1A60F10006681E76F100000DDB3D +:103A200016F042FA07462846314600233A4615F07A +:103A30000DFB0446E81B76F1000001D2012015E0E1 +:103A400016F0E3F8114E0546306816F033FA10B15F +:103A5000306816F086F9284616F0C5F93068214618 +:103A600016F02AFA306816F029FA00200849087082 +:103A7000F8BD00BF347A0020307A0020B47A0020EC +:103A80003C7A0020407A0020E426002034270020E1 +:103A9000B67A0020B0B586B00446008810F04CF924 +:103AA00010B915F01BFC08B106B0B0BDA178207AA2 +:103AB00039B30428F8D129480DF10301006801AA9F +:103AC00005F046FE01469DF803000028ECD09DF865 +:103AD00014000128E8D19DF917200020CDE901004C +:103AE000002A03D401208DF81500FF208DF8140062 +:103AF00001AB0420142212F0A7FD022015F084FF70 +:103B0000D2E70428D0D115480DF10301006801ADBA +:103B10002A4605F01DFE04469DF803000028C3D088 +:103B20009DF814000128BFD102208DF814009DF9E2 +:103B30001700B0F1FF3F03DC05F1130010F01CF893 +:103B400001AB04202146142212F07EFD002015F066 +:103B50006DFF01200121F0F751FEA5E7EC58002090 +:103B6000F8B515460E46044610F0E6F808B10020F8 +:103B7000F8BD204600210DF0BBFC294606F0FEF9F9 +:103B8000C8B107464079032807D00128EFD17888CB +:103B900007210FF08DFE0028E9D1B87910F0180F39 +:103BA0001AD07888214600224FF6FE7300903046E6 +:103BB0000CF064F934E0204614F0E6FB16F071F8DE +:103BC0000028D4D04179CA07D1D08A0706D441F061 +:103BD00002010127417109E0022707E03046214632 +:103BE0000122012709F05AFE0028C0D030460021EA +:103BF0000DF07EFC0B49C98A884206D10A48294645 +:103C000002782046FAF7A2FE0AE0304621463A46FC +:103C100009F044FE0028AAD12046294613F055FA9F +:103C20000120F8BDA86D0020CABA02002DE9F84FA6 +:103C3000DDF82CB088468DF80300042015211E46BF +:103C400017461BFB0100012151FA80F016F05CF9C8 +:103C5000002849D081460C990A9800240425CA46B8 +:103C60000AF8017F8AF802008AF801600AF104006C +:103C700001F10C068AF803B0E1B2594521D2A6F150 +:103C80000C07394616F0EBF8397A0170B97A4170B1 +:103C9000F97A8170397DC170397D032908D10430EA +:103CA000314616F0DCF8B17A153500F8011B05E055 +:103CB00031780E3501717178417106301836013452 +:103CC000DAE70B4EEBB20DF10300414648F2330246 +:103CD000C6F804A00BF000FC0446484616F012F9A2 +:103CE00004480130706000E010242046BDE8F88FE1 +:103CF000882600204470002070B5314B04255C6894 +:103D000059B952B1D379157B2B440C2505EB4305EA +:103D1000EBB2502B84BF102070BD2170EBB28169D3 +:103D2000052B0978617081694978A17023D3291F17 +:103D3000E1701178217191786171D178A171117957 +:103D4000E17151792172917901F00F016172D1799C +:103D5000A172D57995B10021A9420FD2956815F8C5 +:103D60001150E572956805EB410501316D782573B9 +:103D70000234D579F0E70021E17016E004F10B017F +:103D8000147B0C70157B85B10024AC420DD21569F3 +:103D900001EB440615F814507570156905EB4405E0 +:103DA00001346D78B570157BEFE700F11102811CCD +:103DB000104648F20402BDE870400BF08DBB00BF16 +:103DC000882600207FB504464078DB3818280CD8B8 +:103DD000012101FA00F02C49084206D02B488068E6 +:103DE000D0F80412204688477FBD284EB068D0F82E +:103DF000FC112046884750B9607C38B194F83400F3 +:103E000020B9B068D0F8B810097811B100206070FE +:103E1000E4E7D0F8342204F1120109209047002889 +:103E2000F4D00546B06804F10B01D0F83024E72047 +:103E30009047B06804F10801D0F830245020904732 +:103E4000B06804F10A01D0F83024E1209047022044 +:103E500023894FF6FF728DF80C004FF0FF30ADF85C +:103E60000400B068D0F8C061A07A009001A928468B +:103E7000B047A0F1DB011829B6D8012202FA01F1FE +:103E8000014A1142C3D1AFE7112000010C0100200B +:103E90002DE9F8432020EFF3118980F311882C4895 +:103EA0000068006B80472B4E4FF000082A4F01221C +:103EB00086F85D8086F85C20D7E9104522462B46BF +:103EC00015F0C4F8A0FB042300FB053301FB04310B +:103ED000746DC7E91221B168B268611A821A914201 +:103EE00005D986F85C8089F31188BDE8F883051B45 +:103EF00089F311880020854206D304442D1A01203D +:103F000021460AF073FBF6E72021EFF3118781F3D6 +:103F1000118896F85D1019B1002021460AF066FB61 +:103F2000411C05D0411BB06D814238BF084600E0FE +:103F3000B06D011914F03EFE002086F85C000120EF +:103F400086F85E00B46087F31188BDE8F88300BF8F +:103F50008C01001008200020886E0020F0B585B08C +:103F60000D4600211446CDE90311CDE9011101A947 +:103F7000009104A903AA02ABFBF742FC029F002FA9 +:103F8000394618BF0121019E0140002E324618BF5C +:103F900001221140002D10D411B3049840F22B21BE +:103FA00005806FF39F5538462A4613F07BFA039835 +:103FB000314608F0ABFF676010E0C9B104984FF0DC +:103FC000FF316FF39F552A46018030462B2113F0B5 +:103FD00069FA0398314609F0CBFB666015201EE0B4 +:103FE000C8B104984FF6FF720188914214D110E0D5 +:103FF00078B16FF39F5503982B212A4613F052FA9C +:10400000FF2806D004984FF0FF310180142065602E +:1040100005E0032005E004980580658010202080DD +:10402000832005B0F0BD7047B0B588B0C1890446A3 +:10403000A1F1210002281ED3A1F50040022826D3B9 +:1040400048F22100081A022832D2274800780028B6 +:1040500047D126480068002843D048F221020220B8 +:10406000914208BF0320A169627C097808B0BDE8CD +:10407000B040F6F7F3B9207B98BB6D462046294641 +:1040800010F052F820462946F9F742FD29E0204673 +:104090000AF0CCF828B30446007818B96088211DCE +:1040A00014F0D4F9204608B0BDE8B04015F02ABF9E +:1040B000202916D10C48007898B96D46204629462B +:1040C00007F036FA2846F7F711F89DF8120010B1FC +:1040D000059815F017FF9DF8180010B1079815F016 +:1040E00011FF08B0B0BD00BF2426002044270020E7 +:1040F0002DE9FE4F8946097A2D4CDDF830A0174690 +:104100001D464FF000080F29666804BF4FF6FC718A +:10411000A9F8001048F21F018A45029011BF4FF024 +:10412000010B002006F8010B4FF0020B30460BF19B +:10413000500100F8017B0191B8F1090F14D86178A2 +:1041400005EBC10115F08BFE617808F101080BF158 +:10415000080B01316170C9B2B942EDD1002086F877 +:1041600000806070029C19E00A2030706078B842CC +:1041700012D2BAF11F0F08BF13F0DCF948F21F008A +:104180008245DDE901B409D10A484FF480410A2291 +:10419000007815F01FFE01E0DDE901B45FFA8BF352 +:1041A00020464946524603B0BDE8F04F0BF094B9A3 +:1041B000882600209D7A00202DE9FE4F994615465D +:1041C0000F46044615F070FE4FF47A71B1FBF0F023 +:1041D000454315F01AFD80462046394613F040FE4F +:1041E000AB4688B10646006815F0BBFD30685946FD +:1041F00015F062FE306815F061FE0824404615F0A7 +:10420000F2FD2046BDE8FE8F142015F07DFE00284B +:10421000F3D0EA460646504615F0A7FC0120029668 +:10422000594652468DF80000B9F1000F124808BFF8 +:104230004D4601950EF05EFF306070B10F4A0021CF +:1042400086F80C90B76034713161116849B10A4643 +:1042500009690029FBD1166105E0304615F052FED0 +:10426000CBE716603068594615F026FE306815F029 +:1042700025FE0024C2E700BFA5EE0100782600203D +:104280002DE9FF41044690F91900B0F1FF3F01DD2F +:10429000BDE8FF81207D40F002000328F8D1DFF85F +:1042A000A480D8F80800D0F89810098911F00A0FF6 +:1042B000EED061684A78C2F38102032A8DF80C209F +:1042C00008D0022A0CD1B1F80520ADF80420B1F8CD +:1042D000032005E0053101A815F0C1FDD8F808005C +:1042E000C16BA4F10C0795B201AE0868C0B190F99A +:1042F0001910B1F1FF3F3946F7DC017D41F00201B1 +:1043000003293946F1D14268D8F808002946D0F887 +:1043100068333046984700283946E6D0002CB7D19C +:1043200015F076FA30B101A82946002210F082FF7C +:10433000BDE8FF81D8F80C002946826F01A890479C +:10434000BDE8FF810C010020B0B52B498968D1F888 +:10435000D420527B0F2A1FD0D1F8AC301B78DBB1B0 +:10436000D1F8EC10274B0024274D51F82210234A96 +:10437000127851434FF47A72B1FBF2F22049096886 +:10438000891A38BF21461B689B1A38BF23462D68FF +:10439000AA1A38BF224605E01A4A194913681A4A70 +:1043A000096812684FF47A74624382420CD96343FD +:1043B00083420FD94FF47A734B43144983420978EF +:1043C0000ED991B100210EE01049097803290CD0D3 +:1043D000032108E00D490978022906D0022102E0F4 +:1043E000012902D00121094B19700021824288BFA6 +:1043F00001210846B0BD00BF0C010020B47A0020A6 +:10440000147A0020107A00201C7A0020A47A002060 +:1044100010B52E488168D1F8B020D1F8881311600A +:104420008168D1F8B020D1F89C1351608168D1F82F +:10443000B020D1F8A01391608268D2F8B010D2F801 +:104440008032CB60D2F8B010D2F8A4330B61D2F82E +:10445000B010D2F87C324B61D2F8B010D2F884326E +:104460008B610021D2F8B030D961D2F8B030D2F8E7 +:104470008C431C62164CD2F8B0305962D2F8B0307E +:104480009C62144CD2F8B030DC62D2F8B430D2F86E +:1044900048241A608268D2F8B430D2F8A8235A604F +:1044A0008268D2F8B430D2F8AC239A608068D0F831 +:1044B000B420D0F8B433D360D0F8B420D0F8B033FF +:1044C0001361D0F8AC00017010BD00BF0C010020DA +:1044D000419E0200A99F0200F8B5064600780C46EE +:1044E00015F044F808B1B82557E00025002C54D049 +:1044F000307825732070142015F006FD0028A06088 +:104500004AD031780170B6F801104180B6F8031036 +:1045100081808179727901F0F00102F00F0211447B +:104520008171F179A0680836C17171B1480015F048 +:10453000EBFC0146A068816051B1C2792AB136F81E +:10454000023B013A21F8023BF8E70027002501E091 +:10455000102501273178017379B1480015F0D4FC9A +:104560000146A068016149B1027B731C2AB133F88E +:10457000026B013A21F8026BF8E777B1816819B153 +:10458000084615F0BFFCA068017B19B1006915F061 +:10459000B9FCA06815F0B6FC10252846F8BD704798 +:1045A0002DE9FE4FDDF834808DF80B0005209B4689 +:1045B00016460D4608EB480400EB8400C0B215F027 +:1045C000A3FC002846D08146042001950E9D0027BB +:1045D00000EB8400CA464FF6FE740AF8016F0090A3 +:1045E0000C988AF801B00AF104064FF0FF0B8AF824 +:1045F00003808AF80200F8B2404517D205F10C0199 +:10460000304615F02CFCA8783072A8797072697960 +:1046100086F80AB040EA011070722889001B18BFA2 +:1046200001200137F0720C36AD69E4E700980B4DBC +:10463000019948F23002C3B20DF10B00C5F804A095 +:104640000AF04AFF0446484615F05CFC0448013075 +:10465000686000E010242046BDE8FE8F8826002018 +:10466000447000202DE9F04F8FB00E469B468246E5 +:10467000087849781446F378B27801EB0009042BE6 +:1046800038BF9144F76838BF00225FFA82F815F00E +:10469000BCFA234900250190C96811B1F078884718 +:1046A00000E0002000900BA83946102215F09EF87B +:1046B0000746B0FA80F0F178400903295BFA89F1E6 +:1046C00088BF0125414428405FFA89F5BAF1000FFF +:1046D0000FD0F0B10DF108090F46484615F036FA33 +:1046E00008950BA812F034F80E48006815F02AFB64 +:1046F0000EE070B10DF108090F46484615F026FA94 +:1047000008950BA812F024F80648006815F01DFB68 +:104710000746019815F067FBF8B20FB0BDE8F08FBF +:1047200014250020F87900202DE9F041DFF8B88049 +:10473000D8F80810D1F8E8000068002852D0D1F865 +:10474000E03042681B689A4208DDD1F84C0580478A +:10475000D8F80800D0F8E800006858B144680FF0B5 +:104760004FFE844206D9D8F80800D0F8D404BDE83A +:10477000F0410047D8F80800D0F8E8100C688CB376 +:104780006668B6F1FF3F08DCD0F84C058047D8F8E2 +:104790000800D0F8E80004686668A768257B0FF079 +:1047A0002FFED8F80810864206D8D1F8001520460A +:1047B00088472846B847DDE7D1F8E800006848B1E7 +:1047C000D1F8E01040680968884203DABDE8F0419A +:1047D0000EF0D8BF13F094FBD8F808000021D0F8F1 +:1047E000E8000160BDE8F0810C01002010B52E4A00 +:1047F0001278022A49D12B4A1278002A45D1C207E1 +:1048000006D02A4A136A1160934204BF0023136240 +:10481000020708D5254A134643F8041FDC699C4269 +:1048200004BF00231362C20608D5204A134643F88A +:10483000081F9C699C4204BF00231362820608D5AE +:104840001A4A134643F80C1F5C699C4204BF0023BC +:104850001362820708D5154A134643F8181F9C684F +:104860009C4204BF00231362420708D50F4A134637 +:1048700043F81C1F5C689C4204BF00231362C204FF +:1048800003D50A4A4FF47A735361400408D50748A8 +:10489000024642F8101F1169914204BF00210162D3 +:1048A00010BD00BFE5270020242600200875002049 +:1048B000F0B591B004460078A678676828B1B85D75 +:1048C000617840EA0102BA5503E020460CF05FFC33 +:1048D000BA5DA16904F10800D2B20DF1370313F0FB +:1048E0001AFC6078A178E278237F8DF82700608A2F +:1048F0008DF82410A18A8DF825308DF8262060B916 +:1049000040F20112914208D194F8281004F11E00DF +:104910000DF1030209F058F803E00DF1030205F070 +:10492000E5F8FF208DF823000DF103000C90207CAA +:10493000022803D003280FD1022000E000200DF14F +:1049400013058DF823000DF123000DF1030208215A +:104950002B460AF061FC0C956368207809A90DF1DB +:104960003702FFF77FFEB95D01F0F801B95511B0CC +:10497000F0BD704770B586B0274C2848217801AA51 +:104980000BF0FEF9002004218DF80A008DF80800D4 +:1049900000200FF029F922490D78A8421CD212F00C +:1049A00027F8C8B91F48068836B1032004210FF044 +:1049B0001BF9A91B814202DD01208DF808001A486D +:1049C000068836B1012002210FF00EF9A91B8142A1 +:1049D00002DD01208DF80A002278104C01A8214642 +:1049E0000AF0D9FE452021460DF0CEFB0F481049B4 +:1049F0009DF80A200078097808409DF808101143B6 +:104A000018BF012108400DF117018DF81700412052 +:104A10000DF0BAFB06B070BDB92700202079002048 +:104A2000E3BA0200BABA0200BCBA020004250020B0 +:104A3000972700202DE9F84F82462A4800788842BF +:104A40009CBF0520BDE8F88F50460C46009208F048 +:104A500091FA074624484FF6FE7C0078874216D12B +:104A60004FF6FE7008F086FA4FF6FE7CB8420FD182 +:104A70001E49002001230A78BB4209D211F83350A5 +:104A8000D2B295423CBF18462A460133F4E7384675 +:104A9000DFF858B0C6B20BEBC609C84628F802CFFB +:104AA000454655F8020F18B115F02CFA0020286081 +:104AB0004CB16700384615F027FA286070B10099AC +:104AC0003A4614F0C3FC0A48A8F800A089F801404F +:104AD00000780BF836000020BDE8F88F0120BDE813 +:104AE000F88F00BFD8BA0200D7BA0200503D0020AC +:104AF000DE2700202DE9FE4329482C4E4FF0000808 +:104B00000DF1040900240778BC421FD2E0B211F075 +:104B100083FFC8B1054600790138022814D3E8792B +:104B2000411CE97196F8671088420DD92888A5F8CC +:104B300009800DF029FF2888494611F0EDF8484614 +:104B40000AF00AFA0EF098FC0134DDE715484FF63A +:104B5000FE774FF0000800F10C04134805788DB182 +:104B600034F80C0CB8420AD021784A1C227096F80E +:104B70006720914203D9A4F805800DF005FF1C348D +:104B8000013DECE70A490020032808BFBDE8FE8389 +:104B900011F8202012B1013A01F820200130F3E78A +:104BA000E3BA020030560020D1BA0200A86D0020FE +:104BB0004C790020B0B588B0044640798DF81C00CF +:104BC00020798DF81E00284800788DF81F00206895 +:104BD000E8B113F073FAD0B124480078012825D841 +:104BE00020680DF1120111F0AEF86FF00200A27909 +:104BF000411CBDF81200DAB98AB2904218D0ADF863 +:104C0000140001208DF81D002068069009E00020A6 +:104C10008DF81D0014F070F906906FF00200ADF8E9 +:104C2000140005A803F064FF054619E0002517E00D +:104C3000012289B20025ADF804008DF80E206279BA +:104C400088428DF80F2008BF6FF0370521688DF876 +:104C5000105001ACA01C15F002F9204615F040F9E7 +:104C6000E8B208B0B0BD00BFDD2700202426002038 +:104C70002DE9FC412A4D95F86100002844D000241C +:104C80000026602C40D095F86100F040C00702D1AA +:104C900020340136F5E7112095F8618000FA06F717 +:104CA00014F0AAFD95F86110B94385F8611015F06C +:104CB0005EF8281928D0817A31B31021194A2C596D +:104CC000B14011EA080190F9091052F821804668B4 +:104CD000CFB209D006F0D4F9002079B200224FF00B +:104CE0000073009020460EE0017A022902D1C17CB7 +:104CF000C90601D406F0C4F9CDF8008079B2204687 +:104D000000224FF00063B04795F8610028B10648D3 +:104D10000021BDE8FC4115F00DB9BDE8FC8100BFE4 +:104D2000206E002094300440407200202DE9F843AA +:104D3000994616460F4604460EF0FEFF18B16FF076 +:104D40000100013007E02548089D017820460EF05B +:104D5000AFFD18B1204680B2BDE8F883204600219F +:104D60000CF0C6FB294605F009F978B38046407976 +:104D70004FF6FE75042816D001281FD198F80610AA +:104D8000B8F8020011F0180F10D01549B842097890 +:104D900088F8041018BFB0421DD1384631464A4643 +:104DA000F7F7C4FD06E04FF6FE70D4E70D49097D24 +:104DB00088F80410A842CED198F80500022805D042 +:104DC000204607210EF074FD0028C3D12046BDE81F +:104DD000F84313F0D9BA4845DFD0EBE7CCBA02006C +:104DE000D9BA0200A86D0020F8B505680446D5F8C8 +:104DF000F80000B1F8BD68796668022807D105F1AE +:104E0000D000694612F054FDC5F8F80009E0D5F865 +:104E1000EC10D5F8FC20D5F8F4001144C5F8F800E2 +:104E200000910028E6D031688A6B22F400628A6320 +:104E300095F84410C90608D52F6C37B1AB6C2046E5 +:104E400010210022B847D5F8F800B0F5806F84BF74 +:104E50004FF48060C5F8F8000099336B01444A1E96 +:104E60003168B66B1A600E4A9A6043F6F07202EB34 +:104E7000001010409A6810439860D5F858014068B7 +:104E8000006886620846022113F000FF287A002895 +:104E9000B0D120460121012612F02AF92E72F8BD68 +:104EA000018000C010B5017801290BD002291FD064 +:104EB000FD2932D0D32937D01A2939D1BDE8104085 +:104EC00002F062BE2448007802282CD11F4C2078C2 +:104ED0000138012827D814F0A3FD68B3FDF78AF83C +:104EE00008B32078022827D1BDE8104005F046B964 +:104EF000164800780138012815D815480078072889 +:104F000018BF082805D11349097811B90121EFF715 +:104F100075FCBDE81040F2F7E3B81049096811B11B +:104F2000BDE81040084710BDBDE81040FFF77CB851 +:104F3000BDE8104003F056BB14F0A2FD002814BFDA +:104F400001200020BDE810400BF02AB924260020E3 +:104F50000C7A0020BF7A0020D0260020D824002020 +:104F60002DE9F04F85B0264801ACDFF89C80DFF8D2 +:104F70009CA04FF00109251D00F11C06214807786F +:104F8000D7B316F818BCABF10100012831D830684E +:104F900030B156F8041C02311CBF0138306028E0E3 +:104FA000D8F80020C2B19AF8000030B1184951F881 +:104FB0002000C0EB0010810001E01548016836F8C0 +:104FC0001C0C9047BBF1020F08BF012804D1114906 +:104FD00036F81C0C0968884736F81A0C8DF80490CE +:104FE000ADF8100020460AF0C3FF10B1284609F0C2 +:104FF000B3FF2436013FC3E705B0BDE8F08F00BF23 +:1050000020450020E3BA020094230020D727002087 +:1050100090B402009C23002070B52C4D00282B6812 +:1050200041D0044643B9FA2014F06EFF00282860EE +:1050300049D0002101702B681878152621780822A4 +:1050400010FB0630417061788170A178C170E17801 +:1050500001712179417161798171A179C171E17920 +:105060000172217A4172617A8172A17AC172E17A08 +:105070000173217B41730E3004F10D0114F0E6F948 +:1050800028680178013101702B68187800FB06F15F +:10509000E52918D3012110FB061014F084FD2868BF +:1050A000002101700FE073B1187838B10121152289 +:1050B00010FB021014F077FD2B6823B1184614F092 +:1050C00021FF00202860002070BD00BF5027002075 +:1050D000F0B585B070B1044628480D46C08AA0429C +:1050E0000AD113F009FF2649284612F036FC80F059 +:1050F000010602E000263AE012260020ADF8064044 +:105100008DF8040001AF384603F0AEFF58B1043704 +:10511000384612F0D3FF012805D12846394612F04F +:105120001CFC80F001061748007818B3122E08D135 +:10513000012806D12046294605F060FA002818BF4C +:105140000026204629460AF077FA0A280AD0A02825 +:1051500006D1204629460FF069FF204609F074FE6B +:10516000012E04D12046002110F056FF01263046C2 +:1051700005B0F0BD122EDDD0E3E700BFA86D002022 +:10518000E0790020242600202DE9FC470B9C8DF8B7 +:1051900007001E461746884604EB840000F1040908 +:1051A000012050FA89F014F0AFFE00283FD082466B +:1051B0000A9A0C980023514601F8017F8A700A1D53 +:1051C000CC704E70DEB2A6421ED2067816704678BB +:1051D0005670467906F007069670877917F0180F13 +:1051E0000AD07D07C7F300174FF0060558BF022508 +:1051F0003D4446EAC505957085780133D570C5787C +:10520000083015710532DDE70B4D5FFA89F30DF1BA +:10521000070048F23202696041460AF05DF904462F +:10522000504614F06FFE05480130686000E010241D +:105230002046BDE8FC8700BF88260020447000207F +:1052400070B58EB02A4E044601200DF103018DF891 +:105250000300B068D0F83024522090470025282160 +:1052600084F82050657501A80C3014F057FD43F602 +:10527000FF702146ADF80B502546ADF82A000F20EF +:105280008DF828002068019031F8040FADF808006F +:1052900015F8060F8DF80A002089ADF80D00A07AE8 +:1052A000002818BF01208DF80F00E07A002818BFF1 +:1052B00001208DF81000207B002818BF01208DF8F8 +:1052C00011000C48007801280AD1B068D0F83024C9 +:1052D00050209047B0682946D0F83024E12090470C +:1052E000B068D0F8281201A8884700200EB070BD21 +:1052F0000C010020242600202DE9F0410C46080472 +:105300000AD460045CBF0020BDE8F0810FF04EFBC2 +:1053100084F48040BDE8F081244F387809F0C8FB60 +:1053200000283FD005460078A0F12301022917D2BA +:105330000C2012F003F890B306460020C6E90000E6 +:10534000B06005203070E878A9783171707114F080 +:10535000DBFDB06018B3EA78696814F077F81EE0F6 +:1053600027281CD1082011F0E9FFA8B1064601202A +:1053700005F10108307098F80000033014F0C4FD06 +:10538000706048B198F80010CA1C414614F05EF8ED +:105390007878314609F0E8FE284612F0ADFE28463E +:1053A00012F0AAFE84F40040BDE8F0817E270020C0 +:1053B000B0B50446007D012805D0152803D0252866 +:1053C00001D035281FD1217E0A071DD4254D6178D3 +:1053D000A868D0F8D42092F8822072B11B290CD191 +:1053E000E868816A01208847A868D0F82C134FF438 +:1053F0008060884700216170A868D0F8302320467B +:10540000BDE8B0401047217E4A060BD4152801D0D4 +:10541000012801D109070FD4617879B11B290FD177 +:10542000232013E00F488068006D016819B160788F +:10543000BDE8B0400847B0BD312007E00D2100E0D5 +:105440000E21084A926852F82110085C2070054825 +:1054500021468068D0F894000078BDE8B04009F09B +:1054600083BE00BF0C01002070B5284D28780528A8 +:1054700039D8022837D0274C0420254E20702648E2 +:10548000B268417801314170D2F8D400C9B290F8C5 +:105490002430994204D9E120BDE87040FDF73CB9C1 +:1054A000297804290BD1D2F8B8100A780AB3C96C4C +:1054B000F9B102208847B0682978D0F8D400174A9B +:1054C00090F8310013780133834238BF184605291C +:1054D000107008BF70BD032914D183202070BDE86F +:1054E000704013F0BBBB0A488068D0F84C05804779 +:1054F000C1E70A4990F831000A780132824238BF88 +:1055000010460870BDE87040FDF714BFBB7A00205C +:105510000C010020B87A00202D260020B97A002046 +:105520007FB5244C2448254E254D0121012260657C +:105530003068036828469847306801214268284649 +:10554000904713F0AFFB1F48082200F120012046CE +:1055500013F07CFF1C4900200A5C235C934207D1B6 +:1055600001300828F8D113481849082213F06EFFBB +:1055700004F1080005F00CFDA16809B1002088477E +:105580000C4806F0E1FF0CF067FC01AC204614F07B +:1055900083FB0F4D0020002122468DF80400284691 +:1055A00013F096F80B48056014F008F9002004B0D9 +:1055B00070BD00BFD42000202F9E0200D801001033 +:1055C00000400340A87F05004CBA0200F0120050D2 +:1055D0003C7700204C7A002070B5012953D0044656 +:1055E000002942D128480121057A01722021EFF3D8 +:1055F000118681F3118894F82010032916D002290E +:105600001BD0012929D12168E26C636819606168A7 +:10561000236859601168914204D1A169C26822EAE5 +:105620000101C160606AC0B1C0680FE020686168B4 +:10563000086060682168486012E0616A69B10A68C0 +:10564000C8684B681A604A6809684A6028B10168EE +:105650004268116041680068416020460EF094FF86 +:1056600086F3118828460EF0D7F9216B481C0AD022 +:1056700006480029406818BF0846D4E90A21436853 +:10568000BDE87040184770BD38220020A01F0020E0 +:105690002DE9F0412B4B012702462024187A1F7276 +:1056A000EFF3118C84F3118854698C4202D18CF38E +:1056B000118841E01D6A002907FA01F705EBC106D0 +:1056C00048BF03F12C0648BF002792F82050012D57 +:1056D00026D1D2F800E0D2F84C805568C5F800E039 +:1056E000D2F804E01568C5F804E0D8F80050454544 +:1056F00005D1D2F818E0DD6825EA0E05DD609D6968 +:105700009542354601D1DE613568D5F804E0156073 +:10571000C2F804E0CEF800206A60DD683D43DD6039 +:10572000B1F1FF3FD66497615161DCBF0021D961BF +:10573000012119748CF311880EF06EF92046BDE832 +:10574000F08100BF382200202DE9F0418CB0DFF855 +:10575000A8800446D8F80800D0F83C03804708B178 +:10576000FC2045E001AD21461122284614F0F2FB51 +:10577000A07D618A667C677D0B228DF81A00B4F8E3 +:105780001700ADF8161004F119018DF815608DF8A9 +:105790001970ADF81B00606A0A90D8F80800D0F8BC +:1057A000D40090F853008DF8180005F1190014F09A +:1057B000D1FB56B100200B9087B107EBC7008000EA +:1057C00014F0A2FB0B9048B911E0812014F09CFB6F +:1057D0000B9060B18121FF2214F04AFAD8F808003A +:1057E000D0F8442301A907209047002000E01A20A8 +:1057F0000CB0BDE8F08100BF0C01002070B514F0C2 +:1058000058FA14F0B3F814F0B7F8044600F00C009E +:105810000C2803D100BF00BF30BF3BE060071ED49F +:105820000DF0F2FA054600EB800001214600012050 +:1058300012F064FD864212D91C4CA5F1180060617B +:1058400004F10C0013F0BDFA00BF00BF0120F6F711 +:105850006BFE00BF00BF002084F820001CE000BFEA +:1058600000BF200715D40E4E0E4D306881682846C3 +:1058700088470428F9D0B0FA80F004F010014009FC +:1058800040EA111014F044FB074801210160006850 +:1058900000E030BF00BF00BFBDE8704014F00DBA9B +:1058A000D8010010004003402C200940D81B0020E4 +:1058B0002DE9FF4726480DF1040A00270AF10404E8 +:1058C0000397CDE9017790F800902248C84600F18F +:1058D0003906FDB24D4510D20720294600220C237F +:1058E000CDF800A010F09AFE30462146082212F0B2 +:1058F000F7FC08B90137ECE7B846002300214D4515 +:1059000028BF012101980028024618BF01224D45F9 +:1059100038BF01231343012B18D10F4B1C78ACB9AE +:10592000114000F2E2404FF00101019019700B4963 +:10593000086018BFA9F1010801AB07200C225FFA2B +:1059400088F110F081FE064800210180BDE8FF8744 +:10595000D3BA0200A86D002095270020182500204A +:1059600014250020BFB590F91910B1F1FF3F00DDFB +:10597000BFBD017D0429FBD8012202FA01F111F01B +:105980001A0FF5D0234DA968D1F89810098911F0A4 +:105990000A0FEDD040684178C1F3810103298DF8E9 +:1059A0000C1008D002290AD1B0F80510B0F8034055 +:1059B000ADF8041003E0411D01A814F050FA13F0F3 +:1059C00027FF28B1A1B201A801220FF033FCBFBD0F +:1059D000E868A4B22146426F01A890471E2800D073 +:1059E00068B901A8214601220FF024FCE868006D87 +:1059F0008047FE28BCD1E868416D002007E0E868D8 +:105A0000006D8047FF28B3D1E868416D01208847C9 +:105A1000BFBD00BF0C010020B0B52B4CA068416990 +:105A20000A7EFF2A4DD0D0F8D43093F88330022B71 +:105A300012D1D0F804054D698047A1680A69CB6B83 +:105A4000D1F8D41091F82C1032F811101A891044A2 +:105A5000281AA0EB01102CE08B7EA3B1022A12D1F0 +:105A6000D0F804058047D4E902124B695268D1F896 +:105A7000D4101B6912780979C01A6FF007039A1ABB +:105A800012FB010015E0D0F804054D698047D4E908 +:105A900002120B69CC6BD1F8D41091F82C1033F8AA +:105AA0001110238918444418D2F8B40080472044C8 +:105AB000281A002805D44FF6FF718842B8BF014666 +:105AC00000E0002188B2B0BD0C010020BFB5204924 +:105AD0000020204D002208601F49C5E9020008602F +:105AE0001E490870012129701D490D2A03D041F873 +:105AF00022000132F9E71B481B4901601B484DF2A7 +:105B0000F02101601A481B490160012028712869B1 +:105B100000B1BFBD01AC204614F027F800200121E0 +:105B2000224602908DF8040013480DF0E3FA286134 +:105B300014F0C0F90028ECD114F0B6F90F49B1FB0C +:105B4000F0F1286914F0B8F9286914F0B7F9BFBD6D +:105B5000187A0020B8240020207A0020A47A00209F +:105B600060730020107A0020F8240100147A0020CD +:105B70001C7A0020905F010019C3010000A3E1110D +:105B80002DE9F84F0546007D1E4690460F463830F9 +:105B9000C0B211F0D3FBC8B304460D9829461C22AD +:105BA00000900120DDF830A0DDE90A9B207004F1AF +:105BB0001C0013F04BFCA01C39460A2213F046FCD3 +:105BC0000020A4F80C8084F813B084F81890C4F86E +:105BD00014A0E0620098607630782074B6F8010076 +:105BE000A4F811002A7D6889E0812AB104F1380007 +:105BF000E062296913F02AFC607F800708D00A4818 +:105C00000168204659B1BDE8F84F0847BDE8F88F54 +:105C1000064821460078BDE8F84F09F0A5BABDE86E +:105C2000F84F12F069BA00BF04270020997A0020CB +:105C30002DE9F04F89B04FF0000B04461421CDE957 +:105C400002BB04AD284614F069F824484FF0FF0A5F +:105C500005F108094FF000088DF820A0061DB8F1E5 +:105C6000C80F34D01FFA88F7042014222B46394677 +:105C70000AF0DAF838BB44B113F030FE86F805B00C +:105C800046F804BCC6F800B01DE0042039460022E6 +:105C90001423009510F0C2FC484602A9082212F015 +:105CA0001FFB40B901207071DDE904010B30316048 +:105CB00046F8040C049013F011FE2846142114F049 +:105CC0002DF88DF820A00C3608F10108C7E714B1B3 +:105CD00000200DF051FF09B0BDE8F08FF033002037 +:105CE0002DE9F041254E0546371813F085FD044691 +:105CF00097F84A01411C87F84A1128B1204614F050 +:105D000036F80020BDE8F081DFF8748018F82570BF +:105D100007F03F00142898BFFFF7E2FF08EB85006B +:105D2000458878B2B0F1FF3F0CDD78061FD41548E6 +:105D3000006841692846884728460CF06BF801281E +:105D4000FAD1DBE70F4E3068C169284688473068D2 +:105D5000416A284688473068C16A284688470A4809 +:105D600001210160094801688907FCD5C6E706EBF7 +:105D70008500D0F8601101208847BFE7D81B0020BC +:105D80007CB30200B80100102820086028200840D9 +:105D9000F8B505462248234E4168890705D40168B5 +:105DA000F02242EA114186F84D101F494FF00122BE +:105DB0001F4F0A601D4909883968096884682046B0 +:105DC0008847A00105D4E00103D5307840F00200F7 +:105DD00030703868214642682846904710F0A8FE87 +:105DE0001448154A0068C0F305311170C1054FF021 +:105DF000130158BF232140237354382101EA901026 +:105E000000F56050A2F85C00386881682046884739 +:105E100002200DF0ADFF094801210160F8BD00BF6F +:105E2000AC4F00500962084004A40C4000A00C4094 +:105E3000F00100100C1400500EB00C4094046042AD +:105E40002DE9FE4FDDF830800E9E92460C460F2164 +:105E500006EB080201EB4201C9B2502984BF1020B1 +:105E6000BDE8FE8FCDE9011020489B460F9FDDF86D +:105E70003490456813F0F6FCA0421CBF0220BDE838 +:105E8000FE8F25F8024B13F037F80146284613F031 +:105E9000E6FF4FEA1B2180F8038080F801B0817093 +:105EA000DDE9013100F804ABB8F1000F09D019F8B1 +:105EB000022BA8F10108027019F8012C427002307F +:105EC000F2E700F8026B4EB117F8022B013E00F822 +:105ED000012C17F8012C00F8022BF4E703482022CC +:105EE00003B0BDE8F04F09F0F7BA00BF88260020E4 +:105EF0002DE9F043844608981C460625034405EB2B +:105F00004303DBB2502B84BF1020BDE8F083234D48 +:105F10009CF80880DDF824904FF6FD7E6F68079DA1 +:105F2000B8F10F0F02D0B8F1020F08D10EF102063E +:105F3000BCF80080B6B2B04508BFACF800E0BA705B +:105F4000120A3C71FA700EF1020292B2914208BF3D +:105F5000714607F8051B090A07F8041C4CB144B147 +:105F600015F8021B013C397015F8011C79700237D5 +:105F7000F5E7387058B1791C48B119F8022B01388F +:105F800001F8022B19F8012C01F8012CF4E7034861 +:105F900061460622BDE8F04309F09EBA882600203B +:105FA0008B4208BF824207D9009A002A01D01060B4 +:105FB0005160002100207047002B08BF002A10D13B +:105FC000009A002A01D01060516002000B000021ED +:105FD0000020002B08BF002A1CBFC943C04304F0A7 +:105FE00032BEF0B51C4615460B4602460020002185 +:105FF000B4FA84F6202E04BFB5FA85F62036B3FA3B +:1060000083F7202F04BFB2FA82F72037F61BB6F1D0 +:10601000200727BF05FA07F400257F42B4403EBFA2 +:1060200025FA07F73C43B540A34208BFAA4201D373 +:10603000521BA341404149416D0845EAC4756408BB +:10604000761EF1D5059F002F01D03A607B60F0BD30 +:10605000FEB50D46C9890446A1F50040022812D3B9 +:10606000132920D048F20402B4F90400914206D169 +:10607000A18C052903D80221A1844021A180B0F17F +:10608000FF3F1ADDFEBD284608F0D0F80028F9D001 +:106090000446007818B9E989204607F0F3FD204648 +:1060A00013F030FFFEBD6C462846214612F0B2F9CF +:1060B000698820460CF065FAFEBD94F82400013092 +:1060C000C6B2304613F020FF0028DBD00546A07989 +:1060D00027792870E0796870A81CA28CA16A013128 +:1060E000013A13F0B3F947F08001452032462B46C0 +:1060F0000CF04AFB2846BDE8FE4013F003BF704792 +:106100002DE9FE438146284888460026002704786A +:10611000A6420BD2F0B20FF0AFF928B10546407994 +:106120000744F8B2484504D80136F1E7B320BDE88A +:10613000FE834046182113F0F1FD6979A9EB0700B1 +:106140000844C0B205EB4000C088A8F80A0012F06D +:10615000D3FE0146404613F082FE6878012806D13E +:10616000012088F814006888A8F80C0012E06888FC +:10617000694610F04BF968B19DF8081008F10C0061 +:10618000032988F8141019BFBDF800100180694672 +:1061900013F065FE2878297988F80800002088F82F +:1061A0001610BDE8FE8300BFDFBA0200F8B5254F28 +:1061B00005463E1813F020FB044696F84A010138C4 +:1061C00086F84A01000637D11F4810F9251000EB68 +:1061D00085004588CEB2B1F1FF3F0CDD70061FD4BB +:1061E0001A48006881692846884728460BF0F0FD68 +:1061F0000228FAD11AE0154F3868016A2846884704 +:106200003868816A284688473868016B284688477D +:106210000F48012101600F4801688907FCD505E09E +:1062200007EB8500D0F860110020884706F03F009A +:10623000142898BFFFF7BAFF204613F098FD0020FE +:10624000F8BD00BFD81B00207CB30200B8010010CD +:1062500028200860282008402DE9F041002918D4A2 +:106260001F4615460E46044612F08CFE8046204618 +:10627000314680220BF056FE20B1064690F93300DD +:1062800000280AD4404613F059FE00210220BDE840 +:10629000F08100200021BDE8F081D6E9080145F039 +:1062A0000A0547F0E04728403940084310D04046EF +:1062B00013F044FED6E9082303EA070102EA0500C9 +:1062C00042404B40C4E92C01C6E90823BDE8F081F7 +:1062D000B1680B48814203D0B168C4F8A810B0601F +:1062E0004046C4E9285713F029FE04F150004FF04E +:1062F000FF3113F0A3FCD4E92C01BDE8F08100BF0D +:10630000E7DC0100F0B589B017460C4605460DF0F4 +:1063100013FD18B10026304609B0F0BD2846002113 +:1063200000260BF0E5F8394603F028FE0028F2D0ED +:1063300007468079C007EDD0204612F07FFA012889 +:1063400018D10420ADF816408DF8140005AF38467A +:1063500002F08AFE01260128DDD100203A1D2146E7 +:10636000CDE90000CDE9020610480378284600F088 +:1063700011FCD0E7B8794007CCD513F073FAA042EE +:106380000CD100202146CDE90000CDE9020005A88E +:10639000021D06480378284600F0FCFBB879810707 +:1063A0005CBF00F0FB00B8710126B4E7CBBA020075 +:1063B0007FB5294E0446B068D0F8FC1120468847C6 +:1063C00080B9B068D0F82C112046884750B9607C5D +:1063D00038B194F8340020B9B068D0F8B810097812 +:1063E00049B100206070B068D0F84411204604B074 +:1063F000BDE870400847D0F8342204F112010920AA +:1064000090470028EDD00546B06804F10B01D0F8A4 +:106410003024E7209047B06804F10801D0F8302418 +:1064200050209047B06804F10A01D0F83024E120F0 +:106430009047022023894FF6FF728DF80C004FF031 +:10644000FF30ADF80400B068D0F8C061A07A0090C9 +:1064500001A92846B0477FBD0C0100207CB5284E1D +:1064600004460D460DF10701B068D0F828244F20EE +:10647000904712F0C3FF042809D1A5B121494FF478 +:106480007A72600113F0B7FB00F53E702DE012F058 +:10649000B5FF68B1ADB11B494FF47A72E00013F05B +:1064A000AAFBF83021E04FF4867000EB44101CE0AA +:1064B0005DB114494FF47A72600013F09CFB2630F2 +:1064C00006E0602000EBC4000FE0102000EB440069 +:1064D0009DF807104FF0FF3202FA01F1F268C9434C +:1064E00052681278083202FB01000C21122C88BF7E +:1064F00028210844034980B20978484380007CBDC4 +:106500000C010020B47A0020F0B58BB0214D286832 +:10651000416E03A888472868C06B80471E49002643 +:10652000039006960A7B88604E8002F0F0020232E9 +:106530000A7301218DF8101013F05EF90446174814 +:106540000227C068806907701548806808B18047D5 +:10655000099029681348144B0D6DCDE900760E4F54 +:10656000006803AA3946A8470646204613F0FFFBF9 +:10657000B6F1FF3F06DD0D4807600D480178013197 +:10658000017004E0032041F2883104F0A5FE0BB055 +:10659000F0BD00BF347A0020642500200C010020EB +:1065A00054B50200E4260020ADE3010030250020B0 +:1065B000292500202DE9F04F85B0814680690DF135 +:1065C000120200214FF000080778A32008F098FC81 +:1065D000BDF91200D0FA57F01FFA80FBBBF1030F90 +:1065E00028BF4FF0030BBBF1000F16D00BEB4B0095 +:1065F000C00080B213F088FCA8B182465FFA8BF528 +:1066000000240646AC420CD257FA84F1A22032464E +:1066100008F076FC01341836F4E74FF0000B4FF029 +:10662000000A002204E0B5224FF0000B4FF0000AF0 +:1066300099F811005FFA8BF19DF81230CDE902A8AC +:10664000CDE9007109F10201FDF7F0FABAF1000F8E +:1066500002D0504613F056FC05B0BDE8F08F7047ED +:106660002DE9F041806A224A01210125847846788B +:106670005120147013F028FA1E4805701E484EF67B +:1066800060250EB1203007E01C490978002914BFAD +:1066900000EB81004FF47A75194906684FF4804089 +:1066A0000F780021F5F7E6F8DFF85880022198F816 +:1066B000000009F097F906FB05F0B0FBF7F2E007E0 +:1066C0000AD1A00758BFBDE8F08198F80000022168 +:1066D000BDE8F04113F07BBB4FF480401146FEF75C +:1066E00085F84FF480400121BDE8F041F5F7C2B8CC +:1066F000DC270020A727002090B40200D22700202A +:10670000D12700209C7A00202DE9FE4FDDF838903B +:106710008DF80B0001209B4614460D4609F10A0630 +:1067200050FA86F013F0F0FBC8B301950546074612 +:10673000DDE90C8A594605F8014F681C13F04DFB42 +:106740004FEA1A21B9F1000F80F8049080F802A0F6 +:1067500080F80080C1704FEA1821417004D00F9971 +:1067600005304A4612F072FEDFF83C80109801991D +:10677000F3B248F2380288F802000DF10B00C8F8B5 +:10678000045008F0A9FE0446384613F0BBFB002075 +:1067900088F8020005480130C8F8040000E0102421 +:1067A0002046BDE8FE8F00BF8826002044700020F0 +:1067B00070B588B000266D46044620210672284632 +:1067C00013F0ACFA284621460B2212F03FFEB4F833 +:1067D0000B0004F10E010A228DF80D60ADF80B00DC +:1067E00005F10E0012F032FE94F91A00CDF81A608D +:1067F000ADF81E60C207C1B21CBF01228DF81A207D +:106800008A0744BF01228DF81B204A0744BF01229A +:106810008DF81C200A0744BF01228DF81D2049066F +:1068200044BF01218DF81E10B0F1FF3FDCBF0120F5 +:106830008DF81F000020ADF80C00208BADF818007B +:1068400004488068D0F8F41268468847002008B0F1 +:1068500070BD00BF0C010020B0B586B0274D0C46BE +:106860000278A968D1F890309B5CA3F10B028DF8F7 +:106870000030062A0DD8DFE802F0040E381338384D +:1068800017004470A968D1F8A41306B0BDE8B04061 +:10689000084753BB2FE01A2C0AD10020019024E0B6 +:1068A00000798DF8020020E011F026FCA9681CE0B8 +:1068B00090F89D2001908DF80220C2680292028A11 +:1068C000ADF80C20827DD20606D4D1F8D430827E79 +:1068D00093F834309A1A00E000228DF80E20427F9F +:1068E000C08B8DF80F20ADF81000D1F83815684630 +:1068F0008DF80140884706B0B0BD00BF0C010020F4 +:1069000070B5284CA068D0F8D4204169557B00228E +:106910004A77C16891F83020013281F83020C1688F +:1069200091F83010042908D1D0F864018047A0689C +:10693000D0F86C01BDE870400047E068C16B2020D2 +:106940008847A268D2F8D41091F84F600F2E0FD06C +:1069500050694B7B807F98420AD24873D2F8D400AA +:10696000D2F81415407B8847A268D2F8D41000E012 +:106970002E46D2E90303497B90F8304033F81630B5 +:106980006400A3404FF4707404FA01F1B3EB910F6B +:1069900028BF8B08D2F8F024A1EB4301BDE870407A +:1069A000104700BF0C01002070B5044613F02DF90C +:1069B00024498860A0070A4604F1080020F003007B +:1069C00008BF201D112828BF0432002413680022AC +:1069D0001D68B5F1FF3F07DD54B116682E448642AD +:1069E000166012D22E4608E085F00046002404E02E +:1069F000854208D201242E461A469D593344002D63 +:106A0000E7D1002419E01A462E46002AF9D0331A9D +:106A1000042B08D3135040F0004313600A4B5C680A +:106A2000201A586008E0084B10685C68201A58600B +:106A3000106840F000401060141D886813F0D3F90E +:106A4000204670BDD02500200026002010B586B05D +:106A50000146427E8068002343F606040593CDE993 +:106A600003330293438003881C1B022C10D3B3F51D +:106A7000C15F03D040F60204A34212D1038A002A68 +:106A800023F4FE6312BF038243F43472028208E0EF +:106A9000038B23F4FE630AB1038302E043F43472F0 +:106AA000028300224A7602A9009105A904AA03AB39 +:106AB000F8F7A6FE28B105984FF6FF7100888842C6 +:106AC0000ED0049C0299204606F020FA074801687F +:106AD00021B1204606B0BDE81040084706B010BD01 +:106AE000049C0299204606F043FEEFE78026002032 +:106AF00070B50C46214900228D1D214909788A4232 +:106B000010D2C37C6E789E4207D1838935F8066C1B +:106B10009E4202D115F8043C13B908350132EEE764 +:106B20008A4201D1002070BD287828B31548818C95 +:106B300020460EF047FA10B1287801382870124824 +:106B4000011D1248007802464AB10B78FF2B03D092 +:106B500031F8043CA34204D02431013AF4E7297807 +:106B600002E0297801392970094AC9B21278104423 +:106B700088423CBF00202870012070BDAA68002018 +:106B8000CEBA0200A86D002020450020E3BA020022 +:106B9000D1BA02002DE9F84F0B9FDDF834B005465D +:106BA0000220994690460E4607F1010ABBF1000FFC +:106BB00000EB4A0008BF02208DF8010068460FF084 +:106BC0008FFFB8B304460A9884F81A90A6806580AF +:106BD000E076A07F01280AD112F044FEB04206D030 +:106BE000B8F1000F06BF0020A077C4F8248005206C +:106BF0002169BBF1000F087018D00C9881F801A032 +:106C00008D1C0021CAB2BA4208D210F8022B013101 +:106C10002A7010F8012C6A700235F3E712F022FE98 +:106C2000287012F01FFE000A687000E04F702046C6 +:106C300007F0E2FEBDE8F88F70B586B085690446BE +:106C4000284611F03BFA30B112F056F901462846B9 +:106C500010F083FE20B11F480178C9B3002002E084 +:106C60001C48017828460229049004D11A49A28BB5 +:106C7000498B8A422CD1217B51BB297A00268DF881 +:106C80001660CA094DB28DF81520C1F380128DF837 +:106C9000142030B9002D04D44FF400500121F4F732 +:106CA000E9FD04A8FDF786FF8DF80F000DF10F0038 +:106CB000A11C48F234020123CDE9000604F11100C1 +:106CC0000AF036FD002D03D4049808B912F0E6F955 +:106CD00006B070BD24260020A86D0020F8B515462A +:106CE000044625480E461168D268AF690068002F37 +:106CF00018BF3846216120636261D5E9042100296B +:106D000008BF4FF4007162B1D31D11444FF0FF3042 +:106D100023F007032063C91A21F00701C4E90A130D +:106D200008E00731082221F00701A1620CF092FE71 +:106D3000E062F0B1D5E9010104F13803EA69666364 +:106D400007C395F8200084F8480018B10B48416942 +:106D50000131416100206065204604F0ADFB08B1BF +:106D60000230F8BD054804F1080111F0A3FC002031 +:106D7000F8BD0120F8BD00BF7C7A00203822002039 +:106D8000BFB545680446287805380B2815D8DFE8D4 +:106D900000F006140C1415141414141B144220468D +:106DA00004B0BDE8B040FAF79DB9681C0190608955 +:106DB000ADF8000068460DF0DBFCBFBD204604B016 +:106DC000BDE8B04011F015BD681C0DF10A010EF0D0 +:106DD00093FA0128F1D150208DF80C0000208DF895 +:106DE0000E00207A09388DF80D0003A80CF0EAF89F +:106DF0000028E2D00446BDF80A0005F10901227D11 +:106E00006080087884F83800206912F01FFB204663 +:106E100007F0F2FDBFBD204604B0BDE8B04010F061 +:106E2000D9B970472DE9F04F8DB0169E1A9F0B907F +:106E30004FF6FF70ADF83010388086B11C4673B144 +:106E4000DDF86490B9F1000F09D0DDF85CB0BBF15A +:106E5000000F04D0DDF860A0BAF5005F04D9042566 +:106E6000E8B20DB0BDE8F08F0BA806AA214607F0E6 +:106E7000EDF805460028F3D11048806803F03EFB8A +:106E800080460F48ADF814400496ADF80EA0ADF85A +:106E90000CB0CDF808901223C188C07802AA0092E5 +:106EA00006AAF3F7A9FB054610B9BDF81C00388007 +:106EB00002484146806806F04FFED1E7A02300203B +:106EC000B87200202DE9F84F0024804600210022EE +:106ED0000460684602F094F9204DDFF884A08146F2 +:106EE0004FF0FF374FF0190B0020602C1ED02A19ED +:106EF000917AB9B1107A022816D0DAF80400418BE1 +:106F00000069084495F8621011FB0B0150690EF0FE +:106F10005FFF064612F0C8FFB6FBF0F0B84238BF7C +:106F2000074601202034E0E70120002709EA00019C +:106F3000012904D10099B94238BF0F4606E0B9F1E2 +:106F4000000F01D0009F01E0C10701D0C8F8007018 +:106F500040EA090000F00100BDE8F88F206E002033 +:106F6000D01E00202DE9F84F0546D1F800902348A7 +:106F700000268B46814588BF032612F03DFCDFF8D2 +:106F800080A08046DAF80440601B18BF01205AF840 +:106F9000207025B105F1B80012F08CFF28B96FB14F +:106FA00007F1B80012F086FF40B19AF82400CAF841 +:106FB000205040F002008AF8240018E0601BDBF843 +:106FC00000104FEA9904B0FA80F0400940EA40000E +:106FD0000AEB800081609BF80810017412F064FFD6 +:106FE000B4FBF0F105F1B80011F0F4FC8326404643 +:106FF00012F0BDFE3046BDE8F88F00BF03093D002A +:1070000070200020F0B587B00546112012F07CFFFB +:10701000002841D004463B2000211122234612F0D3 +:10702000ABF890BB2078A8422FD1112012F06CFF52 +:1070300058B305463A20002111222B4612F09CF845 +:10704000E0B93A201121224612F03EFD1348144FB8 +:10705000012180F8411078682146B0F1004F84BFCB +:107060000020786001AE1122304612F0EFF9786806 +:10707000182132460690822012F026FD2846112162 +:1070800012F04CFE284612F03DFF2046112112F06E +:1070900045FE204612F036FF07B0F0BDA86D002077 +:1070A0001425002070B524480C460078012801D82A +:1070B00060061CD420060CD4A0052BD420052ED4A9 +:1070C00060055CBF002070BD05F0F0FF84F48060B7 +:1070D00070BD04F089F808F0F7F801200FF068FEA1 +:1070E00003200121EDF78AFB84F0800070BD134E70 +:1070F0003068F0B1808802F01BFA3068056812F041 +:1071000001FF3560ADB1EA882D686DB1E888801A5D +:10711000E880F9E702F0FCF884F4007070BD05F037 +:107120008BF884F4006070BD05484021007812F0AF +:1071300051FE84F0400070BD24260020E826002087 +:107140009D7A00207CB520480C46017029BB1F4861 +:10715000007802281BD109F037FF0CF04FFBB0B1CB +:107160001C21054612F0DAFD194E708B06F11C0148 +:107170002880A81C12F073FE4AF60120A5F8110021 +:1071800014480078013040082874B08C6881124897 +:10719000007810B9032010F003FE1048016951B1C6 +:1071A0000B488DF80040C28A408BADF80400684659 +:1071B000ADF8022088470A48022102220023007805 +:1071C0000DF06CFA7CBD00BFBF7A002024260020A1 +:1071D000A86D0020CDBA0200D026002054750020F2 +:1071E0009D7A00202DE9F04F85B0814680690DF130 +:1071F000130200214FF0000807789D20FAF7E0FF06 +:107200009DF81300B84222D9C01BC4B20A2C28BF73 +:107210000A24E00012F078FEC8B182461848002522 +:1072200056468346E8B2A04214D257FA85F18B2025 +:107230003246FAF7C5FF70795A46C1002BFA01F1C0 +:10724000032888BF0321013571710836EAE700245D +:107250004FF0000A99F811009DF8133009F102016E +:107260000022CDE90074CDE902A8FDF78DFFBAF147 +:10727000000F02D0504612F045FE05B0BDE8F08F79 +:1072800003000102B0B586B00589044612F0EAFA9F +:10729000854212D10020ADF810006068039012F012 +:1072A0005DFD78B30179013903292BD8407901219B +:1072B00021EAD0008DF812002DE020890021ADF8E0 +:1072C0000C006068049001ACAB20224607F018FE69 +:1072D0000DF103012046002202F03AFA104800782E +:1072E000012808D19DF8030028B900208DF814006A +:1072F00003A800F0E9F901208DF8140003A800F0BC +:10730000E3F90BE0248812F0ADFA844206D10020A4 +:107310008DF81200039003A8FDF74CFC06B0B0BD39 +:10732000C2270020F8B5D0E901650446287912F09B +:10733000C9FDD6F8CC206969286852681268D16204 +:1073400096F8F93013B9C368DB06FCD4436823F020 +:10735000020343602B69D3621943476A27F003078E +:107360004762C2F80415416921F001014161012120 +:107370000162D6E93512D6F8C00001604AB1EB6966 +:107380009B68C3F309139A4203D91144DA431144A9 +:107390000160D6F8DC204AB16B6A9B68C3F309131D +:1073A0009A4203D9DB431A4411440160204609F094 +:1073B000DBFC287910F044FB2879BDE8F84012F096 +:1073C00083BD70472DE9F04387B0C468DFF888902B +:1073D00000264FF001081B2E11D0D9F8280008FA1A +:1073E00006F7384209D0A55D12F030FA854204D97B +:1073F000D9F82800B843C9F828000136EBE7D9F8D6 +:107400002860C6B16C461821201D12F087FC0120AF +:1074100000968DF8040000208DF8070099F82E00E2 +:107420008DF80500204607F0CDFB062089F82600E0 +:1074300007B0BDE8F0830020002189F8260041F262 +:1074400004000FF0ACFA054801680029F0D0C42010 +:1074500007B0BDE8F0430847A86D002010250020C4 +:10746000BFB50FF087FA04462148012100F10E0252 +:10747000552012F023FB04F0010418B914B10020C8 +:107480000FF096FC1B4DE220691C0EF03BFF2046DE +:1074900005F010FF0020CDE90200CDE900002878BA +:1074A00001280ED814486946102210F019FF18B1AF +:1074B00068460EF051FA04E00F496846102211F0B8 +:1074C000C5FF6A466220102112F0F8FA2CB120B9EB +:1074D0006A466220102112F0F7FA20460EF0FCFEF8 +:1074E0001CB1002001210CF0D3FA002004B0B0BD83 +:1074F000CC2200202426002004B90200F0B589B077 +:10750000044640890E46010742D5800706D5607BB8 +:10751000062803D0CD2E18BFF02E37D1207B0FF0D8 +:10752000E7FCA8B3217B676905467EB108220FF00E +:10753000F3FC70B16FB1428801780379B87895F89F +:107540000AC0CDE900C60BF03DF803E004220FF0BD +:10755000E3FCEFB178682168CDF80E00387A096A4B +:107560008DF81C00E86809780690787B8A09402924 +:107570008DF81D003878009538BF042200F04001D6 +:1075800000F0200302A8EFF7B3FE02E0E92EC5D019 +:10759000002009B0F0BD704770B50546407D164625 +:1075A00001220FF0FDF9C6B90446B0B1E87D94F8A8 +:1075B0003510884211D194F83910237A0A18287EA0 +:1075C0009A420BD2FF2817D1002084F8352084F886 +:1075D0003800FF208840C0B20EE070BDFF280BD1FC +:1075E000E28BA07E94F82A1000230CF035F8204698 +:1075F000BDE8704010F0E4B984F8370084F8360034 +:1076000012F054FC054612F04FFC68434FF47A71B7 +:10761000B0FBF1F00121208094F83A00608003482B +:107620000078BDE8704006F071BD00BF482600201C +:10763000B0B586B0044601208DF814002046F8F756 +:107640003DFE206918B11F48816820468847207D8B +:1076500058BB0020CDE90000029001208DF8020007 +:107660008DF80500D4E902010088ADF80000087D1E +:1076700009308DF804006846F7F7FEFD9DF8140008 +:1076800098B903980E21406C0546013005F8091B96 +:10769000A168496812F0E3FBE0680169027D2846B1 +:1076A00011F0D4FE68460AF0AFFFE06808B112F0AE +:1076B00029FC204612F04FFA9DF81400207506B000 +:1076C000B0BD00BF50240020B0B586B004460020F5 +:1076D000CDE90000029040F20910ADF804002088C6 +:1076E000ADF80000207A012812D121208DF8020087 +:1076F0001948007878B912F08DF960B9174D6168B2 +:10770000082205F1180011F0A1FE2088288002E06F +:1077100001208DF802006846F7F7AEFD9DF81400D1 +:1077200050B903980721406C00F8011B616812F002 +:1077300096FB68460AF068FF0748007838B912F0EF +:1077400069F920B905480021C0E9061101809DF8BA +:10775000140006B0B0BD00BF242600205024002035 +:107760002DE9F04F85B02048DFF884A000274FF6C0 +:10777000FF7B007800901D48047801A8051DA742F2 +:107780002FD007EBC7003AF82010594527D00AEB55 +:10779000800801208DF80400B8F80200ADF8100050 +:1077A00001A808F0E5FBD0B1124EDDF80090B9F168 +:1077B000000F14D03088B8F80010884208D0BDF807 +:1077C0000610884204D0B11C284610F0C6F810B14B +:1077D000304610F0FFFE1C36A9F10109E7E701373A +:1077E000CDE705B0BDE8F08FD1BA0200E3BA0200E0 +:1077F00020450020305600202DE9F0418AB0054692 +:1078000020480078012839D81F4FF88AA84203D1B0 +:1078100085B30DF049F82BE0284612F042FA48B340 +:10782000044600790138012824D860884FF0000808 +:107830008DF81880ADF8240006AE304608F098FBAD +:10784000C0B1208811496D46088005F10B00311D3B +:1078500012F005FB00200DF05FFFADF814008DF86D +:10786000168028460222217902F088FAC4F80C809A +:10787000012004E0B98C28460EF01DFB00200AB060 +:10788000BDE8F08124260020A86D0020802700207C +:107890002DE9FC41204F0446786808B18047B0B319 +:1078A000F868BA69610312F071FA012500282FD433 +:1078B0001A4904EB440001EB8006F07DFE2838BF36 +:1078C000451C174800210423F57540EA0520019066 +:1078D00001AA20460CF010FB387018B9032070760E +:1078E000FF20B0750F4F12F07CF900234FF0FF0816 +:1078F0000025B84712F075F90123B84712F071F965 +:107900000223B847102086F81880B08300E00B25CA +:107910002846BDE8FC8100BFA0230020B8720020EB +:10792000FF000F9671600200F8B50446FD201D4669 +:107930008DF8030020461E68324600F071F910B140 +:1079400001208DF803009DF80300FD2815D1A6B194 +:10795000E068007B00F00F0002280ED13768204657 +:1079600031463A4600F05CF920B9002F3E46F5D189 +:10797000002602E002208DF803009DF80300FD2898 +:1079800004D1E06B10B104208DF803009DF8037062 +:10799000042F0FD0022F06D0012F0FD128462146E9 +:1079A0000FF04EFC0AE0326822B1284621460FF063 +:1079B00053FB03E0284621460FF030FC78B2F8BDB7 +:1079C0002DE9F843994615460F4606460DF08AF80C +:1079D0001E49DDF820800C78A04216D21C4900EB2D +:1079E000800201EB420212F8073FAB429CBF03202A +:1079F000BDE8F883B8F1000F24D000EB80001570CB +:107A000001EB4000A0F804901CE04FF6FE7000214E +:107A10000DF068F8A04204BF0220BDE8F883B8F179 +:107A2000000F0FD00A4900EB800001F8107001EB45 +:107A30004000FF2181710749C571A0F8049046807C +:107A4000C97C01720020BDE8F88300BFD5BA0200EE +:107A5000B25C0020A86D002010B505F0C1FD044601 +:107A600088BBFBF7D3FCC8B111F0FCFE18490880B5 +:107A700020B91848018821F00701018016480078D4 +:107A8000022804D001280BD11448007840B91548C9 +:107A9000002180F826101248032103E0092409E0A0 +:107AA0000F48012181700F4800F139010E4812F092 +:107AB000D6F900240D48002101800748007810B94C +:107AC00000200CF015FB002C18BF0124204610BD2F +:107AD000887900203E79002024260020E427002019 +:107AE000D0260020A86D0020AE79002014250020AB +:107AF0002DE9F04F87B080465868DDF840A08B46EE +:107B00001F469146002100251B2906D020FA01F2CC +:107B1000D20718BF01350131F6E728064FF0000102 +:107B200014D0E8B212F0F0F990B1044607F1080061 +:107B3000002100221B290CD07B68CB40DB0703D03F +:107B4000435CD6B20132A3550131F3E7002401E0D2 +:107B5000002400217B68BA78E8B2CDE900B902AD13 +:107B60000591084985E811044046FEF7CDFD2CB18A +:107B7000204607B0BDE8F04F12F0C4B907B0BDE829 +:107B8000F08F00BF9279002070B588B004460220C3 +:107B90008DF80A00E08894F82420617EADF8020098 +:107BA000607D8DF810108DF80C00A088ADF80E00E7 +:107BB000501E8DF81200A06A411C069100788DF8C5 +:107BC0001100608AADF81400A08DADF81C00684665 +:107BD00003F02EFF05461048007818B1694620468C +:107BE000FEF736FABDF80E200C4900204FF6FF7361 +:107BF000C4B231F834609E4208D001309642F7D1C9 +:107C000001EBC40041686846884703E015B968463F +:107C10000DF0E2FD08B070BDEC270020DCAE0200E4 +:107C200070B5B2FA82F3B1FA81F45B096409B0B3BA +:107C300012B190F844506DB389B191F844406CB3DF +:107C4000446B0E69096C05698908A408AE4214BF2B +:107C5000ED6800252944611AB1F1704F22DAB2B102 +:107C6000D168097B01F00F01022915D1516B05691B +:107C7000006C146980088908A54214BFE2680022DC +:107C80001044081AB0F1704F01DB012804DB012415 +:107C9000012304E0002302E0012400E0002404EAC0 +:107CA000030070BD00240029C8BF0124002AF6D0BB +:107CB0000129D5DAF3E77047F8B5F0B10446007A48 +:107CC00000F0FE00022818D120460D4600F03AFED2 +:107CD000FF281CBF1E20F8BD227A1B49194B022A1F +:107CE000084608BF18460668002005280AD026FA6C +:107CF00000F7FF0703D00130F7E7E820F8BDC6B270 +:107D0000052E05D1022A18BF032A0DD11A20F8BD6D +:107D1000022A0AD1228803EB80012B0ACB728D72D2 +:107D20000A72120A4A7206E005202268636801EBB3 +:107D3000C001CB608A60227AC0B201210DF0A6F8A2 +:107D40000020F8BD20770020F87300202DE9F84FBF +:107D5000204E214FDFF8848000254FF0010B4FF0BB +:107D600002094FF0110A602D08BFBDE8F88F7C1999 +:107D70002ED0A07A01282BD1607A41B20BFA00F004 +:107D80001131C0B20BFA01F1CA433260726811437B +:107D9000716010F0DDFA04F1100000210EF0AAF974 +:107DA000812809D1A06920B100210EF0A3F9812812 +:107DB00002D184F80A900BE0607A97F861100AFA11 +:107DC00000F00843002187F86100404612F0B2F845 +:107DD0002035C8E708100440206E002040720020C3 +:107DE00070B5044610F0ECFA41F288300EF07AF8E3 +:107DF0001A4D287801280BD8194E4FF4807130782D +:107E000007F0F0FD30784FF4807105F04DFC2878D4 +:107E1000022804D14FF400500121F3F72BFD012C6F +:107E200015D1104803210224104D817004700E48B2 +:107E3000012101700E4805F1390112F010F885F8A2 +:107E400026400FF06DFEBDE870400DF0CDBD41F253 +:107E50008830BDE870400FF05BBB00BF24260020D7 +:107E60009C7A0020D0260020A27A0020A86D002055 +:107E7000AE79002080B51F48007860B111F0E6FCB3 +:107E8000EE281DD811F0E2FC1030C0B211F0F0FC69 +:107E9000194801211BE019480078082815D10FF076 +:107EA0009FFD09200FF07CFF15480078072813D0AC +:107EB000052815D101200EF067FA03F095F90FE0BF +:107EC0000020BDE880400EF05FBA0B48102100781A +:107ED000BDE8804006F01AB907200121ECF78EFCBE +:107EE00008480078012818BF80BDBDE880400FF029 +:107EF00021BB00BFBF7A00209D7A0020D026002041 +:107F00000C7A0020CA270020BCB50446807A0128DC +:107F10000CD1207B00218DF8071060BB1D488DF827 +:107F20000510007802281CD2E07A1CE0258811F0A8 +:107F300087FCE27A85420ED1012A01D1207B07E03D +:107F40001348008800F00700022804D101202073A4 +:107F5000FFF746FF16E0237B2088A11CFAF7A2F961 +:107F600010E002D100208DF8040011F097F801A86C +:107F700009F056F9207BFFF733FF0DF1070152207E +:107F80000AF002F90448816909B120468847BCBD5E +:107F90003E79002024260020547500202DE9F04170 +:107FA0008EB0054611F028FCDFF880800446696831 +:107FB0001022D8F80800D0F808010068836B0AAFD7 +:107FC00038469847064638BBD8F80800D0F808016C +:107FD0000068016901AE304688470D206A69019743 +:107FE0008DF82400D5E9020105926A8B0290288B56 +:107FF000CDE903110790A88B8DF82500101A089081 +:1080000008440690D8F80800D0E9411208681168C1 +:108010008A69314690470646204611F0A8FE002E98 +:1080200018BFE42630460EB0BDE8F0810C010020F8 +:1080300070B51F4DA868D0F8B8100A781D4991F99D +:1080400000101AB1002902D41B49097811B1D0F8E7 +:108050004C05804711F0D0FBEA68184C1269217872 +:108060001278914207D116490978490703D411F0D3 +:108070007EFE012070BD11F07AFE0EF04BFA2078E2 +:108080000FF0FAFA78B1E86824780669204631786A +:108090000CF02AF9347030B1A868D0F8D40090F907 +:1080A000420010F078FEBDE8704011F029B800BF22 +:1080B0000C010020B87A0020AB7A0020582600205E +:1080C000B17A002070B51C480025204C05701B4873 +:1080D00005701B4805701B4885601B480570A0682B +:1080E000D0F80011D0F85022C889103080B29047E3 +:1080F000174E306020B9A068D0F84C058047306832 +:10810000A168D1F80011C989006085801031C18053 +:1081100010483168C0E900150CF09EFEE068C068A8 +:10812000007800B170BDA0680021D0F8582400206C +:10813000BDE87040104700BFB07A0020C27A00202E +:10814000B27A002034250020B37A00200C010020F0 +:10815000787A0020D8790020B0B5234C0021A0689F +:10816000D0F8E8000160A168D1F8D8000068B8B183 +:10817000D1F8E02040681268904211DA0CF040F922 +:10818000A168D1F8D82012685368834204DA50609D +:10819000A168D1F8D8000268D1F8E8000260A168AF +:1081A000D1F8DC00006848B1D1F8E82013681BB1B1 +:1081B0005B6845689D4201DA1060A168D1F8E8006B +:1081C000006848B1D1F8E01040680968884203DAD5 +:1081D000BDE8B0400BF0D6BA0FF092FEA0680021C7 +:1081E000D0F8E8000160B0BD0C0100202DE9F0419D +:1081F000044680681F4F206297F85E00E8B197F848 +:108200005C00D0B91C480068006B8047DFF86C80C8 +:10821000D8E910562A46334610F018FFA0FB052374 +:1082200000FB063301FB0531C8E91221B9687B6DFB +:10823000BA689A1A411A91420CD90EF031FA01210A +:108240002175A2681044E06097F85C0078B187F867 +:108250005D100CE001212175A2681118181A8242E4 +:10826000E16004D21046BDE8F04110F0A3BCBDE8C7 +:10827000F08100BF082000208C010010886E0020D3 +:10828000002840D02DE9F0418EB01F490AAE0025EC +:1082900003904FF020080896059507918DF8185027 +:1082A00001A801210D901948EFF3118788F3118877 +:1082B000047A017280690C900BF090FB14494A68B3 +:1082C0000D980160426010604860FFF78FFF0C98C6 +:1082D00046620B960A96204687F311880BF09CFBAA +:1082E000EFF3118088F311880D990A684B681A60C2 +:1082F0004A6809684A600D9580F311880C984562B8 +:108300000EB0BDE8F0417047C1870200382200205E +:108310000820002070B5204D04462878C0B3A07C0A +:10832000B0B360890BF008FD022801D0607978B302 +:108330001A482978821C0B465BB132F8025CA68988 +:10834000AE4203D11578E67CAE4223D00632013B23 +:10835000F2E7821E481C4FF6FE7101381AD0931DB9 +:1083600052888A421A46F8D10C2004211880A0892C +:1083700023F8040CE07C0A4C03F8020C20780BF084 +:1083800021F828B9207804214FF4FA7211F022FD67 +:10839000012070BD002070BDA1270020B45F002027 +:1083A000997A0020FF2804BF4FF0FF3070472DE975 +:1083B000F84F1D4B0C4605464FF4BE21AF0004F0AC +:1083C000020643EA80004158C9B2914217D11748CA +:1083D0004FEA14299A4647EA0008834611F00CFA3E +:1083E0000BF10101220C88F8009039430A7048F023 +:1083F0000201220E0A7011F0BAFC534605E024F087 +:10840000FF0100F5BE201143016026B945EA0300D3 +:1084100004F0010101700648012181EA5601384348 +:1084200001600020BDE8F88F0020024001100840E4 +:10843000001A44422DE9F84F214CDFF880A0814614 +:1084400000254FF0010BE8469AF80000E778C0B22B +:10845000A9B281422ED2A078FEB2864220D0304608 +:1084600000214246042310F0B9FF9DF8000078284F +:1084700016D0FF2801D07E2803D130467C210CF095 +:1084800061FA06EB4600E77004EB8000808BE08029 +:108490004844B0F5005F0ED9304678210CF052FA0E +:1084A0009AF800005BFA87F10135B1FBF0F202FBAC +:1084B0001017CCE7FF27F8B2BDE8F88F9B7A0020B1 +:1084C000B8720020F8B5D0E90167054611F094F9BB +:1084D0000446D6F8C00098B396F8F81019B9007C95 +:1084E0000338012831D82846FEF71CFFD6F8C00013 +:1084F00000220223016805463DB12F7C033F022F75 +:1085000028BF2B742A606D69F6E73246016052F885 +:10851000C81F21B10A4649690029FBD114321060F5 +:108520000020C6E93000C6E93400C6E9360020461E +:1085300011F01DFC06F13000BDE8F84011F0FCBC64 +:108540003868416821F0020141602046BDE8F840EA +:1085500011F00DBC7CB50C46080426D4E00704BF1E +:1085600000207CBD1E48007808F0E6FF054668B193 +:1085700001200DF107018DF80700522009F004FEDB +:108580000020002610F0FAFF1448867002200EF03A +:10859000D5FE38B101464570332008700F48C078C9 +:1085A00006F0E2FD84F001007CBD0C4E307806F050 +:1085B0007FFA80B1054600780D2805D00C2806D139 +:1085C000284610F067FC02E02846F4F751FC2846E4 +:1085D0000FF092FDEAE784F400407CBDCC26002039 +:1085E000917A002010B5044600780438052831D867 +:1085F000DFE800F0030D151E26311D480078013814 +:10860000012827D82046BDE81040F0F7CDBD184816 +:108610000078F8B92046BDE81040F8F7E3B81448F0 +:108620000078012816D12046BDE810400EF098BB16 +:108630000F48007870B92046BDE8104010F0E8BC43 +:108640000B4800780138012804D82046BDE81040C6 +:1086500010F084BF10BD0648007820B9607F10B9C3 +:10866000601D03F059FA2046BDE8104011F06EBCC1 +:108670002426002010B586B0002190F90B20ADF81B +:108680000C100188B2F1FF3FADF80E104168049163 +:1086900002F0400102DD21B901200DE039B90520C9 +:1086A0000AE0807A012814BF0320002004E0807AC9 +:1086B000012814BF072004208DF8140001ACAB2062 +:1086C0000021224606F01CFC0DF103012046002289 +:1086D00001F03EF80A480078012808D19DF803000F +:1086E00028B900208DF8150003A804F0DAFB01205A +:1086F0008DF8150003A804F0D4FB06B010BD00BF30 +:10870000C22700202DE9F0418EB0054611F074F823 +:10871000DFF87C80044669681022D8F80800D0F899 +:1087200008010068836B0AAF38469847064628BBA5 +:10873000D8F80800D0F808010068016901AE304699 +:1087400088470D2005F1080301978DF824000FCB11 +:10875000CDE90311CDE905320290288B0790688B93 +:108760000890287F8DF82500D8F80800D0E941123C +:10877000086811684A69314690470646204611F05C +:10878000F6FA002E18BFE42630460EB0BDE8F081A0 +:108790000C01002070B51E4DA868D0F8B8100A78FA +:1087A0001C4991F900101AB1002902D41A4909781C +:1087B00011B1D0F84C05804711F01EF8EA68174C4B +:1087C000126921781278914206D115490978490732 +:1087D00002D411F0CCFA17E011F0C9FA0DF09AFEAC +:1087E00020780EF049FF78B1E868247806692046C1 +:1087F00031780BF079FD347030B1A868D0F8D4002E +:1088000090F9420010F0C7FA10F07AFC012070BD18 +:108810000C010020B87A0020AB7A002058260020F6 +:10882000B17A0020F8B5044690F8300003282ED124 +:1088300094F83A0003282AD11D4E04F128010023A0 +:10884000B068D0F8D4201632D55CCF5CAF422DD1C1 +:108850000133082BF8D1D0F830244A2090476768BC +:108860000DF102052946388811F050F85020904744 +:108870007888294611F04AF84B209047B7F8050050 +:10888000294611F043F853209047002100E0E821E9 +:1088900007488068D0F8F40041702A20207004480E +:1088A0008068D0F8401320468847F8BDEA21F1E7F8 +:1088B0000C01002070B5044610F09EFF184E0546CE +:1088C000307810B1174811F000FA1748007810B14D +:1088D000144811F0FAF91548007870B91448007876 +:1088E00058B91448007840B91348007828B913489B +:1088F000007810B91248007820B1284611F037FAF4 +:10890000002070BD0DF006FE2846347011F02FFADD +:10891000601E022802D3034811F0D7F9012070BD70 +:10892000B02700200C010020B27A0020B07A00208D +:10893000B37A0020B87A0020AB7A0020B17A002008 +:10894000B67A00202DE9FE4F0446007A02280ED1A7 +:1089500020888DF80A10090A04250DF108088DF801 +:108960000B108DF80800000A8DF8090001E00825B9 +:10897000A0461648DFF858B00026EA4600F108077E +:108980000BF10809052E1CD0207A1049022808BFD7 +:1089900059460968F140C9070ED0022839465046A9 +:1089A0002A4608BF494611F0D5FA404651462A46A4 +:1089B0000FF096FC012805D009F1040908370136AB +:1089C000E0E7FF26F0B2BDE8FE8F00BFF87300209D +:1089D0002077002010B5407820B11C48002180F895 +:1089E000261010BD194C082084F8260094F8380091 +:1089F00058B91748016809B100208847A18C0520A3 +:108A00000DF0CDFFA08C09F08BFC124800780128F6 +:108A10000AD1002011F06CFAE18A06200DF0BFFFA8 +:108A2000618B04200DF0BBFF0C4800680028D8D0F3 +:108A3000094800780128D4D109484FF480414FF407 +:108A40007A720078BDE8104011F0C1B9A86D00201D +:108A50001025002024260020CA270020842300207F +:108A60009C7A00202DE9F041064600888846114690 +:108A700014460AF0F3FB7088E1796081B088A08128 +:108A8000B079A074F079E0740820607021B11020F2 +:108A900006F1080160706161217A29B100F10805D1 +:108AA00030446570A06100E00546607918B1705DE2 +:108AB00001356570607120460DF098FA074688B957 +:108AC000A179701951B10E30A0620848007B10F0F6 +:108AD0000DFD2844A8EB00000E3802E0A062A8EBD0 +:108AE000050020773846BDE8F08100BFA86D002062 +:108AF000BCB5044602208DF8050001A80DF0F0FF7A +:108B0000B8B30546006904210180217A0139B1FA20 +:108B100081F1490949014170627A012A04BF40315B +:108B20004170A27A012A19BF0120A87680314170D4 +:108B3000607A012804D1606808B101216977286250 +:108B4000E07A012804BF0120E88220880BF0F4F8C5 +:108B500018B1E88A40F00400E8820120A87710F0FC +:108B6000CBF90548686220886880284605F044FFF4 +:108B7000BCBD1020BCBD00BFE07900202DE9FE4344 +:108B800080460A201E4691460F46002908BF00EB8A +:108B900043008DF8090002A80DF0A2FF00B30546BE +:108BA00046EA471049462C69607009202070A01CD5 +:108BB00011F055F9BFB10126AE7710F09DF91148BB +:108BC0006C462146686240460DF0A6F808B12C625A +:108BD0006E772846A5F8028005F00EFFBDE8FE83FB +:108BE0000120BDE8FE830A9804F10A01002EE2D0BC +:108BF00010F8022B013E01F8022B10F8012C01F8AD +:108C0000012CF3E7E07900202DE9F041154610F042 +:108C1000FCFF804625B3DFF874C0DFF874E0002362 +:108C20000027BCF80060DEF80020FCB2AC420CD299 +:108C30007008862809D87444701C0137217BACF871 +:108C40000000915523730646EFE7DCF80420AC42A0 +:108C500018BF002A06D0BCF802104FF48770904766 +:108C60000A48426812B1A8B2002190470748002183 +:108C7000202200230180064988680C310EF029FE6D +:108C80004046BDE8F04111F0AEB800BF70260020AC +:108C900048230020F0B589B0ADF8201007907BB3D1 +:108CA00072B391B207A802AA1C4605F0CFF9064696 +:108CB00038BB194F786808B1804728B3B86801F00D +:108CC0001DFC05461548002203230092C188C07888 +:108CD00002AAF1F791FC06460A2818D0F0B2A8B90A +:108CE00002A821460222EFF7FFF8064678B9BDF840 +:108CF000141061B19DF8180007F0B0FD3E7806E051 +:108D00000426F0B209B0F0BD0B26FAE70126B868D8 +:108D1000294604F021FFF4E7A0230020B8720020C8 +:108D200080B50DF0FDF918480023811C1748027822 +:108D30004FF6FE703AB1C1F80230088021F8023CCB +:108D40000831013AF6E7134A114900231278083135 +:108D50002AB101F80A3B013A21F8100CF8E70E4954 +:108D60000E4A097819B122F8080B0139FAE70C48C4 +:108D70000C494FF47A72007808700B481021007883 +:108D8000BDE8804011F023B8503D0020D7BA020062 +:108D9000B25C0020D5BA0200CEBA0200AA68002058 +:108DA000DCBA02002F7900209C7A0020F8B5D0E9C7 +:108DB00000670D46044610F01FFD96F8311049BBC0 +:108DC0001949097831B30121A6F8311010F0CFFF0D +:108DD0001649002D18BF29460A784868012A08BF9D +:108DE00000281BD0C6E90240D1E9020186F83020F4 +:108DF0000F4A104B3061B8683162A0F58071914222 +:108E000038BF034606F13400002173610EF0B8FF4D +:108E10002046F8BD10F0ABFF0020F8BD8B680020A5 +:108E2000002BDFD1F5E700BF1823002040B8020077 +:108E300001FFFF0080A90300B0B586B00446807A28 +:108E400058BB60680DF117016A4600F081FC0146CD +:108E5000E07AC00621D49DF8170001281DD19DF8A5 +:108E60001000022819D1164A002301EB4100CDE978 +:108E7000003342F8203002EB800014224360FF20D0 +:108E80006B468DF810009DF81200013000F00F00C5 +:108E90008DF8120004200DF0D7FB2046F9F774FA84 +:108EA000054648B9A07A38B9E07AC00604D410F073 +:108EB000D9FC6168F9F762FE284606B0B0BD00BF74 +:108EC000F033002010B51D48007810B91C48007818 +:108ED00020B11C488068D0F84C05804710F08CFC0D +:108EE00019490A78022A24D10122184C0A702378E1 +:108EF000062B05D89A4012F04C0F1CBF83220A7033 +:108F000010F035FF2078042807D80121814011F0A6 +:108F1000130F02D0FAF70EFA207806280DD8012197 +:108F200001FA00F010F04C0F07D0BDE8104009F036 +:108F3000CBBFBDE8104010F01ABF10BDB07A0020C2 +:108F4000B37A00200C010020B87A0020BB7A002000 +:108F50002DE9F04186B0DFF8708098F8650078BBA5 +:108F6000012088F86500C8F80480C8F800800EF079 +:108F700023F8164801AA114690E8F8000420F8C129 +:108F80000490134808F11004124900F11C03204614 +:108F900008F0B2F8C8F84C400AF002FD0E48D0E9DB +:108FA000102347F69160101A73F1000031BF4FF0A3 +:108FB000FF30002047F6906110F048F8C8F85800DC +:108FC00006B0BDE8F08100BF0820002054B80200C0 +:108FD000A01F0020913E0100886E002010B58CB0CB +:108FE0000446007A042802D110F078F910B1C220AA +:108FF0000CB010BDA07850B960680DF1030101AA52 +:1090000000F0A6FB9DF803000028F0D0A078002116 +:10901000CDE906118DF82C10089140F20B11ADF836 +:109020001C104121002808BF612120888DF81A10EA +:10903000ADF8180006A8F6F71FF99DF82C000028D7 +:10904000D6D109981021406C0170A1784170217A25 +:1090500081700330616810F002FF06A809F0D4FAAD +:109060009DF82C00C4E770472DE9F8430446002022 +:109070006FF001014FF6FE72A04648F8040FA8F801 +:10908000081038F8021CC8F80400914202D1C0B29E +:10909000BDE8F883DFF8549000250020B9F800708F +:1090A000BAB2A9B29142F2D24A0012FA85F3D9F8C3 +:1090B000042012F823301B0716D001EB410163880E +:1090C00002EB81014A8893420ED10E1D30460EF00C +:1090D000F5FF012805D14046314610F07EFAB9F877 +:1090E0000070A58101203D460135D9E740260020CA +:1090F00070B51B4E04464FF48061307806F072FC68 +:109100001848092180F8261017480078022802D153 +:1091100016480021017065690FF0EEFE14492846DB +:109120000EF01BFCD8B110200EF008F9B8B10546BE +:109130000220A1692870A06AB0F801206A80C07876 +:1091400068704A2009F020F8A07910B90948052173 +:10915000017030782946BDE8704006F005B870BD52 +:109160009C7A0020A86D002024260020DC27002007 +:10917000E0790020D02600202DE9F04188B0ADF83C +:109180001C10069006A801AA002104F05FFF054606 +:1091900068BB194E706808B1804738B3B06801F0F9 +:1091A000ADF9164F04464FF000080323CDF80080B8 +:1091B000F988F87801AAF1F71FFA054688B9BDF8D1 +:1091C00010109DF8140007F049FBF988F878CDF8E5 +:1091D000008001AA0323F1F70FFA35780A2818BF97 +:1091E0000125B068214604F0B7FC00E00B25E8B289 +:1091F00008B0BDE8F08100BFA0230020B8720020B5 +:1092000010B504461E4849B138300068B0B1C36893 +:109210001B7B03F00F03022BF7D101E0806B68B1D9 +:1092200002B11060C268137B03F00F03022B08D158 +:1092300051B101698A8DC968114415E000210020EF +:109240001CE00120002119E012880169A2F6030246 +:10925000012A4A8B8CBF0969496919231144094ABB +:1092600092F8622012FB0311406B0CF0B1FD2060FC +:1092700010F01AFE2168B1FBF0F10120216010BD51 +:1092800030210020206E00202DE9F84F07461E48AF +:1092900015460E46009300F138094C4624680CB17F +:1092A000B442FBD14FF0000A00F1400B44B32069F7 +:1092B000D4F80080B84220D1204600224FF08053DD +:1092C0000DF0AEFC009870B1204600224FF0807384 +:1092D0000DF0A6FC30690D49086291F8240040F0B9 +:1092E000010081F82400484621460DF0BDFB584698 +:1092F00021460DF093FF0AF1010A002D4446D5D115 +:109300005046BDE8F88F00BF3021002070200020BB +:109310002DE9F0438BB005AC20460EF021FD8220F4 +:109320001821224610F0D0FB18480DF1080800253E +:1093300008F104090778164800F13906ECB2BD427D +:1093400010D20720214600220C23CDF800800DF01A +:1093500065F93046494608220EF0C2FF0135002863 +:10936000ECD004E04FF0FF30013CCDE903000A9857 +:109370000290A1B202AB07200C220DF065F905485E +:10938000002101800BB0BDE8F08300BFD3BA02001A +:10939000A86D002014250020F0B585B005461E48B4 +:1093A0001E4FA96900883E460C88844218BF0026DB +:1093B00016D1688803A901F083FC01280DD19DF81E +:1093C00013209DF812109DF81100042A08BFCF2920 +:1093D00012D0542A08BFEF2911D00020002112E03A +:1093E000297C687C48F202022346CDE90021A91CB1 +:1093F00080220DF051FC0DE08C2802D0E9E74428D2 +:10940000EBD111215F203971F87028462146324690 +:1094100004F0A8FA05B0F0BD887900203E7900205C +:10942000BCB504460022806982230192817839B359 +:10943000FF294FF0000524D0194A0088128880B215 +:1094400090420DD101A80CF089FF019A0023054636 +:10945000002A08BF6FF07C03002818BF012510E028 +:1094600010490978022908D20FF0DCF96FF0760371 +:10947000002808BF6FF07E0301E00CD1802300229A +:109480000025D9B22046FAF737FC1DB1019808B182 +:1094900010F038FDBCBD002200250023F1E700BF1D +:1094A000887900202426002070B588B004461E4824 +:1094B000A16900880E784A7846EA022282421DD1CC +:1094C0008A78102A28BF102203318DF80C2003ADB2 +:1094D000681C0FF0BBFF812011212A4610F0F4FA1E +:1094E0009DF80C001149002818BF01200A8822F0BD +:1094F000100242EA00100880002000E084208DF86D +:109500000900207C0DF1090148F2140203238DF8B3 +:109510000B608DF80A60CDE9001004F11100A11C68 +:1095200008F006F908B070BD887900203E79002067 +:10953000B0B588B010F0B5FB18B304461D480078EC +:10954000012804D1607900F0E70008306071002044 +:109550008DF804006088ADF8100001AD284606F0D3 +:1095600007FD208804350695ADF8140010F07AF94F +:10957000ADF81C006079810601D5410603D40021B5 +:1095800002E0002014E001218DF81F008DF81E106C +:1095900005A80DF0A9FB30B128460DF02EF928469C +:1095A00005F0DAFC03E0607900F0FB006071012057 +:1095B00008B0B0BDE027002070B590B06E460C46F4 +:1095C00005464021304610F0A9FB304629460A22C4 +:1095D0000FF03CFFD5F80A00E989CDF80A0006F142 +:1095E0000E000DF049F9288AADF81700688AADF829 +:1095F0003B00E87FADF82C0010F086FC0A9070B1BB +:10960000EA7F296A0FF022FF4CB10A999DF82C00DD +:10961000A04720B10A9810F075FC1A240AE0074808 +:109620008068D0F888126846884704460A9808B1CE +:1096300010F068FC204610B070BD00BF0C01002087 +:10964000F8B50C46064610F0D7F81D4F0546B86829 +:109650007EB1D0F894000121007802F00DFD28467B +:1096600010F085FB20460AF051F80EF009FC10B30B +:10967000F8BDD0F838038047C0B105F05BFBA8B156 +:10968000F8688069007888B9FAF79CF90D4E30784F +:1096900060B9B86800210027D0F89400007802F083 +:1096A000EBFC10B9204607F0D1FB37702846BDE827 +:1096B000F84010F05CBBBDE8F8400BF065BB00BFA4 +:1096C0000C010020B67A002070B51A4800211B4D0D +:1096D0000160194801604FF470002860184801705B +:1096E0001848017010F091FA174E0446306830B9EE +:1096F00016488068D0F84C058047306828B110F0D3 +:10970000D9FB10B1306810F02CFB3068012110F04B +:10971000D3FB306810F0D2FB204610F064FB0B48FE +:109720008068D0F814150F2088472868BDE870407D +:1097300001F092B9307A00203C7A0020407A002073 +:10974000907A0020B67A0020342700200C010020F7 +:109750002DE9F0418CB00D4601464FF6FF70ADF893 +:109760001A008DB381B30027082614460DF11C089A +:109770000420002214232F70CDE902610DF11A019B +:10978000CDE900860AF0C8FE70B1CDE9047704A8DF +:109790000DF11A0100221423CDE90086CDE9026003 +:1097A00004200AF0B9FE01E001202870BDF81A007B +:1097B00054B107490988884206D207A920461422D5 +:1097C0000FF044FEBDF81A000CB0BDE8F08100BFF8 +:1097D000C0BA0200B0B592B0044600684189CA0719 +:1097E00038D021F0010141810168086AC97F01ADCB +:1097F0002A46FFF737F968BB0B990878042829D166 +:109800000020CDF84200CDF83E00CDF83A00BDF87A +:109810000E00ADF838000EA891F9011002308A064A +:1098200044BF01228DF84320B1F1FF3FCAB2DCBF33 +:1098300001218DF84210510605F1140158BF05F1C0 +:109840001801096810F00BFB20798DF844000EA870 +:1098500010F046FB12B0B0BDF0B589B0ADF82010E5 +:10986000079043B33AB391B207A802AA1C4604F08A +:10987000EDFB064600BB174F786808B18047F0B192 +:10988000B86800F03BFE054613480022032300920F +:10989000C188C07802AAF0F7AFFE90B1C0B20A2822 +:1098A00011D102A821460122EEF71EFB0646002830 +:1098B00018BF012608E00426304609B0F0BD0B268B +:1098C000FAE70D2600E00126B868294604F044F9BD +:1098D000F2E700BFA0230020B87200202DE9FF416D +:1098E000DFF870800C460546ADF8040002208DF8C4 +:1098F0000C00B8F8241001A80EF082FA1A281BD028 +:109900001548164900234FF6FF770278FF209A4248 +:109910000BD031F82360BE4203D1FF2808BFD8B274 +:1099200001E0AE420AD00133F1E7FF2809D1B8F8CF +:10993000241001A810F00CFB002008E001EB8300CC +:1099400003E021F8205001EB80004480012004B0A6 +:10995000BDE8F081A86D0020D2BA020098780020FE +:1099600070B514460E460FF047FF0325052E2CD880 +:10997000DFE806F003090E2B161B19498A6CCAB1E1 +:10998000896C098E02E0154991F8601021801BE076 +:109990001149097E0239B1FA81F14909217013E0B8 +:1099A0000C490A68226049680DE00A490A681AB140 +:1099B000D26802E0802508E000222260496809B1EF +:1099C000C96800E000216160832510F0D0F92846C5 +:1099D00070BD00BF70200020D01E0020206E00202F +:1099E00030210020F8B504460FF006FF1A4F054657 +:1099F0004FF0FF30386204F1B80010F0B2F9174EA2 +:109A0000B6F85600B6F85410884210D1144890F8B1 +:109A10002400397E022918BF002808D0284610F0FB +:109A2000A6F9072003F058F80FF0E6FE0546B6F851 +:109A30005600B6F85410884206D10A4810F091F941 +:109A400008200BF01BF802E0012084F8FC002846F7 +:109A5000BDE8F84010F08BB9D01E00203021002066 +:109A600070200020387100201C48007830B1022896 +:109A700010D001281CD144F2010101E04FF48041D3 +:109A8000174A002811806FF0710108BF6FF0700154 +:109A9000917014E0124844F202016FF07F020180DD +:109AA00010490978012908BF6FF07702827006E03B +:109AB0000B484FF40062018862F3DF01018008481F +:109AC000A021094A41810021C0F80320C17101731E +:109AD000018941F430510181704700BF24260020E4 +:109AE0003E790020E5270020000050A0E0B5134695 +:109AF000062813D0052814D088BBA1F13A0002280B +:109B000016D3622917D068291DD0B1F5817F12D0F4 +:109B100040F20310814222D114491AE0009306203A +:109B200001E005200093002210230CF077FD8CBD8E +:109B30000846012101E008460021102202B0BDE8DC +:109B400080400FF019BB074800780138012806D87B +:109B50000549184610220FF079FC00208CBD0A2020 +:109B60008CBD00BF2426002024B9020014B90200D5 +:109B700070B504461848C1688969097819B1174851 +:109B80000121017070BD164E164D31788A00B5FB6B +:109B9000F2F2A24204D28068D0F84C0580473178B6 +:109BA00004FB01F01049096801EB80040F480068CC +:109BB000C06B8047211AA1F54871B1F1FF3F05DC68 +:109BC0002918091B013148BF00F54874084821468F +:109BD000BDE87040F7F760BE0C010020B67A0020A7 +:109BE000B47A0020FFF6C2FF307A0020347A0020D9 +:109BF000BD6402002DE9F8431B4C1A482188868C6D +:109C000081845020214608F0BFFA184825884FF675 +:109C1000FE78174C08F10109077887B16089294659 +:109C2000B04208D0A84207D020461C2110F076F898 +:109C30004946A4F800806181013F1C34EDE70D4CDA +:109C4000206868B106200DF079FB48B14FF48071AF +:109C500085804180D52101702168BDE8F84308471F +:109C6000BDE8F883A86D00209A690020D1BA0200EF +:109C70003056002060270020F8B5014600681B4DD3 +:109C80000022002304882D6855B16E7B052E05D176 +:109C90002E683688A64208BF013201330435F2E748 +:109CA000134C0526DBB20127D2B2258A4E734E89AA +:109CB00046F400664E810F4E3678B3420E4B28BFF5 +:109CC0003D461B789A424FF6FF7228BF3D460D81F4 +:109CD0000188914205D0A18C0EF092F81A2818BF85 +:109CE000F8BD0120BDE8F8400FF0B7BF587A00205A +:109CF000A86D0020DDBA0200DEBA02002DE9FF41A6 +:109D00000D4603A90DF10A0208F0FEFE044678BBD9 +:109D1000039FBDF80A007880182010F0F5F838B3DA +:109D20007988064600900620002218234FF000088C +:109D30000CF074FC3046294610220FF087FB79881E +:109D4000062018223346C6E904880CF07DFC304614 +:109D500018210FF0E3FF304610F0D4F87888064958 +:109D600000EB400041F8208001EB8000C0F8048047 +:109D7000204604B0BDE8F08130750020F8B50746F4 +:109D8000042014460E468DF8010068460CF0A8FE2B +:109D900048B30546006907210170397D4170797D1E +:109DA0008170B97DC17007F10B00286240F201108B +:109DB000A5F81D000FF0A0F80E48402168620120B0 +:109DC000A876701E10F0FD0F0B4808BF4FF4886195 +:109DD000012C0088E982688004BF0020287628468C +:109DE00004F00AFE00E0102003494FF6FE720A80DC +:109DF000F8BD00BFE0790020802700202DE9F84F52 +:109E0000DFF87090DFF870B000244FF0010AE846E8 +:109E1000002599F800009BF80370C0B2A9B28142F6 +:109E200025D29BF80200FEB2864213D030460021B4 +:109E3000424604230FF0D2FA9DF800007C2818BF98 +:109E4000FF2811D106EB46000BEB8000808B201A17 +:109E500000F5005499F800005AFA87F10135B1FB7A +:109E6000F0F202FB1017D8E77E28EBD0F2E720468D +:109E7000BDE8F88F9B7A0020B8720020F8B51E4D1F +:109E800004464FF0FF3128680FF0D8FED4E901678F +:109E90007168388CC5E90110796911BB398B294487 +:109EA0000A7B013A0A7311061BD1204604F014FF05 +:109EB000B92029898DF8030020460FF07AF90DF1B9 +:109EC0000300012105F0DEFE298920460FF07AF912 +:109ED00070680FF0A0FF388B002105EB8000016156 +:109EE000A86881B22046FCF7BAFB002030702868D1 +:109EF00010F01CF8F8BD00BF0C2400202DE9FE4333 +:109F00008BB11D681E46804685B10FF07EFE04466B +:109F100028680FF0CFFF10B128680FF022FF20460D +:109F20000FF061FF1BE00220BDE8FE830C20174606 +:109F30000C46FCF739FDE0B1E946054648460FF00E +:109F400014FE002041464A4602958DF8000001901B +:109F5000094809F0CFF885E8910050B135602868CC +:109F600041460FF0A9FF28680FF0A8FF0020BDE8C8 +:109F7000FE830820BDE8FE83E19D0200F8B50A4695 +:109F80001C491D4D00234FF6FE760C7802F040016F +:109F90009C420DD035F83370874207D1B04209D0CA +:109FA00005EBC307BF7957407F0613D50133EFE7B1 +:109FB000224600E0DAB24FF6FE73984208BFA24292 +:109FC00011D10026B44207D005EBC600007928B1B4 +:109FD0000136F7E7DAB206E0224604E035F836004B +:109FE0000DF073F8F2B20020A24238BF05EBC200B8 +:109FF000F8BD00BFD6BA02004C5000207CB51C460C +:10A0000016460D46042803D0022812D001282BD171 +:10A0100028460121224601F06FF828B34EB12846A8 +:10A0200002F0A8FF12490978884202D2012030705C +:10A030001AE028460021FFF7A1FF70B1817911F0E5 +:10A04000180F0AD00B49438800884FF6FE72009221 +:10A050000022C98A05F012FF08E00748214602786D +:10A060002846F4F773FC08B100207CBD01207CBDBC +:10A07000D7BA0200A86D0020CABA020070B5056800 +:10A08000D5F8F81031B3D5F8582144685668A16B5B +:10A0900020683268D16202210EF0ECFDD5F858013B +:10A0A000A16B154A40680068C0F8041591FAA1F147 +:10A0B00012683068B1FA81F1926990470446D5F888 +:10A0C000F800011B6879022806D105F1D0000BF0D9 +:10A0D00096FE0BE000240CE0D5F8F400D5F8FC2047 +:10A0E0000A44401AC5F8FC20C5F8F4000020C5F861 +:10A0F000F800204670BD00BFD40100107FB50020DD +:10A10000ADF80C000190ADF8080014200FF0FCFE33 +:10A11000D8B1044618480068A0B1022601AD142E3B +:10A1200006D0A019294606220FF090F90636F6E768 +:10A1300003A9204602220FF089F94C20142122465F +:10A140000FF0C2FC20460FF0DDFE18200FF0DCFE01 +:10A1500088B1182104460FF0E1FD0025022D07D833 +:10A16000A9B20620182223460CF06EFA0135F5E755 +:10A1700020460FF0C7FE7FBDEC2600201CB51B4813 +:10A180000078022831D11A4C206910B10AF090F8F9 +:10A19000FAE70EF02DFA17480178082908D00129AE +:10A1A00005D101200021BDE81C40EAF727BBC170A2 +:10A1B000082101700FF0E2F80A200DF0F1FD0E48C1 +:10A1C0000221007805F00EFC4FF4804000210024AD +:10A1D000F1F750FB0DF1070152208DF8074007F011 +:10A1E000D3FF08200021EAF709FB1CBD242600202C +:10A1F000AC2200200C7A00209C7A00202DE9F84344 +:10A20000DFF874901446D9F8082002EA01038B4263 +:10A2100021D1806843688B4220D966186FF005050C +:10A220009E4226D82240A24223D10068471808F057 +:10A230000BFD8046ACB10FF0DFFA064638460EF053 +:10A2400025F8054630460FF092FD5DB9D9F80400B7 +:10A25000241A0744EEE76FF004050AE06FF00305E7 +:10A2600007E0002540460DF097FA002D18BF4FF08B +:10A27000FF352846BDE8F883DC25002070B51C4D6D +:10A28000A968086C006828B9D1F84C058047A8680F +:10A29000006C00684068174E007800F020003070B5 +:10A2A0000FF0AAFA044614480178832911D13178B5 +:10A2B000A1B1A868016C096891F8781011B9D0F8BB +:10A2C0004C05804720460FF052FDBDE870400BF072 +:10A2D000BBBB2046BDE870400FF049BD8521017031 +:10A2E00020460FF044FD0020BDE87040F8F714BA96 +:10A2F0000C010020C47A0020B87A0020BCB50446C6 +:10A3000040780AF0EBFA6078A0F11901022903D332 +:10A31000F12801D0E12809D1144D287818B900207E +:10A320000BF09AF9287880F0010000E000200F4936 +:10A3300008701048007802280BD10D48007840B909 +:10A34000607840F00200EB2803D130200021F1F7C3 +:10A3500091FA094863780122818C408B0092002297 +:10A36000EEF77EFBBDE8BC400CF0FBBEB72700203B +:10A37000E527002024260020A86D00207FB50EF0E0 +:10A38000E9FBA8B1417B062912D1016845890A7A07 +:10A390008DF80C200C88ADF804400CF013F928055A +:10A3A00004D5002021460CF07BFD20B1012000E007 +:10A3B000002004B070BD104DA98C01A80FF0C8FD9D +:10A3C000002000210CF06CFD04464FF6FF7674B1BE +:10A3D00020680188B142E9D0A98C0DF011FD1A283E +:10A3E000E4D0204600210CF05BFD0446EFE700209E +:10A3F0000FF033FCDAE700BFA86D002070B50D4602 +:10A40000242104460FF08AFC8DB328781A4E207060 +:10A4100068786070A878A070E878E070287920717A +:10A4200068796071A879A071E879E071287A207262 +:10A43000687A6072A87AA072E87AE07204F10C007F +:10A44000E968B047287C2074687C6074287DA0741B +:10A4500004F11300A969B047E96904F11700B04796 +:10A4600095F82000E07695F82100207770BD4FF632 +:10A47000FE70208070BD00BFDB9D020070B5184BE0 +:10A480002021EFF3118081F31188174C1548DA6C05 +:10A4900002609C64154C1A661C64154B04689C424F +:10A4A0000FD14268144B22F47F421A4442608176F5 +:10A4B0000021C160D0F82C1221F04041C0F82C12CC +:10A4C00070BD0C4D0024362CEBD00E2C8EBF42F804 +:10A4D000245053F8246042F824600134F3E700BFAD +:10A4E000381F002008ED00E00010000000300120BF +:10A4F00000000000696F02000000FA052DE9F0433A +:10A5000085B007461C480125846984B3666990F8C4 +:10A5100008800572B868012807D100254046BD6053 +:10A520003C61FE6009F078FA21E03869A0421AD057 +:10A53000204607F114090EF05AFC01A900254846EF +:10A5400032466162CDE903450DF018FA3869406979 +:10A55000864203DD38693146FBF79AF8404609F038 +:10A560005BFA656203E0404609F056FA0125284689 +:10A5700005B0BDE8F08300BF38220020FEB51446C8 +:10A580000DF1050207230D4606460EF027FF9DF844 +:10A5900005109DF806209DF8073026749DF80A6086 +:10A5A000A5819DF80B009DF808504FEA910C01F031 +:10A5B0000301A07242EA01219A009DF8093084F853 +:10A5C00008C042EA9512E1809F01A28047EA9607FF +:10A5D00067720127962806F0030008BF0427384356 +:10A5E000E07205F03F00800140EA9300E08108033B +:10A5F00040EA0C6010442060FEBD70477FB5054600 +:10A6000008460C460FF0AAFB98B10188A94210D069 +:10A61000017904290DD80139058001290DD8144983 +:10A62000097869B1134A52F82110C1EB0111890070 +:10A6300008E00025284604B070BD6FF0010104E079 +:10A640000C490968002280F820208161C161002145 +:10A650006E46ADF802500125C160301D21468DF8CF +:10A6600000500EF0BAFF3046F7F708FAE2E700BFF5 +:10A67000D827002090B40200B0B51D4DE868D0F88E +:10A68000880080470FF0B8F80446E868C06D80473E +:10A690000FF070FA496A90F942008847D5E9020143 +:10A6A000D0F8AC00896C007888470FF063FA096E27 +:10A6B000C08C88470FF05EFA496E408D88470FF0D6 +:10A6C00059FA896E4430884720460FF050FB0FF04E +:10A6D00051FA096B90F843008847A868D0F83024F5 +:10A6E000D0F8D40000F129015220BDE8B040104755 +:10A6F0000C010020BFB5002000210EF06DFB134CB3 +:10A700000021206000200EF067FB606001AC204655 +:10A710000FF0C2FA0E4D0121224628460DF0D8FF57 +:10A720000C4C25600FF006FA21680B4A0AF058F924 +:10A730000A4908700FF0A2F809480FF0A5F8094877 +:10A7400009490A4A09F084FBBFBD00BF302600203A +:10A7500074770020507A0020547A0020BD7A0020BF +:10A7600079B701002D890200995502001589020070 +:10A770001CB5E12903D01949097801B91CBD01892B +:10A780000131018188B2884208D016480021A0F822 +:10A7900070100120BDE81C4000F052BE1048007847 +:10A7A0000028EBD00F4CB4F870108142E6D900209D +:10A7B00000F046FE642100FB01F2B4F87010B2FB19 +:10A7C000F1F21A2ADAD3084A1268002AD6D0ADF874 +:10A7D0000600ADF8041001A890471CBDDBBA0200CA +:10A7E000DA270020A86D0020D4240020F8B50E46FA +:10A7F00007460FF001F880250446022E0AD81649B4 +:10A80000F0B201EB40162EB1B07A10B13068B84208 +:10A8100005D0802520460FF0AAFA2846F8BD0F483B +:10A82000017E022911D1717A4FF4A062406802EBD7 +:10A8300001210B4A11430B4A114000220AF038F95A +:10A840000546304600F01CFCE4E7304600F018FCFA +:10A8500002F0C0FF8125DDE7206E0020D01E002021 +:10A860000100080401FF080470B586B004468DF8A5 +:10A8700016004FF6FC700D46ADF81410081A0328A8 +:10A8800012D8022810D000208DF8170005A803F078 +:10A890006CFF06461148012104701148017008F050 +:10A8A000EBFD304606B070BD0220ADF806508DF8C5 +:10A8B000040001A8FEF7D8FB0126012809D1BDF844 +:10A8C00006008DF81760ADF8140005A803F04DFFE1 +:10A8D00006464FF6FC708542DCD2E0E7EB2700200D +:10A8E000EA27002070B592B0044605300DF12A0128 +:10A8F0000AF002FD012802D0207902282ED06088BB +:10A900000BA900F0DDF9012828D10DF11A000DF195 +:10A9100003010E900BAD01AE28463246FEF718FF3C +:10A920009DF80300D0B19DF8161006F108000DF156 +:10A930001A0203F049F800200F95119001208DF8BC +:10A94000420040F20110ADF8400004208DF83600BE +:10A950006088ADF834000DA8EEF7ECFD12B070BDC4 +:10A960002DE9F0410646087A0D46904601280EBFB3 +:10A97000288828460AF0BAF94FF6FE71884203D1BA +:10A9800000210846BDE8F0811249DFF84CC00022E2 +:10A990000B786146002BF3D00F78B74210D12C7A98 +:10A9A0004F78012C05D1012F0AD14C88A04207D144 +:10A9B0000AE02FB94C88A04202D10C794445E0D07E +:10A9C0000E31013B0132E5E7C2EBC2000CEB400166 +:10A9D000D7E700BFDFBA0200307900202DE9FC473D +:10A9E00004460D4640689146DFF868A09846A16885 +:10A9F00040680A8CCAF804002046CAF808200E688D +:10AA000004F06AF9074610BB03208DF804007019A2 +:10AA1000010A8DF80700000C8DF80610BAF808102E +:10AA20008DF8050020460EF0C4FB01A8042105F0B6 +:10AA300029F910B14FF0FF3704E0484641460DF0C8 +:10AA4000FFF90746BAF8081020460EF0BBFB38465F +:10AA5000BDE8FC870C240020B0B51749CA6892698C +:10AA600012781AB1154801210170B0BD154B144A76 +:10AA7000154D1B7812689B0003FB0024B5FBF3F215 +:10AA8000824203D28868D0F84C0580470F4800689E +:10AA9000C06B8047211AA1F54871B1F1FF3F05DC79 +:10AAA000291B0144013148BF00F54874084821467C +:10AAB000BDE8B040F6F7F0BE0C010020B67A0020E9 +:10AAC000307A0020B47A0020FFF6C2FF347A0020EA +:10AAD000F14D020070B5194D0446287820B1184890 +:10AAE0008068D0F84C058047154E164A052CB06892 +:10AAF000D0F8D410C98C11800BD8DFE804F0030D16 +:10AB00000D050A0D012002E00AF0A6F903202870C5 +:10AB100070BDD0F84C058047022028700AF09CF9DF +:10AB2000B0684FF6FF72D0F8D410CA840649D0F846 +:10AB3000D400C08C48860549C88170BDB27A002017 +:10AB40000C010020AE65002000720020007900207A +:10AB500070B50446B0F90E00227A81B2920702D590 +:10AB6000227B1F2A0CD8154A6368D26C52F82050F9 +:10AB70009D4218BF42F820304A42E281227B0BE01E +:10AB80000E4B1D6D45F820400D4DDB6C53F82060D9 +:10AB9000AE4218BF43F82050102901D30A4902E001 +:10ABA000042902D3074901440A70217AC90718BF52 +:10ABB00007F060FC0020A060002070BD381F00205E +:10ABC000CDF5000014ED00E0F0E300E080690278CC +:10ABD0000A70B0F801304B8002B17047C2788B88A0 +:10ABE00062F302038B80C278D20862F3C3038B80C6 +:10ABF000C278120962F304138B806FF3DF230279AA +:10AC000002F0F80243EA02228A8022F4E062037929 +:10AC100003F0070342EA03228A8042798A7182792B +:10AC2000CA71C2790A72027A4A72427A8A72827A46 +:10AC3000CA72B0F80B208A81427B8A73827BCA7306 +:10AC4000C07B087470477047B0B588B0044640892F +:10AC500006AD294600F034F80DF117016A46284682 +:10AC6000FEF776FD9DF8170070B19DF81000FD28E5 +:10AC700018BF002808D11048007828B9607A18B9A0 +:10AC80006068007806280FD0607A18B9606800788C +:10AC9000072809D0207B18B960680078052805D1FD +:10ACA000064841682046884708B0B0BD4FF49A7006 +:10ACB000FFF7A3FCF8E700BFC127002050240020C5 +:10ACC00070B5064619480C46C08AB04206D10EF04F +:10ACD00013F9014620460FF0C2F806E00EF0B0FD71 +:10ACE000B04205D120460EF0E0FF0125284670BD98 +:10ACF000304621460BF010F805460D480078002834 +:10AD0000F4D10EF087FE0028F0D1002DEED1002501 +:10AD1000002EEBD007480188B142E7D100F11801BD +:10AD2000204608220EF092FBDFE700BFA86D00204E +:10AD300024260020502400202DE9F04104464FF63F +:10AD4000FE70A081207850B3184F04F1040800254C +:10AD50004FF0000C388883B2AAB29A4221D2530035 +:10AD600013FA85F67B6813F82610090715D12078A9 +:10AD700003EB86066188307002EB420003EB800033 +:10AD80004180043041460EF028FC3046A5810EF08B +:10AD900009FD38884FF0010C05460135DBE74FF01F +:10ADA000000C5FFA8CF0BDE8F08100BF4026002067 +:10ADB0002DE9F04F85B005460C464FF6F77035B9D2 +:10ADC000844204D90026304605B0BDE8F08F14490E +:10ADD00008300DF10408134E4FF0010B08F104097F +:10ADE0001FFA80FA0F78002FECD03079FF2814D0AA +:10ADF00075B170888DF804B0ADF81000404605F0CC +:10AE0000B7F850B1284649460CF0A7FD28B1DAE75B +:10AE1000544502D03088A042D5D02436013FE2E725 +:10AE2000E3BA02002045002070B51B4C264630686E +:10AE300088B1017B01390173090609D121682E46C9 +:10AE4000814208BF2646016831600FF05BF8EEE7EB +:10AE500005460646EBE7104C606848B1C17E0139F3 +:10AE6000C176090605D10FF04DF80020606000E0C2 +:10AE70000020216808430DD0084C08214FF47A7255 +:10AE800020780EF0A7FF28B120780821BDE8704097 +:10AE900003F03CB970BD00BF682600209A7A0020FC +:10AEA0001A481B4AD0F8841000681140194A914290 +:10AEB00011D1C0F30332C0F34061082A0ED0092A31 +:10AEC00011D00F2A07D1020213D400F08072A9B169 +:10AED000A2B1112000E0FF2040B270470A200029F3 +:10AEE00008BF0C20F8E74FF0FF30002908BF092009 +:10AEF000F2E70E20002908BF0D20EDE70B20002A05 +:10AF000018BF1020002918BF0F20E5E79412005049 +:10AF100000F0FF0F0010B40B10B517480168890747 +:10AF200026D417480468A00221D416480068006897 +:10AF30008047C0F13E000722C1100729B8BFC210E8 +:10AF4000012000EB24718A42D8BF0A460E490968E5 +:10AF5000C1F30321891A0F29A8BF0F210129D8BFE6 +:10AF6000014641F0F000094981F84D00087810BD14 +:10AF70000249C16010BD00BF10000940FD00004043 +:10AF8000B44F0050EC0100100C1300500D6208404B +:10AF90002DE9F041154F164A164B174CDFF838C013 +:10AFA000DFF838E0DFF838800E4D0F4E0021C0E9A1 +:10AFB0000A11C0E90043C0E90227104A104B114CA6 +:10AFC000C0E90465C0E9068EC0E908C1C0E90C43C8 +:10AFD0008263BDE8F08100BF91F9010029C9010039 +:10AFE000256E0100EDB7010079910100958C0100FB +:10AFF000599801003DF9010061320000FD9D0100FA +:10B00000BDC80100A9820200F8B51A4E0546306895 +:10B0100028B119490978A9420AD8002428E005F086 +:10B0200043FC3068002418B313490978A9421FD99A +:10B03000124A05EB450102EB81044FF0FF31D4E9E0 +:10B0400001570EF0FBFD287870B970683968421E10 +:10B050000A4209D17968814206D3B068084081422A +:10B0600002D10120287000E0002430680EF05EFF5D +:10B070002046F8BDDC2500208DB9020028B702006B +:10B08000F8B505460EF0B8FB0446A87A50B36F7ABF +:10B0900001260CF045FE697A48B1154A48B21130D4 +:10B0A000536806FA00F08343C0435360106006FA09 +:10B0B00001F31049002206FA07F02A72AA72C5E9C4 +:10B0C0000422AA61C5E9002291F8605091F862203B +:10B0D0002B4381F8603012B1013A81F86220C0B28E +:10B0E00009F0CCFC2046BDE8F8400EF040BE00BFA1 +:10B0F00008100440206E0020F8B515460E460446A0 +:10B10000012905D119480178204608F0D1FBA0B9E2 +:10B110002046002106F0ECF92946FEF72FFF012E0C +:10B1200007D14FF6FE7750B14179012907D1408808 +:10B130000AE0C8B14079B04216D10020F8BD6806D7 +:10B140004FF6FE7058BF204608490D7886B2BE42C1 +:10B150000AD03046294608F0ABFB0028EDD1A642C4 +:10B16000204608BF3846F1E70120F8BDCCBA0200FE +:10B170002DE9F041D0E901480546D8F800004168C2 +:10B1800021F00201416020460EF09AFED4F8CC0076 +:10B1900008F092FF04F130000EF0CAFE94F8F800B7 +:10B1A00018B904F16C000EF0BFFED5E901750D4E23 +:10B1B00095F83800B04795F83900B04795F83A004F +:10B1C000B04797F8FB00B04798F80C00FAF7EEFF8D +:10B1D00004F11C000CF064FD002084F8FD00BDE8C3 +:10B1E000F08100BF313102002DE9F04385B01A48EB +:10B1F0000DF10808002708F1040490F800901748A2 +:10B2000000F139054F4523D2FEB2072000220C235E +:10B21000CDF8008031460BF001FA2846214608227D +:10B220000DF05EF8A0B92046002108220DF07CFD4B +:10B2300001370028E6D02046294608220EF006F9FC +:10B24000002031460C22029002AB07200BF0FCF9E3 +:10B2500005B0BDE8F08300BFD3BA0200A86D00209E +:10B26000F0B58DB0451D04460DF1160128460AF0D3 +:10B2700043F801282BD1608806AE3146FFF720FD48 +:10B28000012824D10DF106011020099101F090FC54 +:10B29000012000270A958DF82E0040F201100C972E +:10B2A000ADF82C000B4800788DF822006088ADF8CE +:10B2B000200008AC2046EEF73DF9BDF816008DF8E9 +:10B2C0002C700A96ADF820002046EEF733F90DB049 +:10B2D000F0BD00BF9A27002070B50D4606460EF05F +:10B2E00094FC04460EF0E0FD0146B5FBF0F0022EA2 +:10B2F00006D0012E09D1A9420ED91148006808E0F4 +:10B30000A9420CD90E48406803E0A9420BD90C4869 +:10B3100080680EF013FB0DE00B49094B07E008496C +:10B320000B1D084903E0064901F108030749002203 +:10B33000FEF7E4FD2046BDE870400EF054BD00BFAE +:10B34000C4250020ED9002003D910200818502009D +:10B35000F8B51C4F06460D46F868C068007828B955 +:10B36000B8680021D0F85824012090470EF044FA24 +:10B3700004460CF0C5FD30460EF01CFE0646B868CB +:10B38000D0F8E010D0F8EC0050F825000860B9685B +:10B39000D1F8E4100860B868D0F8E00000680CF05C +:10B3A000B3F9B868D0F8E024D0F8D8000168304686 +:10B3B0009047B868D0F8D40480472046BDE8F840EC +:10B3C0000EF0D5BC0C01002010B51B4C0121A0686B +:10B3D00042695177D0F8D420527B0F2A04D1D0F89B +:10B3E0006401BDE810400047D0F8A8000170E06893 +:10B3F000016C20208847A068104AC1688A61D0F893 +:10B40000D430D0E903215B7B92F8304031F813103F +:10B410006400A1404FF4707404FA03F3B1EB930F8E +:10B4200028BF9908962303EB4101D0F8F03402F1CC +:10B430001000BDE8104018470C0100200169010010 +:10B4400070B518490A780021012A4FF0000213D87C +:10B45000154A02F11003154A1478002264B113F85A +:10B460000C5CFF2D05D01D881DB108B1198000E0CE +:10B470002A442433013CF1E70E4C0D4B4FF6FE7588 +:10B480002478183364B133F8186CAE4205D01E88A6 +:10B490001EB108B1198000E032441C33013CF1E7D1 +:10B4A00090B270BD2426002020450020E3BA02009F +:10B4B00030560020D1BA020070B51A491A4A044623 +:10B4C0000AF0E2FB0146E061012051B3002184F85B +:10B4D000200061626069B0F1FF3F1ADD60690121FF +:10B4E000124A01FA00F0A0616069157A1172116ABE +:10B4F00001EBC000E0642020EFF3118680F3118897 +:10B5000020460DF087FB86F31188284608F084FA60 +:10B5100006E00648A16121462C30E0640DF0CAF82F +:10B52000002070BD05780200492E0200382200205C +:10B5300070B5427C0C46017C85692270428861703E +:10B54000A91C62802888A080A01D0EF088FCA87A23 +:10B550000026A073B5F80B00E66166612082687B67 +:10B560000E35A07458B140000EF0CEFC606130B1D1 +:10B570000246A07C29460DF05BFE054600E0A6745D +:10B5800015F8010B207658B140000EF0BDFCE061CB +:10B5900030B10246207E2946BDE870400DF048BE1D +:10B5A0000020207670BDB0B586B00C46ADF8000026 +:10B5B000002101256078CDE901118DF805508DF845 +:10B5C000030094F9000000F00C01002800F00302D1 +:10B5D00000F0200048BF80310223012A08BF122357 +:10B5E000184408448DF802006846F3F745FE9DF8BC +:10B5F000140088B90398457661884187D4F806100D +:10B60000C0F83E10617D80F84910B4F81710A0F81A +:10B610004B10684606F0F8FF06B0B0BD10B586B016 +:10B6200004460020617800908DF81400CDE90100F7 +:10B630000220012918BF042923D18DF8040001201C +:10B640008DF8050021208DF802002078ADF800006B +:10B650006846F3F711FE9DF81400B8B90398082165 +:10B66000406C0170617841706178022903D1616892 +:10B6700002300EF0F4FB684606F0C6FF9DF8140099 +:10B6800004E0022901D10A20D7E7B32006B010BD9B +:10B690002DE9F84304466FF0010004F10409A0818C +:10B6A000608048460CF00AFD012822D1144E002784 +:10B6B0004FF0000831888AB2B8B290421BD24200E3 +:10B6C00012FA87F3726812F823301B070FD000EBD1 +:10B6D000400002EB80054846291D0CF03EF93188F8 +:10B6E00028B16888A7814FF001080F4660800137B4 +:10B6F000E1E74FF000085FFA88F0BDE8F88300BF8B +:10B70000402600202DE9FF4704460120022108F0D1 +:10B710006BFA2070C0B220B3C0000EF0F5FB00B38E +:10B7200080461348E9464FF0010A09F104064746EE +:10B73000841C10480578B5B1A078013801280DD8CF +:10B7400020888DF800A0ADF80C00484604F010FCED +:10B7500020B1384631460EF082FB07462434013DC5 +:10B76000E9E74FF00008404604B0BDE8F08700BFAD +:10B7700020450020E3BA02002DE9F04106460C20E6 +:10B7800090460D460EF0C0FB044608200EF0BCFBB0 +:10B7900094B1074680B1B8F1000F7E807D60A7604C +:10B7A0000CD028460CF0A8FC38460EF0ABFB204627 +:10B7B000BDE8F0410EF0A6BBBDE8F08100202146B7 +:10B7C0003870074840680EF0A9F90648016841F052 +:10B7D0000801016004480068BDE8F04102F036BF8E +:10B7E00030260020547A0020507A00202DE9F043C2 +:10B7F00089B0109EADF82010079046B31C4633B3B5 +:10B80000154607A802AA214602F020FC0746F8B90F +:10B81000DFF84490D9F80800FEF770FE80460F4824 +:10B82000002203230092C188C07802AAEEF7E4FE4A +:10B83000074630B902A829462246334604F08EFE58 +:10B840000746D9F80800414602F086F900E00427CF +:10B85000F8B209B0BDE8F083A0230020B872002040 +:10B86000F8B5174C607850BB1648184D00210330CE +:10B8700020F0030614483246801B286083199A4240 +:10B8800002D202C22868F9E720F003000021104F1D +:10B89000304440F8041CE820314630602868EC3819 +:10B8A00020F0030041F8E80F00203960FBF77CF836 +:10B8B000C7E9006001206070286804386060F8BD46 +:10B8C00000260020C97A0020003001201C6E0020D4 +:10B8D000D0250020F8B5054616484BF2F521174E45 +:10B8E000006800FB01F714483C0A006800F440209F +:10B8F000B0F5802F10D11248006880030CD4F06896 +:10B900000068804707F022FD3168C9688847C01089 +:10B91000390B484304EBE0342DB90A48006820F0A5 +:10B920007F40204444083069416C2046BDE8F8401F +:10B93000084700BF08400C40B44F0050E001001021 +:10B940008C13005010200940F8B5164F1648BD6CF6 +:10B950000DF034FD0446154801680668214011F0D9 +:10B96000200318BF002D0AD0284600223D650BF0A9 +:10B9700057F90F484FF4804128300EF0DBFA04EA03 +:10B98000060010F4602008BFF8BD0A4991F8612054 +:10B9900042EA504081F8610007480021BDE8F840C4 +:10B9A0000EF0C8BA3021002020000E000C10044018 +:10B9B00070200020206E002040720020BFB5184D7E +:10B9C0000446287820B91748018941F00101018116 +:10B9D000204606F0B7FBBCB1134890F8410098B977 +:10B9E000287888B96C460020622100252246FEF79F +:10B9F0007DF8204600210BF067FD0020FBF702FBDD +:10BA0000CDE90255CDE90055084C206830B128B188 +:10BA100005680EF077FA25602846F8E7BFBD00BF3D +:10BA2000242600203E790020A86D0020E826002072 +:10BA30002DE9F8431A4E04464FF000094FF0D308A1 +:10BA40004FF6FF7736683EB3E089F18881421BD11B +:10BA5000A07C20300BF072FC0028F3D0214620227D +:10BA600005460DF0F3FCA27C2AB105F12000A86187 +:10BA7000A1690DF0EBFC3079294685F8008003F0D0 +:10BA800073FB4FF00109DDE7B942DBD101B20029B8 +:10BA9000DED41328D6D1DBE75FFA89F0BDE8F8835E +:10BAA00074270020B0B58CB006AC182120460EF0EB +:10BAB00035F9154D822018212246A84701AC1121E5 +:10BAC00020460EF02BF93A2011212246A8473B20B0 +:10BAD00011212246A8470D48002180F841100C484A +:10BAE0000078013801280CD80A4A4FF481701021DF +:10BAF0000DF0E4FF28B9074A4FF4817010210DF0D2 +:10BB0000E3FF0CB0B0BD00BFC99A0200A86D0020D1 +:10BB10002426002014B90200F0B585B080B3194F77 +:10BB2000FC686CB305461CB3A61C294608223046A7 +:10BB30000CF0D6FB08B9E468F5E7B868A8B102AD27 +:10BB400031460822681C0DF081FC05F10A013046DF +:10BB50000AF0F9F80120092100220C2300958DF844 +:10BB600008000948007807F04CFA204605F08AF8EA +:10BB7000F86828B904484FF40061007803F032FFF8 +:10BB800005B0F0BDAC220020A37A00202DE9F041E1 +:10BB90000446007A012801D1258803E0204609F0F7 +:10BBA000A5F805464FF6FE70854208BFBDE8F08156 +:10BBB0001048471C104806781048B0F800809EB125 +:10BBC000217A3878012902D1012801D009E040B951 +:10BBD000B7F80100A84204D1781E4146FF220EF0BA +:10BBE00047F80E37013EEAE72846BDE8F04105F088 +:10BBF00095B800BF30790020DFBA02004EB20200D3 +:10BC000070B505460DF0F8FD164E0446B068D0F844 +:10BC1000E010D0F8EC0050F825000860B168D1F8C9 +:10BC2000E410086010480068C06B8047104AB16893 +:10BC30001368D1F8E01063B90C4B1B789B00B0FB84 +:10BC4000F3F50868854204D9B5FBF0F5684358431D +:10BC5000106008680BF058FD2046BDE870400EF0FB +:10BC600086B800BF0C010020347A0020B47A00208E +:10BC7000307A0020BCB51A490020096811B104319E +:10BC80000130FAE7C5B268000EF03EF918B3144966 +:10BC900004460020096831B131F8042BC3B20130E9 +:10BCA00024F81320F6E70F49B1F86E00CA8A9042D3 +:10BCB00007D101F1390200212B46009402F006F968 +:10BCC00006E001F1390200212B460094FCF756FFF3 +:10BCD00020460EF017F9BDE8BC400BF021BF00BFB5 +:10BCE0004C270020A86D0020C1071CD101071DD4DE +:10BCF000C1061ED481061FD4C10420D4810721D4DB +:10BD0000410722D4410423D400F40051012200B29F +:10BD100082EA51310022B0F1FF3FC8BF012202EA9E +:10BD20000100404270470C48006870470A4840686C +:10BD300070470948806870470748C06870470648E0 +:10BD4000406970470448806970470348C06970477C +:10BD500001480069704700BF0875002000B17047B6 +:10BD6000B0B51A4CE06C58B340F2000CEFF3118000 +:10BD70008CF311882020EFF3118180F31188D4E92E +:10BD80001650E16CB1FA81F1C1F11F0100EBC10164 +:10BD9000A94215D9086802680A6051600A688A4297 +:10BDA00004D1416AE26C22EA0101E16401F04EFA39 +:10BDB000E16C29B1E06DB1FA81F1C1F11F01E5E754 +:10BDC000002084F84800BDE8B0407047A01F002064 +:10BDD00070B521B3154612B306680C4607F0D3F8C8 +:10BDE000B0680DF0BEFF47F6FF704FF6FF71854259 +:10BDF00038BF284640008D4208BF4FF0FF30A6F8FC +:10BE0000580060080FD04FF47A7100FB01F40EF077 +:10BE10004BF8B4FBF0F1A04288BF012104E0BDE87B +:10BE200070400BF012BD0021B068A6F8561089B220 +:10BE30000EF042F8B0680EF041F8022086F850008B +:10BE400070BD2DE9FF41044604201E4690460F4672 +:10BE50008DF80D0003A80AF043FEC0B1054646B1B7 +:10BE60000120AF80A8770020E876287840F0800095 +:10BE700028702869390AC1700321877080F8018011 +:10BE80000170204607F058FF18B100200AE0012099 +:10BE90000DE001AE2046314609F03EFF0028F4D007 +:10BEA0002E620120687728466C8002F0A5FD04B060 +:10BEB000BDE8F081B0B58CB0044601206D4611217B +:10BEC0003A238DF81E0020882A46ADF81C006068D1 +:10BED000099000200CF0B0F928B1684611210DF04E +:10BEE0001DFF002001E09DF8000001218DF81F00DA +:10BEF000681C25898DF8291008900DF0B3FC854247 +:10BF000002D10020002106E02089ADF8140060680D +:10BF1000069005A901200B918DF82A0007A8EDF7DE +:10BF200009FB0CB0B0BDF0B589B0054600200C4649 +:10BF30000121ADF810200890CDE905504FF6FC70B6 +:10BF40008DF81E108DF813408DF81210101A03286A +:10BF500011D802280FD000208DF81D0004A8EDF79D +:10BF6000E9FA0646284621460BF0AEFA07F084FAB5 +:10BF7000304609B0F0BD02206F46ADF802208DF8C2 +:10BF800000003846FDF770F801260128EAD1381D77 +:10BF90008DF81D600690E1E7BFB50568174A687A1D +:10BFA000012807D11268686990F8211040699268E9 +:10BFB000904714E068696C4690F821101068826818 +:10BFC000204690476869416990F82120204608F092 +:10BFD0002FFB08B1686801E06FF003006860084853 +:10BFE00040210160802101600021C0F8FC12022084 +:10BFF00008F02AFD03480DF099FFBFBDFC010010B9 +:10C000000444024098700020F8B506680D460446C6 +:10C010000DF0F2FB16490978012902D196F8221099 +:10C0200019B10DF0A4FE00241FE0012786F822704C +:10C030000DF09DFE0F49002D18BF294648680A786B +:10C040007060002086F82020022A4FF0000208BF0E +:10C050008A6886F8240086F8250086F82370B26086 +:10C0600086F826000A20F9F73BFE2046F8BD00BFFF +:10C07000A9270020D4B8020070B5194A194C103213 +:10C080002378002918BF0121002573B112F8106C24 +:10C0900005F00105864206BF11700E46167835433D +:10C0A00018BF01251832013BEFE7A078E90708D057 +:10C0B00098B90120012609F0FFFA022009F0FCFAE4 +:10C0C00008E0012809D1012008F0BEFC022008F098 +:10C0D000BBFCFF26A0783044A07005F0010070BDC5 +:10C0E0001C610020002600202DE9FF41194F4FF66A +:10C0F000FE764FF000086C464FF6FE7080B2B042FC +:10C1000024D10DF087FD0546F88A85424FF6FE7072 +:10C11000F4D00DF095FB85424FF6FE70EED0284628 +:10C1200007F00AFE00284FF6FE70E7D1002D4FF60B +:10C13000FE70E3D020468DF80080ADF80250FCF789 +:10C1400093FF002818BF35462846D7E704B0BDE85E +:10C15000F08100BFA86D002070B5194E044604217F +:10C160001D46307807F02EF908B1012070BD07F0A8 +:10C1700083F9022D21D808200DF0C6FEA8B105468E +:10C180001048016811B108460968FBE705604021C5 +:10C19000307807F017F901460020AC80C1F516721F +:10C1A00009042860EA8002D070BD102070BD30788C +:10C1B00040214FF416720DF00DFE002070BD00BF3F +:10C1C0009D7A0020E82600202DE9F843194C099FAC +:10C1D0008146884611461D4660683E7A0DF03FFE56 +:10C1E000089905700A0A41708270397AC170397AEB +:10C1F000012908D003290AD104300A9D39460DF0DF +:10C200002EFE057003E039780171797841711020B4 +:10C210000C2341464A46012EA070204608BF0E233B +:10C22000032E08BF152303F057F90021A170BDE8C4 +:10C23000F88300BF882600202DE9FC4118200DF06E +:10C2400063FE60B3044617484FF00008002700F172 +:10C250000806032F1AD03078012814D1BDB2062069 +:10C2600000221823009429460AF0D8F958B956E953 +:10C27000020118222346C4E90401062029460AF0D7 +:10C28000E3F986F800800C360137E2E720461821F2 +:10C290000DF044FD2046BDE8FC410DF033BEBDE885 +:10C2A000FC8100BF30750020F0B585B0194EB26832 +:10C2B000116F91F82B1059BBD2F8D410897839B38B +:10C2C000C168007AD2F88821904708B30446B06864 +:10C2D000016F91F82B2042F0040281F82B20D0F856 +:10C2E0005C1302AD28468847F0680127816A012067 +:10C2F0008847B0682A46D0F87863016FD0F8D40038 +:10C30000C38C01F120002146CDE900700520B04723 +:10C3100005B0F0BD0C01002070B517480D220024B7 +:10C3200001680131B1FBF2F303FB1211134A52F819 +:10C33000213042F82140016011490868C01A0860A4 +:10C34000F8F702F80F4D2E780DF0AEFD044628697F +:10C350000DF0B0FD00B170BD002E1CBF4AF20036DA +:10C36000C1F2E1162869B6FBF4F10DF0A5FD2869CC +:10C37000BDE870400DF0A2BD187A00206073002067 +:10C38000207A0020B824002010B50DF003FE0AF03A +:10C3900023FD144CA068D0F8D40090F843000BF0B3 +:10C3A0007DF9A06800210024D0F85824012090478E +:10C3B00004F026FD0AF038FD08F03EF8FDF784F998 +:10C3C00009481221C0E90044846008480DF0A6FC29 +:10C3D0000748047007480470F9F778FBBDE810407F +:10C3E0000CF0A2BE0C01002064790020AC78002083 +:10C3F000AA7A0020A97A002010B51648816829B1D0 +:10C40000154908308968D1F8541288470DF0F4F9BD +:10C41000124900240A6813681C7112680A600DF042 +:10C42000A6FC0F48017811B90E49097849B104708A +:10C430000C48047003F0A4FF0748C168C968097874 +:10C4400001B110BD80680021D0F858240020BDE85B +:10C4500010401047342500200C010020D87900201E +:10C46000B07A0020B37A0020B0B514480068C06BE1 +:10C4700080471348144900780D6884001148B0FBC8 +:10C48000F4F0854204D911488068D0F84C05804703 +:10C490000F48016804FB0511016004FB05110D48FC +:10C4A000F5F7FAF909488068D0F8E40480470DF000 +:10C4B000A3F9BDE8B0400DF05ABC00BF347A0020AB +:10C4C000B47A0020FFF6C2FF3C7A00200C01002065 +:10C4D000307A0020BD64020070B568B115460E4682 +:10C4E000044604290AD0022E11D0012E04D10120C5 +:10C4F00009F052FB114905E0C12070BD042009F08C +:10C500004BFB0D490978884284BF112070BD0C494E +:10C510000020258166736060086820B1014640688C +:10C520000028FBD1043107480C602021007801F07D +:10C53000EDFD002070BD00BFE0BA0200E2BA0200CB +:10C54000587A00209C7A0020FEB5044614486D46B7 +:10C55000046028460DF0A0FB124E002000212A4660 +:10C560008DF8000030460CF0B3F80F4F07F134059A +:10C570007E6028460DF0D8FA0C480521BC630C4CAF +:10C580004FF440620023BA642A46C7E910100949F3 +:10C5900020460AF039FDBC600CF041FEFEBD00BF34 +:10C5A000682700205877002088210020F0270020ED +:10C5B000406F0020694B00007CB5044606981D467C +:10C5C0000B46362902DB174A00210AE012491646BB +:10C5D000124AE381096E51F82310914207D00021DD +:10C5E0000F4A0091002108F0D7FD01207CBD1846BC +:10C5F00005F01EFF286969682073C4E90016287ACF +:10C60000A060297D11B140F00200A0602046FEF735 +:10C610009FFA00207CBD00BF381F0020696F020018 +:10C620000FAC02002BAE020010B596B0184C2020C3 +:10C63000EFF3118180F31188E06810B90AF085F9F1 +:10C64000FAE7E068216A134A0223B0FA80F0C0F1E9 +:10C650001F00137501EBC002E26151F830000021A8 +:10C660002174A06140F2000CEFF311808CF311886B +:10C670002020EFF3118180F311880CF087FDA16970 +:10C6800068461C301C310AF0ABFC16B010BD00BF70 +:10C6900038220020381F00202DE9F041B3F1FF3F80 +:10C6A00003DC5B42B1F1FF3F24DD4FF0000C4FF0A3 +:10C6B000010EDFF85080471E0026B1FBF3F505FBA5 +:10C6C000131418F80440BC55013E8B422946F4D996 +:10C6D0003044714230230138914203DA00F80139C5 +:10C6E0000131F9E7BEF1000F0CBF80F800C0013046 +:10C6F000BDE8F081013A49424FF02D0C4FF0000E99 +:10C70000D7E700BFA1B80200F0B540F6FF7C10F8F3 +:10C71000013B0024082CFAD00646DF0716F8015B1F +:10C720000DD1467806F00F070337122F0DD190F97F +:10C730000220D7B2B2F1FF3F09DD03300DE001F86E +:10C74000015B304601345B08E4E7023006E0C27862 +:10C7500007F07F07043047EAC2171237320942EA6E +:10C760000515654508BFF0BDED43002FEAD04A5DD1 +:10C77000013F0A700131F8E7B0B5056804460DF0D5 +:10C780003BF8002185F8241095F82120033A022A6D +:10C7900028BF85F825100DF0EAFA0F488168B1F13D +:10C7A000FF3FDCBF4FF0FF31E9610C4901602046DB +:10C7B00007F0C6F995F82000022804D10848BDE822 +:10C7C000B0400DF0B3BBD5E9002CE96995F82130F4 +:10C7D0002046BDE8B0406047884702400100008025 +:10C7E000E8700020FEB5876A04467E7801ADB91C6A +:10C7F00028460DF034FB1548294639300BF0ADF8CA +:10C80000B8B11F2E12D806F01F0568000DF07CFB92 +:10C8100078B1064607F10A0000218D420AD000EBEC +:10C820004102128826F811200131F6E7D320FDF7E6 +:10C83000E4FEFEBDA089009601AA00212B4601F06E +:10C8400045FB30460DF05EFBFEBD00BFA86D00202D +:10C85000B0B58AB0144DC5E900011448426001AC7E +:10C8600020460DF0BFF803202146ADF820004FF41C +:10C87000E130079001208DF8180040F20110ADF86A +:10C8800004000B4804900B4803900B480290059855 +:10C8900040F0200005900020EEF79EFAA86008F016 +:10C8A00063FE0AB0B0BD00BF482300207026002000 +:10C8B000816B0200FF600100098C0100F8B5174E82 +:10C8C000706808B1804730B3B068FDF717FE144FA9 +:10C8D000044600253978E8B2884206D2FAF7D8FF34 +:10C8E0003178013508433070F4E70E4F0020357879 +:10C8F000F8707870481E7E21B870B88BF8800020E0 +:10C9000008F020F8B878FE2108F01CF8B06821463D +:10C9100001F022F900E00B252846F8BDA0230020F5 +:10C920009B7A0020B8720020F0B587B0ADF81810DF +:10C93000059033B32AB31C466B46114605A81A4628 +:10C9400001F084FB0546E8B9114F786808B18047CB +:10C95000D8B1B868FDF7D2FD0646684621460022E8 +:10C96000EBF7C2FA054638B9BDF80C1021B19DF8B5 +:10C97000100003F073FF3D78B868314601F0ECF821 +:10C9800000E00425284607B0F0BD0B25FAE700BFFC +:10C99000A02300202DE9FE4F1648174EDFF85C90CB +:10C9A0004FF6FF774FF00208EB464FF0FF3A0A24AC +:10C9B0000578E5B13088B84216D0718871B1013977 +:10C9C000718089B2B1FBF4F202EB8202A1EB420169 +:10C9D00051B90CF00BFD0BF013FA05E00CF006FD5D +:10C9E0000DF0B6FAC6F800A00436013DE1E7BDE857 +:10C9F000FE8F00BFD2BA020098780020A86D0020F8 +:10CA00002DE9FC41E84604464146FEF759F930B3AA +:10CA10001448DFF854C000210078CFB287421BD2FF +:10CA2000FB0053FA81F363441B7AC3B107EBC707DA +:10CA3000C3F10805674458FA85F657FA85F7357843 +:10CA40003A78AA4206D1013B07F1010706F1010637 +:10CA5000F5D104E00131E0E72046F6F741FDBDE8FD +:10CA6000FC8100BF9E270020F05A002010B586B040 +:10CA7000184C00218068CDE90411CDE90211019420 +:10CA800002A9009105A904AA03ABF2F7B9FE059922 +:10CA90004FF6FF720988914201D00C4617E00399C6 +:10CAA000002918BF01210140012904D1029911B1C7 +:10CAB00001AA084602E050B1049801AA2B210BF00C +:10CAC00039FCFF2803D00198204000F100442046A3 +:10CAD00006B010BDFFFF3F0070B505460CF08CFEA0 +:10CAE000174E044696F82400A84386F824003068C0 +:10CAF00020B1B8300DF0DEF9054600E00025706881 +:10CB000018B1B8300DF0D6F9054396F8240030B9C5 +:10CB10002DB9306A18B190F82810890704D420463E +:10CB2000BDE870400DF023B9456A20460DF01FF9AD +:10CB3000306A022100220024A847346270BD00BF81 +:10CB40007020002070B5B0B00FAC842120460DF0ED +:10CB5000E5F8154803A90A4690E86800042068C271 +:10CB60008DF82800CDE9014102F082FB01A80AA955 +:10CB7000FCF71CF998B106AD0C490446142228466E +:10CB80000CF02EFE204629460DF0DAF90546204627 +:10CB90000CF002FA002D18BF4FF0FF3501E04FF006 +:10CBA000FF35284630B070BD90B9020034780020BF +:10CBB00010282FD1FEB5184E0C4630788DF80400A1 +:10CBC0000DF074F905460DF06FF968434FF47A776C +:10CBD000B0FBF7F08DF805000DF068F905460DF093 +:10CBE00063F96843B0FBF7F0000A8DF806000CF01B +:10CBF00083F901AD01460222E81C0CF027FC00205D +:10CC000000212A4640230094EDF708F82078307080 +:10CC1000BDE8FE40704700BF957A0020F8B5184D7A +:10CC2000A87808B1012429E00DF10301E12009F001 +:10CC300069FB144E9DF803100024307E81421DD004 +:10CC400001270DF1020152208DF80240AF7005F06E +:10CC50009BFA307E0B380F2804D806F11801E1202A +:10CC600005F092FA0DF1020152208DF8027005F0E4 +:10CC70008BFA002000240CF081FCAC702046F8BD3B +:10CC8000CC260020A86D00207FB504461748184E1A +:10CC900000783178084302D1608800B17FBDA06977 +:10CCA0000578FF2D08BFFE2528460AF049FF8DF8BC +:10CCB0000F000CF013FB10B128460AF03DF8307855 +:10CCC00010B928460AF038F8207B0028E6D1002069 +:10CCD0000DF10F0148F236020123CDE9001004F1F5 +:10CCE0001100A11C04F024FD7FBD00BFBF27002060 +:10CCF000242600202DE9FC410020ADF8040014207A +:10CD00000DF002F940B3DFF854800446D8F8000073 +:10CD1000F8B100264FF6FE770025122E0DD08119AE +:10CD2000A019062202300CF091FBD8F80000815BBC +:10CD3000B94218BF01350636EFE7ADF8045001A936 +:10CD4000204602220CF082FB4C20142122460CF0DB +:10CD5000BBFE20460DF0D6F8BDE8FC81EC26002095 +:10CD6000B0B5174C6068216801EA000521EA0002AD +:10CD7000680622601DD51348006800F44000B0F535 +:10CD8000000F03D11048006807F044FE04200CF0A7 +:10CD9000DBFD811E022905D207F002F9022007F00F +:10CDA00053FE03E0012808BF07F0FAF8202008F03E +:10CDB000C3FE280648BF04F079F9A560B0BD00BFE6 +:10CDC00090220840B44F0050DC2600202DE9F041AD +:10CDD0004FF02008EFF3118188F311880122144FDE +:10CDE00011490D7A0A72114991F8486081F848207A +:10CDF0000021104A3C7D3975396D1268D2B251F864 +:10CE00002210886040F2000CEFF311808CF311883F +:10CE1000D1E900018847EFF3118088F311883C7550 +:10CE200046EA0520BDE8F08138220020A01F00203E +:10CE3000381F002004ED00E0F8B541680A780F2A99 +:10CE400013D0082A1FD0062A1CD140894A1C0292FE +:10CE5000ADF80400B1F80900ADF80C00C87A8DF8FF +:10CE60000E0001A806F00AF98FBD40898A1CADF8B2 +:10CE7000040048780A31029203918DF8060001A857 +:10CE8000EFF7FEFD8FBD4089ADF804004878022819 +:10CE90008DF8060004BF881C029001A806F0D0F8A7 +:10CEA0008FBDB0B586B0044600202121CDE9000039 +:10CEB00002904FF48670ADF804002088ADF80000B1 +:10CEC000607A0028684608BF01218DF80210F2F749 +:10CED000D3F99DF8140098B90398456C062005F81D +:10CEE000010B616828460CF0BAFFA0782872E07840 +:10CEF0006872207AA872684605F086FB9DF81400D7 +:10CF0000217A002908BF084606B0B0BD89B36FF08A +:10CF1000C0020B0E02EA8112202B05D0212B05D076 +:10CF2000A02B05D1302118E0102116E0202114E0BB +:10CF3000B1F1807F01D240210FE0102B05D0112BE1 +:10CF400005D0402B05D1702107E0502105E060217C +:10CF500003E09021502B08BF8021114341F00F01C5 +:10CF600004C8531C18BF8A42FAD14FF0FF3140F871 +:10CF7000041C7047B0B51749174A00230978994235 +:10CF800006D002EBC3046488844203D00133F6E781 +:10CF90000C4600E0DCB24FF6FE73984208BF8C42AC +:10CFA00001D02046B0BD0024A14204D012F83400C4 +:10CFB00018B10134F8E70C46F3E702EBC405E4B21C +:10CFC00068686B800028ECD00CF09CFF0020686043 +:10CFD000E7E700BFD7BA0200503D002070B50468F3 +:10CFE000616F59B3D4F8582145685668E96B2868D1 +:10CFF0003268D16201210BF03DFED4F85801E96B93 +:10D000000F4A40680068C0F8041591FAA1F112684F +:10D010003068B1FA81F192699047616F091AE07C3A +:10D0200020B104F14C0007F00FF805E0206FA26F6B +:10D03000401A20675018A0670020606770BD00BFCD +:10D04000D40100101CB5002008F04CFF0CF00AFCC5 +:10D0500004460BF051FF01460F480023827820461A +:10D0600007F09AF8002008F03DFF0D4800780228EC +:10D0700010D10A48007801280CD16C4620460CF0EB +:10D0800014FE0CF0DDFB07490B7807490A782146AE +:10D0900002F012F81CBD00BF3E790020CA27002014 +:10D0A00024260020D0270020D22700202DE9FC4193 +:10D0B00014200CF029FF40B3044615484FF0000837 +:10D0C000002700F10806C82F1AD03078012814D1A3 +:10D0D000BDB20420002214230094294609F09EFAD0 +:10D0E00058B956E9020114222346C4E9000104207C +:10D0F000294609F0A9FA86F800800C360137E2E7E4 +:10D100002046BDE8FC410CF0FDBEBDE8FC8100BF3F +:10D11000F033002070B50CF06FFB164D2E78297897 +:10D12000012902D10CF023FE0EE0012129700CF040 +:10D130001EFE1148C168C968097829B980680021B4 +:10D14000D0F85824012090470CF030FF04460CF032 +:10D1500053FB04B92E700CF00AFE0748C168C96879 +:10D16000097829B980680021D0F858240020904718 +:10D17000204670BD262500200C010020F8B5174E72 +:10D18000154D044631682868496D88476040B0F104 +:10D19000FF3F07DC124FB868D0F8D40090F8830046 +:10D1A00001280BD10CF00EFD832808BFF8BD0C48F8 +:10D1B0008068D0F84C05BDE8F840004709F0AAF9AE +:10D1C0000CF000FD832803D0B868D0F84C058047E8 +:10D1D000BDE8F8400BF094BFE4260020347A00202C +:10D1E0000C01002010B5184C0021A068D0F8E80010 +:10D1F0000160A068D0F8D8100968B9B1D0F8E02073 +:10D2000049681268914211DA07F0FAF8A168D1F87A +:10D21000D82012685368834204DA5060A168D1F8BC +:10D22000D8000268D1F8E8000260A068D0F8DC10ED +:10D23000096841B1D0F8E80002681AB152684B6839 +:10D24000934200DA016010BD0C0100202DE9F04787 +:10D25000164C002100F12C03154D4FF0010A80F807 +:10D26000281084F848100ECBD4E91489A76D2E7DC0 +:10D27000C4E91503226585F814A0016340F2000C8F +:10D28000EFF311818CF31188D0E90532C1691046A2 +:10D2900098472020EFF3118180F311882E7584F8D0 +:10D2A00048A0C4E91489A765BDE8F087A01F002045 +:10D2B000381F00202DE9F843804615481549DFF84E +:10D2C00058900078002818BF012000240870E0B2B0 +:10D2D00039F83050CDB109EBC00047884668284680 +:10D2E000394632460CF0EAFB68B92846B8F1000F1F +:10D2F00004D0394632460CF0E7FB04E000213A4600 +:10D3000033460BF039FF0134E1E7BDE8F88300BF95 +:10D31000C2270020C87A0020FCA60200B0B58EB05B +:10D3200001AC0546342120460CF0F8FCD5F802008B +:10D3300029690022CDF80E00287D0B914FF6FF7170 +:10D34000ADF8001069468DF82000287F8DF809009F +:10D35000288DADF81400287E8DF80A00687E8DF8BF +:10D360000800688DADF8320095F82C008DF8340077 +:10D37000FF208DF802002046E9F782FB00200EB066 +:10D38000B0BD7CB5054600EB400014460E460230A9 +:10D390008DF8050001A809F0A3FB18B30169082264 +:10D3A00001F8022B05F01F02324301F8012C002284 +:10D3B000D3B2AB420ED2237801320B7063784B703C +:10D3C000E678A378043406F0070663F306168E7039 +:10D3D0000331EDE7012181764FF6FC71418001F0C8 +:10D3E0000BFB7CBD01207CBD2DE9F84304460820E1 +:10D3F0000CF08AFD20B305462078C61C022050FAA6 +:10D4000086F8404609F09AFF6860B0B1FE215FFAE5 +:10D4100086F9017021464A46686801300CF09AFD91 +:10D420006F684946781C0BF089FB57FA86F1487003 +:10D430000020A5F80280287003E028460CF062FD69 +:10D44000002520460AF058FE2846BDE8F8837047BC +:10D45000B0B5056804460CF0CFF9A97819B1BDE85C +:10D46000B0400CF084BC002169700CF080FC0E48C8 +:10D470008168B1F1FF3FDCBF4FF0FF3169600B49BC +:10D4800001602046FEF788FD287A022804D108486A +:10D49000BDE8B0400CF04ABD6B7AD5E904C26968BA +:10D4A0002046BDE8B0406047884702400300008046 +:10D4B000E87000201CB50C46097F052904D104F151 +:10D4C0000801FDF7FDFB18B304F108000DF106019A +:10D4D0000BF028F9BDF806004FF6FF71884204BF33 +:10D4E000A1201CBD217801290FD10A4A00EB40017F +:10D4F00002EB8101A26951F8043F9A423CBFA2208D +:10D500001CBDA082501C086000E0A08200201CBD51 +:10D51000C8201CBD307500202DE9F04385B01548AA +:10D52000154F00264FF0FF080DF104090024007884 +:10D5300000EBC0008500B54218D0B81990F8211052 +:10D54000802910D1B95980F8218010224B460191D1 +:10D5500041680291017D80698DF80C100490A1B2A0 +:10D56000032009F071F824360134E4E705B0BDE882 +:10D57000F08300BFE3BA020020450020F8B50D4853 +:10D580000D49FF220088097841430C480CF070FBDC +:10D590000B480C490C4A0D4B0D4C0E4D0E4E0F4FC7 +:10D5A000C1610021C0E90176C0E90354C0E9053238 +:10D5B0000170F8BD4EB20200DFBA020030790020DF +:10D5C000EC2300207548020095060200092702009E +:10D5D000051D02008DBB0100E163020011EF000098 +:10D5E00010B5154A212074210CF068FA0A38B0FAF7 +:10D5F00080F0440905F028F80A28104808BF0234D2 +:10D600000078012804D805F05FF80A2808BF043420 +:10D610000B48016819B188470A2808BF083406F08A +:10D6200039F80A2808BF103404F0A6F80A2808BF01 +:10D630002034204610BD00BFA86D00202426002005 +:10D64000FC230020B0B5134D0124E86B01680120D4 +:10D65000884701281BD028683C2101220023002490 +:10D66000C5680D48A84790B106F07EFC0B480C49F0 +:10D670000068D1E900238860C01A0A4BA2EB92022D +:10D680005843B2EB104F98BF020C01240A602046A9 +:10D69000B0BD00BFA401001000A00C403020094024 +:10D6A000F424002040420F002DE9F84305461548B8 +:10D6B000DFF854908846002400F1140699F8000021 +:10D6C000C1B28C4228BFBDE8F883FF2D08D156F8BF +:10D6D000107C0CF0FFF9874209D099F8000003E0B4 +:10D6E00016F8141CA94202D018360134E8E70CF0F1 +:10D6F0008CFA31680A6822EA08020A60BDE8F84339 +:10D700000CF071BB1C61002000260020B0B514484D +:10D71000144D807B95F83911084306D00CF06CF855 +:10D7200095F83B1121B10CF022FB00242046B0BD3E +:10D73000012485F83B410CF01AFB022007F0BCFFE6 +:10D740000D20F8F7CDFA084801680029EED1074905 +:10D7500040220A604A60002185F83A11C461E4E77A +:10D7600018B80200D81B002004800C4038500C4030 +:10D7700079B36FF0C0020B0E02EA8112202B05D0A4 +:10D78000212B05D0A02B05D1302118E0102116E067 +:10D79000202114E0B1F1807F01D240210FE0102B55 +:10D7A00005D0112B05D0402B05D1702107E0502169 +:10D7B00005E0602103E09021502B08BF8021114338 +:10D7C00041F00F0104C8531C18BF8A42FAD140F837 +:10D7D000041C70471CB51548017E022904D119208C +:10D7E000BDE81C400BF0AABD017E01291DD0007EC2 +:10D7F00004281AD00CF000F8044601A8F9F762FBDF +:10D8000028B101990A4831B10BF0E4F80AE0084860 +:10D810000CF0A7FA06E00CF0A4FA06480421283020 +:10D820000CF088FB20460CF0A2FA1CBDD01E002094 +:10D830007C71002070200020B0B54FF0FF300BF05D +:10D84000B5FD104D04461049E86988420DD10F48D6 +:10D850000F4900220BF03CFA0220287607F044FF23 +:10D8600018B9FAF773FAEAF71FFF0A48044208BF2B +:10D87000B0BD09484FF000512830BDE8B0400CF071 +:10D8800059BB00BFD01E002095370000302100207A +:10D89000F50C01000200004070200020F8B5174F81 +:10D8A00006460D46F88AB04201D1012405E0304613 +:10D8B00029460023FEF7C5FA04463046002103F04E +:10D8C00017FEF98A884216D128460021FCF756FB3C +:10D8D00068B1817911F0180F09D04388F98A00885E +:10D8E0004FF6FE720092002202F0C8FA03E02846CA +:10D8F000012109F0B7FC2046F8BD00BFA86D00204B +:10D900002DE9FF41144DD5E900673879F8F7E8F9BA +:10D910000BF072FF04463078B0B90DF104084046B0 +:10D920000BF004FDB87979790C4A434601950290D1 +:10D93000301D05F01BFC38684FF0FF31C16208490B +:10D94000816001213170416020460CF010FA0248DC +:10D9500004B0BDE8F08100BF34BA0200479C020069 +:10D960000018002010B5174B0C0A5B685970002195 +:10D970009C701970117801F01F01D97051781971DC +:10D9800091785971D17899711179D9715179197248 +:10D9900091795972D1799972117AD972517A197330 +:10D9A000917A5973D17A9973117B00F11102D9736D +:10D9B000811C104648F202021023BDE8104001F01D +:10D9C0008BBD00BF882600202DE9F04385B050B301 +:10D9D000144642B30DF104080E46054640F201100C +:10D9E00000211022002743460BF0C6FB06F00F066D +:10D9F0002046C6F1100908EB06014A460BF026FD49 +:10DA000004EB0900414632460BF020FD082F0AD0F6 +:10DA1000E85DE15D4840E119E0550A7AE85D0137CB +:10DA200050400872F2E705B0BDE8F083F8B50D4646 +:10DA300009881446074609F0A7F908B1B820F8BDCF +:10DA4000114806780BF04AF8B04224BFB220F8BD66 +:10DA500018200CF059FAA0B106460771002029469B +:10DA600012223060B01D0BF0F1FC0848016811B1C2 +:10DA700008460968FBE706600CB106F0E1FB0020F0 +:10DA8000F8BD1020F8BD00BFC9BA0200F82600207A +:10DA9000E0B51749FF238868426913764269D37E4F +:10DAA000012B16D10021D176C16BC97AC1B1FF21FA +:10DAB0008DF80710D0F8D41091F84320B1F8521027 +:10DAC000ADF80510D0F8D4138DF8042001A88847CC +:10DAD0008CBDD0F8D400427B90F82C00904200D14D +:10DAE0008CBDC868406C8047BDE88C4009F0E8BD3B +:10DAF0000C01002010B515480078022822D11248E8 +:10DB00000078F8B94FF6FF700021EDF7B3FE104C26 +:10DB1000012040F6B831A04708204FF4DC71A0473F +:10DB200010206421A04720206421A0474FF480509A +:10DB30004FF47A71A047074A35202821BDE81040EC +:10DB40000BF0C2BF10BD00BFE52700202426002037 +:10DB5000ED4701000875002070B5174A0546906929 +:10DB600010B30123147A137209BBE968426905F105 +:10DB70001406914202DAE968F7F78AFD3068B0428C +:10DB800013D06869016869614E60806828614169E5 +:10DB9000E9602021EFF3118581F31188294607F010 +:10DBA000E1FA85F3118802E070BD0120A8602046EB +:10DBB000BDE8704005F030BF38220020B0B58AB013 +:10DBC0001048C178D9B901250F492422C57001AC8C +:10DBD00020460CF0BFF94FF400708DF824500D4D25 +:10DBE0000D49224600230690084805900020049025 +:10DBF00007480190284609F007FA084845630AB02B +:10DC0000B0BD00BFA01F0020F0B50200F0580020FA +:10DC1000D2B60200986F0020959E020038220020A4 +:10DC200021F003010844009940F8083C40F80C2C0E +:10DC300040F8041C029940F8101C019940F8141C8B +:10DC40000F4940F8181C4FF0FF3140F81C1C40E908 +:10DC5000091140E90B1140E9131140E9111140E9A4 +:10DC60000F1140E90D1140F8781DC0E90911C0E914 +:10DC70000111C0E90311C0E90511C0E9071170479E +:10DC8000FD8B02002DE9F041077B04460D208846FC +:10DC900000EB4700C5B228460CF036F908B306463B +:10DCA0002078211D3070701C0CF0D9F8A07804F198 +:10DCB0000E013A467072E078B072607B3773F07292 +:10DCC00006F10D000AF002FE48F080002A463346B5 +:10DCD000C1B2452004F058FD3046BDE8F0410CF0DB +:10DCE00011B9BDE8F0812DE9F041D0F8A8501F46E8 +:10DCF00016468846044625B12046414632463B46F4 +:10DD0000A847D4E928010F40064056EA070008BF9B +:10DD1000BDE8F08120464146802204F003F9C4E9C1 +:10DD20002C6740B1D4F8A8108160D0E90812B14343 +:10DD3000BA43C0E908120020C4F8A80004F150005A +:10DD4000BDE8F0410CF0F2B870B520220D46044653 +:10DD50000BF07CFBA87C0026E661666160B14000A8 +:10DD60000CF0D2F8606130B1AA7C696952000BF006 +:10DD70006DFB002600E00126287E48B140000CF033 +:10DD8000C3F8E06128B12A7EE96952000BF05EFB1E +:10DD90004EB1606908B10CF0B5F8E06908B10CF05B +:10DDA000B1F8002070BD012070BD704770B5044609 +:10DDB00013480168F1B1114E3068D8B10E4D286892 +:10DDC000C0B160888847A8B90E48007830B10E49C4 +:10DDD00051F82000C0EB0010810001E00A48016802 +:10DDE000608832689047012804D160882968BDE8BE +:10DDF0007040084770BD00BF9C2300209423002082 +:10DE000088230020D727002090B402007FB50BF0B4 +:10DE1000F3FC114E04463078C8B901AD28460BF02A +:10DE200085FA00200E4A27212B468DF80C004FF072 +:10DE3000FF300290094805F099F90A4801210125AF +:10DE400009F09EFF0848002109F09AFF357020462E +:10DE50000BF08DFF7FBD00BFAA270020CC760020ED +:10DE600027E8010098700020E870002070B588B0A5 +:10DE7000134E0D460446C22096F8261004291CD0E5 +:10DE800008291AD086F82E50B46201A8182104304F +:10DE90000BF044FF02208DF80950019486F826000B +:10DEA00001208DF8080007480078022802D10648B2 +:10DEB0000021017001A800F085FE08B070BD00BF10 +:10DEC000A86D002024260020DC2700202DE9F84F33 +:10DED000DFF854B00646DBF8000010B30E20DDF882 +:10DEE00028801C4691460D4600EB430009F026FAB7 +:10DEF000B8B1074605714680D42049464FEA440A26 +:10DF00003870781D0BF0ABFF07F10E00414652460A +:10DF10007C730BF09BFADBF800103846BDE8F84F35 +:10DF20000847BDE8F88F00BF5C27002070B50446A5 +:10DF30008069A16A4D788E780BF010FF88B1017965 +:10DF4000013901290DD801210E2D14D89EB90021C7 +:10DF500001750C4935B151F82510C1EB011189004B +:10DF600001E070BD09680122C0E9061180F8202097 +:10DF700005F082FA002104480278A089BDE87040CB +:10DF800001F088BC90B40200DC27002070B5154E6B +:10DF900004464FF6FE713088884221D1162009F0E0 +:10DFA000CDF9E8B10546A0790221002808BF01217A +:10DFB000012069702870A06A4078A872000702D416 +:10DFC000A08903F0F9FCA169A81C0BF048FF002010 +:10DFD0002946E8740448007801F0C6F8A08930802A +:10DFE00070BD00BF802700209C7A0020F8B50D4648 +:10DFF00006460BF00AFE134F0446387808B1002598 +:10E000001BE0B5F5877F07D906F587703861A5F560 +:10E0100087704FF4877501E000203861B8800A48A6 +:10E0200031462A460BF096FF01203870786901309E +:10E030007861284606F06CFC054620460BF0D3FEBE +:10E040002846F8BD70240020A064002070B500238D +:10E05000B3EB113F1CBF052070BD03783F2B84BF7D +:10E06000092070BD44880026B6EB942F1CBF072002 +:10E0700070BD8588B6EB952F1CBF082070BD0A487F +:10E080000078032804BF032070BDD18196210020B1 +:10E090001372D480958091722103908141EA0361CB +:10E0A0002943116070BD00BF982700202DE9F0477B +:10E0B0008AB006468800994690460C1D00270DF14F +:10E0C000080A8DF80700200412D0A5B2B1B2484664 +:10E0D0005246202D28BF20252B460BF07FF9F8B2A1 +:10E0E00051462A460AF030FA07462E44641BEAE7F6 +:10E0F000F8B20DF1070101220AF026FAB0EB080090 +:10E1000018BF012040000AB0BDE8F0872DE9F843B0 +:10E1100005461448DFF8508089460321002400F1A9 +:10E120000C0798F80000C2B2944218D217F80C2CD1 +:10E13000AA4211D10BF069FDB968064638680A6831 +:10E1400042EA09020A6008B10BF0A1FD30460BF06B +:10E150004AFE98F80000002118370134E3E7C8B2FE +:10E16000BDE8F8831C610020002600207CB5154E18 +:10E170000446B07808B1012521E00DF10701E12046 +:10E1800008F0C0F89DF807000025A04217D0012034 +:10E19000B07001200BF0F2F90DF1060152208DF85C +:10E1A000065003F0F1FF204603F0C6F938B10648E7 +:10E1B00001216422047030780BF00CFEBA25284649 +:10E1C0007CBD00BFCC260020917A002080B513488A +:10E1D000007802280BD001280BD088B91148022101 +:10E1E00081700F48018821F00701018080BD022065 +:10E1F00000E001200A490A8822F007021044088042 +:10E2000009480AF0A5FF0028064819BF4FF44171DC +:10E21000A0F801100021817080BD00BF24260020DD +:10E220003E790020D0260020A679002070B5054652 +:10E23000807C0C2826BFA869C67A00260E2000EB39 +:10E2400046000BF061FE044618B1AD6928782070D5 +:10E2500008B1204670BD201D691C0BF000FEB5F80A +:10E26000090060800020002E2073F2D0E87A04F1CB +:10E270000E012073287B607305F10D003206E8D093 +:10E2800030F8022B013E21F8022BF7E7F8B5144DC8 +:10E29000044612484FF6FF762988B14202D111494F +:10E2A0000978298007684FB17868017821B1406802 +:10E2B0000178204604F028FE3F68F4E72888B04241 +:10E2C00003D0C1B2204604F01FFE0BF0CBFA064982 +:10E2D0000880BDE8F8400AF00FBE00BF247A002095 +:10E2E000862700209A7A0020887900202DE9FF41B6 +:10E2F000DFF84C80074613480D4616463946D8F8D5 +:10E30000044009F02AFB0F21002818BF0221002831 +:10E3100020468DF80C100C49098808BF6FF00201E7 +:10E32000ADF8041039460BF09AFD4670057001A94E +:10E33000404600220A2301F0CFF804B0BDE8F08186 +:10E3400088260020E0790020887900207FB5154ECE +:10E35000307828BB04208DF800001348C08AADF83F +:10E3600002000AF0C9FD6D4601462C1D20460BF047 +:10E3700034F92846F3F782FB0BF062FA4FF6FE7190 +:10E3800088420BD0BDF80210884207D0ADF80200D9 +:10E3900020460BF08AFC6846F3F770FB01203070D2 +:10E3A0007FBD00BFEC230020A86D002070B5154E86 +:10E3B00001211C461546F068C0680170F06880694C +:10E3C0000078022803D0B068D0F84C05804705F0EB +:10E3D000020004F0885140180AD00B480178013936 +:10E3E00001700021F0688069017009F07BF903E099 +:10E3F000B068D0F84C058047F0680021C068017013 +:10E4000070BD00BF0C01002029250020B0B5164CBE +:10E41000A06800F1D8030ECB1568D0F8E024186886 +:10E4200009684042904755B1A1686868D1F8E0108A +:10E4300009688842A4BF401A68602D68F3E7A068A5 +:10E44000D0E9381212680B68934207D00A60A068BE +:10E45000D0F8E000006809F057F9A068D0F8D404BB +:10E46000BDE8B040004700BF0C010020F8B50446ED +:10E470000020154F0D462060F868C068007828B964 +:10E48000B8680021D0F85824012090470BF0B4F967 +:10E490000646204629460AF089FC284601460068BF +:10E4A00018B1426863689342F8DA0C60206028680B +:10E4B000A04203D1B868D0F8D40480473046BDE804 +:10E4C000F8400BF054BC00BF0C01002070B5164E94 +:10E4D0000446F068C068007828B9B0680021D0F818 +:10E4E0005824012090470BF087F90546B068D0F812 +:10E4F000F824D0F8D8102046904730B9B068D0F84A +:10E50000DC10D0F8F82420469047B068D0F8E80036 +:10E510000068A04203D107F0E7FFF9F71DFE284687 +:10E52000BDE870400BF023BC0C01002010B515496C +:10E530006FF00B024AB18B180432DB898342F9D1A8 +:10E54000881800F10801C52016E06FF00B024FF6A5 +:10E55000FE732AB18C180432E4899C42F9D107E099 +:10E560006FF00B0262B18B1804321B7B002BF9D1C8 +:10E570001144488108310020034A12780A7010BD06 +:10E58000C72010BD4C790020DABA02001249134AA4 +:10E59000096892F82620002918BF0222D2B2062A62 +:10E5A00005D0052A07D10F49096899B108470C49D8 +:10E5B000096879B1084721B18979022904D0012974 +:10E5C00004D140780BF08EBCFDF754BB06490968B6 +:10E5D00001B10847704700BFD8260020A86D002071 +:10E5E0000C25002008250020782300202DE9F04785 +:10E5F000054615488A464FF0FF394FF00008046879 +:10E600006768BC421DD026462468307D0028F8D0BB +:10E610006DB1F06850450AD1306918B1306250448C +:10E62000F06001E086F81480D6E906108847307D56 +:10E630000028E6D0F068A0EB0A00484538BF8146C4 +:10E64000DFE74846BDE8F08708200020B0B5164A4D +:10E650000121147A11722022EFF3118582F31188BF +:10E66000024652F8143F93420FD0106803681360BB +:10E6700001745A60C16809B100220A758068294690 +:10E6800006F070FD85F3118808E0017CC90706BF1C +:10E69000418A01310121418285F311882046BDE87C +:10E6A000B04005F0B9B900BF3822002070B5144E53 +:10E6B0002021B06DEFF3118581F31188F16CF26DBB +:10E6C000B1FA81F1C1F11F0102EBC101814210D900 +:10E6D0000C480121047A01720B4809F049FD002021 +:10E6E00086F84800204685F31188BDE8704005F0A3 +:10E6F00093B9002086F8480085F3118870BD00BFEB +:10E70000A01F00203822002071040200B0B504468A +:10E71000C068256990F8381001F0030101290ED175 +:10E72000297C61B9416C0A78052A08D1497803220D +:10E73000062908BF0222012908BF02222A740021EB +:10E74000297090F84810A97090F842100069E9709B +:10E7500068600AF0D1FB014605F108000BF07FFB71 +:10E760002069F6F7A5F82075B0BD10B586B004464F +:10E7700000200121CDE9000002904FF48170ADF836 +:10E7800004002088ADF80000E0780128684608BF42 +:10E7900021218DF80210F0F76FFD9DF8140088B963 +:10E7A00003980921406C0170A1784170208805F020 +:10E7B000C3FA10B103980421C182684603F024FF14 +:10E7C0009DF8140006B010BDFEB5047C00F11C03DA +:10E7D000012201256CB11E78F70718BF16F00C0F47 +:10E7E00001D1002502E0760748BF00220833013C32 +:10E7F000F0E7037A0BB1002413E0012D18BF0129C3 +:10E80000F9D101248DF808204179827A0472C088F8 +:10E810008DF803108DF80420ADF8060068460AF064 +:10E8200011FB2046FEBDFEE70F280ED840F2025233 +:10E83000DFE800F014101210080D081010100D1071 +:10E840000810100D4FF2011208E01E2802D141F20B +:10E85000011203E0002201E04FF4817231B1FF297F +:10E8600007D14FF203101040C03008E042F03000F2 +:10E8700005E0C8070CBF42F0200042F01000000481 +:10E8800000F203707047704780B50C4908700C485F +:10E89000002101700B480C49008808800B480C4986 +:10E8A0000BF0DDFA0B480C4901600C480C4900786C +:10E8B0000870BDE8804007F057BB00BF997A002080 +:10E8C000987A00208827002096700020A6790020E2 +:10E8D000C0260020EC580020B8260020C4270020C5 +:10E8E000977A0020F8B5044613480025061D134802 +:10E8F00007783046394639B110F8242B013A022AFC +:10E9000038BF01350139F6E7280611D0E8B24000DA +:10E910000BF0FAFA60B1014667B13278013A012A88 +:10E920009CBF36F8042C21F8022B2436013FF3E774 +:10E93000002000252570F8BD20450020E3BA020024 +:10E9400070B50646807C0930C5B228460BF0DCFA6B +:10E9500018B30446B0782070F0786070307BA070F7 +:10E96000B07BE070F07B2071307C6071707CA071B6 +:10E97000307DE071707D207204F10900B27CB169D4 +:10E980000AF064FD4520FF212A46234603F0FCFEE1 +:10E990002046BDE870400BF0B5BA70BD70B50646B4 +:10E9A0008078032101EB4000C5B228460BF0ACFA99 +:10E9B00000B304463078207070786070B078A07032 +:10E9C000706870B1E11C0022B3789A4209D210F845 +:10E9D000023B013201F8023B10F8013C01F8013C16 +:10E9E000F2E74520C4212A46234603F0CDFE204607 +:10E9F0000BF088FA002070BDB0B50446144890F8BA +:10EA0000261004290AD0082908D0217801F0030132 +:10EA1000012908D121690978062904D161884FF6B6 +:10EA2000FE72914201D1C22508E0C08A814201D123 +:10EA3000207F40B12046E7F707FF054620460BF050 +:10EA400061FA2846B0BD2046FEF768FCF5E700BF36 +:10EA5000A86D002020291CBF6FF0010070477CB515 +:10EA600004464068114EA1684068098CC6E901015E +:10EA7000204600F031F988B9C72031898DF80700A8 +:10EA800020460AF096FB0DF10700012101F0FAF88B +:10EA90003189054620460AF095FB15B14FF0FF304D +:10EAA0007CBD204600F018F97CBD00BF0C2400207E +:10EAB0002DE9F04104461348DFF84C80002700267A +:10EAC00000F1080598F80000874217D215F8080CE5 +:10EAD000A04210D1284608F0E5FA0646286828B179 +:10EAE000F8B24FF40041FFF711FB04E0F8B24FF425 +:10EAF0000041FEF7D9FD18350137E3E73046BDE8A0 +:10EB0000F08100BF1C6100200026002070B5044683 +:10EB1000807861680A5C0D1802F0070262700A5C76 +:10EB200028460421C2F3C102227410F8016B07F0D9 +:10EB300025FE0521A061B006217704F1080004D468 +:10EB40000021C0E90011052005E0691D0BF087F9DF +:10EB5000207F08302077217C012904D1C1B2013007 +:10EB6000695C2077A17570BDF8B50646114801278C +:10EB700014460D4647700720F7F7B2F8022006F05A +:10EB80009BFD3120314609F03BFB0B48032100225D +:10EB90004160016821F0030165F3000165F3410163 +:10EBA0000160064821460068036800209847044831 +:10EBB0000760F8BD182300200C800240CC01001033 +:10EBC000A802504270B58AB000266C46054628213E +:10EBD000867120460BF0A2F804F1190005F10B0133 +:10EBE0000B220AF033FC28680B490860204629688C +:10EBF0000BF0F3F8A888ADF81360ADF81100D5F864 +:10EC00000700CDF8150005488068D0F87C14204630 +:10EC1000884700200AB070BD047A00200C01002053 +:10EC20001CB5154C10200DF106018DF80600A068EA +:10EC3000D0F830245A2090474FF4FA70ADF8040011 +:10EC4000A068D0F8302401A95520904707200DF185 +:10EC500003018DF80300A068D0F8302459209047B4 +:10EC600009200DF107018DF80700A068D0F83024C5 +:10EC7000E02090471CBD00BF0C01002010B51349D7 +:10EC80000446487808B1486A10B900204870086AFC +:10EC900009F030FF0E48006840B10E4800780128A6 +:10ECA00008BF002C0BD0642000210AE00CB1032027 +:10ECB00000E005200021BDE81040E5F79FBD64207D +:10ECC0000121BDE81040EFF769BF00BFAC22002072 +:10ECD00078270020242600202DE9F8430446144E0E +:10ECE00005200DF103080DF10209A5688DF8030058 +:10ECF000318920460AF05DFA4046012100F0C2FF4A +:10ED00004846012109F09CF83189074620460AF05F +:10ED100059FA4FB99DF80200C00705D0686A00286B +:10ED2000E6D00AF057FDE3E73846BDE8F88300BFB8 +:10ED30000C2400200E48007888B90E48007870B97D +:10ED40000D48007858B90D48007840B90C48007853 +:10ED500028B90C48007810B90B48007808B1002099 +:10ED600070470A480078B0FA80F04009704700BF49 +:10ED7000B07A0020B37A0020B87A0020AB7A002065 +:10ED8000B17A002026250020B32700202725002067 +:10ED900010B50446812804D310488068D0F84C058B +:10EDA00080470AF029FD0E490C700C498968D1F89A +:10EDB000B8100A780B4991F900101AB1002902D451 +:10EDC0000949097819B10AF0D2FF012010BD0AF0F3 +:10EDD000CEFFBDE81040F9F72BB900BF0C010020B1 +:10EDE00058260020B87A0020AB7A002080B50AF0BF +:10EDF00003FD134A0023117813708A070CD44907C6 +:10EE000019D50AF0B4FF0F4800218068D0F85824C3 +:10EE10000020BDE8804010470AF0A9FF0948C168FA +:10EE2000C968097829B980680021D0F858240120E0 +:10EE300090470AF0E1FCBDE880400AF098BF00BFAF +:10EE4000907A00200C0100202DE9F8430446134875 +:10EE50004FF6FE79124D09F1010806786FF00100B6 +:10EE6000013087B2BEB12888A0420DD1A81C09F09C +:10EE700025F968B965B128461C210AF04FFFA5F8AD +:10EE80000A80A5F8009003E0BC4201D14845EDD1CD +:10EE90001C35013EE6E7BDE8F88300BFD1BA0200A9 +:10EEA0003056002010B5044681680079FFF72EF92E +:10EEB000207B00B110BD20680AF053FF0E480168A6 +:10EEC0000246A14204D00A460969A142FBD1103290 +:10EED000216911600021216150F8041F21B1084609 +:10EEE00009690029FBD110300460044841680078AA +:10EEF000BDE81040FFF70AB9782600203826002028 +:10EF000010B51446AB2808D0A2280CD0A32812D0E4 +:10EF1000A12817D10F48008811E00B48016820464E +:10EF20000AF09DFF0CE0094802685AB108462146E4 +:10EF3000BDE8104010470648016819B18847208095 +:10EF4000002010BDB52010BDEC5800203424002056 +:10EF5000F423002096700020BFB50AF0FFFE90B1A8 +:10EF60000546408801242421FF228DF80040ADF899 +:10EF70000C0028460AF07CFE802085F821006846B7 +:10EF800005F05EFC00E000240020042104F02CFECB +:10EF900005490978884204D2044801210170F5F737 +:10EFA000E9FC204604B0B0BDE3BA02009727002078 +:10EFB000F8B50AF02AFE1349002200230025002498 +:10EFC000886048680668A6B1B6F1FF3F05DD5BB111 +:10EFD000176835443744176009E0AC4286F00046B4 +:10EFE00098BF2C46002302E00123024635463044F8 +:10EFF000E8E788680AF0F7FEA54288BF2C4620465D +:10F00000F8BD00BFD02500201CB501784478827877 +:10F01000FB298DF806408DF8072001D304200DE070 +:10F0200004F01F01152908D80C4A52F8211021B10B +:10F0300088478DF8050018B90EE001208DF805000D +:10F0400004F0E000202807D10DF105036020002125 +:10F05000032203F099FB1CBD1CBD00BFE021002072 +:10F06000B0B588B0134D0446286808B101201EE0F1 +:10F0700008200AF049FF2860C0B1216801602179A9 +:10F080000171B4F80510A0F8051001AD1821281D74 +:10F090000AF044FE2068019020798DF8090060791B +:10F0A0008DF808002846FFF78DFD00E0102008B01D +:10F0B000B0BD00BFD82600202DE9F84380460320CC +:10F0C0001E46144689468DF80100684607F008FD83 +:10F0D0000125B0B1074600690B21867044700170AC +:10F0E000BD7709F009FF084800217D77BD76A7F8B4 +:10F0F0000280C7E90890054801703846FFF77CFC9C +:10F1000005462846BDE8F883E0790020A7270020BF +:10F11000B0B50C480C490D4AC0E904210C490978E6 +:10F12000C90702D1816951B9B0BD0A4A0D490C4DD8 +:10F13000094B0A4CC0E90615C0E908438262BDE8E4 +:10F14000B04008477423002029780200614F010075 +:10F15000DC270020E1340100D1130200DD9801001A +:10F1600095C90100217C0200F8B511B3044612488C +:10F170000D46A0F11001114800780130013804BF9C +:10F180000320F8BD01F11806097CA1423146F5D1F2 +:10F190000AF03BFD07463046294607F019FD204698 +:10F1A0004FF40041FEF7B2FF38460AF01CFE002083 +:10F1B000F8BD0520F8BD00BF1C610020002600201E +:10F1C000B0B5124949684A68D2E90115D46860B1FE +:10F1D00055EA040005D00E480022C2610D4A5032A3 +:10F1E000026021B1F5F7C5FB01E001B1884755EA9E +:10F1F000040008BFB0BD09F0A7FE05B1A84704B1DF +:10F20000A0470448BDE8B04008F0AABCD01E0020CA +:10F21000001004400100070670B58AB01C46154670 +:10F2200002460B46002006AE102805D0295C81F06E +:10F23000360131540130F7E7304601210094EAF7F6 +:10F24000EDFC02A8214610220AF000F90020102847 +:10F2500005D0295C81F05C0131540130F7E700945E +:10F2600006A802AA01218023EAF7D8FC0AB070BDE3 +:10F2700070B50AF0C1FA104E04463078B0B90F4D9F +:10F280000F4A31210023284603F070FF05F11C00CE +:10F2900006F110010422082309F0B8FF094A4FF0D3 +:10F2A000FF3001210125FFF75FFC35702046BDE8E6 +:10F2B00070400AF05CBD00BF1823002074220020BB +:10F2C000CDE5000080A9030080B51248007805282C +:10F2D0001BD109F083F8062008F062FD0E48007883 +:10F2E00001280AD80D48008800F00700022804D041 +:10F2F0000020002100220AF051F804F0BDF8FAF7CE +:10F3000007F8BDE88040FDF79DBEBDE8804004F0F1 +:10F31000B3B800BFD0260020242600203E7900206C +:10F320007CB5856904460421284607F027FA0E4B70 +:10F3300029796A7902250126009040F20110ADF882 +:10F34000050068461D72094D8DF804102E70084D99 +:10F350002A70627C074D2A7062881A80FFF780FE4F +:10F3600008B108F0DDFB7CBD9C790020BB270020A4 +:10F37000C77A0020C67A0020F8B5144F1446054617 +:10F38000069A079E8DF8031078680370130AC670FA +:10F390004270837036B10899043032460AF056F84C +:10F3A000301D00E0042048F20601C3B20DF1030055 +:10F3B0002A46691AB1FA81F149090901B970214651 +:10F3C00000F08AF80021B970F8BD00BF882600203F +:10F3D0001FB504461348406842700170207A0F2818 +:10F3E00001D0022814D120884FF6FC71401A03285E +:10F3F0000ED802280CD002208DF80C000AF032FA48 +:10F40000ADF80400074801A93622022300F064F891 +:10F41000044821463622022304B0BDE8104000F023 +:10F420005BB800BF8826002070B586B00C46134933 +:10F430000546114800780978084301D1012019E0F8 +:10F44000BDB1B4B1284601F0F7FB064605F1100046 +:10F450000AF056FD86420CD102AE002000212A4659 +:10F4600090230096EAF7DAFB30462146F3F7C6F917 +:10F4700000E0022006B070BDBC270020242600203A +:10F480002DE9F047DDE90897DDF828A080461C4605 +:10F4900015460E463846C4B1B84208D140463146FA +:10F4A0004A463B46FBF79AFA0146002071B919F823 +:10F4B00000102A78BAF1000F18BF11408A4207D114 +:10F4C00001350136013C0130E5E70020BDE8F08759 +:10F4D0006FF00600BDE8F08770B588B004460020E4 +:10F4E0000F260133CDF81A00ADF81E00CDF8160036 +:10F4F000087A8DF81C0008880B49ADF814002078B4 +:10F500004D6805F8010D88780331CDE900510749B0 +:10F51000CDE9020605A8E8F7F1F910B92178013123 +:10F52000217008B070BD00BF8826002094250020FF +:10F5300010B50446812804D30F488068D0F84C05E4 +:10F5400080470AF059F90D490C700B498968D1F8C8 +:10F55000B8100A780A4991F900101AB1002902D4AA +:10F560000849097811B10AF002FC03E00AF0FFFB38 +:10F57000F9F710F9012010BD0C01002058260020D9 +:10F58000B87A0020AB7A002010B5114CA068D0F8F2 +:10F590005C028047B8B10F4900222223CA814A7514 +:10F5A0000D4A4B8212780A75A268D2F8D42092F8DC +:10F5B000243092F831200A74084A4B741278504370 +:10F5C0008000C86110BD1C20BDE81040F3F7A4B84E +:10F5D0000C010020B8750020B97A0020B47A002010 +:10F5E000B0B511488068D0F81814D0F8D40090F85D +:10F5F0005300884740F63875042808BF43F66C4529 +:10F600000AF003FB04460948007845430AF04CFC25 +:10F61000B5FBF0F00649074B0022FAF76FFC2046D5 +:10F62000BDE8B0400AF0DFBB0C010020B47A002036 +:10F63000E17E02002C2700202DE9F8438146124884 +:10F64000884600240025861C10480778BC4218D242 +:10F65000280616D1304608F031FD70B136F8020C9C +:10F66000002541464845304608BF0A2508F075F98F +:10F67000002818BF65F05F0500E000251C36013446 +:10F68000E4E7E8B2BDE8F88330560020D1BA0200C2 +:10F69000BCB50D46134904464089097839B1104973 +:10F6A000C98A884203D1BDE8BC4000F0EFB900210F +:10F6B000FAF764FC60B1807910F0180F08D02B8D38 +:10F6C000627F6189A0896C8E009400F0D7FBBCBD7D +:10F6D0006189A089002202B0BDE8B040FEF7DEB823 +:10F6E000A86D0020CD27002000B5EFF3038212F0B3 +:10F6F000FF0F0DD06A46A2F1200282F309886FF055 +:10F70000020E10604FF08071D1610B49916170471A +:10F710005DF804EB694681F3098880F308884FF0AF +:10F720000200EFF3148180F314880448016821F08B +:10F7300040410160704700BF10F7010034EF00E066 +:10F74000F8B50E4604460AF057F80546D4E901011B +:10F75000814205D128460AF00AFB4FF0FF30F8BD80 +:10F76000E3682168A2690133B3FBF0F707FB1037A8 +:10F7700002FB071031460AF0EDFBA0686169E76003 +:10F7800001308842A06088BF0146284661610AF0C6 +:10F79000EEFAA068F8BD70B5054600780C4616462E +:10F7A0000822087068784870A97840EA01106070F3 +:10F7B000E878A070297940EA8100A070697940EA70 +:10F7C000C100A070A97940EAC110E91DA070E01C39 +:10F7D00009F03CFE04F10B0005F10F01032209F0D2 +:10F7E00035FE0F2E24BFA87CA07370BD70B50668CF +:10F7F0000D4604460AF000F80F490978012901D1A5 +:10F80000317819B10AF0B3FA002413E00121317004 +:10F810000AF0ADFA0948002D18BF28460178426861 +:10F820003172326102290CBF80680020F0600A202A +:10F83000F6F756FA204670BDA8270020C4B802008B +:10F840002DE9FF41124C00254FF0FF360DF1040861 +:10F850000027208881B28F4228BFBDE8FF81616800 +:10F860004A57B2F1FF3F0FDC4B19D0B210F07F00C6 +:10F87000187003D143460396CDE90166B9B2012061 +:10F880000C2206F0E1FE20880C350137E2E700BFCC +:10F8900040260020FEB50446032017460E468DF88C +:10F8A000090002A807F01CF905460120C5B1296925 +:10F8B0000C228F704E700A70A87709F01DFB094862 +:10F8C0006E4631466862204606F026FA10B10120E5 +:10F8D0002E62687701206C80A8762846FFF78CF8A6 +:10F8E000FEBD00BFE0790020F8B5124D04460026A9 +:10F8F00029880844B0F5877F0AD90F48C1F5877772 +:10F900000844B9B203F040FD2E80E41B00213E46BE +:10F9100009480844A1B203F037FD28884FF48772E4 +:10F92000204481B2B1FBF2F101FB120028803019B2 +:10F9300080B2F8BDC826002084620020F8B5114FBF +:10F940000546786808B1804780B1B868FAF7D6FDF7 +:10F9500004460D4806787EB90C48C088C0F50050B2 +:10F9600000B2A84204DB1DB1042605E00B2607E027 +:10F970000020E2F72BFC3E78B8682146FEF7ECF851 +:10F980003046F8BDA023002098270020B872002040 +:10F99000F0B589B0ADF82010079007A802AA0021A1 +:10F9A0000024FEF753FBB0B90C4FB868FAF7A6FD78 +:10F9B00005460B4800940323C188C07802AAEAF7E1 +:10F9C0001BFE0646B868BDF816702946FEF7C4F857 +:10F9D000002E08BF3C46204609B0F0BDA023002001 +:10F9E000B872002070B50D4606460AF00EF90446BE +:10F9F0003046294608F034FAB0B1054600680AF0EE +:10FA0000B0F9286809F0E0FE0A490868854204D088 +:10FA100001460069A842FBD11031286908602846D8 +:10FA20000AF070FA002500E0022520460AF0DBF912 +:10FA3000284670BD7826002010B509F0DDFE0F4C79 +:10FA4000217E022902D0217E042904D10E490C68AE +:10FA50000AF08DF910E00AF08AF909480068006B95 +:10FA60008047084AA0FB020301FB023110F19050CD +:10FA700041F17A00E16C0C18204610BDD01E002028 +:10FA80008C01001000093D000430044010B50F4CFB +:10FA90004FF48051207803F095FC18B10C480121F7 +:10FAA000017010BD0B4802780B480178012918BF7E +:10FAB00003210020EEF74AFF084920780A884FF416 +:10FAC0008051BDE810400AF085B900BF9C7A002043 +:10FAD000E8250020CF270020CE27002096BA02007C +:10FAE00010B5134C206808B3C16C11B10AF060F96D +:10FAF0002068416C11B10AF05BF92068416911B1CD +:10FB00000AF056F92068C16911B10AF051F920686C +:10FB1000416B11B10AF04CF92068C16B11B10AF0C8 +:10FB200047F920680AF0EEF90020206010BD00BF00 +:10FB300044270020BFB501AD0446AB2000212A4672 +:10FB4000FFF7DEF909F0D8F90146284607F005FF6E +:10FB500088B101A9204606F0DFF850B101A803A939 +:10FB600007F01EFD50B101A80DF1020106F05AFE8A +:10FB700008B1002000E0012004B0B0BD0398007976 +:10FB8000002818BF0120F7E72DE9F04186B01248A0 +:10FB90000DF104080027002508F102040678B9B227 +:10FBA000B14214D2082000221423CDF8008006F0C0 +:10FBB00035FD50B99DF80400FF2806D021460022EB +:10FBC000FDF734FF002808BF01350137E7E7A8B289 +:10FBD00006B0BDE8F08100BFC9BA02007CB504469A +:10FBE000032008F0DDF8A07905F00EFE0E4D208907 +:10FBF000E67A2188A278AB78CDE9000604F10C0002 +:10FC0000F3F7D8FC044660B9A878000704D4074885 +:10FC1000007830B9082001E04FF400400121EBF7F3 +:10FC200029FE20467CBD00BF3E790020D226002060 +:10FC3000BCB5114C206970B1104901258D70FFF7DA +:10FC4000CDFFB8B120698DF8075004F031FB0C48A6 +:10FC50000DF1070107E0094800218DF806108170B9 +:10FC600007480DF1060100780091032101220123CC +:10FC700003F0C7F9BCBD00BFAC2200200C7A002005 +:10FC8000A37A002010B588B00C460021049140B141 +:10FC9000CDE902400F48406802A90AF0BFF80138D8 +:10FCA00015E00DF1070003900120029008788DF80F +:10FCB00007000848406802A90AF0B0F818B1013CF2 +:10FCC00004D00120E4E74FF0FF3000E0002008B04E +:10FCD00010BD00BF0C240020B0B50C46054609F04D +:10FCE0008BFD0F490A78862A10D187220A700D49A8 +:10FCF000CA890132CA810AF03AF80B480078A84252 +:10FD000008D1002C14BF1B20002004E0BDE8B04047 +:10FD10000AF02DB8E920BDE8B040F2F7FDBC00BF05 +:10FD2000B87A00205C780020C57A0020F0B5059EE6 +:10FD300000244FF6FF7C0027B44220D21D88654581 +:10FD40001AD017B13F88874201D2854204D81D1DC1 +:10FD50001F4601342B46EFE71F46B44205D23D88CB +:10FD6000654502D001340437F7E73C4654F8045D9A +:10FD70003D609C422746F8D8D9709A701880F0BD33 +:10FD8000B0B5054600781446E91C1070687800F09C +:10FD90000F005070687800099070A87800F0030098 +:10FDA000D070A878C0F380001071A878C0F3C300A9 +:10FDB0005071A878C0099071D01D082209F046FB47 +:10FDC00004F10F0005F10B01032209F03FFBA87BB2 +:10FDD000A074B0BD10B550B1014650F80C0C18B964 +:10FDE00011F8020CFF2804D0084608F085F9052018 +:10FDF00010BD0A4C207801F8020C09480278094825 +:10FE000002F042FD01281CBF042010BD20784FF4F1 +:10FE10000051FEF77BF9002010BD00BF9C7A002046 +:10FE2000D0BA0200482700202DE9F041124F0E46BB +:10FE30003968F1B115460A69DAB18A6A00041C46CC +:10FE400000F101081AB140463146904700E0002019 +:10FE5000A84204BF0020BDE8F081386831462A4638 +:10FE6000234607694046B847012804BF0A20BDE879 +:10FE7000F0810920BDE8F081682700202DE9F041DC +:10FE80000C4605463AB1284621460B220023BDE820 +:10FE9000F041FBF7D6BFDDF81880204600211E4652 +:10FEA000FAF76CF860B107468079C00708D0404681 +:10FEB00031462A46ECF73AFD4FF6FE71884201D1F1 +:10FEC000BDE8F0817880204629460C22DEE71FB588 +:10FED000014604208DF80000087A01280AD0032882 +:10FEE0000AD0022814D10888ADF802006846F9F754 +:10FEF000BBF808E008880DE06C46201D09F06DFB9A +:10FF00002046FBF7C5FB38B96846F1F7B7FD03E0BB +:10FF10004FF6FE70ADF80C00BDF80C0004B010BD3B +:10FF2000B0B505464068007D1030C0B207F006FA53 +:10FF3000D0B16B680446A87829881D781A7D618144 +:10FF4000207304F110006060C5F3401522726572E1 +:10FF500002252580196909F079FA044821460078BC +:10FF6000BDE8B040FFF700B9B0BD00BF997A0020EE +:10FF700070B5064600204FF6FE713446B0607180C1 +:10FF800044F8040F304606F01FFD0546012812D143 +:10FF90000A48B189406801EB410100EB81004188CA +:10FFA0007180061D304608F089F8012803D12046EB +:10FFB000314609F012FB284670BD00BF40260020E4 +:10FFC0002DE9FF4110486C464FF00108251D861CA5 +:10FFD0000E480778AFB1B078013803280ED8F07812 +:10FFE00000070BD430888DF80080ADF80C00204657 +:10FFF000FFF7BEFF10B12846FEF7AEFF2436013FE3 +:020000022000DC +:10000000E8E7BDE8FF8100BF20450020E3BA020019 +:10001000B0B505F0E9F90E4C0E4D1420611CA8474F +:100020000A202146A84709202146A8470A49082056 +:10003000A847B92000F06BFA084C1420A0470A200A +:10004000A0470920A04708202146BDE8B040084746 +:1000500000640020699D020002200020313102006E +:100060002DE9F04107460E465818B968496888429C +:1000700084BF6FF00300BDE8F081DFF830804FF0FF +:10008000FF311C461546D8F8000009F0D7FD384668 +:1000900031462A462346FAF7A1FC0446D8F8000068 +:1000A00009F044FF2046BDE8F08100BF0C24002089 +:1000B00010B504281CD10F4809F0FCFEC0B109F0AE +:1000C000F3FE04460B4809F0F3FE604380084A281B +:1000D0000ED8084809F045FE052005F0EDFA06485F +:1000E000012180F8251005480421283009F022FF5D +:1000F000002010BD7C710020D01E00207020002048 +:10010000BCB504460DF10702002001213A2308F096 +:1001100093F84FF6FF75B8B99DF80700A04212D0CA +:100120000DF10602002001213B2308F085F858B9A3 +:100130009DF80600A04207D19DF80700A04205D215 +:100140002046F6F75FFF3A252846BCBD3B25FBE776 +:1001500070B588B0054680690488104800888442DC +:1001600007D103AB812000211122002609F004F8F9 +:1001700058B1297C687C48F211022346CDE9002160 +:10018000A91C842206F088FD06E0687C0096A91C64 +:1001900003AB224602F078FC08B070BD88790020DD +:1001A000E0B500218DF8071050B110480DF107019E +:1001B0000022012300780091032102F022FF8CBD70 +:1001C0000949487850B1086A40B100224A7008F0E5 +:1001D00091FC3220BDE88C4008F02CBC03200021AB +:1001E000BDE88C40E4F70ABBAC220020A37A0020D3 +:1001F000862806D1114801880520142908BF04204B +:10020000704701467F30C0B203283CBF04207047CE +:100210000120012911D080290FD003290DD00229F6 +:1002200004BF0220704701F0FE00842804BF0320B1 +:1002300070470020882908BF0320704784270020CA +:10024000E0B58DF807000D480DF10701C0680069A1 +:10025000007805F011FC0B490948096800680A6E2E +:100260009DF9071090470146074A6FF39F5191424D +:100270000EBF4FF0FF30054948608CBD0C010020D7 +:100280006C7A0020347A0020FFFF3F0058260020BF +:1002900010B509F0B1FA0D49097819B1BDE810405F +:1002A00009F065BD0A4991F900100029F6D4094901 +:1002B00009780029F2D10849084C4968216009F001 +:1002C00056FD2068BDE81040FCF758BFB37A002007 +:1002D000B87A0020AB7A0020582600202C7A002023 +:1002E000B0B5104CA068016C096811B9D0F84C0584 +:1002F00080470D4D286808F035F9A168096C096838 +:10030000C860286807F0CCFDA168096C09680882FC +:100310000648007828B109F0C9FDA168096C096890 +:10032000C860B0BD0C010020487A0020942700204E +:100330002DE9FC4106464FF0FF300D469046CDE9D1 +:1003400000006846314607F008FB07460B48046882 +:1003500084B11FB12088A84206D008E004F10C0047 +:10036000314607F0FAFA10B1A078404502D004F106 +:100370001800ECE72046BDE8FC8100BFE8790020CA +:1003800010B5114CA068D0F8AC00007808B900F0A6 +:1003900083FDFFF77DFFA068D0F8B800007818B1A2 +:1003A0000A48016801208847F8F78CFDA068D0F85A +:1003B000B8100A783AB1496929B1D0F82813102049 +:1003C000BDE81040084710BD0C0100203027002078 +:1003D000B0B5A0B00E4D0446012085F83000686B22 +:1003E00008B902A868632046F2F738FF03200B4AD9 +:1003F000287508480068A16BC3B2074800910F2B0D +:1004000038BF02460020002104F0C6FE20B0B0BD77 +:10041000381F002004ED00E050AB0200C3AC020026 +:10042000F0B52022EFF3118182F3118890F8282093 +:1004300012B181F31188F0BD0C4A012492F84830C2 +:1004400082F84840466B456A7768066047603860C6 +:1004500080F82840D46C2C43D464706081F31188F8 +:1004600003B1F0BDBDE8F040FEF720B9A01F0020A9 +:10047000B0B5124CD4E91651E06CB0FA80F0C0F17E +:100480001F0001EBC001086802680A6051600A6839 +:100490008A4204D1416AE26C22EA0101E164FCF77C +:1004A000D5FEE06C40B1E16DB0FA80F0C0F11F0004 +:1004B00001EBC001A942E6D8B0BD00BFA01F0020DB +:1004C000F8B50646C86860B110F00F0009D137686A +:1004D00014460D4609F090F997F8251021B109F05E +:1004E00046FC4FF0FF30F8BD012187F8251009F0D8 +:1004F0003EFC296807F10C0C91E88D0029468CE838 +:100500008D0030462246BDE8F840E9F707BEB0B599 +:1005100004461420002108F0F9FE07250A200021D6 +:1005200008F0F4FE681C0FD024FA05F000F0010179 +:10053000092008F0EBFE0A20012108F0E7FE082060 +:1005400009F01EFC013DE9E71420012108F0DEFE60 +:100550004FF42F70BDE8B04009F012BC2DE9F04116 +:100560000F460646C189808998461446727A337CC4 +:10057000451AA8B2FDF79AFD08B1BDE8F081E91966 +:10058000B28914FA81F0904206D9F1890620A1427D +:1005900038BF0520BDE8F081307C89B24246234651 +:1005A00008F01CFF0020BDE8F0817CB540EAC100E6 +:1005B0000D46164640EA4211069800F8011B1946FE +:1005C00009F00BFC044636B108F096FC01462046C3 +:1005D00009F045FC0834012D0DD10DF10702002072 +:1005E00001213A23002507F027FE9DF80710002877 +:1005F00018BF294621707CBD7CB515460DF1060259 +:100600000C4605F03DFE08B101207CBDBDF806603A +:100610006946304605F088F9009858B120462946C9 +:10062000F9F76CFB2046012108F0DEFCFCF762FBC9 +:1006300000207CBD684602F0D3FF08B111207CBDCC +:1006400000980680EAE7704710B50E480078012848 +:1006500016D10D4805F030FB0C4C204607F0B0FCDD +:100660000B48046106F0ECF940F2000CEFF3118046 +:100670008CF3118809F011FCBDE81040FBF7D4BFE2 +:1006800009F096F8A01F0020C11C0200B0760020DF +:10069000381F00202DE9FC410E48104F00264FF076 +:1006A000000805780C480488B5420FD0B1B202208A +:1006B00000222346009705F0B1FF20B93878FF28C3 +:1006C00018BF08F101080E370136EDE71FFA88F070 +:1006D000BDE8FC81DFBA02004EB202003079002092 +:1006E000B0B5054609F088F8044605F013FF0D483B +:1006F000012D06D1012101700B48008B40F0200034 +:1007000007E000210170407828B90748008B20F0ED +:10071000200005490883204609F029FBBDE8B040C8 +:1007200008F0EEBC7C27002000720020E0B50E48E7 +:100730000122018B41F0550101830C49C9684969C7 +:100740000A70018B807EADF8021042F202018DF832 +:1007500004000748ADF800100649006809684A6AB5 +:10076000694690478CBD00BF007200200C0100203C +:10077000E4260020347A0020B0B504460F48007803 +:10078000012815D80E48807B800711D5A07A012852 +:100790000ED0258809F054F8854209D0E07A012866 +:1007A00006D0208808F04AF810B1208801F004F93A +:1007B0002046BDE8B040F7F7A7BB00BF24260020C5 +:1007C000A86D002010B5104C607890B10121217007 +:1007D00008F060F96078FF2810D0002161704FF4B4 +:1007E0007A7100FB01F209488021007809F0F2FAE1 +:1007F00004E000202070002008F04CF9024941205C +:10080000BDE8104001F0C0BC042500209C7A002007 +:100810000E480F4A0F4B0168825800680340D0B25F +:100820000D4A7F2888BF0020934207D1090F022973 +:1008300006D307D0032901D1153004E0FF2002E0E0 +:100840000A2000E00B3040B2704700BF1813005080 +:1008500088FDFFFF00F0FF0F0010B40BB0B5044699 +:10086000481D85B22046294608F09AFC00F0FD029A +:100870002046294607F026FD0A4904EB440001EB17 +:10088000800515F8190F58B12046022108F088FCA0 +:1008900000F0FC022046022107F014FD0020287021 +:1008A000B0BD00BFB8720020B0B510484FF4705111 +:1008B0000F4D006801EA80204142C5E90101012095 +:1008C00006F014FE044608F097FF296839B109F0D4 +:1008D0004EFA4CB12046BDE8B04009F05FB82C603C +:1008E000BDE8B04009F043BAB0BD00BF30240340BA +:1008F000DC2500202DE9F04187680E461944786810 +:10090000814284BF6FF00300BDE8F081DFF82C80E6 +:100910004FF0FF311C461546D8F8000009F08EF95B +:10092000386822468119284609F014FBD8F80000DF +:1009300009F0FCFA0020BDE8F08100BFDC250020B2 +:1009400070B505460F480C46A0F1100609F05DF998 +:100950000D490978013101390ED0337C06F11802B6 +:100960001646AB42F7D104E02978A14205D0A5F1A3 +:100970000C021568002DF7D1002509F034FA28463D +:1009800070BD00BF1C6100200026002080B50D480E +:1009900001420CD0012008F0D7FF012808D10B48F4 +:1009A00000210C4AC1610A49CA613C31016080BD25 +:1009B00009F07AFA3221B1FBF0F10348BDE880403A +:1009C00008F008B8040000207C71002000100440EA +:1009D000D01E00209537000070B50E46044608F082 +:1009E0000BFF0546A068B8B120682169A26901FB28 +:1009F0000201304609F0AEFAD4E901012269013959 +:100A0000A160511CB1FBF0F202FB101020612846DE +:100A100009F0ADF9A06870BD284609F0A8F94FF0BB +:100A2000FF3070BD10B50F4C32200021012223464B +:100A300008F0A2FB0C4B33200021012208F09CFBA4 +:100A40000A4821780078012906D14FF40061642218 +:100A5000BDE8104009F0BEB94FF40061BDE8104098 +:100A6000FEF7C0BFCD270020CC2700209C7A0020B5 +:100A700070B504460F48056802F0FEFC0E481021D0 +:100A80000078FDF743FBD62685B16868007858B139 +:100A9000042006F053FC38B10146448006706868B3 +:100AA00040680078FEF760FB2D68EDE7BDE8704018 +:100AB000FCF7C8BA247A00209D7A0020B0B504461D +:100AC00008F01AFAA51C0146284606F046FF50B168 +:100AD0000C48416911B12046884780B9E07ABDE8E9 +:100AE000B040F7F77DB906480078012807D8A27A08 +:100AF000E37A20882946BDE8B040F1F7D3BBB0BD0A +:100B00002426002054750020F8B5114E0D460446E9 +:100B100031680F4659B108460979A14204D1C1880C +:100B2000A94204BF0020F8BD01680746F2E708208B +:100B300009F0EAF950B1014600200860CD800C713F +:100B40003268002A08BF37463960F8BD1020F8BD6A +:100B50007427002070B5114D134604460E0A13F891 +:100B6000012B6868102A01704FF020314670C0F8E0 +:100B70000710C0F80B10C0F80F1028BF10228270A9 +:100B800040F8031F194608F061FC2846214614224C +:100B90001323BDE87040FEF79FBC00BF88260020ED +:100BA000B0B586B0054600206C4618212872204654 +:100BB00009F0B4F8204629460B2208F047FC04F15E +:100BC0000B0005F10B01082208F040FCA88AADF8E3 +:100BD0001400A87D8DF8160003488068D0F81C1218 +:100BE0002046884706B0B0BD0C01002010B5427BFE +:100BF000042A01D1027C0AB1002010BD40690028FE +:100C0000FAD002789207F7D14A68437B547DA34219 +:100C1000F2D1098843898B42EED1D18883888B42F7 +:100C2000EAD191788078884204D0107800F00C00E6 +:100C30000428E1D1012010BDF8B504464FF6FF7637 +:100C4000002541F221070F2D14D82078082106F045 +:100C500062FE802159B10142324618BFD2431204CC +:100C600087EA460258BF720049081646F2E7013586 +:100C70000134E8E7B0B2102106F04DFE4FF6FF71E7 +:100C80004840F8BD70B5114E04460822A51CF06816 +:100C90002946023007F024FB18B156F80C0F044621 +:100CA0000CE00C36366886B156F80C0F294608223F +:100CB000023007F015FB0028F4D03068C0683060BF +:100CC0002046BDE8704009F01DB970BDAC2200207F +:100CD000E0B50023CDE9003361B10F4A0428137059 +:100CE00008D8DFE800F0030B09131100BDE88C40C1 +:100CF00000F072BA02208CBD012010706A460846CE +:100D00001146FEF791FB8CBD012010706A46084623 +:100D10001146F1F773FD8CBDA42700201FB54FF6D7 +:100D2000FE7188421AD00E4900234A1C0D490978E9 +:100D300099420BD014781CB9B2F80140844202D019 +:100D40000E320133F4E7DAB2914207D1ADF80C006C +:100D500004208DF80000684603F072FD1FBD00BF3F +:100D600030790020DFBA02007FB5D0E90154204677 +:100D700006F0D1F92068416821F002014160416923 +:100D800021F00F0141610321016202A808F0AEFACF +:100D9000074995F8F93095F8FA202068D5E93965C2 +:100DA00009680C680399CDE90065A0477FBD00BFC5 +:100DB000C401001010B508F01FFD0C49097869B98D +:100DC0000B49097851B90B49097839B90A490978A9 +:100DD00021B90A49097811F0FD0F04D0002408F068 +:100DE000C6FF204610BD0124F9E700BFB07A0020FD +:100DF000B37A0020B87A0020AB7A0020B17A0020C4 +:100E0000F0B589B00F4C2068A8B1002001ADC6B282 +:100E10001F2E0DD8AF1903F0FBF80021202905D0B3 +:100E200020FA01F2083107F8012BF7E7301DEEE751 +:100E3000216801A888470448018B41F0040101831F +:100E400009B0F0BD5827002000720020FEB50F4DFC +:100E50000446E8688069007800B1FEBD0D4F0C4E75 +:100E6000396830684B6C01AA022198479DF804004C +:100E70000028F2D00CB901F0CBF9E86801218069B3 +:100E8000017039683068C9698847FEBD0C010020CF +:100E9000E4260020347A002010B508F0ADFC0446AA +:100EA0000C48007820B12046BDE8104008F05FBF34 +:100EB000094890F900000028F5D4084890F900008E +:100EC0000028F0D4064800780028ECD105F022FB79 +:100ED000E9E700BFB17A0020B07A0020B87A00209C +:100EE000AB7A00201CB50E21F8288DF8071017D119 +:100EF0000E4CA068D0F8D41091F884208AB191F8F3 +:100F0000421014228DF80720142905D0D0F830247F +:100F10000DF10701E0209047A068D0F8CC0380478E +:100F20001CBD91F842100E29F0D1F5E70C0100200C +:100F300070B5054608F060FC0F4E0446B068D0F866 +:100F4000F824D0F8D8102846904730B9B068D0F8C7 +:100F5000DC10D0F8F82428469047B068D0F8E810A4 +:100F60000968A94202D1D0F8D80480472046BDE8DC +:100F7000704008F0FCBE00BF0C010020F8B515461B +:100F80000F46064602F03AFCC8B11C21044608F0A0 +:100F9000C5FE002D284608BF012067812680A07469 +:100FA000074890F86C00012812BF0720284606F079 +:100FB000B7FF607403480078013040082074F8BD22 +:100FC000A86D0020CDBA0200F8B50F484FF6FE75A7 +:100FD0000E4C6F1C06784EB12CB120461C2108F037 +:100FE0009DFE678125801C34013EF4E708490020FE +:100FF0000022032A08BFF8BD01EB820301F822009A +:1010000001325D80F5E700BFD1BA02003056002002 +:101010004C79002010B50D49002481F826400C4978 +:10102000087004F037F808F03DFD0A480460FFF747 +:10103000CBFF09480078012803D806F0E1FCF7F758 +:101040006FFEF0F707FE0548046010BDA86D002094 +:101050009C7A0020E879002024260020D826002051 +:10106000F8B5114F0C463968C9B115468A69B2B155 +:101070008A6AB2B100042146461C3046904780B1CE +:10108000A8421CBF0C20F8BD386821468269304652 +:10109000904701460020012908BF0A20F8BD002022 +:1010A000F8BD0920F8BD00BF68270020B0B508F0E2 +:1010B000A3FB044608F02DFE0028FBD0032003F01C +:1010C000C3FC0B48002180F83811204608F04FFE81 +:1010D0000848816802200D4688470446102004F025 +:1010E0002BFD24B103202946BDE8B0400847B0BD20 +:1010F000D81B002018B80200F8B592E87800771CD9 +:1011000008BF0526002780F828700127C0E90431B0 +:1011100000F11801B740F0C11169C0E90B1108498D +:10112000CA6D02EBC602426301F1400240600060FA +:1011300000F10801104607F0BDFA0020F8BD00BF1D +:10114000A01F00202DE9F0414768044608F054FB39 +:1011500005464FF00008D7F8C8609EB17169706805 +:10116000C6F81480C7F8C81006F004FB284608F03B +:10117000FEFDD7F8BC2020463146904708F03CFBE6 +:101180000546E8E72846BDE8F04108F0F0BD70B537 +:101190000446417880786268267F1044A6F10D02EB +:1011A000B2FA82F2520941EA4211227C41EAC201BA +:1011B00000F8011BA16908F010FE05460D2E05D1AF +:1011C00004F10801284608F04AFE0835207C012871 +:1011D00004BFA07D287070BDB0B588B000200DF1AF +:1011E0000B018DF80B00CDE90000684603AAF8F763 +:1011F000AFFA04469DF80B0078B103AD14212846E0 +:1012000008F08CFDFF20214614222B468DF81C008F +:10121000042005F019FA002000E0012008B0B0BD5C +:10122000BFB504460F48002590F82600082801D0D5 +:10123000042814D14FF6FD70ADF8040007F05CFEF1 +:101240000290207861788DF80D508DF80F508DF850 +:101250000C108DF80E0001A8F7F74AFC0546284649 +:1012600004B0B0BDA86D0020FEB58E6A0446777844 +:1012700007F01F00012812D101ADB11C284608F06B +:10128000EEFD0A482946393006F067FB50B11F2FA2 +:1012900005D8B6F80B10B07A02F0ECFA03E0D320D0 +:1012A000F9F7ABF900242046FEBD00BFA86D002071 +:1012B00010B50446C00704D00C4A2120742108F060 +:1012C00003FC200748BFFEF7BBFA09480078012855 +:1012D00003D8A00748BFFCF71FF9600705D50548EC +:1012E000006810B1BDE81040004710BDA86D002097 +:1012F00024260020082400200E485022016841F4D2 +:10130000087121F0020101600B48032140F8041C20 +:1013100041F2300181600121016082604FF4CA62B4 +:10132000016082604FF48652016082600160034870 +:1013300001607047000004605860044000410440B0 +:1013400070B504464668082005F0F8FF90B10546E0 +:10135000012028703078033008F0D6FD686048B16D +:101360003178CA1C314608F0F5FD06482946007858 +:10137000FDF7FAFE606806F0BFFE2046BDE870404B +:1013800008F0C0BDD4260020B0B504460C480D4678 +:10139000007808B904F082FE0A480078A0429CBF99 +:1013A0000020B0BD094A0849002D04EB440018BFD5 +:1013B000294652F8200082692046BDE8B040104717 +:1013C000AB2700208DB9020098BA020028B70200AE +:1013D0001FB50E494FF6FF730A780D49A2B131F8D7 +:1013E000044B013A9C42F9D08442F7D14FF0FF32CE +:1013F000ADF80400074841F8042C02218DF80C10C8 +:10140000818C01A808F0A4FD1FBD00BFD2BA020064 +:1014100098780020A86D002070B1B0B5044608F09F +:10142000F4FB0D49886054F8042D002A05D40B49BB +:101430008A6801328A600BE0704722F00042074B55 +:1014400022605D682A445A600A68A24288BF0C6024 +:10145000BDE8B04008F0C7BCD02500200026002021 +:10146000B0B508F0C9F9044608F053FC0C48002157 +:1014700080F83811032003F0E7FA204608F077FCE3 +:101480000848816802200D4688470446102004F071 +:1014900053FB24B103202946BDE8B0400847B0BD46 +:1014A000D81B002018B8020070B500250C46457105 +:1014B0000D4806780D48AE420CD0415D227B91422A +:1014C00001D00135F7E72046F8F7D6FBE8B28642AF +:1014D00018BF70BD0620002160732068407BBDE806 +:1014E000704000F045BA00BFCEBA02005876002026 +:1014F00010B5044648060FD40E480078012815D8C8 +:10150000204608F0CEFB88B1094900790138C98A24 +:10151000022838BF0C4609E0FF20214605F034FCC4 +:1015200003490028CC8A08BF6FF00104A0B210BDA7 +:10153000A86D0020242600201CB58DF8070002208D +:1015400004F02AFB08B1012415E007F06BFD01242B +:1015500088B10DF10701E12000F016FE0DF1060142 +:1015600052208DF8064000F00FFE044800248470DD +:10157000002008F003F820461CBD00BFCC26002048 +:101580002DE9FC479846AAB115460E4607460024A9 +:101590004FF0FF3A0DF1040931192A1B38464B462A +:1015A000CDF800A0E7F746FB01990C4428B96D1A65 +:1015B000F2D102E000246FF00900B8F1000F18BF6B +:1015C000C8F80040BDE8FC87B0B50F4C0F4D48F29D +:1015D00001012078A84720784FF40041A8472078DF +:1015E00048F22101A847207848F22201A847207834 +:1015F0002021A84720782121A847207822212A46A7 +:10160000BDE8B040104700BF9D7A0020090B0200E2 +:101610002DE9F041DFF83CC04FF0000E4FF000081C +:10162000864513D01F4615466DB131F81E603C88C3 +:10163000A64202BF5FFA88F62CF8164008F10108AE +:101640000237013DF0E70EF1010EE9E75FFA88F09D +:10165000BDE8F0812C730020E0B58DF807000D483F +:10166000017821B100210170EFF7C4FA10E00A48B7 +:10167000816819B10DF10700884709E000200121B8 +:1016800002228DF805000548007801AB03F006F84A +:1016900000208CBDBB270020547500209D7A0020BF +:1016A0007FB504468069068808F0DCF8864209D1D7 +:1016B00007F008FA05460B48012106F01BFF681EDB +:1016C000002301E080230020227C617CC0B2CDE9B0 +:1016D000006048F205000392024A0292A21CFDF744 +:1016E0004BFE7FBD2C73002070B504460F481E468C +:1016F0001546406808F071FB052D057001D846704D +:1017000006E0FE2D06D3DDE90421FF2D427003D053 +:10171000062303E0052301E0082341800348214616 +:101720003822BDE87040FDF7D7BE00BF88260020F4 +:101730002DE9F041DFF83C80DDE9067C1C46D8F855 +:101740000460250605D017F8015B013C06F8015B33 +:10175000F7E7BCF1000F18BF4FF0010C4FEA8C14F3 +:1017600088F80240FDF7B8FE002188F80210BDE8B5 +:10177000F08100BF88260020B0B5142008F0C4FB1B +:10178000D0B11421044608F0C9FA4C201421224695 +:1017900008F094F90546092804D14C20142122466A +:1017A00008F092F9204608F0ADFB044A71200821A8 +:1017B00008F084F92843B0BD0A20B0BDB826002047 +:1017C000B0B5104CA068D0F8E0038047A068D0F80E +:1017D00018028047A068D0F8F00280470025A06872 +:1017E000072D07D0D0F8A00050F8250000B18047A1 +:1017F0000135F4E7D0F858038047EB2008F038F8BB +:101800000120B0BD0C01002070B590B06E460C46B2 +:1018100005464021304608F081FA40F20110ADF84B +:101820000A40ADF80050ADF8110001208DF80E000F +:1018300002208DF808008DF80C0004488068D0F86C +:1018400088123046884710B070BD00BF0C010020E0 +:10185000E0B502464878800709D00D480368ABB16F +:1018600008461146002202B0BDE8804018470948EA +:1018700001916946ADF8002004F0A6F930B10621C7 +:10188000417300680021407B00F072F88CBD00BFFE +:10189000FC260020ED0B02001CB50F4C032184F840 +:1018A0002A1001218DF8071008B100220AE06079A2 +:1018B000022801D8013003E0206902F0F9FC002081 +:1018C0000122607105480DF10701012300910321F8 +:1018D000007801F096FB1CBDAC220020A37A00200A +:1018E000BCB504460D480E4D417044B10D484FF44F +:1018F00080510078FEF776F805F1330000E0281DEE +:10190000002184F001020123017006480DF1070156 +:1019100000910121007801F074FBBCBD0C7A00201D +:10192000AC220020A37A002010B5044620B90E484E +:101930008068D0F84C05804707F05EFF0B490A78B5 +:10194000A2430A7008F013FAFFF7A6FA0648C16826 +:10195000C968097801B110BD80680021D0F8582409 +:101960000020BDE8104010470C010020B17A002093 +:10197000B0B5044614200D4605F0E0FC58B1014610 +:101980000C2008700B488C7000244D708C7300780C +:10199000FDF7EAFB0CE0204607F0DCF838B1062141 +:1019A0004173007B03F0D0FE2046F8F7E7FC1024DB +:1019B0002046B0BD9C7A00202DE9F04104460F4836 +:1019C0004FF00008062600270568A5B128680188A1 +:1019D000A1420ED16989A5F80880490703D5287B63 +:1019E00003F0B2FE2868407BF0216E73FFF7C0FF62 +:1019F0000137281DE8E7F8B2BDE8F081587A0020E9 +:101A0000B0B507F0F9FE05460D48046894B10D48DD +:101A100054F80C1C007821B14FF40051FCF776FB10 +:101A200003E04FF40051FBF73FFE0548214600223A +:101A300003F02AFE284608F09AF92046B0BD00BF00 +:101A4000482700209C7A0020B0B5017D05460C3067 +:101A5000022904D003291AD108F080F902E0008895 +:101A600008F01FF9044690B16878F12818BFE12802 +:101A700006D1A079012806D1208808F04FFA02E0AB +:101A800008B90020A071A07908B10138A071B0BDDB +:101A900010B50D4C207838B90C480D494FF4D6726A +:101AA00008F058FA012020700A48022180F88F10AF +:101AB000012180F88510002180F84510042180F86C +:101AC0009D100321017010BD9B2700204C40002178 +:101AD00050A50200DB030021B0B52021EFF31184F3 +:101AE00081F3118801250B49CA6A0D604069030C16 +:101AF000B0F5802F38BF0423981848610648232189 +:101B000000680268002090470448056084F311884B +:101B1000B0BD00BF042009408401001080022443AE +:101B2000B0B5104C00252574E06810B904F00DFF25 +:101B3000FAE7E068216AB0FA80F0C0F11F0001EB1B +:101B4000C000E169884209D9E061A169026801F138 +:101B50001C0002F11C01A26105F042FA207C002861 +:101B6000E1D1B0BD3822002070B50D46044607F023 +:101B700043FED4E901128A4204D108F0F8F84FF08C +:101B8000FF3070BDE36822680133B3FBF1F606FB5A +:101B900011315554E160A168626901319142A1603F +:101BA00088BF0A46626108F0E2F8A06870BD10B50F +:101BB0008EB0E1B10C460168086AC0B1C97F01AAC4 +:101BC000EFF70CFB6188BDF8102000208A420FD18E +:101BD0009DF8061001290BD10B980178012906D137 +:101BE00021788078401AB0FA80F0400900E00020A7 +:101BF0000EB010BDF0B585B0074615460E460088FC +:101C0000DDE90E121C46F2F715FF05280FD080B94A +:101C1000DDE90C10DDE90A32CDE90032CDE9021030 +:101C2000384631462A462346E5F768FE02E00220A0 +:101C300000E0102005B0F0BDB0B50446202005F04E +:101C40007DFBC0B10546042010222870D4E90001B4 +:101C5000C5F80200A81D07F0F9FBE16805F11600C0 +:101C600007F0BBFC208A2946E88303480078BDE8DA +:101C7000B040FDF779BAB0BD9D7A002010B50F4A8B +:101C80008389526803EB430302EB83044A1E012A53 +:101C90000AD84288022962800BD1043006F00EFA7D +:101CA00038B90020207004E0221D011D104607F005 +:101CB00094FC2046BDE8104007F074BD402600208B +:101CC00010B50C48032290F84810012180F8481004 +:101CD00009480275094A137A1172006940B1084C2B +:101CE000204607F085FE2046BDE8104007F086BE7E +:101CF00010BD00BFA01F0020381F00203822002088 +:101D00004FD40100F8B50E480488204608F0FCF8CE +:101D1000A0B12146FF22054607F0AAFF0948002787 +:101D20000678B74207D2F9B2022022462B46FEF7C8 +:101D30007BF80137F5E7284608F0E4F80020F8BD05 +:101D40004EB20200DFBA0200F8B50D480D4D0E4F3D +:101D50000126046804608CB1B4FA84F0696880F0EC +:101D60001F0006FA00F251F8201094430029F2D027 +:101D700057F820205203EED58847ECE7F8BD00BFA6 +:101D8000E0200240E4B8020000100840F0B585B041 +:101D90000D4F04460B480D4D6E463246397880F89B +:101DA00072402846FDF7ECFF3A78304629468DF818 +:101DB0001240FDF7F0FC4520294600F0E5F905B09A +:101DC000F0BD00BFA86D0020B927002020790020B9 +:101DD0000F49C3070A68496D01D1002106E001F0EF +:101DE000040102F00103C91818BF0121830744BF91 +:101DF00002F0020341EA5301400744BF02F004002D +:101E000041EA90010220002918BF0120704700BF5D +:101E1000402108400F49C3070A68496D01D10121DB +:101E200006E001F0040102F00103C91818BF012106 +:101E3000830744BF02F0020301EA5301400744BF95 +:101E400002F0040001EA90010220002918BF0120DD +:101E5000704700BF4021084070B58AB00C4C4FF469 +:101E60008061DD224FF48066204607F001FF01AD5E +:101E7000284607F059FE042007492A460023CDE9E9 +:101E800005460490034805F0BFF80AB070BD00BFD6 +:101E90004C4C0020E86E0020CD93020070B507F096 +:101EA000ABFC04460B48017821B12046BDE87040E8 +:101EB00007F05DBF01210170074805780748002D34 +:101EC000F3D0064656F80C1B89688847013D30461A +:101ED000F5E700BFAC270020000000000000000074 +:101EE000B0B511F1800201D1002112E00C4A0023AB +:101EF00003EB830544577F2C09D00544D5F80150E6 +:101F00001540954203D08C4201DC0133F0E72BB140 +:101F1000591E01EB81010844D0F801201046B0BDE4 +:101F2000FFFF3F00F0B50F4C00234FF0580C8EB26E +:101F30000027B3F5307F0FD0E1180D8EB54208D1E0 +:101F400039B10D69854204D14AB191F83350154237 +:101F500003D158330137ECE700210846F0BD07FBF9 +:101F60000C41FAE77053002070B5044605680D482F +:101F7000C6680D480068006B8047811B080B05EBA5 +:101F80001132B5EB113F40F6C41188BF50088842AA +:101F9000206004D880084A2802D84FF49671216046 +:101FA00070BD00BFD01E00208C0100102DE9F04153 +:101FB00005460E480078A8429CBF0020BDE8F0818D +:101FC000164688460027BD4208D036F8174007F06D +:101FD00049FC844201D00137F5E7FDB2A5EB0800CA +:101FE000B0FA80F04009BDE8F08100BFD8BA020025 +:101FF00070B507F001FC04460B48017821B120467A +:10200000BDE8704007F0B3BE0121017007480578B4 +:102010000748002DF3D0064656F80C1B8968884700 +:10202000013D3046F5E700BFAD27002003BA0200AE +:10203000A8B9020010B586B00DF11700F9F762FBE0 +:10204000B0B19DF8172004467AB14FF6FC701F21FD +:102050002346ADF80C000F208DF814000020CDE9C8 +:102060000010044803A9F2F743F8204607F04AFF9E +:1020700006B010BD8826002010B50B4C48F21501A3 +:102080002070FEF741FD20783821FEF73DFD07481E +:102090000749084A20610848C4E902210221017267 +:1020A0004FF6FE71018010BDCC240020B534020033 +:1020B00039580200FD610200927900202DE9F041BB +:1020C000C189846948F21F00814208BF0134277822 +:1020D000F800013007F018FF804670B14546661CD5 +:1020E000002405F8017BBC4207D22846314607F0A0 +:1020F000B6FE013408350836F5E74046BDE8F08104 +:1021000010B502460E480024006860B123460479E9 +:1021100094420446F8D1C4888C420446F4D1016844 +:102120001BB1196008E0012010BD11B1044A116013 +:1021300002E0034900220A6007F0E4FE002010BD1F +:102140007427002010B5EEF753FE0C4C207840B9F0 +:1021500006F0D2FE0246AB20002103F0D9FE207823 +:1021600010B107F0BBF828B10548002101700548FF +:1021700001210170BDE8104004F098B82426002029 +:10218000A17A0020A07A0020B0B50C46054652285E +:1021900006D0E22D0BD10B48214607F060FE06E089 +:1021A000074821780078084304BF0120B0BD0648E5 +:1021B00021468068D0F830242846BDE8B04010475A +:1021C000BD270020B67900200C01002010B50423A3 +:1021D000082200F0010403EA901302EA503223447B +:1021E0001A44102303EA1050104401F0010240EA9F +:1021F0004210402202EA91021044802202EA512257 +:1022000010444FF4807202EA1141084380B210BDBD +:1022100010B50D4C2078FE2807D00C480068826B62 +:102220000B48006894F9001090476078FE2807D0AA +:1022300006480068826B0648006894F901109047D0 +:10224000FE206070207010BD24250020347A00200C +:10225000E426002010B5EB2002F07CFD0B480024A2 +:1022600004700B480078862802D1002002F01CF987 +:1022700007F0C2FA07490A6813681C7112680A60FD +:1022800007F075FDBDE8104006F0CEB9B37A002026 +:10229000B87A0020D87900200C480E4B8068DB68A3 +:1022A000D0F8D410D0F8EC00497B50F82100084950 +:1022B0000A680B60991A084A1278920091FBF2F1B1 +:1022C000B1FBF0F202FB1010704700BF0C010020C0 +:1022D000307A002010790020B47A0020B0B50F4C7D +:1022E000A168D1F8B8000278B2B1C569A5B1086C8F +:1022F0000268D06D28B102210023A847A168086CAC +:102300000268106E40B1D1F8B8100023D1F81CC09B +:102310000821BDE8B0406047B0BD00BF0C010020FF +:102320002DE9F04104460D484FF6FE780C4D08F1BA +:10233000010706787EB16889A04218BF002D02D13E +:102340001C35013EF6E728461C2107F0E7FC6F81AB +:10235000A5F80080F4E7BDE8F08100BFD1BA020023 +:1023600030560020B0B570B104460E48416851B1F6 +:1023700000220D462B4625B1A34202D01D681A4605 +:10238000F8E7A34200D0B0BDA14208BF021D2068FB +:102390001060204607F060FD2046BDE8B04007F021 +:1023A000B1BD00BF50260020012919D010B5C08949 +:1023B00001B280EAE130A0EBE13084B2204600F0C7 +:1023C00037F80848084AC16C51F82430934218BFC6 +:1023D00041F824200021006D40F82410BDE8104091 +:1023E000704700BF381F0020696F0200F8B50D4E1E +:1023F00004460D4F306E50F82100B84201D0002045 +:10240000F8BD0A480D461C300090204605F0D6F96C +:102410000028F4D0306E50F82500C01B18BF2046AD +:10242000F8BD00BF381F0020696F0200A01F002008 +:1024300010280FD310380E4A0123410900F01F0065 +:1024400002EB810103FA00F0D1F8F020C1F870012D +:10245000104070470F281CBF0020704704480168D7 +:10246000026822F00202026001F00200704700BF21 +:1024700010E000E010280FD310380E4A0123410964 +:1024800000F01F0002EB810103FA00F0D1F8F02008 +:10249000C1F8F000104070470F281CBF00207047A3 +:1024A00004480168026842F00202026001F0020082 +:1024B000704700BF10E000E000B1704780B52021F8 +:1024C000EFF3118081F311880A49CA6C22B180F3BD +:1024D0001188FCF7EBF804E0002281F8482080F333 +:1024E000118805490122087A0A72BDE8804001F08E +:1024F00093BA00BFA01F002038220020BCB50D4DAC +:10250000286840B96C46204607F06EF80120214645 +:10251000EDF7B8FC28600849097851B948B1074976 +:102520000978012903D1642101F096FBBCBD00F0BC +:102530002AFDBCBD287A0020A2270020A07A002016 +:102540001FB5044600790B2101EB4000C0B204F036 +:10255000F5FE38B122790DF1050122B1012A04D12D +:10256000053107E01FBD033104E00723032A08BF3C +:1025700009231944A2890A8004B0BDE8104005F07F +:10258000BBBD70B505460D200E4607F0BDFCC0B1C1 +:102590000680044615F8020BA070294615F8010CB8 +:1025A000E070201D07F05BFC287AC1210D22234634 +:1025B0002073452000F0E8F82046BDE8704007F0A1 +:1025C000A1BC70BD2DE9F84317460E46044606F03F +:1025D000CDFFB0B10546DDE90898082004F0AEFE55 +:1025E00078B10146C780067180F80390847080F846 +:1025F0000180FE20087068680078BDE8F843FCF7A9 +:10260000B3BDBDE8F883704710B50446007D98B9A6 +:102610002046EDF753FE206918B10A48816820462C +:102620008847217DE06821B107F06CFC0020E06064 +:1026300002E0FCF7E1F920752046BDE8104007F004 +:102640008ABA00BF5024002070B50C2007F05CFC53 +:10265000A8B10C4E04464FF0FF300025A06060602A +:1026600020603088854207D2A9B201200C2223467F +:10267000FDF7DAFB0135F4E7204607F043FC0020C4 +:1026800070BD00BF402600202DE9FC410D4D4FF0EC +:102690000008002600272888874228BFBDE8FC8163 +:1026A0006868B9B200220C2384190120009403F059 +:1026B000B5FF20B92078FF2808BF84F800800C36C9 +:1026C0000137E8E74026002070B5102007F01CFC19 +:1026D000B0B104464FF0FF300026E060A0606060BB +:1026E000206008480578AE4207D2F1B203201022DC +:1026F0002346FDF799FB0136F5E7204607F002FC7B +:10270000002070BDE3BA0200F0B585B04FF0FF3095 +:102710000027ADF810000390CDE90100084801AD95 +:10272000048808480678B74224BF05B0F0BDF9B266 +:10273000022022462B4603F087FF0137F3E700BF54 +:102740004EB20200DFBA020070B50E488068D0F8C1 +:10275000D810096819B9D0F8DC00006880B107F01A +:102760004BF8044607F080F9054601F049FE06469D +:10277000204607F0FCFA701C281A98BF012070BD93 +:10278000002070BD0C0100202DE9F0410746D01C4F +:10279000984614460D4604F0D1FD80B1064685707A +:1027A0004770047024B1F01C4146224607F0D2FB6A +:1027B000044831460078BDE8F041FCF7D5BCBDE8DF +:1027C000F08100BF927A002010B50949094C002021 +:1027D000A04709490120A04708490620A047084909 +:1027E0000720A047074908202246BDE810401047AF +:1027F0009DE90100D58F0200755D0200073B0200D4 +:10280000A9540200D954020080B5EFF723FA0B4A0D +:102810002120742107F058F902F09EFD0848007845 +:10282000012898BF02F0B0FD0648006800B180475B +:1028300002F042FABDE88040F7F760BCA86D0020C6 +:10284000242600200024002070B5D0B1056804467D +:10285000BDB12868A8B107F0D8F90646286807F086 +:1028600029FB10B1286807F07CFA286806F0ACFF55 +:102870002846FEF7D1FD00253046256007F0B3FA63 +:1028800000E00225284670BDF8B517460D460646FD +:1028900007F0BBF93168044639B14FF0FF3051F809 +:1028A0000C1C01300029FAD100E00020B84205D20A +:1028B0003046294604F08CF9012500E00025204629 +:1028C00007F091FA2846F8BD0B4A1278012A11D177 +:1028D0000A4A127882420DD9094A0029094B18BFC9 +:1028E0000A4600EB400103EB810053F82110CB684E +:1028F0001146184700207047AC2700200000000058 +:1029000040B70200000000000B4801688907FCD5B1 +:102910000A4801210A4AD0F83C0101284FF0010081 +:1029200008BF202008239061002010600548036044 +:1029300043601160704700BF58600C40D81B0020F6 +:1029400000400C4038500C4040F00201022918BFF2 +:1029500070477CB50A4D0B4C80B270220423296865 +:102960004E68009020460021B04728680021702260 +:102970007023D0F80CC0204602B0BDE8704060471C +:10298000A401001000A00C4070B50E4A0C490023B1 +:102990004FF6FE74032512780531934228BF70BDAF +:1029A0004E78F60709D131F8036C864205D10E78CE +:1029B000012E04BF21F8034C0D7008310133ECE700 +:1029C0004C500020D6BA02000C4A1278012A11D1CC +:1029D000094A127882420DD9094A0029094B18BFC9 +:1029E0000A4600EB400103EB810053F82110CB684D +:1029F000114618470020704703BA0200AD27002097 +:102A000054B60200A8B9020080B5014600780C282F +:102A100003D00D2814D1486801E04868C83078B167 +:102A2000027802F00302032A0AD1807800F0030042 +:102A3000032805D103480078FCF796FB012080BDF0 +:102A4000002080BDCC26002010B586B001AC11213D +:102A5000204607F063F981201121224607F02EF865 +:102A600070B901AB81200021112206F085FB38B935 +:102A70009DF8040020B10348018841F01001018055 +:102A800006B010BD3E7900207CB50C460D491D787E +:102A900000268DF8070049684A70120A0E70081D5A +:102AA0008A701A78CA7013F8012B194606F0CEFC0A +:102AB000281D214648F21102C3B20DF10700FCF7B0 +:102AC0000BFD7CBD88260020F0B587B001AD044623 +:102AD0001821284607F022F90027022F84BF07B0EB +:102AE000F0BDFEB2062018222B463146FDF79CF9B8 +:102AF000012C08BF002805D10620314618222B469C +:102B000003F0A2FD0137E8E7BCB50C460DF1060164 +:102B1000154603F087FE0146C82091B909490968A6 +:102B200079B1BDF806200020032804BFC820BCBD31 +:102B30000B88934202D006310130F5E7288000204F +:102B40002160BCBDEC260020BCB50D4D0028A96855 +:102B5000D1F8C81318BF01208847044600200DF1A2 +:102B600007018DF80700A868D0F830245620904758 +:102B7000A8680449D0F83024E22090472046BCBD24 +:102B80000C010020B679002010B502460D48002443 +:102B90000068A0B12346047994420446F8D1C48861 +:102BA0008C420446F4D10749002B18BF194602682D +:102BB0000A6007F0A7F901F043FB012010BD0020D7 +:102BC00010BD00BFF82600202DE9F84307460C4849 +:102BD0000C4C90468946002605786DB12078B842A5 +:102BE00007D12046494605F0A1FC10B1464504D264 +:102BF00001360E34013DF0E700242046BDE8F8839D +:102C0000DFBA020030790020B0B505680446B5F897 +:102C10005610A86807F050F9A86807F04FF9204649 +:102C200005F08DFDB5F8580040B14FF6FF718842B0 +:102C300004D00138A5F85800000400D0B0BD2046EB +:102C4000BDE8B04004F001BE70B50D4E0D4C3068CB +:102C50008168204688470546606840F03000606023 +:102C600028060AD030680021426820469047306824 +:102C70008168204688470028F9D1E8B270BD00BFBE +:102C8000D80100100040034080B50E490C48096887 +:102C90000068096C884710F1140F45F6A611A8BF0B +:102CA0006FF0130010F15A0FD8BF6FF05900C0EB4E +:102CB00000200844462180B2B0FBF1F0C0B280BDD4 +:102CC000E4260020347A00200B480C4AD0E9021098 +:102CD000137B0068D1F8E01003F0F00302330078B2 +:102CE0000968137308440649097848430549096887 +:102CF00001EB8000906070470C010020C07700203D +:102D0000B47A0020307A0020F8B50E4E0C46054605 +:102D10000027ACB1606841196160B068D0F8E82064 +:102D20001268944204D1B1F1FF3F01DC676005E015 +:102D3000B1F1FF3F02DCD0F84C0580472468E8E79A +:102D4000F8BD00BF0C01002080B50C4800780628B3 +:102D50000ED10B480178013101700A48018802291F +:102D600006D3013901800620BDE88040E4F7AEB803 +:102D7000FDF7B6FABDE88040F7F780BABB7A0020CD +:102D8000B6270020C679002010B58EB00168044631 +:102D9000086AA0B1C97F01AAEEF720FA0948BDF878 +:102DA0000E10C08A81420AD020689DF82120038835 +:102DB000BDF8100000934FF6FE73FDF75FF80EB0FC +:102DC00010BD00BFA86D00204FF6FE73984203D0DF +:102DD00002F06003602B01D101207047930608D4F4 +:102DE000084B5206DB8A09D4834209D38B42F3D9BC +:102DF00006E00448C08A8842EED901E08342EBD263 +:102E000000207047A86D002070B52020EFF31184DA +:102E100080F3118809480068006B8047084AD2E9AE +:102E20001556084AD2E9102384F3118806F00EF9EA +:102E3000281AB04288BF002070BD00BF8C0100106E +:102E400008200020886E002070B50E480121047A09 +:102E5000017285692020EFF3118680F311882846DE +:102E600000F0BCFD032085F82000284601F08CFB13 +:102E700086F311886D602D602046BDE8704000F03B +:102E8000CBBD00BF3822002010B5F7F7F7FA05F0E8 +:102E900087F802F091FA0B4C94F83C0010B901202D +:102EA00084F83C00F6F754F804F086F804F0C0F813 +:102EB000FAF784FE02F022F906F0FAFD01202070F4 +:102EC00010BD00BFA01F002080B50E480078062866 +:102ED00007D0052809D002280BD1BDE8804006F0B4 +:102EE000ACBFBDE8804006F0A5BF07F057F820B1A1 +:102EF00080BDBDE8804005F0B1BE1C20BDE880402B +:102F0000EFF70ABCBB7A0020B0B505460C46084670 +:102F1000D121FDF715FD08B14570B0BD022004F0C8 +:102F20000DFA40B101464570D12008702046BDE839 +:102F3000B040FCF719B9034810210078BDE8B04053 +:102F4000FBF7E4B89D7A002070B50568686810B199 +:102F50000C46642901D9002070BD296801FB04F6E4 +:102F60006421B6FBF1F106F044FF0146B0FA80F0AF +:102F7000400909B985F853400021632E88BF01211B +:102F800085F8511070BDB0B50468002184F8511067 +:102F900094F85210012906D194F85400002106F04B +:102FA000B5F9012006E094F853500021FFF7CCFF5B +:102FB00084F8535094F8501002291CBF002184F863 +:102FC0005010B0BDB0B5044600786178084406F0F2 +:102FD0009BFF054698B12178284606F09FFE4FF6E4 +:102FE000FE70688006F03EFCA88020786178284456 +:102FF0002975286104F064FD6875A0782876284654 +:10300000B0BD2DE9F843CBB1089CBCB18046981CFB +:103010001F4616468946C0B204F090F970B10546C5 +:10302000023021463A4606F011FA6E7085F800909B +:1030300040462946BDE8F843FCF796B8BDE8F8835A +:10304000B0B505460E2004F079F9A0B1044607207A +:10305000207028886080A8780228207104D16968CF +:10306000601D082206F0F2F9034821460078BDE809 +:10307000B040FCF779B8B0BD9D7A0020B0B50446E9 +:10308000102004F05BF9A0B1054605206168082214 +:103090002870208868802089A881281D06F0D6F92C +:1030A000A07A2946A87303480078BDE8B040FCF731 +:1030B0005BB8B0BD9D7A0020B0B50578ADB10446CF +:1030C00003F082FC01280FD10948A189406801EB77 +:1030D000410210F82210294205D100EB8200294359 +:1030E000017006F05FFB0120B0BD0020B0BD00BF45 +:1030F000402600201FB582B100230193D2E901349C +:1031000012788DF80420094A0293039402F11C03FB +:1031100001AA04F065FF04B010BD044A02F11C03CB +:10312000002204B0BDE8104004F05ABFA01F0020E8 +:10313000FF2817D0B0B5044605F0A4FB0A4D286857 +:1031400050F82410204606F00FFE686850F824104E +:1031500011B1002140F82410A868002140F8241083 +:10316000BDE8B040704700BFE4B80200BBB12DE934 +:10317000F04786B0DFF82CE0EC4666469EE8B007E4 +:1031800086E8B007D3E900451B7A8DF8083063461E +:1031900001940495FFF72AF906B0BDE8F0870023F3 +:1031A000FFF724B9E8B702000A49097809B10120FC +:1031B000704709490978FF2904BF00207047084B70 +:1031C000064A0433022808BF131D1868C84000F0DF +:1031D000010070477C270020B57A0020207700206E +:1031E000F8730020BCB50C4605460DF107016A4690 +:1031F000204602F0C1FA10B14FF6FE740EE09DF8C1 +:10320000070000992870696030B1421E01EB400050 +:1032100030F8024C6A7001E0002068702046BCBDA6 +:10322000B0B50446007A38B1254635F80C0FE96888 +:10323000F1F74EFF01280AD0E07968B134F80A0F9F +:10324000D4F80A10F1F744FF0128254604D1288854 +:10325000FBF76CF90120B0BD0020B0BDC0F34022E7 +:103260008A7100F003028A70C0F380224A77C0F3AB +:1032700000224A71C0F3403281F83120C0F300329D +:103280000A72C0F3C022CA71C2B2800B9309C2F3A2 +:1032900083020B71CA70704710B50120FFF754FC10 +:1032A0000446FBF7BDFC09480078012898BF04F0EC +:1032B000B7FB05F0ABFA02F09FFC05F099F9044862 +:1032C0000078FDF7A7FE204610BD00BF2426002091 +:1032D0009C7A0020B0B50B4890F8664084B10A484B +:1032E000058806F097FC28404FF47A7114FB010220 +:1032F00006484FF480710078BDE8B04006F067BD25 +:10330000B0BD00BFA86D00208EB902009C7A0020DD +:10331000F0B50B4C0B4D50B149B10B4E0327376044 +:10332000B768BF07FCD101262E602060A1602AB1DA +:1033300023B10120C5F800042262A362F0BD00BFE2 +:1033400004400240000048428847024070B50D4BDF +:103350001B3800FB00F193E87000DB6801FB00F212 +:1033600083FB0223C6FB0123C5FB002310091909B7 +:1033700040EA0370001941EBE471000C40EA01409F +:1033800070BD00BFA425002070B50C4D4FF48773AD +:103390006E88EA88921B02F5877292FBF3F404FBB5 +:1033A000132294B28C4228BF0C4605492246314470 +:1033B00006F0D0FDA0196880204670BD7024002062 +:1033C0009263002070B50D46064606F01EFC0446CA +:1033D0003046294604F044FD60B1006806F068FDFF +:1033E000054606F061FD4FF47A71B1FBF0F0B5FBD4 +:1033F000F0F500E00025204606F0F5FC284670BDFB +:103400007CB50C4D0C4C00214FF4C072072328688A +:103410004668022000902046B047286800214FF4FB +:10342000C0720723D0F80CC0204602B0BDE870403F +:10343000604700BFA401001000A00C4080B50B49FC +:1034400002220A720A4A10704FF6FE70088005F0D8 +:1034500053FD04F081F8074804F0B4F8FFF7F4FADC +:1034600005F0DCFABDE88040FEF7AEB888790020B0 +:103470009D7A0020942500200B48007802280BD26A +:103480000A48807B800708D509484FF4807140F6D0 +:10349000C412007806F09EBCF6D105484FF4807146 +:1034A0000078FAF733BE00BF24260020A86D002064 +:1034B0009D7A0020B0B50546242003F03FFF98B167 +:1034C00004463220A9681B2220702878A070686802 +:1034D000606004F1080005F0B9FF04482146007857 +:1034E000BDE8B040FBF740BEB0BD00BFCC2400201B +:1034F00070B5FEF7E3FDC0B10446451C00262078F8 +:1035000086420DD2284606F029FC30B100790138F8 +:10351000012802D82846FBF71FFD08350136EEE7E3 +:103520002046BDE8704006F0EDBC70BD80B50C498A +:103530000978022908BF012800D080BD0948C07859 +:103540000028FAD1FDF740FD06F06AFA18B1BDE88F +:103550008040F6F713BE0020BDE88040FEF79CB91E +:1035600024260020D0260020F8B50D4F06461C4624 +:103570001546786806F073FC681EB0FA80F04009C2 +:103580008001012C08BF8030796834220923087239 +:103590003846314601B0BDE8F040FBF79DBF00BFA3 +:1035A000882600201FB50D4C030A0029626853705D +:1035B000107018BF0121152202238801A0704FF658 +:1035C000FD70ADF804000F208DF80C0001A9204615 +:1035D000FBF782FF0021A17004B010BD88260020F7 +:1035E000B0B5002101600C490A6892B100254FF680 +:1035F000FE74AB1D182B0CD0555BA5421D46F8D1AF +:103600001A44063A02600868C118002001F8020C4A +:10361000B0BDC820B0BD00BFEC260020B0B586B05C +:10362000044600206D4618212075284606F076FBDA +:10363000284621460A2205F009FF6089ADF80A00F4 +:1036400004488068D0F8F81228468847002006B061 +:10365000B0BD00BF0C0100202DE9F0411D4616460B +:103660008846044605F082FF90B10746062003F025 +:1036700065FE68B10146868084704570FD20087043 +:10368000786881F803800078BDE8F041FBF76CBDF5 +:10369000BDE8F08170B586B001AC1421FF22204650 +:1036A00006F0E6FA094800260578AE420AD2F1B2E1 +:1036B000082014222346FCF7B7FB01360A28F4D170 +:1036C0000A2000E0002006B070BD00BFC9BA0200A9 +:1036D0002DE9F04105460B480B4E8846002704783B +:1036E00064B13078A84206D13046414604F01EFF4E +:1036F000002818BF01370E36013CF1E7B8B2BDE82B +:10370000F08100BFDFBA020030790020B0B50D4D66 +:103710000446E8688069007801280AD104F0B0FB0B +:1037200040B1E86880690178012902D10021017067 +:1037300024B1B0BDBDE8B040F2F7E6BEBDE8B04090 +:1037400003F0D0BF0C01002010B504460B48006800 +:10375000A04204D80A488068D0F84C058047B4F1EC +:10376000FF3F04DC06488068D0F84C05804706F02F +:1037700043F8BDE8104006F0FABA00BF3C7A0020DA +:103780000C010020B0B504460A480068A04204D8E5 +:1037900009488068D0F84C05804706F02DF80546AA +:1037A000064804602046F7F757F92846BDE8B040C0 +:1037B00006F0DDBA3C7A00200C010020407A00209F +:1037C0000B480178832902D0017886290BD10A4958 +:1037D0000978032902D10020F1F746BE8521017046 +:1037E0001D20EEF799BF03488068D0F84C050047CC +:1037F000B87A00200C010020BB7A0020B0B54FF64B +:10380000FE704FF6FF7101F0DDFB00B1B0BD08485E +:10381000084D04780020002CF8D0A97C09B1697CFF +:1038200019B92888FFF7B0F828461C35013CF2E7A3 +:10383000D1BA020030560020B0B505460C480C46FF +:103840000078012809D80948808CA04205D1284673 +:1038500006F027FA08B10830B0BD2846214601F02D +:10386000B1FB002818BF1030B0BD00BFA86D00200C +:1038700024260020B0B50B4D0C4695F872108142FD +:1038800028BFB0BDFEF782FA074864210480E879BA +:1038900000FB01F205484FF400710078BDE8B0402C +:1038A00006F098BAA86D00209A6900209C7A002042 +:1038B00070B50D4E0C46B18CFFF7BEFF88B10546C2 +:1038C000807804F02DFB697859B150B1884298BFD7 +:1038D0000846727B012A18BF0846A0429CBF0120FF +:1038E00070BD002070BD00BFA86D002070B50446FB +:1038F0000C4801210160D4E91001D4E91623851890 +:1039000041EB0306280C002240EA064100F00CF8C7 +:10391000D4E91623D4E9060150346CC4BDE87040E4 +:10392000084700BF0420094010B50C4606F0C1F955 +:103930000B498A69A31A0632B3F1004F09D8131B49 +:10394000B3F1FF3F2346C8BF1346A24298BF2346A8 +:103950001A460A6000B110BDBDE8104006F0ADB9CE +:103960001820094010B5044608480949094A0A4B7D +:10397000C4E90210002004F11001C4E90032A06182 +:10398000064804F097FE204610BD00BF899E020045 +:103990008F9E0200839E02007D9E0200A8260020CA +:1039A00010B588B001AC0A491C22204606F0D2FAB4 +:1039B0000020094A002123468DF810000A200390B8 +:1039C00002208DF804000348EBF7C6FB08B010BDD9 +:1039D0000CB70200886E0020F99A0200B0B50D49BC +:1039E000CA68036844682360436804686360C46C01 +:1039F00083692568A54204BF9A43CA608A698242E6 +:103A000004BF0022CA6101220A74022180F820103A +:103A1000B0BD00BF3822002000B1704710B50B4C7C +:103A20002020EFF3118180F31188207C28B1084811 +:103A300090F8480008B9FEF773F80020207240F2B1 +:103A4000000CEFF311808CF3118810BD3822002098 +:103A5000A01F0020F8B50E460B4900281C464D68F3 +:103A6000314618BF0546002A2F6808BF082228469D +:103A7000B847074630B9054A204600212B46009634 +:103A800001F08AFB3846F8BDA01F002077AD020088 +:103A9000BCB5054600200C460DF1070300210122AC +:103AA0008DF80700032005F067FB00B1BCBD9DF851 +:103AB0000700FF2D0DF1070214BFA0432043012191 +:103AC0008DF80700032005F0FFFFBCBD10B542785C +:103AD00001788378C478002A18BF41F00201002BD6 +:103AE00018BF41F00401002C18BF41F00801027911 +:103AF000002A18BF41F040014079002818BF41F06A +:103B00008001C8B210BDBFB504460DF10205082200 +:103B100034F8020BADF80200A81C214605F096FC13 +:103B2000207AC9210D222B468DF80C00B4F809002B +:103B3000ADF80D004520FEF727FE002004B0B0BD13 +:103B4000B0B50B49402200240A6080220A60C1F807 +:103B5000FC42056895F8260020B1064806F0E6F913 +:103B600085F826400220BDE8B04000F06DBF00BFE0 +:103B70000444024098700020B0B550B1044600786B +:103B8000102200F07F010520FDF76AFA0020207066 +:103B9000B0BD064800250488A542F9D2A9B2052087 +:103BA0001022FDF75DFA0135F6E700BFBEBA02004C +:103BB000B0B50D4611461A46F6F7D2FE90B1294629 +:103BC000044604F0B3FC68B12046294600F081FDAC +:103BD00030B96588204605F06BFA2846FDF79EF857 +:103BE0000020B0BDB420B0BD70B50C4B0A4A1C78A3 +:103BF0000432002374B112F8245B00268D4298BF72 +:103C0000012685424FF0000528BF0125013C3540C3 +:103C10002B44EFE7D8B270BD20450020E3BA020084 +:103C200010F1240FD8BF6FF023001B28A8BF1B2062 +:103C300003210F222430A1EB101122EA000022FA06 +:103C400001F14FF6FF7222FA00F040EA014001490B +:103C50000860704718A00C4010B5046894F8522012 +:103C6000012A05D194F85400012105F04FFB02E030 +:103C7000FFF76AF950B194F8500002281CBF0120E8 +:103C800084F85000012084F8510010BD002010BDC0 +:103C9000B0B50B4D04462878A04201D10020B0BD3C +:103CA00058B908488068D0F83803804728B12046C2 +:103CB000F4F700FE08B12C70F0E7E220B0BD00BFC1 +:103CC000AF7A00200C01002070B5B0B10546007A33 +:103CD00000F0FE00022810D12846F4F733FEFF283A +:103CE0000BD02A7A00210646002401F0CFF82A7A68 +:103CF0003046002101F0E4F800E0E824204670BDE1 +:103D000086B0044609486D46047009480068EFF320 +:103D1000118180F311882846152105F0FFFF054A1F +:103D200028461521234605F06DF8FEE7962700206A +:103D3000B0BA020000B802004FF6F871884206D30C +:103D40000830BF22C1B222FA01F1C90701D1002017 +:103D50007047054900B251F820100448027802204B +:103D6000114208BF0120704774B60200947A002007 +:103D7000B0B50A490A4A0B4B0C684D68AC42FCD1FD +:103D8000844208BFB0BD155C145DAC424FF0FF35F6 +:103D900038BF01252C441C5D0C60EDE700600C4031 +:103DA0003CBA020040BA020010B50A4C002120685B +:103DB000426801209047206801680120884708B1C7 +:103DC00000F0D2F804480068E068006880470349C2 +:103DD000C86010BDE001001030200940F42400202C +:103DE00010B50A490A4C0860D1F8980040F0030069 +:103DF000C1F898002068816920208847054800683C +:103E00002068806BBDE81040004700BF8C2108404F +:103E1000B80100102C200940F0B50B4A0B4D0023CF +:103E20004FF4877654888B4224BF0846F0BDA7B272 +:103E300001340133EF5DA4B200F8017BB4FBF6F767 +:103E400007FB16445480EEE7C82600208462002059 +:103E5000F8B5094F0C46054605F0D7FE064607485B +:103E60000749084AC7E90254F8F7F2FC3046BDE8B2 +:103E7000F84005F0B8BF00BF702400209263002016 +:103E8000A0640020893E0200B0B50C460B4D002115 +:103E9000E880698010B1E96801B188473CB1002031 +:103EA0002870AA68A9881AB111B920469047A98834 +:103EB00011B12869FAF79AF8B0BD00BF702400204C +:103EC00070B50B4E05460B4C30688168204688471C +:103ED00000F00300002128603068426820469047C7 +:103EE00030688168204688470028F9D170BD00BF3E +:103EF000D8010010004003402DE9FC410B4C07465F +:103F0000984615460E46606808B1804758B10421AE +:103F1000E0682A464346009106EB473105F064F914 +:103F2000C00FBDE8FC810B20BDE8FC81A023002070 +:103F300010B5FEF75DF8012003F0D8FA044605F04D +:103F40005BFC08490A683AB105F011FF4CB1204604 +:103F5000BDE8104005F022BD0C60BDE8104005F042 +:103F600006BF10BD0C24002010B50A480B4C018878 +:103F7000C907094907D14FF001222260008808686B +:103F8000BDE810400047086880474FF0807020600F +:103F900010BD00BF00A00C408000001004A40C4025 +:103FA0007CB50B4D0B4C00214FF040521C23286870 +:103FB0004668032000902046B047286800214FF44F +:103FC000007209234568012000902046A8477CBD67 +:103FD000A401001000A00C40B0B50C4D297A09B125 +:103FE0000720B0BDA98CFFF727FC0028F8D00446B5 +:103FF00080786D7B03F094FF012D03D161788842B6 +:1040000098BF0846002808BF0720B0BDA86D002053 +:10401000B0B505F0F1FB0A4991E83C000F1D1CC743 +:104020000B69084C1C4485EA950383EA43030C6141 +:10403000534083EA02150D6005F099FE6019B0BD8A +:1040400034780020C5870500F8B50C46054605F014 +:10405000D3FB2B1D6E690ECB8F1AA74238BF3C468F +:1040600022442344B24288BF16466E61B3FBF1F688 +:1040700006FB1131C5E9022105F079FE2046F8BDA5 +:1040800070B50668054605F0B7FB0446707A70B94E +:1040900001207072284602F085F8686805F096FCE9 +:1040A0002846EDF773FC2846002103F021F820464E +:1040B000BDE8704005F05BBEF8B5D0E9006505F0DD +:1040C0009BFB0446307870B1287905F0FFF9012890 +:1040D00006D1286800274760301D05F0F1FE3770D3 +:1040E0002879F2F763F82046BDE8F84005F03FBEB6 +:1040F000B0B58AB0F1F7DCFB04AD822000211822B4 +:1041000000242B4605F038F858B9681C694610227F +:10411000CDE90244CDE9004404F0E2F8B0FA80F0C1 +:10412000440920460AB0B0BDB0B585690C460846C2 +:10413000294605F094FE287A2072B5F809006081BE +:1041400004F10C00E97A0329217506D105F10C016F +:1041500005F085FE287DA075B0BDA9890180B0BDA0 +:104160001CB581690B880A4909888B4204D1094A28 +:10417000194600F01FFD1CBD017C427C48F203047F +:10418000CDE90041811C1046802202F085FD1CBD56 +:1041900088790020007A0020BFB514464FF6FD72E2 +:1041A0000A4DADF804200F228DF80C206A6822F821 +:1041B000020B104605F053FE686813220B2384722D +:1041C00001A92846FBF788F904B0B0BD8826002075 +:1041D000BCB54FF0FF316C460028CDE9001118BF87 +:1041E0000446AB200021224601F092FE054D2146F7 +:1041F000284605F034FE712008212A4605F064FCAB +:10420000BCBD00BFB826002010B50C4A1278A2B180 +:104210006E28034628BF6E23323B322838BF002366 +:1042200008783C2443431BB2012A08BF93FBF4F0F7 +:1042300080B2FF2828BFFF20087010BDAE270020E5 +:10424000F0B585B06C460B4F0026A51C3F687FB1CA +:104250003879B91D12228DF80000284605F0F6F8CD +:10426000F1B208201422234602F0EEF90136EDE700 +:1042700005B0F0BDF8260020F8B50C4D0446002628 +:104280002846002E08BF2E46006858B10179A14289 +:1042900006D101683160076805F034FE3846F4E75E +:1042A0000646EEE7BDE8F840FFF7CABFF826002053 +:1042B00010B50C4901F1100322461C687CB104F1D1 +:1042C00018038442F8D151F8103F834218BF02F11D +:1042D000180182690A6005F015FE002010BD022059 +:1042E00010BD00BFAC22002010B50C4A12688AB184 +:1042F000FF2911D013788B420ED854781C448C427D +:104300000AD9C91AC01A5268C9B2C0B2515C105C4D +:10431000884201D1002010BD012010BD647A002028 +:104320000949084889680088D1F8D420D084074812 +:1043300000220270D1F8D4000549C08C4886054996 +:10434000C8817047AE6500200C010020B27A0020C1 +:10435000007200200079002009480A49C0680A7BE1 +:10436000406802F0F002033200780A73064A1278BD +:104370005043064A1278504380008860704700BF5F +:104380000C010020C0770020B47A0020BA7A002007 +:1043900010B50B4C207830B101280AD0022803D187 +:1043A00002F0EBF905E010BD06488068D0F84C0536 +:1043B000804700202070BDE8104004F0A1BE00BF7F +:1043C000B02700200C010020B0B5044605F014FA17 +:1043D000054602200021F6F77FFF084906482246DD +:1043E000096800688B694FF0FF3198472846BDE89F +:1043F000B04005F0BCBC00BFE4260020347A0020A9 +:10440000F8B505F0F9F9044608480068C06B804724 +:1044100005460748067807480768204605F0A7FCC8 +:10442000E81BB100B0FBF1F0F8BD00BF347A00200A +:10443000B47A0020307A0020BFB505F0E6FB01AD6C +:104440000446284605F091FB002001212A460290EF +:104450008DF804000448FEF74DFE0449086020462C +:1044600005F0C1FCBFBD00BFD95A020034270020AF +:104470000C4800224FF470038168D1F8D8100A600C +:104480008168D1F8DC100A608168D1F8E0100B6017 +:104490008168D1F8E4100B608068D0F8E800026011 +:1044A000704700BF0C01002080B50B4881890131A5 +:1044B000818105F0A1F909490A78862A08D1872265 +:1044C0000A7005F054FCE920BDE88040EEF724B9FD +:1044D000BDE8804005F04BBC5C780020B87A002035 +:1044E00080B50948012101700848406818B10848A2 +:1044F000818901318181F02000F02CFC0548007891 +:10450000BDE88040E5F7DABE2D260020C077002008 +:10451000AC780020BB7A0020F0B585B00B4C246845 +:1045200084B1256A75B1DDE90C6CDDE90A47000448 +:10453000049100210130CDE90047CDE9026C00244F +:10454000A84700B10A24204605B0F0BD6827002026 +:10455000F0B589B005AD0C4601461022102728465B +:1045600005F044F901AE304605F016F9054831462C +:10457000CDE90347CDE90154006805F0ECFB09B033 +:10458000F0BD00BFFC79002010B590F8480088B15C +:104590002020EFF3118480F3118807484169013925 +:1045A000416105D1054884F31188016A00208847DC +:1045B00084F3118810BD00BF38220020381F00206E +:1045C00080B568B101460068D1E9012348B11146C0 +:1045D0001A4604F02BFB0648BDE8804004F026BBD9 +:1045E00080BD04480021BDE8804004F01FBB00BF2F +:1045F000C4BA0200EFB6020070B50948094C844203 +:104600000BD0094D094EB54207D0F5E8020110F86C +:10461000012B54F822209047F5E705F09DFC70BD72 +:10462000A0BE020094BE0200E8BE020038BF020035 +:1046300083B00290002001918DF8030082420BD0DC +:104640000299095C019B1B5C013059409DF80330C5 +:1046500019438DF80310F1E79DF80300B0FA80F0DC +:10466000400903B07047B2B110B586B09368062B0D +:1046700003D35C1C01D000200BE0002404930194C0 +:10468000D2E90034D268CDE90234059201AA04F0DF +:104690009DFA06B010BD002204F098BA2DE9F04151 +:1046A000804610461E4617460D4602F047FE70B182 +:1046B00004462FB126B1204631463A4604F0C6FEE4 +:1046C000257040462146BDE8F041FAF74DBDBDE8F2 +:1046D000F08170B5B0B14279A2B1831D14461D4678 +:1046E00062B11E888E4204D1013C2606447102D17B +:1046F00008E025F8026B0233013AF1E720061CBFFF +:10470000012070BD002070BD10B501784078642490 +:10471000012808BF632429B1052004F0E7FE201A10 +:10472000A0F10D040448007B20B104F0DFFE201A44 +:10473000A0F10E04E0B210BDA86D00200549064AA4 +:104740000A6006490870064806490160064807499C +:10475000016070470027002049FB00004826002028 +:10476000FC2600209975010004270020CD9202004C +:10477000B0B505460C2002F0E1FD80B104460620EC +:1047800069680822207028886080201D04F05EFE81 +:10479000034821460078BDE8B040FAF7E5BCB0BD5B +:1047A0009D7A0020B0B50648084B0649084C064AD9 +:1047B000084DC0E90152C0E903414361B0BD00BFEB +:1047C00050240020A19E02000DE70100B5980000D2 +:1047D0006161000039CE0100B0B50648084B0649BA +:1047E000084C064A084DC0E90152C0E90341436143 +:1047F000B0BD00BF50240020A19E02000DE70100C3 +:10480000B59800006161000081800200B0B50648E3 +:10481000084B0649084C064A084DC0E90152C0E958 +:1048200003414361B0BD00BF50240020A19E02009F +:104830000DE70100B598000061610000816D010085 +:10484000B0B5054602F0C0F8044601280ED108486C +:10485000A9892B78406801EB410110F821209A4387 +:1048600000F8212000EB810004F09CFF2046B0BD41 +:1048700040260020F8B509480A4D00270678084868 +:104880000488BE4208BFF8BDB9B2022022462B46BA +:1048900001F0DAFE0E350137F3E700BFDFBA0200A0 +:1048A0004EB2020030790020E0B50A4800780128B5 +:1048B0000FD80120F7F718FC0749ADF80600C882A9 +:1048C0000DF106015320FDF75FFCBDF80600FCF773 +:1048D000CFF88CBD24260020A86D002010B504461A +:1048E0000948807B000707D40648006820B10748C4 +:1048F00008210078F9F70AFC2046BDE81040F2F7DD +:104900004ABE00BF44240020A86D0020997A0020F0 +:10491000F8B50A4E054605F078F9044608482A46D7 +:10492000002375800027D0E9011004F0E2FE00B1F9 +:104930007780204605F057FA7088F8BD7026002071 +:1049400048230020B0B50C4600210546224603F05E +:10495000B9FC0748007800B1B0BD7C2C054904BF04 +:104960000448C57005EB450001EB80008475B0BDBF +:10497000A0230020B8720020F8B50B4F0446002693 +:104980006D463978F0B288420AD200212A460423C3 +:1049900004F024FD9DF80000A04202D00136F0E7AB +:1049A000FF26F0B2F8BD00BF9B7A0020F8B505F0F5 +:1049B0002CF90A4E044675685DB145B128682F6927 +:1049C00004F002FF284605F09DFA3D46F5E7002079 +:1049D00070602046BDE8F84005F005BA7826002052 +:1049E00070B50A4C034620780E280CD8084E00EB10 +:1049F000400506F8350006EBC5056A610022E9604E +:104A00002A74C5E90132411C217070BD00260020C6 +:104A10001C61002008490A4B421808499A4209685B +:104A200008D801F44001B1F5000F03D10549096828 +:104A3000496C0847704700BF5C8F82FFB44F00503D +:104A4000B71E0500F001001070B50B4D04462E187E +:104A500004F0D2FE96F84311013986F84311090695 +:104A600005D10121AA68A14022EA0101A96005F04F +:104A70007EF9002070BD00BFD81B0020B0B50546F0 +:104A800004F0BAFE044608480178A9430170007892 +:104A9000000704D405480821283005F04BFA2046C9 +:104AA000BDE8B04005F063B9D01E002070200020A2 +:104AB000F8B515460E46074604F09EFE0446084823 +:104AC0004068B84201D0032504E03046294601F091 +:104AD00011FB0546204605F04AF92846F8BD00BFFF +:104AE000D01E0020B0B50A4A931C0A4A147800224E +:104AF000944209D01D88854203D113F8025C8D428F +:104B000003D00A330132F3E72246D0B2B0BD00BF72 +:104B1000B25C0020D5BA02002DE9F04106460A48F1 +:104B200015460C4600278046BC4209D0D8F8002024 +:104B3000E95D30689269904708B10137F4E73C4677 +:104B40002046BDE8F08100BFD001001080B50948C3 +:104B50000078022802D24CF2101107E008D101209F +:104B6000F7F7C2F80449002808BF01310348018063 +:104B700080BD00BF242600202182FFFF007A002094 +:104B80001CB58269094913785278098943EA0222DF +:104B900011400AD0064A047C1388427CCDE90014F7 +:104BA000811C1046002200F0A7FE1CBD3E790020AB +:104BB0008879002010B50B4B0C0A5B6859700021F6 +:104BC0009C7019701178D970517800F11102197127 +:104BD000811C104648F203020523BDE81040FAF795 +:104BE0007BBC00BF882600201FB5044600208DF83E +:104BF000000068462146043005F031F904F06EFBF0 +:104C000000B11FBD6846F6F743FD0128F9D00DF14C +:104C10000E020020214601F033FB1FBD10B50A49EA +:104C20000122087A0A7209494C6944B122684A6132 +:104C3000FEF7F2FE2046BDE8104001F079BBBDE86A +:104C40001040FEF7E9BE00BF38220020A01F002060 +:104C500080B50B4A0146106878B143681B788B42D7 +:104C600005D0024600680028F7D1022080BD016807 +:104C7000116005F047F9002080BD012080BD00BF14 +:104C8000247A002010B5A1F1FE020A4BB2FA82F29A +:104C900054091B6853B1DA888242FAD11A79E407C1 +:104CA00005D1521AB2FA82F25409F2E7FE221046F6 +:104CB00010BD00BFF826002070B586B001AC1421ED +:104CC000FF22204604F0D4FF074800260578AE42B4 +:104CD00024BF06B070BDF1B208201422234601F0B3 +:104CE000B3FC0136F3E700BFC9BA02001FB50146A5 +:104CF00004208DF80000087A022806D10888ADF853 +:104D000002006846F4F7B0F906E06C46201D04F096 +:104D100064FC2046F6F7BCFCBDF80C0004B010BDE6 +:104D20000849094A096852F82130034442F8213001 +:104D300006498A6801328A6005490A681044086099 +:104D4000EFF702BB187A002060730020B82400201F +:104D5000207A00207CB504461630C0B2092810D84D +:104D6000084EB068D0F8282401AD20462946904767 +:104D70000198294601300190B068D0F830242046CF +:104D800090477CBD0C01002010B50B4CE068816998 +:104D90000978022907D1C168097821B1A068D0F843 +:104DA0004C058047E068C168097819B980690178C5 +:104DB0000229FCD010BD00BF0C01002009480021D1 +:104DC0000122C1814175084942820978017507496C +:104DD0008968D1F8D41091F8242091F83110017429 +:104DE00042747047B8750020B97A00200C01002089 +:104DF00010B50A48FE210A4C4170A068D0F8E800BE +:104E0000006848B1E0680121C068017003F0D4FB7C +:104E1000E0680021C068017010BD00BF242500209B +:104E20000C01002080B50A480021017001F072FBDE +:104E3000F7F7E2FA0748C168C968097801B180BD8F +:104E400080680021D0F858240020BDE88040104739 +:104E5000B17A00200C01002007480849084AC0E93F +:104E600004210849084AC0E9082140F20551C183DC +:104E7000F721C173704700BF007200201079002035 +:104E8000D879002020770020F873002070B50B4CF3 +:104E9000094B022A254608BF1D4601262D6806FA41 +:104EA00000F009B1284301E025EA0000022A14BFFE +:104EB0002060186070BD00BF20770020F8730020CC +:104EC00070B50B4C094B251D022A08BF1D1D01267C +:104ED0002D6806FA00F0002925EA000618BF45EA09 +:104EE0000006022A08BF1C46666070BD20770020BD +:104EF000F873002010B50B4CE068C068007828B942 +:104F0000A0680021D0F858240120904704F074FCD8 +:104F100004F02DFFA068D0F8B800806EBDE8104006 +:104F2000004700BF0C010020B0B50D460446FFF756 +:104F300067FAA84205D308488068D0F8E000006806 +:104F40000544054865608068D0F8DC10D0F8EC2492 +:104F50002046BDE8B04010470C01002010B50B4CB6 +:104F6000A268D2F8E030D2F8EC2052F82110196093 +:104F7000A268D2F8E4201160FEF7E6FBA068D0F842 +:104F8000E0000068BDE8104002F0BEBB0C0100204C +:104F900010B58EB00C4691B1014601AA2046ECF73F +:104FA0001DF99DF80A0050B19DF805209DF82030AC +:104FB0000020214603F0F6F908B1A42000E000200B +:104FC0000EB010BDB0B5024609484FF6FF74037825 +:104FD000084801E01C30013B43B105889542F9D1F6 +:104FE00045898D4218BFA142F4D1B0BD0020B0BDAB +:104FF000D1BA020030560020B0B50146094800235E +:105000004FF6FE74027808484AB10588A54203D0DD +:10501000DDB28D4204D001331C30013AF4E70020A8 +:10502000B0BD00BFD1BA020030560020F8B50D4621 +:105030000A4904460848097802304E1C013E09D04E +:10504000294600F11C0702F088FC00283846F5D0FC +:1050500027F81E4CF8BD00BF30560020D1BA020020 +:1050600080B5042000F098FD08490978884284BF83 +:10507000012080BDFF2000F08FFD0146044802782A +:105080000020914288BF012080BD00BFE0BA02002D +:10509000E1BA020080B540F2011000F091FF02F089 +:1050A000AFFD0748007808B1012807D1054800780E +:1050B000012803D1BDE88040FAF72AB880BD00BFBF +:1050C00024260020CA270020B0B50B4A0023156C07 +:1050D000946CC0E901452A7841B1BE2A06D1691C09 +:1050E000631C11F8014B013BBE2CFAD00360B2F1F6 +:1050F000BE0018BF0120B0BD381F00200B4890F83B +:10510000641001B17047012180F864102021EFF391 +:10511000118281F311884FF0FF31C162016C826C02 +:1051200021F0070111440839C1637047381F00207E +:10513000B0B504468260816100201D462075D3E928 +:10514000010120610648E161214603F0B3FA2878A5 +:1051500020B12046BDE8B04003F033BEB0BD00BF73 +:105160000820002070B50B4AD368C56C84696E684E +:1051700023430560466030606860D360012380F897 +:1051800020301374202081F31188EFF3118180F314 +:10519000118870BD38220020BFB50A4C1C34A042D3 +:1051A00008BFBFBD01AC0028089D18BF04460648D3 +:1051B00084E82C0050F8210003F038FD2046FFF76A +:1051C000FFF9FEE7A01F002064BA020070B50B4C87 +:1051D0000B460021CDB234F8356076B101318642FC +:1051E000F8D104EBC5004188994206D140681146C8 +:1051F0001A46BDE8704004F029B970BDFCA6020053 +:105200000A48083880F308880948016841F47001A9 +:10521000016000BF00BF04F0A1FE08B1FFF7ECF988 +:1052200003F01EFF002004F089FD00BF00400120B4 +:1052300088ED00E0B0B5A0B10546007A00F0FE00B0 +:1052400002280ED128461446F3F77CFBFF2808D02D +:10525000002C2A7A18BF01242146FFF731FE0020D6 +:10526000B0BDE820B0BD10B52021EFF3118481F36B +:105270001188017C02290CD10268816843681A6098 +:105280000022027442680068426008462146FFF727 +:1052900069FF84F3118810BD1CB5ADF806100949EB +:1052A0000C6864B10DF10601009111461A46012304 +:1052B000A0470021002808BF6FF04D0100E0B62193 +:1052C000C8B21CBDF023002070B54E8B0C460546BD +:1052D00004F0C8FA864203D02846FAF72BFC30B116 +:1052E00004482146C2682846BDE8704010470120A6 +:1052F00070BD00BF50240020B0B50C46054603F039 +:10530000FBFD0146284602F028FB20B10548C08A73 +:1053100020800120B0BD28462146BDE8B04000F005 +:1053200012BD00BFA86D002010B5F8F727F9054899 +:105330000549064A064B074CC0E90143C0E9032171 +:1053400010BD00BF2C2400209DD30000FD7401007F +:1053500001610100B13B02007FB54FF0FF30094E03 +:1053600000250390CDE9010001AC3088854228BFBB +:105370007FBDA9B201200C22234601F065F9013559 +:10538000F3E700BF402600207FB54FF0FF30002636 +:105390006C46CDE90200CDE9000006480578AE4232 +:1053A00028BF7FBDF1B203201022234601F04CF943 +:1053B0000136F4E7E3BA020080B5084890F82810F7 +:1053C00001B180BD012180F8281004F071FB044870 +:1053D0000021FEF7C7FA0349486080BD381F00204E +:1053E00094760020A01F002080B50A49142004F004 +:1053F000BBFC1420002103F089FF012004F0C0FC55 +:105400001420012103F082FF4FF40C70BDE88040AE +:1054100004F0B6BC01640020BFB5044653B10020BF +:105420000190D3E901051B7803958DF804300290B3 +:1054300001AB00E0034B2046FFF77AFE204604B0A4 +:10544000B0BD00BFCCB90200FF2808BF7047B0B59F +:105450000D46044604F0D0F90649C5F3024311F89D +:10546000242002F0F8021A4401F82420BDE8B040DC +:1054700004F07DBC0210084010B501460848002326 +:10548000027808484AB10478FF2C03D0DCB28C4281 +:1054900004D001330E30013AF4E7002010BD00BF04 +:1054A000DFBA02003079002080B503460848007852 +:1054B00058B908481978007801B908B929B120B954 +:1054C0004520CB210122FDF75FF9002080BD00BF00 +:1054D000A527002004250020BFB50446082234F883 +:1054E000020BADF8040001AD2146A81C03F0AEFF8D +:1054F0002089CA210C222B46ADF80E004520FDF76D +:1055000043F9002004B0B0BDB0B50D46044604F028 +:1055100025FC80B101790139C9B203290BD8012DCD +:1055200018BF012902D8008804F0F8FC2046BDE825 +:10553000B040F9F711BDB0BDBCB5044605200D461D +:105540008DF8050001A801F0CBFA58B10169220AD3 +:10555000CA7041F203320D718C700A804480F9F7F1 +:105560004BFABCBD0120BCBD10B504F04EFB044697 +:1055700007480021202200230180064988680C3159 +:1055800002F0A7F92046BDE8104004F02CBC00BF93 +:10559000702600204823002010B5044601F098FE34 +:1055A000A0420BDDA0B2FAF79FF9054801218171F5 +:1055B00004480068BDE81040F9F748B8FEE700BFAE +:1055C00044250020507A0020F8B50A4F06460D46C3 +:1055D0004FF0FF311446386804F030FB304629465E +:1055E0002246F4F70BFE0446386804F09FFC204680 +:1055F000F8BD00BFDC250020F8B50A4F06460D4671 +:105600004FF0FF311446386804F018FB3046294645 +:105610002246EDF771FC0446386804F087FC20460A +:10562000F8BD00BF0C24002070B5094A1378322B56 +:1056300004BF012070BD074E046803EBC30540683A +:10564000013313707219745150600020117270BDD3 +:105650009E270020F05A002010B586B06C46162117 +:10566000A01C04F05BFB02208DF808000548418B6C +:10567000808CADF80A002046ADF80010FDF7CEFF93 +:1056800006B010BDA86D002070B514460D46064644 +:1056900004F0BBFA3168A94218BFA4F10C0655F812 +:1056A0000C1C3160FF2105F8021C002145F80C1C80 +:1056B000BDE8704004F097BBB0B50446012000FA85 +:1056C00004F504F099F807498A682A438A6021445E +:1056D00091F84321013281F8432104F048FB002076 +:1056E000B0BD00BFD81B00200A484068826800F1A6 +:1056F0003801134652680AB18A42FAD1597B090728 +:1057000006D1408F40F60901884204BF012070474E +:1057100000207047D01E002010B550B90020F6F7C9 +:10572000E3FC04464FF6FE70844206D1054800783B +:1057300018B10020F6F7D8FC0446EFF71BF9204615 +:1057400010BD00BFE4BA020010B50A4B0749084A71 +:105750001B780439013A43B112F8014F013B04317F +:105760008442F8D100200860107010BD306D002018 +:1057700058760020CEBA0200B0B514460D46F7F7B1 +:10578000F9FB07490978884224BF0420B0BD0549C8 +:1057900001EBC00041782970406820600020B0BD56 +:1057A000D7BA0200503D002007480068C00608D460 +:1057B00006480749006808400649884204BF01209E +:1057C00070470020704700BFB04F0050501300508A +:1057D00000C4FF3F00C0071CE0B5B0F90E1000295F +:1057E00001D4027B02B18CBD89B21329FBD0037CAA +:1057F000427C41F40041CDE90013811C1046842213 +:10580000002301F049FA8CBD09498A78920703D533 +:10581000084A1278824200D170470C2088700888AC +:1058200040F0020020F0050008800C2002F012BDBC +:105830003E790020E8270020B0B5094CE17809B195 +:10584000C17801B1B0BD40780028FBD105480025E2 +:10585000A0F870500120F5F7F3FDE570B0BD00BF72 +:10586000CC240020A86D0020B0B585690C46042129 +:10587000284600F083FF206028790528207102D88F +:1058800068796071B0BDFE2805D36979FF28A171E0 +:1058900004BFE8882081B0BD80B508490870084978 +:1058A00009780843000602D1062002F079FA05487B +:1058B00020210078BDE88040F8F728BCBF7A00209E +:1058C000D02600209D7A00201FB50A4BADF80400B9 +:1058D0005C68A170010A20700220E27001228DF83C +:1058E0000C006170184601A90423F9F7F5FD04B016 +:1058F00010BD00BF88260020BCB50A4C8DF80700FB +:105900000DF1070063681A70069A150A5A70102282 +:105910009D70A27048F215020323F9F7DDFD002106 +:10592000A170BCBD8826002010B500220A60094A7B +:1059300012686AB16FF017039C1D09D013441B8BCA +:1059400083422346F8D1101912300860002010BDA0 +:10595000C82010BDEC260020B0B588B004AD0446C8 +:1059600069461022284603F03BFF06482946006896 +:1059700004F0E6FA05992046102203F067FD08B00E +:10598000B0BD00BFF479002070B50546142016465E +:105990000C4604F0B9FA58B1064901230661846047 +:1059A00083734FF499730A688381C0E90025086006 +:1059B00070BD00BF247A00200749087007490978A4 +:1059C00031B9074991F82F1011B1064902220A7026 +:1059D00048F20201FBF798B8A37A002024260020A1 +:1059E000AC220020BC27002070B50A4E084C0025D0 +:1059F000042130782570F9F7F5FF30780421F7F7A6 +:105A000053FE84F82B500020BDE87040E4F72EB818 +:105A1000AC220020A37A00207CB50A4E0446062062 +:105A20008DF807002046318903F0C3FB0DF1070014 +:105A30000121FAF727F931890546204603F0C2FB18 +:105A400028467CBD0C24002080B50A4842F204415F +:105A50004088884206D042F2034188420CBF0020B1 +:105A6000E92003E0012000F081FD1B20BDE880401B +:105A7000ECF752BE4878002010B50A4A12687AB195 +:105A8000137883420CD854781C44844208D9C01A35 +:105A9000526891F90040C0B210568442C8BF0870E5 +:105AA00010BD00BF647A002078B110B50169074CC1 +:105AB000206029B906488068D0F84C0580472068E6 +:105AC000406804490860BDE810407047607A0020D3 +:105AD0000C010020347A002080B503F08DFE0849C7 +:105AE0000A7842F002020A7004F041F905480021E8 +:105AF0008068D0F894000078BDE88040F8F706BBD5 +:105B0000907A00200C01002008480021017008480C +:105B100001700848C168C968097801B17047806898 +:105B20000021D0F858240020104700BFB87A002088 +:105B30002D2600200C010020B0B504460948056858 +:105B400055B1A868204205D0D5E90332204600218E +:105B5000984718B92D68F3E70020B0BD4FF0FF302B +:105B6000B0BD00BFD81B002010B50446094800682E +:105B700020B130F8041BA142F9D110BD082004F077 +:105B8000C3F90028F9D0034904800A68086042601C +:105B900010BD00BF4C27002010B5A0F1FF02094B3B +:105BA0000021B2FA82F252091B6843B15C7B0433D4 +:105BB000241AB4FA84F4640914432144F4E7C8B203 +:105BC00010BD00BF587A0020F8B580B105460948DD +:105BD0000C4600260168374651B10E46084621465C +:105BE000A84700210128F6D0301D3E46F2E70027E5 +:105BF0003846F8BD587A0020F8B5094D094E2C6892 +:105C00005CB1D4E90007006AB0472068B04760691A +:105C1000B0472046B0473C46F2E700202860F8BD78 +:105C2000587A0020059F020010B50A4A00F11C01B5 +:105C3000007C0023927883420AD2140608D011F81F +:105C4000334004F08D04812C08BF013A0133F2E7A0 +:105C5000D0B210BD5026002010B50A4A00F11C0138 +:105C6000007C0023527883420AD2140608D011F82F +:105C7000334004F00D04012C08BF013A0133F2E770 +:105C8000D0B210BD502600207FB51346D0E90A24BB +:105C9000BE251AB104F8015B013AFAE7D0E90A54CB +:105CA000D0E90D26C06BCDE900160290291F2046D1 +:105CB000F7F7B6FF04B070BD10B50A4B2022EFF322 +:105CC000118182F311889A6B002A04DC5C6B44F822 +:105CD0002200501C9863002081F31188012AB8BF6C +:105CE000012010BDA01F002070B50A4D04462020E1 +:105CF000EFF3118180F31188A86B461E701C0128F8 +:105D0000B8BF70BD686B50F8261020468847013E2A +:105D1000F4E700BFA01F00207FB56D46ADF802007C +:105D200000260C4628468DF80060F3F79DF9291DE2 +:105D300007BF66602660204604F091F8204602F016 +:105D4000BDF904B070BDBFB50C46014600206D46DC +:105D50008DF80000281D03F040FC2846F5F798FC5C +:105D6000BDF802004FF6FE712080401A18BF0120D6 +:105D700004B0B0BDBFB5044600880DF1050508228A +:105D80006168ADF80500A81C03F060FB217A0B22C6 +:105D90002B4601704520C821FCF7F6FC002004B01A +:105DA000B0BD10B504460E2004F0AEF878B1A16B7A +:105DB000D4F83E200160426094F84210017294F8D9 +:105DC0004A1001736188418194F84910417310BDF4 +:105DD000B0B50C460546F9F72FFE291A04F57A727C +:105DE000C4EB9100012898BF01200023B2EB910F72 +:105DF00028BF1846B1F1404F28BF1846B0BDB0B516 +:105E00000C46054603F0F8FCD5E901122B69A242C5 +:105E100038BF1446121BAA601A19B2FBF1F303FB38 +:105E20001121296103F0A3FF2046B0BDF8B50C464F +:105E3000054603F0E1FCEA6895E8C2000132B2FBD6 +:105E4000F6F303FB16252944216003F090FF701B35 +:105E5000F11B814238BF0846F8BDF0B54FF0000C89 +:105E6000844504BF0020F0BD1D4616464EB131F8F2 +:105E70001C7035F8024B013EA74204BF0120F0BD63 +:105E8000F4E70CF1010CEBE770B514460E4605463D +:105E900003F0E8FC03F0E6FC0B2E0CBFA84270BD3B +:105EA0002046002101F011F9204600211E22BDE804 +:105EB0007040E8F74BBD2DE9F0414FF6FE780C46F7 +:105EC000054608F1010728462146FFF77BF838B15F +:105ED0001C21064603F022FF7781A6F80080F2E736 +:105EE000BDE8F08140B10246074800210170074833 +:105EF0000221007803F06EBF0348012101700348BE +:105F000002210078F9F76EBD2C240020997A002038 +:105F100080B5AB2807D0A1281CBFB52080BD108854 +:105F20000549088004E003481146006803F097FF24 +:105F3000002080BDEC5800209670002010B504466B +:105F4000062001F0FBF960B10146082008702088A6 +:105F50004880A078087103480078BDE81040F9F740 +:105F600003B910BD9D7A0020B0B50848084C0578EB +:105F700005EB45004100204603F0D0FE4FF6FE70D1 +:105F80001DB124F8060B013DFAE7B0BDA1270020A2 +:105F9000B45F002038B1024607484161074801213B +:105FA000007803F017BF0448002141610348012134 +:105FB0000078F9F717BD00BF2C240020997A002043 +:105FC000B0B5094D288060B100EB4000800084B27C +:105FD000204603F099FF686028B1214603F09EFE39 +:105FE000B0BD00206860B0BD40260020094983791B +:105FF000CA7A2BB15AB98078B0FA80F0400970475C +:106000002AB1C98A4089401A18BF01207047002070 +:10601000704700BFA86D0020B0B50546084800785D +:10602000012888BFB0BD28460C46F1F7E5FB4FF6C6 +:10603000FD7029460D222346BDE8B040F5F701BFAB +:1060400024260020084800F11801084802780020A2 +:10605000824205D00B78FE2B03D00C310130F7E7DC +:106060001046C0B2704700BFB87200209B7A002073 +:106070001CB56FF0D24401948DF806100421ADF8E0 +:10608000042001AA01EB8301042389B2FDF734FF48 +:10609000014908701CBD00BFA0230020B0B507480F +:1060A000074D04782CB155F80C0B00698047013C72 +:1060B000F8E7044801210170B0BD00BF8DB90200AE +:1060C00028B70200AB27002006480122017A02729D +:1060D00005480160054890F8481080F848200448B9 +:1060E0000160704738220020F0790020A01F0020B6 +:1060F000EC79002010B50C460849097E02290AD126 +:1061000001F02EFD04B12060C1B20220012908BFB8 +:106110006FF07E0000E00120C0B210BDD01E002054 +:1061200010B50848084900224FF6FE730024007895 +:10613000844228BF10BD8A718A804B8021F8083BB9 +:106140000134F5E7D6BA02004C50002010B50748DC +:10615000002403210460064801600220FEF774FC5D +:106160000720F0F723F80348447010BDA8025042FE +:106170001080024018230020F8B50C46D0E9001624 +:10618000002701F14C053068013C47F100018269AC +:10619000D20606D429B10068C1B22846FBF7E4FC58 +:1061A000F1E7F8BDD0E900100A6C5AB191F844103B +:1061B000090707D501684FF480624A648A6B42F48C +:1061C00080628A630068816B41F04001816370479F +:1061D000FEB5074609981C4615460E46FFF714FB08 +:1061E000054831463A4683780898CDE9004028466C +:1061F000EDF7E0F9FEBD00BF3E79002010B5044682 +:10620000062001F09BF858B1014631200870206843 +:10621000C1F8020003480078BDE81040F8F7A4BFB9 +:1062200010BD00BFCC240020F8B5094F06461C461F +:106230001546786803F0D1FD447005703846314644 +:106240003022062301B0BDE8F040F9F745B900BFA0 +:10625000882600204FF6FE73984218BF002901D10E +:10626000012070479A42FBD0F8B5ADF80C2002919E +:10627000ADF8040001A8F1F705F8002004B080BDD6 +:10628000BFB5ADF8020002206D4614468DF800003F +:10629000281D03F0A2F92846EBF7F0FBBDF80C101F +:1062A0000138218018BFC82004B0B0BD80B502F00D +:1062B0009DFB08480078012804D038B9BDE880402B +:1062C000FEF770BABDE88040FEF7A0BABDE8804096 +:1062D000FEF782BA2426002010B50446EBF744FCF2 +:1062E0002046FCF7F1FB2046EFF7A2FC04480078BB +:1062F00000B110BD2046BDE8104000F0A8BA00BFB4 +:106300002426002080B5E22806D1084A0846114616 +:1063100003F0A5FD002080BD034A9268D2F828242E +:10632000BDE88040104700BF0C010020B679002076 +:1063300010B50446103001F053FA204650F80C1FF7 +:1063400009B101F07DFE04482146502240684368AF +:10635000BDE81040184700BFA01F002070B50446DC +:1063600008460E4602F0A2FB30B1826832B101202D +:1063700031460125904704E0002001E04068806834 +:1063800000252060284670BD18B105200121DEF7E8 +:1063900035BA0748417831B1016A21B10021417015 +:1063A0000020F8F76BBC05200021DEF727BA00BFFC +:1063B000AC22002010B5084900220B78074993420F +:1063C00005D00C78FF2C04D00E310132F7E7002104 +:1063D000FF220270084610BDDFBA020030790020AB +:1063E000094908480A780530002142B110F8053CF7 +:1063F000FF2B1CBF037819440E30013AF5E788B231 +:10640000704700BF30790020DFBA02007FB5ADF8D9 +:106410000C0004206E460C468DF800003046F9F75B +:10642000A7FD054628B10320311D2072204603F048 +:1064300016FD284604B070BD10B5084CA16829B1FE +:10644000074909680844EDF77FFF08B1012010BD36 +:10645000E068013038BFE060002010BDB8240020A3 +:10646000207A0020084A002800F0010118BF01200E +:10647000138843EAC01010800448028B22F0800287 +:1064800042EAC111018370470079002000720020A8 +:10649000B0B5044603F0B0F9054600F03BF80548F6 +:1064A00044860548C481284603F061FCBDE8B0403D +:1064B00002F026BE007200200079002010B5084CC2 +:1064C0000121E068C06801700648FE210170F5F7FF +:1064D000CBFF01F0F5F8E0680021C068017010BD45 +:1064E0000C0100202425002010B5074C6078FE2800 +:1064F00009D006480068826B0548006894F90110CD +:106500009047FE20607010BD24250020347A0020C2 +:10651000E426002080B508488068D0F8B8000078EC +:10652000B0FA80F04009FDF74FFF0448017811B13F +:1065300001780139017080BD0C0100202B2500205D +:1065400010B5044620B907488068D0F84C0580474C +:1065500003F052F904490A78A2430A70BDE81040DA +:1065600003F005BC0C010020B17A002010B50446F0 +:1065700020B907488068D0F84C05804703F03CF903 +:1065800004490A7822430A70BDE8104003F0EFBBCB +:106590000C010020B17A0020B0B50546084880689B +:1065A000D0F8D84003F028F924680CB1AC42FBD1F4 +:1065B00003F0DDFB002C18BF01242046B0BD00BF56 +:1065C0000C01002098B110B5044601F0C1F8206814 +:1065D000006A03F097FC206803F094FC606908B13E +:1065E00003F090FC2046BDE8104003F08BBC7047E0 +:1065F00010B50848084A4FF6FE730178002031B103 +:1066000032F81C4B9C4218BF01300139F7E780B2C9 +:1066100010BD00BFD1BA020030560020BCB5094CF5 +:10662000246864B1E46954B10004069D013000950A +:10663000A04701460020012908BF0A20BCBD0A204E +:10664000BCBD00BF6827002010B5094C24686CB1A0 +:1066500064695CB100040130A04701460A200A29A0 +:1066600008BF0920002908BF084610BD002010BD42 +:1066700068270020B0B5044602F084FA074D297857 +:10668000884202D36868FBF76DFEE878207101301C +:10669000E870204601F074FC2079B0BD502600203F +:1066A00010B52020EFF3118480F3118805480068AD +:1066B000006B8047044AD2E9102384F3118802F06A +:1066C000C5FC10BD8C010010886E002070B504461A +:1066D0002020EFF3118580F31188207D40B1E6681A +:1066E000FFF7DEFF216A301A884288BF002000E0F1 +:1066F000002085F3118870BD4A1C08BF05212022A7 +:10670000EFF3118382F3118801228A40C0E9081255 +:10671000034AD26D02EBC101416383F311887047D4 +:10672000A01F002000B1704710B5074C207C28B195 +:10673000064890F8480008B9FBF7F2F900202072EB +:10674000BDE81040704700BF38220020A01F002085 +:106750007178CDF8248006940797CDF80CB002909C +:106760000D208DF8280000988DF8290030785844C5 +:1067700008444946CDE904007047704701390329B0 +:1067800084BF4FF0FE307047DFE801F0020B0409D0 +:10679000007870478178008840EA014070470068BF +:1067A00070470088704781B14A6872B10A78042A3C +:1067B0000BD18A684AB102680023916153624B6829 +:1067C000D36189689162EAF7F9BE6FF00200704701 +:1067D000B0B5056802200C46FEF736F964B1D5F86D +:1067E000EC000021B1EB107F06D10420FEF72CF95C +:1067F0004FF0FF30C5F8EC00B0BDF8B50DF10E015B +:1068000000F010F860B902208DF80000BDF80E000D +:10681000ADF80C006846FEF713F8013818BF0120E8 +:1068200004B080BDBFB50C46014602206D468DF810 +:106830000000281D02F0D1FE2846F4F729FFBDF81C +:106840000C100138218018BFC82004B0B0BDBFB5FE +:106850006D4604462846FFF77FF840F201101021EC +:106860002A4603F02BF934B128B96A4640F20110E8 +:10687000102103F029F9BFBDCA071CBF0122027015 +:106880004A0744BF01224270CA0644BF0122C270B7 +:106890008A0644BF01220271C90544BF0121C171AA +:1068A000704710F1140F45F6A611A8BF6FF0130042 +:1068B00010F15A0FD8BF6FF05900C0EB0020084408 +:1068C000462180B2B0FBF1F0C0B2704710F1140F56 +:1068D00045F6A611A8BF6FF0130010F15A0FD8BFEC +:1068E0006FF05900C0EB00200844462180B2B0FB95 +:1068F000F1F0C0B27047B0B50C46054600F0F8FAAA +:1069000068B100F11B01007C0022824207D211F81D +:106910003230AB4208BF01F832400132F5E7B0BD7A +:1069200070B50446006C04F144052CCDA0FB0106B3 +:1069300002FB0161C6184D41300C002240EA0541BE +:10694000FCF7F2FFC4E9146570BD81B040F2000CA1 +:10695000EFF311808CF3118800200090009810B99B +:1069600000980130F9E72020EFF3118180F31188BE +:1069700001B07047E0B500200DF1070201218DF84C +:106980000700032003F09AF830B90DF10703032044 +:106990000021012202F0F0FB9DF807008CBD70473A +:1069A00010B5084B1B6853B1DC79844205D19C8833 +:1069B0008C4202D19C79944201D00C33F2E7184604 +:1069C00010BD00BF6C530020084980890A8890429E +:1069D00024BF00207047496800EB400011F82000F8 +:1069E00010F00F0018BF0120704700BF40260020A4 +:1069F0000849486809880131013904BF01207047FE +:106A000000F10C0200780007104604BF0020704718 +:106A1000F2E700BF402600200146074802780748F9 +:106A200042B10379042B02D80B0404D00139013A96 +:106A30002430F5E700207047E3BA0200204500202B +:106A400080B50648006938B1054802F0D1FF054815 +:106A5000BDE8804002F0D2BF80BD00BF381F0020DB +:106A6000C98102006D880200B0B50D46044602F0EF +:106A7000C3FED5E9001211B14A606A6800E06260A5 +:106A8000002A18BF14462160BDE8B04003F06FB97A +:106A90001CB500200DF10204064905228DF8020004 +:106AA000601C02F0D3FC4120802106222346FBF724 +:106AB0006BFE1CBDF0B902001CB50446042001F0B9 +:106AC000DDFF20780DF10303C62105228DF80300B8 +:106AD000D4F8020001904520FBF756FE00201CBDB3 +:106AE000B0B50125382185700170FCF76BFA0446BA +:106AF00028B1A577257002F0FFF9024860622046B0 +:106B0000B0BD00BFE079002080B508484FF6FE72A6 +:106B1000C18A914202D0807B800700D480BDEDF70E +:106B2000E9FFBDE88040E4F78FB800BFA86D002002 +:106B300080B5FEF739FE60B10648006881034FEA70 +:106B400000414FF0000058BF0816BDE88040FDF737 +:106B500067B880BDB44F005080B50648064900684C +:106B600008400649884204D1F9F752FE1328C8BFED +:106B700080BDFEE71813005000F0FF0F0010B40BAB +:106B8000202918BF704710B503F03FF804460548A8 +:106B9000426812B14188002090472046BDE810406D +:106BA00003F021B97026002010B50446064800689D +:106BB0002060064840686060F8F7FAF9083838BF86 +:106BC0000020A06010BD00BF1C6E00200026002029 +:106BD000B0B50C46054603F018F84CB1002144F856 +:106BE0000C1C296819B10D4655F80C1DFAE72C60EC +:106BF000BDE8B04003F0F7B8B0B502F0FDFD0446C3 +:106C0000064890F8380118B100F0AAFB054600E0EC +:106C10000125204603F0ABF82846B0BDD81B002064 +:106C2000F8B51D461646044602F0E6FD44B104F1EF +:106C3000200720348ECF33432F432A4331438EC461 +:106C4000BDE8F84003F093B880B5084A0020012160 +:106C50001070852002F032FF00B180BD034B85200B +:106C600000210122BDE8804002F086BA9E7A002011 +:106C70001CB504460020019001A9204602F047FD02 +:106C80009DF8040000B11CBDBDF806004006FAD511 +:106C9000608801F0E7FE1CBD1CB5084C8DF80700AC +:106CA0000DF10700646822701A0A63700423A27051 +:106CB0000022E270049AF8F70FFC1CBD8826002021 +:106CC00070B5084E05461446706803F0C8F8706841 +:106CD00029463522092304723046BDE87040F8F792 +:106CE000FBBB00BF8826002010B50446074800788B +:106CF00010B102F0F3FA20B12046BDE81040F2F7DF +:106D00009BB82046BDE81040F1F7B4BC2426002013 +:106D100010B5084A126842B10023032B05D014882D +:106D2000844204D006320133F7E7C82010BD0020AA +:106D30000B8010BDEC26002080B5002206490A70A9 +:106D400020B1012008700549087001E00348027075 +:106D5000FBF7D4FB012080BDA17A0020A07A00209F +:106D60001FB5418801B11FBD041D01A92046FEF7D2 +:106D7000C3FA0128F7D102F075FDADF80C000294BA +:106D800001A8F0F77FFA1FBD10B5084B1B6853B17F +:106D90001A79824218BFFF28F8D11A4632F8064FF6 +:106DA0008C42F3D100E00022104610BDF8260020EE +:106DB000084A92F82E10814202D1117801B1704731 +:106DC00010B9002182F82B1002F82E0F5520012156 +:106DD00002F07ABEAC22002006480021FF2201709A +:106DE0000549C96809690A7004494FF0FF324260D9 +:106DF0000A607047582600200C0100202C7A0020E1 +:106E000010B5044620B906488068D0F84C05804784 +:106E10000448017821430170BDE81040F6F77AB9C3 +:106E20000C010020B17A00200748002101700748BA +:106E3000C168C968097801B1704780680021D0F83D +:106E400058240020104700BFB17A00200C01002018 +:106E5000B0B50C460546FDF7D3FA204468600548F6 +:106E60008068D0F8D810D0F8EC242846BDE8B040AF +:106E7000104700BF0C010020084A0021032904BF6D +:106E80000020704702EB81035B88834202D112F835 +:106E900021300BB90131F1E7012070474C79002016 +:106EA000084A002818BF021D106848B1428912051F +:106EB00004D529B1026812888A4201D0021DF3E785 +:106EC000704700BF587A0020084B002818BF031DE8 +:106ED000186848B1437B8B4204D12AB10368DB892F +:106EE0005B0701D5031DF3E7704700BF587A002008 +:106EF00010B508490431096849B10A7C00239A4257 +:106F0000F9D001EBC3040133E47E8442F7D1084693 +:106F100010BD00BF5026002010B500F11B03007CFF +:106F200060B113F8084B01388C42F9D113F8070C03 +:106F3000104303F8070CA3F10D0010BD002010BD95 +:106F400010B58AB001AC06492022204603F002F8B1 +:106F5000044809902046E8F76DF80AB010BD00BF5C +:106F600094BB0200982600201EF0040F14BFEFF31C +:106F70000980684685462DE9F00F684671467446DB +:106F8000024A904768462146FEE700BF9D950200F1 +:106F900010B5418203461430012100249861C3E9F1 +:106FA000024111781974586102481946BDE8104031 +:106FB00001F080BBB0260020084890F8641001B1B1 +:106FC0007047012180F86410C06D00213029F7D08E +:106FD0004218526042500831F8E700BFA01F00205D +:106FE0002DE9F04F2DED108BC0F800D0D1F800D076 +:106FF000BDEC108BBDE8F08F00BF00BF00BF00BF2D +:1070000000BF00BF00BF00BF10B504460748002AFC +:1070100008BF02462046EFF761FE20B10146204638 +:10702000EEF7DAFA0024204610BD00BFF0B50200EA +:10703000084890F8381001B17047012180F83810E5 +:10704000006A00213029F7D04218526042500831BE +:10705000F8E700BF3822002070B514460D460646FA +:1070600002F0CAFB6168C5E900416168002918BFE8 +:107070000E4635606560BDE8704002F078BE10B520 +:107080000446022001F0FAFC032001F0F7FC002086 +:10709000EDF7C2FF4520C72101222346FBF774FB11 +:1070A000002010BDB0B5054602F0AFFD2C6844B11C +:1070B00054F80C1C2960FF2104F8021C002144F83C +:1070C0000C1C02F090FE2046B0BDB0B50D4600216C +:1070D0000024FAF70DFA2946F2F750FF28B16FF0B5 +:1070E000011184718480016000E004242046B0BD59 +:1070F000B0B5056802200C46FEF7DEFA54B1D5F8AB +:10710000EC000021B1EB107F04D10420BDE8B040B9 +:10711000FEF7D2BAB0BD0068C168490701D58168E1 +:10712000FAE70221C0F88010C168C90702D1D0F87F +:107130008C10F9E70021C0F88010704770B5044644 +:107140001C2015460E4602F0DFFE48B100210673F2 +:107150004581A0F80D10C17301814161C0E9004172 +:1071600070BD80B502F098FC00B180BD0020012107 +:107170000022FFF7A9FE0028F7D001680029F4D00B +:10718000BDE88040EBF772B970B50446182000EBFB +:10719000C405681802F0B8FE064630B130462946EC +:1071A00002F0BCFD70193474F060304670BD027A94 +:1071B0000B7A9A420AD1032A0AD0022A06D10988F8 +:1071C0000088401AB0FA80F04009704700207047EC +:1071D00000F0C3BBF8B54189ADF8041041684A78A6 +:1071E0008DF8062089788DF80C100AB9407A10B114 +:1071F00001A8ECF74FFC8FBD10B50648006940B1FF +:10720000054C204602F0F4FB2046BDE8104002F099 +:10721000F5BB10BD381F002027400100B0B50C465B +:10722000054602F0E9FA00212160696800296160E1 +:1072300008BF29460C606C60BDE8B04002F097BD05 +:10724000B0B50C46054602F0D7FA00216160296806 +:107250000029216008BF29464C602C60BDE8B04081 +:1072600002F085BD012918BF704710B50021044602 +:10727000FFF72BFF0348002102782046BDE81040AD +:10728000E7F764BBCABA020070B50646064D04466D +:107290006FF39D06012002F073FDA8680642F9D045 +:1072A000A8682040286070BD8847024080B5054826 +:1072B00001210068426801209047034803490068A3 +:1072C000486080BDE001001030200940F424002017 +:1072D000074841880088401A4FF4877100F587708D +:1072E00090FBF1F25143081A00F5877080B27047A5 +:1072F000C82600204FF6FF70814208BF704710B5C6 +:107300000C46E9F7F3FA0349E0B2BDE8104002F099 +:107310002BBD00BF0160002080B5074909688A794C +:1073200002B180BDC2680968407800F077FFBDE80F +:10733000804000F0F5BB00BFD826002010B568B132 +:1073400004460C30EFF730FB0146002029B1FF2244 +:10735000086001F10C000C818A7210BD002010BD84 +:1073600010B506483C21012200230068C468044887 +:10737000A047002818BF012010BD00BFA4010010C5 +:1073800000A00C401CB5064980B24FF47F42082390 +:1073900009684C68009003483021A0471CBD00BF1D +:1073A000A401001000A00C401CB5064980B24FF4A7 +:1073B000F802122309684C68009003480421A04792 +:1073C0001CBD00BFA401001000A00C401CB5064964 +:1073D00080B24FF40032112309684C6800900348D2 +:1073E0000421A0471CBD00BFA401001000A00C4058 +:1073F0001CB5064980B24FF440620A2309684C6804 +:10740000009003482021A0471CBD00BFA40100102C +:1074100000A00C4050B14AB110B5044608300EC06F +:1074200021460448FFF7FAFE002010BD6FF002006D +:10743000704700BFD81B002005480649C069884234 +:1074400008BFF6F7C7B904480421283002F072BD1E +:10745000D01E0020953700007020002080B54FF02E +:10746000FF3001F0A3FF800758BF80BD03484FF4F1 +:1074700000612830BDE8804002F05CBD7020002033 +:107480000648007E022804D10548816C09B9C06C09 +:1074900008B1002070470120704700BFD01E0020B7 +:1074A0003021002070B5144600220E46054600F03B +:1074B00041FFFF2807D02B2E18BF40F22B2646EAAB +:1074C000842145F8201070BD10B586B08DF80410E9 +:1074D000024601AC1146601C102201F0B7FF3B20B0 +:1074E0001121224602F0F0FA06B010BDF8B50021D5 +:1074F0000391CDE9011101218DF80410034901F137 +:107500001C0201A900F043FE04B080BDA01F0020B2 +:10751000B0B5074D044604212878FBF753FF00B1AE +:10752000B0BD287804212246BDE8B04002F052BC2C +:107530009D7A002080B502F06DFB42F21071084088 +:10754000421804484FF480410078BDE8804002F0C2 +:1075500041BC00BF9D7A002080B50648064902F074 +:107560007EFC00F0BDFAFDF7DFFEBDE8804000F0D4 +:10757000C7BA00BFAE790020A679002010B5034637 +:1075800006484468A2700A0A2170194603236270F3 +:107590000422BDE81040F7F79FBF00BF88260020F7 +:1075A0001CB50C46002121600DF10601FFF73AF9E8 +:1075B00008B1C8201CBDBDF806002146BDE81C402E +:1075C000FEF7B2B910B50446007801F06FFA08B1C1 +:1075D000022010BD204600210022FEF7D5F9B0FAA6 +:1075E00080F04009000110BDB0B5074B00221B68B8 +:1075F00043B11C798442FAD1DC88D5B2013221F83A +:107600001540F4E7D0B2B0BDF8260020E0B58DF803 +:10761000050006480121002203238DF8041000789C +:1076200001A900910A21FBF7ECFC8CBDA37A002094 +:1076300058B1074B42791B789A4206D2531C4371CA +:1076400000EB4200C180012070470020704700BF5E +:10765000CFBA020001684268054BC3F80720C3F89F +:107660000310044A01684068C2E90A10704700BF6D +:10767000007900200072002010B504460B38102855 +:1076800004D304488068D0F84C05804702488473CE +:10769000012010BD0C0100200072002010B504462E +:1076A0000B38102804D304488068D0F84C05804774 +:1076B0000248847310BD00BF0C010020007200203E +:1076C0000648017841F004010170054800218068F6 +:1076D000D0F894000078F6F719BD00BF907A00202A +:1076E0000C01002080B50648006838B1F2F740FA76 +:1076F00004480068BDE88040F3F7AEB980BD00BF24 +:107700003C7A0020407A002070B5074E044602F013 +:1077100073F8054620463460F2F72AFA2846BDE899 +:10772000704002F024BB00BF3C7A00200749096882 +:1077300049B10A681388834203D1126A5278D2078A +:1077400001D00431F3E70846704700BF587A0020A3 +:10775000074B002211461A684AB1131D8242F9D123 +:10776000034A1368834218BF0A1D406810607047BF +:10777000587A002080B507490138884205D806208C +:10778000FDF762F90420FDF75FF90220BDE88040B3 +:10779000FDF75AB9FEFFFF0F10B5064C28B1064899 +:1077A00001210068426820469047606820F0300060 +:1077B000606010BD00400340D80100101CB50446B5 +:1077C0000498002B0090054808BF03462046F4F7B4 +:1077D000F3FE002818BF002420461CBDE8B70200B5 +:1077E00000F11401816141612021EFF3118281F3E5 +:1077F000118801684368196041680068416082F33C +:107800001188704710B5074C207C08B1FAF788F949 +:107810000020207240F2000CEFF311808CF31188ED +:1078200010BD00BF3822002080B502F03AFA50B1F6 +:1078300001460079421E0120012A03D88A6981F895 +:107840002000CA6180BD002080BDB0B50568044637 +:1078500095F85000022808D1A86802F082FA204664 +:10786000FBF791FB002085F85000B0BDB0B5054690 +:1078700001F0C2FF2C6834B121680029296008BFDB +:10788000294600224A6002F072FA2046B0BD70B567 +:107890000D460646002401F0AFFF2D6825B1296989 +:1078A000B14208BF2C46F8E702F061FA204670BDED +:1078B000F8B50C46054601F09FFF95E8C2002D691A +:1078C0002944216002F053FA701B874238BF3846C2 +:1078D000F8BDBCB5046825790DB9A4792CB14FF079 +:1078E000FF340094E1F7A6F9BCBD02B0BDE8B0409A +:1078F000F9F746BE10B50C4601F0D8F838B100F1E2 +:107900000C0120460222BDE8104001F09FBD4FF45B +:107910009970208010BD10B54A1E012101FA02F3B2 +:1079200000221C0404BF90B210BD0342C3F34E03F7 +:1079300018BF0A434900F4E710B562B10C78037828 +:10794000A34206D1013A00F1010001F10101F5D194 +:107950001C46181B10BD002010BD10B508221306D0 +:1079600007D00B7804789C4203D1013A01300131F1 +:10797000F5E7D0B2B0FA80F0400910BD10B503466B +:107980001B68834204D09C6864699442F8DA00E082 +:10799000034658680B6048600160596010BD70472D +:1079A000064B1A6822B11346D268002AFBD10C3369 +:1079B000817100211860C160704700BF6C530020C6 +:1079C000064A1168814205D031B10A46C968814230 +:1079D000FAD10C32C168116002F094BA6C530020E5 +:1079E00080B506484FF480710078FBF7EBFC00B1DE +:1079F00080BDBDE88040FBF73FBD00BF9D7A002001 +:107A000080B50548FF22007800EBC00081000348E4 +:107A100002F02EF980BD00BFE3BA0200204500202D +:107A200080B50548FF22007800EBC00081000348C4 +:107A300002F01EF980BD00BFE3BA0200204500201D +:107A4000102809D31038012200F01F01400902FA62 +:107A500001F1024A42F82010704700BF80E200E0C6 +:107A6000E0B50178B0F801000DF1050303228DF8AF +:107A70000510ADF806004F208021FAF785FE8CBD79 +:107A800080B505480021017004480170FAF79CFE9A +:107A9000BDE88040FEF7FCBFA57A0020A67A002052 +:107AA000B0B50546C0780C460870281D02F028FACB +:107AB0006080A81D02F024FAA08005F10800B0BD86 +:107AC000B0B5064D2C78601C2870204601F042F8B5 +:107AD000002CF7D00028F5D12046B0BD937A0020C5 +:107AE00003480449044A054BC0E90132C1607047AC +:107AF00004250020E99E020071FD0000C57301000D +:107B00000348064B0349044AC0E90121C36070479A +:107B10000425002071FD0000C5730100E99E0200EC +:107B200010B5064C206818B102F0ECF90020206076 +:107B300000F05EFDBDE8104001F018B8D826002026 +:107B400080B505494870054880210078F7F74AFF5D +:107B5000F8F738FE002080BD042500209C7A002024 +:107B600006490A68002AFCD10022CA610860C86977 +:107B70000028FCD00020C86148687047001004400D +:107B800070B50024A34208D050F824506E1C04D0D5 +:107B900015408D4202D00134F4E7FF24E0B270BDFD +:107BA000064841880088401A4FF4877100F58770B5 +:107BB00090FBF1F202FB110080B27047C826002052 +:107BC0008068D0E90020C1E9002004484FF47052D9 +:107BD000006802EA80208860704700BF30240340BC +:107BE0000648B0F870100131A0F8701088B28842D1 +:107BF00008BF70470120F3F723BC00BFA86D002029 +:107C000003480449044A054BC0E90132C16070478A +:107C10007423002071A70100E17B020019730200A8 +:107C2000054806494FF0FF32007818B141F8042B9F +:107C30000138FAE7704700BFD2BA020098780020F6 +:107C400005484FF4825100680028044848BF4FF4AB +:107C500041510160704700BFAC4F005028A10C405B +:107C600005484FF4805100680028044848BF4FF48D +:107C700040510160704700BFAC4F0050A8A00C40BD +:107C800080B505480068FAF717FC04480068BDE8AD +:107C90008040FBF7C1BE00BFEC790020F0790020E6 +:107CA000B0B5044601F0A8FD054604482146FEF79C +:107CB000DBFE2846BDE8B04002F059B8D81B0020D2 +:107CC000064A0021B1F5307F06D0501890F93330C4 +:107CD000002B02D55831F5E7002070477053002083 +:107CE000E0B5064901AAFCF7E3FE9DF806108128DD +:107CF00018BF6FF07F0148B28CBD00BF01000304C4 +:107D00000A460146044843682BB18068084202D005 +:107D100002484068184770479CB90200D01E0020F6 +:107D200005480068C00704BF00207047034800688A +:107D3000C0B2C009704700BF4021084000000440A5 +:107D4000BCB5044680686A46ECF708F90546832806 +:107D500004D1694620460022FCF7AAFE2846BCBD95 +:107D600010B504463A2000211122234601F004FAFE +:107D700000B110BD01484068606110BD14250020AD +:107D80001FB5044600200390CDE9010001208DF8C5 +:107D9000040001AA2046FFF7FBF8204604B010BDFE +:107DA00005490A78824208BF7047087003481021CD +:107DB0000078F6F7ABB900BFD02600209D7A0020EE +:107DC00080B506484FF480710078FBF7FBFA00B1EC +:107DD00080BDBDE88040FBF74FBB00BF9D7A00200F +:107DE000F8B54188ADF80410411D02910179407F3A +:107DF0008DF806008DF80C1001A8F1F7EFF88FBD93 +:107E000070B50C460646EFF757FF05461E2800D012 +:107E100025B9304621460122FDF70CFA284670BDEF +:107E200010B5064890F82E0028B10020002100244B +:107E3000E6F7B4FE00B10124204610BDAC220020BC +:107E4000FEB5029000200091694601900348406809 +:107E500001F0E4FF013806B080BD00BF0C24002013 +:107E6000064A12683AB11379834202D193688B4271 +:107E700001D01032F5E71046704700BF7826002089 +:107E8000E0B5064904486A46096800684B6C02215F +:107E900098479DF800008CBDE4260020347A00202D +:107EA00005490968401A054909788900B0FBF1F2D3 +:107EB00002FB1100704700BF307A0020B47A002026 +:107EC00000F120014FF0FF32C9B2192938BF00F18B +:107ED00045024038C1B2252938BF0246D0B27047AA +:107EE00005480178832918BF7047002101700348B5 +:107EF0000170F8F745BA00BFB07A0020B37A0020CD +:107F000080B501F079FC0449044A09681160BDE8B4 +:107F1000804001F02CBF00BF3C7A0020407A002056 +:107F20000C2884BF01207047062884BF03207047B7 +:107F3000022884BF05207047002818BF072070471B +:107F400041F01001F1290AD112F0300F07D080B5AD +:107F500001F060FE00F007000230BDE8804070478D +:107F600080B5064A12682AB1926A1AB1000401303B +:107F7000904700E0002080B280BD00BF682700204D +:107F800006494B680A1D23B119461B68002BFAD11C +:107F900000E0114600220260086070475026002071 +:107FA000F8B501A80021FDF78FF8039A6846BE21B5 +:107FB0008242009228BF8FBD1170009A0132F7E70C +:107FC00001460120886000200861C86001F11400AA +:107FD00088614861014800F06DBB00BFA026002009 +:107FE00070B514460D460646002024210022FBF7FA +:107FF00031FD20B131462A46234600F03FFB70BDDB +:1080000010B50446006800F02BFB044821682422C8 +:108010004068436898470020206010BDA01F0020E2 +:1080200010B504460068FFF7DBFB044821681C22FA +:108030004068436898470020206010BDA01F0020C2 +:1080400010B50446006800F00BF804482168582277 +:108050004068436898470020206010BDA01F0020A2 +:108060002021EFF3118281F311888168C3681960C0 +:10807000C16883685960002182F31188EDF7ACBABA +:1080800041680978102908BFFFF7A4B8092904D06E +:10809000052918BF7047E9F725B800F0AABB884248 +:1080A00004BF012070470246002032B129B180B5DB +:1080B0001046FFF752FCBDE88040704750B10022E7 +:1080C0000021072A07D8835C0132002BF9D0012157 +:1080D0000922F6E70021C8B27047E0B54178408830 +:1080E0000DF1050303228DF80510ADF806004420BC +:1080F0008021FAF749FB8CBD80B550B110F8021C05 +:10810000FF291CBF042080BD0C38F9F785F9002039 +:1081100080BD052080BD70B50E46014618461C4640 +:10812000154601F09CFE04F10800314601F055FEB1 +:10813000057070BD1CB504686479022C02D1E7F7A4 +:10814000EBFB1CBD049C049402B0BDE81040E3F7B7 +:1081500009BDF8B50F20B421012200238DF80C00D1 +:108160004FF6FC70ADF8040001A8F7F731F98FBDA8 +:1081700010B5EFF31484002C1CBF002181F3148888 +:108180008047002C1CBF022181F3148810BDB0B5BC +:1081900013460C46054600201C210022FBF75AFC22 +:1081A00018B12946224600F093FAB0BD10B5054C2F +:1081B000D4F800C0BCF1000F04BFB62010BDBDE86C +:1081C000104060473024002010B5054C2069F2F7BC +:1081D00095F9A16801B9E060481CA06010BD00BF1E +:1081E000381F0020FF2807D0044A526852F8203078 +:1081F0008B4218BF42F82010704700BFE4B802005D +:10820000102801D3044A02E0042801D3014A815412 +:10821000704700BF14ED00E0F0E300E0F8B5054B57 +:108220001B682BB1CDE902128DF8040001A8984714 +:108230008FBD00BFDC24002010B514460A4601465D +:1082400023F001003A2811BF0A201846234600F007 +:1082500093FF10BD010700F002004FF0030158BF6B +:10826000012141EA4000014908707047947A0020DA +:1082700080B5044B1B689B699847034900220A603C +:1082800080BD00BFA80100108404604280B504498D +:10829000096849698847034900220A6080BD00BF18 +:1082A000A80100108404604250B180B5073080B24C +:1082B000F0F7C0F8FF28BDE8804004BF01207047F8 +:1082C00000207047E0B58DF807200DF1070201236B +:1082D000FBF712FE014908708CBD00BFA0230020EF +:1082E00010B54AB111F8013B10F8014B013A9C421C +:1082F0001CBF002010BDF4E7012010BD00220128A2 +:108300004FF0000004BF40F2EE204FF47A720229D1 +:1083100008BF0246104670470548B0F85410B0F840 +:108320005600814218BF70470820FCF7A7BB00BF6A +:1083300030210020B0B5144640F2FF3250230546EC +:10834000FFF71EFC1CB155F82010890A2160B0BD52 +:1083500010B5044601F050FA03490A7822430A7026 +:10836000BDE8104001F003BDD01E0020B0B50548A7 +:108370004468C56901F01EFB014620462A46BDE857 +:10838000B0401047D01E002010B5044600F04AFA55 +:1083900030B9204600F060FD002808BF6FF00104EE +:1083A000A0B210BD10B5054CD4F808C0BCF1000F48 +:1083B00004BF012010BDBDE8104060471425002017 +:1083C00001284FF00100044A08BF0320012110706A +:1083D000852001F079BB00BF9E7A002010B5054CC6 +:1083E00004212078F7F7FEFA20780421BDE8104038 +:1083F000F5F75AB99D7A0020F8B5ADF804000448A5 +:1084000002918DF80C20416809B101A888478FBD01 +:1084100054750020B0B585690C4635F8020B24F878 +:10842000020B2946204601F01AFD287A2072B0BDC1 +:10843000E0B5ADF8000004488DF802100192016823 +:1084400009B1684688478CBD547500201FB5ADF84A +:10845000020000206C468DF80000201D01F0BDF8E0 +:108460002046E9F70BFB1FBD10B5034604484468DE +:10847000218019460223BDE81040F7F72DB800BF50 +:108480008826002004480078052818BF7047034854 +:1084900080210078F5F73ABED02600209D7A002092 +:1084A00004480178012903D10021017002480170BC +:1084B000FAF724B8A17A0020A07A002010B50C4663 +:1084C00000F0F4FA30B10C302146022200F0BEFF79 +:1084D000002010BD022010BD10B50446087A032804 +:1084E000207219BF08882080204601F0B8FC0020C7 +:1084F000608110BD054A12683AB153681B7809B112 +:10850000002BF8D000F8013BF5E77047247A0020F3 +:10851000044981F82F0001210028034818BF0221D7 +:1085200001707047AC220020BC27002050B1821D92 +:10853000407938B132F8023B01388B4204BF012048 +:108540007047F6E70020704710B5054BC0B22AB15E +:1085500011F8014B013A6040185CF7E710BD00BF0D +:108560008CA8020004490968401A04490978890066 +:10857000B0FBF1F0704700BF307A0020B47A0020E1 +:10858000054800224FF0807341790131417100208C +:108590000021F5F70BBF00BF24250020044800216F +:1085A00001700448007800B17047F7F7E9BE00BFDA +:1085B000B37A0020B07A002080B505488068D0F8F2 +:1085C000DC04804701F018F9BDE8804001F0CFBB22 +:1085D0000C01002058B110B51C21044601F09EFB8F +:1085E0006FF00100411C20806181BDE810407047A0 +:1085F000B0B5054C206820B1856901F083FC2846A0 +:10860000F9E700202060B0BDE8790020054A38B1C4 +:1086100032F8023B01388B4204BF01207047F6E775 +:1086200000207047087800200448002101700448A9 +:10863000007800B17047F7F7A3BE00BFB07A002002 +:10864000B37A002010B50B4600201C210022FBF756 +:1086500001FA044610B12046FFF7B2FC204610BDD7 +:108660002021EFF3118281F31188016843681960BA +:1086700041680068416082F31188704710B5044674 +:108680000448002B08BF03462046FCF751FD204656 +:1086900010BD00BFCCB90200B0B5054D0024022CBE +:1086A00008BFB0BD55F8240080470134F7E700BF8C +:1086B0006CBA02002022EFF3118382F31188086064 +:1086C00042684A6042681160416083F311887047D4 +:1086D00010B504460448002A08BF02462046FEF7AB +:1086E00057FC204610BD00BFD8B9020010B50446A3 +:1086F0000448002A08BF02462046F8F7FDFC204641 +:1087000010BD00BF54B802002021EFF3118281F3A5 +:1087100011888168C3681960C1688068416082F30C +:10872000118870471CB50C4601A9FEF739FF10B13E +:108730004FF6FF7101E00199498821801CBD016855 +:1087400091F8512022B1012A18BF7047FAF71BBCDB +:1087500091F85310FBF780BAB0B50C46054601F00E +:1087600054FA296844F80C1C2C60BDE8B04001F0B4 +:108770003ABB70B514460D46064600F046F8304642 +:1087800029462246BDE87040E9F7E2BEF8B5ADF8EB +:108790000C0004208DF800006846F7F7E9FBBDF8EF +:1087A000020004B080BD41B2002211F1760FB8BFC3 +:1087B000012201385100052838BF012108467047C1 +:1087C00010B52021EFF3118481F3118880682146D0 +:1087D000FCF7C8FC84F3118810BD0B46416911B148 +:1087E0004878800700D070478A888878097BFAF734 +:1087F00033BFE0B541894068ADF8041040788DF88A +:10880000060001A8FDF79AFB8CBD704710B5044C1B +:10881000606820B101F076FB00206060208010BD10 +:108820004026002080B501F03CFA28B100790138DB +:1088300004283CBF012080BD002080BD80B501F030 +:1088400030FA28B10079013802283CBF012080BDF0 +:10885000002080BD0446FEF7CFFC034803210175CC +:10886000204601F06BFA00BF381F002004488168E1 +:108870000139816018BF7047D0E90310F5F76CB972 +:10888000381F0020FF2806D0034911F8202002F0ED +:10889000FB0201F8202070470210084010B5044C7C +:1088A000207818B1FBF774FD0020207010BD00BFC8 +:1088B000AF7A002080B580780530C0B201F024FB8B +:1088C00018B1BDE8804001F01DBB80BD130608BF94 +:1088D000704711F8023B013A037011F8013C4370F4 +:1088E0000230F3E7014600200A2906D8012202FAE5 +:1088F00001F111F4836F18BF0120704780B504485F +:10890000407808B900F042FDBDE88040F7F75ABF53 +:108910000425002003480121017103480068F5F790 +:1089200095BE00BF44250020507A00200348012155 +:10893000817003480068F5F789BE00BF4425002018 +:10894000507A002080B50448006801F077F90028CB +:1089500018BF6FF0020080BDDC25002080B5044800 +:10896000006801F06BF9002818BF6FF0020080BDAD +:108970000C240020022807D0032804D180B5E7F793 +:1089800017FC002080BDFEE7F4F7C0BE044890F855 +:10899000411119B1D0F86C0100B10047704700BF18 +:1089A000D81B002000214FF0FF320174C0E90221E2 +:1089B00001710160C0E90511818370471CB5C2F3E4 +:1089C000800302F001040093C2F340032246E5F75E +:1089D00003F81CBD10B50129044698BF012101F020 +:1089E0006BFA2046BDE8104001F068BA024803491E +:1089F000034AC0E90221704714250020FD940200BB +:108A0000A1E400000249034A0A6003490870704764 +:108A100064270020092A0200CC26002004490020F7 +:108A20000022092A08BF704741F822000132F8E706 +:108A30005475002002460448012100780AB101F073 +:108A4000C9B9F5F763BB00BF9D7A002080B5FDF77B +:108A500091FF80075CBF002080BD0020FEF7A8F9D1 +:108A6000012080BD0449B1F86E20824208BF7047E2 +:108A7000A1F86E00FFF7A4B9A86D0020082884BFF4 +:108A800002207047024A0146002042F82100704748 +:108A900054750020E0B58DF807000348C16911B195 +:108AA0000DF1070088478CBD54750020014604482D +:108AB000006818B1426812788A42F9D1704700BF45 +:108AC000247A00200448002100680A460131002869 +:108AD000FAD1D0B2704700BF247A002004480021A8 +:108AE00000680A4601310028FAD1D0B2704700BFB1 +:108AF000F82600200349044A0860106084200421FD +:108B000000F0E2BF747A00207827002004498968C9 +:108B1000D1F8E420D1F8EC1051F820001060704733 +:108B20000C0100200021082904BF01207047425C8D +:108B30000131FF2A1CBF00207047F4E710B5002266 +:108B400000238A4224BFD8B210BD10F8014B013275 +:108B50006340F6E70449096821B10A7B824201D0EB +:108B60000431F8E708467047587A002010B5044CE5 +:108B7000206820B14168216001F0C4F9F8E710BD18 +:108B80004C27002004480021043000680A460131C7 +:108B90000028FAD1D0B270475026002004488068DF +:108BA000D0F8B800007808B1F3F726BCFFF73CBD59 +:108BB0000C010020B0B50C46054600F097FF0248B6 +:108BC00044650565B0BD00BF0820002080B5044B9A +:108BD0001C33FFF78BFD4169002908BF084680BDA3 +:108BE000A01F00202022EFF3118382F31188026B73 +:108BF0001143016383F31188F7F712BC00BF00BF74 +:108C000000BF00BF0498804700980199029ADDF8E0 +:108C10000CE0104710B52021EFF3118481F3118887 +:108C20002146FCF79FFA84F3118810BD83B0C0B5CC +:108C300003AF0EC703A9009100F004F8BDE8884017 +:108C400003B07047E0B50246002001914FF0FF31BC +:108C5000009001AB0020DDF705F88CBD04480078DA +:108C6000042803D8022801D0DEF730B9704700BFCE +:108C7000BB7A0020B0B50C46054600F0BDFDA96CDE +:108C8000A143A964BDE8B04001F071B8B0B50C468D +:108C9000054600F0B1FDA96C2143A964BDE8B040D0 +:108CA00001F065B880B5E6F71FFDE7F71FFEF7F79F +:108CB000AFF9BDE88040EBF772BC2020EFF31181E3 +:108CC00080F31188B1FA81F081F31188400970476F +:108CD00010B52023EFF3118483F31188C0E900213C +:108CE00084F3118810BD10B5044600F085FD002105 +:108CF000C4E90011BDE8104001F039B8E0B58DF8C5 +:108D000007000DF10703412081210122F9F73CFD05 +:108D10008CBDE0B50022009068468DF80410ADF8D7 +:108D20000520F6F79DF98CBD28B132B110F8013B52 +:108D3000013A8B42F9D000207047012070471CB5E2 +:108D40000C6891F90430CDE9001201212246E5F7C3 +:108D5000AFF81CBDD0E9002092F83010043918BFDC +:108D6000012152690078F5F7FFBE1CB501A9FEF795 +:108D700017FC044610B90198E6F770FF20461CBDA9 +:108D80000A7A02720A7A022A02D10988018070479F +:108D9000082200F05BBB80B5F7F752FA013004BF40 +:108DA000E82080BDF7F774FA002080BD0A46096804 +:108DB00029B18142FAD1006810600120704700207B +:108DC000704710B52021EFF3118481F31188EFF77C +:108DD0000DFA84F3118810BD80B50B4600200821E0 +:108DE0000022FAF737FE08B14060006080BD10B580 +:108DF0002021EFF3118481F31188FAF7EFFD84F35A +:108E0000118810BD81B0C0B5039303AB009300F08F +:108E1000CDFBBDE8884001B07047FEE780B5F4F7B0 +:108E2000F5FF02480121017080BD00BFA827002086 +:108E300080B5F4F7EBFF02480121017080BD00BF4F +:108E4000A927002010B5C478C2880179037A20468A +:108E5000BDE81040FAF700BC80B500F022FF08B171 +:108E6000007908B1002080BD012080BD0349096858 +:108E700021FA00F000F00100704700BFC02002405E +:108E8000FF2803D0024A926842F82010704700BFC2 +:108E9000E4B8020081784378024840780A46FAF73D +:108EA000DBBB00BFCC26002003488068D0F800015F +:108EB000807B2238C0B270470C0100200348007844 +:108EC000012898BF01F088B80020704724260020B0 +:108ED000034800218068D0F8B8000170704700BFD7 +:108EE0000C01002003480178FE20002908BFFF2064 +:108EF000704700BF7C27002010B5034CE2202146BC +:108F0000FDF700FA204610BDE0790020034991F8F2 +:108F10002610082908BFEEF76FBC7047A86D002027 +:108F2000D9F8CC10D8F8140049680968D1F804259C +:108F3000024270472275026CD0F8D4301268D28A8F +:108F400052064FF04E027047034801680029FCD0DA +:108F500000210160704700BF1C100440E0B5C2F35F +:108F6000800302F0010200930123E4F735FD8CBD7C +:108F70004168034A0978D17000785070704700BF8B +:108F8000CC2600200349012291F8480081F84820AE +:108F9000704700BFA01F002010B5046804F1340022 +:108FA00000F0C2FF002084F8310010BD042805D174 +:108FB00080B51046E7F71CFDBDE8804000207047F3 +:108FC00080B50F20F8F774F900200221BDE8804039 +:108FD000FAF75EBD08288FBF0220024A42F820102F +:108FE00000207047547500201CB50C4601A9FEF7FF +:108FF000D7FA00B11CBD01990C711CBDE0B5019000 +:109000004FF40070ADF800006846F2F707FB8CBD26 +:109010000179042904D0022918BF7047F2F720B95A +:10902000F1F760BC80B503488068D0F8340380470E +:1090300080BD00BF0C01002010B5034C207000F073 +:10904000F3FB607010BD00BF7E27002040B584B0E8 +:1090500002AE0096ECF7A4FF029A039B04B040BD59 +:109060000349002912BF01C900200021ECF758BABA +:10907000B8BB020010B510F8014BFBF745FB012C03 +:1090800008BF0838C0B210BD20220028024818BF0F +:1090900024228150704700BFAC22002080B5002000 +:1090A000FDF786FEFF200321BDE88040FAF7F0BC03 +:1090B00080B50349FF22098800F0DAFD012080BD58 +:1090C0004EB2020003490979002918BF0630400159 +:1090D000704700BFB82400200249088602498881F1 +:1090E000704700BF007200200079002003488068AC +:1090F000D0F82C134FF48050084700BF0C0100201B +:109100000348007808B1F4F705B80020704700BFA5 +:10911000B17A002003488068D0F82C134FF4007017 +:10912000084700BF0C0100200248034A0721002322 +:10913000FEF770B920780020B19F020003488068D4 +:10914000D0F82C134FF40060084700BF0C0100203A +:10915000E0B50021CDE900116946FEF7FEFB80F085 +:1091600001008CBD034A516811B1527802B1084721 +:10917000704700BFE82500201CB514460A4601468A +:10918000009300202346FDF749FA1CBD10B5034C9F +:10919000E06BF6F7A9FA0020E06210BD381F00204E +:1091A000E0B50DF10702012300F018F99DF8070062 +:1091B0008CBD4FF6FF70814208BF7047C8B20021D6 +:1091C00000F0A4B84FF6FF70814208BF7047C8B2E4 +:1091D000012100F09BB880684FF0FF320A60D0E9AF +:1091E0000120C1E90120704710B50468D4F824C0FB +:1091F000029C0294BDE81040604780B58022F8F7D9 +:1092000091FE08B1C06880BD002080BDB0B50024CB +:10921000551E80E836008361C0E90444B0BD80B5C6 +:1092200000F094F800F07AF8BDE8804000F096B8BD +:1092300028B131F8023B013822F8023BF8E7084632 +:10924000704780B510EB520041F100010023FFF799 +:10925000FDFE80BD017809B10020704740680028FC +:10926000FAD0FCF79EBD0A7A032A027208BF00F00A +:10927000F6BD09880180704710B500239A4208BFE7 +:1092800010BDCC5CC4540133F8E70000B0B502490E +:1092900091E83C003CC0B0BDC4B80200024A02EBF9 +:1092A000C000F6F7A3BA00BF0CBA0200B0B502497D +:1092B00091E83C003CC0B0BDD4B80200024A02EBC9 +:1092C000C000F2F7A1BE00BF14BA02000146024876 +:1092D0000078F5F749BF00BF482600200248FF216B +:1092E00008220068FFF720BDEC5800200249D1E9B0 +:1092F0000012C0E900127047381F00200249896837 +:1093000051F82000704700BFE4B80200FF281CBFDE +:10931000014A8154704700BF0020024001480249C1 +:10932000816070470C010020E89F020001210022AB +:1093300001724FF0FF31C0E900217047102802D3BD +:10934000014910380860704700EF00E00148024909 +:10935000016070470C01002050B202000148024930 +:10936000C16070470C01002084AA02000249087005 +:109370001021F4F7CBBE00BF9A7A002002480121E9 +:1093800080F82610704700BFA86D002002480078C2 +:1093900000B17047FFF784B824260020024880F807 +:1093A0002F20E5F78FBC00BFA86D002002490A6896 +:1093B0001040C2430A6070471010044002490A6816 +:1093C0001040C2430A6070470810044000F02CFAB5 +:1093D00001490860DDF718F9D426002001EB40317F +:1093E0000148C06800F00EB9A0230020B9F824108D +:1093F000ADF8000058468DF808807047B068D0F886 +:109400001814D0F8D40090F853000847B5F8541059 +:1094100001396FF31F31A5F85410704794F82200FA +:1094200085F8AA00606AC5F8AC0070470746287C3A +:1094300005F1110103288DF82000704700246A1DF2 +:109440003346CDE90071CDE9020470472AB111F825 +:10945000013B013A00F8013BF8E77047F0B50249DB +:1094600091E8FC00FCC0F0BD40B7020002484FF09C +:1094700000410160704700BF00A10C400248016834 +:1094800041F003010160704724220840024800684F +:10949000C0F30720704700BF30A00C4002480068AE +:1094A000C0F38440704700BF04A00C40024800682D +:1094B000C0F38120704700BF20A00C40024840212B +:1094C0000160FDF7F3BE00BFA8A00C4002490844AC +:1094D00090F84A01704700BFD81B002010B5002348 +:1094E000541E80E81E00C0E9043310BD0249C9685B +:1094F00001B10847002070471425002000F0030048 +:10950000022101FA00F000F01C00704700214FF02A +:10951000FF32C0E90011C0E90221704700F0C9FB29 +:10952000014801210160FEE77C05204370B5024936 +:1095300091E87C007CC070BD40B80200024A02EB9A +:10954000C000EFF733BC00BF24BA0200006801215D +:10955000806900F0080081EAD000704780B500798A +:10956000EDF750FDBDE88040F9F786BF80B5FFF705 +:109570009DFA08B1406880BD002080BD00280249E6 +:1095800018BF012008707047B82700200249012247 +:109590000A60D0E906010847042009400249012277 +:1095A00081F83020F6F714BF381F0020E0B5019392 +:1095B0000023009301ABDCF755FB8CBD80B50A4658 +:1095C000D0F80310104600F0A9FB80BD0068002110 +:1095D00080F822100A20ECF7E9BD09B100F03FBC89 +:1095E00000214160016070474FF4C8014FF47A7266 +:1095F000C0E900217047042303EB8101042389B2F1 +:10960000FFF7ECBE10B50468D4F81CC0BDE81040EC +:109610006047234603958DF804500295FBF7FCBE86 +:109620008DF85400B8F84700ADF855007047BBF806 +:109630000C00049901224346E3F766BD05F10800DA +:1096400004F10A010822FFF701BF41EA90118000EE +:1096500002308DF82D10704740F203714FF6FF7203 +:109660000523FEF78DBA01788DF8391041788DF811 +:109670003A107047A8702079E87060790028287146 +:1096800070470BEB4B0001EB8000A0F81CA070476B +:10969000DAF80860DAF81000BAF9301070478DF87F +:1096A000630002208DF86000E81C2047ADF8380008 +:1096B0006E7B05F10E0000F023BC98F872000130BB +:1096C000C0B2CDE9000570470021416081600160B2 +:1096D000FF2101717047D0E90110401AB0FA80F003 +:1096E00040097047062902D34A1C18BF7047FDF78E +:1096F00003B81CB54FF0FF340094FEF71BFD1CBDF2 +:1097000080B5F0F7B1F9BDE88040FBF71FBA80697A +:1097100002780A70B0F801004880704780B5EEF713 +:10972000D1FCBDE88040FCF7EFB980B5FAF7F8FD51 +:10973000BDE8804000F040BC80B5FFF7EFFFBDE81A +:10974000804000F027BC0021425C0131002AFBD19F +:10975000481E70470021425C0131002AFBD1481E9F +:10976000704780B5FFF7AAFEBDE88040F7F79EBCC2 +:1097700000239A4208BF7047C1540133F9E70B46F2 +:10978000D0F80320C11D184600F0E4BB006800219A +:1097900001700A20ECF70ABD0021C0E90011C0E900 +:1097A00002117047017841F080010170FEF718B98D +:1097B00001480178FDE700BFA01F00200148C069F3 +:1097C000004700BF381F0020E0B5019001A8FEF758 +:1097D00017FC8CBD05300A21B0FBF1F0EEF750BD4F +:1097E000C0E901120421017000207047C0E9011294 +:1097F00002210170002070472021EFF3118081F3D6 +:109800001188704701480078704700BFAF7A002088 +:1098100001480078704700BFB22700200A4603467F +:1098200069208021F8F7B0BF01480078704700BF79 +:109830009A7A0020431C4520C0210122F8F7A4BFDA +:109840000148408B704700BFA86D00200148007898 +:10985000704700BF9D2700200148807C704700BFF3 +:10986000A86D00200148C08A704700BFA86D002085 +:1098700001490870704700BF9D270020014908700A +:10988000704700BF927A002001494860704700BFCE +:10989000F425002001480078704700BF70240020A4 +:1098A0000B46014610461A46FEF74EBE01480068B8 +:1098B00000F03CBBDC2500200148006800F036BB0E +:1098C0000C2400209BF800004FF48051F6F78AB872 +:1098D00002208DF84000E81C00F012BB042039463D +:1098E00014222B46FCF7B0BED0F85413D0F89800E1 +:1098F00004300847ABF800000BF1020000F0AFBAEB +:109900000221808C1080832000F0DEB8ADF80200C8 +:10991000B068D0F830247047DBF84C0000222346B2 +:10992000FDF77EB98DF818009DF840000F287047AC +:10993000014A5160107070473826002018B1006845 +:1099400008B100F00EBA7047014909680968084774 +:10995000E001001001490968C96A0847B801001010 +:109960000148006800680047E801001001480068ED +:1099700040680047E801001001488068704700BF58 +:10998000D81B00200149202200F0E4BA94B602005E +:109990000149202200F0DEBA54B60200E0B5019081 +:1099A00001A8FEF73DFB8CBDA1F1FE00B0FA80F0EE +:1099B000400970470148006D704700BFA01F00209C +:1099C0000068016B21F48071016370470068016BCE +:1099D00041F40071016370470068016B41F48071CC +:1099E000016370470149242200F0B4BACCB50200EB +:1099F00001490860704700BFF02600200149086057 +:109A0000704700BFF426002001494870704700BF2E +:109A10000C7A0020014890F831007047AC220020F9 +:109A2000014890F82E007047AC220020014981F8CF +:109A300032007047AC220020014981F831007047A4 +:109A4000AC2200200148002101707047AF7A00204D +:109A500001490860704700BF3027002001480078A6 +:109A6000704700BFC37A002001480068704700BFFC +:109A7000407A00200148002101607047E879002009 +:109A800001480068704700BFE8790020006801497C +:109A9000EFF792BD914F020001480078704700BF78 +:109AA000B82700200148002101607047587A002043 +:109AB00080B5F1F7D5FE4BF6BE2080BD13460A46B1 +:109AC00001460020F6F7B0B913460A4601460020C9 +:109AD000FCF7BABD01488069C06B7047382200208E +:109AE00080B51046F7F740F9002080BD01460148D7 +:109AF000FCF716BF886E00200148C06CF6F790BCDA +:109B00000820002001680A6802605060084670471B +:109B10000168081AB0FA80F040097047426808608E +:109B20004A601160416070470149242200F012BA76 +:109B3000F0B5020001488069704700BF382200205C +:109B40002020EFF3118180F31188FEE780B52421F6 +:109B500000F0E4F880BD006908B100F0D3B97047A7 +:109B60000088B0FA80F04009704700210170C0E918 +:109B700001117047D5E90201D0F8D4007047DAF836 +:109B80000800006C00687047284621463246FFF7FF +:109B90005DBC691D05F10D02F6F72EBDADF838006C +:109BA000687900247047C521C2B24520F8F7ECBDA2 +:109BB00084F80FA084F80E907047B068D0F8B80011 +:109BC000C16C7047316828688A6D214610478DF84E +:109BD000080002AB61207047ADF83800681D00F046 +:109BE0008FB92046FF214FF0FF32704700208DF8DB +:109BF0002700F9F741BC0978B2FBF1F1084470473E +:109C000000224FF08073FDF70BB880B5FFF7F4FD2D +:109C1000000480BD80B5FAF7FBF980B280BD002159 +:109C20004FF0FF32E8F7CABE01EB400030F8020CFB +:109C300070474068002180F8FD10704780B5E8F754 +:109C4000F9FC013880BD406801210068C16470479B +:109C5000012085210022E0F701BC80B5F6F740FD28 +:109C6000002080BD80B5F6F761FD002080BD0000BA +:109C70000B4611461A46FFF77BBD80B5FAF7C8F9C7 +:109C8000C0B280BD0A4601460020F7F7E9B980B5A9 +:109C9000F4F7DCFC002080BD0021C0E900118160E8 +:109CA000704701460020F1F783B801464A20FCF7CF +:109CB00029BBEFF3108072B67047EFF3108062B6E5 +:109CC000704740680021017070478068D0F84C05EB +:109CD0000047DBF80000F4F7B9BCD7E901102A46C9 +:109CE00020470421007800F075B840465146E2F75D +:109CF000A9B88068D0F84C0500478068D0F84013B8 +:109D0000704700230024FEF7AFBB00220023FBF7BF +:109D100083BB80B5F3F796FC80BD00000A460021A6 +:109D2000FFF726BD40686C3000F000B94FF6FF70B9 +:109D3000F5F78AB801460020FEF712B9FBF7D4FF09 +:109D4000FFF76BF80222E1F70DB90122E1F70AB93A +:109D50000222F6F7B5BB0122F6F7B2BB0021F1F7FC +:109D600027B80021017570470022EEF71BBB80F376 +:109D7000118870470122E2F72BBF0022E2F728BFCB +:109D80000138FDD170476FF00100704703689B6890 +:109D900018470268D26810475846FFF7E8BF2146C7 +:109DA000FAF7D6BB2046FFF7E2BFE81C00F0A8B8E0 +:109DB000084600F0A7B8281D00F0A2B82846FDF715 +:109DC0006FBEE81C00F09CB82846FFF7D0BF012307 +:109DD000EAF7F2B90023EAF7EFB940F8041B70473D +:109DE000D0E901100847000CFFF7C1BF01680968FE +:109DF00008470268126910470168C96908470021CD +:109E0000018070470720F2F767BE0022FAF750BEC4 +:109E10000022FAF74DBE0168096808470268126916 +:109E20001047013080B270470021EFF7C5BB032017 +:109E3000F9F766FF0620DDF749B80220DDF746B8DE +:109E4000E920E8F769BC0846ECF7AEBD0846F7F72D +:109E5000E3BA0846FCF7A8BE0121F4F7B5BC082216 +:109E6000FFF7F4BA0021F8F79FBAC0B2F1F776BF56 +:109E7000000AFCF757BC0021016070478069FFF7BA +:109E8000E2BF8069FFF7E2BF8069FFF7E2BF806948 +:109E900000F0A4B8FEF700FCFCE70020F8F70CBBCC +:109EA00001207047FEF7DCBB0A207047FCF7F8BBC7 +:109EB000FCF70CBC007D704781607047FEF781BFE6 +:109EC000FFF7D0BFF8F7B4BAF8F7D4BA002070475C +:109ED000FEF792BAFFF7A5BFEDF734B9F2F73CB938 +:109EE000F6F7ECBDF7F7B8BBE7F770BAFBF7CCBFF6 +:109EF000FBF7D2BCF9F71ABBE5F7DABA00207047D6 +:109F000000887047F7F788BAECF74EBDF9F74CBFF9 +:109F1000F9F766BFFDF7CAB900207047EAF72ABD16 +:109F2000FBF76EB980687047FDF75ABCF4F78EBB3B +:109F3000FEF7EABBFEF756BEF6F772BAF8F7BCBA00 +:109F4000FCF731BCF3F792BFF5F7A0BDFDF748BFB2 +:109F5000F9F7BABEFFF790B9F8F796BFE9F7FABB81 +:109F60000020704700207047002070470020704795 +:109F7000F32070470020704700207047DC207047B6 +:109F8000DD20704700207047002070470020704798 +:109F9000C2207047E5F7FEBFFFF76FBE0120704794 +:109FA000F5F7F2BAFAF70ABFFFF7AAB8DEF76ABC0C +:109FB00000207047F8F770B9EFF786BBFAF720BAC0 +:109FC000FEF7ECBA00207047002070470020704771 +:109FD0000020704701207047002070470120704723 +:089FE000DFF800F01D870310FB +:109FE800C87900207C720020C0780020947300207B +:109FF8000000000018760020D0790020E8760020C4 +:10A00800D078002088740020CCB4020063B9020024 +:10A01800FAB902007FB9020071B90200E0780020A5 +:10A028005427002028270020182700201C2700205C +:10A038002427002020270020102700201427002094 +:10A048000C270020F0780020F4720020707800209F +:10A05800B474002086B0020014B00200F8B0020008 +:10A068006AB10200DCB10200D0B70200C0B9020038 +:10A07800B4B90200B77A002070790020E0240020EB +:10A0880004770020C8230020AC7A0020AD7A002095 +:10A09800C873002084780020641E00209F270020B9 +:10A0A8008CAF02008CA90200000000000000000034 +:10A0B80034B902002C6B0020887A0020847A0020B2 +:10A0C800402700203C270020447A002010B40200DA +:10A0D800F0770020F06F0020000000000000000072 +:10A0E800B42500200000000000000000000000006F +:10A0F80000000000E4220020B0670020382700207C +:10A10800014A031049480310D549031015470310A5 +:10A11800B16301005D49031081470310A146031094 +:10A128009548031045450310254A031021440310A0 +:10A13800ED47031099490310E14803102149031022 +:10A148005553031089520310CD5203106550031064 +:10A158008D4E031001690100C9B3010091DA0100B5 +:10A168000000000059510310ED500310A9C201006E +:10A17800CD4B03102952031011530310A955031096 +:10A188007555031069530310DD5503103555031039 +:10A19800195A010021540310855C03100D56031051 +:10A1A8004D5D0310A9640310B55B03106D570310D0 +:10A1B800E5610310095E0310C5580310856003109C +:10A1C80071610310B16203109963031055630310A2 +:10A1D800FD600310B15E0310C53D0100D55A0310A0 +:10A1E800D559031009630310D963031019640310C8 +:10A1F800555F0310C56403104D62031071640310AA +:10A208008D64031055640310E1640310297503106D +:10A2180079720310A16B0310F57203109D7403107B +:10A22800797403102D74031061730310FD73031008 +:10A238005574031015750310D96C0310FD740310C1 +:10A24800A5170100E17403103D750310B153010017 +:10A25800F97A0000CD6803102D710310C174031042 +:10A26800F56E0310B973031081B50000056E031075 +:10A278008142010065590100A1770310797D03101F +:10A288003D7E031049750310157E0310357D0310BC +:10A2980099760310997C0310257B031071780310BD +:10A2A800B57D0310ED7C0310857E03102D79031016 +:10A2B800B97A0310917B0310B1790310ED7B031079 +:10A2C800E97D0310617E0310357A0310D57E0310F3 +:10A2D800457C0310A57E0310BD7E0310F5380100F0 +:10A2E800D9800310E97E0310498303108984031081 +:10A2F8008D8103107D820310E58403102B840310E5 +:10A30800C5830310918703106188031045880310E3 +:10A3180059680100B18803107D880310C9880310AB +:10A328001D870310A186031001850310E18803101F +:10A3380099880310F987031011440100359C031014 +:10A34800819D0310E99A0310359B0310C19B0310EC +:10A35800419A0310F18803101D8C0310618F0310BC +:10A36800F1940310919E0310C19E03103D9E0310AB +:10A37800699E0310259E0310619D03100D9E031016 +:10A38800819B0310ED93031055990310C99703108F +:10A39800D9980310BD950310959C0310C19D031017 +:10A3A800A59E03107D9E0310C991031079A6010094 +:10A3B800699C0310DD9D031095900310FD9B03100D +:10A3C800CD990310D18E0200019D0310E19C03106A +:10A3D800219D0310419D0310BD9C0310F59D0310A2 +:10A3E800A19D031055980310E1920310999A031048 +:10A3F800B99E0310559E0310F1010200A7870200C1 +:10A4080039A20310C17E020069A1031075A20310CE +:10A41800C59E0310B9A10310F9A1031015A10310DB +:10A428009DA20310459A020087E80100913C0200B2 +:10A438009D880200059802004196010031A9031089 +:10A44800ADA20310F9E60000B9A8031099A50310FE +:10A458002588010039A803106DA903104957010088 +:10A468006DAC031099B1031009AF031059B1031073 +:10A4780001B103109DA90310859F0200819F02006E +:10A48800719F0200659F0200799F02007D9F020074 +:10A49800699F0200759F0200899F02008D9F02003C +:10A4A8006D9F0200F1B9031075BA031081BB031048 +:10A4B8007144020059810100E5D1010029470100DA +:10A4C800092D02000DE40100996502006DE4010008 +:10A4D800294F0200516E0200AD8D0200CDE401004B +:10A4E800310F0200BD9F02005D4F020051B3010011 +:10A4F8000D8B020001BC010049270200258B0200D8 +:10A50800C59F0200CD9F0200CD9D0000E5DF000041 +:10A51800E9C60310C99F0200BD630000CD9E02007A +:10A52800CD3A0200818D0200CD2102002F9E02004B +:10A5380043920200BD8E0200919F0200E50E0200C8 +:10A54800058701009D7F0100614000218D400021A9 +:10A5580099400021FF4000216F410021074C657997 +:10A5680000F009F861796940490703D50121044AD7 +:10A578008903116070BD70B5024908478003002146 +:10A58800081104402D59000000F00AF8004800475F +:10A59800577F000000F00AF8004800471B880000B9 +:10A5A800806B0C490007000F48717047094A0A4937 +:10A5B80018235079CB56497EC018814201DD0846E0 +:10A5C80002E00F2800DD0F20D189090909010143A4 +:10A5D800D1817047E00200218800002110B533487E +:10A5E800314C8047012807D02034217D002903D130 +:10A5F80001212F4A0905916010BD072801D02D4A75 +:10A6080010472D4A4A60C872704701222C4B02211C +:10A618002A481847274810B5F83080472948406A23 +:10A6280000280DD128490A200856002809DA401CBC +:10A6380007D008462038406A2449884200D180471C +:10A6480010BDFFF7E2FF10BD0021224B204A08464B +:10A65800184701202049400208602048FB22017861 +:10A668001140017013480C30004710B51C49884749 +:10A6780015492039012807D0020404D5002008858F +:10A6880018484862012010BD4A6A0A4B0C339A42A6 +:10A6980001D1154A05E00B494A6A144B9A42F2D196 +:10A6A800134A4A6210BD00006001002175A602002D +:10A6B80000110440A9910200E140002106080000B1 +:10A6C8009F06000008010021540100216392020046 +:10A6D80019410021B5B4020080E100E080030021A7 +:10A6E800F79602000F4100215741002169950200A9 +:10A6F8004D4100218F000100EC2700208700010058 +:10A7080024260020350028000875002028000100B4 +:10A71800D527002029000100D62700208400040046 +:10A728007827002086000100D92200202A00010095 +:10A73800E82700202B000100D32700202C0001006F +:10A74800E22700202D000800252600202E00010009 +:10A75800D42700202F000100DF270020300001004F +:10A76800C727002032000100CD2700203300010058 +:10A77800CC27002034000100CF270020360001003C +:10A78800CE27002038000100DE2700203900010014 +:10A79800E1270020830002009027002063000100C9 +:10A7A800E027002065000100E72700206D00010078 +:10A7B800C87A002071000800B82600206600010051 +:10A7C800C227002043000100C627002044000200E1 +:10A7D8008C27002045000100C02700204600020009 +:10A7E8008827002047000800C026002048000100F4 +:10A7F800C42700204B000100C327002004000100EB +:10A80800E9270020A1000100E62700203700010009 +:10A81800DB27002088000100DA2700203C00010027 +:10A82800E32700203D000100D9270020490002004D +:10A838009227002067000100C12700204D00020078 +:10A848008E2700204E000100C52700204F0002007F +:10A858008A2700203E000100CA270020510001007D +:10A86800DC27002052000100D827002053000100F7 +:10A87800D227002054000100D0270020000000004B +:10A88800000000000097B92EE5725CCB5DCAE47346 +:10A89800B82F0196BA2D03945FC8E671E7705EC9B8 +:10A8A8000295BB2CE3745ACD0691BF28BE290790A8 +:10A8B8005BCCE27559CEE077BC2B05920493BD2A98 +:10A8C800E17658CF51C6E87FB4230D9A0C9BB52288 +:10A8D800E97E50C7EB7C52C50E99B720B6210F9878 +:10A8E80053C4EA7DB2250B9C57C0EE79EF7856C168 +:10A8F8000A9DB324089FB126ED7A54C355C2EC7B58 +:10A90800B027099EA2351B8C47D0FE69FF6846D147 +:10A918001A8DA334188FA136FD6A44D345D2FC6B37 +:10A92800A037198E41D6F86FA4331D8A1C8BA53227 +:10A93800F96E40D7FB6C42D51E89A730A6311F8817 +:10A9480043D4FA6DF3644ADD1681AF38AE39178007 +:10A958004BDCF26549DEF067AC3B15821483AD3AF7 +:10A96800F16648DF1087A93EF5624CDB4DDAF463E7 +:10A97800A83F1186AA3D13844FD8F661F7604ED9D7 +:10A988001285AB3C000136360101000102010001CD +:10A998000301000104010606080400000C0100344C +:10A9A8000D01000F10040101140100FF160800003A +:10A9B80020020000220100FF23010001240100FE03 +:10A9C80025010008260200002801000129010001D4 +:10A9D8002A0200002C01000F2E02000030010001A5 +:10A9E80031010008320200FF34010007350102FF7F +:10A9F800360100003701000138010001390100FF6C +:10AA08003A01000F3C0200FF3E01010F3F01000127 +:10AA18004001041F41010001420100FF4301008081 +:10AA2800440800004E0100084F01000F50010001CA +:10AA3800510100FF520100005301000054010001C0 +:10AA4800580400005C040000600400006404000076 +:10AA5800680400006C040000700400007404000026 +:10AA6800780400007C040000800100FF81010001DF +:10AA7800820100018301020284010001B427002041 +:10AA8800BC7A0020C17A00209C270020AE7A0020E2 +:10AA9800B1270020AF270020519A0200BDA2000074 +:10AAA800978D02006D6502004165020091ED01007D +:10AAB80031F50100990E020029190200016E020009 +:10AAC800254E020065640200999F0200E58E02008F +:10AAD800E1060200554D0200D96D020091640200A2 +:10AAE800D990020055760200F54E0200C996010081 +:10AAF800B97C0100C93C020035ED010041020200A9 +:10AB08002B9702003997020000000000892C0200F0 +:10AB180047060200D5AA01002143020000000000F8 +:10AB2800E96402005D9A0200E14402001591020006 +:10AB3800000000000000000081C60000817E0200C5 +:10AB48002D070200B50D02006861726477617265B5 +:10AB580020657863657074696F6E206964203D2094 +:10AB680025642C207063203D2030782530387820EB +:10AB7800282F55736572732F6B6F656E6B6B2F473C +:10AB880069742F53494D504C454C494E4B2D434306 +:10AB9800313358322D323658322D53444B2D5A4EBC +:10ABA800502F73696D706C656C696E6B5F63633190 +:10ABB8003378785F6363323678785F73646B5F37B6 +:10ABC8005F34315F30305F31372F6B65726E656C83 +:10ABD8002F746972746F73372F7061636B61676567 +:10ABE800732F74692F73797362696F732F66616D40 +:10ABF800696C792F61726D2F6D332F4877692E63D9 +:10AC08003A31303932290048776920616C726561C0 +:10AC1800647920646566696E65643A20696E747249 +:10AC28002320256420282F55736572732F6B6F6559 +:10AC38006E6B6B2F4769742F53494D504C454C49E7 +:10AC48004E4B2D4343313358322D323658322D5323 +:10AC5800444B2D5A4E502F73696D706C656C696E3C +:10AC68006B5F6363313378785F6363323678785F1C +:10AC780073646B5F375F34315F30305F31372F6B10 +:10AC880065726E656C2F746972746F73372F70619B +:10AC9800636B616765732F74692F73797362696F6A +:10ACA800732F66616D696C792F61726D2F6D332F0B +:10ACB8004877692E633A33383529006E6F20495337 +:10ACC800522C206964203D2025642C207063203D8F +:10ACD8002030782530387820282F55736572732FE7 +:10ACE8006B6F656E6B6B2F4769742F53494D504CD2 +:10ACF800454C494E4B2D4343313358322D3236584B +:10AD0800322D53444B2D5A4E502F73696D706C651C +:10AD18006C696E6B5F6363313378785F6363323677 +:10AD280078785F73646B5F375F34315F30305F31E1 +:10AD3800372F6B65726E656C2F746972746F733719 +:10AD48002F7061636B616765732F74692F737973F3 +:10AD580062696F732F66616D696C792F61726D2FEF +:10AD68006D332F4877692E633A3130393529006FB2 +:10AD78007574206F66206D656D6F72793A2068650D +:10AD880061703D307825782C2073697A653D25758A +:10AD980020282F55736572732F6B6F656E6B6B2F41 +:10ADA8004769742F53494D504C454C494E4B2D43E0 +:10ADB80043313358322D323658322D53444B2D5AA5 +:10ADC8004E502F73696D706C656C696E6B5F636351 +:10ADD800313378785F6363323678785F73646B5F9A +:10ADE800375F34315F30305F31372F6B65726E6596 +:10ADF8006C2F746972746F73372F7061636B61673E +:10AE080065732F74692F73797362696F732F727505 +:10AE18006E74696D652F4D656D6F72792E633A3763 +:10AE2800382900696E746E756D3A2025642069733F +:10AE3800206F7574206F662072616E676520282FF9 +:10AE480055736572732F6B6F656E6B6B2F476974E3 +:10AE58002F53494D504C454C494E4B2D43433133AC +:10AE680058322D323658322D53444B2D5A4E502FCE +:10AE780073696D706C656C696E6B5F636331337891 +:10AE8800785F6363323678785F73646B5F375F34FB +:10AE9800315F30305F31372F6B65726E656C2F74A0 +:10AEA8006972746F73372F7061636B616765732F95 +:10AEB80074692F73797362696F732F66616D696C3A +:10AEC800792F61726D2F6D332F4877692E633A336E +:10AED8003737290013000000CDC300001F00000011 +:10AEE800B11601001F800000F134020000000000CC +:10AEF800F17C000001000000F17C0000020000006D +:10AF08009993010002800000B77C01000300000053 +:10AF18006141020004000000219401000480000047 +:10AF28006790010005000000A1160200060000005D +:10AF3800DD8000003000000021F301003100000036 +:10AF4800B16C000032000000E57101003300000020 +:10AF5800B565010034000000396C010036000000BE +:10AF680089CC01001100000051010200140000000A +:10AF7800A994010015000000814B0200FFFF0000AA +:10AF8800000000003600010006000000000000007C +:10AF9800000F00000000000000000000000000009A +:10AFA80000000300FFFF00000403FFFF0000FFFF95 +:10AFB8000F00E8030005401F031000010000000017 +:10AFC800FF3F0F000800050B000000000000000014 +:10AFD8000300010F00000000000000000000000056 +:10AFE8000000000000000000000000000000000059 +:10AFF8000000000000000000000000000000000049 +:10B0080000000000AD000002000000000101710115 +:10B018000101010111010101310101010101800159 +:10B028000001100161013B0014006301730172010A +:10B03800620143010001130106013D0135000401CD +:10B0480012010001000100010001040104013301A3 +:10B0580033013C0144013201360000010001650161 +:10B068000001350081010001050182018301000111 +:10B07800660100010001080109010A010B01030032 +:10B08800710030016000110070003102200350048B +:10B0980080000700100061000000140063007300C6 +:10B0A8007200620043000000130006000000000068 +:10B0B800040012000000000000000000040004006A +:10B0C800370037003C024400000000000000000088 +:10B0D80065000000350081000000050000008300C5 +:10B0E8000000660000000000080009000A000B00CC +:10B0F80003027102300160021102700201020202B1 +:10B10800020280020002100261023A00410063025A +:10B118007302720262024302000213023800000244 +:10B1280000020402120200020002000200020402ED +:10B138000402370037003C024402000239000002D2 +:10B148000002650200023502810200020502820245 +:10B1580083020002660200020002080209020A02D3 +:10B168000B0201037103010301030103010301033E +:10B17800220302030103000310030003000300037A +:10B188000003000300030003420300032403060333 +:10B1980000030003040312032503230325032303E9 +:10B1A8000403040300030003000344030003000333 +:10B1B800230300036503210035038103000305030E +:10B1C8000003000300030003250323030803090306 +:10B1D8000A030B03030471040204600411047004DD +:10B1E80002040204010402040004100461040004BF +:10B1F8001404630473047204620443040004130413 +:10B2080006040004000404041204000400040004FA +:10B218000004510464000004000400044404000411 +:10B22800000400040004650400043504810464007B +:10B2380005040004830400046604000400040804F0 +:10B2480009040A040B040E000B9C0200E79D02008F +:10B25800099F0200059F0200E18202007992020024 +:10B26800719702003D730200F9800200A570020088 +:10B27800D16B020089280200895602005987020012 +:10B28800B1EA010069F1010079C001000DE1010096 +:10B298004797020039790200AD9E0200FD9E010029 +:10B2A8003D990200AF710200679202005F9E0200A2 +:10B2B8005B79020001000000115700000600000041 +:10B2C8009F79020008000000D58901000B000000EA +:10B2D800491A020010000000AD3001000A00000009 +:10B2E800FDA201000200000021D6000005000000B8 +:10B2F80021CD0000070000008DE501000C000000D2 +:10B30800FD7600000D000000710C000064000000D4 +:10B31800ADDD0100FF00000000000000001000404B +:10B3280015000000FF0000007875002020000000D4 +:10B338009875002020000000000000000C000000AC +:10B348000D000000FF000000FF0000002018002092 +:10B358001018002004000000020000000500000092 +:10B36800100000000F000000110000001200000093 +:10B37800000200008E0000008E0001008E00020016 +:10B388008E0003008F0000018F0000028F00000371 +:10B398008E0001048E0000058E0008048E00000453 +:10B3A80089000006500000007F0001003F000400F3 +:10B3B8003F0002003F0001007F0002008E000204EF +:10B3C8008E0001028E00010101280000000000002B +:10B3D8000000000000010030000000000000000034 +:10B3E8000003FF18640000000000000000000000D7 +:10B3F8007856341200000000BAAB000000000001CB +:10B408000000000000000000C003000080070000EA +:10B41800000F0000001E0000003C00000078000043 +:10B4280000F0000000E0010000C0030000800700F9 +:10B4380000000F0000001E0000003C000000780023 +:10B448000000F0000000F0000000004017FF0000BE +:10B45800000000000400FFFF0800000010000000CA +:10B468004018002030180020401A0020301A002010 +:10B478000A000000090000000C0000000B0000009A +:10B4880009080AFF0A0000000A0000000200000084 +:10B498000400000008000000100000002000000068 +:10B4A80040000000800000000001000000020000D1 +:10B4B8000004000000080000001000000020000048 +:10B4C8000040000000000000020000000200000030 +:10B4D8000A00000002000000020001000000000055 +:10B4E8000000000000000000000000000000000054 +:10B4F80000000000000000000E000000C39C0200D5 +:10B50800879D0200C9550200C17B0200A9080200FC +:10B518004589020009B00100F5080200AD98020053 +:10B52800CD0401007D9E010055EA0100F955020095 +:10B53800D7910200313F02005D890200A500010099 +:10B5480061000200B998020071C20000000000000A +:10B5580000000000000000000000000000000000E3 +:10B5680000000000000000000000000000000000D3 +:10B57800000000000000000000602500001000002E +:10B58800C071002040000000000000000000000022 +:10B5980000093D00140000006400000061D70000AD +:10B5A800799F000085400000815100004D44000053 +:10B5B8009DD80000A94E0000558501008D27000088 +:10B5C800F952010000000000000000000000000027 +:10B5D80000000000000000000100000000C201009F +:10B5E8000300000000000000000000000000000050 +:10B5F8000000000001000000000000000002000040 +:10B60800000000000000000001000000022C000003 +:10B618000000000000000000000000000000000022 +:10B628000000000000000000000000000208000008 +:10B638000000000000000000000101000800FFFFFA +:10B6480018260020A02400208824002000000000E4 +:10B65800FFFFFFFF000000000000000040420F0055 +:10B6680008000000000000000000000008000000C2 +:10B6780008000000080000000800000004000000A6 +:10B68800020000000100000001000000FFFFFFFFB2 +:10B698000000000000000000000000003A013A012C +:10B6A80000000000000000000000000052616E640D +:10B6B8006F6D5F736565644175746F6D61746963FF +:10B6C8002829206661696C65640074692E73797332 +:10B6D80062696F732E6B6E6C2E5461736B2E4964A6 +:10B6E8006C655461736B0069643A20307825782062 +:10B6F80061303A20307825782061313A2030782539 +:10B70800780A00050000000000000000E8030000BF +:10B718000000000000000000000000000000000021 +:10B7280004B50200BE7A00205CBA02002CB5020003 +:10B738007C7900207CB502000100000040420F0027 +:10B7480001000000000000000000000000000000F0 +:10B758000308000000000000000000000001650967 +:10B768000000000000000000012C000000000000A4 +:10B77800000000000001001E0000000000000000A2 +:10B7880071B101009D2A0100339C0200B9AA000092 +:10B7980049540000C5840100038000C0038000D51F +:10B7A800038000CC038000DD0380000C0380005D73 +:10B7B800000000000200000001000000030000007B +:10B7C800100000002000000000000500BD00B700C8 +:10B7D800B100BC001C00300038000800380102002D +:10B7E8000000000000000000010000000000000050 +:10B7F800E0000000010000005B4173736572742073 +:10B80800526561736F6E5D20307825303258001EA6 +:10B8180000000000FD5701007589020001010100C8 +:10B8280000000000032C00000000000000000000E1 +:10B8380000000000000000000200000000000000FE +:10B8480000000000FFFFFFFF0000000000000000F4 +:10B8580000000000000000000500000000000000DB +:10B8680041455343434D206F70656E206661696C96 +:10B87800656400414553454342206F70656E2066FC +:10B8880061696C656400001610000018151002004C +:10B898000224145800001000003031323334353699 +:10B8A8003738396162636465660054524E47206FC9 +:10B8B80070656E206661696C6564000202000000B4 +:10B8C80000000000FFFFFFFF000000000200000072 +:10B8D80000000000FFFFFFFF00000000E81D00203F +:10B8E800386C0020B46C0020FFFFFFFF746A002052 +:10B8F80092BA0200D06A002094BA02000000000048 +:10B908000000000000000000000000005A696742C3 +:10B918006565416C6C69616E63653039D0D1D2D38D +:10B92800D4D5D6D7D8D9DADBDCDDDEDF88B224007F +:10B9380088130000100000000000000141737365C7 +:10B948007274206661696C65643A20004572726F92 +:10B9580072207261697365643A200000A6AAACA4DB +:10B96800A9A9A399B19ABCB6A8313118191A2231DC +:10B978001C1E2031313431313117191A21241B1D75 +:10B988001F31313331027F00FF000000000000004A +:10B9980000010000FF00010073870200070000009B +:10B9A80088B70200B066002050B402000C0E020BEB +:10B9B800040B0A070800110F000120181A18182C88 +:10B9C80034041E0000000000000000000000000019 +:10B9D800000000000000000000000000FF00000060 +:10B9E8000000000080A90300020102070146D934C3 +:10B9F800010002040201010101090201782100206D +:10BA08007C210020D8770020C7BA0200E07400200B +:10BA1800C8BA0200E803000000006400B46B00200C +:10BA2800E4B90200445E002024B302003876002006 +:10BA380074BA0200010200030200010300BE0208FA +:10BA480000BE040AFFFFFFFFFFFFFFFF000800041E +:10BA580000020001000005000060000054B9020067 +:10BA680044B902001D4C02008D890200000002400A +:10BA78000929FF00286E756C6C2900000602868271 +:10BA880000081018200001020304060107018813AA +:10BA98000000000022000100440001000020406076 +:10BAA800E803000088130000200000007C1F00202D +:10BAB8002000000000002800C80000080A0001401B +:10BAC8002001080F030C1E040A190505082864FA4A +:0DBAD8000CFF0400014503011E483033003F +:10BAE800BD59000075E300000000000000000000E0 +:10BAF80000000000BD8902005D8F0200E599010089 +:10BB080085990200119E02000B9E02003F8D0200E3 +:10BB180000000000FF9D0200EDA7010039FA0100B6 +:10BB2800E17C020061990100FB9102001D2E0100D9 +:10BB3800C18400006DCA0100417D020000000000C0 +:10BB4800E11E0200A5890200656F01001D8E02003A +:10BB58009D9202008D9702008D9202004D9B02007B +:10BB68004B9D0200459D0200318E0200BD920200ED +:10BB7800CD950200AD92020099970200579D0200F0 +:10BB8800519D0200ED970200E197020084250020F4 +:10BB98004C1D002034B6020058B7020070B70200EE +:10BBA800D0B3020014B602002CB802000000000056 +:08BBB800000000000000000085 +:10BBC00001E500000FA1020100BF0514BF02619F43 +:10BBD000023F0025380100D1007016B5FFECC60405 +:10BBE0000000EEC806EF0000F1CA0040F4CC0A6F76 +:10BBF0000000F6CF0040F7D00090FFFAD41000000C +:10BC0000FBD612DF0000FD931819E05328FA071045 +:10BC10005600400259320000FF035D380000046303 +:10BC20004EFF0000051772000006FF2A4F14800720 +:10BC30005F2814FF80085A331080095FFF3F10808F +:10BC40000A664F1080FF0BCB2130800CCC27FF3FC2 +:10BC5000800DCDC33F800EFFD6271B800FDA2F1B30 +:10BC6000FF8010DE391B8011E5FF4F1B8012E0477B +:10BC70003080FF13E2613F8014F575BF3F807FFF86 +:10BC8000FF3F0CEF04021D60225004002000310031 +:10BC9000B000727E00B400022000200101718140DA +:10BCA00000340131003801B2013C0239003108058D +:10BCB00070003528CFC6016CDC1FC73700FD033785 +:10BCC00044490602005588E50215A02726FF0C27E7 +:10BCD000051B00207B9C69127F2CC81F00200031AF +:10BCE000163F71807A1737E0017000312CFF022374 +:10BCF000287419BF4834B134F80130A0492F9F018E +:10BD0000FF11080200E8BA02009B54BB3E33416FAA +:10BD10001EEA562F9701C57D1B60D7253C00003DCC +:10BD200061C4DB8515625F0CFD74645F0419E13F3B +:10BD30000000382200200031527F06255825B05CD3 +:10BD4000023000316400345A0F3B9A6E0F02080033 +:10BD500033FFFF54F058A00FF03938006FB2027172 +:10BD60003F0E873F2A2BD4D7FDFF0307C2018387ED +:10BD700003007FC3060201A860011C70FFFFFF2BB8 +:10BD80005EC80103075F32058387000171050170FA +:10BD9000D90401718DFF1686B079F76AB1563BFF61 +:10BDA00024FEFE94DF1C14000C012971D686480184 +:10BDB0000C99D7808744911AF245BB9D5C389CBD95 +:10BDC000325032003A001102641001007D9EAF3BF8 +:10BDD0001731FE177183880F00D388F3FE183200E5 +:10BDE0000123456789ABB3CDEF037F0AA7040503A1 +:10BDF000225F2845FF7000202979010019FA95B0CB +:10BE00000B92C054250020A095260033A80034B022 +:10BE10000034083F05FF748CF0AFA880B06E4FD49B +:10BE200001003296B1FF1275B2B45F0EF00034B665 +:10BE3000DF1888F91325BC4AB0E001FFFF80FF3E00 +:10BE40000500F401E803FF9DFF011100010384D107 +:10BE5000A30000A33C00A4F0AA27A6D130BDC10FC7 +:10BE6000F9011FD100F00102010A037F1E01030145 +:10BE7000013C017660FF0308080204030908BE01C3 +:10BE8000E20A05000D028660E00B0102A8B001FF86 +:10BE9000F0000000BD95020009C701007F97020075 +:10BEA0000000000010000000000000001000000072 +:10BEB0000000000010000000000000001000000062 +:10BEC0000000000010000000000000001000000052 +:10BED00000000000D9520000000000001000000027 +:10BEE00000000000D8000000C0BB0200D81B0020EA +:10BEF000A0BE0200301A0020A8BE020030180020A8 +:10BF0000B0BE0200401A0020B8BE02004018002057 +:10BF1000C0BE020010180020C8BE02002018002079 +:10BF2000D0BE0200F0270020D8BE02000C01002085 +:08BF3000E0BE0200001B00202E +:020000025000AC +:107FA800000080011000C0FFFDFF5800FFC1B9FDAF +:107FB800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC9 +:107FC800FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFB9 +:107FD800C508FEC5FFFFFFFF00FFFFFF00C5C5FF87 +:107FE800000000FF00000000FFFFFFFFFFFFFFFF92 +:087FF800FFFFFFFFFFFFFFFF89 +:00000001FF